Compare commits

...

250 Commits
v6.3.9 ... main

Author SHA1 Message Date
1ae45808fd 📝 更新banner链接以优化显示效果
Some checks failed
Docker Image Build / build (push) Failing after 26s
Pre-commit checks / pre-commit (3.11) (push) Failing after 2m32s
Pre-commit checks / pre-commit (3.10) (push) Failing after 3m2s
Pre-commit checks / pre-commit (3.13) (push) Failing after 4m46s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 9m56s
Pre-commit checks / pre-commit (3.12) (push) Failing after 1h12m10s
2025-05-17 00:53:51 +08:00
800dbbba43 📝 更新发布URL为 "https://dash.apage.dev"
Some checks failed
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 2m21s
Pre-commit checks / pre-commit (3.10) (push) Failing after 2m35s
Pre-commit checks / pre-commit (3.11) (push) Failing after 3m16s
Docker Image Build / build (push) Failing after 7m6s
Pre-commit checks / pre-commit (3.12) (push) Failing after 8m32s
Pre-commit checks / pre-commit (3.13) (push) Failing after 14m49s
2025-05-16 20:01:30 +08:00
c627c07aa1 📝 Update Liteyuki logo URLs in Chinese documentation
Some checks failed
Docker Image Build / build (push) Failing after 1m52s
Pre-commit checks / pre-commit (3.10) (push) Failing after 4m38s
Pre-commit checks / pre-commit (3.12) (push) Failing after 5m11s
Pre-commit checks / pre-commit (3.11) (push) Failing after 9m50s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 10m22s
Pre-commit checks / pre-commit (3.13) (push) Failing after 14m46s
2025-05-16 19:03:52 +08:00
4a9259dad4
Update README.md 2025-05-16 18:58:57 +08:00
Nanaloveyuki
fc017c8255 📝 文档与代码注释信息微调
Some checks failed
Docker Image Build / build (push) Failing after 15s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 1m2s
Pre-commit checks / pre-commit (3.10) (push) Failing after 1m46s
Pre-commit checks / pre-commit (3.11) (push) Failing after 1m38s
Pre-commit checks / pre-commit (3.12) (push) Failing after 1m45s
Pre-commit checks / pre-commit (3.13) (push) Failing after 1m43s
2025-04-04 11:44:50 +08:00
Nanaloveyuki
908812a3d9 📝 重置了deploy下的文档
Some checks failed
Docker Image Build / build (push) Failing after 2m10s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 2m30s
Pre-commit checks / pre-commit (3.10) (push) Failing after 3m7s
Pre-commit checks / pre-commit (3.11) (push) Failing after 2m37s
Pre-commit checks / pre-commit (3.12) (push) Failing after 2m42s
Pre-commit checks / pre-commit (3.13) (push) Failing after 3m18s
新添加了adapter.md用来转移配置器相关内容; 修改了部分文件的版权归属日期;
2025-04-03 21:54:03 +08:00
6c7d073cb1
📝 添加文档uptime
Some checks failed
Docker Image Build / build (push) Failing after 36s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 1m34s
Pre-commit checks / pre-commit (3.10) (push) Failing after 2m1s
Pre-commit checks / pre-commit (3.11) (push) Failing after 2m10s
Pre-commit checks / pre-commit (3.12) (push) Failing after 2m5s
Pre-commit checks / pre-commit (3.13) (push) Failing after 2m29s
2025-03-19 02:12:28 +08:00
8677286bd4
📝 更新pages部署地址
Some checks failed
Docker Image Build / build (push) Failing after 40s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 1m46s
Pre-commit checks / pre-commit (3.10) (push) Failing after 2m58s
Pre-commit checks / pre-commit (3.11) (push) Failing after 16s
Pre-commit checks / pre-commit (3.12) (push) Failing after 36s
Pre-commit checks / pre-commit (3.13) (push) Failing after 35s
2025-03-10 23:07:21 +08:00
232ffcf714 📝 修正文档中的LSO LICENSE拼写错误
Some checks failed
Docker Image Build / build (push) Failing after 29s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 2m12s
Pre-commit checks / pre-commit (3.10) (push) Failing after 3m37s
Pre-commit checks / pre-commit (3.11) (push) Failing after 3m17s
Pre-commit checks / pre-commit (3.12) (push) Failing after 3m49s
Pre-commit checks / pre-commit (3.13) (push) Failing after 3m48s
2025-03-09 20:01:36 +08:00
6871bc0d22 更新配置,重新引入 liteyuki_footer.js 脚本
Some checks failed
Docker Image Build / build (push) Failing after 28s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 2m55s
Pre-commit checks / pre-commit (3.10) (push) Failing after 3m27s
Pre-commit checks / pre-commit (3.11) (push) Failing after 3m9s
Pre-commit checks / pre-commit (3.12) (push) Failing after 4m2s
Pre-commit checks / pre-commit (3.13) (push) Failing after 4m17s
2025-03-08 23:26:54 +08:00
641c16ee7a 📝 文档引入神秘js 2025-03-08 23:21:14 +08:00
75c67bdffc 更新配置,禁用清理 URL 功能
Some checks failed
Docker Image Build / build (push) Failing after 54s
Pre-commit checks / pre-commit (3.10) (push) Failing after 2m47s
Pre-commit checks / pre-commit (3.11) (push) Failing after 2m36s
Pre-commit checks / pre-commit (3.12) (push) Failing after 2m35s
Pre-commit checks / pre-commit (3.13) (push) Failing after 2m45s
Deploy VitePress site to Liteyuki PaaS / build (push) Failing after 11m59s
2025-03-07 21:35:21 +08:00
3a60450358 📝 更新文档页脚信息,修正链接文本
Some checks are pending
Docker Image Build / build (push) Waiting to run
Deploy VitePress site to Liteyuki PaaS / build (push) Waiting to run
Pre-commit checks / pre-commit (3.10) (push) Waiting to run
Pre-commit checks / pre-commit (3.11) (push) Waiting to run
Pre-commit checks / pre-commit (3.12) (push) Waiting to run
Pre-commit checks / pre-commit (3.13) (push) Waiting to run
2025-03-07 17:43:43 +08:00
7b97210a31 📝 更新文档页脚信息,添加网站部署链接
Some checks are pending
Docker Image Build / build (push) Waiting to run
Deploy VitePress site to Liteyuki PaaS / build (push) Waiting to run
Pre-commit checks / pre-commit (3.10) (push) Waiting to run
Pre-commit checks / pre-commit (3.11) (push) Waiting to run
Pre-commit checks / pre-commit (3.12) (push) Waiting to run
Pre-commit checks / pre-commit (3.13) (push) Waiting to run
2025-03-07 17:21:01 +08:00
d97145ee5e 📝 更新文档部署工作流程,添加对状态的写入权限并恢复 GITHUB_TOKEN 环境变量 2025-03-07 17:09:01 +08:00
bc3a4355c3 🐛 移除文档部署工作流程中的 GITHUB_TOKEN 环境变量 2025-03-07 17:00:27 +08:00
d835a32683 🗑️ 删除文档部署工作流程文件 2025-03-07 16:49:25 +08:00
aedea1acb9 Merge branch 'main' of https://github.com/LiteyukiStudio/LiteyukiBot 2025-03-07 16:37:18 +08:00
3bce8325c1 📝 新增 Liteyuki PaaS 部署工作流程,优化文档构建和发布步骤 2025-03-07 16:37:15 +08:00
d1c1320963
📝 Create .domain
Some checks failed
Docker Image Build / build (push) Failing after 1m1s
Deploy VitePress site to Pages / build (push) Failing after 1m42s
Pre-commit checks / pre-commit (3.10) (push) Failing after 2m42s
Pre-commit checks / pre-commit (3.11) (push) Failing after 2m55s
Pre-commit checks / pre-commit (3.13) (push) Failing after 3m9s
Pre-commit checks / pre-commit (3.12) (push) Failing after 5m0s
2025-03-07 00:12:44 +08:00
317e07eb71 🐛 更新文档页脚信息,添加Liteyukiflare CDN加速说明
Some checks failed
Pre-commit checks / pre-commit (3.10) (push) Failing after 2m43s
Deploy VitePress site to Pages / build (push) Failing after 3m7s
Pre-commit checks / pre-commit (3.13) (push) Failing after 3m10s
Pre-commit checks / pre-commit (3.12) (push) Failing after 13m53s
Pre-commit checks / pre-commit (3.11) (push) Failing after 13m56s
Docker Image Build / build (push) Failing after 14m14s
2025-03-01 03:05:04 +08:00
37749ae15e 📝 使用Liteyukiflare对GitHub Page进行亚太地区加速 2025-03-01 03:04:34 +08:00
f94c10de61 🐛 修正 Docker 镜像标签的大小写,更新相关文档中的镜像拉取命令
Some checks failed
Pre-commit checks / pre-commit (3.10) (push) Failing after 5s
Pre-commit checks / pre-commit (3.12) (push) Failing after 4s
Pre-commit checks / pre-commit (3.11) (push) Failing after 11s
Pre-commit checks / pre-commit (3.13) (push) Failing after 5s
Docker Image Build / build (push) Failing after 1m41s
Deploy VitePress site to Pages / build (push) Failing after 1m46s
2025-02-18 09:08:50 +08:00
5ccef735be 🐛 更新 Docker 镜像拉取地址,修正文档中的镜像源 2025-02-18 09:07:37 +08:00
262002b49a 🐛 更新 GitHub 容器注册表登录配置,修正 Docker 镜像构建和推送步骤 2025-02-18 09:06:52 +08:00
40c6ba6d9e 🐛 更新管道依赖,修复管道句柄错误
Some checks failed
Pre-commit checks / pre-commit (3.10) (push) Failing after 32s
Docker Image Build / build (push) Failing after 55s
Pre-commit checks / pre-commit (3.12) (push) Failing after 39s
Pre-commit checks / pre-commit (3.11) (push) Failing after 3m28s
Pre-commit checks / pre-commit (3.13) (push) Failing after 3m59s
Deploy VitePress site to Pages / build (push) Failing after 10m0s
2025-02-18 06:47:31 +08:00
60093b562b 🐛 移除 Gotify 插件及相关配置,更新依赖项版本 2025-02-18 06:42:42 +08:00
30880ec13b 在 README 中添加 LiteyukiLab 的徽章链接
Some checks failed
Docker Image Build / build (push) Failing after 32s
Deploy VitePress site to Pages / build (push) Failing after 53s
Pre-commit checks / pre-commit (3.10) (push) Failing after 1m36s
Pre-commit checks / pre-commit (3.11) (push) Failing after 1m38s
Pre-commit checks / pre-commit (3.12) (push) Failing after 1m58s
Pre-commit checks / pre-commit (3.13) (push) Failing after 1m47s
2025-01-13 00:57:50 +08:00
cc1d82312a 添加新的图标配置,更新链接以指向新的资源 2025-01-13 00:49:01 +08:00
efca13d397 🐛 移除 requirements.txt 中的 pip 依赖项
Some checks failed
Docker Image Build / build (push) Failing after 18s
Deploy VitePress site to Pages / build (push) Failing after 52s
Pre-commit checks / pre-commit (3.10) (push) Failing after 1m25s
Pre-commit checks / pre-commit (3.11) (push) Failing after 1m7s
Pre-commit checks / pre-commit (3.12) (push) Failing after 1m27s
Pre-commit checks / pre-commit (3.13) (push) Failing after 1m25s
2024-12-14 02:59:55 +08:00
3a8c09d6db 🐛 删除 __pypackages__ 目录的 .gitignore 文件,并更新主 .gitignore 文件以忽略 pdm 相关文件 2024-12-14 02:57:51 +08:00
cc1bb8e5e4 添加 pre-commit 配置和工作流,集成代码格式化和静态检查工具
Some checks failed
Docker Image Build / build (push) Failing after 29s
Deploy VitePress site to Pages / build (push) Failing after 53s
Pre-commit checks / pre-commit (3.10) (push) Failing after 2m17s
Pre-commit checks / pre-commit (3.11) (push) Failing after 2m1s
Pre-commit checks / pre-commit (3.13) (push) Failing after 2m18s
Pre-commit checks / pre-commit (3.12) (push) Failing after 2m57s
2024-12-13 19:35:07 +08:00
93c17b6026 添加新的配置加载器,支持从YAML、TOML、JSON和环境变量加载配置,并修改默认主机地址
Some checks failed
Docker Image Build / build (push) Failing after 1m25s
Deploy VitePress site to Pages / build (push) Failing after 1m50s
2024-12-02 21:46:29 +08:00
fd3f6272f1 🐛 修复获取系统语言代码的逻辑,处理None值的情况
Some checks failed
Docker Image Build / build (push) Failing after 35s
Deploy VitePress site to Pages / build (push) Failing after 2m11s
2024-11-29 00:04:34 +08:00
4d87a3c0b7 Merge branch 'main' of https://git.liteyuki.icu/bot/app 2024-11-29 00:03:14 +08:00
86f47ee411 🐛 修复获取系统语言代码的逻辑,添加对None值的处理 2024-11-29 00:01:49 +08:00
1d6b8d60f3
Merge pull request #89 from Asankilp/main
Some checks failed
Docker Image Build / build (push) Failing after 21s
Deploy VitePress site to Pages / build (push) Failing after 53s
添加uninfo依赖项
2024-11-27 01:47:23 +08:00
3890704045 添加uninfo依赖项 2024-11-27 01:44:49 +08:00
b0761e9873 🐛 更新docker-compose.yml,修改时区设置为Asia/Chongqing
Some checks failed
Docker Image Build / build (push) Failing after 19s
Deploy VitePress site to Pages / build (push) Failing after 55s
2024-11-23 22:31:51 +08:00
291314de93 新增docker-compose.yml文件,定义应用服务及其配置 2024-11-23 22:31:06 +08:00
fd835e9406 更新.gitignore,新增Python工具链缓存目录排除项;更新README.md,调整标题并添加monorepo说明
Some checks failed
Docker Image Build / build (push) Failing after 37s
Deploy VitePress site to Pages / build (push) Failing after 57s
2024-11-22 20:15:04 +08:00
d681c5645a 🐛 更新Dockerfile,新增libpango-1.0-0和libcairo2依赖
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m0s
Docker Image Build / build (push) Failing after 1m8s
2024-11-21 19:53:49 +08:00
d0619f1fe8 优化Dockerfile,移除不必要的sources.list复制步骤,简化pip安装命令
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m2s
Docker Image Build / build (push) Failing after 1m29s
2024-11-16 02:24:47 +08:00
b022a364e3 更新GitHub Actions工作流,修改并发组名称为“docker-build” 2024-11-16 02:20:06 +08:00
df00c61dd8 新增GitHub Actions工作流以构建和推送Docker镜像,更新.gitignore以排除.github目录 2024-11-16 02:19:31 +08:00
94a021bab0 更新安装文档,替换Docker构建步骤为拉取最新夜间版镜像 2024-11-16 02:17:06 +08:00
6b20e9eae0 更新README.md,将“参考及鸣”更正为“参考及鸣谢”
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 2m9s
2024-11-10 01:20:14 +08:00
0a35a3c6f8 修正README.md中的链接错误,将“lightyuki-link”更正为“liteyuki-link” 2024-11-10 01:19:58 +08:00
2e75c7bc65 更新README.md,新增GitHub和官方仓库链接,优化内容结构
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m17s
2024-11-10 01:15:34 +08:00
3341505715 更新LiteyukiBot克隆命令中的镜像链接
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 2m52s
2024-11-09 23:52:17 +08:00
bdde9c45fd 优化配置文件格式和清理无用调试信息,修改gitea仓库路径 2024-11-09 23:51:35 +08:00
7bf94a15c8 📝 文档新增插件通信部分内容
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m10s
2024-10-26 02:34:58 +08:00
4510477026 Merge branch 'main' of https://github.com/LiteyukiStudio/LiteyukiBot
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 15s
2024-10-23 01:06:47 +08:00
86e50e369b 初步对Uninfo的支持 2024-10-23 01:04:42 +08:00
796fc6f233
Merge pull request #88 from EillesWan/main
🌠也许,大家的测试环境都是*nix?
2024-10-22 13:36:57 +08:00
金羿ELS
80c6875567
🌠也许,大家的测试环境都是*nix?
Update file.py
2024-10-22 13:34:09 +08:00
ab89cd1c72 性能提升200倍
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 11m46s
2024-10-20 23:37:40 +08:00
5e454bc971 性能提升200倍 2024-10-20 23:36:49 +08:00
70bfb0fcee 性能提升200倍 2024-10-20 23:35:44 +08:00
13b95c2732 🐛 修复一些细节小问题 2024-10-20 20:59:30 +08:00
ef5866343d add: nonebot-plugin-gotify 2024-10-20 04:12:17 +08:00
d5ccd105a2 add: nonebot-plugin-gotify 2024-10-20 03:11:26 +08:00
20ad8dc53f 🐛 hotfix: from mypy import 2024-10-19 21:15:37 +08:00
de9c91d8bd 🐛 hotfix: from mypy import 2024-10-19 21:12:55 +08:00
6b64a0c379 🐛 hotfix: from mypy import 2024-10-19 21:10:18 +08:00
f117da7ff3 🎨 更新轻雪依赖版本
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 7m29s
2024-10-14 20:57:30 +08:00
f548a07230 📝 文档删除常规部署,强制使用虚拟环境 2024-10-14 20:51:37 +08:00
e2e53c21fa 📝 文档删除常规部署,强制使用虚拟环境
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 15s
2024-10-14 01:03:06 +08:00
3eaf23a56b 📝 文档删除常规部署,强制使用虚拟环境 2024-10-14 01:02:57 +08:00
4a5dd1f727 🐛 修复一些细节小问题 2024-10-14 00:57:33 +08:00
c2cb416b4e 🐛 hotfix: ubl
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 7m36s
2024-10-13 17:44:24 +08:00
5cd528d5e9 🐛 hotfix: ubl 2024-10-13 17:44:17 +08:00
980fca650b 🐛 hotfix: ubl 2024-10-13 13:44:07 +08:00
9c525141f6 分离magicocacroterline
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 6m48s
2024-10-13 02:56:29 +08:00
3d218a0e8d Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/liteyuki_plugins/nonebot/__init__.py
#	src/liteyuki_plugins/nonebot/nb_utils/adapter_manager/__init__.py
#	src/liteyuki_plugins/nonebot/nb_utils/adapter_manager/onebot.py
#	src/liteyuki_plugins/nonebot/nb_utils/adapter_manager/satori.py
#	src/liteyuki_plugins/nonebot/nb_utils/driver_manager/__init__.py
#	src/liteyuki_plugins/nonebot/nb_utils/driver_manager/auto_set_env.py
#	src/liteyuki_plugins/nonebot/nb_utils/driver_manager/defines.py
2024-10-13 02:55:04 +08:00
db385f597b 分离magicocacroterline 2024-10-13 02:54:47 +08:00
98a9d6413a 分离magicocacroterline 2024-10-13 02:51:33 +08:00
a77f97fd4b 🐛 hotfix: 移除状态卡片Linux下非储存分区
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 8m9s
2024-09-29 22:57:04 +08:00
e6ea1b700f 🐛 hotfix: 天气拉取异常 2024-09-29 22:52:34 +08:00
596f4d06ea 🐛 bug: 修复状态卡片显示问题 2024-09-29 22:35:24 +08:00
8e3d3b3b5d Merge remote-tracking branch 'origin/main'
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 50s
2024-09-27 00:50:05 +08:00
a34ad87e01 todo: add todo file 2024-09-27 00:49:54 +08:00
6c4c7f34cd
📝 Update resource_publish_en.yml
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m32s
2024-09-22 01:56:00 +08:00
0c859957b4 🐛 docs: 添加发布插件表单 2024-09-22 01:48:53 +08:00
fbb9ed82ee 🐛 docs: 添加发布插件表单 2024-09-22 01:42:03 +08:00
b469c9420e 🐛 docs: 添加发布插件表单 2024-09-22 01:38:44 +08:00
aa4d930cc4 🐛 docs: 添加发布插件表单 2024-09-21 23:16:37 +08:00
76be748160
:docs: Update resource_publish_zh.yml 2024-09-21 22:36:04 +08:00
a9dd37b8a5
📝 Update resource_publish_zh.yml 2024-09-21 22:32:47 +08:00
5900d621f2
Create resource_publish_zh.yml 2024-09-21 22:28:58 +08:00
7442a3651b
Create config.yml 2024-09-21 22:28:13 +08:00
413f438689
Rename resource_publish.md to resource_publish.yml 2024-09-21 22:21:20 +08:00
1fc4999b09
:docs: add resource_publish to resource_publish.md 2024-09-21 22:20:43 +08:00
975446a096
Create resource_publish 2024-09-21 22:19:34 +08:00
98cdd2f4b8 🐛 docs: 商店点击主页改为新窗口,修复插件商店仅轻雪不显示的问题
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m33s
2024-09-21 03:22:40 +08:00
c0beec0429 🐛 docs: 商店点击主页改为新窗口,修复插件商店仅轻雪不显示的问题 2024-09-21 03:16:32 +08:00
614d78b3fa 🐛 docs: 商店点击主页改为新窗口,修复插件商店仅轻雪不显示的问题 2024-09-21 03:12:32 +08:00
24b0f345e4 📦 docs: 主页添加开发按钮 2024-09-21 02:51:59 +08:00
0ae10aa1b2 Merge remote-tracking branch 'origin/main' 2024-09-21 02:49:11 +08:00
9fe7478840 📦 docs: 修复文档404 2024-09-21 02:49:01 +08:00
liteyuki-flow[bot]
efca0bc7b3 📦 发布资源: 测试资源包2
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m16s
2024-09-18 01:41:24 +08:00
50c5e99b98 📦 docs: 修改发布按钮样式 2024-09-18 01:38:13 +08:00
7415efcc90 📦 docs: 修改发布按钮样式 2024-09-18 01:32:12 +08:00
5bb4584e6a Merge remote-tracking branch 'origin/main' 2024-09-18 01:31:13 +08:00
795a6f3f76 📦 docs: 修改发布按钮样式 2024-09-18 01:31:03 +08:00
liteyuki-flow[bot]
fa74e08514 📦 发布资源: 测试资源包2 2024-09-18 01:30:26 +08:00
e6cf6e0c68 📦 docs: 修改发布按钮样式 2024-09-18 01:25:43 +08:00
6789c16773 📦 docs: 修改发布按钮样式 2024-09-18 01:24:32 +08:00
cdea0f8563 📦 docs: 修改发布按钮样式 2024-09-18 01:23:21 +08:00
9df55671ac 📦 docs: 修改发布按钮样式 2024-09-18 01:22:08 +08:00
d96c6f13c1 📦 docs: 修改发布按钮样式 2024-09-18 01:05:23 +08:00
bce1bf8704 Merge remote-tracking branch 'origin/main' 2024-09-18 01:04:47 +08:00
8eb626b8da 📦 docs: 修改发布按钮样式 2024-09-18 01:04:37 +08:00
liteyuki-flow[bot]
e6505d335b 📦 发布资源: 测试资源包2 2024-09-18 00:59:47 +08:00
c8cb341afb Merge remote-tracking branch 'origin/main'
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m32s
2024-09-17 16:30:30 +08:00
e99cb88b13 📦 docs: 修改发布按钮样式 2024-09-17 16:30:19 +08:00
liteyuki-flow[bot]
78c3e299d0 📦 发布资源: 轻雪Kakyo语言包 托管版 2024-09-17 16:27:24 +08:00
23338437e9 📦 docs: 资源商店新增发布资源功能 2024-09-17 16:23:07 +08:00
f95899aebd 📦 docs: 资源商店新增发布资源功能
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m16s
2024-09-17 16:21:45 +08:00
5df10c66b6 📦 docs: 资源商店新增发布资源功能 2024-09-17 16:21:18 +08:00
811d1594cd 📦 docs: 资源商店新增发布资源功能 2024-09-17 16:19:47 +08:00
c162208638 📦 docs: 资源商店新增发布资源功能 2024-09-17 16:16:29 +08:00
679d6597d8 Merge remote-tracking branch 'origin/main' 2024-09-17 16:14:18 +08:00
f402799f28 📦 docs: 资源商店新增发布资源功能 2024-09-17 16:14:08 +08:00
liteyuki-flow[bot]
60542d7426 📦 发布资源: 轻雪Kakyo语言包 稳定版 2024-09-17 16:06:05 +08:00
db1fb58717 📦 docs: 资源商店新增发布资源功能 2024-09-17 16:01:19 +08:00
7d5675ec97 Merge remote-tracking branch 'origin/main' 2024-09-17 15:58:56 +08:00
d8c50752f7 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:58:45 +08:00
liteyuki-flow[bot]
c674b837bb 📦 发布资源: 测试资源包 2024-09-17 15:53:47 +08:00
d867996072 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:53:17 +08:00
7ef36c6933 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:52:32 +08:00
982aae4dbf 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:50:10 +08:00
b5d3c6aaa8 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:48:02 +08:00
5537bc32df 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:45:43 +08:00
5c0c723c5d 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:33:32 +08:00
0ed3b307d9 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:31:59 +08:00
53a603d4ee 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:26:21 +08:00
fbf906bea7 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:16:54 +08:00
a87e8bc3e8 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:04:19 +08:00
a16a67dbc9 📦 docs: 资源商店新增发布资源功能 2024-09-17 15:03:48 +08:00
4c2231feb5 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:59:49 +08:00
3932dd60da 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:57:27 +08:00
3c6380cb82 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:55:05 +08:00
2612f99f35 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:52:26 +08:00
0b4b9a6241 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:48:48 +08:00
2d100885ee 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:46:06 +08:00
cb335720b7 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:44:43 +08:00
dc8ad30b84 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:42:22 +08:00
09e00652c3 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:40:54 +08:00
b5b15c82f8 📦 docs: 资源商店新增发布资源功能 2024-09-17 14:37:45 +08:00
72e71124b8 📝 docs: 资源商店新增发布资源功能
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m14s
2024-09-17 01:35:26 +08:00
d2be2acc95 📝 docs: add egg
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m14s
2024-09-15 00:20:22 +08:00
d95614e960
📝 使用复数代替单数visitor
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 22s
2024-09-10 08:17:24 +08:00
dad9482d7a
📝 update readme
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m43s
2024-09-07 04:42:45 +08:00
fff5d09ad9 📝 docs: remove docstring from src of docs
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m18s
2024-09-06 20:05:29 +08:00
e6ffd1fcc0 📝 docs: remove docstring from src of docs 2024-09-06 19:57:53 +08:00
a97747b7c4 Merge remote-tracking branch 'origin/main' 2024-09-06 19:50:15 +08:00
1921dcd023 📝 docs: remove docstring from src of docs 2024-09-06 19:50:01 +08:00
18af1d00bd
📝 update i18n.ts
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m7s
2024-09-05 11:45:12 +08:00
30cdc1da23
Merge pull request #73 from ElapsingDreams/main
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m6s
📝更新轻雪文档url
2024-09-04 20:45:32 +08:00
ElapsingDreams
bb84958ce4
📝更新轻雪文档url
https://bot.liteyuki.icu/usage/  -->  https://bot.liteyuki.icu/
2024-09-04 20:40:31 +08:00
ElapsingDreams
44de3fd00a
📝更新轻雪文档url
https://bot.liteyuki.icu/usage/  -->  https://bot.liteyuki.icu/usage/basic.html
2024-09-04 20:34:13 +08:00
39b1920532 📝 docs: 修改侧边栏选项 2024-09-04 19:15:11 +08:00
aa591ec29e 📝 更新开发规范 2024-09-04 19:10:32 +08:00
310c3f065d 📝 更新开发规范
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m2s
2024-09-04 03:23:18 +08:00
2311ef82c3
🐛 fix: logo display error 2024-09-04 02:57:21 +08:00
b4b931fc95 📝 更新开发规范 2024-09-04 02:43:44 +08:00
d1b887fcaa 📝https://github.com/jooy2/vitepress-sidebar/issues/170#event-14113011263一起更新
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m5s
2024-09-03 22:26:58 +08:00
5a2990770c 📝 新增gitea数据
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 1m27s
2024-09-02 21:28:08 +08:00
1d0f0a2539 📝 新增gitea数据 2024-09-02 21:27:41 +08:00
dbc4d83b08 📝 新增gitea数据 2024-09-02 21:27:28 +08:00
da905d21bd 📝 新增gitea数据 2024-09-02 21:26:11 +08:00
7d91079500 🚀 workflows: 新增gitea工作流
Some checks failed
Deploy VitePress site to Pages / build (push) Failing after 3m1s
2024-09-02 17:08:29 +08:00
81a006a308 🐛 [docs]: 增加访客记录 2024-09-02 11:20:53 +08:00
be59e241c6 🐛 [docs]: 增加访客记录 2024-09-02 00:13:37 +08:00
e493139d85 🐛 [docs]: 英文文档未适配暗色模式的问题 2024-09-01 22:58:24 +08:00
1f59ec2ef9 📝 [docs]: 新增统计信息 2024-09-01 22:52:00 +08:00
20d05f609d 📝 [docs]: 新增统计信息 2024-09-01 22:42:20 +08:00
0f9683de89 📝 [docs]: 新增统计信息 2024-09-01 22:30:46 +08:00
c805db3371 📝 [docs]: 新增在线展示 2024-09-01 22:14:09 +08:00
58d0d12c1f 📝 [docs]: 新增在线展示 2024-09-01 22:00:17 +08:00
359683dbae 📝 [docs]: 新增在线展示 2024-09-01 21:21:04 +08:00
94cab8b743 📝 [docs]: 新增在线展示 2024-09-01 21:16:45 +08:00
837447b6e4 📝 [docs]: 新增在线展示 2024-09-01 20:45:06 +08:00
ad52eade07 📝 [docs]: 新增在线展示 2024-09-01 20:44:50 +08:00
9cae3edb6b 📝 [docs]: 新增在线展示 2024-09-01 20:39:51 +08:00
0860b61ccd 📝 [docs]: 新增在线展示 2024-09-01 18:29:00 +08:00
d125c52b50 📝 [docs]: 新增在线展示 2024-09-01 18:27:45 +08:00
d485e095ae 📝 [docs]: 新增在线展示 2024-09-01 18:25:37 +08:00
499caca7e3 📝 [docs]: 新增在线展示 2024-09-01 17:57:21 +08:00
83a2d36209 📝 [docs]: 新增在线展示 2024-09-01 17:20:33 +08:00
8b77ced05e 📝 [docs]: 新增在线展示 2024-09-01 16:52:10 +08:00
49a9617f08 📝 [docs]: 修改开源协议 2024-09-01 15:45:03 +08:00
06aa919d9b 📝 [docs]: 修改开源协议 2024-09-01 15:34:52 +08:00
77b77c285b 📝 [docs]: 重新更改开发文档侧边栏顺序 2024-09-01 15:31:22 +08:00
bdc32b26fe 🐛 [plugin]: 暂时关闭轻雪推送功能 2024-09-01 13:22:12 +08:00
736125f4ee 🐛 [plugin]: remove crt-util 2024-09-01 11:27:39 +08:00
89cb75f105 🐛 [plugin]: 修复htmlredner造成的错误 2024-09-01 11:21:45 +08:00
34a6261f27 🐛 [plugin]: 移除sign状态插件 2024-09-01 11:06:30 +08:00
ae18bfaee1 🐛 [channel]: 暂停通道接收功能 2024-09-01 11:05:01 +08:00
8510b0ed3f 🐛 [utils]: htmlrender load error 2024-09-01 11:02:58 +08:00
967f1a0e5b 🐛 [utils]: htmlrender load error 2024-09-01 10:59:52 +08:00
6c1fc62ef1 🔥 [plugin]: 移除liteyuki_docs 2024-09-01 10:53:42 +08:00
433c6b3b85 📝 新增开发规范 2024-09-01 10:51:31 +08:00
ee1ae5a071 📝 新增开发规范 2024-09-01 10:35:54 +08:00
49a15d512e 📝 新增开发规范 2024-09-01 10:35:26 +08:00
fd1d73cc32 📝 添加项目结构说明 | add project structure description 2024-09-01 10:23:06 +08:00
29c2aa9404
📝 fix docs index usage 404 2024-09-01 09:46:47 +08:00
0ec1195930
📝 修复中文文档 主页 使用手册404的问题 2024-09-01 09:45:50 +08:00
d7a625bedb
📝 修正英文文档中的liteyuki docstring 跳转路径 2024-09-01 08:27:50 +08:00
3854376210
📝 修正中文文档中的Liteyuki docstring跳转路径 2024-09-01 08:26:47 +08:00
5253d0e515
Merge pull request #71 from ElapsingDreams/main
暂时使用nonebot_plugin_htmlrender以解决issue#68
2024-09-01 08:14:05 +08:00
Envision
3bc7fa82b1 暂时使用nonebot_plugin_htmlrender以解决issue#68 2024-09-01 01:11:24 +08:00
7d98d5819d
🐛 点击 编辑这页 跳转后404 2024-09-01 00:16:34 +08:00
8316c0ff63
📝 修改函数头 2024-09-01 00:03:20 +08:00
315b8c91e5
Merge pull request #70 from ElapsingDreams/main
🐛“__version__”
2024-08-31 23:52:58 +08:00
ElapsingDreams
405eb10a8a
🐛“__version__” 2024-08-31 22:53:08 +08:00
c3072e93c7 📝 修复暗黑模式下商店物品显示对比度不高的问题 2024-08-31 22:06:04 +08:00
ae34ff622d 📝 插件商店支持 2024-08-31 21:50:58 +08:00
d2704818d9 📝 新增开发指南 2024-08-31 20:23:45 +08:00
2ab4184314 📝 新增开发指南 2024-08-31 20:21:26 +08:00
9aade6599c 📝 文档初步大迁移 vuepress -> vitepress 2024-08-31 19:51:34 +08:00
2f87b06c83 📝 文档初步大迁移 vuepress -> vitepress 2024-08-31 19:07:34 +08:00
8bb3f15bd9 📝 文档初步大迁移 vuepress -> vitepress 2024-08-31 19:05:37 +08:00
7f198c83b5 📝 文档初步大迁移 vuepress -> vitepress 2024-08-31 18:57:48 +08:00
f70c75e9c4 ⬇️ 更新文档样式 2024-08-31 16:17:27 +08:00
be5a4b270d ⬇️ 更新文档样式 2024-08-29 15:50:26 +08:00
50c0216435 ⬇️ 更新文档样式 2024-08-29 14:23:13 +08:00
4910de74fd Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.github/workflows/deploy-docs.yml
#	docs/dev/api/README.md
#	docs/dev/api/bot/README.md
#	docs/dev/api/bot/lifespan.md
#	docs/dev/api/comm/README.md
#	docs/dev/api/comm/channel.md
#	docs/dev/api/comm/event.md
#	docs/dev/api/comm/storage.md
#	docs/dev/api/config.md
#	docs/dev/api/core/README.md
#	docs/dev/api/core/manager.md
#	docs/dev/api/dev/README.md
#	docs/dev/api/dev/observer.md
#	docs/dev/api/dev/plugin.md
#	docs/dev/api/exception.md
#	docs/dev/api/log.md
#	docs/dev/api/message/README.md
#	docs/dev/api/message/event.md
#	docs/dev/api/message/matcher.md
#	docs/dev/api/message/on.md
#	docs/dev/api/message/rule.md
#	docs/dev/api/message/session.md
#	docs/dev/api/mkdoc.md
#	docs/dev/api/plugin/README.md
#	docs/dev/api/plugin/load.md
#	docs/dev/api/plugin/manager.md
#	docs/dev/api/plugin/model.md
#	docs/dev/api/utils.md
#	docs/en/dev/api/README.md
#	docs/en/dev/api/bot/README.md
#	docs/en/dev/api/bot/lifespan.md
#	docs/en/dev/api/comm/README.md
#	docs/en/dev/api/comm/channel.md
#	docs/en/dev/api/comm/event.md
#	docs/en/dev/api/comm/storage.md
#	docs/en/dev/api/config.md
#	docs/en/dev/api/core/README.md
#	docs/en/dev/api/core/manager.md
#	docs/en/dev/api/dev/README.md
#	docs/en/dev/api/dev/observer.md
#	docs/en/dev/api/dev/plugin.md
#	docs/en/dev/api/exception.md
#	docs/en/dev/api/log.md
#	docs/en/dev/api/message/README.md
#	docs/en/dev/api/message/event.md
#	docs/en/dev/api/message/matcher.md
#	docs/en/dev/api/message/on.md
#	docs/en/dev/api/message/rule.md
#	docs/en/dev/api/message/session.md
#	docs/en/dev/api/mkdoc.md
#	docs/en/dev/api/plugin/README.md
#	docs/en/dev/api/plugin/load.md
#	docs/en/dev/api/plugin/manager.md
#	docs/en/dev/api/plugin/model.md
#	docs/en/dev/api/utils.md
#	litedoc/__main__.py
#	litedoc/docstring/docstring.py
#	litedoc/output.py
#	litedoc/style/markdown.py
#	litedoc/syntax/astparser.py
2024-08-29 14:20:19 +08:00
f12b6854b7 ⬇️ 更新文档样式 2024-08-29 14:19:39 +08:00
b0b61fbaf7 ⬇️ 2024-08-29 13:54:24 +08:00
7c0b0df6ed ⬇️ 2024-08-29 13:52:19 +08:00
cb3ee4b72f ⬇️ 2024-08-29 13:50:12 +08:00
3a3ef4d6ae
Merge pull request #69 from ElapsingDreams/patch-1
🌐 翻译修正
2024-08-25 14:26:08 +08:00
ElapsingDreams
9b3dea840e
🌐 翻译修正
🌐 翻译修正
Weather service by QWeather
来源:和风天气官方文档
2024-08-25 13:01:22 +08:00
ca89fa7efd ⬇️ 修复部分依赖问题,目前请勿使用清华镜像源安装 2024-08-24 21:19:51 +08:00
4705eac79c 📦 插件商店上新:liteyukibot-plugin-htmlrender及liteyukibot-plugin-lagrange 2024-08-24 11:57:53 +08:00
ebe0c5bcbb 📦 插件商店上新:liteyukibot-plugin-htmlrender及liteyukibot-plugin-lagrange 2024-08-24 11:39:10 +08:00
93c287bbd9
Merge pull request #67 from EillesWan/main
__liteyuki_plugin_meta__支持
2024-08-24 01:46:39 +08:00
0defb00ede 🧨新增未指定metadata的空判断 2024-08-24 01:43:35 +08:00
81c1d0286d 🎇新增依赖 liteyukibot-plugin-htmlrender 以便兼容其他需要 nonebot-plugin-htmlrender 渲染的插件 2024-08-24 01:14:46 +08:00
fb25005bd5 __liteyuki_plugin_meta__支持 2024-08-24 01:09:54 +08:00
2eb5aae23f [nonebot-plugin]状态提供更多品牌的cpu支持 2024-08-23 23:47:01 +08:00
a7d0560932
Merge pull request #66 from EillesWan/main
👻新增内置的页面渲染组件
2024-08-23 20:50:57 +08:00
391f112bb3 😅少改个东西.给改过去 2024-08-23 18:10:09 +08:00
bc8d13ba8a 😅不小心多改了个东西,给改回来 2024-08-23 18:08:11 +08:00
e8ec2ee28a Merge branch 'main' of https://github.com/LiteyukiStudio/LiteyukiBot 2024-08-23 17:58:49 +08:00
b6c8fcbccd 🧐内置页面渲染组件,弃用nonebot-plugin-htmlrender,避免playwright对多平台的不友好绑架 2024-08-23 17:58:36 +08:00
71476560e4 📝 商店新增anti-dislink插件和tag展示 2024-08-22 10:41:41 +08:00
aa2d182840 🐛 修复轻雪与NoneBot对接回复的错误 2024-08-22 10:10:03 +08:00
540 changed files with 10180 additions and 20195 deletions

