ok-script 2.0.19__tar.gz → 2.0.21__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. {ok_script-2.0.19 → ok_script-2.0.21}/PKG-INFO +3 -1
  2. {ok_script-2.0.19 → ok_script-2.0.21}/README.md +2 -0
  3. {ok_script-2.0.19 → ok_script-2.0.21}/docs/mcp.md +10 -1
  4. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/code_runner.py +1 -1
  5. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/mcp_runner.py +66 -1
  6. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/mcp_server.py +4 -2
  7. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/base.py +2 -2
  8. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/keys.py +30 -0
  9. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/post_message.py +24 -2
  10. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/pydirect.py +26 -7
  11. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/pynput.py +13 -9
  12. {ok_script-2.0.19 → ok_script-2.0.21}/ok/task/TaskExecutor.py +10 -1
  13. {ok_script-2.0.19 → ok_script-2.0.21}/ok/task/task.py +2 -1
  14. {ok_script-2.0.19 → ok_script-2.0.21}/ok/test/__init__.py +4 -1
  15. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/about/AboutTab.py +2 -0
  16. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/en_US.qm +0 -0
  17. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/en_US.ts +8 -0
  18. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/es_ES.qm +0 -0
  19. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/es_ES.ts +8 -0
  20. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/ja_JP.qm +0 -0
  21. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/ja_JP.ts +9 -1
  22. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/ko_KR.qm +0 -0
  23. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/ko_KR.ts +9 -1
  24. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/zh_CN.qm +0 -0
  25. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/zh_CN.ts +8 -0
  26. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/zh_TW.qm +0 -0
  27. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/zh_TW.ts +8 -0
  28. ok_script-2.0.21/ok/ui/qt/resources.py +17921 -0
  29. ok_script-2.0.21/ok/ui/qt/tasks/LabelAndLineEdit.py +83 -0
  30. {ok_script-2.0.19 → ok_script-2.0.21}/ok_script.egg-info/PKG-INFO +3 -1
  31. {ok_script-2.0.19 → ok_script-2.0.21}/ok_script.egg-info/SOURCES.txt +3 -0
  32. ok_script-2.0.21/tests/test_mcp_cleanup.py +166 -0
  33. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_mcp_runner.py +1 -1
  34. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_mcp_server.py +35 -0
  35. ok_script-2.0.21/tests/test_mouse_buttons.py +205 -0
  36. ok_script-2.0.21/tests/test_task_executor_next_frame.py +83 -0
  37. ok_script-2.0.19/ok/ui/qt/resources.py +0 -17886
  38. ok_script-2.0.19/ok/ui/qt/tasks/LabelAndLineEdit.py +0 -39
  39. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/develop/SKILL.md +0 -0
  40. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/develop/agents/openai.yaml +0 -0
  41. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/develop/references/windows-input.md +0 -0
  42. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/generate-templates/SKILL.md +0 -0
  43. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/reload-tasks/SKILL.md +0 -0
  44. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/reload-tasks/agents/openai.yaml +0 -0
  45. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/setup-env/SKILL.md +0 -0
  46. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/setup-env/agents/openai.yaml +0 -0
  47. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/setup-env/assets/ok-script-develop/SKILL.md +0 -0
  48. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/setup-project/SKILL.md +0 -0
  49. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/setup-project/agents/openai.yaml +0 -0
  50. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/use_venv/SKILL.md +0 -0
  51. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/write-test/SKILL.md +0 -0
  52. {ok_script-2.0.19 → ok_script-2.0.21}/.agents/skills/write-test/agents/openai.yaml +0 -0
  53. {ok_script-2.0.19 → ok_script-2.0.21}/LICENSE.txt +0 -0
  54. {ok_script-2.0.19 → ok_script-2.0.21}/MANIFEST.in +0 -0
  55. {ok_script-2.0.19 → ok_script-2.0.21}/diagnostics/qq_trace.py +0 -0
  56. {ok_script-2.0.19 → ok_script-2.0.21}/docs/agent-setup.md +0 -0
  57. {ok_script-2.0.19 → ok_script-2.0.21}/docs/feature-crops.md +0 -0
  58. {ok_script-2.0.19 → ok_script-2.0.21}/examples/mcp_observe.py +0 -0
  59. {ok_script-2.0.19 → ok_script-2.0.21}/ok/__init__.py +0 -0
  60. {ok_script-2.0.19 → ok_script-2.0.21}/ok/__main__.py +0 -0
  61. {ok_script-2.0.19 → ok_script-2.0.21}/ok/alas/__init__.py +0 -0
  62. {ok_script-2.0.19 → ok_script-2.0.21}/ok/alas/emulator_base.py +0 -0
  63. {ok_script-2.0.19 → ok_script-2.0.21}/ok/alas/emulator_windows.py +0 -0
  64. {ok_script-2.0.19 → ok_script-2.0.21}/ok/alas/platform_windows.py +0 -0
  65. {ok_script-2.0.19 → ok_script-2.0.21}/ok/alas/utils.py +0 -0
  66. {ok_script-2.0.19 → ok_script-2.0.21}/ok/assets/default-icon.png +0 -0
  67. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/__init__.py +0 -0
  68. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/__init__.py +0 -0
  69. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/deep.py +0 -0
  70. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/minitouch.py +0 -0
  71. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/nemu_ipc.py +0 -0
  72. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/nemu_utils.py +0 -0
  73. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/pool.py +0 -0
  74. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/timer.py +0 -0
  75. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/adb/util.py +0 -0
  76. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/windows/__init__.py +0 -0
  77. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/windows/d3d11.py +0 -0
  78. {ok_script-2.0.19 → ok_script-2.0.21}/ok/capture/windows/dump.py +0 -0
  79. {ok_script-2.0.19 → ok_script-2.0.21}/ok/cli.py +0 -0
  80. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/__init__.py +0 -0
  81. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/capture_labels.py +0 -0
  82. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/config_schema.py +0 -0
  83. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/downloads.py +0 -0
  84. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/events.py +0 -0
  85. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/icons.py +0 -0
  86. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/notifications.py +0 -0
  87. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/plugin_staging.py +0 -0
  88. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/plugins.py +0 -0
  89. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/screenshot.py +0 -0
  90. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/script_editing.py +0 -0
  91. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/script_packager.py +0 -0
  92. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/script_templates.py +0 -0
  93. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/skills.py +0 -0
  94. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/start_controller.py +0 -0
  95. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/task_manager.py +0 -0
  96. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/template_store.py +0 -0
  97. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/translation.py +0 -0
  98. {ok_script-2.0.19 → ok_script-2.0.21}/ok/core/ui_config.py +0 -0
  99. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/DeviceManager.py +0 -0
  100. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/__init__.py +0 -0
  101. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture.py +0 -0
  102. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/__init__.py +0 -0
  103. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/adb.py +0 -0
  104. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/bitblt.py +0 -0
  105. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/bitblt_utils.py +0 -0
  106. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/browser.py +0 -0
  107. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/desktop_duplication.py +0 -0
  108. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/hwnd_window.py +0 -0
  109. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/image.py +0 -0
  110. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/nemu_ipc.py +0 -0
  111. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/types.py +0 -0
  112. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/update.py +0 -0
  113. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/windows_graphics.py +0 -0
  114. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/capture_methods/windows_graphics_hdr.py +0 -0
  115. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction.py +0 -0
  116. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/__init__.py +0 -0
  117. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/adb.py +0 -0
  118. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/base.py +0 -0
  119. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/browser.py +0 -0
  120. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/do_nothing.py +0 -0
  121. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/foreground_post_message.py +0 -0
  122. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/genshin.py +0 -0
  123. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/interaction_methods/swipe.py +0 -0
  124. {ok_script-2.0.19 → ok_script-2.0.21}/ok/device/intercation.py +0 -0
  125. {ok_script-2.0.19 → ok_script-2.0.21}/ok/feature/Box.py +0 -0
  126. {ok_script-2.0.19 → ok_script-2.0.21}/ok/feature/Feature.py +0 -0
  127. {ok_script-2.0.19 → ok_script-2.0.21}/ok/feature/FeatureSet.py +0 -0
  128. {ok_script-2.0.19 → ok_script-2.0.21}/ok/feature/__init__.py +0 -0
  129. {ok_script-2.0.19 → ok_script-2.0.21}/ok/gui/__init__.py +0 -0
  130. {ok_script-2.0.19 → ok_script-2.0.21}/ok/gui/util/pyappify_startup.py +0 -0
  131. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/__init__.py +0 -0
  132. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/manager.py +0 -0
  133. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/messenger_images.py +0 -0
  134. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/pipeline.py +0 -0
  135. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/ppocr.py +0 -0
  136. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/providers.py +0 -0
  137. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/system.py +0 -0
  138. {ok_script-2.0.19 → ok_script-2.0.21}/ok/notification/windows_messenger.py +0 -0
  139. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ocr/__init__.py +0 -0
  140. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ocr/download_paddle_model.py +0 -0
  141. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  142. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  143. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  144. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  145. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  146. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  147. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  148. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  149. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  150. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Media/__init__.py +0 -0
  151. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  152. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Security/__init__.py +0 -0
  153. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  154. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  155. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/UI/ViewManagement/__init__.py +0 -0
  156. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/UI/__init__.py +0 -0
  157. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/Windows/__init__.py +0 -0
  158. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/__init__.py +0 -0
  159. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/delegate.py +0 -0
  160. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/export.py +0 -0
  161. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/idldsl.py +0 -0
  162. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/inspectable.py +0 -0
  163. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/roapi.py +0 -0
  164. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/types.py +0 -0
  165. {ok_script-2.0.19 → ok_script-2.0.21}/ok/rotypes/winstring.py +0 -0
  166. {ok_script-2.0.19 → ok_script-2.0.21}/ok/task/DiagnosisTask.py +0 -0
  167. {ok_script-2.0.19 → ok_script-2.0.21}/ok/task/__init__.py +0 -0
  168. {ok_script-2.0.19 → ok_script-2.0.21}/ok/task/exceptions.py +0 -0
  169. {ok_script-2.0.19 → ok_script-2.0.21}/ok/test/OKTestRunner.py +0 -0
  170. {ok_script-2.0.19 → ok_script-2.0.21}/ok/test/RunTests.py +0 -0
  171. {ok_script-2.0.19 → ok_script-2.0.21}/ok/test/TaskTestCase.py +0 -0
  172. {ok_script-2.0.19 → ok_script-2.0.21}/ok/third_party/__init__.py +0 -0
  173. {ok_script-2.0.19 → ok_script-2.0.21}/ok/third_party/paperclip.py +0 -0
  174. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/__init__.py +0 -0
  175. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/overlay/__init__.py +0 -0
  176. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/overlay/win32_gdi.py +0 -0
  177. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/Communicate.py +0 -0
  178. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/MainWindow.py +0 -0
  179. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/MessageWindow.py +0 -0
  180. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/StartController.py +0 -0
  181. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/TabTitles.py +0 -0
  182. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/__init__.py +0 -0
  183. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/about/HttpTextEdit.py +0 -0
  184. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/about/LinksBar.py +0 -0
  185. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/about/ProjectCard.py +0 -0
  186. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/about/UpdateCard.py +0 -0
  187. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/about/VersionCard.py +0 -0
  188. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/about/__init__.py +0 -0
  189. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/common/OKIcon.py +0 -0
  190. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/common/__init__.py +0 -0
  191. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/common/accent_color.py +0 -0
  192. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/common/config.py +0 -0
  193. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/common/design_system.py +0 -0
  194. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/common/icons.py +0 -0
  195. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/common/style_sheet.py +0 -0
  196. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/debug/DebugTab.py +0 -0
  197. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/debug/JobControls.py +0 -0
  198. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/debug/OverlayWidget.py +0 -0
  199. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/debug/RunCodeTab.py +0 -0
  200. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/debug/Screenshot.py +0 -0
  201. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/debug/__init__.py +0 -0
  202. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/events.py +0 -0
  203. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/GettextTranslator.py +0 -0
  204. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/__init__.py +0 -0
  205. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/path.py +0 -0
  206. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/i18n/update.py +0 -0
  207. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/overlay/OverlayWindow.py +0 -0
  208. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/overlay/__init__.py +0 -0
  209. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/plugins/PluginTab.py +0 -0
  210. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/plugins/__init__.py +0 -0
  211. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/plugins/imported_tabs.py +0 -0
  212. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/__init__.py +0 -0
  213. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/card.qss +0 -0
  214. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/discord.svg +0 -0
  215. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/heart.svg +0 -0
  216. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/message_window.qss +0 -0
  217. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/setting_interface.qss +0 -0
  218. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/status_bar.qss +0 -0
  219. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/stop.svg +0 -0
  220. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/dark/tab.qss +0 -0
  221. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/card.qss +0 -0
  222. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/discord.svg +0 -0
  223. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/heart.svg +0 -0
  224. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/message_window.qss +0 -0
  225. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/setting_interface.qss +0 -0
  226. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/status_bar.qss +0 -0
  227. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/stop.svg +0 -0
  228. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qss/light/tab.qss +0 -0
  229. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/qt.qrc +0 -0
  230. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/settings/GlobalConfigCard.py +0 -0
  231. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/settings/GlobalConfigTab.py +0 -0
  232. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/settings/SettingTab.py +0 -0
  233. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/settings/__init__.py +0 -0
  234. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/start/LogWindow.py +0 -0
  235. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/start/SelectCaptureListView.py +0 -0
  236. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/start/SelectInteractionListView.py +0 -0
  237. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/start/StartCard.py +0 -0
  238. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/start/StartTab.py +0 -0
  239. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/start/__init__.py +0 -0
  240. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/ConfigCard.py +0 -0
  241. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/ConfigItemFactory.py +0 -0
  242. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/ConfigLabelAndWidget.py +0 -0
  243. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/EditTaskTab.py +0 -0
  244. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndButtons.py +0 -0
  245. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndDoubleSpinBox.py +0 -0
  246. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndDropDown.py +0 -0
  247. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndFileSelector.py +0 -0
  248. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndGlobal.py +0 -0
  249. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndList.py +0 -0
  250. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndMcpServer.py +0 -0
  251. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndMultiSelection.py +0 -0
  252. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndSpinBox.py +0 -0
  253. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndSwitchButton.py +0 -0
  254. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndTextEdit.py +0 -0
  255. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/LabelAndWidget.py +0 -0
  256. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/MarkUpWindow.py +0 -0
  257. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/ModifyListDialog.py +0 -0
  258. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/ModifyListItem.py +0 -0
  259. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/OneTimeTaskTab.py +0 -0
  260. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/PythonHighlighter.py +0 -0
  261. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/RecordScript.py +0 -0
  262. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/ScheduleTaskTab.py +0 -0
  263. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/ScriptPackager.py +0 -0
  264. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/StartButton.py +0 -0
  265. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TaskCard.py +0 -0
  266. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TaskManger.py +0 -0
  267. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TaskOpButton.py +0 -0
  268. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TaskTab.py +0 -0
  269. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TemplateFactory.py +0 -0
  270. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TemplateTab.py +0 -0
  271. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TooltipTableWidget.py +0 -0
  272. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/TriggerTaskTab.py +0 -0
  273. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/__init__.py +0 -0
  274. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/tasks/schedule_index_sync.py +0 -0
  275. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/Alert.py +0 -0
  276. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/InitWorker.py +0 -0
  277. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/__init__.py +0 -0
  278. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/app.py +0 -0
  279. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/download.py +0 -0
  280. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/pip_util.py +0 -0
  281. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/pyappify_startup.py +0 -0
  282. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/touch_scroll.py +0 -0
  283. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/util/windows_thumbnail.py +0 -0
  284. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/BaseLoading.py +0 -0
  285. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/BaseWindow.py +0 -0
  286. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/Card.py +0 -0
  287. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/CustomTab.py +0 -0
  288. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/EmptyCard.py +0 -0
  289. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/ExpandCardLayout.py +0 -0
  290. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/FlowLayout.py +0 -0
  291. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/FramelessDialog.py +0 -0
  292. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/ImageWidget.py +0 -0
  293. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/ImportWarningDialog.py +0 -0
  294. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/ListTableWidgetItem.py +0 -0
  295. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/NumericTableWidgetItem.py +0 -0
  296. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/OkCompactSpinBox.py +0 -0
  297. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/SortingTableWidgetItem.py +0 -0
  298. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/StartLoadingDialog.py +0 -0
  299. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/StatusBar.py +0 -0
  300. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/Tab.py +0 -0
  301. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/TabWidget.py +0 -0
  302. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/UpdateConfigWidgetItem.py +0 -0
  303. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/WidgetWithVLabel.py +0 -0
  304. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/YesNonWidgetItem.py +0 -0
  305. {ok_script-2.0.19 → ok_script-2.0.21}/ok/ui/qt/widget/__init__.py +0 -0
  306. {ok_script-2.0.19 → ok_script-2.0.21}/ok/update/__init__.py +0 -0
  307. {ok_script-2.0.19 → ok_script-2.0.21}/ok/update/copy_ok_folder.py +0 -0
  308. {ok_script-2.0.19 → ok_script-2.0.21}/ok/update/inline_ok_requirements.py +0 -0
  309. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/Analytics.py +0 -0
  310. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/GlobalConfig.py +0 -0
  311. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/__init__.py +0 -0
  312. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/blur.py +0 -0
  313. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/clazz.py +0 -0
  314. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/collection.py +0 -0
  315. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/color.py +0 -0
  316. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/config.py +0 -0
  317. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/explorer.py +0 -0
  318. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/file.py +0 -0
  319. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/gpu_driver_settings.py +0 -0
  320. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/handler.py +0 -0
  321. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/i18n.py +0 -0
  322. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/logger.py +0 -0
  323. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/partial_sync_repo.py +0 -0
  324. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/print_hwnd.py +0 -0
  325. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/process.py +0 -0
  326. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/version.py +0 -0
  327. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/window.py +0 -0
  328. {ok_script-2.0.19 → ok_script-2.0.21}/ok/util/windows_schedule.py +0 -0
  329. {ok_script-2.0.19 → ok_script-2.0.21}/ok_script.egg-info/dependency_links.txt +0 -0
  330. {ok_script-2.0.19 → ok_script-2.0.21}/ok_script.egg-info/entry_points.txt +0 -0
  331. {ok_script-2.0.19 → ok_script-2.0.21}/ok_script.egg-info/not-zip-safe +0 -0
  332. {ok_script-2.0.19 → ok_script-2.0.21}/ok_script.egg-info/requires.txt +0 -0
  333. {ok_script-2.0.19 → ok_script-2.0.21}/ok_script.egg-info/top_level.txt +0 -0
  334. {ok_script-2.0.19 → ok_script-2.0.21}/pyproject.toml +0 -0
  335. {ok_script-2.0.19 → ok_script-2.0.21}/setup.cfg +0 -0
  336. {ok_script-2.0.19 → ok_script-2.0.21}/setup.py +0 -0
  337. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_accent_color.py +0 -0
  338. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_app.py +0 -0
  339. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_base_interaction.py +0 -0
  340. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_blur.py +0 -0
  341. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_box.py +0 -0
  342. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_capture_update.py +0 -0
  343. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_cli.py +0 -0
  344. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_config_card.py +0 -0
  345. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_core_events.py +0 -0
  346. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_core_ui_services.py +0 -0
  347. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_debug_job_controls.py +0 -0
  348. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_device_manager.py +0 -0
  349. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_executor_jobs.py +0 -0
  350. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_expand_card_layout.py +0 -0
  351. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_explorer.py +0 -0
  352. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_global_config.py +0 -0
  353. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_gpu_driver_settings.py +0 -0
  354. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_handler.py +0 -0
  355. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_headless_imports.py +0 -0
  356. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_inline_ok_requirements.py +0 -0
  357. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_logger.py +0 -0
  358. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_main_window_notifications.py +0 -0
  359. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_main_window_startup_tab.py +0 -0
  360. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_main_window_system_theme.py +0 -0
  361. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_mcp_setting.py +0 -0
  362. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_missing_frame.py +0 -0
  363. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_navigation_state.py +0 -0
  364. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_nemu_ipc_capture.py +0 -0
  365. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_notifications.py +0 -0
  366. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_ok_mutex.py +0 -0
  367. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_overlay_custom_draw.py +0 -0
  368. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_overlay_lifecycle.py +0 -0
  369. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_package_metadata.py +0 -0
  370. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_plugin_staging.py +0 -0
  371. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_plugin_tabs.py +0 -0
  372. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_plugins.py +0 -0
  373. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_process.py +0 -0
  374. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_process_mutex.py +0 -0
  375. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_pyappify_startup_update.py +0 -0
  376. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_qt_events.py +0 -0
  377. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_qt_legacy_imports.py +0 -0
  378. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_qt_page_layout.py +0 -0
  379. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_runtime_startup.py +0 -0
  380. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_schedule_startup.py +0 -0
  381. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_schedule_task_index_sync.py +0 -0
  382. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_screenshot_naming.py +0 -0
  383. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_screenshot_rendering.py +0 -0
  384. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_skills.py +0 -0
  385. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_start_controller.py +0 -0
  386. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_start_tab_overlay.py +0 -0
  387. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_task_executor_queue.py +0 -0
  388. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_task_reloading.py +0 -0
  389. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_task_ui.py +0 -0
  390. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_template_compression.py +0 -0
  391. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_template_generation.py +0 -0
  392. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_template_tab.py +0 -0
  393. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_touch_scroll.py +0 -0
  394. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_translation_fallback.py +0 -0
  395. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_ui_config.py +0 -0
  396. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_version.py +0 -0
  397. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_windows_graphics_capture.py +0 -0
  398. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_windows_graphics_hdr.py +0 -0
  399. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_windows_schedule_target_parse.py +0 -0
  400. {ok_script-2.0.19 → ok_script-2.0.21}/tests/test_windows_schedule_xml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ok-script
