diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml new file mode 100644 index 00000000..e7f7e81d --- /dev/null +++ b/.github/workflows/deploy-website.yml @@ -0,0 +1,82 @@ +# GitHub Pages deployment workflow +# Builds the Astro website and deploys to GitHub Pages + +name: Deploy Website to GitHub Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + paths: + - "website/**" + - "agents/**" + - "prompts/**" + - "instructions/**" + - "skills/**" + - "collections/**" + - "cookbook/**" + - "eng/generate-website-data.mjs" + - ".github/workflows/deploy-website.yml" + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install root dependencies + run: npm ci + + - name: Install website dependencies + run: npm ci + working-directory: ./website + + - name: Generate website data + run: npm run website:data + + - name: Build Astro site + run: npm run build + working-directory: ./website + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: "./website/dist" + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 893a921b..3452d2df 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,8 @@ reports/ # macOS system files .DS_Store *.tmp + +# Website build artifacts +website/dist/ +website/.astro/ +website/public/data/* diff --git a/.schemas/cookbook.schema.json b/.schemas/cookbook.schema.json new file mode 100644 index 00000000..857bd84e --- /dev/null +++ b/.schemas/cookbook.schema.json @@ -0,0 +1,99 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Cookbook Manifest", + "description": "Schema for cookbook.yml manifest defining cookbooks and recipes", + "type": "object", + "required": ["cookbooks"], + "properties": { + "cookbooks": { + "type": "array", + "description": "List of cookbooks", + "items": { + "type": "object", + "required": ["id", "name", "description", "path", "languages", "recipes"], + "properties": { + "id": { + "type": "string", + "description": "Unique identifier for the cookbook", + "pattern": "^[a-z0-9-]+$" + }, + "name": { + "type": "string", + "description": "Display name for the cookbook" + }, + "description": { + "type": "string", + "description": "Brief description of the cookbook" + }, + "path": { + "type": "string", + "description": "Relative path to the cookbook folder" + }, + "featured": { + "type": "boolean", + "description": "Whether this cookbook should be featured", + "default": false + }, + "languages": { + "type": "array", + "description": "Programming languages supported by this cookbook", + "items": { + "type": "object", + "required": ["id", "name"], + "properties": { + "id": { + "type": "string", + "description": "Language identifier (folder name)", + "pattern": "^[a-z0-9-]+$" + }, + "name": { + "type": "string", + "description": "Display name for the language" + }, + "icon": { + "type": "string", + "description": "Emoji icon for the language" + }, + "extension": { + "type": "string", + "description": "File extension for runnable examples", + "pattern": "^\\.[a-z]+$" + } + } + } + }, + "recipes": { + "type": "array", + "description": "List of recipes in this cookbook", + "items": { + "type": "object", + "required": ["id", "name", "description"], + "properties": { + "id": { + "type": "string", + "description": "Recipe identifier (matches markdown filename without extension)", + "pattern": "^[a-z0-9-]+$" + }, + "name": { + "type": "string", + "description": "Display name for the recipe" + }, + "description": { + "type": "string", + "description": "Brief description of what the recipe covers" + }, + "tags": { + "type": "array", + "description": "Tags for filtering and categorization", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } +} diff --git a/.schemas/tools.schema.json b/.schemas/tools.schema.json new file mode 100644 index 00000000..4de6fc09 --- /dev/null +++ b/.schemas/tools.schema.json @@ -0,0 +1,151 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Tools Catalog", + "description": "Schema for the awesome-copilot tools catalog (website/data/tools.yml)", + "type": "object", + "required": ["tools"], + "additionalProperties": false, + "properties": { + "tools": { + "type": "array", + "description": "List of tools in the catalog", + "minItems": 1, + "items": { + "type": "object", + "required": ["id", "name", "description", "category"], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "description": "Unique identifier for the tool", + "pattern": "^[a-z0-9-]+$", + "minLength": 1, + "maxLength": 50 + }, + "name": { + "type": "string", + "description": "Display name for the tool", + "minLength": 1, + "maxLength": 100 + }, + "description": { + "type": "string", + "description": "Description of what this tool does", + "minLength": 1, + "maxLength": 1000 + }, + "category": { + "type": "string", + "description": "Category for grouping tools", + "minLength": 1, + "maxLength": 50, + "examples": ["MCP Servers", "VS Code Extensions", "CLI Tools", "Visual Studio Extensions"] + }, + "featured": { + "type": "boolean", + "description": "Whether this tool is featured (shown first)", + "default": false + }, + "requirements": { + "type": "array", + "description": "List of requirements to use this tool", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "maxItems": 10 + }, + "features": { + "type": "array", + "description": "List of key features", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "maxItems": 20 + }, + "links": { + "type": "object", + "description": "Links related to this tool", + "additionalProperties": false, + "properties": { + "blog": { + "type": "string", + "description": "Link to a blog post about the tool", + "format": "uri" + }, + "documentation": { + "type": "string", + "description": "Link to documentation", + "format": "uri" + }, + "github": { + "type": "string", + "description": "Link to GitHub repository", + "format": "uri" + }, + "marketplace": { + "type": "string", + "description": "Link to VS Code or Visual Studio Marketplace", + "format": "uri" + }, + "npm": { + "type": "string", + "description": "Link to npm package", + "format": "uri" + }, + "pypi": { + "type": "string", + "description": "Link to PyPI package", + "format": "uri" + }, + "vscode": { + "type": "string", + "description": "VS Code install link (vscode: URI or aka.ms link)" + }, + "vscode-insiders": { + "type": "string", + "description": "VS Code Insiders install link" + }, + "visual-studio": { + "type": "string", + "description": "Visual Studio install link" + } + } + }, + "configuration": { + "type": "object", + "description": "Configuration snippet for the tool", + "required": ["type", "content"], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "description": "Type of configuration (for syntax highlighting)", + "enum": ["json", "yaml", "bash", "toml", "ini"] + }, + "content": { + "type": "string", + "description": "The configuration content" + } + } + }, + "tags": { + "type": "array", + "description": "Tags for filtering and discovery", + "items": { + "type": "string", + "pattern": "^[a-z0-9-]+$", + "minLength": 1, + "maxLength": 30 + }, + "uniqueItems": true, + "maxItems": 15 + } + } + } + } + } +} diff --git a/.vscode/settings.json b/.vscode/settings.json index bf073eb4..b28e8cdb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,7 @@ "*.prompt.md": "prompt" }, "yaml.schemas": { - "./.schemas/collection.schema.json": "*.collection.yml" + "./.schemas/collection.schema.json": "*.collection.yml", + "./.schemas/tools.schema.json": "website/data/tools.yml", } } diff --git a/cookbook/cookbook.yml b/cookbook/cookbook.yml new file mode 100644 index 00000000..d80454b5 --- /dev/null +++ b/cookbook/cookbook.yml @@ -0,0 +1,63 @@ +# yaml-language-server: $schema=../.schemas/cookbook.schema.json +# Cookbook manifest for the Awesome GitHub Copilot website +# This file defines the structure of cookbooks and recipes for the Samples page + +cookbooks: + - id: copilot-sdk + name: GitHub Copilot SDK + description: Ready-to-use recipes for building with the GitHub Copilot SDK across multiple languages + path: cookbook/copilot-sdk + featured: true + languages: + - id: nodejs + name: Node.js / TypeScript + icon: "\uE628" + extension: .ts + - id: python + name: Python + icon: "\uE73C" + extension: .py + - id: dotnet + name: .NET (C#) + icon: "\uE648" + extension: .cs + - id: go + name: Go + icon: "\uE626" + extension: .go + recipes: + - id: error-handling + name: Error Handling + description: Handle errors gracefully including connection failures, timeouts, and cleanup + tags: + - errors + - basics + - reliability + - id: multiple-sessions + name: Multiple Sessions + description: Manage multiple independent conversations simultaneously + tags: + - sessions + - advanced + - concurrency + - id: managing-local-files + name: Managing Local Files + description: Organize files by metadata using AI-powered grouping strategies + tags: + - files + - organization + - ai-powered + - id: pr-visualization + name: PR Visualization + description: Generate interactive PR age charts using GitHub MCP Server + tags: + - github + - visualization + - mcp + - id: persisting-sessions + name: Persisting Sessions + description: Save and resume sessions across restarts + tags: + - sessions + - persistence + - state-management diff --git a/eng/constants.mjs b/eng/constants.mjs index a690076e..180980a2 100644 --- a/eng/constants.mjs +++ b/eng/constants.mjs @@ -123,6 +123,7 @@ const PROMPTS_DIR = path.join(ROOT_FOLDER, "prompts"); const AGENTS_DIR = path.join(ROOT_FOLDER, "agents"); const SKILLS_DIR = path.join(ROOT_FOLDER, "skills"); const COLLECTIONS_DIR = path.join(ROOT_FOLDER, "collections"); +const COOKBOOK_DIR = path.join(ROOT_FOLDER, "cookbook"); const MAX_COLLECTION_ITEMS = 50; // Agent Skills validation constants @@ -145,6 +146,7 @@ export { AGENTS_DIR, SKILLS_DIR, COLLECTIONS_DIR, + COOKBOOK_DIR, MAX_COLLECTION_ITEMS, SKILL_NAME_MIN_LENGTH, SKILL_NAME_MAX_LENGTH, diff --git a/eng/generate-website-data.mjs b/eng/generate-website-data.mjs new file mode 100644 index 00000000..fdd14fc0 --- /dev/null +++ b/eng/generate-website-data.mjs @@ -0,0 +1,825 @@ +#!/usr/bin/env node + +/** + * Generate JSON metadata files for the GitHub Pages website. + * This script extracts metadata from agents, prompts, instructions, skills, and collections + * and writes them to website/data/ for client-side search and display. + */ + +import fs from "fs"; +import path, { dirname } from "path"; +import { fileURLToPath } from "url"; +import { + AGENTS_DIR, + COLLECTIONS_DIR, + COOKBOOK_DIR, + INSTRUCTIONS_DIR, + PROMPTS_DIR, + ROOT_FOLDER, + SKILLS_DIR, +} from "./constants.mjs"; +import { + parseCollectionYaml, + parseFrontmatter, + parseSkillMetadata, + parseYamlFile, +} from "./yaml-parser.mjs"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const WEBSITE_DATA_DIR = path.join(ROOT_FOLDER, "website", "public", "data"); +const WEBSITE_SOURCE_DATA_DIR = path.join(ROOT_FOLDER, "website", "data"); + +/** + * Ensure the output directory exists + */ +function ensureDataDir() { + if (!fs.existsSync(WEBSITE_DATA_DIR)) { + fs.mkdirSync(WEBSITE_DATA_DIR, { recursive: true }); + } +} + +/** + * Extract title from filename or frontmatter + */ +function extractTitle(filePath, frontmatter) { + if (frontmatter?.title) return frontmatter.title; + if (frontmatter?.name) { + return frontmatter.name + .split("-") + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "); + } + // Fallback to filename + const basename = path.basename(filePath); + const name = basename + .replace(/\.(agent|prompt|instructions)\.md$/, "") + .replace(/\.md$/, ""); + return name + .split("-") + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "); +} + +/** + * Generate agents metadata + */ +function generateAgentsData() { + const agents = []; + const files = fs + .readdirSync(AGENTS_DIR) + .filter((f) => f.endsWith(".agent.md")); + + // Track all unique values for filters + const allModels = new Set(); + const allTools = new Set(); + + for (const file of files) { + const filePath = path.join(AGENTS_DIR, file); + const frontmatter = parseFrontmatter(filePath); + const relativePath = path + .relative(ROOT_FOLDER, filePath) + .replace(/\\/g, "/"); + + const model = frontmatter?.model || null; + const tools = frontmatter?.tools || []; + const handoffs = frontmatter?.handoffs || []; + + // Track unique values + if (model) allModels.add(model); + tools.forEach((t) => allTools.add(t)); + + agents.push({ + id: file.replace(".agent.md", ""), + title: extractTitle(filePath, frontmatter), + description: frontmatter?.description || "", + model: model, + tools: tools, + hasHandoffs: handoffs.length > 0, + handoffs: handoffs.map((h) => ({ + label: h.label || "", + agent: h.agent || "", + })), + mcpServers: frontmatter?.["mcp-servers"] + ? Object.keys(frontmatter["mcp-servers"]) + : [], + path: relativePath, + filename: file, + }); + } + + // Sort and return with filter metadata + const sortedAgents = agents.sort((a, b) => a.title.localeCompare(b.title)); + + return { + items: sortedAgents, + filters: { + models: ["(none)", ...Array.from(allModels).sort()], + tools: Array.from(allTools).sort(), + }, + }; +} + +/** + * Generate prompts metadata + */ +function generatePromptsData() { + const prompts = []; + const files = fs + .readdirSync(PROMPTS_DIR) + .filter((f) => f.endsWith(".prompt.md")); + + // Track all unique tools for filters + const allTools = new Set(); + + for (const file of files) { + const filePath = path.join(PROMPTS_DIR, file); + const frontmatter = parseFrontmatter(filePath); + const relativePath = path + .relative(ROOT_FOLDER, filePath) + .replace(/\\/g, "/"); + + const tools = frontmatter?.tools || []; + tools.forEach((t) => allTools.add(t)); + + prompts.push({ + id: file.replace(".prompt.md", ""), + title: extractTitle(filePath, frontmatter), + description: frontmatter?.description || "", + agent: frontmatter?.agent || null, + model: frontmatter?.model || null, + tools: tools, + path: relativePath, + filename: file, + }); + } + + const sortedPrompts = prompts.sort((a, b) => a.title.localeCompare(b.title)); + + return { + items: sortedPrompts, + filters: { + tools: Array.from(allTools).sort(), + }, + }; +} + +/** + * Parse applyTo field into an array of patterns + */ +function parseApplyToPatterns(applyTo) { + if (!applyTo) return []; + + // Handle array format + if (Array.isArray(applyTo)) { + return applyTo.map((p) => p.trim()).filter((p) => p.length > 0); + } + + // Handle string format (comma-separated) + if (typeof applyTo === "string") { + return applyTo + .split(",") + .map((p) => p.trim()) + .filter((p) => p.length > 0); + } + + return []; +} + +/** + * Extract file extension from a glob pattern + */ +function extractExtensionFromPattern(pattern) { + // Match patterns like **.ts, **/*.js, *.py, etc. + const match = pattern.match(/\*\.(\w+)$/); + if (match) return `.${match[1]}`; + + // Match patterns like **/*.{ts,tsx} + const braceMatch = pattern.match(/\*\.\{([^}]+)\}$/); + if (braceMatch) { + return braceMatch[1].split(",").map((ext) => `.${ext.trim()}`); + } + + return null; +} + +/** + * Generate instructions metadata + */ +function generateInstructionsData() { + const instructions = []; + const files = fs + .readdirSync(INSTRUCTIONS_DIR) + .filter((f) => f.endsWith(".instructions.md")); + + // Track all unique patterns and extensions for filters + const allPatterns = new Set(); + const allExtensions = new Set(); + + for (const file of files) { + const filePath = path.join(INSTRUCTIONS_DIR, file); + const frontmatter = parseFrontmatter(filePath); + const relativePath = path + .relative(ROOT_FOLDER, filePath) + .replace(/\\/g, "/"); + + const applyToRaw = frontmatter?.applyTo || null; + const applyToPatterns = parseApplyToPatterns(applyToRaw); + + // Extract extensions from patterns + const extensions = []; + for (const pattern of applyToPatterns) { + allPatterns.add(pattern); + const ext = extractExtensionFromPattern(pattern); + if (ext) { + if (Array.isArray(ext)) { + ext.forEach((e) => { + extensions.push(e); + allExtensions.add(e); + }); + } else { + extensions.push(ext); + allExtensions.add(ext); + } + } + } + + instructions.push({ + id: file.replace(".instructions.md", ""), + title: extractTitle(filePath, frontmatter), + description: frontmatter?.description || "", + applyTo: applyToRaw, + applyToPatterns: applyToPatterns, + extensions: [...new Set(extensions)], + path: relativePath, + filename: file, + }); + } + + const sortedInstructions = instructions.sort((a, b) => + a.title.localeCompare(b.title) + ); + + return { + items: sortedInstructions, + filters: { + patterns: Array.from(allPatterns).sort(), + extensions: ["(none)", ...Array.from(allExtensions).sort()], + }, + }; +} + +/** + * Categorize a skill based on its name and description + */ +function categorizeSkill(name, description) { + const text = `${name} ${description}`.toLowerCase(); + + if (text.includes("azure") || text.includes("appinsights")) return "Azure"; + if ( + text.includes("github") || + text.includes("gh-cli") || + text.includes("git-commit") || + text.includes("git ") + ) + return "Git & GitHub"; + if (text.includes("vscode") || text.includes("vs code")) return "VS Code"; + if ( + text.includes("test") || + text.includes("qa") || + text.includes("playwright") + ) + return "Testing"; + if ( + text.includes("microsoft") || + text.includes("m365") || + text.includes("workiq") + ) + return "Microsoft"; + if (text.includes("cli") || text.includes("command")) return "CLI Tools"; + if ( + text.includes("diagram") || + text.includes("plantuml") || + text.includes("visual") + ) + return "Diagrams"; + if ( + text.includes("nuget") || + text.includes("dotnet") || + text.includes(".net") + ) + return ".NET"; + + return "Other"; +} + +/** + * Generate skills metadata + */ +function generateSkillsData() { + const skills = []; + + if (!fs.existsSync(SKILLS_DIR)) { + return { items: [], filters: { categories: [], hasAssets: ["Yes", "No"] } }; + } + + const folders = fs + .readdirSync(SKILLS_DIR) + .filter((f) => fs.statSync(path.join(SKILLS_DIR, f)).isDirectory()); + + const allCategories = new Set(); + + for (const folder of folders) { + const skillPath = path.join(SKILLS_DIR, folder); + const metadata = parseSkillMetadata(skillPath); + + if (metadata) { + const relativePath = path + .relative(ROOT_FOLDER, skillPath) + .replace(/\\/g, "/"); + const category = categorizeSkill(metadata.name, metadata.description); + allCategories.add(category); + + // Get all files in the skill folder recursively + const files = getSkillFiles(skillPath, relativePath); + + skills.push({ + id: folder, + name: metadata.name, + title: metadata.name + .split("-") + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "), + description: metadata.description, + assets: metadata.assets, + hasAssets: metadata.assets.length > 0, + assetCount: metadata.assets.length, + category: category, + path: relativePath, + skillFile: `${relativePath}/SKILL.md`, + files: files, + }); + } + } + + const sortedSkills = skills.sort((a, b) => a.title.localeCompare(b.title)); + + return { + items: sortedSkills, + filters: { + categories: Array.from(allCategories).sort(), + hasAssets: ["Yes", "No"], + }, + }; +} + +/** + * Get all files in a skill folder recursively + */ +function getSkillFiles(skillPath, relativePath) { + const files = []; + + function walkDir(dir, relDir) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + const relPath = relDir ? `${relDir}/${entry.name}` : entry.name; + + if (entry.isDirectory()) { + walkDir(fullPath, relPath); + } else { + // Get file size + const stats = fs.statSync(fullPath); + files.push({ + path: `${relativePath}/${relPath}`, + name: relPath, + size: stats.size, + }); + } + } + } + + walkDir(skillPath, ""); + return files; +} + +/** + * Generate collections metadata + */ +function generateCollectionsData() { + const collections = []; + + if (!fs.existsSync(COLLECTIONS_DIR)) { + return collections; + } + + const files = fs + .readdirSync(COLLECTIONS_DIR) + .filter((f) => f.endsWith(".collection.yml")); + + // Track all unique tags + const allTags = new Set(); + + for (const file of files) { + const filePath = path.join(COLLECTIONS_DIR, file); + const data = parseCollectionYaml(filePath); + const relativePath = path + .relative(ROOT_FOLDER, filePath) + .replace(/\\/g, "/"); + + if (data) { + const tags = data.tags || []; + tags.forEach((t) => allTags.add(t)); + + // featured can be at top level or nested under display + const featured = data.featured || data.display?.featured || false; + + collections.push({ + id: file.replace(".collection.yml", ""), + name: data.name || file.replace(".collection.yml", ""), + description: data.description || "", + tags: tags, + featured: featured, + items: (data.items || []).map((item) => ({ + path: item.path, + kind: item.kind, + usage: item.usage || null, + })), + path: relativePath, + filename: file, + }); + } + } + + // Sort with featured first, then alphabetically + const sortedCollections = collections.sort((a, b) => { + if (a.featured && !b.featured) return -1; + if (!a.featured && b.featured) return 1; + return a.name.localeCompare(b.name); + }); + + return { + items: sortedCollections, + filters: { + tags: Array.from(allTags).sort(), + }, + }; +} + +/** + * Generate tools metadata from website/data/tools.yml + */ +function generateToolsData() { + const toolsFile = path.join(WEBSITE_SOURCE_DATA_DIR, "tools.yml"); + + if (!fs.existsSync(toolsFile)) { + console.warn("No tools.yml file found at", toolsFile); + return { items: [], filters: { categories: [], tags: [] } }; + } + + const data = parseYamlFile(toolsFile); + + if (!data || !data.tools) { + return { items: [], filters: { categories: [], tags: [] } }; + } + + const allCategories = new Set(); + const allTags = new Set(); + + const tools = data.tools.map((tool) => { + const category = tool.category || "Other"; + allCategories.add(category); + + const tags = tool.tags || []; + tags.forEach((t) => allTags.add(t)); + + return { + id: tool.id, + name: tool.name, + description: tool.description || "", + category: category, + featured: tool.featured || false, + requirements: tool.requirements || [], + features: tool.features || [], + links: tool.links || {}, + configuration: tool.configuration || null, + tags: tags, + }; + }); + + // Sort with featured first, then alphabetically + const sortedTools = tools.sort((a, b) => { + if (a.featured && !b.featured) return -1; + if (!a.featured && b.featured) return 1; + return a.name.localeCompare(b.name); + }); + + return { + items: sortedTools, + filters: { + categories: Array.from(allCategories).sort(), + tags: Array.from(allTags).sort(), + }, + }; +} + +/** + * Generate a combined index for search + */ +function generateSearchIndex( + agents, + prompts, + instructions, + skills, + collections +) { + const index = []; + + for (const agent of agents) { + index.push({ + type: "agent", + id: agent.id, + title: agent.title, + description: agent.description, + path: agent.path, + searchText: `${agent.title} ${agent.description} ${agent.tools.join( + " " + )}`.toLowerCase(), + }); + } + + for (const prompt of prompts) { + index.push({ + type: "prompt", + id: prompt.id, + title: prompt.title, + description: prompt.description, + path: prompt.path, + searchText: `${prompt.title} ${prompt.description}`.toLowerCase(), + }); + } + + for (const instruction of instructions) { + index.push({ + type: "instruction", + id: instruction.id, + title: instruction.title, + description: instruction.description, + path: instruction.path, + searchText: `${instruction.title} ${instruction.description} ${ + instruction.applyTo || "" + }`.toLowerCase(), + }); + } + + for (const skill of skills) { + index.push({ + type: "skill", + id: skill.id, + title: skill.title, + description: skill.description, + path: skill.path, + searchText: `${skill.title} ${skill.description}`.toLowerCase(), + }); + } + + for (const collection of collections) { + index.push({ + type: "collection", + id: collection.id, + title: collection.name, + description: collection.description, + path: collection.path, + tags: collection.tags, + searchText: `${collection.name} ${ + collection.description + } ${collection.tags.join(" ")}`.toLowerCase(), + }); + } + + return index; +} + +/** + * Generate samples/cookbook data from cookbook.yml + */ +function generateSamplesData() { + const cookbookYamlPath = path.join(COOKBOOK_DIR, "cookbook.yml"); + + if (!fs.existsSync(cookbookYamlPath)) { + console.warn( + "Warning: cookbook/cookbook.yml not found, skipping samples generation" + ); + return { + cookbooks: [], + totalRecipes: 0, + totalCookbooks: 0, + filters: { languages: [], tags: [] }, + }; + } + + const cookbookManifest = parseYamlFile(cookbookYamlPath); + if (!cookbookManifest || !cookbookManifest.cookbooks) { + console.warn("Warning: Invalid cookbook.yml format"); + return { + cookbooks: [], + totalRecipes: 0, + totalCookbooks: 0, + filters: { languages: [], tags: [] }, + }; + } + + const allLanguages = new Set(); + const allTags = new Set(); + let totalRecipes = 0; + + const cookbooks = cookbookManifest.cookbooks.map((cookbook) => { + // Collect languages + cookbook.languages.forEach((lang) => allLanguages.add(lang.id)); + + // Process recipes and add file paths + const recipes = cookbook.recipes.map((recipe) => { + // Collect tags + if (recipe.tags) { + recipe.tags.forEach((tag) => allTags.add(tag)); + } + + // Build variants with file paths for each language + const variants = {}; + cookbook.languages.forEach((lang) => { + const docPath = `${cookbook.path}/${lang.id}/${recipe.id}.md`; + const examplePath = `${cookbook.path}/${lang.id}/recipe/${recipe.id}${lang.extension}`; + + // Check if files exist + const docFullPath = path.join(ROOT_FOLDER, docPath); + const exampleFullPath = path.join(ROOT_FOLDER, examplePath); + + if (fs.existsSync(docFullPath)) { + variants[lang.id] = { + doc: docPath, + example: fs.existsSync(exampleFullPath) ? examplePath : null, + }; + } + }); + + totalRecipes++; + + return { + id: recipe.id, + name: recipe.name, + description: recipe.description, + tags: recipe.tags || [], + variants, + }; + }); + + return { + id: cookbook.id, + name: cookbook.name, + description: cookbook.description, + path: cookbook.path, + featured: cookbook.featured || false, + languages: cookbook.languages, + recipes, + }; + }); + + return { + cookbooks, + totalRecipes, + totalCookbooks: cookbooks.length, + filters: { + languages: Array.from(allLanguages).sort(), + tags: Array.from(allTags).sort(), + }, + }; +} + +/** + * Main function + */ +async function main() { + console.log("Generating website data...\n"); + + ensureDataDir(); + + // Generate all data + const agentsData = generateAgentsData(); + const agents = agentsData.items; + console.log( + `✓ Generated ${agents.length} agents (${agentsData.filters.models.length} models, ${agentsData.filters.tools.length} tools)` + ); + + const promptsData = generatePromptsData(); + const prompts = promptsData.items; + console.log( + `✓ Generated ${prompts.length} prompts (${promptsData.filters.tools.length} tools)` + ); + + const instructionsData = generateInstructionsData(); + const instructions = instructionsData.items; + console.log( + `✓ Generated ${instructions.length} instructions (${instructionsData.filters.extensions.length} extensions)` + ); + + const skillsData = generateSkillsData(); + const skills = skillsData.items; + console.log( + `✓ Generated ${skills.length} skills (${skillsData.filters.categories.length} categories)` + ); + + const collectionsData = generateCollectionsData(); + const collections = collectionsData.items; + console.log( + `✓ Generated ${collections.length} collections (${collectionsData.filters.tags.length} tags)` + ); + + const toolsData = generateToolsData(); + const tools = toolsData.items; + console.log( + `✓ Generated ${tools.length} tools (${toolsData.filters.categories.length} categories)` + ); + + const samplesData = generateSamplesData(); + console.log( + `✓ Generated ${samplesData.totalRecipes} recipes in ${samplesData.totalCookbooks} cookbooks (${samplesData.filters.languages.length} languages, ${samplesData.filters.tags.length} tags)` + ); + + const searchIndex = generateSearchIndex( + agents, + prompts, + instructions, + skills, + collections + ); + console.log(`✓ Generated search index with ${searchIndex.length} items`); + + // Write JSON files + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "agents.json"), + JSON.stringify(agentsData, null, 2) + ); + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "prompts.json"), + JSON.stringify(promptsData, null, 2) + ); + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "instructions.json"), + JSON.stringify(instructionsData, null, 2) + ); + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "skills.json"), + JSON.stringify(skillsData, null, 2) + ); + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "collections.json"), + JSON.stringify(collectionsData, null, 2) + ); + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "tools.json"), + JSON.stringify(toolsData, null, 2) + ); + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "samples.json"), + JSON.stringify(samplesData, null, 2) + ); + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "search-index.json"), + JSON.stringify(searchIndex, null, 2) + ); + + // Generate a manifest with counts and timestamps + const manifest = { + generated: new Date().toISOString(), + counts: { + agents: agents.length, + prompts: prompts.length, + instructions: instructions.length, + skills: skills.length, + collections: collections.length, + tools: tools.length, + samples: samplesData.totalRecipes, + total: searchIndex.length, + }, + }; + + fs.writeFileSync( + path.join(WEBSITE_DATA_DIR, "manifest.json"), + JSON.stringify(manifest, null, 2) + ); + + console.log(`\n✓ All data written to website/public/data/`); +} + +main().catch((err) => { + console.error("Error generating website data:", err); + process.exit(1); +}); diff --git a/eng/yaml-parser.mjs b/eng/yaml-parser.mjs index 671fbc81..822a8067 100644 --- a/eng/yaml-parser.mjs +++ b/eng/yaml-parser.mjs @@ -195,6 +195,22 @@ function parseSkillMetadata(skillPath) { ); } +/** + * Parse a generic YAML file (used for tools.yml and other config files) + * @param {string} filePath - Path to the YAML file + * @returns {object|null} Parsed YAML object or null on error + */ +function parseYamlFile(filePath) { + return safeFileOperation( + () => { + const content = fs.readFileSync(filePath, "utf8"); + return yaml.load(content, { schema: yaml.JSON_SCHEMA }); + }, + filePath, + null + ); +} + export { parseCollectionYaml, parseFrontmatter, @@ -202,5 +218,6 @@ export { extractMcpServers, extractMcpServerConfigs, parseSkillMetadata, + parseYamlFile, safeFileOperation, }; diff --git a/package.json b/package.json index 16c99fa6..5a392bb4 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,11 @@ "collection:validate": "node ./eng/validate-collections.mjs", "collection:create": "node ./eng/create-collection.mjs", "skill:validate": "node ./eng/validate-skills.mjs", - "skill:create": "node ./eng/create-skill.mjs" + "skill:create": "node ./eng/create-skill.mjs", + "website:data": "node ./eng/generate-website-data.mjs", + "website:dev": "npm run website:data && npm run --prefix website dev", + "website:build": "npm run build && npm run website:data && npm run --prefix website build", + "website:preview": "npm run --prefix website preview" }, "repository": { "type": "git", diff --git a/website/astro.config.mjs b/website/astro.config.mjs new file mode 100644 index 00000000..87c9e4e6 --- /dev/null +++ b/website/astro.config.mjs @@ -0,0 +1,22 @@ +import sitemap from "@astrojs/sitemap"; +import { defineConfig } from "astro/config"; + +// https://astro.build/config +export default defineConfig({ + site: "https://github.github.io/awesome-copilot", + base: "/awesome-copilot/", + output: "static", + integrations: [sitemap()], + build: { + assets: "assets", + }, + trailingSlash: "always", + vite: { + build: { + sourcemap: true, + }, + css: { + devSourcemap: true, + }, + }, +}); diff --git a/website/data/tools.yml b/website/data/tools.yml new file mode 100644 index 00000000..f7c8148f --- /dev/null +++ b/website/data/tools.yml @@ -0,0 +1,205 @@ +# yaml-language-server: $schema=../../.schemas/tools.schema.json +# Tools data for the Awesome GitHub Copilot website +# Each tool entry provides information for the tools page + +tools: + - id: mcp-server + name: Awesome Copilot MCP Server + description: >- + A Model Context Protocol (MCP) Server that provides prompts for searching and installing + prompts, instructions, agents, and skills directly from this repository. Makes it easy + to discover and add customizations to your editor. + category: MCP Servers + featured: true + requirements: + - Docker installed and running + links: + blog: https://developer.microsoft.com/blog/announcing-awesome-copilot-mcp-server + vscode: https://aka.ms/awesome-copilot/mcp/vscode + vscode-insiders: https://aka.ms/awesome-copilot/mcp/vscode-insiders + visual-studio: https://aka.ms/awesome-copilot/mcp/vs + configuration: + type: json + content: | + { + "servers": { + "awesome-copilot": { + "type": "stdio", + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "ghcr.io/microsoft/mcp-dotnet-samples/awesome-copilot:latest" + ] + } + } + } + tags: + - mcp + - docker + - search + - install + + - id: vscode-extension + name: Awesome GitHub Copilot Browser + description: >- + A VS Code extension that allows you to browse, preview, and download GitHub Copilot + customizations from the awesome-copilot repository. Features a tree view for exploring + agents, prompts, instructions, and skills with smart caching for better performance. + category: VS Code Extensions + featured: true + requirements: + - VS Code version 1.103.0 or higher + - Internet connection to fetch repository data + - A workspace folder open in VS Code (for downloads) + links: + github: https://github.com/timheuer/vscode-awesome-copilot + vscode: vscode:extension/TimHeuer.awesome-copilot + vscode-insiders: vscode-insiders:extension/TimHeuer.awesome-copilot + marketplace: https://marketplace.visualstudio.com/items?itemName=TimHeuer.awesome-copilot + features: + - "🔍 Browse: Explore chat modes, instructions, prompts, agents, and skills in a tree view" + - "📖 Preview: View file content before downloading" + - "⬇️ Download: Save files to appropriate .github/ folders in your workspace" + - "🔃 Refresh: Update repository data with manual refresh" + - "💾 Caching: Smart caching for better performance" + tags: + - vscode + - extension + - browse + - preview + - download + + - id: workspace-architect + name: Workspace Architect + description: >- + A comprehensive library of specialized AI personas and chat modes for GitHub Copilot. + Includes architectural planning, tech stack guidance, and advanced cognitive reasoning + models. Install via npm and use the CLI to download personas and prompts. + category: CLI Tools + featured: false + requirements: + - Node.js 20 or higher + - npm + links: + github: https://github.com/archubbuck/workspace-architect + npm: https://www.npmjs.com/package/workspace-architect + features: + - "📦 CLI tool: List and download personas, prompts, and chat modes" + - "🎭 Rich persona library: Architecture, React, Azure, and more" + - "🧠 Cognitive modes: Advanced reasoning and planning personas" + - "⚡ Easy install: npm install -g workspace-architect" + configuration: + type: bash + content: | + # Install globally + npm install -g workspace-architect + + # List available items + workspace-architect list + + # Download a specific item + workspace-architect download instructions:basic-setup + tags: + - cli + - npm + - personas + - chat-modes + - prompts + + - id: apm + name: APM - Agent Package Manager + description: >- + npm for AI coding agents. The package manager for AGENTS.md, Agent Skills, and MCP servers. + One package installs to every AI agent (Copilot, Cursor, Claude, Codex, Gemini) in their + native format. + category: CLI Tools + featured: true + requirements: + - Python 3.8 or higher (for pip install) + - Or use the shell installer + links: + github: https://github.com/danielmeppiel/apm + pypi: https://pypi.org/project/apm-cli/ + features: + - "📦 Universal packages: One install works for Copilot, Cursor, Claude, and more" + - "🔧 Skills & Instructions: Install guardrails and capabilities" + - "🔌 MCP Server management: Configure and manage MCP servers" + - "🏗️ Create packages: Share your standards and workflows" + - "🌐 Multi-source: GitHub, GitHub Enterprise, Azure DevOps" + configuration: + type: bash + content: | + # Install via shell script + curl -sSL https://raw.githubusercontent.com/danielmeppiel/apm/main/install.sh | sh + + # Or install via pip + pip install apm-cli + + # Install a skill + apm install danielmeppiel/form-builder + + # Compile for your AI tools + apm compile + tags: + - cli + - python + - package-manager + - skills + - agents + - mcp + + - id: prompt-registry + name: Prompt Registry + description: >- + A visual marketplace for discovering, installing, and managing GitHub Copilot prompt + libraries from multiple sources. Browse bundles in a tile-based interface with search, + filters, and one-click install. Supports GitHub, local directories, and APM repositories. + category: VS Code Extensions + featured: false + requirements: + - VS Code + links: + github: https://github.com/AmadeusITGroup/prompt-registry + vscode: vscode:extension/AmadeusITGroup.prompt-registry + vscode-insiders: vscode-insiders:extension/AmadeusITGroup.prompt-registry + marketplace: https://marketplace.visualstudio.com/items?itemName=AmadeusITGroup.prompt-registry + features: + - "🎨 Visual Marketplace: Browse bundles with search, filters, and one-click install" + - "🔌 Multi-Source: Connect to GitHub, local directories, APM, or Awesome Copilot" + - "📦 Version Management: Track versions and enable automatic updates" + - "👥 Profiles & Hubs: Organize bundles by project/team" + - "🌍 Cross-Platform: Works on macOS, Linux, and Windows" + tags: + - vscode + - extension + - marketplace + - prompts + - bundles + + - id: github-node-vs + name: GitHub Node for Visual Studio + description: >- + Adds GitHub and MCP Servers nodes to Solution Explorer in Visual Studio. Quickly access + and manage GitHub-specific files like workflows, Copilot instructions, and agents, plus + MCP server configurations - all without leaving Visual Studio. + category: Visual Studio Extensions + featured: false + requirements: + - Visual Studio 2022 or higher + links: + github: https://github.com/madskristensen/GitHubNode + marketplace: https://marketplace.visualstudio.com/items?itemName=MadsKristensen.GitHubNode + features: + - "📁 GitHub Node: Easy access to .github folder contents in Solution Explorer" + - "➕ Quick Create: Add Copilot instructions, agents, prompts, skills, and workflows" + - "🔌 MCP Servers Node: Centralized access to MCP configurations" + - "🔄 Git Status Icons: See file status directly in the tree view" + - "🌐 Open on GitHub: Quick link to view files on GitHub.com" + tags: + - visual-studio + - extension + - solution-explorer + - github + - mcp diff --git a/website/package-lock.json b/website/package-lock.json new file mode 100644 index 00000000..4aac1dd9 --- /dev/null +++ b/website/package-lock.json @@ -0,0 +1,5191 @@ +{ + "name": "awesome-copilot-website", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "awesome-copilot-website", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@astrojs/sitemap": "^3.7.0", + "astro": "^5.16.15", + "choices.js": "^11.1.0", + "jszip": "^3.10.1" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", + "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.5.tgz", + "integrity": "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==", + "license": "MIT" + }, + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.10", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.10.tgz", + "integrity": "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.19.0", + "smol-toml": "^1.5.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/sitemap": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", + "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", + "license": "MIT", + "dependencies": { + "sitemap": "^8.0.2", + "stream-replace-string": "^2.0.0", + "zod": "^3.25.76" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", + "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.0.tgz", + "integrity": "sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.0.tgz", + "integrity": "sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.0.tgz", + "integrity": "sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.0.tgz", + "integrity": "sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.0.tgz", + "integrity": "sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.0.tgz", + "integrity": "sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.0.tgz", + "integrity": "sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.0.tgz", + "integrity": "sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.0.tgz", + "integrity": "sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.0.tgz", + "integrity": "sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.0.tgz", + "integrity": "sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.0.tgz", + "integrity": "sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.0.tgz", + "integrity": "sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.0.tgz", + "integrity": "sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.0.tgz", + "integrity": "sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.0.tgz", + "integrity": "sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.0.tgz", + "integrity": "sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.0.tgz", + "integrity": "sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.0.tgz", + "integrity": "sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.0.tgz", + "integrity": "sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.0.tgz", + "integrity": "sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.0.tgz", + "integrity": "sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.0.tgz", + "integrity": "sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.0.tgz", + "integrity": "sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.0.tgz", + "integrity": "sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.21.0.tgz", + "integrity": "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.21.0.tgz", + "integrity": "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.21.0.tgz", + "integrity": "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.21.0.tgz", + "integrity": "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.21.0.tgz", + "integrity": "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.21.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz", + "integrity": "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/node": { + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astro": { + "version": "5.16.15", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.16.15.tgz", + "integrity": "sha512-+X1Z0NTi2pa5a0Te6h77Dgc44fYj63j1yx6+39Nvg05lExajxSq7b1Uj/gtY45zoum8fD0+h0nak+DnHighs3A==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/markdown-remark": "6.3.10", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^4.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.1.1", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.6.2", + "diff": "^8.0.3", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.25.0", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.4.0", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "svgo": "^4.0.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.3", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.4", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/choices.js": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/choices.js/-/choices.js-11.1.0.tgz", + "integrity": "sha512-mIt0uLhedHg2ea/K2PACrVpt391vRGHuOoctPAiHcyemezwzNMxj7jOzNEk8e7EbjLh0S0sspDkSCADOKz9kcw==", + "license": "MIT", + "dependencies": { + "fuse.js": "^7.0.0" + } + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", + "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.0.tgz", + "integrity": "sha512-moThBCItUe2bjZip5PF/iZClpKHGLwMvR79Kp8XpGRBrvoRSnySN4VcILdv3/MJzbhvUA5WeiUXF5o538m5fvg==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + } + }, + "node_modules/fontkitten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.2.tgz", + "integrity": "sha512-piJxbLnkD9Xcyi7dWJRnqszEURixe7CrF/efBfbffe2DPyabmuIuqraruY8cXTs19QoM8VJzx47BDRVNXETM7Q==", + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fuse.js": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz", + "integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/h3": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.5.tgz", + "integrity": "sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", + "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", + "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", + "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rollup": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.0.tgz", + "integrity": "sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.57.0", + "@rollup/rollup-android-arm64": "4.57.0", + "@rollup/rollup-darwin-arm64": "4.57.0", + "@rollup/rollup-darwin-x64": "4.57.0", + "@rollup/rollup-freebsd-arm64": "4.57.0", + "@rollup/rollup-freebsd-x64": "4.57.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", + "@rollup/rollup-linux-arm-musleabihf": "4.57.0", + "@rollup/rollup-linux-arm64-gnu": "4.57.0", + "@rollup/rollup-linux-arm64-musl": "4.57.0", + "@rollup/rollup-linux-loong64-gnu": "4.57.0", + "@rollup/rollup-linux-loong64-musl": "4.57.0", + "@rollup/rollup-linux-ppc64-gnu": "4.57.0", + "@rollup/rollup-linux-ppc64-musl": "4.57.0", + "@rollup/rollup-linux-riscv64-gnu": "4.57.0", + "@rollup/rollup-linux-riscv64-musl": "4.57.0", + "@rollup/rollup-linux-s390x-gnu": "4.57.0", + "@rollup/rollup-linux-x64-gnu": "4.57.0", + "@rollup/rollup-linux-x64-musl": "4.57.0", + "@rollup/rollup-openbsd-x64": "4.57.0", + "@rollup/rollup-openharmony-arm64": "4.57.0", + "@rollup/rollup-win32-arm64-msvc": "4.57.0", + "@rollup/rollup-win32-ia32-msvc": "4.57.0", + "@rollup/rollup-win32-x64-gnu": "4.57.0", + "@rollup/rollup-win32-x64-msvc": "4.57.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shiki": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.21.0.tgz", + "integrity": "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.21.0", + "@shikijs/engine-javascript": "3.21.0", + "@shikijs/engine-oniguruma": "3.21.0", + "@shikijs/langs": "3.21.0", + "@shikijs/themes": "3.21.0", + "@shikijs/types": "3.21.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.2.tgz", + "integrity": "sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.4.1" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/smol-toml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz", + "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stream-replace-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz", + "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==", + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/svgo": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", + "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.4.1" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unifont": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.3.tgz", + "integrity": "sha512-b0GtQzKCyuSHGsfj5vyN8st7muZ6VCI4XD4vFlr7Uy1rlWVYxC3npnfk8MyreHxJYrz1ooLDqDzFe9XqQTlAhA==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ofetch": "^1.5.1", + "ohash": "^2.0.11" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.4.tgz", + "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.5", + "lru-cache": "^11.2.0", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-spinner": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", + "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 00000000..8cc55295 --- /dev/null +++ b/website/package.json @@ -0,0 +1,26 @@ +{ + "name": "awesome-copilot-website", + "version": "1.0.0", + "description": "Awesome GitHub Copilot website", + "type": "module", + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "keywords": [ + "github", + "copilot", + "agents", + "prompts" + ], + "author": "GitHub", + "license": "MIT", + "dependencies": { + "@astrojs/sitemap": "^3.7.0", + "astro": "^5.16.15", + "choices.js": "^11.1.0", + "jszip": "^3.10.1" + } +} diff --git a/website/public/fonts/MonaspaceArgonNF-Regular.woff2 b/website/public/fonts/MonaspaceArgonNF-Regular.woff2 new file mode 100755 index 00000000..1a3e12e5 Binary files /dev/null and b/website/public/fonts/MonaspaceArgonNF-Regular.woff2 differ diff --git a/website/public/images/Copilot_Icon_Black.svg b/website/public/images/Copilot_Icon_Black.svg new file mode 100755 index 00000000..300c0caa --- /dev/null +++ b/website/public/images/Copilot_Icon_Black.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/website/public/images/Copilot_Icon_White.svg b/website/public/images/Copilot_Icon_White.svg new file mode 100755 index 00000000..0411bb16 --- /dev/null +++ b/website/public/images/Copilot_Icon_White.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/website/public/styles/global.css b/website/public/styles/global.css new file mode 100644 index 00000000..81f598c7 --- /dev/null +++ b/website/public/styles/global.css @@ -0,0 +1,1576 @@ +/* CSS Variables and Base Styles */ +/* GitHub Copilot Brand Colors: + Purple 1: #C898FD Purple 2: #B870FF Purple 3: #8534F3 (Primary) + Purple 4: #43179E Purple 5: #26115F Purple 6: #160048 + Orange 1: #F4A876 Orange 2: #F08A3A Orange 3: #FE4C25 + Orange 4: #C53211 Orange 5: #801E0F Orange 6: #500A00 +*/ + +/* Nerd Fonts for programming language icons */ +@font-face { + font-family: 'Monaspace Argon NF'; + src: url('/fonts/MonaspaceArgonNF-Regular.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +:root { + /* Dark theme (default) */ + --color-bg: #0d0d12; + --color-bg-secondary: #14141c; + --color-bg-tertiary: #1c1c28; + --color-border: #2d2d3d; + --color-text: #e4e4ec; + --color-text-muted: #9090a8; + --color-text-emphasis: #ffffff; + --color-text-primary: var(--color-text); + --color-text-secondary: var(--color-text-muted); + --color-bg-primary: var(--color-bg); + --color-primary: var(--color-accent); + --color-purple-light: #C898FD; + --color-purple-dark: #43179E; + --color-link: #B870FF; + --color-link-hover: #C898FD; + --color-accent: #8534F3; + --color-accent-hover: #B870FF; + --color-accent-secondary: #FE4C25; + --color-danger: #C53211; + --color-warning: #F08A3A; + --color-success: #10b981; + --color-error: #C53211; + --color-card-bg: rgba(20, 20, 28, 0.8); + --color-card-hover: rgba(28, 28, 40, 0.9); + --color-glass: rgba(255, 255, 255, 0.05); + --color-glass-border: rgba(255, 255, 255, 0.1); + --gradient-primary: linear-gradient(180deg, #8534F3 0%, #B870FF 50%, #FE4C25 100%); + --gradient-accent: linear-gradient(135deg, #43179E 0%, #8534F3 100%); + --gradient-hero: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(133, 52, 243, 0.25), transparent), + radial-gradient(ellipse 60% 40% at 80% 50%, rgba(254, 76, 37, 0.12), transparent), + radial-gradient(ellipse 60% 40% at 20% 50%, rgba(184, 112, 255, 0.12), transparent); + --border-radius: 8px; + --border-radius-lg: 16px; + --border-radius-xl: 24px; + --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.2), 0 2px 4px -2px rgba(0, 0, 0, 0.2); + --shadow-md: 0 12px 24px -10px rgba(0, 0, 0, 0.4); + --shadow-lg: 0 20px 40px -12px rgba(0, 0, 0, 0.5); + --shadow-glow: 0 0 40px -10px rgba(133, 52, 243, 0.5); + --transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1); + --transition-slow: 0.4s cubic-bezier(0.4, 0, 0.2, 1); + --container-width: 1200px; + --header-height: 72px; + --font-mono: 'Monaspace Argon NF', 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; +} + +/* Light theme */ +[data-theme="light"] { + --color-bg: #fafafa; + --color-bg-secondary: #ffffff; + --color-bg-tertiary: #f5f5f7; + --color-border: #e4e4e7; + --color-text: #3f3f46; + --color-text-muted: #71717a; + --color-text-emphasis: #18181b; + --color-link: #8534F3; + --color-link-hover: #43179E; + --color-card-bg: rgba(255, 255, 255, 0.9); + --color-card-hover: rgba(255, 255, 255, 1); + --color-glass: rgba(255, 255, 255, 0.7); + --color-glass-border: rgba(0, 0, 0, 0.08); + --gradient-hero: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(133, 52, 243, 0.12), transparent), + radial-gradient(ellipse 60% 40% at 80% 50%, rgba(254, 76, 37, 0.06), transparent), + radial-gradient(ellipse 60% 40% at 20% 50%, rgba(184, 112, 255, 0.06), transparent); + --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 20px 40px -12px rgba(0, 0, 0, 0.15); + --shadow-glow: 0 0 40px -10px rgba(133, 52, 243, 0.3); +} + +/* Auto theme based on system preference */ +@media (prefers-color-scheme: light) { + :root:not([data-theme="dark"]) { + --color-bg: #fafafa; + --color-bg-secondary: #ffffff; + --color-bg-tertiary: #f5f5f7; + --color-border: #e4e4e7; + --color-text: #3f3f46; + --color-text-muted: #71717a; + --color-text-emphasis: #18181b; + --color-link: #8534F3; + --color-link-hover: #43179E; + --color-card-bg: rgba(255, 255, 255, 0.9); + --color-card-hover: rgba(255, 255, 255, 1); + --color-glass: rgba(255, 255, 255, 0.7); + --color-glass-border: rgba(0, 0, 0, 0.08); + --gradient-hero: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(133, 52, 243, 0.12), transparent), + radial-gradient(ellipse 60% 40% at 80% 50%, rgba(254, 76, 37, 0.06), transparent), + radial-gradient(ellipse 60% 40% at 20% 50%, rgba(184, 112, 255, 0.06), transparent); + --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 20px 40px -12px rgba(0, 0, 0, 0.15); + --shadow-glow: 0 0 40px -10px rgba(133, 52, 243, 0.3); + } +} + +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif; + background-color: var(--color-bg); + color: var(--color-text); + line-height: 1.6; + min-height: 100vh; +} + +/* Accessibility Utilities */ +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +.skip-link { + position: absolute; + top: -100%; + left: 50%; + transform: translateX(-50%); + background: var(--color-accent); + color: var(--color-text-emphasis); + padding: 12px 24px; + border-radius: var(--border-radius); + font-weight: 600; + z-index: 10000; + transition: top var(--transition); +} + +.skip-link:focus { + top: 12px; + outline: 2px solid var(--color-text-emphasis); + outline-offset: 2px; +} + +.container { + max-width: var(--container-width); + margin: 0 auto; + padding: 0 24px; +} + +a { + color: var(--color-link); + text-decoration: none; + transition: color var(--transition); +} + +a:hover { + color: var(--color-link-hover); +} + +/* Header */ +.site-header { + background: var(--color-glass); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border-bottom: 1px solid var(--color-glass-border); + position: sticky; + top: 0; + z-index: 100; + height: var(--header-height); +} + +.header-content { + display: flex; + align-items: center; + justify-content: space-between; + height: var(--header-height); +} + +.logo { + display: flex; + align-items: center; + gap: 10px; + font-weight: 700; + font-size: 20px; + color: var(--color-text-emphasis); + transition: all var(--transition); +} + +.logo:hover { + color: var(--color-text-emphasis); + transform: scale(1.02); +} + +.logo-icon { + width: 32px; + height: 32px; +} + +/* Show white logo by default (dark theme) */ +.logo-icon-light { + display: none; +} + +.logo-icon-dark { + display: block; +} + +/* Light theme: show black logo */ +[data-theme="light"] .logo-icon-light { + display: block; +} + +[data-theme="light"] .logo-icon-dark { + display: none; +} + +/* Auto theme based on system preference */ +@media (prefers-color-scheme: light) { + :root:not([data-theme="dark"]) .logo-icon-light { + display: block; + } + + :root:not([data-theme="dark"]) .logo-icon-dark { + display: none; + } +} + +.main-nav { + display: flex; + gap: 8px; +} + +.main-nav a { + color: var(--color-text-muted); + font-size: 14px; + font-weight: 500; + padding: 8px 14px; + border-radius: var(--border-radius); + transition: all var(--transition); +} + +.main-nav a:hover, +.main-nav a.active { + color: var(--color-text-emphasis); + background: var(--color-bg-tertiary); +} + +.github-link { + color: var(--color-text); + display: flex; + align-items: center; +} + +.github-link:hover { + color: var(--color-text-emphasis); +} + +/* Theme Toggle */ +.header-actions { + display: flex; + align-items: center; + gap: 16px; +} + +.theme-toggle { + background: none; + border: none; + cursor: pointer; + padding: 8px; + border-radius: var(--border-radius); + color: var(--color-text); + display: flex; + align-items: center; + justify-content: center; + transition: all var(--transition); +} + +.theme-toggle:hover { + background-color: var(--color-bg-tertiary); + color: var(--color-text-emphasis); +} + +.theme-toggle svg { + width: 20px; + height: 20px; +} + +.theme-toggle .icon-sun, +.theme-toggle .icon-moon { + display: none; +} + +/* Show sun icon in dark mode (click to switch to light) */ +:root:not([data-theme="light"]) .theme-toggle .icon-sun { + display: block; +} + +:root:not([data-theme="light"]) .theme-toggle .icon-moon { + display: none; +} + +/* Show moon icon in light mode (click to switch to dark) */ +[data-theme="light"] .theme-toggle .icon-sun { + display: none; +} + +[data-theme="light"] .theme-toggle .icon-moon { + display: block; +} + +/* Handle auto mode with prefers-color-scheme */ +@media (prefers-color-scheme: light) { + :root:not([data-theme="dark"]):not([data-theme="light"]) .theme-toggle .icon-sun { + display: none; + } + :root:not([data-theme="dark"]):not([data-theme="light"]) .theme-toggle .icon-moon { + display: block; + } +} + +/* Hero Section */ +.hero { + background: var(--gradient-hero), var(--color-bg); + padding: 50px 0 20px; + text-align: center; + position: relative; +} + +.hero::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%239C92AC' fill-opacity='0.03'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); + pointer-events: none; +} + +.hero h1 { + font-size: 56px; + font-weight: 800; + letter-spacing: -0.02em; + background: var(--gradient-primary); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 20px; + position: relative; +} + +.hero-subtitle { + font-size: 20px; + color: var(--color-text-muted); + max-width: 650px; + margin: 0 auto 40px; + line-height: 1.7; +} + +.hero-search { + max-width: 560px; + margin: 0 auto; + position: relative; + z-index: 100; +} + +.hero-search input { + width: 100%; + padding: 18px 24px; + font-size: 16px; + background: var(--color-glass); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius-xl); + color: var(--color-text); + transition: all var(--transition); + box-shadow: var(--shadow); +} + +.hero-search input:focus { + outline: 2px solid var(--color-accent); + outline-offset: 2px; + border-color: var(--color-accent); + box-shadow: var(--shadow-glow); +} + +.hero-search input::placeholder { + color: var(--color-text-muted); +} + +/* Search Results Dropdown */ +.search-results { + position: absolute; + top: 100%; + left: 0; + right: 0; + background: var(--color-bg-secondary); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius-lg); + margin-top: 12px; + max-height: 450px; + overflow-y: auto; + box-shadow: var(--shadow-lg); + z-index: 1000; +} + +.search-results.hidden { + display: none; +} + +.search-result, +.search-result-item { + display: flex; + align-items: flex-start; + gap: 14px; + padding: 14px 18px; + cursor: pointer; + border-bottom: 1px solid var(--color-glass-border); + transition: all var(--transition); + text-align: left; +} + +.search-result:last-child, +.search-result-item:last-child { + border-bottom: none; +} + +.search-result:hover, +.search-result-item:hover { + background: var(--color-bg-tertiary); +} + +.search-result-type { + font-size: 20px; + flex-shrink: 0; + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + background: var(--color-bg-tertiary); + border-radius: var(--border-radius); +} + +.search-result-title { + font-weight: 600; + font-size: 15px; + color: var(--color-text-emphasis); + margin-bottom: 4px; +} + +.search-result-title mark { + background: linear-gradient(135deg, rgba(99, 102, 241, 0.3), rgba(236, 72, 153, 0.3)); + color: inherit; + padding: 0 2px; + border-radius: 2px; +} + +.search-result-description { + font-size: 13px; + color: var(--color-text-muted); + line-height: 1.5; +} + +.search-result-empty { + padding: 20px; + text-align: center; + color: var(--color-text-muted); + font-size: 14px; +} + +/* Cards Grid */ +.cards-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 24px; +} + +.card { + background: var(--color-card-bg); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius-lg); + padding: 28px; + transition: all var(--transition); + display: block; + color: inherit; + position: relative; + overflow: hidden; +} + +.card-with-count { + display: flex; + align-items: flex-start; + gap: 16px; +} + +.card-with-count .card-icon { + flex-shrink: 0; + margin-bottom: 0; +} + +.card-with-count .card-content { + flex: 1; + min-width: 0; +} + +.card-with-count h3 { + margin-bottom: 6px; +} + +.card-count { + flex-shrink: 0; + font-size: 28px; + font-weight: 700; + background: var(--gradient-primary); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + line-height: 1; + min-width: 40px; + text-align: right; +} + +.card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: var(--gradient-primary); + opacity: 0; + transition: opacity var(--transition); +} + +.card:hover { + background: var(--color-card-hover); + border-color: transparent; + transform: translateY(-4px); + box-shadow: var(--shadow-lg), var(--shadow-glow); +} + +.card:hover::before { + opacity: 1; +} + +.card-icon { + font-size: 40px; + margin-bottom: 16px; + display: inline-block; + transition: transform var(--transition); +} + +.card:hover .card-icon { + transform: scale(1.1); +} + +.card h3 { + font-size: 20px; + font-weight: 700; + color: var(--color-text-emphasis); + margin-bottom: 10px; +} + +.card p { + font-size: 15px; + color: var(--color-text-muted); + line-height: 1.6; +} + +/* Quick Links Section */ +.quick-links { + padding: 80px 0; +} + +/* Featured Section */ +.featured { + padding: 80px 0; + background: var(--color-bg-secondary); + position: relative; +} + +.featured h2 { + font-size: 32px; + font-weight: 800; + color: var(--color-text-emphasis); + margin-bottom: 40px; + text-align: center; +} + +/* Getting Started */ +.getting-started { + padding: 100px 0; + background: var(--gradient-hero), var(--color-bg); +} + +.getting-started h2 { + font-size: 32px; + font-weight: 800; + color: var(--color-text-emphasis); + margin-bottom: 48px; + text-align: center; +} + +.steps { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 48px; + max-width: 900px; + margin: 0 auto; +} + +.step { + text-align: center; + position: relative; +} + +.step-number { + width: 64px; + height: 64px; + background: var(--gradient-primary); + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 24px; + font-weight: 800; + margin: 0 auto 20px; + box-shadow: var(--shadow-glow); +} + +.step h3 { + font-size: 20px; + font-weight: 700; + color: var(--color-text-emphasis); + margin-bottom: 10px; +} + +.step p { + font-size: 15px; + color: var(--color-text-muted); + line-height: 1.6; +} + +/* Footer */ +.site-footer { + background: var(--color-bg-secondary); + border-top: 1px solid var(--color-glass-border); + padding: 32px 0; + text-align: center; +} + +.site-footer p { + font-size: 14px; + color: var(--color-text-muted); +} + +.site-footer a { + color: var(--color-text-muted); + transition: color var(--transition); +} + +.site-footer a:hover { + color: var(--color-accent); +} + +/* Buttons */ +.btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 10px 18px; + font-size: 14px; + font-weight: 500; + border-radius: var(--border-radius); + border: 1px solid transparent; + cursor: pointer; + transition: all var(--transition); + text-decoration: none; +} + +.btn:focus { + outline: 2px solid var(--color-accent); + outline-offset: 2px; +} + +.btn:focus:not(:focus-visible) { + outline: none; +} + +.btn:focus-visible { + outline: 2px solid var(--color-accent); + outline-offset: 2px; +} + +.btn-primary { + background: var(--color-accent); + color: white; + border-color: transparent; + font-weight: 600; +} + +.btn-primary:hover { + background: var(--color-accent-hover); + transform: translateY(-1px); + box-shadow: var(--shadow-glow); + color: white; +} + +.btn-secondary { + background: var(--color-glass); + backdrop-filter: blur(10px); + color: var(--color-text); + border-color: var(--color-glass-border); +} + +.btn-secondary:hover { + background: var(--color-bg-tertiary); + border-color: var(--color-border); +} + +.btn-outline { + background: transparent; + color: var(--color-text); + border-color: var(--color-border); +} + +.btn-outline:hover { + background: var(--color-bg-tertiary); + border-color: var(--color-link); +} + +.btn-icon { + padding: 8px; + background: transparent; + border: none; + color: var(--color-text-muted); +} + +.btn-icon:hover { + color: var(--color-text); +} + +/* Split Button Dropdown */ +.install-dropdown { + position: relative; + display: inline-flex; +} + +.install-dropdown .install-btn-main { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right: 1px solid rgba(255, 255, 255, 0.2); +} + +.install-dropdown .install-btn-toggle { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + padding: 10px 10px; + min-width: auto; +} + +.install-dropdown .install-btn-toggle svg { + transition: transform var(--transition); +} + +.install-dropdown.open .install-btn-toggle svg { + transform: rotate(180deg); +} + +.install-dropdown-menu { + position: absolute; + top: 100%; + right: 0; + margin-top: 4px; + min-width: 160px; + background: var(--color-bg-secondary); + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + box-shadow: var(--shadow-md); + z-index: 1000; + opacity: 0; + visibility: hidden; + transform: translateY(-8px); + transition: all var(--transition); +} + +.install-dropdown.open .install-dropdown-menu { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.install-dropdown-menu a { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 14px; + color: var(--color-text); + text-decoration: none; + font-size: 14px; + transition: background var(--transition); +} + +.install-dropdown-menu a:first-child { + border-radius: var(--border-radius) var(--border-radius) 0 0; +} + +.install-dropdown-menu a:last-child { + border-radius: 0 0 var(--border-radius) var(--border-radius); +} + +.install-dropdown-menu a:hover { + background: var(--color-bg-tertiary); +} + +.install-dropdown-menu svg { + width: 16px; + height: 16px; + flex-shrink: 0; +} + +/* Small variant for list items */ +.install-dropdown.install-dropdown-small .install-btn-main { + padding: 8px 12px; + font-size: 13px; +} + +.install-dropdown.install-dropdown-small .install-btn-toggle { + padding: 8px 8px; +} + +.install-dropdown-menu .dropdown-divider { + height: 1px; + background: var(--color-border); + margin: 4px 0; +} + +/* Spinner animation */ +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.spinner { + animation: spin 1s linear infinite; +} + +/* Button states */ +.btn:disabled { + opacity: 0.7; + cursor: not-allowed; +} + +/* Modal */ +.modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.8); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + padding: 24px; +} + +.modal.hidden { + display: none; +} + +.modal-content { + background: var(--color-bg-secondary); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius-xl); + width: 100%; + max-width: 900px; + max-height: 90vh; + display: flex; + flex-direction: column; + box-shadow: var(--shadow-lg); + overflow: hidden; +} + +.modal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + border-bottom: 1px solid var(--color-glass-border); + background: var(--color-glass); +} + +.modal-header h3 { + font-size: 16px; + font-weight: 600; + color: var(--color-text-emphasis); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.modal-actions { + display: flex; + gap: 8px; +} + +.modal-body { + flex: 1; + overflow: auto; + padding: 0; +} + +.modal-body pre { + margin: 0; + padding: 24px; + font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 13px; + line-height: 1.6; + white-space: pre-wrap; + word-wrap: break-word; + background: var(--color-bg); + color: var(--color-text); + min-height: 200px; +} + +/* Collection Modal View */ +.collection-view { + padding: 20px 24px; +} + +.collection-description { + font-size: 14px; + color: var(--color-text); + margin-bottom: 16px; + line-height: 1.5; +} + +.collection-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 16px; +} + +.collection-items-header { + padding: 10px 0; + border-bottom: 1px solid var(--color-border); + margin-bottom: 8px; + color: var(--color-text-muted); + font-size: 13px; +} + +.collection-items-list { + display: flex; + flex-direction: column; + gap: 2px; +} + +.collection-item { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 12px; + background: var(--color-bg); + border: 1px solid var(--color-border); + border-radius: var(--border-radius); + cursor: pointer; + transition: all var(--transition); +} + +.collection-item:hover { + background: var(--color-bg-tertiary); + border-color: var(--color-accent); +} + +.collection-item-icon { + font-size: 16px; + flex-shrink: 0; + width: 20px; + text-align: center; +} + +.collection-item-info { + flex: 1; + min-width: 0; +} + +.collection-item-name { + font-size: 13px; + font-weight: 500; + color: var(--color-text); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.collection-item-usage { + font-size: 12px; + color: var(--color-text-muted); + margin-top: 2px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.collection-item-type { + font-size: 11px; + color: var(--color-text-muted); + background: var(--color-bg-tertiary); + padding: 2px 6px; + border-radius: 4px; + flex-shrink: 0; + text-transform: capitalize; +} + +.collection-loading, +.collection-error { + padding: 40px; + text-align: center; + color: var(--color-text-muted); +} + +.collection-error { + color: var(--color-error); +} + +/* Page Layouts */ +.page-header { + padding: 56px 0 40px; + background: var(--gradient-hero), var(--color-bg); + border-bottom: 1px solid var(--color-glass-border); +} + +.page-header h1 { + font-size: 36px; + font-weight: 800; + color: var(--color-text); + margin-bottom: 12px; +} + +.page-header p { + font-size: 17px; + color: var(--color-text-muted); +} + +.page-content { + padding: 40px 0 80px; +} + +/* Search and Filter Bar */ +.search-bar { + display: flex; + gap: 16px; + margin-bottom: 24px; + flex-wrap: wrap; +} + +.search-bar input { + flex: 1; + min-width: 250px; + padding: 14px 18px; + font-size: 15px; + background: var(--color-glass); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius-lg); + color: var(--color-text); + transition: all var(--transition); +} + +.search-bar input:focus { + outline: 2px solid var(--color-accent); + outline-offset: 2px; + border-color: var(--color-accent); + box-shadow: var(--shadow-glow); +} + +/* Filters Bar */ +.filters-bar { + display: flex; + gap: 16px; + margin-bottom: 24px; + flex-wrap: wrap; + align-items: center; + padding: 18px 20px; + background: var(--color-glass); + backdrop-filter: blur(10px); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius-lg); + position: relative; + z-index: 10; +} + +.filter-group { + display: flex; + align-items: center; + gap: 10px; +} + +.filter-group label { + font-size: 13px; + font-weight: 500; + color: var(--color-text-muted); + white-space: nowrap; +} + +.filter-group select { + padding: 8px 14px; + font-size: 13px; + background: var(--color-bg); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius); + color: var(--color-text); + min-width: 150px; + cursor: pointer; +} + +.filter-group select:focus { + outline: 2px solid var(--color-accent); + outline-offset: 2px; + border-color: var(--color-accent); +} + +.checkbox-label { + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + user-select: none; + font-size: 13px; + font-weight: 500; + color: var(--color-text-muted); +} + +.checkbox-label input[type="checkbox"] { + width: 18px; + height: 18px; + cursor: pointer; + accent-color: var(--color-accent); +} + +.btn-small { + padding: 8px 14px; + font-size: 13px; +} + +/* Choices.js Theme Overrides */ +.filter-group .choices { + min-width: 200px; +} + +.choices { + margin-bottom: 0; +} + +.choices__inner { + background-color: var(--color-bg); + border-color: var(--color-border); + border-radius: var(--border-radius); + min-height: 42px; + padding: 6px 10px; + font-size: 14px; +} + +.choices__input { + background-color: transparent; + color: var(--color-text); + font-size: 14px; + padding: 4px 0; +} + +.choices__input::placeholder { + color: var(--color-text-muted); +} + +.choices__list--dropdown { + background-color: var(--color-bg-secondary); + border-color: var(--color-border); + border-radius: 0 0 var(--border-radius) var(--border-radius); + z-index: 100; + max-height: 300px; +} + +.choices__list--dropdown .choices__item { + color: var(--color-text); + font-size: 14px; + padding: 10px 14px; +} + +.choices__list--dropdown .choices__item--selectable.is-highlighted { + background-color: var(--color-bg-tertiary); +} + +.choices__list--multiple .choices__item { + background-color: var(--color-link); + border-color: var(--color-link); + border-radius: 4px; + color: white; + font-size: 13px; + padding: 4px 10px; + margin: 2px; +} + +.choices__list--multiple .choices__item .choices__button { + border-left-color: rgba(255,255,255,0.3); + padding-left: 8px; + margin-left: 6px; +} + +.choices__placeholder { + color: var(--color-text-muted); + opacity: 1; +} + +.choices[data-type*="select-multiple"] .choices__inner, +.choices[data-type*="text"] .choices__inner { + cursor: text; +} + +.is-open .choices__inner { + border-color: var(--color-link); + border-radius: var(--border-radius) var(--border-radius) 0 0; +} + +.is-open .choices__list--dropdown { + border-color: var(--color-link); +} + +.choices__list--dropdown .choices__item--selectable::after { + display: none; +} + +/* Tag variants */ +.tag-model { + background: linear-gradient(135deg, rgba(99, 102, 241, 0.2), rgba(139, 92, 246, 0.2)); + color: #a5b4fc; +} + +.tag-none { + background-color: var(--color-bg-tertiary); + color: var(--color-text-muted); + font-style: italic; +} + +.tag-handoffs { + background: linear-gradient(135deg, rgba(245, 158, 11, 0.2), rgba(251, 191, 36, 0.2)); + color: #fcd34d; +} + +.tag-extension { + background: linear-gradient(135deg, rgba(16, 185, 129, 0.2), rgba(52, 211, 153, 0.2)); + color: #6ee7b7; +} + +.tag-category { + background: linear-gradient(135deg, rgba(236, 72, 153, 0.2), rgba(244, 114, 182, 0.2)); + color: #f9a8d4; +} + +.tag-assets { + background: linear-gradient(135deg, rgba(6, 182, 212, 0.2), rgba(34, 211, 238, 0.2)); + color: #67e8f9; +} + +.tag-collection { + background: linear-gradient(135deg, rgba(245, 158, 11, 0.2), rgba(251, 191, 36, 0.2)); + color: #fcd34d; +} + +.tag-featured { + background: var(--gradient-primary); + color: white; + padding: 3px 10px; + border-radius: 12px; + font-size: 12px; + font-weight: 600; +} + +.results-count { + font-size: 14px; + color: var(--color-text-muted); + margin-bottom: 20px; + font-weight: 500; +} + +/* Resource List */ +.resource-list { + display: flex; + flex-direction: column; + gap: 16px; +} + +.resource-item { + background: var(--color-card-bg); + backdrop-filter: blur(10px); + border: 1px solid var(--color-glass-border); + border-radius: var(--border-radius-lg); + padding: 20px 24px; + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 20px; + transition: all var(--transition); + cursor: pointer; + position: relative; +} + +.resource-item::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 4px; + height: 100%; + background: var(--gradient-primary); + border-radius: var(--border-radius-lg) 0 0 var(--border-radius-lg); + opacity: 0; + transition: opacity var(--transition); +} + +.resource-item:hover { + background: var(--color-card-hover); + transform: translateX(4px); + box-shadow: var(--shadow); +} + +.resource-item:hover::before { + opacity: 1; +} + +.resource-info { + flex: 1; + min-width: 0; +} + +.resource-title { + font-size: 16px; + font-weight: 600; + color: var(--color-text-emphasis); + margin-bottom: 4px; +} + +.resource-description { + font-size: 14px; + color: var(--color-text-muted); + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; +} + +.resource-meta { + display: flex; + gap: 8px; + margin-top: 8px; + flex-wrap: wrap; +} + +.resource-tag { + font-size: 12px; + padding: 2px 8px; + background-color: var(--color-bg-tertiary); + border-radius: 12px; + color: var(--color-text-muted); +} + +.resource-actions { + display: flex; + gap: 8px; + flex-shrink: 0; +} + +/* Collection Items */ +.collection-items { + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid var(--color-border); +} + +.collection-item { + display: flex; + align-items: center; + gap: 8px; + padding: 8px 0; + font-size: 13px; + color: var(--color-text-muted); +} + +.collection-item-kind { + font-size: 11px; + padding: 2px 6px; + background-color: var(--color-bg-tertiary); + border-radius: 4px; + text-transform: capitalize; +} + +/* Empty State */ +.empty-state { + text-align: center; + padding: 60px 20px; + color: var(--color-text-muted); +} + +.empty-state h3 { + font-size: 18px; + color: var(--color-text); + margin-bottom: 8px; +} + +/* Loading State */ +.loading { + display: flex; + align-items: center; + justify-content: center; + padding: 60px 20px; + color: var(--color-text-muted); +} + +/* Toast Notifications */ +.toast { + position: fixed; + bottom: 24px; + right: 24px; + padding: 12px 20px; + background-color: var(--color-success); + color: white; + border-radius: var(--border-radius); + font-size: 14px; + font-weight: 500; + z-index: 1100; + animation: slideIn 0.3s ease; +} + +.toast.error { + background-color: var(--color-danger); +} + +@keyframes slideIn { + from { + transform: translateY(100%); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +/* Responsive */ +@media (max-width: 768px) { + .main-nav { + display: none; + } + + .hero h1 { + font-size: 32px; + } + + .hero-subtitle { + font-size: 16px; + } + + .steps { + grid-template-columns: 1fr; + gap: 32px; + } + + .cards-grid { + grid-template-columns: 1fr; + } + + .card-with-count { + flex-wrap: wrap; + } + + .card-count { + position: absolute; + top: 20px; + right: 20px; + } + + .resource-item { + flex-direction: column; + align-items: stretch; + } + + .resource-actions { + justify-content: flex-end; + } +} + +/* Placeholder sections */ +.placeholder-section { + text-align: center; + padding: 80px 20px; + background-color: var(--color-bg-secondary); + border: 2px dashed var(--color-border); + border-radius: var(--border-radius-lg); + margin: 20px 0; +} + +.placeholder-section h3 { + font-size: 24px; + color: var(--color-text-emphasis); + margin-bottom: 12px; +} + +.placeholder-section p { + color: var(--color-text-muted); + max-width: 500px; + margin: 0 auto; +} + +/* Tools page specific */ +.tool-card { + display: flex; + flex-direction: column; + gap: 16px; +} + +.tool-card h3 { + display: flex; + align-items: center; + gap: 12px; +} + +.tool-status { + font-size: 12px; + padding: 4px 8px; + border-radius: 12px; + font-weight: 500; +} + +.tool-status.available { + background-color: rgba(35, 134, 54, 0.2); + color: var(--color-success); +} + +.tool-status.coming-soon { + background-color: rgba(210, 153, 34, 0.2); + color: var(--color-warning); +} diff --git a/website/src/components/Modal.astro b/website/src/components/Modal.astro new file mode 100644 index 00000000..40b283dc --- /dev/null +++ b/website/src/components/Modal.astro @@ -0,0 +1,58 @@ +--- +// Modal component for viewing file contents +--- + + diff --git a/website/src/layouts/BaseLayout.astro b/website/src/layouts/BaseLayout.astro new file mode 100644 index 00000000..a8bc2b5c --- /dev/null +++ b/website/src/layouts/BaseLayout.astro @@ -0,0 +1,165 @@ +--- +interface Props { + title: string; + description?: string; + activeNav?: string; +} + +const { + title, + description = "Community-driven collection of custom agents, prompts, and instructions for GitHub Copilot", + activeNav = "", +} = Astro.props; +const base = import.meta.env.BASE_URL; +--- + + + + + + + {title} - Awesome GitHub Copilot + + + + + + + + + + + + + + + diff --git a/website/src/pages/agents.astro b/website/src/pages/agents.astro new file mode 100644 index 00000000..172cebc3 --- /dev/null +++ b/website/src/pages/agents.astro @@ -0,0 +1,54 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Modal from '../components/Modal.astro'; +--- + + +
+ + +
+
+ + + +
+
+ + +
+
+ + +
+
+ +
+ +
+ +
+
+
Loading agents...
+
+
+
+
+ + + + +
diff --git a/website/src/pages/collections.astro b/website/src/pages/collections.astro new file mode 100644 index 00000000..9e1c439a --- /dev/null +++ b/website/src/pages/collections.astro @@ -0,0 +1,49 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Modal from '../components/Modal.astro'; +--- + + +
+ + +
+
+ + +
+
+ + +
+
+ +
+ +
+ +
+
+
Loading collections...
+
+
+
+
+ + + + +
diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro new file mode 100644 index 00000000..64f1f0d7 --- /dev/null +++ b/website/src/pages/index.astro @@ -0,0 +1,120 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Modal from '../components/Modal.astro'; + +const base = import.meta.env.BASE_URL; +--- + + +
+ +
+
+

