diff --git a/.dev.vars b/.dev.vars
new file mode 100644
index 0000000..e69de29
diff --git a/.github/persistence-context.md b/.github/persistence-context.md
deleted file mode 100644
index 1e3d54d..0000000
--- a/.github/persistence-context.md
+++ /dev/null
@@ -1,69 +0,0 @@
-## Project Overview
-
-This project is a custom-built mini-ORM utility for managing database operations in a Node.js/TypeScript application. It includes features like query building, pagination, joins, and CRUD operations.
-
-### Key Directories and Files
-
-- **`src/backend/persistence/`**: Contains the core persistence logic.
-
- - `persistence.repository.ts`: Implements the `PersistentRepository` class for database operations.
- - `persistence-contracts.ts`: Defines interfaces and types for persistence operations.
- - `persistence-utils.ts`: Utility functions for building SQL queries.
- - `persistence-where-operator.ts`: Helper functions for building `WHERE` clauses.
- - `database-drivers/pg.client.ts`: PostgreSQL database driver implementation.
-
-- **`src/backend/persistence-repositories.ts`**: Exports repository instances for specific database tables.
-
-### Key Features
-
-1. **Dynamic Query Building**:
-
- - Supports `WHERE`, `ORDER BY`, `JOIN`, and pagination.
- - Utility functions like `buildWhereClause`, `buildOrderByClause`, and `buildJoinClause`.
-
-2. **CRUD Operations**:
-
- - `findRows`, `findRowCount`, `createOne`, `createMany`, `updateOne`, `deleteRows`.
-
-3. **Error Handling**:
-
- - Custom error classes like `PersistenceDriverError`.
-
-4. **Database Driver**:
- - Uses PostgreSQL (`pg` package) for database interactions.
-
-### Testing
-
-- Tests are written using Jest.
-- Mocking is used for the database driver (`IPersistentDriver`).
-- Test cases cover all repository methods and utility functions.
-
-### Common Queries
-
-1. **How to test a specific method?**
-
- - Provide the method name and its file path. Example: `findRows` in `persistence.repository.ts`.
-
-2. **How to add a new feature?**
-
- - Specify the feature and its purpose. Example: Add support for `GROUP BY` in queries.
-
-3. **How to debug an issue?**
-
- - Provide the error message and the relevant file or method.
-
-4. **How to write migrations?**
- - Specify the table and column changes. Example: Add a new column to the `users` table.
-
-### Example Prompts
-
-- "Can you check the `findRows` method in `persistence.repository.ts`?"
-- "Can you write test cases for the `updateOne` method?"
-- "How can I add a `GROUP BY` clause to the query builder?"
-- "Can you help me debug this error: `Failed to initialize database connection`?"
-
-### Notes
-
-- Always use parameterized queries to prevent SQL injection.
-- Follow TypeScript best practices for type safety.
-- Use environment variables for database configuration.
diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml
new file mode 100644
index 0000000..ecd27d0
--- /dev/null
+++ b/.github/workflows/claude-code-review.yml
@@ -0,0 +1,75 @@
+name: Claude Code Review
+
+on:
+ pull_request:
+ types: [opened, synchronize]
+ # Optional: Only run on specific file changes
+ # paths:
+ # - "src/**/*.ts"
+ # - "src/**/*.tsx"
+ # - "src/**/*.js"
+ # - "src/**/*.jsx"
+
+jobs:
+ claude-review:
+ # Optional: Filter by PR author
+ # if: |
+ # github.event.pull_request.user.login == 'external-contributor' ||
+ # github.event.pull_request.user.login == 'new-developer' ||
+ # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
+
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ pull-requests: read
+ issues: read
+ id-token: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+
+ - name: Run Claude Code Review
+ id: claude-review
+ uses: anthropics/claude-code-action@beta
+ with:
+ anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
+
+ # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
+ # model: "claude-opus-4-20250514"
+
+ # Direct prompt for automated review (no @claude mention needed)
+ direct_prompt: |
+ Please review this pull request and provide feedback on:
+ - Code quality and best practices
+ - Potential bugs or issues
+ - Performance considerations
+ - Security concerns
+ - Test coverage
+
+ Be constructive and helpful in your feedback.
+
+ # Optional: Customize review based on file types
+ # direct_prompt: |
+ # Review this PR focusing on:
+ # - For TypeScript files: Type safety and proper interface usage
+ # - For API endpoints: Security, input validation, and error handling
+ # - For React components: Performance, accessibility, and best practices
+ # - For tests: Coverage, edge cases, and test quality
+
+ # Optional: Different prompts for different authors
+ # direct_prompt: |
+ # ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
+ # 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
+ # 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
+
+ # Optional: Add specific tools for running tests or linting
+ # allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
+
+ # Optional: Skip review for certain conditions
+ # if: |
+ # !contains(github.event.pull_request.title, '[skip-review]') &&
+ # !contains(github.event.pull_request.title, '[WIP]')
+
diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml
new file mode 100644
index 0000000..58d0fa2
--- /dev/null
+++ b/.github/workflows/claude.yml
@@ -0,0 +1,59 @@
+name: Claude Code
+
+on:
+ issue_comment:
+ types: [created]
+ pull_request_review_comment:
+ types: [created]
+ issues:
+ types: [opened, assigned]
+ pull_request_review:
+ types: [submitted]
+
+jobs:
+ claude:
+ if: |
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
+ (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
+ (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
+ (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ pull-requests: read
+ issues: read
+ id-token: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+
+ - name: Run Claude Code
+ id: claude
+ uses: anthropics/claude-code-action@beta
+ with:
+ anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
+
+ # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
+ # model: "claude-opus-4-20250514"
+
+ # Optional: Customize the trigger phrase (default: @claude)
+ # trigger_phrase: "/claude"
+
+ # Optional: Trigger when specific user is assigned to an issue
+ # assignee_trigger: "claude-bot"
+
+ # Optional: Allow Claude to run specific commands
+ # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
+
+ # Optional: Add custom instructions for Claude to customize its behavior for your project
+ # custom_instructions: |
+ # Follow our coding standards
+ # Ensure all new code has tests
+ # Use TypeScript for new files
+
+ # Optional: Custom environment variables for Claude
+ # claude_env: |
+ # NODE_ENV: test
+
diff --git a/.gitignore b/.gitignore
index 4063fb8..b8abf62 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ pnpm-lock.yaml
bun.lockb
bun.lock
.yarn/install-state.gz
+package-lock.json
# testing
/coverage
@@ -32,6 +33,8 @@ yarn-error.log*
# local env files
.env*.local
+.env
+.dev.vars
# vercel
.vercel
@@ -39,3 +42,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+.vscode/mcp.json
+# Sentry Config File
+.env.sentry-build-plugin
diff --git a/.idea/.gitignore b/.idea/.gitignore
index 13566b8..b58b603 100644
--- a/.idea/.gitignore
+++ b/.idea/.gitignore
@@ -3,6 +3,3 @@
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/prettier.xml b/.idea/prettier.xml
deleted file mode 100644
index ea0f3cf..0000000
--- a/.idea/prettier.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.todo b/.todo
deleted file mode 100644
index 24e2e42..0000000
--- a/.todo
+++ /dev/null
@@ -1,5 +0,0 @@
-- [] tags
-- [] tags archive
-
-- [] bookmarks
-- [] settings()
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..a2d45d8
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,142 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Development Commands
+
+### Development Server
+- `bun run dev` - Start development server with Turbo
+- Open http://localhost:3000 to view the application
+
+### Database Operations
+- `bun run db:generate` - Generate database migrations from schema changes
+- `bun run db:push` - Push schema changes to database
+- `bun run db:studio` - Open Drizzle Studio (database GUI)
+
+### Build & Deployment
+- `bun run build` - Build for production
+- `bun run start` - Start production server
+- `bun run lint` - Run ESLint checks
+
+### Backend Development
+- `bun run play` - Run backend playground script (`src/backend/play.ts`)
+
+## Architecture Overview
+
+### Technology Stack
+- **Frontend**: Next.js 15 (App Router), React 19, TypeScript
+- **Styling**: Tailwind CSS, shadcn/ui components
+- **Backend**: Next.js API routes, Drizzle ORM
+- **Database**: PostgreSQL
+- **Authentication**: GitHub OAuth
+- **Search**: MeilSearch
+- **File Storage**: Cloudinary
+- **State Management**: Jotai, React Hook Form with Zod validation
+
+### Backend & Database
+- **[SQLKit](https://github.com/sqlkit-dev/sqlkit)** - Very light sql query builder, we are using most of the sql query using this.
+- **[Drizzle ORM](https://orm.drizzle.team/)** - Awesome sql tool but we are only using for migration
+- **[PostgreSQL](https://www.postgresql.org/)** - Primary database
+- **[Next.js API Routes](https://nextjs.org/docs/api-routes/introduction)** - Backend API
+
+### Core Directory Structure
+
+#### Frontend (`/src/app/`)
+- Route groups using Next.js App Router:
+ - `(home)` - Main homepage and article feed
+ - `(dashboard-editor)` - Protected dashboard routes
+ - `[username]` - User profile pages
+ - `[username]/[articleHandle]` - Individual article pages
+- API routes in `/api/` for OAuth and development
+
+#### Backend (`/src/backend/`)
+- **Domain Models** (`/domain/`) - Core business logic entities
+- **Persistence** (`/persistence/`) - Database schemas and repositories
+- **Services** (`/services/`) - Business logic actions
+- **Input Validation** - Zod schemas for type-safe inputs
+
+#### Component Architecture (`/src/components/`)
+- **UI Components** - shadcn/ui based design system
+- **Feature Components** - Domain-specific (Editor, Navbar, etc.)
+- **Layout Components** - Page layouts and providers
+
+### Database Schema Architecture
+
+Key entities and their relationships:
+- **Users** - User profiles with social authentication
+- **Articles** - Blog posts with markdown content and metadata
+- **Series** - Article collections/sequences
+- **Comments** - Nested commenting system with resource association
+- **Tags** - Article categorization
+- **Bookmarks** - User content saving
+- **Reactions** - Emoji-based reactions (LOVE, FIRE, WOW, etc.)
+- **User Sessions** - Session management
+- **User Socials** - OAuth provider connections
+
+### Content Management
+- **Rich Text**: Markdoc for markdown parsing and rendering
+- **File Uploads**: Cloudinary integration for images/media
+- **Search**: MeilSearch for full-text search capabilities
+- **Internationalization**: Custom i18n implementation (Bengali/English)
+
+### State Management Patterns
+- **Server State**: Drizzle ORM with PostgreSQL
+- **Client State**: Jotai for global state management
+- **Form State**: React Hook Form with Zod validation
+- **Environment**: Type-safe environment variables with @t3-oss/env-nextjs
+
+## Required Environment Variables
+
+Server-side:
+- `DATABASE_URL` - PostgreSQL connection string
+- `GITHUB_CLIENT_ID` - GitHub OAuth client ID
+- `GITHUB_CLIENT_SECRET` - GitHub OAuth client secret
+- `GITHUB_CALLBACK_URL` - OAuth callback URL
+- `CLOUDINARY_URL` - Cloudinary configuration
+- `MEILISEARCH_ADMIN_API_KEY` - MeilSearch admin API key
+
+Client-side:
+- `NEXT_PUBLIC_MEILISEARCH_API_HOST` - MeilSearch API host URL
+- `NEXT_PUBLIC_MEILISEARCH_SEARCH_API_KEY` - MeilSearch search API key
+
+## Key Features Implementation
+
+### Authentication Flow
+- GitHub OAuth integration via `/api/auth/github`
+- User sessions managed in `userSessionsTable`
+- Social provider connections in `userSocialsTable`
+
+### Content Creation
+- Rich markdown editor with drag-and-drop support
+- Image upload and optimization via Cloudinary
+- Article series management for content organization
+- Tag-based categorization system
+
+### Search Implementation
+- MeilSearch for full-text search across articles
+- Search configuration and indexing handled in backend services
+- Client-side search interface with real-time results
+
+### Community Features
+- Nested commenting system with resource association
+- Emoji-based reactions (LOVE, FIRE, WOW, etc.)
+- User following and bookmarking functionality
+- Social sharing and user profiles
+
+## Development Workflow
+
+1. Database changes require running `bun run db:generate` followed by `bun run db:push`
+2. Backend logic testing can be done via `bun run play` playground script
+3. Type safety is enforced through Zod schemas for all inputs
+4. UI components follow shadcn/ui patterns and conventions
+5. All forms use React Hook Form with Zod validation schemas
+6. When querying data in component always use Tanstack Query.
+7. When interacting with DB, create a action in `src/backend/services` and use sqlkit package (https://github.com/sqlkit-dev/sqlkit)
+8. For Database schema reference look here for drizzle schema `src/backend/persistence/schemas.ts`
+
+## Special Considerations
+
+- **Bengali Language Support**: Custom font loading (Kohinoor Bangla) and i18n
+- **SEO Optimization**: Dynamic sitemaps, Open Graph tags, and schema markup
+- **Performance**: Next.js Image optimization, bundle splitting, and caching
+- **Security**: Input validation via Zod, secure OAuth flow, environment variable validation
\ No newline at end of file
diff --git a/CLOUDFLARE_CRON_SETUP.md b/CLOUDFLARE_CRON_SETUP.md
new file mode 100644
index 0000000..732c432
--- /dev/null
+++ b/CLOUDFLARE_CRON_SETUP.md
@@ -0,0 +1,143 @@
+# Cloudflare Cron Setup for Article Cleanup
+
+This document explains how to set up Cloudflare Cron Triggers to automatically delete expired articles.
+
+## Overview
+
+The system consists of:
+1. **API Route**: `/api/cron/cleanup-articles` - Handles the actual cleanup logic
+2. **Cloudflare Worker**: `src/workers/cron-worker.ts` - Cron trigger that calls the API
+3. **Backend Service**: `src/backend/services/article-cleanup-service.ts` - Database operations
+
+## Setup Instructions
+
+### 1. Install Wrangler CLI
+
+```bash
+npm install -g wrangler
+# or
+bun install -g wrangler
+```
+
+### 2. Authenticate with Cloudflare
+
+```bash
+wrangler login
+```
+
+### 3. Configure Environment Variables
+
+Update `wrangler.toml` with your actual domain:
+
+```toml
+[vars]
+CRON_TARGET_URL = "https://your-actual-domain.com/api/cron/cleanup-articles"
+```
+
+### 4. Set Secret (Optional but Recommended)
+
+For additional security, set a secret that the cron worker will send:
+
+```bash
+wrangler secret put CRON_SECRET
+# Enter your secret when prompted
+```
+
+Then add the same secret to your Next.js environment:
+
+```bash
+# .env.local
+CRON_SECRET=your-secret-key
+```
+
+### 5. Deploy the Cron Worker
+
+```bash
+wrangler deploy src/workers/cron-worker.ts
+```
+
+### 6. Verify Cron Schedule
+
+The cron is configured to run daily at 2:00 AM UTC. You can modify the schedule in `wrangler.toml`:
+
+```toml
+[triggers]
+crons = [
+ "0 2 * * *" # Daily at 2:00 AM UTC
+]
+```
+
+Other common schedules:
+- `"0 * * * *"` - Every hour
+- `"0 2 * * 0"` - Every Sunday at 2:00 AM
+- `"0 2 1 * *"` - First day of every month at 2:00 AM
+
+### 7. Monitor Cron Executions
+
+You can monitor executions in the Cloudflare dashboard:
+1. Go to Workers & Pages
+2. Select your worker
+3. Check the "Logs" tab for execution logs
+
+## Manual Testing
+
+You can test the cleanup manually by calling the API directly:
+
+```bash
+# GET request for testing
+curl https://your-domain.com/api/cron/cleanup-articles
+
+# POST request (mimics cron call)
+curl -X POST https://your-domain.com/api/cron/cleanup-articles \
+ -H "Content-Type: application/json" \
+ -H "x-cron-secret: your-secret-key"
+```
+
+## How It Works
+
+1. **Article Scheduling**: Articles can be scheduled for deletion by setting the `delete_scheduled_at` field
+2. **Cron Trigger**: Cloudflare runs the worker daily at 2:00 AM UTC
+3. **API Call**: Worker calls `/api/cron/cleanup-articles` endpoint
+4. **Cleanup Logic**: Service finds articles where `delete_scheduled_at < current_time` and deletes them
+5. **Response**: API returns count of deleted articles and their details
+
+## Database Schema
+
+Articles are scheduled for deletion using the `delete_scheduled_at` timestamp field:
+
+```sql
+-- Example of scheduling an article for deletion in 30 days
+UPDATE articles
+SET delete_scheduled_at = NOW() + INTERVAL '30 days'
+WHERE id = 'article-id';
+```
+
+## Additional Functions
+
+The cleanup service also provides:
+- `scheduleArticleForDeletion(articleId, deleteAt)` - Schedule an article
+- `cancelScheduledDeletion(articleId)` - Cancel scheduled deletion
+- `getScheduledArticles()` - Get all articles scheduled for deletion
+
+## Troubleshooting
+
+### Common Issues
+
+1. **404 Error**: Check that your `CRON_TARGET_URL` is correct
+2. **401 Unauthorized**: Verify `CRON_SECRET` matches between worker and API
+3. **500 Error**: Check database connection and permissions
+4. **No Articles Deleted**: Verify articles have `delete_scheduled_at` set and are past due
+
+### Debugging
+
+1. Check Cloudflare Worker logs in the dashboard
+2. Check your Next.js application logs
+3. Test the API endpoint manually
+4. Verify database records with `getScheduledArticles()`
+
+## Security Considerations
+
+1. Use `CRON_SECRET` to verify requests come from your worker
+2. Consider rate limiting the endpoint
+3. Log all cleanup operations for audit trails
+4. Ensure proper database permissions for the cleanup operations
\ No newline at end of file
diff --git a/README.md b/README.md
index c403366..55287ee 100644
--- a/README.md
+++ b/README.md
@@ -1,36 +1,319 @@
-This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+# TechDiary
-## Getting Started
+A modern blogging platform designed specifically for the tech community. Built for developers, by developers.
-First, run the development server:
+
+
+## 🌟 Overview
+
+TechDiary is a feature-rich blogging platform that empowers developers and tech enthusiasts to share knowledge, document their journey, and build meaningful connections within the tech community. With support for multiple languages, intuitive writing tools, and powerful engagement features, TechDiary creates the perfect environment for technical content creation and discovery.
+
+## ✨ Key Features
+
+### 📝 Content Creation
+- **Rich Markdown Editor** with live preview and auto-save
+- **Drag-and-drop Image Upload** with cropping capabilities
+- **Series Support** for organizing related articles
+- **Draft Management** with autosave every 30 seconds
+- **SEO Optimization** with meta tags and structured data
+
+### 🌍 Multi-language Support
+- **Bengali and English** interface support
+- **Localized Content** with proper date and number formatting
+- **Easy Language Switching** with persistent preferences
+
+### 🔍 Powerful Search
+- **Full-text Search** powered by MeilSearch
+- **Advanced Filtering** by tags, authors, and dates
+- **Real-time Search Suggestions** and auto-complete
+- **Fast Response Times** (<500ms average)
+
+### 💬 Rich Engagement
+- **Emoji Reactions** (Love, Fire, Wow, Haha, Cry, Unicorn)
+- **Threaded Comments** with nested discussions
+- **Bookmarking System** for saving articles
+- **Following System** to track favorite authors
+
+### 🔐 Secure Authentication
+- **GitHub OAuth** integration for developers
+- **Secure Session Management** with automatic renewal
+- **Profile Customization** with bio, location, education, and social links
+
+### 🎨 Modern UI/UX
+- **Dark/Light Theme** support
+- **Responsive Design** for all devices
+- **Accessibility Compliant** (WCAG 2.1 AA)
+- **Progressive Web App** capabilities
+
+## 🛠 Tech Stack
+
+### Frontend
+- **[Next.js 15](https://nextjs.org/)** - React framework with App Router
+- **[React 19](https://react.dev/)** - UI library
+- **[TypeScript](https://www.typescriptlang.org/)** - Type safety
+- **[Tailwind CSS](https://tailwindcss.com/)** - Utility-first CSS
+- **[shadcn/ui](https://ui.shadcn.com/)** - Component library
+
+### Backend & Database
+- **[SQLKit](https://github.com/sqlkit-dev/sqlkit)** - Very light sql query builder, we are using most of the sql query using this.
+- **[Drizzle ORM](https://orm.drizzle.team/)** - Awesome sql tool but we are only using for migration
+- **[PostgreSQL](https://www.postgresql.org/)** - Primary database
+- **[Next.js API Routes](https://nextjs.org/docs/api-routes/introduction)** - Backend API
+
+### Search & Storage
+- **[MeilSearch](https://www.meilisearch.com/)** - Fast, typo-tolerant search
+- **[Cloudinary](https://cloudinary.com/)** - Image optimization and storage
+- **[Cloudflare R2](https://www.cloudflare.com/en-gb/developer-platform/products/r2/)** - Alternative file storage
+
+### State Management
+- **[Jotai](https://jotai.org/)** - Atomic state management
+- **[TanStack Query](https://tanstack.com/query)** - Server state management
+- **[React Hook Form](https://react-hook-form.com/)** - Form handling
+- **[Zod](https://zod.dev/)** - Schema validation
+
+### Development Tools
+- **[Bun](https://bun.sh/)** - Fast JavaScript runtime and package manager
+- **[ESLint](https://eslint.org/)** - Code linting
+- **[Prettier](https://prettier.io/)** - Code formatting
+
+## 🚀 Quick Start
+
+### Prerequisites
+- **Node.js 18+** or **Bun 1.0+**
+- **PostgreSQL 14+**
+- **MeilSearch instance**
+- **Cloudinary account**
+- **GitHub OAuth App**
+
+### Environment Variables
+
+Create a `.env.local` file in the root directory:
+
+```env
+# Database
+DATABASE_URL="postgresql://username:password@localhost:5432/techdiary"
+
+# Authentication
+GITHUB_CLIENT_ID="your_github_client_id"
+GITHUB_CLIENT_SECRET="your_github_client_secret"
+GITHUB_CALLBACK_URL="http://localhost:3000/api/auth/github/callback"
+
+# File Storage
+CLOUDINARY_URL="cloudinary://api_key:api_secret@cloud_name"
+
+# Search
+MEILISEARCH_ADMIN_API_KEY="your_meilisearch_admin_key"
+NEXT_PUBLIC_MEILISEARCH_API_HOST="http://localhost:7700"
+NEXT_PUBLIC_MEILISEARCH_SEARCH_API_KEY="your_meilisearch_search_key"
+```
+
+### Installation & Setup
+
+1. **Clone the repository**
+ ```bash
+ git clone https://github.com/techdiary-dev/techdiary.dev.git
+ cd techdiary.dev
+ ```
+
+2. **Install dependencies**
+ ```bash
+ bun install
+ # or
+ npm install
+ ```
+
+3. **Set up the database**
+ ```bash
+ # Generate database schema
+ bun run db:generate
+
+ # Apply migrations
+ bun run db:push
+ ```
+
+4. **Start the development server**
+ ```bash
+ bun run dev
+ ```
+
+5. **Open your browser**
+ Navigate to [http://localhost:3000](http://localhost:3000)
+
+## 📋 Available Scripts
```bash
-npm run dev
-# or
-yarn dev
-# or
-pnpm dev
-# or
-bun dev
+# Development
+bun run dev # Start development server
+bun run build # Build for production
+bun run start # Start production server
+bun run lint # Run ESLint
+
+# Database
+bun run db:generate # Generate migrations from schema changes
+bun run db:push # Push schema changes to database
+bun run db:studio # Open Drizzle Studio (database GUI)
+
+# Backend
+bun run play # Run backend playground script
+```
+
+## 🏗 Project Structure
+
+```
+├── src/
+│ ├── app/ # Next.js App Router pages
+│ │ ├── (home)/ # Homepage routes
+│ │ ├── (dashboard-editor)/ # Protected dashboard routes
+│ │ ├── [username]/ # User profile pages
+│ │ └── api/ # API routes
+│ ├── backend/ # Backend logic and services
+│ │ ├── models/ # Domain models and types
+│ │ ├── persistence/ # Database schemas and repositories
+│ │ └── services/ # Business logic and actions
+│ ├── components/ # Reusable UI components
+│ │ ├── ui/ # shadcn/ui components
+│ │ ├── Editor/ # Article editor components
+│ │ ├── Navbar/ # Navigation components
+│ │ └── render-props/ # Render prop components
+│ ├── hooks/ # Custom React hooks
+│ ├── i18n/ # Internationalization
+│ ├── lib/ # Utility libraries
+│ ├── store/ # Global state management
+│ └── styles/ # Global styles and CSS
+├── docs/ # Documentation
+│ ├── components/ # Component documentation
+│ ├── hooks/ # Hooks documentation
+│ └── PRD.md # Product Requirements Document
+├── public/ # Static assets
+└── migrations/ # Database migrations
```
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+## 🎯 Core Features Deep Dive
+
+### Article Editor
+- **Markdown Support**: Full markdown syntax with extensions
+- **Live Preview**: Real-time preview with markdoc parser
+- **Auto-save**: Saves drafts automatically every 30 seconds
+- **Media Upload**: Drag-and-drop with image cropping
+- **Publishing Controls**: Draft/publish with scheduling
+
+### Search System
+- **MeilSearch Integration**: Lightning-fast full-text search
+- **Typo Tolerance**: Finds results even with spelling mistakes
+- **Faceted Search**: Filter by tags, authors, dates
+- **Search Analytics**: Track popular searches and content gaps
+
+### User Experience
+- **Responsive Design**: Mobile-first approach with desktop enhancements
+- **Accessibility**: WCAG 2.1 AA compliant with screen reader support
+- **Performance**: <3 second page loads, optimized images
+- **PWA Ready**: App-like experience on mobile devices
+
+### Community Features
+- **User Profiles**: Rich profiles with bio, skills, social links
+- **Following System**: Follow favorite authors and topics
+- **Engagement Tools**: Reactions, comments, bookmarks
+- **Content Discovery**: Personalized recommendations
+
+## 🌐 Internationalization
+
+TechDiary supports multiple languages with full localization:
+
+- **Interface Translation**: All UI elements translated
+- **Content Localization**: Date, number, and currency formatting
+- **RTL Support**: Right-to-left text support
+- **Language Detection**: Automatic language detection and switching
+
+Currently supported languages:
+- 🇺🇸 English
+- 🇧🇩 Bengali (বাংলা)
+
+## 🔧 Development Guidelines
+
+### Code Style
+- **TypeScript**: Strict mode enabled for type safety
+- **ESLint**: Enforced code quality rules
+- **Prettier**: Consistent code formatting
+- **Conventional Commits**: Structured commit messages
+
+### Component Architecture
+- **Atomic Design**: Reusable component architecture
+- **Render Props**: Logic separation with render props pattern
+- **Custom Hooks**: Reusable stateful logic
+- **Type Safety**: Comprehensive TypeScript coverage
+
+
+## 📖 Documentation
+
+Comprehensive documentation is available in the `/docs` directory:
+
+- **[Component Documentation](docs/components/README.md)** - Custom components guide
+- **[Hooks Documentation](docs/hooks/README.md)** - Custom hooks reference
+- **[PRD](docs/PRD.md)** - Product Requirements Document
+- **[API Documentation](docs/api/README.md)** - Backend API reference
+
+## 🚢 Deployment
+
+### Production Requirements
+- **Node.js 18+** runtime environment
+- **PostgreSQL 14+** database
+- **MeilSearch** search service
+- **Cloudinary** for image storage
+- **GitHub OAuth** application
+
+### Recommended Hosting
+- **Vercel** - Frontend and API hosting
+- **Railway/Supabase** - PostgreSQL database
+- **Meilisearch Cloud** - Search service
+- **Cloudinary** - Image CDN
+
+### Environment Setup
+1. Set up production environment variables
+2. Configure database with SSL
+3. Set up MeilSearch with proper indexes
+4. Configure Cloudinary transformations
+5. Set up GitHub OAuth for production domain
+
+## 🤝 Contributing
+
+We welcome contributions from the community! Please read our contributing guidelines:
+
+1. **Fork the repository**
+2. **Create a feature branch**: `git checkout -b feature/amazing-feature`
+3. **Make your changes**: Follow our code style and conventions
+4. **Write tests**: Ensure your changes are tested
+5. **Submit a pull request**: With a clear description of changes
+
+### Development Setup
+1. Follow the Quick Start guide
+2. Read the component and hooks documentation
+3. Check existing issues or create new ones
+4. Join our Discord community for discussions
+
+## 📄 License
+
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
+## 🙏 Acknowledgments
-This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
+- **Next.js Team** - For the amazing React framework
+- **shadcn** - For the beautiful UI component library
+- **MeilSearch** - For the powerful search engine
+- **Open Source Community** - For the incredible tools and libraries
-## Learn More
+## 📞 Support & Community
-To learn more about Next.js, take a look at the following resources:
+- **Website**: [techdiary.dev](https://techdiary.dev)
+- **Discord**: [Join our community](https://go.techdiary.dev/discord)
+- **GitHub Issues**: [Report bugs or request features](https://github.com/techdiary-dev/techdiary.dev/issues)
+- **Email**: hello@techdiary.dev
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+---
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
-## Deploy on Vercel
+**Built with ❤️ by the TechDiary Team**
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+[⭐ Star this repo](https://github.com/techdiary-dev/techdiary.dev) • [🐛 Report Bug](https://github.com/techdiary-dev/techdiary.dev/issues) • [✨ Request Feature](https://github.com/techdiary-dev/techdiary.dev/issues)
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
+
\ No newline at end of file
diff --git a/bun.lock b/bun.lock
deleted file mode 100644
index 126009f..0000000
--- a/bun.lock
+++ /dev/null
@@ -1,1378 +0,0 @@
-{
- "lockfileVersion": 1,
- "workspaces": {
- "": {
- "name": "techdiary.dev-next",
- "dependencies": {
- "@cloudinary/react": "^1.14.1",
- "@cloudinary/url-gen": "^1.21.0",
- "@hookform/error-message": "^2.0.1",
- "@hookform/resolvers": "^5.0.0",
- "@markdoc/markdoc": "^0.5.1",
- "@radix-ui/react-alert-dialog": "^1.1.6",
- "@radix-ui/react-avatar": "^1.1.3",
- "@radix-ui/react-dialog": "^1.1.6",
- "@radix-ui/react-dropdown-menu": "^2.1.6",
- "@radix-ui/react-hover-card": "^1.1.6",
- "@radix-ui/react-icons": "^1.3.2",
- "@radix-ui/react-label": "^2.1.2",
- "@radix-ui/react-popover": "^1.1.6",
- "@radix-ui/react-separator": "^1.1.2",
- "@radix-ui/react-slot": "^1.1.2",
- "@radix-ui/react-tabs": "^1.1.3",
- "@radix-ui/react-tooltip": "^1.1.8",
- "@t3-oss/env-nextjs": "^0.12.0",
- "@tailwindcss/postcss": "^4.1.1",
- "@tailwindcss/typography": "^0.5.16",
- "@tanstack/react-query": "^5.69.0",
- "class-variance-authority": "^0.7.1",
- "cloudinary": "^2.6.0",
- "clsx": "^2.1.1",
- "cmdk": "^1.1.1",
- "dotenv": "^16.4.7",
- "drizzle-orm": "^0.41.0",
- "jotai": "^2.12.2",
- "lottie-react": "^2.4.1",
- "lucide-react": "^0.484.0",
- "next": "^15.2.4",
- "next-themes": "^0.4.6",
- "pg": "^8.14.1",
- "react": "^19",
- "react-dom": "^19",
- "react-hook-form": "^7.55.0",
- "recharts": "^2.15.1",
- "schema-dts": "^1.1.5",
- "sqlkit": "^1.0.13",
- "tailwind-merge": "^3.0.2",
- "tw-animate-css": "^1.2.4",
- "use-immer": "^0.11.0",
- "zod": "^3.24.2",
- },
- "devDependencies": {
- "@types/node": "^22.13.13",
- "@types/pg": "^8.11.11",
- "@types/react": "^19.0.12",
- "@types/react-dom": "^19",
- "drizzle-kit": "^0.30.6",
- "eslint": "^9",
- "eslint-config-next": "15.2.3",
- "postcss": "^8.5.3",
- "postcss-import": "^16.1.0",
- "postcss-nesting": "^13.0.1",
- "prettier": "^3.5.3",
- "tailwindcss": "^4.1.1",
- "tsx": "^4.19.3",
- "typescript": "^5.8.2",
- },
- },
- },
- "packages": {
- "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
-
- "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
-
- "@babel/runtime": ["@babel/runtime@7.27.6", "", {}, "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q=="],
-
- "@cloudinary/html": ["@cloudinary/html@1.13.4", "", { "dependencies": { "@types/lodash.clonedeep": "^4.5.6", "@types/lodash.debounce": "^4.0.6", "@types/node": "^14.14.10", "lodash.clonedeep": "^4.5.0", "lodash.debounce": "^4.0.8", "typescript": "^4.1.2" } }, "sha512-noBk9D2VZgZkQIs5/y29OsJDmwp0FtgAlKrrp1+0Jp2HMu+68sdDJ3zi4/ZuLCnbdqthGuxP83trowG+Zsa68Q=="],
-
- "@cloudinary/react": ["@cloudinary/react@1.14.3", "", { "dependencies": { "@cloudinary/html": "^1.13.4" }, "peerDependencies": { "react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-AJ662pNAGEapRdkOOQstQHiKtXHBdoNkduWU3levugZ34ZiabBxmViISo16MtxZuBkzj96sV9ppmcq6foPqJ2w=="],
-
- "@cloudinary/transformation-builder-sdk": ["@cloudinary/transformation-builder-sdk@1.17.0", "", { "dependencies": { "@cloudinary/url-gen": "^1.7.0" } }, "sha512-zPHNtEpLkil+1obvLK7zHDMWAs9ZwUGI0GUKnMMkEC3pOLtKETswPBdLAjJTMH512lGc18vgdzogWdItPRN3Kg=="],
-
- "@cloudinary/url-gen": ["@cloudinary/url-gen@1.21.0", "", { "dependencies": { "@cloudinary/transformation-builder-sdk": "^1.15.1" } }, "sha512-ctYcCzX3G3vcgnESTU2ET3K1XsBiXcEnBddCGV0QbR3fJhLLrIShjSMEwZoepgh4LAFOHJu9DzvLFr+E8R7c7g=="],
-
- "@csstools/selector-resolve-nested": ["@csstools/selector-resolve-nested@3.1.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g=="],
-
- "@csstools/selector-specificity": ["@csstools/selector-specificity@5.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw=="],
-
- "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="],
-
- "@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" } }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="],
-
- "@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="],
-
- "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA=="],
-
- "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="],
-
- "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="],
-
- "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="],
-
- "@esbuild/android-arm": ["@esbuild/android-arm@0.19.12", "", { "os": "android", "cpu": "arm" }, "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w=="],
-
- "@esbuild/android-arm64": ["@esbuild/android-arm64@0.19.12", "", { "os": "android", "cpu": "arm64" }, "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA=="],
-
- "@esbuild/android-x64": ["@esbuild/android-x64@0.19.12", "", { "os": "android", "cpu": "x64" }, "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew=="],
-
- "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.19.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g=="],
-
- "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.19.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A=="],
-
- "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.19.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA=="],
-
- "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.19.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg=="],
-
- "@esbuild/linux-arm": ["@esbuild/linux-arm@0.19.12", "", { "os": "linux", "cpu": "arm" }, "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w=="],
-
- "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.19.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA=="],
-
- "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.19.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA=="],
-
- "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA=="],
-
- "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w=="],
-
- "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.19.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg=="],
-
- "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg=="],
-
- "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.19.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg=="],
-
- "@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.12", "", { "os": "linux", "cpu": "x64" }, "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg=="],
-
- "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="],
-
- "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.12", "", { "os": "none", "cpu": "x64" }, "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA=="],
-
- "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="],
-
- "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw=="],
-
- "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA=="],
-
- "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.19.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A=="],
-
- "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.19.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ=="],
-
- "@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="],
-
- "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
-
- "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
-
- "@eslint/config-array": ["@eslint/config-array@0.20.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ=="],
-
- "@eslint/config-helpers": ["@eslint/config-helpers@0.2.2", "", {}, "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg=="],
-
- "@eslint/core": ["@eslint/core@0.14.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg=="],
-
- "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
-
- "@eslint/js": ["@eslint/js@9.28.0", "", {}, "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg=="],
-
- "@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
-
- "@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.1", "", { "dependencies": { "@eslint/core": "^0.14.0", "levn": "^0.4.1" } }, "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w=="],
-
- "@floating-ui/core": ["@floating-ui/core@1.7.1", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw=="],
-
- "@floating-ui/dom": ["@floating-ui/dom@1.7.1", "", { "dependencies": { "@floating-ui/core": "^1.7.1", "@floating-ui/utils": "^0.2.9" } }, "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ=="],
-
- "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.3", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA=="],
-
- "@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="],
-
- "@hookform/error-message": ["@hookform/error-message@2.0.1", "", { "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0", "react-hook-form": "^7.0.0" } }, "sha512-U410sAr92xgxT1idlu9WWOVjndxLdgPUHEB8Schr27C9eh7/xUnITWpCMF93s+lGiG++D4JnbSnrb5A21AdSNg=="],
-
- "@hookform/resolvers": ["@hookform/resolvers@5.1.1", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-J/NVING3LMAEvexJkyTLjruSm7aOFx7QX21pzkiJfMoNG0wl5aFEjLTl7ay7IQb9EWY6AkrBy7tHL2Alijpdcg=="],
-
- "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
-
- "@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
-
- "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
-
- "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
-
- "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.1.0" }, "os": "darwin", "cpu": "arm64" }, "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg=="],
-
- "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.1.0" }, "os": "darwin", "cpu": "x64" }, "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g=="],
-
- "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA=="],
-
- "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.1.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ=="],
-
- "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.1.0", "", { "os": "linux", "cpu": "arm" }, "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA=="],
-
- "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew=="],
-
- "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.1.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ=="],
-
- "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.1.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA=="],
-
- "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q=="],
-
- "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w=="],
-
- "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A=="],
-
- "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.1.0" }, "os": "linux", "cpu": "arm" }, "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ=="],
-
- "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.1.0" }, "os": "linux", "cpu": "arm64" }, "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q=="],
-
- "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.1.0" }, "os": "linux", "cpu": "s390x" }, "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw=="],
-
- "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.1.0" }, "os": "linux", "cpu": "x64" }, "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ=="],
-
- "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" }, "os": "linux", "cpu": "arm64" }, "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA=="],
-
- "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.1.0" }, "os": "linux", "cpu": "x64" }, "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA=="],
-
- "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.2", "", { "dependencies": { "@emnapi/runtime": "^1.4.3" }, "cpu": "none" }, "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ=="],
-
- "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ=="],
-
- "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw=="],
-
- "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.2", "", { "os": "win32", "cpu": "x64" }, "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw=="],
-
- "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
-
- "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
-
- "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
-
- "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
-
- "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
-
- "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
-
- "@markdoc/markdoc": ["@markdoc/markdoc@0.5.2", "", { "optionalDependencies": { "@types/linkify-it": "^3.0.1", "@types/markdown-it": "12.2.3" }, "peerDependencies": { "@types/react": "*", "react": "*" }, "optionalPeers": ["@types/react", "react"] }, "sha512-clrqWpJ3+S8PXigRE+zBIs6LVZYXaJ7JTDFq1CcCWc4xpoB2kz+9qRUQQ4vXtLUjQ8ige1BGdMruV6gM/2gloA=="],
-
- "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.9.0" } }, "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA=="],
-
- "@next/env": ["@next/env@15.3.3", "", {}, "sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw=="],
-
- "@next/eslint-plugin-next": ["@next/eslint-plugin-next@15.2.3", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-eNSOIMJtjs+dp4Ms1tB1PPPJUQHP3uZK+OQ7iFY9qXpGO6ojT6imCL+KcUOqE/GXGidWbBZJzYdgAdPHqeCEPA=="],
-
- "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg=="],
-
- "@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.3.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw=="],
-
- "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw=="],
-
- "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.3.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA=="],
-
- "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw=="],
-
- "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.3.3", "", { "os": "linux", "cpu": "x64" }, "sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw=="],
-
- "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.3.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ=="],
-
- "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.3.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw=="],
-
- "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
-
- "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
-
- "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
-
- "@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
-
- "@petamoriken/float16": ["@petamoriken/float16@3.9.2", "", {}, "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog=="],
-
- "@radix-ui/primitive": ["@radix-ui/primitive@1.1.2", "", {}, "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA=="],
-
- "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.14", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IOZfZ3nPvN6lXpJTBCunFQPRSvK8MDgSc1FB85xnIpUKOw9en0dJj8JmCAxV7BiZdtYlUpmrQjoTFkVYtdoWzQ=="],
-
- "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
-
- "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.10", "", { "dependencies": { "@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-is-hydrated": "0.1.0", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog=="],
-
- "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="],
-
- "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="],
-
- "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
-
- "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-focus-guards": "1.1.2", "@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.4", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw=="],
-
- "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
-
- "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ=="],
-
- "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@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.15", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ=="],
-
- "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA=="],
-
- "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
-
- "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-popper": "1.2.7", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q=="],
-
- "@radix-ui/react-icons": ["@radix-ui/react-icons@1.3.2", "", { "peerDependencies": { "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" } }, "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g=="],
-
- "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "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" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
-
- "@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
-
- "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@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.10", "@radix-ui/react-focus-guards": "1.1.2", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.7", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.10", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew=="],
-
- "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-focus-guards": "1.1.2", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.7", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw=="],
-
- "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.7", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ=="],
-
- "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
-
- "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.4", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA=="],
-
- "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
-
- "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q=="],
-
- "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
-
- "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "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" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
-
- "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "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-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw=="],
-
- "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.7", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.7", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", "@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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw=="],
-
- "@radix-ui/react-use-callback-ref": ["@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" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
-
- "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "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" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="],
-
- "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "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" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
-
- "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "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" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
-
- "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="],
-
- "@radix-ui/react-use-layout-effect": ["@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" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="],
-
- "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="],
-
- "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "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" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="],
-
- "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "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" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="],
-
- "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
-
- "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
-
- "@rushstack/eslint-patch": ["@rushstack/eslint-patch@1.11.0", "", {}, "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ=="],
-
- "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
-
- "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
-
- "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
-
- "@t3-oss/env-core": ["@t3-oss/env-core@0.12.0", "", { "peerDependencies": { "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0" }, "optionalPeers": ["typescript", "valibot", "zod"] }, "sha512-lOPj8d9nJJTt81mMuN9GMk8x5veOt7q9m11OSnCBJhwp1QrL/qR+M8Y467ULBSm9SunosryWNbmQQbgoiMgcdw=="],
-
- "@t3-oss/env-nextjs": ["@t3-oss/env-nextjs@0.12.0", "", { "dependencies": { "@t3-oss/env-core": "0.12.0" }, "peerDependencies": { "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0" }, "optionalPeers": ["typescript", "valibot", "zod"] }, "sha512-rFnvYk1049RnNVUPvY8iQ55AuQh1Rr+qZzQBh3t++RttCGK4COpXGNxS4+45afuQq02lu+QAOy/5955aU8hRKw=="],
-
- "@tailwindcss/node": ["@tailwindcss/node@4.1.8", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.8" } }, "sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q=="],
-
- "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.8", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.8", "@tailwindcss/oxide-darwin-arm64": "4.1.8", "@tailwindcss/oxide-darwin-x64": "4.1.8", "@tailwindcss/oxide-freebsd-x64": "4.1.8", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.8", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.8", "@tailwindcss/oxide-linux-arm64-musl": "4.1.8", "@tailwindcss/oxide-linux-x64-gnu": "4.1.8", "@tailwindcss/oxide-linux-x64-musl": "4.1.8", "@tailwindcss/oxide-wasm32-wasi": "4.1.8", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.8", "@tailwindcss/oxide-win32-x64-msvc": "4.1.8" } }, "sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A=="],
-
- "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.8", "", { "os": "android", "cpu": "arm64" }, "sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg=="],
-
- "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A=="],
-
- "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw=="],
-
- "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg=="],
-
- "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8", "", { "os": "linux", "cpu": "arm" }, "sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ=="],
-
- "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q=="],
-
- "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ=="],
-
- "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.8", "", { "os": "linux", "cpu": "x64" }, "sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g=="],
-
- "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.8", "", { "os": "linux", "cpu": "x64" }, "sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg=="],
-
- "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.8", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.10", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg=="],
-
- "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA=="],
-
- "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.8", "", { "os": "win32", "cpu": "x64" }, "sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ=="],
-
- "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.8", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.8", "@tailwindcss/oxide": "4.1.8", "postcss": "^8.4.41", "tailwindcss": "4.1.8" } }, "sha512-vB/vlf7rIky+w94aWMw34bWW1ka6g6C3xIOdICKX2GC0VcLtL6fhlLiafF0DVIwa9V6EHz8kbWMkS2s2QvvNlw=="],
-
- "@tailwindcss/typography": ["@tailwindcss/typography@0.5.16", "", { "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA=="],
-
- "@tanstack/query-core": ["@tanstack/query-core@5.80.6", "", {}, "sha512-nl7YxT/TAU+VTf+e2zTkObGTyY8YZBMnbgeA1ee66lIVqzKlYursAII6z5t0e6rXgwUMJSV4dshBTNacNpZHbQ=="],
-
- "@tanstack/react-query": ["@tanstack/react-query@5.80.6", "", { "dependencies": { "@tanstack/query-core": "5.80.6" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-izX+5CnkpON3NQGcEm3/d7LfFQNo9ZpFtX2QsINgCYK9LT2VCIdi8D3bMaMSNhrAJCznRoAkFic76uvLroALBw=="],
-
- "@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
-
- "@types/d3-array": ["@types/d3-array@3.2.1", "", {}, "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="],
-
- "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="],
-
- "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="],
-
- "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="],
-
- "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="],
-
- "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="],
-
- "@types/d3-shape": ["@types/d3-shape@3.1.7", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg=="],
-
- "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="],
-
- "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="],
-
- "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
-
- "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
-
- "@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
-
- "@types/linkify-it": ["@types/linkify-it@3.0.5", "", {}, "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw=="],
-
- "@types/lodash": ["@types/lodash@4.17.17", "", {}, "sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ=="],
-
- "@types/lodash.clonedeep": ["@types/lodash.clonedeep@4.5.9", "", { "dependencies": { "@types/lodash": "*" } }, "sha512-19429mWC+FyaAhOLzsS8kZUsI+/GmBAQ0HFiCPsKGU+7pBXOQWhyrY6xNNDwUSX8SMZMJvuFVMF9O5dQOlQK9Q=="],
-
- "@types/lodash.debounce": ["@types/lodash.debounce@4.0.9", "", { "dependencies": { "@types/lodash": "*" } }, "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ=="],
-
- "@types/markdown-it": ["@types/markdown-it@12.2.3", "", { "dependencies": { "@types/linkify-it": "*", "@types/mdurl": "*" } }, "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ=="],
-
- "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="],
-
- "@types/node": ["@types/node@22.15.31", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw=="],
-
- "@types/pg": ["@types/pg@8.15.4", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg=="],
-
- "@types/react": ["@types/react@19.1.7", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-BnsPLV43ddr05N71gaGzyZ5hzkCmGwhMvYc8zmvI8Ci1bRkkDSzDDVfAXfN2tk748OwI7ediiPX6PfT9p0QGVg=="],
-
- "@types/react-dom": ["@types/react-dom@19.1.6", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw=="],
-
- "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.34.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/type-utils": "8.34.0", "@typescript-eslint/utils": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.34.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w=="],
-
- "@typescript-eslint/parser": ["@typescript-eslint/parser@8.34.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/typescript-estree": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA=="],
-
- "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.34.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.34.0", "@typescript-eslint/types": "^8.34.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw=="],
-
- "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.34.0", "", { "dependencies": { "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0" } }, "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw=="],
-
- "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.34.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA=="],
-
- "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.34.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.34.0", "@typescript-eslint/utils": "8.34.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg=="],
-
- "@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
-
- "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.34.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.34.0", "@typescript-eslint/tsconfig-utils": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg=="],
-
- "@typescript-eslint/utils": ["@typescript-eslint/utils@8.34.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/typescript-estree": "8.34.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ=="],
-
- "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.34.0", "", { "dependencies": { "@typescript-eslint/types": "8.34.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA=="],
-
- "@unrs/resolver-binding-darwin-arm64": ["@unrs/resolver-binding-darwin-arm64@1.7.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LIKeCzNSkTWwGHjtiUIfvS96+7kpuyrKq2pzw/0XT2S8ykczj40Hh27oLTbXguCX8tGrCoaD2yXxzwqMMhAzhA=="],
-
- "@unrs/resolver-binding-darwin-x64": ["@unrs/resolver-binding-darwin-x64@1.7.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-GB5G3qUNrdo2l6xaZehpz1ln4wCQ75tr51HZ8OQEcX6XkBIFVL9E4ikCZvCmRmUgKGR+zP5ogyFib7ZbIMWKWA=="],
-
- "@unrs/resolver-binding-freebsd-x64": ["@unrs/resolver-binding-freebsd-x64@1.7.13", "", { "os": "freebsd", "cpu": "x64" }, "sha512-rb8gzoBgqVhDkQiKaq+MrFPhNK3x8XkSFhgU55LfgOa5skv7KIdM3dELKzQVNZNlY49DuZmm0FsEfHK5xPKKiA=="],
-
- "@unrs/resolver-binding-linux-arm-gnueabihf": ["@unrs/resolver-binding-linux-arm-gnueabihf@1.7.13", "", { "os": "linux", "cpu": "arm" }, "sha512-bqdzngbTGzhsqhTV3SWECyZUAyvtewKtrCW4E8QPcK6yHSaN0k1h9gKwNOBxFwIqkQRsAibpm18XDum8M5AiCw=="],
-
- "@unrs/resolver-binding-linux-arm-musleabihf": ["@unrs/resolver-binding-linux-arm-musleabihf@1.7.13", "", { "os": "linux", "cpu": "arm" }, "sha512-vkoL3DSS5tsUNLhNtBJWaqDJNNEQsMCr0o2N02sLCSpe5S8TQHz+klQT42Qgj4PqATMwnG3OF0QQ5BH0oAKIPg=="],
-
- "@unrs/resolver-binding-linux-arm64-gnu": ["@unrs/resolver-binding-linux-arm64-gnu@1.7.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-uNpLKxlDF+NF6aUztbAVhhFSF65zf/6QEfk5NifUgYFbpBObzvMnl2ydEsXV96spwPcmeNTpG9byvq+Twwd3HQ=="],
-
- "@unrs/resolver-binding-linux-arm64-musl": ["@unrs/resolver-binding-linux-arm64-musl@1.7.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-mEFL6q7vtxA6YJ9sLbxCnKOBynOvClVOcqwUErmaCxA94hgP11rlstouySxJCGeFAb8KfUX9mui82waYrqoBlQ=="],
-
- "@unrs/resolver-binding-linux-ppc64-gnu": ["@unrs/resolver-binding-linux-ppc64-gnu@1.7.13", "", { "os": "linux", "cpu": "ppc64" }, "sha512-MjJaNk8HK3rCOIPS6AQPJXlrDfG1LaePum+CZddHZygPqDNZyVrVdWTadT+U51vIx5QOdEE0oXcgTY+7VYsU1g=="],
-
- "@unrs/resolver-binding-linux-riscv64-gnu": ["@unrs/resolver-binding-linux-riscv64-gnu@1.7.13", "", { "os": "linux", "cpu": "none" }, "sha512-9gAuT1+ed2eIuOXHSu4SdJOe7SUEzPTpOTEuTjGePvMEoWHywY5pvlcY7xMn3d8rhKHpwMzEhl8F8Oy+rkudzA=="],
-
- "@unrs/resolver-binding-linux-riscv64-musl": ["@unrs/resolver-binding-linux-riscv64-musl@1.7.13", "", { "os": "linux", "cpu": "none" }, "sha512-CNrJythJN9jC8SIJGoawebYylzGNJuWAWTKxxxx5Fr3DGEXbex/We4U7N4u6/dQAK3cLVOuAE/9a4D2JH35JIA=="],
-
- "@unrs/resolver-binding-linux-s390x-gnu": ["@unrs/resolver-binding-linux-s390x-gnu@1.7.13", "", { "os": "linux", "cpu": "s390x" }, "sha512-J0MVXXPvM2Bv+f+gzOZHLHEmXUJNKwJqkfMDTwE763w/tD+OA7UlTMLQihrcYRXwW5jZ8nbM2cEWTeFsTiH2JQ=="],
-
- "@unrs/resolver-binding-linux-x64-gnu": ["@unrs/resolver-binding-linux-x64-gnu@1.7.13", "", { "os": "linux", "cpu": "x64" }, "sha512-Ii2WhtIpeWUe6XG/YhPUX3JNL3PiyXe56PJzqAYDUyB0gctkk/nngpuPnNKlLMcN9FID0T39mIJPhA6YpRcGDQ=="],
-
- "@unrs/resolver-binding-linux-x64-musl": ["@unrs/resolver-binding-linux-x64-musl@1.7.13", "", { "os": "linux", "cpu": "x64" }, "sha512-8F5E9EhtGYkfEM1OhyVgq76+SnMF5NfZS4v5Rq9JlfuqPnqXWgUjg903hxnG54PQr4I3jmG5bEeT77pGAA3Vvg=="],
-
- "@unrs/resolver-binding-wasm32-wasi": ["@unrs/resolver-binding-wasm32-wasi@1.7.13", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" }, "cpu": "none" }, "sha512-7RXGTyDtyR/5o1FlBcjEaQQmQ2rKvu5Jq0Uhvce3PsbreZ61M4LQ5Mey2OMomIq4opphAkfDdm/lkHhWJNKNrw=="],
-
- "@unrs/resolver-binding-win32-arm64-msvc": ["@unrs/resolver-binding-win32-arm64-msvc@1.7.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-MomJVcaVZe3j+CvkcfIVEcQyOOzauKpJYGY8d6PoKXn1FalMVGHX9/c0kXCI0WCK+CRGMExAiQhD8jkhyUVKxg=="],
-
- "@unrs/resolver-binding-win32-ia32-msvc": ["@unrs/resolver-binding-win32-ia32-msvc@1.7.13", "", { "os": "win32", "cpu": "ia32" }, "sha512-pnHfzbFj6e4gUARI1Yvz0TUhmFZae248O7JOMCSmSBN3R35RJiKyHmsMuIiPrUYWDzm5jUMPTxSs+b3Ipawusw=="],
-
- "@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.7.13", "", { "os": "win32", "cpu": "x64" }, "sha512-tI0+FTntE3BD0UxhTP12F/iTtkeMK+qh72/2aSxPZnTlOcMR9CTJid8CdppbSjj9wenq7PNcqScLtpPENH3Lvg=="],
-
- "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
-
- "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
-
- "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
-
- "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
-
- "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
-
- "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
-
- "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
-
- "array-buffer-byte-length": ["array-buffer-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "is-array-buffer": "^3.0.5" } }, "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw=="],
-
- "array-includes": ["array-includes@3.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.0", "es-object-atoms": "^1.1.1", "get-intrinsic": "^1.3.0", "is-string": "^1.1.1", "math-intrinsics": "^1.1.0" } }, "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ=="],
-
- "array.prototype.findlast": ["array.prototype.findlast@1.2.5", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ=="],
-
- "array.prototype.findlastindex": ["array.prototype.findlastindex@1.2.6", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-shim-unscopables": "^1.1.0" } }, "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ=="],
-
- "array.prototype.flat": ["array.prototype.flat@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg=="],
-
- "array.prototype.flatmap": ["array.prototype.flatmap@1.3.3", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-shim-unscopables": "^1.0.2" } }, "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg=="],
-
- "array.prototype.tosorted": ["array.prototype.tosorted@1.1.4", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" } }, "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA=="],
-
- "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="],
-
- "ast-types-flow": ["ast-types-flow@0.0.8", "", {}, "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ=="],
-
- "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
-
- "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
-
- "axe-core": ["axe-core@4.10.3", "", {}, "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg=="],
-
- "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
-
- "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
-
- "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
-
- "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
-
- "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
-
- "busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="],
-
- "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
-
- "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
-
- "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
-
- "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
-
- "caniuse-lite": ["caniuse-lite@1.0.30001721", "", {}, "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ=="],
-
- "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
-
- "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
-
- "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
-
- "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
-
- "cloudinary": ["cloudinary@2.6.1", "", { "dependencies": { "lodash": "^4.17.21", "q": "^1.5.1" } }, "sha512-Dt7o3p4VzxYoTi+EqWkVQmGy6WiXIyMcG5Gbr9kPR/EQ+jZa+3FFzlDKfDx1uDsaB1aTR1gYeO6wZqrgLFaByQ=="],
-
- "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
-
- "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="],
-
- "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
-
- "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
-
- "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
-
- "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
-
- "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
-
- "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
-
- "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
-
- "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
-
- "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
-
- "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
-
- "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="],
-
- "d3-format": ["d3-format@3.1.0", "", {}, "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="],
-
- "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
-
- "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
-
- "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="],
-
- "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
-
- "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="],
-
- "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
-
- "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
-
- "damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
-
- "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="],
-
- "data-view-byte-length": ["data-view-byte-length@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ=="],
-
- "data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
-
- "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
-
- "decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="],
-
- "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
-
- "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
-
- "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
-
- "detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
-
- "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
-
- "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
-
- "dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="],
-
- "dotenv": ["dotenv@16.5.0", "", {}, "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg=="],
-
- "drizzle-kit": ["drizzle-kit@0.30.6", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.19.7", "esbuild-register": "^3.5.0", "gel": "^2.0.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-U4wWit0fyZuGuP7iNmRleQyK2V8wCuv57vf5l3MnG4z4fzNTjY/U13M8owyQ5RavqvqxBifWORaR3wIUzlN64g=="],
-
- "drizzle-orm": ["drizzle-orm@0.41.0", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-7A4ZxhHk9gdlXmTdPj/lREtP+3u8KvZ4yEN6MYVxBzZGex5Wtdc+CWSbu7btgF6TB0N+MNPrvW7RKBbxJchs/Q=="],
-
- "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
-
- "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
-
- "enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="],
-
- "env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="],
-
- "es-abstract": ["es-abstract@1.24.0", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg=="],
-
- "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
-
- "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
-
- "es-iterator-helpers": ["es-iterator-helpers@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.6", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.4", "safe-array-concat": "^1.1.3" } }, "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w=="],
-
- "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
-
- "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
-
- "es-shim-unscopables": ["es-shim-unscopables@1.1.0", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw=="],
-
- "es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
-
- "esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="],
-
- "esbuild-register": ["esbuild-register@3.6.0", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "esbuild": ">=0.12 <1" } }, "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg=="],
-
- "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
-
- "eslint": ["eslint@9.28.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.28.0", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ=="],
-
- "eslint-config-next": ["eslint-config-next@15.2.3", "", { "dependencies": { "@next/eslint-plugin-next": "15.2.3", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^5.0.0" }, "peerDependencies": { "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-VDQwbajhNMFmrhLWVyUXCqsGPN+zz5G8Ys/QwFubfsxTIrkqdx3N3x3QPW+pERz8bzGPP0IgEm8cNbZcd8PFRQ=="],
-
- "eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="],
-
- "eslint-import-resolver-typescript": ["eslint-import-resolver-typescript@3.10.1", "", { "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.4.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^2.0.0", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.13", "unrs-resolver": "^1.6.2" }, "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", "eslint-plugin-import-x": "*" }, "optionalPeers": ["eslint-plugin-import", "eslint-plugin-import-x"] }, "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ=="],
-
- "eslint-module-utils": ["eslint-module-utils@2.12.0", "", { "dependencies": { "debug": "^3.2.7" } }, "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg=="],
-
- "eslint-plugin-import": ["eslint-plugin-import@2.31.0", "", { "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.12.0", "hasown": "^2.0.2", "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", "object.values": "^1.2.0", "semver": "^6.3.1", "string.prototype.trimend": "^1.0.8", "tsconfig-paths": "^3.15.0" }, "peerDependencies": { "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A=="],
-
- "eslint-plugin-jsx-a11y": ["eslint-plugin-jsx-a11y@6.10.2", "", { "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", "axe-core": "^4.10.0", "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "safe-regex-test": "^1.0.3", "string.prototype.includes": "^2.0.1" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q=="],
-
- "eslint-plugin-react": ["eslint-plugin-react@7.37.5", "", { "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA=="],
-
- "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="],
-
- "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
-
- "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
-
- "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
-
- "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
-
- "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
-
- "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
-
- "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
-
- "eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="],
-
- "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
-
- "fast-equals": ["fast-equals@5.2.2", "", {}, "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw=="],
-
- "fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="],
-
- "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
-
- "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
-
- "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
-
- "fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
-
- "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
-
- "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
-
- "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
-
- "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
-
- "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
-
- "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
-
- "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
-
- "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
-
- "function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
-
- "functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
-
- "gel": ["gel@2.1.0", "", { "dependencies": { "@petamoriken/float16": "^3.8.7", "debug": "^4.3.4", "env-paths": "^3.0.0", "semver": "^7.6.2", "shell-quote": "^1.8.1", "which": "^4.0.0" }, "bin": { "gel": "dist/cli.mjs" } }, "sha512-HCeRqInCt6BjbMmeghJ6BKeYwOj7WJT5Db6IWWAA3IMUUa7or7zJfTUEkUWCxiOtoXnwnm96sFK9Fr47Yh2hOA=="],
-
- "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
-
- "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
-
- "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
-
- "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
-
- "get-tsconfig": ["get-tsconfig@4.10.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="],
-
- "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
-
- "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
-
- "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
-
- "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
-
- "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
-
- "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
-
- "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
-
- "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
-
- "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="],
-
- "has-proto": ["has-proto@1.2.0", "", { "dependencies": { "dunder-proto": "^1.0.0" } }, "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ=="],
-
- "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
-
- "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
-
- "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
-
- "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
-
- "immer": ["immer@10.1.1", "", {}, "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw=="],
-
- "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
-
- "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
-
- "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
-
- "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
-
- "is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
-
- "is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
-
- "is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="],
-
- "is-bigint": ["is-bigint@1.1.0", "", { "dependencies": { "has-bigints": "^1.0.2" } }, "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ=="],
-
- "is-boolean-object": ["is-boolean-object@1.2.2", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A=="],
-
- "is-bun-module": ["is-bun-module@2.0.0", "", { "dependencies": { "semver": "^7.7.1" } }, "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ=="],
-
- "is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
-
- "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
-
- "is-data-view": ["is-data-view@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" } }, "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw=="],
-
- "is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="],
-
- "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
-
- "is-finalizationregistry": ["is-finalizationregistry@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg=="],
-
- "is-generator-function": ["is-generator-function@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "get-proto": "^1.0.0", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ=="],
-
- "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
-
- "is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
-
- "is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
-
- "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
-
- "is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="],
-
- "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
-
- "is-set": ["is-set@2.0.3", "", {}, "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg=="],
-
- "is-shared-array-buffer": ["is-shared-array-buffer@1.0.4", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A=="],
-
- "is-string": ["is-string@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA=="],
-
- "is-symbol": ["is-symbol@1.1.1", "", { "dependencies": { "call-bound": "^1.0.2", "has-symbols": "^1.1.0", "safe-regex-test": "^1.1.0" } }, "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w=="],
-
- "is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="],
-
- "is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="],
-
- "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="],
-
- "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="],
-
- "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
-
- "isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="],
-
- "iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="],
-
- "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
-
- "jotai": ["jotai@2.12.5", "", { "peerDependencies": { "@types/react": ">=17.0.0", "react": ">=17.0.0" }, "optionalPeers": ["@types/react", "react"] }, "sha512-G8m32HW3lSmcz/4mbqx0hgJIQ0ekndKWiYP7kWVKi0p6saLXdSoye+FZiOFyonnd7Q482LCzm8sMDl7Ar1NWDw=="],
-
- "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
-
- "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
-
- "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
-
- "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
-
- "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
-
- "json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="],
-
- "jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
-
- "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
-
- "language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="],
-
- "language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
-
- "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
-
- "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
-
- "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
-
- "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
-
- "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="],
-
- "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="],
-
- "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="],
-
- "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="],
-
- "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="],
-
- "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="],
-
- "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="],
-
- "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="],
-
- "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
-
- "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
-
- "lodash.castarray": ["lodash.castarray@4.4.0", "", {}, "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q=="],
-
- "lodash.clonedeep": ["lodash.clonedeep@4.5.0", "", {}, "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="],
-
- "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
-
- "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="],
-
- "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
-
- "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
-
- "lottie-react": ["lottie-react@2.4.1", "", { "dependencies": { "lottie-web": "^5.10.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-LQrH7jlkigIIv++wIyrOYFLHSKQpEY4zehPicL9bQsrt1rnoKRYCYgpCUe5maqylNtacy58/sQDZTkwMcTRxZw=="],
-
- "lottie-web": ["lottie-web@5.13.0", "", {}, "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ=="],
-
- "lucide-react": ["lucide-react@0.484.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-oZy8coK9kZzvqhSgfbGkPtTgyjpBvs3ukLgDPv14dSOZtBtboryWF5o8i3qen7QbGg7JhiJBz5mK1p8YoMZTLQ=="],
-
- "magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
-
- "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
-
- "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
-
- "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
-
- "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
- "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
-
- "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
- "minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="],
-
- "mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
-
- "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
-
- "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
-
- "napi-postinstall": ["napi-postinstall@0.2.4", "", { "bin": { "napi-postinstall": "lib/cli.js" } }, "sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg=="],
-
- "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
-
- "next": ["next@15.3.3", "", { "dependencies": { "@next/env": "15.3.3", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.3.3", "@next/swc-darwin-x64": "15.3.3", "@next/swc-linux-arm64-gnu": "15.3.3", "@next/swc-linux-arm64-musl": "15.3.3", "@next/swc-linux-x64-gnu": "15.3.3", "@next/swc-linux-x64-musl": "15.3.3", "@next/swc-win32-arm64-msvc": "15.3.3", "@next/swc-win32-x64-msvc": "15.3.3", "sharp": "^0.34.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw=="],
-
- "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
-
- "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
-
- "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
-
- "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
-
- "object.assign": ["object.assign@4.1.7", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0", "has-symbols": "^1.1.0", "object-keys": "^1.1.1" } }, "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw=="],
-
- "object.entries": ["object.entries@1.1.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-object-atoms": "^1.1.1" } }, "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw=="],
-
- "object.fromentries": ["object.fromentries@2.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2", "es-object-atoms": "^1.0.0" } }, "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ=="],
-
- "object.groupby": ["object.groupby@1.0.3", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.2" } }, "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ=="],
-
- "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="],
-
- "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
-
- "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="],
-
- "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
-
- "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
-
- "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
-
- "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
-
- "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
-
- "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
-
- "pg": ["pg@8.16.0", "", { "dependencies": { "pg-connection-string": "^2.9.0", "pg-pool": "^3.10.0", "pg-protocol": "^1.10.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "^1.2.5" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-7SKfdvP8CTNXjMUzfcVTaI+TDzBEeaUnVwiVGZQD1Hh33Kpev7liQba9uLd4CfN8r9mCVsD0JIpq03+Unpz+kg=="],
-
- "pg-cloudflare": ["pg-cloudflare@1.2.5", "", {}, "sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg=="],
-
- "pg-connection-string": ["pg-connection-string@2.9.0", "", {}, "sha512-P2DEBKuvh5RClafLngkAuGe9OUlFV7ebu8w1kmaaOgPcpJd1RIFh7otETfI6hAR8YupOLFTY7nuvvIn7PLciUQ=="],
-
- "pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="],
-
- "pg-pool": ["pg-pool@3.10.0", "", { "peerDependencies": { "pg": ">=8.0" } }, "sha512-DzZ26On4sQ0KmqnO34muPcmKbhrjmyiO4lCCR0VwEd7MjmiKf5NTg/6+apUEu0NF7ESa37CGzFxH513CoUmWnA=="],
-
- "pg-protocol": ["pg-protocol@1.10.0", "", {}, "sha512-IpdytjudNuLv8nhlHs/UrVBhU0e78J0oIS/0AVdTbWxSOkFUVdsHC/NrorO6nXsQNDTT1kzDSOMJubBQviX18Q=="],
-
- "pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="],
-
- "pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "^4.1.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="],
-
- "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
-
- "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
-
- "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
-
- "possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
-
- "postcss": ["postcss@8.5.4", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w=="],
-
- "postcss-import": ["postcss-import@16.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg=="],
-
- "postcss-nesting": ["postcss-nesting@13.0.2", "", { "dependencies": { "@csstools/selector-resolve-nested": "^3.1.0", "@csstools/selector-specificity": "^5.0.0", "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ=="],
-
- "postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
-
- "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
-
- "postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
-
- "postgres-bytea": ["postgres-bytea@1.0.0", "", {}, "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="],
-
- "postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="],
-
- "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="],
-
- "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
-
- "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
-
- "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
-
- "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
-
- "q": ["q@1.5.1", "", {}, "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw=="],
-
- "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
-
- "react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
-
- "react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="],
-
- "react-hook-form": ["react-hook-form@7.57.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-RbEks3+cbvTP84l/VXGUZ+JMrKOS8ykQCRYdm5aYsxnDquL0vspsyNhGRO7pcH6hsZqWlPOjLye7rJqdtdAmlg=="],
-
- "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
-
- "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "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" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
-
- "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
-
- "react-smooth": ["react-smooth@4.0.4", "", { "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q=="],
-
- "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
-
- "react-transition-group": ["react-transition-group@4.4.5", "", { "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" }, "peerDependencies": { "react": ">=16.6.0", "react-dom": ">=16.6.0" } }, "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="],
-
- "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
-
- "recharts": ["recharts@2.15.3", "", { "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", "lodash": "^4.17.21", "react-is": "^18.3.1", "react-smooth": "^4.0.4", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-EdOPzTwcFSuqtvkDoaM5ws/Km1+WTAO2eizL7rqiG0V2UVhTnz0m7J2i0CjVPUCdEkZImaWvXLbZDS2H5t6GFQ=="],
-
- "recharts-scale": ["recharts-scale@0.4.5", "", { "dependencies": { "decimal.js-light": "^2.4.1" } }, "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w=="],
-
- "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="],
-
- "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
-
- "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
-
- "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
-
- "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
-
- "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
-
- "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
-
- "safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="],
-
- "safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="],
-
- "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="],
-
- "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
-
- "schema-dts": ["schema-dts@1.1.5", "", {}, "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg=="],
-
- "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
-
- "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
-
- "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="],
-
- "set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="],
-
- "sharp": ["sharp@0.34.2", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.4", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.2", "@img/sharp-darwin-x64": "0.34.2", "@img/sharp-libvips-darwin-arm64": "1.1.0", "@img/sharp-libvips-darwin-x64": "1.1.0", "@img/sharp-libvips-linux-arm": "1.1.0", "@img/sharp-libvips-linux-arm64": "1.1.0", "@img/sharp-libvips-linux-ppc64": "1.1.0", "@img/sharp-libvips-linux-s390x": "1.1.0", "@img/sharp-libvips-linux-x64": "1.1.0", "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", "@img/sharp-libvips-linuxmusl-x64": "1.1.0", "@img/sharp-linux-arm": "0.34.2", "@img/sharp-linux-arm64": "0.34.2", "@img/sharp-linux-s390x": "0.34.2", "@img/sharp-linux-x64": "0.34.2", "@img/sharp-linuxmusl-arm64": "0.34.2", "@img/sharp-linuxmusl-x64": "0.34.2", "@img/sharp-wasm32": "0.34.2", "@img/sharp-win32-arm64": "0.34.2", "@img/sharp-win32-ia32": "0.34.2", "@img/sharp-win32-x64": "0.34.2" } }, "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg=="],
-
- "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
-
- "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
-
- "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
-
- "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
-
- "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
-
- "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
-
- "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
-
- "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="],
-
- "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
-
- "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
-
- "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
-
- "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
-
- "sqlkit": ["sqlkit@1.0.13", "", {}, "sha512-BMq83FUAWH07DvdfMRnlzq3byQezVub0EGd2XZiB4zdfaICCqRSRk5f3uvlnWF91iHe+TUmU/9No3HgOIU9/rw=="],
-
- "stable-hash": ["stable-hash@0.0.5", "", {}, "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA=="],
-
- "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="],
-
- "streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="],
-
- "string.prototype.includes": ["string.prototype.includes@2.0.1", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3" } }, "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg=="],
-
- "string.prototype.matchall": ["string.prototype.matchall@4.0.12", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="],
-
- "string.prototype.repeat": ["string.prototype.repeat@1.0.0", "", { "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w=="],
-
- "string.prototype.trim": ["string.prototype.trim@1.2.10", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="],
-
- "string.prototype.trimend": ["string.prototype.trimend@1.0.9", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ=="],
-
- "string.prototype.trimstart": ["string.prototype.trimstart@1.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg=="],
-
- "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
-
- "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
-
- "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
-
- "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
-
- "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
-
- "tailwind-merge": ["tailwind-merge@3.3.0", "", {}, "sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ=="],
-
- "tailwindcss": ["tailwindcss@4.1.8", "", {}, "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og=="],
-
- "tapable": ["tapable@2.2.2", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="],
-
- "tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="],
-
- "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
-
- "tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
-
- "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
-
- "ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
-
- "tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
-
- "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
-
- "tsx": ["tsx@4.19.4", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q=="],
-
- "tw-animate-css": ["tw-animate-css@1.3.4", "", {}, "sha512-dd1Ht6/YQHcNbq0znIT6dG8uhO7Ce+VIIhZUhjsryXsMPJQz3bZg7Q2eNzLwipb25bRZslGb2myio5mScd1TFg=="],
-
- "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
-
- "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
-
- "typed-array-byte-length": ["typed-array-byte-length@1.0.3", "", { "dependencies": { "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.14" } }, "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg=="],
-
- "typed-array-byte-offset": ["typed-array-byte-offset@1.0.4", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "for-each": "^0.3.3", "gopd": "^1.2.0", "has-proto": "^1.2.0", "is-typed-array": "^1.1.15", "reflect.getprototypeof": "^1.0.9" } }, "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ=="],
-
- "typed-array-length": ["typed-array-length@1.0.7", "", { "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", "is-typed-array": "^1.1.13", "possible-typed-array-names": "^1.0.0", "reflect.getprototypeof": "^1.0.6" } }, "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg=="],
-
- "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
-
- "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
-
- "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
-
- "unrs-resolver": ["unrs-resolver@1.7.13", "", { "dependencies": { "napi-postinstall": "^0.2.2" }, "optionalDependencies": { "@unrs/resolver-binding-darwin-arm64": "1.7.13", "@unrs/resolver-binding-darwin-x64": "1.7.13", "@unrs/resolver-binding-freebsd-x64": "1.7.13", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.7.13", "@unrs/resolver-binding-linux-arm-musleabihf": "1.7.13", "@unrs/resolver-binding-linux-arm64-gnu": "1.7.13", "@unrs/resolver-binding-linux-arm64-musl": "1.7.13", "@unrs/resolver-binding-linux-ppc64-gnu": "1.7.13", "@unrs/resolver-binding-linux-riscv64-gnu": "1.7.13", "@unrs/resolver-binding-linux-riscv64-musl": "1.7.13", "@unrs/resolver-binding-linux-s390x-gnu": "1.7.13", "@unrs/resolver-binding-linux-x64-gnu": "1.7.13", "@unrs/resolver-binding-linux-x64-musl": "1.7.13", "@unrs/resolver-binding-wasm32-wasi": "1.7.13", "@unrs/resolver-binding-win32-arm64-msvc": "1.7.13", "@unrs/resolver-binding-win32-ia32-msvc": "1.7.13", "@unrs/resolver-binding-win32-x64-msvc": "1.7.13" } }, "sha512-QUjCYKAgrdJpf3wA73zWjOrO7ra19lfnwQ8HRkNOLah5AVDqOS38UunnyhzsSL8AE+2/AGnAHxlr8cGshCP35A=="],
-
- "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
-
- "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
-
- "use-immer": ["use-immer@0.11.0", "", { "peerDependencies": { "immer": ">=8.0.0", "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0" } }, "sha512-RNAqi3GqsWJ4bcCd4LMBgdzvPmTABam24DUaFiKfX9s3MSorNRz9RDZYJkllJoMHUxVLMDetwAuCDeyWNrp1yA=="],
-
- "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
-
- "use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
-
- "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
-
- "victory-vendor": ["victory-vendor@36.9.2", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ=="],
-
- "which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="],
-
- "which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="],
-
- "which-builtin-type": ["which-builtin-type@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.1.0", "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", "which-typed-array": "^1.1.16" } }, "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q=="],
-
- "which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="],
-
- "which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="],
-
- "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
-
- "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
-
- "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
-
- "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
-
- "zod": ["zod@3.25.57", "", {}, "sha512-6tgzLuwVST5oLUxXTmBqoinKMd3JeesgbgseXeFasKKj8Q1FCZrHnbqJOyiEvr4cVAlbug+CgIsmJ8cl/pU5FA=="],
-
- "@cloudinary/html/@types/node": ["@types/node@14.18.63", "", {}, "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ=="],
-
- "@cloudinary/html/typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="],
-
- "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="],
-
- "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
-
- "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
-
- "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="],
-
- "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="],
-
- "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA=="],
-
- "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.9.0" }, "bundled": true }, "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA=="],
-
- "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
-
- "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
-
- "@tailwindcss/typography/postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
-
- "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
-
- "@typescript-eslint/typescript-estree/fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
-
- "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
-
- "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
-
- "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
-
- "eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
-
- "eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
-
- "eslint-plugin-import/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
-
- "eslint-plugin-react/resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
-
- "eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
-
- "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
-
- "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
-
- "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
-
- "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
-
- "tsx/esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.18.20", "", { "os": "android", "cpu": "arm64" }, "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.18.20", "", { "os": "android", "cpu": "x64" }, "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.18.20", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.18.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.18.20", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.18.20", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.18.20", "", { "os": "linux", "cpu": "arm" }, "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.18.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.18.20", "", { "os": "linux", "cpu": "ia32" }, "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.18.20", "", { "os": "linux", "cpu": "ppc64" }, "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.18.20", "", { "os": "linux", "cpu": "none" }, "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.18.20", "", { "os": "linux", "cpu": "s390x" }, "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.18.20", "", { "os": "linux", "cpu": "x64" }, "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.18.20", "", { "os": "none", "cpu": "x64" }, "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.18.20", "", { "os": "openbsd", "cpu": "x64" }, "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.18.20", "", { "os": "sunos", "cpu": "x64" }, "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.18.20", "", { "os": "win32", "cpu": "arm64" }, "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.18.20", "", { "os": "win32", "cpu": "ia32" }, "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g=="],
-
- "@esbuild-kit/core-utils/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.18.20", "", { "os": "win32", "cpu": "x64" }, "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ=="],
-
- "@typescript-eslint/typescript-estree/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
-
- "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
-
- "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
-
- "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA=="],
-
- "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="],
-
- "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.5", "", { "os": "android", "cpu": "arm64" }, "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg=="],
-
- "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="],
-
- "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ=="],
-
- "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="],
-
- "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw=="],
-
- "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="],
-
- "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="],
-
- "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg=="],
-
- "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="],
-
- "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="],
-
- "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg=="],
-
- "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="],
-
- "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA=="],
-
- "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="],
-
- "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.5", "", { "os": "linux", "cpu": "x64" }, "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw=="],
-
- "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.5", "", { "os": "none", "cpu": "x64" }, "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ=="],
-
- "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg=="],
-
- "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="],
-
- "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw=="],
-
- "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="],
-
- "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="],
- }
-}
diff --git a/docs/PRD.md b/docs/PRD.md
new file mode 100644
index 0000000..2d791bc
--- /dev/null
+++ b/docs/PRD.md
@@ -0,0 +1,364 @@
+# Product Requirements Document: TechDiary
+
+**Version:** 1.0
+**Date:** December 2024
+**Status:** Active Development
+
+## Executive Summary
+
+TechDiary is a modern blogging platform designed specifically for the tech community, enabling developers, engineers, and tech enthusiasts to share knowledge, experiences, and insights through articles, while fostering engagement through reactions, comments, and bookmarking.
+
+## 1. Product Overview
+
+### 1.1 Vision Statement
+To create the premier destination for tech professionals to document their journey, share knowledge, and build a supportive community around technology and software development.
+
+### 1.2 Mission Statement
+Empower developers and tech enthusiasts with a platform that makes it easy to write, discover, and engage with high-quality technical content while building meaningful professional connections.
+
+### 1.3 Problem Statement
+- **Knowledge Fragmentation**: Technical knowledge is scattered across multiple platforms with varying quality
+- **Engagement Barriers**: Existing platforms lack intuitive ways to show appreciation and bookmark content
+- **Community Building**: Limited tools for building professional relationships within the tech community
+- **Content Discovery**: Difficulty finding relevant, high-quality technical content
+- **Internationalization**: Limited support for non-English speaking tech communities
+
+### 1.4 Solution Overview
+TechDiary provides a focused, feature-rich blogging platform with:
+- Intuitive markdown-based writing experience
+- Rich engagement features (reactions, comments, bookmarks)
+- Powerful search and content discovery
+- Multi-language support (English/Bengali)
+- Professional networking capabilities
+
+## 2. Business Objectives
+
+### 2.1 Primary Goals
+1. **User Growth**: Achieve 10,000+ registered users within 12 months
+2. **Content Quality**: Maintain high-quality technical content with average 5+ minute read time
+3. **Engagement**: Achieve 70%+ user engagement rate (reactions, comments, bookmarks)
+4. **Community Building**: Foster active community with 500+ regular contributors
+5. **Global Reach**: Support multiple languages starting with Bengali and English
+
+### 2.2 Success Metrics
+- **User Acquisition**: 1,000+ new registrations per month
+- **Content Creation**: 500+ articles published monthly
+- **User Engagement**: 3+ interactions per user session
+- **Retention**: 60%+ monthly active user retention
+- **Content Quality**: 4.5+ average article rating
+- **Search Performance**: <2 second search response time
+
+## 3. Target Users
+
+### 3.1 Primary Personas
+
+#### Persona 1: The Tech Blogger
+- **Profile**: Software developers, engineers, tech leads
+- **Goals**: Share knowledge, build personal brand, document learning journey
+- **Pain Points**: Complex publishing tools, limited audience reach
+- **Behaviors**: Writes 2-4 articles per month, engages with community content
+
+#### Persona 2: The Knowledge Seeker
+- **Profile**: Junior developers, students, career changers
+- **Goals**: Learn new technologies, find solutions, stay updated
+- **Pain Points**: Information overload, outdated content, language barriers
+- **Behaviors**: Reads 10-15 articles per week, bookmarks content, asks questions
+
+#### Persona 3: The Community Builder
+- **Profile**: Tech mentors, team leads, developer advocates
+- **Goals**: Foster learning, support community growth, share expertise
+- **Pain Points**: Limited engagement tools, difficulty tracking impact
+- **Behaviors**: Actively comments, shares content, mentors through articles
+
+### 3.2 Secondary Personas
+- **Tech Companies**: Looking to showcase expertise and attract talent
+- **Educators**: Sharing curriculum and educational content
+- **Open Source Contributors**: Documenting projects and tutorials
+
+## 4. Core Features
+
+### 4.1 Content Creation & Management
+
+#### 4.1.1 Article Editor
+- **Rich Markdown Editor**: Full-featured markdown editor with live preview
+- **Auto-save**: Automatic saving every 30 seconds to prevent data loss
+- **Draft Management**: Save and manage multiple drafts
+- **Media Upload**: Drag-and-drop image upload with cropping capabilities
+- **Series Support**: Organize related articles into series
+- **Publishing Controls**: Draft/publish toggle with scheduling options
+
+#### 4.1.2 Content Organization
+- **Tagging System**: Flexible tagging for content categorization
+- **Series Management**: Group related articles into logical sequences
+- **Cover Images**: Custom cover images with aspect ratio optimization
+- **SEO Optimization**: Meta descriptions, structured data, sitemap generation
+
+### 4.2 User Authentication & Profiles
+
+#### 4.2.1 Authentication
+- **GitHub OAuth**: Primary authentication method for developers
+- **Session Management**: Secure session handling with automatic renewal
+- **Account Security**: Secure password requirements and account protection
+
+#### 4.2.2 User Profiles
+- **Profile Customization**: Avatar, bio, location, education, social links
+- **Professional Information**: GitHub, LinkedIn, personal website links
+- **Achievement System**: Badges for contributions and engagement
+- **Reading History**: Track and display reading activity
+
+### 4.3 Content Discovery & Search
+
+#### 4.3.1 Search System
+- **Full-text Search**: Powered by MeilSearch for fast, relevant results
+- **Filter Options**: Search by tags, authors, date ranges, content type
+- **Search Suggestions**: Auto-complete and suggested searches
+- **Search Analytics**: Track popular searches and content gaps
+
+#### 4.3.2 Content Feeds
+- **Personalized Feed**: Algorithm-based content recommendations
+- **Following Feed**: Content from followed authors
+- **Tag-based Feeds**: Content filtered by preferred tags
+- **Trending Content**: Popular and trending articles
+
+### 4.4 Engagement Features
+
+#### 4.4.1 Reaction System
+- **Emoji Reactions**: Love, Fire, Wow, Haha, Cry, Unicorn reactions
+- **Real-time Updates**: Immediate feedback with optimistic UI updates
+- **Reaction Analytics**: Track popular content types and engagement patterns
+
+#### 4.4.2 Comment System
+- **Nested Comments**: Threaded discussions with reply functionality
+- **Comment Reactions**: React to individual comments
+- **Moderation Tools**: Report and moderate inappropriate content
+- **Notification System**: Alert users to comment activity
+
+#### 4.4.3 Bookmarking
+- **Save for Later**: Bookmark articles for future reading
+- **Bookmark Organization**: Categorize and organize saved content
+- **Reading Lists**: Create custom reading lists
+- **Export Options**: Export bookmarks for external use
+
+### 4.5 Social Features
+
+#### 4.5.1 Following System
+- **Author Following**: Follow favorite authors for content updates
+- **Follower Management**: Manage followers and following lists
+- **Activity Feed**: See activity from followed users
+- **Recommendations**: Suggest authors based on reading patterns
+
+#### 4.5.2 Community Features
+- **User Discovery**: Find and connect with other users
+- **Author Profiles**: Detailed author pages with content history
+- **Social Sharing**: Share articles on external social platforms
+- **Networking**: Professional networking within the platform
+
+### 4.6 Internationalization
+
+#### 4.6.1 Multi-language Support
+- **Bengali Support**: Full Bengali language interface and content
+- **Language Toggle**: Easy switching between English and Bengali
+- **Localized Content**: Date formatting, number formatting, cultural adaptations
+- **RTL Support**: Right-to-left text support for applicable languages
+
+## 5. Technical Requirements
+
+### 5.1 Platform Requirements
+- **Web Application**: Responsive design for desktop and mobile
+- **Modern Browsers**: Support for Chrome, Firefox, Safari, Edge
+- **Mobile Optimization**: Touch-friendly interface for mobile devices
+- **Progressive Web App**: PWA capabilities for mobile app-like experience
+
+### 5.2 Performance Requirements
+- **Page Load Speed**: <3 seconds initial page load
+- **Search Response**: <500ms search result display
+- **Image Loading**: Lazy loading with optimized formats (WebP, AVIF)
+- **Uptime**: 99.9% availability target
+
+### 5.3 Security Requirements
+- **Data Protection**: GDPR compliance and user data protection
+- **Secure Authentication**: OAuth 2.0 with secure session management
+- **Content Security**: XSS protection and input sanitization
+- **API Security**: Rate limiting and authentication for all endpoints
+
+### 5.4 Scalability Requirements
+- **User Capacity**: Support for 100,000+ registered users
+- **Content Volume**: Handle 10,000+ articles with efficient search
+- **Concurrent Users**: Support 1,000+ simultaneous active users
+- **Global CDN**: Fast content delivery worldwide
+
+## 6. User Experience Requirements
+
+### 6.1 Design Principles
+- **Simplicity**: Clean, uncluttered interface focused on content
+- **Accessibility**: WCAG 2.1 AA compliance for inclusive design
+- **Consistency**: Unified design language across all features
+- **Performance**: Fast, responsive interactions with minimal loading
+
+### 6.2 User Interface Requirements
+- **Dark/Light Mode**: Theme switching for user preference
+- **Responsive Design**: Seamless experience across all device sizes
+- **Typography**: Optimized reading experience with proper font choices
+- **Visual Hierarchy**: Clear information architecture and navigation
+
+### 6.3 User Journey Optimization
+- **Onboarding**: Smooth registration and profile setup process
+- **Content Discovery**: Intuitive search and browsing experience
+- **Writing Experience**: Distraction-free, powerful writing environment
+- **Engagement**: Natural, rewarding interaction patterns
+
+## 7. Content Strategy
+
+### 7.1 Content Types
+- **Technical Tutorials**: Step-by-step guides and how-tos
+- **Experience Sharing**: Personal journey and lesson learned articles
+- **Technology Reviews**: Analysis and comparison of tools and frameworks
+- **Open Source**: Project documentation and contribution guides
+- **Career Development**: Professional growth and industry insights
+
+### 7.2 Content Quality Standards
+- **Original Content**: Emphasis on original, valuable insights
+- **Technical Accuracy**: Fact-checking and technical review processes
+- **Writing Quality**: Clear, well-structured, engaging writing
+- **Code Examples**: Working, tested code snippets and examples
+- **Regular Updates**: Encourage updating content to maintain relevance
+
+### 7.3 Content Moderation
+- **Community Guidelines**: Clear rules for acceptable content
+- **Reporting System**: Easy-to-use content reporting tools
+- **Moderation Queue**: Review system for flagged content
+- **Appeal Process**: Fair process for content disputes
+
+## 8. Monetization Strategy
+
+### 8.1 Revenue Streams (Future)
+- **Premium Subscriptions**: Advanced features for power users
+- **Sponsored Content**: Tasteful, relevant sponsored articles
+- **Job Board**: Tech job listings and company profiles
+- **Pro Tools**: Advanced analytics and writing tools
+- **Training Content**: Premium courses and workshops
+
+### 8.2 Community-First Approach
+- **Free Core Features**: Keep essential features free forever
+- **Value-Added Services**: Charge only for premium enhancements
+- **Transparent Pricing**: Clear, honest pricing with no hidden fees
+- **Community Benefits**: Revenue sharing with top contributors
+
+## 9. Development Roadmap
+
+### 9.1 Phase 1: MVP (Months 1-3)
+- ✅ Core authentication (GitHub OAuth)
+- ✅ Basic article creation and editing
+- ✅ User profiles and basic settings
+- ✅ Article discovery and search
+- ✅ Basic reactions and bookmarking
+
+### 9.2 Phase 2: Community Features (Months 4-6)
+- ✅ Comment system with threading
+- 🔄 Following/follower system
+- ✅ Enhanced search with filtering
+- 🔄 Series support for content organization
+- ✅ Multi-language support (Bengali)
+
+### 9.3 Phase 3: Engagement & Growth (Months 7-9)
+- 🔄 Advanced user profiles with achievements (Badges)
+- 🔄 Notification system
+- 📋 Content recommendations algorithm
+- 📋 Mobile app (PWA)
+- 📋 API for third-party integrations
+
+### 9.4 Phase 4: Monetization & Scale (Months 10-12)
+- 📋 Premium subscription features
+- 📋 Advanced analytics dashboard
+- 📋 Content collaboration tools
+- 📋 Enterprise features
+- 📋 Mobile native apps
+
+## 10. Risk Assessment
+
+### 10.1 Technical Risks
+- **Scalability Challenges**: Database performance under high load
+- **Search Performance**: Maintaining fast search with growing content
+- **Security Vulnerabilities**: User data protection and content security
+- **Third-party Dependencies**: GitHub OAuth and external service reliability
+
+### 10.2 Business Risks
+- **Competition**: Existing platforms like Dev.to, Medium, Hashnode
+- **User Acquisition**: Difficulty in building initial user base
+- **Content Quality**: Maintaining high standards as platform grows
+- **Monetization Balance**: Avoiding over-commercialization
+
+### 10.3 Mitigation Strategies
+- **Technical**: Robust testing, performance monitoring, security audits
+- **Business**: Community-first approach, unique value proposition, gradual feature rollout
+- **User Experience**: Continuous user feedback and iterative improvement
+- **Content**: Clear guidelines, moderation tools, quality incentives
+
+## 11. Success Metrics & KPIs
+
+### 11.1 User Metrics
+- **Monthly Active Users (MAU)**: Target 50,000+ in Year 1
+- **Daily Active Users (DAU)**: Target 15,000+ in Year 1
+- **User Retention**: 60%+ monthly retention rate
+- **User Growth Rate**: 20%+ month-over-month growth
+
+### 11.2 Engagement Metrics
+- **Articles per User**: Average 3+ articles per active user
+- **Engagement Rate**: 70%+ users interact with content
+- **Session Duration**: Average 8+ minutes per session
+- **Content Interaction**: 5+ reactions/comments per article
+
+### 11.3 Content Metrics
+- **Content Volume**: 1,000+ new articles monthly
+- **Content Quality**: 4.5+ average rating
+- **Search Success**: 80%+ search queries result in engagement
+- **Content Sharing**: 30%+ articles shared externally
+
+### 11.4 Technical Metrics
+- **Page Load Speed**: <2 seconds average load time
+- **Search Performance**: <500ms average search response
+- **Uptime**: 99.9%+ platform availability
+- **Error Rate**: <0.1% application error rate
+
+## 12. Competitive Analysis
+
+### 12.1 Direct Competitors
+
+#### Dev.to
+- **Strengths**: Large community, good SEO, simple interface
+- **Weaknesses**: Limited customization, basic engagement features
+- **Differentiation**: Better engagement tools, multi-language support
+
+#### Hashnode
+- **Strengths**: Developer-focused, good performance, custom domains
+- **Weaknesses**: Limited social features, complex setup
+- **Differentiation**: Simpler onboarding, stronger community features
+
+#### Medium
+- **Strengths**: Large audience, good discovery, established platform
+- **Weaknesses**: Not tech-focused, paywall issues, limited customization
+- **Differentiation**: Tech-specific features, free access, better tools
+
+### 12.2 Competitive Advantages
+- **Developer-First Design**: Built by developers for developers
+- **Multi-language Support**: Serving non-English tech communities
+- **Rich Engagement**: Advanced reaction and interaction systems
+- **Modern Technology**: Fast, responsive, accessible platform
+- **Community Focus**: Community-driven features and development
+
+## 13. Conclusion
+
+TechDiary represents a significant opportunity to create a developer-focused blogging platform that addresses key gaps in the current market. With its emphasis on community engagement, technical excellence, and inclusive design, TechDiary is positioned to become the go-to platform for tech professionals to share knowledge and build meaningful connections.
+
+The roadmap balances ambitious feature development with pragmatic execution, ensuring sustainable growth while maintaining focus on user value and community building. Success will be measured not just in user numbers, but in the quality of content, strength of community, and positive impact on the global tech ecosystem.
+
+---
+
+**Document Prepared By:** TechDiary Team
+**Next Review Date:** Q1 2025
+**Stakeholders:** Product Team, Engineering Team, Community Managers
+
+Legend:
+✅ Completed
+🔄 In Progress
+📋 Planned
diff --git a/docs/components/AppImage.md b/docs/components/AppImage.md
new file mode 100644
index 0000000..724acf7
--- /dev/null
+++ b/docs/components/AppImage.md
@@ -0,0 +1,313 @@
+# AppImage Component
+
+A wrapper component around Next.js Image that provides Cloudinary integration with automatic optimization and blur placeholders.
+
+## Location
+`src/components/AppImage.tsx`
+
+## Overview
+AppImage is an optimized image component that handles Cloudinary transformations, automatic format selection, quality optimization, and blur placeholders for better user experience.
+
+## Props
+
+```typescript
+interface AppImageProps {
+ alt?: string;
+ sizes?: string;
+ width?: number | `${number}` | undefined;
+ height?: number | `${number}` | undefined;
+ imageSource?: IServerFile;
+}
+```
+
+### Props Details
+- `alt`: Alternative text for accessibility
+- `sizes`: Responsive image sizes (Next.js Image prop)
+- `width`: Image width (Next.js Image prop)
+- `height`: Image height (Next.js Image prop)
+- `imageSource`: Server file object containing provider and key information
+
+## IServerFile Interface
+```typescript
+interface IServerFile {
+ provider: "cloudinary" | "r2" | string;
+ key: string;
+}
+```
+
+## Usage Examples
+
+### Basic Usage
+```typescript
+import AppImage from '@/components/AppImage';
+
+function ArticleCover() {
+ const imageSource = {
+ provider: "cloudinary",
+ key: "articles/my-article-cover"
+ };
+
+ return (
+
+ );
+}
+```
+
+### With Different Providers
+```typescript
+// Cloudinary image
+const cloudinaryImage = {
+ provider: "cloudinary",
+ key: "profile-photos/user-avatar"
+};
+
+// R2/Other provider image
+const r2Image = {
+ provider: "r2",
+ key: "https://example.com/image.jpg"
+};
+
+return (
+
+);
+```
+
+### Responsive Image Grid
+```typescript
+function ImageGallery({ images }: { images: IServerFile[] }) {
+ return (
+
+ {images.map((image, index) => (
+
+ ))}
+
+ );
+}
+```
+
+## Features
+
+### Cloudinary Integration
+- **Automatic format**: Selects optimal format (WebP, AVIF, etc.)
+- **Quality optimization**: Auto quality based on content
+- **URL generation**: Constructs optimized Cloudinary URLs
+- **Blur placeholder**: Generates blurred version for loading states
+
+### Performance Optimizations
+- **Lazy loading**: Images load only when needed
+- **Responsive sizing**: Proper sizes attribute for responsive images
+- **Format selection**: Automatic modern format selection
+- **Quality adjustment**: Optimal quality for file size balance
+
+### Fallback Handling
+- **Provider fallback**: Handles non-Cloudinary providers
+- **Default placeholder**: Falls back to local placeholder image
+- **Error handling**: Graceful degradation for missing images
+
+## Cloudinary Transformations
+
+### Applied Automatically
+```typescript
+// Quality optimization
+.quality("auto")
+
+// Format optimization
+.format("auto")
+
+// Blur placeholder
+.effect(blur(100000))
+```
+
+### Generated URLs
+```typescript
+// Original image
+"https://res.cloudinary.com/techdiary-dev/image/upload/q_auto,f_auto/v1/path/to/image"
+
+// Blur placeholder
+"https://res.cloudinary.com/techdiary-dev/image/upload/q_auto,f_auto,e_blur:100000/v1/path/to/image"
+```
+
+## Provider Support
+
+### Cloudinary Provider
+- Full transformation support
+- Automatic optimization
+- Blur placeholder generation
+- Format and quality selection
+
+### Other Providers (R2, Direct URLs)
+- Direct URL passthrough
+- Default placeholder image
+- No transformations applied
+- Basic Next.js Image functionality
+
+## Implementation Details
+
+### Cloudinary Setup
+```typescript
+const cld = new Cloudinary({
+ cloud: { cloudName: "techdiary-dev" },
+});
+```
+
+### URL Construction
+```typescript
+// Main image URL
+const imageUrl = cld
+ .image(imageSource.key)
+ .quality("auto")
+ .format("auto")
+ .toURL();
+
+// Blur placeholder URL
+const blurUrl = cld
+ .image(imageSource.key)
+ .quality("auto")
+ .format("auto")
+ .effect(blur(100000))
+ .toURL();
+```
+
+## Best Practices
+
+### Sizing and Responsive
+```typescript
+// Provide proper dimensions
+
+
+// Use aspect ratio classes for responsive design
+
+```
+
+### Accessibility
+```typescript
+// Always provide meaningful alt text
+
+
+// Use empty alt for decorative images
+
+```
+
+### Performance
+```typescript
+// Use appropriate sizes for responsive images
+sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
+
+// Preload important images
+
+```
+
+## Common Use Cases
+
+### Article Cover Images
+```typescript
+function ArticleCover({ coverImage }: { coverImage: IServerFile }) {
+ return (
+
+ );
+}
+```
+
+### User Avatars
+```typescript
+function Avatar({ profilePhoto, userName }: {
+ profilePhoto: IServerFile;
+ userName: string;
+}) {
+ return (
+
+ );
+}
+```
+
+### Image Galleries
+```typescript
+function Gallery({ images }: { images: IServerFile[] }) {
+ return (
+
+ {images.map((image, index) => (
+
+ ))}
+
+ );
+}
+```
+
+## Error Handling
+
+The component gracefully handles:
+- Missing imageSource prop
+- Invalid Cloudinary keys
+- Network errors
+- Unsupported image formats
+
+## Environment Configuration
+
+Ensure Cloudinary is properly configured:
+```typescript
+// Environment variables
+NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=techdiary-dev
+CLOUDINARY_API_KEY=your_api_key
+CLOUDINARY_API_SECRET=your_api_secret
+```
+
+## Related Components
+
+- **ImageDropzoneWithCropper**: For image uploads with editing
+- **Next.js Image**: Base component being wrapped
+- **Cloudinary SDK**: For URL generation and transformations
\ No newline at end of file
diff --git a/docs/components/ArticleCard.md b/docs/components/ArticleCard.md
new file mode 100644
index 0000000..4203201
--- /dev/null
+++ b/docs/components/ArticleCard.md
@@ -0,0 +1,213 @@
+# ArticleCard Component
+
+A reusable card component for displaying article information in feeds and lists.
+
+## Location
+`src/components/ArticleCard.tsx`
+
+## Overview
+The ArticleCard component displays a preview of an article with author information, cover image, metadata, and interaction buttons. It includes hover effects and user profile previews.
+
+## Props
+
+```typescript
+interface ArticleCardProps {
+ id: string;
+ title: string;
+ handle: string;
+ excerpt: string;
+ coverImage?: string;
+ author: {
+ id: string;
+ name: string;
+ avatar: string;
+ username: string;
+ };
+ publishedAt: string;
+ readingTime: number;
+}
+```
+
+### Required Props
+- `id`: Unique article identifier
+- `title`: Article title
+- `handle`: URL-friendly article identifier
+- `excerpt`: Brief article summary
+- `author`: Author information object
+- `publishedAt`: Publication date (ISO string)
+- `readingTime`: Estimated reading time in minutes
+
+### Optional Props
+- `coverImage`: URL to article cover image
+
+## Usage Example
+
+```typescript
+import ArticleCard from '@/components/ArticleCard';
+
+function ArticleFeed() {
+ const articles = [
+ {
+ id: "1",
+ title: "Getting Started with React Hooks",
+ handle: "getting-started-react-hooks",
+ excerpt: "Learn the fundamentals of React Hooks and how to use them effectively in your applications.",
+ coverImage: "https://example.com/cover.jpg",
+ author: {
+ id: "user1",
+ name: "John Doe",
+ avatar: "https://example.com/avatar.jpg",
+ username: "johndoe"
+ },
+ publishedAt: "2024-01-15T10:00:00Z",
+ readingTime: 5
+ }
+ ];
+
+ return (
+
+ {articles.map(article => (
+
+ ))}
+
+ );
+}
+```
+
+## Features
+
+### Author Information Display
+- Author avatar with hover card preview
+- Author name linked to profile
+- Publication date (localized)
+- Reading time estimate
+
+### Content Preview
+- Article title with hover effects
+- Excerpt with "Read more" link
+- Optional cover image with aspect ratio 16:9
+
+### User Interactions
+- **Reactions**: Emoji-based reactions (like, love, etc.)
+- **Bookmarking**: Save article for later reading
+- **Authentication**: Login prompt for unauthenticated users
+
+### Responsive Design
+- Mobile-optimized layout
+- Smooth hover transitions
+- Adaptive spacing and typography
+
+## Dependencies
+
+### Hooks Used
+- `useTranslation`: For internationalization
+- `useSession`: For user authentication state
+- `useLoginPopup`: For authentication prompts
+
+### Child Components
+- `UserInformationCard`: Author profile preview
+- `ResourceReaction`: Article reaction system
+- `ResourceBookmark`: Bookmark functionality
+- `HoverCard`: Author info hover preview
+
+## Styling Classes
+
+The component uses Tailwind CSS classes for styling:
+- Container: `flex flex-col p-4 sm:p-5 group`
+- Author section: Flex layout with avatar and metadata
+- Title: `text-lg font-bold` with hover effects
+- Cover image: `aspect-[16/9]` with responsive sizing
+
+## Internationalization
+
+The component supports multiple languages:
+- Reading time text is localized
+- Date formatting respects language preference
+- All interactive elements use translated text
+
+## Performance Optimizations
+
+- **Memoized URL**: Article URL is memoized to prevent recalculation
+- **Optimized images**: Uses Next.js Image component with proper sizing
+- **Hover delays**: HoverCard has optimized delay for better UX
+
+## Accessibility Features
+
+- Semantic HTML structure
+- Proper alt text for images
+- Keyboard navigation support
+- Screen reader friendly markup
+- Time elements with proper datetime attributes
+
+## Data Flow
+
+1. Article data passed as props
+2. User authentication checked via session
+3. Internationalization applied to dates/text
+4. User interactions handled through child components
+5. Navigation handled via Next.js Link components
+
+## Common Use Cases
+
+### Article Feeds
+```typescript
+function Homepage() {
+ return (
+
+ {articles.map(article => (
+
+ ))}
+
+ );
+}
+```
+
+### Search Results
+```typescript
+function SearchResults({ results }: { results: Article[] }) {
+ return (
+
+ {results.map(article => (
+
+ ))}
+
+ );
+}
+```
+
+### User Profile Articles
+```typescript
+function UserArticles({ userId }: { userId: string }) {
+ const { data: articles } = useUserArticles(userId);
+
+ return (
+
+ {articles?.map(article => (
+
+ ))}
+
+ );
+}
+```
+
+## Customization
+
+The component can be customized through:
+- CSS classes for styling overrides
+- Props for different data structures
+- Child component replacement for different functionality
+
+## Related Components
+
+- **UserInformationCard**: Displays detailed user information
+- **ResourceReaction**: Handles article reactions
+- **ResourceBookmark**: Manages article bookmarking
+- **AppImage**: Optimized image handling
+
+## Best Practices
+
+1. **Data validation**: Ensure all required props are provided
+2. **Error handling**: Handle missing images or data gracefully
+3. **Performance**: Use proper keys when rendering lists
+4. **Accessibility**: Provide meaningful alt text and ARIA labels
+5. **Responsive**: Test on various screen sizes
\ No newline at end of file
diff --git a/docs/components/ArticleEditor.md b/docs/components/ArticleEditor.md
new file mode 100644
index 0000000..61e5a0a
--- /dev/null
+++ b/docs/components/ArticleEditor.md
@@ -0,0 +1,383 @@
+# ArticleEditor Component
+
+A comprehensive markdown editor for creating and editing articles with real-time preview, auto-save, and rich formatting tools.
+
+## Location
+`src/components/Editor/ArticleEditor.tsx`
+
+## Overview
+ArticleEditor is a full-featured article editing interface that provides markdown editing capabilities, real-time preview, auto-save functionality, and article management features.
+
+## Props
+
+```typescript
+interface ArticleEditorProps {
+ uuid?: string;
+ article?: Article;
+}
+```
+
+### Props Details
+- `uuid`: Unique identifier for existing article (for editing mode)
+- `article`: Article data object (for editing existing articles)
+
+## Usage Examples
+
+### Creating New Article
+```typescript
+import ArticleEditor from '@/components/Editor/ArticleEditor';
+
+function NewArticlePage() {
+ return (
+
+ );
+}
+```
+
+### Editing Existing Article
+```typescript
+function EditArticlePage({ articleId }: { articleId: string }) {
+ const { data: article } = useQuery({
+ queryKey: ['article', articleId],
+ queryFn: () => fetchArticle(articleId)
+ });
+
+ if (!article) return Loading...
;
+
+ return (
+
+ );
+}
+```
+
+## Key Features
+
+### Real-time Editing
+- **Auto-save**: Automatically saves changes after 1 second of inactivity
+- **Debounced updates**: Prevents excessive API calls during typing
+- **Live status**: Shows saving status and last saved time
+- **Form validation**: Uses Zod schema validation
+
+### Editor Modes
+- **Write mode**: Markdown editing with toolbar
+- **Preview mode**: Rendered markdown preview
+- **Toggle switch**: Easy switching between modes
+
+### Markdown Toolbar
+- **Heading**: Insert H2 headings
+- **Bold**: Bold text formatting
+- **Italic**: Italic text formatting
+- **Image**: Insert image markdown
+
+### Article Management
+- **Publish/Unpublish**: Toggle article publication status
+- **Draft indication**: Visual status indicators
+- **Settings drawer**: Additional article configuration
+- **Navigation**: Back to dashboard
+
+## Component Structure
+
+### Form Management
+```typescript
+const editorForm = useForm({
+ defaultValues: {
+ title: article?.title || "",
+ body: article?.body || "",
+ },
+ resolver: zodResolver(ArticleRepositoryInput.updateArticleInput),
+});
+```
+
+### Auto-save Implementation
+```typescript
+// Title auto-save (1 second delay)
+const setDebouncedTitle = useDebouncedCallback(
+ handleDebouncedSaveTitle,
+ 1000
+);
+
+// Body auto-save (1 second delay)
+const setDebouncedBody = useDebouncedCallback(
+ handleDebouncedSaveBody,
+ 1000
+);
+```
+
+### Markdown Editor Integration
+```typescript
+const editor = useMarkdownEditor({
+ ref: bodyRef,
+ onChange: handleBodyContentChange,
+});
+```
+
+## Hooks Used
+
+### Custom Hooks
+- `useTranslation`: Internationalization
+- `useToggle`: Modal and drawer state management
+- `useAutosizeTextArea`: Auto-resizing title input
+- `useDebouncedCallback`: Auto-save functionality
+- `useMarkdownEditor`: Markdown formatting commands
+- `useAppConfirm`: Confirmation dialogs
+
+### React Query
+- `useMutation`: Article creation and updates
+- Optimistic updates and error handling
+
+## Auto-save Behavior
+
+### Title Auto-save
+- Triggers after 1 second of no typing
+- Creates new article if none exists
+- Updates existing article title
+
+### Body Auto-save
+- Triggers after 1 second of no typing
+- Creates article with default title if new
+- Updates existing article content
+
+### Save Status Display
+```typescript
+{updateMyArticleMutation.isPending ? (
+ {_t("Saving")}...
+) : (
+ article?.updated_at && (
+
+ ({_t("Saved")} {formattedTime(article.updated_at, lang)})
+
+ )
+)}
+```
+
+## Editor Toolbar
+
+### Available Commands
+```typescript
+// Heading command
+editor?.executeCommand("heading")
+
+// Bold formatting
+editor?.executeCommand("bold")
+
+// Italic formatting
+editor?.executeCommand("italic")
+
+// Image insertion
+editor?.executeCommand("image")
+```
+
+### Toolbar Rendering
+```typescript
+const renderEditorToolbar = () => (
+
+ editor?.executeCommand("heading")}
+ Icon={ }
+ />
+ editor?.executeCommand("bold")}
+ Icon={ }
+ />
+ {/* ... more buttons */}
+
+);
+```
+
+## Preview Mode
+
+### Markdown Rendering
+```typescript
+{editorMode === "write" ? (
+
+) : (
+
+ {markdocParser(watchedBody ?? "")}
+
+)}
+```
+
+## Article Management Features
+
+### Publish Toggle
+```typescript
+const handlePublishToggle = useCallback(() => {
+ appConfig.show({
+ title: _t("Are you sure?"),
+ onConfirm: () => {
+ updateMyArticleMutation.mutate({
+ article_id: uuid,
+ is_published: !article?.is_published,
+ });
+ },
+ });
+}, [/* dependencies */]);
+```
+
+### Status Indicators
+```typescript
+
+ {article?.is_published ? (
+ {_t("Published")}
+ ) : (
+ {_t("Draft")}
+ )}
+
+```
+
+## Responsive Design
+
+### Mobile Optimizations
+- Hidden preview/publish buttons on mobile
+- Responsive toolbar layout
+- Touch-friendly interface
+- Adaptive spacing and sizing
+
+### Desktop Features
+- Full toolbar visibility
+- Preview mode toggle
+- Publish/unpublish controls
+- Settings access
+
+## Performance Optimizations
+
+### Debounced Operations
+- Title and body changes debounced to 1 second
+- Prevents excessive API calls
+- Maintains smooth editing experience
+
+### Memoized Callbacks
+- Event handlers memoized with useCallback
+- Dependency arrays optimized
+- Prevents unnecessary re-renders
+
+### Form Optimization
+- React Hook Form for efficient form management
+- Minimal re-renders on value changes
+- Proper validation integration
+
+## Error Handling
+
+### Mutation Error Handling
+```typescript
+onError: (err) => {
+ console.error("Error creating article:", err);
+ alert(
+ err instanceof Error
+ ? err.message
+ : "Failed to create article. Please try again."
+ );
+}
+```
+
+### Navigation Safety
+- Confirmation dialogs for destructive actions
+- Auto-save prevents data loss
+- Proper error state management
+
+## Internationalization
+
+The component supports multiple languages:
+- All UI text is translatable
+- Date formatting respects locale
+- Error messages are localized
+- Placeholder text is translated
+
+## Integration with Other Components
+
+### Child Components
+- **ArticleEditorDrawer**: Article settings and metadata
+- **EditorCommandButton**: Toolbar button component
+- **useMarkdownEditor**: Markdown editing functionality
+
+### External Dependencies
+- **markdocParser**: Markdown to HTML conversion
+- **React Hook Form**: Form state management
+- **Zod**: Input validation
+- **TanStack Query**: Server state management
+
+## Best Practices
+
+### Data Management
+```typescript
+// Always handle loading states
+if (isLoading) return ;
+
+// Proper error boundaries
+if (error) return ;
+
+// Optimistic updates for better UX
+onMutate: (variables) => {
+ // Optimistically update UI
+}
+```
+
+### User Experience
+```typescript
+// Prevent data loss with auto-save
+const setDebouncedBody = useDebouncedCallback(saveContent, 1000);
+
+// Provide visual feedback
+{isSaving && Saving...
}
+
+// Confirm destructive actions
+appConfirm.show({
+ title: "Are you sure?",
+ onConfirm: performAction
+});
+```
+
+## Common Use Cases
+
+### Blog Post Creation
+```typescript
+function CreateBlogPost() {
+ return (
+
+
+
+ );
+}
+```
+
+### Article Editing Workflow
+```typescript
+function EditWorkflow({ articleId }: { articleId: string }) {
+ const { data: article, isLoading } = useArticle(articleId);
+
+ if (isLoading) return ;
+
+ return (
+
+ );
+}
+```
+
+### Draft Management
+```typescript
+function DraftEditor({ draftId }: { draftId: string }) {
+ const { data: draft } = useDraft(draftId);
+
+ return (
+
+ );
+}
+```
\ No newline at end of file
diff --git a/docs/components/ImageDropzoneWithCropper.md b/docs/components/ImageDropzoneWithCropper.md
new file mode 100644
index 0000000..7589823
--- /dev/null
+++ b/docs/components/ImageDropzoneWithCropper.md
@@ -0,0 +1,414 @@
+# ImageDropzoneWithCropper Component
+
+A comprehensive image upload component with drag-and-drop support, cropping functionality, and cloud storage integration.
+
+## Location
+`src/components/ImageDropzoneWithCropper.tsx`
+
+## Overview
+ImageDropzoneWithCropper provides a complete image upload solution with drag-and-drop interface, image cropping capabilities, file management, and integration with cloud storage services.
+
+## Props
+
+```typescript
+interface DropzoneWithCropperProps {
+ prefillFile?: IServerFile | null;
+ disabled?: boolean;
+ label?: string;
+ Icon?: React.ReactNode;
+ enableCropper?: boolean;
+ uploadDirectory?: DIRECTORY_NAME;
+ uploadUniqueFileName?: boolean;
+ onUploadComplete?: (serverFile: IServerFile) => void;
+ onFileDeleteComplete?: () => void;
+ aspectRatio?: number;
+}
+```
+
+### Props Details
+- `prefillFile`: Pre-existing file to display
+- `disabled`: Disable upload functionality
+- `label`: Custom dropzone label text
+- `Icon`: Custom upload icon
+- `enableCropper`: Enable image cropping modal
+- `uploadDirectory`: Target upload directory
+- `uploadUniqueFileName`: Generate unique filenames
+- `onUploadComplete`: Callback when upload succeeds
+- `onFileDeleteComplete`: Callback when file is deleted
+- `aspectRatio`: Crop aspect ratio (default: 1)
+
+## Usage Examples
+
+### Basic Image Upload
+```typescript
+import ImageDropzoneWithCropper from '@/components/ImageDropzoneWithCropper';
+import { DIRECTORY_NAME } from '@/backend/models/domain-models';
+
+function ProfilePhotoUpload() {
+ const handleUploadComplete = (file: IServerFile) => {
+ console.log('Upload completed:', file);
+ // Update user profile photo
+ };
+
+ return (
+
+ );
+}
+```
+
+### Image Upload with Cropping
+```typescript
+function ArticleCoverUpload() {
+ const [coverImage, setCoverImage] = useState(null);
+
+ return (
+ setCoverImage(null)}
+ label="Upload article cover"
+ />
+ );
+}
+```
+
+### Gallery Upload
+```typescript
+function GalleryImageUpload() {
+ const [images, setImages] = useState([]);
+
+ const handleUpload = (file: IServerFile) => {
+ setImages(prev => [...prev, file]);
+ };
+
+ return (
+
+
+ {images.map((image, index) => (
+ {
+ setImages(prev => prev.filter((_, i) => i !== index));
+ }}
+ />
+ ))}
+
+ );
+}
+```
+
+## Features
+
+### Drag and Drop Interface
+- **Visual feedback**: Highlighting on drag over
+- **File validation**: Accepts only image files
+- **Error states**: Visual indication of rejected files
+- **Accessibility**: Keyboard navigation support
+
+### Image Cropping
+- **Advanced cropper**: Uses react-advanced-cropper library
+- **Aspect ratio control**: Configurable aspect ratios
+- **Image manipulation**: Flip, rotate, and crop operations
+- **Grid overlay**: Visual crop guidelines
+- **Real-time preview**: Live crop preview
+
+### File Management
+- **Upload progress**: Loading states during upload
+- **Delete functionality**: Remove uploaded files
+- **File preview**: Display uploaded images
+- **Error handling**: Upload failure management
+
+## Cropper Features
+
+### Image Transformations
+```typescript
+// Horizontal flip
+const flip = (horizontal: boolean, vertical: boolean) => {
+ cropperRef.current?.flipImage(horizontal, vertical);
+};
+
+// Rotation (90-degree increments)
+const rotate = (angle: number) => {
+ cropperRef.current?.rotateImage(angle);
+};
+```
+
+### Crop Controls
+- **Flip horizontal**: Mirror image horizontally
+- **Flip vertical**: Mirror image vertically
+- **Rotate 90°**: Rotate image clockwise
+- **Aspect ratio**: Maintain consistent proportions
+- **Grid overlay**: Visual cropping guides
+
+## Upload Process
+
+### Without Cropping
+1. User drops/selects image
+2. File validation
+3. Direct upload to storage
+4. Callback with file information
+
+### With Cropping
+1. User drops/selects image
+2. Convert to base64 for preview
+3. Open cropping modal
+4. User adjusts crop/rotation
+5. Generate cropped blob
+6. Upload processed image
+7. Callback with file information
+
+## File Storage Integration
+
+### Supported Providers
+```typescript
+// R2 (Cloudflare)
+{
+ provider: "r2",
+ key: "unique-filename.jpg"
+}
+
+// Directory-based organization
+uploadDirectory: DIRECTORY_NAME.PROFILE_PHOTOS
+// Results in: "profile-photos/unique-filename.jpg"
+```
+
+### Upload Configuration
+```typescript
+uploadFile({
+ files: [file],
+ directory: DIRECTORY_NAME.ARTICLE_IMAGES,
+ generateUniqueFileName: true
+})
+```
+
+## Hooks Used
+
+### Custom Hooks
+- `useServerFile`: File upload/delete operations
+- `useToggle`: Modal state management
+
+### React Hooks
+- `useRef`: Cropper instance reference
+- `useState`: Base64 image state
+
+## Component States
+
+### Empty State (No File)
+```typescript
+// Dropzone with upload prompt
+
+```
+
+### Uploading State
+```typescript
+// Loading indicator during upload
+{uploading && (
+
+)}
+```
+
+### Uploaded State (With File)
+```typescript
+// Display uploaded image with delete option
+
+
+
+
+
+
+```
+
+## Cropping Modal
+
+### Modal Structure
+```typescript
+
+
+
+
+ {/* Flip and rotate buttons */}
+ Upload
+
+
+
+```
+
+### Processing Pipeline
+1. Get canvas from cropper
+2. Convert canvas to blob
+3. Upload blob to storage
+4. Return file information
+5. Close modal
+
+## Styling and Layout
+
+### Dropzone Styling
+```typescript
+// Dynamic classes based on state
+className={clsx(
+ "grid w-full h-full p-4 border border-dotted rounded-md",
+ {
+ "bg-green-100": isFileDialogActive,
+ "bg-primary": isDragReject,
+ "cursor-not-allowed": disabled,
+ }
+)}
+```
+
+### Responsive Design
+- Adaptive aspect ratios
+- Mobile-friendly touch controls
+- Responsive modal sizing
+- Optimized for various screen sizes
+
+## Error Handling
+
+### Upload Errors
+```typescript
+.catch((err) => {
+ console.log(err);
+ alert("Error uploading file");
+});
+```
+
+### File Validation
+- Image-only file acceptance
+- File size limitations (via dropzone config)
+- MIME type validation
+- Error state visual feedback
+
+## Accessibility Features
+
+- **Keyboard navigation**: Full keyboard support
+- **Screen reader support**: Proper ARIA labels
+- **Focus management**: Logical tab order
+- **Error announcements**: Screen reader error feedback
+
+## Performance Optimizations
+
+### Image Processing
+- **Client-side cropping**: Reduces server load
+- **Blob conversion**: Efficient binary handling
+- **Canvas optimization**: Memory-efficient processing
+
+### Upload Optimization
+- **Unique filenames**: Prevents conflicts
+- **Directory organization**: Structured storage
+- **Progress indication**: User feedback during upload
+
+## Common Use Cases
+
+### Profile Photo Upload
+```typescript
+ updateUserProfile({ photo: file })}
+/>
+```
+
+### Article Cover Images
+```typescript
+ setArticleCover(file)}
+ label="Upload article cover (16:9 ratio)"
+/>
+```
+
+### Product Images
+```typescript
+
+```
+
+## Dependencies
+
+### External Libraries
+- `react-dropzone`: Drag and drop functionality
+- `react-advanced-cropper`: Image cropping capabilities
+- `lucide-react`: Icons for UI elements
+
+### Internal Dependencies
+- `useServerFile`: Upload/delete functionality
+- `useToggle`: Modal state management
+- `getFileUrl`: File URL generation utility
+
+## Best Practices
+
+### File Management
+```typescript
+// Always handle upload completion
+onUploadComplete={(file) => {
+ // Update application state
+ setImageFile(file);
+ // Show success message
+ showSuccess("Image uploaded successfully");
+}}
+
+// Handle deletion properly
+onFileDeleteComplete={() => {
+ // Clear application state
+ setImageFile(null);
+ // Show confirmation
+ showInfo("Image deleted");
+}}
+```
+
+### User Experience
+```typescript
+// Provide clear labels
+label="Drop your profile photo here or click to browse"
+
+// Use appropriate aspect ratios
+aspectRatio={16/9} // For covers
+aspectRatio={1} // For avatars
+aspectRatio={4/3} // For general images
+
+// Enable cropping for precise control
+enableCropper={true}
+```
+
+### Error Handling
+```typescript
+// Validate files before upload
+accept={{ "image/*": [".jpeg", ".jpg", ".png", ".webp"] }}
+
+// Handle network errors gracefully
+.catch((error) => {
+ showError("Upload failed. Please try again.");
+ console.error("Upload error:", error);
+});
+```
\ No newline at end of file
diff --git a/docs/components/README.md b/docs/components/README.md
new file mode 100644
index 0000000..7437489
--- /dev/null
+++ b/docs/components/README.md
@@ -0,0 +1,627 @@
+# Custom Components Documentation
+
+This directory contains comprehensive documentation for all custom React components used in the TechDiary application (excluding shadcn/ui components).
+
+## Overview
+
+Custom components are reusable UI elements that encapsulate specific functionality and design patterns. They provide consistent interfaces, behavior, and styling throughout the application.
+
+## Available Custom Components
+
+### Core Content Components
+- **[ArticleCard](./ArticleCard.md)** - Article preview cards for feeds and lists
+- **[ArticleEditor](./ArticleEditor.md)** - Comprehensive markdown editor with auto-save
+- **[UserInformationCard](./UserInformationCard.md)** - User profile display with interactions
+
+### Media and Upload Components
+- **[AppImage](./AppImage.md)** - Optimized image component with Cloudinary integration
+- **[ImageDropzoneWithCropper](./ImageDropzoneWithCropper.md)** - File upload with cropping capabilities
+
+### Interactive Components
+- **[ResourceReaction](./ResourceReaction.md)** - Emoji reaction system for articles and comments (UI implementation of ResourceReactionable)
+- **[ResourceBookmark](./ResourceBookmark.md)** - Bookmark button for articles and comments (UI implementation of ResourceBookmarkable)
+
+### Render Props Components
+- **[ResourceReactionable](./ResourceReactionable.md)** - Render prop for reaction functionality with optimistic updates
+- **[ResourceBookmarkable](./ResourceBookmarkable.md)** - Render prop for bookmark functionality with state management
+
+### Navigation Components
+- **Navbar** - Main application navigation with search and user actions
+- **ThemeSwitcher** - Dark/light theme toggle component
+- **LanguageSwitcher** - Bengali/English language toggle
+
+### Layout Components
+- **BaseLayout** - Base application layout wrapper
+- **HomepageLayout** - Homepage-specific layout structure
+
+### Provider Components
+- **CommonProviders** - Application-wide context providers
+- **SessionProvider** - User session management
+- **I18nProvider** - Internationalization context
+
+### Widget Components
+- **DiscordWidget** - Discord community integration
+- **SocialLinksWidget** - Social media links display
+- **LatestUsers** - Recent user registrations display
+- **ImportantLinksWidget** - Curated links section
+
+## Component Categories
+
+### UI Components (Main Interface)
+Components that form the primary user interface:
+- ArticleCard, ArticleEditor, UserInformationCard
+- Navbar, navigation components
+- Layout wrappers and providers
+
+### Media Components
+Components handling images and file uploads:
+- AppImage with Cloudinary optimization
+- ImageDropzoneWithCropper for uploads
+- File management utilities
+
+### Interactive Components
+Components providing user interactions:
+- ResourceReaction for emoji reactions (UI implementation of ResourceReactionable)
+- ResourceBookmark for saving content (UI implementation of ResourceBookmarkable)
+- Comment system components
+
+### Render Props Components
+Components that provide data and logic via render props pattern:
+- ResourceReactionable for reaction functionality
+- ResourceBookmarkable for bookmark functionality
+- Flexible UI rendering with complete control
+
+### Utility Components
+Helper components for specific functions:
+- VisibilitySensor for scroll detection
+- Toast notifications
+- Social login cards
+- Icon components
+
+## Quick Reference
+
+| Component | Purpose | Key Features |
+|-----------|---------|--------------|
+| `ArticleCard` | Article preview | Author info, reactions, bookmarking |
+| `ArticleEditor` | Content creation | Markdown editing, auto-save, preview |
+| `AppImage` | Optimized images | Cloudinary integration, lazy loading |
+| `ImageDropzoneWithCropper` | File uploads | Drag-and-drop, cropping, cloud storage |
+| `UserInformationCard` | User profiles | Bio, social info, follow/edit actions |
+| `ResourceReaction` | Emoji reactions UI | Pre-built UI using ResourceReactionable |
+| `ResourceBookmark` | Bookmark button UI | Pre-built UI using ResourceBookmarkable |
+| `ResourceReactionable` | Reaction logic | Render props, optimistic updates, auth |
+| `ResourceBookmarkable` | Bookmark logic | Render props, state sync, optimistic UI |
+
+## Common Patterns
+
+### 1. Props Interface Pattern
+```typescript
+interface ComponentProps {
+ // Required props
+ id: string;
+ title: string;
+
+ // Optional props with defaults
+ variant?: "primary" | "secondary";
+ disabled?: boolean;
+
+ // Callback functions
+ onAction?: (data: any) => void;
+
+ // Children and composition
+ children?: React.ReactNode;
+}
+```
+
+### 2. Hooks Integration Pattern
+```typescript
+function CustomComponent() {
+ // Translation and i18n
+ const { _t } = useTranslation();
+
+ // Authentication
+ const session = useSession();
+
+ // UI state management
+ const [isOpen, { toggle, close }] = useToggle();
+
+ // API integration
+ const { data, isLoading } = useQuery({...});
+
+ return (/* JSX */);
+}
+```
+
+### 3. Conditional Rendering Pattern
+```typescript
+// Loading states
+if (isLoading) return ;
+
+// Error states
+if (error) return ;
+
+// Authentication-based rendering
+{session ? (
+
+) : (
+
+)}
+
+// Feature flags and permissions
+{hasPermission && }
+```
+
+### 4. Event Handling Pattern
+```typescript
+const handleAction = useCallback((event: Event) => {
+ // Prevent defaults
+ event.preventDefault();
+
+ // Validation
+ if (!isValid) return;
+
+ // Business logic
+ performAction();
+
+ // Callbacks
+ onAction?.(result);
+}, [dependencies]);
+```
+
+### 5. Render Props Pattern
+```typescript
+// Render props component for reusable logic
+function DataProvider({ render, ...props }) {
+ const [data, setData] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ // Data fetching logic
+ useEffect(() => {
+ fetchData().then(setData).finally(() => setLoading(false));
+ }, []);
+
+ return render({ data, loading, refetch: fetchData });
+}
+
+// Usage with complete UI control
+ (
+ loading ? :
+ )}
+/>
+
+// Render props for resource interactions
+ (
+
+ {reactions.map(reaction => (
+ toggle(reaction.type)}>
+ {reaction.emoji} {reaction.count}
+
+ ))}
+
+ )}
+/>
+```
+
+## Styling Conventions
+
+### Tailwind CSS Usage
+```typescript
+// Container patterns
+"flex items-center justify-between"
+"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
+"max-w-4xl mx-auto p-4"
+
+// Interactive states
+"hover:bg-primary/20 transition-colors duration-200"
+"focus:outline-none focus:ring-2 focus:ring-primary"
+"disabled:opacity-50 disabled:cursor-not-allowed"
+
+// Responsive design
+"hidden md:block"
+"text-sm md:text-base"
+"p-2 md:p-4"
+```
+
+### Component Styling Structure
+```typescript
+// Base classes
+const baseClasses = "component-base-styles";
+
+// Variant classes
+const variantClasses = {
+ primary: "primary-variant-styles",
+ secondary: "secondary-variant-styles"
+};
+
+// State classes
+const stateClasses = clsx(baseClasses, {
+ [variantClasses[variant]]: variant,
+ "active-state": isActive,
+ "disabled-state": disabled
+});
+```
+
+## Data Flow Patterns
+
+### 1. Server State Management (React Query)
+```typescript
+// Data fetching
+const { data, isLoading, error } = useQuery({
+ queryKey: ['resource', resourceId],
+ queryFn: () => fetchResource(resourceId)
+});
+
+// Mutations
+const mutation = useMutation({
+ mutationFn: updateResource,
+ onSuccess: () => queryClient.invalidateQueries(['resource'])
+});
+```
+
+### 2. Client State Management (Jotai)
+```typescript
+// Global atoms
+const [session, setSession] = useAtom(sessionAtom);
+const [theme, setTheme] = useAtom(themeAtom);
+const [language, setLanguage] = useAtom(languageAtom);
+```
+
+### 3. Form State Management (React Hook Form)
+```typescript
+const form = useForm({
+ defaultValues: initialData,
+ resolver: zodResolver(validationSchema)
+});
+
+const onSubmit = form.handleSubmit((data) => {
+ // Handle form submission
+});
+```
+
+## Accessibility Guidelines
+
+### Semantic HTML
+```typescript
+// Use proper semantic elements
+
+
+ {content}
+
+
+
+// Navigation structures
+
+
+
+```
+
+### ARIA Attributes
+```typescript
+// Interactive elements
+
+ Delete
+
+
+// Dynamic content
+
+ {isLoading ? "Loading..." : "Content loaded"}
+
+```
+
+### Focus Management
+```typescript
+// Focus trapping in modals
+const focusRef = useRef(null);
+
+useEffect(() => {
+ if (isOpen && focusRef.current) {
+ focusRef.current.focus();
+ }
+}, [isOpen]);
+
+// Skip links for navigation
+
+ Skip to main content
+
+```
+
+## Performance Best Practices
+
+### Component Optimization
+```typescript
+// Memoization for expensive components
+const ExpensiveComponent = React.memo(({ data }) => {
+ return ;
+});
+
+// Callback memoization
+const handleClick = useCallback((id: string) => {
+ onItemClick(id);
+}, [onItemClick]);
+
+// Value memoization
+const processedData = useMemo(() => {
+ return processLargeDataset(rawData);
+}, [rawData]);
+```
+
+### Loading Strategies
+```typescript
+// Lazy loading for large components
+const HeavyComponent = lazy(() => import('./HeavyComponent'));
+
+// Skeleton loading states
+{isLoading ? (
+
+) : (
+
+)}
+
+// Progressive enhancement
+ }>
+
+
+```
+
+### Image Optimization
+```typescript
+// Proper image sizing
+
+
+// Lazy loading implementation
+loading="lazy"
+placeholder="blur"
+blurDataURL={blurredVersion}
+```
+
+## Testing Strategies
+
+### Component Testing
+```typescript
+// Basic rendering tests
+test('renders component with required props', () => {
+ render( );
+ expect(screen.getByText('Test')).toBeInTheDocument();
+});
+
+// Interaction testing
+test('handles user interactions', async () => {
+ const handleClick = jest.fn();
+ render(Click me );
+
+ await user.click(screen.getByRole('button'));
+ expect(handleClick).toHaveBeenCalled();
+});
+
+// Accessibility testing
+test('is accessible', async () => {
+ const { container } = render( );
+ const results = await axe(container);
+ expect(results).toHaveNoViolations();
+});
+```
+
+### Integration Testing
+```typescript
+// API integration
+test('fetches and displays data', async () => {
+ mockAPI.get('/api/data').mockResolvedValue({ data: testData });
+
+ render( );
+
+ await waitFor(() => {
+ expect(screen.getByText(testData.title)).toBeInTheDocument();
+ });
+});
+```
+
+## Internationalization (i18n)
+
+### Translation Integration
+```typescript
+function Component() {
+ const { _t } = useTranslation();
+
+ return (
+
+
{_t("Welcome to TechDiary")}
+
{_t("User count: $", [userCount])}
+
{_t("Get Started")}
+
+ );
+}
+```
+
+### Language-Aware Formatting
+```typescript
+// Date formatting
+const { lang } = useTranslation();
+const formattedDate = formattedTime(date, lang);
+
+// Number formatting
+const formattedNumber = new Intl.NumberFormat(lang).format(number);
+
+// Currency formatting
+const formattedPrice = new Intl.NumberFormat(lang, {
+ style: 'currency',
+ currency: 'USD'
+}).format(price);
+```
+
+## Error Handling
+
+### Error Boundaries
+```typescript
+class ComponentErrorBoundary extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = { hasError: false };
+ }
+
+ static getDerivedStateFromError(error) {
+ return { hasError: true };
+ }
+
+ componentDidCatch(error, errorInfo) {
+ console.error('Component error:', error, errorInfo);
+ }
+
+ render() {
+ if (this.state.hasError) {
+ return ;
+ }
+ return this.props.children;
+ }
+}
+```
+
+### Graceful Degradation
+```typescript
+// Network error handling
+{error ? (
+
+
Failed to load content
+
Try Again
+
+) : (
+
+)}
+
+// Feature detection
+{supportsFeature ? (
+
+) : (
+
+)}
+```
+
+## Contributing Guidelines
+
+### Creating New Components
+
+1. **Component Structure**
+```typescript
+// ComponentName.tsx
+interface ComponentNameProps {
+ // Define props interface
+}
+
+const ComponentName: React.FC = ({
+ prop1,
+ prop2
+}) => {
+ // Hooks
+ // Event handlers
+ // Render logic
+
+ return (
+ // JSX
+ );
+};
+
+export default ComponentName;
+```
+
+2. **Documentation Template**
+```markdown
+# ComponentName
+
+## Overview
+Brief description of the component's purpose.
+
+## Props
+Interface definition with descriptions.
+
+## Usage Examples
+Practical examples of component usage.
+
+## Features
+Key functionality and capabilities.
+
+## Best Practices
+Usage recommendations and patterns.
+```
+
+3. **Testing Requirements**
+- Unit tests for all props and states
+- Integration tests for user interactions
+- Accessibility tests
+- Visual regression tests (if applicable)
+
+### Code Review Checklist
+
+- [ ] Component follows established patterns
+- [ ] Props interface is properly typed
+- [ ] Accessibility requirements met
+- [ ] Performance optimizations applied
+- [ ] Error handling implemented
+- [ ] Documentation updated
+- [ ] Tests written and passing
+- [ ] Internationalization considered
+
+## Architecture Decisions
+
+### Component Organization
+```
+src/components/
+├── ComponentName.tsx # Main component
+├── ComponentName.test.tsx # Tests
+├── ComponentName.stories.tsx # Storybook stories
+├── hooks/ # Component-specific hooks
+├── utils/ # Component utilities
+└── types/ # Type definitions
+```
+
+### Naming Conventions
+- **Components**: PascalCase (e.g., `ArticleCard`)
+- **Props**: camelCase with descriptive names
+- **Event handlers**: `onAction` pattern (e.g., `onUploadComplete`)
+- **Boolean props**: `is` or `has` prefix (e.g., `isLoading`, `hasError`)
+
+### Export Patterns
+```typescript
+// Default export for main component
+export default ComponentName;
+
+// Named exports for types and utilities
+export type { ComponentNameProps };
+export { componentUtility };
+```
+
+## Related Documentation
+
+- [Hooks Documentation](../hooks/README.md) - Custom hooks used in components
+- [Styling Guide](../styling/README.md) - CSS and design system guidelines
+- [API Integration](../api/README.md) - Server state management patterns
+- [Testing Guide](../testing/README.md) - Component testing strategies
+
+## Resources
+
+- [React Documentation](https://react.dev/)
+- [TypeScript Handbook](https://www.typescriptlang.org/docs/)
+- [Tailwind CSS](https://tailwindcss.com/)
+- [React Query](https://tanstack.com/query/latest)
+- [React Hook Form](https://react-hook-form.com/)
+- [Accessibility Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
\ No newline at end of file
diff --git a/docs/components/ResourceBookmark.md b/docs/components/ResourceBookmark.md
new file mode 100644
index 0000000..65868e3
--- /dev/null
+++ b/docs/components/ResourceBookmark.md
@@ -0,0 +1,418 @@
+# ResourceBookmark Component
+
+A pre-built bookmark button component that provides a ready-to-use UI for bookmarking articles and comments.
+
+## Location
+`src/components/ResourceBookmark.tsx`
+
+## Overview
+ResourceBookmark is a UI component that uses ResourceBookmarkable under the hood to provide a consistent bookmark button interface. It includes authentication handling, visual feedback, and responsive design.
+
+## Props
+
+```typescript
+interface ResourceBookmarkProps {
+ resource_type: "ARTICLE" | "COMMENT";
+ resource_id: string;
+}
+```
+
+### Props Details
+- `resource_type`: Type of resource being bookmarked ("ARTICLE" or "COMMENT")
+- `resource_id`: Unique identifier of the resource
+
+## Usage Examples
+
+### Article Bookmark
+```typescript
+import ResourceBookmark from '@/components/ResourceBookmark';
+
+function ArticleCard({ article }) {
+ return (
+
+
{article.title}
+
{article.excerpt}
+
+
+
+
+
+ );
+}
+```
+
+### Comment Bookmark
+```typescript
+function CommentItem({ comment }) {
+ return (
+
+
{comment.content}
+
+
+
+
+
+ );
+}
+```
+
+### In Article Footer
+```typescript
+function ArticleFooter({ articleId }) {
+ return (
+
+ );
+}
+```
+
+## Features
+
+### Visual Design
+- **Bookmark Icon**: SVG bookmark icon with stroke and fill states
+- **Visual Feedback**: Different appearance for bookmarked vs unbookmarked states
+- **Hover Effects**: Smooth hover transitions with background highlight
+- **Responsive**: Touch-friendly size and spacing
+
+### User Interaction
+- **Click to Toggle**: Single click to bookmark/unbookmark
+- **Authentication Check**: Automatic login prompt for unauthenticated users
+- **Immediate Feedback**: Optimistic UI updates via ResourceBookmarkable
+- **State Persistence**: Bookmark state persists across sessions
+
+### Visual States
+
+#### Unbookmarked State
+```typescript
+// Stroke-only bookmark icon
+className="size-5 stroke-2 fill-transparent !stroke-current"
+// Light background on hover
+className="hover:bg-primary/20"
+```
+
+#### Bookmarked State
+```typescript
+// Filled bookmark icon
+className="size-5 stroke-2 !fill-current"
+// Highlighted background
+className="bg-primary/20"
+```
+
+## Implementation Details
+
+### Uses ResourceBookmarkable
+```typescript
+ (
+ // UI implementation
+ )}
+/>
+```
+
+### Authentication Integration
+```typescript
+onClick={() => {
+ if (!session?.user) {
+ loginPopup.show(); // Show login popup
+ return;
+ }
+ toggle(); // Proceed with bookmark toggle
+}}
+```
+
+### Styling Classes
+```typescript
+// Base button styles
+"transition-colors duration-300 flex cursor-pointer px-2 py-1 rounded-sm hover:bg-primary/20"
+
+// Conditional background highlight
+{ "bg-primary/20": bookmarked }
+
+// Icon conditional styling
+{
+ "!stroke-current": !bookmarked,
+ "!fill-current": bookmarked,
+}
+```
+
+## Component Structure
+
+### Button Container
+- Padding: `px-2 py-1` for comfortable click area
+- Rounded corners: `rounded-sm`
+- Hover effect: `hover:bg-primary/20`
+- Transition: `transition-colors duration-300`
+
+### SVG Icon
+- Size: `size-5` (20px × 20px)
+- Stroke width: `stroke-2`
+- Conditional fill based on bookmark state
+- Accessible stroke and fill properties
+
+## Authentication Flow
+
+1. **User clicks bookmark button**
+2. **Authentication check**: Component checks if user is logged in
+3. **If not authenticated**: Shows login popup via `useLoginPopup`
+4. **If authenticated**: Proceeds with bookmark toggle
+5. **UI updates**: Immediate visual feedback via optimistic updates
+6. **Server sync**: ResourceBookmarkable handles server communication
+
+## Accessibility Features
+
+### Semantic HTML
+- Proper `button` element for interaction
+- Keyboard navigation support
+- Focus management
+
+### Visual Accessibility
+- High contrast icon states
+- Clear visual feedback for state changes
+- Consistent sizing and spacing
+- Touch-friendly interaction area
+
+### Screen Reader Support
+```typescript
+// Recommended enhancement
+
+
+
+```
+
+## Integration with Other Components
+
+### With ArticleCard
+```typescript
+function ArticleCard({ article }) {
+ return (
+
+
+ {/* Article content */}
+
+
+
+
+
+
+
+ );
+}
+```
+
+### With Comment System
+```typescript
+function CommentActions({ commentId }) {
+ return (
+
+
+
+
+
+ );
+}
+```
+
+## Customization
+
+### Custom Styling
+```typescript
+// Wrap with custom styles
+
+
+
+
+// Override with CSS
+.custom-bookmark-wrapper button {
+ background: custom-bg;
+ border-radius: custom-radius;
+}
+```
+
+### Alternative Implementation
+If you need different styling, use ResourceBookmarkable directly:
+
+```typescript
+ (
+
+ {bookmarked ? 'Bookmarked ★' : 'Bookmark ☆'}
+
+ )}
+/>
+```
+
+## Performance Characteristics
+
+### Optimizations
+- **Optimistic Updates**: Immediate UI feedback via ResourceBookmarkable
+- **Efficient Re-renders**: Minimal re-renders through proper state management
+- **Cached Queries**: ResourceBookmarkable handles query caching
+- **Lightweight**: Small bundle size with SVG icons
+
+### Bundle Impact
+- Minimal JavaScript overhead
+- Inline SVG (no external icon dependencies)
+- Leverages existing authentication and state management
+
+## Common Use Cases
+
+### Article Feeds
+```typescript
+function ArticleFeed({ articles }) {
+ return (
+
+ {articles.map(article => (
+
+ {article.title}
+ {article.excerpt}
+
+
+
+
+ ))}
+
+ );
+}
+```
+
+### Reading Lists
+```typescript
+function ReadingListItem({ article }) {
+ return (
+
+
+
{article.title}
+
{article.author}
+
+
+
+ );
+}
+```
+
+### Comment Threads
+```typescript
+function CommentThread({ comments }) {
+ return (
+
+ {comments.map(comment => (
+
+
{comment.content}
+
+ {comment.author}
+
+
+
+ ))}
+
+ );
+}
+```
+
+## Related Components
+
+- **[ResourceBookmarkable](./ResourceBookmarkable.md)**: The underlying render prop component
+- **[ResourceReaction](./ResourceReaction.md)**: Companion reaction component
+- **[ArticleCard](./ArticleCard.md)**: Common usage context
+- **useLoginPopup**: Authentication integration
+- **useSession**: User session management
+
+## Best Practices
+
+### Usage Guidelines
+```typescript
+// Always provide both props
+
+
+// Group with related actions
+
+
+
+
+
+
+// Consider accessibility
+
+
+
+```
+
+### Error Handling
+```typescript
+// Wrap in error boundary for production
+Bookmark unavailable}>
+
+
+```
+
+### Performance
+```typescript
+// Use React.memo for lists
+const MemoizedBookmark = React.memo(ResourceBookmark);
+
+// In large lists
+{articles.map(article => (
+
+
+
+))}
+```
\ No newline at end of file
diff --git a/docs/components/ResourceBookmarkable.md b/docs/components/ResourceBookmarkable.md
new file mode 100644
index 0000000..58d1bee
--- /dev/null
+++ b/docs/components/ResourceBookmarkable.md
@@ -0,0 +1,576 @@
+# ResourceBookmarkable Component
+
+A render-prop component that provides bookmark functionality for articles and comments with optimistic updates and state management.
+
+## Location
+`src/components/render-props/ResourceBookmarkable.tsx`
+
+## Overview
+ResourceBookmarkable is a render-prop component that encapsulates all the logic for handling bookmarking of resources (articles or comments). It provides data fetching, optimistic updates, state synchronization, and error handling while allowing complete flexibility in how the bookmark UI is rendered.
+
+## Props
+
+```typescript
+interface Props {
+ resource_type: "ARTICLE" | "COMMENT";
+ resource_id: string;
+ render: ({
+ toggle,
+ bookmarked,
+ }: {
+ toggle: () => void;
+ bookmarked: boolean;
+ }) => React.ReactNode;
+}
+```
+
+### Props Details
+- `resource_type`: Type of resource being bookmarked ("ARTICLE" or "COMMENT")
+- `resource_id`: Unique identifier of the resource
+- `render`: Function that receives bookmark state and toggle function, returns JSX
+
+## Render Function Parameters
+
+### Provided Data and Functions
+```typescript
+{
+ toggle: () => void;
+ bookmarked: boolean;
+}
+```
+
+- `toggle`: Function to toggle bookmark state on/off
+- `bookmarked`: Current bookmark status (true if bookmarked, false if not)
+
+## Usage Examples
+
+### Basic Bookmark Button
+```typescript
+import { ResourceBookmarkable } from '@/components/render-props/ResourceBookmarkable';
+
+function SimpleBookmarkButton({ articleId }) {
+ return (
+ (
+
+ {bookmarked ? 'Remove Bookmark' : 'Add Bookmark'}
+
+ )}
+ />
+ );
+}
+```
+
+### Icon-based Bookmark Toggle
+```typescript
+import { BookmarkIcon, BookmarkFilledIcon } from '@/components/icons';
+
+function IconBookmarkButton({ commentId }) {
+ return (
+ (
+
+ {bookmarked ? (
+
+ ) : (
+
+ )}
+
+ )}
+ />
+ );
+}
+```
+
+### Advanced Bookmark UI with Status
+```typescript
+function DetailedBookmarkButton({ articleId }) {
+ return (
+ (
+
+
+
+
+ {bookmarked ? 'Bookmarked' : 'Bookmark'}
+
+
+
+ {bookmarked && (
+
+ Saved to your reading list
+
+ )}
+
+ )}
+ />
+ );
+}
+```
+
+### Integration with Article Cards
+```typescript
+// How ResourceBookmark component uses ResourceBookmarkable
+function ResourceBookmark({ resource_type, resource_id }) {
+ return (
+ (
+
+
+
+ )}
+ />
+ );
+}
+```
+
+### Bulk Bookmark Actions
+```typescript
+function BookmarkableArticleList({ articles }) {
+ return (
+
+ {articles.map(article => (
+
+
{article.title}
+
{article.excerpt}
+
+
+
(
+
+
+ {bookmarked ? '★ Bookmarked' : '☆ Bookmark'}
+
+
+ {bookmarked && (
+
+ ✓ Saved
+
+ )}
+
+ )}
+ />
+
+
+ ))}
+
+ );
+}
+```
+
+## Key Features
+
+### State Management
+- **Local State**: Uses React `useState` for immediate UI feedback
+- **Server Sync**: Synchronizes with server state via React Query
+- **Optimistic Updates**: Immediate UI response before server confirmation
+- **Error Recovery**: Automatic state correction on server response
+
+### Data Flow
+```typescript
+// Query for fetching bookmark status
+const status = useQuery({
+ queryKey: ["bookmark-status", resource_id],
+ queryFn: () => bookmarkAction.bookmarkStatus({ resource_id, resource_type }),
+ enabled: Boolean(resource_id) && Boolean(resource_type),
+});
+
+// Mutation for toggling bookmark
+const mutation = useMutation({
+ mutationFn: () =>
+ bookmarkAction.toggleResourceBookmark({ resource_id, resource_type }),
+ onSuccess: (data) => {
+ setBookmarked(data?.bookmarked ?? false);
+ },
+});
+```
+
+### Optimistic Updates Implementation
+```typescript
+const toggle = () => {
+ setBookmarked((state) => !state); // Immediate UI update
+ mutation.mutate(); // Server update
+};
+
+// Server response reconciliation
+useEffect(() => {
+ if (status.data) {
+ setBookmarked(status.data.bookmarked ?? false);
+ }
+}, [status.data]);
+```
+
+## State Synchronization
+
+### Initial State Loading
+```typescript
+useEffect(() => {
+ if (status.data) {
+ setBookmarked(status.data.bookmarked ?? false);
+ }
+}, [status.data]);
+```
+
+### Server Response Handling
+```typescript
+onSuccess: (data) => {
+ setBookmarked(data?.bookmarked ?? false);
+}
+```
+
+### Query Configuration
+```typescript
+const status = useQuery({
+ queryKey: ["bookmark-status", resource_id],
+ queryFn: () => bookmarkAction.bookmarkStatus({ resource_id, resource_type }),
+ enabled: Boolean(resource_id) && Boolean(resource_type), // Only fetch when props are valid
+});
+```
+
+## Performance Optimizations
+
+### Conditional Queries
+- Only fetches bookmark status when resource_id and resource_type are provided
+- Prevents unnecessary API calls during component mounting
+
+### Efficient State Updates
+- Local state provides immediate feedback
+- Server state ensures consistency
+- Minimal re-renders through proper state management
+
+### Query Key Strategy
+```typescript
+queryKey: ["bookmark-status", resource_id]
+```
+- Efficient caching per resource
+- Automatic cache invalidation
+- Background refetching when needed
+
+## Common Patterns
+
+### Simple Toggle
+```typescript
+ (
+
+ {bookmarked ? '💙' : '🤍'}
+
+ )}
+/>
+```
+
+### Loading State Handling
+```typescript
+ (
+
+ {bookmarked ? 'Bookmarked ✓' : 'Bookmark'}
+
+ )}
+/>
+```
+
+### Conditional Rendering
+```typescript
+ (
+
+
+ {bookmarked ? 'Remove from Reading List' : 'Save for Later'}
+
+
+ {bookmarked && (
+
+ ✓ Added to your reading list
+ navigate('/bookmarks')}>
+ View All Bookmarks
+
+
+ )}
+
+ )}
+/>
+```
+
+### Custom Styling Based on State
+```typescript
+ (
+
+
+
+ {bookmarked ? 'Bookmarked' : 'Bookmark'}
+
+
+ )}
+/>
+```
+
+## Error Handling
+
+### Network Errors
+```typescript
+// Component handles network errors gracefully
+// State remains consistent even if server requests fail
+// Automatic retry on next interaction
+```
+
+### Invalid Props
+```typescript
+// Query is disabled if resource_id or resource_type are missing
+enabled: Boolean(resource_id) && Boolean(resource_type)
+```
+
+### State Inconsistency
+```typescript
+// Server response always wins for final state
+onSuccess: (data) => {
+ setBookmarked(data?.bookmarked ?? false);
+}
+```
+
+## Accessibility Features
+
+### ARIA Labels
+```typescript
+ (
+
+
+
+ )}
+/>
+```
+
+### Keyboard Navigation
+```typescript
+ (
+ {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ toggle();
+ }
+ }}
+ tabIndex={0}
+ >
+ {bookmarked ? 'Bookmarked' : 'Bookmark'}
+
+ )}
+/>
+```
+
+### Screen Reader Support
+```typescript
+ (
+
+
+ 📖
+
+ {bookmarked
+ ? 'Remove this article from your bookmarks'
+ : 'Add this article to your bookmarks'
+ }
+
+
+
+
+ {bookmarked ? 'Article bookmarked' : 'Bookmark removed'}
+
+
+ )}
+/>
+```
+
+## Integration Examples
+
+### With Authentication
+```typescript
+function AuthenticatedBookmark({ articleId }) {
+ const { user } = useSession();
+
+ if (!user) {
+ return (
+ showLogin()}>
+ Login to Bookmark
+
+ );
+ }
+
+ return (
+ (
+
+ {bookmarked ? 'Bookmarked' : 'Bookmark'}
+
+ )}
+ />
+ );
+}
+```
+
+### With Toast Notifications
+```typescript
+function BookmarkWithFeedback({ articleId }) {
+ const { showToast } = useToast();
+
+ return (
+ (
+ {
+ toggle();
+ showToast(
+ bookmarked
+ ? 'Bookmark removed'
+ : 'Article bookmarked!'
+ );
+ }}
+ >
+ {bookmarked ? 'Remove' : 'Bookmark'}
+
+ )}
+ />
+ );
+}
+```
+
+## Best Practices
+
+### Performance Optimization
+```typescript
+// Memoize expensive render functions
+const BookmarkButton = React.memo(({ toggle, bookmarked }) => (
+
+ {bookmarked ? 'Bookmarked' : 'Bookmark'}
+
+));
+
+ (
+
+ )}
+/>
+```
+
+### State Management
+```typescript
+// Use local state for immediate feedback
+// Trust server state for consistency
+// Handle loading states appropriately
+
+ (
+
+ {isLoading ? 'Saving...' : (bookmarked ? 'Bookmarked' : 'Bookmark')}
+
+ )}
+/>
+```
+
+### Error Boundaries
+```typescript
+function BookmarkWithErrorBoundary({ articleId }) {
+ return (
+ Bookmark unavailable}>
+ (
+
+ )}
+ />
+
+ );
+}
+```
+
+## Related Components
+
+- **ResourceBookmark**: Pre-built UI component using ResourceBookmarkable
+- **BookmarkList**: Component for displaying user's bookmarked items
+- **BookmarkPage**: Full page bookmark management interface
+
+## Dependencies
+
+- **React Query**: Data fetching and caching
+- **Backend Services**: Bookmark API actions
+- **React**: State management and effects
\ No newline at end of file
diff --git a/docs/components/ResourceReaction.md b/docs/components/ResourceReaction.md
new file mode 100644
index 0000000..93ace7d
--- /dev/null
+++ b/docs/components/ResourceReaction.md
@@ -0,0 +1,394 @@
+# ResourceReaction Component
+
+A flexible reaction system component that allows users to add emoji reactions to articles and comments.
+
+## Location
+`src/components/ResourceReaction.tsx`
+
+## Overview
+ResourceReaction provides an interactive emoji reaction system for articles and comments. It displays current reactions with counts and allows authenticated users to add/remove reactions through a hover interface.
+
+## Props
+
+```typescript
+interface ResourceReactionProps {
+ resource_type: "ARTICLE" | "COMMENT";
+ resource_id: string;
+}
+```
+
+### Props Details
+- `resource_type`: Type of resource being reacted to ("ARTICLE" or "COMMENT")
+- `resource_id`: Unique identifier of the resource
+
+## Usage Examples
+
+### Article Reactions
+```typescript
+import ResourceReaction from '@/components/ResourceReaction';
+
+function ArticleCard({ article }) {
+ return (
+
+
{article.title}
+
{article.excerpt}
+
+
+
+
+
+ );
+}
+```
+
+### Comment Reactions
+```typescript
+function CommentItem({ comment }) {
+ return (
+
+
{comment.content}
+
+
+
+
+
+ );
+}
+```
+
+### In Article Pages
+```typescript
+function ArticlePage({ article }) {
+ return (
+
+ {article.title}
+
+ {article.content}
+
+
+
+
+ );
+}
+```
+
+## Available Reaction Types
+
+The component supports multiple emoji reactions:
+- **LOVE**: Heart emoji for appreciation
+- **FIRE**: Fire emoji for excitement
+- **WOW**: Wow emoji for amazement
+- **HAHA**: Laugh emoji for humor
+- **CRY**: Cry emoji for sadness
+- **UNICORN**: Unicorn emoji for special content
+
+Each reaction type has a corresponding SVG file in `/public/reactions/`.
+
+## Component Structure
+
+### Render Props Pattern
+```typescript
+ {
+ // Rendering logic
+ }}
+/>
+```
+
+### Active Reactions Display
+```typescript
+{reactions
+ .filter((r) => r.count)
+ .map((reaction) => (
+ toggle(reaction.reaction_type!)}
+ className={`reaction-button ${
+ reaction.is_reacted ? "bg-primary/20" : ""
+ }`}
+ >
+
+ {reaction.count}
+
+ ))}
+```
+
+### Reaction Picker (Hover Interface)
+```typescript
+
+
+
+
+
+
+
+
+ {reactions.map((reaction) => (
+
toggle(reaction.reaction_type!)}
+ className={`reaction-picker-button ${
+ reaction.is_reacted ? "bg-primary/20" : ""
+ }`}
+ >
+
+
+ ))}
+
+
+
+```
+
+## Features
+
+### Interactive Reactions
+- **Click to toggle**: Add or remove reactions
+- **Visual feedback**: Highlighted state for user's reactions
+- **Count display**: Shows reaction counts
+- **Hover interface**: Access to all reaction types
+
+### Conditional Display
+- **Active reactions**: Only shows reactions with counts > 0
+- **Add button**: Appears when not all reactions are visible
+- **User states**: Visual indication of user's reactions
+
+### Authentication Integration
+- Integrates with authentication system
+- Prevents unauthorized reactions
+- Maintains user reaction state
+
+## Styling and States
+
+### Button States
+```typescript
+// Default state
+className="p-1 w-10 h-6 flex items-center gap-1 cursor-pointer rounded-sm hover:bg-primary/20"
+
+// Reacted state (user has reacted)
+className="... bg-primary/20"
+
+// Hover picker button
+className="p-1 border w-10 h-6 flex-none grid place-content-center cursor-pointer rounded-sm hover:bg-primary/20"
+```
+
+### Visual Indicators
+- **Background highlight**: Active reactions have colored background
+- **Hover effects**: Smooth transitions on interaction
+- **Icon sizing**: Consistent 16px (size-4) and 20px (size-5) icons
+- **Spacing**: Proper gap between elements
+
+## Data Flow
+
+### Reaction State Management
+1. `ResourceReactionable` provides reaction data and toggle function
+2. Component filters and displays active reactions
+3. User clicks trigger toggle function
+4. State updates reflect in UI immediately
+5. Backend synchronization handled by render prop
+
+### Authentication Flow
+1. User attempts to react
+2. Authentication status checked
+3. Authenticated users can toggle reactions
+4. Unauthenticated users see login prompt
+
+## Accessibility Features
+
+### Keyboard Navigation
+- Focusable buttons for all interactions
+- Proper tab order through reactions
+- Enter/Space key activation
+
+### Screen Reader Support
+- Descriptive alt text for reaction images
+- Meaningful button labels
+- ARIA attributes for state communication
+
+### Visual Accessibility
+- High contrast hover states
+- Clear visual feedback for interactions
+- Consistent sizing and spacing
+
+## Performance Optimizations
+
+### Efficient Rendering
+- Conditional rendering prevents unnecessary DOM nodes
+- Filter operations minimize rendered elements
+- Hover card lazy loading
+
+### Image Optimization
+- SVG reaction icons for scalability
+- Consistent naming convention
+- Optimized file sizes
+
+## Integration with ResourceReactionable
+
+### Render Props Pattern
+The component uses the render props pattern through `ResourceReactionable`:
+
+```typescript
+// ResourceReactionable provides:
+{
+ reactions: Array<{
+ reaction_type: string;
+ count: number;
+ is_reacted: boolean;
+ }>;
+ toggle: (reactionType: string) => void;
+}
+```
+
+### Data Structure
+```typescript
+interface Reaction {
+ reaction_type: "LOVE" | "FIRE" | "WOW" | "HAHA" | "CRY" | "UNICORN";
+ count: number;
+ is_reacted: boolean;
+}
+```
+
+## Common Use Cases
+
+### Article Engagement
+```typescript
+function ArticleEngagement({ articleId }) {
+ return (
+
+
+
+
+
+ );
+}
+```
+
+### Comment Interactions
+```typescript
+function CommentActions({ commentId }) {
+ return (
+
+
+
+
+ );
+}
+```
+
+### Bulk Content Display
+```typescript
+function ContentFeed({ items }) {
+ return (
+
+ {items.map(item => (
+
+
{item.title}
+
{item.content}
+
+
+ ))}
+
+ );
+}
+```
+
+## Error Handling
+
+### Network Errors
+- Graceful fallback for failed reactions
+- Optimistic updates with rollback on failure
+- User feedback for connection issues
+
+### Invalid States
+- Handles missing reaction data
+- Fallback for unsupported reaction types
+- Proper error boundaries
+
+## Customization Options
+
+### Styling Customization
+```typescript
+// Custom button styling
+
+
+ {reaction.count}
+
+```
+
+### Layout Variations
+```typescript
+// Horizontal layout (default)
+
+ {/* Reactions */}
+
+
+// Vertical layout
+
+ {/* Reactions */}
+
+
+// Grid layout
+
+ {/* Reactions */}
+
+```
+
+## Best Practices
+
+### Performance
+```typescript
+// Efficient filtering
+.filter((r) => r.count > 0)
+
+// Memoized event handlers
+const handleToggle = useCallback((type) => {
+ toggle(type);
+}, [toggle]);
+
+// Optimized re-renders
+React.memo(ResourceReaction);
+```
+
+### User Experience
+```typescript
+// Clear visual feedback
+className={reaction.is_reacted ? "bg-primary/20" : ""}
+
+// Accessible hover states
+openDelay={0} // Immediate hover response
+
+// Meaningful labels
+alt={`reaction-${resource_id}-${reaction.reaction_type}`}
+```
+
+### Data Management
+```typescript
+// Consistent prop types
+resource_type: "ARTICLE" | "COMMENT"
+
+// Proper error handling
+if (!reactions) return null;
+
+// Optimistic updates
+toggle(reactionType); // Immediate UI update
+```
\ No newline at end of file
diff --git a/docs/components/ResourceReactionable.md b/docs/components/ResourceReactionable.md
new file mode 100644
index 0000000..1f2c69c
--- /dev/null
+++ b/docs/components/ResourceReactionable.md
@@ -0,0 +1,509 @@
+# ResourceReactionable Component
+
+A render-prop component that provides reaction functionality for articles and comments with optimistic updates and authentication handling.
+
+## Location
+`src/components/render-props/ResourceReactionable.tsx`
+
+## Overview
+ResourceReactionable is a render-prop component that encapsulates all the logic for handling emoji reactions on resources (articles or comments). It provides data fetching, optimistic updates, authentication checking, and error handling while allowing complete flexibility in how the UI is rendered.
+
+## Props
+
+```typescript
+interface Props {
+ resource_type: "ARTICLE" | "COMMENT";
+ resource_id: string;
+ render: ({
+ toggle,
+ reactions,
+ getReaction,
+ }: {
+ toggle: (reaction_type: REACTION_TYPE) => void;
+ getReaction: (reaction_type: REACTION_TYPE) => ReactionStatusModel;
+ reactions: ReactionStatusModel[];
+ }) => React.ReactNode;
+}
+```
+
+### Props Details
+- `resource_type`: Type of resource being reacted to ("ARTICLE" or "COMMENT")
+- `resource_id`: Unique identifier of the resource
+- `render`: Function that receives reaction data and handlers, returns JSX
+
+## Render Function Parameters
+
+### Provided Data and Functions
+```typescript
+{
+ toggle: (reaction_type: REACTION_TYPE) => void;
+ getReaction: (reaction_type: REACTION_TYPE) => ReactionStatusModel;
+ reactions: ReactionStatusModel[];
+}
+```
+
+### ReactionStatusModel Interface
+```typescript
+interface ReactionStatusModel {
+ reaction_type: REACTION_TYPE;
+ count: number;
+ is_reacted: boolean;
+}
+```
+
+### REACTION_TYPE Enum
+- `LOVE`: Heart emoji reaction
+- `FIRE`: Fire emoji reaction
+- `WOW`: Wow emoji reaction
+- `HAHA`: Laugh emoji reaction
+- `CRY`: Cry emoji reaction
+- `UNICORN`: Unicorn emoji reaction
+
+## Usage Examples
+
+### Basic Usage with Custom UI
+```typescript
+import { ResourceReactionable } from '@/components/render-props/ResourceReactionable';
+
+function CustomReactionButton({ articleId }) {
+ return (
+ (
+
+ {reactions
+ .filter(r => r.count > 0)
+ .map(reaction => (
+ toggle(reaction.reaction_type)}
+ className={`px-2 py-1 rounded ${
+ reaction.is_reacted ? 'bg-blue-100' : 'bg-gray-100'
+ }`}
+ >
+ {reaction.reaction_type} {reaction.count}
+
+ ))}
+
+ )}
+ />
+ );
+}
+```
+
+### Advanced Usage with Emoji Icons
+```typescript
+function EmojiReactionBar({ commentId }) {
+ const emojiMap = {
+ LOVE: '❤️',
+ FIRE: '🔥',
+ WOW: '😲',
+ HAHA: '😂',
+ CRY: '😢',
+ UNICORN: '🦄'
+ };
+
+ return (
+ (
+
+ {/* Active reactions */}
+
+ {reactions
+ .filter(r => r.count > 0)
+ .map(reaction => (
+ toggle(reaction.reaction_type)}
+ className={`reaction-btn ${
+ reaction.is_reacted ? 'reacted' : ''
+ }`}
+ >
+ {emojiMap[reaction.reaction_type]}
+ {reaction.count}
+
+ ))}
+
+
+ {/* Reaction picker */}
+
+ {Object.entries(emojiMap).map(([type, emoji]) => {
+ const reactionData = getReaction(type as REACTION_TYPE);
+ return (
+ toggle(type as REACTION_TYPE)}
+ className={`picker-btn ${
+ reactionData?.is_reacted ? 'selected' : ''
+ }`}
+ title={`React with ${type.toLowerCase()}`}
+ >
+ {emoji}
+
+ );
+ })}
+
+
+ )}
+ />
+ );
+}
+```
+
+### Integration with Existing Components
+```typescript
+// How ResourceReaction component uses ResourceReactionable
+function ResourceReaction({ resource_type, resource_id }) {
+ return (
+ (
+
+ {reactions
+ .filter(r => r.count)
+ .map(reaction => (
+
toggle(reaction.reaction_type)}
+ className={`p-1 w-10 h-6 flex items-center gap-1 ${
+ reaction.is_reacted ? "bg-primary/20" : ""
+ }`}
+ >
+
+ {reaction.count}
+
+ ))}
+
+ {/* Reaction picker hover card */}
+
+
+
+
+
+
+
+
+ {reactions.map(reaction => (
+
toggle(reaction.reaction_type)}
+ key={reaction.reaction_type}
+ className={`reaction-picker ${
+ reaction.is_reacted ? "bg-primary/20" : ""
+ }`}
+ >
+
+
+ ))}
+
+
+
+
+ )}
+ />
+ );
+}
+```
+
+## Key Features
+
+### Data Management
+- **React Query Integration**: Automatic caching and background updates
+- **Optimistic Updates**: Immediate UI feedback before server confirmation
+- **Error Handling**: Automatic rollback on failure
+- **Authentication**: Automatic login prompt for unauthenticated users
+
+### State Management
+```typescript
+// Query for fetching reaction data
+const query = useQuery({
+ queryKey: ["reaction", resource_id, resource_type],
+ queryFn: () => reactionActions.getResourceReactions({ resource_id, resource_type }),
+});
+
+// Mutation for toggling reactions
+const mutation = useMutation({
+ mutationFn: (reaction_type: REACTION_TYPE) =>
+ reactionActions.toogleReaction({ resource_id, resource_type, reaction_type }),
+ // Optimistic updates and error handling
+});
+```
+
+### Optimistic Updates Implementation
+```typescript
+async onMutate(reaction_type) {
+ // Cancel outgoing requests
+ await queryClient.cancelQueries({
+ queryKey: ["reaction", resource_id, resource_type],
+ });
+
+ // Save current state for rollback
+ const oldReactions = queryClient.getQueryData([
+ "reaction", resource_id, resource_type,
+ ]);
+
+ // Optimistically update the cache
+ queryClient.setQueryData(
+ ["reaction", resource_id, resource_type],
+ (old: ReactionStatusModel[]) => {
+ const index = old.findIndex((r) => r.reaction_type == reaction_type);
+ if (old[index].is_reacted) {
+ old[index].is_reacted = false;
+ --old[index].count;
+ } else {
+ old[index].is_reacted = true;
+ ++old[index].count;
+ }
+ return old;
+ }
+ );
+
+ return { oldReactions };
+}
+```
+
+### Authentication Integration
+```typescript
+async onMutate(reaction_type) {
+ if (!session?.user) {
+ return appLoginPopup.show(); // Show login popup for unauthenticated users
+ }
+ // Continue with reaction logic
+}
+```
+
+## Provided Functions
+
+### toggle(reaction_type)
+```typescript
+const toggle = (reaction_type: REACTION_TYPE) => {
+ mutation.mutate(reaction_type);
+};
+```
+- Toggles a specific reaction on/off
+- Handles authentication automatically
+- Provides optimistic updates
+- Shows login popup if user not authenticated
+
+### getReaction(reaction_type)
+```typescript
+const getReaction = (reaction_type: REACTION_TYPE) => {
+ return query?.data?.find((r) => r.reaction_type === reaction_type);
+};
+```
+- Retrieves specific reaction data
+- Returns reaction status including count and user's reaction state
+- Useful for conditional rendering based on specific reactions
+
+## Error Handling
+
+### Automatic Rollback
+```typescript
+onError: (_, __, context) => {
+ // Rollback optimistic update on error
+ queryClient.setQueryData(
+ ["reaction", resource_id, resource_type],
+ context?.oldReactions
+ );
+}
+```
+
+### Network Error Recovery
+```typescript
+onSettled: () => {
+ // Refetch to ensure consistency
+ queryClient.invalidateQueries({
+ queryKey: ["reaction", resource_id, resource_type],
+ });
+}
+```
+
+## Performance Optimizations
+
+### Query Key Strategy
+```typescript
+queryKey: ["reaction", resource_id, resource_type]
+```
+- Efficient caching per resource
+- Automatic cache invalidation
+- Background refetching
+
+### Optimistic Updates
+- Immediate UI feedback
+- Reduced perceived latency
+- Automatic rollback on failure
+- Consistent state management
+
+## Common Patterns
+
+### Simple Reaction Counter
+```typescript
+ (
+
+ {reactions.reduce((total, r) => total + r.count, 0)} reactions
+
+ )}
+/>
+```
+
+### Conditional Reaction Display
+```typescript
+ {
+ const loveReaction = getReaction('LOVE');
+ return (
+
+ {loveReaction?.count > 0 && (
+ {loveReaction.count} loves
+ )}
+ toggle('LOVE')}>
+ {loveReaction?.is_reacted ? 'Unlike' : 'Love'}
+
+
+ );
+ }}
+/>
+```
+
+### Custom Reaction UI
+```typescript
+ (
+
+ {reactions.map(reaction => (
+
+ toggle(reaction.reaction_type)}
+ className={`reaction-btn ${
+ reaction.is_reacted ? 'user-reacted' : ''
+ }`}
+ >
+
+ {reaction.count}
+
+
+ ))}
+
+ )}
+/>
+```
+
+## Integration with Authentication
+
+### Login Flow
+1. User clicks reaction button
+2. Component checks authentication status
+3. If not logged in, shows login popup
+4. After login, user can proceed with reaction
+5. Reaction is processed and UI updates
+
+### Session Management
+```typescript
+const session = useSession();
+const appLoginPopup = useLoginPopup();
+
+// In mutation onMutate
+if (!session?.user) {
+ return appLoginPopup.show();
+}
+```
+
+## Best Practices
+
+### Render Function Optimization
+```typescript
+// Memoize expensive computations
+const MemoizedReactionUI = React.memo(({ reactions, toggle }) => {
+ const totalReactions = useMemo(() =>
+ reactions.reduce((sum, r) => sum + r.count, 0),
+ [reactions]
+ );
+
+ return (
+
+ Total: {totalReactions}
+ {/* Reaction buttons */}
+
+ );
+});
+
+ (
+
+ )}
+/>
+```
+
+### Error Handling
+```typescript
+ {
+ if (!reactions) {
+ return Loading reactions...
;
+ }
+
+ return (
+
+ {/* Reaction UI */}
+
+ );
+ }}
+/>
+```
+
+### Accessibility
+```typescript
+ (
+
+ {reactions.map(reaction => (
+ toggle(reaction.reaction_type)}
+ aria-label={`${reaction.is_reacted ? 'Remove' : 'Add'} ${
+ reaction.reaction_type.toLowerCase()
+ } reaction. Current count: ${reaction.count}`}
+ aria-pressed={reaction.is_reacted}
+ >
+ {/* Reaction UI */}
+
+ ))}
+
+ )}
+/>
+```
+
+## Related Components
+
+- **ResourceReaction**: Pre-built UI component using ResourceReactionable
+- **useLoginPopup**: Authentication popup integration
+- **useSession**: User session management
+
+## Dependencies
+
+- **React Query**: Data fetching and caching
+- **Jotai**: Session state management
+- **Backend Services**: Reaction API actions
\ No newline at end of file
diff --git a/docs/components/UserInformationCard.md b/docs/components/UserInformationCard.md
new file mode 100644
index 0000000..d562bf5
--- /dev/null
+++ b/docs/components/UserInformationCard.md
@@ -0,0 +1,402 @@
+# UserInformationCard Component
+
+A comprehensive user profile card that displays user information, profile photo, bio, and interactive elements.
+
+## Location
+`src/components/UserInformationCard.tsx`
+
+## Overview
+UserInformationCard is a reusable component that fetches and displays detailed user information including profile photo, name, bio, location, education, and interactive buttons for profile management or following.
+
+## Props
+
+```typescript
+interface Props {
+ userId: string;
+}
+```
+
+### Props Details
+- `userId`: Unique identifier of the user to display
+
+## Usage Examples
+
+### Basic User Card
+```typescript
+import UserInformationCard from '@/components/UserInformationCard';
+
+function UserProfile() {
+ return (
+
+
+
+ );
+}
+```
+
+### In Hover Card (as used in ArticleCard)
+```typescript
+import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
+
+function ArticleAuthor({ authorId, authorName }) {
+ return (
+
+
+ {authorName}
+
+
+
+
+
+ );
+}
+```
+
+### User Directory
+```typescript
+function UserDirectory({ userIds }: { userIds: string[] }) {
+ return (
+
+ {userIds.map(userId => (
+
+
+
+ ))}
+
+ );
+}
+```
+
+## Features
+
+### User Data Display
+- **Profile photo**: Optimized image display with fallbacks
+- **Name and username**: Primary identification
+- **Bio**: User description/introduction
+- **Location**: Geographic information
+- **Education**: Educational background
+
+### Interactive Elements
+- **Profile settings**: For current user (edit profile)
+- **Follow button**: For other users (future implementation)
+- **Responsive layout**: Adapts to container size
+
+### Loading States
+- **Skeleton loading**: Animated placeholder during data fetch
+- **Progressive loading**: Shows structure while fetching data
+- **Error handling**: Graceful fallback for failed requests
+
+## Data Fetching
+
+### React Query Integration
+```typescript
+const query = useQuery({
+ queryKey: ["user", userId],
+ queryFn: () => userActions.getUserById(userId),
+});
+```
+
+### Loading State Rendering
+```typescript
+if (query.isPending) {
+ return (
+
+ {/* Animated skeleton elements */}
+
+
+ {/* More skeleton elements */}
+
+ );
+}
+```
+
+## Component Structure
+
+### Profile Header
+```typescript
+
+ {/* Avatar */}
+
+
+
+
+ {/* Name and username */}
+
+
{query.data?.name}
+
{query.data?.username}
+
+
+```
+
+### Interactive Buttons
+```typescript
+{session?.user?.id == userId ? (
+
+ {_t("Profile Settings")}
+
+) : (
+ alert("Not implemented yet")}
+ className="w-full"
+ >
+ {_t("Follow")}
+
+)}
+```
+
+### Profile Details
+```typescript
+
+ {/* Bio */}
+
+ {query.data?.bio}
+
+
+ {/* Location */}
+ {query.data?.location && (
+
+
{_t("Location")}
+
{query.data?.location}
+
+ )}
+
+ {/* Education */}
+ {query.data?.education && (
+
+
{_t("Education")}
+
{query.data?.education}
+
+ )}
+
+```
+
+## Hooks Used
+
+### Custom Hooks
+- `useTranslation`: For internationalized text
+- `useSession`: For current user authentication state
+
+### React Query
+- `useQuery`: For fetching user data with caching and loading states
+
+## Authentication Integration
+
+### Current User Detection
+```typescript
+const session = useSession();
+const isCurrentUser = session?.user?.id == userId;
+```
+
+### Conditional Rendering
+- Shows "Profile Settings" button for current user
+- Shows "Follow" button for other users
+- Different interaction patterns based on authentication
+
+## Internationalization
+
+### Translated Labels
+```typescript
+{_t("Profile Settings")} // Profile settings button
+{_t("Follow")} // Follow button
+{_t("Location")} // Location label
+{_t("Education")} // Education label
+```
+
+### Multi-language Support
+- All user-facing text is translatable
+- Proper text direction support
+- Cultural formatting considerations
+
+## Loading States
+
+### Skeleton Design
+- Matches actual content layout
+- Smooth animation transitions
+- Progressive disclosure pattern
+- Accessible loading indicators
+
+### Performance Optimization
+- React Query caching prevents redundant requests
+- Optimized re-renders through proper query keys
+- Image optimization through `getFileUrl` utility
+
+## Styling and Layout
+
+### Container Styling
+```typescript
+// Flexible layout container
+
+ {/* Profile header */}
+ {/* Interactive buttons */}
+ {/* Profile details */}
+
+```
+
+### Avatar Styling
+```typescript
+className="w-14 h-14 rounded-full object-cover border-2 border-white/90 shadow-md"
+```
+
+### Responsive Considerations
+- Adapts to container width
+- Mobile-optimized touch targets
+- Flexible image sizing
+- Appropriate text scaling
+
+## Error Handling
+
+### Network Errors
+- Graceful fallback for failed requests
+- Error boundaries for component crashes
+- Retry mechanisms through React Query
+
+### Missing Data
+- Conditional rendering for optional fields
+- Fallback avatars for missing profile photos
+- Default values for empty fields
+
+## Accessibility Features
+
+### Semantic HTML
+- Proper heading hierarchy
+- Descriptive image alt text
+- Accessible button labels
+- Screen reader friendly structure
+
+### Keyboard Navigation
+- Focusable interactive elements
+- Logical tab order
+- Proper ARIA attributes
+
+## Performance Considerations
+
+### Image Optimization
+```typescript
+// Optimized image loading
+
+```
+
+### Query Optimization
+- Proper query key structure for caching
+- Automatic background refetching
+- Stale-while-revalidate pattern
+
+## Common Use Cases
+
+### Author Hover Cards
+```typescript
+function ArticleAuthorHover({ authorId }) {
+ return (
+
+
+ View Author
+
+
+
+
+
+ );
+}
+```
+
+### User Search Results
+```typescript
+function UserSearchResults({ users }) {
+ return (
+
+ {users.map(user => (
+
+ ))}
+
+ );
+}
+```
+
+### Team Member Profiles
+```typescript
+function TeamSection({ teamMembers }) {
+ return (
+
+ Our Team
+
+ {teamMembers.map(member => (
+
+
+
+ ))}
+
+
+ );
+}
+```
+
+## Integration with Other Components
+
+### Related Components
+- **AppImage**: For optimized profile photo display
+- **Button**: For interactive elements
+- **HoverCard**: For popup user previews
+- **Link**: For navigation to user profiles
+
+### Data Dependencies
+- User data from `userActions.getUserById`
+- Session data for authentication context
+- File URL generation via `getFileUrl`
+
+## Best Practices
+
+### Data Management
+```typescript
+// Proper query key structure
+queryKey: ["user", userId]
+
+// Error handling
+if (query.error) {
+ return ;
+}
+
+// Loading states
+if (query.isPending) {
+ return ;
+}
+```
+
+### User Experience
+```typescript
+// Progressive loading
+
+ {/* Skeleton content that matches real layout */}
+
+
+// Clear visual hierarchy
+{name}
+{username}
+
+// Accessible interactions
+
+ {_t("Follow")}
+
+```
+
+### Performance
+```typescript
+// Optimized images
+width={56}
+height={56}
+className="w-14 h-14 rounded-full object-cover"
+
+// Efficient queries
+queryFn: () => userActions.getUserById(userId),
+staleTime: 5 * 60 * 1000, // 5 minutes
+```
\ No newline at end of file
diff --git a/docs/hooks/README.md b/docs/hooks/README.md
new file mode 100644
index 0000000..5543dac
--- /dev/null
+++ b/docs/hooks/README.md
@@ -0,0 +1,299 @@
+# Custom Hooks Documentation
+
+This directory contains comprehensive documentation for all custom React hooks used in the TechDiary application.
+
+## Overview
+
+Custom hooks are reusable functions that encapsulate stateful logic and side effects. They allow you to extract component logic into reusable functions that can be shared across multiple components.
+
+## Available Custom Hooks
+
+### State Management
+- **[useToggle](./useToggle.md)** - Boolean state management with toggle, open, and close functions
+- **[useIsMobile](./useIsMobile.md)** - Responsive breakpoint detection for mobile screens
+
+### User Interaction
+- **[useClickAway](./useClickAway.md)** - Detect clicks outside of specified elements
+- **[useDebouncedCallback](./useDebouncedCallback.md)** - Debounce function calls to limit execution frequency
+
+### UI Enhancement
+- **[useAutosizeTextArea](./useAutosizeTextArea.md)** - Automatically resize textarea elements to fit content
+- **[useMarkdownEditor](./useMarkdownEditor.md)** - Markdown editing commands for textarea elements
+
+### File Management
+- **[useServerFile](./useServerFile.md)** - File upload and deletion with cloud storage integration
+
+### Context-Based Hooks (Require Providers)
+- **[useAppConfirm](./useAppConfirm.md)** - Confirmation dialogs with customizable actions
+- **[useAppAlert](./useAppAlert.md)** - Alert notifications with different types (error, warning, success, info)
+- **[useLoginPopup](./useLoginPopup.md)** - GitHub OAuth login popup for authentication
+- **[useTranslation](./useTranslation.md)** - Internationalization with Bengali/English support
+
+## Quick Reference
+
+| Hook | Purpose | Returns | Provider Required |
+|------|---------|---------|-------------------|
+| `useToggle` | Boolean state with actions | `[state, actions]` | No |
+| `useIsMobile` | Mobile breakpoint detection | `boolean` | No |
+| `useClickAway` | Outside click detection | `ref` | No |
+| `useDebouncedCallback` | Debounced function calls | `debouncedCallback` | No |
+| `useAutosizeTextArea` | Auto-resize textarea | `void` | No |
+| `useMarkdownEditor` | Markdown commands | `{ executeCommand }` | No |
+| `useServerFile` | File operations | `{ uploadFile, deleteFile, ...states }` | No |
+| `useAppConfirm` | Confirmation dialogs | `{ show, closeModal }` | `AppConfirmProvider` |
+| `useAppAlert` | Alert notifications | `{ show, closeModal }` | `AppAlertProvider` |
+| `useLoginPopup` | Login popup | `{ show, closeModal }` | `AppLoginPopupProvider` |
+| `useTranslation` | i18n translations | `{ _t, lang, toggle }` | No (uses Jotai) |
+
+## Common Patterns
+
+### 1. State Management with Actions
+```typescript
+const [isOpen, { toggle, open, close }] = useToggle();
+```
+
+### 2. Ref-based Hooks
+```typescript
+const ref = useRef(null);
+useClickAway(ref, onClickAway);
+```
+
+### 3. Effect-based Hooks
+```typescript
+useAutosizeTextArea(textareaRef, value);
+```
+
+### 4. Function Return Hooks
+```typescript
+const debouncedSearch = useDebouncedCallback(search, 300);
+```
+
+### 5. Context-based Hooks
+```typescript
+const { show } = useAppConfirm();
+const { _t } = useTranslation();
+```
+
+## Provider Setup
+
+For context-based hooks, wrap your app with the required providers:
+
+```typescript
+import {
+ AppConfirmProvider,
+ AppAlertProvider,
+ AppLoginPopupProvider
+} from '@/components';
+
+function App() {
+ return (
+
+
+
+
+
+
+
+ );
+}
+```
+
+## Integration Examples
+
+### Modal with Click Away and Toggle
+```typescript
+function Modal() {
+ const [isOpen, { close, toggle }] = useToggle();
+ const modalRef = useRef(null);
+
+ useClickAway(modalRef, close);
+
+ return (
+ <>
+ Open Modal
+ {isOpen && (
+
+ )}
+ >
+ );
+}
+```
+
+### Auto-resize Search with Debounced API Calls
+```typescript
+function SearchInput() {
+ const [query, setQuery] = useState('');
+ const textareaRef = useRef(null);
+
+ const debouncedSearch = useDebouncedCallback(performSearch, 300);
+ useAutosizeTextArea(textareaRef, query);
+
+ const handleChange = (e: ChangeEvent) => {
+ const value = e.target.value;
+ setQuery(value);
+ debouncedSearch(value);
+ };
+
+ return (
+
+ );
+}
+```
+
+### Internationalized Confirmation Dialog
+```typescript
+function DeleteButton({ onDelete }: { onDelete: () => void }) {
+ const { show } = useAppConfirm();
+ const { _t } = useTranslation();
+
+ const handleDelete = () => {
+ show({
+ title: _t("Confirm Delete"),
+ children: {_t("This action cannot be undone")}
,
+ labels: {
+ confirm: _t("Delete"),
+ cancel: _t("Cancel")
+ },
+ onConfirm: onDelete
+ });
+ };
+
+ return {_t("Delete")} ;
+}
+```
+
+### Authentication-Protected Feature
+```typescript
+function ProtectedFeature() {
+ const { show: showLogin } = useLoginPopup();
+ const { show: showAlert } = useAppAlert();
+ const { _t } = useTranslation();
+ const user = useCurrentUser(); // Assume this exists
+
+ const handleFeatureUse = () => {
+ if (!user) {
+ showLogin();
+ return;
+ }
+
+ try {
+ executeFeature();
+ showAlert({
+ title: _t("Success"),
+ description: _t("Feature executed successfully"),
+ type: "success"
+ });
+ } catch (error) {
+ showAlert({
+ title: _t("Error"),
+ description: _t("Feature failed to execute"),
+ type: "error"
+ });
+ }
+ };
+
+ return (
+
+ {user ? _t("Use Feature") : _t("Login Required")}
+
+ );
+}
+```
+
+## Hook Categories
+
+### Basic Utility Hooks
+Simple hooks that don't require external dependencies or providers:
+- `useToggle`, `useIsMobile`, `useClickAway`, `useDebouncedCallback`
+
+### UI Enhancement Hooks
+Hooks that enhance user interface components:
+- `useAutosizeTextArea`, `useMarkdownEditor`
+
+### Service Integration Hooks
+Hooks that integrate with external services:
+- `useServerFile` (cloud storage), `useTranslation` (i18n)
+
+### Application Context Hooks
+Hooks that require provider setup for app-wide functionality:
+- `useAppConfirm`, `useAppAlert`, `useLoginPopup`
+
+## Best Practices
+
+### 1. Hook Composition
+- Combine multiple hooks for complex functionality
+- Use smaller, focused hooks rather than large monolithic ones
+- Follow the single responsibility principle
+
+### 2. TypeScript Integration
+- All hooks are fully typed
+- Provide generic type parameters where applicable
+- Use proper return type annotations
+
+### 3. Performance Optimization
+- Use `useCallback` and `useMemo` appropriately
+- Minimize re-renders through proper dependency arrays
+- Clean up resources in useEffect cleanup functions
+
+### 4. Error Handling
+- Handle edge cases (null refs, undefined values)
+- Provide fallback behavior for error states
+- Use proper TypeScript null checking
+
+### 5. Provider Organization
+- Group related providers together
+- Consider provider order for dependencies
+- Keep provider state minimal and focused
+
+### 6. Testing
+- Write unit tests for custom hooks using React Testing Library
+- Test edge cases and error conditions
+- Mock external dependencies appropriately
+
+## Architecture Decisions
+
+### File Organization
+- Individual hooks in `/src/hooks/` directory
+- Provider-based hooks in `/src/components/` directory
+- Related hooks grouped by functionality
+- Clear, descriptive file names
+
+### Naming Conventions
+- All hooks start with `use` prefix
+- Descriptive names that indicate purpose
+- Consistent parameter and return value naming
+
+### Dependencies
+- Minimal external dependencies
+- Use React built-in hooks as foundation
+- Leverage TypeScript for type safety
+- Integration with application state management (Jotai)
+
+## Contributing
+
+When adding new custom hooks:
+
+1. Create the hook in appropriate directory (`/src/hooks/` or `/src/components/`)
+2. Follow existing patterns and naming conventions
+3. Add comprehensive TypeScript types
+4. Include JSDoc comments for better IDE support
+5. Create documentation following the existing format
+6. Add usage examples and common patterns
+7. Update this README with the new hook
+8. Consider if a provider is needed for global state
+
+## Resources
+
+- [React Hooks Official Documentation](https://react.dev/reference/react)
+- [Custom Hooks Best Practices](https://react.dev/learn/reusing-logic-with-custom-hooks)
+- [TypeScript with React Hooks](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/hooks)
+- [Context API Best Practices](https://react.dev/learn/passing-data-deeply-with-context)
\ No newline at end of file
diff --git a/docs/hooks/useAppAlert.md b/docs/hooks/useAppAlert.md
new file mode 100644
index 0000000..41d65d5
--- /dev/null
+++ b/docs/hooks/useAppAlert.md
@@ -0,0 +1,278 @@
+# useAppAlert Hook
+
+A context-based hook for displaying alert notifications with different types (error, warning, success, info) throughout the application.
+
+## Location
+`src/components/app-alert.tsx`
+
+## Provider
+`AppAlertProvider` - Must wrap your app or component tree to use this hook
+
+## Signature
+```typescript
+function useAppAlert(): {
+ show: (options: Options) => void;
+ closeModal: () => void;
+}
+```
+
+## Options Interface
+```typescript
+interface Options {
+ title: string;
+ description?: string;
+ type?: "warning" | "error" | "success" | "info";
+ isShowCancel?: boolean;
+ isShowConfirm?: boolean;
+}
+```
+
+## Parameters
+None - Hook uses React Context
+
+## Returns
+An object containing:
+- `show`: Function to display alert dialog
+- `closeModal`: Function to manually close the dialog
+
+## Setup
+
+### 1. Wrap Your App with Provider
+```typescript
+import { AppAlertProvider } from '@/components/app-alert';
+
+function App() {
+ return (
+
+
+
+ );
+}
+```
+
+### 2. Use the Hook
+```typescript
+import { useAppAlert } from '@/components/app-alert';
+
+function MyComponent() {
+ const { show } = useAppAlert();
+
+ const handleError = () => {
+ show({
+ title: "Operation Failed",
+ description: "Unable to save your changes. Please try again.",
+ type: "error"
+ });
+ };
+
+ const handleSuccess = () => {
+ show({
+ title: "Success!",
+ description: "Your changes have been saved successfully.",
+ type: "success"
+ });
+ };
+
+ return (
+
+ Trigger Error
+ Trigger Success
+
+ );
+}
+```
+
+## Alert Types
+
+### Error Alert
+```typescript
+const { show } = useAppAlert();
+
+show({
+ title: "Error",
+ description: "Something went wrong. Please try again later.",
+ type: "error"
+});
+```
+
+### Warning Alert
+```typescript
+show({
+ title: "Warning",
+ description: "This action may have unintended consequences.",
+ type: "warning"
+});
+```
+
+### Success Alert
+```typescript
+show({
+ title: "Success",
+ description: "Your action was completed successfully.",
+ type: "success"
+});
+```
+
+### Info Alert
+```typescript
+show({
+ title: "Information",
+ description: "Here's some helpful information for you.",
+ type: "info"
+});
+```
+
+## Advanced Usage Examples
+
+### Error Handling in API Calls
+```typescript
+function DataFetcher() {
+ const { show } = useAppAlert();
+
+ const fetchData = async () => {
+ try {
+ const response = await fetch('/api/data');
+ if (!response.ok) throw new Error('Failed to fetch');
+
+ show({
+ title: "Data Loaded",
+ description: "Successfully loaded the latest data.",
+ type: "success"
+ });
+ } catch (error) {
+ show({
+ title: "Loading Failed",
+ description: "Could not load data. Please check your connection and try again.",
+ type: "error"
+ });
+ }
+ };
+
+ return Load Data ;
+}
+```
+
+### Form Validation Alerts
+```typescript
+function FormComponent() {
+ const { show } = useAppAlert();
+
+ const validateAndSubmit = (formData: FormData) => {
+ if (!formData.email) {
+ show({
+ title: "Validation Error",
+ description: "Please provide a valid email address.",
+ type: "warning"
+ });
+ return;
+ }
+
+ // Submit form
+ show({
+ title: "Form Submitted",
+ description: "Thank you! Your form has been submitted successfully.",
+ type: "success"
+ });
+ };
+
+ return (
+
+ );
+}
+```
+
+### User Onboarding Tips
+```typescript
+function OnboardingTips() {
+ const { show } = useAppAlert();
+
+ const showTip = () => {
+ show({
+ title: "Pro Tip",
+ description: "You can use keyboard shortcuts to navigate faster. Press 'H' for help.",
+ type: "info"
+ });
+ };
+
+ return Show Tip ;
+}
+```
+
+## Visual Indicators
+
+Each alert type displays a different icon:
+- **Error**: Red CircleX icon
+- **Warning**: Yellow warning triangle
+- **Success**: Green checkmark (using warning icon as placeholder)
+- **Info**: Blue info circle
+
+## Options Details
+
+### Required Options
+- `title`: Alert title text
+
+### Optional Options
+- `description`: Additional descriptive text
+- `type`: Alert type - "error" (default), "warning", "success", "info"
+- `isShowCancel`: Currently not used in implementation
+- `isShowConfirm`: Currently not used in implementation
+
+## Features
+- **Context-based**: Uses React Context for global state management
+- **Type-based styling**: Different icons and colors for each alert type
+- **Internationalization**: Uses translation hook for "Close" button
+- **Accessible**: Built with AlertDialog component for accessibility
+- **TypeScript support**: Fully typed with proper interfaces
+- **Memoized rendering**: Optimized icon rendering with useMemo
+
+## Implementation Details
+- Uses `useState` for dialog state and content management
+- Uses `useCallback` for memoized event handlers
+- Uses `useMemo` for optimized icon rendering
+- Built on top of shadcn/ui AlertDialog component
+- Integrates with i18n translation system
+- Renders icons conditionally based on alert type
+
+## Common Use Cases
+- **API error handling**: Display server error messages
+- **Form validation**: Show validation errors and warnings
+- **Success notifications**: Confirm successful operations
+- **User guidance**: Provide helpful information and tips
+- **System status**: Notify users about system states
+- **Feature announcements**: Inform users about new features
+- **Maintenance notices**: Alert users about system maintenance
+
+## Best Practices
+- Use appropriate alert types for different situations
+- Keep titles concise and descriptions informative
+- Provide actionable information when possible
+- Use error alerts for failures, warnings for cautions
+- Use success alerts for confirmations
+- Use info alerts for helpful tips and information
+
+## Error Handling
+The hook will throw an error if used outside of `AppAlertProvider`:
+```
+Error: useAppAlert must be used within a AppAlertProvider
+```
+
+## Styling
+- Icons are styled with appropriate colors for each type
+- Error icons use `text-destructive` class
+- Warning icons use `text-warning` class
+- Success icons use `text-success` class
+- Info icons use default text color
+- Icons are sized at `size-20` (80px)
+
+## Internationalization
+- Uses `useTranslation` hook for localized text
+- "Close" button text is translated based on current language
+- Supports Bengali and English languages
+
+## Performance Considerations
+- Icon rendering is memoized with `useMemo`
+- Provider state is isolated to prevent unnecessary re-renders
+- Callbacks are memoized to prevent function recreation
+- Lightweight state management with minimal overhead
\ No newline at end of file
diff --git a/docs/hooks/useAppConfirm.md b/docs/hooks/useAppConfirm.md
new file mode 100644
index 0000000..0e40715
--- /dev/null
+++ b/docs/hooks/useAppConfirm.md
@@ -0,0 +1,226 @@
+# useAppConfirm Hook
+
+A context-based hook for displaying confirmation dialogs throughout the application using a provider pattern.
+
+## Location
+`src/components/app-confirm.tsx`
+
+## Provider
+`AppConfirmProvider` - Must wrap your app or component tree to use this hook
+
+## Signature
+```typescript
+function useAppConfirm(): {
+ show: (options: Options) => void;
+ closeModal: () => void;
+}
+```
+
+## Options Interface
+```typescript
+interface Options {
+ title: string;
+ children?: React.ReactNode;
+ labels?: {
+ confirm?: string;
+ cancel?: string;
+ };
+ onCancel?: () => void;
+ onConfirm?: () => void;
+ isShowCancel?: boolean;
+ isShowConfirm?: boolean;
+}
+```
+
+## Parameters
+None - Hook uses React Context
+
+## Returns
+An object containing:
+- `show`: Function to display confirmation dialog
+- `closeModal`: Function to manually close the dialog
+
+## Setup
+
+### 1. Wrap Your App with Provider
+```typescript
+import { AppConfirmProvider } from '@/components/app-confirm';
+
+function App() {
+ return (
+
+
+
+ );
+}
+```
+
+### 2. Use the Hook
+```typescript
+import { useAppConfirm } from '@/components/app-confirm';
+
+function MyComponent() {
+ const { show, closeModal } = useAppConfirm();
+
+ const handleDelete = () => {
+ show({
+ title: "Delete Item",
+ children: Are you sure you want to delete this item? This action cannot be undone.
,
+ labels: {
+ confirm: "Delete",
+ cancel: "Cancel"
+ },
+ onConfirm: () => {
+ // Perform delete action
+ console.log("Item deleted");
+ },
+ onCancel: () => {
+ console.log("Delete cancelled");
+ }
+ });
+ };
+
+ return (
+
+ Delete Item
+
+ );
+}
+```
+
+## Advanced Usage Examples
+
+### Simple Confirmation
+```typescript
+function SimpleConfirm() {
+ const { show } = useAppConfirm();
+
+ const handleAction = () => {
+ show({
+ title: "Confirm Action",
+ children: Do you want to proceed?
,
+ onConfirm: () => {
+ // Proceed with action
+ }
+ });
+ };
+
+ return Proceed ;
+}
+```
+
+### Custom Labels and Actions
+```typescript
+function CustomConfirm() {
+ const { show } = useAppConfirm();
+
+ const handleLogout = () => {
+ show({
+ title: "Sign Out",
+ children: (
+
+
You will be signed out of your account.
+
Any unsaved changes will be lost.
+
+ ),
+ labels: {
+ confirm: "Sign Out",
+ cancel: "Stay Signed In"
+ },
+ onConfirm: async () => {
+ await signOut();
+ window.location.href = '/';
+ }
+ });
+ };
+
+ return Sign Out ;
+}
+```
+
+### Information Only (No Cancel Button)
+```typescript
+function InfoDialog() {
+ const { show } = useAppConfirm();
+
+ const showInfo = () => {
+ show({
+ title: "Information",
+ children: This is an informational message.
,
+ labels: {
+ confirm: "Got it"
+ },
+ isShowCancel: false,
+ onConfirm: () => {
+ console.log("User acknowledged");
+ }
+ });
+ };
+
+ return Show Info ;
+}
+```
+
+## Options Details
+
+### Required Options
+- `title`: Dialog title text
+
+### Optional Options
+- `children`: React content for dialog body
+- `labels.confirm`: Custom confirm button text (default: "Continue")
+- `labels.cancel`: Custom cancel button text (default: "Cancel")
+- `onConfirm`: Callback when confirm button is clicked
+- `onCancel`: Callback when cancel button is clicked
+- `isShowCancel`: Show/hide cancel button (default: true)
+- `isShowConfirm`: Show/hide confirm button (default: true)
+
+## Features
+- **Context-based**: Uses React Context for global state management
+- **Customizable**: Flexible options for different use cases
+- **Accessible**: Built with AlertDialog component for accessibility
+- **TypeScript support**: Fully typed with proper interfaces
+- **Auto-close**: Confirm button automatically closes dialog
+- **Memoized callbacks**: Optimized performance with useCallback
+
+## Implementation Details
+- Uses `useState` for dialog state and content management
+- Uses `useCallback` for memoized event handlers
+- Built on top of shadcn/ui AlertDialog component
+- Renders dialog conditionally based on open state
+- Automatically closes dialog when confirm is clicked
+
+## Common Use Cases
+- **Delete confirmations**: Confirm destructive actions
+- **Form submissions**: Confirm important form actions
+- **Navigation warnings**: Warn about unsaved changes
+- **Logout confirmations**: Confirm user logout
+- **Bulk actions**: Confirm operations on multiple items
+- **Purchase confirmations**: Confirm payments or orders
+- **Settings changes**: Confirm critical setting changes
+
+## Best Practices
+- Always provide clear, descriptive titles
+- Use appropriate button labels that match the action
+- Provide detailed explanations in the children content
+- Handle both confirm and cancel actions appropriately
+- Consider accessibility with proper ARIA attributes
+- Test with keyboard navigation and screen readers
+
+## Error Handling
+The hook will throw an error if used outside of `AppConfirmProvider`:
+```
+Error: useAppConfirm must be used within a ModalProvider
+```
+
+## Styling
+- Uses shadcn/ui AlertDialog components
+- Confirm button uses "destructive" variant by default
+- Cancel button uses "secondary" variant
+- Fully themeable through CSS variables
+
+## Performance Considerations
+- Provider state is isolated to prevent unnecessary re-renders
+- Callbacks are memoized to prevent function recreation
+- Dialog content is only rendered when needed
+- Lightweight state management with minimal overhead
\ No newline at end of file
diff --git a/docs/hooks/useAutosizeTextArea.md b/docs/hooks/useAutosizeTextArea.md
new file mode 100644
index 0000000..dccaf2e
--- /dev/null
+++ b/docs/hooks/useAutosizeTextArea.md
@@ -0,0 +1,144 @@
+# useAutosizeTextArea Hook
+
+A custom hook that automatically resizes a textarea element to fit its content, eliminating the need for manual scrolling.
+
+## Location
+`src/hooks/use-auto-resize-textarea.ts`
+
+## Signature
+```typescript
+function useAutosizeTextArea(
+ textAreaRef: React.RefObject,
+ value: string,
+ initialHeight?: string
+): void
+```
+
+## Parameters
+- `textAreaRef`: React ref object pointing to the textarea element
+- `value`: Current text content of the textarea (triggers resize when changed)
+- `initialHeight` (optional): Initial height to set before auto-sizing
+
+## Returns
+None (void) - This hook has side effects on the referenced textarea
+
+## Usage Example
+
+```typescript
+import { useAutosizeTextArea } from '@/hooks/use-auto-resize-textarea';
+import { useRef, useState } from 'react';
+
+function AutoResizeTextarea() {
+ const [text, setText] = useState('');
+ const textareaRef = useRef(null);
+
+ // Auto-resize textarea based on content
+ useAutosizeTextArea(textareaRef, text);
+
+ return (
+