dsh-plugin-image-workbench 1.1.5 → 1.1.7

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 (173) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +5 -3
  3. package/README.md +7 -3
  4. package/client.js +241 -241
  5. package/cordis.patch.yml +14 -14
  6. package/host.js +51 -0
  7. package/install.mjs +333 -387
  8. package/package.json +3 -2
  9. package/scripts/fetch-style-images.mjs +104 -0
  10. package/scripts/vendor-snapshot.py +154 -154
  11. package/server/access.py +26 -26
  12. package/server/app.py +1371 -1329
  13. package/server/catalog.py +147 -147
  14. package/server/composer.py +391 -391
  15. package/server/drafts.py +158 -158
  16. package/server/history.py +575 -575
  17. package/server/imaging.py +172 -172
  18. package/server/pool.py +1335 -1335
  19. package/server/pool_admin.py +921 -921
  20. package/server/pool_service.py +1073 -1073
  21. package/server/requirements.txt +6 -6
  22. package/server/smoke_check.py +402 -402
  23. package/server/static/access.html +202 -202
  24. package/server/static/index.html +15 -0
  25. package/vendor/chatgpt2api/source/.env.example +82 -82
  26. package/vendor/chatgpt2api/source/.python-version +1 -1
  27. package/vendor/chatgpt2api/source/LICENSE +21 -21
  28. package/vendor/chatgpt2api/source/README.md +391 -391
  29. package/vendor/chatgpt2api/source/VERSION +1 -1
  30. package/vendor/chatgpt2api/source/api/__init__.py +2 -2
  31. package/vendor/chatgpt2api/source/api/accounts.py +537 -537
  32. package/vendor/chatgpt2api/source/api/ai.py +217 -217
  33. package/vendor/chatgpt2api/source/api/app.py +62 -62
  34. package/vendor/chatgpt2api/source/api/errors.py +46 -46
  35. package/vendor/chatgpt2api/source/api/image_inputs.py +309 -309
  36. package/vendor/chatgpt2api/source/api/image_tasks.py +120 -120
  37. package/vendor/chatgpt2api/source/api/support.py +134 -134
  38. package/vendor/chatgpt2api/source/api/system.py +365 -365
  39. package/vendor/chatgpt2api/source/assets/kunrouai.svg +50 -50
  40. package/vendor/chatgpt2api/source/config.default.json +108 -108
  41. package/vendor/chatgpt2api/source/main.py +9 -9
  42. package/vendor/chatgpt2api/source/pyproject.toml +27 -27
  43. package/vendor/chatgpt2api/source/scripts/init_proxy_config.py +186 -186
  44. package/vendor/chatgpt2api/source/scripts/migrate_storage.py +163 -163
  45. package/vendor/chatgpt2api/source/scripts/privoxy-warp.conf +13 -13
  46. package/vendor/chatgpt2api/source/scripts/test_outlook_token_mailbox.py +385 -385
  47. package/vendor/chatgpt2api/source/scripts/test_storage.py +129 -129
  48. package/vendor/chatgpt2api/source/scripts/verify_oauth_refresh.py +92 -92
  49. package/vendor/chatgpt2api/source/services/account_service.py +1757 -1757
  50. package/vendor/chatgpt2api/source/services/auth_service.py +253 -253
  51. package/vendor/chatgpt2api/source/services/backup_service.py +671 -671
  52. package/vendor/chatgpt2api/source/services/config.py +667 -667
  53. package/vendor/chatgpt2api/source/services/content_filter.py +242 -242
  54. package/vendor/chatgpt2api/source/services/cpa_service.py +315 -315
  55. package/vendor/chatgpt2api/source/services/editable_file_task_service.py +260 -260
  56. package/vendor/chatgpt2api/source/services/image_service.py +376 -376
  57. package/vendor/chatgpt2api/source/services/image_storage_service.py +405 -405
  58. package/vendor/chatgpt2api/source/services/image_tags_service.py +76 -76
  59. package/vendor/chatgpt2api/source/services/image_task_service.py +550 -550
  60. package/vendor/chatgpt2api/source/services/log_service.py +337 -337
  61. package/vendor/chatgpt2api/source/services/model_service.py +182 -182
  62. package/vendor/chatgpt2api/source/services/oauth_login_service.py +267 -267
  63. package/vendor/chatgpt2api/source/services/openai_backend_api.py +2763 -2763
  64. package/vendor/chatgpt2api/source/services/openai_oauth.py +32 -32
  65. package/vendor/chatgpt2api/source/services/protocol/__init__.py +2 -2
  66. package/vendor/chatgpt2api/source/services/protocol/anthropic_v1_messages.py +307 -307
  67. package/vendor/chatgpt2api/source/services/protocol/chat_completion_cache.py +238 -238
  68. package/vendor/chatgpt2api/source/services/protocol/conversation.py +1644 -1644
  69. package/vendor/chatgpt2api/source/services/protocol/error_response.py +124 -124
  70. package/vendor/chatgpt2api/source/services/protocol/openai_search.py +19 -19
  71. package/vendor/chatgpt2api/source/services/protocol/openai_v1_chat_complete.py +316 -316
  72. package/vendor/chatgpt2api/source/services/protocol/openai_v1_image_edit.py +86 -86
  73. package/vendor/chatgpt2api/source/services/protocol/openai_v1_image_generations.py +42 -42
  74. package/vendor/chatgpt2api/source/services/protocol/openai_v1_models.py +53 -53
  75. package/vendor/chatgpt2api/source/services/protocol/openai_v1_response.py +453 -453
  76. package/vendor/chatgpt2api/source/services/protocol/web_search_tool.py +160 -160
  77. package/vendor/chatgpt2api/source/services/proxy_service.py +648 -648
  78. package/vendor/chatgpt2api/source/services/storage/__init__.py +5 -5
  79. package/vendor/chatgpt2api/source/services/storage/base.py +38 -38
  80. package/vendor/chatgpt2api/source/services/storage/database_storage.py +194 -194
  81. package/vendor/chatgpt2api/source/services/storage/factory.py +104 -104
  82. package/vendor/chatgpt2api/source/services/storage/git_storage.py +183 -183
  83. package/vendor/chatgpt2api/source/services/storage/json_storage.py +95 -95
  84. package/vendor/chatgpt2api/source/services/sub2api_service.py +531 -531
  85. package/vendor/chatgpt2api/source/utils/helper.py +469 -469
  86. package/vendor/chatgpt2api/source/utils/image_tokens.py +346 -346
  87. package/vendor/chatgpt2api/source/utils/log.py +110 -110
  88. package/vendor/chatgpt2api/source/utils/pkce.py +19 -19
  89. package/vendor/chatgpt2api/source/utils/pow.py +207 -207
  90. package/vendor/chatgpt2api/source/utils/sentinel.py +159 -159
  91. package/vendor/chatgpt2api/source/utils/turnstile.py +184 -184
  92. package/vendor/chatgpt2api/source/uv.lock +904 -904
  93. package/vendor/chatgpt2api/source/web/bun.lock +1501 -1501
  94. package/vendor/chatgpt2api/source/web/components.json +24 -24
  95. package/vendor/chatgpt2api/source/web/eslint.config.mjs +17 -17
  96. package/vendor/chatgpt2api/source/web/next.config.ts +40 -40
  97. package/vendor/chatgpt2api/source/web/package.json +58 -58
  98. package/vendor/chatgpt2api/source/web/postcss.config.mjs +5 -5
  99. package/vendor/chatgpt2api/source/web/src/app/accounts/components/account-import-dialog.tsx +925 -925
  100. package/vendor/chatgpt2api/source/web/src/app/accounts/page.tsx +1307 -1307
  101. package/vendor/chatgpt2api/source/web/src/app/debug/components/chat-panel.tsx +224 -224
  102. package/vendor/chatgpt2api/source/web/src/app/debug/components/editable-file-panel.tsx +444 -444
  103. package/vendor/chatgpt2api/source/web/src/app/debug/components/ppt-panel.tsx +9 -9
  104. package/vendor/chatgpt2api/source/web/src/app/debug/components/psd-panel.tsx +9 -9
  105. package/vendor/chatgpt2api/source/web/src/app/debug/components/search-panel.tsx +172 -172
  106. package/vendor/chatgpt2api/source/web/src/app/debug/components/skill-panel.tsx +169 -169
  107. package/vendor/chatgpt2api/source/web/src/app/debug/components/types.ts +39 -39
  108. package/vendor/chatgpt2api/source/web/src/app/debug/page.tsx +59 -59
  109. package/vendor/chatgpt2api/source/web/src/app/globals.css +230 -230
  110. package/vendor/chatgpt2api/source/web/src/app/image/components/image-composer.tsx +542 -542
  111. package/vendor/chatgpt2api/source/web/src/app/image/components/image-results.tsx +554 -554
  112. package/vendor/chatgpt2api/source/web/src/app/image/components/image-sidebar.tsx +176 -176
  113. package/vendor/chatgpt2api/source/web/src/app/image/page.tsx +1799 -1799
  114. package/vendor/chatgpt2api/source/web/src/app/image-manager/page.tsx +732 -732
  115. package/vendor/chatgpt2api/source/web/src/app/layout.tsx +50 -50
  116. package/vendor/chatgpt2api/source/web/src/app/login/page.tsx +101 -101
  117. package/vendor/chatgpt2api/source/web/src/app/logs/page.tsx +356 -356
  118. package/vendor/chatgpt2api/source/web/src/app/page.tsx +30 -30
  119. package/vendor/chatgpt2api/source/web/src/app/settings/components/api-docs-card.tsx +341 -341
  120. package/vendor/chatgpt2api/source/web/src/app/settings/components/backup-settings-card.tsx +447 -447
  121. package/vendor/chatgpt2api/source/web/src/app/settings/components/base-url-card.tsx +71 -71
  122. package/vendor/chatgpt2api/source/web/src/app/settings/components/config-card.tsx +491 -491
  123. package/vendor/chatgpt2api/source/web/src/app/settings/components/cpa-pool-dialog.tsx +108 -108
  124. package/vendor/chatgpt2api/source/web/src/app/settings/components/cpa-pools-card.tsx +169 -169
  125. package/vendor/chatgpt2api/source/web/src/app/settings/components/import-browser-dialog.tsx +185 -185
  126. package/vendor/chatgpt2api/source/web/src/app/settings/components/proxy-runtime-card.tsx +379 -379
  127. package/vendor/chatgpt2api/source/web/src/app/settings/components/proxy-settings-card.tsx +127 -127
  128. package/vendor/chatgpt2api/source/web/src/app/settings/components/proxy-settings.tsx +200 -200
  129. package/vendor/chatgpt2api/source/web/src/app/settings/components/settings-header.tsx +12 -12
  130. package/vendor/chatgpt2api/source/web/src/app/settings/components/sub2api-connections.tsx +886 -886
  131. package/vendor/chatgpt2api/source/web/src/app/settings/components/third-party-apps-card.tsx +81 -81
  132. package/vendor/chatgpt2api/source/web/src/app/settings/components/user-keys-card.tsx +422 -422
  133. package/vendor/chatgpt2api/source/web/src/app/settings/page.tsx +135 -135
  134. package/vendor/chatgpt2api/source/web/src/app/settings/store.ts +1069 -1069
  135. package/vendor/chatgpt2api/source/web/src/components/date-range-filter.tsx +49 -49
  136. package/vendor/chatgpt2api/source/web/src/components/header-actions.tsx +24 -24
  137. package/vendor/chatgpt2api/source/web/src/components/image-lightbox.tsx +434 -434
  138. package/vendor/chatgpt2api/source/web/src/components/image-thumbnail.tsx +46 -46
  139. package/vendor/chatgpt2api/source/web/src/components/theme-script.tsx +18 -18
  140. package/vendor/chatgpt2api/source/web/src/components/theme-toggle.tsx +14 -14
  141. package/vendor/chatgpt2api/source/web/src/components/top-nav.tsx +263 -263
  142. package/vendor/chatgpt2api/source/web/src/components/ui/animated-theme-toggler.tsx +256 -256
  143. package/vendor/chatgpt2api/source/web/src/components/ui/badge.tsx +41 -41
  144. package/vendor/chatgpt2api/source/web/src/components/ui/button.tsx +59 -59
  145. package/vendor/chatgpt2api/source/web/src/components/ui/calendar.tsx +46 -46
  146. package/vendor/chatgpt2api/source/web/src/components/ui/card.tsx +61 -61
  147. package/vendor/chatgpt2api/source/web/src/components/ui/checkbox.tsx +27 -27
  148. package/vendor/chatgpt2api/source/web/src/components/ui/dia-text-reveal.tsx +267 -267
  149. package/vendor/chatgpt2api/source/web/src/components/ui/dialog.tsx +132 -132
  150. package/vendor/chatgpt2api/source/web/src/components/ui/field.tsx +13 -13
  151. package/vendor/chatgpt2api/source/web/src/components/ui/input.tsx +19 -19
  152. package/vendor/chatgpt2api/source/web/src/components/ui/label.tsx +24 -24
  153. package/vendor/chatgpt2api/source/web/src/components/ui/morphing-text.tsx +149 -149
  154. package/vendor/chatgpt2api/source/web/src/components/ui/popover.tsx +38 -38
  155. package/vendor/chatgpt2api/source/web/src/components/ui/select.tsx +175 -175
  156. package/vendor/chatgpt2api/source/web/src/components/ui/sheet.tsx +143 -143
  157. package/vendor/chatgpt2api/source/web/src/components/ui/table.tsx +29 -29
  158. package/vendor/chatgpt2api/source/web/src/components/ui/tabs.tsx +91 -91
  159. package/vendor/chatgpt2api/source/web/src/components/ui/text-3d-flip.tsx +269 -269
  160. package/vendor/chatgpt2api/source/web/src/components/ui/textarea.tsx +18 -18
  161. package/vendor/chatgpt2api/source/web/src/components/version-release-dialog.tsx +127 -127
  162. package/vendor/chatgpt2api/source/web/src/constants/common-env.ts +6 -6
  163. package/vendor/chatgpt2api/source/web/src/hooks/use-version-check.ts +85 -85
  164. package/vendor/chatgpt2api/source/web/src/lib/api.ts +926 -926
  165. package/vendor/chatgpt2api/source/web/src/lib/auth-session.ts +26 -26
  166. package/vendor/chatgpt2api/source/web/src/lib/release.ts +25 -25
  167. package/vendor/chatgpt2api/source/web/src/lib/request.ts +93 -93
  168. package/vendor/chatgpt2api/source/web/src/lib/use-auth-guard.ts +89 -89
  169. package/vendor/chatgpt2api/source/web/src/lib/utils.ts +6 -6
  170. package/vendor/chatgpt2api/source/web/src/store/auth.ts +112 -112
  171. package/vendor/chatgpt2api/source/web/src/store/editable-file-history.ts +33 -33
  172. package/vendor/chatgpt2api/source/web/src/store/image-conversations.ts +318 -318
  173. package/vendor/chatgpt2api/source/web/tsconfig.json +42 -42