Awesome GitHub Copilot

+

Community-contributed instructions, prompts, agents, and skills to enhance your GitHub Copilot experience

+ +
+
+ + + + + + + + +
+
+

Getting Started

+
+
+ +

Browse

+

Explore agents, prompts, instructions, and skills

+
+
+ +

Preview

+

Click any item to view its full content

+
+
+ +

Install

+

One-click install to VS Code or copy to clipboard

+
+
+
+
+
+ + + + +
diff --git a/website/src/pages/instructions.astro b/website/src/pages/instructions.astro new file mode 100644 index 00000000..e9b1f0d1 --- /dev/null +++ b/website/src/pages/instructions.astro @@ -0,0 +1,43 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Modal from '../components/Modal.astro'; +--- + + +
+ + +
+
+ + +
+
+ + +
+ +
+ +
+
+
Loading instructions...
+
+
+
+
+ + + + +
diff --git a/website/src/pages/prompts.astro b/website/src/pages/prompts.astro new file mode 100644 index 00000000..00778338 --- /dev/null +++ b/website/src/pages/prompts.astro @@ -0,0 +1,43 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Modal from '../components/Modal.astro'; +--- + + +
+ + +
+
+ + +
+
+ + +
+ +
+ +
+
+
Loading prompts...
+
+
+
+
+ + + + +
diff --git a/website/src/pages/samples.astro b/website/src/pages/samples.astro new file mode 100644 index 00000000..7cd17618 --- /dev/null +++ b/website/src/pages/samples.astro @@ -0,0 +1,248 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Modal from '../components/Modal.astro'; + +const base = import.meta.env.BASE_URL; +--- + + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ +
+
Loading samples...
+
+
+
+
+ + + + + + +
diff --git a/website/src/pages/skills.astro b/website/src/pages/skills.astro new file mode 100644 index 00000000..af40aad1 --- /dev/null +++ b/website/src/pages/skills.astro @@ -0,0 +1,49 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import Modal from '../components/Modal.astro'; +--- + + +
+ + +
+
+ + +
+
+ + +
+
+ +
+ +
+ +
+
+
Loading skills...
+
+
+
+
+ + + + +
diff --git a/website/src/pages/tools.astro b/website/src/pages/tools.astro new file mode 100644 index 00000000..52b8fc22 --- /dev/null +++ b/website/src/pages/tools.astro @@ -0,0 +1,311 @@ +--- +import BaseLayout from "../layouts/BaseLayout.astro"; +--- + + +
+ + +
+
+
+ +
+ + + +
+
+
+ +
+ +
+

