diff --git a/.env.example b/.env.example
index dc00d2e6..4077e9cd 100644
--- a/.env.example
+++ b/.env.example
@@ -42,6 +42,12 @@ ARCHON_DOCS_PORT=3838
# If not set, defaults to localhost, 127.0.0.1, ::1, and the HOST value above
VITE_ALLOWED_HOSTS=
+# Development Tools
+# VITE_SHOW_DEVTOOLS: Show TanStack Query DevTools (for developers only)
+# Set to "true" to enable the DevTools panel in bottom right corner
+# Defaults to "false" for end users
+VITE_SHOW_DEVTOOLS=false
+
# When enabled, PROD mode will proxy ARCHON_SERVER_PORT through ARCHON_UI_PORT. This exposes both the
# Archon UI and API through a single port. This is useful when deploying Archon behind a reverse
# proxy where you want to expose the frontend on a single external domain.
diff --git a/.gitignore b/.gitignore
index 5145d4dc..bf0230ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ __pycache__
PRPs/local
PRPs/completed/
/logs/
+.zed
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000..3c0928c1
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,388 @@
+# AGENTS.md
+
+## Alpha Development Guidelines
+
+**Local-only deployment** - each user runs their own instance.
+
+### Core Principles
+
+- **No backwards compatibility** - remove deprecated code immediately
+- **Detailed errors over graceful failures** - we want to identify and fix issues fast
+- **Break things to improve them** - alpha is for rapid iteration
+
+### Error Handling
+
+**Core Principle**: In alpha, we need to intelligently decide when to fail hard and fast to quickly address issues, and when to allow processes to complete in critical services despite failures. Read below carefully and make intelligent decisions on a case-by-case basis.
+
+#### When to Fail Fast and Loud (Let it Crash!)
+
+These errors should stop execution and bubble up immediately: (except for crawling flows)
+
+- **Service startup failures** - If credentials, database, or any service can't initialize, the system should crash with a clear error
+- **Missing configuration** - Missing environment variables or invalid settings should stop the system
+- **Database connection failures** - Don't hide connection issues, expose them
+- **Authentication/authorization failures** - Security errors must be visible and halt the operation
+- **Data corruption or validation errors** - Never silently accept bad data, Pydantic should raise
+- **Critical dependencies unavailable** - If a required service is down, fail immediately
+- **Invalid data that would corrupt state** - Never store zero embeddings, null foreign keys, or malformed JSON
+
+#### When to Complete but Log Detailed Errors
+
+These operations should continue but track and report failures clearly:
+
+- **Batch processing** - When crawling websites or processing documents, complete what you can and report detailed failures for each item
+- **Background tasks** - Embedding generation, async jobs should finish the queue but log failures
+- **WebSocket events** - Don't crash on a single event failure, log it and continue serving other clients
+- **Optional features** - If projects/tasks are disabled, log and skip rather than crash
+- **External API calls** - Retry with exponential backoff, then fail with a clear message about what service failed and why
+
+#### Critical Nuance: Never Accept Corrupted Data
+
+When a process should continue despite failures, it must **skip the failed item entirely** rather than storing corrupted data:
+
+**❌ WRONG - Silent Corruption:**
+
+```python
+try:
+ embedding = create_embedding(text)
+except Exception as e:
+ embedding = [0.0] * 1536 # NEVER DO THIS - corrupts database
+ store_document(doc, embedding)
+```
+
+**✅ CORRECT - Skip Failed Items:**
+
+```python
+try:
+ embedding = create_embedding(text)
+ store_document(doc, embedding) # Only store on success
+except Exception as e:
+ failed_items.append({'doc': doc, 'error': str(e)})
+ logger.error(f"Skipping document {doc.id}: {e}")
+ # Continue with next document, don't store anything
+```
+
+**✅ CORRECT - Batch Processing with Failure Tracking:**
+
+```python
+def process_batch(items):
+ results = {'succeeded': [], 'failed': []}
+
+ for item in items:
+ try:
+ result = process_item(item)
+ results['succeeded'].append(result)
+ except Exception as e:
+ results['failed'].append({
+ 'item': item,
+ 'error': str(e),
+ 'traceback': traceback.format_exc()
+ })
+ logger.error(f"Failed to process {item.id}: {e}")
+
+ # Always return both successes and failures
+ return results
+```
+
+#### Error Message Guidelines
+
+- Include context about what was being attempted when the error occurred
+- Preserve full stack traces with `exc_info=True` in Python logging
+- Use specific exception types, not generic Exception catching
+- Include relevant IDs, URLs, or data that helps debug the issue
+- Never return None/null to indicate failure - raise an exception with details
+- For batch operations, always report both success count and detailed failure list
+
+### Code Quality
+
+- Remove dead code immediately rather than maintaining it - no backward compatibility or legacy functions
+- Prioritize functionality over production-ready patterns
+- Focus on user experience and feature completeness
+- When updating code, don't reference what is changing (avoid keywords like LEGACY, CHANGED, REMOVED), instead focus on comments that document just the functionality of the code
+
+## Architecture Overview
+
+Archon V2 Alpha is a microservices-based knowledge management system with MCP (Model Context Protocol) integration:
+
+- **Frontend (port 3737)**: React + TypeScript + Vite + TailwindCSS
+ - **UI Strategy**: Radix UI primitives in `/features`, custom components in legacy `/components`
+ - **State Management**: TanStack Query for all data fetching in `/features`
+ - **Styling**: Tron-inspired glassmorphism with Tailwind CSS
+- **Main Server (port 8181)**: FastAPI with HTTP polling for updates
+- **MCP Server (port 8051)**: Lightweight HTTP-based MCP protocol server
+- **Agents Service (port 8052)**: PydanticAI agents for AI/ML operations
+- **Database**: Supabase (PostgreSQL + pgvector for embeddings)
+
+## Development Commands
+
+### Frontend (archon-ui-main/)
+
+```bash
+npm run dev # Start development server on port 3737
+npm run build # Build for production
+npm run lint # Run ESLint
+npm run test # Run Vitest tests
+npm run test:coverage # Run tests with coverage report
+```
+
+# Biome Linter Guide for AI Assistants
+
+## Overview
+
+This project uses Biome for linting and formatting the `/src/features` directory. Biome provides fast, machine-readable feedback that AI assistants can use to improve code quality.
+
+## Configuration
+
+Biome is configured in `biome.json`:
+
+- **Scope**: Only checks `/src/features/**` directory
+- **Formatting**: 2 spaces, 80 char line width
+- **Linting**: Recommended rules enabled
+- **Import Organization**: Automatically sorts and groups imports
+
+## AI Assistant Workflow in the new /features directory
+
+1. **Check Issues**: Run `npm run biome:ai` to get JSON output
+2. **Parse Output**: Extract error locations and types
+3. **Apply Fixes**:
+ - Run `npm run biome:ai-fix` for auto-fixable issues
+ - Manually fix remaining issues based on patterns above
+4. **Verify**: Run `npm run biome:ai` again to confirm fixes
+
+## JSON Output Format
+
+When using `biome:ai`, the output is structured JSON:
+
+```json
+{
+ "diagnostics": [
+ {
+ "file": "path/to/file.tsx",
+ "line": 10,
+ "column": 5,
+ "severity": "error",
+ "message": "Description of the issue",
+ "rule": "lint/a11y/useButtonType"
+ }
+ ]
+}
+```
+
+### Backend (python/)
+
+```bash
+# Using uv package manager
+uv sync # Install/update dependencies
+uv run pytest # Run tests
+uv run python -m src.server.main # Run server locally
+
+# With Docker
+docker-compose up --build -d # Start all services
+docker-compose logs -f # View logs
+docker-compose restart # Restart services
+```
+
+### Testing
+
+```bash
+# Frontend tests (from archon-ui-main/)
+npm run test:coverage:stream # Run with streaming output
+npm run test:ui # Run with Vitest UI
+
+# Backend tests (from python/)
+uv run pytest tests/test_api_essentials.py -v
+uv run pytest tests/test_service_integration.py -v
+```
+
+## Key API Endpoints
+
+### Knowledge Base
+
+- `POST /api/knowledge/crawl` - Crawl a website
+- `POST /api/knowledge/upload` - Upload documents (PDF, DOCX, MD)
+- `GET /api/knowledge/items` - List knowledge items
+- `POST /api/knowledge/search` - RAG search
+
+### MCP Integration
+
+- `GET /api/mcp/health` - MCP server status
+- `POST /api/mcp/tools/{tool_name}` - Execute MCP tool
+- `GET /api/mcp/tools` - List available tools
+
+### Projects & Tasks (when enabled)
+
+- `GET /api/projects` - List all projects
+- `POST /api/projects` - Create project
+- `GET /api/projects/{id}` - Get single project
+- `PUT /api/projects/{id}` - Update project
+- `DELETE /api/projects/{id}` - Delete project
+- `GET /api/projects/{id}/tasks` - Get tasks for project (use this, not getTasks)
+- `POST /api/tasks` - Create task
+- `PUT /api/tasks/{id}` - Update task
+- `DELETE /api/tasks/{id}` - Delete task
+
+## Polling Architecture
+
+### HTTP Polling (replaced Socket.IO)
+
+- **Polling intervals**: 1-2s for active operations, 5-10s for background data
+- **ETag caching**: Reduces bandwidth by ~70% via 304 Not Modified responses
+- **Smart pausing**: Stops polling when browser tab is inactive
+- **Progress endpoints**: `/api/progress/crawl`, `/api/progress/project-creation`
+
+### Key Polling Hooks
+
+- `usePolling` - Generic polling with ETag support
+- `useDatabaseMutation` - Optimistic updates with rollback
+- `useProjectMutation` - Project-specific operations
+
+## Environment Variables
+
+Required in `.env`:
+
+```bash
+SUPABASE_URL=https://your-project.supabase.co
+SUPABASE_SERVICE_KEY=your-service-key-here
+```
+
+Optional:
+
+```bash
+OPENAI_API_KEY=your-openai-key # Can be set via UI
+LOGFIRE_TOKEN=your-logfire-token # For observability
+LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR
+```
+
+## File Organization
+
+### Frontend Structure
+
+- `src/components/` - Legacy UI components (custom-built)
+- `src/features/` - Modern vertical slice architecture with Radix UI
+ - `ui/primitives/` - Radix UI primitives with Tron glassmorphism
+ - `projects/` - Project management feature
+ - `tasks/` - Task management sub-feature
+- `src/pages/` - Main application pages
+- `src/services/` - API communication and business logic
+- `src/hooks/` - Custom React hooks
+- `src/contexts/` - React context providers
+
+### UI Libraries
+
+- **Radix UI** (@radix-ui/react-\*) - Unstyled, accessible primitives for `/features`
+- **TanStack Query** - Data fetching and caching for `/features`
+- **React DnD** - Drag and drop for Kanban boards
+- **Tailwind CSS** - Utility-first styling with Tron-inspired glassmorphism
+- **Framer Motion** - Animations (minimal usage)
+
+### Theme Management
+
+- **ThemeContext** - Manages light/dark theme state
+- **Tailwind dark mode** - Uses `dark:` prefix with selector strategy
+- **Automatic switching** - All components respect theme via Tailwind classes
+- **Persistent** - Theme choice saved in localStorage
+- **Tron aesthetic** - Stronger neon glows in dark mode, subtle in light mode
+
+We're migrating to a vertical slice architecture where each feature is self-contained. Features are organized by domain hierarchy - main features contain their sub-features. For example, tasks are a sub-feature of projects, so they live at `features/projects/tasks/` rather than as separate siblings. Each feature level has its own components, hooks, types, and services folders. This keeps related code together and makes the codebase more maintainable as it scales.
+
+### Backend Structure
+
+- `src/server/` - Main FastAPI application
+- `src/server/api_routes/` - API route handlers
+- `src/server/services/` - Business logic services
+- `src/mcp/` - MCP server implementation
+- `src/agents/` - PydanticAI agent implementations
+
+## Database Schema
+
+Key tables in Supabase:
+
+- `sources` - Crawled websites and uploaded documents
+- `documents` - Processed document chunks with embeddings
+- `projects` - Project management (optional feature)
+- `tasks` - Task tracking linked to projects
+- `code_examples` - Extracted code snippets
+
+## API Naming Conventions
+
+### Task Status Values
+
+Use database values directly (no UI mapping):
+
+- `todo`, `doing`, `review`, `done`
+
+### Service Method Patterns
+
+- `get[Resource]sByProject(projectId)` - Scoped queries
+- `get[Resource](id)` - Single resource
+- `create[Resource](data)` - Create operations
+- `update[Resource](id, updates)` - Updates
+- `delete[Resource](id)` - Soft deletes
+
+### State Naming
+
+- `is[Action]ing` - Loading states (e.g., `isSwitchingProject`)
+- `[resource]Error` - Error messages
+- `selected[Resource]` - Current selection
+
+## Common Development Tasks
+
+### Add a new API endpoint
+
+1. Create route handler in `python/src/server/api_routes/`
+2. Add service logic in `python/src/server/services/`
+3. Include router in `python/src/server/main.py`
+4. Update frontend service in `archon-ui-main/src/services/`
+
+### Add a new UI component
+
+For **features** directory (preferred for new components):
+
+1. Use Radix UI primitives from `src/features/ui/primitives/`
+2. Create component in relevant feature folder under `src/features/`
+3. Use TanStack Query for data fetching
+4. Apply Tron-inspired glassmorphism styling with Tailwind
+
+For **legacy** components:
+
+1. Create component in `archon-ui-main/src/components/`
+2. Add to page in `archon-ui-main/src/pages/`
+3. Include any new API calls in services
+4. Add tests in `archon-ui-main/test/`
+
+### Debug MCP connection issues
+
+1. Check MCP health: `curl http://localhost:8051/health`
+2. View MCP logs: `docker-compose logs archon-mcp`
+3. Test tool execution via UI MCP page
+4. Verify Supabase connection and credentials
+
+## Code Quality Standards
+
+We enforce code quality through automated linting and type checking:
+
+- **Python 3.12** with 120 character line length
+- **Ruff** for linting - checks for errors, warnings, unused imports, and code style
+- **Mypy** for type checking - ensures type safety across the codebase
+- **Auto-formatting** on save in IDEs to maintain consistent style
+- Run `uv run ruff check` and `uv run mypy src/` locally before committing
+
+## MCP Tools Available
+
+When connected to Cursor/Windsurf:
+
+- `archon:perform_rag_query` - Search knowledge base
+- `archon:search_code_examples` - Find code snippets
+- `archon:manage_project` - Project operations
+- `archon:manage_task` - Task management
+- `archon:get_available_sources` - List knowledge sources
+
+## Important Notes
+
+- Projects feature is optional - toggle in Settings UI
+- All services communicate via HTTP, not gRPC
+- HTTP polling handles all updates (Socket.IO removed)
+- Frontend uses Vite proxy for API calls in development
+- Python backend uses `uv` for dependency management
+- Docker Compose handles service orchestration
+- we use tanstack query NO PROP DRILLING! refacring in progress!
diff --git a/CLAUDE.md b/CLAUDE.md
index 23808e55..b618b161 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -18,7 +18,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
#### When to Fail Fast and Loud (Let it Crash!)
-These errors should stop execution and bubble up immediately:
+These errors should stop execution and bubble up immediately: (except for crawling flows)
- **Service startup failures** - If credentials, database, or any service can't initialize, the system should crash with a clear error
- **Missing configuration** - Missing environment variables or invalid settings should stop the system
@@ -102,16 +102,6 @@ def process_batch(items):
- Focus on user experience and feature completeness
- When updating code, don't reference what is changing (avoid keywords like LEGACY, CHANGED, REMOVED), instead focus on comments that document just the functionality of the code
-## Architecture Overview
-
-Archon V2 Alpha is a microservices-based knowledge management system with MCP (Model Context Protocol) integration:
-
-- **Frontend (port 3737)**: React + TypeScript + Vite + TailwindCSS
-- **Main Server (port 8181)**: FastAPI with HTTP polling for updates
-- **MCP Server (port 8051)**: Lightweight HTTP-based MCP protocol server
-- **Agents Service (port 8052)**: PydanticAI agents for AI/ML operations
-- **Database**: Supabase (PostgreSQL + pgvector for embeddings)
-
## Development Commands
### Frontend (archon-ui-main/)
@@ -119,129 +109,231 @@ Archon V2 Alpha is a microservices-based knowledge management system with MCP (M
```bash
npm run dev # Start development server on port 3737
npm run build # Build for production
-npm run lint # Run ESLint
-npm run test # Run Vitest tests
-npm run test:coverage # Run tests with coverage report
+npm run lint # Run ESLint on legacy code (excludes /features)
+npm run lint:files path/to/file.tsx # Lint specific files
+
+# Biome for /src/features directory only
+npm run biome # Check features directory
+npm run biome:fix # Auto-fix issues
+npm run biome:format # Format code (120 char lines)
+npm run biome:ai # Machine-readable JSON output for AI
+npm run biome:ai-fix # Auto-fix with JSON output
+
+# Testing
+npm run test # Run all tests in watch mode
+npm run test:ui # Run with Vitest UI interface
+npm run test:coverage:stream # Run once with streaming output
+vitest run src/features/projects # Test specific directory
+
+# TypeScript
+npx tsc --noEmit # Check all TypeScript errors
+npx tsc --noEmit 2>&1 | grep "src/features" # Check features only
```
### Backend (python/)
```bash
-# Using uv package manager
-uv sync # Install/update dependencies
-uv run pytest # Run tests
-uv run python -m src.server.main # Run server locally
+# Using uv package manager (preferred)
+uv sync --group all # Install all dependencies
+uv run python -m src.server.main # Run server locally on 8181
+uv run pytest # Run all tests
+uv run pytest tests/test_api_essentials.py -v # Run specific test
+uv run ruff check # Run linter
+uv run ruff check --fix # Auto-fix linting issues
+uv run mypy src/ # Type check
-# With Docker
-docker-compose up --build -d # Start all services
-docker-compose logs -f # View logs
-docker-compose restart # Restart services
+# Docker operations
+docker compose up --build -d # Start all services
+docker compose --profile backend up -d # Backend only (for hybrid dev)
+docker compose logs -f archon-server # View server logs
+docker compose logs -f archon-mcp # View MCP server logs
+docker compose restart archon-server # Restart after code changes
+docker compose down # Stop all services
+docker compose down -v # Stop and remove volumes
```
-### Testing
+### Quick Workflows
```bash
-# Frontend tests (from archon-ui-main/)
-npm run test:coverage:stream # Run with streaming output
-npm run test:ui # Run with Vitest UI
+# Hybrid development (recommended) - backend in Docker, frontend local
+make dev # Or manually: docker compose --profile backend up -d && cd archon-ui-main && npm run dev
-# Backend tests (from python/)
-uv run pytest tests/test_api_essentials.py -v
-uv run pytest tests/test_service_integration.py -v
+# Full Docker mode
+make dev-docker # Or: docker compose up --build -d
+
+# Run linters before committing
+make lint # Runs both frontend and backend linters
+make lint-fe # Frontend only (ESLint + Biome)
+make lint-be # Backend only (Ruff + MyPy)
+
+# Testing
+make test # Run all tests
+make test-fe # Frontend tests only
+make test-be # Backend tests only
```
-## Key API Endpoints
+## Architecture Overview
-### Knowledge Base
+Archon V2 Alpha is a microservices-based knowledge management system with MCP (Model Context Protocol) integration:
-- `POST /api/knowledge/crawl` - Crawl a website
-- `POST /api/knowledge/upload` - Upload documents (PDF, DOCX, MD)
-- `GET /api/knowledge/items` - List knowledge items
-- `POST /api/knowledge/search` - RAG search
+### Service Architecture
-### MCP Integration
+- **Frontend (port 3737)**: React + TypeScript + Vite + TailwindCSS
+ - **Dual UI Strategy**:
+ - `/features` - Modern vertical slice with Radix UI primitives + TanStack Query
+ - `/components` - Legacy custom components (being migrated)
+ - **State Management**: TanStack Query for all data fetching (no prop drilling)
+ - **Styling**: Tron-inspired glassmorphism with Tailwind CSS
+ - **Linting**: Biome for `/features`, ESLint for legacy code
-- `GET /api/mcp/health` - MCP server status
-- `POST /api/mcp/tools/{tool_name}` - Execute MCP tool
-- `GET /api/mcp/tools` - List available tools
+- **Main Server (port 8181)**: FastAPI with HTTP polling for updates
+ - Handles all business logic, database operations, and external API calls
+ - WebSocket support removed in favor of HTTP polling with ETag caching
-### Projects & Tasks (when enabled)
+- **MCP Server (port 8051)**: Lightweight HTTP-based MCP protocol server
+ - Provides tools for AI assistants (Claude, Cursor, Windsurf)
+ - Exposes knowledge search, task management, and project operations
-- `GET /api/projects` - List all projects
-- `POST /api/projects` - Create project
-- `GET /api/projects/{id}` - Get single project
-- `PUT /api/projects/{id}` - Update project
-- `DELETE /api/projects/{id}` - Delete project
-- `GET /api/projects/{id}/tasks` - Get tasks for project (use this, not getTasks)
-- `POST /api/tasks` - Create task
-- `PUT /api/tasks/{id}` - Update task
-- `DELETE /api/tasks/{id}` - Delete task
+- **Agents Service (port 8052)**: PydanticAI agents for AI/ML operations
+ - Handles complex AI workflows and document processing
+
+- **Database**: Supabase (PostgreSQL + pgvector for embeddings)
+ - Cloud or local Supabase both supported
+ - pgvector for semantic search capabilities
+
+### Frontend Architecture Details
+
+#### Vertical Slice Architecture (/features)
+
+Features are organized by domain hierarchy with self-contained modules:
+
+```
+src/features/
+├── ui/
+│ ├── primitives/ # Radix UI base components
+│ ├── hooks/ # Shared UI hooks (useSmartPolling, etc)
+│ └── types/ # UI type definitions
+├── projects/
+│ ├── components/ # Project UI components
+│ ├── hooks/ # Project hooks (useProjectQueries, etc)
+│ ├── services/ # Project API services
+│ ├── types/ # Project type definitions
+│ ├── tasks/ # Tasks sub-feature (nested under projects)
+│ │ ├── components/
+│ │ ├── hooks/ # Task-specific hooks
+│ │ ├── services/ # Task API services
+│ │ └── types/
+│ └── documents/ # Documents sub-feature
+│ ├── components/
+│ ├── services/
+│ └── types/
+```
+
+#### TanStack Query Patterns
+
+All data fetching uses TanStack Query with consistent patterns:
+
+```typescript
+// Query keys factory pattern
+export const projectKeys = {
+ all: ["projects"] as const,
+ lists: () => [...projectKeys.all, "list"] as const,
+ detail: (id: string) => [...projectKeys.all, "detail", id] as const,
+};
+
+// Smart polling with visibility awareness
+const { refetchInterval } = useSmartPolling(10000); // Pauses when tab inactive
+
+// Optimistic updates with rollback
+useMutation({
+ onMutate: async (data) => {
+ await queryClient.cancelQueries(key);
+ const previous = queryClient.getQueryData(key);
+ queryClient.setQueryData(key, optimisticData);
+ return { previous };
+ },
+ onError: (err, vars, context) => {
+ if (context?.previous) {
+ queryClient.setQueryData(key, context.previous);
+ }
+ },
+});
+```
+
+### Backend Architecture Details
+
+#### Service Layer Pattern
+
+```python
+# API Route -> Service -> Database
+# src/server/api_routes/projects.py
+@router.get("/{project_id}")
+async def get_project(project_id: str):
+ return await project_service.get_project(project_id)
+
+# src/server/services/project_service.py
+async def get_project(project_id: str):
+ # Business logic here
+ return await db.fetch_project(project_id)
+```
+
+#### Error Handling Patterns
+
+```python
+# Use specific exceptions
+class ProjectNotFoundError(Exception): pass
+class ValidationError(Exception): pass
+
+# Rich error responses
+@app.exception_handler(ProjectNotFoundError)
+async def handle_not_found(request, exc):
+ return JSONResponse(
+ status_code=404,
+ content={"detail": str(exc), "type": "not_found"}
+ )
+```
## Polling Architecture
### HTTP Polling (replaced Socket.IO)
+
- **Polling intervals**: 1-2s for active operations, 5-10s for background data
- **ETag caching**: Reduces bandwidth by ~70% via 304 Not Modified responses
- **Smart pausing**: Stops polling when browser tab is inactive
-- **Progress endpoints**: `/api/progress/crawl`, `/api/progress/project-creation`
+- **Progress endpoints**: `/api/progress/{id}` for operation tracking
### Key Polling Hooks
-- `usePolling` - Generic polling with ETag support
-- `useDatabaseMutation` - Optimistic updates with rollback
-- `useProjectMutation` - Project-specific operations
-## Environment Variables
-
-Required in `.env`:
-
-```bash
-SUPABASE_URL=https://your-project.supabase.co
-SUPABASE_SERVICE_KEY=your-service-key-here
-```
-
-Optional:
-
-```bash
-OPENAI_API_KEY=your-openai-key # Can be set via UI
-LOGFIRE_TOKEN=your-logfire-token # For observability
-LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR
-```
-
-## File Organization
-
-### Frontend Structure
-
-- `src/components/` - Reusable UI components
-- `src/pages/` - Main application pages
-- `src/services/` - API communication and business logic
-- `src/hooks/` - Custom React hooks
-- `src/contexts/` - React context providers
-
-### Backend Structure
-
-- `src/server/` - Main FastAPI application
-- `src/server/api_routes/` - API route handlers
-- `src/server/services/` - Business logic services
-- `src/mcp/` - MCP server implementation
-- `src/agents/` - PydanticAI agent implementations
+- `useSmartPolling` - Adjusts interval based on page visibility/focus
+- `useCrawlProgressPolling` - Specialized for crawl progress with auto-cleanup
+- `useProjectTasks` - Smart polling for task lists
## Database Schema
Key tables in Supabase:
- `sources` - Crawled websites and uploaded documents
+ - Stores metadata, crawl status, and configuration
- `documents` - Processed document chunks with embeddings
+ - Text chunks with vector embeddings for semantic search
- `projects` - Project management (optional feature)
+ - Contains features array, documents, and metadata
- `tasks` - Task tracking linked to projects
+ - Status: todo, doing, review, done
+ - Assignee: User, Archon, AI IDE Agent
- `code_examples` - Extracted code snippets
+ - Language, summary, and relevance metadata
## API Naming Conventions
### Task Status Values
+
Use database values directly (no UI mapping):
+
- `todo`, `doing`, `review`, `done`
### Service Method Patterns
+
- `get[Resource]sByProject(projectId)` - Scoped queries
- `get[Resource](id)` - Single resource
- `create[Resource](data)` - Create operations
@@ -249,10 +341,30 @@ Use database values directly (no UI mapping):
- `delete[Resource](id)` - Soft deletes
### State Naming
+
- `is[Action]ing` - Loading states (e.g., `isSwitchingProject`)
- `[resource]Error` - Error messages
- `selected[Resource]` - Current selection
+## Environment Variables
+
+Required in `.env`:
+
+```bash
+SUPABASE_URL=https://your-project.supabase.co # Or http://host.docker.internal:8000 for local
+SUPABASE_SERVICE_KEY=your-service-key-here # Use legacy key format for cloud Supabase
+```
+
+Optional:
+
+```bash
+LOGFIRE_TOKEN=your-logfire-token # For observability
+LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR
+ARCHON_SERVER_PORT=8181 # Server port
+ARCHON_MCP_PORT=8051 # MCP server port
+ARCHON_UI_PORT=3737 # Frontend port
+```
+
## Common Development Tasks
### Add a new API endpoint
@@ -260,47 +372,72 @@ Use database values directly (no UI mapping):
1. Create route handler in `python/src/server/api_routes/`
2. Add service logic in `python/src/server/services/`
3. Include router in `python/src/server/main.py`
-4. Update frontend service in `archon-ui-main/src/services/`
+4. Update frontend service in `archon-ui-main/src/features/[feature]/services/`
-### Add a new UI component
+### Add a new UI component in features directory
-1. Create component in `archon-ui-main/src/components/`
-2. Add to page in `archon-ui-main/src/pages/`
-3. Include any new API calls in services
-4. Add tests in `archon-ui-main/test/`
+1. Use Radix UI primitives from `src/features/ui/primitives/`
+2. Create component in relevant feature folder under `src/features/[feature]/components/`
+3. Define types in `src/features/[feature]/types/`
+4. Use TanStack Query hook from `src/features/[feature]/hooks/`
+5. Apply Tron-inspired glassmorphism styling with Tailwind
### Debug MCP connection issues
1. Check MCP health: `curl http://localhost:8051/health`
-2. View MCP logs: `docker-compose logs archon-mcp`
+2. View MCP logs: `docker compose logs archon-mcp`
3. Test tool execution via UI MCP page
4. Verify Supabase connection and credentials
+### Fix TypeScript/Linting Issues
+
+```bash
+# TypeScript errors in features
+npx tsc --noEmit 2>&1 | grep "src/features"
+
+# Biome auto-fix for features
+npm run biome:fix
+
+# ESLint for legacy code
+npm run lint:files src/components/SomeComponent.tsx
+```
+
## Code Quality Standards
-We enforce code quality through automated linting and type checking:
+### Frontend
+
+- **TypeScript**: Strict mode enabled, no implicit any
+- **Biome** for `/src/features/`: 120 char lines, double quotes, trailing commas
+- **ESLint** for legacy code: Standard React rules
+- **Testing**: Vitest with React Testing Library
+
+### Backend
- **Python 3.12** with 120 character line length
-- **Ruff** for linting - checks for errors, warnings, unused imports, and code style
-- **Mypy** for type checking - ensures type safety across the codebase
-- **Auto-formatting** on save in IDEs to maintain consistent style
-- Run `uv run ruff check` and `uv run mypy src/` locally before committing
+- **Ruff** for linting - checks for errors, warnings, unused imports
+- **Mypy** for type checking - ensures type safety
+- **Pytest** for testing with async support
## MCP Tools Available
-When connected to Cursor/Windsurf:
+When connected to Client/Cursor/Windsurf:
- `archon:perform_rag_query` - Search knowledge base
- `archon:search_code_examples` - Find code snippets
-- `archon:manage_project` - Project operations
-- `archon:manage_task` - Task management
+- `archon:create_project` - Create new project
+- `archon:list_projects` - List all projects
+- `archon:create_task` - Create task in project
+- `archon:list_tasks` - List and filter tasks
+- `archon:update_task` - Update task status/details
- `archon:get_available_sources` - List knowledge sources
## Important Notes
- Projects feature is optional - toggle in Settings UI
- All services communicate via HTTP, not gRPC
-- HTTP polling handles all updates (Socket.IO removed)
+- HTTP polling handles all updates
- Frontend uses Vite proxy for API calls in development
- Python backend uses `uv` for dependency management
- Docker Compose handles service orchestration
+- TanStack Query for all data fetching - NO PROP DRILLING
+- Vertical slice architecture in `/features` - features own their sub-features
diff --git a/archon-ui-main/.eslintrc.cjs b/archon-ui-main/.eslintrc.cjs
index f7de173a..62100daa 100644
--- a/archon-ui-main/.eslintrc.cjs
+++ b/archon-ui-main/.eslintrc.cjs
@@ -6,28 +6,119 @@ module.exports = {
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
- ignorePatterns: ['dist', '.eslintrc.cjs'],
+ ignorePatterns: [
+ 'dist',
+ '.eslintrc.cjs',
+ 'public',
+ '__mocks__',
+ '*.config.js',
+ '*.config.ts',
+ 'coverage',
+ 'node_modules',
+ 'src/features/**' // Biome handles this directory
+ ],
parser: '@typescript-eslint/parser',
+ parserOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ },
plugins: ['react-refresh'],
rules: {
+ /**
+ * LINTING STRATEGY FOR ALPHA DEVELOPMENT:
+ *
+ * Development: Warnings don't block local development, allowing rapid iteration
+ * CI/PR: Run with --max-warnings 0 to treat warnings as errors before merge
+ *
+ * Philosophy:
+ * - Strict typing where it helps AI assistants (Claude Code, Copilot, etc.)
+ * - Pragmatic flexibility for alpha-stage rapid development
+ * - Console.log allowed locally but caught in CI
+ * - Progressive enhancement: stricter rules in /features (new code) vs /components (legacy)
+ */
+
+ // React Refresh
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
- '@typescript-eslint/no-unused-vars': ['warn', {
+
+ // TypeScript - Pragmatic strictness for AI-assisted development
+ '@typescript-eslint/no-explicit-any': 'warn', // Visible but won't block development
+ '@typescript-eslint/no-non-null-assertion': 'warn', // Allow when developer is certain
+ '@typescript-eslint/no-empty-function': 'warn', // Sometimes needed for placeholders
+ '@typescript-eslint/ban-types': 'error', // Keep strict - prevents real issues
+
+ // Help AI assistants understand code intent
+ '@typescript-eslint/explicit-function-return-type': ['warn', {
+ allowExpressions: true,
+ allowTypedFunctionExpressions: true,
+ allowHigherOrderFunctions: true,
+ allowDirectConstAssertionInArrowFunctions: true,
+ }],
+
+ // Better TypeScript patterns
+ '@typescript-eslint/prefer-as-const': 'error',
+
+ // Variable and import management - strict with escape hatches
+ '@typescript-eslint/no-unused-vars': ['error', {
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
- ignoreRestSiblings: true
+ ignoreRestSiblings: true,
+ destructuredArrayIgnorePattern: '^_'
}],
- '@typescript-eslint/no-explicit-any': 'off',
- '@typescript-eslint/no-empty-function': 'off',
- '@typescript-eslint/ban-types': 'off',
- '@typescript-eslint/no-non-null-assertion': 'warn',
- '@typescript-eslint/no-inferrable-types': 'off',
+
+ // React hooks - warn to allow intentional omissions during development
'react-hooks/exhaustive-deps': 'warn',
- 'no-case-declarations': 'off',
- 'no-constant-condition': 'warn',
- 'prefer-const': 'warn',
- 'no-undef': 'off',
+
+ // Console usage - warn locally, CI treats as error
+ 'no-console': ['warn', { allow: ['error', 'warn'] }], // console.log caught but not blocking
+
+ // General code quality
+ 'prefer-const': 'error',
+ 'no-var': 'error',
+ 'no-constant-condition': 'error',
+ 'no-debugger': 'warn', // Warn in dev, error in CI
+ 'no-alert': 'error',
+
+ // Disable rules that conflict with TypeScript
+ 'no-undef': 'off', // TypeScript handles this better
+ 'no-unused-vars': 'off', // Use @typescript-eslint/no-unused-vars instead
},
-}
+
+ // Override rules for specific file types and directories
+ overrides: [
+ {
+ // Stricter rules for new vertical slice architecture
+ files: ['src/features/**/*.{ts,tsx}'],
+ rules: {
+ '@typescript-eslint/no-explicit-any': 'error', // No any in new code
+ '@typescript-eslint/explicit-function-return-type': ['error', {
+ allowExpressions: true,
+ allowTypedFunctionExpressions: true,
+ }],
+ 'no-console': ['error', { allow: ['error', 'warn'] }], // Stricter console usage
+ }
+ },
+ {
+ // More lenient for legacy components being migrated
+ files: ['src/components/**/*.{ts,tsx}', 'src/services/**/*.{ts,tsx}'],
+ rules: {
+ '@typescript-eslint/no-explicit-any': 'warn', // Still visible during migration
+ '@typescript-eslint/explicit-function-return-type': 'off', // Not required for legacy
+ 'no-console': 'warn', // Warn during migration
+ }
+ },
+ {
+ // Test files - most lenient but still helpful
+ files: ['**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}', 'test/**/*'],
+ rules: {
+ '@typescript-eslint/no-explicit-any': 'warn', // OK in tests but still visible
+ '@typescript-eslint/no-non-null-assertion': 'off', // Fine in tests
+ '@typescript-eslint/no-empty-function': 'off', // Mock functions need this
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ 'no-console': 'off', // Debugging in tests is fine
+ }
+ }
+ ]
+};
\ No newline at end of file
diff --git a/archon-ui-main/biome.json b/archon-ui-main/biome.json
new file mode 100644
index 00000000..90e476bf
--- /dev/null
+++ b/archon-ui-main/biome.json
@@ -0,0 +1,41 @@
+{
+ "$schema": "https://biomejs.dev/schemas/2.2.2/schema.json",
+ "files": {
+ "includes": ["src/features/**"]
+ },
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "space",
+ "indentWidth": 2,
+ "lineWidth": 120,
+ "bracketSpacing": true,
+ "attributePosition": "auto"
+ },
+ "javascript": {
+ "formatter": {
+ "quoteStyle": "double",
+ "jsxQuoteStyle": "double",
+ "quoteProperties": "asNeeded",
+ "trailingCommas": "all",
+ "semicolons": "always",
+ "arrowParentheses": "always",
+ "bracketSameLine": false
+ }
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true
+ }
+ },
+ "assist": {
+ "enabled": true,
+ "actions": {
+ "source": {
+ "organizeImports": {
+ "level": "on"
+ }
+ }
+ }
+ }
+}
diff --git a/archon-ui-main/package-lock.json b/archon-ui-main/package-lock.json
index c5a0773e..cb8e8f36 100644
--- a/archon-ui-main/package-lock.json
+++ b/archon-ui-main/package-lock.json
@@ -8,11 +8,17 @@
"name": "archon-ui",
"version": "0.1.0",
"dependencies": {
- "@milkdown/crepe": "^7.5.0",
- "@milkdown/kit": "^7.5.0",
- "@milkdown/plugin-history": "^7.5.0",
- "@milkdown/preset-commonmark": "^7.5.0",
- "@xyflow/react": "^12.3.0",
+ "@mdxeditor/editor": "^3.42.0",
+ "@radix-ui/react-alert-dialog": "^1.1.15",
+ "@radix-ui/react-dialog": "^1.1.15",
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
+ "@radix-ui/react-popover": "^1.1.15",
+ "@radix-ui/react-select": "^2.2.6",
+ "@radix-ui/react-tabs": "^1.1.13",
+ "@radix-ui/react-toast": "^1.2.15",
+ "@radix-ui/react-tooltip": "^1.2.8",
+ "@tanstack/react-query": "^5.85.8",
+ "@tanstack/react-query-devtools": "^5.85.8",
"clsx": "latest",
"date-fns": "^4.1.0",
"fractional-indexing": "^3.2.0",
@@ -23,24 +29,26 @@
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.3.1",
+ "react-markdown": "^10.1.0",
"react-router-dom": "^6.26.2",
"tailwind-merge": "latest",
"zod": "^3.25.46"
},
"devDependencies": {
+ "@biomejs/biome": "2.2.2",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^14.3.1",
"@testing-library/user-event": "^14.5.2",
"@types/node": "^20.19.0",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.1",
- "@typescript-eslint/eslint-plugin": "^5.54.0",
- "@typescript-eslint/parser": "^5.54.0",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^1.6.0",
"@vitest/ui": "^1.6.0",
"autoprefixer": "latest",
- "eslint": "^8.50.0",
+ "eslint": "^8.57.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.1",
"jsdom": "^24.1.0",
@@ -263,6 +271,7 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -272,6 +281,7 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -305,6 +315,7 @@
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
"integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.28.0"
@@ -395,6 +406,7 @@
"version": "7.28.1",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz",
"integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
@@ -411,6 +423,169 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@biomejs/biome": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.2.tgz",
+ "integrity": "sha512-j1omAiQWCkhuLgwpMKisNKnsM6W8Xtt1l0WZmqY/dFj8QPNkIoTvk4tSsi40FaAAkBE1PU0AFG2RWFBWenAn+w==",
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "bin": {
+ "biome": "bin/biome"
+ },
+ "engines": {
+ "node": ">=14.21.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/biome"
+ },
+ "optionalDependencies": {
+ "@biomejs/cli-darwin-arm64": "2.2.2",
+ "@biomejs/cli-darwin-x64": "2.2.2",
+ "@biomejs/cli-linux-arm64": "2.2.2",
+ "@biomejs/cli-linux-arm64-musl": "2.2.2",
+ "@biomejs/cli-linux-x64": "2.2.2",
+ "@biomejs/cli-linux-x64-musl": "2.2.2",
+ "@biomejs/cli-win32-arm64": "2.2.2",
+ "@biomejs/cli-win32-x64": "2.2.2"
+ }
+ },
+ "node_modules/@biomejs/cli-darwin-arm64": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.2.tgz",
+ "integrity": "sha512-6ePfbCeCPryWu0CXlzsWNZgVz/kBEvHiPyNpmViSt6A2eoDf4kXs3YnwQPzGjy8oBgQulrHcLnJL0nkCh80mlQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-darwin-x64": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.2.tgz",
+ "integrity": "sha512-Tn4JmVO+rXsbRslml7FvKaNrlgUeJot++FkvYIhl1OkslVCofAtS35MPlBMhXgKWF9RNr9cwHanrPTUUXcYGag==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-arm64": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.2.tgz",
+ "integrity": "sha512-JfrK3gdmWWTh2J5tq/rcWCOsImVyzUnOS2fkjhiYKCQ+v8PqM+du5cfB7G1kXas+7KQeKSWALv18iQqdtIMvzw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-arm64-musl": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.2.tgz",
+ "integrity": "sha512-/MhYg+Bd6renn6i1ylGFL5snYUn/Ct7zoGVKhxnro3bwekiZYE8Kl39BSb0MeuqM+72sThkQv4TnNubU9njQRw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-x64": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.2.tgz",
+ "integrity": "sha512-Ogb+77edO5LEP/xbNicACOWVLt8mgC+E1wmpUakr+O4nKwLt9vXe74YNuT3T1dUBxC/SnrVmlzZFC7kQJEfquQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-x64-musl": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.2.tgz",
+ "integrity": "sha512-ZCLXcZvjZKSiRY/cFANKg+z6Fhsf9MHOzj+NrDQcM+LbqYRT97LyCLWy2AS+W2vP+i89RyRM+kbGpUzbRTYWig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-win32-arm64": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.2.tgz",
+ "integrity": "sha512-wBe2wItayw1zvtXysmHJQoQqXlTzHSpQRyPpJKiNIR21HzH/CrZRDFic1C1jDdp+zAPtqhNExa0owKMbNwW9cQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-win32-x64": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.2.tgz",
+ "integrity": "sha512-DAuHhHekGfiGb6lCcsT4UyxQmVwQiBCBUMwVra/dcOSs9q8OhfaZgey51MlekT3p8UwRqtXQfFuEJBhJNdLZwg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
"node_modules/@codemirror/autocomplete": {
"version": "6.18.6",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz",
@@ -763,6 +938,19 @@
"crelt": "^1.0.5"
}
},
+ "node_modules/@codemirror/merge": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/@codemirror/merge/-/merge-6.10.2.tgz",
+ "integrity": "sha512-rmHzVkt5FnCtsi0IgvDIDjh/J4LmbfOboB7FMvVl21IHO0p1QM6jSwjkBjBD3D+c+T79OabEqoduCqvJCBV8Yg==",
+ "license": "MIT",
+ "dependencies": {
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.17.0",
+ "@lezer/highlight": "^1.0.0",
+ "style-mod": "^4.1.0"
+ }
+ },
"node_modules/@codemirror/search": {
"version": "6.5.11",
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz",
@@ -783,18 +971,6 @@
"@marijn/find-cluster-break": "^1.0.0"
}
},
- "node_modules/@codemirror/theme-one-dark": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.3.tgz",
- "integrity": "sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==",
- "license": "MIT",
- "dependencies": {
- "@codemirror/language": "^6.0.0",
- "@codemirror/state": "^6.0.0",
- "@codemirror/view": "^6.0.0",
- "@lezer/highlight": "^1.0.0"
- }
- },
"node_modules/@codemirror/view": {
"version": "6.38.1",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.1.tgz",
@@ -807,6 +983,61 @@
"w3c-keyname": "^2.2.4"
}
},
+ "node_modules/@codesandbox/nodebox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/@codesandbox/nodebox/-/nodebox-0.1.8.tgz",
+ "integrity": "sha512-2VRS6JDSk+M+pg56GA6CryyUSGPjBEe8Pnae0QL3jJF1mJZJVMDKr93gJRtBbLkfZN6LD/DwMtf+2L0bpWrjqg==",
+ "license": "SEE LICENSE IN ./LICENSE",
+ "dependencies": {
+ "outvariant": "^1.4.0",
+ "strict-event-emitter": "^0.4.3"
+ }
+ },
+ "node_modules/@codesandbox/sandpack-client": {
+ "version": "2.19.8",
+ "resolved": "https://registry.npmjs.org/@codesandbox/sandpack-client/-/sandpack-client-2.19.8.tgz",
+ "integrity": "sha512-CMV4nr1zgKzVpx4I3FYvGRM5YT0VaQhALMW9vy4wZRhEyWAtJITQIqZzrTGWqB1JvV7V72dVEUCUPLfYz5hgJQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@codesandbox/nodebox": "0.1.8",
+ "buffer": "^6.0.3",
+ "dequal": "^2.0.2",
+ "mime-db": "^1.52.0",
+ "outvariant": "1.4.0",
+ "static-browser-server": "1.0.3"
+ }
+ },
+ "node_modules/@codesandbox/sandpack-react": {
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/@codesandbox/sandpack-react/-/sandpack-react-2.20.0.tgz",
+ "integrity": "sha512-takd1YpW/PMQ6KPQfvseWLHWklJovGY8QYj8MtWnskGKbjOGJ6uZfyZbcJ6aCFLQMpNyjTqz9AKNbvhCOZ1TUQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@codemirror/autocomplete": "^6.4.0",
+ "@codemirror/commands": "^6.1.3",
+ "@codemirror/lang-css": "^6.0.1",
+ "@codemirror/lang-html": "^6.4.0",
+ "@codemirror/lang-javascript": "^6.1.2",
+ "@codemirror/language": "^6.3.2",
+ "@codemirror/state": "^6.2.0",
+ "@codemirror/view": "^6.7.1",
+ "@codesandbox/sandpack-client": "^2.19.8",
+ "@lezer/highlight": "^1.1.3",
+ "@react-hook/intersection-observer": "^3.1.1",
+ "@stitches/core": "^1.2.6",
+ "anser": "^2.1.1",
+ "clean-set": "^1.1.2",
+ "dequal": "^2.0.2",
+ "escape-carriage": "^1.3.1",
+ "lz-string": "^1.4.4",
+ "react-devtools-inline": "4.4.0",
+ "react-is": "^17.0.2"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19",
+ "react-dom": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
@@ -1417,28 +1648,56 @@
}
},
"node_modules/@floating-ui/core": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.1.tgz",
- "integrity": "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==",
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
+ "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
"license": "MIT",
"dependencies": {
- "@floating-ui/utils": "^0.2.9"
+ "@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/dom": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.1.tgz",
- "integrity": "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==",
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
+ "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
"license": "MIT",
"dependencies": {
- "@floating-ui/core": "^1.7.1",
- "@floating-ui/utils": "^0.2.9"
+ "@floating-ui/core": "^1.7.3",
+ "@floating-ui/utils": "^0.2.10"
+ }
+ },
+ "node_modules/@floating-ui/react": {
+ "version": "0.27.16",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.16.tgz",
+ "integrity": "sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.1.6",
+ "@floating-ui/utils": "^0.2.10",
+ "tabbable": "^6.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=17.0.0",
+ "react-dom": ">=17.0.0"
+ }
+ },
+ "node_modules/@floating-ui/react-dom": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
+ "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.4"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
}
},
"node_modules/@floating-ui/utils": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
- "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
+ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
"license": "MIT"
},
"node_modules/@humanwhocodes/config-array": {
@@ -1588,6 +1847,7 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
@@ -1601,6 +1861,261 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@lexical/clipboard": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.33.1.tgz",
+ "integrity": "sha512-Qd3/Cm3TW2DFQv58kMtLi86u5YOgpBdf+o7ySbXz55C613SLACsYQBB3X5Vu5hTx/t/ugYOpII4HkiatW6d9zA==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/html": "0.33.1",
+ "@lexical/list": "0.33.1",
+ "@lexical/selection": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/code": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/code/-/code-0.33.1.tgz",
+ "integrity": "sha512-E0Y/+1znkqVpP52Y6blXGAduoZek9SSehJN+vbH+4iQKyFwTA7JB+jd5C5/K0ik55du9X7SN/oTynByg7lbcAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1",
+ "prismjs": "^1.30.0"
+ }
+ },
+ "node_modules/@lexical/devtools-core": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.33.1.tgz",
+ "integrity": "sha512-3yHu5diNtjwhoe2q/x9as6n6rIfA+QO2CfaVjFRkam8rkAW6zUzQT1D0fQdE8nOfWvXBgY1mH/ZLP4dDXBdG5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/html": "0.33.1",
+ "@lexical/link": "0.33.1",
+ "@lexical/mark": "0.33.1",
+ "@lexical/table": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ },
+ "peerDependencies": {
+ "react": ">=17.x",
+ "react-dom": ">=17.x"
+ }
+ },
+ "node_modules/@lexical/dragon": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.33.1.tgz",
+ "integrity": "sha512-UQ6DLkcDAr83wA1vz3sUgtcpYcMifC4sF0MieZAoMzFrna6Ekqj7OJ7g8Lo7m7AeuT4NETRVDsjIEDdrQMKLLA==",
+ "license": "MIT",
+ "dependencies": {
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/hashtag": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.33.1.tgz",
+ "integrity": "sha512-M3IsDe4cifggMBZgYAVT7hCLWcwQ3dIcUPdr9Xc6wDQQQdEqOQYB0PO//9bSYUVq+BNiiTgysc+TtlM7PiJfiw==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/history": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.33.1.tgz",
+ "integrity": "sha512-Bk0h3D6cFkJ7w3HKvqQua7n6Xfz7nR7L3gLDBH9L0nsS4MM9+LteSEZPUe0kj4VuEjnxufYstTc9HA2aNLKxnQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/html": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.33.1.tgz",
+ "integrity": "sha512-t14vu4eKa6BWz1N7/rwXgXif1k4dj73dRvllWJgfXum+a36vn1aySNYOlOfqWXF7k1b3uJmoqsWK7n/1ASnimw==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/selection": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/link": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.33.1.tgz",
+ "integrity": "sha512-JCTu7Fft2J2kgfqJiWnGei+UMIXVKiZKaXzuHCuGQTFu92DeCyd02azBaFazZHEkSqCIFZ0DqVV2SpIJmd0Ygw==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/list": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.33.1.tgz",
+ "integrity": "sha512-PXp56dWADSThc9WhwWV4vXhUc3sdtCqsfPD3UQNGUZ9rsAY1479rqYLtfYgEmYPc8JWXikQCAKEejahCJIm8OQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/selection": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/mark": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.33.1.tgz",
+ "integrity": "sha512-tGdOf1e694lnm/HyWUKEkEWjDyfhCBFG7u8iRKNpsYTpB3M1FsJUXbphE2bb8MyWfhHbaNxnklupSSaSPzO88A==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/markdown": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.33.1.tgz",
+ "integrity": "sha512-p5zwWNF70pELRx60wxE8YOFVNiNDkw7gjKoYqkED23q5hj4mcqco9fQf6qeeZChjxLKjfyT6F1PpWgxmlBlxBw==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/code": "0.33.1",
+ "@lexical/link": "0.33.1",
+ "@lexical/list": "0.33.1",
+ "@lexical/rich-text": "0.33.1",
+ "@lexical/text": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/offset": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/offset/-/offset-0.33.1.tgz",
+ "integrity": "sha512-3YIlUs43QdKSBLEfOkuciE2tn9loxVmkSs/HgaIiLYl0Edf1W00FP4ItSmYU4De5GopXsHq6+Y3ry4pU/ciUiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/overflow": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.33.1.tgz",
+ "integrity": "sha512-3BDq1lOw567FeCk4rN2ellKwoXTM9zGkGuKnSGlXS1JmtGGGSvT+uTANX3KOOfqTNSrOkrwoM+3hlFv7p6VpiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/plain-text": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.33.1.tgz",
+ "integrity": "sha512-2HxdhAx6bwF8y5A9P0q3YHsYbhUo4XXm+GyKJO87an8JClL2W+GYLTSDbfNWTh4TtH95eG+UYLOjNEgyU6tsWA==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/clipboard": "0.33.1",
+ "@lexical/selection": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/react": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/react/-/react-0.33.1.tgz",
+ "integrity": "sha512-ylnUmom5h8PY+Z14uDmKLQEoikTPN77GRM0NRCIdtbWmOQqOq/5BhuCzMZE1WvpL5C6n3GtK6IFnsMcsKmVOcw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react": "^0.27.8",
+ "@lexical/devtools-core": "0.33.1",
+ "@lexical/dragon": "0.33.1",
+ "@lexical/hashtag": "0.33.1",
+ "@lexical/history": "0.33.1",
+ "@lexical/link": "0.33.1",
+ "@lexical/list": "0.33.1",
+ "@lexical/mark": "0.33.1",
+ "@lexical/markdown": "0.33.1",
+ "@lexical/overflow": "0.33.1",
+ "@lexical/plain-text": "0.33.1",
+ "@lexical/rich-text": "0.33.1",
+ "@lexical/table": "0.33.1",
+ "@lexical/text": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "@lexical/yjs": "0.33.1",
+ "lexical": "0.33.1",
+ "react-error-boundary": "^3.1.4"
+ },
+ "peerDependencies": {
+ "react": ">=17.x",
+ "react-dom": ">=17.x"
+ }
+ },
+ "node_modules/@lexical/rich-text": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.33.1.tgz",
+ "integrity": "sha512-ZBIsj4LwmamRBCGjJiPSLj7N/XkUDv/pnYn5Rp0BL42WpOiQLvOoGLrZxgUJZEmRPQnx42ZgLKVgrWHsyjuoAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/clipboard": "0.33.1",
+ "@lexical/selection": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/selection": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.33.1.tgz",
+ "integrity": "sha512-KXPkdCDdVfIUXmkwePu9DAd3kLjL0aAqL5G9CMCFsj7RG9lLvvKk7kpivrAIbRbcsDzO44QwsFPisZHbX4ioXA==",
+ "license": "MIT",
+ "dependencies": {
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/table": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.33.1.tgz",
+ "integrity": "sha512-pzB11i1Y6fzmy0IPUKJyCdhVBgXaNOxJUxrQJWdKNYCh1eMwwMEQvj+8inItd/11aUkjcdHjwDTht8gL2UHKiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/clipboard": "0.33.1",
+ "@lexical/utils": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/text": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/text/-/text-0.33.1.tgz",
+ "integrity": "sha512-CnyU3q3RytXXWVSvC5StOKISzFAPGK9MuesNDDGyZk7yDK+J98gV6df4RBKfqwcokFMThpkUlvMeKe1+S2y25A==",
+ "license": "MIT",
+ "dependencies": {
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/utils": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.33.1.tgz",
+ "integrity": "sha512-eKysPjzEE9zD+2af3WRX5U3XbeNk0z4uv1nXGH3RG15uJ4Huzjht82hzsQpCFUobKmzYlQaQs5y2IYKE2puipQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/list": "0.33.1",
+ "@lexical/selection": "0.33.1",
+ "@lexical/table": "0.33.1",
+ "lexical": "0.33.1"
+ }
+ },
+ "node_modules/@lexical/yjs": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.33.1.tgz",
+ "integrity": "sha512-Zx1rabMm/Zjk7n7YQMIQLUN+tqzcg1xqcgNpEHSfK1GA8QMPXCPvXWFT3ZDC4tfZOSy/YIqpVUyWZAomFqRa+g==",
+ "license": "MIT",
+ "dependencies": {
+ "@lexical/offset": "0.33.1",
+ "@lexical/selection": "0.33.1",
+ "lexical": "0.33.1"
+ },
+ "peerDependencies": {
+ "yjs": ">=13.5.22"
+ }
+ },
"node_modules/@lezer/common": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
@@ -1784,414 +2299,88 @@
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
"license": "MIT"
},
- "node_modules/@milkdown/components": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/components/-/components-7.15.1.tgz",
- "integrity": "sha512-yGfjSi7VaRtiyoJA/KGVQtXpig2GYFe7uFAC6kRwskJZF/LQH/+hjjTgpPIcGn+AhKghtJ049ZXnJkgFU45YYA==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.5.1",
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/plugin-tooltip": "7.15.1",
- "@milkdown/preset-commonmark": "7.15.1",
- "@milkdown/preset-gfm": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/transformer": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "@types/lodash.debounce": "^4.0.7",
- "@types/lodash.throttle": "^4.1.9",
- "clsx": "^2.0.0",
- "dompurify": "^3.2.5",
- "lodash.debounce": "^4.0.8",
- "lodash.throttle": "^4.1.1",
- "nanoid": "^5.0.9",
- "tslib": "^2.8.1",
- "unist-util-visit": "^5.0.0",
- "vue": "^3.5.13"
- },
- "peerDependencies": {
- "@codemirror/language": "^6",
- "@codemirror/state": "^6",
- "@codemirror/view": "^6"
- }
- },
- "node_modules/@milkdown/components/node_modules/nanoid": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
- "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.js"
- },
- "engines": {
- "node": "^18 || >=20"
- }
- },
- "node_modules/@milkdown/core": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/core/-/core-7.15.1.tgz",
- "integrity": "sha512-jcuKZnZ9rrffwpAFq+0pMIwfxnchZOCFSIQT7NQnsOhzFXnCNXu69cxzlcK3CZExDgkmivHM62xFsjN9l7vTdg==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/transformer": "7.15.1",
- "remark-parse": "^11.0.0",
- "remark-stringify": "^11.0.0",
- "tslib": "^2.8.1",
- "unified": "^11.0.3"
- }
- },
- "node_modules/@milkdown/crepe": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/crepe/-/crepe-7.15.1.tgz",
- "integrity": "sha512-2n63s4vBzTO0IBTO/nIsS/XKyPIpOXjiIwXgkIXkbzNt/sPA6hEwtvEJDCz7uzRo/MCxZu0jLjPW/OpVMakLNg==",
+ "node_modules/@mdxeditor/editor": {
+ "version": "3.42.0",
+ "resolved": "https://registry.npmjs.org/@mdxeditor/editor/-/editor-3.42.0.tgz",
+ "integrity": "sha512-nQN07RkTm842T477IjPqp1FhWCQMpmbLToOVrc6EjSI60aHifwzva+eqYmElHFKE2jyGiD5FsaQXri1SSORJNg==",
"license": "MIT",
"dependencies": {
"@codemirror/commands": "^6.2.4",
- "@codemirror/language": "^6.10.1",
- "@codemirror/language-data": "^6.3.1",
- "@codemirror/state": "^6.4.1",
- "@codemirror/theme-one-dark": "^6.1.2",
- "@codemirror/view": "^6.16.0",
- "@floating-ui/dom": "^1.5.1",
- "@milkdown/kit": "7.15.1",
- "@types/lodash-es": "^4.17.12",
- "clsx": "^2.0.0",
+ "@codemirror/lang-markdown": "^6.2.3",
+ "@codemirror/language-data": "^6.5.1",
+ "@codemirror/merge": "^6.4.0",
+ "@codemirror/state": "^6.4.0",
+ "@codemirror/view": "^6.23.0",
+ "@codesandbox/sandpack-react": "^2.20.0",
+ "@lexical/clipboard": "^0.33.1",
+ "@lexical/link": "^0.33.1",
+ "@lexical/list": "^0.33.1",
+ "@lexical/markdown": "^0.33.1",
+ "@lexical/plain-text": "^0.33.1",
+ "@lexical/react": "^0.33.1",
+ "@lexical/rich-text": "^0.33.1",
+ "@lexical/selection": "^0.33.1",
+ "@lexical/utils": "^0.33.1",
+ "@mdxeditor/gurx": "^1.1.4",
+ "@radix-ui/colors": "^3.0.0",
+ "@radix-ui/react-dialog": "^1.1.11",
+ "@radix-ui/react-icons": "^1.3.2",
+ "@radix-ui/react-popover": "^1.1.11",
+ "@radix-ui/react-popper": "^1.2.4",
+ "@radix-ui/react-select": "^2.2.2",
+ "@radix-ui/react-toggle-group": "^1.1.7",
+ "@radix-ui/react-toolbar": "^1.1.7",
+ "@radix-ui/react-tooltip": "^1.2.4",
+ "classnames": "^2.3.2",
+ "cm6-theme-basic-light": "^0.2.0",
"codemirror": "^6.0.1",
- "katex": "^0.16.0",
- "lodash-es": "^4.17.21",
- "nanoid": "^5.0.9",
- "prosemirror-virtual-cursor": "^0.4.2",
- "remark-math": "^6.0.0",
- "tslib": "^2.8.1",
- "unist-util-visit": "^5.0.0",
- "vue": "^3.5.13"
- }
- },
- "node_modules/@milkdown/crepe/node_modules/nanoid": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
- "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.js"
+ "downshift": "^7.6.0",
+ "js-yaml": "4.1.0",
+ "lexical": "^0.33.1",
+ "mdast-util-directive": "^3.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-frontmatter": "^2.0.1",
+ "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-highlight-mark": "^1.2.2",
+ "mdast-util-mdx": "^3.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-to-markdown": "^2.1.0",
+ "micromark-extension-directive": "^3.0.0",
+ "micromark-extension-frontmatter": "^2.0.0",
+ "micromark-extension-gfm-strikethrough": "^2.0.0",
+ "micromark-extension-gfm-table": "^2.0.0",
+ "micromark-extension-gfm-task-list-item": "^2.0.1",
+ "micromark-extension-highlight-mark": "^1.2.0",
+ "micromark-extension-mdx-jsx": "^3.0.0",
+ "micromark-extension-mdx-md": "^2.0.0",
+ "micromark-extension-mdxjs": "^3.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.1",
+ "micromark-util-symbol": "^2.0.0",
+ "react-hook-form": "^7.56.1",
+ "unidiff": "^1.0.2"
},
"engines": {
- "node": "^18 || >=20"
- }
- },
- "node_modules/@milkdown/ctx": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/ctx/-/ctx-7.15.1.tgz",
- "integrity": "sha512-MO2EymuAmcT9TVcbZVr0TriFMAPP1d1p/cWVbyqZXKsxK1sRzNxJCpdPm20LD2e2qJt6pRziIf/ugGww1Tvf7A==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/exception": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/exception": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/exception/-/exception-7.15.1.tgz",
- "integrity": "sha512-QMpT/8SYM1CIuptHrOKzaelZd4ZU1j9mz3m2EwF4Ql0PNOXoWW50/P7gtr71foyTu3fPyXA9f8/GaTkihD/b/Q==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/kit": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/kit/-/kit-7.15.1.tgz",
- "integrity": "sha512-wmUt9mN+rfJgCz11c3z2E8ExIKhd2QLdFPCPb8OHamebsf+td5nS0HX2vpvkaumgD4AQA0KCbMs9WmqChG/K7w==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/components": "7.15.1",
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/plugin-block": "7.15.1",
- "@milkdown/plugin-clipboard": "7.15.1",
- "@milkdown/plugin-cursor": "7.15.1",
- "@milkdown/plugin-history": "7.15.1",
- "@milkdown/plugin-indent": "7.15.1",
- "@milkdown/plugin-listener": "7.15.1",
- "@milkdown/plugin-slash": "7.15.1",
- "@milkdown/plugin-tooltip": "7.15.1",
- "@milkdown/plugin-trailing": "7.15.1",
- "@milkdown/plugin-upload": "7.15.1",
- "@milkdown/preset-commonmark": "7.15.1",
- "@milkdown/preset-gfm": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/transformer": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-block": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-block/-/plugin-block-7.15.1.tgz",
- "integrity": "sha512-ltftyP6brSs5N3q9mJhcauqfuDuGIGm2dsXwpibsRsO8WbCptVpQPjHCNGJp+/Y+bLrRas5DAz+cqFvfDvCDYA==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.5.1",
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "@types/lodash.throttle": "^4.1.9",
- "lodash.throttle": "^4.1.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-clipboard": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-clipboard/-/plugin-clipboard-7.15.1.tgz",
- "integrity": "sha512-mtq+CQhuCR/bVKHep588OsrIHxQAve85VHIPHPaU768c6jkQhGlr82a0bp90hhzTMREWDqxsFrJAxPM+PDtugA==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-cursor": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-cursor/-/plugin-cursor-7.15.1.tgz",
- "integrity": "sha512-HZloO+PpoXvdf854aflIA1pq5cmoRHNvaiC3QCeywAz6y0EHFr0NSJRQQZwXIefdbi5l/CP/lkc9dJJotzgEng==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-history": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-history/-/plugin-history-7.15.1.tgz",
- "integrity": "sha512-2LkYbZYuix7LUI/sR1NQO5oZOjcT9E6wJhDHcMmeO8XoIO6r0q8STdH7jvITkB/Rr9wNRXfI+V86hvsfB0aMbw==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-indent": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-indent/-/plugin-indent-7.15.1.tgz",
- "integrity": "sha512-D3asSTw6Jvyn3TRVOGNNwhslL0OgnU0Fi9G1JOt9nsaqDIuTMQQhapJzr3VCZn1ko9hdlYUKBQnPkAXngNZKjg==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-listener": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-listener/-/plugin-listener-7.15.1.tgz",
- "integrity": "sha512-lnpFzAmhJK0+No0R4utWNx31cDunBqkdBGMBbV6571SHgfVIHw/T8z64t8Fo7xNt9OjcgKee877tk6TaL98HiQ==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "@types/lodash.debounce": "^4.0.7",
- "lodash.debounce": "^4.0.8",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-slash": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-slash/-/plugin-slash-7.15.1.tgz",
- "integrity": "sha512-b/wvpr7+hRgNsftu3XbUMHEKOKUSdNN+HXMhTqTIheB/m/Y7zSdPL3kXMQC1ZRwHyDu1oL6lUuMCMCJ8cDiMvg==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.5.1",
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "@types/lodash.debounce": "^4.0.7",
- "lodash.debounce": "^4.0.8",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-tooltip": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-tooltip/-/plugin-tooltip-7.15.1.tgz",
- "integrity": "sha512-Q/TwzqM4CRSTmz0+E/amtNTgk7DJpAOjjCR4am02N2HbYP7GcL92mC1pEx//tus1AW9+LOdF+cmWyObHGkC7Vg==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.5.1",
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "@types/lodash.throttle": "^4.1.9",
- "lodash.throttle": "^4.1.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-trailing": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-trailing/-/plugin-trailing-7.15.1.tgz",
- "integrity": "sha512-zsECiNOMta4bIy+4a+BplmMwWfrhy3SYcm1kH6DjvkpoBG6LtZC4fblEnlW4feHzDwXVLHkbac5urR4rsZxLcA==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/plugin-upload": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/plugin-upload/-/plugin-upload-7.15.1.tgz",
- "integrity": "sha512-9sU2GRERc7lhQ8mSANZ3v1531pmVRImJx4Pr73oB7VPRDS8GbnhtuVI6VewoVh3zJkM8MSE4G4L/TfWXfa2UGQ==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/preset-commonmark": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/preset-commonmark/-/preset-commonmark-7.15.1.tgz",
- "integrity": "sha512-P1dewR9TGe8VFIE5F+W9g/2QQzf47EZ+Uq4CF5mYAFbjzPHwJDgfN4vA/o43feXFNxu5cm4UQFWzSCtDNZFTWg==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/transformer": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "remark-inline-links": "^7.0.0",
- "tslib": "^2.8.1",
- "unist-util-visit": "^5.0.0",
- "unist-util-visit-parents": "^6.0.1"
- }
- },
- "node_modules/@milkdown/preset-gfm": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/preset-gfm/-/preset-gfm-7.15.1.tgz",
- "integrity": "sha512-cmQsx1lwWGi7vv/8Kx92dToWpqKWLDp5OZSWE0eiLCtAV87v+vL/bT6xDrjqmlpFjA5WEM7ah+Ki3EpqLsRfng==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/preset-commonmark": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/transformer": "7.15.1",
- "@milkdown/utils": "7.15.1",
- "prosemirror-safari-ime-span": "^1.0.1",
- "remark-gfm": "^4.0.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/prose": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/prose/-/prose-7.15.1.tgz",
- "integrity": "sha512-8xSgiC6qk8j9zDbRZiWcdclr4vIxU6tnzMBg/Kr4pIEOsir0KA+c6kPNFj7T91BeaV9ksCsWOmYfBwd2SptCXQ==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/exception": "7.15.1",
- "prosemirror-changeset": "^2.2.1",
- "prosemirror-commands": "^1.6.2",
- "prosemirror-dropcursor": "^1.8.1",
- "prosemirror-gapcursor": "^1.3.2",
- "prosemirror-history": "^1.4.1",
- "prosemirror-inputrules": "^1.4.0",
- "prosemirror-keymap": "^1.2.2",
- "prosemirror-model": "^1.24.1",
- "prosemirror-schema-list": "^1.5.0",
- "prosemirror-state": "^1.4.3",
- "prosemirror-tables": "^1.7.0",
- "prosemirror-transform": "^1.10.2",
- "prosemirror-view": "^1.37.1",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/transformer": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/transformer/-/transformer-7.15.1.tgz",
- "integrity": "sha512-Hwp0swHmvN2D6iM67mnoP7wPeiDipz/GDdyO7CfnYjUsUQcRHzMouoqJ91dp9bO+f4EJ0Vr+8C1qIYRAn4ZDhA==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "remark": "^15.0.1",
- "remark-parse": "^11.0.0",
- "remark-stringify": "^11.0.0",
- "tslib": "^2.8.1",
- "unified": "^11.0.3"
- }
- },
- "node_modules/@milkdown/utils": {
- "version": "7.15.1",
- "resolved": "https://registry.npmjs.org/@milkdown/utils/-/utils-7.15.1.tgz",
- "integrity": "sha512-CvApKO84xdIGOUqvVeyDKRyN+PYqi8WNC9im7YWis2EojaSEleX7GMVOoWUHcB8xSdyuY+yJzPguMsx3QKuHIg==",
- "license": "MIT",
- "dependencies": {
- "@milkdown/core": "7.15.1",
- "@milkdown/ctx": "7.15.1",
- "@milkdown/exception": "7.15.1",
- "@milkdown/prose": "7.15.1",
- "@milkdown/transformer": "7.15.1",
- "nanoid": "^5.0.9",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@milkdown/utils/node_modules/nanoid": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
- "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.js"
+ "node": ">=16"
},
+ "peerDependencies": {
+ "react": ">= 18 || >= 19",
+ "react-dom": ">= 18 || >= 19"
+ }
+ },
+ "node_modules/@mdxeditor/gurx": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@mdxeditor/gurx/-/gurx-1.2.3.tgz",
+ "integrity": "sha512-5DQOlEx46oN9spggrC8husAGAhVoEFBGIYKN48es08XhRUbSU6l5bcIQYwRrQaY8clU1tExIcXzw8/fNnoxjpg==",
+ "license": "MIT",
"engines": {
- "node": "^18 || >=20"
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "react": ">= 18 || >= 19",
+ "react-dom": ">= 18 || >= 19"
}
},
"node_modules/@nodelib/fs.scandir": {
@@ -2232,6 +2421,12 @@
"node": ">= 8"
}
},
+ "node_modules/@open-draft/deferred-promise": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz",
+ "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==",
+ "license": "MIT"
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -2250,6 +2445,946 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@radix-ui/colors": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz",
+ "integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/number": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
+ "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/primitive": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
+ "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-alert-dialog": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz",
+ "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dialog": "1.1.15",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
+ "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collection": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
+ "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz",
+ "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
+ "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
+ "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-escape-keydown": "1.1.1"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dropdown-menu": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz",
+ "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-menu": "2.1.16",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
+ "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
+ "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-icons": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz",
+ "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
+ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-menu": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz",
+ "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-popper": "1.2.8",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-roving-focus": "1.1.11",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz",
+ "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-popper": "1.2.8",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popper": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
+ "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-layout-effect": "1.1.1",
+ "@radix-ui/react-use-rect": "1.1.1",
+ "@radix-ui/react-use-size": "1.1.1",
+ "@radix-ui/rect": "1.1.1"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-portal": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
+ "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
+ "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
+ "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
+ "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/number": "1.1.1",
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-focus-guards": "1.1.3",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-popper": "1.2.8",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1",
+ "@radix-ui/react-use-previous": "1.1.1",
+ "@radix-ui/react-visually-hidden": "1.2.3",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-separator": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz",
+ "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz",
+ "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-roving-focus": "1.1.11",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toast": {
+ "version": "1.2.15",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz",
+ "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-collection": "1.1.7",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1",
+ "@radix-ui/react-visually-hidden": "1.2.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz",
+ "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle-group": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz",
+ "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-roving-focus": "1.1.11",
+ "@radix-ui/react-toggle": "1.1.10",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toolbar": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.1.11.tgz",
+ "integrity": "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-roving-focus": "1.1.11",
+ "@radix-ui/react-separator": "1.1.7",
+ "@radix-ui/react-toggle-group": "1.1.11"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tooltip": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz",
+ "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.3",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.11",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-popper": "1.2.8",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.5",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "@radix-ui/react-visually-hidden": "1.2.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
+ "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
+ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-effect-event": "0.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-effect-event": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
+ "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
+ "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-previous": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
+ "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-rect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz",
+ "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/rect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
+ "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-visually-hidden": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz",
+ "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/@radix-ui/rect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz",
+ "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
+ "license": "MIT"
+ },
"node_modules/@react-dnd/asap": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
@@ -2268,6 +3403,28 @@
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==",
"license": "MIT"
},
+ "node_modules/@react-hook/intersection-observer": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@react-hook/intersection-observer/-/intersection-observer-3.1.2.tgz",
+ "integrity": "sha512-mWU3BMkmmzyYMSuhO9wu3eJVP21N8TcgYm9bZnTrMwuM818bEk+0NRM3hP+c/TqA9Ln5C7qE53p1H0QMtzYdvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-hook/passive-layout-effect": "^1.2.0",
+ "intersection-observer": "^0.10.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/@react-hook/passive-layout-effect": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz",
+ "integrity": "sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
"node_modules/@remix-run/router": {
"version": "1.23.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
@@ -2571,6 +3728,65 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@stitches/core": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz",
+ "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==",
+ "license": "MIT"
+ },
+ "node_modules/@tanstack/query-core": {
+ "version": "5.85.7",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.85.7.tgz",
+ "integrity": "sha512-FLT3EtuTbXBmOrDku4bI80Eivmjn/o/Zc1lVEd/6yzR8UAUSnDwYiwghCZvLqHyGSN5mO35ux1yPGMFYBFRSwA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/query-devtools": {
+ "version": "5.84.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.84.0.tgz",
+ "integrity": "sha512-fbF3n+z1rqhvd9EoGp5knHkv3p5B2Zml1yNRjh7sNXklngYI5RVIWUrUjZ1RIcEoscarUb0+bOvIs5x9dwzOXQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.85.8",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.85.8.tgz",
+ "integrity": "sha512-r3rW55STAO03EJg5mrCVIJvaEK3oeHme5u7QovuRFIKRbEgTzTv2DPdenX46X+x56LsU3ree1N4rzI/+gJ7KEA==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.85.7"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "node_modules/@tanstack/react-query-devtools": {
+ "version": "5.85.8",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.85.8.tgz",
+ "integrity": "sha512-83SXqRpmVlRMpaj32veez/8ohjY7O4VQIYDqW91b4i9AQjiYgE24FbBfR/SOL8b5MfKhHMZkD+BQSpCh9jY06w==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-devtools": "5.84.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "@tanstack/react-query": "^5.85.8",
+ "react": "^18 || ^19"
+ }
+ },
"node_modules/@testing-library/dom": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
@@ -2777,55 +3993,6 @@
"@babel/types": "^7.20.7"
}
},
- "node_modules/@types/d3-color": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
- "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
- "license": "MIT"
- },
- "node_modules/@types/d3-drag": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz",
- "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
- "license": "MIT",
- "dependencies": {
- "@types/d3-selection": "*"
- }
- },
- "node_modules/@types/d3-interpolate": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
- "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
- "license": "MIT",
- "dependencies": {
- "@types/d3-color": "*"
- }
- },
- "node_modules/@types/d3-selection": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz",
- "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==",
- "license": "MIT"
- },
- "node_modules/@types/d3-transition": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz",
- "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
- "license": "MIT",
- "dependencies": {
- "@types/d3-selection": "*"
- }
- },
- "node_modules/@types/d3-zoom": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
- "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
- "license": "MIT",
- "dependencies": {
- "@types/d3-interpolate": "*",
- "@types/d3-selection": "*"
- }
- },
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
@@ -2839,9 +4006,17 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
- "dev": true,
"license": "MIT"
},
+ "node_modules/@types/estree-jsx": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
+ "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
"node_modules/@types/hast": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
@@ -2858,45 +4033,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/katex": {
- "version": "0.16.7",
- "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
- "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==",
- "license": "MIT"
- },
- "node_modules/@types/lodash": {
- "version": "4.17.20",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz",
- "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==",
- "license": "MIT"
- },
- "node_modules/@types/lodash-es": {
- "version": "4.17.12",
- "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
- "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
- "license": "MIT",
- "dependencies": {
- "@types/lodash": "*"
- }
- },
- "node_modules/@types/lodash.debounce": {
- "version": "4.0.9",
- "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz",
- "integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==",
- "license": "MIT",
- "dependencies": {
- "@types/lodash": "*"
- }
- },
- "node_modules/@types/lodash.throttle": {
- "version": "4.1.9",
- "resolved": "https://registry.npmjs.org/@types/lodash.throttle/-/lodash.throttle-4.1.9.tgz",
- "integrity": "sha512-PCPVfpfueguWZQB7pJQK890F2scYKoDUL3iM522AptHWn7d5NQmeS/LTEHIcLr5PaTzl3dK2Z0xSUHHTHwaL5g==",
- "license": "MIT",
- "dependencies": {
- "@types/lodash": "*"
- }
- },
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -2926,14 +4062,12 @@
"version": "15.7.14",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
"integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
- "devOptional": true,
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.23",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
"integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
@@ -2944,26 +4078,19 @@
"version": "18.3.7",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
"integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "^18.0.0"
}
},
"node_modules/@types/semver": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
- "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==",
"dev": true,
"license": "MIT"
},
- "node_modules/@types/trusted-types": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
- "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
- "license": "MIT",
- "optional": true
- },
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -2971,33 +4098,34 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
- "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+ "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@eslint-community/regexpp": "^4.4.0",
- "@typescript-eslint/scope-manager": "5.62.0",
- "@typescript-eslint/type-utils": "5.62.0",
- "@typescript-eslint/utils": "5.62.0",
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/type-utils": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
- "ignore": "^5.2.0",
- "natural-compare-lite": "^1.4.0",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^5.0.0",
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -3006,26 +4134,27 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
- "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/scope-manager": "5.62.0",
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/typescript-estree": "5.62.0",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -3034,17 +4163,17 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
- "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/visitor-keys": "5.62.0"
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -3052,26 +4181,26 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
- "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+ "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "5.62.0",
- "@typescript-eslint/utils": "5.62.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
"debug": "^4.3.4",
- "tsutils": "^3.21.0"
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "*"
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -3080,13 +4209,13 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
- "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -3094,22 +4223,23 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
- "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/visitor-keys": "5.62.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -3121,45 +4251,70 @@
}
}
},
- "node_modules/@typescript-eslint/utils": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
- "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@types/json-schema": "^7.0.9",
- "@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.62.0",
- "@typescript-eslint/types": "5.62.0",
- "@typescript-eslint/typescript-estree": "5.62.0",
- "eslint-scope": "^5.1.1",
- "semver": "^7.3.7"
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.62.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
- "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "5.62.0",
- "eslint-visitor-keys": "^3.3.0"
+ "@typescript-eslint/types": "6.21.0",
+ "eslint-visitor-keys": "^3.4.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -3170,7 +4325,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
- "dev": true,
"license": "ISC"
},
"node_modules/@vitejs/plugin-react": {
@@ -3417,165 +4571,10 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@vue/compiler-core": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.18.tgz",
- "integrity": "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.28.0",
- "@vue/shared": "3.5.18",
- "entities": "^4.5.0",
- "estree-walker": "^2.0.2",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/@vue/compiler-core/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/@vue/compiler-core/node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "license": "MIT"
- },
- "node_modules/@vue/compiler-dom": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz",
- "integrity": "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-core": "3.5.18",
- "@vue/shared": "3.5.18"
- }
- },
- "node_modules/@vue/compiler-sfc": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz",
- "integrity": "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.28.0",
- "@vue/compiler-core": "3.5.18",
- "@vue/compiler-dom": "3.5.18",
- "@vue/compiler-ssr": "3.5.18",
- "@vue/shared": "3.5.18",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.30.17",
- "postcss": "^8.5.6",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "license": "MIT"
- },
- "node_modules/@vue/compiler-ssr": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz",
- "integrity": "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-dom": "3.5.18",
- "@vue/shared": "3.5.18"
- }
- },
- "node_modules/@vue/reactivity": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.18.tgz",
- "integrity": "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg==",
- "license": "MIT",
- "dependencies": {
- "@vue/shared": "3.5.18"
- }
- },
- "node_modules/@vue/runtime-core": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.18.tgz",
- "integrity": "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w==",
- "license": "MIT",
- "dependencies": {
- "@vue/reactivity": "3.5.18",
- "@vue/shared": "3.5.18"
- }
- },
- "node_modules/@vue/runtime-dom": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz",
- "integrity": "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw==",
- "license": "MIT",
- "dependencies": {
- "@vue/reactivity": "3.5.18",
- "@vue/runtime-core": "3.5.18",
- "@vue/shared": "3.5.18",
- "csstype": "^3.1.3"
- }
- },
- "node_modules/@vue/server-renderer": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.18.tgz",
- "integrity": "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-ssr": "3.5.18",
- "@vue/shared": "3.5.18"
- },
- "peerDependencies": {
- "vue": "3.5.18"
- }
- },
- "node_modules/@vue/shared": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz",
- "integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==",
- "license": "MIT"
- },
- "node_modules/@xyflow/react": {
- "version": "12.6.4",
- "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.6.4.tgz",
- "integrity": "sha512-/dOQ43Nu217cwHzy7f8kNUrFMeJJENzftVgT2VdFFHi6fHlG83pF+gLmvkRW9Be7alCsR6G+LFxxCdsQQbazHg==",
- "license": "MIT",
- "dependencies": {
- "@xyflow/system": "0.0.61",
- "classcat": "^5.0.3",
- "zustand": "^4.4.0"
- },
- "peerDependencies": {
- "react": ">=17",
- "react-dom": ">=17"
- }
- },
- "node_modules/@xyflow/system": {
- "version": "0.0.61",
- "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.61.tgz",
- "integrity": "sha512-TsZG/Ez8dzxX6/Ol44LvFqVZsYvyz6dpDlAQZZk6hTL7JLGO5vN3dboRJqMwU8/Qtr5IEv5YBzojjAwIqW1HCA==",
- "license": "MIT",
- "dependencies": {
- "@types/d3-drag": "^3.0.7",
- "@types/d3-selection": "^3.0.10",
- "@types/d3-transition": "^3.0.8",
- "@types/d3-zoom": "^3.0.8",
- "d3-drag": "^3.0.0",
- "d3-selection": "^3.0.0",
- "d3-zoom": "^3.0.0"
- }
- },
"node_modules/acorn": {
- "version": "8.14.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
- "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
- "dev": true,
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -3588,7 +4587,6 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
"license": "MIT",
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -3634,6 +4632,12 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/anser": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/anser/-/anser-2.3.2.tgz",
+ "integrity": "sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==",
+ "license": "MIT"
+ },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -3692,9 +4696,20 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
"license": "Python-2.0"
},
+ "node_modules/aria-hidden": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
+ "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/aria-query": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
@@ -3820,6 +4835,26 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
@@ -3890,6 +4925,30 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -4047,6 +5106,36 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/check-error": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
@@ -4098,10 +5187,16 @@
"node": ">= 6"
}
},
- "node_modules/classcat": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz",
- "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==",
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
+ "license": "MIT"
+ },
+ "node_modules/clean-set": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/clean-set/-/clean-set-1.1.2.tgz",
+ "integrity": "sha512-cA8uCj0qSoG9e0kevyOWXwPaELRPVg5Pxp6WskLMwerx257Zfnh8Nl0JBH59d7wQzij2CK7qEfJQK3RjuKKIug==",
"license": "MIT"
},
"node_modules/clsx": {
@@ -4113,6 +5208,18 @@
"node": ">=6"
}
},
+ "node_modules/cm6-theme-basic-light": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/cm6-theme-basic-light/-/cm6-theme-basic-light-0.2.0.tgz",
+ "integrity": "sha512-1prg2gv44sYfpHscP26uLT/ePrh0mlmVwMSoSd3zYKQ92Ab3jPRLzyCnpyOCQLJbK+YdNs4HvMRqMNYdy4pMhA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@codemirror/language": "^6.0.0",
+ "@codemirror/state": "^6.0.0",
+ "@codemirror/view": "^6.0.0",
+ "@lezer/highlight": "^1.0.0"
+ }
+ },
"node_modules/codemirror": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz",
@@ -4161,6 +5268,16 @@
"node": ">= 0.8"
}
},
+ "node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@@ -4171,6 +5288,12 @@
"node": ">= 6"
}
},
+ "node_modules/compute-scroll-into-view": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-2.0.4.tgz",
+ "integrity": "sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g==",
+ "license": "MIT"
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -4267,109 +5390,17 @@
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
- "node_modules/d3-color": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
- "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/d3-dispatch": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
- "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/d3-drag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
- "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
+ "node_modules/d": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
+ "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
"license": "ISC",
"dependencies": {
- "d3-dispatch": "1 - 3",
- "d3-selection": "3"
+ "es5-ext": "^0.10.64",
+ "type": "^2.7.2"
},
"engines": {
- "node": ">=12"
- }
- },
- "node_modules/d3-ease": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
- "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/d3-interpolate": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
- "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
- "license": "ISC",
- "dependencies": {
- "d3-color": "1 - 3"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/d3-selection": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
- "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/d3-timer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
- "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/d3-transition": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
- "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
- "license": "ISC",
- "dependencies": {
- "d3-color": "1 - 3",
- "d3-dispatch": "1 - 3",
- "d3-ease": "1 - 3",
- "d3-interpolate": "1 - 3",
- "d3-timer": "1 - 3"
- },
- "engines": {
- "node": ">=12"
- },
- "peerDependencies": {
- "d3-selection": "2 - 3"
- }
- },
- "node_modules/d3-zoom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
- "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
- "license": "ISC",
- "dependencies": {
- "d3-dispatch": "1 - 3",
- "d3-drag": "2 - 3",
- "d3-interpolate": "1 - 3",
- "d3-selection": "2 - 3",
- "d3-transition": "2 - 3"
- },
- "engines": {
- "node": ">=12"
+ "node": ">=0.12"
}
},
"node_modules/data-urls": {
@@ -4541,6 +5572,12 @@
"node": ">=6"
}
},
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
+ "license": "MIT"
+ },
"node_modules/devlop": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
@@ -4632,13 +5669,32 @@
"dev": true,
"license": "MIT"
},
- "node_modules/dompurify": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz",
- "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==",
- "license": "(MPL-2.0 OR Apache-2.0)",
- "optionalDependencies": {
- "@types/trusted-types": "^2.0.7"
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/downshift": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/downshift/-/downshift-7.6.2.tgz",
+ "integrity": "sha512-iOv+E1Hyt3JDdL9yYcOgW7nZ7GQ2Uz6YbggwXvKUSleetYhU2nXD482Rz6CzvM4lvI1At34BYruKAL4swRGxaA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.14.8",
+ "compute-scroll-into-view": "^2.0.4",
+ "prop-types": "^15.7.2",
+ "react-is": "^17.0.2",
+ "tslib": "^2.3.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.12.0"
}
},
"node_modules/dunder-proto": {
@@ -4760,6 +5816,46 @@
"node": ">= 0.4"
}
},
+ "node_modules/es5-ext": {
+ "version": "0.10.64",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
+ "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
+ "hasInstallScript": true,
+ "license": "ISC",
+ "dependencies": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "esniff": "^2.0.1",
+ "next-tick": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+ "license": "MIT",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "node_modules/es6-symbol": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
+ "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
+ "license": "ISC",
+ "dependencies": {
+ "d": "^1.0.2",
+ "ext": "^1.7.0"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
"node_modules/esbuild": {
"version": "0.21.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
@@ -4809,6 +5905,12 @@
"node": ">=6"
}
},
+ "node_modules/escape-carriage": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/escape-carriage/-/escape-carriage-1.3.1.tgz",
+ "integrity": "sha512-GwBr6yViW3ttx1kb7/Oh+gKQ1/TrhYwxKqVmg5gS+BK+Qe2KrOa/Vh7w3HPBvgGf0LfcDGoY9I6NHKoA5Hozhw==",
+ "license": "MIT"
+ },
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -4903,33 +6005,6 @@
}
},
"node_modules/eslint-scope": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
- "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^4.1.1"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/eslint-scope": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
@@ -4946,14 +6021,17 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint/node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "Apache-2.0",
"engines": {
- "node": ">=4.0"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/globals": {
@@ -4972,6 +6050,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/esniff": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
+ "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
+ "license": "ISC",
+ "dependencies": {
+ "d": "^1.0.1",
+ "es5-ext": "^0.10.62",
+ "event-emitter": "^0.3.5",
+ "type": "^2.7.2"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/espree": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
@@ -5003,16 +6096,6 @@
"node": ">=0.10"
}
},
- "node_modules/esquery/node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
- }
- },
"node_modules/esrecurse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
@@ -5026,7 +6109,7 @@
"node": ">=4.0"
}
},
- "node_modules/esrecurse/node_modules/estraverse": {
+ "node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
@@ -5036,14 +6119,28 @@
"node": ">=4.0"
}
},
- "node_modules/estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
+ "node_modules/estree-util-is-identifier-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
+ "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/estree-util-visit": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz",
+ "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
}
},
"node_modules/estree-walker": {
@@ -5066,6 +6163,16 @@
"node": ">=0.10.0"
}
},
+ "node_modules/event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+ "license": "MIT",
+ "dependencies": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
"node_modules/execa": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
@@ -5090,6 +6197,15 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
+ "node_modules/ext": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+ "license": "ISC",
+ "dependencies": {
+ "type": "^2.7.2"
+ }
+ },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -5156,6 +6272,19 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fault": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz",
+ "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "format": "^0.2.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/fflate": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
@@ -5277,6 +6406,14 @@
"node": ">= 6"
}
},
+ "node_modules/format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
"node_modules/fraction.js": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
@@ -5414,6 +6551,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
@@ -5605,6 +6751,46 @@
"node": ">= 0.4"
}
},
+ "node_modules/hast-util-to-jsx-runtime": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
+ "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-is-identifier-name": "^3.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "mdast-util-mdx-expression": "^2.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-mdxjs-esm": "^2.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "style-to-js": "^1.0.0",
+ "unist-util-position": "^5.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -5640,6 +6826,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/html-url-attributes": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
+ "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -5691,6 +6887,26 @@
"node": ">=0.10.0"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -5757,6 +6973,12 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/inline-style-parser": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz",
+ "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
+ "license": "MIT"
+ },
"node_modules/internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
@@ -5772,6 +6994,36 @@
"node": ">= 0.4"
}
},
+ "node_modules/intersection-observer": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.10.0.tgz",
+ "integrity": "sha512-fn4bQ0Xq8FTej09YC/jqKZwtijpvARlRp6wxL5WTA6yPe2YWSJ5RJh7Nm79rK2qB0wr6iDQzH60XGq5V/7u8YQ==",
+ "license": "W3C-20150513"
+ },
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-arguments": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
@@ -5899,6 +7151,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -5932,6 +7194,16 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-map": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
@@ -6141,6 +7413,17 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/isomorphic.js": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz",
+ "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==",
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "type": "GitHub Sponsors ❤",
+ "url": "https://github.com/sponsors/dmonad"
+ }
+ },
"node_modules/istanbul-lib-coverage": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
@@ -6231,7 +7514,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -6328,31 +7610,6 @@
"node": ">=6"
}
},
- "node_modules/katex": {
- "version": "0.16.22",
- "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz",
- "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==",
- "funding": [
- "https://opencollective.com/katex",
- "https://github.com/sponsors/katex"
- ],
- "license": "MIT",
- "dependencies": {
- "commander": "^8.3.0"
- },
- "bin": {
- "katex": "cli.js"
- }
- },
- "node_modules/katex/node_modules/commander": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
- "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -6363,6 +7620,15 @@
"json-buffer": "3.0.1"
}
},
+ "node_modules/kleur": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -6377,6 +7643,34 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lexical": {
+ "version": "0.33.1",
+ "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.33.1.tgz",
+ "integrity": "sha512-+kiCS/GshQmCs/meMb8MQT4AMvw3S3Ef0lSCv2Xi6Itvs59OD+NjQWNfYkDteIbKtVE/w0Yiqh56VyGwIb8UcA==",
+ "license": "MIT"
+ },
+ "node_modules/lib0": {
+ "version": "0.2.114",
+ "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.114.tgz",
+ "integrity": "sha512-gcxmNFzA4hv8UYi8j43uPlQ7CGcyMJ2KQb5kZASw6SnAKAf10hK12i2fjrS3Cl/ugZa5Ui6WwIu1/6MIXiHttQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "isomorphic.js": "^0.2.4"
+ },
+ "bin": {
+ "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js",
+ "0gentesthtml": "bin/gentesthtml.js",
+ "0serve": "bin/0serve.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "GitHub Sponsors ❤",
+ "url": "https://github.com/sponsors/dmonad"
+ }
+ },
"node_modules/lilconfig": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
@@ -6437,18 +7731,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lodash-es": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
- "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
- "license": "MIT"
- },
- "node_modules/lodash.debounce": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
- "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
- "license": "MIT"
- },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -6456,12 +7738,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lodash.throttle": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
- "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
- "license": "MIT"
- },
"node_modules/longest-streak": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
@@ -6517,7 +7793,6 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
- "dev": true,
"license": "MIT",
"bin": {
"lz-string": "bin/bin.js"
@@ -6527,6 +7802,7 @@
"version": "0.30.17",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
"integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0"
@@ -6587,30 +7863,20 @@
"node": ">= 0.4"
}
},
- "node_modules/mdast-util-definitions": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz",
- "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==",
+ "node_modules/mdast-util-directive": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz",
+ "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
"@types/unist": "^3.0.0",
- "unist-util-visit": "^5.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-find-and-replace": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz",
- "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "escape-string-regexp": "^5.0.0",
- "unist-util-is": "^6.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
"unist-util-visit-parents": "^6.0.0"
},
"funding": {
@@ -6618,18 +7884,6 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
- "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/mdast-util-from-markdown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
@@ -6654,59 +7908,36 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/mdast-util-gfm": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz",
- "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==",
- "license": "MIT",
- "dependencies": {
- "mdast-util-from-markdown": "^2.0.0",
- "mdast-util-gfm-autolink-literal": "^2.0.0",
- "mdast-util-gfm-footnote": "^2.0.0",
- "mdast-util-gfm-strikethrough": "^2.0.0",
- "mdast-util-gfm-table": "^2.0.0",
- "mdast-util-gfm-task-list-item": "^2.0.0",
- "mdast-util-to-markdown": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm-autolink-literal": {
+ "node_modules/mdast-util-frontmatter": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz",
- "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==",
+ "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz",
+ "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==",
"license": "MIT",
"dependencies": {
"@types/mdast": "^4.0.0",
- "ccount": "^2.0.0",
"devlop": "^1.0.0",
- "mdast-util-find-and-replace": "^3.0.0",
- "micromark-util-character": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm-footnote": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz",
- "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "devlop": "^1.1.0",
+ "escape-string-regexp": "^5.0.0",
"mdast-util-from-markdown": "^2.0.0",
"mdast-util-to-markdown": "^2.0.0",
- "micromark-util-normalize-identifier": "^2.0.0"
+ "micromark-extension-frontmatter": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/mdast-util-gfm-strikethrough": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz",
@@ -6755,19 +7986,86 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/mdast-util-math": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz",
- "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==",
+ "node_modules/mdast-util-highlight-mark": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-highlight-mark/-/mdast-util-highlight-mark-1.2.2.tgz",
+ "integrity": "sha512-OYumVoytj+B9YgwzBhBcYUCLYHIPvJtAvwnMyKhUXbfUFuER5S+FDZyu9fadUxm2TCT5fRYK3jQXh2ioWAxrMw==",
"license": "MIT",
"dependencies": {
+ "micromark-extension-highlight-mark": "1.2.0"
+ }
+ },
+ "node_modules/mdast-util-mdx": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz",
+ "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-mdx-expression": "^2.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-mdxjs-esm": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-expression": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
+ "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
"@types/hast": "^3.0.0",
"@types/mdast": "^4.0.0",
"devlop": "^1.0.0",
- "longest-streak": "^3.0.0",
"mdast-util-from-markdown": "^2.0.0",
- "mdast-util-to-markdown": "^2.1.0",
- "unist-util-remove-position": "^5.0.0"
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-jsx": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz",
+ "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
+ "unist-util-stringify-position": "^4.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdxjs-esm": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
+ "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
},
"funding": {
"type": "opencollective",
@@ -6788,6 +8086,27 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
+ "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/mdast-util-to-markdown": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
@@ -6908,54 +8227,33 @@
"micromark-util-types": "^2.0.0"
}
},
- "node_modules/micromark-extension-gfm": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
- "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==",
- "license": "MIT",
- "dependencies": {
- "micromark-extension-gfm-autolink-literal": "^2.0.0",
- "micromark-extension-gfm-footnote": "^2.0.0",
- "micromark-extension-gfm-strikethrough": "^2.0.0",
- "micromark-extension-gfm-table": "^2.0.0",
- "micromark-extension-gfm-tagfilter": "^2.0.0",
- "micromark-extension-gfm-task-list-item": "^2.0.0",
- "micromark-util-combine-extensions": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-autolink-literal": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
- "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
- "license": "MIT",
- "dependencies": {
- "micromark-util-character": "^2.0.0",
- "micromark-util-sanitize-uri": "^2.0.0",
- "micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-footnote": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
- "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
+ "node_modules/micromark-extension-directive": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz",
+ "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==",
"license": "MIT",
"dependencies": {
"devlop": "^1.0.0",
- "micromark-core-commonmark": "^2.0.0",
"micromark-factory-space": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "parse-entities": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-frontmatter": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz",
+ "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==",
+ "license": "MIT",
+ "dependencies": {
+ "fault": "^2.0.0",
"micromark-util-character": "^2.0.0",
- "micromark-util-normalize-identifier": "^2.0.0",
- "micromark-util-sanitize-uri": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
},
@@ -6999,19 +8297,6 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/micromark-extension-gfm-tagfilter": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz",
- "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==",
- "license": "MIT",
- "dependencies": {
- "micromark-util-types": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/micromark-extension-gfm-task-list-item": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz",
@@ -7029,19 +8314,116 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/micromark-extension-math": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz",
- "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==",
+ "node_modules/micromark-extension-highlight-mark": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-highlight-mark/-/micromark-extension-highlight-mark-1.2.0.tgz",
+ "integrity": "sha512-huGtbd/9kQsMk8u7nrVMaS5qH/47yDG6ZADggo5Owz5JoY8wdfQjfuy118/QiYNCvdFuFDbzT0A7K7Hp2cBsXA==",
"license": "MIT",
"dependencies": {
- "@types/katex": "^0.16.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "uvu": "^0.5.6"
+ }
+ },
+ "node_modules/micromark-extension-mdx-expression": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz",
+ "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
"devlop": "^1.0.0",
- "katex": "^0.16.0",
+ "micromark-factory-mdx-expression": "^2.0.0",
"micromark-factory-space": "^2.0.0",
"micromark-util-character": "^2.0.0",
+ "micromark-util-events-to-acorn": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-extension-mdx-jsx": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz",
+ "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-is-identifier-name": "^3.0.0",
+ "micromark-factory-mdx-expression": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-events-to-acorn": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-mdx-md": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz",
+ "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-mdxjs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz",
+ "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==",
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.0.0",
+ "acorn-jsx": "^5.0.0",
+ "micromark-extension-mdx-expression": "^3.0.0",
+ "micromark-extension-mdx-jsx": "^3.0.0",
+ "micromark-extension-mdx-md": "^2.0.0",
+ "micromark-extension-mdxjs-esm": "^3.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-mdxjs-esm": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz",
+ "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-events-to-acorn": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unist-util-position-from-estree": "^2.0.0",
+ "vfile-message": "^4.0.0"
},
"funding": {
"type": "opencollective",
@@ -7091,6 +8473,33 @@
"micromark-util-types": "^2.0.0"
}
},
+ "node_modules/micromark-factory-mdx-expression": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz",
+ "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-events-to-acorn": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unist-util-position-from-estree": "^2.0.0",
+ "vfile-message": "^4.0.0"
+ }
+ },
"node_modules/micromark-factory-space": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
@@ -7292,6 +8701,31 @@
],
"license": "MIT"
},
+ "node_modules/micromark-util-events-to-acorn": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz",
+ "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "@types/unist": "^3.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-visit": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "vfile-message": "^4.0.0"
+ }
+ },
"node_modules/micromark-util-html-tag-name": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
@@ -7439,7 +8873,6 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -7539,6 +8972,15 @@
"integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
"license": "MIT"
},
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/mrmime": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
@@ -7571,6 +9013,7 @@
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -7592,12 +9035,11 @@
"dev": true,
"license": "MIT"
},
- "node_modules/natural-compare-lite": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
- "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
- "dev": true,
- "license": "MIT"
+ "node_modules/next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
+ "license": "ISC"
},
"node_modules/node-releases": {
"version": "2.0.19",
@@ -7666,7 +9108,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -7787,10 +9228,10 @@
"node": ">= 0.8.0"
}
},
- "node_modules/orderedmap": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
- "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
+ "node_modules/outvariant": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.0.tgz",
+ "integrity": "sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==",
"license": "MIT"
},
"node_modules/p-limit": {
@@ -7845,6 +9286,31 @@
"node": ">=6"
}
},
+ "node_modules/parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/parse-entities/node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "license": "MIT"
+ },
"node_modules/parse5": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
@@ -7950,6 +9416,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
@@ -8018,6 +9485,7 @@
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -8210,181 +9678,31 @@
"node": ">=6"
}
},
- "node_modules/prosemirror-changeset": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz",
- "integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==",
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"license": "MIT",
"dependencies": {
- "prosemirror-transform": "^1.0.0"
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
}
},
- "node_modules/prosemirror-commands": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
- "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-model": "^1.0.0",
- "prosemirror-state": "^1.0.0",
- "prosemirror-transform": "^1.10.2"
- }
+ "node_modules/prop-types/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
},
- "node_modules/prosemirror-dropcursor": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
- "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-state": "^1.0.0",
- "prosemirror-transform": "^1.1.0",
- "prosemirror-view": "^1.1.0"
- }
- },
- "node_modules/prosemirror-gapcursor": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz",
- "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-keymap": "^1.0.0",
- "prosemirror-model": "^1.0.0",
- "prosemirror-state": "^1.0.0",
- "prosemirror-view": "^1.0.0"
- }
- },
- "node_modules/prosemirror-history": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz",
- "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-state": "^1.2.2",
- "prosemirror-transform": "^1.0.0",
- "prosemirror-view": "^1.31.0",
- "rope-sequence": "^1.3.0"
- }
- },
- "node_modules/prosemirror-inputrules": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.0.tgz",
- "integrity": "sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-state": "^1.0.0",
- "prosemirror-transform": "^1.0.0"
- }
- },
- "node_modules/prosemirror-keymap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
- "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-state": "^1.0.0",
- "w3c-keyname": "^2.2.0"
- }
- },
- "node_modules/prosemirror-model": {
- "version": "1.25.1",
- "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.1.tgz",
- "integrity": "sha512-AUvbm7qqmpZa5d9fPKMvH1Q5bqYQvAZWOGRvxsB6iFLyycvC9MwNemNVjHVrWgjaoxAfY8XVg7DbvQ/qxvI9Eg==",
- "license": "MIT",
- "dependencies": {
- "orderedmap": "^2.0.0"
- }
- },
- "node_modules/prosemirror-safari-ime-span": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/prosemirror-safari-ime-span/-/prosemirror-safari-ime-span-1.0.2.tgz",
- "integrity": "sha512-QJqD8s1zE/CuK56kDsUhndh5hiHh/gFnAuPOA9ytva2s85/ZEt2tNWeALTJN48DtWghSKOmiBsvVn2OlnJ5H2w==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-state": "^1.4.3",
- "prosemirror-view": "^1.33.8"
- },
- "funding": {
- "url": "https://github.com/sponsors/ocavue"
- }
- },
- "node_modules/prosemirror-schema-list": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
- "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-model": "^1.0.0",
- "prosemirror-state": "^1.0.0",
- "prosemirror-transform": "^1.7.3"
- }
- },
- "node_modules/prosemirror-state": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
- "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-model": "^1.0.0",
- "prosemirror-transform": "^1.0.0",
- "prosemirror-view": "^1.27.0"
- }
- },
- "node_modules/prosemirror-tables": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz",
- "integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-keymap": "^1.2.2",
- "prosemirror-model": "^1.25.0",
- "prosemirror-state": "^1.4.3",
- "prosemirror-transform": "^1.10.3",
- "prosemirror-view": "^1.39.1"
- }
- },
- "node_modules/prosemirror-transform": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz",
- "integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-model": "^1.21.0"
- }
- },
- "node_modules/prosemirror-view": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.40.0.tgz",
- "integrity": "sha512-2G3svX0Cr1sJjkD/DYWSe3cfV5VPVTBOxI9XQEGWJDFEpsZb/gh4MV29ctv+OJx2RFX4BLt09i+6zaGM/ldkCw==",
- "license": "MIT",
- "dependencies": {
- "prosemirror-model": "^1.20.0",
- "prosemirror-state": "^1.0.0",
- "prosemirror-transform": "^1.1.0"
- }
- },
- "node_modules/prosemirror-virtual-cursor": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/prosemirror-virtual-cursor/-/prosemirror-virtual-cursor-0.4.2.tgz",
- "integrity": "sha512-pUMKnIuOhhnMcgIJUjhIQTVJruBEGxfMBVQSrK0g2qhGPDm1i12KdsVaFw15dYk+29tZcxjMeR7P5VDKwmbwJg==",
+ "node_modules/property-information": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
+ "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
"license": "MIT",
"funding": {
- "url": "https://github.com/sponsors/ocavue"
- },
- "peerDependencies": {
- "prosemirror-model": "^1.0.0",
- "prosemirror-state": "^1.0.0",
- "prosemirror-view": "^1.0.0"
- },
- "peerDependenciesMeta": {
- "prosemirror-model": {
- "optional": true
- },
- "prosemirror-state": {
- "optional": true
- },
- "prosemirror-view": {
- "optional": true
- }
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/psl": {
@@ -8450,6 +9768,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-devtools-inline": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/react-devtools-inline/-/react-devtools-inline-4.4.0.tgz",
+ "integrity": "sha512-ES0GolSrKO8wsKbsEkVeiR/ZAaHQTY4zDh1UW8DImVmm8oaGLl3ijJDvSGe+qDRKPZdPRnDtWWnSvvrgxXdThQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es6-symbol": "^3"
+ }
+ },
"node_modules/react-dnd": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
@@ -8502,13 +9829,71 @@
"react": "^18.3.1"
}
},
+ "node_modules/react-error-boundary": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz",
+ "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ },
+ "peerDependencies": {
+ "react": ">=16.13.1"
+ }
+ },
+ "node_modules/react-hook-form": {
+ "version": "7.62.0",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
+ "integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-hook-form"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
- "dev": true,
"license": "MIT"
},
+ "node_modules/react-markdown": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
+ "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "hast-util-to-jsx-runtime": "^2.0.0",
+ "html-url-attributes": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-rehype": "^11.0.0",
+ "unified": "^11.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18",
+ "react": ">=18"
+ }
+ },
"node_modules/react-refresh": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
@@ -8519,6 +9904,53 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-remove-scroll": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
+ "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "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
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
+ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-style-singleton": "^2.2.2",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-router": {
"version": "6.30.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
@@ -8551,6 +9983,28 @@
"react-dom": ">=16.8"
}
},
+ "node_modules/react-style-singleton": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
+ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "tslib": "^2.0.0"
+ },
+ "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
+ }
+ }
+ },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -8618,71 +10072,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/remark": {
- "version": "15.0.1",
- "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz",
- "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "remark-parse": "^11.0.0",
- "remark-stringify": "^11.0.0",
- "unified": "^11.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/remark-gfm": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz",
- "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "mdast-util-gfm": "^3.0.0",
- "micromark-extension-gfm": "^3.0.0",
- "remark-parse": "^11.0.0",
- "remark-stringify": "^11.0.0",
- "unified": "^11.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/remark-inline-links": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/remark-inline-links/-/remark-inline-links-7.0.0.tgz",
- "integrity": "sha512-4uj1pPM+F495ySZhTIB6ay2oSkTsKgmYaKk/q5HIdhX2fuyLEegpjWa0VdJRJ01sgOqAFo7MBKdDUejIYBMVMQ==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "mdast-util-definitions": "^6.0.0",
- "unist-util-visit": "^5.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/remark-math": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz",
- "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^4.0.0",
- "mdast-util-math": "^3.0.0",
- "micromark-extension-math": "^3.0.0",
- "unified": "^11.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/remark-parse": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
@@ -8699,15 +10088,17 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/remark-stringify": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
- "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
+ "node_modules/remark-rehype": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
+ "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
"license": "MIT",
"dependencies": {
+ "@types/hast": "^3.0.0",
"@types/mdast": "^4.0.0",
- "mdast-util-to-markdown": "^2.0.0",
- "unified": "^11.0.0"
+ "mdast-util-to-hast": "^13.0.0",
+ "unified": "^11.0.0",
+ "vfile": "^6.0.0"
},
"funding": {
"type": "opencollective",
@@ -8820,12 +10211,6 @@
"fsevents": "~2.3.2"
}
},
- "node_modules/rope-sequence": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
- "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
- "license": "MIT"
- },
"node_modules/rrweb-cssom": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
@@ -8857,6 +10242,18 @@
"queue-microtask": "^1.2.2"
}
},
+ "node_modules/sade": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+ "license": "MIT",
+ "dependencies": {
+ "mri": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/safe-regex-test": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
@@ -9099,11 +10496,22 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@@ -9111,6 +10519,18 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/static-browser-server": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/static-browser-server/-/static-browser-server-1.0.3.tgz",
+ "integrity": "sha512-ZUyfgGDdFRbZGGJQ1YhiM930Yczz5VlbJObrQLlk24+qNHVQx4OlLcYswEUo3bIyNAbQUIUR9Yr5/Hqjzqb4zA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-draft/deferred-promise": "^2.1.0",
+ "dotenv": "^16.0.3",
+ "mime-db": "^1.52.0",
+ "outvariant": "^1.3.0"
+ }
+ },
"node_modules/std-env": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
@@ -9132,6 +10552,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/strict-event-emitter": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.4.6.tgz",
+ "integrity": "sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg==",
+ "license": "MIT"
+ },
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -9202,6 +10628,20 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
+ "node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -9294,6 +10734,24 @@
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
"license": "MIT"
},
+ "node_modules/style-to-js": {
+ "version": "1.1.17",
+ "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz",
+ "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==",
+ "license": "MIT",
+ "dependencies": {
+ "style-to-object": "1.0.9"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz",
+ "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==",
+ "license": "MIT",
+ "dependencies": {
+ "inline-style-parser": "0.2.4"
+ }
+ },
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
@@ -9397,6 +10855,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
+ "license": "MIT"
+ },
"node_modules/tailwind-merge": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.0.tgz",
@@ -9569,6 +11033,16 @@
"node": ">=18"
}
},
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/trough": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
@@ -9579,6 +11053,19 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/ts-api-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
+ "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@@ -9643,28 +11130,11 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
- "node_modules/tsutils": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
- "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tslib": "^1.8.1"
- },
- "engines": {
- "node": ">= 6"
- },
- "peerDependencies": {
- "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
- }
- },
- "node_modules/tsutils/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true,
- "license": "0BSD"
+ "node_modules/type": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
+ "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==",
+ "license": "ISC"
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -9706,7 +11176,7 @@
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
- "devOptional": true,
+ "dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -9730,6 +11200,24 @@
"devOptional": true,
"license": "MIT"
},
+ "node_modules/unidiff": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unidiff/-/unidiff-1.0.4.tgz",
+ "integrity": "sha512-ynU0vsAXw0ir8roa+xPCUHmnJ5goc5BTM2Kuc3IJd8UwgaeRs7VSD5+eeaQL+xp1JtB92hu/Zy/Lgy7RZcr1pQ==",
+ "license": "MIT",
+ "dependencies": {
+ "diff": "^5.1.0"
+ }
+ },
+ "node_modules/unidiff/node_modules/diff": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/unified": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
@@ -9762,14 +11250,26 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/unist-util-remove-position": {
+ "node_modules/unist-util-position": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz",
- "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
"license": "MIT",
"dependencies": {
- "@types/unist": "^3.0.0",
- "unist-util-visit": "^5.0.0"
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position-from-estree": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz",
+ "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
},
"funding": {
"type": "opencollective",
@@ -9880,13 +11380,47 @@
"requires-port": "^1.0.0"
}
},
- "node_modules/use-sync-external-store": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
- "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "node_modules/use-callback-ref": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
+ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
"license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-sidecar": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "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
+ }
}
},
"node_modules/util-deprecate": {
@@ -9896,6 +11430,33 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/uvu": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
+ "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0",
+ "diff": "^5.0.0",
+ "kleur": "^4.0.3",
+ "sade": "^1.7.3"
+ },
+ "bin": {
+ "uvu": "bin.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/uvu/node_modules/diff": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
@@ -10080,27 +11641,6 @@
}
}
},
- "node_modules/vue": {
- "version": "3.5.18",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.18.tgz",
- "integrity": "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-dom": "3.5.18",
- "@vue/compiler-sfc": "3.5.18",
- "@vue/runtime-dom": "3.5.18",
- "@vue/server-renderer": "3.5.18",
- "@vue/shared": "3.5.18"
- },
- "peerDependencies": {
- "typescript": "*"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
"node_modules/w3c-keyname": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
@@ -10438,6 +11978,24 @@
"node": ">= 14.6"
}
},
+ "node_modules/yjs": {
+ "version": "13.6.27",
+ "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.27.tgz",
+ "integrity": "sha512-OIDwaflOaq4wC6YlPBy2L6ceKeKuF7DeTxx+jPzv1FHn9tCZ0ZwSRnUBxD05E3yed46fv/FWJbvR+Ud7x0L7zw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "lib0": "^0.2.99"
+ },
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=8.0.0"
+ },
+ "funding": {
+ "type": "GitHub Sponsors ❤",
+ "url": "https://github.com/sponsors/dmonad"
+ }
+ },
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
@@ -10470,34 +12028,6 @@
"url": "https://github.com/sponsors/colinhacks"
}
},
- "node_modules/zustand": {
- "version": "4.5.7",
- "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
- "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
- "license": "MIT",
- "dependencies": {
- "use-sync-external-store": "^1.2.2"
- },
- "engines": {
- "node": ">=12.7.0"
- },
- "peerDependencies": {
- "@types/react": ">=16.8",
- "immer": ">=9.0.6",
- "react": ">=16.8"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "immer": {
- "optional": true
- },
- "react": {
- "optional": true
- }
- }
- },
"node_modules/zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
diff --git a/archon-ui-main/package.json b/archon-ui-main/package.json
index 1f5a91c8..336132fe 100644
--- a/archon-ui-main/package.json
+++ b/archon-ui-main/package.json
@@ -7,6 +7,14 @@
"dev": "npx vite",
"build": "npx vite build",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
+ "lint:files": "eslint --ext .js,.jsx,.ts,.tsx",
+ "biome": "biome check",
+ "biome:fix": "biome check --write",
+ "biome:format": "biome format --write",
+ "biome:lint": "biome lint",
+ "biome:ai": "biome check --reporter=json",
+ "biome:ai-fix": "biome check --write --reporter=json",
+ "biome:ci": "biome ci",
"preview": "npx vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
@@ -18,11 +26,17 @@
"seed:projects": "node --loader ts-node/esm ../scripts/seed-project-data.ts"
},
"dependencies": {
- "@milkdown/crepe": "^7.5.0",
- "@milkdown/kit": "^7.5.0",
- "@milkdown/plugin-history": "^7.5.0",
- "@milkdown/preset-commonmark": "^7.5.0",
- "@xyflow/react": "^12.3.0",
+ "@mdxeditor/editor": "^3.42.0",
+ "@radix-ui/react-alert-dialog": "^1.1.15",
+ "@radix-ui/react-dialog": "^1.1.15",
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
+ "@radix-ui/react-popover": "^1.1.15",
+ "@radix-ui/react-select": "^2.2.6",
+ "@radix-ui/react-tabs": "^1.1.13",
+ "@radix-ui/react-toast": "^1.2.15",
+ "@radix-ui/react-tooltip": "^1.2.8",
+ "@tanstack/react-query": "^5.85.8",
+ "@tanstack/react-query-devtools": "^5.85.8",
"clsx": "latest",
"date-fns": "^4.1.0",
"fractional-indexing": "^3.2.0",
@@ -33,24 +47,26 @@
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.3.1",
+ "react-markdown": "^10.1.0",
"react-router-dom": "^6.26.2",
"tailwind-merge": "latest",
"zod": "^3.25.46"
},
"devDependencies": {
+ "@biomejs/biome": "2.2.2",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^14.3.1",
"@testing-library/user-event": "^14.5.2",
"@types/node": "^20.19.0",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.1",
- "@typescript-eslint/eslint-plugin": "^5.54.0",
- "@typescript-eslint/parser": "^5.54.0",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^1.6.0",
"@vitest/ui": "^1.6.0",
"autoprefixer": "latest",
- "eslint": "^8.50.0",
+ "eslint": "^8.57.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.1",
"jsdom": "^24.1.0",
diff --git a/archon-ui-main/src/App.tsx b/archon-ui-main/src/App.tsx
index 427347cb..0eb27606 100644
--- a/archon-ui-main/src/App.tsx
+++ b/archon-ui-main/src/App.tsx
@@ -1,5 +1,7 @@
import { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { KnowledgeBasePage } from './pages/KnowledgeBasePage';
import { SettingsPage } from './pages/SettingsPage';
import { MCPPage } from './pages/MCPPage';
@@ -7,7 +9,9 @@ import { OnboardingPage } from './pages/OnboardingPage';
import { MainLayout } from './components/layouts/MainLayout';
import { ThemeProvider } from './contexts/ThemeContext';
import { ToastProvider } from './contexts/ToastContext';
+import { ToastProvider as FeaturesToastProvider } from './features/ui/components/ToastProvider';
import { SettingsProvider, useSettings } from './contexts/SettingsContext';
+import { TooltipProvider } from './features/ui/primitives/tooltip';
import { ProjectPage } from './pages/ProjectPage';
import { DisconnectScreenOverlay } from './components/DisconnectScreenOverlay';
import { ErrorBoundaryWithBugReport } from './components/bug-report/ErrorBoundaryWithBugReport';
@@ -15,6 +19,28 @@ import { MigrationBanner } from './components/ui/MigrationBanner';
import { serverHealthService } from './services/serverHealthService';
import { useMigrationStatus } from './hooks/useMigrationStatus';
+// Create a client with optimized settings for our polling use case
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ // Keep data fresh for 2 seconds by default
+ staleTime: 2000,
+ // Cache data for 5 minutes
+ gcTime: 5 * 60 * 1000,
+ // Retry failed requests 3 times
+ retry: 3,
+ // Refetch on window focus
+ refetchOnWindowFocus: true,
+ // Don't refetch on reconnect by default (we handle this manually)
+ refetchOnReconnect: false,
+ },
+ mutations: {
+ // Retry mutations once on failure
+ retry: 1,
+ },
+ },
+});
+
const AppRoutes = () => {
const { projectsEnabled } = useSettings();
@@ -105,12 +131,21 @@ const AppContent = () => {
export function App() {
return (
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ {import.meta.env.VITE_SHOW_DEVTOOLS === 'true' && (
+
+ )}
+
);
}
\ No newline at end of file
diff --git a/archon-ui-main/src/components/knowledge-base/CrawlingProgressCard.tsx b/archon-ui-main/src/components/knowledge-base/CrawlingProgressCard.tsx
index 0f391581..f5eeb5aa 100644
--- a/archon-ui-main/src/components/knowledge-base/CrawlingProgressCard.tsx
+++ b/archon-ui-main/src/components/knowledge-base/CrawlingProgressCard.tsx
@@ -26,7 +26,7 @@ import { Card } from '../ui/Card';
import { Button } from '../ui/Button';
import { Badge } from '../ui/Badge';
import { CrawlProgressData } from '../../types/crawl';
-import { useCrawlProgressPolling } from '../../hooks/usePolling';
+import { useCrawlProgressPolling } from '../../hooks/useCrawlQueries';
import { useTerminalScroll } from '../../hooks/useTerminalScroll';
interface CrawlingProgressCardProps {
diff --git a/archon-ui-main/src/components/project-tasks/DataTab.tsx b/archon-ui-main/src/components/project-tasks/DataTab.tsx
deleted file mode 100644
index 6ba8dac2..00000000
--- a/archon-ui-main/src/components/project-tasks/DataTab.tsx
+++ /dev/null
@@ -1,956 +0,0 @@
-import React, { useCallback, useState, useEffect, useMemo } from 'react';
-import '@xyflow/react/dist/style.css';
-import { ReactFlow, Node, Edge, Background, Controls, MarkerType, NodeChange, applyNodeChanges, EdgeChange, applyEdgeChanges, ConnectionLineType, addEdge, Connection, Handle, Position } from '@xyflow/react';
-import { Database, Info, Calendar, TrendingUp, Edit, Plus, X, Save, Trash2 } from 'lucide-react';
-import { projectService } from '../../services/projectService';
-import { useToast } from '../../contexts/ToastContext';
-
-// Custom node types - will be defined inside the component to access state
-
-const createTableNode = (id: string, label: string, columns: string[], x: number, y: number): Node => ({
- id,
- type: 'table',
- data: {
- label,
- columns
- },
- position: {
- x,
- y
- }
-});
-
-// Default fallback nodes for basic database structure
-const defaultNodes: Node[] = [
- createTableNode('users', 'Users', ['id (PK) - UUID', 'email - VARCHAR(255)', 'password - VARCHAR(255)', 'firstName - VARCHAR(100)', 'lastName - VARCHAR(100)', 'createdAt - TIMESTAMP', 'updatedAt - TIMESTAMP'], 150, 100),
- createTableNode('projects', 'Projects', ['id (PK) - UUID', 'title - VARCHAR(255)', 'description - TEXT', 'status - VARCHAR(50)', 'userId (FK) - UUID', 'createdAt - TIMESTAMP', 'updatedAt - TIMESTAMP'], 500, 100)
-];
-
-const defaultEdges: Edge[] = [{
- id: 'projects-users',
- source: 'users',
- target: 'projects',
- sourceHandle: 'Users-id',
- targetHandle: 'Projects-userId',
- animated: true,
- style: {
- stroke: '#d946ef'
- },
- markerEnd: {
- type: MarkerType.Arrow,
- color: '#d946ef'
- }
-}];
-
-// Data metadata card component for the new data structure
-const DataCard = ({ data }: { data: any }) => {
- const iconMap: { [key: string]: any } = {
- 'ShoppingCart': Database,
- 'Database': Database,
- 'Info': Info,
- 'Calendar': Calendar,
- 'TrendingUp': TrendingUp
- };
-
- const IconComponent = iconMap[data.icon] || Database;
-
- const colorClasses = {
- cyan: 'from-cyan-900/40 to-cyan-800/30 border-cyan-500/50 text-cyan-400',
- blue: 'from-blue-900/40 to-blue-800/30 border-blue-500/50 text-blue-400',
- purple: 'from-purple-900/40 to-purple-800/30 border-purple-500/50 text-purple-400',
- pink: 'from-pink-900/40 to-pink-800/30 border-pink-500/50 text-pink-400'
- };
-
- const colorClass = colorClasses[data.color as keyof typeof colorClasses] || colorClasses.cyan;
-
- return (
-
-
-
-
Project Data Overview
-
-
-
-
Description:
-
{data.description}
-
-
-
- Last updated: {data.updated}
-
-
-
- );
-};
-
-interface DataTabProps {
- project?: {
- id: string;
- title: string;
- data?: any[];
- } | null;
-}
-
-export const DataTab = ({ project }: DataTabProps) => {
- const [nodes, setNodes] = useState([]);
- const [edges, setEdges] = useState([]);
- const [loading, setLoading] = useState(true);
- const [viewMode, setViewMode] = useState<'metadata' | 'erd'>('metadata');
- const [editingNode, setEditingNode] = useState(null);
- const [showEditModal, setShowEditModal] = useState(false);
- const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
- const [isSaving, setIsSaving] = useState(false);
- const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
- const [nodeToDelete, setNodeToDelete] = useState(null);
-
- const { showToast } = useToast();
-
-
- // Helper function to normalize nodes to ensure required properties
- const normalizeNode = (node: any): Node => {
- return {
- id: node.id || `node-${Date.now()}-${Math.random()}`,
- type: node.type || 'table',
- position: {
- x: node.position?.x || 100,
- y: node.position?.y || 100
- },
- data: {
- label: node.data?.label || 'Untitled',
- columns: node.data?.columns || ['id (PK) - UUID']
- }
- };
- };
-
- useEffect(() => {
- console.log('DataTab project data:', project?.data);
-
- // Determine view mode based on data structure
- if (project?.data) {
- if (Array.isArray(project.data) && project.data.length > 0) {
- // Handle array format: [{"type": "erd", ...}] or [{"description": "...", "progress": 65}]
- const firstItem = project.data[0];
- console.log('First data item (array):', firstItem);
-
- if (firstItem.description && typeof firstItem.progress === 'number') {
- console.log('Setting metadata view');
- setViewMode('metadata');
- } else if (firstItem.type === 'erd' && firstItem.nodes && firstItem.edges) {
- console.log('Setting ERD view with structured array data');
- setViewMode('erd');
- // Normalize nodes to ensure required properties
- const normalizedNodes = firstItem.nodes.map(normalizeNode);
- setNodes(normalizedNodes);
- // Fix any ArrowClosed marker types in loaded edges
- const sanitizedEdges = firstItem.edges.map((edge: any) => ({
- ...edge,
- markerEnd: edge.markerEnd ? {
- ...edge.markerEnd,
- type: edge.markerEnd.type === 'ArrowClosed' ? MarkerType.Arrow : edge.markerEnd.type
- } : undefined
- }));
- setEdges(sanitizedEdges);
- } else {
- console.log('Setting ERD view for array data');
- setViewMode('erd');
- // Normalize nodes to ensure required properties
- const normalizedNodes = project.data.map(normalizeNode);
- setNodes(normalizedNodes);
- setEdges([]);
- }
- } else if (typeof project.data === 'object' && !Array.isArray(project.data) &&
- (project.data as any).type === 'erd' &&
- (project.data as any).nodes &&
- (project.data as any).edges) {
- // Handle direct object format: {"type": "erd", "nodes": [...], "edges": [...]}
- console.log('Setting ERD view with direct object data');
- setViewMode('erd');
- // Normalize nodes to ensure required properties
- const normalizedNodes = (project.data as any).nodes.map(normalizeNode);
- setNodes(normalizedNodes);
- // Fix any ArrowClosed marker types in loaded edges
- const sanitizedEdges = (project.data as any).edges.map((edge: any) => ({
- ...edge,
- markerEnd: edge.markerEnd ? {
- ...edge.markerEnd,
- type: edge.markerEnd.type === 'ArrowClosed' ? MarkerType.Arrow : edge.markerEnd.type
- } : undefined
- }));
- setEdges(sanitizedEdges);
- } else {
- console.log('Unknown data format, showing empty state');
- setViewMode('erd');
- setNodes([]);
- setEdges([]);
- }
- } else {
- console.log('No data, using empty state');
- setViewMode('erd');
- setNodes([]);
- setEdges([]);
- }
- setLoading(false);
- }, [project]);
-
- const onNodesChange = useCallback((changes: NodeChange[]) => {
- setNodes(nds => applyNodeChanges(changes, nds));
- setHasUnsavedChanges(true);
- }, []);
-
- const onEdgesChange = useCallback((changes: EdgeChange[]) => {
- setEdges(eds => applyEdgeChanges(changes, eds));
- setHasUnsavedChanges(true);
- }, []);
- const onConnect = useCallback(async (connection: Connection) => {
- const newEdgeProps = {
- animated: true,
- style: {
- stroke: '#22d3ee'
- },
- markerEnd: {
- type: MarkerType.Arrow,
- color: '#22d3ee'
- },
- label: 'relates to',
- labelStyle: {
- fill: '#e94560',
- fontWeight: 500
- },
- labelBgStyle: {
- fill: 'rgba(0, 0, 0, 0.7)'
- }
- };
-
- const newEdges = addEdge({ ...connection, ...newEdgeProps }, edges);
- setEdges(newEdges);
-
- // Auto-save to database
- await saveToDatabase(nodes, newEdges);
- }, [nodes, edges, project?.id]);
-
- const handleNodeClick = useCallback((event: React.MouseEvent, node: Node) => {
- setEditingNode(node);
- setShowEditModal(true);
- }, []);
-
-
-
- const addTableNode = async () => {
- if (!project?.id) {
- console.error('❌ No project ID available for adding table');
- return;
- }
-
- console.log('🔄 Adding new table...');
- const newNodeId = `table-${Date.now()}`;
- const newNode = createTableNode(newNodeId, `New Table ${nodes.length + 1}`, ['id (PK) - UUID', 'name - VARCHAR(255)', 'description - TEXT', 'createdAt - TIMESTAMP', 'updatedAt - TIMESTAMP'], 400, 300);
- const newNodes = [...nodes, newNode];
- setNodes(newNodes);
-
- // Auto-save to database
- try {
- console.log('💾 Saving new table to database...');
- await saveToDatabase(newNodes, edges);
- console.log('✅ New table saved successfully');
- } catch (error) {
- console.error('❌ Failed to save new table:', error);
- // Optionally revert the UI change if save failed
- setNodes(nodes);
- }
- };
-
- const saveToDatabase = async (nodesToSave = nodes, edgesToSave = edges) => {
- if (!project?.id) {
- console.error('No project ID available for saving');
- return;
- }
-
- console.log('💾 saveToDatabase called with:', {
- projectId: project.id,
- nodeCount: nodesToSave.length,
- edgeCount: edgesToSave.length
- });
-
- setIsSaving(true);
- try {
- const updatedData = {
- type: 'erd',
- nodes: nodesToSave,
- edges: edgesToSave
- };
-
- console.log('🔄 Calling projectService.updateProject with data:', updatedData);
-
- const result = await projectService.updateProject(project.id, {
- data: [updatedData] // Wrap in array to match UpdateProjectRequest type
- });
-
- console.log('✅ ERD data saved successfully, result:', result);
- setHasUnsavedChanges(false);
- } catch (error) {
- console.error('❌ Failed to save ERD data:', error);
- console.error('Error details:', error);
- throw error; // Re-throw so calling function can handle it
- } finally {
- setIsSaving(false);
- }
- };
-
- const saveNodeChanges = async (updatedNode: Node) => {
- // Update local state first
- const newNodes = nodes.map(node =>
- node.id === updatedNode.id ? updatedNode : node
- );
- setNodes(newNodes);
-
- // Save to database
- await saveToDatabase(newNodes, edges);
-
- setShowEditModal(false);
- setEditingNode(null);
- };
-
- const handleManualSave = async () => {
- await saveToDatabase();
- };
-
- const handleDeleteNode = useCallback(async (event: React.MouseEvent, nodeId: string) => {
- event.stopPropagation(); // Prevent triggering the edit modal
-
- if (!project?.id) {
- console.error('❌ No project ID available for deleting table');
- return;
- }
-
- // Show custom confirmation dialog
- setNodeToDelete(nodeId);
- setShowDeleteConfirm(true);
- }, [project?.id]);
-
- const confirmDelete = useCallback(async () => {
- if (!nodeToDelete) return;
-
- console.log('🗑️ Deleting table:', nodeToDelete);
-
- try {
- // Remove node from UI
- const newNodes = nodes.filter(node => node.id !== nodeToDelete);
-
- // Remove any edges connected to this node
- const newEdges = edges.filter(edge =>
- edge.source !== nodeToDelete && edge.target !== nodeToDelete
- );
-
- setNodes(newNodes);
- setEdges(newEdges);
-
- // Save to database
- console.log('💾 Saving after table deletion...');
- await saveToDatabase(newNodes, newEdges);
- console.log('✅ Table deleted successfully');
- showToast('Table deleted successfully', 'success');
-
- // Close confirmation dialog
- setShowDeleteConfirm(false);
- setNodeToDelete(null);
- } catch (error) {
- console.error('❌ Failed to delete table:', error);
- // Revert UI changes on error
- setNodes(nodes);
- setEdges(edges);
- showToast('Failed to delete table', 'error');
- }
- }, [nodeToDelete, nodes, edges, saveToDatabase]);
-
- const cancelDelete = useCallback(() => {
- setShowDeleteConfirm(false);
- setNodeToDelete(null);
- }, []);
-
- // Memoize nodeTypes to prevent recreation on every render
- const nodeTypes = useMemo(() => ({
- table: ({ data, id }: any) => (
-
-
-
-
-
-
-
-
-
- {data.columns.map((col: string, i: number) => {
- const isPK = col.includes('PK');
- const isFK = col.includes('FK');
- return (
-
- {col}
- {isPK && (
-
- )}
- {isFK && (
-
- )}
-
- );
- })}
-
-
- )
- }), [handleNodeClick, handleDeleteNode, nodes]);
-
- if (loading) {
- return (
-
- );
- }
-
- return (
-
-
-
-
-
-
- {viewMode === 'metadata' ? 'Data Overview' : 'Data Relationships'}
- {viewMode === 'erd' && nodes.length > 0 && ` (${nodes.length} tables)`}
- {viewMode === 'metadata' && Array.isArray(project?.data) && ` (${project.data.length} items)`}
-
- {viewMode === 'metadata' && (
-
- )}
- {viewMode === 'erd' && (
-
-
- {hasUnsavedChanges && (
-
- )}
-
-
- )}
-
-
- {viewMode === 'metadata' ? (
-
- {Array.isArray(project?.data) && project.data.length > 0 ? (
-
- {project.data.map((item, index) => (
-
- ))}
-
- ) : (
-
-
-
No metadata available
-
Switch to ERD view to see database schema
-
- )}
-
- ) : (
-
- {/* Subtle neon glow at the top */}
-
- {nodes.length === 0 ? (
-
-
-
No data schema defined
-
Add tables to design your database
-
- ) : (
-
-
-
- )}
-
- )}
-
- {/* Delete Confirmation Modal */}
- {showDeleteConfirm && (
-
n.id === nodeToDelete)?.data.label as string || 'table'}
- />
- )}
-
- {/* Edit Modal */}
- {showEditModal && editingNode && (
- {
- setShowEditModal(false);
- setEditingNode(null);
- }}
- />
- )}
-
-
- );
-};
-
-// Delete Confirmation Modal Component
-const DeleteConfirmModal = ({
- onConfirm,
- onCancel,
- tableName
-}: {
- onConfirm: () => void;
- onCancel: () => void;
- tableName: string;
-}) => {
- return (
-
-
-
-
-
-
-
-
-
-
- Delete Table
-
-
- This action cannot be undone
-
-
-
-
-
- Are you sure you want to delete the "{tableName}" table?
- This will also remove all related connections.
-
-
-
-
-
-
-
-
-
- );
-};
-
-// Column interface for better type management
-interface ColumnDefinition {
- name: string;
- dataType: string;
- columnType: 'regular' | 'pk' | 'fk';
- referencedTable?: string;
- referencedColumn?: string;
-}
-
-// Edit Table Modal Component
-const EditTableModal = ({
- node,
- nodes,
- edges,
- onSave,
- onUpdateEdges,
- onClose
-}: {
- node: Node;
- nodes: Node[];
- edges: Edge[];
- onSave: (node: Node) => void;
- onUpdateEdges: (edges: Edge[]) => void;
- onClose: () => void;
-}) => {
- const [tableName, setTableName] = useState(node.data.label as string);
- const [columns, setColumns] = useState([]);
-
- // Parse existing columns into structured format
- useEffect(() => {
- const parsedColumns = (node.data.columns as string[]).map((colStr: string) => {
- const parts = colStr.split(' - ');
- const nameAndType = parts[0];
- const dataType = parts[1] || 'VARCHAR(255)';
-
- let columnType: 'regular' | 'pk' | 'fk' = 'regular';
- let name = nameAndType;
- const referencedTable = '';
- const referencedColumn = '';
-
- if (nameAndType.includes('(PK)')) {
- columnType = 'pk';
- name = nameAndType.replace(' (PK)', '');
- } else if (nameAndType.includes('(FK)')) {
- columnType = 'fk';
- name = nameAndType.replace(' (FK)', '');
- }
-
- return {
- name,
- dataType,
- columnType,
- referencedTable,
- referencedColumn
- };
- });
- setColumns(parsedColumns);
- }, [node.data.columns]);
-
- const addColumn = () => {
- setColumns([...columns, {
- name: 'newColumn',
- dataType: 'VARCHAR(255)',
- columnType: 'regular',
- referencedTable: '',
- referencedColumn: ''
- }]);
- };
-
- const updateColumn = (index: number, field: keyof ColumnDefinition, value: string) => {
- const newColumns = [...columns];
- newColumns[index] = { ...newColumns[index], [field]: value };
- setColumns(newColumns);
- };
-
- const removeColumn = (index: number) => {
- setColumns(columns.filter((_, i) => i !== index));
- };
-
- // Get available tables for FK references (exclude current table)
- const getAvailableTables = () => {
- return nodes.filter(n => n.id !== node.id).map(n => ({
- id: n.id,
- label: n.data.label as string
- }));
- };
-
- // Get available columns for a specific table
- const getAvailableColumns = (tableId: string) => {
- const targetNode = nodes.find(n => n.id === tableId);
- if (!targetNode) return [];
-
- return (targetNode.data.columns as string[])
- .filter(col => col.includes('(PK)')) // Only allow referencing primary keys
- .map(col => {
- const name = col.split(' - ')[0].replace(' (PK)', '');
- return { name, label: name };
- });
- };
-
- const handleSave = () => {
- // Convert columns back to string format
- const columnStrings = columns.map(col => {
- let name = col.name;
- if (col.columnType === 'pk') {
- name += ' (PK)';
- } else if (col.columnType === 'fk') {
- name += ' (FK)';
- }
- return `${name} - ${col.dataType}`;
- });
-
- const updatedNode = {
- ...node,
- data: {
- ...node.data,
- label: tableName,
- columns: columnStrings
- }
- };
-
- // Create edges for FK relationships
- const newEdges = [...edges];
-
- // Remove existing edges from this table
- const filteredEdges = newEdges.filter(edge => edge.source !== node.id);
-
- // Add new edges for FK columns
- columns.forEach(col => {
- if (col.columnType === 'fk' && col.referencedTable && col.referencedColumn) {
- const edgeId = `${col.referencedTable}-${node.id}`;
- const newEdge = {
- id: edgeId,
- source: col.referencedTable,
- target: node.id,
- sourceHandle: `${nodes.find(n => n.id === col.referencedTable)?.data.label}-${col.referencedColumn}`,
- targetHandle: `${tableName}-${col.name}`,
- animated: true,
- style: {
- stroke: '#d946ef'
- },
- markerEnd: {
- type: MarkerType.Arrow,
- color: '#d946ef'
- }
- };
- filteredEdges.push(newEdge);
- }
- });
-
- // Update edges state
- onUpdateEdges(filteredEdges);
-
- onSave(updatedNode);
- };
-
- return (
-
-
-
-
-
- Edit Table
-
-
-
-
-
- {/* Table Name */}
-
-
- setTableName(e.target.value)}
- className="w-full px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-cyan-500 focus:outline-none"
- />
-
-
- {/* Columns */}
-
-
-
-
-
-
- {/* Column Headers */}
-
-
Column Name
-
Data Type
-
Type
-
References (FK only)
-
-
-
-
- {columns.map((column, index) => (
-
- {/* Column Name */}
-
updateColumn(index, 'name', e.target.value)}
- className="col-span-3 px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-cyan-500 focus:outline-none text-sm"
- />
-
- {/* Data Type */}
-
updateColumn(index, 'dataType', e.target.value)}
- className="col-span-2 px-3 py-2 bg-gray-800 border border-gray-600 rounded-lg text-white focus:border-cyan-500 focus:outline-none text-sm"
- />
-
- {/* Column Type */}
-
-
- {/* FK Reference (only show for FK columns) */}
- {column.columnType === 'fk' && (
- <>
-
-
-
- >
- )}
-
- {/* Spacer for non-FK columns */}
- {column.columnType !== 'fk' &&
}
-
- {/* Remove Button */}
-
-
- ))}
-
-
-
-
- {/* Actions */}
-
-
-
-
-
-
- );
-};
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/DocsTab.tsx b/archon-ui-main/src/components/project-tasks/DocsTab.tsx
deleted file mode 100644
index e2e08624..00000000
--- a/archon-ui-main/src/components/project-tasks/DocsTab.tsx
+++ /dev/null
@@ -1,1494 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { Plus, X, Search, Upload, Link as LinkIcon, Check, Brain, Save, History, Eye, Edit3, Sparkles } from 'lucide-react';
-import { Button } from '../ui/Button';
-import { knowledgeBaseService, KnowledgeItem } from '../../services/knowledgeBaseService';
-import { projectService } from '../../services/projectService';
-import { useToast } from '../../contexts/ToastContext';
-import { Input } from '../ui/Input';
-import { Card } from '../ui/Card';
-import { Badge } from '../ui/Badge';
-import { Select } from '../ui/Select';
-import { useCrawlProgressPolling } from '../../hooks/usePolling';
-import { MilkdownEditor } from './MilkdownEditor';
-import { VersionHistoryModal } from './VersionHistoryModal';
-import { PRPViewer } from '../prp';
-import { DocumentCard, NewDocumentCard } from './DocumentCard';
-
-
-
-
-interface ProjectDoc {
- id: string;
- title: string;
- created_at: string;
- updated_at: string;
- // Content field stores markdown or structured data
- content?: any;
- document_type?: string;
-}
-
-interface Task {
- id: string;
- title: string;
- feature: string;
- status: 'backlog' | 'in-progress' | 'review' | 'complete';
-}
-
-// Document Templates - Updated for proper MCP database storage
-const DOCUMENT_TEMPLATES = {
- 'prp_base': {
- name: 'Feature PRP Template',
- icon: '🚀',
- document_type: 'prp',
- content: {
- document_type: 'prp',
- title: 'New Feature Implementation',
- version: '1.0',
- author: 'User',
- date: new Date().toISOString().split('T')[0],
- status: 'draft',
-
- goal: 'Build a specific feature - replace with your goal',
-
- why: [
- 'Business value this feature provides',
- 'User problem this solves',
- 'How it integrates with existing functionality'
- ],
-
- what: {
- description: 'Detailed description of what users will see and experience',
- success_criteria: [
- 'Measurable outcome 1 (e.g., response time < 200ms)',
- 'User behavior outcome 2 (e.g., 90% task completion rate)',
- 'Technical outcome 3 (e.g., zero data loss during operations)'
- ],
- user_stories: [
- 'As a [user type], I want to [action] so that [benefit]',
- 'As a [user type], I need to [requirement] in order to [goal]'
- ]
- },
-
- context: {
- documentation: [
- {
- source: 'https://docs.example.com/api',
- why: 'API endpoints and data models needed'
- },
- {
- source: 'src/components/Example.tsx',
- why: 'Existing pattern to follow for UI components'
- }
- ],
- existing_code: [
- {
- file: 'src/services/baseService.ts',
- purpose: 'Service layer pattern to extend'
- }
- ],
- gotchas: [
- 'Critical requirement or constraint to remember',
- 'Common mistake to avoid during implementation'
- ],
- dependencies: [
- 'Package or service that must be available',
- 'Another feature that must be completed first'
- ]
- },
-
- implementation_blueprint: {
- phase_1_foundation: {
- description: 'Set up core infrastructure',
- duration: '2-3 days',
- tasks: [
- {
- title: 'Create TypeScript interfaces',
- details: 'Define all data types and API contracts',
- files: ['src/types/newFeature.ts']
- },
- {
- title: 'Set up database schema',
- details: 'Create tables and relationships if needed',
- files: ['migrations/add_feature_tables.sql']
- }
- ]
- },
- phase_2_implementation: {
- description: 'Build core functionality',
- duration: '1 week',
- tasks: [
- {
- title: 'Implement service layer',
- details: 'Business logic and data access',
- files: ['src/services/newFeatureService.ts']
- },
- {
- title: 'Create API endpoints',
- details: 'RESTful endpoints with proper validation',
- files: ['src/api/newFeatureApi.ts']
- },
- {
- title: 'Build UI components',
- details: 'React components with TypeScript',
- files: ['src/components/NewFeature.tsx']
- }
- ]
- },
- phase_3_integration: {
- description: 'Connect everything and test',
- duration: '2-3 days',
- tasks: [
- {
- title: 'Integrate frontend with backend',
- details: 'Connect UI to API endpoints',
- files: ['src/hooks/useNewFeature.ts']
- },
- {
- title: 'Add comprehensive tests',
- details: 'Unit, integration, and E2E tests',
- files: ['tests/newFeature.test.ts']
- }
- ]
- }
- },
-
- validation: {
- level_1_syntax: [
- 'npm run lint -- --fix',
- 'npm run typecheck',
- 'Ensure no TypeScript errors'
- ],
- level_2_unit_tests: [
- 'npm run test -- newFeature',
- 'Verify all unit tests pass with >80% coverage'
- ],
- level_3_integration: [
- 'npm run test:integration',
- 'Test API endpoints with proper data flow'
- ],
- level_4_end_to_end: [
- 'Start development server and test user flows',
- 'Verify feature works as expected in browser',
- 'Test error scenarios and edge cases'
- ]
- }
- }
- },
- 'prp_task': {
- name: 'Task/Bug Fix PRP',
- icon: '✅',
- document_type: 'prp',
- content: {
- document_type: 'prp',
- title: 'Task or Bug Fix',
- version: '1.0',
- author: 'User',
- date: new Date().toISOString().split('T')[0],
- status: 'draft',
-
- goal: 'Fix specific bug or complete targeted task',
-
- why: [
- 'Impact on users or system if not fixed',
- 'How this fits into larger project goals',
- 'Priority level and urgency'
- ],
-
- what: {
- description: 'Specific problem to solve and expected outcome',
- current_behavior: 'What happens now (the problem)',
- expected_behavior: 'What should happen instead',
- acceptance_criteria: [
- 'Specific testable condition 1',
- 'Specific testable condition 2',
- 'No regressions in existing functionality'
- ]
- },
-
- context: {
- affected_files: [
- {
- path: 'src/component.tsx',
- reason: 'Contains the bug or needs the change'
- },
- {
- path: 'src/service.ts',
- reason: 'Related logic that may need updates'
- }
- ],
- root_cause: 'Analysis of why this issue exists',
- related_issues: [
- 'Link to GitHub issue or ticket',
- 'Related bugs or enhancement requests'
- ],
- dependencies: [
- 'Other tasks that must be completed first',
- 'External services or APIs involved'
- ]
- },
-
- implementation_steps: [
- {
- step: 1,
- action: 'Reproduce the issue',
- details: 'Create test case that demonstrates the problem'
- },
- {
- step: 2,
- action: 'Identify root cause',
- details: 'Debug and trace the issue to its source'
- },
- {
- step: 3,
- action: 'Implement fix',
- details: 'Apply minimal change that resolves the issue'
- },
- {
- step: 4,
- action: 'Test solution',
- details: 'Verify fix works and doesn\'t break other functionality'
- },
- {
- step: 5,
- action: 'Update documentation',
- details: 'Update any relevant docs or comments'
- }
- ],
-
- validation: {
- reproduction_test: [
- 'Steps to reproduce the original issue',
- 'Verify the issue no longer occurs'
- ],
- regression_tests: [
- 'Run existing test suite to ensure no regressions',
- 'Test related functionality manually'
- ],
- edge_cases: [
- 'Test boundary conditions',
- 'Test error scenarios'
- ]
- }
- }
- },
- 'prp_planning': {
- name: 'Architecture/Planning PRP',
- icon: '📐',
- document_type: 'prp',
- content: {
- document_type: 'prp',
- title: 'System Architecture and Planning',
- version: '1.0',
- author: 'User',
- date: new Date().toISOString().split('T')[0],
- status: 'draft',
-
- goal: 'Design and plan system architecture for [specific system/feature]',
-
- why: [
- 'Strategic business objective driving this architecture',
- 'Technical debt or scalability issues to address',
- 'Future growth and maintainability requirements'
- ],
-
- what: {
- scope: 'System boundaries, affected components, and integration points',
- deliverables: [
- 'Comprehensive architecture documentation',
- 'Component specifications and interfaces',
- 'Implementation roadmap and timeline',
- 'Migration/deployment strategy'
- ],
- constraints: [
- 'Budget and timeline limitations',
- 'Technical constraints and dependencies',
- 'Regulatory or compliance requirements'
- ]
- },
-
- current_state_analysis: {
- strengths: [
- 'What works well in the current system',
- 'Stable components that should be preserved',
- 'Existing patterns worth maintaining'
- ],
- weaknesses: [
- 'Performance bottlenecks and limitations',
- 'Maintenance and scaling challenges',
- 'Security or reliability concerns'
- ],
- opportunities: [
- 'Modern technologies to leverage',
- 'Process improvements to implement',
- 'Business capabilities to enable'
- ],
- threats: [
- 'Risks during transition period',
- 'Dependencies on legacy systems',
- 'Resource and timeline constraints'
- ]
- },
-
- proposed_architecture: {
- overview: 'High-level description of the new architecture',
- components: {
- frontend: {
- technology: 'React 18 with TypeScript',
- patterns: 'Component composition with ShadCN UI',
- state_management: 'React hooks with context for global state'
- },
- backend: {
- technology: 'FastAPI with async Python',
- patterns: 'Service layer with repository pattern',
- database: 'Supabase PostgreSQL with proper indexing'
- },
- realtime: {
- technology: 'HTTP polling for live updates',
- patterns: 'ETag-based polling with smart pausing'
- },
- infrastructure: {
- deployment: 'Docker containers with orchestration',
- monitoring: 'Comprehensive logging and metrics',
- security: 'OAuth2 with proper encryption'
- }
- },
- data_flow: [
- 'User interaction → Frontend validation → API call',
- 'Backend processing → Database operations → Response',
- 'Real-time events → HTTP polling → UI updates'
- ],
- integration_points: [
- 'External APIs and their usage patterns',
- 'Third-party services and data sources',
- 'Legacy system interfaces'
- ]
- },
-
- implementation_phases: {
- phase_1_foundation: {
- duration: '2-3 weeks',
- objective: 'Core infrastructure and basic functionality',
- deliverables: [
- 'Database schema and basic API endpoints',
- 'Authentication and authorization system',
- 'Core UI components and routing'
- ],
- success_criteria: [
- 'Basic user flows working end-to-end',
- 'Core API responses under 200ms',
- 'Authentication working with test users'
- ]
- },
- phase_2_features: {
- duration: '3-4 weeks',
- objective: 'Primary feature implementation',
- deliverables: [
- 'Complete feature set with UI',
- 'Real-time updates and notifications',
- 'Data validation and error handling'
- ],
- success_criteria: [
- 'All major user stories implemented',
- 'Real-time features working reliably',
- 'Comprehensive error handling'
- ]
- },
- phase_3_optimization: {
- duration: '1-2 weeks',
- objective: 'Testing, optimization, and deployment',
- deliverables: [
- 'Comprehensive test suite',
- 'Performance optimization',
- 'Production deployment'
- ],
- success_criteria: [
- 'Test coverage >80%',
- 'Performance targets met',
- 'Successful production deployment'
- ]
- }
- },
-
- success_metrics: {
- performance: [
- 'API response time <200ms for 95% of requests',
- 'UI load time <2 seconds',
- 'Support 1000+ concurrent users'
- ],
- quality: [
- 'Test coverage >80%',
- 'Zero critical security vulnerabilities',
- 'Mean time to recovery <15 minutes'
- ],
- business: [
- 'User task completion rate >90%',
- 'Feature adoption >60% within first month',
- 'User satisfaction score >4.5/5'
- ]
- },
-
- risks_and_mitigation: {
- technical_risks: [
- {
- risk: 'Integration complexity with legacy systems',
- mitigation: 'Phased approach with fallback options'
- },
- {
- risk: 'Performance issues at scale',
- mitigation: 'Load testing and optimization in early phases'
- }
- ],
- business_risks: [
- {
- risk: 'Timeline delays due to scope creep',
- mitigation: 'Clear requirements and change control process'
- }
- ]
- }
- }
- },
-
- // Simple markdown templates for non-PRP documents
- 'markdown_doc': {
- name: 'Markdown Document',
- icon: '📝',
- document_type: 'markdown',
- content: {
- markdown: `# Document Title
-
-## Overview
-
-Provide a brief overview of this document...
-
-## Content
-
-Add your content here...
-
-## Next Steps
-
-- [ ] Action item 1
-- [ ] Action item 2`
- }
- },
-
- 'meeting_notes': {
- name: 'Meeting Notes',
- icon: '📋',
- document_type: 'meeting_notes',
- content: {
- meeting_date: new Date().toISOString().split('T')[0],
- attendees: ['Person 1', 'Person 2'],
- agenda: [
- 'Agenda item 1',
- 'Agenda item 2'
- ],
- notes: 'Meeting discussion notes...',
- action_items: [
- {
- item: 'Action item 1',
- owner: 'Person Name',
- due_date: 'YYYY-MM-DD'
- }
- ],
- next_meeting: 'YYYY-MM-DD'
- }
- }
-};
-
-/* ——————————————————————————————————————————— */
-/* Main component */
-/* ——————————————————————————————————————————— */
-export const DocsTab = ({
- tasks,
- project
-}: {
- tasks: Task[];
- project?: {
- id: string;
- title: string;
- created_at?: string;
- updated_at?: string;
- } | null;
-}) => {
- // Document state
- const [documents, setDocuments] = useState([]);
- const [selectedDocument, setSelectedDocument] = useState(null);
- const [isEditing, setIsEditing] = useState(false);
- const [isSaving, setIsSaving] = useState(false);
- const [loading, setLoading] = useState(false);
- const [showTemplateModal, setShowTemplateModal] = useState(false);
- const [showVersionHistory, setShowVersionHistory] = useState(false);
- const [viewMode, setViewMode] = useState<'beautiful' | 'markdown'>('beautiful');
-
- // Dark mode detection
- const [isDarkMode, setIsDarkMode] = useState(false);
-
- useEffect(() => {
- const checkDarkMode = () => {
- const htmlElement = document.documentElement;
- const hasDarkClass = htmlElement.classList.contains('dark');
- const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
- setIsDarkMode(hasDarkClass || prefersDark);
- };
-
- checkDarkMode();
-
- // Listen for changes
- const observer = new MutationObserver(checkDarkMode);
- observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
-
- const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
- mediaQuery.addEventListener('change', checkDarkMode);
-
- return () => {
- observer.disconnect();
- mediaQuery.removeEventListener('change', checkDarkMode);
- };
- }, []);
-
- // Knowledge management state
- const [showTechnicalModal, setShowTechnicalModal] = useState(false);
- const [showBusinessModal, setShowBusinessModal] = useState(false);
- const [selectedTechnicalSources, setSelectedTechnicalSources] = useState([]);
- const [selectedBusinessSources, setSelectedBusinessSources] = useState([]);
- const [showAddSourceModal, setShowAddSourceModal] = useState(false);
- const [sourceType, setSourceType] = useState<'technical' | 'business'>('technical');
- const [knowledgeItems, setKnowledgeItems] = useState([]);
- const [activeProgressId, setActiveProgressId] = useState(null);
- const { showToast } = useToast();
-
- // Poll for crawl progress
- const crawlProgress = useCrawlProgressPolling(activeProgressId);
-
- // Load project documents from the project data
- const loadProjectDocuments = async () => {
- if (!project?.id || !project.docs) return;
-
- try {
- setLoading(true);
-
- // Use the docs directly from the project data
- const projectDocuments: ProjectDoc[] = project.docs.map((doc: any) => ({
- id: doc.id,
- title: doc.title || 'Untitled Document',
- created_at: doc.created_at,
- updated_at: doc.updated_at,
- content: doc.content,
- document_type: doc.document_type || 'document'
- }));
-
- setDocuments(projectDocuments);
-
- // Auto-select first document if available and no document is currently selected
- if (projectDocuments.length > 0 && !selectedDocument) {
- setSelectedDocument(projectDocuments[0]);
- }
-
- console.log(`Loaded ${projectDocuments.length} documents from project data`);
- } catch (error) {
- console.error('Failed to load documents:', error);
- showToast('Failed to load documents', 'error');
- } finally {
- setLoading(false);
- }
- };
-
- // Create new document from template
- const createDocumentFromTemplate = async (templateKey: string) => {
- if (!project?.id) return;
-
- const template = DOCUMENT_TEMPLATES[templateKey as keyof typeof DOCUMENT_TEMPLATES];
- if (!template) return;
-
- try {
- setIsSaving(true);
-
- // Create the document in the database first
- const newDocument = await projectService.createDocument(project.id, {
- title: template.name,
- content: template.content,
- document_type: template.document_type,
- tags: []
- });
-
- // Add to documents list with the real document from the database
- setDocuments(prev => [...prev, newDocument]);
- setSelectedDocument(newDocument);
-
- console.log('Document created successfully:', newDocument);
- showToast('Document created successfully', 'success');
- setShowTemplateModal(false);
- } catch (error) {
- console.error('Failed to create document:', error);
- showToast(
- error instanceof Error ? error.message : 'Failed to create document',
- 'error'
- );
- } finally {
- setIsSaving(false);
- }
- };
-
- // Save document changes
- const saveDocument = async () => {
- if (!selectedDocument || !project?.id) return;
-
- try {
- setIsSaving(true);
-
- // Call backend API to persist changes
- const updatedDocument = await projectService.updateDocument(
- project.id,
- selectedDocument.id,
- {
- title: selectedDocument.title,
- content: selectedDocument.content,
- tags: selectedDocument.tags,
- author: selectedDocument.author
- }
- );
-
- // Update local state with backend response
- setDocuments(prev => prev.map(doc =>
- doc.id === selectedDocument.id ? updatedDocument : doc
- ));
- setSelectedDocument(updatedDocument);
-
- console.log('Document saved successfully:', updatedDocument);
- showToast('Document saved successfully', 'success');
- setIsEditing(false);
- } catch (error) {
- console.error('Failed to save document:', error);
- showToast(
- error instanceof Error ? error.message : 'Failed to save document',
- 'error'
- );
- } finally {
- setIsSaving(false);
- }
- };
-
- // Note: Block editing functions removed - now handled by BlockNoteEditor internally
-
- // Load project data including linked sources
- const loadProjectData = async () => {
- if (!project?.id) return;
-
- try {
- const response = await fetch(`/api/projects/${project.id}`);
- if (!response.ok) throw new Error('Failed to load project data');
-
- const projectData = await response.json();
-
- // Initialize selected sources from saved project data
- const technicalSourceIds = (projectData.technical_sources || []).map((source: any) => source.source_id);
- const businessSourceIds = (projectData.business_sources || []).map((source: any) => source.source_id);
-
- setSelectedTechnicalSources(technicalSourceIds);
- setSelectedBusinessSources(businessSourceIds);
-
- console.log('Loaded project sources:', {
- technical: technicalSourceIds,
- business: businessSourceIds
- });
- } catch (error) {
- console.error('Failed to load project data:', error);
- showToast('Failed to load project sources', 'error');
- }
- };
-
- // Load knowledge items and documents on mount
- useEffect(() => {
- loadKnowledgeItems();
- loadProjectDocuments();
- loadProjectData(); // Load saved sources
-
- // Cleanup function
- return () => {
- console.log('🧹 DocsTab: Cleanup');
- // Polling cleanup happens automatically in hooks
- };
- }, [project?.id]);
-
- // Clear selected document when project changes
- useEffect(() => {
- setSelectedDocument(null);
- }, [project?.id]);
-
- // Handle crawl progress updates
- useEffect(() => {
- if (crawlProgress.data) {
- const status = crawlProgress.data.status;
- console.log('📊 Crawl progress update:', crawlProgress.data);
-
- if (status === 'completed') {
- showToast('Crawling completed successfully', 'success');
- loadKnowledgeItems(); // Reload knowledge items
- setActiveProgressId(null); // Clear active progress
- } else if (status === 'failed' || status === 'error') {
- const errorMsg = crawlProgress.data.error || 'Crawling failed';
- showToast(`Crawling failed: ${errorMsg}`, 'error');
- setActiveProgressId(null); // Clear active progress
- }
- }
- }, [crawlProgress.data, showToast]);
-
- // Existing knowledge loading function
- const loadKnowledgeItems = async (knowledgeType?: 'technical' | 'business') => {
- try {
- setLoading(true);
- const response = await knowledgeBaseService.getKnowledgeItems({
- knowledge_type: knowledgeType,
- page: 1,
- per_page: 50
- });
- setKnowledgeItems(response.items);
- } catch (error) {
- console.error('Failed to load knowledge items:', error);
- showToast('Failed to load knowledge items', 'error');
- setKnowledgeItems([]);
- } finally {
- setLoading(false);
- }
- };
-
- // Knowledge management helper functions (simplified for brevity)
- const transformToLegacyFormat = (items: KnowledgeItem[]) => {
- return items.map(item => ({
- id: item.id,
- title: item.title,
- type: item.metadata.source_type || 'url',
- lastUpdated: new Date(item.updated_at).toLocaleDateString()
- }));
- };
-
- const technicalSources = transformToLegacyFormat(
- knowledgeItems.filter(item => item.metadata.knowledge_type === 'technical')
- );
-
- const businessSources = transformToLegacyFormat(
- knowledgeItems.filter(item => item.metadata.knowledge_type === 'business')
- );
-
- const toggleTechnicalSource = (id: string) => {
- setSelectedTechnicalSources(prev => prev.includes(id) ? prev.filter(item => item !== id) : [...prev, id]);
- };
- const toggleBusinessSource = (id: string) => {
- setSelectedBusinessSources(prev => prev.includes(id) ? prev.filter(item => item !== id) : [...prev, id]);
- };
- const saveTechnicalSources = async () => {
- if (!project?.id) return;
-
- try {
- await projectService.updateProject(project.id, {
- technical_sources: selectedTechnicalSources
- });
- showToast('Technical sources updated successfully', 'success');
- setShowTechnicalModal(false);
- // Reload project data to reflect the changes
- await loadProjectData();
- } catch (error) {
- console.error('Failed to save technical sources:', error);
- showToast('Failed to update technical sources', 'error');
- }
- };
-
- const saveBusinessSources = async () => {
- if (!project?.id) return;
-
- try {
- await projectService.updateProject(project.id, {
- business_sources: selectedBusinessSources
- });
- showToast('Business sources updated successfully', 'success');
- setShowBusinessModal(false);
- // Reload project data to reflect the changes
- await loadProjectData();
- } catch (error) {
- console.error('Failed to save business sources:', error);
- showToast('Failed to update business sources', 'error');
- }
- };
-
- const handleStartCrawl = async (progressId: string, initialData: any) => {
- console.log(`🚀 Starting crawl tracking for: ${progressId}`);
- setActiveProgressId(progressId);
- showToast('Crawling started - tracking progress', 'success');
- };
-
- const openAddSourceModal = (type: 'technical' | 'business') => {
- setSourceType(type);
- setShowAddSourceModal(true);
- };
-
- return (
-
-
- {/* Document Header */}
-
-
- {/* Document Cards Container */}
-
-
- {documents.map(doc => (
- {
- try {
- // Call API to delete from database first
- await projectService.deleteDocument(project.id, docId);
-
- // Then remove from local state
- setDocuments(prev => prev.filter(d => d.id !== docId));
- if (selectedDocument?.id === docId) {
- setSelectedDocument(documents.find(d => d.id !== docId) || null);
- }
- showToast('Document deleted', 'success');
- } catch (error) {
- console.error('Failed to delete document:', error);
- showToast('Failed to delete document', 'error');
- }
- }}
- isDarkMode={isDarkMode}
- />
- ))}
-
- {/* Add New Document Card */}
- setShowTemplateModal(true)} />
-
-
-
- {/* Document Content */}
- {loading ? (
-
- ) : selectedDocument ? (
- // Show PRPViewer in beautiful mode for all documents
- viewMode === 'beautiful' ? (
-
- ) : (
-
{
- try {
- setIsSaving(true);
-
- // Call backend API to persist changes
- const savedDocument = await projectService.updateDocument(
- project.id,
- updatedDocument.id,
- {
- title: updatedDocument.title,
- content: updatedDocument.content,
- tags: updatedDocument.tags,
- author: updatedDocument.author
- }
- );
-
- // Update local state with backend response
- setSelectedDocument(savedDocument);
- setDocuments(prev => prev.map(doc =>
- doc.id === updatedDocument.id ? savedDocument : doc
- ));
-
- console.log('Document saved via MilkdownEditor');
- showToast('Document saved successfully', 'success');
- } catch (error) {
- console.error('Failed to save document:', error);
- showToast(
- error instanceof Error ? error.message : 'Failed to save document',
- 'error'
- );
- } finally {
- setIsSaving(false);
- }
- }}
- className="mb-8"
- />
- )
- ) : (
-
-
-
No documents found
-
Create a new document to get started
-
- )}
-
- {/* Knowledge Sections */}
-
- technicalSources.find(source => source.id === id))}
- onAddClick={() => setShowTechnicalModal(true)}
- />
- businessSources.find(source => source.id === id))}
- onAddClick={() => setShowBusinessModal(true)}
- />
-
-
-
- {/* Template Selection Modal */}
- {showTemplateModal && (
-
setShowTemplateModal(false)}
- onSelectTemplate={createDocumentFromTemplate}
- isCreating={isSaving}
- />
- )}
-
- {/* Existing Modals (simplified for brevity) */}
- {showTechnicalModal && (
- setShowTechnicalModal(false)}
- onAddSource={() => openAddSourceModal('technical')}
- />
- )}
-
- {showBusinessModal && (
- setShowBusinessModal(false)}
- onAddSource={() => openAddSourceModal('business')}
- />
- )}
-
- {showAddSourceModal && (
- setShowAddSourceModal(false)}
- onSuccess={() => {
- loadKnowledgeItems();
- setShowAddSourceModal(false);
- }}
- onStartCrawl={handleStartCrawl}
- />
- )}
-
- {/* Version History Modal */}
- {showVersionHistory && project && (
- setShowVersionHistory(false)}
- onRestore={() => {
- // Reload documents after restore
- loadProjectDocuments();
- setShowVersionHistory(false);
- }}
- />
- )}
-
- );
-};
-
-
-/* ——————————————————————————————————————————— */
-/* Helper components */
-/* ——————————————————————————————————————————— */
-
-// ArchonEditor component removed - replaced with BlockNoteEditor
-
-// Template Modal Component
-const TemplateModal: React.FC<{
- onClose: () => void;
- onSelectTemplate: (templateKey: string) => void;
- isCreating: boolean;
-}> = ({ onClose, onSelectTemplate, isCreating }) => {
- const templates = Object.entries(DOCUMENT_TEMPLATES);
-
- const getTemplateDescription = (key: string, template: any) => {
- const descriptions: Record = {
- 'prp_base': 'Comprehensive template for implementing new features with full context, validation loops, and structured implementation blueprint.',
- 'prp_task': 'Focused template for specific tasks or bug fixes with clear steps and validation criteria.',
- 'prp_planning': 'Strategic template for architecture planning and system design with risk analysis and success metrics.',
- 'markdown_doc': 'Simple markdown document for general documentation and notes.',
- 'meeting_notes': 'Structured template for meeting notes with attendees, agenda, and action items.'
- };
- return descriptions[key] || 'Document template';
- };
-
- return (
-
-
-
-
-
-
- Choose a Template
-
-
-
-
-
- {templates.map(([key, template]) => (
-
- ))}
-
-
- {isCreating && (
-
-
-
Creating document...
-
- )}
-
-
-
- );
-};
-
-const KnowledgeSection: React.FC<{
- title: string;
- color: 'blue' | 'purple' | 'pink' | 'orange';
- sources: any[];
- onAddClick: () => void;
-}> = ({
- title,
- color,
- sources = [],
- onAddClick
-}) => {
- const colorMap = {
- blue: {
- bg: 'bg-blue-500/10',
- border: 'border-blue-500/30',
- text: 'text-blue-600 dark:text-blue-400',
- buttonBg: 'bg-blue-500/20',
- buttonHover: 'hover:bg-blue-500/30',
- buttonBorder: 'border-blue-500/40',
- buttonShadow: 'hover:shadow-[0_0_15px_rgba(59,130,246,0.3)]'
- },
- purple: {
- bg: 'bg-purple-500/10',
- border: 'border-purple-500/30',
- text: 'text-purple-600 dark:text-purple-400',
- buttonBg: 'bg-purple-500/20',
- buttonHover: 'hover:bg-purple-500/30',
- buttonBorder: 'border-purple-500/40',
- buttonShadow: 'hover:shadow-[0_0_15px_rgba(168,85,247,0.3)]'
- },
- pink: {
- bg: 'bg-pink-500/10',
- border: 'border-pink-500/30',
- text: 'text-pink-600 dark:text-pink-400',
- buttonBg: 'bg-pink-500/20',
- buttonHover: 'hover:bg-pink-500/30',
- buttonBorder: 'border-pink-500/40',
- buttonShadow: 'hover:shadow-[0_0_15px_rgba(236,72,153,0.3)]'
- },
- orange: {
- bg: 'bg-orange-500/10',
- border: 'border-orange-500/30',
- text: 'text-orange-600 dark:text-orange-400',
- buttonBg: 'bg-orange-500/20',
- buttonHover: 'hover:bg-orange-500/30',
- buttonBorder: 'border-orange-500/40',
- buttonShadow: 'hover:shadow-[0_0_15px_rgba(249,115,22,0.3)]'
- }
- };
- return
-
-
-
- {title}
-
-
-
-
-
- {sources && sources.length > 0 ?
- {sources.map(source => source &&
- {source.type === 'url' ?
:
}
-
-
- {source.title}
-
-
- Updated {source.lastUpdated}
-
-
-
)}
-
:
-
No knowledge sources added yet
-
- Click "Add Sources" to select relevant documents
-
-
}
-
- ;
-};
-
-const SourceSelectionModal: React.FC<{
- title: string;
- sources: any[];
- selectedSources: string[];
- onToggleSource: (id: string) => void;
- onSave: () => void;
- onClose: () => void;
- onAddSource: () => void;
-}> = ({
- title,
- sources,
- selectedSources,
- onToggleSource,
- onSave,
- onClose,
- onAddSource
-}) => {
- const [searchQuery, setSearchQuery] = useState('');
- // Filter sources based on search query
- const filteredSources = sources.filter(source => source.title.toLowerCase().includes(searchQuery.toLowerCase()));
- return
-
-
-
-
- {title}
-
-
-
- {/* Search and Add Source */}
-
-
-
- setSearchQuery(e.target.value)} placeholder="Search sources..." className="w-full bg-white/50 dark:bg-black/70 border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-white rounded-md py-2 pl-10 pr-3 focus:outline-none focus:border-blue-400 focus:shadow-[0_0_10px_rgba(59,130,246,0.2)] transition-all duration-300" />
-
-
-
- {/* Sources List */}
-
- {filteredSources.length > 0 ?
- {filteredSources.map(source =>
onToggleSource(source.id)} className={`flex items-center gap-3 p-3 rounded-md cursor-pointer transition-all duration-200
- ${selectedSources.includes(source.id) ? 'bg-blue-100/80 dark:bg-blue-900/30 border border-blue-300 dark:border-blue-500/50' : 'bg-white/50 dark:bg-black/30 border border-gray-200 dark:border-gray-800 hover:border-gray-300 dark:hover:border-gray-700'}`}>
-
- {selectedSources.includes(source.id) && }
-
- {source.type === 'url' ?
:
}
-
-
- {source.title}
-
-
- Updated {source.lastUpdated}
-
-
-
)}
-
:
- No sources found matching your search
-
}
-
- {/* Action Buttons */}
-
-
-
-
-
-
-
;
-};
-
-interface AddKnowledgeModalProps {
- sourceType: 'technical' | 'business';
- onClose: () => void;
- onSuccess: () => void;
- onStartCrawl: (progressId: string, initialData: any) => void;
-}
-
-const AddKnowledgeModal = ({
- sourceType,
- onClose,
- onSuccess,
- onStartCrawl
-}: AddKnowledgeModalProps) => {
- const [method, setMethod] = useState<'url' | 'file'>('url');
- const [url, setUrl] = useState('');
- const [updateFrequency, setUpdateFrequency] = useState('7');
- const [tags, setTags] = useState([]);
- const [newTag, setNewTag] = useState('');
- const [selectedFile, setSelectedFile] = useState(null);
- const [loading, setLoading] = useState(false);
- const { showToast } = useToast();
-
- const handleSubmit = async () => {
- try {
- setLoading(true);
-
- if (method === 'url') {
- if (!url.trim()) {
- showToast('Please enter a URL', 'error');
- return;
- }
-
- const result = await knowledgeBaseService.crawlUrl({
- url: url.trim(),
- knowledge_type: sourceType,
- tags,
- update_frequency: parseInt(updateFrequency)
- });
-
- // Check if result contains a progressId for progress tracking
- if ((result as any).progressId) {
- // Start progress tracking via polling
- onStartCrawl((result as any).progressId, {
- currentUrl: url.trim(),
- totalPages: 0,
- processedPages: 0
- });
-
- showToast('Crawling started - tracking progress', 'success');
- onClose(); // Close modal immediately
- } else {
- // Fallback for immediate response
- showToast((result as any).message || 'Crawling started', 'success');
- onSuccess();
- }
- } else {
- if (!selectedFile) {
- showToast('Please select a file', 'error');
- return;
- }
-
- const result = await knowledgeBaseService.uploadDocument(selectedFile, {
- knowledge_type: sourceType,
- tags
- });
-
- showToast((result as any).message || 'Document uploaded successfully', 'success');
- onSuccess();
- }
- } catch (error) {
- console.error('Failed to add knowledge:', error);
- showToast('Failed to add knowledge source', 'error');
- } finally {
- setLoading(false);
- }
- };
-
- return
-
-
- Add {sourceType === 'technical' ? 'Technical' : 'Business'} Knowledge Source
-
-
- {/* Source Type Selection */}
-
-
-
-
-
- {/* URL Input */}
- {method === 'url' &&
- setUrl(e.target.value)} placeholder="https://..." accentColor="blue" />
-
}
-
- {/* File Upload */}
- {method === 'file' &&
-
-
setSelectedFile(e.target.files?.[0] || null)}
- className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-purple-50 file:text-purple-700 hover:file:bg-purple-100"
- />
-
- Supports PDF, MD, DOC up to 10MB
-
-
}
-
- {/* Update Frequency */}
- {method === 'url' &&
-
}
-
- {/* Tags */}
-
-
-
- {tags.map(tag =>
- {tag}
- )}
-
-
setNewTag(e.target.value)} onKeyDown={e => {
- if (e.key === 'Enter' && newTag.trim()) {
- setTags([...tags, newTag.trim()]);
- setNewTag('');
- }
- }} placeholder="Add tags..." accentColor="purple" />
-
-
- {/* Action Buttons */}
-
-
-
-
-
-
;
-};
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/DocumentCard.tsx b/archon-ui-main/src/components/project-tasks/DocumentCard.tsx
deleted file mode 100644
index e6ec5b9b..00000000
--- a/archon-ui-main/src/components/project-tasks/DocumentCard.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-import React, { useState } from 'react';
-import { Rocket, Code, Briefcase, Users, FileText, X, Plus, Clipboard } from 'lucide-react';
-import { useToast } from '../../contexts/ToastContext';
-
-export interface ProjectDoc {
- id: string;
- title: string;
- content: any;
- document_type?: string;
- updated_at: string;
- created_at?: string;
-}
-
-interface DocumentCardProps {
- document: ProjectDoc;
- isActive: boolean;
- onSelect: (doc: ProjectDoc) => void;
- onDelete: (docId: string) => void;
- isDarkMode: boolean;
-}
-
-export const DocumentCard: React.FC = ({
- document,
- isActive,
- onSelect,
- onDelete,
- isDarkMode
-}) => {
- const [showDelete, setShowDelete] = useState(false);
- const { showToast } = useToast();
-
- const getDocumentIcon = (type?: string) => {
- switch (type) {
- case 'prp': return ;
- case 'technical': return ;
- case 'business': return ;
- case 'meeting_notes': return ;
- default: return ;
- }
- };
-
- const getTypeColor = (type?: string) => {
- switch (type) {
- case 'prp': return 'bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/30';
- case 'technical': return 'bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/30';
- case 'business': return 'bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/30';
- case 'meeting_notes': return 'bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/30';
- default: return 'bg-gray-500/10 text-gray-600 dark:text-gray-400 border-gray-500/30';
- }
- };
-
- const handleCopyId = (e: React.MouseEvent) => {
- e.stopPropagation();
- navigator.clipboard.writeText(document.id);
- showToast('Document ID copied to clipboard', 'success');
-
- // Visual feedback
- const button = e.currentTarget;
- const originalHTML = button.innerHTML;
- button.innerHTML = '✓Copied
';
- setTimeout(() => {
- button.innerHTML = originalHTML;
- }, 2000);
- };
-
- return (
- onSelect(document)}
- onMouseEnter={() => setShowDelete(true)}
- onMouseLeave={() => setShowDelete(false)}
- >
- {/* Document Type Badge */}
-
- {getDocumentIcon(document.document_type)}
- {document.document_type || 'document'}
-
-
- {/* Title */}
-
- {document.title}
-
-
- {/* Metadata */}
-
- {new Date(document.updated_at || document.created_at || Date.now()).toLocaleDateString()}
-
-
- {/* ID Display Section - Always visible for active, hover for others */}
-
-
- {document.id.slice(0, 8)}...
-
-
-
-
- {/* Delete Button */}
- {showDelete && !isActive && (
-
- )}
-
- );
-};
-
-// New Document Card Component
-interface NewDocumentCardProps {
- onClick: () => void;
-}
-
-export const NewDocumentCard: React.FC = ({ onClick }) => {
- return (
-
- );
-};
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/DraggableTaskCard.tsx b/archon-ui-main/src/components/project-tasks/DraggableTaskCard.tsx
deleted file mode 100644
index 62435e3b..00000000
--- a/archon-ui-main/src/components/project-tasks/DraggableTaskCard.tsx
+++ /dev/null
@@ -1,275 +0,0 @@
-import React, { useRef, useState } from 'react';
-import { useDrag, useDrop } from 'react-dnd';
-import { Edit, Trash2, RefreshCw, Tag, Clipboard } from 'lucide-react';
-import { Task } from './TaskTableView';
-import { ItemTypes, getAssigneeIcon, getAssigneeGlow, getOrderColor, getOrderGlow } from '../../lib/task-utils';
-import { useToast } from '../../contexts/ToastContext';
-
-export interface DraggableTaskCardProps {
- task: Task;
- index: number;
- onView: () => void;
- onComplete: () => void;
- onDelete: (task: Task) => void;
- onTaskReorder: (taskId: string, targetIndex: number, status: Task['status']) => void;
- hoveredTaskId?: string | null;
- onTaskHover?: (taskId: string | null) => void;
- selectedTasks?: Set;
- onTaskSelect?: (taskId: string) => void;
-}
-
-export const DraggableTaskCard = ({
- task,
- index,
- onView,
- onComplete,
- onDelete,
- onTaskReorder,
- hoveredTaskId,
- onTaskHover,
- selectedTasks,
- onTaskSelect,
-}: DraggableTaskCardProps) => {
- const { showToast } = useToast();
-
- const [{ isDragging }, drag] = useDrag({
- type: ItemTypes.TASK,
- item: { id: task.id, status: task.status, index },
- collect: (monitor) => ({
- isDragging: !!monitor.isDragging()
- })
- });
-
- const [, drop] = useDrop({
- accept: ItemTypes.TASK,
- hover: (draggedItem: { id: string; status: Task['status']; index: number }, monitor) => {
- if (!monitor.isOver({ shallow: true })) return;
- if (draggedItem.id === task.id) return;
- if (draggedItem.status !== task.status) return;
-
- const draggedIndex = draggedItem.index;
- const hoveredIndex = index;
-
- if (draggedIndex === hoveredIndex) return;
-
-
- // Move the task immediately for visual feedback (same pattern as table view)
- onTaskReorder(draggedItem.id, hoveredIndex, task.status);
-
- // Update the dragged item's index to prevent re-triggering
- draggedItem.index = hoveredIndex;
- }
- });
-
- const [isFlipped, setIsFlipped] = useState(false);
-
- const toggleFlip = (e: React.MouseEvent) => {
- e.stopPropagation();
- setIsFlipped(!isFlipped);
- };
-
- const isHighlighted = hoveredTaskId === task.id;
- const isSelected = selectedTasks?.has(task.id) || false;
-
- const handleMouseEnter = () => {
- onTaskHover?.(task.id);
- };
-
- const handleMouseLeave = () => {
- onTaskHover?.(null);
- };
-
- const handleTaskClick = (e: React.MouseEvent) => {
- if (e.ctrlKey || e.metaKey) {
- e.stopPropagation();
- onTaskSelect?.(task.id);
- }
- };
-
-
- // Card styling - using CSS-based height animation for better scrolling
-
- // Card styling constants
- const cardScale = 'scale-100';
- const cardOpacity = 'opacity-100';
-
- // Subtle highlight effect for related tasks - applied to the card, not parent
- const highlightGlow = isHighlighted
- ? 'border-cyan-400/50 shadow-[0_0_8px_rgba(34,211,238,0.2)]'
- : '';
-
- // Selection styling
- const selectionGlow = isSelected
- ? 'border-blue-500 shadow-[0_0_12px_rgba(59,130,246,0.4)] bg-blue-50/30 dark:bg-blue-900/20'
- : '';
-
- // Simplified hover effect - just a glowing border
- const hoverEffectClasses = 'group-hover:border-cyan-400/70 dark:group-hover:border-cyan-500/50 group-hover:shadow-[0_0_15px_rgba(34,211,238,0.4)] dark:group-hover:shadow-[0_0_15px_rgba(34,211,238,0.6)]';
-
- // Base card styles with proper rounded corners
- const cardBaseStyles = 'bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border border-gray-200 dark:border-gray-700 rounded-lg';
-
- // Transition settings
- const transitionStyles = 'transition-all duration-200 ease-in-out';
-
- return (
- drag(drop(node))}
- style={{
- perspective: '1000px',
- transformStyle: 'preserve-3d'
- }}
- className={`flip-card w-full min-h-[140px] cursor-move relative ${cardScale} ${cardOpacity} ${isDragging ? 'opacity-50 scale-90' : ''} ${transitionStyles} group`}
- onMouseEnter={handleMouseEnter}
- onMouseLeave={handleMouseLeave}
- onClick={handleTaskClick}
- >
-
- {/* Front side with subtle hover effect */}
-
- {/* Priority indicator */}
-
-
- {/* Content container with fixed padding - exactly matching back side structure */}
-
-
-
-
- {task.feature}
-
-
- {/* Task order display */}
-
- {task.task_order}
-
-
- {/* Action buttons group */}
-
-
-
-
-
-
-
-
- {task.title}
-
-
- {/* Spacer to push assignee section to bottom */}
-
-
-
-
-
- {getAssigneeIcon(task.assignee?.name || 'User')}
-
-
{task.assignee?.name || 'User'}
-
-
-
-
-
-
- {/* Back side */}
- {/* Back side with same hover effect */}
-
- {/* Priority indicator */}
-
-
- {/* Content container with fixed padding */}
-
-
-
- {task.title}
-
-
-
-
- {/* Description container with absolute positioning inside parent bounds */}
-
-
-
-
-
- );
-};
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/EditTaskModal.tsx b/archon-ui-main/src/components/project-tasks/EditTaskModal.tsx
deleted file mode 100644
index fc00312c..00000000
--- a/archon-ui-main/src/components/project-tasks/EditTaskModal.tsx
+++ /dev/null
@@ -1,243 +0,0 @@
-import React, { memo, useCallback, useMemo, useState, useEffect, useRef } from 'react';
-import { X } from 'lucide-react';
-import { Button } from '../ui/Button';
-import { ArchonLoadingSpinner } from '../animations/Animations';
-import { DebouncedInput, FeatureInput } from './TaskInputComponents';
-import type { Task } from './TaskTableView';
-
-interface EditTaskModalProps {
- isModalOpen: boolean;
- editingTask: Task | null;
- projectFeatures: any[];
- isLoadingFeatures: boolean;
- isSavingTask: boolean;
- onClose: () => void;
- onSave: (task: Task) => Promise;
- getTasksForPrioritySelection: (status: Task['status']) => Array<{value: number, label: string}>;
-}
-
-const ASSIGNEE_OPTIONS = ['User', 'Archon', 'AI IDE Agent'] as const;
-
-// Removed debounce utility - now using DebouncedInput component
-
-export const EditTaskModal = memo(({
- isModalOpen,
- editingTask,
- projectFeatures,
- isLoadingFeatures,
- isSavingTask,
- onClose,
- onSave,
- getTasksForPrioritySelection
-}: EditTaskModalProps) => {
- const [localTask, setLocalTask] = useState(null);
-
- // Diagnostic: Track render count
- const renderCount = useRef(0);
-
- useEffect(() => {
- renderCount.current++;
- console.log(`[EditTaskModal] Render #${renderCount.current}`, {
- localTask: localTask?.title,
- isModalOpen,
- timestamp: Date.now()
- });
- });
-
- // Sync local state with editingTask when it changes
- useEffect(() => {
- if (editingTask) {
- setLocalTask(editingTask);
- }
- }, [editingTask]);
-
- const priorityOptions = useMemo(() => {
- console.log(`[EditTaskModal] Recalculating priorityOptions for status: ${localTask?.status || 'todo'}`);
- return getTasksForPrioritySelection(localTask?.status || 'todo');
- }, [localTask?.status, getTasksForPrioritySelection]);
-
- // Memoized handlers for input changes
- const handleTitleChange = useCallback((value: string) => {
- console.log('[EditTaskModal] Title changed via DebouncedInput:', value);
- setLocalTask(prev => prev ? { ...prev, title: value } : null);
- }, []);
-
- const handleDescriptionChange = useCallback((value: string) => {
- console.log('[EditTaskModal] Description changed via DebouncedInput:', value);
- setLocalTask(prev => prev ? { ...prev, description: value } : null);
- }, []);
-
- const handleFeatureChange = useCallback((value: string) => {
- console.log('[EditTaskModal] Feature changed via FeatureInput:', value);
- setLocalTask(prev => prev ? { ...prev, feature: value } : null);
- }, []);
-
- const handleStatusChange = useCallback((e: React.ChangeEvent) => {
- const newStatus = e.target.value as Task['status'];
- const newOrder = getTasksForPrioritySelection(newStatus)[0]?.value || 1;
- setLocalTask(prev => prev ? { ...prev, status: newStatus, task_order: newOrder } : null);
- }, [getTasksForPrioritySelection]);
-
- const handlePriorityChange = useCallback((e: React.ChangeEvent) => {
- setLocalTask(prev => prev ? { ...prev, task_order: parseInt(e.target.value) } : null);
- }, []);
-
- const handleAssigneeChange = useCallback((e: React.ChangeEvent) => {
- setLocalTask(prev => prev ? {
- ...prev,
- assignee: { name: e.target.value as 'User' | 'Archon' | 'AI IDE Agent', avatar: '' }
- } : null);
- }, []);
-
- const handleSave = useCallback(() => {
- if (localTask) {
- onSave(localTask);
- }
- }, [localTask, onSave]);
-
- const handleClose = useCallback(() => {
- onClose();
- }, [onClose]);
-
- if (!isModalOpen) return null;
-
- return (
-
-
-
-
-
- {editingTask?.id ? 'Edit Task' : 'New Task'}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}, (prevProps, nextProps) => {
- // Custom comparison function to prevent unnecessary re-renders
- // Only re-render if these specific props change
- const isEqual = (
- prevProps.isModalOpen === nextProps.isModalOpen &&
- prevProps.editingTask?.id === nextProps.editingTask?.id &&
- prevProps.editingTask?.title === nextProps.editingTask?.title &&
- prevProps.editingTask?.description === nextProps.editingTask?.description &&
- prevProps.editingTask?.status === nextProps.editingTask?.status &&
- prevProps.editingTask?.assignee?.name === nextProps.editingTask?.assignee?.name &&
- prevProps.editingTask?.feature === nextProps.editingTask?.feature &&
- prevProps.editingTask?.task_order === nextProps.editingTask?.task_order &&
- prevProps.isSavingTask === nextProps.isSavingTask &&
- prevProps.isLoadingFeatures === nextProps.isLoadingFeatures &&
- prevProps.projectFeatures === nextProps.projectFeatures // Reference equality check
- );
-
- if (!isEqual) {
- console.log('[EditTaskModal] Props changed, re-rendering');
- }
-
- return isEqual;
-});
-
-EditTaskModal.displayName = 'EditTaskModal';
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/FeaturesTab.tsx b/archon-ui-main/src/components/project-tasks/FeaturesTab.tsx
deleted file mode 100644
index 10add1b4..00000000
--- a/archon-ui-main/src/components/project-tasks/FeaturesTab.tsx
+++ /dev/null
@@ -1,814 +0,0 @@
-import { useCallback, useState, useEffect, useMemo } from 'react'
-import '@xyflow/react/dist/style.css'
-import {
- ReactFlow,
- Node,
- Edge,
- Controls,
- MarkerType,
- NodeProps,
- Handle,
- Position,
- NodeChange,
- applyNodeChanges,
- EdgeChange,
- applyEdgeChanges,
- Connection,
- addEdge,
-} from '@xyflow/react'
-import { Layout, Component as ComponentIcon, X, Trash2, Edit, Save } from 'lucide-react'
-import { projectService } from '../../services/projectService'
-import { useToast } from '../../contexts/ToastContext'
-
-// Define custom node types following React Flow v12 pattern
-type PageNodeData = {
- label: string;
- type: string;
- route: string;
- components: number;
-};
-
-type ServiceNodeData = {
- label: string;
- type: string;
-};
-
-// Define union type for all custom nodes
-type CustomNodeTypes = Node | Node;
-
-// Custom node components
-const PageNode = ({ data }: NodeProps) => {
- const pageData = data as PageNodeData;
- return (
-
-
-
-
-
{pageData.type}
-
-
Route: {pageData.route}
-
Components: {pageData.components}
-
-
-
-
- );
-};
-
-const ServiceNode = ({ data }: NodeProps) => {
- const serviceData = data as ServiceNodeData;
- return (
-
-
-
-
-
-
{serviceData.label}
-
-
{serviceData.type}
-
-
-
- );
-};
-
-const nodeTypes = {
- page: PageNode,
- service: ServiceNode,
-}
-
-// Default/fallback nodes for when project has no features data
-const defaultNodes: Node[] = [
- {
- id: 'start',
- type: 'page',
- data: {
- label: 'Start App',
- type: 'Entry Point',
- route: '/',
- components: 3,
- },
- position: {
- x: 400,
- y: 0,
- },
- },
- {
- id: 'home',
- type: 'page',
- data: {
- label: 'Homepage',
- type: 'Main View',
- route: '/home',
- components: 6,
- },
- position: {
- x: 400,
- y: 150,
- },
- },
-];
-
-// Default/fallback edges
-const defaultEdges: Edge[] = [
- {
- id: 'start-home',
- source: 'start',
- target: 'home',
- animated: true,
- style: {
- stroke: '#22d3ee',
- },
- markerEnd: {
- type: MarkerType.ArrowClosed,
- color: '#22d3ee',
- },
- },
-];
-
-interface FeaturesTabProps {
- project?: {
- id: string;
- title: string;
- features?: any[];
- } | null;
-}
-
-export const FeaturesTab = ({ project }: FeaturesTabProps) => {
- const [nodes, setNodes] = useState([])
- const [edges, setEdges] = useState([])
- const [loading, setLoading] = useState(true)
- const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
- const [nodeToDelete, setNodeToDelete] = useState(null)
- const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
- const [editingNode, setEditingNode] = useState(null)
- const [showEditModal, setShowEditModal] = useState(false)
- const [isSaving, setIsSaving] = useState(false)
-
- const { showToast } = useToast()
-
- // Load features from project or show empty state
- useEffect(() => {
- if (project?.features && Array.isArray(project.features) && project.features.length > 0) {
- // Ensure all nodes have required properties with defaults
- const normalizedNodes = project.features.map((node: any, index: number) => ({
- ...node,
- // Ensure position exists with sensible defaults
- position: node.position || {
- x: 250 + (index % 3) * 250, // Spread horizontally
- y: 200 + Math.floor(index / 3) * 150 // Stack vertically
- },
- // Ensure type exists (fallback based on data structure)
- type: node.type || (node.data?.route ? 'page' : 'service'),
- // Ensure data exists
- data: node.data || { label: 'Unknown', type: 'Unknown Component' }
- }));
-
- setNodes(normalizedNodes)
- // Generate edges based on the flow (simplified logic)
- const generatedEdges = generateEdgesFromNodes(normalizedNodes)
- setEdges(generatedEdges)
- } else {
- // Show empty state - no nodes or edges
- setNodes([])
- setEdges([])
- }
- setLoading(false)
- }, [project])
-
- // Helper function to generate edges based on node positioning and types
- const generateEdgesFromNodes = (nodes: Node[]): Edge[] => {
- const edges: Edge[] = []
-
- // Sort nodes by y position to create a logical flow (with safety check for position)
- const sortedNodes = [...nodes].sort((a, b) => {
- const aY = a.position?.y || 0;
- const bY = b.position?.y || 0;
- return aY - bY;
- })
-
- for (let i = 0; i < sortedNodes.length - 1; i++) {
- const currentNode = sortedNodes[i]
- const nextNode = sortedNodes[i + 1]
-
- // Connect sequential nodes with appropriate styling
- const edgeStyle = currentNode.type === 'service' ? '#d946ef' : '#22d3ee'
-
- edges.push({
- id: `${currentNode.id}-${nextNode.id}`,
- source: currentNode.id,
- target: nextNode.id,
- animated: true,
- style: {
- stroke: edgeStyle,
- },
- markerEnd: {
- type: MarkerType.ArrowClosed,
- color: edgeStyle,
- },
- })
- }
-
- return edges
- }
-
- const onNodesChange = useCallback(
- (changes: NodeChange[]) => {
- setNodes((nds) => applyNodeChanges(changes, nds))
- setHasUnsavedChanges(true)
- },
- [],
- )
-
- const onEdgesChange = useCallback(
- (changes: EdgeChange[]) => {
- setEdges((eds) => applyEdgeChanges(changes, eds))
- setHasUnsavedChanges(true)
- },
- [],
- )
-
- const onConnect = useCallback(
- (connection: Connection) => {
- const sourceNode = nodes.find((node) => node.id === connection.source)
- // Set edge color based on source node type
- const edgeStyle =
- sourceNode?.type === 'service'
- ? {
- stroke: '#d946ef',
- }
- : // Fuchsia for service nodes
- {
- stroke: '#22d3ee',
- } // Cyan for page nodes
- setEdges((eds) =>
- addEdge(
- {
- ...connection,
- animated: true,
- style: edgeStyle,
- markerEnd: {
- type: MarkerType.ArrowClosed,
- color: edgeStyle.stroke,
- },
- },
- eds,
- ),
- )
- setHasUnsavedChanges(true)
- },
- [nodes],
- )
-
- const saveToDatabase = async (nodesToSave = nodes, edgesToSave = edges) => {
- if (!project?.id) {
- console.error('❌ No project ID available for saving features');
- return;
- }
-
- setIsSaving(true);
- try {
- console.log('💾 Saving features to database...');
- await projectService.updateProject(project.id, {
- features: nodesToSave
- });
- console.log('✅ Features saved successfully');
- setHasUnsavedChanges(false);
- } catch (error) {
- console.error('❌ Failed to save features:', error);
- throw error;
- } finally {
- setIsSaving(false);
- }
- };
-
- const handleManualSave = async () => {
- await saveToDatabase();
- };
-
- const addPageNode = async () => {
- const newNode: Node = {
- id: `page-${Date.now()}`,
- type: 'page',
- data: {
- label: `New Page`,
- type: 'Page Component',
- route: '/new-page',
- components: 0,
- },
- position: {
- x: 250,
- y: 200,
- },
- }
- const newNodes = [...nodes, newNode];
- setNodes(newNodes);
- setHasUnsavedChanges(true);
-
- // Auto-save when adding
- try {
- await saveToDatabase(newNodes, edges);
- } catch (error) {
- // Revert on error
- setNodes(nodes);
- }
- }
-
- const addServiceNode = async () => {
- const newNode: Node = {
- id: `service-${Date.now()}`,
- type: 'service',
- data: {
- label: 'New Service',
- type: 'Service Component',
- },
- position: {
- x: 250,
- y: 200,
- },
- }
- const newNodes = [...nodes, newNode];
- setNodes(newNodes);
- setHasUnsavedChanges(true);
-
- // Auto-save when adding
- try {
- await saveToDatabase(newNodes, edges);
- } catch (error) {
- // Revert on error
- setNodes(nodes);
- }
- }
-
- const handleDeleteNode = useCallback(async (event: React.MouseEvent, nodeId: string) => {
- event.stopPropagation();
-
- if (!project?.id) {
- console.error('❌ No project ID available for deleting node');
- return;
- }
-
- // Show custom confirmation dialog
- setNodeToDelete(nodeId);
- setShowDeleteConfirm(true);
- }, [project?.id]);
-
- const confirmDelete = useCallback(async () => {
- if (!nodeToDelete) return;
-
- console.log('🗑️ Deleting node:', nodeToDelete);
-
- try {
- // Remove node from UI
- const newNodes = nodes.filter(node => node.id !== nodeToDelete);
-
- // Remove any edges connected to this node
- const newEdges = edges.filter(edge =>
- edge.source !== nodeToDelete && edge.target !== nodeToDelete
- );
-
- setNodes(newNodes);
- setEdges(newEdges);
-
- // Save to database
- await saveToDatabase(newNodes, newEdges);
- showToast('Node deleted successfully', 'success');
-
- // Close confirmation dialog
- setShowDeleteConfirm(false);
- setNodeToDelete(null);
- } catch (error) {
- console.error('❌ Failed to delete node:', error);
- // Revert UI changes on error
- setNodes(nodes);
- setEdges(edges);
- showToast('Failed to delete node', 'error');
- }
- }, [nodeToDelete, nodes, edges]);
-
- const cancelDelete = useCallback(() => {
- setShowDeleteConfirm(false);
- setNodeToDelete(null);
- }, []);
-
- const handleNodeClick = useCallback((event: React.MouseEvent, node: Node) => {
- setEditingNode(node);
- setShowEditModal(true);
- }, []);
-
- const saveNodeChanges = async (updatedNode: Node) => {
- // Update local state first
- const newNodes = nodes.map(node =>
- node.id === updatedNode.id ? updatedNode : node
- );
- setNodes(newNodes);
-
- // Save to database
- await saveToDatabase(newNodes, edges);
-
- setShowEditModal(false);
- setEditingNode(null);
- };
-
- // Memoize node types with delete and edit functionality
- const nodeTypes = useMemo(() => ({
- page: ({ data, id }: NodeProps) => {
- const pageData = data as any;
- return (
-
-
-
{
- const actualNode = nodes.find(node => node.id === id);
- if (actualNode) {
- handleNodeClick(e, actualNode);
- }
- }}
- >
-
-
-
-
-
-
-
-
{pageData.type}
-
-
Route: {pageData.route}
-
Components: {pageData.components}
-
-
-
-
- );
- },
- service: ({ data, id }: NodeProps) => {
- const serviceData = data as any;
- return (
-
-
-
{
- const actualNode = nodes.find(node => node.id === id);
- if (actualNode) {
- handleNodeClick(e, actualNode);
- }
- }}
- >
-
-
-
-
{serviceData.label}
-
-
-
-
-
-
-
{serviceData.type}
-
-
-
- );
- }
- }), [handleNodeClick, handleDeleteNode, nodes]);
-
- if (loading) {
- return (
-
- )
- }
-
- return (
-
-
-
-
-
-
- Feature Planner {project?.features ? `(${project.features.length} features)` : '(Default)'}
-
-
- {hasUnsavedChanges && (
-
- )}
-
-
-
-
-
- {/* Subtle neon glow at the top */}
-
- {nodes.length === 0 ? (
-
-
-
No features defined
-
Add pages and services to get started
-
- ) : (
-
-
-
- )}
-
-
- {/* Delete Confirmation Modal */}
- {showDeleteConfirm && (
-
n.id === nodeToDelete)?.data.label as string || 'node'}
- />
- )}
-
- {/* Edit Modal */}
- {showEditModal && editingNode && (
- {
- setShowEditModal(false);
- setEditingNode(null);
- }}
- />
- )}
-
-
- )
-}
-
-// Delete Confirmation Modal Component
-const DeleteConfirmModal = ({
- onConfirm,
- onCancel,
- nodeName
-}: {
- onConfirm: () => void;
- onCancel: () => void;
- nodeName: string;
-}) => {
- return (
-
-
-
-
-
-
-
-
-
-
- Delete Node
-
-
- This action cannot be undone
-
-
-
-
-
- Are you sure you want to delete "{nodeName}"?
- This will also remove all related connections.
-
-
-
-
-
-
-
-
-
- );
-};
-
-// Edit Feature Modal Component
-const EditFeatureModal = ({
- node,
- onSave,
- onClose
-}: {
- node: Node;
- onSave: (node: Node) => void;
- onClose: () => void;
-}) => {
- const [name, setName] = useState(node.data.label as string);
- const [route, setRoute] = useState((node.data as any).route || '');
- const [components, setComponents] = useState((node.data as any).components || 0);
-
- const isPageNode = node.type === 'page';
-
- const handleSave = () => {
- const updatedNode = {
- ...node,
- data: {
- ...node.data,
- label: name,
- ...(isPageNode && { route, components })
- }
- };
- onSave(updatedNode);
- };
-
- return (
-
-
-
-
- {isPageNode ? : }
- Edit {isPageNode ? 'Page' : 'Service'}
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
diff --git a/archon-ui-main/src/components/project-tasks/MilkdownEditor.css b/archon-ui-main/src/components/project-tasks/MilkdownEditor.css
deleted file mode 100644
index c9c272d7..00000000
--- a/archon-ui-main/src/components/project-tasks/MilkdownEditor.css
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Milkdown Editor Custom Styles - Archon Theme */
-
-/* Main editor container */
-.milkdown-crepe-editor {
- background: rgba(255, 255, 255, 0.5);
- backdrop-filter: blur(10px);
- border: 1px solid rgba(59, 130, 246, 0.3);
- border-radius: 12px;
- padding: 1.5rem;
- position: relative;
- overflow: hidden;
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
-}
-
-/* Gradient border effect */
-.milkdown-crepe-editor::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 2px;
- background: linear-gradient(90deg, #3b82f6, #a855f7);
- opacity: 0.8;
-}
-
-/* Dark mode container */
-.dark .milkdown-crepe-editor {
- background: rgba(0, 0, 0, 0.3);
- backdrop-filter: blur(20px);
- border-color: rgba(59, 130, 246, 0.5);
- box-shadow: 0 0 20px rgba(59, 130, 246, 0.1);
-}
-
-/* Remove default Crepe theme styling */
-.milkdown-crepe-editor .milkdown {
- background: transparent !important;
- border: none !important;
- box-shadow: none !important;
-}
-
-/* Editor content area */
-.milkdown-crepe-editor .ProseMirror {
- font-family: Inter, system-ui, -apple-system, sans-serif;
- min-height: 400px;
- max-width: 100%;
- padding: 1rem;
- background: transparent;
- color: #1f2937;
- line-height: 1.6;
-}
-
-.dark .milkdown-crepe-editor .ProseMirror {
- color: #f9fafb;
-}
-
-/* Remove dark mode filter - use proper theming instead */
-.milkdown-theme-dark {
- filter: none;
-}
-
-/* Typography */
-.milkdown-crepe-editor h1 {
- font-size: 2rem;
- font-weight: 700;
- margin-bottom: 1rem;
- color: #111827;
-}
-
-.dark .milkdown-crepe-editor h1 {
- color: #f9fafb;
-}
-
-.milkdown-crepe-editor h2 {
- font-size: 1.5rem;
- font-weight: 600;
- margin-top: 1.5rem;
- margin-bottom: 0.75rem;
- color: #374151;
-}
-
-.dark .milkdown-crepe-editor h2 {
- color: #e5e7eb;
-}
-
-.milkdown-crepe-editor h3 {
- font-size: 1.25rem;
- font-weight: 600;
- margin-top: 1rem;
- margin-bottom: 0.5rem;
- color: #4b5563;
-}
-
-.dark .milkdown-crepe-editor h3 {
- color: #d1d5db;
-}
-
-/* Links */
-.milkdown-crepe-editor a {
- color: #3b82f6;
- text-decoration: none;
- transition: color 0.2s;
-}
-
-.milkdown-crepe-editor a:hover {
- color: #2563eb;
- text-decoration: underline;
-}
-
-.dark .milkdown-crepe-editor a {
- color: #60a5fa;
-}
-
-.dark .milkdown-crepe-editor a:hover {
- color: #93bbfc;
-}
-
-/* Code blocks */
-.milkdown-crepe-editor pre {
- background: rgba(0, 0, 0, 0.05);
- border: 1px solid rgba(0, 0, 0, 0.1);
- border-radius: 8px;
- padding: 1rem;
- overflow-x: auto;
- font-family: 'JetBrains Mono', 'Fira Code', monospace;
-}
-
-.dark .milkdown-crepe-editor pre {
- background: rgba(255, 255, 255, 0.05);
- border-color: rgba(255, 255, 255, 0.1);
-}
-
-.milkdown-crepe-editor code {
- background: rgba(59, 130, 246, 0.1);
- padding: 0.125rem 0.375rem;
- border-radius: 4px;
- font-size: 0.875rem;
- font-family: 'JetBrains Mono', 'Fira Code', monospace;
-}
-
-.dark .milkdown-crepe-editor code {
- background: rgba(59, 130, 246, 0.2);
-}
-
-/* Lists */
-.milkdown-crepe-editor ul,
-.milkdown-crepe-editor ol {
- padding-left: 1.5rem;
- margin: 0.5rem 0;
-}
-
-.milkdown-crepe-editor li {
- margin: 0.25rem 0;
-}
-
-/* Blockquotes */
-.milkdown-crepe-editor blockquote {
- border-left: 4px solid #3b82f6;
- padding-left: 1rem;
- margin: 1rem 0;
- color: #6b7280;
- font-style: italic;
-}
-
-.dark .milkdown-crepe-editor blockquote {
- color: #9ca3af;
- border-left-color: #60a5fa;
-}
-
-/* Tables */
-.milkdown-crepe-editor table {
- border-collapse: collapse;
- width: 100%;
- margin: 1rem 0;
-}
-
-.milkdown-crepe-editor th,
-.milkdown-crepe-editor td {
- border: 1px solid rgba(0, 0, 0, 0.1);
- padding: 0.5rem;
- text-align: left;
-}
-
-.dark .milkdown-crepe-editor th,
-.dark .milkdown-crepe-editor td {
- border-color: rgba(255, 255, 255, 0.1);
-}
-
-.milkdown-crepe-editor th {
- background: rgba(59, 130, 246, 0.05);
- font-weight: 600;
-}
-
-.dark .milkdown-crepe-editor th {
- background: rgba(59, 130, 246, 0.1);
-}
-
-/* Toolbar styling */
-.milkdown-crepe-editor .milkdown-toolbar {
- background: transparent;
- border: none;
- padding: 0;
- margin-bottom: 1rem;
-}
-
-/* Toolbar buttons */
-.milkdown-crepe-editor .toolbar-item {
- background: rgba(255, 255, 255, 0.8);
- border: 1px solid rgba(0, 0, 0, 0.1);
- border-radius: 6px;
- padding: 0.375rem 0.75rem;
- margin: 0 0.25rem;
- cursor: pointer;
- transition: all 0.2s;
- color: #374151;
-}
-
-.dark .milkdown-crepe-editor .toolbar-item {
- background: rgba(255, 255, 255, 0.1);
- border-color: rgba(255, 255, 255, 0.2);
- color: #e5e7eb;
-}
-
-.milkdown-crepe-editor .toolbar-item:hover {
- background: #3b82f6;
- border-color: #3b82f6;
- color: white;
- transform: translateY(-1px);
- box-shadow: 0 4px 6px -1px rgba(59, 130, 246, 0.3);
-}
-
-/* Selection */
-.milkdown-crepe-editor .ProseMirror ::selection {
- background: rgba(59, 130, 246, 0.3);
-}
-
-.dark .milkdown-crepe-editor .ProseMirror ::selection {
- background: rgba(96, 165, 250, 0.3);
-}
-
-/* Focus state */
-.milkdown-crepe-editor .ProseMirror:focus {
- outline: none;
-}
-
-/* Placeholder */
-.milkdown-crepe-editor .ProseMirror.is-empty::before {
- content: 'Start writing...';
- color: #9ca3af;
- position: absolute;
- pointer-events: none;
-}
-
-/* Horizontal rule */
-.milkdown-crepe-editor hr {
- border: none;
- height: 1px;
- background: linear-gradient(90deg, transparent, rgba(59, 130, 246, 0.5), transparent);
- margin: 2rem 0;
-}
-
-/* Save button animation */
-@keyframes pulse-glow {
- 0% {
- box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);
- }
- 70% {
- box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
- }
- 100% {
- box-shadow: 0 0 0 0 rgba(59, 130, 246, 0);
- }
-}
-
-.save-button-pulse {
- animation: pulse-glow 2s infinite;
-}
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/MilkdownEditor.tsx b/archon-ui-main/src/components/project-tasks/MilkdownEditor.tsx
deleted file mode 100644
index 6f945ccb..00000000
--- a/archon-ui-main/src/components/project-tasks/MilkdownEditor.tsx
+++ /dev/null
@@ -1,555 +0,0 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { Crepe, CrepeFeature } from '@milkdown/crepe';
-import '@milkdown/crepe/theme/common/style.css';
-import '@milkdown/crepe/theme/frame.css';
-import '@milkdown/crepe/theme/frame-dark.css';
-import './MilkdownEditor.css';
-import { Save, Undo } from 'lucide-react';
-
-interface MilkdownEditorProps {
- document: {
- id: string;
- title: string;
- content?: any;
- created_at: string;
- updated_at: string;
- };
- onSave: (document: any) => void;
- className?: string;
- isDarkMode?: boolean;
-}
-
-export const MilkdownEditor: React.FC = ({
- document: doc,
- onSave,
- className = '',
- isDarkMode = false,
-}) => {
- const editorRef = useRef(null);
- const crepeRef = useRef(null);
- const [isLoading, setIsLoading] = useState(false);
- const [hasChanges, setHasChanges] = useState(false);
- const [isReverted, setIsReverted] = useState(false);
- const [originalContent, setOriginalContent] = useState('');
- const [currentContent, setCurrentContent] = useState('');
-
- // Convert document content to markdown string
- const getMarkdownContent = () => {
- if (typeof doc.content === 'string') {
- return doc.content;
- }
-
- if (doc.content && typeof doc.content === 'object') {
- // If content has a markdown field, use it
- if (doc.content.markdown) {
- return doc.content.markdown;
- }
-
- // Check if this is a PRP document
- if (doc.content.document_type === 'prp' || doc.document_type === 'prp') {
- return convertPRPToMarkdown(doc.content);
- }
-
- // Otherwise, convert the content object to a readable markdown format
- let markdown = `# ${doc.title}\n\n`;
-
- Object.entries(doc.content).forEach(([key, value]) => {
- const sectionTitle = key.replace(/_/g, ' ').charAt(0).toUpperCase() + key.replace(/_/g, ' ').slice(1);
- markdown += `## ${sectionTitle}\n\n`;
-
- if (Array.isArray(value)) {
- value.forEach(item => {
- markdown += `- ${item}\n`;
- });
- markdown += '\n';
- } else if (typeof value === 'object' && value !== null) {
- if (value.description) {
- markdown += `${value.description}\n\n`;
- } else {
- Object.entries(value).forEach(([subKey, subValue]) => {
- markdown += `**${subKey}:** ${subValue}\n\n`;
- });
- }
- } else {
- markdown += `${value}\n\n`;
- }
- });
-
- return markdown;
- }
-
- return `# ${doc.title}\n\nStart writing...`;
- };
-
- // Helper function to format values for markdown
- // Enhanced formatValue to handle complex nested structures
- const formatValue = (value: any, indent = '', depth = 0): string => {
- if (value === null || value === undefined) {
- return '';
- }
-
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
- return String(value);
- }
-
- if (Array.isArray(value)) {
- if (value.length === 0) return '';
-
- // Check if it's a simple array (strings/numbers)
- const isSimple = value.every(item =>
- typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean'
- );
-
- if (isSimple) {
- return value.map(item => `${indent}- ${item}`).join('\n') + '\n';
- }
-
- // Complex array with objects
- return value.map((item, index) => {
- if (typeof item === 'object' && item !== null) {
- const itemLines = formatValue(item, indent + ' ', depth + 1).split('\n');
- const firstLine = itemLines[0];
- const restLines = itemLines.slice(1).join('\n');
-
- if (itemLines.length === 1 || (itemLines.length === 2 && !itemLines[1])) {
- // Single line item
- return `${indent}- ${firstLine}`;
- } else {
- // Multi-line item
- return `${indent}-\n${indent} ${firstLine}${restLines ? '\n' + restLines : ''}`;
- }
- }
- return `${indent}- ${formatValue(item, indent + ' ', depth + 1)}`;
- }).join('\n') + '\n';
- }
-
- if (typeof value === 'object' && value !== null) {
- const entries = Object.entries(value);
- if (entries.length === 0) return '';
-
- // Check if it's a simple object (all values are primitives)
- const isSimple = entries.every(([_, val]) =>
- typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean'
- );
-
- if (isSimple && entries.length <= 3 && depth > 0) {
- // Inline simple objects
- const pairs = entries.map(([k, v]) => `${formatKey(k)}: ${v}`);
- return pairs.join(', ');
- }
-
- let result = '';
- entries.forEach(([key, val], index) => {
- const formattedKey = formatKey(key);
-
- if (val === null || val === undefined) {
- return; // Skip null/undefined
- }
-
- if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {
- result += `${indent}**${formattedKey}:** ${val}\n`;
- } else if (Array.isArray(val)) {
- result += `${indent}**${formattedKey}:**\n${formatValue(val, indent, depth + 1)}`;
- } else if (typeof val === 'object') {
- // Use appropriate heading level based on depth
- const headingLevel = Math.min(depth + 3, 6);
- const heading = '#'.repeat(headingLevel);
- result += `${indent}${heading} ${formattedKey}\n\n${formatValue(val, indent, depth + 1)}`;
- }
-
- // Add spacing between top-level sections
- if (depth === 0 && index < entries.length - 1) {
- result += '\n';
- }
- });
-
- return result;
- }
-
- return String(value);
- };
-
- // Helper to format keys nicely
- const formatKey = (key: string): string => {
- return key
- .replace(/_/g, ' ')
- .replace(/([a-z])([A-Z])/g, '$1 $2')
- .split(' ')
- .filter(word => word.length > 0)
- .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
- .join(' ');
- };
-
- // Convert PRP document structure to readable markdown - fully dynamic
- const convertPRPToMarkdown = (content: any): string => {
- // Handle raw string content
- if (typeof content === 'string') {
- return content;
- }
-
- // Handle null/undefined
- if (!content || typeof content !== 'object') {
- return `# ${doc.title}\n\nNo content available.`;
- }
-
- // Start with title
- let markdown = `# ${content.title || doc.title || 'Untitled Document'}\n\n`;
-
- // Group metadata fields
- const metadataFields = ['version', 'author', 'date', 'status', 'document_type', 'created_at', 'updated_at'];
- const metadata = metadataFields.filter(field => content[field]);
-
- if (metadata.length > 0) {
- markdown += `## Metadata\n\n`;
- metadata.forEach(field => {
- const value = content[field];
- const label = formatKey(field);
- markdown += `- **${label}:** ${value}\n`;
- });
- markdown += '\n';
- }
-
- // Process all other fields dynamically
- const skipFields = ['title', ...metadataFields, 'id', '_id', 'project_id'];
-
- // Sort fields by priority (known important fields first)
- const priorityFields = [
- 'goal', 'goals', 'objective', 'objectives',
- 'why', 'rationale', 'background',
- 'what', 'description', 'overview',
- 'context', 'background_context',
- 'user_personas', 'personas', 'users', 'stakeholders',
- 'user_flows', 'flows', 'journeys', 'workflows',
- 'requirements', 'functional_requirements', 'non_functional_requirements',
- 'success_metrics', 'metrics', 'kpis', 'success_criteria',
- 'timeline', 'roadmap', 'milestones', 'phases',
- 'implementation_plan', 'implementation_roadmap', 'plan',
- 'technical_requirements', 'technical_implementation', 'architecture',
- 'validation_gates', 'testing_strategy', 'quality_gates',
- 'risks', 'risk_assessment', 'mitigation_strategies'
- ];
-
- // Create ordered list of fields
- const orderedFields = [];
- const remainingFields = [];
-
- Object.keys(content).forEach(key => {
- if (skipFields.includes(key)) return;
-
- const lowerKey = key.toLowerCase();
- const priorityIndex = priorityFields.findIndex(pf =>
- lowerKey === pf || lowerKey.includes(pf) || pf.includes(lowerKey)
- );
-
- if (priorityIndex !== -1) {
- orderedFields.push({ key, priority: priorityIndex });
- } else {
- remainingFields.push(key);
- }
- });
-
- // Sort by priority
- orderedFields.sort((a, b) => a.priority - b.priority);
-
- // Process fields in order
- const allFields = [...orderedFields.map(f => f.key), ...remainingFields];
-
- allFields.forEach(key => {
- const value = content[key];
- if (value === null || value === undefined) return;
-
- const sectionTitle = formatKey(key);
- markdown += `## ${sectionTitle}\n\n`;
-
- // Handle different value types
- if (typeof value === 'string') {
- markdown += `${value}\n\n`;
- } else if (typeof value === 'number' || typeof value === 'boolean') {
- markdown += `${value}\n\n`;
- } else if (Array.isArray(value)) {
- markdown += formatValue(value) + '\n';
- } else if (typeof value === 'object') {
- markdown += formatValue(value) + '\n';
- }
- });
-
- return markdown.trim();
- };
-
- // Initialize editor
- useEffect(() => {
- if (!editorRef.current || crepeRef.current) return;
-
- const initialContent = getMarkdownContent();
- setOriginalContent(initialContent);
- setCurrentContent(initialContent);
-
- // Add theme class to root element
- if (isDarkMode) {
- editorRef.current.classList.add('milkdown-theme-dark');
- }
-
- const crepe = new Crepe({
- root: editorRef.current,
- defaultValue: initialContent,
- features: {
- [CrepeFeature.HeaderMeta]: true,
- [CrepeFeature.LinkTooltip]: true,
- [CrepeFeature.ImageBlock]: true,
- [CrepeFeature.BlockEdit]: true,
- [CrepeFeature.ListItem]: true,
- [CrepeFeature.CodeBlock]: true,
- [CrepeFeature.Table]: true,
- [CrepeFeature.Toolbar]: true,
- },
- });
-
- crepe.create().then(() => {
- console.log('Milkdown editor created');
-
- // Set up content change tracking
- const editorElement = editorRef.current?.querySelector('.ProseMirror');
- if (editorElement) {
- // Listen for input events on the editor
- const handleInput = () => {
- // Get current markdown content
- const markdown = crepe.getMarkdown();
- console.log('Editor content changed via input:', markdown.substring(0, 50) + '...');
- setCurrentContent(markdown);
-
- // Compare trimmed content to avoid whitespace issues
- const hasUnsavedChanges = markdown.trim() !== originalContent.trim();
- setHasChanges(hasUnsavedChanges);
- setIsReverted(false);
- };
-
- // Listen to multiple events to catch all changes
- editorElement.addEventListener('input', handleInput);
- editorElement.addEventListener('keyup', handleInput);
- editorElement.addEventListener('paste', handleInput);
- editorElement.addEventListener('cut', handleInput);
-
- // Store the handlers for cleanup
- (editorElement as any)._milkdownHandlers = {
- input: handleInput,
- keyup: handleInput,
- paste: handleInput,
- cut: handleInput
- };
- }
- }).catch((error) => {
- console.error('Failed to create Milkdown editor:', error);
- });
-
- crepeRef.current = crepe;
-
- return () => {
- // Clean up event listeners
- const editorElement = editorRef.current?.querySelector('.ProseMirror');
- if (editorElement && (editorElement as any)._milkdownHandlers) {
- const handlers = (editorElement as any)._milkdownHandlers;
- editorElement.removeEventListener('input', handlers.input);
- editorElement.removeEventListener('keyup', handlers.keyup);
- editorElement.removeEventListener('paste', handlers.paste);
- editorElement.removeEventListener('cut', handlers.cut);
- delete (editorElement as any)._milkdownHandlers;
- }
-
- if (crepeRef.current) {
- crepeRef.current.destroy();
- crepeRef.current = null;
- }
- };
- }, [doc.id, originalContent]);
-
- // Update theme class when isDarkMode changes
- useEffect(() => {
- if (editorRef.current) {
- if (isDarkMode) {
- editorRef.current.classList.add('milkdown-theme-dark');
- } else {
- editorRef.current.classList.remove('milkdown-theme-dark');
- }
- }
- }, [isDarkMode]);
-
- // Add keyboard shortcut for saving
- useEffect(() => {
- const handleKeyDown = (e: KeyboardEvent) => {
- if ((e.metaKey || e.ctrlKey) && e.key === 's') {
- e.preventDefault();
- if (hasChanges && !isLoading) {
- handleSave();
- }
- }
- };
-
- window.addEventListener('keydown', handleKeyDown);
- return () => {
- window.removeEventListener('keydown', handleKeyDown);
- };
- }, [hasChanges, isLoading, currentContent]);
-
- // Handle manual save
- const handleSave = async () => {
- if (!hasChanges || isLoading) return;
-
- try {
- setIsLoading(true);
- console.log('Saving document with content:', currentContent.substring(0, 100) + '...');
-
- // Create updated document with markdown content stored in content field
- const updatedDocument = {
- ...doc,
- content: {
- markdown: currentContent,
- // Preserve any other content fields
- ...(typeof doc.content === 'object' && doc.content !== null ? doc.content : {})
- },
- updated_at: new Date().toISOString(),
- };
-
- await onSave(updatedDocument);
-
- // Update state after successful save
- setHasChanges(false);
- setIsReverted(false);
- setOriginalContent(currentContent);
- console.log('Document saved successfully');
- } catch (error) {
- console.error('Error saving document:', error);
- // You might want to show an error toast here
- } finally {
- setIsLoading(false);
- }
- };
-
- // Handle undo changes
- const handleUndo = () => {
- if (crepeRef.current && editorRef.current) {
- // Destroy and recreate editor with original content
- crepeRef.current.destroy();
-
- const crepe = new Crepe({
- root: editorRef.current,
- defaultValue: originalContent,
- features: {
- [CrepeFeature.HeaderMeta]: true,
- [CrepeFeature.LinkTooltip]: true,
- [CrepeFeature.ImageBlock]: true,
- [CrepeFeature.BlockEdit]: true,
- [CrepeFeature.ListItem]: true,
- [CrepeFeature.CodeBlock]: true,
- [CrepeFeature.Table]: true,
- [CrepeFeature.Toolbar]: true,
- },
- });
-
- crepe.create().then(() => {
- console.log('Milkdown editor reverted to original content');
-
- // Set up content change tracking for the new editor instance
- const editorElement = editorRef.current?.querySelector('.ProseMirror');
- if (editorElement) {
- const handleInput = () => {
- const markdown = crepe.getMarkdown();
- console.log('Editor content changed after undo:', markdown.substring(0, 50) + '...');
- setCurrentContent(markdown);
- const hasUnsavedChanges = markdown.trim() !== originalContent.trim();
- setHasChanges(hasUnsavedChanges);
- setIsReverted(false);
- };
-
- editorElement.addEventListener('input', handleInput);
- editorElement.addEventListener('keyup', handleInput);
- editorElement.addEventListener('paste', handleInput);
- editorElement.addEventListener('cut', handleInput);
-
- (editorElement as any)._milkdownHandlers = {
- input: handleInput,
- keyup: handleInput,
- paste: handleInput,
- cut: handleInput
- };
- }
-
- setCurrentContent(originalContent);
- setHasChanges(false);
- setIsReverted(true);
- }).catch((error) => {
- console.error('Failed to revert Milkdown editor:', error);
- });
-
- crepeRef.current = crepe;
- }
- };
-
- return (
-
-
-
-
- {doc.title}
-
-
- {isLoading ? (
-
-
- Saving...
-
- ) : isReverted ? (
-
-
- Reverted
-
- ) : hasChanges ? (
-
-
- Unsaved changes
-
- ) : (
-
-
- All changes saved
-
- )}
-
-
-
- {hasChanges && (
-
- )}
-
-
-
-
-
-
- );
-};
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/Tabs.tsx b/archon-ui-main/src/components/project-tasks/Tabs.tsx
deleted file mode 100644
index fd66d55c..00000000
--- a/archon-ui-main/src/components/project-tasks/Tabs.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import React, { useMemo, useState, createContext, useContext } from 'react';
-interface TabsProps {
- defaultValue: string;
- value?: string;
- onValueChange?: (value: string) => void;
- children: React.ReactNode;
- className?: string;
-}
-const TabsContext = createContext<{
- value: string;
- onValueChange: (value: string) => void;
-}>({
- value: '',
- onValueChange: () => {}
-});
-export const Tabs = ({
- defaultValue,
- value,
- onValueChange,
- children,
- className = ''
-}: TabsProps) => {
- const [internalValue, setInternalValue] = useState(defaultValue);
- const activeValue = value !== undefined ? value : internalValue;
- const contextValue = useMemo(() => ({
- value: activeValue,
- onValueChange: (newValue: string) => {
- setInternalValue(newValue);
- onValueChange?.(newValue);
- }
- }), [activeValue, onValueChange]);
- return
- {children}
- ;
-};
-interface TabsListProps {
- children: React.ReactNode;
- className?: string;
-}
-export const TabsList = ({
- children,
- className = ''
-}: TabsListProps) => {
- return
- {/* Subtle neon glow effect */}
-
- {children}
-
;
-};
-interface TabsTriggerProps {
- value: string;
- children: React.ReactNode;
- className?: string;
- onClick?: () => void;
- color?: 'blue' | 'purple' | 'pink' | 'orange' | 'cyan' | 'green';
-}
-export const TabsTrigger = ({
- value,
- children,
- className = '',
- onClick,
- color = 'blue'
-}: TabsTriggerProps) => {
- const {
- value: activeValue,
- onValueChange
- } = useContext(TabsContext);
- const isActive = activeValue === value;
- const handleClick = () => {
- onValueChange(value);
- onClick?.();
- };
- const colorMap = {
- blue: {
- text: 'text-blue-600 dark:text-blue-400',
- glow: 'bg-blue-500 shadow-[0_0_10px_2px_rgba(59,130,246,0.4)] dark:shadow-[0_0_20px_5px_rgba(59,130,246,0.7)]',
- hover: 'hover:text-blue-500 dark:hover:text-blue-400/70'
- },
- purple: {
- text: 'text-purple-600 dark:text-purple-400',
- glow: 'bg-purple-500 shadow-[0_0_10px_2px_rgba(168,85,247,0.4)] dark:shadow-[0_0_20px_5px_rgba(168,85,247,0.7)]',
- hover: 'hover:text-purple-500 dark:hover:text-purple-400/70'
- },
- pink: {
- text: 'text-pink-600 dark:text-pink-400',
- glow: 'bg-pink-500 shadow-[0_0_10px_2px_rgba(236,72,153,0.4)] dark:shadow-[0_0_20px_5px_rgba(236,72,153,0.7)]',
- hover: 'hover:text-pink-500 dark:hover:text-pink-400/70'
- },
- orange: {
- text: 'text-orange-600 dark:text-orange-400',
- glow: 'bg-orange-500 shadow-[0_0_10px_2px_rgba(249,115,22,0.4)] dark:shadow-[0_0_20px_5px_rgba(249,115,22,0.7)]',
- hover: 'hover:text-orange-500 dark:hover:text-orange-400/70'
- },
- cyan: {
- text: 'text-cyan-600 dark:text-cyan-400',
- glow: 'bg-cyan-500 shadow-[0_0_10px_2px_rgba(34,211,238,0.4)] dark:shadow-[0_0_20px_5px_rgba(34,211,238,0.7)]',
- hover: 'hover:text-cyan-500 dark:hover:text-cyan-400/70'
- },
- green: {
- text: 'text-emerald-600 dark:text-emerald-400',
- glow: 'bg-emerald-500 shadow-[0_0_10px_2px_rgba(16,185,129,0.4)] dark:shadow-[0_0_20px_5px_rgba(16,185,129,0.7)]',
- hover: 'hover:text-emerald-500 dark:hover:text-emerald-400/70'
- }
- };
- return ;
-};
-interface TabsContentProps {
- value: string;
- children: React.ReactNode;
- className?: string;
-}
-export const TabsContent = ({
- value,
- children,
- className = ''
-}: TabsContentProps) => {
- const {
- value: activeValue
- } = useContext(TabsContext);
- // Simplified TabsContent - we're handling animations in the parent component now
- if (activeValue !== value) return null;
- return
- {children}
-
;
-};
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/TaskBoardView.tsx b/archon-ui-main/src/components/project-tasks/TaskBoardView.tsx
deleted file mode 100644
index 58761486..00000000
--- a/archon-ui-main/src/components/project-tasks/TaskBoardView.tsx
+++ /dev/null
@@ -1,371 +0,0 @@
-import React, { useRef, useState, useCallback } from 'react';
-import { useDrop } from 'react-dnd';
-import { useToast } from '../../contexts/ToastContext';
-import { DeleteConfirmModal } from '../common/DeleteConfirmModal';
-import { Trash2 } from 'lucide-react';
-import { Task } from './TaskTableView'; // Import Task interface
-import { ItemTypes, getAssigneeIcon, getAssigneeGlow, getOrderColor, getOrderGlow } from '../../lib/task-utils';
-import { DraggableTaskCard } from './DraggableTaskCard';
-
-interface TaskBoardViewProps {
- tasks: Task[];
- onTaskView: (task: Task) => void;
- onTaskComplete: (taskId: string) => void;
- onTaskDelete: (task: Task) => void;
- onTaskMove: (taskId: string, newStatus: Task['status']) => void;
- onTaskReorder: (taskId: string, targetIndex: number, status: Task['status']) => void;
-}
-
-interface ColumnDropZoneProps {
- status: Task['status'];
- title: string;
- tasks: Task[];
- onTaskMove: (taskId: string, newStatus: Task['status']) => void;
- onTaskView: (task: Task) => void;
- onTaskDelete: (task: Task) => void;
- onTaskReorder: (taskId: string, targetIndex: number, status: Task['status']) => void;
- allTasks: Task[];
- hoveredTaskId: string | null;
- onTaskHover: (taskId: string | null) => void;
- selectedTasks: Set;
- onTaskSelect: (taskId: string) => void;
-}
-
-const ColumnDropZone = ({
- status,
- title,
- tasks,
- onTaskMove,
- onTaskView,
- onTaskDelete,
- onTaskReorder,
- allTasks,
- hoveredTaskId,
- onTaskHover,
- selectedTasks,
- onTaskSelect
-}: ColumnDropZoneProps) => {
- const ref = useRef(null);
-
- const [{ isOver }, drop] = useDrop({
- accept: ItemTypes.TASK,
- drop: (item: { id: string; status: Task['status'] }) => {
- if (item.status !== status) {
- // Moving to different status - use length of current column as new order
- onTaskMove(item.id, status);
- }
- },
- collect: (monitor) => ({
- isOver: !!monitor.isOver()
- })
- });
-
- drop(ref);
-
- // Get column header color based on status
- const getColumnColor = () => {
- switch (status) {
- case 'todo':
- return 'text-gray-600 dark:text-gray-400';
- case 'doing':
- return 'text-blue-600 dark:text-blue-400';
- case 'review':
- return 'text-purple-600 dark:text-purple-400';
- case 'done':
- return 'text-green-600 dark:text-green-400';
- }
- };
-
- // Get column header glow based on status
- const getColumnGlow = () => {
- switch (status) {
- case 'todo':
- return 'bg-gray-500/30';
- case 'doing':
- return 'bg-blue-500/30 shadow-[0_0_10px_2px_rgba(59,130,246,0.2)]';
- case 'review':
- return 'bg-purple-500/30 shadow-[0_0_10px_2px_rgba(168,85,247,0.2)]';
- case 'done':
- return 'bg-green-500/30 shadow-[0_0_10px_2px_rgba(16,185,129,0.2)]';
- }
- };
-
- // Just use the tasks as-is since they're already parent tasks only
- const organizedTasks = tasks;
-
- return (
-
-
-
{title}
- {/* Column header divider with glow */}
-
-
-
-
- {organizedTasks.map((task, index) => (
- onTaskView(task)}
- onComplete={() => onTaskComplete(task.id)}
- onDelete={onTaskDelete}
- onTaskReorder={onTaskReorder}
- hoveredTaskId={hoveredTaskId}
- onTaskHover={onTaskHover}
- selectedTasks={selectedTasks}
- onTaskSelect={onTaskSelect}
- />
- ))}
-
-
- );
-};
-
-export const TaskBoardView = ({
- tasks,
- onTaskView,
- onTaskComplete,
- onTaskDelete,
- onTaskMove,
- onTaskReorder
-}: TaskBoardViewProps) => {
- const [hoveredTaskId, setHoveredTaskId] = useState(null);
- const [selectedTasks, setSelectedTasks] = useState>(new Set());
-
- // State for delete confirmation modal
- const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
- const [taskToDelete, setTaskToDelete] = useState(null);
-
- const { showToast } = useToast();
-
- // Multi-select handlers
- const toggleTaskSelection = useCallback((taskId: string) => {
- setSelectedTasks(prev => {
- const newSelection = new Set(prev);
- if (newSelection.has(taskId)) {
- newSelection.delete(taskId);
- } else {
- newSelection.add(taskId);
- }
- return newSelection;
- });
- }, []);
-
- const selectAllTasks = useCallback(() => {
- setSelectedTasks(new Set(tasks.map(task => task.id)));
- }, [tasks]);
-
- const clearSelection = useCallback(() => {
- setSelectedTasks(new Set());
- }, []);
-
- // Mass delete handler
- const handleMassDelete = useCallback(async () => {
- if (selectedTasks.size === 0) return;
-
- const tasksToDelete = tasks.filter(task => selectedTasks.has(task.id));
-
- try {
- const results = await Promise.allSettled(
- tasksToDelete.map(task => Promise.resolve(onTaskDelete(task)))
- );
- const rejected = results.filter(r => r.status === 'rejected');
- if (rejected.length) {
- console.error('Some deletions failed:', rejected.length);
- }
- clearSelection();
- } catch (error) {
- console.error('Failed to delete tasks:', error);
- }
- }, [selectedTasks, tasks, onTaskDelete, clearSelection]);
-
- // Mass status change handler
- const handleMassStatusChange = useCallback(async (newStatus: Task['status']) => {
- if (selectedTasks.size === 0) return;
-
- const tasksToUpdate = tasks.filter(task => selectedTasks.has(task.id));
-
- try {
- // Call onTaskMove so optimistic UI and counts refresh immediately; parent persists
- tasksToUpdate.forEach(task => onTaskMove(task.id, newStatus));
- clearSelection();
- showToast(`Moved ${tasksToUpdate.length} task${tasksToUpdate.length !== 1 ? 's' : ''} to ${newStatus}`, 'success');
- } catch (error) {
- console.error('Failed to update tasks:', error);
- showToast('Failed to move some tasks', 'error');
- }
- }, [selectedTasks, tasks, onTaskMove, clearSelection, showToast]);
-
- // No status mapping needed - using database values directly
-
- // Handle task deletion (opens confirmation modal)
- const handleDeleteTask = useCallback((task: Task) => {
- setTaskToDelete(task);
- setShowDeleteConfirm(true);
- }, [setTaskToDelete, setShowDeleteConfirm]);
-
- // Confirm deletion and execute
- const confirmDeleteTask = useCallback(async () => {
- if (!taskToDelete) return;
-
- try {
- // Delegate deletion to parent to avoid duplicate API calls
- await onTaskDelete(taskToDelete);
- } catch (error) {
- console.error('Failed to delete task:', error);
- } finally {
- setShowDeleteConfirm(false);
- setTaskToDelete(null);
- }
- }, [taskToDelete, onTaskDelete, setShowDeleteConfirm, setTaskToDelete]);
-
- // Cancel deletion
- const cancelDeleteTask = useCallback(() => {
- setShowDeleteConfirm(false);
- setTaskToDelete(null);
- }, [setShowDeleteConfirm, setTaskToDelete]);
-
- // Simple task filtering for board view
- const getTasksByStatus = (status: Task['status']) => {
- return tasks
- .filter(task => task.status === status)
- .sort((a, b) => a.task_order - b.task_order);
- };
-
- // Note: With optimistic updates, we no longer show loading overlays for successful moves
- // Tasks update instantly and only rollback on actual failures
-
- return (
-
-
- {/* Multi-select toolbar */}
- {selectedTasks.size > 0 && (
-
-
-
- {selectedTasks.size} task{selectedTasks.size !== 1 ? 's' : ''} selected
-
-
-
-
- {/* Status change dropdown */}
-
-
- {/* Mass delete button */}
-
-
- {/* Clear selection */}
-
-
-
- )}
-
- {/* Board Columns */}
-
- {/* Todo Column */}
-
-
- {/* Doing Column */}
-
-
- {/* Review Column */}
-
-
- {/* Done Column */}
-
-
-
- {/* Delete Confirmation Modal for Tasks */}
- {showDeleteConfirm && taskToDelete && (
-
- )}
-
- );
-};
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/TaskInputComponents.tsx b/archon-ui-main/src/components/project-tasks/TaskInputComponents.tsx
deleted file mode 100644
index 75924c33..00000000
--- a/archon-ui-main/src/components/project-tasks/TaskInputComponents.tsx
+++ /dev/null
@@ -1,172 +0,0 @@
-import React, { memo, useState, useEffect, useCallback, useRef } from 'react';
-
-interface DebouncedInputProps {
- value: string;
- onChange: (value: string) => void;
- placeholder?: string;
- className?: string;
- type?: 'text' | 'textarea';
- rows?: number;
-}
-
-// Memoized input component that manages its own state
-export const DebouncedInput = memo(({
- value,
- onChange,
- placeholder,
- className,
- type = 'text',
- rows = 5
-}: DebouncedInputProps) => {
- const [localValue, setLocalValue] = useState(value);
- const timeoutRef = useRef();
- const isFirstRender = useRef(true);
-
- // Sync with external value only on mount or when externally changed
- useEffect(() => {
- if (isFirstRender.current) {
- isFirstRender.current = false;
- return;
- }
- // Only update if the external value is different from local
- if (value !== localValue) {
- setLocalValue(value);
- }
- }, [value]);
-
- const handleChange = useCallback((e: React.ChangeEvent) => {
- const newValue = e.target.value;
- setLocalValue(newValue);
-
- // Clear existing timeout
- if (timeoutRef.current) {
- clearTimeout(timeoutRef.current);
- }
-
- // Set new timeout for debounced update
- timeoutRef.current = setTimeout(() => {
- onChange(newValue);
- }, 300);
- }, [onChange]);
-
- // Cleanup timeout on unmount
- useEffect(() => {
- return () => {
- if (timeoutRef.current) {
- clearTimeout(timeoutRef.current);
- }
- };
- }, []);
-
- if (type === 'textarea') {
- return (
-
- );
- }
-
- return (
-
- );
-}, (prevProps, nextProps) => {
- // Custom comparison - only re-render if external value or onChange changes
- return prevProps.value === nextProps.value &&
- prevProps.onChange === nextProps.onChange &&
- prevProps.placeholder === nextProps.placeholder &&
- prevProps.className === nextProps.className;
-});
-
-DebouncedInput.displayName = 'DebouncedInput';
-
-interface FeatureInputProps {
- value: string;
- onChange: (value: string) => void;
- projectFeatures: any[];
- isLoadingFeatures: boolean;
- placeholder?: string;
- className?: string;
-}
-
-// Memoized feature input with datalist
-export const FeatureInput = memo(({
- value,
- onChange,
- projectFeatures,
- isLoadingFeatures,
- placeholder,
- className
-}: FeatureInputProps) => {
- const [localValue, setLocalValue] = useState(value);
- const timeoutRef = useRef();
-
- // Sync with external value
- useEffect(() => {
- if (value !== localValue) {
- setLocalValue(value);
- }
- }, [value]);
-
- const handleChange = useCallback((e: React.ChangeEvent) => {
- const newValue = e.target.value;
- setLocalValue(newValue);
-
- if (timeoutRef.current) {
- clearTimeout(timeoutRef.current);
- }
-
- timeoutRef.current = setTimeout(() => {
- onChange(newValue);
- }, 300);
- }, [onChange]);
-
- useEffect(() => {
- return () => {
- if (timeoutRef.current) {
- clearTimeout(timeoutRef.current);
- }
- };
- }, []);
-
- return (
-
-
-
- {isLoadingFeatures && (
-
- )}
-
- );
-}, (prevProps, nextProps) => {
- return prevProps.value === nextProps.value &&
- prevProps.onChange === nextProps.onChange &&
- prevProps.isLoadingFeatures === nextProps.isLoadingFeatures &&
- prevProps.projectFeatures === nextProps.projectFeatures;
-});
-
-FeatureInput.displayName = 'FeatureInput';
\ No newline at end of file
diff --git a/archon-ui-main/src/components/project-tasks/TaskTableView.tsx b/archon-ui-main/src/components/project-tasks/TaskTableView.tsx
deleted file mode 100644
index e830e0ea..00000000
--- a/archon-ui-main/src/components/project-tasks/TaskTableView.tsx
+++ /dev/null
@@ -1,875 +0,0 @@
-import React, { useState, useCallback, useRef, useEffect } from 'react';
-import { useDrag, useDrop } from 'react-dnd';
-import { Check, Trash2, Edit, Tag, User, Bot, Clipboard, Save, Plus } from 'lucide-react';
-import { useToast } from '../../contexts/ToastContext';
-import { DeleteConfirmModal } from '../common/DeleteConfirmModal';
-import { projectService } from '../../services/projectService';
-import { ItemTypes, getAssigneeIcon, getAssigneeGlow, getOrderColor, getOrderGlow } from '../../lib/task-utils';
-import { DraggableTaskCard } from './DraggableTaskCard';
-
-export interface Task {
- id: string;
- title: string;
- description: string;
- status: 'todo' | 'doing' | 'review' | 'done';
- assignee: {
- name: 'User' | 'Archon' | 'AI IDE Agent';
- avatar: string;
- };
- feature: string;
- featureColor: string;
- task_order: number;
-}
-
-interface TaskTableViewProps {
- tasks: Task[];
- onTaskView: (task: Task) => void;
- onTaskComplete: (taskId: string) => void;
- onTaskDelete: (task: Task) => void;
- onTaskReorder: (taskId: string, newOrder: number, status: Task['status']) => void;
- onTaskCreate?: (task: Omit) => Promise;
- onTaskUpdate?: (taskId: string, updates: Partial) => Promise;
-}
-
-const getAssigneeGlassStyle = (assigneeName: 'User' | 'Archon' | 'AI IDE Agent') => {
- switch (assigneeName) {
- case 'User':
- return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-blue-400 dark:border-blue-500'; // blue glass
- case 'AI IDE Agent':
- return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-emerald-400 dark:border-emerald-500'; // emerald green glass (like toggle)
- case 'Archon':
- return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-pink-400 dark:border-pink-500'; // pink glass
- default:
- return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-blue-400 dark:border-blue-500';
- }
-};
-
-// Get glass morphism style based on task order (lower = higher priority = warmer color)
-const getOrderGlassStyle = (order: number) => {
- if (order <= 3) return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-rose-400 dark:border-rose-500'; // red glass
- if (order <= 6) return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-orange-400 dark:border-orange-500'; // orange glass
- if (order <= 10) return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-blue-400 dark:border-blue-500'; // blue glass
- return 'backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60 dark:from-white/10 dark:to-black/30 border-emerald-400 dark:border-emerald-500'; // green glass
-};
-
-const getOrderTextColor = (order: number) => {
- if (order <= 3) return 'text-rose-500 dark:text-rose-400'; // red text
- if (order <= 6) return 'text-orange-500 dark:text-orange-400'; // orange text
- if (order <= 10) return 'text-blue-500 dark:text-blue-400'; // blue text
- return 'text-emerald-500 dark:text-emerald-400'; // green text
-};
-
-
-
-// Helper function to reorder tasks properly
-const reorderTasks = (tasks: Task[], fromIndex: number, toIndex: number): Task[] => {
- const result = [...tasks];
- const [movedTask] = result.splice(fromIndex, 1);
- result.splice(toIndex, 0, movedTask);
-
- // Update task_order to be sequential (1, 2, 3, ...)
- return result.map((task, index) => ({
- ...task,
- task_order: index + 1
- }));
-};
-
-// Inline editable cell component
-interface EditableCellProps {
- value: string;
- onSave: (value: string) => void;
- type?: 'text' | 'textarea' | 'select';
- options?: string[];
- placeholder?: string;
- isEditing: boolean;
- onEdit: () => void;
- onCancel: () => void;
-}
-
-const EditableCell = ({
- value,
- onSave,
- type = 'text',
- options = [],
- placeholder = '',
- isEditing,
- onEdit,
- onCancel
-}: EditableCellProps) => {
- const [editValue, setEditValue] = useState(value);
-
- const handleSave = () => {
- onSave(editValue);
- };
-
- const handleCancel = () => {
- setEditValue(value);
- onCancel();
- };
-
- // Handle keyboard events for Tab/Enter to save, Escape to cancel
- const handleKeyDown = (e: React.KeyboardEvent) => {
- if (e.key === 'Enter' || e.key === 'Tab') {
- e.preventDefault();
- handleSave();
- } else if (e.key === 'Escape') {
- e.preventDefault();
- handleCancel();
- }
- };
-
- // Handle blur to save (when clicking outside)
- const handleBlur = () => {
- handleSave();
- };
-
- if (!isEditing) {
- return (
-
-
- {value || Click to edit}
-
-
- );
- }
-
- return (
-
- {type === 'select' ? (
-
- ) : type === 'textarea' ? (
-
- );
-};
-
-interface DraggableTaskRowProps {
- task: Task;
- index: number;
- onTaskView: (task: Task) => void;
- onTaskComplete: (taskId: string) => void;
- onTaskDelete: (task: Task) => void;
- onTaskReorder: (taskId: string, newOrder: number, status: Task['status']) => void;
- onTaskUpdate?: (taskId: string, updates: Partial) => Promise;
- tasksInStatus: Task[];
- style?: React.CSSProperties;
-}
-
-const DraggableTaskRow = ({
- task,
- index,
- onTaskView,
- onTaskComplete,
- onTaskDelete,
- onTaskReorder,
- onTaskUpdate,
- tasksInStatus,
- style
-}: DraggableTaskRowProps) => {
- const [editingField, setEditingField] = useState(null);
- const [isHovering, setIsHovering] = useState(false);
-
- const [{ isDragging }, drag] = useDrag({
- type: ItemTypes.TASK,
- item: { id: task.id, index, status: task.status },
- collect: (monitor) => ({
- isDragging: !!monitor.isDragging(),
- }),
- });
-
- const [{ isOver, canDrop }, drop] = useDrop({
- accept: ItemTypes.TASK,
- hover: (draggedItem: { id: string; index: number; status: Task['status'] }, monitor) => {
- if (!monitor.isOver({ shallow: true })) return;
- if (draggedItem.id === task.id) return;
- if (draggedItem.status !== task.status) return;
-
- const draggedIndex = draggedItem.index;
- const hoveredIndex = index;
-
- if (draggedIndex === hoveredIndex) return;
-
- console.log('HOVER: Moving task', draggedItem.id, 'to index', draggedIndex, 'to', hoveredIndex);
-
- // Move the task immediately for visual feedback
- onTaskReorder(draggedItem.id, hoveredIndex, task.status);
-
- // Update the dragged item's index to prevent re-triggering
- draggedItem.index = hoveredIndex;
- },
- collect: (monitor) => ({
- isOver: !!monitor.isOver(),
- canDrop: !!monitor.canDrop(),
- }),
- });
-
- const handleUpdateField = async (field: string, value: string) => {
- if (onTaskUpdate) {
- const updates: Partial = {};
-
- if (field === 'title') {
- updates.title = value;
- } else if (field === 'status') {
- updates.status = value as Task['status'];
- } else if (field === 'assignee') {
- updates.assignee = { name: value as 'User' | 'Archon' | 'AI IDE Agent', avatar: '' };
- } else if (field === 'feature') {
- updates.feature = value;
- }
-
- try {
- await onTaskUpdate(task.id, updates);
- setEditingField(null);
- } catch (error) {
- console.error('Failed to update task:', error);
- }
- }
- };
-
- return (
- drag(drop(node))}
- className={`
- group transition-all duration-200 cursor-move
- ${index % 2 === 0 ? 'bg-white/50 dark:bg-black/50' : 'bg-gray-50/80 dark:bg-gray-900/30'}
- hover:bg-gradient-to-r hover:from-cyan-50/70 hover:to-purple-50/70 dark:hover:from-cyan-900/20 dark:hover:to-purple-900/20
- border-b border-gray-200 dark:border-gray-800 last:border-b-0
- ${isDragging ? 'opacity-50 scale-105 shadow-lg z-50' : ''}
- ${isOver && canDrop ? 'bg-cyan-100/50 dark:bg-cyan-900/20 border-cyan-400' : ''}
- ${isHovering ? 'transform translate-y-1 shadow-md' : ''}
- `}
- onMouseLeave={() => setIsHovering(false)}
- style={style}
- >
-
-
-
- {task.task_order}
-
-
- |
-
-
-
- handleUpdateField('title', value)}
- isEditing={editingField === 'title'}
- onEdit={() => setEditingField('title')}
- onCancel={() => setEditingField(null)}
- placeholder="Task title..."
- />
-
-
- |
-
- {
- handleUpdateField('status', value as Task['status']);
- }}
- type="select"
- options={['todo', 'doing', 'review', 'done']}
- isEditing={editingField === 'status'}
- onEdit={() => setEditingField('status')}
- onCancel={() => setEditingField(null)}
- />
- |
-
-
- handleUpdateField('feature', value)}
- isEditing={editingField === 'feature'}
- onEdit={() => setEditingField('feature')}
- onCancel={() => setEditingField(null)}
- placeholder="Feature name..."
- />
-
- |
-
-
- setEditingField('assignee')}
- title={`Assignee: ${task.assignee?.name || 'User'}`}
- >
- {getAssigneeIcon(task.assignee?.name || 'User')}
-
- {editingField === 'assignee' && (
-
-
-
- )}
-
- |
-
-
-
-
-
- {/* Copy Task ID Button - Matching Board View */}
-
-
- |
-
- );
-};
-
-// Add Task Row Component - Always visible empty input row
-interface AddTaskRowProps {
- onTaskCreate?: (task: Omit) => Promise;
- tasks: Task[];
- statusFilter: Task['status'] | 'all';
-}
-
-const AddTaskRow = ({ onTaskCreate, tasks, statusFilter }: AddTaskRowProps) => {
- const [newTask, setNewTask] = useState>({
- title: '',
- description: '',
- status: statusFilter === 'all' ? 'todo' : statusFilter,
- assignee: { name: 'AI IDE Agent', avatar: '' },
- feature: '',
- featureColor: '#3b82f6',
- task_order: 1
- });
-
- const handleCreateTask = async () => {
- if (!newTask.title.trim() || !onTaskCreate) return;
-
- // Calculate the next order number for the target status
- const targetStatus = newTask.status;
- const tasksInStatus = tasks.filter(t => t.status === targetStatus);
- const nextOrder = tasksInStatus.length > 0 ? Math.max(...tasksInStatus.map(t => t.task_order)) + 1 : 1;
-
- try {
- await onTaskCreate({
- ...newTask,
- task_order: nextOrder
- });
-
- // Reset only the title to allow quick adding
- setNewTask(prev => ({
- ...prev,
- title: '',
- description: ''
- }));
- } catch (error) {
- console.error('Failed to create task:', error);
- }
- };
-
- const handleKeyPress = (e: React.KeyboardEvent) => {
- if (e.key === 'Enter' && !e.shiftKey) {
- e.preventDefault();
- handleCreateTask();
- }
- };
-
- // Update status when filter changes
- React.useEffect(() => {
- if (statusFilter !== 'all') {
- setNewTask(prev => ({ ...prev, status: statusFilter }));
- }
- }, [statusFilter]);
-
- return (
- <>
-
- {/* Toned down neon blue line separator */}
- |
-
- |
-
-
- |
-
- |
-
- setNewTask(prev => ({ ...prev, title: e.target.value }))}
- onKeyPress={handleKeyPress}
- placeholder="Type task title and press Enter..."
- className="w-full bg-white/90 dark:bg-black/90 border border-cyan-300 dark:border-cyan-600 rounded px-2 py-1.5 text-sm focus:outline-none focus:border-cyan-500 focus:shadow-[0_0_5px_rgba(34,211,238,0.3)] transition-all duration-200"
- autoFocus
- />
- |
-
-
- |
-
- setNewTask(prev => ({ ...prev, feature: e.target.value }))}
- onKeyPress={handleKeyPress}
- placeholder="Feature..."
- className="w-full bg-white/90 dark:bg-black/90 border border-cyan-300 dark:border-cyan-600 rounded px-2 py-1.5 text-sm focus:outline-none focus:border-cyan-500 focus:shadow-[0_0_5px_rgba(34,211,238,0.3)]"
- />
- |
-
-
- |
-
-
- Press Enter
-
- |
-
- >
- );
-};
-
-export const TaskTableView = ({
- tasks,
- onTaskView,
- onTaskComplete,
- onTaskDelete,
- onTaskReorder,
- onTaskCreate,
- onTaskUpdate
-}: TaskTableViewProps) => {
- const [statusFilter, setStatusFilter] = useState('todo');
-
- // State for delete confirmation modal
- const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
- const [taskToDelete, setTaskToDelete] = useState(null);
-
- const { showToast } = useToast();
-
- // Refs for scroll fade effect
- const tableContainerRef = useRef(null);
- const tableRef = useRef(null);
- const [scrollOpacities, setScrollOpacities] = useState