@@ -1,202 +1,202 @@
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">
6
- <title>申请访问 · 手绘工坊号池工作台</title>
7
- <style>
8
- :root{
9
- --bg:#f5f3fb; --panel:#ffffff; --ink:#1f1b2e; --ink-2:#5b5573; --ink-3:#8b86a3;
10
- --line:#e8e4f5; --primary:#6a5ae0; --primary-2:#8b7cf6; --pink:#ff6b9a;
11
- --ok:#12b886; --err:#e03131; --chip:#f1eefe;
12
- }
13
- *{box-sizing:border-box}
14
- [hidden]{display:none!important}
15
- body{margin:0;min-height:100vh;color:var(--ink);
16
- font:14px/1.7 -apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;
17
- background:radial-gradient(1100px 620px at 12% -12%,#e6dfff 0%,transparent 62%),
18
- radial-gradient(900px 560px at 100% 0%,#ffe7f0 0%,transparent 58%),
19
- var(--bg);
20
- display:flex;align-items:center;justify-content:center;padding:24px}
21
- .card{width:100%;max-width:420px;background:var(--panel);border:1px solid var(--line);
22
- border-radius:20px;box-shadow:0 18px 60px rgba(80,60,160,.13);padding:30px 28px 24px}
23
- .brand{display:inline-flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.6px;
24
- color:var(--primary);background:var(--chip);border:1px solid #ddd6fb;border-radius:20px;
25
- padding:5px 12px;margin-bottom:18px}
26
- .brand i{width:7px;height:7px;border-radius:50%;background:var(--primary);display:block}
27
- h1{font-size:22px;margin:0 0 6px;letter-spacing:.5px}
28
- .lead{font-size:12.5px;color:var(--ink-2);margin:0 0 22px;line-height:1.8}
29
- .lead b{color:var(--ink);font-weight:600}
30
- .steps{display:flex;gap:6px;margin:0 0 20px}
31
- .steps span{flex:1;height:4px;border-radius:4px;background:var(--line)}
32
- .steps span.on{background:linear-gradient(90deg,var(--primary),var(--pink))}
33
- label{display:block;font-size:11.5px;color:var(--ink-2);margin:0 0 7px;font-weight:600}
34
- input{width:100%;border:1px solid var(--line);border-radius:11px;background:#fbfaff;
35
- padding:12px 13px;font:inherit;color:var(--ink);outline:none;transition:.15s}
36
- input:focus{border-color:var(--primary-2);background:#fff;box-shadow:0 0 0 3px rgba(139,124,246,.14)}
37
- input.code{font-size:22px;letter-spacing:9px;text-align:center;font-weight:600;
38
- font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
39
- .btn{width:100%;border:0;border-radius:11px;padding:12px 14px;font:inherit;font-weight:600;
40
- cursor:pointer;margin-top:14px;transition:.15s;background:#f1eefe;color:var(--primary)}
41
- .btn:hover{filter:brightness(.97)}
42
- .btn.primary{background:linear-gradient(135deg,var(--primary),var(--pink));color:#fff;
43
- box-shadow:0 8px 20px rgba(106,90,224,.26)}
44
- .btn.ghost{background:#fff;border:1px solid var(--line);color:var(--ink-2);font-weight:500}
45
- .btn:disabled{opacity:.55;cursor:not-allowed}
46
- .msg{margin-top:14px;font-size:12px;line-height:1.7;border-radius:10px;padding:0;min-height:0}
47
- .msg:not(:empty){padding:10px 12px;border:1px solid var(--line);background:#faf9ff;color:var(--ink-2)}
48
- .msg.err{border-color:#ffd6d6;background:#fff5f5;color:#c92a2a}
49
- .msg.ok{border-color:#c3f0dd;background:#f2fcf8;color:#087f5b}
50
- .notice{background:#f2fcf8;border:1px solid #c3f0dd;color:#087f5b;border-radius:11px;
51
- padding:11px 13px;font-size:12px;line-height:1.75;margin:0 0 18px}
52
- .foot{margin-top:22px;padding-top:16px;border-top:1px solid var(--line);
53
- display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--ink-3)}
54
- .foot a{color:var(--ink-3);text-decoration:none;cursor:pointer;border-bottom:1px dashed var(--line)}
55
- .foot a:hover{color:var(--primary)}
56
- .admin{margin-top:16px;padding:14px;border:1px solid var(--line);border-radius:12px;background:#fbfaff}
57
- .admin p{margin:0 0 10px;font-size:11.5px;color:var(--ink-2);line-height:1.7}
58
- .hint{font-size:11px;color:var(--ink-3);margin:12px 0 0;line-height:1.7}
59
- </style>
60
- </head>
61
- <body>
62
- <div class="card">
63
- <div class="brand"><i></i>手绘工坊 · 号池工作台</div>
64
- <h1>申请访问</h1>
65
- <p class="lead">工作台仅供受邀使用。填写你的邮箱点<b>申请访问</b>,管理员会把验证码回复到这个邮箱。收到后回到本页填入邮箱和验证码即可进入。</p>
66
- <div class="steps"><span id="s1" class="on"></span><span id="s2"></span></div>
67
-
68
- <div id="step1">
69
- <label for="email">申请邮箱</label>
70
- <input id="email" type="email" maxlength="254" autocomplete="email" spellcheck="false" placeholder="name@example.com">
71
- <button id="reqBtn" class="btn primary" type="button">申请访问</button>
72
- <p class="hint">请填能收信的邮箱,管理员会把验证码回复到这里。</p>
73
- </div>
74
-
75
- <div id="step2" hidden>
76
- <div class="notice" id="notice">申请已提交,验证码会回复到你填的邮箱。</div>
77
- <label for="email2">申请时用的邮箱</label>
78
- <input id="email2" type="email" maxlength="254" autocomplete="email" spellcheck="false">
79
- <label for="code" style="margin-top:14px">验证码</label>
80
- <input id="code" class="code" type="text" inputmode="numeric" autocomplete="one-time-code" placeholder="000000">
81
- <button id="verBtn" class="btn primary" type="button">进入工作台</button>
82
- <button id="backBtn" class="btn ghost" type="button">换一个邮箱重新申请</button>
83
- </div>
84
-
85
- <div id="msg" class="msg" role="status"></div>
86
-
87
- <div class="foot">
88
- <span>验证码 24 小时有效 · 一次性 · 与邮箱绑定</span>
89
- <a id="adminToggle" type="button">管理员入口</a>
90
- </div>
91
- <div id="adminBox" class="admin" hidden>
92
- <p>管理员可凭主口令直接进入,不需要申请验证码。主口令只保存在服务器上,请勿写进共享文档。</p>
93
- <label for="master">主口令</label>
94
- <input id="master" type="password" autocomplete="current-password" placeholder="输入主口令">
95
- <button id="masterBtn" class="btn" type="button">进入工作台</button>
96
- </div>
97
- </div>
98
-
99
- <script>
100
- (function(){
101
- var $ = function(id){ return document.getElementById(id); };
102
- var msg = $('msg');
103
- function say(t, cls){
104
- msg.textContent = t || '';
105
- msg.className = 'msg' + (cls ? ' ' + cls : '');
106
- }
107
- function busy(btn, on){
108
- if(on){
109
- if(!btn.dataset.label) btn.dataset.label = btn.textContent;
110
- btn.disabled = true;
111
- btn.textContent = '处理中…';
112
- }else{
113
- btn.disabled = false;
114
- btn.textContent = btn.dataset.label || btn.textContent;
115
- }
116
- }
117
- function post(url, data){
118
- return fetch(url, {method:'POST', headers:{'Content-Type':'application/json'},
119
- body:JSON.stringify(data)}).then(function(r){
120
- return r.json().catch(function(){ return {}; }).then(function(d){
121
- return {status:r.status, data:d};
122
- });
123
- });
124
- }
125
-
126
- function showStep(n){
127
- $('step1').hidden = (n !== 1);
128
- $('step2').hidden = (n !== 2);
129
- $('s2').className = (n === 2 ? 'on' : '');
130
- say('');
131
- }
132
-
133
- $('reqBtn').addEventListener('click', function(){
134
- var u = $('email').value.trim().toLowerCase();
135
- if(!u){ say('请先填申请邮箱', 'err'); return; }
136
- var badMail = !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(u) || u.indexOf('..') >= 0 || u.charAt(0) === '.';
137
- if(badMail){ say('请填有效的邮箱地址', 'err'); return; }
138
- var btn = this; busy(btn, true);
139
- post('/api/access/request', {email:u}).then(function(res){
140
- busy(btn, false);
141
- if(!res.data.ok){ say(res.data.msg || '提交失败,请稍后重试', 'err'); return; }
142
- sessionStorage.setItem('wb_access_email', u);
143
- $('email2').value = u;
144
- showStep(2);
145
- $('notice').textContent = res.data.reused
146
- ? '该邮箱已有一份待审核的申请,请联系管理员索取之前发出的验证码。'
147
- : '申请已提交,管理员会把验证码回复到这个邮箱,填入下方即可进入。';
148
- $('code').focus();
149
- }).catch(function(){ busy(btn, false); say('网络异常,请稍后重试', 'err'); });
150
- });
151
-
152
- $('verBtn').addEventListener('click', function(){
153
- var u = $('email2').value.trim().toLowerCase();
154
- var c = $('code').value.trim();
155
- if(!u){ say('请填申请时用的邮箱', 'err'); return; }
156
- if(!/^\d{6}$/.test(c)){ say('验证码是 6 位数字', 'err'); return; }
157
- var btn = this; busy(btn, true);
158
- post('/api/access/verify', {email:u, code:c}).then(function(res){
159
- busy(btn, false);
160
- if(!res.data.ok){ say(res.data.msg || '验证失败', 'err'); return; }
161
- sessionStorage.removeItem('wb_access_email');
162
- location.href = '/';
163
- }).catch(function(){ busy(btn, false); say('网络异常,请稍后重试', 'err'); });
164
- });
165
-
166
- $('backBtn').addEventListener('click', function(){
167
- sessionStorage.removeItem('wb_access_email');
168
- $('code').value = '';
169
- showStep(1);
170
- $('email').focus();
171
- });
172
-
173
- $('adminToggle').addEventListener('click', function(){
174
- $('adminBox').hidden = !$('adminBox').hidden;
175
- if(!$('adminBox').hidden) $('master').focus();
176
- });
177
-
178
- $('masterBtn').addEventListener('click', function(){
179
- var p = $('master').value;
180
- if(!p){ say('请输入主口令', 'err'); return; }
181
- var btn = this; busy(btn, true);
182
- post('/api/access/master', {password:p}).then(function(res){
183
- busy(btn, false);
184
- if(!res.data.ok){ say(res.data.msg || '验证失败', 'err'); return; }
185
- location.href = '/';
186
- }).catch(function(){ busy(btn, false); say('网络异常,请稍后重试', 'err'); });
187
- });
188
-
189
- $('email').addEventListener('keydown', function(e){ if(e.key === 'Enter') $('reqBtn').click(); });
190
- $('code').addEventListener('keydown', function(e){ if(e.key === 'Enter') $('verBtn').click(); });
191
- $('master').addEventListener('keydown', function(e){ if(e.key === 'Enter') $('masterBtn').click(); });
192
- $('code').addEventListener('input', function(){ this.value = this.value.replace(/\D/g,'').slice(0,6); });
193
-
194
- var saved = sessionStorage.getItem('wb_access_email');
195
- if(saved){ $('email').value = saved; $('email2').value = saved; showStep(2); $('code').focus(); }
196
- if(new URLSearchParams(location.search).get('expired') === '1'){
197
- say('登录状态已失效,请重新申请验证码', 'err');
198
- }
199
- })();
200
- </script>
201
- </body>
202
- </html>
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">
6
+ <title>申请访问 · 手绘工坊号池工作台</title>
7
+ <style>
8
+ :root{
9
+ --bg:#f5f3fb; --panel:#ffffff; --ink:#1f1b2e; --ink-2:#5b5573; --ink-3:#8b86a3;
10
+ --line:#e8e4f5; --primary:#6a5ae0; --primary-2:#8b7cf6; --pink:#ff6b9a;
11
+ --ok:#12b886; --err:#e03131; --chip:#f1eefe;
12
+ }
13
+ *{box-sizing:border-box}
14
+ [hidden]{display:none!important}
15
+ body{margin:0;min-height:100vh;color:var(--ink);
16
+ font:14px/1.7 -apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;
17
+ background:radial-gradient(1100px 620px at 12% -12%,#e6dfff 0%,transparent 62%),
18
+ radial-gradient(900px 560px at 100% 0%,#ffe7f0 0%,transparent 58%),
19
+ var(--bg);
20
+ display:flex;align-items:center;justify-content:center;padding:24px}
21
+ .card{width:100%;max-width:420px;background:var(--panel);border:1px solid var(--line);
22
+ border-radius:20px;box-shadow:0 18px 60px rgba(80,60,160,.13);padding:30px 28px 24px}
23
+ .brand{display:inline-flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.6px;
24
+ color:var(--primary);background:var(--chip);border:1px solid #ddd6fb;border-radius:20px;
25
+ padding:5px 12px;margin-bottom:18px}
26
+ .brand i{width:7px;height:7px;border-radius:50%;background:var(--primary);display:block}
27
+ h1{font-size:22px;margin:0 0 6px;letter-spacing:.5px}
28
+ .lead{font-size:12.5px;color:var(--ink-2);margin:0 0 22px;line-height:1.8}
29
+ .lead b{color:var(--ink);font-weight:600}
30
+ .steps{display:flex;gap:6px;margin:0 0 20px}
31
+ .steps span{flex:1;height:4px;border-radius:4px;background:var(--line)}
32
+ .steps span.on{background:linear-gradient(90deg,var(--primary),var(--pink))}
33
+ label{display:block;font-size:11.5px;color:var(--ink-2);margin:0 0 7px;font-weight:600}
34
+ input{width:100%;border:1px solid var(--line);border-radius:11px;background:#fbfaff;
35
+ padding:12px 13px;font:inherit;color:var(--ink);outline:none;transition:.15s}
36
+ input:focus{border-color:var(--primary-2);background:#fff;box-shadow:0 0 0 3px rgba(139,124,246,.14)}
37
+ input.code{font-size:22px;letter-spacing:9px;text-align:center;font-weight:600;
38
+ font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
39
+ .btn{width:100%;border:0;border-radius:11px;padding:12px 14px;font:inherit;font-weight:600;
40
+ cursor:pointer;margin-top:14px;transition:.15s;background:#f1eefe;color:var(--primary)}
41
+ .btn:hover{filter:brightness(.97)}
42
+ .btn.primary{background:linear-gradient(135deg,var(--primary),var(--pink));color:#fff;
43
+ box-shadow:0 8px 20px rgba(106,90,224,.26)}
44
+ .btn.ghost{background:#fff;border:1px solid var(--line);color:var(--ink-2);font-weight:500}
45
+ .btn:disabled{opacity:.55;cursor:not-allowed}
46
+ .msg{margin-top:14px;font-size:12px;line-height:1.7;border-radius:10px;padding:0;min-height:0}
47
+ .msg:not(:empty){padding:10px 12px;border:1px solid var(--line);background:#faf9ff;color:var(--ink-2)}
48
+ .msg.err{border-color:#ffd6d6;background:#fff5f5;color:#c92a2a}
49
+ .msg.ok{border-color:#c3f0dd;background:#f2fcf8;color:#087f5b}
50
+ .notice{background:#f2fcf8;border:1px solid #c3f0dd;color:#087f5b;border-radius:11px;
51
+ padding:11px 13px;font-size:12px;line-height:1.75;margin:0 0 18px}
52
+ .foot{margin-top:22px;padding-top:16px;border-top:1px solid var(--line);
53
+ display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--ink-3)}
54
+ .foot a{color:var(--ink-3);text-decoration:none;cursor:pointer;border-bottom:1px dashed var(--line)}
55
+ .foot a:hover{color:var(--primary)}
56
+ .admin{margin-top:16px;padding:14px;border:1px solid var(--line);border-radius:12px;background:#fbfaff}
57
+ .admin p{margin:0 0 10px;font-size:11.5px;color:var(--ink-2);line-height:1.7}
58
+ .hint{font-size:11px;color:var(--ink-3);margin:12px 0 0;line-height:1.7}
59
+ </style>
60
+ </head>
61
+ <body>
62
+ <div class="card">
63
+ <div class="brand"><i></i>手绘工坊 · 号池工作台</div>
64
+ <h1>申请访问</h1>
65
+ <p class="lead">工作台仅供受邀使用。填写你的邮箱点<b>申请访问</b>,管理员会把验证码回复到这个邮箱。收到后回到本页填入邮箱和验证码即可进入。</p>
66
+ <div class="steps"><span id="s1" class="on"></span><span id="s2"></span></div>
67
+
68
+ <div id="step1">
69
+ <label for="email">申请邮箱</label>
70
+ <input id="email" type="email" maxlength="254" autocomplete="email" spellcheck="false" placeholder="name@example.com">
71
+ <button id="reqBtn" class="btn primary" type="button">申请访问</button>
72
+ <p class="hint">请填能收信的邮箱,管理员会把验证码回复到这里。</p>
73
+ </div>
74
+
75
+ <div id="step2" hidden>
76
+ <div class="notice" id="notice">申请已提交,验证码会回复到你填的邮箱。</div>
77
+ <label for="email2">申请时用的邮箱</label>
78
+ <input id="email2" type="email" maxlength="254" autocomplete="email" spellcheck="false">
79
+ <label for="code" style="margin-top:14px">验证码</label>
80
+ <input id="code" class="code" type="text" inputmode="numeric" autocomplete="one-time-code" placeholder="000000">
81
+ <button id="verBtn" class="btn primary" type="button">进入工作台</button>
82
+ <button id="backBtn" class="btn ghost" type="button">换一个邮箱重新申请</button>
83
+ </div>
84
+
85
+ <div id="msg" class="msg" role="status"></div>
86
+
87
+ <div class="foot">
88
+ <span>验证码 24 小时有效 · 一次性 · 与邮箱绑定</span>
89
+ <a id="adminToggle" type="button">管理员入口</a>
90
+ </div>
91
+ <div id="adminBox" class="admin" hidden>
92
+ <p>管理员可凭主口令直接进入,不需要申请验证码。主口令只保存在服务器上,请勿写进共享文档。</p>
93
+ <label for="master">主口令</label>
94
+ <input id="master" type="password" autocomplete="current-password" placeholder="输入主口令">
95
+ <button id="masterBtn" class="btn" type="button">进入工作台</button>
96
+ </div>
97
+ </div>
98
+
99
+ <script>
100
+ (function(){
101
+ var $ = function(id){ return document.getElementById(id); };
102
+ var msg = $('msg');
103
+ function say(t, cls){
104
+ msg.textContent = t || '';
105
+ msg.className = 'msg' + (cls ? ' ' + cls : '');
106
+ }
107
+ function busy(btn, on){
108
+ if(on){
109
+ if(!btn.dataset.label) btn.dataset.label = btn.textContent;
110
+ btn.disabled = true;
111
+ btn.textContent = '处理中…';
112
+ }else{
113
+ btn.disabled = false;
114
+ btn.textContent = btn.dataset.label || btn.textContent;
115
+ }
116
+ }
117
+ function post(url, data){
118
+ return fetch(url, {method:'POST', headers:{'Content-Type':'application/json'},
119
+ body:JSON.stringify(data)}).then(function(r){
120
+ return r.json().catch(function(){ return {}; }).then(function(d){
121
+ return {status:r.status, data:d};
122
+ });
123
+ });
124
+ }
125
+
126
+ function showStep(n){
127
+ $('step1').hidden = (n !== 1);
128
+ $('step2').hidden = (n !== 2);
129
+ $('s2').className = (n === 2 ? 'on' : '');
130
+ say('');
131
+ }
132
+
133
+ $('reqBtn').addEventListener('click', function(){
134
+ var u = $('email').value.trim().toLowerCase();
135
+ if(!u){ say('请先填申请邮箱', 'err'); return; }
136
+ var badMail = !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(u) || u.indexOf('..') >= 0 || u.charAt(0) === '.';
137
+ if(badMail){ say('请填有效的邮箱地址', 'err'); return; }
138
+ var btn = this; busy(btn, true);
139
+ post('/api/access/request', {email:u}).then(function(res){
140
+ busy(btn, false);
141
+ if(!res.data.ok){ say(res.data.msg || '提交失败,请稍后重试', 'err'); return; }
142
+ sessionStorage.setItem('wb_access_email', u);
143
+ $('email2').value = u;
144
+ showStep(2);
145
+ $('notice').textContent = res.data.reused
146
+ ? '该邮箱已有一份待审核的申请,请联系管理员索取之前发出的验证码。'
147
+ : '申请已提交,管理员会把验证码回复到这个邮箱,填入下方即可进入。';
148
+ $('code').focus();
149
+ }).catch(function(){ busy(btn, false); say('网络异常,请稍后重试', 'err'); });
150
+ });
151
+
152
+ $('verBtn').addEventListener('click', function(){
153
+ var u = $('email2').value.trim().toLowerCase();
154
+ var c = $('code').value.trim();
155
+ if(!u){ say('请填申请时用的邮箱', 'err'); return; }
156
+ if(!/^\d{6}$/.test(c)){ say('验证码是 6 位数字', 'err'); return; }
157
+ var btn = this; busy(btn, true);
158
+ post('/api/access/verify', {email:u, code:c}).then(function(res){
159
+ busy(btn, false);
160
+ if(!res.data.ok){ say(res.data.msg || '验证失败', 'err'); return; }
161
+ sessionStorage.removeItem('wb_access_email');
162
+ location.href = '/';
163
+ }).catch(function(){ busy(btn, false); say('网络异常,请稍后重试', 'err'); });
164
+ });
165
+
166
+ $('backBtn').addEventListener('click', function(){
167
+ sessionStorage.removeItem('wb_access_email');
168
+ $('code').value = '';
169
+ showStep(1);
170
+ $('email').focus();
171
+ });
172
+
173
+ $('adminToggle').addEventListener('click', function(){
174
+ $('adminBox').hidden = !$('adminBox').hidden;
175
+ if(!$('adminBox').hidden) $('master').focus();
176
+ });
177
+
178
+ $('masterBtn').addEventListener('click', function(){
179
+ var p = $('master').value;
180
+ if(!p){ say('请输入主口令', 'err'); return; }
181
+ var btn = this; busy(btn, true);
182
+ post('/api/access/master', {password:p}).then(function(res){
183
+ busy(btn, false);
184
+ if(!res.data.ok){ say(res.data.msg || '验证失败', 'err'); return; }
185
+ location.href = '/';
186
+ }).catch(function(){ busy(btn, false); say('网络异常,请稍后重试', 'err'); });
187
+ });
188
+
189
+ $('email').addEventListener('keydown', function(e){ if(e.key === 'Enter') $('reqBtn').click(); });
190
+ $('code').addEventListener('keydown', function(e){ if(e.key === 'Enter') $('verBtn').click(); });
191
+ $('master').addEventListener('keydown', function(e){ if(e.key === 'Enter') $('masterBtn').click(); });
192
+ $('code').addEventListener('input', function(){ this.value = this.value.replace(/\D/g,'').slice(0,6); });
193
+
194
+ var saved = sessionStorage.getItem('wb_access_email');
195
+ if(saved){ $('email').value = saved; $('email2').value = saved; showStep(2); $('code').focus(); }
196
+ if(new URLSearchParams(location.search).get('expired') === '1'){
197
+ say('登录状态已失效,请重新申请验证码', 'err');
198
+ }
199
+ })();
200
+ </script>
201
+ </body>
202
+ </html>
@@ -612,6 +612,7 @@
612
612
  <div class="header-ad" id="headerAd" title="使用提示">
613
613
  <span class="ad-tag">提示</span>
614
614
  <div class="ad-view"><div class="ad-track" id="adTrack">
615
+ <div class="ad-item" id="adSamples" title="刚安装成功时,缩略图会在后台自动补齐,补完刷新就是真图">缩略图先同步,渐变是占位</div>
615
616
  <div class="ad-item">如果不知道怎么上手,可以试着直接点击「批量出图」。</div>
616
617
  <div class="ad-item">使用过程中有任何问题,可以多看看公众号详细介绍。</div>
617
618
  <div class="ad-item">如果发现其他问题,估计作者也搞不定,就直接问 AI 吧。</div>
@@ -4694,6 +4695,20 @@ setInterval(refreshPool, 10000);
4694
4695
  }, EASE);
4695
4696
  }
4696
4697
  }, HOLD);
4698
+
4699
+ /* 缩略图那条只改 hover 文案、不动文字和节点:条数一变,上面的计数就错位,
4700
+ 文字一长就被 440px 的框截成省略号。具体差多少张放在 title 里。 */
4701
+ var el = document.getElementById('adSamples');
4702
+ if(!el) return;
4703
+ fetch('/api/samples', {cache: 'no-store'})
4704
+ .then(function(r){ return r.ok ? r.json() : null; })
4705
+ .then(function(s){
4706
+ if(!s || !s.total) return;
4707
+ el.title = s.missing > 0
4708
+ ? '缩略图后台同步中:已 ' + s.have + ' / ' + s.total + ' 张,还差 ' + s.missing + ' 张,补完刷新即可。'
4709
+ : '缩略图已全部就位(共 ' + s.total + ' 张)。';
4710
+ })
4711
+ .catch(function(){}); // 状态读不到就保持默认说明,不影响轮播
4697
4712
  })();
4698
4713
  </script>
4699
4714
 
@@ -1,82 +1,82 @@
1
- # ============================================
2
- # ChatGPT2API 环境变量配置示例
3
- # ============================================
4
-
5
- # 认证密钥(必填)
6
- CHATGPT2API_AUTH_KEY=your_secret_key_here
7
-
8
- # 基础 URL(可选,用于生成图片 URL)
9
- # CHATGPT2API_BASE_URL=https://your-domain.com
10
-
11
- # ============================================
12
- # 存储后端配置
13
- # ============================================
14
-
15
- # 存储后端类型(可选值: json, sqlite, postgres, git)
16
- # 默认: json
17
- STORAGE_BACKEND=json
18
-
19
- # ============================================
20
- # 数据库配置(当 STORAGE_BACKEND=sqlite/postgres 时使用)
21
- # ============================================
22
-
23
- # PostgreSQL 示例
24
- # DATABASE_URL=postgresql://user:password@localhost:5432/chatgpt2api
25
-
26
- # Supabase 示例
27
- # DATABASE_URL=postgresql://postgres.xxx:password@aws-1-us-west-1.pooler.supabase.com:5432/postgres
28
-
29
- # SQLite 示例(不指定时自动使用 data/accounts.db)
30
- # DATABASE_URL=sqlite:///app/data/accounts.db
31
-
32
- # ============================================
33
- # Git 仓库配置(当 STORAGE_BACKEND=git 时使用)
34
- # ============================================
35
-
36
- # Git 仓库地址(必填)
37
- # GIT_REPO_URL=https://github.com/your-username/your-private-repo.git
38
-
39
- # Git 访问令牌(必填)
40
- # GitHub: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
41
- # GitLab: glpat-xxxxxxxxxxxxxxxxxxxx
42
- # GIT_TOKEN=your_git_token_here
43
-
44
- # Git 分支(可选,默认: main)
45
- # GIT_BRANCH=main
46
-
47
- # Git 仓库中的文件路径(可选,默认: accounts.json)
48
- # GIT_FILE_PATH=accounts.json
49
-
50
- # ============================================
51
- # WARP / FlareSolverr 稳定代理配置(可选)
52
- # ============================================
53
-
54
- # docker-compose.warp.yml 暴露到宿主机的端口
55
- # WARP_SOCKS_PORT=40000
56
- # PRIVOXY_PORT=40080
57
- # FLARESOLVERR_PORT=8191
58
-
59
- # FlareSolverr 日志与时区
60
- # FLARESOLVERR_LOG_LEVEL=info
61
- # TZ=Asia/Shanghai
62
-
63
- # Cloudflare WARP+ License Key(可选)
64
- # WARP_LICENSE_KEY=
65
-
66
- # 初始化 proxy_runtime 默认值
67
- # CHATGPT2API_PROXY_RUNTIME_ENABLED=true
68
- # CHATGPT2API_PROXY_RUNTIME_EGRESS_MODE=single_proxy
69
- # CHATGPT2API_PROXY_RUNTIME_PROXY_URL=http://privoxy:8118
70
- # CHATGPT2API_PROXY_RUNTIME_RESOURCE_PROXY_URL=
71
- # CHATGPT2API_PROXY_RUNTIME_SKIP_SSL_VERIFY=false
72
- # CHATGPT2API_PROXY_RUNTIME_RESET_STATUS_CODES=403
73
-
74
- # Cloudflare clearance 刷新配置
75
- # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_ENABLED=true
76
- # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_MODE=flaresolverr
77
- # CHATGPT2API_FLARESOLVERR_URL=http://flaresolverr:8191
78
- # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_TIMEOUT_SEC=60
79
- # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_REFRESH_INTERVAL=3600
80
- # CHATGPT2API_PROXY_RUNTIME_WARM_UP_ON_START=false
81
- # CHATGPT2API_PROXY_RUNTIME_BROWSER=chrome
82
- # CHATGPT2API_PROXY_RUNTIME_USER_AGENT=
1
+ # ============================================
2
+ # ChatGPT2API 环境变量配置示例
3
+ # ============================================
4
+
5
+ # 认证密钥(必填)
6
+ CHATGPT2API_AUTH_KEY=your_secret_key_here
7
+
8
+ # 基础 URL(可选,用于生成图片 URL)
9
+ # CHATGPT2API_BASE_URL=https://your-domain.com
10
+
11
+ # ============================================
12
+ # 存储后端配置
13
+ # ============================================
14
+
15
+ # 存储后端类型(可选值: json, sqlite, postgres, git)
16
+ # 默认: json
17
+ STORAGE_BACKEND=json
18
+
19
+ # ============================================
20
+ # 数据库配置(当 STORAGE_BACKEND=sqlite/postgres 时使用)
21
+ # ============================================
22
+
23
+ # PostgreSQL 示例
24
+ # DATABASE_URL=postgresql://user:password@localhost:5432/chatgpt2api
25
+
26
+ # Supabase 示例
27
+ # DATABASE_URL=postgresql://postgres.xxx:password@aws-1-us-west-1.pooler.supabase.com:5432/postgres
28
+
29
+ # SQLite 示例(不指定时自动使用 data/accounts.db)
30
+ # DATABASE_URL=sqlite:///app/data/accounts.db
31
+
32
+ # ============================================
33
+ # Git 仓库配置(当 STORAGE_BACKEND=git 时使用)
34
+ # ============================================
35
+
36
+ # Git 仓库地址(必填)
37
+ # GIT_REPO_URL=https://github.com/your-username/your-private-repo.git
38
+
39
+ # Git 访问令牌(必填)
40
+ # GitHub: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
41
+ # GitLab: glpat-xxxxxxxxxxxxxxxxxxxx
42
+ # GIT_TOKEN=your_git_token_here
43
+
44
+ # Git 分支(可选,默认: main)
45
+ # GIT_BRANCH=main
46
+
47
+ # Git 仓库中的文件路径(可选,默认: accounts.json)
48
+ # GIT_FILE_PATH=accounts.json
49
+
50
+ # ============================================
51
+ # WARP / FlareSolverr 稳定代理配置(可选)
52
+ # ============================================
53
+
54
+ # docker-compose.warp.yml 暴露到宿主机的端口
55
+ # WARP_SOCKS_PORT=40000
56
+ # PRIVOXY_PORT=40080
57
+ # FLARESOLVERR_PORT=8191
58
+
59
+ # FlareSolverr 日志与时区
60
+ # FLARESOLVERR_LOG_LEVEL=info
61
+ # TZ=Asia/Shanghai
62
+
63
+ # Cloudflare WARP+ License Key(可选)
64
+ # WARP_LICENSE_KEY=
65
+
66
+ # 初始化 proxy_runtime 默认值
67
+ # CHATGPT2API_PROXY_RUNTIME_ENABLED=true
68
+ # CHATGPT2API_PROXY_RUNTIME_EGRESS_MODE=single_proxy
69
+ # CHATGPT2API_PROXY_RUNTIME_PROXY_URL=http://privoxy:8118
70
+ # CHATGPT2API_PROXY_RUNTIME_RESOURCE_PROXY_URL=
71
+ # CHATGPT2API_PROXY_RUNTIME_SKIP_SSL_VERIFY=false
72
+ # CHATGPT2API_PROXY_RUNTIME_RESET_STATUS_CODES=403
73
+
74
+ # Cloudflare clearance 刷新配置
75
+ # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_ENABLED=true
76
+ # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_MODE=flaresolverr
77
+ # CHATGPT2API_FLARESOLVERR_URL=http://flaresolverr:8191
78
+ # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_TIMEOUT_SEC=60
79
+ # CHATGPT2API_PROXY_RUNTIME_CLEARANCE_REFRESH_INTERVAL=3600
80
+ # CHATGPT2API_PROXY_RUNTIME_WARM_UP_ON_START=false
81
+ # CHATGPT2API_PROXY_RUNTIME_BROWSER=chrome
82
+ # CHATGPT2API_PROXY_RUNTIME_USER_AGENT=
@@ -1 +1 @@
1
- 3.13
1
+ 3.13