More Tools Coming Soon

+

+ We're working on additional tools to enhance your GitHub Copilot + experience. Check back soon! +

+
+
+
+
+ + + + +
diff --git a/website/src/scripts/choices.ts b/website/src/scripts/choices.ts new file mode 100644 index 00000000..c63fa5de --- /dev/null +++ b/website/src/scripts/choices.ts @@ -0,0 +1,34 @@ +/** + * Choices.js wrapper with sensible defaults + */ +import Choices from 'choices.js'; +import 'choices.js/public/assets/styles/choices.min.css'; + +export type { Choices }; + +/** + * Get selected values from a Choices instance + */ +export function getChoicesValues(choices: Choices): string[] { + const val = choices.getValue(true); + return Array.isArray(val) ? val : (val ? [val] : []); +} + +/** + * Create a new Choices instance with sensible defaults + */ +export function createChoices(selector: string | HTMLSelectElement, options: Partial = {}): Choices { + return new Choices(selector, { + removeItemButton: true, + searchPlaceholderValue: 'Search...', + noResultsText: 'No results found', + noChoicesText: 'No options available', + itemSelectText: '', + shouldSort: false, + searchResultLimit: 100, + resetScrollPosition: false, + ...options, + }); +} + +export { Choices }; diff --git a/website/src/scripts/jszip.ts b/website/src/scripts/jszip.ts new file mode 100644 index 00000000..a0040227 --- /dev/null +++ b/website/src/scripts/jszip.ts @@ -0,0 +1,7 @@ +/** + * JSZip entry point for bundling + */ +import JSZip from 'jszip'; + +export { JSZip }; +export default JSZip; diff --git a/website/src/scripts/modal.ts b/website/src/scripts/modal.ts new file mode 100644 index 00000000..38c8e288 --- /dev/null +++ b/website/src/scripts/modal.ts @@ -0,0 +1,546 @@ +/** + * Modal functionality for file viewing + */ + +import { + fetchFileContent, + fetchData, + getVSCodeInstallUrl, + copyToClipboard, + showToast, + downloadFile, + shareFile, + getResourceType, + escapeHtml, + getResourceIcon, +} from "./utils"; + +// Modal state +let currentFilePath: string | null = null; +let currentFileContent: string | null = null; +let currentFileType: string | null = null; +let triggerElement: HTMLElement | null = null; + +// Collection data cache +interface CollectionItem { + path: string; + kind: string; + usage?: string | null; +} + +interface Collection { + id: string; + name: string; + description?: string; + path: string; + items: CollectionItem[]; + tags?: string[]; +} + +interface CollectionsData { + items: Collection[]; +} + +let collectionsCache: CollectionsData | null = null; + +/** + * Get all focusable elements within a container + */ +function getFocusableElements(container: HTMLElement): HTMLElement[] { + const focusableSelectors = [ + "button:not([disabled])", + "a[href]", + "input:not([disabled])", + "select:not([disabled])", + "textarea:not([disabled])", + '[tabindex]:not([tabindex="-1"])', + ].join(", "); + + return Array.from( + container.querySelectorAll(focusableSelectors) + ).filter((el) => el.offsetParent !== null); // Filter out hidden elements +} + +/** + * Handle keyboard navigation within modal (focus trap) + */ +function handleModalKeydown(e: KeyboardEvent, modal: HTMLElement): void { + if (e.key === "Tab") { + const focusableElements = getFocusableElements(modal); + if (focusableElements.length === 0) return; + + const firstElement = focusableElements[0]; + const lastElement = focusableElements[focusableElements.length - 1]; + + if (e.shiftKey) { + // Shift+Tab: if on first element, wrap to last + if (document.activeElement === firstElement) { + e.preventDefault(); + lastElement.focus(); + } + } else { + // Tab: if on last element, wrap to first + if (document.activeElement === lastElement) { + e.preventDefault(); + firstElement.focus(); + } + } + } +} + +/** + * Setup modal functionality + */ +export function setupModal(): void { + const modal = document.getElementById("file-modal"); + const closeBtn = document.getElementById("close-modal"); + const copyBtn = document.getElementById("copy-btn"); + const downloadBtn = document.getElementById("download-btn"); + const shareBtn = document.getElementById("share-btn"); + + if (!modal) return; + + closeBtn?.addEventListener("click", closeModal); + + modal.addEventListener("click", (e) => { + if (e.target === modal) closeModal(); + }); + + document.addEventListener("keydown", (e) => { + if (!modal.classList.contains("hidden")) { + if (e.key === "Escape") { + closeModal(); + } else { + handleModalKeydown(e, modal); + } + } + }); + + copyBtn?.addEventListener("click", async () => { + if (currentFileContent) { + const success = await copyToClipboard(currentFileContent); + showToast( + success ? "Copied to clipboard!" : "Failed to copy", + success ? "success" : "error" + ); + } + }); + + downloadBtn?.addEventListener("click", async () => { + if (currentFilePath) { + const success = await downloadFile(currentFilePath); + showToast( + success ? "Download started!" : "Download failed", + success ? "success" : "error" + ); + } + }); + + shareBtn?.addEventListener("click", async () => { + if (currentFilePath) { + const success = await shareFile(currentFilePath); + showToast( + success ? "Link copied to clipboard!" : "Failed to copy link", + success ? "success" : "error" + ); + } + }); + + // Setup install dropdown toggle + setupInstallDropdown("install-dropdown"); + + // Handle browser back/forward navigation + window.addEventListener("hashchange", handleHashChange); + + // Check for deep link on initial load + handleHashChange(); +} + +/** + * Handle hash changes for deep linking + */ +function handleHashChange(): void { + const hash = window.location.hash; + + if (hash && hash.startsWith("#file=")) { + const filePath = decodeURIComponent(hash.slice(6)); + if (filePath && filePath !== currentFilePath) { + const type = getResourceType(filePath); + openFileModal(filePath, type, false); // Don't update hash since we're responding to it + } + } else if (!hash || hash === "#") { + // No hash or empty hash - close modal if open + if (currentFilePath) { + closeModal(false); // Don't update hash since we're responding to it + } + } +} + +/** + * Update URL hash for deep linking + */ +function updateHash(filePath: string | null): void { + if (filePath) { + const newHash = `#file=${encodeURIComponent(filePath)}`; + if (window.location.hash !== newHash) { + history.pushState(null, "", newHash); + } + } else { + if (window.location.hash) { + history.pushState( + null, + "", + window.location.pathname + window.location.search + ); + } + } +} + +/** + * Setup install dropdown toggle functionality + */ +export function setupInstallDropdown(containerId: string): void { + const container = document.getElementById(containerId); + if (!container) return; + + const toggle = container.querySelector( + ".install-btn-toggle" + ); + const menuItems = container.querySelectorAll( + ".install-dropdown-menu a" + ); + + toggle?.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + const isOpen = container.classList.toggle("open"); + toggle.setAttribute("aria-expanded", String(isOpen)); + + // Focus first menu item when opening + if (isOpen && menuItems.length > 0) { + menuItems[0].focus(); + } + }); + + // Keyboard navigation for dropdown + toggle?.addEventListener("keydown", (e) => { + if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") { + e.preventDefault(); + container.classList.add("open"); + toggle.setAttribute("aria-expanded", "true"); + if (menuItems.length > 0) { + menuItems[0].focus(); + } + } + }); + + // Keyboard navigation within menu + menuItems.forEach((item, index) => { + item.addEventListener("keydown", (e) => { + switch (e.key) { + case "ArrowDown": + e.preventDefault(); + if (index < menuItems.length - 1) { + menuItems[index + 1].focus(); + } + break; + case "ArrowUp": + e.preventDefault(); + if (index > 0) { + menuItems[index - 1].focus(); + } else { + toggle?.focus(); + } + break; + case "Escape": + e.preventDefault(); + container.classList.remove("open"); + toggle?.setAttribute("aria-expanded", "false"); + toggle?.focus(); + break; + case "Tab": + // Close menu on tab out + container.classList.remove("open"); + toggle?.setAttribute("aria-expanded", "false"); + break; + } + }); + }); + + // Close dropdown when clicking outside + document.addEventListener("click", (e) => { + if (!container.contains(e.target as Node)) { + container.classList.remove("open"); + toggle?.setAttribute("aria-expanded", "false"); + } + }); + + // Close dropdown when clicking a menu item + container.querySelectorAll(".install-dropdown-menu a").forEach((link) => { + link.addEventListener("click", () => { + container.classList.remove("open"); + toggle?.setAttribute("aria-expanded", "false"); + }); + }); +} + +/** + * Open file viewer modal + * @param filePath - Path to the file + * @param type - Resource type (agent, prompt, instruction, etc.) + * @param updateUrl - Whether to update the URL hash (default: true) + * @param trigger - The element that triggered the modal (for focus return) + */ +export async function openFileModal( + filePath: string, + type: string, + updateUrl = true, + trigger?: HTMLElement +): Promise { + const modal = document.getElementById("file-modal"); + const title = document.getElementById("modal-title"); + const modalContent = document.getElementById("modal-content"); + const contentEl = modalContent?.querySelector("code"); + const installDropdown = document.getElementById("install-dropdown"); + const installBtnMain = document.getElementById( + "install-btn-main" + ) as HTMLAnchorElement | null; + const installVscode = document.getElementById( + "install-vscode" + ) as HTMLAnchorElement | null; + const installInsiders = document.getElementById( + "install-insiders" + ) as HTMLAnchorElement | null; + const copyBtn = document.getElementById("copy-btn"); + const downloadBtn = document.getElementById("download-btn"); + const closeBtn = document.getElementById("close-modal"); + + if (!modal || !title || !modalContent) return; + + currentFilePath = filePath; + currentFileType = type; + + // Track trigger element for focus return + triggerElement = trigger || (document.activeElement as HTMLElement); + + // Update URL for deep linking + if (updateUrl) { + updateHash(filePath); + } + + // Show modal with loading state + title.textContent = filePath.split("/").pop() || filePath; + modal.classList.remove("hidden"); + + // Set focus to close button for accessibility + setTimeout(() => { + closeBtn?.focus(); + }, 0); + + // Handle collections differently - show as item list + if (type === "collection") { + await openCollectionModal( + filePath, + title, + modalContent, + installDropdown, + copyBtn, + downloadBtn + ); + return; + } + + // Regular file modal + if (contentEl) { + contentEl.textContent = "Loading..."; + } + + // Show copy/download buttons for regular files + if (copyBtn) copyBtn.style.display = "inline-flex"; + if (downloadBtn) downloadBtn.style.display = "inline-flex"; + + // Restore pre/code structure if it was replaced by collection view + if (!modalContent.querySelector("pre")) { + modalContent.innerHTML = ''; + } + const codeEl = modalContent.querySelector("code"); + + // Setup install dropdown + const vscodeUrl = getVSCodeInstallUrl(type, filePath, false); + const insidersUrl = getVSCodeInstallUrl(type, filePath, true); + + if (vscodeUrl && installDropdown) { + installDropdown.style.display = "inline-flex"; + installDropdown.classList.remove("open"); + if (installBtnMain) installBtnMain.href = vscodeUrl; + if (installVscode) installVscode.href = vscodeUrl; + if (installInsiders) installInsiders.href = insidersUrl || "#"; + } else if (installDropdown) { + installDropdown.style.display = "none"; + } + + // Fetch and display content + const fileContent = await fetchFileContent(filePath); + currentFileContent = fileContent; + + if (fileContent && codeEl) { + codeEl.textContent = fileContent; + } else if (codeEl) { + codeEl.textContent = + "Failed to load file content. Click the button below to view on GitHub."; + } +} + +/** + * Open collection modal with item list + */ +async function openCollectionModal( + filePath: string, + title: HTMLElement, + modalContent: HTMLElement, + installDropdown: HTMLElement | null, + copyBtn: HTMLElement | null, + downloadBtn: HTMLElement | null +): Promise { + // Hide install dropdown and copy/download for collections + if (installDropdown) installDropdown.style.display = "none"; + if (copyBtn) copyBtn.style.display = "none"; + if (downloadBtn) downloadBtn.style.display = "none"; + + // Show loading + modalContent.innerHTML = + '
Loading collection...
'; + + // Load collections data if not cached + if (!collectionsCache) { + collectionsCache = await fetchData("collections.json"); + } + + if (!collectionsCache) { + modalContent.innerHTML = + '
Failed to load collection data.
'; + return; + } + + // Find the collection + const collection = collectionsCache.items.find((c) => c.path === filePath); + if (!collection) { + modalContent.innerHTML = + '
Collection not found.
'; + return; + } + + // Update title + title.textContent = collection.name; + + // Render collection view + modalContent.innerHTML = ` +
+
${escapeHtml( + collection.description || "" + )}
+ ${ + collection.tags && collection.tags.length > 0 + ? ` +
+ ${collection.tags + .map((t) => `${escapeHtml(t)}`) + .join("")} +
+ ` + : "" + } +
+ ${collection.items.length} items in this collection +
+
+ ${collection.items + .map( + (item) => ` +
+ ${getResourceIcon( + item.kind + )} +
+
${escapeHtml( + item.path.split("/").pop() || item.path + )}
+ ${ + item.usage + ? `
${escapeHtml( + item.usage + )}
` + : "" + } +
+ ${escapeHtml(item.kind)} +
+ ` + ) + .join("")} +
+
+ `; + + // Add click handlers to collection items + modalContent.querySelectorAll(".collection-item").forEach((el) => { + el.addEventListener("click", () => { + const path = (el as HTMLElement).dataset.path; + const itemType = (el as HTMLElement).dataset.type; + if (path && itemType) { + openFileModal(path, itemType); + } + }); + }); +} + +/** + * Close modal + * @param updateUrl - Whether to update the URL hash (default: true) + */ +export function closeModal(updateUrl = true): void { + const modal = document.getElementById("file-modal"); + const installDropdown = document.getElementById("install-dropdown"); + + if (modal) { + modal.classList.add("hidden"); + } + if (installDropdown) { + installDropdown.classList.remove("open"); + } + + // Update URL for deep linking + if (updateUrl) { + updateHash(null); + } + + // Return focus to trigger element + if ( + triggerElement && + triggerElement.isConnected && + typeof triggerElement.focus === "function" + ) { + triggerElement.focus(); + } + + currentFilePath = null; + currentFileContent = null; + currentFileType = null; + triggerElement = null; +} + +/** + * Get current file path (for external use) + */ +export function getCurrentFilePath(): string | null { + return currentFilePath; +} + +/** + * Get current file content (for external use) + */ +export function getCurrentFileContent(): string | null { + return currentFileContent; +} diff --git a/website/src/scripts/pages/agents.ts b/website/src/scripts/pages/agents.ts new file mode 100644 index 00000000..5fd6f71b --- /dev/null +++ b/website/src/scripts/pages/agents.ts @@ -0,0 +1,176 @@ +/** + * Agents page functionality + */ +import { createChoices, getChoicesValues, type Choices } from '../choices'; +import { FuzzySearch, SearchItem } from '../search'; +import { fetchData, debounce, escapeHtml, getGitHubUrl, getInstallDropdownHtml, setupDropdownCloseHandlers, getActionButtonsHtml, setupActionHandlers } from '../utils'; +import { setupModal, openFileModal } from '../modal'; + +interface Agent extends SearchItem { + path: string; + model?: string; + tools?: string[]; + hasHandoffs?: boolean; +} + +interface AgentsData { + items: Agent[]; + filters: { + models: string[]; + tools: string[]; + }; +} + +const resourceType = 'agent'; +let allItems: Agent[] = []; +let search = new FuzzySearch(); +let modelSelect: Choices; +let toolSelect: Choices; + +let currentFilters = { + models: [] as string[], + tools: [] as string[], + hasHandoffs: false, +}; + +function applyFiltersAndRender(): void { + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const countEl = document.getElementById('results-count'); + const query = searchInput?.value || ''; + + let results = query ? search.search(query) : [...allItems]; + + if (currentFilters.models.length > 0) { + results = results.filter(item => { + if (currentFilters.models.includes('(none)') && !item.model) { + return true; + } + return item.model && currentFilters.models.includes(item.model); + }); + } + + if (currentFilters.tools.length > 0) { + results = results.filter(item => + item.tools?.some(tool => currentFilters.tools.includes(tool)) + ); + } + + if (currentFilters.hasHandoffs) { + results = results.filter(item => item.hasHandoffs); + } + + renderItems(results, query); + + const activeFilters: string[] = []; + if (currentFilters.models.length > 0) activeFilters.push(`models: ${currentFilters.models.length}`); + if (currentFilters.tools.length > 0) activeFilters.push(`tools: ${currentFilters.tools.length}`); + if (currentFilters.hasHandoffs) activeFilters.push('has handoffs'); + + let countText = `${results.length} of ${allItems.length} agents`; + if (activeFilters.length > 0) { + countText += ` (filtered by ${activeFilters.join(', ')})`; + } + if (countEl) countEl.textContent = countText; +} + +function renderItems(items: Agent[], query = ''): void { + const list = document.getElementById('resource-list'); + if (!list) return; + + if (items.length === 0) { + list.innerHTML = ` +
+