3
- Version: 2.0.19
3
+ Version: 2.0.21
4
4
  Summary: Automation with Computer Vision for Python
5
5
  Author-email: ok-oldking <firedcto@gmail.com>
6
6
  License: ok-script License
@@ -212,6 +212,8 @@ python -m venv .venv
212
212
  - [白荆回廊](https://github.com/ok-oldking/ok-baijing)(停止维护)
213
213
  - [明日方舟:终末地](https://github.com/AliceJump/ok-end-field)
214
214
  - [异环](https://github.com/BnanZ0/ok-nte)
215
+ - [棕色尘埃 2](https://github.com/GodRaymond233/ok-bd2)
216
+ - [蓝色星原:旅谣](https://github.com/longer-sausage/OK-AzurPromilia)
215
217
 
216
218
  ## 社区与发布
217
219
 
@@ -85,6 +85,8 @@ python -m venv .venv
85
85
  - [白荆回廊](https://github.com/ok-oldking/ok-baijing)(停止维护)
86
86
  - [明日方舟:终末地](https://github.com/AliceJump/ok-end-field)
87
87
  - [异环](https://github.com/BnanZ0/ok-nte)
88
+ - [棕色尘埃 2](https://github.com/GodRaymond233/ok-bd2)
89
+ - [蓝色星原:旅谣](https://github.com/longer-sausage/OK-AzurPromilia)
88
90
 
89
91
  ## 社区与发布
90
92
 
@@ -72,6 +72,15 @@ Applications using `OK(config).start()` can enable MCP through their config:
72
72
  "mcp": {"enabled": True, "port": 8765, "artifact_directory": "logs/mcp"}
73
73
  ```
74
74
 
75
+ MCP artifacts use a seven-day retention period by default. Set `mcp.retention_days`
76
+ to a nonnegative number of days, or `0` to disable cleanup. Cleanup runs on startup
77
+ and at most once per hour when submitting runs/reloads or requesting screenshots.
78
+ It removes expired completed run directories (including their logs, status and
79
+ custom artifacts), their in-memory status records, and old observation images.
80
+ Run age is measured from `finished_at`; observation age uses the image file's
81
+ modification time. Active/nonterminal runs, unrecognized files and connection
82
+ records are preserved. Copy evidence elsewhere if it must outlive retention.
83
+
75
84
  The server binds only to IPv4 loopback and validates HTTP Host and Origin.
76
85
  Each instance writes `logs/mcp/connections/<pid>-<port>.json` containing its URL,
77
86
  bearer token, process ID, process start time and project directory. These records
@@ -143,7 +152,7 @@ Clients supporting MCP resources can also discover these skills through
143
152
 
144
153
  States are `queued`, `running`, `stopping`, `succeeded`, `failed`, and
145
154
  `cancelled`. Only the last three are terminal. Run IDs are scoped to the current
146
- process; saved artifacts remain available after restarting it.
155
+ process; saved artifacts remain available after restarting it until retention cleanup.
147
156
 
148
157
  ## Preferred workflow for existing tasks
149
158
 
@@ -24,7 +24,7 @@ from typing import Any
24
24
 
25
25
  from ok.task.exceptions import TaskDisabledException
26
26
 
27
- _log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', datefmt='%H:%M:%S')
27
+ _log_formatter = logging.Formatter('%(asctime)s.%(msecs)03d %(levelname)s %(message)s', datefmt='%H:%M:%S')
28
28
  _capture_lock = threading.Lock()
29
29
  _run_ids = itertools.count(1)
30
30
 
@@ -4,6 +4,9 @@ import hashlib
4
4
  import importlib.util
5
5
  import inspect
6
6
  import json
7
+ import math
8
+ import re
9
+ import shutil
7
10
  import sys
8
11
  import threading
9
12
  import time
@@ -15,9 +18,11 @@ from pathlib import Path
15
18
  from ok.core.code_runner import capture_output
16
19
  from ok.task.exceptions import TaskDisabledException
17
20
  from ok.task.task import BaseTask, TriggerTask
21
+ from ok.util.logger import Logger
18
22
 
19
23
 
20
24
  TERMINAL_STATES = {'succeeded', 'failed', 'cancelled'}
25
+ logger = Logger.get_logger(__name__)
21
26
 
22
27
 
23
28
  class McpTaskRunner:
@@ -30,7 +35,10 @@ class McpTaskRunner:
30
35
  """
31
36
 
32
37
  def __init__(self, executor, app, screenshot_service, artifact_directory='logs/mcp', prepare=None,
33
- task_manager=None):
38
+ task_manager=None, retention_days=7):
39
+ if (isinstance(retention_days, bool) or not isinstance(retention_days, (int, float))
40
+ or not math.isfinite(retention_days) or retention_days < 0):
41
+ raise ValueError('mcp.retention_days must be a finite nonnegative number')
34
42
  self.executor = executor
35
43
  self.app = app
36
44
  self.screenshot_service = screenshot_service
@@ -42,8 +50,63 @@ class McpTaskRunner:
42
50
  self._active = None
43
51
  self._observation_job = None
44
52
  self._closed = False
53
+ self.retention_days = retention_days
54
+ self._next_cleanup = 0
55
+ self._cleanup_artifacts()
45
56
  self.executor.enable_frame_snapshots()
46
57
 
58
+ def _cleanup_artifacts(self):
59
+ """Expire completed runs and observations, at most hourly during activity."""
60
+ with self._lock:
61
+ now = time.monotonic()
62
+ if self.retention_days == 0 or now < self._next_cleanup:
63
+ return
64
+ self._next_cleanup = now + 3600
65
+ cutoff = time.time() - self.retention_days * 86400
66
+ try:
67
+ paths = list(self.artifact_directory.iterdir())
68
+ except FileNotFoundError:
69
+ return
70
+ except OSError as error:
71
+ logger.warning(f'Could not scan MCP artifacts: {error}')
72
+ return
73
+ for path in paths:
74
+ try:
75
+ # Only operate on framework-owned entries inside this root.
76
+ # In particular, never follow directory links or junctions.
77
+ if path.is_symlink() or path.resolve() != path:
78
+ continue
79
+ if path.name == 'observations' and path.is_dir():
80
+ for image in path.iterdir():
81
+ if (re.fullmatch(r'[0-9a-f]{32}\.png', image.name)
82
+ and not image.is_symlink() and image.is_file()
83
+ and image.resolve() == image
84
+ and image.stat().st_mtime < cutoff):
85
+ try:
86
+ image.unlink()
87
+ except OSError as error:
88
+ logger.warning(f'Could not remove MCP observation {image}: {error}')
89
+ elif (re.fullmatch(r'[0-9a-f]{32}', path.name) and path.is_dir()
90
+ and path.name != self._active):
91
+ try:
92
+ record = json.loads((path / 'status.json').read_text(encoding='utf-8'))
93
+ except (ValueError, UnicodeError):
94
+ continue
95
+ if not isinstance(record, dict):
96
+ continue
97
+ finished = record.get('finished_at')
98
+ if (record.get('run_id') == path.name
99
+ and isinstance(record.get('state'), str)
100
+ and record['state'] in TERMINAL_STATES
101
+ and isinstance(finished, (int, float)) and not isinstance(finished, bool)
102
+ and math.isfinite(finished) and finished < cutoff):
103
+ shutil.rmtree(path)
104
+ self._runs.pop(path.name, None)
105
+ except FileNotFoundError:
106
+ pass # Another server sharing this directory may have removed it.
107
+ except OSError as error:
108
+ logger.warning(f'Could not clean MCP artifacts {path}: {error}')
109
+
47
110
  def _save(self, record):
48
111
  path = Path(record['artifact_directory']) / 'status.json'
49
112
  temporary = path.with_suffix('.tmp')
@@ -135,6 +198,7 @@ class McpTaskRunner:
135
198
  raise RuntimeError('MCP task runner is shutting down')
136
199
  if self._active is not None:
137
200
  raise RuntimeError(f'Run {self._active} is still active; wait until it has stopped')
201
+ self._cleanup_artifacts()
138
202
  run_id = uuid.uuid4().hex
139
203
  owner = f'mcp:{run_id}'
140
204
  self.executor.acquire_exclusive(owner)
@@ -282,6 +346,7 @@ class McpTaskRunner:
282
346
  with self._lock:
283
347
  if self._closed:
284
348
  raise RuntimeError('MCP task runner is shutting down')
349
+ self._cleanup_artifacts()
285
350
  if (self._active is None and self._observation_job is None and self.executor.current_job is None
286
351
  and self.executor.current_task is None and self.executor.exclusive_owner is None):
287
352
  def capture():
@@ -232,7 +232,7 @@ class LocalMcpServer:
232
232
  app = runtime.headless_app if runtime.should_init_task_manager_headless() else runtime.app
233
233
  self.runner = McpTaskRunner(runtime.task_executor, app, runtime.screenshot,
234
234
  config.get('artifact_directory', 'logs/mcp'), self._prepare_device,
235
- task_manager=og.task_manager)
235
+ task_manager=og.task_manager, retention_days=config.get('retention_days', 7))
236
236
  self._server = None
237
237
  self._socket = None
238
238
  self._thread = None
@@ -289,9 +289,11 @@ class LocalMcpServer:
289
289
  self.port = self._socket.getsockname()[1]
290
290
  app = create_mcp_app(self.runner, self.token, self.port, self.exit_process)
291
291
  import uvicorn
292
+ # uvicorn's default log_config goes through dictConfig, which closes every
293
+ # existing handler in the process, including the ok-script.log file handler.
292
294
  self._server = uvicorn.Server(uvicorn.Config(
293
295
  app, host='127.0.0.1', port=self.port, log_level='warning', access_log=False,
294
- timeout_graceful_shutdown=5))
296
+ log_config=None, timeout_graceful_shutdown=5))
295
297
 
296
298
  def serve():
297
299
  try:
@@ -36,8 +36,8 @@ class BaseCaptureMethod:
36
36
  """Capture a frame.
37
37
 
38
38
  :param busy_wait: Seconds to wait when another caller owns the capture.
39
- The default 0 returns None immediately, which suits polling loops
40
- such as the task executor; one-off captures should wait instead.
39
+ The default 0 returns None immediately. The task executor waits
40
+ briefly; one-off captures should wait longer.
41
41
  """
42
42
  if self.exit_event.is_set():
43
43
  return
@@ -151,3 +151,33 @@ ADB_KEY_MAP = {
151
151
  'printscreen': 'KEYCODE_SYSRQ',
152
152
  'print_screen': 'KEYCODE_SYSRQ',
153
153
  }
154
+
155
+ XBUTTON1 = 0x0001
156
+ XBUTTON2 = 0x0002
157
+ MOUSEEVENTF_XDOWN = 0x0080
158
+ MOUSEEVENTF_XUP = 0x0100
159
+
160
+ WM_XBUTTONDOWN = 0x020B
161
+ WM_XBUTTONUP = 0x020C
162
+ MK_XBUTTON1 = 0x0020
163
+ MK_XBUTTON2 = 0x0040
164
+
165
+ MOUSE_BUTTON_MAP = {
166
+ 'mouse4': XBUTTON1,
167
+ 'xbutton1': XBUTTON1,
168
+ 'mouse5': XBUTTON2,
169
+ 'xbutton2': XBUTTON2,
170
+ }
171
+
172
+
173
+ def is_mouse_button(key) -> bool:
174
+ if not isinstance(key, str):
175
+ return False
176
+ return key.strip().lower() in MOUSE_BUTTON_MAP
177
+
178
+
179
+ def get_mouse_button(key) -> int:
180
+ if not isinstance(key, str):
181
+ return 0
182
+ return MOUSE_BUTTON_MAP.get(key.strip().lower(), 0)
183
+
@@ -6,7 +6,10 @@ import win32gui
6
6
 
7
7
  from ok.device.capture_methods.base import BaseCaptureMethod
8
8
  from ok.device.interaction_methods.base import BaseInteraction
9
- from ok.device.interaction_methods.keys import vk_key_dict
9
+ from ok.device.interaction_methods.keys import (
10
+ vk_key_dict, is_mouse_button, get_mouse_button,
11
+ XBUTTON1, MK_XBUTTON1, MK_XBUTTON2, WM_XBUTTONDOWN, WM_XBUTTONUP
12
+ )
10
13
  from ok.util.logger import Logger
11
14
 
12
15
  logger = Logger.get_logger(__name__)
@@ -37,12 +40,27 @@ class PostMessageInteraction(BaseInteraction):
37
40
  def send_key_down(self, key, activate=True):
38
41
  if activate:
39
42
  self.try_activate()
43
+ if is_mouse_button(key):
44
+ btn = get_mouse_button(key)
45
+ mk = MK_XBUTTON1 if btn == XBUTTON1 else MK_XBUTTON2
46
+ wparam = win32api.MAKELONG(mk, btn)
47
+ pos = getattr(self, 'mouse_pos', (0, 0))
48
+ lparam = win32api.MAKELONG(int(pos[0]), int(pos[1]))
49
+ self.post(WM_XBUTTONDOWN, wparam, lparam)
50
+ return
40
51
  vk_code = self.get_key_by_str(key)
41
52
  lparam = self.make_lparam(vk_code, is_up=False)
42
53
  self.post(win32con.WM_KEYDOWN, vk_code, lparam)
43
54
 
44
55
  def send_key_up(self, key):
45
56
  # logger.debug(f'send_key_up {key}')
57
+ if is_mouse_button(key):
58
+ btn = get_mouse_button(key)
59
+ wparam = win32api.MAKELONG(0, btn)
60
+ pos = getattr(self, 'mouse_pos', (0, 0))
61
+ lparam = win32api.MAKELONG(int(pos[0]), int(pos[1]))
62
+ self.post(WM_XBUTTONUP, wparam, lparam)
63
+ return
46
64
  vk_code = self.get_key_by_str(key)
47
65
  lparam = self.make_lparam(vk_code, is_up=True)
48
66
  self.post(win32con.WM_KEYUP, vk_code, lparam)
@@ -215,6 +233,9 @@ class PostMessageInteraction(BaseInteraction):
215
233
  self._dynamic_target_hwnd = target_hwnd
216
234
 
217
235
  local_x, local_y = win32gui.ScreenToClient(target_hwnd, (abs_x, abs_y))
236
+ # Button messages must use the same target-client coordinates as
237
+ # the preceding move, including when a child window is selected.
238
+ self.mouse_pos = (local_x, local_y)
218
239
 
219
240
  hwnd_descriptions = []
220
241
  for index, hwnd_info in enumerate(hwnds):
@@ -233,7 +254,8 @@ class PostMessageInteraction(BaseInteraction):
233
254
  except Exception as e:
234
255
  logger.error(f'update_mouse_pos conversion error targeting {base_hwnd}', e)
235
256
  self._dynamic_target_hwnd = base_hwnd
236
- return win32api.MAKELONG(int(x), int(y))
257
+ self.mouse_pos = (int(x), int(y))
258
+ return win32api.MAKELONG(*self.mouse_pos)
237
259
 
238
260
  def mouse_up(self, key="left"):
239
261
  if key == "left":
@@ -1,14 +1,19 @@
1
+ import ctypes
1
2
  import time
2
3
 
3
4
  import pydirectinput
4
5
 
5
6
  from ok.device.capture_methods.base import BaseCaptureMethod
6
7
  from ok.device.interaction_methods.base import BaseInteraction
7
- from ok.device.interaction_methods.keys import normalize_pydirect_key
8
+ from ok.device.interaction_methods.keys import (
9
+ normalize_pydirect_key, is_mouse_button, get_mouse_button,
10
+ MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP
11
+ )
8
12
  from ok.util.logger import Logger
9
13
  from ok.util.process import is_admin
10
14
 
11
15
  logger = Logger.get_logger(__name__)
16
+ user32 = ctypes.windll.user32
12
17
 
13
18
  class PyDirectInteraction(BaseInteraction):
14
19
 
@@ -35,6 +40,12 @@ class PyDirectInteraction(BaseInteraction):
35
40
  if not self.clickable():
36
41
  logger.error(f"can't click on {key}, because capture is not clickable")
37
42
  return
43
+ if is_mouse_button(key):
44
+ btn = get_mouse_button(key)
45
+ user32.mouse_event(MOUSEEVENTF_XDOWN, 0, 0, btn, 0)
46
+ time.sleep(down_time)
47
+ user32.mouse_event(MOUSEEVENTF_XUP, 0, 0, btn, 0)
48
+ return
38
49
  key = normalize_pydirect_key(key)
39
50
  pydirectinput.keyDown(key)
40
51
  time.sleep(down_time)
@@ -44,8 +55,22 @@ class PyDirectInteraction(BaseInteraction):
44
55
  if not self.clickable():
45
56
  logger.error(f"can't click on {key}, because capture is not clickable")
46
57
  return
58
+ if is_mouse_button(key):
59
+ btn = get_mouse_button(key)
60
+ user32.mouse_event(MOUSEEVENTF_XDOWN, 0, 0, btn, 0)
61
+ return
47
62
  pydirectinput.keyDown(normalize_pydirect_key(key))
48
63
 
64
+ def send_key_up(self, key):
65
+ if not self.clickable():
66
+ logger.error(f"can't click on {key}, because capture is not clickable")
67
+ return
68
+ if is_mouse_button(key):
69
+ btn = get_mouse_button(key)
70
+ user32.mouse_event(MOUSEEVENTF_XUP, 0, 0, btn, 0)
71
+ return
72
+ pydirectinput.keyUp(normalize_pydirect_key(key))
73
+
49
74
  def scroll(self, x, y, scroll_amount):
50
75
  import mouse
51
76
  if scroll_amount < 0:
@@ -62,12 +87,6 @@ class PyDirectInteraction(BaseInteraction):
62
87
  time.sleep(0.001)
63
88
  time.sleep(0.02)
64
89
 
65
- def send_key_up(self, key):
66
- if not self.clickable():
67
- logger.error(f"can't click on {key}, because capture is not clickable")
68
- return
69
- pydirectinput.keyUp(normalize_pydirect_key(key))
70
-
71
90
  def move(self, x, y):
72
91
  import mouse
73
92
  if not self.clickable():
@@ -2,6 +2,7 @@ import time
2
2
 
3
3
  from ok.device.capture_methods.base import BaseCaptureMethod
4
4
  from ok.device.interaction_methods.base import BaseInteraction
5
+ from ok.device.interaction_methods.keys import is_mouse_button, get_mouse_button, XBUTTON1
5
6
  from ok.util.logger import Logger
6
7
  from ok.util.process import is_admin
7
8
 
@@ -53,36 +54,37 @@ class PynputInteraction(BaseInteraction):
53
54
  except KeyError:
54
55
  return key
55
56
 
56
- def send_key(self, key, down_time=0.01):
57
+ def _key_controller(self, key):
58
+ if is_mouse_button(key):
59
+ from pynput import mouse
60
+ return mouse.Controller(), self.get_mouse_button(key)
57
61
  from pynput import keyboard
62
+ return keyboard.Controller(), self._parse_key(str(key))
63
+
64
+ def send_key(self, key, down_time=0.01):
58
65
  if not self.clickable():
59
66
  logger.error(f"can't click on {key}, because capture is not clickable")
60
67
  return
61
68
 
62
- controller = keyboard.Controller()
63
- parsed_key = self._parse_key(str(key))
69
+ controller, parsed_key = self._key_controller(key)
64
70
  controller.press(parsed_key)
65
71
  time.sleep(down_time)
66
72
  controller.release(parsed_key)
67
73
 
68
74
  def send_key_down(self, key):
69
- from pynput import keyboard
70
75
  if not self.clickable():
71
76
  logger.error(f"can't click on {key}, because capture is not clickable")
72
77
  return
73
78
 
74
- controller = keyboard.Controller()
75
- parsed_key = self._parse_key(str(key))
79
+ controller, parsed_key = self._key_controller(key)
76
80
  controller.press(parsed_key)
77
81
 
78
82
  def send_key_up(self, key):
79
- from pynput import keyboard
80
83
  if not self.clickable():
81
84
  logger.error(f"can't click on {key}, because capture is not clickable")
82
85
  return
83
86
 
84
- controller = keyboard.Controller()
85
- parsed_key = self._parse_key(str(key))
87
+ controller, parsed_key = self._key_controller(key)
86
88
  controller.release(parsed_key)
87
89
 
88
90
  def scroll(self, x, y, scroll_amount):
@@ -184,6 +186,8 @@ class PynputInteraction(BaseInteraction):
184
186
 
185
187
  def get_mouse_button(self, key):
186
188
  from pynput import mouse
189
+ if is_mouse_button(key):
190
+ return mouse.Button.x1 if get_mouse_button(key) == XBUTTON1 else mouse.Button.x2
187
191
  if key == "right":
188
192
  return mouse.Button.right
189
193
  if key == "middle":
@@ -15,6 +15,9 @@ from ok.util.window import ratio_text_to_number
15
15
 
16
16
  logger = Logger.get_logger(__name__)
17
17
 
18
+ # How long next_frame() waits for another caller to finish its capture request.
19
+ NEXT_FRAME_BUSY_WAIT = 0.1
20
+
18
21
 
19
22
  class ExecutorJob:
20
23
  """A callable that runs once on the executor thread, outside the task queue.
@@ -321,7 +324,13 @@ class TaskExecutor:
321
324
  if time_out is not None and time.time() - start >= time_out:
322
325
  return None
323
326
  if self.can_capture():
324
- frame = self.method.get_frame()
327
+ # A one-off capture on another thread (debug screenshot,
328
+ # template capture) owns the request for about one frame.
329
+ # Waiting for it is far cheaper than the retry sleep below.
330
+ busy_wait = NEXT_FRAME_BUSY_WAIT
331
+ if time_out is not None:
332
+ busy_wait = min(busy_wait, max(0, time_out - (time.time() - start)))
333
+ frame = self.method.get_frame(busy_wait=busy_wait)
325
334
  if frame is not None:
326
335
  height, width = frame.shape[:2]
327
336
  if height <= 0 or width <= 0:
@@ -29,7 +29,8 @@ VALID_NAMED_KEYS = {
29
29
  'caps_lock', 'num_lock', 'scroll_lock', 'print_screen',
30
30
  'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12',
31
31
  'num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9',
32
- 'windows', 'win', 'command', 'cmd', 'cmd_l', 'cmd_r', 'meta'
32
+ 'windows', 'win', 'command', 'cmd', 'cmd_l', 'cmd_r', 'meta',
33
+ 'mouse4', 'mouse5', 'xbutton1', 'xbutton2'
33
34
  }
34
35
 
35
36
  logger = Logger.get_logger(__name__)
@@ -12,7 +12,10 @@ def init_ok(config):
12
12
  config['debug'] = True
13
13
  config['analytics'] = None
14
14
  config['check_mutex'] = False
15
- print(f'OKTestRunner init_ok config: {config}')
15
+ try:
16
+ print(f'OKTestRunner init_ok config: {config}')
17
+ except UnicodeEncodeError:
18
+ print(f'OKTestRunner init_ok config: {str(config).encode("ascii", errors="replace").decode("ascii")}')
16
19
  ok = OK(config)
17
20
  ok.task_executor.debug_mode = True
18
21
  ok.device_manager.capture_method = ImageCaptureMethod(
@@ -66,6 +66,8 @@ class AboutTab(Tab):
66
66
  {"name": self.tr("Onmyoji"), "url": "https://github.com/YunLiuZ/ok-Onmyoji", "website": "https://ok-script.com/ok-onmyoji/"},
67
67
  {"name": self.tr("Arknights: Endfield"), "url": "https://github.com/AliceJump/ok-end-field", "website": "https://ok-script.com/ok-end-field/"},
68
68
  {"name": self.tr("Neverness to Everness"), "url": "https://github.com/BnanZ0/ok-neverness-to-everness", "website": "https://ok-script.com/ok-nte/"},
69
+ {"name": self.tr("BrownDust II"), "url": "https://github.com/GodRaymond233/ok-bd2"},
70
+ {"name": self.tr("Azur Promilia"), "url": "https://github.com/longer-sausage/OK-AzurPromilia"},
69
71
  ]
70
72
 
71
73
  def normalize_url(url):
@@ -93,6 +93,14 @@
93
93
  <source>Disclaimer</source>
94
94
  <translation>Disclaimer</translation>
95
95
  </message>
96
+ <message>
97
+ <source>BrownDust II</source>
98
+ <translation>BrownDust II</translation>
99
+ </message>
100
+ <message>
101
+ <source>Azur Promilia</source>
102
+ <translation>Azur Promilia</translation>
103
+ </message>
96
104
  </context>
97
105
  <context>
98
106
  <name>ActWindow</name>
@@ -93,6 +93,14 @@
93
93
  <source>Disclaimer</source>
94
94
  <translation>Aviso legal</translation>
95
95
  </message>
96
+ <message>
97
+ <source>BrownDust II</source>
98
+ <translation>BrownDust II</translation>
99
+ </message>
100
+ <message>
101
+ <source>Azur Promilia</source>
102
+ <translation>Azur Promilia</translation>
103
+ </message>
96
104
  </context>
97
105
  <context>
98
106
  <name>ActWindow</name>
@@ -93,6 +93,14 @@
93
93
  <source>Disclaimer</source>
94
94
  <translation>免責事項</translation>
95
95
  </message>
96
+ <message>
97
+ <source>BrownDust II</source>
98
+ <translation>ブラウンダスト2</translation>
99
+ </message>
100
+ <message>
101
+ <source>Azur Promilia</source>
102
+ <translation>アズールプロミリア</translation>
103
+ </message>
96
104
  </context>
97
105
  <context>
98
106
  <name>ActWindow</name>
@@ -3284,4 +3292,4 @@
3284
3292
  <translation>いいえ</translation>
3285
3293
  </message>
3286
3294
  </context>
3287
- </TS>
3295
+ </TS>
@@ -93,6 +93,14 @@
93
93
  <source>Disclaimer</source>
94
94
  <translation>면책 조항</translation>
95
95
  </message>
96
+ <message>
97
+ <source>BrownDust II</source>
98
+ <translation>브라운더스트2</translation>
99
+ </message>
100
+ <message>
101
+ <source>Azur Promilia</source>
102
+ <translation>아주르 프로밀리아</translation>
103
+ </message>
96
104
  </context>
97
105
  <context>
98
106
  <name>ActWindow</name>
@@ -3293,4 +3301,4 @@
3293
3301
  <translation>아니요</translation>
3294
3302
  </message>
3295
3303
  </context>
3296
- </TS>
3304
+ </TS>
@@ -93,6 +93,14 @@
93
93
  <source>Disclaimer</source>
94
94
  <translation>免责声明</translation>
95
95
  </message>
96
+ <message>
97
+ <source>BrownDust II</source>
98
+ <translation>棕色尘埃 2</translation>
99
+ </message>
100
+ <message>
101
+ <source>Azur Promilia</source>
102
+ <translation>蓝色星原:旅谣</translation>
103
+ </message>
96
104
  </context>
97
105
  <context>
98
106
  <name>ActWindow</name>
@@ -93,6 +93,14 @@
93
93
  <source>Disclaimer</source>
94
94
  <translation>免責聲明</translation>
95
95
  </message>
96
+ <message>
97
+ <source>BrownDust II</source>
98
+ <translation>棕色塵埃 2</translation>
99
+ </message>
100
+ <message>
101
+ <source>Azur Promilia</source>
102
+ <translation>藍色星原:旅謠</translation>
103
+ </message>
96
104
  </context>
97
105
  <context>
98
106
  <name>ActWindow</name>