ascript 1.3.27__py3-none-win_amd64.whl

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 (177) hide show
  1. ascript/__init__.py +8 -0
  2. ascript/hooks/__init__.py +0 -0
  3. ascript/hooks/hook-ascript.py +2 -0
  4. ascript/windows/__init__.py +29 -0
  5. ascript/windows/daos/__init__.py +0 -0
  6. ascript/windows/daos/screen.py +143 -0
  7. ascript/windows/hardware/__init__.py +5 -0
  8. ascript/windows/hardware/keyboard.py +279 -0
  9. ascript/windows/hardware/logitech_driver.py +179 -0
  10. ascript/windows/hardware/mouse.py +308 -0
  11. ascript/windows/license/__init__.py +16 -0
  12. ascript/windows/license/achttp.cp310-win_amd64.pyd +0 -0
  13. ascript/windows/license/achttp.cp311-win_amd64.pyd +0 -0
  14. ascript/windows/license/achttp.cp312-win_amd64.pyd +0 -0
  15. ascript/windows/license/achttp.cp313-win_amd64.pyd +0 -0
  16. ascript/windows/license/achttp.cp314-win_amd64.pyd +0 -0
  17. ascript/windows/license/achttp.cp38-win_amd64.pyd +0 -0
  18. ascript/windows/license/achttp.cp39-win_amd64.pyd +0 -0
  19. ascript/windows/media/__init__.py +0 -0
  20. ascript/windows/resources/__init__.py +0 -0
  21. ascript/windows/resources/libs/logitech/x64/LogitechGkeyEnginesWrapper.dll +0 -0
  22. ascript/windows/resources/libs/logitech/x86/LogitechGkeyEnginesWrapper.dll +0 -0
  23. ascript/windows/resources/templates/__init__.py +0 -0
  24. ascript/windows/resources/templates/__init__py.win.template +51 -0
  25. ascript/windows/resources/templates/build.as.win.template +14 -0
  26. ascript/windows/resources/templates/build.py +71 -0
  27. ascript/windows/resources/templates/logo_windows.ico +0 -0
  28. ascript/windows/resources/templates/windows/main.py +50 -0
  29. ascript/windows/resources/templates/windows/pyproject.toml +44 -0
  30. ascript/windows/resources/templates/windows/res/img/logo.ico +0 -0
  31. ascript/windows/screen/__init__.py +13 -0
  32. ascript/windows/screen/as_cv.py +382 -0
  33. ascript/windows/screen/canny.py +128 -0
  34. ascript/windows/screen/code_scanner.py +72 -0
  35. ascript/windows/screen/color_algorithms.py +277 -0
  36. ascript/windows/screen/find_colors.py +251 -0
  37. ascript/windows/screen/find_images.py +217 -0
  38. ascript/windows/screen/ocr/__init__.py +4 -0
  39. ascript/windows/screen/ocr/ocr.py +223 -0
  40. ascript/windows/screen/ocr/rapidocr_hook.py +301 -0
  41. ascript/windows/screen/ocrx.py +169 -0
  42. ascript/windows/screen/screen_core.py +139 -0
  43. ascript/windows/store/__init__.py +21 -0
  44. ascript/windows/system/__init__.py +8 -0
  45. ascript/windows/system/device.py +355 -0
  46. ascript/windows/system/easy_print.py +115 -0
  47. ascript/windows/system/env.py +492 -0
  48. ascript/windows/system/exception/__init__.py +1 -0
  49. ascript/windows/system/key_value.py +145 -0
  50. ascript/windows/system/pip.py +175 -0
  51. ascript/windows/system/r.py +165 -0
  52. ascript/windows/system/runtime.py +62 -0
  53. ascript/windows/tools/__init__.py +27 -0
  54. ascript/windows/tools/__main__.py +21 -0
  55. ascript/windows/tools/action.json +33 -0
  56. ascript/windows/tools/action.py +168 -0
  57. ascript/windows/tools/colors_tool.py +391 -0
  58. ascript/windows/tools/config.py +26 -0
  59. ascript/windows/tools/dumptool.py +18 -0
  60. ascript/windows/tools/eel_api.py +495 -0
  61. ascript/windows/tools/gpplug/__init__.py +0 -0
  62. ascript/windows/tools/gpplug/plug.py +70 -0
  63. ascript/windows/tools/mouse_catch.py +168 -0
  64. ascript/windows/tools/plug_manager.py +38 -0
  65. ascript/windows/tools/tool_api.py +906 -0
  66. ascript/windows/tools/tool_window.py +56 -0
  67. ascript/windows/tools/uia_worker.py +365 -0
  68. ascript/windows/tools/web/app_store_window.html +481 -0
  69. ascript/windows/tools/web/colors.html +532 -0
  70. ascript/windows/tools/web/css/screen.css +1342 -0
  71. ascript/windows/tools/web/css/viewtree.css +357 -0
  72. ascript/windows/tools/web/flot_control.html +195 -0
  73. ascript/windows/tools/web/img/ico/favicon.png +0 -0
  74. ascript/windows/tools/web/img/ico/paintpalette.png +0 -0
  75. ascript/windows/tools/web/img/svg/find_colors.svg +1 -0
  76. ascript/windows/tools/web/img/svg/find_images.svg +1 -0
  77. ascript/windows/tools/web/img/svg/illustration-6.svg +89 -0
  78. ascript/windows/tools/web/img/svg/img_default.svg +1 -0
  79. ascript/windows/tools/web/img/svg/ocr.svg +1 -0
  80. ascript/windows/tools/web/js/screen/colors.js +466 -0
  81. ascript/windows/tools/web/js/screen/gp_plug.js +108 -0
  82. ascript/windows/tools/web/js/screen/image_mouse.js +464 -0
  83. ascript/windows/tools/web/js/screen/img_view.js +558 -0
  84. ascript/windows/tools/web/js/screen/plug.js +246 -0
  85. ascript/windows/tools/web/js/screen/screen.js +690 -0
  86. ascript/windows/tools/web/js/screen/screen_api.js +778 -0
  87. ascript/windows/tools/web/js/screen/screen_maker.js +10 -0
  88. ascript/windows/tools/web/js/utils/map.js +73 -0
  89. ascript/windows/tools/web/js/utils/upload.js +157 -0
  90. ascript/windows/tools/web/js/viewtree/niv_js.js +27 -0
  91. ascript/windows/tools/web/js/viewtree/vtree.js +1510 -0
  92. ascript/windows/tools/web/libs/bootstrap/css/bootstrap.min.css +6 -0
  93. ascript/windows/tools/web/libs/bootstrap/js/bootstrap.bundle.min.js +7 -0
  94. ascript/windows/tools/web/libs/bootstrap-icons/0-circle.svg +4 -0
  95. ascript/windows/tools/web/libs/bootstrap-icons/0-square.svg +4 -0
  96. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.css +2078 -0
  97. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.json +2052 -0
  98. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.min.css +5 -0
  99. ascript/windows/tools/web/libs/bootstrap-icons/font/bootstrap-icons.scss +2090 -0
  100. ascript/windows/tools/web/libs/bootstrap-icons/font/fonts/bootstrap-icons.woff +0 -0
  101. ascript/windows/tools/web/libs/bootstrap-icons/font/fonts/bootstrap-icons.woff2 +0 -0
  102. ascript/windows/tools/web/libs/feather-icons/dist/feather.min.js +13 -0
  103. ascript/windows/tools/web/libs/feather-icons/dist/icons.json +1 -0
  104. ascript/windows/tools/web/libs/jquery/core.js +399 -0
  105. ascript/windows/tools/web/libs/jquery/jquery.js +10598 -0
  106. ascript/windows/tools/web/libs/jquery/jquery.min.js +4 -0
  107. ascript/windows/tools/web/libs/jquery/jquery.min.js.zip +0 -0
  108. ascript/windows/tools/web/libs/jquery/jquery.slim.js +8495 -0
  109. ascript/windows/tools/web/libs/jquery/jquery.slim.min.js +2 -0
  110. ascript/windows/tools/web/libs/jquery-menu/jquery.contextMenu.js +2134 -0
  111. ascript/windows/tools/web/libs/jquery-menu/jquery.contextMenu.min.css +16 -0
  112. ascript/windows/tools/web/libs/jquery-zTree/css/zTreeStyle.css +97 -0
  113. ascript/windows/tools/web/libs/jquery-zTree/img/diy/1_close.png +0 -0
  114. ascript/windows/tools/web/libs/jquery-zTree/img/diy/1_open.png +0 -0
  115. ascript/windows/tools/web/libs/jquery-zTree/img/diy/2.png +0 -0
  116. ascript/windows/tools/web/libs/jquery-zTree/img/diy/3.png +0 -0
  117. ascript/windows/tools/web/libs/jquery-zTree/img/diy/4.png +0 -0
  118. ascript/windows/tools/web/libs/jquery-zTree/img/diy/5.png +0 -0
  119. ascript/windows/tools/web/libs/jquery-zTree/img/diy/6.png +0 -0
  120. ascript/windows/tools/web/libs/jquery-zTree/img/diy/7.png +0 -0
  121. ascript/windows/tools/web/libs/jquery-zTree/img/diy/8.png +0 -0
  122. ascript/windows/tools/web/libs/jquery-zTree/img/diy/9.png +0 -0
  123. ascript/windows/tools/web/libs/jquery-zTree/img/line_conn.gif +0 -0
  124. ascript/windows/tools/web/libs/jquery-zTree/img/loading.gif +0 -0
  125. ascript/windows/tools/web/libs/jquery-zTree/img/tree-node-btn.png +0 -0
  126. ascript/windows/tools/web/libs/jquery-zTree/img/zTreeStandard.gif +0 -0
  127. ascript/windows/tools/web/libs/jquery-zTree/img/zTreeStandard.png +0 -0
  128. ascript/windows/tools/web/libs/jquery-zTree/js/jquery.ztree.all.min.js +3 -0
  129. ascript/windows/tools/web/libs/treeview/css/jquery.treeview.css +79 -0
  130. ascript/windows/tools/web/libs/treeview/img/file.png +0 -0
  131. ascript/windows/tools/web/libs/treeview/img/ico_loading.png +0 -0
  132. ascript/windows/tools/web/libs/treeview/img/icon4.png +0 -0
  133. ascript/windows/tools/web/libs/treeview/img/icon5.png +0 -0
  134. ascript/windows/tools/web/libs/treeview/img/icon6.png +0 -0
  135. ascript/windows/tools/web/libs/treeview/img/py.png +0 -0
  136. ascript/windows/tools/web/libs/treeview/img/treeview-black-line.gif +0 -0
  137. ascript/windows/tools/web/libs/treeview/img/treeview-black.gif +0 -0
  138. ascript/windows/tools/web/libs/treeview/img/treeview-default-line.gif +0 -0
  139. ascript/windows/tools/web/libs/treeview/img/treeview-default.gif +0 -0
  140. ascript/windows/tools/web/libs/treeview/img/treeview-famfamfam-line.gif +0 -0
  141. ascript/windows/tools/web/libs/treeview/img/treeview-famfamfam.gif +0 -0
  142. ascript/windows/tools/web/libs/treeview/img/treeview-gray-line.gif +0 -0
  143. ascript/windows/tools/web/libs/treeview/img/treeview-gray.gif +0 -0
  144. ascript/windows/tools/web/libs/treeview/img/treeview-red-line.gif +0 -0
  145. ascript/windows/tools/web/libs/treeview/img/treeview-red.gif +0 -0
  146. ascript/windows/tools/web/libs/treeview/js/jquery.treeview.edit.js +37 -0
  147. ascript/windows/tools/web/libs/treeview/js/jquery.treeview.js +250 -0
  148. ascript/windows/tools/web/license_window.html +255 -0
  149. ascript/windows/tools/web/plugs/a.html +653 -0
  150. ascript/windows/tools/web/plugs/demo.html +52 -0
  151. ascript/windows/tools/web/plugs/find_colors.html +629 -0
  152. ascript/windows/tools/web/plugs/find_images.html +699 -0
  153. ascript/windows/tools/web/plugs/rapidocr.html +954 -0
  154. ascript/windows/tools/web/vtree.html +496 -0
  155. ascript/windows/tools/webview/assets/index-HymBPl-I.css +1 -0
  156. ascript/windows/tools/webview/assets/index-PqA_m8tL.js +17 -0
  157. ascript/windows/tools/webview/index.html +13 -0
  158. ascript/windows/ui/__init__.py +6 -0
  159. ascript/windows/ui/app_store_window.py +272 -0
  160. ascript/windows/ui/draw_window.py +231 -0
  161. ascript/windows/ui/flot_test.py +297 -0
  162. ascript/windows/ui/flot_window.py +488 -0
  163. ascript/windows/ui/license_window.py +111 -0
  164. ascript/windows/ui/web_window.py +466 -0
  165. ascript/windows/utils/__init__.py +0 -0
  166. ascript/windows/utils/node_utils.py +20 -0
  167. ascript/windows/utils/screen_utils.py +280 -0
  168. ascript/windows/window/Selector.py +1015 -0
  169. ascript/windows/window/Window.py +747 -0
  170. ascript/windows/window/__init__.py +5 -0
  171. ascript/windows/window/launcher.py +213 -0
  172. ascript/windows/window/uia_runtime.py +26 -0
  173. ascript-1.3.27.dist-info/METADATA +41 -0
  174. ascript-1.3.27.dist-info/RECORD +177 -0
  175. ascript-1.3.27.dist-info/WHEEL +5 -0
  176. ascript-1.3.27.dist-info/entry_points.txt +2 -0
  177. ascript-1.3.27.dist-info/top_level.txt +1 -0
