ronghua commited on
Commit
b491539
·
1 Parent(s): 378b79e
.env.example ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ PORT=3000
2
+ ROUTE_PREFIX=
3
+ AUTH_TOKEN=
4
+ TOKEN_FILE=.token
5
+ TOKEN_LIST_FILE=.token-list
.gitignore ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /target
2
+ /get-token/target
3
+ /*.log
4
+ /*.env
5
+ /static/tokeninfo.min.html
6
+ node_modules
7
+ .DS_Store
8
+ /.vscode
9
+ /.cargo
10
+ /.token
11
+ /.token-list
12
+ /cursor-api
13
+ /cursor-api.exe
14
+ /release
Cargo.lock ADDED
@@ -0,0 +1,2086 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "addr2line"
7
+ version = "0.24.2"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
10
+ dependencies = [
11
+ "gimli",
12
+ ]
13
+
14
+ [[package]]
15
+ name = "adler2"
16
+ version = "2.0.0"
17
+ source = "registry+https://github.com/rust-lang/crates.io-index"
18
+ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
19
+
20
+ [[package]]
21
+ name = "aho-corasick"
22
+ version = "1.1.3"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
25
+ dependencies = [
26
+ "memchr",
27
+ ]
28
+
29
+ [[package]]
30
+ name = "android-tzdata"
31
+ version = "0.1.1"
32
+ source = "registry+https://github.com/rust-lang/crates.io-index"
33
+ checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
34
+
35
+ [[package]]
36
+ name = "android_system_properties"
37
+ version = "0.1.5"
38
+ source = "registry+https://github.com/rust-lang/crates.io-index"
39
+ checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
40
+ dependencies = [
41
+ "libc",
42
+ ]
43
+
44
+ [[package]]
45
+ name = "anyhow"
46
+ version = "1.0.95"
47
+ source = "registry+https://github.com/rust-lang/crates.io-index"
48
+ checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
49
+
50
+ [[package]]
51
+ name = "async-compression"
52
+ version = "0.4.18"
53
+ source = "registry+https://github.com/rust-lang/crates.io-index"
54
+ checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522"
55
+ dependencies = [
56
+ "flate2",
57
+ "futures-core",
58
+ "memchr",
59
+ "pin-project-lite",
60
+ "tokio",
61
+ ]
62
+
63
+ [[package]]
64
+ name = "async-trait"
65
+ version = "0.1.83"
66
+ source = "registry+https://github.com/rust-lang/crates.io-index"
67
+ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
68
+ dependencies = [
69
+ "proc-macro2",
70
+ "quote",
71
+ "syn",
72
+ ]
73
+
74
+ [[package]]
75
+ name = "atomic-waker"
76
+ version = "1.1.2"
77
+ source = "registry+https://github.com/rust-lang/crates.io-index"
78
+ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
79
+
80
+ [[package]]
81
+ name = "autocfg"
82
+ version = "1.4.0"
83
+ source = "registry+https://github.com/rust-lang/crates.io-index"
84
+ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
85
+
86
+ [[package]]
87
+ name = "axum"
88
+ version = "0.7.9"
89
+ source = "registry+https://github.com/rust-lang/crates.io-index"
90
+ checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
91
+ dependencies = [
92
+ "async-trait",
93
+ "axum-core",
94
+ "bytes",
95
+ "futures-util",
96
+ "http",
97
+ "http-body",
98
+ "http-body-util",
99
+ "hyper",
100
+ "hyper-util",
101
+ "itoa",
102
+ "matchit",
103
+ "memchr",
104
+ "mime",
105
+ "percent-encoding",
106
+ "pin-project-lite",
107
+ "rustversion",
108
+ "serde",
109
+ "serde_json",
110
+ "serde_path_to_error",
111
+ "serde_urlencoded",
112
+ "sync_wrapper",
113
+ "tokio",
114
+ "tower",
115
+ "tower-layer",
116
+ "tower-service",
117
+ "tracing",
118
+ ]
119
+
120
+ [[package]]
121
+ name = "axum-core"
122
+ version = "0.4.5"
123
+ source = "registry+https://github.com/rust-lang/crates.io-index"
124
+ checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
125
+ dependencies = [
126
+ "async-trait",
127
+ "bytes",
128
+ "futures-util",
129
+ "http",
130
+ "http-body",
131
+ "http-body-util",
132
+ "mime",
133
+ "pin-project-lite",
134
+ "rustversion",
135
+ "sync_wrapper",
136
+ "tower-layer",
137
+ "tower-service",
138
+ "tracing",
139
+ ]
140
+
141
+ [[package]]
142
+ name = "backtrace"
143
+ version = "0.3.74"
144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
145
+ checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
146
+ dependencies = [
147
+ "addr2line",
148
+ "cfg-if",
149
+ "libc",
150
+ "miniz_oxide",
151
+ "object",
152
+ "rustc-demangle",
153
+ "windows-targets",
154
+ ]
155
+
156
+ [[package]]
157
+ name = "base64"
158
+ version = "0.22.1"
159
+ source = "registry+https://github.com/rust-lang/crates.io-index"
160
+ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
161
+
162
+ [[package]]
163
+ name = "bitflags"
164
+ version = "2.6.0"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
167
+
168
+ [[package]]
169
+ name = "block-buffer"
170
+ version = "0.10.4"
171
+ source = "registry+https://github.com/rust-lang/crates.io-index"
172
+ checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
173
+ dependencies = [
174
+ "generic-array",
175
+ ]
176
+
177
+ [[package]]
178
+ name = "bumpalo"
179
+ version = "3.16.0"
180
+ source = "registry+https://github.com/rust-lang/crates.io-index"
181
+ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
182
+
183
+ [[package]]
184
+ name = "byteorder"
185
+ version = "1.5.0"
186
+ source = "registry+https://github.com/rust-lang/crates.io-index"
187
+ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
188
+
189
+ [[package]]
190
+ name = "bytes"
191
+ version = "1.9.0"
192
+ source = "registry+https://github.com/rust-lang/crates.io-index"
193
+ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
194
+
195
+ [[package]]
196
+ name = "cc"
197
+ version = "1.2.5"
198
+ source = "registry+https://github.com/rust-lang/crates.io-index"
199
+ checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
200
+ dependencies = [
201
+ "shlex",
202
+ ]
203
+
204
+ [[package]]
205
+ name = "cfg-if"
206
+ version = "1.0.0"
207
+ source = "registry+https://github.com/rust-lang/crates.io-index"
208
+ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
209
+
210
+ [[package]]
211
+ name = "chrono"
212
+ version = "0.4.39"
213
+ source = "registry+https://github.com/rust-lang/crates.io-index"
214
+ checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
215
+ dependencies = [
216
+ "android-tzdata",
217
+ "iana-time-zone",
218
+ "js-sys",
219
+ "num-traits",
220
+ "serde",
221
+ "wasm-bindgen",
222
+ "windows-targets",
223
+ ]
224
+
225
+ [[package]]
226
+ name = "core-foundation"
227
+ version = "0.9.4"
228
+ source = "registry+https://github.com/rust-lang/crates.io-index"
229
+ checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
230
+ dependencies = [
231
+ "core-foundation-sys",
232
+ "libc",
233
+ ]
234
+
235
+ [[package]]
236
+ name = "core-foundation-sys"
237
+ version = "0.8.7"
238
+ source = "registry+https://github.com/rust-lang/crates.io-index"
239
+ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
240
+
241
+ [[package]]
242
+ name = "cpufeatures"
243
+ version = "0.2.16"
244
+ source = "registry+https://github.com/rust-lang/crates.io-index"
245
+ checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
246
+ dependencies = [
247
+ "libc",
248
+ ]
249
+
250
+ [[package]]
251
+ name = "crc32fast"
252
+ version = "1.4.2"
253
+ source = "registry+https://github.com/rust-lang/crates.io-index"
254
+ checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
255
+ dependencies = [
256
+ "cfg-if",
257
+ ]
258
+
259
+ [[package]]
260
+ name = "crypto-common"
261
+ version = "0.1.6"
262
+ source = "registry+https://github.com/rust-lang/crates.io-index"
263
+ checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
264
+ dependencies = [
265
+ "generic-array",
266
+ "typenum",
267
+ ]
268
+
269
+ [[package]]
270
+ name = "cursor-api"
271
+ version = "0.1.0"
272
+ dependencies = [
273
+ "axum",
274
+ "base64",
275
+ "bytes",
276
+ "chrono",
277
+ "dotenvy",
278
+ "flate2",
279
+ "futures",
280
+ "hex",
281
+ "prost",
282
+ "prost-build",
283
+ "rand",
284
+ "regex",
285
+ "reqwest",
286
+ "serde",
287
+ "serde_json",
288
+ "sha2",
289
+ "tokio",
290
+ "tokio-stream",
291
+ "tower-http",
292
+ "uuid",
293
+ ]
294
+
295
+ [[package]]
296
+ name = "digest"
297
+ version = "0.10.7"
298
+ source = "registry+https://github.com/rust-lang/crates.io-index"
299
+ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
300
+ dependencies = [
301
+ "block-buffer",
302
+ "crypto-common",
303
+ ]
304
+
305
+ [[package]]
306
+ name = "displaydoc"
307
+ version = "0.2.5"
308
+ source = "registry+https://github.com/rust-lang/crates.io-index"
309
+ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
310
+ dependencies = [
311
+ "proc-macro2",
312
+ "quote",
313
+ "syn",
314
+ ]
315
+
316
+ [[package]]
317
+ name = "dotenvy"
318
+ version = "0.15.7"
319
+ source = "registry+https://github.com/rust-lang/crates.io-index"
320
+ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
321
+
322
+ [[package]]
323
+ name = "either"
324
+ version = "1.13.0"
325
+ source = "registry+https://github.com/rust-lang/crates.io-index"
326
+ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
327
+
328
+ [[package]]
329
+ name = "encoding_rs"
330
+ version = "0.8.35"
331
+ source = "registry+https://github.com/rust-lang/crates.io-index"
332
+ checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
333
+ dependencies = [
334
+ "cfg-if",
335
+ ]
336
+
337
+ [[package]]
338
+ name = "equivalent"
339
+ version = "1.0.1"
340
+ source = "registry+https://github.com/rust-lang/crates.io-index"
341
+ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
342
+
343
+ [[package]]
344
+ name = "errno"
345
+ version = "0.3.10"
346
+ source = "registry+https://github.com/rust-lang/crates.io-index"
347
+ checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
348
+ dependencies = [
349
+ "libc",
350
+ "windows-sys 0.59.0",
351
+ ]
352
+
353
+ [[package]]
354
+ name = "fastrand"
355
+ version = "2.3.0"
356
+ source = "registry+https://github.com/rust-lang/crates.io-index"
357
+ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
358
+
359
+ [[package]]
360
+ name = "fixedbitset"
361
+ version = "0.4.2"
362
+ source = "registry+https://github.com/rust-lang/crates.io-index"
363
+ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
364
+
365
+ [[package]]
366
+ name = "flate2"
367
+ version = "1.0.35"
368
+ source = "registry+https://github.com/rust-lang/crates.io-index"
369
+ checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
370
+ dependencies = [
371
+ "crc32fast",
372
+ "miniz_oxide",
373
+ ]
374
+
375
+ [[package]]
376
+ name = "fnv"
377
+ version = "1.0.7"
378
+ source = "registry+https://github.com/rust-lang/crates.io-index"
379
+ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
380
+
381
+ [[package]]
382
+ name = "foreign-types"
383
+ version = "0.3.2"
384
+ source = "registry+https://github.com/rust-lang/crates.io-index"
385
+ checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
386
+ dependencies = [
387
+ "foreign-types-shared",
388
+ ]
389
+
390
+ [[package]]
391
+ name = "foreign-types-shared"
392
+ version = "0.1.1"
393
+ source = "registry+https://github.com/rust-lang/crates.io-index"
394
+ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
395
+
396
+ [[package]]
397
+ name = "form_urlencoded"
398
+ version = "1.2.1"
399
+ source = "registry+https://github.com/rust-lang/crates.io-index"
400
+ checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
401
+ dependencies = [
402
+ "percent-encoding",
403
+ ]
404
+
405
+ [[package]]
406
+ name = "futures"
407
+ version = "0.3.31"
408
+ source = "registry+https://github.com/rust-lang/crates.io-index"
409
+ checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
410
+ dependencies = [
411
+ "futures-channel",
412
+ "futures-core",
413
+ "futures-io",
414
+ "futures-sink",
415
+ "futures-task",
416
+ "futures-util",
417
+ ]
418
+
419
+ [[package]]
420
+ name = "futures-channel"
421
+ version = "0.3.31"
422
+ source = "registry+https://github.com/rust-lang/crates.io-index"
423
+ checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
424
+ dependencies = [
425
+ "futures-core",
426
+ "futures-sink",
427
+ ]
428
+
429
+ [[package]]
430
+ name = "futures-core"
431
+ version = "0.3.31"
432
+ source = "registry+https://github.com/rust-lang/crates.io-index"
433
+ checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
434
+
435
+ [[package]]
436
+ name = "futures-io"
437
+ version = "0.3.31"
438
+ source = "registry+https://github.com/rust-lang/crates.io-index"
439
+ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
440
+
441
+ [[package]]
442
+ name = "futures-macro"
443
+ version = "0.3.31"
444
+ source = "registry+https://github.com/rust-lang/crates.io-index"
445
+ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
446
+ dependencies = [
447
+ "proc-macro2",
448
+ "quote",
449
+ "syn",
450
+ ]
451
+
452
+ [[package]]
453
+ name = "futures-sink"
454
+ version = "0.3.31"
455
+ source = "registry+https://github.com/rust-lang/crates.io-index"
456
+ checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
457
+
458
+ [[package]]
459
+ name = "futures-task"
460
+ version = "0.3.31"
461
+ source = "registry+https://github.com/rust-lang/crates.io-index"
462
+ checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
463
+
464
+ [[package]]
465
+ name = "futures-util"
466
+ version = "0.3.31"
467
+ source = "registry+https://github.com/rust-lang/crates.io-index"
468
+ checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
469
+ dependencies = [
470
+ "futures-channel",
471
+ "futures-core",
472
+ "futures-io",
473
+ "futures-macro",
474
+ "futures-sink",
475
+ "futures-task",
476
+ "memchr",
477
+ "pin-project-lite",
478
+ "pin-utils",
479
+ "slab",
480
+ ]
481
+
482
+ [[package]]
483
+ name = "generic-array"
484
+ version = "0.14.7"
485
+ source = "registry+https://github.com/rust-lang/crates.io-index"
486
+ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
487
+ dependencies = [
488
+ "typenum",
489
+ "version_check",
490
+ ]
491
+
492
+ [[package]]
493
+ name = "getrandom"
494
+ version = "0.2.15"
495
+ source = "registry+https://github.com/rust-lang/crates.io-index"
496
+ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
497
+ dependencies = [
498
+ "cfg-if",
499
+ "libc",
500
+ "wasi",
501
+ ]
502
+
503
+ [[package]]
504
+ name = "gimli"
505
+ version = "0.31.1"
506
+ source = "registry+https://github.com/rust-lang/crates.io-index"
507
+ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
508
+
509
+ [[package]]
510
+ name = "h2"
511
+ version = "0.4.7"
512
+ source = "registry+https://github.com/rust-lang/crates.io-index"
513
+ checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e"
514
+ dependencies = [
515
+ "atomic-waker",
516
+ "bytes",
517
+ "fnv",
518
+ "futures-core",
519
+ "futures-sink",
520
+ "http",
521
+ "indexmap",
522
+ "slab",
523
+ "tokio",
524
+ "tokio-util",
525
+ "tracing",
526
+ ]
527
+
528
+ [[package]]
529
+ name = "hashbrown"
530
+ version = "0.15.2"
531
+ source = "registry+https://github.com/rust-lang/crates.io-index"
532
+ checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
533
+
534
+ [[package]]
535
+ name = "heck"
536
+ version = "0.5.0"
537
+ source = "registry+https://github.com/rust-lang/crates.io-index"
538
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
539
+
540
+ [[package]]
541
+ name = "hex"
542
+ version = "0.4.3"
543
+ source = "registry+https://github.com/rust-lang/crates.io-index"
544
+ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
545
+
546
+ [[package]]
547
+ name = "http"
548
+ version = "1.2.0"
549
+ source = "registry+https://github.com/rust-lang/crates.io-index"
550
+ checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
551
+ dependencies = [
552
+ "bytes",
553
+ "fnv",
554
+ "itoa",
555
+ ]
556
+
557
+ [[package]]
558
+ name = "http-body"
559
+ version = "1.0.1"
560
+ source = "registry+https://github.com/rust-lang/crates.io-index"
561
+ checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
562
+ dependencies = [
563
+ "bytes",
564
+ "http",
565
+ ]
566
+
567
+ [[package]]
568
+ name = "http-body-util"
569
+ version = "0.1.2"
570
+ source = "registry+https://github.com/rust-lang/crates.io-index"
571
+ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
572
+ dependencies = [
573
+ "bytes",
574
+ "futures-util",
575
+ "http",
576
+ "http-body",
577
+ "pin-project-lite",
578
+ ]
579
+
580
+ [[package]]
581
+ name = "httparse"
582
+ version = "1.9.5"
583
+ source = "registry+https://github.com/rust-lang/crates.io-index"
584
+ checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
585
+
586
+ [[package]]
587
+ name = "httpdate"
588
+ version = "1.0.3"
589
+ source = "registry+https://github.com/rust-lang/crates.io-index"
590
+ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
591
+
592
+ [[package]]
593
+ name = "hyper"
594
+ version = "1.5.2"
595
+ source = "registry+https://github.com/rust-lang/crates.io-index"
596
+ checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0"
597
+ dependencies = [
598
+ "bytes",
599
+ "futures-channel",
600
+ "futures-util",
601
+ "h2",
602
+ "http",
603
+ "http-body",
604
+ "httparse",
605
+ "httpdate",
606
+ "itoa",
607
+ "pin-project-lite",
608
+ "smallvec",
609
+ "tokio",
610
+ "want",
611
+ ]
612
+
613
+ [[package]]
614
+ name = "hyper-rustls"
615
+ version = "0.27.5"
616
+ source = "registry+https://github.com/rust-lang/crates.io-index"
617
+ checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
618
+ dependencies = [
619
+ "futures-util",
620
+ "http",
621
+ "hyper",
622
+ "hyper-util",
623
+ "rustls",
624
+ "rustls-pki-types",
625
+ "tokio",
626
+ "tokio-rustls",
627
+ "tower-service",
628
+ ]
629
+
630
+ [[package]]
631
+ name = "hyper-tls"
632
+ version = "0.6.0"
633
+ source = "registry+https://github.com/rust-lang/crates.io-index"
634
+ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
635
+ dependencies = [
636
+ "bytes",
637
+ "http-body-util",
638
+ "hyper",
639
+ "hyper-util",
640
+ "native-tls",
641
+ "tokio",
642
+ "tokio-native-tls",
643
+ "tower-service",
644
+ ]
645
+
646
+ [[package]]
647
+ name = "hyper-util"
648
+ version = "0.1.10"
649
+ source = "registry+https://github.com/rust-lang/crates.io-index"
650
+ checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
651
+ dependencies = [
652
+ "bytes",
653
+ "futures-channel",
654
+ "futures-util",
655
+ "http",
656
+ "http-body",
657
+ "hyper",
658
+ "pin-project-lite",
659
+ "socket2",
660
+ "tokio",
661
+ "tower-service",
662
+ "tracing",
663
+ ]
664
+
665
+ [[package]]
666
+ name = "iana-time-zone"
667
+ version = "0.1.61"
668
+ source = "registry+https://github.com/rust-lang/crates.io-index"
669
+ checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
670
+ dependencies = [
671
+ "android_system_properties",
672
+ "core-foundation-sys",
673
+ "iana-time-zone-haiku",
674
+ "js-sys",
675
+ "wasm-bindgen",
676
+ "windows-core",
677
+ ]
678
+
679
+ [[package]]
680
+ name = "iana-time-zone-haiku"
681
+ version = "0.1.2"
682
+ source = "registry+https://github.com/rust-lang/crates.io-index"
683
+ checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
684
+ dependencies = [
685
+ "cc",
686
+ ]
687
+
688
+ [[package]]
689
+ name = "icu_collections"
690
+ version = "1.5.0"
691
+ source = "registry+https://github.com/rust-lang/crates.io-index"
692
+ checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
693
+ dependencies = [
694
+ "displaydoc",
695
+ "yoke",
696
+ "zerofrom",
697
+ "zerovec",
698
+ ]
699
+
700
+ [[package]]
701
+ name = "icu_locid"
702
+ version = "1.5.0"
703
+ source = "registry+https://github.com/rust-lang/crates.io-index"
704
+ checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
705
+ dependencies = [
706
+ "displaydoc",
707
+ "litemap",
708
+ "tinystr",
709
+ "writeable",
710
+ "zerovec",
711
+ ]
712
+
713
+ [[package]]
714
+ name = "icu_locid_transform"
715
+ version = "1.5.0"
716
+ source = "registry+https://github.com/rust-lang/crates.io-index"
717
+ checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
718
+ dependencies = [
719
+ "displaydoc",
720
+ "icu_locid",
721
+ "icu_locid_transform_data",
722
+ "icu_provider",
723
+ "tinystr",
724
+ "zerovec",
725
+ ]
726
+
727
+ [[package]]
728
+ name = "icu_locid_transform_data"
729
+ version = "1.5.0"
730
+ source = "registry+https://github.com/rust-lang/crates.io-index"
731
+ checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
732
+
733
+ [[package]]
734
+ name = "icu_normalizer"
735
+ version = "1.5.0"
736
+ source = "registry+https://github.com/rust-lang/crates.io-index"
737
+ checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
738
+ dependencies = [
739
+ "displaydoc",
740
+ "icu_collections",
741
+ "icu_normalizer_data",
742
+ "icu_properties",
743
+ "icu_provider",
744
+ "smallvec",
745
+ "utf16_iter",
746
+ "utf8_iter",
747
+ "write16",
748
+ "zerovec",
749
+ ]
750
+
751
+ [[package]]
752
+ name = "icu_normalizer_data"
753
+ version = "1.5.0"
754
+ source = "registry+https://github.com/rust-lang/crates.io-index"
755
+ checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
756
+
757
+ [[package]]
758
+ name = "icu_properties"
759
+ version = "1.5.1"
760
+ source = "registry+https://github.com/rust-lang/crates.io-index"
761
+ checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
762
+ dependencies = [
763
+ "displaydoc",
764
+ "icu_collections",
765
+ "icu_locid_transform",
766
+ "icu_properties_data",
767
+ "icu_provider",
768
+ "tinystr",
769
+ "zerovec",
770
+ ]
771
+
772
+ [[package]]
773
+ name = "icu_properties_data"
774
+ version = "1.5.0"
775
+ source = "registry+https://github.com/rust-lang/crates.io-index"
776
+ checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
777
+
778
+ [[package]]
779
+ name = "icu_provider"
780
+ version = "1.5.0"
781
+ source = "registry+https://github.com/rust-lang/crates.io-index"
782
+ checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
783
+ dependencies = [
784
+ "displaydoc",
785
+ "icu_locid",
786
+ "icu_provider_macros",
787
+ "stable_deref_trait",
788
+ "tinystr",
789
+ "writeable",
790
+ "yoke",
791
+ "zerofrom",
792
+ "zerovec",
793
+ ]
794
+
795
+ [[package]]
796
+ name = "icu_provider_macros"
797
+ version = "1.5.0"
798
+ source = "registry+https://github.com/rust-lang/crates.io-index"
799
+ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
800
+ dependencies = [
801
+ "proc-macro2",
802
+ "quote",
803
+ "syn",
804
+ ]
805
+
806
+ [[package]]
807
+ name = "idna"
808
+ version = "1.0.3"
809
+ source = "registry+https://github.com/rust-lang/crates.io-index"
810
+ checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
811
+ dependencies = [
812
+ "idna_adapter",
813
+ "smallvec",
814
+ "utf8_iter",
815
+ ]
816
+
817
+ [[package]]
818
+ name = "idna_adapter"
819
+ version = "1.2.0"
820
+ source = "registry+https://github.com/rust-lang/crates.io-index"
821
+ checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
822
+ dependencies = [
823
+ "icu_normalizer",
824
+ "icu_properties",
825
+ ]
826
+
827
+ [[package]]
828
+ name = "indexmap"
829
+ version = "2.7.0"
830
+ source = "registry+https://github.com/rust-lang/crates.io-index"
831
+ checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
832
+ dependencies = [
833
+ "equivalent",
834
+ "hashbrown",
835
+ ]
836
+
837
+ [[package]]
838
+ name = "ipnet"
839
+ version = "2.10.1"
840
+ source = "registry+https://github.com/rust-lang/crates.io-index"
841
+ checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
842
+
843
+ [[package]]
844
+ name = "itertools"
845
+ version = "0.13.0"
846
+ source = "registry+https://github.com/rust-lang/crates.io-index"
847
+ checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
848
+ dependencies = [
849
+ "either",
850
+ ]
851
+
852
+ [[package]]
853
+ name = "itoa"
854
+ version = "1.0.14"
855
+ source = "registry+https://github.com/rust-lang/crates.io-index"
856
+ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
857
+
858
+ [[package]]
859
+ name = "js-sys"
860
+ version = "0.3.76"
861
+ source = "registry+https://github.com/rust-lang/crates.io-index"
862
+ checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
863
+ dependencies = [
864
+ "once_cell",
865
+ "wasm-bindgen",
866
+ ]
867
+
868
+ [[package]]
869
+ name = "libc"
870
+ version = "0.2.169"
871
+ source = "registry+https://github.com/rust-lang/crates.io-index"
872
+ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
873
+
874
+ [[package]]
875
+ name = "linux-raw-sys"
876
+ version = "0.4.14"
877
+ source = "registry+https://github.com/rust-lang/crates.io-index"
878
+ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
879
+
880
+ [[package]]
881
+ name = "litemap"
882
+ version = "0.7.4"
883
+ source = "registry+https://github.com/rust-lang/crates.io-index"
884
+ checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
885
+
886
+ [[package]]
887
+ name = "log"
888
+ version = "0.4.22"
889
+ source = "registry+https://github.com/rust-lang/crates.io-index"
890
+ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
891
+
892
+ [[package]]
893
+ name = "matchit"
894
+ version = "0.7.3"
895
+ source = "registry+https://github.com/rust-lang/crates.io-index"
896
+ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
897
+
898
+ [[package]]
899
+ name = "memchr"
900
+ version = "2.7.4"
901
+ source = "registry+https://github.com/rust-lang/crates.io-index"
902
+ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
903
+
904
+ [[package]]
905
+ name = "mime"
906
+ version = "0.3.17"
907
+ source = "registry+https://github.com/rust-lang/crates.io-index"
908
+ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
909
+
910
+ [[package]]
911
+ name = "miniz_oxide"
912
+ version = "0.8.2"
913
+ source = "registry+https://github.com/rust-lang/crates.io-index"
914
+ checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
915
+ dependencies = [
916
+ "adler2",
917
+ ]
918
+
919
+ [[package]]
920
+ name = "mio"
921
+ version = "1.0.3"
922
+ source = "registry+https://github.com/rust-lang/crates.io-index"
923
+ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
924
+ dependencies = [
925
+ "libc",
926
+ "wasi",
927
+ "windows-sys 0.52.0",
928
+ ]
929
+
930
+ [[package]]
931
+ name = "multimap"
932
+ version = "0.10.0"
933
+ source = "registry+https://github.com/rust-lang/crates.io-index"
934
+ checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
935
+
936
+ [[package]]
937
+ name = "native-tls"
938
+ version = "0.2.12"
939
+ source = "registry+https://github.com/rust-lang/crates.io-index"
940
+ checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
941
+ dependencies = [
942
+ "libc",
943
+ "log",
944
+ "openssl",
945
+ "openssl-probe",
946
+ "openssl-sys",
947
+ "schannel",
948
+ "security-framework",
949
+ "security-framework-sys",
950
+ "tempfile",
951
+ ]
952
+
953
+ [[package]]
954
+ name = "num-traits"
955
+ version = "0.2.19"
956
+ source = "registry+https://github.com/rust-lang/crates.io-index"
957
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
958
+ dependencies = [
959
+ "autocfg",
960
+ ]
961
+
962
+ [[package]]
963
+ name = "object"
964
+ version = "0.36.7"
965
+ source = "registry+https://github.com/rust-lang/crates.io-index"
966
+ checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
967
+ dependencies = [
968
+ "memchr",
969
+ ]
970
+
971
+ [[package]]
972
+ name = "once_cell"
973
+ version = "1.20.2"
974
+ source = "registry+https://github.com/rust-lang/crates.io-index"
975
+ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
976
+
977
+ [[package]]
978
+ name = "openssl"
979
+ version = "0.10.68"
980
+ source = "registry+https://github.com/rust-lang/crates.io-index"
981
+ checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
982
+ dependencies = [
983
+ "bitflags",
984
+ "cfg-if",
985
+ "foreign-types",
986
+ "libc",
987
+ "once_cell",
988
+ "openssl-macros",
989
+ "openssl-sys",
990
+ ]
991
+
992
+ [[package]]
993
+ name = "openssl-macros"
994
+ version = "0.1.1"
995
+ source = "registry+https://github.com/rust-lang/crates.io-index"
996
+ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
997
+ dependencies = [
998
+ "proc-macro2",
999
+ "quote",
1000
+ "syn",
1001
+ ]
1002
+
1003
+ [[package]]
1004
+ name = "openssl-probe"
1005
+ version = "0.1.5"
1006
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1007
+ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
1008
+
1009
+ [[package]]
1010
+ name = "openssl-sys"
1011
+ version = "0.9.104"
1012
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1013
+ checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
1014
+ dependencies = [
1015
+ "cc",
1016
+ "libc",
1017
+ "pkg-config",
1018
+ "vcpkg",
1019
+ ]
1020
+
1021
+ [[package]]
1022
+ name = "percent-encoding"
1023
+ version = "2.3.1"
1024
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1025
+ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
1026
+
1027
+ [[package]]
1028
+ name = "petgraph"
1029
+ version = "0.6.5"
1030
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1031
+ checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
1032
+ dependencies = [
1033
+ "fixedbitset",
1034
+ "indexmap",
1035
+ ]
1036
+
1037
+ [[package]]
1038
+ name = "pin-project-lite"
1039
+ version = "0.2.15"
1040
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1041
+ checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
1042
+
1043
+ [[package]]
1044
+ name = "pin-utils"
1045
+ version = "0.1.0"
1046
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1047
+ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1048
+
1049
+ [[package]]
1050
+ name = "pkg-config"
1051
+ version = "0.3.31"
1052
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1053
+ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
1054
+
1055
+ [[package]]
1056
+ name = "ppv-lite86"
1057
+ version = "0.2.20"
1058
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1059
+ checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
1060
+ dependencies = [
1061
+ "zerocopy",
1062
+ ]
1063
+
1064
+ [[package]]
1065
+ name = "prettyplease"
1066
+ version = "0.2.25"
1067
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1068
+ checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
1069
+ dependencies = [
1070
+ "proc-macro2",
1071
+ "syn",
1072
+ ]
1073
+
1074
+ [[package]]
1075
+ name = "proc-macro2"
1076
+ version = "1.0.92"
1077
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1078
+ checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
1079
+ dependencies = [
1080
+ "unicode-ident",
1081
+ ]
1082
+
1083
+ [[package]]
1084
+ name = "prost"
1085
+ version = "0.13.4"
1086
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1087
+ checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec"
1088
+ dependencies = [
1089
+ "bytes",
1090
+ "prost-derive",
1091
+ ]
1092
+
1093
+ [[package]]
1094
+ name = "prost-build"
1095
+ version = "0.13.4"
1096
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1097
+ checksum = "d0f3e5beed80eb580c68e2c600937ac2c4eedabdfd5ef1e5b7ea4f3fba84497b"
1098
+ dependencies = [
1099
+ "heck",
1100
+ "itertools",
1101
+ "log",
1102
+ "multimap",
1103
+ "once_cell",
1104
+ "petgraph",
1105
+ "prettyplease",
1106
+ "prost",
1107
+ "prost-types",
1108
+ "regex",
1109
+ "syn",
1110
+ "tempfile",
1111
+ ]
1112
+
1113
+ [[package]]
1114
+ name = "prost-derive"
1115
+ version = "0.13.4"
1116
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1117
+ checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3"
1118
+ dependencies = [
1119
+ "anyhow",
1120
+ "itertools",
1121
+ "proc-macro2",
1122
+ "quote",
1123
+ "syn",
1124
+ ]
1125
+
1126
+ [[package]]
1127
+ name = "prost-types"
1128
+ version = "0.13.4"
1129
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1130
+ checksum = "cc2f1e56baa61e93533aebc21af4d2134b70f66275e0fcdf3cbe43d77ff7e8fc"
1131
+ dependencies = [
1132
+ "prost",
1133
+ ]
1134
+
1135
+ [[package]]
1136
+ name = "quote"
1137
+ version = "1.0.37"
1138
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1139
+ checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
1140
+ dependencies = [
1141
+ "proc-macro2",
1142
+ ]
1143
+
1144
+ [[package]]
1145
+ name = "rand"
1146
+ version = "0.8.5"
1147
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1148
+ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1149
+ dependencies = [
1150
+ "libc",
1151
+ "rand_chacha",
1152
+ "rand_core",
1153
+ ]
1154
+
1155
+ [[package]]
1156
+ name = "rand_chacha"
1157
+ version = "0.3.1"
1158
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1159
+ checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1160
+ dependencies = [
1161
+ "ppv-lite86",
1162
+ "rand_core",
1163
+ ]
1164
+
1165
+ [[package]]
1166
+ name = "rand_core"
1167
+ version = "0.6.4"
1168
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1169
+ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1170
+ dependencies = [
1171
+ "getrandom",
1172
+ ]
1173
+
1174
+ [[package]]
1175
+ name = "regex"
1176
+ version = "1.11.1"
1177
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1178
+ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
1179
+ dependencies = [
1180
+ "aho-corasick",
1181
+ "memchr",
1182
+ "regex-automata",
1183
+ "regex-syntax",
1184
+ ]
1185
+
1186
+ [[package]]
1187
+ name = "regex-automata"
1188
+ version = "0.4.9"
1189
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1190
+ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
1191
+ dependencies = [
1192
+ "aho-corasick",
1193
+ "memchr",
1194
+ "regex-syntax",
1195
+ ]
1196
+
1197
+ [[package]]
1198
+ name = "regex-syntax"
1199
+ version = "0.8.5"
1200
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1201
+ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
1202
+
1203
+ [[package]]
1204
+ name = "reqwest"
1205
+ version = "0.12.9"
1206
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1207
+ checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f"
1208
+ dependencies = [
1209
+ "async-compression",
1210
+ "base64",
1211
+ "bytes",
1212
+ "encoding_rs",
1213
+ "futures-core",
1214
+ "futures-util",
1215
+ "h2",
1216
+ "http",
1217
+ "http-body",
1218
+ "http-body-util",
1219
+ "hyper",
1220
+ "hyper-rustls",
1221
+ "hyper-tls",
1222
+ "hyper-util",
1223
+ "ipnet",
1224
+ "js-sys",
1225
+ "log",
1226
+ "mime",
1227
+ "native-tls",
1228
+ "once_cell",
1229
+ "percent-encoding",
1230
+ "pin-project-lite",
1231
+ "rustls-pemfile",
1232
+ "serde",
1233
+ "serde_json",
1234
+ "serde_urlencoded",
1235
+ "sync_wrapper",
1236
+ "system-configuration",
1237
+ "tokio",
1238
+ "tokio-native-tls",
1239
+ "tokio-util",
1240
+ "tower-service",
1241
+ "url",
1242
+ "wasm-bindgen",
1243
+ "wasm-bindgen-futures",
1244
+ "wasm-streams",
1245
+ "web-sys",
1246
+ "windows-registry",
1247
+ ]
1248
+
1249
+ [[package]]
1250
+ name = "ring"
1251
+ version = "0.17.8"
1252
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1253
+ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
1254
+ dependencies = [
1255
+ "cc",
1256
+ "cfg-if",
1257
+ "getrandom",
1258
+ "libc",
1259
+ "spin",
1260
+ "untrusted",
1261
+ "windows-sys 0.52.0",
1262
+ ]
1263
+
1264
+ [[package]]
1265
+ name = "rustc-demangle"
1266
+ version = "0.1.24"
1267
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1268
+ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
1269
+
1270
+ [[package]]
1271
+ name = "rustix"
1272
+ version = "0.38.42"
1273
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1274
+ checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
1275
+ dependencies = [
1276
+ "bitflags",
1277
+ "errno",
1278
+ "libc",
1279
+ "linux-raw-sys",
1280
+ "windows-sys 0.59.0",
1281
+ ]
1282
+
1283
+ [[package]]
1284
+ name = "rustls"
1285
+ version = "0.23.20"
1286
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1287
+ checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b"
1288
+ dependencies = [
1289
+ "once_cell",
1290
+ "rustls-pki-types",
1291
+ "rustls-webpki",
1292
+ "subtle",
1293
+ "zeroize",
1294
+ ]
1295
+
1296
+ [[package]]
1297
+ name = "rustls-pemfile"
1298
+ version = "2.2.0"
1299
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1300
+ checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
1301
+ dependencies = [
1302
+ "rustls-pki-types",
1303
+ ]
1304
+
1305
+ [[package]]
1306
+ name = "rustls-pki-types"
1307
+ version = "1.10.1"
1308
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1309
+ checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37"
1310
+
1311
+ [[package]]
1312
+ name = "rustls-webpki"
1313
+ version = "0.102.8"
1314
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1315
+ checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
1316
+ dependencies = [
1317
+ "ring",
1318
+ "rustls-pki-types",
1319
+ "untrusted",
1320
+ ]
1321
+
1322
+ [[package]]
1323
+ name = "rustversion"
1324
+ version = "1.0.18"
1325
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1326
+ checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
1327
+
1328
+ [[package]]
1329
+ name = "ryu"
1330
+ version = "1.0.18"
1331
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1332
+ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
1333
+
1334
+ [[package]]
1335
+ name = "schannel"
1336
+ version = "0.1.27"
1337
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1338
+ checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
1339
+ dependencies = [
1340
+ "windows-sys 0.59.0",
1341
+ ]
1342
+
1343
+ [[package]]
1344
+ name = "security-framework"
1345
+ version = "2.11.1"
1346
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1347
+ checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
1348
+ dependencies = [
1349
+ "bitflags",
1350
+ "core-foundation",
1351
+ "core-foundation-sys",
1352
+ "libc",
1353
+ "security-framework-sys",
1354
+ ]
1355
+
1356
+ [[package]]
1357
+ name = "security-framework-sys"
1358
+ version = "2.13.0"
1359
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1360
+ checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5"
1361
+ dependencies = [
1362
+ "core-foundation-sys",
1363
+ "libc",
1364
+ ]
1365
+
1366
+ [[package]]
1367
+ name = "serde"
1368
+ version = "1.0.216"
1369
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1370
+ checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
1371
+ dependencies = [
1372
+ "serde_derive",
1373
+ ]
1374
+
1375
+ [[package]]
1376
+ name = "serde_derive"
1377
+ version = "1.0.216"
1378
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1379
+ checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
1380
+ dependencies = [
1381
+ "proc-macro2",
1382
+ "quote",
1383
+ "syn",
1384
+ ]
1385
+
1386
+ [[package]]
1387
+ name = "serde_json"
1388
+ version = "1.0.134"
1389
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1390
+ checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
1391
+ dependencies = [
1392
+ "itoa",
1393
+ "memchr",
1394
+ "ryu",
1395
+ "serde",
1396
+ ]
1397
+
1398
+ [[package]]
1399
+ name = "serde_path_to_error"
1400
+ version = "0.1.16"
1401
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1402
+ checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6"
1403
+ dependencies = [
1404
+ "itoa",
1405
+ "serde",
1406
+ ]
1407
+
1408
+ [[package]]
1409
+ name = "serde_urlencoded"
1410
+ version = "0.7.1"
1411
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1412
+ checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
1413
+ dependencies = [
1414
+ "form_urlencoded",
1415
+ "itoa",
1416
+ "ryu",
1417
+ "serde",
1418
+ ]
1419
+
1420
+ [[package]]
1421
+ name = "sha2"
1422
+ version = "0.10.8"
1423
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1424
+ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
1425
+ dependencies = [
1426
+ "cfg-if",
1427
+ "cpufeatures",
1428
+ "digest",
1429
+ ]
1430
+
1431
+ [[package]]
1432
+ name = "shlex"
1433
+ version = "1.3.0"
1434
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1435
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1436
+
1437
+ [[package]]
1438
+ name = "slab"
1439
+ version = "0.4.9"
1440
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1441
+ checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
1442
+ dependencies = [
1443
+ "autocfg",
1444
+ ]
1445
+
1446
+ [[package]]
1447
+ name = "smallvec"
1448
+ version = "1.13.2"
1449
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1450
+ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
1451
+
1452
+ [[package]]
1453
+ name = "socket2"
1454
+ version = "0.5.8"
1455
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1456
+ checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
1457
+ dependencies = [
1458
+ "libc",
1459
+ "windows-sys 0.52.0",
1460
+ ]
1461
+
1462
+ [[package]]
1463
+ name = "spin"
1464
+ version = "0.9.8"
1465
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1466
+ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
1467
+
1468
+ [[package]]
1469
+ name = "stable_deref_trait"
1470
+ version = "1.2.0"
1471
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1472
+ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1473
+
1474
+ [[package]]
1475
+ name = "subtle"
1476
+ version = "2.6.1"
1477
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1478
+ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
1479
+
1480
+ [[package]]
1481
+ name = "syn"
1482
+ version = "2.0.91"
1483
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1484
+ checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035"
1485
+ dependencies = [
1486
+ "proc-macro2",
1487
+ "quote",
1488
+ "unicode-ident",
1489
+ ]
1490
+
1491
+ [[package]]
1492
+ name = "sync_wrapper"
1493
+ version = "1.0.2"
1494
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1495
+ checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
1496
+ dependencies = [
1497
+ "futures-core",
1498
+ ]
1499
+
1500
+ [[package]]
1501
+ name = "synstructure"
1502
+ version = "0.13.1"
1503
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1504
+ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
1505
+ dependencies = [
1506
+ "proc-macro2",
1507
+ "quote",
1508
+ "syn",
1509
+ ]
1510
+
1511
+ [[package]]
1512
+ name = "system-configuration"
1513
+ version = "0.6.1"
1514
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1515
+ checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
1516
+ dependencies = [
1517
+ "bitflags",
1518
+ "core-foundation",
1519
+ "system-configuration-sys",
1520
+ ]
1521
+
1522
+ [[package]]
1523
+ name = "system-configuration-sys"
1524
+ version = "0.6.0"
1525
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1526
+ checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
1527
+ dependencies = [
1528
+ "core-foundation-sys",
1529
+ "libc",
1530
+ ]
1531
+
1532
+ [[package]]
1533
+ name = "tempfile"
1534
+ version = "3.14.0"
1535
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1536
+ checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
1537
+ dependencies = [
1538
+ "cfg-if",
1539
+ "fastrand",
1540
+ "once_cell",
1541
+ "rustix",
1542
+ "windows-sys 0.59.0",
1543
+ ]
1544
+
1545
+ [[package]]
1546
+ name = "tinystr"
1547
+ version = "0.7.6"
1548
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1549
+ checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
1550
+ dependencies = [
1551
+ "displaydoc",
1552
+ "zerovec",
1553
+ ]
1554
+
1555
+ [[package]]
1556
+ name = "tokio"
1557
+ version = "1.42.0"
1558
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1559
+ checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
1560
+ dependencies = [
1561
+ "backtrace",
1562
+ "bytes",
1563
+ "libc",
1564
+ "mio",
1565
+ "pin-project-lite",
1566
+ "socket2",
1567
+ "tokio-macros",
1568
+ "windows-sys 0.52.0",
1569
+ ]
1570
+
1571
+ [[package]]
1572
+ name = "tokio-macros"
1573
+ version = "2.4.0"
1574
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1575
+ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
1576
+ dependencies = [
1577
+ "proc-macro2",
1578
+ "quote",
1579
+ "syn",
1580
+ ]
1581
+
1582
+ [[package]]
1583
+ name = "tokio-native-tls"
1584
+ version = "0.3.1"
1585
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1586
+ checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
1587
+ dependencies = [
1588
+ "native-tls",
1589
+ "tokio",
1590
+ ]
1591
+
1592
+ [[package]]
1593
+ name = "tokio-rustls"
1594
+ version = "0.26.1"
1595
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1596
+ checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
1597
+ dependencies = [
1598
+ "rustls",
1599
+ "tokio",
1600
+ ]
1601
+
1602
+ [[package]]
1603
+ name = "tokio-stream"
1604
+ version = "0.1.17"
1605
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1606
+ checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
1607
+ dependencies = [
1608
+ "futures-core",
1609
+ "pin-project-lite",
1610
+ "tokio",
1611
+ ]
1612
+
1613
+ [[package]]
1614
+ name = "tokio-util"
1615
+ version = "0.7.13"
1616
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1617
+ checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
1618
+ dependencies = [
1619
+ "bytes",
1620
+ "futures-core",
1621
+ "futures-sink",
1622
+ "pin-project-lite",
1623
+ "tokio",
1624
+ ]
1625
+
1626
+ [[package]]
1627
+ name = "tower"
1628
+ version = "0.5.2"
1629
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1630
+ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
1631
+ dependencies = [
1632
+ "futures-core",
1633
+ "futures-util",
1634
+ "pin-project-lite",
1635
+ "sync_wrapper",
1636
+ "tokio",
1637
+ "tower-layer",
1638
+ "tower-service",
1639
+ "tracing",
1640
+ ]
1641
+
1642
+ [[package]]
1643
+ name = "tower-http"
1644
+ version = "0.6.2"
1645
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1646
+ checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697"
1647
+ dependencies = [
1648
+ "bitflags",
1649
+ "bytes",
1650
+ "http",
1651
+ "pin-project-lite",
1652
+ "tower-layer",
1653
+ "tower-service",
1654
+ ]
1655
+
1656
+ [[package]]
1657
+ name = "tower-layer"
1658
+ version = "0.3.3"
1659
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1660
+ checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
1661
+
1662
+ [[package]]
1663
+ name = "tower-service"
1664
+ version = "0.3.3"
1665
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1666
+ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
1667
+
1668
+ [[package]]
1669
+ name = "tracing"
1670
+ version = "0.1.41"
1671
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1672
+ checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
1673
+ dependencies = [
1674
+ "log",
1675
+ "pin-project-lite",
1676
+ "tracing-core",
1677
+ ]
1678
+
1679
+ [[package]]
1680
+ name = "tracing-core"
1681
+ version = "0.1.33"
1682
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1683
+ checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
1684
+ dependencies = [
1685
+ "once_cell",
1686
+ ]
1687
+
1688
+ [[package]]
1689
+ name = "try-lock"
1690
+ version = "0.2.5"
1691
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1692
+ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
1693
+
1694
+ [[package]]
1695
+ name = "typenum"
1696
+ version = "1.17.0"
1697
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1698
+ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
1699
+
1700
+ [[package]]
1701
+ name = "unicode-ident"
1702
+ version = "1.0.14"
1703
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1704
+ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
1705
+
1706
+ [[package]]
1707
+ name = "untrusted"
1708
+ version = "0.9.0"
1709
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1710
+ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
1711
+
1712
+ [[package]]
1713
+ name = "url"
1714
+ version = "2.5.4"
1715
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1716
+ checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
1717
+ dependencies = [
1718
+ "form_urlencoded",
1719
+ "idna",
1720
+ "percent-encoding",
1721
+ ]
1722
+
1723
+ [[package]]
1724
+ name = "utf16_iter"
1725
+ version = "1.0.5"
1726
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1727
+ checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
1728
+
1729
+ [[package]]
1730
+ name = "utf8_iter"
1731
+ version = "1.0.4"
1732
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1733
+ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
1734
+
1735
+ [[package]]
1736
+ name = "uuid"
1737
+ version = "1.11.0"
1738
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1739
+ checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
1740
+ dependencies = [
1741
+ "getrandom",
1742
+ ]
1743
+
1744
+ [[package]]
1745
+ name = "vcpkg"
1746
+ version = "0.2.15"
1747
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1748
+ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
1749
+
1750
+ [[package]]
1751
+ name = "version_check"
1752
+ version = "0.9.5"
1753
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1754
+ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
1755
+
1756
+ [[package]]
1757
+ name = "want"
1758
+ version = "0.3.1"
1759
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1760
+ checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
1761
+ dependencies = [
1762
+ "try-lock",
1763
+ ]
1764
+
1765
+ [[package]]
1766
+ name = "wasi"
1767
+ version = "0.11.0+wasi-snapshot-preview1"
1768
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1769
+ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
1770
+
1771
+ [[package]]
1772
+ name = "wasm-bindgen"
1773
+ version = "0.2.99"
1774
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1775
+ checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
1776
+ dependencies = [
1777
+ "cfg-if",
1778
+ "once_cell",
1779
+ "wasm-bindgen-macro",
1780
+ ]
1781
+
1782
+ [[package]]
1783
+ name = "wasm-bindgen-backend"
1784
+ version = "0.2.99"
1785
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1786
+ checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
1787
+ dependencies = [
1788
+ "bumpalo",
1789
+ "log",
1790
+ "proc-macro2",
1791
+ "quote",
1792
+ "syn",
1793
+ "wasm-bindgen-shared",
1794
+ ]
1795
+
1796
+ [[package]]
1797
+ name = "wasm-bindgen-futures"
1798
+ version = "0.4.49"
1799
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1800
+ checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2"
1801
+ dependencies = [
1802
+ "cfg-if",
1803
+ "js-sys",
1804
+ "once_cell",
1805
+ "wasm-bindgen",
1806
+ "web-sys",
1807
+ ]
1808
+
1809
+ [[package]]
1810
+ name = "wasm-bindgen-macro"
1811
+ version = "0.2.99"
1812
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1813
+ checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
1814
+ dependencies = [
1815
+ "quote",
1816
+ "wasm-bindgen-macro-support",
1817
+ ]
1818
+
1819
+ [[package]]
1820
+ name = "wasm-bindgen-macro-support"
1821
+ version = "0.2.99"
1822
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1823
+ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
1824
+ dependencies = [
1825
+ "proc-macro2",
1826
+ "quote",
1827
+ "syn",
1828
+ "wasm-bindgen-backend",
1829
+ "wasm-bindgen-shared",
1830
+ ]
1831
+
1832
+ [[package]]
1833
+ name = "wasm-bindgen-shared"
1834
+ version = "0.2.99"
1835
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1836
+ checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
1837
+
1838
+ [[package]]
1839
+ name = "wasm-streams"
1840
+ version = "0.4.2"
1841
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1842
+ checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
1843
+ dependencies = [
1844
+ "futures-util",
1845
+ "js-sys",
1846
+ "wasm-bindgen",
1847
+ "wasm-bindgen-futures",
1848
+ "web-sys",
1849
+ ]
1850
+
1851
+ [[package]]
1852
+ name = "web-sys"
1853
+ version = "0.3.76"
1854
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1855
+ checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc"
1856
+ dependencies = [
1857
+ "js-sys",
1858
+ "wasm-bindgen",
1859
+ ]
1860
+
1861
+ [[package]]
1862
+ name = "windows-core"
1863
+ version = "0.52.0"
1864
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1865
+ checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
1866
+ dependencies = [
1867
+ "windows-targets",
1868
+ ]
1869
+
1870
+ [[package]]
1871
+ name = "windows-registry"
1872
+ version = "0.2.0"
1873
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1874
+ checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
1875
+ dependencies = [
1876
+ "windows-result",
1877
+ "windows-strings",
1878
+ "windows-targets",
1879
+ ]
1880
+
1881
+ [[package]]
1882
+ name = "windows-result"
1883
+ version = "0.2.0"
1884
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1885
+ checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
1886
+ dependencies = [
1887
+ "windows-targets",
1888
+ ]
1889
+
1890
+ [[package]]
1891
+ name = "windows-strings"
1892
+ version = "0.1.0"
1893
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1894
+ checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
1895
+ dependencies = [
1896
+ "windows-result",
1897
+ "windows-targets",
1898
+ ]
1899
+
1900
+ [[package]]
1901
+ name = "windows-sys"
1902
+ version = "0.52.0"
1903
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1904
+ checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
1905
+ dependencies = [
1906
+ "windows-targets",
1907
+ ]
1908
+
1909
+ [[package]]
1910
+ name = "windows-sys"
1911
+ version = "0.59.0"
1912
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1913
+ checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
1914
+ dependencies = [
1915
+ "windows-targets",
1916
+ ]
1917
+
1918
+ [[package]]
1919
+ name = "windows-targets"
1920
+ version = "0.52.6"
1921
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1922
+ checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
1923
+ dependencies = [
1924
+ "windows_aarch64_gnullvm",
1925
+ "windows_aarch64_msvc",
1926
+ "windows_i686_gnu",
1927
+ "windows_i686_gnullvm",
1928
+ "windows_i686_msvc",
1929
+ "windows_x86_64_gnu",
1930
+ "windows_x86_64_gnullvm",
1931
+ "windows_x86_64_msvc",
1932
+ ]
1933
+
1934
+ [[package]]
1935
+ name = "windows_aarch64_gnullvm"
1936
+ version = "0.52.6"
1937
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1938
+ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
1939
+
1940
+ [[package]]
1941
+ name = "windows_aarch64_msvc"
1942
+ version = "0.52.6"
1943
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1944
+ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
1945
+
1946
+ [[package]]
1947
+ name = "windows_i686_gnu"
1948
+ version = "0.52.6"
1949
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1950
+ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
1951
+
1952
+ [[package]]
1953
+ name = "windows_i686_gnullvm"
1954
+ version = "0.52.6"
1955
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1956
+ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
1957
+
1958
+ [[package]]
1959
+ name = "windows_i686_msvc"
1960
+ version = "0.52.6"
1961
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1962
+ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
1963
+
1964
+ [[package]]
1965
+ name = "windows_x86_64_gnu"
1966
+ version = "0.52.6"
1967
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1968
+ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
1969
+
1970
+ [[package]]
1971
+ name = "windows_x86_64_gnullvm"
1972
+ version = "0.52.6"
1973
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1974
+ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
1975
+
1976
+ [[package]]
1977
+ name = "windows_x86_64_msvc"
1978
+ version = "0.52.6"
1979
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1980
+ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
1981
+
1982
+ [[package]]
1983
+ name = "write16"
1984
+ version = "1.0.0"
1985
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1986
+ checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
1987
+
1988
+ [[package]]
1989
+ name = "writeable"
1990
+ version = "0.5.5"
1991
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1992
+ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
1993
+
1994
+ [[package]]
1995
+ name = "yoke"
1996
+ version = "0.7.5"
1997
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1998
+ checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
1999
+ dependencies = [
2000
+ "serde",
2001
+ "stable_deref_trait",
2002
+ "yoke-derive",
2003
+ "zerofrom",
2004
+ ]
2005
+
2006
+ [[package]]
2007
+ name = "yoke-derive"
2008
+ version = "0.7.5"
2009
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2010
+ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
2011
+ dependencies = [
2012
+ "proc-macro2",
2013
+ "quote",
2014
+ "syn",
2015
+ "synstructure",
2016
+ ]
2017
+
2018
+ [[package]]
2019
+ name = "zerocopy"
2020
+ version = "0.7.35"
2021
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2022
+ checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
2023
+ dependencies = [
2024
+ "byteorder",
2025
+ "zerocopy-derive",
2026
+ ]
2027
+
2028
+ [[package]]
2029
+ name = "zerocopy-derive"
2030
+ version = "0.7.35"
2031
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2032
+ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
2033
+ dependencies = [
2034
+ "proc-macro2",
2035
+ "quote",
2036
+ "syn",
2037
+ ]
2038
+
2039
+ [[package]]
2040
+ name = "zerofrom"
2041
+ version = "0.1.5"
2042
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2043
+ checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
2044
+ dependencies = [
2045
+ "zerofrom-derive",
2046
+ ]
2047
+
2048
+ [[package]]
2049
+ name = "zerofrom-derive"
2050
+ version = "0.1.5"
2051
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2052
+ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
2053
+ dependencies = [
2054
+ "proc-macro2",
2055
+ "quote",
2056
+ "syn",
2057
+ "synstructure",
2058
+ ]
2059
+
2060
+ [[package]]
2061
+ name = "zeroize"
2062
+ version = "1.8.1"
2063
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2064
+ checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
2065
+
2066
+ [[package]]
2067
+ name = "zerovec"
2068
+ version = "0.10.4"
2069
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2070
+ checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
2071
+ dependencies = [
2072
+ "yoke",
2073
+ "zerofrom",
2074
+ "zerovec-derive",
2075
+ ]
2076
+
2077
+ [[package]]
2078
+ name = "zerovec-derive"
2079
+ version = "0.10.3"
2080
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2081
+ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
2082
+ dependencies = [
2083
+ "proc-macro2",
2084
+ "quote",
2085
+ "syn",
2086
+ ]
Cargo.toml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "cursor-api"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ authors = ["wisdgod <nav@wisdgod.com>"]
6
+
7
+ [build-dependencies]
8
+ prost-build = "0.13.4"
9
+
10
+ [dependencies]
11
+ axum = { version = "0.7.9", features = ["json"] }
12
+ base64 = { version = "0.22.1", default-features = false, features = ["std"] }
13
+ bytes = "1.9.0"
14
+ chrono = { version = "0.4.39", features = ["serde"] }
15
+ dotenvy = "0.15.7"
16
+ flate2 = { version = "1.0.35", default-features = false, features = ["rust_backend"] }
17
+ futures = { version = "0.3.31", default-features = false, features = ["std"] }
18
+ hex = { version = "0.4.3", default-features = false, features = ["std"] }
19
+ prost = "0.13.4"
20
+ rand = { version = "0.8.5", default-features = false, features = ["std", "std_rng"] }
21
+ regex = { version = "1.11.1", default-features = false, features = ["std", "perf"] }
22
+ reqwest = { version = "0.12.9", features = ["json", "gzip", "stream"] }
23
+ serde = { version = "1.0.216", features = ["derive"] }
24
+ serde_json = { version = "1.0.134", features = ["std"] }
25
+ sha2 = { version = "0.10.8", default-features = false }
26
+ tokio = { version = "1.42.0", features = ["rt-multi-thread", "macros", "net", "sync", "time"] }
27
+ tokio-stream = { version = "0.1.17", features = ["time"] }
28
+ tower-http = { version = "0.6.2", features = ["cors"] }
29
+ uuid = { version = "1.11.0", features = ["v4"] }
30
+
31
+ # 优化设置
32
+ [profile.release]
33
+ lto = true # 启用链接时优化
34
+ codegen-units = 1 # 减少并行编译单元以提高优化
35
+ panic = 'abort' # 在 panic 时直接终止,减小二进制大小
36
+ strip = true # 移除调试符号
37
+ opt-level = 3 # 最高优化级别
38
+
39
+ # 构建脚本设置
40
+ [package.metadata.cross.target.x86_64-unknown-linux-gnu]
41
+ image = "ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main"
42
+
43
+ [package.metadata.cross.target.aarch64-unknown-linux-gnu]
44
+ image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main"
45
+
46
+ [package.metadata.cross.target.x86_64-apple-darwin]
47
+ image = "ghcr.io/cross-rs/x86_64-apple-darwin:main"
48
+
49
+ [package.metadata.cross.target.aarch64-apple-darwin]
50
+ image = "ghcr.io/cross-rs/aarch64-apple-darwin:main"
Dockerfile ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 构建阶段
2
+ FROM rust:1.83.0-slim-bookworm as builder
3
+
4
+ WORKDIR /app
5
+
6
+ # 安装构建依赖
7
+ RUN apt-get update && \
8
+ apt-get install -y --no-install-recommends \
9
+ build-essential \
10
+ protobuf-compiler \
11
+ pkg-config \
12
+ libssl-dev \
13
+ nodejs \
14
+ npm \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # 复制项目文件
18
+ COPY . .
19
+
20
+ # 构建
21
+ RUN rustup target add x86_64-unknown-linux-gnu && \
22
+ cargo build --target x86_64-unknown-linux-gnu --release && \
23
+ cp target/x86_64-unknown-linux-gnu/release/cursor-api /app/cursor-api
24
+
25
+ # 运行阶段
26
+ FROM debian:bookworm-slim
27
+
28
+ WORKDIR /app
29
+
30
+ ENV TZ=Asia/Shanghai
31
+
32
+ # 安装运行时依赖
33
+ RUN apt-get update && \
34
+ apt-get install -y --no-install-recommends \
35
+ ca-certificates \
36
+ tzdata \
37
+ && rm -rf /var/lib/apt/lists/*
38
+
39
+ # 复制构建产物
40
+ COPY --from=builder /app/cursor-api .
41
+
42
+ # 设置默认端口
43
+ ENV PORT=3000
44
+
45
+ # 动态暴露端口
46
+ EXPOSE ${PORT}
47
+
48
+ CMD ["./cursor-api"]
build.rs ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::io::Result;
2
+ use std::path::Path;
3
+ use std::process::Command;
4
+
5
+ fn check_and_install_deps() -> Result<()> {
6
+ let scripts_dir = Path::new("scripts");
7
+ let node_modules = scripts_dir.join("node_modules");
8
+
9
+ // 如果 node_modules 不存在,运行 npm install
10
+ if !node_modules.exists() {
11
+ println!("cargo:warning=Installing HTML minifier dependencies...");
12
+
13
+ let status = Command::new("npm")
14
+ .current_dir(scripts_dir)
15
+ .arg("install")
16
+ .status()?;
17
+
18
+ if !status.success() {
19
+ panic!("Failed to install npm dependencies");
20
+ }
21
+ println!("cargo:warning=Dependencies installed successfully");
22
+ }
23
+ Ok(())
24
+ }
25
+
26
+ fn minify_html() -> Result<()> {
27
+ println!("cargo:warning=Minifying HTML files...");
28
+
29
+ let status = Command::new("node")
30
+ .args(&["scripts/minify-html.js"])
31
+ .status()?;
32
+
33
+ if !status.success() {
34
+ panic!("HTML minification failed");
35
+ }
36
+ Ok(())
37
+ }
38
+
39
+ fn main() -> Result<()> {
40
+ // Proto 文件处理
41
+ println!("cargo:rerun-if-changed=src/message.proto");
42
+ let mut config = prost_build::Config::new();
43
+ config.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]");
44
+ config
45
+ .compile_protos(&["src/message.proto"], &["src/"])
46
+ .unwrap();
47
+
48
+ // HTML 文件处理
49
+ println!("cargo:rerun-if-changed=static/tokeninfo.html");
50
+ println!("cargo:rerun-if-changed=scripts/minify-html.js");
51
+ println!("cargo:rerun-if-changed=scripts/package.json");
52
+
53
+ // 检查并安装依赖
54
+ check_and_install_deps()?;
55
+
56
+ // 运行 HTML 压缩
57
+ minify_html()?;
58
+
59
+ Ok(())
60
+ }
get-token/Cargo.lock ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "ahash"
7
+ version = "0.8.11"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
10
+ dependencies = [
11
+ "cfg-if",
12
+ "once_cell",
13
+ "version_check",
14
+ "zerocopy",
15
+ ]
16
+
17
+ [[package]]
18
+ name = "bitflags"
19
+ version = "2.6.0"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
22
+
23
+ [[package]]
24
+ name = "cc"
25
+ version = "1.2.5"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
28
+ dependencies = [
29
+ "shlex",
30
+ ]
31
+
32
+ [[package]]
33
+ name = "cfg-if"
34
+ version = "1.0.0"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
37
+
38
+ [[package]]
39
+ name = "fallible-iterator"
40
+ version = "0.3.0"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
43
+
44
+ [[package]]
45
+ name = "fallible-streaming-iterator"
46
+ version = "0.1.9"
47
+ source = "registry+https://github.com/rust-lang/crates.io-index"
48
+ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
49
+
50
+ [[package]]
51
+ name = "get-token"
52
+ version = "0.1.0"
53
+ dependencies = [
54
+ "rusqlite",
55
+ ]
56
+
57
+ [[package]]
58
+ name = "hashbrown"
59
+ version = "0.14.5"
60
+ source = "registry+https://github.com/rust-lang/crates.io-index"
61
+ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
62
+ dependencies = [
63
+ "ahash",
64
+ ]
65
+
66
+ [[package]]
67
+ name = "hashlink"
68
+ version = "0.9.1"
69
+ source = "registry+https://github.com/rust-lang/crates.io-index"
70
+ checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
71
+ dependencies = [
72
+ "hashbrown",
73
+ ]
74
+
75
+ [[package]]
76
+ name = "libsqlite3-sys"
77
+ version = "0.30.1"
78
+ source = "registry+https://github.com/rust-lang/crates.io-index"
79
+ checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
80
+ dependencies = [
81
+ "cc",
82
+ "pkg-config",
83
+ "vcpkg",
84
+ ]
85
+
86
+ [[package]]
87
+ name = "once_cell"
88
+ version = "1.20.2"
89
+ source = "registry+https://github.com/rust-lang/crates.io-index"
90
+ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
91
+
92
+ [[package]]
93
+ name = "pkg-config"
94
+ version = "0.3.31"
95
+ source = "registry+https://github.com/rust-lang/crates.io-index"
96
+ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
97
+
98
+ [[package]]
99
+ name = "proc-macro2"
100
+ version = "1.0.92"
101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
102
+ checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
103
+ dependencies = [
104
+ "unicode-ident",
105
+ ]
106
+
107
+ [[package]]
108
+ name = "quote"
109
+ version = "1.0.37"
110
+ source = "registry+https://github.com/rust-lang/crates.io-index"
111
+ checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
112
+ dependencies = [
113
+ "proc-macro2",
114
+ ]
115
+
116
+ [[package]]
117
+ name = "rusqlite"
118
+ version = "0.32.1"
119
+ source = "registry+https://github.com/rust-lang/crates.io-index"
120
+ checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
121
+ dependencies = [
122
+ "bitflags",
123
+ "fallible-iterator",
124
+ "fallible-streaming-iterator",
125
+ "hashlink",
126
+ "libsqlite3-sys",
127
+ "smallvec",
128
+ ]
129
+
130
+ [[package]]
131
+ name = "shlex"
132
+ version = "1.3.0"
133
+ source = "registry+https://github.com/rust-lang/crates.io-index"
134
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
135
+
136
+ [[package]]
137
+ name = "smallvec"
138
+ version = "1.13.2"
139
+ source = "registry+https://github.com/rust-lang/crates.io-index"
140
+ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
141
+
142
+ [[package]]
143
+ name = "syn"
144
+ version = "2.0.91"
145
+ source = "registry+https://github.com/rust-lang/crates.io-index"
146
+ checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035"
147
+ dependencies = [
148
+ "proc-macro2",
149
+ "quote",
150
+ "unicode-ident",
151
+ ]
152
+
153
+ [[package]]
154
+ name = "unicode-ident"
155
+ version = "1.0.14"
156
+ source = "registry+https://github.com/rust-lang/crates.io-index"
157
+ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
158
+
159
+ [[package]]
160
+ name = "vcpkg"
161
+ version = "0.2.15"
162
+ source = "registry+https://github.com/rust-lang/crates.io-index"
163
+ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
164
+
165
+ [[package]]
166
+ name = "version_check"
167
+ version = "0.9.5"
168
+ source = "registry+https://github.com/rust-lang/crates.io-index"
169
+ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
170
+
171
+ [[package]]
172
+ name = "zerocopy"
173
+ version = "0.7.35"
174
+ source = "registry+https://github.com/rust-lang/crates.io-index"
175
+ checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
176
+ dependencies = [
177
+ "zerocopy-derive",
178
+ ]
179
+
180
+ [[package]]
181
+ name = "zerocopy-derive"
182
+ version = "0.7.35"
183
+ source = "registry+https://github.com/rust-lang/crates.io-index"
184
+ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
185
+ dependencies = [
186
+ "proc-macro2",
187
+ "quote",
188
+ "syn",
189
+ ]
get-token/Cargo.toml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "get-token"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+
6
+ [dependencies]
7
+ rusqlite = { version = "0.32.1", default-features = false, features = ["bundled"] }
8
+
9
+ [profile.release]
10
+ lto = true
11
+ codegen-units = 1
12
+ panic = 'abort'
13
+ strip = true
14
+ opt-level = 3
get-token/README.md ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Cursor Token 获取工具
2
+
3
+ 这个工具用于从 Cursor 编辑器的本地数据库中获取访问令牌。
4
+
5
+ ## 系统要求
6
+
7
+ - Rust 编程环境
8
+ - Cargo 包管理器
9
+
10
+ ## 构建说明
11
+
12
+ ### Windows
13
+
14
+ 1. 安装 Rust
15
+ ```powershell
16
+ winget install Rustlang.Rust
17
+ # 或访问 https://rustup.rs/ 下载安装程序
18
+ ```
19
+
20
+ 2. 克隆项目并构建
21
+ ```powershell
22
+ git clone <repository-url>
23
+ cd get-token
24
+ cargo build --release
25
+ ```
26
+
27
+ 3. 构建完成后,可执行文件位于 `target/release/get-token.exe`
28
+
29
+ ### macOS
30
+
31
+ 1. 安装 Rust
32
+ ```bash
33
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
34
+ ```
35
+
36
+ 2. 克隆项目并构建
37
+ ```bash
38
+ git clone <repository-url>
39
+ cd get-token
40
+ cargo build --release
41
+ ```
42
+
43
+ 3. 构建完成后,可执行文件位于 `target/release/get-token`
44
+
45
+ ## 使用方法
46
+
47
+ 直接运行编译好的可执行文件即可:
48
+
49
+ - Windows: `.\target\release\get-token.exe`
50
+ - macOS: `./target/release/get-token`
51
+
52
+ 程序将自动查找并显示 Cursor 编辑器的访问令牌。
53
+
54
+ ## 注意事项
55
+
56
+ - 确保 Cursor 编辑器已经安装并且至少登录过一次
57
+ - Windows 数据库路径:`%USERPROFILE%\AppData\Roaming\Cursor\User\globalStorage\state.vscdb`
58
+ - macOS 数据库路径:`~/Library/Application Support/Cursor/User/globalStorage/state.vscdb`
get-token/src/main.rs ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use rusqlite::Connection;
2
+ use std::env;
3
+ use std::path::PathBuf;
4
+
5
+ fn main() {
6
+ let home_dir = env::var("HOME")
7
+ .or_else(|_| env::var("USERPROFILE"))
8
+ .unwrap();
9
+ let db_path = if cfg!(target_os = "windows") {
10
+ PathBuf::from(home_dir).join(r"AppData\Roaming\Cursor\User\globalStorage\state.vscdb")
11
+ } else {
12
+ PathBuf::from(home_dir)
13
+ .join("Library/Application Support/Cursor/User/globalStorage/state.vscdb")
14
+ };
15
+
16
+ match Connection::open(&db_path) {
17
+ Ok(conn) => {
18
+ match conn.query_row(
19
+ "SELECT value FROM ItemTable WHERE key = 'cursorAuth/accessToken'",
20
+ [],
21
+ |row| row.get::<_, String>(0),
22
+ ) {
23
+ Ok(token) => println!("访问令牌: {}", token.trim()),
24
+ Err(err) => eprintln!("获取令牌时出错: {}", err),
25
+ }
26
+ }
27
+ Err(err) => eprintln!("无法打开数据库: {}", err),
28
+ }
29
+ }
scripts/build.ps1 ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ��ɫ�������
2
+ function Write-Info { Write-Host "[INFO] $args" -ForegroundColor Blue }
3
+ function Write-Warn { Write-Host "[WARN] $args" -ForegroundColor Yellow }
4
+ function Write-Error { Write-Host "[ERROR] $args" -ForegroundColor Red; exit 1 }
5
+
6
+ # ����Ҫ�Ĺ���
7
+ function Test-Requirements {
8
+ $tools = @("cargo", "protoc", "npm", "node")
9
+ $missing = @()
10
+
11
+ foreach ($tool in $tools) {
12
+ if (!(Get-Command $tool -ErrorAction SilentlyContinue)) {
13
+ $missing += $tool
14
+ }
15
+ }
16
+
17
+ if ($missing.Count -gt 0) {
18
+ Write-Error "ȱ�ٱ�Ҫ����: $($missing -join ', ')"
19
+ }
20
+ }
21
+
22
+ # �� Test-Requirements �����������º���
23
+ function Initialize-VSEnvironment {
24
+ Write-Info "���ڳ�ʼ�� Visual Studio ����..."
25
+
26
+ # ֱ��ʹ����֪�� vcvarsall.bat ·��
27
+ $vcvarsallPath = "E:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat"
28
+
29
+ if (-not (Test-Path $vcvarsallPath)) {
30
+ Write-Error "δ�ҵ� vcvarsall.bat: $vcvarsallPath"
31
+ return
32
+ }
33
+
34
+ Write-Info "ʹ�� vcvarsall.bat ·��: $vcvarsallPath"
35
+
36
+ # ��ȡ��������
37
+ $archArg = "x64"
38
+ $command = "`"$vcvarsallPath`" $archArg && set"
39
+
40
+ try {
41
+ $output = cmd /c "$command" 2>&1
42
+
43
+ # ��������Ƿ�ɹ�ִ��
44
+ if ($LASTEXITCODE -ne 0) {
45
+ Write-Error "vcvarsall.bat ִ��ʧ�ܣ��˳���: $LASTEXITCODE"
46
+ return
47
+ }
48
+
49
+ # ���µ�ǰ PowerShell �Ự�Ļ�������
50
+ foreach ($line in $output) {
51
+ if ($line -match "^([^=]+)=(.*)$") {
52
+ $name = $matches[1]
53
+ $value = $matches[2]
54
+ if (![string]::IsNullOrEmpty($name)) {
55
+ Set-Item -Path "env:$name" -Value $value -ErrorAction SilentlyContinue
56
+ }
57
+ }
58
+ }
59
+
60
+ Write-Info "Visual Studio ������ʼ�����"
61
+ }
62
+ catch {
63
+ Write-Error "��ʼ�� Visual Studio ����ʱ��������: $_"
64
+ }
65
+ }
66
+
67
+ # ������Ϣ
68
+ function Show-Help {
69
+ Write-Host @"
70
+ �÷�: $(Split-Path $MyInvocation.MyCommand.Path -Leaf) [ѡ��]
71
+
72
+ ѡ��:
73
+ --static ʹ�þ�̬���ӣ�Ĭ�϶�̬���ӣ�
74
+ --help ��ʾ�˰�����Ϣ
75
+
76
+ Ĭ�ϱ������� Windows ֧�ֵļܹ� (x64 �� arm64)
77
+ "@
78
+ }
79
+
80
+ # ��������
81
+ function New-Target {
82
+ param (
83
+ [string]$target,
84
+ [string]$rustflags
85
+ )
86
+
87
+ Write-Info "���ڹ��� $target..."
88
+
89
+ # ���û���������ִ�й���
90
+ $env:RUSTFLAGS = $rustflags
91
+ cargo build --target $target --release
92
+
93
+ # �ƶ���������
94
+ $binaryName = "cursor-api"
95
+ if ($UseStatic) {
96
+ $binaryName += "-static"
97
+ }
98
+
99
+ $sourcePath = "target/$target/release/cursor-api.exe"
100
+ $targetPath = "release/${binaryName}-${target}.exe"
101
+
102
+ if (Test-Path $sourcePath) {
103
+ Copy-Item $sourcePath $targetPath -Force
104
+ Write-Info "��ɹ��� $target"
105
+ }
106
+ else {
107
+ Write-Warn "��������δ�ҵ�: $target"
108
+ return $false
109
+ }
110
+ return $true
111
+ }
112
+
113
+ # ��������
114
+ $UseStatic = $false
115
+
116
+ foreach ($arg in $args) {
117
+ switch ($arg) {
118
+ "--static" { $UseStatic = $true }
119
+ "--help" { Show-Help; exit 0 }
120
+ default { Write-Error "δ֪����: $arg" }
121
+ }
122
+ }
123
+
124
+ # ������
125
+ try {
126
+ # �������
127
+ Test-Requirements
128
+
129
+ # ��ʼ�� Visual Studio ����
130
+ Initialize-VSEnvironment
131
+
132
+ # ���� release Ŀ¼
133
+ New-Item -ItemType Directory -Force -Path "release" | Out-Null
134
+
135
+ # ����Ŀ��ƽ̨
136
+ $targets = @(
137
+ "x86_64-pc-windows-msvc",
138
+ "aarch64-pc-windows-msvc"
139
+ )
140
+
141
+ # ���þ�̬���ӱ�־
142
+ $rustflags = ""
143
+ if ($UseStatic) {
144
+ $rustflags = "-C target-feature=+crt-static"
145
+ }
146
+
147
+ Write-Info "��ʼ����..."
148
+
149
+ # ��������Ŀ��
150
+ foreach ($target in $targets) {
151
+ New-Target -target $target -rustflags $rustflags
152
+ }
153
+
154
+ Write-Info "������ɣ�"
155
+ }
156
+ catch {
157
+ Write-Error "���������������: $_"
158
+ }
scripts/build.sh ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # 颜色输出函数
5
+ info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
6
+ warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; }
7
+ error() { echo -e "\033[1;31m[ERROR]\033[0m $*" >&2; exit 1; }
8
+
9
+ # 检查是否在 Linux 环境
10
+ is_linux() {
11
+ [ "$(uname -s)" = "Linux" ]
12
+ }
13
+
14
+ # 检查必要的工具
15
+ check_requirements() {
16
+ local missing_tools=()
17
+
18
+ # 基础工具检查
19
+ for tool in cargo protoc npm node; do
20
+ if ! command -v "$tool" &>/dev/null; then
21
+ missing_tools+=("$tool")
22
+ fi
23
+ done
24
+
25
+ # Linux 特定检查
26
+ if [[ $USE_CROSS == true ]] && ! command -v cross &>/dev/null; then
27
+ missing_tools+=("cross")
28
+ fi
29
+
30
+ if [[ ${#missing_tools[@]} -gt 0 ]]; then
31
+ error "缺少必要工具: ${missing_tools[*]}"
32
+ fi
33
+ }
34
+
35
+ # 帮助信息
36
+ show_help() {
37
+ cat << EOF
38
+ 用法: $(basename "$0") [选项]
39
+
40
+ 选项:
41
+ --cross 使用 cross 进行交叉编译(仅在 Linux 上有效)
42
+ --static 使用静态链接(默认动态链接)
43
+ --help 显示此帮助信息
44
+
45
+ 不带参数时只编译当前平台
46
+ EOF
47
+ }
48
+
49
+ # 并行构建函数
50
+ build_target() {
51
+ local target=$1
52
+ local extension=""
53
+ local rustflags="${2:-}"
54
+
55
+ info "正在构建 $target..."
56
+
57
+ # 确定文件后缀
58
+ [[ $target == *"windows"* ]] && extension=".exe"
59
+
60
+ # 设置目标特定的环境变量
61
+ local build_env=()
62
+ if [[ $target == "aarch64-unknown-linux-gnu" ]]; then
63
+ build_env+=(
64
+ "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc"
65
+ "CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++"
66
+ "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc"
67
+ "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig"
68
+ "PKG_CONFIG_ALLOW_CROSS=1"
69
+ "OPENSSL_DIR=/usr"
70
+ "OPENSSL_INCLUDE_DIR=/usr/include"
71
+ "OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu"
72
+ )
73
+ fi
74
+
75
+ # 判断是否使用 cross(仅在 Linux 上)
76
+ if [[ $target != "$CURRENT_TARGET" ]]; then
77
+ env ${build_env[@]+"${build_env[@]}"} RUSTFLAGS="$rustflags" cargo build --target "$target" --release
78
+ else
79
+ env ${build_env[@]+"${build_env[@]}"} RUSTFLAGS="$rustflags" cargo build --release
80
+ fi
81
+
82
+ # 移动编译产物到 release 目录
83
+ local binary_name="cursor-api"
84
+ [[ $USE_STATIC == true ]] && binary_name+="-static"
85
+
86
+ if [[ -f "target/$target/release/cursor-api$extension" ]]; then
87
+ cp "target/$target/release/cursor-api$extension" "release/${binary_name}-$target$extension"
88
+ info "完成构建 $target"
89
+ else
90
+ warn "构建产物未找到: $target"
91
+ return 1
92
+ fi
93
+ }
94
+
95
+ # 获取 CPU 架构
96
+ ARCH=$(uname -m | sed 's/^aarch64\|arm64$/aarch64/;s/^x86_64\|x86-64\|x64\|amd64$/x86_64/')
97
+ OS=$(uname -s)
98
+
99
+ # 确定当前系统的目标平台
100
+ get_target() {
101
+ local arch=$1
102
+ local os=$2
103
+ case "$os" in
104
+ "Darwin") echo "${arch}-apple-darwin" ;;
105
+ "Linux") echo "${arch}-unknown-linux-gnu" ;;
106
+ "MINGW"*|"MSYS"*|"CYGWIN"*|"Windows_NT") echo "${arch}-pc-windows-msvc" ;;
107
+ "FreeBSD") echo "x86_64-unknown-freebsd" ;;
108
+ *) error "不支持的系统: $os" ;;
109
+ esac
110
+ }
111
+
112
+ # 设置当前目标平台
113
+ CURRENT_TARGET=$(get_target "$ARCH" "$OS")
114
+
115
+ # 检查是否成功获取目标平台
116
+ [ -z "$CURRENT_TARGET" ] && error "无法确定当前系统的目标平台"
117
+
118
+ # 获取系统对应的所有目标
119
+ get_targets() {
120
+ case "$1" in
121
+ "linux") echo "x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu" ;;
122
+ "windows") echo "x86_64-pc-windows-msvc aarch64-pc-windows-msvc" ;;
123
+ "macos") echo "x86_64-apple-darwin aarch64-apple-darwin" ;;
124
+ "freebsd") echo "x86_64-unknown-freebsd" ;;
125
+ *) error "不支持的系统组: $1" ;;
126
+ esac
127
+ }
128
+
129
+ # 解析参数
130
+ USE_CROSS=false
131
+ USE_STATIC=false
132
+
133
+ while [[ $# -gt 0 ]]; do
134
+ case $1 in
135
+ --cross) USE_CROSS=true ;;
136
+ --static) USE_STATIC=true ;;
137
+ --help) show_help; exit 0 ;;
138
+ *) error "未知参数: $1" ;;
139
+ esac
140
+ shift
141
+ done
142
+
143
+ # 检查依赖
144
+ check_requirements
145
+
146
+ # 确定要构建的目标
147
+ if [[ $USE_CROSS == true ]] && is_linux; then
148
+ # 只在 Linux 上使用 cross 进行多架构构建
149
+ TARGETS=($(get_targets "linux"))
150
+ else
151
+ # 其他系统或不使用 cross 时只构建当前系统的所有架构
152
+ case "$OS" in
153
+ "Darwin") TARGETS=($(get_targets "macos")) ;;
154
+ "Linux") TARGETS=("$CURRENT_TARGET") ;;
155
+ "MINGW"*|"MSYS"*|"CYGWIN"*|"Windows_NT") TARGETS=($(get_targets "windows")) ;;
156
+ "FreeBSD") TARGETS=("$CURRENT_TARGET") ;;
157
+ *) error "不支持的系统: $OS" ;;
158
+ esac
159
+ fi
160
+
161
+ # 创建 release 目录
162
+ mkdir -p release
163
+
164
+ # 设置静态链接标志
165
+ RUSTFLAGS=""
166
+ [[ $USE_STATIC == true ]] && RUSTFLAGS="-C target-feature=+crt-static"
167
+
168
+ # 并行构建所有目标
169
+ info "开始构建..."
170
+ for target in "${TARGETS[@]}"; do
171
+ build_target "$target" "$RUSTFLAGS" &
172
+ done
173
+
174
+ # 等待所有构建完成
175
+ wait
176
+
177
+ # 为 macOS 平台创建通用二进制
178
+ if [[ "$OS" == "Darwin" ]] && [[ ${#TARGETS[@]} -gt 1 ]]; then
179
+ binary_suffix=""
180
+ [[ $USE_STATIC == true ]] && binary_suffix="-static"
181
+
182
+ if [[ -f "release/cursor-api${binary_suffix}-x86_64-apple-darwin" ]] && \
183
+ [[ -f "release/cursor-api${binary_suffix}-aarch64-apple-darwin" ]]; then
184
+ info "创建 macOS 通用二进制..."
185
+ lipo -create \
186
+ "release/cursor-api${binary_suffix}-x86_64-apple-darwin" \
187
+ "release/cursor-api${binary_suffix}-aarch64-apple-darwin" \
188
+ -output "release/cursor-api${binary_suffix}-universal-apple-darwin"
189
+ fi
190
+ fi
191
+
192
+ info "构建完成!"
scripts/minify-html.js ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+
3
+ const { minify } = require('html-minifier-terser');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ // 配置选项
8
+ const options = {
9
+ collapseWhitespace: true,
10
+ removeComments: true,
11
+ removeEmptyAttributes: true,
12
+ removeOptionalTags: true,
13
+ removeRedundantAttributes: true,
14
+ removeScriptTypeAttributes: true,
15
+ removeStyleLinkTypeAttributes: true,
16
+ minifyCSS: true,
17
+ minifyJS: true,
18
+ processScripts: ['application/json'],
19
+ };
20
+
21
+ // 处理文件
22
+ async function minifyFile(inputPath, outputPath) {
23
+ try {
24
+ const html = fs.readFileSync(inputPath, 'utf8');
25
+ const minified = await minify(html, options);
26
+ fs.writeFileSync(outputPath, minified);
27
+ console.log(`✓ Minified ${path.basename(inputPath)} -> ${path.basename(outputPath)}`);
28
+ } catch (err) {
29
+ console.error(`✗ Error processing ${inputPath}:`, err);
30
+ process.exit(1);
31
+ }
32
+ }
33
+
34
+ // 主函数
35
+ async function main() {
36
+ const staticDir = path.join(__dirname, '..', 'static');
37
+ const files = [
38
+ ['tokeninfo.html', 'tokeninfo.min.html'],
39
+ ];
40
+
41
+ for (const [input, output] of files) {
42
+ await minifyFile(
43
+ path.join(staticDir, input),
44
+ path.join(staticDir, output)
45
+ );
46
+ }
47
+ }
48
+
49
+ main();
scripts/package-lock.json ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "html-minifier-scripts",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "html-minifier-scripts",
9
+ "version": "1.0.0",
10
+ "dependencies": {
11
+ "html-minifier-terser": "^7.2.0"
12
+ },
13
+ "engines": {
14
+ "node": ">=14.0.0"
15
+ }
16
+ },
17
+ "node_modules/@jridgewell/gen-mapping": {
18
+ "version": "0.3.8",
19
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
20
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "@jridgewell/set-array": "^1.2.1",
24
+ "@jridgewell/sourcemap-codec": "^1.4.10",
25
+ "@jridgewell/trace-mapping": "^0.3.24"
26
+ },
27
+ "engines": {
28
+ "node": ">=6.0.0"
29
+ }
30
+ },
31
+ "node_modules/@jridgewell/resolve-uri": {
32
+ "version": "3.1.2",
33
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
34
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
35
+ "license": "MIT",
36
+ "engines": {
37
+ "node": ">=6.0.0"
38
+ }
39
+ },
40
+ "node_modules/@jridgewell/set-array": {
41
+ "version": "1.2.1",
42
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
43
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
44
+ "license": "MIT",
45
+ "engines": {
46
+ "node": ">=6.0.0"
47
+ }
48
+ },
49
+ "node_modules/@jridgewell/source-map": {
50
+ "version": "0.3.6",
51
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
52
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
53
+ "license": "MIT",
54
+ "dependencies": {
55
+ "@jridgewell/gen-mapping": "^0.3.5",
56
+ "@jridgewell/trace-mapping": "^0.3.25"
57
+ }
58
+ },
59
+ "node_modules/@jridgewell/sourcemap-codec": {
60
+ "version": "1.5.0",
61
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
62
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
63
+ "license": "MIT"
64
+ },
65
+ "node_modules/@jridgewell/trace-mapping": {
66
+ "version": "0.3.25",
67
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
68
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
69
+ "license": "MIT",
70
+ "dependencies": {
71
+ "@jridgewell/resolve-uri": "^3.1.0",
72
+ "@jridgewell/sourcemap-codec": "^1.4.14"
73
+ }
74
+ },
75
+ "node_modules/acorn": {
76
+ "version": "8.14.0",
77
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
78
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
79
+ "license": "MIT",
80
+ "bin": {
81
+ "acorn": "bin/acorn"
82
+ },
83
+ "engines": {
84
+ "node": ">=0.4.0"
85
+ }
86
+ },
87
+ "node_modules/buffer-from": {
88
+ "version": "1.1.2",
89
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
90
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
91
+ "license": "MIT"
92
+ },
93
+ "node_modules/camel-case": {
94
+ "version": "4.1.2",
95
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
96
+ "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
97
+ "license": "MIT",
98
+ "dependencies": {
99
+ "pascal-case": "^3.1.2",
100
+ "tslib": "^2.0.3"
101
+ }
102
+ },
103
+ "node_modules/clean-css": {
104
+ "version": "5.3.3",
105
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
106
+ "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
107
+ "license": "MIT",
108
+ "dependencies": {
109
+ "source-map": "~0.6.0"
110
+ },
111
+ "engines": {
112
+ "node": ">= 10.0"
113
+ }
114
+ },
115
+ "node_modules/commander": {
116
+ "version": "10.0.1",
117
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
118
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
119
+ "license": "MIT",
120
+ "engines": {
121
+ "node": ">=14"
122
+ }
123
+ },
124
+ "node_modules/dot-case": {
125
+ "version": "3.0.4",
126
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
127
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
128
+ "license": "MIT",
129
+ "dependencies": {
130
+ "no-case": "^3.0.4",
131
+ "tslib": "^2.0.3"
132
+ }
133
+ },
134
+ "node_modules/entities": {
135
+ "version": "4.5.0",
136
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
137
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
138
+ "license": "BSD-2-Clause",
139
+ "engines": {
140
+ "node": ">=0.12"
141
+ },
142
+ "funding": {
143
+ "url": "https://github.com/fb55/entities?sponsor=1"
144
+ }
145
+ },
146
+ "node_modules/html-minifier-terser": {
147
+ "version": "7.2.0",
148
+ "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
149
+ "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
150
+ "license": "MIT",
151
+ "dependencies": {
152
+ "camel-case": "^4.1.2",
153
+ "clean-css": "~5.3.2",
154
+ "commander": "^10.0.0",
155
+ "entities": "^4.4.0",
156
+ "param-case": "^3.0.4",
157
+ "relateurl": "^0.2.7",
158
+ "terser": "^5.15.1"
159
+ },
160
+ "bin": {
161
+ "html-minifier-terser": "cli.js"
162
+ },
163
+ "engines": {
164
+ "node": "^14.13.1 || >=16.0.0"
165
+ }
166
+ },
167
+ "node_modules/lower-case": {
168
+ "version": "2.0.2",
169
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
170
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
171
+ "license": "MIT",
172
+ "dependencies": {
173
+ "tslib": "^2.0.3"
174
+ }
175
+ },
176
+ "node_modules/no-case": {
177
+ "version": "3.0.4",
178
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
179
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
180
+ "license": "MIT",
181
+ "dependencies": {
182
+ "lower-case": "^2.0.2",
183
+ "tslib": "^2.0.3"
184
+ }
185
+ },
186
+ "node_modules/param-case": {
187
+ "version": "3.0.4",
188
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
189
+ "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
190
+ "license": "MIT",
191
+ "dependencies": {
192
+ "dot-case": "^3.0.4",
193
+ "tslib": "^2.0.3"
194
+ }
195
+ },
196
+ "node_modules/pascal-case": {
197
+ "version": "3.1.2",
198
+ "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
199
+ "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
200
+ "license": "MIT",
201
+ "dependencies": {
202
+ "no-case": "^3.0.4",
203
+ "tslib": "^2.0.3"
204
+ }
205
+ },
206
+ "node_modules/relateurl": {
207
+ "version": "0.2.7",
208
+ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
209
+ "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
210
+ "license": "MIT",
211
+ "engines": {
212
+ "node": ">= 0.10"
213
+ }
214
+ },
215
+ "node_modules/source-map": {
216
+ "version": "0.6.1",
217
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
218
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
219
+ "license": "BSD-3-Clause",
220
+ "engines": {
221
+ "node": ">=0.10.0"
222
+ }
223
+ },
224
+ "node_modules/source-map-support": {
225
+ "version": "0.5.21",
226
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
227
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
228
+ "license": "MIT",
229
+ "dependencies": {
230
+ "buffer-from": "^1.0.0",
231
+ "source-map": "^0.6.0"
232
+ }
233
+ },
234
+ "node_modules/terser": {
235
+ "version": "5.37.0",
236
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
237
+ "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
238
+ "license": "BSD-2-Clause",
239
+ "dependencies": {
240
+ "@jridgewell/source-map": "^0.3.3",
241
+ "acorn": "^8.8.2",
242
+ "commander": "^2.20.0",
243
+ "source-map-support": "~0.5.20"
244
+ },
245
+ "bin": {
246
+ "terser": "bin/terser"
247
+ },
248
+ "engines": {
249
+ "node": ">=10"
250
+ }
251
+ },
252
+ "node_modules/terser/node_modules/commander": {
253
+ "version": "2.20.3",
254
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
255
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
256
+ "license": "MIT"
257
+ },
258
+ "node_modules/tslib": {
259
+ "version": "2.8.1",
260
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
261
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
262
+ "license": "0BSD"
263
+ }
264
+ }
265
+ }
scripts/package.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "html-minifier-scripts",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "engines": {
6
+ "node": ">=14.0.0"
7
+ },
8
+ "dependencies": {
9
+ "html-minifier-terser": "^7.2.0"
10
+ }
11
+ }
scripts/setup-windows.ps1 ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ���� PowerShell ����Ϊ UTF-8
2
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
3
+ $OutputEncoding = [System.Text.Encoding]::UTF8
4
+
5
+ # ����Ƿ��Թ���ԱȨ������
6
+ if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
7
+ Write-Warning "���Թ���ԱȨ�����д˽ű�"
8
+ exit 1
9
+ }
10
+
11
+ # ��鲢��װ Chocolatey
12
+ if (!(Get-Command choco -ErrorAction SilentlyContinue)) {
13
+ Write-Output "���ڰ�װ Chocolatey..."
14
+ Set-ExecutionPolicy Bypass -Scope Process -Force
15
+ [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
16
+ iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
17
+ }
18
+
19
+ # ��װ��Ҫ�Ĺ���
20
+ Write-Output "���ڰ�װ��Ҫ�Ĺ���..."
21
+ choco install -y mingw
22
+ choco install -y protoc
23
+ choco install -y git
24
+
25
+ # ��װ Rust ����
26
+ Write-Output "���ڰ�װ Rust ����..."
27
+ rustup target add x86_64-pc-windows-msvc
28
+ rustup target add x86_64-unknown-linux-gnu
29
+ cargo install cross
30
+
31
+ Write-Output "��װ��ɣ�"
src/lib.rs ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
2
+ use flate2::read::GzDecoder;
3
+ use prost::Message;
4
+ use rand::{thread_rng, Rng};
5
+ use sha2::{Digest, Sha256};
6
+ use std::io::Read;
7
+ use uuid::Uuid;
8
+
9
+ pub mod proto {
10
+ include!(concat!(env!("OUT_DIR"), "/cursor.rs"));
11
+ }
12
+
13
+ use proto::{ChatMessage, ResMessage};
14
+
15
+ #[derive(Debug)]
16
+ pub struct ChatInput {
17
+ pub role: String,
18
+ pub content: String,
19
+ }
20
+
21
+ fn process_chat_inputs(inputs: Vec<ChatInput>) -> (String, Vec<proto::chat_message::Message>) {
22
+ // 收集 system 和 developer 指令
23
+ let instructions = inputs
24
+ .iter()
25
+ .filter(|input| input.role == "system" || input.role == "developer")
26
+ .map(|input| input.content.clone())
27
+ .collect::<Vec<String>>()
28
+ .join("\n\n");
29
+
30
+ // 使用默认指令或收集到的指令
31
+ let instructions = if instructions.is_empty() {
32
+ "Respond in Chinese by default".to_string()
33
+ } else {
34
+ instructions
35
+ };
36
+
37
+ // 过滤出 user 和 assistant 对话
38
+ let mut chat_inputs: Vec<ChatInput> = inputs
39
+ .into_iter()
40
+ .filter(|input| input.role == "user" || input.role == "assistant")
41
+ .collect();
42
+
43
+ // 处理空对话情况
44
+ if chat_inputs.is_empty() {
45
+ return (
46
+ instructions,
47
+ vec![proto::chat_message::Message {
48
+ role: 1, // user
49
+ content: " ".to_string(),
50
+ message_id: Uuid::new_v4().to_string(),
51
+ }],
52
+ );
53
+ }
54
+
55
+ // 如果第一条是 assistant,插入空的 user 消息
56
+ if chat_inputs
57
+ .first()
58
+ .map_or(false, |input| input.role == "assistant")
59
+ {
60
+ chat_inputs.insert(
61
+ 0,
62
+ ChatInput {
63
+ role: "user".to_string(),
64
+ content: " ".to_string(),
65
+ },
66
+ );
67
+ }
68
+
69
+ // 处理连续相同角色的情况
70
+ let mut i = 1;
71
+ while i < chat_inputs.len() {
72
+ if chat_inputs[i].role == chat_inputs[i - 1].role {
73
+ let insert_role = if chat_inputs[i].role == "user" {
74
+ "assistant"
75
+ } else {
76
+ "user"
77
+ };
78
+ chat_inputs.insert(
79
+ i,
80
+ ChatInput {
81
+ role: insert_role.to_string(),
82
+ content: " ".to_string(),
83
+ },
84
+ );
85
+ }
86
+ i += 1;
87
+ }
88
+
89
+ // 确保最后一条是 user
90
+ if chat_inputs
91
+ .last()
92
+ .map_or(false, |input| input.role == "assistant")
93
+ {
94
+ chat_inputs.push(ChatInput {
95
+ role: "user".to_string(),
96
+ content: " ".to_string(),
97
+ });
98
+ }
99
+
100
+ // 转换为 proto messages
101
+ let messages = chat_inputs
102
+ .into_iter()
103
+ .map(|input| proto::chat_message::Message {
104
+ role: if input.role == "user" { 1 } else { 2 },
105
+ content: input.content,
106
+ message_id: Uuid::new_v4().to_string(),
107
+ })
108
+ .collect();
109
+
110
+ (instructions, messages)
111
+ }
112
+
113
+ pub async fn encode_chat_message(
114
+ inputs: Vec<ChatInput>,
115
+ model_name: &str,
116
+ ) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
117
+ let (instructions, messages) = process_chat_inputs(inputs);
118
+
119
+ let chat = ChatMessage {
120
+ messages,
121
+ instructions: Some(proto::chat_message::Instructions {
122
+ content: instructions,
123
+ }),
124
+ project_path: "/path/to/project".to_string(),
125
+ model: Some(proto::chat_message::Model {
126
+ name: model_name.to_string(),
127
+ empty: String::new(),
128
+ }),
129
+ request_id: Uuid::new_v4().to_string(),
130
+ summary: String::new(),
131
+ conversation_id: Uuid::new_v4().to_string(),
132
+ };
133
+
134
+ let mut encoded = Vec::new();
135
+ chat.encode(&mut encoded)?;
136
+
137
+ let len_prefix = format!("{:010x}", encoded.len()).to_uppercase();
138
+ let content = hex::encode_upper(&encoded);
139
+
140
+ Ok(hex::decode(len_prefix + &content)?)
141
+ }
142
+
143
+ pub async fn decode_response(data: &[u8]) -> String {
144
+ if let Ok(decoded) = decode_proto_messages(data) {
145
+ if !decoded.is_empty() {
146
+ return decoded;
147
+ }
148
+ }
149
+ decompress_response(data).await
150
+ }
151
+
152
+ fn decode_proto_messages(data: &[u8]) -> Result<String, Box<dyn std::error::Error>> {
153
+ let hex_str = hex::encode(data);
154
+ let mut pos = 0;
155
+ let mut messages = Vec::new();
156
+
157
+ while pos + 10 <= hex_str.len() {
158
+ let msg_len = i64::from_str_radix(&hex_str[pos..pos + 10], 16)?;
159
+ pos += 10;
160
+
161
+ if pos + (msg_len * 2) as usize > hex_str.len() {
162
+ break;
163
+ }
164
+
165
+ let msg_data = &hex_str[pos..pos + (msg_len * 2) as usize];
166
+ pos += (msg_len * 2) as usize;
167
+
168
+ let buffer = hex::decode(msg_data)?;
169
+ let response = ResMessage::decode(&buffer[..])?;
170
+ messages.push(response.msg);
171
+ }
172
+
173
+ Ok(messages.join(""))
174
+ }
175
+
176
+ async fn decompress_response(data: &[u8]) -> String {
177
+ if data.len() <= 5 {
178
+ return String::new();
179
+ }
180
+
181
+ let mut decoder = GzDecoder::new(&data[5..]);
182
+ let mut text = String::new();
183
+
184
+ match decoder.read_to_string(&mut text) {
185
+ Ok(_) => {
186
+ if !text.contains("<|BEGIN_SYSTEM|>") {
187
+ text
188
+ } else {
189
+ String::new()
190
+ }
191
+ }
192
+ Err(_) => String::new(),
193
+ }
194
+ }
195
+
196
+ pub fn generate_random_id(
197
+ size: usize,
198
+ dict_type: Option<&str>,
199
+ custom_chars: Option<&str>,
200
+ ) -> String {
201
+ let charset = match (dict_type, custom_chars) {
202
+ (_, Some(chars)) => chars,
203
+ (Some("alphabet"), _) => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
204
+ (Some("max"), _) => "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-",
205
+ _ => "0123456789",
206
+ };
207
+
208
+ let mut rng = thread_rng();
209
+ (0..size)
210
+ .map(|_| {
211
+ let idx = rng.gen_range(0..charset.len());
212
+ charset.chars().nth(idx).unwrap()
213
+ })
214
+ .collect()
215
+ }
216
+
217
+ pub fn generate_hash() -> String {
218
+ let random_bytes = rand::thread_rng().gen::<[u8; 32]>();
219
+ let mut hasher = Sha256::new();
220
+ hasher.update(random_bytes);
221
+ hex::encode(hasher.finalize())
222
+ }
223
+
224
+ fn obfuscate_bytes(bytes: &mut Vec<u8>) {
225
+ let mut prev: u8 = 165;
226
+ for (idx, byte) in bytes.iter_mut().enumerate() {
227
+ let old_value = *byte;
228
+ *byte = (old_value ^ prev).wrapping_add((idx % 256) as u8);
229
+ prev = *byte;
230
+ }
231
+ }
232
+
233
+ pub fn generate_checksum(device_id: &str, mac_addr: Option<&str>) -> String {
234
+ let timestamp = std::time::SystemTime::now()
235
+ .duration_since(std::time::UNIX_EPOCH)
236
+ .unwrap()
237
+ .as_millis()
238
+ / 1_000_000;
239
+
240
+ let mut timestamp_bytes = vec![
241
+ ((timestamp >> 40) & 255) as u8,
242
+ ((timestamp >> 32) & 255) as u8,
243
+ ((timestamp >> 24) & 255) as u8,
244
+ ((timestamp >> 16) & 255) as u8,
245
+ ((timestamp >> 8) & 255) as u8,
246
+ (255 & timestamp) as u8,
247
+ ];
248
+
249
+ obfuscate_bytes(&mut timestamp_bytes);
250
+ let encoded = BASE64.encode(&timestamp_bytes);
251
+
252
+ match mac_addr {
253
+ Some(mac) => format!("{}{}/{}", encoded, device_id, mac),
254
+ None => format!("{}{}", encoded, device_id),
255
+ }
256
+ }
src/main.rs ADDED
@@ -0,0 +1,661 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use axum::{
2
+ body::Body,
3
+ extract::State,
4
+ http::{HeaderMap, StatusCode},
5
+ response::{IntoResponse, Response},
6
+ routing::{get, post},
7
+ Json, Router,
8
+ };
9
+ use bytes::Bytes;
10
+ use chrono::{DateTime, Local, Utc};
11
+ use futures::StreamExt;
12
+ use reqwest::Client;
13
+ use serde::{Deserialize, Serialize};
14
+ use std::sync::atomic::{AtomicUsize, Ordering};
15
+ use std::{convert::Infallible, sync::Arc};
16
+ use tokio::sync::Mutex;
17
+ use tower_http::cors::CorsLayer;
18
+ use uuid::Uuid;
19
+
20
+ // 应用状态
21
+ struct AppState {
22
+ start_time: DateTime<Local>,
23
+ version: String,
24
+ total_requests: u64,
25
+ active_requests: u64,
26
+ request_logs: Vec<RequestLog>,
27
+ route_prefix: String,
28
+ token_infos: Vec<TokenInfo>,
29
+ }
30
+
31
+ // 模型定义
32
+ #[derive(Serialize, Deserialize, Clone)]
33
+ struct Model {
34
+ id: String,
35
+ created: i64,
36
+ object: String,
37
+ owned_by: String,
38
+ }
39
+
40
+ // 请求日志
41
+ #[derive(Serialize, Clone)]
42
+ struct RequestLog {
43
+ timestamp: DateTime<Local>,
44
+ model: String,
45
+ checksum: String,
46
+ auth_token: String,
47
+ stream: bool,
48
+ }
49
+
50
+ // 聊天请求
51
+ #[derive(Deserialize)]
52
+ struct ChatRequest {
53
+ model: String,
54
+ messages: Vec<Message>,
55
+ #[serde(default)]
56
+ stream: bool,
57
+ }
58
+
59
+ // 添加用于请求的消息结构体
60
+ #[derive(Serialize, Deserialize)]
61
+ struct Message {
62
+ role: String,
63
+ content: String,
64
+ }
65
+
66
+ // 支持的模型列表
67
+ mod models;
68
+ use models::AVAILABLE_MODELS;
69
+
70
+ // 用于存储 token 信息
71
+ #[derive(Debug)]
72
+ struct TokenInfo {
73
+ token: String,
74
+ checksum: String,
75
+ }
76
+
77
+ // TokenUpdateRequest 结构体
78
+ #[derive(Deserialize)]
79
+ struct TokenUpdateRequest {
80
+ tokens: String,
81
+ #[serde(default)]
82
+ token_list: Option<String>,
83
+ }
84
+
85
+ // 自定义错误类型
86
+ #[derive(Debug)]
87
+ enum ChatError {
88
+ ModelNotSupported(String),
89
+ EmptyMessages,
90
+ StreamNotSupported(String),
91
+ NoTokens,
92
+ RequestFailed(String),
93
+ Unauthorized,
94
+ }
95
+
96
+ impl ChatError {
97
+ fn to_json(&self) -> serde_json::Value {
98
+ let (code, message) = match self {
99
+ ChatError::ModelNotSupported(model) => (
100
+ "model_not_supported",
101
+ format!("Model '{}' is not supported", model),
102
+ ),
103
+ ChatError::EmptyMessages => (
104
+ "empty_messages",
105
+ "Message array cannot be empty".to_string(),
106
+ ),
107
+ ChatError::StreamNotSupported(model) => (
108
+ "stream_not_supported",
109
+ format!("Streaming is not supported for model '{}'", model),
110
+ ),
111
+ ChatError::NoTokens => ("no_tokens", "No available tokens".to_string()),
112
+ ChatError::RequestFailed(err) => ("request_failed", format!("Request failed: {}", err)),
113
+ ChatError::Unauthorized => ("unauthorized", "Invalid authorization token".to_string()),
114
+ };
115
+
116
+ serde_json::json!({
117
+ "error": {
118
+ "code": code,
119
+ "message": message
120
+ }
121
+ })
122
+ }
123
+ }
124
+
125
+ #[tokio::main]
126
+ async fn main() {
127
+ // 加载环境变量
128
+ dotenvy::dotenv().ok();
129
+
130
+ // 处理 token 文件路径
131
+ let token_file = std::env::var("TOKEN_FILE").unwrap_or_else(|_| ".token".to_string());
132
+
133
+ // 加载 tokens
134
+ let token_infos = load_tokens(&token_file);
135
+
136
+ // 获取路由前缀配置
137
+ let route_prefix = std::env::var("ROUTE_PREFIX").unwrap_or_default();
138
+
139
+ // 初始化应用状态
140
+ let state = Arc::new(Mutex::new(AppState {
141
+ start_time: Local::now(),
142
+ version: env!("CARGO_PKG_VERSION").to_string(),
143
+ total_requests: 0,
144
+ active_requests: 0,
145
+ request_logs: Vec::new(),
146
+ route_prefix: route_prefix.clone(),
147
+ token_infos,
148
+ }));
149
+
150
+ // 设置路由
151
+ let app = Router::new()
152
+ .route("/", get(handle_root))
153
+ .route("/tokeninfo", get(handle_tokeninfo_page))
154
+ .route(&format!("{}/v1/models", route_prefix), get(handle_models))
155
+ .route("/checksum", get(handle_checksum))
156
+ .route("/update-tokeninfo", get(handle_update_tokeninfo))
157
+ .route("/get-tokeninfo", post(handle_get_tokeninfo))
158
+ .route("/update-tokeninfo", post(handle_update_tokeninfo_post))
159
+ .route(
160
+ &format!("{}/v1/chat/completions", route_prefix),
161
+ post(handle_chat),
162
+ )
163
+ .route("/logs", get(handle_logs))
164
+ .layer(CorsLayer::permissive())
165
+ .with_state(state);
166
+
167
+ // 启动服务器
168
+ let port = std::env::var("PORT").unwrap_or_else(|_| "3000".to_string());
169
+ let addr = format!("0.0.0.0:{}", port);
170
+ println!("服务器运行在端口 {}", port);
171
+
172
+ let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
173
+ axum::serve(listener, app).await.unwrap();
174
+ }
175
+
176
+ // Token 加载函数
177
+ fn load_tokens(token_file: &str) -> Vec<TokenInfo> {
178
+ let token_list_file =
179
+ std::env::var("TOKEN_LIST_FILE").unwrap_or_else(|_| ".token-list".to_string());
180
+
181
+ // 读取并规范化 .token 文件
182
+ let tokens = if let Ok(content) = std::fs::read_to_string(token_file) {
183
+ let normalized = content.replace("\r\n", "\n");
184
+ if normalized != content {
185
+ std::fs::write(token_file, &normalized).unwrap();
186
+ }
187
+ normalized
188
+ .lines()
189
+ .enumerate()
190
+ .filter_map(|(idx, line)| {
191
+ let parts: Vec<&str> = line.split("::").collect();
192
+ match parts.len() {
193
+ 1 => Some(line.to_string()),
194
+ 2 => Some(parts[1].to_string()),
195
+ _ => {
196
+ println!("警告: 第{}行包含多个'::'分隔符,已忽略此行", idx + 1);
197
+ None
198
+ }
199
+ }
200
+ })
201
+ .filter(|s| !s.is_empty())
202
+ .collect::<Vec<_>>()
203
+ } else {
204
+ eprintln!("警告: 无法读取token文件 '{}'", token_file);
205
+ Vec::new()
206
+ };
207
+
208
+ // 读取现有的 token-list
209
+ let mut token_map: std::collections::HashMap<String, String> =
210
+ if let Ok(content) = std::fs::read_to_string(&token_list_file) {
211
+ content
212
+ .split('\n')
213
+ .filter(|s| !s.is_empty())
214
+ .filter_map(|line| {
215
+ let parts: Vec<&str> = line.split(',').collect();
216
+ if parts.len() == 2 {
217
+ Some((parts[0].to_string(), parts[1].to_string()))
218
+ } else {
219
+ None
220
+ }
221
+ })
222
+ .collect()
223
+ } else {
224
+ std::collections::HashMap::new()
225
+ };
226
+
227
+ // 为新 token 生成 checksum
228
+ for token in tokens {
229
+ if !token_map.contains_key(&token) {
230
+ let checksum = cursor_api::generate_checksum(
231
+ &cursor_api::generate_hash(),
232
+ Some(&cursor_api::generate_hash()),
233
+ );
234
+ token_map.insert(token, checksum);
235
+ }
236
+ }
237
+
238
+ // 更新 token-list 文件
239
+ let token_list_content = token_map
240
+ .iter()
241
+ .map(|(token, checksum)| format!("{},{}", token, checksum))
242
+ .collect::<Vec<_>>()
243
+ .join("\n");
244
+ std::fs::write(token_list_file, token_list_content).unwrap();
245
+
246
+ // 转换为 TokenInfo vector
247
+ token_map
248
+ .into_iter()
249
+ .map(|(token, checksum)| TokenInfo { token, checksum })
250
+ .collect()
251
+ }
252
+
253
+ // 根路由处理
254
+ async fn handle_root(State(state): State<Arc<Mutex<AppState>>>) -> Json<serde_json::Value> {
255
+ let state = state.lock().await;
256
+ let uptime = (Local::now() - state.start_time).num_seconds();
257
+
258
+ Json(serde_json::json!({
259
+ "status": "healthy",
260
+ "version": state.version,
261
+ "uptime": uptime,
262
+ "stats": {
263
+ "started": state.start_time,
264
+ "totalRequests": state.total_requests,
265
+ "activeRequests": state.active_requests,
266
+ "memory": {
267
+ "heapTotal": 0,
268
+ "heapUsed": 0,
269
+ "rss": 0
270
+ }
271
+ },
272
+ "models": AVAILABLE_MODELS.iter().map(|m| &m.id).collect::<Vec<_>>(),
273
+ "endpoints": [
274
+ &format!("{}/v1/chat/completions", state.route_prefix),
275
+ &format!("{}/v1/models", state.route_prefix),
276
+ "/checksum",
277
+ "/tokeninfo",
278
+ "/update-tokeninfo",
279
+ "/get-tokeninfo"
280
+ ]
281
+ }))
282
+ }
283
+
284
+ async fn handle_tokeninfo_page() -> impl IntoResponse {
285
+ Response::builder()
286
+ .header("Content-Type", "text/html")
287
+ .body(include_str!("../static/tokeninfo.min.html").to_string())
288
+ .unwrap()
289
+ }
290
+
291
+ // 模型列表处理
292
+ async fn handle_models() -> Json<serde_json::Value> {
293
+ Json(serde_json::json!({
294
+ "object": "list",
295
+ "data": AVAILABLE_MODELS.to_vec()
296
+ }))
297
+ }
298
+
299
+ // Checksum 处理
300
+ async fn handle_checksum() -> Json<serde_json::Value> {
301
+ let checksum = cursor_api::generate_checksum(
302
+ &cursor_api::generate_hash(),
303
+ Some(&cursor_api::generate_hash()),
304
+ );
305
+ Json(serde_json::json!({
306
+ "checksum": checksum
307
+ }))
308
+ }
309
+
310
+ // 更新 TokenInfo 处理
311
+ async fn handle_update_tokeninfo(
312
+ State(state): State<Arc<Mutex<AppState>>>,
313
+ ) -> Json<serde_json::Value> {
314
+ // 获取当前的 token 文件路径
315
+ let token_file = std::env::var("TOKEN_FILE").unwrap_or_else(|_| ".token".to_string());
316
+
317
+ // 重新加载 tokens
318
+ let token_infos = load_tokens(&token_file);
319
+
320
+ // 更新应用状态
321
+ {
322
+ let mut state = state.lock().await;
323
+ state.token_infos = token_infos;
324
+ }
325
+
326
+ Json(serde_json::json!({
327
+ "status": "success",
328
+ "message": "Token list has been reloaded"
329
+ }))
330
+ }
331
+
332
+ // 获取 TokenInfo 处理
333
+ async fn handle_get_tokeninfo(
334
+ State(_state): State<Arc<Mutex<AppState>>>,
335
+ headers: HeaderMap,
336
+ ) -> Result<Json<serde_json::Value>, StatusCode> {
337
+ // 验证 AUTH_TOKEN
338
+ let auth_header = headers
339
+ .get("authorization")
340
+ .and_then(|h| h.to_str().ok())
341
+ .and_then(|h| h.strip_prefix("Bearer "))
342
+ .ok_or(StatusCode::UNAUTHORIZED)?;
343
+
344
+ let env_token = std::env::var("AUTH_TOKEN").map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
345
+
346
+ if auth_header != env_token {
347
+ return Err(StatusCode::UNAUTHORIZED);
348
+ }
349
+
350
+ // 获取文件路径
351
+ let token_file = std::env::var("TOKEN_FILE").unwrap_or_else(|_| ".token".to_string());
352
+ let token_list_file =
353
+ std::env::var("TOKEN_LIST_FILE").unwrap_or_else(|_| ".token-list".to_string());
354
+
355
+ // 读取文件内容
356
+ let tokens = std::fs::read_to_string(&token_file).unwrap_or_else(|_| String::new());
357
+ let token_list = std::fs::read_to_string(&token_list_file).unwrap_or_else(|_| String::new());
358
+
359
+ Ok(Json(serde_json::json!({
360
+ "status": "success",
361
+ "token_file": token_file,
362
+ "token_list_file": token_list_file,
363
+ "tokens": tokens,
364
+ "token_list": token_list
365
+ })))
366
+ }
367
+
368
+ async fn handle_update_tokeninfo_post(
369
+ State(state): State<Arc<Mutex<AppState>>>,
370
+ headers: HeaderMap,
371
+ Json(request): Json<TokenUpdateRequest>,
372
+ ) -> Result<Json<serde_json::Value>, StatusCode> {
373
+ // 验证 AUTH_TOKEN
374
+ let auth_header = headers
375
+ .get("authorization")
376
+ .and_then(|h| h.to_str().ok())
377
+ .and_then(|h| h.strip_prefix("Bearer "))
378
+ .ok_or(StatusCode::UNAUTHORIZED)?;
379
+
380
+ let env_token = std::env::var("AUTH_TOKEN").map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
381
+
382
+ if auth_header != env_token {
383
+ return Err(StatusCode::UNAUTHORIZED);
384
+ }
385
+
386
+ // 获取文件路径
387
+ let token_file = std::env::var("TOKEN_FILE").unwrap_or_else(|_| ".token".to_string());
388
+ let token_list_file =
389
+ std::env::var("TOKEN_LIST_FILE").unwrap_or_else(|_| ".token-list".to_string());
390
+
391
+ // 写入 .token 文件
392
+ std::fs::write(&token_file, &request.tokens).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
393
+
394
+ // 如果提供了 token_list,则写入
395
+ if let Some(token_list) = request.token_list {
396
+ std::fs::write(&token_list_file, token_list)
397
+ .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
398
+ }
399
+
400
+ // 重新加载 tokens
401
+ let token_infos = load_tokens(&token_file);
402
+ let token_infos_len = token_infos.len();
403
+
404
+ // 更新应用状态
405
+ {
406
+ let mut state = state.lock().await;
407
+ state.token_infos = token_infos;
408
+ }
409
+
410
+ Ok(Json(serde_json::json!({
411
+ "status": "success",
412
+ "message": "Token files have been updated and reloaded",
413
+ "token_file": token_file,
414
+ "token_list_file": token_list_file,
415
+ "token_count": token_infos_len
416
+ })))
417
+ }
418
+
419
+ // 日志处理
420
+ async fn handle_logs(State(state): State<Arc<Mutex<AppState>>>) -> Json<serde_json::Value> {
421
+ let state = state.lock().await;
422
+ Json(serde_json::json!({
423
+ "total": state.request_logs.len(),
424
+ "logs": state.request_logs,
425
+ "timestamp": Utc::now(),
426
+ "status": "success"
427
+ }))
428
+ }
429
+
430
+ // 聊天处理函数的签名
431
+ async fn handle_chat(
432
+ State(state): State<Arc<Mutex<AppState>>>,
433
+ headers: HeaderMap,
434
+ Json(request): Json<ChatRequest>,
435
+ ) -> Result<Response<Body>, (StatusCode, Json<serde_json::Value>)> {
436
+ // 验证模型是否支持
437
+ if !AVAILABLE_MODELS.iter().any(|m| m.id == request.model) {
438
+ return Err((
439
+ StatusCode::BAD_REQUEST,
440
+ Json(ChatError::ModelNotSupported(request.model.clone()).to_json()),
441
+ ));
442
+ }
443
+
444
+ let request_time = Local::now();
445
+
446
+ // 验证请求
447
+ if request.messages.is_empty() {
448
+ return Err((
449
+ StatusCode::BAD_REQUEST,
450
+ Json(ChatError::EmptyMessages.to_json()),
451
+ ));
452
+ }
453
+
454
+ // 验证 O1 模型不支持流式输出
455
+ if request.model.starts_with("o1") && request.stream {
456
+ return Err((
457
+ StatusCode::BAD_REQUEST,
458
+ Json(ChatError::StreamNotSupported(request.model.clone()).to_json()),
459
+ ));
460
+ }
461
+
462
+ // 获取并处理认证令牌
463
+ let auth_token = headers
464
+ .get("authorization")
465
+ .and_then(|h| h.to_str().ok())
466
+ .and_then(|h| h.strip_prefix("Bearer "))
467
+ .ok_or((
468
+ StatusCode::UNAUTHORIZED,
469
+ Json(ChatError::Unauthorized.to_json()),
470
+ ))?;
471
+
472
+ // 验证环境变量中的 AUTH_TOKEN
473
+ if let Ok(env_token) = std::env::var("AUTH_TOKEN") {
474
+ if auth_token != env_token {
475
+ return Err((
476
+ StatusCode::UNAUTHORIZED,
477
+ Json(ChatError::Unauthorized.to_json()),
478
+ ));
479
+ }
480
+ }
481
+
482
+ // 完整的令牌处理逻辑和对应的 checksum
483
+ let (auth_token, checksum) = {
484
+ static CURRENT_KEY_INDEX: AtomicUsize = AtomicUsize::new(0);
485
+ let state_guard = state.lock().await;
486
+ let token_infos = &state_guard.token_infos;
487
+
488
+ if token_infos.is_empty() {
489
+ return Err((
490
+ StatusCode::SERVICE_UNAVAILABLE,
491
+ Json(ChatError::NoTokens.to_json()),
492
+ ));
493
+ }
494
+
495
+ let index = CURRENT_KEY_INDEX.fetch_add(1, Ordering::SeqCst) % token_infos.len();
496
+ let token_info = &token_infos[index];
497
+ (token_info.token.clone(), token_info.checksum.clone())
498
+ };
499
+
500
+ // 更新请求日志
501
+ {
502
+ let mut state = state.lock().await;
503
+ state.total_requests += 1;
504
+ state.active_requests += 1;
505
+ state.request_logs.push(RequestLog {
506
+ timestamp: request_time,
507
+ model: request.model.clone(),
508
+ checksum: checksum.clone(),
509
+ auth_token: auth_token.clone(),
510
+ stream: request.stream,
511
+ });
512
+
513
+ if state.request_logs.len() > 100 {
514
+ state.request_logs.remove(0);
515
+ }
516
+ }
517
+
518
+ // 消息转换
519
+ let chat_inputs: Vec<cursor_api::ChatInput> = request
520
+ .messages
521
+ .into_iter()
522
+ .map(|m| cursor_api::ChatInput {
523
+ role: m.role,
524
+ content: m.content,
525
+ })
526
+ .collect();
527
+
528
+ // 将消息转换为hex格式
529
+ let hex_data = cursor_api::encode_chat_message(chat_inputs, &request.model)
530
+ .await
531
+ .map_err(|_| {
532
+ (
533
+ StatusCode::INTERNAL_SERVER_ERROR,
534
+ Json(
535
+ ChatError::RequestFailed("Failed to encode chat message".to_string()).to_json(),
536
+ ),
537
+ )
538
+ })?;
539
+
540
+ // 构建请求客户端
541
+ let client = Client::new();
542
+ let request_id = Uuid::new_v4().to_string();
543
+ let response = client
544
+ .post("https://api2.cursor.sh/aiserver.v1.AiService/StreamChat")
545
+ .header("Content-Type", "application/connect+proto")
546
+ .header("Authorization", format!("Bearer {}", auth_token))
547
+ .header("connect-accept-encoding", "gzip,br")
548
+ .header("connect-protocol-version", "1")
549
+ .header("user-agent", "connect-es/1.4.0")
550
+ .header("x-amzn-trace-id", format!("Root={}", &request_id))
551
+ .header("x-cursor-checksum", &checksum)
552
+ .header("x-cursor-client-version", "0.42.5")
553
+ .header("x-cursor-timezone", "Asia/Shanghai")
554
+ .header("x-ghost-mode", "false")
555
+ .header("x-request-id", &request_id)
556
+ .header("Host", "api2.cursor.sh")
557
+ .body(hex_data)
558
+ .send()
559
+ .await
560
+ .map_err(|e| {
561
+ (
562
+ StatusCode::INTERNAL_SERVER_ERROR,
563
+ Json(ChatError::RequestFailed(format!("Request failed: {}", e)).to_json()),
564
+ )
565
+ })?;
566
+
567
+ // 释放活动请求计数
568
+ {
569
+ let mut state = state.lock().await;
570
+ state.active_requests -= 1;
571
+ }
572
+
573
+ if request.stream {
574
+ let response_id = format!("chatcmpl-{}", Uuid::new_v4());
575
+
576
+ let stream = response.bytes_stream().then(move |chunk| {
577
+ let response_id = response_id.clone();
578
+ let model = request.model.clone();
579
+
580
+ async move {
581
+ let chunk = chunk.unwrap_or_default();
582
+ let text = cursor_api::decode_response(&chunk).await;
583
+
584
+ if text.is_empty() {
585
+ return Ok::<_, Infallible>(Bytes::from("[DONE]"));
586
+ }
587
+
588
+ let data = serde_json::json!({
589
+ "id": &response_id,
590
+ "object": "chat.completion.chunk",
591
+ "created": chrono::Utc::now().timestamp(),
592
+ "model": model,
593
+ "choices": [{
594
+ "index": 0,
595
+ "delta": {
596
+ "content": text
597
+ }
598
+ }]
599
+ });
600
+
601
+ Ok::<_, Infallible>(Bytes::from(format!("data: {}\n\n", data.to_string())))
602
+ }
603
+ });
604
+
605
+ Ok(Response::builder()
606
+ .header("Content-Type", "text/event-stream")
607
+ .header("Cache-Control", "no-cache")
608
+ .header("Connection", "keep-alive")
609
+ .body(Body::from_stream(stream))
610
+ .unwrap())
611
+ } else {
612
+ // 非流式响应
613
+ let mut full_text = String::new();
614
+ let mut stream = response.bytes_stream();
615
+
616
+ while let Some(chunk) = stream.next().await {
617
+ let chunk = chunk.map_err(|e| {
618
+ (
619
+ StatusCode::INTERNAL_SERVER_ERROR,
620
+ Json(
621
+ ChatError::RequestFailed(format!("Failed to read response chunk: {}", e))
622
+ .to_json(),
623
+ ),
624
+ )
625
+ })?;
626
+ full_text.push_str(&cursor_api::decode_response(&chunk).await);
627
+ }
628
+
629
+ // 处理文本
630
+ full_text = full_text
631
+ .replace(
632
+ regex::Regex::new(r"^.*<\|END_USER\|>").unwrap().as_str(),
633
+ "",
634
+ )
635
+ .replace(regex::Regex::new(r"^\n[a-zA-Z]?").unwrap().as_str(), "")
636
+ .trim()
637
+ .to_string();
638
+
639
+ let response_data = serde_json::json!({
640
+ "id": format!("chatcmpl-{}", Uuid::new_v4()),
641
+ "object": "chat.completion",
642
+ "created": chrono::Utc::now().timestamp(),
643
+ "model": request.model,
644
+ "choices": [{
645
+ "index": 0,
646
+ "message": {
647
+ "role": "assistant",
648
+ "content": full_text
649
+ },
650
+ "finish_reason": "stop"
651
+ }],
652
+ "usage": {
653
+ "prompt_tokens": 0,
654
+ "completion_tokens": 0,
655
+ "total_tokens": 0
656
+ }
657
+ });
658
+
659
+ Ok(Response::new(Body::from(response_data.to_string())))
660
+ }
661
+ }
src/message.proto ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ syntax = "proto3";
2
+
3
+ package cursor;
4
+
5
+ message ChatMessage {
6
+ message FileContent {
7
+ message Position {
8
+ int32 line = 1;
9
+ int32 column = 2;
10
+ }
11
+ message Range {
12
+ Position start = 1;
13
+ Position end = 2;
14
+ }
15
+
16
+ string filename = 1;
17
+ string content = 2;
18
+ Position position = 3;
19
+ string language = 5;
20
+ Range range = 6;
21
+ int32 length = 8;
22
+ int32 type = 9;
23
+ int32 error_code = 11;
24
+ }
25
+
26
+ message Message {
27
+ string content = 1;
28
+ int32 role = 2;
29
+ string message_id = 13;
30
+ }
31
+
32
+ message Instructions {
33
+ string content = 1;
34
+ }
35
+
36
+ message Model {
37
+ string name = 1;
38
+ string empty = 4;
39
+ }
40
+
41
+ // repeated FileContent files = 1;
42
+ repeated Message messages = 2;
43
+ Instructions instructions = 4;
44
+ string projectPath = 5;
45
+ Model model = 7;
46
+ string requestId = 9;
47
+ string summary = 11; // 或许是空的,描述会话做了什么事情,但是不是标题 或许可以当作额外的设定来用
48
+ string conversationId = 15; // 又来一个uuid
49
+ }
50
+
51
+ message ResMessage {
52
+ string msg = 1;
53
+ }
src/models.rs ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use std::sync::LazyLock;
2
+ use crate::Model;
3
+
4
+ const MODEL_OBJECT: &str = "model";
5
+ const ANTHROPIC: &str = "anthropic";
6
+ const CURSOR: &str = "cursor";
7
+ const GOOGLE: &str = "google";
8
+ const OPENAI: &str = "openai";
9
+
10
+ pub static AVAILABLE_MODELS: LazyLock<Vec<Model>> = LazyLock::new(|| {
11
+ vec![
12
+ Model {
13
+ id: "cursor-small".into(),
14
+ created: 1706659200,
15
+ object: MODEL_OBJECT.into(),
16
+ owned_by: CURSOR.into()
17
+ },
18
+ Model {
19
+ id: "claude-3-opus".into(),
20
+ created: 1706659200,
21
+ object: MODEL_OBJECT.into(),
22
+ owned_by: ANTHROPIC.into()
23
+ },
24
+ Model {
25
+ id: "cursor-fast".into(),
26
+ created: 1706659200,
27
+ object: MODEL_OBJECT.into(),
28
+ owned_by: CURSOR.into()
29
+ },
30
+ Model {
31
+ id: "gpt-3.5-turbo".into(),
32
+ created: 1706659200,
33
+ object: MODEL_OBJECT.into(),
34
+ owned_by: OPENAI.into()
35
+ },
36
+ Model {
37
+ id: "gpt-4-turbo-2024-04-09".into(),
38
+ created: 1706659200,
39
+ object: MODEL_OBJECT.into(),
40
+ owned_by: OPENAI.into()
41
+ },
42
+ Model {
43
+ id: "gpt-4".into(),
44
+ created: 1706659200,
45
+ object: MODEL_OBJECT.into(),
46
+ owned_by: OPENAI.into()
47
+ },
48
+ Model {
49
+ id: "gpt-4o-128k".into(),
50
+ created: 1706659200,
51
+ object: MODEL_OBJECT.into(),
52
+ owned_by: OPENAI.into()
53
+ },
54
+ Model {
55
+ id: "gemini-1.5-flash-500k".into(),
56
+ created: 1706659200,
57
+ object: MODEL_OBJECT.into(),
58
+ owned_by: GOOGLE.into()
59
+ },
60
+ Model {
61
+ id: "claude-3-haiku-200k".into(),
62
+ created: 1706659200,
63
+ object: MODEL_OBJECT.into(),
64
+ owned_by: ANTHROPIC.into()
65
+ },
66
+ Model {
67
+ id: "claude-3-5-sonnet-200k".into(),
68
+ created: 1706659200,
69
+ object: MODEL_OBJECT.into(),
70
+ owned_by: ANTHROPIC.into()
71
+ },
72
+ Model {
73
+ id: "claude-3-5-sonnet-20240620".into(),
74
+ created: 1706659200,
75
+ object: MODEL_OBJECT.into(),
76
+ owned_by: ANTHROPIC.into()
77
+ },
78
+ Model {
79
+ id: "claude-3-5-sonnet-20241022".into(),
80
+ created: 1706659200,
81
+ object: MODEL_OBJECT.into(),
82
+ owned_by: ANTHROPIC.into()
83
+ },
84
+ Model {
85
+ id: "gpt-4o-mini".into(),
86
+ created: 1706659200,
87
+ object: MODEL_OBJECT.into(),
88
+ owned_by: OPENAI.into()
89
+ },
90
+ Model {
91
+ id: "o1-mini".into(),
92
+ created: 1706659200,
93
+ object: MODEL_OBJECT.into(),
94
+ owned_by: OPENAI.into()
95
+ },
96
+ Model {
97
+ id: "o1-preview".into(),
98
+ created: 1706659200,
99
+ object: MODEL_OBJECT.into(),
100
+ owned_by: OPENAI.into()
101
+ },
102
+ Model {
103
+ id: "o1".into(),
104
+ created: 1706659200,
105
+ object: MODEL_OBJECT.into(),
106
+ owned_by: OPENAI.into()
107
+ },
108
+ Model {
109
+ id: "claude-3.5-haiku".into(),
110
+ created: 1706659200,
111
+ object: MODEL_OBJECT.into(),
112
+ owned_by: ANTHROPIC.into()
113
+ },
114
+ Model {
115
+ id: "gemini-exp-1206".into(),
116
+ created: 1706659200,
117
+ object: MODEL_OBJECT.into(),
118
+ owned_by: GOOGLE.into()
119
+ },
120
+ Model {
121
+ id: "gemini-2.0-flash-thinking-exp".into(),
122
+ created: 1706659200,
123
+ object: MODEL_OBJECT.into(),
124
+ owned_by: GOOGLE.into()
125
+ },
126
+ Model {
127
+ id: "gemini-2.0-flash-exp".into(),
128
+ created: 1706659200,
129
+ object: MODEL_OBJECT.into(),
130
+ owned_by: GOOGLE.into()
131
+ }
132
+ ]
133
+ });
static/tokeninfo.html ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="zh">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Token 信息管理</title>
8
+ <style>
9
+ body {
10
+ font-family: Arial, sans-serif;
11
+ max-width: 800px;
12
+ margin: 20px auto;
13
+ padding: 0 20px;
14
+ }
15
+
16
+ .container {
17
+ background: #f5f5f5;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ margin-bottom: 20px;
21
+ }
22
+
23
+ .button-group {
24
+ display: flex;
25
+ gap: 10px;
26
+ margin: 10px 0;
27
+ }
28
+
29
+ textarea {
30
+ width: 100%;
31
+ min-height: 150px;
32
+ margin: 10px 0;
33
+ font-family: monospace;
34
+ resize: vertical;
35
+ }
36
+
37
+ button {
38
+ background: #4CAF50;
39
+ color: white;
40
+ padding: 10px 20px;
41
+ border: none;
42
+ border-radius: 4px;
43
+ cursor: pointer;
44
+ }
45
+
46
+ button:hover {
47
+ background: #45a049;
48
+ }
49
+
50
+ button.secondary {
51
+ background: #607D8B;
52
+ }
53
+
54
+ button.secondary:hover {
55
+ background: #546E7A;
56
+ }
57
+
58
+ .error {
59
+ color: red;
60
+ margin: 10px 0;
61
+ }
62
+
63
+ .success {
64
+ color: green;
65
+ margin: 10px 0;
66
+ }
67
+
68
+ #authToken {
69
+ width: 100%;
70
+ padding: 8px;
71
+ margin: 10px 0;
72
+ }
73
+ </style>
74
+ </head>
75
+
76
+ <body>
77
+ <h1>Token 信息管理</h1>
78
+
79
+ <div class="container">
80
+ <h2>认证</h2>
81
+ <input type="password" id="authToken" placeholder="输入 AUTH_TOKEN">
82
+ </div>
83
+
84
+ <div class="container">
85
+ <h2>Token 配置</h2>
86
+ <div class="button-group">
87
+ <button onclick="getTokenInfo()">获取当前配置</button>
88
+ <button onclick="updateTokenInfo()" class="secondary">保存更改</button>
89
+ </div>
90
+
91
+ <h3>Token 文件内容</h3>
92
+ <textarea id="tokens" placeholder="每行一个 token"></textarea>
93
+
94
+ <h3>Token List 文件内容</h3>
95
+ <textarea id="tokenList" placeholder="token,checksum 格式,每行一对"></textarea>
96
+ </div>
97
+
98
+ <div id="message"></div>
99
+
100
+ <script>
101
+ function showMessage(text, isError = false) {
102
+ const msg = document.getElementById('message');
103
+ msg.className = isError ? 'error' : 'success';
104
+ msg.textContent = text;
105
+ }
106
+
107
+ async function getTokenInfo() {
108
+ const authToken = document.getElementById('authToken').value;
109
+ if (!authToken) {
110
+ showMessage('请输入 AUTH_TOKEN', true);
111
+ return;
112
+ }
113
+
114
+ try {
115
+ const response = await fetch('/get-tokeninfo', {
116
+ method: 'POST',
117
+ headers: {
118
+ 'Authorization': `Bearer ${authToken}`
119
+ }
120
+ });
121
+
122
+ if (!response.ok) {
123
+ throw new Error(`HTTP error! status: ${response.status}`);
124
+ }
125
+
126
+ const data = await response.json();
127
+ document.getElementById('tokens').value = data.tokens;
128
+ document.getElementById('tokenList').value = data.token_list;
129
+ showMessage('配置获取成功');
130
+ } catch (error) {
131
+ showMessage(`获取失败: ${error.message}`, true);
132
+ }
133
+ }
134
+
135
+ async function updateTokenInfo() {
136
+ const authToken = document.getElementById('authToken').value;
137
+ const tokens = document.getElementById('tokens').value;
138
+ const tokenList = document.getElementById('tokenList').value;
139
+
140
+ if (!authToken) {
141
+ showMessage('请输入 AUTH_TOKEN', true);
142
+ return;
143
+ }
144
+
145
+ if (!tokens) {
146
+ showMessage('Token 文件内容不能为空', true);
147
+ return;
148
+ }
149
+
150
+ try {
151
+ const response = await fetch('/update-tokeninfo', {
152
+ method: 'POST',
153
+ headers: {
154
+ 'Authorization': `Bearer ${authToken}`,
155
+ 'Content-Type': 'application/json'
156
+ },
157
+ body: JSON.stringify({
158
+ tokens: tokens,
159
+ token_list: tokenList || undefined
160
+ })
161
+ });
162
+
163
+ if (!response.ok) {
164
+ throw new Error(`HTTP error! status: ${response.status}`);
165
+ }
166
+
167
+ const data = await response.json();
168
+ showMessage(`更新成功: ${data.message}`);
169
+ } catch (error) {
170
+ showMessage(`更新失败: ${error.message}`, true);
171
+ }
172
+ }
173
+
174
+ // 快捷键支持
175
+ document.addEventListener('keydown', function (e) {
176
+ if (e.ctrlKey && e.key === 's') {
177
+ e.preventDefault();
178
+ updateTokenInfo();
179
+ }
180
+ });
181
+ </script>
182
+ </body>
183
+
184
+ </html>