this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

first commit

Co-authored-by: Copilot <copilot@github.com>

nove-b e158e72e

+2574
+3
.gitignore
··· 1 + node_modules 2 + .vercel 3 + dist
+51
README.md
··· 1 + # Tangled Activity Graph API 2 + 3 + Tangled の Atom フィードを集計し、GitHub README に埋め込める SVG のカレンダーヒートマップを返す Vercel Serverless Functions プロジェクトです。 4 + 5 + このプロジェクトでは、ローカル環境で Vercel CLI にログインしたり `npx vercel` を実行したりする必要はありません。 6 + 7 + ## セットアップ 8 + 9 + ```bash 10 + npm install 11 + npm run build 12 + ``` 13 + 14 + ローカル起動: 15 + 16 + ```bash 17 + npm run dev 18 + ``` 19 + 20 + ローカル確認 URL: 21 + 22 + ```text 23 + http://localhost:3000/api/graph?account=nove-b.dev&range=1 24 + ``` 25 + 26 + ## エンドポイント 27 + 28 + ```text 29 + /api/graph?account=nove-b.dev&range=1 30 + ``` 31 + 32 + - `account`: Tangled のアカウント名。`@` ありでも受け付けます。 33 + - `range`: 1〜12 の月数。省略時は 12。 34 + 35 + ## README への埋め込み例 36 + 37 + ```md 38 + ![Tangled Activity](https://your-vercel-domain.vercel.app/api/graph?account=nove-b.dev&range=1) 39 + ``` 40 + 41 + ## デプロイ 42 + 43 + 1. GitHub にこのプロジェクトを push します。 44 + 2. Vercel ダッシュボードで該当 GitHub リポジトリを Import します。 45 + 3. 以降は push ごとに自動デプロイされます。 46 + 47 + デプロイ後、以下の形式で GitHub アカウントの `README.md` に埋め込めます。 48 + 49 + ```md 50 + ![Tangled Activity](https://your-vercel-domain.vercel.app/api/graph?account=nove-b.dev&range=1) 51 + ```
+53
api/graph.ts
··· 1 + import type { VercelRequest, VercelResponse } from '@vercel/node'; 2 + 3 + import { 4 + buildGraphSvg, 5 + clampRange, 6 + fetchActivityByDay, 7 + normalizeAccount, 8 + } from '../src/tangledGraph'; 9 + 10 + export default async function handler( 11 + req: VercelRequest, 12 + res: VercelResponse, 13 + ): Promise<void> { 14 + const accountParam = Array.isArray(req.query.account) 15 + ? req.query.account[0] 16 + : req.query.account; 17 + const rangeParam = Array.isArray(req.query.range) 18 + ? req.query.range[0] 19 + : req.query.range; 20 + 21 + const account = normalizeAccount(accountParam); 22 + const range = clampRange(rangeParam); 23 + 24 + res.setHeader('Content-Type', 'image/svg+xml; charset=utf-8'); 25 + res.setHeader('Cache-Control', 's-maxage=1800, stale-while-revalidate=86400'); 26 + 27 + if (!account) { 28 + res.status(400).send( 29 + buildGraphSvg({ 30 + account: 'unknown', 31 + range, 32 + days: [], 33 + error: 'Missing or invalid account parameter', 34 + }), 35 + ); 36 + return; 37 + } 38 + 39 + try { 40 + const days = await fetchActivityByDay(account, range); 41 + res.status(200).send(buildGraphSvg({ account, range, days })); 42 + } catch (error) { 43 + const message = error instanceof Error ? error.message : 'Failed to load feed'; 44 + res.status(502).send( 45 + buildGraphSvg({ 46 + account, 47 + range, 48 + days: [], 49 + error: message, 50 + }), 51 + ); 52 + } 53 + }
+2032
package-lock.json
··· 1 + { 2 + "name": "tangled-activity", 3 + "version": "0.1.0", 4 + "lockfileVersion": 3, 5 + "requires": true, 6 + "packages": { 7 + "": { 8 + "name": "tangled-activity", 9 + "version": "0.1.0", 10 + "dependencies": { 11 + "fast-xml-parser": "^4.5.3" 12 + }, 13 + "devDependencies": { 14 + "@types/node": "^22.15.3", 15 + "@vercel/node": "^5.1.14", 16 + "tsx": "^4.19.2", 17 + "typescript": "^5.8.3" 18 + } 19 + }, 20 + "node_modules/@bytecodealliance/preview2-shim": { 21 + "version": "0.17.6", 22 + "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.6.tgz", 23 + "integrity": "sha512-n3cM88gTen5980UOBAD6xDcNNL3ocTK8keab21bpx1ONdA+ARj7uD1qoFxOWCyKlkpSi195FH+GeAut7Oc6zZw==", 24 + "dev": true, 25 + "license": "(Apache-2.0 WITH LLVM-exception)" 26 + }, 27 + "node_modules/@edge-runtime/format": { 28 + "version": "2.2.1", 29 + "resolved": "https://registry.npmjs.org/@edge-runtime/format/-/format-2.2.1.tgz", 30 + "integrity": "sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==", 31 + "dev": true, 32 + "license": "MPL-2.0", 33 + "engines": { 34 + "node": ">=16" 35 + } 36 + }, 37 + "node_modules/@edge-runtime/node-utils": { 38 + "version": "2.3.0", 39 + "resolved": "https://registry.npmjs.org/@edge-runtime/node-utils/-/node-utils-2.3.0.tgz", 40 + "integrity": "sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==", 41 + "dev": true, 42 + "license": "MPL-2.0", 43 + "engines": { 44 + "node": ">=16" 45 + } 46 + }, 47 + "node_modules/@edge-runtime/ponyfill": { 48 + "version": "2.4.2", 49 + "resolved": "https://registry.npmjs.org/@edge-runtime/ponyfill/-/ponyfill-2.4.2.tgz", 50 + "integrity": "sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==", 51 + "dev": true, 52 + "license": "MPL-2.0", 53 + "engines": { 54 + "node": ">=16" 55 + } 56 + }, 57 + "node_modules/@edge-runtime/primitives": { 58 + "version": "4.1.0", 59 + "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-4.1.0.tgz", 60 + "integrity": "sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==", 61 + "dev": true, 62 + "license": "MPL-2.0", 63 + "engines": { 64 + "node": ">=16" 65 + } 66 + }, 67 + "node_modules/@edge-runtime/vm": { 68 + "version": "3.2.0", 69 + "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.2.0.tgz", 70 + "integrity": "sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==", 71 + "dev": true, 72 + "license": "MPL-2.0", 73 + "dependencies": { 74 + "@edge-runtime/primitives": "4.1.0" 75 + }, 76 + "engines": { 77 + "node": ">=16" 78 + } 79 + }, 80 + "node_modules/@esbuild/aix-ppc64": { 81 + "version": "0.27.0", 82 + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", 83 + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", 84 + "cpu": [ 85 + "ppc64" 86 + ], 87 + "dev": true, 88 + "license": "MIT", 89 + "optional": true, 90 + "os": [ 91 + "aix" 92 + ], 93 + "engines": { 94 + "node": ">=18" 95 + } 96 + }, 97 + "node_modules/@esbuild/android-arm": { 98 + "version": "0.27.0", 99 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", 100 + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", 101 + "cpu": [ 102 + "arm" 103 + ], 104 + "dev": true, 105 + "license": "MIT", 106 + "optional": true, 107 + "os": [ 108 + "android" 109 + ], 110 + "engines": { 111 + "node": ">=18" 112 + } 113 + }, 114 + "node_modules/@esbuild/android-arm64": { 115 + "version": "0.27.0", 116 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", 117 + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", 118 + "cpu": [ 119 + "arm64" 120 + ], 121 + "dev": true, 122 + "license": "MIT", 123 + "optional": true, 124 + "os": [ 125 + "android" 126 + ], 127 + "engines": { 128 + "node": ">=18" 129 + } 130 + }, 131 + "node_modules/@esbuild/android-x64": { 132 + "version": "0.27.0", 133 + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", 134 + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", 135 + "cpu": [ 136 + "x64" 137 + ], 138 + "dev": true, 139 + "license": "MIT", 140 + "optional": true, 141 + "os": [ 142 + "android" 143 + ], 144 + "engines": { 145 + "node": ">=18" 146 + } 147 + }, 148 + "node_modules/@esbuild/darwin-arm64": { 149 + "version": "0.27.0", 150 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", 151 + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", 152 + "cpu": [ 153 + "arm64" 154 + ], 155 + "dev": true, 156 + "license": "MIT", 157 + "optional": true, 158 + "os": [ 159 + "darwin" 160 + ], 161 + "engines": { 162 + "node": ">=18" 163 + } 164 + }, 165 + "node_modules/@esbuild/darwin-x64": { 166 + "version": "0.27.0", 167 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", 168 + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", 169 + "cpu": [ 170 + "x64" 171 + ], 172 + "dev": true, 173 + "license": "MIT", 174 + "optional": true, 175 + "os": [ 176 + "darwin" 177 + ], 178 + "engines": { 179 + "node": ">=18" 180 + } 181 + }, 182 + "node_modules/@esbuild/freebsd-arm64": { 183 + "version": "0.27.0", 184 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", 185 + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", 186 + "cpu": [ 187 + "arm64" 188 + ], 189 + "dev": true, 190 + "license": "MIT", 191 + "optional": true, 192 + "os": [ 193 + "freebsd" 194 + ], 195 + "engines": { 196 + "node": ">=18" 197 + } 198 + }, 199 + "node_modules/@esbuild/freebsd-x64": { 200 + "version": "0.27.0", 201 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", 202 + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", 203 + "cpu": [ 204 + "x64" 205 + ], 206 + "dev": true, 207 + "license": "MIT", 208 + "optional": true, 209 + "os": [ 210 + "freebsd" 211 + ], 212 + "engines": { 213 + "node": ">=18" 214 + } 215 + }, 216 + "node_modules/@esbuild/linux-arm": { 217 + "version": "0.27.0", 218 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", 219 + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", 220 + "cpu": [ 221 + "arm" 222 + ], 223 + "dev": true, 224 + "license": "MIT", 225 + "optional": true, 226 + "os": [ 227 + "linux" 228 + ], 229 + "engines": { 230 + "node": ">=18" 231 + } 232 + }, 233 + "node_modules/@esbuild/linux-arm64": { 234 + "version": "0.27.0", 235 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", 236 + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", 237 + "cpu": [ 238 + "arm64" 239 + ], 240 + "dev": true, 241 + "license": "MIT", 242 + "optional": true, 243 + "os": [ 244 + "linux" 245 + ], 246 + "engines": { 247 + "node": ">=18" 248 + } 249 + }, 250 + "node_modules/@esbuild/linux-ia32": { 251 + "version": "0.27.0", 252 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", 253 + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", 254 + "cpu": [ 255 + "ia32" 256 + ], 257 + "dev": true, 258 + "license": "MIT", 259 + "optional": true, 260 + "os": [ 261 + "linux" 262 + ], 263 + "engines": { 264 + "node": ">=18" 265 + } 266 + }, 267 + "node_modules/@esbuild/linux-loong64": { 268 + "version": "0.27.0", 269 + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", 270 + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", 271 + "cpu": [ 272 + "loong64" 273 + ], 274 + "dev": true, 275 + "license": "MIT", 276 + "optional": true, 277 + "os": [ 278 + "linux" 279 + ], 280 + "engines": { 281 + "node": ">=18" 282 + } 283 + }, 284 + "node_modules/@esbuild/linux-mips64el": { 285 + "version": "0.27.0", 286 + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", 287 + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", 288 + "cpu": [ 289 + "mips64el" 290 + ], 291 + "dev": true, 292 + "license": "MIT", 293 + "optional": true, 294 + "os": [ 295 + "linux" 296 + ], 297 + "engines": { 298 + "node": ">=18" 299 + } 300 + }, 301 + "node_modules/@esbuild/linux-ppc64": { 302 + "version": "0.27.0", 303 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", 304 + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", 305 + "cpu": [ 306 + "ppc64" 307 + ], 308 + "dev": true, 309 + "license": "MIT", 310 + "optional": true, 311 + "os": [ 312 + "linux" 313 + ], 314 + "engines": { 315 + "node": ">=18" 316 + } 317 + }, 318 + "node_modules/@esbuild/linux-riscv64": { 319 + "version": "0.27.0", 320 + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", 321 + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", 322 + "cpu": [ 323 + "riscv64" 324 + ], 325 + "dev": true, 326 + "license": "MIT", 327 + "optional": true, 328 + "os": [ 329 + "linux" 330 + ], 331 + "engines": { 332 + "node": ">=18" 333 + } 334 + }, 335 + "node_modules/@esbuild/linux-s390x": { 336 + "version": "0.27.0", 337 + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", 338 + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", 339 + "cpu": [ 340 + "s390x" 341 + ], 342 + "dev": true, 343 + "license": "MIT", 344 + "optional": true, 345 + "os": [ 346 + "linux" 347 + ], 348 + "engines": { 349 + "node": ">=18" 350 + } 351 + }, 352 + "node_modules/@esbuild/linux-x64": { 353 + "version": "0.27.0", 354 + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", 355 + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", 356 + "cpu": [ 357 + "x64" 358 + ], 359 + "dev": true, 360 + "license": "MIT", 361 + "optional": true, 362 + "os": [ 363 + "linux" 364 + ], 365 + "engines": { 366 + "node": ">=18" 367 + } 368 + }, 369 + "node_modules/@esbuild/netbsd-arm64": { 370 + "version": "0.27.0", 371 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", 372 + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", 373 + "cpu": [ 374 + "arm64" 375 + ], 376 + "dev": true, 377 + "license": "MIT", 378 + "optional": true, 379 + "os": [ 380 + "netbsd" 381 + ], 382 + "engines": { 383 + "node": ">=18" 384 + } 385 + }, 386 + "node_modules/@esbuild/netbsd-x64": { 387 + "version": "0.27.0", 388 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", 389 + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", 390 + "cpu": [ 391 + "x64" 392 + ], 393 + "dev": true, 394 + "license": "MIT", 395 + "optional": true, 396 + "os": [ 397 + "netbsd" 398 + ], 399 + "engines": { 400 + "node": ">=18" 401 + } 402 + }, 403 + "node_modules/@esbuild/openbsd-arm64": { 404 + "version": "0.27.0", 405 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", 406 + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", 407 + "cpu": [ 408 + "arm64" 409 + ], 410 + "dev": true, 411 + "license": "MIT", 412 + "optional": true, 413 + "os": [ 414 + "openbsd" 415 + ], 416 + "engines": { 417 + "node": ">=18" 418 + } 419 + }, 420 + "node_modules/@esbuild/openbsd-x64": { 421 + "version": "0.27.0", 422 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", 423 + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", 424 + "cpu": [ 425 + "x64" 426 + ], 427 + "dev": true, 428 + "license": "MIT", 429 + "optional": true, 430 + "os": [ 431 + "openbsd" 432 + ], 433 + "engines": { 434 + "node": ">=18" 435 + } 436 + }, 437 + "node_modules/@esbuild/openharmony-arm64": { 438 + "version": "0.27.0", 439 + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", 440 + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", 441 + "cpu": [ 442 + "arm64" 443 + ], 444 + "dev": true, 445 + "license": "MIT", 446 + "optional": true, 447 + "os": [ 448 + "openharmony" 449 + ], 450 + "engines": { 451 + "node": ">=18" 452 + } 453 + }, 454 + "node_modules/@esbuild/sunos-x64": { 455 + "version": "0.27.0", 456 + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", 457 + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", 458 + "cpu": [ 459 + "x64" 460 + ], 461 + "dev": true, 462 + "license": "MIT", 463 + "optional": true, 464 + "os": [ 465 + "sunos" 466 + ], 467 + "engines": { 468 + "node": ">=18" 469 + } 470 + }, 471 + "node_modules/@esbuild/win32-arm64": { 472 + "version": "0.27.0", 473 + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", 474 + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", 475 + "cpu": [ 476 + "arm64" 477 + ], 478 + "dev": true, 479 + "license": "MIT", 480 + "optional": true, 481 + "os": [ 482 + "win32" 483 + ], 484 + "engines": { 485 + "node": ">=18" 486 + } 487 + }, 488 + "node_modules/@esbuild/win32-ia32": { 489 + "version": "0.27.0", 490 + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", 491 + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", 492 + "cpu": [ 493 + "ia32" 494 + ], 495 + "dev": true, 496 + "license": "MIT", 497 + "optional": true, 498 + "os": [ 499 + "win32" 500 + ], 501 + "engines": { 502 + "node": ">=18" 503 + } 504 + }, 505 + "node_modules/@esbuild/win32-x64": { 506 + "version": "0.27.0", 507 + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", 508 + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", 509 + "cpu": [ 510 + "x64" 511 + ], 512 + "dev": true, 513 + "license": "MIT", 514 + "optional": true, 515 + "os": [ 516 + "win32" 517 + ], 518 + "engines": { 519 + "node": ">=18" 520 + } 521 + }, 522 + "node_modules/@fastify/busboy": { 523 + "version": "2.1.1", 524 + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", 525 + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", 526 + "dev": true, 527 + "license": "MIT", 528 + "engines": { 529 + "node": ">=14" 530 + } 531 + }, 532 + "node_modules/@isaacs/balanced-match": { 533 + "version": "4.0.1", 534 + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", 535 + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", 536 + "dev": true, 537 + "license": "MIT", 538 + "engines": { 539 + "node": "20 || >=22" 540 + } 541 + }, 542 + "node_modules/@isaacs/brace-expansion": { 543 + "version": "5.0.1", 544 + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", 545 + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", 546 + "dev": true, 547 + "license": "MIT", 548 + "dependencies": { 549 + "@isaacs/balanced-match": "^4.0.1" 550 + }, 551 + "engines": { 552 + "node": "20 || >=22" 553 + } 554 + }, 555 + "node_modules/@isaacs/fs-minipass": { 556 + "version": "4.0.1", 557 + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", 558 + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", 559 + "dev": true, 560 + "license": "ISC", 561 + "dependencies": { 562 + "minipass": "^7.0.4" 563 + }, 564 + "engines": { 565 + "node": ">=18.0.0" 566 + } 567 + }, 568 + "node_modules/@mapbox/node-pre-gyp": { 569 + "version": "2.0.3", 570 + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.3.tgz", 571 + "integrity": "sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==", 572 + "dev": true, 573 + "license": "BSD-3-Clause", 574 + "dependencies": { 575 + "consola": "^3.2.3", 576 + "detect-libc": "^2.0.0", 577 + "https-proxy-agent": "^7.0.5", 578 + "node-fetch": "^2.6.7", 579 + "nopt": "^8.0.0", 580 + "semver": "^7.5.3", 581 + "tar": "^7.4.0" 582 + }, 583 + "bin": { 584 + "node-pre-gyp": "bin/node-pre-gyp" 585 + }, 586 + "engines": { 587 + "node": ">=18" 588 + } 589 + }, 590 + "node_modules/@nodelib/fs.scandir": { 591 + "version": "2.1.5", 592 + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 593 + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 594 + "dev": true, 595 + "license": "MIT", 596 + "dependencies": { 597 + "@nodelib/fs.stat": "2.0.5", 598 + "run-parallel": "^1.1.9" 599 + }, 600 + "engines": { 601 + "node": ">= 8" 602 + } 603 + }, 604 + "node_modules/@nodelib/fs.stat": { 605 + "version": "2.0.5", 606 + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 607 + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 608 + "dev": true, 609 + "license": "MIT", 610 + "engines": { 611 + "node": ">= 8" 612 + } 613 + }, 614 + "node_modules/@nodelib/fs.walk": { 615 + "version": "1.2.8", 616 + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 617 + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 618 + "dev": true, 619 + "license": "MIT", 620 + "dependencies": { 621 + "@nodelib/fs.scandir": "2.1.5", 622 + "fastq": "^1.6.0" 623 + }, 624 + "engines": { 625 + "node": ">= 8" 626 + } 627 + }, 628 + "node_modules/@renovatebot/pep440": { 629 + "version": "4.2.1", 630 + "resolved": "https://registry.npmjs.org/@renovatebot/pep440/-/pep440-4.2.1.tgz", 631 + "integrity": "sha512-2FK1hF93Fuf1laSdfiEmJvSJPVIDHEUTz68D3Fi9s0IZrrpaEcj6pTFBTbYvsgC5du4ogrtf5re7yMMvrKNgkw==", 632 + "dev": true, 633 + "license": "Apache-2.0", 634 + "engines": { 635 + "node": "^20.9.0 || ^22.11.0 || ^24", 636 + "pnpm": "^10.0.0" 637 + } 638 + }, 639 + "node_modules/@rollup/pluginutils": { 640 + "version": "5.3.0", 641 + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", 642 + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", 643 + "dev": true, 644 + "license": "MIT", 645 + "dependencies": { 646 + "@types/estree": "^1.0.0", 647 + "estree-walker": "^2.0.2", 648 + "picomatch": "^4.0.2" 649 + }, 650 + "engines": { 651 + "node": ">=14.0.0" 652 + }, 653 + "peerDependencies": { 654 + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" 655 + }, 656 + "peerDependenciesMeta": { 657 + "rollup": { 658 + "optional": true 659 + } 660 + } 661 + }, 662 + "node_modules/@ts-morph/common": { 663 + "version": "0.11.1", 664 + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.11.1.tgz", 665 + "integrity": "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==", 666 + "dev": true, 667 + "license": "MIT", 668 + "dependencies": { 669 + "fast-glob": "^3.2.7", 670 + "minimatch": "^3.0.4", 671 + "mkdirp": "^1.0.4", 672 + "path-browserify": "^1.0.1" 673 + } 674 + }, 675 + "node_modules/@ts-morph/common/node_modules/minimatch": { 676 + "version": "3.1.5", 677 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", 678 + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", 679 + "dev": true, 680 + "license": "ISC", 681 + "dependencies": { 682 + "brace-expansion": "^1.1.7" 683 + }, 684 + "engines": { 685 + "node": "*" 686 + } 687 + }, 688 + "node_modules/@types/estree": { 689 + "version": "1.0.8", 690 + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", 691 + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", 692 + "dev": true, 693 + "license": "MIT" 694 + }, 695 + "node_modules/@types/json-schema": { 696 + "version": "7.0.15", 697 + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 698 + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 699 + "dev": true, 700 + "license": "MIT" 701 + }, 702 + "node_modules/@types/node": { 703 + "version": "22.19.17", 704 + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz", 705 + "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", 706 + "dev": true, 707 + "license": "MIT", 708 + "dependencies": { 709 + "undici-types": "~6.21.0" 710 + } 711 + }, 712 + "node_modules/@vercel/build-utils": { 713 + "version": "13.21.0", 714 + "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-13.21.0.tgz", 715 + "integrity": "sha512-A1vtlzFYbjvxRxhnt94LUxrn9JVX2EuXALi/NFyxNA1M51eGQwI5LZaroNlgIRXdx7LCJxBQEUMKc1fi0aqU/g==", 716 + "dev": true, 717 + "license": "Apache-2.0", 718 + "dependencies": { 719 + "@vercel/python-analysis": "0.11.1", 720 + "cjs-module-lexer": "1.2.3", 721 + "es-module-lexer": "1.5.0" 722 + } 723 + }, 724 + "node_modules/@vercel/build-utils/node_modules/es-module-lexer": { 725 + "version": "1.5.0", 726 + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", 727 + "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==", 728 + "dev": true, 729 + "license": "MIT" 730 + }, 731 + "node_modules/@vercel/error-utils": { 732 + "version": "2.1.0", 733 + "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.1.0.tgz", 734 + "integrity": "sha512-DiJcXBOB9N6QM4d7hYPM9Ck/AUjzBl58XNQPxS74o7CuvIanjzrGgygP/70VsyEASeIJMazk1LrhwcNTR/eZGQ==", 735 + "dev": true, 736 + "license": "Apache-2.0" 737 + }, 738 + "node_modules/@vercel/nft": { 739 + "version": "1.5.0", 740 + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-1.5.0.tgz", 741 + "integrity": "sha512-IWTDeIoWhQ7ZtRO/JRKH+jhmeQvZYhtGPmzw/QGDY+wDCQqfm25P9yIdoAFagu4fWsK4IwZXDFIjrmp5rRm/sA==", 742 + "dev": true, 743 + "license": "MIT", 744 + "dependencies": { 745 + "@mapbox/node-pre-gyp": "^2.0.0", 746 + "@rollup/pluginutils": "^5.1.3", 747 + "acorn": "^8.6.0", 748 + "acorn-import-attributes": "^1.9.5", 749 + "async-sema": "^3.1.1", 750 + "bindings": "^1.4.0", 751 + "estree-walker": "2.0.2", 752 + "glob": "^13.0.0", 753 + "graceful-fs": "^4.2.9", 754 + "node-gyp-build": "^4.2.2", 755 + "picomatch": "^4.0.2", 756 + "resolve-from": "^5.0.0" 757 + }, 758 + "bin": { 759 + "nft": "out/cli.js" 760 + }, 761 + "engines": { 762 + "node": ">=20" 763 + } 764 + }, 765 + "node_modules/@vercel/node": { 766 + "version": "5.7.15", 767 + "resolved": "https://registry.npmjs.org/@vercel/node/-/node-5.7.15.tgz", 768 + "integrity": "sha512-o8YtafKgaYsY7/4SRKlrvTx/cEB5o3vQG3/eq5Qo66n4WaFeZV8R8GG+BzSU3SYozasQlQxkbPxedUNF4sZJ8A==", 769 + "dev": true, 770 + "license": "Apache-2.0", 771 + "dependencies": { 772 + "@edge-runtime/node-utils": "2.3.0", 773 + "@edge-runtime/primitives": "4.1.0", 774 + "@edge-runtime/vm": "3.2.0", 775 + "@types/node": "20.11.0", 776 + "@vercel/build-utils": "13.21.0", 777 + "@vercel/error-utils": "2.1.0", 778 + "@vercel/nft": "1.5.0", 779 + "@vercel/static-config": "3.3.0", 780 + "async-listen": "3.0.0", 781 + "cjs-module-lexer": "1.2.3", 782 + "edge-runtime": "2.5.9", 783 + "es-module-lexer": "1.4.1", 784 + "esbuild": "0.27.0", 785 + "etag": "1.8.1", 786 + "mime-types": "2.1.35", 787 + "node-fetch": "2.6.9", 788 + "path-to-regexp": "6.1.0", 789 + "path-to-regexp-updated": "npm:path-to-regexp@6.3.0", 790 + "ts-morph": "12.0.0", 791 + "tsx": "4.21.0", 792 + "typescript": "npm:typescript@5.9.3", 793 + "undici": "5.28.4" 794 + } 795 + }, 796 + "node_modules/@vercel/node/node_modules/@types/node": { 797 + "version": "20.11.0", 798 + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", 799 + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", 800 + "dev": true, 801 + "license": "MIT", 802 + "dependencies": { 803 + "undici-types": "~5.26.4" 804 + } 805 + }, 806 + "node_modules/@vercel/node/node_modules/undici-types": { 807 + "version": "5.26.5", 808 + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 809 + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 810 + "dev": true, 811 + "license": "MIT" 812 + }, 813 + "node_modules/@vercel/python-analysis": { 814 + "version": "0.11.1", 815 + "resolved": "https://registry.npmjs.org/@vercel/python-analysis/-/python-analysis-0.11.1.tgz", 816 + "integrity": "sha512-EPPLuXJQhIDUx08H9nG76AR2HSgBquwe3OAX5s2w20M923iaWeGGVkhX/4yZ89CJfXEZgE1Aj/mX7lVHOVIcYA==", 817 + "dev": true, 818 + "license": "Apache-2.0", 819 + "dependencies": { 820 + "@bytecodealliance/preview2-shim": "0.17.6", 821 + "@renovatebot/pep440": "4.2.1", 822 + "fs-extra": "11.1.1", 823 + "js-yaml": "4.1.1", 824 + "minimatch": "10.1.1", 825 + "smol-toml": "1.5.2", 826 + "zod": "3.22.4" 827 + } 828 + }, 829 + "node_modules/@vercel/static-config": { 830 + "version": "3.3.0", 831 + "resolved": "https://registry.npmjs.org/@vercel/static-config/-/static-config-3.3.0.tgz", 832 + "integrity": "sha512-GpS3tPwUeDJCkrKbMNtS2XLRFgfxTlN7YNUL+Bo23+fGolrDw6Oq79R3yvxTYgqRaJMGSEqC7iMw6mj6I5loxg==", 833 + "dev": true, 834 + "license": "Apache-2.0", 835 + "dependencies": { 836 + "ajv": "8.6.3", 837 + "json-schema-to-ts": "1.6.4", 838 + "ts-morph": "12.0.0" 839 + } 840 + }, 841 + "node_modules/abbrev": { 842 + "version": "3.0.1", 843 + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", 844 + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", 845 + "dev": true, 846 + "license": "ISC", 847 + "engines": { 848 + "node": "^18.17.0 || >=20.5.0" 849 + } 850 + }, 851 + "node_modules/acorn": { 852 + "version": "8.16.0", 853 + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", 854 + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", 855 + "dev": true, 856 + "license": "MIT", 857 + "bin": { 858 + "acorn": "bin/acorn" 859 + }, 860 + "engines": { 861 + "node": ">=0.4.0" 862 + } 863 + }, 864 + "node_modules/acorn-import-attributes": { 865 + "version": "1.9.5", 866 + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", 867 + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", 868 + "dev": true, 869 + "license": "MIT", 870 + "peerDependencies": { 871 + "acorn": "^8" 872 + } 873 + }, 874 + "node_modules/agent-base": { 875 + "version": "7.1.4", 876 + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", 877 + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", 878 + "dev": true, 879 + "license": "MIT", 880 + "engines": { 881 + "node": ">= 14" 882 + } 883 + }, 884 + "node_modules/ajv": { 885 + "version": "8.6.3", 886 + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", 887 + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", 888 + "dev": true, 889 + "license": "MIT", 890 + "dependencies": { 891 + "fast-deep-equal": "^3.1.1", 892 + "json-schema-traverse": "^1.0.0", 893 + "require-from-string": "^2.0.2", 894 + "uri-js": "^4.2.2" 895 + }, 896 + "funding": { 897 + "type": "github", 898 + "url": "https://github.com/sponsors/epoberezkin" 899 + } 900 + }, 901 + "node_modules/argparse": { 902 + "version": "2.0.1", 903 + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 904 + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 905 + "dev": true, 906 + "license": "Python-2.0" 907 + }, 908 + "node_modules/async-listen": { 909 + "version": "3.0.0", 910 + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.0.tgz", 911 + "integrity": "sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==", 912 + "dev": true, 913 + "license": "MIT", 914 + "engines": { 915 + "node": ">= 14" 916 + } 917 + }, 918 + "node_modules/async-sema": { 919 + "version": "3.1.1", 920 + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", 921 + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", 922 + "dev": true, 923 + "license": "MIT" 924 + }, 925 + "node_modules/balanced-match": { 926 + "version": "1.0.2", 927 + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 928 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 929 + "dev": true, 930 + "license": "MIT" 931 + }, 932 + "node_modules/bindings": { 933 + "version": "1.5.0", 934 + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 935 + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 936 + "dev": true, 937 + "license": "MIT", 938 + "dependencies": { 939 + "file-uri-to-path": "1.0.0" 940 + } 941 + }, 942 + "node_modules/brace-expansion": { 943 + "version": "1.1.14", 944 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", 945 + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", 946 + "dev": true, 947 + "license": "MIT", 948 + "dependencies": { 949 + "balanced-match": "^1.0.0", 950 + "concat-map": "0.0.1" 951 + } 952 + }, 953 + "node_modules/braces": { 954 + "version": "3.0.3", 955 + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 956 + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 957 + "dev": true, 958 + "license": "MIT", 959 + "dependencies": { 960 + "fill-range": "^7.1.1" 961 + }, 962 + "engines": { 963 + "node": ">=8" 964 + } 965 + }, 966 + "node_modules/chownr": { 967 + "version": "3.0.0", 968 + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", 969 + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", 970 + "dev": true, 971 + "license": "BlueOak-1.0.0", 972 + "engines": { 973 + "node": ">=18" 974 + } 975 + }, 976 + "node_modules/cjs-module-lexer": { 977 + "version": "1.2.3", 978 + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", 979 + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", 980 + "dev": true, 981 + "license": "MIT" 982 + }, 983 + "node_modules/code-block-writer": { 984 + "version": "10.1.1", 985 + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", 986 + "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==", 987 + "dev": true, 988 + "license": "MIT" 989 + }, 990 + "node_modules/concat-map": { 991 + "version": "0.0.1", 992 + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 993 + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 994 + "dev": true, 995 + "license": "MIT" 996 + }, 997 + "node_modules/consola": { 998 + "version": "3.4.2", 999 + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", 1000 + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", 1001 + "dev": true, 1002 + "license": "MIT", 1003 + "engines": { 1004 + "node": "^14.18.0 || >=16.10.0" 1005 + } 1006 + }, 1007 + "node_modules/convert-hrtime": { 1008 + "version": "3.0.0", 1009 + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-3.0.0.tgz", 1010 + "integrity": "sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==", 1011 + "dev": true, 1012 + "license": "MIT", 1013 + "engines": { 1014 + "node": ">=8" 1015 + } 1016 + }, 1017 + "node_modules/debug": { 1018 + "version": "4.4.3", 1019 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", 1020 + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", 1021 + "dev": true, 1022 + "license": "MIT", 1023 + "dependencies": { 1024 + "ms": "^2.1.3" 1025 + }, 1026 + "engines": { 1027 + "node": ">=6.0" 1028 + }, 1029 + "peerDependenciesMeta": { 1030 + "supports-color": { 1031 + "optional": true 1032 + } 1033 + } 1034 + }, 1035 + "node_modules/detect-libc": { 1036 + "version": "2.1.2", 1037 + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", 1038 + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", 1039 + "dev": true, 1040 + "license": "Apache-2.0", 1041 + "engines": { 1042 + "node": ">=8" 1043 + } 1044 + }, 1045 + "node_modules/edge-runtime": { 1046 + "version": "2.5.9", 1047 + "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.9.tgz", 1048 + "integrity": "sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==", 1049 + "dev": true, 1050 + "license": "MPL-2.0", 1051 + "dependencies": { 1052 + "@edge-runtime/format": "2.2.1", 1053 + "@edge-runtime/ponyfill": "2.4.2", 1054 + "@edge-runtime/vm": "3.2.0", 1055 + "async-listen": "3.0.1", 1056 + "mri": "1.2.0", 1057 + "picocolors": "1.0.0", 1058 + "pretty-ms": "7.0.1", 1059 + "signal-exit": "4.0.2", 1060 + "time-span": "4.0.0" 1061 + }, 1062 + "bin": { 1063 + "edge-runtime": "dist/cli/index.js" 1064 + }, 1065 + "engines": { 1066 + "node": ">=16" 1067 + } 1068 + }, 1069 + "node_modules/edge-runtime/node_modules/async-listen": { 1070 + "version": "3.0.1", 1071 + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.1.tgz", 1072 + "integrity": "sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==", 1073 + "dev": true, 1074 + "license": "MIT", 1075 + "engines": { 1076 + "node": ">= 14" 1077 + } 1078 + }, 1079 + "node_modules/es-module-lexer": { 1080 + "version": "1.4.1", 1081 + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", 1082 + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", 1083 + "dev": true, 1084 + "license": "MIT" 1085 + }, 1086 + "node_modules/esbuild": { 1087 + "version": "0.27.0", 1088 + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", 1089 + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", 1090 + "dev": true, 1091 + "hasInstallScript": true, 1092 + "license": "MIT", 1093 + "bin": { 1094 + "esbuild": "bin/esbuild" 1095 + }, 1096 + "engines": { 1097 + "node": ">=18" 1098 + }, 1099 + "optionalDependencies": { 1100 + "@esbuild/aix-ppc64": "0.27.0", 1101 + "@esbuild/android-arm": "0.27.0", 1102 + "@esbuild/android-arm64": "0.27.0", 1103 + "@esbuild/android-x64": "0.27.0", 1104 + "@esbuild/darwin-arm64": "0.27.0", 1105 + "@esbuild/darwin-x64": "0.27.0", 1106 + "@esbuild/freebsd-arm64": "0.27.0", 1107 + "@esbuild/freebsd-x64": "0.27.0", 1108 + "@esbuild/linux-arm": "0.27.0", 1109 + "@esbuild/linux-arm64": "0.27.0", 1110 + "@esbuild/linux-ia32": "0.27.0", 1111 + "@esbuild/linux-loong64": "0.27.0", 1112 + "@esbuild/linux-mips64el": "0.27.0", 1113 + "@esbuild/linux-ppc64": "0.27.0", 1114 + "@esbuild/linux-riscv64": "0.27.0", 1115 + "@esbuild/linux-s390x": "0.27.0", 1116 + "@esbuild/linux-x64": "0.27.0", 1117 + "@esbuild/netbsd-arm64": "0.27.0", 1118 + "@esbuild/netbsd-x64": "0.27.0", 1119 + "@esbuild/openbsd-arm64": "0.27.0", 1120 + "@esbuild/openbsd-x64": "0.27.0", 1121 + "@esbuild/openharmony-arm64": "0.27.0", 1122 + "@esbuild/sunos-x64": "0.27.0", 1123 + "@esbuild/win32-arm64": "0.27.0", 1124 + "@esbuild/win32-ia32": "0.27.0", 1125 + "@esbuild/win32-x64": "0.27.0" 1126 + } 1127 + }, 1128 + "node_modules/estree-walker": { 1129 + "version": "2.0.2", 1130 + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 1131 + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1132 + "dev": true, 1133 + "license": "MIT" 1134 + }, 1135 + "node_modules/etag": { 1136 + "version": "1.8.1", 1137 + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1138 + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 1139 + "dev": true, 1140 + "license": "MIT", 1141 + "engines": { 1142 + "node": ">= 0.6" 1143 + } 1144 + }, 1145 + "node_modules/fast-deep-equal": { 1146 + "version": "3.1.3", 1147 + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1148 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1149 + "dev": true, 1150 + "license": "MIT" 1151 + }, 1152 + "node_modules/fast-glob": { 1153 + "version": "3.3.3", 1154 + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", 1155 + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", 1156 + "dev": true, 1157 + "license": "MIT", 1158 + "dependencies": { 1159 + "@nodelib/fs.stat": "^2.0.2", 1160 + "@nodelib/fs.walk": "^1.2.3", 1161 + "glob-parent": "^5.1.2", 1162 + "merge2": "^1.3.0", 1163 + "micromatch": "^4.0.8" 1164 + }, 1165 + "engines": { 1166 + "node": ">=8.6.0" 1167 + } 1168 + }, 1169 + "node_modules/fast-xml-parser": { 1170 + "version": "4.5.6", 1171 + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.6.tgz", 1172 + "integrity": "sha512-Yd4vkROfJf8AuJrDIVMVmYfULKmIJszVsMv7Vo71aocsKgFxpdlpSHXSaInvyYfgw2PRuObQSW2GFpVMUjxu9A==", 1173 + "funding": [ 1174 + { 1175 + "type": "github", 1176 + "url": "https://github.com/sponsors/NaturalIntelligence" 1177 + } 1178 + ], 1179 + "license": "MIT", 1180 + "dependencies": { 1181 + "strnum": "^1.0.5" 1182 + }, 1183 + "bin": { 1184 + "fxparser": "src/cli/cli.js" 1185 + } 1186 + }, 1187 + "node_modules/fastq": { 1188 + "version": "1.20.1", 1189 + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", 1190 + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", 1191 + "dev": true, 1192 + "license": "ISC", 1193 + "dependencies": { 1194 + "reusify": "^1.0.4" 1195 + } 1196 + }, 1197 + "node_modules/file-uri-to-path": { 1198 + "version": "1.0.0", 1199 + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 1200 + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", 1201 + "dev": true, 1202 + "license": "MIT" 1203 + }, 1204 + "node_modules/fill-range": { 1205 + "version": "7.1.1", 1206 + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 1207 + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 1208 + "dev": true, 1209 + "license": "MIT", 1210 + "dependencies": { 1211 + "to-regex-range": "^5.0.1" 1212 + }, 1213 + "engines": { 1214 + "node": ">=8" 1215 + } 1216 + }, 1217 + "node_modules/fs-extra": { 1218 + "version": "11.1.1", 1219 + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", 1220 + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", 1221 + "dev": true, 1222 + "license": "MIT", 1223 + "dependencies": { 1224 + "graceful-fs": "^4.2.0", 1225 + "jsonfile": "^6.0.1", 1226 + "universalify": "^2.0.0" 1227 + }, 1228 + "engines": { 1229 + "node": ">=14.14" 1230 + } 1231 + }, 1232 + "node_modules/fsevents": { 1233 + "version": "2.3.3", 1234 + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1235 + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1236 + "dev": true, 1237 + "hasInstallScript": true, 1238 + "license": "MIT", 1239 + "optional": true, 1240 + "os": [ 1241 + "darwin" 1242 + ], 1243 + "engines": { 1244 + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1245 + } 1246 + }, 1247 + "node_modules/get-tsconfig": { 1248 + "version": "4.14.0", 1249 + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", 1250 + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", 1251 + "dev": true, 1252 + "license": "MIT", 1253 + "dependencies": { 1254 + "resolve-pkg-maps": "^1.0.0" 1255 + }, 1256 + "funding": { 1257 + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" 1258 + } 1259 + }, 1260 + "node_modules/glob": { 1261 + "version": "13.0.6", 1262 + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", 1263 + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", 1264 + "dev": true, 1265 + "license": "BlueOak-1.0.0", 1266 + "dependencies": { 1267 + "minimatch": "^10.2.2", 1268 + "minipass": "^7.1.3", 1269 + "path-scurry": "^2.0.2" 1270 + }, 1271 + "engines": { 1272 + "node": "18 || 20 || >=22" 1273 + }, 1274 + "funding": { 1275 + "url": "https://github.com/sponsors/isaacs" 1276 + } 1277 + }, 1278 + "node_modules/glob-parent": { 1279 + "version": "5.1.2", 1280 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1281 + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1282 + "dev": true, 1283 + "license": "ISC", 1284 + "dependencies": { 1285 + "is-glob": "^4.0.1" 1286 + }, 1287 + "engines": { 1288 + "node": ">= 6" 1289 + } 1290 + }, 1291 + "node_modules/glob/node_modules/balanced-match": { 1292 + "version": "4.0.4", 1293 + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", 1294 + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", 1295 + "dev": true, 1296 + "license": "MIT", 1297 + "engines": { 1298 + "node": "18 || 20 || >=22" 1299 + } 1300 + }, 1301 + "node_modules/glob/node_modules/brace-expansion": { 1302 + "version": "5.0.5", 1303 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", 1304 + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", 1305 + "dev": true, 1306 + "license": "MIT", 1307 + "dependencies": { 1308 + "balanced-match": "^4.0.2" 1309 + }, 1310 + "engines": { 1311 + "node": "18 || 20 || >=22" 1312 + } 1313 + }, 1314 + "node_modules/glob/node_modules/minimatch": { 1315 + "version": "10.2.5", 1316 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", 1317 + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", 1318 + "dev": true, 1319 + "license": "BlueOak-1.0.0", 1320 + "dependencies": { 1321 + "brace-expansion": "^5.0.5" 1322 + }, 1323 + "engines": { 1324 + "node": "18 || 20 || >=22" 1325 + }, 1326 + "funding": { 1327 + "url": "https://github.com/sponsors/isaacs" 1328 + } 1329 + }, 1330 + "node_modules/graceful-fs": { 1331 + "version": "4.2.11", 1332 + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1333 + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 1334 + "dev": true, 1335 + "license": "ISC" 1336 + }, 1337 + "node_modules/https-proxy-agent": { 1338 + "version": "7.0.6", 1339 + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", 1340 + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", 1341 + "dev": true, 1342 + "license": "MIT", 1343 + "dependencies": { 1344 + "agent-base": "^7.1.2", 1345 + "debug": "4" 1346 + }, 1347 + "engines": { 1348 + "node": ">= 14" 1349 + } 1350 + }, 1351 + "node_modules/is-extglob": { 1352 + "version": "2.1.1", 1353 + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1354 + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1355 + "dev": true, 1356 + "license": "MIT", 1357 + "engines": { 1358 + "node": ">=0.10.0" 1359 + } 1360 + }, 1361 + "node_modules/is-glob": { 1362 + "version": "4.0.3", 1363 + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1364 + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1365 + "dev": true, 1366 + "license": "MIT", 1367 + "dependencies": { 1368 + "is-extglob": "^2.1.1" 1369 + }, 1370 + "engines": { 1371 + "node": ">=0.10.0" 1372 + } 1373 + }, 1374 + "node_modules/is-number": { 1375 + "version": "7.0.0", 1376 + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1377 + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1378 + "dev": true, 1379 + "license": "MIT", 1380 + "engines": { 1381 + "node": ">=0.12.0" 1382 + } 1383 + }, 1384 + "node_modules/js-yaml": { 1385 + "version": "4.1.1", 1386 + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", 1387 + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", 1388 + "dev": true, 1389 + "license": "MIT", 1390 + "dependencies": { 1391 + "argparse": "^2.0.1" 1392 + }, 1393 + "bin": { 1394 + "js-yaml": "bin/js-yaml.js" 1395 + } 1396 + }, 1397 + "node_modules/json-schema-to-ts": { 1398 + "version": "1.6.4", 1399 + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-1.6.4.tgz", 1400 + "integrity": "sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==", 1401 + "dev": true, 1402 + "license": "MIT", 1403 + "dependencies": { 1404 + "@types/json-schema": "^7.0.6", 1405 + "ts-toolbelt": "^6.15.5" 1406 + } 1407 + }, 1408 + "node_modules/json-schema-traverse": { 1409 + "version": "1.0.0", 1410 + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 1411 + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", 1412 + "dev": true, 1413 + "license": "MIT" 1414 + }, 1415 + "node_modules/jsonfile": { 1416 + "version": "6.2.1", 1417 + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", 1418 + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", 1419 + "dev": true, 1420 + "license": "MIT", 1421 + "dependencies": { 1422 + "universalify": "^2.0.0" 1423 + }, 1424 + "optionalDependencies": { 1425 + "graceful-fs": "^4.1.6" 1426 + } 1427 + }, 1428 + "node_modules/lru-cache": { 1429 + "version": "11.3.5", 1430 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", 1431 + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", 1432 + "dev": true, 1433 + "license": "BlueOak-1.0.0", 1434 + "engines": { 1435 + "node": "20 || >=22" 1436 + } 1437 + }, 1438 + "node_modules/merge2": { 1439 + "version": "1.4.1", 1440 + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1441 + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1442 + "dev": true, 1443 + "license": "MIT", 1444 + "engines": { 1445 + "node": ">= 8" 1446 + } 1447 + }, 1448 + "node_modules/micromatch": { 1449 + "version": "4.0.8", 1450 + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 1451 + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 1452 + "dev": true, 1453 + "license": "MIT", 1454 + "dependencies": { 1455 + "braces": "^3.0.3", 1456 + "picomatch": "^2.3.1" 1457 + }, 1458 + "engines": { 1459 + "node": ">=8.6" 1460 + } 1461 + }, 1462 + "node_modules/micromatch/node_modules/picomatch": { 1463 + "version": "2.3.2", 1464 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", 1465 + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", 1466 + "dev": true, 1467 + "license": "MIT", 1468 + "engines": { 1469 + "node": ">=8.6" 1470 + }, 1471 + "funding": { 1472 + "url": "https://github.com/sponsors/jonschlinkert" 1473 + } 1474 + }, 1475 + "node_modules/mime-db": { 1476 + "version": "1.52.0", 1477 + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1478 + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1479 + "dev": true, 1480 + "license": "MIT", 1481 + "engines": { 1482 + "node": ">= 0.6" 1483 + } 1484 + }, 1485 + "node_modules/mime-types": { 1486 + "version": "2.1.35", 1487 + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1488 + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1489 + "dev": true, 1490 + "license": "MIT", 1491 + "dependencies": { 1492 + "mime-db": "1.52.0" 1493 + }, 1494 + "engines": { 1495 + "node": ">= 0.6" 1496 + } 1497 + }, 1498 + "node_modules/minimatch": { 1499 + "version": "10.1.1", 1500 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", 1501 + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", 1502 + "dev": true, 1503 + "license": "BlueOak-1.0.0", 1504 + "dependencies": { 1505 + "@isaacs/brace-expansion": "^5.0.0" 1506 + }, 1507 + "engines": { 1508 + "node": "20 || >=22" 1509 + }, 1510 + "funding": { 1511 + "url": "https://github.com/sponsors/isaacs" 1512 + } 1513 + }, 1514 + "node_modules/minipass": { 1515 + "version": "7.1.3", 1516 + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", 1517 + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", 1518 + "dev": true, 1519 + "license": "BlueOak-1.0.0", 1520 + "engines": { 1521 + "node": ">=16 || 14 >=14.17" 1522 + } 1523 + }, 1524 + "node_modules/minizlib": { 1525 + "version": "3.1.0", 1526 + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", 1527 + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", 1528 + "dev": true, 1529 + "license": "MIT", 1530 + "dependencies": { 1531 + "minipass": "^7.1.2" 1532 + }, 1533 + "engines": { 1534 + "node": ">= 18" 1535 + } 1536 + }, 1537 + "node_modules/mkdirp": { 1538 + "version": "1.0.4", 1539 + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 1540 + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 1541 + "dev": true, 1542 + "license": "MIT", 1543 + "bin": { 1544 + "mkdirp": "bin/cmd.js" 1545 + }, 1546 + "engines": { 1547 + "node": ">=10" 1548 + } 1549 + }, 1550 + "node_modules/mri": { 1551 + "version": "1.2.0", 1552 + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", 1553 + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", 1554 + "dev": true, 1555 + "license": "MIT", 1556 + "engines": { 1557 + "node": ">=4" 1558 + } 1559 + }, 1560 + "node_modules/ms": { 1561 + "version": "2.1.3", 1562 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1563 + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1564 + "dev": true, 1565 + "license": "MIT" 1566 + }, 1567 + "node_modules/node-fetch": { 1568 + "version": "2.6.9", 1569 + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", 1570 + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", 1571 + "dev": true, 1572 + "license": "MIT", 1573 + "dependencies": { 1574 + "whatwg-url": "^5.0.0" 1575 + }, 1576 + "engines": { 1577 + "node": "4.x || >=6.0.0" 1578 + }, 1579 + "peerDependencies": { 1580 + "encoding": "^0.1.0" 1581 + }, 1582 + "peerDependenciesMeta": { 1583 + "encoding": { 1584 + "optional": true 1585 + } 1586 + } 1587 + }, 1588 + "node_modules/node-gyp-build": { 1589 + "version": "4.8.4", 1590 + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", 1591 + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", 1592 + "dev": true, 1593 + "license": "MIT", 1594 + "bin": { 1595 + "node-gyp-build": "bin.js", 1596 + "node-gyp-build-optional": "optional.js", 1597 + "node-gyp-build-test": "build-test.js" 1598 + } 1599 + }, 1600 + "node_modules/nopt": { 1601 + "version": "8.1.0", 1602 + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", 1603 + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", 1604 + "dev": true, 1605 + "license": "ISC", 1606 + "dependencies": { 1607 + "abbrev": "^3.0.0" 1608 + }, 1609 + "bin": { 1610 + "nopt": "bin/nopt.js" 1611 + }, 1612 + "engines": { 1613 + "node": "^18.17.0 || >=20.5.0" 1614 + } 1615 + }, 1616 + "node_modules/parse-ms": { 1617 + "version": "2.1.0", 1618 + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", 1619 + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", 1620 + "dev": true, 1621 + "license": "MIT", 1622 + "engines": { 1623 + "node": ">=6" 1624 + } 1625 + }, 1626 + "node_modules/path-browserify": { 1627 + "version": "1.0.1", 1628 + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", 1629 + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", 1630 + "dev": true, 1631 + "license": "MIT" 1632 + }, 1633 + "node_modules/path-scurry": { 1634 + "version": "2.0.2", 1635 + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", 1636 + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", 1637 + "dev": true, 1638 + "license": "BlueOak-1.0.0", 1639 + "dependencies": { 1640 + "lru-cache": "^11.0.0", 1641 + "minipass": "^7.1.2" 1642 + }, 1643 + "engines": { 1644 + "node": "18 || 20 || >=22" 1645 + }, 1646 + "funding": { 1647 + "url": "https://github.com/sponsors/isaacs" 1648 + } 1649 + }, 1650 + "node_modules/path-to-regexp": { 1651 + "version": "6.1.0", 1652 + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.1.0.tgz", 1653 + "integrity": "sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==", 1654 + "dev": true, 1655 + "license": "MIT" 1656 + }, 1657 + "node_modules/path-to-regexp-updated": { 1658 + "name": "path-to-regexp", 1659 + "version": "6.3.0", 1660 + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", 1661 + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", 1662 + "dev": true, 1663 + "license": "MIT" 1664 + }, 1665 + "node_modules/picocolors": { 1666 + "version": "1.0.0", 1667 + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1668 + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1669 + "dev": true, 1670 + "license": "ISC" 1671 + }, 1672 + "node_modules/picomatch": { 1673 + "version": "4.0.4", 1674 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", 1675 + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", 1676 + "dev": true, 1677 + "license": "MIT", 1678 + "engines": { 1679 + "node": ">=12" 1680 + }, 1681 + "funding": { 1682 + "url": "https://github.com/sponsors/jonschlinkert" 1683 + } 1684 + }, 1685 + "node_modules/pretty-ms": { 1686 + "version": "7.0.1", 1687 + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", 1688 + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", 1689 + "dev": true, 1690 + "license": "MIT", 1691 + "dependencies": { 1692 + "parse-ms": "^2.1.0" 1693 + }, 1694 + "engines": { 1695 + "node": ">=10" 1696 + }, 1697 + "funding": { 1698 + "url": "https://github.com/sponsors/sindresorhus" 1699 + } 1700 + }, 1701 + "node_modules/punycode": { 1702 + "version": "2.3.1", 1703 + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1704 + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1705 + "dev": true, 1706 + "license": "MIT", 1707 + "engines": { 1708 + "node": ">=6" 1709 + } 1710 + }, 1711 + "node_modules/queue-microtask": { 1712 + "version": "1.2.3", 1713 + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1714 + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1715 + "dev": true, 1716 + "funding": [ 1717 + { 1718 + "type": "github", 1719 + "url": "https://github.com/sponsors/feross" 1720 + }, 1721 + { 1722 + "type": "patreon", 1723 + "url": "https://www.patreon.com/feross" 1724 + }, 1725 + { 1726 + "type": "consulting", 1727 + "url": "https://feross.org/support" 1728 + } 1729 + ], 1730 + "license": "MIT" 1731 + }, 1732 + "node_modules/require-from-string": { 1733 + "version": "2.0.2", 1734 + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 1735 + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 1736 + "dev": true, 1737 + "license": "MIT", 1738 + "engines": { 1739 + "node": ">=0.10.0" 1740 + } 1741 + }, 1742 + "node_modules/resolve-from": { 1743 + "version": "5.0.0", 1744 + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 1745 + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 1746 + "dev": true, 1747 + "license": "MIT", 1748 + "engines": { 1749 + "node": ">=8" 1750 + } 1751 + }, 1752 + "node_modules/resolve-pkg-maps": { 1753 + "version": "1.0.0", 1754 + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 1755 + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 1756 + "dev": true, 1757 + "license": "MIT", 1758 + "funding": { 1759 + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" 1760 + } 1761 + }, 1762 + "node_modules/reusify": { 1763 + "version": "1.1.0", 1764 + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", 1765 + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", 1766 + "dev": true, 1767 + "license": "MIT", 1768 + "engines": { 1769 + "iojs": ">=1.0.0", 1770 + "node": ">=0.10.0" 1771 + } 1772 + }, 1773 + "node_modules/run-parallel": { 1774 + "version": "1.2.0", 1775 + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1776 + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1777 + "dev": true, 1778 + "funding": [ 1779 + { 1780 + "type": "github", 1781 + "url": "https://github.com/sponsors/feross" 1782 + }, 1783 + { 1784 + "type": "patreon", 1785 + "url": "https://www.patreon.com/feross" 1786 + }, 1787 + { 1788 + "type": "consulting", 1789 + "url": "https://feross.org/support" 1790 + } 1791 + ], 1792 + "license": "MIT", 1793 + "dependencies": { 1794 + "queue-microtask": "^1.2.2" 1795 + } 1796 + }, 1797 + "node_modules/semver": { 1798 + "version": "7.7.4", 1799 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", 1800 + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", 1801 + "dev": true, 1802 + "license": "ISC", 1803 + "bin": { 1804 + "semver": "bin/semver.js" 1805 + }, 1806 + "engines": { 1807 + "node": ">=10" 1808 + } 1809 + }, 1810 + "node_modules/signal-exit": { 1811 + "version": "4.0.2", 1812 + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", 1813 + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", 1814 + "dev": true, 1815 + "license": "ISC", 1816 + "engines": { 1817 + "node": ">=14" 1818 + }, 1819 + "funding": { 1820 + "url": "https://github.com/sponsors/isaacs" 1821 + } 1822 + }, 1823 + "node_modules/smol-toml": { 1824 + "version": "1.5.2", 1825 + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.5.2.tgz", 1826 + "integrity": "sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==", 1827 + "dev": true, 1828 + "license": "BSD-3-Clause", 1829 + "engines": { 1830 + "node": ">= 18" 1831 + }, 1832 + "funding": { 1833 + "url": "https://github.com/sponsors/cyyynthia" 1834 + } 1835 + }, 1836 + "node_modules/strnum": { 1837 + "version": "1.1.2", 1838 + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", 1839 + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", 1840 + "funding": [ 1841 + { 1842 + "type": "github", 1843 + "url": "https://github.com/sponsors/NaturalIntelligence" 1844 + } 1845 + ], 1846 + "license": "MIT" 1847 + }, 1848 + "node_modules/tar": { 1849 + "version": "7.5.13", 1850 + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", 1851 + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", 1852 + "dev": true, 1853 + "license": "BlueOak-1.0.0", 1854 + "dependencies": { 1855 + "@isaacs/fs-minipass": "^4.0.0", 1856 + "chownr": "^3.0.0", 1857 + "minipass": "^7.1.2", 1858 + "minizlib": "^3.1.0", 1859 + "yallist": "^5.0.0" 1860 + }, 1861 + "engines": { 1862 + "node": ">=18" 1863 + } 1864 + }, 1865 + "node_modules/time-span": { 1866 + "version": "4.0.0", 1867 + "resolved": "https://registry.npmjs.org/time-span/-/time-span-4.0.0.tgz", 1868 + "integrity": "sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==", 1869 + "dev": true, 1870 + "license": "MIT", 1871 + "dependencies": { 1872 + "convert-hrtime": "^3.0.0" 1873 + }, 1874 + "engines": { 1875 + "node": ">=10" 1876 + }, 1877 + "funding": { 1878 + "url": "https://github.com/sponsors/sindresorhus" 1879 + } 1880 + }, 1881 + "node_modules/to-regex-range": { 1882 + "version": "5.0.1", 1883 + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1884 + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1885 + "dev": true, 1886 + "license": "MIT", 1887 + "dependencies": { 1888 + "is-number": "^7.0.0" 1889 + }, 1890 + "engines": { 1891 + "node": ">=8.0" 1892 + } 1893 + }, 1894 + "node_modules/tr46": { 1895 + "version": "0.0.3", 1896 + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 1897 + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", 1898 + "dev": true, 1899 + "license": "MIT" 1900 + }, 1901 + "node_modules/ts-morph": { 1902 + "version": "12.0.0", 1903 + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-12.0.0.tgz", 1904 + "integrity": "sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==", 1905 + "dev": true, 1906 + "license": "MIT", 1907 + "dependencies": { 1908 + "@ts-morph/common": "~0.11.0", 1909 + "code-block-writer": "^10.1.1" 1910 + } 1911 + }, 1912 + "node_modules/ts-toolbelt": { 1913 + "version": "6.15.5", 1914 + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", 1915 + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==", 1916 + "dev": true, 1917 + "license": "Apache-2.0" 1918 + }, 1919 + "node_modules/tsx": { 1920 + "version": "4.21.0", 1921 + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", 1922 + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", 1923 + "dev": true, 1924 + "license": "MIT", 1925 + "dependencies": { 1926 + "esbuild": "~0.27.0", 1927 + "get-tsconfig": "^4.7.5" 1928 + }, 1929 + "bin": { 1930 + "tsx": "dist/cli.mjs" 1931 + }, 1932 + "engines": { 1933 + "node": ">=18.0.0" 1934 + }, 1935 + "optionalDependencies": { 1936 + "fsevents": "~2.3.3" 1937 + } 1938 + }, 1939 + "node_modules/typescript": { 1940 + "version": "5.9.3", 1941 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", 1942 + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", 1943 + "dev": true, 1944 + "license": "Apache-2.0", 1945 + "bin": { 1946 + "tsc": "bin/tsc", 1947 + "tsserver": "bin/tsserver" 1948 + }, 1949 + "engines": { 1950 + "node": ">=14.17" 1951 + } 1952 + }, 1953 + "node_modules/undici": { 1954 + "version": "5.28.4", 1955 + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", 1956 + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", 1957 + "dev": true, 1958 + "license": "MIT", 1959 + "dependencies": { 1960 + "@fastify/busboy": "^2.0.0" 1961 + }, 1962 + "engines": { 1963 + "node": ">=14.0" 1964 + } 1965 + }, 1966 + "node_modules/undici-types": { 1967 + "version": "6.21.0", 1968 + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", 1969 + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", 1970 + "dev": true, 1971 + "license": "MIT" 1972 + }, 1973 + "node_modules/universalify": { 1974 + "version": "2.0.1", 1975 + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", 1976 + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", 1977 + "dev": true, 1978 + "license": "MIT", 1979 + "engines": { 1980 + "node": ">= 10.0.0" 1981 + } 1982 + }, 1983 + "node_modules/uri-js": { 1984 + "version": "4.4.1", 1985 + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1986 + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1987 + "dev": true, 1988 + "license": "BSD-2-Clause", 1989 + "dependencies": { 1990 + "punycode": "^2.1.0" 1991 + } 1992 + }, 1993 + "node_modules/webidl-conversions": { 1994 + "version": "3.0.1", 1995 + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 1996 + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", 1997 + "dev": true, 1998 + "license": "BSD-2-Clause" 1999 + }, 2000 + "node_modules/whatwg-url": { 2001 + "version": "5.0.0", 2002 + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 2003 + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 2004 + "dev": true, 2005 + "license": "MIT", 2006 + "dependencies": { 2007 + "tr46": "~0.0.3", 2008 + "webidl-conversions": "^3.0.0" 2009 + } 2010 + }, 2011 + "node_modules/yallist": { 2012 + "version": "5.0.0", 2013 + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", 2014 + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", 2015 + "dev": true, 2016 + "license": "BlueOak-1.0.0", 2017 + "engines": { 2018 + "node": ">=18" 2019 + } 2020 + }, 2021 + "node_modules/zod": { 2022 + "version": "3.22.4", 2023 + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", 2024 + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", 2025 + "dev": true, 2026 + "license": "MIT", 2027 + "funding": { 2028 + "url": "https://github.com/sponsors/colinhacks" 2029 + } 2030 + } 2031 + } 2032 + }
+18
package.json
··· 1 + { 2 + "name": "tangled-activity", 3 + "version": "0.1.0", 4 + "private": true, 5 + "scripts": { 6 + "build": "tsc --noEmit", 7 + "dev": "tsx src/localDevServer.ts" 8 + }, 9 + "dependencies": { 10 + "fast-xml-parser": "^4.5.3" 11 + }, 12 + "devDependencies": { 13 + "@types/node": "^22.15.3", 14 + "@vercel/node": "^5.1.14", 15 + "tsx": "^4.19.2", 16 + "typescript": "^5.8.3" 17 + } 18 + }
+68
src/localDevServer.ts
··· 1 + import http from 'node:http'; 2 + import { URL } from 'node:url'; 3 + 4 + import { 5 + buildGraphSvg, 6 + clampRange, 7 + fetchActivityByDay, 8 + normalizeAccount, 9 + } from './tangledGraph'; 10 + 11 + const PORT = Number(process.env.PORT ?? 3000); 12 + 13 + const server = http.createServer(async (req, res) => { 14 + if (!req.url) { 15 + res.statusCode = 400; 16 + res.end('Bad Request'); 17 + return; 18 + } 19 + 20 + const url = new URL(req.url, `http://localhost:${PORT}`); 21 + 22 + if (url.pathname !== '/api/graph') { 23 + res.statusCode = 404; 24 + res.setHeader('Content-Type', 'text/plain; charset=utf-8'); 25 + res.end('Not Found'); 26 + return; 27 + } 28 + 29 + const account = normalizeAccount(url.searchParams.get('account') ?? undefined); 30 + const range = clampRange(url.searchParams.get('range') ?? undefined); 31 + 32 + res.setHeader('Content-Type', 'image/svg+xml; charset=utf-8'); 33 + res.setHeader('Cache-Control', 'no-store'); 34 + 35 + if (!account) { 36 + res.statusCode = 400; 37 + res.end( 38 + buildGraphSvg({ 39 + account: 'unknown', 40 + range, 41 + days: [], 42 + error: 'Missing or invalid account parameter', 43 + }), 44 + ); 45 + return; 46 + } 47 + 48 + try { 49 + const days = await fetchActivityByDay(account, range); 50 + res.statusCode = 200; 51 + res.end(buildGraphSvg({ account, range, days })); 52 + } catch (error) { 53 + const message = error instanceof Error ? error.message : 'Failed to load feed'; 54 + res.statusCode = 502; 55 + res.end( 56 + buildGraphSvg({ 57 + account, 58 + range, 59 + days: [], 60 + error: message, 61 + }), 62 + ); 63 + } 64 + }); 65 + 66 + server.listen(PORT, () => { 67 + process.stdout.write(`Local server running at http://localhost:${PORT}\n`); 68 + });
+327
src/tangledGraph.ts
··· 1 + import { XMLParser } from 'fast-xml-parser'; 2 + 3 + type ActivityMap = Map<string, number>; 4 + 5 + type HeatmapDay = { 6 + date: Date; 7 + isoDate: string; 8 + count: number; 9 + level: 0 | 1 | 2 | 3 | 4; 10 + weekIndex: number; 11 + weekdayIndex: number; 12 + inRange: boolean; 13 + }; 14 + 15 + type GraphSvgOptions = { 16 + account: string; 17 + range: number; 18 + days: HeatmapDay[]; 19 + error?: string; 20 + }; 21 + 22 + type ParsedFeed = { 23 + feed?: { 24 + entry?: Array<{ updated?: string }> | { updated?: string }; 25 + }; 26 + }; 27 + 28 + const CELL_SIZE = 11; 29 + const CELL_GAP = 3; 30 + const HEADER_HEIGHT = 68; 31 + const FOOTER_HEIGHT = 28; 32 + const LEFT_GUTTER = 36; 33 + const RIGHT_GUTTER = 16; 34 + const TOP_GUTTER = 18; 35 + const MONTH_LABEL_OFFSET = 12; 36 + const CARD_RADIUS = 12; 37 + const HEADER_TEXT_X = 16; 38 + const HEADER_TITLE_Y = 53; 39 + const LOGO_WIDTH = 140; 40 + const LOGO_HEIGHT = 24; 41 + const LOGO_URL = 'https://assets.tangled.network/tangled_logotype_black_on_trans.svg'; 42 + const MIN_CANVAS_WIDTH = 700; 43 + const HEADER_CHAR_WIDTH = 8.2; 44 + const SUMMARY_CHAR_WIDTH = 6.2; 45 + const WEEKDAY_LABELS = [ 46 + { label: 'Mon', row: 1 }, 47 + { label: 'Wed', row: 3 }, 48 + { label: 'Fri', row: 5 }, 49 + ]; 50 + const MONTH_LABELS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 51 + const HEATMAP_COLORS = ['#ebedf0', '#d1d5db', '#9ca3af', '#4b5563', '#111827'] as const; 52 + 53 + export function normalizeAccount(input: string | undefined): string | null { 54 + if (!input) { 55 + return null; 56 + } 57 + 58 + const account = input.trim().replace(/^@/, ''); 59 + if (!account || !/^[a-z0-9._-]+$/i.test(account)) { 60 + return null; 61 + } 62 + 63 + return account; 64 + } 65 + 66 + export function clampRange(input: string | undefined): number { 67 + const parsed = Number.parseInt(input ?? '12', 10); 68 + if (Number.isNaN(parsed)) { 69 + return 12; 70 + } 71 + 72 + return Math.min(12, Math.max(1, parsed)); 73 + } 74 + 75 + export async function fetchActivityByDay(account: string, range: number): Promise<HeatmapDay[]> { 76 + const feedUrl = `https://tangled.org/${encodeURIComponent(account)}/feed.atom`; 77 + const response = await fetch(feedUrl, { 78 + headers: { 79 + Accept: 'application/atom+xml, application/xml, text/xml;q=0.9, */*;q=0.8', 80 + 'User-Agent': 'tangled-activity-graph', 81 + }, 82 + }); 83 + 84 + if (!response.ok) { 85 + throw new Error(`Feed request failed with ${response.status}`); 86 + } 87 + 88 + const xml = await response.text(); 89 + const parser = new XMLParser({ 90 + ignoreAttributes: false, 91 + removeNSPrefix: true, 92 + parseTagValue: true, 93 + trimValues: true, 94 + }); 95 + const parsed = parser.parse(xml) as ParsedFeed; 96 + const entries = toEntryArray(parsed.feed?.entry); 97 + 98 + const now = startOfUtcDay(new Date()); 99 + const rangeStart = startOfUtcDay(subtractUtcMonths(now, range)); 100 + const calendarStart = startOfUtcWeek(rangeStart); 101 + const counts = aggregateEntries(entries, rangeStart, now); 102 + 103 + return buildDays(counts, rangeStart, calendarStart, now); 104 + } 105 + 106 + export function buildGraphSvg({ account, range, days, error }: GraphSvgOptions): string { 107 + const weekCount = days.length === 0 ? 1 : Math.max(...days.map((day) => day.weekIndex)) + 1; 108 + const graphWidth = weekCount * (CELL_SIZE + CELL_GAP) - CELL_GAP; 109 + const graphHeight = 7 * (CELL_SIZE + CELL_GAP) - CELL_GAP; 110 + const graphStartY = TOP_GUTTER + HEADER_HEIGHT; 111 + const baseGraphWidth = LEFT_GUTTER + graphWidth + RIGHT_GUTTER; 112 + const headerText = `@${account} Tangled activity`; 113 + 114 + const monthLabels = buildMonthLabels(days); 115 + const maxCount = days.reduce((max, day) => Math.max(max, day.count), 0); 116 + const activeDays = days.reduce((sum, day) => sum + (day.count > 0 ? 1 : 0), 0); 117 + const totalCount = days.reduce((sum, day) => sum + day.count, 0); 118 + const summaryText = error 119 + ? error 120 + : `${totalCount} activities on ${activeDays} active days, peak ${maxCount}/day`; 121 + const headerRequiredWidth = HEADER_TEXT_X + Math.ceil(headerText.length * HEADER_CHAR_WIDTH) + RIGHT_GUTTER; 122 + const summaryRequiredWidth = LEFT_GUTTER + Math.ceil(summaryText.length * SUMMARY_CHAR_WIDTH) + RIGHT_GUTTER; 123 + const width = Math.max(MIN_CANVAS_WIDTH, baseGraphWidth, headerRequiredWidth, summaryRequiredWidth); 124 + const height = TOP_GUTTER + HEADER_HEIGHT + graphHeight + FOOTER_HEIGHT; 125 + 126 + const rects = days 127 + .map((day) => { 128 + const x = LEFT_GUTTER + day.weekIndex * (CELL_SIZE + CELL_GAP); 129 + const y = graphStartY + day.weekdayIndex * (CELL_SIZE + CELL_GAP); 130 + const fill = day.inRange ? HEATMAP_COLORS[day.level] : '#f8fafc'; 131 + const stroke = day.inRange ? 'none' : '#e5e7eb'; 132 + const tooltip = `${day.isoDate}: ${day.count} activit${day.count === 1 ? 'y' : 'ies'}`; 133 + 134 + return `<g><title>${escapeXml(tooltip)}</title><rect x="${x}" y="${y}" width="${CELL_SIZE}" height="${CELL_SIZE}" rx="2" fill="${fill}" stroke="${stroke}" /></g>`; 135 + }) 136 + .join(''); 137 + 138 + const weekdays = WEEKDAY_LABELS.map(({ label, row }) => { 139 + const y = graphStartY + row * (CELL_SIZE + CELL_GAP) + CELL_SIZE - 1; 140 + return `<text x="8" y="${y}" font-size="10" fill="#6b7280">${label}</text>`; 141 + }).join(''); 142 + 143 + const months = monthLabels 144 + .map(({ label, weekIndex }) => { 145 + const x = LEFT_GUTTER + weekIndex * (CELL_SIZE + CELL_GAP); 146 + return `<text x="${x}" y="${graphStartY - MONTH_LABEL_OFFSET}" font-size="10" fill="#6b7280">${label}</text>`; 147 + }) 148 + .join(''); 149 + 150 + const summary = error 151 + ? `<text x="${LEFT_GUTTER}" y="${height - 10}" font-size="11" fill="#b91c1c">${escapeXml(error)}</text>` 152 + : `<text x="${LEFT_GUTTER}" y="${height - 10}" font-size="11" fill="#4b5563">${escapeXml(summaryText)}</text>`; 153 + const accountUrl = `https://tangled.org/@${encodeURIComponent(account)}`; 154 + 155 + return `<?xml version="1.0" encoding="UTF-8"?> 156 + <svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" preserveAspectRatio="xMinYMin meet" style="max-width:100%;height:auto" role="img" aria-labelledby="title desc"> 157 + <title id="title">${escapeXml(headerText)}</title> 158 + <desc id="desc">Calendar heatmap of Tangled activities for ${escapeXml(account)}</desc> 159 + <a href="${accountUrl}" target="_blank"> 160 + <rect width="100%" height="100%" rx="${CARD_RADIUS}" fill="#ffffff" stroke="#e5e7eb" /> 161 + <text x="${HEADER_TEXT_X}" y="${HEADER_TITLE_Y}" font-size="15" font-weight="600" fill="#111827">${escapeXml(headerText)}</text> 162 + 163 + ${months} 164 + ${weekdays} 165 + ${rects} 166 + ${summary} 167 + ${renderLogo(width, height)} 168 + </a> 169 + </svg>`; 170 + } 171 + 172 + function toEntryArray( 173 + entries: Array<{ updated?: string }> | { updated?: string } | undefined, 174 + ): Array<{ updated?: string }> { 175 + if (!entries) { 176 + return []; 177 + } 178 + 179 + return Array.isArray(entries) ? entries : [entries]; 180 + } 181 + 182 + function aggregateEntries( 183 + entries: Array<{ updated?: string }>, 184 + rangeStart: Date, 185 + rangeEnd: Date, 186 + ): ActivityMap { 187 + const counts: ActivityMap = new Map(); 188 + 189 + for (const entry of entries) { 190 + if (!entry.updated) { 191 + continue; 192 + } 193 + 194 + const updatedAt = new Date(entry.updated); 195 + if (Number.isNaN(updatedAt.getTime())) { 196 + continue; 197 + } 198 + 199 + const day = startOfUtcDay(updatedAt); 200 + if (day < rangeStart || day > rangeEnd) { 201 + continue; 202 + } 203 + 204 + const key = isoDay(day); 205 + counts.set(key, (counts.get(key) ?? 0) + 1); 206 + } 207 + 208 + return counts; 209 + } 210 + 211 + function buildDays( 212 + counts: ActivityMap, 213 + rangeStart: Date, 214 + calendarStart: Date, 215 + rangeEnd: Date, 216 + ): HeatmapDay[] { 217 + const days: HeatmapDay[] = []; 218 + 219 + for (let cursor = new Date(calendarStart); cursor <= rangeEnd; cursor = addUtcDays(cursor, 1)) { 220 + const isoDate = isoDay(cursor); 221 + const count = counts.get(isoDate) ?? 0; 222 + const inRange = cursor >= rangeStart && cursor <= rangeEnd; 223 + const weekIndex = Math.floor(diffDays(calendarStart, cursor) / 7); 224 + const weekdayIndex = cursor.getUTCDay(); 225 + 226 + days.push({ 227 + date: new Date(cursor), 228 + isoDate, 229 + count, 230 + level: inRange ? activityLevel(count) : 0, 231 + weekIndex, 232 + weekdayIndex, 233 + inRange, 234 + }); 235 + } 236 + 237 + return days; 238 + } 239 + 240 + function buildMonthLabels(days: HeatmapDay[]): Array<{ label: string; weekIndex: number }> { 241 + const seen = new Set<string>(); 242 + const labels: Array<{ label: string; weekIndex: number }> = []; 243 + 244 + for (const day of days) { 245 + if (!day.inRange) { 246 + continue; 247 + } 248 + 249 + const key = `${day.date.getUTCFullYear()}-${day.date.getUTCMonth()}`; 250 + if (seen.has(key)) { 251 + continue; 252 + } 253 + 254 + seen.add(key); 255 + labels.push({ 256 + label: MONTH_LABELS[day.date.getUTCMonth()], 257 + weekIndex: day.weekIndex, 258 + }); 259 + } 260 + 261 + return labels; 262 + } 263 + 264 + function activityLevel(count: number): 0 | 1 | 2 | 3 | 4 { 265 + if (count <= 0) { 266 + return 0; 267 + } 268 + if (count === 1) { 269 + return 1; 270 + } 271 + if (count <= 3) { 272 + return 2; 273 + } 274 + if (count <= 6) { 275 + return 3; 276 + } 277 + return 4; 278 + } 279 + 280 + function renderLogo(width: number, height: number): string { 281 + const x = width - RIGHT_GUTTER - LOGO_WIDTH; 282 + const y = height - FOOTER_HEIGHT + 1; 283 + 284 + return `<image x="${x}" y="${y}" width="${LOGO_WIDTH}" height="${LOGO_HEIGHT}" href="${LOGO_URL}" />`; 285 + } 286 + 287 + function subtractUtcMonths(date: Date, months: number): Date { 288 + const targetYear = date.getUTCFullYear(); 289 + const targetMonth = date.getUTCMonth() - months; 290 + const targetDay = Math.min(date.getUTCDate(), daysInUtcMonth(targetYear, targetMonth)); 291 + 292 + return new Date(Date.UTC(targetYear, targetMonth, targetDay)); 293 + } 294 + 295 + function startOfUtcWeek(date: Date): Date { 296 + return addUtcDays(date, -date.getUTCDay()); 297 + } 298 + 299 + function startOfUtcDay(date: Date): Date { 300 + return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())); 301 + } 302 + 303 + function addUtcDays(date: Date, days: number): Date { 304 + return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days)); 305 + } 306 + 307 + function diffDays(from: Date, to: Date): number { 308 + const millisecondsPerDay = 24 * 60 * 60 * 1000; 309 + return Math.round((to.getTime() - from.getTime()) / millisecondsPerDay); 310 + } 311 + 312 + function isoDay(date: Date): string { 313 + return date.toISOString().slice(0, 10); 314 + } 315 + 316 + function daysInUtcMonth(year: number, month: number): number { 317 + return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); 318 + } 319 + 320 + function escapeXml(value: string): string { 321 + return value 322 + .replace(/&/g, '&amp;') 323 + .replace(/</g, '&lt;') 324 + .replace(/>/g, '&gt;') 325 + .replace(/"/g, '&quot;') 326 + .replace(/'/g, '&apos;'); 327 + }
+15
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "target": "ES2022", 4 + "module": "CommonJS", 5 + "moduleResolution": "Node", 6 + "strict": true, 7 + "esModuleInterop": true, 8 + "forceConsistentCasingInFileNames": true, 9 + "skipLibCheck": true, 10 + "resolveJsonModule": true, 11 + "lib": ["ES2022", "DOM"], 12 + "types": ["node"] 13 + }, 14 + "include": ["api/**/*.ts", "src/**/*.ts"] 15 + }
+7
vercel.json
··· 1 + { 2 + "functions": { 3 + "api/**/*.ts": { 4 + "runtime": "@vercel/node@5.1.14" 5 + } 6 + } 7 + }