No agents found

+

Try a different search term or adjust filters

+
+ `; + return; + } + + list.innerHTML = items.map(item => ` +
+
+
${query ? search.highlight(item.title, query) : escapeHtml(item.title)}
+
${escapeHtml(item.description || 'No description')}
+
+ ${item.model ? `${escapeHtml(item.model)}` : ''} + ${item.tools?.slice(0, 3).map(t => `${escapeHtml(t)}`).join('') || ''} + ${item.tools && item.tools.length > 3 ? `+${item.tools.length - 3} more` : ''} + ${item.hasHandoffs ? `handoffs` : ''} +
+
+
+ ${getInstallDropdownHtml(resourceType, item.path, true)} + ${getActionButtonsHtml(item.path, true)} + + GitHub + +
+
+ `).join(''); + + // Add click handlers + list.querySelectorAll('.resource-item').forEach(el => { + el.addEventListener('click', () => { + const path = (el as HTMLElement).dataset.path; + if (path) openFileModal(path, resourceType); + }); + }); +} + +export async function initAgentsPage(): Promise { + const list = document.getElementById('resource-list'); + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const handoffsCheckbox = document.getElementById('filter-handoffs') as HTMLInputElement; + const clearFiltersBtn = document.getElementById('clear-filters'); + + const data = await fetchData('agents.json'); + if (!data || !data.items) { + if (list) list.innerHTML = '

Failed to load data

'; + return; + } + + allItems = data.items; + search.setItems(allItems); + + // Initialize Choices.js for model filter + modelSelect = createChoices('#filter-model', { placeholderValue: 'All Models' }); + modelSelect.setChoices(data.filters.models.map(m => ({ value: m, label: m })), 'value', 'label', true); + document.getElementById('filter-model')?.addEventListener('change', () => { + currentFilters.models = getChoicesValues(modelSelect); + applyFiltersAndRender(); + }); + + // Initialize Choices.js for tool filter + toolSelect = createChoices('#filter-tool', { placeholderValue: 'All Tools' }); + toolSelect.setChoices(data.filters.tools.map(t => ({ value: t, label: t })), 'value', 'label', true); + document.getElementById('filter-tool')?.addEventListener('change', () => { + currentFilters.tools = getChoicesValues(toolSelect); + applyFiltersAndRender(); + }); + + applyFiltersAndRender(); + + searchInput?.addEventListener('input', debounce(() => applyFiltersAndRender(), 200)); + + handoffsCheckbox?.addEventListener('change', () => { + currentFilters.hasHandoffs = handoffsCheckbox.checked; + applyFiltersAndRender(); + }); + + clearFiltersBtn?.addEventListener('click', () => { + currentFilters = { models: [], tools: [], hasHandoffs: false }; + modelSelect.removeActiveItems(); + toolSelect.removeActiveItems(); + if (handoffsCheckbox) handoffsCheckbox.checked = false; + if (searchInput) searchInput.value = ''; + applyFiltersAndRender(); + }); + + setupModal(); + setupDropdownCloseHandlers(); + setupActionHandlers(); +} + +// Auto-initialize when DOM is ready +document.addEventListener('DOMContentLoaded', initAgentsPage); diff --git a/website/src/scripts/pages/collections.ts b/website/src/scripts/pages/collections.ts new file mode 100644 index 00000000..3ad07f3d --- /dev/null +++ b/website/src/scripts/pages/collections.ts @@ -0,0 +1,143 @@ +/** + * Collections page functionality + */ +import { createChoices, getChoicesValues, type Choices } from '../choices'; +import { FuzzySearch, SearchItem } from '../search'; +import { fetchData, debounce, escapeHtml, getGitHubUrl } from '../utils'; +import { setupModal, openFileModal } from '../modal'; + +interface Collection extends SearchItem { + id: string; + name: string; + path: string; + tags?: string[]; + featured?: boolean; + itemCount: number; +} + +interface CollectionsData { + items: Collection[]; + filters: { + tags: string[]; + }; +} + +const resourceType = 'collection'; +let allItems: Collection[] = []; +let search = new FuzzySearch(); +let tagSelect: Choices; +let currentFilters = { + tags: [] as string[], + featured: false +}; + +function applyFiltersAndRender(): void { + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const countEl = document.getElementById('results-count'); + const query = searchInput?.value || ''; + + let results = query ? search.search(query) : [...allItems]; + + if (currentFilters.tags.length > 0) { + results = results.filter(item => item.tags?.some(tag => currentFilters.tags.includes(tag))); + } + if (currentFilters.featured) { + results = results.filter(item => item.featured); + } + + renderItems(results, query); + const activeFilters: string[] = []; + if (currentFilters.tags.length > 0) activeFilters.push(`${currentFilters.tags.length} tag${currentFilters.tags.length > 1 ? 's' : ''}`); + if (currentFilters.featured) activeFilters.push('featured'); + let countText = `${results.length} of ${allItems.length} collections`; + if (activeFilters.length > 0) { + countText += ` (filtered by ${activeFilters.join(', ')})`; + } + if (countEl) countEl.textContent = countText; +} + +function renderItems(items: Collection[], query = ''): void { + const list = document.getElementById('resource-list'); + if (!list) return; + + if (items.length === 0) { + list.innerHTML = '

No collections found

Try a different search term or adjust filters

'; + return; + } + + list.innerHTML = items.map(item => ` +
+
+
${item.featured ? '⭐ ' : ''}${query ? search.highlight(item.name, query) : escapeHtml(item.name)}
+
${escapeHtml(item.description || 'No description')}
+
+ ${item.itemCount} items + ${item.tags?.slice(0, 4).map(t => `${escapeHtml(t)}`).join('') || ''} + ${item.tags && item.tags.length > 4 ? `+${item.tags.length - 4} more` : ''} +
+
+
+ GitHub +
+
+ `).join(''); + + // Add click handlers + list.querySelectorAll('.resource-item').forEach(el => { + el.addEventListener('click', () => { + const path = (el as HTMLElement).dataset.path; + if (path) openFileModal(path, resourceType); + }); + }); +} + +export async function initCollectionsPage(): Promise { + const list = document.getElementById('resource-list'); + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const featuredCheckbox = document.getElementById('filter-featured') as HTMLInputElement; + const clearFiltersBtn = document.getElementById('clear-filters'); + + const data = await fetchData('collections.json'); + if (!data || !data.items) { + if (list) list.innerHTML = '

Failed to load data

'; + return; + } + + allItems = data.items; + + // Map collection items to search items + const searchItems = allItems.map(item => ({ + ...item, + title: item.name, + searchText: `${item.name} ${item.description} ${item.tags?.join(' ') || ''}`.toLowerCase() + })); + search.setItems(searchItems); + + tagSelect = createChoices('#filter-tag', { placeholderValue: 'All Tags' }); + tagSelect.setChoices(data.filters.tags.map(t => ({ value: t, label: t })), 'value', 'label', true); + document.getElementById('filter-tag')?.addEventListener('change', () => { + currentFilters.tags = getChoicesValues(tagSelect); + applyFiltersAndRender(); + }); + + applyFiltersAndRender(); + searchInput?.addEventListener('input', debounce(() => applyFiltersAndRender(), 200)); + + featuredCheckbox?.addEventListener('change', () => { + currentFilters.featured = featuredCheckbox.checked; + applyFiltersAndRender(); + }); + + clearFiltersBtn?.addEventListener('click', () => { + currentFilters = { tags: [], featured: false }; + tagSelect.removeActiveItems(); + if (featuredCheckbox) featuredCheckbox.checked = false; + if (searchInput) searchInput.value = ''; + applyFiltersAndRender(); + }); + + setupModal(); +} + +// Auto-initialize when DOM is ready +document.addEventListener('DOMContentLoaded', initCollectionsPage); diff --git a/website/src/scripts/pages/index.ts b/website/src/scripts/pages/index.ts new file mode 100644 index 00000000..6fa86746 --- /dev/null +++ b/website/src/scripts/pages/index.ts @@ -0,0 +1,135 @@ +/** + * Homepage functionality + */ +import { FuzzySearch, type SearchItem } from '../search'; +import { fetchData, debounce, escapeHtml, truncate, getResourceIcon } from '../utils'; +import { setupModal, openFileModal } from '../modal'; + +interface Manifest { + counts: { + agents: number; + prompts: number; + instructions: number; + skills: number; + collections: number; + tools: number; + }; +} + +interface Collection { + id: string; + name: string; + description?: string; + path: string; + tags?: string[]; + featured?: boolean; + itemCount: number; +} + +interface CollectionsData { + items: Collection[]; +} + +export async function initHomepage(): Promise { + // Load manifest for stats + const manifest = await fetchData('manifest.json'); + if (manifest && manifest.counts) { + // Populate counts in cards + const countKeys = ['agents', 'prompts', 'instructions', 'skills', 'collections', 'tools'] as const; + countKeys.forEach(key => { + const countEl = document.querySelector(`.card-count[data-count="${key}"]`); + if (countEl && manifest.counts[key] !== undefined) { + countEl.textContent = manifest.counts[key].toString(); + } + }); + } + + // Load search index + const searchIndex = await fetchData('search-index.json'); + if (searchIndex) { + const search = new FuzzySearch(); + search.setItems(searchIndex); + + const searchInput = document.getElementById('global-search') as HTMLInputElement; + const resultsDiv = document.getElementById('search-results'); + + if (searchInput && resultsDiv) { + searchInput.addEventListener('input', debounce(() => { + const query = searchInput.value.trim(); + if (query.length < 2) { + resultsDiv.classList.add('hidden'); + return; + } + + const results = search.search(query).slice(0, 10); + if (results.length === 0) { + resultsDiv.innerHTML = '
No results found
'; + } else { + resultsDiv.innerHTML = results.map(item => ` +
+ ${getResourceIcon(item.type)} +
+
${search.highlight(item.title, query)}
+
${truncate(item.description, 60)}
+
+
+ `).join(''); + + // Add click handlers + resultsDiv.querySelectorAll('.search-result').forEach(el => { + el.addEventListener('click', () => { + const path = (el as HTMLElement).dataset.path; + const type = (el as HTMLElement).dataset.type; + if (path && type) openFileModal(path, type); + }); + }); + } + resultsDiv.classList.remove('hidden'); + }, 200)); + + // Close results when clicking outside + document.addEventListener('click', (e) => { + if (!searchInput.contains(e.target as Node) && !resultsDiv.contains(e.target as Node)) { + resultsDiv.classList.add('hidden'); + } + }); + } + } + + // Load featured collections + const collectionsData = await fetchData('collections.json'); + if (collectionsData && collectionsData.items) { + const featured = collectionsData.items.filter(c => c.featured).slice(0, 6); + const featuredEl = document.getElementById('featured-collections'); + if (featuredEl) { + if (featured.length > 0) { + featuredEl.innerHTML = featured.map(c => ` +
+

