diff --git a/.gitignore b/.gitignore index f7b97a6..1c0415e 100644 --- a/.gitignore +++ b/.gitignore @@ -111,4 +111,9 @@ temp/ ehthumbs.db Thumbs.db -.kiro \ No newline at end of file +.claude +.serena + +__pycache__ + +.turbo \ No newline at end of file diff --git a/.storybook/globals.css b/.storybook/globals.css deleted file mode 100644 index e27c680..0000000 --- a/.storybook/globals.css +++ /dev/null @@ -1,59 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - :root { - --background: 0 0% 100%; - --foreground: 222.2 84% 4.9%; - --card: 0 0% 100%; - --card-foreground: 222.2 84% 4.9%; - --popover: 0 0% 100%; - --popover-foreground: 222.2 84% 4.9%; - --primary: 221.2 83.2% 53.3%; - --primary-foreground: 210 40% 98%; - --secondary: 210 40% 96%; - --secondary-foreground: 222.2 84% 4.9%; - --muted: 210 40% 96%; - --muted-foreground: 215.4 16.3% 46.9%; - --accent: 210 40% 96%; - --accent-foreground: 222.2 84% 4.9%; - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 210 40% 98%; - --border: 214.3 31.8% 91.4%; - --input: 214.3 31.8% 91.4%; - --ring: 221.2 83.2% 53.3%; - --radius: 0.5rem; - } - - .dark { - --background: 222.2 84% 4.9%; - --foreground: 210 40% 98%; - --card: 222.2 84% 4.9%; - --card-foreground: 210 40% 98%; - --popover: 222.2 84% 4.9%; - --popover-foreground: 210 40% 98%; - --primary: 217.2 91.2% 59.8%; - --primary-foreground: 222.2 84% 4.9%; - --secondary: 217.2 32.6% 17.5%; - --secondary-foreground: 210 40% 98%; - --muted: 217.2 32.6% 17.5%; - --muted-foreground: 215 20.2% 65.1%; - --accent: 217.2 32.6% 17.5%; - --accent-foreground: 210 40% 98%; - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 210 40% 98%; - --border: 217.2 32.6% 17.5%; - --input: 217.2 32.6% 17.5%; - --ring: 224.3 76.3% 94.1%; - } -} - -@layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground; - } -} \ No newline at end of file diff --git a/.storybook/main.ts b/.storybook/main.ts deleted file mode 100644 index 349185f..0000000 --- a/.storybook/main.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { StorybookConfig } from '@storybook/react-vite' -import { mergeConfig } from 'vite' - -const config: StorybookConfig = { - stories: ['../stories/**/*.stories.@(js|jsx|ts|tsx|mdx)'], - addons: [ - '@storybook/addon-essentials', - '@storybook/addon-interactions', - '@storybook/addon-links', - ], - framework: { - name: '@storybook/react-vite', - options: {}, - }, - typescript: { - check: false, - reactDocgen: 'react-docgen-typescript', - reactDocgenTypescriptOptions: { - shouldExtractLiteralValuesFromEnum: true, - propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), - }, - }, - viteFinal: async (config) => { - return mergeConfig(config, { - css: { - postcss: { - plugins: [ - require('tailwindcss'), - require('autoprefixer'), - ], - }, - }, - define: { - // Define any global constants if needed - 'process.env.STORYBOOK': true, - }, - resolve: { - alias: { - // Mock the @agentarea/react module for Storybook - '@agentarea/react': require.resolve('../.storybook/mocks/agentarea-react.tsx'), - }, - }, - }) - }, -} - -export default config \ No newline at end of file diff --git a/.storybook/mocks/agentarea-react.tsx b/.storybook/mocks/agentarea-react.tsx deleted file mode 100644 index 12754e9..0000000 --- a/.storybook/mocks/agentarea-react.tsx +++ /dev/null @@ -1,566 +0,0 @@ -import React, { createContext, useContext } from 'react' - -// Mock contexts that match the expected interfaces -const MockAgentContext = createContext({ - runtime: null, - isConnected: true, - agentCard: { - name: 'Demo Agent', - description: 'A demonstration agent for Storybook stories', - version: '1.0.0', - logoUrl: 'https://via.placeholder.com/64x64/4169e1/white?text=A', - supportedFeatures: ['streaming', 'realtime', 'cancellation'] - }, - capabilities: [ - { - name: 'Data Analysis', - description: 'Analyze datasets and generate insights', - inputTypes: ['csv', 'json', 'text'], - outputTypes: ['json', 'chart', 'report'] - } - ], - connect: async () => {}, - disconnect: async () => {}, - sendTask: async () => ({ taskId: 'mock-task', task: {} }), - getTask: async () => ({}), - getAllTasks: async () => [], - cancelTask: async () => {} -}) - -const MockInputContext = createContext({ - activeRequests: [], - pendingResponses: new Map(), - validationErrors: new Map(), - submissionStatus: new Map(), - error: null, - submitResponse: async (requestId: string, value: unknown) => { - console.log('Mock submitResponse:', requestId, value) - }, - validateInput: (requestId: string, value: unknown) => ({ valid: true, errors: [] }), - cancelInputRequest: async (requestId: string) => { - console.log('Mock cancelInputRequest:', requestId) - }, - clearValidationErrors: (requestId: string) => { - console.log('Mock clearValidationErrors:', requestId) - }, - addInputRequest: (request: any) => { - console.log('Mock addInputRequest:', request) - }, - removeInputRequest: (requestId: string) => { - console.log('Mock removeInputRequest:', requestId) - }, - updateInputRequest: (requestId: string, updates: any) => { - console.log('Mock updateInputRequest:', requestId, updates) - } -}) - -const MockArtifactContext = createContext({ - artifacts: new Map(), - getArtifact: (id: string) => null, - addArtifact: (artifact: any) => { - console.log('Mock addArtifact:', artifact) - }, - removeArtifact: (id: string) => { - console.log('Mock removeArtifact:', id) - }, - updateArtifact: (id: string, updates: any) => { - console.log('Mock updateArtifact:', id, updates) - } -}) - -const MockCommunicationContext = createContext({ - messages: [], - sendMessage: (message: any) => { - console.log('Mock sendMessage:', message) - }, - clearMessages: () => { - console.log('Mock clearMessages') - } -}) - -// Mock hook functions -export const useAgentContext = () => useContext(MockAgentContext) -export const useInputContext = () => useContext(MockInputContext) -export const useArtifactContext = () => useContext(MockArtifactContext) -export const useCommunicationContext = () => useContext(MockCommunicationContext) - -// Additional mock hooks -export const useAgent = () => ({ - runtime: null, - isConnected: true, - connect: async () => {}, - disconnect: async () => {}, - sendTask: async () => ({ taskId: 'mock-task', task: {} }), - error: null -}) - -export const useAgentCard = () => ({ - agentCard: { - name: 'Demo Agent', - description: 'A demonstration agent for Storybook stories', - version: '1.0.0', - logoUrl: 'https://via.placeholder.com/64x64/4169e1/white?text=A' - }, - loading: false, - error: null -}) - -export const useAgentCapabilities = () => ({ - capabilities: [ - { - name: 'Data Analysis', - description: 'Analyze datasets and generate insights', - inputTypes: ['csv', 'json', 'text'], - outputTypes: ['json', 'chart', 'report'] - } - ], - loading: false, - error: null -}) - -export const useConnection = () => ({ - isConnected: true, - connectionStatus: 'connected', - connect: async () => {}, - disconnect: async () => {}, - error: null -}) - -export const useTask = (taskId?: string) => ({ - task: taskId ? { - id: taskId, - title: 'Mock Task', - status: 'pending', - progress: 0.5 - } : null, - loading: false, - error: null, - cancel: async () => {}, - retry: async () => {} -}) - -export const useTaskList = () => ({ - tasks: [ - { id: 'task-1', title: 'Mock Task 1', status: 'completed', progress: 1 }, - { id: 'task-2', title: 'Mock Task 2', status: 'working', progress: 0.7 }, - { id: 'task-3', title: 'Mock Task 3', status: 'pending', progress: 0 } - ], - loading: false, - error: null, - refresh: async () => {} -}) - -export const useTaskCreation = () => ({ - createTask: async (input: any) => ({ taskId: 'new-task', task: {} }), - loading: false, - error: null -}) - -// Mock UI Components -export const Button = React.forwardRef< - HTMLButtonElement, - React.ButtonHTMLAttributes & { - variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' - size?: 'default' | 'sm' | 'lg' | 'icon' - } ->(({ className, variant = 'default', size = 'default', ...props }, ref) => { - const baseClasses = 'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50' - - const variants = { - default: 'bg-primary text-primary-foreground hover:bg-primary/90', - destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90', - outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground', - secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80', - ghost: 'hover:bg-accent hover:text-accent-foreground', - link: 'text-primary underline-offset-4 hover:underline' - } - - const sizes = { - default: 'h-10 px-4 py-2', - sm: 'h-9 rounded-md px-3', - lg: 'h-11 rounded-md px-8', - icon: 'h-10 w-10' - } - - return ( - - {onCancel && ( - - )} - - - ), - Approval: ({ request, onSubmit, onCancel, ...props }: any) => ( -
-
Mock Approval Input
-
- {request?.prompt || 'Mock approval prompt'} -
-
- - - {onCancel && ( - - )} -
-
- ), - Field: ({ label, value, onChange, ...props }: any) => ( -
- {label && } - onChange?.(e.target.value)} - /> -
- ), - Selection: ({ request, onSubmit, ...props }: any) => ( -
-
Mock Selection Input
-
- {request?.prompt || 'Mock selection prompt'} -
- -
- ), - Upload: ({ request, onSubmit, ...props }: any) => ( -
-
Mock Upload Input
-
- {request?.prompt || 'Mock upload prompt'} -
- -
- ) -} - -// Mock Chat Components -export const Chat = { - Root: ({ children, ...props }: any) => ( -
- {children} -
- ), - Message: ({ role, children, ...props }: any) => ( -
-
{children}
-
- ), - Input: ({ onSend, placeholder, ...props }: any) => ( -
-
- { - if (e.key === 'Enter') { - onSend?.({ text: (e.target as HTMLInputElement).value }) - ;(e.target as HTMLInputElement).value = '' - } - }} - /> - -
-
- ), - File: ({ file, ...props }: any) => ( -
-
{file?.name || 'Mock file'}
-
- {file?.size ? `${Math.round(file.size / 1024)}KB` : 'Mock size'} -
-
- ), - Markdown: ({ content, ...props }: any) => ( -
-
') || 'Mock markdown' }} /> -
- ), - ToolCall: ({ toolCall, onApprove, onReject, ...props }: any) => ( -
-
Tool Call: {toolCall?.name || 'Mock Tool'}
-
- - -
-
- ), - Typing: ({ isTyping, ...props }: any) => ( - isTyping ? ( -
- Agent is typing... -
- ) : null - ) -} - -// Mock Block Components -export const Block = { - Message: ({ message, ...props }: any) => ( -
-
Block Message
-
- {typeof message?.content === 'string' ? message.content : 'Mock block message'} -
-
- ), - Protocol: ({ protocol, ...props }: any) => ( -
-
Protocol: {protocol?.type || 'Mock Protocol'}
-
- Version: {protocol?.version || '1.0.0'} -
-
- ), - Status: ({ status, ...props }: any) => ( -
-
Status: {status?.type || 'Mock Status'}
-
- State: {status?.state || 'online'} -
-
- ), - Metadata: ({ metadata, title, ...props }: any) => ( -
-
{title || 'Metadata'}
-
-        {JSON.stringify(metadata || { mock: 'metadata' }, null, 2)}
-      
-
- ) -} - -// Mock Task Components -export const Task = ({ task, ...props }: any) => ( -
-
Task: {task?.title || 'Mock Task'}
-
- Status: {task?.status || 'pending'} -
- {task?.progress && ( -
-
-
- )} -
-) - -// Mock Agent Primitive Components -export const AgentPrimitive = { - Root: ({ children, ...props }: any) => ( -
- {children} -
- ), - Card: ({ agent, ...props }: any) => ( -
-
{agent?.name || 'Mock Agent'}
-
- {agent?.description || 'Mock agent description'} -
-
- ), - Status: ({ status, ...props }: any) => ( -
-
- {status || 'online'} -
- ), - Capabilities: ({ capabilities, ...props }: any) => ( -
-
Capabilities
-
- {(capabilities || ['Mock Capability']).map((cap: any, index: number) => ( - - {typeof cap === 'string' ? cap : cap.name} - - ))} -
-
- ) -} - -// Mock Task Primitive Components -export const TaskPrimitive = { - Root: ({ children, ...props }: any) => ( -
- {children} -
- ), - Header: ({ task, ...props }: any) => ( -
-
{task?.title || 'Mock Task'}
-
{task?.status || 'pending'}
-
- ), - Progress: ({ progress, ...props }: any) => ( -
-
-
- ), - Actions: ({ children, ...props }: any) => ( -
- {children} -
- ) -} - -// Mock Provider Components (these won't be used due to the alias, but included for completeness) -export const AgentProvider = ({ children }: { children: React.ReactNode }) => ( - - {children} - -) - -export const InputProvider = ({ children }: { children: React.ReactNode }) => ( - - {children} - -) - -export const ArtifactProvider = ({ children }: { children: React.ReactNode }) => ( - - {children} - -) - -export const CommunicationProvider = ({ children }: { children: React.ReactNode }) => ( - - {children} - -) - -// Default export for compatibility -export default { - useAgentContext, - useInputContext, - useArtifactContext, - useCommunicationContext, - Button, - Artifact, - Input, - Chat, - Block, - Task, - AgentPrimitive, - TaskPrimitive, - AgentProvider, - InputProvider, - ArtifactProvider, - CommunicationProvider -} \ No newline at end of file diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index e84c17c..0000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,59 +0,0 @@ - \ No newline at end of file diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx deleted file mode 100644 index c59bf8c..0000000 --- a/.storybook/preview.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import type { Preview } from '@storybook/react' -import React from 'react' -import './globals.css' - -// Error Boundary for Storybook -class StorybookErrorBoundary extends React.Component< - { children: React.ReactNode }, - { hasError: boolean; error?: Error } -> { - constructor(props: { children: React.ReactNode }) { - super(props) - this.state = { hasError: false } - } - - static getDerivedStateFromError(error: Error) { - return { hasError: true, error } - } - - componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { - console.error('Storybook Error Boundary caught an error:', error, errorInfo) - } - - render() { - if (this.state.hasError) { - return ( -
-

- Story Error -

-

- This story encountered an error while rendering. Check the console for details. -

-
- Error Details -
-              {this.state.error?.toString()}
-            
-
- -
- ) - } - - return this.props.children - } -} - -const preview: Preview = { - parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, - docs: { - toc: true, - }, - }, - - decorators: [ - (Story, context) => { - return ( - -
-
- -
-
-
- ) - }, - ], -} - -export default preview \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..014a09c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,257 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Repository Overview + +This is the **AgentArea UI SDK**, a protocol-agnostic React UI library for building sophisticated agent communication interfaces. The project is built as a modern TypeScript monorepo using pnpm workspaces. + +## Architecture + +### Package Structure + +- **`@agentarea/core`** (`packages/core/`) - Protocol-agnostic runtime library that handles A2A, ACP, and custom agent protocols +- **`@agentarea/react`** (`packages/react/`) - React UI components and hooks for agent interfaces +- **`apps/docs/`** - Fumadocs-based Next.js documentation site with interactive MDX examples +- **`apps/storybook/`** - Storybook for component development and visual testing +- **`examples/`** - Example implementations showing usage patterns + +### Component Architecture + +The React library follows a **primitive-first approach** inspired by Radix UI: + +``` +AgentUI (Entry Point Provider) +├── Primitives (Low-level building blocks) +│ ├── AgentPrimitive - Agent display and interaction +│ └── TaskPrimitive - Task state and lifecycle management +├── Composed Components (High-level, ready-to-use) +│ ├── Task - Complete task interface +│ ├── Chat - Messaging with markdown, files, tool calls +│ ├── Artifact - Content display (code, data, images, files) +│ ├── Input - Dynamic form generation and validation +│ └── Block - Protocol communication display +└── Hooks (State management) + ├── useTask, useAgent, useArtifacts + ├── useConnection, useRealtime + └── useRuntimeEnvironment +``` + +### Key Design Principles + +- **Task-first design**: Built for structured task workflows, not just chat +- **Protocol agnostic**: Works with A2A, ACP, or custom protocols via runtime adapters +- **Compound components**: Flexible composition patterns (e.g., `Chat.Message`, `Artifact.Code`) +- **SSR support**: Works with Next.js and other SSR frameworks +- **Real-time ready**: Built-in WebSocket support with automatic reconnection + +## Common Development Commands + +### Building and Development + +```bash +# Install dependencies +pnpm install + +# Build all packages (core builds first due to dependency) +pnpm build + +# Development with watch mode +pnpm dev + +# Build individual packages +pnpm build:core +pnpm build:react + +# Type checking +pnpm type-check +``` + +### Testing + +```bash +# Run all tests (Vitest) +pnpm test + +# Watch mode +pnpm test:watch + +# With UI +pnpm test:ui + +# Coverage report +pnpm test:coverage + +# Test the build process +pnpm test:build +``` + +### Documentation and Storybook + +```bash +# Start Storybook development server +pnpm storybook + +# Build Storybook for deployment +pnpm build-storybook + +# Start docs site (Fumadocs/Next.js) +cd apps/docs && pnpm dev + +# Build docs site +cd apps/docs && pnpm build +``` + +### Package Management + +```bash +# Clean all build artifacts +pnpm clean + +# Publish packages (dry run first) +pnpm publish:dry-run +pnpm publish:packages + +# Version bumping +pnpm version:patch +pnpm version:minor +pnpm version:major +``` + +## Development Environment + +### TypeScript Configuration + +- Uses TypeScript project references for efficient builds +- Root `tsconfig.json` only contains references to packages +- Each package has its own TypeScript configuration + +### Testing Setup + +- **Vitest** with React Testing Library for component testing +- **jsdom** environment for DOM testing +- **jest-axe** for accessibility testing +- Path aliases configured for `@agentarea/core`, `@agentarea/react`, and `@test-utils` + +### Package Dependencies + +- **Core package**: Minimal dependencies, includes `@a2a-js/sdk` +- **React package**: Depends on core, uses Radix UI primitives, Tailwind CSS utilities +- **Peer dependencies**: React 18+ required + +## Documentation Architecture + +### Fumadocs Documentation (`apps/docs/`) + +- Built with Next.js 15 and Fumadocs +- Interactive MDX examples with live component demos +- Components imported directly from `@agentarea/react` +- Real React state management in documentation examples + +### MDX Documentation Pattern + +Each component doc follows this structure: + +```mdx +--- +title: Component Name +description: Brief description +--- + +import { Component } from "@agentarea/react"; +import { useState } from "react"; + +// Description and code examples + +export function InteractiveExample() { + const [state, setState] = useState() + return +} + + +``` + +### Storybook + +- Stories located in `apps/storybook/stories/` +- Comprehensive examples including edge cases, accessibility, and performance scenarios +- Stories serve as both documentation and testing + +## Protocol Integration + +### Runtime System + +The core package provides runtime implementations: + +- **BaseRuntime**: Abstract base for all protocols +- **A2ARuntime**: Agent-to-Agent protocol implementation +- **AgentAreaRuntime**: Custom AgentArea protocol +- **RuntimeFactory**: Factory for creating and managing runtimes + +### Usage Pattern + +```tsx +// Provider wraps entire app or agent interface + + + + + +``` + +## Component Development Guidelines + +### Adding New Components + +1. Create in `packages/react/src/components/` +2. Follow compound component pattern if applicable +3. Export from `packages/react/src/index.ts` +4. Add Storybook stories in `apps/storybook/stories/` +5. Add documentation in `apps/docs/content/docs/` + +### Styling Approach + +- Built on Tailwind CSS with shadcn/ui components +- Uses `class-variance-authority` for component variants +- `tailwind-merge` for className merging +- CSS custom properties for theming + +### State Management + +- React Context for global state (agents, tasks, artifacts) +- Custom hooks for component-specific logic +- Optimistic updates for real-time interactions + +## File Testing + +- Test files use `.test.ts` or `.spec.ts` extensions +- Located alongside source files in each package +- Vitest configuration includes both `packages/**` and `test/**` directories +- Mock utilities in `test/test-utils.ts` + +## Important Notes for Development + +### Monorepo Workspace + +- Uses pnpm workspaces with `packages/*` and `apps/*` +- Workspace dependencies use `workspace:*` protocol +- Build order matters: core must build before react + +### Bundle Optimization + +- Tree-shakeable exports +- Lazy loading for specialized components +- No side effects declared in package.json +- ESM-only packages (type: "module") + +### SSR Considerations + +- SSR-safe components in `components/ssr-safe/` +- Environment detection utilities +- Graceful degradation patterns for client-only features + +### Error Handling + +- Comprehensive error boundaries for each component family +- Graceful fallbacks for protocol connection failures +- Development vs production error handling diff --git a/LICENSE b/LICENSE index 47e3db0..2c3d7df 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 AgentArea +Copyright (c) 2025 AgentArea Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/apps/a2a-nextjs/.gitignore b/apps/a2a-nextjs/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/apps/a2a-nextjs/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/a2a-nextjs/README.md b/apps/a2a-nextjs/README.md new file mode 100644 index 0000000..a7fb834 --- /dev/null +++ b/apps/a2a-nextjs/README.md @@ -0,0 +1,235 @@ +# AgentArea UI SDK - A2A Next.js Demo + +This is a comprehensive demonstration of the AgentArea UI SDK components running with Agent-to-Agent (A2A) protocol support in a Next.js application. + +## Features Demonstrated + +### Core Components +- **AgentUI Provider**: Main wrapper providing A2A runtime and configuration +- **Task Management**: Task creation, status tracking, progress monitoring +- **Chat Interface**: Real-time messaging with artifact support +- **Artifact Display**: Code, data, and file artifacts with actions +- **Debug Tools**: Runtime environment and connection monitoring + +### A2A Protocol Features +- WebSocket connection management +- Real-time task updates +- Agent communication patterns +- Protocol-agnostic runtime system + +## Demo Sections + +### 1. Connection Management +- **Endpoint Configuration**: Set custom A2A WebSocket endpoints +- **Connection Controls**: Connect/disconnect functionality +- **Status Monitoring**: Visual connection state indicators + +### 2. Task Creation & Management +- **Task Input**: Rich text area for task descriptions +- **Send Task**: Create and submit tasks to agents +- **Status Tracking**: Real-time task status updates +- **Progress Monitoring**: Visual progress indicators +- **Task Actions**: Cancel, retry, and manage tasks + +### 3. Agent Communication +- **Chat Interface**: Bi-directional messaging with agents +- **Message History**: Scrollable conversation view +- **Streaming Support**: Real-time message updates +- **Artifact Integration**: Inline artifact display in messages + +### 4. Artifact Management +- **Code Artifacts**: Syntax-highlighted code display +- **Data Artifacts**: JSON/structured data visualization +- **File Artifacts**: Document and media file handling +- **Artifact Actions**: Download, share, and preview capabilities + +### 5. Debug & Monitoring +- **Environment Info**: Runtime environment detection +- **Connection Monitor**: Active connection tracking +- **Performance Metrics**: Latency and status monitoring +- **Development Tools**: Debug panel for troubleshooting + +## Getting Started + +### Prerequisites +- Node.js 18+ and pnpm +- AgentArea UI SDK packages (workspace dependencies) + +### Installation & Setup +```bash +# Install dependencies (from project root) +pnpm install + +# Build the required packages +pnpm build + +# Start the demo +cd apps/a2a-nextjs +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +### Configuration +1. **A2A Endpoint**: Configure your Agent-to-Agent WebSocket endpoint +2. **Authentication**: Set up authentication credentials if required +3. **Debug Mode**: Enable debug tools for development + +## Usage Examples + +### Basic Task Creation +```tsx +import { AgentUI, Task } from "@agentarea/react"; + +function TaskDemo() { + return ( + + + Create Task + + ); +} +``` + +### Chat with Artifacts +```tsx +import { AgentUI, Chat, Artifact } from "@agentarea/react"; + +function ChatDemo() { + return ( + + + + Here's your analysis result. + + + + + ); +} +``` + +### Connection Monitoring +```tsx +import { AgentUI } from "@agentarea/react"; + +function MonitorDemo() { + return ( + + + + + ); +} +``` + +## Development + +### Project Structure +``` +apps/a2a-nextjs/ +├── src/ +│ └── app/ +│ ├── page.tsx # Main demo page +│ ├── layout.tsx # App layout +│ └── globals.css # Global styles +├── package.json # Dependencies +└── README.md # This file +``` + +### Key Dependencies +- `@agentarea/core`: Protocol-agnostic runtime +- `@agentarea/react`: React UI components +- `next`: Next.js framework +- `tailwindcss`: Styling + +### Available Scripts +- `pnpm dev`: Start development server +- `pnpm build`: Build for production +- `pnpm start`: Start production server +- `pnpm lint`: Run ESLint + +## Architecture + +### Component Hierarchy +``` +AgentUI (Provider) +├── Task Components +│ ├── Task.Input +│ ├── Task.Send +│ ├── Task.Status +│ └── Task.Progress +├── Chat Components +│ ├── Chat.Root +│ ├── Chat.Message +│ ├── Chat.Content +│ └── Chat.Input +├── Artifact Components +│ ├── Artifact.Container +│ ├── Artifact.Code +│ └── Artifact.Data +└── Debug Components + ├── AgentUI.Connection + └── AgentUI.Debug +``` + +### Runtime System +- **A2A Runtime**: Handles Agent-to-Agent protocol communication +- **Connection Management**: WebSocket connection lifecycle +- **Task Management**: Task creation, tracking, and updates +- **Real-time Updates**: Live data synchronization + +## Customization + +### Styling +The demo uses Tailwind CSS for styling. Customize by: +- Modifying `globals.css` for global styles +- Adding custom component classes +- Using Tailwind utilities for quick styling + +### Protocol Configuration +Configure A2A protocol settings: +```tsx + +``` + +### Theme Support +The demo supports light/dark themes: +```tsx + // 'light' | 'dark' | 'system' +``` + +## Troubleshooting + +### Common Issues +1. **Connection Failed**: Check endpoint URL and network connectivity +2. **Components Not Rendering**: Ensure packages are built and imported correctly +3. **WebSocket Errors**: Verify A2A endpoint supports required protocols + +### Debug Tools +- Enable debug mode: `` +- Use browser dev tools for network monitoring +- Check console for runtime errors and warnings + +## Next Steps + +This demo provides a foundation for building A2A-enabled applications. Consider: +- Adding real agent endpoints +- Implementing authentication flows +- Creating custom artifact types +- Building specialized task templates +- Adding persistent storage +- Implementing error handling strategies + +## Support + +For issues, feature requests, or questions: +- Check the main project documentation +- Review component source code in `packages/react/src/` +- Open issues in the project repository diff --git a/apps/a2a-nextjs/eslint.config.mjs b/apps/a2a-nextjs/eslint.config.mjs new file mode 100644 index 0000000..c85fb67 --- /dev/null +++ b/apps/a2a-nextjs/eslint.config.mjs @@ -0,0 +1,16 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), +]; + +export default eslintConfig; diff --git a/apps/a2a-nextjs/next.config.ts b/apps/a2a-nextjs/next.config.ts new file mode 100644 index 0000000..4d89b9f --- /dev/null +++ b/apps/a2a-nextjs/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + transpilePackages: ['@agentarea/core', '@agentarea/react', '@agentarea/styles'], +}; + +export default nextConfig; diff --git a/apps/a2a-nextjs/package.json b/apps/a2a-nextjs/package.json new file mode 100644 index 0000000..d46adfd --- /dev/null +++ b/apps/a2a-nextjs/package.json @@ -0,0 +1,30 @@ +{ + "name": "a2a-nextjs", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "react": "19.1.0", + "react-dom": "19.1.0", + "next": "15.4.2", + "@agentarea/core": "workspace:*", + "@agentarea/react": "workspace:*", + "@agentarea/styles": "workspace:*" + }, + "devDependencies": { + "typescript": "^5", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "@tailwindcss/postcss": "^4", + "tailwindcss": "^4", + "eslint": "^9", + "eslint-config-next": "15.4.2", + "@eslint/eslintrc": "^3" + } +} diff --git a/apps/a2a-nextjs/postcss.config.mjs b/apps/a2a-nextjs/postcss.config.mjs new file mode 100644 index 0000000..c7bcb4b --- /dev/null +++ b/apps/a2a-nextjs/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/apps/a2a-nextjs/public/file.svg b/apps/a2a-nextjs/public/file.svg new file mode 100644 index 0000000..004145c --- /dev/null +++ b/apps/a2a-nextjs/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/a2a-nextjs/public/globe.svg b/apps/a2a-nextjs/public/globe.svg new file mode 100644 index 0000000..567f17b --- /dev/null +++ b/apps/a2a-nextjs/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/a2a-nextjs/public/next.svg b/apps/a2a-nextjs/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/apps/a2a-nextjs/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/a2a-nextjs/public/vercel.svg b/apps/a2a-nextjs/public/vercel.svg new file mode 100644 index 0000000..7705396 --- /dev/null +++ b/apps/a2a-nextjs/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/a2a-nextjs/public/window.svg b/apps/a2a-nextjs/public/window.svg new file mode 100644 index 0000000..b2b2a44 --- /dev/null +++ b/apps/a2a-nextjs/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/a2a-nextjs/src/app/.well-known/agent-card.json/route.ts b/apps/a2a-nextjs/src/app/.well-known/agent-card.json/route.ts new file mode 100644 index 0000000..85d4188 --- /dev/null +++ b/apps/a2a-nextjs/src/app/.well-known/agent-card.json/route.ts @@ -0,0 +1,27 @@ +export async function GET(req: Request) { + const origin = new URL(req.url).origin + + const agentCard = { + name: "Mock A2A Agent", + description: "Local mock agent implementing minimal A2A surfaces for development/testing", + capabilities: [ + { + name: "task-submission", + description: "Submit a text prompt and receive a mock response", + inputTypes: ["message"], + outputTypes: ["message"], + }, + { + name: "message-sending", + description: "Send generic A2A messages via message.send", + inputTypes: ["message"], + outputTypes: ["message"], + }, + ], + endpoints: { main: origin }, + streaming: false, + pushNotifications: false, + } + + return Response.json(agentCard) +} \ No newline at end of file diff --git a/apps/a2a-nextjs/src/app/.well-known/agent.json/route.ts b/apps/a2a-nextjs/src/app/.well-known/agent.json/route.ts new file mode 100644 index 0000000..2392fac --- /dev/null +++ b/apps/a2a-nextjs/src/app/.well-known/agent.json/route.ts @@ -0,0 +1,31 @@ +export async function GET(req: Request) { + const origin = new URL(req.url).origin + + const agent = { + name: "Mock A2A Agent", + description: "Local mock agent (agent.json) for A2A discovery fallback", + url: origin, + defaultInputModes: ["message"], + defaultOutputModes: ["message"], + skills: [ + { + name: "task-submission", + description: "Submit a text prompt and receive a mock response", + defaultInputModes: ["message"], + defaultOutputModes: ["message"], + }, + { + name: "message-sending", + description: "Send generic A2A messages via message.send", + defaultInputModes: ["message"], + defaultOutputModes: ["message"], + }, + ], + capabilities: { + streaming: false, + pushNotifications: false, + }, + } + + return Response.json(agent) +} \ No newline at end of file diff --git a/apps/a2a-nextjs/src/app/favicon.ico b/apps/a2a-nextjs/src/app/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/apps/a2a-nextjs/src/app/favicon.ico differ diff --git a/apps/a2a-nextjs/src/app/globals.css b/apps/a2a-nextjs/src/app/globals.css new file mode 100644 index 0000000..ac8e513 --- /dev/null +++ b/apps/a2a-nextjs/src/app/globals.css @@ -0,0 +1,4 @@ +/* Custom app styles */ +body { + font-family: Arial, Helvetica, sans-serif; +} diff --git a/apps/a2a-nextjs/src/app/layout.tsx b/apps/a2a-nextjs/src/app/layout.tsx new file mode 100644 index 0000000..7c48f86 --- /dev/null +++ b/apps/a2a-nextjs/src/app/layout.tsx @@ -0,0 +1,35 @@ +'use client' + +import { Geist, Geist_Mono } from "next/font/google"; +import '@agentarea/styles/index.css'; +import '@agentarea/styles/components.css'; +import "./globals.css"; +import { AgentProvider } from '@agentarea/react'; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + {children} + + + + ); +} diff --git a/apps/a2a-nextjs/src/app/page.tsx b/apps/a2a-nextjs/src/app/page.tsx new file mode 100644 index 0000000..afe1a7f --- /dev/null +++ b/apps/a2a-nextjs/src/app/page.tsx @@ -0,0 +1,676 @@ +"use client"; + +import React, { useMemo, useState, useEffect, useCallback } from "react"; +import { AgentUI, Task, Chat, Artifact, MultiAgent, useTaskList, TaskGraphNode, TimelineEvent, LogEntry } from "@agentarea/react"; +import { createRuntimeFactory, A2ARuntime, type RestEndpointMapping } from "@agentarea/core"; +import { useTask, useTaskCreation } from "@agentarea/react"; + +interface ComplianceIssue { + severity: "error" | "warning" | "info"; + code: string; + message: string; + recommendation?: string; +} + +interface ComplianceResult { + compliant: boolean; + version: string; + supportedFeatures: string[]; + issues?: ComplianceIssue[]; +} + +interface Capability { + name: string; + description?: string; + inputTypes?: string[]; + outputTypes?: string[]; +} + +interface AgentCard { + name: string; + description?: string; + capabilities: Capability[]; + streaming?: boolean; + pushNotifications?: boolean; +} + +// Type-safe helpers to parse unknown JSON without using 'any' +const isRecord = (v: unknown): v is Record => typeof v === "object" && v !== null; +const getString = (v: unknown): string | undefined => (typeof v === "string" ? v : undefined); +const getBool = (v: unknown): boolean | undefined => (typeof v === "boolean" ? v : undefined); +const getStringArray = (v: unknown): string[] | undefined => + Array.isArray(v) && v.every((x) => typeof x === "string") ? (v as string[]) : undefined; + +// Small helper: validate HTTP/HTTPS URL +const isValidHttpUrl = (value: string): boolean => { + try { + const u = new URL(value); + return u.protocol === "http:" || u.protocol === "https:"; + } catch { + return false; + } +}; + +// Helper to extract a human-readable error message from unknown errors without using 'any' +const getErrorMessage = (e: unknown, fallback = "An error occurred"): string => { + if (e instanceof Error && typeof e.message === "string") return e.message; + if (isRecord(e)) { + const msg = getString(e.message); + if (msg) return msg; + } + try { + return JSON.stringify(e); + } catch { + return fallback; + } +}; + +function mapAgentCardFromData(data: unknown): AgentCard { + const obj = isRecord(data) ? data : {}; + const name = getString(obj["name"]) ?? "Custom Agent"; + const description = getString(obj["description"]) ?? "Agent from custom endpoint"; + const defaultInputModes = getStringArray(obj["defaultInputModes"]); + const defaultOutputModes = getStringArray(obj["defaultOutputModes"]); + + let capabilities: Capability[] = []; + const skillsVal = obj["skills"]; + if (Array.isArray(skillsVal)) { + capabilities = skillsVal.map((skill): Capability => { + const so = isRecord(skill) ? skill : {}; + const capName = getString(so["name"]) ?? "Custom Capability"; + const capDesc = getString(so["description"]); + const inputTypes = getStringArray(so["defaultInputModes"]) ?? defaultInputModes ?? ["message"]; + const outputTypes = getStringArray(so["defaultOutputModes"]) ?? defaultOutputModes ?? ["message"]; + return { name: capName, description: capDesc, inputTypes, outputTypes }; + }); + } else { + const capsVal = obj["capabilities"]; + if (Array.isArray(capsVal)) { + capabilities = capsVal.map((cap): Capability => { + const co = isRecord(cap) ? cap : {}; + const capName = getString(co["name"]) ?? "Capability"; + const capDesc = getString(co["description"]); + const inputTypes = getStringArray(co["inputTypes"]); + const outputTypes = getStringArray(co["outputTypes"]); + return { name: capName, description: capDesc, inputTypes, outputTypes }; + }); + } + } + + let streaming = false; + let pushNotifications = false; + const capsField = obj["capabilities"]; + if (isRecord(capsField)) { + streaming = getBool(capsField["streaming"]) ?? false; + pushNotifications = getBool(capsField["pushNotifications"]) ?? false; + } + + return { name, description, capabilities, streaming, pushNotifications }; +} + +export default function Home() { + // UI State Management + type UIPhase = 'setup' | 'task-entry' | 'task-sent' | 'agent-working' | 'communication'; + const [currentPhase, setCurrentPhase] = useState('setup'); + + // Existing state + const [taskId, setTaskId] = useState(undefined); + const [taskInput, setTaskInput] = useState(""); + const [endpoint, setEndpoint] = useState("http://localhost:5055"); + const [isConnected, setIsConnected] = useState(false); + const [additionalHeaders, setAdditionalHeaders] = useState>({}); + + // A2A Debugger state + const [detectedProtocol, setDetectedProtocol] = useState(null); + const [agentCard, setAgentCard] = useState(null); + const [compliance, setCompliance] = useState(null); + const [validating, setValidating] = useState(false); + const [validationError, setValidationError] = useState(null); + + // Prevent hydration mismatch for components that format dates/times locally + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); + const normalizedEndpoint = useMemo(() => { + let url = endpoint.trim(); + if (url.startsWith("ws://")) { + url = "http://" + url.slice(5); + } else if (url.startsWith("wss://")) { + url = "https://" + url.slice(6); + } + if (url.endsWith("/")) { + url = url.slice(0, -1); + } + return url; + }, [endpoint]); + const isUrlValid = useMemo(() => isValidHttpUrl(normalizedEndpoint), [normalizedEndpoint]); + + // Consider the endpoint verified if URL is valid and compliance reports compliant + const isVerified = useMemo(() => { + if (!isUrlValid) return false; + if (compliance) return !!compliance.compliant; + return false; + }, [isUrlValid, compliance]); + + // Create a configured A2A runtime instance using JSON-REST transport with A2A endpoint mapping + const configuredRuntime = useMemo(() => { + const factory = createRuntimeFactory(); + const endpointMapping: RestEndpointMapping = { + 'message.send': { + path: '/a2a/message.send', + method: 'POST' as const, + paramMapping: 'body' as const + }, + 'task.get': { + path: '/a2a/task.get', + method: 'POST' as const, + paramMapping: 'body' as const + }, + 'task.cancel': { + path: '/a2a/task.cancel', + method: 'POST' as const, + paramMapping: 'body' as const + } + }; + return factory.createRuntime("a2a", { + endpoint: normalizedEndpoint, + authentication: { + type: 'none' + }, + transport: { + type: "json-rest", + config: { + baseURL: normalizedEndpoint, + timeout: 30000, + }, + endpointMapping: endpointMapping + }, + // Use default agent card resolver; add custom fallback fetch in validation below + }); + }, [normalizedEndpoint]); + + const handleTaskInputChange = useCallback((e: React.ChangeEvent) => { + setTaskInput(e.target.value); + }, []); + + // Helper to add/update headers + const handleHeaderChange = useCallback((key: string, value: string) => { + setAdditionalHeaders(prev => { + if (value.trim() === '') { + const { [key]: _, ...rest } = prev; + return rest; + } + return { ...prev, [key]: value }; + }); + }, []); + + const handleAddHeader = useCallback(() => { + const key = `header-${Date.now()}`; + setAdditionalHeaders(prev => ({ ...prev, [key]: '' })); + }, []); + + // A2A-compliant connect: discover agent card via well-known endpoints, validate compliance, then connect + const handleConnect = useCallback(async () => { + try { + if (isConnected) { + setIsConnected(false); + setCurrentPhase('setup'); + return; + } + if (!isUrlValid || validating) return; + + setValidating(true); + setValidationError(null); + setDetectedProtocol(null); + setCompliance(null); + setAgentCard(null); + + // Create headers object including additional headers + const headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + ...additionalHeaders + }; + + // Attempt to detect protocol (may fail or be non-A2A for custom endpoints) + const factory = createRuntimeFactory(); + try { + const protocol = await factory.detectProtocol(normalizedEndpoint); + setDetectedProtocol(protocol); + } catch (e) { + console.warn("Protocol detection failed, assuming A2A:", e); + setDetectedProtocol("a2a"); + } + + // Discover agent card + const candidates = [ + `${normalizedEndpoint}/.well-known/agent-card.json`, + `${normalizedEndpoint}/.well-known/agent.json`, + `${normalizedEndpoint}/agent-card`, + ]; + + let foundCard: AgentCard | null = null; + for (const url of candidates) { + try { + const res = await fetch(url, { headers }); + if (res.ok) { + const data = await res.json(); + const mapped = mapAgentCardFromData(data); + if (mapped && mapped.name) { + foundCard = mapped; + break; + } + } + } catch (e) { + // continue trying next candidate + } + } + + if (!foundCard) { + throw new Error("No agent card found at well-known endpoints. Ensure your agent exposes agent-card.json at /.well-known/agent-card.json or /agent-card"); + } + + setAgentCard(foundCard); + + // Validate A2A compliance + const a2a = configuredRuntime as unknown as A2ARuntime; + let comp: ComplianceResult | null = null; + try { + comp = (await a2a.validateA2ACompliance(normalizedEndpoint)) as ComplianceResult; + if (comp) setCompliance(comp); + } catch (e) { + console.warn("A2A compliance validation failed:", e); + // Set basic compliance info based on successful agent card discovery + comp = { + compliant: true, + version: "unknown", + supportedFeatures: [], + issues: [{ severity: "warning", code: "COMPLIANCE_CHECK_FAILED", message: "Could not validate full A2A compliance" }] + }; + setCompliance(comp); + } + + if (comp?.compliant) { + setIsConnected(true); + + // If we have a task input, move to task entry phase + if (taskInput.trim()) { + setCurrentPhase('task-entry'); + } else { + setCurrentPhase('task-entry'); + } + } else { + setIsConnected(false); + throw new Error("Endpoint failed A2A compliance"); + } + } catch (e) { + setValidationError(getErrorMessage(e, "Failed to connect")); + } finally { + setValidating(false); + } + }, [isConnected, isUrlValid, validating, normalizedEndpoint, configuredRuntime, additionalHeaders, taskInput]); + + // Real multiagent system data - no mock data + + // Track latest created/updated taskId from AgentUI context (must be inside provider) + const TaskIdTracker = React.memo(function TaskIdTracker(props: { onChange: (id: string) => void }) { + const { tasks } = useTaskList(); + useEffect(() => { + if (tasks.length > 0) { + props.onChange(tasks[0].id); + } + }, [tasks, props.onChange]); + return null; + }); + + return ( +
+
+ {/* Header */} +
+

+ AgentArea UI SDK - A2A Debugger +

+

+ Connect to any A2A-compatible agent by its HTTP/HTTPS base URL, validate protocol compatibility, inspect capabilities, and send tasks. +

+ + {/* Connection Controls */} +
+
+
+ + setEndpoint(e.target.value)} + className="w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary" + placeholder="https://your-agent.example.com" + /> + {(endpoint.startsWith("ws://") || endpoint.startsWith("wss://")) && ( +

+ Detected WebSocket scheme. A2A endpoints should be HTTP/HTTPS. Converted to {normalizedEndpoint} +

+ )} + {!isUrlValid && endpoint.trim().length > 0 && ( +

Please enter a valid HTTP/HTTPS URL

+ )} +
+
+ +
+
+ + {/* Additional Headers Configuration */} +
+

Additional Headers

+

Configure custom headers for A2A agent requests

+
+ {Object.entries(additionalHeaders).map(([key, value]) => ( +
+ { + const newKey = e.target.value || key; + const { [key]: oldValue, ...rest } = additionalHeaders; + setAdditionalHeaders({ ...rest, [newKey]: value }); + }} + className="flex-1 px-3 py-1 text-sm border border-border rounded bg-background" + /> + handleHeaderChange(key, e.target.value)} + className="flex-1 px-3 py-1 text-sm border border-border rounded bg-background" + /> + +
+ ))} + +
+
+ + {/* Connection Status */} +
+
+ + {isConnected ? `Connected to ${normalizedEndpoint}` : "Disconnected"} + +
+
+ + {/* Validation Results - Compact Design */} + {isConnected && ( +
+
+

Connection Details

+
+ +
+ Protocol: {detectedProtocol || "Unknown"} + + +
+ A2A v{compliance?.version || "?"} + +
+
+ +
+ {/* Agent Info */} +
+
+

Agent

+ {agentCard && ( + + {agentCard.capabilities?.length || 0} capabilities + + )} +
+ {agentCard ? ( +
+

{agentCard.name}

+ {agentCard.description && ( +

{agentCard.description}

+ )} +
+ Streaming: {agentCard.streaming ? "✓" : "✗"} + Push: {agentCard.pushNotifications ? "✓" : "✗"} +
+
+ ) : ( +

No agent info available

+ )} +
+ + {/* Compliance & Features */} +
+

Status & Features

+ {compliance ? ( +
+ {compliance.supportedFeatures?.length > 0 && ( +
+

Features:

+
+ {compliance.supportedFeatures.slice(0, 4).map((f) => ( + {f} + ))} + {compliance.supportedFeatures.length > 4 && ( + +{compliance.supportedFeatures.length - 4} more + )} +
+
+ )} + {compliance.issues && compliance.issues.length > 0 && ( +
+

Issues:

+
+ {compliance.issues.slice(0, 2).map((i) => ( +

+ {i.code}: {i.message} +

+ ))} + {compliance.issues.length > 2 && ( +

+{compliance.issues.length - 2} more issues

+ )} +
+
+ )} +
+ ) : ( +

Compliance check pending

+ )} +
+
+
+ )} + + {validationError && ( +
+

{validationError}

+
+ )} +
+ + {/* Main Content */} + + {/* Track latest task id from context */} + { + setTaskId((prev) => { + if (prev !== id) { + setTaskInput(""); + setCurrentPhase('agent-working'); + } + return id; + }); + }, [])} + /> + + {/* Phase-based UI Rendering */} + {currentPhase === 'setup' && ( +
+

Connect to Agent

+

Enter your agent endpoint above and validate the connection to get started.

+
+ )} + + {currentPhase === 'task-entry' && ( +
+
+

+ Create Task +

+
+ +
+ { + setCurrentPhase('task-sent'); + }} + > + Send Task + +
+ {!isVerified && ( +

Validate the endpoint to enable task sending.

+ )} +
+
+
+ )} + + {currentPhase === 'task-sent' && ( +
+

Task Sent

+

Your task has been sent to the agent. Waiting for response...

+
+
+ )} + + {(currentPhase === 'agent-working' || currentPhase === 'communication') && taskId && ( +
+ {/* Task Management Section */} +
+ {/* Left Column - Task Status & Control */} +
+
+

+ Task Management +

+
+ + +
+ Cancel + Retry +
+
+
+ + {/* Artifacts Section */} +
+

Artifacts

+ +
+
+ + {/* Right Column - Communication */} +
+
+

Agent Communication

+ +
+
+
+ + {/* MultiAgent System Components */} +
+ {/* Task Graph - Shows agent collaboration */} +
+

Task Orchestration

+ +
+ + {/* Timeline - Shows real-time events */} +
+

System Timeline

+ +
+ + {/* System Logs - Shows agent activity */} +
+

System Logs

+ +
+
+ + {/* Agent Network Visualization */} +
+

Agent Network

+

Real-time visualization of agent interactions and task delegation

+
+ Agent network visualization will be implemented with real multiagent system data +
+
+
+ )} +
+
+
+ ); +} diff --git a/apps/a2a-nextjs/tailwind.config.ts b/apps/a2a-nextjs/tailwind.config.ts new file mode 100644 index 0000000..65fe62a --- /dev/null +++ b/apps/a2a-nextjs/tailwind.config.ts @@ -0,0 +1,55 @@ +import type { Config } from 'tailwindcss' + +const config: Config = { + content: [ + './src/app/**/*.{ts,tsx,mdx}', + '../../packages/react/src/**/*.{ts,tsx}', + ], + theme: { + extend: { + colors: { + border: "hsl(var(--agentarea-border))", + input: "hsl(var(--agentarea-input))", + ring: "hsl(var(--agentarea-ring))", + background: "hsl(var(--agentarea-background))", + foreground: "hsl(var(--agentarea-foreground))", + primary: { + DEFAULT: "hsl(var(--agentarea-primary))", + foreground: "hsl(var(--agentarea-primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--agentarea-secondary))", + foreground: "hsl(var(--agentarea-secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--agentarea-destructive))", + foreground: "hsl(var(--agentarea-destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--agentarea-muted))", + foreground: "hsl(var(--agentarea-muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--agentarea-accent))", + foreground: "hsl(var(--agentarea-accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--agentarea-popover))", + foreground: "hsl(var(--agentarea-popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--agentarea-card))", + foreground: "hsl(var(--agentarea-card-foreground))", + }, + }, + borderRadius: { + lg: 'var(--agentarea-radius)', + md: 'calc(var(--agentarea-radius) - 2px)', + sm: 'calc(var(--agentarea-radius) - 4px)', + }, + }, + }, + plugins: [], +} + +export default config; \ No newline at end of file diff --git a/apps/a2a-nextjs/tsconfig.json b/apps/a2a-nextjs/tsconfig.json new file mode 100644 index 0000000..01221b0 --- /dev/null +++ b/apps/a2a-nextjs/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"], + "@agentarea/core": ["../../packages/core/src"], + "@agentarea/react": ["../../packages/react/src"], + "@agentarea/react/*": ["../../packages/react/src/*"] + }, + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/apps/chat-vite/.gitignore b/apps/chat-vite/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/apps/chat-vite/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/apps/chat-vite/README.md b/apps/chat-vite/README.md new file mode 100644 index 0000000..7959ce4 --- /dev/null +++ b/apps/chat-vite/README.md @@ -0,0 +1,69 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default tseslint.config([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + ...tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + ...tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + ...tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default tseslint.config([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/apps/chat-vite/eslint.config.js b/apps/chat-vite/eslint.config.js new file mode 100644 index 0000000..d94e7de --- /dev/null +++ b/apps/chat-vite/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { globalIgnores } from 'eslint/config' + +export default tseslint.config([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/apps/chat-vite/index.html b/apps/chat-vite/index.html new file mode 100644 index 0000000..e4b78ea --- /dev/null +++ b/apps/chat-vite/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/apps/chat-vite/package.json b/apps/chat-vite/package.json new file mode 100644 index 0000000..2119157 --- /dev/null +++ b/apps/chat-vite/package.json @@ -0,0 +1,31 @@ +{ + "name": "chat-vite", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.1.0", + "react-dom": "^19.1.0", + "@agentarea/core": "workspace:*", + "@agentarea/react": "workspace:*" + }, + "devDependencies": { + "@eslint/js": "^9.30.1", + "@types/react": "^19.1.8", + "@types/react-dom": "^19.1.6", + "@vitejs/plugin-react-swc": "^3.10.2", + "eslint": "^9.30.1", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.35.1", + "vite": "^7.0.4" + } +} diff --git a/apps/chat-vite/public/vite.svg b/apps/chat-vite/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/apps/chat-vite/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/chat-vite/src/App.css b/apps/chat-vite/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/apps/chat-vite/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/apps/chat-vite/src/App.tsx b/apps/chat-vite/src/App.tsx new file mode 100644 index 0000000..3d7ded3 --- /dev/null +++ b/apps/chat-vite/src/App.tsx @@ -0,0 +1,35 @@ +import { useState } from 'react' +import reactLogo from './assets/react.svg' +import viteLogo from '/vite.svg' +import './App.css' + +function App() { + const [count, setCount] = useState(0) + + return ( + <> + +

Vite + React

+
+ +

+ Edit src/App.tsx and save to test HMR +

+
+

+ Click on the Vite and React logos to learn more +

+ + ) +} + +export default App diff --git a/apps/chat-vite/src/assets/react.svg b/apps/chat-vite/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/apps/chat-vite/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/chat-vite/src/index.css b/apps/chat-vite/src/index.css new file mode 100644 index 0000000..08a3ac9 --- /dev/null +++ b/apps/chat-vite/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/apps/chat-vite/src/main.tsx b/apps/chat-vite/src/main.tsx new file mode 100644 index 0000000..bef5202 --- /dev/null +++ b/apps/chat-vite/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/apps/chat-vite/src/vite-env.d.ts b/apps/chat-vite/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/apps/chat-vite/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/apps/chat-vite/tsconfig.app.json b/apps/chat-vite/tsconfig.app.json new file mode 100644 index 0000000..227a6c6 --- /dev/null +++ b/apps/chat-vite/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/apps/chat-vite/tsconfig.json b/apps/chat-vite/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/apps/chat-vite/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/apps/chat-vite/tsconfig.node.json b/apps/chat-vite/tsconfig.node.json new file mode 100644 index 0000000..f85a399 --- /dev/null +++ b/apps/chat-vite/tsconfig.node.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/apps/chat-vite/vite.config.ts b/apps/chat-vite/vite.config.ts new file mode 100644 index 0000000..2328e17 --- /dev/null +++ b/apps/chat-vite/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/apps/docs b/apps/docs new file mode 160000 index 0000000..13f7279 --- /dev/null +++ b/apps/docs @@ -0,0 +1 @@ +Subproject commit 13f7279ba85d1c5dc3d6c06c920d5f3dfd61761d diff --git a/package.json b/package.json index d1994df..9898500 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,19 @@ "description": "Protocol-agnostic agent communication library", "private": true, "scripts": { - "build": "tsc --build", + "build": "pnpm build:styles && tsc --build", "build:core": "pnpm --filter @agentarea/core build", "build:react": "pnpm --filter @agentarea/react build", - "clean": "tsc --build --clean && pnpm -r clean", + "build:styles": "pnpm --filter @agentarea/styles build", + "clean": "pnpm -r clean && tsc --build --clean", + "clean:all": "pnpm clean && rm -rf node_modules && pnpm -r exec -- rm -rf node_modules", + "clean:deps": "rm -rf node_modules && pnpm -r exec -- rm -rf node_modules", "dev": "pnpm -r dev", + "dev:a2a-nextjs": "pnpm --filter @agentarea/styles build:css && turbo run dev --filter=a2a-nextjs", + "turbo:build": "turbo run build", + "turbo:dev": "turbo run dev --parallel", + "turbo:test": "turbo run test", + "turbo:type-check": "turbo run type-check", "type-check": "tsc --build --dry", "lint": "echo \"Linting not configured yet\"", "test": "vitest run", @@ -40,6 +48,7 @@ "devDependencies": { "@agentarea/core": "workspace:*", "@agentarea/react": "workspace:*", + "@agentarea/styles": "workspace:*", "@storybook/addon-essentials": "^8.6.14", "@storybook/addon-interactions": "^8.6.14", "@storybook/addon-links": "^8.6.14", @@ -65,6 +74,7 @@ "storybook": "^8.6.14", "tailwindcss": "^3.4.17", "tailwindcss-animate": "^1.0.7", + "turbo": "^2.5.6", "typescript": "^5.8.3", "vite": "^6.0.7", "vitest": "^2.1.8" @@ -76,5 +86,6 @@ "bugs": { "url": "https://github.com/agentarea-hq/agentarea-ui-sdk/issues" }, - "homepage": "https://github.com/agentarea-hq/agentarea-ui-sdk#readme" + "homepage": "https://github.com/agentarea-hq/agentarea-ui-sdk#readme", + "packageManager": "pnpm@10.12.4" } \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json index a41b627..2384b70 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -23,7 +23,7 @@ "scripts": { "build": "pnpm clean && tsc", "dev": "tsc --watch", - "clean": "rm -rf dist", + "clean": "rm -rf dist tsconfig.tsbuildinfo", "type-check": "tsc --noEmit", "prepublishOnly": "pnpm build" }, diff --git a/packages/core/src/agent-card/index.ts b/packages/core/src/agent-card/index.ts new file mode 100644 index 0000000..ad62a4b --- /dev/null +++ b/packages/core/src/agent-card/index.ts @@ -0,0 +1,284 @@ +// Agent Card resolver system for A2A protocol +// Supports various discovery methods including well-known endpoints, custom resolvers, and registries + +import type { AgentCard } from '../types' + +// Agent Card resolver configuration +export interface AgentCardResolverConfig { + type: 'well-known' | 'custom-endpoint' | 'registry' | 'static' | 'function' | 'multi' + endpoint?: string + fallbackEndpoints?: string[] + timeout?: number + retries?: number + transform?: AgentCardTransform + auth?: { + type: 'bearer' | 'api-key' | 'basic' + token?: string + apiKey?: string + username?: string + password?: string + } +} + +// Function to transform raw agent card data +export interface AgentCardTransform { + (rawData: any): AgentCard +} + +// Agent Card resolver interface +export interface AgentCardResolver { + readonly type: string + resolve(url: string): Promise + configure(config: Partial): void + getConfig(): AgentCardResolverConfig +} + +// Base resolver implementation +export abstract class BaseAgentCardResolver implements AgentCardResolver { + protected config: AgentCardResolverConfig + + constructor(config: AgentCardResolverConfig) { + this.config = { ...config } + } + + abstract readonly type: string + abstract resolve(url: string): Promise + + configure(config: Partial): void { + this.config = { ...this.config, ...config } + } + + getConfig(): AgentCardResolverConfig { + return { ...this.config } + } + + protected async fetchJson(url: string): Promise { + const headers: Record = { + 'Accept': 'application/json', + 'User-Agent': 'AgentArea-UI-SDK/2.0' + } + + // Add authentication + if (this.config.auth) { + switch (this.config.auth.type) { + case 'bearer': + if (this.config.auth.token) { + headers['Authorization'] = `Bearer ${this.config.auth.token}` + } + break + case 'api-key': + if (this.config.auth.apiKey) { + headers['X-API-Key'] = this.config.auth.apiKey + } + break + case 'basic': + if (this.config.auth.username && this.config.auth.password) { + const credentials = btoa(`${this.config.auth.username}:${this.config.auth.password}`) + headers['Authorization'] = `Basic ${credentials}` + } + break + } + } + + const controller = new AbortController() + const timeout = this.config.timeout || 10000 + const timeoutId = setTimeout(() => controller.abort(), timeout) + + try { + const response = await fetch(url, { + method: 'GET', + headers, + signal: controller.signal + }) + + clearTimeout(timeoutId) + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`) + } + + return await response.json() + } catch (error) { + clearTimeout(timeoutId) + throw error + } + } + + protected transformAgentCard(rawData: any): AgentCard { + if (this.config.transform) { + return this.config.transform(rawData) + } + + // Default transformation - assume A2A standard format + return { + name: rawData.name || 'Unknown Agent', + description: rawData.description || '', + capabilities: rawData.skills?.map((skill: any) => ({ + name: skill.name, + description: skill.description, + inputTypes: skill.defaultInputModes || rawData.defaultInputModes || [], + outputTypes: skill.defaultOutputModes || rawData.defaultOutputModes || [] + })) || rawData.capabilities || [], + endpoints: { main: rawData.url || rawData.endpoint }, + streaming: rawData.capabilities?.streaming || false, + pushNotifications: rawData.capabilities?.pushNotifications || false, + } + } +} + +// Well-known endpoint resolver (/.well-known/agent-card.json) +export class WellKnownAgentCardResolver extends BaseAgentCardResolver { + readonly type = 'well-known' + + async resolve(url: string): Promise { + const wellKnownUrl = this.buildWellKnownUrl(url) + + try { + const rawData = await this.fetchJson(wellKnownUrl) + return this.transformAgentCard(rawData) + } catch (error) { + throw new Error(`Failed to resolve agent card from well-known endpoint: ${(error as Error).message}`) + } + } + + private buildWellKnownUrl(baseUrl: string): string { + const url = new URL(baseUrl) + return `${url.protocol}//${url.host}/.well-known/agent-card.json` + } +} + +// Custom endpoint resolver +export class CustomEndpointAgentCardResolver extends BaseAgentCardResolver { + readonly type = 'custom-endpoint' + + async resolve(url: string): Promise { + const endpoint = this.config.endpoint || `${url}/agent-card` + + try { + const rawData = await this.fetchJson(endpoint) + return this.transformAgentCard(rawData) + } catch (error) { + throw new Error(`Failed to resolve agent card from custom endpoint: ${(error as Error).message}`) + } + } +} + +// Static agent card resolver (for testing or offline scenarios) +export class StaticAgentCardResolver extends BaseAgentCardResolver { + readonly type = 'static' + private staticCard: AgentCard + + constructor(config: AgentCardResolverConfig, agentCard: AgentCard) { + super(config) + this.staticCard = agentCard + } + + async resolve(url: string): Promise { + // Return static card with URL updated + return { + ...this.staticCard, + endpoints: { ...this.staticCard.endpoints, main: url }, + } + } +} + +// Function-based resolver for custom logic +export class FunctionAgentCardResolver extends BaseAgentCardResolver { + readonly type = 'function' + private resolverFunction: (url: string) => Promise + + constructor(config: AgentCardResolverConfig, resolverFn: (url: string) => Promise) { + super(config) + this.resolverFunction = resolverFn + } + + async resolve(url: string): Promise { + try { + return await this.resolverFunction(url) + } catch (error) { + throw new Error(`Function resolver failed: ${(error as Error).message}`) + } + } +} + +// Agent Card resolver factory +export class AgentCardResolverFactory { + createResolver(config: AgentCardResolverConfig, ...args: any[]): AgentCardResolver { + switch (config.type) { + case 'well-known': + return new WellKnownAgentCardResolver(config) + case 'custom-endpoint': + return new CustomEndpointAgentCardResolver(config) + case 'static': + if (args[0]) { + return new StaticAgentCardResolver(config, args[0]) + } + throw new Error('Static resolver requires an AgentCard argument') + case 'function': + if (args[0] && typeof args[0] === 'function') { + return new FunctionAgentCardResolver(config, args[0]) + } + throw new Error('Function resolver requires a function argument') + default: + throw new Error(`Unsupported resolver type: ${config.type}`) + } + } +} + +export function createAgentCardResolverFactory(): AgentCardResolverFactory { + return new AgentCardResolverFactory() +} + +// Multi-resolver with fallback support +export class MultiAgentCardResolver implements AgentCardResolver { + readonly type = 'multi' + private resolvers: AgentCardResolver[] + private config: AgentCardResolverConfig + + constructor(resolvers: AgentCardResolver[], config: AgentCardResolverConfig = { type: 'multi' }) { + this.resolvers = resolvers + this.config = config + } + + async resolve(url: string): Promise { + const errors: Error[] = [] + + for (const resolver of this.resolvers) { + try { + return await resolver.resolve(url) + } catch (error) { + errors.push(error as Error) + } + } + + throw new Error(`All resolvers failed: ${errors.map(e => e.message).join('; ')}`) + } + + configure(config: Partial): void { + this.config = { ...this.config, ...config } + // Optionally propagate config to child resolvers + } + + getConfig(): AgentCardResolverConfig { + return { ...this.config } + } +} + +// Default agent card resolver factory function +export function createDefaultAgentCardResolver(config?: Partial): AgentCardResolver { + const resolverConfig: AgentCardResolverConfig = { + type: 'well-known', + timeout: 10000, + retries: 2, + ...config + } + + // Create multi-resolver with well-known and custom-endpoint fallback + const factory = new AgentCardResolverFactory() + const resolvers = [ + factory.createResolver({ ...resolverConfig, type: 'well-known' }), + factory.createResolver({ ...resolverConfig, type: 'custom-endpoint' }) + ] + + return new MultiAgentCardResolver(resolvers, resolverConfig) +} \ No newline at end of file diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 0f77a3d..cd9c1a8 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,17 +1,59 @@ -// Export all types -export * from './types' +// Core AgentArea UI SDK exports -// Export runtime implementations with explicit re-exports to avoid conflicts -export { BaseRuntime } from './runtime/base-runtime' -export { A2ARuntime, createA2ARuntime, type A2AConfig } from './runtime/a2a-runtime' -export { AgentAreaRuntime, createAgentAreaRuntime, type AgentAreaConfig } from './runtime/agentarea-runtime' -export { - RuntimeFactory, - RuntimeManager, - createRuntimeFactory, - createRuntimeManager, - getGlobalRuntimeManager, - setGlobalRuntimeManager, - type RuntimeManagerEvent, - type RuntimeHealthStatus -} from './runtime/runtime-factory' \ No newline at end of file +// Runtime exports +export * from './runtime'; + +// Agent primitives exports - Core building blocks for agent interfaces +export * from './primitives'; + +// Type exports (avoiding conflicts with runtime exports) +export type { + // Environment types + RuntimeEnvironment, + EnvironmentCapabilities, + BuildEnvironment, + SSRCompatibility, + AgentUIConfig, + DynamicImportConfig, + + // Core types + Message, + MessagePart, + TaskInput, + Task, + TaskStatus, + TaskResponse, + TaskProgress, + TaskError, + TaskUpdate, + Artifact, + EnhancedArtifact, + TaskInputRequest, + InputResponse, + TaskWithInputs, + CommunicationBlock, + ValidationRule, + InputOption, + FormField, + Subscription, + AgentUpdate, + ProtocolMessage, + AgentCard, + Capability, + ArtifactMetadata, + Connection, + ConnectionConfig, + RuntimeEvent, + ValidationError, + RuntimeConfig, + AuthConfig +} from './types'; + +// Transport types +export type { RestEndpointMapping } from './transport'; + +// Export both the interface and the concrete implementation +export type { AgentRuntime } from './types'; +export { AgentAreaRuntime } from './runtime/agentarea-runtime'; +export { A2ARuntime } from './runtime/a2a-runtime'; +export { createRuntimeFactory } from './runtime/runtime-factory'; diff --git a/packages/core/src/primitives/agent.ts b/packages/core/src/primitives/agent.ts new file mode 100644 index 0000000..20722ff --- /dev/null +++ b/packages/core/src/primitives/agent.ts @@ -0,0 +1,342 @@ +// Agent primitive for managing AI agent instances and capabilities + +import { AgentMessage, MessageContent } from './message'; +import { Conversation } from './conversation'; + +export interface AgentCapability { + id: string; + name: string; + description: string; + type: 'tool' | 'skill' | 'knowledge' | 'integration'; + enabled: boolean; + config?: Record; +} + +export interface AgentModel { + id: string; + name: string; + provider: string; + version?: string; + contextWindow: number; + maxTokens?: number; + supportedFeatures: string[]; + pricing?: { + inputTokens: number; + outputTokens: number; + currency: string; + }; +} + +export interface AgentConfig { + id?: string; + name: string; + description?: string; + model: AgentModel; + systemPrompt?: string; + temperature?: number; + maxTokens?: number; + capabilities: AgentCapability[]; + metadata?: Record; +} + +export interface AgentState { + id: string; + name: string; + status: 'idle' | 'thinking' | 'responding' | 'error' | 'offline'; + currentConversation?: string; + activeCapabilities: string[]; + metrics: { + totalMessages: number; + totalTokens: number; + totalCost: number; + averageResponseTime: number; + uptime: number; + }; + lastActivity: Date; + createdAt: Date; +} + +export interface AgentResponse { + messageId: string; + content: MessageContent[]; + metadata: { + model: string; + tokens: { + input: number; + output: number; + total: number; + }; + cost?: number; + latency: number; + reasoning?: string; + toolCalls?: ToolCall[]; + }; +} + +export interface ToolCall { + id: string; + name: string; + arguments: Record; + result?: any; + error?: string; + executionTime?: number; +} + +export interface AgentThinkingState { + step: string; + reasoning: string; + confidence: number; + nextActions: string[]; +} + +export class Agent { + private config: Required; + private state: AgentState; + private conversations: Map = new Map(); + private listeners: Set<(state: AgentState) => void> = new Set(); + private thinkingListeners: Set<(thinking: AgentThinkingState) => void> = new Set(); + + constructor(config: AgentConfig) { + this.config = { + id: config.id || `agent_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + name: config.name, + description: config.description || '', + model: config.model, + systemPrompt: config.systemPrompt || '', + temperature: config.temperature ?? 0.7, + maxTokens: config.maxTokens || config.model.maxTokens || 4096, + capabilities: config.capabilities, + metadata: config.metadata || {} + }; + + this.state = { + id: this.config.id, + name: this.config.name, + status: 'idle', + activeCapabilities: this.config.capabilities + .filter(cap => cap.enabled) + .map(cap => cap.id), + metrics: { + totalMessages: 0, + totalTokens: 0, + totalCost: 0, + averageResponseTime: 0, + uptime: 0 + }, + lastActivity: new Date(), + createdAt: new Date() + }; + } + + async processMessage( + message: AgentMessage, + conversation: Conversation, + options?: { + stream?: boolean; + tools?: string[]; + reasoning?: boolean; + } + ): Promise { + this.updateStatus('thinking'); + const startTime = Date.now(); + + try { + // Simulate thinking process + if (options?.reasoning) { + await this.simulateThinking(message.content[0]?.content || ''); + } + + this.updateStatus('responding'); + + // Simulate AI processing + const response = await this.generateResponse(message, conversation, options); + + // Update metrics + const latency = Date.now() - startTime; + this.updateMetrics(response.metadata.tokens.total, response.metadata.cost || 0, latency); + + this.updateStatus('idle'); + return response; + + } catch (error) { + this.updateStatus('error'); + throw error; + } + } + + getCapability(id: string): AgentCapability | undefined { + return this.config.capabilities.find(cap => cap.id === id); + } + + enableCapability(id: string): boolean { + const capability = this.getCapability(id); + if (capability) { + capability.enabled = true; + if (!this.state.activeCapabilities.includes(id)) { + this.state.activeCapabilities.push(id); + } + this.notifyStateListeners(); + return true; + } + return false; + } + + disableCapability(id: string): boolean { + const capability = this.getCapability(id); + if (capability) { + capability.enabled = false; + this.state.activeCapabilities = this.state.activeCapabilities.filter(capId => capId !== id); + this.notifyStateListeners(); + return true; + } + return false; + } + + updateConfig(updates: Partial): void { + Object.assign(this.config, updates); + if (updates.name) { + this.state.name = updates.name; + } + this.notifyStateListeners(); + } + + getState(): AgentState { + return { ...this.state }; + } + + getConfig(): AgentConfig { + return { ...this.config }; + } + + subscribe(listener: (state: AgentState) => void): () => void { + this.listeners.add(listener); + return () => this.listeners.delete(listener); + } + + subscribeToThinking(listener: (thinking: AgentThinkingState) => void): () => void { + this.thinkingListeners.add(listener); + return () => this.thinkingListeners.delete(listener); + } + + private async simulateThinking(input: string): Promise { + const thinkingSteps = [ + { step: 'analyzing', reasoning: 'Analyzing user input and context', confidence: 0.3 }, + { step: 'planning', reasoning: 'Planning response strategy', confidence: 0.6 }, + { step: 'generating', reasoning: 'Generating response content', confidence: 0.9 } + ]; + + for (const thinking of thinkingSteps) { + this.notifyThinkingListeners({ + ...thinking, + nextActions: ['respond', 'clarify', 'use_tool'] + }); + await new Promise(resolve => setTimeout(resolve, 500)); + } + } + + private async generateResponse( + message: AgentMessage, + conversation: Conversation, + options?: any + ): Promise { + // Simulate AI response generation + const responseContent = `I understand your message: "${message.content[0]?.content}". How can I help you further?`; + + const tokens = { + input: message.content[0]?.content.length || 0, + output: responseContent.length, + total: (message.content[0]?.content.length || 0) + responseContent.length + }; + + const cost = this.config.model.pricing ? + (tokens.input * this.config.model.pricing.inputTokens + tokens.output * this.config.model.pricing.outputTokens) / 1000000 + : 0; + + return { + messageId: `resp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + content: [{ + type: 'text', + content: responseContent + }], + metadata: { + model: this.config.model.id, + tokens, + cost, + latency: Math.random() * 1000 + 500, // Simulate 500-1500ms latency + reasoning: options?.reasoning ? 'Analyzed input and generated contextual response' : undefined + } + }; + } + + private updateStatus(status: AgentState['status']): void { + this.state.status = status; + this.state.lastActivity = new Date(); + this.notifyStateListeners(); + } + + private updateMetrics(tokens: number, cost: number, latency: number): void { + this.state.metrics.totalMessages++; + this.state.metrics.totalTokens += tokens; + this.state.metrics.totalCost += cost; + + // Update average response time + const totalResponses = this.state.metrics.totalMessages; + this.state.metrics.averageResponseTime = + (this.state.metrics.averageResponseTime * (totalResponses - 1) + latency) / totalResponses; + } + + private notifyStateListeners(): void { + this.listeners.forEach(listener => listener(this.state)); + } + + private notifyThinkingListeners(thinking: AgentThinkingState): void { + this.thinkingListeners.forEach(listener => listener(thinking)); + } +} + +export class AgentRegistry { + private agents: Map = new Map(); + private listeners: Set<(agents: Agent[]) => void> = new Set(); + + registerAgent(agent: Agent): void { + this.agents.set(agent.getState().id, agent); + this.notifyListeners(); + } + + unregisterAgent(id: string): boolean { + const deleted = this.agents.delete(id); + if (deleted) { + this.notifyListeners(); + } + return deleted; + } + + getAgent(id: string): Agent | undefined { + return this.agents.get(id); + } + + getAllAgents(): Agent[] { + return Array.from(this.agents.values()); + } + + getActiveAgents(): Agent[] { + return this.getAllAgents().filter(agent => + agent.getState().status !== 'offline' + ); + } + + findAgentsByCapability(capabilityId: string): Agent[] { + return this.getAllAgents().filter(agent => + agent.getState().activeCapabilities.includes(capabilityId) + ); + } + + subscribe(listener: (agents: Agent[]) => void): () => void { + this.listeners.add(listener); + return () => this.listeners.delete(listener); + } + + private notifyListeners(): void { + this.listeners.forEach(listener => listener(this.getAllAgents())); + } +} \ No newline at end of file diff --git a/packages/core/src/primitives/conversation.ts b/packages/core/src/primitives/conversation.ts new file mode 100644 index 0000000..07ee2aa --- /dev/null +++ b/packages/core/src/primitives/conversation.ts @@ -0,0 +1,257 @@ +// Agent conversation primitive for managing chat sessions + +import { AgentMessage, MessageManager, createMessage, MessageRole } from './message'; + +export interface ConversationConfig { + id?: string; + title?: string; + systemPrompt?: string; + maxMessages?: number; + retentionPolicy?: 'all' | 'sliding_window' | 'summary'; + metadata?: Record; +} + +export interface ConversationState { + id: string; + title: string; + createdAt: Date; + updatedAt: Date; + messageCount: number; + isActive: boolean; + metadata: Record; +} + +export interface ConversationSummary { + conversationId: string; + summary: string; + messageRange: { start: string; end: string }; + createdAt: Date; +} + +export class Conversation { + private messageManager: MessageManager; + private config: Required; + private state: ConversationState; + private summaries: ConversationSummary[] = []; + private listeners: Set<(state: ConversationState) => void> = new Set(); + + constructor(config: ConversationConfig = {}) { + this.messageManager = new MessageManager(); + this.config = { + id: config.id || `conv_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + title: config.title || 'New Conversation', + systemPrompt: config.systemPrompt || '', + maxMessages: config.maxMessages || 1000, + retentionPolicy: config.retentionPolicy || 'all', + metadata: config.metadata || {} + }; + + this.state = { + id: this.config.id, + title: this.config.title, + createdAt: new Date(), + updatedAt: new Date(), + messageCount: 0, + isActive: true, + metadata: this.config.metadata + }; + + // Add system message if provided + if (this.config.systemPrompt) { + this.addMessage('system', this.config.systemPrompt); + } + + // Subscribe to message updates + this.messageManager.subscribe(() => { + this.updateState(); + }); + } + + addMessage(role: keyof MessageRole, content: string, metadata?: Record): AgentMessage { + const message = createMessage(role, content, { metadata }); + this.messageManager.addMessage(message); + this.enforceRetentionPolicy(); + return message; + } + + addUserMessage(content: string, metadata?: Record): AgentMessage { + return this.addMessage('user', content, metadata); + } + + addAssistantMessage(content: string, metadata?: Record): AgentMessage { + return this.addMessage('assistant', content, metadata); + } + + streamAssistantMessage(content: string, metadata?: Record): AgentMessage { + const message = createMessage('assistant', '', { + status: 'streaming', + metadata + }); + this.messageManager.addMessage(message); + return message; + } + + updateMessage(messageId: string, updates: Partial): void { + this.messageManager.updateMessage(messageId, updates); + } + + getMessages(): AgentMessage[] { + return this.messageManager.getMessages(); + } + + getLastMessage(): AgentMessage | undefined { + const messages = this.getMessages(); + return messages[messages.length - 1]; + } + + getMessagesByRole(role: keyof MessageRole): AgentMessage[] { + return this.getMessages().filter(msg => msg.role === role); + } + + getState(): ConversationState { + return { ...this.state }; + } + + updateTitle(title: string): void { + this.state.title = title; + this.updateState(); + } + + archive(): void { + this.state.isActive = false; + this.updateState(); + } + + restore(): void { + this.state.isActive = true; + this.updateState(); + } + + clear(): void { + this.messageManager.clear(); + this.summaries = []; + + // Re-add system message if it exists + if (this.config.systemPrompt) { + this.addMessage('system', this.config.systemPrompt); + } + + this.updateState(); + } + + export(): { + config: ConversationConfig; + state: ConversationState; + messages: AgentMessage[]; + summaries: ConversationSummary[]; + } { + return { + config: this.config, + state: this.state, + messages: this.getMessages(), + summaries: this.summaries + }; + } + + subscribe(listener: (state: ConversationState) => void): () => void { + this.listeners.add(listener); + return () => this.listeners.delete(listener); + } + + private updateState(): void { + this.state.updatedAt = new Date(); + this.state.messageCount = this.getMessages().length; + this.notifyListeners(); + } + + private notifyListeners(): void { + this.listeners.forEach(listener => listener(this.state)); + } + + private enforceRetentionPolicy(): void { + const messages = this.getMessages(); + + if (this.config.retentionPolicy === 'sliding_window' && messages.length > this.config.maxMessages) { + // Keep system messages and remove oldest user/assistant messages + const systemMessages = messages.filter(msg => msg.role === 'system'); + const otherMessages = messages.filter(msg => msg.role !== 'system'); + + const messagesToKeep = this.config.maxMessages - systemMessages.length; + const keptMessages = otherMessages.slice(-messagesToKeep); + + this.messageManager.clear(); + [...systemMessages, ...keptMessages].forEach(msg => { + this.messageManager.addMessage(msg); + }); + } + } + + private async createSummary(messages: AgentMessage[]): Promise { + // This would typically call an AI service to summarize + // For now, return a basic summary + const summary = `Conversation with ${messages.length} messages`; + + return { + conversationId: this.state.id, + summary, + messageRange: { + start: messages[0]?.id || '', + end: messages[messages.length - 1]?.id || '' + }, + createdAt: new Date() + }; + } +} + +export class ConversationManager { + private conversations: Map = new Map(); + private activeConversationId: string | null = null; + + createConversation(config?: ConversationConfig): Conversation { + const conversation = new Conversation(config); + this.conversations.set(conversation.getState().id, conversation); + this.activeConversationId = conversation.getState().id; + return conversation; + } + + getConversation(id: string): Conversation | undefined { + return this.conversations.get(id); + } + + getActiveConversation(): Conversation | undefined { + return this.activeConversationId ? this.conversations.get(this.activeConversationId) : undefined; + } + + setActiveConversation(id: string): boolean { + if (this.conversations.has(id)) { + this.activeConversationId = id; + return true; + } + return false; + } + + getAllConversations(): Conversation[] { + return Array.from(this.conversations.values()); + } + + getActiveConversations(): Conversation[] { + return this.getAllConversations().filter(conv => conv.getState().isActive); + } + + deleteConversation(id: string): boolean { + const deleted = this.conversations.delete(id); + if (this.activeConversationId === id) { + this.activeConversationId = null; + } + return deleted; + } + + archiveConversation(id: string): boolean { + const conversation = this.conversations.get(id); + if (conversation) { + conversation.archive(); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/packages/core/src/primitives/index.ts b/packages/core/src/primitives/index.ts new file mode 100644 index 0000000..4b9fa85 --- /dev/null +++ b/packages/core/src/primitives/index.ts @@ -0,0 +1,70 @@ +// Agent primitives - Core building blocks for agent interfaces + +// Message primitives +export type { + MessageRole, + MessageContent, + AgentMessage, + MessageStreamChunk +} from './message'; +export { + MessageManager, + createMessage +} from './message'; + +// Conversation primitives +export type { + ConversationConfig, + ConversationState, + ConversationSummary +} from './conversation'; +export { + Conversation, + ConversationManager +} from './conversation'; + +// Agent primitives +export type { + AgentCapability, + AgentModel, + AgentConfig, + AgentState, + AgentResponse, + ToolCall, + AgentThinkingState +} from './agent'; +export { + Agent, + AgentRegistry +} from './agent'; + +// Tool primitives +export type { + ToolParameter, + ToolSchema, + ToolExecution, + ToolConfig, + ToolFunction +} from './tool'; +export { + Tool, + ToolRegistry, + createBuiltinTools +} from './tool'; + +// Utility functions for creating agent instances +export const createAgent = (config: import('./agent').AgentConfig): import('./agent').Agent => { + return new (require('./agent').Agent)(config); +}; + +export const createConversation = (config?: import('./conversation').ConversationConfig): import('./conversation').Conversation => { + return new (require('./conversation').Conversation)(config); +}; + +export const createTool = ( + schema: import('./tool').ToolSchema, + implementation: import('./tool').ToolFunction, + config?: import('./tool').ToolConfig +): import('./tool').Tool => { + return new (require('./tool').Tool)(schema, implementation, config); +}; \ No newline at end of file diff --git a/packages/core/src/primitives/message.ts b/packages/core/src/primitives/message.ts new file mode 100644 index 0000000..e40b0e4 --- /dev/null +++ b/packages/core/src/primitives/message.ts @@ -0,0 +1,117 @@ +// Agent message primitive for conversation interfaces + +export interface MessageRole { + user: 'user'; + assistant: 'assistant'; + system: 'system'; + tool: 'tool'; +} + +export interface MessageContent { + type: 'text' | 'image' | 'audio' | 'file' | 'code' | 'tool_call' | 'tool_result'; + content: string; + metadata?: Record; +} + +export interface AgentMessage { + id: string; + role: keyof MessageRole; + content: MessageContent[]; + timestamp: Date; + status?: 'pending' | 'streaming' | 'complete' | 'error'; + metadata?: { + model?: string; + tokens?: number; + cost?: number; + latency?: number; + [key: string]: any; + }; +} + +export interface MessageStreamChunk { + messageId: string; + delta: Partial; + isComplete: boolean; +} + +export class MessageManager { + private messages: Map = new Map(); + private listeners: Set<(message: AgentMessage) => void> = new Set(); + + addMessage(message: AgentMessage): void { + this.messages.set(message.id, message); + this.notifyListeners(message); + } + + updateMessage(id: string, updates: Partial): void { + const existing = this.messages.get(id); + if (existing) { + const updated = { ...existing, ...updates }; + this.messages.set(id, updated); + this.notifyListeners(updated); + } + } + + streamMessage(chunk: MessageStreamChunk): void { + const existing = this.messages.get(chunk.messageId); + if (existing && chunk.delta.content) { + const lastContent = existing.content[existing.content.length - 1]; + if (lastContent && lastContent.type === chunk.delta.type) { + lastContent.content += chunk.delta.content; + } else if (chunk.delta.content) { + existing.content.push({ + type: chunk.delta.type || 'text', + content: chunk.delta.content + }); + } + + if (chunk.isComplete) { + existing.status = 'complete'; + } + + this.notifyListeners(existing); + } + } + + getMessage(id: string): AgentMessage | undefined { + return this.messages.get(id); + } + + getMessages(): AgentMessage[] { + return Array.from(this.messages.values()).sort( + (a, b) => a.timestamp.getTime() - b.timestamp.getTime() + ); + } + + subscribe(listener: (message: AgentMessage) => void): () => void { + this.listeners.add(listener); + return () => this.listeners.delete(listener); + } + + private notifyListeners(message: AgentMessage): void { + this.listeners.forEach(listener => listener(message)); + } + + clear(): void { + this.messages.clear(); + } +} + +export const createMessage = ( + role: keyof MessageRole, + content: string | MessageContent[], + options?: Partial +): AgentMessage => { + const messageContent: MessageContent[] = typeof content === 'string' + ? [{ type: 'text', content }] + : content; + + return { + id: options?.id || `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + role, + content: messageContent, + timestamp: new Date(), + status: 'complete', + ...options + }; +}; \ No newline at end of file diff --git a/packages/core/src/primitives/tool.ts b/packages/core/src/primitives/tool.ts new file mode 100644 index 0000000..813c25c --- /dev/null +++ b/packages/core/src/primitives/tool.ts @@ -0,0 +1,369 @@ +// Tool primitive for agent capabilities and function calling + +export interface ToolParameter { + name: string; + type: 'string' | 'number' | 'boolean' | 'object' | 'array'; + description: string; + required: boolean; + enum?: string[]; + properties?: Record; + items?: ToolParameter; +} + +export interface ToolSchema { + id: string; + name: string; + description: string; + parameters: ToolParameter[]; + returns?: { + type: string; + description: string; + }; + examples?: { + input: Record; + output: any; + description: string; + }[]; +} + +export interface ToolExecution { + id: string; + toolId: string; + arguments: Record; + result?: any; + error?: string; + startTime: Date; + endTime?: Date; + duration?: number; + metadata?: Record; +} + +export interface ToolConfig { + timeout?: number; + retries?: number; + validation?: boolean; + logging?: boolean; + rateLimit?: { + requests: number; + window: number; // milliseconds + }; +} + +export type ToolFunction = (args: Record) => Promise | any; + +export class Tool { + private schema: ToolSchema; + private implementation: ToolFunction; + private config: ToolConfig; + private executions: Map = new Map(); + private rateLimitTracker: { timestamp: number; count: number } = { timestamp: 0, count: 0 }; + + constructor(schema: ToolSchema, implementation: ToolFunction, config: ToolConfig = {}) { + this.schema = schema; + this.implementation = implementation; + this.config = { + timeout: config.timeout || 30000, + retries: config.retries || 0, + validation: config.validation ?? true, + logging: config.logging ?? true, + rateLimit: config.rateLimit + }; + } + + async execute(args: Record, executionId?: string): Promise { + const id = executionId || `exec_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; + + const execution: ToolExecution = { + id, + toolId: this.schema.id, + arguments: args, + startTime: new Date() + }; + + this.executions.set(id, execution); + + try { + // Rate limiting check + if (this.config.rateLimit && !this.checkRateLimit()) { + throw new Error(`Rate limit exceeded for tool ${this.schema.name}`); + } + + // Validation + if (this.config.validation) { + this.validateArguments(args); + } + + // Execute with timeout + const result = await this.executeWithTimeout(args); + + execution.result = result; + execution.endTime = new Date(); + execution.duration = execution.endTime.getTime() - execution.startTime.getTime(); + + if (this.config.logging) { + console.log(`Tool ${this.schema.name} executed successfully in ${execution.duration}ms`); + } + + return execution; + + } catch (error) { + execution.error = error instanceof Error ? error.message : String(error); + execution.endTime = new Date(); + execution.duration = execution.endTime.getTime() - execution.startTime.getTime(); + + if (this.config.logging) { + console.error(`Tool ${this.schema.name} failed:`, execution.error); + } + + return execution; + } + } + + getSchema(): ToolSchema { + return { ...this.schema }; + } + + getConfig(): ToolConfig { + return { ...this.config }; + } + + getExecution(id: string): ToolExecution | undefined { + return this.executions.get(id); + } + + getExecutions(): ToolExecution[] { + return Array.from(this.executions.values()).sort( + (a, b) => b.startTime.getTime() - a.startTime.getTime() + ); + } + + getSuccessRate(): number { + const executions = this.getExecutions(); + if (executions.length === 0) return 0; + + const successful = executions.filter(exec => !exec.error).length; + return successful / executions.length; + } + + getAverageExecutionTime(): number { + const executions = this.getExecutions().filter(exec => exec.duration !== undefined); + if (executions.length === 0) return 0; + + const totalTime = executions.reduce((sum, exec) => sum + (exec.duration || 0), 0); + return totalTime / executions.length; + } + + updateConfig(config: Partial): void { + Object.assign(this.config, config); + } + + clearExecutions(): void { + this.executions.clear(); + } + + private async executeWithTimeout(args: Record): Promise { + return new Promise(async (resolve, reject) => { + const timeoutId = setTimeout(() => { + reject(new Error(`Tool execution timed out after ${this.config.timeout}ms`)); + }, this.config.timeout); + + try { + const result = await this.implementation(args); + clearTimeout(timeoutId); + resolve(result); + } catch (error) { + clearTimeout(timeoutId); + reject(error); + } + }); + } + + private validateArguments(args: Record): void { + for (const param of this.schema.parameters) { + if (param.required && !(param.name in args)) { + throw new Error(`Missing required parameter: ${param.name}`); + } + + if (param.name in args) { + this.validateParameterType(param, args[param.name]); + } + } + } + + private validateParameterType(param: ToolParameter, value: any): void { + const actualType = Array.isArray(value) ? 'array' : typeof value; + + if (param.type !== actualType && !(param.type === 'object' && actualType === 'object')) { + throw new Error(`Parameter ${param.name} expected ${param.type}, got ${actualType}`); + } + + if (param.enum && !param.enum.includes(value)) { + throw new Error(`Parameter ${param.name} must be one of: ${param.enum.join(', ')}`); + } + } + + private checkRateLimit(): boolean { + if (!this.config.rateLimit) return true; + + const now = Date.now(); + const windowStart = now - this.config.rateLimit.window; + + if (this.rateLimitTracker.timestamp < windowStart) { + // Reset window + this.rateLimitTracker = { timestamp: now, count: 1 }; + return true; + } + + if (this.rateLimitTracker.count >= this.config.rateLimit.requests) { + return false; + } + + this.rateLimitTracker.count++; + return true; + } +} + +export class ToolRegistry { + private tools: Map = new Map(); + private categories: Map = new Map(); + + registerTool(tool: Tool, category?: string): void { + const schema = tool.getSchema(); + this.tools.set(schema.id, tool); + + if (category) { + if (!this.categories.has(category)) { + this.categories.set(category, []); + } + this.categories.get(category)!.push(schema.id); + } + } + + unregisterTool(id: string): boolean { + const deleted = this.tools.delete(id); + + // Remove from categories + for (const [category, toolIds] of this.categories.entries()) { + const index = toolIds.indexOf(id); + if (index > -1) { + toolIds.splice(index, 1); + if (toolIds.length === 0) { + this.categories.delete(category); + } + } + } + + return deleted; + } + + getTool(id: string): Tool | undefined { + return this.tools.get(id); + } + + getAllTools(): Tool[] { + return Array.from(this.tools.values()); + } + + getToolsByCategory(category: string): Tool[] { + const toolIds = this.categories.get(category) || []; + return toolIds.map(id => this.tools.get(id)!).filter(Boolean); + } + + getCategories(): string[] { + return Array.from(this.categories.keys()); + } + + searchTools(query: string): Tool[] { + const lowerQuery = query.toLowerCase(); + return this.getAllTools().filter(tool => { + const schema = tool.getSchema(); + return ( + schema.name.toLowerCase().includes(lowerQuery) || + schema.description.toLowerCase().includes(lowerQuery) + ); + }); + } + + async executeTool(toolId: string, args: Record): Promise { + const tool = this.getTool(toolId); + if (!tool) { + throw new Error(`Tool not found: ${toolId}`); + } + return tool.execute(args); + } + + getToolSchemas(): ToolSchema[] { + return this.getAllTools().map(tool => tool.getSchema()); + } +} + +// Built-in tools +export const createBuiltinTools = (): Tool[] => { + return [ + new Tool( + { + id: 'web_search', + name: 'Web Search', + description: 'Search the web for information', + parameters: [ + { + name: 'query', + type: 'string', + description: 'Search query', + required: true + }, + { + name: 'limit', + type: 'number', + description: 'Maximum number of results', + required: false + } + ], + returns: { + type: 'array', + description: 'Array of search results' + } + }, + async (args) => { + // Simulate web search + return [ + { + title: `Search result for: ${args.query}`, + url: 'https://example.com', + snippet: 'This is a simulated search result.' + } + ]; + } + ), + + new Tool( + { + id: 'calculate', + name: 'Calculator', + description: 'Perform mathematical calculations', + parameters: [ + { + name: 'expression', + type: 'string', + description: 'Mathematical expression to evaluate', + required: true + } + ], + returns: { + type: 'number', + description: 'Calculation result' + } + }, + async (args) => { + // Simple calculator (in real implementation, use a safe math parser) + try { + // This is unsafe - use a proper math parser in production + return eval(args.expression); + } catch (error) { + throw new Error('Invalid mathematical expression'); + } + }, + { timeout: 5000 } + ) + ]; +}; \ No newline at end of file diff --git a/packages/core/src/runtime/a2a-runtime.ts b/packages/core/src/runtime/a2a-runtime.ts index 0e430bd..1ec2199 100644 --- a/packages/core/src/runtime/a2a-runtime.ts +++ b/packages/core/src/runtime/a2a-runtime.ts @@ -1,14 +1,15 @@ // A2A Protocol runtime implementation -// Uses official @a2a-js/sdk - -import { A2AClient } from '@a2a-js/sdk/client' -import type { - AgentCard as A2AAgentCard, - Message as A2AMessage, - Task as A2ATask, - MessageSendParams, - Part as A2APart -} from '@a2a-js/sdk' +// Refactored to use transport abstraction and agent-card resolver system + +// Removed direct dependency on @a2a-js/sdk +// import { A2AClient } from '@a2a-js/sdk/client' +// import type { +// AgentCard as A2AAgentCard, +// Message as A2AMessage, +// Task as A2ATask, +// MessageSendParams, +// Part as A2APart +// } from '@a2a-js/sdk' import { BaseRuntime } from './base-runtime' import type { RuntimeConfig, @@ -32,13 +33,21 @@ import type { ProtocolMessage, Subscription, TaskUpdateCallback, - AgentUpdateCallback + AgentUpdateCallback, + TaskNode, + SubTask, + DelegationConfig, + DelegationDetails } from '../types' +import type { Transport } from '../transport' +import { createTransportFactory } from '../transport' +import type { AgentCardResolver } from '../agent-card' +import { createAgentCardResolverFactory, createDefaultAgentCardResolver } from '../agent-card' export interface A2AConfig extends RuntimeConfig { agentBaseUrl: string authentication?: { - type: 'bearer' | 'api-key' | 'oauth' | 'openid' + type: 'bearer' | 'api-key' | 'oauth' | 'openid' | 'none' token?: string apiKey?: string config?: Record @@ -52,28 +61,56 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { readonly protocolType = 'a2a' as const readonly version = '1.0.0' - private client: A2AClient - private agentCard: A2AAgentCard | null = null + private transport!: Transport + private agentCard: AgentCard | null = null private discoveredAgents: Map = new Map() + private agentCardResolver!: AgentCardResolver constructor(config: A2AConfig) { super(config as RuntimeConfig) - this.client = new A2AClient(config.agentBaseUrl) + + // Initialize transport from config + const tf = createTransportFactory() + const transportType = config.transport?.type || 'json-rest' + const baseURLCandidate = (config.agentBaseUrl || (config as any).endpoint) as string | undefined + if (!baseURLCandidate) { + throw new Error('A2ARuntime requires either config.agentBaseUrl or config.endpoint to be provided') + } + const baseURL = baseURLCandidate + const transportConfig = config.transport?.config || { + baseURL, + timeout: config.timeout, + headers: undefined, + authentication: config.authentication?.type === 'bearer' && config.authentication.token + ? { type: 'bearer', token: config.authentication.token } + : config.authentication?.type === 'none' + ? { type: 'none' } + : undefined + } + + this.transport = tf.createTransport( + transportType, + { ...transportConfig, baseURL: transportConfig.baseURL || baseURL }, + config.transport?.endpointMapping + ) + + // Initialize agent card resolver + const resolverFactory = createAgentCardResolverFactory() + this.agentCardResolver = config.agentCardResolver + ? resolverFactory.createResolver(config.agentCardResolver) + : createDefaultAgentCardResolver({ type: 'well-known' }) } protected initializeProtocolSettings(): void { - // A2A-specific initialization - if (this.config?.authentication?.type === 'bearer' && this.config.authentication.token) { - // Set up authentication headers for A2A client if needed - // This would depend on the @a2a-js/sdk implementation - } + // No-op for transport-based implementation; configs handled in constructor } // Protocol-specific connection implementation protected async performConnect(connection: Connection, config: ConnectionConfig): Promise { try { - // Test connection by fetching agent card - this.agentCard = await this.client.getAgentCard() + // Test connection by fetching agent card via resolver + const endpoint = (this.config?.endpoint as string) || (this.config as A2AConfig).agentBaseUrl + this.agentCard = await this.agentCardResolver.resolve(endpoint) // Update connection with agent information connection.agentId = this.agentCard?.name || 'unknown' @@ -88,7 +125,6 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { } protected async performDisconnect(connection: Connection): Promise { - // A2A doesn't require explicit disconnection, but we can clean up resources if (connection.agentId === this.agentCard?.name) { this.agentCard = null } @@ -97,14 +133,9 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { // A2A-specific agent discovery async discoverAgents(endpoint: string): Promise { try { - // Create a temporary client for discovery - const discoveryClient = new A2AClient(endpoint) - const agentCard = await discoveryClient.getAgentCard() - - const mappedCard = this.mapA2AAgentCard(agentCard) - this.discoveredAgents.set(endpoint, mappedCard) - - return [mappedCard] + const card = await this.agentCardResolver.resolve(endpoint) + this.discoveredAgents.set(endpoint, card) + return [card] } catch (error) { throw new Error(`Failed to discover agents at ${endpoint}: ${(error as Error).message}`) } @@ -117,7 +148,6 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { throw new Error(`Agent ${agentId} not found in discovered agents`) } - // Return intersection of requested capabilities and agent capabilities const agentCapabilities = agent.capabilities.map(cap => cap.name) return capabilities.filter(cap => agentCapabilities.includes(cap)) } @@ -125,7 +155,6 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { // A2A message handling async handleA2AMessage(message: ProtocolA2AMessage): Promise { try { - // Process A2A-specific message format const processedMessage: ProtocolMessage = { id: message.correlationId || message.id, type: message.messageType, @@ -148,13 +177,11 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { // A2A protocol compliance validation async validateA2ACompliance(endpoint: string): Promise { try { - const client = new A2AClient(endpoint) - const agentCard = await client.getAgentCard() + const agentCard = await this.agentCardResolver.resolve(endpoint) const issues: any[] = [] const supportedFeatures: string[] = [] - // Check required A2A fields if (!agentCard.name) { issues.push({ severity: 'error', @@ -174,26 +201,24 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { } // Check capabilities - if (agentCard.capabilities) { - if (agentCard.capabilities.streaming) { - supportedFeatures.push('streaming') - } - if (agentCard.capabilities.pushNotifications) { - supportedFeatures.push('push-notifications') - } + if (agentCard.streaming) { + supportedFeatures.push('streaming') + } + if (agentCard.pushNotifications) { + supportedFeatures.push('push-notifications') } - // Check input/output modes - if (agentCard.defaultInputModes && agentCard.defaultInputModes.length > 0) { + // Check input/output modes from capabilities + if (agentCard.capabilities?.some(c => (c.inputTypes?.length || 0) > 0)) { supportedFeatures.push('input-modes') } - if (agentCard.defaultOutputModes && agentCard.defaultOutputModes.length > 0) { + if (agentCard.capabilities?.some(c => (c.outputTypes?.length || 0) > 0)) { supportedFeatures.push('output-modes') } return { compliant: issues.filter(i => i.severity === 'error').length === 0, - version: '1.0.0', // A2A protocol version + version: '1.0.0', supportedFeatures, issues: issues.length > 0 ? issues : undefined } @@ -229,11 +254,11 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { getSupportedCapabilities(): string[] { const capabilities = ['message-sending', 'task-submission'] - if (this.agentCard?.capabilities?.streaming) { + if (this.agentCard?.streaming) { capabilities.push('streaming') } - if (this.agentCard?.capabilities?.pushNotifications) { + if (this.agentCard?.pushNotifications) { capabilities.push('push-notifications') } @@ -242,18 +267,13 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { // Input request handling for A2A protocol async handleInputRequest(taskId: string, response: InputResponse): Promise { - // A2A protocol doesn't have built-in input request handling - // This would need to be implemented based on the specific A2A agent's capabilities throw new Error('Input request handling not implemented for A2A protocol') } // Real-time subscriptions subscribeToTask(taskId: string, callback: TaskUpdateCallback): Subscription { - // A2A doesn't have built-in real-time subscriptions - // This could be implemented using polling or WebSocket extensions const subscriptionId = `task-${taskId}-${Date.now()}` - // Simple polling implementation const pollInterval = setInterval(async () => { try { const task = await this.getTask(taskId) @@ -266,9 +286,9 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { error: task.error }) } catch (error) { - // Ignore polling errors to avoid spam + // ignore } - }, 5000) // Poll every 5 seconds + }, 5000) return this.createSubscription(subscriptionId, () => { clearInterval(pollInterval) @@ -276,16 +296,14 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { } subscribeToAgent(agentId: string, callback: AgentUpdateCallback): Subscription { - // A2A doesn't have built-in agent subscriptions const subscriptionId = `agent-${agentId}-${Date.now()}` - // Simple polling implementation for agent status const pollInterval = setInterval(async () => { try { const agentCard = await this.getAgentCard() callback({ agentId, - status: 'online', // A2A doesn't provide status, assume online if reachable + status: 'online', capabilities: agentCard.capabilities, metadata: { agentCard }, timestamp: new Date() @@ -297,7 +315,7 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { timestamp: new Date() }) } - }, 30000) // Poll every 30 seconds + }, 30000) return this.createSubscription(subscriptionId, () => { clearInterval(pollInterval) @@ -306,76 +324,59 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { // Artifact management async downloadArtifact(artifactId: string): Promise { - // A2A protocol doesn't have built-in artifact download - // This would need to be implemented based on the artifact's URL or content throw new Error('Artifact download not implemented for A2A protocol') } async uploadArtifact(file: File, metadata?: ArtifactMetadata): Promise { - // A2A protocol doesn't have built-in artifact upload - // This would need to be implemented based on the agent's capabilities throw new Error('Artifact upload not implemented for A2A protocol') } // Protocol message handling async sendMessage(message: ProtocolMessage, targetAgent: string): Promise { - // Convert protocol message to A2A message format - const a2aMessage: A2AMessage = { - kind: 'message', - messageId: message.id, - role: 'user', - parts: [{ - text: JSON.stringify(message.payload) - } as A2APart] - } - - const params: MessageSendParams = { - message: a2aMessage, - configuration: { - blocking: true, - acceptedOutputModes: ['message'] + // For transport abstraction, map to a2a sendMessage RPC or REST endpoint + const req = { + method: 'message.send', + params: { + kind: 'message', + messageId: message.id, + role: 'user', + parts: [{ text: JSON.stringify(message.payload) }] } } - const response = await this.client.sendMessage(params) - - if ('error' in response) { - throw new Error(`A2A Error: ${response.error.message}`) + const res = await this.transport.request(req) + if (!res.success) { + throw new Error(`A2A Error: ${res.error?.message || 'Unknown error'}`) } } async handleProtocolMessage(message: ProtocolMessage): Promise { - // Handle incoming protocol messages - // This is a base implementation that can be extended console.log('Received protocol message:', message) - // Emit as a task update if it's task-related if (message.type === 'task-update' && message.payload) { const update = message.payload as TaskUpdate this.emitTaskUpdate(update) } } - - async sendTask(input: TaskInput): Promise { - const params: MessageSendParams = { - message: this.mapToA2AMessage(input.message), - configuration: { - blocking: true, - acceptedOutputModes: ['message', 'task'] + const req = { + method: 'message.send', + params: { + kind: 'message', + messageId: `msg-${Date.now()}`, + role: input.message.role, + parts: input.message.parts?.map(p => p.type === 'text' ? { text: p.content } : { data: p.content }) } } - const response = await this.client.sendMessage(params) - - // Handle different response types - if ('error' in response) { - throw new Error(`A2A Error: ${response.error.message}`) + const res = await this.transport.request(req) + if (!res.success) { + throw new Error(`A2A Error: ${res.error?.message || 'Unknown error'}`) } return { - task: this.mapA2AResponseToTask(response), + task: this.mapA2AResponseToTask(res.data), streaming: false } } @@ -384,53 +385,42 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { if (!this.supportsStreaming()) { throw new Error('Streaming not supported by this agent') } - - const params: MessageSendParams = { - message: this.mapToA2AMessage(input.message), - configuration: { - blocking: false, - acceptedOutputModes: ['message', 'task'] - } - } - - const streamGenerator = this.client.sendMessageStream(params) - - try { - for await (const eventData of streamGenerator) { - const update = this.mapA2AEventToTaskUpdate(eventData) - this.emitTaskUpdate(update) - yield update - } - } catch (error) { - this.emitError(error as Error) - throw error - } + // Streaming not supported by transports in this implementation - could be implemented via SSE/WS later + throw new Error('Streaming not supported in current transport implementation') } async getTask(taskId: string): Promise { - const response = await this.client.getTask({ taskId } as any) - - if ('error' in response) { - throw new Error(`A2A Error: ${response.error.message}`) + const req = { + method: 'task.get', + params: { taskId } + } + + const res = await this.transport.request(req) + if (!res.success) { + throw new Error(`A2A Error: ${res.error?.message || 'Unknown error'}`) } - return this.mapA2AResponseToTask(response.result) + return this.mapA2AResponseToTask(res.data) } async cancelTask(taskId: string): Promise { - const response = await this.client.cancelTask({ taskId } as any) - - if ('error' in response) { - throw new Error(`A2A Error: ${response.error.message}`) + const req = { + method: 'task.cancel', + params: { taskId } } + const res = await this.transport.request(req) + if (!res.success) { + throw new Error(`A2A Error: ${res.error?.message || 'Unknown error'}`) + } } async getAgentCard(): Promise { - if (!this.agentCard) { - this.agentCard = await this.client.getAgentCard() - } - return this.mapA2AAgentCard(this.agentCard!) + if (this.agentCard) return this.agentCard + + const endpoint = (this.config?.endpoint as string) || (this.config as A2AConfig).agentBaseUrl + this.agentCard = await this.agentCardResolver.resolve(endpoint) + return this.agentCard } async getCapabilities(): Promise { @@ -439,77 +429,124 @@ export class A2ARuntime extends BaseRuntime implements A2ARuntimeInterface { } supportsStreaming(): boolean { - return this.agentCard?.capabilities?.streaming === true + return this.agentCard?.streaming === true } - private mapToA2AMessage(message: Message): A2AMessage { + private mapA2AResponseToTask(result: any): Task { + const core = (result?.result) ? result.result : result return { - kind: 'message', - messageId: `msg-${Date.now()}`, - role: message.role, - parts: message.parts.map((part: any) => { - if (part.type === 'text') { - return { - text: part.content as string - } as A2APart - } else if (part.type === 'file') { - return { - uri: part.content as string, - mimeType: part.mimeType - } as unknown as A2APart - } else { - return { - data: part.content - } as A2APart - } - }) + id: core?.id || core?.taskId || `task-${Date.now()}`, + contextId: core?.contextId, + status: core?.status || 'submitted', + input: core?.input || { message: { role: 'user', parts: [] } }, + artifacts: core?.artifacts || [], + messages: core?.messages || [], + progress: core?.progress, + error: core?.error, + createdAt: new Date(core?.createdAt || Date.now()), + updatedAt: new Date(core?.updatedAt || Date.now()) } } - private mapA2AResponseToTask(result: any): Task { - return { - id: result.id || result.taskId, - contextId: result.contextId, - status: result.status || 'submitted', - input: result.input || { message: { role: 'user', parts: [] } }, - artifacts: result.artifacts || [], - messages: result.messages || [], - progress: result.progress, - error: result.error, - createdAt: new Date(result.createdAt || Date.now()), - updatedAt: new Date(result.updatedAt || Date.now()) + async delegateSubTask( + parentTaskId: string, + subTasks: SubTask[], + config?: DelegationConfig + ): Promise { + const delegationId = `del_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; + const parallel = config?.parallel ?? true; + const maxDepth = config?.maxDepth ?? 5; + const includeLog = config?.contextPassing?.includeLog ?? 5; + const artifacts = config?.contextPassing?.artifacts ?? []; + + if (maxDepth <= 0) { + throw new Error("Maximum delegation depth exceeded"); } - } - private mapA2AEventToTaskUpdate(event: any): TaskUpdate { - return { - taskId: event.taskId, - status: event.status, - progress: event.progress, - artifacts: event.artifacts, - messages: event.messages, - error: event.error + const details: DelegationDetails = { + delegationId, + parentTaskId, + subTasks: [...subTasks], + status: 'pending' as const, + config, + timestamp: new Date(), + }; + + this.emit({ type: 'delegation', details, runtime: this }); + + try { + const parentTask = await this.getTask(parentTaskId); + const logSnippet: string[] = []; // Placeholder: recent events as strings + + const subTaskPromises = subTasks.map(async (subTask) => { + const baseInput = subTask.input || { message: { role: 'agent' as const, parts: [] } }; + const enhancedInput: TaskInput = { + ...baseInput, + metadata: { + ...(baseInput.metadata || {}), + parentTaskId, + delegationId, + logContext: logSnippet.slice(-includeLog), + artifacts, + }, + }; + + this.emit({ type: 'sub-task-started', subTask, delegationId, runtime: this }); + + const response = await this.submitTask(enhancedInput); + + this.emit({ type: 'sub-task-completed', subTask, delegationId, runtime: this }); + + return { ...subTask, response }; + }); + + if (parallel) { + await Promise.all(subTaskPromises); + } else { + for (const promise of subTaskPromises) { + await promise; + } + } + + details.status = 'completed'; + details.subTasks = subTasks.map((st) => ({ ...st, status: 'completed' as const })); + + return details; + } catch (error) { + details.status = 'failed'; + this.emit({ type: 'delegation-failed', delegationId, error: error as Error, runtime: this }); + throw error; } } - private mapA2AAgentCard(card: A2AAgentCard): AgentCard { - return { - name: card.name, - description: card.description, - capabilities: card.skills?.map((skill: any) => ({ - name: skill.name, - description: skill.description, - inputTypes: skill.defaultInputModes || card.defaultInputModes || [], - outputTypes: skill.defaultOutputModes || card.defaultOutputModes || [] - })) || [], - endpoints: { main: card.url }, - streaming: card.capabilities?.streaming || false, - pushNotifications: card.capabilities?.pushNotifications || false + async getDelegationTree(taskId: string): Promise { + const rootTask = await this.getTask(taskId); + const rootNode: TaskNode = { + id: rootTask.id, + description: rootTask.description || rootTask.input?.prompt || 'Root Task', + agentId: rootTask.agentId || 'primary', + status: rootTask.status as any, // Map to TaskNode status + input: rootTask.input, + response: rootTask.response, + children: [], + logSnippet: [], // Fetch from events + createdAt: rootTask.createdAt || new Date(), + updatedAt: new Date(), + }; + + const delegations: DelegationDetails[] = []; // Placeholder: fetch from runtime + for (const del of delegations) { + for (const sub of del.subTasks) { + const childNode = await this.getDelegationTree(sub.id); + rootNode.children.push(childNode); + } } + + return rootNode; } } // Factory function for creating A2A runtime export function createA2ARuntime(config: { agentBaseUrl: string; authentication?: any }): A2ARuntime { return new A2ARuntime(config as A2AConfig) -} \ No newline at end of file +} diff --git a/packages/core/src/runtime/base-runtime.ts b/packages/core/src/runtime/base-runtime.ts index 51599bd..3a1cf4e 100644 --- a/packages/core/src/runtime/base-runtime.ts +++ b/packages/core/src/runtime/base-runtime.ts @@ -102,7 +102,7 @@ export abstract class BaseRuntime implements AgentRuntime { throw new Error('Authentication type is required') } - const validTypes = ['bearer', 'api-key', 'oauth', 'openid'] + const validTypes = ['bearer', 'api-key', 'oauth', 'openid', 'none'] if (!validTypes.includes(auth.type)) { throw new Error(`Invalid authentication type: ${auth.type}`) } @@ -119,6 +119,9 @@ export abstract class BaseRuntime implements AgentRuntime { throw new Error('API key is required for api-key authentication') } break + case 'none': + // No validation required for no authentication + break } } diff --git a/packages/core/src/runtime/cache-manager.ts b/packages/core/src/runtime/cache-manager.ts new file mode 100644 index 0000000..be30760 --- /dev/null +++ b/packages/core/src/runtime/cache-manager.ts @@ -0,0 +1,661 @@ +export interface CacheEntry { + key: string; + value: T; + timestamp: number; + ttl: number; // Time to live in milliseconds + accessCount: number; + lastAccessed: number; + size: number; // Estimated size in bytes + tags?: string[]; + metadata?: Record; +} + +export interface CacheConfig { + maxSize: number; // Maximum cache size in bytes + maxEntries: number; // Maximum number of entries + defaultTtl: number; // Default TTL in milliseconds + cleanupInterval: number; // Cleanup interval in milliseconds + evictionPolicy: EvictionPolicy; + compressionThreshold: number; // Size threshold for compression + enableCompression: boolean; + enableMetrics: boolean; +} + +export type EvictionPolicy = 'lru' | 'lfu' | 'fifo' | 'ttl' | 'size'; + +export interface CacheMetrics { + hits: number; + misses: number; + hitRate: number; + totalEntries: number; + totalSize: number; + evictions: number; + compressions: number; + averageAccessTime: number; + memoryUsage: { + used: number; + available: number; + percentage: number; + }; + topKeys: Array<{ key: string; accessCount: number; size: number }>; +} + +export interface CacheQuery { + tags?: string[]; + keyPattern?: RegExp; + minAccessCount?: number; + maxAge?: number; + minSize?: number; + maxSize?: number; +} + +export class CacheManager { + private static instance: CacheManager; + private cache = new Map(); + private accessOrder: string[] = []; // For LRU + private accessFrequency = new Map(); // For LFU + private insertionOrder: string[] = []; // For FIFO + private cleanupTimer?: NodeJS.Timeout; + private metrics: CacheMetrics; + private config: CacheConfig; + + private constructor(config?: Partial) { + this.config = { + maxSize: 50 * 1024 * 1024, // 50MB + maxEntries: 10000, + defaultTtl: 30 * 60 * 1000, // 30 minutes + cleanupInterval: 5 * 60 * 1000, // 5 minutes + evictionPolicy: 'lru', + compressionThreshold: 1024, // 1KB + enableCompression: true, + enableMetrics: true, + ...config + }; + + this.metrics = { + hits: 0, + misses: 0, + hitRate: 0, + totalEntries: 0, + totalSize: 0, + evictions: 0, + compressions: 0, + averageAccessTime: 0, + memoryUsage: { + used: 0, + available: this.config.maxSize, + percentage: 0 + }, + topKeys: [] + }; + + this.startCleanupTimer(); + } + + static getInstance(config?: Partial): CacheManager { + if (!CacheManager.instance) { + CacheManager.instance = new CacheManager(config); + } + return CacheManager.instance; + } + + // Main cache operations + + async set(key: string, value: T, options?: { + ttl?: number; + tags?: string[]; + metadata?: Record; + compress?: boolean; + }): Promise { + const startTime = performance.now(); + + try { + // Calculate size + const serialized = JSON.stringify(value); + let size = new TextEncoder().encode(serialized).length; + let finalValue: T | string = value; + let compressed = false; + + // Apply compression if enabled and threshold met + if ( + this.config.enableCompression && + (options?.compress ?? size >= this.config.compressionThreshold) + ) { + try { + // Simple compression simulation (in real implementation, use compression-utils) + const compressedStr = this.simpleCompress(serialized); + if (compressedStr.length < serialized.length) { + finalValue = compressedStr as T; + size = new TextEncoder().encode(compressedStr).length; + compressed = true; + this.metrics.compressions++; + } + } catch (error) { + console.warn('Compression failed, storing uncompressed:', error); + } + } + + const entry: CacheEntry = { + key, + value: finalValue, + timestamp: Date.now(), + ttl: options?.ttl ?? this.config.defaultTtl, + accessCount: 0, + lastAccessed: Date.now(), + size, + tags: options?.tags, + metadata: { + ...options?.metadata, + compressed + } + }; + + // Check if we need to evict entries + await this.ensureCapacity(size); + + // Remove existing entry if it exists + if (this.cache.has(key)) { + this.removeFromTracking(key); + } + + // Add new entry + const entryWithKey = { ...entry, key }; + this.cache.set(key, entryWithKey); + this.addToTracking(key); + + // Update metrics + if (this.config.enableMetrics) { + this.updateMetricsAfterSet(size, performance.now() - startTime); + } + } catch (error) { + console.error('Cache set operation failed:', error); + throw error; + } + } + + async get(key: string): Promise { + const startTime = performance.now(); + + try { + const entry = this.cache.get(key) as CacheEntry | undefined; + + if (!entry) { + this.metrics.misses++; + this.updateHitRate(); + return null; + } + + // Check TTL + if (this.isExpired(entry)) { + this.delete(key); + this.metrics.misses++; + this.updateHitRate(); + return null; + } + + // Update access tracking + entry.accessCount++; + entry.lastAccessed = Date.now(); + this.updateAccessTracking(key); + + // Handle decompression if needed + let value = entry.value; + if (entry.metadata?.compressed) { + try { + const decompressed = this.simpleDecompress(entry.value as string); + value = JSON.parse(decompressed) as T; + } catch (error) { + console.warn('Decompression failed, returning raw value:', error); + } + } + + // Update metrics + this.metrics.hits++; + this.updateHitRate(); + + if (this.config.enableMetrics) { + this.updateAverageAccessTime(performance.now() - startTime); + } + + return value; + } catch (error) { + console.error('Cache get operation failed:', error); + this.metrics.misses++; + this.updateHitRate(); + return null; + } + } + + delete(key: string): boolean { + const entry = this.cache.get(key); + if (!entry) { + return false; + } + + this.cache.delete(key); + this.removeFromTracking(key); + + // Update metrics + this.metrics.totalEntries = this.cache.size; + this.metrics.totalSize -= entry.size; + this.updateMemoryUsage(); + + return true; + } + + has(key: string): boolean { + const entry = this.cache.get(key); + return entry ? !this.isExpired(entry) : false; + } + + clear(): void { + this.cache.clear(); + this.accessOrder.length = 0; + this.accessFrequency.clear(); + this.insertionOrder.length = 0; + + // Reset metrics + this.metrics.totalEntries = 0; + this.metrics.totalSize = 0; + this.updateMemoryUsage(); + } + + // Advanced operations + + async getMultiple(keys: string[]): Promise> { + const results = new Map(); + + await Promise.all( + keys.map(async (key) => { + const value = await this.get(key); + if (value !== null) { + results.set(key, value); + } + }) + ); + + return results; + } + + async setMultiple(entries: Array<{ key: string; value: T; options?: any }>): Promise { + await Promise.all( + entries.map(({ key, value, options }) => this.set(key, value, options)) + ); + } + + deleteMultiple(keys: string[]): number { + let deletedCount = 0; + for (const key of keys) { + if (this.delete(key)) { + deletedCount++; + } + } + return deletedCount; + } + + // Query operations + + query(query: CacheQuery): CacheEntry[] { + const results: CacheEntry[] = []; + + for (const [key, entry] of this.cache) { + if (this.matchesQuery(key, entry, query)) { + results.push({ ...entry }); + } + } + + return results; + } + + queryKeys(query: CacheQuery): string[] { + return this.query(query).map(entry => entry.key); + } + + deleteByQuery(query: CacheQuery): number { + const keysToDelete = this.queryKeys(query); + return this.deleteMultiple(keysToDelete); + } + + // Tag operations + + getByTag(tag: string): CacheEntry[] { + return this.query({ tags: [tag] }); + } + + deleteByTag(tag: string): number { + return this.deleteByQuery({ tags: [tag] }); + } + + // Utility methods + + private matchesQuery(key: string, entry: CacheEntry, query: CacheQuery): boolean { + // Check tags + if (query.tags && query.tags.length > 0) { + if (!entry.tags || !query.tags.some(tag => entry.tags!.includes(tag))) { + return false; + } + } + + // Check key pattern + if (query.keyPattern && !query.keyPattern.test(key)) { + return false; + } + + // Check access count + if (query.minAccessCount !== undefined && entry.accessCount < query.minAccessCount) { + return false; + } + + // Check age + if (query.maxAge !== undefined) { + const age = Date.now() - entry.timestamp; + if (age > query.maxAge) { + return false; + } + } + + // Check size + if (query.minSize !== undefined && entry.size < query.minSize) { + return false; + } + + if (query.maxSize !== undefined && entry.size > query.maxSize) { + return false; + } + + return true; + } + + private isExpired(entry: CacheEntry): boolean { + return Date.now() - entry.timestamp > entry.ttl; + } + + private async ensureCapacity(newEntrySize: number): Promise { + // Check entry count limit + while (this.cache.size >= this.config.maxEntries) { + await this.evictOne(); + } + + // Check size limit + while (this.metrics.totalSize + newEntrySize > this.config.maxSize) { + await this.evictOne(); + } + } + + private async evictOne(): Promise { + let keyToEvict: string | null = null; + + switch (this.config.evictionPolicy) { + case 'lru': + keyToEvict = this.accessOrder[0] || null; + break; + case 'lfu': + keyToEvict = this.findLeastFrequentlyUsed(); + break; + case 'fifo': + keyToEvict = this.insertionOrder[0] || null; + break; + case 'ttl': + keyToEvict = this.findEarliestExpiring(); + break; + case 'size': + keyToEvict = this.findLargestEntry(); + break; + } + + if (keyToEvict) { + this.delete(keyToEvict); + this.metrics.evictions++; + } + } + + private findLeastFrequentlyUsed(): string | null { + let minFreq = Infinity; + let leastUsedKey: string | null = null; + + for (const [key, freq] of this.accessFrequency) { + if (freq < minFreq) { + minFreq = freq; + leastUsedKey = key; + } + } + + return leastUsedKey; + } + + private findEarliestExpiring(): string | null { + let earliestExpiry = Infinity; + let keyToEvict: string | null = null; + + for (const [key, entry] of this.cache) { + const expiryTime = entry.timestamp + entry.ttl; + if (expiryTime < earliestExpiry) { + earliestExpiry = expiryTime; + keyToEvict = key; + } + } + + return keyToEvict; + } + + private findLargestEntry(): string | null { + let maxSize = 0; + let largestKey: string | null = null; + + for (const [key, entry] of this.cache) { + if (entry.size > maxSize) { + maxSize = entry.size; + largestKey = key; + } + } + + return largestKey; + } + + private addToTracking(key: string): void { + // LRU tracking + this.accessOrder.push(key); + + // LFU tracking + this.accessFrequency.set(key, 0); + + // FIFO tracking + this.insertionOrder.push(key); + } + + private removeFromTracking(key: string): void { + // LRU tracking + const lruIndex = this.accessOrder.indexOf(key); + if (lruIndex > -1) { + this.accessOrder.splice(lruIndex, 1); + } + + // LFU tracking + this.accessFrequency.delete(key); + + // FIFO tracking + const fifoIndex = this.insertionOrder.indexOf(key); + if (fifoIndex > -1) { + this.insertionOrder.splice(fifoIndex, 1); + } + } + + private updateAccessTracking(key: string): void { + // Update LRU order + const index = this.accessOrder.indexOf(key); + if (index > -1) { + this.accessOrder.splice(index, 1); + this.accessOrder.push(key); + } + + // Update LFU frequency + const currentFreq = this.accessFrequency.get(key) || 0; + this.accessFrequency.set(key, currentFreq + 1); + } + + // Cleanup operations + + private startCleanupTimer(): void { + this.cleanupTimer = setInterval(() => { + this.cleanup(); + }, this.config.cleanupInterval); + } + + private cleanup(): void { + const now = Date.now(); + const expiredKeys: string[] = []; + + // Find expired entries + for (const [key, entry] of this.cache) { + if (now - entry.timestamp > entry.ttl) { + expiredKeys.push(key); + } + } + + // Remove expired entries + for (const key of expiredKeys) { + this.delete(key); + } + + // Update metrics + this.updateMetrics(); + } + + // Metrics and monitoring + + private updateMetricsAfterSet(size: number, accessTime: number): void { + this.metrics.totalEntries = this.cache.size; + this.metrics.totalSize += size; + this.updateMemoryUsage(); + this.updateAverageAccessTime(accessTime); + } + + private updateHitRate(): void { + const total = this.metrics.hits + this.metrics.misses; + this.metrics.hitRate = total > 0 ? this.metrics.hits / total : 0; + } + + private updateMemoryUsage(): void { + this.metrics.memoryUsage = { + used: this.metrics.totalSize, + available: this.config.maxSize - this.metrics.totalSize, + percentage: (this.metrics.totalSize / this.config.maxSize) * 100 + }; + } + + private updateAverageAccessTime(accessTime: number): void { + const totalOperations = this.metrics.hits + this.metrics.misses; + if (totalOperations === 1) { + this.metrics.averageAccessTime = accessTime; + } else { + this.metrics.averageAccessTime = + (this.metrics.averageAccessTime * (totalOperations - 1) + accessTime) / totalOperations; + } + } + + private updateMetrics(): void { + this.metrics.totalEntries = this.cache.size; + + // Calculate total size + let totalSize = 0; + for (const entry of this.cache.values()) { + totalSize += entry.size; + } + this.metrics.totalSize = totalSize; + + // Update memory usage + this.updateMemoryUsage(); + + // Update top keys + this.updateTopKeys(); + } + + private updateTopKeys(): void { + const entries = Array.from(this.cache.entries()) + .map(([key, entry]) => ({ + key, + accessCount: entry.accessCount, + size: entry.size + })) + .sort((a, b) => b.accessCount - a.accessCount) + .slice(0, 10); + + this.metrics.topKeys = entries; + } + + // Simple compression/decompression (placeholder) + private simpleCompress(data: string): string { + // Simple run-length encoding for demonstration + return data.replace(/(.)\1+/g, (match, char) => { + return `${char}${match.length}`; + }); + } + + private simpleDecompress(data: string): string { + // Reverse of simple compression + return data.replace(/(.)([0-9]+)/g, (match, char, count) => { + return char.repeat(parseInt(count)); + }); + } + + // Public API + + getMetrics(): CacheMetrics { + this.updateMetrics(); + return { ...this.metrics }; + } + + getConfig(): CacheConfig { + return { ...this.config }; + } + + updateConfig(newConfig: Partial): void { + this.config = { ...this.config, ...newConfig }; + + // Restart cleanup timer if interval changed + if (newConfig.cleanupInterval && this.cleanupTimer) { + clearInterval(this.cleanupTimer); + this.startCleanupTimer(); + } + } + + // Export/Import for persistence + + export(): { entries: Array; config: CacheConfig; metrics: CacheMetrics } { + const entries = Array.from(this.cache.entries()).map(([key, entry]) => ({ ...entry, key })); + return { + entries, + config: this.config, + metrics: this.metrics + }; + } + + import(data: { entries: Array; config?: CacheConfig }): void { + this.clear(); + + if (data.config) { + this.updateConfig(data.config); + } + + // Import entries + for (const entry of data.entries) { + const { key, ...entryData } = entry; + const entryWithKey = { ...entryData, key }; + this.cache.set(key, entryWithKey); + this.addToTracking(key); + } + + this.updateMetrics(); + } + + // Cleanup on destruction + destroy(): void { + if (this.cleanupTimer) { + clearInterval(this.cleanupTimer); + } + this.clear(); + } +} + +// Export singleton instance getter +export const getCacheManager = (config?: Partial) => CacheManager.getInstance(config); \ No newline at end of file diff --git a/packages/core/src/runtime/compression-utils.ts b/packages/core/src/runtime/compression-utils.ts new file mode 100644 index 0000000..cd99dfe --- /dev/null +++ b/packages/core/src/runtime/compression-utils.ts @@ -0,0 +1,621 @@ +export interface CompressionResult { + compressed: string | Uint8Array; + originalSize: number; + compressedSize: number; + compressionRatio: number; + algorithm: CompressionAlgorithm; + metadata?: Record; +} + +export interface CompressionOptions { + algorithm: CompressionAlgorithm; + level?: number; // 1-9 for most algorithms + threshold?: number; // minimum size to compress + chunkSize?: number; // for streaming compression +} + +export type CompressionAlgorithm = 'gzip' | 'deflate' | 'lz4' | 'brotli' | 'none'; + +export interface CompressionMetrics { + totalCompressions: number; + totalOriginalBytes: number; + totalCompressedBytes: number; + averageCompressionRatio: number; + averageCompressionTime: number; + algorithmUsage: Record; +} + +export class CompressionUtils { + private static instance: CompressionUtils; + private metrics: CompressionMetrics = { + totalCompressions: 0, + totalOriginalBytes: 0, + totalCompressedBytes: 0, + averageCompressionRatio: 1, + averageCompressionTime: 0, + algorithmUsage: { + gzip: 0, + deflate: 0, + lz4: 0, + brotli: 0, + none: 0 + } + }; + + private constructor() {} + + static getInstance(): CompressionUtils { + if (!CompressionUtils.instance) { + CompressionUtils.instance = new CompressionUtils(); + } + return CompressionUtils.instance; + } + + // Main compression method + async compress(data: string | object, options: CompressionOptions): Promise { + const startTime = performance.now(); + + // Convert data to string if needed + const inputString = typeof data === 'string' ? data : JSON.stringify(data); + const originalSize = new TextEncoder().encode(inputString).length; + + // Check threshold + if (options.threshold && originalSize < options.threshold) { + return this.createNoCompressionResult(inputString, originalSize); + } + + let result: CompressionResult; + + try { + switch (options.algorithm) { + case 'gzip': + result = await this.compressGzip(inputString, options); + break; + case 'deflate': + result = await this.compressDeflate(inputString, options); + break; + case 'lz4': + result = await this.compressLZ4(inputString, options); + break; + case 'brotli': + result = await this.compressBrotli(inputString, options); + break; + case 'none': + default: + result = this.createNoCompressionResult(inputString, originalSize); + break; + } + + // Update metrics + const compressionTime = performance.now() - startTime; + this.updateMetrics(result, compressionTime); + + return result; + } catch (error) { + console.warn(`Compression failed with ${options.algorithm}, falling back to no compression:`, error); + return this.createNoCompressionResult(inputString, originalSize); + } + } + + // Decompress data + async decompress(compressedData: string | Uint8Array, algorithm: CompressionAlgorithm): Promise { + try { + switch (algorithm) { + case 'gzip': + return await this.decompressGzip(compressedData); + case 'deflate': + return await this.decompressDeflate(compressedData); + case 'lz4': + return await this.decompressLZ4(compressedData); + case 'brotli': + return await this.decompressBrotli(compressedData); + case 'none': + default: + return typeof compressedData === 'string' ? compressedData : new TextDecoder().decode(compressedData); + } + } catch (error) { + console.error(`Decompression failed with ${algorithm}:`, error); + throw new Error(`Failed to decompress data using ${algorithm}`); + } + } + + // GZIP compression (browser-compatible) + private async compressGzip(data: string, options: CompressionOptions): Promise { + if (typeof CompressionStream !== 'undefined') { + // Use native CompressionStream API (modern browsers) + return this.compressWithStream(data, 'gzip', options); + } else { + // Fallback for environments without CompressionStream + return this.compressWithFallback(data, 'gzip', options); + } + } + + // Deflate compression + private async compressDeflate(data: string, options: CompressionOptions): Promise { + if (typeof CompressionStream !== 'undefined') { + return this.compressWithStream(data, 'deflate', options); + } else { + return this.compressWithFallback(data, 'deflate', options); + } + } + + // LZ4 compression (simplified implementation) + private async compressLZ4(data: string, options: CompressionOptions): Promise { + // Simplified LZ4-like compression + const compressed = this.simpleLZ4Compress(data); + const originalSize = new TextEncoder().encode(data).length; + const compressedSize = new TextEncoder().encode(compressed).length; + + return { + compressed, + originalSize, + compressedSize, + compressionRatio: originalSize / compressedSize, + algorithm: 'lz4', + metadata: { level: options.level || 1 } + }; + } + + // Brotli compression + private async compressBrotli(data: string, options: CompressionOptions): Promise { + if (typeof CompressionStream !== 'undefined') { + return this.compressWithStream(data, 'br', options); + } else { + return this.compressWithFallback(data, 'brotli', options); + } + } + + // Use native CompressionStream API + private async compressWithStream(data: string, format: string, options: CompressionOptions): Promise { + const stream = new CompressionStream(format as any); + const writer = stream.writable.getWriter(); + const reader = stream.readable.getReader(); + + // Write data + const encoder = new TextEncoder(); + const inputBytes = encoder.encode(data); + await writer.write(inputBytes); + await writer.close(); + + // Read compressed data + const chunks: Uint8Array[] = []; + let totalSize = 0; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + chunks.push(value); + totalSize += value.length; + } + + // Combine chunks + const compressed = new Uint8Array(totalSize); + let offset = 0; + for (const chunk of chunks) { + compressed.set(chunk, offset); + offset += chunk.length; + } + + return { + compressed, + originalSize: inputBytes.length, + compressedSize: compressed.length, + compressionRatio: inputBytes.length / compressed.length, + algorithm: format === 'br' ? 'brotli' : format as CompressionAlgorithm, + metadata: { level: options.level } + }; + } + + // Fallback compression for environments without native support + private async compressWithFallback(data: string, algorithm: CompressionAlgorithm, options: CompressionOptions): Promise { + // Simple text-based compression fallback + let compressed: string; + + switch (algorithm) { + case 'gzip': + case 'deflate': + compressed = this.simpleDeflateCompress(data); + break; + case 'brotli': + compressed = this.simpleBrotliCompress(data); + break; + default: + compressed = data; + } + + const originalSize = new TextEncoder().encode(data).length; + const compressedSize = new TextEncoder().encode(compressed).length; + + return { + compressed, + originalSize, + compressedSize, + compressionRatio: originalSize / compressedSize, + algorithm, + metadata: { fallback: true, level: options.level } + }; + } + + // Simple deflate-like compression + private simpleDeflateCompress(data: string): string { + // Dictionary-based compression + const dictionary = new Map(); + let dictIndex = 0; + let compressed = data; + + // Find repeated patterns + const patterns = this.findRepeatedPatterns(data, 3, 10); + + // Replace patterns with shorter codes + for (const pattern of patterns) { + if (pattern.length > 3 && pattern.count > 1) { + const code = `\x00${dictIndex.toString(36)}`; + dictionary.set(code, pattern.text); + compressed = compressed.split(pattern.text).join(code); + dictIndex++; + } + } + + // Prepend dictionary + const dictStr = JSON.stringify(Object.fromEntries(dictionary)); + return `${dictStr.length.toString(36)}:${dictStr}${compressed}`; + } + + // Simple Brotli-like compression + private simpleBrotliCompress(data: string): string { + // Use a combination of dictionary and run-length encoding + let compressed = this.runLengthEncode(data); + compressed = this.simpleDeflateCompress(compressed); + return compressed; + } + + // Simple LZ4-like compression + private simpleLZ4Compress(data: string): string { + const result: string[] = []; + let i = 0; + + while (i < data.length) { + // Look for matches in previous data + const match = this.findLongestMatch(data, i, Math.max(0, i - 65536)); + + if (match && match.length >= 4) { + // Encode match as offset:length + result.push(`\x01${(i - match.offset).toString(36)}:${match.length.toString(36)}`); + i += match.length; + } else { + // Literal character + result.push(data[i]); + i++; + } + } + + return result.join(''); + } + + // Run-length encoding + private runLengthEncode(data: string): string { + const result: string[] = []; + let i = 0; + + while (i < data.length) { + const char = data[i]; + let count = 1; + + // Count consecutive characters + while (i + count < data.length && data[i + count] === char && count < 255) { + count++; + } + + if (count > 3) { + result.push(`\x02${count.toString(36)}${char}`); + } else { + result.push(char.repeat(count)); + } + + i += count; + } + + return result.join(''); + } + + // Find repeated patterns in text + private findRepeatedPatterns(text: string, minLength: number, maxLength: number): Array<{ text: string; count: number; length: number }> { + const patterns = new Map(); + + for (let len = minLength; len <= maxLength; len++) { + for (let i = 0; i <= text.length - len; i++) { + const pattern = text.substr(i, len); + patterns.set(pattern, (patterns.get(pattern) || 0) + 1); + } + } + + return Array.from(patterns.entries()) + .filter(([, count]) => count > 1) + .map(([text, count]) => ({ text, count, length: text.length })) + .sort((a, b) => (b.count * b.length) - (a.count * a.length)); + } + + // Find longest match for LZ compression + private findLongestMatch(data: string, pos: number, searchStart: number): { offset: number; length: number } | null { + let bestMatch: { offset: number; length: number } | null = null; + + for (let i = searchStart; i < pos; i++) { + let matchLength = 0; + + while ( + pos + matchLength < data.length && + i + matchLength < pos && + data[pos + matchLength] === data[i + matchLength] && + matchLength < 255 + ) { + matchLength++; + } + + if (matchLength > 0 && (!bestMatch || matchLength > bestMatch.length)) { + bestMatch = { offset: i, length: matchLength }; + } + } + + return bestMatch; + } + + // Decompression methods + private async decompressGzip(data: string | Uint8Array): Promise { + if (typeof DecompressionStream !== 'undefined') { + return this.decompressWithStream(data, 'gzip'); + } else { + return this.decompressWithFallback(data, 'gzip'); + } + } + + private async decompressDeflate(data: string | Uint8Array): Promise { + if (typeof DecompressionStream !== 'undefined') { + return this.decompressWithStream(data, 'deflate'); + } else { + return this.decompressWithFallback(data, 'deflate'); + } + } + + private async decompressLZ4(data: string | Uint8Array): Promise { + const dataStr = typeof data === 'string' ? data : new TextDecoder().decode(data); + return this.simpleLZ4Decompress(dataStr); + } + + private async decompressBrotli(data: string | Uint8Array): Promise { + if (typeof DecompressionStream !== 'undefined') { + return this.decompressWithStream(data, 'br'); + } else { + return this.decompressWithFallback(data, 'brotli'); + } + } + + // Use native DecompressionStream API + private async decompressWithStream(data: string | Uint8Array, format: string): Promise { + const stream = new DecompressionStream(format as any); + const writer = stream.writable.getWriter(); + const reader = stream.readable.getReader(); + + // Write compressed data + const inputBytes = typeof data === 'string' ? new TextEncoder().encode(data) : data; + await writer.write(inputBytes); + await writer.close(); + + // Read decompressed data + const chunks: Uint8Array[] = []; + let totalSize = 0; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + chunks.push(value); + totalSize += value.length; + } + + // Combine chunks and decode + const decompressed = new Uint8Array(totalSize); + let offset = 0; + for (const chunk of chunks) { + decompressed.set(chunk, offset); + offset += chunk.length; + } + + return new TextDecoder().decode(decompressed); + } + + // Fallback decompression + private async decompressWithFallback(data: string | Uint8Array, algorithm: CompressionAlgorithm): Promise { + const dataStr = typeof data === 'string' ? data : new TextDecoder().decode(data); + + switch (algorithm) { + case 'gzip': + case 'deflate': + return this.simpleDeflateDecompress(dataStr); + case 'brotli': + return this.simpleBrotliDecompress(dataStr); + default: + return dataStr; + } + } + + // Simple deflate decompression + private simpleDeflateDecompress(data: string): string { + // Extract dictionary + const colonIndex = data.indexOf(':'); + if (colonIndex === -1) return data; + + const dictLength = parseInt(data.substring(0, colonIndex), 36); + const dictStr = data.substring(colonIndex + 1, colonIndex + 1 + dictLength); + const compressed = data.substring(colonIndex + 1 + dictLength); + + try { + const dictionary = JSON.parse(dictStr); + let decompressed = compressed; + + // Replace codes with original patterns + for (const [code, pattern] of Object.entries(dictionary)) { + decompressed = decompressed.split(code).join(pattern as string); + } + + return decompressed; + } catch { + return data; // Return original if decompression fails + } + } + + // Simple Brotli decompression + private simpleBrotliDecompress(data: string): string { + let decompressed = this.simpleDeflateDecompress(data); + decompressed = this.runLengthDecode(decompressed); + return decompressed; + } + + // Simple LZ4 decompression + private simpleLZ4Decompress(data: string): string { + const result: string[] = []; + let i = 0; + + while (i < data.length) { + if (data[i] === '\x01') { + // Match reference + i++; + const colonIndex = data.indexOf(':', i); + const offset = parseInt(data.substring(i, colonIndex), 36); + const lengthEnd = data.indexOf('\x01', colonIndex + 1); + const endIndex = lengthEnd === -1 ? data.length : lengthEnd; + const length = parseInt(data.substring(colonIndex + 1, endIndex), 36); + + // Copy from previous data + const startPos = result.length - offset; + for (let j = 0; j < length; j++) { + result.push(result[startPos + j] || ''); + } + + i = endIndex; + } else { + // Literal character + result.push(data[i]); + i++; + } + } + + return result.join(''); + } + + // Run-length decoding + private runLengthDecode(data: string): string { + const result: string[] = []; + let i = 0; + + while (i < data.length) { + if (data[i] === '\x02') { + // Run-length encoded sequence + i++; + let countEnd = i; + while (countEnd < data.length && data[countEnd] !== '\x02' && /[0-9a-z]/.test(data[countEnd])) { + countEnd++; + } + + const count = parseInt(data.substring(i, countEnd), 36); + const char = data[countEnd]; + + result.push(char.repeat(count)); + i = countEnd + 1; + } else { + result.push(data[i]); + i++; + } + } + + return result.join(''); + } + + // Create no-compression result + private createNoCompressionResult(data: string, originalSize: number): CompressionResult { + return { + compressed: data, + originalSize, + compressedSize: originalSize, + compressionRatio: 1, + algorithm: 'none' + }; + } + + // Update compression metrics + private updateMetrics(result: CompressionResult, compressionTime: number): void { + this.metrics.totalCompressions++; + this.metrics.totalOriginalBytes += result.originalSize; + this.metrics.totalCompressedBytes += result.compressedSize; + this.metrics.algorithmUsage[result.algorithm]++; + + // Update average compression ratio + this.metrics.averageCompressionRatio = this.metrics.totalOriginalBytes / this.metrics.totalCompressedBytes; + + // Update average compression time + const totalTime = this.metrics.averageCompressionTime * (this.metrics.totalCompressions - 1) + compressionTime; + this.metrics.averageCompressionTime = totalTime / this.metrics.totalCompressions; + } + + // Public API methods + + // Get compression metrics + getMetrics(): CompressionMetrics { + return { ...this.metrics }; + } + + // Get optimal algorithm for data + getOptimalAlgorithm(data: string | object, options?: { prioritizeSpeed?: boolean; prioritizeRatio?: boolean }): CompressionAlgorithm { + const dataStr = typeof data === 'string' ? data : JSON.stringify(data); + const size = new TextEncoder().encode(dataStr).length; + + // Small data - no compression + if (size < 1024) { + return 'none'; + } + + // Medium data - fast compression + if (size < 10240) { + return options?.prioritizeSpeed ? 'lz4' : 'deflate'; + } + + // Large data - best compression + if (options?.prioritizeRatio) { + return 'brotli'; + } else if (options?.prioritizeSpeed) { + return 'lz4'; + } else { + return 'gzip'; // Good balance + } + } + + // Benchmark compression algorithms + async benchmarkAlgorithms(testData: string): Promise> { + const algorithms: CompressionAlgorithm[] = ['none', 'lz4', 'deflate', 'gzip', 'brotli']; + const results: Record = {}; + + for (const algorithm of algorithms) { + const startTime = performance.now(); + + try { + const result = await this.compress(testData, { algorithm }); + const endTime = performance.now(); + + results[algorithm] = { + ratio: result.compressionRatio, + time: endTime - startTime + }; + } catch (error) { + results[algorithm] = { + ratio: 1, + time: 0 + }; + } + } + + return results as Record; + } +} + +// Export singleton instance getter +export const getCompressionUtils = () => CompressionUtils.getInstance(); \ No newline at end of file diff --git a/packages/core/src/runtime/connection-pool.ts b/packages/core/src/runtime/connection-pool.ts new file mode 100644 index 0000000..7e3c554 --- /dev/null +++ b/packages/core/src/runtime/connection-pool.ts @@ -0,0 +1,403 @@ +// Connection pool for optimized connection management and reuse + +import type { + Connection, + ConnectionConfig, + ValidationResult +} from '../types' +import { Connection as RuntimeConnection, ConnectionConfig as RuntimeConnectionConfig } from '../types/runtime'; + +export interface ConnectionPoolOptions { + maxPoolSize?: number + idleTimeout?: number + connectionTimeout?: number + enableHealthCheck?: boolean + healthCheckInterval?: number + maxRetries?: number +} + +export interface PooledConnection { + connection: Connection + poolId: string + createdAt: number + lastUsed: number + isIdle: boolean + healthCheckCount: number + endpoint: string + pool: ConnectionPool + config: ConnectionConfig + close(): Promise +} + +export interface ConnectionPoolMetrics { + totalConnections: number + activeConnections: number + idleConnections: number + poolHitRate: number + averageConnectionTime: number + failedConnections: number +} + +export class ConnectionPool { + private pools = new Map() + private options: Required + private metrics: ConnectionPoolMetrics + private healthCheckTimer: NodeJS.Timeout | null = null + private connectionCounter = 0 + + constructor(options: ConnectionPoolOptions = {}) { + this.options = { + maxPoolSize: options.maxPoolSize ?? 10, + idleTimeout: options.idleTimeout ?? 30000, // 30 seconds + connectionTimeout: options.connectionTimeout ?? 10000, // 10 seconds + enableHealthCheck: options.enableHealthCheck ?? true, + healthCheckInterval: options.healthCheckInterval ?? 60000, // 1 minute + maxRetries: options.maxRetries ?? 3 + } + + this.metrics = { + totalConnections: 0, + activeConnections: 0, + idleConnections: 0, + poolHitRate: 0, + averageConnectionTime: 0, + failedConnections: 0 + } + + if (this.options.enableHealthCheck) { + this.startHealthCheck() + } + + // Clean up idle connections periodically + this.startIdleCleanup() + } + + /** + * Get a connection from the pool or create a new one + */ + async getConnection( + endpoint: string, + config: ConnectionConfig + ): Promise { + const startTime = performance.now() + const poolKey = this.generatePoolKey(endpoint, config) + + try { + // Try to get existing connection from pool + const existingConnection = await this.getExistingConnection(poolKey) + if (existingConnection) { + this.updatePoolHitRate(true) + existingConnection.lastUsed = Date.now() + existingConnection.isIdle = false + this.updateMetrics(performance.now() - startTime, false) + return existingConnection + } + + // Create new connection + const newConnection = await this.createConnection(endpoint, config, poolKey) + this.addToPool(poolKey, newConnection) + + this.updatePoolHitRate(false) + this.updateMetrics(performance.now() - startTime, true) + + return newConnection + } catch (error) { + this.metrics.failedConnections++ + throw error + } + } + + /** + * Return a connection to the pool + */ + releaseConnection(connection: PooledConnection): void { + connection.isIdle = true + connection.lastUsed = Date.now() + this.metrics.activeConnections = Math.max(0, this.metrics.activeConnections - 1) + this.metrics.idleConnections++ + } + + /** + * Remove a connection from the pool + */ + removeConnection(connection: PooledConnection): void { + const poolKey = this.generatePoolKey(connection.endpoint, { + endpoint: connection.endpoint, + authentication: connection.config?.authentication, + protocols: connection.config?.protocols || ['json-rpc', 'json-rest'] + }) + + const pool = this.pools.get(poolKey) + if (pool) { + const index = pool.findIndex(conn => conn.poolId === connection.poolId) + if (index !== -1) { + pool.splice(index, 1) + this.metrics.totalConnections-- + + if (connection.isIdle) { + this.metrics.idleConnections-- + } else { + this.metrics.activeConnections-- + } + + // Clean up empty pools + if (pool.length === 0) { + this.pools.delete(poolKey) + } + } + } + + // Mark connection as disconnected + connection.connection.status = 'disconnected' + } + + /** + * Clear all connections from all pools + */ + clearAll(): void { + for (const pool of this.pools.values()) { + for (const connection of pool) { + if (typeof connection.close === 'function') { + connection.close().catch(console.error) + } + } + } + + this.pools.clear() + this.metrics = { + totalConnections: 0, + activeConnections: 0, + idleConnections: 0, + poolHitRate: 0, + averageConnectionTime: 0, + failedConnections: 0 + } + } + + /** + * Get current pool metrics + */ + getMetrics(): ConnectionPoolMetrics { + return { ...this.metrics } + } + + /** + * Destroy the connection pool + */ + destroy(): void { + if (this.healthCheckTimer) { + clearInterval(this.healthCheckTimer) + this.healthCheckTimer = null + } + + this.clearAll() + } + + /** + * Get existing connection from pool + */ + private async getExistingConnection(poolKey: string): Promise { + const pool = this.pools.get(poolKey) + if (!pool || pool.length === 0) return null + + // Find idle connection + const idleConnection = pool.find(conn => conn.isIdle) + if (idleConnection) { + // Validate connection health + if (await this.isConnectionHealthy(idleConnection)) { + return idleConnection + } else { + // Remove unhealthy connection + this.removeConnection(idleConnection) + return null + } + } + + // No idle connections available + return null + } + + /** + * Create a new connection + */ + private async createConnection( + endpoint: string, + config: ConnectionConfig, + poolKey: string + ): Promise { + const poolId = `conn_${++this.connectionCounter}_${Date.now()}` + + // Create base connection (simplified implementation) + const baseConnection: Connection = { + id: poolId, + agentId: 'pool-agent', + endpoint, + status: 'connecting', + protocols: config.protocols || ['json-rpc', 'json-rest'], + metadata: {}, + createdAt: new Date(), + lastActivity: new Date() + } + + // Create pooled connection wrapper + const pooledConnection: PooledConnection = { + connection: baseConnection, + poolId, + createdAt: Date.now(), + lastUsed: Date.now(), + isIdle: false, + healthCheckCount: 0, + endpoint, + pool: this, + config, + close: async () => { + baseConnection.status = 'disconnected' + this.removeConnection(pooledConnection) + } + } + + // Simulate connection attempt with WebSocket-like interface + await new Promise((resolve, reject) => { + setTimeout(() => { + if (Math.random() > 0.1) { // 90% success rate for simulation + // Simulate WebSocket connection with protocols property + const wsConnection = { + endpoint: config.endpoint, + authentication: config.authentication, + protocols: config.protocols || ['json-rpc', 'json-rest'] + } + resolve() + } else { + reject(new Error('Connection failed')) + } + }, 100) // Simulate connection delay + }) + + baseConnection.status = 'connected' + + return pooledConnection + } + + /** + * Add connection to pool + */ + private addToPool(poolKey: string, connection: PooledConnection): void { + let pool = this.pools.get(poolKey) + if (!pool) { + pool = [] + this.pools.set(poolKey, pool) + } + + // Check pool size limit + if (pool.length >= this.options.maxPoolSize) { + // Remove oldest idle connection + const oldestIdle = pool + .filter(conn => conn.isIdle) + .sort((a, b) => a.lastUsed - b.lastUsed)[0] + + if (oldestIdle) { + this.removeConnection(oldestIdle) + } + } + + pool.push(connection) + this.metrics.totalConnections++ + this.metrics.activeConnections++ + } + + /** + * Generate pool key for connection grouping + */ + private generatePoolKey(endpoint: string, config: ConnectionConfig): string { + const keyData = { + endpoint, + authType: config.authentication?.type, + // Add other relevant config properties for grouping + } + + return JSON.stringify(keyData) + } + + /** + * Check if connection is healthy + */ + private async isConnectionHealthy(connection: PooledConnection): Promise { + try { + // Simple health check - could be enhanced based on protocol + if (connection.connection.status !== 'connected') return false + + // Check if connection is too old + const age = Date.now() - connection.createdAt + if (age > this.options.idleTimeout * 10) return false // Max age is 10x idle timeout + + // Update last activity as health check + connection.connection.lastActivity = new Date() + + connection.healthCheckCount++ + return true + } catch (error) { + return false + } + } + + /** + * Start periodic health checks + */ + private startHealthCheck(): void { + this.healthCheckTimer = setInterval(async () => { + for (const [poolKey, pool] of this.pools.entries()) { + const unhealthyConnections: PooledConnection[] = [] + + for (const connection of pool) { + if (connection.isIdle && !(await this.isConnectionHealthy(connection))) { + unhealthyConnections.push(connection) + } + } + + // Remove unhealthy connections + for (const connection of unhealthyConnections) { + this.removeConnection(connection) + } + } + }, this.options.healthCheckInterval) + } + + /** + * Start idle connection cleanup + */ + private startIdleCleanup(): void { + setInterval(() => { + const now = Date.now() + + for (const pool of this.pools.values()) { + const expiredConnections = pool.filter(conn => + conn.isIdle && (now - conn.lastUsed) > this.options.idleTimeout + ) + + for (const connection of expiredConnections) { + this.removeConnection(connection) + } + } + }, this.options.idleTimeout / 2) // Check twice per timeout period + } + + /** + * Update pool hit rate metrics + */ + private updatePoolHitRate(isHit: boolean): void { + const totalRequests = this.metrics.totalConnections + (isHit ? 0 : 1) + const hits = this.metrics.poolHitRate * (totalRequests - 1) + (isHit ? 1 : 0) + this.metrics.poolHitRate = totalRequests > 0 ? hits / totalRequests : 0 + } + + /** + * Update connection metrics + */ + private updateMetrics(connectionTime: number, isNewConnection: boolean): void { + if (isNewConnection) { + // Update average connection time + const totalTime = this.metrics.averageConnectionTime * (this.metrics.totalConnections - 1) + connectionTime + this.metrics.averageConnectionTime = totalTime / this.metrics.totalConnections + } + } +} \ No newline at end of file diff --git a/packages/core/src/runtime/index.ts b/packages/core/src/runtime/index.ts index 852aa94..d0dc158 100644 --- a/packages/core/src/runtime/index.ts +++ b/packages/core/src/runtime/index.ts @@ -1,5 +1,12 @@ // Export all runtime implementations export * from './base-runtime' -export * from './a2a-runtime' +export * from './runtime-factory' export * from './agentarea-runtime' -export * from './runtime-factory' \ No newline at end of file +export * from './a2a-runtime' +export * from './lazy-runtime-manager' +export * from './connection-pool' +export * from './performance-monitor' +export * from './message-batcher' +export * from './compression-utils' +export * from './cache-manager' +export * from './performance-dashboard' \ No newline at end of file diff --git a/packages/core/src/runtime/lazy-runtime-manager.ts b/packages/core/src/runtime/lazy-runtime-manager.ts new file mode 100644 index 0000000..16f8a80 --- /dev/null +++ b/packages/core/src/runtime/lazy-runtime-manager.ts @@ -0,0 +1,365 @@ +// Lazy runtime manager for optimized initialization and caching + +import type { + AgentRuntime, + RuntimeConfig, + Connection, + ConnectionConfig, + ValidationResult +} from '../types' +import { RuntimeFactory } from './runtime-factory' +// Note: ConnectionPool will be implemented separately +// import { ConnectionPool } from './connection-pool' +import { PerformanceMonitor, getPerformanceMonitor } from './performance-monitor' + +export interface LazyRuntimeOptions { + maxCacheSize?: number + cacheTimeout?: number + preloadProtocols?: string[] + enableMetrics?: boolean +} + +export interface RuntimeMetrics { + initializationTime: number + cacheHitRate: number + activeRuntimes: number + totalRequests: number + averageInitTime: number + performance?: any + connectionPool?: any +} + +export class LazyRuntimeManager { + private runtimeCache = new Map>() + private runtimeInstances = new Map() + // private connectionPool: ConnectionPool // Will be enabled when ConnectionPool is integrated + private factory: RuntimeFactory + private options: Required + private metrics: RuntimeMetrics + private cacheTimers = new Map() + private performanceMonitor: PerformanceMonitor + + constructor(options: LazyRuntimeOptions = {}) { + this.options = { + maxCacheSize: options.maxCacheSize ?? 10, + cacheTimeout: options.cacheTimeout ?? 300000, // 5 minutes + preloadProtocols: options.preloadProtocols ?? [], + enableMetrics: options.enableMetrics ?? true + } + + // this.connectionPool = new ConnectionPool({ + // maxPoolSize: 20, + // idleTimeout: 60000, + // enableHealthCheck: true + // }) // Will be enabled when ConnectionPool is integrated + + this.factory = RuntimeFactory.getInstance() + this.performanceMonitor = getPerformanceMonitor() + + this.metrics = { + initializationTime: 0, + cacheHitRate: 0, + activeRuntimes: 0, + totalRequests: 0, + averageInitTime: 0 + } + + // Preload specified protocols + this.preloadRuntimes() + } + + /** + * Get or create a runtime instance with lazy loading + */ + async getRuntime( + protocolType: 'a2a' | 'agentarea', + config: RuntimeConfig + ): Promise { + const timingId = this.performanceMonitor.startTiming('initialization') + const cacheKey = this.generateCacheKey(protocolType, config) + + this.metrics.totalRequests++ + + try { + // Check if runtime is already cached + if (this.runtimeCache.has(cacheKey)) { + const runtime = await this.runtimeCache.get(cacheKey)! + this.updateCacheHitRate(true) + this.performanceMonitor.endTiming(timingId) + return runtime + } + + // Create new runtime promise + const runtimePromise = this.createRuntime(protocolType, config) + + // Cache the promise to prevent duplicate creation + this.runtimeCache.set(cacheKey, runtimePromise) + + try { + const runtime = await runtimePromise + this.runtimeInstances.set(cacheKey, runtime) + + // Set up cache expiration + this.setupCacheExpiration(cacheKey) + + // Update metrics + const initTime = this.performanceMonitor.endTiming(timingId) + this.updateMetrics(initTime) + this.updateCacheHitRate(false) + + // Manage cache size + this.manageCacheSize() + + return runtime + } catch (error) { + // Remove failed promise from cache + this.runtimeCache.delete(cacheKey) + throw error + } + } catch (error) { + this.performanceMonitor.endTiming(timingId) + this.performanceMonitor.incrementCounter('errors') + throw error + } + } + + /** + * Get a connection from the pool for a specific endpoint + */ + async getConnection( + endpoint: string, + config: ConnectionConfig + ): Promise { + // return this.connectionPool.getConnection(endpoint, config) // Will be enabled when ConnectionPool is integrated + throw new Error('ConnectionPool not yet implemented') + } + + /** + * Validate connection configuration without creating runtime + */ + async validateConnection( + protocolType: 'a2a' | 'agentarea', + config: ConnectionConfig + ): Promise { + try { + // Use a lightweight validation approach + const tempRuntime = await this.getRuntime(protocolType, { + endpoint: config.endpoint, + authentication: config.authentication + }) + + return await tempRuntime.validateConnection(config) + } catch (error) { + return { + valid: false, + errors: [{ + code: 'VALIDATION_ERROR', + message: (error as Error).message, + field: 'connection' + }] + } + } + } + + /** + * Clear specific runtime from cache + */ + clearRuntime(protocolType: 'a2a' | 'agentarea', config: RuntimeConfig): void { + const cacheKey = this.generateCacheKey(protocolType, config) + + // Clear timer + const timer = this.cacheTimers.get(cacheKey) + if (timer) { + clearTimeout(timer) + this.cacheTimers.delete(cacheKey) + } + + // Remove from caches + this.runtimeCache.delete(cacheKey) + this.runtimeInstances.delete(cacheKey) + + this.metrics.activeRuntimes = Math.max(0, this.metrics.activeRuntimes - 1) + } + + /** + * Clear all cached runtimes + */ + clearAll(): void { + // Clear all timers + for (const timer of this.cacheTimers.values()) { + clearTimeout(timer) + } + + this.cacheTimers.clear() + this.runtimeCache.clear() + this.runtimeInstances.clear() + // this.connectionPool.clearAll() // Will be enabled when ConnectionPool is integrated + + this.metrics.activeRuntimes = 0 + } + + /** + * Get current performance metrics + */ + getMetrics(): RuntimeMetrics { + const performanceMetrics = this.performanceMonitor.getCurrentMetrics() + + return { + ...this.metrics, + performance: performanceMetrics + // connectionPool: this.connectionPool.getMetrics() // Will be enabled when ConnectionPool is integrated + } + } + + /** + * Preload runtimes for specified protocols + */ + private async preloadRuntimes(): Promise { + if (this.options.preloadProtocols.length === 0) return + + const preloadPromises = this.options.preloadProtocols.map(async (protocol) => { + try { + if (protocol === 'a2a' || protocol === 'agentarea') { + // Create minimal config for preloading + const config: RuntimeConfig = { + endpoint: 'http://localhost:3000', // Placeholder + timeout: 5000 + } + + await this.getRuntime(protocol, config) + } + } catch (error) { + // Ignore preload errors + console.warn(`Failed to preload runtime for protocol ${protocol}:`, error) + } + }) + + await Promise.allSettled(preloadPromises) + } + + /** + * Create a new runtime instance + */ + private async createRuntime( + protocolType: 'a2a' | 'agentarea', + config: RuntimeConfig + ): Promise { + const connectionTimingId = this.performanceMonitor.startTiming('connection') + + try { + // Enhance config (connection pool integration pending) + const enhancedConfig = { + ...config + // connectionPool: this.connectionPool // Will be enabled when ConnectionPool is integrated + } + + const runtime = this.factory.createRuntime(protocolType, enhancedConfig) + + this.performanceMonitor.endTiming(connectionTimingId) + this.performanceMonitor.incrementCounter('connections') + + // Initialize runtime if needed + if (typeof (runtime as any).initialize === 'function') { + await (runtime as any).initialize() + } + + this.metrics.activeRuntimes++ + + return runtime + } catch (error) { + this.performanceMonitor.endTiming(connectionTimingId) + this.performanceMonitor.incrementCounter('errors') + throw error + } + } + + /** + * Generate cache key for runtime configuration + */ + private generateCacheKey(protocolType: string, config: RuntimeConfig): string { + const keyData = { + protocol: protocolType, + endpoint: config.endpoint, + authType: config.authentication?.type, + // Include other relevant config properties + timeout: config.timeout, + transport: config.transport?.type + } + + return JSON.stringify(keyData) + } + + /** + * Set up cache expiration for a runtime + */ + private setupCacheExpiration(cacheKey: string): void { + const timer = setTimeout(() => { + this.runtimeCache.delete(cacheKey) + this.runtimeInstances.delete(cacheKey) + this.cacheTimers.delete(cacheKey) + this.metrics.activeRuntimes = Math.max(0, this.metrics.activeRuntimes - 1) + }, this.options.cacheTimeout) + + this.cacheTimers.set(cacheKey, timer) + } + + /** + * Manage cache size by removing oldest entries + */ + private manageCacheSize(): void { + if (this.runtimeCache.size <= this.options.maxCacheSize) return + + // Remove oldest entries (simple FIFO approach) + const keysToRemove = Array.from(this.runtimeCache.keys()) + .slice(0, this.runtimeCache.size - this.options.maxCacheSize) + + for (const key of keysToRemove) { + const timer = this.cacheTimers.get(key) + if (timer) { + clearTimeout(timer) + this.cacheTimers.delete(key) + } + + this.runtimeCache.delete(key) + this.runtimeInstances.delete(key) + this.metrics.activeRuntimes = Math.max(0, this.metrics.activeRuntimes - 1) + } + } + + /** + * Update initialization metrics + */ + private updateMetrics(initTime: number): void { + this.metrics.initializationTime = initTime + + // Update rolling average + const totalTime = this.metrics.averageInitTime * (this.metrics.totalRequests - 1) + initTime + this.metrics.averageInitTime = totalTime / this.metrics.totalRequests + } + + /** + * Update cache hit rate + */ + private updateCacheHitRate(isHit: boolean): void { + const hits = this.metrics.cacheHitRate * (this.metrics.totalRequests - 1) + const newHits = hits + (isHit ? 1 : 0) + this.metrics.cacheHitRate = newHits / this.metrics.totalRequests + } +} + +// Singleton instance for global access +let globalLazyRuntimeManager: LazyRuntimeManager | null = null + +export function getLazyRuntimeManager(options?: LazyRuntimeOptions): LazyRuntimeManager { + if (!globalLazyRuntimeManager) { + globalLazyRuntimeManager = new LazyRuntimeManager(options) + } + return globalLazyRuntimeManager +} + +export function resetLazyRuntimeManager(): void { + if (globalLazyRuntimeManager) { + globalLazyRuntimeManager.clearAll() + globalLazyRuntimeManager = null + } +} \ No newline at end of file diff --git a/packages/core/src/runtime/message-batcher.ts b/packages/core/src/runtime/message-batcher.ts new file mode 100644 index 0000000..3ed50a4 --- /dev/null +++ b/packages/core/src/runtime/message-batcher.ts @@ -0,0 +1,448 @@ +import { PerformanceMonitor, getPerformanceMonitor } from './performance-monitor'; + +export interface BatchableMessage { + id: string; + type: string; + payload: unknown; + priority: 'low' | 'normal' | 'high' | 'critical'; + timestamp: Date; + retryCount?: number; + maxRetries?: number; + timeout?: number; +} + +export interface BatchConfig { + maxBatchSize: number; + maxWaitTime: number; // milliseconds + priorityThresholds: { + critical: number; // immediate send + high: number; // fast batch + normal: number; // normal batch + low: number; // slow batch + }; + compressionEnabled: boolean; + compressionThreshold: number; // bytes +} + +export interface BatchResult { + batchId: string; + messageIds: string[]; + success: boolean; + error?: Error; + timestamp: Date; + processingTime: number; + compressionRatio?: number; +} + +export interface BatchMetrics { + totalBatches: number; + totalMessages: number; + averageBatchSize: number; + averageProcessingTime: number; + compressionSavings: number; + failureRate: number; +} + +export class MessageBatcher { + private static instance: MessageBatcher; + private config: BatchConfig; + private performanceMonitor: PerformanceMonitor; + + // Message queues by priority + private queues = { + critical: [] as BatchableMessage[], + high: [] as BatchableMessage[], + normal: [] as BatchableMessage[], + low: [] as BatchableMessage[] + }; + + // Batch timers + private batchTimers = new Map(); + + // Metrics tracking + private metrics: BatchMetrics = { + totalBatches: 0, + totalMessages: 0, + averageBatchSize: 0, + averageProcessingTime: 0, + compressionSavings: 0, + failureRate: 0 + }; + + // Processing state + private isProcessing = false; + private processingQueue: BatchableMessage[] = []; + + private constructor(config: BatchConfig) { + this.config = config; + this.performanceMonitor = getPerformanceMonitor(); + this.startBatchProcessing(); + } + + static getInstance(config?: BatchConfig): MessageBatcher { + if (!MessageBatcher.instance) { + const defaultConfig: BatchConfig = { + maxBatchSize: 50, + maxWaitTime: 1000, // 1 second + priorityThresholds: { + critical: 0, // immediate + high: 100, // 100ms + normal: 1000, // 1s + low: 5000 // 5s + }, + compressionEnabled: true, + compressionThreshold: 1024 // 1KB + }; + + MessageBatcher.instance = new MessageBatcher(config || defaultConfig); + } + + return MessageBatcher.instance; + } + + // Add message to batch queue + async addMessage(message: BatchableMessage): Promise { + const timingId = this.performanceMonitor.startTiming('message'); + + try { + // Validate message + this.validateMessage(message); + + // Add to appropriate queue based on priority + this.queues[message.priority].push(message); + + // Handle critical messages immediately + if (message.priority === 'critical') { + await this.processCriticalMessage(message); + this.performanceMonitor.endTiming(timingId); + return; + } + + // Schedule batch processing if not already scheduled + this.scheduleBatchProcessing(message.priority); + + this.performanceMonitor.endTiming(timingId); + this.performanceMonitor.incrementCounter('messages'); + } catch (error) { + this.performanceMonitor.endTiming(timingId); + this.performanceMonitor.incrementCounter('errors'); + throw error; + } + } + + // Validate message structure + private validateMessage(message: BatchableMessage): void { + if (!message.id || !message.type) { + throw new Error('Message must have id and type'); + } + + if (!['low', 'normal', 'high', 'critical'].includes(message.priority)) { + throw new Error('Invalid message priority'); + } + + if (message.timeout && message.timeout < 0) { + throw new Error('Message timeout must be positive'); + } + } + + // Process critical message immediately + private async processCriticalMessage(message: BatchableMessage): Promise { + const batch = [message]; + await this.processBatch(batch, 'critical-immediate'); + } + + // Schedule batch processing for a priority level + private scheduleBatchProcessing(priority: keyof typeof this.queues): void { + const timerKey = `batch-${priority}`; + + // Clear existing timer if any + if (this.batchTimers.has(timerKey)) { + clearTimeout(this.batchTimers.get(timerKey)!); + } + + // Set new timer based on priority threshold + const delay = this.config.priorityThresholds[priority]; + const timer = setTimeout(() => { + this.processPriorityQueue(priority); + this.batchTimers.delete(timerKey); + }, delay); + + this.batchTimers.set(timerKey, timer); + } + + // Process messages from a specific priority queue + private async processPriorityQueue(priority: keyof typeof this.queues): Promise { + const queue = this.queues[priority]; + if (queue.length === 0) return; + + // Create batches from queue + const batches = this.createBatches(queue, this.config.maxBatchSize); + + // Clear the queue + this.queues[priority] = []; + + // Process each batch + for (const batch of batches) { + await this.processBatch(batch, `${priority}-batch`); + } + } + + // Create batches from message array + private createBatches(messages: BatchableMessage[], maxSize: number): BatchableMessage[][] { + const batches: BatchableMessage[][] = []; + + for (let i = 0; i < messages.length; i += maxSize) { + batches.push(messages.slice(i, i + maxSize)); + } + + return batches; + } + + // Process a batch of messages + private async processBatch(messages: BatchableMessage[], batchType: string): Promise { + const batchId = `batch-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + const startTime = Date.now(); + + try { + // Prepare batch payload + let payload = this.prepareBatchPayload(messages); + let compressionRatio: number | undefined; + + // Apply compression if enabled and threshold met + if (this.config.compressionEnabled) { + const originalSize = JSON.stringify(payload).length; + if (originalSize > this.config.compressionThreshold) { + const compressed = await this.compressPayload(payload); + const compressedSize = compressed.length; + compressionRatio = originalSize / compressedSize; + payload = compressed; + + // Update compression metrics + this.metrics.compressionSavings += (originalSize - compressedSize); + } + } + + // Send batch (placeholder - would integrate with actual transport) + await this.sendBatch(batchId, payload, batchType); + + const processingTime = Date.now() - startTime; + + // Update metrics + this.updateBatchMetrics(messages.length, processingTime, true); + + const result: BatchResult = { + batchId, + messageIds: messages.map(m => m.id), + success: true, + timestamp: new Date(), + processingTime, + compressionRatio + }; + + return result; + } catch (error) { + const processingTime = Date.now() - startTime; + + // Update failure metrics + this.updateBatchMetrics(messages.length, processingTime, false); + + // Handle retry logic + await this.handleBatchFailure(messages, error as Error); + + const result: BatchResult = { + batchId, + messageIds: messages.map(m => m.id), + success: false, + error: error as Error, + timestamp: new Date(), + processingTime + }; + + return result; + } + } + + // Prepare batch payload + private prepareBatchPayload(messages: BatchableMessage[]): any { + return { + batchId: `batch-${Date.now()}`, + timestamp: new Date().toISOString(), + messageCount: messages.length, + messages: messages.map(msg => ({ + id: msg.id, + type: msg.type, + payload: msg.payload, + priority: msg.priority, + timestamp: msg.timestamp.toISOString() + })) + }; + } + + // Compress payload (placeholder implementation) + private async compressPayload(payload: any): Promise { + // In a real implementation, this would use a compression library like pako or lz-string + const jsonString = JSON.stringify(payload); + + // Simple compression simulation (in reality, use proper compression) + const compressed = jsonString + .replace(/\s+/g, ' ') // Remove extra whitespace + .replace(/"([^"]+)":/g, '$1:') // Remove quotes from keys where possible + .trim(); + + return compressed; + } + + // Send batch (placeholder - integrate with transport layer) + private async sendBatch(batchId: string, payload: any, batchType: string): Promise { + // Simulate network delay + await new Promise(resolve => setTimeout(resolve, Math.random() * 100)); + + // Simulate occasional failures for testing + if (Math.random() < 0.05) { // 5% failure rate + throw new Error(`Batch send failed: ${batchId}`); + } + + console.log(`Batch sent successfully: ${batchId} (${batchType})`); + } + + // Handle batch processing failure + private async handleBatchFailure(messages: BatchableMessage[], error: Error): Promise { + console.error('Batch processing failed:', error); + + // Retry logic for failed messages + const retryableMessages = messages.filter(msg => { + const retryCount = (msg.retryCount || 0) + 1; + const maxRetries = msg.maxRetries || 3; + + if (retryCount <= maxRetries) { + msg.retryCount = retryCount; + return true; + } + + return false; + }); + + // Re-queue retryable messages with lower priority + for (const message of retryableMessages) { + // Reduce priority for retry (except critical) + if (message.priority !== 'critical') { + const priorities = ['low', 'normal', 'high']; + const currentIndex = priorities.indexOf(message.priority); + if (currentIndex > 0) { + message.priority = priorities[currentIndex - 1] as any; + } + } + + this.queues[message.priority].push(message); + } + + // Schedule retry processing + if (retryableMessages.length > 0) { + setTimeout(() => { + for (const priority of Object.keys(this.queues) as Array) { + if (this.queues[priority].length > 0) { + this.scheduleBatchProcessing(priority); + } + } + }, 5000); // 5 second delay for retries + } + } + + // Update batch processing metrics + private updateBatchMetrics(messageCount: number, processingTime: number, success: boolean): void { + this.metrics.totalBatches++; + this.metrics.totalMessages += messageCount; + + // Update average batch size + this.metrics.averageBatchSize = this.metrics.totalMessages / this.metrics.totalBatches; + + // Update average processing time + const totalTime = this.metrics.averageProcessingTime * (this.metrics.totalBatches - 1) + processingTime; + this.metrics.averageProcessingTime = totalTime / this.metrics.totalBatches; + + // Update failure rate + if (!success) { + const totalFailures = this.metrics.failureRate * (this.metrics.totalBatches - 1) + 1; + this.metrics.failureRate = totalFailures / this.metrics.totalBatches; + } else { + const totalFailures = this.metrics.failureRate * (this.metrics.totalBatches - 1); + this.metrics.failureRate = totalFailures / this.metrics.totalBatches; + } + } + + // Start periodic batch processing + private startBatchProcessing(): void { + setInterval(() => { + this.processAllQueues(); + }, this.config.maxWaitTime); + } + + // Process all non-empty queues + private async processAllQueues(): Promise { + if (this.isProcessing) return; + + this.isProcessing = true; + + try { + // Process in priority order: high -> normal -> low + const priorities: Array = ['high', 'normal', 'low']; + + for (const priority of priorities) { + if (this.queues[priority].length > 0) { + await this.processPriorityQueue(priority); + } + } + } finally { + this.isProcessing = false; + } + } + + // Public API methods + + // Get current metrics + getMetrics(): BatchMetrics { + return { ...this.metrics }; + } + + // Get queue status + getQueueStatus(): { [K in keyof typeof this.queues]: number } { + return { + critical: this.queues.critical.length, + high: this.queues.high.length, + normal: this.queues.normal.length, + low: this.queues.low.length + }; + } + + // Force process all queues + async flushAll(): Promise { + // Clear all timers + for (const timer of this.batchTimers.values()) { + clearTimeout(timer); + } + this.batchTimers.clear(); + + // Process all queues immediately + await this.processAllQueues(); + } + + // Update configuration + updateConfig(newConfig: Partial): void { + this.config = { ...this.config, ...newConfig }; + } + + // Shutdown batcher + async shutdown(): Promise { + // Clear all timers + for (const timer of this.batchTimers.values()) { + clearTimeout(timer); + } + this.batchTimers.clear(); + + // Process remaining messages + await this.flushAll(); + } +} + +// Export singleton instance getter +export const getMessageBatcher = () => MessageBatcher.getInstance(); \ No newline at end of file diff --git a/packages/core/src/runtime/performance-dashboard.ts b/packages/core/src/runtime/performance-dashboard.ts new file mode 100644 index 0000000..9d0897c --- /dev/null +++ b/packages/core/src/runtime/performance-dashboard.ts @@ -0,0 +1,679 @@ +export interface DashboardConfig { + refreshInterval: number; // milliseconds + maxDataPoints: number; + enableRealTimeUpdates: boolean; + enableAlerts: boolean; + thresholds: { + memoryUsage: number; // percentage + responseTime: number; // milliseconds + errorRate: number; // percentage + cacheHitRate: number; // percentage + }; +} + +export interface MetricDataPoint { + timestamp: number; + value: number; + label?: string; + metadata?: Record; +} + +export interface ChartData { + labels: string[]; + datasets: Array<{ + label: string; + data: number[]; + color: string; + type: 'line' | 'bar' | 'area'; + }>; +} + +export interface DashboardWidget { + id: string; + title: string; + type: 'metric' | 'chart' | 'table' | 'alert'; + size: 'small' | 'medium' | 'large'; + position: { x: number; y: number; width: number; height: number }; + config: Record; + data: unknown; +} + +export interface AlertRule { + id: string; + name: string; + metric: string; + condition: 'gt' | 'lt' | 'eq' | 'gte' | 'lte'; + threshold: number; + severity: 'low' | 'medium' | 'high' | 'critical'; + enabled: boolean; + cooldown: number; // milliseconds + lastTriggered?: number; +} + +export interface DashboardAlert { + id: string; + ruleId: string; + message: string; + severity: 'low' | 'medium' | 'high' | 'critical'; + timestamp: number; + acknowledged: boolean; + metadata?: Record; +} + +export class PerformanceDashboard { + private static instance: PerformanceDashboard; + private config: DashboardConfig; + private widgets = new Map(); + private metrics = new Map(); + private alerts: DashboardAlert[] = []; + private alertRules = new Map(); + private updateTimer?: NodeJS.Timeout; + private subscribers = new Set<(data: DashboardData) => void>(); + + private constructor(config?: Partial) { + this.config = { + refreshInterval: 5000, // 5 seconds + maxDataPoints: 100, + enableRealTimeUpdates: true, + enableAlerts: true, + thresholds: { + memoryUsage: 80, + responseTime: 1000, + errorRate: 5, + cacheHitRate: 90 + }, + ...config + }; + + this.initializeDefaultWidgets(); + this.initializeDefaultAlertRules(); + + if (this.config.enableRealTimeUpdates) { + this.startUpdateTimer(); + } + } + + static getInstance(config?: Partial): PerformanceDashboard { + if (!PerformanceDashboard.instance) { + PerformanceDashboard.instance = new PerformanceDashboard(config); + } + return PerformanceDashboard.instance; + } + + // Widget management + + addWidget(widget: DashboardWidget): void { + this.widgets.set(widget.id, widget); + this.notifySubscribers(); + } + + removeWidget(widgetId: string): boolean { + const removed = this.widgets.delete(widgetId); + if (removed) { + this.notifySubscribers(); + } + return removed; + } + + updateWidget(widgetId: string, updates: Partial): void { + const widget = this.widgets.get(widgetId); + if (widget) { + this.widgets.set(widgetId, { ...widget, ...updates }); + this.notifySubscribers(); + } + } + + getWidget(widgetId: string): DashboardWidget | undefined { + return this.widgets.get(widgetId); + } + + getAllWidgets(): DashboardWidget[] { + return Array.from(this.widgets.values()); + } + + // Metric management + + addMetricData(metricName: string, dataPoint: MetricDataPoint): void { + if (!this.metrics.has(metricName)) { + this.metrics.set(metricName, []); + } + + const data = this.metrics.get(metricName)!; + data.push(dataPoint); + + // Keep only the latest data points + if (data.length > this.config.maxDataPoints) { + data.splice(0, data.length - this.config.maxDataPoints); + } + + // Check alert rules + if (this.config.enableAlerts) { + this.checkAlertRules(metricName, dataPoint.value); + } + + this.notifySubscribers(); + } + + getMetricData(metricName: string): MetricDataPoint[] { + return this.metrics.get(metricName) || []; + } + + getAllMetrics(): Map { + return new Map(this.metrics); + } + + clearMetricData(metricName?: string): void { + if (metricName) { + this.metrics.delete(metricName); + } else { + this.metrics.clear(); + } + this.notifySubscribers(); + } + + // Chart data generation + + generateChartData(metricNames: string[], timeRange?: { start: number; end: number }): ChartData { + const colors = ['#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6', '#06b6d4']; + const datasets: ChartData['datasets'] = []; + const allTimestamps = new Set(); + + // Collect all timestamps + metricNames.forEach(metricName => { + const data = this.getMetricData(metricName); + data.forEach(point => { + if (!timeRange || (point.timestamp >= timeRange.start && point.timestamp <= timeRange.end)) { + allTimestamps.add(point.timestamp); + } + }); + }); + + const sortedTimestamps = Array.from(allTimestamps).sort(); + const labels = sortedTimestamps.map(ts => new Date(ts).toLocaleTimeString()); + + // Generate datasets + metricNames.forEach((metricName, index) => { + const data = this.getMetricData(metricName); + const dataMap = new Map(data.map(point => [point.timestamp, point.value])); + + const values = sortedTimestamps.map(ts => dataMap.get(ts) || 0); + + datasets.push({ + label: metricName, + data: values, + color: colors[index % colors.length], + type: 'line' + }); + }); + + return { labels, datasets }; + } + + // Alert management + + addAlertRule(rule: AlertRule): void { + this.alertRules.set(rule.id, rule); + } + + removeAlertRule(ruleId: string): boolean { + return this.alertRules.delete(ruleId); + } + + updateAlertRule(ruleId: string, updates: Partial): void { + const rule = this.alertRules.get(ruleId); + if (rule) { + this.alertRules.set(ruleId, { ...rule, ...updates }); + } + } + + getAlertRule(ruleId: string): AlertRule | undefined { + return this.alertRules.get(ruleId); + } + + getAllAlertRules(): AlertRule[] { + return Array.from(this.alertRules.values()); + } + + private checkAlertRules(metricName: string, value: number): void { + const now = Date.now(); + + for (const rule of this.alertRules.values()) { + if (!rule.enabled || rule.metric !== metricName) { + continue; + } + + // Check cooldown + if (rule.lastTriggered && (now - rule.lastTriggered) < rule.cooldown) { + continue; + } + + // Check condition + let triggered = false; + switch (rule.condition) { + case 'gt': + triggered = value > rule.threshold; + break; + case 'gte': + triggered = value >= rule.threshold; + break; + case 'lt': + triggered = value < rule.threshold; + break; + case 'lte': + triggered = value <= rule.threshold; + break; + case 'eq': + triggered = value === rule.threshold; + break; + } + + if (triggered) { + this.triggerAlert(rule, value); + } + } + } + + private triggerAlert(rule: AlertRule, value: number): void { + const alert: DashboardAlert = { + id: `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + ruleId: rule.id, + message: `${rule.name}: ${rule.metric} is ${value} (threshold: ${rule.threshold})`, + severity: rule.severity, + timestamp: Date.now(), + acknowledged: false, + metadata: { + metric: rule.metric, + value, + threshold: rule.threshold, + condition: rule.condition + } + }; + + this.alerts.unshift(alert); + + // Keep only the latest 100 alerts + if (this.alerts.length > 100) { + this.alerts = this.alerts.slice(0, 100); + } + + // Update rule's last triggered time + rule.lastTriggered = Date.now(); + + this.notifySubscribers(); + } + + getAlerts(options?: { severity?: string; acknowledged?: boolean; limit?: number }): DashboardAlert[] { + let filtered = this.alerts; + + if (options?.severity) { + filtered = filtered.filter(alert => alert.severity === options.severity); + } + + if (options?.acknowledged !== undefined) { + filtered = filtered.filter(alert => alert.acknowledged === options.acknowledged); + } + + if (options?.limit) { + filtered = filtered.slice(0, options.limit); + } + + return filtered; + } + + acknowledgeAlert(alertId: string): boolean { + const alert = this.alerts.find(a => a.id === alertId); + if (alert) { + alert.acknowledged = true; + this.notifySubscribers(); + return true; + } + return false; + } + + clearAlerts(acknowledged?: boolean): void { + if (acknowledged !== undefined) { + this.alerts = this.alerts.filter(alert => alert.acknowledged !== acknowledged); + } else { + this.alerts = []; + } + this.notifySubscribers(); + } + + // Data collection from various sources + + async collectRuntimeMetrics(): Promise { + const timestamp = Date.now(); + + try { + // Memory usage + if (typeof performance !== 'undefined' && (performance as any).memory) { + const memory = (performance as any).memory; + this.addMetricData('memory.used', { + timestamp, + value: memory.usedJSHeapSize / 1024 / 1024 // MB + }); + + this.addMetricData('memory.total', { + timestamp, + value: memory.totalJSHeapSize / 1024 / 1024 // MB + }); + + this.addMetricData('memory.usage_percentage', { + timestamp, + value: (memory.usedJSHeapSize / memory.totalJSHeapSize) * 100 + }); + } + + // Performance timing + if (typeof performance !== 'undefined' && (performance as any).timing) { + const timing = (performance as any).timing; + const loadTime = timing.loadEventEnd - timing.navigationStart; + + if (loadTime > 0) { + this.addMetricData('page.load_time', { + timestamp, + value: loadTime + }); + } + } + + // Connection information (browser only) + if (typeof globalThis !== 'undefined' && (globalThis as any).navigator?.connection) { + const connection = (globalThis as any).navigator.connection; + + this.addMetricData('network.downlink', { + timestamp, + value: connection.downlink || 0 + }); + + this.addMetricData('network.rtt', { + timestamp, + value: connection.rtt || 0 + }); + } + + } catch (error) { + console.warn('Failed to collect runtime metrics:', error); + } + } + + async collectCacheMetrics(): Promise { + try { + // This would integrate with the CacheManager + // For now, we'll simulate some cache metrics + const timestamp = Date.now(); + + // Simulated cache metrics + this.addMetricData('cache.hit_rate', { + timestamp, + value: Math.random() * 100 // 0-100% + }); + + this.addMetricData('cache.size', { + timestamp, + value: Math.random() * 50 // 0-50MB + }); + + this.addMetricData('cache.entries', { + timestamp, + value: Math.floor(Math.random() * 1000) // 0-1000 entries + }); + + } catch (error) { + console.warn('Failed to collect cache metrics:', error); + } + } + + async collectPerformanceMetrics(): Promise { + try { + // This would integrate with the PerformanceMonitor + const timestamp = Date.now(); + + // Simulated performance metrics + this.addMetricData('performance.response_time', { + timestamp, + value: Math.random() * 500 + 100 // 100-600ms + }); + + this.addMetricData('performance.throughput', { + timestamp, + value: Math.random() * 1000 + 500 // 500-1500 ops/sec + }); + + this.addMetricData('performance.error_rate', { + timestamp, + value: Math.random() * 10 // 0-10% + }); + + } catch (error) { + console.warn('Failed to collect performance metrics:', error); + } + } + + // Real-time updates + + private startUpdateTimer(): void { + this.updateTimer = setInterval(async () => { + await this.collectAllMetrics(); + }, this.config.refreshInterval); + } + + private async collectAllMetrics(): Promise { + await Promise.all([ + this.collectRuntimeMetrics(), + this.collectCacheMetrics(), + this.collectPerformanceMetrics() + ]); + } + + // Subscription management + + subscribe(callback: (data: DashboardData) => void): () => void { + this.subscribers.add(callback); + + // Send initial data + callback(this.getDashboardData()); + + // Return unsubscribe function + return () => { + this.subscribers.delete(callback); + }; + } + + private notifySubscribers(): void { + const data = this.getDashboardData(); + for (const callback of this.subscribers) { + try { + callback(data); + } catch (error) { + console.error('Error notifying dashboard subscriber:', error); + } + } + } + + // Dashboard data export + + getDashboardData(): DashboardData { + return { + widgets: this.getAllWidgets(), + metrics: Object.fromEntries(this.metrics), + alerts: this.getAlerts({ limit: 20 }), + alertRules: this.getAllAlertRules(), + config: this.config, + timestamp: Date.now() + }; + } + + // Configuration + + updateConfig(newConfig: Partial): void { + this.config = { ...this.config, ...newConfig }; + + // Restart timer if refresh interval changed + if (newConfig.refreshInterval && this.updateTimer) { + clearInterval(this.updateTimer); + if (this.config.enableRealTimeUpdates) { + this.startUpdateTimer(); + } + } + + this.notifySubscribers(); + } + + getConfig(): DashboardConfig { + return { ...this.config }; + } + + // Initialize default widgets and rules + + private initializeDefaultWidgets(): void { + const defaultWidgets: DashboardWidget[] = [ + { + id: 'memory-usage', + title: 'Memory Usage', + type: 'metric', + size: 'small', + position: { x: 0, y: 0, width: 1, height: 1 }, + config: { metric: 'memory.usage_percentage', unit: '%' }, + data: null + }, + { + id: 'response-time', + title: 'Response Time', + type: 'chart', + size: 'medium', + position: { x: 1, y: 0, width: 2, height: 1 }, + config: { metrics: ['performance.response_time'], timeRange: 300000 }, + data: null + }, + { + id: 'cache-hit-rate', + title: 'Cache Hit Rate', + type: 'metric', + size: 'small', + position: { x: 0, y: 1, width: 1, height: 1 }, + config: { metric: 'cache.hit_rate', unit: '%' }, + data: null + }, + { + id: 'alerts-table', + title: 'Recent Alerts', + type: 'table', + size: 'large', + position: { x: 0, y: 2, width: 3, height: 2 }, + config: { showAcknowledged: false, limit: 10 }, + data: null + } + ]; + + defaultWidgets.forEach(widget => this.addWidget(widget)); + } + + private initializeDefaultAlertRules(): void { + const defaultRules: AlertRule[] = [ + { + id: 'high-memory-usage', + name: 'High Memory Usage', + metric: 'memory.usage_percentage', + condition: 'gt', + threshold: this.config.thresholds.memoryUsage, + severity: 'high', + enabled: true, + cooldown: 60000 // 1 minute + }, + { + id: 'slow-response-time', + name: 'Slow Response Time', + metric: 'performance.response_time', + condition: 'gt', + threshold: this.config.thresholds.responseTime, + severity: 'medium', + enabled: true, + cooldown: 30000 // 30 seconds + }, + { + id: 'high-error-rate', + name: 'High Error Rate', + metric: 'performance.error_rate', + condition: 'gt', + threshold: this.config.thresholds.errorRate, + severity: 'critical', + enabled: true, + cooldown: 60000 // 1 minute + }, + { + id: 'low-cache-hit-rate', + name: 'Low Cache Hit Rate', + metric: 'cache.hit_rate', + condition: 'lt', + threshold: this.config.thresholds.cacheHitRate, + severity: 'medium', + enabled: true, + cooldown: 300000 // 5 minutes + } + ]; + + defaultRules.forEach(rule => this.addAlertRule(rule)); + } + + // Export/Import for persistence + + export(): { + widgets: DashboardWidget[]; + alertRules: AlertRule[]; + config: DashboardConfig; + } { + return { + widgets: this.getAllWidgets(), + alertRules: this.getAllAlertRules(), + config: this.config + }; + } + + import(data: { + widgets?: DashboardWidget[]; + alertRules?: AlertRule[]; + config?: Partial; + }): void { + if (data.config) { + this.updateConfig(data.config); + } + + if (data.widgets) { + this.widgets.clear(); + data.widgets.forEach(widget => this.addWidget(widget)); + } + + if (data.alertRules) { + this.alertRules.clear(); + data.alertRules.forEach(rule => this.addAlertRule(rule)); + } + } + + // Cleanup + + destroy(): void { + if (this.updateTimer) { + clearInterval(this.updateTimer); + } + + this.widgets.clear(); + this.metrics.clear(); + this.alerts = []; + this.alertRules.clear(); + this.subscribers.clear(); + } +} + +export interface DashboardData { + widgets: DashboardWidget[]; + metrics: Record; + alerts: DashboardAlert[]; + alertRules: AlertRule[]; + config: DashboardConfig; + timestamp: number; +} + +// Export singleton instance getter +export const getPerformanceDashboard = (config?: Partial) => + PerformanceDashboard.getInstance(config); \ No newline at end of file diff --git a/packages/core/src/runtime/performance-monitor.ts b/packages/core/src/runtime/performance-monitor.ts new file mode 100644 index 0000000..83bc8a5 --- /dev/null +++ b/packages/core/src/runtime/performance-monitor.ts @@ -0,0 +1,378 @@ +import { RuntimeConfig, ValidationResult } from '../types/runtime'; + +export interface PerformanceMetrics { + // Runtime metrics + initializationTime: number; + connectionTime: number; + messageLatency: number; + throughput: number; + + // Memory metrics + memoryUsage: number; + heapSize: number; + gcCount: number; + + // Connection metrics + activeConnections: number; + poolUtilization: number; + connectionErrors: number; + + // Task metrics + taskExecutionTime: number; + taskQueueSize: number; + taskSuccessRate: number; + + timestamp: Date; +} + +export interface PerformanceAlert { + id: string; + type: 'warning' | 'error' | 'critical'; + metric: keyof PerformanceMetrics; + threshold: number; + currentValue: number; + message: string; + timestamp: Date; +} + +export interface PerformanceThresholds { + initializationTime: { warning: number; error: number }; + connectionTime: { warning: number; error: number }; + messageLatency: { warning: number; error: number }; + throughput: { warning: number; error: number }; + memoryUsage: { warning: number; error: number }; + heapSize: { warning: number; error: number }; + gcCount: { warning: number; error: number }; + activeConnections: { warning: number; error: number }; + poolUtilization: { warning: number; error: number }; + connectionErrors: { warning: number; error: number }; + taskExecutionTime: { warning: number; error: number }; + taskQueueSize: { warning: number; error: number }; + taskSuccessRate: { warning: number; error: number }; +} + +export interface PerformanceMonitorOptions { + enabled: boolean; + collectInterval: number; // milliseconds + retentionPeriod: number; // milliseconds + thresholds: PerformanceThresholds; + alertCallback?: (alert: PerformanceAlert) => void; +} + +export class PerformanceMonitor { + private static instance: PerformanceMonitor; + private options: PerformanceMonitorOptions; + private metrics: PerformanceMetrics[] = []; + private alerts: PerformanceAlert[] = []; + private collectTimer?: NodeJS.Timeout; + private startTime: number = Date.now(); + + // Performance counters + private counters = { + connections: 0, + messages: 0, + tasks: 0, + errors: 0, + gcEvents: 0 + }; + + // Timing measurements + private timings = new Map(); + + private constructor(options: PerformanceMonitorOptions) { + this.options = options; + + if (options.enabled) { + this.startCollection(); + } + } + + static getInstance(options?: PerformanceMonitorOptions): PerformanceMonitor { + if (!PerformanceMonitor.instance) { + const defaultOptions: PerformanceMonitorOptions = { + enabled: true, + collectInterval: 5000, // 5 seconds + retentionPeriod: 3600000, // 1 hour + thresholds: { + initializationTime: { warning: 1000, error: 3000 }, + connectionTime: { warning: 2000, error: 5000 }, + messageLatency: { warning: 100, error: 500 }, + throughput: { warning: 10, error: 5 }, // messages per second + memoryUsage: { warning: 100 * 1024 * 1024, error: 500 * 1024 * 1024 }, // 100MB/500MB + heapSize: { warning: 80 * 1024 * 1024, error: 400 * 1024 * 1024 }, // 80MB/400MB + gcCount: { warning: 100, error: 200 }, + activeConnections: { warning: 50, error: 100 }, + poolUtilization: { warning: 0.8, error: 0.95 }, + connectionErrors: { warning: 5, error: 10 }, + taskExecutionTime: { warning: 1000, error: 5000 }, + taskQueueSize: { warning: 20, error: 50 }, + taskSuccessRate: { warning: 0.9, error: 0.8 } + } + }; + + PerformanceMonitor.instance = new PerformanceMonitor(options || defaultOptions); + } + + return PerformanceMonitor.instance; + } + + // Start performance data collection + private startCollection(): void { + this.collectTimer = setInterval(() => { + this.collectMetrics(); + this.cleanupOldData(); + }, this.options.collectInterval); + } + + // Stop performance data collection + stopCollection(): void { + if (this.collectTimer) { + clearInterval(this.collectTimer); + this.collectTimer = undefined; + } + } + + // Collect current performance metrics + private collectMetrics(): void { + const now = new Date(); + const memoryUsage = this.getMemoryUsage(); + + const metrics: PerformanceMetrics = { + initializationTime: this.getAverageTime('initialization'), + connectionTime: this.getAverageTime('connection'), + messageLatency: this.getAverageTime('message'), + throughput: this.calculateThroughput(), + memoryUsage: memoryUsage.used, + heapSize: memoryUsage.heapUsed, + gcCount: this.counters.gcEvents, + activeConnections: this.counters.connections, + poolUtilization: this.calculatePoolUtilization(), + connectionErrors: this.counters.errors, + taskExecutionTime: this.getAverageTime('task'), + taskQueueSize: 0, // Would be populated by runtime + taskSuccessRate: this.calculateTaskSuccessRate(), + timestamp: now + }; + + this.metrics.push(metrics); + this.checkThresholds(metrics); + } + + // Get memory usage information + private getMemoryUsage(): { used: number; heapUsed: number } { + if (typeof process !== 'undefined' && process.memoryUsage) { + const usage = process.memoryUsage(); + return { + used: usage.rss, + heapUsed: usage.heapUsed + }; + } + + // Fallback for browser environment + return { + used: 0, + heapUsed: 0 + }; + } + + // Calculate average time for a specific operation + private getAverageTime(operation: string): number { + const times = Array.from(this.timings.entries()) + .filter(([key]) => key.startsWith(operation)) + .map(([, time]) => time); + + return times.length > 0 ? times.reduce((a, b) => a + b, 0) / times.length : 0; + } + + // Calculate message throughput (messages per second) + private calculateThroughput(): number { + const timeWindow = 60000; // 1 minute + const cutoff = Date.now() - timeWindow; + + const recentMetrics = this.metrics.filter(m => m.timestamp.getTime() > cutoff); + return recentMetrics.length > 0 ? this.counters.messages / (timeWindow / 1000) : 0; + } + + // Calculate connection pool utilization + private calculatePoolUtilization(): number { + // This would be calculated based on actual pool metrics + // For now, return a placeholder + return Math.min(this.counters.connections / 10, 1); // Assume max 10 connections + } + + // Calculate task success rate + private calculateTaskSuccessRate(): number { + const totalTasks = this.counters.tasks; + const failedTasks = this.counters.errors; + + return totalTasks > 0 ? (totalTasks - failedTasks) / totalTasks : 1; + } + + // Check performance thresholds and generate alerts + private checkThresholds(metrics: PerformanceMetrics): void { + const checks: Array<{ metric: keyof PerformanceThresholds; value: number }> = [ + { metric: 'initializationTime', value: metrics.initializationTime }, + { metric: 'connectionTime', value: metrics.connectionTime }, + { metric: 'messageLatency', value: metrics.messageLatency }, + { metric: 'throughput', value: metrics.throughput }, + { metric: 'memoryUsage', value: metrics.memoryUsage }, + { metric: 'heapSize', value: metrics.heapSize }, + { metric: 'gcCount', value: metrics.gcCount }, + { metric: 'activeConnections', value: metrics.activeConnections }, + { metric: 'poolUtilization', value: metrics.poolUtilization }, + { metric: 'connectionErrors', value: metrics.connectionErrors }, + { metric: 'taskExecutionTime', value: metrics.taskExecutionTime }, + { metric: 'taskQueueSize', value: metrics.taskQueueSize }, + { metric: 'taskSuccessRate', value: metrics.taskSuccessRate } + ]; + + for (const check of checks) { + const thresholds = this.options.thresholds[check.metric]; + if (!thresholds) continue; + + let alertType: 'warning' | 'error' | null = null; + let threshold = 0; + + if (check.metric === 'taskSuccessRate') { + // For success rate, lower values are worse + if (check.value < thresholds.error) { + alertType = 'error'; + threshold = thresholds.error; + } else if (check.value < thresholds.warning) { + alertType = 'warning'; + threshold = thresholds.warning; + } + } else { + // For other metrics, higher values are worse + if (check.value > thresholds.error) { + alertType = 'error'; + threshold = thresholds.error; + } else if (check.value > thresholds.warning) { + alertType = 'warning'; + threshold = thresholds.warning; + } + } + + if (alertType) { + this.generateAlert(alertType, check.metric, threshold, check.value); + } + } + } + + // Generate performance alert + private generateAlert( + type: 'warning' | 'error', + metric: keyof PerformanceThresholds, + threshold: number, + currentValue: number + ): void { + const alert: PerformanceAlert = { + id: `alert-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, + type, + metric, + threshold, + currentValue, + message: `Performance ${type}: ${metric} is ${currentValue}, threshold is ${threshold}`, + timestamp: new Date() + }; + + this.alerts.push(alert); + + if (this.options.alertCallback) { + this.options.alertCallback(alert); + } + } + + // Clean up old performance data + private cleanupOldData(): void { + const cutoff = Date.now() - this.options.retentionPeriod; + + this.metrics = this.metrics.filter(m => m.timestamp.getTime() > cutoff); + this.alerts = this.alerts.filter(a => a.timestamp.getTime() > cutoff); + } + + // Public API methods + + // Record timing for an operation + startTiming(operation: string): string { + const timingId = `${operation}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + this.timings.set(timingId, Date.now()); + return timingId; + } + + // End timing for an operation + endTiming(timingId: string): number { + const startTime = this.timings.get(timingId); + if (!startTime) return 0; + + const duration = Date.now() - startTime; + this.timings.delete(timingId); + return duration; + } + + // Increment counters + incrementCounter(type: keyof typeof this.counters): void { + this.counters[type]++; + } + + // Get current metrics + getCurrentMetrics(): PerformanceMetrics | null { + return this.metrics.length > 0 ? this.metrics[this.metrics.length - 1] : null; + } + + // Get metrics history + getMetricsHistory(limit?: number): PerformanceMetrics[] { + return limit ? this.metrics.slice(-limit) : [...this.metrics]; + } + + // Get active alerts + getActiveAlerts(): PerformanceAlert[] { + return [...this.alerts]; + } + + // Get performance summary + getPerformanceSummary(): { + uptime: number; + totalMetrics: number; + activeAlerts: number; + averageLatency: number; + memoryTrend: 'increasing' | 'decreasing' | 'stable'; + } { + const uptime = Date.now() - this.startTime; + const recentMetrics = this.metrics.slice(-10); + + let memoryTrend: 'increasing' | 'decreasing' | 'stable' = 'stable'; + if (recentMetrics.length >= 2) { + const first = recentMetrics[0].memoryUsage; + const last = recentMetrics[recentMetrics.length - 1].memoryUsage; + const change = (last - first) / first; + + if (change > 0.1) memoryTrend = 'increasing'; + else if (change < -0.1) memoryTrend = 'decreasing'; + } + + return { + uptime, + totalMetrics: this.metrics.length, + activeAlerts: this.alerts.length, + averageLatency: this.getAverageTime('message'), + memoryTrend + }; + } + + // Update configuration + updateOptions(options: Partial): void { + this.options = { ...this.options, ...options }; + + if (options.enabled !== undefined) { + if (options.enabled && !this.collectTimer) { + this.startCollection(); + } else if (!options.enabled && this.collectTimer) { + this.stopCollection(); + } + } + } +} + +// Export singleton instance getter +export const getPerformanceMonitor = () => PerformanceMonitor.getInstance(); \ No newline at end of file diff --git a/packages/core/src/runtime/runtime-factory.ts b/packages/core/src/runtime/runtime-factory.ts index cf85338..a66bc91 100644 --- a/packages/core/src/runtime/runtime-factory.ts +++ b/packages/core/src/runtime/runtime-factory.ts @@ -8,6 +8,10 @@ import type { TaskInput, TaskResponse, ProtocolMessage, + TaskNode, + SubTask, + DelegationConfig, + DelegationDetails, } from "../types"; import { A2ARuntime, type A2AConfig } from "./a2a-runtime"; import { AgentAreaRuntime, type AgentAreaConfig } from "./agentarea-runtime"; @@ -30,11 +34,13 @@ export class RuntimeFactory { ): AgentRuntime { switch (protocolType) { case "a2a": - return new A2ARuntime(config as A2AConfig); + // A2A runtime can be constructed with agentBaseUrl or endpoint. + // Pass config through as-is; A2ARuntime handles fallback logic. + return new A2ARuntime(config as A2AConfig) case "agentarea": - return new AgentAreaRuntime(config as AgentAreaConfig); + return new AgentAreaRuntime(config as AgentAreaConfig) default: - throw new Error(`Unsupported protocol type: ${protocolType}`); + throw new Error(`Unsupported protocol type: ${protocolType}`) } } @@ -303,6 +309,116 @@ export class RuntimeManager implements IRuntimeManager { } } + async delegateSubTask( + parentTaskId: string, + subTasks: SubTask[], + config?: DelegationConfig + ): Promise { + if (!this.activeRuntime) { + throw new Error("No active runtime available for delegation"); + } + + const delegationId = `del_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; + const parallel = config?.parallel ?? true; + const maxDepth = config?.maxDepth ?? 5; + const includeLog = config?.contextPassing?.includeLog ?? 5; + const artifacts = config?.contextPassing?.artifacts ?? []; + + // Validate depth (simplified; in real, check task history) + if (maxDepth <= 0) { + throw new Error("Maximum delegation depth exceeded"); + } + + const details: DelegationDetails = { + delegationId, + parentTaskId, + subTasks: [...subTasks], + status: 'pending' as const, + config, + timestamp: new Date(), + }; + + this.emitEvent({ type: 'delegation-created', details }); + + try { + // Prepare context for each sub-task (log snippet + artifacts) + const parentTask = await this.activeRuntime.getTask(parentTaskId); + // Simulate log snippet (in real, fetch from runtime events) + const logSnippet: string[] = []; // Placeholder: recent events as strings + + const subTaskPromises = subTasks.map(async (subTask) => { + const baseInput = subTask.input || { message: { role: 'agent' as const, parts: [] } }; + const enhancedInput: TaskInput = { + ...baseInput, + metadata: { + ...(baseInput.metadata || {}), + parentTaskId, + delegationId, + logContext: logSnippet.slice(-includeLog), + artifacts, + }, + }; + + this.emitEvent({ type: 'sub-task-started', subTask, delegationId }); + + const response = await this.activeRuntime!.submitTask(enhancedInput); + + this.emitEvent({ type: 'sub-task-completed', subTask, delegationId }); + + return { ...subTask, response }; + }); + + if (parallel) { + await Promise.all(subTaskPromises); + } else { + for (const promise of subTaskPromises) { + await promise; + } + } + + details.status = 'completed'; + details.subTasks = subTasks.map((st, i) => ({ ...st, status: 'completed' as const })); + + return details; + } catch (error) { + details.status = 'failed'; + this.emitEvent({ type: 'delegation-failed', delegationId, error: error as Error }); + throw error; + } + } + + async getDelegationTree(taskId: string): Promise { + if (!this.activeRuntime) { + throw new Error("No active runtime available"); + } + + // Fetch root task + const rootTask = await this.activeRuntime.getTask(taskId); + const rootNode: TaskNode = { + id: rootTask.id, + description: rootTask.description || rootTask.input?.prompt || 'Root Task', + agentId: rootTask.agentId || 'primary', + status: 'completed', // Assume; in real, query status + input: rootTask.input, + response: rootTask.response, + children: [], + logSnippet: [], // Fetch from events + createdAt: rootTask.createdAt || new Date(), + updatedAt: new Date(), + }; + + // Recursively fetch children (simplified; in real, query delegations) + const delegations: any[] = []; // Placeholder: fetch from runtime + for (const del of delegations) { + for (const sub of del.subTasks) { + const childNode = await this.getDelegationTree(sub.id); + rootNode.children.push(childNode); + } + } + + return rootNode; + } + async broadcastMessage( message: ProtocolMessage, protocols?: string[] @@ -464,7 +580,11 @@ export type RuntimeManagerEvent = runtimeId: string; runtime: AgentRuntime; previousRuntime?: AgentRuntime; - }; + } + | { type: "delegation-created"; details: DelegationDetails } + | { type: "sub-task-started"; subTask: SubTask; delegationId: string } + | { type: "sub-task-completed"; subTask: SubTask; delegationId: string } + | { type: "delegation-failed"; delegationId: string; error: Error }; export interface RuntimeHealthStatus { totalRuntimes: number; diff --git a/packages/core/src/transport/index.ts b/packages/core/src/transport/index.ts new file mode 100644 index 0000000..16134ae --- /dev/null +++ b/packages/core/src/transport/index.ts @@ -0,0 +1,108 @@ +// Transport layer abstraction for A2A protocol communication +// Supports JSON-RPC 2.0 and JSON-REST transports + +export interface TransportRequest { + method: string + params?: unknown + headers?: Record + timeout?: number +} + +export interface TransportResponse { + success: boolean + data?: T + error?: TransportError + headers?: Record +} + +export interface TransportError { + code: number | string + message: string + data?: unknown +} + +export interface TransportConfig { + baseURL: string + timeout?: number + retries?: number + headers?: Record + authentication?: TransportAuth +} + +export interface TransportAuth { + type: 'bearer' | 'api-key' | 'oauth' | 'basic' | 'none' + token?: string + apiKey?: string + username?: string + password?: string + headerName?: string +} + +// Base transport interface +export interface Transport { + readonly type: 'json-rpc' | 'json-rest' + + // Core request method + request(request: TransportRequest): Promise> + + // Batch requests (if supported) + batch?(requests: TransportRequest[]): Promise[]> + + // Streaming support + stream?(request: TransportRequest): AsyncIterable> + + // Health check + healthCheck(): Promise + + // Configuration + configure(config: Partial): void + getConfig(): TransportConfig +} + +// JSON-RPC 2.0 specific types +export interface JsonRpcRequest { + jsonrpc: '2.0' + method: string + params?: unknown + id?: string | number | null +} + +export interface JsonRpcResponse { + jsonrpc: '2.0' + id: string | number | null + result?: T + error?: JsonRpcError +} + +export interface JsonRpcError { + code: number + message: string + data?: unknown +} + +// JSON-REST specific types +export interface RestRequest { + path: string + method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' + body?: unknown + query?: Record +} + +// Method mapping for REST endpoints +export interface RestEndpointMapping { + [methodName: string]: { + path: string + method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' + paramMapping?: 'body' | 'query' | 'path' + } +} + +// Transport factory interface +export interface TransportFactory { + createTransport(type: 'json-rpc' | 'json-rest', config: TransportConfig, mapping?: RestEndpointMapping): Transport +} + +// Re-export all transport implementations +export * from './json-rpc-transport' +export * from './json-rest-transport' +export * from './transport-factory' \ No newline at end of file diff --git a/packages/core/src/transport/json-rest-transport.ts b/packages/core/src/transport/json-rest-transport.ts new file mode 100644 index 0000000..81be3aa --- /dev/null +++ b/packages/core/src/transport/json-rest-transport.ts @@ -0,0 +1,213 @@ +// JSON-REST transport implementation for A2A protocol +import type { + Transport, + TransportRequest, + TransportResponse, + TransportConfig, + TransportError, + RestEndpointMapping +} from './index' + +export class JsonRestTransport implements Transport { + readonly type = 'json-rest' as const + + private config: TransportConfig + private endpointMapping?: RestEndpointMapping + + constructor(config: TransportConfig, mapping?: RestEndpointMapping) { + this.config = { ...config } + this.endpointMapping = mapping + } + + async request(request: TransportRequest): Promise> { + try { + const { url, method, body } = this.resolveRequest(request) + const response = await this.performHttpRequest(url, method, body, request.headers, request.timeout) + + if (!response.ok) { + return { + success: false, + error: { + code: response.status, + message: `HTTP ${response.status}: ${response.statusText}`, + data: await response.text() + } + } + } + + const data = await this.safeJson(response) + return { + success: true, + data, + headers: this.extractHeaders(response.headers) + } + } catch (error) { + return { + success: false, + error: { + code: 'TRANSPORT_ERROR', + message: (error as Error).message, + data: error + } + } + } + } + + async batch(requests: TransportRequest[]): Promise[]> { + // REST batch is not standardized; we will perform sequential requests for simplicity + const results: TransportResponse[] = [] + for (const req of requests) { + results.push(await this.request(req)) + } + return results + } + + async *stream(request: TransportRequest): AsyncIterable> { + // Streaming not implemented for REST by default + throw new Error('Streaming not supported in JSON-REST transport. Use SSE or WebSocket transport instead.') + } + + async healthCheck(): Promise { + try { + const headers: Record = { + 'Accept': 'application/json', + ...this.config.headers, + } + + if (this.config.authentication) { + const auth = this.config.authentication + switch (auth.type) { + case 'bearer': + if (auth.token) headers['Authorization'] = `Bearer ${auth.token}` + break + case 'api-key': + if (auth.apiKey && auth.headerName) headers[auth.headerName] = auth.apiKey + else if (auth.apiKey) headers['X-API-Key'] = auth.apiKey + break + case 'basic': + if (auth.username && auth.password) { + const credentials = btoa(`${auth.username}:${auth.password}`) + headers['Authorization'] = `Basic ${credentials}` + } + break + } + } + + const response = await fetch(`${this.config.baseURL}/health`, { + method: 'GET', + headers, + }) + return response.ok + } catch (error) { + return false + } + } + + configure(config: Partial): void { + this.config = { ...this.config, ...config } + } + + getConfig(): TransportConfig { + return { ...this.config } + } + + private resolveRequest(request: TransportRequest): { url: string; method: string; body?: unknown } { + if (this.endpointMapping && this.endpointMapping[request.method]) { + const { path, method, paramMapping } = this.endpointMapping[request.method] + let url = `${this.config.baseURL}${path}` + let body: unknown + + if (paramMapping === 'query' && request.params && typeof request.params === 'object') { + const qs = new URLSearchParams() + for (const [key, value] of Object.entries(request.params as Record)) { + if (value !== undefined && value !== null) qs.append(key, String(value)) + } + url += `?${qs.toString()}` + } else if (paramMapping === 'body') { + body = request.params + } else { + body = request.params + } + + return { url, method, body } + } + + // Fallback: assume request.method is a path for REST + const url = `${this.config.baseURL}/${request.method}` + return { url, method: 'POST', body: request.params } + } + + private async performHttpRequest( + url: string, + method: string, + body?: unknown, + headers?: Record, + timeout?: number + ): Promise { + const requestHeaders: Record = { + 'Content-Type': 'application/json', + ...this.config.headers, + ...headers + } + + // Authentication + if (this.config.authentication) { + const auth = this.config.authentication + switch (auth.type) { + case 'bearer': + if (auth.token) requestHeaders['Authorization'] = `Bearer ${auth.token}` + break + case 'api-key': + if (auth.apiKey && auth.headerName) { + requestHeaders[auth.headerName] = auth.apiKey + } else if (auth.apiKey) { + requestHeaders['X-API-Key'] = auth.apiKey + } + break + case 'basic': + if (auth.username && auth.password) { + const credentials = btoa(`${auth.username}:${auth.password}`) + requestHeaders['Authorization'] = `Basic ${credentials}` + } + break + } + } + + const controller = new AbortController() + const timeoutMs = timeout || this.config.timeout || 30000 + const timeoutId = setTimeout(() => controller.abort(), timeoutMs) + + try { + const response = await fetch(url, { + method, + headers: requestHeaders, + body: body !== undefined ? JSON.stringify(body) : undefined, + signal: controller.signal + }) + + clearTimeout(timeoutId) + return response + } catch (error) { + clearTimeout(timeoutId) + throw error + } + } + + private async safeJson(response: Response): Promise { + const text = await response.text() + try { + return JSON.parse(text) as T + } catch { + // @ts-expect-error - when T is not JSON object + return text + } + } + + private extractHeaders(headers: Headers): Record { + const result: Record = {} + headers.forEach((value, key) => { + result[key] = value + }) + return result + } +} \ No newline at end of file diff --git a/packages/core/src/transport/json-rpc-transport.ts b/packages/core/src/transport/json-rpc-transport.ts new file mode 100644 index 0000000..e0b926b --- /dev/null +++ b/packages/core/src/transport/json-rpc-transport.ts @@ -0,0 +1,212 @@ +// JSON-RPC 2.0 transport implementation for A2A protocol +import type { + Transport, + TransportRequest, + TransportResponse, + TransportConfig, + TransportError, + JsonRpcRequest, + JsonRpcResponse, + JsonRpcError +} from './index' + +export class JsonRpcTransport implements Transport { + readonly type = 'json-rpc' as const + + private config: TransportConfig + private requestId = 0 + + constructor(config: TransportConfig) { + this.config = { ...config } + } + + async request(request: TransportRequest): Promise> { + try { + const rpcRequest = this.buildRpcRequest(request) + const response = await this.performHttpRequest(rpcRequest, request.headers, request.timeout) + + if (!response.ok) { + return { + success: false, + error: { + code: response.status, + message: `HTTP ${response.status}: ${response.statusText}`, + data: await response.text() + } + } + } + + const rpcResponse = await response.json() as JsonRpcResponse + return this.processRpcResponse(rpcResponse) + } catch (error) { + return { + success: false, + error: { + code: 'TRANSPORT_ERROR', + message: (error as Error).message, + data: error + } + } + } + } + + async batch(requests: TransportRequest[]): Promise[]> { + try { + const rpcRequests = requests.map(req => this.buildRpcRequest(req)) + const firstRequest = requests[0] + + const response = await this.performHttpRequest( + rpcRequests, + firstRequest?.headers, + firstRequest?.timeout + ) + + if (!response.ok) { + const error: TransportError = { + code: response.status, + message: `HTTP ${response.status}: ${response.statusText}`, + data: await response.text() + } + return requests.map(() => ({ success: false, error })) + } + + const rpcResponses = await response.json() as JsonRpcResponse[] + return rpcResponses.map((rpcResponse) => this.processRpcResponse(rpcResponse)) + } catch (error) { + const transportError: TransportError = { + code: 'BATCH_ERROR', + message: (error as Error).message, + data: error + } + return requests.map(() => ({ success: false, error: transportError })) + } + } + + async *stream(request: TransportRequest): AsyncIterable> { + // JSON-RPC doesn't natively support streaming, but we can implement polling + // or use server-sent events if the server supports it + throw new Error('Streaming not supported in JSON-RPC transport. Use WebSocket or SSE transport instead.') + } + + async healthCheck(): Promise { + try { + const healthRequest: TransportRequest = { + method: 'system.ping', + params: {} + } + + const response = await this.request(healthRequest) + return response.success + } catch (error) { + return false + } + } + + configure(config: Partial): void { + this.config = { ...this.config, ...config } + } + + getConfig(): TransportConfig { + return { ...this.config } + } + + private buildRpcRequest(request: TransportRequest): JsonRpcRequest { + return { + jsonrpc: '2.0', + method: request.method, + params: request.params, + id: ++this.requestId + } + } + + private async performHttpRequest( + body: JsonRpcRequest | JsonRpcRequest[], + headers?: Record, + timeout?: number + ): Promise { + const requestHeaders: Record = { + 'Content-Type': 'application/json', + ...this.config.headers, + ...headers + } + + // Add authentication headers + if (this.config.authentication) { + const auth = this.config.authentication + switch (auth.type) { + case 'bearer': + if (auth.token) { + requestHeaders['Authorization'] = `Bearer ${auth.token}` + } + break + case 'api-key': + if (auth.apiKey && auth.headerName) { + requestHeaders[auth.headerName] = auth.apiKey + } else if (auth.apiKey) { + requestHeaders['X-API-Key'] = auth.apiKey + } + break + case 'basic': + if (auth.username && auth.password) { + const credentials = btoa(`${auth.username}:${auth.password}`) + requestHeaders['Authorization'] = `Basic ${credentials}` + } + break + } + } + + const controller = new AbortController() + const timeoutMs = timeout || this.config.timeout || 30000 + + const timeoutId = setTimeout(() => controller.abort(), timeoutMs) + + try { + const response = await fetch(this.config.baseURL, { + method: 'POST', + headers: requestHeaders, + body: JSON.stringify(body), + signal: controller.signal + }) + + clearTimeout(timeoutId) + return response + } catch (error) { + clearTimeout(timeoutId) + throw error + } + } + + private processRpcResponse(rpcResponse: JsonRpcResponse): TransportResponse { + if (rpcResponse.error) { + return { + success: false, + error: { + code: rpcResponse.error.code, + message: rpcResponse.error.message, + data: rpcResponse.error.data + } + } + } + + return { + success: true, + data: rpcResponse.result + } + } + + // Method for mapping A2A protocol methods to JSON-RPC calls + static mapA2AMethodToRpc(method: string): string { + const methodMap: Record = { + 'getAgentCard': 'agent.getCard', + 'sendMessage': 'message.send', + 'createTask': 'task.create', + 'getTask': 'task.get', + 'updateTask': 'task.update', + 'cancelTask': 'task.cancel', + 'listCapabilities': 'capabilities.list', + 'negotiate': 'capabilities.negotiate' + } + + return methodMap[method] || method + } +} \ No newline at end of file diff --git a/packages/core/src/transport/transport-factory.ts b/packages/core/src/transport/transport-factory.ts new file mode 100644 index 0000000..1d4ec5c --- /dev/null +++ b/packages/core/src/transport/transport-factory.ts @@ -0,0 +1,20 @@ +import type { TransportFactory as ITransportFactory, Transport, TransportConfig, RestEndpointMapping } from './index' +import { JsonRpcTransport } from './json-rpc-transport' +import { JsonRestTransport } from './json-rest-transport' + +export class TransportFactory implements ITransportFactory { + createTransport(type: 'json-rpc' | 'json-rest', config: TransportConfig, mapping?: RestEndpointMapping): Transport { + switch (type) { + case 'json-rpc': + return new JsonRpcTransport(config) + case 'json-rest': + return new JsonRestTransport(config, mapping) + default: + throw new Error(`Unsupported transport type: ${type}`) + } + } +} + +export function createTransportFactory() { + return new TransportFactory() +} \ No newline at end of file diff --git a/packages/core/src/types/core.ts b/packages/core/src/types/core.ts index 493a38c..2b466b5 100644 --- a/packages/core/src/types/core.ts +++ b/packages/core/src/types/core.ts @@ -2,7 +2,7 @@ // Re-export AuthConfig from runtime to avoid circular dependencies export interface AuthConfig { - type: 'bearer' | 'api-key' | 'oauth' | 'openid' + type: 'bearer' | 'api-key' | 'oauth' | 'openid' | 'none' config?: Record } @@ -19,16 +19,21 @@ export interface MessagePart { } export interface TaskInput { + prompt?: string; message: Message context?: Record capabilities?: string[] + metadata?: Record; } export interface Task { id: string + description?: string; + agentId?: string; contextId?: string status: TaskStatus input: TaskInput + response?: TaskResponse; artifacts?: Artifact[] messages?: Message[] progress?: TaskProgress @@ -190,4 +195,4 @@ export interface CommunicationBlock { target?: string content: unknown metadata?: Record -} \ No newline at end of file +} diff --git a/packages/core/src/types/runtime.ts b/packages/core/src/types/runtime.ts index c85a219..3c7b752 100644 --- a/packages/core/src/types/runtime.ts +++ b/packages/core/src/types/runtime.ts @@ -12,6 +12,15 @@ import type { CommunicationBlock, AuthConfig } from './core' +// Import transport types for configuration +import type { + TransportConfig, + RestEndpointMapping +} from '../transport' +// Import agent card resolver types +import type { + AgentCardResolverConfig +} from '../agent-card' // Base AgentRuntime interface with protocol identification export interface AgentRuntime { @@ -61,13 +70,21 @@ export interface AgentRuntime { export interface RuntimeConfig { endpoint?: string authentication?: { - type: 'bearer' | 'api-key' | 'oauth' | 'openid' + type: 'bearer' | 'api-key' | 'oauth' | 'openid' | 'none' token?: string apiKey?: string config?: Record } timeout?: number retries?: number + // Transport configuration + transport?: { + type?: 'json-rpc' | 'json-rest' + config?: TransportConfig + endpointMapping?: RestEndpointMapping + } + // Agent card resolver configuration + agentCardResolver?: AgentCardResolverConfig [key: string]: unknown } @@ -75,12 +92,52 @@ export interface RuntimeFactory { (config: T): AgentRuntime } +export interface TaskNode { + id: string; + description: string; + agentId: string; + status: 'pending' | 'running' | 'completed' | 'failed'; + input?: TaskInput; + response?: TaskResponse; + children: TaskNode[]; + logSnippet?: string[]; // Serialized event log for context + createdAt: Date; + updatedAt: Date; +} + +export interface SubTask extends TaskNode { + parentId: string; + delegationId: string; +} + +export interface DelegationConfig { + parallel?: boolean; // Run sub-tasks async + maxDepth?: number; // Prevent infinite delegation + contextPassing?: { + includeLog?: number; // Number of recent events to pass + artifacts?: string[]; // Artifact IDs to include + }; +} + +export interface DelegationDetails { + delegationId: string; + parentTaskId: string; + subTasks: SubTask[]; + status: 'pending' | 'running' | 'completed' | 'failed'; + config?: DelegationConfig; + timestamp: Date; +} + // Runtime events export type RuntimeEvent = | { type: 'connected'; runtime: AgentRuntime } | { type: 'disconnected'; runtime: AgentRuntime } | { type: 'error'; error: Error; runtime: AgentRuntime } | { type: 'task-update'; update: TaskUpdate; runtime: AgentRuntime } + | { type: 'delegation'; details: DelegationDetails; runtime: AgentRuntime } + | { type: 'sub-task-started'; subTask: SubTask; delegationId: string; runtime: AgentRuntime } + | { type: 'sub-task-completed'; subTask: SubTask; delegationId: string; runtime: AgentRuntime } + | { type: 'delegation-failed'; delegationId: string; error: Error; runtime: AgentRuntime } export interface RuntimeEventListener { (event: RuntimeEvent): void @@ -304,4 +361,4 @@ export interface RuntimeManager { // Multi-protocol operations submitTaskToAnyRuntime(input: TaskInput, preferredProtocol?: string): Promise broadcastMessage(message: ProtocolMessage, protocols?: string[]): Promise -} \ No newline at end of file +} diff --git a/packages/react/package.json b/packages/react/package.json index cd8f794..f626ca2 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -14,7 +14,9 @@ }, "./package.json": "./package.json" }, - "sideEffects": false, + "sideEffects": [ + "**/*.css" + ], "files": [ "dist", "README.md", @@ -42,6 +44,7 @@ }, "dependencies": { "@agentarea/core": "workspace:*", + "@agentarea/styles": "workspace:*", "@radix-ui/react-progress": "^1.1.0", "@radix-ui/react-slot": "^1.1.0", "class-variance-authority": "^0.7.1", diff --git a/packages/react/src/components/agent-ui.tsx b/packages/react/src/components/agent-ui.tsx index 7798a22..c048c11 100644 --- a/packages/react/src/components/agent-ui.tsx +++ b/packages/react/src/components/agent-ui.tsx @@ -1,3 +1,5 @@ +"use client" + import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react' import type { AgentRuntime, @@ -11,6 +13,7 @@ import type { import { useRuntimeEnvironment } from '../hooks/use-runtime-environment' import { AgentProvider } from './providers/agent-provider' import { ConfigProvider } from './providers/config-provider' +import { InputProvider } from './providers/input-provider' // Main AgentUI configuration interface export interface AgentUIProps { @@ -207,13 +210,18 @@ export function AgentUI({ data-theme={currentTheme} data-debug={debugEnabled} data-environment={environment.isNextJS ? 'nextjs' : environment.isVite ? 'vite' : 'react'} + suppressHydrationWarning > {agentRuntime ? ( - {children} + + {children} + ) : ( - children + + {children} + )}
@@ -234,10 +242,28 @@ export function useAgentUI(): AgentUIContextValue { // Helper function to create runtime from type string function createRuntimeFromType(type: string, config: RuntimeConfig): AgentRuntime | null { - // This would typically use the RuntimeFactory from core - // For now, return null as the factory implementation is in task 2 - console.warn(`AgentUI: Runtime creation for type "${type}" not yet implemented. Requires RuntimeFactory from task 2.`) - return null + try { + // Lazily import to avoid circular deps in some bundlers + const { createRuntimeFactory } = require('@agentarea/core') as typeof import('@agentarea/core') + const factory = createRuntimeFactory() + + // Normalize config to include endpoint/auth if provided + const normalizedConfig: RuntimeConfig = { + ...config, + endpoint: config.endpoint, + authentication: config.authentication, + } + + if (type === 'a2a' || type === 'agentarea') { + return factory.createRuntime(type, normalizedConfig) + } + + console.warn(`AgentUI: Unsupported runtime type "${type}". Supported types: 'a2a', 'agentarea'.`) + return null + } catch (err) { + console.error('AgentUI: Failed to create runtime from type:', err) + return null + } } // AgentUI.Provider - Explicit provider pattern usage @@ -328,10 +354,14 @@ function AgentUIProvider({ const content = agentRuntime ? ( - {children} + + {children} + ) : ( - children + + {children} + ) return ( diff --git a/packages/react/src/components/artifacts/__tests__/artifact-code.test.tsx b/packages/react/src/components/artifacts/__tests__/artifact-code.test.tsx index e388d5b..47762df 100644 --- a/packages/react/src/components/artifacts/__tests__/artifact-code.test.tsx +++ b/packages/react/src/components/artifacts/__tests__/artifact-code.test.tsx @@ -1,3 +1,4 @@ +import React from 'react' import { describe, it, expect, vi } from 'vitest' import { render, screen, fireEvent, waitFor } from '@test-utils' import { axe } from 'jest-axe' diff --git a/packages/react/src/components/artifacts/__tests__/artifact-container.test.tsx b/packages/react/src/components/artifacts/__tests__/artifact-container.test.tsx index 193f041..239582e 100644 --- a/packages/react/src/components/artifacts/__tests__/artifact-container.test.tsx +++ b/packages/react/src/components/artifacts/__tests__/artifact-container.test.tsx @@ -1,3 +1,4 @@ +import React from 'react' import { describe, it, expect, vi } from 'vitest' import { render, screen, fireEvent } from '@test-utils' import { axe } from 'jest-axe' diff --git a/packages/react/src/components/artifacts/artifact-code.tsx b/packages/react/src/components/artifacts/artifact-code.tsx index e0122a2..aaaab31 100644 --- a/packages/react/src/components/artifacts/artifact-code.tsx +++ b/packages/react/src/components/artifacts/artifact-code.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { cn } from "../../lib/utils" import { Button } from "../ui/button" diff --git a/packages/react/src/components/artifacts/artifact-container.tsx b/packages/react/src/components/artifacts/artifact-container.tsx index 9ad9064..0f03508 100644 --- a/packages/react/src/components/artifacts/artifact-container.tsx +++ b/packages/react/src/components/artifacts/artifact-container.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { cn } from "../../lib/utils" import { Button } from "../ui/button" diff --git a/packages/react/src/components/chat.tsx b/packages/react/src/components/chat.tsx index 05c32c4..c6d325f 100644 --- a/packages/react/src/components/chat.tsx +++ b/packages/react/src/components/chat.tsx @@ -118,6 +118,7 @@ const ChatMessage = React.forwardRef( "text-xs opacity-70 mt-1", isUser ? "text-right" : "text-left" )} + suppressHydrationWarning > {timestamp.toLocaleTimeString()}
@@ -736,7 +737,83 @@ const ChatInputForm = React.forwardRef( ) ChatInputForm.displayName = "Chat.InputForm" -// Export as namespace +// Import Block components and useTask hook +import { Block } from './blocks' +import { useTask } from '../hooks/use-task' + +// Simple chat component displaying communication blocks +export interface ChatSimpleProps extends React.HTMLAttributes { + taskId?: string + autoScroll?: boolean + maxHeight?: string + showMetadata?: boolean + showTimestamp?: boolean + showRouting?: boolean + expandable?: boolean +} + +const ChatSimple = React.forwardRef( + ({ + taskId, + autoScroll = true, + maxHeight = "400px", + showMetadata = true, + showTimestamp = true, + showRouting = true, + expandable = false, + className, + ...props + }, ref) => { + const { communicationBlocks } = useTask(taskId) + const scrollRef = React.useRef(null) + + React.useEffect(() => { + if (autoScroll && scrollRef.current) { + scrollRef.current.scrollTop = scrollRef.current.scrollHeight + } + }) + + return ( +
+
+ {communicationBlocks.length > 0 ? ( + communicationBlocks.map((block) => ( + + )) + ) : ( +
+ {taskId ? ( + "No communication blocks available for this task." + ) : ( + "No active task. Create a task to see communication blocks." + )} +
+ )} +
+
+ ) + } +) +ChatSimple.displayName = "Chat.Simple" + export const Chat = { Root: ChatRoot, Message: ChatMessage, @@ -746,4 +823,5 @@ export const Chat = { Input: ChatInput, InputForm: ChatInputForm, Typing: ChatTyping, + Simple: ChatSimple, } \ No newline at end of file diff --git a/packages/react/src/components/error-boundaries/__tests__/base-error-boundary.test.tsx b/packages/react/src/components/error-boundaries/__tests__/base-error-boundary.test.tsx index 2d23d06..de77146 100644 --- a/packages/react/src/components/error-boundaries/__tests__/base-error-boundary.test.tsx +++ b/packages/react/src/components/error-boundaries/__tests__/base-error-boundary.test.tsx @@ -1,3 +1,4 @@ +import React from 'react' import { describe, it, expect, vi } from 'vitest' import { render, screen, fireEvent } from '@test-utils' import { BaseErrorBoundary } from '../base-error-boundary' diff --git a/packages/react/src/components/inputs/__tests__/input-form.test.tsx b/packages/react/src/components/inputs/__tests__/input-form.test.tsx index f4d3fdd..8ed4dcd 100644 --- a/packages/react/src/components/inputs/__tests__/input-form.test.tsx +++ b/packages/react/src/components/inputs/__tests__/input-form.test.tsx @@ -1,3 +1,4 @@ +import React from 'react' import { describe, it, expect, vi } from 'vitest' import { render, screen, fireEvent, waitFor } from '@test-utils' import { axe } from 'jest-axe' diff --git a/packages/react/src/components/inputs/input-approval.tsx b/packages/react/src/components/inputs/input-approval.tsx index 913ff11..52af714 100644 --- a/packages/react/src/components/inputs/input-approval.tsx +++ b/packages/react/src/components/inputs/input-approval.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { useState, useCallback } from "react" import { cn } from "../../lib/utils" diff --git a/packages/react/src/components/inputs/input-field.tsx b/packages/react/src/components/inputs/input-field.tsx index 8b68445..03af549 100644 --- a/packages/react/src/components/inputs/input-field.tsx +++ b/packages/react/src/components/inputs/input-field.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { useState, useCallback, useEffect } from "react" import { cn } from "../../lib/utils" diff --git a/packages/react/src/components/inputs/input-form.tsx b/packages/react/src/components/inputs/input-form.tsx index bd3ae3d..53c6311 100644 --- a/packages/react/src/components/inputs/input-form.tsx +++ b/packages/react/src/components/inputs/input-form.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { useState, useCallback, useEffect } from "react" import { cn } from "../../lib/utils" diff --git a/packages/react/src/components/inputs/input-selection.tsx b/packages/react/src/components/inputs/input-selection.tsx index 392421f..781dc93 100644 --- a/packages/react/src/components/inputs/input-selection.tsx +++ b/packages/react/src/components/inputs/input-selection.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { useState, useCallback, useMemo } from "react" import { cn } from "../../lib/utils" diff --git a/packages/react/src/components/inputs/input-upload.tsx b/packages/react/src/components/inputs/input-upload.tsx index 5dd2652..9010c64 100644 --- a/packages/react/src/components/inputs/input-upload.tsx +++ b/packages/react/src/components/inputs/input-upload.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { useState, useCallback, useRef } from "react" import { cn } from "../../lib/utils" diff --git a/packages/react/src/components/multi-agent/agent-log.tsx b/packages/react/src/components/multi-agent/agent-log.tsx new file mode 100644 index 0000000..8bce9cc --- /dev/null +++ b/packages/react/src/components/multi-agent/agent-log.tsx @@ -0,0 +1,78 @@ +import * as React from "react" +import { cn } from "../../lib/utils" + +export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' + +export interface LogEntry { + id: string + level: LogLevel + message: string + timestamp: Date + context?: Record +} + +export interface AgentLogProps extends React.HTMLAttributes { + agentId?: string + entries?: LogEntry[] + levels?: LogLevel[] + maxHeight?: number + follow?: boolean +} + +function levelClass(level: LogLevel) { + switch (level) { + case 'trace': return 'text-gray-500' + case 'debug': return 'text-slate-500' + case 'info': return 'text-blue-600' + case 'warn': return 'text-amber-600' + case 'error': return 'text-red-600' + default: return 'text-foreground' + } +} + +const AgentLogRoot = React.forwardRef( + ({ className, agentId, entries = [], levels, maxHeight = 240, follow = true, ...props }, ref) => { + const containerRef = React.useRef(null) + const mergedRef = (node: HTMLDivElement) => { + containerRef.current = node + if (typeof ref === 'function') ref(node) + else if (ref) (ref as React.MutableRefObject).current = node + } + + React.useEffect(() => { + if (!follow || !containerRef.current) return + containerRef.current.scrollTop = containerRef.current.scrollHeight + }, [entries, follow]) + + const filtered = React.useMemo(() => { + if (!levels || levels.length === 0) return entries + const set = new Set(levels) + return entries.filter(e => set.has(e.level)) + }, [entries, levels]) + + return ( +
+
+
{agentId ? `Agent ${agentId} Logs` : 'Agent Logs'}
+
{filtered.length} entries
+
+
+ {filtered.length === 0 ? ( +
No log entries.
+ ) : ( + filtered.map(e => ( +
+ {e.timestamp.toLocaleTimeString()} + {e.level} + {e.message} +
+ )) + )} +
+
+ ) + } +) +AgentLogRoot.displayName = 'AgentLog' + +export const AgentLog = AgentLogRoot \ No newline at end of file diff --git a/packages/react/src/components/multi-agent/index.ts b/packages/react/src/components/multi-agent/index.ts new file mode 100644 index 0000000..c67720e --- /dev/null +++ b/packages/react/src/components/multi-agent/index.ts @@ -0,0 +1,14 @@ +import { TaskGraph } from './task-graph' +import { Timeline } from './timeline' +import { AgentLog } from './agent-log' + +export { TaskGraph, Timeline, AgentLog } +export type { TaskGraphNode, TaskStatus } from './task-graph' +export type { TimelineEvent, TimelineEventType } from './timeline' +export type { LogEntry, LogLevel } from './agent-log' + +export const MultiAgent = { + TaskGraph, + Timeline, + AgentLog, +} as const \ No newline at end of file diff --git a/packages/react/src/components/multi-agent/task-graph.tsx b/packages/react/src/components/multi-agent/task-graph.tsx new file mode 100644 index 0000000..6043964 --- /dev/null +++ b/packages/react/src/components/multi-agent/task-graph.tsx @@ -0,0 +1,131 @@ +import * as React from "react" +import { cn } from "../../lib/utils" +import { Badge } from "../ui/badge" + +export type TaskStatus = 'submitted' | 'working' | 'input-required' | 'completed' | 'canceled' | 'failed' | 'rejected' + +export interface TaskGraphNode { + id: string + label?: string + status?: TaskStatus + agentId?: string + parentId?: string + children?: TaskGraphNode[] + metadata?: Record +} + +export interface TaskGraphProps extends React.HTMLAttributes { + rootId?: string + nodes?: TaskGraphNode[] + maxHeight?: number + collapsible?: boolean + defaultExpanded?: boolean + onFocusNode?: (nodeId: string) => void +} + +function StatusBadge({ status }: { status?: TaskStatus }) { + if (!status) return null + const color = + status === 'completed' ? 'bg-green-100 text-green-800' : + status === 'working' ? 'bg-blue-100 text-blue-800' : + status === 'failed' || status === 'rejected' ? 'bg-red-100 text-red-800' : + status === 'input-required' ? 'bg-amber-100 text-amber-800' : + 'bg-gray-100 text-gray-800' + return {status} +} + +function NodeRow({ node, depth, collapsible, onFocusNode }: { node: TaskGraphNode; depth: number; collapsible: boolean; onFocusNode?: (id: string) => void }) { + const [open, setOpen] = React.useState(true) + const hasChildren = !!node.children?.length + const paddingLeft = 8 + depth * 16 + return ( +
+
+ {hasChildren && collapsible ? ( + + ) : ( + + )} +
+
+ {node.label || node.id} + + {node.agentId && {node.agentId}} +
+ {node.parentId && ( +
child of {node.parentId}
+ )} +
+ +
+ {hasChildren && open && ( +
+ {node.children!.map((child) => ( + + ))} +
+ )} +
+ ) +} + +const TaskGraphRoot = React.forwardRef( + ({ className, rootId, nodes = [], maxHeight = 360, collapsible = true, defaultExpanded = true, onFocusNode, ...props }, ref) => { + const [expandedAll, setExpandedAll] = React.useState(defaultExpanded) + + // Normalize nodes: if a flat array with parentId is provided, build a tree + const tree = React.useMemo(() => { + if (!nodes.length) return [] as TaskGraphNode[] + const byId = new Map() + nodes.forEach(n => byId.set(n.id, { ...n, children: n.children ? [...n.children] : [] })) + byId.forEach(n => { + if (n.parentId && byId.has(n.parentId)) { + const p = byId.get(n.parentId)! + p.children = p.children || [] + p.children.push(n) + } + }) + const roots = [...byId.values()].filter(n => !n.parentId) + // If rootId specified, pick it + if (rootId) { + const root = byId.get(rootId) + return root ? [root] : roots + } + return roots + }, [nodes, rootId]) + + React.useEffect(() => { + // Expand/collapse all by toggling a global key + // We pass defaultExpanded to NodeRow via key to reset their local state + }, [expandedAll]) + + return ( +
+
+
Task Graph
+
+ + +
+
+
+ {tree.length === 0 ? ( +
No task graph data. Provide nodes or create subtasks.
+ ) : ( +
+ {tree.map((n) => ( + + ))} +
+ )} +
+
+ ) + } +) +TaskGraphRoot.displayName = "TaskGraph" + +export const TaskGraph = TaskGraphRoot +export { Badge } \ No newline at end of file diff --git a/packages/react/src/components/multi-agent/task-tree-list.tsx b/packages/react/src/components/multi-agent/task-tree-list.tsx new file mode 100644 index 0000000..2e455f7 --- /dev/null +++ b/packages/react/src/components/multi-agent/task-tree-list.tsx @@ -0,0 +1,34 @@ +'use client' + +import React, { useState } from 'react'; +import type { TaskNode } from '../../../../core/src/types/runtime'; + +interface TaskTreeListProps { + node: TaskNode; +} + +const TaskTreeList: React.FC = ({ node }) => { + const [expanded, setExpanded] = useState(true); + + return ( +
+
+ {node.description} + {node.status} +
+
+
{node.agentId}
+ {node.children.length > 0 && ( + + )} + {expanded && node.children.map((child: TaskNode) => ( + + ))} +
+
+ ); +}; + +export { TaskTreeList }; diff --git a/packages/react/src/components/multi-agent/temp-task-graph.tsx b/packages/react/src/components/multi-agent/temp-task-graph.tsx new file mode 100644 index 0000000..75e5e0b --- /dev/null +++ b/packages/react/src/components/multi-agent/temp-task-graph.tsx @@ -0,0 +1,50 @@ +'use client' + +import React from 'react'; +import type { TaskNode } from '../../../../core/src/types/runtime'; + +interface TempTaskGraphProps { + nodes: TaskNode[]; +} + +const TempTaskGraph: React.FC = ({ nodes }) => { + const renderGraph = (nodes: TaskNode[], x = 0, y = 0, level = 0) => { + return ( + + {nodes.map((node, i) => { + const nodeX = i * 150; + const nodeY = level * 100; + return ( + + + {node.agentId.slice(0, 3)} + {node.status} + {node.children.length > 0 && ( + + {node.children.map((child, ci) => ( + + ))} + {renderGraph(node.children, 0, 100, level + 1)} + + )} + + ); + })} + + ); + }; + + return ( + + + {renderGraph(nodes)} + + ); +}; + +export { TempTaskGraph }; diff --git a/packages/react/src/components/multi-agent/timeline.tsx b/packages/react/src/components/multi-agent/timeline.tsx new file mode 100644 index 0000000..483be84 --- /dev/null +++ b/packages/react/src/components/multi-agent/timeline.tsx @@ -0,0 +1,61 @@ +import * as React from "react" +import { cn } from "../../lib/utils" + +export type TimelineEventType = 'message' | 'status' | 'artifact' | 'log' + +export interface TimelineEvent { + id: string + type: TimelineEventType + taskId?: string + agentId?: string + timestamp: Date + title?: string + summary?: string + payload?: unknown +} + +export interface TimelineProps extends React.HTMLAttributes { + events?: TimelineEvent[] + maxHeight?: number + showAgent?: boolean + showTask?: boolean +} + +const TimelineRoot = React.forwardRef( + ({ className, events = [], maxHeight = 360, showAgent = true, showTask = true, ...props }, ref) => { + const ordered = React.useMemo(() => { + return [...events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime()) + }, [events]) + + return ( +
+
Multi-Agent Timeline
+
+ {ordered.length === 0 ? ( +
No timeline events.
+ ) : ( +
    + {ordered.map(e => ( +
  • +
    +
    +
    {e.timestamp.toLocaleTimeString()}
    +
    + {e.title || e.type} + {showAgent && e.agentId && @{e.agentId}} + {showTask && e.taskId && #{e.taskId}} +
    + {e.summary &&
    {e.summary}
    } +
    +
  • + ))} +
+ )} +
+
+ ) + } +) +TimelineRoot.displayName = 'Timeline' + +export const Timeline = TimelineRoot \ No newline at end of file diff --git a/packages/react/src/components/primitives/agent-primitive.tsx b/packages/react/src/components/primitives/agent-primitive.tsx index 7c9c34b..ff16cc8 100644 --- a/packages/react/src/components/primitives/agent-primitive.tsx +++ b/packages/react/src/components/primitives/agent-primitive.tsx @@ -1,79 +1,85 @@ -import { forwardRef, HTMLAttributes } from 'react' -import { useAgent, useAgentCapabilities, useConnection } from '../../hooks/use-agent' -import type { Capability } from '@agentarea/core' +"use client" + +import { forwardRef, HTMLAttributes } from "react"; +import { + useAgent, + useAgentCapabilities, + useConnection, +} from "../../hooks/use-agent"; +import type { Capability } from "@agentarea/core"; // Root container for agent component export interface AgentRootProps extends HTMLAttributes {} const AgentRoot = forwardRef( ({ children, ...props }, ref) => { - const { agentCard } = useAgent() + const { agentCard } = useAgent(); return (
{children}
- ) + ); } -) -AgentRoot.displayName = 'AgentPrimitive.Root' +); +AgentRoot.displayName = "AgentPrimitive.Root"; // Agent name display export interface AgentNameProps extends HTMLAttributes {} const AgentName = forwardRef( ({ children, ...props }, ref) => { - const { agentCard } = useAgent() + const { agentCard } = useAgent(); return (
- {children || agentCard?.name || 'Unknown Agent'} + {children || agentCard?.name || "Unknown Agent"}
- ) + ); } -) -AgentName.displayName = 'AgentPrimitive.Name' +); +AgentName.displayName = "AgentPrimitive.Name"; // Agent description display export interface AgentDescriptionProps extends HTMLAttributes {} const AgentDescription = forwardRef( ({ children, ...props }, ref) => { - const { agentCard } = useAgent() + const { agentCard } = useAgent(); return (
- {children || agentCard?.description || ''} + {children || agentCard?.description || ""}
- ) + ); } -) -AgentDescription.displayName = 'AgentPrimitive.Description' +); +AgentDescription.displayName = "AgentPrimitive.Description"; // Agent connection status export interface AgentStatusProps extends HTMLAttributes {} const AgentStatus = forwardRef( ({ children, ...props }, ref) => { - const { isConnected } = useConnection() + const { isConnected } = useConnection(); return (
- {children || (isConnected ? 'Connected' : 'Disconnected')} + {children || (isConnected ? "Connected" : "Disconnected")}
- ) + ); } -) -AgentStatus.displayName = 'AgentPrimitive.Status' +); +AgentStatus.displayName = "AgentPrimitive.Status"; // Agent capabilities list export interface AgentCapabilitiesProps extends HTMLAttributes { - renderCapability?: (capability: Capability, index: number) => React.ReactNode + renderCapability?: (capability: Capability, index: number) => React.ReactNode; } const AgentCapabilities = forwardRef( ({ renderCapability, children, ...props }, ref) => { - const capabilities = useAgentCapabilities() + const capabilities = useAgentCapabilities(); return (
@@ -81,27 +87,27 @@ const AgentCapabilities = forwardRef(
{capabilities.map((capability, index) => (
- {renderCapability ? - renderCapability(capability, index) : ( -
-
{capability.name}
-
{capability.description}
-
- ) - } + {renderCapability ? ( + renderCapability(capability, index) + ) : ( +
+
{capability.name}
+
{capability.description}
+
+ )}
))}
)}
- ) + ); } -) -AgentCapabilities.displayName = 'AgentPrimitive.Capabilities' +); +AgentCapabilities.displayName = "AgentPrimitive.Capabilities"; // Individual capability display export interface AgentCapabilityProps extends HTMLAttributes { - capability: Capability + capability: Capability; } const AgentCapability = forwardRef( @@ -112,85 +118,101 @@ const AgentCapability = forwardRef(
{capability.name}
{capability.description}
-
- Input Types: {capability.inputTypes.join(', ')} -
-
- Output Types: {capability.outputTypes.join(', ')} -
+
Input Types: {capability.inputTypes.join(", ")}
+
Output Types: {capability.outputTypes.join(", ")}
)}
- ) + ); } -) -AgentCapability.displayName = 'AgentPrimitive.Capability' +); +AgentCapability.displayName = "AgentPrimitive.Capability"; // Feature support indicators export interface AgentFeaturesProps extends HTMLAttributes {} const AgentFeatures = forwardRef( ({ children, ...props }, ref) => { - const { supportsStreaming, supportsPushNotifications } = useAgent() + const { supportsStreaming, supportsPushNotifications } = useAgent(); return (
{children || (
- Streaming: {supportsStreaming() ? 'Supported' : 'Not Supported'} + Streaming: {supportsStreaming() ? "Supported" : "Not Supported"}
-
- Push Notifications: {supportsPushNotifications() ? 'Supported' : 'Not Supported'} +
+ Push Notifications:{" "} + {supportsPushNotifications() ? "Supported" : "Not Supported"}
)}
- ) + ); } -) -AgentFeatures.displayName = 'AgentPrimitive.Features' +); +AgentFeatures.displayName = "AgentPrimitive.Features"; // Conditional rendering based on agent state export interface AgentIfProps extends HTMLAttributes { - connected?: boolean - hasCapabilities?: boolean - supportsStreaming?: boolean - supportsPushNotifications?: boolean + connected?: boolean; + hasCapabilities?: boolean; + supportsStreaming?: boolean; + supportsPushNotifications?: boolean; } const AgentIf = forwardRef( - ({ - connected, - hasCapabilities, - supportsStreaming: supportsStreamingProp, - supportsPushNotifications: supportsPushProp, - children, - ...props - }, ref) => { - const { isConnected, supportsStreaming, supportsPushNotifications } = useAgent() - const capabilities = useAgentCapabilities() + ( + { + connected, + hasCapabilities, + supportsStreaming: supportsStreamingProp, + supportsPushNotifications: supportsPushProp, + children, + ...props + }, + ref + ) => { + const { isConnected, supportsStreaming, supportsPushNotifications } = + useAgent(); + const capabilities = useAgentCapabilities(); // Check connection condition - if (connected !== undefined && isConnected !== connected) return null + if (connected !== undefined && isConnected !== connected) return null; // Check capabilities condition - if (hasCapabilities !== undefined && (capabilities.length > 0) !== hasCapabilities) return null + if ( + hasCapabilities !== undefined && + capabilities.length > 0 !== hasCapabilities + ) + return null; // Check streaming support condition - if (supportsStreamingProp !== undefined && supportsStreaming() !== supportsStreamingProp) return null + if ( + supportsStreamingProp !== undefined && + supportsStreaming() !== supportsStreamingProp + ) + return null; // Check push notifications support condition - if (supportsPushProp !== undefined && supportsPushNotifications() !== supportsPushProp) return null + if ( + supportsPushProp !== undefined && + supportsPushNotifications() !== supportsPushProp + ) + return null; return (
{children}
- ) + ); } -) -AgentIf.displayName = 'AgentPrimitive.If' +); +AgentIf.displayName = "AgentPrimitive.If"; // Export as namespace export const AgentPrimitive = { @@ -202,4 +224,4 @@ export const AgentPrimitive = { Capability: AgentCapability, Features: AgentFeatures, If: AgentIf, -} \ No newline at end of file +}; diff --git a/packages/react/src/components/primitives/task-primitive.tsx b/packages/react/src/components/primitives/task-primitive.tsx index a51a4b6..116d2ad 100644 --- a/packages/react/src/components/primitives/task-primitive.tsx +++ b/packages/react/src/components/primitives/task-primitive.tsx @@ -1,3 +1,5 @@ +"use client" + import { forwardRef, HTMLAttributes, FormHTMLAttributes, ButtonHTMLAttributes, TextareaHTMLAttributes } from 'react' import { useTask, useTaskCreation } from '../../hooks/use-task' import type { Task, TaskStatus } from '@agentarea/core' diff --git a/packages/react/src/components/providers/agent-provider.tsx b/packages/react/src/components/providers/agent-provider.tsx index d8df517..e703ae1 100644 --- a/packages/react/src/components/providers/agent-provider.tsx +++ b/packages/react/src/components/providers/agent-provider.tsx @@ -1,9 +1,20 @@ -import { createContext, useContext, useEffect, useState, ReactNode, useCallback } from 'react' +"use client" + +// @ts-ignore - React types not available in workspace +import React, { createContext, useContext, useEffect, useState, useCallback } from 'react' +// @ts-ignore - React types not available in workspace +import type { ReactNode } from 'react' + +// @ts-ignore - JSX runtime not available +/** @jsx React.createElement */ import type { AgentRuntime, RuntimeEvent, Task, TaskInput, + TaskStatus, + TaskProgress, + TaskError, AgentCard, Capability, TaskWithInputs, @@ -115,7 +126,7 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid setRuntimes(new Map(manager.getAllRuntimes())) break case 'runtime-switched': - setActiveRuntime(event.runtime) + setActiveRuntime(event.runtime || null) break } } @@ -170,8 +181,8 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid } }, [activeRuntime, isClient]) - const handleTaskUpdate = useCallback((update: any) => { - setTasks(prev => { + const handleTaskUpdate = useCallback((update: { taskId: string; status?: TaskStatus; progress?: TaskProgress; artifacts?: any[]; messages?: any[]; error?: TaskError; inputRequests?: TaskInputRequest[]; inputResponses?: InputResponse[]; communicationBlocks?: CommunicationBlock[]; enhancedArtifacts?: any[] }) => { + setTasks((prev: Map) => { const newTasks = new Map(prev) const { taskId } = update const existingTask = newTasks.get(taskId) @@ -187,19 +198,19 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid error: update.error || existingTask.error, updatedAt: new Date(), // Enhanced properties - inputRequests: update.inputRequests || existingTask.inputRequests, - inputResponses: update.inputResponses || existingTask.inputResponses, - communicationBlocks: update.communicationBlocks || existingTask.communicationBlocks, - enhancedArtifacts: update.enhancedArtifacts || existingTask.enhancedArtifacts + inputRequests: update.inputRequests || existingTask.inputRequests || [], + inputResponses: update.inputResponses || existingTask.inputResponses || [], + communicationBlocks: update.communicationBlocks || existingTask.communicationBlocks || [], + enhancedArtifacts: update.enhancedArtifacts || existingTask.enhancedArtifacts || [] } newTasks.set(taskId, updatedTask) // Update active input requests if (updatedTask.inputRequests) { - setActiveInputRequests(prev => { - const filtered = prev.filter(req => req.taskId !== taskId) - const activeRequests = updatedTask.inputRequests?.filter(req => - !updatedTask.inputResponses?.some(resp => resp.requestId === req.id) + setActiveInputRequests((prev: TaskInputRequest[]) => { + const filtered = prev.filter((req: TaskInputRequest) => req.taskId !== taskId) + const activeRequests = updatedTask.inputRequests?.filter((req: TaskInputRequest) => + !updatedTask.inputResponses?.some((resp: InputResponse) => resp.requestId === req.id) ) || [] return [...filtered, ...activeRequests] }) @@ -207,8 +218,8 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid // Update communication blocks if (updatedTask.communicationBlocks) { - setCommunicationBlocks(prev => { - const filtered = prev.filter(block => block.taskId !== taskId) + setCommunicationBlocks((prev: CommunicationBlock[]) => { + const filtered = prev.filter((block: CommunicationBlock) => block.taskId !== taskId) return [...filtered, ...updatedTask.communicationBlocks!] }) } @@ -244,11 +255,11 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid const connection = await activeRuntime.connect(endpoint, config) - setConnections(prev => [...prev.filter(c => c.endpoint !== endpoint), connection]) - setConnectionStatus(prev => ({ ...prev, [endpoint]: 'connected' })) + setConnections((prev: Connection[]) => [...prev.filter((c: Connection) => c.endpoint !== endpoint), connection]) + setConnectionStatus((prev: Record) => ({ ...prev, [endpoint]: 'connected' })) setError(null) } catch (err) { - setConnectionStatus(prev => ({ ...prev, [endpoint]: 'error' })) + setConnectionStatus((prev: Record) => ({ ...prev, [endpoint]: 'error' })) setError(err as Error) throw err } @@ -262,10 +273,10 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid try { await activeRuntime.disconnect(connectionId) - setConnections(prev => prev.filter(c => c.id !== connectionId)) - setConnectionStatus(prev => { + setConnections((prev: Connection[]) => prev.filter((c: Connection) => c.id !== connectionId)) + setConnectionStatus((prev: Record) => { const newStatus = { ...prev } - const connection = connections.find(c => c.id === connectionId) + const connection = connections.find((c: Connection) => c.id === connectionId) if (connection) { newStatus[connection.endpoint] = 'disconnected' } @@ -287,7 +298,7 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid } }, [manager]) - const submitTask = useCallback(async (input: any, agentId?: string) => { + const submitTask = useCallback(async (input: TaskInput, agentId?: string) => { if (!activeRuntime) { throw new Error('No active runtime available') } @@ -304,7 +315,7 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid enhancedArtifacts: [] } - setTasks(prev => new Map(prev.set(response.task.id, taskWithInputs))) + setTasks((prev: Map) => new Map(prev.set(response.task.id, taskWithInputs))) return response.task } catch (err) { @@ -319,7 +330,7 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid } try { - const request = activeInputRequests.find(req => req.id === requestId) + const request = activeInputRequests.find((req: TaskInputRequest) => req.id === requestId) if (!request) { throw new Error(`Input request ${requestId} not found`) } @@ -327,10 +338,10 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid await activeRuntime.handleInputRequest(request.taskId, response) // Update local state - setActiveInputRequests(prev => prev.filter(req => req.id !== requestId)) + setActiveInputRequests((prev: TaskInputRequest[]) => prev.filter((req: TaskInputRequest) => req.id !== requestId)) // Update task with response - setTasks(prev => { + setTasks((prev: Map) => { const newTasks = new Map(prev) const task = newTasks.get(request.taskId) if (task) { @@ -358,7 +369,7 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid await activeRuntime.sendMessage(message, targetAgent) // Add message to local state - setProtocolMessages(prev => [...prev, message]) + setProtocolMessages((prev: ProtocolMessage[]) => [...prev, message]) } catch (err) { setError(err as Error) throw err @@ -401,6 +412,7 @@ export function AgentProvider({ runtime, runtimeManager, children }: AgentProvid sendProtocolMessage } + // @ts-ignore - JSX runtime issue return ( {children} diff --git a/packages/react/src/components/providers/config-provider.tsx b/packages/react/src/components/providers/config-provider.tsx index 1514ddc..62f3bec 100644 --- a/packages/react/src/components/providers/config-provider.tsx +++ b/packages/react/src/components/providers/config-provider.tsx @@ -1,4 +1,6 @@ -import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react' +"use client" + +import React, { createContext, useContext, useEffect, useState, useMemo, ReactNode } from 'react' import type { AgentUIConfig, RuntimeEnvironment, BuildEnvironment, EnvironmentCapabilities } from '@agentarea/core' import { useRuntimeEnvironment, useBuildEnvironment, useEnvironmentCapabilities } from '../../hooks/use-runtime-environment' import { createEnvironmentConfig, ConfigUtils } from '../../lib/environment-config' @@ -72,14 +74,21 @@ export function ConfigProvider({ const environment = useRuntimeEnvironment() const buildEnvironment = useBuildEnvironment() const capabilities = useEnvironmentCapabilities() - - const [config, setConfig] = useState(() => + + // Memoize user-provided config objects to stabilize references + const stableUserConfig = useMemo(() => userConfig, [JSON.stringify(userConfig)]) + const stableDevConfig = useMemo(() => developmentConfig, [JSON.stringify(developmentConfig)]) + const stableProdConfig = useMemo(() => productionConfig, [JSON.stringify(productionConfig)]) + const stableNextConfig = useMemo(() => nextjsConfig, [JSON.stringify(nextjsConfig)]) + const stableViteConfig = useMemo(() => viteConfig, [JSON.stringify(viteConfig)]) + + const [config, setConfig] = useState(() => generateInitialConfig( - userConfig, - developmentConfig, - productionConfig, - nextjsConfig, - viteConfig, + stableUserConfig, + stableDevConfig, + stableProdConfig, + stableNextConfig, + stableViteConfig, environment, buildEnvironment, capabilities, @@ -96,11 +105,11 @@ export function ConfigProvider({ // Update configuration when environment or user config changes useEffect(() => { const newConfig = generateInitialConfig( - userConfig, - developmentConfig, - productionConfig, - nextjsConfig, - viteConfig, + stableUserConfig, + stableDevConfig, + stableProdConfig, + stableNextConfig, + stableViteConfig, environment, buildEnvironment, capabilities, @@ -108,11 +117,11 @@ export function ConfigProvider({ ) setConfig(newConfig) }, [ - userConfig, - developmentConfig, - productionConfig, - nextjsConfig, - viteConfig, + stableUserConfig, + stableDevConfig, + stableProdConfig, + stableNextConfig, + stableViteConfig, environment, buildEnvironment, capabilities, @@ -135,22 +144,25 @@ export function ConfigProvider({ console.error('AgentUI Configuration Errors:', result.errors) } } - }, [config, validateOnMount, environment, buildEnvironment, capabilities]) + }, [config, validateOnMount, environment, buildEnvironment.mode, capabilities]) + + // Memoize configManager used in helpers to avoid unnecessary re-instantiation in closures + const configManager = useMemo( + () => createEnvironmentConfig(environment, buildEnvironment, capabilities), + [environment, buildEnvironment, capabilities] + ) const updateConfig = (updates: Partial) => { - setConfig(prevConfig => { - const configManager = createEnvironmentConfig(environment, buildEnvironment, capabilities) - return configManager.generateConfig({ ...prevConfig, ...updates }) - }) + setConfig(prevConfig => configManager.generateConfig({ ...prevConfig, ...updates })) } const resetConfig = () => { const newConfig = generateInitialConfig( - userConfig, - developmentConfig, - productionConfig, - nextjsConfig, - viteConfig, + stableUserConfig, + stableDevConfig, + stableProdConfig, + stableNextConfig, + stableViteConfig, environment, buildEnvironment, capabilities, @@ -187,7 +199,6 @@ export function ConfigProvider({ } const getOptimizedConfig = (): AgentUIConfig => { - const configManager = createEnvironmentConfig(environment, buildEnvironment, capabilities) return configManager.generateConfig(config) } diff --git a/packages/react/src/components/providers/input-provider.tsx b/packages/react/src/components/providers/input-provider.tsx index 3070dd5..2ccc98d 100644 --- a/packages/react/src/components/providers/input-provider.tsx +++ b/packages/react/src/components/providers/input-provider.tsx @@ -1,3 +1,5 @@ +"use client" + import { createContext, useContext, useEffect, useState, ReactNode, useCallback } from 'react' import type { TaskInputRequest, diff --git a/packages/react/src/components/task.tsx b/packages/react/src/components/task.tsx index 82edf9e..2fc8e62 100644 --- a/packages/react/src/components/task.tsx +++ b/packages/react/src/components/task.tsx @@ -274,6 +274,40 @@ const TaskCancel = React.forwardRef( ) TaskCancel.displayName = "Task.Cancel" +// Task retry button +export interface TaskRetryProps extends React.ButtonHTMLAttributes { + taskId?: string + onRetry?: (taskId: string) => void +} + +const TaskRetry = React.forwardRef( + ({ taskId, onRetry, onClick, children, ...props }, ref) => { + const { task } = useTask(taskId) + + const handleClick = async (e: React.MouseEvent) => { + if (taskId && onRetry) { + onRetry(taskId) + } + onClick?.(e) + } + + const canRetry = task?.status === "failed" || task?.status === "canceled" + + return ( + + ) + } +) +TaskRetry.displayName = "Task.Retry" + // Enhanced task chat interface export interface TaskChatProps extends React.HTMLAttributes { taskId?: string @@ -372,7 +406,7 @@ const TaskChat = React.forwardRef( key={index} role={message.role} avatar={message.role === "agent" ? avatarAgent : avatarUser} - timestamp={new Date()} + // Avoid SSR mismatch by not rendering dynamic timestamp > {message.parts.map((part, partIndex) => (
@@ -430,7 +464,7 @@ const TaskChat = React.forwardRef( { + const [tree, setTree] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const { runtimeManager } = useAgentContext(); + + const fetchTree = async () => { + if (!runtimeManager) return; + setLoading(true); + try { + const node = await runtimeManager.getDelegationTree(parentTaskId); + setTree(node); + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to fetch delegation tree'); + } finally { + setLoading(false); + } + }; + + const delegate = async (subTasks: SubTask[], config?: DelegationConfig) => { + if (!runtimeManager) throw new Error('No runtime manager available'); + setLoading(true); + try { + const details = await runtimeManager.delegateSubTask(parentTaskId, subTasks, config); + await fetchTree(); // Refresh tree + return details; + } catch (err) { + setError(err instanceof Error ? err.message : 'Delegation failed'); + throw err; + } finally { + setLoading(false); + } + }; + + useEffect(() => { + if (parentTaskId) fetchTree(); + }, [parentTaskId]); + + return { tree, delegate, loading, error, refetch: fetchTree }; +}; \ No newline at end of file diff --git a/packages/react/src/hooks/use-graceful-degradation.ts b/packages/react/src/hooks/use-graceful-degradation.ts index 60c295f..1051059 100644 --- a/packages/react/src/hooks/use-graceful-degradation.ts +++ b/packages/react/src/hooks/use-graceful-degradation.ts @@ -1,3 +1,5 @@ +"use client" + import React from 'react' import { FeatureDetection, ArtifactUtils, InputUtils, ErrorMessages } from '../lib/fallback-utils' import type { EnhancedArtifact, TaskInputRequest } from '@agentarea/core' diff --git a/packages/react/src/hooks/use-realtime.ts b/packages/react/src/hooks/use-realtime.ts index 330bb34..152c063 100644 --- a/packages/react/src/hooks/use-realtime.ts +++ b/packages/react/src/hooks/use-realtime.ts @@ -1,3 +1,5 @@ +"use client" + import { useState, useCallback, useEffect, useRef } from 'react' import { useAgentContext } from '../components/providers/agent-provider' import type { diff --git a/packages/react/src/hooks/use-runtime-environment.ts b/packages/react/src/hooks/use-runtime-environment.ts index 9a5a2d8..4c07d2c 100644 --- a/packages/react/src/hooks/use-runtime-environment.ts +++ b/packages/react/src/hooks/use-runtime-environment.ts @@ -1,3 +1,5 @@ +"use client" + import { useMemo } from 'react' import type { RuntimeEnvironment } from '@agentarea/core' diff --git a/packages/react/src/hooks/use-ssr.ts b/packages/react/src/hooks/use-ssr.ts index 6e85af4..076dcee 100644 --- a/packages/react/src/hooks/use-ssr.ts +++ b/packages/react/src/hooks/use-ssr.ts @@ -1,3 +1,5 @@ +"use client" + import { useEffect, useState } from 'react' /** diff --git a/packages/react/src/hooks/use-task.ts b/packages/react/src/hooks/use-task.ts index 77c24e6..ad839c0 100644 --- a/packages/react/src/hooks/use-task.ts +++ b/packages/react/src/hooks/use-task.ts @@ -1,3 +1,5 @@ +"use client" + import { useState, useCallback, useEffect, useRef } from 'react' import { useAgentContext } from '../components/providers/agent-provider' import type { @@ -310,9 +312,9 @@ export function useTaskInput(taskId: string) { const [error, setError] = useState(null) const task = tasks.get(taskId) as TaskWithInputs | undefined - const activeRequests = task?.inputRequests || [] - const responses = new Map( - (task?.inputResponses || []).map(response => [response.requestId, response]) + const activeRequests: TaskInputRequest[] = task?.inputRequests ?? [] + const responses: Map = new Map( + (task?.inputResponses ?? []).map((response: InputResponse) => [response.requestId, response]) ) const submitResponse = useCallback(async (requestId: string, value: unknown): Promise => { diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 1fe077e..6ce6351 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,3 +1,6 @@ +// Import styles +import '@agentarea/styles/index.css' + // Export React components and providers export * from './components/providers/agent-provider' export * from './components/providers/config-provider' @@ -9,6 +12,9 @@ export * from './components/agent-ui' export * from './components/artifacts' export * from './components/inputs' export * from './components/blocks' +export * from './components/multi-agent' +export * from './components/multi-agent/task-tree-list' +export * from './components/multi-agent/temp-task-graph' // Export SSR-safe components export * from './components/ssr-safe/agent-ui-ssr' @@ -21,8 +27,9 @@ export * from './hooks/use-connection' export * from './hooks/use-realtime' export * from './hooks/use-ssr' export * from './hooks/use-runtime-environment' +export * from './hooks/use-delegation' // Export utilities and configuration export * from './lib/dynamic-import' export * from './lib/environment-config' -export * from './lib/config-manager' \ No newline at end of file +export * from './lib/config-manager' diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index 289a9fa..163134f 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -2,7 +2,6 @@ "compilerOptions": { "target": "es2018", "lib": ["dom", "dom.iterable", "es2020"], - "types": ["node"], "module": "esnext", "moduleResolution": "node", "rootDir": "./src", @@ -14,10 +13,10 @@ "strict": true, "esModuleInterop": true, "skipLibCheck": true, + "types": ["node", "react", "react-dom"], "forceConsistentCasingInFileNames": true, "allowSyntheticDefaultImports": true, - "resolveJsonModule": true, - "composite": true + "resolveJsonModule": true }, "include": [ "src/**/*" diff --git a/packages/styles/package.json b/packages/styles/package.json new file mode 100644 index 0000000..1d4a67a --- /dev/null +++ b/packages/styles/package.json @@ -0,0 +1,53 @@ +{ + "name": "@agentarea/styles", + "version": "0.1.0", + "description": "Pre-compiled CSS styles for AgentArea UI components", + "main": "dist/index.css", + "types": "dist/index.d.ts", + "exports": { + "./index.css": "./dist/index.css", + "./components.css": "./dist/components.css", + "./package.json": "./package.json" + }, + "sideEffects": [ + "*.css" + ], + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "scripts": { + "build": "pnpm clean && pnpm build:css && pnpm build:types", + "build:css": "tailwindcss -i ./src/index.css -o ./dist/index.css --minify && tailwindcss -i ./src/components.css -o ./dist/components.css --minify", + "build:types": "cp src/index.d.ts dist/index.d.ts", + "dev": "pnpm build:css --watch", + "clean": "rm -rf dist", + "prepublishOnly": "pnpm build" + }, + "keywords": [ + "css", + "styles", + "ui", + "agent", + "components", + "tailwind" + ], + "license": "MIT", + "type": "module", + "devDependencies": { + "autoprefixer": "^10.4.20", + "postcss": "^8.5.0", + "tailwindcss": "^3.4.17", + "typescript": "^5.8.3" + }, + "repository": { + "type": "git", + "url": "https://github.com/agentarea-hq/agentarea-ui-sdk.git", + "directory": "packages/styles" + }, + "bugs": { + "url": "https://github.com/agentarea-hq/agentarea-ui-sdk/issues" + }, + "homepage": "https://github.com/agentarea-hq/agentarea-ui-sdk#readme" +} \ No newline at end of file diff --git a/packages/styles/src/components.css b/packages/styles/src/components.css new file mode 100644 index 0000000..0a0960a --- /dev/null +++ b/packages/styles/src/components.css @@ -0,0 +1,39 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* AgentArea UI Component Utilities */ +/* These are optional utility classes that can be used alongside Tailwind */ + +@layer components { + /* Chat message variants */ + .chat-message-user { + @apply flex-row-reverse; + } + + .chat-message-agent { + @apply flex-row; + } + + .chat-message-streaming { + @apply animate-pulse; + } + + /* Task status variants */ + .task-status-running { + @apply bg-blue-50 text-blue-800 border-blue-200; + } + + .task-status-completed { + @apply bg-green-50 text-green-800 border-green-200; + } + + .task-status-failed { + @apply bg-red-50 text-red-800 border-red-200; + } + + /* Progress bar animation */ + .progress-indeterminate { + @apply animate-pulse; + } +} \ No newline at end of file diff --git a/packages/styles/src/index.css b/packages/styles/src/index.css new file mode 100644 index 0000000..82b0357 --- /dev/null +++ b/packages/styles/src/index.css @@ -0,0 +1,60 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* AgentArea UI Base Styles */ +@layer base { + :root { + --agentarea-background: 0 0% 100%; + --agentarea-foreground: 222.2 84% 4.9%; + --agentarea-card: 0 0% 100%; + --agentarea-card-foreground: 222.2 84% 4.9%; + --agentarea-popover: 0 0% 100%; + --agentarea-popover-foreground: 222.2 84% 4.9%; + --agentarea-primary: 222.2 84% 4.9%; + --agentarea-primary-foreground: 210 40% 98%; + --agentarea-secondary: 210 40% 96%; + --agentarea-secondary-foreground: 222.2 84% 4.9%; + --agentarea-muted: 210 40% 96%; + --agentarea-muted-foreground: 215.4 16.3% 46.9%; + --agentarea-accent: 210 40% 96%; + --agentarea-accent-foreground: 222.2 84% 4.9%; + --agentarea-destructive: 0 84.2% 60.2%; + --agentarea-destructive-foreground: 210 40% 98%; + --agentarea-border: 214.3 31.8% 91.4%; + --agentarea-input: 214.3 31.8% 91.4%; + --agentarea-ring: 222.2 84% 4.9%; + --agentarea-radius: 0.5rem; + } + + .dark { + --agentarea-background: 222.2 84% 4.9%; + --agentarea-foreground: 210 40% 98%; + --agentarea-card: 222.2 84% 4.9%; + --agentarea-card-foreground: 210 40% 98%; + --agentarea-popover: 222.2 84% 4.9%; + --agentarea-popover-foreground: 210 40% 98%; + --agentarea-primary: 210 40% 98%; + --agentarea-primary-foreground: 222.2 84% 4.9%; + --agentarea-secondary: 222.2 84% 4.9%; + --agentarea-secondary-foreground: 210 40% 98%; + --agentarea-muted: 222.2 84% 4.9%; + --agentarea-muted-foreground: 215 20.2% 65.1%; + --agentarea-accent: 222.2 84% 4.9%; + --agentarea-accent-foreground: 210 40% 98%; + --agentarea-destructive: 0 62.8% 30.6%; + --agentarea-destructive-foreground: 210 40% 98%; + --agentarea-border: 217.2 32.6% 17.5%; + --agentarea-input: 217.2 32.6% 17.5%; + --agentarea-ring: 212.7 26.8% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/packages/styles/tailwind.config.js b/packages/styles/tailwind.config.js new file mode 100644 index 0000000..dabb300 --- /dev/null +++ b/packages/styles/tailwind.config.js @@ -0,0 +1,69 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + '../react/src/**/*.{js,ts,jsx,tsx}', + '../react/dist/**/*.{js,ts,jsx,tsx}', + '../core/src/**/*.{js,ts,jsx,tsx}', + '../core/dist/**/*.{js,ts,jsx,tsx}', + '../../apps/*/src/**/*.{js,ts,jsx,tsx}' + ], + theme: { + extend: { + colors: { + border: 'hsl(var(--agentarea-border))', + input: 'hsl(var(--agentarea-input))', + ring: 'hsl(var(--agentarea-ring))', + background: 'hsl(var(--agentarea-background))', + foreground: 'hsl(var(--agentarea-foreground))', + primary: { + DEFAULT: 'hsl(var(--agentarea-primary))', + foreground: 'hsl(var(--agentarea-primary-foreground))' + }, + secondary: { + DEFAULT: 'hsl(var(--agentarea-secondary))', + foreground: 'hsl(var(--agentarea-secondary-foreground))' + }, + destructive: { + DEFAULT: 'hsl(var(--agentarea-destructive))', + foreground: 'hsl(var(--agentarea-destructive-foreground))' + }, + muted: { + DEFAULT: 'hsl(var(--agentarea-muted))', + foreground: 'hsl(var(--agentarea-muted-foreground))' + }, + accent: { + DEFAULT: 'hsl(var(--agentarea-accent))', + foreground: 'hsl(var(--agentarea-accent-foreground))' + }, + popover: { + DEFAULT: 'hsl(var(--agentarea-popover))', + foreground: 'hsl(var(--agentarea-popover-foreground))' + }, + card: { + DEFAULT: 'hsl(var(--agentarea-card))', + foreground: 'hsl(var(--agentarea-card-foreground))' + } + }, + borderRadius: { + lg: 'var(--agentarea-radius)', + md: 'calc(var(--agentarea-radius) - 2px)', + sm: 'calc(var(--agentarea-radius) - 4px)' + }, + keyframes: { + 'accordion-down': { + from: { height: '0' }, + to: { height: 'var(--radix-accordion-content-height)' } + }, + 'accordion-up': { + from: { height: 'var(--radix-accordion-content-height)' }, + to: { height: '0' } + } + }, + animation: { + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out' + } + } + }, + plugins: [] +}; \ No newline at end of file diff --git a/packages/styles/tsconfig.json b/packages/styles/tsconfig.json new file mode 100644 index 0000000..159be9e --- /dev/null +++ b/packages/styles/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "declarationMap": true, + "sourceMap": false, + "composite": true, + "incremental": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "dist", + "node_modules", + "**/*.test.*", + "**/*.spec.*" + ] +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 400367c..613679a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,12 @@ importers: '@agentarea/react': specifier: workspace:* version: link:packages/react + '@agentarea/styles': + specifier: workspace:* + version: link:packages/styles '@storybook/addon-essentials': specifier: ^8.6.14 - version: 8.6.14(@types/react@19.1.8)(storybook@8.6.14) + version: 8.6.14(@types/react@19.1.13)(storybook@8.6.14) '@storybook/addon-interactions': specifier: ^8.6.14 version: 8.6.14(storybook@8.6.14) @@ -31,19 +34,19 @@ importers: version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.14)(typescript@5.8.3) '@storybook/react-vite': specifier: ^8.6.14 - version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.45.0)(storybook@8.6.14)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0)) + version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.50.2)(storybook@8.6.14)(typescript@5.8.3)(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1)) '@storybook/test': specifier: ^8.6.14 version: 8.6.14(storybook@8.6.14) '@testing-library/jest-dom': specifier: ^6.6.3 - version: 6.6.3 + version: 6.8.0 '@testing-library/react': specifier: ^16.1.0 - version: 16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@testing-library/user-event': specifier: ^14.5.2 - version: 14.5.2(@testing-library/dom@10.4.0) + version: 14.6.1(@testing-library/dom@10.4.0) '@types/jest': specifier: ^29.5.14 version: 29.5.14 @@ -52,10 +55,10 @@ importers: version: 24.0.13 '@types/react': specifier: ^19.1.8 - version: 19.1.8 + version: 19.1.13 '@types/react-dom': specifier: ^19.1.6 - version: 19.1.6(@types/react@19.1.8) + version: 19.1.9(@types/react@19.1.13) '@vitest/ui': specifier: ^2.1.8 version: 2.1.9(vitest@2.1.9) @@ -89,21 +92,180 @@ importers: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.17) + turbo: + specifier: ^2.5.6 + version: 2.5.6 typescript: specifier: ^5.8.3 version: 5.8.3 vite: specifier: ^6.0.7 - version: 6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0) + version: 6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1) vitest: specifier: ^2.1.8 - version: 2.1.9(@types/node@24.0.13)(@vitest/ui@2.1.9)(jsdom@26.1.0) + version: 2.1.9(@types/node@24.0.13)(@vitest/ui@2.1.9)(jsdom@26.1.0)(lightningcss@1.30.1) + + apps/a2a-nextjs: + dependencies: + '@agentarea/core': + specifier: workspace:* + version: link:../../packages/core + '@agentarea/react': + specifier: workspace:* + version: link:../../packages/react + '@agentarea/styles': + specifier: workspace:* + version: link:../../packages/styles + next: + specifier: 15.4.2 + version: 15.4.2(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: + specifier: 19.1.0 + version: 19.1.0 + react-dom: + specifier: 19.1.0 + version: 19.1.0(react@19.1.0) + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.1 + '@tailwindcss/postcss': + specifier: ^4 + version: 4.1.13 + '@types/node': + specifier: ^20 + version: 20.19.15 + '@types/react': + specifier: ^19 + version: 19.1.13 + '@types/react-dom': + specifier: ^19 + version: 19.1.9(@types/react@19.1.13) + eslint: + specifier: ^9 + version: 9.35.0(jiti@2.5.1) + eslint-config-next: + specifier: 15.4.2 + version: 15.4.2(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + tailwindcss: + specifier: ^4 + version: 4.1.13 + typescript: + specifier: ^5 + version: 5.8.3 + + apps/chat-vite: + dependencies: + '@agentarea/core': + specifier: workspace:* + version: link:../../packages/core + '@agentarea/react': + specifier: workspace:* + version: link:../../packages/react + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + devDependencies: + '@eslint/js': + specifier: ^9.30.1 + version: 9.35.0 + '@types/react': + specifier: ^19.1.8 + version: 19.1.13 + '@types/react-dom': + specifier: ^19.1.6 + version: 19.1.9(@types/react@19.1.13) + '@vitejs/plugin-react-swc': + specifier: ^3.10.2 + version: 3.11.0(vite@7.1.5(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1)) + eslint: + specifier: ^9.30.1 + version: 9.35.0(jiti@2.5.1) + eslint-plugin-react-hooks: + specifier: ^5.2.0 + version: 5.2.0(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-react-refresh: + specifier: ^0.4.20 + version: 0.4.20(eslint@9.35.0(jiti@2.5.1)) + globals: + specifier: ^16.3.0 + version: 16.4.0 + typescript: + specifier: ~5.8.3 + version: 5.8.3 + typescript-eslint: + specifier: ^8.35.1 + version: 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + vite: + specifier: ^7.0.4 + version: 7.1.5(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1) + + apps/docs: + dependencies: + '@agentarea/core': + specifier: workspace:* + version: link:../../packages/core + '@agentarea/react': + specifier: workspace:* + version: link:../../packages/react + '@agentarea/styles': + specifier: workspace:* + version: link:../../packages/styles + fumadocs-core: + specifier: 15.6.4 + version: 15.6.4(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + fumadocs-mdx: + specifier: 11.6.11 + version: 11.6.11(fumadocs-core@15.6.4(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1)) + fumadocs-ui: + specifier: 15.6.4 + version: 15.6.4(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.1.13) + next: + specifier: 15.4.1 + version: 15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.1.11 + version: 4.1.13 + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 + '@types/node': + specifier: 24.0.13 + version: 24.0.13 + '@types/react': + specifier: ^19.1.8 + version: 19.1.13 + '@types/react-dom': + specifier: ^19.1.6 + version: 19.1.9(@types/react@19.1.13) + postcss: + specifier: ^8.5.6 + version: 8.5.6 + react-live: + specifier: ^4.1.8 + version: 4.1.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + tailwindcss: + specifier: ^4.1.11 + version: 4.1.13 + typescript: + specifier: ^5.8.3 + version: 5.8.3 packages/core: dependencies: '@a2a-js/sdk': specifier: ^0.2.4 - version: 0.2.4 + version: 0.2.5 devDependencies: '@types/node': specifier: ^24.0.13 @@ -117,12 +279,15 @@ importers: '@agentarea/core': specifier: workspace:* version: link:../core + '@agentarea/styles': + specifier: workspace:* + version: link:../styles '@radix-ui/react-progress': specifier: ^1.1.0 - version: 1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@radix-ui/react-slot': specifier: ^1.1.0 - version: 1.2.3(@types/react@19.1.8)(react@19.1.0) + version: 1.2.3(@types/react@19.1.13)(react@19.1.0) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -138,10 +303,10 @@ importers: version: 24.0.13 '@types/react': specifier: ^19.1.8 - version: 19.1.8 + version: 19.1.13 '@types/react-dom': specifier: ^19.1.6 - version: 19.1.6(@types/react@19.1.8) + version: 19.1.9(@types/react@19.1.13) react: specifier: ^19.1.0 version: 19.1.0 @@ -152,23 +317,34 @@ importers: specifier: ^5.8.3 version: 5.8.3 + packages/styles: + devDependencies: + autoprefixer: + specifier: ^10.4.20 + version: 10.4.21(postcss@8.5.6) + postcss: + specifier: ^8.5.0 + version: 8.5.6 + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17 + typescript: + specifier: ^5.8.3 + version: 5.8.3 + packages: - '@a2a-js/sdk@0.2.4': - resolution: {integrity: sha512-s9wEF5SUswhaAeAERA3tIBcrYEqWfkf+B3yiofxFX8+wnJMQL2l6bT6e7LZqjFf8sup0IRqFtGbckBPDLQymjw==} + '@a2a-js/sdk@0.2.5': + resolution: {integrity: sha512-VTDuRS5V0ATbJ/LkaQlisMnTAeYKXAK6scMguVBstf+KIBQ7HIuKhiXLv+G/hvejkV+THoXzoNifInAkU81P1g==} engines: {node: '>=18'} - '@adobe/css-tools@4.4.3': - resolution: {integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==} + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@asamuzakjp/css-color@3.2.0': resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} @@ -176,16 +352,16 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + '@babel/compat-data@7.28.4': + resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.0': - resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} + '@babel/core@7.28.4': + resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.0': - resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} + '@babel/generator@7.28.3': + resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.27.2': @@ -200,8 +376,8 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.27.3': - resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -218,33 +394,33 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.27.6': - resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.0': - resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime@7.27.6': - resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.0': - resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.1': - resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} - '@csstools/color-helpers@5.0.2': - resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} engines: {node: '>=18'} '@csstools/css-calc@2.1.4': @@ -254,8 +430,8 @@ packages: '@csstools/css-parser-algorithms': ^3.0.5 '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-color-parser@3.0.10': - resolution: {integrity: sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==} + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} engines: {node: '>=18'} peerDependencies: '@csstools/css-parser-algorithms': ^3.0.5 @@ -271,14 +447,23 @@ packages: resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} engines: {node: '>=18'} + '@emnapi/core@1.5.0': + resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} + + '@emnapi/runtime@1.5.0': + resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.6': - resolution: {integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==} + '@esbuild/aix-ppc64@0.25.9': + resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -289,8 +474,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.6': - resolution: {integrity: sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==} + '@esbuild/android-arm64@0.25.9': + resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -301,8 +486,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.6': - resolution: {integrity: sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==} + '@esbuild/android-arm@0.25.9': + resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -313,8 +498,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.6': - resolution: {integrity: sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==} + '@esbuild/android-x64@0.25.9': + resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -325,8 +510,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.6': - resolution: {integrity: sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==} + '@esbuild/darwin-arm64@0.25.9': + resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -337,8 +522,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.6': - resolution: {integrity: sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==} + '@esbuild/darwin-x64@0.25.9': + resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -349,8 +534,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.6': - resolution: {integrity: sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==} + '@esbuild/freebsd-arm64@0.25.9': + resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -361,8 +546,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.6': - resolution: {integrity: sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==} + '@esbuild/freebsd-x64@0.25.9': + resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -373,8 +558,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.6': - resolution: {integrity: sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==} + '@esbuild/linux-arm64@0.25.9': + resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -385,8 +570,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.6': - resolution: {integrity: sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==} + '@esbuild/linux-arm@0.25.9': + resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -397,8 +582,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.6': - resolution: {integrity: sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==} + '@esbuild/linux-ia32@0.25.9': + resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -409,8 +594,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.6': - resolution: {integrity: sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==} + '@esbuild/linux-loong64@0.25.9': + resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -421,8 +606,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.6': - resolution: {integrity: sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==} + '@esbuild/linux-mips64el@0.25.9': + resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -433,8 +618,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.6': - resolution: {integrity: sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==} + '@esbuild/linux-ppc64@0.25.9': + resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -445,8 +630,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.6': - resolution: {integrity: sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==} + '@esbuild/linux-riscv64@0.25.9': + resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -457,8 +642,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.6': - resolution: {integrity: sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==} + '@esbuild/linux-s390x@0.25.9': + resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -469,14 +654,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.6': - resolution: {integrity: sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==} + '@esbuild/linux-x64@0.25.9': + resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.6': - resolution: {integrity: sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==} + '@esbuild/netbsd-arm64@0.25.9': + resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -487,14 +672,14 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.6': - resolution: {integrity: sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==} + '@esbuild/netbsd-x64@0.25.9': + resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.6': - resolution: {integrity: sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==} + '@esbuild/openbsd-arm64@0.25.9': + resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -505,14 +690,14 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.6': - resolution: {integrity: sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==} + '@esbuild/openbsd-x64@0.25.9': + resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.6': - resolution: {integrity: sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==} + '@esbuild/openharmony-arm64@0.25.9': + resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -523,8 +708,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.6': - resolution: {integrity: sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==} + '@esbuild/sunos-x64@0.25.9': + resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -535,8 +720,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.6': - resolution: {integrity: sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==} + '@esbuild/win32-arm64@0.25.9': + resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -547,8 +732,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.6': - resolution: {integrity: sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==} + '@esbuild/win32-ia32@0.25.9': + resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -559,16 +744,214 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.6': - resolution: {integrity: sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==} + '@esbuild/win32-x64@0.25.9': + resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.3.1': + resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.15.2': + resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.35.0': + resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.3.5': + resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/react-dom@2.1.6': + resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + + '@formatjs/intl-localematcher@0.6.1': + resolution: {integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@img/sharp-darwin-arm64@0.34.3': + resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.3': + resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.0': + resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.0': + resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.0': + resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.0': + resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.0': + resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.0': + resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.0': + resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.0': + resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.3': + resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.3': + resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.3': + resolution: {integrity: sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.3': + resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.3': + resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.3': + resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.3': + resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.3': + resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.3': + resolution: {integrity: sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.3': + resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.3': + resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jest/expect-utils@29.7.0': resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -590,25 +973,139 @@ packages: typescript: optional: true - '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@mdx-js/react@3.1.0': - resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} peerDependencies: '@types/react': '>=16' react: '>=16' + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@next/env@15.4.1': + resolution: {integrity: sha512-DXQwFGAE2VH+f2TJsKepRXpODPU+scf5fDbKOME8MMyeyswe4XwgRdiiIYmBfkXU+2ssliLYznajTrOQdnLR5A==} + + '@next/env@15.4.2': + resolution: {integrity: sha512-kd7MvW3pAP7tmk1NaiX4yG15xb2l4gNhteKQxt3f+NGR22qwPymn9RBuv26QKfIKmfo6z2NpgU8W2RT0s0jlvg==} + + '@next/eslint-plugin-next@15.4.2': + resolution: {integrity: sha512-k0rjdWjXBY6tAOty1ckrMETE6Mx66d85NsgcAIdDp7/cXOsTJ93ywmbg3uUcpxX5TUHFEcCWI5mb8nPhwCe9jg==} + + '@next/swc-darwin-arm64@15.4.1': + resolution: {integrity: sha512-L+81yMsiHq82VRXS2RVq6OgDwjvA4kDksGU8hfiDHEXP+ncKIUhUsadAVB+MRIp2FErs/5hpXR0u2eluWPAhig==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-arm64@15.4.2': + resolution: {integrity: sha512-ovqjR8NjCBdBf1U+R/Gvn0RazTtXS9n6wqs84iFaCS1NHbw9ksVE4dfmsYcLoyUVd9BWE0bjkphOWrrz8uz/uw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.4.1': + resolution: {integrity: sha512-jfz1RXu6SzL14lFl05/MNkcN35lTLMJWPbqt7Xaj35+ZWAX342aePIJrN6xBdGeKl6jPXJm0Yqo3Xvh3Gpo3Uw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-darwin-x64@15.4.2': + resolution: {integrity: sha512-I8d4W7tPqbdbHRI4z1iBfaoJIBrEG4fnWKIe+Rj1vIucNZ5cEinfwkBt3RcDF00bFRZRDpvKuDjgMFD3OyRBnw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.4.1': + resolution: {integrity: sha512-k0tOFn3dsnkaGfs6iQz8Ms6f1CyQe4GacXF979sL8PNQxjYS1swx9VsOyUQYaPoGV8nAZ7OX8cYaeiXGq9ahPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-gnu@15.4.2': + resolution: {integrity: sha512-lvhz02dU3Ec5thzfQ2RCUeOFADjNkS/px1W7MBt7HMhf0/amMfT8Z/aXOwEA+cVWN7HSDRSUc8hHILoHmvajsg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.4.1': + resolution: {integrity: sha512-4ogGQ/3qDzbbK3IwV88ltihHFbQVq6Qr+uEapzXHXBH1KsVBZOB50sn6BWHPcFjwSoMX2Tj9eH/fZvQnSIgc3g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.4.2': + resolution: {integrity: sha512-v+5PPfL8UP+KKHS3Mox7QMoeFdMlaV0zeNMIF7eLC4qTiVSO0RPNnK0nkBZSD5BEkkf//c+vI9s/iHxddCZchA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.4.1': + resolution: {integrity: sha512-Jj0Rfw3wIgp+eahMz/tOGwlcYYEFjlBPKU7NqoOkTX0LY45i5W0WcDpgiDWSLrN8KFQq/LW7fZq46gxGCiOYlQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.4.2': + resolution: {integrity: sha512-PHLYOC9W2cu6I/JEKo77+LW4uPNvyEQiSkVRUQPsOIsf01PRr8PtPhwtz3XNnC9At8CrzPkzqQ9/kYDg4R4Inw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.4.1': + resolution: {integrity: sha512-9WlEZfnw1vFqkWsTMzZDgNL7AUI1aiBHi0S2m8jvycPyCq/fbZjtE/nDkhJRYbSjXbtRHYLDBlmP95kpjEmJbw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.4.2': + resolution: {integrity: sha512-lpmUF9FfLFns4JbTu+5aJGA8aR9dXaA12eoNe9CJbVkGib0FDiPa4kBGTwy0xDxKNGlv3bLDViyx1U+qafmuJQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.4.1': + resolution: {integrity: sha512-WodRbZ9g6CQLRZsG3gtrA9w7Qfa9BwDzhFVdlI6sV0OCPq9JrOrJSp9/ioLsezbV8w9RCJ8v55uzJuJ5RgWLZg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-arm64-msvc@15.4.2': + resolution: {integrity: sha512-aMjogoGnRepas0LQ/PBPsvvUzj+IoXw2IoDSEShEtrsu2toBiaxEWzOQuPZ8nie8+1iF7TA63S7rlp3YWAjNEg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.4.1': + resolution: {integrity: sha512-y+wTBxelk2xiNofmDOVU7O5WxTHcvOoL3srOM0kxTzKDjQ57kPU0tpnPJ/BWrRnsOwXEv0+3QSbGR7hY4n9LkQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.4.2': + resolution: {integrity: sha512-FxwauyexSFu78wEqR/+NB9MnqXVj6SxJKwcVs2CRjeSX/jBagDCgtR2W36PZUYm0WPgY1pQ3C1+nn7zSnwROuw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -621,6 +1118,14 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@orama/orama@3.1.14': + resolution: {integrity: sha512-Iq4RxYC7y0pA/hLgcUGpYYs5Vze4qNmJk0Qi1uIrg2bHGpm6A06nbjWcH9h4HQsddkDFFlanLj/zYBH3Sxdb4w==} + engines: {node: '>= 20.0.0'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -628,26 +1133,40 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} peerDependencies: '@types/react': '*' + '@types/react-dom': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true + '@types/react-dom': + optional: true - '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: '@types/react': '*' + '@types/react-dom': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true + '@types/react-dom': + optional: true - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -659,8 +1178,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-progress@1.1.7': - resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==} + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -672,8 +1191,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -681,118 +1200,464 @@ packages: '@types/react': optional: true - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} - engines: {node: '>=14.0.0'} + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - rollup: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-navigation-menu@1.2.14': + resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-progress@1.1.7': + resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.2.10': + resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': optional: true - '@rollup/rollup-android-arm-eabi@4.45.0': - resolution: {integrity: sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg==} + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.50.2': + resolution: {integrity: sha512-uLN8NAiFVIRKX9ZQha8wy6UUs06UNSZ32xj6giK/rmMXAgKahwExvK6SsmgU5/brh4w/nSgj8e0k3c1HBQpa0A==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.45.0': - resolution: {integrity: sha512-PSZ0SvMOjEAxwZeTx32eI/j5xSYtDCRxGu5k9zvzoY77xUNssZM+WV6HYBLROpY5CkXsbQjvz40fBb7WPwDqtQ==} + '@rollup/rollup-android-arm64@4.50.2': + resolution: {integrity: sha512-oEouqQk2/zxxj22PNcGSskya+3kV0ZKH+nQxuCCOGJ4oTXBdNTbv+f/E3c74cNLeMO1S5wVWacSws10TTSB77g==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.45.0': - resolution: {integrity: sha512-BA4yPIPssPB2aRAWzmqzQ3y2/KotkLyZukVB7j3psK/U3nVJdceo6qr9pLM2xN6iRP/wKfxEbOb1yrlZH6sYZg==} + '@rollup/rollup-darwin-arm64@4.50.2': + resolution: {integrity: sha512-OZuTVTpj3CDSIxmPgGH8en/XtirV5nfljHZ3wrNwvgkT5DQLhIKAeuFSiwtbMto6oVexV0k1F1zqURPKf5rI1Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.45.0': - resolution: {integrity: sha512-Pr2o0lvTwsiG4HCr43Zy9xXrHspyMvsvEw4FwKYqhli4FuLE5FjcZzuQ4cfPe0iUFCvSQG6lACI0xj74FDZKRA==} + '@rollup/rollup-darwin-x64@4.50.2': + resolution: {integrity: sha512-Wa/Wn8RFkIkr1vy1k1PB//VYhLnlnn5eaJkfTQKivirOvzu5uVd2It01ukeQstMursuz7S1bU+8WW+1UPXpa8A==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.45.0': - resolution: {integrity: sha512-lYE8LkE5h4a/+6VnnLiL14zWMPnx6wNbDG23GcYFpRW1V9hYWHAw9lBZ6ZUIrOaoK7NliF1sdwYGiVmziUF4vA==} + '@rollup/rollup-freebsd-arm64@4.50.2': + resolution: {integrity: sha512-QkzxvH3kYN9J1w7D1A+yIMdI1pPekD+pWx7G5rXgnIlQ1TVYVC6hLl7SOV9pi5q9uIDF9AuIGkuzcbF7+fAhow==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.45.0': - resolution: {integrity: sha512-PVQWZK9sbzpvqC9Q0GlehNNSVHR+4m7+wET+7FgSnKG3ci5nAMgGmr9mGBXzAuE5SvguCKJ6mHL6vq1JaJ/gvw==} + '@rollup/rollup-freebsd-x64@4.50.2': + resolution: {integrity: sha512-dkYXB0c2XAS3a3jmyDkX4Jk0m7gWLFzq1C3qUnJJ38AyxIF5G/dyS4N9B30nvFseCfgtCEdbYFhk0ChoCGxPog==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.45.0': - resolution: {integrity: sha512-hLrmRl53prCcD+YXTfNvXd776HTxNh8wPAMllusQ+amcQmtgo3V5i/nkhPN6FakW+QVLoUUr2AsbtIRPFU3xIA==} + '@rollup/rollup-linux-arm-gnueabihf@4.50.2': + resolution: {integrity: sha512-9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.45.0': - resolution: {integrity: sha512-XBKGSYcrkdiRRjl+8XvrUR3AosXU0NvF7VuqMsm7s5nRy+nt58ZMB19Jdp1RdqewLcaYnpk8zeVs/4MlLZEJxw==} + '@rollup/rollup-linux-arm-musleabihf@4.50.2': + resolution: {integrity: sha512-+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.45.0': - resolution: {integrity: sha512-fRvZZPUiBz7NztBE/2QnCS5AtqLVhXmUOPj9IHlfGEXkapgImf4W9+FSkL8cWqoAjozyUzqFmSc4zh2ooaeF6g==} + '@rollup/rollup-linux-arm64-gnu@4.50.2': + resolution: {integrity: sha512-df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.45.0': - resolution: {integrity: sha512-Btv2WRZOcUGi8XU80XwIvzTg4U6+l6D0V6sZTrZx214nrwxw5nAi8hysaXj/mctyClWgesyuxbeLylCBNauimg==} + '@rollup/rollup-linux-arm64-musl@4.50.2': + resolution: {integrity: sha512-iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.45.0': - resolution: {integrity: sha512-Li0emNnwtUZdLwHjQPBxn4VWztcrw/h7mgLyHiEI5Z0MhpeFGlzaiBHpSNVOMB/xucjXTTcO+dhv469Djr16KA==} + '@rollup/rollup-linux-loong64-gnu@4.50.2': + resolution: {integrity: sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.45.0': - resolution: {integrity: sha512-sB8+pfkYx2kvpDCfd63d5ScYT0Fz1LO6jIb2zLZvmK9ob2D8DeVqrmBDE0iDK8KlBVmsTNzrjr3G1xV4eUZhSw==} + '@rollup/rollup-linux-ppc64-gnu@4.50.2': + resolution: {integrity: sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.45.0': - resolution: {integrity: sha512-5GQ6PFhh7E6jQm70p1aW05G2cap5zMOvO0se5JMecHeAdj5ZhWEHbJ4hiKpfi1nnnEdTauDXxPgXae/mqjow9w==} + '@rollup/rollup-linux-riscv64-gnu@4.50.2': + resolution: {integrity: sha512-Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.45.0': - resolution: {integrity: sha512-N/euLsBd1rekWcuduakTo/dJw6U6sBP3eUq+RXM9RNfPuWTvG2w/WObDkIvJ2KChy6oxZmOSC08Ak2OJA0UiAA==} + '@rollup/rollup-linux-riscv64-musl@4.50.2': + resolution: {integrity: sha512-82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.45.0': - resolution: {integrity: sha512-2l9sA7d7QdikL0xQwNMO3xURBUNEWyHVHfAsHsUdq+E/pgLTUcCE+gih5PCdmyHmfTDeXUWVhqL0WZzg0nua3g==} + '@rollup/rollup-linux-s390x-gnu@4.50.2': + resolution: {integrity: sha512-4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.45.0': - resolution: {integrity: sha512-XZdD3fEEQcwG2KrJDdEQu7NrHonPxxaV0/w2HpvINBdcqebz1aL+0vM2WFJq4DeiAVT6F5SUQas65HY5JDqoPw==} + '@rollup/rollup-linux-x64-gnu@4.50.2': + resolution: {integrity: sha512-9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.45.0': - resolution: {integrity: sha512-7ayfgvtmmWgKWBkCGg5+xTQ0r5V1owVm67zTrsEY1008L5ro7mCyGYORomARt/OquB9KY7LpxVBZes+oSniAAQ==} + '@rollup/rollup-linux-x64-musl@4.50.2': + resolution: {integrity: sha512-HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xvw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.45.0': - resolution: {integrity: sha512-B+IJgcBnE2bm93jEW5kHisqvPITs4ddLOROAcOc/diBgrEiQJJ6Qcjby75rFSmH5eMGrqJryUgJDhrfj942apQ==} + '@rollup/rollup-openharmony-arm64@4.50.2': + resolution: {integrity: sha512-nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KYA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.50.2': + resolution: {integrity: sha512-eFUvvnTYEKeTyHEijQKz81bLrUQOXKZqECeiWH6tb8eXXbZk+CXSG2aFrig2BQ/pjiVRj36zysjgILkqarS2YA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.45.0': - resolution: {integrity: sha512-+CXwwG66g0/FpWOnP/v1HnrGVSOygK/osUbu3wPRy8ECXjoYKjRAyfxYpDQOfghC5qPJYLPH0oN4MCOjwgdMug==} + '@rollup/rollup-win32-ia32-msvc@4.50.2': + resolution: {integrity: sha512-cBaWmXqyfRhH8zmUxK3d3sAhEWLrtMjWBRwdMMHJIXSjvjLKvv49adxiEz+FJ8AP90apSDDBx2Tyd/WylV6ikA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.45.0': - resolution: {integrity: sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA==} + '@rollup/rollup-win32-x64-msvc@4.50.2': + resolution: {integrity: sha512-APwKy6YUhvZaEoHyM+9xqmTpviEI+9eL7LoCH+aLcvWYHJ663qG5zx7WzWZY+a9qkg5JtzcMyJ9z0WtQBMDmgA==} cpu: [x64] os: [win32] + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.12.0': + resolution: {integrity: sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==} + + '@shikijs/core@3.12.2': + resolution: {integrity: sha512-L1Safnhra3tX/oJK5kYHaWmLEBJi1irASwewzY3taX5ibyXyMkkSDZlq01qigjryOBwrXSdFgTiZ3ryzSNeu7Q==} + + '@shikijs/engine-javascript@3.12.2': + resolution: {integrity: sha512-Nm3/azSsaVS7hk6EwtHEnTythjQfwvrO5tKqMlaH9TwG1P+PNaR8M0EAKZ+GaH2DFwvcr4iSfTveyxMIvXEHMw==} + + '@shikijs/engine-oniguruma@3.12.2': + resolution: {integrity: sha512-hozwnFHsLvujK4/CPVHNo3Bcg2EsnG8krI/ZQ2FlBlCRpPZW4XAEQmEwqegJsypsTAN9ehu2tEYe30lYKSZW/w==} + + '@shikijs/langs@3.12.2': + resolution: {integrity: sha512-bVx5PfuZHDSHoBal+KzJZGheFuyH4qwwcwG/n+MsWno5cTlKmaNtTsGzJpHYQ8YPbB5BdEdKU1rga5/6JGY8ww==} + + '@shikijs/rehype@3.12.2': + resolution: {integrity: sha512-9wg+FKv0ByaQScTonpZdrDhADOoJP/yCWLAuiYYG6GehwNV5rGwnLvWKj33UmtLedKMSHzWUdB+Un6rfDFo/FA==} + + '@shikijs/themes@3.12.2': + resolution: {integrity: sha512-fTR3QAgnwYpfGczpIbzPjlRnxyONJOerguQv1iwpyQZ9QXX4qy/XFQqXlf17XTsorxnHoJGbH/LXBvwtqDsF5A==} + + '@shikijs/transformers@3.12.2': + resolution: {integrity: sha512-+z1aMq4N5RoNGY8i7qnTYmG2MBYzFmwkm/yOd6cjEI7OVzcldVvzQCfxU1YbIVgsyB0xHVc2jFe1JhgoXyUoSQ==} + + '@shikijs/types@3.12.2': + resolution: {integrity: sha512-K5UIBzxCyv0YoxN3LMrKB9zuhp1bV+LgewxuVwHdl4Gz5oePoUFrr9EfgJlGlDeXCU1b/yhdnXeuRvAnz8HN8Q==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@storybook/addon-actions@8.6.14': resolution: {integrity: sha512-mDQxylxGGCQSK7tJPkD144J8jWh9IU9ziJMHfB84PKpI/V5ZgqMDnpr2bssTrUaGDqU5e1/z8KcRF+Melhs9pQ==} peerDependencies: @@ -896,8 +1761,8 @@ packages: '@storybook/global@5.0.0': resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} - '@storybook/icons@1.4.0': - resolution: {integrity: sha512-Td73IeJxOyalzvjQL+JXx72jlIYHgs+REaHiREOqfpo3A2AYYG71AUbcv+lg7mEDIweKVCxsMQ0UKo634c8XeA==} + '@storybook/icons@1.6.0': + resolution: {integrity: sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==} engines: {node: '>=14.0.0'} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta @@ -953,15 +1818,181 @@ packages: typescript: optional: true - '@storybook/test@8.6.14': - resolution: {integrity: sha512-GkPNBbbZmz+XRdrhMtkxPotCLOQ1BaGNp/gFZYdGDk2KmUWBKmvc5JxxOhtoXM2703IzNFlQHSSNnhrDZYuLlw==} - peerDependencies: - storybook: ^8.6.14 + '@storybook/test@8.6.14': + resolution: {integrity: sha512-GkPNBbbZmz+XRdrhMtkxPotCLOQ1BaGNp/gFZYdGDk2KmUWBKmvc5JxxOhtoXM2703IzNFlQHSSNnhrDZYuLlw==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/theming@8.6.14': + resolution: {integrity: sha512-r4y+LsiB37V5hzpQo+BM10PaCsp7YlZ0YcZzQP1OCkPlYXmUAFy2VvDKaFRpD8IeNPKug2u4iFm/laDEbs03dg==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@swc/core-darwin-arm64@1.13.5': + resolution: {integrity: sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.13.5': + resolution: {integrity: sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.13.5': + resolution: {integrity: sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.13.5': + resolution: {integrity: sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.13.5': + resolution: {integrity: sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.13.5': + resolution: {integrity: sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.13.5': + resolution: {integrity: sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.13.5': + resolution: {integrity: sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.13.5': + resolution: {integrity: sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.13.5': + resolution: {integrity: sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.13.5': + resolution: {integrity: sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + + '@tailwindcss/node@4.1.13': + resolution: {integrity: sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==} + + '@tailwindcss/oxide-android-arm64@4.1.13': + resolution: {integrity: sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.13': + resolution: {integrity: sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.13': + resolution: {integrity: sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.13': + resolution: {integrity: sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': + resolution: {integrity: sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': + resolution: {integrity: sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': + resolution: {integrity: sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': + resolution: {integrity: sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@storybook/theming@8.6.14': - resolution: {integrity: sha512-r4y+LsiB37V5hzpQo+BM10PaCsp7YlZ0YcZzQP1OCkPlYXmUAFy2VvDKaFRpD8IeNPKug2u4iFm/laDEbs03dg==} - peerDependencies: - storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@tailwindcss/oxide-linux-x64-musl@4.1.13': + resolution: {integrity: sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.13': + resolution: {integrity: sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': + resolution: {integrity: sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': + resolution: {integrity: sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.13': + resolution: {integrity: sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==} + engines: {node: '>= 10'} + + '@tailwindcss/postcss@4.1.13': + resolution: {integrity: sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ==} '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} @@ -971,8 +2002,8 @@ packages: resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - '@testing-library/jest-dom@6.6.3': - resolution: {integrity: sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==} + '@testing-library/jest-dom@6.8.0': + resolution: {integrity: sha512-WgXcWzVM6idy5JaftTVC8Vs83NKRmGJz4Hqs4oyOuO2J4r/y79vvKZsb+CaGyCSEbUPI6OsewfPd0G1A0/TUZQ==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} '@testing-library/react@16.3.0': @@ -996,6 +2027,15 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1008,8 +2048,8 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.7': - resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} @@ -1020,9 +2060,15 @@ packages: '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/doctrine@0.0.9': resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -1032,6 +2078,9 @@ packages: '@types/express@4.17.23': resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/http-errors@2.0.5': resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} @@ -1047,28 +2096,46 @@ packages: '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdx@2.0.13': resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@20.19.15': + resolution: {integrity: sha512-W3bqcbLsRdFDVcmAM5l6oLlcl67vjevn8j1FPZ4nx+K5jNoWCh+FC/btxFoBPnvQlrHHDwfjp1kjIEDfwJ0Mog==} + '@types/node@24.0.13': resolution: {integrity: sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==} + '@types/prismjs@1.26.5': + resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} + '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-dom@19.1.6': - resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==} + '@types/react-dom@19.1.9': + resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.8': - resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} + '@types/react@19.1.13': + resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} '@types/resolve@1.20.6': resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} @@ -1082,6 +2149,12 @@ packages: '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} @@ -1091,6 +2164,168 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + '@typescript-eslint/eslint-plugin@8.44.0': + resolution: {integrity: sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.44.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.44.0': + resolution: {integrity: sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.44.0': + resolution: {integrity: sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.44.0': + resolution: {integrity: sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.44.0': + resolution: {integrity: sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.44.0': + resolution: {integrity: sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.44.0': + resolution: {integrity: sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.44.0': + resolution: {integrity: sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.44.0': + resolution: {integrity: sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.44.0': + resolution: {integrity: sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + '@vitejs/plugin-react-swc@3.11.0': + resolution: {integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==} + peerDependencies: + vite: ^4 || ^5 || ^6 || ^7 + '@vitest/expect@2.0.5': resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} @@ -1141,6 +2376,11 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} @@ -1150,12 +2390,15 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -1166,8 +2409,8 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} any-promise@1.3.0: @@ -1180,6 +2423,13 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -1187,17 +2437,60 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + autoprefixer@10.4.21: resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} engines: {node: ^10 || ^12 || >=14} @@ -1209,13 +2502,28 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axe-core@4.10.3: + resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + engines: {node: '>=4'} + axe-core@4.9.1: resolution: {integrity: sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==} engines: {node: '>=4'} + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + baseline-browser-mapping@2.8.4: + resolution: {integrity: sha512-L+YvJwGAgwJBV1p6ffpSTa2KRc69EeeYGYjRVWKs0GKrK+LON0GC0gV+rKSNtALEDvMDqkvCFq9r1r94/Gjwxw==} + hasBin: true + better-opn@3.0.2: resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} engines: {node: '>=12.0.0'} @@ -1232,6 +2540,9 @@ packages: resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} engines: {node: '>=18'} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} @@ -1242,8 +2553,8 @@ packages: browser-assert@1.2.1: resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} - browserslist@4.25.1: - resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} + browserslist@4.26.2: + resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1267,15 +2578,22 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001727: - resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + caniuse-lite@1.0.30001743: + resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - chai@5.2.1: - resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} chalk@3.0.0: @@ -1286,6 +2604,18 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -1294,6 +2624,14 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + chromatic@11.29.0: resolution: {integrity: sha512-yisBlntp9hHVj19lIQdpTlcYIXuU9H/DbFuu6tyWHmj6hWT2EtukCCcxYXL78XdQt1vm2GfIrtgtKpj/Rzmo4A==} hasBin: true @@ -1313,10 +2651,16 @@ packages: class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1324,10 +2668,26 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -1369,10 +2729,25 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -1381,8 +2756,16 @@ packages: supports-color: optional: true - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1393,10 +2776,16 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -1405,6 +2794,10 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -1417,6 +2810,16 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-libc@2.1.0: + resolution: {integrity: sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -1427,6 +2830,10 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -1447,8 +2854,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.182: - resolution: {integrity: sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==} + electron-to-chromium@1.5.218: + resolution: {integrity: sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1464,10 +2871,18 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} + engines: {node: '>=10.13.0'} + entities@6.0.1: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + engines: {node: '>= 0.4'} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -1476,6 +2891,10 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} @@ -1483,6 +2902,24 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -1493,27 +2930,173 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.6: - resolution: {integrity: sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==} - engines: {node: '>=18'} - hasBin: true + esbuild@0.25.9: + resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-config-next@15.4.2: + resolution: {integrity: sha512-rAeZyTWn1/36Y+S+KpJ/W+RAUmM6fpBWsON4Uci+5l9DIKrhkMK0rgAZQ45ktx+xFk5tyYwkTBGit/9jalsHrw==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.20: + resolution: {integrity: sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==} + peerDependencies: + eslint: '>=8.40' + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} + eslint@9.35.0: + resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.4.0: + resolution: {integrity: sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -1540,15 +3123,32 @@ packages: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1558,6 +3158,10 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1570,6 +3174,10 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} @@ -1597,9 +3205,71 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + fumadocs-core@15.6.4: + resolution: {integrity: sha512-lDm+65c8bs46nirL8o5m3rFsvkY4t6xLL7tCYZxqLseTD2DjgkT2H/RVFgMVNmu6yU36SWB4C6VhPJhLpbnoVw==} + peerDependencies: + '@oramacloud/client': 1.x.x || 2.x.x + '@types/react': '*' + algoliasearch: 5.x.x + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + peerDependenciesMeta: + '@oramacloud/client': + optional: true + '@types/react': + optional: true + algoliasearch: + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + + fumadocs-mdx@11.6.11: + resolution: {integrity: sha512-8KPOMU53ujQtNWvmmBpyGb9BRdFXZKS0m0O6udSlXCoLU/VZlQSJE0ntxX1e5JCDVsxPR63jleCVq1c/WXmEVw==} + hasBin: true + peerDependencies: + '@fumadocs/mdx-remote': ^1.2.0 + fumadocs-core: ^14.0.0 || ^15.0.0 + next: ^15.3.0 + vite: 6.x.x + peerDependenciesMeta: + '@fumadocs/mdx-remote': + optional: true + next: + optional: true + vite: + optional: true + + fumadocs-ui@15.6.4: + resolution: {integrity: sha512-0sm4dH+Yw/39gGVBknlQHpY2wClX+T//SJ2ftargFzUfKQnuaAr6wVuOYWB1+puRSHjgJEFWS08h3/s9wlC/Yw==} + peerDependencies: + '@types/react': '*' + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + tailwindcss: ^3.4.14 || ^4.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + next: + optional: true + tailwindcss: + optional: true + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1608,10 +3278,24 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1624,6 +3308,18 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -1631,6 +3327,13 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1638,6 +3341,10 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + has-symbols@1.1.0: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} @@ -1650,10 +3357,28 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + html-encoding-sniffer@4.0.0: resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} engines: {node: '>=18'} + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -1674,6 +3399,31 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.0: + resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} @@ -1681,18 +3431,53 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-arguments@1.2.0: resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} engines: {node: '>= 0.4'} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -1701,6 +3486,17 @@ packages: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -1710,6 +3506,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -1722,10 +3522,29 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -1733,17 +3552,52 @@ packages: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + is-typed-array@1.1.15: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -1779,11 +3633,19 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true + jiti@2.5.1: + resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} + hasBin: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - jsdoc-type-pratt-parser@4.1.0: - resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsdoc-type-pratt-parser@4.8.0: + resolution: {integrity: sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==} engines: {node: '>=12.0.0'} jsdom@26.1.0: @@ -1800,11 +3662,106 @@ packages: engines: {node: '>=6'} hasBin: true + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -1822,12 +3779,23 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - loupe@3.1.4: - resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.1: + resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -1839,16 +3807,71 @@ packages: resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} engines: {node: '>=12'} - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} map-or-similar@1.5.0: resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -1871,6 +3894,111 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1900,6 +4028,9 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -1911,6 +4042,15 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -1929,12 +4069,72 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + napi-postinstall@0.3.3: + resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + next@15.4.1: + resolution: {integrity: sha512-eNKB1q8C7o9zXF8+jgJs2CzSLIU3T6bQtX6DcTnCq1sIR1CJ0GlSyRs1BubQi3/JgCnr9Vr+rS5mOMI38FFyQw==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + next@15.4.2: + resolution: {integrity: sha512-oH1rmFso+84NIkocfuxaGKcXIjMUTmnzV2x0m8qsYtB4gD6iflLMESXt5XJ8cFgWMBei4v88rNr/j+peNg72XA==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + node-releases@2.0.21: + resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -1944,8 +4144,12 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} - nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + npm-to-yarn@3.0.1: + resolution: {integrity: sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + nwsapi@2.2.22: + resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -1959,14 +4163,52 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.3: + resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -1978,6 +4220,13 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} @@ -2017,8 +4266,8 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} pify@2.3.0: @@ -2043,8 +4292,8 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 @@ -2071,13 +4320,25 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + engines: {node: '>=4'} + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -2086,10 +4347,21 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + prism-react-renderer@2.4.1: + resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} + peerDependencies: + react: '>=16.0.0' + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -2117,9 +4389,9 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} + raw-body@3.0.1: + resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} + engines: {node: '>= 0.10'} react-docgen-typescript@2.4.0: resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} @@ -2135,12 +4407,58 @@ packages: peerDependencies: react: ^19.1.0 + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-live@4.1.8: + resolution: {integrity: sha512-B2SgNqwPuS2ekqj4lcxi5TibEcjWkdVyYykBEUBshPAPDQ527x2zPEZg560n8egNtAjUpwXFQm7pcXV65aAYmg==} + engines: {node: '>= 0.12.0', npm: '>= 2.0.0'} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + react-medium-image-zoom@5.3.0: + resolution: {integrity: sha512-RCIzVlsKqy3BYgGgYbolUfuvx0aSKC7YhX/IJGEp+WJxsqdIVYJHkBdj++FAj6VD7RiWj6VVmdCfa/9vJE9hZg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.1: + resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + react@19.1.0: resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} engines: {node: '>=0.10.0'} @@ -2152,25 +4470,92 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.10: resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} hasBin: true + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.45.0: - resolution: {integrity: sha512-WLjEcJRIo7i3WDDgOIJqVI2d+lAC3EwvOGy+Xfq6hs+GQuAA4Di/H72xmXkOhrIWFg2PFYSKZYfH0f4vfKXN4A==} + rollup@4.50.2: + resolution: {integrity: sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2180,9 +4565,17 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + safe-regex-test@1.1.0: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} @@ -2197,6 +4590,9 @@ packages: scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2218,9 +4614,21 @@ packages: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.34.3: + resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2229,6 +4637,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@3.12.2: + resolution: {integrity: sha512-uIrKI+f9IPz1zDT+GMz+0RjzKJiijVr6WDWm9Pe3NNY6QigKCfifCEv9v9R2mDASKKjzjQ2QpFLcxaR3iHSnMA==} + side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -2252,8 +4663,11 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} slash@3.0.0: @@ -2268,6 +4682,16 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -2282,6 +4706,10 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + storybook@8.6.14: resolution: {integrity: sha512-sVKbCj/OTx67jhmauhxc2dcr1P+yOgz/x3h0krwjyMgdc5Oubvxyg4NYDZmzAw+ym36g/lzH8N0Ccp4dwtdfxw==} hasBin: true @@ -2299,12 +4727,38 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -2315,10 +4769,33 @@ packages: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} - strip-indent@4.0.0: - resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + strip-indent@4.1.0: + resolution: {integrity: sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w==} engines: {node: '>=12'} + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + style-to-js@1.1.17: + resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==} + + style-to-object@1.0.9: + resolution: {integrity: sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -2338,6 +4815,9 @@ packages: tailwind-merge@2.6.0: resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} + tailwindcss-animate@1.0.7: resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} peerDependencies: @@ -2348,6 +4828,17 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + tailwindcss@4.1.13: + resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} + + tapable@2.2.3: + resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==} + engines: {node: '>=6'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -2364,8 +4855,11 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} tinypool@1.1.1: @@ -2407,6 +4901,18 @@ packages: resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} engines: {node: '>=18'} + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-dedent@2.2.0: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} @@ -2414,6 +4920,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tsconfig-paths@4.2.0: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} @@ -2421,6 +4930,44 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + turbo-darwin-64@2.5.6: + resolution: {integrity: sha512-3C1xEdo4aFwMJAPvtlPqz1Sw/+cddWIOmsalHFMrsqqydcptwBfu26WW2cDm3u93bUzMbBJ8k3zNKFqxJ9ei2A==} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@2.5.6: + resolution: {integrity: sha512-LyiG+rD7JhMfYwLqB6k3LZQtYn8CQQUePbpA8mF/hMLPAekXdJo1g0bUPw8RZLwQXUIU/3BU7tXENvhSGz5DPA==} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@2.5.6: + resolution: {integrity: sha512-GOcUTT0xiT/pSnHL4YD6Yr3HreUhU8pUcGqcI2ksIF9b2/r/kRHwGFcsHgpG3+vtZF/kwsP0MV8FTlTObxsYIA==} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@2.5.6: + resolution: {integrity: sha512-10Tm15bruJEA3m0V7iZcnQBpObGBcOgUcO+sY7/2vk1bweW34LMhkWi8svjV9iDF68+KJDThnYDlYE/bc7/zzQ==} + cpu: [arm64] + os: [linux] + + turbo-windows-64@2.5.6: + resolution: {integrity: sha512-FyRsVpgaj76It0ludwZsNN40ytHN+17E4PFJyeliBEbxrGTc5BexlXVpufB7XlAaoaZVxbS6KT8RofLfDRyEPg==} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@2.5.6: + resolution: {integrity: sha512-j/tWu8cMeQ7HPpKri6jvKtyXg9K1gRyhdK4tKrrchH8GNHscPX/F71zax58yYtLRWTiK04zNzPcUJuoS0+v/+Q==} + cpu: [arm64] + os: [win32] + + turbo@2.5.6: + resolution: {integrity: sha512-gxToHmi9oTBNB05UjUsrWf0OyN5ZXtD0apOarC1KIx232Vp3WimRNy3810QzeNSgyD5rsaIDXlxlbnOzlouo+w==} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -2429,14 +4976,65 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.44.0: + resolution: {integrity: sha512-ib7mCkYuIzYonCq9XWF5XNw+fkj2zg629PSa9KNIQ47RXFF763S5BIX4wqz1+FLPogTZoiw8KmCiRPRa8bL3qw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + typescript@5.8.3: resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.8.0: resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -2445,12 +5043,43 @@ packages: resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-editable@2.3.3: + resolution: {integrity: sha512-7wVD2JbfAFJ3DK0vITvXBdpd9JAz5BcKAAolsnLBuBn6UDDwBGuCIAGvR3yA2BNKm578vAMVHFCWaOcA+BhhiA==} + peerDependencies: + react: '>= 16.8.0' + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -2473,13 +5102,19 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@2.1.9: resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.19: - resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} + vite@5.4.20: + resolution: {integrity: sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -2509,8 +5144,8 @@ packages: terser: optional: true - vite@6.3.5: - resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + vite@6.3.6: + resolution: {integrity: sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -2549,6 +5184,46 @@ packages: yaml: optional: true + vite@7.1.5: + resolution: {integrity: sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + 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 + vitest@2.1.9: resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} engines: {node: ^18.0.0 || >=20.0.0} @@ -2597,6 +5272,18 @@ packages: resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + which-typed-array@1.1.19: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} @@ -2611,6 +5298,10 @@ packages: engines: {node: '>=8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2641,8 +5332,12 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.8.0: - resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} engines: {node: '>= 14.6'} hasBin: true @@ -2650,9 +5345,15 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zod@4.1.8: + resolution: {integrity: sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: - '@a2a-js/sdk@0.2.4': + '@a2a-js/sdk@0.2.5': dependencies: '@types/cors': 2.8.19 '@types/express': 4.17.23 @@ -2663,19 +5364,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@adobe/css-tools@4.4.3': {} + '@adobe/css-tools@4.4.4': {} '@alloc/quick-lru@5.2.0': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 - '@asamuzakjp/css-color@3.2.0': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 lru-cache: 10.4.3 @@ -2686,41 +5382,41 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.0': {} + '@babel/compat-data@7.28.4': {} - '@babel/core@7.28.0': + '@babel/core@7.28.4': dependencies: - '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 + '@babel/generator': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) - '@babel/helpers': 7.27.6 - '@babel/parser': 7.28.0 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.1 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.28.0': + '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.1 - '@jridgewell/gen-mapping': 0.3.12 - '@jridgewell/trace-mapping': 0.3.29 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.28.0 + '@babel/compat-data': 7.28.4 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.1 + browserslist: 4.26.2 lru-cache: 5.1.1 semver: 6.3.1 @@ -2728,17 +5424,17 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.1 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.0 + '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -2748,50 +5444,50 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.27.6': + '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.1 + '@babel/types': 7.28.4 - '@babel/parser@7.28.0': + '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.1 + '@babel/types': 7.28.4 - '@babel/runtime@7.27.6': {} + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.0 - '@babel/types': 7.28.1 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 - '@babel/traverse@7.28.0': + '@babel/traverse@7.28.4': dependencies: '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 + '@babel/generator': 7.28.3 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.0 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/types': 7.28.1 - debug: 4.4.1 + '@babel/types': 7.28.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.1': + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@csstools/color-helpers@5.0.2': {} + '@csstools/color-helpers@5.1.0': {} '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-color-parser@3.0.10(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': dependencies: - '@csstools/color-helpers': 5.0.2 + '@csstools/color-helpers': 5.1.0 '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) '@csstools/css-tokenizer': 3.0.4 @@ -2802,333 +5498,996 @@ snapshots: '@csstools/css-tokenizer@3.0.4': {} + '@emnapi/core@1.5.0': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.5.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/aix-ppc64@0.25.6': + '@esbuild/aix-ppc64@0.25.9': optional: true '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm64@0.25.6': + '@esbuild/android-arm64@0.25.9': optional: true '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-arm@0.25.6': + '@esbuild/android-arm@0.25.9': optional: true '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/android-x64@0.25.6': + '@esbuild/android-x64@0.25.9': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.25.6': + '@esbuild/darwin-arm64@0.25.9': optional: true '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/darwin-x64@0.25.6': + '@esbuild/darwin-x64@0.25.9': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.25.6': + '@esbuild/freebsd-arm64@0.25.9': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.25.6': + '@esbuild/freebsd-x64@0.25.9': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.25.9': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.25.9': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.25.9': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.25.9': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.25.9': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.25.9': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.25.9': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.25.9': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.25.9': + optional: true + + '@esbuild/netbsd-arm64@0.25.9': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.25.9': + optional: true + + '@esbuild/openbsd-arm64@0.25.9': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.25.9': + optional: true + + '@esbuild/openharmony-arm64@0.25.9': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.25.9': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.25.9': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.25.9': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.25.9': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0(jiti@2.5.1))': + dependencies: + eslint: 9.35.0(jiti@2.5.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.21.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.3.1': {} + + '@eslint/core@0.15.2': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.35.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.3.5': + dependencies: + '@eslint/core': 0.15.2 + levn: 0.4.1 + + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/react-dom@2.1.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/dom': 1.7.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + '@floating-ui/utils@0.2.10': {} + + '@formatjs/intl-localematcher@0.6.1': + dependencies: + tslib: 2.8.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@img/sharp-darwin-arm64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.0 + optional: true + + '@img/sharp-darwin-x64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.0 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.0': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.0': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.0': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.0': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.0': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.0': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.0': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.0': + optional: true + + '@img/sharp-linux-arm64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.0 + optional: true + + '@img/sharp-linux-arm@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.0 + optional: true + + '@img/sharp-linux-ppc64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.0 + optional: true + + '@img/sharp-linux-s390x@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.0 + optional: true + + '@img/sharp-linux-x64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.0 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 + optional: true + + '@img/sharp-wasm32@0.34.3': + dependencies: + '@emnapi/runtime': 1.5.0 + optional: true + + '@img/sharp-win32-arm64@0.34.3': + optional: true + + '@img/sharp-win32-ia32@0.34.3': + optional: true + + '@img/sharp-win32-x64@0.34.3': optional: true - '@esbuild/linux-arm64@0.21.5': + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.0.13 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.8.3)(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1))': + dependencies: + glob: 10.4.5 + magic-string: 0.27.0 + react-docgen-typescript: 2.4.0(typescript@5.8.3) + vite: 6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1) + optionalDependencies: + typescript: 5.8.3 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.1.13)(react@19.1.0)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.1.13 + react: 19.1.0 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.1 optional: true - '@esbuild/linux-arm64@0.25.6': - optional: true + '@next/env@15.4.1': {} - '@esbuild/linux-arm@0.21.5': - optional: true + '@next/env@15.4.2': {} - '@esbuild/linux-arm@0.25.6': - optional: true + '@next/eslint-plugin-next@15.4.2': + dependencies: + fast-glob: 3.3.1 - '@esbuild/linux-ia32@0.21.5': + '@next/swc-darwin-arm64@15.4.1': optional: true - '@esbuild/linux-ia32@0.25.6': + '@next/swc-darwin-arm64@15.4.2': optional: true - '@esbuild/linux-loong64@0.21.5': + '@next/swc-darwin-x64@15.4.1': optional: true - '@esbuild/linux-loong64@0.25.6': + '@next/swc-darwin-x64@15.4.2': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@next/swc-linux-arm64-gnu@15.4.1': optional: true - '@esbuild/linux-mips64el@0.25.6': + '@next/swc-linux-arm64-gnu@15.4.2': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@next/swc-linux-arm64-musl@15.4.1': optional: true - '@esbuild/linux-ppc64@0.25.6': + '@next/swc-linux-arm64-musl@15.4.2': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@next/swc-linux-x64-gnu@15.4.1': optional: true - '@esbuild/linux-riscv64@0.25.6': + '@next/swc-linux-x64-gnu@15.4.2': optional: true - '@esbuild/linux-s390x@0.21.5': + '@next/swc-linux-x64-musl@15.4.1': optional: true - '@esbuild/linux-s390x@0.25.6': + '@next/swc-linux-x64-musl@15.4.2': optional: true - '@esbuild/linux-x64@0.21.5': + '@next/swc-win32-arm64-msvc@15.4.1': optional: true - '@esbuild/linux-x64@0.25.6': + '@next/swc-win32-arm64-msvc@15.4.2': optional: true - '@esbuild/netbsd-arm64@0.25.6': + '@next/swc-win32-x64-msvc@15.4.1': optional: true - '@esbuild/netbsd-x64@0.21.5': + '@next/swc-win32-x64-msvc@15.4.2': optional: true - '@esbuild/netbsd-x64@0.25.6': - optional: true + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 - '@esbuild/openbsd-arm64@0.25.6': - optional: true + '@nodelib/fs.stat@2.0.5': {} - '@esbuild/openbsd-x64@0.21.5': - optional: true + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 - '@esbuild/openbsd-x64@0.25.6': - optional: true + '@nolyfill/is-core-module@1.0.39': {} - '@esbuild/openharmony-arm64@0.25.6': - optional: true + '@orama/orama@3.1.14': {} - '@esbuild/sunos-x64@0.21.5': + '@pkgjs/parseargs@0.11.0': optional: true - '@esbuild/sunos-x64@0.25.6': - optional: true + '@polka/url@1.0.0-next.29': {} - '@esbuild/win32-arm64@0.21.5': - optional: true + '@radix-ui/number@1.1.1': {} - '@esbuild/win32-arm64@0.25.6': - optional: true + '@radix-ui/primitive@1.1.3': {} - '@esbuild/win32-ia32@0.21.5': - optional: true + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@esbuild/win32-ia32@0.25.6': - optional: true + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@esbuild/win32-x64@0.21.5': - optional: true + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@esbuild/win32-x64@0.25.6': - optional: true + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.13)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 - '@isaacs/cliui@8.0.2': + '@radix-ui/react-context@1.1.2(@types/react@19.1.13)(react@19.1.0)': dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.0) + aria-hidden: 1.2.6 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@jest/expect-utils@29.7.0': + '@radix-ui/react-direction@1.1.1(@types/react@19.1.13)(react@19.1.0)': dependencies: - jest-get-type: 29.6.3 + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 - '@jest/schemas@29.6.3': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@sinclair/typebox': 0.27.8 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@jest/types@29.6.3': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.13)(react@19.1.0)': dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 24.0.13 - '@types/yargs': 17.0.33 - chalk: 4.1.2 + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 - '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0))': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - glob: 10.4.5 - magic-string: 0.27.0 - react-docgen-typescript: 2.4.0(typescript@5.8.3) - vite: 6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) optionalDependencies: - typescript: 5.8.3 + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@jridgewell/gen-mapping@0.3.12': + '@radix-ui/react-id@1.1.1(@types/react@19.1.13)(react@19.1.0)': dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.29 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 + + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.0) + aria-hidden: 1.2.6 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/rect': 1.1.1 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@jridgewell/resolve-uri@3.1.2': {} + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@jridgewell/sourcemap-codec@1.5.4': {} + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@jridgewell/trace-mapping@0.3.29': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@mdx-js/react@3.1.0(@types/react@19.1.8)(react@19.1.0)': + '@radix-ui/react-progress@1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@types/mdx': 2.0.13 - '@types/react': 19.1.8 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.0) react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@nodelib/fs.scandir@2.1.5': + '@radix-ui/react-slot@1.2.3(@types/react@19.1.13)(react@19.1.0)': dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 + + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) - '@nodelib/fs.stat@2.0.5': {} + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.13)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 - '@nodelib/fs.walk@1.2.8': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.13)(react@19.1.0)': dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 - '@pkgjs/parseargs@0.11.0': - optional: true + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.13)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 - '@polka/url@1.0.0-next.29': {} + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.13)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.13)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.13 - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.8)(react@19.1.0)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.13)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.8 + '@types/react': 19.1.13 - '@radix-ui/react-context@1.1.2(@types/react@19.1.8)(react@19.1.0)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.13)(react@19.1.0)': dependencies: react: 19.1.0 optionalDependencies: - '@types/react': 19.1.8 + '@types/react': 19.1.13 - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.13)(react@19.1.0)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/rect': 1.1.1 react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.8 - '@types/react-dom': 19.1.6(@types/react@19.1.8) + '@types/react': 19.1.13 - '@radix-ui/react-progress@1.1.7(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.13)(react@19.1.0)': dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@19.1.8)(react@19.1.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.13)(react@19.1.0) react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.8 - '@types/react-dom': 19.1.6(@types/react@19.1.8) + '@types/react': 19.1.13 - '@radix-ui/react-slot@1.2.3(@types/react@19.1.8)(react@19.1.0)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.8 + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) + + '@radix-ui/rect@1.1.1': {} + + '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/pluginutils@5.2.0(rollup@4.45.0)': + '@rollup/pluginutils@5.3.0(rollup@4.50.2)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.2 + picomatch: 4.0.3 optionalDependencies: - rollup: 4.45.0 + rollup: 4.50.2 - '@rollup/rollup-android-arm-eabi@4.45.0': + '@rollup/rollup-android-arm-eabi@4.50.2': optional: true - '@rollup/rollup-android-arm64@4.45.0': + '@rollup/rollup-android-arm64@4.50.2': optional: true - '@rollup/rollup-darwin-arm64@4.45.0': + '@rollup/rollup-darwin-arm64@4.50.2': optional: true - '@rollup/rollup-darwin-x64@4.45.0': + '@rollup/rollup-darwin-x64@4.50.2': optional: true - '@rollup/rollup-freebsd-arm64@4.45.0': + '@rollup/rollup-freebsd-arm64@4.50.2': optional: true - '@rollup/rollup-freebsd-x64@4.45.0': + '@rollup/rollup-freebsd-x64@4.50.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.45.0': + '@rollup/rollup-linux-arm-gnueabihf@4.50.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.45.0': + '@rollup/rollup-linux-arm-musleabihf@4.50.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.45.0': + '@rollup/rollup-linux-arm64-gnu@4.50.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.45.0': + '@rollup/rollup-linux-arm64-musl@4.50.2': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.45.0': + '@rollup/rollup-linux-loong64-gnu@4.50.2': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.45.0': + '@rollup/rollup-linux-ppc64-gnu@4.50.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.45.0': + '@rollup/rollup-linux-riscv64-gnu@4.50.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.45.0': + '@rollup/rollup-linux-riscv64-musl@4.50.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.45.0': + '@rollup/rollup-linux-s390x-gnu@4.50.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.45.0': + '@rollup/rollup-linux-x64-gnu@4.50.2': optional: true - '@rollup/rollup-linux-x64-musl@4.45.0': + '@rollup/rollup-linux-x64-musl@4.50.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.45.0': + '@rollup/rollup-openharmony-arm64@4.50.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.45.0': + '@rollup/rollup-win32-arm64-msvc@4.50.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.45.0': + '@rollup/rollup-win32-ia32-msvc@4.50.2': optional: true + '@rollup/rollup-win32-x64-msvc@4.50.2': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@rushstack/eslint-patch@1.12.0': {} + + '@shikijs/core@3.12.2': + dependencies: + '@shikijs/types': 3.12.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.12.2': + dependencies: + '@shikijs/types': 3.12.2 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.3 + + '@shikijs/engine-oniguruma@3.12.2': + dependencies: + '@shikijs/types': 3.12.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.12.2': + dependencies: + '@shikijs/types': 3.12.2 + + '@shikijs/rehype@3.12.2': + dependencies: + '@shikijs/types': 3.12.2 + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.1 + shiki: 3.12.2 + unified: 11.0.5 + unist-util-visit: 5.0.0 + + '@shikijs/themes@3.12.2': + dependencies: + '@shikijs/types': 3.12.2 + + '@shikijs/transformers@3.12.2': + dependencies: + '@shikijs/core': 3.12.2 + '@shikijs/types': 3.12.2 + + '@shikijs/types@3.12.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + '@sinclair/typebox@0.27.8': {} + '@standard-schema/spec@1.0.0': {} + '@storybook/addon-actions@8.6.14(storybook@8.6.14)': dependencies: '@storybook/global': 5.0.0 @@ -3152,9 +6511,9 @@ snapshots: storybook: 8.6.14 ts-dedent: 2.2.0 - '@storybook/addon-docs@8.6.14(@types/react@19.1.8)(storybook@8.6.14)': + '@storybook/addon-docs@8.6.14(@types/react@19.1.13)(storybook@8.6.14)': dependencies: - '@mdx-js/react': 3.1.0(@types/react@19.1.8)(react@19.1.0) + '@mdx-js/react': 3.1.1(@types/react@19.1.13)(react@19.1.0) '@storybook/blocks': 8.6.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.14) '@storybook/csf-plugin': 8.6.14(storybook@8.6.14) '@storybook/react-dom-shim': 8.6.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.14) @@ -3165,12 +6524,12 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@storybook/addon-essentials@8.6.14(@types/react@19.1.8)(storybook@8.6.14)': + '@storybook/addon-essentials@8.6.14(@types/react@19.1.13)(storybook@8.6.14)': dependencies: '@storybook/addon-actions': 8.6.14(storybook@8.6.14) '@storybook/addon-backgrounds': 8.6.14(storybook@8.6.14) '@storybook/addon-controls': 8.6.14(storybook@8.6.14) - '@storybook/addon-docs': 8.6.14(@types/react@19.1.8)(storybook@8.6.14) + '@storybook/addon-docs': 8.6.14(@types/react@19.1.13)(storybook@8.6.14) '@storybook/addon-highlight': 8.6.14(storybook@8.6.14) '@storybook/addon-measure': 8.6.14(storybook@8.6.14) '@storybook/addon-outline': 8.6.14(storybook@8.6.14) @@ -3226,20 +6585,20 @@ snapshots: '@storybook/blocks@8.6.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.14)': dependencies: - '@storybook/icons': 1.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@storybook/icons': 1.6.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) storybook: 8.6.14 ts-dedent: 2.2.0 optionalDependencies: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - '@storybook/builder-vite@8.6.14(storybook@8.6.14)(vite@6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0))': + '@storybook/builder-vite@8.6.14(storybook@8.6.14)(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1))': dependencies: '@storybook/csf-plugin': 8.6.14(storybook@8.6.14) browser-assert: 1.2.1 storybook: 8.6.14 ts-dedent: 2.2.0 - vite: 6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0) + vite: 6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1) '@storybook/components@8.6.14(storybook@8.6.14)': dependencies: @@ -3250,9 +6609,9 @@ snapshots: '@storybook/theming': 8.6.14(storybook@8.6.14) better-opn: 3.0.2 browser-assert: 1.2.1 - esbuild: 0.25.6 - esbuild-register: 3.6.0(esbuild@0.25.6) - jsdoc-type-pratt-parser: 4.1.0 + esbuild: 0.25.9 + esbuild-register: 3.6.0(esbuild@0.25.9) + jsdoc-type-pratt-parser: 4.8.0 process: 0.11.10 recast: 0.23.11 semver: 7.7.2 @@ -3271,7 +6630,7 @@ snapshots: '@storybook/global@5.0.0': {} - '@storybook/icons@1.4.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@storybook/icons@1.6.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) @@ -3296,21 +6655,21 @@ snapshots: react-dom: 19.1.0(react@19.1.0) storybook: 8.6.14 - '@storybook/react-vite@8.6.14(@storybook/test@8.6.14(storybook@8.6.14))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.45.0)(storybook@8.6.14)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0))': + '@storybook/react-vite@8.6.14(@storybook/test@8.6.14(storybook@8.6.14))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.50.2)(storybook@8.6.14)(typescript@5.8.3)(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0)) - '@rollup/pluginutils': 5.2.0(rollup@4.45.0) - '@storybook/builder-vite': 8.6.14(storybook@8.6.14)(vite@6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0)) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.8.3)(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1)) + '@rollup/pluginutils': 5.3.0(rollup@4.50.2) + '@storybook/builder-vite': 8.6.14(storybook@8.6.14)(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1)) '@storybook/react': 8.6.14(@storybook/test@8.6.14(storybook@8.6.14))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@8.6.14)(typescript@5.8.3) find-up: 5.0.0 - magic-string: 0.30.17 + magic-string: 0.30.19 react: 19.1.0 react-docgen: 7.1.1 react-dom: 19.1.0(react@19.1.0) resolve: 1.22.10 storybook: 8.6.14 tsconfig-paths: 4.2.0 - vite: 6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0) + vite: 6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1) optionalDependencies: '@storybook/test': 8.6.14(storybook@8.6.14) transitivePeerDependencies: @@ -3348,10 +6707,138 @@ snapshots: dependencies: storybook: 8.6.14 + '@swc/core-darwin-arm64@1.13.5': + optional: true + + '@swc/core-darwin-x64@1.13.5': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.13.5': + optional: true + + '@swc/core-linux-arm64-gnu@1.13.5': + optional: true + + '@swc/core-linux-arm64-musl@1.13.5': + optional: true + + '@swc/core-linux-x64-gnu@1.13.5': + optional: true + + '@swc/core-linux-x64-musl@1.13.5': + optional: true + + '@swc/core-win32-arm64-msvc@1.13.5': + optional: true + + '@swc/core-win32-ia32-msvc@1.13.5': + optional: true + + '@swc/core-win32-x64-msvc@1.13.5': + optional: true + + '@swc/core@1.13.5': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.25 + optionalDependencies: + '@swc/core-darwin-arm64': 1.13.5 + '@swc/core-darwin-x64': 1.13.5 + '@swc/core-linux-arm-gnueabihf': 1.13.5 + '@swc/core-linux-arm64-gnu': 1.13.5 + '@swc/core-linux-arm64-musl': 1.13.5 + '@swc/core-linux-x64-gnu': 1.13.5 + '@swc/core-linux-x64-musl': 1.13.5 + '@swc/core-win32-arm64-msvc': 1.13.5 + '@swc/core-win32-ia32-msvc': 1.13.5 + '@swc/core-win32-x64-msvc': 1.13.5 + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@swc/types@0.1.25': + dependencies: + '@swc/counter': 0.1.3 + + '@tailwindcss/node@4.1.13': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.3 + jiti: 2.5.1 + lightningcss: 1.30.1 + magic-string: 0.30.19 + source-map-js: 1.2.1 + tailwindcss: 4.1.13 + + '@tailwindcss/oxide-android-arm64@4.1.13': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.13': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.13': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.13': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.13': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': + optional: true + + '@tailwindcss/oxide@4.1.13': + dependencies: + detect-libc: 2.1.0 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-x64': 4.1.13 + '@tailwindcss/oxide-freebsd-x64': 4.1.13 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.13 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.13 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-x64-musl': 4.1.13 + '@tailwindcss/oxide-wasm32-wasi': 4.1.13 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.13 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.13 + + '@tailwindcss/postcss@4.1.13': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.13 + '@tailwindcss/oxide': 4.1.13 + postcss: 8.5.6 + tailwindcss: 4.1.13 + '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.27.1 - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.28.4 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -3361,7 +6848,7 @@ snapshots: '@testing-library/jest-dom@6.5.0': dependencies: - '@adobe/css-tools': 4.4.3 + '@adobe/css-tools': 4.4.4 aria-query: 5.3.2 chalk: 3.0.0 css.escape: 1.5.1 @@ -3369,52 +6856,60 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 - '@testing-library/jest-dom@6.6.3': + '@testing-library/jest-dom@6.8.0': dependencies: - '@adobe/css-tools': 4.4.3 + '@adobe/css-tools': 4.4.4 aria-query: 5.3.2 - chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 - lodash: 4.17.21 + picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@testing-library/react@16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.28.4 '@testing-library/dom': 10.4.0 react: 19.1.0 react-dom: 19.1.0(react@19.1.0) optionalDependencies: - '@types/react': 19.1.8 - '@types/react-dom': 19.1.6(@types/react@19.1.8) + '@types/react': 19.1.13 + '@types/react-dom': 19.1.9(@types/react@19.1.13) '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': dependencies: '@testing-library/dom': 10.4.0 + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.1 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.7 + '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.1 + '@babel/types': 7.28.4 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.1 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 - '@types/babel__traverse@7.20.7': + '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.1 + '@babel/types': 7.28.4 '@types/body-parser@1.19.6': dependencies: @@ -3429,8 +6924,16 @@ snapshots: dependencies: '@types/node': 24.0.13 + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + '@types/doctrine@0.0.9': {} + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + '@types/estree@1.0.8': {} '@types/express-serve-static-core@4.19.6': @@ -3447,6 +6950,10 @@ snapshots: '@types/qs': 6.14.0 '@types/serve-static': 1.15.8 + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/http-errors@2.0.5': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -3464,23 +6971,39 @@ snapshots: expect: 29.7.0 pretty-format: 29.7.0 + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/mdx@2.0.13': {} '@types/mime@1.3.5': {} + '@types/ms@2.1.0': {} + + '@types/node@20.19.15': + dependencies: + undici-types: 6.21.0 + '@types/node@24.0.13': dependencies: undici-types: 7.8.0 + '@types/prismjs@1.26.5': {} + '@types/qs@6.14.0': {} '@types/range-parser@1.2.7': {} - '@types/react-dom@19.1.6(@types/react@19.1.8)': + '@types/react-dom@19.1.9(@types/react@19.1.13)': dependencies: - '@types/react': 19.1.8 + '@types/react': 19.1.13 - '@types/react@19.1.8': + '@types/react@19.1.13': dependencies: csstype: 3.1.3 @@ -3499,6 +7022,10 @@ snapshots: '@types/stack-utils@2.0.3': {} + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + '@types/uuid@9.0.8': {} '@types/yargs-parser@21.0.3': {} @@ -3507,27 +7034,189 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 + '@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.44.0 + '@typescript-eslint/type-utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.44.0 + eslint: 9.35.0(jiti@2.5.1) + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.44.0 + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.44.0 + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.44.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.8.3) + '@typescript-eslint/types': 8.44.0 + debug: 4.4.3 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.44.0': + dependencies: + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/visitor-keys': 8.44.0 + + '@typescript-eslint/tsconfig-utils@8.44.0(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + + '@typescript-eslint/type-utils@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.44.0': {} + + '@typescript-eslint/typescript-estree@8.44.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/project-service': 8.44.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.8.3) + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/visitor-keys': 8.44.0 + debug: 4.4.3 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + '@typescript-eslint/scope-manager': 8.44.0 + '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.8.3) + eslint: 9.35.0(jiti@2.5.1) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.44.0': + dependencies: + '@typescript-eslint/types': 8.44.0 + eslint-visitor-keys: 4.2.1 + + '@ungap/structured-clone@1.3.0': {} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@vitejs/plugin-react-swc@3.11.0(vite@7.1.5(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.27 + '@swc/core': 1.13.5 + vite: 7.1.5(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1) + transitivePeerDependencies: + - '@swc/helpers' + '@vitest/expect@2.0.5': dependencies: '@vitest/spy': 2.0.5 '@vitest/utils': 2.0.5 - chai: 5.2.1 + chai: 5.3.3 tinyrainbow: 1.2.0 '@vitest/expect@2.1.9': dependencies: '@vitest/spy': 2.1.9 '@vitest/utils': 2.1.9 - chai: 5.2.1 + chai: 5.3.3 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.9(vite@5.4.19(@types/node@24.0.13))': + '@vitest/mocker@2.1.9(vite@5.4.20(@types/node@24.0.13)(lightningcss@1.30.1))': dependencies: '@vitest/spy': 2.1.9 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.19 optionalDependencies: - vite: 5.4.19(@types/node@24.0.13) + vite: 5.4.20(@types/node@24.0.13)(lightningcss@1.30.1) '@vitest/pretty-format@2.0.5': dependencies: @@ -3545,7 +7234,7 @@ snapshots: '@vitest/snapshot@2.1.9': dependencies: '@vitest/pretty-format': 2.1.9 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 1.1.2 '@vitest/spy@2.0.5': @@ -3562,22 +7251,22 @@ snapshots: fflate: 0.8.2 flatted: 3.3.3 pathe: 1.1.2 - sirv: 3.0.1 - tinyglobby: 0.2.14 + sirv: 3.0.2 + tinyglobby: 0.2.15 tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@24.0.13)(@vitest/ui@2.1.9)(jsdom@26.1.0) + vitest: 2.1.9(@types/node@24.0.13)(@vitest/ui@2.1.9)(jsdom@26.1.0)(lightningcss@1.30.1) '@vitest/utils@2.0.5': dependencies: '@vitest/pretty-format': 2.0.5 estree-walker: 3.0.3 - loupe: 3.1.4 + loupe: 3.2.1 tinyrainbow: 1.2.0 '@vitest/utils@2.1.9': dependencies: '@vitest/pretty-format': 2.1.9 - loupe: 3.1.4 + loupe: 3.2.1 tinyrainbow: 1.2.0 accepts@1.3.8: @@ -3585,13 +7274,24 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn@8.15.0: {} agent-base@7.1.4: {} + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + ansi-regex@5.0.1: {} - ansi-regex@6.1.0: {} + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: @@ -3599,7 +7299,7 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} any-promise@1.3.0: {} @@ -3610,24 +7310,103 @@ snapshots: arg@5.0.2: {} + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.3.0: dependencies: dequal: 2.0.3 aria-query@5.3.2: {} + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + array-flatten@1.1.1: {} + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + assertion-error@2.0.1: {} + ast-types-flow@0.0.8: {} + ast-types@0.16.1: dependencies: tslib: 2.8.1 + astring@1.9.0: {} + + async-function@1.0.0: {} + autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.25.1 - caniuse-lite: 1.0.30001727 + browserslist: 4.26.2 + caniuse-lite: 1.0.30001743 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -3638,10 +7417,18 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axe-core@4.10.3: {} + axe-core@4.9.1: {} + axobject-query@4.1.0: {} + + bail@2.0.2: {} + balanced-match@1.0.2: {} + baseline-browser-mapping@2.8.4: {} + better-opn@3.0.2: dependencies: open: 8.4.2 @@ -3669,16 +7456,21 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.1 + debug: 4.4.3 http-errors: 2.0.0 iconv-lite: 0.6.3 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.0 + raw-body: 3.0.1 type-is: 2.0.1 transitivePeerDependencies: - supports-color + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -3689,12 +7481,13 @@ snapshots: browser-assert@1.2.1: {} - browserslist@4.25.1: + browserslist@4.26.2: dependencies: - caniuse-lite: 1.0.30001727 - electron-to-chromium: 1.5.182 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.1) + baseline-browser-mapping: 2.8.4 + caniuse-lite: 1.0.30001743 + electron-to-chromium: 1.5.218 + node-releases: 2.0.21 + update-browserslist-db: 1.1.3(browserslist@4.26.2) bytes@3.1.2: {} @@ -3717,16 +7510,20 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + callsites@3.1.0: {} + camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001727: {} + caniuse-lite@1.0.30001743: {} + + ccount@2.0.1: {} - chai@5.2.1: + chai@5.3.3: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.4 + loupe: 3.2.1 pathval: 2.0.1 chalk@3.0.0: @@ -3739,6 +7536,14 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + check-error@2.1.1: {} chokidar@3.6.0: @@ -3753,6 +7558,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@3.0.0: {} + chromatic@11.29.0: {} ci-info@3.9.0: {} @@ -3761,16 +7572,38 @@ snapshots: dependencies: clsx: 2.1.1 + client-only@0.0.1: {} + clsx@2.1.1: {} + collapse-white-space@2.1.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + + comma-separated-tokens@2.0.3: {} + commander@4.1.1: {} + compute-scroll-into-view@3.1.1: {} + + concat-map@0.0.1: {} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -3805,23 +7638,53 @@ snapshots: csstype@3.1.3: {} + damerau-levenshtein@1.0.8: {} + data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + debug@2.6.9: dependencies: ms: 2.0.0 - debug@4.4.1: + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: dependencies: ms: 2.1.3 decimal.js@10.6.0: {} + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + deep-eql@5.0.2: {} + deep-is@0.1.4: {} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 @@ -3830,18 +7693,36 @@ snapshots: define-lazy-prop@2.0.0: {} + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + depd@2.0.0: {} dequal@2.0.3: {} destroy@1.2.0: {} + detect-libc@2.1.0: {} + + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + didyoumean@1.2.2: {} diff-sequences@29.6.3: {} dlv@1.1.3: {} + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + doctrine@3.0.0: dependencies: esutils: 2.0.3 @@ -3850,42 +7731,154 @@ snapshots: dom-accessibility-api@0.6.3: {} - dunder-proto@1.0.1: + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.218: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.18.3: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.3 + + entities@6.0.1: {} + + es-abstract@1.24.0: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.2.1: dependencies: - call-bind-apply-helpers: 1.0.2 + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 - eastasianwidth@0.2.0: {} - - ee-first@1.1.1: {} - - electron-to-chromium@1.5.182: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - encodeurl@1.0.2: {} + es-module-lexer@1.7.0: {} - encodeurl@2.0.0: {} + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 - entities@6.0.1: {} + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 - es-define-property@1.0.1: {} + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 - es-errors@1.3.0: {} + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 - es-module-lexer@1.7.0: {} + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 - es-object-atoms@1.1.1: + esast-util-from-js@2.0.1: dependencies: - es-errors: 1.3.0 + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 - esbuild-register@3.6.0(esbuild@0.25.6): + esbuild-register@3.6.0(esbuild@0.25.9): dependencies: - debug: 4.4.1 - esbuild: 0.25.6 + debug: 4.4.3 + esbuild: 0.25.9 transitivePeerDependencies: - supports-color @@ -3915,34 +7908,34 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - esbuild@0.25.6: + esbuild@0.25.9: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.6 - '@esbuild/android-arm': 0.25.6 - '@esbuild/android-arm64': 0.25.6 - '@esbuild/android-x64': 0.25.6 - '@esbuild/darwin-arm64': 0.25.6 - '@esbuild/darwin-x64': 0.25.6 - '@esbuild/freebsd-arm64': 0.25.6 - '@esbuild/freebsd-x64': 0.25.6 - '@esbuild/linux-arm': 0.25.6 - '@esbuild/linux-arm64': 0.25.6 - '@esbuild/linux-ia32': 0.25.6 - '@esbuild/linux-loong64': 0.25.6 - '@esbuild/linux-mips64el': 0.25.6 - '@esbuild/linux-ppc64': 0.25.6 - '@esbuild/linux-riscv64': 0.25.6 - '@esbuild/linux-s390x': 0.25.6 - '@esbuild/linux-x64': 0.25.6 - '@esbuild/netbsd-arm64': 0.25.6 - '@esbuild/netbsd-x64': 0.25.6 - '@esbuild/openbsd-arm64': 0.25.6 - '@esbuild/openbsd-x64': 0.25.6 - '@esbuild/openharmony-arm64': 0.25.6 - '@esbuild/sunos-x64': 0.25.6 - '@esbuild/win32-arm64': 0.25.6 - '@esbuild/win32-ia32': 0.25.6 - '@esbuild/win32-x64': 0.25.6 + '@esbuild/aix-ppc64': 0.25.9 + '@esbuild/android-arm': 0.25.9 + '@esbuild/android-arm64': 0.25.9 + '@esbuild/android-x64': 0.25.9 + '@esbuild/darwin-arm64': 0.25.9 + '@esbuild/darwin-x64': 0.25.9 + '@esbuild/freebsd-arm64': 0.25.9 + '@esbuild/freebsd-x64': 0.25.9 + '@esbuild/linux-arm': 0.25.9 + '@esbuild/linux-arm64': 0.25.9 + '@esbuild/linux-ia32': 0.25.9 + '@esbuild/linux-loong64': 0.25.9 + '@esbuild/linux-mips64el': 0.25.9 + '@esbuild/linux-ppc64': 0.25.9 + '@esbuild/linux-riscv64': 0.25.9 + '@esbuild/linux-s390x': 0.25.9 + '@esbuild/linux-x64': 0.25.9 + '@esbuild/netbsd-arm64': 0.25.9 + '@esbuild/netbsd-x64': 0.25.9 + '@esbuild/openbsd-arm64': 0.25.9 + '@esbuild/openbsd-x64': 0.25.9 + '@esbuild/openharmony-arm64': 0.25.9 + '@esbuild/sunos-x64': 0.25.9 + '@esbuild/win32-arm64': 0.25.9 + '@esbuild/win32-ia32': 0.25.9 + '@esbuild/win32-x64': 0.25.9 escalade@3.2.0: {} @@ -3950,8 +7943,244 @@ snapshots: escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-config-next@15.4.2(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3): + dependencies: + '@next/eslint-plugin-next': 15.4.2 + '@rushstack/eslint-patch': 1.12.0 + '@typescript-eslint/eslint-plugin': 8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + eslint: 9.35.0(jiti@2.5.1) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-react: 7.37.5(eslint@9.35.0(jiti@2.5.1)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.35.0(jiti@2.5.1)) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) + get-tsconfig: 4.10.1 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + eslint: 9.35.0(jiti@2.5.1) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.35.0(jiti@2.5.1) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.35.0(jiti@2.5.1)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.35.0(jiti@2.5.1)): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.35.0(jiti@2.5.1) + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-react-hooks@5.2.0(eslint@9.35.0(jiti@2.5.1)): + dependencies: + eslint: 9.35.0(jiti@2.5.1) + + eslint-plugin-react-refresh@0.4.20(eslint@9.35.0(jiti@2.5.1)): + dependencies: + eslint: 9.35.0(jiti@2.5.1) + + eslint-plugin-react@7.37.5(eslint@9.35.0(jiti@2.5.1)): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.35.0(jiti@2.5.1) + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.35.0(jiti@2.5.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.1 + '@eslint/core': 0.15.2 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.35.0 + '@eslint/plugin-kit': 0.3.5 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.5.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.4.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -4008,6 +8237,18 @@ snapshots: transitivePeerDependencies: - supports-color + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4016,16 +8257,24 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + fastq@1.19.1: dependencies: reusify: 1.1.0 - fdir@6.4.6(picomatch@4.0.2): + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: - picomatch: 4.0.2 + picomatch: 4.0.3 fflate@0.8.2: {} + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -4047,6 +8296,11 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + flatted@3.3.3: {} for-each@0.3.5: @@ -4067,8 +8321,99 @@ snapshots: fsevents@2.3.3: optional: true + fumadocs-core@15.6.4(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@formatjs/intl-localematcher': 0.6.1 + '@orama/orama': 3.1.14 + '@shikijs/rehype': 3.12.2 + '@shikijs/transformers': 3.12.2 + github-slugger: 2.0.0 + hast-util-to-estree: 3.1.3 + hast-util-to-jsx-runtime: 2.3.6 + image-size: 2.0.2 + negotiator: 1.0.0 + npm-to-yarn: 3.0.1 + react-remove-scroll: 2.7.1(@types/react@19.1.13)(react@19.1.0) + remark: 15.0.1 + remark-gfm: 4.0.1 + remark-rehype: 11.1.2 + scroll-into-view-if-needed: 3.1.0 + shiki: 3.12.2 + unist-util-visit: 5.0.0 + optionalDependencies: + '@types/react': 19.1.13 + next: 15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + transitivePeerDependencies: + - supports-color + + fumadocs-mdx@11.6.11(fumadocs-core@15.6.4(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1)): + dependencies: + '@mdx-js/mdx': 3.1.1 + '@standard-schema/spec': 1.0.0 + chokidar: 4.0.3 + esbuild: 0.25.9 + estree-util-value-to-estree: 3.4.0 + fumadocs-core: 15.6.4(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + js-yaml: 4.1.0 + lru-cache: 11.2.1 + picocolors: 1.1.1 + tinyexec: 1.0.1 + tinyglobby: 0.2.15 + unist-util-visit: 5.0.0 + zod: 4.1.8 + optionalDependencies: + next: 15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + vite: 6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1) + transitivePeerDependencies: + - supports-color + + fumadocs-ui@15.6.4(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.1.13): + dependencies: + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.13)(react@19.1.0) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + class-variance-authority: 0.7.1 + fumadocs-core: 15.6.4(@types/react@19.1.13)(next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + lodash.merge: 4.6.2 + next-themes: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + postcss-selector-parser: 7.1.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-medium-image-zoom: 5.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + scroll-into-view-if-needed: 3.1.0 + tailwind-merge: 3.3.1 + optionalDependencies: + '@types/react': 19.1.13 + next: 15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + tailwindcss: 4.1.13 + transitivePeerDependencies: + - '@oramacloud/client' + - '@types/react-dom' + - algoliasearch + - supports-color + function-bind@1.1.2: {} + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + gensync@1.0.0-beta.2: {} get-intrinsic@1.3.0: @@ -4084,11 +8429,25 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + github-slugger@2.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4106,16 +8465,33 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + globals@14.0.0: {} + + globals@16.4.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + gopd@1.2.0: {} graceful-fs@4.2.11: {} + graphemer@1.4.0: {} + + has-bigints@1.1.0: {} + has-flag@4.0.0: {} has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.1 + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + has-symbols@1.1.0: {} has-tostringtag@1.0.2: @@ -4126,10 +8502,75 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.17 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.17 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + html-encoding-sniffer@4.0.0: dependencies: whatwg-encoding: 3.1.1 + html-void-elements@3.0.0: {} + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -4141,39 +8582,101 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.6: + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.7.0: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + image-size@2.0.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inherits@2.0.4: {} + + inline-style-parser@0.2.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + ipaddr.js@1.9.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.3.4: + optional: true + + is-async-function@2.1.1: dependencies: - agent-base: 7.1.4 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 - iconv-lite@0.4.24: + is-bigint@1.1.0: dependencies: - safer-buffer: 2.1.2 + has-bigints: 1.1.0 - iconv-lite@0.6.3: + is-binary-path@2.1.0: dependencies: - safer-buffer: 2.1.2 - - indent-string@4.0.0: {} - - inherits@2.0.4: {} - - ipaddr.js@1.9.1: {} + binary-extensions: 2.3.0 - is-arguments@1.2.0: + is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-binary-path@2.1.0: + is-bun-module@2.0.0: dependencies: - binary-extensions: 2.3.0 + semver: 7.7.2 is-callable@1.2.7: {} @@ -4181,10 +8684,27 @@ snapshots: dependencies: hasown: 2.0.2 + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-decimal@2.0.1: {} + is-docker@2.2.1: {} is-extglob@2.1.1: {} + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + is-fullwidth-code-point@3.0.0: {} is-generator-function@1.1.0: @@ -4198,8 +8718,21 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-number@7.0.0: {} + is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} is-regex@1.2.1: @@ -4209,16 +8742,55 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + is-typed-array@1.1.15: dependencies: which-typed-array: 1.1.19 + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-wsl@2.2.0: dependencies: is-docker: 2.2.1 + isarray@2.0.5: {} + isexe@2.0.0: {} + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -4267,99 +8839,621 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 - jest-util@29.7.0: + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.0.13 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jiti@1.21.7: {} + + jiti@2.5.1: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsdoc-type-pratt-parser@4.8.0: {} + + jsdom@26.1.0: + dependencies: + cssstyle: 4.6.0 + data-urls: 5.0.0 + decimal.js: 10.6.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.22 + parse5: 7.3.0 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + ws: 8.18.3 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-darwin-arm64@1.30.1: + optional: true + + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: + dependencies: + detect-libc: 2.1.0 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@3.2.1: {} + + lru-cache@10.4.3: {} + + lru-cache@11.2.1: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lz-string@1.5.0: {} + + magic-string@0.27.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + map-or-similar@1.5.0: {} + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.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.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.0 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + media-typer@0.3.0: {} + + media-typer@1.1.0: {} + + memoizerific@1.11.3: + dependencies: + map-or-similar: 1.5.0 + + merge-descriptors@1.0.3: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: dependencies: - '@jest/types': 29.6.3 - '@types/node': 24.0.13 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - jiti@1.21.7: {} + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 - js-tokens@4.0.0: {} + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 - jsdoc-type-pratt-parser@4.1.0: {} + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 - jsdom@26.1.0: + micromark-extension-mdxjs@3.0.0: dependencies: - cssstyle: 4.6.0 - data-urls: 5.0.0 - decimal.js: 10.6.0 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 - parse5: 7.3.0 - rrweb-cssom: 0.8.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 5.1.2 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.2.0 - ws: 8.18.3 - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 - jsesc@3.1.0: {} + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - json5@2.2.3: {} + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lilconfig@3.1.3: {} + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 - lines-and-columns@1.2.4: {} + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 - locate-path@6.0.0: + micromark-factory-title@2.0.1: dependencies: - p-locate: 5.0.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lodash.merge@4.6.2: {} + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lodash@4.17.21: {} + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - loupe@3.1.4: {} + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 - lru-cache@10.4.3: {} + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - lru-cache@5.1.1: + micromark-util-combine-extensions@2.0.1: dependencies: - yallist: 3.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 - lz-string@1.5.0: {} + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 - magic-string@0.27.0: + micromark-util-decode-string@2.0.1: dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} - magic-string@0.30.17: + micromark-util-events-to-acorn@2.0.3: dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 - map-or-similar@1.5.0: {} + micromark-util-html-tag-name@2.0.1: {} - math-intrinsics@1.1.0: {} + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 - media-typer@0.3.0: {} + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 - media-typer@1.1.0: {} + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 - memoizerific@1.11.3: + micromark-util-subtokenize@2.1.0: dependencies: - map-or-similar: 1.5.0 + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 - merge-descriptors@1.0.3: {} + micromark-util-symbol@2.0.1: {} - merge2@1.4.1: {} + micromark-util-types@2.0.2: {} - methods@1.1.2: {} + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color micromatch@4.0.8: dependencies: @@ -4382,6 +9476,10 @@ snapshots: min-indent@1.0.1: {} + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 @@ -4390,6 +9488,12 @@ snapshots: minipass@7.1.2: {} + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mkdirp@3.0.1: {} + mrmime@2.0.1: {} ms@2.0.0: {} @@ -4404,15 +9508,74 @@ snapshots: nanoid@3.3.11: {} + napi-postinstall@0.3.3: {} + + natural-compare@1.4.0: {} + negotiator@0.6.3: {} - node-releases@2.0.19: {} + negotiator@1.0.0: {} + + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + next@15.4.1(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@next/env': 15.4.1 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001743 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.1.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.4.1 + '@next/swc-darwin-x64': 15.4.1 + '@next/swc-linux-arm64-gnu': 15.4.1 + '@next/swc-linux-arm64-musl': 15.4.1 + '@next/swc-linux-x64-gnu': 15.4.1 + '@next/swc-linux-x64-musl': 15.4.1 + '@next/swc-win32-arm64-msvc': 15.4.1 + '@next/swc-win32-x64-msvc': 15.4.1 + sharp: 0.34.3 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + next@15.4.2(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@next/env': 15.4.2 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001743 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.1.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.4.2 + '@next/swc-darwin-x64': 15.4.2 + '@next/swc-linux-arm64-gnu': 15.4.2 + '@next/swc-linux-arm64-musl': 15.4.2 + '@next/swc-linux-x64-gnu': 15.4.2 + '@next/swc-linux-x64-musl': 15.4.2 + '@next/swc-win32-arm64-msvc': 15.4.2 + '@next/swc-win32-x64-msvc': 15.4.2 + sharp: 0.34.3 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + node-releases@2.0.21: {} normalize-path@3.0.0: {} normalize-range@0.1.2: {} - nwsapi@2.2.20: {} + npm-to-yarn@3.0.1: {} + + nwsapi@2.2.22: {} object-assign@4.1.1: {} @@ -4420,16 +9583,77 @@ snapshots: object-inspect@1.13.4: {} + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + on-finished@2.4.1: dependencies: ee-first: 1.1.1 + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.3: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.0.1 + regex-recursion: 6.0.2 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 is-docker: 2.2.1 is-wsl: 2.2.0 + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -4440,6 +9664,20 @@ snapshots: package-json-from-dist@1.0.1: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse5@7.3.0: dependencies: entities: 6.0.1 @@ -4467,7 +9705,7 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.2: {} + picomatch@4.0.3: {} pify@2.3.0: {} @@ -4475,7 +9713,7 @@ snapshots: polished@4.3.1: dependencies: - '@babel/runtime': 7.27.6 + '@babel/runtime': 7.28.4 possible-typed-array-names@1.1.0: {} @@ -4486,7 +9724,7 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.10 - postcss-js@4.0.1(postcss@8.5.6): + postcss-js@4.1.0(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 postcss: 8.5.6 @@ -4494,7 +9732,7 @@ snapshots: postcss-load-config@4.0.2(postcss@8.5.6): dependencies: lilconfig: 3.1.3 - yaml: 2.8.0 + yaml: 2.8.1 optionalDependencies: postcss: 8.5.6 @@ -4508,14 +9746,27 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@7.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss-value-parser@4.2.0: {} + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + prelude-ls@1.2.1: {} + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -4528,8 +9779,22 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + prism-react-renderer@2.4.1(react@19.1.0): + dependencies: + '@types/prismjs': 1.26.5 + clsx: 2.1.1 + react: 19.1.0 + process@0.11.10: {} + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@7.1.0: {} + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -4556,63 +9821,228 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.0: + raw-body@3.0.1: dependencies: bytes: 3.1.2 http-errors: 2.0.0 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 unpipe: 1.0.0 - react-docgen-typescript@2.4.0(typescript@5.8.3): + react-docgen-typescript@2.4.0(typescript@5.8.3): + dependencies: + typescript: 5.8.3 + + react-docgen@7.1.1: + dependencies: + '@babel/core': 7.28.4 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.10 + strip-indent: 4.1.0 + transitivePeerDependencies: + - supports-color + + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + + react-is@16.13.1: {} + + react-is@17.0.2: {} + + react-is@18.3.1: {} + + react-live@4.1.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + prism-react-renderer: 2.4.1(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + sucrase: 3.35.0 + use-editable: 2.3.3(react@19.1.0) + + react-medium-image-zoom@5.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-remove-scroll-bar@2.3.8(@types/react@19.1.13)(react@19.1.0): + dependencies: + react: 19.1.0 + react-style-singleton: 2.2.3(@types/react@19.1.13)(react@19.1.0) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 + + react-remove-scroll@2.7.1(@types/react@19.1.13)(react@19.1.0): + dependencies: + react: 19.1.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.13)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.13)(react@19.1.0) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.13)(react@19.1.0) + use-sidecar: 1.1.3(@types/react@19.1.13)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.13 + + react-style-singleton@2.2.3(@types/react@19.1.13)(react@19.1.0): + dependencies: + get-nonce: 1.0.1 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 + + react@19.1.0: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.0.1: dependencies: - typescript: 5.8.3 + regex-utilities: 2.3.0 - react-docgen@7.1.1: + regexp.prototype.flags@1.5.4: dependencies: - '@babel/core': 7.28.0 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.1 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.7 - '@types/doctrine': 0.0.9 - '@types/resolve': 1.20.6 - doctrine: 3.0.0 - resolve: 1.22.10 - strip-indent: 4.0.0 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 transitivePeerDependencies: - supports-color - react-dom@19.1.0(react@19.1.0): + remark-gfm@4.0.1: dependencies: - react: 19.1.0 - scheduler: 0.26.0 - - react-is@17.0.2: {} - - react-is@18.3.1: {} + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color - react@19.1.0: {} + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color - read-cache@1.0.0: + remark-parse@11.0.0: dependencies: - pify: 2.3.0 + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color - readdirp@3.6.0: + remark-rehype@11.1.2: dependencies: - picomatch: 2.3.1 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 - recast@0.23.11: + remark-stringify@11.0.0: dependencies: - ast-types: 0.16.1 - esprima: 4.0.1 - source-map: 0.6.1 - tiny-invariant: 1.3.3 - tslib: 2.8.1 + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 - redent@3.0.0: + remark@15.0.1: dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 + '@types/mdast': 4.0.4 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} resolve@1.22.10: dependencies: @@ -4620,32 +10050,39 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + reusify@1.1.0: {} - rollup@4.45.0: + rollup@4.50.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.45.0 - '@rollup/rollup-android-arm64': 4.45.0 - '@rollup/rollup-darwin-arm64': 4.45.0 - '@rollup/rollup-darwin-x64': 4.45.0 - '@rollup/rollup-freebsd-arm64': 4.45.0 - '@rollup/rollup-freebsd-x64': 4.45.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.45.0 - '@rollup/rollup-linux-arm-musleabihf': 4.45.0 - '@rollup/rollup-linux-arm64-gnu': 4.45.0 - '@rollup/rollup-linux-arm64-musl': 4.45.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.45.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.45.0 - '@rollup/rollup-linux-riscv64-gnu': 4.45.0 - '@rollup/rollup-linux-riscv64-musl': 4.45.0 - '@rollup/rollup-linux-s390x-gnu': 4.45.0 - '@rollup/rollup-linux-x64-gnu': 4.45.0 - '@rollup/rollup-linux-x64-musl': 4.45.0 - '@rollup/rollup-win32-arm64-msvc': 4.45.0 - '@rollup/rollup-win32-ia32-msvc': 4.45.0 - '@rollup/rollup-win32-x64-msvc': 4.45.0 + '@rollup/rollup-android-arm-eabi': 4.50.2 + '@rollup/rollup-android-arm64': 4.50.2 + '@rollup/rollup-darwin-arm64': 4.50.2 + '@rollup/rollup-darwin-x64': 4.50.2 + '@rollup/rollup-freebsd-arm64': 4.50.2 + '@rollup/rollup-freebsd-x64': 4.50.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.50.2 + '@rollup/rollup-linux-arm-musleabihf': 4.50.2 + '@rollup/rollup-linux-arm64-gnu': 4.50.2 + '@rollup/rollup-linux-arm64-musl': 4.50.2 + '@rollup/rollup-linux-loong64-gnu': 4.50.2 + '@rollup/rollup-linux-ppc64-gnu': 4.50.2 + '@rollup/rollup-linux-riscv64-gnu': 4.50.2 + '@rollup/rollup-linux-riscv64-musl': 4.50.2 + '@rollup/rollup-linux-s390x-gnu': 4.50.2 + '@rollup/rollup-linux-x64-gnu': 4.50.2 + '@rollup/rollup-linux-x64-musl': 4.50.2 + '@rollup/rollup-openharmony-arm64': 4.50.2 + '@rollup/rollup-win32-arm64-msvc': 4.50.2 + '@rollup/rollup-win32-ia32-msvc': 4.50.2 + '@rollup/rollup-win32-x64-msvc': 4.50.2 fsevents: 2.3.3 rrweb-cssom@0.8.0: {} @@ -4654,8 +10091,21 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + safe-buffer@5.2.1: {} + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + safe-regex-test@1.1.0: dependencies: call-bound: 1.0.4 @@ -4670,6 +10120,10 @@ snapshots: scheduler@0.26.0: {} + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + semver@6.3.1: {} semver@7.7.2: {} @@ -4710,14 +10164,68 @@ snapshots: gopd: 1.2.0 has-property-descriptors: 1.0.2 + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + setprototypeof@1.2.0: {} + sharp@0.34.3: + dependencies: + color: 4.2.3 + detect-libc: 2.1.0 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.3 + '@img/sharp-darwin-x64': 0.34.3 + '@img/sharp-libvips-darwin-arm64': 1.2.0 + '@img/sharp-libvips-darwin-x64': 1.2.0 + '@img/sharp-libvips-linux-arm': 1.2.0 + '@img/sharp-libvips-linux-arm64': 1.2.0 + '@img/sharp-libvips-linux-ppc64': 1.2.0 + '@img/sharp-libvips-linux-s390x': 1.2.0 + '@img/sharp-libvips-linux-x64': 1.2.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 + '@img/sharp-libvips-linuxmusl-x64': 1.2.0 + '@img/sharp-linux-arm': 0.34.3 + '@img/sharp-linux-arm64': 0.34.3 + '@img/sharp-linux-ppc64': 0.34.3 + '@img/sharp-linux-s390x': 0.34.3 + '@img/sharp-linux-x64': 0.34.3 + '@img/sharp-linuxmusl-arm64': 0.34.3 + '@img/sharp-linuxmusl-x64': 0.34.3 + '@img/sharp-wasm32': 0.34.3 + '@img/sharp-win32-arm64': 0.34.3 + '@img/sharp-win32-ia32': 0.34.3 + '@img/sharp-win32-x64': 0.34.3 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + shiki@3.12.2: + dependencies: + '@shikijs/core': 3.12.2 + '@shikijs/engine-javascript': 3.12.2 + '@shikijs/engine-oniguruma': 3.12.2 + '@shikijs/langs': 3.12.2 + '@shikijs/themes': 3.12.2 + '@shikijs/types': 3.12.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -4750,7 +10258,12 @@ snapshots: signal-exit@4.1.0: {} - sirv@3.0.1: + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + optional: true + + sirv@3.0.2: dependencies: '@polka/url': 1.0.0-next.29 mrmime: 2.0.1 @@ -4762,6 +10275,12 @@ snapshots: source-map@0.6.1: {} + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + stable-hash@0.0.5: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -4772,6 +10291,11 @@ snapshots: std-env@3.9.0: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + storybook@8.6.14: dependencies: '@storybook/core': 8.6.14(storybook@8.6.14) @@ -4790,15 +10314,70 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.1.0 + ansi-regex: 6.2.2 strip-bom@3.0.0: {} @@ -4806,13 +10385,28 @@ snapshots: dependencies: min-indent: 1.0.1 - strip-indent@4.0.0: + strip-indent@4.1.0: {} + + strip-json-comments@3.1.1: {} + + style-to-js@1.1.17: dependencies: - min-indent: 1.0.1 + style-to-object: 1.0.9 + + style-to-object@1.0.9: + dependencies: + inline-style-parser: 0.2.4 + + styled-jsx@5.1.6(@babel/core@7.28.4)(react@19.1.0): + dependencies: + client-only: 0.0.1 + react: 19.1.0 + optionalDependencies: + '@babel/core': 7.28.4 sucrase@3.35.0: dependencies: - '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 glob: 10.4.5 lines-and-columns: 1.2.4 @@ -4830,6 +10424,8 @@ snapshots: tailwind-merge@2.6.0: {} + tailwind-merge@3.3.1: {} + tailwindcss-animate@1.0.7(tailwindcss@3.4.17): dependencies: tailwindcss: 3.4.17 @@ -4852,7 +10448,7 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) postcss-load-config: 4.0.2(postcss@8.5.6) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 @@ -4861,6 +10457,19 @@ snapshots: transitivePeerDependencies: - ts-node + tailwindcss@4.1.13: {} + + tapable@2.2.3: {} + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -4875,10 +10484,12 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.14: + tinyexec@1.0.1: {} + + tinyglobby@0.2.15: dependencies: - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 tinypool@1.1.1: {} @@ -4908,10 +10519,25 @@ snapshots: dependencies: punycode: 2.3.1 + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-api-utils@2.1.0(typescript@5.8.3): + dependencies: + typescript: 5.8.3 + ts-dedent@2.2.0: {} ts-interface-checker@0.1.13: {} + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + tsconfig-paths@4.2.0: dependencies: json5: 2.2.3 @@ -4920,6 +10546,37 @@ snapshots: tslib@2.8.1: {} + turbo-darwin-64@2.5.6: + optional: true + + turbo-darwin-arm64@2.5.6: + optional: true + + turbo-linux-64@2.5.6: + optional: true + + turbo-linux-arm64@2.5.6: + optional: true + + turbo-windows-64@2.5.6: + optional: true + + turbo-windows-arm64@2.5.6: + optional: true + + turbo@2.5.6: + optionalDependencies: + turbo-darwin-64: 2.5.6 + turbo-darwin-arm64: 2.5.6 + turbo-linux-64: 2.5.6 + turbo-linux-arm64: 2.5.6 + turbo-windows-64: 2.5.6 + turbo-windows-arm64: 2.5.6 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -4931,10 +10588,100 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.1 + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/parser': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.44.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.8.3) + eslint: 9.35.0(jiti@2.5.1) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + typescript@5.8.3: {} + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} + undici-types@7.8.0: {} + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + unpipe@1.0.0: {} unplugin@1.16.1: @@ -4942,12 +10689,59 @@ snapshots: acorn: 8.15.0 webpack-virtual-modules: 0.6.2 - update-browserslist-db@1.1.3(browserslist@4.25.1): + unrs-resolver@1.11.1: dependencies: - browserslist: 4.25.1 + napi-postinstall: 0.3.3 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + update-browserslist-db@1.1.3(browserslist@4.26.2): + dependencies: + browserslist: 4.26.2 escalade: 3.2.0 picocolors: 1.1.1 + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-callback-ref@1.3.3(@types/react@19.1.13)(react@19.1.0): + dependencies: + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 + + use-editable@2.3.3(react@19.1.0): + dependencies: + react: 19.1.0 + + use-sidecar@1.1.3(@types/react@19.1.13)(react@19.1.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.13 + util-deprecate@1.0.2: {} util@0.12.5: @@ -4966,13 +10760,23 @@ snapshots: vary@1.1.2: {} - vite-node@2.1.9(@types/node@24.0.13): + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite-node@2.1.9(@types/node@24.0.13)(lightningcss@1.30.1): dependencies: cac: 6.7.14 - debug: 4.4.1 + debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 1.1.2 - vite: 5.4.19(@types/node@24.0.13) + vite: 5.4.20(@types/node@24.0.13)(lightningcss@1.30.1) transitivePeerDependencies: - '@types/node' - less @@ -4984,50 +10788,67 @@ snapshots: - supports-color - terser - vite@5.4.19(@types/node@24.0.13): + vite@5.4.20(@types/node@24.0.13)(lightningcss@1.30.1): dependencies: esbuild: 0.21.5 postcss: 8.5.6 - rollup: 4.45.0 + rollup: 4.50.2 optionalDependencies: '@types/node': 24.0.13 fsevents: 2.3.3 + lightningcss: 1.30.1 - vite@6.3.5(@types/node@24.0.13)(jiti@1.21.7)(yaml@2.8.0): + vite@6.3.6(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1): dependencies: - esbuild: 0.25.6 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.45.0 - tinyglobby: 0.2.14 + rollup: 4.50.2 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.0.13 fsevents: 2.3.3 - jiti: 1.21.7 - yaml: 2.8.0 + jiti: 2.5.1 + lightningcss: 1.30.1 + yaml: 2.8.1 + + vite@7.1.5(@types/node@24.0.13)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1): + dependencies: + esbuild: 0.25.9 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.50.2 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.0.13 + fsevents: 2.3.3 + jiti: 2.5.1 + lightningcss: 1.30.1 + yaml: 2.8.1 - vitest@2.1.9(@types/node@24.0.13)(@vitest/ui@2.1.9)(jsdom@26.1.0): + vitest@2.1.9(@types/node@24.0.13)(@vitest/ui@2.1.9)(jsdom@26.1.0)(lightningcss@1.30.1): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.19(@types/node@24.0.13)) + '@vitest/mocker': 2.1.9(vite@5.4.20(@types/node@24.0.13)(lightningcss@1.30.1)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 '@vitest/spy': 2.1.9 '@vitest/utils': 2.1.9 - chai: 5.2.1 - debug: 4.4.1 + chai: 5.3.3 + debug: 4.4.3 expect-type: 1.2.2 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 1.1.2 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinypool: 1.1.1 tinyrainbow: 1.2.0 - vite: 5.4.19(@types/node@24.0.13) - vite-node: 2.1.9(@types/node@24.0.13) + vite: 5.4.20(@types/node@24.0.13)(lightningcss@1.30.1) + vite-node: 2.1.9(@types/node@24.0.13)(lightningcss@1.30.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.0.13 @@ -5063,6 +10884,37 @@ snapshots: tr46: 5.1.1 webidl-conversions: 7.0.0 + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 @@ -5082,6 +10934,8 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + word-wrap@1.2.5: {} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -5090,9 +10944,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 ws@8.18.3: {} @@ -5102,6 +10956,12 @@ snapshots: yallist@3.1.1: {} - yaml@2.8.0: {} + yallist@5.0.0: {} + + yaml@2.8.1: {} yocto-queue@0.1.0: {} + + zod@4.1.8: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4340350..fa0f9ee 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - - 'packages/*' \ No newline at end of file + - 'packages/*' + - 'apps/*' \ No newline at end of file diff --git a/scripts/proper_a2a_agent.py b/scripts/proper_a2a_agent.py new file mode 100644 index 0000000..42e49b9 --- /dev/null +++ b/scripts/proper_a2a_agent.py @@ -0,0 +1,319 @@ +#!/usr/bin/env python3 +""" +Proper A2A Agent implementation using Google's official a2a-sdk +Based on the HelloWorld example from a2a-samples +""" + +import asyncio +from typing import Optional, AsyncIterator +from starlette.applications import Starlette +from starlette.middleware.cors import CORSMiddleware +from starlette.responses import JSONResponse +from starlette.routing import Route +from starlette.requests import Request +import uvicorn +import argparse +import json +from a2a.server.agent_execution import AgentExecutor +from a2a.server.apps import A2AStarletteApplication +from a2a.types import AgentCard, AgentSkill, AgentCapabilities +from a2a.server.request_handlers import DefaultRequestHandler +from a2a.server.events.event_queue import EventQueue +from a2a.server.tasks import InMemoryTaskStore +from a2a.server.agent_execution.context import RequestContext +from a2a.utils import new_agent_text_message + + +class SimpleAgent: + """Simple agent that processes messages and returns responses""" + + async def process_message(self, message: str) -> str: + """Process a message and return a response""" + return f"Processed: {message}" + +class SimpleAgentExecutor(AgentExecutor): + """Agent executor that handles A2A protocol requests""" + + def __init__(self): + self.agent = SimpleAgent() + + async def execute(self, context: RequestContext, event_queue: EventQueue): + """Execute the agent logic and send streaming response with A2A protocol events""" + # Get the message from the request context + message = "Hello World from A2A Agent!" + if hasattr(context, 'request') and context.request and hasattr(context.request, 'message'): + if hasattr(context.request.message, 'content'): + message = context.request.message.content + elif hasattr(context.request.message, 'parts') and context.request.message.parts: + # Extract text from parts + text_parts = [] + for part in context.request.message.parts: + if hasattr(part, 'text') and part.text: + text_parts.append(part.text) + if text_parts: + message = ' '.join(text_parts) + + # Send task status update - started + await event_queue.enqueue_event({ + "type": "task-status-update", + "data": { + "taskId": context.request_id, + "status": { + "state": "running", + "progress": 0.1, + "message": "Task started - analyzing request" + } + } + }) + + # Send initial processing message + await event_queue.enqueue_event(new_agent_text_message(f"🤖 Processing your request: {message}")) + await asyncio.sleep(0.8) + + # Send progress update + await event_queue.enqueue_event({ + "type": "task-status-update", + "data": { + "taskId": context.request_id, + "status": { + "state": "running", + "progress": 0.3, + "message": "Gathering information..." + } + } + }) + + # Simulate streaming response with multiple chunks and different event types + streaming_responses = [ + {"type": "message", "content": "🔍 I'm analyzing your request and gathering relevant context..."}, + {"type": "progress", "progress": 0.5, "message": "Processing data..."}, + {"type": "message", "content": "📊 Found relevant information. Generating response..."}, + {"type": "progress", "progress": 0.7, "message": "Crafting response..."}, + {"type": "message", "content": f"✨ **Response to '{message}':**\n\nThis is a comprehensive answer that demonstrates the A2A protocol streaming capabilities. The agent can:\n\n• Process complex requests\n• Provide real-time updates\n• Stream responses progressively\n• Handle various message types"}, + {"type": "artifact", "content": "📄 Generated artifact: analysis_report.md"}, + {"type": "progress", "progress": 0.9, "message": "Finalizing response..."}, + {"type": "message", "content": "✅ Task completed successfully! The agent has processed your request and provided a detailed response with streaming updates."} + ] + + for i, response in enumerate(streaming_responses): + await asyncio.sleep(0.6) # Simulate processing time + + if response["type"] == "message": + await event_queue.enqueue_event(new_agent_text_message(response["content"])) + elif response["type"] == "progress": + await event_queue.enqueue_event({ + "type": "task-status-update", + "data": { + "taskId": context.request_id, + "status": { + "state": "running", + "progress": response["progress"], + "message": response["message"] + } + } + }) + elif response["type"] == "artifact": + await event_queue.enqueue_event({ + "type": "artifact-update", + "data": { + "taskId": context.request_id, + "artifact": { + "id": f"artifact_{i}", + "name": "analysis_report.md", + "type": "text/markdown", + "content": f"# Analysis Report\n\nRequest: {message}\n\nThis is a mock artifact generated by the A2A agent to demonstrate artifact streaming capabilities.", + "metadata": { + "created_at": "2024-01-01T12:00:00Z", + "size": 156 + } + } + } + }) + + # Send final task completion status + await event_queue.enqueue_event({ + "type": "task-status-update", + "data": { + "taskId": context.request_id, + "status": { + "state": "completed", + "progress": 1.0, + "message": "Task completed successfully" + } + } + }) + + async def cancel(self, context: RequestContext, event_queue: EventQueue): + """Handle task cancellation""" + await event_queue.enqueue_event(new_agent_text_message("Task cancelled")) + + +def create_agent_card(port: int) -> AgentCard: + """Create the agent card that describes this agent's capabilities""" + + # Define the agent's skill + skill = AgentSkill( + id="simple_chat", + name="Simple Chat", + description="A simple chat agent that can respond to messages and provide basic assistance", + tags=["chat", "assistant", "simple"], + examples=[ + "Hello, how are you?", + "Can you help me?", + "What time is it?" + ] + ) + + # Create the agent card + agent_card = AgentCard( + name="Simple A2A Agent", + description="A simple agent that demonstrates A2A protocol implementation with streaming support", + url=f"http://localhost:{port}/", + version="1.0.0", + defaultInputModes=["text"], + defaultOutputModes=["text"], + capabilities=AgentCapabilities( + streaming=True, + pushNotifications=False + ), + skills=[skill] + ) + + return agent_card + + +def create_extended_agent_card(port: int) -> AgentCard: + """Create the extended agent card (for authenticated requests).""" + base_card = create_agent_card(port) + # Add additional skills for authenticated users + extended_skills = base_card.skills + [ + AgentSkill( + id="advanced_help", + name="Advanced Help", + description="Get detailed help and advanced features (authenticated users only)", + examples=["Advanced help", "Show all features"] + ) + ] + + return AgentCard( + name=base_card.name + " (Extended)", + description=base_card.description + " with extended features for authenticated users", + url=f"http://localhost:{port}/", + version="1.0.0", + defaultInputModes=["text"], + defaultOutputModes=["text"], + capabilities=AgentCapabilities( + streaming=True, + pushNotifications=False + ), + skills=extended_skills + ) + + +def main(): + """Main function to run the A2A agent server""" + parser = argparse.ArgumentParser(description='Run A2A Agent Server') + parser.add_argument('--port', type=int, default=5055, help='Port to run the server on') + parser.add_argument('--host', type=str, default='localhost', help='Host to run the server on') + args = parser.parse_args() + + # Create agent card + agent_card = create_agent_card(args.port) + + # Create agent executor + agent_executor = SimpleAgentExecutor() + + # Create task store + task_store = InMemoryTaskStore() + + # Create request handler + request_handler = DefaultRequestHandler( + agent_executor=agent_executor, + task_store=task_store + ) + + # Create REST endpoint handlers for frontend compatibility + async def handle_message_send(request: Request): + """Handle REST-style message.send requests""" + try: + body = await request.json() + + # Convert REST request to JSON-RPC format + jsonrpc_request = { + "jsonrpc": "2.0", + "id": f"rest-{asyncio.get_event_loop().time()}", + "method": "message/send", + "params": body + } + + # Process through the A2A request handler + context = RequestContext() + + # For REST compatibility, return a simple success response + # The actual A2A protocol will handle streaming through the proper endpoints + return JSONResponse({ + "jsonrpc": "2.0", + "id": jsonrpc_request["id"], + "result": { + "id": jsonrpc_request["id"], + "status": {"state": "accepted"}, + "message": "Task accepted and will be processed via A2A protocol" + } + }) + + except Exception as e: + return JSONResponse( + { + "jsonrpc": "2.0", + "id": "error", + "error": { + "code": -32603, + "message": f"Internal error: {str(e)}" + } + }, + status_code=500 + ) + + # Create A2A Starlette application + a2a_app = A2AStarletteApplication( + agent_card=agent_card, + http_handler=request_handler + ) + + app = a2a_app.build() + + # Add REST endpoints for frontend compatibility + from starlette.routing import Mount + rest_routes = [ + Route("/message.send", handle_message_send, methods=["POST"]), + Route("/task.get", handle_message_send, methods=["POST"]), # Reuse for now + Route("/task.cancel", handle_message_send, methods=["POST"]) # Reuse for now + ] + + # Mount REST endpoints under /a2a/ + app.mount("/a2a", Starlette(routes=rest_routes)) + + # Add CORS middleware + app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + + print(f"Starting A2A Agent Server on {args.host}:{args.port}") + print(f"Agent Card available at: http://{args.host}:{args.port}/.well-known/agent.json") + print(f"A2A Protocol endpoint: http://{args.host}:{args.port}/a2a") + + # Run the server + uvicorn.run( + app, + host=args.host, + port=args.port, + log_level="info" + ) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/stories/Accessibility.stories.tsx b/stories/Accessibility.stories.tsx deleted file mode 100644 index d65d058..0000000 --- a/stories/Accessibility.stories.tsx +++ /dev/null @@ -1,672 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import { Artifact, Input, Block, Task, Chat } from '@agentarea/react' -import type { EnhancedArtifact, TaskInputRequest, ProtocolMessage, EnhancedTask } from '@agentarea/core' -import { useState, useRef, useEffect } from 'react' - -const meta: Meta = { - title: 'Accessibility/Testing Scenarios', - parameters: { - layout: 'centered', - docs: { - description: { - component: 'Accessibility testing scenarios for all components with keyboard navigation, screen reader support, and WCAG compliance', - }, - }, - }, - tags: ['autodocs'], -} - -export default meta -type Story = StoryObj - -// Mock data for accessibility testing -const mockAccessibleArtifact: EnhancedArtifact = { - id: 'accessible-artifact-1', - taskId: 'task-1', - displayType: 'code', - content: { - code: { - language: 'javascript', - content: `// Accessible button component example -function AccessibleButton({ children, onClick, disabled = false, ariaLabel }) { - return ( - - ) -}` - } - }, - mimeType: 'text/javascript', - size: 256, - createdAt: new Date(), - downloadable: true, - shareable: true, - metadata: { - name: 'Accessible Button Component', - language: 'javascript' - } -} - -const mockAccessibleInputRequest: TaskInputRequest = { - id: 'accessible-input-1', - taskId: 'task-1', - type: 'form', - prompt: 'User Registration Form (Accessibility Test)', - required: true, - metadata: { - fields: [ - { - name: 'firstName', - type: 'text', - label: 'First Name', - placeholder: 'Enter your first name', - validation: [ - { type: 'required', message: 'First name is required for account creation' } - ] - }, - { - name: 'email', - type: 'email', - label: 'Email Address', - placeholder: 'Enter your email address', - validation: [ - { type: 'required', message: 'Email address is required' }, - { type: 'pattern', value: '^[^@]+@[^@]+\\.[^@]+$', message: 'Please enter a valid email address' } - ] - }, - { - name: 'password', - type: 'password', - label: 'Password', - placeholder: 'Create a secure password', - validation: [ - { type: 'required', message: 'Password is required' }, - { type: 'minLength', value: 8, message: 'Password must be at least 8 characters long' } - ] - }, - { - name: 'newsletter', - type: 'checkbox', - label: 'Subscribe to our newsletter for updates and tips' - } - ] - } -} - -// Keyboard Navigation Testing -export const KeyboardNavigation: Story = { - render: () => { - const [focusedElement, setFocusedElement] = useState('') - - const handleFocus = (elementName: string) => { - setFocusedElement(elementName) - } - - return ( -
-
-

Keyboard Navigation Test

-

- Use Tab to navigate forward, Shift+Tab to navigate backward. - Currently focused: {focusedElement || 'None'} -

-
-

• Tab through all interactive elements

-

• Enter/Space to activate buttons and checkboxes

-

• Arrow keys for radio buttons and select options

-

• Escape to close modals and dropdowns

-
-
- - {/* Artifact with keyboard navigation */} -
handleFocus('Artifact Container')} - tabIndex={0} - > - handleFocus('Download Button')} - onShare={() => handleFocus('Share Button')} - /> -
- - {/* Input form with keyboard navigation */} -
handleFocus('Input Form')}> - handleFocus('Submit Button')} - onCancel={() => handleFocus('Cancel Button')} - /> -
- - {/* Navigation instructions */} -
-

Keyboard Navigation Instructions:

-
    -
  • Use Tab key to move between interactive elements
  • -
  • Use Shift+Tab to move backward
  • -
  • Use Enter or Space to activate buttons
  • -
  • Use arrow keys within form controls
  • -
  • Focus indicators should be clearly visible
  • -
-
-
- ) - }, -} - -// Screen Reader Testing -export const ScreenReaderSupport: Story = { - render: () => { - const [announcements, setAnnouncements] = useState([]) - - const addAnnouncement = (message: string) => { - setAnnouncements(prev => [...prev, `${new Date().toLocaleTimeString()}: ${message}`]) - } - - return ( -
-
-

Screen Reader Support Test

-

- This section tests ARIA labels, descriptions, and live regions for screen reader compatibility. -

-
-

• All interactive elements have proper ARIA labels

-

• Form fields have associated labels and error messages

-

• Status updates are announced via live regions

-

• Complex widgets have appropriate ARIA roles

-
-
- - {/* Live region for announcements */} -
- {announcements[announcements.length - 1]} -
- - {/* Artifact with ARIA labels */} -
-

- Code Artifact: Accessible Button Component -

- addAnnouncement('Downloading accessible button component code')} - onShare={() => addAnnouncement('Sharing accessible button component code')} - aria-describedby="artifact-description" - /> -

- JavaScript code example showing how to create an accessible button component with proper ARIA attributes. -

-
- - {/* Form with comprehensive ARIA support */} -
-

- Accessible Registration Form -

- addAnnouncement('Form submitted successfully')} - onCancel={() => addAnnouncement('Form submission cancelled')} - aria-describedby="form-description" - /> -

- Registration form with proper labels, error messages, and validation feedback. -

-
- - {/* Announcements log */} -
-

Screen Reader Announcements Log:

-
- {announcements.length === 0 ? ( -

No announcements yet. Interact with elements above.

- ) : ( - announcements.map((announcement, index) => ( -
- {announcement} -
- )) - )} -
-
-
- ) - }, -} - -// High Contrast and Color Testing -export const HighContrastMode: Story = { - render: () => { - const [highContrast, setHighContrast] = useState(false) - - return ( -
-
-

High Contrast & Color Accessibility

-

- Testing color contrast ratios and ensuring information is not conveyed by color alone. -

- -
- - {/* Color-blind friendly status indicators */} -
-

Status Indicators (Color + Icon)

-
- - -
-
- - {/* Form validation with multiple indicators */} -
-

Form Validation (Multiple Indicators)

- -
- - {/* Contrast testing guide */} -
-

Accessibility Guidelines:

-
    -
  • Text contrast ratio should be at least 4.5:1 for normal text
  • -
  • Text contrast ratio should be at least 3:1 for large text
  • -
  • Interactive elements should have 3:1 contrast with adjacent colors
  • -
  • Information should not be conveyed by color alone
  • -
  • Focus indicators should be clearly visible in all modes
  • -
-
- - -
- ) - }, -} - -// Focus Management Testing -export const FocusManagement: Story = { - render: () => { - const [modalOpen, setModalOpen] = useState(false) - const [focusHistory, setFocusHistory] = useState([]) - const triggerRef = useRef(null) - const modalRef = useRef(null) - - const addFocusEvent = (element: string) => { - setFocusHistory(prev => [...prev.slice(-4), `${new Date().toLocaleTimeString()}: Focus moved to ${element}`]) - } - - const openModal = () => { - setModalOpen(true) - addFocusEvent('Modal dialog') - // Focus should move to modal - setTimeout(() => { - modalRef.current?.focus() - }, 100) - } - - const closeModal = () => { - setModalOpen(false) - addFocusEvent('Modal trigger button (restored)') - // Focus should return to trigger - setTimeout(() => { - triggerRef.current?.focus() - }, 100) - } - - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Escape' && modalOpen) { - closeModal() - } - } - - document.addEventListener('keydown', handleKeyDown) - return () => document.removeEventListener('keydown', handleKeyDown) - }, [modalOpen]) - - return ( -
-
-

Focus Management Test

-

- Testing proper focus management for modals, dropdowns, and dynamic content. -

-
-

• Focus should be trapped within modals

-

• Focus should return to trigger element when modal closes

-

• Tab order should be logical and predictable

-

• Skip links should be available for long content

-
-
- - {/* Focus history */} -
-

Focus Movement History:

-
- {focusHistory.length === 0 ? ( -

No focus events yet.

- ) : ( - focusHistory.map((event, index) => ( -
- {event} -
- )) - )} -
-
- - {/* Modal trigger */} -
- - - {/* Other focusable elements */} -
- - - addFocusEvent('Text input')} - className="px-2 py-1 border rounded focus:outline-none focus:ring-2 focus:ring-blue-300" - /> -
-
- - {/* Modal overlay */} - {modalOpen && ( -
-
addFocusEvent('Modal container')} - > - - - -
- addFocusEvent('Modal input field')} - className="w-full px-3 py-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-300" - /> - -
- - -
-
-
-
- )} - - {/* Instructions */} -
-

Focus Management Test Instructions:

-
    -
  • Tab through elements and observe focus movement
  • -
  • Open modal and verify focus moves to modal
  • -
  • Tab within modal - focus should stay trapped
  • -
  • Press Escape or close modal - focus should return to trigger
  • -
  • Check that focus indicators are always visible
  • -
-
-
- ) - }, -} - -// ARIA Roles and Properties Testing -export const ARIACompliance: Story = { - render: () => { - const [expandedSections, setExpandedSections] = useState>(new Set()) - - const toggleSection = (sectionId: string) => { - setExpandedSections(prev => { - const newSet = new Set(prev) - if (newSet.has(sectionId)) { - newSet.delete(sectionId) - } else { - newSet.add(sectionId) - } - return newSet - }) - } - - return ( -
-
-

ARIA Roles and Properties Test

-

- Testing proper ARIA roles, properties, and states for complex UI components. -

-
- - {/* Accordion with ARIA */} -
-

- Accessible Accordion -

- - {['section1', 'section2', 'section3'].map((sectionId, index) => { - const isExpanded = expandedSections.has(sectionId) - const headingId = `accordion-heading-${sectionId}` - const panelId = `accordion-panel-${sectionId}` - - return ( -
-
- -
- - -
- ) - })} -
- - {/* Tab panel with ARIA */} -
-

- Accessible Tab Panel -

- -
-
- {['Overview', 'Details', 'Settings'].map((tab, index) => ( - - ))} -
- -
-

- This is the overview tab content. Tab panels should have proper ARIA roles and relationships. -

-
-
-
- - {/* Live region examples */} -
-

- Live Regions -

- -
-
-
Polite Announcements
-
- Form validation messages and status updates appear here -
-
- -
-
Assertive Announcements
-
- Critical errors and urgent notifications appear here -
-
-
-
- - {/* ARIA testing checklist */} -
-

ARIA Compliance Checklist:

-
    -
  • ✓ All interactive elements have accessible names
  • -
  • ✓ Form controls have associated labels
  • -
  • ✓ Complex widgets use appropriate ARIA roles
  • -
  • ✓ State changes are communicated via ARIA properties
  • -
  • ✓ Live regions announce dynamic content changes
  • -
  • ✓ Focus management follows ARIA authoring practices
  • -
  • ✓ Keyboard navigation matches expected patterns
  • -
-
-
- ) - }, -} \ No newline at end of file diff --git a/stories/AgentPrimitive.stories.tsx b/stories/AgentPrimitive.stories.tsx deleted file mode 100644 index 345dffd..0000000 --- a/stories/AgentPrimitive.stories.tsx +++ /dev/null @@ -1,259 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import { AgentPrimitive } from '@agentarea/react' - -const meta: Meta = { - title: 'Components/AgentPrimitive', - component: AgentPrimitive.Root, - parameters: { - layout: 'centered', - docs: { - description: { - component: 'Agent primitive components for displaying agent information and status', - }, - }, - }, - tags: ['autodocs'], -} - -export default meta -type Story = StoryObj - -// Mock data for stories -const mockCapabilities = [ - { - name: 'Data Analysis', - description: 'Analyze datasets and generate insights', - inputTypes: ['csv', 'json', 'text'], - outputTypes: ['json', 'chart', 'report'] - }, - { - name: 'Document Generation', - description: 'Create documents and reports', - inputTypes: ['text', 'data'], - outputTypes: ['pdf', 'docx', 'html'] - }, - { - name: 'Code Review', - description: 'Review and analyze code for best practices', - inputTypes: ['javascript', 'typescript', 'python'], - outputTypes: ['report', 'suggestions'] - } -] - -// Agent Name Story -export const AgentName: Story = { - render: () => ( - - Analytics Agent - - ), -} - -// Agent Description Story -export const AgentDescription: Story = { - render: () => ( - - A specialized agent for data analysis, visualization, and insights generation. - Capable of processing various data formats and producing comprehensive reports. - - ), -} - -// Agent Status Story -export const AgentStatus: Story = { - render: () => ( -
- - Connected - - - - Disconnected - -
- ), -} - -// Agent Capabilities Story -export const AgentCapabilities: Story = { - render: () => ( -
- ( -
-
- {capability.name} -
-
- {capability.description} -
-
- Input: {capability.inputTypes.join(', ')} -
- Output: {capability.outputTypes.join(', ')} -
-
- )} - > - {mockCapabilities.map((capability, index) => ( - - ))} -
-
- ), -} - -// Agent Features Story -export const AgentFeatures: Story = { - render: () => ( - -
-
- ✓ Streaming Supported -
-
- ✗ Push Notifications -
-
-
- ), -} - -// Complete Agent Card Story -export const CompleteAgentCard: Story = { - render: () => ( -
- -
- - Analytics Agent - - - - Advanced data analysis and visualization agent with machine learning capabilities - - - -
- -
-

Features

- -
- - Streaming - - - Real-time Updates - -
-
-
- -
-

Capabilities

-
- {mockCapabilities.map((capability) => ( -
-
- {capability.name} -
-
- {capability.description} -
-
- ))} -
-
-
-
- ), -} \ No newline at end of file diff --git a/stories/Artifact.stories.tsx b/stories/Artifact.stories.tsx deleted file mode 100644 index 891e979..0000000 --- a/stories/Artifact.stories.tsx +++ /dev/null @@ -1,435 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import { Artifact } from '@agentarea/react' -import type { EnhancedArtifact } from '@agentarea/core' - -const meta: Meta = { - title: 'Components/Artifact', - component: Artifact, - parameters: { - layout: 'centered', - docs: { - description: { - component: 'Artifact display components for showing task outputs and results with different content types', - }, - }, - }, - tags: ['autodocs'], - argTypes: { - onDownload: { action: 'download' }, - onShare: { action: 'share' }, - onPreview: { action: 'preview' }, - }, -} - -export default meta -type Story = StoryObj - -// Mock artifacts for stories -const mockTextArtifact: EnhancedArtifact = { - id: 'artifact-text-1', - taskId: 'task-1', - displayType: 'text', - content: 'This is a sample text artifact containing analysis results and insights from the data processing task.', - mimeType: 'text/plain', - size: 156, - createdAt: new Date('2024-01-15T10:30:00Z'), - downloadable: true, - shareable: true, - metadata: { - name: 'Analysis Summary', - author: 'Data Analysis Agent', - version: '1.0' - } -} - -const mockCodeArtifact: EnhancedArtifact = { - id: 'artifact-code-1', - taskId: 'task-1', - displayType: 'code', - content: { - code: { - language: 'python', - content: `import pandas as pd -import matplotlib.pyplot as plt - -def analyze_sales_data(df): - """Analyze sales data and generate insights.""" - - # Calculate monthly totals - monthly_sales = df.groupby('month')['sales'].sum() - - # Find top performing products - top_products = df.groupby('product')['sales'].sum().sort_values(ascending=False).head(5) - - # Generate visualization - fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) - - # Monthly sales trend - monthly_sales.plot(kind='line', ax=ax1, marker='o') - ax1.set_title('Monthly Sales Trend') - ax1.set_xlabel('Month') - ax1.set_ylabel('Sales ($)') - - # Top products bar chart - top_products.plot(kind='bar', ax=ax2) - ax2.set_title('Top 5 Products by Sales') - ax2.set_xlabel('Product') - ax2.set_ylabel('Sales ($)') - ax2.tick_params(axis='x', rotation=45) - - plt.tight_layout() - return fig, monthly_sales, top_products - -# Example usage -if __name__ == "__main__": - # Load data - df = pd.read_csv('sales_data.csv') - - # Perform analysis - chart, monthly, products = analyze_sales_data(df) - - # Save results - chart.savefig('sales_analysis.png', dpi=300, bbox_inches='tight') - print("Analysis complete!") -` - } - }, - mimeType: 'text/x-python', - size: 1247, - createdAt: new Date('2024-01-15T10:35:00Z'), - downloadable: true, - shareable: true, - metadata: { - name: 'Sales Analysis Script', - language: 'python', - author: 'Code Generation Agent' - } -} - -const mockFileArtifact: EnhancedArtifact = { - id: 'artifact-file-1', - taskId: 'task-1', - displayType: 'file', - content: 'https://example.com/reports/sales_report_q4_2024.pdf', - mimeType: 'application/pdf', - size: 2048576, // 2MB - createdAt: new Date('2024-01-15T10:40:00Z'), - downloadable: true, - shareable: true, - metadata: { - name: 'Q4 2024 Sales Report', - pages: 24, - author: 'Report Generation Agent', - category: 'financial' - } -} - -const mockDataArtifact: EnhancedArtifact = { - id: 'artifact-data-1', - taskId: 'task-1', - displayType: 'data', - content: { - summary: { - totalSales: 1250000, - totalOrders: 3420, - averageOrderValue: 365.50, - topProduct: 'Premium Widget', - growthRate: 0.23 - }, - monthlyBreakdown: [ - { month: 'October', sales: 420000, orders: 1150 }, - { month: 'November', sales: 380000, orders: 1040 }, - { month: 'December', sales: 450000, orders: 1230 } - ], - topProducts: [ - { name: 'Premium Widget', sales: 280000, units: 560 }, - { name: 'Standard Widget', sales: 220000, units: 880 }, - { name: 'Deluxe Widget', sales: 180000, units: 300 } - ] - }, - mimeType: 'application/json', - size: 512, - createdAt: new Date('2024-01-15T10:45:00Z'), - downloadable: true, - shareable: true, - metadata: { - name: 'Sales Data Analysis', - format: 'json', - schema: 'sales-summary-v1' - } -} - -const mockImageArtifact: EnhancedArtifact = { - id: 'artifact-image-1', - taskId: 'task-1', - displayType: 'image', - content: { - image: { - url: 'https://via.placeholder.com/600x400/4f46e5/ffffff?text=Sales+Chart', - alt: 'Q4 2024 Sales Performance Chart', - width: 600, - height: 400 - } - }, - mimeType: 'image/png', - size: 89432, - createdAt: new Date('2024-01-15T10:50:00Z'), - downloadable: true, - shareable: true, - metadata: { - name: 'Sales Performance Chart', - dimensions: '600x400', - format: 'PNG', - dpi: 300 - } -} - -// Basic artifact stories -export const TextArtifact: Story = { - args: { - artifact: mockTextArtifact, - }, -} - -export const CodeArtifact: Story = { - args: { - artifact: mockCodeArtifact, - }, -} - -export const FileArtifact: Story = { - args: { - artifact: mockFileArtifact, - }, -} - -export const DataArtifact: Story = { - args: { - artifact: mockDataArtifact, - }, -} - -export const ImageArtifact: Story = { - args: { - artifact: mockImageArtifact, - }, -} - -// Container component stories -export const ArtifactContainer: Story = { - render: () => ( -
- console.log('Download:', artifact.metadata?.name)} - onShare={(artifact) => console.log('Share:', artifact.metadata?.name)} - > -
-

Custom content inside the artifact container.

-
-
- - - Custom Action - - } - > -
- print("Hello, World!") -
-
-
- ), -} - -// Specialized component stories -export const CodeWithSyntaxHighlighting: Story = { - render: () => ( -
- = new Map() - - async createUser(userData: Omit): Promise { - const user: User = { - id: crypto.randomUUID(), - ...userData, - createdAt: new Date() - } - - this.users.set(user.id, user) - return user - } - - async getUserById(id: string): Promise { - return this.users.get(id) || null - } - - async updateUser(id: string, updates: Partial): Promise { - const user = this.users.get(id) - if (!user) return null - - const updatedUser = { ...user, ...updates } - this.users.set(id, updatedUser) - return updatedUser - } -}` - } - } - }} - showLineNumbers={true} - maxHeight={400} - theme="auto" - /> -
- ), -} - -export const DataVisualization: Story = { - render: () => ( -
- -
- ), -} - -// Interactive stories -export const InteractiveArtifacts: Story = { - render: () => { - const handleDownload = (artifact: EnhancedArtifact) => { - alert(`Downloading: ${artifact.metadata?.name}`) - } - - const handleShare = (artifact: EnhancedArtifact) => { - alert(`Sharing: ${artifact.metadata?.name}`) - } - - const handlePreview = (artifact: EnhancedArtifact) => { - alert(`Previewing: ${artifact.metadata?.name}`) - } - - return ( -
- - - - - -
- ) - }, -} - -// Error states -export const ErrorStates: Story = { - render: () => ( -
- - - -
- ), -} - -// Large content handling -export const LargeContent: Story = { - render: () => ( -
- - `// Line ${i + 1}: This is a long line of code that demonstrates scrolling behavior -function processData${i}(data) { - return data.map(item => ({ ...item, processed: true, timestamp: Date.now() })) -}` - ).join('\n') - } - } - }} - maxHeight={300} - showLineNumbers={true} - /> -
- ), -} \ No newline at end of file diff --git a/stories/Block.stories.tsx b/stories/Block.stories.tsx deleted file mode 100644 index d917256..0000000 --- a/stories/Block.stories.tsx +++ /dev/null @@ -1,647 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import { Block } from '@agentarea/react' -import type { ProtocolMessage, CommunicationBlock } from '@agentarea/core' - -const meta: Meta = { - title: 'Components/Block', - component: Block.Message, - parameters: { - layout: 'centered', - docs: { - description: { - component: 'Communication block components for displaying agent-to-agent messages and protocol exchanges', - }, - }, - }, - tags: ['autodocs'], - argTypes: { - onExpand: { action: 'expand' }, - onCollapse: { action: 'collapse' }, - }, -} - -export default meta -type Story = StoryObj - -// Mock protocol messages for stories -const mockProtocolMessage: ProtocolMessage = { - id: 'msg-001', - type: 'task_request', - source: 'user-agent', - target: 'analytics-agent', - payload: { - taskType: 'data_analysis', - parameters: { - dataset: 'sales_q4_2024.csv', - analysisType: 'descriptive', - outputFormat: 'report' - }, - priority: 'high', - deadline: '2024-01-20T18:00:00Z' - }, - timestamp: new Date('2024-01-15T14:30:00Z'), - metadata: { - correlationId: 'corr-123', - sessionId: 'session-456', - version: '1.0' - } -} - -const mockResponseMessage: ProtocolMessage = { - id: 'msg-002', - type: 'task_response', - source: 'analytics-agent', - target: 'user-agent', - payload: { - status: 'completed', - result: { - summary: 'Analysis completed successfully', - insights: [ - 'Revenue increased by 23% compared to Q3', - 'Top performing product category: Electronics', - 'Customer retention rate improved to 87%' - ], - artifactIds: ['artifact-001', 'artifact-002'] - }, - executionTime: 45.2 - }, - timestamp: new Date('2024-01-15T14:32:15Z'), - metadata: { - correlationId: 'corr-123', - sessionId: 'session-456', - version: '1.0' - } -} - -const mockErrorMessage: ProtocolMessage = { - id: 'msg-003', - type: 'error', - source: 'database-agent', - target: 'analytics-agent', - payload: { - errorCode: 'CONNECTION_TIMEOUT', - message: 'Failed to connect to database after 30 seconds', - details: { - host: 'db.example.com', - port: 5432, - database: 'analytics', - retryAttempts: 3 - }, - recoverable: true - }, - timestamp: new Date('2024-01-15T14:31:45Z'), - metadata: { - correlationId: 'corr-124', - severity: 'high' - } -} - -const mockCommunicationBlock: CommunicationBlock = { - id: 'block-001', - type: 'message', - source: 'workflow-orchestrator', - target: 'broadcast', - content: { - announcement: 'System maintenance scheduled for tonight at 2 AM UTC', - duration: '30 minutes', - affectedServices: ['analytics', 'reporting', 'data-export'], - alternativeEndpoint: 'backup.example.com' - }, - timestamp: new Date('2024-01-15T16:00:00Z'), - metadata: { - priority: 'high', - category: 'maintenance', - broadcastType: 'system' - } -} - -// Basic message stories -export const BasicMessage: Story = { - args: { - message: mockProtocolMessage, - showMetadata: true, - showTimestamp: true, - showRouting: true, - }, -} - -export const ResponseMessage: Story = { - args: { - message: mockResponseMessage, - showMetadata: true, - showTimestamp: true, - showRouting: true, - }, -} - -export const ErrorMessage: Story = { - args: { - message: mockErrorMessage, - showMetadata: true, - showTimestamp: true, - showRouting: true, - isError: true, - }, -} - -export const CommunicationBlockMessage: Story = { - args: { - message: mockCommunicationBlock, - showMetadata: true, - showTimestamp: true, - showRouting: true, - }, -} - -// Expandable message -export const ExpandableMessage: Story = { - args: { - message: { - ...mockProtocolMessage, - payload: { - ...mockProtocolMessage.payload, - largeDataset: Array(20).fill(0).map((_, i) => ({ - id: i + 1, - name: `Item ${i + 1}`, - value: Math.random() * 1000, - category: ['A', 'B', 'C'][i % 3] - })) - } - }, - expandable: true, - showMetadata: true, - }, -} - -// Correlated messages -export const CorrelatedMessages: Story = { - render: () => ( -
- - - -
- ), -} - -// Protocol component stories -export const ProtocolDisplay: Story = { - render: () => ( -
- - - -
- ), -} - -export const ProtocolWithIssues: Story = { - render: () => ( -
- -
- ), -} - -// Status component stories -export const ConnectionStatus: Story = { - render: () => ( -
- - - - - -
- ), -} - -export const TaskStatus: Story = { - render: () => ( -
- - - -
- ), -} - -export const AgentStatus: Story = { - render: () => ( -
- - - -
- ), -} - -// Real-time status updates -export const RealTimeStatus: Story = { - render: () => ( -
- -
-

This status block simulates real-time updates with animation.

-
-
- ), -} - -// Metadata component stories -export const MetadataDisplay: Story = { - render: () => ( -
- - - -
- ), -} - -// Complex message thread -export const MessageThread: Story = { - render: () => { - const messages = [ - { - ...mockProtocolMessage, - id: 'msg-thread-1', - type: 'task_request', - timestamp: new Date('2024-01-15T14:30:00Z') - }, - { - id: 'msg-thread-2', - type: 'task_accepted', - source: 'analytics-agent', - target: 'user-agent', - payload: { - taskId: 'task-123', - estimatedDuration: '2-3 minutes', - status: 'accepted' - }, - timestamp: new Date('2024-01-15T14:30:05Z'), - metadata: { correlationId: 'corr-123' } - }, - { - id: 'msg-thread-3', - type: 'task_progress', - source: 'analytics-agent', - target: 'user-agent', - payload: { - taskId: 'task-123', - progress: 0.5, - currentStep: 'data_processing', - message: 'Processing 50% complete' - }, - timestamp: new Date('2024-01-15T14:31:30Z'), - metadata: { correlationId: 'corr-123' } - }, - { - ...mockResponseMessage, - id: 'msg-thread-4', - timestamp: new Date('2024-01-15T14:32:15Z') - } - ] - - return ( -
-

Message Thread

- {messages.map((message, index) => ( - 0 ? messages[0] as ProtocolMessage : undefined} - showCorrelation={index > 0} - /> - ))} -
- ) - }, -} - -// Error handling and edge cases -export const ErrorStates: Story = { - render: () => ( -
- - - - - -
- ), -} - -// Performance with large data -export const LargeDataHandling: Story = { - render: () => { - const largePayload = { - dataPoints: Array(1000).fill(0).map((_, i) => ({ - id: i, - timestamp: new Date(Date.now() - i * 1000).toISOString(), - value: Math.random() * 100, - category: `Category ${i % 10}`, - metadata: { - source: `sensor-${i % 50}`, - quality: Math.random() > 0.1 ? 'good' : 'poor' - } - })), - summary: { - totalPoints: 1000, - averageValue: 50.5, - categories: 10, - timeRange: '16.7 minutes' - } - } - - return ( -
- -
-

This message contains 1000 data points to test large payload handling.

-
-
- ) - }, -} \ No newline at end of file diff --git a/stories/Chat.stories.tsx b/stories/Chat.stories.tsx deleted file mode 100644 index 18bbbb5..0000000 --- a/stories/Chat.stories.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import React, { useState } from 'react' -import { Chat } from '@agentarea/react' - -const meta: Meta = { - title: 'Components/Chat', - component: Chat.Root, - parameters: { - layout: 'centered', - docs: { - description: { - component: 'Advanced chat UI components with streaming, markdown, file attachments, and tool calls', - }, - }, - }, - tags: ['autodocs'], -} - -export default meta -type Story = StoryObj - -// Basic chat message -export const BasicMessage: Story = { - render: () => ( -
- - Hello! Can you help me analyze this data? - - - - Of course! I'd be happy to help you analyze your data. Could you please share the dataset you'd like me to examine? - -
- ), -} - -// Markdown message -export const MarkdownMessage: Story = { - render: () => ( -
- - - -
- ), -} - -// File attachment -export const FileAttachment: Story = { - render: () => ( -
- - Here's the dataset you requested: - alert('Downloading file...')} - onPreview={() => alert('Opening preview...')} - /> - -
- ), -} - -// Tool call with approval -export const ToolCallApproval: Story = { - render: () => { - const [toolCall, setToolCall] = useState({ - id: 'tool_123', - name: 'execute_sql_query', - parameters: { - query: 'SELECT * FROM sales WHERE date >= "2024-01-01"', - database: 'production' - }, - status: 'pending' as const - }) - - const handleApprove = (id: string) => { - setToolCall(prev => ({ ...prev, status: 'approved' as const })) - } - - const handleReject = (id: string) => { - setToolCall(prev => ({ ...prev, status: 'rejected' as const })) - } - - return ( -
- - I need to run a SQL query to fetch the sales data. Please review and approve: - - -
- ) - }, -} - -// Chat input with file upload -export const ChatInputExample: Story = { - render: () => { - const [messages, setMessages] = useState([]) - - const handleSend = ({ text, files }: { text: string; files?: File[] }) => { - const message = text + (files?.length ? ` (with ${files.length} files)` : '') - setMessages(prev => [...prev, message]) - } - - return ( -
-
- {messages.map((msg, i) => ( -
- {msg} -
- ))} -
- - -
- ) - }, -} - -// Complete chat interface -export const CompleteChatInterface: Story = { - render: () => { - const [messages, setMessages] = useState([ - { - role: 'agent' as const, - content: 'Hello! I\'m your AI assistant. How can I help you today?', - timestamp: new Date(Date.now() - 60000) - }, - { - role: 'user' as const, - content: 'I need help analyzing my sales data', - timestamp: new Date(Date.now() - 30000) - }, - { - role: 'agent' as const, - content: 'I\'d be happy to help! Please upload your sales data file and I\'ll analyze it for you.', - timestamp: new Date(Date.now() - 15000) - } - ]) - const [isAgentTyping, setIsAgentTyping] = useState(false) - - const handleSend = ({ text, files }: { text: string; files?: File[] }) => { - // Add user message - setMessages(prev => [...prev, { - role: 'user' as const, - content: text + (files?.length ? ` [${files.length} files attached]` : ''), - timestamp: new Date() - }]) - - // Simulate agent response - setIsAgentTyping(true) - setTimeout(() => { - setIsAgentTyping(false) - setMessages(prev => [...prev, { - role: 'agent' as const, - content: 'Thank you for sharing that information. Let me process this and get back to you with insights.', - timestamp: new Date() - }]) - }, 2000) - } - - return ( -
-
-

AI Assistant Chat

-
- - - {messages.map((message, index) => ( - - - - ))} - - {isAgentTyping && ( - - )} - - -
- -
-
- ) - }, -} \ No newline at end of file diff --git a/stories/ChatEnhanced.stories.tsx b/stories/ChatEnhanced.stories.tsx deleted file mode 100644 index 2b690b7..0000000 --- a/stories/ChatEnhanced.stories.tsx +++ /dev/null @@ -1,829 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; -import { Chat, Artifact, Input } from "@agentarea/react"; -import type { EnhancedArtifact, TaskInputRequest } from "@agentarea/core"; -import { useState } from "react"; -import React from "react"; - -const meta: Meta = { - title: "Components/Chat Enhanced", - component: Chat.Root, - parameters: { - layout: "centered", - docs: { - description: { - component: - "Enhanced Chat components with artifact rendering and input collection capabilities", - }, - }, - }, - tags: ["autodocs"], -}; - -export default meta; -type Story = StoryObj; - -// Mock artifacts for chat -const mockCodeArtifact: EnhancedArtifact = { - id: "chat-artifact-1", - taskId: "chat-task-1", - displayType: "code", - content: { - code: { - language: "python", - content: `import pandas as pd -import matplotlib.pyplot as plt - -# Load and analyze sales data -df = pd.read_csv('sales_data.csv') - -# Calculate monthly revenue -monthly_revenue = df.groupby('month')['revenue'].sum() - -# Create visualization -plt.figure(figsize=(10, 6)) -monthly_revenue.plot(kind='bar') -plt.title('Monthly Revenue Analysis') -plt.xlabel('Month') -plt.ylabel('Revenue ($)') -plt.xticks(rotation=45) -plt.tight_layout() -plt.show() - -print(f"Total revenue: {monthly_revenue.sum():,.2f}") -print(f"Average monthly revenue: {monthly_revenue.mean():,.2f}")`, - }, - }, - mimeType: "text/x-python", - size: 512, - createdAt: new Date(), - downloadable: true, - shareable: true, - metadata: { - name: "Sales Analysis Script", - language: "python", - }, -}; - -const mockDataArtifact: EnhancedArtifact = { - id: "chat-artifact-2", - taskId: "chat-task-1", - displayType: "data", - content: { - analysis_results: { - total_revenue: 1250000, - total_orders: 3420, - average_order_value: 365.5, - top_products: [ - { name: "Premium Widget", revenue: 280000, units: 560 }, - { name: "Standard Widget", revenue: 220000, units: 880 }, - { name: "Deluxe Widget", revenue: 180000, units: 300 }, - ], - monthly_breakdown: { - october: { revenue: 420000, orders: 1150 }, - november: { revenue: 380000, orders: 1040 }, - december: { revenue: 450000, orders: 1230 }, - }, - }, - }, - mimeType: "application/json", - size: 1024, - createdAt: new Date(), - downloadable: true, - shareable: true, - metadata: { - name: "Analysis Results", - format: "JSON", - }, -}; - -const mockInputRequest: TaskInputRequest = { - id: "chat-input-1", - taskId: "chat-task-1", - type: "approval", - prompt: "Database Query Approval", - required: true, - metadata: { - title: "Execute Analytics Query", - description: - "I need permission to run a query on the sales database to get the latest data.", - context: { - query: 'SELECT * FROM sales WHERE date >= "2024-01-01"', - database: "production_sales", - estimatedRows: 50000, - }, - }, -}; - -// Enhanced chat with artifacts -export const ChatWithArtifacts: Story = { - render: () => { - const [messages, setMessages] = useState([ - { - role: "user" as const, - content: "Can you analyze our sales data and create a visualization?", - timestamp: new Date(Date.now() - 300000), - }, - { - role: "agent" as const, - content: - "I will analyze your sales data and create a visualization. Let me start by generating the analysis script.", - timestamp: new Date(Date.now() - 240000), - }, - { - role: "agent" as const, - content: - "Here is the Python script I have created for your sales analysis:", - timestamp: new Date(Date.now() - 180000), - artifacts: [mockCodeArtifact], - }, - { - role: "agent" as const, - content: - "I have also processed your data and here are the key insights:", - timestamp: new Date(Date.now() - 120000), - artifacts: [mockDataArtifact], - }, - ]); - - return ( -
-
-

Sales Analysis Chat

-
- -
- {messages.map((message, index) => ( -
-
-
-
{message.content}
-
- {message.timestamp.toLocaleTimeString()} -
-
- - {/* Render artifacts */} - {message.artifacts?.map((artifact) => ( - - console.log("Download:", artifact.metadata?.name) - } - onShare={(artifact) => - console.log("Share:", artifact.metadata?.name) - } - /> - ))} -
-
- ))} -
- -
- { - setMessages((prev) => [ - ...prev, - { - role: "user" as const, - content: text, - timestamp: new Date(), - }, - ]); - }} - placeholder="Ask about the analysis..." - /> -
-
- ); - }, -}; - -// Chat with input forms -export const ChatWithInputForms: Story = { - render: () => { - const [messages, setMessages] = useState([ - { - role: "user" as const, - content: "I need you to analyze our customer database", - timestamp: new Date(Date.now() - 180000), - }, - { - role: "agent" as const, - content: - "I can help you analyze your customer database. However, I need your approval to access the production database.", - timestamp: new Date(Date.now() - 120000), - }, - ]); - - const [pendingInputs, setPendingInputs] = useState([mockInputRequest]); - - const handleInputResponse = (requestId: string, response: any) => { - setPendingInputs((prev) => prev.filter((req) => req.id !== requestId)); - - const approved = response.approved; - const reasonText = response.reason ? `: ${response.reason}` : ""; - setMessages((prev) => [ - ...prev, - { - role: "user" as const, - content: approved - ? `✅ Approved database access${reasonText}` - : `❌ Rejected database access${reasonText}`, - timestamp: new Date(), - }, - { - role: "agent" as const, - content: approved - ? "Thank you! I will now access the database and perform the analysis. This may take a few minutes." - : "I understand. Is there an alternative approach you would prefer for the analysis?", - timestamp: new Date(), - }, - ]); - }; - - return ( -
-
-

Customer Analysis Chat

-
- -
- {messages.map((message, index) => ( -
-
-
{message.content}
-
- {message.timestamp.toLocaleTimeString()} -
-
-
- ))} - - {/* Render pending input requests */} - {pendingInputs.map((request) => ( -
- - handleInputResponse(request.id, response.value) - } - /> -
- ))} -
- -
- { - setMessages((prev) => [ - ...prev, - { - role: "user" as const, - content: text, - timestamp: new Date(), - }, - ]); - }} - placeholder="Continue the conversation..." - /> -
-
- ); - }, -}; - -// Multi-agent conversation -export const MultiAgentChat: Story = { - render: () => { - const [messages] = useState([ - { - role: "user" as const, - content: "I need a comprehensive business report for Q4", - timestamp: new Date(Date.now() - 600000), - agent: "User", - }, - { - role: "agent" as const, - content: - "I will coordinate with our specialized agents to create a comprehensive Q4 report. Let me delegate the tasks.", - timestamp: new Date(Date.now() - 540000), - agent: "Coordinator Agent", - }, - { - role: "agent" as const, - content: - "I will handle the financial analysis portion. Gathering revenue, profit, and expense data now.", - timestamp: new Date(Date.now() - 480000), - agent: "Finance Agent", - }, - { - role: "agent" as const, - content: - "I will analyze customer metrics including acquisition, retention, and satisfaction scores.", - timestamp: new Date(Date.now() - 420000), - agent: "Customer Analytics Agent", - }, - { - role: "agent" as const, - content: - "I will create the visualizations and format the final report once all data is collected.", - timestamp: new Date(Date.now() - 360000), - agent: "Report Generation Agent", - }, - { - role: "agent" as const, - content: - "Financial analysis complete. Q4 revenue increased 18% YoY to $2.4M. Detailed breakdown attached.", - timestamp: new Date(Date.now() - 240000), - agent: "Finance Agent", - artifacts: [mockDataArtifact], - }, - { - role: "agent" as const, - content: - "Customer analysis shows 87% retention rate and NPS of 72. Customer acquisition cost decreased by 12%.", - timestamp: new Date(Date.now() - 180000), - agent: "Customer Analytics Agent", - }, - { - role: "agent" as const, - content: - "All analyses are complete. Generating the comprehensive Q4 business report now.", - timestamp: new Date(Date.now() - 120000), - agent: "Report Generation Agent", - }, - ]); - - const getAgentColor = (agent: string) => { - const colors = { - User: "bg-primary text-primary-foreground", - "Coordinator Agent": "bg-blue-100 text-blue-900 border-blue-200", - "Finance Agent": "bg-green-100 text-green-900 border-green-200", - "Customer Analytics Agent": - "bg-purple-100 text-purple-900 border-purple-200", - "Report Generation Agent": - "bg-orange-100 text-orange-900 border-orange-200", - }; - return colors[agent as keyof typeof colors] || "bg-muted"; - }; - - const getAgentIcon = (agent: string) => { - const icons = { - User: "👤", - "Coordinator Agent": "🎯", - "Finance Agent": "💰", - "Customer Analytics Agent": "📊", - "Report Generation Agent": "📄", - }; - return icons[agent as keyof typeof icons] || "🤖"; - }; - - return ( -
-
-

- Multi-Agent Business Report Generation -

-
- Coordinated task execution across multiple specialized agents -
-
- -
- {messages.map((message, index) => ( -
-
- {getAgentIcon(message.agent)} - {message.agent} - - {message.timestamp.toLocaleTimeString()} -
- -
-
{message.content}
-
- - {/* Render artifacts */} - {message.artifacts?.map((artifact) => ( -
- - console.log("Download:", artifact.metadata?.name) - } - onShare={(artifact) => - console.log("Share:", artifact.metadata?.name) - } - /> -
- ))} -
- ))} -
- -
- -
-
- ); - }, -}; - -// Chat with streaming responses -export const StreamingChat: Story = { - render: () => { - const [messages, setMessages] = useState([ - { - role: "user" as const, - content: "Explain machine learning in simple terms", - timestamp: new Date(Date.now() - 60000), - }, - ]); - - const [isStreaming, setIsStreaming] = useState(false); - const [streamingContent, setStreamingContent] = useState(""); - - const fullResponse = `Machine learning is like teaching a computer to recognize patterns and make predictions, similar to how humans learn from experience. - -Here's a simple analogy: Imagine you're learning to recognize different dog breeds. At first, you might not know the difference between a Golden Retriever and a Labrador. But as you see more examples of each breed, you start to notice patterns - Golden Retrievers tend to have longer, fluffier coats, while Labradors have shorter, denser fur. - -Machine learning works similarly: - -1. **Training**: We show the computer thousands of examples (like photos of different dog breeds with labels) - -2. **Pattern Recognition**: The computer identifies patterns in the data (coat length, ear shape, size, etc.) - -3. **Prediction**: When shown a new photo, the computer uses these learned patterns to make an educated guess about the breed - -The key types of machine learning include: -- **Supervised Learning**: Learning with examples and correct answers -- **Unsupervised Learning**: Finding hidden patterns in data without being told what to look for -- **Reinforcement Learning**: Learning through trial and error, like a game - -Machine learning is everywhere today - from email spam filters to recommendation systems on Netflix, from voice assistants to autonomous vehicles. It's essentially giving computers the ability to improve their performance on tasks through experience, without being explicitly programmed for every possible scenario.`; - - const simulateStreaming = () => { - setIsStreaming(true); - setStreamingContent(""); - - let index = 0; - const interval = setInterval(() => { - if (index < fullResponse.length) { - setStreamingContent((prev) => prev + fullResponse[index]); - index++; - } else { - clearInterval(interval); - setIsStreaming(false); - setMessages((prev) => [ - ...prev, - { - role: "agent" as const, - content: fullResponse, - timestamp: new Date(), - }, - ]); - setStreamingContent(""); - } - }, 20); - }; - - React.useEffect(() => { - const timer = setTimeout(simulateStreaming, 1000); - return () => clearTimeout(timer); - }, []); - - return ( -
-
-

Streaming Response Demo

-
- -
- {messages.map((message, index) => ( -
-
-
- {message.content} -
-
- {message.timestamp.toLocaleTimeString()} -
-
-
- ))} - - {/* Streaming message */} - {isStreaming && ( -
-
-
- {streamingContent} - | -
-
Streaming...
-
-
- )} -
- -
- -
-
- ); - }, -}; - -// Chat with file attachments and artifacts -export const ChatWithFiles: Story = { - render: () => { - const [messages, setMessages] = useState([ - { - role: "user" as const, - content: "I have uploaded our sales data. Can you analyze it?", - timestamp: new Date(Date.now() - 300000), - files: [ - { - name: "sales_data_q4.csv", - size: 245760, - type: "text/csv", - url: "https://example.com/sales_data_q4.csv", - }, - ], - }, - { - role: "agent" as const, - content: - "I have received your sales data file. Let me analyze it and provide insights.", - timestamp: new Date(Date.now() - 240000), - }, - { - role: "agent" as const, - content: - "Analysis complete! Here are the key findings from your Q4 sales data:", - timestamp: new Date(Date.now() - 180000), - artifacts: [mockDataArtifact], - }, - { - role: "agent" as const, - content: - "I have also created a Python script that you can use to reproduce this analysis:", - timestamp: new Date(Date.now() - 120000), - artifacts: [mockCodeArtifact], - }, - ]); - - const handleSend = ({ text, files }: { text: string; files?: File[] }) => { - const newMessage = { - role: "user" as const, - content: text, - timestamp: new Date(), - files: files?.map((file) => ({ - name: file.name, - size: file.size, - type: file.type, - url: URL.createObjectURL(file), - })), - }; - - setMessages((prev) => [...prev, newMessage]); - - // Simulate agent response - setTimeout(() => { - const fileCount = files?.length || 0; - setMessages((prev) => [ - ...prev, - { - role: "agent" as const, - content: - fileCount > 0 - ? `I have received ${fileCount} file(s). Let me analyze them for you.` - : "How else can I help you with your data analysis?", - timestamp: new Date(), - }, - ]); - }, 1000); - }; - - return ( -
-
-

File Analysis Chat

-
- -
- {messages.map((message, index) => ( -
-
-
-
{message.content}
-
- {message.timestamp.toLocaleTimeString()} -
-
- - {/* Render file attachments */} - {message.files?.map((file, fileIndex) => ( -
- console.log("Download:", file.name)} - onPreview={() => console.log("Preview:", file.name)} - /> -
- ))} - - {/* Render artifacts */} - {message.artifacts?.map((artifact) => ( - - console.log("Download:", artifact.metadata?.name) - } - onShare={(artifact) => - console.log("Share:", artifact.metadata?.name) - } - /> - ))} -
-
- ))} -
- -
- -
-
- ); - }, -}; - -// Error handling in chat -export const ChatErrorHandling: Story = { - render: () => { - const [messages, setMessages] = useState([ - { - role: "user" as const, - content: "Can you analyze this database?", - timestamp: new Date(Date.now() - 180000), - }, - { - role: "agent" as const, - content: - "I will try to connect to the database and analyze it for you.", - timestamp: new Date(Date.now() - 120000), - }, - { - role: "system" as const, - content: - "❌ Error: Failed to connect to database. Connection timeout after 30 seconds.", - timestamp: new Date(Date.now() - 60000), - isError: true, - }, - { - role: "agent" as const, - content: - "I apologize, but I am unable to connect to the database right now. This could be due to network issues or the database being temporarily unavailable. Would you like me to try again, or is there another way I can help you?", - timestamp: new Date(Date.now() - 30000), - }, - ]); - - const handleRetry = () => { - setMessages((prev) => [ - ...prev, - { - role: "user" as const, - content: "Please try again", - timestamp: new Date(), - }, - ]); - - setTimeout(() => { - setMessages((prev) => [ - ...prev, - { - role: "agent" as const, - content: "Attempting to reconnect to the database...", - timestamp: new Date(), - }, - ]); - }, 1000); - }; - - return ( -
-
-

Error Handling Demo

-
- -
- {messages.map((message, index) => ( -
-
-
{message.content}
-
- {message.timestamp.toLocaleTimeString()} -
-
-
- ))} -
- -
- - -
-
- ); - }, -}; diff --git a/stories/EdgeCases.stories.tsx b/stories/EdgeCases.stories.tsx deleted file mode 100644 index 60d5d5c..0000000 --- a/stories/EdgeCases.stories.tsx +++ /dev/null @@ -1,682 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import { Artifact, Input, Block, Task, Chat } from '@agentarea/react' -import type { EnhancedArtifact, TaskInputRequest, ProtocolMessage, EnhancedTask } from '@agentarea/core' -import { useState } from 'react' - -const meta: Meta = { - title: 'Testing/Edge Cases', - parameters: { - layout: 'centered', - docs: { - description: { - component: 'Edge case testing scenarios including error states, empty data, malformed content, and boundary conditions', - }, - }, - }, - tags: ['autodocs'], -} - -export default meta -type Story = StoryObj - -// Empty and null data testing -export const EmptyDataHandling: Story = { - render: () => ( -
-
-

Empty Data Handling

-

- Testing how components handle empty, null, or undefined data gracefully. -

-
- - {/* Empty artifact */} -
-

Empty Artifact Content

- -
- - {/* Null content artifact */} -
-

Null Content Artifact

- -
- - {/* Empty form fields */} -
-

Empty Form Configuration

- -
- - {/* Empty message */} -
-

Empty Protocol Message

- -
-
- ), -} - -// Malformed data testing -export const MalformedDataHandling: Story = { - render: () => ( -
-
-

Malformed Data Handling

-

- Testing component resilience with corrupted, malformed, or unexpected data structures. -

-
- - {/* Malformed code artifact */} -
-

Malformed Code Artifact

- -
- - {/* Invalid JSON data */} -
-

Invalid JSON Data

- -
- - {/* Circular reference data */} -
-

Circular Reference Data

- { - const obj: any = { id: 'circular', name: 'test' } - obj.self = obj // Create circular reference - return { - id: 'circular-ref', - taskId: 'task-1', - displayType: 'data', - content: obj, - mimeType: 'application/json', - size: 100, - createdAt: new Date(), - downloadable: true, - shareable: true, - metadata: { name: 'Circular Reference' } - } - })()} - /> -
- - {/* Invalid form field types */} -
-

Invalid Form Field Types

- -
-
- ), -} - -// Boundary value testing -export const BoundaryValues: Story = { - render: () => { - // Generate very long content - const veryLongText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '.repeat(200) - const veryLongCode = Array(1000).fill(0).map((_, i) => - `// Line ${i + 1}: This is a very long line of code that tests horizontal scrolling and line wrapping behavior in code displays` - ).join('\n') - - // Generate large data structure - const largeDataStructure = { - metadata: { - generatedAt: new Date().toISOString(), - recordCount: 10000, - description: 'Large dataset for boundary testing' - }, - data: Array(1000).fill(0).map((_, i) => ({ - id: i, - name: `Record ${i}`, - value: Math.random() * 1000, - category: `Category ${i % 10}`, - tags: Array(5).fill(0).map((_, j) => `tag-${i}-${j}`), - metadata: { - created: new Date(Date.now() - Math.random() * 86400000).toISOString(), - updated: new Date().toISOString(), - version: Math.floor(Math.random() * 10) + 1 - } - })) - } - - return ( -
-
-

Boundary Value Testing

-

- Testing components with extreme values: very long content, large datasets, and edge cases. -

-
- - {/* Very long text */} -
-

Very Long Text Content

- -
- - {/* Very long code */} -
-

Very Long Code File

- -
- - {/* Large data structure */} -
-

Large Data Structure

- -
- - {/* Very long form */} -
-

Form with Many Fields

- ({ - name: `field${i}`, - type: ['text', 'email', 'number', 'textarea', 'select'][i % 5] as any, - label: `Field ${i + 1}: ${['Personal Info', 'Contact Details', 'Preferences', 'Settings', 'Additional'][i % 5]}`, - placeholder: `Enter your ${['name', 'email', 'age', 'comments', 'choice'][i % 5]}`, - validation: i % 3 === 0 ? [{ type: 'required', message: `Field ${i + 1} is required` }] : [], - options: i % 5 === 4 ? [ - { value: 'option1', label: `Option 1 for field ${i + 1}` }, - { value: 'option2', label: `Option 2 for field ${i + 1}` }, - { value: 'option3', label: `Option 3 for field ${i + 1}` } - ] : undefined - })) - } - }} - showProgress={true} - /> -
-
- ) - }, -} - -// Unicode and special character testing -export const UnicodeAndSpecialCharacters: Story = { - render: () => ( -
-
-

Unicode & Special Characters

-

- Testing component handling of various Unicode characters, emojis, and special symbols. -

-
- - {/* Unicode text */} -
-

Multilingual Text

- -
- - {/* Emoji and symbols */} -
-

Emojis and Symbols

- -
- - {/* Special characters in code */} -
-

Code with Special Characters

- -
- - {/* Form with special characters */} -
-

Form with Unicode Labels

- -
-
- ), -} - -// Error recovery testing -export const ErrorRecovery: Story = { - render: () => { - const [simulateError, setSimulateError] = useState(false) - const [errorCount, setErrorCount] = useState(0) - - const triggerError = () => { - setSimulateError(true) - setErrorCount(prev => prev + 1) - setTimeout(() => setSimulateError(false), 3000) - } - - return ( -
-
-

Error Recovery Testing

-

- Testing component behavior during errors and recovery scenarios. -

- -
- - {/* Error boundary simulation */} -
-

Component Error Handling

- {simulateError ? ( -
-
- ⚠️ - Component Error -
-

- A simulated error occurred while rendering this component. -

- -
- ) : ( - - )} -
- - {/* Network error simulation */} -
-

Network Error Handling

- -
- - {/* Form validation error recovery */} -
-

Form Error Recovery

- { - if (simulateError) { - throw new Error('Simulated submission error') - } - }} - /> -
- - {/* Instructions */} -
-

Error Recovery Test Instructions:

-
    -
  • Click "Simulate Error" to trigger error states
  • -
  • Observe how components handle and recover from errors
  • -
  • Check that error messages are clear and actionable
  • -
  • Verify that retry mechanisms work properly
  • -
  • Ensure components don't crash the entire application
  • -
-
-
- ) - }, -} \ No newline at end of file diff --git a/stories/Hooks.stories.tsx b/stories/Hooks.stories.tsx deleted file mode 100644 index a53ff9b..0000000 --- a/stories/Hooks.stories.tsx +++ /dev/null @@ -1,434 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' -import React, { useState } from 'react' -import { - useAgent, - useAgentCard, - useAgentCapabilities, - useConnection, - useTask, - useTaskList, - useTaskCreation -} from '@agentarea/react' - -const meta: Meta = { - title: 'Hooks/Examples', - parameters: { - layout: 'centered', - docs: { - description: { - component: 'Examples of AgentArea hooks in action', - }, - }, - }, - tags: ['autodocs'], -} - -export default meta -type Story = StoryObj - -// useAgent hook example -const UseAgentExample = () => { - const { - isConnected, - agentCard, - capabilities, - supportsStreaming, - supportsPushNotifications, - error - } = useAgent() - - return ( -
-

useAgent() Hook

-
- Connection Status: {isConnected ? '✅ Connected' : '❌ Disconnected'} -
- - {agentCard && ( -
- Agent: {agentCard.name} -
{agentCard.description}
-
- )} - -
- Features: -
- Streaming: {supportsStreaming() ? '✅' : '❌'} | - Push Notifications: {supportsPushNotifications() ? '✅' : '❌'} -
-
- -
- Capabilities: {capabilities.length} available -
- - {error && ( -
- Error: {error.message} -
- )} -
- ) -} - -export const UseAgentHook: Story = { - render: () => -} - -// useAgentCard hook example -const UseAgentCardExample = () => { - const agentCard = useAgentCard() - - return ( -
-

useAgentCard() Hook

- {agentCard ? ( -
-
- {agentCard.name} -
-
- {agentCard.description} -
-
- Version: {agentCard.version} -
- {agentCard.supportedFeatures && ( -
- Features: {agentCard.supportedFeatures.join(', ')} -
- )} -
- ) : ( -
No agent card available
- )} -
- ) -} - -export const UseAgentCardHook: Story = { - render: () => -} - -// useAgentCapabilities hook example -const UseAgentCapabilitiesExample = () => { - const capabilities = useAgentCapabilities() - - return ( -
-

useAgentCapabilities() Hook

-
Found {capabilities.length} capabilities:
-
- {capabilities.map((capability, index) => ( -
-
- {capability.name} -
-
- {capability.description} -
-
- Input: {capability.inputTypes.join(', ')} | - Output: {capability.outputTypes.join(', ')} -
-
- ))} -
-
- ) -} - -export const UseAgentCapabilitiesHook: Story = { - render: () => -} - -// useConnection hook example -const UseConnectionExample = () => { - const { isConnected, error, connect, disconnect } = useConnection() - - return ( -
-

useConnection() Hook

-
- Status: {isConnected ? '✅ Connected' : '❌ Disconnected'} -
- -
- - -
- - {error && ( -
- Error: {error.message} -
- )} -
- ) -} - -export const UseConnectionHook: Story = { - render: () => -} - -// useTaskCreation hook example -const UseTaskCreationExample = () => { - const { createTask, createStreamingTask, isCreating, error, canStream } = useTaskCreation() - const [taskInput, setTaskInput] = useState('Analyze the quarterly sales data') - const [lastTaskId, setLastTaskId] = useState(null) - const [streamingResults, setStreamingResults] = useState([]) - - const handleCreateTask = async () => { - try { - const response = await createTask({ - message: { - role: 'user', - parts: [{ type: 'text', content: taskInput }] - } - }) - setLastTaskId(response.taskId) - } catch (err) { - console.error('Failed to create task:', err) - } - } - - const handleCreateStreamingTask = async () => { - try { - setStreamingResults([]) - for await (const update of createStreamingTask({ - message: { - role: 'user', - parts: [{ type: 'text', content: taskInput }] - } - })) { - setStreamingResults(prev => [...prev, `${update.type}: ${update.task.status}`]) - if (update.type === 'task-completed') { - setLastTaskId(update.taskId) - } - } - } catch (err) { - console.error('Failed to create streaming task:', err) - } - } - - return ( -
-

useTaskCreation() Hook

- -
- -