+138
.github/workflows/cli.yml
+138
.github/workflows/cli.yml
···
1
+
name: Release CLI Binaries
2
+
3
+
on:
4
+
push:
5
+
tags:
6
+
- 'cli@*'
7
+
workflow_dispatch:
8
+
inputs:
9
+
tag:
10
+
description: 'Tag to release (e.g. cli@1.0.0)'
11
+
required: true
12
+
type: string
13
+
14
+
jobs:
15
+
build:
16
+
name: Build CLI Binaries
17
+
runs-on: ubuntu-latest
18
+
defaults:
19
+
run:
20
+
working-directory: cli
21
+
steps:
22
+
- name: Checkout
23
+
uses: actions/checkout@v4
24
+
25
+
- name: Install Nix
26
+
uses: DeterminateSystems/nix-installer-action@main
27
+
with:
28
+
logger: pretty
29
+
30
+
- name: Setup Nix cache
31
+
uses: DeterminateSystems/magic-nix-cache-action@main
32
+
33
+
- name: Check flake
34
+
run: nix flake check
35
+
36
+
- name: Build Darwin aarch64 only (for testing)
37
+
run: |
38
+
echo "Building for macOS aarch64 only..."
39
+
mkdir -p releases
40
+
nix build .#grain-macos-aarch64 -o result-macos-aarch64
41
+
cp result-macos-aarch64/bin/grain releases/grain-darwin-aarch64
42
+
43
+
- name: Prepare release assets
44
+
run: |
45
+
mkdir -p release-assets
46
+
cp releases/grain-darwin-aarch64 release-assets/
47
+
cp install.sh release-assets/
48
+
49
+
# Create checksums
50
+
cd release-assets
51
+
sha256sum grain-darwin-aarch64 > checksums.txt
52
+
53
+
# List files for verification
54
+
ls -la
55
+
56
+
- name: Get tag name
57
+
id: tag
58
+
run: |
59
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
60
+
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
61
+
else
62
+
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
63
+
fi
64
+
65
+
- name: Create Release
66
+
uses: softprops/action-gh-release@v1
67
+
with:
68
+
tag_name: ${{ steps.tag.outputs.tag }}
69
+
name: Grain CLI ${{ steps.tag.outputs.tag }}
70
+
draft: false
71
+
prerelease: false
72
+
files: |
73
+
cli/release-assets/*
74
+
body: |
75
+
## Grain CLI ${{ steps.tag.outputs.tag }} (Test Build)
76
+
77
+
**Note: This is a test build with only macOS Apple Silicon support.**
78
+
79
+
### Installation
80
+
81
+
Quick install:
82
+
```bash
83
+
curl -L https://github.com/grainsocial/grain/releases/download/${{ steps.tag.outputs.tag }}/install.sh | bash
84
+
```
85
+
86
+
Or download manually:
87
+
88
+
- **macOS Apple Silicon**: `grain-darwin-aarch64`
89
+
90
+
### Usage
91
+
92
+
```bash
93
+
grain login
94
+
grain gallery list
95
+
grain gallery create
96
+
```
97
+
98
+
### Checksums
99
+
100
+
See `checksums.txt` for SHA256 checksums.
101
+
env:
102
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
103
+
104
+
test-install:
105
+
name: Test Installation
106
+
needs: build
107
+
strategy:
108
+
matrix:
109
+
os: [ubuntu-latest, macos-latest]
110
+
runs-on: ${{ matrix.os }}
111
+
steps:
112
+
- name: Checkout
113
+
uses: actions/checkout@v4
114
+
115
+
- name: Get tag name
116
+
id: tag
117
+
run: |
118
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
119
+
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
120
+
else
121
+
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
122
+
fi
123
+
124
+
- name: Test install script
125
+
run: |
126
+
# Wait for release to be available
127
+
sleep 30
128
+
129
+
# Test the install script
130
+
curl -L https://github.com/grainsocial/grain/releases/download/${{ steps.tag.outputs.tag }}/grain-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m) -o grain-test || exit 0
131
+
132
+
if [ -f grain-test ]; then
133
+
chmod +x grain-test
134
+
./grain-test --help
135
+
echo "✅ Binary works correctly"
136
+
else
137
+
echo "⚠️ Binary not available yet for this platform"
138
+
fi
+9
README.md
+9
README.md
···
50
50
- **Tech Stack**: Deno, TypeScript
51
51
- **Features**: Content labeling, moderation tools
52
52
53
+
### 💻 [CLI](/cli)
54
+
55
+
Command-line interface for interacting with Grain Social from the terminal.
56
+
Provides tools for gallery management, photo uploads, and platform interaction.
57
+
58
+
- **Tech Stack**: Rust
59
+
- **Features**: Gallery creation/management, photo uploads, authentication
60
+
- **Installation**: Download from [releases](https://github.com/grainsocial/grain/releases)
61
+
53
62
### 🌐 [Infrastructure](/nginx)
54
63
55
64
Nginx reverse proxy configuration for routing requests between services.
+1
cli/.gitignore
+1
cli/.gitignore
···
1
+
target
+2900
cli/Cargo.lock
+2900
cli/Cargo.lock
···
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.1"
17
+
source = "registry+https://github.com/rust-lang/crates.io-index"
18
+
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
19
+
20
+
[[package]]
21
+
name = "aligned-vec"
22
+
version = "0.6.4"
23
+
source = "registry+https://github.com/rust-lang/crates.io-index"
24
+
checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
25
+
dependencies = [
26
+
"equator",
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 = "anstream"
46
+
version = "0.6.20"
47
+
source = "registry+https://github.com/rust-lang/crates.io-index"
48
+
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
49
+
dependencies = [
50
+
"anstyle",
51
+
"anstyle-parse",
52
+
"anstyle-query",
53
+
"anstyle-wincon",
54
+
"colorchoice",
55
+
"is_terminal_polyfill",
56
+
"utf8parse",
57
+
]
58
+
59
+
[[package]]
60
+
name = "anstyle"
61
+
version = "1.0.11"
62
+
source = "registry+https://github.com/rust-lang/crates.io-index"
63
+
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
64
+
65
+
[[package]]
66
+
name = "anstyle-parse"
67
+
version = "0.2.7"
68
+
source = "registry+https://github.com/rust-lang/crates.io-index"
69
+
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
70
+
dependencies = [
71
+
"utf8parse",
72
+
]
73
+
74
+
[[package]]
75
+
name = "anstyle-query"
76
+
version = "1.1.4"
77
+
source = "registry+https://github.com/rust-lang/crates.io-index"
78
+
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
79
+
dependencies = [
80
+
"windows-sys 0.60.2",
81
+
]
82
+
83
+
[[package]]
84
+
name = "anstyle-wincon"
85
+
version = "3.0.10"
86
+
source = "registry+https://github.com/rust-lang/crates.io-index"
87
+
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
88
+
dependencies = [
89
+
"anstyle",
90
+
"once_cell_polyfill",
91
+
"windows-sys 0.60.2",
92
+
]
93
+
94
+
[[package]]
95
+
name = "anyhow"
96
+
version = "1.0.98"
97
+
source = "registry+https://github.com/rust-lang/crates.io-index"
98
+
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
99
+
100
+
[[package]]
101
+
name = "arbitrary"
102
+
version = "1.4.1"
103
+
source = "registry+https://github.com/rust-lang/crates.io-index"
104
+
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
105
+
106
+
[[package]]
107
+
name = "arg_enum_proc_macro"
108
+
version = "0.3.4"
109
+
source = "registry+https://github.com/rust-lang/crates.io-index"
110
+
checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
111
+
dependencies = [
112
+
"proc-macro2",
113
+
"quote",
114
+
"syn",
115
+
]
116
+
117
+
[[package]]
118
+
name = "arrayvec"
119
+
version = "0.7.6"
120
+
source = "registry+https://github.com/rust-lang/crates.io-index"
121
+
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
122
+
123
+
[[package]]
124
+
name = "atomic-waker"
125
+
version = "1.1.2"
126
+
source = "registry+https://github.com/rust-lang/crates.io-index"
127
+
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
128
+
129
+
[[package]]
130
+
name = "autocfg"
131
+
version = "1.5.0"
132
+
source = "registry+https://github.com/rust-lang/crates.io-index"
133
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
134
+
135
+
[[package]]
136
+
name = "av1-grain"
137
+
version = "0.2.4"
138
+
source = "registry+https://github.com/rust-lang/crates.io-index"
139
+
checksum = "4f3efb2ca85bc610acfa917b5aaa36f3fcbebed5b3182d7f877b02531c4b80c8"
140
+
dependencies = [
141
+
"anyhow",
142
+
"arrayvec",
143
+
"log",
144
+
"nom",
145
+
"num-rational",
146
+
"v_frame",
147
+
]
148
+
149
+
[[package]]
150
+
name = "avif-serialize"
151
+
version = "0.8.5"
152
+
source = "registry+https://github.com/rust-lang/crates.io-index"
153
+
checksum = "2ea8ef51aced2b9191c08197f55450d830876d9933f8f48a429b354f1d496b42"
154
+
dependencies = [
155
+
"arrayvec",
156
+
]
157
+
158
+
[[package]]
159
+
name = "backtrace"
160
+
version = "0.3.75"
161
+
source = "registry+https://github.com/rust-lang/crates.io-index"
162
+
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
163
+
dependencies = [
164
+
"addr2line",
165
+
"cfg-if",
166
+
"libc",
167
+
"miniz_oxide",
168
+
"object",
169
+
"rustc-demangle",
170
+
"windows-targets 0.52.6",
171
+
]
172
+
173
+
[[package]]
174
+
name = "base64"
175
+
version = "0.22.1"
176
+
source = "registry+https://github.com/rust-lang/crates.io-index"
177
+
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
178
+
179
+
[[package]]
180
+
name = "bit_field"
181
+
version = "0.10.2"
182
+
source = "registry+https://github.com/rust-lang/crates.io-index"
183
+
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
184
+
185
+
[[package]]
186
+
name = "bitflags"
187
+
version = "1.3.2"
188
+
source = "registry+https://github.com/rust-lang/crates.io-index"
189
+
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
190
+
191
+
[[package]]
192
+
name = "bitflags"
193
+
version = "2.9.1"
194
+
source = "registry+https://github.com/rust-lang/crates.io-index"
195
+
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
196
+
197
+
[[package]]
198
+
name = "bitstream-io"
199
+
version = "2.6.0"
200
+
source = "registry+https://github.com/rust-lang/crates.io-index"
201
+
checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2"
202
+
203
+
[[package]]
204
+
name = "built"
205
+
version = "0.7.7"
206
+
source = "registry+https://github.com/rust-lang/crates.io-index"
207
+
checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b"
208
+
209
+
[[package]]
210
+
name = "bumpalo"
211
+
version = "3.19.0"
212
+
source = "registry+https://github.com/rust-lang/crates.io-index"
213
+
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
214
+
215
+
[[package]]
216
+
name = "bytemuck"
217
+
version = "1.23.1"
218
+
source = "registry+https://github.com/rust-lang/crates.io-index"
219
+
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
220
+
221
+
[[package]]
222
+
name = "byteorder-lite"
223
+
version = "0.1.0"
224
+
source = "registry+https://github.com/rust-lang/crates.io-index"
225
+
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
226
+
227
+
[[package]]
228
+
name = "bytes"
229
+
version = "1.10.1"
230
+
source = "registry+https://github.com/rust-lang/crates.io-index"
231
+
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
232
+
233
+
[[package]]
234
+
name = "cc"
235
+
version = "1.2.31"
236
+
source = "registry+https://github.com/rust-lang/crates.io-index"
237
+
checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
238
+
dependencies = [
239
+
"jobserver",
240
+
"libc",
241
+
"shlex",
242
+
]
243
+
244
+
[[package]]
245
+
name = "cfg-expr"
246
+
version = "0.15.8"
247
+
source = "registry+https://github.com/rust-lang/crates.io-index"
248
+
checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
249
+
dependencies = [
250
+
"smallvec",
251
+
"target-lexicon",
252
+
]
253
+
254
+
[[package]]
255
+
name = "cfg-if"
256
+
version = "1.0.1"
257
+
source = "registry+https://github.com/rust-lang/crates.io-index"
258
+
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
259
+
260
+
[[package]]
261
+
name = "chrono"
262
+
version = "0.4.41"
263
+
source = "registry+https://github.com/rust-lang/crates.io-index"
264
+
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
265
+
dependencies = [
266
+
"android-tzdata",
267
+
"iana-time-zone",
268
+
"js-sys",
269
+
"num-traits",
270
+
"serde",
271
+
"wasm-bindgen",
272
+
"windows-link",
273
+
]
274
+
275
+
[[package]]
276
+
name = "clap"
277
+
version = "4.5.42"
278
+
source = "registry+https://github.com/rust-lang/crates.io-index"
279
+
checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
280
+
dependencies = [
281
+
"clap_builder",
282
+
"clap_derive",
283
+
]
284
+
285
+
[[package]]
286
+
name = "clap_builder"
287
+
version = "4.5.42"
288
+
source = "registry+https://github.com/rust-lang/crates.io-index"
289
+
checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
290
+
dependencies = [
291
+
"anstream",
292
+
"anstyle",
293
+
"clap_lex",
294
+
"strsim",
295
+
]
296
+
297
+
[[package]]
298
+
name = "clap_derive"
299
+
version = "4.5.41"
300
+
source = "registry+https://github.com/rust-lang/crates.io-index"
301
+
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
302
+
dependencies = [
303
+
"heck",
304
+
"proc-macro2",
305
+
"quote",
306
+
"syn",
307
+
]
308
+
309
+
[[package]]
310
+
name = "clap_lex"
311
+
version = "0.7.5"
312
+
source = "registry+https://github.com/rust-lang/crates.io-index"
313
+
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
314
+
315
+
[[package]]
316
+
name = "color_quant"
317
+
version = "1.1.0"
318
+
source = "registry+https://github.com/rust-lang/crates.io-index"
319
+
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
320
+
321
+
[[package]]
322
+
name = "colorchoice"
323
+
version = "1.0.4"
324
+
source = "registry+https://github.com/rust-lang/crates.io-index"
325
+
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
326
+
327
+
[[package]]
328
+
name = "console"
329
+
version = "0.15.11"
330
+
source = "registry+https://github.com/rust-lang/crates.io-index"
331
+
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
332
+
dependencies = [
333
+
"encode_unicode",
334
+
"libc",
335
+
"once_cell",
336
+
"unicode-width",
337
+
"windows-sys 0.59.0",
338
+
]
339
+
340
+
[[package]]
341
+
name = "console"
342
+
version = "0.16.0"
343
+
source = "registry+https://github.com/rust-lang/crates.io-index"
344
+
checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d"
345
+
dependencies = [
346
+
"encode_unicode",
347
+
"libc",
348
+
"once_cell",
349
+
"unicode-width",
350
+
"windows-sys 0.60.2",
351
+
]
352
+
353
+
[[package]]
354
+
name = "core-foundation"
355
+
version = "0.9.4"
356
+
source = "registry+https://github.com/rust-lang/crates.io-index"
357
+
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
358
+
dependencies = [
359
+
"core-foundation-sys",
360
+
"libc",
361
+
]
362
+
363
+
[[package]]
364
+
name = "core-foundation-sys"
365
+
version = "0.8.7"
366
+
source = "registry+https://github.com/rust-lang/crates.io-index"
367
+
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
368
+
369
+
[[package]]
370
+
name = "crc32fast"
371
+
version = "1.5.0"
372
+
source = "registry+https://github.com/rust-lang/crates.io-index"
373
+
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
374
+
dependencies = [
375
+
"cfg-if",
376
+
]
377
+
378
+
[[package]]
379
+
name = "crossbeam-deque"
380
+
version = "0.8.6"
381
+
source = "registry+https://github.com/rust-lang/crates.io-index"
382
+
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
383
+
dependencies = [
384
+
"crossbeam-epoch",
385
+
"crossbeam-utils",
386
+
]
387
+
388
+
[[package]]
389
+
name = "crossbeam-epoch"
390
+
version = "0.9.18"
391
+
source = "registry+https://github.com/rust-lang/crates.io-index"
392
+
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
393
+
dependencies = [
394
+
"crossbeam-utils",
395
+
]
396
+
397
+
[[package]]
398
+
name = "crossbeam-utils"
399
+
version = "0.8.21"
400
+
source = "registry+https://github.com/rust-lang/crates.io-index"
401
+
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
402
+
403
+
[[package]]
404
+
name = "crunchy"
405
+
version = "0.2.4"
406
+
source = "registry+https://github.com/rust-lang/crates.io-index"
407
+
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
408
+
409
+
[[package]]
410
+
name = "dialoguer"
411
+
version = "0.11.0"
412
+
source = "registry+https://github.com/rust-lang/crates.io-index"
413
+
checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de"
414
+
dependencies = [
415
+
"console 0.15.11",
416
+
"shell-words",
417
+
"tempfile",
418
+
"thiserror 1.0.69",
419
+
"zeroize",
420
+
]
421
+
422
+
[[package]]
423
+
name = "dirs"
424
+
version = "6.0.0"
425
+
source = "registry+https://github.com/rust-lang/crates.io-index"
426
+
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
427
+
dependencies = [
428
+
"dirs-sys",
429
+
]
430
+
431
+
[[package]]
432
+
name = "dirs-sys"
433
+
version = "0.5.0"
434
+
source = "registry+https://github.com/rust-lang/crates.io-index"
435
+
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
436
+
dependencies = [
437
+
"libc",
438
+
"option-ext",
439
+
"redox_users",
440
+
"windows-sys 0.60.2",
441
+
]
442
+
443
+
[[package]]
444
+
name = "displaydoc"
445
+
version = "0.2.5"
446
+
source = "registry+https://github.com/rust-lang/crates.io-index"
447
+
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
448
+
dependencies = [
449
+
"proc-macro2",
450
+
"quote",
451
+
"syn",
452
+
]
453
+
454
+
[[package]]
455
+
name = "either"
456
+
version = "1.15.0"
457
+
source = "registry+https://github.com/rust-lang/crates.io-index"
458
+
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
459
+
460
+
[[package]]
461
+
name = "encode_unicode"
462
+
version = "1.0.0"
463
+
source = "registry+https://github.com/rust-lang/crates.io-index"
464
+
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
465
+
466
+
[[package]]
467
+
name = "encoding_rs"
468
+
version = "0.8.35"
469
+
source = "registry+https://github.com/rust-lang/crates.io-index"
470
+
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
471
+
dependencies = [
472
+
"cfg-if",
473
+
]
474
+
475
+
[[package]]
476
+
name = "equator"
477
+
version = "0.4.2"
478
+
source = "registry+https://github.com/rust-lang/crates.io-index"
479
+
checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
480
+
dependencies = [
481
+
"equator-macro",
482
+
]
483
+
484
+
[[package]]
485
+
name = "equator-macro"
486
+
version = "0.4.2"
487
+
source = "registry+https://github.com/rust-lang/crates.io-index"
488
+
checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
489
+
dependencies = [
490
+
"proc-macro2",
491
+
"quote",
492
+
"syn",
493
+
]
494
+
495
+
[[package]]
496
+
name = "equivalent"
497
+
version = "1.0.2"
498
+
source = "registry+https://github.com/rust-lang/crates.io-index"
499
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
500
+
501
+
[[package]]
502
+
name = "errno"
503
+
version = "0.3.13"
504
+
source = "registry+https://github.com/rust-lang/crates.io-index"
505
+
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
506
+
dependencies = [
507
+
"libc",
508
+
"windows-sys 0.60.2",
509
+
]
510
+
511
+
[[package]]
512
+
name = "exr"
513
+
version = "1.73.0"
514
+
source = "registry+https://github.com/rust-lang/crates.io-index"
515
+
checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0"
516
+
dependencies = [
517
+
"bit_field",
518
+
"half",
519
+
"lebe",
520
+
"miniz_oxide",
521
+
"rayon-core",
522
+
"smallvec",
523
+
"zune-inflate",
524
+
]
525
+
526
+
[[package]]
527
+
name = "fastrand"
528
+
version = "2.3.0"
529
+
source = "registry+https://github.com/rust-lang/crates.io-index"
530
+
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
531
+
532
+
[[package]]
533
+
name = "fdeflate"
534
+
version = "0.3.7"
535
+
source = "registry+https://github.com/rust-lang/crates.io-index"
536
+
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
537
+
dependencies = [
538
+
"simd-adler32",
539
+
]
540
+
541
+
[[package]]
542
+
name = "flate2"
543
+
version = "1.1.2"
544
+
source = "registry+https://github.com/rust-lang/crates.io-index"
545
+
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
546
+
dependencies = [
547
+
"crc32fast",
548
+
"miniz_oxide",
549
+
]
550
+
551
+
[[package]]
552
+
name = "fnv"
553
+
version = "1.0.7"
554
+
source = "registry+https://github.com/rust-lang/crates.io-index"
555
+
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
556
+
557
+
[[package]]
558
+
name = "foreign-types"
559
+
version = "0.3.2"
560
+
source = "registry+https://github.com/rust-lang/crates.io-index"
561
+
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
562
+
dependencies = [
563
+
"foreign-types-shared",
564
+
]
565
+
566
+
[[package]]
567
+
name = "foreign-types-shared"
568
+
version = "0.1.1"
569
+
source = "registry+https://github.com/rust-lang/crates.io-index"
570
+
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
571
+
572
+
[[package]]
573
+
name = "form_urlencoded"
574
+
version = "1.2.1"
575
+
source = "registry+https://github.com/rust-lang/crates.io-index"
576
+
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
577
+
dependencies = [
578
+
"percent-encoding",
579
+
]
580
+
581
+
[[package]]
582
+
name = "futures-channel"
583
+
version = "0.3.31"
584
+
source = "registry+https://github.com/rust-lang/crates.io-index"
585
+
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
586
+
dependencies = [
587
+
"futures-core",
588
+
]
589
+
590
+
[[package]]
591
+
name = "futures-core"
592
+
version = "0.3.31"
593
+
source = "registry+https://github.com/rust-lang/crates.io-index"
594
+
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
595
+
596
+
[[package]]
597
+
name = "futures-macro"
598
+
version = "0.3.31"
599
+
source = "registry+https://github.com/rust-lang/crates.io-index"
600
+
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
601
+
dependencies = [
602
+
"proc-macro2",
603
+
"quote",
604
+
"syn",
605
+
]
606
+
607
+
[[package]]
608
+
name = "futures-sink"
609
+
version = "0.3.31"
610
+
source = "registry+https://github.com/rust-lang/crates.io-index"
611
+
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
612
+
613
+
[[package]]
614
+
name = "futures-task"
615
+
version = "0.3.31"
616
+
source = "registry+https://github.com/rust-lang/crates.io-index"
617
+
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
618
+
619
+
[[package]]
620
+
name = "futures-util"
621
+
version = "0.3.31"
622
+
source = "registry+https://github.com/rust-lang/crates.io-index"
623
+
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
624
+
dependencies = [
625
+
"futures-core",
626
+
"futures-macro",
627
+
"futures-task",
628
+
"pin-project-lite",
629
+
"pin-utils",
630
+
"slab",
631
+
]
632
+
633
+
[[package]]
634
+
name = "getrandom"
635
+
version = "0.2.16"
636
+
source = "registry+https://github.com/rust-lang/crates.io-index"
637
+
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
638
+
dependencies = [
639
+
"cfg-if",
640
+
"libc",
641
+
"wasi 0.11.1+wasi-snapshot-preview1",
642
+
]
643
+
644
+
[[package]]
645
+
name = "getrandom"
646
+
version = "0.3.3"
647
+
source = "registry+https://github.com/rust-lang/crates.io-index"
648
+
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
649
+
dependencies = [
650
+
"cfg-if",
651
+
"libc",
652
+
"r-efi",
653
+
"wasi 0.14.2+wasi-0.2.4",
654
+
]
655
+
656
+
[[package]]
657
+
name = "gif"
658
+
version = "0.13.3"
659
+
source = "registry+https://github.com/rust-lang/crates.io-index"
660
+
checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b"
661
+
dependencies = [
662
+
"color_quant",
663
+
"weezl",
664
+
]
665
+
666
+
[[package]]
667
+
name = "gimli"
668
+
version = "0.31.1"
669
+
source = "registry+https://github.com/rust-lang/crates.io-index"
670
+
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
671
+
672
+
[[package]]
673
+
name = "grain-cli"
674
+
version = "0.1.0"
675
+
dependencies = [
676
+
"anyhow",
677
+
"chrono",
678
+
"clap",
679
+
"dialoguer",
680
+
"dirs",
681
+
"futures-util",
682
+
"http-body-util",
683
+
"hyper",
684
+
"hyper-util",
685
+
"image",
686
+
"indicatif",
687
+
"open",
688
+
"reqwest",
689
+
"serde",
690
+
"serde_json",
691
+
"tokio",
692
+
"tokio-util",
693
+
"url",
694
+
"urlencoding",
695
+
]
696
+
697
+
[[package]]
698
+
name = "h2"
699
+
version = "0.4.11"
700
+
source = "registry+https://github.com/rust-lang/crates.io-index"
701
+
checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785"
702
+
dependencies = [
703
+
"atomic-waker",
704
+
"bytes",
705
+
"fnv",
706
+
"futures-core",
707
+
"futures-sink",
708
+
"http",
709
+
"indexmap",
710
+
"slab",
711
+
"tokio",
712
+
"tokio-util",
713
+
"tracing",
714
+
]
715
+
716
+
[[package]]
717
+
name = "half"
718
+
version = "2.6.0"
719
+
source = "registry+https://github.com/rust-lang/crates.io-index"
720
+
checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
721
+
dependencies = [
722
+
"cfg-if",
723
+
"crunchy",
724
+
]
725
+
726
+
[[package]]
727
+
name = "hashbrown"
728
+
version = "0.15.4"
729
+
source = "registry+https://github.com/rust-lang/crates.io-index"
730
+
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
731
+
732
+
[[package]]
733
+
name = "heck"
734
+
version = "0.5.0"
735
+
source = "registry+https://github.com/rust-lang/crates.io-index"
736
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
737
+
738
+
[[package]]
739
+
name = "http"
740
+
version = "1.3.1"
741
+
source = "registry+https://github.com/rust-lang/crates.io-index"
742
+
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
743
+
dependencies = [
744
+
"bytes",
745
+
"fnv",
746
+
"itoa",
747
+
]
748
+
749
+
[[package]]
750
+
name = "http-body"
751
+
version = "1.0.1"
752
+
source = "registry+https://github.com/rust-lang/crates.io-index"
753
+
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
754
+
dependencies = [
755
+
"bytes",
756
+
"http",
757
+
]
758
+
759
+
[[package]]
760
+
name = "http-body-util"
761
+
version = "0.1.3"
762
+
source = "registry+https://github.com/rust-lang/crates.io-index"
763
+
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
764
+
dependencies = [
765
+
"bytes",
766
+
"futures-core",
767
+
"http",
768
+
"http-body",
769
+
"pin-project-lite",
770
+
]
771
+
772
+
[[package]]
773
+
name = "httparse"
774
+
version = "1.10.1"
775
+
source = "registry+https://github.com/rust-lang/crates.io-index"
776
+
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
777
+
778
+
[[package]]
779
+
name = "httpdate"
780
+
version = "1.0.3"
781
+
source = "registry+https://github.com/rust-lang/crates.io-index"
782
+
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
783
+
784
+
[[package]]
785
+
name = "hyper"
786
+
version = "1.6.0"
787
+
source = "registry+https://github.com/rust-lang/crates.io-index"
788
+
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
789
+
dependencies = [
790
+
"bytes",
791
+
"futures-channel",
792
+
"futures-util",
793
+
"h2",
794
+
"http",
795
+
"http-body",
796
+
"httparse",
797
+
"httpdate",
798
+
"itoa",
799
+
"pin-project-lite",
800
+
"smallvec",
801
+
"tokio",
802
+
"want",
803
+
]
804
+
805
+
[[package]]
806
+
name = "hyper-rustls"
807
+
version = "0.27.7"
808
+
source = "registry+https://github.com/rust-lang/crates.io-index"
809
+
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
810
+
dependencies = [
811
+
"http",
812
+
"hyper",
813
+
"hyper-util",
814
+
"rustls",
815
+
"rustls-pki-types",
816
+
"tokio",
817
+
"tokio-rustls",
818
+
"tower-service",
819
+
]
820
+
821
+
[[package]]
822
+
name = "hyper-tls"
823
+
version = "0.6.0"
824
+
source = "registry+https://github.com/rust-lang/crates.io-index"
825
+
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
826
+
dependencies = [
827
+
"bytes",
828
+
"http-body-util",
829
+
"hyper",
830
+
"hyper-util",
831
+
"native-tls",
832
+
"tokio",
833
+
"tokio-native-tls",
834
+
"tower-service",
835
+
]
836
+
837
+
[[package]]
838
+
name = "hyper-util"
839
+
version = "0.1.16"
840
+
source = "registry+https://github.com/rust-lang/crates.io-index"
841
+
checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
842
+
dependencies = [
843
+
"base64",
844
+
"bytes",
845
+
"futures-channel",
846
+
"futures-core",
847
+
"futures-util",
848
+
"http",
849
+
"http-body",
850
+
"hyper",
851
+
"ipnet",
852
+
"libc",
853
+
"percent-encoding",
854
+
"pin-project-lite",
855
+
"socket2",
856
+
"system-configuration",
857
+
"tokio",
858
+
"tower-service",
859
+
"tracing",
860
+
"windows-registry",
861
+
]
862
+
863
+
[[package]]
864
+
name = "iana-time-zone"
865
+
version = "0.1.63"
866
+
source = "registry+https://github.com/rust-lang/crates.io-index"
867
+
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
868
+
dependencies = [
869
+
"android_system_properties",
870
+
"core-foundation-sys",
871
+
"iana-time-zone-haiku",
872
+
"js-sys",
873
+
"log",
874
+
"wasm-bindgen",
875
+
"windows-core",
876
+
]
877
+
878
+
[[package]]
879
+
name = "iana-time-zone-haiku"
880
+
version = "0.1.2"
881
+
source = "registry+https://github.com/rust-lang/crates.io-index"
882
+
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
883
+
dependencies = [
884
+
"cc",
885
+
]
886
+
887
+
[[package]]
888
+
name = "icu_collections"
889
+
version = "2.0.0"
890
+
source = "registry+https://github.com/rust-lang/crates.io-index"
891
+
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
892
+
dependencies = [
893
+
"displaydoc",
894
+
"potential_utf",
895
+
"yoke",
896
+
"zerofrom",
897
+
"zerovec",
898
+
]
899
+
900
+
[[package]]
901
+
name = "icu_locale_core"
902
+
version = "2.0.0"
903
+
source = "registry+https://github.com/rust-lang/crates.io-index"
904
+
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
905
+
dependencies = [
906
+
"displaydoc",
907
+
"litemap",
908
+
"tinystr",
909
+
"writeable",
910
+
"zerovec",
911
+
]
912
+
913
+
[[package]]
914
+
name = "icu_normalizer"
915
+
version = "2.0.0"
916
+
source = "registry+https://github.com/rust-lang/crates.io-index"
917
+
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
918
+
dependencies = [
919
+
"displaydoc",
920
+
"icu_collections",
921
+
"icu_normalizer_data",
922
+
"icu_properties",
923
+
"icu_provider",
924
+
"smallvec",
925
+
"zerovec",
926
+
]
927
+
928
+
[[package]]
929
+
name = "icu_normalizer_data"
930
+
version = "2.0.0"
931
+
source = "registry+https://github.com/rust-lang/crates.io-index"
932
+
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
933
+
934
+
[[package]]
935
+
name = "icu_properties"
936
+
version = "2.0.1"
937
+
source = "registry+https://github.com/rust-lang/crates.io-index"
938
+
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
939
+
dependencies = [
940
+
"displaydoc",
941
+
"icu_collections",
942
+
"icu_locale_core",
943
+
"icu_properties_data",
944
+
"icu_provider",
945
+
"potential_utf",
946
+
"zerotrie",
947
+
"zerovec",
948
+
]
949
+
950
+
[[package]]
951
+
name = "icu_properties_data"
952
+
version = "2.0.1"
953
+
source = "registry+https://github.com/rust-lang/crates.io-index"
954
+
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
955
+
956
+
[[package]]
957
+
name = "icu_provider"
958
+
version = "2.0.0"
959
+
source = "registry+https://github.com/rust-lang/crates.io-index"
960
+
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
961
+
dependencies = [
962
+
"displaydoc",
963
+
"icu_locale_core",
964
+
"stable_deref_trait",
965
+
"tinystr",
966
+
"writeable",
967
+
"yoke",
968
+
"zerofrom",
969
+
"zerotrie",
970
+
"zerovec",
971
+
]
972
+
973
+
[[package]]
974
+
name = "idna"
975
+
version = "1.0.3"
976
+
source = "registry+https://github.com/rust-lang/crates.io-index"
977
+
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
978
+
dependencies = [
979
+
"idna_adapter",
980
+
"smallvec",
981
+
"utf8_iter",
982
+
]
983
+
984
+
[[package]]
985
+
name = "idna_adapter"
986
+
version = "1.2.1"
987
+
source = "registry+https://github.com/rust-lang/crates.io-index"
988
+
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
989
+
dependencies = [
990
+
"icu_normalizer",
991
+
"icu_properties",
992
+
]
993
+
994
+
[[package]]
995
+
name = "image"
996
+
version = "0.25.6"
997
+
source = "registry+https://github.com/rust-lang/crates.io-index"
998
+
checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
999
+
dependencies = [
1000
+
"bytemuck",
1001
+
"byteorder-lite",
1002
+
"color_quant",
1003
+
"exr",
1004
+
"gif",
1005
+
"image-webp",
1006
+
"num-traits",
1007
+
"png",
1008
+
"qoi",
1009
+
"ravif",
1010
+
"rayon",
1011
+
"rgb",
1012
+
"tiff",
1013
+
"zune-core",
1014
+
"zune-jpeg",
1015
+
]
1016
+
1017
+
[[package]]
1018
+
name = "image-webp"
1019
+
version = "0.2.3"
1020
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1021
+
checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b"
1022
+
dependencies = [
1023
+
"byteorder-lite",
1024
+
"quick-error",
1025
+
]
1026
+
1027
+
[[package]]
1028
+
name = "imgref"
1029
+
version = "1.11.0"
1030
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1031
+
checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
1032
+
1033
+
[[package]]
1034
+
name = "indexmap"
1035
+
version = "2.10.0"
1036
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1037
+
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
1038
+
dependencies = [
1039
+
"equivalent",
1040
+
"hashbrown",
1041
+
]
1042
+
1043
+
[[package]]
1044
+
name = "indicatif"
1045
+
version = "0.18.0"
1046
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1047
+
checksum = "70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cd"
1048
+
dependencies = [
1049
+
"console 0.16.0",
1050
+
"portable-atomic",
1051
+
"unicode-width",
1052
+
"unit-prefix",
1053
+
"web-time",
1054
+
]
1055
+
1056
+
[[package]]
1057
+
name = "interpolate_name"
1058
+
version = "0.2.4"
1059
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1060
+
checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
1061
+
dependencies = [
1062
+
"proc-macro2",
1063
+
"quote",
1064
+
"syn",
1065
+
]
1066
+
1067
+
[[package]]
1068
+
name = "io-uring"
1069
+
version = "0.7.9"
1070
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1071
+
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
1072
+
dependencies = [
1073
+
"bitflags 2.9.1",
1074
+
"cfg-if",
1075
+
"libc",
1076
+
]
1077
+
1078
+
[[package]]
1079
+
name = "ipnet"
1080
+
version = "2.11.0"
1081
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1082
+
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
1083
+
1084
+
[[package]]
1085
+
name = "iri-string"
1086
+
version = "0.7.8"
1087
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1088
+
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
1089
+
dependencies = [
1090
+
"memchr",
1091
+
"serde",
1092
+
]
1093
+
1094
+
[[package]]
1095
+
name = "is-docker"
1096
+
version = "0.2.0"
1097
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1098
+
checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
1099
+
dependencies = [
1100
+
"once_cell",
1101
+
]
1102
+
1103
+
[[package]]
1104
+
name = "is-wsl"
1105
+
version = "0.4.0"
1106
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1107
+
checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
1108
+
dependencies = [
1109
+
"is-docker",
1110
+
"once_cell",
1111
+
]
1112
+
1113
+
[[package]]
1114
+
name = "is_terminal_polyfill"
1115
+
version = "1.70.1"
1116
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1117
+
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
1118
+
1119
+
[[package]]
1120
+
name = "itertools"
1121
+
version = "0.12.1"
1122
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1123
+
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
1124
+
dependencies = [
1125
+
"either",
1126
+
]
1127
+
1128
+
[[package]]
1129
+
name = "itoa"
1130
+
version = "1.0.15"
1131
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1132
+
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
1133
+
1134
+
[[package]]
1135
+
name = "jobserver"
1136
+
version = "0.1.33"
1137
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1138
+
checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a"
1139
+
dependencies = [
1140
+
"getrandom 0.3.3",
1141
+
"libc",
1142
+
]
1143
+
1144
+
[[package]]
1145
+
name = "jpeg-decoder"
1146
+
version = "0.3.2"
1147
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1148
+
checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
1149
+
1150
+
[[package]]
1151
+
name = "js-sys"
1152
+
version = "0.3.77"
1153
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1154
+
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
1155
+
dependencies = [
1156
+
"once_cell",
1157
+
"wasm-bindgen",
1158
+
]
1159
+
1160
+
[[package]]
1161
+
name = "lebe"
1162
+
version = "0.5.2"
1163
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1164
+
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
1165
+
1166
+
[[package]]
1167
+
name = "libc"
1168
+
version = "0.2.174"
1169
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1170
+
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
1171
+
1172
+
[[package]]
1173
+
name = "libfuzzer-sys"
1174
+
version = "0.4.10"
1175
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1176
+
checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404"
1177
+
dependencies = [
1178
+
"arbitrary",
1179
+
"cc",
1180
+
]
1181
+
1182
+
[[package]]
1183
+
name = "libredox"
1184
+
version = "0.1.9"
1185
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1186
+
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
1187
+
dependencies = [
1188
+
"bitflags 2.9.1",
1189
+
"libc",
1190
+
]
1191
+
1192
+
[[package]]
1193
+
name = "linux-raw-sys"
1194
+
version = "0.9.4"
1195
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1196
+
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
1197
+
1198
+
[[package]]
1199
+
name = "litemap"
1200
+
version = "0.8.0"
1201
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1202
+
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
1203
+
1204
+
[[package]]
1205
+
name = "lock_api"
1206
+
version = "0.4.13"
1207
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1208
+
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
1209
+
dependencies = [
1210
+
"autocfg",
1211
+
"scopeguard",
1212
+
]
1213
+
1214
+
[[package]]
1215
+
name = "log"
1216
+
version = "0.4.27"
1217
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1218
+
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
1219
+
1220
+
[[package]]
1221
+
name = "loop9"
1222
+
version = "0.1.5"
1223
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1224
+
checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
1225
+
dependencies = [
1226
+
"imgref",
1227
+
]
1228
+
1229
+
[[package]]
1230
+
name = "maybe-rayon"
1231
+
version = "0.1.1"
1232
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1233
+
checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
1234
+
dependencies = [
1235
+
"cfg-if",
1236
+
"rayon",
1237
+
]
1238
+
1239
+
[[package]]
1240
+
name = "memchr"
1241
+
version = "2.7.5"
1242
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1243
+
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
1244
+
1245
+
[[package]]
1246
+
name = "mime"
1247
+
version = "0.3.17"
1248
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1249
+
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
1250
+
1251
+
[[package]]
1252
+
name = "minimal-lexical"
1253
+
version = "0.2.1"
1254
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1255
+
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
1256
+
1257
+
[[package]]
1258
+
name = "miniz_oxide"
1259
+
version = "0.8.9"
1260
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1261
+
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
1262
+
dependencies = [
1263
+
"adler2",
1264
+
"simd-adler32",
1265
+
]
1266
+
1267
+
[[package]]
1268
+
name = "mio"
1269
+
version = "1.0.4"
1270
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1271
+
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
1272
+
dependencies = [
1273
+
"libc",
1274
+
"wasi 0.11.1+wasi-snapshot-preview1",
1275
+
"windows-sys 0.59.0",
1276
+
]
1277
+
1278
+
[[package]]
1279
+
name = "native-tls"
1280
+
version = "0.2.14"
1281
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1282
+
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
1283
+
dependencies = [
1284
+
"libc",
1285
+
"log",
1286
+
"openssl",
1287
+
"openssl-probe",
1288
+
"openssl-sys",
1289
+
"schannel",
1290
+
"security-framework",
1291
+
"security-framework-sys",
1292
+
"tempfile",
1293
+
]
1294
+
1295
+
[[package]]
1296
+
name = "new_debug_unreachable"
1297
+
version = "1.0.6"
1298
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1299
+
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
1300
+
1301
+
[[package]]
1302
+
name = "nom"
1303
+
version = "7.1.3"
1304
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1305
+
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
1306
+
dependencies = [
1307
+
"memchr",
1308
+
"minimal-lexical",
1309
+
]
1310
+
1311
+
[[package]]
1312
+
name = "noop_proc_macro"
1313
+
version = "0.3.0"
1314
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1315
+
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
1316
+
1317
+
[[package]]
1318
+
name = "num-bigint"
1319
+
version = "0.4.6"
1320
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1321
+
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
1322
+
dependencies = [
1323
+
"num-integer",
1324
+
"num-traits",
1325
+
]
1326
+
1327
+
[[package]]
1328
+
name = "num-derive"
1329
+
version = "0.4.2"
1330
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1331
+
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
1332
+
dependencies = [
1333
+
"proc-macro2",
1334
+
"quote",
1335
+
"syn",
1336
+
]
1337
+
1338
+
[[package]]
1339
+
name = "num-integer"
1340
+
version = "0.1.46"
1341
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1342
+
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
1343
+
dependencies = [
1344
+
"num-traits",
1345
+
]
1346
+
1347
+
[[package]]
1348
+
name = "num-rational"
1349
+
version = "0.4.2"
1350
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1351
+
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
1352
+
dependencies = [
1353
+
"num-bigint",
1354
+
"num-integer",
1355
+
"num-traits",
1356
+
]
1357
+
1358
+
[[package]]
1359
+
name = "num-traits"
1360
+
version = "0.2.19"
1361
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1362
+
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
1363
+
dependencies = [
1364
+
"autocfg",
1365
+
]
1366
+
1367
+
[[package]]
1368
+
name = "object"
1369
+
version = "0.36.7"
1370
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1371
+
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
1372
+
dependencies = [
1373
+
"memchr",
1374
+
]
1375
+
1376
+
[[package]]
1377
+
name = "once_cell"
1378
+
version = "1.21.3"
1379
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1380
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
1381
+
1382
+
[[package]]
1383
+
name = "once_cell_polyfill"
1384
+
version = "1.70.1"
1385
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1386
+
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
1387
+
1388
+
[[package]]
1389
+
name = "open"
1390
+
version = "5.3.2"
1391
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1392
+
checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95"
1393
+
dependencies = [
1394
+
"is-wsl",
1395
+
"libc",
1396
+
"pathdiff",
1397
+
]
1398
+
1399
+
[[package]]
1400
+
name = "openssl"
1401
+
version = "0.10.73"
1402
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1403
+
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
1404
+
dependencies = [
1405
+
"bitflags 2.9.1",
1406
+
"cfg-if",
1407
+
"foreign-types",
1408
+
"libc",
1409
+
"once_cell",
1410
+
"openssl-macros",
1411
+
"openssl-sys",
1412
+
]
1413
+
1414
+
[[package]]
1415
+
name = "openssl-macros"
1416
+
version = "0.1.1"
1417
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1418
+
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
1419
+
dependencies = [
1420
+
"proc-macro2",
1421
+
"quote",
1422
+
"syn",
1423
+
]
1424
+
1425
+
[[package]]
1426
+
name = "openssl-probe"
1427
+
version = "0.1.6"
1428
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1429
+
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
1430
+
1431
+
[[package]]
1432
+
name = "openssl-sys"
1433
+
version = "0.9.109"
1434
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1435
+
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
1436
+
dependencies = [
1437
+
"cc",
1438
+
"libc",
1439
+
"pkg-config",
1440
+
"vcpkg",
1441
+
]
1442
+
1443
+
[[package]]
1444
+
name = "option-ext"
1445
+
version = "0.2.0"
1446
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1447
+
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
1448
+
1449
+
[[package]]
1450
+
name = "parking_lot"
1451
+
version = "0.12.4"
1452
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1453
+
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
1454
+
dependencies = [
1455
+
"lock_api",
1456
+
"parking_lot_core",
1457
+
]
1458
+
1459
+
[[package]]
1460
+
name = "parking_lot_core"
1461
+
version = "0.9.11"
1462
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1463
+
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
1464
+
dependencies = [
1465
+
"cfg-if",
1466
+
"libc",
1467
+
"redox_syscall",
1468
+
"smallvec",
1469
+
"windows-targets 0.52.6",
1470
+
]
1471
+
1472
+
[[package]]
1473
+
name = "paste"
1474
+
version = "1.0.15"
1475
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1476
+
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
1477
+
1478
+
[[package]]
1479
+
name = "pathdiff"
1480
+
version = "0.2.3"
1481
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1482
+
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
1483
+
1484
+
[[package]]
1485
+
name = "percent-encoding"
1486
+
version = "2.3.1"
1487
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1488
+
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
1489
+
1490
+
[[package]]
1491
+
name = "pin-project-lite"
1492
+
version = "0.2.16"
1493
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1494
+
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
1495
+
1496
+
[[package]]
1497
+
name = "pin-utils"
1498
+
version = "0.1.0"
1499
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1500
+
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1501
+
1502
+
[[package]]
1503
+
name = "pkg-config"
1504
+
version = "0.3.32"
1505
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1506
+
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
1507
+
1508
+
[[package]]
1509
+
name = "png"
1510
+
version = "0.17.16"
1511
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1512
+
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
1513
+
dependencies = [
1514
+
"bitflags 1.3.2",
1515
+
"crc32fast",
1516
+
"fdeflate",
1517
+
"flate2",
1518
+
"miniz_oxide",
1519
+
]
1520
+
1521
+
[[package]]
1522
+
name = "portable-atomic"
1523
+
version = "1.11.1"
1524
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1525
+
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
1526
+
1527
+
[[package]]
1528
+
name = "potential_utf"
1529
+
version = "0.1.2"
1530
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1531
+
checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
1532
+
dependencies = [
1533
+
"zerovec",
1534
+
]
1535
+
1536
+
[[package]]
1537
+
name = "ppv-lite86"
1538
+
version = "0.2.21"
1539
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1540
+
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
1541
+
dependencies = [
1542
+
"zerocopy",
1543
+
]
1544
+
1545
+
[[package]]
1546
+
name = "proc-macro2"
1547
+
version = "1.0.95"
1548
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1549
+
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
1550
+
dependencies = [
1551
+
"unicode-ident",
1552
+
]
1553
+
1554
+
[[package]]
1555
+
name = "profiling"
1556
+
version = "1.0.17"
1557
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1558
+
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
1559
+
dependencies = [
1560
+
"profiling-procmacros",
1561
+
]
1562
+
1563
+
[[package]]
1564
+
name = "profiling-procmacros"
1565
+
version = "1.0.17"
1566
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1567
+
checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
1568
+
dependencies = [
1569
+
"quote",
1570
+
"syn",
1571
+
]
1572
+
1573
+
[[package]]
1574
+
name = "qoi"
1575
+
version = "0.4.1"
1576
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1577
+
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
1578
+
dependencies = [
1579
+
"bytemuck",
1580
+
]
1581
+
1582
+
[[package]]
1583
+
name = "quick-error"
1584
+
version = "2.0.1"
1585
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1586
+
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
1587
+
1588
+
[[package]]
1589
+
name = "quote"
1590
+
version = "1.0.40"
1591
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1592
+
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
1593
+
dependencies = [
1594
+
"proc-macro2",
1595
+
]
1596
+
1597
+
[[package]]
1598
+
name = "r-efi"
1599
+
version = "5.3.0"
1600
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1601
+
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
1602
+
1603
+
[[package]]
1604
+
name = "rand"
1605
+
version = "0.8.5"
1606
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1607
+
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1608
+
dependencies = [
1609
+
"libc",
1610
+
"rand_chacha",
1611
+
"rand_core",
1612
+
]
1613
+
1614
+
[[package]]
1615
+
name = "rand_chacha"
1616
+
version = "0.3.1"
1617
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1618
+
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1619
+
dependencies = [
1620
+
"ppv-lite86",
1621
+
"rand_core",
1622
+
]
1623
+
1624
+
[[package]]
1625
+
name = "rand_core"
1626
+
version = "0.6.4"
1627
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1628
+
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1629
+
dependencies = [
1630
+
"getrandom 0.2.16",
1631
+
]
1632
+
1633
+
[[package]]
1634
+
name = "rav1e"
1635
+
version = "0.7.1"
1636
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1637
+
checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
1638
+
dependencies = [
1639
+
"arbitrary",
1640
+
"arg_enum_proc_macro",
1641
+
"arrayvec",
1642
+
"av1-grain",
1643
+
"bitstream-io",
1644
+
"built",
1645
+
"cfg-if",
1646
+
"interpolate_name",
1647
+
"itertools",
1648
+
"libc",
1649
+
"libfuzzer-sys",
1650
+
"log",
1651
+
"maybe-rayon",
1652
+
"new_debug_unreachable",
1653
+
"noop_proc_macro",
1654
+
"num-derive",
1655
+
"num-traits",
1656
+
"once_cell",
1657
+
"paste",
1658
+
"profiling",
1659
+
"rand",
1660
+
"rand_chacha",
1661
+
"simd_helpers",
1662
+
"system-deps",
1663
+
"thiserror 1.0.69",
1664
+
"v_frame",
1665
+
"wasm-bindgen",
1666
+
]
1667
+
1668
+
[[package]]
1669
+
name = "ravif"
1670
+
version = "0.11.20"
1671
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1672
+
checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b"
1673
+
dependencies = [
1674
+
"avif-serialize",
1675
+
"imgref",
1676
+
"loop9",
1677
+
"quick-error",
1678
+
"rav1e",
1679
+
"rayon",
1680
+
"rgb",
1681
+
]
1682
+
1683
+
[[package]]
1684
+
name = "rayon"
1685
+
version = "1.10.0"
1686
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1687
+
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
1688
+
dependencies = [
1689
+
"either",
1690
+
"rayon-core",
1691
+
]
1692
+
1693
+
[[package]]
1694
+
name = "rayon-core"
1695
+
version = "1.12.1"
1696
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1697
+
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
1698
+
dependencies = [
1699
+
"crossbeam-deque",
1700
+
"crossbeam-utils",
1701
+
]
1702
+
1703
+
[[package]]
1704
+
name = "redox_syscall"
1705
+
version = "0.5.17"
1706
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1707
+
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
1708
+
dependencies = [
1709
+
"bitflags 2.9.1",
1710
+
]
1711
+
1712
+
[[package]]
1713
+
name = "redox_users"
1714
+
version = "0.5.2"
1715
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1716
+
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
1717
+
dependencies = [
1718
+
"getrandom 0.2.16",
1719
+
"libredox",
1720
+
"thiserror 2.0.12",
1721
+
]
1722
+
1723
+
[[package]]
1724
+
name = "reqwest"
1725
+
version = "0.12.22"
1726
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1727
+
checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
1728
+
dependencies = [
1729
+
"base64",
1730
+
"bytes",
1731
+
"encoding_rs",
1732
+
"futures-core",
1733
+
"h2",
1734
+
"http",
1735
+
"http-body",
1736
+
"http-body-util",
1737
+
"hyper",
1738
+
"hyper-rustls",
1739
+
"hyper-tls",
1740
+
"hyper-util",
1741
+
"js-sys",
1742
+
"log",
1743
+
"mime",
1744
+
"native-tls",
1745
+
"percent-encoding",
1746
+
"pin-project-lite",
1747
+
"rustls-pki-types",
1748
+
"serde",
1749
+
"serde_json",
1750
+
"serde_urlencoded",
1751
+
"sync_wrapper",
1752
+
"tokio",
1753
+
"tokio-native-tls",
1754
+
"tower",
1755
+
"tower-http",
1756
+
"tower-service",
1757
+
"url",
1758
+
"wasm-bindgen",
1759
+
"wasm-bindgen-futures",
1760
+
"web-sys",
1761
+
]
1762
+
1763
+
[[package]]
1764
+
name = "rgb"
1765
+
version = "0.8.52"
1766
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1767
+
checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
1768
+
1769
+
[[package]]
1770
+
name = "ring"
1771
+
version = "0.17.14"
1772
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1773
+
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
1774
+
dependencies = [
1775
+
"cc",
1776
+
"cfg-if",
1777
+
"getrandom 0.2.16",
1778
+
"libc",
1779
+
"untrusted",
1780
+
"windows-sys 0.52.0",
1781
+
]
1782
+
1783
+
[[package]]
1784
+
name = "rustc-demangle"
1785
+
version = "0.1.26"
1786
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1787
+
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
1788
+
1789
+
[[package]]
1790
+
name = "rustix"
1791
+
version = "1.0.8"
1792
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1793
+
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
1794
+
dependencies = [
1795
+
"bitflags 2.9.1",
1796
+
"errno",
1797
+
"libc",
1798
+
"linux-raw-sys",
1799
+
"windows-sys 0.60.2",
1800
+
]
1801
+
1802
+
[[package]]
1803
+
name = "rustls"
1804
+
version = "0.23.31"
1805
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1806
+
checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc"
1807
+
dependencies = [
1808
+
"once_cell",
1809
+
"rustls-pki-types",
1810
+
"rustls-webpki",
1811
+
"subtle",
1812
+
"zeroize",
1813
+
]
1814
+
1815
+
[[package]]
1816
+
name = "rustls-pki-types"
1817
+
version = "1.12.0"
1818
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1819
+
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
1820
+
dependencies = [
1821
+
"zeroize",
1822
+
]
1823
+
1824
+
[[package]]
1825
+
name = "rustls-webpki"
1826
+
version = "0.103.4"
1827
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1828
+
checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc"
1829
+
dependencies = [
1830
+
"ring",
1831
+
"rustls-pki-types",
1832
+
"untrusted",
1833
+
]
1834
+
1835
+
[[package]]
1836
+
name = "rustversion"
1837
+
version = "1.0.21"
1838
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1839
+
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
1840
+
1841
+
[[package]]
1842
+
name = "ryu"
1843
+
version = "1.0.20"
1844
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1845
+
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
1846
+
1847
+
[[package]]
1848
+
name = "schannel"
1849
+
version = "0.1.27"
1850
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1851
+
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
1852
+
dependencies = [
1853
+
"windows-sys 0.59.0",
1854
+
]
1855
+
1856
+
[[package]]
1857
+
name = "scopeguard"
1858
+
version = "1.2.0"
1859
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1860
+
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
1861
+
1862
+
[[package]]
1863
+
name = "security-framework"
1864
+
version = "2.11.1"
1865
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1866
+
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
1867
+
dependencies = [
1868
+
"bitflags 2.9.1",
1869
+
"core-foundation",
1870
+
"core-foundation-sys",
1871
+
"libc",
1872
+
"security-framework-sys",
1873
+
]
1874
+
1875
+
[[package]]
1876
+
name = "security-framework-sys"
1877
+
version = "2.14.0"
1878
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1879
+
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
1880
+
dependencies = [
1881
+
"core-foundation-sys",
1882
+
"libc",
1883
+
]
1884
+
1885
+
[[package]]
1886
+
name = "serde"
1887
+
version = "1.0.219"
1888
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1889
+
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
1890
+
dependencies = [
1891
+
"serde_derive",
1892
+
]
1893
+
1894
+
[[package]]
1895
+
name = "serde_derive"
1896
+
version = "1.0.219"
1897
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1898
+
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
1899
+
dependencies = [
1900
+
"proc-macro2",
1901
+
"quote",
1902
+
"syn",
1903
+
]
1904
+
1905
+
[[package]]
1906
+
name = "serde_json"
1907
+
version = "1.0.142"
1908
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1909
+
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
1910
+
dependencies = [
1911
+
"itoa",
1912
+
"memchr",
1913
+
"ryu",
1914
+
"serde",
1915
+
]
1916
+
1917
+
[[package]]
1918
+
name = "serde_spanned"
1919
+
version = "0.6.9"
1920
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1921
+
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
1922
+
dependencies = [
1923
+
"serde",
1924
+
]
1925
+
1926
+
[[package]]
1927
+
name = "serde_urlencoded"
1928
+
version = "0.7.1"
1929
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1930
+
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
1931
+
dependencies = [
1932
+
"form_urlencoded",
1933
+
"itoa",
1934
+
"ryu",
1935
+
"serde",
1936
+
]
1937
+
1938
+
[[package]]
1939
+
name = "shell-words"
1940
+
version = "1.1.0"
1941
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1942
+
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
1943
+
1944
+
[[package]]
1945
+
name = "shlex"
1946
+
version = "1.3.0"
1947
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1948
+
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1949
+
1950
+
[[package]]
1951
+
name = "signal-hook-registry"
1952
+
version = "1.4.6"
1953
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1954
+
checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
1955
+
dependencies = [
1956
+
"libc",
1957
+
]
1958
+
1959
+
[[package]]
1960
+
name = "simd-adler32"
1961
+
version = "0.3.7"
1962
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1963
+
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
1964
+
1965
+
[[package]]
1966
+
name = "simd_helpers"
1967
+
version = "0.1.0"
1968
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1969
+
checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
1970
+
dependencies = [
1971
+
"quote",
1972
+
]
1973
+
1974
+
[[package]]
1975
+
name = "slab"
1976
+
version = "0.4.10"
1977
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1978
+
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
1979
+
1980
+
[[package]]
1981
+
name = "smallvec"
1982
+
version = "1.15.1"
1983
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1984
+
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
1985
+
1986
+
[[package]]
1987
+
name = "socket2"
1988
+
version = "0.6.0"
1989
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1990
+
checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
1991
+
dependencies = [
1992
+
"libc",
1993
+
"windows-sys 0.59.0",
1994
+
]
1995
+
1996
+
[[package]]
1997
+
name = "stable_deref_trait"
1998
+
version = "1.2.0"
1999
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2000
+
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
2001
+
2002
+
[[package]]
2003
+
name = "strsim"
2004
+
version = "0.11.1"
2005
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2006
+
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
2007
+
2008
+
[[package]]
2009
+
name = "subtle"
2010
+
version = "2.6.1"
2011
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2012
+
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
2013
+
2014
+
[[package]]
2015
+
name = "syn"
2016
+
version = "2.0.104"
2017
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2018
+
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
2019
+
dependencies = [
2020
+
"proc-macro2",
2021
+
"quote",
2022
+
"unicode-ident",
2023
+
]
2024
+
2025
+
[[package]]
2026
+
name = "sync_wrapper"
2027
+
version = "1.0.2"
2028
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2029
+
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
2030
+
dependencies = [
2031
+
"futures-core",
2032
+
]
2033
+
2034
+
[[package]]
2035
+
name = "synstructure"
2036
+
version = "0.13.2"
2037
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2038
+
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
2039
+
dependencies = [
2040
+
"proc-macro2",
2041
+
"quote",
2042
+
"syn",
2043
+
]
2044
+
2045
+
[[package]]
2046
+
name = "system-configuration"
2047
+
version = "0.6.1"
2048
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2049
+
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
2050
+
dependencies = [
2051
+
"bitflags 2.9.1",
2052
+
"core-foundation",
2053
+
"system-configuration-sys",
2054
+
]
2055
+
2056
+
[[package]]
2057
+
name = "system-configuration-sys"
2058
+
version = "0.6.0"
2059
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2060
+
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
2061
+
dependencies = [
2062
+
"core-foundation-sys",
2063
+
"libc",
2064
+
]
2065
+
2066
+
[[package]]
2067
+
name = "system-deps"
2068
+
version = "6.2.2"
2069
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2070
+
checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
2071
+
dependencies = [
2072
+
"cfg-expr",
2073
+
"heck",
2074
+
"pkg-config",
2075
+
"toml",
2076
+
"version-compare",
2077
+
]
2078
+
2079
+
[[package]]
2080
+
name = "target-lexicon"
2081
+
version = "0.12.16"
2082
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2083
+
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
2084
+
2085
+
[[package]]
2086
+
name = "tempfile"
2087
+
version = "3.20.0"
2088
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2089
+
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
2090
+
dependencies = [
2091
+
"fastrand",
2092
+
"getrandom 0.3.3",
2093
+
"once_cell",
2094
+
"rustix",
2095
+
"windows-sys 0.59.0",
2096
+
]
2097
+
2098
+
[[package]]
2099
+
name = "thiserror"
2100
+
version = "1.0.69"
2101
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2102
+
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
2103
+
dependencies = [
2104
+
"thiserror-impl 1.0.69",
2105
+
]
2106
+
2107
+
[[package]]
2108
+
name = "thiserror"
2109
+
version = "2.0.12"
2110
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2111
+
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
2112
+
dependencies = [
2113
+
"thiserror-impl 2.0.12",
2114
+
]
2115
+
2116
+
[[package]]
2117
+
name = "thiserror-impl"
2118
+
version = "1.0.69"
2119
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2120
+
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
2121
+
dependencies = [
2122
+
"proc-macro2",
2123
+
"quote",
2124
+
"syn",
2125
+
]
2126
+
2127
+
[[package]]
2128
+
name = "thiserror-impl"
2129
+
version = "2.0.12"
2130
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2131
+
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
2132
+
dependencies = [
2133
+
"proc-macro2",
2134
+
"quote",
2135
+
"syn",
2136
+
]
2137
+
2138
+
[[package]]
2139
+
name = "tiff"
2140
+
version = "0.9.1"
2141
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2142
+
checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
2143
+
dependencies = [
2144
+
"flate2",
2145
+
"jpeg-decoder",
2146
+
"weezl",
2147
+
]
2148
+
2149
+
[[package]]
2150
+
name = "tinystr"
2151
+
version = "0.8.1"
2152
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2153
+
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
2154
+
dependencies = [
2155
+
"displaydoc",
2156
+
"zerovec",
2157
+
]
2158
+
2159
+
[[package]]
2160
+
name = "tokio"
2161
+
version = "1.47.1"
2162
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2163
+
checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038"
2164
+
dependencies = [
2165
+
"backtrace",
2166
+
"bytes",
2167
+
"io-uring",
2168
+
"libc",
2169
+
"mio",
2170
+
"parking_lot",
2171
+
"pin-project-lite",
2172
+
"signal-hook-registry",
2173
+
"slab",
2174
+
"socket2",
2175
+
"tokio-macros",
2176
+
"windows-sys 0.59.0",
2177
+
]
2178
+
2179
+
[[package]]
2180
+
name = "tokio-macros"
2181
+
version = "2.5.0"
2182
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2183
+
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
2184
+
dependencies = [
2185
+
"proc-macro2",
2186
+
"quote",
2187
+
"syn",
2188
+
]
2189
+
2190
+
[[package]]
2191
+
name = "tokio-native-tls"
2192
+
version = "0.3.1"
2193
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2194
+
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
2195
+
dependencies = [
2196
+
"native-tls",
2197
+
"tokio",
2198
+
]
2199
+
2200
+
[[package]]
2201
+
name = "tokio-rustls"
2202
+
version = "0.26.2"
2203
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2204
+
checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
2205
+
dependencies = [
2206
+
"rustls",
2207
+
"tokio",
2208
+
]
2209
+
2210
+
[[package]]
2211
+
name = "tokio-util"
2212
+
version = "0.7.16"
2213
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2214
+
checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5"
2215
+
dependencies = [
2216
+
"bytes",
2217
+
"futures-core",
2218
+
"futures-sink",
2219
+
"pin-project-lite",
2220
+
"tokio",
2221
+
]
2222
+
2223
+
[[package]]
2224
+
name = "toml"
2225
+
version = "0.8.23"
2226
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2227
+
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
2228
+
dependencies = [
2229
+
"serde",
2230
+
"serde_spanned",
2231
+
"toml_datetime",
2232
+
"toml_edit",
2233
+
]
2234
+
2235
+
[[package]]
2236
+
name = "toml_datetime"
2237
+
version = "0.6.11"
2238
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2239
+
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
2240
+
dependencies = [
2241
+
"serde",
2242
+
]
2243
+
2244
+
[[package]]
2245
+
name = "toml_edit"
2246
+
version = "0.22.27"
2247
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2248
+
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
2249
+
dependencies = [
2250
+
"indexmap",
2251
+
"serde",
2252
+
"serde_spanned",
2253
+
"toml_datetime",
2254
+
"winnow",
2255
+
]
2256
+
2257
+
[[package]]
2258
+
name = "tower"
2259
+
version = "0.5.2"
2260
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2261
+
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
2262
+
dependencies = [
2263
+
"futures-core",
2264
+
"futures-util",
2265
+
"pin-project-lite",
2266
+
"sync_wrapper",
2267
+
"tokio",
2268
+
"tower-layer",
2269
+
"tower-service",
2270
+
]
2271
+
2272
+
[[package]]
2273
+
name = "tower-http"
2274
+
version = "0.6.6"
2275
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2276
+
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
2277
+
dependencies = [
2278
+
"bitflags 2.9.1",
2279
+
"bytes",
2280
+
"futures-util",
2281
+
"http",
2282
+
"http-body",
2283
+
"iri-string",
2284
+
"pin-project-lite",
2285
+
"tower",
2286
+
"tower-layer",
2287
+
"tower-service",
2288
+
]
2289
+
2290
+
[[package]]
2291
+
name = "tower-layer"
2292
+
version = "0.3.3"
2293
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2294
+
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
2295
+
2296
+
[[package]]
2297
+
name = "tower-service"
2298
+
version = "0.3.3"
2299
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2300
+
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
2301
+
2302
+
[[package]]
2303
+
name = "tracing"
2304
+
version = "0.1.41"
2305
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2306
+
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
2307
+
dependencies = [
2308
+
"pin-project-lite",
2309
+
"tracing-core",
2310
+
]
2311
+
2312
+
[[package]]
2313
+
name = "tracing-core"
2314
+
version = "0.1.34"
2315
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2316
+
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
2317
+
dependencies = [
2318
+
"once_cell",
2319
+
]
2320
+
2321
+
[[package]]
2322
+
name = "try-lock"
2323
+
version = "0.2.5"
2324
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2325
+
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
2326
+
2327
+
[[package]]
2328
+
name = "unicode-ident"
2329
+
version = "1.0.18"
2330
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2331
+
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
2332
+
2333
+
[[package]]
2334
+
name = "unicode-width"
2335
+
version = "0.2.1"
2336
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2337
+
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
2338
+
2339
+
[[package]]
2340
+
name = "unit-prefix"
2341
+
version = "0.5.1"
2342
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2343
+
checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817"
2344
+
2345
+
[[package]]
2346
+
name = "untrusted"
2347
+
version = "0.9.0"
2348
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2349
+
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
2350
+
2351
+
[[package]]
2352
+
name = "url"
2353
+
version = "2.5.4"
2354
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2355
+
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
2356
+
dependencies = [
2357
+
"form_urlencoded",
2358
+
"idna",
2359
+
"percent-encoding",
2360
+
]
2361
+
2362
+
[[package]]
2363
+
name = "urlencoding"
2364
+
version = "2.1.3"
2365
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2366
+
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
2367
+
2368
+
[[package]]
2369
+
name = "utf8_iter"
2370
+
version = "1.0.4"
2371
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2372
+
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
2373
+
2374
+
[[package]]
2375
+
name = "utf8parse"
2376
+
version = "0.2.2"
2377
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2378
+
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
2379
+
2380
+
[[package]]
2381
+
name = "v_frame"
2382
+
version = "0.3.9"
2383
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2384
+
checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2"
2385
+
dependencies = [
2386
+
"aligned-vec",
2387
+
"num-traits",
2388
+
"wasm-bindgen",
2389
+
]
2390
+
2391
+
[[package]]
2392
+
name = "vcpkg"
2393
+
version = "0.2.15"
2394
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2395
+
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
2396
+
2397
+
[[package]]
2398
+
name = "version-compare"
2399
+
version = "0.2.0"
2400
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2401
+
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
2402
+
2403
+
[[package]]
2404
+
name = "want"
2405
+
version = "0.3.1"
2406
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2407
+
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
2408
+
dependencies = [
2409
+
"try-lock",
2410
+
]
2411
+
2412
+
[[package]]
2413
+
name = "wasi"
2414
+
version = "0.11.1+wasi-snapshot-preview1"
2415
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2416
+
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
2417
+
2418
+
[[package]]
2419
+
name = "wasi"
2420
+
version = "0.14.2+wasi-0.2.4"
2421
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2422
+
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
2423
+
dependencies = [
2424
+
"wit-bindgen-rt",
2425
+
]
2426
+
2427
+
[[package]]
2428
+
name = "wasm-bindgen"
2429
+
version = "0.2.100"
2430
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2431
+
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
2432
+
dependencies = [
2433
+
"cfg-if",
2434
+
"once_cell",
2435
+
"rustversion",
2436
+
"wasm-bindgen-macro",
2437
+
]
2438
+
2439
+
[[package]]
2440
+
name = "wasm-bindgen-backend"
2441
+
version = "0.2.100"
2442
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2443
+
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
2444
+
dependencies = [
2445
+
"bumpalo",
2446
+
"log",
2447
+
"proc-macro2",
2448
+
"quote",
2449
+
"syn",
2450
+
"wasm-bindgen-shared",
2451
+
]
2452
+
2453
+
[[package]]
2454
+
name = "wasm-bindgen-futures"
2455
+
version = "0.4.50"
2456
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2457
+
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
2458
+
dependencies = [
2459
+
"cfg-if",
2460
+
"js-sys",
2461
+
"once_cell",
2462
+
"wasm-bindgen",
2463
+
"web-sys",
2464
+
]
2465
+
2466
+
[[package]]
2467
+
name = "wasm-bindgen-macro"
2468
+
version = "0.2.100"
2469
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2470
+
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
2471
+
dependencies = [
2472
+
"quote",
2473
+
"wasm-bindgen-macro-support",
2474
+
]
2475
+
2476
+
[[package]]
2477
+
name = "wasm-bindgen-macro-support"
2478
+
version = "0.2.100"
2479
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2480
+
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
2481
+
dependencies = [
2482
+
"proc-macro2",
2483
+
"quote",
2484
+
"syn",
2485
+
"wasm-bindgen-backend",
2486
+
"wasm-bindgen-shared",
2487
+
]
2488
+
2489
+
[[package]]
2490
+
name = "wasm-bindgen-shared"
2491
+
version = "0.2.100"
2492
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2493
+
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
2494
+
dependencies = [
2495
+
"unicode-ident",
2496
+
]
2497
+
2498
+
[[package]]
2499
+
name = "web-sys"
2500
+
version = "0.3.77"
2501
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2502
+
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
2503
+
dependencies = [
2504
+
"js-sys",
2505
+
"wasm-bindgen",
2506
+
]
2507
+
2508
+
[[package]]
2509
+
name = "web-time"
2510
+
version = "1.1.0"
2511
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2512
+
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
2513
+
dependencies = [
2514
+
"js-sys",
2515
+
"wasm-bindgen",
2516
+
]
2517
+
2518
+
[[package]]
2519
+
name = "weezl"
2520
+
version = "0.1.10"
2521
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2522
+
checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3"
2523
+
2524
+
[[package]]
2525
+
name = "windows-core"
2526
+
version = "0.61.2"
2527
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2528
+
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
2529
+
dependencies = [
2530
+
"windows-implement",
2531
+
"windows-interface",
2532
+
"windows-link",
2533
+
"windows-result",
2534
+
"windows-strings",
2535
+
]
2536
+
2537
+
[[package]]
2538
+
name = "windows-implement"
2539
+
version = "0.60.0"
2540
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2541
+
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
2542
+
dependencies = [
2543
+
"proc-macro2",
2544
+
"quote",
2545
+
"syn",
2546
+
]
2547
+
2548
+
[[package]]
2549
+
name = "windows-interface"
2550
+
version = "0.59.1"
2551
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2552
+
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
2553
+
dependencies = [
2554
+
"proc-macro2",
2555
+
"quote",
2556
+
"syn",
2557
+
]
2558
+
2559
+
[[package]]
2560
+
name = "windows-link"
2561
+
version = "0.1.3"
2562
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2563
+
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
2564
+
2565
+
[[package]]
2566
+
name = "windows-registry"
2567
+
version = "0.5.3"
2568
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2569
+
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
2570
+
dependencies = [
2571
+
"windows-link",
2572
+
"windows-result",
2573
+
"windows-strings",
2574
+
]
2575
+
2576
+
[[package]]
2577
+
name = "windows-result"
2578
+
version = "0.3.4"
2579
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2580
+
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
2581
+
dependencies = [
2582
+
"windows-link",
2583
+
]
2584
+
2585
+
[[package]]
2586
+
name = "windows-strings"
2587
+
version = "0.4.2"
2588
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2589
+
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
2590
+
dependencies = [
2591
+
"windows-link",
2592
+
]
2593
+
2594
+
[[package]]
2595
+
name = "windows-sys"
2596
+
version = "0.52.0"
2597
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2598
+
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
2599
+
dependencies = [
2600
+
"windows-targets 0.52.6",
2601
+
]
2602
+
2603
+
[[package]]
2604
+
name = "windows-sys"
2605
+
version = "0.59.0"
2606
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2607
+
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
2608
+
dependencies = [
2609
+
"windows-targets 0.52.6",
2610
+
]
2611
+
2612
+
[[package]]
2613
+
name = "windows-sys"
2614
+
version = "0.60.2"
2615
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2616
+
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
2617
+
dependencies = [
2618
+
"windows-targets 0.53.3",
2619
+
]
2620
+
2621
+
[[package]]
2622
+
name = "windows-targets"
2623
+
version = "0.52.6"
2624
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2625
+
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
2626
+
dependencies = [
2627
+
"windows_aarch64_gnullvm 0.52.6",
2628
+
"windows_aarch64_msvc 0.52.6",
2629
+
"windows_i686_gnu 0.52.6",
2630
+
"windows_i686_gnullvm 0.52.6",
2631
+
"windows_i686_msvc 0.52.6",
2632
+
"windows_x86_64_gnu 0.52.6",
2633
+
"windows_x86_64_gnullvm 0.52.6",
2634
+
"windows_x86_64_msvc 0.52.6",
2635
+
]
2636
+
2637
+
[[package]]
2638
+
name = "windows-targets"
2639
+
version = "0.53.3"
2640
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2641
+
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
2642
+
dependencies = [
2643
+
"windows-link",
2644
+
"windows_aarch64_gnullvm 0.53.0",
2645
+
"windows_aarch64_msvc 0.53.0",
2646
+
"windows_i686_gnu 0.53.0",
2647
+
"windows_i686_gnullvm 0.53.0",
2648
+
"windows_i686_msvc 0.53.0",
2649
+
"windows_x86_64_gnu 0.53.0",
2650
+
"windows_x86_64_gnullvm 0.53.0",
2651
+
"windows_x86_64_msvc 0.53.0",
2652
+
]
2653
+
2654
+
[[package]]
2655
+
name = "windows_aarch64_gnullvm"
2656
+
version = "0.52.6"
2657
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2658
+
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
2659
+
2660
+
[[package]]
2661
+
name = "windows_aarch64_gnullvm"
2662
+
version = "0.53.0"
2663
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2664
+
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
2665
+
2666
+
[[package]]
2667
+
name = "windows_aarch64_msvc"
2668
+
version = "0.52.6"
2669
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2670
+
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
2671
+
2672
+
[[package]]
2673
+
name = "windows_aarch64_msvc"
2674
+
version = "0.53.0"
2675
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2676
+
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
2677
+
2678
+
[[package]]
2679
+
name = "windows_i686_gnu"
2680
+
version = "0.52.6"
2681
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2682
+
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
2683
+
2684
+
[[package]]
2685
+
name = "windows_i686_gnu"
2686
+
version = "0.53.0"
2687
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2688
+
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
2689
+
2690
+
[[package]]
2691
+
name = "windows_i686_gnullvm"
2692
+
version = "0.52.6"
2693
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2694
+
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
2695
+
2696
+
[[package]]
2697
+
name = "windows_i686_gnullvm"
2698
+
version = "0.53.0"
2699
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2700
+
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
2701
+
2702
+
[[package]]
2703
+
name = "windows_i686_msvc"
2704
+
version = "0.52.6"
2705
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2706
+
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
2707
+
2708
+
[[package]]
2709
+
name = "windows_i686_msvc"
2710
+
version = "0.53.0"
2711
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2712
+
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
2713
+
2714
+
[[package]]
2715
+
name = "windows_x86_64_gnu"
2716
+
version = "0.52.6"
2717
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2718
+
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
2719
+
2720
+
[[package]]
2721
+
name = "windows_x86_64_gnu"
2722
+
version = "0.53.0"
2723
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2724
+
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
2725
+
2726
+
[[package]]
2727
+
name = "windows_x86_64_gnullvm"
2728
+
version = "0.52.6"
2729
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2730
+
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
2731
+
2732
+
[[package]]
2733
+
name = "windows_x86_64_gnullvm"
2734
+
version = "0.53.0"
2735
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2736
+
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
2737
+
2738
+
[[package]]
2739
+
name = "windows_x86_64_msvc"
2740
+
version = "0.52.6"
2741
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2742
+
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
2743
+
2744
+
[[package]]
2745
+
name = "windows_x86_64_msvc"
2746
+
version = "0.53.0"
2747
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2748
+
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
2749
+
2750
+
[[package]]
2751
+
name = "winnow"
2752
+
version = "0.7.12"
2753
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2754
+
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
2755
+
dependencies = [
2756
+
"memchr",
2757
+
]
2758
+
2759
+
[[package]]
2760
+
name = "wit-bindgen-rt"
2761
+
version = "0.39.0"
2762
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2763
+
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
2764
+
dependencies = [
2765
+
"bitflags 2.9.1",
2766
+
]
2767
+
2768
+
[[package]]
2769
+
name = "writeable"
2770
+
version = "0.6.1"
2771
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2772
+
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
2773
+
2774
+
[[package]]
2775
+
name = "yoke"
2776
+
version = "0.8.0"
2777
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2778
+
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
2779
+
dependencies = [
2780
+
"serde",
2781
+
"stable_deref_trait",
2782
+
"yoke-derive",
2783
+
"zerofrom",
2784
+
]
2785
+
2786
+
[[package]]
2787
+
name = "yoke-derive"
2788
+
version = "0.8.0"
2789
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2790
+
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
2791
+
dependencies = [
2792
+
"proc-macro2",
2793
+
"quote",
2794
+
"syn",
2795
+
"synstructure",
2796
+
]
2797
+
2798
+
[[package]]
2799
+
name = "zerocopy"
2800
+
version = "0.8.26"
2801
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2802
+
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
2803
+
dependencies = [
2804
+
"zerocopy-derive",
2805
+
]
2806
+
2807
+
[[package]]
2808
+
name = "zerocopy-derive"
2809
+
version = "0.8.26"
2810
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2811
+
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
2812
+
dependencies = [
2813
+
"proc-macro2",
2814
+
"quote",
2815
+
"syn",
2816
+
]
2817
+
2818
+
[[package]]
2819
+
name = "zerofrom"
2820
+
version = "0.1.6"
2821
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2822
+
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
2823
+
dependencies = [
2824
+
"zerofrom-derive",
2825
+
]
2826
+
2827
+
[[package]]
2828
+
name = "zerofrom-derive"
2829
+
version = "0.1.6"
2830
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2831
+
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
2832
+
dependencies = [
2833
+
"proc-macro2",
2834
+
"quote",
2835
+
"syn",
2836
+
"synstructure",
2837
+
]
2838
+
2839
+
[[package]]
2840
+
name = "zeroize"
2841
+
version = "1.8.1"
2842
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2843
+
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
2844
+
2845
+
[[package]]
2846
+
name = "zerotrie"
2847
+
version = "0.2.2"
2848
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2849
+
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
2850
+
dependencies = [
2851
+
"displaydoc",
2852
+
"yoke",
2853
+
"zerofrom",
2854
+
]
2855
+
2856
+
[[package]]
2857
+
name = "zerovec"
2858
+
version = "0.11.3"
2859
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2860
+
checksum = "bdbb9122ea75b11bf96e7492afb723e8a7fbe12c67417aa95e7e3d18144d37cd"
2861
+
dependencies = [
2862
+
"yoke",
2863
+
"zerofrom",
2864
+
"zerovec-derive",
2865
+
]
2866
+
2867
+
[[package]]
2868
+
name = "zerovec-derive"
2869
+
version = "0.11.1"
2870
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2871
+
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
2872
+
dependencies = [
2873
+
"proc-macro2",
2874
+
"quote",
2875
+
"syn",
2876
+
]
2877
+
2878
+
[[package]]
2879
+
name = "zune-core"
2880
+
version = "0.4.12"
2881
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2882
+
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
2883
+
2884
+
[[package]]
2885
+
name = "zune-inflate"
2886
+
version = "0.2.54"
2887
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2888
+
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
2889
+
dependencies = [
2890
+
"simd-adler32",
2891
+
]
2892
+
2893
+
[[package]]
2894
+
name = "zune-jpeg"
2895
+
version = "0.4.20"
2896
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2897
+
checksum = "fc1f7e205ce79eb2da3cd71c5f55f3589785cb7c79f6a03d1c8d1491bda5d089"
2898
+
dependencies = [
2899
+
"zune-core",
2900
+
]
+29
cli/Cargo.toml
+29
cli/Cargo.toml
···
1
+
[package]
2
+
name = "grain-cli"
3
+
version = "0.1.0"
4
+
edition = "2021"
5
+
6
+
[[bin]]
7
+
name = "grain"
8
+
path = "src/main.rs"
9
+
10
+
[dependencies]
11
+
tokio = { version = "1.0", features = ["full"] }
12
+
reqwest = { version = "0.12", features = ["json"] }
13
+
serde = { version = "1.0", features = ["derive"] }
14
+
serde_json = "1.0"
15
+
clap = { version = "4.0", features = ["derive"] }
16
+
dialoguer = "0.11"
17
+
image = "0.25"
18
+
anyhow = "1.0"
19
+
open = "5.0"
20
+
hyper = { version = "1.0", features = ["full"] }
21
+
hyper-util = { version = "0.1", features = ["full"] }
22
+
http-body-util = "0.1"
23
+
tokio-util = "0.7"
24
+
futures-util = "0.3"
25
+
chrono = { version = "0.4", features = ["serde"] }
26
+
urlencoding = "2.1"
27
+
url = "2.5"
28
+
indicatif = "0.18"
29
+
dirs = "6.0"
+72
cli/README.md
+72
cli/README.md
···
1
+
# Grain CLI
2
+
3
+
⚠️ **Work in Progress**: This CLI is currently under development and is not
4
+
ready for use yet.
5
+
6
+
A command-line interface for [grain.social](https://grain.social) - a platform
7
+
for sharing photo galleries.
8
+
9
+
## Features
10
+
11
+
- **Authentication**: OAuth login flow with grain.social
12
+
- **Gallery Management**: List and create photo galleries
13
+
- **Image Upload**: Bulk upload images from local folders with automatic
14
+
resizing
15
+
16
+
## Requirements
17
+
18
+
- [Rust](https://rustup.rs/) installed
19
+
- AT Protocol account ([Bluesky](https://bsky.app))
20
+
21
+
## Installation
22
+
23
+
Build from source:
24
+
25
+
```bash
26
+
cargo build --release
27
+
```
28
+
29
+
The binary will be available at `target/release/grain`.
30
+
31
+
## Usage
32
+
33
+
### Authentication
34
+
35
+
First, authenticate with your grain.social account:
36
+
37
+
```bash
38
+
grain login
39
+
```
40
+
41
+
This will open your browser for OAuth authentication.
42
+
43
+
### Gallery Commands
44
+
45
+
List your existing galleries:
46
+
47
+
```bash
48
+
grain gallery list
49
+
```
50
+
51
+
Create a new gallery from a folder of images:
52
+
53
+
```bash
54
+
grain gallery create
55
+
```
56
+
57
+
You'll be prompted for:
58
+
59
+
- Gallery title
60
+
- Gallery description (optional)
61
+
- Path to folder containing images
62
+
63
+
The CLI will automatically resize images and upload them to your new gallery.
64
+
65
+
### Verbose Output
66
+
67
+
Add `--verbose` to any command for detailed output:
68
+
69
+
```bash
70
+
grain login --verbose
71
+
grain gallery create --verbose
72
+
```
+128
cli/flake.nix
+128
cli/flake.nix
···
1
+
{
2
+
description = "Grain CLI - A command-line interface for grain.social";
3
+
4
+
inputs = {
5
+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
6
+
flake-utils.url = "github:numtide/flake-utils";
7
+
rust-overlay = {
8
+
url = "github:oxalica/rust-overlay";
9
+
inputs.nixpkgs.follows = "nixpkgs";
10
+
};
11
+
};
12
+
13
+
outputs = { self, nixpkgs, flake-utils, rust-overlay }:
14
+
flake-utils.lib.eachDefaultSystem (system:
15
+
let
16
+
overlays = [ (import rust-overlay) ];
17
+
pkgs = import nixpkgs { inherit system overlays; };
18
+
19
+
rustToolchain = pkgs.rust-bin.stable.latest.default.override {
20
+
extensions = [ "rust-src" ];
21
+
targets = [
22
+
"x86_64-unknown-linux-gnu"
23
+
"x86_64-pc-windows-gnu"
24
+
"x86_64-apple-darwin"
25
+
"aarch64-apple-darwin"
26
+
"aarch64-unknown-linux-gnu"
27
+
];
28
+
};
29
+
30
+
# Build function for different targets
31
+
buildGrainCLI = target: pkgs.stdenv.mkDerivation rec {
32
+
pname = "grain-cli-${target}";
33
+
version = "0.1.0";
34
+
35
+
src = ./.;
36
+
37
+
nativeBuildInputs = with pkgs; [
38
+
rustToolchain
39
+
pkg-config
40
+
] ++ pkgs.lib.optionals (target == "x86_64-pc-windows-gnu") [
41
+
pkgs.pkgsCross.mingwW64.stdenv.cc
42
+
];
43
+
44
+
buildInputs = with pkgs; [
45
+
openssl
46
+
] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
47
+
pkgs.darwin.apple_sdk.frameworks.Security
48
+
pkgs.darwin.apple_sdk.frameworks.SystemConfiguration
49
+
];
50
+
51
+
buildPhase = ''
52
+
export CARGO_HOME=$TMPDIR/cargo
53
+
export OPENSSL_NO_VENDOR=1
54
+
export PKG_CONFIG_PATH="${pkgs.openssl.dev}/lib/pkgconfig:$PKG_CONFIG_PATH"
55
+
56
+
${if target == "x86_64-pc-windows-gnu" then ''
57
+
export CC_x86_64_pc_windows_gnu="${pkgs.pkgsCross.mingwW64.stdenv.cc}/bin/x86_64-w64-mingw32-gcc"
58
+
export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER="${pkgs.pkgsCross.mingwW64.stdenv.cc}/bin/x86_64-w64-mingw32-gcc"
59
+
export PKG_CONFIG_ALLOW_CROSS=1
60
+
'' else ""}
61
+
62
+
cargo build --release --target ${target}
63
+
'';
64
+
65
+
installPhase = ''
66
+
mkdir -p $out/bin
67
+
cp target/${target}/release/grain${if target == "x86_64-pc-windows-gnu" then ".exe" else ""} $out/bin/
68
+
'';
69
+
};
70
+
71
+
in {
72
+
packages = {
73
+
default = buildGrainCLI system;
74
+
75
+
# Cross-compilation targets
76
+
grain-linux-x86_64 = buildGrainCLI "x86_64-unknown-linux-gnu";
77
+
grain-linux-aarch64 = buildGrainCLI "aarch64-unknown-linux-gnu";
78
+
grain-macos-x86_64 = buildGrainCLI "x86_64-apple-darwin";
79
+
grain-macos-aarch64 = buildGrainCLI "aarch64-apple-darwin";
80
+
grain-windows-x86_64 = buildGrainCLI "x86_64-pc-windows-gnu";
81
+
};
82
+
83
+
devShells.default = pkgs.mkShell {
84
+
inputsFrom = [ self.packages.${system}.default ];
85
+
packages = with pkgs; [
86
+
rustToolchain
87
+
pkg-config
88
+
openssl
89
+
cargo-cross
90
+
];
91
+
};
92
+
93
+
# Helper script to build all targets
94
+
apps.build-all = flake-utils.lib.mkApp {
95
+
drv = pkgs.writeShellScriptBin "build-all" ''
96
+
set -e
97
+
98
+
echo "Building Grain CLI for all platforms..."
99
+
100
+
mkdir -p releases
101
+
102
+
# Build for each platform
103
+
echo "Building for Linux x86_64..."
104
+
nix build .#grain-linux-x86_64 -o result-linux-x86_64
105
+
cp result-linux-x86_64/bin/grain releases/grain-linux-x86_64
106
+
107
+
echo "Building for Linux aarch64..."
108
+
nix build .#grain-linux-aarch64 -o result-linux-aarch64
109
+
cp result-linux-aarch64/bin/grain releases/grain-linux-aarch64
110
+
111
+
echo "Building for macOS x86_64..."
112
+
nix build .#grain-macos-x86_64 -o result-macos-x86_64
113
+
cp result-macos-x86_64/bin/grain releases/grain-darwin-x86_64
114
+
115
+
echo "Building for macOS aarch64..."
116
+
nix build .#grain-macos-aarch64 -o result-macos-aarch64
117
+
cp result-macos-aarch64/bin/grain releases/grain-darwin-aarch64
118
+
119
+
echo "Building for Windows x86_64..."
120
+
nix build .#grain-windows-x86_64 -o result-windows-x86_64
121
+
cp result-windows-x86_64/bin/grain.exe releases/grain-windows-x86_64.exe
122
+
123
+
echo "All builds complete! Binaries are in releases/"
124
+
ls -la releases/
125
+
'';
126
+
};
127
+
});
128
+
}
+48
cli/install.sh
+48
cli/install.sh
···
1
+
#!/bin/bash
2
+
3
+
set -e
4
+
5
+
echo "🌾 Installing Grain CLI..."
6
+
7
+
# Detect OS and architecture
8
+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
9
+
ARCH=$(uname -m)
10
+
11
+
# Map architecture names
12
+
case $ARCH in
13
+
x86_64)
14
+
ARCH="x86_64"
15
+
;;
16
+
arm64|aarch64)
17
+
ARCH="aarch64"
18
+
;;
19
+
*)
20
+
echo "❌ Unsupported architecture: $ARCH"
21
+
exit 1
22
+
;;
23
+
esac
24
+
25
+
# Set GitHub repository (replace with your actual repo)
26
+
REPO="grainsocial/grain"
27
+
BINARY_NAME="grain-${OS}-${ARCH}"
28
+
29
+
echo "📦 Downloading Grain CLI for ${OS}-${ARCH}..."
30
+
31
+
# Download pre-built binary
32
+
if ! curl -L "https://github.com/${REPO}/releases/latest/download/${BINARY_NAME}" -o grain; then
33
+
echo "❌ Pre-built binary not available for ${OS}-${ARCH}"
34
+
echo "Please build from source instead:"
35
+
echo " cargo build --release"
36
+
exit 1
37
+
fi
38
+
39
+
# Make executable
40
+
chmod +x grain
41
+
42
+
# Install to system
43
+
echo "🔗 Installing to /usr/local/bin (requires sudo)..."
44
+
sudo mv grain /usr/local/bin/
45
+
46
+
echo "✅ Grain CLI installed successfully!"
47
+
echo "📖 Run 'grain --help' to get started"
48
+
echo "🔐 Run 'grain login' to authenticate"
+763
cli/src/main.rs
+763
cli/src/main.rs
···
1
+
use anyhow::{Context, Result};
2
+
use clap::{Parser, Subcommand};
3
+
use dialoguer::{Confirm, Input};
4
+
use reqwest::{header::HeaderMap, Client, Method};
5
+
use serde::{Deserialize, Serialize};
6
+
use serde_json::Value;
7
+
use std::collections::HashMap;
8
+
use std::sync::{Arc, Mutex};
9
+
use std::fs;
10
+
use std::path::Path;
11
+
use std::process;
12
+
use std::time::Duration;
13
+
use hyper::server::conn::http1;
14
+
use hyper::service::service_fn;
15
+
use hyper::{body::Incoming as IncomingBody, Request, Response, StatusCode};
16
+
use hyper_util::rt::TokioIo;
17
+
use http_body_util::Full;
18
+
use tokio::net::TcpListener;
19
+
use indicatif::{ProgressBar, ProgressStyle};
20
+
use dirs;
21
+
22
+
mod photo_manip;
23
+
use photo_manip::{do_resize, ResizeOptions};
24
+
25
+
const API_BASE: &str = "http://localhost:8080";
26
+
const OAUTH_PORT: u16 = 8787;
27
+
const OAUTH_PATH: &str = "/callback";
28
+
const OAUTH_TIMEOUT: Duration = Duration::from_secs(300); // 5 minutes
29
+
30
+
#[derive(Parser)]
31
+
#[command(name = "grain")]
32
+
#[command(about = "A CLI for grain.social")]
33
+
struct Cli {
34
+
#[command(subcommand)]
35
+
command: Option<Commands>,
36
+
37
+
#[arg(short, long, global = true, help = "Enable verbose output")]
38
+
verbose: bool,
39
+
}
40
+
41
+
#[derive(Subcommand)]
42
+
enum Commands {
43
+
#[command(about = "Authenticate with grain.social")]
44
+
Login,
45
+
#[command(about = "Manage your galleries")]
46
+
Gallery {
47
+
#[command(subcommand)]
48
+
action: GalleryAction,
49
+
},
50
+
}
51
+
52
+
#[derive(Subcommand)]
53
+
enum GalleryAction {
54
+
#[command(about = "List your galleries")]
55
+
List,
56
+
#[command(about = "Create a new gallery from a folder of images")]
57
+
Create,
58
+
#[command(about = "Delete a gallery")]
59
+
Delete,
60
+
#[command(about = "Open a gallery in the browser")]
61
+
Show,
62
+
}
63
+
64
+
#[derive(Serialize, Deserialize)]
65
+
struct AuthData {
66
+
did: String,
67
+
token: String,
68
+
#[serde(rename = "expiresAt")]
69
+
expires_at: Option<String>,
70
+
}
71
+
72
+
#[derive(Deserialize)]
73
+
struct GalleryItem {
74
+
title: Option<String>,
75
+
items: Option<Vec<Value>>,
76
+
uri: String,
77
+
}
78
+
79
+
#[derive(Debug, Deserialize)]
80
+
struct LoginResponse {
81
+
url: Option<String>,
82
+
}
83
+
84
+
#[derive(Deserialize)]
85
+
struct GalleriesResponse {
86
+
items: Option<Vec<GalleryItem>>,
87
+
}
88
+
89
+
#[derive(Debug, Deserialize)]
90
+
struct CreateGalleryResponse {
91
+
#[serde(rename = "galleryUri")]
92
+
gallery_uri: String,
93
+
}
94
+
95
+
#[derive(Deserialize)]
96
+
struct UploadPhotoResponse {
97
+
#[serde(rename = "photoUri")]
98
+
photo_uri: String,
99
+
}
100
+
101
+
fn exit_with_error(message: &str, code: i32) -> ! {
102
+
eprintln!("{}", message);
103
+
process::exit(code);
104
+
}
105
+
106
+
async fn make_request<T>(
107
+
client: &Client,
108
+
url: &str,
109
+
method: Method,
110
+
body: Option<Vec<u8>>,
111
+
token: Option<&str>,
112
+
content_type: Option<&str>,
113
+
) -> Result<T>
114
+
where
115
+
T: for<'de> Deserialize<'de>,
116
+
{
117
+
let mut headers = HeaderMap::new();
118
+
headers.insert("Accept", "application/json".parse()?);
119
+
120
+
if let Some(token) = token {
121
+
headers.insert("Authorization", format!("Bearer {}", token).parse()?);
122
+
}
123
+
124
+
if let Some(ct) = content_type {
125
+
headers.insert("Content-Type", ct.parse()?);
126
+
}
127
+
128
+
let mut request = client.request(method, url).headers(headers);
129
+
130
+
if let Some(body) = body {
131
+
request = request.body(body);
132
+
}
133
+
134
+
let response = request.send().await?;
135
+
136
+
let status = response.status();
137
+
if !status.is_success() {
138
+
let text = response.text().await?;
139
+
return Err(anyhow::anyhow!("HTTP {}: {}", status, text));
140
+
}
141
+
142
+
let content_type = response.headers()
143
+
.get("content-type")
144
+
.and_then(|v| v.to_str().ok())
145
+
.unwrap_or("");
146
+
147
+
if !content_type.contains("application/json") {
148
+
return Err(anyhow::anyhow!("Expected JSON response"));
149
+
}
150
+
151
+
let data: T = response.json().await?;
152
+
Ok(data)
153
+
}
154
+
155
+
fn get_auth_file_path() -> Result<std::path::PathBuf> {
156
+
let config_dir = dirs::config_dir()
157
+
.ok_or_else(|| anyhow::anyhow!("Unable to determine config directory"))?;
158
+
let grain_config_dir = config_dir.join("grain");
159
+
fs::create_dir_all(&grain_config_dir)?;
160
+
Ok(grain_config_dir.join("auth.json"))
161
+
}
162
+
163
+
async fn load_auth() -> Result<AuthData> {
164
+
let auth_file = get_auth_file_path()?;
165
+
let auth_text = fs::read_to_string(&auth_file)
166
+
.with_context(|| "Please run 'login' first")?;
167
+
168
+
let auth: AuthData = serde_json::from_str(&auth_text)
169
+
.with_context(|| "Invalid auth file format")?;
170
+
171
+
if auth.did.is_empty() || auth.token.is_empty() {
172
+
exit_with_error("Please re-authenticate.", 1);
173
+
}
174
+
175
+
if let Some(expires_at) = &auth.expires_at {
176
+
if let Ok(expires) = chrono::DateTime::parse_from_rfc3339(expires_at) {
177
+
if chrono::Utc::now() >= expires {
178
+
exit_with_error("Authentication expired. Please re-authenticate.", 1);
179
+
}
180
+
}
181
+
}
182
+
183
+
Ok(auth)
184
+
}
185
+
186
+
187
+
async fn handle_login(client: &Client, verbose: bool) -> Result<()> {
188
+
let handle: String = Input::new()
189
+
.with_prompt("Enter your handle")
190
+
.default("ansel.grain.social".to_string())
191
+
.interact()?;
192
+
193
+
let login_url = format!("{}/oauth/login?handle={}&client=cli", API_BASE, urlencoding::encode(&handle));
194
+
195
+
let data: LoginResponse = make_request(
196
+
client,
197
+
&login_url,
198
+
Method::POST,
199
+
None,
200
+
None,
201
+
None,
202
+
).await?;
203
+
204
+
if verbose {
205
+
println!("Login response: {:?}", data);
206
+
}
207
+
208
+
if let Some(url) = data.url {
209
+
let result = Arc::new(Mutex::new(None::<HashMap<String, String>>));
210
+
let (tx, mut rx) = tokio::sync::oneshot::channel::<()>();
211
+
let tx = Arc::new(Mutex::new(Some(tx)));
212
+
213
+
if verbose {
214
+
println!("Waiting for OAuth redirect on http://localhost:{}{}...", OAUTH_PORT, OAUTH_PATH);
215
+
}
216
+
217
+
// Open browser
218
+
open::that(&url)?;
219
+
if verbose {
220
+
println!("Opened browser for: {}", url);
221
+
}
222
+
223
+
// Start OAuth server with timeout
224
+
let listener = TcpListener::bind((std::net::Ipv4Addr::new(127, 0, 0, 1), OAUTH_PORT)).await?;
225
+
226
+
let result_for_task = result.clone();
227
+
let tx_for_task = tx.clone();
228
+
229
+
let server_task = async move {
230
+
if verbose {
231
+
println!("OAuth server listening on port {}...", OAUTH_PORT);
232
+
}
233
+
234
+
match listener.accept().await {
235
+
Ok((stream, addr)) => {
236
+
if verbose {
237
+
println!("Received connection from: {}", addr);
238
+
}
239
+
240
+
let io = TokioIo::new(stream);
241
+
let result_clone = result_for_task.clone();
242
+
let tx_clone = tx_for_task.clone();
243
+
244
+
let service = service_fn(move |req: Request<IncomingBody>| {
245
+
let result = result_clone.clone();
246
+
let tx = tx_clone.clone();
247
+
async move {
248
+
let uri = req.uri();
249
+
if verbose {
250
+
println!("Received request: {} {}", req.method(), uri);
251
+
}
252
+
253
+
if uri.path() == OAUTH_PATH {
254
+
if verbose {
255
+
println!("Matched OAuth callback path: {}", OAUTH_PATH);
256
+
}
257
+
258
+
if let Some(query) = uri.query() {
259
+
if verbose {
260
+
println!("Query string: {}", query);
261
+
}
262
+
263
+
let params: HashMap<String, String> = url::form_urlencoded::parse(query.as_bytes())
264
+
.into_owned()
265
+
.collect();
266
+
267
+
if verbose {
268
+
println!("Parsed parameters: {:?}", params);
269
+
}
270
+
271
+
if let Ok(mut r) = result.lock() {
272
+
*r = Some(params);
273
+
if verbose {
274
+
println!("Successfully stored OAuth parameters");
275
+
}
276
+
277
+
// Signal that we have the parameters
278
+
if let Ok(mut tx_guard) = tx.lock() {
279
+
if let Some(sender) = tx_guard.take() {
280
+
let _ = sender.send(());
281
+
if verbose {
282
+
println!("Sent completion signal");
283
+
}
284
+
}
285
+
}
286
+
} else if verbose {
287
+
println!("Failed to lock result mutex");
288
+
}
289
+
} else if verbose {
290
+
println!("No query string found in OAuth callback");
291
+
}
292
+
293
+
let html = r#"
294
+
<!DOCTYPE html>
295
+
<html lang="en">
296
+
<head>
297
+
<meta charset="UTF-8" />
298
+
<title>Authentication Complete</title>
299
+
<style>
300
+
body { font-family: sans-serif; text-align: center; margin-top: 10vh; }
301
+
.box { display: inline-block; padding: 2em; border: 1px solid #ccc; border-radius: 8px; background: #fafafa; }
302
+
</style>
303
+
</head>
304
+
<body>
305
+
<div class="box">
306
+
<h1>✅ Authentication Complete</h1>
307
+
<p>You may now return to your terminal.</p>
308
+
<p>You can close this tab.</p>
309
+
</div>
310
+
</body>
311
+
</html>
312
+
"#;
313
+
314
+
Ok::<_, anyhow::Error>(Response::builder()
315
+
.status(StatusCode::OK)
316
+
.header("content-type", "text/html; charset=utf-8")
317
+
.body(Full::new(hyper::body::Bytes::from(html)))?)
318
+
} else {
319
+
if verbose {
320
+
println!("Path '{}' does not match OAuth callback path '{}'", uri.path(), OAUTH_PATH);
321
+
}
322
+
323
+
Ok(Response::builder()
324
+
.status(StatusCode::NOT_FOUND)
325
+
.body(Full::new(hyper::body::Bytes::from("Not found")))?)
326
+
}
327
+
}
328
+
});
329
+
330
+
// Handle the connection with timeout
331
+
if verbose {
332
+
println!("Serving HTTP connection...");
333
+
}
334
+
335
+
let connection = http1::Builder::new()
336
+
.serve_connection(io, service);
337
+
338
+
match tokio::time::timeout(Duration::from_secs(10), connection).await {
339
+
Ok(Ok(_)) => {
340
+
if verbose {
341
+
println!("Connection served successfully");
342
+
}
343
+
}
344
+
Ok(Err(e)) => {
345
+
if verbose {
346
+
println!("Connection error: {}", e);
347
+
}
348
+
}
349
+
Err(_) => {
350
+
if verbose {
351
+
println!("Connection handling timed out");
352
+
}
353
+
}
354
+
}
355
+
}
356
+
Err(e) => {
357
+
if verbose {
358
+
println!("Failed to accept connection: {}", e);
359
+
}
360
+
}
361
+
}
362
+
363
+
if verbose {
364
+
println!("Server task ending");
365
+
}
366
+
};
367
+
368
+
// Start the server task in the background
369
+
tokio::spawn(server_task);
370
+
371
+
// Wait for either the OAuth callback or timeout
372
+
tokio::select! {
373
+
_ = &mut rx => {
374
+
if verbose {
375
+
println!("OAuth callback received, proceeding...");
376
+
}
377
+
},
378
+
_ = tokio::time::sleep(OAUTH_TIMEOUT) => {
379
+
eprintln!("Timed out waiting for OAuth redirect.");
380
+
}
381
+
}
382
+
383
+
let params_result = {
384
+
let guard = result.lock();
385
+
match guard {
386
+
Ok(p) => p.clone(),
387
+
Err(_) => None,
388
+
}
389
+
};
390
+
391
+
if let Some(params) = params_result {
392
+
if verbose {
393
+
println!("Received redirect with params: {:?}", params);
394
+
}
395
+
save_auth_params(¶ms).await?;
396
+
println!("Login successful! You can now use other commands.");
397
+
} else {
398
+
eprintln!("No redirect received.");
399
+
}
400
+
}
401
+
402
+
Ok(())
403
+
}
404
+
405
+
async fn save_auth_params(params: &HashMap<String, String>) -> Result<()> {
406
+
let auth_file = get_auth_file_path()?;
407
+
let json = serde_json::to_string_pretty(params)?;
408
+
fs::write(&auth_file, json)?;
409
+
println!("Saved config data to {}", auth_file.display());
410
+
Ok(())
411
+
}
412
+
413
+
async fn fetch_galleries(client: &Client) -> Result<Vec<GalleryItem>> {
414
+
let auth = load_auth().await?;
415
+
let galleries_url = format!(
416
+
"{}/xrpc/social.grain.gallery.getActorGalleries?actor={}",
417
+
API_BASE,
418
+
urlencoding::encode(&auth.did)
419
+
);
420
+
421
+
let data: GalleriesResponse = make_request(
422
+
client,
423
+
&galleries_url,
424
+
Method::GET,
425
+
None,
426
+
Some(&auth.token),
427
+
None,
428
+
).await?;
429
+
430
+
Ok(data.items.unwrap_or_default())
431
+
}
432
+
433
+
async fn handle_galleries_list(client: &Client) -> Result<()> {
434
+
let items = fetch_galleries(client).await?;
435
+
436
+
if items.is_empty() {
437
+
println!("No galleries found.");
438
+
} else {
439
+
for item in items {
440
+
let count = item.items.as_ref().map(|i| i.len()).unwrap_or(0);
441
+
let title = item.title.as_deref().unwrap_or("Untitled");
442
+
println!("{} ({})", title, count);
443
+
}
444
+
}
445
+
446
+
Ok(())
447
+
}
448
+
449
+
async fn delete_gallery(client: &Client, gallery_uri: &str) -> Result<()> {
450
+
let auth = load_auth().await?;
451
+
let delete_url = format!("{}/xrpc/social.grain.gallery.deleteGallery", API_BASE);
452
+
453
+
let payload = serde_json::json!({
454
+
"uri": gallery_uri
455
+
});
456
+
457
+
let _response: Value = make_request(
458
+
client,
459
+
&delete_url,
460
+
Method::POST,
461
+
Some(payload.to_string().into_bytes()),
462
+
Some(&auth.token),
463
+
Some("application/json"),
464
+
).await?;
465
+
466
+
Ok(())
467
+
}
468
+
469
+
async fn handle_gallery_delete(client: &Client) -> Result<()> {
470
+
let galleries = fetch_galleries(client).await?;
471
+
472
+
if galleries.is_empty() {
473
+
println!("No galleries found to delete.");
474
+
return Ok(());
475
+
}
476
+
477
+
// Create selection options for dialoguer
478
+
let gallery_options: Vec<String> = galleries
479
+
.iter()
480
+
.map(|item| {
481
+
let count = item.items.as_ref().map(|i| i.len()).unwrap_or(0);
482
+
let title = item.title.as_deref().unwrap_or("Untitled");
483
+
format!("{} ({} items)", title, count)
484
+
})
485
+
.collect();
486
+
487
+
let selection = dialoguer::Select::new()
488
+
.with_prompt("Select a gallery to delete")
489
+
.items(&gallery_options)
490
+
.default(0)
491
+
.interact()?;
492
+
493
+
let selected_gallery = &galleries[selection];
494
+
let title = selected_gallery.title.as_deref().unwrap_or("Untitled");
495
+
496
+
let confirm = dialoguer::Confirm::new()
497
+
.with_prompt(format!("Are you sure you want to delete gallery '{}'? This action cannot be undone.", title))
498
+
.default(false)
499
+
.interact()?;
500
+
501
+
if confirm {
502
+
delete_gallery(client, &selected_gallery.uri).await?;
503
+
println!("Gallery '{}' deleted successfully.", title);
504
+
} else {
505
+
println!("Gallery deletion cancelled.");
506
+
}
507
+
508
+
Ok(())
509
+
}
510
+
511
+
async fn handle_gallery_show(client: &Client) -> Result<()> {
512
+
let galleries = fetch_galleries(client).await?;
513
+
514
+
if galleries.is_empty() {
515
+
println!("No galleries found to show.");
516
+
return Ok(());
517
+
}
518
+
519
+
// Create selection options for dialoguer
520
+
let gallery_options: Vec<String> = galleries
521
+
.iter()
522
+
.map(|item| {
523
+
let count = item.items.as_ref().map(|i| i.len()).unwrap_or(0);
524
+
let title = item.title.as_deref().unwrap_or("Untitled");
525
+
format!("{} ({} items)", title, count)
526
+
})
527
+
.collect();
528
+
529
+
let selection = dialoguer::Select::new()
530
+
.with_prompt("Select a gallery to open")
531
+
.items(&gallery_options)
532
+
.default(0)
533
+
.interact()?;
534
+
535
+
let selected_gallery = &galleries[selection];
536
+
let web_url = selected_gallery.uri.strip_prefix("at://").unwrap_or(&selected_gallery.uri);
537
+
let formatted_url = format!("https://grain.social/{}", web_url);
538
+
539
+
println!("Opening gallery in browser: {}", formatted_url);
540
+
open::that(&formatted_url)?;
541
+
542
+
Ok(())
543
+
}
544
+
545
+
async fn create_gallery(client: &Client, title: &str, description: &str) -> Result<String> {
546
+
let auth = load_auth().await?;
547
+
let create_url = format!("{}/xrpc/social.grain.gallery.createGallery", API_BASE);
548
+
549
+
let payload = serde_json::json!({
550
+
"title": title,
551
+
"description": description
552
+
});
553
+
554
+
let response: CreateGalleryResponse = make_request(
555
+
client,
556
+
&create_url,
557
+
Method::POST,
558
+
Some(payload.to_string().into_bytes()),
559
+
Some(&auth.token),
560
+
Some("application/json"),
561
+
).await?;
562
+
563
+
Ok(response.gallery_uri)
564
+
}
565
+
566
+
async fn upload_photo(client: &Client, image_buffer: &[u8]) -> Result<String> {
567
+
let auth = load_auth().await?;
568
+
let upload_url = format!("{}/xrpc/social.grain.photo.uploadPhoto", API_BASE);
569
+
570
+
let response: UploadPhotoResponse = make_request(
571
+
client,
572
+
&upload_url,
573
+
Method::POST,
574
+
Some(image_buffer.to_vec()),
575
+
Some(&auth.token),
576
+
Some("image/jpeg"),
577
+
).await?;
578
+
579
+
println!("Photo uploaded successfully: {}", response.photo_uri);
580
+
Ok(response.photo_uri)
581
+
}
582
+
583
+
async fn create_gallery_item(
584
+
client: &Client,
585
+
gallery_uri: &str,
586
+
photo_uri: &str,
587
+
position: u32,
588
+
) -> Result<()> {
589
+
let auth = load_auth().await?;
590
+
let create_url = format!("{}/xrpc/social.grain.gallery.createItem", API_BASE);
591
+
592
+
let payload = serde_json::json!({
593
+
"galleryUri": gallery_uri,
594
+
"photoUri": photo_uri,
595
+
"position": position
596
+
});
597
+
598
+
let _response: Value = make_request(
599
+
client,
600
+
&create_url,
601
+
Method::POST,
602
+
Some(payload.to_string().into_bytes()),
603
+
Some(&auth.token),
604
+
Some("application/json"),
605
+
).await?;
606
+
607
+
Ok(())
608
+
}
609
+
610
+
async fn handle_gallery_create(client: &Client, verbose: bool) -> Result<()> {
611
+
let title: String = Input::new()
612
+
.with_prompt("Gallery title")
613
+
.interact()?;
614
+
615
+
let description: String = Input::new()
616
+
.with_prompt("Gallery description (optional)")
617
+
.allow_empty(true)
618
+
.interact()?;
619
+
620
+
let folder_path: String = Input::new()
621
+
.with_prompt("Path to folder of image files to upload")
622
+
.validate_with(|input: &String| -> Result<(), &str> {
623
+
let path = Path::new(input);
624
+
if !path.exists() {
625
+
return Err("Directory does not exist");
626
+
}
627
+
if !path.is_dir() {
628
+
return Err("Path is not a directory");
629
+
}
630
+
Ok(())
631
+
})
632
+
.interact()?;
633
+
634
+
// List image files in the folder
635
+
let image_extensions = [".jpg", ".jpeg"];
636
+
let mut image_files = Vec::new();
637
+
638
+
let entries = fs::read_dir(&folder_path)?;
639
+
for entry in entries {
640
+
let entry = entry?;
641
+
if entry.file_type()?.is_file() {
642
+
let file_name = entry.file_name();
643
+
let file_name_str = file_name.to_string_lossy().to_lowercase();
644
+
if image_extensions.iter().any(|ext| file_name_str.ends_with(ext)) {
645
+
image_files.push(entry.file_name().to_string_lossy().to_string());
646
+
}
647
+
}
648
+
}
649
+
650
+
if image_files.is_empty() {
651
+
exit_with_error("No image files found in the selected folder.", 1);
652
+
}
653
+
654
+
println!("Found {} image files in '{}':", image_files.len(), folder_path);
655
+
for file in &image_files {
656
+
println!(" - {}", file);
657
+
}
658
+
659
+
let confirm = Confirm::new()
660
+
.with_prompt(format!("Are you sure you want to upload these {} images?", image_files.len()))
661
+
.default(true)
662
+
.interact()?;
663
+
664
+
if !confirm {
665
+
println!("Aborted by user.");
666
+
return Ok(());
667
+
}
668
+
669
+
let gallery_uri = create_gallery(client, &title, &description).await?;
670
+
671
+
let pb = ProgressBar::new(image_files.len() as u64);
672
+
pb.set_style(
673
+
ProgressStyle::default_bar()
674
+
.template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} {msg}")
675
+
.unwrap()
676
+
.progress_chars("#>-")
677
+
);
678
+
679
+
let mut position = 0;
680
+
681
+
for file_name in image_files {
682
+
pb.set_message(format!("Processing {}", file_name));
683
+
684
+
let file_path = format!("{}/{}", folder_path, file_name);
685
+
let file_data = fs::read(&file_path)?;
686
+
687
+
let resized = do_resize(&file_data, ResizeOptions {
688
+
width: 2000,
689
+
height: 2000,
690
+
max_size: 1000 * 1000, // 1MB
691
+
mode: "inside".to_string(),
692
+
verbose,
693
+
})?;
694
+
695
+
let photo_uri = upload_photo(client, &resized.buffer).await?;
696
+
697
+
create_gallery_item(client, &gallery_uri, &photo_uri, position).await?;
698
+
position += 1;
699
+
pb.inc(1);
700
+
}
701
+
702
+
pb.finish_with_message("All images uploaded successfully!");
703
+
704
+
let web_url = gallery_uri.strip_prefix("at://").unwrap_or(&gallery_uri);
705
+
let formatted_url = format!("https://grain.social/{}", web_url);
706
+
println!("Here's a link to the gallery: {}", formatted_url);
707
+
708
+
Ok(())
709
+
}
710
+
711
+
#[tokio::main]
712
+
async fn main() -> Result<()> {
713
+
let cli = Cli::parse();
714
+
let client = Client::new();
715
+
716
+
match cli.command {
717
+
None => {
718
+
println!(r#"
719
+
██████╗ ██████╗ █████╗ ██╗███╗ ██╗
720
+
██╔════╝ ██╔══██╗██╔══██╗██║████╗ ██║
721
+
██║ ███╗██████╔╝███████║██║██╔██╗ ██║
722
+
██║ ██║██╔══██╗██╔══██║██║██║╚██╗██║
723
+
╚██████╔╝██║ ██║██║ ██║██║██║ ╚████║
724
+
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝
725
+
726
+
https://grain.social CLI
727
+
728
+
Use --help to see available commands.
729
+
"#);
730
+
}
731
+
Some(Commands::Login) => {
732
+
if let Err(e) = handle_login(&client, cli.verbose).await {
733
+
eprintln!("Login failed: {}", e);
734
+
}
735
+
}
736
+
Some(Commands::Gallery { action }) => {
737
+
match action {
738
+
GalleryAction::List => {
739
+
if let Err(e) = handle_galleries_list(&client).await {
740
+
exit_with_error(&format!("Failed to fetch galleries: {}", e), 1);
741
+
}
742
+
}
743
+
GalleryAction::Create => {
744
+
if let Err(e) = handle_gallery_create(&client, cli.verbose).await {
745
+
exit_with_error(&format!("Failed to create gallery: {}", e), 1);
746
+
}
747
+
}
748
+
GalleryAction::Delete => {
749
+
if let Err(e) = handle_gallery_delete(&client).await {
750
+
exit_with_error(&format!("Failed to delete gallery: {}", e), 1);
751
+
}
752
+
}
753
+
GalleryAction::Show => {
754
+
if let Err(e) = handle_gallery_show(&client).await {
755
+
exit_with_error(&format!("Failed to show gallery: {}", e), 1);
756
+
}
757
+
}
758
+
}
759
+
}
760
+
}
761
+
762
+
Ok(())
763
+
}
+129
cli/src/photo_manip.rs
+129
cli/src/photo_manip.rs
···
1
+
use anyhow::Result;
2
+
use image::codecs::jpeg::JpegEncoder;
3
+
use image::ExtendedColorType;
4
+
use std::io::Cursor;
5
+
use std::time::Instant;
6
+
7
+
pub struct ResizeOptions {
8
+
pub width: u32,
9
+
pub height: u32,
10
+
pub max_size: usize, // in bytes
11
+
pub mode: String,
12
+
pub verbose: bool,
13
+
}
14
+
15
+
pub struct ResizeResult {
16
+
pub buffer: Vec<u8>,
17
+
}
18
+
19
+
pub fn do_resize(input: &[u8], opts: ResizeOptions) -> Result<ResizeResult> {
20
+
let start_time = Instant::now();
21
+
if opts.verbose {
22
+
eprintln!("Starting image resize - input size: {} bytes, target: {}x{}, max_size: {} bytes",
23
+
input.len(), opts.width, opts.height, opts.max_size);
24
+
}
25
+
26
+
let img_load_start = Instant::now();
27
+
let img = image::load_from_memory(input)?;
28
+
if opts.verbose {
29
+
eprintln!("Image loaded in {:?} - dimensions: {}x{}", img_load_start.elapsed(), img.width(), img.height());
30
+
}
31
+
32
+
let resize_start = Instant::now();
33
+
let resized = match opts.mode.as_str() {
34
+
"inside" => img.resize(opts.width, opts.height, image::imageops::FilterType::Triangle),
35
+
"cover" => img.resize_to_fill(opts.width, opts.height, image::imageops::FilterType::Triangle),
36
+
_ => img.resize(opts.width, opts.height, image::imageops::FilterType::Triangle),
37
+
};
38
+
if opts.verbose {
39
+
eprintln!("Image resized in {:?} - new dimensions: {}x{}", resize_start.elapsed(), resized.width(), resized.height());
40
+
}
41
+
42
+
// Binary search for the best quality that fits under max_size
43
+
let mut best_result: Option<ResizeResult> = None;
44
+
let mut min_quality = 1u8;
45
+
let mut max_quality = 100u8;
46
+
let mut iteration = 0;
47
+
48
+
let search_start = Instant::now();
49
+
if opts.verbose {
50
+
eprintln!("Starting binary search for optimal quality");
51
+
}
52
+
53
+
while max_quality > min_quality + 1 {
54
+
iteration += 1;
55
+
let quality = (min_quality + max_quality) / 2;
56
+
let encode_start = Instant::now();
57
+
58
+
let mut buffer = Vec::new();
59
+
{
60
+
let mut cursor = Cursor::new(&mut buffer);
61
+
let mut encoder = JpegEncoder::new_with_quality(&mut cursor, quality);
62
+
encoder.encode(
63
+
resized.as_bytes(),
64
+
resized.width(),
65
+
resized.height(),
66
+
ExtendedColorType::Rgb8,
67
+
)?;
68
+
}
69
+
70
+
let size = buffer.len();
71
+
if opts.verbose {
72
+
eprintln!("Iteration {}: quality={}, size={} bytes, encoded in {:?}",
73
+
iteration, quality, size, encode_start.elapsed());
74
+
}
75
+
76
+
if size <= opts.max_size {
77
+
min_quality = quality;
78
+
best_result = Some(ResizeResult {
79
+
buffer,
80
+
});
81
+
if opts.verbose {
82
+
eprintln!(" -> Fits! New min_quality: {}", min_quality);
83
+
}
84
+
} else {
85
+
max_quality = quality;
86
+
if opts.verbose {
87
+
eprintln!(" -> Too large! New max_quality: {}", max_quality);
88
+
}
89
+
}
90
+
}
91
+
92
+
if opts.verbose {
93
+
eprintln!("Binary search completed in {:?} after {} iterations", search_start.elapsed(), iteration);
94
+
}
95
+
96
+
// Try with minimum quality if no result yet
97
+
if best_result.is_none() {
98
+
if opts.verbose {
99
+
eprintln!("No result found, trying minimum quality: {}", min_quality);
100
+
}
101
+
let final_encode_start = Instant::now();
102
+
103
+
let mut buffer = Vec::new();
104
+
{
105
+
let mut cursor = Cursor::new(&mut buffer);
106
+
let mut encoder = JpegEncoder::new_with_quality(&mut cursor, min_quality);
107
+
encoder.encode(
108
+
resized.as_bytes(),
109
+
resized.width(),
110
+
resized.height(),
111
+
ExtendedColorType::Rgb8,
112
+
)?;
113
+
}
114
+
115
+
if opts.verbose {
116
+
eprintln!("Final encode with quality {} completed in {:?}, size: {} bytes",
117
+
min_quality, final_encode_start.elapsed(), buffer.len());
118
+
}
119
+
120
+
best_result = Some(ResizeResult {
121
+
buffer,
122
+
});
123
+
}
124
+
125
+
if opts.verbose {
126
+
eprintln!("Total resize operation completed in {:?}", start_time.elapsed());
127
+
}
128
+
best_result.ok_or_else(|| anyhow::anyhow!("Failed to compress image"))
129
+
}
cli/test_photos/R0090101.JPG
cli/test_photos/R0090101.JPG
This is a binary file and will not be displayed.
cli/test_photos/R0090102.JPG
cli/test_photos/R0090102.JPG
This is a binary file and will not be displayed.
cli/test_photos/R0090104.JPG
cli/test_photos/R0090104.JPG
This is a binary file and will not be displayed.