${escapeHtml(c.name)}

+

${escapeHtml(truncate(c.description, 80))}

+
+ ${c.itemCount} items + ${c.tags?.slice(0, 3).map(t => `${escapeHtml(t)}`).join('') || ''} +
+
+ `).join(''); + + // Add click handlers + featuredEl.querySelectorAll('.card').forEach(el => { + el.addEventListener('click', () => { + const path = (el as HTMLElement).dataset.path; + if (path) openFileModal(path, 'collection'); + }); + }); + } else { + featuredEl.innerHTML = '

No featured collections yet

'; + } + } + } + + // Setup modal + setupModal(); +} + +// Auto-initialize when DOM is ready +document.addEventListener('DOMContentLoaded', initHomepage); diff --git a/website/src/scripts/pages/instructions.ts b/website/src/scripts/pages/instructions.ts new file mode 100644 index 00000000..500e1757 --- /dev/null +++ b/website/src/scripts/pages/instructions.ts @@ -0,0 +1,128 @@ +/** + * Instructions page functionality + */ +import { createChoices, getChoicesValues, type Choices } from '../choices'; +import { FuzzySearch, SearchItem } from '../search'; +import { fetchData, debounce, escapeHtml, getGitHubUrl, getInstallDropdownHtml, setupDropdownCloseHandlers, getActionButtonsHtml, setupActionHandlers } from '../utils'; +import { setupModal, openFileModal } from '../modal'; + +interface Instruction extends SearchItem { + path: string; + applyTo?: string; + extensions?: string[]; +} + +interface InstructionsData { + items: Instruction[]; + filters: { + extensions: string[]; + }; +} + +const resourceType = 'instruction'; +let allItems: Instruction[] = []; +let search = new FuzzySearch(); +let extensionSelect: Choices; +let currentFilters = { extensions: [] as string[] }; + +function applyFiltersAndRender(): void { + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const countEl = document.getElementById('results-count'); + const query = searchInput?.value || ''; + + let results = query ? search.search(query) : [...allItems]; + + if (currentFilters.extensions.length > 0) { + results = results.filter(item => { + if (currentFilters.extensions.includes('(none)') && (!item.extensions || item.extensions.length === 0)) { + return true; + } + return item.extensions?.some(ext => currentFilters.extensions.includes(ext)); + }); + } + + renderItems(results, query); + let countText = `${results.length} of ${allItems.length} instructions`; + if (currentFilters.extensions.length > 0) { + countText += ` (filtered by ${currentFilters.extensions.length} extension${currentFilters.extensions.length > 1 ? 's' : ''})`; + } + if (countEl) countEl.textContent = countText; +} + +function renderItems(items: Instruction[], query = ''): void { + const list = document.getElementById('resource-list'); + if (!list) return; + + if (items.length === 0) { + list.innerHTML = '

No instructions found

Try a different search term or adjust filters

'; + return; + } + + list.innerHTML = items.map(item => ` +
+
+
${query ? search.highlight(item.title, query) : escapeHtml(item.title)}
+
${escapeHtml(item.description || 'No description')}
+
+ ${item.applyTo ? `applies to: ${escapeHtml(item.applyTo)}` : ''} + ${item.extensions?.slice(0, 4).map(e => `${escapeHtml(e)}`).join('') || ''} + ${item.extensions && item.extensions.length > 4 ? `+${item.extensions.length - 4} more` : ''} +
+
+
+ ${getInstallDropdownHtml('instructions', item.path, true)} + ${getActionButtonsHtml(item.path, true)} + + GitHub + +
+
+ `).join(''); + + // Add click handlers + list.querySelectorAll('.resource-item').forEach(el => { + el.addEventListener('click', () => { + const path = (el as HTMLElement).dataset.path; + if (path) openFileModal(path, resourceType); + }); + }); +} + +export async function initInstructionsPage(): Promise { + const list = document.getElementById('resource-list'); + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const clearFiltersBtn = document.getElementById('clear-filters'); + + const data = await fetchData('instructions.json'); + if (!data || !data.items) { + if (list) list.innerHTML = '

Failed to load data

'; + return; + } + + allItems = data.items; + search.setItems(allItems); + + extensionSelect = createChoices('#filter-extension', { placeholderValue: 'All Extensions' }); + extensionSelect.setChoices(data.filters.extensions.map(e => ({ value: e, label: e })), 'value', 'label', true); + document.getElementById('filter-extension')?.addEventListener('change', () => { + currentFilters.extensions = getChoicesValues(extensionSelect); + applyFiltersAndRender(); + }); + + applyFiltersAndRender(); + searchInput?.addEventListener('input', debounce(() => applyFiltersAndRender(), 200)); + + clearFiltersBtn?.addEventListener('click', () => { + currentFilters = { extensions: [] }; + extensionSelect.removeActiveItems(); + if (searchInput) searchInput.value = ''; + applyFiltersAndRender(); + }); + + setupModal(); + setupDropdownCloseHandlers(); + setupActionHandlers(); +} + +// Auto-initialize when DOM is ready +document.addEventListener('DOMContentLoaded', initInstructionsPage); diff --git a/website/src/scripts/pages/prompts.ts b/website/src/scripts/pages/prompts.ts new file mode 100644 index 00000000..e660d727 --- /dev/null +++ b/website/src/scripts/pages/prompts.ts @@ -0,0 +1,123 @@ +/** + * Prompts page functionality + */ +import { createChoices, getChoicesValues, type Choices } from '../choices'; +import { FuzzySearch, SearchItem } from '../search'; +import { fetchData, debounce, escapeHtml, getGitHubUrl, getInstallDropdownHtml, setupDropdownCloseHandlers, getActionButtonsHtml, setupActionHandlers } from '../utils'; +import { setupModal, openFileModal } from '../modal'; + +interface Prompt extends SearchItem { + path: string; + tools?: string[]; +} + +interface PromptsData { + items: Prompt[]; + filters: { + tools: string[]; + }; +} + +const resourceType = 'prompt'; +let allItems: Prompt[] = []; +let search = new FuzzySearch(); +let toolSelect: Choices; +let currentFilters = { tools: [] as string[] }; + +function applyFiltersAndRender(): void { + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const countEl = document.getElementById('results-count'); + const query = searchInput?.value || ''; + + let results = query ? search.search(query) : [...allItems]; + + if (currentFilters.tools.length > 0) { + results = results.filter(item => + item.tools?.some(tool => currentFilters.tools.includes(tool)) + ); + } + + renderItems(results, query); + let countText = `${results.length} of ${allItems.length} prompts`; + if (currentFilters.tools.length > 0) { + countText += ` (filtered by ${currentFilters.tools.length} tool${currentFilters.tools.length > 1 ? 's' : ''})`; + } + if (countEl) countEl.textContent = countText; +} + +function renderItems(items: Prompt[], query = ''): void { + const list = document.getElementById('resource-list'); + if (!list) return; + + if (items.length === 0) { + list.innerHTML = '

No prompts found

Try a different search term or adjust filters

'; + return; + } + + list.innerHTML = items.map(item => ` +
+
+
${query ? search.highlight(item.title, query) : escapeHtml(item.title)}
+
${escapeHtml(item.description || 'No description')}
+
+ ${item.tools?.slice(0, 4).map(t => `${escapeHtml(t)}`).join('') || ''} + ${item.tools && item.tools.length > 4 ? `+${item.tools.length - 4} more` : ''} +
+
+
+ ${getInstallDropdownHtml(resourceType, item.path, true)} + ${getActionButtonsHtml(item.path, true)} + + GitHub + +
+
+ `).join(''); + + // Add click handlers + list.querySelectorAll('.resource-item').forEach(el => { + el.addEventListener('click', () => { + const path = (el as HTMLElement).dataset.path; + if (path) openFileModal(path, resourceType); + }); + }); +} + +export async function initPromptsPage(): Promise { + const list = document.getElementById('resource-list'); + const searchInput = document.getElementById('search-input') as HTMLInputElement; + const clearFiltersBtn = document.getElementById('clear-filters'); + + const data = await fetchData('prompts.json'); + if (!data || !data.items) { + if (list) list.innerHTML = '

Failed to load data

'; + return; + } + + allItems = data.items; + search.setItems(allItems); + + toolSelect = createChoices('#filter-tool', { placeholderValue: 'All Tools' }); + toolSelect.setChoices(data.filters.tools.map(t => ({ value: t, label: t })), 'value', 'label', true); + document.getElementById('filter-tool')?.addEventListener('change', () => { + currentFilters.tools = getChoicesValues(toolSelect); + applyFiltersAndRender(); + }); + + applyFiltersAndRender(); + searchInput?.addEventListener('input', debounce(() => applyFiltersAndRender(), 200)); + + clearFiltersBtn?.addEventListener('click', () => { + currentFilters = { tools: [] }; + toolSelect.removeActiveItems(); + if (searchInput) searchInput.value = ''; + applyFiltersAndRender(); + }); + + setupModal(); + setupDropdownCloseHandlers(); + setupActionHandlers(); +} + +// Auto-initialize when DOM is ready +document.addEventListener('DOMContentLoaded', initPromptsPage); diff --git a/website/src/scripts/pages/samples.ts b/website/src/scripts/pages/samples.ts new file mode 100644 index 00000000..8a896284 --- /dev/null +++ b/website/src/scripts/pages/samples.ts @@ -0,0 +1,522 @@ +/** + * Samples/Cookbook page functionality + */ + +import { FuzzySearch, type SearchableItem } from "../search"; +import { fetchData, escapeHtml } from "../utils"; +import { createChoices, getChoicesValues, type Choices } from "../choices"; + +// Types +interface Language { + id: string; + name: string; + icon: string; + extension: string; +} + +interface RecipeVariant { + doc: string; + example: string | null; +} + +interface Recipe { + id: string; + name: string; + description: string; + tags: string[]; + variants: Record; +} + +interface Cookbook { + id: string; + name: string; + description: string; + path: string; + featured: boolean; + languages: Language[]; + recipes: Recipe[]; +} + +interface SamplesData { + cookbooks: Cookbook[]; + totalRecipes: number; + totalCookbooks: number; + filters: { + languages: string[]; + tags: string[]; + }; +} + +// State +let samplesData: SamplesData | null = null; +let search: FuzzySearch | null = null; +let selectedLanguage: string | null = null; +let selectedTags: string[] = []; +let expandedRecipes: Set = new Set(); +let tagChoices: Choices | null = null; + +/** + * Initialize the samples page + */ +export async function initSamplesPage(): Promise { + try { + // Load samples data + samplesData = await fetchData("samples.json"); + + if (!samplesData || samplesData.cookbooks.length === 0) { + showEmptyState(); + return; + } + + // Initialize search with all recipes + const allRecipes = samplesData.cookbooks.flatMap((cookbook) => + cookbook.recipes.map( + (recipe) => + ({ + ...recipe, + title: recipe.name, + cookbookId: cookbook.id, + } as SearchableItem & { cookbookId: string }) + ) + ); + search = new FuzzySearch(allRecipes); + + // Setup UI + setupFilters(); + setupSearch(); + renderCookbooks(); + updateResultsCount(); + } catch (error) { + console.error("Failed to initialize samples page:", error); + showEmptyState(); + } +} + +/** + * Show empty state when no cookbooks are available + */ +function showEmptyState(): void { + const container = document.getElementById("samples-list"); + if (container) { + container.innerHTML = ` +
+