0
.dockerignore Normal file → Executable file
View File

2
.domain Normal file
View File

@ -0,0 +1,2 @@
bot.liteyuki.icu
docs.app.bot.pages.git.liteyuki.icu

1
.github/ISSUE_TEMPLATE/config.yml vendored Executable file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -0,0 +1,59 @@
name: Publish Resource
title: "Resource: {name}"
description: Publish the resource to the LiteyukiBot official store
labels: [ "Resource" ]
body:
- type: input
id: name
attributes:
label: Name
description: The readable name of the resource pack
placeholder: e.g. Cute UI Resource Pack
validations:
required: true
- type: input
id: description
attributes:
label: Description
description: A brief description of the resource
placeholder: e.g. Makes the rendering card style more beautiful
validations:
required: true
- type: input
id: author
attributes:
label: Author
description: The GitHub username of the author
placeholder: e.g. snowykami
validations:
required: true
- type: input
id: link
attributes:
label: Link
description: Direct download link of the resource pack
placeholder: e.g. https://aaa.com/r.zip
validations:
required: true
- type: input
id: homepage
attributes:
label: Homepage
description: Homepage of the resource pack
placeholder: e.g. https://github.com/user/repo
validations:
required: false
- type: input
id: tags
attributes:
label: Tags
description: Tags
placeholder: 'e.g. [{"label": "Tag Name", "color": "#ea5252"}]'
value: '[ { "label": "Text", "color": "#a2d8f4" } ]'
validations:
required: false

View File

@ -0,0 +1,59 @@
name: 发布资源
title: "Resource: {name}"
description: 发布资源到轻雪机器人官方商店
labels: [ "Resource" ]
body:
- type: input
id: name
attributes:
label: 名称
description: 资源包的可读名称
placeholder: e.g. 可爱UI资源包
validations:
required: true
- type: input
id: description
attributes:
label: 描述
description: 资源的简短描述
placeholder: e.g. 使渲染卡片的样式更美观
validations:
required: true
- type: input
id: author
attributes:
label: 作者
description: 作者的github用户名
placeholder: e.g. snowykami
validations:
required: true
- type: input
id: link
attributes:
label: 下载链接
description: 资源包直接下载链接
placeholder: e.g. https://aaa.com/r.zip
validations:
required: true
- type: input
id: homepage
attributes:
label: 主页
description: 资源包主页
placeholder: e.g. https://github.com/user/repo
validations:
required: false
- type: input
id: tags
attributes:
label: 标签
description: 标签
placeholder: 'e.g. [{"label": "标签名", "color": "#ea5252"}]'
value: '[ { "label": "标签名", "color": "#a2d8f4" } ]'
validations:
required: false

0
.github/ISSUE_TEMPLATE/问题反馈.md vendored Normal file → Executable file
View File

0
.github/dependabot.yml vendored Normal file → Executable file
View File

View File

@ -1,44 +0,0 @@
# 问题反馈
## **请确保**
- 已认真阅读[文档]("https://bot.liteyuki.icu"),该问题不是文档提及的或你自己操作不当造成的
- 你的问题是在最新版本的代码上测试的
- 请勿重复提交相同或类似的issue
## **描述问题**
请在此简单描述问题
## **如何复现**
请阐述一下如何重现这个问题
### 预期
描述你期望发生的事情
### 实际
描述实际发生的事情
## **日志或截图**
```
日志内容
```
## **设备信息**
- **系统**: [例如 Ubuntu 22.04]
- **CPU**: [例如 Intel i7-7700K]
- **内存**: [例如 16GB]
- **Python**: [例如CPython 3.10.7]
**补充内容**
可选,推荐提供`pip freeze`的输出,以及其他相关信息,以及你的建议

43
.github/workflows/build-image.yml vendored Executable file
View File

