A personal website powered by Astro and ATProto

Initial commit: ATproto-powered personal website with Bluesky integration

- Added ATproto client for fetching Bluesky posts
- Implemented ContentFeed component with image support
- Created BlueskyPost component with embed handling
- Added configuration system with environment variables
- Set up component registry for dynamic content rendering
- Added responsive layout with Tailwind CSS
- Configured to display user's own posts using handle
- Supports image embeds, external links, and quoted posts

+170 -28
README.md
··· 1 - # Astro Starter Kit: Minimal 1 + # ATproto Personal Website Template 2 + 3 + A modern personal website template powered by Astro, Tailwind CSS, and the ATproto protocol. This template allows you to create a personal website that displays content from your ATproto repository, including Bluesky posts, custom lexicon types, and more. 4 + 5 + ## Features 6 + 7 + - **Type-safe ATproto Integration**: Full TypeScript support for ATproto records and custom lexicon 8 + - **Component-driven Rendering**: Only render content types that have dedicated components 9 + - **Feed Support**: Display content from custom Bluesky feeds 10 + - **Custom Lexicon Support**: Easy to add new content types with custom components 11 + - **Theme Customization**: Configurable colors, fonts, and styling 12 + - **Performance Optimized**: Caching and efficient data fetching 13 + - **Responsive Design**: Works on all device sizes 14 + - **Dark Mode Support**: Built-in dark/light theme switching 15 + 16 + ## Supported Content Types 17 + 18 + - **Bluesky Posts**: Standard Bluesky posts with text, images, and embeds 19 + - **Whitewind Blog Posts**: Blog posts with titles, content, and tags 20 + - **Leaflet Publications**: Publications with categories and rich content 21 + - **Grain Image Galleries**: Image galleries with descriptions and captions 22 + 23 + ## Quick Start 24 + 25 + 1. **Clone the template**: 26 + ```bash 27 + git clone <your-repo-url> 28 + cd your-website 29 + ``` 30 + 31 + 2. **Install dependencies**: 32 + ```bash 33 + npm install 34 + ``` 35 + 36 + 3. **Configure your environment**: 37 + ```bash 38 + cp env.example .env 39 + ``` 40 + 41 + Edit `.env` with your configuration: 42 + ```env 43 + ATPROTO_DID=did:plc:your-did-here 44 + SITE_TITLE=My Personal Website 45 + SITE_AUTHOR=Your Name 46 + ``` 47 + 48 + 4. **Start development server**: 49 + ```bash 50 + npm run dev 51 + ``` 52 + 53 + ## Configuration 54 + 55 + ### Environment Variables 56 + 57 + | Variable | Description | Default | 58 + |----------|-------------|---------| 59 + | `ATPROTO_DID` | Your ATproto DID | Required | 60 + | `ATPROTO_PDS_URL` | PDS server URL | `https://bsky.social` | 61 + | `SITE_TITLE` | Website title | `My Personal Website` | 62 + | `SITE_DESCRIPTION` | Website description | `A personal website powered by ATproto` | 63 + | `SITE_AUTHOR` | Your name | `Your Name` | 64 + | `SITE_URL` | Your website URL | `https://example.com` | 65 + | `THEME_PRIMARY_COLOR` | Primary color | `#3b82f6` | 66 + | `THEME_SECONDARY_COLOR` | Secondary color | `#64748b` | 67 + | `THEME_ACCENT_COLOR` | Accent color | `#f59e0b` | 68 + | `THEME_FONT_FAMILY` | Font family | `Inter, system-ui, sans-serif` | 69 + | `CONTENT_DEFAULT_FEED_LIMIT` | Default feed limit | `20` | 70 + | `CONTENT_CACHE_TTL` | Cache TTL (ms) | `300000` | 71 + 72 + ## Usage 73 + 74 + ### Adding Content Components 75 + 76 + The template uses a component registry system. To add a new content type: 2 77 3 - ```sh 4 - npm create astro@latest -- --template minimal 78 + 1. **Define the type** in `src/lib/types/atproto.ts`: 79 + ```typescript 80 + export interface MyCustomType extends CustomLexiconRecord { 81 + $type: 'app.bsky.actor.profile#myCustomType'; 82 + title: string; 83 + content: string; 84 + } 85 + ``` 86 + 87 + 2. **Create a component** in `src/components/content/`: 88 + ```astro 89 + --- 90 + interface Props { 91 + title: string; 92 + content: string; 93 + } 94 + const { title, content } = Astro.props; 95 + --- 96 + 97 + <article class="..."> 98 + <h2>{title}</h2> 99 + <div>{content}</div> 100 + </article> 101 + ``` 102 + 103 + 3. **Register the component** in `src/lib/components/register.ts`: 104 + ```typescript 105 + registerComponent('app.bsky.actor.profile#myCustomType', MyCustomComponent); 106 + ``` 107 + 108 + ### Using Feed Components 109 + 110 + Display content from a Bluesky feed: 111 + 112 + ```astro 113 + <BlueskyFeed 114 + feedUri="at://did:plc:.../app.bsky.feed.generator/..." 115 + limit={10} 116 + showAuthor={true} 117 + showTimestamp={true} 118 + /> 5 119 ``` 6 120 7 - > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 121 + Display content from your repository: 8 122 9 - ## 🚀 Project Structure 123 + ```astro 124 + <ContentFeed 125 + did="did:plc:your-did" 126 + limit={20} 127 + showAuthor={false} 128 + showTimestamp={true} 129 + /> 130 + ``` 10 131 11 - Inside of your Astro project, you'll see the following folders and files: 132 + ## Project Structure 12 133 13 - ```text 14 - / 15 - ├── public/ 16 - ├── src/ 17 - │ └── pages/ 18 - │ └── index.astro 19 - └── package.json 134 + ``` 135 + src/ 136 + ├── lib/ 137 + │ ├── atproto/ # ATproto API integration 138 + │ ├── components/ # Component registry 139 + │ ├── config/ # Site configuration 140 + │ └── types/ # TypeScript definitions 141 + ├── components/ 142 + │ ├── content/ # Content rendering components 143 + │ ├── layout/ # Layout components 144 + │ └── ui/ # UI components 145 + ├── pages/ # Astro pages 146 + └── styles/ # Global styles 20 147 ``` 21 148 22 - Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. 149 + ## Deployment 150 + 151 + ### Cloudflare Pages 152 + 153 + 1. Connect your repository to Cloudflare Pages 154 + 2. Set build command: `npm run build` 155 + 3. Set build output directory: `dist` 156 + 4. Add environment variables in Cloudflare Pages settings 157 + 158 + ### Other Platforms 23 159 24 - There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components. 160 + The site can be deployed to any static hosting platform that supports Astro: 161 + - Vercel 162 + - Netlify 163 + - GitHub Pages 164 + - etc. 25 165 26 - Any static assets, like images, can be placed in the `public/` directory. 166 + ## Custom Lexicon 167 + 168 + To publish custom lexicon for others to use: 27 169 28 - ## 🧞 Commands 170 + 1. Define your lexicon schema following the ATproto specification 171 + 2. Publish to your PDS or a public repository 172 + 3. Create components for rendering your custom types 173 + 4. Document the lexicon for other developers 29 174 30 - All commands are run from the root of the project, from a terminal: 175 + ## Contributing 31 176 32 - | Command | Action | 33 - | :------------------------ | :----------------------------------------------- | 34 - | `npm install` | Installs dependencies | 35 - | `npm run dev` | Starts local dev server at `localhost:4321` | 36 - | `npm run build` | Build your production site to `./dist/` | 37 - | `npm run preview` | Preview your build locally, before deploying | 38 - | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 39 - | `npm run astro -- --help` | Get help using the Astro CLI | 177 + 1. Fork the repository 178 + 2. Create a feature branch 179 + 3. Make your changes 180 + 4. Add tests if applicable 181 + 5. Submit a pull request 40 182 41 - ## 👀 Want to learn more? 183 + ## License 42 184 43 - Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). 185 + MIT License - see LICENSE file for details.
+7 -1
astro.config.mjs
··· 1 1 // @ts-check 2 2 import { defineConfig } from 'astro/config'; 3 3 4 + import tailwindcss from '@tailwindcss/vite'; 5 + 4 6 // https://astro.build/config 5 - export default defineConfig({}); 7 + export default defineConfig({ 8 + vite: { 9 + plugins: [tailwindcss()] 10 + } 11 + });
+20
env.example
··· 1 + # ATproto Configuration 2 + ATPROTO_HANDLE=your-handle.bsky.social 3 + ATPROTO_DID=did:plc:your-did-here 4 + ATPROTO_PDS_URL=https://bsky.social 5 + 6 + # Site Configuration 7 + SITE_TITLE=My Personal Website 8 + SITE_DESCRIPTION=A personal website powered by ATproto 9 + SITE_AUTHOR=Your Name 10 + SITE_URL=https://your-domain.com 11 + 12 + # Theme Configuration 13 + THEME_PRIMARY_COLOR=#3b82f6 14 + THEME_SECONDARY_COLOR=#64748b 15 + THEME_ACCENT_COLOR=#f59e0b 16 + THEME_FONT_FAMILY=Inter, system-ui, sans-serif 17 + 18 + # Content Configuration 19 + CONTENT_DEFAULT_FEED_LIMIT=20 20 + CONTENT_CACHE_TTL=300000
+1918 -6
package-lock.json
··· 8 8 "name": "attempt2-home", 9 9 "version": "0.0.1", 10 10 "dependencies": { 11 - "astro": "^5.12.8" 11 + "@astrojs/check": "^0.9.4", 12 + "@atproto/api": "^0.16.2", 13 + "@atproto/xrpc": "^0.7.1", 14 + "@tailwindcss/typography": "^0.5.16", 15 + "@tailwindcss/vite": "^4.1.11", 16 + "@types/node": "^24.2.0", 17 + "astro": "^5.12.8", 18 + "dotenv": "^17.2.1", 19 + "tailwindcss": "^4.1.11", 20 + "typescript": "^5.9.2" 21 + } 22 + }, 23 + "node_modules/@ampproject/remapping": { 24 + "version": "2.3.0", 25 + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 26 + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 27 + "license": "Apache-2.0", 28 + "dependencies": { 29 + "@jridgewell/gen-mapping": "^0.3.5", 30 + "@jridgewell/trace-mapping": "^0.3.24" 31 + }, 32 + "engines": { 33 + "node": ">=6.0.0" 34 + } 35 + }, 36 + "node_modules/@astrojs/check": { 37 + "version": "0.9.4", 38 + "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.4.tgz", 39 + "integrity": "sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA==", 40 + "license": "MIT", 41 + "dependencies": { 42 + "@astrojs/language-server": "^2.15.0", 43 + "chokidar": "^4.0.1", 44 + "kleur": "^4.1.5", 45 + "yargs": "^17.7.2" 46 + }, 47 + "bin": { 48 + "astro-check": "dist/bin.js" 49 + }, 50 + "peerDependencies": { 51 + "typescript": "^5.0.0" 12 52 } 13 53 }, 14 54 "node_modules/@astrojs/compiler": { ··· 23 63 "integrity": "sha512-7dwEVigz9vUWDw3nRwLQ/yH/xYovlUA0ZD86xoeKEBmkz9O6iELG1yri67PgAPW6VLL/xInA4t7H0CK6VmtkKQ==", 24 64 "license": "MIT" 25 65 }, 66 + "node_modules/@astrojs/language-server": { 67 + "version": "2.15.4", 68 + "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.15.4.tgz", 69 + "integrity": "sha512-JivzASqTPR2bao9BWsSc/woPHH7OGSGc9aMxXL4U6egVTqBycB3ZHdBJPuOCVtcGLrzdWTosAqVPz1BVoxE0+A==", 70 + "license": "MIT", 71 + "dependencies": { 72 + "@astrojs/compiler": "^2.10.3", 73 + "@astrojs/yaml2ts": "^0.2.2", 74 + "@jridgewell/sourcemap-codec": "^1.4.15", 75 + "@volar/kit": "~2.4.7", 76 + "@volar/language-core": "~2.4.7", 77 + "@volar/language-server": "~2.4.7", 78 + "@volar/language-service": "~2.4.7", 79 + "fast-glob": "^3.2.12", 80 + "muggle-string": "^0.4.1", 81 + "volar-service-css": "0.0.62", 82 + "volar-service-emmet": "0.0.62", 83 + "volar-service-html": "0.0.62", 84 + "volar-service-prettier": "0.0.62", 85 + "volar-service-typescript": "0.0.62", 86 + "volar-service-typescript-twoslash-queries": "0.0.62", 87 + "volar-service-yaml": "0.0.62", 88 + "vscode-html-languageservice": "^5.2.0", 89 + "vscode-uri": "^3.0.8" 90 + }, 91 + "bin": { 92 + "astro-ls": "bin/nodeServer.js" 93 + }, 94 + "peerDependencies": { 95 + "prettier": "^3.0.0", 96 + "prettier-plugin-astro": ">=0.11.0" 97 + }, 98 + "peerDependenciesMeta": { 99 + "prettier": { 100 + "optional": true 101 + }, 102 + "prettier-plugin-astro": { 103 + "optional": true 104 + } 105 + } 106 + }, 26 107 "node_modules/@astrojs/markdown-remark": { 27 108 "version": "6.3.5", 28 109 "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.5.tgz", ··· 82 163 "node": "18.20.8 || ^20.3.0 || >=22.0.0" 83 164 } 84 165 }, 166 + "node_modules/@astrojs/yaml2ts": { 167 + "version": "0.2.2", 168 + "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.2.tgz", 169 + "integrity": "sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==", 170 + "license": "MIT", 171 + "dependencies": { 172 + "yaml": "^2.5.0" 173 + } 174 + }, 175 + "node_modules/@atproto/api": { 176 + "version": "0.16.2", 177 + "resolved": "https://registry.npmjs.org/@atproto/api/-/api-0.16.2.tgz", 178 + "integrity": "sha512-sSTg31J8ws8DNaoiizp+/uJideRxRaJsq+Nyl8rnSxGw0w3oCvoeRU19iRWh2t0jZEmiRJAGkveGu23NKmPYEQ==", 179 + "license": "MIT", 180 + "dependencies": { 181 + "@atproto/common-web": "^0.4.2", 182 + "@atproto/lexicon": "^0.4.12", 183 + "@atproto/syntax": "^0.4.0", 184 + "@atproto/xrpc": "^0.7.1", 185 + "await-lock": "^2.2.2", 186 + "multiformats": "^9.9.0", 187 + "tlds": "^1.234.0", 188 + "zod": "^3.23.8" 189 + } 190 + }, 191 + "node_modules/@atproto/common-web": { 192 + "version": "0.4.2", 193 + "resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.2.tgz", 194 + "integrity": "sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==", 195 + "license": "MIT", 196 + "dependencies": { 197 + "graphemer": "^1.4.0", 198 + "multiformats": "^9.9.0", 199 + "uint8arrays": "3.0.0", 200 + "zod": "^3.23.8" 201 + } 202 + }, 203 + "node_modules/@atproto/lexicon": { 204 + "version": "0.4.12", 205 + "resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.4.12.tgz", 206 + "integrity": "sha512-fcEvEQ1GpQYF5igZ4IZjPWEoWVpsEF22L9RexxLS3ptfySXLflEyH384e7HITzO/73McDeaJx3lqHIuqn9ulnw==", 207 + "license": "MIT", 208 + "dependencies": { 209 + "@atproto/common-web": "^0.4.2", 210 + "@atproto/syntax": "^0.4.0", 211 + "iso-datestring-validator": "^2.2.2", 212 + "multiformats": "^9.9.0", 213 + "zod": "^3.23.8" 214 + } 215 + }, 216 + "node_modules/@atproto/syntax": { 217 + "version": "0.4.0", 218 + "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.0.tgz", 219 + "integrity": "sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==", 220 + "license": "MIT" 221 + }, 222 + "node_modules/@atproto/xrpc": { 223 + "version": "0.7.1", 224 + "resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.7.1.tgz", 225 + "integrity": "sha512-ANHEzlskYlMEdH18m+Itp3a8d0pEJao2qoDybDoMupTnoeNkya4VKIaOgAi6ERQnqatBBZyn9asW+7rJmSt/8g==", 226 + "license": "MIT", 227 + "dependencies": { 228 + "@atproto/lexicon": "^0.4.12", 229 + "zod": "^3.23.8" 230 + } 231 + }, 85 232 "node_modules/@babel/helper-string-parser": { 86 233 "version": "7.27.1", 87 234 "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", ··· 138 285 "cross-fetch": "^3.0.4", 139 286 "fontkit": "^2.0.2" 140 287 } 288 + }, 289 + "node_modules/@emmetio/abbreviation": { 290 + "version": "2.3.3", 291 + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", 292 + "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", 293 + "license": "MIT", 294 + "dependencies": { 295 + "@emmetio/scanner": "^1.0.4" 296 + } 297 + }, 298 + "node_modules/@emmetio/css-abbreviation": { 299 + "version": "2.1.8", 300 + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", 301 + "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", 302 + "license": "MIT", 303 + "dependencies": { 304 + "@emmetio/scanner": "^1.0.4" 305 + } 306 + }, 307 + "node_modules/@emmetio/css-parser": { 308 + "version": "0.4.0", 309 + "resolved": "https://registry.npmjs.org/@emmetio/css-parser/-/css-parser-0.4.0.tgz", 310 + "integrity": "sha512-z7wkxRSZgrQHXVzObGkXG+Vmj3uRlpM11oCZ9pbaz0nFejvCDmAiNDpY75+wgXOcffKpj4rzGtwGaZxfJKsJxw==", 311 + "license": "MIT", 312 + "dependencies": { 313 + "@emmetio/stream-reader": "^2.2.0", 314 + "@emmetio/stream-reader-utils": "^0.1.0" 315 + } 316 + }, 317 + "node_modules/@emmetio/html-matcher": { 318 + "version": "1.3.0", 319 + "resolved": "https://registry.npmjs.org/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz", 320 + "integrity": "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==", 321 + "license": "ISC", 322 + "dependencies": { 323 + "@emmetio/scanner": "^1.0.0" 324 + } 325 + }, 326 + "node_modules/@emmetio/scanner": { 327 + "version": "1.0.4", 328 + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", 329 + "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==", 330 + "license": "MIT" 331 + }, 332 + "node_modules/@emmetio/stream-reader": { 333 + "version": "2.2.0", 334 + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz", 335 + "integrity": "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==", 336 + "license": "MIT" 337 + }, 338 + "node_modules/@emmetio/stream-reader-utils": { 339 + "version": "0.1.0", 340 + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz", 341 + "integrity": "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==", 342 + "license": "MIT" 141 343 }, 142 344 "node_modules/@emnapi/runtime": { 143 345 "version": "1.4.5", ··· 926 1128 "url": "https://opencollective.com/libvips" 927 1129 } 928 1130 }, 1131 + "node_modules/@isaacs/fs-minipass": { 1132 + "version": "4.0.1", 1133 + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", 1134 + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", 1135 + "license": "ISC", 1136 + "dependencies": { 1137 + "minipass": "^7.0.4" 1138 + }, 1139 + "engines": { 1140 + "node": ">=18.0.0" 1141 + } 1142 + }, 1143 + "node_modules/@jridgewell/gen-mapping": { 1144 + "version": "0.3.12", 1145 + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", 1146 + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", 1147 + "license": "MIT", 1148 + "dependencies": { 1149 + "@jridgewell/sourcemap-codec": "^1.5.0", 1150 + "@jridgewell/trace-mapping": "^0.3.24" 1151 + } 1152 + }, 1153 + "node_modules/@jridgewell/resolve-uri": { 1154 + "version": "3.1.2", 1155 + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 1156 + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 1157 + "license": "MIT", 1158 + "engines": { 1159 + "node": ">=6.0.0" 1160 + } 1161 + }, 929 1162 "node_modules/@jridgewell/sourcemap-codec": { 930 1163 "version": "1.5.4", 931 1164 "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", 932 1165 "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", 933 1166 "license": "MIT" 934 1167 }, 1168 + "node_modules/@jridgewell/trace-mapping": { 1169 + "version": "0.3.29", 1170 + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", 1171 + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", 1172 + "license": "MIT", 1173 + "dependencies": { 1174 + "@jridgewell/resolve-uri": "^3.1.0", 1175 + "@jridgewell/sourcemap-codec": "^1.4.14" 1176 + } 1177 + }, 1178 + "node_modules/@nodelib/fs.scandir": { 1179 + "version": "2.1.5", 1180 + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 1181 + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 1182 + "license": "MIT", 1183 + "dependencies": { 1184 + "@nodelib/fs.stat": "2.0.5", 1185 + "run-parallel": "^1.1.9" 1186 + }, 1187 + "engines": { 1188 + "node": ">= 8" 1189 + } 1190 + }, 1191 + "node_modules/@nodelib/fs.stat": { 1192 + "version": "2.0.5", 1193 + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 1194 + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 1195 + "license": "MIT", 1196 + "engines": { 1197 + "node": ">= 8" 1198 + } 1199 + }, 1200 + "node_modules/@nodelib/fs.walk": { 1201 + "version": "1.2.8", 1202 + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 1203 + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 1204 + "license": "MIT", 1205 + "dependencies": { 1206 + "@nodelib/fs.scandir": "2.1.5", 1207 + "fastq": "^1.6.0" 1208 + }, 1209 + "engines": { 1210 + "node": ">= 8" 1211 + } 1212 + }, 935 1213 "node_modules/@oslojs/encoding": { 936 1214 "version": "1.1.0", 937 1215 "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", ··· 1302 1580 "tslib": "^2.8.0" 1303 1581 } 1304 1582 }, 1583 + "node_modules/@tailwindcss/node": { 1584 + "version": "4.1.11", 1585 + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", 1586 + "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", 1587 + "license": "MIT", 1588 + "dependencies": { 1589 + "@ampproject/remapping": "^2.3.0", 1590 + "enhanced-resolve": "^5.18.1", 1591 + "jiti": "^2.4.2", 1592 + "lightningcss": "1.30.1", 1593 + "magic-string": "^0.30.17", 1594 + "source-map-js": "^1.2.1", 1595 + "tailwindcss": "4.1.11" 1596 + } 1597 + }, 1598 + "node_modules/@tailwindcss/oxide": { 1599 + "version": "4.1.11", 1600 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", 1601 + "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", 1602 + "hasInstallScript": true, 1603 + "license": "MIT", 1604 + "dependencies": { 1605 + "detect-libc": "^2.0.4", 1606 + "tar": "^7.4.3" 1607 + }, 1608 + "engines": { 1609 + "node": ">= 10" 1610 + }, 1611 + "optionalDependencies": { 1612 + "@tailwindcss/oxide-android-arm64": "4.1.11", 1613 + "@tailwindcss/oxide-darwin-arm64": "4.1.11", 1614 + "@tailwindcss/oxide-darwin-x64": "4.1.11", 1615 + "@tailwindcss/oxide-freebsd-x64": "4.1.11", 1616 + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", 1617 + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", 1618 + "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", 1619 + "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", 1620 + "@tailwindcss/oxide-linux-x64-musl": "4.1.11", 1621 + "@tailwindcss/oxide-wasm32-wasi": "4.1.11", 1622 + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", 1623 + "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" 1624 + } 1625 + }, 1626 + "node_modules/@tailwindcss/oxide-android-arm64": { 1627 + "version": "4.1.11", 1628 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", 1629 + "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", 1630 + "cpu": [ 1631 + "arm64" 1632 + ], 1633 + "license": "MIT", 1634 + "optional": true, 1635 + "os": [ 1636 + "android" 1637 + ], 1638 + "engines": { 1639 + "node": ">= 10" 1640 + } 1641 + }, 1642 + "node_modules/@tailwindcss/oxide-darwin-arm64": { 1643 + "version": "4.1.11", 1644 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", 1645 + "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", 1646 + "cpu": [ 1647 + "arm64" 1648 + ], 1649 + "license": "MIT", 1650 + "optional": true, 1651 + "os": [ 1652 + "darwin" 1653 + ], 1654 + "engines": { 1655 + "node": ">= 10" 1656 + } 1657 + }, 1658 + "node_modules/@tailwindcss/oxide-darwin-x64": { 1659 + "version": "4.1.11", 1660 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", 1661 + "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", 1662 + "cpu": [ 1663 + "x64" 1664 + ], 1665 + "license": "MIT", 1666 + "optional": true, 1667 + "os": [ 1668 + "darwin" 1669 + ], 1670 + "engines": { 1671 + "node": ">= 10" 1672 + } 1673 + }, 1674 + "node_modules/@tailwindcss/oxide-freebsd-x64": { 1675 + "version": "4.1.11", 1676 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", 1677 + "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", 1678 + "cpu": [ 1679 + "x64" 1680 + ], 1681 + "license": "MIT", 1682 + "optional": true, 1683 + "os": [ 1684 + "freebsd" 1685 + ], 1686 + "engines": { 1687 + "node": ">= 10" 1688 + } 1689 + }, 1690 + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { 1691 + "version": "4.1.11", 1692 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", 1693 + "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", 1694 + "cpu": [ 1695 + "arm" 1696 + ], 1697 + "license": "MIT", 1698 + "optional": true, 1699 + "os": [ 1700 + "linux" 1701 + ], 1702 + "engines": { 1703 + "node": ">= 10" 1704 + } 1705 + }, 1706 + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { 1707 + "version": "4.1.11", 1708 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", 1709 + "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", 1710 + "cpu": [ 1711 + "arm64" 1712 + ], 1713 + "license": "MIT", 1714 + "optional": true, 1715 + "os": [ 1716 + "linux" 1717 + ], 1718 + "engines": { 1719 + "node": ">= 10" 1720 + } 1721 + }, 1722 + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { 1723 + "version": "4.1.11", 1724 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", 1725 + "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", 1726 + "cpu": [ 1727 + "arm64" 1728 + ], 1729 + "license": "MIT", 1730 + "optional": true, 1731 + "os": [ 1732 + "linux" 1733 + ], 1734 + "engines": { 1735 + "node": ">= 10" 1736 + } 1737 + }, 1738 + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { 1739 + "version": "4.1.11", 1740 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", 1741 + "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", 1742 + "cpu": [ 1743 + "x64" 1744 + ], 1745 + "license": "MIT", 1746 + "optional": true, 1747 + "os": [ 1748 + "linux" 1749 + ], 1750 + "engines": { 1751 + "node": ">= 10" 1752 + } 1753 + }, 1754 + "node_modules/@tailwindcss/oxide-linux-x64-musl": { 1755 + "version": "4.1.11", 1756 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", 1757 + "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", 1758 + "cpu": [ 1759 + "x64" 1760 + ], 1761 + "license": "MIT", 1762 + "optional": true, 1763 + "os": [ 1764 + "linux" 1765 + ], 1766 + "engines": { 1767 + "node": ">= 10" 1768 + } 1769 + }, 1770 + "node_modules/@tailwindcss/oxide-wasm32-wasi": { 1771 + "version": "4.1.11", 1772 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", 1773 + "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", 1774 + "bundleDependencies": [ 1775 + "@napi-rs/wasm-runtime", 1776 + "@emnapi/core", 1777 + "@emnapi/runtime", 1778 + "@tybys/wasm-util", 1779 + "@emnapi/wasi-threads", 1780 + "tslib" 1781 + ], 1782 + "cpu": [ 1783 + "wasm32" 1784 + ], 1785 + "license": "MIT", 1786 + "optional": true, 1787 + "dependencies": { 1788 + "@emnapi/core": "^1.4.3", 1789 + "@emnapi/runtime": "^1.4.3", 1790 + "@emnapi/wasi-threads": "^1.0.2", 1791 + "@napi-rs/wasm-runtime": "^0.2.11", 1792 + "@tybys/wasm-util": "^0.9.0", 1793 + "tslib": "^2.8.0" 1794 + }, 1795 + "engines": { 1796 + "node": ">=14.0.0" 1797 + } 1798 + }, 1799 + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { 1800 + "version": "4.1.11", 1801 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", 1802 + "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", 1803 + "cpu": [ 1804 + "arm64" 1805 + ], 1806 + "license": "MIT", 1807 + "optional": true, 1808 + "os": [ 1809 + "win32" 1810 + ], 1811 + "engines": { 1812 + "node": ">= 10" 1813 + } 1814 + }, 1815 + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { 1816 + "version": "4.1.11", 1817 + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", 1818 + "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", 1819 + "cpu": [ 1820 + "x64" 1821 + ], 1822 + "license": "MIT", 1823 + "optional": true, 1824 + "os": [ 1825 + "win32" 1826 + ], 1827 + "engines": { 1828 + "node": ">= 10" 1829 + } 1830 + }, 1831 + "node_modules/@tailwindcss/typography": { 1832 + "version": "0.5.16", 1833 + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", 1834 + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", 1835 + "license": "MIT", 1836 + "dependencies": { 1837 + "lodash.castarray": "^4.4.0", 1838 + "lodash.isplainobject": "^4.0.6", 1839 + "lodash.merge": "^4.6.2", 1840 + "postcss-selector-parser": "6.0.10" 1841 + }, 1842 + "peerDependencies": { 1843 + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" 1844 + } 1845 + }, 1846 + "node_modules/@tailwindcss/vite": { 1847 + "version": "4.1.11", 1848 + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.11.tgz", 1849 + "integrity": "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==", 1850 + "license": "MIT", 1851 + "dependencies": { 1852 + "@tailwindcss/node": "4.1.11", 1853 + "@tailwindcss/oxide": "4.1.11", 1854 + "tailwindcss": "4.1.11" 1855 + }, 1856 + "peerDependencies": { 1857 + "vite": "^5.2.0 || ^6 || ^7" 1858 + } 1859 + }, 1305 1860 "node_modules/@types/debug": { 1306 1861 "version": "4.1.12", 1307 1862 "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", ··· 1380 1935 "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", 1381 1936 "license": "ISC" 1382 1937 }, 1938 + "node_modules/@volar/kit": { 1939 + "version": "2.4.22", 1940 + "resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.4.22.tgz", 1941 + "integrity": "sha512-o2LhNb2PLCUJ6v2XSqN7m+pJt+SE0QW1U2E52jnS8yZ03ohcGOOuFJdH1VlZgCBk0RlwO4xp0OaDoTtyTvMTrw==", 1942 + "license": "MIT", 1943 + "dependencies": { 1944 + "@volar/language-service": "2.4.22", 1945 + "@volar/typescript": "2.4.22", 1946 + "typesafe-path": "^0.2.2", 1947 + "vscode-languageserver-textdocument": "^1.0.11", 1948 + "vscode-uri": "^3.0.8" 1949 + }, 1950 + "peerDependencies": { 1951 + "typescript": "*" 1952 + } 1953 + }, 1954 + "node_modules/@volar/language-core": { 1955 + "version": "2.4.22", 1956 + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.22.tgz", 1957 + "integrity": "sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==", 1958 + "license": "MIT", 1959 + "dependencies": { 1960 + "@volar/source-map": "2.4.22" 1961 + } 1962 + }, 1963 + "node_modules/@volar/language-server": { 1964 + "version": "2.4.22", 1965 + "resolved": "https://registry.npmjs.org/@volar/language-server/-/language-server-2.4.22.tgz", 1966 + "integrity": "sha512-THIGWcQsEJKZU7SjVKPcy4MIamX4qpusKErj33ru7fi2WcD+FmFjYY/F2LIk/C15xEcb34JT1uZBlbO2dfzYSQ==", 1967 + "license": "MIT", 1968 + "dependencies": { 1969 + "@volar/language-core": "2.4.22", 1970 + "@volar/language-service": "2.4.22", 1971 + "@volar/typescript": "2.4.22", 1972 + "path-browserify": "^1.0.1", 1973 + "request-light": "^0.7.0", 1974 + "vscode-languageserver": "^9.0.1", 1975 + "vscode-languageserver-protocol": "^3.17.5", 1976 + "vscode-languageserver-textdocument": "^1.0.11", 1977 + "vscode-uri": "^3.0.8" 1978 + } 1979 + }, 1980 + "node_modules/@volar/language-service": { 1981 + "version": "2.4.22", 1982 + "resolved": "https://registry.npmjs.org/@volar/language-service/-/language-service-2.4.22.tgz", 1983 + "integrity": "sha512-8TmvOf/6uqaJMBVQIP9kgVpRzMrqLI3nCmWuSIPAldlmwjZTOiN17GA4AL4sTFJUg61xCSyMQWbProNFQ88yew==", 1984 + "license": "MIT", 1985 + "dependencies": { 1986 + "@volar/language-core": "2.4.22", 1987 + "vscode-languageserver-protocol": "^3.17.5", 1988 + "vscode-languageserver-textdocument": "^1.0.11", 1989 + "vscode-uri": "^3.0.8" 1990 + } 1991 + }, 1992 + "node_modules/@volar/source-map": { 1993 + "version": "2.4.22", 1994 + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.22.tgz", 1995 + "integrity": "sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==", 1996 + "license": "MIT" 1997 + }, 1998 + "node_modules/@volar/typescript": { 1999 + "version": "2.4.22", 2000 + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.22.tgz", 2001 + "integrity": "sha512-6ZczlJW1/GWTrNnkmZxJp4qyBt/SGVlcTuCWpI5zLrdPdCZsj66Aff9ZsfFaT3TyjG8zVYgBMYPuCm/eRkpcpQ==", 2002 + "license": "MIT", 2003 + "dependencies": { 2004 + "@volar/language-core": "2.4.22", 2005 + "path-browserify": "^1.0.1", 2006 + "vscode-uri": "^3.0.8" 2007 + } 2008 + }, 2009 + "node_modules/@vscode/emmet-helper": { 2010 + "version": "2.11.0", 2011 + "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.11.0.tgz", 2012 + "integrity": "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==", 2013 + "license": "MIT", 2014 + "dependencies": { 2015 + "emmet": "^2.4.3", 2016 + "jsonc-parser": "^2.3.0", 2017 + "vscode-languageserver-textdocument": "^1.0.1", 2018 + "vscode-languageserver-types": "^3.15.1", 2019 + "vscode-uri": "^3.0.8" 2020 + } 2021 + }, 2022 + "node_modules/@vscode/l10n": { 2023 + "version": "0.0.18", 2024 + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz", 2025 + "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", 2026 + "license": "MIT" 2027 + }, 1383 2028 "node_modules/acorn": { 1384 2029 "version": "8.15.0", 1385 2030 "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", ··· 1392 2037 "node": ">=0.4.0" 1393 2038 } 1394 2039 }, 2040 + "node_modules/ajv": { 2041 + "version": "8.17.1", 2042 + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", 2043 + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", 2044 + "license": "MIT", 2045 + "dependencies": { 2046 + "fast-deep-equal": "^3.1.3", 2047 + "fast-uri": "^3.0.1", 2048 + "json-schema-traverse": "^1.0.0", 2049 + "require-from-string": "^2.0.2" 2050 + }, 2051 + "funding": { 2052 + "type": "github", 2053 + "url": "https://github.com/sponsors/epoberezkin" 2054 + } 2055 + }, 1395 2056 "node_modules/ansi-align": { 1396 2057 "version": "3.0.1", 1397 2058 "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", ··· 1601 2262 "sharp": "^0.33.3" 1602 2263 } 1603 2264 }, 2265 + "node_modules/await-lock": { 2266 + "version": "2.2.2", 2267 + "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.2.2.tgz", 2268 + "integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==", 2269 + "license": "MIT" 2270 + }, 1604 2271 "node_modules/axobject-query": { 1605 2272 "version": "4.1.0", 1606 2273 "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", ··· 1688 2355 "url": "https://github.com/sponsors/sindresorhus" 1689 2356 } 1690 2357 }, 2358 + "node_modules/braces": { 2359 + "version": "3.0.3", 2360 + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 2361 + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 2362 + "license": "MIT", 2363 + "dependencies": { 2364 + "fill-range": "^7.1.1" 2365 + }, 2366 + "engines": { 2367 + "node": ">=8" 2368 + } 2369 + }, 1691 2370 "node_modules/brotli": { 1692 2371 "version": "1.3.3", 1693 2372 "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", ··· 1776 2455 "url": "https://paulmillr.com/funding/" 1777 2456 } 1778 2457 }, 2458 + "node_modules/chownr": { 2459 + "version": "3.0.0", 2460 + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", 2461 + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", 2462 + "license": "BlueOak-1.0.0", 2463 + "engines": { 2464 + "node": ">=18" 2465 + } 2466 + }, 1779 2467 "node_modules/ci-info": { 1780 2468 "version": "4.3.0", 1781 2469 "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", ··· 1803 2491 "url": "https://github.com/sponsors/sindresorhus" 1804 2492 } 1805 2493 }, 2494 + "node_modules/cliui": { 2495 + "version": "8.0.1", 2496 + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 2497 + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 2498 + "license": "ISC", 2499 + "dependencies": { 2500 + "string-width": "^4.2.0", 2501 + "strip-ansi": "^6.0.1", 2502 + "wrap-ansi": "^7.0.0" 2503 + }, 2504 + "engines": { 2505 + "node": ">=12" 2506 + } 2507 + }, 2508 + "node_modules/cliui/node_modules/ansi-regex": { 2509 + "version": "5.0.1", 2510 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2511 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2512 + "license": "MIT", 2513 + "engines": { 2514 + "node": ">=8" 2515 + } 2516 + }, 2517 + "node_modules/cliui/node_modules/ansi-styles": { 2518 + "version": "4.3.0", 2519 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2520 + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2521 + "license": "MIT", 2522 + "dependencies": { 2523 + "color-convert": "^2.0.1" 2524 + }, 2525 + "engines": { 2526 + "node": ">=8" 2527 + }, 2528 + "funding": { 2529 + "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2530 + } 2531 + }, 2532 + "node_modules/cliui/node_modules/emoji-regex": { 2533 + "version": "8.0.0", 2534 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2535 + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2536 + "license": "MIT" 2537 + }, 2538 + "node_modules/cliui/node_modules/string-width": { 2539 + "version": "4.2.3", 2540 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2541 + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2542 + "license": "MIT", 2543 + "dependencies": { 2544 + "emoji-regex": "^8.0.0", 2545 + "is-fullwidth-code-point": "^3.0.0", 2546 + "strip-ansi": "^6.0.1" 2547 + }, 2548 + "engines": { 2549 + "node": ">=8" 2550 + } 2551 + }, 2552 + "node_modules/cliui/node_modules/strip-ansi": { 2553 + "version": "6.0.1", 2554 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2555 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2556 + "license": "MIT", 2557 + "dependencies": { 2558 + "ansi-regex": "^5.0.1" 2559 + }, 2560 + "engines": { 2561 + "node": ">=8" 2562 + } 2563 + }, 2564 + "node_modules/cliui/node_modules/wrap-ansi": { 2565 + "version": "7.0.0", 2566 + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2567 + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2568 + "license": "MIT", 2569 + "dependencies": { 2570 + "ansi-styles": "^4.0.0", 2571 + "string-width": "^4.1.0", 2572 + "strip-ansi": "^6.0.0" 2573 + }, 2574 + "engines": { 2575 + "node": ">=10" 2576 + }, 2577 + "funding": { 2578 + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2579 + } 2580 + }, 1806 2581 "node_modules/clone": { 1807 2582 "version": "2.1.2", 1808 2583 "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", ··· 1840 2615 "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1841 2616 "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1842 2617 "license": "MIT", 1843 - "optional": true, 1844 2618 "dependencies": { 1845 2619 "color-name": "~1.1.4" 1846 2620 }, ··· 1852 2626 "version": "1.1.4", 1853 2627 "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1854 2628 "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1855 - "license": "MIT", 1856 - "optional": true 2629 + "license": "MIT" 1857 2630 }, 1858 2631 "node_modules/color-string": { 1859 2632 "version": "1.9.1", ··· 1996 2769 "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", 1997 2770 "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", 1998 2771 "license": "Apache-2.0", 1999 - "optional": true, 2000 2772 "engines": { 2001 2773 "node": ">=8" 2002 2774 } ··· 2053 2825 "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", 2054 2826 "license": "MIT" 2055 2827 }, 2828 + "node_modules/dotenv": { 2829 + "version": "17.2.1", 2830 + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", 2831 + "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", 2832 + "license": "BSD-2-Clause", 2833 + "engines": { 2834 + "node": ">=12" 2835 + }, 2836 + "funding": { 2837 + "url": "https://dotenvx.com" 2838 + } 2839 + }, 2056 2840 "node_modules/dset": { 2057 2841 "version": "3.1.4", 2058 2842 "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", ··· 2062 2846 "node": ">=4" 2063 2847 } 2064 2848 }, 2849 + "node_modules/emmet": { 2850 + "version": "2.4.11", 2851 + "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.4.11.tgz", 2852 + "integrity": "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==", 2853 + "license": "MIT", 2854 + "workspaces": [ 2855 + "./packages/scanner", 2856 + "./packages/abbreviation", 2857 + "./packages/css-abbreviation", 2858 + "./" 2859 + ], 2860 + "dependencies": { 2861 + "@emmetio/abbreviation": "^2.3.3", 2862 + "@emmetio/css-abbreviation": "^2.1.8" 2863 + } 2864 + }, 2065 2865 "node_modules/emoji-regex": { 2066 2866 "version": "10.4.0", 2067 2867 "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", 2068 2868 "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", 2069 2869 "license": "MIT" 2070 2870 }, 2871 + "node_modules/enhanced-resolve": { 2872 + "version": "5.18.2", 2873 + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", 2874 + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", 2875 + "license": "MIT", 2876 + "dependencies": { 2877 + "graceful-fs": "^4.2.4", 2878 + "tapable": "^2.2.0" 2879 + }, 2880 + "engines": { 2881 + "node": ">=10.13.0" 2882 + } 2883 + }, 2071 2884 "node_modules/entities": { 2072 2885 "version": "6.0.1", 2073 2886 "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", ··· 2127 2940 "@esbuild/win32-x64": "0.25.8" 2128 2941 } 2129 2942 }, 2943 + "node_modules/escalade": { 2944 + "version": "3.2.0", 2945 + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 2946 + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 2947 + "license": "MIT", 2948 + "engines": { 2949 + "node": ">=6" 2950 + } 2951 + }, 2130 2952 "node_modules/escape-string-regexp": { 2131 2953 "version": "5.0.0", 2132 2954 "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", ··· 2166 2988 "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 2167 2989 "license": "MIT" 2168 2990 }, 2991 + "node_modules/fast-glob": { 2992 + "version": "3.3.3", 2993 + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", 2994 + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", 2995 + "license": "MIT", 2996 + "dependencies": { 2997 + "@nodelib/fs.stat": "^2.0.2", 2998 + "@nodelib/fs.walk": "^1.2.3", 2999 + "glob-parent": "^5.1.2", 3000 + "merge2": "^1.3.0", 3001 + "micromatch": "^4.0.8" 3002 + }, 3003 + "engines": { 3004 + "node": ">=8.6.0" 3005 + } 3006 + }, 3007 + "node_modules/fast-uri": { 3008 + "version": "3.0.6", 3009 + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", 3010 + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", 3011 + "funding": [ 3012 + { 3013 + "type": "github", 3014 + "url": "https://github.com/sponsors/fastify" 3015 + }, 3016 + { 3017 + "type": "opencollective", 3018 + "url": "https://opencollective.com/fastify" 3019 + } 3020 + ], 3021 + "license": "BSD-3-Clause" 3022 + }, 3023 + "node_modules/fastq": { 3024 + "version": "1.19.1", 3025 + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", 3026 + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", 3027 + "license": "ISC", 3028 + "dependencies": { 3029 + "reusify": "^1.0.4" 3030 + } 3031 + }, 2169 3032 "node_modules/fdir": { 2170 3033 "version": "6.4.6", 2171 3034 "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", ··· 2180 3043 } 2181 3044 } 2182 3045 }, 3046 + "node_modules/fill-range": { 3047 + "version": "7.1.1", 3048 + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 3049 + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 3050 + "license": "MIT", 3051 + "dependencies": { 3052 + "to-regex-range": "^5.0.1" 3053 + }, 3054 + "engines": { 3055 + "node": ">=8" 3056 + } 3057 + }, 2183 3058 "node_modules/flattie": { 2184 3059 "version": "1.1.1", 2185 3060 "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", ··· 2230 3105 "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 2231 3106 } 2232 3107 }, 3108 + "node_modules/get-caller-file": { 3109 + "version": "2.0.5", 3110 + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 3111 + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 3112 + "license": "ISC", 3113 + "engines": { 3114 + "node": "6.* || 8.* || >= 10.*" 3115 + } 3116 + }, 2233 3117 "node_modules/get-east-asian-width": { 2234 3118 "version": "1.3.0", 2235 3119 "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", ··· 2247 3131 "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", 2248 3132 "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", 2249 3133 "license": "ISC" 3134 + }, 3135 + "node_modules/glob-parent": { 3136 + "version": "5.1.2", 3137 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 3138 + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 3139 + "license": "ISC", 3140 + "dependencies": { 3141 + "is-glob": "^4.0.1" 3142 + }, 3143 + "engines": { 3144 + "node": ">= 6" 3145 + } 3146 + }, 3147 + "node_modules/graceful-fs": { 3148 + "version": "4.2.11", 3149 + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 3150 + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 3151 + "license": "ISC" 3152 + }, 3153 + "node_modules/graphemer": { 3154 + "version": "1.4.0", 3155 + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 3156 + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 3157 + "license": "MIT" 2250 3158 }, 2251 3159 "node_modules/h3": { 2252 3160 "version": "1.15.4", ··· 2515 3423 "url": "https://github.com/sponsors/sindresorhus" 2516 3424 } 2517 3425 }, 3426 + "node_modules/is-extglob": { 3427 + "version": "2.1.1", 3428 + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 3429 + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 3430 + "license": "MIT", 3431 + "engines": { 3432 + "node": ">=0.10.0" 3433 + } 3434 + }, 2518 3435 "node_modules/is-fullwidth-code-point": { 2519 3436 "version": "3.0.0", 2520 3437 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", ··· 2524 3441 "node": ">=8" 2525 3442 } 2526 3443 }, 3444 + "node_modules/is-glob": { 3445 + "version": "4.0.3", 3446 + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 3447 + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 3448 + "license": "MIT", 3449 + "dependencies": { 3450 + "is-extglob": "^2.1.1" 3451 + }, 3452 + "engines": { 3453 + "node": ">=0.10.0" 3454 + } 3455 + }, 2527 3456 "node_modules/is-inside-container": { 2528 3457 "version": "1.0.0", 2529 3458 "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", ··· 2542 3471 "url": "https://github.com/sponsors/sindresorhus" 2543 3472 } 2544 3473 }, 3474 + "node_modules/is-number": { 3475 + "version": "7.0.0", 3476 + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 3477 + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 3478 + "license": "MIT", 3479 + "engines": { 3480 + "node": ">=0.12.0" 3481 + } 3482 + }, 2545 3483 "node_modules/is-plain-obj": { 2546 3484 "version": "4.1.0", 2547 3485 "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", ··· 2569 3507 "url": "https://github.com/sponsors/sindresorhus" 2570 3508 } 2571 3509 }, 3510 + "node_modules/iso-datestring-validator": { 3511 + "version": "2.2.2", 3512 + "resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz", 3513 + "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==", 3514 + "license": "MIT" 3515 + }, 3516 + "node_modules/jiti": { 3517 + "version": "2.5.1", 3518 + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", 3519 + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", 3520 + "license": "MIT", 3521 + "bin": { 3522 + "jiti": "lib/jiti-cli.mjs" 3523 + } 3524 + }, 2572 3525 "node_modules/js-yaml": { 2573 3526 "version": "4.1.0", 2574 3527 "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", ··· 2581 3534 "js-yaml": "bin/js-yaml.js" 2582 3535 } 2583 3536 }, 3537 + "node_modules/json-schema-traverse": { 3538 + "version": "1.0.0", 3539 + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 3540 + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", 3541 + "license": "MIT" 3542 + }, 3543 + "node_modules/jsonc-parser": { 3544 + "version": "2.3.1", 3545 + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", 3546 + "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", 3547 + "license": "MIT" 3548 + }, 2584 3549 "node_modules/kleur": { 2585 3550 "version": "4.1.5", 2586 3551 "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", ··· 2590 3555 "node": ">=6" 2591 3556 } 2592 3557 }, 3558 + "node_modules/lightningcss": { 3559 + "version": "1.30.1", 3560 + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", 3561 + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", 3562 + "license": "MPL-2.0", 3563 + "dependencies": { 3564 + "detect-libc": "^2.0.3" 3565 + }, 3566 + "engines": { 3567 + "node": ">= 12.0.0" 3568 + }, 3569 + "funding": { 3570 + "type": "opencollective", 3571 + "url": "https://opencollective.com/parcel" 3572 + }, 3573 + "optionalDependencies": { 3574 + "lightningcss-darwin-arm64": "1.30.1", 3575 + "lightningcss-darwin-x64": "1.30.1", 3576 + "lightningcss-freebsd-x64": "1.30.1", 3577 + "lightningcss-linux-arm-gnueabihf": "1.30.1", 3578 + "lightningcss-linux-arm64-gnu": "1.30.1", 3579 + "lightningcss-linux-arm64-musl": "1.30.1", 3580 + "lightningcss-linux-x64-gnu": "1.30.1", 3581 + "lightningcss-linux-x64-musl": "1.30.1", 3582 + "lightningcss-win32-arm64-msvc": "1.30.1", 3583 + "lightningcss-win32-x64-msvc": "1.30.1" 3584 + } 3585 + }, 3586 + "node_modules/lightningcss-darwin-arm64": { 3587 + "version": "1.30.1", 3588 + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", 3589 + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", 3590 + "cpu": [ 3591 + "arm64" 3592 + ], 3593 + "license": "MPL-2.0", 3594 + "optional": true, 3595 + "os": [ 3596 + "darwin" 3597 + ], 3598 + "engines": { 3599 + "node": ">= 12.0.0" 3600 + }, 3601 + "funding": { 3602 + "type": "opencollective", 3603 + "url": "https://opencollective.com/parcel" 3604 + } 3605 + }, 3606 + "node_modules/lightningcss-darwin-x64": { 3607 + "version": "1.30.1", 3608 + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", 3609 + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", 3610 + "cpu": [ 3611 + "x64" 3612 + ], 3613 + "license": "MPL-2.0", 3614 + "optional": true, 3615 + "os": [ 3616 + "darwin" 3617 + ], 3618 + "engines": { 3619 + "node": ">= 12.0.0" 3620 + }, 3621 + "funding": { 3622 + "type": "opencollective", 3623 + "url": "https://opencollective.com/parcel" 3624 + } 3625 + }, 3626 + "node_modules/lightningcss-freebsd-x64": { 3627 + "version": "1.30.1", 3628 + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", 3629 + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", 3630 + "cpu": [ 3631 + "x64" 3632 + ], 3633 + "license": "MPL-2.0", 3634 + "optional": true, 3635 + "os": [ 3636 + "freebsd" 3637 + ], 3638 + "engines": { 3639 + "node": ">= 12.0.0" 3640 + }, 3641 + "funding": { 3642 + "type": "opencollective", 3643 + "url": "https://opencollective.com/parcel" 3644 + } 3645 + }, 3646 + "node_modules/lightningcss-linux-arm-gnueabihf": { 3647 + "version": "1.30.1", 3648 + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", 3649 + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", 3650 + "cpu": [ 3651 + "arm" 3652 + ], 3653 + "license": "MPL-2.0", 3654 + "optional": true, 3655 + "os": [ 3656 + "linux" 3657 + ], 3658 + "engines": { 3659 + "node": ">= 12.0.0" 3660 + }, 3661 + "funding": { 3662 + "type": "opencollective", 3663 + "url": "https://opencollective.com/parcel" 3664 + } 3665 + }, 3666 + "node_modules/lightningcss-linux-arm64-gnu": { 3667 + "version": "1.30.1", 3668 + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", 3669 + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", 3670 + "cpu": [ 3671 + "arm64" 3672 + ], 3673 + "license": "MPL-2.0", 3674 + "optional": true, 3675 + "os": [ 3676 + "linux" 3677 + ], 3678 + "engines": { 3679 + "node": ">= 12.0.0" 3680 + }, 3681 + "funding": { 3682 + "type": "opencollective", 3683 + "url": "https://opencollective.com/parcel" 3684 + } 3685 + }, 3686 + "node_modules/lightningcss-linux-arm64-musl": { 3687 + "version": "1.30.1", 3688 + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", 3689 + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", 3690 + "cpu": [ 3691 + "arm64" 3692 + ], 3693 + "license": "MPL-2.0", 3694 + "optional": true, 3695 + "os": [ 3696 + "linux" 3697 + ], 3698 + "engines": { 3699 + "node": ">= 12.0.0" 3700 + }, 3701 + "funding": { 3702 + "type": "opencollective", 3703 + "url": "https://opencollective.com/parcel" 3704 + } 3705 + }, 3706 + "node_modules/lightningcss-linux-x64-gnu": { 3707 + "version": "1.30.1", 3708 + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", 3709 + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", 3710 + "cpu": [ 3711 + "x64" 3712 + ], 3713 + "license": "MPL-2.0", 3714 + "optional": true, 3715 + "os": [ 3716 + "linux" 3717 + ], 3718 + "engines": { 3719 + "node": ">= 12.0.0" 3720 + }, 3721 + "funding": { 3722 + "type": "opencollective", 3723 + "url": "https://opencollective.com/parcel" 3724 + } 3725 + }, 3726 + "node_modules/lightningcss-linux-x64-musl": { 3727 + "version": "1.30.1", 3728 + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", 3729 + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", 3730 + "cpu": [ 3731 + "x64" 3732 + ], 3733 + "license": "MPL-2.0", 3734 + "optional": true, 3735 + "os": [ 3736 + "linux" 3737 + ], 3738 + "engines": { 3739 + "node": ">= 12.0.0" 3740 + }, 3741 + "funding": { 3742 + "type": "opencollective", 3743 + "url": "https://opencollective.com/parcel" 3744 + } 3745 + }, 3746 + "node_modules/lightningcss-win32-arm64-msvc": { 3747 + "version": "1.30.1", 3748 + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", 3749 + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", 3750 + "cpu": [ 3751 + "arm64" 3752 + ], 3753 + "license": "MPL-2.0", 3754 + "optional": true, 3755 + "os": [ 3756 + "win32" 3757 + ], 3758 + "engines": { 3759 + "node": ">= 12.0.0" 3760 + }, 3761 + "funding": { 3762 + "type": "opencollective", 3763 + "url": "https://opencollective.com/parcel" 3764 + } 3765 + }, 3766 + "node_modules/lightningcss-win32-x64-msvc": { 3767 + "version": "1.30.1", 3768 + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", 3769 + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", 3770 + "cpu": [ 3771 + "x64" 3772 + ], 3773 + "license": "MPL-2.0", 3774 + "optional": true, 3775 + "os": [ 3776 + "win32" 3777 + ], 3778 + "engines": { 3779 + "node": ">= 12.0.0" 3780 + }, 3781 + "funding": { 3782 + "type": "opencollective", 3783 + "url": "https://opencollective.com/parcel" 3784 + } 3785 + }, 3786 + "node_modules/lodash": { 3787 + "version": "4.17.21", 3788 + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 3789 + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 3790 + "license": "MIT" 3791 + }, 3792 + "node_modules/lodash.castarray": { 3793 + "version": "4.4.0", 3794 + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", 3795 + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", 3796 + "license": "MIT" 3797 + }, 3798 + "node_modules/lodash.isplainobject": { 3799 + "version": "4.0.6", 3800 + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 3801 + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", 3802 + "license": "MIT" 3803 + }, 3804 + "node_modules/lodash.merge": { 3805 + "version": "4.6.2", 3806 + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 3807 + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 3808 + "license": "MIT" 3809 + }, 2593 3810 "node_modules/longest-streak": { 2594 3811 "version": "3.1.0", 2595 3812 "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", ··· 2866 4083 "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", 2867 4084 "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", 2868 4085 "license": "CC0-1.0" 4086 + }, 4087 + "node_modules/merge2": { 4088 + "version": "1.4.1", 4089 + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 4090 + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 4091 + "license": "MIT", 4092 + "engines": { 4093 + "node": ">= 8" 4094 + } 2869 4095 }, 2870 4096 "node_modules/micromark": { 2871 4097 "version": "4.0.2", ··· 3430 4656 ], 3431 4657 "license": "MIT" 3432 4658 }, 4659 + "node_modules/micromatch": { 4660 + "version": "4.0.8", 4661 + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 4662 + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 4663 + "license": "MIT", 4664 + "dependencies": { 4665 + "braces": "^3.0.3", 4666 + "picomatch": "^2.3.1" 4667 + }, 4668 + "engines": { 4669 + "node": ">=8.6" 4670 + } 4671 + }, 4672 + "node_modules/micromatch/node_modules/picomatch": { 4673 + "version": "2.3.1", 4674 + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 4675 + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 4676 + "license": "MIT", 4677 + "engines": { 4678 + "node": ">=8.6" 4679 + }, 4680 + "funding": { 4681 + "url": "https://github.com/sponsors/jonschlinkert" 4682 + } 4683 + }, 4684 + "node_modules/minipass": { 4685 + "version": "7.1.2", 4686 + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 4687 + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 4688 + "license": "ISC", 4689 + "engines": { 4690 + "node": ">=16 || 14 >=14.17" 4691 + } 4692 + }, 4693 + "node_modules/minizlib": { 4694 + "version": "3.0.2", 4695 + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", 4696 + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", 4697 + "license": "MIT", 4698 + "dependencies": { 4699 + "minipass": "^7.1.2" 4700 + }, 4701 + "engines": { 4702 + "node": ">= 18" 4703 + } 4704 + }, 4705 + "node_modules/mkdirp": { 4706 + "version": "3.0.1", 4707 + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", 4708 + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", 4709 + "license": "MIT", 4710 + "bin": { 4711 + "mkdirp": "dist/cjs/src/bin.js" 4712 + }, 4713 + "engines": { 4714 + "node": ">=10" 4715 + }, 4716 + "funding": { 4717 + "url": "https://github.com/sponsors/isaacs" 4718 + } 4719 + }, 3433 4720 "node_modules/mrmime": { 3434 4721 "version": "2.0.1", 3435 4722 "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", ··· 3444 4731 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 3445 4732 "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 3446 4733 "license": "MIT" 4734 + }, 4735 + "node_modules/muggle-string": { 4736 + "version": "0.4.1", 4737 + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", 4738 + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", 4739 + "license": "MIT" 4740 + }, 4741 + "node_modules/multiformats": { 4742 + "version": "9.9.0", 4743 + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", 4744 + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==", 4745 + "license": "(Apache-2.0 AND MIT)" 3447 4746 }, 3448 4747 "node_modules/nanoid": { 3449 4748 "version": "3.3.11", ··· 3645 4944 "url": "https://github.com/inikulin/parse5?sponsor=1" 3646 4945 } 3647 4946 }, 4947 + "node_modules/path-browserify": { 4948 + "version": "1.0.1", 4949 + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", 4950 + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", 4951 + "license": "MIT" 4952 + }, 3648 4953 "node_modules/picocolors": { 3649 4954 "version": "1.1.1", 3650 4955 "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", ··· 3691 4996 "node": "^10 || ^12 || >=14" 3692 4997 } 3693 4998 }, 4999 + "node_modules/postcss-selector-parser": { 5000 + "version": "6.0.10", 5001 + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", 5002 + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", 5003 + "license": "MIT", 5004 + "dependencies": { 5005 + "cssesc": "^3.0.0", 5006 + "util-deprecate": "^1.0.2" 5007 + }, 5008 + "engines": { 5009 + "node": ">=4" 5010 + } 5011 + }, 5012 + "node_modules/prettier": { 5013 + "version": "3.6.2", 5014 + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", 5015 + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", 5016 + "license": "MIT", 5017 + "optional": true, 5018 + "peer": true, 5019 + "bin": { 5020 + "prettier": "bin/prettier.cjs" 5021 + }, 5022 + "engines": { 5023 + "node": ">=14" 5024 + }, 5025 + "funding": { 5026 + "url": "https://github.com/prettier/prettier?sponsor=1" 5027 + } 5028 + }, 3694 5029 "node_modules/prismjs": { 3695 5030 "version": "1.30.0", 3696 5031 "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", ··· 3731 5066 "type": "github", 3732 5067 "url": "https://github.com/sponsors/wooorm" 3733 5068 } 5069 + }, 5070 + "node_modules/queue-microtask": { 5071 + "version": "1.2.3", 5072 + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 5073 + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 5074 + "funding": [ 5075 + { 5076 + "type": "github", 5077 + "url": "https://github.com/sponsors/feross" 5078 + }, 5079 + { 5080 + "type": "patreon", 5081 + "url": "https://www.patreon.com/feross" 5082 + }, 5083 + { 5084 + "type": "consulting", 5085 + "url": "https://feross.org/support" 5086 + } 5087 + ], 5088 + "license": "MIT" 3734 5089 }, 3735 5090 "node_modules/radix3": { 3736 5091 "version": "1.1.2", ··· 3917 5272 "url": "https://opencollective.com/unified" 3918 5273 } 3919 5274 }, 5275 + "node_modules/request-light": { 5276 + "version": "0.7.0", 5277 + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.7.0.tgz", 5278 + "integrity": "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==", 5279 + "license": "MIT" 5280 + }, 5281 + "node_modules/require-directory": { 5282 + "version": "2.1.1", 5283 + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 5284 + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 5285 + "license": "MIT", 5286 + "engines": { 5287 + "node": ">=0.10.0" 5288 + } 5289 + }, 5290 + "node_modules/require-from-string": { 5291 + "version": "2.0.2", 5292 + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 5293 + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 5294 + "license": "MIT", 5295 + "engines": { 5296 + "node": ">=0.10.0" 5297 + } 5298 + }, 3920 5299 "node_modules/restructure": { 3921 5300 "version": "3.0.2", 3922 5301 "resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz", ··· 3984 5363 "url": "https://opencollective.com/unified" 3985 5364 } 3986 5365 }, 5366 + "node_modules/reusify": { 5367 + "version": "1.1.0", 5368 + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", 5369 + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", 5370 + "license": "MIT", 5371 + "engines": { 5372 + "iojs": ">=1.0.0", 5373 + "node": ">=0.10.0" 5374 + } 5375 + }, 3987 5376 "node_modules/rollup": { 3988 5377 "version": "4.46.2", 3989 5378 "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", ··· 4023 5412 "fsevents": "~2.3.2" 4024 5413 } 4025 5414 }, 5415 + "node_modules/run-parallel": { 5416 + "version": "1.2.0", 5417 + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 5418 + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 5419 + "funding": [ 5420 + { 5421 + "type": "github", 5422 + "url": "https://github.com/sponsors/feross" 5423 + }, 5424 + { 5425 + "type": "patreon", 5426 + "url": "https://www.patreon.com/feross" 5427 + }, 5428 + { 5429 + "type": "consulting", 5430 + "url": "https://feross.org/support" 5431 + } 5432 + ], 5433 + "license": "MIT", 5434 + "dependencies": { 5435 + "queue-microtask": "^1.2.2" 5436 + } 5437 + }, 4026 5438 "node_modules/semver": { 4027 5439 "version": "7.7.2", 4028 5440 "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", ··· 4184 5596 "url": "https://github.com/chalk/strip-ansi?sponsor=1" 4185 5597 } 4186 5598 }, 5599 + "node_modules/tailwindcss": { 5600 + "version": "4.1.11", 5601 + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", 5602 + "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", 5603 + "license": "MIT" 5604 + }, 5605 + "node_modules/tapable": { 5606 + "version": "2.2.2", 5607 + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", 5608 + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", 5609 + "license": "MIT", 5610 + "engines": { 5611 + "node": ">=6" 5612 + } 5613 + }, 5614 + "node_modules/tar": { 5615 + "version": "7.4.3", 5616 + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", 5617 + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", 5618 + "license": "ISC", 5619 + "dependencies": { 5620 + "@isaacs/fs-minipass": "^4.0.0", 5621 + "chownr": "^3.0.0", 5622 + "minipass": "^7.1.2", 5623 + "minizlib": "^3.0.1", 5624 + "mkdirp": "^3.0.1", 5625 + "yallist": "^5.0.0" 5626 + }, 5627 + "engines": { 5628 + "node": ">=18" 5629 + } 5630 + }, 4187 5631 "node_modules/tiny-inflate": { 4188 5632 "version": "1.0.3", 4189 5633 "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", ··· 4212 5656 "url": "https://github.com/sponsors/SuperchupuDev" 4213 5657 } 4214 5658 }, 5659 + "node_modules/tlds": { 5660 + "version": "1.259.0", 5661 + "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.259.0.tgz", 5662 + "integrity": "sha512-AldGGlDP0PNgwppe2quAvuBl18UcjuNtOnDuUkqhd6ipPqrYYBt3aTxK1QTsBVknk97lS2JcafWMghjGWFtunw==", 5663 + "license": "MIT", 5664 + "bin": { 5665 + "tlds": "bin.js" 5666 + } 5667 + }, 5668 + "node_modules/to-regex-range": { 5669 + "version": "5.0.1", 5670 + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 5671 + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 5672 + "license": "MIT", 5673 + "dependencies": { 5674 + "is-number": "^7.0.0" 5675 + }, 5676 + "engines": { 5677 + "node": ">=8.0" 5678 + } 5679 + }, 4215 5680 "node_modules/tr46": { 4216 5681 "version": "0.0.3", 4217 5682 "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", ··· 4276 5741 "url": "https://github.com/sponsors/sindresorhus" 4277 5742 } 4278 5743 }, 5744 + "node_modules/typesafe-path": { 5745 + "version": "0.2.2", 5746 + "resolved": "https://registry.npmjs.org/typesafe-path/-/typesafe-path-0.2.2.tgz", 5747 + "integrity": "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==", 5748 + "license": "MIT" 5749 + }, 4279 5750 "node_modules/typescript": { 4280 5751 "version": "5.9.2", 4281 5752 "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", 4282 5753 "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", 4283 5754 "license": "Apache-2.0", 4284 - "peer": true, 4285 5755 "bin": { 4286 5756 "tsc": "bin/tsc", 4287 5757 "tsserver": "bin/tsserver" ··· 4290 5760 "node": ">=14.17" 4291 5761 } 4292 5762 }, 5763 + "node_modules/typescript-auto-import-cache": { 5764 + "version": "0.3.6", 5765 + "resolved": "https://registry.npmjs.org/typescript-auto-import-cache/-/typescript-auto-import-cache-0.3.6.tgz", 5766 + "integrity": "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==", 5767 + "license": "MIT", 5768 + "dependencies": { 5769 + "semver": "^7.3.8" 5770 + } 5771 + }, 4293 5772 "node_modules/ufo": { 4294 5773 "version": "1.6.1", 4295 5774 "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", 4296 5775 "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", 4297 5776 "license": "MIT" 5777 + }, 5778 + "node_modules/uint8arrays": { 5779 + "version": "3.0.0", 5780 + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz", 5781 + "integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==", 5782 + "license": "MIT", 5783 + "dependencies": { 5784 + "multiformats": "^9.4.2" 5785 + } 4298 5786 }, 4299 5787 "node_modules/ultrahtml": { 4300 5788 "version": "1.6.0", ··· 4579 6067 } 4580 6068 } 4581 6069 }, 6070 + "node_modules/util-deprecate": { 6071 + "version": "1.0.2", 6072 + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 6073 + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 6074 + "license": "MIT" 6075 + }, 4582 6076 "node_modules/vfile": { 4583 6077 "version": "6.0.3", 4584 6078 "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", ··· 4714 6208 } 4715 6209 } 4716 6210 }, 6211 + "node_modules/volar-service-css": { 6212 + "version": "0.0.62", 6213 + "resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.62.tgz", 6214 + "integrity": "sha512-JwNyKsH3F8PuzZYuqPf+2e+4CTU8YoyUHEHVnoXNlrLe7wy9U3biomZ56llN69Ris7TTy/+DEX41yVxQpM4qvg==", 6215 + "license": "MIT", 6216 + "dependencies": { 6217 + "vscode-css-languageservice": "^6.3.0", 6218 + "vscode-languageserver-textdocument": "^1.0.11", 6219 + "vscode-uri": "^3.0.8" 6220 + }, 6221 + "peerDependencies": { 6222 + "@volar/language-service": "~2.4.0" 6223 + }, 6224 + "peerDependenciesMeta": { 6225 + "@volar/language-service": { 6226 + "optional": true 6227 + } 6228 + } 6229 + }, 6230 + "node_modules/volar-service-emmet": { 6231 + "version": "0.0.62", 6232 + "resolved": "https://registry.npmjs.org/volar-service-emmet/-/volar-service-emmet-0.0.62.tgz", 6233 + "integrity": "sha512-U4dxWDBWz7Pi4plpbXf4J4Z/ss6kBO3TYrACxWNsE29abu75QzVS0paxDDhI6bhqpbDFXlpsDhZ9aXVFpnfGRQ==", 6234 + "license": "MIT", 6235 + "dependencies": { 6236 + "@emmetio/css-parser": "^0.4.0", 6237 + "@emmetio/html-matcher": "^1.3.0", 6238 + "@vscode/emmet-helper": "^2.9.3", 6239 + "vscode-uri": "^3.0.8" 6240 + }, 6241 + "peerDependencies": { 6242 + "@volar/language-service": "~2.4.0" 6243 + }, 6244 + "peerDependenciesMeta": { 6245 + "@volar/language-service": { 6246 + "optional": true 6247 + } 6248 + } 6249 + }, 6250 + "node_modules/volar-service-html": { 6251 + "version": "0.0.62", 6252 + "resolved": "https://registry.npmjs.org/volar-service-html/-/volar-service-html-0.0.62.tgz", 6253 + "integrity": "sha512-Zw01aJsZRh4GTGUjveyfEzEqpULQUdQH79KNEiKVYHZyuGtdBRYCHlrus1sueSNMxwwkuF5WnOHfvBzafs8yyQ==", 6254 + "license": "MIT", 6255 + "dependencies": { 6256 + "vscode-html-languageservice": "^5.3.0", 6257 + "vscode-languageserver-textdocument": "^1.0.11", 6258 + "vscode-uri": "^3.0.8" 6259 + }, 6260 + "peerDependencies": { 6261 + "@volar/language-service": "~2.4.0" 6262 + }, 6263 + "peerDependenciesMeta": { 6264 + "@volar/language-service": { 6265 + "optional": true 6266 + } 6267 + } 6268 + }, 6269 + "node_modules/volar-service-prettier": { 6270 + "version": "0.0.62", 6271 + "resolved": "https://registry.npmjs.org/volar-service-prettier/-/volar-service-prettier-0.0.62.tgz", 6272 + "integrity": "sha512-h2yk1RqRTE+vkYZaI9KYuwpDfOQRrTEMvoHol0yW4GFKc75wWQRrb5n/5abDrzMPrkQbSip8JH2AXbvrRtYh4w==", 6273 + "license": "MIT", 6274 + "dependencies": { 6275 + "vscode-uri": "^3.0.8" 6276 + }, 6277 + "peerDependencies": { 6278 + "@volar/language-service": "~2.4.0", 6279 + "prettier": "^2.2 || ^3.0" 6280 + }, 6281 + "peerDependenciesMeta": { 6282 + "@volar/language-service": { 6283 + "optional": true 6284 + }, 6285 + "prettier": { 6286 + "optional": true 6287 + } 6288 + } 6289 + }, 6290 + "node_modules/volar-service-typescript": { 6291 + "version": "0.0.62", 6292 + "resolved": "https://registry.npmjs.org/volar-service-typescript/-/volar-service-typescript-0.0.62.tgz", 6293 + "integrity": "sha512-p7MPi71q7KOsH0eAbZwPBiKPp9B2+qrdHAd6VY5oTo9BUXatsOAdakTm9Yf0DUj6uWBAaOT01BSeVOPwucMV1g==", 6294 + "license": "MIT", 6295 + "dependencies": { 6296 + "path-browserify": "^1.0.1", 6297 + "semver": "^7.6.2", 6298 + "typescript-auto-import-cache": "^0.3.3", 6299 + "vscode-languageserver-textdocument": "^1.0.11", 6300 + "vscode-nls": "^5.2.0", 6301 + "vscode-uri": "^3.0.8" 6302 + }, 6303 + "peerDependencies": { 6304 + "@volar/language-service": "~2.4.0" 6305 + }, 6306 + "peerDependenciesMeta": { 6307 + "@volar/language-service": { 6308 + "optional": true 6309 + } 6310 + } 6311 + }, 6312 + "node_modules/volar-service-typescript-twoslash-queries": { 6313 + "version": "0.0.62", 6314 + "resolved": "https://registry.npmjs.org/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.62.tgz", 6315 + "integrity": "sha512-KxFt4zydyJYYI0kFAcWPTh4u0Ha36TASPZkAnNY784GtgajerUqM80nX/W1d0wVhmcOFfAxkVsf/Ed+tiYU7ng==", 6316 + "license": "MIT", 6317 + "dependencies": { 6318 + "vscode-uri": "^3.0.8" 6319 + }, 6320 + "peerDependencies": { 6321 + "@volar/language-service": "~2.4.0" 6322 + }, 6323 + "peerDependenciesMeta": { 6324 + "@volar/language-service": { 6325 + "optional": true 6326 + } 6327 + } 6328 + }, 6329 + "node_modules/volar-service-yaml": { 6330 + "version": "0.0.62", 6331 + "resolved": "https://registry.npmjs.org/volar-service-yaml/-/volar-service-yaml-0.0.62.tgz", 6332 + "integrity": "sha512-k7gvv7sk3wa+nGll3MaSKyjwQsJjIGCHFjVkl3wjaSP2nouKyn9aokGmqjrl39mi88Oy49giog2GkZH526wjig==", 6333 + "license": "MIT", 6334 + "dependencies": { 6335 + "vscode-uri": "^3.0.8", 6336 + "yaml-language-server": "~1.15.0" 6337 + }, 6338 + "peerDependencies": { 6339 + "@volar/language-service": "~2.4.0" 6340 + }, 6341 + "peerDependenciesMeta": { 6342 + "@volar/language-service": { 6343 + "optional": true 6344 + } 6345 + } 6346 + }, 6347 + "node_modules/vscode-css-languageservice": { 6348 + "version": "6.3.7", 6349 + "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.7.tgz", 6350 + "integrity": "sha512-5TmXHKllPzfkPhW4UE9sODV3E0bIOJPOk+EERKllf2SmAczjfTmYeq5txco+N3jpF8KIZ6loj/JptpHBQuVQRA==", 6351 + "license": "MIT", 6352 + "dependencies": { 6353 + "@vscode/l10n": "^0.0.18", 6354 + "vscode-languageserver-textdocument": "^1.0.12", 6355 + "vscode-languageserver-types": "3.17.5", 6356 + "vscode-uri": "^3.1.0" 6357 + } 6358 + }, 6359 + "node_modules/vscode-html-languageservice": { 6360 + "version": "5.5.1", 6361 + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.5.1.tgz", 6362 + "integrity": "sha512-/ZdEtsZ3OiFSyL00kmmu7crFV9KwWR+MgpzjsxO60DQH7sIfHZM892C/E4iDd11EKocr+NYuvOA4Y7uc3QzLEA==", 6363 + "license": "MIT", 6364 + "dependencies": { 6365 + "@vscode/l10n": "^0.0.18", 6366 + "vscode-languageserver-textdocument": "^1.0.12", 6367 + "vscode-languageserver-types": "^3.17.5", 6368 + "vscode-uri": "^3.1.0" 6369 + } 6370 + }, 6371 + "node_modules/vscode-json-languageservice": { 6372 + "version": "4.1.8", 6373 + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.1.8.tgz", 6374 + "integrity": "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==", 6375 + "license": "MIT", 6376 + "dependencies": { 6377 + "jsonc-parser": "^3.0.0", 6378 + "vscode-languageserver-textdocument": "^1.0.1", 6379 + "vscode-languageserver-types": "^3.16.0", 6380 + "vscode-nls": "^5.0.0", 6381 + "vscode-uri": "^3.0.2" 6382 + }, 6383 + "engines": { 6384 + "npm": ">=7.0.0" 6385 + } 6386 + }, 6387 + "node_modules/vscode-json-languageservice/node_modules/jsonc-parser": { 6388 + "version": "3.3.1", 6389 + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", 6390 + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", 6391 + "license": "MIT" 6392 + }, 6393 + "node_modules/vscode-jsonrpc": { 6394 + "version": "8.2.0", 6395 + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", 6396 + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", 6397 + "license": "MIT", 6398 + "engines": { 6399 + "node": ">=14.0.0" 6400 + } 6401 + }, 6402 + "node_modules/vscode-languageserver": { 6403 + "version": "9.0.1", 6404 + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", 6405 + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", 6406 + "license": "MIT", 6407 + "dependencies": { 6408 + "vscode-languageserver-protocol": "3.17.5" 6409 + }, 6410 + "bin": { 6411 + "installServerIntoExtension": "bin/installServerIntoExtension" 6412 + } 6413 + }, 6414 + "node_modules/vscode-languageserver-protocol": { 6415 + "version": "3.17.5", 6416 + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", 6417 + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", 6418 + "license": "MIT", 6419 + "dependencies": { 6420 + "vscode-jsonrpc": "8.2.0", 6421 + "vscode-languageserver-types": "3.17.5" 6422 + } 6423 + }, 6424 + "node_modules/vscode-languageserver-textdocument": { 6425 + "version": "1.0.12", 6426 + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", 6427 + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", 6428 + "license": "MIT" 6429 + }, 6430 + "node_modules/vscode-languageserver-types": { 6431 + "version": "3.17.5", 6432 + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", 6433 + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", 6434 + "license": "MIT" 6435 + }, 6436 + "node_modules/vscode-nls": { 6437 + "version": "5.2.0", 6438 + "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz", 6439 + "integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==", 6440 + "license": "MIT" 6441 + }, 6442 + "node_modules/vscode-uri": { 6443 + "version": "3.1.0", 6444 + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", 6445 + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", 6446 + "license": "MIT" 6447 + }, 4717 6448 "node_modules/web-namespaces": { 4718 6449 "version": "2.0.1", 4719 6450 "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", ··· 4787 6518 "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", 4788 6519 "license": "MIT" 4789 6520 }, 6521 + "node_modules/y18n": { 6522 + "version": "5.0.8", 6523 + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 6524 + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 6525 + "license": "ISC", 6526 + "engines": { 6527 + "node": ">=10" 6528 + } 6529 + }, 6530 + "node_modules/yallist": { 6531 + "version": "5.0.0", 6532 + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", 6533 + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", 6534 + "license": "BlueOak-1.0.0", 6535 + "engines": { 6536 + "node": ">=18" 6537 + } 6538 + }, 6539 + "node_modules/yaml": { 6540 + "version": "2.8.1", 6541 + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", 6542 + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", 6543 + "license": "ISC", 6544 + "bin": { 6545 + "yaml": "bin.mjs" 6546 + }, 6547 + "engines": { 6548 + "node": ">= 14.6" 6549 + } 6550 + }, 6551 + "node_modules/yaml-language-server": { 6552 + "version": "1.15.0", 6553 + "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-1.15.0.tgz", 6554 + "integrity": "sha512-N47AqBDCMQmh6mBLmI6oqxryHRzi33aPFPsJhYy3VTUGCdLHYjGh4FZzpUjRlphaADBBkDmnkM/++KNIOHi5Rw==", 6555 + "license": "MIT", 6556 + "dependencies": { 6557 + "ajv": "^8.11.0", 6558 + "lodash": "4.17.21", 6559 + "request-light": "^0.5.7", 6560 + "vscode-json-languageservice": "4.1.8", 6561 + "vscode-languageserver": "^7.0.0", 6562 + "vscode-languageserver-textdocument": "^1.0.1", 6563 + "vscode-languageserver-types": "^3.16.0", 6564 + "vscode-nls": "^5.0.0", 6565 + "vscode-uri": "^3.0.2", 6566 + "yaml": "2.2.2" 6567 + }, 6568 + "bin": { 6569 + "yaml-language-server": "bin/yaml-language-server" 6570 + }, 6571 + "optionalDependencies": { 6572 + "prettier": "2.8.7" 6573 + } 6574 + }, 6575 + "node_modules/yaml-language-server/node_modules/prettier": { 6576 + "version": "2.8.7", 6577 + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", 6578 + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", 6579 + "license": "MIT", 6580 + "optional": true, 6581 + "bin": { 6582 + "prettier": "bin-prettier.js" 6583 + }, 6584 + "engines": { 6585 + "node": ">=10.13.0" 6586 + }, 6587 + "funding": { 6588 + "url": "https://github.com/prettier/prettier?sponsor=1" 6589 + } 6590 + }, 6591 + "node_modules/yaml-language-server/node_modules/request-light": { 6592 + "version": "0.5.8", 6593 + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.5.8.tgz", 6594 + "integrity": "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==", 6595 + "license": "MIT" 6596 + }, 6597 + "node_modules/yaml-language-server/node_modules/vscode-jsonrpc": { 6598 + "version": "6.0.0", 6599 + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", 6600 + "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", 6601 + "license": "MIT", 6602 + "engines": { 6603 + "node": ">=8.0.0 || >=10.0.0" 6604 + } 6605 + }, 6606 + "node_modules/yaml-language-server/node_modules/vscode-languageserver": { 6607 + "version": "7.0.0", 6608 + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", 6609 + "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", 6610 + "license": "MIT", 6611 + "dependencies": { 6612 + "vscode-languageserver-protocol": "3.16.0" 6613 + }, 6614 + "bin": { 6615 + "installServerIntoExtension": "bin/installServerIntoExtension" 6616 + } 6617 + }, 6618 + "node_modules/yaml-language-server/node_modules/vscode-languageserver-protocol": { 6619 + "version": "3.16.0", 6620 + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", 6621 + "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", 6622 + "license": "MIT", 6623 + "dependencies": { 6624 + "vscode-jsonrpc": "6.0.0", 6625 + "vscode-languageserver-types": "3.16.0" 6626 + } 6627 + }, 6628 + "node_modules/yaml-language-server/node_modules/vscode-languageserver-types": { 6629 + "version": "3.16.0", 6630 + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", 6631 + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==", 6632 + "license": "MIT" 6633 + }, 6634 + "node_modules/yaml-language-server/node_modules/yaml": { 6635 + "version": "2.2.2", 6636 + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz", 6637 + "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==", 6638 + "license": "ISC", 6639 + "engines": { 6640 + "node": ">= 14" 6641 + } 6642 + }, 6643 + "node_modules/yargs": { 6644 + "version": "17.7.2", 6645 + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 6646 + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 6647 + "license": "MIT", 6648 + "dependencies": { 6649 + "cliui": "^8.0.1", 6650 + "escalade": "^3.1.1", 6651 + "get-caller-file": "^2.0.5", 6652 + "require-directory": "^2.1.1", 6653 + "string-width": "^4.2.3", 6654 + "y18n": "^5.0.5", 6655 + "yargs-parser": "^21.1.1" 6656 + }, 6657 + "engines": { 6658 + "node": ">=12" 6659 + } 6660 + }, 4790 6661 "node_modules/yargs-parser": { 4791 6662 "version": "21.1.1", 4792 6663 "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", ··· 4794 6665 "license": "ISC", 4795 6666 "engines": { 4796 6667 "node": ">=12" 6668 + } 6669 + }, 6670 + "node_modules/yargs/node_modules/ansi-regex": { 6671 + "version": "5.0.1", 6672 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 6673 + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 6674 + "license": "MIT", 6675 + "engines": { 6676 + "node": ">=8" 6677 + } 6678 + }, 6679 + "node_modules/yargs/node_modules/emoji-regex": { 6680 + "version": "8.0.0", 6681 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 6682 + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 6683 + "license": "MIT" 6684 + }, 6685 + "node_modules/yargs/node_modules/string-width": { 6686 + "version": "4.2.3", 6687 + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 6688 + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 6689 + "license": "MIT", 6690 + "dependencies": { 6691 + "emoji-regex": "^8.0.0", 6692 + "is-fullwidth-code-point": "^3.0.0", 6693 + "strip-ansi": "^6.0.1" 6694 + }, 6695 + "engines": { 6696 + "node": ">=8" 6697 + } 6698 + }, 6699 + "node_modules/yargs/node_modules/strip-ansi": { 6700 + "version": "6.0.1", 6701 + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 6702 + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 6703 + "license": "MIT", 6704 + "dependencies": { 6705 + "ansi-regex": "^5.0.1" 6706 + }, 6707 + "engines": { 6708 + "node": ">=8" 4797 6709 } 4798 6710 }, 4799 6711 "node_modules/yocto-queue": {
+11 -2
package.json
··· 9 9 "astro": "astro" 10 10 }, 11 11 "dependencies": { 12 - "astro": "^5.12.8" 12 + "@astrojs/check": "^0.9.4", 13 + "@atproto/api": "^0.16.2", 14 + "@atproto/xrpc": "^0.7.1", 15 + "@tailwindcss/typography": "^0.5.16", 16 + "@tailwindcss/vite": "^4.1.11", 17 + "@types/node": "^24.2.0", 18 + "astro": "^5.12.8", 19 + "dotenv": "^17.2.1", 20 + "tailwindcss": "^4.1.11", 21 + "typescript": "^5.9.2" 13 22 } 14 - } 23 + }
+49
src/components/content/BlueskyFeed.astro
··· 1 + --- 2 + import { AtprotoClient } from '../../lib/atproto/client'; 3 + import { loadConfig } from '../../lib/config/site'; 4 + import BlueskyPost from './BlueskyPost.astro'; 5 + 6 + interface Props { 7 + feedUri: string; 8 + limit?: number; 9 + showAuthor?: boolean; 10 + showTimestamp?: boolean; 11 + } 12 + 13 + const { feedUri, limit = 10, showAuthor = true, showTimestamp = true } = Astro.props; 14 + 15 + const config = loadConfig(); 16 + const client = new AtprotoClient(config.atproto.pdsUrl); 17 + 18 + // Fetch feed data with error handling 19 + let blueskyPosts: any[] = []; 20 + try { 21 + const records = await client.getFeed(feedUri, limit); 22 + const filteredRecords = client.filterSupportedRecords(records); 23 + 24 + // Only render Bluesky posts 25 + blueskyPosts = filteredRecords.filter(record => 26 + record.value && record.value.$type === 'app.bsky.feed.post' 27 + ); 28 + } catch (error) { 29 + console.error('Error fetching feed:', error); 30 + blueskyPosts = []; 31 + } 32 + --- 33 + 34 + <div class="space-y-4"> 35 + {blueskyPosts.length > 0 ? ( 36 + blueskyPosts.map((record) => ( 37 + <BlueskyPost 38 + post={record.value} 39 + showAuthor={showAuthor} 40 + showTimestamp={showTimestamp} 41 + /> 42 + )) 43 + ) : ( 44 + <div class="text-center py-8 text-gray-500 dark:text-gray-400"> 45 + <p>No posts found in this feed.</p> 46 + <p class="text-sm mt-2">This could be due to authentication requirements or the feed being empty.</p> 47 + </div> 48 + )} 49 + </div>
+115
src/components/content/BlueskyPost.astro
··· 1 + --- 2 + import type { BlueskyPost } from '../../lib/types/atproto'; 3 + 4 + interface Props { 5 + post: BlueskyPost; 6 + showAuthor?: boolean; 7 + showTimestamp?: boolean; 8 + } 9 + 10 + const { post, showAuthor = false, showTimestamp = true } = Astro.props; 11 + 12 + // Validate post data 13 + if (!post || !post.text) { 14 + return null; 15 + } 16 + 17 + const formatDate = (dateString: string) => { 18 + return new Date(dateString).toLocaleDateString('en-US', { 19 + year: 'numeric', 20 + month: 'short', 21 + day: 'numeric', 22 + }); 23 + }; 24 + 25 + // Helper function to get image URL from blob reference 26 + const getImageUrl = (imageRef: string) => { 27 + return `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=did:plc:6ayddqghxhciedbaofoxkcbs&cid=${imageRef}`; 28 + }; 29 + 30 + // Helper function to render images 31 + const renderImages = (images: any[]) => { 32 + if (!images || images.length === 0) return null; 33 + 34 + return ( 35 + <div class={`grid gap-2 ${images.length === 1 ? 'grid-cols-1' : images.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}> 36 + {images.map((image: any) => { 37 + const imageUrl = getImageUrl(image.image.ref.$link); 38 + return ( 39 + <div class="relative"> 40 + <img 41 + src={imageUrl} 42 + alt={image.alt || 'Post image'} 43 + class="rounded-lg w-full h-auto object-cover" 44 + style={`aspect-ratio: ${image.aspectRatio?.width || 1} / ${image.aspectRatio?.height || 1}`} 45 + /> 46 + </div> 47 + ); 48 + })} 49 + </div> 50 + ); 51 + }; 52 + --- 53 + 54 + <article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 mb-4"> 55 + {showAuthor && post.author && ( 56 + <div class="flex items-center mb-3"> 57 + <div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white text-sm font-medium"> 58 + {post.author.displayName?.[0] || 'U'} 59 + </div> 60 + <div class="ml-3"> 61 + <div class="text-sm font-medium text-gray-900 dark:text-white"> 62 + {post.author.displayName || 'Unknown'} 63 + </div> 64 + <div class="text-xs text-gray-500 dark:text-gray-400"> 65 + @{post.author.handle || 'unknown'} 66 + </div> 67 + </div> 68 + </div> 69 + )} 70 + 71 + <div class="text-gray-900 dark:text-white mb-3"> 72 + {post.text} 73 + </div> 74 + 75 + {post.embed && ( 76 + <div class="mb-3"> 77 + {/* Handle image embeds */} 78 + {post.embed.$type === 'app.bsky.embed.images' && post.embed.images && ( 79 + renderImages(post.embed.images) 80 + )} 81 + 82 + {/* Handle external link embeds */} 83 + {post.embed.$type === 'app.bsky.embed.external' && post.embed.external && ( 84 + <div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3"> 85 + <div class="text-sm text-gray-600 dark:text-gray-400 mb-1"> 86 + {post.embed.external.uri} 87 + </div> 88 + <div class="text-sm font-medium text-gray-900 dark:text-white"> 89 + {post.embed.external.title} 90 + </div> 91 + {post.embed.external.description && ( 92 + <div class="text-sm text-gray-600 dark:text-gray-400 mt-1"> 93 + {post.embed.external.description} 94 + </div> 95 + )} 96 + </div> 97 + )} 98 + 99 + {/* Handle record embeds (quotes/reposts) */} 100 + {post.embed.$type === 'app.bsky.embed.record' && post.embed.record && ( 101 + <div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3 bg-gray-50 dark:bg-gray-700"> 102 + <div class="text-sm text-gray-600 dark:text-gray-400"> 103 + Quoted post 104 + </div> 105 + </div> 106 + )} 107 + </div> 108 + )} 109 + 110 + {showTimestamp && post.createdAt && ( 111 + <div class="text-xs text-gray-500 dark:text-gray-400"> 112 + {formatDate(post.createdAt)} 113 + </div> 114 + )} 115 + </article>
+144
src/components/content/ContentFeed.astro
··· 1 + --- 2 + import { AtprotoClient } from '../../lib/atproto/client'; 3 + import { loadConfig } from '../../lib/config/site'; 4 + import type { AtprotoRecord } from '../../lib/types/atproto'; 5 + 6 + interface Props { 7 + handle: string; 8 + collection?: string; 9 + limit?: number; 10 + feedUri?: string; 11 + showAuthor?: boolean; 12 + showTimestamp?: boolean; 13 + } 14 + 15 + const { 16 + handle, 17 + collection = 'app.bsky.feed.post', 18 + limit = 10, 19 + feedUri, 20 + showAuthor = true, 21 + showTimestamp = true 22 + } = Astro.props; 23 + 24 + const config = loadConfig(); 25 + const client = new AtprotoClient(config.atproto.pdsUrl); 26 + 27 + // Helper function to get image URL from blob reference 28 + const getImageUrl = (imageRef: string) => { 29 + return `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=did:plc:6ayddqghxhciedbaofoxkcbs&cid=${imageRef}`; 30 + }; 31 + 32 + // Helper function to format date 33 + const formatDate = (dateString: string) => { 34 + return new Date(dateString).toLocaleDateString('en-US', { 35 + year: 'numeric', 36 + month: 'short', 37 + day: 'numeric', 38 + }); 39 + }; 40 + 41 + // Fetch data based on whether it's a feed or collection with error handling 42 + let records: AtprotoRecord[] = []; 43 + try { 44 + if (feedUri) { 45 + records = await client.getFeed(feedUri, limit); 46 + } else { 47 + records = await client.getRecords(handle, collection, limit); 48 + } 49 + 50 + } catch (error) { 51 + console.error('ContentFeed: Error fetching content:', error); 52 + records = []; 53 + } 54 + --- 55 + 56 + <div class="space-y-6"> 57 + {records.length > 0 ? ( 58 + <div class="space-y-4"> 59 + {records.map((record) => { 60 + if (record.value?.$type !== 'app.bsky.feed.post') return null; 61 + 62 + const post = record.value; 63 + return ( 64 + <article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 mb-4"> 65 + <div class="text-gray-900 dark:text-white mb-3"> 66 + {post.text} 67 + </div> 68 + 69 + {post.embed && ( 70 + <div class="mb-3"> 71 + {/* Handle image embeds */} 72 + {post.embed.$type === 'app.bsky.embed.images' && post.embed.images && ( 73 + <div class={`grid gap-2 ${post.embed.images.length === 1 ? 'grid-cols-1' : post.embed.images.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}> 74 + {post.embed.images.map((image: any) => { 75 + // Handle both string and BlobRef object formats 76 + let imageRef; 77 + if (typeof image.image?.ref === 'string') { 78 + imageRef = image.image.ref; 79 + } else if (image.image?.ref?.$link) { 80 + imageRef = image.image.ref.$link; 81 + } else if (image.image?.ref?.toString) { 82 + // Handle BlobRef object 83 + imageRef = image.image.ref.toString(); 84 + } 85 + 86 + const imageUrl = imageRef ? getImageUrl(imageRef) : ''; 87 + return ( 88 + <div class="relative"> 89 + <img 90 + src={imageUrl} 91 + alt={image.alt || 'Post image'} 92 + class="rounded-lg w-full h-auto object-cover" 93 + style={`aspect-ratio: ${image.aspectRatio?.width || 1} / ${image.aspectRatio?.height || 1}`} 94 + /> 95 + </div> 96 + ); 97 + })} 98 + </div> 99 + )} 100 + 101 + {/* Handle external link embeds */} 102 + {post.embed.$type === 'app.bsky.embed.external' && post.embed.external && ( 103 + <div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3"> 104 + <div class="text-sm text-gray-600 dark:text-gray-400 mb-1"> 105 + {post.embed.external.uri} 106 + </div> 107 + <div class="text-sm font-medium text-gray-900 dark:text-white"> 108 + {post.embed.external.title} 109 + </div> 110 + {post.embed.external.description && ( 111 + <div class="text-sm text-gray-600 dark:text-gray-400 mt-1"> 112 + {post.embed.external.description} 113 + </div> 114 + )} 115 + </div> 116 + )} 117 + 118 + {/* Handle record embeds (quotes/reposts) */} 119 + {post.embed.$type === 'app.bsky.embed.record' && post.embed.record && ( 120 + <div class="border border-gray-200 dark:border-gray-700 rounded-lg p-3 bg-gray-50 dark:bg-gray-700"> 121 + <div class="text-sm text-gray-600 dark:text-gray-400"> 122 + Quoted post 123 + </div> 124 + </div> 125 + )} 126 + </div> 127 + )} 128 + 129 + {showTimestamp && post.createdAt && ( 130 + <div class="text-xs text-gray-500 dark:text-gray-400"> 131 + {formatDate(post.createdAt)} 132 + </div> 133 + )} 134 + </article> 135 + ); 136 + })} 137 + </div> 138 + ) : ( 139 + <div class="text-center py-8 text-gray-500 dark:text-gray-400"> 140 + <p>No posts found.</p> 141 + <p class="text-sm mt-2">Debug: Handle = {handle}, Records fetched = {records.length}</p> 142 + </div> 143 + )} 144 + </div>
+68
src/components/content/GrainImageGallery.astro
··· 1 + --- 2 + import type { GrainImageGallery } from '../../lib/types/atproto'; 3 + 4 + interface Props { 5 + gallery: GrainImageGallery; 6 + showDescription?: boolean; 7 + showTimestamp?: boolean; 8 + columns?: number; 9 + } 10 + 11 + const { gallery, showDescription = true, showTimestamp = true, columns = 3 } = Astro.props; 12 + 13 + const formatDate = (dateString: string) => { 14 + return new Date(dateString).toLocaleDateString('en-US', { 15 + year: 'numeric', 16 + month: 'long', 17 + day: 'numeric', 18 + }); 19 + }; 20 + 21 + const gridCols = { 22 + 1: 'grid-cols-1', 23 + 2: 'grid-cols-2', 24 + 3: 'grid-cols-3', 25 + 4: 'grid-cols-4', 26 + 5: 'grid-cols-5', 27 + 6: 'grid-cols-6', 28 + }[columns] || 'grid-cols-3'; 29 + --- 30 + 31 + <article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-6"> 32 + <header class="mb-4"> 33 + <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2"> 34 + {gallery.title} 35 + </h2> 36 + 37 + {showDescription && gallery.description && ( 38 + <div class="text-gray-600 dark:text-gray-400 mb-3"> 39 + {gallery.description} 40 + </div> 41 + )} 42 + 43 + {showTimestamp && ( 44 + <div class="text-sm text-gray-500 dark:text-gray-400 mb-4"> 45 + Created on {formatDate(gallery.createdAt)} 46 + </div> 47 + )} 48 + </header> 49 + 50 + {gallery.images && gallery.images.length > 0 && ( 51 + <div class={`grid ${gridCols} gap-4`}> 52 + {gallery.images.map((image) => ( 53 + <div class="relative group"> 54 + <img 55 + src={image.url} 56 + alt={image.alt || 'Gallery image'} 57 + class="w-full h-48 object-cover rounded-lg transition-transform duration-200 group-hover:scale-105" 58 + /> 59 + {image.alt && ( 60 + <div class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 text-white text-sm p-2 rounded-b-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200"> 61 + {image.alt} 62 + </div> 63 + )} 64 + </div> 65 + ))} 66 + </div> 67 + )} 68 + </article>
+47
src/components/content/LeafletPublication.astro
··· 1 + --- 2 + import type { LeafletPublication } from '../../lib/types/atproto'; 3 + 4 + interface Props { 5 + publication: LeafletPublication; 6 + showCategory?: boolean; 7 + showTimestamp?: boolean; 8 + } 9 + 10 + const { publication, showCategory = true, showTimestamp = true } = Astro.props; 11 + 12 + const formatDate = (dateString: string) => { 13 + return new Date(dateString).toLocaleDateString('en-US', { 14 + year: 'numeric', 15 + month: 'long', 16 + day: 'numeric', 17 + }); 18 + }; 19 + --- 20 + 21 + <article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-6"> 22 + <header class="mb-4"> 23 + <div class="flex items-center justify-between mb-2"> 24 + <h2 class="text-2xl font-bold text-gray-900 dark:text-white"> 25 + {publication.title} 26 + </h2> 27 + 28 + {showCategory && publication.category && ( 29 + <span class="px-3 py-1 bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 text-sm rounded-full"> 30 + {publication.category} 31 + </span> 32 + )} 33 + </div> 34 + 35 + {showTimestamp && ( 36 + <div class="text-sm text-gray-500 dark:text-gray-400 mb-3"> 37 + Published on {formatDate(publication.publishedAt)} 38 + </div> 39 + )} 40 + </header> 41 + 42 + <div class="prose prose-gray dark:prose-invert max-w-none"> 43 + <div class="text-gray-700 dark:text-gray-300 leading-relaxed"> 44 + {publication.content} 45 + </div> 46 + </div> 47 + </article>
+49
src/components/content/WhitewindBlogPost.astro
··· 1 + --- 2 + import type { WhitewindBlogPost } from '../../lib/types/atproto'; 3 + 4 + interface Props { 5 + post: WhitewindBlogPost; 6 + showTags?: boolean; 7 + showTimestamp?: boolean; 8 + } 9 + 10 + const { post, showTags = true, showTimestamp = true } = Astro.props; 11 + 12 + const formatDate = (dateString: string) => { 13 + return new Date(dateString).toLocaleDateString('en-US', { 14 + year: 'numeric', 15 + month: 'long', 16 + day: 'numeric', 17 + }); 18 + }; 19 + --- 20 + 21 + <article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-6"> 22 + <header class="mb-4"> 23 + <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-2"> 24 + {post.title} 25 + </h2> 26 + 27 + {showTimestamp && ( 28 + <div class="text-sm text-gray-500 dark:text-gray-400 mb-3"> 29 + Published on {formatDate(post.publishedAt)} 30 + </div> 31 + )} 32 + 33 + {showTags && post.tags && post.tags.length > 0 && ( 34 + <div class="flex flex-wrap gap-2 mb-4"> 35 + {post.tags.map((tag) => ( 36 + <span class="px-2 py-1 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs rounded-full"> 37 + #{tag} 38 + </span> 39 + ))} 40 + </div> 41 + )} 42 + </header> 43 + 44 + <div class="prose prose-gray dark:prose-invert max-w-none"> 45 + <div class="text-gray-700 dark:text-gray-300 leading-relaxed"> 46 + {post.content} 47 + </div> 48 + </div> 49 + </article>
+26
src/layouts/Layout.astro
··· 1 + --- 2 + import '../styles/global.css'; 3 + 4 + interface Props { 5 + title: string; 6 + description?: string; 7 + } 8 + 9 + const { title, description } = Astro.props; 10 + --- 11 + 12 + <!DOCTYPE html> 13 + <html lang="en"> 14 + <head> 15 + <meta charset="UTF-8" /> 16 + <meta name="description" content={description || "A personal website powered by ATproto"} /> 17 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 18 + <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> 19 + <title>{title || 'Home'} | Tynanverse</title> 20 + </head> 21 + <body class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white font-sans"> 22 + <div class="min-h-screen"> 23 + <slot /> 24 + </div> 25 + </body> 26 + </html>
+172
src/lib/atproto/client.ts
··· 1 + import { AtpAgent } from '@atproto/api'; 2 + import type { AtprotoRecord } from '../types/atproto'; 3 + 4 + // Simple in-memory cache with TTL 5 + class AtprotoCache { 6 + private cache = new Map<string, { data: any; timestamp: number }>(); 7 + private ttl = 5 * 60 * 1000; // 5 minutes 8 + 9 + set(key: string, data: any): void { 10 + this.cache.set(key, { data, timestamp: Date.now() }); 11 + } 12 + 13 + get(key: string): any | null { 14 + const item = this.cache.get(key); 15 + if (!item) return null; 16 + 17 + if (Date.now() - item.timestamp > this.ttl) { 18 + this.cache.delete(key); 19 + return null; 20 + } 21 + 22 + return item.data; 23 + } 24 + 25 + clear(): void { 26 + this.cache.clear(); 27 + } 28 + } 29 + 30 + export class AtprotoClient { 31 + private agent: AtpAgent; 32 + private cache: AtprotoCache; 33 + 34 + constructor(pdsUrl: string = 'https://bsky.social') { 35 + this.agent = new AtpAgent({ service: pdsUrl }); 36 + this.cache = new AtprotoCache(); 37 + } 38 + 39 + async resolveHandle(handle: string): Promise<string | null> { 40 + const cacheKey = `handle:${handle}`; 41 + const cached = this.cache.get(cacheKey); 42 + if (cached) return cached; 43 + 44 + try { 45 + const response = await this.agent.api.com.atproto.identity.resolveHandle({ 46 + handle: handle, 47 + }); 48 + 49 + const did = response.data.did; 50 + this.cache.set(cacheKey, did); 51 + return did; 52 + } catch (error) { 53 + console.error('Error resolving handle:', error); 54 + return null; 55 + } 56 + } 57 + 58 + async getRecords(identifier: string, collection: string, limit: number = 50): Promise<AtprotoRecord[]> { 59 + // Check if identifier is a handle (contains @) or DID 60 + let did = identifier; 61 + if (identifier.includes('@')) { 62 + console.log('AtprotoClient: Resolving handle to DID:', identifier); 63 + const resolvedDid = await this.resolveHandle(identifier); 64 + if (!resolvedDid) { 65 + console.error('AtprotoClient: Failed to resolve handle:', identifier); 66 + return []; 67 + } 68 + did = resolvedDid; 69 + console.log('AtprotoClient: Resolved handle to DID:', did); 70 + } 71 + 72 + const cacheKey = `records:${did}:${collection}:${limit}`; 73 + const cached = this.cache.get(cacheKey); 74 + if (cached) return cached; 75 + 76 + console.log('AtprotoClient: Fetching records for DID:', did); 77 + console.log('AtprotoClient: Collection:', collection); 78 + console.log('AtprotoClient: Limit:', limit); 79 + 80 + try { 81 + const response = await this.agent.api.com.atproto.repo.listRecords({ 82 + repo: did, 83 + collection, 84 + limit, 85 + }); 86 + 87 + console.log('AtprotoClient: API response received'); 88 + console.log('AtprotoClient: Records count:', response.data.records.length); 89 + 90 + const records = response.data.records.map((record: any) => ({ 91 + uri: record.uri, 92 + cid: record.cid, 93 + value: record.value, 94 + indexedAt: record.indexedAt, 95 + })); 96 + 97 + this.cache.set(cacheKey, records); 98 + return records; 99 + } catch (error) { 100 + console.error('AtprotoClient: Error fetching records:', error); 101 + console.error('AtprotoClient: Error details:', { 102 + did, 103 + collection, 104 + limit, 105 + error: error instanceof Error ? error.message : String(error) 106 + }); 107 + return []; 108 + } 109 + } 110 + 111 + async getFeed(feedUri: string, limit: number = 20): Promise<AtprotoRecord[]> { 112 + const cacheKey = `feed:${feedUri}:${limit}`; 113 + const cached = this.cache.get(cacheKey); 114 + if (cached) return cached; 115 + 116 + try { 117 + const response = await this.agent.api.app.bsky.feed.getFeed({ 118 + feed: feedUri, 119 + limit, 120 + }); 121 + 122 + const records = response.data.feed.map((item: any) => ({ 123 + uri: item.post.uri, 124 + cid: item.post.cid, 125 + value: item.post.record, 126 + indexedAt: item.post.indexedAt, 127 + })); 128 + 129 + this.cache.set(cacheKey, records); 130 + return records; 131 + } catch (error) { 132 + console.error('Error fetching feed:', error); 133 + return []; 134 + } 135 + } 136 + 137 + async getProfile(did: string): Promise<any> { 138 + const cacheKey = `profile:${did}`; 139 + const cached = this.cache.get(cacheKey); 140 + if (cached) return cached; 141 + 142 + try { 143 + const response = await this.agent.api.app.bsky.actor.getProfile({ 144 + actor: did, 145 + }); 146 + 147 + this.cache.set(cacheKey, response.data); 148 + return response.data; 149 + } catch (error) { 150 + console.error('Error fetching profile:', error); 151 + return null; 152 + } 153 + } 154 + 155 + // Filter records by supported content types 156 + filterSupportedRecords(records: AtprotoRecord[]): AtprotoRecord[] { 157 + return records.filter(record => { 158 + const type = record.value?.$type; 159 + return type && ( 160 + type === 'app.bsky.feed.post' || 161 + type === 'app.bsky.actor.profile#whitewindBlogPost' || 162 + type === 'app.bsky.actor.profile#leafletPublication' || 163 + type === 'app.bsky.actor.profile#grainImageGallery' 164 + ); 165 + }); 166 + } 167 + 168 + // Clear cache (useful for development) 169 + clearCache(): void { 170 + this.cache.clear(); 171 + } 172 + }
+23
src/lib/components/register.ts
··· 1 + import { registerComponent } from './registry'; 2 + import BlueskyPost from '../../components/content/BlueskyPost.astro'; 3 + import WhitewindBlogPost from '../../components/content/WhitewindBlogPost.astro'; 4 + import LeafletPublication from '../../components/content/LeafletPublication.astro'; 5 + import GrainImageGallery from '../../components/content/GrainImageGallery.astro'; 6 + 7 + // Register all content components 8 + export function registerAllComponents() { 9 + // Register Bluesky post component 10 + registerComponent('app.bsky.feed.post', BlueskyPost); 11 + 12 + // Register Whitewind blog post component 13 + registerComponent('app.bsky.actor.profile#whitewindBlogPost', WhitewindBlogPost); 14 + 15 + // Register Leaflet publication component 16 + registerComponent('app.bsky.actor.profile#leafletPublication', LeafletPublication); 17 + 18 + // Register Grain image gallery component 19 + registerComponent('app.bsky.actor.profile#grainImageGallery', GrainImageGallery); 20 + } 21 + 22 + // Auto-register components when this module is imported 23 + registerAllComponents();
+57
src/lib/components/registry.ts
··· 1 + import type { ContentComponent } from '../types/atproto'; 2 + 3 + // Component registry for type-safe content rendering 4 + class ComponentRegistry { 5 + private components = new Map<string, ContentComponent>(); 6 + 7 + // Register a component for a specific content type 8 + register(type: string, component: any, props?: Record<string, any>): void { 9 + this.components.set(type, { 10 + type, 11 + component, 12 + props, 13 + }); 14 + } 15 + 16 + // Get a component for a specific content type 17 + get(type: string): ContentComponent | undefined { 18 + return this.components.get(type); 19 + } 20 + 21 + // Check if a component exists for a content type 22 + has(type: string): boolean { 23 + return this.components.has(type); 24 + } 25 + 26 + // Get all registered component types 27 + getRegisteredTypes(): string[] { 28 + return Array.from(this.components.keys()); 29 + } 30 + 31 + // Clear all registered components 32 + clear(): void { 33 + this.components.clear(); 34 + } 35 + } 36 + 37 + // Global component registry instance 38 + export const componentRegistry = new ComponentRegistry(); 39 + 40 + // Type-safe component registration helper 41 + export function registerComponent( 42 + type: string, 43 + component: any, 44 + props?: Record<string, any> 45 + ): void { 46 + componentRegistry.register(type, component, props); 47 + } 48 + 49 + // Type-safe component retrieval helper 50 + export function getComponent(type: string): ContentComponent | undefined { 51 + return componentRegistry.get(type); 52 + } 53 + 54 + // Check if content type has a registered component 55 + export function hasComponent(type: string): boolean { 56 + return componentRegistry.has(type); 57 + }
+87
src/lib/config/site.ts
··· 1 + import dotenv from 'dotenv'; 2 + 3 + // Load environment variables from .env file 4 + dotenv.config(); 5 + 6 + export interface SiteConfig { 7 + // ATproto configuration 8 + atproto: { 9 + handle: string; 10 + did?: string; // Keep for backward compatibility 11 + pdsUrl?: string; 12 + }; 13 + 14 + // Site metadata 15 + site: { 16 + title: string; 17 + description: string; 18 + author: string; 19 + url: string; 20 + }; 21 + 22 + // Theme configuration 23 + theme: { 24 + primaryColor: string; 25 + secondaryColor: string; 26 + accentColor: string; 27 + fontFamily: string; 28 + }; 29 + 30 + // Content configuration 31 + content: { 32 + defaultFeedLimit: number; 33 + cacheTTL: number; // in milliseconds 34 + }; 35 + } 36 + 37 + // Default configuration 38 + export const defaultConfig: SiteConfig = { 39 + atproto: { 40 + handle: '', 41 + did: '', 42 + pdsUrl: 'https://bsky.social', 43 + }, 44 + site: { 45 + title: 'Tynanverse', 46 + description: 'A personal website powered by ATproto, made by Tynan', 47 + author: 'Tynan', 48 + url: 'https://your-domain.com', 49 + }, 50 + theme: { 51 + primaryColor: '#3b82f6', 52 + secondaryColor: '#64748b', 53 + accentColor: '#f59e0b', 54 + fontFamily: 'Inter, system-ui, sans-serif', 55 + }, 56 + content: { 57 + defaultFeedLimit: 20, 58 + cacheTTL: 5 * 60 * 1000, // 5 minutes 59 + }, 60 + }; 61 + 62 + // Load configuration from environment variables 63 + export function loadConfig(): SiteConfig { 64 + return { 65 + atproto: { 66 + handle: process.env.ATPROTO_HANDLE || defaultConfig.atproto.handle, 67 + did: process.env.ATPROTO_DID || defaultConfig.atproto.did, 68 + pdsUrl: process.env.ATPROTO_PDS_URL || defaultConfig.atproto.pdsUrl, 69 + }, 70 + site: { 71 + title: process.env.SITE_TITLE || defaultConfig.site.title, 72 + description: process.env.SITE_DESCRIPTION || defaultConfig.site.description, 73 + author: process.env.SITE_AUTHOR || defaultConfig.site.author, 74 + url: process.env.SITE_URL || defaultConfig.site.url, 75 + }, 76 + theme: { 77 + primaryColor: process.env.THEME_PRIMARY_COLOR || defaultConfig.theme.primaryColor, 78 + secondaryColor: process.env.THEME_SECONDARY_COLOR || defaultConfig.theme.secondaryColor, 79 + accentColor: process.env.THEME_ACCENT_COLOR || defaultConfig.theme.accentColor, 80 + fontFamily: process.env.THEME_FONT_FAMILY || defaultConfig.theme.fontFamily, 81 + }, 82 + content: { 83 + defaultFeedLimit: parseInt(process.env.CONTENT_DEFAULT_FEED_LIMIT || '20'), 84 + cacheTTL: parseInt(process.env.CONTENT_CACHE_TTL || '300000'), 85 + }, 86 + }; 87 + }
+124
src/lib/types/atproto.ts
··· 1 + // Base ATproto record types 2 + export interface AtprotoRecord { 3 + uri: string; 4 + cid: string; 5 + value: any; 6 + indexedAt: string; 7 + } 8 + 9 + // Bluesky post types with proper embed handling 10 + export interface BlueskyPost { 11 + text: string; 12 + createdAt: string; 13 + embed?: { 14 + $type: 'app.bsky.embed.images' | 'app.bsky.embed.external' | 'app.bsky.embed.record'; 15 + images?: Array<{ 16 + alt?: string; 17 + image: { 18 + $type: 'blob'; 19 + ref: { 20 + $link: string; 21 + }; 22 + mimeType: string; 23 + size: number; 24 + }; 25 + aspectRatio?: { 26 + width: number; 27 + height: number; 28 + }; 29 + }>; 30 + external?: { 31 + uri: string; 32 + title: string; 33 + description?: string; 34 + }; 35 + record?: { 36 + uri: string; 37 + cid: string; 38 + }; 39 + }; 40 + author?: { 41 + displayName?: string; 42 + handle?: string; 43 + }; 44 + reply?: { 45 + root: { 46 + uri: string; 47 + cid: string; 48 + }; 49 + parent: { 50 + uri: string; 51 + cid: string; 52 + }; 53 + }; 54 + facets?: Array<{ 55 + index: { 56 + byteStart: number; 57 + byteEnd: number; 58 + }; 59 + features: Array<{ 60 + $type: string; 61 + [key: string]: any; 62 + }>; 63 + }>; 64 + langs?: string[]; 65 + uri?: string; 66 + cid?: string; 67 + } 68 + 69 + // Custom lexicon types (to be extended) 70 + export interface CustomLexiconRecord { 71 + $type: string; 72 + [key: string]: any; 73 + } 74 + 75 + // Whitewind blog post type 76 + export interface WhitewindBlogPost extends CustomLexiconRecord { 77 + $type: 'app.bsky.actor.profile#whitewindBlogPost'; 78 + title: string; 79 + content: string; 80 + publishedAt: string; 81 + tags?: string[]; 82 + } 83 + 84 + // Leaflet publication type 85 + export interface LeafletPublication extends CustomLexiconRecord { 86 + $type: 'app.bsky.actor.profile#leafletPublication'; 87 + title: string; 88 + content: string; 89 + publishedAt: string; 90 + category?: string; 91 + } 92 + 93 + // Grain social image gallery type 94 + export interface GrainImageGallery extends CustomLexiconRecord { 95 + $type: 'app.bsky.actor.profile#grainImageGallery'; 96 + title: string; 97 + description?: string; 98 + images: Array<{ 99 + alt: string; 100 + url: string; 101 + }>; 102 + createdAt: string; 103 + } 104 + 105 + // Union type for all supported content types 106 + export type SupportedContentType = 107 + | BlueskyPost 108 + | WhitewindBlogPost 109 + | LeafletPublication 110 + | GrainImageGallery; 111 + 112 + // Component registry type 113 + export interface ContentComponent { 114 + type: string; 115 + component: any; 116 + props?: Record<string, any>; 117 + } 118 + 119 + // Feed configuration type 120 + export interface FeedConfig { 121 + uri: string; 122 + limit?: number; 123 + filter?: (record: AtprotoRecord) => boolean; 124 + }
+51 -12
src/pages/index.astro
··· 1 1 --- 2 + import Layout from '../layouts/Layout.astro'; 3 + import ContentFeed from '../components/content/ContentFeed.astro'; 4 + import { loadConfig } from '../lib/config/site'; 2 5 6 + const config = loadConfig(); 3 7 --- 4 8 5 - <html lang="en"> 6 - <head> 7 - <meta charset="utf-8" /> 8 - <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> 9 - <meta name="viewport" content="width=device-width" /> 10 - <meta name="generator" content={Astro.generator} /> 11 - <title>Astro</title> 12 - </head> 13 - <body> 14 - <h1>Astro</h1> 15 - </body> 16 - </html> 9 + <Layout title="Home Page"> 10 + <div class="container mx-auto px-4 py-8"> 11 + <header class="text-center mb-12"> 12 + <h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4"> 13 + Welcome to {config.site.title || 'Tynanverse'} 14 + </h1> 15 + <p class="text-xl text-gray-600 dark:text-gray-400 max-w-2xl mx-auto"> 16 + {config.site.description || 'A personal website powered by ATproto, made by Tynan'} 17 + </p> 18 + </header> 19 + 20 + <main class="max-w-4xl mx-auto space-y-12"> 21 + <!-- My Posts Feed --> 22 + {config.atproto.handle && config.atproto.handle !== 'your-handle-here' ? ( 23 + <section> 24 + <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6"> 25 + My Posts 26 + </h2> 27 + <ContentFeed 28 + handle={config.atproto.handle} 29 + limit={10} 30 + showAuthor={false} 31 + showTimestamp={true} 32 + /> 33 + </section> 34 + ) : ( 35 + <section> 36 + <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6"> 37 + Configuration Required 38 + </h2> 39 + <div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-6"> 40 + <p class="text-yellow-800 dark:text-yellow-200 mb-4"> 41 + To display your posts, please configure your Bluesky handle in the environment variables. 42 + </p> 43 + <div class="text-sm text-yellow-700 dark:text-yellow-300"> 44 + <p class="mb-2">Create a <code class="bg-yellow-100 dark:bg-yellow-800 px-1 rounded">.env</code> file with:</p> 45 + <pre class="bg-yellow-100 dark:bg-yellow-800 p-3 rounded text-xs overflow-x-auto"> 46 + ATPROTO_HANDLE=your-handle.bsky.social 47 + SITE_TITLE=Your Site Title 48 + SITE_AUTHOR=Your Name</pre> 49 + </div> 50 + </div> 51 + </section> 52 + )} 53 + </main> 54 + </div> 55 + </Layout>
+76
src/styles/global.css
··· 1 + @import "tailwindcss"; 2 + 3 + /* Custom styles */ 4 + html { 5 + font-family: var(--font-family, Inter, system-ui, sans-serif); 6 + } 7 + 8 + body { 9 + font-feature-settings: "rlig" 1, "calt" 1; 10 + } 11 + 12 + /* Prose styles */ 13 + .prose { 14 + color: rgb(55 65 81); 15 + } 16 + 17 + .dark .prose { 18 + color: rgb(209 213 219); 19 + } 20 + 21 + .prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 { 22 + color: rgb(17 24 39); 23 + font-weight: 600; 24 + } 25 + 26 + .dark .prose h1, .dark .prose h2, .dark .prose h3, .dark .prose h4, .dark .prose h5, .dark .prose h6 { 27 + color: rgb(255 255 255); 28 + } 29 + 30 + .prose a { 31 + color: rgb(37 99 235); 32 + } 33 + 34 + .prose a:hover { 35 + color: rgb(30 64 175); 36 + } 37 + 38 + .dark .prose a { 39 + color: rgb(96 165 250); 40 + } 41 + 42 + .dark .prose a:hover { 43 + color: rgb(147 197 253); 44 + } 45 + 46 + .prose blockquote { 47 + border-left: 4px solid rgb(209 213 219); 48 + padding-left: 1rem; 49 + font-style: italic; 50 + } 51 + 52 + .dark .prose blockquote { 53 + border-left-color: rgb(75 85 99); 54 + } 55 + 56 + .prose code { 57 + background-color: rgb(243 244 246); 58 + padding: 0.125rem 0.25rem; 59 + border-radius: 0.25rem; 60 + font-size: 0.875rem; 61 + } 62 + 63 + .dark .prose code { 64 + background-color: rgb(31 41 55); 65 + } 66 + 67 + .prose pre { 68 + background-color: rgb(243 244 246); 69 + padding: 1rem; 70 + border-radius: 0.5rem; 71 + overflow-x: auto; 72 + } 73 + 74 + .dark .prose pre { 75 + background-color: rgb(31 41 55); 76 + }