No Samples Available

+

Check back soon for code samples and recipes.

+
+ `; + } + + // Hide filters + const filtersBar = document.getElementById("filters-bar"); + if (filtersBar) filtersBar.style.display = "none"; +} + +/** + * Setup language and tag filters + */ +function setupFilters(): void { + if (!samplesData) return; + + // Language filter + const languageSelect = document.getElementById( + "filter-language" + ) as HTMLSelectElement; + if (languageSelect) { + // Get unique languages across all cookbooks + const languages = new Map(); + samplesData.cookbooks.forEach((cookbook) => { + cookbook.languages.forEach((lang) => { + if (!languages.has(lang.id)) { + languages.set(lang.id, lang); + } + }); + }); + + languageSelect.innerHTML = ''; + languages.forEach((lang, id) => { + const option = document.createElement("option"); + option.value = id; + option.textContent = `${lang.icon} ${lang.name}`; + languageSelect.appendChild(option); + }); + + languageSelect.addEventListener("change", () => { + selectedLanguage = languageSelect.value || null; + renderCookbooks(); + updateResultsCount(); + }); + } + + // Tag filter (multi-select with Choices.js) + const tagSelect = document.getElementById("filter-tag") as HTMLSelectElement; + if (tagSelect && samplesData.filters.tags.length > 0) { + // Initialize Choices.js + tagChoices = createChoices("#filter-tag", { placeholderValue: "All Tags" }); + tagChoices.setChoices( + samplesData.filters.tags.map((tag) => ({ value: tag, label: tag })), + "value", + "label", + true + ); + + tagSelect.addEventListener("change", () => { + selectedTags = getChoicesValues(tagChoices!); + renderCookbooks(); + updateResultsCount(); + }); + } + + // Clear filters button + const clearBtn = document.getElementById("clear-filters"); + clearBtn?.addEventListener("click", clearFilters); +} + +/** + * Setup search functionality + */ +function setupSearch(): void { + const searchInput = document.getElementById( + "search-input" + ) as HTMLInputElement; + if (!searchInput) return; + + let debounceTimer: number; + searchInput.addEventListener("input", () => { + clearTimeout(debounceTimer); + debounceTimer = window.setTimeout(() => { + renderCookbooks(); + updateResultsCount(); + }, 200); + }); +} + +/** + * Clear all filters + */ +function clearFilters(): void { + selectedLanguage = null; + selectedTags = []; + + const languageSelect = document.getElementById( + "filter-language" + ) as HTMLSelectElement; + if (languageSelect) languageSelect.value = ""; + + // Clear Choices.js selection + if (tagChoices) { + tagChoices.removeActiveItems(); + } + + const searchInput = document.getElementById( + "search-input" + ) as HTMLInputElement; + if (searchInput) searchInput.value = ""; + + renderCookbooks(); + updateResultsCount(); +} + +/** + * Get filtered recipes + */ +function getFilteredRecipes(): { + cookbook: Cookbook; + recipe: Recipe; + highlighted?: string; +}[] { + if (!samplesData || !search) return []; + + const searchInput = document.getElementById( + "search-input" + ) as HTMLInputElement; + const query = searchInput?.value.trim() || ""; + + let results: { cookbook: Cookbook; recipe: Recipe; highlighted?: string }[] = + []; + + if (query) { + // Use fuzzy search - returns SearchableItem[] directly + const searchResults = search.search(query); + results = searchResults.map((item) => { + const recipe = item as SearchableItem & { cookbookId: string }; + const cookbook = samplesData!.cookbooks.find( + (c) => c.id === recipe.cookbookId + )!; + return { + cookbook, + recipe: recipe as unknown as Recipe, + highlighted: search!.highlight(recipe.title, query), + }; + }); + } else { + // No search query - return all recipes + results = samplesData.cookbooks.flatMap((cookbook) => + cookbook.recipes.map((recipe) => ({ cookbook, recipe })) + ); + } + + // Apply language filter + if (selectedLanguage) { + results = results.filter( + ({ recipe }) => recipe.variants[selectedLanguage!] + ); + } + + // Apply tag filter + if (selectedTags.length > 0) { + results = results.filter(({ recipe }) => + selectedTags.some((tag) => recipe.tags.includes(tag)) + ); + } + + return results; +} + +/** + * Render cookbooks and recipes + */ +function renderCookbooks(): void { + const container = document.getElementById("samples-list"); + if (!container || !samplesData) return; + + const filteredResults = getFilteredRecipes(); + + if (filteredResults.length === 0) { + container.innerHTML = ` +
+