@ -0,0 +1,43 @@
name: Docker Image Build
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: write
concurrency:
group: docker-build
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USERNAME }}
password: ${{ secrets.GHCR_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/liteyukistudio/liteyukibot:latest
- name: Log out from GitHub Container Registry
run: docker logout ghcr.io

View File

@ -0,0 +1,66 @@
name: Deploy VitePress site to Liteyuki PaaS
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: write
statuses: write
concurrency:
group: pages
cancel-in-progress: false
env:
MELI_SITE: "800a7c09-dd9c-4ba7-a43f-af9bc69808c4"
jobs:
# 构建工作
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # 如果未启用 lastUpdated则不需要
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: "3.11"
- name: Setup API markdown
run: |-
python -m pip install litedoc
litedoc liteyuki -o docs/zh/dev/api -l zh-Hans -cd class -fd func -md func -vd var -bu https://github.com/LiteyukiStudio/LiteyukiBot/tree/main/liteyuki/
litedoc liteyuki -o docs/en/dev/api -l en -cd class -fd func -md func -vd var -bu https://github.com/LiteyukiStudio/LiteyukiBot/tree/main/liteyuki/
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
run_install: true
version: 8
- name: 设置 Node.js
run: |-
cd docs
pnpm install
- name: 构建文档
env:
NODE_OPTIONS: --max_old_space_size=8192
run: |-
cd docs
pnpm run docs:build
> .vitepress/dist/.nojekyll
- name: "发布"
run: |
npx -p "@getmeli/cli" meli upload docs/.vitepress/dist \
--url "https://dash.apage.dev" \
--site "$MELI_SITE" \
--token "$MELI_TOKEN" \
--release "$GITHUB_SHA"
env:
MELI_TOKEN: ${{ secrets.MELI_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,61 +0,0 @@
name: 部署文档
on:
push:
branches:
# 确保这是你正在使用的分支名称
- main
permissions:
contents: write
jobs:
deploy-gh-pages:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
# 如果你文档需要 Git 子模块,取消注释下一行
# submodules: true
- name: 安装 pnpm
uses: pnpm/action-setup@v2
with:
run_install: true
version: 8
- name: 设置 Node.js
run: |-
cd docs
pnpm install
- name: 设置Python
uses: actions/setup-python@v2
with:
python-version: '3.10'
- name: 生成API markdown
run: |-
python -m pip install pydantic
python liteyuki/mkdoc.py
- name: 构建文档
env:
NODE_OPTIONS: --max_old_space_size=8192
run: |-
cd docs
pnpm run docs:build
> .vuepress/dist/.nojekyll
- name: 部署文档
uses: JamesIves/github-pages-deploy-action@v4
with:
# 这是文档部署到的分支名称
branch: gh-pages
folder: docs/.vuepress/dist

51
.github/workflows/issue_handler.yml vendored Executable file
View File

@ -0,0 +1,51 @@
name: Issue Handler
on:
issues:
types: [ opened, edited, closed ]
concurrency:
group: issue_handler
cancel-in-progress: false
jobs:
check-issue:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Check issue title
id: check_title
run: |
ISSUE_TITLE="${{ github.event.issue.title }}"
if [[ "$ISSUE_TITLE" == Plugin:* || "$ISSUE_TITLE" == Resource:* ]]; then
echo "Title starts with Plugin: or Resource:."
echo "::set-output name=title_match::true"
else
echo "Title does not start with Plugin: or Resource:."
echo "::set-output name=title_match::false"
fi
- name: Set up Python
uses: actions/setup-python@v2
if: steps.check_title.outputs.title_match == 'true'
with:
python-version: '3.12'
- name: Install dependencies
if: steps.check_title.outputs.title_match == 'true'
run: |
echo "Installing dependencies."
pip install -r liteyuki_flow/requirements.txt
- name: Run Plugin/Resource issue handler
if: steps.check_title.outputs.title_match == 'true'
run: |
echo "Running Plugin/Resource issue handler."
python -m liteyuki_flow --handle
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPOSITORY: ${{ github.repository }}
ACT_TYPE: ${{ github.event.action }}

30
.github/workflows/pre-commit.yml vendored Executable file
View File

@ -0,0 +1,30 @@
name: Pre-commit checks
on: [push, pull_request]
jobs:
pre-commit:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13'] # 添加你想要测试的 Python 版本
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }} # 使用矩阵中的 Python 版本
- name: Install dependencies
run: |
python -m pip install pdm
python -m pip install pre-commit
pdm config python.use_venv false
pdm install --no-lock
pre-commit install
- name: Run pre-commit
run: pre-commit run --all-files

5
.github/workflows/pypi-publish.yml vendored Normal file → Executable file
View File

@ -1,8 +1,9 @@
name: Publish
on:
release:
types: [published]
push:
tags:
- 'v*'
jobs:
pypi-publish:

23
.gitignore vendored Normal file → Executable file
View File

@ -17,14 +17,13 @@ __pycache__/
/plugins/
#config
config/
/config/
!config/default.yml
_config.yml
config.yml
config.example.yml
# vuepress
.github
# mupy
mypy.ini
@ -54,4 +53,22 @@ dist
doc
mkdoc2.py
result.json
result.json
# litedoc
docs/zh/dev/api
docs/en/dev/api
mkdoc.bat
# vitepress
docs/.vitepress/dist/
docs/.vitepress/cache
docs/.vitepress/.temp
# python toolchain
.mypy_cache/
.pytest_cache/
# pdm
__pypackages__/
pdm.lock

26
.pre-commit-config.yaml Executable file
View File

@ -0,0 +1,26 @@
fail_fast: true
repos:
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
args: [--config=./pyproject.toml]
- repo: https://github.com/timothycrosley/isort
rev: 5.13.2
hooks:
- id: isort
args: ["--profile", "black"]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
- id: mypy
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files

6
Dockerfile Normal file → Executable file
View File

@ -2,17 +2,15 @@ FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/python:3.10-slim
ENV TZ Asia/Shanghai
COPY docker/sources.list /etc/apt/sources.list
RUN apt-get update && apt-get install -y git
WORKDIR /liteyukibot
COPY . /liteyukibot
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN pip install --no-cache-dir -r requirements.txt
RUN apt-get install -y libnss3 libnspr4 libdbus-1-3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libxkbcommon0 libasound2
RUN apt-get install -y libnss3 libnspr4 libdbus-1-3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libxkbcommon0 libasound2 libpango-1.0-0 libcairo2
EXPOSE 20216

0
LICENSE Normal file → Executable file
View File

60
README.md Normal file → Executable file
View File

@ -1,52 +1,70 @@
<div align="center">
[//]: # (<img src="https://cdn.liteyuki.icu/static/svg/lylogo-full.svg" style="align-content: center; width: 50%; margin-top:10%;" alt="a">)
[![][banner]][lightyuki-link]
[//]: # (<img src="https://cdn.liteyuki.icu/logos/bot.svg" style="align-content: center; width: 50%; margin-top:10%;" alt="a">)
[![][banner]][liteyuki-link]
<h2><a href="https://bot.liteyuki.icu"> <span style="color: #a2d8f4">轻雪</span> <span style="color: #d0e9ff">6</span></a></h2>
<h4> <span style="color: #a2d8f4">✨ 轻量,高效,易于扩展✨</span></h4>
[![][OneBot]][onebot-link]
[![][NoneBot2]][nonebot-link]
[![][Liteyuki6.0]][lightyuki-link]
[![][Liteyuki6.0]][liteyuki-link]
[![][Python3.10+]][python-link]
[![][Usage]][usage-link]
[![][Repo]][repo-link]
[![][Github]][github-link]
[![][LiteyukiLab]][liteyukilab-link]
![docs uptime](https://uptime.liteyuki.icu/api/badge/8/uptime?labelPrefix=Docs+&style=for-the-badge)
- 基于[Nonebot2](https://github.com/nonebot/nonebot2),有良好的生态支持
</div>
## 关于
访问[轻雪6.0](https://bot.liteyuki.icu)主页获取更多信息
## 特点及优势
- 原生支持与任意`Python`Bot框架互联有良好的生态支持
- 开箱即用,无需复杂配置
- 集成包管理器,支持一键安装插件
- 支持OneBot标准通信但不限于此
- 自定义主题支持,满足审美需求
- 国际化支持,支持多种语言
- 高性能500插件2s内启动
<h3>👇更多内容请访问👇</h3>
<h2><a href="https://bot.liteyuki.icu">轻雪机器人主页</a></h2>
</div>
## 服务及支持(敬请期待)
- 提供Liteyuki Cloud官方的容器化托管服务无需担心服务器问题
### 感谢
- [NoneBot2](https://nonebot.dev)提供的框架支持
- [nonebot-plugin-htmlrender](https://github.com/kexue-z/nonebot-plugin-htmlrender)提供的渲染功能
- [nonebot-plugin-alconna](https://github.com/ArcletProject/nonebot-plugin-alconna)提供的命令解析功能
**👇所有内容请访问👇**: [bot.liteyuki.icu](https://bot.liteyuki.icu)
## 参考及鸣谢
- [nonebot-plugin-uninfo](https://github.com/RF-Tar-Railt/nonebot-plugin-uninfo)为会话部分用户信息提供了参考
- [nonebot-plugin-alconna](https://github.com/nonebot/plugin-alconna/)为消息部分提供了参考
[OneBot]: https://img.shields.io/badge/OneBot-11/12-blue?style=for-the-badge
## 其他
- 本仓库是一个monorepo包含了框架文档测试内置资源包内置插件预设配置等
[NoneBot2]: https://img.shields.io/badge/Nonebot-2-red?style=for-the-badge
[Liteyuki6.0]: https://img.shields.io/badge/Liteyuki-6.0-blue?style=for-the-badge
[Python3.10+]: https://img.shields.io/badge/Python-3.10+-blue?style=for-the-badge
[Usage]: https://img.shields.io/badge/文档-页面-blue?style=for-the-badge
[Usage]: https://img.shields.io/badge/主页-文档-blue?style=for-the-badge
[onebot-link]:https://onebot.dev/
[Repo]: https://img.shields.io/badge/官方托管-仓库-blue?style=for-the-badge
[Github]: https://img.shields.io/badge/Github-仓库-blue?style=for-the-badge
[LiteyukiLab]: https://img.shields.io/badge/轻雪社区-官方-blue?style=for-the-badge
[nonebot-link]:https://nonebot.dev/
[lightyuki-link]:/
[python-link]:https://www.python.org/
[usage-link]:https://bot.liteyuki.icu/
[banner]: https://socialify.git.ci/LiteyukiStudio/LiteyukiBot/image?description=1&forks=1&issues=1&Plus&pulls=1&stargazers=1&theme=Auto&logo=https%3a%2f%2fcdn.liteyuki.icu%2fstatic%2fsvg%2flylogo-full.svg
[liteyuki-link]:https://bot.liteyuki.icu/
[repo-link]:https://git.liteyuki.icu/bot/app
[github-link]:https://github.com/LiteyukiStudio/LiteyukiBot
[liteyukilab-link]:https://lab.liteyuki.icu/@LiteyukiBot
[banner]: https://socialify.git.ci/LiteyukiStudio/LiteyukiBot/image?description=1&font=Source+Code+Pro&forks=1&issues=1&logo=https%3A%2F%2Fcdn.liteyuki.icu%2Flogos%2Fbot.svg&name=1&owner=1&pattern=Floating+Cogs&pulls=1&stargazers=1&theme=Auto

6
config/default.yml Normal file → Executable file
View File

@ -1,8 +1,10 @@
nonebot:
host: 127.0.0.1
host: 0.0.0.0
port: 20216
command_start: ["", "/"]
nickname: [ "liteyuki" ]
default_language: zh
driver: ~fastapi+~httpx+~websockets
alconna_use_command_start: true
alconna_use_command_start: true
gotify_token: "empty token"

12
docker-compose.yml Executable file
View File

@ -0,0 +1,12 @@
version: '3.8'
services:
app:
image: git.liteyuki.icu/bot/app:latest
ports:
- "20216:20216"
environment:
- TZ=Asia/Chongqing
volumes:
- .:/liteyukibot
command: [ "python", "main.py" ]

0
docker/sources.list Normal file → Executable file
View File

5
docs/.gitignore vendored
View File

@ -1,5 +0,0 @@
node_modules/
./.vuepress/.cache/
./.vuepress/.temp/
./.vuepress/dist/

138
docs/.vitepress/config/common.ts Executable file
View File

@ -0,0 +1,138 @@
// 共有配置项导入index用
import { defineConfig } from "vitepress";
import { generateSidebar } from "vitepress-sidebar";
import { zh } from "./zh";
import { en } from "./en";
let defaultLocale = "zh";
const commonSidebarOptions = {
collapsed: true,
convertSameNameSubFileToGroupIndexPage: true,
useTitleFromFrontmatter: true,
useFolderTitleFromIndexFile: true,
useFolderLinkFromIndexFile: true,
includeFolderIndexFile: true,
sortMenusByFrontmatterOrder: true,
rootGroupText: "LITEYUKIBOT",
};
/**
* Generate sidebar config
* multiple languages and sections
* @returns {any[]}
*/
function generateSidebarConfig(): any[] {
let sections = ["dev", "store", "usage", "deploy"];
let languages = ["zh", "en"];
let ret = [];
for (let language of languages) {
for (let section of sections) {
if (language === defaultLocale) {
ret.push({
basePath: `/${section}/`,
scanStartPath: `${language}/${section}`,
resolvePath: `/${section}/`,
...commonSidebarOptions,
});
} else {
ret.push({
basePath: `/${language}/${section}/`,
scanStartPath: `${language}/${section}`,
resolvePath: `/${language}/${section}/`,
...commonSidebarOptions,
});
}
}
}
return ret;
}
export const common = defineConfig({
head: [
// 配置favicon.ico
["link", { rel: "icon", type: "image/x-icon", href: "favicon.ico" }],
[
"link",
{
rel: "stylesheet",
href: "https://fonts.font.im/css?family=Cousine:400,400i,700,700i|Poppins:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i",
},
],
["script", { src: "https://cdn.liteyuki.icu/js/liteyuki_footer.js" }],
],
rewrites: {
[`${defaultLocale}/:rest*`]: ":rest*",
},
cleanUrls: false,
themeConfig: {
logo: {
light: "https://cdn.liteyuki.icu/logos/bot.svg",
dark: "https://cdn.liteyuki.icu/logos/bot.svg",
alt: "LiteyukiBot Logo",
},
sidebar: generateSidebar([...generateSidebarConfig()]),
socialLinks: [
{ icon: "github", link: "https://github.com/LiteyukiStudio/LiteyukiBot" },
{
icon: {
svg: '<svg t="1725391346807" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5067" width="256" height="256"><path d="M1004.692673 466.396616l-447.094409-447.073929c-25.743103-25.763582-67.501405-25.763582-93.264987 0l-103.873521 103.873521 78.171378 78.171378c12.533635-6.00058 26.562294-9.359266 41.389666-9.359266 53.02219 0 96.00928 42.98709 96.00928 96.00928 0 14.827372-3.358686 28.856031-9.359266 41.389666l127.97824 127.97824c12.533635-6.00058 26.562294-9.359266 41.389666-9.359266 53.02219 0 96.00928 42.98709 96.00928 96.00928s-42.98709 96.00928-96.00928 96.00928-96.00928-42.98709-96.00928-96.00928c0-14.827372 3.358686-28.856031 9.359266-41.389666l-127.97824-127.97824c-3.051489 1.454065-6.184898 2.744293-9.379746 3.870681l0 266.97461c37.273227 13.188988 63.99936 48.721433 63.99936 90.520695 0 53.02219-42.98709 96.00928-96.00928 96.00928s-96.00928-42.98709-96.00928-96.00928c0-41.799262 26.726133-77.331707 63.99936-90.520695l0-266.97461c-37.273227-13.188988-63.99936-48.721433-63.99936-90.520695 0-14.827372 3.358686-28.856031 9.359266-41.389666l-78.171378-78.171378-295.892081 295.871601c-25.743103 25.784062-25.743103 67.542365 0 93.285467l447.114889 447.073929c25.743103 25.743103 67.480925 25.743103 93.264987 0l445.00547-445.00547c25.763582-25.763582 25.763582-67.542365 0-93.285467z" fill="#a2d8f4" p-id="5068"></path></svg>',
},
link: "https://git.liteyuki.icu/bot/app",
},
{
icon: {
svg: '<svg t="1736700504329" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14158" width="200" height="200"><path d="M944.355556 142.222222c-17.066667-22.755556-45.511111-34.133333-79.644445-34.133333-28.444444 0-68.266667 5.688889-108.088889 22.755555h-5.688889c17.066667 11.377778 34.133333 28.444444 51.2 39.822223 56.888889-17.066667 91.022222-11.377778 96.711111 0 11.377778 11.377778 5.688889 45.511111-22.755555 91.022222 11.377778 17.066667 17.066667 34.133333 28.444444 51.2 0 0 0 5.688889 5.688889 5.688889 22.755556-34.133333 34.133333-62.577778 45.511111-91.022222 11.377778-28.444444 5.688889-62.577778-11.377777-85.333334z" p-id="14159" fill="#a2d8f4"></path><path d="M267.377778 512a45.511111 45.511111 0 1 0 91.022222 0 45.511111 45.511111 0 1 0-91.022222 0Z" p-id="14160" fill="#a2d8f4"></path><path d="M625.777778 614.4c-113.777778 85.333333-227.555556 153.6-324.266667 193.422222-11.377778 5.688889-17.066667 5.688889-28.444444 11.377778 22.755556 17.066667 51.2 34.133333 79.644444 45.511111 51.2 22.755556 108.088889 34.133333 164.977778 34.133333s113.777778-11.377778 164.977778-34.133333c51.2-22.755556 96.711111-51.2 136.533333-91.022222 39.822222-39.822222 68.266667-85.333333 91.022222-130.844445 22.755556-51.2 34.133333-108.088889 34.133334-159.288888 0-51.2-11.377778-102.4-28.444445-153.6-5.688889 5.688889-11.377778 17.066667-17.066667 22.755555-68.266667 79.644444-164.977778 176.355556-273.066666 261.688889zM813.511111 187.733333c-5.688889-5.688889-11.377778-5.688889-11.377778-11.377777-17.066667-17.066667-34.133333-28.444444-51.2-39.822223-22.755556-11.377778-45.511111-28.444444-68.266666-34.133333-56.888889-28.444444-108.088889-39.822222-164.977778-39.822222s-113.777778 11.377778-164.977778 34.133333c-51.2 22.755556-96.711111 51.2-136.533333 91.022222-39.822222 34.133333-68.266667 79.644444-91.022222 130.844445-22.755556 51.2-34.133333 108.088889-34.133334 159.288889 0 51.2 11.377778 96.711111 22.755556 142.222222-22.755556 34.133333-39.822222 68.266667-51.2 96.711111-11.377778 39.822222-5.688889 68.266667 11.377778 91.022222 17.066667 22.755556 45.511111 34.133333 79.644444 34.133334h11.377778c28.444444 0 62.577778-11.377778 96.711111-22.755556-17.066667-11.377778-34.133333-28.444444-51.2-39.822222-51.2 11.377778-85.333333 11.377778-96.711111 0 0-17.066667 5.688889-45.511111 34.133333-96.711111 17.066667 34.133333 39.822222 62.577778 68.266667 91.022222h5.688889c17.066667-5.688889 39.822222-11.377778 62.577777-17.066667 91.022222-34.133333 204.8-102.4 307.2-187.733333 108.088889-85.333333 199.111111-170.666667 256-250.311111l34.133334-51.2c-22.755556-28.444444-39.822222-56.888889-68.266667-79.644445z m-500.622222 420.977778c-56.888889 0-102.4-45.511111-102.4-102.4s45.511111-102.4 102.4-102.4S409.6 455.111111 409.6 512c0 51.2-45.511111 96.711111-96.711111 96.711111z" p-id="14161" fill="#a2d8f4"></path></svg>',
},
link: "https://lab.liteyuki.icu/@LiteyukiBot",
},
],
search: {
provider: "local",
options: {
locales: {
root: {
translations: {
button: {
buttonText: "搜索文档",
buttonAriaLabel: "打开搜索框",
},
modal: {
noResultsText: "没有找到搜索结果",
resetButtonTitle: "清除查询条件",
footer: {
selectText: "选择",
navigateText: "切换",
},
},
},
},
en: {
translations: {
button: {
buttonText: "Search",
buttonAriaLabel: "Search",
},
modal: {
noResultsText: "No results found",
resetButtonTitle: "Reset search query",
footer: {
selectText: "Select",
navigateText: "Navigate",
},
},
},
},
},
},
},
},
sitemap: {
hostname: "https://bot.liteyuki.icu",
},
lastUpdated: true,
locales: {
root: { label: "简体中文", ...zh },
en: { label: "English", ...en },
},
});

35
docs/.vitepress/config/en.ts Executable file
View File

@ -0,0 +1,35 @@
import {defineConfig} from 'vitepress'
import {ThemeConfig} from "./utils";
export const en = defineConfig({
lang: "en-US",
title: "LiteyukiBot",
description: "A high-performance, easy-to-use chatbot framework and application",
themeConfig: {
nav: [
{text: 'Deploy', link: '/en/deploy/install'},
{text: 'Usage', link: '/en/usage/basic'},
{text: 'Extension', link: '/en/store/resource'},
{text: 'Develop', link: '/en/dev/guide'},
],
docFooter: {
prev: 'Prev Page',
next: 'Next Page'
},
editLink: ThemeConfig.getEditLink(
'Edit this page on GitHub',
),
footer: {
message: 'Page is deployed at <a href="https://meli.liteyuki.icu" target="_blank">Liteyuki Meli</a> and accelerated by <a href="https://cdn.liteyuki.icu" target="_blank">Liteyukiflare</a><br>Documentation built with <a href="https://vitepress.dev/">VitePress</a> | API references generated by <a href="https://github.com/LiteyukiStudio/litedoc">litedoc</a>',
copyright: ThemeConfig.copyright
},
outline: ThemeConfig.getOutLine("Page Content"),
langMenuLabel: 'Language',
returnToTopLabel: 'Back to top',
sidebarMenuLabel: 'Menu',
darkModeSwitchLabel: 'Theme',
lightModeSwitchTitle: 'Light Mode',
darkModeSwitchTitle: 'Dark Mode',
},
})

View File

@ -0,0 +1,6 @@
import {defineConfig} from "vitepress";
import {common} from './common'
export default defineConfig({
...common,
})

40
docs/.vitepress/config/utils.ts Executable file
View File

@ -0,0 +1,40 @@
// 本模块储存一些工具函数和引用
/**
* GetEditLink Options
* @param text Edit link text
*/
export const ThemeConfig = {
getEditLink: (editPageText: string): { pattern: (params: { filePath: string; }) => string; text: string; } => {
return {
pattern: ({filePath}: { filePath: string; }): string => {
// 匹配 /dev/api或 /{lang}/dev/api
const regex = /^[^\/]+\/dev\/api/;
console.log(filePath);
if (regex.test(filePath)) {
// remove {lang}/api prefix
filePath = filePath.replace(regex, '')
.replace('index.md', '__init__.py')
.replace('.md', '.py');
// 若文件名(不含扩展)和上级文件夹相同,返回文件夹/__init__.py
if (filePath.split('/').pop().split('.')[0] === filePath.split('/').slice(-2, -1)[0]) {
filePath = filePath.split('/').slice(0, -1).join('/') + '/__init__.py';
}
return `https://github.com/LiteyukiStudio/LiteyukiBot/tree/main/liteyuki${filePath}`;
} else {
return `https://github.com/LiteyukiStudio/LiteyukiBot/tree/main/docs/${filePath}`;
}
},
text: editPageText
};
},
getOutLine: (label: string): { label: string; level: [number, number]; } => {
return {
label: label,
level: [2, 6]
};
},
copyright: 'Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved'
}

35
docs/.vitepress/config/zh.ts Executable file
View File

@ -0,0 +1,35 @@
import {defineConfig} from 'vitepress'
import {ThemeConfig} from "./utils";
export const zh = defineConfig({
lang: "zh-Hans",
title: "轻雪机器人",
description: "一个综合性的机器人应用及管理框架",
themeConfig: {
nav: [
{text: '部署', link: '/deploy/install'},
{text: '使用', link: '/usage/basic'},
{text: '扩展', link: '/store/resource'},
{text: '开发', link: '/dev/guide'},
],
docFooter: {
prev: '上一页',
next: '下一页'
},
editLink: ThemeConfig.getEditLink(
'在 GitHub 上编辑此页',
),
footer: {
message: '网站部署在 <a href="https://meli.liteyuki.icu" target="_blank">Liteyuki Meli</a> 由 <a href="https://cdn.liteyuki.icu" target="_blank">Liteyukiflare</a> 提供加速服务<br>文档由 <a href="https://vitepress.dev/">VitePress</a> 构建 | API引用由 <a href="https://github.com/LiteyukiStudio/litedoc">litedoc</a> 生成',
copyright: ThemeConfig.copyright
},
outline: ThemeConfig.getOutLine("页面内容"),
langMenuLabel: '语言',
returnToTopLabel: '返回顶部',
sidebarMenuLabel: '菜单',
darkModeSwitchLabel: '主题',
lightModeSwitchTitle: '轻色模式',
darkModeSwitchTitle: '深色模式',
},
})

18
docs/.vitepress/theme/index.ts Executable file
View File

@ -0,0 +1,18 @@
import DefaultTheme from 'vitepress/theme'
import './liteyuki.scss'
import StatsBar from '../../components/StatsBar.vue'
import PluginStore from '../../components/PluginStore.vue'
import ResStore from '../../components/ResStore.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('StatsBar', StatsBar);
app.component('PluginStore', PluginStore);
app.component('ResStore', ResStore);
},
Layout: StatsBar
}

View File

@ -0,0 +1,149 @@
:root {
--vp-c-brand-1: #149ef8;
--vp-c-brand-2: #0434ad;
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #34a3fe 30%, #8d44ff);
--vp-home-hero-image-background-image: linear-gradient(-45deg, #d0e9ff 50%, #a2d8f4 50%);
--vp-home-hero-image-filter: blur(44px);
--vp-c-gray-1: #eee;
--vp-c-gray-2: #aaa;
--border-radius-1: 10px;
--border-radius-2: 20px;
--border-radius-3: 40px;
--vp-font-family-base: 'Poppins', 'Punctuation SC', 'Inter', ui-sans-serif, system-ui,
'PingFang SC', 'Noto Sans CJK SC', 'Noto Sans SC', 'Heiti SC',
'Microsoft YaHei', 'DengXian', sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
--vp-font-family-mono: 'Cousine', monospace;
--red: #ef4444;
--liteyuki-color: #149ef8;
--button-radius: 6px;
}
.dark {
--vp-home-hero-image-background-image: linear-gradient(-45deg, #004785 50%, #0374ad 50%);
--vp-c-gray-1: #333;
--vp-c-gray-2: #666;
}
.tab-buttons {
padding: 7px;
flex: 1;
display: flex;
justify-content: flex-start;
height: 60%;
align-items: center;
}
.tab-title {
text-align: center;
justify-content: center;
flex: 1;
}
.item-search-box {
border-radius: 100px;
width: 80%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ccc;
}
.search-box-div {
display: flex;
justify-content: space-around;
margin: 10px 0;
}
.item-search-box {
width: 80%;
}
.item-card {
position: relative;
border-radius: 15px;
background-color: var(--vp-c-gray-1);
height: 160px;
padding: 16px;
margin: 10px;
box-sizing: border-box;
transition: background 0.3s ease;
}
.item-name {
font-size: 20px;
margin-bottom: 10px;
}
.item-description {
color: var(--vp-c-gray-2);
font-size: 13px;
white-space: pre-wrap;
}
.author-info {
display: flex;
justify-content: left;
align-items: center;
}
.author-name {
font-size: 15px;
font-weight: normal;
}
.avatar {
border-radius: 50%;
margin: 0 10px;
}
/*store*/
.store-tabs {
display: flex;
justify-content: flex-end;
margin: 10px 0;
}
.publish-button {
right: 10px;
bottom: 10px;
padding: 5px 10px;
border-radius: 10px;
background-color: var(--vp-c-brand-1);
color: white;
font-size: 15px;
cursor: pointer;
}
.pub-window {
input {
width: 100%;
padding: 10px;
margin: 10px 0;
border-radius: 10px;
border: 1px solid #ccc;
}
}
.pub-option {
margin: 10px;
padding: 5px;
border: 2px solid var(--vp-c-gray-1);
border-radius: var(--button-radius);
background-color: var(--vp-c-gray-1);
&.close {
}
&.submit {
background-color: var(--vp-c-brand-1);
}
}

View File

@ -1,21 +0,0 @@
import {defineClientConfig} from "vuepress/client";
import resourceStoreComp from "./components/ResStore.vue";
import pluginStoreComp from "./components/PluginStore.vue";
import dashComp from "./components/Dash.vue";
import homeComp from "./components/Home.vue";
import geoComp from "./components/Geo.vue";
// import ElementPlus from 'element-plus';
export default defineClientConfig({
enhance: ({app, router, siteData}) => {
app.component("homeComp", homeComp);
app.component("dashComp", dashComp);
app.component("resourceStoreComp", resourceStoreComp);
app.component("pluginStoreComp", pluginStoreComp);
app.component("geoComp", geoComp);
// app.use(ElementPlus);
},
});

View File

@ -1,62 +0,0 @@
<script setup lang="ts">
import {computed, ref} from 'vue'
import ItemCard from './PluginItemCard.vue'
let filteredItems = computed(() => {
if (!search.value) {
return items.value
}
return items.value.filter(item =>
item.name.toLowerCase().includes(search.value.toLowerCase()) ||
item.desc.toLowerCase().includes(search.value.toLowerCase()) ||
item.author.toLowerCase().includes(search.value.toLowerCase()) ||
item.module_name.toLowerCase().includes(search.value.toLowerCase())
)
})
// Nonebot
let items = ref([])
let search = ref('')
//
fetch("/assets/plugins.json")
.then(response => response.json())
.then(data => {
items.value = data
})
.catch(error => console.error(error))
//
fetch('https://registry.nonebot.dev/plugins.json')
.then(response => response.json())
.then(data => {
items.value = items.value.concat(data)
})
</script>
<template>
<div class="market">
<h1>插件商店</h1>
<p>内容来自<a href="https://nonebot.dev/store/plugins">NoneBot插件商店</a>和轻雪商店在此仅作引用具体请访问NoneBot插件商店</p>
<!-- 搜索框-->
<div class="search-box-div"><input class="item-search-box" type="text" placeholder="搜索插件" v-model="search"/></div>
<div class="items">
<!-- 使用filteredItems来布局商品 -->
<ItemCard v-for="item in filteredItems" :key="item.id" :item="item"/>
</div>
</div>
</template>
<style scoped>
h1 {
color: #00a6ff;
text-align: center;
font-weight: bold;
}
.items {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 10px;
}
</style>

View File

@ -1,53 +0,0 @@
<script setup lang="ts">
import {computed, ref} from 'vue'
import ItemCard from './ResItemCard.vue'
import * as url from "node:url";
// public/assets/resources.json
let filteredItems = computed(() => {
if (!search.value) {
return items.value.reverse()
}
return items.value.filter(item =>
item.name.toLowerCase().includes(search.value.toLowerCase()) ||
item.description.toLowerCase().includes(search.value.toLowerCase()) ||
item.author.toLowerCase().includes(search.value.toLowerCase())
).reverse()
})
// Nonebot
let items = ref([])
let search = ref('')
fetch("/assets/resources.json")
.then(response => response.json())
.then(data => {
items.value = data
})
.catch(error => console.error(error))
//
</script>
<template>
<div class="market">
<h1>主题/资源商店</h1>
<div class="search-box-div"><input class="item-search-box" type="text" placeholder="搜索资源" v-model="search" /></div>
<div class="items">
<!-- 使用filteredItems来布局商品 -->
<ItemCard v-for="item in filteredItems" :key="item.id" :item="item"/>
</div>
</div>
</template>
<style scoped>
h1 {
color: #00a6ff;
text-align: center;
font-weight: bold;
}
.items {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 10px;
}
</style>

View File

@ -1,47 +0,0 @@
import {defineUserConfig} from "vuepress";
import theme from "./theme.js";
import viteBundler from "@vuepress/bundler-vite";
export default defineUserConfig({
base: "/",
locales: {
"/": {
// 设置正在使用的语言
lang: "zh-CN",
title: "LiteyukiBot 轻雪机器人",
description: "LiteyukiBot | 轻雪机器人 | An OneBot Standard ChatBot | 一个OneBot标准的聊天机器人",
head: [
["script", {"src": "/js/zh/get_data.js", "type": "module"}],
]
},
"/en/": {
// 设置正在使用的语言
lang: "en-US",
title: "LiteyukiBot",
description: "LiteyukiBot | An OneBot Standard ChatBot ",
head: [
["script", {"src": "/js/en/get_data.js", "type": "module"}],
]
},
},
head: [
// 设置 favor.ico.vuepress/public 下
["script", {src: "/js/style.js", "type": "module"}],
['link', {rel: 'icon', href: 'https://cdn.liteyuki.icu/favicon.ico'},],
['link', {rel: 'stylesheet', href: 'https://cdn.bootcdn.net/ajax/libs/firacode/6.2.0/fira_code.min.css'}],
[
"meta",
{
name: "viewport",
content: "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no",
},
],
],
theme,
// 和 PWA 一起启用
// shouldPrefetch: false,
});

View File

@ -1,25 +0,0 @@
import {navbar} from "vuepress-theme-hope";
export const enNavbarConfig = navbar([
"/en/",
{
text: "Deploy",
link: "/en/deploy/",
prefix: "deploy/",
},
{
text: "Usage",
link: "/en/usage/",
prefix: "usage/",
},
{
text: "Extensions",
link: "/en/store/",
prefix: "store/",
},
{
text: "Contribute",
link: "/en/dev/",
prefix: "dev/",
},
]);

View File

@ -1,2 +0,0 @@
export * from "./zh.js"
export * from "./en.js"

View File

@ -1,26 +0,0 @@
import {navbar} from "vuepress-theme-hope";
export const zhNavbarConfig = navbar([
"/",
{
text: "安装及部署",
link: "/deploy/",
prefix: "deploy/",
},
{
text: "使用及功能",
link: "/usage/",
prefix: "usage/",
},
{
text: "资源及插件",
link: "/store/",
prefix: "store/",
},
{
text: "开发及贡献",
link: "/dev/",
prefix: "dev/",
},
]);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#FDD7AD" d="M512 0 335.448 88.272l-70.616 35.312-70.624 35.312-176.552 88.28v529.648L512 1024l494.344-247.176V247.176z"/><path fill="#CBB292" d="m759.176 370.76-70.624 35.304-494.344-247.168 70.624-35.312zM512 494.344V1024L17.656 776.824V247.176z"/><path fill="#7F6E5D" d="M1006.344 247.168v529.656L512 1024V494.344l176.552-88.28v70.624l141.24-70.624v-70.616z"/><path fill="#7F5B53" d="M829.792 335.448v70.624L688.56 476.68v-70.624z"/><path fill="#CBB292" d="m829.792 335.448-70.624 35.312-494.344-247.176 70.624-35.312z"/><path fill="#2C3E50" d="m682.52 550.32 157.032-78.512a17.656 17.656 0 0 1 25.552 15.792v9.32a52.96 52.96 0 0 1-29.28 47.376L678.8 622.8a17.656 17.656 0 0 1-25.552-15.792v-9.312a52.96 52.96 0 0 1 29.28-47.376z"/></svg>

Before

Width:  |  Height:  |  Size: 854 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024"><defs><linearGradient id="a" x1="522.593" x2="522.593" y1="-70.302" y2="-335.937" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" stop-color="#fe5d5a" stop-opacity=".1"/><stop offset=".908" stop-color="#ef1220" stop-opacity=".5"/></linearGradient><linearGradient id="b" x1="107.12" x2="935.038" y1="-373.67" y2="-373.67" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" stop-color="#ff5e59"/><stop offset="1" stop-color="#f01422"/></linearGradient><linearGradient id="c" x1="519.405" x2="519.405" y1="-195.547" y2="-726.816" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" stop-color="#ffe2e2"/><stop offset=".888" stop-color="#ff8e8e"/></linearGradient><linearGradient id="d" x1="191.5" x2="483.9" y1="-564.9" y2="-564.9" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" stop-color="#e92700" stop-opacity=".3"/><stop offset=".013" stop-color="#ef1220" stop-opacity=".2"/></linearGradient><linearGradient id="e" x1="403.502" x2="253.121" y1="-847.32" y2="-586.853" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" stop-color="#ff5e59"/><stop offset=".201" stop-color="#f01422"/></linearGradient><linearGradient id="f" x1="330.485" x2="330.485" y1="-801.787" y2="-625.789" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" stop-color="#ff5e59"/><stop offset=".201" stop-color="#f01422"/></linearGradient><linearGradient id="g" x1="397.351" x2="256.845" y1="-647.231" y2="-890.596" gradientUnits="userSpaceOnUse" spreadMethod="pad"><stop offset="0" stop-color="#ffa6a6"/><stop offset=".908" stop-color="#ff6b5d"/></linearGradient></defs><path fill="url(#a)" d="M501.2 662.3 327.6 763.8c-13.9 8.1-14.2 28.1-.5 36.7l179.1 97.7c10.9 5.9 24.1 5.9 34.9-.1l177-97.9c13.6-8.5 13.4-28.3-.3-36.5l-168.4-101c-14.8-9-33.3-9.1-48.2-.4Z"/><path fill="#f63037" d="m110.2 525.7-3.1 77.6 57.5 18.5L184 519.4Z"/><path fill="url(#b)" d="m476.6 363.5-328 154.6c-21 42.7-55.4 65.4-35.5 103.5 4.2 8 9.4 14.4 15.4 18.1l358.2 195.5c21.8 11.9 48.1 11.8 69.8-.2l354-195.8c27.2-16.9 34.8-90.3 7.3-106.8L573 364.1c-29.7-17.8-66.6-18-96.4-.6Z"/><path fill="url(#c)" d="M476.6 298.7 129.4 501.6c-27.8 16.3-28.4 56.3-1 73.3l358.2 195.5c21.8 11.9 48.1 11.8 69.8-.2l354-195.8c27.2-16.9 26.9-56.6-.6-73.1L573 299.3c-29.7-17.8-66.6-18-96.4-.6Z"/><path fill="#ff8989" fill-opacity=".31" d="m481.2 387.8 39.4 123.4c1.1 3.4 4 6 7.6 6.6l173.4 30.4-33-118.3c-.9-3.3-3.6-5.8-7-6.5l-180.4-35.6ZM327 499.2l40.4 101.1L496.7 525c2.5-1.5 3.7-4.5 2.7-7.3l-36-106.8-127.6 65c-8.6 4.3-12.4 14.4-8.8 23.3ZM523.8 540.5l-140.3 77.2L567.2 659c3.2.7 6.6.1 9.3-1.6l134.6-85-174.7-33.8c-4.3-1-8.7-.3-12.6 1.9Z"/><path fill="url(#d)" d="M483.9 406.1c0 35.46-65.46 64.2-146.2 64.2s-146.2-28.74-146.2-64.2c0-35.46 65.46-64.2 146.2-64.2s146.2 28.74 146.2 64.2Z"/><path fill="url(#e)" d="m254.2 188.4-123 83.1c-1.8 1.3-2.6 3.6-1.8 5.7l39.1 110.6c.6 1.7 2 2.9 3.8 3.2l221.8 40.5c1.3.3 2.7-.1 3.7-.8l131.7-93.6c1.9-1.4 2.6-3.9 1.7-6.1l-49.4-107c-.6-1.5-2.1-2.6-3.7-2.8l-220.3-33.5c-1.3-.2-2.6.1-3.6.7Z"/><path fill="url(#f)" d="m528.6 274.5 3 59.1-205 65.6-177.2-72.7-20-49.2 1.9-54.1Z"/><path fill="url(#g)" d="m250.6 138-112.3 76c-6 4.1-8.5 11.7-6.1 18.5l34.2 96.6c1.9 5.4 6.6 9.3 12.1 10.4l211 38.5c4.3.7 8.6-.2 12.1-2.7l120.5-85.5c6.3-4.4 8.4-12.7 5.3-19.7l-43.1-93.5c-2.2-4.9-6.8-8.3-12.1-9.1L262 135.6c-4-.7-8 .2-11.4 2.4Z"/><path fill="#fff" d="m419.8 252.8-79-11-29-57.7c-3.8-7.6-13.2-10.7-20.8-6.9-7.6 3.8-10.7 13.2-6.9 20.8l26.6 52.9-61.8 42.2c-7.1 4.8-8.9 14.5-4.1 21.5 3 4.4 7.9 6.8 12.8 6.8 3 0 6-.9 8.7-2.7l68-46.4 81.1 11.2c.7.1 1.4.1 2.1.1 7.6 0 14.3-5.6 15.3-13.4 1.4-8.4-4.5-16.2-13-17.4Z"/></svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -1 +0,0 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>

Before

Width:  |  Height:  |  Size: 963 B

View File

@ -1 +0,0 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 960 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1536 1024"><path fill="#1296db" d="M1425.067.256H110.933A110.933 110.933 0 0 0 0 110.848v723.627a110.933 110.933 0 0 0 110.933 110.933h1314.39c61.269 0 110.933-49.75 110.677-110.677V110.848A110.933 110.933 0 0 0 1425.067.256z" class="selected" data-spm-anchor-id="a313x.7781069.0.i4"/><path fill="#FFF" d="M664.747 723.797V435.883L517.12 620.373l-147.456-184.49v288l-148.053-67.158V221.781h147.626l147.627 184.576 147.541-184.576h147.627v565.76z"/><path d="M1024 0h426.667A85.333 85.333 0 0 1 1536 85.333v768a85.333 85.333 0 0 1-85.333 85.334H1024V0z" opacity=".1"/><path fill="#FFF" d="m1256.96 731.307-170.667-216.491h113.75V304.64h113.749v210.176h113.835z" opacity=".5"/></svg>

Before

Width:  |  Height:  |  Size: 771 B

View File

@ -1,20 +0,0 @@
[
{
"module_name": "liteyukibot-plugin-nonebot",
"project_link": "liteyukibot-plugin-nonebot",
"name": "NoneBot插件",
"desc": "在轻雪中使用NoneBot为NoneBot开发者提供了更多便捷功能(已内置)",
"author": "snowykami",
"homepage": "https://github.com/LiteyukiStudio/liteyukibot-plugin-nonebot",
"tags": [
{
"label": "server",
"color": "#aeeaa8"
}
],
"is_official": true,
"type": "application",
"valid": true,
"version": "rolling"
}
]

View File

@ -1,291 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1366 768">
<defs>
<style>
.cls-1 {
fill: url(#_未命名的渐变_8);
}
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7, .cls-8, .cls-9, .cls-10, .cls-11, .cls-12, .cls-13, .cls-14, .cls-15, .cls-16, .cls-17, .cls-18, .cls-19, .cls-20, .cls-21, .cls-22, .cls-23, .cls-24, .cls-25, .cls-26, .cls-27, .cls-28, .cls-29, .cls-30, .cls-31, .cls-32, .cls-33, .cls-34 {
stroke-width: 0px;
}
.cls-2 {
fill: url(#_未命名的渐变_9-3);
}
.cls-3 {
fill: url(#_未命名的渐变_11);
}
.cls-4 {
fill: url(#_未命名的渐变_11-4);
}
.cls-5 {
fill: url(#_未命名的渐变_5);
}
.cls-6 {
fill: url(#_未命名的渐变_55);
}
.cls-7 {
fill: url(#_未命名的渐变_11-5);
}
.cls-8 {
fill: url(#_未命名的渐变_65);
}
.cls-9 {
fill: url(#_未命名的渐变_3-2);
}
.cls-10 {
fill: url(#_未命名的渐变_7-3);
}
.cls-11 {
fill: url(#_未命名的渐变_7);
}
.cls-12 {
fill: url(#_未命名的渐变_58);
}
.cls-13 {
fill: url(#_未命名的渐变_3-3);
}
.cls-14 {
fill: url(#_未命名的渐变_67);
}
.cls-15 {
fill: url(#_未命名的渐变_11-2);
}
.cls-16 {
fill: url(#_未命名的渐变_72);
}
.cls-17 {
fill: url(#_未命名的渐变_71);
}
.cls-18, .cls-35 {
fill: #fff;
}
.cls-19 {
fill: url(#_未命名的渐变_4);
}
.cls-20 {
fill: url(#_未命名的渐变_3);
}
.cls-21 {
fill: url(#_未命名的渐变_240);
}
.cls-22 {
fill: url(#_未命名的渐变_9-2);
}
.cls-23 {
fill: url(#_未命名的渐变_6);
}
.cls-24 {
fill: url(#_未命名的渐变_9-4);
}
.cls-25 {
fill: url(#_未命名的渐变_66);
}
.cls-26 {
fill: url(#_未命名的渐变_7-2);
}
.cls-35 {
stroke: #fff;
stroke-miterlimit: 10;
}
.cls-27 {
fill: url(#_未命名的渐变_9);
}
.cls-28 {
fill: url(#_未命名的渐变_9-5);
}
.cls-29 {
fill: url(#_未命名的渐变_68);
}
.cls-30 {
fill: url(#_未命名的渐变_11-3);
}
.cls-31 {
fill: url(#_未命名的渐变_69);
}
.cls-32 {
fill: #9cf;
}
.cls-33 {
fill: url(#_未命名的渐变_58-2);
}
.cls-34 {
fill: url(#_未命名的渐变_4-2);
}
</style>
<linearGradient id="_未命名的渐变_11" data-name="未命名的渐变 11" x1="445.89" y1="235.02" x2="528.25" y2="235.02" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#73fff1"/>
<stop offset="1" stop-color="#5cefff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_11-2" data-name="未命名的渐变 11" x1="549.98" y1="292.99" x2="584.05" y2="292.99" xlink:href="#_未命名的渐变_11"/>
<linearGradient id="_未命名的渐变_11-3" data-name="未命名的渐变 11" x1="553" y1="212" x2="585" y2="212" xlink:href="#_未命名的渐变_11"/>
<linearGradient id="_未命名的渐变_11-4" data-name="未命名的渐变 11" x1="609.82" y1="260.3" x2="698.34" y2="260.3" xlink:href="#_未命名的渐变_11"/>
<linearGradient id="_未命名的渐变_11-5" data-name="未命名的渐变 11" x1="702.75" y1="282.24" x2="784.94" y2="282.24" xlink:href="#_未命名的渐变_11"/>
<linearGradient id="_未命名的渐变_240" data-name="未命名的渐变 240" x1="835" y1="294" x2="960" y2="294" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#eadeff"/>
<stop offset=".28" stop-color="#e0efff"/>
<stop offset=".43" stop-color="#d9ecff"/>
<stop offset=".59" stop-color="#aedbff"/>
<stop offset="1" stop-color="#00d7ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_9" data-name="未命名的渐变 9" x1="664.92" y1="424.34" x2="766.76" y2="424.34" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#2ebbff"/>
<stop offset="1" stop-color="#006bff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_9-2" data-name="未命名的渐变 9" x1="761.74" y1="467.72" x2="842.05" y2="467.72" xlink:href="#_未命名的渐变_9"/>
<linearGradient id="_未命名的渐变_9-3" data-name="未命名的渐变 9" x1="951.96" y1="394" x2="977.04" y2="394" xlink:href="#_未命名的渐变_9"/>
<linearGradient id="_未命名的渐变_9-4" data-name="未命名的渐变 9" x1="952.19" y1="456.86" x2="977.56" y2="456.86" xlink:href="#_未命名的渐变_9"/>
<linearGradient id="_未命名的渐变_9-5" data-name="未命名的渐变 9" x1="848.96" y1="437.15" x2="934.09" y2="437.15" xlink:href="#_未命名的渐变_9"/>
<linearGradient id="_未命名的渐变_4" data-name="未命名的渐变 4" x1="418.01" y1="402.81" x2="470.25" y2="402.81" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6445ff"/>
<stop offset="1" stop-color="#5c86ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_4-2" data-name="未命名的渐变 4" x1="445.81" y1="464.45" x2="466.06" y2="464.45" xlink:href="#_未命名的渐变_4"/>
<linearGradient id="_未命名的渐变_72" data-name="未命名的渐变 72" x1="634.1" y1="393.61" x2="649.62" y2="390.81" gradientTransform="translate(-320.36 273.4) rotate(-11.09) scale(1.44 .77)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#c4aeff"/>
<stop offset=".43" stop-color="#ce9fff"/>
<stop offset=".55" stop-color="#af8eff"/>
<stop offset=".72" stop-color="#7d74ff"/>
<stop offset=".9" stop-color="#6333ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_58" data-name="未命名的渐变 58" x1="620.28" y1="400.01" x2="636.02" y2="397.18" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b1ccff"/>
<stop offset=".34" stop-color="#b8c0ff"/>
<stop offset=".94" stop-color="#cba2ff"/>
<stop offset="1" stop-color="#ce9fff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_3" data-name="未命名的渐变 3" x1="469.91" y1="455" x2="478" y2="455" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#5c86ff"/>
<stop offset="1" stop-color="#64a2ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_3-2" data-name="未命名的渐变 3" x1="470.95" y1="475.89" x2="477.01" y2="475.89" xlink:href="#_未命名的渐变_3"/>
<linearGradient id="_未命名的渐变_65" data-name="未命名的渐变 65" x1="485.09" y1="467.16" x2="502.74" y2="469.91" gradientTransform="translate(-109.75 153.43) rotate(-15.93)" gradientUnits="userSpaceOnUse">
<stop offset=".11" stop-color="#64a2ff"/>
<stop offset=".28" stop-color="#62a6ff"/>
<stop offset="1" stop-color="#5cb5ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_66" data-name="未命名的渐变 66" x1="506.01" y1="471.79" x2="532.2" y2="471.17" gradientTransform="translate(117.47 -103.02) rotate(12.81)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#5cb5ff"/>
<stop offset="1" stop-color="#74e0ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_68" data-name="未命名的渐变 68" x1="559.81" y1="469.17" x2="583.24" y2="468.62" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#9cd1ff"/>
<stop offset="1" stop-color="#bae0ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_71" data-name="未命名的渐变 71" x1="584.93" y1="460.83" x2="609.05" y2="460.83" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#a6d3ff"/>
<stop offset=".7" stop-color="#b1ccff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_58-2" data-name="未命名的渐变 58" x1="605.79" y1="473.79" x2="643.63" y2="466.98" xlink:href="#_未命名的渐变_58"/>
<linearGradient id="_未命名的渐变_3-3" data-name="未命名的渐变 3" x1="479.91" y1="397.6" x2="514.17" y2="397.6" xlink:href="#_未命名的渐变_3"/>
<linearGradient id="_未命名的渐变_5" data-name="未命名的渐变 5" x1="525.59" y1="402.28" x2="558.08" y2="402.28" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#64a2ff"/>
<stop offset="1" stop-color="#5cc9ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_69" data-name="未命名的渐变 69" x1="583.43" y1="398.41" x2="604.15" y2="398.41" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#84c9ff"/>
<stop offset=".42" stop-color="#b1ccff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_67" data-name="未命名的渐变 67" x1="531.83" y1="464.83" x2="558.02" y2="464.22" gradientTransform="translate(-86.67 132.78) rotate(-12.37)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#74e0ff"/>
<stop offset=".56" stop-color="#8dd6ff"/>
<stop offset="1" stop-color="#9cd1ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_6" data-name="未命名的渐变 6" x1="531" y1="411" x2="539" y2="411" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#64a2ff"/>
<stop offset="1" stop-color="#5cbfff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_7" data-name="未命名的渐变 7" x1="553.98" y1="380.5" x2="559" y2="380.5" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#64ccff"/>
<stop offset="1" stop-color="#84c9ff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_7-2" data-name="未命名的渐变 7" x1="546.98" y1="383.5" x2="552" y2="383.5" xlink:href="#_未命名的渐变_7"/>
<linearGradient id="_未命名的渐变_7-3" data-name="未命名的渐变 7" y1="404.39" x2="561.98" y2="404.39" xlink:href="#_未命名的渐变_7"/>
<linearGradient id="_未命名的渐变_8" data-name="未命名的渐变 8" x1="578.42" y1="391.26" x2="586.42" y2="391.26" gradientUnits="userSpaceOnUse">
<stop offset=".01" stop-color="#84c9ff"/>
<stop offset="1" stop-color="#b1ccff"/>
</linearGradient>
<linearGradient id="_未命名的渐变_55" data-name="未命名的渐变 55" x1="623.35" y1="385.26" x2="623.75" y2="385.26" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b1c9ff"/>
<stop offset=".42" stop-color="#b1ccff"/>
</linearGradient>
</defs>
<g id="_图层_3" data-name="图层 3">
<path class="cls-32" d="m447,485c11.04,8.56,30.35.82,33,0,14.37-4.43,15.38-15.33,26-15,10.44.33,13.16,10.98,24,10,6.48-.59,7.04-4.53,16-6,8-1.31,8.66,1.66,17,1,12.76-1.01,15.73-8.33,24-6,8.42,4.47,11.58,6.51,22,5,0,0,11.3-1.75,32-10,1.42-9.07,4.72,6.12,11.99,12,10.1,9.09,19.95-.4,31,8,10.86,8.26,13.5,26.66,13,31-1.65,4.39,6.37,10.16,6,10-4.41-.77-20.72-10.82-25-11-6.8-1.26-15.53-2.26-24-5-17.1-5.24-15.17-10.82-34-10-7.53.04-6.69-.47-12,1-2.54-.23-9.74.73-13-1-18.29-11.87-9.94,11.78-36,3-9.47,1.86-14.72.65-18.02-1.12-2.21-1.19-4.61-5.33-6.74-4.61-.57.19-.74.58-2.24,1.74-1.2.93-2.27,1.58-3,2-.91.36-1.91.7-3,1-2.93.8-5.59,1.02-7.75,1.02-.74,0-1.87-.01-3.25-.02-3.97,0-3.61.03-4,0-2.87-.21-3.75-.93-7-1-.42,0-.77,0-1,0h-6c-3,.22-5.39.65-7,1-1.72.37-3.36.82-10,3-3.07,1.01-4.59,1.59-6,2-1.81.53-5.13,1.49-9,2-5.07.67-9,.3-12,0-6.54-.65-11.56-2.18-14-3-4.6-1.55-26.12-13.37-20-10,0,0,0,0,0,0-.03-.02-20.88-13.37-28-32-1.09-2.85-2-6-2-6-.52-1.8-1.44-5.03-2-9-.44-3.12-1.34-9.53,0-10,1.69-.59,6.23,8.51,7.27,10.48,5.15,9.76,18.12,22.54,52.73,35.52Z"/>
<path class="cls-32" d="m633,394c-13.63,7.43-2.93,57.29,2,57,1.82-.11,1.13-6.97,8-16,3-3.94,3.81-3.37,5-6,.88-3.8,2.06-11.66-2-19-.61-1.11-1.29-2.11-2-3-.31-.36-.8-1.04-1-2-.06-.32-.19-.91,0-1,.26-.13.82.87,2,2,.84.81,1.71,1.61,3,2,1.06.32,1.94.17,3,0,1.38-.23,2.37-.69,3-1,1.31-.64,2.25-1.09,3-2,1.84-2.22,1.14-5.41,1-6-.33-1.36-.69-1.29-2-4-.87-1.8-.57-1.55-2-5-.49-1.19-1-2.79-2-6-.12-.39-.37-1.22,0-2,0,0,.29-.6,1-1,1.98-1.11,11.6.55,15,1,2.66.35,13.92,1.61,15.83,2.95.42.3.8.64,1.17,1.05,2.43,2.73.93,4.31,3,9,3.83,8.69,13.16,12.57,19,15,5.09,2.12,8.54,2.5,13,3,6.22.69,7.53-.22,8-1,.74-1.23-.27-2.7-1-5-1.53-4.78-.3-8.09,0-12,.51-6.64-1.77-13.74-4-17-9.26-13.54-41.29,4.77-71-2-1.28-.29-9.89-2.3-12,1-1.87,2.94,2.99,7.55,1,12-1.49,3.33-5.5,3.63-8,5Z"/>
<path class="cls-32" d="m683,228c-22.42,19.49,74.7,203.11,32,245-9.08,8.91-26.9,13.94-28,28-.65,8.33,4.78,18.3,13,23,13.88,7.94,28.83,2.05,33-1,2.68-1.96,4-4,4-4,1.44-2.22,1.56-3.91,3-8,.76-2.17,1.5-3.9,2-5,.43-1.13.95-2.86,1-5,.04-1.88-.32-2.29-.25-4.13.04-1.01.22-5.22,2.25-5.87.27-.09,1.3-.35,3,1-.17-.41-.33-.87-.21-.95.24-.16,1.16,1.42,2.21,1.95,2.87,1.44,7.56-.07,8-2-10.79-5.85-14.4-6.84-15-6-.79,1.11,3.49,5.56,3,6-.37.33-3.05-1.93-3-2,.05-.07,3.08,1.97,4,3,.08.09.44.51,1,1,.23.2.43.36.55.46.1.12.26.31.45.54,2.9,3.62,4.2,7.01,4.62,8.05.92,2.28,2.67,5.77,6.38,10.95,15.05,16.54,34.83,19.18,54,9,16.33,3.81,7.85,10.54,33,5,25.9-4.5,50.39,1.98,49-25-1.26-10.66-5.86-19.02,0-10,8.68,14.17,21.69,39.51,43,27,6.44-4.99,5.9-9.29,8-16,1.22-1.48,4.53-4.38,6-4,.01.08.16,1-.41,1.5-.6.53-1.8.43-2.59-.5,2.97,10.52,12.31,17.02,21,16,7.93-.94,13.74-10.13,14.27-11.06.54-.96.98-1.97.98-1.97s.41-.95.75-1.97c1.19-3.64,1.46-7.4,1.46-7.4.88-11.86.98-15.27.98-15.27.35-11.02.5-9.78.67-17.66.19-8.34-.04-7.03.13-13.62,0,0,.55-21.79-3.25-26.05-.48-.54-1-1-1-1-1.02-.91-1.79-1.28-3-2,0,0-1-.67-3-2-1-.67-2.08-1.22-3-2-1.25-1.06-1.85-1.94-3-2-.39-.02-.52.07-1,0-1.2-.18-1.99-1.02-2-1-.02.03.5.41,3,2,.1-.62,1.27-2.67,2-3,5.54-4.98,5.58-5.38,8-10,6.12-15.03-2.92-19.21-14-26-1.23-1.16-1.87-.9-3-1-.59-2.25-2.17-3.18-3-6-1.01-2.71-2.29-10.67-2-12,.57-5.41,2.39-8.84,4-11,2.1-2.82,3.85-3.49,6-7,1.22-2,2.84-4.65,3-8,.25-5.38-3.39-9.63-8-15-2.47-2.87-5.06-5.17-6-6-2.42-2.13-4.22-3.42-5-4-5.14-3.8-8.31-10.94-9.7-14.15-5.32-12.26-7.9-23.86-8.3-32.85-1.17-26.5-38.54-51.77-63-35-7.04,5.65-2.81,10.14-11,18-10.42,10-22.57,7.8-34,13-5.71,3.43-10.18.22-16-2-9.95-3.09-18.5-13.48-24-22-1.52-1.57-3.98-3.73-7.79-5.64-30.14-4.8-47.97-7.45-51.21-7.36-.78.02-4.27.18-7.57-1.74-7.85-9.54-30.21,6.06-40.43,13.74Z"/>
<path class="cls-32" d="m667,174c-4.66.36-8.11,1.64-10.79,3.57-13.35,9.62-7.67,24.47-21.35,37.56-3.88,3.71-4.86,2.87-33.86,12.87-.06.02-2.46.85-4,0-.23-.13-.75-.41-1-1-.23-.54-.15-1.16-.12-1.33.02-.16.09-.51.12-.67h0c1.24-1.71,8.11-11.55,4.97-21.02-3.76-11.34-20.93-19.28-39.97-12.98-12.11,2.27-15.97.27-17.33-1.85-1.94-3.02.84-6.86,5.33-19.16,3.86-10.58,5.89-16.13,6-22,.1-5.49-1.43-13.73-10-24-23.21-14.8-47-13.43-56-2-1.46,1.85-5.64,7.92-4,20-3.3,4.02-9.31,1.14-20,4-10.63,1.96-20.69,9.46-13,23,5.63,9.91,94.53,145.36,192.09,115.49,50.17-15.36,72.52-65.2,72.91-66.49.03-.1.51-1.68,0-2-.15-.1-.3-.03-1,0h-3c-1.55,0-3.44-.77-4-1-.5-.2-1.8-.75-5-3-1.04-.73-2.42-1.73-4-3-3.1-.72-4.4-1.96-5-3-.3-.52-.38-.9-1-2-1.21-2.14-1.61-1.92-2-3-.34-.93-.04-1.09,0-5,0-.35,0-.06,0-2,0-3.6.02-3.67,0-4-.12-1.85-.9-3.16-2-5-2.63-4.41-6.25-6.57-7-7-1.67-.96-2.99-1.38-5-2-2.56-.79-6.28-1.69-11-2Z"/>
</g>
<g id="_背景" data-name="背景">
<path class="cls-18" d="m572,182c-16.42-3.08-26.21,8.1-31,4-7.63-6.54,18.33-33.97,9-55-6.88-15.51-30.12-21.13-45-21-3.33.03-16.49.44-31,9-30.76,18.15-37.62,55.27-56,109-20.03,58.55-43.71,77.3-45,119-.4,13.04.88,31.37,1,33,2.91,40.64,9.7,47.97,12,64,.27,1.85.98,7.34,5,12,.83.96,1.59,1.64,2.01,2,.47.48,1.15,1.18,1.99,2,10.84,10.63,27.33,20.18,27.33,20.18,17.89,10.12,26.84,15.18,35.66,13.82,3.19-.49,6.88-1.68,16.62-3.27,3.46-.56,6.46-.79,12.39-1.73,3.95-.63,7.36-.89,10-1,3.64-.15,6.36-.03,7,0,4.66.22,8.01.84,9,1,3.81.61,10.14.32,21-4,3.96.13,4.67,2.49,9,4,4.59,1.6,5.73-.37,15,0,16.7,2.72,12.4-.95,25-4,5.48-.56,5.78,1.97,14,3,9.86,2.45,36.35-8.51,48,1,6.44,5.27,9.1,4.24,16,6,7.05,3.78,15.85,4.35,23,8,18.2,11.17,34.14,20.96,51,2,5.59-6.98,3.83-12.43,8-14,7.13-2.81,31.59,30.21,58,23,15.36-6.57,13.31-4.51,28,1,5.68,1.04,23.32-3.84,33-4,12.6-.87,15.51.92,21-2,11.5-6.32,8.35-12.82,9-21,6.52,3,17.82,31.94,43,18,6.28-4.14,7.41-10.27,11-10,3.81.29,3.43,7.28,9,11,7.22,4.82,20.84,1.79,26-6,1.88-2.84,1.95-5.28,2-16,.06-12.86,2.5-34.29,1-57-.27-4.14-.62-6.12-2-8-1.81-2.47-4.68-3.81-7.73-8.57-.11-.18-.21-.33-.27-.43,0-.08-.02-.19-.02-.33.03-1.6,1.77-2.75,2.36-3.17,1.19-.85,2.8-2.4,4.66-5.5,10.77-33.99-34.41-21.61-20-59,3.12-6.89,6.55-6.37,8-12,2.32-9.04-4.5-18.26-8-23-5.99-8.1-8.37-6.45-17-17-2.93-3.58-6.84-8.36-9.5-15.5-2.32-6.24-2.48-11.05-2.5-12.5,0-.42,0-.77,0-1,.13-4.73-.28-14.34-6-24-8.66-14.64-25.27-22.26-40-22-22.75.41-39.01,19.59-41,22-4.52,5.48-5.53,9.19-11,12-8.17,4.19-19.82,3.24-29-1-1.04-.48-1.78-.88-2-1-13.03-7.1-12.62-18.04-23-25-.78-.52-2.86-1.85-9.5-3.93-18.42-5.77-40.67-7.51-55.5-8.07-1.93.07-4.76-.05-8-1-3.67-1.08-6.36-2.77-8-4-5.34-3.78-6.82-2.84-9-5-3.59-3.56.14-10.39-3-17-2.84-5.97-10.15-7.96-14-9-2.47-.67-11.2-2.68-20,2-1.88,1-6.08,3.3-9,8-2.37,3.82-1.56,5.46-4,14-2.08,7.28-3.18,10.97-6,13-1.17.85-5.1,3.27-13,1-3.07-.18-7.45,0-12,2-8.86,3.88-12,11.82-14,11-2.79-1.15,5.52-15.64,0-28-5.58-12.5-22.22-15.85-23-16Z"/>
<g id="_主体" data-name="主体">
<path id="lite-l" class="cls-3" d="m516,141c.03-1.1-.07-2.97-1-5-.89-1.93-2.11-3.1-2.75-3.7-.4-.38-1.57-1.42-3.37-2.29-1.11-.53-2.12-.83-2.88-1.01-.48,0-1.16,0-1.98.04-1.4.09-4.59.32-7.8,1.81-3.86,1.79-6.04,4.59-7.21,6.15-1.03,1.36-.93,1.77-4,8-1.08,2.19-1.79,3.57-2,4-5.9,11.79-12,35-12,35-7.65,29.08-7.7,25.76-12,44-2.8,11.87-4.71,21.49-6,28-.61,3.07-2.21,11.25-4,22,0,0-1.57,9.87-3,30-.1,1.34-.46,7.05,1,14,.85,4.05,3,8,3,8h0c2.28,2.98,4.52,4.83,5.99,5.89,11.06,8,23.32,4.35,57.01,4.11,3.06-.02,5.53-.01,7,0,1.02-.28,2.51-.84,4-2,.52-.41,1.27-1.06,2-2,.45-.58,1.59-1.91,2-4,.21-1.08.43-2.87,0-5-.36-1.17-.7-2.18-1-3-.3-.83-.53-1.39-1-2-.36-.46-.73-.79-1-1-.24-.23-.76-.76-1-1-1.73-1.73-1.87-1.87-2-2-1.25-1.2-2.82-1.65-4-2-5.84-1.71-23-2-23-2-4.12-.07-10.14-.62-17.53-2.99,1.73-17.19,5.56-49.39,13.31-81.46,4.95-20.51,4.35-18.09,8.22-30.55,5.85-18.81,8.77-28.22,11-34,0,0,3.24-8.41,4.63-15.69.44-2.32.84-4.8.84-4.8.18-1.17.35-2.34.53-3.5Z"/>
<path id="lite-i-1" class="cls-15" d="m569,240c4.11.31,6.91,2.96,8,4,6.83,6.48,6.93,17.68,7,26,0,.06,0,.03,0,7,0,14.32,0,21.48,0,22,.04,13.27.66,35.34-4,42-1.29,1.84-3,3-3,3-2.97,2.01-6.17,1.99-8,2-1.45,0-7.74-.12-13-5-6.34-5.87-6.06-13.87-6-15,0-.07,0-9.93,0-10,0-38.04,0-37.85,0-38-.02-1.29-.01-3.53,0-8,.03-9.9.15-12.06,1-15,1.28-4.42,3.15-6.95,4-8,1.1-1.36,2.19-2.34,3-3,.7-.58,1.7-1.32,3-2,.98-.52,4.28-2.28,8-2Z"/>
<path id="lite-i-1-1" class="cls-30" d="m566.78,196.07c8.85-.96,18.71,7.52,18.2,17.09-.5,9.28-10.62,16.63-19.33,14.46-6.93-1.73-13.7-9.65-12.51-18.4,1.06-7.79,7.93-12.52,13.65-13.14Z"/>
<path id="lite-t" class="cls-4" d="m643,219c-5.46,4.9-13.26-2.45-24,3-1.76.89-7.94,4.02-9,10-.72,4.08.94,7.61,1.38,8.43.48.92,2.17,4.11,5.62,5.57,1.09.46,1.2.26,6,1,5.06.78,4.17.82,6,1,2.02.19,4,.68,6,1,.54.09,1.55.25,2,1,.42.71.13,1.6,0,2-.61,1.93-.44,4.05-1,6-1.01,3.51-.87,8.39-1,13-.29,10.62-1.82,12.94-2,20-.11,4.19-.42,18.97,9,31,1.49,1.9,10.06,12.84,21,12,1.28-.1,5.89-.45,9-4,4.48-5.11,2.13-12.61,2-13-1.5-4.54-4.19-4.73-8-10-4-5.53-5.15-11-6-15-1.67-7.89-.83-14.05,0-20,1.22-8.76,3.02-10.14,4-16,.13-.81.46-2.94,2-5,0,0,.85-1.13,2-2,2.17-1.64,8.68-.49,12.72-.42,3.25.06,5.06.09,7.28-.58,1.17-.35,8.31-2.66,10-9,1.37-5.14-1.51-11.55-6-14-3.8-2.07-12.48-2.26-15-3-1.03-.3-1.9-.93-2-1-.47-.34-.82-.6-1-1-.56-1.23.89-2.87,1-3,.54-.96,1.27-2.32,2-4,1.51-3.46,2.99-6.85,3-11,0-1.91.01-6.19-3-10-3.3-4.17-8.02-4.99-9.42-5.24-.92-.16-6.37-1-11.58,2.24-1.61,1-4.15,3-7,9-5.75,12.08-1.75,17.18-6,21Z"/>
<path id="lite-e" class="cls-7" d="m735,276c-.58.39-5.22,3.65-5,8,.19,3.92,4.21,6.49,5,7,5.42,3.48,9.31.51,25-1,10.15-.98,16.08-.47,21-5,1.89-1.74,2.72-3.39,3-4,2.32-5.01-.29-10.09-1-14-1.83-10.01-12.11-17.03-15-19-1.39-.95-8.43-5.63-19-7-4.47-.58-13.46-1.75-23,3-8.94,4.45-13.31,11.6-16,16-5.84,9.56-6.79,18.48-7,21-.4,4.87-1.09,14.86,5,25,4.96,8.26,11.87,12.39,15,14,8.24,4.25,15.6,4.12,23,4,9.99-.17,16.58-2.61,23-5,2-.74,5.17-2.02,8-5,1.68-1.77,4.08-4.29,4-8-.07-3.36-2.16-6.53-5-8-2.95-1.53-5.9-.81-9,0-6.07,1.58-6.81,4.01-12,6-6.49,2.49-12.52,1.46-15,1-3.77-.69-9.81-1.81-14-7-3.24-4.01-3.72-8.41-4-11-.26-2.43-1.1-10.07,4-17,.43-.59,7.21-9.48,18-9,1.43.06,9.65.59,14,7,1.16,1.71,2.94,4.33,2,6-2.22,3.93-15.76-4.29-25,2Z"/>
<path id="logo-snow" class="cls-21" d="m875,272l13.33,22,9.67-15-8-20,4-6,6,2,9,13,7-11,9,1,3,7-11,13,17,2,4,8-5,4-22-4-13.5,16.8,27.5,5.2,11-14,7,1,3,7-9,11,19,3,4,7-4,5-18-3,7,14-4,4-8-1-10-20-40-8-2-2-20-37-23-4-3-7,4-5,16,3-9-15,4-6,7,1,9,16,9-10,7,2,3,6-10,14Z"/>
<path id="yuki-y" class="cls-27" d="m717,426c-18.61-18.39-62.05-50.01-50-71,2.85-4.5,7.34-9.45,17-7,15.19,5.99,14.64,39.18,45,55,8.67-18.92,10.28-33.18,10-43-.12-4.37-.74-12.15,4-16,.82-.55,5.22-3.4,10.85-2.15,3.86.85,6.25,3.17,7.15,4.15.5.6,1.28,1.58,2.09,2.87,8.99,14.33.03,32.06-11.49,69.45-4.1,13.3-6.65,21.58-9.6,33.68-5.81,23.86-8.17,40.38-20,51-11.03,9.91-22.32.03-23-9-2.89-15.02,23.13-56.98,18-68Z"/>
<path id="yuki-u" class="cls-22" d="m776,433c-.54-.11-5.36-1.02-9,2-2.31,1.92-3.04,4.55-4,8-.74,2.66-.91,4.8-1,6-.59,8.25,0,15,0,15,1.18,13.55,1.77,20.33,3,23,1.04,2.27,4.07,8.71,11,13,6.21,3.85,12.31,3.91,21,4,.81,0,16.83.09,21-4,.22-.21,1.2-1.26,2-1,.93.3.69,2.05,2,4,0,0,.63.93,2,2,3.54,2.75,12.53,3.41,16-1,.62-.79,1.75-2.64,2-5,.07-.68.05-1.22.02-1.76-.13-2.75-.88-4.83-1.02-5.24-1.31-3.73-3.37-15.69-4-23-.58-6.71.42-5.3,0-19-.11-3.63-.12-9.19-3-15-1.36-2.75-2.63-4.09-4-5-2.95-1.96-6.82-2.22-10-1-.8.31-3.48,1.34-5,4-1.36,2.37-1.11,4.83-1,6,.66,6.98.45,14.01,1,21,.72,9.13.57,11.51-1,14-1.8,2.86-4.42,4.2-6,5-7.58,3.86-15,.82-17,0-2.54-1.04-3.49-2.11-4-3-.74-1.29-.88-2.78-1-4-.13-1.35-.05-2.34,0-3v-16c-.19-7.44-.28-11.16-2-14-.52-.85-3.02-4.98-8-6Z"/>
<path id="yuki-i-1-1" class="cls-2" d="m964,382c-6.65.3-12.55,6.12-12,13,.53,6.56,6.7,11.28,13,11,6.65-.3,12.55-6.12,12-13-.53-6.56-6.7-11.28-13-11Z"/>
<path id="yuki-i-1" class="cls-24" d="m964,413c-.8.03-3.41.23-6,2,0,0-1.73,1.18-3,3-3.44,4.92-2.32,14.54-2,25,.14,4.66,0,9.33,0,14,0,11.92,0,17.88,0,18-.51,8.41-1.54,11.05,0,16,.77,2.5,1.84,5.92,5,8,3.21,2.11,6.76,1.77,8.36,1.62.77-.07,5.65-.54,8.64-3.62,3.4-3.49,2.66-8.56,2-17-.09-1.11-1.18-15.43-1-28,.1-7.33-.76-14.71,0-22,.11-1.03.52-4.77-1-9-.64-1.78-1.55-4.19-4-6-2.89-2.13-6.05-2.04-7-2Z"/>
<path id="yuki-k" class="cls-28" d="m918,409c-.26-.11-.66-.27-1.17-.44,0,0-4.46-1.53-9.91-1-4.47.44-18.59,11.34-31.93,31.43-.35-10.53-.23-21.87.56-33.9.37-5.55.85-10.92,1.44-16.1.26-1.2.52-2.94.41-5.03-.09-1.81-.25-4.96-2.27-8.04-.56-.85-2.9-4.42-7.52-5.51-5.61-1.33-10.01,2.08-10.62,2.58-3.44,2.76-4.45,6.67-5,9-3.6,15.32-3,27-3,27,.42,8.15,1.67,32.57,1,50-.22,5.66.05,11.33,0,17-.05,6.02-.13,9.05,1,13,1.45,5.07,4.08,8.75,6,11,1.19,1.11,3.93,3.36,8,4,3.99.63,7.79-.51,9.84-1.85,11.06-7.21,1.65-39.59,4.55-40.56.39-.13,1.19.88,2.61,3.4,8.89,11.22,14.99,15.39,30,29,7.7,10.13,23.45,3.59,22-8-.19-16.59-39.62-33.08-31.91-39.47,1.89-2.38,6-8.21,6.91-9.53,5.47-7.8,10.83-8.44,13-15,1.34-4.04.69-6.57.43-7.38-1.01-3.15-3.39-4.94-4.43-5.62Z"/>
<path id="lite-jp-1" class="cls-19" d="m452,384c-1.75-1-2.61-.17-10,1-2.22.35-7.11,1.06-13,3-1.36.45-2.68.93-3,2-.49,1.65,1.56,4.27,4,5,.32.09.56.13.74.16,2.19.34,3.89-.56,5.26-1.16,1.96-.87,3.64-1.24,7-2,0,0,4.44-1,5,0,.02.04.04.07.04.07.07.18-.02.5-.04,2.93,0,.06,0,.71,0,2,0,5.01.09,5.71,0,7-.2,2.74-.3,4.11-1,5-1.25,1.58-3.23,1.52-7,2-5.62.72-4.41,1.27-10,2-7.19.94-9.49.07-11,2-1.32,1.68-1.32,4.57,0,6,1.74,1.88,5.46.88,9,0,7.35-1.82,19.55-4.84,29-6,4.81-.59,12-1.09,13-4,.57-1.65,0-3,0-3-.06-.14-.62-1.43-2-2-1.19-.49-2.36-.18-3,0-6.78,1.91-9.23,2.82-10,2-.45-.48-.17-1.39,0-2,1.77-6.29,1.22-12.36,1-14-.23-1.67-.84-6.18-4-8Z"/>
<path id="liteecho-1" class="cls-34" d="m448,440c-1.02.34-1.72,1.18-2,2-.31.93-.06,1.78,0,2,.38,1.39.25,7.26,0,19-.12,5.74-.36,7.73,0,12,.21,2.49.58,5.11,2,8,.87,1.76,1.83,3.72,4,5,2.08,1.23,4.09,1.14,7,1,2.69-.13,6.51-.31,7-2,.37-1.27-1.18-3.23-3-4-2.78-1.18-4.84.97-7,0-2.17-.97-2.69-4.29-3-7-1.07-9.45-.9-24.04-1-30-.02-1.36-.12-5.21-2-6-.58-.25-1.37-.21-2,0Z"/>
<path id="yuki-jp-4-1" class="cls-16" d="m636.06,390.95c-2.11.2-3.55,1.9-3.93,2.35-.57.68-.91,1.34-1.11,1.8,1.09,1.05,6.06,5.64,11.22,4.91,2.33-.33,5.1-1.81,5.34-2.63.03-.09.03-.17.03-.17,0-.29-.33-.71-1.89-1.83-1.33-.96-2.23-1.61-3.3-2.18-.69-.37-1.23-.6-1.68-.79-2.41-1.04-3.62-1.55-4.68-1.45Z"/>
<path id="yuki-jp-4" class="cls-12" d="m621,375c.37-.49,1.34-1.8,3-2,2.33-.28,3.93,1.89,4,2,.33.46.44.81,1,3,.59,2.3.88,3.45,1,4,.33,1.56.71,3.58,1,6,.65,5.37.61,6.78,1,10,.79,6.47,1.28,10.5,3,15,.07.18,1.23,3.21,1,7-.08,1.29-.29,2.25-1,3-1,1.07-2.67,1.39-4,1-.58-.17-1.69-.65-3-3-1.53-2.75-1.78-5.26-2-7-.3-2.39-.86-5.79-2-10-1-6.33-2-12.67-3-19-.33-1.67-.67-3.33-1-5-.1-.53-.53-2.95,1-5Z"/>
<path id="liteecho-i-1-1" class="cls-20" d="m474,451c-1.86-.04-3.59,1.27-4,3-.56,2.38,1.47,5.01,4,5,2.03-.01,4-1.72,4-4,0-2.25-1.92-3.96-4-4Z"/>
<path id="liteecho-i-1" class="cls-9" d="m475,464c-.61-.3-1.38-.31-2,0-.14.07-.62.33-1,1-1.18,2.08-1.01,7.51-1,8,.16,5.45,0,9,0,9-.08,1.78-.22,3.7,1,5,.21.22.94,1,2,1,1.08,0,1.81-.8,2-1,1.05-1.14,1.02-2.72,1-4-.03-2.33.04-4.67,0-7-.05-3.31.17-8.95-1-11-.12-.2-.41-.71-1-1Z"/>
<path id="liteecho-t" class="cls-8" d="m492.48,452.64c-.52.03-1.3.07-1.92.55-.25.19-.76.67-1.1,2.68-.15.92-.29,2.26-.14,3.91-1.17.01-3.52.16-5.32,1.22-.38.22-.77.51-1,1-.39.85-.08,1.91.41,2.59.74,1.01,1.99,1.19,3.59,1.41.85.12,1.57.12,2.05.1-.06.76-.12,1.85-.14,3.16-.01,1.22-.03,2.48.14,4.12.15,1.49.3,2.92.96,4.62.39,1.03.78,1.67,1,2,.25.39.74,1.08,1.48,1.76,1.12,1.05,2.67,2.5,4.52,2.24,1.2-.17,2.57-1.06,2.76-2.24.12-.76-.29-1.46-.55-1.92-.43-.76-.87-.99-1.51-1.65-.95-.97-1.44-1.93-1.78-2.61-.71-1.41-.9-2.61-1.1-3.85-.15-.97-.37-2.35-.14-4.12.09-.67.22-1.22.32-1.61.56,0,1.35-.04,2.29-.17,1.54-.21,2.32-.32,2.88-.82.8-.71,1.27-2.03.83-3.01-.13-.3-.38-.61-1-1-1.52-.94-3.22-1.02-4.36-.94.11-.49.27-1.25.41-2.2.49-3.18.14-3.81-.14-4.12-.26-.3-.59-.43-1.24-.69-.4-.16-1.18-.47-2.2-.41Z"/>
<path id="liteecho-e" class="cls-25" d="m515.41,469.49c-1.24,0-1.82.11-2.17.53-.63.76-.29,2.24.31,3.15,1.51,2.31,5.53,2.25,7.8,1.77,1.4-.3,4.49-.94,5.98-3.77,1.7-3.21-.04-6.62-.4-7.27-1.86-3.4-5.47-4.29-7.14-4.7-3.37-.83-6.16.05-7.27.4-1.07.34-2.81.91-4.53,2.4-3.45,2.98-3.92,7.09-4,8-.27,3.05.7,5.35,1,6,.27.6,1.17,2.42,3,4,1.04.89,2.16,1.53,3,2,.99.56,1.75.89,2,1,1.02.44,1.88.81,3,1,1.17.2,2.07.1,3,0,.34-.04,1.85-.22,4-1,3.3-1.2,4.59-2.54,5-3,.47-.53.68-.9.71-1.34.06-1.15-1.21-2.31-2.48-2.62-.51-.12-.94-.08-1.23-.05-2.01.26-3.04,1.28-4.31,1.86-2.59,1.19-5.84.41-7.69-.86-1.16-.8-1.95-1.93-2-2-.26-.38-.69-1.07-1-2-.26-.77-.95-2.86,0-5,.82-1.85,2.41-2.69,3-3,2.34-1.23,5.06-1.05,7,0,.69.37,1.64.9,2,2,.29.87.26,2.23-.52,2.84-1,.8-2.36-.34-6.07-.36Z"/>
<path id="liteecho-c" class="cls-29" d="m570,456c-1.16,0-4.12.04-7,2-1.54,1.05-2.49,2.26-3,3-1.62,2.38-1.87,4.7-2,6-.12,1.26-.36,4,1,7,2.14,4.72,6.61,6.52,8,7,1.04.36,4.93,1.64,9,0,.94-.38,2.74-1.13,4-3,.45-.66,1.99-2.94,1-5-.54-1.12-1.88-2.25-3-2-1.41.32-1.04,2.48-3,4-1.92,1.48-4.45,1.09-5,1-.54-.08-2.42-.41-4-2-2.4-2.42-2.04-5.66-2-6,.07-.51.43-3.37,3-5,2.25-1.43,5.33-1.38,7,0,.93.77.92,1.55,2,2,1.26.52,3.2.27,4-1,.72-1.15.17-2.56,0-3-.15-.38-.69-1.63-3-3-.98-.58-3.45-2.01-7-2Z"/>
<path id="liteecho-h" class="cls-17" d="m590,439c-.92-.49-2.08-.44-3,0-1.8.87-1.99,2.91-2,3v9c0,4,.04,8,0,12-.03,3,.1,6,0,9-.1,3.04-.29,5.38,1,8,.45.91,1.42,2.89,3,3,1.63.11,2.9-1.85,3-2,1.44-2.28.03-4.1,0-9-.02-2.85,0-5.82,2-8,.37-.4,1.8-1.97,4-2,2.44-.04,3.91,1.89,4,2,.92,1.22,1,2.52,1,3-.33,1.67-.67,3.33-1,5-.41,1.12-.91,2.85-1,5-.09,2.3-.16,3.99,1,5,1.28,1.11,3.61,1.02,5,0,1.65-1.21,1.8-3.61,2-7,.08-1.27.04-2.31,0-3v-8c-.02-.84-.16-2.36-1-4-.51-1-1.73-2.93-4-4-3.65-1.72-7.65-.14-8,0-1.5.62-2.24,1.36-3,1-.71-.34-.94-1.4-1-4-.12-5.04.61-6.66,0-10-.56-3.06-1.54-3.76-2-4Z"/>
<path id="liteecho-o" class="cls-33" d="m625,458c-4.27-.18-7.17,2.27-8,3-3.05,2.66-3.79,6-4,7-.18.88-1.21,5.84,2,10,2.08,2.69,4.82,3.62,6,4,1.29.42,4.46,1.39,8,0,2.95-1.16,4.51-3.31,5-4,1.43-2.02,1.81-3.97,2-5,.46-2.51.1-4.49,0-5-.67-3.35-2.52-5.47-3-6-.69-.76-3.46-3.8-8-4Z"/>
<path id="liteecho-o-white" class="cls-35" d="m623.5,464.5c-2.49.24-3.75,2.55-4,3-.09.17-1.81,3.42,0,6,1.68,2.39,5.6,3.06,8,1,2.1-1.8,2.13-4.93,1-7-.84-1.54-2.7-3.22-5-3Z"/>
<path id="lite-jp-2" class="cls-13" d="m481,384c-.71.63-1.32,1.81-1,3,.38,1.44,1.86,1.95,2,2,.77.25,1.44.12,2,0,4.88-1.04,5.31-1.31,6-1,1.18.54,1.54,2.08,2,4,.41,1.72.73,3.08,0,4-.65.81-2.11.89-5,1-1.25.05-2.29.03-3,0-.53.14-1.96.61-3,2-.4.54-1.21,1.61-1,3,.24,1.62,1.7,2.78,3,3,.44.08.79.03,1,0,4.59-.65,6.89-.98,7-1,2.55-.43,3.84-.64,4.45-.34,1.26.62,1.41,1.86,2.55,5.34,0,0,1.48,4.5,4,10,.8,1.75,1.53,3.13,2,4,.16.13,2.42,1.9,5,1,.16-.06,2.44-.88,3-3,.21-.78.1-1.42,0-2-.27-1.54-.96-2.26-2-4-.12-.21.03.04-2-4-.67-1.33-1.32-2.67-2-4-1.91-3.76-2.3-4.3-2-5,.2-.46.49-.53,4-2,1.13-.48,2.45-1.03,4-2,1.13-.71,1.71-1.21,2-2,.06-.17.35-1.03,0-2-.48-1.32-1.88-2.03-3-2-.31,0-.54.07-.66.11-2.2.63-4.77,1.67-5.34,1.89-2.21.88-3.31,1.31-4,1-.42-.19-.77-.54-2-4-1.21-3.42-1.11-3.77-1-4,.42-.85,1.37-.79,6-2,2.46-.64,3.57-1.02,4-2,.3-.68.14-1.39,0-2-.09-.4-.54-2.17-2-3-1.17-.66-2.4-.38-4,0-3.65.88-4.88,2.55-6,2-.55-.27-1.15-1.13-1-4-.42-2-.76-3-1-3h0c-.76-1.48-2.4-2.29-4-2-1.51.27-2.7,1.47-3,3-.17,2.45.41,4.01,1,5,.57.95,1.14,1.36,1,2-.24,1.14-2.45,1.64-4,2-2.38.55-3.11.2-4,1Z"/>
<path id="yuki-jp-1" class="cls-5" d="m526,396c-.46,1.12-.62,2.69,0,4,.19.41.79,1.49,2,2,1.22.51,2.43.16,3,0,5-1.43,7.51-2.15,8-2,4.42,1.34,3.64,20.08,7,22,2.14,1.22,4,1,4,1,1.43-.17,3.03-.97,3.02-1,0,0,0,0-.02,0,.27-.2.65-.52,1-1,1.53-2.12.85-5.32-1-10-3.3-8.33-6.24-11.07-5-13,.71-1.1,1.84-.46,5.57-2.36,2.51-1.27,4.06-2.06,4.43-3.64.46-1.98-1.11-4.46-3-5-1.01-.29-2.23.21-4.65,1.22-3.32,1.39-3.58,2.02-4.35,1.78-2.25-.7-.9-6.34-4-8-1.22-.65-2.84-.54-4,0-.31.14-1.56.73-2,2-.24.7-.14,1.29,0,2,.51,2.66,2.08,3.57,2,5.99,0,0,0,0,0,0,.01,0,.02,0,.02,0,.01.1-10.37-.01-12.02,4Z"/>
<path id="yuki-jp-2-3" class="cls-31" d="m603,386c-.23-.2-.95-.74-2-1-.58-.14-1.39-.34-2,0-.79.44-.86,1.6-1,3,0,0-.62,6.23-2,9-.43.86-.97,1.66-.97,1.66-.12.18-.24.35-.35.5-.2.27-.42.55-.68.84-1.47,1.68-5.93,4.2-5.93,4.2-3.23,1.82-3.66,2.04-4.07,2.8-.61,1.13-.9,2.9,0,4,.8.97,2.17.99,3,1,.7,0,3.05-.07,7.17-3.17,1.64-1.24,3.78-2.89,5.83-5.83,3.15-4.53,3.72-8.76,4-11,.52-4.2-.4-5.48-1-6Z"/>
<path id="liteecho-e2" class="cls-14" d="m540.81,469.18c-1.13.52-1.6.87-1.74,1.41-.25.96.69,2.15,1.62,2.72,2.35,1.44,5.96-.31,7.81-1.71,1.14-.86,3.66-2.76,3.81-5.96.17-3.63-2.85-5.97-3.45-6.41-3.13-2.29-6.78-1.55-8.46-1.22-3.41.68-5.55,2.66-6.41,3.45-.83.76-2.15,2.02-3.08,4.1-1.85,4.16-.53,8.09-.22,8.94,1.05,2.88,2.91,4.54,3.46,5,.5.42,2.09,1.69,4.42,2.34,1.32.37,2.61.46,3.57.53,1.13.08,1.96.06,2.24.05,1.11-.04,2.04-.06,3.14-.37,1.14-.32,1.92-.79,2.71-1.28.29-.18,1.58-.98,3.19-2.61,2.48-2.49,3.07-4.25,3.25-4.84.2-.68.24-1.11.07-1.51-.43-1.07-2.08-1.58-3.36-1.31-.51.11-.88.32-1.13.48-1.71,1.09-2.2,2.45-3.11,3.52-1.84,2.18-5.11,2.86-7.32,2.49-1.39-.23-2.59-.92-2.66-.96-.4-.23-1.08-.67-1.76-1.38-.56-.59-2.08-2.19-2.13-4.52-.04-2.02,1.04-3.46,1.44-3.99,1.59-2.11,4.14-3.1,6.33-2.98.79.04,1.86.12,2.66.96.63.67,1.18,1.91.74,2.79-.57,1.15-2.28.69-5.65,2.26Z"/>
</g>
<circle class="cls-23" cx="535" cy="411" r="4"/>
<ellipse class="cls-11" cx="556.49" cy="380.5" rx="2.51" ry="2.5"/>
<ellipse class="cls-26" cx="549.49" cy="383.5" rx="2.51" ry="2.5"/>
<circle class="cls-10" cx="557.98" cy="404.39" r="4"/>
<circle class="cls-1" cx="582.42" cy="391.26" r="4"/>
<circle class="cls-6" cx="590.42" cy="385.26" r="4"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,73 +0,0 @@
// 定义全局变量来存储数据
let globalTotal = 0;
let globalOnline = 0;
// 从API获取数据并更新全局变量
function fetchAndUpdateData() {
Promise.all([
fetch("https://api.liteyuki.icu/count").then(res => res.json()),
fetch("https://api.liteyuki.icu/online").then(res => res.json())
])
.then(([countRes, onlineRes]) => {
globalTotal = countRes.register;
globalOnline = onlineRes.online;
})
.catch(err => {
console.error("Error fetching data:", err);
});
}
// 更新页面显示,使用全局变量中的数据
function updatePageDisplay() {
let countInfo = document.getElementById("count-info");
if (!countInfo) {
let info = `<div id="count-info" style="text-align: center; font-size: 20px; font-weight: 500">
Instances:<span id="total">${globalTotal}</span>&nbsp;&nbsp;&nbsp;&nbsp;Online:<span id="online">${globalOnline}</span></div>`;
let mainDescription = document.querySelector("#main-description");
if (mainDescription) {
mainDescription.insertAdjacentHTML('afterend', info);
}
}
}
// 初始调用更新数据
fetchAndUpdateData();
updatePageDisplay();
// 设置定时器,分别以不同频率调用更新数据和更新页面的函数
setInterval(fetchAndUpdateData, 10000); // 每10秒更新一次数据
setInterval(updatePageDisplay, 1000); // 每1秒更新一次页面显示

View File

@ -1,93 +0,0 @@
echart = require('echarts');
let chart = echarts.init(document.getElementById('main-chart'));
const color = ['#9ae5fc', '#dcbf71']; // 自定义图中要用到的颜色
console.log("加载图标");
// 在地图加载完成后设置所有地区不可选
function setAllRegionsUnselectable(geoModel) {
const regions = geoModel.get('regions');
// 遍历所有地区并设置selected为false
for (let i = 0; i < regions.length; i++) {
const region = regions[i];
region.selected = false;
}
// 更新模型以反映更改
geoModel.set('regions', regions);
// 更新图表以显示更改
chart.setOption({
geo: {
regions: regions
}
});
}
// 获取数据并初始化图表
fetch('https://api.liteyuki.icu/distribution')
.then(response => response.json())
.then(data => {
// 构造 ECharts 需要的数据格式
const locations = data.locations;
const seriesData = locations.map(location => ({
value: [location[1], location[0]] // 直接使用经纬度数组
}));
console.log(seriesData);
// 初始化图表选项
chart.setOption({
backgroundColor: '#454545',
title: {
text: 'LiteyukiBot分布demo',
subtext: 'LiteyukiBot分布',
textStyle: {
color: '#fff',
fontSize: 20
},
top: '10px',
left: '10px'
},
geo: {
map: 'world',
roam: false,
itemStyle: {
normal: {
areaColor: '#000',
borderType: null, // 设置边界线类型为无
borderColor: '#000', // 设置边界线颜色
},
emphasis: {
areaColor: '#000',
borderType: null, // 设置边界线类型为无
borderColor: '#000', // 设置边界线颜色
}
},
regions: [] // 先保留为空
},
series: [{
// 散点效果
type: 'scatter',
coordinateSystem: 'geo', // 表示使用的坐标系为地理坐标系
symbolSize: 5, // 设置散点的大小为20
itemStyle: {
color: '#ffeb3b', // 黄色
},
data: seriesData
}],
textStyle: {
fontSize: 1
}
});
// 在地图加载完成后设置所有地区不可选
chart.on('ready', function () {
const geoModel = chart.getModel().componentModels.geo[0];
setAllRegionsUnselectable(geoModel);
});
// 自适应窗口大小变化
window.addEventListener("resize", function () {
chart.resize();
});
})
.catch(error => console.error('Error fetching data:', error));

View File

@ -1,31 +0,0 @@
function applyStyle() {
// 先检测页面中是否有macos-tab有则不再添加
let tabs = document.body.querySelectorAll('.macos-tab')
if (tabs.length > 0) {
return
}
let lineNumbers = document.body.querySelectorAll('[class^="language-"].line-numbers-mode')
lineNumbers.forEach((item) => {
// 插入现成的html文本
let title = item.getAttribute('data-title')
let tabStr =
"<div class='tab macos-tab' style='display: flex; background-color: #d0e9ff'>" +
" <div class='tab-buttons'>" +
" <div class='tab-button' style='background-color: #FF5F57'></div>" +
" <div class='tab-button' style='background-color: #FFBD2E'></div>" +
" <div class='tab-button' style='background-color: #27C93F'></div>" +
" </div>" +
` <div class='tab-title'>${title}</div>` +
" <div style='flex: 1'></div>" +
"</div>"
// 在代码块前插入选项卡
item.insertAdjacentHTML('beforebegin', tabStr);
})
}
applyStyle()
// 定时器每隔1s检查一次
setInterval(() => {
applyStyle()
}, 1000)

File diff suppressed because one or more lines are too long

View File

@ -1,73 +0,0 @@
// 定义全局变量来存储数据
let globalTotal = 0;
let globalOnline = 0;
// 从API获取数据并更新全局变量
function fetchAndUpdateData() {
Promise.all([
fetch("https://api.liteyuki.icu/count").then(res => res.json()),
fetch("https://api.liteyuki.icu/online").then(res => res.json())
])
.then(([countRes, onlineRes]) => {
globalTotal = countRes.register;
globalOnline = onlineRes.online;
})
.catch(err => {
console.error("Error fetching data:", err);
});
}
// 更新页面显示,使用全局变量中的数据
function updatePageDisplay() {
let countInfo = document.getElementById("count-info");
if (!countInfo) {
let info = `<div id="count-info" style="text-align: center; font-size: 20px; font-weight: 500">
全球实例:<span id="total">${globalTotal}</span>&nbsp;&nbsp;&nbsp;&nbsp;线:<span id="online">${globalOnline}</span></div>`;
let mainDescription = document.querySelector("#main-description");
if (mainDescription) {
mainDescription.insertAdjacentHTML('afterend', info);
}
}
}
// 初始调用更新数据
fetchAndUpdateData();
updatePageDisplay();
// 设置定时器,分别以不同频率调用更新数据和更新页面的函数
setInterval(fetchAndUpdateData, 10000); // 每10秒更新一次数据
setInterval(updatePageDisplay, 1000); // 每1秒更新一次页面显示

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" class="icon" viewBox="0 0 3280.944 2800"><path fill="#41b883" d="M1645.332 601.004h375.675L1081.82 2238.478 142.636 601.004h718.477l220.708 379.704 216.013-379.704z"/><path fill="#41b883" d="M142.636 601.004l939.185 1637.474 939.186-1637.474h-375.675l-563.51 982.484-568.208-982.484z"/><path fill="#35495e" d="M513.188 601.004l568.207 987.23 563.511-987.23h-347.498l-216.013 379.704-220.708-379.704zM1607.792 1311.83l594.678 2.293 187.353-316.325-598.662 2.292zM2198.506 1909.57C2867.436 732.7 2939.502 605.426 2937.874 603.78c-.715-.723 45.303-1.314 102.262-1.314s103.562.428 103.562.951c0 .523-208.57 367.978-463.491 816.567L2216.715 2235.6l-102.1.596-102.102.596z"/><path fill="#41b883" d="M1680.563 2233.328c0-1.34 168.208-298.145 440.375-777.048a4135645.775 4135645.775 0 00337.619-594.19l146.13-257.25 170.746-.04 170.747-.04-5.536 9.741c-3.044 5.358-43.727 77.302-90.407 159.875-85.356 150.992-337.562 595.163-656.602 1156.373l-172 302.559-170.536.588c-93.795.322-170.536.069-170.536-.567z"/><path fill="#35495e" d="M1429.783 1625.351l594.679 2.292 187.353-316.324-598.662 2.292z"/><path fill="#41b883" d="M1524.207 1464.903l608.285 6.877 173.746-320.909h-619.072z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,10 +0,0 @@
import {sidebar} from "vuepress-theme-hope";
export const enSidebarConfig = sidebar(
{
"/en/deploy/": "structure",
"/en/usage/": "structure",
"/en/store/": "structure",
"/en/dev/": "structure",
}
)

View File

@ -1,2 +0,0 @@
export * from "./zh.js"
export * from "./en.js"

View File

@ -1,11 +0,0 @@
import {sidebar} from "vuepress-theme-hope";
export const zhSidebarConfig = sidebar(
{
"/deploy/": "structure",
"/usage/": "structure",
"/store/": "structure",
"/dev/": "structure",
}
)

View File

@ -1,7 +0,0 @@
// you can change config here
$colors: #c0392b, #d35400, #f39c12, #27ae60, #16a085, #2980b9, #8e44ad, #2c3e50,
#7f8c8d !default;
body {
overflow-x: hidden;
}

View File

@ -1,100 +0,0 @@
// place your custom styles here
:root {
--code-window-border-radius: 10px;
--button-distance: 8px;
}
#main-title {
font-family: ColorTube, "Fira Code", serif;
color: #ff0000 !important; /* 你想要的颜色 */
line-height: 2;
}
@font-face {
font-family: ColorTube;
src: url("/assets/fonts/ColorTube.woff") format("woff")
}
code {
font-family: "Fira Code", monospace !important;
}
.vp-hero-image {
overflow: hidden;
padding: -50px;
}
#main-title {
display: none;
}
.theme-hope-content pre {
overflow: auto;
margin: 0 0;
padding: 1rem;
border-radius: 6px;
line-height: 1.375;
}
// 移除该before
.theme-hope-content pre::before {
content: none;
}
.theme-hope-content > div[class*=language-] {
margin: 0 0 0 0;
// 仅下半部分有圆弧
border-radius: 0 0 var(--code-window-border-radius) var(--code-window-border-radius);
}
.tab {
display: flex;
height: 25px;
margin-bottom: 0;
justify-content: space-between;
align-items: center;
border-top-left-radius: var(--code-window-border-radius);
border-top-right-radius: var(--code-window-border-radius);
}
.tab-buttons {
padding: 7px;
flex: 1;
display: flex;
justify-content: flex-start;
height: 60%;
align-items: center;
}
.tab-button {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-right: var(--button-distance);
border-radius: 50%;
height: 100%;
aspect-ratio: 1/1;
}
.tab-title {
text-align: center;
justify-content: center;
flex: 1;
}
.item-search-box {
border-radius: 100px;
width: 80%;
padding: 10px;
margin: 10px 0;
border: 1px solid #ccc;
}
.search-box-div {
display: flex;
justify-content: space-around;
margin: 10px 0;
}
.item-search-box {
width: 80%;
}

View File

@ -1,2 +0,0 @@
// you can change colors here
$theme-color: #00a6ff;

View File

@ -1,203 +0,0 @@
import {hopeTheme} from "vuepress-theme-hope";
import {enSidebarConfig, zhSidebarConfig} from "./sidebar/index.js";
import {enNavbarConfig, zhNavbarConfig} from "./navbar/index.js";
export default hopeTheme({
hostname: "https://vuepress-theme-hope-docs-demo.netlify.app",
hotReload: true,
locales: {
"/": {
navbar: zhNavbarConfig,
sidebar: zhSidebarConfig,
author: {
name: "远野千束",
url: "https://sfkm.me",
}
},
"/en/": {
navbar: enNavbarConfig,
sidebar: enSidebarConfig,
author: {
name: "SnowyKami",
url: "https://sfkm.me",
}
}
},
iconAssets: "fontawesome-with-brands",
logo: "https://cdn.liteyuki.icu/static/img/liteyuki_icon_640.png",
repo: "https://github.com/LiteyukiStudio/LiteyukiBot",
docsDir: "docs",
// 页脚
footer: "LiteyukiBot",
displayFooter: true,
// 加密配置
encrypt: {
config: {
"/demo/encrypt.html": ["1234"],
},
},
// 多语言配置
metaLocales: {
editLink: "在 GitHub 上编辑",
},
// 如果想要实时查看任何改变,启用它。注: 这对更新性能有很大负面影响
// hotReload: true,
// 在这里配置主题提供的插件
plugins: {
search: true,
// search: true,
comment: {
provider: "Giscus",
repo: "snowykami/LiteyukiBot",
repoId: "R_kgDOHVNKpQ",
category: "Announcements",
categoryId: "DIC_kwDOHVNKpc4CeWxj",
},
components: {
components: ["Badge", "VPCard"],
},
// 此处开启了很多功能用于演示,你应仅保留用到的功能。
mdEnhance: {
echarts: true,
alert: true,
align: true,
attrs: true,
codetabs: true,
footnote: true,
component: true,
demo: true,
figure: true,
imgLazyload: true,
imgSize: true,
include: true,
mark: true,
stylize: [
{
matcher: "Recommended",
replacer: ({tag}) => {
if (tag === "em")
return {
tag: "Badge",
attrs: {type: "tip"},
content: "Recommended",
};
},
},
],
sub: true,
sup: true,
tabs: true,
vPre: true,
// 在启用之前安装 chart.js
// chart: true,
// insert component easily
// 在启用之前安装 echarts
// echarts: true,
// 在启用之前安装 flowchart.ts
// flowchart: true,
// gfm requires mathjax-full to provide tex support
// gfm: true,
// 在启用之前安装 katex
// katex: true,
// 在启用之前安装 mathjax-full
// mathjax: true,
// 在启用之前安装 mermaid
// mermaid: true,
// playground: {
// presets: ["ts", "vue"],
// },
// 在启用之前安装 reveal.js
// revealJs: {
// plugins: ["highlight", "math", "search", "notes", "zoom"],
// },
// 在启用之前安装 @vue/repl
// vuePlayground: true,
// install sandpack-vue3 before enabling it
// sandpack: true,
},
// 如果你需要 PWA。安装 @vuepress/plugin-pwa 并取消下方注释
// pwa: {
// favicon: "/favicon.ico",
// cacheHTML: true,
// cachePic: true,
// appendBase: true,
// apple: {
// icon: "/assets/icon/apple-icon-152.png",
// statusBarColor: "black",
// },
// msTile: {
// image: "/assets/icon/ms-icon-144.png",
// color: "#ffffff",
// },
// manifest: {
// icons: [
// {
// src: "/assets/icon/chrome-mask-512.png",
// sizes: "512x512",
// purpose: "maskable",
// type: "image/png",
// },
// {
// src: "/assets/icon/chrome-mask-192.png",
// sizes: "192x192",
// purpose: "maskable",
// type: "image/png",
// },
// {
// src: "/assets/icon/chrome-512.png",
// sizes: "512x512",
// type: "image/png",
// },
// {
// src: "/assets/icon/chrome-192.png",
// sizes: "192x192",
// type: "image/png",
// },
// ],
// shortcuts: [
// {
// name: "Demo",
// short_name: "Demo",
// url: "/demo/",
// icons: [
// {
// src: "/assets/icon/guide-maskable.png",
// sizes: "192x192",
// purpose: "maskable",
// type: "image/png",
// },
// ],
// },
// ],
// },
// },
},
});

View File

@ -1,82 +0,0 @@
---
home: true
icon: home
title: 首页
heroImage: https://cdn.liteyuki.icu/static/svg/lylogo-full.svg
heroImageDark: https://cdn.liteyuki.icu/static/svg/lylogo-full-dark.svg
bgImage:
bgImageDark:
bgImageStyle:
background-attachment: fixed
heroText: LiteyukiBot
tagline: LiteyukiBot 轻雪机器人,综合性的机器人应用及管理框架
actions:
- text: 快速部署
icon: rocket
link: ./deploy/install.html
type: primary
- text: 使用手册
icon: book
link: ./usage/basic_command.html
highlights:
- header: 简洁至上
image: /assets/image/layout.svg
bgImage: https://theme-hope-assets.vuejs.press/bg/2-light.svg
bgImageDark: https://theme-hope-assets.vuejs.press/bg/2-dark.svg
bgImageStyle:
background-repeat: repeat
background-size: initial
features:
- title: 支持多种框架
icon: robot
details: 兼容nonebotmelobot等拥有良好的生态支持
link: https://nonebot.dev/
- title: 便捷管理
icon: plug
details: 使用包管理器,便捷管理插件及资源包
- title: 主题支持
icon: paint-brush
details: 使用资源包对外观进行完全自定义
link: https://bot.liteyuki.icu/usage/resource_pack.html
- title: 国际化
icon: globe
details: 通过资源包支持多种语言
link: https://baike.baidu.com/item/i18n/6771940
- title: 简易使用
icon: cog
details: 无需繁琐前期过程,开箱即用
link: https://bot.liteyuki.icu/deployment/config.html
- title: 超高性能
icon: tachometer-alt
details: 500个插件2s内启动
- title: 滚动更新
icon: cloud-download
details: 让你的机器人保持最新提交
- title: 开源项目
icon: code
details: 项目遵循MIT LICENCE开源欢迎各位的贡献
- header: 快速部署
image: /assets/image/box.svg
bgImage: https://theme-hope-assets.vuejs.press/bg/3-light.svg
bgImageDark: https://theme-hope-assets.vuejs.press/bg/3-dark.svg
highlights:
- title: 安装 Git 及 Python3.10+
- title: 使用 <code>git clone https://github.com/LiteyukiStudio/LiteyukiBot --depth=1</code> 以克隆项目至本地。
details: 如果无法连接到GitHub可以使用 <code>git clone https://gitee.com/snowykami/LiteyukiBot --depth=1</code>
- title: 使用 <code>cd LiteyukiBot</code> 切换到项目目录。
- title: 使用 <code>pip install -r requirements.txt</code> 安装项目依赖。
details: 如果你有多个 Python 环境,请使用 <code>pythonx -m pip install -r requirements.txt</code>
- title: 使用 <code>python main.py</code> 启动项目。
copyright: © 2021-2024 SnowyKami All Rights Reserved
---

View File

@ -0,0 +1,26 @@
<script setup lang="ts">
import {getTextRef} from "./scripts/i18n";
import {repoPath, repoURL} from "./scripts/const";
const contributorImgSrc = `https://contrib.rocks/image?repo=${repoPath}`
const contributorsUrl = `${repoURL}/graphs/contributors`
</script>
<template>
<div class="contributor-bar">
<h2>{{ getTextRef('thx_contributors') }}</h2>
<a :href="contributorsUrl">
<div class="contributor-list">
<img :src=contributorImgSrc alt="Contributors">
</div>
</a>
</div>
</template>
<style scoped>
.contributor-bar {
display: flex;
flex-direction: column;
align-items: center;
}
</style>

View File

View File

View File

View File

@ -2,16 +2,19 @@
<div class="item-card">
<div class="item-name">{{ props.item.name }}</div>
<div class="item-description">{{ props.item.desc }}</div>
<div class="tags">
<span class="tag" v-for="tag in props.item.tags" :key="tag" :style=getTagStyle(tag.color)>{{ tag.label }}</span>
</div>
<div class="item-bar">
<!-- 三个可点击svg一个github一个下载一个可点击"https://github.com/{{ username }}.png?size=80"个人头像配上id-->
<a :href=props.item.homepage class="btn">
<a :href=props.item.homepage class="btn" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16">
<path fill="currentColor"
d="m7.775 3.275l1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0a.751.751 0 0 1 .018-1.042a.751.751 0 0 1 1.042-.018a1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018a.751.751 0 0 1-.018-1.042m-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018a.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0a.751.751 0 0 1-.018 1.042a.751.751 0 0 1-1.042.018a1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83"/>
</svg>
</a>
<!-- <button class="copy-btn btn"><div @click="copyToClipboard">安装</div></button> 点击后把安装命令写入剪贴板-->
<!-- <button class="copy-btn btn"><div @click="copyToClipboard">安装</div></button> 点击后把安装命令写入剪贴板-->
<button class="btn copy-btn" @click="copyToClipboard">复制安装命令</button>
<div class="btn">
@ -45,22 +48,26 @@ const copyToClipboard = () => {
})
}
const getTagStyle = (backgroundColor: string) => {
// RGB
const rgb = backgroundColor.replace(/^#/, '');
const [r, g, b] = rgb.match(/.{2}/g).map(x => parseInt(x, 16));
//
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
//
return {
backgroundColor: backgroundColor,
color: brightness > 128 ? '#000' : '#fff'
};
};
//
</script>
<style scoped>
.item-card {
position: relative;
border-radius: 15px;
background-color: #00000011;
height: 160px;
padding: 16px;
margin: 10px;
box-sizing: border-box;
transition: background 0.3s ease;
}
.btn {
margin-right: 15px;
}
@ -75,43 +82,11 @@ button {
color: #666;
}
.copy-btn:hover {
color: #111;
}
.item-name {
color: #111;
font-size: 20px;
margin-bottom: 10px;
}
.item-description {
color: #333;
font-size: 12px;
white-space: pre-wrap;
}
.icon {
width: 20px;
height: 20px;
color: $themeColor;
}
.author-info {
display: flex;
justify-content: left;
align-items: center;
}
.author-name {
font-size: 15px;
font-weight: normal;
}
.avatar {
border-radius: 50%;
margin: 0 10px;
}
.item-bar {
position: absolute;
@ -123,4 +98,12 @@ button {
justify-content: space-between;
color: #00000055;
}
.tag {
display: inline-block;
padding: 0 5px;
margin-right: 5px;
border-radius: 5px;
font-size: 12px;
}
</style>

91
docs/components/PluginStore.vue Executable file
View File

@ -0,0 +1,91 @@
<script setup lang="ts">
import {computed, ref} from 'vue'
import ItemCard from './PluginItemCard.vue'
import ToggleSwitch from "./ToggleSwitch.vue";
import {getTextRef} from "./scripts/i18n";
import pluginsJson from "../public/plugins.json"
let showLiteyukiPluginOnly = ref(false)
let filteredItems = computed(() => {
let filtered = items.value
if (search.value) {
filtered = filtered.filter(item =>
item.name.toLowerCase().includes(search.value.toLowerCase()) ||
item.desc.toLowerCase().includes(search.value.toLowerCase()) ||
item.author.toLowerCase().includes(search.value.toLowerCase()) ||
item.module_name.toLowerCase().includes(search.value.toLowerCase())
)
}
if (showLiteyukiPluginOnly.value) {
filtered = filtered.filter(item => item.is_liteyuki_plugin)
}
return filtered
})
// Nonebot
let items = ref([])
let search = ref('')
//
items.value = pluginsJson
items.value.forEach(item => {
item.is_liteyuki_plugin = true
})
//
fetch('https://registry.nonebot.dev/plugins.json')
.then(response => response.json())
.then(data => {
// datais_officialfalse
data.forEach(item => {
item.is_official = false
})
items.value = items.value.concat(data)
})
</script>
<template>
<div class="market">
<h1>{{ getTextRef('pluginStore') }}</h1>
<p>{{ getTextRef('pluginStoreDesc') }}</p>
<!-- 搜索框-->
<div class="search-box-div">
<input class="item-search-box" type="text" v-model="search" :placeholder="getTextRef('search')"/>
<ToggleSwitch v-model:modelValue="showLiteyukiPluginOnly"/>
{{ getTextRef('liteyukiOnly') }}
</div>
<!-- 按钮们-->
<!-- <div class="tab">-->
<!-- <button @click="open"-->
<!-- </div>-->
<div class="items">
<!-- 使用filteredItems来布局商品 -->
<ItemCard v-for="item in filteredItems" :key="item.id" :item="item"/>
</div>
</div>
</template>
<style scoped>
h1 {
color: #00a6ff;
text-align: center;
font-weight: bold;
}
.items {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 10px;
}
.search-box-div {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
}
.search-box-div input {
margin-right: 10px;
}
</style>

View File

@ -4,7 +4,7 @@
<div class="item-description">{{ props.item.description }}</div>
<div class="item-bar">
<!-- 三个可点击svg一个github一个下载一个可点击"https://github.com/{{ username }}.png?size=80"个人头像配上id-->
<a :href=props.item.link class="">
<a :href=props.item.link class="" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16">
<path fill="currentColor"
d="m7.775 3.275l1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0a.751.751 0 0 1 .018-1.042a.751.751 0 0 1 1.042-.018a1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018a.751.751 0 0 1-.018-1.042m-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018a.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0a.751.751 0 0 1-.018 1.042a.751.751 0 0 1-1.042.018a1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83"/>
@ -28,32 +28,8 @@ const props = defineProps({
</script>
<style scoped>
.item-card {
position: relative;
border-radius: 15px;
background-color: #00000011;
height: 160px;
padding: 16px;
margin: 10px;
box-sizing: border-box;
transition: background 0.3s ease;
}
.item-card:hover {
border: 2px solid $themeColor;
}
.item-name {
color: $themeColor;
font-size: 20px;
margin-bottom: 10px;
}
.item-description {
color: #333;
font-size: 15px;
white-space: pre-wrap;
}
.icon {
width: 20px;
@ -61,21 +37,9 @@ const props = defineProps({
color: $themeColor;
}
.author-info {
display: flex;
justify-content: left;
align-items: center;
}
.author-name {
font-size: 15px;
font-weight: normal;
}
.avatar {
border-radius: 50%;
margin: 0 10px;
}
.item-bar {
position: absolute;

View File

@ -0,0 +1,38 @@
<template>
<div v-if="isVisible" class="floating-window">
<div class="window-content">
<slot></slot>
</div>
</div>
</template>
<script setup lang="ts">
import {defineProps} from 'vue'
const props = defineProps({
isVisible: Boolean,
})
</script>
<style scoped>
.floating-window {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.window-content {
background: var(--vp-c-gray-1);
padding: 20px;
border-radius: 5px;
max-width: 60%;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
</style>

105
docs/components/ResStore.vue Executable file
View File

@ -0,0 +1,105 @@
<script setup lang="ts">
import {computed, ref} from 'vue'
import ItemCard from './ResItemCard.vue'
import ResPubWindow from "./ResPubWindow.vue";
import {getTextRef, formatLang} from "./scripts/i18n";
import {RepoUrl} from "./scripts/statsApi";
import resourcesJson from "../public/resources.json"
import {useData} from "vitepress";
// formLan
// public/assets/resources.json
let filteredItems = computed(() => {
if (!search.value) {
return items.value.reverse()
}
return items.value.filter(item =>
item.name.toLowerCase().includes(search.value.toLowerCase()) ||
item.description.toLowerCase().includes(search.value.toLowerCase()) ||
item.author.toLowerCase().includes(search.value.toLowerCase())
).reverse()
})
// Nonebot
let items = ref([])
let search = ref('')
items.value = resourcesJson
//
const isPublishWindowOpen = ref(false)
let newRes = ref({
name: '',
})
function openPublishWindow() {
isPublishWindowOpen.value = true
}
function closePublishWindow() {
isPublishWindowOpen.value = false
}
let submitLang = ""
if (formatLang(useData().site.value.lang) === "zh") {
submitLang = "zh"
} else {
submitLang = "en"
}
function submitForm() {
const title = encodeURI(`Resource: ${newRes.value.name}`)
const issueURL = `${RepoUrl}/issues/new?assignees=&labels=Resource&template=resource_publish_${submitLang}.yml&title=${title}`
console.log(issueURL)
window.open(issueURL, '_blank')
}
</script>
<template>
<div class="market">
<h1>{{ getTextRef('resourceStore') }}</h1>
<div class="search-box-div"><input class="item-search-box" type="text" :placeholder="getTextRef('search')"
v-model="search"/></div>
<div class="store-tabs" style="display: flex">
<button class="store-button publish-button" @click="openPublishWindow">{{ getTextRef('publishRes') }}</button>
</div>
<div class="items">
<!-- 使用filteredItems来布局商品 -->
<ItemCard v-for="item in filteredItems" :key="item.id" :item="item"/>
</div>
<ResPubWindow class="pub-window" :is-visible="isPublishWindowOpen">
<h2>{{ getTextRef("publishRes") }}</h2>
<form @submit.prevent="submitForm">
<label for="name">{{ getTextRef("resName") }}</label>
<input type="text" id="name" v-model="newRes.name" :placeholder="getTextRef('resNameText')"/>
<div class="pub-options" style="display: flex; justify-content: center">
<button class="pub-option close" type="button" @click="closePublishWindow">{{
getTextRef("closeButtonText")
}}
</button>
<button class="pub-option submit" type="submit" @click="submitForm">{{
getTextRef("submitButtonText")
}}
</button>
</div>
</form>
</ResPubWindow>
</div>
</template>
<style scoped>
h1 {
color: #00a6ff;
text-align: center;
font-weight: bold;
}
.items {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 10px;
}
</style>

301
docs/components/StatsBar.vue Executable file
View File

@ -0,0 +1,301 @@
<script setup lang="ts">
import DefaultTheme from "vitepress/theme";
import {ref, onMounted, onUnmounted} from "vue";
import {statsApi, GithubStats, RepoUrl, StarMapUrl, uploadVisitRecord} from "./scripts/statsApi";
import {getTextRef, updateRefData} from "./scripts/i18n";
import {onBeforeRouteUpdate} from 'vue-router';
const {Layout} = DefaultTheme;
let githubStats: GithubStats | null = null;
const dataSections = {
total: {
name: 'total',
color: '#00a6ff',
value: ref(-1),
link: StarMapUrl
},
online: {
name: 'online',
color: '#7eff7e',
value: ref(-1),
link: StarMapUrl
},
stars: {
name: 'stars',
color: '#ffcc00',
value: ref(-1),
link: `${RepoUrl}/stargazers`
},
forks: {
name: 'forks',
color: '#ff6600',
value: ref(-1),
link: `${RepoUrl}/forks`
},
issues: {
name: 'issues',
color: '#ff0000',
value: ref(-1),
link: `${RepoUrl}/issues`
},
prs: {
name: 'prs',
color: '#f15df1',
value: ref(-1),
link: `${RepoUrl}/pulls`
},
plugins: {
name: 'plugins',
color: '#a766ff',
value: ref(-1),
link: './store/plugin'
},
resources: {
name: 'resources',
color: '#5a54fa',
value: ref(-1),
link: './store/resource'
},
visitors: {
name: 'visitors',
color: '#00a6ff',
value: ref(-1),
link: RepoUrl
},
}
async function updateData() {
// dataSections.online.value.value = await statsApi.getOnline();
// dataSections.total.value.value = await statsApi.getTotal();
[
dataSections.online.value.value,
dataSections.total.value.value,
dataSections.plugins.value.value,
dataSections.resources.value.value,
dataSections.visitors.value.value,
githubStats,
] = await Promise.all([
statsApi.getOnline(),
statsApi.getTotal(),
statsApi.getPluginNum(),
statsApi.getResourceNum(),
statsApi.getVisitCount(),
statsApi.getGithubStats(),
]);
dataSections.stars.value.value = githubStats?.stars || 0;
dataSections.forks.value.value = githubStats?.forks || 0;
dataSections.issues.value.value = githubStats?.issues || 0;
dataSections.prs.value.value = githubStats?.prs || 0;
}
function formatNumber(num: { value: number }): string {
return num.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
onMounted(() => {
const intervalId = setInterval(updateData, 10000);
updateData();
uploadVisitRecord();
onUnmounted(() => {
clearInterval(intervalId);
});
});
onBeforeRouteUpdate(() => {
updateRefData();
});
console.log(
" _ _ _ _ _ ____ _ \n" +
" | | (_) | | | (_) _ \\ | | \n" +
" | | _| |_ ___ _ _ _ _| | ___| |_) | ___ | |_ \n" +
" | | | | __/ _ \\ | | | | | | |/ / | _ < / _ \\| __|\n" +
" | |____| | || __/ |_| | |_| | <| | |_) | (_) | |_ \n" +
" |______|_|\\__\\___|\\__, |\\__,_|_|\\_\\_|____/ \\___/ \\__|\n" +
" __/ | \n" +
" |___/ "
)
console.log(
getTextRef('easterEgg')
)
</script>
<template>
<Layout>
<template #home-features-before>
<div class="stats-bar-content">
<div class="stats-bar">
<div class="stats-info">
<div class="stats-title">{{ getTextRef('stats') }}</div>
<div class="sections">
<div v-for="section in Object.values(dataSections)" :key="section.name" class="section">
<a :href="section.link" target="_blank">
<div class="section-tab">
<span class="dot" :style="{backgroundColor: section.color}"></span>
<span class="text">{{ getTextRef(section.name) }}</span>
</div>
<div class="number">{{ formatNumber(section.value) }}</div>
</a>
</div>
</div>
</div>
<div class="starmap">
<iframe src="https://starmap.liteyuki.icu/" width="100%" height="300px" class="gamma">
</iframe>
</div>
</div>
</div>
</template>
</Layout>
</template>
<style scoped>
.stats-bar-content {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.gamma {
filter: brightness(1.8);
}
.dark .gamma {
filter: brightness(1.0);
}
.stats-bar {
width: 80%;
max-width: 1150px;
display: flex;
justify-content: space-between;
padding: 20px;
margin: 10px;
border-radius: var(--border-radius-2);
background-color: var(--vp-c-gray-1);
flex-direction: column; /* 默认纵向布局 */
}
.stats-info{
margin-bottom: 20px;
}
.stats-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 20px;
text-align: center;
}
.sections {
height: 100%;
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 15px;
margin: 10px;
}
.section {
display: flex;
flex-direction: column;
position: relative; /* 使伪元素相对于父元素定位 */
border-radius: var(--border-radius-2);
}
.section::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 0 solid transparent; /* 初始边框为透明 */
transition: border 0.1s ease-in-out; /* 添加过渡效果 */
border-radius: var(--border-radius-2);
pointer-events: none; /* 确保伪元素不会阻挡点击事件 */
}
.section:hover::before {
border: 1px solid #00a6ff; /* 悬停时添加边框 */
border-radius: var(--border-radius-2);
}
.section-tab {
margin-left: 15px;
display: flex;
justify-content: flex-start;
align-items: center; /* 确保垂直居中 */
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 5px;
}
.text {
font-size: 14px;
white-space: nowrap;
align-items: center;
}
.number {
font-size: 27px;
font-weight: bold;
margin-top: 5px;
margin-left: 15px;
}
.starmap {
position: relative;
width: 100%;
height: 200px;
overflow: hidden;
border-radius: var(--border-radius-2);
}
.starmap iframe {
position: absolute;
top: -150px; /* 根据需要调整裁剪位置 */
left: -40px; /* 根据需要调整裁剪位置 */;
width: calc(100% + 80px); /* 根据需要调整裁剪宽度 */
height: calc(100% + 300px); /* 根据需要调整裁剪高度 */
}
@media (min-width: 768px) {
/* PC模式下的样式 */
.stats-bar {
flex-direction: row;
margin: 30px;
}
.stats-info {
width: 40%;
margin: 10px 30px 30px 30px;
}
.starmap {
width: 60%;
height: 400px;
}
.starmap iframe {
position: absolute;
top: -130px; /* 根据需要调整裁剪位置 */
left: -60px; /* 根据需要调整裁剪位置 */;
width: calc(100% + 120px); /* 根据需要调整裁剪宽度 */
height: calc(100% + 280px); /* 根据需要调整裁剪高度 */
}
}
</style>

View File

View File

@ -0,0 +1,67 @@
<template>
<label class="switch">
<input type="checkbox" :checked="modelValue" @change="updateValue($event.target.checked)">
<span class="slider round"></span>
</label>
</template>
<script setup lang="ts">
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
modelValue: Boolean
})
const emit = defineEmits(['update:modelValue'])
const updateValue = (value: boolean) => {
emit('update:modelValue', value)
}
</script>
<style scoped>
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #2196F3;
}
input:checked + .slider:before {
transform: translateX(26px); /* 调整为 26px 以确保对齐 */
}
</style>

View File

@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,4 @@
export const platformBaseURL = "https://github.com/"
export const repoPath = "LiteyukiStudio/LiteyukiBot"
export const repoURL = `${platformBaseURL}${repoPath}`

112
docs/components/scripts/i18n.ts Executable file
View File

@ -0,0 +1,112 @@
import {ref} from "vue";
import {useData} from "vitepress";
const i18nData = {
en: {
stats: 'Stats',
online: 'Online',
offline: 'Offline',
total: 'Total',
fetching: 'Fetching',
stars: 'Stars',
forks: 'Forks',
issues: 'Issues',
prs: 'Pull Requests',
visitors: 'Visitors',
size: 'Size',
plugins: 'Plugins',
resources: 'Resources',
pluginStore: 'Plugin Store',
pluginStoreDesc: 'Content from the LightSnow Plugin Store, LightSnow supports NoneBot through the lpnonebot plugin, and references some NoneBot plugins',
liteyukiOnly: 'Liteyuki Only',
search: 'Search',
resourceStore: 'Resources Store',
thx_contributors: 'Thanks the following contributors!',
easterEgg: 'Congratulations on finding the Easter egg!',
publishPlugin: 'Publish Plugin',
publishRes: 'Publish Resource',
closeButtonText: 'Close',
submitButtonText: 'Submit',
resName: 'Name',
resDesc: 'Description',
resAuthor: 'Author',
resLink: 'Download Link',
resHomepage: 'Homepage',
resNameText: 'Example: Kawaii Style Theme',
resDescText: 'Example: A kawaii style and color theme',
resAuthorText: 'Usually the github username, Example: yanyongyu',
resLinkText: 'Direct download link, usually zip package link',
resHomepageText: 'Optional, can be the name of the git platform repository"',
},
zh: {
stats: '统计信息',
online: '在线',
offline: '离线',
total: '实例',
fetching: '获取中',
stars: '星星',
forks: '分叉',
issues: '议题',
prs: '拉取请求',
visitors: '访客',
size: '大小',
plugins: '插件',
resources: '主题资源',
store: '商店',
pluginStore: '插件商店',
pluginStoreDesc: '内容来自轻雪插件商店轻雪通过lpnonebot插件对NoneBot实现支持引用了部分NoneBot插件',
liteyukiOnly: '仅轻雪',
search: '搜索',
resourceStore: '资源商店',
thx_contributors: '感谢以下贡献者!',
easterEgg: '恭喜你发现了彩蛋!',
publishPlugin: '发布插件',
publishRes: '发布资源',
closeButtonText: '关闭',
submitButtonText: '提交',
resName: '名称',
resDesc: '描述',
resAuthor: '作者',
resLink: '下载链接',
resHomepage: '主页',
resNameText: '示例:可爱风格主题',
resDescText: '示例:一个可爱风格和配色的主题',
resAuthorText: '通常为github用户名示例yanyongyu',
resLinkText: '直接下载链接通常为zip包链接',
resHomepageText: '可选可为git平台仓库名',
}
}
let refData = {}
function getText(lang: string, key: string): string {
lang = formatLang(lang);
return i18nData[lang][key];
}
export function formatLang(lang: string): string {
if (lang.includes('-')) {
return lang.split('-')[0];
}
return lang;
}
export function updateRefData() {
const lang = formatLang(useData().site.value.lang);
for (let key in refData) {
refData[key].value = getText(lang, key);
}
}
export function getTextRef(key: string): any {
const lang = formatLang(useData().site.value.lang);
refData[key] = getText(lang, key);
return refData[key] || key;
}

View File

@ -0,0 +1,182 @@
// URL
export const OWNER = "LiteyukiStudio"
export const REPO = "LiteyukiBot"
const githubAPIUrl = "https://api.github.com"
const giteaAPIUrl = "https://git.liteyuki.icu/api/v1"
const onlineFetchUrl = "https://api.liteyuki.icu/online";
const totalFetchUrl = "https://api.liteyuki.icu/count";
const visitRecordUrl = "https://api.liteyuki.icu/visit";
const visitCountUrl = "https://api.liteyuki.icu/visit_count";
export const RepoUrl = `https://github.com/${OWNER}/${REPO}`
export const StarMapUrl = "https://starmap.liteyuki.icu"
type GithubStats = {
stars: number;
forks: number;
watchers: number;
issues?: number;
prs?: number;
size?: number;
}
// 异步接口
interface StatsApi {
getTotal: () => Promise<number>;
getOnline: () => Promise<number>;
getGithubStats: () => Promise<GithubStats>;
getPluginNum: () => Promise<number>;
getResourceNum: () => Promise<number>;
getVisitCount: () => Promise<number>;
}
export type {GithubStats};
async function getGiteaStats() {
try {
const url = `${giteaAPIUrl}/repos/${OWNER}/${REPO}`;
console.log(url);
const res = await fetch(url);
const data = await res.json();
return {
stars: data.stars_count,
forks: data.forks_count,
watchers: data.watchers_count,
issues: 0,
prs: 0,
size: data.size,
};
} catch (e) {
return {
stars: -1,
forks: -1,
watchers: -1,
issues: -1,
prs: -1,
size: -1,
};
}
}
async function getGithubStats() {
try {
const res = await fetch(`${githubAPIUrl}/repos/${OWNER}/${REPO}`);
const data = await res.json();
return {
stars: data.stargazers_count,
forks: data.forks_count,
watchers: data.watchers_count,
issues: data.open_issues_count,
prs: data.open_issues_count,
size: data.size,
};
} catch (e) {
return {
stars: -1,
forks: -1,
watchers: -1,
issues: -1,
prs: -1,
size: -1,
};
}
}
async function getRepoStats() {
// 两个接口各数据,加和返回
const githubStats = await getGithubStats();
const giteaStats = await getGiteaStats();
return {
stars: githubStats.stars + giteaStats.stars,
forks: githubStats.forks + giteaStats.forks,
watchers: githubStats.watchers + giteaStats.watchers,
issues: githubStats.issues + giteaStats.issues,
prs: githubStats.prs + giteaStats.prs,
size: githubStats.size + giteaStats.size,
};
}
// 实现接口
export const statsApi: StatsApi = {
getTotal: async () => {
try {
const res = await fetch(totalFetchUrl);
const data = await res.json();
return data.register;
} catch (e) {
return -1;
}
},
getOnline: async () => {
try {
const res = await fetch(onlineFetchUrl);
const data = await res.json();
return data.online;
} catch (e) {
return -1;
}
},
getGithubStats: getRepoStats,
getPluginNum: async () => {
try {
const res = await fetch('/plugins.json');
const data = await res.json();
return data.length;
} catch (e) {
return -1;
}
},
getResourceNum: async () => {
try {
const res = await fetch('/resources.json');
const data = await res.json();
return data.length;
} catch (e) {
return -1;
}
},
getVisitCount: async () => {
try {
const res = await fetch(visitCountUrl);
const data = await res.json();
return data.count;
} catch (e) {
return -1;
}
}
};
function getDeviceId(): string {
// 用户每次访问时生成一个唯一的设备ID储存在localStorage中用于统计用户数量
const deviceIdKey = 'deviceId';
let deviceId = localStorage.getItem(deviceIdKey);
if (!deviceId) {
deviceId = generateUUID();
localStorage.setItem(deviceIdKey, deviceId);
}
return deviceId;
}
export async function uploadVisitRecord() {
const deviceId = getDeviceId();
try {
await fetch(visitRecordUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({'device_id': deviceId}).toString(),
});
} catch (e) {
console.error('Failed to upload visit record:', e);
}
}
function generateUUID(): string {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

View File

@ -1,8 +0,0 @@
---
title: 项目部署
index: false
icon: laptop-code
category: 部署
---
<Catalog />

View File

@ -1,9 +0,0 @@
# note
开发者选项
allow_update: true # 是否允许更新
log_level: "INFO" # 日志等级
log_icon: true # 是否显示日志等级图标(某些控制台字体不可用)
auto_report: true # 是否自动上报问题给轻雪服务器
auto_update: true # 是否自动更新轻雪每天4点检查更新
safe_mode: false # 安全模式,开启后将不会加载任何第三方插件
dev_mode: false # 开发者模式,开启后将会启动看门狗

View File

@ -1,78 +0,0 @@
---
title: 配置
icon: cog
order: 2
category: 使用指南
tag:
- 配置
- 部署
---
轻雪支持`yaml``json``toml`作为配置文件,取决于你个人的喜好
首次运行后生成`config.yml``config`目录,你可修改配置项后重启轻雪,绝大多数情况下,你只需要修改`superusers``nickname`字段即可
启动时会加载项目目录下`config.yml/yaml/json/toml``config`目录下的所有配置文件,你可在`config`目录下创建多个配置文件,轻雪会自动合并这些配置文件
## **基础配置项**
```yaml
nonebot:
# Nonebot机器人的配置以前的最外层配置项仍可为Nonebot服务但是部分内容会被覆盖请尽快迁移
command_start: [ "/", "" ] # 指令前缀,若没有""空命令头请开启alconna_use_command_start保证alconna解析正常
host: 127.0.0.1 # 监听地址默认为本机若要接收外部请求请填写0.0.0.0
port: 20216 # 绑定端口
nickname: [ "liteyuki" ] # 机器人昵称列表
superusers: [ "1919810" ] # 超级用户列表
liteyuki:
# 写在外层的配置项将会被覆盖建议迁移到liteyuki下
log_level: "INFO" # 日志等级
log_icon: true # 是否显示日志等级图标(某些控制台字体不可用)
auto_report: true # 是否自动上报问题给轻雪服务器
auto_update: true # 是否自动更新轻雪每天4点检查更新
plugins: [ ] # 轻雪插件列表
plugin_dirs: [ ] # 轻雪插件目录列表
```
## **其他配置**
以下为默认值,如需自定义请手动添加
```yaml
# 高级NoneBot配置
nonebot:
onebot_access_token: "" # 访问令牌,对公开放时建议设置
default_language: "zh-CN" # 默认语言
alconna_auto_completion: false # alconna是否自动补全指令默认false建议开启
safe_mode: false # 安全模式开启后将不会加载任何第三方NoneBot插件
# 其他Nonebot插件的配置项
custom_config_1: "custom_value1"
custom_config_2: "custom_value2"
# 开发者选项
liteyuki:
allow_update: true # 是否允许更新
debug: false # 轻雪调试开启会自动重载Bot或者资源其他插件自带的调试功能也将开启
dev_mode: false # 开发者模式,开启后将会启动监视者,监视文件变化并自动重载
...
```
> [!tip]
> 如果要使用NoneBot和dotenv配置文件请自行创建`.env.{ENVIRONMENT}`,并在`config.yml`中添加`nonebot.environment:{ENVIRONMENT}`字段
## **与NoneBot对接的OneBot实现端配置**
生产环境中推荐反向WebSocket
不同的实现端给出的字段可能不同,但是基本上都是一样的,这里给出一个参考值
| 字段 | 参考值 | 说明 |
|-------------|------------------------------------|----------------------------------|
| 协议 | 反向WebSocket | 推荐使用反向ws协议进行通信即轻雪作为服务端 |
| 地址 | ws://127.0.0.1:20216/onebot/v11/ws | 地址取决于配置文件,本机默认为`127.0.0.1:20216` |
| AccessToken | `""` | 如果你给轻雪配置了`AccessToken`,请在此填写相同的值 |
## **其他**
- 要使用其他通信方式请访问[OneBot Adapter](https://onebot.adapters.nonebot.dev/)获取详细信息
- 轻雪不局限于OneBot适配器你可以使用NoneBot2支持的任何适配器

View File

@ -1,58 +0,0 @@
---
title: 答疑
icon: question
order: 3
category: 使用指南
tag:
- 配置
- 部署
---
## **常见问题**
- 设备上Python环境太乱了pip和python不对应怎么办
- 请使用`/path/to/python -m pip install -r requirements.txt`来安装依赖,
然后用`/path/to/python main.py`来启动Bot
其中`/path/to/python`是你要用来运行Bot的可执行文件
- 为什么我启动后机器人没有反应?
- 请检查配置文件的`command_start``superusers`,确认你有权限使用命令并按照正确的命令发送
- 确认命令头没有和`nickname{}`冲突,例如一个命令是`help`,但是`Bot`昵称有一个`help`那么将会被解析为nickname而不是命令
- 更新轻雪失败,报错`InvalidGitRepositoryError`
- 请正确安装`Git`,并使用克隆而非直接下载的方式部署轻雪
- 怎么登录聊天平台例如QQ
- 你有这个问题说明你不是很了解这个项目,本项目不负责实现登录功能,只负责处理和回应消息,登录功能由实现端(协议端)提供,
实现端本身不负责处理响应逻辑将消息按照OneBot标准处理好上报给轻雪
你需要使用Onebot标准的实现端来连接到轻雪并将消息上报给轻雪下面已经列出一些推荐的实现端
- `Playwright`安装失败
- 输入`playwright install`安装浏览器
- 有的插件安装后报错无法启动
- 请先查阅插件文档,确认插件必要配置项完好后,仍然出现问题,请联系插件作者或在安全模式`safe_mode: true`下启动轻雪,在安全模式下你可以使用`npm uninstall`卸载问题插件
- 其他问题
-
加入QQ群[775840726](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=SzmDYbfR6jY94o9KFNon7AwelRyI6M_u&authKey=ygeBdEmdFNyCWuNR4w0M1M8%2B5oDg7k%2FDfN0tzBkYcnbB%2FGHNnlVEnCIGbdftsnn7&noverify=0&group_code=775840726)
## **推荐方案(QQ)**
1. [Lagrange.OneBot](https://github.com/KonataDev/Lagrange.Core)基于NTQQ的OneBot实现目前Markdown消息支持Lagrange
2. [LLOneBot](https://github.com/LLOneBot/LLOneBot)NTQQ的OneBot插件需要安装NTQQ
3. [OpenShamrock](https://github.com/whitechi73/OpenShamrock)基于Lsposed的OneBot11实现
4. [TRSS-Yunzai](https://github.com/TimeRainStarSky/Yunzai),基于`node.js`,可使用`ws-plugin`进行通信
5. [go-cqhttp](https://github.com/Mrs4s/go-cqhttp)`go`语言实现的OneBot11实现端目前可用性较低
6. [Gensokyo](https://github.com/Hoshinonyaruko/Gensokyo),基于 OneBot QQ官方机器人Api Golang 原生实现,需要官方机器人权限
7. 人工实现的`Onebot`协议自己整一个WebSocket客户端看着QQ的消息然后给轻雪传输数据
## **推荐方案(Minecraft)**
1. [MinecraftOneBot](https://github.com/snowykami/MinecraftOnebot)我们专门为Minecraft开发的服务器Bot支持OneBotV11标准
使用其他项目连接请先自行查阅文档若有困难请联系对应开发者而不是Liteyuki的开发者
## **鸣谢**
- [Nonebot2](https://nonebot.dev)提供的框架支持
- [nonebot-plugin-htmlrender](https://github.com/kexue-z/nonebot-plugin-htmlrender/tree/master)提供的渲染功能
- [nonebot-plugin-alconna](https://github.com/ArcletProject/nonebot-plugin-alconna)提供的命令解析功能
- [MiSans](https://hyperos.mi.com/font/zh/)[MapleMono](https://gitee.com/mirrors/Maple-Mono)提供的字体,且遵守了相关字体开源协议

View File

@ -1,60 +0,0 @@
---
title: 安装
icon: download
order: 1
category: 使用指南
tag:
- 安装
---
## **开始安装**
### **常规部署**
1. 安装 [`Git`](https://git-scm.com/download/) 和 [`Python3.10+`](https://www.python.org/downloads/release/python-31010/) 环境
```bash
# 克隆项目到本地轻雪使用Git进行版本管理该步骤为必要项
git clone https://github.com/LiteyukiStudio/LiteyukiBot --depth=1
# 切换到Bot目录下
cd LiteyukiBot
# 安装依赖
pip install -r requirements.txt
# 启动Bot
python main.py
```
> [!tip]
> 推荐使用虚拟环境来运行轻雪,以避免依赖冲突,你可以使用`python -m venv .venv`来创建虚拟环境,然后使用`.venv\Scripts\activate`来激活虚拟环境Linux下使用`source .venv/bin/activate`激活)
### **使用Docker构建镜像部署**
1. 安装 [`Docker`](https://docs.docker.com/get-docker/)
2. 克隆项目 `git clone https://github.com/LiteyukiStudio/LiteyukiBot --depth=1`
3. 进入轻雪目录 `cd LiteyukiBot`
4. 构建镜像 `docker build -t liteyukibot .`
5. 启动容器 `docker run -p 20216:20216 -v $(pwd):/liteyukibot -v $(pwd)/.cache:/root/.cache liteyukibot`
> [!tip]
> Windows请使用项目绝对目录`/path/to/LiteyukiBot`代替`$(pwd)` <br>
> 若你修改了端口号请将`20216:20216`中的`20216`替换为你的端口号
### **使用TRSS Scripts部署**
[TRSS_Liteyuki轻雪机器人管理脚本](https://timerainstarsky.github.io/TRSS_Liteyuki/)该功能由TRSS提供支持不是LiteyukiBot官方提供的功能推荐使用`Arch Linux`
## **设备要求**
- Windows系统版本最低`Windows10+`/`Windows Server 2019+`
- Linux系统要支持Python3.10+,推荐`Ubuntu 20.04+`(~~别用你那b CentOS~~)
- CPU: 至少`1vCPU`
- 内存: Bot无其他插件会占用`300~500MB`,包括`chromium``node`等进程,其他插件占用视具体插件而定,建议`1GB`以上
- 硬盘: 至少`1GB`空间
> [!warning]
> 如果设备上有多个环境,请使用`path/to/python -m pip install -r requirements.txt`来安装依赖,`path/to/python`为你的Python可执行文件路径
> [!warning]
> 轻雪的更新功能依赖Git如果你没有安装Git直接下载源代码运行你将无法使用更新功能
#### 其他问题请移步至[答疑](/deployment/fandq)

View File

@ -1,8 +0,0 @@
---
title: 开发及贡献
index: false
icon: laptop-code
category: 开发
---
<Catalog />

View File

@ -1,7 +0,0 @@
---
title: liteyuki
index: true
icon: laptop-code
category: API
---

View File

@ -1,581 +0,0 @@
---
title: liteyuki.bot
index: true
icon: laptop-code
category: API
---
### ***def*** `get_bot() -> LiteyukiBot`
获取轻雪实例
Returns:
LiteyukiBot: 当前的轻雪实例
<details>
<summary>源代码</summary>
```python
def get_bot() -> LiteyukiBot:
"""
获取轻雪实例
Returns:
LiteyukiBot: 当前的轻雪实例
"""
if IS_MAIN_PROCESS:
if _BOT_INSTANCE is None:
raise RuntimeError('Liteyuki instance not initialized.')
return _BOT_INSTANCE
else:
raise RuntimeError("Can't get bot instance in sub process.")
```
</details>
### ***def*** `get_config(key: str, default: Any) -> Any`
获取配置
Args:
key: 配置键
default: 默认值
Returns:
Any: 配置值
<details>
<summary>源代码</summary>
```python
def get_config(key: str, default: Any=None) -> Any:
"""
获取配置
Args:
key: 配置键
default: 默认值
Returns:
Any: 配置值
"""
return get_bot().config.get(key, default)
```
</details>
### ***def*** `get_config_with_compat(key: str, compat_keys: tuple[str], default: Any) -> Any`
获取配置,兼容旧版本
Args:
key: 配置键
compat_keys: 兼容键
default: 默认值
Returns:
Any: 配置值
<details>
<summary>源代码</summary>
```python
def get_config_with_compat(key: str, compat_keys: tuple[str], default: Any=None) -> Any:
"""
获取配置,兼容旧版本
Args:
key: 配置键
compat_keys: 兼容键
default: 默认值
Returns:
Any: 配置值
"""
if key in get_bot().config:
return get_bot().config[key]
for compat_key in compat_keys:
if compat_key in get_bot().config:
logger.warning(f'Config key "{compat_key}" will be deprecated, use "{key}" instead.')
return get_bot().config[compat_key]
return default
```
</details>
### ***def*** `print_logo() -> None`
<details>
<summary>源代码</summary>
```python
def print_logo():
print('\x1b[34m' + '\n __ ______ ________ ________ __ __ __ __ __ __ ______ \n / | / |/ |/ |/ \\ / |/ | / |/ | / |/ |\n $$ | $$$$$$/ $$$$$$$$/ $$$$$$$$/ $$ \\ /$$/ $$ | $$ |$$ | /$$/ $$$$$$/ \n $$ | $$ | $$ | $$ |__ $$ \\/$$/ $$ | $$ |$$ |/$$/ $$ | \n $$ | $$ | $$ | $$ | $$ $$/ $$ | $$ |$$ $$< $$ | \n $$ | $$ | $$ | $$$$$/ $$$$/ $$ | $$ |$$$$$ \\ $$ | \n $$ |_____ _$$ |_ $$ | $$ |_____ $$ | $$ \\__$$ |$$ |$$ \\ _$$ |_ \n $$ |/ $$ | $$ | $$ | $$ | $$ $$/ $$ | $$ |/ $$ |\n $$$$$$$$/ $$$$$$/ $$/ $$$$$$$$/ $$/ $$$$$$/ $$/ $$/ $$$$$$/ \n ' + '\x1b[0m')
```
</details>
### ***class*** `LiteyukiBot`
### &emsp; ***def*** `__init__(self) -> None`
&emsp;初始化轻雪实例
Args:
*args:
**kwargs: 配置
<details>
<summary>源代码</summary>
```python
def __init__(self, *args, **kwargs) -> None:
"""
初始化轻雪实例
Args:
*args:
**kwargs: 配置
"""
'常规操作'
print_logo()
global _BOT_INSTANCE
_BOT_INSTANCE = self
'配置'
self.config: dict[str, Any] = kwargs
'初始化'
self.init(**self.config)
logger.info('Liteyuki is initializing...')
'生命周期管理'
self.lifespan = Lifespan()
self.process_manager: ProcessManager = ProcessManager(lifespan=self.lifespan)
'事件循环'
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
self.stop_event = threading.Event()
self.call_restart_count = 0
'加载插件加载器'
load_plugin('liteyuki.plugins.plugin_loader')
'信号处理'
signal.signal(signal.SIGINT, self._handle_exit)
signal.signal(signal.SIGTERM, self._handle_exit)
atexit.register(self.process_manager.terminate_all)
```
</details>
### &emsp; ***def*** `run(self) -> None`
&emsp;启动逻辑
<details>
<summary>源代码</summary>
```python
def run(self):
"""
启动逻辑
"""
self.lifespan.before_start()
self.process_manager.start_all()
self.lifespan.after_start()
self.keep_alive()
```
</details>
### &emsp; ***def*** `keep_alive(self) -> None`
&emsp;保持轻雪运行
Returns:
<details>
<summary>源代码</summary>
```python
def keep_alive(self):
"""
保持轻雪运行
Returns:
"""
try:
while not self.stop_event.is_set():
time.sleep(0.5)
except KeyboardInterrupt:
logger.info('Liteyuki is stopping...')
self.stop()
```
</details>
### &emsp; ***def*** `restart(self, delay: int) -> None`
&emsp;重启轻雪本体
Returns:
<details>
<summary>源代码</summary>
```python
def restart(self, delay: int=0):
"""
重启轻雪本体
Returns:
"""
if self.call_restart_count < 1:
executable = sys.executable
args = sys.argv
logger.info('Restarting LiteyukiBot...')
time.sleep(delay)
if platform.system() == 'Windows':
cmd = 'start'
elif platform.system() == 'Linux':
cmd = 'nohup'
elif platform.system() == 'Darwin':
cmd = 'open'
else:
cmd = 'nohup'
self.process_manager.terminate_all()
threading.Thread(target=os.system, args=(f"{cmd} {executable} {' '.join(args)}",)).start()
sys.exit(0)
self.call_restart_count += 1
```
</details>
### &emsp; ***def*** `restart_process(self, name: Optional[str]) -> None`
&emsp;停止轻雪
Args:
name: 进程名称, 默认为None, 所有进程
Returns:
<details>
<summary>源代码</summary>
```python
def restart_process(self, name: Optional[str]=None):
"""
停止轻雪
Args:
name: 进程名称, 默认为None, 所有进程
Returns:
"""
self.lifespan.before_process_shutdown()
self.lifespan.before_process_shutdown()
if name is not None:
chan_active = get_channel(f'{name}-active')
chan_active.send(1)
else:
for process_name in self.process_manager.processes:
chan_active = get_channel(f'{process_name}-active')
chan_active.send(1)
```
</details>
### &emsp; ***def*** `init(self) -> None`
&emsp;初始化轻雪, 自动调用
Returns:
<details>
<summary>源代码</summary>
```python
def init(self, *args, **kwargs):
"""
初始化轻雪, 自动调用
Returns:
"""
self.init_logger()
```
</details>
### &emsp; ***def*** `init_logger(self) -> None`
&emsp;
<details>
<summary>源代码</summary>
```python
def init_logger(self):
init_log(config=self.config)
```
</details>
### &emsp; ***def*** `stop(self) -> None`
&emsp;停止轻雪
Returns:
<details>
<summary>源代码</summary>
```python
def stop(self):
"""
停止轻雪
Returns:
"""
self.stop_event.set()
self.loop.stop()
```
</details>
### &emsp; ***def*** `on_before_start(self, func: LIFESPAN_FUNC) -> None`
&emsp;注册启动前的函数
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_before_start(self, func: LIFESPAN_FUNC):
"""
注册启动前的函数
Args:
func:
Returns:
"""
return self.lifespan.on_before_start(func)
```
</details>
### &emsp; ***def*** `on_after_start(self, func: LIFESPAN_FUNC) -> None`
&emsp;注册启动后的函数
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_after_start(self, func: LIFESPAN_FUNC):
"""
注册启动后的函数
Args:
func:
Returns:
"""
return self.lifespan.on_after_start(func)
```
</details>
### &emsp; ***def*** `on_after_shutdown(self, func: LIFESPAN_FUNC) -> None`
&emsp;注册停止后的函数:未实现
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_after_shutdown(self, func: LIFESPAN_FUNC):
"""
注册停止后的函数:未实现
Args:
func:
Returns:
"""
return self.lifespan.on_after_shutdown(func)
```
</details>
### &emsp; ***def*** `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> None`
&emsp;注册进程停止前的函数,为子进程停止时调用
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_before_process_shutdown(self, func: LIFESPAN_FUNC):
"""
注册进程停止前的函数,为子进程停止时调用
Args:
func:
Returns:
"""
return self.lifespan.on_before_process_shutdown(func)
```
</details>
### &emsp; ***def*** `on_before_process_restart(self, func: LIFESPAN_FUNC) -> None`
&emsp;注册进程重启前的函数,为子进程重启时调用
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_before_process_restart(self, func: LIFESPAN_FUNC):
"""
注册进程重启前的函数,为子进程重启时调用
Args:
func:
Returns:
"""
return self.lifespan.on_before_process_restart(func)
```
</details>
### &emsp; ***def*** `on_after_restart(self, func: LIFESPAN_FUNC) -> None`
&emsp;注册重启后的函数:未实现
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_after_restart(self, func: LIFESPAN_FUNC):
"""
注册重启后的函数:未实现
Args:
func:
Returns:
"""
return self.lifespan.on_after_restart(func)
```
</details>
### &emsp; ***def*** `on_after_nonebot_init(self, func: LIFESPAN_FUNC) -> None`
&emsp;注册nonebot初始化后的函数
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_after_nonebot_init(self, func: LIFESPAN_FUNC):
"""
注册nonebot初始化后的函数
Args:
func:
Returns:
"""
return self.lifespan.on_after_nonebot_init(func)
```
</details>
### ***var*** `executable = sys.executable`
### ***var*** `args = sys.argv`
### ***var*** `chan_active = get_channel(f'{name}-active')`
### ***var*** `cmd = 'start'`
### ***var*** `chan_active = get_channel(f'{process_name}-active')`
### ***var*** `cmd = 'nohup'`
### ***var*** `cmd = 'open'`
### ***var*** `cmd = 'nohup'`

View File

@ -1,450 +0,0 @@
---
title: liteyuki.bot.lifespan
order: 1
icon: laptop-code
category: API
---
### ***def*** `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
运行函数
Args:
funcs:
Returns:
<details>
<summary>源代码</summary>
```python
@staticmethod
def run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC], *args, **kwargs) -> None:
"""
运行函数
Args:
funcs:
Returns:
"""
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
tasks = []
for func in funcs:
if is_coroutine_callable(func):
tasks.append(func(*args, **kwargs))
else:
tasks.append(async_wrapper(func)(*args, **kwargs))
loop.run_until_complete(asyncio.gather(*tasks))
```
</details>
### ***class*** `Lifespan`
### &emsp; ***def*** `__init__(self) -> None`
&emsp;轻雪生命周期管理,启动、停止、重启
<details>
<summary>源代码</summary>
```python
def __init__(self) -> None:
"""
轻雪生命周期管理,启动、停止、重启
"""
self.life_flag: int = 0
self._before_start_funcs: list[LIFESPAN_FUNC] = []
self._after_start_funcs: list[LIFESPAN_FUNC] = []
self._before_process_shutdown_funcs: list[LIFESPAN_FUNC] = []
self._after_shutdown_funcs: list[LIFESPAN_FUNC] = []
self._before_process_restart_funcs: list[LIFESPAN_FUNC] = []
self._after_restart_funcs: list[LIFESPAN_FUNC] = []
self._after_nonebot_init_funcs: list[LIFESPAN_FUNC] = []
```
</details>
### &emsp; ***@staticmethod***
### &emsp; ***def*** `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
&emsp;运行函数
Args:
funcs:
Returns:
<details>
<summary>源代码</summary>
```python
@staticmethod
def run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC], *args, **kwargs) -> None:
"""
运行函数
Args:
funcs:
Returns:
"""
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
tasks = []
for func in funcs:
if is_coroutine_callable(func):
tasks.append(func(*args, **kwargs))
else:
tasks.append(async_wrapper(func)(*args, **kwargs))
loop.run_until_complete(asyncio.gather(*tasks))
```
</details>
### &emsp; ***def*** `on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
&emsp;注册启动时的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
<details>
<summary>源代码</summary>
```python
def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
"""
注册启动时的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
"""
self._before_start_funcs.append(func)
return func
```
</details>
### &emsp; ***def*** `on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
&emsp;注册启动时的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
<details>
<summary>源代码</summary>
```python
def on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
"""
注册启动时的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
"""
self._after_start_funcs.append(func)
return func
```
</details>
### &emsp; ***def*** `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
&emsp;注册停止前的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
<details>
<summary>源代码</summary>
```python
def on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
"""
注册停止前的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
"""
self._before_process_shutdown_funcs.append(func)
return func
```
</details>
### &emsp; ***def*** `on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
&emsp;注册停止后的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
<details>
<summary>源代码</summary>
```python
def on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
"""
注册停止后的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
"""
self._after_shutdown_funcs.append(func)
return func
```
</details>
### &emsp; ***def*** `on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
&emsp;注册重启时的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
<details>
<summary>源代码</summary>
```python
def on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
"""
注册重启时的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
"""
self._before_process_restart_funcs.append(func)
return func
```
</details>
### &emsp; ***def*** `on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
&emsp;注册重启后的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
<details>
<summary>源代码</summary>
```python
def on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
"""
注册重启后的函数
Args:
func:
Returns:
LIFESPAN_FUNC:
"""
self._after_restart_funcs.append(func)
return func
```
</details>
### &emsp; ***def*** `on_after_nonebot_init(self, func: Any) -> None`
&emsp;注册 NoneBot 初始化后的函数
Args:
func:
Returns:
<details>
<summary>源代码</summary>
```python
def on_after_nonebot_init(self, func):
"""
注册 NoneBot 初始化后的函数
Args:
func:
Returns:
"""
self._after_nonebot_init_funcs.append(func)
return func
```
</details>
### &emsp; ***def*** `before_start(self) -> None`
&emsp;启动前
Returns:
<details>
<summary>源代码</summary>
```python
def before_start(self) -> None:
"""
启动前
Returns:
"""
logger.debug('Running before_start functions')
self.run_funcs(self._before_start_funcs)
```
</details>
### &emsp; ***def*** `after_start(self) -> None`
&emsp;启动后
Returns:
<details>
<summary>源代码</summary>
```python
def after_start(self) -> None:
"""
启动后
Returns:
"""
logger.debug('Running after_start functions')
self.run_funcs(self._after_start_funcs)
```
</details>
### &emsp; ***def*** `before_process_shutdown(self) -> None`
&emsp;停止前
Returns:
<details>
<summary>源代码</summary>
```python
def before_process_shutdown(self) -> None:
"""
停止前
Returns:
"""
logger.debug('Running before_shutdown functions')
self.run_funcs(self._before_process_shutdown_funcs)
```
</details>
### &emsp; ***def*** `after_shutdown(self) -> None`
&emsp;停止后
Returns:
<details>
<summary>源代码</summary>
```python
def after_shutdown(self) -> None:
"""
停止后
Returns:
"""
logger.debug('Running after_shutdown functions')
self.run_funcs(self._after_shutdown_funcs)
```
</details>
### &emsp; ***def*** `before_process_restart(self) -> None`
&emsp;重启前
Returns:
<details>
<summary>源代码</summary>
```python
def before_process_restart(self) -> None:
"""
重启前
Returns:
"""
logger.debug('Running before_restart functions')
self.run_funcs(self._before_process_restart_funcs)
```
</details>
### &emsp; ***def*** `after_restart(self) -> None`
&emsp;重启后
Returns:
<details>
<summary>源代码</summary>
```python
def after_restart(self) -> None:
"""
重启后
Returns:
"""
logger.debug('Running after_restart functions')
self.run_funcs(self._after_restart_funcs)
```
</details>
### ***var*** `tasks = []`
### ***var*** `loop = asyncio.get_event_loop()`
### ***var*** `loop = asyncio.new_event_loop()`

View File

@ -1,7 +0,0 @@
---
title: liteyuki.comm
index: true
icon: laptop-code
category: API
---

View File

@ -1,427 +0,0 @@
---
title: liteyuki.comm.channel
order: 1
icon: laptop-code
category: API
---
### ***def*** `set_channel(name: str, channel: Channel) -> None`
设置通道实例
Args:
name: 通道名称
channel: 通道实例
<details>
<summary>源代码</summary>
```python
def set_channel(name: str, channel: Channel):
"""
设置通道实例
Args:
name: 通道名称
channel: 通道实例
"""
if not isinstance(channel, Channel):
raise TypeError(f'channel_ must be an instance of Channel, {type(channel)} found')
if IS_MAIN_PROCESS:
_channel[name] = channel
else:
channel_deliver_passive_channel.send(('set_channel', {'name': name, 'channel_': channel}))
```
</details>
### ***def*** `set_channels(channels: dict[str, Channel]) -> None`
设置通道实例
Args:
channels: 通道名称
<details>
<summary>源代码</summary>
```python
def set_channels(channels: dict[str, Channel]):
"""
设置通道实例
Args:
channels: 通道名称
"""
for name, channel in channels.items():
set_channel(name, channel)
```
</details>
### ***def*** `get_channel(name: str) -> Channel`
获取通道实例
Args:
name: 通道名称
Returns:
<details>
<summary>源代码</summary>
```python
def get_channel(name: str) -> Channel:
"""
获取通道实例
Args:
name: 通道名称
Returns:
"""
if IS_MAIN_PROCESS:
return _channel[name]
else:
recv_chan = Channel[Channel[Any]]('recv_chan')
channel_deliver_passive_channel.send(('get_channel', {'name': name, 'recv_chan': recv_chan}))
return recv_chan.receive()
```
</details>
### ***def*** `get_channels() -> dict[str, Channel]`
获取通道实例
Returns:
<details>
<summary>源代码</summary>
```python
def get_channels() -> dict[str, Channel]:
"""
获取通道实例
Returns:
"""
if IS_MAIN_PROCESS:
return _channel
else:
recv_chan = Channel[dict[str, Channel[Any]]]('recv_chan')
channel_deliver_passive_channel.send(('get_channels', {'recv_chan': recv_chan}))
return recv_chan.receive()
```
</details>
### ***def*** `on_set_channel(data: tuple[str, dict[str, Any]]) -> None`
<details>
<summary>源代码</summary>
```python
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'set_channel')
def on_set_channel(data: tuple[str, dict[str, Any]]):
name, channel = (data[1]['name'], data[1]['channel_'])
set_channel(name, channel)
```
</details>
### ***def*** `on_get_channel(data: tuple[str, dict[str, Any]]) -> None`
<details>
<summary>源代码</summary>
```python
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channel')
def on_get_channel(data: tuple[str, dict[str, Any]]):
name, recv_chan = (data[1]['name'], data[1]['recv_chan'])
recv_chan.send(get_channel(name))
```
</details>
### ***def*** `on_get_channels(data: tuple[str, dict[str, Any]]) -> None`
<details>
<summary>源代码</summary>
```python
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channels')
def on_get_channels(data: tuple[str, dict[str, Any]]):
recv_chan = data[1]['recv_chan']
recv_chan.send(get_channels())
```
</details>
### ***def*** `decorator(func: Callable[[T], Any]) -> Callable[[T], Any]`
<details>
<summary>源代码</summary>
```python
def decorator(func: Callable[[T], Any]) -> Callable[[T], Any]:
global _func_id
async def wrapper(data: T) -> Any:
if filter_func is not None:
if is_coroutine_callable(filter_func):
if not await filter_func(data):
return
elif not filter_func(data):
return
if is_coroutine_callable(func):
return await func(data)
else:
return func(data)
_callback_funcs[_func_id] = wrapper
if IS_MAIN_PROCESS:
self._on_main_receive_funcs.append(_func_id)
else:
self._on_sub_receive_funcs.append(_func_id)
_func_id += 1
return func
```
</details>
### ***async def*** `wrapper(data: T) -> Any`
<details>
<summary>源代码</summary>
```python
async def wrapper(data: T) -> Any:
if filter_func is not None:
if is_coroutine_callable(filter_func):
if not await filter_func(data):
return
elif not filter_func(data):
return
if is_coroutine_callable(func):
return await func(data)
else:
return func(data)
```
</details>
### ***class*** `Channel(Generic[T])`
通道类,可以在进程间和进程内通信,双向但同时只能有一个发送者和一个接收者
有两种接收工作方式,但是只能选择一种,主动接收和被动接收,主动接收使用 `receive` 方法,被动接收使用 `on_receive` 装饰器
### &emsp; ***def*** `__init__(self, _id: str, type_check: Optional[bool]) -> None`
&emsp;初始化通道
Args:
_id: 通道ID
type_check: 是否开启类型检查, 若为空,则传入泛型默认开启,否则默认关闭
<details>
<summary>源代码</summary>
```python
def __init__(self, _id: str, type_check: Optional[bool]=None):
"""
初始化通道
Args:
_id: 通道ID
type_check: 是否开启类型检查, 若为空,则传入泛型默认开启,否则默认关闭
"""
self.conn_send, self.conn_recv = Pipe()
self._closed = False
self._on_main_receive_funcs: list[int] = []
self._on_sub_receive_funcs: list[int] = []
self.name: str = _id
self.is_main_receive_loop_running = False
self.is_sub_receive_loop_running = False
if type_check is None:
type_check = self._get_generic_type() is not None
elif type_check:
if self._get_generic_type() is None:
raise TypeError('Type hint is required for enforcing type check.')
self.type_check = type_check
```
</details>
### &emsp; ***def*** `send(self, data: T) -> None`
&emsp;发送数据
Args:
data: 数据
<details>
<summary>源代码</summary>
```python
def send(self, data: T):
"""
发送数据
Args:
data: 数据
"""
if self.type_check:
_type = self._get_generic_type()
if _type is not None and (not self._validate_structure(data, _type)):
raise TypeError(f'Data must be an instance of {_type}, {type(data)} found')
if self._closed:
raise RuntimeError('Cannot send to a closed channel_')
self.conn_send.send(data)
```
</details>
### &emsp; ***def*** `receive(self) -> T`
&emsp;接收数据
Args:
<details>
<summary>源代码</summary>
```python
def receive(self) -> T:
"""
接收数据
Args:
"""
if self._closed:
raise RuntimeError('Cannot receive from a closed channel_')
while True:
data = self.conn_recv.recv()
return data
```
</details>
### &emsp; ***def*** `close(self) -> None`
&emsp;关闭通道
<details>
<summary>源代码</summary>
```python
def close(self):
"""
关闭通道
"""
self._closed = True
self.conn_send.close()
self.conn_recv.close()
```
</details>
### &emsp; ***def*** `on_receive(self, filter_func: Optional[FILTER_FUNC]) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]`
&emsp;接收数据并执行函数
Args:
filter_func: 过滤函数为None则不过滤
Returns:
装饰器,装饰一个函数在接收到数据后执行
<details>
<summary>源代码</summary>
```python
def on_receive(self, filter_func: Optional[FILTER_FUNC]=None) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]:
"""
接收数据并执行函数
Args:
filter_func: 过滤函数为None则不过滤
Returns:
装饰器,装饰一个函数在接收到数据后执行
"""
if not self.is_sub_receive_loop_running and (not IS_MAIN_PROCESS):
threading.Thread(target=self._start_sub_receive_loop, daemon=True).start()
if not self.is_main_receive_loop_running and IS_MAIN_PROCESS:
threading.Thread(target=self._start_main_receive_loop, daemon=True).start()
def decorator(func: Callable[[T], Any]) -> Callable[[T], Any]:
global _func_id
async def wrapper(data: T) -> Any:
if filter_func is not None:
if is_coroutine_callable(filter_func):
if not await filter_func(data):
return
elif not filter_func(data):
return
if is_coroutine_callable(func):
return await func(data)
else:
return func(data)
_callback_funcs[_func_id] = wrapper
if IS_MAIN_PROCESS:
self._on_main_receive_funcs.append(_func_id)
else:
self._on_sub_receive_funcs.append(_func_id)
_func_id += 1
return func
return decorator
```
</details>
### ***var*** `T = TypeVar('T')`
### ***var*** `channel_deliver_active_channel = Channel(_id='channel_deliver_active_channel')`
### ***var*** `channel_deliver_passive_channel = Channel(_id='channel_deliver_passive_channel')`
### ***var*** `recv_chan = data[1]['recv_chan']`
### ***var*** `recv_chan = Channel[Channel[Any]]('recv_chan')`
### ***var*** `recv_chan = Channel[dict[str, Channel[Any]]]('recv_chan')`
### ***var*** `type_check = self._get_generic_type() is not None`
### ***var*** `data = self.conn_recv.recv()`
### ***var*** `func = _callback_funcs[func_id]`
### ***var*** `func = _callback_funcs[func_id]`
### ***var*** `data = self.conn_recv.recv()`
### ***var*** `data = self.conn_recv.recv()`

View File

@ -1,25 +0,0 @@
---
title: liteyuki.comm.event
order: 1
icon: laptop-code
category: API
---
### ***class*** `Event`
事件类
### &emsp; ***def*** `__init__(self, name: str, data: dict[str, Any]) -> None`
&emsp;
<details>
<summary>源代码</summary>
```python
def __init__(self, name: str, data: dict[str, Any]):
self.name = name
self.data = data
```
</details>

View File

@ -1,563 +0,0 @@
---
title: liteyuki.comm.storage
order: 1
icon: laptop-code
category: API
---
### ***def*** `run_subscriber_receive_funcs(channel_: str, data: Any) -> None`
运行订阅者接收函数
Args:
channel_: 频道
data: 数据
<details>
<summary>源代码</summary>
```python
@staticmethod
def run_subscriber_receive_funcs(channel_: str, data: Any):
"""
运行订阅者接收函数
Args:
channel_: 频道
data: 数据
"""
if IS_MAIN_PROCESS:
if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]:
run_coroutine(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
elif channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]:
run_coroutine(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
```
</details>
### ***def*** `on_get(data: tuple[str, dict[str, Any]]) -> None`
<details>
<summary>源代码</summary>
```python
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get')
def on_get(data: tuple[str, dict[str, Any]]):
key = data[1]['key']
default = data[1]['default']
recv_chan = data[1]['recv_chan']
recv_chan.send(shared_memory.get(key, default))
```
</details>
### ***def*** `on_set(data: tuple[str, dict[str, Any]]) -> None`
<details>
<summary>源代码</summary>
```python
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'set')
def on_set(data: tuple[str, dict[str, Any]]):
key = data[1]['key']
value = data[1]['value']
shared_memory.set(key, value)
```
</details>
### ***def*** `on_delete(data: tuple[str, dict[str, Any]]) -> None`
<details>
<summary>源代码</summary>
```python
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'delete')
def on_delete(data: tuple[str, dict[str, Any]]):
key = data[1]['key']
shared_memory.delete(key)
```
</details>
### ***def*** `on_get_all(data: tuple[str, dict[str, Any]]) -> None`
<details>
<summary>源代码</summary>
```python
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get_all')
def on_get_all(data: tuple[str, dict[str, Any]]):
recv_chan = data[1]['recv_chan']
recv_chan.send(shared_memory.get_all())
```
</details>
### ***def*** `on_publish(data: tuple[str, Any]) -> None`
<details>
<summary>源代码</summary>
```python
@channel.publish_channel.on_receive()
def on_publish(data: tuple[str, Any]):
channel_, data = data
shared_memory.run_subscriber_receive_funcs(channel_, data)
```
</details>
### ***def*** `decorator(func: ON_RECEIVE_FUNC) -> ON_RECEIVE_FUNC`
<details>
<summary>源代码</summary>
```python
def decorator(func: ON_RECEIVE_FUNC) -> ON_RECEIVE_FUNC:
async def wrapper(data: Any):
if is_coroutine_callable(func):
await func(data)
else:
func(data)
if IS_MAIN_PROCESS:
if channel_ not in _on_main_subscriber_receive_funcs:
_on_main_subscriber_receive_funcs[channel_] = []
_on_main_subscriber_receive_funcs[channel_].append(wrapper)
else:
if channel_ not in _on_sub_subscriber_receive_funcs:
_on_sub_subscriber_receive_funcs[channel_] = []
_on_sub_subscriber_receive_funcs[channel_].append(wrapper)
return wrapper
```
</details>
### ***async def*** `wrapper(data: Any) -> None`
<details>
<summary>源代码</summary>
```python
async def wrapper(data: Any):
if is_coroutine_callable(func):
await func(data)
else:
func(data)
```
</details>
### ***class*** `Subscriber`
### &emsp; ***def*** `__init__(self) -> None`
&emsp;
<details>
<summary>源代码</summary>
```python
def __init__(self):
self._subscribers = {}
```
</details>
### &emsp; ***def*** `receive(self) -> Any`
&emsp;
<details>
<summary>源代码</summary>
```python
def receive(self) -> Any:
pass
```
</details>
### &emsp; ***def*** `unsubscribe(self) -> None`
&emsp;
<details>
<summary>源代码</summary>
```python
def unsubscribe(self) -> None:
pass
```
</details>
### ***class*** `KeyValueStore`
### &emsp; ***def*** `__init__(self) -> None`
&emsp;
<details>
<summary>源代码</summary>
```python
def __init__(self):
self._store = {}
self.active_chan = Channel[tuple[str, Optional[dict[str, Any]]]](_id='shared_memory-active')
self.passive_chan = Channel[tuple[str, Optional[dict[str, Any]]]](_id='shared_memory-passive')
self.publish_channel = Channel[tuple[str, Any]](_id='shared_memory-publish')
self.is_main_receive_loop_running = False
self.is_sub_receive_loop_running = False
```
</details>
### &emsp; ***def*** `set(self, key: str, value: Any) -> None`
&emsp;设置键值对
Args:
key: 键
value: 值
<details>
<summary>源代码</summary>
```python
def set(self, key: str, value: Any) -> None:
"""
设置键值对
Args:
key: 键
value: 值
"""
if IS_MAIN_PROCESS:
lock = _get_lock(key)
with lock:
self._store[key] = value
else:
self.passive_chan.send(('set', {'key': key, 'value': value}))
```
</details>
### &emsp; ***def*** `get(self, key: str, default: Optional[Any]) -> Optional[Any]`
&emsp;获取键值对
Args:
key: 键
default: 默认值
Returns:
Any: 值
<details>
<summary>源代码</summary>
```python
def get(self, key: str, default: Optional[Any]=None) -> Optional[Any]:
"""
获取键值对
Args:
key: 键
default: 默认值
Returns:
Any: 值
"""
if IS_MAIN_PROCESS:
lock = _get_lock(key)
with lock:
return self._store.get(key, default)
else:
recv_chan = Channel[Optional[Any]]('recv_chan')
self.passive_chan.send(('get', {'key': key, 'default': default, 'recv_chan': recv_chan}))
return recv_chan.receive()
```
</details>
### &emsp; ***def*** `delete(self, key: str, ignore_key_error: bool) -> None`
&emsp;删除键值对
Args:
key: 键
ignore_key_error: 是否忽略键不存在的错误
Returns:
<details>
<summary>源代码</summary>
```python
def delete(self, key: str, ignore_key_error: bool=True) -> None:
"""
删除键值对
Args:
key: 键
ignore_key_error: 是否忽略键不存在的错误
Returns:
"""
if IS_MAIN_PROCESS:
lock = _get_lock(key)
with lock:
if key in self._store:
try:
del self._store[key]
del _locks[key]
except KeyError as e:
if not ignore_key_error:
raise e
else:
self.passive_chan.send(('delete', {'key': key}))
```
</details>
### &emsp; ***def*** `get_all(self) -> dict[str, Any]`
&emsp;获取所有键值对
Returns:
dict[str, Any]: 键值对
<details>
<summary>源代码</summary>
```python
def get_all(self) -> dict[str, Any]:
"""
获取所有键值对
Returns:
dict[str, Any]: 键值对
"""
if IS_MAIN_PROCESS:
return self._store
else:
recv_chan = Channel[dict[str, Any]]('recv_chan')
self.passive_chan.send(('get_all', {'recv_chan': recv_chan}))
return recv_chan.receive()
```
</details>
### &emsp; ***def*** `publish(self, channel_: str, data: Any) -> None`
&emsp;发布消息
Args:
channel_: 频道
data: 数据
Returns:
<details>
<summary>源代码</summary>
```python
def publish(self, channel_: str, data: Any) -> None:
"""
发布消息
Args:
channel_: 频道
data: 数据
Returns:
"""
self.active_chan.send(('publish', {'channel': channel_, 'data': data}))
```
</details>
### &emsp; ***def*** `on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]`
&emsp;订阅者接收消息时的回调
Args:
channel_: 频道
Returns:
装饰器
<details>
<summary>源代码</summary>
```python
def on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]:
"""
订阅者接收消息时的回调
Args:
channel_: 频道
Returns:
装饰器
"""
if IS_MAIN_PROCESS and (not self.is_main_receive_loop_running):
threading.Thread(target=self._start_receive_loop, daemon=True).start()
shared_memory.is_main_receive_loop_running = True
elif not IS_MAIN_PROCESS and (not self.is_sub_receive_loop_running):
threading.Thread(target=self._start_receive_loop, daemon=True).start()
shared_memory.is_sub_receive_loop_running = True
def decorator(func: ON_RECEIVE_FUNC) -> ON_RECEIVE_FUNC:
async def wrapper(data: Any):
if is_coroutine_callable(func):
await func(data)
else:
func(data)
if IS_MAIN_PROCESS:
if channel_ not in _on_main_subscriber_receive_funcs:
_on_main_subscriber_receive_funcs[channel_] = []
_on_main_subscriber_receive_funcs[channel_].append(wrapper)
else:
if channel_ not in _on_sub_subscriber_receive_funcs:
_on_sub_subscriber_receive_funcs[channel_] = []
_on_sub_subscriber_receive_funcs[channel_].append(wrapper)
return wrapper
return decorator
```
</details>
### &emsp; ***@staticmethod***
### &emsp; ***def*** `run_subscriber_receive_funcs(channel_: str, data: Any) -> None`
&emsp;运行订阅者接收函数
Args:
channel_: 频道
data: 数据
<details>
<summary>源代码</summary>
```python
@staticmethod
def run_subscriber_receive_funcs(channel_: str, data: Any):
"""
运行订阅者接收函数
Args:
channel_: 频道
data: 数据
"""
if IS_MAIN_PROCESS:
if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]:
run_coroutine(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
elif channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]:
run_coroutine(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
```
</details>
### ***class*** `GlobalKeyValueStore`
### &emsp; ***@classmethod***
### &emsp; ***def*** `get_instance(cls: Any) -> None`
&emsp;
<details>
<summary>源代码</summary>
```python
@classmethod
def get_instance(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None:
cls._instance = KeyValueStore()
return cls._instance
```
</details>
### &emsp; ***attr*** `_instance: None`
### &emsp; ***attr*** `_lock: threading.Lock()`
### ***var*** `key = data[1]['key']`
### ***var*** `default = data[1]['default']`
### ***var*** `recv_chan = data[1]['recv_chan']`
### ***var*** `key = data[1]['key']`
### ***var*** `value = data[1]['value']`
### ***var*** `key = data[1]['key']`
### ***var*** `recv_chan = data[1]['recv_chan']`
### ***var*** `lock = _get_lock(key)`
### ***var*** `lock = _get_lock(key)`
### ***var*** `recv_chan = Channel[Optional[Any]]('recv_chan')`
### ***var*** `lock = _get_lock(key)`
### ***var*** `recv_chan = Channel[dict[str, Any]]('recv_chan')`
### ***var*** `data = self.active_chan.receive()`
### ***var*** `data = self.publish_channel.receive()`

View File

@ -1,231 +0,0 @@
---
title: liteyuki.config
order: 1
icon: laptop-code
category: API
---
### ***def*** `flat_config(config: dict[str, Any]) -> dict[str, Any]`
扁平化配置文件
{a:{b:{c:1}}} -> {"a.b.c": 1}
Args:
config: 配置项目
Returns:
扁平化后的配置文件,但也包含原有的键值对
<details>
<summary>源代码</summary>
```python
def flat_config(config: dict[str, Any]) -> dict[str, Any]:
"""
扁平化配置文件
{a:{b:{c:1}}} -> {"a.b.c": 1}
Args:
config: 配置项目
Returns:
扁平化后的配置文件,但也包含原有的键值对
"""
new_config = copy.deepcopy(config)
for key, value in config.items():
if isinstance(value, dict):
for k, v in flat_config(value).items():
new_config[f'{key}.{k}'] = v
return new_config
```
</details>
### ***def*** `load_from_yaml(file: str) -> dict[str, Any]`
Load config from yaml file
<details>
<summary>源代码</summary>
```python
def load_from_yaml(file: str) -> dict[str, Any]:
"""
Load config from yaml file
"""
logger.debug(f'Loading YAML config from {file}')
config = yaml.safe_load(open(file, 'r', encoding='utf-8'))
return flat_config(config if config is not None else {})
```
</details>
### ***def*** `load_from_json(file: str) -> dict[str, Any]`
Load config from json file
<details>
<summary>源代码</summary>
```python
def load_from_json(file: str) -> dict[str, Any]:
"""
Load config from json file
"""
logger.debug(f'Loading JSON config from {file}')
config = json.load(open(file, 'r', encoding='utf-8'))
return flat_config(config if config is not None else {})
```
</details>
### ***def*** `load_from_toml(file: str) -> dict[str, Any]`
Load config from toml file
<details>
<summary>源代码</summary>
```python
def load_from_toml(file: str) -> dict[str, Any]:
"""
Load config from toml file
"""
logger.debug(f'Loading TOML config from {file}')
config = toml.load(open(file, 'r', encoding='utf-8'))
return flat_config(config if config is not None else {})
```
</details>
### ***def*** `load_from_files() -> dict[str, Any]`
从指定文件加载配置项,会自动识别文件格式
默认执行扁平化选项
<details>
<summary>源代码</summary>
```python
def load_from_files(*files: str, no_warning: bool=False) -> dict[str, Any]:
"""
从指定文件加载配置项,会自动识别文件格式
默认执行扁平化选项
"""
config = {}
for file in files:
if os.path.exists(file):
if file.endswith(('.yaml', 'yml')):
config.update(load_from_yaml(file))
elif file.endswith('.json'):
config.update(load_from_json(file))
elif file.endswith('.toml'):
config.update(load_from_toml(file))
elif not no_warning:
logger.warning(f'Unsupported config file format: {file}')
elif not no_warning:
logger.warning(f'Config file not found: {file}')
return config
```
</details>
### ***def*** `load_configs_from_dirs() -> dict[str, Any]`
从目录下加载配置文件,不递归
按照读取文件的优先级反向覆盖
默认执行扁平化选项
<details>
<summary>源代码</summary>
```python
def load_configs_from_dirs(*directories: str, no_waring: bool=False) -> dict[str, Any]:
"""
从目录下加载配置文件,不递归
按照读取文件的优先级反向覆盖
默认执行扁平化选项
"""
config = {}
for directory in directories:
if not os.path.exists(directory):
if not no_waring:
logger.warning(f'Directory not found: {directory}')
continue
for file in os.listdir(directory):
if file.endswith(_SUPPORTED_CONFIG_FORMATS):
config.update(load_from_files(os.path.join(directory, file), no_warning=no_waring))
return config
```
</details>
### ***def*** `load_config_in_default(no_waring: bool) -> dict[str, Any]`
从一个标准的轻雪项目加载配置文件
项目目录下的config.*和config目录下的所有配置文件
项目目录下的配置文件优先
<details>
<summary>源代码</summary>
```python
def load_config_in_default(no_waring: bool=False) -> dict[str, Any]:
"""
从一个标准的轻雪项目加载配置文件
项目目录下的config.*和config目录下的所有配置文件
项目目录下的配置文件优先
"""
config = load_configs_from_dirs('config', no_waring=no_waring)
config.update(load_from_files('config.yaml', 'config.toml', 'config.json', 'config.yml', no_warning=no_waring))
return config
```
</details>
### ***class*** `SatoriNodeConfig(BaseModel)`
### ***class*** `SatoriConfig(BaseModel)`
### ***class*** `BasicConfig(BaseModel)`
### ***var*** `new_config = copy.deepcopy(config)`
### ***var*** `config = yaml.safe_load(open(file, 'r', encoding='utf-8'))`
### ***var*** `config = json.load(open(file, 'r', encoding='utf-8'))`
### ***var*** `config = toml.load(open(file, 'r', encoding='utf-8'))`
### ***var*** `config = {}`
### ***var*** `config = {}`
### ***var*** `config = load_configs_from_dirs('config', no_waring=no_waring)`

Some files were not shown because too many files have changed in this diff Show More