@@ -0,0 +1,250 @@
1
+ /*
2
+ * Treeview 1.4.2 - jQuery plugin to hide and show branches of a tree
3
+ *
4
+ * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
5
+ *
6
+ * Copyright Jörn Zaefferer
7
+ * Released under the MIT license:
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ */
10
+
11
+ ;(function($) {
12
+
13
+ // TODO rewrite as a widget, removing all the extra plugins
14
+ $.extend($.fn, {
15
+ swapClass: function(c1, c2) {
16
+ var c1Elements = this.filter('.' + c1);
17
+ this.filter('.' + c2).removeClass(c2).addClass(c1);
18
+ c1Elements.removeClass(c1).addClass(c2);
19
+ return this;
20
+ },
21
+ replaceClass: function(c1, c2) {
22
+ return this.filter('.' + c1).removeClass(c1).addClass(c2).end();
23
+ },
24
+ hoverClass: function(className) {
25
+ className = className || "hover";
26
+ return this.hover(function() {
27
+ $(this).addClass(className);
28
+ }, function() {
29
+ $(this).removeClass(className);
30
+ });
31
+ },
32
+ heightToggle: function(animated, callback) {
33
+ animated ?
34
+ this.animate({ height: "toggle" }, animated, callback) :
35
+ this.each(function(){
36
+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
37
+ if(callback)
38
+ callback.apply(this, arguments);
39
+ });
40
+ },
41
+ heightHide: function(animated, callback) {
42
+ if (animated) {
43
+ this.animate({ height: "hide" }, animated, callback);
44
+ } else {
45
+ this.hide();
46
+ if (callback)
47
+ this.each(callback);
48
+ }
49
+ },
50
+ prepareBranches: function(settings) {
51
+ if (!settings.prerendered) {
52
+ // mark last tree items
53
+ this.filter(":last-child:not(ul)").addClass(CLASSES.last);
54
+ // collapse whole tree, or only those marked as closed, anyway except those marked as open
55
+ this.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide();
56
+ }
57
+ // return all items with sublists
58
+ return this.filter(":has(>ul)");
59
+ },
60
+ applyClasses: function(settings, toggler) {
61
+ // TODO use event delegation
62
+ this.filter(":has(>ul):not(:has(>a))").find(">span").unbind("click.treeview").bind("click.treeview", function(event) {
63
+ // don't handle click events on children, eg. checkboxes
64
+ if ( this == event.target )
65
+ toggler.apply($(this).next());
66
+ }).add( $("a", this) ).hoverClass();
67
+
68
+ if (!settings.prerendered) {
69
+ // handle closed ones first
70
+ this.filter(":has(>ul:hidden)")
71
+ .addClass(CLASSES.expandable)
72
+ .replaceClass(CLASSES.last, CLASSES.lastExpandable);
73
+
74
+ // handle open ones
75
+ this.not(":has(>ul:hidden)")
76
+ .addClass(CLASSES.collapsable)
77
+ .replaceClass(CLASSES.last, CLASSES.lastCollapsable);
78
+
79
+ // create hitarea if not present
80
+ var hitarea = this.find("div." + CLASSES.hitarea);
81
+ if (!hitarea.length)
82
+ hitarea = this.prepend("<div class=\"" + CLASSES.hitarea + "\"/>").find("div." + CLASSES.hitarea);
83
+ hitarea.removeClass().addClass(CLASSES.hitarea).each(function() {
84
+ var classes = "";
85
+ $.each($(this).parent().attr("class").split(" "), function() {
86
+ classes += this + "-hitarea ";
87
+ });
88
+ $(this).addClass( classes );
89
+ })
90
+ }
91
+
92
+ // apply event to hitarea
93
+ this.find("div." + CLASSES.hitarea).click( toggler );
94
+ },
95
+ treeview: function(settings) {
96
+
97
+ settings = $.extend({
98
+ cookieId: "treeview"
99
+ }, settings);
100
+
101
+ if ( settings.toggle ) {
102
+ var callback = settings.toggle;
103
+ settings.toggle = function() {
104
+ return callback.apply($(this).parent()[0], arguments);
105
+ };
106
+ }
107
+
108
+ // factory for treecontroller
109
+ function treeController(tree, control) {
110
+ // factory for click handlers
111
+ function handler(filter) {
112
+ return function() {
113
+ // reuse toggle event handler, applying the elements to toggle
114
+ // start searching for all hitareas
115
+ toggler.apply( $("div." + CLASSES.hitarea, tree).filter(function() {
116
+ // for plain toggle, no filter is provided, otherwise we need to check the parent element
117
+ return filter ? $(this).parent("." + filter).length : true;
118
+ }) );
119
+ return false;
120
+ };
121
+ }
122
+ // click on first element to collapse tree
123
+ $("a:eq(0)", control).click( handler(CLASSES.collapsable) );
124
+ // click on second to expand tree
125
+ $("a:eq(1)", control).click( handler(CLASSES.expandable) );
126
+ // click on third to toggle tree
127
+ $("a:eq(2)", control).click( handler() );
128
+ }
129
+
130
+ // handle toggle event
131
+ function toggler() {
132
+ $(this)
133
+ .parent()
134
+ // swap classes for hitarea
135
+ .find(">.hitarea")
136
+ .swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
137
+ .swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
138
+ .end()
139
+ // swap classes for parent li
140
+ .swapClass( CLASSES.collapsable, CLASSES.expandable )
141
+ .swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
142
+ // find child lists
143
+ .find( ">ul" )
144
+ // toggle them
145
+ .heightToggle( settings.animated, settings.toggle );
146
+ if ( settings.unique ) {
147
+ $(this).parent()
148
+ .siblings()
149
+ // swap classes for hitarea
150
+ .find(">.hitarea")
151
+ .replaceClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
152
+ .replaceClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
153
+ .end()
154
+ .replaceClass( CLASSES.collapsable, CLASSES.expandable )
155
+ .replaceClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
156
+ .find( ">ul" )
157
+ .heightHide( settings.animated, settings.toggle );
158
+ }
159
+ }
160
+ this.data("toggler", toggler);
161
+
162
+ function serialize() {
163
+ function binary(arg) {
164
+ return arg ? 1 : 0;
165
+ }
166
+ var data = [];
167
+ branches.each(function(i, e) {
168
+ data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0;
169
+ });
170
+ $.cookie(settings.cookieId, data.join(""), settings.cookieOptions );
171
+ }
172
+
173
+ function deserialize() {
174
+ var stored = $.cookie(settings.cookieId);
175
+ if ( stored ) {
176
+ var data = stored.split("");
177
+ branches.each(function(i, e) {
178
+ $(e).find(">ul")[ parseInt(data[i]) ? "show" : "hide" ]();
179
+ });
180
+ }
181
+ }
182
+
183
+ // add treeview class to activate styles
184
+ this.addClass("treeview");
185
+
186
+ // prepare branches and find all tree items with child lists
187
+ var branches = this.find("li").prepareBranches(settings);
188
+
189
+ switch(settings.persist) {
190
+ case "cookie":
191
+ var toggleCallback = settings.toggle;
192
+ settings.toggle = function() {
193
+ serialize();
194
+ if (toggleCallback) {
195
+ toggleCallback.apply(this, arguments);
196
+ }
197
+ };
198
+ deserialize();
199
+ break;
200
+ case "location":
201
+ var current = this.find("a").filter(function() {
202
+ return location.href.toLowerCase().indexOf(this.href.toLowerCase()) == 0;
203
+ });
204
+ if ( current.length ) {
205
+ // TODO update the open/closed classes
206
+ var items = current.addClass("selected").parents("ul, li").add( current.next() ).show();
207
+ if (settings.prerendered) {
208
+ // if prerendered is on, replicate the basic class swapping
209
+ items.filter("li")
210
+ .swapClass( CLASSES.collapsable, CLASSES.expandable )
211
+ .swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
212
+ .find(">.hitarea")
213
+ .swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
214
+ .swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea );
215
+ }
216
+ }
217
+ break;
218
+ }
219
+
220
+ branches.applyClasses(settings, toggler);
221
+
222
+ // if control option is set, create the treecontroller and show it
223
+ if ( settings.control ) {
224
+ treeController(this, settings.control);
225
+ $(settings.control).show();
226
+ }
227
+
228
+ return this;
229
+ }
230
+ });
231
+
232
+ // classes used by the plugin
233
+ // need to be styled via external stylesheet, see first example
234
+ $.treeview = {};
235
+ var CLASSES = ($.treeview.classes = {
236
+ open: "open",
237
+ closed: "closed",
238
+ expandable: "expandable",
239
+ expandableHitarea: "expandable-hitarea",
240
+ lastExpandableHitarea: "lastExpandable-hitarea",
241
+ collapsable: "collapsable",
242
+ collapsableHitarea: "collapsable-hitarea",
243
+ lastCollapsableHitarea: "lastCollapsable-hitarea",
244
+ lastCollapsable: "lastCollapsable",
245
+ lastExpandable: "lastExpandable",
246
+ last: "last",
247
+ hitarea: "hitarea"
248
+ });
249
+
250
+ })(jQuery);
@@ -0,0 +1,255 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AScript 引擎</title>
7
+ <link href="./libs/bootstrap/css/bootstrap.min.css" rel="stylesheet">
8
+ <style>
9
+ :root {
10
+ --vs-bg-main: #1e1e1e;
11
+ --vs-bg-side: #252526;
12
+ --vs-border: #333333;
13
+ --vs-accent: #007acc;
14
+ --vs-text: #888888;
15
+ --vs-text-light: #cccccc;
16
+ --vs-input-bg: #3c3c3c;
17
+ --vs-error: #f48771;
18
+ }
19
+
20
+ html, body {
21
+ height: 100%; margin: 0; padding: 0;
22
+ background-color: var(--vs-bg-main);
23
+ color: var(--vs-text-light);
24
+ font-family: 'Microsoft YaHei', 'Segoe UI', system-ui, sans-serif;
25
+ overflow: hidden; display: flex; flex-direction: column;
26
+ user-select: none;
27
+ }
28
+
29
+ header {
30
+ background-color: var(--vs-bg-side);
31
+ padding: 20px 28px;
32
+ border-bottom: 1px solid var(--vs-border);
33
+ flex-shrink: 0;
34
+ }
35
+
36
+ #app-name {
37
+ font-size: 1.1rem; font-weight: 600; color: #fff;
38
+ margin: 0; letter-spacing: 0.5px;
39
+ }
40
+
41
+ main { flex: 1; padding: 28px; overflow-y: auto; display: flex; flex-direction: column; }
42
+
43
+ .meta-group { display: flex; gap: 40px; margin-bottom: 10px; flex-shrink: 0; }
44
+ .meta-label { font-size: 11px; color: #555; text-transform: uppercase; display: block; margin-bottom: 6px; font-weight: bold; }
45
+ .meta-value { font-family: 'Consolas', monospace; font-size: 14px; color: var(--vs-accent); }
46
+
47
+ #desc-container {
48
+ flex: 1;
49
+ font-size: 14px;
50
+ line-height: 1.8;
51
+ color: #999;
52
+ overflow-y: auto;
53
+ margin-bottom: 20px;
54
+ padding-top: 0;
55
+ padding-right: 10px;
56
+ }
57
+
58
+ #desc-container b, #desc-container strong { color: #ddd; font-weight: 600; }
59
+ #desc-container p { margin: 0 0 1.2rem 0; }
60
+
61
+ .auth-wrapper { margin-top: auto; padding-top: 20px; border-top: 1px solid var(--vs-border); }
62
+
63
+ .vs-input-group {
64
+ display: flex; background: var(--vs-input-bg);
65
+ border: 1px solid transparent; height: 36px; border-radius: 2px;
66
+ transition: border 0.2s; align-items: stretch;
67
+ }
68
+ .vs-input-group.error { border-color: var(--vs-error) !important; }
69
+ .vs-input-group:focus-within { border-color: var(--vs-accent); }
70
+
71
+ #license-key {
72
+ background: transparent; border: none; color: white;
73
+ padding: 0 12px; flex: 1; font-size: 13px; outline: none;
74
+ }
75
+
76
+ .btn-vs-action {
77
+ background: var(--vs-accent); color: white; border: none;
78
+ padding: 0 16px; font-size: 12px; cursor: pointer;
79
+ display: flex; flex-direction: row; align-items: center;
80
+ justify-content: center; min-width: 90px;
81
+ }
82
+
83
+ .btn-link-vs {
84
+ color: var(--vs-accent); background: none; border: none;
85
+ font-size: 11px; cursor: pointer; padding: 0; margin-left: 15px;
86
+ text-decoration: underline; opacity: 0.8;
87
+ }
88
+ .btn-link-vs:hover { opacity: 1; }
89
+
90
+ #card-expire {
91
+ color: #aaa;
92
+ font-size: 11px;
93
+ margin-left: 10px;
94
+ padding: 2px 6px;
95
+ background: #2d2d2d;
96
+ border-radius: 2px;
97
+ font-family: 'Consolas', monospace;
98
+ }
99
+
100
+ .spinner {
101
+ width: 12px; height: 12px; border: 2px solid rgba(255,255,255,0.2);
102
+ border-radius: 50%; border-top-color: #fff;
103
+ animation: spin 0.8s linear infinite; margin-right: 8px;
104
+ }
105
+ @keyframes spin { to { transform: rotate(360deg); } }
106
+
107
+ footer { flex-shrink: 0; }
108
+ .btn-launch {
109
+ width: 100%; border: none; padding: 16px;
110
+ font-weight: 600; text-transform: uppercase; font-size: 13px;
111
+ background: #333; color: #666; transition: 0.3s;
112
+ }
113
+ .btn-launch:not(:disabled) { background: var(--vs-accent); color: white; cursor: pointer; }
114
+
115
+ ::-webkit-scrollbar { width: 4px; }
116
+ ::-webkit-scrollbar-thumb { background: #333; }
117
+ </style>
118
+ </head>
119
+ <body>
120
+
121
+ <header>
122
+ <div class="d-flex justify-content-between align-items-center">
123
+ <h1 id="app-name">引擎系统</h1>
124
+ <div id="price-tag" style="font-size: 10px; padding: 2px 8px; border: 1px solid #333; color: #555;">...</div>
125
+ </div>
126
+ </header>
127
+
128
+ <main>
129
+ <div class="meta-group">
130
+ <div><span class="meta-label">应用 ID</span><span id="app-id" class="meta-value">--</span></div>
131
+ <div><span class="meta-label">开发作者</span><span id="app-auth" class="meta-value">--</span></div>
132
+ </div>
133
+
134
+ <div id="desc-container">正在检索应用配置信息...</div>
135
+
136
+ <div id="auth-section" class="auth-wrapper" style="display: none;">
137
+ <div id="active-info" style="display: none; margin-bottom: 12px;">
138
+ <div class="d-flex align-items-center justify-content-between">
139
+ <div>
140
+ <span style="color: #4ade80; font-size: 12px;">● 授权验证成功</span>
141
+ <span id="card-expire"></span>
142
+ </div>
143
+ <button class="btn-link-vs" onclick="resetAuth()">更换激活码</button>
144
+ </div>
145
+ </div>
146
+
147
+ <div id="input-area">
148
+ <div class="vs-input-group" id="input-container">
149
+ <input type="text" id="license-key" placeholder="输入激活码以解锁专业功能" autocomplete="off">
150
+ <button class="btn-vs-action" id="activate-btn" onclick="handleActivate()">
151
+ <span id="btn-content" style="display:flex; align-items:center;">激活</span>
152
+ </button>
153
+ </div>
154
+ <div id="expire-msg" class="text-danger mt-2" style="display:none; font-size: 11px;">验证失败:授权码无效或已过期。</div>
155
+ </div>
156
+ </div>
157
+ </main>
158
+
159
+ <footer>
160
+ <button id="enter-btn" class="btn-launch" disabled onclick="handleEnter()">立即启动系统</button>
161
+ </footer>
162
+
163
+ <script>
164
+ async function initPage() {
165
+ try {
166
+ const appData = await window.callPython("get_app_info");
167
+ document.getElementById('app-name').innerText = appData.name;
168
+ document.getElementById('app-auth').innerText = appData.auth;
169
+ document.getElementById('app-id').innerText = appData.id;
170
+ document.getElementById('desc-container').innerHTML = appData.desc;
171
+
172
+ const priceTag = document.getElementById('price-tag');
173
+ if (appData.is_free === 1) {
174
+ priceTag.innerText = "社区免费版";
175
+ priceTag.style.color = "#28a745";
176
+ document.getElementById('enter-btn').disabled = false;
177
+ } else {
178
+ priceTag.innerText = "专业授权版";
179
+ priceTag.style.color = "#ffbf00";
180
+ document.getElementById('auth-section').style.display = 'block';
181
+ const cachedKey = await window.callPython("get_cached_key");
182
+ if (cachedKey) {
183
+ document.getElementById('license-key').value = cachedKey;
184
+ handleActivate(cachedKey);
185
+ }
186
+ }
187
+ } catch(e) { console.error(e); }
188
+ }
189
+
190
+ async function handleActivate(keyOverride = null) {
191
+ const keyInput = document.getElementById('license-key');
192
+ const inputContainer = document.getElementById('input-container');
193
+ const btn = document.getElementById('activate-btn');
194
+ const btnContent = document.getElementById('btn-content');
195
+ const expireMsg = document.getElementById('expire-msg');
196
+ const key = keyOverride || keyInput.value.trim();
197
+
198
+ if (!key) {
199
+ inputContainer.classList.add('error');
200
+ setTimeout(() => inputContainer.classList.remove('error'), 1000);
201
+ return;
202
+ }
203
+
204
+ // 重置状态
205
+ btn.disabled = true;
206
+ btnContent.innerHTML = '<div class="spinner"></div><span>验证中</span>';
207
+ expireMsg.style.display = 'none';
208
+ inputContainer.classList.remove('error');
209
+
210
+ try {
211
+ // 这里获取的是 Python activate_key 返回的原始对象 (包含 code 和 data)
212
+ const res = await window.callPython("activate_key", key);
213
+
214
+ // 核心逻辑:只有 code == 1 且 data.status == 1 才是激活成功
215
+ if (res && res.code === 1 && res.data && res.data.status === 1) {
216
+ document.getElementById('active-info').style.display = 'block';
217
+ document.getElementById('input-area').style.display = 'none';
218
+ document.getElementById('card-expire').innerText = "到期时间: " + res.data.expire;
219
+ document.getElementById('enter-btn').disabled = false;
220
+ expireMsg.style.display = 'none';
221
+ } else {
222
+ // 如果 status 不为 1 (例如过期 status=2,或者错误 code=0)
223
+ inputContainer.classList.add('error');
224
+ expireMsg.style.display = 'block';
225
+
226
+ // 优先展示后端返回的错误消息
227
+ let errorText = "验证失败:授权码无效或已过期。";
228
+ if (res && res.data && res.data.msg) errorText = "验证失败:" + res.data.msg;
229
+ else if (res && res.msg) errorText = "提示:" + res.msg;
230
+
231
+ expireMsg.innerText = errorText;
232
+ document.getElementById('enter-btn').disabled = true;
233
+ document.getElementById('active-info').style.display = 'none';
234
+ }
235
+ } catch (e) {
236
+ expireMsg.innerText = "异常:无法连接验证服务器";
237
+ expireMsg.style.display = 'block';
238
+ } finally {
239
+ btn.disabled = false;
240
+ btnContent.innerHTML = '激活';
241
+ }
242
+ }
243
+
244
+ function resetAuth() {
245
+ document.getElementById('active-info').style.display = 'none';
246
+ document.getElementById('input-area').style.display = 'block';
247
+ document.getElementById('enter-btn').disabled = true;
248
+ document.getElementById('expire-msg').style.display = 'none';
249
+ }
250
+
251
+ function handleEnter() { window.callPython("start_app"); }
252
+ window.addEventListener('onPythonReady', initPage);
253
+ </script>
254
+ </body>
255
+ </html>