No Results Found

+

Try adjusting your search or filters.

+
+ `; + return; + } + + // Group by cookbook + const byCookbook = new Map< + string, + { cookbook: Cookbook; recipes: { recipe: Recipe; highlighted?: string }[] } + >(); + filteredResults.forEach(({ cookbook, recipe, highlighted }) => { + if (!byCookbook.has(cookbook.id)) { + byCookbook.set(cookbook.id, { cookbook, recipes: [] }); + } + byCookbook.get(cookbook.id)!.recipes.push({ recipe, highlighted }); + }); + + let html = ""; + byCookbook.forEach(({ cookbook, recipes }) => { + html += renderCookbookSection(cookbook, recipes); + }); + + container.innerHTML = html; + + // Setup event listeners + setupRecipeListeners(); +} + +/** + * Render a cookbook section + */ +function renderCookbookSection( + cookbook: Cookbook, + recipes: { recipe: Recipe; highlighted?: string }[] +): string { + const languageTabs = cookbook.languages + .map( + (lang) => ` + + ` + ) + .join(""); + + const recipeCards = recipes + .map(({ recipe, highlighted }) => + renderRecipeCard(cookbook, recipe, highlighted) + ) + .join(""); + + return ` +
+
+
+

${escapeHtml(cookbook.name)}

+

${escapeHtml(cookbook.description)}

+
+
+ ${languageTabs} +
+
+
+ ${recipeCards} +
+
+ `; +} + +/** + * Render a recipe card + */ +function renderRecipeCard( + cookbook: Cookbook, + recipe: Recipe, + highlightedName?: string +): string { + const recipeKey = `${cookbook.id}-${recipe.id}`; + const isExpanded = expandedRecipes.has(recipeKey); + + // Determine which language to show + const displayLang = selectedLanguage || cookbook.languages[0]?.id || "nodejs"; + const variant = recipe.variants[displayLang]; + + const tags = recipe.tags + .map((tag) => `${escapeHtml(tag)}`) + .join(""); + + const langIndicators = cookbook.languages + .filter((lang) => recipe.variants[lang.id]) + .map( + (lang) => + `${lang.icon}` + ) + .join(""); + + return ` +
+
+

${highlightedName || escapeHtml(recipe.name)}

+
${langIndicators}
+
+

${escapeHtml(recipe.description)}

+
${tags}
+
+ ${ + variant + ? ` + + ${ + variant.example + ? ` + + ` + : "" + } + + + GitHub + + ` + : 'Not available for selected language' + } +
+
+ `; +} + +/** + * Setup event listeners for recipe interactions + */ +function setupRecipeListeners(): void { + // View recipe buttons + document.querySelectorAll(".view-recipe-btn").forEach((btn) => { + btn.addEventListener("click", async (e) => { + e.stopPropagation(); + const docPath = (btn as HTMLElement).dataset.doc; + if (docPath) { + await showRecipeContent(docPath, "recipe"); + } + }); + }); + + // View example buttons + document.querySelectorAll(".view-example-btn").forEach((btn) => { + btn.addEventListener("click", async (e) => { + e.stopPropagation(); + const examplePath = (btn as HTMLElement).dataset.example; + if (examplePath) { + await showRecipeContent(examplePath, "example"); + } + }); + }); + + // Language tab clicks + document.querySelectorAll(".lang-tab").forEach((tab) => { + tab.addEventListener("click", (e) => { + const langId = (tab as HTMLElement).dataset.lang; + if (langId) { + selectedLanguage = langId; + // Update language filter select + const languageSelect = document.getElementById( + "filter-language" + ) as HTMLSelectElement; + if (languageSelect) languageSelect.value = langId; + renderCookbooks(); + updateResultsCount(); + } + }); + }); +} + +/** + * Show recipe/example content in modal + */ +async function showRecipeContent( + filePath: string, + type: "recipe" | "example" +): Promise { + // Use existing modal infrastructure + const { openFileModal } = await import("../modal"); + await openFileModal(filePath, type); +} + +/** + * Update results count display + */ +function updateResultsCount(): void { + const resultsCount = document.getElementById("results-count"); + if (!resultsCount || !samplesData) return; + + const filtered = getFilteredRecipes(); + const total = samplesData.totalRecipes; + + if (filtered.length === total) { + resultsCount.textContent = `${total} recipe${total !== 1 ? "s" : ""}`; + } else { + resultsCount.textContent = `${filtered.length} of ${total} recipe${ + total !== 1 ? "s" : "" + }`; + } +} + +// Auto-initialize when DOM is ready +if (typeof document !== "undefined") { + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", () => initSamplesPage()); + } else { + initSamplesPage(); + } +} diff --git a/website/src/scripts/pages/skills.ts b/website/src/scripts/pages/skills.ts new file mode 100644 index 00000000..9689833f --- /dev/null +++ b/website/src/scripts/pages/skills.ts @@ -0,0 +1,288 @@ +/** + * Skills page functionality + */ +import { createChoices, getChoicesValues, type Choices } from "../choices"; +import { FuzzySearch, SearchItem } from "../search"; +import { + fetchData, + debounce, + escapeHtml, + getGitHubUrl, + getRawGitHubUrl, + showToast, +} from "../utils"; +import { setupModal, openFileModal } from "../modal"; +import JSZip from "../jszip"; + +interface SkillFile { + name: string; + path: string; +} + +interface Skill extends SearchItem { + id: string; + path: string; + skillFile: string; + category: string; + hasAssets: boolean; + assetCount: number; + files: SkillFile[]; +} + +interface SkillsData { + items: Skill[]; + filters: { + categories: string[]; + }; +} + +const resourceType = "skill"; +let allItems: Skill[] = []; +let search = new FuzzySearch(); +let categorySelect: Choices; +let currentFilters = { + categories: [] as string[], + hasAssets: false, +}; + +function applyFiltersAndRender(): void { + const searchInput = document.getElementById( + "search-input" + ) as HTMLInputElement; + const countEl = document.getElementById("results-count"); + const query = searchInput?.value || ""; + + let results = query ? search.search(query) : [...allItems]; + + if (currentFilters.categories.length > 0) { + results = results.filter((item) => + currentFilters.categories.includes(item.category) + ); + } + if (currentFilters.hasAssets) { + results = results.filter((item) => item.hasAssets); + } + + renderItems(results, query); + const activeFilters: string[] = []; + if (currentFilters.categories.length > 0) + activeFilters.push( + `${currentFilters.categories.length} categor${ + currentFilters.categories.length > 1 ? "ies" : "y" + }` + ); + if (currentFilters.hasAssets) activeFilters.push("has assets"); + let countText = `${results.length} of ${allItems.length} skills`; + if (activeFilters.length > 0) { + countText += ` (filtered by ${activeFilters.join(", ")})`; + } + if (countEl) countEl.textContent = countText; +} + +function renderItems(items: Skill[], query = ""): void { + const list = document.getElementById("resource-list"); + if (!list) return; + + if (items.length === 0) { + list.innerHTML = + '

No skills found

Try a different search term or adjust filters

'; + return; + } + + list.innerHTML = items + .map( + (item) => ` +
+
+
${ + query ? search.highlight(item.title, query) : escapeHtml(item.title) + }
+
${escapeHtml( + item.description || "No description" + )}
+
+ ${escapeHtml( + item.category + )} + ${ + item.hasAssets + ? `${ + item.assetCount + } asset${item.assetCount === 1 ? "" : "s"}` + : "" + } + ${item.files.length} file${ + item.files.length === 1 ? "" : "s" + } +
+
+
+ + GitHub +
+
+ ` + ) + .join(""); + + // Add click handlers for opening modal + list.querySelectorAll(".resource-item").forEach((el) => { + el.addEventListener("click", (e) => { + // Don't trigger modal if clicking download button or github link + if ((e.target as HTMLElement).closest(".resource-actions")) return; + const path = (el as HTMLElement).dataset.path; + if (path) openFileModal(path, resourceType); + }); + }); + + // Add download handlers + list.querySelectorAll(".download-skill-btn").forEach((btn) => { + btn.addEventListener("click", (e) => { + e.stopPropagation(); + const skillId = (btn as HTMLElement).dataset.skillId; + if (skillId) downloadSkill(skillId, btn as HTMLButtonElement); + }); + }); +} + +async function downloadSkill( + skillId: string, + btn: HTMLButtonElement +): Promise { + const skill = allItems.find((item) => item.id === skillId); + if (!skill || !skill.files || skill.files.length === 0) { + showToast("No files found for this skill.", "error"); + return; + } + + const originalContent = btn.innerHTML; + btn.disabled = true; + btn.innerHTML = + ' Preparing...'; + + try { + const zip = new JSZip(); + const folder = zip.folder(skill.id); + + const fetchPromises = skill.files.map(async (file) => { + const url = getRawGitHubUrl(file.path); + try { + const response = await fetch(url); + if (!response.ok) return null; + const content = await response.text(); + return { name: file.name, content }; + } catch { + return null; + } + }); + + const results = await Promise.all(fetchPromises); + let addedFiles = 0; + for (const result of results) { + if (result && folder) { + folder.file(result.name, result.content); + addedFiles++; + } + } + + if (addedFiles === 0) throw new Error("Failed to fetch any files"); + + const blob = await zip.generateAsync({ type: "blob" }); + const downloadUrl = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = downloadUrl; + link.download = `${skill.id}.zip`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(downloadUrl); + + btn.innerHTML = + ' Downloaded!'; + setTimeout(() => { + btn.disabled = false; + btn.innerHTML = originalContent; + }, 2000); + } catch (error) { + const message = error instanceof Error ? error.message : "Download failed."; + showToast(message, "error"); + btn.innerHTML = + ' Failed'; + setTimeout(() => { + btn.disabled = false; + btn.innerHTML = originalContent; + }, 2000); + } +} + +export async function initSkillsPage(): Promise { + const list = document.getElementById("resource-list"); + const searchInput = document.getElementById( + "search-input" + ) as HTMLInputElement; + const hasAssetsCheckbox = document.getElementById( + "filter-has-assets" + ) as HTMLInputElement; + const clearFiltersBtn = document.getElementById("clear-filters"); + + const data = await fetchData("skills.json"); + if (!data || !data.items) { + if (list) + list.innerHTML = + '

Failed to load data

'; + return; + } + + allItems = data.items; + search.setItems(allItems); + + categorySelect = createChoices("#filter-category", { + placeholderValue: "All Categories", + }); + categorySelect.setChoices( + data.filters.categories.map((c) => ({ value: c, label: c })), + "value", + "label", + true + ); + document.getElementById("filter-category")?.addEventListener("change", () => { + currentFilters.categories = getChoicesValues(categorySelect); + applyFiltersAndRender(); + }); + + applyFiltersAndRender(); + searchInput?.addEventListener( + "input", + debounce(() => applyFiltersAndRender(), 200) + ); + + hasAssetsCheckbox?.addEventListener("change", () => { + currentFilters.hasAssets = hasAssetsCheckbox.checked; + applyFiltersAndRender(); + }); + + clearFiltersBtn?.addEventListener("click", () => { + currentFilters = { categories: [], hasAssets: false }; + categorySelect.removeActiveItems(); + if (hasAssetsCheckbox) hasAssetsCheckbox.checked = false; + if (searchInput) searchInput.value = ""; + applyFiltersAndRender(); + }); + + setupModal(); +} + +// Auto-initialize when DOM is ready +document.addEventListener("DOMContentLoaded", initSkillsPage); diff --git a/website/src/scripts/pages/tools.ts b/website/src/scripts/pages/tools.ts new file mode 100644 index 00000000..ceb16525 --- /dev/null +++ b/website/src/scripts/pages/tools.ts @@ -0,0 +1,322 @@ +/** + * Tools page functionality + */ +import { FuzzySearch, type SearchableItem } from "../search"; +import { fetchData, debounce, escapeHtml } from "../utils"; + +export interface Tool extends SearchableItem { + id: string; + name: string; + title: string; + description: string; + category: string; + featured: boolean; + requirements: string[]; + features: string[]; + links: { + blog?: string; + vscode?: string; + "vscode-insiders"?: string; + "visual-studio"?: string; + github?: string; + documentation?: string; + marketplace?: string; + npm?: string; + pypi?: string; + }; + configuration?: { + type: string; + content: string; + }; + tags: string[]; +} + +interface ToolsData { + items: Tool[]; + filters: { + categories: string[]; + tags: string[]; + }; +} + +let allItems: Tool[] = []; +let search: FuzzySearch; +let currentFilters = { + categories: [] as string[], + query: "", +}; + +function formatMultilineText(text: string): string { + return escapeHtml(text).replace(/\r?\n/g, "
"); +} + +function applyFiltersAndRender(): void { + const searchInput = document.getElementById( + "search-input" + ) as HTMLInputElement; + const countEl = document.getElementById("results-count"); + const query = searchInput?.value || ""; + currentFilters.query = query; + + let results = query ? search.search(query) : [...allItems]; + + if (currentFilters.categories.length > 0) { + results = results.filter((item) => + currentFilters.categories.includes(item.category) + ); + } + + renderTools(results, query); + + let countText = `${results.length} of ${allItems.length} tools`; + if (currentFilters.categories.length > 0) { + countText += ` (filtered by ${currentFilters.categories.length} categories)`; + } + if (countEl) countEl.textContent = countText; +} + +function renderTools(tools: Tool[], query = ""): void { + const container = document.getElementById("tools-list"); + if (!container) return; + + if (tools.length === 0) { + container.innerHTML = ` +
+

No tools found

+

Try a different search term or adjust filters

+
+ `; + return; + } + + container.innerHTML = tools + .map((tool) => { + const badges: string[] = []; + if (tool.featured) { + badges.push('Featured'); + } + badges.push( + `${escapeHtml(tool.category)}` + ); + + const features = + tool.features && tool.features.length > 0 + ? `
+

