+3
.gitignore
+3
.gitignore
-2
.npmrc
-2
.npmrc
+1
-1
.vscode/settings.json
+1
-1
.vscode/settings.json
+14
LICENSE
+14
LICENSE
···
1
+
BSD Zero Clause License
2
+
3
+
Copyright (c) 2025 Mary
4
+
5
+
Permission to use, copy, modify, and/or distribute this software for any
6
+
purpose with or without fee is hereby granted.
7
+
8
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14
+
PERFORMANCE OF THIS SOFTWARE.
+32
-31
package.json
+32
-31
package.json
···
4
4
"dev": "vite",
5
5
"build": "tsc -b && vite build",
6
6
"preview": "vite preview",
7
-
"fmt": "prettier --cache --write ."
7
+
"fmt": "PRETTIER_EXPERIMENTAL_CLI=1 prettier --cache --write ."
8
8
},
9
9
"dependencies": {
10
-
"@atcute/atproto": "^3.0.2",
11
-
"@atcute/bluesky": "^3.0.2",
12
-
"@atcute/car": "^3.1.1",
13
-
"@atcute/cbor": "^2.2.4",
14
-
"@atcute/cid": "^2.2.3",
15
-
"@atcute/client": "^4.0.3",
16
-
"@atcute/crypto": "^2.2.2",
17
-
"@atcute/did-plc": "^0.1.5",
18
-
"@atcute/identity": "^1.0.2",
19
-
"@atcute/identity-resolver": "^1.1.0",
20
-
"@atcute/lexicons": "^1.0.3",
21
-
"@atcute/multibase": "^1.1.4",
22
-
"@atcute/tid": "^1.0.2",
23
-
"@badrap/valita": "^0.4.5",
24
-
"@mary/array-fns": "npm:@jsr/mary__array-fns@^0.1.4",
25
-
"@mary/ds-queue": "npm:@jsr/mary__ds-queue@^0.1.2",
26
-
"@mary/events": "npm:@jsr/mary__events@^0.2.0",
10
+
"@atcute/atproto": "^3.1.9",
11
+
"@atcute/bluesky": "^3.2.13",
12
+
"@atcute/car": "^5.0.0",
13
+
"@atcute/cbor": "^2.2.8",
14
+
"@atcute/cid": "^2.2.6",
15
+
"@atcute/client": "^4.1.1",
16
+
"@atcute/crypto": "^2.3.0",
17
+
"@atcute/did-plc": "^0.2.0",
18
+
"@atcute/identity": "^1.1.3",
19
+
"@atcute/identity-resolver": "^1.2.0",
20
+
"@atcute/lexicons": "^1.2.5",
21
+
"@atcute/multibase": "^1.1.6",
22
+
"@atcute/repo": "^0.1.0",
23
+
"@atcute/tid": "^1.0.3",
24
+
"@badrap/valita": "^0.4.6",
25
+
"@mary/array-fns": "jsr:^0.1.5",
26
+
"@mary/ds-queue": "jsr:^0.1.3",
27
+
"@mary/events": "jsr:^0.2.0",
27
28
"@mary/solid-freeze": "npm:@externdefs/solid-freeze@^0.1.1",
28
-
"@mary/tar": "npm:@jsr/mary__tar@^0.2.4",
29
-
"nanoid": "^5.1.5",
29
+
"@mary/tar": "jsr:^0.3.1",
30
+
"nanoid": "^5.1.6",
30
31
"native-file-system-adapter": "^3.0.1",
31
-
"solid-js": "^1.9.7"
32
+
"solid-js": "^1.9.10"
32
33
},
33
34
"devDependencies": {
34
35
"@tailwindcss/forms": "^0.5.10",
35
-
"@types/node": "^22.15.21",
36
-
"autoprefixer": "^10.4.21",
37
-
"prettier": "^3.5.3",
38
-
"prettier-plugin-tailwindcss": "^0.6.11",
39
-
"tailwindcss": "^3.4.17",
40
-
"terser": "^5.39.2",
41
-
"typescript": "~5.8.3",
42
-
"vite": "^6.3.5",
43
-
"vite-plugin-solid": "^2.11.6",
44
-
"wrangler": "^4.16.1"
36
+
"@types/node": "^22.19.2",
37
+
"autoprefixer": "^10.4.22",
38
+
"prettier": "^3.7.4",
39
+
"prettier-plugin-tailwindcss": "^0.6.14",
40
+
"tailwindcss": "^3.4.18",
41
+
"terser": "^5.44.1",
42
+
"typescript": "~5.9.3",
43
+
"vite": "^7.2.7",
44
+
"vite-plugin-solid": "^2.11.10",
45
+
"wrangler": "^4.53.0"
45
46
}
46
47
}
+957
-1151
pnpm-lock.yaml
+957
-1151
pnpm-lock.yaml
···
9
9
.:
10
10
dependencies:
11
11
'@atcute/atproto':
12
-
specifier: ^3.0.2
13
-
version: 3.0.2
12
+
specifier: ^3.1.9
13
+
version: 3.1.9
14
14
'@atcute/bluesky':
15
-
specifier: ^3.0.2
16
-
version: 3.0.2
15
+
specifier: ^3.2.13
16
+
version: 3.2.13
17
17
'@atcute/car':
18
-
specifier: ^3.1.1
19
-
version: 3.1.1
18
+
specifier: ^5.0.0
19
+
version: 5.0.0
20
20
'@atcute/cbor':
21
-
specifier: ^2.2.4
22
-
version: 2.2.4
21
+
specifier: ^2.2.8
22
+
version: 2.2.8
23
23
'@atcute/cid':
24
-
specifier: ^2.2.3
25
-
version: 2.2.3
24
+
specifier: ^2.2.6
25
+
version: 2.2.6
26
26
'@atcute/client':
27
-
specifier: ^4.0.3
28
-
version: 4.0.3
27
+
specifier: ^4.1.1
28
+
version: 4.1.1
29
29
'@atcute/crypto':
30
-
specifier: ^2.2.2
31
-
version: 2.2.2
30
+
specifier: ^2.3.0
31
+
version: 2.3.0
32
32
'@atcute/did-plc':
33
-
specifier: ^0.1.5
34
-
version: 0.1.5
33
+
specifier: ^0.2.0
34
+
version: 0.2.0
35
35
'@atcute/identity':
36
-
specifier: ^1.0.2
37
-
version: 1.0.2
36
+
specifier: ^1.1.3
37
+
version: 1.1.3
38
38
'@atcute/identity-resolver':
39
-
specifier: ^1.1.0
40
-
version: 1.1.0(@atcute/identity@1.0.2)
39
+
specifier: ^1.2.0
40
+
version: 1.2.0(@atcute/identity@1.1.3)
41
41
'@atcute/lexicons':
42
+
specifier: ^1.2.5
43
+
version: 1.2.5
44
+
'@atcute/multibase':
45
+
specifier: ^1.1.6
46
+
version: 1.1.6
47
+
'@atcute/repo':
48
+
specifier: ^0.1.0
49
+
version: 0.1.0
50
+
'@atcute/tid':
42
51
specifier: ^1.0.3
43
52
version: 1.0.3
44
-
'@atcute/multibase':
45
-
specifier: ^1.1.4
46
-
version: 1.1.4
47
-
'@atcute/tid':
48
-
specifier: ^1.0.2
49
-
version: 1.0.2
50
53
'@badrap/valita':
51
-
specifier: ^0.4.5
52
-
version: 0.4.5
54
+
specifier: ^0.4.6
55
+
version: 0.4.6
53
56
'@mary/array-fns':
54
-
specifier: npm:@jsr/mary__array-fns@^0.1.4
55
-
version: '@jsr/mary__array-fns@0.1.4'
57
+
specifier: jsr:^0.1.5
58
+
version: '@jsr/mary__array-fns@0.1.5'
56
59
'@mary/ds-queue':
57
-
specifier: npm:@jsr/mary__ds-queue@^0.1.2
58
-
version: '@jsr/mary__ds-queue@0.1.2'
60
+
specifier: jsr:^0.1.3
61
+
version: '@jsr/mary__ds-queue@0.1.3'
59
62
'@mary/events':
60
-
specifier: npm:@jsr/mary__events@^0.2.0
63
+
specifier: jsr:^0.2.0
61
64
version: '@jsr/mary__events@0.2.0'
62
65
'@mary/solid-freeze':
63
66
specifier: npm:@externdefs/solid-freeze@^0.1.1
64
-
version: '@externdefs/solid-freeze@0.1.1(solid-js@1.9.7)'
67
+
version: '@externdefs/solid-freeze@0.1.1(solid-js@1.9.10)'
65
68
'@mary/tar':
66
-
specifier: npm:@jsr/mary__tar@^0.2.4
67
-
version: '@jsr/mary__tar@0.2.4'
69
+
specifier: jsr:^0.3.1
70
+
version: '@jsr/mary__tar@0.3.1'
68
71
nanoid:
69
-
specifier: ^5.1.5
70
-
version: 5.1.5
72
+
specifier: ^5.1.6
73
+
version: 5.1.6
71
74
native-file-system-adapter:
72
75
specifier: ^3.0.1
73
76
version: 3.0.1
74
77
solid-js:
75
-
specifier: ^1.9.7
76
-
version: 1.9.7
78
+
specifier: ^1.9.10
79
+
version: 1.9.10
77
80
devDependencies:
78
81
'@tailwindcss/forms':
79
82
specifier: ^0.5.10
80
-
version: 0.5.10(tailwindcss@3.4.17)
83
+
version: 0.5.10(tailwindcss@3.4.18)
81
84
'@types/node':
82
-
specifier: ^22.15.21
83
-
version: 22.15.21
85
+
specifier: ^22.19.2
86
+
version: 22.19.2
84
87
autoprefixer:
85
-
specifier: ^10.4.21
86
-
version: 10.4.21(postcss@8.5.3)
88
+
specifier: ^10.4.22
89
+
version: 10.4.22(postcss@8.5.6)
87
90
prettier:
88
-
specifier: ^3.5.3
89
-
version: 3.5.3
91
+
specifier: ^3.7.4
92
+
version: 3.7.4
90
93
prettier-plugin-tailwindcss:
91
-
specifier: ^0.6.11
92
-
version: 0.6.11(prettier@3.5.3)
94
+
specifier: ^0.6.14
95
+
version: 0.6.14(prettier@3.7.4)
93
96
tailwindcss:
94
-
specifier: ^3.4.17
95
-
version: 3.4.17
97
+
specifier: ^3.4.18
98
+
version: 3.4.18
96
99
terser:
97
-
specifier: ^5.39.2
98
-
version: 5.39.2
100
+
specifier: ^5.44.1
101
+
version: 5.44.1
99
102
typescript:
100
-
specifier: ~5.8.3
101
-
version: 5.8.3
103
+
specifier: ~5.9.3
104
+
version: 5.9.3
102
105
vite:
103
-
specifier: ^6.3.5
104
-
version: 6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0)
106
+
specifier: ^7.2.7
107
+
version: 7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1)
105
108
vite-plugin-solid:
106
-
specifier: ^2.11.6
107
-
version: 2.11.6(solid-js@1.9.7)(vite@6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0))
109
+
specifier: ^2.11.10
110
+
version: 2.11.10(solid-js@1.9.10)(vite@7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1))
108
111
wrangler:
109
-
specifier: ^4.16.1
110
-
version: 4.16.1
112
+
specifier: ^4.53.0
113
+
version: 4.53.0
111
114
112
115
packages:
113
116
···
115
118
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
116
119
engines: {node: '>=10'}
117
120
118
-
'@ampproject/remapping@2.3.0':
119
-
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
120
-
engines: {node: '>=6.0.0'}
121
-
122
-
'@atcute/atproto@3.0.2':
123
-
resolution: {integrity: sha512-p37GqTmrxc1XaxtX8JsePEuomL+PtDeGdy0lcBm+HisD03ZZTia7MouxUpnYezX0l926fFaDc9tllIBtX9iSsQ==}
121
+
'@atcute/atproto@3.1.9':
122
+
resolution: {integrity: sha512-DyWwHCTdR4hY2BPNbLXgVmm7lI+fceOwWbE4LXbGvbvVtSn+ejSVFaAv01Ra3kWDha0whsOmbJL8JP0QPpf1+w==}
124
123
125
-
'@atcute/bluesky@3.0.2':
126
-
resolution: {integrity: sha512-xDRu/8Rlu3uTG/Mf625vUvKiFvy3hdCE371pXSJpHofivNZxi+MburdmYgOsBWZstNMo4vTBUviWaLJpL23rFg==}
124
+
'@atcute/bluesky@3.2.13':
125
+
resolution: {integrity: sha512-ZG/mqsCjVU6zvH6XsRw+oQglrsdu5R7mnncMO+Ux0KWbX2xJw4ZMFHfs7ZTC69dVPK9r/yle7YbpygZTOWDM9A==}
127
126
128
-
'@atcute/car@3.1.1':
129
-
resolution: {integrity: sha512-yhez/LqIl0zHubG6z/G/gqWYHmg7wJ5L4jNkbXj5FvZ4eOvmzsw8+ojbdq6wfMU4p5NhP0pUJNLkTZHbYSPmLg==}
127
+
'@atcute/car@5.0.0':
128
+
resolution: {integrity: sha512-OIY2xTXv8lSpZsDSn/UYQtJSMvDw5Hi4Q+uyvmiqSM+fht08QRAEq/nxa5YFciPZ3nfDFnZ3//EgJw7QhkSXLQ==}
130
129
131
-
'@atcute/cbor@2.2.4':
132
-
resolution: {integrity: sha512-8Y/OTM8zs5VInOCjfx4f9Idiiz7ygM/FkfWv/HW3/ZUsXczn1xk7GzTBbm4P5crn4C5luwDGpO7FwClMOERrow==}
130
+
'@atcute/cbor@2.2.8':
131
+
resolution: {integrity: sha512-UzOAN9BuN6JCXgn0ryV8qZuRJUDrNqrbLd6EFM8jc6RYssjRyGRxNy6RZ1NU/07Hd8Tq/0pz8+nQiMu5Zai5uw==}
133
132
134
-
'@atcute/cid@2.2.3':
135
-
resolution: {integrity: sha512-WEzNSL1EuCVtCQDFYEBIm4dEP6PcMEwi8IYUVIWvT77eO5EjY58F63z5T4qMABxSBM0+L4kqMxypdL1Fzf6LZw==}
133
+
'@atcute/cid@2.2.6':
134
+
resolution: {integrity: sha512-bTAHHbJ24p+E//V4KCS4xdmd39o211jJswvqQOevj7vk+5IYcgDLx1ryZWZ1sEPOo9x875li/kj5gpKL14RDwQ==}
136
135
137
-
'@atcute/client@4.0.3':
138
-
resolution: {integrity: sha512-RIOZWFVLca/HiPAAUDqQPOdOreCxTbL5cb+WUf5yqQOKIu5yEAP3eksinmlLmgIrlr5qVOE7brazUUzaskFCfw==}
136
+
'@atcute/client@4.1.1':
137
+
resolution: {integrity: sha512-FROCbTTCeL5u4tO/n72jDEKyKqjdlXMB56Ehve3W/gnnLGCYWvN42sS7tvL1Mgu6sbO3yZwsXKDrmM2No4XpjA==}
139
138
140
-
'@atcute/crypto@2.2.2':
141
-
resolution: {integrity: sha512-zpJjB6m0+Wy4YrgBJTSps4wbi3Xv1z/yZO/m/3sUYl1bIqUdHhH3vmDJtiXkRONgKNhiaQdukyt0omd9n4vDUA==}
139
+
'@atcute/crypto@2.3.0':
140
+
resolution: {integrity: sha512-w5pkJKCjbNMQu+F4JRHbR3ROQyhi1wbn+GSC6WDQamcYHkZmEZk1/eoI354bIQOOfkEM6aFLv718iskrkon4GQ==}
142
141
143
-
'@atcute/did-plc@0.1.5':
144
-
resolution: {integrity: sha512-f0UTge7i1MgHNk73SKN2FE/nt/FzRyEypIbc85hL32sig0kCs87yZ2W+1okBkaBoQ6Fis2ILwwAA5VAUJE3Yng==}
142
+
'@atcute/did-plc@0.2.0':
143
+
resolution: {integrity: sha512-1sGek8GRM/Ph7nLVRREm8FqM7g4shGckItvdVwJcRbUa8Rh0zOsXQa0QyYWAC0k40BhkqO9FwKXhJEaXCmF5oQ==}
145
144
146
-
'@atcute/identity-resolver@1.1.0':
147
-
resolution: {integrity: sha512-Ak41aYsQwW1xPan7BXM6TfQ18AkQg8RVH2s7Ppcg3b7YJUo8v24KJXaYoha3t+Tcr0T1xx56j/vZPIfwUG+b4g==}
145
+
'@atcute/identity-resolver@1.2.0':
146
+
resolution: {integrity: sha512-5UbSJfdV3JIkF8ksXz7g4nKBWasf2wROvzM66cfvTIWydWFO6/oS1KZd+zo9Eokje5Scf5+jsY9ZfgVARLepXg==}
148
147
peerDependencies:
149
148
'@atcute/identity': ^1.0.0
150
149
151
-
'@atcute/identity@1.0.2':
152
-
resolution: {integrity: sha512-SrDPHuEarEHj9bx7NfYn7DYG6kIgJIMRU581iOCIaVaiZ1WhE9D8QxTxeYG/rbGNSa85E891ECp1sQcKiBN0kg==}
150
+
'@atcute/identity@1.1.3':
151
+
resolution: {integrity: sha512-oIqPoI8TwWeQxvcLmFEZLdN2XdWcaLVtlm8pNk0E72As9HNzzD9pwKPrLr3rmTLRIoULPPFmq9iFNsTeCIU9ng==}
152
+
153
+
'@atcute/lexicons@1.2.5':
154
+
resolution: {integrity: sha512-9yO9WdgxW8jZ7SbzUycH710z+JmsQ9W9n5S6i6eghYju32kkluFmgBeS47r8e8p2+Dv4DemS7o/3SUGsX9FR5Q==}
153
155
154
-
'@atcute/lexicons@1.0.3':
155
-
resolution: {integrity: sha512-R4xa3AMD+uMNn67/Nly0ohieT+vuN2qeV8Oq/mkpb0O3pFTuG7IkhXEGIXVnFY6I/NEQGhWB1FjHYpgRyL35Pw==}
156
+
'@atcute/mst@0.1.0':
157
+
resolution: {integrity: sha512-h+iDToKEnBpigk2DOHjSqY63vJtjYKUIztqu1CZ0P+I54wV2SrgoqAXAT1xrW6A1Iup8cjTv+U2H5WVG4KxPLw==}
156
158
157
-
'@atcute/multibase@1.1.4':
158
-
resolution: {integrity: sha512-NUf5AeeSOmuZHGU+4GAaMtISJoG+ZHtW/vUVA4lK/YDt/7LODAW0Fd0NNIIUPVUoW0xJS6zSEIWvwLLuxmEHhA==}
159
+
'@atcute/multibase@1.1.6':
160
+
resolution: {integrity: sha512-HBxuCgYLKPPxETV0Rot4VP9e24vKl8JdzGCZOVsDaOXJgbRZoRIF67Lp0H/OgnJeH/Xpva8Z5ReoTNJE5dn3kg==}
159
161
160
-
'@atcute/tid@1.0.2':
161
-
resolution: {integrity: sha512-ahmjroNyeDPJhtuf3+HTJropaH04HmJ8fhntDu73Gpz/RkAF7+nkz6kcP2QTgfvMCgMPAJUdskAAP82GPDTY9w==}
162
+
'@atcute/repo@0.1.0':
163
+
resolution: {integrity: sha512-INiYAuma8dydBu7cqd2WVpcXh3mzhIepYBUqFWAK5MqMulPRLTRCc/9GW3G9pxYrOdlvLCVamG2Jf8XK0nuFEw==}
162
164
163
-
'@atcute/uint8array@1.0.2':
164
-
resolution: {integrity: sha512-JvD61GCKLknPFmusf34LVOPRb2rzl7BaJWt2ejxDz+/UzKCsHBYjhbeQgZg7w4hCXu1GVBAaKJMlXv+jRHW5IQ==}
165
+
'@atcute/tid@1.0.3':
166
+
resolution: {integrity: sha512-wfMJx1IMdnu0CZgWl0uR4JO2s6PGT1YPhpytD4ZHzEYKKQVuqV6Eb/7vieaVo1eYNMp2FrY67FZObeR7utRl2w==}
165
167
166
-
'@atcute/util-fetch@1.0.1':
167
-
resolution: {integrity: sha512-Clc0E/5ufyGBVfYBUwWNlHONlZCoblSr4Ho50l1LhmRPGB1Wu/AQ9Sz+rsBg7fdaW/auve8ulmwhRhnX2cGRow==}
168
+
'@atcute/uint8array@1.0.6':
169
+
resolution: {integrity: sha512-ucfRBQc7BFT8n9eCyGOzDHEMKF/nZwhS2pPao4Xtab1ML3HdFYcX2DM1tadCzas85QTGxHe5urnUAAcNKGRi9A==}
168
170
169
-
'@atcute/varint@1.0.2':
170
-
resolution: {integrity: sha512-0O31hePzzr4O3NGWHUKKOyta6CGSL+AtN8iir8grGxu9jXyI7DBARlw6PbgKA6uTAvsXdpmRmF8MX+p0TsLnNg==}
171
+
'@atcute/util-fetch@1.0.4':
172
+
resolution: {integrity: sha512-sIU9Qk0dE8PLEXSfhy+gIJV+HpiiknMytCI2SqLlqd0vgZUtEKI/EQfP+23LHWvP+CLCzVDOa6cpH045OlmNBg==}
173
+
174
+
'@atcute/varint@1.0.3':
175
+
resolution: {integrity: sha512-fdvMPyBB+McDT+Ai5e9RwEbwYV4yjZ60S2Dn5PTjGqUyxvoCH1z42viuheDZRUDkmfQehXJTZ5az7dSozVNtog==}
171
176
172
177
'@babel/code-frame@7.27.1':
173
178
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
174
179
engines: {node: '>=6.9.0'}
175
180
176
-
'@babel/compat-data@7.27.2':
177
-
resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==}
181
+
'@babel/compat-data@7.28.5':
182
+
resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==}
178
183
engines: {node: '>=6.9.0'}
179
184
180
-
'@babel/core@7.27.1':
181
-
resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==}
185
+
'@babel/core@7.28.5':
186
+
resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==}
182
187
engines: {node: '>=6.9.0'}
183
188
184
-
'@babel/generator@7.27.1':
185
-
resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==}
189
+
'@babel/generator@7.28.5':
190
+
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
186
191
engines: {node: '>=6.9.0'}
187
192
188
193
'@babel/helper-compilation-targets@7.27.2':
189
194
resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==}
195
+
engines: {node: '>=6.9.0'}
196
+
197
+
'@babel/helper-globals@7.28.0':
198
+
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
190
199
engines: {node: '>=6.9.0'}
191
200
192
201
'@babel/helper-module-imports@7.18.6':
···
197
206
resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
198
207
engines: {node: '>=6.9.0'}
199
208
200
-
'@babel/helper-module-transforms@7.27.1':
201
-
resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==}
209
+
'@babel/helper-module-transforms@7.28.3':
210
+
resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==}
202
211
engines: {node: '>=6.9.0'}
203
212
peerDependencies:
204
213
'@babel/core': ^7.0.0
···
211
220
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
212
221
engines: {node: '>=6.9.0'}
213
222
214
-
'@babel/helper-validator-identifier@7.27.1':
215
-
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
223
+
'@babel/helper-validator-identifier@7.28.5':
224
+
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
216
225
engines: {node: '>=6.9.0'}
217
226
218
227
'@babel/helper-validator-option@7.27.1':
219
228
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
220
229
engines: {node: '>=6.9.0'}
221
230
222
-
'@babel/helpers@7.27.1':
223
-
resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==}
231
+
'@babel/helpers@7.28.4':
232
+
resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==}
224
233
engines: {node: '>=6.9.0'}
225
234
226
-
'@babel/parser@7.27.2':
227
-
resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==}
235
+
'@babel/parser@7.28.5':
236
+
resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==}
228
237
engines: {node: '>=6.0.0'}
229
238
hasBin: true
230
239
···
238
247
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
239
248
engines: {node: '>=6.9.0'}
240
249
241
-
'@babel/traverse@7.27.1':
242
-
resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==}
250
+
'@babel/traverse@7.28.5':
251
+
resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==}
243
252
engines: {node: '>=6.9.0'}
244
253
245
-
'@babel/types@7.27.1':
246
-
resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==}
254
+
'@babel/types@7.28.5':
255
+
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
247
256
engines: {node: '>=6.9.0'}
248
257
249
-
'@badrap/valita@0.4.5':
250
-
resolution: {integrity: sha512-4QwGbuhh/JesHRQj79mO/l37PvJj4l/tlAu7+S1n4h47qwaNpZ0WDvIwUGLYUsdi9uQ5UPpiG9wb1Wm3XUFBUQ==}
258
+
'@badrap/valita@0.4.6':
259
+
resolution: {integrity: sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==}
251
260
engines: {node: '>= 18'}
252
261
253
-
'@cloudflare/kv-asset-handler@0.4.0':
254
-
resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==}
262
+
'@cloudflare/kv-asset-handler@0.4.1':
263
+
resolution: {integrity: sha512-Nu8ahitGFFJztxUml9oD/DLb7Z28C8cd8F46IVQ7y5Btz575pvMY8AqZsXkX7Gds29eCKdMgIHjIvzskHgPSFg==}
255
264
engines: {node: '>=18.0.0'}
256
265
257
-
'@cloudflare/unenv-preset@2.3.2':
258
-
resolution: {integrity: sha512-MtUgNl+QkQyhQvv5bbWP+BpBC1N0me4CHHuP2H4ktmOMKdB/6kkz/lo+zqiA4mEazb4y+1cwyNjVrQ2DWeE4mg==}
266
+
'@cloudflare/unenv-preset@2.7.13':
267
+
resolution: {integrity: sha512-NulO1H8R/DzsJguLC0ndMuk4Ufv0KSlN+E54ay9rn9ZCQo0kpAPwwh3LhgpZ96a3Dr6L9LqW57M4CqC34iLOvw==}
259
268
peerDependencies:
260
-
unenv: 2.0.0-rc.17
261
-
workerd: ^1.20250508.0
269
+
unenv: 2.0.0-rc.24
270
+
workerd: ^1.20251202.0
262
271
peerDependenciesMeta:
263
272
workerd:
264
273
optional: true
265
274
266
-
'@cloudflare/workerd-darwin-64@1.20250508.0':
267
-
resolution: {integrity: sha512-9x09MrA9Y5RQs3zqWvWns8xHgM2pVNXWpeJ+3hQYu4PrwPFZXtTD6b/iMmOnlYKzINlREq1RGeEybMFyWEUlUg==}
275
+
'@cloudflare/workerd-darwin-64@1.20251202.0':
276
+
resolution: {integrity: sha512-/uvEAWEukTWb1geHhbjGUeZqcSSSyYzp0mvoPUBl+l0ont4NVGao3fgwM0q8wtKvgoKCHSG6zcG23wj9Opj3Nw==}
268
277
engines: {node: '>=16'}
269
278
cpu: [x64]
270
279
os: [darwin]
271
280
272
-
'@cloudflare/workerd-darwin-arm64@1.20250508.0':
273
-
resolution: {integrity: sha512-0Ili+nE2LLRzYue/yPc1pepSyNNg6LxR3/ng/rlQzVQUxPXIXldHFkJ/ynsYwQnAcf6OxasSi/kbTm6yvDoSAQ==}
281
+
'@cloudflare/workerd-darwin-arm64@1.20251202.0':
282
+
resolution: {integrity: sha512-f52xRvcI9cWRd6400EZStRtXiRC5XKEud7K5aFIbbUv0VeINltujFQQ9nHWtsF6g1quIXWkjhh5u01gPAYNNXA==}
274
283
engines: {node: '>=16'}
275
284
cpu: [arm64]
276
285
os: [darwin]
277
286
278
-
'@cloudflare/workerd-linux-64@1.20250508.0':
279
-
resolution: {integrity: sha512-5saVrZ3uVwYxvBa7BaonXjeqB6X0YF3ak05qvBaWcmZ3FNmnarMm2W8842cnbhnckDVBpB/iDo51Sy6Y7y1jcw==}
287
+
'@cloudflare/workerd-linux-64@1.20251202.0':
288
+
resolution: {integrity: sha512-HYXinF5RBH7oXbsFUMmwKCj+WltpYbf5mRKUBG5v3EuPhUjSIFB84U+58pDyfBJjcynHdy3EtvTWcvh/+lcgow==}
280
289
engines: {node: '>=16'}
281
290
cpu: [x64]
282
291
os: [linux]
283
292
284
-
'@cloudflare/workerd-linux-arm64@1.20250508.0':
285
-
resolution: {integrity: sha512-muQe1pkxRi3eaq1Q417xvfGd2SlktbLTzNhT5Yftsx8OecWrYuB8i4ttR6Nr5ER06bfEj0FqQjqJJhcp6wLLUQ==}
293
+
'@cloudflare/workerd-linux-arm64@1.20251202.0':
294
+
resolution: {integrity: sha512-++L02Jdoxz7hEA9qDaQjbVU1RzQS+S+eqIi22DkPe2Tgiq2M3UfNpeu+75k5L9DGRIkZPYvwMBMbcmKvQqdIIg==}
286
295
engines: {node: '>=16'}
287
296
cpu: [arm64]
288
297
os: [linux]
289
298
290
-
'@cloudflare/workerd-windows-64@1.20250508.0':
291
-
resolution: {integrity: sha512-EJj8iTWFMqjgvZUxxNvzK7frA1JMFi3y/9eDIdZPL/OaQh3cmk5Lai5DCXsKYUxfooMBZWYTp53zOLrvuJI8VQ==}
299
+
'@cloudflare/workerd-windows-64@1.20251202.0':
300
+
resolution: {integrity: sha512-gzeU6eDydTi7ib+Q9DD/c0hpXtqPucnHk2tfGU03mljPObYxzMkkPGgB5qxpksFvub3y4K0ChjqYxGJB4F+j3g==}
292
301
engines: {node: '>=16'}
293
302
cpu: [x64]
294
303
os: [win32]
···
297
306
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
298
307
engines: {node: '>=12'}
299
308
300
-
'@emnapi/runtime@1.4.3':
301
-
resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==}
309
+
'@emnapi/runtime@1.7.1':
310
+
resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==}
302
311
303
-
'@esbuild/aix-ppc64@0.25.4':
304
-
resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==}
312
+
'@esbuild/aix-ppc64@0.25.12':
313
+
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
305
314
engines: {node: '>=18'}
306
315
cpu: [ppc64]
307
316
os: [aix]
308
317
309
-
'@esbuild/aix-ppc64@0.25.5':
310
-
resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==}
318
+
'@esbuild/aix-ppc64@0.27.0':
319
+
resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==}
311
320
engines: {node: '>=18'}
312
321
cpu: [ppc64]
313
322
os: [aix]
314
323
315
-
'@esbuild/android-arm64@0.25.4':
316
-
resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==}
324
+
'@esbuild/android-arm64@0.25.12':
325
+
resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
317
326
engines: {node: '>=18'}
318
327
cpu: [arm64]
319
328
os: [android]
320
329
321
-
'@esbuild/android-arm64@0.25.5':
322
-
resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==}
330
+
'@esbuild/android-arm64@0.27.0':
331
+
resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==}
323
332
engines: {node: '>=18'}
324
333
cpu: [arm64]
325
334
os: [android]
326
335
327
-
'@esbuild/android-arm@0.25.4':
328
-
resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==}
336
+
'@esbuild/android-arm@0.25.12':
337
+
resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
329
338
engines: {node: '>=18'}
330
339
cpu: [arm]
331
340
os: [android]
332
341
333
-
'@esbuild/android-arm@0.25.5':
334
-
resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==}
342
+
'@esbuild/android-arm@0.27.0':
343
+
resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==}
335
344
engines: {node: '>=18'}
336
345
cpu: [arm]
337
346
os: [android]
338
347
339
-
'@esbuild/android-x64@0.25.4':
340
-
resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==}
348
+
'@esbuild/android-x64@0.25.12':
349
+
resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
341
350
engines: {node: '>=18'}
342
351
cpu: [x64]
343
352
os: [android]
344
353
345
-
'@esbuild/android-x64@0.25.5':
346
-
resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==}
354
+
'@esbuild/android-x64@0.27.0':
355
+
resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==}
347
356
engines: {node: '>=18'}
348
357
cpu: [x64]
349
358
os: [android]
350
359
351
-
'@esbuild/darwin-arm64@0.25.4':
352
-
resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==}
360
+
'@esbuild/darwin-arm64@0.25.12':
361
+
resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
353
362
engines: {node: '>=18'}
354
363
cpu: [arm64]
355
364
os: [darwin]
356
365
357
-
'@esbuild/darwin-arm64@0.25.5':
358
-
resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==}
366
+
'@esbuild/darwin-arm64@0.27.0':
367
+
resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==}
359
368
engines: {node: '>=18'}
360
369
cpu: [arm64]
361
370
os: [darwin]
362
371
363
-
'@esbuild/darwin-x64@0.25.4':
364
-
resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==}
372
+
'@esbuild/darwin-x64@0.25.12':
373
+
resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
365
374
engines: {node: '>=18'}
366
375
cpu: [x64]
367
376
os: [darwin]
368
377
369
-
'@esbuild/darwin-x64@0.25.5':
370
-
resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==}
378
+
'@esbuild/darwin-x64@0.27.0':
379
+
resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==}
371
380
engines: {node: '>=18'}
372
381
cpu: [x64]
373
382
os: [darwin]
374
383
375
-
'@esbuild/freebsd-arm64@0.25.4':
376
-
resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==}
384
+
'@esbuild/freebsd-arm64@0.25.12':
385
+
resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
377
386
engines: {node: '>=18'}
378
387
cpu: [arm64]
379
388
os: [freebsd]
380
389
381
-
'@esbuild/freebsd-arm64@0.25.5':
382
-
resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==}
390
+
'@esbuild/freebsd-arm64@0.27.0':
391
+
resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==}
383
392
engines: {node: '>=18'}
384
393
cpu: [arm64]
385
394
os: [freebsd]
386
395
387
-
'@esbuild/freebsd-x64@0.25.4':
388
-
resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==}
396
+
'@esbuild/freebsd-x64@0.25.12':
397
+
resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
389
398
engines: {node: '>=18'}
390
399
cpu: [x64]
391
400
os: [freebsd]
392
401
393
-
'@esbuild/freebsd-x64@0.25.5':
394
-
resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==}
402
+
'@esbuild/freebsd-x64@0.27.0':
403
+
resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==}
395
404
engines: {node: '>=18'}
396
405
cpu: [x64]
397
406
os: [freebsd]
398
407
399
-
'@esbuild/linux-arm64@0.25.4':
400
-
resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==}
408
+
'@esbuild/linux-arm64@0.25.12':
409
+
resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
401
410
engines: {node: '>=18'}
402
411
cpu: [arm64]
403
412
os: [linux]
404
413
405
-
'@esbuild/linux-arm64@0.25.5':
406
-
resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==}
414
+
'@esbuild/linux-arm64@0.27.0':
415
+
resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==}
407
416
engines: {node: '>=18'}
408
417
cpu: [arm64]
409
418
os: [linux]
410
419
411
-
'@esbuild/linux-arm@0.25.4':
412
-
resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==}
420
+
'@esbuild/linux-arm@0.25.12':
421
+
resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
413
422
engines: {node: '>=18'}
414
423
cpu: [arm]
415
424
os: [linux]
416
425
417
-
'@esbuild/linux-arm@0.25.5':
418
-
resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==}
426
+
'@esbuild/linux-arm@0.27.0':
427
+
resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==}
419
428
engines: {node: '>=18'}
420
429
cpu: [arm]
421
430
os: [linux]
422
431
423
-
'@esbuild/linux-ia32@0.25.4':
424
-
resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==}
432
+
'@esbuild/linux-ia32@0.25.12':
433
+
resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
425
434
engines: {node: '>=18'}
426
435
cpu: [ia32]
427
436
os: [linux]
428
437
429
-
'@esbuild/linux-ia32@0.25.5':
430
-
resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==}
438
+
'@esbuild/linux-ia32@0.27.0':
439
+
resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==}
431
440
engines: {node: '>=18'}
432
441
cpu: [ia32]
433
442
os: [linux]
434
443
435
-
'@esbuild/linux-loong64@0.25.4':
436
-
resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==}
444
+
'@esbuild/linux-loong64@0.25.12':
445
+
resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
437
446
engines: {node: '>=18'}
438
447
cpu: [loong64]
439
448
os: [linux]
440
449
441
-
'@esbuild/linux-loong64@0.25.5':
442
-
resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==}
450
+
'@esbuild/linux-loong64@0.27.0':
451
+
resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==}
443
452
engines: {node: '>=18'}
444
453
cpu: [loong64]
445
454
os: [linux]
446
455
447
-
'@esbuild/linux-mips64el@0.25.4':
448
-
resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==}
456
+
'@esbuild/linux-mips64el@0.25.12':
457
+
resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
449
458
engines: {node: '>=18'}
450
459
cpu: [mips64el]
451
460
os: [linux]
452
461
453
-
'@esbuild/linux-mips64el@0.25.5':
454
-
resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==}
462
+
'@esbuild/linux-mips64el@0.27.0':
463
+
resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==}
455
464
engines: {node: '>=18'}
456
465
cpu: [mips64el]
457
466
os: [linux]
458
467
459
-
'@esbuild/linux-ppc64@0.25.4':
460
-
resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==}
468
+
'@esbuild/linux-ppc64@0.25.12':
469
+
resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
461
470
engines: {node: '>=18'}
462
471
cpu: [ppc64]
463
472
os: [linux]
464
473
465
-
'@esbuild/linux-ppc64@0.25.5':
466
-
resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==}
474
+
'@esbuild/linux-ppc64@0.27.0':
475
+
resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==}
467
476
engines: {node: '>=18'}
468
477
cpu: [ppc64]
469
478
os: [linux]
470
479
471
-
'@esbuild/linux-riscv64@0.25.4':
472
-
resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==}
480
+
'@esbuild/linux-riscv64@0.25.12':
481
+
resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
473
482
engines: {node: '>=18'}
474
483
cpu: [riscv64]
475
484
os: [linux]
476
485
477
-
'@esbuild/linux-riscv64@0.25.5':
478
-
resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==}
486
+
'@esbuild/linux-riscv64@0.27.0':
487
+
resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==}
479
488
engines: {node: '>=18'}
480
489
cpu: [riscv64]
481
490
os: [linux]
482
491
483
-
'@esbuild/linux-s390x@0.25.4':
484
-
resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==}
492
+
'@esbuild/linux-s390x@0.25.12':
493
+
resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
485
494
engines: {node: '>=18'}
486
495
cpu: [s390x]
487
496
os: [linux]
488
497
489
-
'@esbuild/linux-s390x@0.25.5':
490
-
resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==}
498
+
'@esbuild/linux-s390x@0.27.0':
499
+
resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==}
491
500
engines: {node: '>=18'}
492
501
cpu: [s390x]
493
502
os: [linux]
494
503
495
-
'@esbuild/linux-x64@0.25.4':
496
-
resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==}
504
+
'@esbuild/linux-x64@0.25.12':
505
+
resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
497
506
engines: {node: '>=18'}
498
507
cpu: [x64]
499
508
os: [linux]
500
509
501
-
'@esbuild/linux-x64@0.25.5':
502
-
resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==}
510
+
'@esbuild/linux-x64@0.27.0':
511
+
resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==}
503
512
engines: {node: '>=18'}
504
513
cpu: [x64]
505
514
os: [linux]
506
515
507
-
'@esbuild/netbsd-arm64@0.25.4':
508
-
resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==}
516
+
'@esbuild/netbsd-arm64@0.25.12':
517
+
resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
509
518
engines: {node: '>=18'}
510
519
cpu: [arm64]
511
520
os: [netbsd]
512
521
513
-
'@esbuild/netbsd-arm64@0.25.5':
514
-
resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==}
522
+
'@esbuild/netbsd-arm64@0.27.0':
523
+
resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==}
515
524
engines: {node: '>=18'}
516
525
cpu: [arm64]
517
526
os: [netbsd]
518
527
519
-
'@esbuild/netbsd-x64@0.25.4':
520
-
resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==}
528
+
'@esbuild/netbsd-x64@0.25.12':
529
+
resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
521
530
engines: {node: '>=18'}
522
531
cpu: [x64]
523
532
os: [netbsd]
524
533
525
-
'@esbuild/netbsd-x64@0.25.5':
526
-
resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==}
534
+
'@esbuild/netbsd-x64@0.27.0':
535
+
resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==}
527
536
engines: {node: '>=18'}
528
537
cpu: [x64]
529
538
os: [netbsd]
530
539
531
-
'@esbuild/openbsd-arm64@0.25.4':
532
-
resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==}
540
+
'@esbuild/openbsd-arm64@0.25.12':
541
+
resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
533
542
engines: {node: '>=18'}
534
543
cpu: [arm64]
535
544
os: [openbsd]
536
545
537
-
'@esbuild/openbsd-arm64@0.25.5':
538
-
resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==}
546
+
'@esbuild/openbsd-arm64@0.27.0':
547
+
resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==}
539
548
engines: {node: '>=18'}
540
549
cpu: [arm64]
541
550
os: [openbsd]
542
551
543
-
'@esbuild/openbsd-x64@0.25.4':
544
-
resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==}
552
+
'@esbuild/openbsd-x64@0.25.12':
553
+
resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
545
554
engines: {node: '>=18'}
546
555
cpu: [x64]
547
556
os: [openbsd]
548
557
549
-
'@esbuild/openbsd-x64@0.25.5':
550
-
resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==}
558
+
'@esbuild/openbsd-x64@0.27.0':
559
+
resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==}
551
560
engines: {node: '>=18'}
552
561
cpu: [x64]
553
562
os: [openbsd]
554
563
555
-
'@esbuild/sunos-x64@0.25.4':
556
-
resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==}
564
+
'@esbuild/openharmony-arm64@0.25.12':
565
+
resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
566
+
engines: {node: '>=18'}
567
+
cpu: [arm64]
568
+
os: [openharmony]
569
+
570
+
'@esbuild/openharmony-arm64@0.27.0':
571
+
resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==}
572
+
engines: {node: '>=18'}
573
+
cpu: [arm64]
574
+
os: [openharmony]
575
+
576
+
'@esbuild/sunos-x64@0.25.12':
577
+
resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
557
578
engines: {node: '>=18'}
558
579
cpu: [x64]
559
580
os: [sunos]
560
581
561
-
'@esbuild/sunos-x64@0.25.5':
562
-
resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==}
582
+
'@esbuild/sunos-x64@0.27.0':
583
+
resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==}
563
584
engines: {node: '>=18'}
564
585
cpu: [x64]
565
586
os: [sunos]
566
587
567
-
'@esbuild/win32-arm64@0.25.4':
568
-
resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==}
588
+
'@esbuild/win32-arm64@0.25.12':
589
+
resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
569
590
engines: {node: '>=18'}
570
591
cpu: [arm64]
571
592
os: [win32]
572
593
573
-
'@esbuild/win32-arm64@0.25.5':
574
-
resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==}
594
+
'@esbuild/win32-arm64@0.27.0':
595
+
resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==}
575
596
engines: {node: '>=18'}
576
597
cpu: [arm64]
577
598
os: [win32]
578
599
579
-
'@esbuild/win32-ia32@0.25.4':
580
-
resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==}
600
+
'@esbuild/win32-ia32@0.25.12':
601
+
resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
581
602
engines: {node: '>=18'}
582
603
cpu: [ia32]
583
604
os: [win32]
584
605
585
-
'@esbuild/win32-ia32@0.25.5':
586
-
resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==}
606
+
'@esbuild/win32-ia32@0.27.0':
607
+
resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==}
587
608
engines: {node: '>=18'}
588
609
cpu: [ia32]
589
610
os: [win32]
590
611
591
-
'@esbuild/win32-x64@0.25.4':
592
-
resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==}
612
+
'@esbuild/win32-x64@0.25.12':
613
+
resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
593
614
engines: {node: '>=18'}
594
615
cpu: [x64]
595
616
os: [win32]
596
617
597
-
'@esbuild/win32-x64@0.25.5':
598
-
resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==}
618
+
'@esbuild/win32-x64@0.27.0':
619
+
resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==}
599
620
engines: {node: '>=18'}
600
621
cpu: [x64]
601
622
os: [win32]
···
604
625
resolution: {integrity: sha512-duvZBfJB9oOLphx04ckKF534hP186xIBFaw4GHJ5fGeZY5syZs59UeumV5NC6aiEU9hVhAFMOnDDGkQrFqHrnQ==}
605
626
peerDependencies:
606
627
solid-js: ^1.8.5
607
-
608
-
'@fastify/busboy@2.1.1':
609
-
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
610
-
engines: {node: '>=14'}
611
628
612
629
'@img/sharp-darwin-arm64@0.33.5':
613
630
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
···
714
731
cpu: [x64]
715
732
os: [win32]
716
733
717
-
'@isaacs/cliui@8.0.2':
718
-
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
719
-
engines: {node: '>=12'}
734
+
'@jridgewell/gen-mapping@0.3.13':
735
+
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
720
736
721
-
'@jridgewell/gen-mapping@0.3.8':
722
-
resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
723
-
engines: {node: '>=6.0.0'}
737
+
'@jridgewell/remapping@2.3.5':
738
+
resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
724
739
725
740
'@jridgewell/resolve-uri@3.1.2':
726
741
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
727
742
engines: {node: '>=6.0.0'}
728
743
729
-
'@jridgewell/set-array@1.2.1':
730
-
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
731
-
engines: {node: '>=6.0.0'}
732
-
733
-
'@jridgewell/source-map@0.3.6':
734
-
resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
744
+
'@jridgewell/source-map@0.3.11':
745
+
resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==}
735
746
736
-
'@jridgewell/sourcemap-codec@1.5.0':
737
-
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
747
+
'@jridgewell/sourcemap-codec@1.5.5':
748
+
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
738
749
739
-
'@jridgewell/trace-mapping@0.3.25':
740
-
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
750
+
'@jridgewell/trace-mapping@0.3.31':
751
+
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
741
752
742
753
'@jridgewell/trace-mapping@0.3.9':
743
754
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
744
755
745
-
'@jsr/mary__array-fns@0.1.4':
746
-
resolution: {integrity: sha512-+HbGYR9Ll5blEmAvVAoPejyGj01YeBbVmJ59qxaMDKt5i3F90ohYLA5a78y6AULDlet1IxYB+a/cMN+A0vGnDg==, tarball: https://npm.jsr.io/~/11/@jsr/mary__array-fns/0.1.4.tgz}
756
+
'@jsr/mary__array-fns@0.1.5':
757
+
resolution: {integrity: sha512-gI4scq/Hh9GtFUJfS8cvZf5nr+cs7udvrEpMv75grws5/0LIwBycKeeJcNi4+xNl6x4CGW6Fp46puhtJiQOpMg==, tarball: https://npm.jsr.io/~/11/@jsr/mary__array-fns/0.1.5.tgz}
747
758
748
-
'@jsr/mary__ds-queue@0.1.2':
749
-
resolution: {integrity: sha512-AOZ/FXYHVWI05bNHgi/Ln0RCiWvOQuZ/fZ1AxkT27Ytbon8VNtLAYs7uOgVITJcbMrsdE6zJXh/bP9LF16sk/A==, tarball: https://npm.jsr.io/~/11/@jsr/mary__ds-queue/0.1.2.tgz}
759
+
'@jsr/mary__ds-queue@0.1.3':
760
+
resolution: {integrity: sha512-gGqIHXiAmhUUtonNI6YVvL7VlXjEHUpGdc7RGU8BLP4XnFvqovDTH5y9VlBZmvozTWgTIMoZF6/1//sMrvYKtQ==, tarball: https://npm.jsr.io/~/11/@jsr/mary__ds-queue/0.1.3.tgz}
750
761
751
762
'@jsr/mary__events@0.2.0':
752
763
resolution: {integrity: sha512-WcBRbtuTno3zcfXKd7SEeKr1lAJF+CQ8BCv+PEEMmNKNqFurkEksGxRB3UDPZxIxjJ7sAqMVTL26wRuMpAcIeA==, tarball: https://npm.jsr.io/~/11/@jsr/mary__events/0.2.0.tgz}
753
764
754
-
'@jsr/mary__tar@0.2.4':
755
-
resolution: {integrity: sha512-jFjPcZj8DRSukPLZOt6+h74cVFdfdTMG9gzbW67YByCJTD52PEpe2sNcfCSw4mQ8hZBNgwiufCPyYL8hR9yicA==, tarball: https://npm.jsr.io/~/11/@jsr/mary__tar/0.2.4.tgz}
765
+
'@jsr/mary__tar@0.3.1':
766
+
resolution: {integrity: sha512-T803kucwCLVOXFJGzVbpkT5vRK6fARy5HL6xMiLK5hJFck72bsAeluENlRnvD0kFPSlFNp/5EJWfTHnpDK0qYA==, tarball: https://npm.jsr.io/~/11/@jsr/mary__tar/0.3.1.tgz}
756
767
757
-
'@noble/secp256k1@2.2.3':
758
-
resolution: {integrity: sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==}
768
+
'@noble/secp256k1@3.0.0':
769
+
resolution: {integrity: sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==}
759
770
760
771
'@nodelib/fs.scandir@2.1.5':
761
772
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
···
769
780
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
770
781
engines: {node: '>= 8'}
771
782
772
-
'@pkgjs/parseargs@0.11.0':
773
-
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
774
-
engines: {node: '>=14'}
783
+
'@poppinss/colors@4.1.5':
784
+
resolution: {integrity: sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==}
785
+
786
+
'@poppinss/dumper@0.6.5':
787
+
resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==}
788
+
789
+
'@poppinss/exception@1.2.2':
790
+
resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==}
775
791
776
-
'@rollup/rollup-android-arm-eabi@4.41.1':
777
-
resolution: {integrity: sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==}
792
+
'@rollup/rollup-android-arm-eabi@4.53.3':
793
+
resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==}
778
794
cpu: [arm]
779
795
os: [android]
780
796
781
-
'@rollup/rollup-android-arm64@4.41.1':
782
-
resolution: {integrity: sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==}
797
+
'@rollup/rollup-android-arm64@4.53.3':
798
+
resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==}
783
799
cpu: [arm64]
784
800
os: [android]
785
801
786
-
'@rollup/rollup-darwin-arm64@4.41.1':
787
-
resolution: {integrity: sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==}
802
+
'@rollup/rollup-darwin-arm64@4.53.3':
803
+
resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==}
788
804
cpu: [arm64]
789
805
os: [darwin]
790
806
791
-
'@rollup/rollup-darwin-x64@4.41.1':
792
-
resolution: {integrity: sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==}
807
+
'@rollup/rollup-darwin-x64@4.53.3':
808
+
resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==}
793
809
cpu: [x64]
794
810
os: [darwin]
795
811
796
-
'@rollup/rollup-freebsd-arm64@4.41.1':
797
-
resolution: {integrity: sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==}
812
+
'@rollup/rollup-freebsd-arm64@4.53.3':
813
+
resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==}
798
814
cpu: [arm64]
799
815
os: [freebsd]
800
816
801
-
'@rollup/rollup-freebsd-x64@4.41.1':
802
-
resolution: {integrity: sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==}
817
+
'@rollup/rollup-freebsd-x64@4.53.3':
818
+
resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==}
803
819
cpu: [x64]
804
820
os: [freebsd]
805
821
806
-
'@rollup/rollup-linux-arm-gnueabihf@4.41.1':
807
-
resolution: {integrity: sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==}
822
+
'@rollup/rollup-linux-arm-gnueabihf@4.53.3':
823
+
resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==}
808
824
cpu: [arm]
809
825
os: [linux]
810
826
811
-
'@rollup/rollup-linux-arm-musleabihf@4.41.1':
812
-
resolution: {integrity: sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==}
827
+
'@rollup/rollup-linux-arm-musleabihf@4.53.3':
828
+
resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==}
813
829
cpu: [arm]
814
830
os: [linux]
815
831
816
-
'@rollup/rollup-linux-arm64-gnu@4.41.1':
817
-
resolution: {integrity: sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==}
832
+
'@rollup/rollup-linux-arm64-gnu@4.53.3':
833
+
resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==}
818
834
cpu: [arm64]
819
835
os: [linux]
820
836
821
-
'@rollup/rollup-linux-arm64-musl@4.41.1':
822
-
resolution: {integrity: sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==}
837
+
'@rollup/rollup-linux-arm64-musl@4.53.3':
838
+
resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==}
823
839
cpu: [arm64]
824
840
os: [linux]
825
841
826
-
'@rollup/rollup-linux-loongarch64-gnu@4.41.1':
827
-
resolution: {integrity: sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==}
842
+
'@rollup/rollup-linux-loong64-gnu@4.53.3':
843
+
resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==}
828
844
cpu: [loong64]
829
845
os: [linux]
830
846
831
-
'@rollup/rollup-linux-powerpc64le-gnu@4.41.1':
832
-
resolution: {integrity: sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==}
847
+
'@rollup/rollup-linux-ppc64-gnu@4.53.3':
848
+
resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==}
833
849
cpu: [ppc64]
834
850
os: [linux]
835
851
836
-
'@rollup/rollup-linux-riscv64-gnu@4.41.1':
837
-
resolution: {integrity: sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==}
852
+
'@rollup/rollup-linux-riscv64-gnu@4.53.3':
853
+
resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==}
838
854
cpu: [riscv64]
839
855
os: [linux]
840
856
841
-
'@rollup/rollup-linux-riscv64-musl@4.41.1':
842
-
resolution: {integrity: sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==}
857
+
'@rollup/rollup-linux-riscv64-musl@4.53.3':
858
+
resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==}
843
859
cpu: [riscv64]
844
860
os: [linux]
845
861
846
-
'@rollup/rollup-linux-s390x-gnu@4.41.1':
847
-
resolution: {integrity: sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==}
862
+
'@rollup/rollup-linux-s390x-gnu@4.53.3':
863
+
resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==}
848
864
cpu: [s390x]
849
865
os: [linux]
850
866
851
-
'@rollup/rollup-linux-x64-gnu@4.41.1':
852
-
resolution: {integrity: sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==}
867
+
'@rollup/rollup-linux-x64-gnu@4.53.3':
868
+
resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==}
853
869
cpu: [x64]
854
870
os: [linux]
855
871
856
-
'@rollup/rollup-linux-x64-musl@4.41.1':
857
-
resolution: {integrity: sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==}
872
+
'@rollup/rollup-linux-x64-musl@4.53.3':
873
+
resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==}
858
874
cpu: [x64]
859
875
os: [linux]
860
876
861
-
'@rollup/rollup-win32-arm64-msvc@4.41.1':
862
-
resolution: {integrity: sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==}
877
+
'@rollup/rollup-openharmony-arm64@4.53.3':
878
+
resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==}
879
+
cpu: [arm64]
880
+
os: [openharmony]
881
+
882
+
'@rollup/rollup-win32-arm64-msvc@4.53.3':
883
+
resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==}
863
884
cpu: [arm64]
864
885
os: [win32]
865
886
866
-
'@rollup/rollup-win32-ia32-msvc@4.41.1':
867
-
resolution: {integrity: sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==}
887
+
'@rollup/rollup-win32-ia32-msvc@4.53.3':
888
+
resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==}
868
889
cpu: [ia32]
869
890
os: [win32]
870
891
871
-
'@rollup/rollup-win32-x64-msvc@4.41.1':
872
-
resolution: {integrity: sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==}
892
+
'@rollup/rollup-win32-x64-gnu@4.53.3':
893
+
resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==}
894
+
cpu: [x64]
895
+
os: [win32]
896
+
897
+
'@rollup/rollup-win32-x64-msvc@4.53.3':
898
+
resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==}
873
899
cpu: [x64]
874
900
os: [win32]
875
901
902
+
'@sindresorhus/is@7.1.1':
903
+
resolution: {integrity: sha512-rO92VvpgMc3kfiTjGT52LEtJ8Yc5kCWhZjLQ3LwlA4pSgPpQO7bVpYXParOD8Jwf+cVQECJo3yP/4I8aZtUQTQ==}
904
+
engines: {node: '>=18'}
905
+
906
+
'@speed-highlight/core@1.2.12':
907
+
resolution: {integrity: sha512-uilwrK0Ygyri5dToHYdZSjcvpS2ZwX0w5aSt3GCEN9hrjxWCoeV4Z2DTXuxjwbntaLQIEEAlCeNQss5SoHvAEA==}
908
+
909
+
'@standard-schema/spec@1.0.0':
910
+
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
911
+
876
912
'@tailwindcss/forms@0.5.10':
877
913
resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==}
878
914
peerDependencies:
···
887
923
'@types/babel__template@7.4.4':
888
924
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
889
925
890
-
'@types/babel__traverse@7.20.7':
891
-
resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==}
926
+
'@types/babel__traverse@7.28.0':
927
+
resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
892
928
893
-
'@types/estree@1.0.7':
894
-
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
929
+
'@types/estree@1.0.8':
930
+
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
895
931
896
-
'@types/node@22.15.21':
897
-
resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==}
932
+
'@types/node@22.19.2':
933
+
resolution: {integrity: sha512-LPM2G3Syo1GLzXLGJAKdqoU35XvrWzGJ21/7sgZTUpbkBaOasTj8tjwn6w+hCkqaa1TfJ/w67rJSwYItlJ2mYw==}
898
934
899
935
acorn-walk@8.3.2:
900
936
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
···
905
941
engines: {node: '>=0.4.0'}
906
942
hasBin: true
907
943
908
-
acorn@8.14.1:
909
-
resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==}
944
+
acorn@8.15.0:
945
+
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
910
946
engines: {node: '>=0.4.0'}
911
947
hasBin: true
912
948
913
-
ansi-regex@5.0.1:
914
-
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
915
-
engines: {node: '>=8'}
916
-
917
-
ansi-regex@6.1.0:
918
-
resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
919
-
engines: {node: '>=12'}
920
-
921
-
ansi-styles@4.3.0:
922
-
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
923
-
engines: {node: '>=8'}
924
-
925
-
ansi-styles@6.2.1:
926
-
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
927
-
engines: {node: '>=12'}
928
-
929
949
any-promise@1.3.0:
930
950
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
931
951
···
936
956
arg@5.0.2:
937
957
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
938
958
939
-
as-table@1.0.55:
940
-
resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
941
-
942
-
autoprefixer@10.4.21:
943
-
resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==}
959
+
autoprefixer@10.4.22:
960
+
resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==}
944
961
engines: {node: ^10 || ^12 || >=14}
945
962
hasBin: true
946
963
peerDependencies:
947
964
postcss: ^8.1.0
948
965
949
-
babel-plugin-jsx-dom-expressions@0.39.8:
950
-
resolution: {integrity: sha512-/MVOIIjonylDXnrWmG23ZX82m9mtKATsVHB7zYlPfDR9Vdd/NBE48if+wv27bSkBtyO7EPMUlcUc4J63QwuACQ==}
966
+
babel-plugin-jsx-dom-expressions@0.40.3:
967
+
resolution: {integrity: sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w==}
951
968
peerDependencies:
952
969
'@babel/core': ^7.20.12
953
970
954
-
babel-preset-solid@1.9.6:
955
-
resolution: {integrity: sha512-HXTK9f93QxoH8dYn1M2mJdOlWgMsR88Lg/ul6QCZGkNTktjTE5HAf93YxQumHoCudLEtZrU1cFCMFOVho6GqFg==}
971
+
babel-preset-solid@1.9.10:
972
+
resolution: {integrity: sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ==}
956
973
peerDependencies:
957
974
'@babel/core': ^7.0.0
975
+
solid-js: ^1.9.10
976
+
peerDependenciesMeta:
977
+
solid-js:
978
+
optional: true
958
979
959
-
balanced-match@1.0.2:
960
-
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
980
+
baseline-browser-mapping@2.9.5:
981
+
resolution: {integrity: sha512-D5vIoztZOq1XM54LUdttJVc96ggEsIfju2JBvht06pSzpckp3C7HReun67Bghzrtdsq9XdMGbSSB3v3GhMNmAA==}
982
+
hasBin: true
961
983
962
984
binary-extensions@2.3.0:
963
985
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
···
966
988
blake3-wasm@2.1.5:
967
989
resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
968
990
969
-
brace-expansion@2.0.1:
970
-
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
971
-
972
991
braces@3.0.3:
973
992
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
974
993
engines: {node: '>=8'}
975
994
976
-
browserslist@4.24.5:
977
-
resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==}
995
+
browserslist@4.28.1:
996
+
resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
978
997
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
979
998
hasBin: true
980
999
···
985
1004
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
986
1005
engines: {node: '>= 6'}
987
1006
988
-
caniuse-lite@1.0.30001718:
989
-
resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==}
1007
+
caniuse-lite@1.0.30001760:
1008
+
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
990
1009
991
1010
chokidar@3.6.0:
992
1011
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
···
1016
1035
convert-source-map@2.0.0:
1017
1036
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
1018
1037
1019
-
cookie@0.7.2:
1020
-
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
1021
-
engines: {node: '>= 0.6'}
1022
-
1023
-
cross-spawn@7.0.6:
1024
-
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
1025
-
engines: {node: '>= 8'}
1038
+
cookie@1.1.1:
1039
+
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
1040
+
engines: {node: '>=18'}
1026
1041
1027
1042
cssesc@3.0.0:
1028
1043
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
1029
1044
engines: {node: '>=4'}
1030
1045
hasBin: true
1031
1046
1032
-
csstype@3.1.3:
1033
-
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
1047
+
csstype@3.2.3:
1048
+
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
1034
1049
1035
-
data-uri-to-buffer@2.0.2:
1036
-
resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
1037
-
1038
-
debug@4.4.1:
1039
-
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
1050
+
debug@4.4.3:
1051
+
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
1040
1052
engines: {node: '>=6.0'}
1041
1053
peerDependencies:
1042
1054
supports-color: '*'
···
1044
1056
supports-color:
1045
1057
optional: true
1046
1058
1047
-
defu@6.1.4:
1048
-
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
1049
-
1050
-
detect-libc@2.0.4:
1051
-
resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
1059
+
detect-libc@2.1.2:
1060
+
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
1052
1061
engines: {node: '>=8'}
1053
1062
1054
1063
didyoumean@1.2.2:
···
1057
1066
dlv@1.1.3:
1058
1067
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
1059
1068
1060
-
eastasianwidth@0.2.0:
1061
-
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
1062
-
1063
-
electron-to-chromium@1.5.158:
1064
-
resolution: {integrity: sha512-9vcp2xHhkvraY6AHw2WMi+GDSLPX42qe2xjYaVoZqFRJiOcilVQFq9mZmpuHEQpzlgGDelKlV7ZiGcmMsc8WxQ==}
1065
-
1066
-
emoji-regex@8.0.0:
1067
-
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
1068
-
1069
-
emoji-regex@9.2.2:
1070
-
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
1069
+
electron-to-chromium@1.5.267:
1070
+
resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
1071
1071
1072
-
entities@6.0.0:
1073
-
resolution: {integrity: sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==}
1072
+
entities@6.0.1:
1073
+
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
1074
1074
engines: {node: '>=0.12'}
1075
1075
1076
-
esbuild@0.25.4:
1077
-
resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==}
1076
+
error-stack-parser-es@1.0.5:
1077
+
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
1078
+
1079
+
esbuild@0.25.12:
1080
+
resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
1078
1081
engines: {node: '>=18'}
1079
1082
hasBin: true
1080
1083
1081
-
esbuild@0.25.5:
1082
-
resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==}
1084
+
esbuild@0.27.0:
1085
+
resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==}
1083
1086
engines: {node: '>=18'}
1084
1087
hasBin: true
1085
1088
···
1094
1097
resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
1095
1098
engines: {node: '>=6'}
1096
1099
1097
-
exsolve@1.0.5:
1098
-
resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==}
1099
-
1100
1100
fast-glob@3.3.3:
1101
1101
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
1102
1102
engines: {node: '>=8.6.0'}
···
1104
1104
fastq@1.19.1:
1105
1105
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
1106
1106
1107
-
fdir@6.4.4:
1108
-
resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==}
1107
+
fdir@6.5.0:
1108
+
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
1109
+
engines: {node: '>=12.0.0'}
1109
1110
peerDependencies:
1110
1111
picomatch: ^3 || ^4
1111
1112
peerDependenciesMeta:
···
1120
1121
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
1121
1122
engines: {node: '>=8'}
1122
1123
1123
-
foreground-child@3.3.1:
1124
-
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
1125
-
engines: {node: '>=14'}
1126
-
1127
-
fraction.js@4.3.7:
1128
-
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
1124
+
fraction.js@5.3.4:
1125
+
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
1129
1126
1130
1127
fsevents@2.3.3:
1131
1128
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
···
1139
1136
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
1140
1137
engines: {node: '>=6.9.0'}
1141
1138
1142
-
get-source@2.0.12:
1143
-
resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
1144
-
1145
1139
glob-parent@5.1.2:
1146
1140
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
1147
1141
engines: {node: '>= 6'}
···
1153
1147
glob-to-regexp@0.4.1:
1154
1148
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
1155
1149
1156
-
glob@10.4.5:
1157
-
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
1158
-
hasBin: true
1159
-
1160
-
globals@11.12.0:
1161
-
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
1162
-
engines: {node: '>=4'}
1163
-
1164
1150
hasown@2.0.2:
1165
1151
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
1166
1152
engines: {node: '>= 0.4'}
···
1168
1154
html-entities@2.3.3:
1169
1155
resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==}
1170
1156
1171
-
is-arrayish@0.3.2:
1172
-
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
1157
+
is-arrayish@0.3.4:
1158
+
resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==}
1173
1159
1174
1160
is-binary-path@2.1.0:
1175
1161
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
···
1183
1169
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
1184
1170
engines: {node: '>=0.10.0'}
1185
1171
1186
-
is-fullwidth-code-point@3.0.0:
1187
-
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
1188
-
engines: {node: '>=8'}
1189
-
1190
1172
is-glob@4.0.3:
1191
1173
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
1192
1174
engines: {node: '>=0.10.0'}
···
1199
1181
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
1200
1182
engines: {node: '>=12.13'}
1201
1183
1202
-
isexe@2.0.0:
1203
-
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1204
-
1205
-
jackspeak@3.4.3:
1206
-
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
1207
-
1208
1184
jiti@1.21.7:
1209
1185
resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
1210
1186
hasBin: true
···
1221
1197
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
1222
1198
engines: {node: '>=6'}
1223
1199
hasBin: true
1200
+
1201
+
kleur@4.1.5:
1202
+
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
1203
+
engines: {node: '>=6'}
1224
1204
1225
1205
lilconfig@3.1.3:
1226
1206
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
···
1229
1209
lines-and-columns@1.2.4:
1230
1210
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
1231
1211
1232
-
lru-cache@10.4.3:
1233
-
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
1234
-
1235
1212
lru-cache@5.1.1:
1236
1213
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
1237
1214
···
1256
1233
resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
1257
1234
hasBin: true
1258
1235
1259
-
miniflare@4.20250508.3:
1260
-
resolution: {integrity: sha512-43oTmZ0CCmUcieetI5YDDyX0IiwhOcVIWzdBBCqWXK3F1XgQwg4d3fTqRyJnCmHIoaYx9CE1kTEKZC1UahPQhA==}
1236
+
miniflare@4.20251202.1:
1237
+
resolution: {integrity: sha512-cRp2QNgnt9wpLMoNs4MOzzomyfe9UTS9sPRxIpUvxMl+mweCZ0FHpWWQvCnU7wWlfAP8VGZrHwqSsV5ERA6ahQ==}
1261
1238
engines: {node: '>=18.0.0'}
1262
1239
hasBin: true
1263
1240
1264
-
minimatch@9.0.5:
1265
-
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
1266
-
engines: {node: '>=16 || 14 >=14.17'}
1267
-
1268
-
minipass@7.1.2:
1269
-
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
1270
-
engines: {node: '>=16 || 14 >=14.17'}
1271
-
1272
1241
ms@2.1.3:
1273
1242
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1274
1243
1275
-
mustache@4.2.0:
1276
-
resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
1277
-
hasBin: true
1278
-
1279
1244
mz@2.7.0:
1280
1245
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
1281
1246
···
1284
1249
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1285
1250
hasBin: true
1286
1251
1287
-
nanoid@5.1.5:
1288
-
resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==}
1252
+
nanoid@5.1.6:
1253
+
resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==}
1289
1254
engines: {node: ^18 || >=20}
1290
1255
hasBin: true
1291
1256
···
1298
1263
engines: {node: '>=10.5.0'}
1299
1264
deprecated: Use your platform's native DOMException instead
1300
1265
1301
-
node-releases@2.0.19:
1302
-
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
1266
+
node-releases@2.0.27:
1267
+
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
1303
1268
1304
1269
normalize-path@3.0.0:
1305
1270
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
···
1316
1281
object-hash@3.0.0:
1317
1282
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
1318
1283
engines: {node: '>= 6'}
1319
-
1320
-
ohash@2.0.11:
1321
-
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
1322
-
1323
-
package-json-from-dist@1.0.1:
1324
-
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
1325
1284
1326
1285
parse5@7.3.0:
1327
1286
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
1328
1287
1329
-
path-key@3.1.1:
1330
-
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1331
-
engines: {node: '>=8'}
1332
-
1333
1288
path-parse@1.0.7:
1334
1289
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1335
-
1336
-
path-scurry@1.11.1:
1337
-
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
1338
-
engines: {node: '>=16 || 14 >=14.18'}
1339
1290
1340
1291
path-to-regexp@6.3.0:
1341
1292
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
···
1350
1301
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1351
1302
engines: {node: '>=8.6'}
1352
1303
1353
-
picomatch@4.0.2:
1354
-
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
1304
+
picomatch@4.0.3:
1305
+
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
1355
1306
engines: {node: '>=12'}
1356
1307
1357
1308
pify@2.3.0:
···
1368
1319
peerDependencies:
1369
1320
postcss: ^8.0.0
1370
1321
1371
-
postcss-js@4.0.1:
1372
-
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
1322
+
postcss-js@4.1.0:
1323
+
resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==}
1373
1324
engines: {node: ^12 || ^14 || >= 16}
1374
1325
peerDependencies:
1375
1326
postcss: ^8.4.21
1376
1327
1377
-
postcss-load-config@4.0.2:
1378
-
resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
1379
-
engines: {node: '>= 14'}
1328
+
postcss-load-config@6.0.1:
1329
+
resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
1330
+
engines: {node: '>= 18'}
1380
1331
peerDependencies:
1332
+
jiti: '>=1.21.0'
1381
1333
postcss: '>=8.0.9'
1382
-
ts-node: '>=9.0.0'
1334
+
tsx: ^4.8.1
1335
+
yaml: ^2.4.2
1383
1336
peerDependenciesMeta:
1337
+
jiti:
1338
+
optional: true
1384
1339
postcss:
1385
1340
optional: true
1386
-
ts-node:
1341
+
tsx:
1342
+
optional: true
1343
+
yaml:
1387
1344
optional: true
1388
1345
1389
1346
postcss-nested@6.2.0:
···
1399
1356
postcss-value-parser@4.2.0:
1400
1357
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
1401
1358
1402
-
postcss@8.5.3:
1403
-
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
1359
+
postcss@8.5.6:
1360
+
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
1404
1361
engines: {node: ^10 || ^12 || >=14}
1405
1362
1406
-
prettier-plugin-tailwindcss@0.6.11:
1407
-
resolution: {integrity: sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==}
1363
+
prettier-plugin-tailwindcss@0.6.14:
1364
+
resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==}
1408
1365
engines: {node: '>=14.21.3'}
1409
1366
peerDependencies:
1410
1367
'@ianvs/prettier-plugin-sort-imports': '*'
1368
+
'@prettier/plugin-hermes': '*'
1369
+
'@prettier/plugin-oxc': '*'
1411
1370
'@prettier/plugin-pug': '*'
1412
1371
'@shopify/prettier-plugin-liquid': '*'
1413
1372
'@trivago/prettier-plugin-sort-imports': '*'
···
1426
1385
prettier-plugin-svelte: '*'
1427
1386
peerDependenciesMeta:
1428
1387
'@ianvs/prettier-plugin-sort-imports':
1388
+
optional: true
1389
+
'@prettier/plugin-hermes':
1390
+
optional: true
1391
+
'@prettier/plugin-oxc':
1429
1392
optional: true
1430
1393
'@prettier/plugin-pug':
1431
1394
optional: true
···
1458
1421
prettier-plugin-svelte:
1459
1422
optional: true
1460
1423
1461
-
prettier@3.5.3:
1462
-
resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
1424
+
prettier@3.7.4:
1425
+
resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==}
1463
1426
engines: {node: '>=14'}
1464
1427
hasBin: true
1465
1428
1466
-
printable-characters@1.0.42:
1467
-
resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
1468
-
1469
1429
queue-microtask@1.2.3:
1470
1430
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1471
1431
···
1476
1436
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
1477
1437
engines: {node: '>=8.10.0'}
1478
1438
1479
-
resolve@1.22.10:
1480
-
resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
1439
+
resolve@1.22.11:
1440
+
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
1481
1441
engines: {node: '>= 0.4'}
1482
1442
hasBin: true
1483
1443
···
1485
1445
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
1486
1446
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1487
1447
1488
-
rollup@4.41.1:
1489
-
resolution: {integrity: sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==}
1448
+
rollup@4.53.3:
1449
+
resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==}
1490
1450
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
1491
1451
hasBin: true
1492
1452
···
1497
1457
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
1498
1458
hasBin: true
1499
1459
1500
-
semver@7.7.2:
1501
-
resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
1460
+
semver@7.7.3:
1461
+
resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==}
1502
1462
engines: {node: '>=10'}
1503
1463
hasBin: true
1504
1464
1505
-
seroval-plugins@1.3.2:
1506
-
resolution: {integrity: sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==}
1465
+
seroval-plugins@1.3.3:
1466
+
resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==}
1507
1467
engines: {node: '>=10'}
1508
1468
peerDependencies:
1509
1469
seroval: ^1.0
···
1516
1476
resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
1517
1477
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1518
1478
1519
-
shebang-command@2.0.0:
1520
-
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1521
-
engines: {node: '>=8'}
1479
+
simple-swizzle@0.2.4:
1480
+
resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==}
1522
1481
1523
-
shebang-regex@3.0.0:
1524
-
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1525
-
engines: {node: '>=8'}
1526
-
1527
-
signal-exit@4.1.0:
1528
-
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1529
-
engines: {node: '>=14'}
1530
-
1531
-
simple-swizzle@0.2.2:
1532
-
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
1533
-
1534
-
solid-js@1.9.7:
1535
-
resolution: {integrity: sha512-/saTKi8iWEM233n5OSi1YHCCuh66ZIQ7aK2hsToPe4tqGm7qAejU1SwNuTPivbWAYq7SjuHVVYxxuZQNRbICiw==}
1482
+
solid-js@1.9.10:
1483
+
resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==}
1536
1484
1537
1485
solid-refresh@0.6.3:
1538
1486
resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==}
···
1550
1498
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
1551
1499
engines: {node: '>=0.10.0'}
1552
1500
1553
-
stacktracey@2.1.8:
1554
-
resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==}
1555
-
1556
1501
stoppable@1.1.0:
1557
1502
resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
1558
1503
engines: {node: '>=4', npm: '>=6'}
1559
1504
1560
-
string-width@4.2.3:
1561
-
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
1562
-
engines: {node: '>=8'}
1563
-
1564
-
string-width@5.1.2:
1565
-
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
1566
-
engines: {node: '>=12'}
1567
-
1568
-
strip-ansi@6.0.1:
1569
-
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1570
-
engines: {node: '>=8'}
1571
-
1572
-
strip-ansi@7.1.0:
1573
-
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
1574
-
engines: {node: '>=12'}
1575
-
1576
-
sucrase@3.35.0:
1577
-
resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
1505
+
sucrase@3.35.1:
1506
+
resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
1578
1507
engines: {node: '>=16 || 14 >=14.17'}
1579
1508
hasBin: true
1509
+
1510
+
supports-color@10.2.2:
1511
+
resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
1512
+
engines: {node: '>=18'}
1580
1513
1581
1514
supports-preserve-symlinks-flag@1.0.0:
1582
1515
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1583
1516
engines: {node: '>= 0.4'}
1584
1517
1585
-
tailwindcss@3.4.17:
1586
-
resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
1518
+
tailwindcss@3.4.18:
1519
+
resolution: {integrity: sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==}
1587
1520
engines: {node: '>=14.0.0'}
1588
1521
hasBin: true
1589
1522
1590
-
terser@5.39.2:
1591
-
resolution: {integrity: sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==}
1523
+
terser@5.44.1:
1524
+
resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==}
1592
1525
engines: {node: '>=10'}
1593
1526
hasBin: true
1594
1527
···
1599
1532
thenify@3.3.1:
1600
1533
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
1601
1534
1602
-
tinyglobby@0.2.14:
1603
-
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
1535
+
tinyglobby@0.2.15:
1536
+
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
1604
1537
engines: {node: '>=12.0.0'}
1605
1538
1606
1539
to-regex-range@5.0.1:
···
1613
1546
tslib@2.8.1:
1614
1547
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
1615
1548
1616
-
typescript@5.8.3:
1617
-
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
1549
+
typescript@5.9.3:
1550
+
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
1618
1551
engines: {node: '>=14.17'}
1619
1552
hasBin: true
1620
1553
1621
-
ufo@1.6.1:
1622
-
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
1623
-
1624
1554
undici-types@6.21.0:
1625
1555
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
1626
1556
1627
-
undici@5.29.0:
1628
-
resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==}
1629
-
engines: {node: '>=14.0'}
1557
+
undici@7.14.0:
1558
+
resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==}
1559
+
engines: {node: '>=20.18.1'}
1630
1560
1631
-
unenv@2.0.0-rc.17:
1632
-
resolution: {integrity: sha512-B06u0wXkEd+o5gOCMl/ZHl5cfpYbDZKAT+HWTL+Hws6jWu7dCiqBBXXXzMFcFVJb8D4ytAnYmxJA83uwOQRSsg==}
1561
+
unenv@2.0.0-rc.24:
1562
+
resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==}
1633
1563
1634
-
update-browserslist-db@1.1.3:
1635
-
resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
1564
+
update-browserslist-db@1.2.2:
1565
+
resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==}
1636
1566
hasBin: true
1637
1567
peerDependencies:
1638
1568
browserslist: '>= 4.21.0'
···
1640
1570
util-deprecate@1.0.2:
1641
1571
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
1642
1572
1643
-
validate-html-nesting@1.2.2:
1644
-
resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==}
1645
-
1646
-
vite-plugin-solid@2.11.6:
1647
-
resolution: {integrity: sha512-Sl5CTqJTGyEeOsmdH6BOgalIZlwH3t4/y0RQuFLMGnvWMBvxb4+lq7x3BSiAw6etf0QexfNJW7HSOO/Qf7pigg==}
1573
+
vite-plugin-solid@2.11.10:
1574
+
resolution: {integrity: sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw==}
1648
1575
peerDependencies:
1649
1576
'@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.*
1650
1577
solid-js: ^1.7.2
1651
-
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
1578
+
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
1652
1579
peerDependenciesMeta:
1653
1580
'@testing-library/jest-dom':
1654
1581
optional: true
1655
1582
1656
-
vite@6.3.5:
1657
-
resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==}
1658
-
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
1583
+
vite@7.2.7:
1584
+
resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==}
1585
+
engines: {node: ^20.19.0 || >=22.12.0}
1659
1586
hasBin: true
1660
1587
peerDependencies:
1661
-
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
1588
+
'@types/node': ^20.19.0 || >=22.12.0
1662
1589
jiti: '>=1.21.0'
1663
-
less: '*'
1590
+
less: ^4.0.0
1664
1591
lightningcss: ^1.21.0
1665
-
sass: '*'
1666
-
sass-embedded: '*'
1667
-
stylus: '*'
1668
-
sugarss: '*'
1592
+
sass: ^1.70.0
1593
+
sass-embedded: ^1.70.0
1594
+
stylus: '>=0.54.8'
1595
+
sugarss: ^5.0.0
1669
1596
terser: ^5.16.0
1670
1597
tsx: ^4.8.1
1671
1598
yaml: ^2.4.2
···
1693
1620
yaml:
1694
1621
optional: true
1695
1622
1696
-
vitefu@1.0.6:
1697
-
resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==}
1623
+
vitefu@1.1.1:
1624
+
resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==}
1698
1625
peerDependencies:
1699
-
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
1626
+
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0
1700
1627
peerDependenciesMeta:
1701
1628
vite:
1702
1629
optional: true
···
1705
1632
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
1706
1633
engines: {node: '>= 8'}
1707
1634
1708
-
which@2.0.2:
1709
-
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1710
-
engines: {node: '>= 8'}
1711
-
hasBin: true
1712
-
1713
-
workerd@1.20250508.0:
1714
-
resolution: {integrity: sha512-ffLxe7dXSuGoA6jb3Qx2SClIV1aLHfJQ6RhGhzYHjQgv7dL6fdUOSIIGgzmu2mRKs+WFSujp6c8WgKquco6w3w==}
1635
+
workerd@1.20251202.0:
1636
+
resolution: {integrity: sha512-p08YfrUMHkjCECNdT36r+6DpJIZX4kixbZ4n6GMUcLR5Gh18fakSCsiQrh72iOm4M9QHv/rM7P8YvCrUPWT5sg==}
1715
1637
engines: {node: '>=16'}
1716
1638
hasBin: true
1717
1639
1718
-
wrangler@4.16.1:
1719
-
resolution: {integrity: sha512-YiLdWXcaQva2K/bqokpsZbySPmoT8TJFyJPsQPZumnkgimM9+/g/yoXArByA+pf+xU8jhw7ybQ8X1yBGXv731g==}
1720
-
engines: {node: '>=18.0.0'}
1640
+
wrangler@4.53.0:
1641
+
resolution: {integrity: sha512-/wvnHlRnlHsqaeIgGbmcEJE5NFYdTUWHCKow+U5Tv2XwQXI9vXUqBwCLAGy/BwqyS5nnycRt2kppqCzgHgyb7Q==}
1642
+
engines: {node: '>=20.0.0'}
1721
1643
hasBin: true
1722
1644
peerDependencies:
1723
-
'@cloudflare/workers-types': ^4.20250508.0
1645
+
'@cloudflare/workers-types': ^4.20251202.0
1724
1646
peerDependenciesMeta:
1725
1647
'@cloudflare/workers-types':
1726
1648
optional: true
1727
1649
1728
-
wrap-ansi@7.0.0:
1729
-
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
1730
-
engines: {node: '>=10'}
1731
-
1732
-
wrap-ansi@8.1.0:
1733
-
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
1734
-
engines: {node: '>=12'}
1735
-
1736
1650
ws@8.18.0:
1737
1651
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
1738
1652
engines: {node: '>=10.0.0'}
···
1748
1662
yallist@3.1.1:
1749
1663
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
1750
1664
1751
-
yaml@2.8.0:
1752
-
resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==}
1753
-
engines: {node: '>= 14.6'}
1754
-
hasBin: true
1665
+
youch-core@0.3.3:
1666
+
resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==}
1755
1667
1756
-
yocto-queue@1.2.1:
1757
-
resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==}
1758
-
engines: {node: '>=12.20'}
1759
-
1760
-
youch@3.3.4:
1761
-
resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==}
1668
+
youch@4.1.0-beta.10:
1669
+
resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==}
1762
1670
1763
1671
zod@3.22.3:
1764
1672
resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==}
···
1767
1675
1768
1676
'@alloc/quick-lru@5.2.0': {}
1769
1677
1770
-
'@ampproject/remapping@2.3.0':
1678
+
'@atcute/atproto@3.1.9':
1771
1679
dependencies:
1772
-
'@jridgewell/gen-mapping': 0.3.8
1773
-
'@jridgewell/trace-mapping': 0.3.25
1680
+
'@atcute/lexicons': 1.2.5
1774
1681
1775
-
'@atcute/atproto@3.0.2':
1682
+
'@atcute/bluesky@3.2.13':
1776
1683
dependencies:
1777
-
'@atcute/lexicons': 1.0.3
1684
+
'@atcute/atproto': 3.1.9
1685
+
'@atcute/lexicons': 1.2.5
1778
1686
1779
-
'@atcute/bluesky@3.0.2':
1687
+
'@atcute/car@5.0.0':
1780
1688
dependencies:
1781
-
'@atcute/atproto': 3.0.2
1782
-
'@atcute/lexicons': 1.0.3
1689
+
'@atcute/cbor': 2.2.8
1690
+
'@atcute/cid': 2.2.6
1691
+
'@atcute/uint8array': 1.0.6
1692
+
'@atcute/varint': 1.0.3
1783
1693
1784
-
'@atcute/car@3.1.1':
1694
+
'@atcute/cbor@2.2.8':
1785
1695
dependencies:
1786
-
'@atcute/cbor': 2.2.4
1787
-
'@atcute/cid': 2.2.3
1788
-
'@atcute/uint8array': 1.0.2
1789
-
'@atcute/varint': 1.0.2
1790
-
yocto-queue: 1.2.1
1696
+
'@atcute/cid': 2.2.6
1697
+
'@atcute/multibase': 1.1.6
1698
+
'@atcute/uint8array': 1.0.6
1791
1699
1792
-
'@atcute/cbor@2.2.4':
1700
+
'@atcute/cid@2.2.6':
1793
1701
dependencies:
1794
-
'@atcute/cid': 2.2.3
1795
-
'@atcute/multibase': 1.1.4
1796
-
'@atcute/uint8array': 1.0.2
1702
+
'@atcute/multibase': 1.1.6
1703
+
'@atcute/uint8array': 1.0.6
1797
1704
1798
-
'@atcute/cid@2.2.3':
1705
+
'@atcute/client@4.1.1':
1799
1706
dependencies:
1800
-
'@atcute/multibase': 1.1.4
1801
-
'@atcute/uint8array': 1.0.2
1707
+
'@atcute/identity': 1.1.3
1708
+
'@atcute/lexicons': 1.2.5
1802
1709
1803
-
'@atcute/client@4.0.3':
1710
+
'@atcute/crypto@2.3.0':
1804
1711
dependencies:
1805
-
'@atcute/identity': 1.0.2
1806
-
'@atcute/lexicons': 1.0.3
1712
+
'@atcute/multibase': 1.1.6
1713
+
'@atcute/uint8array': 1.0.6
1714
+
'@noble/secp256k1': 3.0.0
1807
1715
1808
-
'@atcute/crypto@2.2.2':
1716
+
'@atcute/did-plc@0.2.0':
1809
1717
dependencies:
1810
-
'@atcute/multibase': 1.1.4
1811
-
'@atcute/uint8array': 1.0.2
1812
-
'@noble/secp256k1': 2.2.3
1718
+
'@atcute/cbor': 2.2.8
1719
+
'@atcute/cid': 2.2.6
1720
+
'@atcute/crypto': 2.3.0
1721
+
'@atcute/identity': 1.1.3
1722
+
'@atcute/lexicons': 1.2.5
1723
+
'@atcute/multibase': 1.1.6
1724
+
'@atcute/uint8array': 1.0.6
1725
+
'@badrap/valita': 0.4.6
1813
1726
1814
-
'@atcute/did-plc@0.1.5':
1727
+
'@atcute/identity-resolver@1.2.0(@atcute/identity@1.1.3)':
1815
1728
dependencies:
1816
-
'@atcute/cbor': 2.2.4
1817
-
'@atcute/cid': 2.2.3
1818
-
'@atcute/crypto': 2.2.2
1819
-
'@atcute/multibase': 1.1.4
1820
-
'@atcute/uint8array': 1.0.2
1821
-
'@badrap/valita': 0.4.5
1729
+
'@atcute/identity': 1.1.3
1730
+
'@atcute/lexicons': 1.2.5
1731
+
'@atcute/util-fetch': 1.0.4
1732
+
'@badrap/valita': 0.4.6
1822
1733
1823
-
'@atcute/identity-resolver@1.1.0(@atcute/identity@1.0.2)':
1734
+
'@atcute/identity@1.1.3':
1824
1735
dependencies:
1825
-
'@atcute/identity': 1.0.2
1826
-
'@atcute/lexicons': 1.0.3
1827
-
'@atcute/util-fetch': 1.0.1
1828
-
'@badrap/valita': 0.4.5
1736
+
'@atcute/lexicons': 1.2.5
1737
+
'@badrap/valita': 0.4.6
1829
1738
1830
-
'@atcute/identity@1.0.2':
1739
+
'@atcute/lexicons@1.2.5':
1831
1740
dependencies:
1832
-
'@atcute/lexicons': 1.0.3
1833
-
'@badrap/valita': 0.4.5
1741
+
'@standard-schema/spec': 1.0.0
1742
+
esm-env: 1.2.2
1743
+
1744
+
'@atcute/mst@0.1.0':
1745
+
dependencies:
1746
+
'@atcute/cbor': 2.2.8
1747
+
'@atcute/cid': 2.2.6
1748
+
'@atcute/uint8array': 1.0.6
1834
1749
1835
-
'@atcute/lexicons@1.0.3':
1750
+
'@atcute/multibase@1.1.6':
1836
1751
dependencies:
1837
-
esm-env: 1.2.2
1752
+
'@atcute/uint8array': 1.0.6
1838
1753
1839
-
'@atcute/multibase@1.1.4':
1754
+
'@atcute/repo@0.1.0':
1840
1755
dependencies:
1841
-
'@atcute/uint8array': 1.0.2
1756
+
'@atcute/car': 5.0.0
1757
+
'@atcute/cbor': 2.2.8
1758
+
'@atcute/cid': 2.2.6
1759
+
'@atcute/crypto': 2.3.0
1760
+
'@atcute/lexicons': 1.2.5
1761
+
'@atcute/mst': 0.1.0
1762
+
'@atcute/uint8array': 1.0.6
1842
1763
1843
-
'@atcute/tid@1.0.2': {}
1764
+
'@atcute/tid@1.0.3': {}
1844
1765
1845
-
'@atcute/uint8array@1.0.2': {}
1766
+
'@atcute/uint8array@1.0.6': {}
1846
1767
1847
-
'@atcute/util-fetch@1.0.1':
1768
+
'@atcute/util-fetch@1.0.4':
1848
1769
dependencies:
1849
-
'@badrap/valita': 0.4.5
1770
+
'@badrap/valita': 0.4.6
1850
1771
1851
-
'@atcute/varint@1.0.2': {}
1772
+
'@atcute/varint@1.0.3': {}
1852
1773
1853
1774
'@babel/code-frame@7.27.1':
1854
1775
dependencies:
1855
-
'@babel/helper-validator-identifier': 7.27.1
1776
+
'@babel/helper-validator-identifier': 7.28.5
1856
1777
js-tokens: 4.0.0
1857
1778
picocolors: 1.1.1
1858
1779
1859
-
'@babel/compat-data@7.27.2': {}
1780
+
'@babel/compat-data@7.28.5': {}
1860
1781
1861
-
'@babel/core@7.27.1':
1782
+
'@babel/core@7.28.5':
1862
1783
dependencies:
1863
-
'@ampproject/remapping': 2.3.0
1864
1784
'@babel/code-frame': 7.27.1
1865
-
'@babel/generator': 7.27.1
1785
+
'@babel/generator': 7.28.5
1866
1786
'@babel/helper-compilation-targets': 7.27.2
1867
-
'@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1)
1868
-
'@babel/helpers': 7.27.1
1869
-
'@babel/parser': 7.27.2
1787
+
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
1788
+
'@babel/helpers': 7.28.4
1789
+
'@babel/parser': 7.28.5
1870
1790
'@babel/template': 7.27.2
1871
-
'@babel/traverse': 7.27.1
1872
-
'@babel/types': 7.27.1
1791
+
'@babel/traverse': 7.28.5
1792
+
'@babel/types': 7.28.5
1793
+
'@jridgewell/remapping': 2.3.5
1873
1794
convert-source-map: 2.0.0
1874
-
debug: 4.4.1
1795
+
debug: 4.4.3
1875
1796
gensync: 1.0.0-beta.2
1876
1797
json5: 2.2.3
1877
1798
semver: 6.3.1
1878
1799
transitivePeerDependencies:
1879
1800
- supports-color
1880
1801
1881
-
'@babel/generator@7.27.1':
1802
+
'@babel/generator@7.28.5':
1882
1803
dependencies:
1883
-
'@babel/parser': 7.27.2
1884
-
'@babel/types': 7.27.1
1885
-
'@jridgewell/gen-mapping': 0.3.8
1886
-
'@jridgewell/trace-mapping': 0.3.25
1804
+
'@babel/parser': 7.28.5
1805
+
'@babel/types': 7.28.5
1806
+
'@jridgewell/gen-mapping': 0.3.13
1807
+
'@jridgewell/trace-mapping': 0.3.31
1887
1808
jsesc: 3.1.0
1888
1809
1889
1810
'@babel/helper-compilation-targets@7.27.2':
1890
1811
dependencies:
1891
-
'@babel/compat-data': 7.27.2
1812
+
'@babel/compat-data': 7.28.5
1892
1813
'@babel/helper-validator-option': 7.27.1
1893
-
browserslist: 4.24.5
1814
+
browserslist: 4.28.1
1894
1815
lru-cache: 5.1.1
1895
1816
semver: 6.3.1
1896
1817
1818
+
'@babel/helper-globals@7.28.0': {}
1819
+
1897
1820
'@babel/helper-module-imports@7.18.6':
1898
1821
dependencies:
1899
-
'@babel/types': 7.27.1
1822
+
'@babel/types': 7.28.5
1900
1823
1901
1824
'@babel/helper-module-imports@7.27.1':
1902
1825
dependencies:
1903
-
'@babel/traverse': 7.27.1
1904
-
'@babel/types': 7.27.1
1826
+
'@babel/traverse': 7.28.5
1827
+
'@babel/types': 7.28.5
1905
1828
transitivePeerDependencies:
1906
1829
- supports-color
1907
1830
1908
-
'@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)':
1831
+
'@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)':
1909
1832
dependencies:
1910
-
'@babel/core': 7.27.1
1833
+
'@babel/core': 7.28.5
1911
1834
'@babel/helper-module-imports': 7.27.1
1912
-
'@babel/helper-validator-identifier': 7.27.1
1913
-
'@babel/traverse': 7.27.1
1835
+
'@babel/helper-validator-identifier': 7.28.5
1836
+
'@babel/traverse': 7.28.5
1914
1837
transitivePeerDependencies:
1915
1838
- supports-color
1916
1839
···
1918
1841
1919
1842
'@babel/helper-string-parser@7.27.1': {}
1920
1843
1921
-
'@babel/helper-validator-identifier@7.27.1': {}
1844
+
'@babel/helper-validator-identifier@7.28.5': {}
1922
1845
1923
1846
'@babel/helper-validator-option@7.27.1': {}
1924
1847
1925
-
'@babel/helpers@7.27.1':
1848
+
'@babel/helpers@7.28.4':
1926
1849
dependencies:
1927
1850
'@babel/template': 7.27.2
1928
-
'@babel/types': 7.27.1
1851
+
'@babel/types': 7.28.5
1929
1852
1930
-
'@babel/parser@7.27.2':
1853
+
'@babel/parser@7.28.5':
1931
1854
dependencies:
1932
-
'@babel/types': 7.27.1
1855
+
'@babel/types': 7.28.5
1933
1856
1934
-
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)':
1857
+
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)':
1935
1858
dependencies:
1936
-
'@babel/core': 7.27.1
1859
+
'@babel/core': 7.28.5
1937
1860
'@babel/helper-plugin-utils': 7.27.1
1938
1861
1939
1862
'@babel/template@7.27.2':
1940
1863
dependencies:
1941
1864
'@babel/code-frame': 7.27.1
1942
-
'@babel/parser': 7.27.2
1943
-
'@babel/types': 7.27.1
1865
+
'@babel/parser': 7.28.5
1866
+
'@babel/types': 7.28.5
1944
1867
1945
-
'@babel/traverse@7.27.1':
1868
+
'@babel/traverse@7.28.5':
1946
1869
dependencies:
1947
1870
'@babel/code-frame': 7.27.1
1948
-
'@babel/generator': 7.27.1
1949
-
'@babel/parser': 7.27.2
1871
+
'@babel/generator': 7.28.5
1872
+
'@babel/helper-globals': 7.28.0
1873
+
'@babel/parser': 7.28.5
1950
1874
'@babel/template': 7.27.2
1951
-
'@babel/types': 7.27.1
1952
-
debug: 4.4.1
1953
-
globals: 11.12.0
1875
+
'@babel/types': 7.28.5
1876
+
debug: 4.4.3
1954
1877
transitivePeerDependencies:
1955
1878
- supports-color
1956
1879
1957
-
'@babel/types@7.27.1':
1880
+
'@babel/types@7.28.5':
1958
1881
dependencies:
1959
1882
'@babel/helper-string-parser': 7.27.1
1960
-
'@babel/helper-validator-identifier': 7.27.1
1883
+
'@babel/helper-validator-identifier': 7.28.5
1961
1884
1962
-
'@badrap/valita@0.4.5': {}
1885
+
'@badrap/valita@0.4.6': {}
1963
1886
1964
-
'@cloudflare/kv-asset-handler@0.4.0':
1887
+
'@cloudflare/kv-asset-handler@0.4.1':
1965
1888
dependencies:
1966
1889
mime: 3.0.0
1967
1890
1968
-
'@cloudflare/unenv-preset@2.3.2(unenv@2.0.0-rc.17)(workerd@1.20250508.0)':
1891
+
'@cloudflare/unenv-preset@2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251202.0)':
1969
1892
dependencies:
1970
-
unenv: 2.0.0-rc.17
1893
+
unenv: 2.0.0-rc.24
1971
1894
optionalDependencies:
1972
-
workerd: 1.20250508.0
1895
+
workerd: 1.20251202.0
1973
1896
1974
-
'@cloudflare/workerd-darwin-64@1.20250508.0':
1897
+
'@cloudflare/workerd-darwin-64@1.20251202.0':
1975
1898
optional: true
1976
1899
1977
-
'@cloudflare/workerd-darwin-arm64@1.20250508.0':
1900
+
'@cloudflare/workerd-darwin-arm64@1.20251202.0':
1978
1901
optional: true
1979
1902
1980
-
'@cloudflare/workerd-linux-64@1.20250508.0':
1903
+
'@cloudflare/workerd-linux-64@1.20251202.0':
1981
1904
optional: true
1982
1905
1983
-
'@cloudflare/workerd-linux-arm64@1.20250508.0':
1906
+
'@cloudflare/workerd-linux-arm64@1.20251202.0':
1984
1907
optional: true
1985
1908
1986
-
'@cloudflare/workerd-windows-64@1.20250508.0':
1909
+
'@cloudflare/workerd-windows-64@1.20251202.0':
1987
1910
optional: true
1988
1911
1989
1912
'@cspotcode/source-map-support@0.8.1':
1990
1913
dependencies:
1991
1914
'@jridgewell/trace-mapping': 0.3.9
1992
1915
1993
-
'@emnapi/runtime@1.4.3':
1916
+
'@emnapi/runtime@1.7.1':
1994
1917
dependencies:
1995
1918
tslib: 2.8.1
1996
1919
optional: true
1997
1920
1998
-
'@esbuild/aix-ppc64@0.25.4':
1921
+
'@esbuild/aix-ppc64@0.25.12':
1922
+
optional: true
1923
+
1924
+
'@esbuild/aix-ppc64@0.27.0':
1925
+
optional: true
1926
+
1927
+
'@esbuild/android-arm64@0.25.12':
1999
1928
optional: true
2000
1929
2001
-
'@esbuild/aix-ppc64@0.25.5':
1930
+
'@esbuild/android-arm64@0.27.0':
2002
1931
optional: true
2003
1932
2004
-
'@esbuild/android-arm64@0.25.4':
1933
+
'@esbuild/android-arm@0.25.12':
2005
1934
optional: true
2006
1935
2007
-
'@esbuild/android-arm64@0.25.5':
1936
+
'@esbuild/android-arm@0.27.0':
2008
1937
optional: true
2009
1938
2010
-
'@esbuild/android-arm@0.25.4':
1939
+
'@esbuild/android-x64@0.25.12':
2011
1940
optional: true
2012
1941
2013
-
'@esbuild/android-arm@0.25.5':
1942
+
'@esbuild/android-x64@0.27.0':
2014
1943
optional: true
2015
1944
2016
-
'@esbuild/android-x64@0.25.4':
1945
+
'@esbuild/darwin-arm64@0.25.12':
2017
1946
optional: true
2018
1947
2019
-
'@esbuild/android-x64@0.25.5':
1948
+
'@esbuild/darwin-arm64@0.27.0':
2020
1949
optional: true
2021
1950
2022
-
'@esbuild/darwin-arm64@0.25.4':
1951
+
'@esbuild/darwin-x64@0.25.12':
2023
1952
optional: true
2024
1953
2025
-
'@esbuild/darwin-arm64@0.25.5':
1954
+
'@esbuild/darwin-x64@0.27.0':
2026
1955
optional: true
2027
1956
2028
-
'@esbuild/darwin-x64@0.25.4':
1957
+
'@esbuild/freebsd-arm64@0.25.12':
2029
1958
optional: true
2030
1959
2031
-
'@esbuild/darwin-x64@0.25.5':
1960
+
'@esbuild/freebsd-arm64@0.27.0':
2032
1961
optional: true
2033
1962
2034
-
'@esbuild/freebsd-arm64@0.25.4':
1963
+
'@esbuild/freebsd-x64@0.25.12':
2035
1964
optional: true
2036
1965
2037
-
'@esbuild/freebsd-arm64@0.25.5':
1966
+
'@esbuild/freebsd-x64@0.27.0':
2038
1967
optional: true
2039
1968
2040
-
'@esbuild/freebsd-x64@0.25.4':
1969
+
'@esbuild/linux-arm64@0.25.12':
2041
1970
optional: true
2042
1971
2043
-
'@esbuild/freebsd-x64@0.25.5':
1972
+
'@esbuild/linux-arm64@0.27.0':
2044
1973
optional: true
2045
1974
2046
-
'@esbuild/linux-arm64@0.25.4':
1975
+
'@esbuild/linux-arm@0.25.12':
2047
1976
optional: true
2048
1977
2049
-
'@esbuild/linux-arm64@0.25.5':
1978
+
'@esbuild/linux-arm@0.27.0':
2050
1979
optional: true
2051
1980
2052
-
'@esbuild/linux-arm@0.25.4':
1981
+
'@esbuild/linux-ia32@0.25.12':
2053
1982
optional: true
2054
1983
2055
-
'@esbuild/linux-arm@0.25.5':
1984
+
'@esbuild/linux-ia32@0.27.0':
2056
1985
optional: true
2057
1986
2058
-
'@esbuild/linux-ia32@0.25.4':
1987
+
'@esbuild/linux-loong64@0.25.12':
2059
1988
optional: true
2060
1989
2061
-
'@esbuild/linux-ia32@0.25.5':
1990
+
'@esbuild/linux-loong64@0.27.0':
2062
1991
optional: true
2063
1992
2064
-
'@esbuild/linux-loong64@0.25.4':
1993
+
'@esbuild/linux-mips64el@0.25.12':
2065
1994
optional: true
2066
1995
2067
-
'@esbuild/linux-loong64@0.25.5':
1996
+
'@esbuild/linux-mips64el@0.27.0':
2068
1997
optional: true
2069
1998
2070
-
'@esbuild/linux-mips64el@0.25.4':
1999
+
'@esbuild/linux-ppc64@0.25.12':
2071
2000
optional: true
2072
2001
2073
-
'@esbuild/linux-mips64el@0.25.5':
2002
+
'@esbuild/linux-ppc64@0.27.0':
2074
2003
optional: true
2075
2004
2076
-
'@esbuild/linux-ppc64@0.25.4':
2005
+
'@esbuild/linux-riscv64@0.25.12':
2077
2006
optional: true
2078
2007
2079
-
'@esbuild/linux-ppc64@0.25.5':
2008
+
'@esbuild/linux-riscv64@0.27.0':
2080
2009
optional: true
2081
2010
2082
-
'@esbuild/linux-riscv64@0.25.4':
2011
+
'@esbuild/linux-s390x@0.25.12':
2083
2012
optional: true
2084
2013
2085
-
'@esbuild/linux-riscv64@0.25.5':
2014
+
'@esbuild/linux-s390x@0.27.0':
2086
2015
optional: true
2087
2016
2088
-
'@esbuild/linux-s390x@0.25.4':
2017
+
'@esbuild/linux-x64@0.25.12':
2089
2018
optional: true
2090
2019
2091
-
'@esbuild/linux-s390x@0.25.5':
2020
+
'@esbuild/linux-x64@0.27.0':
2092
2021
optional: true
2093
2022
2094
-
'@esbuild/linux-x64@0.25.4':
2023
+
'@esbuild/netbsd-arm64@0.25.12':
2095
2024
optional: true
2096
2025
2097
-
'@esbuild/linux-x64@0.25.5':
2026
+
'@esbuild/netbsd-arm64@0.27.0':
2098
2027
optional: true
2099
2028
2100
-
'@esbuild/netbsd-arm64@0.25.4':
2029
+
'@esbuild/netbsd-x64@0.25.12':
2101
2030
optional: true
2102
2031
2103
-
'@esbuild/netbsd-arm64@0.25.5':
2032
+
'@esbuild/netbsd-x64@0.27.0':
2104
2033
optional: true
2105
2034
2106
-
'@esbuild/netbsd-x64@0.25.4':
2035
+
'@esbuild/openbsd-arm64@0.25.12':
2107
2036
optional: true
2108
2037
2109
-
'@esbuild/netbsd-x64@0.25.5':
2038
+
'@esbuild/openbsd-arm64@0.27.0':
2110
2039
optional: true
2111
2040
2112
-
'@esbuild/openbsd-arm64@0.25.4':
2041
+
'@esbuild/openbsd-x64@0.25.12':
2113
2042
optional: true
2114
2043
2115
-
'@esbuild/openbsd-arm64@0.25.5':
2044
+
'@esbuild/openbsd-x64@0.27.0':
2116
2045
optional: true
2117
2046
2118
-
'@esbuild/openbsd-x64@0.25.4':
2047
+
'@esbuild/openharmony-arm64@0.25.12':
2119
2048
optional: true
2120
2049
2121
-
'@esbuild/openbsd-x64@0.25.5':
2050
+
'@esbuild/openharmony-arm64@0.27.0':
2122
2051
optional: true
2123
2052
2124
-
'@esbuild/sunos-x64@0.25.4':
2053
+
'@esbuild/sunos-x64@0.25.12':
2125
2054
optional: true
2126
2055
2127
-
'@esbuild/sunos-x64@0.25.5':
2056
+
'@esbuild/sunos-x64@0.27.0':
2128
2057
optional: true
2129
2058
2130
-
'@esbuild/win32-arm64@0.25.4':
2059
+
'@esbuild/win32-arm64@0.25.12':
2131
2060
optional: true
2132
2061
2133
-
'@esbuild/win32-arm64@0.25.5':
2062
+
'@esbuild/win32-arm64@0.27.0':
2134
2063
optional: true
2135
2064
2136
-
'@esbuild/win32-ia32@0.25.4':
2065
+
'@esbuild/win32-ia32@0.25.12':
2137
2066
optional: true
2138
2067
2139
-
'@esbuild/win32-ia32@0.25.5':
2068
+
'@esbuild/win32-ia32@0.27.0':
2140
2069
optional: true
2141
2070
2142
-
'@esbuild/win32-x64@0.25.4':
2071
+
'@esbuild/win32-x64@0.25.12':
2143
2072
optional: true
2144
2073
2145
-
'@esbuild/win32-x64@0.25.5':
2074
+
'@esbuild/win32-x64@0.27.0':
2146
2075
optional: true
2147
2076
2148
-
'@externdefs/solid-freeze@0.1.1(solid-js@1.9.7)':
2077
+
'@externdefs/solid-freeze@0.1.1(solid-js@1.9.10)':
2149
2078
dependencies:
2150
-
solid-js: 1.9.7
2151
-
2152
-
'@fastify/busboy@2.1.1': {}
2079
+
solid-js: 1.9.10
2153
2080
2154
2081
'@img/sharp-darwin-arm64@0.33.5':
2155
2082
optionalDependencies:
···
2217
2144
2218
2145
'@img/sharp-wasm32@0.33.5':
2219
2146
dependencies:
2220
-
'@emnapi/runtime': 1.4.3
2147
+
'@emnapi/runtime': 1.7.1
2221
2148
optional: true
2222
2149
2223
2150
'@img/sharp-win32-ia32@0.33.5':
···
2226
2153
'@img/sharp-win32-x64@0.33.5':
2227
2154
optional: true
2228
2155
2229
-
'@isaacs/cliui@8.0.2':
2156
+
'@jridgewell/gen-mapping@0.3.13':
2230
2157
dependencies:
2231
-
string-width: 5.1.2
2232
-
string-width-cjs: string-width@4.2.3
2233
-
strip-ansi: 7.1.0
2234
-
strip-ansi-cjs: strip-ansi@6.0.1
2235
-
wrap-ansi: 8.1.0
2236
-
wrap-ansi-cjs: wrap-ansi@7.0.0
2158
+
'@jridgewell/sourcemap-codec': 1.5.5
2159
+
'@jridgewell/trace-mapping': 0.3.31
2237
2160
2238
-
'@jridgewell/gen-mapping@0.3.8':
2161
+
'@jridgewell/remapping@2.3.5':
2239
2162
dependencies:
2240
-
'@jridgewell/set-array': 1.2.1
2241
-
'@jridgewell/sourcemap-codec': 1.5.0
2242
-
'@jridgewell/trace-mapping': 0.3.25
2163
+
'@jridgewell/gen-mapping': 0.3.13
2164
+
'@jridgewell/trace-mapping': 0.3.31
2243
2165
2244
2166
'@jridgewell/resolve-uri@3.1.2': {}
2245
2167
2246
-
'@jridgewell/set-array@1.2.1': {}
2247
-
2248
-
'@jridgewell/source-map@0.3.6':
2168
+
'@jridgewell/source-map@0.3.11':
2249
2169
dependencies:
2250
-
'@jridgewell/gen-mapping': 0.3.8
2251
-
'@jridgewell/trace-mapping': 0.3.25
2170
+
'@jridgewell/gen-mapping': 0.3.13
2171
+
'@jridgewell/trace-mapping': 0.3.31
2252
2172
2253
-
'@jridgewell/sourcemap-codec@1.5.0': {}
2173
+
'@jridgewell/sourcemap-codec@1.5.5': {}
2254
2174
2255
-
'@jridgewell/trace-mapping@0.3.25':
2175
+
'@jridgewell/trace-mapping@0.3.31':
2256
2176
dependencies:
2257
2177
'@jridgewell/resolve-uri': 3.1.2
2258
-
'@jridgewell/sourcemap-codec': 1.5.0
2178
+
'@jridgewell/sourcemap-codec': 1.5.5
2259
2179
2260
2180
'@jridgewell/trace-mapping@0.3.9':
2261
2181
dependencies:
2262
2182
'@jridgewell/resolve-uri': 3.1.2
2263
-
'@jridgewell/sourcemap-codec': 1.5.0
2183
+
'@jridgewell/sourcemap-codec': 1.5.5
2264
2184
2265
-
'@jsr/mary__array-fns@0.1.4': {}
2185
+
'@jsr/mary__array-fns@0.1.5': {}
2266
2186
2267
-
'@jsr/mary__ds-queue@0.1.2': {}
2187
+
'@jsr/mary__ds-queue@0.1.3': {}
2268
2188
2269
2189
'@jsr/mary__events@0.2.0': {}
2270
2190
2271
-
'@jsr/mary__tar@0.2.4': {}
2191
+
'@jsr/mary__tar@0.3.1': {}
2272
2192
2273
-
'@noble/secp256k1@2.2.3': {}
2193
+
'@noble/secp256k1@3.0.0': {}
2274
2194
2275
2195
'@nodelib/fs.scandir@2.1.5':
2276
2196
dependencies:
···
2284
2204
'@nodelib/fs.scandir': 2.1.5
2285
2205
fastq: 1.19.1
2286
2206
2287
-
'@pkgjs/parseargs@0.11.0':
2207
+
'@poppinss/colors@4.1.5':
2208
+
dependencies:
2209
+
kleur: 4.1.5
2210
+
2211
+
'@poppinss/dumper@0.6.5':
2212
+
dependencies:
2213
+
'@poppinss/colors': 4.1.5
2214
+
'@sindresorhus/is': 7.1.1
2215
+
supports-color: 10.2.2
2216
+
2217
+
'@poppinss/exception@1.2.2': {}
2218
+
2219
+
'@rollup/rollup-android-arm-eabi@4.53.3':
2288
2220
optional: true
2289
2221
2290
-
'@rollup/rollup-android-arm-eabi@4.41.1':
2222
+
'@rollup/rollup-android-arm64@4.53.3':
2291
2223
optional: true
2292
2224
2293
-
'@rollup/rollup-android-arm64@4.41.1':
2225
+
'@rollup/rollup-darwin-arm64@4.53.3':
2294
2226
optional: true
2295
2227
2296
-
'@rollup/rollup-darwin-arm64@4.41.1':
2228
+
'@rollup/rollup-darwin-x64@4.53.3':
2297
2229
optional: true
2298
2230
2299
-
'@rollup/rollup-darwin-x64@4.41.1':
2231
+
'@rollup/rollup-freebsd-arm64@4.53.3':
2300
2232
optional: true
2301
2233
2302
-
'@rollup/rollup-freebsd-arm64@4.41.1':
2234
+
'@rollup/rollup-freebsd-x64@4.53.3':
2303
2235
optional: true
2304
2236
2305
-
'@rollup/rollup-freebsd-x64@4.41.1':
2237
+
'@rollup/rollup-linux-arm-gnueabihf@4.53.3':
2306
2238
optional: true
2307
2239
2308
-
'@rollup/rollup-linux-arm-gnueabihf@4.41.1':
2240
+
'@rollup/rollup-linux-arm-musleabihf@4.53.3':
2309
2241
optional: true
2310
2242
2311
-
'@rollup/rollup-linux-arm-musleabihf@4.41.1':
2243
+
'@rollup/rollup-linux-arm64-gnu@4.53.3':
2312
2244
optional: true
2313
2245
2314
-
'@rollup/rollup-linux-arm64-gnu@4.41.1':
2246
+
'@rollup/rollup-linux-arm64-musl@4.53.3':
2315
2247
optional: true
2316
2248
2317
-
'@rollup/rollup-linux-arm64-musl@4.41.1':
2249
+
'@rollup/rollup-linux-loong64-gnu@4.53.3':
2318
2250
optional: true
2319
2251
2320
-
'@rollup/rollup-linux-loongarch64-gnu@4.41.1':
2252
+
'@rollup/rollup-linux-ppc64-gnu@4.53.3':
2253
+
optional: true
2254
+
2255
+
'@rollup/rollup-linux-riscv64-gnu@4.53.3':
2321
2256
optional: true
2322
2257
2323
-
'@rollup/rollup-linux-powerpc64le-gnu@4.41.1':
2258
+
'@rollup/rollup-linux-riscv64-musl@4.53.3':
2324
2259
optional: true
2325
2260
2326
-
'@rollup/rollup-linux-riscv64-gnu@4.41.1':
2261
+
'@rollup/rollup-linux-s390x-gnu@4.53.3':
2327
2262
optional: true
2328
2263
2329
-
'@rollup/rollup-linux-riscv64-musl@4.41.1':
2264
+
'@rollup/rollup-linux-x64-gnu@4.53.3':
2330
2265
optional: true
2331
2266
2332
-
'@rollup/rollup-linux-s390x-gnu@4.41.1':
2267
+
'@rollup/rollup-linux-x64-musl@4.53.3':
2333
2268
optional: true
2334
2269
2335
-
'@rollup/rollup-linux-x64-gnu@4.41.1':
2270
+
'@rollup/rollup-openharmony-arm64@4.53.3':
2336
2271
optional: true
2337
2272
2338
-
'@rollup/rollup-linux-x64-musl@4.41.1':
2273
+
'@rollup/rollup-win32-arm64-msvc@4.53.3':
2339
2274
optional: true
2340
2275
2341
-
'@rollup/rollup-win32-arm64-msvc@4.41.1':
2276
+
'@rollup/rollup-win32-ia32-msvc@4.53.3':
2342
2277
optional: true
2343
2278
2344
-
'@rollup/rollup-win32-ia32-msvc@4.41.1':
2279
+
'@rollup/rollup-win32-x64-gnu@4.53.3':
2345
2280
optional: true
2346
2281
2347
-
'@rollup/rollup-win32-x64-msvc@4.41.1':
2282
+
'@rollup/rollup-win32-x64-msvc@4.53.3':
2348
2283
optional: true
2349
2284
2350
-
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.17)':
2285
+
'@sindresorhus/is@7.1.1': {}
2286
+
2287
+
'@speed-highlight/core@1.2.12': {}
2288
+
2289
+
'@standard-schema/spec@1.0.0': {}
2290
+
2291
+
'@tailwindcss/forms@0.5.10(tailwindcss@3.4.18)':
2351
2292
dependencies:
2352
2293
mini-svg-data-uri: 1.4.4
2353
-
tailwindcss: 3.4.17
2294
+
tailwindcss: 3.4.18
2354
2295
2355
2296
'@types/babel__core@7.20.5':
2356
2297
dependencies:
2357
-
'@babel/parser': 7.27.2
2358
-
'@babel/types': 7.27.1
2298
+
'@babel/parser': 7.28.5
2299
+
'@babel/types': 7.28.5
2359
2300
'@types/babel__generator': 7.27.0
2360
2301
'@types/babel__template': 7.4.4
2361
-
'@types/babel__traverse': 7.20.7
2302
+
'@types/babel__traverse': 7.28.0
2362
2303
2363
2304
'@types/babel__generator@7.27.0':
2364
2305
dependencies:
2365
-
'@babel/types': 7.27.1
2306
+
'@babel/types': 7.28.5
2366
2307
2367
2308
'@types/babel__template@7.4.4':
2368
2309
dependencies:
2369
-
'@babel/parser': 7.27.2
2370
-
'@babel/types': 7.27.1
2310
+
'@babel/parser': 7.28.5
2311
+
'@babel/types': 7.28.5
2371
2312
2372
-
'@types/babel__traverse@7.20.7':
2313
+
'@types/babel__traverse@7.28.0':
2373
2314
dependencies:
2374
-
'@babel/types': 7.27.1
2315
+
'@babel/types': 7.28.5
2375
2316
2376
-
'@types/estree@1.0.7': {}
2317
+
'@types/estree@1.0.8': {}
2377
2318
2378
-
'@types/node@22.15.21':
2319
+
'@types/node@22.19.2':
2379
2320
dependencies:
2380
2321
undici-types: 6.21.0
2381
2322
···
2383
2324
2384
2325
acorn@8.14.0: {}
2385
2326
2386
-
acorn@8.14.1: {}
2387
-
2388
-
ansi-regex@5.0.1: {}
2389
-
2390
-
ansi-regex@6.1.0: {}
2391
-
2392
-
ansi-styles@4.3.0:
2393
-
dependencies:
2394
-
color-convert: 2.0.1
2395
-
2396
-
ansi-styles@6.2.1: {}
2327
+
acorn@8.15.0: {}
2397
2328
2398
2329
any-promise@1.3.0: {}
2399
2330
···
2404
2335
2405
2336
arg@5.0.2: {}
2406
2337
2407
-
as-table@1.0.55:
2408
-
dependencies:
2409
-
printable-characters: 1.0.42
2410
-
2411
-
autoprefixer@10.4.21(postcss@8.5.3):
2338
+
autoprefixer@10.4.22(postcss@8.5.6):
2412
2339
dependencies:
2413
-
browserslist: 4.24.5
2414
-
caniuse-lite: 1.0.30001718
2415
-
fraction.js: 4.3.7
2340
+
browserslist: 4.28.1
2341
+
caniuse-lite: 1.0.30001760
2342
+
fraction.js: 5.3.4
2416
2343
normalize-range: 0.1.2
2417
2344
picocolors: 1.1.1
2418
-
postcss: 8.5.3
2345
+
postcss: 8.5.6
2419
2346
postcss-value-parser: 4.2.0
2420
2347
2421
-
babel-plugin-jsx-dom-expressions@0.39.8(@babel/core@7.27.1):
2348
+
babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.28.5):
2422
2349
dependencies:
2423
-
'@babel/core': 7.27.1
2350
+
'@babel/core': 7.28.5
2424
2351
'@babel/helper-module-imports': 7.18.6
2425
-
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1)
2426
-
'@babel/types': 7.27.1
2352
+
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5)
2353
+
'@babel/types': 7.28.5
2427
2354
html-entities: 2.3.3
2428
2355
parse5: 7.3.0
2429
-
validate-html-nesting: 1.2.2
2430
2356
2431
-
babel-preset-solid@1.9.6(@babel/core@7.27.1):
2357
+
babel-preset-solid@1.9.10(@babel/core@7.28.5)(solid-js@1.9.10):
2432
2358
dependencies:
2433
-
'@babel/core': 7.27.1
2434
-
babel-plugin-jsx-dom-expressions: 0.39.8(@babel/core@7.27.1)
2359
+
'@babel/core': 7.28.5
2360
+
babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.28.5)
2361
+
optionalDependencies:
2362
+
solid-js: 1.9.10
2435
2363
2436
-
balanced-match@1.0.2: {}
2364
+
baseline-browser-mapping@2.9.5: {}
2437
2365
2438
2366
binary-extensions@2.3.0: {}
2439
2367
2440
2368
blake3-wasm@2.1.5: {}
2441
-
2442
-
brace-expansion@2.0.1:
2443
-
dependencies:
2444
-
balanced-match: 1.0.2
2445
2369
2446
2370
braces@3.0.3:
2447
2371
dependencies:
2448
2372
fill-range: 7.1.1
2449
2373
2450
-
browserslist@4.24.5:
2374
+
browserslist@4.28.1:
2451
2375
dependencies:
2452
-
caniuse-lite: 1.0.30001718
2453
-
electron-to-chromium: 1.5.158
2454
-
node-releases: 2.0.19
2455
-
update-browserslist-db: 1.1.3(browserslist@4.24.5)
2376
+
baseline-browser-mapping: 2.9.5
2377
+
caniuse-lite: 1.0.30001760
2378
+
electron-to-chromium: 1.5.267
2379
+
node-releases: 2.0.27
2380
+
update-browserslist-db: 1.2.2(browserslist@4.28.1)
2456
2381
2457
2382
buffer-from@1.1.2: {}
2458
2383
2459
2384
camelcase-css@2.0.1: {}
2460
2385
2461
-
caniuse-lite@1.0.30001718: {}
2386
+
caniuse-lite@1.0.30001760: {}
2462
2387
2463
2388
chokidar@3.6.0:
2464
2389
dependencies:
···
2481
2406
color-string@1.9.1:
2482
2407
dependencies:
2483
2408
color-name: 1.1.4
2484
-
simple-swizzle: 0.2.2
2409
+
simple-swizzle: 0.2.4
2485
2410
2486
2411
color@4.2.3:
2487
2412
dependencies:
···
2494
2419
2495
2420
convert-source-map@2.0.0: {}
2496
2421
2497
-
cookie@0.7.2: {}
2498
-
2499
-
cross-spawn@7.0.6:
2500
-
dependencies:
2501
-
path-key: 3.1.1
2502
-
shebang-command: 2.0.0
2503
-
which: 2.0.2
2422
+
cookie@1.1.1: {}
2504
2423
2505
2424
cssesc@3.0.0: {}
2506
2425
2507
-
csstype@3.1.3: {}
2508
-
2509
-
data-uri-to-buffer@2.0.2: {}
2426
+
csstype@3.2.3: {}
2510
2427
2511
-
debug@4.4.1:
2428
+
debug@4.4.3:
2512
2429
dependencies:
2513
2430
ms: 2.1.3
2514
2431
2515
-
defu@6.1.4: {}
2516
-
2517
-
detect-libc@2.0.4: {}
2432
+
detect-libc@2.1.2: {}
2518
2433
2519
2434
didyoumean@1.2.2: {}
2520
2435
2521
2436
dlv@1.1.3: {}
2522
2437
2523
-
eastasianwidth@0.2.0: {}
2438
+
electron-to-chromium@1.5.267: {}
2524
2439
2525
-
electron-to-chromium@1.5.158: {}
2440
+
entities@6.0.1: {}
2526
2441
2527
-
emoji-regex@8.0.0: {}
2528
-
2529
-
emoji-regex@9.2.2: {}
2530
-
2531
-
entities@6.0.0: {}
2442
+
error-stack-parser-es@1.0.5: {}
2532
2443
2533
-
esbuild@0.25.4:
2444
+
esbuild@0.25.12:
2534
2445
optionalDependencies:
2535
-
'@esbuild/aix-ppc64': 0.25.4
2536
-
'@esbuild/android-arm': 0.25.4
2537
-
'@esbuild/android-arm64': 0.25.4
2538
-
'@esbuild/android-x64': 0.25.4
2539
-
'@esbuild/darwin-arm64': 0.25.4
2540
-
'@esbuild/darwin-x64': 0.25.4
2541
-
'@esbuild/freebsd-arm64': 0.25.4
2542
-
'@esbuild/freebsd-x64': 0.25.4
2543
-
'@esbuild/linux-arm': 0.25.4
2544
-
'@esbuild/linux-arm64': 0.25.4
2545
-
'@esbuild/linux-ia32': 0.25.4
2546
-
'@esbuild/linux-loong64': 0.25.4
2547
-
'@esbuild/linux-mips64el': 0.25.4
2548
-
'@esbuild/linux-ppc64': 0.25.4
2549
-
'@esbuild/linux-riscv64': 0.25.4
2550
-
'@esbuild/linux-s390x': 0.25.4
2551
-
'@esbuild/linux-x64': 0.25.4
2552
-
'@esbuild/netbsd-arm64': 0.25.4
2553
-
'@esbuild/netbsd-x64': 0.25.4
2554
-
'@esbuild/openbsd-arm64': 0.25.4
2555
-
'@esbuild/openbsd-x64': 0.25.4
2556
-
'@esbuild/sunos-x64': 0.25.4
2557
-
'@esbuild/win32-arm64': 0.25.4
2558
-
'@esbuild/win32-ia32': 0.25.4
2559
-
'@esbuild/win32-x64': 0.25.4
2446
+
'@esbuild/aix-ppc64': 0.25.12
2447
+
'@esbuild/android-arm': 0.25.12
2448
+
'@esbuild/android-arm64': 0.25.12
2449
+
'@esbuild/android-x64': 0.25.12
2450
+
'@esbuild/darwin-arm64': 0.25.12
2451
+
'@esbuild/darwin-x64': 0.25.12
2452
+
'@esbuild/freebsd-arm64': 0.25.12
2453
+
'@esbuild/freebsd-x64': 0.25.12
2454
+
'@esbuild/linux-arm': 0.25.12
2455
+
'@esbuild/linux-arm64': 0.25.12
2456
+
'@esbuild/linux-ia32': 0.25.12
2457
+
'@esbuild/linux-loong64': 0.25.12
2458
+
'@esbuild/linux-mips64el': 0.25.12
2459
+
'@esbuild/linux-ppc64': 0.25.12
2460
+
'@esbuild/linux-riscv64': 0.25.12
2461
+
'@esbuild/linux-s390x': 0.25.12
2462
+
'@esbuild/linux-x64': 0.25.12
2463
+
'@esbuild/netbsd-arm64': 0.25.12
2464
+
'@esbuild/netbsd-x64': 0.25.12
2465
+
'@esbuild/openbsd-arm64': 0.25.12
2466
+
'@esbuild/openbsd-x64': 0.25.12
2467
+
'@esbuild/openharmony-arm64': 0.25.12
2468
+
'@esbuild/sunos-x64': 0.25.12
2469
+
'@esbuild/win32-arm64': 0.25.12
2470
+
'@esbuild/win32-ia32': 0.25.12
2471
+
'@esbuild/win32-x64': 0.25.12
2560
2472
2561
-
esbuild@0.25.5:
2473
+
esbuild@0.27.0:
2562
2474
optionalDependencies:
2563
-
'@esbuild/aix-ppc64': 0.25.5
2564
-
'@esbuild/android-arm': 0.25.5
2565
-
'@esbuild/android-arm64': 0.25.5
2566
-
'@esbuild/android-x64': 0.25.5
2567
-
'@esbuild/darwin-arm64': 0.25.5
2568
-
'@esbuild/darwin-x64': 0.25.5
2569
-
'@esbuild/freebsd-arm64': 0.25.5
2570
-
'@esbuild/freebsd-x64': 0.25.5
2571
-
'@esbuild/linux-arm': 0.25.5
2572
-
'@esbuild/linux-arm64': 0.25.5
2573
-
'@esbuild/linux-ia32': 0.25.5
2574
-
'@esbuild/linux-loong64': 0.25.5
2575
-
'@esbuild/linux-mips64el': 0.25.5
2576
-
'@esbuild/linux-ppc64': 0.25.5
2577
-
'@esbuild/linux-riscv64': 0.25.5
2578
-
'@esbuild/linux-s390x': 0.25.5
2579
-
'@esbuild/linux-x64': 0.25.5
2580
-
'@esbuild/netbsd-arm64': 0.25.5
2581
-
'@esbuild/netbsd-x64': 0.25.5
2582
-
'@esbuild/openbsd-arm64': 0.25.5
2583
-
'@esbuild/openbsd-x64': 0.25.5
2584
-
'@esbuild/sunos-x64': 0.25.5
2585
-
'@esbuild/win32-arm64': 0.25.5
2586
-
'@esbuild/win32-ia32': 0.25.5
2587
-
'@esbuild/win32-x64': 0.25.5
2475
+
'@esbuild/aix-ppc64': 0.27.0
2476
+
'@esbuild/android-arm': 0.27.0
2477
+
'@esbuild/android-arm64': 0.27.0
2478
+
'@esbuild/android-x64': 0.27.0
2479
+
'@esbuild/darwin-arm64': 0.27.0
2480
+
'@esbuild/darwin-x64': 0.27.0
2481
+
'@esbuild/freebsd-arm64': 0.27.0
2482
+
'@esbuild/freebsd-x64': 0.27.0
2483
+
'@esbuild/linux-arm': 0.27.0
2484
+
'@esbuild/linux-arm64': 0.27.0
2485
+
'@esbuild/linux-ia32': 0.27.0
2486
+
'@esbuild/linux-loong64': 0.27.0
2487
+
'@esbuild/linux-mips64el': 0.27.0
2488
+
'@esbuild/linux-ppc64': 0.27.0
2489
+
'@esbuild/linux-riscv64': 0.27.0
2490
+
'@esbuild/linux-s390x': 0.27.0
2491
+
'@esbuild/linux-x64': 0.27.0
2492
+
'@esbuild/netbsd-arm64': 0.27.0
2493
+
'@esbuild/netbsd-x64': 0.27.0
2494
+
'@esbuild/openbsd-arm64': 0.27.0
2495
+
'@esbuild/openbsd-x64': 0.27.0
2496
+
'@esbuild/openharmony-arm64': 0.27.0
2497
+
'@esbuild/sunos-x64': 0.27.0
2498
+
'@esbuild/win32-arm64': 0.27.0
2499
+
'@esbuild/win32-ia32': 0.27.0
2500
+
'@esbuild/win32-x64': 0.27.0
2588
2501
2589
2502
escalade@3.2.0: {}
2590
2503
2591
2504
esm-env@1.2.2: {}
2592
2505
2593
2506
exit-hook@2.2.1: {}
2594
-
2595
-
exsolve@1.0.5: {}
2596
2507
2597
2508
fast-glob@3.3.3:
2598
2509
dependencies:
···
2606
2517
dependencies:
2607
2518
reusify: 1.1.0
2608
2519
2609
-
fdir@6.4.4(picomatch@4.0.2):
2520
+
fdir@6.5.0(picomatch@4.0.3):
2610
2521
optionalDependencies:
2611
-
picomatch: 4.0.2
2522
+
picomatch: 4.0.3
2612
2523
2613
2524
fetch-blob@3.2.0:
2614
2525
dependencies:
···
2620
2531
dependencies:
2621
2532
to-regex-range: 5.0.1
2622
2533
2623
-
foreground-child@3.3.1:
2624
-
dependencies:
2625
-
cross-spawn: 7.0.6
2626
-
signal-exit: 4.1.0
2627
-
2628
-
fraction.js@4.3.7: {}
2534
+
fraction.js@5.3.4: {}
2629
2535
2630
2536
fsevents@2.3.3:
2631
2537
optional: true
···
2634
2540
2635
2541
gensync@1.0.0-beta.2: {}
2636
2542
2637
-
get-source@2.0.12:
2638
-
dependencies:
2639
-
data-uri-to-buffer: 2.0.2
2640
-
source-map: 0.6.1
2641
-
2642
2543
glob-parent@5.1.2:
2643
2544
dependencies:
2644
2545
is-glob: 4.0.3
···
2649
2550
2650
2551
glob-to-regexp@0.4.1: {}
2651
2552
2652
-
glob@10.4.5:
2653
-
dependencies:
2654
-
foreground-child: 3.3.1
2655
-
jackspeak: 3.4.3
2656
-
minimatch: 9.0.5
2657
-
minipass: 7.1.2
2658
-
package-json-from-dist: 1.0.1
2659
-
path-scurry: 1.11.1
2660
-
2661
-
globals@11.12.0: {}
2662
-
2663
2553
hasown@2.0.2:
2664
2554
dependencies:
2665
2555
function-bind: 1.1.2
2666
2556
2667
2557
html-entities@2.3.3: {}
2668
2558
2669
-
is-arrayish@0.3.2: {}
2559
+
is-arrayish@0.3.4: {}
2670
2560
2671
2561
is-binary-path@2.1.0:
2672
2562
dependencies:
···
2678
2568
2679
2569
is-extglob@2.1.1: {}
2680
2570
2681
-
is-fullwidth-code-point@3.0.0: {}
2682
-
2683
2571
is-glob@4.0.3:
2684
2572
dependencies:
2685
2573
is-extglob: 2.1.1
···
2688
2576
2689
2577
is-what@4.1.16: {}
2690
2578
2691
-
isexe@2.0.0: {}
2692
-
2693
-
jackspeak@3.4.3:
2694
-
dependencies:
2695
-
'@isaacs/cliui': 8.0.2
2696
-
optionalDependencies:
2697
-
'@pkgjs/parseargs': 0.11.0
2698
-
2699
2579
jiti@1.21.7: {}
2700
2580
2701
2581
js-tokens@4.0.0: {}
···
2704
2584
2705
2585
json5@2.2.3: {}
2706
2586
2587
+
kleur@4.1.5: {}
2588
+
2707
2589
lilconfig@3.1.3: {}
2708
2590
2709
2591
lines-and-columns@1.2.4: {}
2710
2592
2711
-
lru-cache@10.4.3: {}
2712
-
2713
2593
lru-cache@5.1.1:
2714
2594
dependencies:
2715
2595
yallist: 3.1.1
···
2729
2609
2730
2610
mini-svg-data-uri@1.4.4: {}
2731
2611
2732
-
miniflare@4.20250508.3:
2612
+
miniflare@4.20251202.1:
2733
2613
dependencies:
2734
2614
'@cspotcode/source-map-support': 0.8.1
2735
2615
acorn: 8.14.0
···
2738
2618
glob-to-regexp: 0.4.1
2739
2619
sharp: 0.33.5
2740
2620
stoppable: 1.1.0
2741
-
undici: 5.29.0
2742
-
workerd: 1.20250508.0
2621
+
undici: 7.14.0
2622
+
workerd: 1.20251202.0
2743
2623
ws: 8.18.0
2744
-
youch: 3.3.4
2624
+
youch: 4.1.0-beta.10
2745
2625
zod: 3.22.3
2746
2626
transitivePeerDependencies:
2747
2627
- bufferutil
2748
2628
- utf-8-validate
2749
2629
2750
-
minimatch@9.0.5:
2751
-
dependencies:
2752
-
brace-expansion: 2.0.1
2753
-
2754
-
minipass@7.1.2: {}
2755
-
2756
2630
ms@2.1.3: {}
2757
-
2758
-
mustache@4.2.0: {}
2759
2631
2760
2632
mz@2.7.0:
2761
2633
dependencies:
···
2765
2637
2766
2638
nanoid@3.3.11: {}
2767
2639
2768
-
nanoid@5.1.5: {}
2640
+
nanoid@5.1.6: {}
2769
2641
2770
2642
native-file-system-adapter@3.0.1:
2771
2643
optionalDependencies:
···
2774
2646
node-domexception@1.0.0:
2775
2647
optional: true
2776
2648
2777
-
node-releases@2.0.19: {}
2649
+
node-releases@2.0.27: {}
2778
2650
2779
2651
normalize-path@3.0.0: {}
2780
2652
···
2783
2655
object-assign@4.1.1: {}
2784
2656
2785
2657
object-hash@3.0.0: {}
2786
-
2787
-
ohash@2.0.11: {}
2788
-
2789
-
package-json-from-dist@1.0.1: {}
2790
2658
2791
2659
parse5@7.3.0:
2792
2660
dependencies:
2793
-
entities: 6.0.0
2794
-
2795
-
path-key@3.1.1: {}
2661
+
entities: 6.0.1
2796
2662
2797
2663
path-parse@1.0.7: {}
2798
2664
2799
-
path-scurry@1.11.1:
2800
-
dependencies:
2801
-
lru-cache: 10.4.3
2802
-
minipass: 7.1.2
2803
-
2804
2665
path-to-regexp@6.3.0: {}
2805
2666
2806
2667
pathe@2.0.3: {}
···
2809
2670
2810
2671
picomatch@2.3.1: {}
2811
2672
2812
-
picomatch@4.0.2: {}
2673
+
picomatch@4.0.3: {}
2813
2674
2814
2675
pify@2.3.0: {}
2815
2676
2816
2677
pirates@4.0.7: {}
2817
2678
2818
-
postcss-import@15.1.0(postcss@8.5.3):
2679
+
postcss-import@15.1.0(postcss@8.5.6):
2819
2680
dependencies:
2820
-
postcss: 8.5.3
2681
+
postcss: 8.5.6
2821
2682
postcss-value-parser: 4.2.0
2822
2683
read-cache: 1.0.0
2823
-
resolve: 1.22.10
2684
+
resolve: 1.22.11
2824
2685
2825
-
postcss-js@4.0.1(postcss@8.5.3):
2686
+
postcss-js@4.1.0(postcss@8.5.6):
2826
2687
dependencies:
2827
2688
camelcase-css: 2.0.1
2828
-
postcss: 8.5.3
2689
+
postcss: 8.5.6
2829
2690
2830
-
postcss-load-config@4.0.2(postcss@8.5.3):
2691
+
postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6):
2831
2692
dependencies:
2832
2693
lilconfig: 3.1.3
2833
-
yaml: 2.8.0
2834
2694
optionalDependencies:
2835
-
postcss: 8.5.3
2695
+
jiti: 1.21.7
2696
+
postcss: 8.5.6
2836
2697
2837
-
postcss-nested@6.2.0(postcss@8.5.3):
2698
+
postcss-nested@6.2.0(postcss@8.5.6):
2838
2699
dependencies:
2839
-
postcss: 8.5.3
2700
+
postcss: 8.5.6
2840
2701
postcss-selector-parser: 6.1.2
2841
2702
2842
2703
postcss-selector-parser@6.1.2:
···
2846
2707
2847
2708
postcss-value-parser@4.2.0: {}
2848
2709
2849
-
postcss@8.5.3:
2710
+
postcss@8.5.6:
2850
2711
dependencies:
2851
2712
nanoid: 3.3.11
2852
2713
picocolors: 1.1.1
2853
2714
source-map-js: 1.2.1
2854
2715
2855
-
prettier-plugin-tailwindcss@0.6.11(prettier@3.5.3):
2716
+
prettier-plugin-tailwindcss@0.6.14(prettier@3.7.4):
2856
2717
dependencies:
2857
-
prettier: 3.5.3
2858
-
2859
-
prettier@3.5.3: {}
2718
+
prettier: 3.7.4
2860
2719
2861
-
printable-characters@1.0.42: {}
2720
+
prettier@3.7.4: {}
2862
2721
2863
2722
queue-microtask@1.2.3: {}
2864
2723
···
2870
2729
dependencies:
2871
2730
picomatch: 2.3.1
2872
2731
2873
-
resolve@1.22.10:
2732
+
resolve@1.22.11:
2874
2733
dependencies:
2875
2734
is-core-module: 2.16.1
2876
2735
path-parse: 1.0.7
···
2878
2737
2879
2738
reusify@1.1.0: {}
2880
2739
2881
-
rollup@4.41.1:
2740
+
rollup@4.53.3:
2882
2741
dependencies:
2883
-
'@types/estree': 1.0.7
2742
+
'@types/estree': 1.0.8
2884
2743
optionalDependencies:
2885
-
'@rollup/rollup-android-arm-eabi': 4.41.1
2886
-
'@rollup/rollup-android-arm64': 4.41.1
2887
-
'@rollup/rollup-darwin-arm64': 4.41.1
2888
-
'@rollup/rollup-darwin-x64': 4.41.1
2889
-
'@rollup/rollup-freebsd-arm64': 4.41.1
2890
-
'@rollup/rollup-freebsd-x64': 4.41.1
2891
-
'@rollup/rollup-linux-arm-gnueabihf': 4.41.1
2892
-
'@rollup/rollup-linux-arm-musleabihf': 4.41.1
2893
-
'@rollup/rollup-linux-arm64-gnu': 4.41.1
2894
-
'@rollup/rollup-linux-arm64-musl': 4.41.1
2895
-
'@rollup/rollup-linux-loongarch64-gnu': 4.41.1
2896
-
'@rollup/rollup-linux-powerpc64le-gnu': 4.41.1
2897
-
'@rollup/rollup-linux-riscv64-gnu': 4.41.1
2898
-
'@rollup/rollup-linux-riscv64-musl': 4.41.1
2899
-
'@rollup/rollup-linux-s390x-gnu': 4.41.1
2900
-
'@rollup/rollup-linux-x64-gnu': 4.41.1
2901
-
'@rollup/rollup-linux-x64-musl': 4.41.1
2902
-
'@rollup/rollup-win32-arm64-msvc': 4.41.1
2903
-
'@rollup/rollup-win32-ia32-msvc': 4.41.1
2904
-
'@rollup/rollup-win32-x64-msvc': 4.41.1
2744
+
'@rollup/rollup-android-arm-eabi': 4.53.3
2745
+
'@rollup/rollup-android-arm64': 4.53.3
2746
+
'@rollup/rollup-darwin-arm64': 4.53.3
2747
+
'@rollup/rollup-darwin-x64': 4.53.3
2748
+
'@rollup/rollup-freebsd-arm64': 4.53.3
2749
+
'@rollup/rollup-freebsd-x64': 4.53.3
2750
+
'@rollup/rollup-linux-arm-gnueabihf': 4.53.3
2751
+
'@rollup/rollup-linux-arm-musleabihf': 4.53.3
2752
+
'@rollup/rollup-linux-arm64-gnu': 4.53.3
2753
+
'@rollup/rollup-linux-arm64-musl': 4.53.3
2754
+
'@rollup/rollup-linux-loong64-gnu': 4.53.3
2755
+
'@rollup/rollup-linux-ppc64-gnu': 4.53.3
2756
+
'@rollup/rollup-linux-riscv64-gnu': 4.53.3
2757
+
'@rollup/rollup-linux-riscv64-musl': 4.53.3
2758
+
'@rollup/rollup-linux-s390x-gnu': 4.53.3
2759
+
'@rollup/rollup-linux-x64-gnu': 4.53.3
2760
+
'@rollup/rollup-linux-x64-musl': 4.53.3
2761
+
'@rollup/rollup-openharmony-arm64': 4.53.3
2762
+
'@rollup/rollup-win32-arm64-msvc': 4.53.3
2763
+
'@rollup/rollup-win32-ia32-msvc': 4.53.3
2764
+
'@rollup/rollup-win32-x64-gnu': 4.53.3
2765
+
'@rollup/rollup-win32-x64-msvc': 4.53.3
2905
2766
fsevents: 2.3.3
2906
2767
2907
2768
run-parallel@1.2.0:
···
2910
2771
2911
2772
semver@6.3.1: {}
2912
2773
2913
-
semver@7.7.2: {}
2774
+
semver@7.7.3: {}
2914
2775
2915
-
seroval-plugins@1.3.2(seroval@1.3.2):
2776
+
seroval-plugins@1.3.3(seroval@1.3.2):
2916
2777
dependencies:
2917
2778
seroval: 1.3.2
2918
2779
···
2921
2782
sharp@0.33.5:
2922
2783
dependencies:
2923
2784
color: 4.2.3
2924
-
detect-libc: 2.0.4
2925
-
semver: 7.7.2
2785
+
detect-libc: 2.1.2
2786
+
semver: 7.7.3
2926
2787
optionalDependencies:
2927
2788
'@img/sharp-darwin-arm64': 0.33.5
2928
2789
'@img/sharp-darwin-x64': 0.33.5
···
2944
2805
'@img/sharp-win32-ia32': 0.33.5
2945
2806
'@img/sharp-win32-x64': 0.33.5
2946
2807
2947
-
shebang-command@2.0.0:
2948
-
dependencies:
2949
-
shebang-regex: 3.0.0
2950
-
2951
-
shebang-regex@3.0.0: {}
2952
-
2953
-
signal-exit@4.1.0: {}
2954
-
2955
-
simple-swizzle@0.2.2:
2808
+
simple-swizzle@0.2.4:
2956
2809
dependencies:
2957
-
is-arrayish: 0.3.2
2810
+
is-arrayish: 0.3.4
2958
2811
2959
-
solid-js@1.9.7:
2812
+
solid-js@1.9.10:
2960
2813
dependencies:
2961
-
csstype: 3.1.3
2814
+
csstype: 3.2.3
2962
2815
seroval: 1.3.2
2963
-
seroval-plugins: 1.3.2(seroval@1.3.2)
2816
+
seroval-plugins: 1.3.3(seroval@1.3.2)
2964
2817
2965
-
solid-refresh@0.6.3(solid-js@1.9.7):
2818
+
solid-refresh@0.6.3(solid-js@1.9.10):
2966
2819
dependencies:
2967
-
'@babel/generator': 7.27.1
2820
+
'@babel/generator': 7.28.5
2968
2821
'@babel/helper-module-imports': 7.27.1
2969
-
'@babel/types': 7.27.1
2970
-
solid-js: 1.9.7
2822
+
'@babel/types': 7.28.5
2823
+
solid-js: 1.9.10
2971
2824
transitivePeerDependencies:
2972
2825
- supports-color
2973
2826
···
2980
2833
2981
2834
source-map@0.6.1: {}
2982
2835
2983
-
stacktracey@2.1.8:
2984
-
dependencies:
2985
-
as-table: 1.0.55
2986
-
get-source: 2.0.12
2987
-
2988
2836
stoppable@1.1.0: {}
2989
2837
2990
-
string-width@4.2.3:
2991
-
dependencies:
2992
-
emoji-regex: 8.0.0
2993
-
is-fullwidth-code-point: 3.0.0
2994
-
strip-ansi: 6.0.1
2995
-
2996
-
string-width@5.1.2:
2997
-
dependencies:
2998
-
eastasianwidth: 0.2.0
2999
-
emoji-regex: 9.2.2
3000
-
strip-ansi: 7.1.0
3001
-
3002
-
strip-ansi@6.0.1:
2838
+
sucrase@3.35.1:
3003
2839
dependencies:
3004
-
ansi-regex: 5.0.1
3005
-
3006
-
strip-ansi@7.1.0:
3007
-
dependencies:
3008
-
ansi-regex: 6.1.0
3009
-
3010
-
sucrase@3.35.0:
3011
-
dependencies:
3012
-
'@jridgewell/gen-mapping': 0.3.8
2840
+
'@jridgewell/gen-mapping': 0.3.13
3013
2841
commander: 4.1.1
3014
-
glob: 10.4.5
3015
2842
lines-and-columns: 1.2.4
3016
2843
mz: 2.7.0
3017
2844
pirates: 4.0.7
2845
+
tinyglobby: 0.2.15
3018
2846
ts-interface-checker: 0.1.13
3019
2847
2848
+
supports-color@10.2.2: {}
2849
+
3020
2850
supports-preserve-symlinks-flag@1.0.0: {}
3021
2851
3022
-
tailwindcss@3.4.17:
2852
+
tailwindcss@3.4.18:
3023
2853
dependencies:
3024
2854
'@alloc/quick-lru': 5.2.0
3025
2855
arg: 5.0.2
···
3035
2865
normalize-path: 3.0.0
3036
2866
object-hash: 3.0.0
3037
2867
picocolors: 1.1.1
3038
-
postcss: 8.5.3
3039
-
postcss-import: 15.1.0(postcss@8.5.3)
3040
-
postcss-js: 4.0.1(postcss@8.5.3)
3041
-
postcss-load-config: 4.0.2(postcss@8.5.3)
3042
-
postcss-nested: 6.2.0(postcss@8.5.3)
2868
+
postcss: 8.5.6
2869
+
postcss-import: 15.1.0(postcss@8.5.6)
2870
+
postcss-js: 4.1.0(postcss@8.5.6)
2871
+
postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)
2872
+
postcss-nested: 6.2.0(postcss@8.5.6)
3043
2873
postcss-selector-parser: 6.1.2
3044
-
resolve: 1.22.10
3045
-
sucrase: 3.35.0
2874
+
resolve: 1.22.11
2875
+
sucrase: 3.35.1
3046
2876
transitivePeerDependencies:
3047
-
- ts-node
2877
+
- tsx
2878
+
- yaml
3048
2879
3049
-
terser@5.39.2:
2880
+
terser@5.44.1:
3050
2881
dependencies:
3051
-
'@jridgewell/source-map': 0.3.6
3052
-
acorn: 8.14.1
2882
+
'@jridgewell/source-map': 0.3.11
2883
+
acorn: 8.15.0
3053
2884
commander: 2.20.3
3054
2885
source-map-support: 0.5.21
3055
2886
···
3061
2892
dependencies:
3062
2893
any-promise: 1.3.0
3063
2894
3064
-
tinyglobby@0.2.14:
2895
+
tinyglobby@0.2.15:
3065
2896
dependencies:
3066
-
fdir: 6.4.4(picomatch@4.0.2)
3067
-
picomatch: 4.0.2
2897
+
fdir: 6.5.0(picomatch@4.0.3)
2898
+
picomatch: 4.0.3
3068
2899
3069
2900
to-regex-range@5.0.1:
3070
2901
dependencies:
···
3075
2906
tslib@2.8.1:
3076
2907
optional: true
3077
2908
3078
-
typescript@5.8.3: {}
3079
-
3080
-
ufo@1.6.1: {}
2909
+
typescript@5.9.3: {}
3081
2910
3082
2911
undici-types@6.21.0: {}
3083
2912
3084
-
undici@5.29.0:
3085
-
dependencies:
3086
-
'@fastify/busboy': 2.1.1
2913
+
undici@7.14.0: {}
3087
2914
3088
-
unenv@2.0.0-rc.17:
2915
+
unenv@2.0.0-rc.24:
3089
2916
dependencies:
3090
-
defu: 6.1.4
3091
-
exsolve: 1.0.5
3092
-
ohash: 2.0.11
3093
2917
pathe: 2.0.3
3094
-
ufo: 1.6.1
3095
2918
3096
-
update-browserslist-db@1.1.3(browserslist@4.24.5):
2919
+
update-browserslist-db@1.2.2(browserslist@4.28.1):
3097
2920
dependencies:
3098
-
browserslist: 4.24.5
2921
+
browserslist: 4.28.1
3099
2922
escalade: 3.2.0
3100
2923
picocolors: 1.1.1
3101
2924
3102
2925
util-deprecate@1.0.2: {}
3103
2926
3104
-
validate-html-nesting@1.2.2: {}
3105
-
3106
-
vite-plugin-solid@2.11.6(solid-js@1.9.7)(vite@6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0)):
2927
+
vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1)):
3107
2928
dependencies:
3108
-
'@babel/core': 7.27.1
2929
+
'@babel/core': 7.28.5
3109
2930
'@types/babel__core': 7.20.5
3110
-
babel-preset-solid: 1.9.6(@babel/core@7.27.1)
2931
+
babel-preset-solid: 1.9.10(@babel/core@7.28.5)(solid-js@1.9.10)
3111
2932
merge-anything: 5.1.7
3112
-
solid-js: 1.9.7
3113
-
solid-refresh: 0.6.3(solid-js@1.9.7)
3114
-
vite: 6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0)
3115
-
vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0))
2933
+
solid-js: 1.9.10
2934
+
solid-refresh: 0.6.3(solid-js@1.9.10)
2935
+
vite: 7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1)
2936
+
vitefu: 1.1.1(vite@7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1))
3116
2937
transitivePeerDependencies:
3117
2938
- supports-color
3118
2939
3119
-
vite@6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0):
2940
+
vite@7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1):
3120
2941
dependencies:
3121
-
esbuild: 0.25.5
3122
-
fdir: 6.4.4(picomatch@4.0.2)
3123
-
picomatch: 4.0.2
3124
-
postcss: 8.5.3
3125
-
rollup: 4.41.1
3126
-
tinyglobby: 0.2.14
2942
+
esbuild: 0.25.12
2943
+
fdir: 6.5.0(picomatch@4.0.3)
2944
+
picomatch: 4.0.3
2945
+
postcss: 8.5.6
2946
+
rollup: 4.53.3
2947
+
tinyglobby: 0.2.15
3127
2948
optionalDependencies:
3128
-
'@types/node': 22.15.21
2949
+
'@types/node': 22.19.2
3129
2950
fsevents: 2.3.3
3130
2951
jiti: 1.21.7
3131
-
terser: 5.39.2
3132
-
yaml: 2.8.0
2952
+
terser: 5.44.1
3133
2953
3134
-
vitefu@1.0.6(vite@6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0)):
2954
+
vitefu@1.1.1(vite@7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1)):
3135
2955
optionalDependencies:
3136
-
vite: 6.3.5(@types/node@22.15.21)(jiti@1.21.7)(terser@5.39.2)(yaml@2.8.0)
2956
+
vite: 7.2.7(@types/node@22.19.2)(jiti@1.21.7)(terser@5.44.1)
3137
2957
3138
2958
web-streams-polyfill@3.3.3:
3139
2959
optional: true
3140
2960
3141
-
which@2.0.2:
3142
-
dependencies:
3143
-
isexe: 2.0.0
3144
-
3145
-
workerd@1.20250508.0:
2961
+
workerd@1.20251202.0:
3146
2962
optionalDependencies:
3147
-
'@cloudflare/workerd-darwin-64': 1.20250508.0
3148
-
'@cloudflare/workerd-darwin-arm64': 1.20250508.0
3149
-
'@cloudflare/workerd-linux-64': 1.20250508.0
3150
-
'@cloudflare/workerd-linux-arm64': 1.20250508.0
3151
-
'@cloudflare/workerd-windows-64': 1.20250508.0
2963
+
'@cloudflare/workerd-darwin-64': 1.20251202.0
2964
+
'@cloudflare/workerd-darwin-arm64': 1.20251202.0
2965
+
'@cloudflare/workerd-linux-64': 1.20251202.0
2966
+
'@cloudflare/workerd-linux-arm64': 1.20251202.0
2967
+
'@cloudflare/workerd-windows-64': 1.20251202.0
3152
2968
3153
-
wrangler@4.16.1:
2969
+
wrangler@4.53.0:
3154
2970
dependencies:
3155
-
'@cloudflare/kv-asset-handler': 0.4.0
3156
-
'@cloudflare/unenv-preset': 2.3.2(unenv@2.0.0-rc.17)(workerd@1.20250508.0)
2971
+
'@cloudflare/kv-asset-handler': 0.4.1
2972
+
'@cloudflare/unenv-preset': 2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251202.0)
3157
2973
blake3-wasm: 2.1.5
3158
-
esbuild: 0.25.4
3159
-
miniflare: 4.20250508.3
2974
+
esbuild: 0.27.0
2975
+
miniflare: 4.20251202.1
3160
2976
path-to-regexp: 6.3.0
3161
-
unenv: 2.0.0-rc.17
3162
-
workerd: 1.20250508.0
2977
+
unenv: 2.0.0-rc.24
2978
+
workerd: 1.20251202.0
3163
2979
optionalDependencies:
3164
2980
fsevents: 2.3.3
3165
-
sharp: 0.33.5
3166
2981
transitivePeerDependencies:
3167
2982
- bufferutil
3168
2983
- utf-8-validate
3169
2984
3170
-
wrap-ansi@7.0.0:
3171
-
dependencies:
3172
-
ansi-styles: 4.3.0
3173
-
string-width: 4.2.3
3174
-
strip-ansi: 6.0.1
3175
-
3176
-
wrap-ansi@8.1.0:
3177
-
dependencies:
3178
-
ansi-styles: 6.2.1
3179
-
string-width: 5.1.2
3180
-
strip-ansi: 7.1.0
3181
-
3182
2985
ws@8.18.0: {}
3183
2986
3184
2987
yallist@3.1.1: {}
3185
2988
3186
-
yaml@2.8.0: {}
3187
-
3188
-
yocto-queue@1.2.1: {}
2989
+
youch-core@0.3.3:
2990
+
dependencies:
2991
+
'@poppinss/exception': 1.2.2
2992
+
error-stack-parser-es: 1.0.5
3189
2993
3190
-
youch@3.3.4:
2994
+
youch@4.1.0-beta.10:
3191
2995
dependencies:
3192
-
cookie: 0.7.2
3193
-
mustache: 4.2.0
3194
-
stacktracey: 2.1.8
2996
+
'@poppinss/colors': 4.1.5
2997
+
'@poppinss/dumper': 0.6.5
2998
+
'@speed-highlight/core': 1.2.12
2999
+
cookie: 1.1.1
3000
+
youch-core: 0.3.3
3195
3001
3196
3002
zod@3.22.3: {}
+1
-1
src/api/queries/plc.ts
+1
-1
src/api/queries/plc.ts
···
1
1
import { defs } from '@atcute/did-plc';
2
-
import { Did } from '@atcute/lexicons/syntax';
2
+
import type { Did } from '@atcute/lexicons/syntax';
3
3
4
4
export const getPlcAuditLogs = async ({ did, signal }: { did: Did<'plc'>; signal?: AbortSignal }) => {
5
5
const origin = import.meta.env.VITE_PLC_DIRECTORY_URL;
+2
-2
src/api/types/plc.ts
+2
-2
src/api/types/plc.ts
···
1
1
import * as v from '@badrap/valita';
2
2
3
-
import { defs, UnsignedOperation } from '@atcute/did-plc';
3
+
import { defs, type UnsignedOperation } from '@atcute/did-plc';
4
4
5
-
import { ToValidator } from '../utils/valita';
5
+
import type { ToValidator } from '../utils/valita';
6
6
import { serviceUrlString } from './strings';
7
7
8
8
const _unsignedOperation = defs.unsignedOperation as ToValidator<UnsignedOperation>;
+72
src/components/accordion.tsx
+72
src/components/accordion.tsx
···
1
+
import { createSignal, type JSX, Show } from 'solid-js';
2
+
3
+
import ChevronRightIcon from '~/components/ic-icons/baseline-chevron-right';
4
+
5
+
export interface AccordionProps {
6
+
title: string;
7
+
children: JSX.Element;
8
+
defaultOpen?: boolean;
9
+
}
10
+
11
+
export const Accordion = (props: AccordionProps) => {
12
+
const [isOpen, setIsOpen] = createSignal(props.defaultOpen ?? false);
13
+
14
+
return (
15
+
<div class="border-b border-gray-200">
16
+
<button
17
+
type="button"
18
+
onClick={() => setIsOpen(!isOpen())}
19
+
class="flex w-full items-center gap-3 px-4 py-3 text-left hover:bg-gray-50"
20
+
>
21
+
<ChevronRightIcon
22
+
class={`h-5 w-5 text-gray-500 transition-transform` + (isOpen() ? ` rotate-90` : ``)}
23
+
/>
24
+
<span class="font-semibold">{props.title}</span>
25
+
</button>
26
+
27
+
<Show when={isOpen()}>
28
+
<div class="pb-4 pl-12 pr-4">{props.children}</div>
29
+
</Show>
30
+
</div>
31
+
);
32
+
};
33
+
34
+
export interface SubsectionProps {
35
+
title: string;
36
+
children: JSX.Element;
37
+
}
38
+
39
+
export const Subsection = (props: SubsectionProps) => {
40
+
return (
41
+
<div class="mb-4 last:mb-0">
42
+
<h4 class="mb-3 text-sm font-semibold text-gray-600">{props.title}</h4>
43
+
<div class="flex flex-col gap-3">{props.children}</div>
44
+
</div>
45
+
);
46
+
};
47
+
48
+
export interface StatusBadgeProps {
49
+
variant: 'idle' | 'pending' | 'success' | 'error';
50
+
children: JSX.Element;
51
+
}
52
+
53
+
export const StatusBadge = (props: StatusBadgeProps) => {
54
+
const variantStyles = () => {
55
+
switch (props.variant) {
56
+
case 'idle':
57
+
return 'bg-gray-100 text-gray-600';
58
+
case 'pending':
59
+
return 'bg-yellow-100 text-yellow-800';
60
+
case 'success':
61
+
return 'bg-green-100 text-green-800';
62
+
case 'error':
63
+
return 'bg-red-100 text-red-800';
64
+
}
65
+
};
66
+
67
+
return (
68
+
<span class={`inline-flex items-center rounded px-2 py-0.5 text-xs font-medium ${variantStyles()}`}>
69
+
{props.children}
70
+
</span>
71
+
);
72
+
};
+65
src/components/file-drop-zone.tsx
+65
src/components/file-drop-zone.tsx
···
1
+
import type { JSX } from 'solid-js';
2
+
3
+
import { createDropZone, type CreateDropZoneOptions } from '~/lib/hooks/dropzone';
4
+
5
+
import Button from './inputs/button';
6
+
7
+
interface FileDropZoneProps {
8
+
accept?: string;
9
+
disabled?: boolean;
10
+
onFiles: (files: File[]) => void;
11
+
dataTypes?: CreateDropZoneOptions['dataTypes'];
12
+
multiple?: boolean;
13
+
children?: JSX.Element;
14
+
}
15
+
16
+
const FileDropZone = (props: FileDropZoneProps) => {
17
+
const { ref: dropRef, isDropping } = createDropZone({
18
+
dataTypes: props.dataTypes,
19
+
multiple: props.multiple ?? false,
20
+
onDrop(files) {
21
+
if (files) {
22
+
props.onFiles(files);
23
+
}
24
+
},
25
+
});
26
+
27
+
const handleBrowse = () => {
28
+
const input = document.createElement('input');
29
+
input.type = 'file';
30
+
if (props.accept) {
31
+
input.accept = props.accept;
32
+
}
33
+
if (props.multiple) {
34
+
input.multiple = true;
35
+
}
36
+
input.oninput = () => {
37
+
const files = Array.from(input.files!);
38
+
if (files.length > 0) {
39
+
props.onFiles(files);
40
+
}
41
+
};
42
+
input.click();
43
+
};
44
+
45
+
return (
46
+
<fieldset
47
+
ref={dropRef}
48
+
disabled={props.disabled}
49
+
class={
50
+
`relative grid place-items-center rounded border border-gray-300 px-6 py-12 disabled:opacity-50` +
51
+
(props.disabled || !isDropping() ? ` bg-gray-100` : ` bg-green-100`)
52
+
}
53
+
>
54
+
<div class="flex flex-col items-center gap-4">
55
+
<Button variant="outline" onClick={handleBrowse}>
56
+
Browse files
57
+
</Button>
58
+
<p class="select-none font-medium text-gray-600">or drop your file here</p>
59
+
</div>
60
+
{props.children}
61
+
</fieldset>
62
+
);
63
+
};
64
+
65
+
export default FileDropZone;
+2
-2
src/components/inputs/multiline-input.tsx
+2
-2
src/components/inputs/multiline-input.tsx
···
1
-
import { createEffect, JSX } from 'solid-js';
1
+
import { createEffect, type JSX } from 'solid-js';
2
2
3
3
import { createId } from '~/lib/hooks/id';
4
4
5
-
import { BoundInputEvent } from './_types';
5
+
import type { BoundInputEvent } from './_types';
6
6
7
7
interface MultilineInputProps {
8
8
label: JSX.Element;
+2
-2
src/components/inputs/radio-input.tsx
+2
-2
src/components/inputs/radio-input.tsx
···
1
-
import { JSX } from 'solid-js';
1
+
import type { JSX } from 'solid-js';
2
2
3
3
import { createId } from '~/lib/hooks/id';
4
4
5
-
import { BoundInputEvent } from './_types';
5
+
import type { BoundInputEvent } from './_types';
6
6
7
7
interface RadioInputProps<T extends string> {
8
8
label: JSX.Element;
+2
-2
src/components/inputs/select-input.tsx
+2
-2
src/components/inputs/select-input.tsx
···
1
-
import { createEffect, JSX } from 'solid-js';
1
+
import { createEffect, type JSX } from 'solid-js';
2
2
3
3
import { createId } from '~/lib/hooks/id';
4
4
5
-
import { BoundInputEvent } from './_types';
5
+
import type { BoundInputEvent } from './_types';
6
6
7
7
interface SelectInputProps<T extends string> {
8
8
label: JSX.Element;
+5
-3
src/components/inputs/text-input.tsx
+5
-3
src/components/inputs/text-input.tsx
···
1
-
import { createEffect, JSX } from 'solid-js';
1
+
import { createEffect, type JSX } from 'solid-js';
2
2
3
3
import { createId } from '~/lib/hooks/id';
4
4
5
-
import { BoundInputEvent } from './_types';
5
+
import type { BoundInputEvent } from './_types';
6
6
7
-
interface TextInputProps {
7
+
export interface TextInputProps {
8
8
label: JSX.Element;
9
9
blurb?: JSX.Element;
10
10
monospace?: boolean;
11
11
type?: 'text' | 'password' | 'url' | 'email';
12
12
name?: string;
13
13
required?: boolean;
14
+
disabled?: boolean;
14
15
autocomplete?: 'off' | 'on' | 'one-time-code' | 'username';
15
16
autocorrect?: 'off' | 'on';
16
17
pattern?: string;
···
55
56
id={fieldId}
56
57
name={props.name}
57
58
required={props.required}
59
+
disabled={props.disabled}
58
60
autocomplete={props.autocomplete}
59
61
pattern={props.pattern}
60
62
placeholder={props.placeholder}
+1
-1
src/components/inputs/toggle-input.tsx
+1
-1
src/components/inputs/toggle-input.tsx
+22
src/components/page-header.tsx
+22
src/components/page-header.tsx
···
1
+
import type { JSX } from 'solid-js';
2
+
3
+
interface PageHeaderProps {
4
+
title: string;
5
+
subtitle?: string;
6
+
children?: JSX.Element;
7
+
}
8
+
9
+
const PageHeader = (props: PageHeaderProps) => {
10
+
return (
11
+
<>
12
+
<div class="p-4">
13
+
<h1 class="text-lg font-bold text-purple-800">{props.title}</h1>
14
+
{props.subtitle && <p class="text-gray-600">{props.subtitle}</p>}
15
+
{props.children}
16
+
</div>
17
+
<hr class="mx-4 border-gray-300" />
18
+
</>
19
+
);
20
+
};
21
+
22
+
export default PageHeader;
+1
-1
src/components/wizard.tsx
+1
-1
src/components/wizard.tsx
+104
-4
src/lib/utils/confirmation-code.ts
+104
-4
src/lib/utils/confirmation-code.ts
···
1
-
import { customAlphabet } from 'nanoid';
1
+
import { sample } from '@mary/array-fns';
2
2
3
-
const generateCode = customAlphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', 10);
3
+
const words = [
4
+
'abroad',
5
+
'acorn',
6
+
'anaconda',
7
+
'anchovy',
8
+
'aorta',
9
+
'argue',
10
+
'ashy',
11
+
'astound',
12
+
'attest',
13
+
'babied',
14
+
'bobcat',
15
+
'bondless',
16
+
'bullion',
17
+
'bunny',
18
+
'celtic',
19
+
'chivalry',
20
+
'circling',
21
+
'civic',
22
+
'clobber',
23
+
'conform',
24
+
'cosmic',
25
+
'crier',
26
+
'curtly',
27
+
'depose',
28
+
'diagnosis',
29
+
'disfigure',
30
+
'drank',
31
+
'ducktail',
32
+
'eel',
33
+
'effort',
34
+
'equipment',
35
+
'eternal',
36
+
'exemplify',
37
+
'filtrate',
38
+
'fit',
39
+
'flaccid',
40
+
'fool',
41
+
'germinate',
42
+
'glade',
43
+
'graveness',
44
+
'gray',
45
+
'hydrant',
46
+
'italicize',
47
+
'landowner',
48
+
'lavender',
49
+
'mandatory',
50
+
'molecule',
51
+
'multitude',
52
+
'music',
53
+
'national',
54
+
'neatly',
55
+
'omnivore',
56
+
'other',
57
+
'overdrive',
58
+
'overhang',
59
+
'overlying',
60
+
'padded',
61
+
'pang',
62
+
'paralyses',
63
+
'partner',
64
+
'pedometer',
65
+
'plaything',
66
+
'pointy',
67
+
'prescribe',
68
+
'pueblo',
69
+
'pursuant',
70
+
'reprise',
71
+
'resilient',
72
+
'reusable',
73
+
'roster',
74
+
'scenic',
75
+
'selected',
76
+
'singer',
77
+
'slacker',
78
+
'smirk',
79
+
'smoked',
80
+
'smugly',
81
+
'startle',
82
+
'sternum',
83
+
'strut',
84
+
'subsystem',
85
+
'supper',
86
+
'swifter',
87
+
'tacking',
88
+
'traffic',
89
+
'tragedy',
90
+
'trapper',
91
+
'tummy',
92
+
'twiddle',
93
+
'unglazed',
94
+
'ungloved',
95
+
'unicorn',
96
+
'unissued',
97
+
'unmovable',
98
+
'unwary',
99
+
'uselessly',
100
+
'venus',
101
+
'vertebrae',
102
+
'wildly',
103
+
'wrecker',
104
+
];
4
105
5
106
export const generateConfirmationCode = () => {
6
-
const code = generateCode();
7
-
return `${code.slice(0, 5)}-${code.slice(5, 10)}`;
107
+
return sample(words, 3).join(' ');
8
108
};
+1
-1
src/lib/utils/search-params.ts
+1
-1
src/lib/utils/search-params.ts
+17
src/lib/utils/stream.ts
+17
src/lib/utils/stream.ts
···
1
+
export async function* iterateStream<T>(stream: ReadableStream<T>) {
2
+
const reader = stream.getReader();
3
+
4
+
try {
5
+
while (true) {
6
+
const { done, value } = await reader.read();
7
+
8
+
if (done) {
9
+
return;
10
+
}
11
+
12
+
yield value;
13
+
}
14
+
} finally {
15
+
reader.releaseLock();
16
+
}
17
+
}
+9
src/routes.ts
+9
src/routes.ts
···
22
22
path: '/crypto-generate',
23
23
component: lazy(() => import('./views/crypto/crypto-generate')),
24
24
},
25
+
{
26
+
path: '/crypto-info',
27
+
component: lazy(() => import('./views/crypto/crypto-info')),
28
+
},
25
29
26
30
{
27
31
path: '/did-lookup',
···
47
51
{
48
52
path: '/repo-archive-explore',
49
53
component: lazy(() => import('./views/repository/repo-archive-explore/page')),
54
+
},
55
+
56
+
{
57
+
path: '/account-migrate',
58
+
component: lazy(() => import('./views/account/account-migrate/page')),
50
59
},
51
60
52
61
{
+49
src/views/account/account-migrate/context.tsx
+49
src/views/account/account-migrate/context.tsx
···
1
+
import { createContext, createSignal, useContext, type JSX } from 'solid-js';
2
+
3
+
import type { CredentialManager } from '@atcute/client';
4
+
import type { DidDocument } from '@atcute/identity';
5
+
import type { AtprotoDid, Did } from '@atcute/lexicons/syntax';
6
+
7
+
export interface SourceAccount {
8
+
did: AtprotoDid;
9
+
didDoc: DidDocument;
10
+
pdsUrl: string;
11
+
manager: CredentialManager | null;
12
+
}
13
+
14
+
export interface DestinationAccount {
15
+
pdsUrl: string;
16
+
serviceDid: Did;
17
+
manager: CredentialManager | null;
18
+
}
19
+
20
+
export interface MigrationContextValue {
21
+
source: () => SourceAccount | null;
22
+
setSource: (account: SourceAccount | null) => void;
23
+
destination: () => DestinationAccount | null;
24
+
setDestination: (account: DestinationAccount | null) => void;
25
+
}
26
+
27
+
const MigrationContext = createContext<MigrationContextValue>();
28
+
29
+
export const MigrationProvider = (props: { children: JSX.Element }) => {
30
+
const [source, setSource] = createSignal<SourceAccount | null>(null);
31
+
const [destination, setDestination] = createSignal<DestinationAccount | null>(null);
32
+
33
+
const value: MigrationContextValue = {
34
+
source,
35
+
setSource,
36
+
destination,
37
+
setDestination,
38
+
};
39
+
40
+
return <MigrationContext.Provider value={value}>{props.children}</MigrationContext.Provider>;
41
+
};
42
+
43
+
export const useMigration = (): MigrationContextValue => {
44
+
const context = useContext(MigrationContext);
45
+
if (!context) {
46
+
throw new Error('useMigration must be used within a MigrationProvider');
47
+
}
48
+
return context;
49
+
};
+54
src/views/account/account-migrate/page.tsx
+54
src/views/account/account-migrate/page.tsx
···
1
+
import { createEffect, createSignal, onCleanup } from 'solid-js';
2
+
3
+
import { history } from '~/globals/navigation';
4
+
5
+
import { useTitle } from '~/lib/navigation/router';
6
+
7
+
import PageHeader from '~/components/page-header';
8
+
9
+
import { MigrationProvider } from './context';
10
+
11
+
import SourceAccountSection from './sections/source-account';
12
+
import DestinationAccountSection from './sections/destination-account';
13
+
import RepositorySection from './sections/repository';
14
+
import BlobsSection from './sections/blobs';
15
+
import PreferencesSection from './sections/preferences';
16
+
import IdentitySection from './sections/identity';
17
+
import AccountStatusSection from './sections/account-status';
18
+
19
+
const AccountMigratePage = () => {
20
+
const [hasStarted, setHasStarted] = createSignal(false);
21
+
22
+
createEffect(() => {
23
+
if (hasStarted()) {
24
+
const cleanup = history.block((tx) => {
25
+
if (window.confirm(`You have a migration in progress. Leave this page?`)) {
26
+
cleanup();
27
+
tx.retry();
28
+
}
29
+
});
30
+
31
+
onCleanup(cleanup);
32
+
}
33
+
});
34
+
35
+
useTitle(() => `Migrate account โ boat`);
36
+
37
+
return (
38
+
<MigrationProvider>
39
+
<PageHeader title="Migrate account" subtitle="Move your account data to another server" />
40
+
41
+
<div class="flex flex-col">
42
+
<SourceAccountSection onStarted={() => setHasStarted(true)} />
43
+
<DestinationAccountSection />
44
+
<RepositorySection />
45
+
<BlobsSection />
46
+
<PreferencesSection />
47
+
<IdentitySection />
48
+
<AccountStatusSection />
49
+
</div>
50
+
</MigrationProvider>
51
+
);
52
+
};
53
+
54
+
export default AccountMigratePage;
+207
src/views/account/account-migrate/sections/account-status.tsx
+207
src/views/account/account-migrate/sections/account-status.tsx
···
1
+
import { Show } from 'solid-js';
2
+
3
+
import { Client, type CredentialManager, ok } from '@atcute/client';
4
+
5
+
import { createMutation } from '~/lib/utils/mutation';
6
+
7
+
import { Accordion, StatusBadge, Subsection } from '~/components/accordion';
8
+
import Button from '~/components/inputs/button';
9
+
10
+
import { useMigration } from '../context';
11
+
12
+
interface AccountStatus {
13
+
activated: boolean;
14
+
validDid: boolean;
15
+
repoCommit: string;
16
+
repoRev: string;
17
+
repoBlocks: number;
18
+
indexedRecords: number;
19
+
privateStateValues: number;
20
+
expectedBlobs: number;
21
+
importedBlobs: number;
22
+
}
23
+
24
+
const AccountStatusSection = () => {
25
+
const { source, destination } = useMigration();
26
+
27
+
const checkSourceMutation = createMutation({
28
+
async mutationFn({ manager }: { manager: CredentialManager }) {
29
+
const sourceClient = new Client({ handler: manager });
30
+
return await ok(sourceClient.get('com.atproto.server.checkAccountStatus')) as AccountStatus;
31
+
},
32
+
onError(err) {
33
+
console.error(err);
34
+
},
35
+
});
36
+
37
+
const checkDestMutation = createMutation({
38
+
async mutationFn({ manager }: { manager: CredentialManager }) {
39
+
const destClient = new Client({ handler: manager });
40
+
return await ok(destClient.get('com.atproto.server.checkAccountStatus')) as AccountStatus;
41
+
},
42
+
onError(err) {
43
+
console.error(err);
44
+
},
45
+
});
46
+
47
+
const activateMutation = createMutation({
48
+
async mutationFn({ manager }: { manager: CredentialManager }) {
49
+
const destClient = new Client({ handler: manager });
50
+
await ok(destClient.post('com.atproto.server.activateAccount', { as: null }));
51
+
},
52
+
onSuccess() {
53
+
const dest = destination();
54
+
if (dest?.manager) {
55
+
checkDestMutation.mutate({ manager: dest.manager });
56
+
}
57
+
},
58
+
onError(err) {
59
+
console.error(err);
60
+
},
61
+
});
62
+
63
+
const deactivateMutation = createMutation({
64
+
async mutationFn({ manager }: { manager: CredentialManager }) {
65
+
if (!confirm('Are you sure you want to deactivate your source account? This will prevent the old PDS from serving your data.')) {
66
+
throw new Error('Cancelled');
67
+
}
68
+
const sourceClient = new Client({ handler: manager });
69
+
await ok(sourceClient.post('com.atproto.server.deactivateAccount', { as: null, input: {} }));
70
+
},
71
+
onSuccess() {
72
+
const src = source();
73
+
if (src?.manager) {
74
+
checkSourceMutation.mutate({ manager: src.manager });
75
+
}
76
+
},
77
+
onError(err) {
78
+
if (err instanceof Error && err.message === 'Cancelled') return;
79
+
console.error(err);
80
+
},
81
+
});
82
+
83
+
const renderStatus = (status: AccountStatus) => (
84
+
<div class="space-y-1 text-sm">
85
+
<p>
86
+
<span class="text-gray-500">Status:</span>{' '}
87
+
<StatusBadge variant={status.activated ? 'success' : 'idle'}>
88
+
{status.activated ? 'Active' : 'Deactivated'}
89
+
</StatusBadge>
90
+
</p>
91
+
<p>
92
+
<span class="text-gray-500">Records:</span>{' '}
93
+
<span class="font-mono">{status.indexedRecords}</span>
94
+
</p>
95
+
<p>
96
+
<span class="text-gray-500">Blobs:</span>{' '}
97
+
<span class="font-mono">{status.importedBlobs}/{status.expectedBlobs}</span>
98
+
</p>
99
+
<p>
100
+
<span class="text-gray-500">Repo blocks:</span>{' '}
101
+
<span class="font-mono">{status.repoBlocks}</span>
102
+
</p>
103
+
</div>
104
+
);
105
+
106
+
return (
107
+
<Accordion title="Account Status">
108
+
<Subsection title="Source account">
109
+
<Show
110
+
when={source()?.manager}
111
+
fallback={<p class="text-sm text-gray-500">Sign in to source account first.</p>}
112
+
>
113
+
{(manager) => (
114
+
<>
115
+
<div class="flex items-center gap-3">
116
+
<Button
117
+
variant="outline"
118
+
onClick={() => checkSourceMutation.mutate({ manager: manager() })}
119
+
disabled={checkSourceMutation.isPending}
120
+
>
121
+
{checkSourceMutation.isPending ? 'Checking...' : 'Check status'}
122
+
</Button>
123
+
</div>
124
+
125
+
<Show when={checkSourceMutation.isError}>
126
+
<p class="text-sm text-red-600">{`${checkSourceMutation.error}`}</p>
127
+
</Show>
128
+
129
+
<Show when={checkSourceMutation.data}>
130
+
{(status) => (
131
+
<>
132
+
{renderStatus(status())}
133
+
134
+
<Show when={status().activated}>
135
+
<div class="mt-3">
136
+
<Button
137
+
variant="secondary"
138
+
onClick={() => deactivateMutation.mutate({ manager: manager() })}
139
+
disabled={deactivateMutation.isPending}
140
+
>
141
+
{deactivateMutation.isPending ? 'Deactivating...' : 'Deactivate source account'}
142
+
</Button>
143
+
</div>
144
+
</Show>
145
+
</>
146
+
)}
147
+
</Show>
148
+
</>
149
+
)}
150
+
</Show>
151
+
</Subsection>
152
+
153
+
<Subsection title="Destination account">
154
+
<Show
155
+
when={destination()?.manager}
156
+
fallback={<p class="text-sm text-gray-500">Sign in to destination account first.</p>}
157
+
>
158
+
{(manager) => (
159
+
<>
160
+
<div class="flex items-center gap-3">
161
+
<Button
162
+
variant="outline"
163
+
onClick={() => checkDestMutation.mutate({ manager: manager() })}
164
+
disabled={checkDestMutation.isPending}
165
+
>
166
+
{checkDestMutation.isPending ? 'Checking...' : 'Check status'}
167
+
</Button>
168
+
</div>
169
+
170
+
<Show when={checkDestMutation.isError}>
171
+
<p class="text-sm text-red-600">{`${checkDestMutation.error}`}</p>
172
+
</Show>
173
+
174
+
<Show when={checkDestMutation.data}>
175
+
{(status) => (
176
+
<>
177
+
{renderStatus(status())}
178
+
179
+
<Show when={!status().activated}>
180
+
<div class="mt-3">
181
+
<Button
182
+
onClick={() => activateMutation.mutate({ manager: manager() })}
183
+
disabled={activateMutation.isPending}
184
+
>
185
+
{activateMutation.isPending ? 'Activating...' : 'Activate destination account'}
186
+
</Button>
187
+
</div>
188
+
</Show>
189
+
</>
190
+
)}
191
+
</Show>
192
+
</>
193
+
)}
194
+
</Show>
195
+
</Subsection>
196
+
197
+
<Show when={activateMutation.isError || deactivateMutation.isError}>
198
+
<p class="text-sm text-red-600">
199
+
{activateMutation.isError ? `Failed to activate: ${activateMutation.error}` : ''}
200
+
{deactivateMutation.isError ? `Failed to deactivate: ${deactivateMutation.error}` : ''}
201
+
</p>
202
+
</Show>
203
+
</Accordion>
204
+
);
205
+
};
206
+
207
+
export default AccountStatusSection;
+455
src/views/account/account-migrate/sections/blobs.tsx
+455
src/views/account/account-migrate/sections/blobs.tsx
···
1
+
import { showOpenFilePicker, showSaveFilePicker } from 'native-file-system-adapter';
2
+
import { createSignal, For, Show } from 'solid-js';
3
+
4
+
import { Client, ClientResponseError, type CredentialManager, ok, simpleFetchHandler } from '@atcute/client';
5
+
import { untar, writeTarEntry } from '@mary/tar';
6
+
7
+
import { createMutation } from '~/lib/utils/mutation';
8
+
9
+
import { Accordion, StatusBadge, Subsection } from '~/components/accordion';
10
+
import Button from '~/components/inputs/button';
11
+
12
+
import { useMigration, type SourceAccount } from '../context';
13
+
14
+
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
15
+
16
+
const BlobsSection = () => {
17
+
const { source, destination } = useMigration();
18
+
19
+
// Progress state (kept separate since mutations don't handle incremental updates)
20
+
const [exportProgress, setExportProgress] = createSignal<string>();
21
+
const [importProgress, setImportProgress] = createSignal<string>();
22
+
23
+
const exportMutation = createMutation({
24
+
async mutationFn({ source }: { source: SourceAccount }) {
25
+
const sourceClient = new Client({ handler: simpleFetchHandler({ service: source.pdsUrl }) });
26
+
27
+
setExportProgress('Retrieving list of blobs...');
28
+
29
+
// Get list of all blobs
30
+
let blobs: string[] = [];
31
+
let cursor: string | undefined;
32
+
do {
33
+
const data = await ok(
34
+
sourceClient.get('com.atproto.sync.listBlobs', {
35
+
params: { did: source.did, cursor, limit: 1_000 },
36
+
}),
37
+
);
38
+
cursor = data.cursor;
39
+
blobs = blobs.concat(data.cids);
40
+
setExportProgress(`Retrieving list of blobs (found ${blobs.length})`);
41
+
} while (cursor !== undefined);
42
+
43
+
if (blobs.length === 0) {
44
+
return { count: 0, cancelled: false };
45
+
}
46
+
47
+
setExportProgress('Waiting for file picker...');
48
+
49
+
const fd = await showSaveFilePicker({
50
+
suggestedName: `blobs-${source.did}-${new Date().toISOString()}.tar`,
51
+
// @ts-expect-error: ponyfill doesn't have the full typings
52
+
id: 'blob-export',
53
+
startIn: 'downloads',
54
+
types: [
55
+
{
56
+
description: 'Tarball archive',
57
+
accept: { 'application/tar': ['.tar'] },
58
+
},
59
+
],
60
+
}).catch((err) => {
61
+
if (err instanceof DOMException && err.name === 'AbortError') {
62
+
return undefined;
63
+
}
64
+
throw err;
65
+
});
66
+
67
+
if (!fd) {
68
+
return { count: 0, cancelled: true };
69
+
}
70
+
71
+
const writable = await fd.createWritable();
72
+
73
+
let downloaded = 0;
74
+
for (const cid of blobs) {
75
+
setExportProgress(`Downloading blobs (${downloaded}/${blobs.length})`);
76
+
77
+
const downloadBlob = async (): Promise<Uint8Array | undefined> => {
78
+
let attempts = 0;
79
+
while (true) {
80
+
if (attempts > 0) await sleep(2_000);
81
+
attempts++;
82
+
83
+
try {
84
+
const response = await sourceClient.get('com.atproto.sync.getBlob', {
85
+
as: 'bytes',
86
+
params: { did: source.did, cid },
87
+
});
88
+
89
+
if (response.ok) {
90
+
return response.data;
91
+
}
92
+
93
+
if (response.status === 400 && response.data.message === 'Blob not found') {
94
+
return undefined;
95
+
}
96
+
97
+
if (response.status === 429) {
98
+
await sleep(10_000);
99
+
}
100
+
101
+
if (attempts < 3) continue;
102
+
throw new ClientResponseError(response);
103
+
} catch (err) {
104
+
if (attempts < 3) continue;
105
+
throw err;
106
+
}
107
+
}
108
+
};
109
+
110
+
const data = await downloadBlob();
111
+
if (data !== undefined) {
112
+
const entry = writeTarEntry({ filename: `blobs/${cid}`, data });
113
+
await writable.write(entry);
114
+
}
115
+
116
+
downloaded++;
117
+
}
118
+
119
+
await writable.close();
120
+
return { count: blobs.length, cancelled: false };
121
+
},
122
+
onError(err) {
123
+
console.error(err);
124
+
},
125
+
onSettled() {
126
+
setExportProgress();
127
+
},
128
+
});
129
+
130
+
const importFromFileMutation = createMutation({
131
+
async mutationFn({ destManager }: { destManager: CredentialManager }) {
132
+
setImportProgress('Waiting for file picker...');
133
+
134
+
const [fd] = await showOpenFilePicker({
135
+
// @ts-expect-error: ponyfill doesn't have the full typings
136
+
id: 'blob-import',
137
+
types: [
138
+
{
139
+
description: 'Tarball archive',
140
+
accept: { 'application/tar': ['.tar'] },
141
+
},
142
+
],
143
+
}).catch((err) => {
144
+
if (err instanceof DOMException && err.name === 'AbortError') {
145
+
return [undefined];
146
+
}
147
+
throw err;
148
+
});
149
+
150
+
if (!fd) {
151
+
return { uploaded: 0, failed: 0, cancelled: true };
152
+
}
153
+
154
+
setImportProgress('Reading archive...');
155
+
const file = await fd.getFile();
156
+
157
+
const destClient = new Client({ handler: destManager });
158
+
159
+
let uploaded = 0;
160
+
let failed = 0;
161
+
162
+
for await (const entry of untar(file.stream())) {
163
+
if (entry.type !== 'file') continue;
164
+
165
+
const filename = entry.name;
166
+
// Extract CID from path like "blobs/bafk..."
167
+
const cid = filename.split('/').pop();
168
+
if (!cid) continue;
169
+
170
+
setImportProgress(`Uploading blobs (${uploaded} uploaded, ${failed} failed)`);
171
+
172
+
try {
173
+
const data = await entry.bytes();
174
+
await destClient.post('com.atproto.repo.uploadBlob', {
175
+
input: data,
176
+
headers: {
177
+
'content-type': 'application/octet-stream',
178
+
},
179
+
});
180
+
uploaded++;
181
+
} catch (err) {
182
+
console.error(`Failed to upload blob ${cid}:`, err);
183
+
failed++;
184
+
}
185
+
}
186
+
187
+
return { uploaded, failed, cancelled: false };
188
+
},
189
+
onError(err) {
190
+
console.error(err);
191
+
},
192
+
onSettled() {
193
+
setImportProgress();
194
+
},
195
+
});
196
+
197
+
const importFromSourceMutation = createMutation({
198
+
async mutationFn({ source, destManager }: { source: SourceAccount; destManager: CredentialManager }) {
199
+
setImportProgress('Checking for missing blobs...');
200
+
201
+
const sourceClient = new Client({ handler: simpleFetchHandler({ service: source.pdsUrl }) });
202
+
const destClient = new Client({ handler: destManager });
203
+
204
+
let uploaded = 0;
205
+
let failed = 0;
206
+
let cursor: string | undefined;
207
+
208
+
do {
209
+
const data = await ok(
210
+
destClient.get('com.atproto.repo.listMissingBlobs', {
211
+
params: { cursor, limit: 100 },
212
+
}),
213
+
);
214
+
cursor = data.cursor;
215
+
216
+
for (const blob of data.blobs) {
217
+
setImportProgress(`Uploading missing blobs (${uploaded} uploaded, ${failed} failed)`);
218
+
219
+
try {
220
+
const response = await sourceClient.get('com.atproto.sync.getBlob', {
221
+
as: 'stream',
222
+
params: { did: source.did, cid: blob.cid },
223
+
});
224
+
225
+
if (!response.ok) {
226
+
failed++;
227
+
continue;
228
+
}
229
+
230
+
const contentType = response.headers.get('content-type') || 'application/octet-stream';
231
+
232
+
await destClient.post('com.atproto.repo.uploadBlob', {
233
+
input: response.data,
234
+
headers: {
235
+
'content-type': contentType,
236
+
},
237
+
});
238
+
239
+
uploaded++;
240
+
} catch (err) {
241
+
console.error(`Failed to transfer blob ${blob.cid}:`, err);
242
+
failed++;
243
+
}
244
+
}
245
+
} while (cursor !== undefined);
246
+
247
+
return { uploaded, failed };
248
+
},
249
+
onError(err) {
250
+
console.error(err);
251
+
},
252
+
onSettled() {
253
+
setImportProgress();
254
+
},
255
+
});
256
+
257
+
const checkStatusMutation = createMutation({
258
+
async mutationFn({ destManager }: { destManager: CredentialManager }) {
259
+
const destClient = new Client({ handler: destManager });
260
+
const status = await ok(destClient.get('com.atproto.server.checkAccountStatus'));
261
+
262
+
let missingBlobs: string[] = [];
263
+
264
+
// Get list of missing blobs if any
265
+
if (status.expectedBlobs > status.importedBlobs) {
266
+
let cursor: string | undefined;
267
+
do {
268
+
const data = await ok(
269
+
destClient.get('com.atproto.repo.listMissingBlobs', {
270
+
params: { cursor, limit: 100 },
271
+
}),
272
+
);
273
+
cursor = data.cursor;
274
+
missingBlobs.push(...data.blobs.map((b) => b.cid));
275
+
} while (cursor !== undefined);
276
+
}
277
+
278
+
return {
279
+
expected: status.expectedBlobs,
280
+
imported: status.importedBlobs,
281
+
missingBlobs,
282
+
};
283
+
},
284
+
onError(err) {
285
+
console.error(err);
286
+
},
287
+
});
288
+
289
+
const isImporting = () => importFromFileMutation.isPending || importFromSourceMutation.isPending;
290
+
291
+
const getExportStatusText = () => {
292
+
const data = exportMutation.data;
293
+
if (data?.cancelled) return undefined;
294
+
if (data?.count === 0) return 'No blobs to export';
295
+
if (data) return `Exported ${data.count} blobs`;
296
+
return exportProgress();
297
+
};
298
+
299
+
const getImportStatusText = () => {
300
+
const fileData = importFromFileMutation.data;
301
+
const sourceData = importFromSourceMutation.data;
302
+
303
+
if (fileData && !fileData.cancelled) {
304
+
return (
305
+
`Uploaded ${fileData.uploaded} blobs` + (fileData.failed > 0 ? ` (${fileData.failed} failed)` : '')
306
+
);
307
+
}
308
+
if (sourceData) {
309
+
if (sourceData.uploaded === 0 && sourceData.failed === 0) return 'No missing blobs';
310
+
return (
311
+
`Uploaded ${sourceData.uploaded} blobs` +
312
+
(sourceData.failed > 0 ? ` (${sourceData.failed} failed)` : '')
313
+
);
314
+
}
315
+
return importProgress();
316
+
};
317
+
318
+
const getImportError = () => importFromFileMutation.error || importFromSourceMutation.error;
319
+
320
+
return (
321
+
<Accordion title="Blobs">
322
+
<Subsection title="Export from source">
323
+
<p class="text-sm text-gray-600">Download all blobs as a tarball for backup or manual import.</p>
324
+
325
+
<Show when={source()} fallback={<p class="text-sm text-gray-500">Resolve source account first.</p>}>
326
+
{(src) => (
327
+
<>
328
+
<div class="flex items-center gap-3">
329
+
<Button
330
+
onClick={() => exportMutation.mutate({ source: src() })}
331
+
disabled={exportMutation.isPending}
332
+
>
333
+
{exportMutation.isPending ? 'Exporting...' : 'Export to file'}
334
+
</Button>
335
+
<Show when={getExportStatusText()}>
336
+
{(text) => <span class="text-sm text-gray-600">{text()}</span>}
337
+
</Show>
338
+
</div>
339
+
340
+
<Show when={exportMutation.error}>
341
+
{(err) => <p class="text-sm text-red-600">{`${err()}`}</p>}
342
+
</Show>
343
+
</>
344
+
)}
345
+
</Show>
346
+
</Subsection>
347
+
348
+
<Subsection title="Import to destination">
349
+
<p class="text-sm text-gray-600">Upload blobs from a tarball or transfer directly from source.</p>
350
+
351
+
<Show
352
+
when={destination()?.manager}
353
+
fallback={<p class="text-sm text-gray-500">Sign in to destination account first.</p>}
354
+
>
355
+
{(destManager) => (
356
+
<>
357
+
<div class="flex flex-wrap items-center gap-3">
358
+
<Button
359
+
onClick={() => importFromFileMutation.mutate({ destManager: destManager() })}
360
+
disabled={isImporting()}
361
+
>
362
+
{isImporting() ? 'Importing...' : 'Import from file'}
363
+
</Button>
364
+
365
+
<Show when={source()}>
366
+
{(src) => (
367
+
<Button
368
+
variant="secondary"
369
+
onClick={() =>
370
+
importFromSourceMutation.mutate({ source: src(), destManager: destManager() })
371
+
}
372
+
disabled={isImporting()}
373
+
>
374
+
Transfer from source
375
+
</Button>
376
+
)}
377
+
</Show>
378
+
</div>
379
+
380
+
<Show when={getImportStatusText()}>
381
+
{(text) => <span class="text-sm text-gray-600">{text()}</span>}
382
+
</Show>
383
+
384
+
<Show when={getImportError()}>{(err) => <p class="text-sm text-red-600">{`${err()}`}</p>}</Show>
385
+
</>
386
+
)}
387
+
</Show>
388
+
</Subsection>
389
+
390
+
<Subsection title="Status">
391
+
<Show
392
+
when={destination()?.manager}
393
+
fallback={<p class="text-sm text-gray-500">Sign in to destination account first.</p>}
394
+
>
395
+
{(destManager) => (
396
+
<>
397
+
<div class="flex items-center gap-3">
398
+
<Button
399
+
variant="outline"
400
+
onClick={() => checkStatusMutation.mutate({ destManager: destManager() })}
401
+
disabled={checkStatusMutation.isPending}
402
+
>
403
+
{checkStatusMutation.isPending ? 'Checking...' : 'Check status'}
404
+
</Button>
405
+
406
+
<Show when={checkStatusMutation.data}>
407
+
{(status) => (
408
+
<span class="text-sm">
409
+
<StatusBadge variant={status().imported === status().expected ? 'success' : 'pending'}>
410
+
{status().imported}/{status().expected} blobs
411
+
</StatusBadge>
412
+
</span>
413
+
)}
414
+
</Show>
415
+
</div>
416
+
417
+
<Show when={checkStatusMutation.data?.missingBlobs.length}>
418
+
{(count) => (
419
+
<div class="mt-2 rounded border border-yellow-300 bg-yellow-50 p-3">
420
+
<p class="mb-2 text-sm font-medium text-yellow-800">{count()} missing blobs</p>
421
+
422
+
<Show when={source()}>
423
+
{(src) => (
424
+
<Button
425
+
variant="secondary"
426
+
onClick={() =>
427
+
importFromSourceMutation.mutate({ source: src(), destManager: destManager() })
428
+
}
429
+
disabled={isImporting()}
430
+
>
431
+
Transfer missing from source
432
+
</Button>
433
+
)}
434
+
</Show>
435
+
436
+
<details class="mt-2">
437
+
<summary class="cursor-pointer text-sm text-yellow-700">Show CIDs</summary>
438
+
<div class="mt-1 max-h-32 overflow-auto font-mono text-xs">
439
+
<For each={checkStatusMutation.data?.missingBlobs}>
440
+
{(cid) => <div class="truncate">{cid}</div>}
441
+
</For>
442
+
</div>
443
+
</details>
444
+
</div>
445
+
)}
446
+
</Show>
447
+
</>
448
+
)}
449
+
</Show>
450
+
</Subsection>
451
+
</Accordion>
452
+
);
453
+
};
454
+
455
+
export default BlobsSection;
+437
src/views/account/account-migrate/sections/destination-account.tsx
+437
src/views/account/account-migrate/sections/destination-account.tsx
···
1
+
import { createSignal, Show } from 'solid-js';
2
+
3
+
import {
4
+
type AtpAccessJwt,
5
+
Client,
6
+
ClientResponseError,
7
+
CredentialManager,
8
+
ok,
9
+
simpleFetchHandler,
10
+
} from '@atcute/client';
11
+
import type { Did, Handle } from '@atcute/lexicons/syntax';
12
+
13
+
import { formatTotpCode, TOTP_RE } from '~/api/utils/auth';
14
+
import { decodeJwt } from '~/api/utils/jwt';
15
+
import { isServiceUrlString } from '~/api/types/strings';
16
+
17
+
import { createMutation } from '~/lib/utils/mutation';
18
+
19
+
import { Accordion, StatusBadge, Subsection } from '~/components/accordion';
20
+
import Button from '~/components/inputs/button';
21
+
import TextInput from '~/components/inputs/text-input';
22
+
23
+
import { useMigration } from '../context';
24
+
25
+
class InsufficientLoginError extends Error {}
26
+
27
+
const DestinationAccountSection = () => {
28
+
const { source, destination, setDestination } = useMigration();
29
+
30
+
// Connect state
31
+
const [pdsUrl, setPdsUrl] = createSignal('');
32
+
const [connectError, setConnectError] = createSignal<string>();
33
+
34
+
// Create account state
35
+
const [newHandle, setNewHandle] = createSignal('');
36
+
const [newEmail, setNewEmail] = createSignal('');
37
+
const [newPassword, setNewPassword] = createSignal('');
38
+
const [inviteCode, setInviteCode] = createSignal('');
39
+
const [createError, setCreateError] = createSignal<string>();
40
+
41
+
// Login state
42
+
const [loginPassword, setLoginPassword] = createSignal('');
43
+
const [loginOtp, setLoginOtp] = createSignal('');
44
+
const [isLoginTotpRequired, setIsLoginTotpRequired] = createSignal(false);
45
+
const [loginError, setLoginError] = createSignal<string>();
46
+
47
+
const connectMutation = createMutation({
48
+
async mutationFn({ pdsUrl }: { pdsUrl: string }) {
49
+
const destClient = new Client({ handler: simpleFetchHandler({ service: pdsUrl }) });
50
+
const desc = await ok(destClient.get('com.atproto.server.describeServer'));
51
+
52
+
return { serviceDid: desc.did };
53
+
},
54
+
onMutate() {
55
+
setConnectError();
56
+
},
57
+
onSuccess({ serviceDid }) {
58
+
setDestination({ pdsUrl: pdsUrl(), serviceDid, manager: null });
59
+
},
60
+
onError(err) {
61
+
console.error(err);
62
+
setConnectError(`Failed to connect: ${err}`);
63
+
},
64
+
});
65
+
66
+
const createAccountMutation = createMutation({
67
+
async mutationFn({
68
+
sourceDid,
69
+
sourceManager,
70
+
destPdsUrl,
71
+
destServiceDid,
72
+
handle,
73
+
email,
74
+
password,
75
+
inviteCode,
76
+
}: {
77
+
sourceDid: Did;
78
+
sourceManager: CredentialManager;
79
+
destPdsUrl: string;
80
+
destServiceDid: string;
81
+
handle: Handle;
82
+
email: string;
83
+
password: string;
84
+
inviteCode: string;
85
+
}) {
86
+
// Get service auth token from old PDS
87
+
const sourceClient = new Client({ handler: sourceManager });
88
+
const authResp = await ok(
89
+
sourceClient.get('com.atproto.server.getServiceAuth', {
90
+
params: {
91
+
aud: destServiceDid as Did,
92
+
lxm: 'com.atproto.server.createAccount',
93
+
},
94
+
}),
95
+
);
96
+
const serviceJwt = authResp.token;
97
+
98
+
// Create account on new PDS with service auth
99
+
const destClient = new Client({ handler: simpleFetchHandler({ service: destPdsUrl }) });
100
+
const createResp = await destClient.post('com.atproto.server.createAccount', {
101
+
headers: { Authorization: `Bearer ${serviceJwt}` },
102
+
input: {
103
+
did: sourceDid,
104
+
handle: handle,
105
+
email: email,
106
+
password: password,
107
+
inviteCode: inviteCode || undefined,
108
+
},
109
+
});
110
+
111
+
if (!createResp.ok) {
112
+
throw new ClientResponseError(createResp);
113
+
}
114
+
115
+
if (createResp.data.did !== sourceDid) {
116
+
throw new Error(`Created account has different DID: ${createResp.data.did}`);
117
+
}
118
+
119
+
// Login to the new account
120
+
const manager = new CredentialManager({ service: destPdsUrl });
121
+
await manager.login({
122
+
identifier: sourceDid,
123
+
password: password,
124
+
});
125
+
126
+
return manager;
127
+
},
128
+
onMutate() {
129
+
setCreateError();
130
+
},
131
+
onSuccess(manager) {
132
+
setDestination({ ...destination()!, manager });
133
+
setNewPassword('');
134
+
},
135
+
onError(err) {
136
+
if (err instanceof ClientResponseError) {
137
+
if (err.error === 'InvalidInviteCode') {
138
+
setCreateError(`Invalid invite code`);
139
+
return;
140
+
}
141
+
if (err.error === 'HandleNotAvailable') {
142
+
setCreateError(`Handle is not available`);
143
+
return;
144
+
}
145
+
if (err.description) {
146
+
setCreateError(err.description);
147
+
return;
148
+
}
149
+
}
150
+
console.error(err);
151
+
setCreateError(`${err}`);
152
+
},
153
+
});
154
+
155
+
const loginMutation = createMutation({
156
+
async mutationFn({
157
+
pdsUrl,
158
+
did,
159
+
password,
160
+
otp,
161
+
}: {
162
+
pdsUrl: string;
163
+
did: string;
164
+
password: string;
165
+
otp: string;
166
+
}) {
167
+
const manager = new CredentialManager({ service: pdsUrl });
168
+
const session = await manager.login({
169
+
identifier: did,
170
+
password: password,
171
+
code: formatTotpCode(otp),
172
+
});
173
+
174
+
const decoded = decodeJwt(session.accessJwt) as AtpAccessJwt;
175
+
if (decoded.scope !== 'com.atproto.access') {
176
+
throw new InsufficientLoginError(`You need to sign in with a main password, not an app password`);
177
+
}
178
+
179
+
return manager;
180
+
},
181
+
onMutate() {
182
+
setLoginError();
183
+
},
184
+
onSuccess(manager) {
185
+
setDestination({ ...destination()!, manager });
186
+
setLoginPassword('');
187
+
setLoginOtp('');
188
+
setIsLoginTotpRequired(false);
189
+
},
190
+
onError(err) {
191
+
if (err instanceof ClientResponseError) {
192
+
if (err.error === 'AuthFactorTokenRequired') {
193
+
setLoginOtp('');
194
+
setIsLoginTotpRequired(true);
195
+
return;
196
+
}
197
+
if (err.error === 'AuthenticationRequired') {
198
+
setLoginError(`Invalid identifier or password`);
199
+
return;
200
+
}
201
+
if (err.description?.includes('Token is invalid')) {
202
+
setLoginError(`Invalid one-time confirmation code`);
203
+
setIsLoginTotpRequired(true);
204
+
return;
205
+
}
206
+
}
207
+
if (err instanceof InsufficientLoginError) {
208
+
setLoginError(err.message);
209
+
return;
210
+
}
211
+
console.error(err);
212
+
setLoginError(`${err}`);
213
+
},
214
+
});
215
+
216
+
const isConnected = () => destination() !== null;
217
+
const isAuthenticated = () => destination()?.manager != null;
218
+
const canCreateAccount = () => source()?.manager != null;
219
+
220
+
return (
221
+
<Accordion title="Destination Account">
222
+
<Subsection title="Connect to PDS">
223
+
<Show when={!isConnected()}>
224
+
<form
225
+
onSubmit={(ev) => {
226
+
ev.preventDefault();
227
+
connectMutation.mutate({ pdsUrl: pdsUrl() });
228
+
}}
229
+
class="flex flex-col gap-3"
230
+
>
231
+
<TextInput
232
+
label="PDS URL"
233
+
type="url"
234
+
placeholder="https://pds.example.com"
235
+
value={pdsUrl()}
236
+
required
237
+
onChange={(text, event) => {
238
+
setPdsUrl(text);
239
+
const input = event.currentTarget;
240
+
if (text !== '' && !isServiceUrlString(text)) {
241
+
input.setCustomValidity('Must be a valid URL');
242
+
} else {
243
+
input.setCustomValidity('');
244
+
}
245
+
}}
246
+
/>
247
+
248
+
<Show when={connectError()}>
249
+
<p class="text-sm text-red-600">{connectError()}</p>
250
+
</Show>
251
+
252
+
<div>
253
+
<Button type="submit" disabled={connectMutation.isPending}>
254
+
{connectMutation.isPending ? 'Connecting...' : 'Connect'}
255
+
</Button>
256
+
</div>
257
+
</form>
258
+
</Show>
259
+
260
+
<Show when={isConnected()}>
261
+
<div class="flex flex-col gap-2 text-sm">
262
+
<p>
263
+
<span class="text-gray-500">URL:</span>{' '}
264
+
<span class="font-mono">{destination()!.pdsUrl}</span>
265
+
</p>
266
+
<p>
267
+
<span class="text-gray-500">Service DID:</span>{' '}
268
+
<span class="font-mono">{destination()!.serviceDid}</span>
269
+
</p>
270
+
<div class="mt-1">
271
+
<button
272
+
type="button"
273
+
onClick={() => setDestination(null)}
274
+
class="text-sm text-purple-800 hover:underline"
275
+
>
276
+
Change PDS
277
+
</button>
278
+
</div>
279
+
</div>
280
+
</Show>
281
+
</Subsection>
282
+
283
+
<Show when={isConnected() && !isAuthenticated()}>
284
+
<Subsection title="Create new account">
285
+
<Show when={!canCreateAccount()}>
286
+
<p class="text-sm text-gray-600">
287
+
You need to authenticate to your source account first to create an account on the
288
+
destination PDS.
289
+
</p>
290
+
</Show>
291
+
292
+
<Show when={canCreateAccount()}>
293
+
<form
294
+
onSubmit={(ev) => {
295
+
ev.preventDefault();
296
+
const src = source()!;
297
+
const dest = destination()!;
298
+
createAccountMutation.mutate({
299
+
sourceDid: src.did,
300
+
sourceManager: src.manager!,
301
+
destPdsUrl: dest.pdsUrl,
302
+
destServiceDid: dest.serviceDid,
303
+
handle: newHandle() as Handle,
304
+
email: newEmail(),
305
+
password: newPassword(),
306
+
inviteCode: inviteCode(),
307
+
});
308
+
}}
309
+
class="flex flex-col gap-3"
310
+
>
311
+
<TextInput
312
+
label="Handle"
313
+
placeholder="alice.pds.example.com"
314
+
value={newHandle()}
315
+
required
316
+
onChange={setNewHandle}
317
+
/>
318
+
319
+
<TextInput
320
+
label="Email"
321
+
type="email"
322
+
placeholder="alice@example.com"
323
+
value={newEmail()}
324
+
required
325
+
onChange={setNewEmail}
326
+
/>
327
+
328
+
<TextInput
329
+
label="Password"
330
+
type="password"
331
+
value={newPassword()}
332
+
required
333
+
onChange={setNewPassword}
334
+
/>
335
+
336
+
<TextInput
337
+
label="Invite code (if required)"
338
+
placeholder="pds-example-com-xxxxx"
339
+
value={inviteCode()}
340
+
onChange={setInviteCode}
341
+
/>
342
+
343
+
<Show when={createError()}>
344
+
<p class="text-sm text-red-600">{createError()}</p>
345
+
</Show>
346
+
347
+
<div>
348
+
<Button type="submit" disabled={createAccountMutation.isPending}>
349
+
{createAccountMutation.isPending ? 'Creating...' : 'Create account'}
350
+
</Button>
351
+
</div>
352
+
</form>
353
+
</Show>
354
+
</Subsection>
355
+
356
+
<Subsection title="Or login to existing account">
357
+
<p class="mb-2 text-sm text-gray-600">
358
+
If you already have a deactivated account on the destination PDS.
359
+
</p>
360
+
361
+
<Show when={!source()}>
362
+
<p class="text-sm text-gray-600">
363
+
Resolve your source account first so we know which DID to use.
364
+
</p>
365
+
</Show>
366
+
367
+
<Show when={source()}>
368
+
<form
369
+
onSubmit={(ev) => {
370
+
ev.preventDefault();
371
+
const src = source()!;
372
+
const dest = destination()!;
373
+
loginMutation.mutate({
374
+
pdsUrl: dest.pdsUrl,
375
+
did: src.did,
376
+
password: loginPassword(),
377
+
otp: loginOtp(),
378
+
});
379
+
}}
380
+
class="flex flex-col gap-3"
381
+
>
382
+
<TextInput
383
+
label="Password"
384
+
type="password"
385
+
value={loginPassword()}
386
+
required
387
+
onChange={setLoginPassword}
388
+
/>
389
+
390
+
<Show when={isLoginTotpRequired()}>
391
+
<TextInput
392
+
label="One-time confirmation code"
393
+
blurb="A code has been sent to your email address."
394
+
type="text"
395
+
autocomplete="one-time-code"
396
+
pattern={TOTP_RE.source}
397
+
placeholder="AAAAA-BBBBB"
398
+
value={loginOtp()}
399
+
required
400
+
onChange={setLoginOtp}
401
+
monospace
402
+
/>
403
+
</Show>
404
+
405
+
<Show when={loginError()}>
406
+
<p class="text-sm text-red-600">{loginError()}</p>
407
+
</Show>
408
+
409
+
<div>
410
+
<Button type="submit" disabled={loginMutation.isPending}>
411
+
{loginMutation.isPending ? 'Signing in...' : 'Sign in'}
412
+
</Button>
413
+
</div>
414
+
</form>
415
+
</Show>
416
+
</Subsection>
417
+
</Show>
418
+
419
+
<Show when={isAuthenticated()}>
420
+
<Subsection title="Account status">
421
+
<div class="flex items-center gap-2">
422
+
<StatusBadge variant="success">Signed in</StatusBadge>
423
+
<button
424
+
type="button"
425
+
onClick={() => setDestination({ ...destination()!, manager: null })}
426
+
class="text-sm text-purple-800 hover:underline"
427
+
>
428
+
Sign out
429
+
</button>
430
+
</div>
431
+
</Subsection>
432
+
</Show>
433
+
</Accordion>
434
+
);
435
+
};
436
+
437
+
export default DestinationAccountSection;
+545
src/views/account/account-migrate/sections/identity.tsx
+545
src/views/account/account-migrate/sections/identity.tsx
···
1
+
import { createSignal, For, Index, Show } from 'solid-js';
2
+
3
+
import { Client, ClientResponseError, type CredentialManager, ok } from '@atcute/client';
4
+
import { type DidKeyString, Secp256k1PrivateKeyExportable } from '@atcute/crypto';
5
+
import type { Did } from '@atcute/lexicons/syntax';
6
+
7
+
import { getPlcAuditLogs } from '~/api/queries/plc';
8
+
import { formatTotpCode, TOTP_RE } from '~/api/utils/auth';
9
+
10
+
import { createMutation } from '~/lib/utils/mutation';
11
+
12
+
import { Accordion, StatusBadge, Subsection } from '~/components/accordion';
13
+
import Button from '~/components/inputs/button';
14
+
import TextInput from '~/components/inputs/text-input';
15
+
import ToggleInput from '~/components/inputs/toggle-input';
16
+
17
+
import { getPlcPayload } from '~/views/identity/plc-applicator/plc-utils';
18
+
19
+
import { useMigration } from '../context';
20
+
21
+
interface RecommendedCredentials {
22
+
alsoKnownAs?: string[];
23
+
rotationKeys?: string[];
24
+
verificationMethods?: Record<string, unknown>;
25
+
services?: Record<string, unknown>;
26
+
}
27
+
28
+
interface GeneratedKeypair {
29
+
publicDidKey: DidKeyString;
30
+
privateHex: string;
31
+
privateMultikey: string;
32
+
}
33
+
34
+
const IdentitySection = () => {
35
+
const { source, destination } = useMigration();
36
+
37
+
// Rotation key state
38
+
const [useGeneratedKey, setUseGeneratedKey] = createSignal(false);
39
+
const [customKeys, setCustomKeys] = createSignal<string[]>([]);
40
+
const [plcToken, setPlcToken] = createSignal('');
41
+
42
+
const requestTokenMutation = createMutation({
43
+
async mutationFn({ manager }: { manager: CredentialManager }) {
44
+
const client = new Client({ handler: manager });
45
+
await ok(client.post('com.atproto.identity.requestPlcOperationSignature', { as: null }));
46
+
},
47
+
onError(err) {
48
+
console.error(err);
49
+
},
50
+
});
51
+
52
+
const loadCredentialsMutation = createMutation({
53
+
async mutationFn({ manager }: { manager: CredentialManager }) {
54
+
const client = new Client({ handler: manager });
55
+
return (await ok(
56
+
client.get('com.atproto.identity.getRecommendedDidCredentials', {}),
57
+
)) as RecommendedCredentials;
58
+
},
59
+
onError(err) {
60
+
console.error(err);
61
+
},
62
+
});
63
+
64
+
// Analyze current rotation keys to find user-controlled keys that should be preserved
65
+
const analyzeRotationKeysMutation = createMutation({
66
+
async mutationFn({ did, sourceManager }: { did: Did<'plc'>; sourceManager: CredentialManager }, signal) {
67
+
// Get current rotation keys from PLC audit log
68
+
const auditLogs = await getPlcAuditLogs({ did, signal });
69
+
const latestEntry = auditLogs[auditLogs.length - 1];
70
+
const currentPayload = getPlcPayload(latestEntry);
71
+
const currentRotationKeys = currentPayload.rotationKeys ?? [];
72
+
73
+
// Get source PDS's recommended credentials to identify PDS-controlled keys
74
+
const sourceClient = new Client({ handler: sourceManager });
75
+
const sourcePdsCredentials = (await ok(
76
+
sourceClient.get('com.atproto.identity.getRecommendedDidCredentials', {}),
77
+
)) as RecommendedCredentials;
78
+
const sourcePdsKeys = new Set(sourcePdsCredentials.rotationKeys ?? []);
79
+
80
+
// Keys in current doc that aren't from source PDS are user-controlled
81
+
const userControlledKeys = currentRotationKeys.filter((key) => !sourcePdsKeys.has(key));
82
+
83
+
return {
84
+
currentRotationKeys,
85
+
sourcePdsKeys: sourcePdsCredentials.rotationKeys ?? [],
86
+
userControlledKeys,
87
+
};
88
+
},
89
+
onSuccess(data) {
90
+
// Pre-populate custom keys with user-controlled keys
91
+
if (data.userControlledKeys.length > 0) {
92
+
setCustomKeys(data.userControlledKeys);
93
+
}
94
+
},
95
+
onError(err) {
96
+
console.error(err);
97
+
},
98
+
});
99
+
100
+
const generateKeyMutation = createMutation({
101
+
async mutationFn() {
102
+
const keypair = await Secp256k1PrivateKeyExportable.createKeypair();
103
+
const [publicDidKey, privateHex, privateMultikey] = await Promise.all([
104
+
keypair.exportPublicKey('did'),
105
+
keypair.exportPrivateKey('rawHex'),
106
+
keypair.exportPrivateKey('multikey'),
107
+
]);
108
+
return { publicDidKey, privateHex, privateMultikey } as GeneratedKeypair;
109
+
},
110
+
onError(err) {
111
+
console.error(err);
112
+
},
113
+
});
114
+
115
+
const signAndSubmitMutation = createMutation({
116
+
async mutationFn({
117
+
sourceManager,
118
+
destManager,
119
+
token,
120
+
credentials,
121
+
generatedKey,
122
+
customKeys,
123
+
}: {
124
+
sourceManager: CredentialManager;
125
+
destManager: CredentialManager;
126
+
token: string;
127
+
credentials: RecommendedCredentials;
128
+
generatedKey?: GeneratedKeypair;
129
+
customKeys: string[];
130
+
}) {
131
+
const sourceClient = new Client({ handler: sourceManager });
132
+
const destClient = new Client({ handler: destManager });
133
+
134
+
// Prepend user keys to PDS-provided keys (so user keys appear first for recovery)
135
+
const pdsRotationKeys = credentials.rotationKeys ?? [];
136
+
const userKeys: string[] = [];
137
+
if (generatedKey) {
138
+
userKeys.push(generatedKey.publicDidKey);
139
+
}
140
+
userKeys.push(...customKeys.filter((k) => k.trim()));
141
+
const rotationKeys = [...userKeys, ...pdsRotationKeys];
142
+
143
+
// Sign the PLC operation on the source PDS
144
+
const signage = await ok(
145
+
sourceClient.post('com.atproto.identity.signPlcOperation', {
146
+
input: {
147
+
token: formatTotpCode(token),
148
+
alsoKnownAs: credentials.alsoKnownAs,
149
+
rotationKeys: rotationKeys,
150
+
services: credentials.services,
151
+
verificationMethods: credentials.verificationMethods,
152
+
},
153
+
}),
154
+
);
155
+
156
+
// Submit via the destination PDS
157
+
await ok(
158
+
destClient.post('com.atproto.identity.submitPlcOperation', {
159
+
as: null,
160
+
input: {
161
+
operation: signage.operation,
162
+
},
163
+
}),
164
+
);
165
+
},
166
+
onSuccess() {
167
+
setPlcToken('');
168
+
},
169
+
onError(err) {
170
+
console.error(err);
171
+
},
172
+
});
173
+
174
+
// Calculate rotation key counts
175
+
const pdsKeyCount = () => loadCredentialsMutation.data?.rotationKeys?.length ?? 0;
176
+
const totalKeyCount = () => {
177
+
const custom = customKeys().filter((k) => k.trim()).length;
178
+
const generated = useGeneratedKey() && generateKeyMutation.data ? 1 : 0;
179
+
return pdsKeyCount() + custom + generated;
180
+
};
181
+
const canAddCustomKey = () => totalKeyCount() < 5;
182
+
const isOverLimit = () => totalKeyCount() > 5;
183
+
184
+
const addCustomKey = () => {
185
+
if (canAddCustomKey()) {
186
+
setCustomKeys([...customKeys(), '']);
187
+
}
188
+
};
189
+
190
+
const removeCustomKey = (index: number) => {
191
+
setCustomKeys(customKeys().filter((_, i) => i !== index));
192
+
};
193
+
194
+
const updateCustomKey = (index: number, value: string) => {
195
+
setCustomKeys(customKeys().map((k, i) => (i === index ? value : k)));
196
+
};
197
+
198
+
const canSignAndSubmit = () => {
199
+
const src = source();
200
+
const dest = destination();
201
+
const creds = loadCredentialsMutation.data;
202
+
const token = plcToken().trim();
203
+
204
+
return !!(src?.manager && dest?.manager && creds && token && !isOverLimit());
205
+
};
206
+
207
+
const handleSignAndSubmit = () => {
208
+
const src = source();
209
+
const dest = destination();
210
+
const creds = loadCredentialsMutation.data;
211
+
const token = plcToken().trim();
212
+
213
+
if (!src?.manager || !dest?.manager || !creds || !token || isOverLimit()) return;
214
+
215
+
signAndSubmitMutation.mutate({
216
+
sourceManager: src.manager,
217
+
destManager: dest.manager,
218
+
token,
219
+
credentials: creds,
220
+
generatedKey: useGeneratedKey() ? generateKeyMutation.data : undefined,
221
+
customKeys: customKeys(),
222
+
});
223
+
};
224
+
225
+
const getSubmitErrorMessage = () => {
226
+
const err = signAndSubmitMutation.error;
227
+
if (err instanceof ClientResponseError) {
228
+
if (err.error === 'InvalidToken' || err.error === 'ExpiredToken') {
229
+
return 'Confirmation code has expired or is invalid';
230
+
}
231
+
}
232
+
return `${err}`;
233
+
};
234
+
235
+
return (
236
+
<Accordion title="Identity (PLC)">
237
+
<div class="mb-4 rounded border border-yellow-300 bg-yellow-50 p-3">
238
+
<p class="text-sm font-medium text-yellow-800">
239
+
This updates your DID document to point to the new PDS. This is the critical step that makes the
240
+
migration official.
241
+
</p>
242
+
</div>
243
+
244
+
<Subsection title="1. Preview new credentials">
245
+
<p class="text-sm text-gray-600">View what your DID document will look like after the migration.</p>
246
+
247
+
<Show
248
+
when={destination()?.manager}
249
+
fallback={<p class="text-sm text-gray-500">Sign in to destination account first.</p>}
250
+
>
251
+
{(manager) => (
252
+
<>
253
+
<div class="flex items-center gap-3">
254
+
<Button
255
+
variant="outline"
256
+
onClick={() => loadCredentialsMutation.mutate({ manager: manager() })}
257
+
disabled={loadCredentialsMutation.isPending}
258
+
>
259
+
{loadCredentialsMutation.isPending ? 'Loading...' : 'Load credentials'}
260
+
</Button>
261
+
262
+
<Show when={loadCredentialsMutation.isSuccess}>
263
+
<StatusBadge variant="success">Loaded</StatusBadge>
264
+
</Show>
265
+
</div>
266
+
267
+
<Show when={loadCredentialsMutation.isError}>
268
+
<p class="text-sm text-red-600">{`${loadCredentialsMutation.error}`}</p>
269
+
</Show>
270
+
271
+
<Show when={loadCredentialsMutation.data}>
272
+
{(creds) => (
273
+
<>
274
+
<div class="mt-2 text-sm">
275
+
<p class="text-gray-500">
276
+
Destination PDS rotation keys ({creds().rotationKeys?.length ?? 0}/5):
277
+
</p>
278
+
<div class="mt-1 flex flex-col gap-1">
279
+
<For each={creds().rotationKeys ?? []}>
280
+
{(key) => <code class="block truncate text-xs text-gray-700">{key}</code>}
281
+
</For>
282
+
</div>
283
+
</div>
284
+
285
+
<Show when={source()?.manager && source()}>
286
+
{(src) => (
287
+
<div class="mt-3 rounded border border-blue-200 bg-blue-50 p-3">
288
+
<div class="flex items-center justify-between">
289
+
<p class="text-sm font-medium text-blue-800">Analyze existing rotation keys</p>
290
+
<Button
291
+
variant="outline"
292
+
onClick={() =>
293
+
analyzeRotationKeysMutation.mutate({
294
+
did: src().did as Did<'plc'>,
295
+
sourceManager: src().manager!,
296
+
})
297
+
}
298
+
disabled={analyzeRotationKeysMutation.isPending}
299
+
>
300
+
{analyzeRotationKeysMutation.isPending ? 'Analyzing...' : 'Analyze'}
301
+
</Button>
302
+
</div>
303
+
<p class="mt-1 text-xs text-blue-600">
304
+
Check if you have any user-controlled rotation keys that should be preserved
305
+
during migration.
306
+
</p>
307
+
308
+
<Show when={analyzeRotationKeysMutation.error}>
309
+
<p class="mt-2 text-sm text-red-600">{`${analyzeRotationKeysMutation.error}`}</p>
310
+
</Show>
311
+
312
+
<Show when={analyzeRotationKeysMutation.data}>
313
+
{(analysis) => (
314
+
<div class="mt-2 text-sm">
315
+
<Show
316
+
when={analysis().userControlledKeys.length > 0}
317
+
fallback={
318
+
<p class="text-blue-700">
319
+
No user-controlled rotation keys found. Your current keys are all
320
+
managed by your source PDS.
321
+
</p>
322
+
}
323
+
>
324
+
<p class="font-medium text-blue-800">
325
+
Found {analysis().userControlledKeys.length} user-controlled key(s) to
326
+
preserve:
327
+
</p>
328
+
<div class="mt-1 flex flex-col gap-1">
329
+
<For each={analysis().userControlledKeys}>
330
+
{(key) => (
331
+
<code class="block truncate text-xs text-blue-700">{key}</code>
332
+
)}
333
+
</For>
334
+
</div>
335
+
<p class="mt-2 text-xs text-blue-600">
336
+
These keys have been added to the custom keys section below.
337
+
</p>
338
+
</Show>
339
+
</div>
340
+
)}
341
+
</Show>
342
+
</div>
343
+
)}
344
+
</Show>
345
+
346
+
<details class="mt-2">
347
+
<summary class="cursor-pointer text-sm text-gray-600">View full credentials</summary>
348
+
<pre class="mt-2 max-h-48 overflow-auto rounded border border-gray-200 bg-gray-50 p-2 font-mono text-xs">
349
+
{JSON.stringify(creds(), null, 2)}
350
+
</pre>
351
+
</details>
352
+
</>
353
+
)}
354
+
</Show>
355
+
</>
356
+
)}
357
+
</Show>
358
+
</Subsection>
359
+
360
+
<Subsection title="2. Rotation keys (optional)">
361
+
<p class="text-sm text-gray-600">
362
+
Add a rotation key to recover your account if your new PDS goes rogue. This will be prepended to the
363
+
PDS rotation keys shown above.
364
+
</p>
365
+
366
+
<ToggleInput
367
+
label="Generate a new rotation key"
368
+
checked={useGeneratedKey()}
369
+
onChange={(checked) => {
370
+
setUseGeneratedKey(checked);
371
+
// Auto-generate if checked and no key exists yet
372
+
if (checked && !generateKeyMutation.data && !generateKeyMutation.isPending) {
373
+
generateKeyMutation.mutate();
374
+
}
375
+
}}
376
+
/>
377
+
378
+
<Show when={useGeneratedKey() && generateKeyMutation.isPending}>
379
+
<p class="mt-2 text-sm text-gray-500">Generating key...</p>
380
+
</Show>
381
+
382
+
<Show when={useGeneratedKey() && generateKeyMutation.isError}>
383
+
<p class="mt-2 text-sm text-red-600">{`${generateKeyMutation.error}`}</p>
384
+
</Show>
385
+
386
+
<Show when={useGeneratedKey() && generateKeyMutation.data}>
387
+
{(keypair) => (
388
+
<div class="rounded border border-green-300 bg-green-50 p-3">
389
+
<p class="mb-2 text-sm font-semibold text-green-800">Save your rotation key private key!</p>
390
+
<p class="mb-3 text-xs text-green-700">
391
+
Store this securely. You'll need it to recover your account if your PDS becomes unavailable or
392
+
malicious.
393
+
</p>
394
+
395
+
<div class="flex flex-col gap-2 text-sm">
396
+
<div>
397
+
<p class="font-medium text-gray-600">Public key (did:key)</p>
398
+
<p class="break-all font-mono text-xs">{keypair().publicDidKey}</p>
399
+
</div>
400
+
<div>
401
+
<p class="font-medium text-gray-600">Private key (hex)</p>
402
+
<p class="break-all font-mono text-xs">{keypair().privateHex}</p>
403
+
</div>
404
+
<div>
405
+
<p class="font-medium text-gray-600">Private key (multikey)</p>
406
+
<p class="break-all font-mono text-xs">{keypair().privateMultikey}</p>
407
+
</div>
408
+
</div>
409
+
</div>
410
+
)}
411
+
</Show>
412
+
413
+
<div class="rounded border border-gray-200 bg-gray-50 p-3">
414
+
<p class="mb-2 text-sm font-medium text-gray-700">Custom rotation keys</p>
415
+
<p class="mb-3 text-xs text-gray-500">
416
+
Add existing rotation keys (did:key format) you already control.
417
+
</p>
418
+
419
+
<Index each={customKeys()}>
420
+
{(key, index) => (
421
+
<div class="mb-2 flex items-center gap-2">
422
+
<TextInput
423
+
label=""
424
+
placeholder="did:key:z..."
425
+
monospace
426
+
autocomplete="off"
427
+
value={key()}
428
+
onChange={(value) => updateCustomKey(index, value)}
429
+
/>
430
+
<button
431
+
type="button"
432
+
class="shrink-0 rounded px-2 py-1 text-sm text-red-600 hover:bg-red-50"
433
+
onClick={() => removeCustomKey(index)}
434
+
>
435
+
Remove
436
+
</button>
437
+
</div>
438
+
)}
439
+
</Index>
440
+
441
+
<Button variant="outline" onClick={addCustomKey} disabled={!canAddCustomKey()}>
442
+
Add rotation key
443
+
</Button>
444
+
445
+
<Show when={isOverLimit()}>
446
+
<p class="mt-2 text-sm text-red-600">
447
+
Too many rotation keys. PLC documents can only have up to 5 rotation keys total.
448
+
</p>
449
+
</Show>
450
+
451
+
<p class="mt-2 text-xs text-gray-500">
452
+
Total keys: {totalKeyCount()}/5 (PDS: {pdsKeyCount()}
453
+
{useGeneratedKey() && generateKeyMutation.data ? ', generated: 1' : ''}
454
+
{customKeys().filter((k) => k.trim()).length > 0
455
+
? `, custom: ${customKeys().filter((k) => k.trim()).length}`
456
+
: ''}
457
+
)
458
+
</p>
459
+
</div>
460
+
</Subsection>
461
+
462
+
<Subsection title="3. Request operation signature">
463
+
<p class="text-sm text-gray-600">Request a confirmation token via email from your source PDS.</p>
464
+
465
+
<Show
466
+
when={source()?.manager}
467
+
fallback={<p class="text-sm text-gray-500">Sign in to source account first.</p>}
468
+
>
469
+
{(manager) => (
470
+
<>
471
+
<div class="flex items-center gap-3">
472
+
<Button
473
+
onClick={() => requestTokenMutation.mutate({ manager: manager() })}
474
+
disabled={requestTokenMutation.isPending}
475
+
>
476
+
{requestTokenMutation.isPending ? 'Requesting...' : 'Request token'}
477
+
</Button>
478
+
479
+
<Show when={requestTokenMutation.isSuccess}>
480
+
<StatusBadge variant="success">Email sent</StatusBadge>
481
+
</Show>
482
+
</div>
483
+
484
+
<Show when={requestTokenMutation.isError}>
485
+
<p class="text-sm text-red-600">{`${requestTokenMutation.error}`}</p>
486
+
</Show>
487
+
488
+
<Show when={requestTokenMutation.isSuccess}>
489
+
<p class="text-sm text-gray-600">Check your email inbox for the confirmation code.</p>
490
+
</Show>
491
+
</>
492
+
)}
493
+
</Show>
494
+
</Subsection>
495
+
496
+
<Subsection title="4. Sign and submit">
497
+
<p class="text-sm text-gray-600">Enter the confirmation code and submit the PLC operation.</p>
498
+
499
+
<Show when={!source()?.manager || !destination()?.manager}>
500
+
<p class="text-sm text-gray-500">Sign in to both source and destination accounts first.</p>
501
+
</Show>
502
+
503
+
<Show when={!loadCredentialsMutation.data}>
504
+
<p class="text-sm text-gray-500">Load credentials first.</p>
505
+
</Show>
506
+
507
+
<Show when={useGeneratedKey() && !generateKeyMutation.data}>
508
+
<p class="text-sm text-gray-500">Generate your rotation key first.</p>
509
+
</Show>
510
+
511
+
<Show when={source()?.manager && destination()?.manager && loadCredentialsMutation.data}>
512
+
<TextInput
513
+
label="Confirmation code from email"
514
+
type="text"
515
+
autocomplete="one-time-code"
516
+
pattern={TOTP_RE.source}
517
+
placeholder="AAAAA-BBBBB"
518
+
value={plcToken()}
519
+
onChange={setPlcToken}
520
+
monospace
521
+
/>
522
+
523
+
<div class="flex items-center gap-3">
524
+
<Button
525
+
onClick={handleSignAndSubmit}
526
+
disabled={signAndSubmitMutation.isPending || !canSignAndSubmit()}
527
+
>
528
+
{signAndSubmitMutation.isPending ? 'Submitting...' : 'Sign and submit'}
529
+
</Button>
530
+
531
+
<Show when={signAndSubmitMutation.isSuccess}>
532
+
<StatusBadge variant="success">Identity updated successfully</StatusBadge>
533
+
</Show>
534
+
</div>
535
+
536
+
<Show when={signAndSubmitMutation.isError}>
537
+
<p class="text-sm text-red-600">{getSubmitErrorMessage()}</p>
538
+
</Show>
539
+
</Show>
540
+
</Subsection>
541
+
</Accordion>
542
+
);
543
+
};
544
+
545
+
export default IdentitySection;
+180
src/views/account/account-migrate/sections/preferences.tsx
+180
src/views/account/account-migrate/sections/preferences.tsx
···
1
+
import { showSaveFilePicker } from 'native-file-system-adapter';
2
+
import { createSignal, Show } from 'solid-js';
3
+
4
+
import { Client, type CredentialManager, ok } from '@atcute/client';
5
+
6
+
import { createMutation } from '~/lib/utils/mutation';
7
+
8
+
import { Accordion, StatusBadge, Subsection } from '~/components/accordion';
9
+
import Button from '~/components/inputs/button';
10
+
import MultilineInput from '~/components/inputs/multiline-input';
11
+
12
+
import { useMigration } from '../context';
13
+
14
+
const PreferencesSection = () => {
15
+
const { source, destination } = useMigration();
16
+
17
+
const [prefsInput, setPrefsInput] = createSignal('');
18
+
19
+
const exportMutation = createMutation({
20
+
async mutationFn({ sourceManager }: { sourceManager: CredentialManager }) {
21
+
const sourceClient = new Client({ handler: sourceManager });
22
+
const prefs = await ok(sourceClient.get('app.bsky.actor.getPreferences', { params: {} }));
23
+
return JSON.stringify(prefs, null, 2);
24
+
},
25
+
onSuccess(json) {
26
+
setPrefsInput(json);
27
+
},
28
+
onError(err) {
29
+
console.error(err);
30
+
},
31
+
});
32
+
33
+
const downloadPrefs = async () => {
34
+
const prefs = exportMutation.data;
35
+
if (!prefs) return;
36
+
37
+
try {
38
+
const fd = await showSaveFilePicker({
39
+
suggestedName: `preferences-${source()?.did}-${new Date().toISOString()}.json`,
40
+
// @ts-expect-error: ponyfill doesn't have the full typings
41
+
id: 'prefs-export',
42
+
startIn: 'downloads',
43
+
types: [
44
+
{
45
+
description: 'JSON file',
46
+
accept: { 'application/json': ['.json'] },
47
+
},
48
+
],
49
+
}).catch((err) => {
50
+
if (err instanceof DOMException && err.name === 'AbortError') {
51
+
return undefined;
52
+
}
53
+
throw err;
54
+
});
55
+
56
+
if (!fd) return;
57
+
58
+
const writable = await fd.createWritable();
59
+
await writable.write(prefs);
60
+
await writable.close();
61
+
} catch (err) {
62
+
console.error(err);
63
+
}
64
+
};
65
+
66
+
const importMutation = createMutation({
67
+
async mutationFn({ destManager, input }: { destManager: CredentialManager; input: string }) {
68
+
const prefs = JSON.parse(input);
69
+
70
+
// Validate that it has a preferences array
71
+
if (!prefs.preferences || !Array.isArray(prefs.preferences)) {
72
+
throw new Error('Invalid preferences format: missing preferences array');
73
+
}
74
+
75
+
const destClient = new Client({ handler: destManager });
76
+
await destClient.post('app.bsky.actor.putPreferences', {
77
+
as: null,
78
+
input: prefs,
79
+
});
80
+
},
81
+
onError(err) {
82
+
console.error(err);
83
+
},
84
+
});
85
+
86
+
const getImportErrorMessage = () => {
87
+
const err = importMutation.error;
88
+
if (err instanceof SyntaxError) {
89
+
return 'Invalid JSON format';
90
+
}
91
+
return `${err}`;
92
+
};
93
+
94
+
return (
95
+
<Accordion title="Preferences">
96
+
<Subsection title="Export from source">
97
+
<p class="text-sm text-gray-600">
98
+
Export your Bluesky preferences (muted words, content filters, saved feeds, etc).
99
+
</p>
100
+
101
+
<Show
102
+
when={source()?.manager}
103
+
fallback={<p class="text-sm text-gray-500">Sign in to source account first.</p>}
104
+
>
105
+
{(sourceManager) => (
106
+
<>
107
+
<div class="flex items-center gap-3">
108
+
<Button
109
+
onClick={() => exportMutation.mutate({ sourceManager: sourceManager() })}
110
+
disabled={exportMutation.isPending}
111
+
>
112
+
{exportMutation.isPending ? 'Exporting...' : 'Export preferences'}
113
+
</Button>
114
+
115
+
<Show when={exportMutation.data}>
116
+
<Button variant="secondary" onClick={downloadPrefs}>
117
+
Download as file
118
+
</Button>
119
+
</Show>
120
+
</div>
121
+
122
+
<Show when={exportMutation.error}>
123
+
{(err) => <p class="text-sm text-red-600">{`${err()}`}</p>}
124
+
</Show>
125
+
126
+
<Show when={exportMutation.data}>
127
+
{(prefs) => (
128
+
<details class="mt-2">
129
+
<summary class="cursor-pointer text-sm text-gray-600">
130
+
View exported preferences
131
+
</summary>
132
+
<pre class="mt-2 max-h-48 overflow-auto rounded border border-gray-200 bg-gray-50 p-2 font-mono text-xs">
133
+
{prefs()}
134
+
</pre>
135
+
</details>
136
+
)}
137
+
</Show>
138
+
</>
139
+
)}
140
+
</Show>
141
+
</Subsection>
142
+
143
+
<Subsection title="Import to destination">
144
+
<p class="text-sm text-gray-600">Paste preferences JSON or use the exported data above.</p>
145
+
146
+
<Show
147
+
when={destination()?.manager}
148
+
fallback={<p class="text-sm text-gray-500">Sign in to destination account first.</p>}
149
+
>
150
+
{(destManager) => (
151
+
<>
152
+
<MultilineInput label="Preferences JSON" value={prefsInput()} onChange={setPrefsInput} />
153
+
154
+
<div class="flex items-center gap-3">
155
+
<Button
156
+
onClick={() =>
157
+
importMutation.mutate({ destManager: destManager(), input: prefsInput().trim() })
158
+
}
159
+
disabled={importMutation.isPending || !prefsInput().trim()}
160
+
>
161
+
{importMutation.isPending ? 'Importing...' : 'Import preferences'}
162
+
</Button>
163
+
164
+
<Show when={importMutation.isSuccess}>
165
+
<StatusBadge variant="success">Preferences imported successfully</StatusBadge>
166
+
</Show>
167
+
</div>
168
+
169
+
<Show when={importMutation.error}>
170
+
<p class="text-sm text-red-600">{getImportErrorMessage()}</p>
171
+
</Show>
172
+
</>
173
+
)}
174
+
</Show>
175
+
</Subsection>
176
+
</Accordion>
177
+
);
178
+
};
179
+
180
+
export default PreferencesSection;
+291
src/views/account/account-migrate/sections/repository.tsx
+291
src/views/account/account-migrate/sections/repository.tsx
···
1
+
import { showOpenFilePicker, showSaveFilePicker } from 'native-file-system-adapter';
2
+
import { createSignal, Show } from 'solid-js';
3
+
4
+
import { Client, type CredentialManager, ok, simpleFetchHandler } from '@atcute/client';
5
+
import type { Did } from '@atcute/lexicons/syntax';
6
+
7
+
import { formatBytes } from '~/lib/utils/intl/bytes';
8
+
import { createMutation } from '~/lib/utils/mutation';
9
+
import { iterateStream } from '~/lib/utils/stream';
10
+
11
+
import { Accordion, StatusBadge, Subsection } from '~/components/accordion';
12
+
import Button from '~/components/inputs/button';
13
+
14
+
import { useMigration } from '../context';
15
+
16
+
const RepositorySection = () => {
17
+
const { source, destination } = useMigration();
18
+
19
+
// Export state
20
+
const [exportStatus, setExportStatus] = createSignal<string>();
21
+
22
+
// Import state
23
+
const [importStatus, setImportStatus] = createSignal<string>();
24
+
const [importedRecords, setImportedRecords] = createSignal<number>();
25
+
26
+
const exportMutation = createMutation({
27
+
async mutationFn({ pdsUrl, did }: { pdsUrl: string; did: Did }) {
28
+
setExportStatus('Waiting for file picker...');
29
+
30
+
const fd = await showSaveFilePicker({
31
+
suggestedName: `repo-${did}-${new Date().toISOString()}.car`,
32
+
// @ts-expect-error: ponyfill doesn't have the full typings
33
+
id: 'repo-export',
34
+
startIn: 'downloads',
35
+
types: [
36
+
{
37
+
description: 'CAR archive file',
38
+
accept: { 'application/vnd.ipld.car': ['.car'] },
39
+
},
40
+
],
41
+
}).catch((err) => {
42
+
if (err instanceof DOMException && err.name === 'AbortError') {
43
+
return undefined;
44
+
}
45
+
throw err;
46
+
});
47
+
48
+
if (!fd) {
49
+
setExportStatus();
50
+
return null;
51
+
}
52
+
53
+
const writable = await fd.createWritable();
54
+
55
+
setExportStatus('Downloading repository...');
56
+
57
+
const sourceClient = new Client({ handler: simpleFetchHandler({ service: pdsUrl }) });
58
+
const response = await sourceClient.get('com.atproto.sync.getRepo', {
59
+
as: 'stream',
60
+
params: { did },
61
+
});
62
+
63
+
if (!response.ok) {
64
+
throw new Error(`Failed to download repository: ${response.status}`);
65
+
}
66
+
67
+
let size = 0;
68
+
for await (const chunk of iterateStream(response.data)) {
69
+
size += chunk.length;
70
+
await writable.write(chunk);
71
+
setExportStatus(`Downloading repository... (${formatBytes(size)})`);
72
+
}
73
+
74
+
await writable.close();
75
+
setExportStatus(`Exported ${formatBytes(size)}`);
76
+
return size;
77
+
},
78
+
onMutate() {
79
+
setExportStatus();
80
+
},
81
+
onError(err) {
82
+
console.error(err);
83
+
setExportStatus();
84
+
},
85
+
});
86
+
87
+
const importFromFileMutation = createMutation({
88
+
async mutationFn({ manager }: { manager: CredentialManager }) {
89
+
setImportStatus('Waiting for file picker...');
90
+
91
+
const [fd] = await showOpenFilePicker({
92
+
// @ts-expect-error: ponyfill doesn't have the full typings
93
+
id: 'repo-import',
94
+
types: [
95
+
{
96
+
description: 'CAR archive file',
97
+
accept: { 'application/vnd.ipld.car': ['.car'] },
98
+
},
99
+
],
100
+
}).catch((err) => {
101
+
if (err instanceof DOMException && err.name === 'AbortError') {
102
+
return [undefined];
103
+
}
104
+
throw err;
105
+
});
106
+
107
+
if (!fd) {
108
+
setImportStatus();
109
+
return null;
110
+
}
111
+
112
+
const file = await fd.getFile();
113
+
114
+
setImportStatus(`Uploading repository (${formatBytes(file.size)})...`);
115
+
116
+
const destClient = new Client({ handler: manager });
117
+
const importResp = await destClient.post('com.atproto.repo.importRepo', {
118
+
as: null,
119
+
input: file,
120
+
headers: {
121
+
'content-type': 'application/vnd.ipld.car',
122
+
},
123
+
});
124
+
125
+
if (!importResp.ok) {
126
+
throw new Error(`Failed to import repository: ${importResp.status}`);
127
+
}
128
+
129
+
// Check account status to get record count
130
+
const status = await ok(destClient.get('com.atproto.server.checkAccountStatus', {}));
131
+
setImportedRecords(status.indexedRecords);
132
+
133
+
setImportStatus(`Imported successfully`);
134
+
return status.indexedRecords;
135
+
},
136
+
onMutate() {
137
+
setImportStatus();
138
+
setImportedRecords();
139
+
},
140
+
onError(err) {
141
+
console.error(err);
142
+
setImportStatus();
143
+
},
144
+
});
145
+
146
+
const importFromSourceMutation = createMutation({
147
+
async mutationFn({
148
+
sourcePdsUrl,
149
+
sourceDid,
150
+
destManager,
151
+
}: {
152
+
sourcePdsUrl: string;
153
+
sourceDid: Did;
154
+
destManager: CredentialManager;
155
+
}) {
156
+
setImportStatus('Downloading from source PDS...');
157
+
158
+
const sourceClient = new Client({ handler: simpleFetchHandler({ service: sourcePdsUrl }) });
159
+
const response = await sourceClient.get('com.atproto.sync.getRepo', {
160
+
as: 'bytes',
161
+
params: { did: sourceDid },
162
+
});
163
+
164
+
if (!response.ok) {
165
+
throw new Error(`Failed to download repository: ${response.status}`);
166
+
}
167
+
168
+
setImportStatus(`Uploading to destination (${formatBytes(response.data.length)})...`);
169
+
170
+
const destClient = new Client({ handler: destManager });
171
+
const importResp = await destClient.post('com.atproto.repo.importRepo', {
172
+
as: null,
173
+
input: response.data,
174
+
headers: {
175
+
'content-type': 'application/vnd.ipld.car',
176
+
},
177
+
});
178
+
179
+
if (!importResp.ok) {
180
+
throw new Error(`Failed to import repository: ${importResp.status}`);
181
+
}
182
+
183
+
// Check account status to get record count
184
+
const status = await ok(destClient.get('com.atproto.server.checkAccountStatus', {}));
185
+
setImportedRecords(status.indexedRecords);
186
+
187
+
setImportStatus(`Imported successfully`);
188
+
return status.indexedRecords;
189
+
},
190
+
onMutate() {
191
+
setImportStatus();
192
+
setImportedRecords();
193
+
},
194
+
onError(err) {
195
+
console.error(err);
196
+
setImportStatus();
197
+
},
198
+
});
199
+
200
+
const isExporting = () => exportMutation.isPending;
201
+
const isImporting = () => importFromFileMutation.isPending || importFromSourceMutation.isPending;
202
+
203
+
return (
204
+
<Accordion title="Repository">
205
+
<Subsection title="Export from source">
206
+
<p class="text-sm text-gray-600">
207
+
Download the repository as a CAR file for backup or manual import.
208
+
</p>
209
+
210
+
<Show when={source()} fallback={<p class="text-sm text-gray-500">Resolve source account first.</p>}>
211
+
{(src) => (
212
+
<>
213
+
<div class="flex items-center gap-3">
214
+
<Button
215
+
onClick={() => exportMutation.mutate({ pdsUrl: src().pdsUrl, did: src().did })}
216
+
disabled={isExporting()}
217
+
>
218
+
{isExporting() ? 'Exporting...' : 'Export to file'}
219
+
</Button>
220
+
<Show when={exportStatus()}>
221
+
<span class="text-sm text-gray-600">{exportStatus()}</span>
222
+
</Show>
223
+
</div>
224
+
225
+
<Show when={exportMutation.isError}>
226
+
<p class="text-sm text-red-600">{`${exportMutation.error}`}</p>
227
+
</Show>
228
+
</>
229
+
)}
230
+
</Show>
231
+
</Subsection>
232
+
233
+
<Subsection title="Import to destination">
234
+
<p class="text-sm text-gray-600">Upload a repository CAR file or transfer directly from source.</p>
235
+
236
+
<Show
237
+
when={destination()?.manager}
238
+
fallback={<p class="text-sm text-gray-500">Sign in to destination account first.</p>}
239
+
>
240
+
{(manager) => (
241
+
<>
242
+
<div class="flex flex-wrap items-center gap-3">
243
+
<Button
244
+
onClick={() => importFromFileMutation.mutate({ manager: manager() })}
245
+
disabled={isImporting()}
246
+
>
247
+
{isImporting() ? 'Importing...' : 'Import from file'}
248
+
</Button>
249
+
250
+
<Show when={source()}>
251
+
{(src) => (
252
+
<Button
253
+
variant="secondary"
254
+
onClick={() =>
255
+
importFromSourceMutation.mutate({
256
+
sourcePdsUrl: src().pdsUrl,
257
+
sourceDid: src().did,
258
+
destManager: manager(),
259
+
})
260
+
}
261
+
disabled={isImporting()}
262
+
>
263
+
Transfer from source
264
+
</Button>
265
+
)}
266
+
</Show>
267
+
</div>
268
+
269
+
<Show when={importStatus()}>
270
+
<div class="flex items-center gap-2">
271
+
<span class="text-sm text-gray-600">{importStatus()}</span>
272
+
<Show when={importedRecords() !== undefined}>
273
+
<StatusBadge variant="success">{importedRecords()} records</StatusBadge>
274
+
</Show>
275
+
</div>
276
+
</Show>
277
+
278
+
<Show when={importFromFileMutation.isError || importFromSourceMutation.isError}>
279
+
<p class="text-sm text-red-600">
280
+
{`${importFromFileMutation.error || importFromSourceMutation.error}`}
281
+
</p>
282
+
</Show>
283
+
</>
284
+
)}
285
+
</Show>
286
+
</Subsection>
287
+
</Accordion>
288
+
);
289
+
};
290
+
291
+
export default RepositorySection;
+265
src/views/account/account-migrate/sections/source-account.tsx
+265
src/views/account/account-migrate/sections/source-account.tsx
···
1
+
import { createSignal, Show } from 'solid-js';
2
+
3
+
import { type AtpAccessJwt, ClientResponseError, CredentialManager } from '@atcute/client';
4
+
import { getPdsEndpoint, isAtprotoDid } from '@atcute/identity';
5
+
import { isHandle, type AtprotoDid } from '@atcute/lexicons/syntax';
6
+
7
+
import { getDidDocument } from '~/api/queries/did-doc';
8
+
import { resolveHandleViaAppView } from '~/api/queries/handle';
9
+
import { formatTotpCode, TOTP_RE } from '~/api/utils/auth';
10
+
import { decodeJwt } from '~/api/utils/jwt';
11
+
12
+
import { createMutation } from '~/lib/utils/mutation';
13
+
14
+
import { Accordion, StatusBadge, Subsection } from '~/components/accordion';
15
+
import Button from '~/components/inputs/button';
16
+
import TextInput from '~/components/inputs/text-input';
17
+
18
+
import { useMigration } from '../context';
19
+
20
+
interface SourceAccountSectionProps {
21
+
onStarted?: () => void;
22
+
}
23
+
24
+
class InsufficientLoginError extends Error {}
25
+
26
+
const SourceAccountSection = (props: SourceAccountSectionProps) => {
27
+
const { source, setSource } = useMigration();
28
+
29
+
// Resolve state
30
+
const [identifier, setIdentifier] = createSignal('');
31
+
const [resolveError, setResolveError] = createSignal<string>();
32
+
33
+
// Auth state
34
+
const [password, setPassword] = createSignal('');
35
+
const [otp, setOtp] = createSignal('');
36
+
const [isTotpRequired, setIsTotpRequired] = createSignal(false);
37
+
const [authError, setAuthError] = createSignal<string>();
38
+
39
+
const resolveMutation = createMutation({
40
+
async mutationFn({ identifier }: { identifier: string }) {
41
+
let did: AtprotoDid;
42
+
if (isAtprotoDid(identifier)) {
43
+
did = identifier;
44
+
} else if (isHandle(identifier)) {
45
+
did = await resolveHandleViaAppView({ handle: identifier });
46
+
} else {
47
+
throw new Error(`${identifier} is not a valid DID or handle`);
48
+
}
49
+
50
+
const didDoc = await getDidDocument({ did });
51
+
const pdsUrl = getPdsEndpoint(didDoc);
52
+
53
+
if (!pdsUrl) {
54
+
throw new Error(`No PDS endpoint found in DID document`);
55
+
}
56
+
57
+
return { did, didDoc, pdsUrl };
58
+
},
59
+
onMutate() {
60
+
setResolveError();
61
+
},
62
+
onSuccess({ did, didDoc, pdsUrl }) {
63
+
setSource({ did, didDoc, pdsUrl, manager: null });
64
+
props.onStarted?.();
65
+
},
66
+
onError(err) {
67
+
if (err instanceof ClientResponseError) {
68
+
if (err.error === 'InvalidRequest' && err.description?.includes('resolve handle')) {
69
+
setResolveError(`Can't resolve handle, is it typed correctly?`);
70
+
return;
71
+
}
72
+
}
73
+
console.error(err);
74
+
setResolveError(`${err}`);
75
+
},
76
+
});
77
+
78
+
const authMutation = createMutation({
79
+
async mutationFn({ pdsUrl, did, password, otp }: { pdsUrl: string; did: string; password: string; otp: string }) {
80
+
const manager = new CredentialManager({ service: pdsUrl });
81
+
const session = await manager.login({
82
+
identifier: did,
83
+
password: password,
84
+
code: formatTotpCode(otp),
85
+
});
86
+
87
+
const decoded = decodeJwt(session.accessJwt) as AtpAccessJwt;
88
+
if (decoded.scope !== 'com.atproto.access') {
89
+
throw new InsufficientLoginError(`You need to sign in with a main password, not an app password`);
90
+
}
91
+
92
+
return manager;
93
+
},
94
+
onMutate() {
95
+
setAuthError();
96
+
},
97
+
onSuccess(manager) {
98
+
setSource({ ...source()!, manager });
99
+
setPassword('');
100
+
setOtp('');
101
+
setIsTotpRequired(false);
102
+
},
103
+
onError(err) {
104
+
if (err instanceof ClientResponseError) {
105
+
if (err.error === 'AuthFactorTokenRequired') {
106
+
setOtp('');
107
+
setIsTotpRequired(true);
108
+
return;
109
+
}
110
+
if (err.error === 'AuthenticationRequired') {
111
+
setAuthError(`Invalid identifier or password`);
112
+
return;
113
+
}
114
+
if (err.error === 'AccountTakedown') {
115
+
setAuthError(`Account has been taken down`);
116
+
return;
117
+
}
118
+
if (err.description?.includes('Token is invalid')) {
119
+
setAuthError(`Invalid one-time confirmation code`);
120
+
setIsTotpRequired(true);
121
+
return;
122
+
}
123
+
}
124
+
if (err instanceof InsufficientLoginError) {
125
+
setAuthError(err.message);
126
+
return;
127
+
}
128
+
console.error(err);
129
+
setAuthError(`${err}`);
130
+
},
131
+
});
132
+
133
+
const isResolved = () => source() !== null;
134
+
const isAuthenticated = () => source()?.manager != null;
135
+
136
+
return (
137
+
<Accordion title="Source Account" defaultOpen>
138
+
<Subsection title="Resolve identity">
139
+
<Show when={!isResolved()}>
140
+
<form
141
+
onSubmit={(ev) => {
142
+
ev.preventDefault();
143
+
resolveMutation.mutate({ identifier: identifier() });
144
+
}}
145
+
class="flex flex-col gap-3"
146
+
>
147
+
<TextInput
148
+
label="Handle or DID"
149
+
placeholder="alice.bsky.social"
150
+
value={identifier()}
151
+
required
152
+
autofocus
153
+
onChange={setIdentifier}
154
+
/>
155
+
156
+
<Show when={resolveError()}>
157
+
<p class="text-sm text-red-600">{resolveError()}</p>
158
+
</Show>
159
+
160
+
<div>
161
+
<Button type="submit" disabled={resolveMutation.isPending}>
162
+
{resolveMutation.isPending ? 'Resolving...' : 'Resolve'}
163
+
</Button>
164
+
</div>
165
+
</form>
166
+
</Show>
167
+
168
+
<Show when={isResolved()}>
169
+
<div class="flex flex-col gap-2 text-sm">
170
+
<p>
171
+
<span class="text-gray-500">DID:</span>{' '}
172
+
<span class="font-mono">{source()!.did}</span>
173
+
</p>
174
+
<p>
175
+
<span class="text-gray-500">PDS:</span>{' '}
176
+
<span class="font-mono">{source()!.pdsUrl}</span>
177
+
</p>
178
+
<div class="mt-1">
179
+
<button
180
+
type="button"
181
+
onClick={() => setSource(null)}
182
+
class="text-sm text-purple-800 hover:underline"
183
+
>
184
+
Change account
185
+
</button>
186
+
</div>
187
+
</div>
188
+
</Show>
189
+
</Subsection>
190
+
191
+
<Show when={isResolved()}>
192
+
<Subsection title="Authenticate">
193
+
<p class="text-sm text-gray-600">
194
+
Authentication is required for some operations like exporting preferences or signing PLC operations.
195
+
</p>
196
+
197
+
<Show when={!isAuthenticated()}>
198
+
<form
199
+
onSubmit={(ev) => {
200
+
ev.preventDefault();
201
+
const src = source()!;
202
+
authMutation.mutate({
203
+
pdsUrl: src.pdsUrl,
204
+
did: src.did,
205
+
password: password(),
206
+
otp: otp(),
207
+
});
208
+
}}
209
+
class="flex flex-col gap-3"
210
+
>
211
+
<TextInput
212
+
label="Main password"
213
+
blurb="Your credentials stay entirely within your browser."
214
+
type="password"
215
+
value={password()}
216
+
required
217
+
onChange={setPassword}
218
+
/>
219
+
220
+
<Show when={isTotpRequired()}>
221
+
<TextInput
222
+
label="One-time confirmation code"
223
+
blurb="A code has been sent to your email address."
224
+
type="text"
225
+
autocomplete="one-time-code"
226
+
pattern={TOTP_RE.source}
227
+
placeholder="AAAAA-BBBBB"
228
+
value={otp()}
229
+
required
230
+
onChange={setOtp}
231
+
monospace
232
+
/>
233
+
</Show>
234
+
235
+
<Show when={authError()}>
236
+
<p class="text-sm text-red-600">{authError()}</p>
237
+
</Show>
238
+
239
+
<div>
240
+
<Button type="submit" disabled={authMutation.isPending}>
241
+
{authMutation.isPending ? 'Signing in...' : 'Sign in'}
242
+
</Button>
243
+
</div>
244
+
</form>
245
+
</Show>
246
+
247
+
<Show when={isAuthenticated()}>
248
+
<div class="flex items-center gap-2">
249
+
<StatusBadge variant="success">Signed in</StatusBadge>
250
+
<button
251
+
type="button"
252
+
onClick={() => setSource({ ...source()!, manager: null })}
253
+
class="text-sm text-purple-800 hover:underline"
254
+
>
255
+
Sign out
256
+
</button>
257
+
</div>
258
+
</Show>
259
+
</Subsection>
260
+
</Show>
261
+
</Accordion>
262
+
);
263
+
};
264
+
265
+
export default SourceAccountSection;
+2
-5
src/views/blob/blob-export.tsx
+2
-5
src/views/blob/blob-export.tsx
···
17
17
import Button from '~/components/inputs/button';
18
18
import TextInput from '~/components/inputs/text-input';
19
19
import Logger, { createLogger } from '~/components/logger';
20
+
import PageHeader from '~/components/page-header';
20
21
21
22
const BlobExportPage = () => {
22
23
const logger = createLogger();
···
229
230
230
231
return (
231
232
<>
232
-
<div class="p-4">
233
-
<h1 class="text-lg font-bold text-purple-800">Export blobs</h1>
234
-
<p class="text-gray-600">Download all blobs from an account into a tarball</p>
235
-
</div>
236
-
<hr class="mx-4 border-gray-300" />
233
+
<PageHeader title="Export blobs" subtitle="Download all blobs from an account into a tarball" />
237
234
238
235
<form
239
236
onSubmit={(ev) => {
+8
-9
src/views/bluesky/threadgate-applicator/page.tsx
+8
-9
src/views/bluesky/threadgate-applicator/page.tsx
···
2
2
3
3
import { AppBskyFeedDefs, AppBskyFeedThreadgate } from '@atcute/bluesky';
4
4
import { CredentialManager } from '@atcute/client';
5
-
import { DidDocument } from '@atcute/identity';
5
+
import type { DidDocument } from '@atcute/identity';
6
6
7
-
import { UnwrapArray } from '~/api/utils/types';
7
+
import type { UnwrapArray } from '~/api/utils/types';
8
8
9
9
import { history } from '~/globals/navigation';
10
10
11
11
import { useTitle } from '~/lib/navigation/router';
12
12
13
+
import PageHeader from '~/components/page-header';
13
14
import { Wizard } from '~/components/wizard';
14
15
15
16
import Step1_HandleInput from './steps/step1_handle-input';
···
18
19
import Step4_Confirmation from './steps/step4_confirmation';
19
20
import Step5_Finished from './steps/step5_finished';
20
21
21
-
export interface ThreadgateState
22
-
extends Pick<AppBskyFeedThreadgate.Main, 'allow' | 'hiddenReplies' | 'createdAt'> {
22
+
export interface ThreadgateState extends Pick<
23
+
AppBskyFeedThreadgate.Main,
24
+
'allow' | 'hiddenReplies' | 'createdAt'
25
+
> {
23
26
uri: string;
24
27
}
25
28
···
78
81
79
82
return (
80
83
<>
81
-
<div class="p-4">
82
-
<h1 class="text-lg font-bold text-purple-800">Retroactive thread gating</h1>
83
-
<p class="text-gray-600">Set reply permissions on all of your past Bluesky posts</p>
84
-
</div>
85
-
<hr class="mx-4 border-gray-300" />
84
+
<PageHeader title="Retroactive thread gating" subtitle="Set reply permissions on all of your past Bluesky posts" />
86
85
87
86
<Wizard<ThreadgateApplicatorConstraints>
88
87
initialStep="Step1_HandleInput"
+2
-2
src/views/bluesky/threadgate-applicator/steps/step1_handle-input.tsx
+2
-2
src/views/bluesky/threadgate-applicator/steps/step1_handle-input.tsx
···
14
14
15
15
import Button from '~/components/inputs/button';
16
16
import TextInput from '~/components/inputs/text-input';
17
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
17
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
18
18
19
-
import { ThreadgateApplicatorConstraints, ThreadgateState, ThreadItem } from '../page';
19
+
import type { ThreadgateApplicatorConstraints, ThreadgateState, ThreadItem } from '../page';
20
20
import { sortThreadgateState } from '../utils';
21
21
22
22
class NoThreadsError extends Error {}
+3
-10
src/views/bluesky/threadgate-applicator/steps/step2_rules-input.tsx
+3
-10
src/views/bluesky/threadgate-applicator/steps/step2_rules-input.tsx
···
2
2
3
3
import { AppBskyFeedThreadgate } from '@atcute/bluesky';
4
4
import { ok } from '@atcute/client';
5
-
import { $type } from '@atcute/lexicons';
5
+
import type { $type } from '@atcute/lexicons';
6
6
7
7
import { appViewRpc } from '~/globals/rpc';
8
8
···
11
11
import { createQuery } from '~/lib/utils/query';
12
12
13
13
import RadioInput from '~/components/inputs/radio-input';
14
-
import { Stage, StageActions, WizardStepProps } from '~/components/wizard';
14
+
import { Stage, StageActions, type WizardStepProps } from '~/components/wizard';
15
15
16
16
import CircularProgressView from '~/components/circular-progress-view';
17
17
import Button from '~/components/inputs/button';
18
18
import ToggleInput from '~/components/inputs/toggle-input';
19
19
20
-
import { ThreadgateApplicatorConstraints, ThreadgateRule } from '../page';
20
+
import type { ThreadgateApplicatorConstraints, ThreadgateRule } from '../page';
21
21
import { sortThreadgateAllow } from '../utils';
22
22
23
23
const enum FilterType {
···
255
255
blurb={
256
256
<>
257
257
<span>This will apply to {filteredThreads().length} threads. </span>
258
-
{/* <button
259
-
type="button"
260
-
hidden={filteredThreads().length < 1}
261
-
class="font-medium text-purple-800 hover:underline"
262
-
>
263
-
View
264
-
</button> */}
265
258
</>
266
259
}
267
260
value={filter()}
+2
-2
src/views/bluesky/threadgate-applicator/steps/step3_authentication.tsx
+2
-2
src/views/bluesky/threadgate-applicator/steps/step3_authentication.tsx
···
2
2
3
3
import { CredentialManager } from '@atcute/client';
4
4
5
-
import { WizardStepProps } from '~/components/wizard';
5
+
import type { WizardStepProps } from '~/components/wizard';
6
6
import BlueskyLoginStep from '~/components/wizards/bluesky-login-step';
7
7
8
-
import { ThreadgateApplicatorConstraints } from '../page';
8
+
import type { ThreadgateApplicatorConstraints } from '../page';
9
9
10
10
const Step3_Authentication = ({
11
11
data,
+4
-5
src/views/bluesky/threadgate-applicator/steps/step4_confirmation.tsx
+4
-5
src/views/bluesky/threadgate-applicator/steps/step4_confirmation.tsx
···
3
3
import type { ComAtprotoRepoApplyWrites } from '@atcute/atproto';
4
4
import type { AppBskyFeedThreadgate } from '@atcute/bluesky';
5
5
import { Client, ClientResponseError } from '@atcute/client';
6
-
import { InferXRPCBodyInput } from '@atcute/lexicons';
6
+
import { parseCanonicalResourceUri } from '@atcute/lexicons';
7
7
import { chunked } from '@mary/array-fns';
8
-
import { parseCanonicalResourceUri } from '@atcute/lexicons';
9
8
10
9
import { dequal } from '~/lib/utils/dequal';
11
10
import { createMutation } from '~/lib/utils/mutation';
···
13
12
import Button from '~/components/inputs/button';
14
13
import ToggleInput from '~/components/inputs/toggle-input';
15
14
import Logger, { createLogger } from '~/components/logger';
16
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
15
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
17
16
18
-
import { ThreadgateApplicatorConstraints } from '../page';
17
+
import type { ThreadgateApplicatorConstraints } from '../page';
19
18
20
19
const Step4_Confirmation = ({
21
20
data,
···
35
34
logger.log(`Preparing writes`);
36
35
37
36
const rules = data.rules;
38
-
const writes: InferXRPCBodyInput<ComAtprotoRepoApplyWrites.mainSchema['input']>['writes'] = [];
37
+
const writes: ComAtprotoRepoApplyWrites.$input['writes'] = [];
39
38
40
39
const now = new Date().toISOString();
41
40
for (const { post, threadgate } of data.threads) {
+2
-2
src/views/bluesky/threadgate-applicator/steps/step5_finished.tsx
+2
-2
src/views/bluesky/threadgate-applicator/steps/step5_finished.tsx
···
1
-
import { Stage, WizardStepProps } from '~/components/wizard';
1
+
import { Stage, type WizardStepProps } from '~/components/wizard';
2
2
3
-
import { ThreadgateApplicatorConstraints } from '../page';
3
+
import type { ThreadgateApplicatorConstraints } from '../page';
4
4
5
5
export const Step5_Finished = ({}: WizardStepProps<ThreadgateApplicatorConstraints, 'Step5_Finished'>) => {
6
6
return (
+1
-1
src/views/bluesky/threadgate-applicator/utils.ts
+1
-1
src/views/bluesky/threadgate-applicator/utils.ts
+3
-6
src/views/crypto/crypto-generate.tsx
+3
-6
src/views/crypto/crypto-generate.tsx
···
6
6
7
7
import Button from '~/components/inputs/button';
8
8
import RadioInput from '~/components/inputs/radio-input';
9
+
import PageHeader from '~/components/page-header';
9
10
10
11
type KeyType = 'p256' | 'secp256k1';
11
12
···
26
27
27
28
return (
28
29
<>
29
-
<div class="p-4">
30
-
<h1 class="text-lg font-bold text-purple-800">Generate secret keys</h1>
31
-
<p class="text-gray-600">Create a new secp256k1/nistp256 keypair</p>
32
-
</div>
33
-
<hr class="mx-4 border-gray-300" />
30
+
<PageHeader title="Generate secret keys" subtitle="Create a new secp256k1/nistp256 keypair" />
34
31
35
32
<form
36
33
onSubmit={async (ev) => {
···
54
51
]);
55
52
56
53
const result: KeypairResult = {
57
-
type: keypair.type,
54
+
type: keypair.type as KeyType,
58
55
publicDidKey,
59
56
privateHex,
60
57
privateMultikey,
+255
src/views/crypto/crypto-info.tsx
+255
src/views/crypto/crypto-info.tsx
···
1
+
import { createMemo, createSignal, Match, Show, Switch } from 'solid-js';
2
+
3
+
import {
4
+
type DidKeyString,
5
+
P256PrivateKeyExportable,
6
+
P256PublicKey,
7
+
parseDidKey,
8
+
parsePrivateMultikey,
9
+
parsePublicMultikey,
10
+
Secp256k1PrivateKeyExportable,
11
+
Secp256k1PublicKey,
12
+
} from '@atcute/crypto';
13
+
import { fromBase16 } from '@atcute/multibase';
14
+
15
+
import { useTitle } from '~/lib/navigation/router';
16
+
17
+
import Button from '~/components/inputs/button';
18
+
import RadioInput from '~/components/inputs/radio-input';
19
+
import TextInput from '~/components/inputs/text-input';
20
+
import PageHeader from '~/components/page-header';
21
+
22
+
type KeyType = 'p256' | 'secp256k1';
23
+
type KeyFormat = 'did:key' | 'multikey' | 'hex';
24
+
25
+
interface KeyInfo {
26
+
keyType: KeyType;
27
+
isPrivate: boolean;
28
+
inputFormat: KeyFormat;
29
+
publicDidKey: DidKeyString;
30
+
publicMultikey: string;
31
+
privateHex?: string;
32
+
privateMultikey?: string;
33
+
}
34
+
35
+
const DID_KEY_REGEX = /^did:key:z[a-km-zA-HJ-NP-Z1-9]+$/;
36
+
const MULTIKEY_REGEX = /^z[a-km-zA-HJ-NP-Z1-9]+$/;
37
+
const HEX_REGEX = /^[0-9a-f]+$/;
38
+
39
+
const CryptoInfoPage = () => {
40
+
const [input, setInput] = createSignal('');
41
+
const [hexKeyType, setHexKeyType] = createSignal<KeyType>();
42
+
const [result, setResult] = createSignal<KeyInfo>();
43
+
const [error, setError] = createSignal<string>();
44
+
45
+
const detectedFormat = createMemo((): KeyFormat | undefined => {
46
+
const $input = input().trim();
47
+
48
+
if (DID_KEY_REGEX.test($input)) {
49
+
return 'did:key';
50
+
}
51
+
if (MULTIKEY_REGEX.test($input)) {
52
+
return 'multikey';
53
+
}
54
+
if (HEX_REGEX.test($input)) {
55
+
return 'hex';
56
+
}
57
+
});
58
+
59
+
const canSubmit = createMemo(() => {
60
+
const format = detectedFormat();
61
+
if (!format) {
62
+
return false;
63
+
}
64
+
if (format === 'hex' && !hexKeyType()) {
65
+
return false;
66
+
}
67
+
return true;
68
+
});
69
+
70
+
useTitle(() => `View crypto key info โ boat`);
71
+
72
+
return (
73
+
<>
74
+
<PageHeader title="View crypto key info" subtitle="Show basic metadata about a public or private key" />
75
+
76
+
<form
77
+
onSubmit={async (ev) => {
78
+
ev.preventDefault();
79
+
80
+
const $input = input().trim();
81
+
const format = detectedFormat();
82
+
83
+
setResult();
84
+
setError();
85
+
86
+
try {
87
+
let info: KeyInfo;
88
+
89
+
if (format === 'did:key') {
90
+
const parsed = parseDidKey($input);
91
+
const pubKey =
92
+
parsed.type === 'p256'
93
+
? await P256PublicKey.importRaw(parsed.publicKeyBytes)
94
+
: await Secp256k1PublicKey.importRaw(parsed.publicKeyBytes);
95
+
96
+
info = {
97
+
keyType: parsed.type,
98
+
isPrivate: false,
99
+
inputFormat: 'did:key',
100
+
publicDidKey: await pubKey.exportPublicKey('did'),
101
+
publicMultikey: await pubKey.exportPublicKey('multikey'),
102
+
};
103
+
} else if (format === 'multikey') {
104
+
// try parsing as private key first
105
+
try {
106
+
const parsed = parsePrivateMultikey($input);
107
+
const privKey =
108
+
parsed.type === 'p256'
109
+
? await P256PrivateKeyExportable.importRaw(parsed.privateKeyBytes)
110
+
: await Secp256k1PrivateKeyExportable.importRaw(parsed.privateKeyBytes);
111
+
112
+
info = {
113
+
keyType: parsed.type,
114
+
isPrivate: true,
115
+
inputFormat: 'multikey',
116
+
publicDidKey: await privKey.exportPublicKey('did'),
117
+
publicMultikey: await privKey.exportPublicKey('multikey'),
118
+
privateHex: await privKey.exportPrivateKey('rawHex'),
119
+
privateMultikey: await privKey.exportPrivateKey('multikey'),
120
+
};
121
+
} catch {
122
+
// try parsing as public key
123
+
const parsed = parsePublicMultikey($input);
124
+
const pubKey =
125
+
parsed.type === 'p256'
126
+
? await P256PublicKey.importRaw(parsed.publicKeyBytes)
127
+
: await Secp256k1PublicKey.importRaw(parsed.publicKeyBytes);
128
+
129
+
info = {
130
+
keyType: parsed.type,
131
+
isPrivate: false,
132
+
inputFormat: 'multikey',
133
+
publicDidKey: await pubKey.exportPublicKey('did'),
134
+
publicMultikey: await pubKey.exportPublicKey('multikey'),
135
+
};
136
+
}
137
+
} else if (format === 'hex') {
138
+
const keyType = hexKeyType()!;
139
+
const privateKeyBytes = fromBase16($input);
140
+
141
+
const privKey =
142
+
keyType === 'p256'
143
+
? await P256PrivateKeyExportable.importRaw(privateKeyBytes)
144
+
: await Secp256k1PrivateKeyExportable.importRaw(privateKeyBytes);
145
+
146
+
info = {
147
+
keyType: keyType,
148
+
isPrivate: true,
149
+
inputFormat: 'hex',
150
+
publicDidKey: await privKey.exportPublicKey('did'),
151
+
publicMultikey: await privKey.exportPublicKey('multikey'),
152
+
privateHex: await privKey.exportPrivateKey('rawHex'),
153
+
privateMultikey: await privKey.exportPrivateKey('multikey'),
154
+
};
155
+
} else {
156
+
throw new Error('Unknown key format');
157
+
}
158
+
159
+
setResult(info);
160
+
} catch (err) {
161
+
console.error(err);
162
+
setError(`Failed to parse key: ${err}`);
163
+
}
164
+
}}
165
+
class="flex flex-col gap-4 p-4"
166
+
>
167
+
<TextInput
168
+
label="Public or private key"
169
+
blurb="Accepts did:key, multikey, or hex format"
170
+
monospace
171
+
autocomplete="off"
172
+
autocorrect="off"
173
+
placeholder="did:key:z... or z... or a5973930f9d348..."
174
+
value={input()}
175
+
required
176
+
onChange={setInput}
177
+
/>
178
+
179
+
<Show when={detectedFormat() === 'hex'}>
180
+
<RadioInput
181
+
label="This is a..."
182
+
value={hexKeyType()}
183
+
required
184
+
options={[
185
+
{ value: 'secp256k1', label: `ES256K (secp256k1) private key` },
186
+
{ value: 'p256', label: `ES256 (p256) private key` },
187
+
]}
188
+
onChange={setHexKeyType}
189
+
/>
190
+
</Show>
191
+
192
+
<div>
193
+
<Button type="submit" disabled={!canSubmit()}>
194
+
Inspect
195
+
</Button>
196
+
</div>
197
+
</form>
198
+
199
+
<hr class="mx-4 border-gray-300" />
200
+
201
+
<Switch>
202
+
<Match when={error()}>
203
+
<div class="p-4 text-red-600">{error()}</div>
204
+
</Match>
205
+
206
+
<Match when={result()} keyed>
207
+
{(info) => (
208
+
<div class="flex flex-col gap-6 break-words p-4 text-gray-900">
209
+
<div>
210
+
<p class="font-semibold text-gray-600">Key type</p>
211
+
<span>
212
+
{/* @once */ info.keyType === 'p256'
213
+
? 'ES256 (p256)'
214
+
: 'ES256K (secp256k1)'}{' '}
215
+
{/* @once */ info.isPrivate ? 'private' : 'public'} key
216
+
</span>
217
+
</div>
218
+
219
+
<div>
220
+
<p class="font-semibold text-gray-600">Input encoding</p>
221
+
<span>{/* @once */ info.inputFormat}</span>
222
+
</div>
223
+
224
+
<div>
225
+
<p class="font-semibold text-gray-600">Public key (did:key)</p>
226
+
<span class="font-mono">{/* @once */ info.publicDidKey}</span>
227
+
</div>
228
+
229
+
<div>
230
+
<p class="font-semibold text-gray-600">Public key (multikey)</p>
231
+
<span class="font-mono">{/* @once */ info.publicMultikey}</span>
232
+
</div>
233
+
234
+
<Show when={info.privateHex}>
235
+
<div>
236
+
<p class="font-semibold text-gray-600">Private key (hex)</p>
237
+
<span class="font-mono">{/* @once */ info.privateHex}</span>
238
+
</div>
239
+
</Show>
240
+
241
+
<Show when={info.privateMultikey}>
242
+
<div>
243
+
<p class="font-semibold text-gray-600">Private key (multikey)</p>
244
+
<span class="font-mono">{/* @once */ info.privateMultikey}</span>
245
+
</div>
246
+
</Show>
247
+
</div>
248
+
)}
249
+
</Match>
250
+
</Switch>
251
+
</>
252
+
);
253
+
};
254
+
255
+
export default CryptoInfoPage;
+6
-8
src/views/frontpage.tsx
+6
-8
src/views/frontpage.tsx
···
1
-
import { Component, ComponentProps } from 'solid-js';
1
+
import type { Component, ComponentProps } from 'solid-js';
2
2
3
3
import { useTitle } from '~/lib/navigation/router';
4
+
5
+
import PageHeader from '~/components/page-header';
4
6
5
7
import HistoryIcon from '~/components/ic-icons/baseline-history';
6
8
import KeyIcon from '~/components/ic-icons/baseline-key';
···
102
104
{
103
105
name: `Migrate account`,
104
106
description: `Move your account data to another server`,
105
-
href: null,
107
+
href: '/account-migrate',
106
108
icon: MoveUpOutlinedIcon,
107
109
},
108
110
],
···
119
121
{
120
122
name: `View crypto key info`,
121
123
description: `Show basic metadata about a public or private key`,
122
-
href: null,
124
+
href: `/crypto-info`,
123
125
icon: KeyVisualizerIcon,
124
126
},
125
127
],
···
170
172
171
173
return (
172
174
<>
173
-
<div class="p-4">
174
-
<h1 class="text-lg font-bold text-purple-800">boat</h1>
175
-
<p class="text-gray-600">handy online tools for AT Protocol</p>
176
-
</div>
177
-
<hr class="mx-4 border-gray-300" />
175
+
<PageHeader title="boat" subtitle="handy online tools for AT Protocol" />
178
176
179
177
<div class="flex grow flex-col pb-2">{nodes}</div>
180
178
+18
-29
src/views/identity/did-lookup.tsx
+18
-29
src/views/identity/did-lookup.tsx
···
15
15
import ErrorView from '~/components/error-view';
16
16
import Button from '~/components/inputs/button';
17
17
import TextInput from '~/components/inputs/text-input';
18
+
import PageHeader from '~/components/page-header';
18
19
19
20
const DidLookupPage = () => {
20
21
const [params, setParams] = useSearchParams({
···
46
47
47
48
return (
48
49
<>
49
-
<div class="p-4">
50
-
<h1 class="text-lg font-bold text-purple-800">View identity info</h1>
51
-
<p class="text-gray-600">Look up an account's DID document</p>
52
-
</div>
53
-
<hr class="mx-4 border-gray-300" />
50
+
<PageHeader title="View identity info" subtitle="Look up an account's DID document" />
54
51
55
52
<form
56
53
onSubmit={(ev) => {
···
100
97
101
98
<div>
102
99
<p class="font-semibold text-gray-600">Identifies as</p>
103
-
<ol class="list-disc pl-4">{doc.alsoKnownAs?.map((ident) => <li>{ident}</li>)}</ol>
100
+
<ol class="list-disc pl-4">
101
+
{doc.alsoKnownAs?.map((ident) => (
102
+
<li>{ident}</li>
103
+
))}
104
+
</ol>
104
105
</div>
105
106
106
107
<div>
···
129
130
130
131
<div class="mt-2 flex flex-wrap gap-2 empty:hidden">
131
132
{isPDS && isServiceUrl && (
132
-
<button
133
-
disabled
134
-
class="flex h-9 select-none items-center rounded border border-gray-300 px-4 text-sm font-semibold text-gray-800 hover:bg-gray-100 active:bg-gray-100 disabled:pointer-events-none disabled:opacity-50"
135
-
>
133
+
<Button variant="outline" disabled>
136
134
View PDS info
137
-
</button>
135
+
</Button>
138
136
)}
139
137
140
138
{isPDS && isServiceUrl && (
141
-
<button
142
-
disabled
143
-
class="flex h-9 select-none items-center rounded border border-gray-300 px-4 text-sm font-semibold text-gray-800 hover:bg-gray-100 active:bg-gray-100 disabled:pointer-events-none disabled:opacity-50"
144
-
>
139
+
<Button variant="outline" disabled>
145
140
Explore account repository
146
-
</button>
141
+
</Button>
147
142
)}
148
143
149
144
{isLabeler && isServiceUrl && (
150
-
<button
151
-
disabled
152
-
class="flex h-9 select-none items-center rounded border border-gray-300 px-4 text-sm font-semibold text-gray-800 hover:bg-gray-100 active:bg-gray-100 disabled:pointer-events-none disabled:opacity-50"
153
-
>
145
+
<Button variant="outline" disabled>
154
146
View emitted labels
155
-
</button>
147
+
</Button>
156
148
)}
157
149
</div>
158
150
</li>
···
181
173
</div>
182
174
183
175
<div class="flex flex-wrap gap-4 p-4 pt-2">
184
-
<button
176
+
<Button
177
+
variant="outline"
185
178
onClick={() => {
186
179
navigator.clipboard.writeText(JSON.stringify(doc, null, 2));
187
180
}}
188
-
class="flex h-9 select-none items-center rounded border border-gray-300 px-4 text-sm font-semibold text-gray-800 hover:bg-gray-100 active:bg-gray-100"
189
181
>
190
182
Copy DID document
191
-
</button>
183
+
</Button>
192
184
193
185
{isDidPlc && (
194
-
<a
195
-
href={`/plc-oplogs?q=${params.q!}`}
196
-
class="flex h-9 select-none items-center rounded border border-gray-300 px-4 text-sm font-semibold text-gray-800 hover:bg-gray-100 active:bg-gray-100"
197
-
>
186
+
<Button variant="outline" href={`/plc-oplogs?q=${params.q!}`}>
198
187
View PLC operation logs
199
-
</a>
188
+
</Button>
200
189
)}
201
190
</div>
202
191
</>
+4
-8
src/views/identity/plc-applicator/page.tsx
+4
-8
src/views/identity/plc-applicator/page.tsx
···
5
5
import type { P256PrivateKey, Secp256k1PrivateKey } from '@atcute/crypto';
6
6
import type { CompatibleOperation, IndexedEntry, IndexedEntryWithSigner } from '@atcute/did-plc';
7
7
import type { DidDocument } from '@atcute/identity';
8
-
import { InferXRPCBodyInput } from '@atcute/lexicons';
9
8
import type { Did } from '@atcute/lexicons/syntax';
10
9
11
-
import { UpdatePayload } from '~/api/types/plc';
10
+
import type { UpdatePayload } from '~/api/types/plc';
12
11
13
12
import { history } from '~/globals/navigation';
14
13
15
14
import { useTitle } from '~/lib/navigation/router';
16
15
16
+
import PageHeader from '~/components/page-header';
17
17
import { Wizard } from '~/components/wizard';
18
18
19
19
import Step1_HandleInput from './steps/step1_handle-input';
···
33
33
export interface PdsSigningMethod {
34
34
type: 'pds';
35
35
manager: CredentialManager;
36
-
recommendedDidDoc: InferXRPCBodyInput<ComAtprotoIdentityGetRecommendedDidCredentials.mainSchema['output']>;
36
+
recommendedDidDoc: ComAtprotoIdentityGetRecommendedDidCredentials.$output;
37
37
}
38
38
39
39
export type Keypair = P256PrivateKey | Secp256k1PrivateKey;
···
102
102
103
103
return (
104
104
<>
105
-
<div class="p-4">
106
-
<h1 class="text-lg font-bold text-purple-800">Apply PLC operations</h1>
107
-
<p class="text-gray-600">Submit operations to your did:plc identity</p>
108
-
</div>
109
-
<hr class="mx-4 border-gray-300" />
105
+
<PageHeader title="Apply PLC operations" subtitle="Submit operations to your did:plc identity" />
110
106
111
107
<Wizard<PlcApplicatorConstraints>
112
108
initialStep="Step1_HandleInput"
+1
-1
src/views/identity/plc-applicator/plc-utils.ts
+1
-1
src/views/identity/plc-applicator/plc-utils.ts
+4
-2
src/views/identity/plc-applicator/steps/step1_handle-input.tsx
+4
-2
src/views/identity/plc-applicator/steps/step1_handle-input.tsx
···
14
14
import Button from '~/components/inputs/button';
15
15
import RadioInput from '~/components/inputs/radio-input';
16
16
import TextInput from '~/components/inputs/text-input';
17
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
17
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
18
18
19
-
import { PlcApplicatorConstraints, type PlcInformation } from '../page';
19
+
import type { PlcApplicatorConstraints, PlcInformation } from '../page';
20
20
21
21
type Method = 'pds' | 'key';
22
22
···
84
84
if (message !== undefined) {
85
85
setError(message);
86
86
} else {
87
+
console.error(err);
88
+
87
89
setError(`Something went wrong: ${err}`);
88
90
}
89
91
},
+3
-3
src/views/identity/plc-applicator/steps/step2_pds-authentication.tsx
+3
-3
src/views/identity/plc-applicator/steps/step2_pds-authentication.tsx
···
1
1
import { createSignal, Match, Show, Switch } from 'solid-js';
2
2
3
-
import { AtpAccessJwt, Client, ClientResponseError, CredentialManager, ok } from '@atcute/client';
3
+
import { type AtpAccessJwt, Client, ClientResponseError, CredentialManager, ok } from '@atcute/client';
4
4
import { getPdsEndpoint } from '@atcute/identity';
5
5
6
6
import { formatTotpCode, TOTP_RE } from '~/api/utils/auth';
···
10
10
11
11
import Button from '~/components/inputs/button';
12
12
import TextInput from '~/components/inputs/text-input';
13
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
13
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
14
14
15
-
import { PlcApplicatorConstraints } from '../page';
15
+
import type { PlcApplicatorConstraints } from '../page';
16
16
17
17
class InsufficientLoginError extends Error {}
18
18
+3
-9
src/views/identity/plc-applicator/steps/step2_private-key-input.tsx
+3
-9
src/views/identity/plc-applicator/steps/step2_private-key-input.tsx
···
8
8
import Button from '~/components/inputs/button';
9
9
import RadioInput from '~/components/inputs/radio-input';
10
10
import TextInput from '~/components/inputs/text-input';
11
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
11
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
12
12
13
13
import type { Keypair, PlcApplicatorConstraints, PrivateKeySigningMethod } from '../page';
14
14
···
97
97
});
98
98
},
99
99
onError(error) {
100
-
let message: string | undefined;
101
-
102
-
if (message !== undefined) {
103
-
setError(message);
104
-
} else {
105
-
console.error(error);
106
-
setError(`Something went wrong: ${error}`);
107
-
}
100
+
console.error(error);
101
+
setError(`Something went wrong: ${error}`);
108
102
},
109
103
});
110
104
+2
-2
src/views/identity/plc-applicator/steps/step3_operation-select.tsx
+2
-2
src/views/identity/plc-applicator/steps/step3_operation-select.tsx
···
12
12
import Button from '~/components/inputs/button';
13
13
import RadioInput from '~/components/inputs/radio-input';
14
14
import SelectInput from '~/components/inputs/select-input';
15
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
15
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
16
16
17
-
import { PlcApplicatorConstraints } from '../page';
17
+
import type { PlcApplicatorConstraints } from '../page';
18
18
19
19
const Step3_OperationSelect = ({
20
20
data,
+2
-2
src/views/identity/plc-applicator/steps/step4_payload-input.tsx
+2
-2
src/views/identity/plc-applicator/steps/step4_payload-input.tsx
···
4
4
5
5
import Button from '~/components/inputs/button';
6
6
import MultilineInput from '~/components/inputs/multiline-input';
7
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
7
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
8
8
9
-
import { PlcApplicatorConstraints } from '../page';
9
+
import type { PlcApplicatorConstraints } from '../page';
10
10
import { getPlcPayload } from '../plc-utils';
11
11
12
12
export const Step4_PayloadInput = ({
+2
-2
src/views/identity/plc-applicator/steps/step5_pds-confirmation.tsx
+2
-2
src/views/identity/plc-applicator/steps/step5_pds-confirmation.tsx
···
9
9
import CheckIcon from '~/components/ic-icons/baseline-check';
10
10
import Button from '~/components/inputs/button';
11
11
import TextInput from '~/components/inputs/text-input';
12
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
12
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
13
13
14
-
import { PlcApplicatorConstraints } from '../page';
14
+
import type { PlcApplicatorConstraints } from '../page';
15
15
16
16
export const Step5_PdsConfirmation = ({
17
17
data,
+5
-6
src/views/identity/plc-applicator/steps/step5_private-key-confirmation.tsx
+5
-6
src/views/identity/plc-applicator/steps/step5_private-key-confirmation.tsx
···
9
9
10
10
import Button from '~/components/inputs/button';
11
11
import TextInput from '~/components/inputs/text-input';
12
-
import { Stage, StageActions, StageErrorView, WizardStepProps } from '~/components/wizard';
12
+
import { Stage, StageActions, StageErrorView, type WizardStepProps } from '~/components/wizard';
13
13
14
-
import { PlcApplicatorConstraints } from '../page';
14
+
import type { PlcApplicatorConstraints } from '../page';
15
15
16
16
const Step5_PrivateKeyConfirmation = ({
17
17
data,
···
78
78
}}
79
79
>
80
80
<p class="text-pretty">
81
-
To continue with this submission, type in the following code{' '}
82
-
<code class="whitespace-nowrap font-bold">{code}</code> to the confirmation box below.
81
+
To continue with this submission, type in <code class="whitespace-nowrap font-bold">{code}</code> to
82
+
the confirmation box below.
83
83
</p>
84
84
85
85
<TextInput
86
-
label="Confirmation code"
86
+
label="Confirmation"
87
87
type="text"
88
88
autocomplete="one-time-code"
89
89
autocorrect="off"
90
90
required
91
91
pattern={code}
92
-
placeholder="AAAAA-BBBBB"
93
92
autofocus={isActive()}
94
93
monospace
95
94
/>
+2
-2
src/views/identity/plc-applicator/steps/step6_finished.tsx
+2
-2
src/views/identity/plc-applicator/steps/step6_finished.tsx
···
1
-
import { Stage, WizardStepProps } from '~/components/wizard';
1
+
import { Stage, type WizardStepProps } from '~/components/wizard';
2
2
3
-
import { PlcApplicatorConstraints } from '../page';
3
+
import type { PlcApplicatorConstraints } from '../page';
4
4
5
5
export const Step6_Finished = ({}: WizardStepProps<PlcApplicatorConstraints, 'Step6_Finished'>) => {
6
6
return (
+3
-6
src/views/identity/plc-oplogs.tsx
+3
-6
src/views/identity/plc-oplogs.tsx
···
1
-
import { createSignal, JSX, Match, onCleanup, Switch } from 'solid-js';
1
+
import { createSignal, Match, onCleanup, Switch, type JSX } from 'solid-js';
2
2
3
3
import type { IndexedEntry, Service } from '@atcute/did-plc';
4
4
import { isPlcDid } from '@atcute/identity';
···
20
20
import ContentCopyIcon from '~/components/ic-icons/baseline-content-copy';
21
21
import Button from '~/components/inputs/button';
22
22
import TextInput from '~/components/inputs/text-input';
23
+
import PageHeader from '~/components/page-header';
23
24
24
25
const PlcOperationLogPage = () => {
25
26
const [params, setParams] = useSearchParams({
···
55
56
56
57
return (
57
58
<>
58
-
<div class="p-4">
59
-
<h1 class="text-lg font-bold text-purple-800">View PLC operation logs</h1>
60
-
<p class="text-gray-600">Show history of a did:plc identity</p>
61
-
</div>
62
-
<hr class="mx-4 border-gray-300" />
59
+
<PageHeader title="View PLC operation logs" subtitle="Show history of a did:plc identity" />
63
60
64
61
<form
65
62
onSubmit={(ev) => {
+4
-5
src/views/repository/repo-archive-explore/page.tsx
+4
-5
src/views/repository/repo-archive-explore/page.tsx
···
1
1
import { Match, Switch } from 'solid-js';
2
2
3
-
import { RepoReader } from '@atcute/car/v4';
3
+
import { fromStream } from '@atcute/repo';
4
4
5
5
import { createMutation } from '~/lib/utils/mutation';
6
6
7
+
import type { Archive, RecordEntry } from './types';
8
+
import ExploreView from './views/explore';
7
9
import WelcomeView from './views/welcome';
8
10
9
-
import { Archive, RecordEntry } from './types';
10
-
import ExploreView from './views/explore';
11
-
12
11
const ArchiveExplorePage = () => {
13
12
const mutation = createMutation({
14
13
async mutationFn({ file }: { file: File }): Promise<Archive> {
15
14
const stream = file.stream();
16
-
await using repo = RepoReader.fromStream(stream);
15
+
await using repo = fromStream(stream);
17
16
18
17
const collections = new Map<string, RecordEntry[]>();
19
18
const archive: Archive = {
+1
-1
src/views/repository/repo-archive-explore/views/explore/record.tsx
+1
-1
src/views/repository/repo-archive-explore/views/explore/record.tsx
+9
-42
src/views/repository/repo-archive-explore/views/welcome.tsx
+9
-42
src/views/repository/repo-archive-explore/views/welcome.tsx
···
3
3
import type { MutationReturn } from '~/lib/utils/mutation';
4
4
5
5
import CircularProgress from '~/components/circular-progress';
6
+
import FileDropZone from '~/components/file-drop-zone';
7
+
import PageHeader from '~/components/page-header';
6
8
7
-
import { Archive } from '../types';
8
-
import { createDropZone } from '~/lib/hooks/dropzone';
9
+
import type { Archive } from '../types';
9
10
10
11
interface WelcomeViewProps {
11
12
mutation: MutationReturn<Archive, { file: File }>;
12
13
}
13
14
14
15
const WelcomeView = ({ mutation }: WelcomeViewProps) => {
15
-
const { ref: dropRef, isDropping } = createDropZone({
16
-
// Checked, the mime type for CAR files is blank.
17
-
dataTypes: [''],
18
-
multiple: false,
19
-
onDrop(files) {
20
-
if (files) {
21
-
mutation.mutate({ file: files[0] });
22
-
}
23
-
},
24
-
});
25
-
26
16
return (
27
17
<>
28
-
<div class="p-4">
29
-
<h1 class="text-lg font-bold text-purple-800">Explore archive</h1>
30
-
<p class="text-gray-600">Explore a repository archive</p>
31
-
</div>
32
-
<hr class="mx-4 border-gray-300" />
18
+
<PageHeader title="Explore archive" subtitle="Explore a repository archive" />
33
19
34
20
<div class="flex flex-col gap-4 p-4">
35
-
<fieldset
36
-
ref={dropRef}
37
-
class={
38
-
`grid place-items-center rounded border border-gray-300 px-6 py-12 disabled:opacity-50` +
39
-
(!isDropping() ? ` bg-gray-100` : ` bg-green-100`)
40
-
}
21
+
<FileDropZone
22
+
accept=".car,application/vnd.ipld.car"
23
+
dataTypes={['']}
24
+
onFiles={(files) => mutation.mutate({ file: files[0] })}
41
25
>
42
-
<div class="flex flex-col items-center gap-4">
43
-
<button
44
-
onClick={() => {
45
-
const input = document.createElement('input');
46
-
input.type = 'file';
47
-
input.accept = '.car,application/vnd.ipld.car';
48
-
input.oninput = () => mutation.mutate({ file: input.files![0] });
49
-
50
-
input.click();
51
-
}}
52
-
class="flex h-9 select-none items-center rounded border border-gray-400 px-4 text-sm font-semibold text-gray-800 hover:bg-gray-200 active:bg-gray-200 disabled:pointer-events-none"
53
-
>
54
-
Browse files
55
-
</button>
56
-
<p class="select-none font-medium text-gray-600">or drop your file here</p>
57
-
</div>
58
-
59
26
<div
60
27
hidden={!mutation.isPending}
61
28
class="absolute inset-0 flex flex-col items-center justify-center gap-3 bg-gray-50"
···
63
30
<CircularProgress />
64
31
<span class="font-medium">Reading CAR file</span>
65
32
</div>
66
-
</fieldset>
33
+
</FileDropZone>
67
34
68
35
<Show when={mutation.error}>
69
36
<p class="whitespace-pre-wrap text-[0.8125rem] font-medium leading-5 text-red-800">
+10
-43
src/views/repository/repo-archive-unpack.tsx
+10
-43
src/views/repository/repo-archive-unpack.tsx
···
1
1
import { FileSystemWritableFileStream, showSaveFilePicker } from 'native-file-system-adapter';
2
2
import { createSignal } from 'solid-js';
3
3
4
-
import { RepoReader } from '@atcute/car/v4';
4
+
import { fromStream } from '@atcute/repo';
5
5
import { writeTarEntry } from '@mary/tar';
6
6
7
-
import { createDropZone } from '~/lib/hooks/dropzone';
8
7
import { useTitle } from '~/lib/navigation/router';
9
8
import { makeAbortable } from '~/lib/utils/abortable';
10
9
10
+
import FileDropZone from '~/components/file-drop-zone';
11
11
import Logger, { createLogger } from '~/components/logger';
12
+
import PageHeader from '~/components/page-header';
12
13
13
14
// @ts-expect-error: new API
14
15
const yieldToScheduler: () => Promise<void> = window?.scheduler?.yield
···
22
23
const [getSignal, cleanup] = makeAbortable();
23
24
const [pending, setPending] = createSignal(false);
24
25
25
-
const { ref: dropRef, isDropping } = createDropZone({
26
-
// Checked, the mime type for CAR files is blank.
27
-
dataTypes: [''],
28
-
multiple: false,
29
-
onDrop(files) {
30
-
if (files) {
31
-
onFileDrop(files);
32
-
}
33
-
},
34
-
});
35
-
36
26
const mutate = async (file: File, signal: AbortSignal) => {
37
27
logger.log(`Starting extraction`);
38
28
39
29
const stream = file.stream();
40
-
await using repo = RepoReader.fromStream(stream);
30
+
await using repo = fromStream(stream);
41
31
42
32
let count = 0;
43
33
···
155
145
156
146
return (
157
147
<>
158
-
<div class="p-4">
159
-
<h1 class="text-lg font-bold text-purple-800">Unpack archive</h1>
160
-
<p class="text-gray-600">Extract a repository archive into a tarball</p>
161
-
</div>
162
-
<hr class="mx-4 border-gray-300" />
148
+
<PageHeader title="Unpack archive" subtitle="Extract a repository archive into a tarball" />
163
149
164
150
<div class="p-4">
165
-
<fieldset
166
-
ref={dropRef}
151
+
<FileDropZone
152
+
accept=".car,application/vnd.ipld.car"
153
+
dataTypes={['']}
167
154
disabled={pending()}
168
-
class={
169
-
`grid place-items-center rounded border border-gray-300 px-6 py-12 disabled:opacity-50` +
170
-
(pending() || !isDropping() ? ` bg-gray-100` : ` bg-green-100`)
171
-
}
172
-
>
173
-
<div class="flex flex-col items-center gap-4">
174
-
<button
175
-
onClick={() => {
176
-
const input = document.createElement('input');
177
-
input.type = 'file';
178
-
input.accept = '.car,application/vnd.ipld.car';
179
-
input.oninput = () => onFileDrop(Array.from(input.files!));
180
-
181
-
input.click();
182
-
}}
183
-
class="flex h-9 select-none items-center rounded border border-gray-400 px-4 text-sm font-semibold text-gray-800 hover:bg-gray-200 active:bg-gray-200 disabled:pointer-events-none"
184
-
>
185
-
Browse files
186
-
</button>
187
-
<p class="select-none font-medium text-gray-600">or drop your file here</p>
188
-
</div>
189
-
</fieldset>
155
+
onFiles={onFileDrop}
156
+
/>
190
157
</div>
191
158
<hr class="mx-4 border-gray-300" />
192
159
+3
-24
src/views/repository/repo-export.tsx
+3
-24
src/views/repository/repo-export.tsx
···
11
11
import { useTitle } from '~/lib/navigation/router';
12
12
import { makeAbortable } from '~/lib/utils/abortable';
13
13
import { formatBytes } from '~/lib/utils/intl/bytes';
14
+
import { iterateStream } from '~/lib/utils/stream';
14
15
15
16
import Button from '~/components/inputs/button';
16
17
import TextInput from '~/components/inputs/text-input';
17
18
import Logger, { createLogger } from '~/components/logger';
19
+
import PageHeader from '~/components/page-header';
18
20
19
21
const RepoExportPage = () => {
20
22
const logger = createLogger();
···
135
137
136
138
return (
137
139
<>
138
-
<div class="p-4">
139
-
<h1 class="text-lg font-bold text-purple-800">Export repository</h1>
140
-
<p class="text-gray-600">Download an archive of an account's repository</p>
141
-
</div>
142
-
<hr class="mx-4 border-gray-300" />
140
+
<PageHeader title="Export repository" subtitle="Download an archive of an account's repository" />
143
141
144
142
<form
145
143
onSubmit={(ev) => {
···
222
220
};
223
221
224
222
export default RepoExportPage;
225
-
226
-
export async function* iterateStream<T>(stream: ReadableStream<T>) {
227
-
// Get a lock on the stream
228
-
const reader = stream.getReader();
229
-
230
-
try {
231
-
while (true) {
232
-
const { done, value } = await reader.read();
233
-
234
-
if (done) {
235
-
return;
236
-
}
237
-
238
-
yield value;
239
-
}
240
-
} finally {
241
-
reader.releaseLock();
242
-
}
243
-
}
+1
tsconfig.app.json
+1
tsconfig.app.json