Compare changes

Choose any two refs to compare.

+26
.env.example
··· 1 + # Linkat Directory Configuration 2 + # Copy this file to .env and update with your values 3 + 4 + # Primary user DID (required if no users configured) 5 + DIRECTORY_OWNER=did:plc:your-did-here 6 + 7 + # Hide the directory owner's card (optional, default: false) 8 + HIDE_OWNER_CARD=false 9 + 10 + # Multiple users (comma-separated, optional) 11 + # These users will be displayed alongside DIRECTORY_OWNER 12 + PUBLIC_LINKAT_USERS=did:plc:user1,did:web:user2,did:plc:user3 13 + 14 + # Display user banner (optional, default: false) 15 + DISPLAY_USER_BANNER=false 16 + 17 + # Optional: Set to 'true' to display the user's description. Defaults to 'false'. 18 + # Note: This only affects the display of user descriptions on the home page cards. 19 + DISPLAY_USER_DESCRIPTION=false 20 + 21 + # Example DIDs: 22 + # DIRECTORY_OWNER=did:plc:abc123def456ghi789jkl012mno345pqr678stu 23 + # PUBLIC_LINKAT_USERS=did:plc:user1,did:plc:user2,did:plc:user3,did:plc:user4 24 + 25 + # Publicly accessible origin for prerendering (required) 26 + PUBLIC_ORIGIN=http://localhost:5713
+1
.gitignore
··· 185 185 .vercel 186 186 187 187 # End of https://www.toptal.com/developers/gitignore/api/node,macos,svelte,vercel 188 + git-diff.txt
+17 -1
.vscode/settings.json
··· 3 3 "css.validate": false, 4 4 "tailwindCSS.includeLanguages": { 5 5 "svelte": "html" 6 - } 6 + }, 7 + "cSpell.words": [ 8 + "atproto", 9 + "Decentralised", 10 + "diddoc", 11 + "Dids", 12 + "ewan", 13 + "ewanc", 14 + "Linkat", 15 + "mkizka", 16 + "pdsurl", 17 + "prerender", 18 + "prerendering", 19 + "rkey", 20 + "utilises", 21 + "xrpc" 22 + ] 7 23 }
+64 -57
README.md
··· 1 - # Website Template 1 + # Linkat Directory 2 2 3 3 [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) 4 4 5 - This repository provides a versatile frontend template, primarily designed for [WhiteWind](https://whtwnd.com/), a Markdown blog service utilising [ATProto](https://atproto.com/). It is built upon a customised version of [WhiteBreeze](https://github.com/hugeblank/whitebreeze), specifically derived from commit [ff402f3](https://github.com/ewanc26/website/commit/ff402f3460d86c40ead13294ae1ff5d8605f741c) of [my website](https://github.com/ewanc26/website). 6 - 7 - This template offers a pre-configured starting point with a robust structure, ready for customisation across various frontend projects, though its core focus remains WhiteWind compatibility. 5 + <img src="./static/logo.png" alt="Linkat Directory" width="100"/> 8 6 9 - ## Purpose 7 + ## Project Purpose 10 8 11 - This project serves as a foundational template to streamline the creation of WhiteWind-compatible blog frontends. It leverages the WhiteBreeze framework to provide a robust and customisable base for displaying AT Protocol-based blog posts. 9 + Linkat Directory is a SvelteKit application designed to serve as an alternate frontend to Linkat, providing a curated directory of links, primarily focusing on Bluesky profiles and content. It allows for the display of user profiles, including their Decentralised Identifiers (DIDs), handles, display names, avatars, and descriptions. The application is built with a focus on responsiveness and ease of use, providing a clean interface for discovering links. 12 10 13 11 ## Installation 14 12 15 - To commence using this template, ensure Node.js and npm are installed on your system. 13 + To set up the Linkat Directory locally, follow these steps: 14 + 15 + 1. **Clone the repository:** 16 + ```bash 17 + git clone git@github.com:ewanc26/linkat-directory.git 18 + cd linkat-directory 19 + ``` 16 20 17 - ### Prerequisites 21 + 2. **Install dependencies:** 22 + ```bash 23 + npm install 24 + ``` 18 25 19 - - Node.js (LTS version recommended) 20 - - npm (comes with Node.js) 21 - - Docker and Docker Compose (for Dockerised deployment) 26 + 3. **Configure environment variables:** 27 + Create a `.env` file in the project root based on `.env.example`. At a minimum, you should define `DIRECTORY_OWNER` or `PUBLIC_LINKAT_USERS`. 28 + 29 + Example for a single directory owner: 30 + ``` 31 + DIRECTORY_OWNER=did:plc:your-did-here 32 + ``` 33 + 34 + Example for multiple users: 35 + ``` 36 + PUBLIC_LINKAT_USERS=did:plc:user1,did:web:user2 37 + ``` 22 38 23 - ### Environment Variables 39 + Example for hiding the directory owner's card: 40 + ``` 41 + HIDE_OWNER_CARD=true 42 + ``` 24 43 25 - Prior to running the application, configure the following environment variables within a `.env` file located in the project root: 44 + Example for displaying the user banner (default: false): 45 + ``` 46 + DISPLAY_USER_BANNER=true 47 + ``` 26 48 27 - ```ini 28 - PUBLIC_ATPROTOCOL_USER="myhandle.bsky.social" # Your handle, or DID 49 + Example for controlling the display of the user description: 29 50 ``` 30 - #### Note 51 + DISPLAY_USER_DESCRIPTION=true 52 + ``` 31 53 32 - You should also add your DID to the `.static/.well-known/atproto-did` file if you want to use your domain as your AT Protocol handle. 54 + Note: `DISPLAY_USER_DESCRIPTION` only affects the display of user descriptions on the home page cards. 33 55 34 - #### Optional Environment Variables 35 - 36 - - `PUBLIC_LASTFM_USERNAME`: Required for the Now Playing (Last.fm) feature in `src/lib/components/profile/Status.svelte`. 37 - - `PUBLIC_ACTIVITYPUB_USER=@user@server.tld`: Enables ActivityPub compatibility for improved content sharing and discoverability. 56 + 4. **Run the development server:** 57 + ```bash 58 + npm run dev 59 + ``` 60 + The application will typically be accessible at `http://localhost:5173`. For prerendering, the `origin` defaults to `http://localhost:5713` unless the `PUBLIC_ORIGIN` environment variable is set. 38 61 39 62 ## Usage 40 63 41 - ### Development 42 - 43 - To run the project in development mode: 44 - 45 - ```sh 46 - npm install 47 - npm run dev 48 - ``` 49 - 50 - ### Production 51 - 52 - For optimal production deployment, the following record types are required in your [AT Protocol repository](https://atproto.com/specs/repository): 64 + Once the application is running, you can: 53 65 54 - #### Required Records 66 + - Browse the main directory page to see configured users. 67 + - View individual user profiles by navigating to `/user/[did]`, where `[did]` is the user's Decentralised Identifier. 68 + - The application dynamically generates Open Graph and Twitter metadata for improved social sharing. 55 69 56 - - `app.bsky.actor.profile`: Your profile. 57 - - `com.whtwnd.blog.entry`: Your blog posts. 58 - - `blue.linkat.board`: Your links. 70 + ## Project Structure 59 71 60 - ### Deployment 61 - 62 - #### Standalone 63 - 64 - To build and run the project as a standalone application: 72 + Key directories and files: 65 73 66 - ```sh 67 - npm install 68 - npm run build 69 - node index.js 70 - ``` 74 + - `src/routes/`: Contains SvelteKit routes, including the main page (`+page.svelte`) and user profile pages (`user/[did]/+page.svelte`). 75 + - `src/lib/components/`: Reusable Svelte components, such as `DynamicHead.svelte` for managing dynamic `<head>` content, and profile-related components. 76 + - `src/lib/css/`: Global CSS styles, including `app.css` (for general styling) and `variables.css` (for CSS variables). 77 + - `src/lib/utils/`: Utility functions, such as caching mechanisms. 78 + - `src/lib/profile/profile.ts`: Logic for fetching and processing user profile data from Bluesky. 79 + - `svelte.config.js`: SvelteKit configuration, including prerendering settings. The `origin` property in `prerender` now defaults to `http://localhost:5713` unless overridden by the `PUBLIC_ORIGIN` environment variable. 71 80 72 - Environment variables can be set before the last command, and the port can be configured with the `PORT` variable. 81 + ## Contributing 73 82 74 - #### Dockerised 83 + Contributions are welcome! Please ensure your code adheres to the project's coding standards, including British English for comments and documentation, and responsive design principles. 75 84 76 - To deploy using Docker: 85 + ## Credits 77 86 78 - 1. Modify `compose.yaml` to change the host port if necessary. 79 - 2. Run the following command: 87 + This project utilises data and concepts from: 80 88 81 - ```sh 82 - docker compose up -d 83 - ``` 89 + - [linkat.blue](https://linkat.blue) by [mkizka.dev](https://bsky.app/profile/did:plc:4gow62pk3vqpuwiwaslcwisa) 90 + - [atproto.com](https://atproto.com) by [Bluesky](https://bsky.social) 84 91 85 - ## Licensing 92 + ## License 86 93 87 - This project is a template based on WhiteBreeze. For comprehensive licensing details, please consult the `LICENSE` file within this repository. 94 + This project is licensed under the [GNU Affero General Public License Version 3](LICENSE).
+2539 -361
package-lock.json
··· 1 1 { 2 - "name": "website-template", 2 + "name": "linkat-directory", 3 3 "version": "0.0.1", 4 4 "lockfileVersion": 3, 5 5 "requires": true, 6 6 "packages": { 7 7 "": { 8 - "name": "website-template", 8 + "name": "linkat-directory", 9 9 "version": "0.0.1", 10 10 "dependencies": { 11 11 "@resvg/resvg-js": "^2.6.2", ··· 22 22 "unified": "^11.0.5" 23 23 }, 24 24 "devDependencies": { 25 - "@sveltejs/adapter-vercel": "^5.7.0", 25 + "@sveltejs/adapter-vercel": "^5.8.1", 26 26 "@sveltejs/kit": "^2.24.0", 27 27 "@sveltejs/vite-plugin-svelte": "^4.0.4", 28 28 "@tailwindcss/forms": "^0.5.9", ··· 44 44 }, 45 45 "node_modules/@alloc/quick-lru": { 46 46 "version": "5.2.0", 47 + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", 48 + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", 47 49 "dev": true, 48 50 "license": "MIT", 49 51 "engines": { ··· 55 57 }, 56 58 "node_modules/@ampproject/remapping": { 57 59 "version": "2.3.0", 60 + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 61 + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 58 62 "dev": true, 59 63 "license": "Apache-2.0", 60 64 "dependencies": { ··· 65 69 "node": ">=6.0.0" 66 70 } 67 71 }, 72 + "node_modules/@esbuild/aix-ppc64": { 73 + "version": "0.25.8", 74 + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", 75 + "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", 76 + "cpu": [ 77 + "ppc64" 78 + ], 79 + "dev": true, 80 + "license": "MIT", 81 + "optional": true, 82 + "os": [ 83 + "aix" 84 + ], 85 + "engines": { 86 + "node": ">=18" 87 + } 88 + }, 89 + "node_modules/@esbuild/android-arm": { 90 + "version": "0.25.8", 91 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", 92 + "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", 93 + "cpu": [ 94 + "arm" 95 + ], 96 + "dev": true, 97 + "license": "MIT", 98 + "optional": true, 99 + "os": [ 100 + "android" 101 + ], 102 + "engines": { 103 + "node": ">=18" 104 + } 105 + }, 106 + "node_modules/@esbuild/android-arm64": { 107 + "version": "0.25.8", 108 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", 109 + "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", 110 + "cpu": [ 111 + "arm64" 112 + ], 113 + "dev": true, 114 + "license": "MIT", 115 + "optional": true, 116 + "os": [ 117 + "android" 118 + ], 119 + "engines": { 120 + "node": ">=18" 121 + } 122 + }, 123 + "node_modules/@esbuild/android-x64": { 124 + "version": "0.25.8", 125 + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", 126 + "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", 127 + "cpu": [ 128 + "x64" 129 + ], 130 + "dev": true, 131 + "license": "MIT", 132 + "optional": true, 133 + "os": [ 134 + "android" 135 + ], 136 + "engines": { 137 + "node": ">=18" 138 + } 139 + }, 68 140 "node_modules/@esbuild/darwin-arm64": { 69 - "version": "0.21.5", 141 + "version": "0.25.8", 142 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", 143 + "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", 70 144 "cpu": [ 71 145 "arm64" 72 146 ], ··· 77 151 "darwin" 78 152 ], 79 153 "engines": { 80 - "node": ">=12" 154 + "node": ">=18" 155 + } 156 + }, 157 + "node_modules/@esbuild/darwin-x64": { 158 + "version": "0.25.8", 159 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", 160 + "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", 161 + "cpu": [ 162 + "x64" 163 + ], 164 + "dev": true, 165 + "license": "MIT", 166 + "optional": true, 167 + "os": [ 168 + "darwin" 169 + ], 170 + "engines": { 171 + "node": ">=18" 172 + } 173 + }, 174 + "node_modules/@esbuild/freebsd-arm64": { 175 + "version": "0.25.8", 176 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", 177 + "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", 178 + "cpu": [ 179 + "arm64" 180 + ], 181 + "dev": true, 182 + "license": "MIT", 183 + "optional": true, 184 + "os": [ 185 + "freebsd" 186 + ], 187 + "engines": { 188 + "node": ">=18" 189 + } 190 + }, 191 + "node_modules/@esbuild/freebsd-x64": { 192 + "version": "0.25.8", 193 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", 194 + "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", 195 + "cpu": [ 196 + "x64" 197 + ], 198 + "dev": true, 199 + "license": "MIT", 200 + "optional": true, 201 + "os": [ 202 + "freebsd" 203 + ], 204 + "engines": { 205 + "node": ">=18" 206 + } 207 + }, 208 + "node_modules/@esbuild/linux-arm": { 209 + "version": "0.25.8", 210 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", 211 + "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", 212 + "cpu": [ 213 + "arm" 214 + ], 215 + "dev": true, 216 + "license": "MIT", 217 + "optional": true, 218 + "os": [ 219 + "linux" 220 + ], 221 + "engines": { 222 + "node": ">=18" 223 + } 224 + }, 225 + "node_modules/@esbuild/linux-arm64": { 226 + "version": "0.25.8", 227 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", 228 + "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", 229 + "cpu": [ 230 + "arm64" 231 + ], 232 + "dev": true, 233 + "license": "MIT", 234 + "optional": true, 235 + "os": [ 236 + "linux" 237 + ], 238 + "engines": { 239 + "node": ">=18" 240 + } 241 + }, 242 + "node_modules/@esbuild/linux-ia32": { 243 + "version": "0.25.8", 244 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", 245 + "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", 246 + "cpu": [ 247 + "ia32" 248 + ], 249 + "dev": true, 250 + "license": "MIT", 251 + "optional": true, 252 + "os": [ 253 + "linux" 254 + ], 255 + "engines": { 256 + "node": ">=18" 257 + } 258 + }, 259 + "node_modules/@esbuild/linux-loong64": { 260 + "version": "0.25.8", 261 + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", 262 + "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", 263 + "cpu": [ 264 + "loong64" 265 + ], 266 + "dev": true, 267 + "license": "MIT", 268 + "optional": true, 269 + "os": [ 270 + "linux" 271 + ], 272 + "engines": { 273 + "node": ">=18" 274 + } 275 + }, 276 + "node_modules/@esbuild/linux-mips64el": { 277 + "version": "0.25.8", 278 + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", 279 + "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", 280 + "cpu": [ 281 + "mips64el" 282 + ], 283 + "dev": true, 284 + "license": "MIT", 285 + "optional": true, 286 + "os": [ 287 + "linux" 288 + ], 289 + "engines": { 290 + "node": ">=18" 291 + } 292 + }, 293 + "node_modules/@esbuild/linux-ppc64": { 294 + "version": "0.25.8", 295 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", 296 + "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", 297 + "cpu": [ 298 + "ppc64" 299 + ], 300 + "dev": true, 301 + "license": "MIT", 302 + "optional": true, 303 + "os": [ 304 + "linux" 305 + ], 306 + "engines": { 307 + "node": ">=18" 308 + } 309 + }, 310 + "node_modules/@esbuild/linux-riscv64": { 311 + "version": "0.25.8", 312 + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", 313 + "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", 314 + "cpu": [ 315 + "riscv64" 316 + ], 317 + "dev": true, 318 + "license": "MIT", 319 + "optional": true, 320 + "os": [ 321 + "linux" 322 + ], 323 + "engines": { 324 + "node": ">=18" 325 + } 326 + }, 327 + "node_modules/@esbuild/linux-s390x": { 328 + "version": "0.25.8", 329 + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", 330 + "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", 331 + "cpu": [ 332 + "s390x" 333 + ], 334 + "dev": true, 335 + "license": "MIT", 336 + "optional": true, 337 + "os": [ 338 + "linux" 339 + ], 340 + "engines": { 341 + "node": ">=18" 342 + } 343 + }, 344 + "node_modules/@esbuild/linux-x64": { 345 + "version": "0.25.8", 346 + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", 347 + "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", 348 + "cpu": [ 349 + "x64" 350 + ], 351 + "dev": true, 352 + "license": "MIT", 353 + "optional": true, 354 + "os": [ 355 + "linux" 356 + ], 357 + "engines": { 358 + "node": ">=18" 359 + } 360 + }, 361 + "node_modules/@esbuild/netbsd-arm64": { 362 + "version": "0.25.8", 363 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", 364 + "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", 365 + "cpu": [ 366 + "arm64" 367 + ], 368 + "dev": true, 369 + "license": "MIT", 370 + "optional": true, 371 + "os": [ 372 + "netbsd" 373 + ], 374 + "engines": { 375 + "node": ">=18" 376 + } 377 + }, 378 + "node_modules/@esbuild/netbsd-x64": { 379 + "version": "0.25.8", 380 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", 381 + "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", 382 + "cpu": [ 383 + "x64" 384 + ], 385 + "dev": true, 386 + "license": "MIT", 387 + "optional": true, 388 + "os": [ 389 + "netbsd" 390 + ], 391 + "engines": { 392 + "node": ">=18" 393 + } 394 + }, 395 + "node_modules/@esbuild/openbsd-arm64": { 396 + "version": "0.25.8", 397 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", 398 + "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", 399 + "cpu": [ 400 + "arm64" 401 + ], 402 + "dev": true, 403 + "license": "MIT", 404 + "optional": true, 405 + "os": [ 406 + "openbsd" 407 + ], 408 + "engines": { 409 + "node": ">=18" 410 + } 411 + }, 412 + "node_modules/@esbuild/openbsd-x64": { 413 + "version": "0.25.8", 414 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", 415 + "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", 416 + "cpu": [ 417 + "x64" 418 + ], 419 + "dev": true, 420 + "license": "MIT", 421 + "optional": true, 422 + "os": [ 423 + "openbsd" 424 + ], 425 + "engines": { 426 + "node": ">=18" 427 + } 428 + }, 429 + "node_modules/@esbuild/openharmony-arm64": { 430 + "version": "0.25.8", 431 + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", 432 + "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", 433 + "cpu": [ 434 + "arm64" 435 + ], 436 + "dev": true, 437 + "license": "MIT", 438 + "optional": true, 439 + "os": [ 440 + "openharmony" 441 + ], 442 + "engines": { 443 + "node": ">=18" 444 + } 445 + }, 446 + "node_modules/@esbuild/sunos-x64": { 447 + "version": "0.25.8", 448 + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", 449 + "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", 450 + "cpu": [ 451 + "x64" 452 + ], 453 + "dev": true, 454 + "license": "MIT", 455 + "optional": true, 456 + "os": [ 457 + "sunos" 458 + ], 459 + "engines": { 460 + "node": ">=18" 461 + } 462 + }, 463 + "node_modules/@esbuild/win32-arm64": { 464 + "version": "0.25.8", 465 + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", 466 + "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", 467 + "cpu": [ 468 + "arm64" 469 + ], 470 + "dev": true, 471 + "license": "MIT", 472 + "optional": true, 473 + "os": [ 474 + "win32" 475 + ], 476 + "engines": { 477 + "node": ">=18" 478 + } 479 + }, 480 + "node_modules/@esbuild/win32-ia32": { 481 + "version": "0.25.8", 482 + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", 483 + "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", 484 + "cpu": [ 485 + "ia32" 486 + ], 487 + "dev": true, 488 + "license": "MIT", 489 + "optional": true, 490 + "os": [ 491 + "win32" 492 + ], 493 + "engines": { 494 + "node": ">=18" 495 + } 496 + }, 497 + "node_modules/@esbuild/win32-x64": { 498 + "version": "0.25.8", 499 + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", 500 + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", 501 + "cpu": [ 502 + "x64" 503 + ], 504 + "dev": true, 505 + "license": "MIT", 506 + "optional": true, 507 + "os": [ 508 + "win32" 509 + ], 510 + "engines": { 511 + "node": ">=18" 81 512 } 82 513 }, 83 514 "node_modules/@eslint-community/eslint-utils": { 84 - "version": "4.4.1", 515 + "version": "4.7.0", 516 + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", 517 + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", 85 518 "dev": true, 86 519 "license": "MIT", 87 520 "dependencies": { ··· 99 532 }, 100 533 "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 101 534 "version": "3.4.3", 535 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 536 + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 102 537 "dev": true, 103 538 "license": "Apache-2.0", 104 539 "engines": { ··· 110 545 }, 111 546 "node_modules/@eslint-community/regexpp": { 112 547 "version": "4.12.1", 548 + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 549 + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 113 550 "dev": true, 114 551 "license": "MIT", 115 552 "engines": { ··· 117 554 } 118 555 }, 119 556 "node_modules/@eslint/config-array": { 120 - "version": "0.19.0", 557 + "version": "0.21.0", 558 + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", 559 + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", 121 560 "dev": true, 122 561 "license": "Apache-2.0", 123 562 "dependencies": { 124 - "@eslint/object-schema": "^2.1.4", 563 + "@eslint/object-schema": "^2.1.6", 125 564 "debug": "^4.3.1", 126 565 "minimatch": "^3.1.2" 127 566 }, ··· 129 568 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 130 569 } 131 570 }, 571 + "node_modules/@eslint/config-helpers": { 572 + "version": "0.3.0", 573 + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", 574 + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", 575 + "dev": true, 576 + "license": "Apache-2.0", 577 + "engines": { 578 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 579 + } 580 + }, 132 581 "node_modules/@eslint/core": { 133 - "version": "0.9.0", 582 + "version": "0.15.1", 583 + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", 584 + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", 134 585 "dev": true, 135 586 "license": "Apache-2.0", 587 + "dependencies": { 588 + "@types/json-schema": "^7.0.15" 589 + }, 136 590 "engines": { 137 591 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 138 592 } 139 593 }, 140 594 "node_modules/@eslint/eslintrc": { 141 - "version": "3.2.0", 595 + "version": "3.3.1", 596 + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", 597 + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", 142 598 "dev": true, 143 599 "license": "MIT", 144 600 "dependencies": { ··· 161 617 }, 162 618 "node_modules/@eslint/eslintrc/node_modules/globals": { 163 619 "version": "14.0.0", 620 + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 621 + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 164 622 "dev": true, 165 623 "license": "MIT", 166 624 "engines": { ··· 171 629 } 172 630 }, 173 631 "node_modules/@eslint/js": { 174 - "version": "9.16.0", 632 + "version": "9.32.0", 633 + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", 634 + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", 175 635 "dev": true, 176 636 "license": "MIT", 177 637 "engines": { 178 638 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 639 + }, 640 + "funding": { 641 + "url": "https://eslint.org/donate" 179 642 } 180 643 }, 181 644 "node_modules/@eslint/object-schema": { 182 - "version": "2.1.4", 645 + "version": "2.1.6", 646 + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", 647 + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", 183 648 "dev": true, 184 649 "license": "Apache-2.0", 185 650 "engines": { ··· 187 652 } 188 653 }, 189 654 "node_modules/@eslint/plugin-kit": { 190 - "version": "0.2.3", 655 + "version": "0.3.4", 656 + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", 657 + "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", 191 658 "dev": true, 192 659 "license": "Apache-2.0", 193 660 "dependencies": { 661 + "@eslint/core": "^0.15.1", 194 662 "levn": "^0.4.1" 195 663 }, 196 664 "engines": { ··· 199 667 }, 200 668 "node_modules/@humanfs/core": { 201 669 "version": "0.19.1", 670 + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 671 + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 202 672 "dev": true, 203 673 "license": "Apache-2.0", 204 674 "engines": { ··· 207 677 }, 208 678 "node_modules/@humanfs/node": { 209 679 "version": "0.16.6", 680 + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 681 + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 210 682 "dev": true, 211 683 "license": "Apache-2.0", 212 684 "dependencies": { ··· 219 691 }, 220 692 "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 221 693 "version": "0.3.1", 694 + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 695 + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 222 696 "dev": true, 223 697 "license": "Apache-2.0", 224 698 "engines": { ··· 231 705 }, 232 706 "node_modules/@humanwhocodes/module-importer": { 233 707 "version": "1.0.1", 708 + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 709 + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 234 710 "dev": true, 235 711 "license": "Apache-2.0", 236 712 "engines": { ··· 242 718 } 243 719 }, 244 720 "node_modules/@humanwhocodes/retry": { 245 - "version": "0.4.1", 721 + "version": "0.4.3", 722 + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", 723 + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", 246 724 "dev": true, 247 725 "license": "Apache-2.0", 248 726 "engines": { ··· 255 733 }, 256 734 "node_modules/@isaacs/cliui": { 257 735 "version": "8.0.2", 736 + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 737 + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 258 738 "dev": true, 259 739 "license": "ISC", 260 740 "dependencies": { ··· 271 751 }, 272 752 "node_modules/@isaacs/fs-minipass": { 273 753 "version": "4.0.1", 754 + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", 755 + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", 274 756 "dev": true, 275 757 "license": "ISC", 276 758 "dependencies": { ··· 281 763 } 282 764 }, 283 765 "node_modules/@jridgewell/gen-mapping": { 284 - "version": "0.3.5", 766 + "version": "0.3.12", 767 + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", 768 + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", 285 769 "dev": true, 286 770 "license": "MIT", 287 771 "dependencies": { 288 - "@jridgewell/set-array": "^1.2.1", 289 - "@jridgewell/sourcemap-codec": "^1.4.10", 772 + "@jridgewell/sourcemap-codec": "^1.5.0", 290 773 "@jridgewell/trace-mapping": "^0.3.24" 291 - }, 292 - "engines": { 293 - "node": ">=6.0.0" 294 774 } 295 775 }, 296 776 "node_modules/@jridgewell/resolve-uri": { 297 777 "version": "3.1.2", 298 - "dev": true, 299 - "license": "MIT", 300 - "engines": { 301 - "node": ">=6.0.0" 302 - } 303 - }, 304 - "node_modules/@jridgewell/set-array": { 305 - "version": "1.2.1", 778 + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 779 + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 306 780 "dev": true, 307 781 "license": "MIT", 308 782 "engines": { ··· 310 784 } 311 785 }, 312 786 "node_modules/@jridgewell/sourcemap-codec": { 313 - "version": "1.5.0", 787 + "version": "1.5.4", 788 + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", 789 + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", 314 790 "dev": true, 315 791 "license": "MIT" 316 792 }, 317 793 "node_modules/@jridgewell/trace-mapping": { 318 - "version": "0.3.25", 794 + "version": "0.3.29", 795 + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", 796 + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", 319 797 "dev": true, 320 798 "license": "MIT", 321 799 "dependencies": { ··· 325 803 }, 326 804 "node_modules/@mapbox/node-pre-gyp": { 327 805 "version": "2.0.0", 806 + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz", 807 + "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==", 328 808 "dev": true, 329 809 "license": "BSD-3-Clause", 330 810 "dependencies": { ··· 345 825 }, 346 826 "node_modules/@nodelib/fs.scandir": { 347 827 "version": "2.1.5", 828 + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 829 + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 348 830 "dev": true, 349 831 "license": "MIT", 350 832 "dependencies": { ··· 357 839 }, 358 840 "node_modules/@nodelib/fs.stat": { 359 841 "version": "2.0.5", 842 + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 843 + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 360 844 "dev": true, 361 845 "license": "MIT", 362 846 "engines": { ··· 365 849 }, 366 850 "node_modules/@nodelib/fs.walk": { 367 851 "version": "1.2.8", 852 + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 853 + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 368 854 "dev": true, 369 855 "license": "MIT", 370 856 "dependencies": { ··· 377 863 }, 378 864 "node_modules/@pkgjs/parseargs": { 379 865 "version": "0.11.0", 866 + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 867 + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 380 868 "dev": true, 381 869 "license": "MIT", 382 870 "optional": true, ··· 385 873 } 386 874 }, 387 875 "node_modules/@polka/url": { 388 - "version": "1.0.0-next.28", 876 + "version": "1.0.0-next.29", 877 + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", 878 + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", 389 879 "dev": true, 390 880 "license": "MIT" 391 881 }, 392 882 "node_modules/@resvg/resvg-js": { 393 883 "version": "2.6.2", 884 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js/-/resvg-js-2.6.2.tgz", 885 + "integrity": "sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==", 394 886 "license": "MPL-2.0", 395 887 "engines": { 396 888 "node": ">= 10" ··· 410 902 "@resvg/resvg-js-win32-x64-msvc": "2.6.2" 411 903 } 412 904 }, 905 + "node_modules/@resvg/resvg-js-android-arm-eabi": { 906 + "version": "2.6.2", 907 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.6.2.tgz", 908 + "integrity": "sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==", 909 + "cpu": [ 910 + "arm" 911 + ], 912 + "license": "MPL-2.0", 913 + "optional": true, 914 + "os": [ 915 + "android" 916 + ], 917 + "engines": { 918 + "node": ">= 10" 919 + } 920 + }, 921 + "node_modules/@resvg/resvg-js-android-arm64": { 922 + "version": "2.6.2", 923 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm64/-/resvg-js-android-arm64-2.6.2.tgz", 924 + "integrity": "sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ==", 925 + "cpu": [ 926 + "arm64" 927 + ], 928 + "license": "MPL-2.0", 929 + "optional": true, 930 + "os": [ 931 + "android" 932 + ], 933 + "engines": { 934 + "node": ">= 10" 935 + } 936 + }, 413 937 "node_modules/@resvg/resvg-js-darwin-arm64": { 414 938 "version": "2.6.2", 939 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-arm64/-/resvg-js-darwin-arm64-2.6.2.tgz", 940 + "integrity": "sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A==", 415 941 "cpu": [ 416 942 "arm64" 417 943 ], ··· 424 950 "node": ">= 10" 425 951 } 426 952 }, 953 + "node_modules/@resvg/resvg-js-darwin-x64": { 954 + "version": "2.6.2", 955 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-x64/-/resvg-js-darwin-x64-2.6.2.tgz", 956 + "integrity": "sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw==", 957 + "cpu": [ 958 + "x64" 959 + ], 960 + "license": "MPL-2.0", 961 + "optional": true, 962 + "os": [ 963 + "darwin" 964 + ], 965 + "engines": { 966 + "node": ">= 10" 967 + } 968 + }, 969 + "node_modules/@resvg/resvg-js-linux-arm-gnueabihf": { 970 + "version": "2.6.2", 971 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm-gnueabihf/-/resvg-js-linux-arm-gnueabihf-2.6.2.tgz", 972 + "integrity": "sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw==", 973 + "cpu": [ 974 + "arm" 975 + ], 976 + "license": "MPL-2.0", 977 + "optional": true, 978 + "os": [ 979 + "linux" 980 + ], 981 + "engines": { 982 + "node": ">= 10" 983 + } 984 + }, 985 + "node_modules/@resvg/resvg-js-linux-arm64-gnu": { 986 + "version": "2.6.2", 987 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-gnu/-/resvg-js-linux-arm64-gnu-2.6.2.tgz", 988 + "integrity": "sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg==", 989 + "cpu": [ 990 + "arm64" 991 + ], 992 + "license": "MPL-2.0", 993 + "optional": true, 994 + "os": [ 995 + "linux" 996 + ], 997 + "engines": { 998 + "node": ">= 10" 999 + } 1000 + }, 1001 + "node_modules/@resvg/resvg-js-linux-arm64-musl": { 1002 + "version": "2.6.2", 1003 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-musl/-/resvg-js-linux-arm64-musl-2.6.2.tgz", 1004 + "integrity": "sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg==", 1005 + "cpu": [ 1006 + "arm64" 1007 + ], 1008 + "license": "MPL-2.0", 1009 + "optional": true, 1010 + "os": [ 1011 + "linux" 1012 + ], 1013 + "engines": { 1014 + "node": ">= 10" 1015 + } 1016 + }, 1017 + "node_modules/@resvg/resvg-js-linux-x64-gnu": { 1018 + "version": "2.6.2", 1019 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-gnu/-/resvg-js-linux-x64-gnu-2.6.2.tgz", 1020 + "integrity": "sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw==", 1021 + "cpu": [ 1022 + "x64" 1023 + ], 1024 + "license": "MPL-2.0", 1025 + "optional": true, 1026 + "os": [ 1027 + "linux" 1028 + ], 1029 + "engines": { 1030 + "node": ">= 10" 1031 + } 1032 + }, 1033 + "node_modules/@resvg/resvg-js-linux-x64-musl": { 1034 + "version": "2.6.2", 1035 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-musl/-/resvg-js-linux-x64-musl-2.6.2.tgz", 1036 + "integrity": "sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ==", 1037 + "cpu": [ 1038 + "x64" 1039 + ], 1040 + "license": "MPL-2.0", 1041 + "optional": true, 1042 + "os": [ 1043 + "linux" 1044 + ], 1045 + "engines": { 1046 + "node": ">= 10" 1047 + } 1048 + }, 1049 + "node_modules/@resvg/resvg-js-win32-arm64-msvc": { 1050 + "version": "2.6.2", 1051 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-arm64-msvc/-/resvg-js-win32-arm64-msvc-2.6.2.tgz", 1052 + "integrity": "sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ==", 1053 + "cpu": [ 1054 + "arm64" 1055 + ], 1056 + "license": "MPL-2.0", 1057 + "optional": true, 1058 + "os": [ 1059 + "win32" 1060 + ], 1061 + "engines": { 1062 + "node": ">= 10" 1063 + } 1064 + }, 1065 + "node_modules/@resvg/resvg-js-win32-ia32-msvc": { 1066 + "version": "2.6.2", 1067 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-ia32-msvc/-/resvg-js-win32-ia32-msvc-2.6.2.tgz", 1068 + "integrity": "sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w==", 1069 + "cpu": [ 1070 + "ia32" 1071 + ], 1072 + "license": "MPL-2.0", 1073 + "optional": true, 1074 + "os": [ 1075 + "win32" 1076 + ], 1077 + "engines": { 1078 + "node": ">= 10" 1079 + } 1080 + }, 1081 + "node_modules/@resvg/resvg-js-win32-x64-msvc": { 1082 + "version": "2.6.2", 1083 + "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-x64-msvc/-/resvg-js-win32-x64-msvc-2.6.2.tgz", 1084 + "integrity": "sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ==", 1085 + "cpu": [ 1086 + "x64" 1087 + ], 1088 + "license": "MPL-2.0", 1089 + "optional": true, 1090 + "os": [ 1091 + "win32" 1092 + ], 1093 + "engines": { 1094 + "node": ">= 10" 1095 + } 1096 + }, 427 1097 "node_modules/@rollup/pluginutils": { 428 - "version": "5.1.3", 1098 + "version": "5.2.0", 1099 + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", 1100 + "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", 429 1101 "dev": true, 430 1102 "license": "MIT", 431 1103 "dependencies": { ··· 445 1117 } 446 1118 } 447 1119 }, 1120 + "node_modules/@rollup/rollup-android-arm-eabi": { 1121 + "version": "4.46.1", 1122 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.1.tgz", 1123 + "integrity": "sha512-oENme6QxtLCqjChRUUo3S6X8hjCXnWmJWnedD7VbGML5GUtaOtAyx+fEEXnBXVf0CBZApMQU0Idwi0FmyxzQhw==", 1124 + "cpu": [ 1125 + "arm" 1126 + ], 1127 + "dev": true, 1128 + "license": "MIT", 1129 + "optional": true, 1130 + "os": [ 1131 + "android" 1132 + ] 1133 + }, 1134 + "node_modules/@rollup/rollup-android-arm64": { 1135 + "version": "4.46.1", 1136 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.1.tgz", 1137 + "integrity": "sha512-OikvNT3qYTl9+4qQ9Bpn6+XHM+ogtFadRLuT2EXiFQMiNkXFLQfNVppi5o28wvYdHL2s3fM0D/MZJ8UkNFZWsw==", 1138 + "cpu": [ 1139 + "arm64" 1140 + ], 1141 + "dev": true, 1142 + "license": "MIT", 1143 + "optional": true, 1144 + "os": [ 1145 + "android" 1146 + ] 1147 + }, 448 1148 "node_modules/@rollup/rollup-darwin-arm64": { 449 - "version": "4.28.0", 1149 + "version": "4.46.1", 1150 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.1.tgz", 1151 + "integrity": "sha512-EFYNNGij2WllnzljQDQnlFTXzSJw87cpAs4TVBAWLdkvic5Uh5tISrIL6NRcxoh/b2EFBG/TK8hgRrGx94zD4A==", 450 1152 "cpu": [ 451 1153 "arm64" 452 1154 ], ··· 457 1159 "darwin" 458 1160 ] 459 1161 }, 1162 + "node_modules/@rollup/rollup-darwin-x64": { 1163 + "version": "4.46.1", 1164 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.1.tgz", 1165 + "integrity": "sha512-ZaNH06O1KeTug9WI2+GRBE5Ujt9kZw4a1+OIwnBHal92I8PxSsl5KpsrPvthRynkhMck4XPdvY0z26Cym/b7oA==", 1166 + "cpu": [ 1167 + "x64" 1168 + ], 1169 + "dev": true, 1170 + "license": "MIT", 1171 + "optional": true, 1172 + "os": [ 1173 + "darwin" 1174 + ] 1175 + }, 1176 + "node_modules/@rollup/rollup-freebsd-arm64": { 1177 + "version": "4.46.1", 1178 + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.1.tgz", 1179 + "integrity": "sha512-n4SLVebZP8uUlJ2r04+g2U/xFeiQlw09Me5UFqny8HGbARl503LNH5CqFTb5U5jNxTouhRjai6qPT0CR5c/Iig==", 1180 + "cpu": [ 1181 + "arm64" 1182 + ], 1183 + "dev": true, 1184 + "license": "MIT", 1185 + "optional": true, 1186 + "os": [ 1187 + "freebsd" 1188 + ] 1189 + }, 1190 + "node_modules/@rollup/rollup-freebsd-x64": { 1191 + "version": "4.46.1", 1192 + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.1.tgz", 1193 + "integrity": "sha512-8vu9c02F16heTqpvo3yeiu7Vi1REDEC/yES/dIfq3tSXe6mLndiwvYr3AAvd1tMNUqE9yeGYa5w7PRbI5QUV+w==", 1194 + "cpu": [ 1195 + "x64" 1196 + ], 1197 + "dev": true, 1198 + "license": "MIT", 1199 + "optional": true, 1200 + "os": [ 1201 + "freebsd" 1202 + ] 1203 + }, 1204 + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 1205 + "version": "4.46.1", 1206 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.1.tgz", 1207 + "integrity": "sha512-K4ncpWl7sQuyp6rWiGUvb6Q18ba8mzM0rjWJ5JgYKlIXAau1db7hZnR0ldJvqKWWJDxqzSLwGUhA4jp+KqgDtQ==", 1208 + "cpu": [ 1209 + "arm" 1210 + ], 1211 + "dev": true, 1212 + "license": "MIT", 1213 + "optional": true, 1214 + "os": [ 1215 + "linux" 1216 + ] 1217 + }, 1218 + "node_modules/@rollup/rollup-linux-arm-musleabihf": { 1219 + "version": "4.46.1", 1220 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.1.tgz", 1221 + "integrity": "sha512-YykPnXsjUjmXE6j6k2QBBGAn1YsJUix7pYaPLK3RVE0bQL2jfdbfykPxfF8AgBlqtYbfEnYHmLXNa6QETjdOjQ==", 1222 + "cpu": [ 1223 + "arm" 1224 + ], 1225 + "dev": true, 1226 + "license": "MIT", 1227 + "optional": true, 1228 + "os": [ 1229 + "linux" 1230 + ] 1231 + }, 1232 + "node_modules/@rollup/rollup-linux-arm64-gnu": { 1233 + "version": "4.46.1", 1234 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.1.tgz", 1235 + "integrity": "sha512-kKvqBGbZ8i9pCGW3a1FH3HNIVg49dXXTsChGFsHGXQaVJPLA4f/O+XmTxfklhccxdF5FefUn2hvkoGJH0ScWOA==", 1236 + "cpu": [ 1237 + "arm64" 1238 + ], 1239 + "dev": true, 1240 + "license": "MIT", 1241 + "optional": true, 1242 + "os": [ 1243 + "linux" 1244 + ] 1245 + }, 1246 + "node_modules/@rollup/rollup-linux-arm64-musl": { 1247 + "version": "4.46.1", 1248 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.1.tgz", 1249 + "integrity": "sha512-zzX5nTw1N1plmqC9RGC9vZHFuiM7ZP7oSWQGqpbmfjK7p947D518cVK1/MQudsBdcD84t6k70WNczJOct6+hdg==", 1250 + "cpu": [ 1251 + "arm64" 1252 + ], 1253 + "dev": true, 1254 + "license": "MIT", 1255 + "optional": true, 1256 + "os": [ 1257 + "linux" 1258 + ] 1259 + }, 1260 + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 1261 + "version": "4.46.1", 1262 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.1.tgz", 1263 + "integrity": "sha512-O8CwgSBo6ewPpktFfSDgB6SJN9XDcPSvuwxfejiddbIC/hn9Tg6Ai0f0eYDf3XvB/+PIWzOQL+7+TZoB8p9Yuw==", 1264 + "cpu": [ 1265 + "loong64" 1266 + ], 1267 + "dev": true, 1268 + "license": "MIT", 1269 + "optional": true, 1270 + "os": [ 1271 + "linux" 1272 + ] 1273 + }, 1274 + "node_modules/@rollup/rollup-linux-ppc64-gnu": { 1275 + "version": "4.46.1", 1276 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.1.tgz", 1277 + "integrity": "sha512-JnCfFVEKeq6G3h3z8e60kAp8Rd7QVnWCtPm7cxx+5OtP80g/3nmPtfdCXbVl063e3KsRnGSKDHUQMydmzc/wBA==", 1278 + "cpu": [ 1279 + "ppc64" 1280 + ], 1281 + "dev": true, 1282 + "license": "MIT", 1283 + "optional": true, 1284 + "os": [ 1285 + "linux" 1286 + ] 1287 + }, 1288 + "node_modules/@rollup/rollup-linux-riscv64-gnu": { 1289 + "version": "4.46.1", 1290 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.1.tgz", 1291 + "integrity": "sha512-dVxuDqS237eQXkbYzQQfdf/njgeNw6LZuVyEdUaWwRpKHhsLI+y4H/NJV8xJGU19vnOJCVwaBFgr936FHOnJsQ==", 1292 + "cpu": [ 1293 + "riscv64" 1294 + ], 1295 + "dev": true, 1296 + "license": "MIT", 1297 + "optional": true, 1298 + "os": [ 1299 + "linux" 1300 + ] 1301 + }, 1302 + "node_modules/@rollup/rollup-linux-riscv64-musl": { 1303 + "version": "4.46.1", 1304 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.1.tgz", 1305 + "integrity": "sha512-CvvgNl2hrZrTR9jXK1ye0Go0HQRT6ohQdDfWR47/KFKiLd5oN5T14jRdUVGF4tnsN8y9oSfMOqH6RuHh+ck8+w==", 1306 + "cpu": [ 1307 + "riscv64" 1308 + ], 1309 + "dev": true, 1310 + "license": "MIT", 1311 + "optional": true, 1312 + "os": [ 1313 + "linux" 1314 + ] 1315 + }, 1316 + "node_modules/@rollup/rollup-linux-s390x-gnu": { 1317 + "version": "4.46.1", 1318 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.1.tgz", 1319 + "integrity": "sha512-x7ANt2VOg2565oGHJ6rIuuAon+A8sfe1IeUx25IKqi49OjSr/K3awoNqr9gCwGEJo9OuXlOn+H2p1VJKx1psxA==", 1320 + "cpu": [ 1321 + "s390x" 1322 + ], 1323 + "dev": true, 1324 + "license": "MIT", 1325 + "optional": true, 1326 + "os": [ 1327 + "linux" 1328 + ] 1329 + }, 1330 + "node_modules/@rollup/rollup-linux-x64-gnu": { 1331 + "version": "4.46.1", 1332 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.1.tgz", 1333 + "integrity": "sha512-9OADZYryz/7E8/qt0vnaHQgmia2Y0wrjSSn1V/uL+zw/i7NUhxbX4cHXdEQ7dnJgzYDS81d8+tf6nbIdRFZQoQ==", 1334 + "cpu": [ 1335 + "x64" 1336 + ], 1337 + "dev": true, 1338 + "license": "MIT", 1339 + "optional": true, 1340 + "os": [ 1341 + "linux" 1342 + ] 1343 + }, 1344 + "node_modules/@rollup/rollup-linux-x64-musl": { 1345 + "version": "4.46.1", 1346 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.1.tgz", 1347 + "integrity": "sha512-NuvSCbXEKY+NGWHyivzbjSVJi68Xfq1VnIvGmsuXs6TCtveeoDRKutI5vf2ntmNnVq64Q4zInet0UDQ+yMB6tA==", 1348 + "cpu": [ 1349 + "x64" 1350 + ], 1351 + "dev": true, 1352 + "license": "MIT", 1353 + "optional": true, 1354 + "os": [ 1355 + "linux" 1356 + ] 1357 + }, 1358 + "node_modules/@rollup/rollup-win32-arm64-msvc": { 1359 + "version": "4.46.1", 1360 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.1.tgz", 1361 + "integrity": "sha512-mWz+6FSRb82xuUMMV1X3NGiaPFqbLN9aIueHleTZCc46cJvwTlvIh7reQLk4p97dv0nddyewBhwzryBHH7wtPw==", 1362 + "cpu": [ 1363 + "arm64" 1364 + ], 1365 + "dev": true, 1366 + "license": "MIT", 1367 + "optional": true, 1368 + "os": [ 1369 + "win32" 1370 + ] 1371 + }, 1372 + "node_modules/@rollup/rollup-win32-ia32-msvc": { 1373 + "version": "4.46.1", 1374 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.1.tgz", 1375 + "integrity": "sha512-7Thzy9TMXDw9AU4f4vsLNBxh7/VOKuXi73VH3d/kHGr0tZ3x/ewgL9uC7ojUKmH1/zvmZe2tLapYcZllk3SO8Q==", 1376 + "cpu": [ 1377 + "ia32" 1378 + ], 1379 + "dev": true, 1380 + "license": "MIT", 1381 + "optional": true, 1382 + "os": [ 1383 + "win32" 1384 + ] 1385 + }, 1386 + "node_modules/@rollup/rollup-win32-x64-msvc": { 1387 + "version": "4.46.1", 1388 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.1.tgz", 1389 + "integrity": "sha512-7GVB4luhFmGUNXXJhH2jJwZCFB3pIOixv2E3s17GQHBFUOQaISlt7aGcQgqvCaDSxTZJUzlK/QJ1FN8S94MrzQ==", 1390 + "cpu": [ 1391 + "x64" 1392 + ], 1393 + "dev": true, 1394 + "license": "MIT", 1395 + "optional": true, 1396 + "os": [ 1397 + "win32" 1398 + ] 1399 + }, 460 1400 "node_modules/@shuding/opentype.js": { 461 1401 "version": "1.4.0-beta.0", 1402 + "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz", 1403 + "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==", 462 1404 "license": "MIT", 463 1405 "dependencies": { 464 1406 "fflate": "^0.7.3", ··· 473 1415 }, 474 1416 "node_modules/@sveltejs/acorn-typescript": { 475 1417 "version": "1.0.5", 1418 + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz", 1419 + "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", 476 1420 "dev": true, 477 1421 "license": "MIT", 478 1422 "peerDependencies": { ··· 480 1424 } 481 1425 }, 482 1426 "node_modules/@sveltejs/adapter-vercel": { 483 - "version": "5.7.0", 1427 + "version": "5.8.1", 1428 + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-vercel/-/adapter-vercel-5.8.1.tgz", 1429 + "integrity": "sha512-5G4+KEWHXU2FC2sRWtauJPgDTC1vRuhnK6wi6+cKX96G7nBXM/mDG1cO7joJS1PbDEUQ9kXIgZ2XgsimOLn+qQ==", 484 1430 "dev": true, 485 1431 "license": "MIT", 486 1432 "dependencies": { 487 - "@vercel/nft": "^0.29.2", 488 - "esbuild": "^0.24.0" 1433 + "@vercel/nft": "^0.30.0", 1434 + "esbuild": "^0.25.4" 489 1435 }, 490 1436 "peerDependencies": { 491 1437 "@sveltejs/kit": "^2.4.0" 492 1438 } 493 1439 }, 494 - "node_modules/@sveltejs/adapter-vercel/node_modules/@esbuild/darwin-arm64": { 495 - "version": "0.24.2", 496 - "cpu": [ 497 - "arm64" 498 - ], 499 - "dev": true, 500 - "license": "MIT", 501 - "optional": true, 502 - "os": [ 503 - "darwin" 504 - ], 505 - "engines": { 506 - "node": ">=18" 507 - } 508 - }, 509 - "node_modules/@sveltejs/adapter-vercel/node_modules/esbuild": { 510 - "version": "0.24.2", 511 - "dev": true, 512 - "hasInstallScript": true, 513 - "license": "MIT", 514 - "bin": { 515 - "esbuild": "bin/esbuild" 516 - }, 517 - "engines": { 518 - "node": ">=18" 519 - }, 520 - "optionalDependencies": { 521 - "@esbuild/aix-ppc64": "0.24.2", 522 - "@esbuild/android-arm": "0.24.2", 523 - "@esbuild/android-arm64": "0.24.2", 524 - "@esbuild/android-x64": "0.24.2", 525 - "@esbuild/darwin-arm64": "0.24.2", 526 - "@esbuild/darwin-x64": "0.24.2", 527 - "@esbuild/freebsd-arm64": "0.24.2", 528 - "@esbuild/freebsd-x64": "0.24.2", 529 - "@esbuild/linux-arm": "0.24.2", 530 - "@esbuild/linux-arm64": "0.24.2", 531 - "@esbuild/linux-ia32": "0.24.2", 532 - "@esbuild/linux-loong64": "0.24.2", 533 - "@esbuild/linux-mips64el": "0.24.2", 534 - "@esbuild/linux-ppc64": "0.24.2", 535 - "@esbuild/linux-riscv64": "0.24.2", 536 - "@esbuild/linux-s390x": "0.24.2", 537 - "@esbuild/linux-x64": "0.24.2", 538 - "@esbuild/netbsd-arm64": "0.24.2", 539 - "@esbuild/netbsd-x64": "0.24.2", 540 - "@esbuild/openbsd-arm64": "0.24.2", 541 - "@esbuild/openbsd-x64": "0.24.2", 542 - "@esbuild/sunos-x64": "0.24.2", 543 - "@esbuild/win32-arm64": "0.24.2", 544 - "@esbuild/win32-ia32": "0.24.2", 545 - "@esbuild/win32-x64": "0.24.2" 546 - } 547 - }, 548 1440 "node_modules/@sveltejs/kit": { 549 - "version": "2.24.0", 1441 + "version": "2.26.1", 1442 + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.26.1.tgz", 1443 + "integrity": "sha512-FwDhHAoXYUGnYndrrEzEYcKdYWpSoRKq4kli29oMe83hLri4/DOGQk3xUgwjDo0LKpSmj5M/Sj29/Ug3wO0Cbg==", 550 1444 "dev": true, 551 1445 "license": "MIT", 552 1446 "dependencies": { ··· 577 1471 }, 578 1472 "node_modules/@sveltejs/vite-plugin-svelte": { 579 1473 "version": "4.0.4", 1474 + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-4.0.4.tgz", 1475 + "integrity": "sha512-0ba1RQ/PHen5FGpdSrW7Y3fAMQjrXantECALeOiOdBdzR5+5vPP6HVZRLmZaQL+W8m++o+haIAKq5qT+MiZ7VA==", 580 1476 "dev": true, 581 1477 "license": "MIT", 582 1478 "dependencies": { ··· 597 1493 }, 598 1494 "node_modules/@sveltejs/vite-plugin-svelte-inspector": { 599 1495 "version": "3.0.1", 1496 + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-3.0.1.tgz", 1497 + "integrity": "sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==", 600 1498 "dev": true, 601 1499 "license": "MIT", 602 1500 "dependencies": { ··· 612 1510 } 613 1511 }, 614 1512 "node_modules/@tailwindcss/forms": { 615 - "version": "0.5.9", 1513 + "version": "0.5.10", 1514 + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz", 1515 + "integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==", 616 1516 "dev": true, 617 1517 "license": "MIT", 618 1518 "dependencies": { 619 1519 "mini-svg-data-uri": "^1.2.3" 620 1520 }, 621 1521 "peerDependencies": { 622 - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" 1522 + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" 623 1523 } 624 1524 }, 625 1525 "node_modules/@tailwindcss/nesting": { 626 1526 "version": "0.0.0-insiders.565cd3e", 1527 + "resolved": "https://registry.npmjs.org/@tailwindcss/nesting/-/nesting-0.0.0-insiders.565cd3e.tgz", 1528 + "integrity": "sha512-WhHoFBx19TnH/c+xLwT/sxei6+4RpdfiyG3MYXfmLaMsADmVqBkF7B6lDalgZD9YdM459MF7DtxVbWkOrV7IaQ==", 627 1529 "license": "MIT", 628 1530 "dependencies": { 629 1531 "postcss-nested": "^5.0.5" ··· 632 1534 "postcss": "^8.2.15" 633 1535 } 634 1536 }, 635 - "node_modules/@tailwindcss/nesting/node_modules/postcss-nested": { 636 - "version": "5.0.6", 637 - "license": "MIT", 638 - "dependencies": { 639 - "postcss-selector-parser": "^6.0.6" 640 - }, 641 - "engines": { 642 - "node": ">=12.0" 643 - }, 644 - "funding": { 645 - "type": "opencollective", 646 - "url": "https://opencollective.com/postcss/" 647 - }, 648 - "peerDependencies": { 649 - "postcss": "^8.2.14" 650 - } 651 - }, 652 1537 "node_modules/@tailwindcss/typography": { 653 - "version": "0.5.15", 1538 + "version": "0.5.16", 1539 + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", 1540 + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", 654 1541 "dev": true, 655 1542 "license": "MIT", 656 1543 "dependencies": { ··· 660 1547 "postcss-selector-parser": "6.0.10" 661 1548 }, 662 1549 "peerDependencies": { 663 - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" 664 - } 665 - }, 666 - "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { 667 - "version": "6.0.10", 668 - "dev": true, 669 - "license": "MIT", 670 - "dependencies": { 671 - "cssesc": "^3.0.0", 672 - "util-deprecate": "^1.0.2" 673 - }, 674 - "engines": { 675 - "node": ">=4" 1550 + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" 676 1551 } 677 1552 }, 678 1553 "node_modules/@types/cookie": { 679 1554 "version": "0.6.0", 1555 + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", 1556 + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", 680 1557 "dev": true, 681 1558 "license": "MIT" 682 1559 }, 683 1560 "node_modules/@types/debug": { 684 1561 "version": "4.1.12", 1562 + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", 1563 + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", 685 1564 "license": "MIT", 686 1565 "dependencies": { 687 1566 "@types/ms": "*" 688 1567 } 689 1568 }, 690 1569 "node_modules/@types/estree": { 691 - "version": "1.0.6", 1570 + "version": "1.0.8", 1571 + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", 1572 + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", 692 1573 "dev": true, 693 1574 "license": "MIT" 694 1575 }, 695 1576 "node_modules/@types/hast": { 696 1577 "version": "3.0.4", 1578 + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", 1579 + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", 697 1580 "license": "MIT", 698 1581 "dependencies": { 699 1582 "@types/unist": "*" ··· 701 1584 }, 702 1585 "node_modules/@types/json-schema": { 703 1586 "version": "7.0.15", 1587 + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 1588 + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 704 1589 "dev": true, 705 1590 "license": "MIT" 706 1591 }, 707 1592 "node_modules/@types/mdast": { 708 1593 "version": "4.0.4", 1594 + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", 1595 + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", 709 1596 "license": "MIT", 710 1597 "dependencies": { 711 1598 "@types/unist": "*" 712 1599 } 713 1600 }, 714 1601 "node_modules/@types/ms": { 715 - "version": "0.7.34", 1602 + "version": "2.1.0", 1603 + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", 1604 + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", 716 1605 "license": "MIT" 717 1606 }, 718 1607 "node_modules/@types/node": { 719 - "version": "22.10.1", 1608 + "version": "22.16.5", 1609 + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.5.tgz", 1610 + "integrity": "sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==", 720 1611 "dev": true, 721 1612 "license": "MIT", 722 1613 "dependencies": { 723 - "undici-types": "~6.20.0" 1614 + "undici-types": "~6.21.0" 724 1615 } 725 1616 }, 726 1617 "node_modules/@types/sanitize-html": { 727 - "version": "2.13.0", 1618 + "version": "2.16.0", 1619 + "resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.16.0.tgz", 1620 + "integrity": "sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==", 728 1621 "dev": true, 729 1622 "license": "MIT", 730 1623 "dependencies": { ··· 733 1626 }, 734 1627 "node_modules/@types/unist": { 735 1628 "version": "3.0.3", 1629 + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", 1630 + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", 736 1631 "license": "MIT" 737 1632 }, 738 1633 "node_modules/@typescript-eslint/eslint-plugin": { 739 - "version": "8.16.0", 1634 + "version": "8.38.0", 1635 + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", 1636 + "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", 740 1637 "dev": true, 741 1638 "license": "MIT", 742 1639 "dependencies": { 743 1640 "@eslint-community/regexpp": "^4.10.0", 744 - "@typescript-eslint/scope-manager": "8.16.0", 745 - "@typescript-eslint/type-utils": "8.16.0", 746 - "@typescript-eslint/utils": "8.16.0", 747 - "@typescript-eslint/visitor-keys": "8.16.0", 1641 + "@typescript-eslint/scope-manager": "8.38.0", 1642 + "@typescript-eslint/type-utils": "8.38.0", 1643 + "@typescript-eslint/utils": "8.38.0", 1644 + "@typescript-eslint/visitor-keys": "8.38.0", 748 1645 "graphemer": "^1.4.0", 749 - "ignore": "^5.3.1", 1646 + "ignore": "^7.0.0", 750 1647 "natural-compare": "^1.4.0", 751 - "ts-api-utils": "^1.3.0" 1648 + "ts-api-utils": "^2.1.0" 752 1649 }, 753 1650 "engines": { 754 1651 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 758 1655 "url": "https://opencollective.com/typescript-eslint" 759 1656 }, 760 1657 "peerDependencies": { 761 - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", 762 - "eslint": "^8.57.0 || ^9.0.0" 763 - }, 764 - "peerDependenciesMeta": { 765 - "typescript": { 766 - "optional": true 767 - } 1658 + "@typescript-eslint/parser": "^8.38.0", 1659 + "eslint": "^8.57.0 || ^9.0.0", 1660 + "typescript": ">=4.8.4 <5.9.0" 1661 + } 1662 + }, 1663 + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { 1664 + "version": "7.0.5", 1665 + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", 1666 + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", 1667 + "dev": true, 1668 + "license": "MIT", 1669 + "engines": { 1670 + "node": ">= 4" 768 1671 } 769 1672 }, 770 1673 "node_modules/@typescript-eslint/parser": { 771 - "version": "8.16.0", 1674 + "version": "8.38.0", 1675 + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", 1676 + "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", 772 1677 "dev": true, 773 - "license": "BSD-2-Clause", 1678 + "license": "MIT", 774 1679 "dependencies": { 775 - "@typescript-eslint/scope-manager": "8.16.0", 776 - "@typescript-eslint/types": "8.16.0", 777 - "@typescript-eslint/typescript-estree": "8.16.0", 778 - "@typescript-eslint/visitor-keys": "8.16.0", 1680 + "@typescript-eslint/scope-manager": "8.38.0", 1681 + "@typescript-eslint/types": "8.38.0", 1682 + "@typescript-eslint/typescript-estree": "8.38.0", 1683 + "@typescript-eslint/visitor-keys": "8.38.0", 779 1684 "debug": "^4.3.4" 780 1685 }, 781 1686 "engines": { ··· 786 1691 "url": "https://opencollective.com/typescript-eslint" 787 1692 }, 788 1693 "peerDependencies": { 789 - "eslint": "^8.57.0 || ^9.0.0" 1694 + "eslint": "^8.57.0 || ^9.0.0", 1695 + "typescript": ">=4.8.4 <5.9.0" 1696 + } 1697 + }, 1698 + "node_modules/@typescript-eslint/project-service": { 1699 + "version": "8.38.0", 1700 + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", 1701 + "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", 1702 + "dev": true, 1703 + "license": "MIT", 1704 + "dependencies": { 1705 + "@typescript-eslint/tsconfig-utils": "^8.38.0", 1706 + "@typescript-eslint/types": "^8.38.0", 1707 + "debug": "^4.3.4" 790 1708 }, 791 - "peerDependenciesMeta": { 792 - "typescript": { 793 - "optional": true 794 - } 1709 + "engines": { 1710 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1711 + }, 1712 + "funding": { 1713 + "type": "opencollective", 1714 + "url": "https://opencollective.com/typescript-eslint" 1715 + }, 1716 + "peerDependencies": { 1717 + "typescript": ">=4.8.4 <5.9.0" 795 1718 } 796 1719 }, 797 1720 "node_modules/@typescript-eslint/scope-manager": { 798 - "version": "8.16.0", 1721 + "version": "8.38.0", 1722 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", 1723 + "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", 799 1724 "dev": true, 800 1725 "license": "MIT", 801 1726 "dependencies": { 802 - "@typescript-eslint/types": "8.16.0", 803 - "@typescript-eslint/visitor-keys": "8.16.0" 1727 + "@typescript-eslint/types": "8.38.0", 1728 + "@typescript-eslint/visitor-keys": "8.38.0" 804 1729 }, 805 1730 "engines": { 806 1731 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 810 1735 "url": "https://opencollective.com/typescript-eslint" 811 1736 } 812 1737 }, 1738 + "node_modules/@typescript-eslint/tsconfig-utils": { 1739 + "version": "8.38.0", 1740 + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", 1741 + "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", 1742 + "dev": true, 1743 + "license": "MIT", 1744 + "engines": { 1745 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1746 + }, 1747 + "funding": { 1748 + "type": "opencollective", 1749 + "url": "https://opencollective.com/typescript-eslint" 1750 + }, 1751 + "peerDependencies": { 1752 + "typescript": ">=4.8.4 <5.9.0" 1753 + } 1754 + }, 813 1755 "node_modules/@typescript-eslint/type-utils": { 814 - "version": "8.16.0", 1756 + "version": "8.38.0", 1757 + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", 1758 + "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", 815 1759 "dev": true, 816 1760 "license": "MIT", 817 1761 "dependencies": { 818 - "@typescript-eslint/typescript-estree": "8.16.0", 819 - "@typescript-eslint/utils": "8.16.0", 1762 + "@typescript-eslint/types": "8.38.0", 1763 + "@typescript-eslint/typescript-estree": "8.38.0", 1764 + "@typescript-eslint/utils": "8.38.0", 820 1765 "debug": "^4.3.4", 821 - "ts-api-utils": "^1.3.0" 1766 + "ts-api-utils": "^2.1.0" 822 1767 }, 823 1768 "engines": { 824 1769 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 828 1773 "url": "https://opencollective.com/typescript-eslint" 829 1774 }, 830 1775 "peerDependencies": { 831 - "eslint": "^8.57.0 || ^9.0.0" 832 - }, 833 - "peerDependenciesMeta": { 834 - "typescript": { 835 - "optional": true 836 - } 1776 + "eslint": "^8.57.0 || ^9.0.0", 1777 + "typescript": ">=4.8.4 <5.9.0" 837 1778 } 838 1779 }, 839 1780 "node_modules/@typescript-eslint/types": { 840 - "version": "8.16.0", 1781 + "version": "8.38.0", 1782 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", 1783 + "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", 841 1784 "dev": true, 842 1785 "license": "MIT", 843 1786 "engines": { ··· 849 1792 } 850 1793 }, 851 1794 "node_modules/@typescript-eslint/typescript-estree": { 852 - "version": "8.16.0", 1795 + "version": "8.38.0", 1796 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", 1797 + "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", 853 1798 "dev": true, 854 - "license": "BSD-2-Clause", 1799 + "license": "MIT", 855 1800 "dependencies": { 856 - "@typescript-eslint/types": "8.16.0", 857 - "@typescript-eslint/visitor-keys": "8.16.0", 1801 + "@typescript-eslint/project-service": "8.38.0", 1802 + "@typescript-eslint/tsconfig-utils": "8.38.0", 1803 + "@typescript-eslint/types": "8.38.0", 1804 + "@typescript-eslint/visitor-keys": "8.38.0", 858 1805 "debug": "^4.3.4", 859 1806 "fast-glob": "^3.3.2", 860 1807 "is-glob": "^4.0.3", 861 1808 "minimatch": "^9.0.4", 862 1809 "semver": "^7.6.0", 863 - "ts-api-utils": "^1.3.0" 1810 + "ts-api-utils": "^2.1.0" 864 1811 }, 865 1812 "engines": { 866 1813 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 869 1816 "type": "opencollective", 870 1817 "url": "https://opencollective.com/typescript-eslint" 871 1818 }, 872 - "peerDependenciesMeta": { 873 - "typescript": { 874 - "optional": true 875 - } 1819 + "peerDependencies": { 1820 + "typescript": ">=4.8.4 <5.9.0" 876 1821 } 877 1822 }, 878 1823 "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { 879 - "version": "2.0.1", 1824 + "version": "2.0.2", 1825 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", 1826 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", 880 1827 "dev": true, 881 1828 "license": "MIT", 882 1829 "dependencies": { ··· 885 1832 }, 886 1833 "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { 887 1834 "version": "9.0.5", 1835 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1836 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 888 1837 "dev": true, 889 1838 "license": "ISC", 890 1839 "dependencies": { ··· 898 1847 } 899 1848 }, 900 1849 "node_modules/@typescript-eslint/utils": { 901 - "version": "8.16.0", 1850 + "version": "8.38.0", 1851 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", 1852 + "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", 902 1853 "dev": true, 903 1854 "license": "MIT", 904 1855 "dependencies": { 905 - "@eslint-community/eslint-utils": "^4.4.0", 906 - "@typescript-eslint/scope-manager": "8.16.0", 907 - "@typescript-eslint/types": "8.16.0", 908 - "@typescript-eslint/typescript-estree": "8.16.0" 1856 + "@eslint-community/eslint-utils": "^4.7.0", 1857 + "@typescript-eslint/scope-manager": "8.38.0", 1858 + "@typescript-eslint/types": "8.38.0", 1859 + "@typescript-eslint/typescript-estree": "8.38.0" 909 1860 }, 910 1861 "engines": { 911 1862 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 915 1866 "url": "https://opencollective.com/typescript-eslint" 916 1867 }, 917 1868 "peerDependencies": { 918 - "eslint": "^8.57.0 || ^9.0.0" 919 - }, 920 - "peerDependenciesMeta": { 921 - "typescript": { 922 - "optional": true 923 - } 1869 + "eslint": "^8.57.0 || ^9.0.0", 1870 + "typescript": ">=4.8.4 <5.9.0" 924 1871 } 925 1872 }, 926 1873 "node_modules/@typescript-eslint/visitor-keys": { 927 - "version": "8.16.0", 1874 + "version": "8.38.0", 1875 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", 1876 + "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", 928 1877 "dev": true, 929 1878 "license": "MIT", 930 1879 "dependencies": { 931 - "@typescript-eslint/types": "8.16.0", 932 - "eslint-visitor-keys": "^4.2.0" 1880 + "@typescript-eslint/types": "8.38.0", 1881 + "eslint-visitor-keys": "^4.2.1" 933 1882 }, 934 1883 "engines": { 935 1884 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 940 1889 } 941 1890 }, 942 1891 "node_modules/@ungap/structured-clone": { 943 - "version": "1.2.0", 1892 + "version": "1.3.0", 1893 + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", 1894 + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", 944 1895 "license": "ISC" 945 1896 }, 946 1897 "node_modules/@vercel/nft": { 947 - "version": "0.29.2", 1898 + "version": "0.30.0", 1899 + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.30.0.tgz", 1900 + "integrity": "sha512-xVye7Z0riD9czsMuEJYpFqm2FR33r3euYaFzuEPCoUtYuDwmus3rJfKtcFU7Df+pgj8p4zs78x5lOWYoLNr+7Q==", 948 1901 "dev": true, 949 1902 "license": "MIT", 950 1903 "dependencies": { ··· 966 1919 }, 967 1920 "engines": { 968 1921 "node": ">=18" 969 - } 970 - }, 971 - "node_modules/@vercel/nft/node_modules/resolve-from": { 972 - "version": "5.0.0", 973 - "dev": true, 974 - "license": "MIT", 975 - "engines": { 976 - "node": ">=8" 977 1922 } 978 1923 }, 979 1924 "node_modules/abbrev": { 980 - "version": "3.0.0", 1925 + "version": "3.0.1", 1926 + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", 1927 + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", 981 1928 "dev": true, 982 1929 "license": "ISC", 983 1930 "engines": { ··· 986 1933 }, 987 1934 "node_modules/acorn": { 988 1935 "version": "8.15.0", 1936 + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", 1937 + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", 989 1938 "dev": true, 990 1939 "license": "MIT", 991 1940 "bin": { ··· 997 1946 }, 998 1947 "node_modules/acorn-import-attributes": { 999 1948 "version": "1.9.5", 1949 + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", 1950 + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", 1000 1951 "dev": true, 1001 1952 "license": "MIT", 1002 1953 "peerDependencies": { ··· 1005 1956 }, 1006 1957 "node_modules/acorn-jsx": { 1007 1958 "version": "5.3.2", 1959 + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 1960 + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 1008 1961 "dev": true, 1009 1962 "license": "MIT", 1010 1963 "peerDependencies": { ··· 1012 1965 } 1013 1966 }, 1014 1967 "node_modules/agent-base": { 1015 - "version": "7.1.3", 1968 + "version": "7.1.4", 1969 + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", 1970 + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", 1016 1971 "dev": true, 1017 1972 "license": "MIT", 1018 1973 "engines": { ··· 1021 1976 }, 1022 1977 "node_modules/ajv": { 1023 1978 "version": "6.12.6", 1979 + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1980 + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1024 1981 "dev": true, 1025 1982 "license": "MIT", 1026 1983 "dependencies": { ··· 1036 1993 }, 1037 1994 "node_modules/ansi-regex": { 1038 1995 "version": "6.1.0", 1996 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", 1997 + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", 1039 1998 "dev": true, 1040 1999 "license": "MIT", 1041 2000 "engines": { ··· 1047 2006 }, 1048 2007 "node_modules/ansi-styles": { 1049 2008 "version": "4.3.0", 2009 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2010 + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1050 2011 "dev": true, 1051 2012 "license": "MIT", 1052 2013 "dependencies": { ··· 1061 2022 }, 1062 2023 "node_modules/any-promise": { 1063 2024 "version": "1.3.0", 2025 + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", 2026 + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", 1064 2027 "dev": true, 1065 2028 "license": "MIT" 1066 2029 }, 1067 2030 "node_modules/anymatch": { 1068 2031 "version": "3.1.3", 2032 + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 2033 + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 1069 2034 "dev": true, 1070 2035 "license": "ISC", 1071 2036 "dependencies": { ··· 1078 2043 }, 1079 2044 "node_modules/anymatch/node_modules/picomatch": { 1080 2045 "version": "2.3.1", 2046 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 2047 + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1081 2048 "dev": true, 1082 2049 "license": "MIT", 1083 2050 "engines": { ··· 1089 2056 }, 1090 2057 "node_modules/arg": { 1091 2058 "version": "5.0.2", 2059 + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", 2060 + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", 1092 2061 "dev": true, 1093 2062 "license": "MIT" 1094 2063 }, 1095 2064 "node_modules/argparse": { 1096 2065 "version": "2.0.1", 2066 + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 2067 + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1097 2068 "dev": true, 1098 2069 "license": "Python-2.0" 1099 2070 }, 1100 2071 "node_modules/aria-query": { 1101 2072 "version": "5.3.2", 2073 + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", 2074 + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", 1102 2075 "dev": true, 1103 2076 "license": "Apache-2.0", 1104 2077 "engines": { ··· 1107 2080 }, 1108 2081 "node_modules/async-sema": { 1109 2082 "version": "3.1.1", 2083 + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", 2084 + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", 1110 2085 "dev": true, 1111 2086 "license": "MIT" 1112 2087 }, 1113 2088 "node_modules/autoprefixer": { 1114 2089 "version": "10.4.21", 2090 + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", 2091 + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", 1115 2092 "dev": true, 1116 2093 "funding": [ 1117 2094 { ··· 1148 2125 }, 1149 2126 "node_modules/axobject-query": { 1150 2127 "version": "4.1.0", 2128 + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", 2129 + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", 1151 2130 "dev": true, 1152 2131 "license": "Apache-2.0", 1153 2132 "engines": { ··· 1156 2135 }, 1157 2136 "node_modules/bail": { 1158 2137 "version": "2.0.2", 2138 + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", 2139 + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", 1159 2140 "license": "MIT", 1160 2141 "funding": { 1161 2142 "type": "github", ··· 1164 2145 }, 1165 2146 "node_modules/balanced-match": { 1166 2147 "version": "1.0.2", 2148 + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 2149 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1167 2150 "dev": true, 1168 2151 "license": "MIT" 1169 2152 }, 1170 2153 "node_modules/base64-js": { 1171 2154 "version": "0.0.8", 2155 + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", 2156 + "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==", 1172 2157 "license": "MIT", 1173 2158 "engines": { 1174 2159 "node": ">= 0.4" ··· 1176 2161 }, 1177 2162 "node_modules/binary-extensions": { 1178 2163 "version": "2.3.0", 2164 + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", 2165 + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", 1179 2166 "dev": true, 1180 2167 "license": "MIT", 1181 2168 "engines": { ··· 1187 2174 }, 1188 2175 "node_modules/bindings": { 1189 2176 "version": "1.5.0", 2177 + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", 2178 + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", 1190 2179 "dev": true, 1191 2180 "license": "MIT", 1192 2181 "dependencies": { ··· 1194 2183 } 1195 2184 }, 1196 2185 "node_modules/brace-expansion": { 1197 - "version": "1.1.11", 2186 + "version": "1.1.12", 2187 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", 2188 + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", 1198 2189 "dev": true, 1199 2190 "license": "MIT", 1200 2191 "dependencies": { ··· 1204 2195 }, 1205 2196 "node_modules/braces": { 1206 2197 "version": "3.0.3", 2198 + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 2199 + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 1207 2200 "dev": true, 1208 2201 "license": "MIT", 1209 2202 "dependencies": { ··· 1215 2208 }, 1216 2209 "node_modules/browserslist": { 1217 2210 "version": "4.25.1", 2211 + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", 2212 + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", 1218 2213 "dev": true, 1219 2214 "funding": [ 1220 2215 { ··· 1246 2241 }, 1247 2242 "node_modules/callsites": { 1248 2243 "version": "3.1.0", 2244 + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 2245 + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 1249 2246 "dev": true, 1250 2247 "license": "MIT", 1251 2248 "engines": { ··· 1254 2251 }, 1255 2252 "node_modules/camelcase-css": { 1256 2253 "version": "2.0.1", 2254 + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", 2255 + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", 1257 2256 "dev": true, 1258 2257 "license": "MIT", 1259 2258 "engines": { ··· 1262 2261 }, 1263 2262 "node_modules/camelize": { 1264 2263 "version": "1.0.1", 2264 + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", 2265 + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", 1265 2266 "license": "MIT", 1266 2267 "funding": { 1267 2268 "url": "https://github.com/sponsors/ljharb" ··· 1269 2270 }, 1270 2271 "node_modules/caniuse-lite": { 1271 2272 "version": "1.0.30001727", 2273 + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", 2274 + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", 1272 2275 "dev": true, 1273 2276 "funding": [ 1274 2277 { ··· 1288 2291 }, 1289 2292 "node_modules/ccount": { 1290 2293 "version": "2.0.1", 2294 + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", 2295 + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", 1291 2296 "license": "MIT", 1292 2297 "funding": { 1293 2298 "type": "github", ··· 1296 2301 }, 1297 2302 "node_modules/chalk": { 1298 2303 "version": "4.1.2", 2304 + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 2305 + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1299 2306 "dev": true, 1300 2307 "license": "MIT", 1301 2308 "dependencies": { ··· 1311 2318 }, 1312 2319 "node_modules/character-entities": { 1313 2320 "version": "2.0.2", 2321 + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", 2322 + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", 1314 2323 "license": "MIT", 1315 2324 "funding": { 1316 2325 "type": "github", ··· 1319 2328 }, 1320 2329 "node_modules/character-entities-html4": { 1321 2330 "version": "2.1.0", 2331 + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", 2332 + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", 1322 2333 "license": "MIT", 1323 2334 "funding": { 1324 2335 "type": "github", ··· 1327 2338 }, 1328 2339 "node_modules/character-entities-legacy": { 1329 2340 "version": "3.0.0", 2341 + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", 2342 + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", 1330 2343 "license": "MIT", 1331 2344 "funding": { 1332 2345 "type": "github", ··· 1334 2347 } 1335 2348 }, 1336 2349 "node_modules/chokidar": { 1337 - "version": "4.0.1", 2350 + "version": "4.0.3", 2351 + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", 2352 + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", 1338 2353 "dev": true, 1339 2354 "license": "MIT", 1340 2355 "dependencies": { ··· 1349 2364 }, 1350 2365 "node_modules/chownr": { 1351 2366 "version": "3.0.0", 2367 + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", 2368 + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", 1352 2369 "dev": true, 1353 2370 "license": "BlueOak-1.0.0", 1354 2371 "engines": { ··· 1357 2374 }, 1358 2375 "node_modules/clsx": { 1359 2376 "version": "2.1.1", 2377 + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", 2378 + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", 1360 2379 "dev": true, 1361 2380 "license": "MIT", 1362 2381 "engines": { ··· 1365 2384 }, 1366 2385 "node_modules/color-convert": { 1367 2386 "version": "2.0.1", 2387 + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2388 + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1368 2389 "dev": true, 1369 2390 "license": "MIT", 1370 2391 "dependencies": { ··· 1376 2397 }, 1377 2398 "node_modules/color-name": { 1378 2399 "version": "1.1.4", 2400 + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2401 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1379 2402 "license": "MIT" 1380 2403 }, 1381 2404 "node_modules/comma-separated-tokens": { 1382 2405 "version": "2.0.3", 2406 + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", 2407 + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", 1383 2408 "license": "MIT", 1384 2409 "funding": { 1385 2410 "type": "github", ··· 1388 2413 }, 1389 2414 "node_modules/commander": { 1390 2415 "version": "4.1.1", 2416 + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", 2417 + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", 1391 2418 "dev": true, 1392 2419 "license": "MIT", 1393 2420 "engines": { ··· 1396 2423 }, 1397 2424 "node_modules/concat-map": { 1398 2425 "version": "0.0.1", 2426 + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 2427 + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1399 2428 "dev": true, 1400 2429 "license": "MIT" 1401 2430 }, 1402 2431 "node_modules/consola": { 1403 2432 "version": "3.4.2", 2433 + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", 2434 + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", 1404 2435 "dev": true, 1405 2436 "license": "MIT", 1406 2437 "engines": { ··· 1409 2440 }, 1410 2441 "node_modules/cookie": { 1411 2442 "version": "0.6.0", 2443 + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", 2444 + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", 1412 2445 "dev": true, 1413 2446 "license": "MIT", 1414 2447 "engines": { ··· 1417 2450 }, 1418 2451 "node_modules/cross-spawn": { 1419 2452 "version": "7.0.6", 2453 + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 2454 + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 1420 2455 "dev": true, 1421 2456 "license": "MIT", 1422 2457 "dependencies": { ··· 1430 2465 }, 1431 2466 "node_modules/css-background-parser": { 1432 2467 "version": "0.1.0", 2468 + "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz", 2469 + "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==", 1433 2470 "license": "MIT" 1434 2471 }, 1435 2472 "node_modules/css-box-shadow": { 1436 2473 "version": "1.0.0-3", 2474 + "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz", 2475 + "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==", 1437 2476 "license": "MIT" 1438 2477 }, 1439 2478 "node_modules/css-color-keywords": { 1440 2479 "version": "1.0.0", 2480 + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", 2481 + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", 1441 2482 "license": "ISC", 1442 2483 "engines": { 1443 2484 "node": ">=4" ··· 1445 2486 }, 1446 2487 "node_modules/css-gradient-parser": { 1447 2488 "version": "0.0.16", 2489 + "resolved": "https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.16.tgz", 2490 + "integrity": "sha512-3O5QdqgFRUbXvK1x5INf1YkBz1UKSWqrd63vWsum8MNHDBYD5urm3QtxZbKU259OrEXNM26lP/MPY3d1IGkBgA==", 1448 2491 "license": "MIT", 1449 2492 "engines": { 1450 2493 "node": ">=16" ··· 1452 2495 }, 1453 2496 "node_modules/css-to-react-native": { 1454 2497 "version": "3.2.0", 2498 + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", 2499 + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", 1455 2500 "license": "MIT", 1456 2501 "dependencies": { 1457 2502 "camelize": "^1.0.0", ··· 1461 2506 }, 1462 2507 "node_modules/cssesc": { 1463 2508 "version": "3.0.0", 2509 + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", 2510 + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", 1464 2511 "license": "MIT", 1465 2512 "bin": { 1466 2513 "cssesc": "bin/cssesc" ··· 1470 2517 } 1471 2518 }, 1472 2519 "node_modules/debug": { 1473 - "version": "4.3.7", 2520 + "version": "4.4.1", 2521 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", 2522 + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", 1474 2523 "license": "MIT", 1475 2524 "dependencies": { 1476 2525 "ms": "^2.1.3" ··· 1485 2534 } 1486 2535 }, 1487 2536 "node_modules/decode-named-character-reference": { 1488 - "version": "1.0.2", 2537 + "version": "1.2.0", 2538 + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", 2539 + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", 1489 2540 "license": "MIT", 1490 2541 "dependencies": { 1491 2542 "character-entities": "^2.0.0" ··· 1497 2548 }, 1498 2549 "node_modules/deep-is": { 1499 2550 "version": "0.1.4", 2551 + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 2552 + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 1500 2553 "dev": true, 1501 2554 "license": "MIT" 1502 2555 }, 1503 2556 "node_modules/deepmerge": { 1504 2557 "version": "4.3.1", 2558 + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", 2559 + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", 1505 2560 "license": "MIT", 1506 2561 "engines": { 1507 2562 "node": ">=0.10.0" ··· 1509 2564 }, 1510 2565 "node_modules/dequal": { 1511 2566 "version": "2.0.3", 2567 + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", 2568 + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", 1512 2569 "license": "MIT", 1513 2570 "engines": { 1514 2571 "node": ">=6" 1515 2572 } 1516 2573 }, 1517 2574 "node_modules/detect-libc": { 1518 - "version": "2.0.3", 2575 + "version": "2.0.4", 2576 + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", 2577 + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", 1519 2578 "dev": true, 1520 2579 "license": "Apache-2.0", 1521 2580 "engines": { ··· 1524 2583 }, 1525 2584 "node_modules/devalue": { 1526 2585 "version": "5.1.1", 2586 + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", 2587 + "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==", 1527 2588 "dev": true, 1528 2589 "license": "MIT" 1529 2590 }, 1530 2591 "node_modules/devlop": { 1531 2592 "version": "1.1.0", 2593 + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", 2594 + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", 1532 2595 "license": "MIT", 1533 2596 "dependencies": { 1534 2597 "dequal": "^2.0.0" ··· 1540 2603 }, 1541 2604 "node_modules/didyoumean": { 1542 2605 "version": "1.2.2", 2606 + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", 2607 + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", 1543 2608 "dev": true, 1544 2609 "license": "Apache-2.0" 1545 2610 }, 1546 2611 "node_modules/dlv": { 1547 2612 "version": "1.1.3", 2613 + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", 2614 + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", 1548 2615 "dev": true, 1549 2616 "license": "MIT" 1550 2617 }, 1551 2618 "node_modules/dom-serializer": { 1552 2619 "version": "2.0.0", 2620 + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", 2621 + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", 1553 2622 "license": "MIT", 1554 2623 "dependencies": { 1555 2624 "domelementtype": "^2.3.0", ··· 1562 2631 }, 1563 2632 "node_modules/domelementtype": { 1564 2633 "version": "2.3.0", 2634 + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", 2635 + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", 1565 2636 "funding": [ 1566 2637 { 1567 2638 "type": "github", ··· 1572 2643 }, 1573 2644 "node_modules/domhandler": { 1574 2645 "version": "5.0.3", 2646 + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", 2647 + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", 1575 2648 "license": "BSD-2-Clause", 1576 2649 "dependencies": { 1577 2650 "domelementtype": "^2.3.0" ··· 1584 2657 } 1585 2658 }, 1586 2659 "node_modules/domutils": { 1587 - "version": "3.1.0", 2660 + "version": "3.2.2", 2661 + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", 2662 + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", 1588 2663 "license": "BSD-2-Clause", 1589 2664 "dependencies": { 1590 2665 "dom-serializer": "^2.0.0", ··· 1597 2672 }, 1598 2673 "node_modules/eastasianwidth": { 1599 2674 "version": "0.2.0", 2675 + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 2676 + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 1600 2677 "dev": true, 1601 2678 "license": "MIT" 1602 2679 }, 1603 2680 "node_modules/electron-to-chromium": { 1604 - "version": "1.5.185", 2681 + "version": "1.5.192", 2682 + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.192.tgz", 2683 + "integrity": "sha512-rP8Ez0w7UNw/9j5eSXCe10o1g/8B1P5SM90PCCMVkIRQn2R0LEHWz4Eh9RnxkniuDe1W0cTSOB3MLlkTGDcuCg==", 1605 2684 "dev": true, 1606 2685 "license": "ISC" 1607 2686 }, 1608 2687 "node_modules/emoji-regex": { 1609 - "version": "9.2.2", 1610 - "dev": true, 2688 + "version": "10.4.0", 2689 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", 2690 + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", 1611 2691 "license": "MIT" 1612 2692 }, 1613 2693 "node_modules/entities": { 1614 2694 "version": "4.5.0", 2695 + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 2696 + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 1615 2697 "license": "BSD-2-Clause", 1616 2698 "engines": { 1617 2699 "node": ">=0.12" ··· 1621 2703 } 1622 2704 }, 1623 2705 "node_modules/esbuild": { 1624 - "version": "0.21.5", 2706 + "version": "0.25.8", 2707 + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", 2708 + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", 1625 2709 "dev": true, 1626 2710 "hasInstallScript": true, 1627 2711 "license": "MIT", ··· 1629 2713 "esbuild": "bin/esbuild" 1630 2714 }, 1631 2715 "engines": { 1632 - "node": ">=12" 2716 + "node": ">=18" 1633 2717 }, 1634 2718 "optionalDependencies": { 1635 - "@esbuild/aix-ppc64": "0.21.5", 1636 - "@esbuild/android-arm": "0.21.5", 1637 - "@esbuild/android-arm64": "0.21.5", 1638 - "@esbuild/android-x64": "0.21.5", 1639 - "@esbuild/darwin-arm64": "0.21.5", 1640 - "@esbuild/darwin-x64": "0.21.5", 1641 - "@esbuild/freebsd-arm64": "0.21.5", 1642 - "@esbuild/freebsd-x64": "0.21.5", 1643 - "@esbuild/linux-arm": "0.21.5", 1644 - "@esbuild/linux-arm64": "0.21.5", 1645 - "@esbuild/linux-ia32": "0.21.5", 1646 - "@esbuild/linux-loong64": "0.21.5", 1647 - "@esbuild/linux-mips64el": "0.21.5", 1648 - "@esbuild/linux-ppc64": "0.21.5", 1649 - "@esbuild/linux-riscv64": "0.21.5", 1650 - "@esbuild/linux-s390x": "0.21.5", 1651 - "@esbuild/linux-x64": "0.21.5", 1652 - "@esbuild/netbsd-x64": "0.21.5", 1653 - "@esbuild/openbsd-x64": "0.21.5", 1654 - "@esbuild/sunos-x64": "0.21.5", 1655 - "@esbuild/win32-arm64": "0.21.5", 1656 - "@esbuild/win32-ia32": "0.21.5", 1657 - "@esbuild/win32-x64": "0.21.5" 2719 + "@esbuild/aix-ppc64": "0.25.8", 2720 + "@esbuild/android-arm": "0.25.8", 2721 + "@esbuild/android-arm64": "0.25.8", 2722 + "@esbuild/android-x64": "0.25.8", 2723 + "@esbuild/darwin-arm64": "0.25.8", 2724 + "@esbuild/darwin-x64": "0.25.8", 2725 + "@esbuild/freebsd-arm64": "0.25.8", 2726 + "@esbuild/freebsd-x64": "0.25.8", 2727 + "@esbuild/linux-arm": "0.25.8", 2728 + "@esbuild/linux-arm64": "0.25.8", 2729 + "@esbuild/linux-ia32": "0.25.8", 2730 + "@esbuild/linux-loong64": "0.25.8", 2731 + "@esbuild/linux-mips64el": "0.25.8", 2732 + "@esbuild/linux-ppc64": "0.25.8", 2733 + "@esbuild/linux-riscv64": "0.25.8", 2734 + "@esbuild/linux-s390x": "0.25.8", 2735 + "@esbuild/linux-x64": "0.25.8", 2736 + "@esbuild/netbsd-arm64": "0.25.8", 2737 + "@esbuild/netbsd-x64": "0.25.8", 2738 + "@esbuild/openbsd-arm64": "0.25.8", 2739 + "@esbuild/openbsd-x64": "0.25.8", 2740 + "@esbuild/openharmony-arm64": "0.25.8", 2741 + "@esbuild/sunos-x64": "0.25.8", 2742 + "@esbuild/win32-arm64": "0.25.8", 2743 + "@esbuild/win32-ia32": "0.25.8", 2744 + "@esbuild/win32-x64": "0.25.8" 1658 2745 } 1659 2746 }, 1660 2747 "node_modules/escalade": { 1661 2748 "version": "3.2.0", 2749 + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 2750 + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 1662 2751 "dev": true, 1663 2752 "license": "MIT", 1664 2753 "engines": { ··· 1667 2756 }, 1668 2757 "node_modules/escape-html": { 1669 2758 "version": "1.0.3", 2759 + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 2760 + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", 1670 2761 "license": "MIT" 1671 2762 }, 1672 2763 "node_modules/escape-string-regexp": { 1673 2764 "version": "4.0.0", 2765 + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 2766 + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1674 2767 "license": "MIT", 1675 2768 "engines": { 1676 2769 "node": ">=10" ··· 1680 2773 } 1681 2774 }, 1682 2775 "node_modules/eslint": { 1683 - "version": "9.16.0", 2776 + "version": "9.32.0", 2777 + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", 2778 + "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", 1684 2779 "dev": true, 1685 2780 "license": "MIT", 1686 2781 "dependencies": { 1687 2782 "@eslint-community/eslint-utils": "^4.2.0", 1688 2783 "@eslint-community/regexpp": "^4.12.1", 1689 - "@eslint/config-array": "^0.19.0", 1690 - "@eslint/core": "^0.9.0", 1691 - "@eslint/eslintrc": "^3.2.0", 1692 - "@eslint/js": "9.16.0", 1693 - "@eslint/plugin-kit": "^0.2.3", 2784 + "@eslint/config-array": "^0.21.0", 2785 + "@eslint/config-helpers": "^0.3.0", 2786 + "@eslint/core": "^0.15.0", 2787 + "@eslint/eslintrc": "^3.3.1", 2788 + "@eslint/js": "9.32.0", 2789 + "@eslint/plugin-kit": "^0.3.4", 1694 2790 "@humanfs/node": "^0.16.6", 1695 2791 "@humanwhocodes/module-importer": "^1.0.1", 1696 - "@humanwhocodes/retry": "^0.4.1", 2792 + "@humanwhocodes/retry": "^0.4.2", 1697 2793 "@types/estree": "^1.0.6", 1698 2794 "@types/json-schema": "^7.0.15", 1699 2795 "ajv": "^6.12.4", 1700 2796 "chalk": "^4.0.0", 1701 - "cross-spawn": "^7.0.5", 2797 + "cross-spawn": "^7.0.6", 1702 2798 "debug": "^4.3.2", 1703 2799 "escape-string-regexp": "^4.0.0", 1704 - "eslint-scope": "^8.2.0", 1705 - "eslint-visitor-keys": "^4.2.0", 1706 - "espree": "^10.3.0", 2800 + "eslint-scope": "^8.4.0", 2801 + "eslint-visitor-keys": "^4.2.1", 2802 + "espree": "^10.4.0", 1707 2803 "esquery": "^1.5.0", 1708 2804 "esutils": "^2.0.2", 1709 2805 "fast-deep-equal": "^3.1.3", ··· 1739 2835 }, 1740 2836 "node_modules/eslint-compat-utils": { 1741 2837 "version": "0.5.1", 2838 + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", 2839 + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", 1742 2840 "dev": true, 1743 2841 "license": "MIT", 1744 2842 "dependencies": { ··· 1753 2851 }, 1754 2852 "node_modules/eslint-plugin-svelte": { 1755 2853 "version": "2.46.1", 2854 + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.1.tgz", 2855 + "integrity": "sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==", 1756 2856 "dev": true, 1757 2857 "license": "MIT", 1758 2858 "dependencies": { ··· 1784 2884 } 1785 2885 } 1786 2886 }, 2887 + "node_modules/eslint-plugin-svelte/node_modules/postcss-selector-parser": { 2888 + "version": "6.1.2", 2889 + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", 2890 + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", 2891 + "dev": true, 2892 + "license": "MIT", 2893 + "dependencies": { 2894 + "cssesc": "^3.0.0", 2895 + "util-deprecate": "^1.0.2" 2896 + }, 2897 + "engines": { 2898 + "node": ">=4" 2899 + } 2900 + }, 1787 2901 "node_modules/eslint-scope": { 1788 - "version": "8.2.0", 2902 + "version": "8.4.0", 2903 + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", 2904 + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", 1789 2905 "dev": true, 1790 2906 "license": "BSD-2-Clause", 1791 2907 "dependencies": { ··· 1800 2916 } 1801 2917 }, 1802 2918 "node_modules/eslint-visitor-keys": { 1803 - "version": "4.2.0", 2919 + "version": "4.2.1", 2920 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", 2921 + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", 1804 2922 "dev": true, 1805 2923 "license": "Apache-2.0", 1806 2924 "engines": { ··· 1812 2930 }, 1813 2931 "node_modules/esm-env": { 1814 2932 "version": "1.2.2", 2933 + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", 2934 + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", 1815 2935 "dev": true, 1816 2936 "license": "MIT" 1817 2937 }, 1818 2938 "node_modules/espree": { 1819 - "version": "10.3.0", 2939 + "version": "10.4.0", 2940 + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", 2941 + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", 1820 2942 "dev": true, 1821 2943 "license": "BSD-2-Clause", 1822 2944 "dependencies": { 1823 - "acorn": "^8.14.0", 2945 + "acorn": "^8.15.0", 1824 2946 "acorn-jsx": "^5.3.2", 1825 - "eslint-visitor-keys": "^4.2.0" 2947 + "eslint-visitor-keys": "^4.2.1" 1826 2948 }, 1827 2949 "engines": { 1828 2950 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 1833 2955 }, 1834 2956 "node_modules/esquery": { 1835 2957 "version": "1.6.0", 2958 + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 2959 + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 1836 2960 "dev": true, 1837 2961 "license": "BSD-3-Clause", 1838 2962 "dependencies": { ··· 1844 2968 }, 1845 2969 "node_modules/esrap": { 1846 2970 "version": "2.1.0", 2971 + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz", 2972 + "integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==", 1847 2973 "dev": true, 1848 2974 "license": "MIT", 1849 2975 "dependencies": { ··· 1852 2978 }, 1853 2979 "node_modules/esrecurse": { 1854 2980 "version": "4.3.0", 2981 + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 2982 + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1855 2983 "dev": true, 1856 2984 "license": "BSD-2-Clause", 1857 2985 "dependencies": { ··· 1863 2991 }, 1864 2992 "node_modules/estraverse": { 1865 2993 "version": "5.3.0", 2994 + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 2995 + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1866 2996 "dev": true, 1867 2997 "license": "BSD-2-Clause", 1868 2998 "engines": { ··· 1871 3001 }, 1872 3002 "node_modules/estree-walker": { 1873 3003 "version": "2.0.2", 3004 + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 3005 + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 1874 3006 "dev": true, 1875 3007 "license": "MIT" 1876 3008 }, 1877 3009 "node_modules/esutils": { 1878 3010 "version": "2.0.3", 3011 + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 3012 + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1879 3013 "dev": true, 1880 3014 "license": "BSD-2-Clause", 1881 3015 "engines": { ··· 1884 3018 }, 1885 3019 "node_modules/extend": { 1886 3020 "version": "3.0.2", 3021 + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 3022 + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", 1887 3023 "license": "MIT" 1888 3024 }, 1889 3025 "node_modules/fast-deep-equal": { 1890 3026 "version": "3.1.3", 3027 + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 3028 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1891 3029 "dev": true, 1892 3030 "license": "MIT" 1893 3031 }, 1894 3032 "node_modules/fast-glob": { 1895 - "version": "3.3.2", 3033 + "version": "3.3.3", 3034 + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", 3035 + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", 1896 3036 "dev": true, 1897 3037 "license": "MIT", 1898 3038 "dependencies": { ··· 1900 3040 "@nodelib/fs.walk": "^1.2.3", 1901 3041 "glob-parent": "^5.1.2", 1902 3042 "merge2": "^1.3.0", 1903 - "micromatch": "^4.0.4" 3043 + "micromatch": "^4.0.8" 1904 3044 }, 1905 3045 "engines": { 1906 3046 "node": ">=8.6.0" ··· 1908 3048 }, 1909 3049 "node_modules/fast-glob/node_modules/glob-parent": { 1910 3050 "version": "5.1.2", 3051 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 3052 + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1911 3053 "dev": true, 1912 3054 "license": "ISC", 1913 3055 "dependencies": { ··· 1919 3061 }, 1920 3062 "node_modules/fast-json-stable-stringify": { 1921 3063 "version": "2.1.0", 3064 + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 3065 + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1922 3066 "dev": true, 1923 3067 "license": "MIT" 1924 3068 }, 1925 3069 "node_modules/fast-levenshtein": { 1926 3070 "version": "2.0.6", 3071 + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 3072 + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1927 3073 "dev": true, 1928 3074 "license": "MIT" 1929 3075 }, 1930 3076 "node_modules/fastq": { 1931 - "version": "1.17.1", 3077 + "version": "1.19.1", 3078 + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", 3079 + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", 1932 3080 "dev": true, 1933 3081 "license": "ISC", 1934 3082 "dependencies": { ··· 1936 3084 } 1937 3085 }, 1938 3086 "node_modules/fdir": { 1939 - "version": "6.4.2", 3087 + "version": "6.4.6", 3088 + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", 3089 + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", 1940 3090 "dev": true, 1941 3091 "license": "MIT", 1942 3092 "peerDependencies": { ··· 1950 3100 }, 1951 3101 "node_modules/fflate": { 1952 3102 "version": "0.7.4", 3103 + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", 3104 + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", 1953 3105 "license": "MIT" 1954 3106 }, 1955 3107 "node_modules/file-entry-cache": { 1956 3108 "version": "8.0.0", 3109 + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 3110 + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 1957 3111 "dev": true, 1958 3112 "license": "MIT", 1959 3113 "dependencies": { ··· 1965 3119 }, 1966 3120 "node_modules/file-uri-to-path": { 1967 3121 "version": "1.0.0", 3122 + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", 3123 + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", 1968 3124 "dev": true, 1969 3125 "license": "MIT" 1970 3126 }, 1971 3127 "node_modules/fill-range": { 1972 3128 "version": "7.1.1", 3129 + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 3130 + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 1973 3131 "dev": true, 1974 3132 "license": "MIT", 1975 3133 "dependencies": { ··· 1981 3139 }, 1982 3140 "node_modules/find-up": { 1983 3141 "version": "5.0.0", 3142 + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 3143 + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1984 3144 "dev": true, 1985 3145 "license": "MIT", 1986 3146 "dependencies": { ··· 1996 3156 }, 1997 3157 "node_modules/flat-cache": { 1998 3158 "version": "4.0.1", 3159 + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 3160 + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 1999 3161 "dev": true, 2000 3162 "license": "MIT", 2001 3163 "dependencies": { ··· 2007 3169 } 2008 3170 }, 2009 3171 "node_modules/flatted": { 2010 - "version": "3.3.2", 3172 + "version": "3.3.3", 3173 + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 3174 + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", 2011 3175 "dev": true, 2012 3176 "license": "ISC" 2013 3177 }, 2014 3178 "node_modules/foreground-child": { 2015 - "version": "3.3.0", 3179 + "version": "3.3.1", 3180 + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", 3181 + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", 2016 3182 "dev": true, 2017 3183 "license": "ISC", 2018 3184 "dependencies": { 2019 - "cross-spawn": "^7.0.0", 3185 + "cross-spawn": "^7.0.6", 2020 3186 "signal-exit": "^4.0.1" 2021 3187 }, 2022 3188 "engines": { ··· 2028 3194 }, 2029 3195 "node_modules/fraction.js": { 2030 3196 "version": "4.3.7", 3197 + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", 3198 + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", 2031 3199 "dev": true, 2032 3200 "license": "MIT", 2033 3201 "engines": { ··· 2040 3208 }, 2041 3209 "node_modules/fsevents": { 2042 3210 "version": "2.3.3", 3211 + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 3212 + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 2043 3213 "dev": true, 3214 + "hasInstallScript": true, 2044 3215 "license": "MIT", 2045 3216 "optional": true, 2046 3217 "os": [ ··· 2052 3223 }, 2053 3224 "node_modules/function-bind": { 2054 3225 "version": "1.1.2", 3226 + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 3227 + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 2055 3228 "license": "MIT", 2056 3229 "funding": { 2057 3230 "url": "https://github.com/sponsors/ljharb" ··· 2059 3232 }, 2060 3233 "node_modules/glob": { 2061 3234 "version": "10.4.5", 3235 + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 3236 + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 2062 3237 "dev": true, 2063 3238 "license": "ISC", 2064 3239 "dependencies": { ··· 2078 3253 }, 2079 3254 "node_modules/glob-parent": { 2080 3255 "version": "6.0.2", 3256 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 3257 + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 2081 3258 "dev": true, 2082 3259 "license": "ISC", 2083 3260 "dependencies": { ··· 2088 3265 } 2089 3266 }, 2090 3267 "node_modules/glob/node_modules/brace-expansion": { 2091 - "version": "2.0.1", 3268 + "version": "2.0.2", 3269 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", 3270 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", 2092 3271 "dev": true, 2093 3272 "license": "MIT", 2094 3273 "dependencies": { ··· 2097 3276 }, 2098 3277 "node_modules/glob/node_modules/minimatch": { 2099 3278 "version": "9.0.5", 3279 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 3280 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 2100 3281 "dev": true, 2101 3282 "license": "ISC", 2102 3283 "dependencies": { ··· 2110 3291 } 2111 3292 }, 2112 3293 "node_modules/globals": { 2113 - "version": "15.13.0", 3294 + "version": "15.15.0", 3295 + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", 3296 + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", 2114 3297 "dev": true, 2115 3298 "license": "MIT", 2116 3299 "engines": { ··· 2122 3305 }, 2123 3306 "node_modules/graceful-fs": { 2124 3307 "version": "4.2.11", 3308 + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 3309 + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 2125 3310 "dev": true, 2126 3311 "license": "ISC" 2127 3312 }, 2128 3313 "node_modules/graphemer": { 2129 3314 "version": "1.4.0", 3315 + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 3316 + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 2130 3317 "dev": true, 2131 3318 "license": "MIT" 2132 3319 }, 2133 3320 "node_modules/has-flag": { 2134 3321 "version": "4.0.0", 3322 + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 3323 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2135 3324 "dev": true, 2136 3325 "license": "MIT", 2137 3326 "engines": { ··· 2140 3329 }, 2141 3330 "node_modules/hasown": { 2142 3331 "version": "2.0.2", 3332 + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 3333 + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 2143 3334 "license": "MIT", 2144 3335 "dependencies": { 2145 3336 "function-bind": "^1.1.2" ··· 2149 3340 } 2150 3341 }, 2151 3342 "node_modules/hast-util-from-parse5": { 2152 - "version": "8.0.2", 3343 + "version": "8.0.3", 3344 + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", 3345 + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", 2153 3346 "license": "MIT", 2154 3347 "dependencies": { 2155 3348 "@types/hast": "^3.0.0", 2156 3349 "@types/unist": "^3.0.0", 2157 3350 "devlop": "^1.0.0", 2158 3351 "hastscript": "^9.0.0", 2159 - "property-information": "^6.0.0", 3352 + "property-information": "^7.0.0", 2160 3353 "vfile": "^6.0.0", 2161 3354 "vfile-location": "^5.0.0", 2162 3355 "web-namespaces": "^2.0.0" ··· 2168 3361 }, 2169 3362 "node_modules/hast-util-parse-selector": { 2170 3363 "version": "4.0.0", 3364 + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", 3365 + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", 2171 3366 "license": "MIT", 2172 3367 "dependencies": { 2173 3368 "@types/hast": "^3.0.0" ··· 2179 3374 }, 2180 3375 "node_modules/hast-util-raw": { 2181 3376 "version": "9.1.0", 3377 + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", 3378 + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", 2182 3379 "license": "MIT", 2183 3380 "dependencies": { 2184 3381 "@types/hast": "^3.0.0", ··· 2202 3399 }, 2203 3400 "node_modules/hast-util-sanitize": { 2204 3401 "version": "5.0.2", 3402 + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", 3403 + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", 2205 3404 "license": "MIT", 2206 3405 "dependencies": { 2207 3406 "@types/hast": "^3.0.0", ··· 2214 3413 } 2215 3414 }, 2216 3415 "node_modules/hast-util-to-html": { 2217 - "version": "9.0.3", 3416 + "version": "9.0.5", 3417 + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", 3418 + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", 2218 3419 "license": "MIT", 2219 3420 "dependencies": { 2220 3421 "@types/hast": "^3.0.0", ··· 2224 3425 "hast-util-whitespace": "^3.0.0", 2225 3426 "html-void-elements": "^3.0.0", 2226 3427 "mdast-util-to-hast": "^13.0.0", 2227 - "property-information": "^6.0.0", 3428 + "property-information": "^7.0.0", 2228 3429 "space-separated-tokens": "^2.0.0", 2229 3430 "stringify-entities": "^4.0.0", 2230 3431 "zwitch": "^2.0.4" ··· 2236 3437 }, 2237 3438 "node_modules/hast-util-to-parse5": { 2238 3439 "version": "8.0.0", 3440 + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", 3441 + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", 2239 3442 "license": "MIT", 2240 3443 "dependencies": { 2241 3444 "@types/hast": "^3.0.0", ··· 2251 3454 "url": "https://opencollective.com/unified" 2252 3455 } 2253 3456 }, 3457 + "node_modules/hast-util-to-parse5/node_modules/property-information": { 3458 + "version": "6.5.0", 3459 + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", 3460 + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", 3461 + "license": "MIT", 3462 + "funding": { 3463 + "type": "github", 3464 + "url": "https://github.com/sponsors/wooorm" 3465 + } 3466 + }, 2254 3467 "node_modules/hast-util-whitespace": { 2255 3468 "version": "3.0.0", 3469 + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", 3470 + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", 2256 3471 "license": "MIT", 2257 3472 "dependencies": { 2258 3473 "@types/hast": "^3.0.0" ··· 2263 3478 } 2264 3479 }, 2265 3480 "node_modules/hastscript": { 2266 - "version": "9.0.0", 3481 + "version": "9.0.1", 3482 + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", 3483 + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", 2267 3484 "license": "MIT", 2268 3485 "dependencies": { 2269 3486 "@types/hast": "^3.0.0", 2270 3487 "comma-separated-tokens": "^2.0.0", 2271 3488 "hast-util-parse-selector": "^4.0.0", 2272 - "property-information": "^6.0.0", 3489 + "property-information": "^7.0.0", 2273 3490 "space-separated-tokens": "^2.0.0" 2274 3491 }, 2275 3492 "funding": { ··· 2279 3496 }, 2280 3497 "node_modules/hex-rgb": { 2281 3498 "version": "4.3.0", 3499 + "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz", 3500 + "integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==", 2282 3501 "license": "MIT", 2283 3502 "engines": { 2284 3503 "node": ">=6" ··· 2289 3508 }, 2290 3509 "node_modules/html-void-elements": { 2291 3510 "version": "3.0.0", 3511 + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", 3512 + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", 2292 3513 "license": "MIT", 2293 3514 "funding": { 2294 3515 "type": "github", ··· 2297 3518 }, 2298 3519 "node_modules/htmlparser2": { 2299 3520 "version": "8.0.2", 3521 + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", 3522 + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", 2300 3523 "funding": [ 2301 3524 "https://github.com/fb55/htmlparser2?sponsor=1", 2302 3525 { ··· 2314 3537 }, 2315 3538 "node_modules/https-proxy-agent": { 2316 3539 "version": "7.0.6", 3540 + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", 3541 + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", 2317 3542 "dev": true, 2318 3543 "license": "MIT", 2319 3544 "dependencies": { ··· 2326 3551 }, 2327 3552 "node_modules/ignore": { 2328 3553 "version": "5.3.2", 3554 + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 3555 + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 2329 3556 "dev": true, 2330 3557 "license": "MIT", 2331 3558 "engines": { ··· 2333 3560 } 2334 3561 }, 2335 3562 "node_modules/import-fresh": { 2336 - "version": "3.3.0", 3563 + "version": "3.3.1", 3564 + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 3565 + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 2337 3566 "dev": true, 2338 3567 "license": "MIT", 2339 3568 "dependencies": { ··· 2347 3576 "url": "https://github.com/sponsors/sindresorhus" 2348 3577 } 2349 3578 }, 3579 + "node_modules/import-fresh/node_modules/resolve-from": { 3580 + "version": "4.0.0", 3581 + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 3582 + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 3583 + "dev": true, 3584 + "license": "MIT", 3585 + "engines": { 3586 + "node": ">=4" 3587 + } 3588 + }, 2350 3589 "node_modules/imurmurhash": { 2351 3590 "version": "0.1.4", 3591 + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 3592 + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 2352 3593 "dev": true, 2353 3594 "license": "MIT", 2354 3595 "engines": { ··· 2357 3598 }, 2358 3599 "node_modules/is-binary-path": { 2359 3600 "version": "2.1.0", 3601 + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 3602 + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 2360 3603 "dev": true, 2361 3604 "license": "MIT", 2362 3605 "dependencies": { ··· 2367 3610 } 2368 3611 }, 2369 3612 "node_modules/is-core-module": { 2370 - "version": "2.15.1", 3613 + "version": "2.16.1", 3614 + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 3615 + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 2371 3616 "license": "MIT", 2372 3617 "dependencies": { 2373 3618 "hasown": "^2.0.2" ··· 2381 3626 }, 2382 3627 "node_modules/is-extglob": { 2383 3628 "version": "2.1.1", 3629 + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 3630 + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 2384 3631 "dev": true, 2385 3632 "license": "MIT", 2386 3633 "engines": { ··· 2389 3636 }, 2390 3637 "node_modules/is-fullwidth-code-point": { 2391 3638 "version": "3.0.0", 3639 + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 3640 + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2392 3641 "dev": true, 2393 3642 "license": "MIT", 2394 3643 "engines": { ··· 2397 3646 }, 2398 3647 "node_modules/is-glob": { 2399 3648 "version": "4.0.3", 3649 + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 3650 + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 2400 3651 "dev": true, 2401 3652 "license": "MIT", 2402 3653 "dependencies": { ··· 2408 3659 }, 2409 3660 "node_modules/is-number": { 2410 3661 "version": "7.0.0", 3662 + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 3663 + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 2411 3664 "dev": true, 2412 3665 "license": "MIT", 2413 3666 "engines": { ··· 2416 3669 }, 2417 3670 "node_modules/is-plain-obj": { 2418 3671 "version": "4.1.0", 3672 + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", 3673 + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", 2419 3674 "license": "MIT", 2420 3675 "engines": { 2421 3676 "node": ">=12" ··· 2426 3681 }, 2427 3682 "node_modules/is-plain-object": { 2428 3683 "version": "5.0.0", 3684 + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", 3685 + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", 2429 3686 "license": "MIT", 2430 3687 "engines": { 2431 3688 "node": ">=0.10.0" ··· 2433 3690 }, 2434 3691 "node_modules/is-reference": { 2435 3692 "version": "3.0.3", 3693 + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", 3694 + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", 2436 3695 "dev": true, 2437 3696 "license": "MIT", 2438 3697 "dependencies": { ··· 2441 3700 }, 2442 3701 "node_modules/isexe": { 2443 3702 "version": "2.0.0", 3703 + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 3704 + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 2444 3705 "dev": true, 2445 3706 "license": "ISC" 2446 3707 }, 2447 3708 "node_modules/jackspeak": { 2448 3709 "version": "3.4.3", 3710 + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 3711 + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 2449 3712 "dev": true, 2450 3713 "license": "BlueOak-1.0.0", 2451 3714 "dependencies": { ··· 2459 3722 } 2460 3723 }, 2461 3724 "node_modules/jiti": { 2462 - "version": "1.21.6", 3725 + "version": "1.21.7", 3726 + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", 3727 + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", 2463 3728 "dev": true, 2464 3729 "license": "MIT", 2465 3730 "bin": { ··· 2468 3733 }, 2469 3734 "node_modules/js-yaml": { 2470 3735 "version": "4.1.0", 3736 + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 3737 + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 2471 3738 "dev": true, 2472 3739 "license": "MIT", 2473 3740 "dependencies": { ··· 2479 3746 }, 2480 3747 "node_modules/json-buffer": { 2481 3748 "version": "3.0.1", 3749 + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 3750 + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 2482 3751 "dev": true, 2483 3752 "license": "MIT" 2484 3753 }, 2485 3754 "node_modules/json-schema-traverse": { 2486 3755 "version": "0.4.1", 3756 + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 3757 + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 2487 3758 "dev": true, 2488 3759 "license": "MIT" 2489 3760 }, 2490 3761 "node_modules/json-stable-stringify-without-jsonify": { 2491 3762 "version": "1.0.1", 3763 + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 3764 + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 2492 3765 "dev": true, 2493 3766 "license": "MIT" 2494 3767 }, 2495 3768 "node_modules/keyv": { 2496 3769 "version": "4.5.4", 3770 + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 3771 + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 2497 3772 "dev": true, 2498 3773 "license": "MIT", 2499 3774 "dependencies": { ··· 2502 3777 }, 2503 3778 "node_modules/kleur": { 2504 3779 "version": "4.1.5", 3780 + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", 3781 + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", 2505 3782 "dev": true, 2506 3783 "license": "MIT", 2507 3784 "engines": { ··· 2510 3787 }, 2511 3788 "node_modules/known-css-properties": { 2512 3789 "version": "0.35.0", 3790 + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", 3791 + "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", 2513 3792 "dev": true, 2514 3793 "license": "MIT" 2515 3794 }, 2516 3795 "node_modules/levn": { 2517 3796 "version": "0.4.1", 3797 + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 3798 + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 2518 3799 "dev": true, 2519 3800 "license": "MIT", 2520 3801 "dependencies": { ··· 2527 3808 }, 2528 3809 "node_modules/lilconfig": { 2529 3810 "version": "2.1.0", 3811 + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", 3812 + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", 2530 3813 "dev": true, 2531 3814 "license": "MIT", 2532 3815 "engines": { ··· 2535 3818 }, 2536 3819 "node_modules/linebreak": { 2537 3820 "version": "1.1.0", 3821 + "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz", 3822 + "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==", 2538 3823 "license": "MIT", 2539 3824 "dependencies": { 2540 3825 "base64-js": "0.0.8", ··· 2543 3828 }, 2544 3829 "node_modules/lines-and-columns": { 2545 3830 "version": "1.2.4", 3831 + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 3832 + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 2546 3833 "dev": true, 2547 3834 "license": "MIT" 2548 3835 }, 2549 3836 "node_modules/locate-character": { 2550 3837 "version": "3.0.0", 3838 + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", 3839 + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", 2551 3840 "dev": true, 2552 3841 "license": "MIT" 2553 3842 }, 2554 3843 "node_modules/locate-path": { 2555 3844 "version": "6.0.0", 3845 + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 3846 + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 2556 3847 "dev": true, 2557 3848 "license": "MIT", 2558 3849 "dependencies": { ··· 2567 3858 }, 2568 3859 "node_modules/lodash.castarray": { 2569 3860 "version": "4.4.0", 3861 + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", 3862 + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", 2570 3863 "dev": true, 2571 3864 "license": "MIT" 2572 3865 }, 2573 3866 "node_modules/lodash.isplainobject": { 2574 3867 "version": "4.0.6", 3868 + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 3869 + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", 2575 3870 "dev": true, 2576 3871 "license": "MIT" 2577 3872 }, 2578 3873 "node_modules/lodash.merge": { 2579 3874 "version": "4.6.2", 3875 + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 3876 + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 2580 3877 "dev": true, 2581 3878 "license": "MIT" 2582 3879 }, 2583 3880 "node_modules/longest-streak": { 2584 3881 "version": "3.1.0", 3882 + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", 3883 + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", 2585 3884 "license": "MIT", 2586 3885 "funding": { 2587 3886 "type": "github", ··· 2590 3889 }, 2591 3890 "node_modules/lru-cache": { 2592 3891 "version": "10.4.3", 3892 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 3893 + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 2593 3894 "dev": true, 2594 3895 "license": "ISC" 2595 3896 }, 2596 3897 "node_modules/magic-string": { 2597 - "version": "0.30.14", 3898 + "version": "0.30.17", 3899 + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", 3900 + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", 2598 3901 "dev": true, 2599 3902 "license": "MIT", 2600 3903 "dependencies": { ··· 2603 3906 }, 2604 3907 "node_modules/markdown-table": { 2605 3908 "version": "3.0.4", 3909 + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", 3910 + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", 2606 3911 "license": "MIT", 2607 3912 "funding": { 2608 3913 "type": "github", ··· 2610 3915 } 2611 3916 }, 2612 3917 "node_modules/mdast-util-find-and-replace": { 2613 - "version": "3.0.1", 3918 + "version": "3.0.2", 3919 + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", 3920 + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", 2614 3921 "license": "MIT", 2615 3922 "dependencies": { 2616 3923 "@types/mdast": "^4.0.0", ··· 2625 3932 }, 2626 3933 "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { 2627 3934 "version": "5.0.0", 3935 + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", 3936 + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", 2628 3937 "license": "MIT", 2629 3938 "engines": { 2630 3939 "node": ">=12" ··· 2635 3944 }, 2636 3945 "node_modules/mdast-util-from-markdown": { 2637 3946 "version": "2.0.2", 3947 + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", 3948 + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", 2638 3949 "license": "MIT", 2639 3950 "dependencies": { 2640 3951 "@types/mdast": "^4.0.0", ··· 2656 3967 } 2657 3968 }, 2658 3969 "node_modules/mdast-util-gfm": { 2659 - "version": "3.0.0", 3970 + "version": "3.1.0", 3971 + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", 3972 + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", 2660 3973 "license": "MIT", 2661 3974 "dependencies": { 2662 3975 "mdast-util-from-markdown": "^2.0.0", ··· 2674 3987 }, 2675 3988 "node_modules/mdast-util-gfm-autolink-literal": { 2676 3989 "version": "2.0.1", 3990 + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", 3991 + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", 2677 3992 "license": "MIT", 2678 3993 "dependencies": { 2679 3994 "@types/mdast": "^4.0.0", ··· 2688 4003 } 2689 4004 }, 2690 4005 "node_modules/mdast-util-gfm-footnote": { 2691 - "version": "2.0.0", 4006 + "version": "2.1.0", 4007 + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", 4008 + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", 2692 4009 "license": "MIT", 2693 4010 "dependencies": { 2694 4011 "@types/mdast": "^4.0.0", ··· 2704 4021 }, 2705 4022 "node_modules/mdast-util-gfm-strikethrough": { 2706 4023 "version": "2.0.0", 4024 + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", 4025 + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", 2707 4026 "license": "MIT", 2708 4027 "dependencies": { 2709 4028 "@types/mdast": "^4.0.0", ··· 2717 4036 }, 2718 4037 "node_modules/mdast-util-gfm-table": { 2719 4038 "version": "2.0.0", 4039 + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", 4040 + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", 2720 4041 "license": "MIT", 2721 4042 "dependencies": { 2722 4043 "@types/mdast": "^4.0.0", ··· 2732 4053 }, 2733 4054 "node_modules/mdast-util-gfm-task-list-item": { 2734 4055 "version": "2.0.0", 4056 + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", 4057 + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", 2735 4058 "license": "MIT", 2736 4059 "dependencies": { 2737 4060 "@types/mdast": "^4.0.0", ··· 2746 4069 }, 2747 4070 "node_modules/mdast-util-phrasing": { 2748 4071 "version": "4.1.0", 4072 + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", 4073 + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", 2749 4074 "license": "MIT", 2750 4075 "dependencies": { 2751 4076 "@types/mdast": "^4.0.0", ··· 2758 4083 }, 2759 4084 "node_modules/mdast-util-to-hast": { 2760 4085 "version": "13.2.0", 4086 + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", 4087 + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", 2761 4088 "license": "MIT", 2762 4089 "dependencies": { 2763 4090 "@types/hast": "^3.0.0", ··· 2777 4104 }, 2778 4105 "node_modules/mdast-util-to-markdown": { 2779 4106 "version": "2.1.2", 4107 + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", 4108 + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", 2780 4109 "license": "MIT", 2781 4110 "dependencies": { 2782 4111 "@types/mdast": "^4.0.0", ··· 2796 4125 }, 2797 4126 "node_modules/mdast-util-to-string": { 2798 4127 "version": "4.0.0", 4128 + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", 4129 + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", 2799 4130 "license": "MIT", 2800 4131 "dependencies": { 2801 4132 "@types/mdast": "^4.0.0" ··· 2807 4138 }, 2808 4139 "node_modules/merge2": { 2809 4140 "version": "1.4.1", 4141 + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 4142 + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 2810 4143 "dev": true, 2811 4144 "license": "MIT", 2812 4145 "engines": { ··· 2814 4147 } 2815 4148 }, 2816 4149 "node_modules/micromark": { 2817 - "version": "4.0.1", 4150 + "version": "4.0.2", 4151 + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", 4152 + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", 2818 4153 "funding": [ 2819 4154 { 2820 4155 "type": "GitHub Sponsors", ··· 2847 4182 } 2848 4183 }, 2849 4184 "node_modules/micromark-core-commonmark": { 2850 - "version": "2.0.2", 4185 + "version": "2.0.3", 4186 + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", 4187 + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", 2851 4188 "funding": [ 2852 4189 { 2853 4190 "type": "GitHub Sponsors", ··· 2880 4217 }, 2881 4218 "node_modules/micromark-extension-gfm": { 2882 4219 "version": "3.0.0", 4220 + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", 4221 + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", 2883 4222 "license": "MIT", 2884 4223 "dependencies": { 2885 4224 "micromark-extension-gfm-autolink-literal": "^2.0.0", ··· 2898 4237 }, 2899 4238 "node_modules/micromark-extension-gfm-autolink-literal": { 2900 4239 "version": "2.1.0", 4240 + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", 4241 + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", 2901 4242 "license": "MIT", 2902 4243 "dependencies": { 2903 4244 "micromark-util-character": "^2.0.0", ··· 2912 4253 }, 2913 4254 "node_modules/micromark-extension-gfm-footnote": { 2914 4255 "version": "2.1.0", 4256 + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", 4257 + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", 2915 4258 "license": "MIT", 2916 4259 "dependencies": { 2917 4260 "devlop": "^1.0.0", ··· 2930 4273 }, 2931 4274 "node_modules/micromark-extension-gfm-strikethrough": { 2932 4275 "version": "2.1.0", 4276 + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", 4277 + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", 2933 4278 "license": "MIT", 2934 4279 "dependencies": { 2935 4280 "devlop": "^1.0.0", ··· 2945 4290 } 2946 4291 }, 2947 4292 "node_modules/micromark-extension-gfm-table": { 2948 - "version": "2.1.0", 4293 + "version": "2.1.1", 4294 + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", 4295 + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", 2949 4296 "license": "MIT", 2950 4297 "dependencies": { 2951 4298 "devlop": "^1.0.0", ··· 2961 4308 }, 2962 4309 "node_modules/micromark-extension-gfm-tagfilter": { 2963 4310 "version": "2.0.0", 4311 + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", 4312 + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", 2964 4313 "license": "MIT", 2965 4314 "dependencies": { 2966 4315 "micromark-util-types": "^2.0.0" ··· 2972 4321 }, 2973 4322 "node_modules/micromark-extension-gfm-task-list-item": { 2974 4323 "version": "2.1.0", 4324 + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", 4325 + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", 2975 4326 "license": "MIT", 2976 4327 "dependencies": { 2977 4328 "devlop": "^1.0.0", ··· 2987 4338 }, 2988 4339 "node_modules/micromark-factory-destination": { 2989 4340 "version": "2.0.1", 4341 + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", 4342 + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", 2990 4343 "funding": [ 2991 4344 { 2992 4345 "type": "GitHub Sponsors", ··· 3006 4359 }, 3007 4360 "node_modules/micromark-factory-label": { 3008 4361 "version": "2.0.1", 4362 + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", 4363 + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", 3009 4364 "funding": [ 3010 4365 { 3011 4366 "type": "GitHub Sponsors", ··· 3026 4381 }, 3027 4382 "node_modules/micromark-factory-space": { 3028 4383 "version": "2.0.1", 4384 + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", 4385 + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", 3029 4386 "funding": [ 3030 4387 { 3031 4388 "type": "GitHub Sponsors", ··· 3044 4401 }, 3045 4402 "node_modules/micromark-factory-title": { 3046 4403 "version": "2.0.1", 4404 + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", 4405 + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", 3047 4406 "funding": [ 3048 4407 { 3049 4408 "type": "GitHub Sponsors", ··· 3064 4423 }, 3065 4424 "node_modules/micromark-factory-whitespace": { 3066 4425 "version": "2.0.1", 4426 + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", 4427 + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", 3067 4428 "funding": [ 3068 4429 { 3069 4430 "type": "GitHub Sponsors", ··· 3084 4445 }, 3085 4446 "node_modules/micromark-util-character": { 3086 4447 "version": "2.1.1", 4448 + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", 4449 + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", 3087 4450 "funding": [ 3088 4451 { 3089 4452 "type": "GitHub Sponsors", ··· 3102 4465 }, 3103 4466 "node_modules/micromark-util-chunked": { 3104 4467 "version": "2.0.1", 4468 + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", 4469 + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", 3105 4470 "funding": [ 3106 4471 { 3107 4472 "type": "GitHub Sponsors", ··· 3119 4484 }, 3120 4485 "node_modules/micromark-util-classify-character": { 3121 4486 "version": "2.0.1", 4487 + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", 4488 + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", 3122 4489 "funding": [ 3123 4490 { 3124 4491 "type": "GitHub Sponsors", ··· 3138 4505 }, 3139 4506 "node_modules/micromark-util-combine-extensions": { 3140 4507 "version": "2.0.1", 4508 + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", 4509 + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", 3141 4510 "funding": [ 3142 4511 { 3143 4512 "type": "GitHub Sponsors", ··· 3156 4525 }, 3157 4526 "node_modules/micromark-util-decode-numeric-character-reference": { 3158 4527 "version": "2.0.2", 4528 + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", 4529 + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", 3159 4530 "funding": [ 3160 4531 { 3161 4532 "type": "GitHub Sponsors", ··· 3173 4544 }, 3174 4545 "node_modules/micromark-util-decode-string": { 3175 4546 "version": "2.0.1", 4547 + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", 4548 + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", 3176 4549 "funding": [ 3177 4550 { 3178 4551 "type": "GitHub Sponsors", ··· 3193 4566 }, 3194 4567 "node_modules/micromark-util-encode": { 3195 4568 "version": "2.0.1", 4569 + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", 4570 + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", 3196 4571 "funding": [ 3197 4572 { 3198 4573 "type": "GitHub Sponsors", ··· 3207 4582 }, 3208 4583 "node_modules/micromark-util-html-tag-name": { 3209 4584 "version": "2.0.1", 4585 + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", 4586 + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", 3210 4587 "funding": [ 3211 4588 { 3212 4589 "type": "GitHub Sponsors", ··· 3221 4598 }, 3222 4599 "node_modules/micromark-util-normalize-identifier": { 3223 4600 "version": "2.0.1", 4601 + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", 4602 + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", 3224 4603 "funding": [ 3225 4604 { 3226 4605 "type": "GitHub Sponsors", ··· 3238 4617 }, 3239 4618 "node_modules/micromark-util-resolve-all": { 3240 4619 "version": "2.0.1", 4620 + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", 4621 + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", 3241 4622 "funding": [ 3242 4623 { 3243 4624 "type": "GitHub Sponsors", ··· 3255 4636 }, 3256 4637 "node_modules/micromark-util-sanitize-uri": { 3257 4638 "version": "2.0.1", 4639 + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", 4640 + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", 3258 4641 "funding": [ 3259 4642 { 3260 4643 "type": "GitHub Sponsors", ··· 3273 4656 } 3274 4657 }, 3275 4658 "node_modules/micromark-util-subtokenize": { 3276 - "version": "2.0.3", 4659 + "version": "2.1.0", 4660 + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", 4661 + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", 3277 4662 "funding": [ 3278 4663 { 3279 4664 "type": "GitHub Sponsors", ··· 3294 4679 }, 3295 4680 "node_modules/micromark-util-symbol": { 3296 4681 "version": "2.0.1", 4682 + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", 4683 + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", 3297 4684 "funding": [ 3298 4685 { 3299 4686 "type": "GitHub Sponsors", ··· 3307 4694 "license": "MIT" 3308 4695 }, 3309 4696 "node_modules/micromark-util-types": { 3310 - "version": "2.0.1", 4697 + "version": "2.0.2", 4698 + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", 4699 + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", 3311 4700 "funding": [ 3312 4701 { 3313 4702 "type": "GitHub Sponsors", ··· 3322 4711 }, 3323 4712 "node_modules/micromatch": { 3324 4713 "version": "4.0.8", 4714 + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 4715 + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 3325 4716 "dev": true, 3326 4717 "license": "MIT", 3327 4718 "dependencies": { ··· 3334 4725 }, 3335 4726 "node_modules/micromatch/node_modules/picomatch": { 3336 4727 "version": "2.3.1", 4728 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 4729 + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 3337 4730 "dev": true, 3338 4731 "license": "MIT", 3339 4732 "engines": { ··· 3345 4738 }, 3346 4739 "node_modules/mini-svg-data-uri": { 3347 4740 "version": "1.4.4", 4741 + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", 4742 + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", 3348 4743 "dev": true, 3349 4744 "license": "MIT", 3350 4745 "bin": { ··· 3353 4748 }, 3354 4749 "node_modules/minimatch": { 3355 4750 "version": "3.1.2", 4751 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 4752 + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 3356 4753 "dev": true, 3357 4754 "license": "ISC", 3358 4755 "dependencies": { ··· 3364 4761 }, 3365 4762 "node_modules/minipass": { 3366 4763 "version": "7.1.2", 4764 + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 4765 + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 3367 4766 "dev": true, 3368 4767 "license": "ISC", 3369 4768 "engines": { ··· 3372 4771 }, 3373 4772 "node_modules/minizlib": { 3374 4773 "version": "3.0.2", 4774 + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", 4775 + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", 3375 4776 "dev": true, 3376 4777 "license": "MIT", 3377 4778 "dependencies": { ··· 3383 4784 }, 3384 4785 "node_modules/mkdirp": { 3385 4786 "version": "3.0.1", 4787 + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", 4788 + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", 3386 4789 "dev": true, 3387 4790 "license": "MIT", 3388 4791 "bin": { ··· 3397 4800 }, 3398 4801 "node_modules/mri": { 3399 4802 "version": "1.2.0", 4803 + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", 4804 + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", 3400 4805 "dev": true, 3401 4806 "license": "MIT", 3402 4807 "engines": { ··· 3404 4809 } 3405 4810 }, 3406 4811 "node_modules/mrmime": { 3407 - "version": "2.0.0", 4812 + "version": "2.0.1", 4813 + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", 4814 + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", 3408 4815 "dev": true, 3409 4816 "license": "MIT", 3410 4817 "engines": { ··· 3413 4820 }, 3414 4821 "node_modules/ms": { 3415 4822 "version": "2.1.3", 4823 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 4824 + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 3416 4825 "license": "MIT" 3417 4826 }, 3418 4827 "node_modules/mz": { 3419 4828 "version": "2.7.0", 4829 + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", 4830 + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", 3420 4831 "dev": true, 3421 4832 "license": "MIT", 3422 4833 "dependencies": { ··· 3427 4838 }, 3428 4839 "node_modules/nanoid": { 3429 4840 "version": "3.3.11", 4841 + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", 4842 + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", 3430 4843 "funding": [ 3431 4844 { 3432 4845 "type": "github", ··· 3443 4856 }, 3444 4857 "node_modules/natural-compare": { 3445 4858 "version": "1.4.0", 4859 + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 4860 + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 3446 4861 "dev": true, 3447 4862 "license": "MIT" 3448 4863 }, 3449 4864 "node_modules/node-fetch": { 3450 4865 "version": "2.7.0", 4866 + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 4867 + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 3451 4868 "dev": true, 3452 4869 "license": "MIT", 3453 4870 "dependencies": { ··· 3467 4884 }, 3468 4885 "node_modules/node-gyp-build": { 3469 4886 "version": "4.8.4", 4887 + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", 4888 + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", 3470 4889 "dev": true, 3471 4890 "license": "MIT", 3472 4891 "bin": { ··· 3477 4896 }, 3478 4897 "node_modules/node-releases": { 3479 4898 "version": "2.0.19", 4899 + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", 4900 + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", 3480 4901 "dev": true, 3481 4902 "license": "MIT" 3482 4903 }, 3483 4904 "node_modules/nopt": { 3484 4905 "version": "8.1.0", 4906 + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", 4907 + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", 3485 4908 "dev": true, 3486 4909 "license": "ISC", 3487 4910 "dependencies": { ··· 3496 4919 }, 3497 4920 "node_modules/normalize-path": { 3498 4921 "version": "3.0.0", 4922 + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 4923 + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 3499 4924 "dev": true, 3500 4925 "license": "MIT", 3501 4926 "engines": { ··· 3504 4929 }, 3505 4930 "node_modules/normalize-range": { 3506 4931 "version": "0.1.2", 4932 + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", 4933 + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", 3507 4934 "dev": true, 3508 4935 "license": "MIT", 3509 4936 "engines": { ··· 3512 4939 }, 3513 4940 "node_modules/object-assign": { 3514 4941 "version": "4.1.1", 4942 + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 4943 + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 3515 4944 "dev": true, 3516 4945 "license": "MIT", 3517 4946 "engines": { ··· 3520 4949 }, 3521 4950 "node_modules/object-hash": { 3522 4951 "version": "3.0.0", 4952 + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", 4953 + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", 3523 4954 "dev": true, 3524 4955 "license": "MIT", 3525 4956 "engines": { ··· 3528 4959 }, 3529 4960 "node_modules/optionator": { 3530 4961 "version": "0.9.4", 4962 + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 4963 + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 3531 4964 "dev": true, 3532 4965 "license": "MIT", 3533 4966 "dependencies": { ··· 3544 4977 }, 3545 4978 "node_modules/p-limit": { 3546 4979 "version": "3.1.0", 4980 + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 4981 + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 3547 4982 "dev": true, 3548 4983 "license": "MIT", 3549 4984 "dependencies": { ··· 3558 4993 }, 3559 4994 "node_modules/p-locate": { 3560 4995 "version": "5.0.0", 4996 + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 4997 + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 3561 4998 "dev": true, 3562 4999 "license": "MIT", 3563 5000 "dependencies": { ··· 3572 5009 }, 3573 5010 "node_modules/package-json-from-dist": { 3574 5011 "version": "1.0.1", 5012 + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", 5013 + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", 3575 5014 "dev": true, 3576 5015 "license": "BlueOak-1.0.0" 3577 5016 }, 3578 5017 "node_modules/pako": { 3579 5018 "version": "0.2.9", 5019 + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", 5020 + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", 3580 5021 "license": "MIT" 3581 5022 }, 3582 5023 "node_modules/parent-module": { 3583 5024 "version": "1.0.1", 5025 + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 5026 + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 3584 5027 "dev": true, 3585 5028 "license": "MIT", 3586 5029 "dependencies": { ··· 3592 5035 }, 3593 5036 "node_modules/parse-css-color": { 3594 5037 "version": "0.2.1", 5038 + "resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz", 5039 + "integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==", 3595 5040 "license": "MIT", 3596 5041 "dependencies": { 3597 5042 "color-name": "^1.1.4", ··· 3600 5045 }, 3601 5046 "node_modules/parse-srcset": { 3602 5047 "version": "1.0.2", 5048 + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", 5049 + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", 3603 5050 "license": "MIT" 3604 5051 }, 3605 5052 "node_modules/parse5": { 3606 - "version": "7.2.1", 5053 + "version": "7.3.0", 5054 + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", 5055 + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", 3607 5056 "license": "MIT", 3608 5057 "dependencies": { 3609 - "entities": "^4.5.0" 5058 + "entities": "^6.0.0" 3610 5059 }, 3611 5060 "funding": { 3612 5061 "url": "https://github.com/inikulin/parse5?sponsor=1" 3613 5062 } 3614 5063 }, 5064 + "node_modules/parse5/node_modules/entities": { 5065 + "version": "6.0.1", 5066 + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", 5067 + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", 5068 + "license": "BSD-2-Clause", 5069 + "engines": { 5070 + "node": ">=0.12" 5071 + }, 5072 + "funding": { 5073 + "url": "https://github.com/fb55/entities?sponsor=1" 5074 + } 5075 + }, 3615 5076 "node_modules/path-exists": { 3616 5077 "version": "4.0.0", 5078 + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 5079 + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 3617 5080 "dev": true, 3618 5081 "license": "MIT", 3619 5082 "engines": { ··· 3622 5085 }, 3623 5086 "node_modules/path-key": { 3624 5087 "version": "3.1.1", 5088 + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 5089 + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 3625 5090 "dev": true, 3626 5091 "license": "MIT", 3627 5092 "engines": { ··· 3630 5095 }, 3631 5096 "node_modules/path-parse": { 3632 5097 "version": "1.0.7", 5098 + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 5099 + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 3633 5100 "license": "MIT" 3634 5101 }, 3635 5102 "node_modules/path-scurry": { 3636 5103 "version": "1.11.1", 5104 + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 5105 + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 3637 5106 "dev": true, 3638 5107 "license": "BlueOak-1.0.0", 3639 5108 "dependencies": { ··· 3649 5118 }, 3650 5119 "node_modules/picocolors": { 3651 5120 "version": "1.1.1", 5121 + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 5122 + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 3652 5123 "license": "ISC" 3653 5124 }, 3654 5125 "node_modules/picomatch": { 3655 - "version": "4.0.2", 5126 + "version": "4.0.3", 5127 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", 5128 + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", 3656 5129 "dev": true, 3657 5130 "license": "MIT", 3658 5131 "engines": { ··· 3664 5137 }, 3665 5138 "node_modules/pify": { 3666 5139 "version": "2.3.0", 5140 + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 5141 + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", 3667 5142 "license": "MIT", 3668 5143 "engines": { 3669 5144 "node": ">=0.10.0" 3670 5145 } 3671 5146 }, 3672 5147 "node_modules/pirates": { 3673 - "version": "4.0.6", 5148 + "version": "4.0.7", 5149 + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", 5150 + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", 3674 5151 "dev": true, 3675 5152 "license": "MIT", 3676 5153 "engines": { ··· 3679 5156 }, 3680 5157 "node_modules/postcss": { 3681 5158 "version": "8.5.6", 5159 + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", 5160 + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", 3682 5161 "funding": [ 3683 5162 { 3684 5163 "type": "opencollective", ··· 3705 5184 }, 3706 5185 "node_modules/postcss-import": { 3707 5186 "version": "16.1.1", 5187 + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-16.1.1.tgz", 5188 + "integrity": "sha512-2xVS1NCZAfjtVdvXiyegxzJ447GyqCeEI5V7ApgQVOWnros1p5lGNovJNapwPpMombyFBfqDwt7AD3n2l0KOfQ==", 3708 5189 "license": "MIT", 3709 5190 "dependencies": { 3710 5191 "postcss-value-parser": "^4.0.0", ··· 3720 5201 }, 3721 5202 "node_modules/postcss-js": { 3722 5203 "version": "4.0.1", 5204 + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", 5205 + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", 3723 5206 "dev": true, 3724 5207 "license": "MIT", 3725 5208 "dependencies": { ··· 3738 5221 }, 3739 5222 "node_modules/postcss-load-config": { 3740 5223 "version": "3.1.4", 5224 + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", 5225 + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", 3741 5226 "dev": true, 3742 5227 "license": "MIT", 3743 5228 "dependencies": { ··· 3765 5250 } 3766 5251 }, 3767 5252 "node_modules/postcss-nested": { 3768 - "version": "6.2.0", 3769 - "dev": true, 3770 - "funding": [ 3771 - { 3772 - "type": "opencollective", 3773 - "url": "https://opencollective.com/postcss/" 3774 - }, 3775 - { 3776 - "type": "github", 3777 - "url": "https://github.com/sponsors/ai" 3778 - } 3779 - ], 5253 + "version": "5.0.6", 5254 + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", 5255 + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", 3780 5256 "license": "MIT", 3781 5257 "dependencies": { 3782 - "postcss-selector-parser": "^6.1.1" 5258 + "postcss-selector-parser": "^6.0.6" 3783 5259 }, 3784 5260 "engines": { 3785 5261 "node": ">=12.0" 3786 5262 }, 5263 + "funding": { 5264 + "type": "opencollective", 5265 + "url": "https://opencollective.com/postcss/" 5266 + }, 3787 5267 "peerDependencies": { 3788 5268 "postcss": "^8.2.14" 3789 5269 } 3790 5270 }, 3791 5271 "node_modules/postcss-safe-parser": { 3792 5272 "version": "6.0.0", 5273 + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", 5274 + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", 3793 5275 "dev": true, 3794 5276 "license": "MIT", 3795 5277 "engines": { ··· 3805 5287 }, 3806 5288 "node_modules/postcss-scss": { 3807 5289 "version": "4.0.9", 5290 + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", 5291 + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", 3808 5292 "dev": true, 3809 5293 "funding": [ 3810 5294 { ··· 3829 5313 } 3830 5314 }, 3831 5315 "node_modules/postcss-selector-parser": { 3832 - "version": "6.1.2", 5316 + "version": "6.0.10", 5317 + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", 5318 + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", 3833 5319 "license": "MIT", 3834 5320 "dependencies": { 3835 5321 "cssesc": "^3.0.0", ··· 3841 5327 }, 3842 5328 "node_modules/postcss-value-parser": { 3843 5329 "version": "4.2.0", 5330 + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", 5331 + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", 3844 5332 "license": "MIT" 3845 5333 }, 3846 5334 "node_modules/prelude-ls": { 3847 5335 "version": "1.2.1", 5336 + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 5337 + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 3848 5338 "dev": true, 3849 5339 "license": "MIT", 3850 5340 "engines": { ··· 3852 5342 } 3853 5343 }, 3854 5344 "node_modules/property-information": { 3855 - "version": "6.5.0", 5345 + "version": "7.1.0", 5346 + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", 5347 + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", 3856 5348 "license": "MIT", 3857 5349 "funding": { 3858 5350 "type": "github", ··· 3861 5353 }, 3862 5354 "node_modules/punycode": { 3863 5355 "version": "2.3.1", 5356 + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 5357 + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 3864 5358 "dev": true, 3865 5359 "license": "MIT", 3866 5360 "engines": { ··· 3869 5363 }, 3870 5364 "node_modules/queue-microtask": { 3871 5365 "version": "1.2.3", 5366 + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 5367 + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 3872 5368 "dev": true, 3873 5369 "funding": [ 3874 5370 { ··· 3888 5384 }, 3889 5385 "node_modules/read-cache": { 3890 5386 "version": "1.0.0", 5387 + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", 5388 + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", 3891 5389 "license": "MIT", 3892 5390 "dependencies": { 3893 5391 "pify": "^2.3.0" 3894 5392 } 3895 5393 }, 3896 5394 "node_modules/readdirp": { 3897 - "version": "4.0.2", 5395 + "version": "4.1.2", 5396 + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", 5397 + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", 3898 5398 "dev": true, 3899 5399 "license": "MIT", 3900 5400 "engines": { 3901 - "node": ">= 14.16.0" 5401 + "node": ">= 14.18.0" 3902 5402 }, 3903 5403 "funding": { 3904 5404 "type": "individual", ··· 3907 5407 }, 3908 5408 "node_modules/rehype-raw": { 3909 5409 "version": "7.0.0", 5410 + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", 5411 + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", 3910 5412 "license": "MIT", 3911 5413 "dependencies": { 3912 5414 "@types/hast": "^3.0.0", ··· 3920 5422 }, 3921 5423 "node_modules/rehype-sanitize": { 3922 5424 "version": "6.0.0", 5425 + "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", 5426 + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", 3923 5427 "license": "MIT", 3924 5428 "dependencies": { 3925 5429 "@types/hast": "^3.0.0", ··· 3932 5436 }, 3933 5437 "node_modules/rehype-stringify": { 3934 5438 "version": "10.0.1", 5439 + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", 5440 + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", 3935 5441 "license": "MIT", 3936 5442 "dependencies": { 3937 5443 "@types/hast": "^3.0.0", ··· 3945 5451 }, 3946 5452 "node_modules/remark": { 3947 5453 "version": "15.0.1", 5454 + "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", 5455 + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", 3948 5456 "license": "MIT", 3949 5457 "dependencies": { 3950 5458 "@types/mdast": "^4.0.0", ··· 3958 5466 } 3959 5467 }, 3960 5468 "node_modules/remark-gfm": { 3961 - "version": "4.0.0", 5469 + "version": "4.0.1", 5470 + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", 5471 + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", 3962 5472 "license": "MIT", 3963 5473 "dependencies": { 3964 5474 "@types/mdast": "^4.0.0", ··· 3975 5485 }, 3976 5486 "node_modules/remark-parse": { 3977 5487 "version": "11.0.0", 5488 + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", 5489 + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", 3978 5490 "license": "MIT", 3979 5491 "dependencies": { 3980 5492 "@types/mdast": "^4.0.0", ··· 3988 5500 } 3989 5501 }, 3990 5502 "node_modules/remark-rehype": { 3991 - "version": "11.1.1", 5503 + "version": "11.1.2", 5504 + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", 5505 + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", 3992 5506 "license": "MIT", 3993 5507 "dependencies": { 3994 5508 "@types/hast": "^3.0.0", ··· 4004 5518 }, 4005 5519 "node_modules/remark-stringify": { 4006 5520 "version": "11.0.0", 5521 + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", 5522 + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", 4007 5523 "license": "MIT", 4008 5524 "dependencies": { 4009 5525 "@types/mdast": "^4.0.0", ··· 4016 5532 } 4017 5533 }, 4018 5534 "node_modules/resolve": { 4019 - "version": "1.22.8", 5535 + "version": "1.22.10", 5536 + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", 5537 + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", 4020 5538 "license": "MIT", 4021 5539 "dependencies": { 4022 - "is-core-module": "^2.13.0", 5540 + "is-core-module": "^2.16.0", 4023 5541 "path-parse": "^1.0.7", 4024 5542 "supports-preserve-symlinks-flag": "^1.0.0" 4025 5543 }, 4026 5544 "bin": { 4027 5545 "resolve": "bin/resolve" 4028 5546 }, 5547 + "engines": { 5548 + "node": ">= 0.4" 5549 + }, 4029 5550 "funding": { 4030 5551 "url": "https://github.com/sponsors/ljharb" 4031 5552 } 4032 5553 }, 4033 5554 "node_modules/resolve-from": { 4034 - "version": "4.0.0", 5555 + "version": "5.0.0", 5556 + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 5557 + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 4035 5558 "dev": true, 4036 5559 "license": "MIT", 4037 5560 "engines": { 4038 - "node": ">=4" 5561 + "node": ">=8" 4039 5562 } 4040 5563 }, 4041 5564 "node_modules/reusify": { 4042 - "version": "1.0.4", 5565 + "version": "1.1.0", 5566 + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", 5567 + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", 4043 5568 "dev": true, 4044 5569 "license": "MIT", 4045 5570 "engines": { ··· 4048 5573 } 4049 5574 }, 4050 5575 "node_modules/rollup": { 4051 - "version": "4.28.0", 5576 + "version": "4.46.1", 5577 + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.1.tgz", 5578 + "integrity": "sha512-33xGNBsDJAkzt0PvninskHlWnTIPgDtTwhg0U38CUoNP/7H6wI2Cz6dUeoNPbjdTdsYTGuiFFASuUOWovH0SyQ==", 4052 5579 "dev": true, 4053 5580 "license": "MIT", 4054 5581 "dependencies": { 4055 - "@types/estree": "1.0.6" 5582 + "@types/estree": "1.0.8" 4056 5583 }, 4057 5584 "bin": { 4058 5585 "rollup": "dist/bin/rollup" ··· 4062 5589 "npm": ">=8.0.0" 4063 5590 }, 4064 5591 "optionalDependencies": { 4065 - "@rollup/rollup-android-arm-eabi": "4.28.0", 4066 - "@rollup/rollup-android-arm64": "4.28.0", 4067 - "@rollup/rollup-darwin-arm64": "4.28.0", 4068 - "@rollup/rollup-darwin-x64": "4.28.0", 4069 - "@rollup/rollup-freebsd-arm64": "4.28.0", 4070 - "@rollup/rollup-freebsd-x64": "4.28.0", 4071 - "@rollup/rollup-linux-arm-gnueabihf": "4.28.0", 4072 - "@rollup/rollup-linux-arm-musleabihf": "4.28.0", 4073 - "@rollup/rollup-linux-arm64-gnu": "4.28.0", 4074 - "@rollup/rollup-linux-arm64-musl": "4.28.0", 4075 - "@rollup/rollup-linux-powerpc64le-gnu": "4.28.0", 4076 - "@rollup/rollup-linux-riscv64-gnu": "4.28.0", 4077 - "@rollup/rollup-linux-s390x-gnu": "4.28.0", 4078 - "@rollup/rollup-linux-x64-gnu": "4.28.0", 4079 - "@rollup/rollup-linux-x64-musl": "4.28.0", 4080 - "@rollup/rollup-win32-arm64-msvc": "4.28.0", 4081 - "@rollup/rollup-win32-ia32-msvc": "4.28.0", 4082 - "@rollup/rollup-win32-x64-msvc": "4.28.0", 5592 + "@rollup/rollup-android-arm-eabi": "4.46.1", 5593 + "@rollup/rollup-android-arm64": "4.46.1", 5594 + "@rollup/rollup-darwin-arm64": "4.46.1", 5595 + "@rollup/rollup-darwin-x64": "4.46.1", 5596 + "@rollup/rollup-freebsd-arm64": "4.46.1", 5597 + "@rollup/rollup-freebsd-x64": "4.46.1", 5598 + "@rollup/rollup-linux-arm-gnueabihf": "4.46.1", 5599 + "@rollup/rollup-linux-arm-musleabihf": "4.46.1", 5600 + "@rollup/rollup-linux-arm64-gnu": "4.46.1", 5601 + "@rollup/rollup-linux-arm64-musl": "4.46.1", 5602 + "@rollup/rollup-linux-loongarch64-gnu": "4.46.1", 5603 + "@rollup/rollup-linux-ppc64-gnu": "4.46.1", 5604 + "@rollup/rollup-linux-riscv64-gnu": "4.46.1", 5605 + "@rollup/rollup-linux-riscv64-musl": "4.46.1", 5606 + "@rollup/rollup-linux-s390x-gnu": "4.46.1", 5607 + "@rollup/rollup-linux-x64-gnu": "4.46.1", 5608 + "@rollup/rollup-linux-x64-musl": "4.46.1", 5609 + "@rollup/rollup-win32-arm64-msvc": "4.46.1", 5610 + "@rollup/rollup-win32-ia32-msvc": "4.46.1", 5611 + "@rollup/rollup-win32-x64-msvc": "4.46.1", 4083 5612 "fsevents": "~2.3.2" 4084 5613 } 4085 5614 }, 4086 5615 "node_modules/run-parallel": { 4087 5616 "version": "1.2.0", 5617 + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 5618 + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 4088 5619 "dev": true, 4089 5620 "funding": [ 4090 5621 { ··· 4107 5638 }, 4108 5639 "node_modules/sade": { 4109 5640 "version": "1.8.1", 5641 + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", 5642 + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", 4110 5643 "dev": true, 4111 5644 "license": "MIT", 4112 5645 "dependencies": { ··· 4117 5650 } 4118 5651 }, 4119 5652 "node_modules/sanitize-html": { 4120 - "version": "2.13.1", 5653 + "version": "2.17.0", 5654 + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.0.tgz", 5655 + "integrity": "sha512-dLAADUSS8rBwhaevT12yCezvioCA+bmUTPH/u57xKPT8d++voeYE6HeluA/bPbQ15TwDBG2ii+QZIEmYx8VdxA==", 4121 5656 "license": "MIT", 4122 5657 "dependencies": { 4123 5658 "deepmerge": "^4.2.2", ··· 4130 5665 }, 4131 5666 "node_modules/satori": { 4132 5667 "version": "0.12.2", 5668 + "resolved": "https://registry.npmjs.org/satori/-/satori-0.12.2.tgz", 5669 + "integrity": "sha512-3C/laIeE6UUe9A+iQ0A48ywPVCCMKCNSTU5Os101Vhgsjd3AAxGNjyq0uAA8kulMPK5n0csn8JlxPN9riXEjLA==", 4133 5670 "license": "MPL-2.0", 4134 5671 "dependencies": { 4135 5672 "@shuding/opentype.js": "1.4.0-beta.0", ··· 4148 5685 "node": ">=16" 4149 5686 } 4150 5687 }, 4151 - "node_modules/satori/node_modules/emoji-regex": { 4152 - "version": "10.4.0", 4153 - "license": "MIT" 4154 - }, 4155 5688 "node_modules/semver": { 4156 - "version": "7.6.3", 5689 + "version": "7.7.2", 5690 + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 5691 + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 4157 5692 "dev": true, 4158 5693 "license": "ISC", 4159 5694 "bin": { ··· 4165 5700 }, 4166 5701 "node_modules/set-cookie-parser": { 4167 5702 "version": "2.7.1", 5703 + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", 5704 + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", 4168 5705 "dev": true, 4169 5706 "license": "MIT" 4170 5707 }, 4171 5708 "node_modules/shebang-command": { 4172 5709 "version": "2.0.0", 5710 + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 5711 + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 4173 5712 "dev": true, 4174 5713 "license": "MIT", 4175 5714 "dependencies": { ··· 4181 5720 }, 4182 5721 "node_modules/shebang-regex": { 4183 5722 "version": "3.0.0", 5723 + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 5724 + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 4184 5725 "dev": true, 4185 5726 "license": "MIT", 4186 5727 "engines": { ··· 4189 5730 }, 4190 5731 "node_modules/signal-exit": { 4191 5732 "version": "4.1.0", 5733 + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 5734 + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 4192 5735 "dev": true, 4193 5736 "license": "ISC", 4194 5737 "engines": { ··· 4199 5742 } 4200 5743 }, 4201 5744 "node_modules/sirv": { 4202 - "version": "3.0.0", 5745 + "version": "3.0.1", 5746 + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz", 5747 + "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==", 4203 5748 "dev": true, 4204 5749 "license": "MIT", 4205 5750 "dependencies": { ··· 4213 5758 }, 4214 5759 "node_modules/source-map-js": { 4215 5760 "version": "1.2.1", 5761 + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 5762 + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 4216 5763 "license": "BSD-3-Clause", 4217 5764 "engines": { 4218 5765 "node": ">=0.10.0" ··· 4220 5767 }, 4221 5768 "node_modules/space-separated-tokens": { 4222 5769 "version": "2.0.2", 5770 + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", 5771 + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", 4223 5772 "license": "MIT", 4224 5773 "funding": { 4225 5774 "type": "github", ··· 4228 5777 }, 4229 5778 "node_modules/string-width": { 4230 5779 "version": "5.1.2", 5780 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 5781 + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 4231 5782 "dev": true, 4232 5783 "license": "MIT", 4233 5784 "dependencies": { ··· 4245 5796 "node_modules/string-width-cjs": { 4246 5797 "name": "string-width", 4247 5798 "version": "4.2.3", 5799 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 5800 + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 4248 5801 "dev": true, 4249 5802 "license": "MIT", 4250 5803 "dependencies": { ··· 4258 5811 }, 4259 5812 "node_modules/string-width-cjs/node_modules/ansi-regex": { 4260 5813 "version": "5.0.1", 5814 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 5815 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 4261 5816 "dev": true, 4262 5817 "license": "MIT", 4263 5818 "engines": { ··· 4266 5821 }, 4267 5822 "node_modules/string-width-cjs/node_modules/emoji-regex": { 4268 5823 "version": "8.0.0", 5824 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 5825 + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 4269 5826 "dev": true, 4270 5827 "license": "MIT" 4271 5828 }, 4272 5829 "node_modules/string-width-cjs/node_modules/strip-ansi": { 4273 5830 "version": "6.0.1", 5831 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 5832 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 4274 5833 "dev": true, 4275 5834 "license": "MIT", 4276 5835 "dependencies": { ··· 4280 5839 "node": ">=8" 4281 5840 } 4282 5841 }, 5842 + "node_modules/string-width/node_modules/emoji-regex": { 5843 + "version": "9.2.2", 5844 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 5845 + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 5846 + "dev": true, 5847 + "license": "MIT" 5848 + }, 4283 5849 "node_modules/string.prototype.codepointat": { 4284 5850 "version": "0.2.1", 5851 + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", 5852 + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==", 4285 5853 "license": "MIT" 4286 5854 }, 4287 5855 "node_modules/stringify-entities": { 4288 5856 "version": "4.0.4", 5857 + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", 5858 + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", 4289 5859 "license": "MIT", 4290 5860 "dependencies": { 4291 5861 "character-entities-html4": "^2.0.0", ··· 4298 5868 }, 4299 5869 "node_modules/strip-ansi": { 4300 5870 "version": "7.1.0", 5871 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 5872 + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 4301 5873 "dev": true, 4302 5874 "license": "MIT", 4303 5875 "dependencies": { ··· 4313 5885 "node_modules/strip-ansi-cjs": { 4314 5886 "name": "strip-ansi", 4315 5887 "version": "6.0.1", 5888 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 5889 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 4316 5890 "dev": true, 4317 5891 "license": "MIT", 4318 5892 "dependencies": { ··· 4324 5898 }, 4325 5899 "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 4326 5900 "version": "5.0.1", 5901 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 5902 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 4327 5903 "dev": true, 4328 5904 "license": "MIT", 4329 5905 "engines": { ··· 4332 5908 }, 4333 5909 "node_modules/strip-json-comments": { 4334 5910 "version": "3.1.1", 5911 + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 5912 + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 4335 5913 "dev": true, 4336 5914 "license": "MIT", 4337 5915 "engines": { ··· 4343 5921 }, 4344 5922 "node_modules/sucrase": { 4345 5923 "version": "3.35.0", 5924 + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", 5925 + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", 4346 5926 "dev": true, 4347 5927 "license": "MIT", 4348 5928 "dependencies": { ··· 4364 5944 }, 4365 5945 "node_modules/supports-color": { 4366 5946 "version": "7.2.0", 5947 + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 5948 + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 4367 5949 "dev": true, 4368 5950 "license": "MIT", 4369 5951 "dependencies": { ··· 4375 5957 }, 4376 5958 "node_modules/supports-preserve-symlinks-flag": { 4377 5959 "version": "1.0.0", 5960 + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 5961 + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 4378 5962 "license": "MIT", 4379 5963 "engines": { 4380 5964 "node": ">= 0.4" ··· 4384 5968 } 4385 5969 }, 4386 5970 "node_modules/svelte": { 4387 - "version": "5.36.2", 5971 + "version": "5.37.1", 5972 + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.37.1.tgz", 5973 + "integrity": "sha512-h8arWpQZ+3z8eahyBT5KkiBOUsG6xvI5Ykg0ozRr9xEdImgSMUPUlOFWRNkUsT7Ti0DSUCTEbPoped0aoxFyWA==", 4388 5974 "dev": true, 4389 5975 "license": "MIT", 4390 5976 "dependencies": { ··· 4408 5994 } 4409 5995 }, 4410 5996 "node_modules/svelte-check": { 4411 - "version": "4.2.2", 5997 + "version": "4.3.0", 5998 + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.0.tgz", 5999 + "integrity": "sha512-Iz8dFXzBNAM7XlEIsUjUGQhbEE+Pvv9odb9+0+ITTgFWZBGeJRRYqHUUglwe2EkLD5LIsQaAc4IUJyvtKuOO5w==", 4412 6000 "dev": true, 4413 6001 "license": "MIT", 4414 6002 "dependencies": { ··· 4431 6019 }, 4432 6020 "node_modules/svelte-eslint-parser": { 4433 6021 "version": "0.43.0", 6022 + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz", 6023 + "integrity": "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==", 4434 6024 "dev": true, 4435 6025 "license": "MIT", 4436 6026 "dependencies": { ··· 4457 6047 }, 4458 6048 "node_modules/svelte-eslint-parser/node_modules/eslint-scope": { 4459 6049 "version": "7.2.2", 6050 + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", 6051 + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", 4460 6052 "dev": true, 4461 6053 "license": "BSD-2-Clause", 4462 6054 "dependencies": { ··· 4472 6064 }, 4473 6065 "node_modules/svelte-eslint-parser/node_modules/eslint-visitor-keys": { 4474 6066 "version": "3.4.3", 6067 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 6068 + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 4475 6069 "dev": true, 4476 6070 "license": "Apache-2.0", 4477 6071 "engines": { ··· 4483 6077 }, 4484 6078 "node_modules/svelte-eslint-parser/node_modules/espree": { 4485 6079 "version": "9.6.1", 6080 + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", 6081 + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", 4486 6082 "dev": true, 4487 6083 "license": "BSD-2-Clause", 4488 6084 "dependencies": { ··· 4499 6095 }, 4500 6096 "node_modules/tailwindcss": { 4501 6097 "version": "3.4.17", 6098 + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", 6099 + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", 4502 6100 "dev": true, 4503 6101 "license": "MIT", 4504 6102 "dependencies": { ··· 4535 6133 }, 4536 6134 "node_modules/tailwindcss/node_modules/chokidar": { 4537 6135 "version": "3.6.0", 6136 + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 6137 + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 4538 6138 "dev": true, 4539 6139 "license": "MIT", 4540 6140 "dependencies": { ··· 4558 6158 }, 4559 6159 "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { 4560 6160 "version": "5.1.2", 6161 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 6162 + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 4561 6163 "dev": true, 4562 6164 "license": "ISC", 4563 6165 "dependencies": { ··· 4569 6171 }, 4570 6172 "node_modules/tailwindcss/node_modules/lilconfig": { 4571 6173 "version": "3.1.3", 6174 + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", 6175 + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", 4572 6176 "dev": true, 4573 6177 "license": "MIT", 4574 6178 "engines": { ··· 4580 6184 }, 4581 6185 "node_modules/tailwindcss/node_modules/picomatch": { 4582 6186 "version": "2.3.1", 6187 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 6188 + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 4583 6189 "dev": true, 4584 6190 "license": "MIT", 4585 6191 "engines": { ··· 4591 6197 }, 4592 6198 "node_modules/tailwindcss/node_modules/postcss-import": { 4593 6199 "version": "15.1.0", 6200 + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", 6201 + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", 4594 6202 "dev": true, 4595 6203 "license": "MIT", 4596 6204 "dependencies": { ··· 4607 6215 }, 4608 6216 "node_modules/tailwindcss/node_modules/postcss-load-config": { 4609 6217 "version": "4.0.2", 6218 + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", 6219 + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", 4610 6220 "dev": true, 4611 6221 "funding": [ 4612 6222 { ··· 4639 6249 } 4640 6250 } 4641 6251 }, 6252 + "node_modules/tailwindcss/node_modules/postcss-nested": { 6253 + "version": "6.2.0", 6254 + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", 6255 + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", 6256 + "dev": true, 6257 + "funding": [ 6258 + { 6259 + "type": "opencollective", 6260 + "url": "https://opencollective.com/postcss/" 6261 + }, 6262 + { 6263 + "type": "github", 6264 + "url": "https://github.com/sponsors/ai" 6265 + } 6266 + ], 6267 + "license": "MIT", 6268 + "dependencies": { 6269 + "postcss-selector-parser": "^6.1.1" 6270 + }, 6271 + "engines": { 6272 + "node": ">=12.0" 6273 + }, 6274 + "peerDependencies": { 6275 + "postcss": "^8.2.14" 6276 + } 6277 + }, 6278 + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { 6279 + "version": "6.1.2", 6280 + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", 6281 + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", 6282 + "dev": true, 6283 + "license": "MIT", 6284 + "dependencies": { 6285 + "cssesc": "^3.0.0", 6286 + "util-deprecate": "^1.0.2" 6287 + }, 6288 + "engines": { 6289 + "node": ">=4" 6290 + } 6291 + }, 4642 6292 "node_modules/tailwindcss/node_modules/readdirp": { 4643 6293 "version": "3.6.0", 6294 + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 6295 + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 4644 6296 "dev": true, 4645 6297 "license": "MIT", 4646 6298 "dependencies": { ··· 4651 6303 } 4652 6304 }, 4653 6305 "node_modules/tailwindcss/node_modules/yaml": { 4654 - "version": "2.6.1", 6306 + "version": "2.8.0", 6307 + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", 6308 + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", 4655 6309 "dev": true, 4656 6310 "license": "ISC", 4657 6311 "bin": { 4658 6312 "yaml": "bin.mjs" 4659 6313 }, 4660 6314 "engines": { 4661 - "node": ">= 14" 6315 + "node": ">= 14.6" 4662 6316 } 4663 6317 }, 4664 6318 "node_modules/tar": { 4665 6319 "version": "7.4.3", 6320 + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", 6321 + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", 4666 6322 "dev": true, 4667 6323 "license": "ISC", 4668 6324 "dependencies": { ··· 4679 6335 }, 4680 6336 "node_modules/thenify": { 4681 6337 "version": "3.3.1", 6338 + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", 6339 + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", 4682 6340 "dev": true, 4683 6341 "license": "MIT", 4684 6342 "dependencies": { ··· 4687 6345 }, 4688 6346 "node_modules/thenify-all": { 4689 6347 "version": "1.6.0", 6348 + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", 6349 + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", 4690 6350 "dev": true, 4691 6351 "license": "MIT", 4692 6352 "dependencies": { ··· 4698 6358 }, 4699 6359 "node_modules/tiny-inflate": { 4700 6360 "version": "1.0.3", 6361 + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", 6362 + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", 4701 6363 "license": "MIT" 4702 6364 }, 4703 6365 "node_modules/to-regex-range": { 4704 6366 "version": "5.0.1", 6367 + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 6368 + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 4705 6369 "dev": true, 4706 6370 "license": "MIT", 4707 6371 "dependencies": { ··· 4713 6377 }, 4714 6378 "node_modules/totalist": { 4715 6379 "version": "3.0.1", 6380 + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", 6381 + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", 4716 6382 "dev": true, 4717 6383 "license": "MIT", 4718 6384 "engines": { ··· 4721 6387 }, 4722 6388 "node_modules/tr46": { 4723 6389 "version": "0.0.3", 6390 + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 6391 + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", 4724 6392 "dev": true, 4725 6393 "license": "MIT" 4726 6394 }, 4727 6395 "node_modules/trim-lines": { 4728 6396 "version": "3.0.1", 6397 + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", 6398 + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", 4729 6399 "license": "MIT", 4730 6400 "funding": { 4731 6401 "type": "github", ··· 4734 6404 }, 4735 6405 "node_modules/trough": { 4736 6406 "version": "2.2.0", 6407 + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", 6408 + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", 4737 6409 "license": "MIT", 4738 6410 "funding": { 4739 6411 "type": "github", ··· 4741 6413 } 4742 6414 }, 4743 6415 "node_modules/ts-api-utils": { 4744 - "version": "1.4.3", 6416 + "version": "2.1.0", 6417 + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", 6418 + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", 4745 6419 "dev": true, 4746 6420 "license": "MIT", 4747 6421 "engines": { 4748 - "node": ">=16" 6422 + "node": ">=18.12" 4749 6423 }, 4750 6424 "peerDependencies": { 4751 - "typescript": ">=4.2.0" 6425 + "typescript": ">=4.8.4" 4752 6426 } 4753 6427 }, 4754 6428 "node_modules/ts-interface-checker": { 4755 6429 "version": "0.1.13", 6430 + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", 6431 + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", 4756 6432 "dev": true, 4757 6433 "license": "Apache-2.0" 4758 6434 }, 4759 6435 "node_modules/type-check": { 4760 6436 "version": "0.4.0", 6437 + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 6438 + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 4761 6439 "dev": true, 4762 6440 "license": "MIT", 4763 6441 "dependencies": { ··· 4768 6446 } 4769 6447 }, 4770 6448 "node_modules/typescript": { 4771 - "version": "5.7.2", 6449 + "version": "5.8.3", 6450 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", 6451 + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", 4772 6452 "dev": true, 4773 6453 "license": "Apache-2.0", 4774 6454 "bin": { ··· 4780 6460 } 4781 6461 }, 4782 6462 "node_modules/typescript-eslint": { 4783 - "version": "8.16.0", 6463 + "version": "8.38.0", 6464 + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.38.0.tgz", 6465 + "integrity": "sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==", 4784 6466 "dev": true, 4785 6467 "license": "MIT", 4786 6468 "dependencies": { 4787 - "@typescript-eslint/eslint-plugin": "8.16.0", 4788 - "@typescript-eslint/parser": "8.16.0", 4789 - "@typescript-eslint/utils": "8.16.0" 6469 + "@typescript-eslint/eslint-plugin": "8.38.0", 6470 + "@typescript-eslint/parser": "8.38.0", 6471 + "@typescript-eslint/typescript-estree": "8.38.0", 6472 + "@typescript-eslint/utils": "8.38.0" 4790 6473 }, 4791 6474 "engines": { 4792 6475 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 4796 6479 "url": "https://opencollective.com/typescript-eslint" 4797 6480 }, 4798 6481 "peerDependencies": { 4799 - "eslint": "^8.57.0 || ^9.0.0" 4800 - }, 4801 - "peerDependenciesMeta": { 4802 - "typescript": { 4803 - "optional": true 4804 - } 6482 + "eslint": "^8.57.0 || ^9.0.0", 6483 + "typescript": ">=4.8.4 <5.9.0" 4805 6484 } 4806 6485 }, 4807 6486 "node_modules/undici-types": { 4808 - "version": "6.20.0", 6487 + "version": "6.21.0", 6488 + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", 6489 + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", 4809 6490 "dev": true, 4810 6491 "license": "MIT" 4811 6492 }, 4812 6493 "node_modules/unicode-trie": { 4813 6494 "version": "2.0.0", 6495 + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", 6496 + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", 4814 6497 "license": "MIT", 4815 6498 "dependencies": { 4816 6499 "pako": "^0.2.5", ··· 4819 6502 }, 4820 6503 "node_modules/unified": { 4821 6504 "version": "11.0.5", 6505 + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", 6506 + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", 4822 6507 "license": "MIT", 4823 6508 "dependencies": { 4824 6509 "@types/unist": "^3.0.0", ··· 4836 6521 }, 4837 6522 "node_modules/unist-util-is": { 4838 6523 "version": "6.0.0", 6524 + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", 6525 + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", 4839 6526 "license": "MIT", 4840 6527 "dependencies": { 4841 6528 "@types/unist": "^3.0.0" ··· 4847 6534 }, 4848 6535 "node_modules/unist-util-position": { 4849 6536 "version": "5.0.0", 6537 + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", 6538 + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", 4850 6539 "license": "MIT", 4851 6540 "dependencies": { 4852 6541 "@types/unist": "^3.0.0" ··· 4858 6547 }, 4859 6548 "node_modules/unist-util-stringify-position": { 4860 6549 "version": "4.0.0", 6550 + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", 6551 + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", 4861 6552 "license": "MIT", 4862 6553 "dependencies": { 4863 6554 "@types/unist": "^3.0.0" ··· 4869 6560 }, 4870 6561 "node_modules/unist-util-visit": { 4871 6562 "version": "5.0.0", 6563 + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", 6564 + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", 4872 6565 "license": "MIT", 4873 6566 "dependencies": { 4874 6567 "@types/unist": "^3.0.0", ··· 4882 6575 }, 4883 6576 "node_modules/unist-util-visit-parents": { 4884 6577 "version": "6.0.1", 6578 + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", 6579 + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", 4885 6580 "license": "MIT", 4886 6581 "dependencies": { 4887 6582 "@types/unist": "^3.0.0", ··· 4894 6589 }, 4895 6590 "node_modules/update-browserslist-db": { 4896 6591 "version": "1.1.3", 6592 + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", 6593 + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", 4897 6594 "dev": true, 4898 6595 "funding": [ 4899 6596 { ··· 4923 6620 }, 4924 6621 "node_modules/uri-js": { 4925 6622 "version": "4.4.1", 6623 + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 6624 + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 4926 6625 "dev": true, 4927 6626 "license": "BSD-2-Clause", 4928 6627 "dependencies": { ··· 4931 6630 }, 4932 6631 "node_modules/util-deprecate": { 4933 6632 "version": "1.0.2", 6633 + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 6634 + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 4934 6635 "license": "MIT" 4935 6636 }, 4936 6637 "node_modules/vfile": { 4937 6638 "version": "6.0.3", 6639 + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", 6640 + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", 4938 6641 "license": "MIT", 4939 6642 "dependencies": { 4940 6643 "@types/unist": "^3.0.0", ··· 4947 6650 }, 4948 6651 "node_modules/vfile-location": { 4949 6652 "version": "5.0.3", 6653 + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", 6654 + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", 4950 6655 "license": "MIT", 4951 6656 "dependencies": { 4952 6657 "@types/unist": "^3.0.0", ··· 4958 6663 } 4959 6664 }, 4960 6665 "node_modules/vfile-message": { 4961 - "version": "4.0.2", 6666 + "version": "4.0.3", 6667 + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", 6668 + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", 4962 6669 "license": "MIT", 4963 6670 "dependencies": { 4964 6671 "@types/unist": "^3.0.0", ··· 4970 6677 } 4971 6678 }, 4972 6679 "node_modules/vite": { 4973 - "version": "5.4.11", 6680 + "version": "5.4.19", 6681 + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", 6682 + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", 4974 6683 "dev": true, 4975 6684 "license": "MIT", 4976 6685 "dependencies": { ··· 5027 6736 } 5028 6737 } 5029 6738 }, 6739 + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { 6740 + "version": "0.21.5", 6741 + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 6742 + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 6743 + "cpu": [ 6744 + "ppc64" 6745 + ], 6746 + "dev": true, 6747 + "license": "MIT", 6748 + "optional": true, 6749 + "os": [ 6750 + "aix" 6751 + ], 6752 + "engines": { 6753 + "node": ">=12" 6754 + } 6755 + }, 6756 + "node_modules/vite/node_modules/@esbuild/android-arm": { 6757 + "version": "0.21.5", 6758 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 6759 + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 6760 + "cpu": [ 6761 + "arm" 6762 + ], 6763 + "dev": true, 6764 + "license": "MIT", 6765 + "optional": true, 6766 + "os": [ 6767 + "android" 6768 + ], 6769 + "engines": { 6770 + "node": ">=12" 6771 + } 6772 + }, 6773 + "node_modules/vite/node_modules/@esbuild/android-arm64": { 6774 + "version": "0.21.5", 6775 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 6776 + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 6777 + "cpu": [ 6778 + "arm64" 6779 + ], 6780 + "dev": true, 6781 + "license": "MIT", 6782 + "optional": true, 6783 + "os": [ 6784 + "android" 6785 + ], 6786 + "engines": { 6787 + "node": ">=12" 6788 + } 6789 + }, 6790 + "node_modules/vite/node_modules/@esbuild/android-x64": { 6791 + "version": "0.21.5", 6792 + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 6793 + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 6794 + "cpu": [ 6795 + "x64" 6796 + ], 6797 + "dev": true, 6798 + "license": "MIT", 6799 + "optional": true, 6800 + "os": [ 6801 + "android" 6802 + ], 6803 + "engines": { 6804 + "node": ">=12" 6805 + } 6806 + }, 6807 + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { 6808 + "version": "0.21.5", 6809 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 6810 + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 6811 + "cpu": [ 6812 + "arm64" 6813 + ], 6814 + "dev": true, 6815 + "license": "MIT", 6816 + "optional": true, 6817 + "os": [ 6818 + "darwin" 6819 + ], 6820 + "engines": { 6821 + "node": ">=12" 6822 + } 6823 + }, 6824 + "node_modules/vite/node_modules/@esbuild/darwin-x64": { 6825 + "version": "0.21.5", 6826 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 6827 + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 6828 + "cpu": [ 6829 + "x64" 6830 + ], 6831 + "dev": true, 6832 + "license": "MIT", 6833 + "optional": true, 6834 + "os": [ 6835 + "darwin" 6836 + ], 6837 + "engines": { 6838 + "node": ">=12" 6839 + } 6840 + }, 6841 + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { 6842 + "version": "0.21.5", 6843 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 6844 + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 6845 + "cpu": [ 6846 + "arm64" 6847 + ], 6848 + "dev": true, 6849 + "license": "MIT", 6850 + "optional": true, 6851 + "os": [ 6852 + "freebsd" 6853 + ], 6854 + "engines": { 6855 + "node": ">=12" 6856 + } 6857 + }, 6858 + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { 6859 + "version": "0.21.5", 6860 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 6861 + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 6862 + "cpu": [ 6863 + "x64" 6864 + ], 6865 + "dev": true, 6866 + "license": "MIT", 6867 + "optional": true, 6868 + "os": [ 6869 + "freebsd" 6870 + ], 6871 + "engines": { 6872 + "node": ">=12" 6873 + } 6874 + }, 6875 + "node_modules/vite/node_modules/@esbuild/linux-arm": { 6876 + "version": "0.21.5", 6877 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 6878 + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 6879 + "cpu": [ 6880 + "arm" 6881 + ], 6882 + "dev": true, 6883 + "license": "MIT", 6884 + "optional": true, 6885 + "os": [ 6886 + "linux" 6887 + ], 6888 + "engines": { 6889 + "node": ">=12" 6890 + } 6891 + }, 6892 + "node_modules/vite/node_modules/@esbuild/linux-arm64": { 6893 + "version": "0.21.5", 6894 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 6895 + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 6896 + "cpu": [ 6897 + "arm64" 6898 + ], 6899 + "dev": true, 6900 + "license": "MIT", 6901 + "optional": true, 6902 + "os": [ 6903 + "linux" 6904 + ], 6905 + "engines": { 6906 + "node": ">=12" 6907 + } 6908 + }, 6909 + "node_modules/vite/node_modules/@esbuild/linux-ia32": { 6910 + "version": "0.21.5", 6911 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 6912 + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 6913 + "cpu": [ 6914 + "ia32" 6915 + ], 6916 + "dev": true, 6917 + "license": "MIT", 6918 + "optional": true, 6919 + "os": [ 6920 + "linux" 6921 + ], 6922 + "engines": { 6923 + "node": ">=12" 6924 + } 6925 + }, 6926 + "node_modules/vite/node_modules/@esbuild/linux-loong64": { 6927 + "version": "0.21.5", 6928 + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 6929 + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 6930 + "cpu": [ 6931 + "loong64" 6932 + ], 6933 + "dev": true, 6934 + "license": "MIT", 6935 + "optional": true, 6936 + "os": [ 6937 + "linux" 6938 + ], 6939 + "engines": { 6940 + "node": ">=12" 6941 + } 6942 + }, 6943 + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { 6944 + "version": "0.21.5", 6945 + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 6946 + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 6947 + "cpu": [ 6948 + "mips64el" 6949 + ], 6950 + "dev": true, 6951 + "license": "MIT", 6952 + "optional": true, 6953 + "os": [ 6954 + "linux" 6955 + ], 6956 + "engines": { 6957 + "node": ">=12" 6958 + } 6959 + }, 6960 + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { 6961 + "version": "0.21.5", 6962 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 6963 + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 6964 + "cpu": [ 6965 + "ppc64" 6966 + ], 6967 + "dev": true, 6968 + "license": "MIT", 6969 + "optional": true, 6970 + "os": [ 6971 + "linux" 6972 + ], 6973 + "engines": { 6974 + "node": ">=12" 6975 + } 6976 + }, 6977 + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { 6978 + "version": "0.21.5", 6979 + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 6980 + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 6981 + "cpu": [ 6982 + "riscv64" 6983 + ], 6984 + "dev": true, 6985 + "license": "MIT", 6986 + "optional": true, 6987 + "os": [ 6988 + "linux" 6989 + ], 6990 + "engines": { 6991 + "node": ">=12" 6992 + } 6993 + }, 6994 + "node_modules/vite/node_modules/@esbuild/linux-s390x": { 6995 + "version": "0.21.5", 6996 + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 6997 + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 6998 + "cpu": [ 6999 + "s390x" 7000 + ], 7001 + "dev": true, 7002 + "license": "MIT", 7003 + "optional": true, 7004 + "os": [ 7005 + "linux" 7006 + ], 7007 + "engines": { 7008 + "node": ">=12" 7009 + } 7010 + }, 7011 + "node_modules/vite/node_modules/@esbuild/linux-x64": { 7012 + "version": "0.21.5", 7013 + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 7014 + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 7015 + "cpu": [ 7016 + "x64" 7017 + ], 7018 + "dev": true, 7019 + "license": "MIT", 7020 + "optional": true, 7021 + "os": [ 7022 + "linux" 7023 + ], 7024 + "engines": { 7025 + "node": ">=12" 7026 + } 7027 + }, 7028 + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { 7029 + "version": "0.21.5", 7030 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 7031 + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 7032 + "cpu": [ 7033 + "x64" 7034 + ], 7035 + "dev": true, 7036 + "license": "MIT", 7037 + "optional": true, 7038 + "os": [ 7039 + "netbsd" 7040 + ], 7041 + "engines": { 7042 + "node": ">=12" 7043 + } 7044 + }, 7045 + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { 7046 + "version": "0.21.5", 7047 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 7048 + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 7049 + "cpu": [ 7050 + "x64" 7051 + ], 7052 + "dev": true, 7053 + "license": "MIT", 7054 + "optional": true, 7055 + "os": [ 7056 + "openbsd" 7057 + ], 7058 + "engines": { 7059 + "node": ">=12" 7060 + } 7061 + }, 7062 + "node_modules/vite/node_modules/@esbuild/sunos-x64": { 7063 + "version": "0.21.5", 7064 + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 7065 + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 7066 + "cpu": [ 7067 + "x64" 7068 + ], 7069 + "dev": true, 7070 + "license": "MIT", 7071 + "optional": true, 7072 + "os": [ 7073 + "sunos" 7074 + ], 7075 + "engines": { 7076 + "node": ">=12" 7077 + } 7078 + }, 7079 + "node_modules/vite/node_modules/@esbuild/win32-arm64": { 7080 + "version": "0.21.5", 7081 + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 7082 + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 7083 + "cpu": [ 7084 + "arm64" 7085 + ], 7086 + "dev": true, 7087 + "license": "MIT", 7088 + "optional": true, 7089 + "os": [ 7090 + "win32" 7091 + ], 7092 + "engines": { 7093 + "node": ">=12" 7094 + } 7095 + }, 7096 + "node_modules/vite/node_modules/@esbuild/win32-ia32": { 7097 + "version": "0.21.5", 7098 + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 7099 + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 7100 + "cpu": [ 7101 + "ia32" 7102 + ], 7103 + "dev": true, 7104 + "license": "MIT", 7105 + "optional": true, 7106 + "os": [ 7107 + "win32" 7108 + ], 7109 + "engines": { 7110 + "node": ">=12" 7111 + } 7112 + }, 7113 + "node_modules/vite/node_modules/@esbuild/win32-x64": { 7114 + "version": "0.21.5", 7115 + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 7116 + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 7117 + "cpu": [ 7118 + "x64" 7119 + ], 7120 + "dev": true, 7121 + "license": "MIT", 7122 + "optional": true, 7123 + "os": [ 7124 + "win32" 7125 + ], 7126 + "engines": { 7127 + "node": ">=12" 7128 + } 7129 + }, 7130 + "node_modules/vite/node_modules/esbuild": { 7131 + "version": "0.21.5", 7132 + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", 7133 + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 7134 + "dev": true, 7135 + "hasInstallScript": true, 7136 + "license": "MIT", 7137 + "bin": { 7138 + "esbuild": "bin/esbuild" 7139 + }, 7140 + "engines": { 7141 + "node": ">=12" 7142 + }, 7143 + "optionalDependencies": { 7144 + "@esbuild/aix-ppc64": "0.21.5", 7145 + "@esbuild/android-arm": "0.21.5", 7146 + "@esbuild/android-arm64": "0.21.5", 7147 + "@esbuild/android-x64": "0.21.5", 7148 + "@esbuild/darwin-arm64": "0.21.5", 7149 + "@esbuild/darwin-x64": "0.21.5", 7150 + "@esbuild/freebsd-arm64": "0.21.5", 7151 + "@esbuild/freebsd-x64": "0.21.5", 7152 + "@esbuild/linux-arm": "0.21.5", 7153 + "@esbuild/linux-arm64": "0.21.5", 7154 + "@esbuild/linux-ia32": "0.21.5", 7155 + "@esbuild/linux-loong64": "0.21.5", 7156 + "@esbuild/linux-mips64el": "0.21.5", 7157 + "@esbuild/linux-ppc64": "0.21.5", 7158 + "@esbuild/linux-riscv64": "0.21.5", 7159 + "@esbuild/linux-s390x": "0.21.5", 7160 + "@esbuild/linux-x64": "0.21.5", 7161 + "@esbuild/netbsd-x64": "0.21.5", 7162 + "@esbuild/openbsd-x64": "0.21.5", 7163 + "@esbuild/sunos-x64": "0.21.5", 7164 + "@esbuild/win32-arm64": "0.21.5", 7165 + "@esbuild/win32-ia32": "0.21.5", 7166 + "@esbuild/win32-x64": "0.21.5" 7167 + } 7168 + }, 5030 7169 "node_modules/vitefu": { 5031 - "version": "1.0.4", 7170 + "version": "1.1.1", 7171 + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", 7172 + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", 5032 7173 "dev": true, 5033 7174 "license": "MIT", 5034 7175 "workspaces": [ 5035 7176 "tests/deps/*", 5036 - "tests/projects/*" 7177 + "tests/projects/*", 7178 + "tests/projects/workspace/packages/*" 5037 7179 ], 5038 7180 "peerDependencies": { 5039 - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" 7181 + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" 5040 7182 }, 5041 7183 "peerDependenciesMeta": { 5042 7184 "vite": { ··· 5046 7188 }, 5047 7189 "node_modules/web-namespaces": { 5048 7190 "version": "2.0.1", 7191 + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", 7192 + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", 5049 7193 "license": "MIT", 5050 7194 "funding": { 5051 7195 "type": "github", ··· 5054 7198 }, 5055 7199 "node_modules/webidl-conversions": { 5056 7200 "version": "3.0.1", 7201 + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 7202 + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", 5057 7203 "dev": true, 5058 7204 "license": "BSD-2-Clause" 5059 7205 }, 5060 7206 "node_modules/whatwg-url": { 5061 7207 "version": "5.0.0", 7208 + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 7209 + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 5062 7210 "dev": true, 5063 7211 "license": "MIT", 5064 7212 "dependencies": { ··· 5068 7216 }, 5069 7217 "node_modules/which": { 5070 7218 "version": "2.0.2", 7219 + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 7220 + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 5071 7221 "dev": true, 5072 7222 "license": "ISC", 5073 7223 "dependencies": { ··· 5082 7232 }, 5083 7233 "node_modules/word-wrap": { 5084 7234 "version": "1.2.5", 7235 + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 7236 + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 5085 7237 "dev": true, 5086 7238 "license": "MIT", 5087 7239 "engines": { ··· 5090 7242 }, 5091 7243 "node_modules/wrap-ansi": { 5092 7244 "version": "8.1.0", 7245 + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 7246 + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 5093 7247 "dev": true, 5094 7248 "license": "MIT", 5095 7249 "dependencies": { ··· 5107 7261 "node_modules/wrap-ansi-cjs": { 5108 7262 "name": "wrap-ansi", 5109 7263 "version": "7.0.0", 7264 + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 7265 + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 5110 7266 "dev": true, 5111 7267 "license": "MIT", 5112 7268 "dependencies": { ··· 5123 7279 }, 5124 7280 "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 5125 7281 "version": "5.0.1", 7282 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 7283 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 5126 7284 "dev": true, 5127 7285 "license": "MIT", 5128 7286 "engines": { ··· 5131 7289 }, 5132 7290 "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 5133 7291 "version": "8.0.0", 7292 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 7293 + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 5134 7294 "dev": true, 5135 7295 "license": "MIT" 5136 7296 }, 5137 7297 "node_modules/wrap-ansi-cjs/node_modules/string-width": { 5138 7298 "version": "4.2.3", 7299 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 7300 + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 5139 7301 "dev": true, 5140 7302 "license": "MIT", 5141 7303 "dependencies": { ··· 5149 7311 }, 5150 7312 "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 5151 7313 "version": "6.0.1", 7314 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 7315 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 5152 7316 "dev": true, 5153 7317 "license": "MIT", 5154 7318 "dependencies": { ··· 5160 7324 }, 5161 7325 "node_modules/wrap-ansi/node_modules/ansi-styles": { 5162 7326 "version": "6.2.1", 7327 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 7328 + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 5163 7329 "dev": true, 5164 7330 "license": "MIT", 5165 7331 "engines": { ··· 5171 7337 }, 5172 7338 "node_modules/yallist": { 5173 7339 "version": "5.0.0", 7340 + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", 7341 + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", 5174 7342 "dev": true, 5175 7343 "license": "BlueOak-1.0.0", 5176 7344 "engines": { ··· 5179 7347 }, 5180 7348 "node_modules/yaml": { 5181 7349 "version": "1.10.2", 7350 + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", 7351 + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", 5182 7352 "dev": true, 5183 7353 "license": "ISC", 5184 7354 "engines": { ··· 5187 7357 }, 5188 7358 "node_modules/yocto-queue": { 5189 7359 "version": "0.1.0", 7360 + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 7361 + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 5190 7362 "dev": true, 5191 7363 "license": "MIT", 5192 7364 "engines": { ··· 5198 7370 }, 5199 7371 "node_modules/yoga-wasm-web": { 5200 7372 "version": "0.3.3", 7373 + "resolved": "https://registry.npmjs.org/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz", 7374 + "integrity": "sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==", 5201 7375 "license": "MIT" 5202 7376 }, 5203 7377 "node_modules/zimmerframe": { 5204 7378 "version": "1.1.2", 7379 + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", 7380 + "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", 5205 7381 "dev": true, 5206 7382 "license": "MIT" 5207 7383 }, 5208 7384 "node_modules/zwitch": { 5209 7385 "version": "2.0.4", 7386 + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", 7387 + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", 5210 7388 "license": "MIT", 5211 7389 "funding": { 5212 7390 "type": "github",
+2 -3
package.json
··· 1 1 { 2 - "name": "website-template", 2 + "name": "linkat-directory", 3 3 "version": "0.0.1", 4 4 "type": "module", 5 5 "scripts": { ··· 11 11 "lint": "eslint ." 12 12 }, 13 13 "devDependencies": { 14 - 15 - "@sveltejs/adapter-vercel": "^5.7.0", 14 + "@sveltejs/adapter-vercel": "^5.8.1", 16 15 "@sveltejs/kit": "^2.24.0", 17 16 "@sveltejs/vite-plugin-svelte": "^4.0.4", 18 17 "@tailwindcss/forms": "^0.5.9",
+1 -7
src/app.html
··· 10 10 <meta name="mobile-web-app-capable" content="yes" /> 11 11 <meta name="apple-mobile-web-app-capable" content="yes" /> 12 12 <meta name="msapplication-TileColor" content="#000000" /> 13 - <meta 14 - name="msapplication-TileImage" 15 - content="%sveltekit.assets%/favicon/ms-icon-144x144.png" 16 - /> 17 - 18 - <!-- THEME LOADER - MUST BE FIRST SCRIPT --> 19 - <script src="%sveltekit.assets%/scripts/themeLoader.js"></script> 13 + <link rel="icon" href="/logo.ico" /> 20 14 %sveltekit.head% 21 15 </head> 22 16 <body data-sveltekit-preload-data="hover">
+27 -468
src/lib/components/archive/ArchiveCard.svelte
··· 1 1 <script lang="ts"> 2 - import { fly, fade } from "svelte/transition"; 3 - import { quintOut } from "svelte/easing"; 4 - import { formatDate, formatNumber } from "$utils/formatters"; 5 - import { getMilestone } from "$utils/milestones"; 6 - import DocumentIcon from "$components/icons/utility/DocumentIcon.svelte"; 7 - import LinkExternalIcon from "$components/icons/utility/LinkExternalIcon.svelte"; 8 - import CoffeeIcon from "$components/icons/utility/CoffeeIcon.svelte"; 9 - import ClockIcon from "$components/icons/utility/ClockIcon.svelte"; 10 - import BookIcon from "$components/icons/utility/BookIcon.svelte"; 11 - import BooksIcon from "$components/icons/utility/BooksIcon.svelte"; 12 - 13 - export let type: 'post' | 'link'; 14 - export let post: any = {}; // For post type 15 - export let title: string = ""; // For link type or post title 16 - export let url: string = ""; // For link type 17 - export let value: string = ""; // For link type 18 - export let monthIndex: number = 0; 19 - export let postIndex: number = 0; 20 - export let localeLoaded: boolean = false; 21 - export let postNumber: number | null = null; // New prop for milestone calculation 22 - 23 - // Reactive variable to store the display date string for posts 24 - let displayDate: string; 25 - 26 - // Update displayDate whenever post.createdAt or localeLoaded changes for posts 27 - $: { 28 - if (type === 'post' && localeLoaded && post?.createdAt) { 29 - const postDate = new Date(post.createdAt); 30 - displayDate = formatDate(postDate); 31 - } else if (type === 'post') { 32 - displayDate = "Loading..."; 33 - } 34 - } 35 - 36 - // Calculate milestone information 37 - $: milestone = type === 'post' && postNumber ? getMilestone(postNumber) : null; 38 - 39 - // Determine the title to display based on type 40 - $: displayTitle = type === 'post' ? post?.title : title; 41 - $: href = type === 'post' ? `/blog/${post.rkey}` : url; 42 - 43 - // Calculate reading time category for visual styling 44 - $: readingTime = type === 'post' ? Math.ceil(post.wordCount / 200) : 0; 45 - $: isLongRead = readingTime > 10; 46 - $: isMediumRead = readingTime > 5 && readingTime <= 10; 47 - $: isQuickRead = readingTime <= 2; 48 - 49 - // Get appropriate icon based on reading time 50 - $: getReadingTimeIcon = (time: number) => { 51 - if (time <= 2) return 'quick'; // Coffee cup for quick reads 52 - if (time <= 5) return 'short'; // Clock for short reads 53 - if (time <= 10) return 'medium'; // Book for medium reads 54 - return 'long'; // Stack of books for long reads 55 - }; 2 + export let type: 'link' | 'user'; 3 + export let url: string; 4 + export let title: string; 5 + export let value: string | undefined = undefined; 56 6 </script> 57 7 58 - <div 59 - class="archive-card group" 60 - class:long-read={type === 'post' && isLongRead} 61 - class:medium-read={type === 'post' && isMediumRead} 62 - class:has-milestone={milestone} 63 - in:fly={{ 64 - y: 15, 65 - x: 0, 66 - delay: 150 + monthIndex * 30 + postIndex * 50, 67 - duration: 300, 68 - easing: quintOut, 69 - }} 70 - > 71 - <a {href} class="card-link"> 72 - <article class="card-content"> 73 - <!-- Milestone banner (appears at top if present) --> 74 - {#if milestone} 75 - <div 76 - class="milestone-banner" 77 - class:special={milestone.type === 'special'} 78 - class:major={milestone.type === 'major'} 79 - class:minor={milestone.type === 'minor'} 80 - in:fade={{ delay: 300, duration: 400 }} 81 - > 82 - <span class="milestone-emoji" role="img" aria-label="milestone">{milestone.emoji}</span> 83 - <span class="milestone-text">{milestone.text}</span> 84 - </div> 85 - {/if} 86 - 87 - <!-- Header section with title and type indicator --> 88 - <header class="card-header"> 89 - {#if type === 'post'} 90 - <div class="type-indicator post-indicator"> 91 - <DocumentIcon size="14" /> 92 - <span class="sr-only">Blog post</span> 93 - </div> 94 - {:else} 95 - <div class="type-indicator link-indicator"> 96 - <LinkExternalIcon size="14" /> 97 - <span class="sr-only">External link</span> 98 - </div> 99 - {/if} 100 - 101 - <h3 class="card-title" title={displayTitle}> 102 - {displayTitle} 103 - </h3> 104 - </header> 105 - 106 - <!-- Main content area --> 107 - <div class="card-body"> 108 - {#if type === 'post'} 109 - <!-- Reading stats with visual emphasis --> 110 - <div class="reading-stats"> 111 - <div class="stat-item words"> 112 - <span class="stat-number">{formatNumber(post.wordCount) || '0'}</span> 113 - <span class="stat-label">words</span> 114 - </div> 115 - <div class="stat-divider">โ€ข</div> 116 - <div class="stat-item time" class:highlight={isLongRead}> 117 - <div class="reading-time-icon" class:quick={isQuickRead} class:medium={isMediumRead} class:long={isLongRead}> 118 - {#if getReadingTimeIcon(readingTime) === 'quick'} 119 - <CoffeeIcon size="14" /> 120 - {:else if getReadingTimeIcon(readingTime) === 'short'} 121 - <ClockIcon size="14" /> 122 - {:else if getReadingTimeIcon(readingTime) === 'medium'} 123 - <BookIcon size="14" /> 124 - {:else} 125 - <BooksIcon size="14" /> 126 - {/if} 127 - </div> 128 - <span class="stat-number">{Math.ceil(post.wordCount / 200)}</span> 129 - <span class="stat-label">min read</span> 130 - </div> 131 - </div> 132 - {:else if type === 'link'} 133 - <p class="link-value">{value}</p> 134 - {/if} 135 - </div> 136 - 137 - <!-- Footer with metadata --> 138 - <footer class="card-footer"> 139 - {#if type === 'post'} 140 - <div class="date-section"> 141 - <span class="date-label">Last Updated</span> 142 - <div class="date-value"> 143 - {#if localeLoaded && displayDate !== "Loading..."} 144 - <span transition:fade>{displayDate}</span> 145 - {:else} 146 - <span class="loading">Loading...</span> 147 - {/if} 148 - </div> 149 - </div> 150 - {:else if type === 'link'} 151 - <div class="link-domain"> 152 - {url?.replace(/^https?:\/\//, "").split("/")[0]} 153 - </div> 154 - {/if} 155 - </footer> 156 - </article> 8 + {#if type === 'link'} 9 + <a 10 + href={url} 11 + target="_blank" 12 + rel="noopener noreferrer" 13 + class="block p-4 rounded-lg border hover:shadow-lg transition-shadow" 14 + style="background: var(--card-bg); border-color: var(--border-color);" 15 + > 16 + {#if value} 17 + <div class="text-2xl mb-2">{value}</div> 18 + {/if} 19 + <h3 class="font-semibold text-lg mb-1">{title}</h3> 20 + <p class="text-sm text-link opacity-75 truncate">{url}</p> 157 21 </a> 158 - </div> 159 - 160 - <style> 161 - .archive-card { 162 - backface-visibility: hidden; 163 - transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1); 164 - } 165 - 166 - .card-link { 167 - display: block; 168 - text-decoration: none; 169 - height: 100%; 170 - } 171 - 172 - .card-content { 173 - display: flex; 174 - flex-direction: column; 175 - height: 100%; 176 - min-height: 140px; 177 - padding: 20px; 178 - border: 1px solid transparent; 179 - border-radius: 0px; 180 - background: var(--header-footer-bg); 181 - transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1); 182 - position: relative; 183 - overflow: hidden; 184 - } 185 - 186 - .card-content::before { 187 - content: ''; 188 - position: absolute; 189 - top: 0; 190 - left: 0; 191 - right: 0; 192 - height: 3px; 193 - background: var(--link-color); 194 - transform: scaleX(0); 195 - transition: transform 0.3s ease; 196 - transform-origin: left; 197 - } 198 - 199 - .group:hover .card-content { 200 - border-color: var(--button-bg); 201 - transform: translateY(-2px); 202 - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); 203 - } 204 - 205 - .group:hover .card-content::before { 206 - transform: scaleX(1); 207 - } 208 - 209 - /* Disable line animation for milestone cards */ 210 - .has-milestone .card-content::before { 211 - display: none; 212 - } 213 - 214 - /* Milestone Banner Styles */ 215 - .milestone-banner { 216 - display: flex; 217 - align-items: center; 218 - justify-content: center; 219 - gap: 8px; 220 - padding: 8px 12px; 221 - margin: -20px -20px 16px -20px; 222 - font-size: 0.85rem; 223 - font-weight: 600; 224 - text-align: center; 225 - position: relative; 226 - overflow: hidden; 227 - } 228 - 229 - .milestone-banner::before { 230 - content: ''; 231 - position: absolute; 232 - top: 0; 233 - left: -100%; 234 - width: 100%; 235 - height: 100%; 236 - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); 237 - animation: shimmer 2s infinite; 238 - } 239 - 240 - @keyframes shimmer { 241 - 0% { left: -100%; } 242 - 100% { left: 100%; } 243 - } 244 - 245 - .milestone-banner.special { 246 - background: linear-gradient(135deg, var(--button-bg), var(--button-hover-bg)); 247 - color: white; 248 - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); 249 - } 250 - 251 - .milestone-banner.major { 252 - background: linear-gradient(135deg, var(--button-bg), var(--text-color)); 253 - color: var(--header-footer-bg); 254 - } 255 - 256 - .milestone-banner.minor { 257 - background: var(--button-bg); 258 - color: var(--text-color); 259 - opacity: 0.9; 260 - } 261 - 262 - .milestone-emoji { 263 - font-size: 1rem; 264 - filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1)); 265 - } 266 - 267 - .milestone-text { 268 - letter-spacing: 0.02em; 269 - } 270 - 271 - /* Adjust card content when milestone is present */ 272 - .has-milestone .card-header { 273 - margin-bottom: 12px; 274 - } 275 - 276 - .has-milestone .card-content { 277 - min-height: 160px; 278 - } 279 - 280 - /* Header Styles */ 281 - .card-header { 282 - display: flex; 283 - align-items: flex-start; 284 - gap: 12px; 285 - margin-bottom: 16px; 286 - } 287 - 288 - .type-indicator { 289 - flex-shrink: 0; 290 - padding: 6px; 291 - border-radius: 0px; 292 - margin-top: 2px; 293 - transition: all 0.3s ease; 294 - } 295 - 296 - .post-indicator, .link-indicator { 297 - background: var(--button-bg); 298 - color: var(--text-color); 299 - opacity: 0.8; 300 - } 301 - 302 - .group:hover .type-indicator { 303 - transform: scale(1.1); 304 - } 305 - 306 - .card-title { 307 - flex: 1; 308 - margin: 0; 309 - font-size: 1.1rem; 310 - font-weight: 600; 311 - line-height: 1.4; 312 - color: var(--link-color); 313 - display: -webkit-box; 314 - -webkit-line-clamp: 3; 315 - line-clamp: 3; 316 - -webkit-box-orient: vertical; 317 - overflow: hidden; 318 - word-break: break-word; 319 - transition: color 0.3s ease; 320 - } 321 - 322 - .group:hover .card-title { 323 - color: var(--link-hover-color); 324 - } 325 - 326 - /* Body Styles */ 327 - .card-body { 328 - flex: 1; 329 - display: flex; 330 - align-items: center; 331 - } 332 - 333 - .reading-stats { 334 - display: flex; 335 - align-items: center; 336 - gap: 12px; 337 - font-size: 0.95rem; 338 - } 339 - 340 - .stat-item { 341 - display: flex; 342 - align-items: center; 343 - gap: 6px; 344 - } 345 - 346 - .reading-time-icon { 347 - display: flex; 348 - align-items: center; 349 - color: var(--text-color); 350 - opacity: 0.7; 351 - transition: all 0.3s ease; 352 - } 353 - 354 - .stat-number { 355 - font-weight: 600; 356 - color: var(--text-color); 357 - } 358 - 359 - .stat-label { 360 - font-size: 0.85rem; 361 - color: var(--text-color); 362 - opacity: 0.7; 363 - } 364 - 365 - .stat-item.highlight .stat-number { 366 - color: var(--link-color); 367 - font-weight: 700; 368 - } 369 - 370 - .stat-divider { 371 - color: var(--text-color); 372 - opacity: 0.4; 373 - } 374 - 375 - .link-value { 376 - color: var(--text-color); 377 - font-size: 0.9rem; 378 - line-height: 1.4; 379 - margin: 0; 380 - } 381 - 382 - /* Footer Styles */ 383 - .card-footer { 384 - margin-top: auto; 385 - padding-top: 16px; 386 - } 387 - 388 - .date-section { 389 - display: flex; 390 - flex-direction: column; 391 - gap: 4px; 392 - } 393 - 394 - .date-label { 395 - font-size: 0.75rem; 396 - color: var(--text-color); 397 - opacity: 0.6; 398 - text-transform: uppercase; 399 - letter-spacing: 0.5px; 400 - font-weight: 500; 401 - } 402 - 403 - .date-value { 404 - font-size: 0.9rem; 405 - color: var(--text-color); 406 - font-weight: 500; 407 - } 408 - 409 - .loading { 410 - opacity: 0.5; 411 - font-style: italic; 412 - } 413 - 414 - .link-domain { 415 - font-size: 0.8rem; 416 - color: var(--text-color); 417 - opacity: 0.7; 418 - font-family: monospace; 419 - background: var(--button-bg); 420 - padding: 4px 8px; 421 - border-radius: 0px; 422 - display: inline-block; 423 - } 424 - 425 - /* Adaptive sizing based on content */ 426 - .long-read .card-content { 427 - min-height: 160px; 428 - } 429 - 430 - .medium-read .card-content { 431 - min-height: 150px; 432 - } 433 - 434 - .long-read .card-content::before { 435 - height: 4px; 436 - background: var(--link-color); 437 - } 438 - 439 - /* Screen reader only content */ 440 - .sr-only { 441 - position: absolute; 442 - width: 1px; 443 - height: 1px; 444 - padding: 0; 445 - margin: -1px; 446 - overflow: hidden; 447 - clip: rect(0, 0, 0, 0); 448 - white-space: nowrap; 449 - border: 0; 450 - } 451 - 452 - /* Responsive adjustments */ 453 - @media (max-width: 640px) { 454 - .card-content { 455 - padding: 16px; 456 - min-height: 120px; 457 - } 458 - 459 - .card-title { 460 - font-size: 1rem; 461 - } 462 - 463 - .reading-stats { 464 - font-size: 0.85rem; 465 - } 466 - 467 - .milestone-banner { 468 - margin: -16px -16px 12px -16px; 469 - font-size: 0.8rem; 470 - } 471 - } 472 - </style> 22 + {:else if type === 'user'} 23 + <a 24 + href={url} 25 + class="block p-4 rounded-lg border hover:shadow-lg transition-shadow" 26 + style="background: var(--card-bg); border-color: var(--border-color);" 27 + > 28 + <h3 class="font-semibold text-lg mb-1">{title}</h3> 29 + <p class="text-sm text-link opacity-75 truncate">{url}</p> 30 + </a> 31 + {/if}
-35
src/lib/components/archive/MonthSection.svelte
··· 1 - <script lang="ts"> 2 - import { slide } from "svelte/transition"; 3 - 4 - import { quintOut } from "svelte/easing"; 5 - import { ArchiveCard } from "./index"; 6 - import StatsDisplay from "./StatsDisplay.svelte"; 7 - 8 - export let monthName: string; 9 - export let postsInMonth: any[]; 10 - export let monthIndex: number; 11 - export let localeLoaded: boolean; 12 - import { calculateTotalReadTime, calculateTotalWordCount, formatReadTime } from "$utils/tally"; 13 - 14 - $: rawTotalReadTime = calculateTotalReadTime(postsInMonth); 15 - $: totalReadTime = formatReadTime(rawTotalReadTime); 16 - $: totalWordCount = calculateTotalWordCount(postsInMonth); 17 - 18 - // Calculate the number of posts 19 - let postCount = postsInMonth.length; 20 - </script> 21 - 22 - <div 23 - class="mb-12 ml-4" 24 - in:slide={{ delay: 100 + monthIndex * 50, duration: 300, easing: quintOut }} 25 - > 26 - <h2 class="text-2xl font-bold mb-1 ml-2">{monthName}</h2> 27 - <StatsDisplay {totalReadTime} {totalWordCount} {postCount} /> 28 - <div 29 - class="grid grid-cols-[repeat(auto-fill,minmax(280px,1fr)_)] gap-x-6 gap-y-6 mx-4 my-8" 30 - > 31 - {#each postsInMonth as post, postIndex (post.rkey)} 32 - <ArchiveCard type="post" {post} {monthIndex} {postIndex} {localeLoaded} postNumber={post.postNumber} /> 33 - {/each} 34 - </div> 35 - </div>
-24
src/lib/components/archive/StatsDisplay.svelte
··· 1 - <script lang="ts"> 2 - import { formatNumber } from "$utils/formatters"; 3 - 4 - export let totalReadTime: string; 5 - export let totalWordCount: number; 6 - export let postCount: number | undefined = undefined; 7 - 8 - // Determine singular or plural for word count 9 - $: wordLabel = totalWordCount === 1 ? "word" : "words"; 10 - $: postLabel = postCount === 1 ? "post" : "posts"; 11 - </script> 12 - 13 - {#if postCount !== undefined} 14 - <p class="text-sm opacity-50 mb-4 ml-2"> 15 - {totalReadTime} read time โ€ข {formatNumber(totalWordCount)} 16 - {wordLabel} โ€ข {formatNumber(postCount)} 17 - {postLabel} 18 - </p> 19 - {:else} 20 - <div class="mb-6 ml-4 text-sm opacity-70"> 21 - <p>Total Read Time: {totalReadTime}</p> 22 - <p>Total Word Count: {formatNumber(totalWordCount)} {wordLabel}</p> 23 - </div> 24 - {/if}
+139
src/lib/components/archive/UserDirectory.svelte
··· 1 + <script lang="ts"> 2 + import { onMount } from "svelte"; 3 + import { goto } from "$app/navigation"; 4 + import type { User } from "$lib/components/shared/interfaces"; 5 + 6 + export let users: User[]; 7 + export let primaryUserDid: string | undefined; 8 + export let userLinkBoards: { [did: string]: LinkBoard | undefined }; 9 + export let displayBanner: boolean = false; 10 + export let displayDescription: boolean = false; 11 + import type { LinkBoard } from "$lib/components/shared/interfaces"; 12 + 13 + let loading = true; 14 + let userProfiles: any[] = []; 15 + 16 + onMount(async () => { 17 + if (users && users.length > 0) { 18 + const profiles = await Promise.all( 19 + users.map(async (user) => { 20 + let enrichedUser = { 21 + ...user, 22 + hasLinks: !!userLinkBoards?.[user.did]?.cards?.length 23 + }; 24 + 25 + try { 26 + const response = await fetch( 27 + `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${user.did}` 28 + ); 29 + if (response.ok) { 30 + const profile = await response.json(); 31 + return { 32 + ...enrichedUser, 33 + handle: profile.handle || user.handle, 34 + displayName: profile.displayName || user.displayName, 35 + avatar: profile.avatar, 36 + description: displayDescription ? profile.description : undefined, 37 + banner: profile.banner 38 + }; 39 + } 40 + } catch (error) { 41 + console.error(`Error fetching profile for ${user.did}:`, error); 42 + } 43 + 44 + return enrichedUser; // fallback if fetch fails 45 + }) 46 + ); 47 + userProfiles = profiles.filter(Boolean); 48 + } 49 + loading = false; 50 + }); 51 + 52 + function navigateToUser(user: any) { 53 + const userBoard = userLinkBoards[user.did]; 54 + if (userBoard && userBoard.cards?.length > 0) { 55 + goto(`/user/${encodeURIComponent(user.did)}`); 56 + } else { 57 + // Construct Bluesky profile URL 58 + const blueskyHandle = user.did; 59 + window.open(`https://bsky.app/profile/${blueskyHandle}`, '_blank'); 60 + } 61 + } 62 + </script> 63 + 64 + <div class="user-directory"> 65 + <h1 class="text-3xl font-bold mb-8 text-center">Users</h1> 66 + {#if loading} 67 + <div class="text-center py-8"> 68 + <p class="text-lg opacity-75">Loading user profiles...</p> 69 + </div> 70 + {:else if userProfiles.length === 0} 71 + <div class="text-center py-8"> 72 + <p class="text-lg opacity-75"> 73 + No users configured or found. Please check your configuration and ensure users have associated Linkat data. 74 + {#if primaryUserDid} 75 + <br />Directory owner is set to: {primaryUserDid} 76 + {:else} 77 + <br />No directory owner is set. 78 + {/if} 79 + </p> 80 + </div> 81 + {:else} 82 + <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> 83 + {#each userProfiles as user (user.did)} 84 + <button 85 + class="user-card cursor-pointer rounded-lg p-6 transition-transform hover:scale-105 text-left w-full" 86 + style="background: var(--card-bg); border: 1px solid var(--border-color);" 87 + on:click={() => navigateToUser(user)} 88 + > 89 + {#if displayBanner} 90 + <div 91 + class="w-full h-32 rounded-t-lg mb-4 bg-cover bg-center" 92 + style="background-image: url({user.banner});" 93 + ></div> 94 + {/if} 95 + 96 + <div class="flex items-start gap-4"> 97 + {#if user.avatar} 98 + <img 99 + src={user.avatar} 100 + alt={user.displayName || user.handle} 101 + class="w-16 h-16 rounded-full object-cover" 102 + /> 103 + {:else} 104 + <div class="w-16 h-16 rounded-full bg-[var(--muted-bg)] flex items-center justify-center"> 105 + <span class="text-2xl font-bold text-[var(--text-color)]"> 106 + {(user.displayName || user.handle || '?').charAt(0).toUpperCase()} 107 + </span> 108 + </div> 109 + {/if} 110 + 111 + <div class="flex-1 min-w-0"> 112 + <h3 class="font-bold text-lg truncate"> 113 + {user.displayName || user.handle || 'Unknown User'} 114 + </h3> 115 + <p class="text-sm opacity-75 truncate"> 116 + @{user.handle || user.did} 117 + </p> 118 + {#if displayDescription && user.description} 119 + <p class="text-[var(--text-color)] mt-2">{user.description}</p> 120 + {/if} 121 + </div> 122 + </div> 123 + 124 + <div class="mt-4 text-center"> 125 + {#if user.hasLinks} 126 + <span class="text-sm text-link hover:text-link-hover"> 127 + View links โ†’ 128 + </span> 129 + {:else} 130 + <span class="text-sm text-link hover:text-link-hover"> 131 + No links - View Bluesky profile โ†’ 132 + </span> 133 + {/if} 134 + </div> 135 + </button> 136 + {/each} 137 + </div> 138 + {/if} 139 + </div>
-39
src/lib/components/archive/YearContent.svelte
··· 1 - <script lang="ts"> 2 - import { fly, fade } from "svelte/transition"; 3 - import { quintOut } from "svelte/easing"; 4 - import MonthSection from "./MonthSection.svelte"; 5 - import { calculateTotalReadTime, calculateTotalWordCount, formatReadTime } from "$utils/tally"; 6 - import StatsDisplay from "./StatsDisplay.svelte"; 7 - 8 - export const year: number = 0; 9 - export let months: Record<string, any[]>; 10 - export let localeLoaded: boolean; 11 - 12 - // Calculate yearly totals 13 - $: rawYearlyTotalReadTime = Object.values(months).reduce((total, postsInMonth) => { 14 - return total + calculateTotalReadTime(postsInMonth); 15 - }, 0); 16 - $: yearlyTotalReadTime = formatReadTime(rawYearlyTotalReadTime); 17 - 18 - $: yearlyTotalWordCount = Object.values(months).reduce((total, postsInMonth) => { 19 - return total + calculateTotalWordCount(postsInMonth); 20 - }, 0); 21 - </script> 22 - 23 - <div 24 - in:fly={{ y: 20, duration: 300, delay: 50, easing: quintOut }} 25 - out:fade={{ duration: 200 }} 26 - class="year-content" 27 - > 28 - <StatsDisplay totalReadTime={yearlyTotalReadTime} totalWordCount={yearlyTotalWordCount} /> 29 - 30 - {#each Object.entries(months) as [monthName, postsInMonth], monthIndex} 31 - <MonthSection 32 - {monthName} 33 - {postsInMonth} 34 - {monthIndex} 35 - {localeLoaded} 36 - 37 - /> 38 - {/each} 39 - </div>
-62
src/lib/components/archive/YearTabs.svelte
··· 1 - <script lang="ts"> 2 - export let groupedByYear: any[]; 3 - export let activeYear: number; 4 - 5 - function setActiveYear(year: number) { 6 - activeYear = year; 7 - } 8 - 9 - // Calculate the active tab index more reliably 10 - $: activeTabIndex = groupedByYear.findIndex((g) => g.year === activeYear); 11 - $: indicatorLeft = activeTabIndex >= 0 ? activeTabIndex * 100 : 0; 12 - </script> 13 - 14 - <div 15 - class="flex mb-6 ml-4 border-b border-[var(--button-bg)] overflow-x-auto relative tabs-container" 16 - > 17 - <div class="tab-indicator-container absolute bottom-0 left-0 h-0.5 w-full"> 18 - <div 19 - class="tab-indicator bg-[var(--link-color)] h-full absolute bottom-0 transition-all duration-300 ease-out" 20 - style="left: {indicatorLeft}px; width: 100px;" 21 - ></div> 22 - </div> 23 - 24 - {#each groupedByYear as { year }, i} 25 - <button 26 - class="w-[100px] min-w-[100px] px-4 py-2 font-medium transition-all duration-300 relative z-10 text-center 27 - {activeYear === year 28 - ? 'text-[var(--link-color)]' 29 - : 'text-[var(--text-color)] opacity-80 hover:text-[var(--link-hover-color)]'}" 30 - onclick={() => setActiveYear(year)} 31 - > 32 - <span 33 - class="relative {activeYear === year 34 - ? 'transform transition-transform duration-300 scale-105' 35 - : ''}" 36 - > 37 - {year} 38 - </span> 39 - </button> 40 - {/each} 41 - </div> 42 - 43 - <style> 44 - /* Custom scrollbar styling for tabs container */ 45 - .tabs-container::-webkit-scrollbar { 46 - height: 6px; 47 - } 48 - 49 - .tabs-container::-webkit-scrollbar-track { 50 - background: var(--header-footer-bg); 51 - border-radius: 0px; 52 - } 53 - 54 - .tabs-container::-webkit-scrollbar-thumb { 55 - background: var(--button-bg); 56 - border-radius: 0px; 57 - } 58 - 59 - .tabs-container::-webkit-scrollbar-thumb:hover { 60 - background: var(--button-hover-bg); 61 - } 62 - </style>
-5
src/lib/components/archive/index.ts
··· 1 - export { default as YearTabs } from "./YearTabs.svelte"; 2 - export { default as YearContent } from "./YearContent.svelte"; 3 - export { default as MonthSection } from "./MonthSection.svelte"; 4 - export { default as ArchiveCard } from "./ArchiveCard.svelte"; 5 - export { default as StatsDisplay } from "./StatsDisplay.svelte";
-15
src/lib/components/icons/index.ts
··· 1 - export { default as BlueskyIcon } from "./social/BlueskyIcon.svelte"; 2 - export { default as FacebookIcon } from "./social/FacebookIcon.svelte"; 3 - export { default as MastodonIcon } from './social/MastodonIcon.svelte'; 4 - export { default as RedditIcon } from './social/RedditIcon.svelte'; 5 - export { default as RssIcon } from './social/RssIcon.svelte'; 6 - export { default as ShareIcons } from './social/ShareIcons.svelte'; 7 - export { default as BookOpenIcon } from './utility/BookOpenIcon.svelte'; 8 1 export { default as CopyLinkIcon } from './utility/CopyLinkIcon.svelte'; 9 2 export { default as HomeIcon } from './utility/HomeIcon.svelte'; 10 - export { default as LinkIcon } from './utility/LinkIcon.svelte'; 11 3 export { default as MoonIcon } from './utility/MoonIcon.svelte'; 12 - export { default as PostIcon } from './utility/PostIcon.svelte'; 13 4 export { default as SunIcon } from './utility/SunIcon.svelte'; 14 - export { default as DocumentIcon } from "./utility/DocumentIcon.svelte"; 15 - export { default as LinkExternalIcon } from "./utility/LinkExternalIcon.svelte"; 16 - export { default as CoffeeIcon } from "./utility/CoffeeIcon.svelte"; 17 - export { default as ClockIcon } from "./utility/ClockIcon.svelte"; 18 - export { default as BookIcon } from "./utility/BookIcon.svelte"; 19 - export { default as BooksIcon } from "./utility/BooksIcon.svelte"; 20 5 export { default as EditIcon } from "./utility/EditIcon.svelte";
-17
src/lib/components/icons/social/BlueskyIcon.svelte
··· 1 - <script> 2 - export let size = "18"; 3 - export let fill = "currentColor"; 4 - </script> 5 - 6 - <svg 7 - role="img" 8 - viewBox="0 0 24 24" 9 - xmlns="http://www.w3.org/2000/svg" 10 - width={size} 11 - height={size} 12 - {fill} 13 - > 14 - <path 15 - d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z" 16 - /> 17 - </svg>
-17
src/lib/components/icons/social/FacebookIcon.svelte
··· 1 - <script> 2 - export let size = "18"; 3 - export let fill = "currentColor"; 4 - </script> 5 - 6 - <svg 7 - role="img" 8 - viewBox="0 0 24 24" 9 - xmlns="http://www.w3.org/2000/svg" 10 - width={size} 11 - height={size} 12 - {fill} 13 - > 14 - <path 15 - d="M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z" 16 - /> 17 - </svg>
-17
src/lib/components/icons/social/MastodonIcon.svelte
··· 1 - <script> 2 - export let size = "18"; 3 - export let fill = "currentColor"; 4 - </script> 5 - 6 - <svg 7 - role="img" 8 - viewBox="0 0 24 24" 9 - xmlns="http://www.w3.org/2000/svg" 10 - width={size} 11 - height={size} 12 - {fill} 13 - > 14 - <path 15 - d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z" 16 - /> 17 - </svg>
-17
src/lib/components/icons/social/RedditIcon.svelte
··· 1 - <script> 2 - export let size = "18"; 3 - export let fill = "currentColor"; 4 - </script> 5 - 6 - <svg 7 - role="img" 8 - viewBox="0 0 24 24" 9 - xmlns="http://www.w3.org/2000/svg" 10 - width={size} 11 - height={size} 12 - {fill} 13 - > 14 - <path 15 - d="M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z" 16 - /> 17 - </svg>
-21
src/lib/components/icons/social/RssIcon.svelte
··· 1 - <script> 2 - export let size = "24"; 3 - export let stroke = "currentColor"; 4 - export let fill = "none"; 5 - </script> 6 - 7 - <svg 8 - xmlns="http://www.w3.org/2000/svg" 9 - width={size} 10 - height={size} 11 - viewBox="0 0 24 24" 12 - {fill} 13 - {stroke} 14 - stroke-width="2" 15 - stroke-linecap="round" 16 - stroke-linejoin="round" 17 - > 18 - <path d="M4 11a9 9 0 0 1 9 9" /> 19 - <path d="M4 4a16 16 0 0 1 16 16" /> 20 - <circle cx="5" cy="19" r="1" /> 21 - </svg>
-262
src/lib/components/icons/social/ShareIcons.svelte
··· 1 - <script lang="ts"> 2 - import { getStores } from "$app/stores"; 3 - const { page } = getStores(); 4 - import { env } from '$env/dynamic/public'; 5 - 6 - // Icons 7 - import { BlueskyIcon, FacebookIcon, RedditIcon, MastodonIcon, CopyLinkIcon } from "$components/icons"; 8 - 9 - // Props 10 - export let title: string; 11 - export let showInHeader: boolean = false; 12 - export let profile: { handle: string; displayName?: string }; 13 - export let mastodonInstance: string = "mastodon.social"; 14 - // Add fediverseCreator prop for Mastodon tagging 15 - let fediverseCreator: string | undefined = env.PUBLIC_ACTIVITYPUB_USER; 16 - 17 - $: mastodonUserTag = 18 - fediverseCreator && 19 - (fediverseCreator.startsWith("http://") || 20 - fediverseCreator.startsWith("https://")) 21 - ? fediverseCreator 22 - : fediverseCreator && fediverseCreator.startsWith("@") 23 - ? fediverseCreator 24 - : `@${fediverseCreator}`; 25 - 26 - // Define specific share texts for each platform 27 - $: blueskyShareText = `${title} by @${profile?.handle} - ${$page.url.href}`; 28 - $: mastodonShareText = 29 - mastodonUserTag 30 - ? mastodonUserTag.startsWith("http://") || 31 - mastodonUserTag.startsWith("https://") 32 - ? `${title} by ${mastodonUserTag} - ${$page.url.href}` 33 - : `${title} by ${mastodonUserTag} - ${$page.url.href}` 34 - : `${title} - ${$page.url.href}`; 35 - $: facebookShareText = `${title} - ${$page.url.href}`; 36 - $: redditShareText = `${title} - ${$page.url.href}`; 37 - 38 - // Truncate for character limits 39 - $: truncatedBlueskyText = 40 - blueskyShareText.length > 300 41 - ? blueskyShareText.substring(0, 297) + "..." 42 - : blueskyShareText; 43 - $: truncatedMastodonText = 44 - mastodonShareText && 45 - (mastodonShareText.length > 500 46 - ? mastodonShareText.substring(0, 497) + "..." 47 - : mastodonShareText); 48 - $: truncatedFacebookText = 49 - facebookShareText.length > 280 50 - ? facebookShareText.substring(0, 277) + "..." 51 - : facebookShareText; 52 - $: truncatedRedditText = 53 - redditShareText.length > 300 54 - ? redditShareText.substring(0, 297) + "..." 55 - : redditShareText; 56 - 57 - // Encode the share texts for use in URLs 58 - $: encodedBlueskyText = encodeURIComponent(truncatedBlueskyText); 59 - $: encodedMastodonText = 60 - mastodonShareText && encodeURIComponent(truncatedMastodonText); 61 - $: encodedFacebookText = encodeURIComponent(truncatedFacebookText); 62 - $: encodedRedditText = encodeURIComponent(truncatedRedditText); 63 - 64 - // Construct the Bluesky share URL 65 - $: blueskyShareUrl = `https://bsky.app/intent/compose?text=${encodedBlueskyText}`; 66 - 67 - // Construct the Reddit share URL 68 - $: redditShareUrl = `https://www.reddit.com/submit?url=${encodeURIComponent($page.url.href)}&title=${encodedRedditText}`; 69 - 70 - // Construct the Facebook share URL 71 - $: facebookShareUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent($page.url.href)}&quote=${encodedFacebookText}`; 72 - 73 - // Construct the Mastodon share URL 74 - $: mastodonShareUrl = 75 - mastodonShareText && 76 - `https://${mastodonInstance}/share?text=${encodedMastodonText}`; 77 - 78 - // Reactive statement to open Mastodon share URL when mastodonInstance changes 79 - let mastodonShareTrigger = false; 80 - $: if (mastodonShareTrigger && mastodonInstance && mastodonShareUrl) { 81 - window.open(mastodonShareUrl, "_blank", "noopener,noreferrer"); 82 - mastodonShareTrigger = false; // Reset trigger 83 - } 84 - 85 - // Copy Link 86 - let copyLinkText = "Copy Link"; 87 - let showCopyFeedback = false; 88 - 89 - const copyLink = async () => { 90 - try { 91 - await navigator.clipboard.writeText($page.url.href); 92 - copyLinkText = "Copied!"; 93 - showCopyFeedback = true; 94 - setTimeout(() => { 95 - showCopyFeedback = false; 96 - copyLinkText = "Copy Link"; 97 - }, 2000); 98 - } catch (err) { 99 - console.error("Failed to copy: ", err); 100 - copyLinkText = "Failed!"; 101 - showCopyFeedback = true; 102 - setTimeout(() => { 103 - showCopyFeedback = false; 104 - copyLinkText = "Copy Link"; 105 - }, 2000); 106 - } 107 - }; 108 - </script> 109 - 110 - <div 111 - class={`share-icons flex items-center gap-2 ${showInHeader ? "ml-auto mr-2" : "justify-center my-4"}`} 112 - > 113 - <!-- Bluesky Share Button --> 114 - <a 115 - href={blueskyShareUrl} 116 - target="_blank" 117 - rel="noopener noreferrer" 118 - class="icon-button p-2 rounded-full transition-all duration-300 hover:scale-110" 119 - style="background-color: var(--card-bg);" 120 - aria-label="Share on Bluesky" 121 - title="Share on Bluesky" 122 - > 123 - <BlueskyIcon /> 124 - </a> 125 - 126 - <!-- Facebook Share Button --> 127 - <a 128 - href={facebookShareUrl} 129 - target="_blank" 130 - rel="noopener noreferrer" 131 - class="icon-button p-2 rounded-full transition-all duration-300 hover:scale-110" 132 - style="background-color: var(--card-bg);" 133 - aria-label="Share on Facebook" 134 - title="Share on Facebook" 135 - > 136 - <FacebookIcon /> 137 - </a> 138 - 139 - <!-- Reddit Share Button --> 140 - <a 141 - href={redditShareUrl} 142 - target="_blank" 143 - rel="noopener noreferrer" 144 - class="icon-button p-2 rounded-full transition-all duration-300 hover:scale-110" 145 - style="background-color: var(--card-bg);" 146 - aria-label="Share on Reddit" 147 - title="Share on Reddit" 148 - > 149 - <RedditIcon /> 150 - </a> 151 - 152 - {#if env.PUBLIC_ACTIVITYPUB_USER && env.PUBLIC_ACTIVITYPUB_USER.length > 0} 153 - <button 154 - on:click|preventDefault={() => { 155 - const instance = prompt( 156 - "Enter your Mastodon instance (e.g. mastodon.social):", 157 - mastodonInstance 158 - ); 159 - if (instance) { 160 - mastodonInstance = instance; 161 - mastodonShareTrigger = true; 162 - } 163 - }} 164 - on:keydown={(e) => { 165 - if (e.key === "Enter" || e.key === " ") { 166 - const instance = prompt( 167 - "Enter your Mastodon instance (e.g. mastodon.social):", 168 - mastodonInstance 169 - ); 170 - if (instance) { 171 - mastodonInstance = instance; 172 - mastodonShareTrigger = true; 173 - } 174 - } 175 - }} 176 - class="icon-button p-2 rounded-full transition-all duration-300 hover:scale-110" 177 - style="background-color: var(--card-bg);" 178 - aria-label="Share on Mastodon" 179 - title="Share on Mastodon" 180 - tabindex="0" 181 - > 182 - <MastodonIcon /> 183 - </button> 184 - {/if} 185 - 186 - <!-- Copy Link Button --> 187 - <div class="relative flex items-center"> 188 - <button 189 - on:click={copyLink} 190 - class="icon-button p-2 rounded-full transition-all duration-300 hover:scale-110" 191 - style="background-color: var(--card-bg);" 192 - aria-label="Copy Link" 193 - title="Copy Link" 194 - > 195 - <CopyLinkIcon /> 196 - </button> 197 - {#if showCopyFeedback} 198 - <span 199 - class="copy-feedback absolute left-full ml-2 text-sm font-medium" 200 - class:copied={copyLinkText === 'Copied!'} 201 - class:failed={copyLinkText === 'Failed!'} 202 - > 203 - {copyLinkText} 204 - </span> 205 - {/if} 206 - </div> 207 - </div> 208 - 209 - <style> 210 - /* Common icon styling - this will match ThemeToggle.svelte */ 211 - .icon-button { 212 - color: var(--text-color); 213 - } 214 - 215 - .icon-button:hover { 216 - background-color: var(--button-hover-bg) !important; 217 - } 218 - 219 - /* Responsive adjustments */ 220 - @media (max-width: 640px) { 221 - .share-icons { 222 - gap: 0.5rem; 223 - } 224 - 225 - /* Hide copy feedback text on mobile */ 226 - .copy-feedback { 227 - display: none; 228 - } 229 - } 230 - 231 - .copy-feedback { 232 - opacity: 0; 233 - animation: fade-in-out 2s forwards; 234 - } 235 - 236 - .copy-feedback.copied { 237 - color: var(--accent-color); 238 - } 239 - 240 - .copy-feedback.failed { 241 - color: var(--error-color); 242 - } 243 - 244 - @keyframes fade-in-out { 245 - 0% { 246 - opacity: 0; 247 - transform: translateX(-10px); 248 - } 249 - 20% { 250 - opacity: 1; 251 - transform: translateX(0); 252 - } 253 - 80% { 254 - opacity: 1; 255 - transform: translateX(0); 256 - } 257 - 100% { 258 - opacity: 0; 259 - transform: translateX(10px); 260 - } 261 - } 262 - </style>
-20
src/lib/components/icons/utility/BookIcon.svelte
··· 1 - <script> 2 - export let size = "14"; 3 - export let fill = "none"; 4 - export let stroke = "currentColor"; 5 - export let strokeWidth = "2"; 6 - </script> 7 - 8 - <svg 9 - width={size} 10 - height={size} 11 - viewBox="0 0 24 24" 12 - {fill} 13 - {stroke} 14 - stroke-width={strokeWidth} 15 - stroke-linecap="round" 16 - stroke-linejoin="round" 17 - > 18 - <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" /> 19 - <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" /> 20 - </svg>
-21
src/lib/components/icons/utility/BookOpenIcon.svelte
··· 1 - <script> 2 - export let size = "24"; 3 - export let stroke = "currentColor"; 4 - export let fill = "none"; 5 - </script> 6 - 7 - <svg 8 - xmlns="http://www.w3.org/2000/svg" 9 - width={size} 10 - height={size} 11 - viewBox="0 0 24 24" 12 - {fill} 13 - {stroke} 14 - stroke-width="2" 15 - stroke-linecap="round" 16 - stroke-linejoin="round" 17 - class="feather feather-book-open" 18 - > 19 - <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /> 20 - <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /> 21 - </svg>
-20
src/lib/components/icons/utility/BooksIcon.svelte
··· 1 - <script> 2 - export let size = "14"; 3 - export let fill = "none"; 4 - export let stroke = "currentColor"; 5 - export let strokeWidth = "2"; 6 - </script> 7 - 8 - <svg 9 - width={size} 10 - height={size} 11 - viewBox="0 0 24 24" 12 - {fill} 13 - {stroke} 14 - stroke-width={strokeWidth} 15 - stroke-linecap="round" 16 - stroke-linejoin="round" 17 - > 18 - <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /> 19 - <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /> 20 - </svg>
-20
src/lib/components/icons/utility/ClockIcon.svelte
··· 1 - <script> 2 - export let size = "14"; 3 - export let fill = "none"; 4 - export let stroke = "currentColor"; 5 - export let strokeWidth = "2"; 6 - </script> 7 - 8 - <svg 9 - width={size} 10 - height={size} 11 - viewBox="0 0 24 24" 12 - {fill} 13 - {stroke} 14 - stroke-width={strokeWidth} 15 - stroke-linecap="round" 16 - stroke-linejoin="round" 17 - > 18 - <circle cx="12" cy="12" r="10" /> 19 - <polyline points="12,6 12,12 16,14" /> 20 - </svg>
-23
src/lib/components/icons/utility/CoffeeIcon.svelte
··· 1 - <script> 2 - export let size = "14"; 3 - export let fill = "none"; 4 - export let stroke = "currentColor"; 5 - export let strokeWidth = "2"; 6 - </script> 7 - 8 - <svg 9 - width={size} 10 - height={size} 11 - viewBox="0 0 24 24" 12 - {fill} 13 - {stroke} 14 - stroke-width={strokeWidth} 15 - stroke-linecap="round" 16 - stroke-linejoin="round" 17 - > 18 - <path d="M17 8h1a4 4 0 0 1 4 4v0a4 4 0 0 1-4 4h-1" /> 19 - <path d="M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4V8Z" /> 20 - <line x1="6" y1="2" x2="6" y2="4" /> 21 - <line x1="10" y1="2" x2="10" y2="4" /> 22 - <line x1="14" y1="2" x2="14" y2="4" /> 23 - </svg>
-23
src/lib/components/icons/utility/DocumentIcon.svelte
··· 1 - <script> 2 - export let size = "14"; 3 - export let fill = "none"; 4 - export let stroke = "currentColor"; 5 - export let strokeWidth = "2"; 6 - </script> 7 - 8 - <svg 9 - width={size} 10 - height={size} 11 - viewBox="0 0 24 24" 12 - {fill} 13 - {stroke} 14 - stroke-width={strokeWidth} 15 - stroke-linecap="round" 16 - stroke-linejoin="round" 17 - > 18 - <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /> 19 - <polyline points="14,2 14,8 20,8" /> 20 - <line x1="16" y1="13" x2="8" y2="13" /> 21 - <line x1="16" y1="17" x2="8" y2="17" /> 22 - <line x1="10" y1="9" x2="8" y2="9" /> 23 - </svg>
-9
src/lib/components/icons/utility/LinkIcon.svelte
··· 1 - <script lang="ts"> 2 - export let size: string = "14"; 3 - export let colour: string = "currentColor"; 4 - </script> 5 - 6 - <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={colour} stroke-width="2"> 7 - <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/> 8 - <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/> 9 - </svg>
-12
src/lib/components/icons/utility/PostIcon.svelte
··· 1 - <script lang="ts"> 2 - export let size: string = "14"; 3 - export let colour: string = "currentColor"; 4 - </script> 5 - 6 - <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={colour} stroke-width="2"> 7 - <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> 8 - <polyline points="14,2 14,8 20,8"/> 9 - <line x1="16" y1="13" x2="8" y2="13"/> 10 - <line x1="16" y1="17" x2="8" y2="17"/> 11 - <line x1="10" y1="9" x2="8" y2="9"/> 12 - </svg>
+57
src/lib/components/layout/DirectoryHeader.svelte
··· 1 + <script lang="ts"> 2 + import { env } from "$env/dynamic/public"; 3 + import { page } from "$app/stores"; 4 + import { getProfile } from "$components/profile/profile"; 5 + 6 + let isUserPage = $derived($page.route.id === '/user/[did]'); 7 + 8 + let profile = $state<{ displayName?: string; handle?: string } | null>(null); 9 + let loading = $state(true); 10 + let error = $state<string | null>(null); 11 + 12 + $effect(() => { 13 + if (env.DIRECTORY_OWNER) { 14 + loading = true; 15 + getProfile(fetch) 16 + .then((p) => { 17 + profile = p; 18 + error = null; 19 + }) 20 + .catch((err) => { 21 + console.error('Failed to load profile:', err); 22 + error = err.message; 23 + profile = null; 24 + }) 25 + .finally(() => { 26 + loading = false; 27 + }); 28 + } else { 29 + loading = false; 30 + } 31 + }); 32 + </script> 33 + 34 + <header class="py-4 px-4 sm:px-8 mb-6"> 35 + <div class="max-w-[1000px] mx-auto"> 36 + <div class="flex justify-between items-center mb-4"> 37 + <h1 class="text-lg font-semibold text-[var(--text-color)]"> 38 + {env.DIRECTORY_OWNER ? ( 39 + loading ? 'Loading...' : ( 40 + profile ? 41 + `${profile.displayName || profile.handle || env.DIRECTORY_OWNER}'s Linkat Directory` : 42 + `${env.DIRECTORY_OWNER}'s Linkat Directory` 43 + ) 44 + ) : 'Linkat Directory'} 45 + </h1> 46 + 47 + {#if isUserPage} 48 + <a 49 + href="/" 50 + class="text-sm text-link hover:text-link-hover transition-colors" 51 + > 52 + โ† Home 53 + </a> 54 + {/if} 55 + </div> 56 + </div> 57 + </header>
+61
src/lib/components/layout/DynamicHead.svelte
··· 1 + <script lang="ts"> 2 + import { getStores } from '$app/stores'; 3 + const { page } = getStores(); 4 + 5 + import type { DynamicHeadProps } from '$lib/components/shared/interfaces'; 6 + 7 + // Define props for dynamic head content 8 + let { 9 + title, 10 + description, 11 + keywords, 12 + ogUrl = $page.url.origin + $page.url.pathname, 13 + ogTitle, 14 + ogDescription, 15 + ogImage, 16 + ogImageWidth = '1200', 17 + ogImageHeight = '630', 18 + twitterCard = 'summary_large_image', 19 + twitterUrl = $page.url.origin + $page.url.pathname, 20 + twitterTitle, 21 + twitterDescription, 22 + twitterImage 23 + }: DynamicHeadProps = $props(); 24 + 25 + // Fallback for Open Graph and Twitter titles/descriptions if not provided 26 + ogTitle = ogTitle || title; 27 + ogDescription = ogDescription || description; 28 + twitterTitle = twitterTitle || title; 29 + twitterDescription = twitterDescription || description; 30 + </script> 31 + 32 + <svelte:head> 33 + <title>{title}</title> 34 + {#if description} 35 + <meta name="description" content={description} /> 36 + {/if} 37 + {#if keywords} 38 + <meta name="keywords" content={keywords} /> 39 + {/if} 40 + 41 + <!-- Open Graph / Facebook --> 42 + <meta property="og:type" content="website" /> 43 + <meta property="og:url" content={ogUrl} /> 44 + <meta property="og:title" content={ogTitle} /> 45 + <meta property="og:description" content={ogDescription} /> 46 + <meta property="og:site_name" content="Linkat Directory" /> 47 + {#if ogImage} 48 + <meta property="og:image" content={ogImage} /> 49 + <meta property="og:image:width" content={ogImageWidth} /> 50 + <meta property="og:image:height" content={ogImageHeight} /> 51 + {/if} 52 + 53 + <!-- Twitter --> 54 + <meta name="twitter:card" content={twitterCard} /> 55 + <meta name="twitter:url" content={twitterUrl} /> 56 + <meta name="twitter:title" content={twitterTitle} /> 57 + <meta name="twitter:description" content={twitterDescription} /> 58 + {#if twitterImage} 59 + <meta name="twitter:image" content={twitterImage} /> 60 + {/if} 61 + </svelte:head>
+2 -29
src/lib/components/layout/Navigation.svelte
··· 1 1 <script lang="ts"> 2 2 import { getStores } from "$app/stores"; 3 3 const { page } = getStores(); 4 - import ThemeToggle from "./ThemeToggle.svelte"; 5 - import { HomeIcon, RssIcon, BookOpenIcon } from "$components/icons"; 6 - 7 - export const isHomePage: boolean = false; 8 - export let isBlogIndex: boolean = false; 4 + import { HomeIcon } from "$components/icons"; 9 5 10 - // Reactive statement to get the origin without http:// or https:// 11 - $: cleanOrigin = $page.url.origin.replace(/^https?:\/\//, ''); 6 + let {} = $props(); 12 7 </script> 13 8 14 9 <nav class="flex items-center box-border my-6"> ··· 22 17 <HomeIcon /> 23 18 </a> 24 19 {/if} 25 - {#if isBlogIndex} 26 - <!-- RSS Feed Link --> 27 - <a 28 - href="{$page.url.origin}/blog/rss" 29 - class="font-medium text-[large] hover:text-[var(--link-hover-color)]" 30 - aria-label="RSS Feed" 31 - download="{cleanOrigin}_Blog.rss" 32 - > 33 - <RssIcon /> 34 - </a> 35 - {/if} 36 - {#if $page.url.pathname.startsWith("/blog/") && $page.url.pathname !== "/blog/"} 37 - <a 38 - href="/blog" 39 - class="flex items-center gap-2 text-sm text-[var(--text-color)] hover:text-[var(--link-hover-color)]" 40 - aria-label="Back to blog" 41 - > 42 - <BookOpenIcon /> 43 - </a> 44 - {/if} 45 20 </div> 46 - <div class="ml-auto"></div> 47 - <ThemeToggle /> 48 21 </nav>
-152
src/lib/components/layout/ThemeToggle.svelte
··· 1 - <script lang="ts"> 2 - import { onMount } from "svelte"; 3 - import { SunIcon, MoonIcon } from "$components/icons"; 4 - import EditIcon from "$components/icons/utility/EditIcon.svelte"; 5 - import { 6 - THEMES, 7 - applyTheme, 8 - getThemePreferences, 9 - saveThemePreferences, 10 - updateThemeColorMeta, 11 - dispatchThemeChangeEvent, 12 - setupSystemThemeListener 13 - } from "../../themeLoader"; 14 - 15 - let isDarkMode: boolean = true; 16 - let currentTheme: string = "default"; 17 - let isDropdownOpen: boolean = false; 18 - 19 - onMount(() => { 20 - // Retrieve current theme preferences (already applied by theme-loader) 21 - const preferences = getThemePreferences(); 22 - isDarkMode = preferences.isDarkMode; 23 - currentTheme = preferences.themeId; 24 - 25 - // Update meta tag and dispatch a theme change event 26 - updateThemeColorMeta(); 27 - dispatchThemeChangeEvent(isDarkMode, currentTheme); 28 - 29 - // Set up system theme listener 30 - setupSystemThemeListener(); 31 - 32 - // Close dropdown when clicking outside the theme controls 33 - document.addEventListener("click", (e: MouseEvent) => { 34 - const themeControls = document.querySelector(".theme-controls"); 35 - if ( 36 - isDropdownOpen && 37 - themeControls && 38 - !e.composedPath().includes(themeControls) 39 - ) { 40 - isDropdownOpen = false; 41 - } 42 - }); 43 - }); 44 - 45 - function toggleTheme(): void { 46 - isDarkMode = !isDarkMode; 47 - applyTheme(isDarkMode, currentTheme); 48 - saveThemePreferences(isDarkMode, currentTheme); 49 - updateThemeColorMeta(); 50 - dispatchThemeChangeEvent(isDarkMode, currentTheme); 51 - } 52 - 53 - // Change the colour theme 54 - function changeColorTheme(themeId: string): void { 55 - currentTheme = themeId; 56 - applyTheme(isDarkMode, currentTheme); 57 - saveThemePreferences(isDarkMode, currentTheme); 58 - updateThemeColorMeta(); 59 - dispatchThemeChangeEvent(isDarkMode, currentTheme); 60 - isDropdownOpen = false; 61 - } 62 - 63 - // Toggle the dropdown for theme selection 64 - function toggleDropdown(e: MouseEvent): void { 65 - e.stopPropagation(); 66 - isDropdownOpen = !isDropdownOpen; 67 - } 68 - </script> 69 - 70 - <div class="theme-controls relative"> 71 - <div class="flex items-center gap-2"> 72 - <button 73 - onclick={toggleDropdown} 74 - class="icon-button p-2 rounded-full transition-all duration-300 hover:scale-110" 75 - style="background-color: var(--card-bg);" 76 - aria-label="Change theme" 77 - aria-expanded={isDropdownOpen} 78 - > 79 - <EditIcon size="20" stroke="var(--text-color)" /> 80 - </button> 81 - 82 - <button 83 - onclick={toggleTheme} 84 - class="icon-button p-2 rounded-full transition-all duration-300 hover:scale-110" 85 - style="background-color: var(--card-bg);" 86 - aria-label={isDarkMode ? "Switch to light mode" : "Switch to dark mode"} 87 - > 88 - {#if isDarkMode} 89 - <!-- Sun icon for switching to light mode --> 90 - <SunIcon stroke="var(--text-color)" /> 91 - {:else} 92 - <!-- Moon icon for switching to dark mode --> 93 - <MoonIcon stroke="var(--text-color)" /> 94 - {/if} 95 - </button> 96 - </div> 97 - 98 - {#if isDropdownOpen} 99 - <div 100 - class="theme-dropdown absolute right-0 mt-2 py-2 w-48 rounded shadow-lg z-10" 101 - style="background-color: var(--card-bg); border: 1px solid var(--button-bg);" 102 - > 103 - <div class="max-h-80 overflow-y-auto"> 104 - {#each THEMES as theme} 105 - <button 106 - class="theme-option w-full text-left px-4 py-2 transition-colors duration-200" 107 - class:active={currentTheme === theme.id} 108 - onclick={() => changeColorTheme(theme.id)} 109 - > 110 - {theme.name} 111 - </button> 112 - {/each} 113 - </div> 114 - </div> 115 - {/if} 116 - </div> 117 - 118 - <style> 119 - /* Common icon styling */ 120 - .icon-button { 121 - color: var(--text-color); 122 - } 123 - 124 - .icon-button:hover { 125 - background-color: var(--button-hover-bg) !important; 126 - } 127 - 128 - .theme-option { 129 - color: var(--text-color); 130 - } 131 - 132 - .theme-option:hover { 133 - background-color: var(--button-bg); 134 - } 135 - 136 - .theme-option.active { 137 - background-color: var(--button-hover-bg); 138 - font-weight: 500; 139 - } 140 - 141 - .theme-dropdown { 142 - max-height: 80vh; 143 - } 144 - 145 - /* Responsive adjustments */ 146 - @media (max-width: 640px) { 147 - .theme-dropdown { 148 - width: 12rem; 149 - right: 0; 150 - } 151 - } 152 - </style>
+47 -48
src/lib/components/layout/footer/Main.svelte
··· 1 1 <script lang="ts"> 2 2 import { onMount } from "svelte"; 3 - import { env } from "$env/dynamic/public"; 4 - import TidClock from "./TidClock.svelte"; 5 3 6 4 export let profile: any; 7 - export const posts: any = undefined; 5 + let showDetails = false; 8 6 9 7 onMount(() => { 10 8 const copyrightYearElement = document.getElementById("copyright-year"); ··· 12 10 copyrightYearElement.textContent = new Date().getFullYear().toString(); 13 11 } 14 12 }); 13 + 14 + function toggleDetails() { 15 + showDetails = !showDetails; 16 + } 15 17 </script> 16 18 17 - <footer class="text-center py-4 text-primary text-sm opacity-60"> 18 - <div class="flex flex-col justify-center items-center gap-2"> 19 - <div> 19 + <footer class="text-center py-6 text-primary text-sm opacity-60"> 20 + <div class="max-w-2xl mx-auto px-4"> 21 + <!-- Main footer line --> 22 + <div class="mb-3"> 20 23 <span>&copy; <span id="copyright-year"></span></span> 21 - 22 - <span class="mx-1"></span> 23 - 24 24 {#if profile?.handle} 25 + <span class="mx-2">โ€ข</span> 25 26 <a 26 27 href="https://bsky.app/profile/{profile.did}" 27 - class="text-[var(--link-color)] hover:text-[var(--link-hover-color)]" 28 + class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] transition-colors" 28 29 > 29 30 @{profile.handle} 30 31 </a> 31 - {:else} 32 - <span>{profile?.displayName || profile?.did}</span> 33 32 {/if} 34 - 35 - {#if env.PUBLIC_ACTIVITYPUB_USER && env.PUBLIC_ACTIVITYPUB_USER.length > 0 && profile?.handle} 36 - <span class="mx-1"></span> 37 - {/if} 38 - 39 - {#if env.PUBLIC_ACTIVITYPUB_USER && env.PUBLIC_ACTIVITYPUB_USER.length > 0} 40 - <a 41 - rel="me" 42 - href={`https://${env.PUBLIC_ACTIVITYPUB_USER.split("@")[2]}/@${env.PUBLIC_ACTIVITYPUB_USER.split("@")[1]}`} 43 - class="text-[var(--link-color)] hover:text-[var(--link-hover-color)]" 44 - > 45 - @{env.PUBLIC_ACTIVITYPUB_USER.split( 46 - "@", 47 - )[1]}@{env.PUBLIC_ACTIVITYPUB_USER.split("@")[2]} 48 - </a> 49 - {/if} 50 - </div> 51 - 52 - <div> 53 - <span 54 - >powered by <a 55 - class="text-[var(--link-color)] hover:text-[var(--link-hover-color)]" 56 - href="https://atproto.com/guides/glossary#at-protocol">atproto</a 57 - ></span 33 + <span class="mx-2">โ€ข</span> 34 + <button 35 + class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] transition-colors underline bg-none border-none cursor-pointer text-sm" 36 + on:click={toggleDetails} 58 37 > 38 + {showDetails ? 'Hide details' : 'About'} 39 + </button> 59 40 </div> 60 41 61 - <div> 62 - <span>template made by <a 63 - class="text-[var(--link-color)] hover:text-[var(--link-hover-color)]" 64 - href="https://bsky.app/profile/did:plc:ofrbh253gwicbkc5nktqepol">ewan</a 65 - ></span> 66 - </div> 67 - 68 - <div> 69 - <span class="mx-1"></span> 70 - <TidClock /> 71 - </div> 42 + <!-- Collapsible details --> 43 + {#if showDetails} 44 + <div class="text-xs opacity-75 leading-relaxed space-y-2 transition-all duration-200"> 45 + <div> 46 + Linkat Directory made by 47 + <a 48 + class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] transition-colors" 49 + href="https://bsky.app/profile/did:plc:ofrbh253gwicbkc5nktqepol" 50 + > 51 + ewan 52 + </a> 53 + </div> 54 + <div> 55 + <a 56 + class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] transition-colors" 57 + href="https://github.com/ewanc26/linkat-directory" 58 + > 59 + Open source 60 + </a> 61 + and free to use under AGPL-3.0. Not affiliated with 62 + <a 63 + class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] transition-colors" 64 + href="https://linkat.blue" 65 + > 66 + Linkat 67 + </a> 68 + </div> 69 + </div> 70 + {/if} 72 71 </div> 73 - </footer> 72 + </footer>
-96
src/lib/components/layout/footer/TidClock.svelte
··· 1 - <script lang="ts"> 2 - import { onMount, onDestroy } from "svelte"; 3 - 4 - let currentTID = ''; 5 - let interval: NodeJS.Timeout; 6 - let isRunning = true; 7 - 8 - // Base32-sortable character set for TID encoding 9 - const BASE32_SORTABLE = '234567abcdefghijklmnopqrstuvwxyz'; 10 - 11 - /** 12 - * Generate a random 10-bit clock identifier 13 - */ 14 - function generateClockId(): number { 15 - return Math.floor(Math.random() * 1024); // 2^10 = 1024 16 - } 17 - 18 - /** 19 - * Convert a number to base32-sortable encoding 20 - */ 21 - function toBase32Sortable(num: bigint): string { 22 - if (num === 0n) { 23 - return '2222222222222'; 24 - } 25 - 26 - let result = ''; 27 - while (num > 0n) { 28 - result = BASE32_SORTABLE[Number(num % 32n)] + result; 29 - num = num / 32n; 30 - } 31 - 32 - // Pad to 13 characters for consistent TID length 33 - return result.padStart(13, '2'); 34 - } 35 - 36 - /** 37 - * Generate a TID for the current timestamp 38 - */ 39 - function generateTID(): string { 40 - // Get current timestamp in microseconds since UNIX epoch 41 - const nowMs = Date.now(); 42 - const nowMicroseconds = BigInt(nowMs * 1000); // Convert to microseconds 43 - 44 - // Generate random clock identifier (10 bits) 45 - const clockId = generateClockId(); 46 - 47 - // Combine timestamp (53 bits) and clock identifier (10 bits) 48 - // The top bit is always 0, so we have 63 bits in total 49 - const tidBigInt = (nowMicroseconds << 10n) | BigInt(clockId); 50 - 51 - return toBase32Sortable(tidBigInt); 52 - } 53 - 54 - /** 55 - * Update the TID display value 56 - */ 57 - function updateTID() { 58 - if (isRunning) { 59 - currentTID = generateTID(); 60 - } 61 - } 62 - 63 - /** 64 - * Copy the TID to the clipboard 65 - */ 66 - async function copyTID() { 67 - try { 68 - await navigator.clipboard.writeText(currentTID); 69 - console.log('TID copied to clipboard:', currentTID); 70 - } catch (err) { 71 - console.error('Failed to copy TID:', err); 72 - } 73 - } 74 - 75 - onMount(() => { 76 - // Generate initial TID 77 - updateTID(); 78 - 79 - // Update every 100ms for a smooth display 80 - interval = setInterval(updateTID, 100); 81 - }); 82 - 83 - onDestroy(() => { 84 - if (interval) { 85 - clearInterval(interval); 86 - } 87 - }); 88 - </script> 89 - 90 - <button 91 - class="inline-block bg-none border-none text-[var(--link-color)] font-mono text-xs cursor-pointer px-0.5 py-0 rounded-md transition-all duration-200 ease-in-out hover:text-[var(--link-hover-color)] hover:bg-[var(--button-bg)]" 92 - on:click={copyTID} 93 - title="Click to copy TID" 94 - > 95 - {currentTID} 96 - </button>
-1
src/lib/components/layout/index.ts
··· 1 1 export { default as Navigation } from "./Navigation.svelte"; 2 2 export { default as Footer } from "./footer/Main.svelte"; 3 - export { default as ThemeToggle } from "./ThemeToggle.svelte";
+7 -2
src/lib/components/layout/main/DynamicLinks.svelte
··· 1 1 <script lang="ts"> 2 - import { ArchiveCard } from "$components/archive"; 2 + import ArchiveCard from "$lib/components/archive/ArchiveCard.svelte"; 3 3 import type { LinkBoard } from "$components/shared"; 4 4 5 5 // Export the data prop that will receive the fetched links ··· 12 12 class="grid grid-cols-[repeat(auto-fill,minmax(260px,1fr)_)] gap-x-6 gap-y-6 my-6" 13 13 > 14 14 {#each data.cards as link} 15 - <ArchiveCard type="link" url={link.url} title={link.text} value={link.emoji} /> 15 + <ArchiveCard 16 + type="link" 17 + url={link.url} 18 + title={link.text} 19 + value={link.emoji} 20 + /> 16 21 {/each} 17 22 </div> 18 23 </div>
-102
src/lib/components/layout/main/LatestBlogPost.svelte
··· 1 - <script lang="ts"> 2 - import { slide } from "svelte/transition"; 3 - import { quintOut } from "svelte/easing"; 4 - import { ArchiveCard } from "$components/archive"; 5 - import type { Post } from "$components/shared"; 6 - 7 - export let posts: Post[] = []; 8 - export let localeLoaded: boolean = false; 9 - 10 - // Get the latest post with proper validation 11 - $: latestPost = posts && posts.length > 0 ? posts[0] : null; 12 - 13 - // Additional validation to ensure the post has valid data 14 - $: isValidPost = latestPost && 15 - latestPost.title && 16 - latestPost.createdAt instanceof Date && 17 - !isNaN(latestPost.createdAt.getTime()) && 18 - latestPost.content; 19 - 20 - // Use the postNumber from the latestPost object 21 - $: postNumber = latestPost ? latestPost.postNumber : null; 22 - </script> 23 - 24 - {#if isValidPost} 25 - <section 26 - class="latest-blog-post" 27 - in:slide={{ delay: 200, duration: 400, easing: quintOut }} 28 - > 29 - <div class="section-header"> 30 - <h2 class="section-title">Latest Blog Post</h2> 31 - </div> 32 - 33 - <div class="latest-post-container"> 34 - <ArchiveCard 35 - type="post" 36 - post={latestPost} 37 - monthIndex={0} 38 - postIndex={0} 39 - postNumber={postNumber} 40 - {localeLoaded} 41 - /> 42 - </div> 43 - </section> 44 - {/if} 45 - 46 - <style> 47 - .latest-blog-post { 48 - margin-bottom: 3rem; 49 - } 50 - 51 - .section-header { 52 - display: flex; 53 - align-items: center; 54 - justify-content: space-between; 55 - margin-bottom: 1.5rem; 56 - padding: 0; 57 - } 58 - 59 - .section-title { 60 - margin: 0; 61 - font-size: 1.75rem; 62 - font-weight: 700; 63 - color: var(--text-color); 64 - position: relative; 65 - } 66 - 67 - .section-title::after { 68 - content: ''; 69 - position: absolute; 70 - bottom: -4px; 71 - left: 0; 72 - width: 3rem; 73 - height: 3px; 74 - background: var(--link-color); 75 - border-radius: 0px; 76 - } 77 - 78 - .latest-post-container { 79 - display: grid; 80 - grid-template-columns: 1fr; 81 - max-width: 400px; 82 - } 83 - 84 - /* Responsive adjustments */ 85 - @media (max-width: 640px) { 86 - .section-header { 87 - flex-direction: column; 88 - align-items: flex-start; 89 - gap: 1rem; 90 - } 91 - 92 - .section-title { 93 - font-size: 1.5rem; 94 - } 95 - } 96 - 97 - @media (min-width: 768px) { 98 - .latest-post-container { 99 - max-width: 420px; 100 - } 101 - } 102 - </style>
+61
src/lib/components/layout/main/MultiUserLinks.svelte
··· 1 + <script lang="ts"> 2 + import ArchiveCard from "$lib/components/archive/ArchiveCard.svelte"; 3 + import type { LinkBoard } from "$components/shared"; 4 + 5 + // Props that will receive the fetched links for multiple users 6 + let { userLinkBoards = {}, profile }: { 7 + userLinkBoards?: { [did: string]: LinkBoard | undefined }, 8 + profile: any 9 + } = $props(); 10 + 11 + // Filter out undefined boards and create a clean array 12 + let validBoards = $derived(Object.entries(userLinkBoards) 13 + .filter(([, board]) => board && board.cards && board.cards.length > 0) 14 + .map(([did, board]) => ({ did, board: board! }))); 15 + 16 + // Helper function to format user display name 17 + function getUserDisplayName(did: string): string { 18 + if (did === profile.did) { 19 + return profile.displayName || "My Links"; 20 + } 21 + // For now, use shortened DID for other users 22 + // In a future enhancement, we could fetch their profile info 23 + return `User ${did.slice(-8)}`; 24 + } 25 + </script> 26 + 27 + {#if validBoards.length > 0} 28 + <div class="space-y-8"> 29 + {#each validBoards as { did, board } (did)} 30 + <div class="user-links-section"> 31 + {#if validBoards.length > 1} 32 + <!-- Show user header only when there are multiple users --> 33 + <div class="flex items-center mb-4"> 34 + <h3 class="text-lg font-semibold text-[var(--text-color)]"> 35 + {getUserDisplayName(did)} 36 + </h3> 37 + <span class="ml-2 text-sm text-[var(--text-color-secondary)]"> 38 + ({board.cards.length} link{board.cards.length !== 1 ? 's' : ''}) 39 + </span> 40 + </div> 41 + {:else} 42 + <!-- Single user - add some top margin for spacing --> 43 + <div class="mb-4"></div> 44 + {/if} 45 + 46 + <div 47 + class="grid grid-cols-[repeat(auto-fill,minmax(260px,1fr)_)] gap-x-6 gap-y-6" 48 + > 49 + {#each board.cards as link} 50 + <ArchiveCard type="link" url={link.url} title={link.text} value={link.emoji} /> 51 + {/each} 52 + </div> 53 + </div> 54 + {/each} 55 + </div> 56 + {:else} 57 + <!-- Placeholder for blue.linkat.board --> 58 + <div class="mb-12 ml-4 text-center text-sm italic opacity-75"> 59 + create <code>blue.linkat.board</code> records at <a href="https://linkat.blue/" class="text-link hover:text-link-hover">https://linkat.blue/</a> 60 + </div> 61 + {/if}
+1 -2
src/lib/components/layout/main/index.ts
··· 1 - export { default as DynamicLinks } from "./DynamicLinks.svelte"; 2 - export { default as LatestBlogPost } from "./LatestBlogPost.svelte"; 1 + export { default as DynamicLinks } from "./DynamicLinks.svelte";
-11
src/lib/components/post/PostContent.svelte
··· 1 - <script lang="ts"> 2 - import type { Post } from "$components/shared"; 3 - 4 - export let post: Post; 5 - </script> 6 - 7 - <hr class="my-6 border-[var(--button-bg)]" /> 8 - <article class="prose dark:prose-invert mx-auto text-center"> 9 - {@html post.content} 10 - </article> 11 - <hr class="my-6 border-[var(--button-bg)]" />
-62
src/lib/components/post/PostHead.svelte
··· 1 - <script lang="ts"> 2 - import { getStores } from "$app/stores"; 3 - const { page } = getStores(); 4 - import type { Post } from "$components/shared"; 5 - import { env } from "$env/dynamic/public"; 6 - 7 - export let post: Post | undefined; 8 - </script> 9 - 10 - <svelte:head> 11 - {#if post !== undefined} 12 - <title>{post?.title} - Blog - Site Name</title> 13 - <meta name="description" content={post.excerpt} /> 14 - <meta 15 - name="keywords" 16 - content="personal blog, Blog - Site Name" 17 - /> 18 - 19 - <!-- Open Graph / Facebook --> 20 - <meta property="og:type" content="article" /> 21 - <meta property="og:url" content={$page.url.origin + $page.url.pathname} /> 22 - <meta 23 - property="og:title" 24 - content={`${post.title} - Blog - Site Name`} 25 - /> 26 - <meta property="og:description" content={post.excerpt} /> 27 - <meta property="og:site_name" content="Blog - Site Name" /> 28 - {#if $page.url.origin} 29 - <meta property="og:image" content={$page.url.origin + "/embed/blog.png"} /> 30 - {/if} 31 - <meta property="og:image:width" content="1200" /> 32 - <meta property="og:image:height" content="630" /> 33 - <meta 34 - property="article:published_time" 35 - content={post.createdAt.toISOString()} 36 - /> 37 - <meta property="article:word_count" content={post.wordCount.toString()} /> 38 - 39 - <!-- Fediverse --> 40 - {#if env.PUBLIC_ACTIVITYPUB_USER && env.PUBLIC_ACTIVITYPUB_USER.length > 0} 41 - <meta name="fediverse:creator" content={env.PUBLIC_ACTIVITYPUB_USER}> 42 - {/if} 43 - 44 - <!-- Twitter --> 45 - <meta name="twitter:card" content="summary_large_image" /> 46 - <meta name="twitter:url" content={$page.url.origin + $page.url.pathname} /> 47 - <meta 48 - name="twitter:title" 49 - content={`${post.title} - Blog - Site Name`} 50 - /> 51 - <meta name="twitter:description" content={post.excerpt} /> 52 - {#if $page.url.origin} 53 - <meta name="twitter:image" content={$page.url.origin + "/embed/blog.png"} /> 54 - {/if} 55 - {:else} 56 - <title>Post Not Found - Blog - Site Name</title> 57 - <meta 58 - name="description" 59 - content="The requested blog post could not be found." 60 - /> 61 - {/if} 62 - </svelte:head>
-100
src/lib/components/post/PostHeader.svelte
··· 1 - <script lang="ts"> 2 - import { fade } from "svelte/transition"; 3 - import { formatRelativeTime, formatDate } from "$utils/formatters"; 4 - import { ShareIcons } from "$components/icons"; 5 - import { formatNumber } from "$utils/formatters"; 6 - import type { Post } from "$components/shared"; 7 - import { onMount } from 'svelte'; 8 - 9 - let { post, profile, rkey, localeLoaded } = $props<{ 10 - post: Post; 11 - profile: any; 12 - rkey: string; 13 - localeLoaded: boolean; 14 - }>(); 15 - 16 - // Determine singular or plural for word count 17 - let wordLabel = post.wordCount === 1 ? "word" : "words"; 18 - 19 - let displayDate = $derived(localeLoaded && post.createdAt ? formatRelativeTime(post.createdAt) : 'datetime loading...'); 20 - let absoluteDisplayDate = $derived(localeLoaded && post.createdAt ? formatDate(new Date(post.createdAt)) : 'datetime loading...'); 21 - 22 - let fediverseCreator = $state(''); 23 - 24 - onMount(() => { 25 - const metaTag = document.querySelector('meta[name="fediverse:creator"]'); 26 - if (metaTag) { 27 - fediverseCreator = metaTag.getAttribute('content') || ''; 28 - } else if (profile?.did) { 29 - fediverseCreator = `https://bsky.app/profile/${profile.handle}`; 30 - } 31 - }); 32 - </script> 33 - 34 - <!-- Title with more breathing room --> 35 - <div class="flex items-center justify-between"> 36 - <div class="flex-1"></div> 37 - <h1 class="text-center my-12 flex-grow leading-relaxed">{post.title}</h1> 38 - <div class="flex-1"></div> 39 - </div> 40 - 41 - <!-- Metadata section with improved spacing and grouping --> 42 - <div class="text-center text-[var(--text-color)] opacity-80 mb-12 space-y-4"> 43 - <!-- Author and date info --> 44 - <div class="space-y-2"> 45 - <p class="text-base"> 46 - last updated by <a 47 - href={`https://bsky.app/profile/${profile?.handle}`} 48 - class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] font-medium" 49 - >{#key profile?.displayName} 50 - <span transition:fade={{ duration: 200 }}>{profile?.displayName}</span> 51 - {/key}</a 52 - > 53 - <span transition:fade={{ duration: 200 }}>{displayDate}</span> 54 - </p> 55 - <p class="text-sm opacity-70"> 56 - <span transition:fade={{ duration: 200 }}>({absoluteDisplayDate})</span> 57 - </p> 58 - </div> 59 - 60 - <!-- Links section with subtle separation --> 61 - <div class="pt-3 mt-1"> 62 - <p class="text-sm opacity-75"> 63 - View on <a 64 - href={`https://whtwnd.nat.vg/${profile?.did}/${rkey}`} 65 - onerror={(e) => { 66 - e.preventDefault(); 67 - if (e.target instanceof HTMLAnchorElement) { 68 - e.target.href = `https://whtwnd.com/${profile?.did}/${rkey}`; 69 - } 70 - }} 71 - class="hover:text-[var(--link-hover-color)] underline decoration-dotted">WhiteWind</a 72 - > 73 - or see the record at 74 - <a 75 - href={`https://atproto.at/viewer?uri=${profile?.did}/com.whtwnd.blog.entry/${rkey}`} 76 - onerror={(e) => { 77 - e.preventDefault(); 78 - if (e.target instanceof HTMLAnchorElement) { 79 - e.target.href = `https://pdsls.dev/at://${profile?.did}/com.whtwnd.blog.entry/${rkey}`; 80 - e.target.textContent = 'PDSls'; 81 - } 82 - }} 83 - class="hover:text-[var(--link-hover-color)] underline decoration-dotted">atproto.at</a 84 - > 85 - </p> 86 - </div> 87 - 88 - <!-- Reading time with subtle emphasis --> 89 - <div class="px-2 py-1 inline-block"> 90 - <p class="text-sm opacity-70"> 91 - {Math.ceil(post.wordCount / 200)} min read โ€ข {formatNumber(post.wordCount)} 92 - {wordLabel} 93 - </p> 94 - </div> 95 - 96 - <!-- Share icons with reduced spacing --> 97 - <div class="pt-1"> 98 - <ShareIcons title={post.title} {profile} /> 99 - </div> 100 - </div>
-34
src/lib/components/post/PostNavigation.svelte
··· 1 - <script lang="ts"> 2 - import type { Post } from "$components/shared"; 3 - 4 - export let adjacentPosts: { 5 - previous: Post | null; 6 - next: Post | null; 7 - }; 8 - </script> 9 - 10 - <div class="flex justify-between mt-8 mb-8 gap-4"> 11 - {#if adjacentPosts.previous} 12 - <a 13 - href="/blog/{adjacentPosts.previous.rkey}" 14 - class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] max-w-[45%] truncate" 15 - title={adjacentPosts.previous.title} 16 - > 17 - โ† {adjacentPosts.previous.title} 18 - </a> 19 - {:else} 20 - <span></span> 21 - {/if} 22 - 23 - {#if adjacentPosts.next} 24 - <a 25 - href="/blog/{adjacentPosts.next.rkey}" 26 - class="text-[var(--link-color)] hover:text-[var(--link-hover-color)] max-w-[45%] truncate" 27 - title={adjacentPosts.next.title} 28 - > 29 - {adjacentPosts.next.title} โ†’ 30 - </a> 31 - {:else} 32 - <span></span> 33 - {/if} 34 - </div>
-4
src/lib/components/post/index.ts
··· 1 - export { default as PostHead } from "./PostHead.svelte"; 2 - export { default as PostHeader } from "./PostHeader.svelte"; 3 - export { default as PostContent } from "./PostContent.svelte"; 4 - export { default as PostNavigation } from "./PostNavigation.svelte";
-69
src/lib/components/profile/Profile.svelte
··· 1 - <script lang="ts"> 2 - // The profile object is passed as a prop to this component. 3 - export let profile: any; 4 - import { Status } from "."; 5 - </script> 6 - 7 - <!-- Profile Banner: Displays the user's banner image. --> 8 - <div 9 - class="profile-banner p-4 relative rounded-none mx-2 mb-2" 10 - style="background-image: url({profile?.banner}); background-size: cover; background-position: center; min-height: 150px;" 11 - ></div> 12 - 13 - {#if profile} 14 - <!-- Profile Content: Main container for avatar, user info, and status. --> 15 - <div class="profile-content mx-2 mb-8 relative"> 16 - <!-- Mobile: Stack vertically, Desktop: Side by side --> 17 - <div class="flex flex-col sm:flex-row sm:items-start text-left sm:gap-6"> 18 - <!-- Profile Avatar --> 19 - <img 20 - src={profile?.avatar} 21 - alt="{profile?.displayName || 'User'}'s avatar" 22 - class="rounded-none shadow-lg hover:transform-none flex-shrink-0 relative z-10 23 - w-24 h-24 -mt-12 mx-auto mb-4 24 - sm:w-32 sm:h-32 sm:-mt-16 sm:mx-0 sm:mb-0" 25 - /> 26 - 27 - <!-- User Information: Display name, handle, DID, description, status --> 28 - <div class="flex-1 min-w-0 p-4 rounded-none overflow-hidden" style="background: var(--card-bg);"> 29 - <div class="mb-3"> 30 - <h4 class="text-lg font-semibold mb-1 leading-tight truncate text-center sm:text-left">{profile?.displayName}</h4> 31 - <h6 class="mb-2 text-center sm:text-left"> 32 - <a 33 - href="https://bsky.app/profile/{profile?.handle}" 34 - class="text-link hover:text-link-hover text-sm truncate block">@{profile?.handle}</a 35 - > 36 - </h6> 37 - <h6 class="opacity-40 mb-3 text-center sm:text-left"> 38 - <span class="text-xs font-mono overflow-hidden text-ellipsis whitespace-nowrap hidden sm:block">{profile?.did}</span> 39 - </h6> 40 - </div> 41 - 42 - <!-- Profile Description --> 43 - {#if profile?.description} 44 - <div class="mb-3"> 45 - <p class="text-sm leading-relaxed text-center sm:text-left">{profile?.description}</p> 46 - </div> 47 - {/if} 48 - 49 - <!-- Display consolidated status/music using the updated Status component --> 50 - <div class="text-center sm:text-left"> 51 - <Status {profile} /> 52 - </div> 53 - </div> 54 - </div> 55 - </div> 56 - {:else} 57 - <!-- Placeholder for app.bsky.actor.profile --> 58 - <div 59 - class="profile-content flex flex-col items-center justify-center text-center mx-2 p-4 relative rounded-none" 60 - style="background: var(--card-bg);" 61 - > 62 - <p class="text-center text-sm italic opacity-75"> 63 - create a `app.bsky.actor.profile` record at <a 64 - href="https://bsky.app/" 65 - class="text-link hover:text-link-hover">https://bsky.app/</a 66 - > 67 - </p> 68 - </div> 69 - {/if}
-125
src/lib/components/profile/Status.svelte
··· 1 - <script lang="ts"> 2 - import { onMount } from "svelte"; 3 - import { env } from "$env/dynamic/public"; 4 - import { fade } from "svelte/transition"; 5 - 6 - /** 7 - * The profile object is passed as a prop to this component. 8 - * It should contain at least 'displayName', 'handle', or 'did' fields. 9 - */ 10 - export let profile: any; 11 - 12 - // RecentFM-related state 13 - let musicLoading = false; 14 - let musicError: string | null = null; 15 - let trackData: { 16 - name: string; 17 - artist: string; 18 - url: string; 19 - } | null = null; 20 - let showContent = false; 21 - 22 - /** 23 - * Fetches recent music from Last.fm via RecentFM API 24 - */ 25 - async function fetchRecentMusic(): Promise<void> { 26 - const lastfmUsername = env.PUBLIC_LASTFM_USERNAME; 27 - 28 - if (!lastfmUsername) { 29 - return; 30 - } 31 - 32 - musicLoading = true; 33 - musicError = null; 34 - 35 - try { 36 - const params = new URLSearchParams({ 37 - username: lastfmUsername, 38 - emoji: "๐ŸŽง", 39 - nomoji: "false", 40 - }); 41 - 42 - const url = `https://recentfm.rknight.me/now.php?${params.toString()}`; 43 - 44 - const response = await fetch(url); 45 - 46 - if (!response.ok) { 47 - throw new Error(`HTTP error! status: ${response.status}`); 48 - } 49 - 50 - const data = await response.json(); 51 - 52 - if (data.content) { 53 - const parser = new DOMParser(); 54 - const doc = parser.parseFromString(data.content, "text/html"); 55 - const link = doc.querySelector("a"); 56 - 57 - if (link) { 58 - const fullText = link.textContent || ""; 59 - const url = link.href; 60 - 61 - const match = fullText.match(/^(.+?) by (.+)$/); 62 - if (match) { 63 - trackData = { 64 - name: match[1].trim(), 65 - artist: match[2].trim(), 66 - url: url, 67 - }; 68 - } 69 - } 70 - } 71 - } catch (err) { 72 - console.error("[RecentFM] Error fetching RecentFM data:", err); 73 - musicError = "Failed to load recent tracks"; 74 - } finally { 75 - musicLoading = false; 76 - } 77 - } 78 - 79 - // Load data on mount 80 - onMount(async () => { 81 - await fetchRecentMusic(); 82 - 83 - // Introduce a delay before showing content 84 - setTimeout(() => { 85 - showContent = true; 86 - }, 2000); // 2 second delay 87 - }); 88 - </script> 89 - 90 - <!-- Last.fm Music Display --> 91 - {#if showContent && profile} 92 - <div transition:fade={{ duration: 500 }}> 93 - <div class="py-2"> 94 - {#if trackData} 95 - <!-- Music Display --> 96 - <div class="recent-track-info"> 97 - <p class="text-xs opacity-60 text-center sm:text-left"> 98 - {profile.displayName || profile.handle || profile.did} was last listening 99 - to 100 - </p> 101 - <p class="text-xs font-medium text-center sm:text-left mt-0.5"> 102 - <a 103 - href={trackData.url} 104 - class="text-link hover:text-link-hover" 105 - target="_blank" 106 - rel="noopener noreferrer" 107 - > 108 - "{trackData.name}" by {trackData.artist} 109 - </a> 110 - </p> 111 - </div> 112 - {:else if musicError} 113 - <p class="text-xs opacity-60 text-center sm:text-left text-red-500"> 114 - {musicError} 115 - </p> 116 - {/if} 117 - 118 - {#if musicLoading} 119 - <p class="text-xs opacity-60 italic text-center sm:text-left"> 120 - Loading recent tracks... 121 - </p> 122 - {/if} 123 - </div> 124 - </div> 125 - {/if}
-2
src/lib/components/profile/index.ts
··· 1 - export { default as Profile } from "./Profile.svelte"; 2 - export { default as Status } from "./Status.svelte";
+2 -2
src/lib/components/profile/profile.ts
··· 20 20 } 21 21 22 22 export async function getProfile(fetch: typeof globalThis.fetch): Promise<Profile> { 23 - const cacheKey = `profile_${env.PUBLIC_ATPROTOCOL_USER}`; 23 + const cacheKey = `profile_${env.DIRECTORY_OWNER}`; 24 24 let profile: Profile | null = getCache<Profile>(cacheKey); 25 25 26 26 if (profile) { ··· 29 29 30 30 try { 31 31 const fetchProfile = await safeFetch( 32 - `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${env.PUBLIC_ATPROTOCOL_USER}`, 32 + `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${env.DIRECTORY_OWNER}`, 33 33 fetch 34 34 ); 35 35 const split = fetchProfile["did"].split(":");
+1 -1
src/lib/components/shared/NotFoundMessage.svelte
··· 1 1 <div class="flex justify-center items-center min-h-[50vh]"> 2 2 <h1 class="text-center pt-4 pb-4"> 3 - it's either loading or the post doesn't exist 3 + It's either loading or the user doesn't exist 4 4 </h1> 5 5 </div>
+28 -49
src/lib/components/shared/interfaces.ts
··· 1 - /** 2 - * Represents a blog post with its content and metadata. 3 - */ 4 - export interface Post { 5 - postNumber?: number; 6 - title: string; // The title of the post. 7 - rkey: string; // A unique key for the post. 8 - createdAt: Date; // The date and time the post was created. 9 - content: string; // The content of the post, parsed to HTML. 10 - excerpt: string; // A plain text excerpt for meta descriptions. 11 - wordCount: number; // The word count for reading time calculation. 12 - } 13 - 14 - /** 15 - * Represents a blog post in its raw Markdown format. 16 - */ 17 - export interface MarkdownPost { 18 - title: string; // The title of the post. 19 - rkey: string; // A unique key for the post. 20 - createdAt: Date; // The date and time the post was created. 21 - mdcontent: string; // The raw Markdown content of the post. 22 - } 23 - 24 1 // Define the type for the fetched links data 25 2 /** 26 3 * Represents a single link card with a URL, text, and an emoji. ··· 32 9 } 33 10 34 11 /** 12 + * Represents the properties for the DynamicHead component. 13 + */ 14 + export interface DynamicHeadProps { 15 + title: string; 16 + description: string; 17 + keywords: string; 18 + ogUrl?: string; 19 + ogTitle: string; 20 + ogDescription: string; 21 + ogImage?: string; 22 + ogImageWidth?: string; 23 + ogImageHeight?: string; 24 + twitterCard?: string; 25 + twitterUrl?: string; 26 + twitterTitle: string; 27 + twitterDescription: string; 28 + twitterImage?: string; 29 + } 30 + 31 + /** 35 32 * Represents a board containing multiple link cards. 36 33 */ 37 34 export interface LinkBoard { ··· 51 48 * Represents public environment variables. 52 49 */ 53 50 export interface PublicEnv { 54 - PUBLIC_ATPROTOCOL_USER: string; // Public user for ATProtocol. 55 - PUBLIC_ACTIVITYPUB_USER: string; // Public user for ActivityPub. 51 + DIRECTORY_OWNER: string; // Public user for ATProtocol. 56 52 } 57 53 58 54 /** ··· 69 65 } 70 66 71 67 /** 72 - * Represents a status update or a short message. 73 - */ 74 - export interface StatusUpdate { 75 - text: string; // The content of the status update. 76 - createdAt: Date; // The date and time the status update was created. 77 - tid: string; // A unique identifier for the status update. 78 - } 79 - 80 - /** 81 - * Properties for displaying recent content, possibly from a feed or similar source. 82 - */ 83 - export interface RecentFMProps { 84 - nomoji?: boolean; // Optional flag to disable emojis. 85 - displayName?: string; // Optional display name. 86 - } 87 - 88 - /** 89 - * Represents the result of the BlogService, containing posts, profile, and utility functions. 68 + * Represents a user with basic details. 90 69 */ 91 - export interface BlogServiceResult { 92 - posts: Map<string, Post>; 93 - profile: Profile; 94 - sortedPosts: Post[]; 95 - getPost: (rkey: string) => Post | null; 96 - getAdjacentPosts: (rkey: string) => { previous: Post | null; next: Post | null }; 70 + export interface User { 71 + did: string; 72 + handle?: string; 73 + displayName?: string; 74 + avatar?: string; 75 + description?: string; 97 76 }
+36
src/lib/config/linkat-users.ts
··· 1 + import { env } from "$env/dynamic/public"; 2 + 3 + /** 4 + * Configuration for Linkat users to display 5 + * 6 + * Users can be configured via environment variables: 7 + * - PUBLIC_LINKAT_USERS: Comma-separated list of DIDs (e.g., "did:plc:abc123,did:web:example.com") 8 + * - DIRECTORY_OWNER: Primary user DID (fallback if no users configured) 9 + * 10 + * Format: "did:plc:xxxxxxxxxxxxxxxxxxxxxxxx" or "did:web:xxxxxxxxxxxxxxxxxxxxxxxx" 11 + * The first user will be treated as the primary user 12 + */ 13 + 14 + function parseUsersFromEnv(): string[] { 15 + const users: string[] = []; 16 + 17 + // Always include DIRECTORY_OWNER as the primary user if configured 18 + if (env.DIRECTORY_OWNER) { 19 + users.push(env.DIRECTORY_OWNER); 20 + } 21 + 22 + // Add additional users from PUBLIC_LINKAT_USERS, avoiding duplicates 23 + if (env.PUBLIC_LINKAT_USERS) { 24 + const envUsers = env.PUBLIC_LINKAT_USERS.split(',') 25 + .map(did => did.trim()) 26 + .filter(did => did.startsWith('did:') && did !== env.DIRECTORY_OWNER); 27 + users.push(...envUsers); 28 + } 29 + 30 + return users; 31 + } 32 + 33 + export const LINKAT_USERS = parseUsersFromEnv(); 34 + 35 + // Maximum number of users to display (1-10) 36 + export const MAX_USERS = 10;
+7 -138
src/lib/css/app.css
··· 1 1 @import "$css/variables.css"; 2 2 3 - /* Minimalist flat styles with gentle dark pastel green theme */ 3 + /* Linkat Directory - Core CSS Styles */ 4 4 @tailwind base; 5 5 @tailwind components; 6 6 @tailwind utilities; 7 7 8 8 @layer base { 9 9 10 - /* Scrollbar styling */ 10 + /* Custom scrollbar styling for webkit browsers */ 11 11 ::-webkit-scrollbar { 12 12 width: 10px; 13 13 height: 10px; ··· 33 33 body { 34 34 background-color: var(--background-color); 35 35 color: var(--text-color); 36 - font-family: "Recursive", sans-serif; 37 - font-variation-settings: "MONO" 0, "CASL" 0, "wght" 300, "slnt" 0, 38 - "CRSV" 0.5; 36 + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; 39 37 } 40 38 41 39 h1 { 42 40 @apply text-4xl font-bold; 43 - font-variation-settings: "MONO" 0, "CASL" 0.8, "wght" 700, "slnt" 0, 44 - "CRSV" 0.9; 45 41 } 46 42 47 43 h2 { 48 44 @apply text-3xl font-bold; 49 - font-variation-settings: "MONO" 0, "CASL" 0.7, "wght" 650, "slnt" 0, 50 - "CRSV" 0.85; 51 45 } 52 46 53 47 h3 { 54 48 @apply text-2xl font-bold; 55 - font-variation-settings: "MONO" 0, "CASL" 0.6, "wght" 600, "slnt" 0, 56 - "CRSV" 0.8; 57 49 } 58 50 59 51 h4 { 60 52 @apply text-xl font-semibold; 61 - font-variation-settings: "MONO" 0, "CASL" 0.5, "wght" 550, "slnt" 0, 62 - "CRSV" 0.75; 63 53 } 64 54 65 55 h5 { 66 56 @apply text-lg font-semibold; 67 - font-variation-settings: "MONO" 0, "CASL" 0.4, "wght" 500, "slnt" 0, 68 - "CRSV" 0.7; 69 57 } 70 58 71 59 h6 { 72 60 @apply text-sm font-semibold; 73 - font-variation-settings: "MONO" 0, "CASL" 0.3, "wght" 450, "slnt" 0, 74 - "CRSV" 0.6; 75 61 } 76 62 77 63 a { 78 64 @apply text-[var(--link-color)] hover:text-[var(--link-hover-color)] no-underline; 79 - font-variation-settings: "MONO" 0, "CASL" 0, "wght" 450, "slnt" 0, 80 - "CRSV" 0.5; 81 - /* Reduced transition complexity */ 65 + /* Simplified hover transitions */ 82 66 transition: color 0.2s ease; 83 67 } 84 68 85 69 a:hover { 86 - font-variation-settings: "MONO" 0, "CASL" 0, "wght" 600, "slnt" 0, 87 - "CRSV" 0.5; 70 + @apply font-semibold; 88 71 } 89 72 90 73 a, ··· 95 78 text-decoration: none !important; 96 79 } 97 80 98 - /* Last.FM info styles */ 99 - .recent-played { 100 - @apply text-center; 101 - } 102 - 103 - .recent-track-info { 104 - @apply space-y-0.5; 105 - } 106 - 107 81 /* Header links - simplified transitions */ 108 82 header a, 109 83 a.font-medium { ··· 117 91 transform: scale(1.1); 118 92 } 119 93 120 - /* Typography styles for blog content */ 94 + /* Typography styles for blog/prose content using Tailwind Typography plugin */ 121 95 .prose { 122 96 @apply max-w-none; 123 97 } ··· 153 127 text-decoration: none; 154 128 } 155 129 156 - /* Update prose elements to use variables */ 130 + /* Prose element styling with CSS variables for theme consistency */ 157 131 .prose a { 158 132 color: var(--link-color); 159 133 text-decoration: none; ··· 184 158 .prose pre code { 185 159 @apply bg-transparent p-0; 186 160 } 187 - 188 - /* Post grid and cards - simplified animations */ 189 - .post-card { 190 - @apply border-0 rounded-none p-4 shadow-md; 191 - background-color: var(--card-bg); 192 - color: var(--text-color); 193 - /* Only animate specific properties on hover */ 194 - transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease; 195 - } 196 - 197 - .post-card:hover { 198 - background-color: var(--header-footer-bg); 199 - transform: scale(1.05); 200 - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); 201 - } 202 - 203 - /* Profile banner - simplified */ 204 - .profile-banner { 205 - @apply bg-cover bg-center rounded-md border-0; 206 - transition: opacity 0.2s ease; 207 - } 208 - 209 - .profile-banner:hover { 210 - opacity: 0.95; 211 - } 212 - 213 - /* Profile section elements */ 214 - .flex-wrap { 215 - @apply gap-4 items-center; 216 - } 217 - 218 - div.items-center { 219 - @apply p-3; 220 - } 221 - 222 - .rounded-full { 223 - @apply shadow-none; 224 - transition: transform 0.2s ease; 225 - } 226 - 227 - .rounded-full:hover { 228 - transform: scale(1.05); 229 - } 230 - 231 - /* Account handle and related info */ 232 - h4.content-around, 233 - h6.content-around { 234 - @apply my-2 text-left; 235 - } 236 - 237 - /* Links styling within the profile section - simplified */ 238 - .profile-banner a, 239 - .flex-wrap a, 240 - div.items-center a, 241 - h4.content-around a, 242 - h6.content-around a { 243 - @apply no-underline hover:no-underline inline-block; 244 - color: var(--link-color); 245 - transition: color 0.2s ease, transform 0.2s ease; 246 - } 247 - 248 - .profile-banner a:hover, 249 - .flex-wrap a:hover, 250 - div.items-center a:hover, 251 - h4.content-around a:hover, 252 - h6.content-around a:hover { 253 - color: var(--link-hover-color); 254 - transform: scale(1.1); 255 - } 256 - 257 - /* Remove any borders throughout profile section */ 258 - .profile-banner, 259 - .profile-banner *, 260 - .flex-wrap *, 261 - div.items-center *, 262 - .rounded-full, 263 - h4.content-around *, 264 - h6.content-around * { 265 - @apply border-0; 266 - } 267 - 268 - /* Comments section styling */ 269 - :global(.comments-section) { 270 - @apply mt-8 p-4 border-0 rounded-md bg-[var(--header-footer-bg)]; 271 - } 272 - 273 - :global(.comments-section input, .comments-section button) { 274 - @apply bg-[var(--button-bg)] border-0 rounded-sm; 275 - } 276 - } 277 - 278 - .prose+.flex.justify-between { 279 - @apply mt-12 mb-8; 280 - } 281 - 282 - .prose+.flex.justify-between a { 283 - @apply max-w-[45%] truncate; 284 - } 285 - 286 - .prose+.flex.justify-between a:first-child { 287 - @apply text-left; 288 - } 289 - 290 - .prose+.flex.justify-between a:last-child { 291 - @apply text-right; 292 161 } 293 162 294 163 .text-link {
+35 -21
src/lib/css/variables.css
··· 1 - /* Default mono theme - dark mode */ 2 - :root { 3 - font-family: sans-serif, system-ui; 4 - --background-color: #1a1a1a; 5 - --text-color: #f0f0f0; 6 - --header-footer-bg: #2a2a2a; 7 - --button-bg: #4a4a4a; 8 - --button-hover-bg: #6a6a6a; 9 - --link-color: #9a9a9a; 10 - --link-hover-color: #b0b0b0; 11 - --card-bg: #2a2a2a; 1 + @media (prefers-color-scheme: dark) { 2 + /* Default mono theme - dark mode */ 3 + :root { 4 + font-family: sans-serif, system-ui; 5 + --background-color: #1a1a1a; 6 + --text-color: #f0f0f0; 7 + --header-footer-bg: #2a2a2a; 8 + --button-bg: #4a4a4a; 9 + --button-hover-bg: #6a6a6a; 10 + --link-color: #9a9a9a; 11 + --link-hover-color: #b0b0b0; 12 + --card-bg: #2a2a2a; 13 + --border-color: #404040; 14 + --error-color: #ff6b6b; 15 + --placeholder-color: #666666; 16 + --secondary-text-color: #b0b0b0; 17 + --muted-bg: #333333; 18 + } 12 19 } 13 20 14 - /* Default mono theme - light mode */ 15 - :root.light { 16 - --background-color: #f0f0f0; 17 - --text-color: #1a1a1a; 18 - --header-footer-bg: #e0e0e0; 19 - --button-bg: #b0b0b0; 20 - --button-hover-bg: #9a9a9a; 21 - --link-color: #6a6a6a; 22 - --link-hover-color: #4a4a4a; 23 - --card-bg: #e0e0e0; 21 + @media (prefers-color-scheme: light) { 22 + /* Default mono theme - light mode */ 23 + :root { 24 + --background-color: #f0f0f0; 25 + --text-color: #1a1a1a; 26 + --header-footer-bg: #e0e0e0; 27 + --button-bg: #b0b0b0; 28 + --button-hover-bg: #9a6a6a; 29 + --link-color: #6a6a6a; 30 + --link-hover-color: #4a4a4a; 31 + --card-bg: #e0e0e0; 32 + --border-color: #cccccc; 33 + --error-color: #dc2626; 34 + --placeholder-color: #999999; 35 + --secondary-text-color: #4a4a4a; 36 + --muted-bg: #d0d0d0; 37 + } 24 38 }
-3
src/lib/parser/index.ts
··· 1 - export { parse } from './parser.ts'; 2 - export { customSchema } from './schema.ts'; 3 - export { rehypeUpgradeImage } from './plugins.ts';
-34
src/lib/parser/parser.ts
··· 1 - import { extractTextFromMarkdown, calculateWordCount } from "$utils/textProcessor"; 2 - import { createMarkdownProcessor } from "./processor"; 3 - import type { Post, MarkdownPost } from "./types"; 4 - 5 - export async function parse(mdposts: Map<string, MarkdownPost>): Promise<Map<string, Post>> { 6 - const posts: Map<string, Post> = new Map(); 7 - const processor = createMarkdownProcessor(); 8 - 9 - for (const [rkey, post] of mdposts) { 10 - const parsedHtml = String( 11 - await processor.process(post.mdcontent) 12 - ); 13 - 14 - // Ensure mdcontent is a string before processing 15 - const markdownContent = post.mdcontent || ''; 16 - 17 - // Extract plain text for excerpt 18 - const excerpt = await extractTextFromMarkdown(markdownContent); 19 - 20 - // Calculate word count from markdown content 21 - const wordCount = calculateWordCount(markdownContent); 22 - 23 - posts.set(rkey, { 24 - title: post.title, 25 - rkey: post.rkey, 26 - createdAt: post.createdAt, 27 - content: parsedHtml, 28 - excerpt, 29 - wordCount, 30 - }); 31 - } 32 - 33 - return posts; 34 - }
-25
src/lib/parser/plugins.ts
··· 1 - import type { Node, Root, Element, Plugin } from "./types"; 2 - 3 - // Automatically enforce https on PDS images. Heavily inspired by WhiteWind's blob replacer: 4 - // https://github.com/whtwnd/whitewind-blog/blob/7eb8d4623eea617fd562b93d66a0e235323a2f9a/frontend/src/services/DocProvider.tsx#L90 5 - // In theory we could also use their cache, but I'd like to rely on their API as little as possible, opting to pull from the PDS instead. 6 - const upgradeImage = (child: Node): void => { 7 - if (child.type !== "element") { 8 - return; 9 - } 10 - const elem = child as Element; 11 - if (elem.tagName === "img") { 12 - // Ensure https 13 - const src = elem.properties.src; 14 - if (src !== undefined && typeof src === "string") { 15 - elem.properties.src = src.replace(/http:\/\//, "https://"); 16 - } 17 - } 18 - elem.children.forEach((child) => upgradeImage(child)); 19 - }; 20 - 21 - export const rehypeUpgradeImage: Plugin<[], Root, Node> = () => { 22 - return (tree) => { 23 - tree.children.forEach((child) => upgradeImage(child)); 24 - }; 25 - };
-21
src/lib/parser/processor.ts
··· 1 - import rehypeStringify from "rehype-stringify"; 2 - import remarkParse from "remark-parse"; 3 - import remarkGfm from "remark-gfm"; 4 - import remarkRehype from "remark-rehype"; 5 - import rehypeSanitize from "rehype-sanitize"; 6 - import rehypeRaw from "rehype-raw"; 7 - import { unified } from "unified"; 8 - import { customSchema } from "./schema"; 9 - import { rehypeUpgradeImage } from "./plugins"; 10 - import type { Schema } from "./types"; 11 - 12 - export const createMarkdownProcessor = () => { 13 - return unified() 14 - .use(remarkParse, { fragment: true }) // Parse the MD 15 - .use(remarkGfm) // Parse GH specific MD 16 - .use(remarkRehype, { allowDangerousHtml: true }) // Convert to HTML 17 - .use(rehypeRaw) // Parse HTML that exists as raw text leftover from MD parse 18 - .use(rehypeUpgradeImage) 19 - .use(rehypeSanitize, customSchema as Schema) // Sanitize the HTML 20 - .use(rehypeStringify); // Stringify 21 - };
-43
src/lib/parser/schema.ts
··· 1 - import { defaultSchema } from "rehype-sanitize"; 2 - import type { Schema } from "./types"; 3 - 4 - // WhiteWind's own custom schema: 5 - // https://github.com/whtwnd/whitewind-blog/blob/7eb8d4623eea617fd562b93d66a0e235323a2f9a/frontend/src/services/DocProvider.tsx#L122 6 - export const customSchema: Schema = { 7 - ...defaultSchema, 8 - attributes: { 9 - ...defaultSchema.attributes, 10 - font: [...(defaultSchema.attributes?.font ?? []), "color"], 11 - blockquote: [ 12 - ...(defaultSchema.attributes?.blockquote ?? []), 13 - // bluesky 14 - "className", 15 - "dataBlueskyUri", 16 - "dataBlueskyCid", 17 - // instagram 18 - "dataInstgrmCaptioned", 19 - "dataInstgrmPermalink", 20 - "dataInstgrmVersion", 21 - ], 22 - iframe: [ 23 - "width", 24 - "height", 25 - "title", 26 - "frameborder", 27 - "allow", 28 - "referrerpolicy", 29 - "allowfullscreen", 30 - "style", 31 - "seamless", 32 - ["src", /https:\/\/(www.youtube.com|bandcamp.com)\/.*/], 33 - ], 34 - section: ["dataFootnotes", "className"], 35 - }, 36 - tagNames: [ 37 - ...(defaultSchema.tagNames ?? []), 38 - "font", 39 - "mark", 40 - "iframe", 41 - "section", 42 - ], 43 - };
-8
src/lib/parser/types.ts
··· 1 - import type { Schema } from "../../../node_modules/rehype-sanitize/lib"; 2 - import type { Node } from "unist"; 3 - import type { Root, Element } from "hast"; 4 - import type { Plugin } from "unified"; 5 - import type { Post, MarkdownPost } from "$components/shared"; 6 - 7 - export type { Schema, Node, Root, Element, Plugin, Post, MarkdownPost }; 8 -
-189
src/lib/services/blogService.ts
··· 1 - import { getProfile } from "$components/profile/profile"; 2 - import type { Profile, MarkdownPost, Post, BlogServiceResult } from "$components/shared"; 3 - import { parse } from "$lib/parser"; 4 - 5 - // Cache for blog data 6 - let profile: Profile; 7 - let allPosts: Map<string, Post>; 8 - let sortedPosts: Post[] = []; 9 - 10 - /** 11 - * Validates and processes a single blog record 12 - */ 13 - function processRecord(data: any): MarkdownPost | null { 14 - const matches = data["uri"].split("/"); 15 - const rkey = matches[matches.length - 1]; 16 - 17 - // Enhanced debugging for development 18 - if (process.env.NODE_ENV === 'development') { 19 - console.log('=== Record Debug Info ==='); 20 - console.log('URI:', data["uri"]); 21 - console.log('Data structure keys:', Object.keys(data)); 22 - } 23 - 24 - // Try both access patterns to be safe 25 - const record = data["value"] || data.value; 26 - 27 - if (!record) { 28 - console.warn(`No record value found for ${rkey}`, { 29 - dataKeys: Object.keys(data), 30 - }); 31 - return null; 32 - } 33 - 34 - // Validate URI format and visibility 35 - if ( 36 - !matches || 37 - matches.length !== 5 || 38 - !record || 39 - (record["visibility"] && record["visibility"] !== "public") 40 - ) { 41 - if (process.env.NODE_ENV === 'development') { 42 - console.warn('Post skipped due to validation failure:', { 43 - rkey, 44 - matchesLength: matches?.length, 45 - hasRecord: !!record, 46 - visibility: record?.["visibility"], 47 - }); 48 - } 49 - return null; 50 - } 51 - 52 - // Extract fields with fallback patterns 53 - const content = record["content"] || record.content || (record.value && record.value.content); 54 - const title = record["title"] || record.title || (record.value && record.value.title); 55 - const createdAt = record["createdAt"] || record.createdAt || (record.value && record.value.createdAt); 56 - 57 - // Skip if missing required content 58 - if (!content) { 59 - console.warn(`Skipping post with missing content: ${rkey}`); 60 - return null; 61 - } 62 - 63 - // Handle createdAt - use current time as fallback for missing dates 64 - let createdAtDate: Date; 65 - if (!createdAt) { 66 - console.warn(`Post missing createdAt, using current time: ${rkey}`); 67 - createdAtDate = new Date(); 68 - } else { 69 - createdAtDate = new Date(createdAt); 70 - 71 - // Skip posts with invalid dates 72 - if (isNaN(createdAtDate.getTime())) { 73 - console.warn(`Skipping post with invalid date: ${rkey}`, { 74 - rawCreatedAt: createdAt, 75 - }); 76 - return null; 77 - } 78 - } 79 - 80 - // Use title if available, otherwise generate one 81 - const finalTitle = title || `Untitled Post (${rkey})`; 82 - 83 - return { 84 - title: finalTitle, 85 - createdAt: createdAtDate, 86 - mdcontent: content, 87 - rkey, 88 - }; 89 - } 90 - 91 - /** 92 - * Fetches and processes all blog posts 93 - */ 94 - export async function loadAllPosts(fetch: typeof window.fetch): Promise<BlogServiceResult> { 95 - try { 96 - // Load profile if not cached 97 - if (profile === undefined) { 98 - profile = await getProfile(fetch); 99 - } 100 - 101 - // Load posts if not cached 102 - if (allPosts === undefined) { 103 - const rawResponse = await fetch( 104 - `${profile.pds}/xrpc/com.atproto.repo.listRecords?repo=${profile.did}&collection=com.whtwnd.blog.entry` 105 - ); 106 - 107 - if (!rawResponse.ok) { 108 - throw new Error(`Failed to fetch posts: ${rawResponse.status}`); 109 - } 110 - 111 - const response = await rawResponse.json(); 112 - 113 - if (!response.records || response.records.length === 0) { 114 - allPosts = new Map(); 115 - sortedPosts = []; 116 - } else { 117 - const mdposts: Map<string, MarkdownPost> = new Map(); 118 - 119 - // Process all records 120 - for (const data of response.records) { 121 - const processedPost = processRecord(data); 122 - if (processedPost) { 123 - mdposts.set(processedPost.rkey, processedPost); 124 - } 125 - } 126 - 127 - console.log(`Successfully processed ${mdposts.size} posts out of ${response.records.length} total records`); 128 - 129 - // Parse markdown content 130 - allPosts = await parse(mdposts); 131 - sortedPosts = Array.from(allPosts.values()).sort( 132 - (a, b) => b.createdAt.getTime() - a.createdAt.getTime() 133 - ); 134 - 135 - // Assign postNumber based on chronological order (1 = latest, 2 = second latest, etc.) 136 - // Assign postNumber based on reverse chronological order (total posts = latest, 1 = oldest) 137 - const totalPosts = sortedPosts.length; 138 - sortedPosts.forEach((post, index) => { 139 - post.postNumber = totalPosts - index; 140 - }); 141 - } 142 - } 143 - 144 - return { 145 - posts: allPosts, 146 - profile, 147 - sortedPosts, 148 - getPost: (rkey: string) => allPosts.get(rkey) || null, 149 - getAdjacentPosts: (rkey: string): { previous: Post | null; next: Post | null } => { 150 - const index = sortedPosts.findIndex((post) => post.rkey === rkey); 151 - return { 152 - previous: index > 0 ? sortedPosts[index - 1] : null, 153 - next: index < sortedPosts.length - 1 ? sortedPosts[index + 1] : null, 154 - }; 155 - }, 156 - }; 157 - } catch (error) { 158 - console.error("Error in loadAllPosts:", error); 159 - return { 160 - posts: new Map(), 161 - profile: profile || ({} as Profile), 162 - sortedPosts: [], 163 - getPost: () => null, 164 - getAdjacentPosts: () => ({ previous: null, next: null }), 165 - }; 166 - } 167 - } 168 - 169 - /** 170 - * Gets the latest N blog posts (for homepage display) 171 - */ 172 - export async function getLatestPosts(fetch: typeof window.fetch, limit: number = 3): Promise<Post[]> { 173 - try { 174 - const { sortedPosts } = await loadAllPosts(fetch); 175 - return sortedPosts.slice(0, limit); 176 - } catch (error) { 177 - console.error("Error fetching latest posts:", error); 178 - return []; 179 - } 180 - } 181 - 182 - /** 183 - * Clears the cache (useful for testing or force refresh) 184 - */ 185 - export function clearCache(): void { 186 - profile = undefined as any; 187 - allPosts = undefined as any; 188 - sortedPosts = []; 189 - }
-130
src/lib/themeLoader.ts
··· 1 - import type { Theme } from "$components/shared/interfaces"; 2 - 3 - // Theme configuration - single source of truth 4 - export const THEMES: Theme[] = [ 5 - { id: "default", name: "Green (Default)" }, 6 - ]; 7 - 8 - export const THEME_STORAGE_KEYS = { 9 - MODE: "theme-mode", 10 - COLOR: "color-theme", 11 - } as const; 12 - 13 - export type ThemeMode = "light" | "dark"; 14 - 15 - /** 16 - * Applies theme classes to the document element 17 - */ 18 - export function applyTheme(isDarkMode: boolean, themeId: string): void { 19 - // Remove all existing theme classes 20 - document.documentElement.classList.remove("light"); 21 - THEMES.forEach((theme) => { 22 - if (theme.id !== "default") { 23 - document.documentElement.classList.remove(theme.id); 24 - } 25 - }); 26 - 27 - // Apply light mode class if needed 28 - if (!isDarkMode) { 29 - document.documentElement.classList.add("light"); 30 - } 31 - 32 - // Apply color theme class if not default 33 - if (themeId !== "default") { 34 - document.documentElement.classList.add(themeId); 35 - } 36 - } 37 - 38 - /** 39 - * Gets the user's theme preferences from localStorage and system 40 - */ 41 - export function getThemePreferences(): { isDarkMode: boolean; themeId: string } { 42 - const savedThemeMode = localStorage.getItem(THEME_STORAGE_KEYS.MODE); 43 - const savedColorTheme = localStorage.getItem(THEME_STORAGE_KEYS.COLOR); 44 - 45 - let isDarkMode: boolean; 46 - if (savedThemeMode) { 47 - isDarkMode = savedThemeMode === "dark"; 48 - } else { 49 - // Use system preference as default 50 - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; 51 - isDarkMode = prefersDark; 52 - } 53 - 54 - const themeId = savedColorTheme || "default"; 55 - 56 - return { isDarkMode, themeId }; 57 - } 58 - 59 - /** 60 - * Saves theme preferences to localStorage 61 - */ 62 - export function saveThemePreferences(isDarkMode: boolean, themeId: string): void { 63 - localStorage.setItem(THEME_STORAGE_KEYS.MODE, isDarkMode ? "dark" : "light"); 64 - localStorage.setItem(THEME_STORAGE_KEYS.COLOR, themeId); 65 - } 66 - 67 - /** 68 - * Updates the theme-color meta tag for browser UI 69 - */ 70 - export function updateThemeColorMeta(): void { 71 - const themeColor = getComputedStyle(document.documentElement) 72 - .getPropertyValue("--background-color") 73 - .trim(); 74 - 75 - let metaTag = document.querySelector('meta[name="theme-color"]') as HTMLMetaElement; 76 - if (!metaTag) { 77 - metaTag = document.createElement("meta"); 78 - metaTag.setAttribute("name", "theme-color"); 79 - document.head.appendChild(metaTag); 80 - } 81 - metaTag.setAttribute("content", themeColor); 82 - } 83 - 84 - /** 85 - * Dispatches a custom event when theme changes 86 - */ 87 - export function dispatchThemeChangeEvent(isDarkMode: boolean, themeId: string): void { 88 - document.dispatchEvent( 89 - new CustomEvent("themeChanged", { 90 - detail: { isDarkMode, theme: themeId }, 91 - }) 92 - ); 93 - } 94 - 95 - /** 96 - * Sets up system theme change listener 97 - */ 98 - export function setupSystemThemeListener(): void { 99 - window 100 - .matchMedia("(prefers-color-scheme: dark)") 101 - .addEventListener("change", (e) => { 102 - // Only apply system preference if user hasn't set a manual preference 103 - if (localStorage.getItem(THEME_STORAGE_KEYS.MODE) === null) { 104 - const { themeId } = getThemePreferences(); 105 - applyTheme(e.matches, themeId); 106 - updateThemeColorMeta(); 107 - dispatchThemeChangeEvent(e.matches, themeId); 108 - } 109 - }); 110 - } 111 - 112 - /** 113 - * Initializes theme system - should be called as early as possible 114 - */ 115 - export function initializeTheme(): void { 116 - const { isDarkMode, themeId } = getThemePreferences(); 117 - applyTheme(isDarkMode, themeId); 118 - 119 - // Update meta tag when DOM is ready 120 - if (document.readyState === "loading") { 121 - document.addEventListener("DOMContentLoaded", updateThemeColorMeta); 122 - } else { 123 - updateThemeColorMeta(); 124 - } 125 - } 126 - 127 - // Auto-initialize when script loads (for inline usage) 128 - if (typeof window !== "undefined") { 129 - initializeTheme(); 130 - }
-121
src/lib/utils/formatters.ts
··· 1 - /** 2 - * Returns the ordinal suffix for a given number (e.g., "st", "nd", "rd", "th"). 3 - * @param num The number to get the ordinal suffix for. 4 - * @returns The ordinal suffix. 5 - */ 6 - export function getOrdinalSuffix(num: number): string { 7 - const lastDigit = num % 10; 8 - const lastTwoDigits = num % 100; 9 - 10 - if (lastTwoDigits >= 11 && lastTwoDigits <= 13) { 11 - return 'th'; 12 - } 13 - 14 - switch (lastDigit) { 15 - case 1: 16 - return 'st'; 17 - case 2: 18 - return 'nd'; 19 - case 3: 20 - return 'rd'; 21 - default: 22 - return 'th'; 23 - } 24 - } 25 - 26 - export function formatDate( 27 - date: Date | string, 28 - locale: string = typeof window !== "undefined" 29 - ? window.navigator.language 30 - : "en-GB" 31 - ): string { 32 - const dateObj = new Date(date); 33 - 34 - const options: Intl.DateTimeFormatOptions = { 35 - year: "numeric", 36 - month: "long", 37 - day: "numeric", 38 - hour: "2-digit", 39 - minute: "2-digit", 40 - }; 41 - 42 - const formattedDate = new Intl.DateTimeFormat(locale, options).format( 43 - dateObj 44 - ); 45 - 46 - // Only add ordinal suffix for English locales 47 - if (locale.startsWith("en")) { 48 - const day = dateObj.getDate(); 49 - return formattedDate.replace(/(\d+)/, `$1${getOrdinalSuffix(day)}`); 50 - } 51 - 52 - return formattedDate; 53 - } 54 - 55 - export function formatMonthYear( 56 - date: Date | string, 57 - locale: string = typeof window !== "undefined" 58 - ? window.navigator.language 59 - : "en-GB" 60 - ): string { 61 - const dateObj = new Date(date); 62 - 63 - const options: Intl.DateTimeFormatOptions = { 64 - year: "numeric", 65 - month: "long", 66 - }; 67 - 68 - return new Intl.DateTimeFormat(locale, options).format(dateObj); 69 - } 70 - 71 - // Function to format a date relative to the current time (e.g., '2 hours ago') 72 - export function formatRelativeTime( 73 - date: Date | string, 74 - locale: string = typeof window !== "undefined" 75 - ? window.navigator.language 76 - : "en-GB" 77 - ): string { 78 - const dateObj = new Date(date); 79 - const now = new Date(); 80 - const diffInSeconds = Math.round((now.getTime() - dateObj.getTime()) / 1000); 81 - 82 - const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" }); 83 - 84 - const units: { unit: Intl.RelativeTimeFormatUnit; seconds: number }[] = [ 85 - { unit: "year", seconds: 31536000 }, 86 - { unit: "month", seconds: 2592000 }, 87 - { unit: "week", seconds: 604800 }, 88 - { unit: "day", seconds: 86400 }, 89 - { unit: "hour", seconds: 3600 }, 90 - { unit: "minute", seconds: 60 }, 91 - { unit: "second", seconds: 1 }, 92 - ]; 93 - 94 - for (const { unit, seconds } of units) { 95 - if (Math.abs(diffInSeconds) >= seconds) { 96 - const value = Math.round(diffInSeconds / seconds); 97 - return rtf.format(-value, unit); 98 - } 99 - } 100 - 101 - return rtf.format(0, "second"); // Should ideally not happen if date is in the past 102 - } 103 - 104 - /** 105 - * Formats a number according to the specified locale and options. 106 - * @param value The number to format. 107 - * @param locale The locale to use for formatting (e.g., 'en-GB', 'en-US'). Defaults to 'en-GB'. 108 - * @param options Options for number formatting, conforming to Intl.NumberFormatOptions. 109 - * @returns The formatted number string. 110 - */ 111 - export function formatNumber(value: number, locale: string = 'en-GB', options?: Intl.NumberFormatOptions): string { 112 - if (typeof value !== 'number') { 113 - return String(value); // Return as string if not a number 114 - } 115 - try { 116 - return new Intl.NumberFormat(locale, options).format(value); 117 - } catch (error) { 118 - console.error(`Error formatting number for locale ${locale}:`, error); 119 - return value.toLocaleString(locale); // Fallback to basic toLocaleString on error 120 - } 121 - }
-100
src/lib/utils/milestones.ts
··· 1 - import { formatNumber, getOrdinalSuffix } from './formatters'; 2 - 3 - 4 - export interface Milestone { 5 - text: string; 6 - emoji: string; 7 - type: 'special' | 'major' | 'minor'; 8 - } 9 - 10 - /** 11 - * Determines if a post number represents a milestone and returns milestone info 12 - */ 13 - export function getMilestone(postNumber: number): Milestone | null { 14 - // Special milestones defined in a more maintainable structure. 15 - const specialMilestones: { number: number; text: string; emoji: string; }[] = [ 16 - { number: 1, text: "First Post!", emoji: "๐ŸŽ‰" }, 17 - { number: 100, text: "Centennial Post!", emoji: "๐Ÿ’ฏ" }, 18 - { number: 365, text: "Daily Dose Complete!", emoji: "๏ฟฝ" }, 19 - { number: 500, text: "Half Thousand!", emoji: "๐Ÿ†" }, 20 - { number: 1000, text: "One Thousand Posts!", emoji: "๐ŸŒŸ" }, 21 - { number: 10000, text: "Ten Thousand Posts!", emoji: "๐Ÿš€" }, 22 - { number: 200, text: "Double Century!", emoji: "๐ŸŽ‰๐ŸŽ‰" }, 23 - { number: 250, text: "Quarter Thousand!", emoji: "โœจโœจ" }, 24 - { number: 750, text: "Three-Quarter Thousand!", emoji: "๐Ÿ’ซ๐Ÿ’ซ" }, 25 - ]; 26 - 27 - for (const milestone of specialMilestones) { 28 - if (postNumber === milestone.number) { 29 - return { 30 - text: milestone.text, 31 - emoji: milestone.emoji, 32 - type: 'special' 33 - }; 34 - } 35 - } 36 - 37 - // Major milestones (every 50 posts after 100) 38 - if (postNumber > 100 && postNumber % 250 === 0) { 39 - return { 40 - text: `${formatNumber(postNumber)} Posts!`, 41 - emoji: "๏ฟฝ", 42 - type: 'major' 43 - }; 44 - } 45 - 46 - if (postNumber > 100 && postNumber % 50 === 0) { 47 - return { 48 - text: `${formatNumber(postNumber)} Posts!`, 49 - emoji: "๐ŸŽฏ", 50 - type: 'major' 51 - }; 52 - } 53 - 54 - // Specific major milestone that doesn't fit the general rule. 55 - if (postNumber === 150) { 56 - return { 57 - text: "One Hundred Fifty Posts!", 58 - emoji: "๐ŸŽ‰", 59 - type: 'major' 60 - }; 61 - } 62 - 63 - // Minor milestones (every 10 posts, but not major milestones). 64 - // This check should come after special and major milestones to ensure correct precedence. 65 - if (postNumber % 10 === 0 && postNumber % 50 !== 0) { 66 - const ordinal = getOrdinal(postNumber); 67 - return { 68 - text: `${ordinal} Post!`, 69 - emoji: "โœจ", 70 - type: 'minor' 71 - }; 72 - } 73 - 74 - // Very special fun ones that are not part of the main special milestones array. 75 - const funMilestones: { number: number; text: string; emoji: string; }[] = [ 76 - { number: 404, text: "Post Not Found!", emoji: "๐Ÿ”" }, 77 - { number: 123, text: "One Two Three!", emoji: "๐Ÿ”ข" }, 78 - { number: 333, text: "Triple Three!", emoji: "โœจโœจโœจ" }, 79 - ]; 80 - 81 - for (const milestone of funMilestones) { 82 - if (postNumber === milestone.number) { 83 - return { 84 - text: milestone.text, 85 - emoji: milestone.emoji, 86 - type: 'special' 87 - }; 88 - } 89 - } 90 - 91 - return null; 92 - } 93 - 94 - /** 95 - * Converts a number to its ordinal form (1st, 2nd, 3rd, etc.) 96 - */ 97 - function getOrdinal(num: number): string { 98 - const formatted = formatNumber(num); 99 - return formatted + getOrdinalSuffix(num); 100 - }
-40
src/lib/utils/tally.ts
··· 1 - /** 2 - * Calculates the total read time for a given array of posts. 3 - * Assumes an average reading speed of 200 words per minute. 4 - * @param posts - An array of post objects, each with a 'wordCount' property. 5 - * @returns The total read time in minutes, rounded up. 6 - */ 7 - export function calculateTotalReadTime(posts: { wordCount: number }[]): number { 8 - return posts.reduce((total, post) => { 9 - return total + Math.ceil(post.wordCount / 200); 10 - }, 0); 11 - } 12 - 13 - /** 14 - * Calculates the total word count for a given array of posts. 15 - * @param posts - An array of post objects, each with a 'wordCount' property. 16 - * @returns The total word count. 17 - */ 18 - export function calculateTotalWordCount(posts: { wordCount: number }[]): number { 19 - return posts.reduce((total, post) => total + post.wordCount, 0); 20 - } 21 - 22 - /** 23 - * Formats a given number of minutes into a human-readable string (e.g., "2 hours", "3 days"). 24 - * @param minutes - The total number of minutes. 25 - * @returns A formatted string representing the time. 26 - */ 27 - export function formatReadTime(minutes: number): string { 28 - if (minutes < 60) { 29 - return `${minutes} min`; 30 - } else if (minutes < 60 * 24) { 31 - const hours = Math.round(minutes / 60); 32 - return `${hours} hour${hours === 1 ? '' : 's'}`; 33 - } else if (minutes < 60 * 24 * 7) { 34 - const days = Math.round(minutes / (60 * 24)); 35 - return `${days} day${days === 1 ? '' : 's'}`; 36 - } else { 37 - const weeks = Math.round(minutes / (60 * 24 * 7)); 38 - return `${weeks} week${weeks === 1 ? '' : 's'}`; 39 - } 40 - }
-69
src/lib/utils/textProcessor.ts
··· 1 - import remarkParse from "remark-parse"; 2 - import remarkGfm from "remark-gfm"; 3 - import remarkRehype from "remark-rehype"; 4 - import rehypeStringify from "rehype-stringify"; 5 - import { unified } from "unified"; 6 - import type { Node } from "unist"; 7 - 8 - type TextNode = Node & { type: "text"; value: string }; 9 - type ParentNode = Node & { children: Node[] }; 10 - 11 - /** 12 - * Extracts plain text from markdown content and truncates it to a specified length. 13 - * @param markdown The markdown content to process. 14 - * @param maxLength The maximum length of the extracted text (default: 160). 15 - * @returns A promise that resolves to the extracted and truncated plain text. 16 - */ 17 - export async function extractTextFromMarkdown( 18 - markdown: string, 19 - maxLength: number = 160 20 - ): Promise<string> { 21 - // Process the markdown to get plain text 22 - const plainText = String( 23 - await unified() 24 - .use(remarkParse, { fragment: true }) 25 - .use(remarkGfm) 26 - .use(() => (tree) => { 27 - // Simple transformer that visits all nodes and removes everything but text 28 - const visit = (node: Node): string => { 29 - if (node.type === "text") { 30 - const textNode = node as TextNode; 31 - return textNode.value; 32 - } 33 - if ("children" in node) { 34 - const parentNode = node as ParentNode; 35 - return parentNode.children.map(visit).filter(Boolean).join(" "); 36 - } 37 - return ""; 38 - }; 39 - 40 - // Replace tree with just text content 41 - return { 42 - type: "root", 43 - children: [{ type: "text", value: visit(tree) }], 44 - }; 45 - }) 46 - .use(remarkRehype) 47 - .use(rehypeStringify) 48 - .process(markdown) 49 - ); 50 - 51 - // Clean up the text 52 - let cleaned = plainText.replace(/\s+/g, " ").trim(); 53 - 54 - // Truncate to maxLength if necessary 55 - if (cleaned.length > maxLength) { 56 - cleaned = cleaned.substring(0, maxLength) + "..."; 57 - } 58 - 59 - return cleaned; 60 - } 61 - 62 - /** 63 - * Calculates the word count of a given string. 64 - * @param text The input string. 65 - * @returns The number of words in the string. 66 - */ 67 - export function calculateWordCount(text: string): number { 68 - return text.split(/\s+/).filter((word) => word.length > 0).length; 69 - }
+9 -20
src/routes/+layout.svelte
··· 1 1 <script lang="ts"> 2 2 import "$css/app.css"; 3 - import { getStores } from "$app/stores"; 4 - const { page } = getStores(); 5 - import Profile from "$components/profile/Profile.svelte"; 6 - import { Navigation, Footer } from "$components/layout"; 3 + import { Footer } from "$components/layout"; 4 + import DirectoryHeader from "$lib/components/layout/DirectoryHeader.svelte"; 7 5 8 6 let { data, children } = $props(); 9 - 10 - // Check if we're on the home page or blog page using $derived 11 - const showProfile = $derived( 12 - $page.route.id ? ["/", "/blog"].includes($page.route.id) : false 13 - ); 14 - const isHomePage = $derived($page.route.id === "/"); 15 - const isBlogIndex = $derived($page.route.id === "/blog"); 16 7 </script> 17 8 18 - <div class="box-border mx-auto px-4 sm:px-8 max-w-[1000px] pb-8"> 19 - <Navigation {isHomePage} {isBlogIndex} /> 20 - 21 - {#if showProfile} 22 - <Profile profile={data.profile} /> 23 - {/if} 24 - 25 - {@render children()} 9 + <div class="min-h-screen"> 10 + <DirectoryHeader /> 11 + 12 + <div class="box-border mx-auto px-4 sm:px-8 max-w-[1000px] pb-8"> 13 + {@render children()} 26 14 27 - <Footer profile={data.profile} posts={data.posts} /> 15 + <Footer profile={data.profile} /> 16 + </div> 28 17 </div>
+90 -20
src/routes/+layout.ts
··· 1 - import { getProfile } from "$components/profile/profile"; 2 - import { getLatestPosts } from "$services/blogService"; 1 + import { getProfile, safeFetch } from "$components/profile/profile"; 3 2 import type { Profile, LinkBoard } from "$components/shared"; 3 + import { LINKAT_USERS } from "$lib/config/linkat-users"; 4 + import { env } from "$env/dynamic/public"; 4 5 5 6 // Profile data cache 6 - let profile: Profile; 7 + let profile: Profile | undefined; 7 8 let dynamicLinks: LinkBoard | undefined; 8 9 9 10 export async function load({ fetch }) { 10 - if (profile === undefined) { 11 - profile = await getProfile(fetch); 11 + const userDids = LINKAT_USERS; 12 + 13 + // If no users configured, return empty state 14 + if (userDids.length === 0) { 15 + return { 16 + profile: null, 17 + pdsUrl: null, 18 + did: null, 19 + posts: new Map(), 20 + dynamicLinks: null, 21 + userLinkBoards: {}, 22 + linkatUsers: [], 23 + noUsersConfigured: true, 24 + }; 25 + } 26 + 27 + // Use the first user as primary if not already cached 28 + const primaryUserDid = userDids[0]; 29 + if (!profile || profile.did !== primaryUserDid) { 30 + // Create a mock profile if we can't fetch the real one 31 + try { 32 + // Temporarily set env to the primary user for getProfile 33 + const originalEnv = env.DIRECTORY_OWNER; 34 + env.DIRECTORY_OWNER = primaryUserDid; 35 + profile = await getProfile(fetch); 36 + if (originalEnv) env.DIRECTORY_OWNER = originalEnv; 37 + } catch (error) { 38 + console.error("Error fetching primary user profile:", error); 39 + // Create fallback profile 40 + profile = { 41 + avatar: "", 42 + banner: "", 43 + displayName: "Linkat User", 44 + did: primaryUserDid, 45 + handle: primaryUserDid, 46 + description: "Linkat directory user", 47 + pds: "https://bsky.social", 48 + }; 49 + } 12 50 } 13 51 14 - // Fetch dynamic links only if not already cached 15 - if (dynamicLinks === undefined) { 52 + const userLinkBoards: { [did: string]: LinkBoard | undefined } = {}; 53 + 54 + // Fetch dynamic links for all configured users 55 + for (const userDid of userDids) { 16 56 try { 17 - const rawResponse = await fetch( 18 - `${profile.pds}/xrpc/com.atproto.repo.listRecords?repo=${profile.did}&collection=blue.linkat.board&rkey=self` 19 - ); 20 - const response = await rawResponse.json(); 21 - if (response && response.records && response.records.length > 0) { 22 - dynamicLinks = response.records[0].value as LinkBoard; 57 + // Get user's PDS 58 + const split = userDid.split(":"); 59 + let pdsurl; 60 + if (split[0] === "did") { 61 + if (split[1] === "plc") { 62 + const diddoc = await safeFetch(`https://plc.directory/${userDid}`, fetch); 63 + for (const service of diddoc["service"]) { 64 + if (service["id"] === "#atproto_pds") { 65 + pdsurl = service["serviceEndpoint"]; 66 + break; 67 + } 68 + } 69 + } else if (split[1] === "web") { 70 + pdsurl = `https://${split[2]}`; 71 + } 72 + } 73 + 74 + if (pdsurl) { 75 + const rawResponse = await fetch( 76 + `${pdsurl}/xrpc/com.atproto.repo.listRecords?repo=${userDid}&collection=blue.linkat.board&rkey=self` 77 + ); 78 + const response = await rawResponse.json(); 79 + if (response && response.records && response.records.length > 0) { 80 + userLinkBoards[userDid] = response.records[0].value as LinkBoard; 81 + } 23 82 } 24 83 } catch (error) { 25 - console.error("Error fetching dynamic links:", error); 84 + console.error(`Error fetching dynamic links for ${userDid}:`, error); 26 85 } 27 86 } 28 87 29 - // Fetch latest blog posts using the consolidated service 30 - const latestPosts = await getLatestPosts(fetch, 3); 88 + // For backward compatibility, keep the single dynamicLinks 89 + dynamicLinks = profile ? userLinkBoards[profile.did] : undefined; 31 90 32 91 return { 33 92 profile, 34 - pdsUrl: profile.pds, 35 - did: profile.did, 36 - posts: new Map(), // Keep this for compatibility with existing Footer component 93 + pdsUrl: profile?.pds, 94 + did: profile?.did, 95 + posts: new Map(), 37 96 dynamicLinks, 38 - latestPosts, 97 + userLinkBoards, 98 + linkatUsers: userDids.filter(did => { 99 + const hideOwnerCard = env.HIDE_OWNER_CARD === 'true'; 100 + if (hideOwnerCard && did === primaryUserDid) { 101 + return false; // Hide the owner's card if HIDE_OWNER_CARD is true 102 + } 103 + return true; // Always include the user if not hidden 104 + }), 105 + noUsersConfigured: false, 106 + primaryUserDid, 107 + displayUserBanner: env.DISPLAY_USER_BANNER === 'true', 108 + displayUserDescription: env.DISPLAY_USER_DESCRIPTION === 'true', 39 109 }; 40 110 }
+117 -51
src/routes/+page.svelte
··· 1 1 <script lang="ts"> 2 - import { onMount } from "svelte"; 3 2 import { getStores } from "$app/stores"; 3 + import { env } from "$env/dynamic/public"; 4 + import UserDirectory from "$lib/components/archive/UserDirectory.svelte"; 5 + import DynamicHead from "$lib/components/layout/DynamicHead.svelte"; 6 + import { getProfile } from "$lib/components/profile/profile"; 7 + 4 8 const { page } = getStores(); 5 - import { DynamicLinks, LatestBlogPost } from "$components/layout/main"; 6 - 7 9 let { data } = $props(); 8 10 9 - // State to track if locale has been properly loaded 10 - let localeLoaded = $state(false); 11 + // Environment variable for directory owner 12 + let directoryOwner = env.DIRECTORY_OWNER ?? ""; 11 13 12 - onMount(() => { 13 - // Set a brief timeout to ensure the browser has time to determine locale 14 - setTimeout(() => { 15 - localeLoaded = true; 16 - }, 10); 14 + // Profile state for directory owner - initialize with data.profile if available 15 + let ownerProfile = $state<{ displayName?: string; handle?: string } | null>( 16 + data.profile || null 17 + ); 18 + 19 + // Load the directory owner's profile only if we don't already have it 20 + $effect(() => { 21 + if (directoryOwner && !ownerProfile) { 22 + const loadOwner = async () => { 23 + try { 24 + const result = await getProfile(fetch); 25 + ownerProfile = result; 26 + } catch (err) { 27 + console.error("Could not fetch owner profile:", err); 28 + ownerProfile = null; 29 + } 30 + }; 31 + loadOwner(); 32 + } 17 33 }); 18 - </script> 19 34 20 - <svelte:head> 21 - <title>Site Name</title> 22 - <meta 23 - name="description" 24 - content="Welcome to Site Name - A personal space where I share my thoughts on coding, technology, and life." 25 - /> 26 - <meta 27 - name="keywords" 28 - content="Ewan, personal website, coding, technology, programming, tech blog, Site Name" 29 - /> 35 + // Derived reactive values for user display options 36 + let displayUserBanner = $derived(data.displayUserBanner); 37 + let displayUserDescription = $derived(data.displayUserDescription); 30 38 31 - <!-- Open Graph / Facebook --> 32 - <meta property="og:type" content="website" /> 33 - <meta property="og:url" content={$page.url.origin + $page.url.pathname} /> 34 - <meta property="og:title" content="Site Title" /> 35 - <meta 36 - property="og:description" 37 - content="Welcome to Site Name - A personal space where I share my thoughts on coding, technology, and life." 38 - /> 39 - <meta property="og:site_name" content="Site Name" /> 40 - {#if $page.url.origin} 41 - <meta property="og:image" content={$page.url.origin + "/embed/main.png"} /> 42 - {/if} 43 - <meta property="og:image:width" content="1200" /> 44 - <meta property="og:image:height" content="630" /> 39 + /** 40 + * Shuffles an array in place using the Fisher-Yates (Knuth) algorithm. 41 + * @param array The array to shuffle. 42 + * @returns The shuffled array. 43 + */ 44 + function shuffleArray<T>(array: T[]): T[] { 45 + let currentIndex = array.length, randomIndex; 45 46 46 - <!-- Twitter --> 47 - <meta name="twitter:card" content="summary_large_image" /> 48 - <meta name="twitter:url" content={$page.url.origin + $page.url.pathname} /> 49 - <meta name="twitter:title" content="Site Title" /> 50 - <meta 51 - name="twitter:description" content="A personal space where I share my thoughts on coding, technology, and life." 52 - /> 53 - {#if $page.url.origin} 54 - <meta name="twitter:image" content={$page.url.origin + "/embed/main.png"} /> 55 - {/if} 56 - </svelte:head> 47 + while (currentIndex !== 0) { 48 + randomIndex = Math.floor(Math.random() * currentIndex); 49 + currentIndex--; 57 50 58 - <!-- Latest Blog Post section (only show if we have posts) --> 59 - {#if data.latestPosts && data.latestPosts.length > 0} 60 - <LatestBlogPost posts={data.latestPosts} {localeLoaded} /> 61 - {/if} 51 + [array[currentIndex], array[randomIndex]] = [ 52 + array[randomIndex], 53 + array[currentIndex], 54 + ]; 55 + } 56 + return array; 57 + } 58 + 59 + const getDisplayName = (p: { displayName?: string; handle?: string } | null | undefined) => 60 + p?.displayName || p?.handle || null; 62 61 63 - <DynamicLinks data={data.dynamicLinks} /> 62 + // Computed title that prioritizes display name, then handle, then DID 63 + const pageTitle = $derived(() => { 64 + if (!directoryOwner) return "Linkat Directory"; 65 + 66 + const displayName = getDisplayName(ownerProfile); 67 + if (displayName) { 68 + return `${displayName}'s Linkat Directory`; 69 + } 70 + 71 + // Fallback to directoryOwner (DID) while loading 72 + return `${directoryOwner}'s Linkat Directory`; 73 + }); 74 + 75 + const pageDescription = $derived(() => { 76 + if (!directoryOwner) return "Discover amazing users curated by the Linkat community"; 77 + 78 + const displayName = getDisplayName(ownerProfile) || directoryOwner; 79 + return `Discover users' links curated by ${displayName} in ${displayName}'s Linkat Directory`; 80 + }); 81 + 82 + const pageKeywords = $derived(() => { 83 + const baseKeywords = "Linkat, directory, links, Bluesky, community, curation"; 84 + if (!directoryOwner) return baseKeywords; 85 + 86 + const displayName = getDisplayName(ownerProfile) || directoryOwner; 87 + return `${baseKeywords}, ${displayName}`; 88 + }); 89 + </script> 90 + 91 + <DynamicHead 92 + title={pageTitle()} 93 + description={pageDescription()} 94 + keywords={pageKeywords()} 95 + ogTitle={pageTitle()} 96 + ogDescription={pageDescription()} 97 + twitterTitle={pageTitle()} 98 + twitterDescription={pageDescription()} 99 + /> 100 + 101 + <div class="container mx-auto px-4 py-8"> 102 + {#if data.noUsersConfigured} 103 + <div class="text-center py-12"> 104 + <div class="max-w-4xl mx-auto px-4"> 105 + <p class="text-lg mb-4 opacity-75"> 106 + Welcome to Linkat Directory! No users are currently configured. 107 + </p> 108 + <div class="bg-[var(--muted-bg)] rounded-lg p-6 text-left overflow-hidden"> 109 + <h3 class="font-semibold mb-2">To get started:</h3> 110 + <ol class="list-decimal list-inside space-y-2 text-sm"> 111 + <li class="break-words">Copy <code class="break-all bg-[var(--card-bg)] px-1 py-0.5 rounded text-xs">. env.example</code> to <code class="break-all bg-[var(--card-bg)] px-1 py-0.5 rounded text-xs">.env</code></li> 112 + <li class="break-words">Set your DID: <code class="break-all bg-[var(--card-bg)] px-1 py-0.5 rounded text-xs">DIRECTORY_OWNER=did:plc:your-did-here</code></li> 113 + <li class="break-words">Set the origin: <code class="break-all bg-[var(--card-bg)] px-1 py-0.5 rounded text-xs">PUBLIC_ORIGIN=http://localhost:5713</code></li> 114 + <li class="break-words">Optionally add more users: <code class="break-all bg-[var(--card-bg)] px-1 py-0.5 rounded text-xs">PUBLIC_LINKAT_USERS=did:plc:user1,did:plc:user2</code></li> 115 + <li class="break-words">Restart the development server</li> 116 + </ol> 117 + </div> 118 + </div> 119 + </div> 120 + {:else} 121 + <UserDirectory 122 + users={shuffleArray([...data.linkatUsers]).map(did => ({ did }))} 123 + primaryUserDid={directoryOwner} 124 + userLinkBoards={data.userLinkBoards} 125 + displayBanner={displayUserBanner} 126 + displayDescription={displayUserDescription} 127 + /> 128 + {/if} 129 + </div>
-8
src/routes/blog/+layout.ts
··· 1 - import { loadAllPosts } from "$services/blogService"; 2 - 3 - export const prerender = false; 4 - export const trailingSlash = "never"; 5 - 6 - export async function load({ fetch }) { 7 - return await loadAllPosts(fetch); 8 - }
-199
src/routes/blog/+page.svelte
··· 1 - <script lang="ts"> 2 - import { onMount } from "svelte"; 3 - import YearTabs from "$components/archive/YearTabs.svelte"; 4 - import YearContent from "$components/archive/YearContent.svelte"; 5 - import { getStores } from "$app/stores"; 6 - const { page } = getStores(); 7 - const { data } = $props(); 8 - import type { Post } from "$components/shared"; 9 - 10 - // Get posts from data with enhanced validation 11 - const posts = $derived( 12 - Array.from((data.posts || new Map()).values() as Iterable<Post>) 13 - .filter((post) => { 14 - // Enhanced validation for posts 15 - const hasValidTitle = post.title && typeof post.title === 'string'; 16 - const hasValidDate = post.createdAt instanceof Date && !isNaN(post.createdAt.getTime()); 17 - const hasValidContent = post.content && typeof post.content === 'string'; 18 - const hasValidRkey = post.rkey && typeof post.rkey === 'string'; 19 - 20 - const isValid = hasValidTitle && hasValidDate && hasValidContent && hasValidRkey; 21 - 22 - if (!isValid && process.env.NODE_ENV === 'development') { 23 - console.warn('Invalid post filtered out:', { 24 - title: post.title, 25 - rkey: post.rkey, 26 - hasValidTitle, 27 - hasValidDate, 28 - hasValidContent, 29 - hasValidRkey, 30 - createdAt: post.createdAt, 31 - }); 32 - } 33 - 34 - return isValid; 35 - }) 36 - .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()) 37 - ); 38 - 39 - // State to track if locale has been properly loaded 40 - let localeLoaded = $state(false); 41 - 42 - onMount(() => { 43 - // Set a brief timeout to ensure the browser has time to determine locale 44 - setTimeout(() => { 45 - localeLoaded = true; 46 - }, 10); 47 - }); 48 - 49 - // Helper function to get only month name 50 - function getMonthName(date: Date): string { 51 - try { 52 - return new Intl.DateTimeFormat( 53 - typeof window !== "undefined" ? window.navigator.language : "en-GB", 54 - { month: "long" } 55 - ).format(date); 56 - } catch (error) { 57 - console.warn('Error formatting month name:', error); 58 - return date.toLocaleDateString('en-GB', { month: 'long' }); 59 - } 60 - } 61 - 62 - // Group posts by year and month 63 - type YearMonthGroup = { 64 - year: number; 65 - months: Record<string, Post[]>; 66 - }; 67 - 68 - const groupedByYear = $derived( 69 - (() => { 70 - if (!posts || posts.length === 0) { 71 - return []; 72 - } 73 - 74 - const groups: Record<number, Record<string, Post[]>> = {}; 75 - 76 - posts.forEach((post) => { 77 - try { 78 - const year = post.createdAt.getFullYear(); 79 - const month = getMonthName(post.createdAt); 80 - 81 - if (!groups[year]) groups[year] = {}; 82 - if (!groups[year][month]) groups[year][month] = []; 83 - 84 - groups[year][month].push(post); 85 - } catch (error) { 86 - console.warn('Error grouping post:', { post, error }); 87 - } 88 - }); 89 - 90 - // Convert to array of year groups sorted by year (descending) 91 - return Object.entries(groups) 92 - .sort(([yearA], [yearB]) => Number(yearB) - Number(yearA)) 93 - .map(([year, months]) => ({ 94 - year: Number(year), 95 - months, 96 - })); 97 - })() as YearMonthGroup[] 98 - ); 99 - 100 - // State for active year tab 101 - let activeYear = $state(0); 102 - 103 - // Set initial active year when data is loaded 104 - $effect(() => { 105 - if (groupedByYear.length > 0) { 106 - activeYear = groupedByYear[0].year; 107 - } 108 - }); 109 - 110 - // Computed loading and error states 111 - const isLoading = $derived(!localeLoaded); 112 - const hasData = $derived(data && data.posts && data.posts.size > 0); 113 - const hasValidPosts = $derived(posts && posts.length > 0); 114 - const hasProfile = $derived(data && data.profile); 115 - </script> 116 - 117 - <svelte:head> 118 - <title>Blog - Site Name</title> 119 - <meta 120 - name="description" 121 - content="Welcome to Blog - Site Name - Keywords" 122 - /> 123 - <meta 124 - name="keywords" 125 - content="personal blog, Blog - Site Name" 126 - /> 127 - <link 128 - rel="alternate" 129 - type="application/rss+xml" 130 - title="Blog - Site Name RSS Feed" 131 - href="{$page.url.origin}/blog/rss" 132 - /> 133 - 134 - <!-- Open Graph / Facebook --> 135 - <meta property="og:type" content="website" /> 136 - <meta property="og:url" content={$page.url.origin + $page.url.pathname} /> 137 - <meta property="og:title" content="Blog - Site Title" /> 138 - <meta 139 - property="og:description" 140 - content="Welcome to Blog - Site Name - Keywords" 141 - /> 142 - <meta property="og:site_name" content="Blog - Site Name" /> 143 - {#if $page.url.origin} 144 - <meta property="og:image" content={$page.url.origin + "/embed/blog.png"} /> 145 - {/if} 146 - <meta property="og:image:width" content="1200" /> 147 - <meta property="og:image:height" content="630" /> 148 - 149 - <!-- Twitter --> 150 - <meta name="twitter:card" content="summary_large_image" /> 151 - <meta name="twitter:url" content={$page.url.origin + $page.url.pathname} /> 152 - <meta name="twitter:title" content="Blog - Site Title" /> 153 - <meta 154 - name="twitter:description" content="Keywords" 155 - /> 156 - {#if $page.url.origin} 157 - <meta name="twitter:image" content={$page.url.origin + "/embed/blog.png"} /> 158 - {/if} 159 - </svelte:head> 160 - 161 - {#if isLoading} 162 - <div 163 - class="flex justify-center items-center min-h-[200px] text-lg text-[var(--text-color)] opacity-70" 164 - > 165 - Loading... 166 - </div> 167 - {:else if !hasProfile} 168 - <div 169 - class="flex flex-col items-center justify-center min-h-[200px] text-lg text-[var(--text-color)] opacity-70 text-center" 170 - > 171 - <p>Unable to load profile data.</p> 172 - <p class="mt-2 text-sm">Please try refreshing the page.</p> 173 - </div> 174 - {:else if !hasData} 175 - <div 176 - class="flex flex-col items-center justify-center min-h-[200px] text-lg text-[var(--text-color)] opacity-70 text-center" 177 - > 178 - <p>No blog data available.</p> 179 - <p class="mt-2 text-sm">This blog uses the <a href="https://whtwnd.com">WhiteWind</a> blogging lexicon, 180 - <code>com.whtwnd.blog.entry</code>, but there seem to be no records available.</p> 181 - </div> 182 - {:else if !hasValidPosts} 183 - <div 184 - class="flex flex-col items-center justify-center min-h-[200px] text-lg text-[var(--text-color)] opacity-70 text-center" 185 - > 186 - <p>No valid blog posts found.</p> 187 - <p class="mt-2 text-sm">Posts were found but none have valid content, titles, and dates.</p> 188 - </div> 189 - {:else} 190 - <!-- Year tabs with animated indicator --> 191 - <YearTabs {groupedByYear} bind:activeYear /> 192 - 193 - <!-- Content for active year with animations --> 194 - {#each groupedByYear as { year, months } (year)} 195 - {#if year === activeYear} 196 - <YearContent {year} {months} {localeLoaded} /> 197 - {/if} 198 - {/each} 199 - {/if}
-50
src/routes/blog/[rkey]/+page.svelte
··· 1 - <script lang="ts" module> 2 - declare global { 3 - interface Window { 4 - $page: { 5 - url: URL; 6 - }; 7 - } 8 - } 9 - </script> 10 - 11 - <script lang="ts"> 12 - import { onMount } from "svelte"; 13 - import type { Post } from "$components/shared"; 14 - import { 15 - PostHead, 16 - PostHeader, 17 - PostContent, 18 - PostNavigation, 19 - } from "$components/post"; 20 - import { NotFoundMessage } from "$components/shared"; 21 - 22 - let { data }: { data: any } = $props(); 23 - let post = $derived(data.post as Post); 24 - let adjacentPosts = $derived(data.adjacentPosts); 25 - 26 - // State to track if locale has been properly loaded 27 - let localeLoaded = $state(false); 28 - 29 - onMount(() => { 30 - // Set localeLoaded to true when component is mounted in the browser 31 - localeLoaded = true; 32 - }); 33 - </script> 34 - 35 - <PostHead {post} /> 36 - 37 - {#if post !== undefined} 38 - <div class="max-w-4xl mx-auto px-4"> 39 - <PostHeader 40 - {post} 41 - profile={data.profile} 42 - rkey={data.rkey} 43 - {localeLoaded} 44 - /> 45 - <PostContent {post} /> 46 - <PostNavigation {adjacentPosts} /> 47 - </div> 48 - {:else} 49 - <NotFoundMessage /> 50 - {/if}
-20
src/routes/blog/[rkey]/+page.ts
··· 1 - export const prerender = false; 2 - 3 - export const load = async ({ parent, params }) => { 4 - const { getPost, profile, getAdjacentPosts } = await parent(); 5 - const post = getPost(params.rkey); 6 - 7 - if (!post) return { status: 404 }; 8 - 9 - // Get adjacent posts for navigation 10 - const adjacentPosts = getAdjacentPosts(params.rkey); 11 - 12 - return { 13 - post, 14 - rkey: params.rkey, 15 - posts: new Map([[params.rkey, post]]), 16 - profile, 17 - adjacentPosts, 18 - getAdjacentPosts: () => adjacentPosts, 19 - }; 20 - };
-133
src/routes/blog/rss/+server.ts
··· 1 - import type { RequestHandler } from "./$types"; 2 - import { dev } from "$app/environment"; 3 - import { parse } from "$lib/parser"; 4 - import type { MarkdownPost } from "$components/shared"; 5 - import { getProfile } from "$components/profile/profile"; // Import getProfile 6 - 7 - export const GET: RequestHandler = async ({ url, fetch }) => { 8 - try { 9 - // Use getProfile to get profile data 10 - const profileData = await getProfile(fetch); 11 - 12 - const did = profileData.did; 13 - const pdsUrl = profileData.pds; 14 - 15 - if (!pdsUrl) throw new Error("Could not find PDS URL"); 16 - 17 - // Get blog posts 18 - const postsResponse = await fetch( 19 - `${pdsUrl}/xrpc/com.atproto.repo.listRecords?repo=${did}&collection=com.whtwnd.blog.entry` 20 - ); 21 - if (!postsResponse.ok) 22 - throw new Error(`Posts fetch failed: ${postsResponse.status}`); 23 - const postsData = await postsResponse.json(); 24 - 25 - // Process posts 26 - const mdposts: Map<string, MarkdownPost> = new Map(); 27 - for (const data of postsData.records) { 28 - const matches = data.uri.split("/"); 29 - const rkey = matches[matches.length - 1]; 30 - const record = data.value; 31 - 32 - if ( 33 - matches && 34 - matches.length === 5 && 35 - record && 36 - (record.visibility === "public" || !record.visibility) 37 - ) { 38 - mdposts.set(rkey, { 39 - title: record.title, 40 - createdAt: new Date(record.createdAt), 41 - mdcontent: record.content, 42 - rkey, 43 - }); 44 - } 45 - } 46 - 47 - // Parse markdown posts to HTML 48 - const posts = await parse(mdposts); 49 - 50 - // Sort posts by date (newest first) 51 - const sortedPosts = Array.from(posts.values()).sort( 52 - (a, b) => b.createdAt.getTime() - a.createdAt.getTime() 53 - ); 54 - 55 - // Build the RSS XML 56 - const baseUrl = dev ? url.origin : "https://example.com"; // Update with your production domain 57 - const rssXml = `<?xml version="1.0" encoding="UTF-8" ?> 58 - <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"> 59 - <channel> 60 - <title>Blog - Site Name</title> 61 - <description>Keywords</description> 62 - <link>${baseUrl}/blog</link> 63 - <atom:link href="${baseUrl}/blog/rss" rel="self" type="application/rss+xml" /> 64 - <image> 65 - ${baseUrl ? `<url>${baseUrl}/embed/blog.png</url>` : ''} 66 - <title>Blog - Site Name</title> 67 - <link>${baseUrl}/blog</link> 68 - </image> 69 - <lastBuildDate>${new Date().toUTCString()}</lastBuildDate> 70 - ${sortedPosts 71 - .map( 72 - (post) => ` 73 - <item> 74 - <title>${escapeXml(post.title)}</title> 75 - <link>${baseUrl}/blog/${post.rkey}</link> 76 - <guid isPermaLink="true">${baseUrl}/blog/${post.rkey}</guid> 77 - <pubDate>${new Date(post.createdAt).toUTCString()}</pubDate> 78 - <description><![CDATA[${post.excerpt || ""}]]></description> 79 - <content:encoded><![CDATA[${post.content || ""}]]></content:encoded> 80 - <author>${profileData.displayName || profileData.handle} (${ 81 - profileData.handle 82 - })</author> 83 - ${baseUrl ? `<media:content url="${baseUrl}/embed/blog.png" medium="image" />` : ''} 84 - </item>` 85 - ) 86 - .join("")} 87 - </channel> 88 - </rss>`; 89 - 90 - return new Response(rssXml, { 91 - headers: { 92 - "Content-Type": "application/xml", 93 - "Cache-Control": "max-age=0, s-maxage=3600", 94 - }, 95 - }); 96 - } catch (error) { 97 - console.error("Error generating RSS feed:", error); 98 - 99 - // Return a minimal valid RSS feed in case of error 100 - return new Response( 101 - `<?xml version="1.0" encoding="UTF-8" ?> 102 - <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> 103 - <channel> 104 - <title>Blog - Site Name</title> 105 - <description>Keywords</description> 106 - <link>${url.origin}/blog</link> 107 - <atom:link href="${ 108 - url.origin 109 - }/blog/rss" rel="self" type="application/rss+xml" /> 110 - <lastBuildDate>${new Date().toUTCString()}</lastBuildDate> 111 - <!-- Error occurred while generating feed items --> 112 - </channel> 113 - </rss>`, 114 - { 115 - headers: { 116 - "Content-Type": "application/xml", 117 - "Cache-Control": "no-cache", 118 - }, 119 - } 120 - ); 121 - } 122 - }; 123 - 124 - // Helper function to escape XML special characters 125 - function escapeXml(unsafe: string): string { 126 - if (!unsafe) return ""; 127 - return unsafe 128 - .replace(/&/g, "&amp;") 129 - .replace(/</g, "&lt;") 130 - .replace(/>/g, "&gt;") 131 - .replace(/"/g, "&quot;") 132 - .replace(/'/g, "&apos;"); 133 - }
+76
src/routes/user/[did]/+layout.ts
··· 1 + import type { LayoutLoad } from "./$types"; 2 + 3 + export const load: LayoutLoad = async ({ params, fetch }) => { 4 + const { did } = params; 5 + 6 + try { 7 + // Fetch user profile 8 + const profileResponse = await fetch( 9 + `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${did}` 10 + ); 11 + 12 + if (!profileResponse.ok) { 13 + return { 14 + did, 15 + profile: null, 16 + dynamicLinks: undefined, 17 + error: "User not found" 18 + }; 19 + } 20 + 21 + const profile = await profileResponse.json(); 22 + 23 + // Get user's PDS and fetch Linkat links 24 + const split = did.split(":"); 25 + let pdsurl: string | null = null; 26 + let dynamicLinks = undefined; 27 + 28 + if (split[0] === "did") { 29 + if (split[1] === "plc") { 30 + const diddocResponse = await fetch(`https://plc.directory/${did}`); 31 + if (diddocResponse.ok) { 32 + const diddoc = await diddocResponse.json(); 33 + for (const service of diddoc["service"] || []) { 34 + if (service["id"] === "#atproto_pds") { 35 + pdsurl = service["serviceEndpoint"]; 36 + break; 37 + } 38 + } 39 + } 40 + } else if (split[1] === "web") { 41 + pdsurl = `https://${split[2]}`; 42 + } 43 + } 44 + 45 + if (pdsurl) { 46 + try { 47 + const linksResponse = await fetch( 48 + `${pdsurl}/xrpc/com.atproto.repo.listRecords?repo=${did}&collection=blue.linkat.board&rkey=self` 49 + ); 50 + 51 + if (linksResponse.ok) { 52 + const result = await linksResponse.json(); 53 + if (result.records && result.records.length > 0) { 54 + dynamicLinks = result.records[0].value; 55 + } 56 + } 57 + } catch (error) { 58 + console.error("Error fetching dynamic links:", error); 59 + } 60 + } 61 + 62 + return { 63 + did, 64 + profile, 65 + dynamicLinks, 66 + error: null 67 + }; 68 + } catch (error) { 69 + return { 70 + did, 71 + profile: null, 72 + dynamicLinks: undefined, 73 + error: error instanceof Error ? error.message : "An error occurred" 74 + }; 75 + } 76 + };
+120
src/routes/user/[did]/+page.svelte
··· 1 + <script lang="ts"> 2 + import DynamicLinks from "$lib/components/layout/main/DynamicLinks.svelte"; 3 + import DynamicHead from "$lib/components/layout/DynamicHead.svelte"; 4 + import { getStores } from "$app/stores"; 5 + import { env } from "$env/dynamic/public"; 6 + import { getProfile } from "$components/profile/profile"; 7 + 8 + const { page } = getStores(); 9 + let { data } = $props(); 10 + 11 + let profile = $derived(data.profile); 12 + let dynamicLinks = $derived(data.dynamicLinks); 13 + let error = $derived(data.error); 14 + let did = $derived(data.did); 15 + 16 + let directoryOwner = env.DIRECTORY_OWNER; 17 + let ownerProfile = $state<{ displayName?: string; handle?: string } | null>(null); 18 + 19 + $effect(() => { 20 + if (directoryOwner) { 21 + const loadOwner = async () => { 22 + try { 23 + const result = await getProfile(fetch); 24 + ownerProfile = result; 25 + } catch (err) { 26 + console.error("Could not fetch owner profile:", err); 27 + ownerProfile = null; 28 + } 29 + }; 30 + loadOwner(); 31 + } 32 + }); 33 + 34 + const getDisplayName = (p: { displayName?: string; handle?: string } | null | undefined) => 35 + p?.displayName || p?.handle || null; 36 + </script> 37 + 38 + <DynamicHead 39 + title={ 40 + directoryOwner 41 + ? `${getDisplayName(profile) || did} โ€“ ${getDisplayName(ownerProfile) || directoryOwner}'s Linkat Directory` 42 + : `${getDisplayName(profile) || did} โ€“ Linkat Directory` 43 + } 44 + description={ 45 + directoryOwner 46 + ? `View ${getDisplayName(profile) || did}'s curated links in ${getDisplayName(ownerProfile) || directoryOwner}'s Linkat Directory` 47 + : `View ${getDisplayName(profile) || did}'s curated links in the Linkat Directory` 48 + } 49 + ogTitle={ 50 + directoryOwner 51 + ? `${getDisplayName(profile) || did} โ€“ ${getDisplayName(ownerProfile) || directoryOwner}'s Linkat Directory` 52 + : `${getDisplayName(profile) || did} โ€“ Linkat Directory` 53 + } 54 + ogDescription={ 55 + directoryOwner 56 + ? `View ${getDisplayName(profile) || did}'s curated links in ${getDisplayName(ownerProfile) || directoryOwner}'s Linkat Directory` 57 + : `View ${getDisplayName(profile) || did}'s curated links in the Linkat Directory` 58 + } 59 + twitterTitle={ 60 + directoryOwner 61 + ? `${getDisplayName(profile) || did} โ€“ ${getDisplayName(ownerProfile) || directoryOwner}'s Linkat Directory` 62 + : `${getDisplayName(profile) || did} โ€“ Linkat Directory` 63 + } 64 + twitterDescription={ 65 + directoryOwner 66 + ? `View ${getDisplayName(profile) || did}'s curated links in ${getDisplayName(ownerProfile) || directoryOwner}'s Linkat Directory` 67 + : `View ${getDisplayName(profile) || did}'s curated links in the Linkat Directory` 68 + } 69 + keywords={`Linkat, directory, links, Bluesky, curation, ${getDisplayName(profile) || did}, ${getDisplayName(ownerProfile) || directoryOwner}`} 70 + /> 71 + 72 + <div class="container mx-auto px-4 py-8"> 73 + {#if error} 74 + <div class="text-center py-8"> 75 + <h1 class="text-2xl font-bold mb-4">Error</h1> 76 + <p class="text-[var(--error-color)]">{error}</p> 77 + </div> 78 + {:else if !profile} 79 + <div class="text-center py-8"> 80 + <h1 class="text-2xl font-bold mb-4">User Not Found</h1> 81 + <p class="text-[var(--placeholder-color)]">The user with DID {did} was not found.</p> 82 + </div> 83 + {:else} 84 + <div class="max-w-4xl mx-auto"> 85 + <!-- Profile Header --> 86 + <div class="bg-[var(--card-bg)] rounded-lg shadow-md p-6 mb-6"> 87 + <div class="flex flex-col sm:flex-row items-center sm:items-start gap-4 mb-4"> 88 + {#if profile.avatar} 89 + <img 90 + src={profile.avatar} 91 + alt={profile.displayName || profile.handle} 92 + class="w-20 h-20 rounded-full object-cover" 93 + /> 94 + {:else} 95 + <div class="w-20 h-20 rounded-full bg-[var(--muted-bg)] flex items-center justify-center"> 96 + <span class="text-3xl font-bold text-[var(--text-color)]"> 97 + {(profile.displayName || profile.handle || '?').charAt(0).toUpperCase()} 98 + </span> 99 + </div> 100 + {/if} 101 + 102 + <div class="text-center sm:text-left"> 103 + <h1 class="text-2xl font-bold">{profile.displayName || profile.handle}</h1> 104 + <p class="text-[var(--secondary-text-color)]">@{profile.handle}</p> 105 + <code class="text-[var(--secondary-text-color)] text-sm">{did}</code> 106 + {#if profile.description} 107 + <p class="text-[var(--text-color)] mt-2">{profile.description}</p> 108 + {/if} 109 + </div> 110 + </div> 111 + </div> 112 + 113 + <!-- Links Section --> 114 + <div class="bg-[var(--card-bg)] rounded-lg shadow-md p-6"> 115 + <h2 class="text-xl font-bold mb-4">Links</h2> 116 + <DynamicLinks data={dynamicLinks} /> 117 + </div> 118 + </div> 119 + {/if} 120 + </div>
-1
static/.well-known/atproto-did
··· 1 - placeholder - replace with your DID
static/logo.ico

This is a binary file and will not be displayed.

static/logo.png

This is a binary file and will not be displayed.

-79
static/scripts/themeLoader.js
··· 1 - // Inline theme loader - compiled from themeLoader.ts 2 - // This runs immediately when the script loads 3 - (function() { 4 - 'use strict'; 5 - 6 - // Theme configuration - single source of truth 7 - const THEMES = [ 8 - { id: "default", name: "Green (Default)" } 9 - ]; 10 - 11 - const THEME_STORAGE_KEYS = { 12 - MODE: "theme-mode", 13 - COLOR: "color-theme", 14 - }; 15 - 16 - /** 17 - * Applies theme classes to the document element 18 - */ 19 - function applyTheme(isDarkMode, themeId) { 20 - // Remove all existing theme classes 21 - document.documentElement.classList.remove("light"); 22 - THEMES.forEach((theme) => { 23 - if (theme.id !== "default") { 24 - document.documentElement.classList.remove(theme.id); 25 - } 26 - }); 27 - 28 - // Apply light mode class if needed 29 - if (!isDarkMode) { 30 - document.documentElement.classList.add("light"); 31 - } 32 - 33 - // Apply color theme class if not default 34 - if (themeId !== "default") { 35 - document.documentElement.classList.add(themeId); 36 - } 37 - } 38 - 39 - /** 40 - * Gets the user's theme preferences from localStorage and system 41 - */ 42 - function getThemePreferences() { 43 - const savedThemeMode = localStorage.getItem(THEME_STORAGE_KEYS.MODE); 44 - const savedColorTheme = localStorage.getItem(THEME_STORAGE_KEYS.COLOR); 45 - 46 - let isDarkMode; 47 - if (savedThemeMode) { 48 - isDarkMode = savedThemeMode === "dark"; 49 - } else { 50 - // Use system preference as default 51 - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; 52 - isDarkMode = prefersDark; 53 - } 54 - 55 - const themeId = savedColorTheme || "default"; 56 - 57 - return { isDarkMode, themeId }; 58 - } 59 - 60 - /** 61 - * Initializes theme system - runs immediately 62 - */ 63 - function initializeTheme() { 64 - const { isDarkMode, themeId } = getThemePreferences(); 65 - applyTheme(isDarkMode, themeId); 66 - } 67 - 68 - // Initialize theme immediately 69 - initializeTheme(); 70 - 71 - // Make theme functions available globally for the Svelte component 72 - window.__themeLoader = { 73 - THEMES, 74 - THEME_STORAGE_KEYS, 75 - applyTheme, 76 - getThemePreferences, 77 - initializeTheme 78 - }; 79 - })();
+4 -1
svelte.config.js
··· 14 14 adapter: adapter(), 15 15 prerender: { 16 16 entries: ['*'], 17 - origin: 'https://ewancroft.uk' 17 + origin: process.env.PUBLIC_ORIGIN || 'http://localhost:5713' 18 18 }, 19 19 alias: { 20 20 '$components': './src/lib/components', 21 21 '$css': './src/lib/css', 22 22 '$services': './src/lib/services', 23 23 '$utils': './src/lib/utils' 24 + }, 25 + env: { 26 + publicPrefix: '' 24 27 } 25 28 } 26 29 };