Features

+
    ${tool.features + .map((f) => `
  • ${escapeHtml(f)}
  • `) + .join("")}
+
` + : ""; + + const requirements = + tool.requirements && tool.requirements.length > 0 + ? `
+

Requirements

+
    ${tool.requirements + .map((r) => `
  • ${escapeHtml(r)}
  • `) + .join("")}
+
` + : ""; + + const tags = + tool.tags && tool.tags.length > 0 + ? `
+ ${tool.tags + .map((t) => `${escapeHtml(t)}`) + .join("")} +
` + : ""; + + const config = tool.configuration + ? `
+

Configuration

+
+
${escapeHtml(tool.configuration.content)}
+
+ +
` + : ""; + + const actions: string[] = []; + if (tool.links.blog) { + actions.push( + `📖 Blog` + ); + } + if (tool.links.marketplace) { + actions.push( + `🏪 Marketplace` + ); + } + if (tool.links.npm) { + actions.push( + `📦 npm` + ); + } + if (tool.links.pypi) { + actions.push( + `🐍 PyPI` + ); + } + if (tool.links.documentation) { + actions.push( + `📚 Docs` + ); + } + if (tool.links.github) { + actions.push( + `GitHub` + ); + } + if (tool.links.vscode) { + actions.push( + `Install in VS Code` + ); + } + if (tool.links["vscode-insiders"]) { + actions.push( + `VS Code Insiders` + ); + } + if (tool.links["visual-studio"]) { + actions.push( + `Visual Studio` + ); + } + + const actionsHtml = + actions.length > 0 + ? `
${actions.join("")}
` + : ""; + + const titleHtml = query + ? search.highlight(tool.name, query) + : escapeHtml(tool.name); + const descriptionHtml = formatMultilineText(tool.description); + + return ` +
+
+

${titleHtml}

+
+ ${badges.join("")} +
+
+

${descriptionHtml}

+ ${features} + ${requirements} + ${config} + ${tags} + ${actionsHtml} +
+ `; + }) + .join(""); + + setupCopyConfigHandlers(); +} + +function setupCopyConfigHandlers(): void { + document.querySelectorAll(".copy-config-btn").forEach((btn) => { + btn.addEventListener("click", async (e) => { + e.stopPropagation(); + const button = e.currentTarget as HTMLButtonElement; + const config = decodeURIComponent(button.dataset.config || ""); + try { + await navigator.clipboard.writeText(config); + button.classList.add("copied"); + const originalHtml = button.innerHTML; + button.innerHTML = ` + + + + Copied! + `; + setTimeout(() => { + button.classList.remove("copied"); + button.innerHTML = originalHtml; + }, 2000); + } catch (err) { + console.error("Failed to copy:", err); + } + }); + }); +} + +export async function initToolsPage(): Promise { + const container = document.getElementById("tools-list"); + const searchInput = document.getElementById( + "search-input" + ) as HTMLInputElement; + const categoryFilter = document.getElementById( + "filter-category" + ) as HTMLSelectElement; + const clearFiltersBtn = document.getElementById("clear-filters"); + + if (container) { + container.innerHTML = '
Loading tools...
'; + } + + const data = await fetchData("tools.json"); + if (!data || !data.items) { + if (container) + container.innerHTML = + '

Failed to load tools

'; + return; + } + + // Map items to include title for FuzzySearch + allItems = data.items.map((item) => ({ + ...item, + title: item.name, // FuzzySearch uses title + })); + + search = new FuzzySearch(); + search.setItems(allItems); + + // Populate category filter + if (categoryFilter && data.filters.categories) { + categoryFilter.innerHTML = + '' + + data.filters.categories + .map( + (c) => `` + ) + .join(""); + + categoryFilter.addEventListener("change", () => { + currentFilters.categories = categoryFilter.value + ? [categoryFilter.value] + : []; + applyFiltersAndRender(); + }); + } + + // Search input handler + searchInput?.addEventListener( + "input", + debounce(() => applyFiltersAndRender(), 200) + ); + + // Clear filters + clearFiltersBtn?.addEventListener("click", () => { + currentFilters = { categories: [], query: "" }; + if (categoryFilter) categoryFilter.value = ""; + if (searchInput) searchInput.value = ""; + applyFiltersAndRender(); + }); + + applyFiltersAndRender(); +} + +// Auto-initialize when DOM is ready +document.addEventListener("DOMContentLoaded", initToolsPage); diff --git a/website/src/scripts/search.ts b/website/src/scripts/search.ts new file mode 100644 index 00000000..28342dfb --- /dev/null +++ b/website/src/scripts/search.ts @@ -0,0 +1,184 @@ +/** + * Fuzzy search implementation for the Awesome Copilot website + * Simple substring matching on title and description with scoring + */ + +import { escapeHtml, fetchData } from "./utils"; + +export interface SearchItem { + title: string; + description?: string; + searchText?: string; + path: string; + type: string; + [key: string]: unknown; +} + +export interface SearchableItem { + title: string; + description?: string; + [key: string]: unknown; +} + +export interface SearchOptions { + fields?: string[]; + limit?: number; + minScore?: number; +} + +export class FuzzySearch { + private items: T[] = []; + + constructor(items: T[] = []) { + this.items = items; + } + + /** + * Update the items to search + */ + setItems(items: T[]): void { + this.items = items; + } + + /** + * Search items with fuzzy matching + */ + search(query: string, options: SearchOptions = {}): T[] { + const { + fields = ["title", "description", "searchText"], + limit = 50, + minScore = 0, + } = options; + + if (!query || query.trim().length === 0) { + return this.items.slice(0, limit); + } + + const normalizedQuery = query.toLowerCase().trim(); + const queryWords = normalizedQuery.split(/\s+/); + const results: Array<{ item: T; score: number }> = []; + + for (const item of this.items) { + const score = this.calculateScore(item, queryWords, fields); + if (score > minScore) { + results.push({ item, score }); + } + } + + // Sort by score descending + results.sort((a, b) => b.score - a.score); + + return results.slice(0, limit).map((r) => r.item); + } + + /** + * Calculate match score for an item + */ + private calculateScore( + item: T, + queryWords: string[], + fields: string[] + ): number { + let totalScore = 0; + + for (const word of queryWords) { + let wordScore = 0; + + for (const field of fields) { + const value = (item as Record)[field]; + if (!value) continue; + + const normalizedValue = String(value).toLowerCase(); + + // Exact match in title gets highest score + if (field === "title" && normalizedValue === word) { + wordScore = Math.max(wordScore, 100); + } + // Title starts with word + else if (field === "title" && normalizedValue.startsWith(word)) { + wordScore = Math.max(wordScore, 80); + } + // Title contains word + else if (field === "title" && normalizedValue.includes(word)) { + wordScore = Math.max(wordScore, 60); + } + // Description contains word + else if (field === "description" && normalizedValue.includes(word)) { + wordScore = Math.max(wordScore, 30); + } + // searchText (includes tags, tools, etc) contains word + else if (field === "searchText" && normalizedValue.includes(word)) { + wordScore = Math.max(wordScore, 20); + } + } + + totalScore += wordScore; + } + + // Bonus for matching all words + const matchesAllWords = queryWords.every((word) => + fields.some((field) => { + const value = (item as Record)[field]; + return value && String(value).toLowerCase().includes(word); + }) + ); + + if (matchesAllWords && queryWords.length > 1) { + totalScore *= 1.5; + } + + return totalScore; + } + + /** + * Highlight matching text in a string + */ + highlight(text: string, query: string): string { + if (!query || !text) return escapeHtml(text || ""); + + const normalizedQuery = query.toLowerCase().trim(); + const words = normalizedQuery.split(/\s+/); + let result = escapeHtml(text); + + for (const word of words) { + if (word.length < 2) continue; + const regex = new RegExp( + `(${word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, + "gi" + ); + const parts = result.split(/(<[^>]+>)/g); + let inMark = false; + result = parts + .map((part) => { + if (part.startsWith("<")) { + if (part.toLowerCase() === "") inMark = true; + if (part.toLowerCase() === "") inMark = false; + return part; + } + + if (inMark) { + return part; + } + + return part.replace(regex, "$1"); + }) + .join(""); + } + + return result; + } +} + +// Global search instance (uses SearchItem for the global search index) +export const globalSearch = new FuzzySearch(); + +/** + * Initialize global search with search index + */ +export async function initGlobalSearch(): Promise> { + const searchIndex = await fetchData("search-index.json"); + if (searchIndex) { + globalSearch.setItems(searchIndex); + } + return globalSearch; +} diff --git a/website/src/scripts/theme.ts b/website/src/scripts/theme.ts new file mode 100644 index 00000000..d0a9cf68 --- /dev/null +++ b/website/src/scripts/theme.ts @@ -0,0 +1,65 @@ +/** + * Theme management for the Awesome Copilot website + * Supports light/dark mode with user preference storage + */ + +const THEME_KEY = 'theme'; + +/** + * Get the current theme preference + */ +function getThemePreference(): 'light' | 'dark' { + const stored = localStorage.getItem(THEME_KEY); + if (stored === 'light' || stored === 'dark') { + return stored; + } + // Check system preference + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + return 'light'; + } + return 'dark'; +} + +/** + * Apply theme to the document + */ +function applyTheme(theme: 'light' | 'dark'): void { + document.documentElement.setAttribute('data-theme', theme); +} + +const initialTheme = getThemePreference(); +applyTheme(initialTheme); + +/** + * Toggle between light and dark theme + */ +export function toggleTheme(): void { + const current = document.documentElement.getAttribute('data-theme') as 'light' | 'dark'; + const newTheme = current === 'light' ? 'dark' : 'light'; + applyTheme(newTheme); + localStorage.setItem(THEME_KEY, newTheme); +} + +/** + * Initialize theme toggle button + */ +export function initThemeToggle(): void { + const toggleBtn = document.getElementById('theme-toggle'); + if (toggleBtn) { + toggleBtn.addEventListener('click', toggleTheme); + } + + // Listen for system theme changes + if (window.matchMedia) { + window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => { + // Only auto-switch if user hasn't set a preference + const stored = localStorage.getItem(THEME_KEY); + if (!stored) { + applyTheme(e.matches ? 'light' : 'dark'); + } + }); + } +} + +// Auto-initialize when DOM is ready +document.addEventListener('DOMContentLoaded', initThemeToggle); diff --git a/website/src/scripts/utils.ts b/website/src/scripts/utils.ts new file mode 100644 index 00000000..479c7082 --- /dev/null +++ b/website/src/scripts/utils.ts @@ -0,0 +1,431 @@ +/** + * Utility functions for the Awesome Copilot website + */ + +const REPO_BASE_URL = + "https://raw.githubusercontent.com/github/awesome-copilot/main"; +const REPO_GITHUB_URL = "https://github.com/github/awesome-copilot/blob/main"; + +// VS Code install URL configurations +const VSCODE_INSTALL_CONFIG: Record< + string, + { baseUrl: string; scheme: string } +> = { + instructions: { + baseUrl: "https://aka.ms/awesome-copilot/install/instructions", + scheme: "chat-instructions", + }, + prompt: { + baseUrl: "https://aka.ms/awesome-copilot/install/prompt", + scheme: "chat-prompt", + }, + agent: { + baseUrl: "https://aka.ms/awesome-copilot/install/agent", + scheme: "chat-agent", + }, +}; + +/** + * Get the base path for the site + */ +export function getBasePath(): string { + // In Astro, import.meta.env.BASE_URL is available at build time + // At runtime, we use a data attribute on the body + if (typeof document !== "undefined") { + return document.body.dataset.basePath || "/"; + } + return "/"; +} + +/** + * Fetch JSON data from the data directory + */ +export async function fetchData( + filename: string +): Promise { + try { + const basePath = getBasePath(); + const response = await fetch(`${basePath}data/${filename}`); + if (!response.ok) throw new Error(`Failed to fetch ${filename}`); + return await response.json(); + } catch (error) { + console.error(`Error fetching ${filename}:`, error); + return null; + } +} + +/** + * Fetch raw file content from GitHub + */ +export async function fetchFileContent( + filePath: string +): Promise { + try { + const response = await fetch(`${REPO_BASE_URL}/${filePath}`); + if (!response.ok) throw new Error(`Failed to fetch ${filePath}`); + return await response.text(); + } catch (error) { + console.error(`Error fetching file content:`, error); + return null; + } +} + +/** + * Copy text to clipboard + */ +export async function copyToClipboard(text: string): Promise { + try { + await navigator.clipboard.writeText(text); + return true; + } catch { + // Deprecated fallback for older browsers that lack the async clipboard API. + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.style.position = "fixed"; + textarea.style.opacity = "0"; + document.body.appendChild(textarea); + textarea.select(); + const success = document.execCommand("copy"); + document.body.removeChild(textarea); + return success; + } +} + +/** + * Generate VS Code install URL + * @param type - Resource type (agent, prompt, instructions) + * @param filePath - Path to the file + * @param insiders - Whether to use VS Code Insiders + */ +export function getVSCodeInstallUrl( + type: string, + filePath: string, + insiders = false +): string | null { + const config = VSCODE_INSTALL_CONFIG[type]; + if (!config) return null; + + const rawUrl = `${REPO_BASE_URL}/${filePath}`; + const vscodeScheme = insiders ? "vscode-insiders" : "vscode"; + const innerUrl = `${vscodeScheme}:${ + config.scheme + }/install?url=${encodeURIComponent(rawUrl)}`; + + return `${config.baseUrl}?url=${encodeURIComponent(innerUrl)}`; +} + +/** + * Get GitHub URL for a file + */ +export function getGitHubUrl(filePath: string): string { + return `${REPO_GITHUB_URL}/${filePath}`; +} + +/** + * Get raw GitHub URL for a file (for fetching content) + */ +export function getRawGitHubUrl(filePath: string): string { + return `${REPO_BASE_URL}/${filePath}`; +} + +/** + * Download a file from its path + */ +export async function downloadFile(filePath: string): Promise { + try { + const response = await fetch(`${REPO_BASE_URL}/${filePath}`); + if (!response.ok) throw new Error("Failed to fetch file"); + + const content = await response.text(); + const filename = filePath.split("/").pop() || "file.md"; + + const blob = new Blob([content], { type: "text/markdown" }); + const url = URL.createObjectURL(blob); + + const a = document.createElement("a"); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + + return true; + } catch (error) { + console.error("Download failed:", error); + return false; + } +} + +/** + * Share/copy link to clipboard (deep link to current page with file hash) + */ +export async function shareFile(filePath: string): Promise { + const deepLinkUrl = `${window.location.origin}${ + window.location.pathname + }#file=${encodeURIComponent(filePath)}`; + return copyToClipboard(deepLinkUrl); +} + +/** + * Show a toast notification + */ +export function showToast( + message: string, + type: "success" | "error" = "success" +): void { + const existing = document.querySelector(".toast"); + if (existing) existing.remove(); + + const toast = document.createElement("div"); + toast.className = `toast ${type}`; + toast.textContent = message; + document.body.appendChild(toast); + + setTimeout(() => { + toast.remove(); + }, 3000); +} + +/** + * Debounce function for search input + */ +export function debounce void>( + func: T, + wait: number +): (...args: Parameters) => void { + let timeout: ReturnType; + return function executedFunction(...args: Parameters) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +} + +/** + * Escape HTML to prevent XSS + */ +export function escapeHtml(text: string): string { + const div = document.createElement("div"); + div.textContent = text; + return div.innerHTML; +} + +/** + * Truncate text with ellipsis + */ +export function truncate(text: string | undefined, maxLength: number): string { + if (!text || text.length <= maxLength) return text || ""; + return text.slice(0, maxLength).trim() + "..."; +} + +/** + * Get resource type from file path + */ +export function getResourceType(filePath: string): string { + if (filePath.endsWith(".agent.md")) return "agent"; + if (filePath.endsWith(".prompt.md")) return "prompt"; + if (filePath.endsWith(".instructions.md")) return "instruction"; + if (filePath.includes("/skills/") && filePath.endsWith("SKILL.md")) + return "skill"; + if (filePath.endsWith(".collection.yml")) return "collection"; + return "unknown"; +} + +/** + * Format a resource type for display + */ +export function formatResourceType(type: string): string { + const labels: Record = { + agent: "🤖 Agent", + prompt: "🎯 Prompt", + instruction: "📋 Instruction", + skill: "⚡ Skill", + collection: "📦 Collection", + }; + return labels[type] || type; +} + +/** + * Get icon for resource type + */ +export function getResourceIcon(type: string): string { + const icons: Record = { + agent: "🤖", + prompt: "🎯", + instruction: "📋", + skill: "⚡", + collection: "📦", + }; + return icons[type] || "📄"; +} + +/** + * Generate HTML for install dropdown button + */ +export function getInstallDropdownHtml( + type: string, + filePath: string, + small = false +): string { + const vscodeUrl = getVSCodeInstallUrl(type, filePath, false); + const insidersUrl = getVSCodeInstallUrl(type, filePath, true); + + if (!vscodeUrl) return ""; + + const sizeClass = small ? "install-dropdown-small" : ""; + const uniqueId = `install-${filePath.replace(/[^a-zA-Z0-9]/g, "-")}`; + + return ` + + `; +} + +/** + * Setup dropdown close handlers for dynamically created dropdowns + */ +export function setupDropdownCloseHandlers(): void { + if (dropdownHandlersReady) return; + dropdownHandlersReady = true; + + document.addEventListener( + "click", + (e) => { + const target = e.target as HTMLElement; + const dropdown = target.closest( + '.install-dropdown[data-install-scope="list"]' + ); + const toggle = target.closest( + ".install-btn-toggle" + ) as HTMLButtonElement | null; + const menuLink = target.closest( + ".install-dropdown-menu a" + ) as HTMLAnchorElement | null; + + if (dropdown) { + e.stopPropagation(); + + if (toggle) { + e.preventDefault(); + const isOpen = dropdown.classList.toggle("open"); + toggle.setAttribute("aria-expanded", String(isOpen)); + return; + } + + if (menuLink) { + dropdown.classList.remove("open"); + const toggleBtn = dropdown.querySelector( + ".install-btn-toggle" + ); + toggleBtn?.setAttribute("aria-expanded", "false"); + return; + } + + return; + } + + document + .querySelectorAll('.install-dropdown[data-install-scope="list"].open') + .forEach((openDropdown) => { + openDropdown.classList.remove("open"); + const toggleBtn = openDropdown.querySelector( + ".install-btn-toggle" + ); + toggleBtn?.setAttribute("aria-expanded", "false"); + }); + }, + true + ); +} + +/** + * Generate HTML for action buttons (download, share) in list view + */ +export function getActionButtonsHtml(filePath: string, small = false): string { + const btnClass = small ? "btn-small" : ""; + const iconSize = small ? 14 : 16; + + return ` + + + `; +} + +/** + * Setup global action handlers for download and share buttons + */ +export function setupActionHandlers(): void { + if (actionHandlersReady) return; + actionHandlersReady = true; + + document.addEventListener( + "click", + async (e) => { + const target = (e.target as HTMLElement).closest( + ".action-download, .action-share" + ) as HTMLElement | null; + if (!target) return; + + e.preventDefault(); + e.stopPropagation(); + + const path = target.dataset.path; + if (!path) return; + + if (target.classList.contains("action-download")) { + const success = await downloadFile(path); + showToast( + success ? "Download started!" : "Download failed", + success ? "success" : "error" + ); + return; + } + + const success = await shareFile(path); + showToast( + success ? "Link copied!" : "Failed to copy link", + success ? "success" : "error" + ); + }, + true + ); +} + +let dropdownHandlersReady = false; +let actionHandlersReady = false;