diff --git a/backend/src/build-system/__tests__/fullstack-gen.spec.ts b/backend/src/build-system/__tests__/fullstack-gen.spec.ts index d62758af..830b9f35 100644 --- a/backend/src/build-system/__tests__/fullstack-gen.spec.ts +++ b/backend/src/build-system/__tests__/fullstack-gen.spec.ts @@ -10,15 +10,15 @@ import { BuilderContext } from '../context'; import { FrontendCodeHandler } from '../handlers/frontend-code-generate'; import { FileStructureAndArchitectureHandler } from '../handlers/file-manager/file-struct'; import { BackendRequirementHandler } from '../handlers/backend/requirements-document'; +import { UIUXLayoutHandler } from '../handlers/ux/uiux-layout'; (isIntegrationTest ? describe : describe.skip)('Build Sequence Test', () => { it('should execute build sequence successfully', async () => { const sequence: BuildSequence = { id: 'test-backend-sequence', version: '1.0.0', - name: 'Wrtie a Cool personal website', - description: - 'A personal blog website. I am a cybersecurity engineer so i want it to show i am a really cool hacker, with cool terminal functionality', + name: 'Wrtie a Single page Cool cybersecurity personal website', + description: `A Single page personal blog website. I am a cybersecurity engineer so i want it to show i am a really cool hacker, with cool terminal functionality`, databaseType: 'SQLite', model: 'gpt-4o-mini', projectSize: 'medium', // limit for fun @@ -40,6 +40,11 @@ import { BackendRequirementHandler } from '../handlers/backend/requirements-docu name: 'UX Sitemap Structure Node', // requires: ['op:UX:SMD'], }, + { + handler: UIUXLayoutHandler, + name: 'UIUX Layout Handler', + // requires: ['op:UX:SMD'], + }, { handler: UXDMDHandler, name: 'UX DataMap Document Node', diff --git a/backend/src/build-system/__tests__/test-file-create.spec.ts b/backend/src/build-system/__tests__/test-file-create.spec.ts index 5dfc5f8c..e35555e1 100644 --- a/backend/src/build-system/__tests__/test-file-create.spec.ts +++ b/backend/src/build-system/__tests__/test-file-create.spec.ts @@ -1,71 +1,71 @@ -import * as fs from 'fs-extra'; -import * as path from 'path'; -import { FileGeneratorHandler } from '../handlers/file-manager/file-generate'; -import { Logger } from '@nestjs/common'; -import { isIntegrationTest } from 'src/common/utils'; +// import * as fs from 'fs-extra'; +// import * as path from 'path'; +// import { FileGeneratorHandler } from '../handlers/file-manager/file-generate'; +// import { Logger } from '@nestjs/common'; +// import { isIntegrationTest } from 'src/common/utils'; -(isIntegrationTest ? describe : describe.skip)('FileGeneratorHandler', () => { - const projectSrcPath = path.normalize( - path.join('src', 'build-system', '__tests__', 'test-project'), - ); +// (isIntegrationTest ? describe : describe.skip)('FileGeneratorHandler', () => { +// const projectSrcPath = path.normalize( +// path.join('src', 'build-system', '__tests__', 'test-project'), +// ); - const mdFilePath = path.normalize( - path.join('src', 'build-system', '__tests__', 'file-arch.md'), - ); +// const mdFilePath = path.normalize( +// path.join('src', 'build-system', '__tests__', 'file-arch.md'), +// ); - const structMdFilePath = path.normalize( - path.join('src', 'build-system', '__tests__', 'file-structure-document.md'), - ); +// const structMdFilePath = path.normalize( +// path.join('src', 'build-system', '__tests__', 'file-structure-document.md'), +// ); - beforeEach(async () => { - // Ensure the project directory is clean - await fs.remove( - path.normalize( - path.join('src', 'build-system', '__tests__', 'test-project', 'src'), - ), - ); - }); +// beforeEach(async () => { +// // Ensure the project directory is clean +// await fs.remove( +// path.normalize( +// path.join('src', 'build-system', '__tests__', 'test-project', 'src'), +// ), +// ); +// }); - afterEach(async () => { - // Clean up the generated test files - await fs.remove( - path.normalize( - path.join('src', 'build-system', '__tests__', 'test-project', 'src'), - ), - ); - }); +// afterEach(async () => { +// // Clean up the generated test files +// await fs.remove( +// path.normalize( +// path.join('src', 'build-system', '__tests__', 'test-project', 'src'), +// ), +// ); +// }); - it('should generate files based on file-arch.md', async () => { - const archMarkdownContent = fs.readFileSync( - path.normalize(path.resolve(mdFilePath)), - 'utf8', - ); - const structMarkdownContent = fs.readFileSync( - path.normalize(path.resolve(structMdFilePath)), - 'utf8', - ); +// it('should generate files based on file-arch.md', async () => { +// const archMarkdownContent = fs.readFileSync( +// path.normalize(path.resolve(mdFilePath)), +// 'utf8', +// ); +// const structMarkdownContent = fs.readFileSync( +// path.normalize(path.resolve(structMdFilePath)), +// 'utf8', +// ); - const handler = new FileGeneratorHandler(); +// const handler = new FileGeneratorHandler(); - // Run the file generator with the JSON data - const result = await handler.generateFiles( - archMarkdownContent, - projectSrcPath, - ); +// // Run the file generator with the JSON data +// const result = await handler.generateFiles( +// archMarkdownContent, +// projectSrcPath, +// ); - Logger.log('File generation result:', result); +// Logger.log('File generation result:', result); - // Verify that all files exist - const jsonData = JSON.parse( - /([\s\S]*?)<\/GENERATEDCODE>/.exec( - archMarkdownContent, - )![1], - ); - const files = Object.keys(jsonData.files); +// // Verify that all files exist +// const jsonData = JSON.parse( +// /([\s\S]*?)<\/GENERATEDCODE>/.exec( +// archMarkdownContent, +// )![1], +// ); +// const files = Object.keys(jsonData.files); - for (const file of files) { - const filePath = path.resolve(projectSrcPath, file); - expect(fs.existsSync(filePath)).toBeTruthy(); - } - }, 30000); -}); +// for (const file of files) { +// const filePath = path.resolve(projectSrcPath, file); +// expect(fs.existsSync(filePath)).toBeTruthy(); +// } +// }, 30000); +// }); diff --git a/backend/src/build-system/__tests__/test.backend-code-generator.spec.ts b/backend/src/build-system/__tests__/test.backend-code-generator.spec.ts index 75c43f88..01a29114 100644 --- a/backend/src/build-system/__tests__/test.backend-code-generator.spec.ts +++ b/backend/src/build-system/__tests__/test.backend-code-generator.spec.ts @@ -1,77 +1,77 @@ -import { BuildSequence } from '../types'; -import * as fs from 'fs'; -import { executeBuildSequence } from './utils'; -import { isIntegrationTest } from 'src/common/utils'; -import { PRDHandler } from '../handlers/product-manager/product-requirements-document/prd'; -import { UXSMDHandler } from '../handlers/ux/sitemap-document'; -import { DBRequirementHandler } from '../handlers/database/requirements-document'; -import { DBSchemaHandler } from '../handlers/database/schemas/schemas'; -import { BackendCodeHandler } from '../handlers/backend/code-generate'; -import { ProjectInitHandler } from '../handlers/project-init'; -(isIntegrationTest ? describe : describe.skip)( - 'Sequence: PRD -> UXSD -> UXDD -> UXSS -> DBSchemas -> BackendCodeGenerator', - () => { - // Generate a unique folder with a timestamp - const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); - const logFolderPath = `./logs/backend_code_generator-${timestamp}`; - fs.mkdirSync(logFolderPath, { recursive: true }); +// import { BuildSequence } from '../types'; +// import * as fs from 'fs'; +// import { executeBuildSequence } from './utils'; +// import { isIntegrationTest } from 'src/common/utils'; +// import { PRDHandler } from '../handlers/product-manager/product-requirements-document/prd'; +// import { UXSMDHandler } from '../handlers/ux/sitemap-document'; +// import { DBRequirementHandler } from '../handlers/database/requirements-document'; +// import { DBSchemaHandler } from '../handlers/database/schemas/schemas'; +// import { BackendCodeHandler } from '../handlers/backend/code-generate'; +// import { ProjectInitHandler } from '../handlers/project-init'; +// (isIntegrationTest ? describe : describe.skip)( +// 'Sequence: PRD -> UXSD -> UXDD -> UXSS -> DBSchemas -> BackendCodeGenerator', +// () => { +// // Generate a unique folder with a timestamp +// const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); +// const logFolderPath = `./logs/backend_code_generator-${timestamp}`; +// fs.mkdirSync(logFolderPath, { recursive: true }); - (isIntegrationTest ? it : it.skip)( - 'should execute the backend code generation sequence and log results to individual files', - async () => { - // Define the build sequence up to Backend Code Generator - const sequence: BuildSequence = { - id: 'test-backend-sequence', - version: '1.0.0', - name: 'Spotify-like Music Web', - description: 'Users can play music', - databaseType: 'SQLite', - nodes: [ - { - handler: ProjectInitHandler, - name: 'Project Folders Setup', - }, - { - handler: PRDHandler, - name: 'PRD Generation Node', - }, +// (isIntegrationTest ? it : it.skip)( +// 'should execute the backend code generation sequence and log results to individual files', +// async () => { +// // Define the build sequence up to Backend Code Generator +// const sequence: BuildSequence = { +// id: 'test-backend-sequence', +// version: '1.0.0', +// name: 'Spotify-like Music Web', +// description: 'Users can play music', +// databaseType: 'SQLite', +// nodes: [ +// { +// handler: ProjectInitHandler, +// name: 'Project Folders Setup', +// }, +// { +// handler: PRDHandler, +// name: 'PRD Generation Node', +// }, - { - handler: UXSMDHandler, - name: 'UX Sitemap Document Node', - // requires: ['op:PRD'], - }, +// { +// handler: UXSMDHandler, +// name: 'UX Sitemap Document Node', +// // requires: ['op:PRD'], +// }, - { - handler: UXSMDHandler, - name: 'UX Data Map Document Node', - // requires: ['op:UX:SMD'], - }, +// { +// handler: UXSMDHandler, +// name: 'UX Data Map Document Node', +// // requires: ['op:UX:SMD'], +// }, - { - handler: DBRequirementHandler, - name: 'Database Requirements Node', - // requires: ['op:UX:DATAMAP:DOC'], - }, +// { +// handler: DBRequirementHandler, +// name: 'Database Requirements Node', +// // requires: ['op:UX:DATAMAP:DOC'], +// }, - { - handler: DBSchemaHandler, - name: 'Database Schemas Node', - // requires: ['op:DATABASE_REQ'], - }, +// { +// handler: DBSchemaHandler, +// name: 'Database Schemas Node', +// // requires: ['op:DATABASE_REQ'], +// }, - { - handler: BackendCodeHandler, - name: 'Backend Code Generator Node', - // requires: ['op:DATABASE:SCHEMAS', 'op:UX:DATAMAP:DOC'], - }, - ], - }; +// { +// handler: BackendCodeHandler, +// name: 'Backend Code Generator Node', +// // requires: ['op:DATABASE:SCHEMAS', 'op:UX:DATAMAP:DOC'], +// }, +// ], +// }; - // Initialize the BuilderContext with the defined sequence and environment - executeBuildSequence('backend code geneerate', sequence); - }, - 600000, - ); // Timeout set to 10 minutes - }, -); +// // Initialize the BuilderContext with the defined sequence and environment +// executeBuildSequence('backend code geneerate', sequence); +// }, +// 600000, +// ); // Timeout set to 10 minutes +// }, +// ); diff --git a/backend/src/build-system/__tests__/test.sms-lvl2.spec.ts b/backend/src/build-system/__tests__/test.sms-lvl2.spec.ts index d6c684c6..eab03c18 100644 --- a/backend/src/build-system/__tests__/test.sms-lvl2.spec.ts +++ b/backend/src/build-system/__tests__/test.sms-lvl2.spec.ts @@ -1,55 +1,55 @@ -import { isIntegrationTest } from 'src/common/utils'; -import { PRDHandler } from '../handlers/product-manager/product-requirements-document/prd'; -import { ProjectInitHandler } from '../handlers/project-init'; -import { UXDMDHandler } from '../handlers/ux/datamap'; -import { UXSMDHandler } from '../handlers/ux/sitemap-document'; -import { UXSMSHandler as UXSMSHandler } from '../handlers/ux/sitemap-structure'; -import { UXSMSPageByPageHandler } from '../handlers/ux/sitemap-structure/sms-page'; -import { BuildSequence } from '../types'; -import { executeBuildSequence } from './utils'; +// import { isIntegrationTest } from 'src/common/utils'; +// import { PRDHandler } from '../handlers/product-manager/product-requirements-document/prd'; +// import { ProjectInitHandler } from '../handlers/project-init'; +// import { UXDMDHandler } from '../handlers/ux/datamap'; +// import { UXSMDHandler } from '../handlers/ux/sitemap-document'; +// import { UXSMSHandler as UXSMSHandler } from '../handlers/ux/sitemap-structure'; +// import { UXSMSPageByPageHandler } from '../handlers/ux/sitemap-structure/sms-page'; +// import { BuildSequence } from '../types'; +// import { executeBuildSequence } from './utils'; -(isIntegrationTest ? describe : describe.skip)('Build Sequence Test', () => { - it('should execute build sequence successfully', async () => { - const sequence: BuildSequence = { - id: 'test-backend-sequence', - version: '1.0.0', - name: 'Spotify-like Music Web', - description: 'Users can play music', - databaseType: 'SQLite', - nodes: [ - { - handler: ProjectInitHandler, - name: 'Project Folders Setup', - description: 'Create project folders', - }, +// (isIntegrationTest ? describe : describe.skip)('Build Sequence Test', () => { +// it('should execute build sequence successfully', async () => { +// const sequence: BuildSequence = { +// id: 'test-backend-sequence', +// version: '1.0.0', +// name: 'Spotify-like Music Web', +// description: 'Users can play music', +// databaseType: 'SQLite', +// nodes: [ +// { +// handler: ProjectInitHandler, +// name: 'Project Folders Setup', +// description: 'Create project folders', +// }, - { - handler: PRDHandler, - name: 'Project Requirements Document Node', - }, +// { +// handler: PRDHandler, +// name: 'Project Requirements Document Node', +// }, - { - handler: UXSMDHandler, - name: 'UX Sitemap Document Node', - }, +// { +// handler: UXSMDHandler, +// name: 'UX Sitemap Document Node', +// }, - { - handler: UXSMSHandler, - name: 'UX Sitemap Structure Node', - }, - { - handler: UXDMDHandler, - name: 'UX DataMap Document Node', - }, - { - handler: UXSMSPageByPageHandler, - name: 'Level 2 UX Sitemap Structure Node details', - }, - ], - }; +// { +// handler: UXSMSHandler, +// name: 'UX Sitemap Structure Node', +// }, +// { +// handler: UXDMDHandler, +// name: 'UX DataMap Document Node', +// }, +// { +// handler: UXSMSPageByPageHandler, +// name: 'Level 2 UX Sitemap Structure Node details', +// }, +// ], +// }; - const result = await executeBuildSequence('fullstack-code-gen', sequence); - expect(result.success).toBe(true); - expect(result.metrics).toBeDefined(); - }, 300000); -}); +// const result = await executeBuildSequence('fullstack-code-gen', sequence); +// expect(result.success).toBe(true); +// expect(result.metrics).toBeDefined(); +// }, 300000); +// }); diff --git a/backend/src/build-system/__tests__/virtual-dir.spec.ts b/backend/src/build-system/__tests__/virtual-dir.spec.ts index 51d3dfb6..6533a78a 100644 --- a/backend/src/build-system/__tests__/virtual-dir.spec.ts +++ b/backend/src/build-system/__tests__/virtual-dir.spec.ts @@ -1,52 +1,52 @@ -// TODO: adding virtual dir example here - -import * as fs from 'fs-extra'; -import * as path from 'path'; -import { VirtualDirectory } from '../virtual-dir'; -import { Logger } from '@nestjs/common'; -import { isIntegrationTest } from 'src/common/utils'; - -// TODO: skip for now, some bug here -(isIntegrationTest ? describe : describe.skip)('VirtualDirectory', () => { - const structMdFilePath = path.normalize( - path.join('src', 'build-system', '__tests__'), - ); - - describe('VirtualDirectory', () => { - let virtualDir: VirtualDirectory; - let structMarkdownContent: string; - - beforeEach(() => { - structMarkdownContent = fs.readFileSync(structMdFilePath, 'utf8'); - virtualDir = new VirtualDirectory(); - virtualDir.parseJsonStructure(structMarkdownContent); - }); - - it('should print tree structure', () => { - const files = virtualDir.getAllFiles(); - Logger.log(files); - }); - - // change test path to your current test file - it('should validate existing files', () => { - expect(virtualDir.isValidFile('src/pages/Home/index.tsx')).toBeTruthy(); - expect(virtualDir.isValidFile('nonexistent.ts')).toBeFalsy(); - }); - - it('should validate existing directories', () => { - expect(virtualDir.isValidDirectory('src')).toBeTruthy(); - expect(virtualDir.isValidDirectory('src/components/common')).toBeTruthy(); - expect(virtualDir.isValidDirectory('api')).toBeFalsy(); - expect(virtualDir.isValidDirectory('nonexistent')).toBeFalsy(); - }); - - it('should resolve relative paths correctly', () => { - const resolved = virtualDir.resolveRelativePath( - 'src/components/common/Button/index.tsx', - '../Loader/index.tsx', - ); - expect(virtualDir.isValidFile(resolved)).toBeTruthy(); - expect(resolved).toBe('src/components/common/Loader/index.tsx'); - }); - }); -}); +// // TODO: adding virtual dir example here + +// import * as fs from 'fs-extra'; +// import * as path from 'path'; +// import { VirtualDirectory } from '../virtual-dir'; +// import { Logger } from '@nestjs/common'; +// import { isIntegrationTest } from 'src/common/utils'; + +// // TODO: skip for now, some bug here +// (isIntegrationTest ? describe : describe.skip)('VirtualDirectory', () => { +// const structMdFilePath = path.normalize( +// path.join('src', 'build-system', '__tests__'), +// ); + +// describe('VirtualDirectory', () => { +// let virtualDir: VirtualDirectory; +// let structMarkdownContent: string; + +// beforeEach(() => { +// structMarkdownContent = fs.readFileSync(structMdFilePath, 'utf8'); +// virtualDir = new VirtualDirectory(); +// virtualDir.parseJsonStructure(structMarkdownContent); +// }); + +// it('should print tree structure', () => { +// const files = virtualDir.getAllFiles(); +// Logger.log(files); +// }); + +// // change test path to your current test file +// it('should validate existing files', () => { +// expect(virtualDir.isValidFile('src/pages/Home/index.tsx')).toBeTruthy(); +// expect(virtualDir.isValidFile('nonexistent.ts')).toBeFalsy(); +// }); + +// it('should validate existing directories', () => { +// expect(virtualDir.isValidDirectory('src')).toBeTruthy(); +// expect(virtualDir.isValidDirectory('src/components/common')).toBeTruthy(); +// expect(virtualDir.isValidDirectory('api')).toBeFalsy(); +// expect(virtualDir.isValidDirectory('nonexistent')).toBeFalsy(); +// }); + +// it('should resolve relative paths correctly', () => { +// const resolved = virtualDir.resolveRelativePath( +// 'src/components/common/Button/index.tsx', +// '../Loader/index.tsx', +// ); +// expect(virtualDir.isValidFile(resolved)).toBeTruthy(); +// expect(resolved).toBe('src/components/common/Loader/index.tsx'); +// }); +// }); +// }); diff --git a/backend/src/build-system/handlers/file-manager/file-struct/index.ts b/backend/src/build-system/handlers/file-manager/file-struct/index.ts index 7e8345ec..e2af7cc0 100644 --- a/backend/src/build-system/handlers/file-manager/file-struct/index.ts +++ b/backend/src/build-system/handlers/file-manager/file-struct/index.ts @@ -6,6 +6,7 @@ import { removeCodeBlockFences, extractJsonFromText, formatResponse, + mergePaths, } from 'src/build-system/utils/strings'; import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; import { @@ -33,7 +34,7 @@ export const prompts = { Output Format: Return a JSON object in the following format: - Surround the JSON object with tags. + You must surround the JSON object with tags. { @@ -109,7 +110,7 @@ export const prompts = { switch (projectPart.toLowerCase()) { case 'frontend': roleDescription = 'an expert frontend developer'; - includeSections = ` + includeSections = ` Non-SPA Folder Structure example: src/ contexts/ - Global state management @@ -123,6 +124,7 @@ export const prompts = { index.tsx - Main entry point that imports Home page pages/ Home/ + index.tsx - Contains ALL component code and application logic For SPAs, you MUST use exactly this structure - no variations allowed.` @@ -236,12 +238,12 @@ Output Format: return `Your task is to analyze the given project directory structure and create a detailed JSON object mapping file dependencies. The output JSON must be precisely formatted and wrapped in tags. -### Instructions +# Instructions ${ isSPAFlag ? `**SPA Special Case**: - - If the structure only contains src/index.tsx and src/pages/Home/index.tsx, this is a Single Page Application (SPA) with the mandatory minimal structure. + - If the structure only contains src/index.tsx and src/pages/Home/index.tsx this is a Single Page Application (SPA) with the mandatory minimal structure. - For SPAs with this exact structure, the JSON must look like this: \`\`\`json @@ -257,9 +259,13 @@ Output Format: } \`\`\` + + - IMPORTANT EXCEPTION FOR UI COMPONENTS: + - Even in SPA mode, shadcn UI component dependencies ARE ALLOWED and SHOULD be added + - For the Home page, add appropriate shadcn UI dependencies from the available file structure - This is MANDATORY: for SPAs, create exactly these two files with exactly these dependencies - no more, no less. -**For non-SPA projects**: ` +## For non-SPA projects: ` : 'For projects' } - Analyze the directory structure to identify all files and folders. @@ -269,7 +275,7 @@ Output Format: - Identify direct dependencies for each file by considering typical imports based on roles, naming conventions, and the provided analysis. - For context files, ensure they are properly referenced in index.tsx or router.tsx, as contexts typically need to be provided at a high level in the application. -3. **Generate File Dependency JSON**: +## Generate File Dependency JSON: - Each file must be represented using its full path starting from src/. - Ensure dependencies are strictly limited to files in the "Paths" array. - Use absolute file paths from "Paths" for all "dependsOn" values. @@ -280,16 +286,54 @@ Output Format: - Organize the output in a \`files\` object where keys are file paths, and values are their dependency objects. - For the router, remember to include all the page components as dependencies, as the router imports them to define the application routes. -4. **Output Requirements**: +## UI Component Dependencies: + - This project uses the shadcn UI component library. + - Components that likely need UI elements (forms, buttons, inputs, etc.) should include appropriate shadcn component dependencies. + - Shadcn components are imported with the syntax @/components/ui/[component-name].tsx + - Analyze component purposes carefully to determine which shadcn components they should depend on + - Examples: + - A data table component should depend on table.tsx + - A navigation component with dropdowns should depend on dropdown-menu.tsx + +## Balanced Dependency Approach: + - Most components should have 1-3 relevant UI dependencies + - Complex components (like forms or tables) may have more + - Simple components may have just one or even none + +## Global Components Usage: + - Consider how global components are used across pages. + - Global components (like navigation bars, footers, layouts) should be dependencies for all page components. + - For example, a Nav component should be included as a dependency for all page files. + - Ensure these global components are properly represented in the dependency tree for all relevant pages. + +## CRITICAL: STRICT DEPENDENCY VALIDATION + +1. Allowlist-Only Approach: + - Create an internal allowlist containing ONLY the exact file paths from the provided file structure + - EVERY dependency MUST EXACTLY match one of the paths in this allowlist + - NO EXCEPTIONS: If a logical UI component doesn't exist in the allowlist, DO NOT ADD IT + +2. Verification Process: + - After generating each file's dependencies, VERIFY each dependency against the allowlist + - If any dependency is not in the allowlist, REMOVE it immediately + - For UI components, ONLY use paths that are EXACTLY as listed in the file structure + +3. **Before Generating Output**: + - Perform a final validation pass to ensure EVERY dependency exists in the allowlist + - Remove ANY dependencies that don't have an exact match in the file structure + +This is mission-critical: The system will reject ANY file references that don't exactly match the provided structure. + +## Output Requirements: - The JSON object must strictly follow this structure: \`\`\`json { "files": { - "src/path/to/file1": { + "src/index.tsx": { "dependsOn": ["src/path/to/dependency1", "src/path/to/dependency2"] }, - "src/path/to/file2": { + "src/path/to/file1": { "dependsOn": [] } } @@ -301,14 +345,19 @@ Output Format: All dependencies must exist in the "Paths" array. No inferred or assumed files should be added. - Wrap the JSON output with \`\` tags. -### Notes + +## Notes - The \`dependsOn\` field should reflect logical dependencies inferred from both the directory structure and the page-by-page analysis. - Use common project patterns to deduce dependencies (e.g., pages depend on components, contexts, hooks, and styles). - Include all files in the output, even if they have no dependencies. - For context providers, ensure they are included as dependencies in either index.tsx or router.tsx to maintain proper context hierarchy in the React application. +- Global components like navigation bars should appear as dependencies in all page components. - Include all files in the output, even if they have no dependencies. -### Output +## Validation Step +Before finalizing, verify each UI component dependency against the complete list of available UI components. Remove any dependency that doesn't have an exact match in the file structure. + +## Output Return only the JSON object wrapped in \`\` tags. Do not forget tags. `; @@ -349,6 +398,14 @@ export class FileStructureAndArchitectureHandler }; } + // Calculate isSPA flag based on sitemap + const pageViewCount = (sitemapDoc.match(/page_view_/g) || []).length; + const isSPAFlag = pageViewCount === 1; + + this.logger.log(`Is SPA: ${isSPAFlag}`); + + context.setGlobalContext('isSPAFlag', isSPAFlag); + const fileStructPrompt = prompts.generateCommonFileStructurePrompt( projectName, sitemapDoc, @@ -457,6 +514,22 @@ export class FileStructureAndArchitectureHandler }; } + let added_structure = ''; + try { + added_structure = mergePaths(fileStructureJsonContent); + if (!added_structure) { + this.logger.error('Failed to add directory.' + added_structure); + throw new ResponseParsingError('Failed to add directory.'); + } + } catch (error) { + return { + success: false, + error: new ResponseParsingError( + `Failed to add directory. ${error.message}`, + ), + }; + } + context.virtualDirectory.getAllFiles().forEach((file) => { this.logger.log(file); }); @@ -466,7 +539,7 @@ export class FileStructureAndArchitectureHandler this.logger.log('Generating File Architecture Document...'); this.virtualDir = context.virtualDirectory; - const fileStructure = removeCodeBlockFences(fileStructureContent); + const fileStructure = removeCodeBlockFences(added_structure); if (!fileStructure || !datamapDoc) { return { success: false, @@ -552,12 +625,17 @@ export class FileStructureAndArchitectureHandler } if (!this.validateJsonData(jsonData)) { - this.logger.error('File architecture JSON validation failed.'); + this.logger.error( + 'File architecture JSON validation failed.', + fileArchContent, + ); throw new ResponseParsingError( 'File architecture JSON validation failed.', ); } + this.logger.debug(fileArchContent); + const { nodes } = buildDependencyGraph(jsonData); invalidFiles = validateAgainstVirtualDirectory(nodes, this.virtualDir); if (invalidFiles) { @@ -598,11 +676,21 @@ export class FileStructureAndArchitectureHandler } } + /** + * Validates the structure and content of the JSON data. + * @param jsonData The JSON data to validate. + * @returns A boolean indicating whether the JSON data is valid. + */ private validateJsonData(jsonData: { files: Record; }): boolean { const validPathRegex = /^[a-zA-Z0-9_\-/.]+$/; + const shouldIgnore = (filePath: string) => { + // this.logger.log(`Checking if should ignore: ${filePath}`); + return filePath.startsWith('@/components/ui/'); + }; + for (const [file, details] of Object.entries(jsonData.files)) { if (!validPathRegex.test(file)) { this.logger.error(`Invalid file path: ${file}`); @@ -610,6 +698,10 @@ export class FileStructureAndArchitectureHandler } for (const dependency of details.dependsOn) { + if (shouldIgnore(dependency)) { + continue; + } + if (!validPathRegex.test(dependency)) { this.logger.error( `Invalid dependency path "${dependency}" in file "${file}".`, diff --git a/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts b/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts index 3b5035ec..8f6f1396 100644 --- a/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts +++ b/backend/src/build-system/handlers/frontend-code-generate/CodeReview.ts @@ -17,7 +17,10 @@ import { readFileSync } from 'fs'; import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; import { createFileWithRetries } from 'src/build-system/utils/files'; import { BuilderContext } from 'src/build-system/context'; -import { removeCodeBlockFences } from 'src/build-system/utils/strings'; +import { + parseGenerateTag, + removeCodeBlockFences, +} from 'src/build-system/utils/strings'; import { generateCommonErrorPrompt, generateFileOperationPrompt, @@ -227,7 +230,7 @@ export class FrontendQueueProcessor { }, { role: 'assistant', - content: `Let me check my result and I must follow the output format.`, + content: `Let me check my result and I must follow the output format I shouldn't write explain outside the json.`, }, ], }, @@ -238,11 +241,8 @@ export class FrontendQueueProcessor { this.logger.debug('Fix Response: ' + fixResponse); this.logger.debug('dependency file Paths ' + task.dependenciesPath); const parsed_fixResponse = removeCodeBlockFences(fixResponse); - - let operations = fileOperationManager.parse( - parsed_fixResponse, - task.filePath, - ); + const cleaned_Data = parseGenerateTag(parsed_fixResponse); + let operations = fileOperationManager.parse(cleaned_Data, task.filePath); // **If LLM requested additional files, read them** if (operations.some((op) => op.action === 'read')) { @@ -307,7 +307,7 @@ export class FrontendQueueProcessor { }, { role: 'assistant', - content: `Let me check my result and I must follow the output format`, + content: `Let me check my result and I must follow the output format I shouldn't write explain outside the json`, }, ], }, diff --git a/backend/src/build-system/handlers/frontend-code-generate/index.ts b/backend/src/build-system/handlers/frontend-code-generate/index.ts index 8a13f3ee..502c568f 100644 --- a/backend/src/build-system/handlers/frontend-code-generate/index.ts +++ b/backend/src/build-system/handlers/frontend-code-generate/index.ts @@ -13,7 +13,7 @@ import { BuildNode, BuildNodeRequire } from 'src/build-system/hanlder-manager'; import normalizePath from 'normalize-path'; import path from 'path'; import { generateCSSPrompt, generateFrontEndCodePrompt } from './prompt'; -import { formatResponse } from 'src/build-system/utils/strings'; +import { removeCodeBlockFences } from 'src/build-system/utils/strings'; import { writeFileSync } from 'fs'; import { MessageInterface } from 'src/common/model-provider/types'; @@ -21,7 +21,8 @@ import { FrontendCodeValidator } from './CodeValidator'; import { FrontendQueueProcessor, CodeTaskQueue } from './CodeReview'; // import { FileFAHandler } from '../file-manager/file-arch'; import { FileStructureAndArchitectureHandler } from '../file-manager/file-struct'; - +import { PRDHandler } from '../product-manager/product-requirements-document/prd'; +import { UIUXLayoutHandler } from '../ux/uiux-layout'; interface FileInfos { [fileName: string]: { dependsOn: string[]; @@ -36,6 +37,8 @@ interface FileInfos { @BuildNodeRequire([ UXSMSHandler, UXDMDHandler, + PRDHandler, + UIUXLayoutHandler, BackendRequirementHandler, FileStructureAndArchitectureHandler, ]) @@ -56,6 +59,9 @@ export class FrontendCodeHandler implements BuildHandler { // 1. Retrieve the necessary input from context const sitemapStruct = context.getNodeData(UXSMSHandler); const uxDataMapDoc = context.getNodeData(UXDMDHandler); + const prdHandler = context.getNodeData(PRDHandler); + const uiUXLayoutHandler = context.getNodeData(UIUXLayoutHandler); + // const prdHandler = context.getGlobalContext('projectOverview'); const backendRequirementDoc = context.getNodeData( BackendRequirementHandler, ); @@ -83,9 +89,19 @@ export class FrontendCodeHandler implements BuildHandler { const renameMap = new Map(); // 3. Prepare for Dependency + // have bug const { concurrencyLayers, fileInfos } = await generateFilesDependencyWithLayers(fileArchDoc, this.virtualDir); + // concurrencyLayers.forEach((layer, index) => { + // console.log(`Layer #${index + 1} has ${layer.length} file(s):`, layer); + // }); + + // Object.entries(fileInfos).forEach(([filePath, info]) => { + // this.logger.debug(`File: ${filePath}`); + // this.logger.debug(`Depends On: ${info.dependsOn.join(', ')}`); + // }); + const validator = new FrontendCodeValidator(frontendPath); // validator.installDependencies(); @@ -160,8 +176,8 @@ export class FrontendCodeHandler implements BuildHandler { file, dependenciesText, directDepsPathString, - sitemapStruct, - uxDataMapDoc, + uiUXLayoutHandler, + prdHandler, failedFiles, ); } @@ -229,7 +245,19 @@ export class FrontendCodeHandler implements BuildHandler { for (const dep of directDepsArray) { try { - const resolvedDepPath = normalizePath(path.resolve(frontendPath, dep)); + let resolvedDepPath = dep; + + // Resolve alias-based paths (assuming `@/` maps to `frontendPath/src/`) + if (dep.startsWith('@/')) { + resolvedDepPath = path.join( + frontendPath, + 'src', + dep.replace(/^@\//, ''), + ); + } else { + resolvedDepPath = normalizePath(path.resolve(frontendPath, dep)); + } + const depContent = await readFileWithRetries(resolvedDepPath, 3, 200); dependenciesText += `\n\n File path: ${dep}\n\`\`\`typescript\n${depContent}\n\`\`\`\n`; } catch (err) { @@ -249,8 +277,8 @@ export class FrontendCodeHandler implements BuildHandler { file: string, dependenciesText: string, directDepsPathString: string, - sitemapStruct: string, - uxDataMapDoc: string, + uiUXLayoutHandler: string, + productRe: string, failedFiles: any[], ): Promise { let generatedCode = ''; @@ -259,6 +287,8 @@ export class FrontendCodeHandler implements BuildHandler { try { const fileExtension = path.extname(file); + const isSPAFlag = context.getGlobalContext('isSPAFlag'); + let frontendCodePrompt = ''; if (fileExtension === '.css') { frontendCodePrompt = generateCSSPrompt(file, directDepsPathString); @@ -282,8 +312,12 @@ export class FrontendCodeHandler implements BuildHandler { }, { role: 'user' as const, - content: `## Sitemap Structure - ${sitemapStruct} + content: `## product requirement + ${productRe} + + ## project layout + ${uiUXLayoutHandler} + `, }, // To DO need to dynamically add the UX Datamap Documentation and Backend Requirement Documentation based on the file generate @@ -319,7 +353,7 @@ export class FrontendCodeHandler implements BuildHandler { }, { role: 'user', - content: `Now you can provide the code, don't forget the tags. Do not be lazy.`, + content: `Now you can provide the code. Do not be lazy.`, }, // { // role: 'assistant', @@ -331,8 +365,9 @@ export class FrontendCodeHandler implements BuildHandler { modelResponse = await chatSyncWithClocker( context, { - // model: context.defaultModel || 'gpt-4o', - model: 'o3-mini-high', + model: isSPAFlag + ? 'claude-3.7-sonnet' // Use Claude for SPAs + : 'o3-mini-high', // Use default or fallback for non-SPAs messages, }, 'generate frontend code', @@ -340,7 +375,7 @@ export class FrontendCodeHandler implements BuildHandler { ); this.logger.debug('generated code: ', modelResponse); - generatedCode = formatResponse(modelResponse); + generatedCode = removeCodeBlockFences(modelResponse); return generatedCode; } catch (err) { diff --git a/backend/src/build-system/handlers/frontend-code-generate/prompt.ts b/backend/src/build-system/handlers/frontend-code-generate/prompt.ts index f023a926..955faf4d 100644 --- a/backend/src/build-system/handlers/frontend-code-generate/prompt.ts +++ b/backend/src/build-system/handlers/frontend-code-generate/prompt.ts @@ -3,7 +3,7 @@ export function generateFrontEndCodePrompt( dependencyFilePath: string, theme: string, ): string { - return `Role: You are an expert frontend developer specializing in building scalable, maintainable, and production-ready React applications using TypeScript. + return `Role: You are an expert frontend developer specializing in building scalable, maintainable, and production-ready React applications using TypeScript. Task: Generate complete, type-safe, and maintainable React code. Current File: ${currentFile}. @@ -26,18 +26,101 @@ ${theme} 10. Mock the response if the API returns an empty or undefined value, and you don't need to explicitly show that it is mock data. 11. Write EVERY CODE DETAIL, DON'T LEAVE TODO. 12. Image Assets: If your implementation requires any images except some button logo, you can use placeholder image URLs from https://picsum.photos//. Note that the width and height values (e.g., 500/300) are adjustable as needed. + 13. RESPONSIVE DESIGN: Ensure all components are fully responsive: + - The main container and all top-level components MUST use responsive design principles + - Use responsive prefixes (sm:, md:, lg:, xl:, 2xl:) for breakpoints + - Use flex or grid layouts with appropriate responsive settings + - Ensure text is readable across all device sizes + 14. Visual Design: + - Experiment with different font choices where appropriate using Tailwind's font-family classes + - Use varying font weights and sizes to create visual hierarchy + - Consider using gradients, shadows, and other visual elements to enhance the UI + 15. Icons and Visual Elements: + - Use Lucide icons where appropriate (import from 'lucide-react') + - Choose icons that match the context and purpose of UI elements + - Ensure icons have appropriate sizes and colors that match the overall design + - Consider using icons for navigation, actions, and status indicators + - When user requirements are highly specific, use appropriate specific icons from the Lucide library instead of generic logos + 16. Animations: + - Consider adding subtle animations in appropriate places to enhance user experience + - Framer Motion is available if needed, but use it judiciously - not every component needs animation, might be core element + - Good candidates for animation: page transitions, hover effects, expanding/collapsing elements + - Keep animations subtle and purposeful - avoid excessive or distracting animations + - IMPORTANT: When using Framer Motion transitions or animations, especially for page transitions: + - Implement a scroll-to-top mechanism when components mount or pages change + - Use the useEffect hook with window.scrollTo(0, 0) to ensure the page starts at the top + - For route changes, consider adding scrollRestoration logic + - Example implementation: + \`\`\` + useEffect(() => { + window.scrollTo(0, 0); + }, []); + \`\`\` + - For route-based applications, implement this in route change handlers or consider using a wrapper component + - Test scroll position after animations to ensure users always start at the top of new content + 17. Component Organization: + - Avoid repeating complex components of the same type within a file + - For complex components (not basic UI elements like buttons or inputs), create reusable components with props to handle variations + - If multiple instances of similar complex components are needed, implement a single component that accepts different props or use a mapping function + - Extract repeated patterns into helper functions or custom hooks + 18. Typography and Font Access Rules: + - When Typography specifications are provided in the theme (e.g., "Headings: 'Roboto Mono'"), use the corresponding CSS variable format + - Font access pattern: Convert the font name to kebab-case with a "font-" prefix + - For example: + - "Roboto Mono" should be accessed as "font-roboto-mono" + - "Open Sans" should be accessed as "font-open-sans" + - Use these variables in your Tailwind classes like: className="font-roboto-mono" + - Follow size specifications exactly as provided in the theme + - For special UI elements like terminals that specify a certain font, make sure to apply that font specifically to those elements + - Example mapping: + - If theme specifies: + Typography: + - Headings: "Roboto Mono" + - Body: "Open Sans" + - Special Elements: "Roboto Mono" for terminal interactions + - Then implement as: + - Headings: className="font-roboto-mono text-3xl" (or appropriate size) + - Body text: className="font-open-sans text-base" + - Terminal elements: className="font-roboto-mono text-sm" + 19. Provider Structure and Organization: + - When implementing the application's provider structure, ensure proper nesting order + - Router (react-router) should be positioned as the outermost provider in the application + - All Context Providers (such as ThemeProvider, AuthProvider, etc.) should be wrapped inside the Router + - This structure ensures routing functionality is available to all providers and components + - The recommended pattern is: + \`\`\` + + + + + + + + + + \`\`\` + - This organization ensures that routing information and navigation is available throughout the entire provider hierarchy + 20. Shadcn/UI Components + - Import and implement shadcn/ui components following their documentation patterns + - Example import pattern: + import { Button } from "@/components/ui/button"; + import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; + - Correctly use shadcn component variants and sizes (e.g., variant="outline" or size="sm") + 21. In TypeScript, when using backticks (\`\`) or quotes, remember to use a backslash (\\) to escape special characters like < or variables. ## Library: "react-router": "^6", "react": "^18", - "@tailwindcss/vite": "^4.0.0" + "@tailwindcss": "^4.0.0" + shadcn/ui components + Lucide React icons + Framer Motion + Recharts (for data visualization) + React Hook Form (for forms) + Zod (for validation) ## Output Format: - Output your final code wrapped in tags ONLY, like: - - - ...full code... - + Output your final code wrapped code fense. Do not write otherthings outside code fense `; } @@ -46,29 +129,138 @@ export function generateCSSPrompt( directDependencies: string, ): string { return ` - You are an expert CSS developer. Generate valid, production-ready CSS for the file "${fileName}". + You are an expert CSS developer specializing in modern, scalable, and maintainable CSS. +Your task is to **enhance** "\${fileName}" while ensuring the following key requirements: + +## **Package Information** +This project uses: +- "@tailwindcss/vite": "^4.0.0" +- ShadCN for UI components + +## **🚀 Purpose** +The following is the **current default** \`index.css\`. Your task is to **optimize and enhance it** without changing its core structure. The goal is to improve styling while *keeping all existing configurations intact. + +## **📜 Rules & Guidelines** +1. **Preserve All Existing Styles & Structure** + - Do **NOT** remove or replace any existing CSS variables. + - Do **NOT** override or discard the current ShadCN-compatible color palette. + +2. **Strictly CSS-Only** + - No JavaScript, React, or any non-CSS content. + +3. **Enhance, Don’t Replace** + - Keep all original Tailwind imports, plugins, and ShadCN compatibility. + - Improve maintainability while ensuring **the output is a strict upgrade**. + +4. **No Unnecessary Additions** + - Do **NOT** introduce random components (e.g., \`.interactive-terminal\`, \`.about-me\`). + - This file is meant for **global styles only**, not component-specific styles. + +5. **Logical Organization (Maintain These Sections)** + - **Imports & Plugins**: Tailwind setup (\`@import "tailwindcss";\`). + - **CSS Variables & Theming**: \`:root\`, \`.dark\`, \`@theme inline\`. + - **Base Styles & Utility Enhancements**: \`@layer base\` optimizations. + - **Custom Animations**: Maintain \`@keyframes\` but optimize where needed. + +6. **Performance Optimizations** + - Ensure **minimal overrides**. + - Use **only valid Tailwind utility classes** (e.g., replace deprecated classes like \`bg-opacity-50\` with \`bg-black/50\`). + - Keep **CSS concise** and **reduce redundancy**. + +7. **Ensure Dark Mode Functions Correctly** + - Maintain proper contrast between **dark mode (\`.dark\`) and light mode (\`:root\`)**. + - Do **not** blindly invert colors. + +8. **Comment Where Necessary** + - Provide **brief, meaningful comments** for key changes. + +## **📝 Output Format** +Generate the **updated** CSS using the format below: + + +@import "tailwindcss"; +@plugin "tailwindcss-animate"; + +/* Custom Dark Mode Variant */ +@custom-variant dark (&:is(.dark *)); + +/* Theme Colors & Variables */ +:root { + --background: hsl(0 0% 100%); + --foreground: hsl(0 0% 3.9%); + --card: hsl(0 0% 100%); + --card-foreground: hsl(0 0% 3.9%); + --primary: hsl(0 0% 9%); + --primary-foreground: hsl(0 0% 98%); + --secondary: hsl(0 0% 96.1%); + --secondary-foreground: hsl(0 0% 9%); + --muted: hsl(0 0% 96.1%); + --muted-foreground: hsl(0 0% 45.1%); + --border: hsl(0 0% 89.8%); + --ring: hsl(0 0% 3.9%); + --radius: 0.6rem; +} - ## Context - - Sitemap Strucutrue: - - UX Datamap Documentation: +.dark { + --background: hsl(0 0% 3.9%); + --foreground: hsl(0 0% 98%); + --card: hsl(0 0% 3.9%); + --card-foreground: hsl(0 0% 98%); + --primary: hsl(0 0% 98%); + --primary-foreground: hsl(0 0% 9%); + --secondary: hsl(0 0% 14.9%); + --secondary-foreground: hsl(0 0% 98%); + --muted: hsl(0 0% 14.9%); + --muted-foreground: hsl(0 0% 63.9%); + --border: hsl(0 0% 14.9%); + --ring: hsl(0 0% 83.1%); +} - - Direct Dependencies (if any and may include references to other styles or partials): - ${directDependencies} +/* Inline Theming */ +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-border: var(--border); + --color-ring: var(--ring); + --radius-sm: calc(var(--radius) - 4px); + --radius-lg: calc(var(--radius) + 4px); + --animate-accordion-down: accordion-down 0.2s ease-out; + --animate-accordion-up: accordion-up 0.2s ease-out; +} - - Direct Dependencies Context: +/* Custom Animations */ +@keyframes accordion-down { + from { height: 0; } + to { height: var(--radix-accordion-content-height); } +} + +@keyframes accordion-up { + from { height: var(--radix-accordion-content-height); } + to { height: 0; } +} - ## Rules & Guidelines - 1. **Do NOT** include any JavaScript or React code—only plain CSS. - 2. **Do NOT** wrap your output in code fences (\`\`\`). - 3. You may define classes, IDs, or any selectors you need, but **be sure** to keep it purely CSS. - 4. Ensure the output is well-structured, readable, and adheres to best practices (e.g., BEM if you prefer). - 5. Include comments for clarity if needed, but keep them concise. +/* Base Styles & Utility Enhancements */ +@layer base { + * { + @apply outline-[var(--ring)]/50; /* Keep outlines but avoid forced borders */ + } - ## Output Format - Please produce the complete CSS content in the format described: - - /* Your CSS content here */ - + body { + @apply bg-background text-foreground; + } +} + + +Ensure your output **only enhances the original file** without unnecessary changes. + `; } @@ -169,6 +361,7 @@ Available operations: Not assignable to parameter of type → Use the READ tool if you dont have enough information to fix. **Output format:** +Return only the JSON object wrapped in \`\` tags. To keep the structure consistent, other operations remain single-action: 1. Read File @@ -204,6 +397,8 @@ If a file needs to be renamed: } } } + +Do not forget tags. `; } diff --git a/backend/src/build-system/handlers/product-manager/product-requirements-document/prd.ts b/backend/src/build-system/handlers/product-manager/product-requirements-document/prd.ts index 3d79aea1..25f36afc 100644 --- a/backend/src/build-system/handlers/product-manager/product-requirements-document/prd.ts +++ b/backend/src/build-system/handlers/product-manager/product-requirements-document/prd.ts @@ -48,6 +48,33 @@ export class PRDHandler implements BuildHandler { // Send the prompt to the LLM server and process the response const prdContent = await this.generatePRDFromLLM(context, prompt); + // Extract the "Project Overview" section + const projectOverview = this.extractProjectOverviewSection(prdContent); + + // Extract the "Features" section + const features = this.extractFeaturesSection(prdContent); + + // Set the extracted overview to a global context variable + if (projectOverview) { + context.setGlobalContext('projectOverview', projectOverview); + this.logger.log( + 'Project Overview extracted and set to global context', + projectOverview, + ); + } else { + this.logger.warn('Could not extract Project Overview section'); + } + + if (features) { + context.setGlobalContext('projectFeatures', features); + this.logger.log( + 'Features section extracted and set to global context', + features, + ); + } else { + this.logger.warn('Could not extract Features section'); + } + if (!prdContent || prdContent.trim() === '') { throw new ResponseParsingError('Generated PRD content is empty.'); } @@ -87,4 +114,65 @@ export class PRDHandler implements BuildHandler { throw new ModelUnavailableError('Model is unavailable: ' + error); } } + + /** + * Extracts a specific section from the PRD content by section title + * @param prdContent The full PRD content + * @param sectionNumber The section number (e.g., "1" for "#### 1. Project Overview") + * @param sectionTitle The section title (e.g., "Project Overview") + * @returns The extracted section content or null if not found + */ + private extractSection( + prdContent: string, + sectionNumber: string, + sectionTitle: string, + ): string | null { + try { + // Define regex pattern to match the specified section + // This pattern matches from "#### [sectionNumber]. [sectionTitle]" until the next "####" heading + const pattern = new RegExp( + `#### ${sectionNumber}\\.\\s*${sectionTitle}([\\s\\S]*?)(?=####|$)`, + ); + const match = prdContent.match(pattern); + + if (match && match[1]) { + // Trim the extracted content to remove leading/trailing whitespace + return match[1].trim(); + } + + // If no match found, try an alternative approach with just the title + const simplifiedPattern = new RegExp( + `#### (?:${sectionNumber}\\.)?\\s*${sectionTitle}([\\s\\S]*?)(?=####|$)`, + ); + const simplifiedMatch = prdContent.match(simplifiedPattern); + + if (simplifiedMatch && simplifiedMatch[1]) { + return simplifiedMatch[1].trim(); + } + + this.logger.warn(`Could not find ${sectionTitle} section in PRD content`); + return null; + } catch (error) { + this.logger.error(`Error extracting ${sectionTitle} section:`, error); + return null; + } + } + + /** + * Extracts the "Project Overview" section from the PRD content + * @param prdContent The full PRD content + * @returns The extracted project overview section or null if not found + */ + private extractProjectOverviewSection(prdContent: string): string | null { + return this.extractSection(prdContent, '1', 'Project Overview'); + } + + /** + * Extracts the "Features" section from the PRD content + * @param prdContent The full PRD content + * @returns The extracted features section or null if not found + */ + private extractFeaturesSection(prdContent: string): string | null { + return this.extractSection(prdContent, '5', 'Features'); + } } diff --git a/backend/src/build-system/handlers/ux/sitemap-document/prompt.ts b/backend/src/build-system/handlers/ux/sitemap-document/prompt.ts index 8d6e6477..6c4adf09 100644 --- a/backend/src/build-system/handlers/ux/sitemap-document/prompt.ts +++ b/backend/src/build-system/handlers/ux/sitemap-document/prompt.ts @@ -100,6 +100,12 @@ export const prompts = { 4. Theme Analysis - Analyze any design theme indicated in the product requirements document. - Include details on color palette, typography, and visual style. + - Color Palette: + - Primary: [Primary color with hex code] + - Secondary: [Secondary color with hex code] + - Accent: [Accent color with hex code] + - Background: [Background color with hex code] + - Text: [Text color with hex code] - Specify exact color codes and font sizes. - you must explain why choices were made base on user's project name and description. - please provide a brief explanation of the theme and how it aligns with the project's goals. diff --git a/backend/src/build-system/handlers/ux/uiux-layout/index.ts b/backend/src/build-system/handlers/ux/uiux-layout/index.ts new file mode 100644 index 00000000..acbe275d --- /dev/null +++ b/backend/src/build-system/handlers/ux/uiux-layout/index.ts @@ -0,0 +1,101 @@ +import { BuildHandler, BuildResult } from 'src/build-system/types'; +import { BuilderContext } from 'src/build-system/context'; +import { prompts } from './prompt'; +import { Logger } from '@nestjs/common'; +import { removeCodeBlockFences } from 'src/build-system/utils/strings'; +import { chatSyncWithClocker } from 'src/build-system/utils/handler-helper'; +import { MessageInterface } from 'src/common/model-provider/types'; +import { + MissingConfigurationError, + ModelUnavailableError, + ResponseParsingError, +} from 'src/build-system/errors'; +import { BuildNode, BuildNodeRequire } from 'src/build-system/hanlder-manager'; +import { UXSMSHandler } from '../sitemap-structure'; +import { PRDHandler } from '../../product-manager/product-requirements-document/prd'; + +/** + * UXSMS: UX Sitemap Structure + **/ + +@BuildNode() +@BuildNodeRequire([UXSMSHandler, PRDHandler]) +export class UIUXLayoutHandler implements BuildHandler { + private readonly logger = new Logger('UIUXLayoutHandler'); + + async run(context: BuilderContext): Promise> { + this.logger.log('Generating UX UX Layout Document...'); + + // Extract relevant data from the context + const projectName = + context.getGlobalContext('projectName') || 'Default Project Name'; + + const sitemapDoc = context.getNodeData(UXSMSHandler); + const prd = context.getNodeData(PRDHandler); + + const platform = context.getGlobalContext('platform') || 'Default Platform'; + + // Validate required parameters + if (!projectName || typeof projectName !== 'string') { + throw new MissingConfigurationError('Missing or invalid projectName.'); + } + if (!sitemapDoc || typeof sitemapDoc !== 'string') { + throw new MissingConfigurationError( + 'Missing or invalid sitemap document.', + ); + } + + const prompt = prompts.generateUIUXLayoutPrompt(); + + const messages: MessageInterface[] = [ + { + role: 'system', + content: prompt, + }, + { + role: 'user', + content: ` + here is the product requirement Doc: + ${prd} + + Here is the UX Sitemap Documentation (SMD): + + ${sitemapDoc} + + Please generate the layout now`, + }, + { + role: 'user', + content: `Check if you covered all major pages, user flows.`, + }, + ]; + + try { + const uxStructureContent = await chatSyncWithClocker( + context, + { + // model: context.defaultModel || 'gpt-4o-mini', + model: 'claude-3.7-sonnet', + messages, + }, + 'generateUIUXLayout', + UIUXLayoutHandler.name, + ); + + if (!uxStructureContent || uxStructureContent.trim() === '') { + this.logger.error('Generated UX Sitemap Structure content is empty.'); + throw new ResponseParsingError( + 'Generated UX Sitemap Structure content is empty.', + ); + } + + this.logger.log('Successfully generated UX Sitemap Structure content.'); + return { + success: true, + data: removeCodeBlockFences(uxStructureContent), + }; + } catch (error) { + throw new ModelUnavailableError('Model is unavailable: ' + error); + } + } +} diff --git a/backend/src/build-system/handlers/ux/uiux-layout/prompt.ts b/backend/src/build-system/handlers/ux/uiux-layout/prompt.ts new file mode 100644 index 00000000..55e4ea50 --- /dev/null +++ b/backend/src/build-system/handlers/ux/uiux-layout/prompt.ts @@ -0,0 +1,386 @@ +export const prompts = { + // To do add linking view relation like how each page is been connected + generateUIUXLayoutPrompt: (): string => { + return `Role & Objective +You are a senior UX designer tasked with creating optimal page layouts based on project requirements and sitemap information. Your goal is to develop a comprehensive layout strategy that ensures: + +Intuitive user navigation and interaction +Effective content hierarchy and organization +Visual appeal aligned with brand identity +Responsive design across all devices +Maximum conversion potential + +Project Information +[Insert brief project description here including target audience, business goals, and unique requirements] +Required Deliverables +0. Global Component System +Before detailing individual pages, define the global components that will appear consistently across the entire site: + +Header/Navigation System: Structure, elements, and behavior +Footer: Content organization and hierarchy +Reusable UI Components: Buttons, cards, forms, modals, etc. +Global Design Elements: Color application, typography implementation, spacing guidelines + +1. Sitemap Analysis +Based on the provided sitemap documentation: + +Review and categorize all pages in the sitemap +Identify each page's purpose and primary user objectives +Map user flows between interconnected pages +Determine content hierarchy and information architecture +Note any critical interactions or conversion points + +For each page type identified in the sitemap, provide a brief functional summary including: + +Primary user goals +Key content requirements +Critical interactions +Success metrics + +Example format: +Copy[PAGE TYPE]: [Brief description of purpose] +- Primary User Goals: [What users expect to accomplish] +- Key Content: [Essential content elements] +- Critical Interactions: [Important user actions] +- Relationship to Other Pages: [How this page connects to others] + +2. Layout Recommendations +For each page, provide: + +Recommended Layout Pattern: Choose from the layout library below +Justification: Explain why this layout best serves the page's purpose +Key Components: List essential UI elements and their placement +Global Component Integration: How global components (header, footer, etc.) integrate with this specific page layout +Responsive Behavior: How the layout adapts across breakpoints + +Example format: +CopyHOMEPAGE + Layout: Hero Section + Card Grid + Justification: Creates immediate brand impact while showcasing multiple product categories + Key Components: + - Full-width hero with primary CTA above the fold + - 3-column product category grid (2-column on tablet, 1-column on mobile) + - Social proof section with customer testimonials + - Newsletter signup before footer + Global Component Integration: + - Standard header with transparent background transitioning to solid on scroll + - Simplified mega-menu showing all primary categories + - Full-width footer with all standard sections + - Floating CTA button appears after scrolling past hero section + +3. Global Components & Navigation Strategy + Global Components Implementation + + Header/Navigation Bar: Consistent implementation across all pages + + Structure and elements (logo, menu items, search, account access) + Behavior on scroll (fixed, sticky, collapsing) + Responsive adaptations + + Footer: Standard implementation across the site + + Content sections (sitemap, contact info, legal, newsletter) + Visual hierarchy and organization + Mobile presentation + + Shared UI Elements: Components appearing on multiple pages + Call-to-action buttons (styling, placement consistency) + Alert/notification system + Cookie consent/privacy notices + Chat/support widgets + +Navigation Strategy + + Navigation Type: [Horizontal, vertical, hamburger, etc.] + Information Architecture: How content hierarchy is reflected + Wayfinding Elements: Breadcrumbs, progress indicators, etc. + Search Implementation: Placement and functionality + +4. Interaction Design Notes + + Micro-interactions: Key hover/click behaviors + Scrolling Strategy: Standard, parallax, or specialized scrolling + Transition Effects: Page-to-page and within-page animations + Loading States: How content appears during page loads + +5. Accessibility Considerations + + Navigation Accessibility: Keyboard navigation, screen reader support + Content Hierarchy: How semantic structure supports accessibility + Visual Accessibility: Color contrast, text sizing, touch targets + +Layout Pattern Library: + Content-Focused Layouts + + Single Column: Linear content flow, ideal for storytelling and mobile experiences + Two-Column: Main content with supporting sidebar, good for blogs and documentation + Three-Column: Content-rich layouts with multiple information hierarchies + Grid Layout: Organized, uniform content blocks (products, portfolio items, etc.) + Masonry Grid: Variable-height items arranged in a space-efficient grid (Pinterest style) + Nested Grids: Hierarchical grid structures with different column counts in different sections + List View: Sequential items displayed with consistent formatting, good for news feeds, search results + Alternating Sections: Contrasting full-width sections that alternate in layout and visual style + + Navigation Patterns + + Fixed Top Navigation: Horizontal menu that remains accessible while scrolling + Fixed Sidebar: Vertical navigation that stays visible during page scrolling + Hamburger/Expandable: Hidden navigation that expands when activated + Mega Menu: Expandable navigation showcasing multiple categories simultaneously + Bottom Navigation: Mobile-friendly navigation fixed to the bottom of the screen + Tabbed Navigation: Content segmented into accessible tabs + Breadcrumb Trail: Hierarchical path showing current location within site structure + Icon-Based Navigation: Visual navigation using recognizable icons (mobile apps, dashboards) + Contextual Navigation: Dynamic menus that change based on user location or behavior + Floating Action Button (FAB): Prominent circular button for primary actions (mobile interfaces) + + Visual Layout Strategies + + Hero-Centered: Dominant visual element introducing the page + Card-Based: Content organized in distinct, modular card components + F-Pattern: Following natural left-to-right, top-to-bottom reading patterns + Z-Pattern: Strategic placement of elements following a Z-shaped visual flow + Split Screen: Side-by-side content sections with equal or varying emphasis + Asymmetrical Layout: Intentionally unbalanced layout creating visual interest + Broken Grid: Overlapping elements and unconventional spacing for creative impact + Minimal White Space: Clean design emphasizing negative space around content + Full-Bleed Images: Edge-to-edge visual content without margins + Layered Layout: Content layers creating depth with overlapping elements + Rule of Thirds: Content aligned to imaginary grid dividing screen into nine equal parts + + Specialized Layouts + + Dashboard: Data-focused layout with widgets, charts, and controls + Product Detail: Featured item with supporting information and actions + E-commerce Listing: Product grid with filtering and sorting capabilities + Landing Page: Conversion-focused with progressive content and strong CTAs + Portfolio/Gallery: Visual showcase with optimal media presentation + Blog Article: Long-form content optimized for readability + Documentation: Technical information with navigation hierarchy + Onboarding Sequence: Step-by-step introduction to products or features + Comparison Layout: Side-by-side product or plan comparison + Pricing Table: Structured display of pricing tiers and features + Timeline: Chronological content display for storytelling or history + Map-Based Interface: Geographic data visualization with interactive elements + Form Layout: Optimized data collection experience + Checkout Flow: Multi-step purchase process + Account Settings: Organized user preference controls + Help Center: Support resources with search and categorization + Social Feed: Dynamic content stream with interaction elements + Video-Centric Layout: Content organization around featured video content + Print-Inspired Layout: Editorial design mimicking print publications + Event/Conference: Schedule and session information display + + Interactive Elements & Techniques + + Sticky Elements: Components that remain fixed during scrolling + Progressive Disclosure: Revealing content as needed (accordions, tabs) + Infinite Scroll: Continuous content loading as the user scrolls + Parallax Effects: Multi-layered scrolling creating depth perception + Horizontal Scrolling: Side-to-side content navigation + Modal Overlays: Focused content windows appearing above the main interface + Carousels/Sliders: Rotating content panels in limited space + Expandable Panels: Collapsible content sections for progressive disclosure + Drag-and-Drop Interfaces: Interactive elements for sorting, organizing, and customizing + Scroll-Triggered Animations: Content and effects that activate during scrolling + Microinteractions: Small animations providing feedback for user actions + Split-Page Scrolling: Different scroll behaviors in different page sections + Scroll Snapping: Content that locks to specific positions during scrolling + Skeleton Screens: Loading placeholders mimicking content structure + Interactive Storytelling: Layouts changing as users progress through narrative + + Responsive Design Patterns + + Mobile-First Layout: Designed primarily for mobile with progressive enhancement + Responsive Grid System: Fluid grid adjusting columns based on screen width + Column Drop: Multi-column layouts that stack on smaller screens + Layout Shifter: Complete layout changes between breakpoints + Mostly Fluid: Minor adjustments to fluid grid at various breakpoints + Off-Canvas Navigation: Navigation elements hidden off-screen on mobile + Priority+ Pattern: Most important navigation items visible, others in dropdown + Content Choreography: Rearranging content priority across breakpoints + Viewport-Based Typography: Font sizes relative to viewport dimensions + Container Queries: Layouts responding to parent container width rather than viewport + + Submission Format + Present your layout strategy as a comprehensive document with: + + Executive summary of your approach + Page-by-page recommendations with justifications + Navigation and interaction specifications + Accessibility implementation notes + Responsive considerations across desktop, tablet, and mobile + + `; + }, +}; + +/**export const prompts = { + // To do add linking view relation like how each page is been connected + generateUIUXLayoutPrompt: (): string => { + return `Role & Objective +You are a senior UX designer tasked with creating optimal page layouts based on project requirements and sitemap information. Your goal is to develop a comprehensive layout strategy that ensures: + +Intuitive user navigation and interaction +Effective content hierarchy and organization +Visual appeal aligned with brand identity +Responsive design across all devices +Maximum conversion potential + +Required Deliverables +1. Sitemap Analysis +Analyze the following pages and their purpose: + +Homepage: [Key objectives, primary user actions] +About: [Brand story elements, team structure] +Products/Services: [Catalog structure, filtering needs] +Contact/Support: [Communication channels, response expectations] +Blog/Resources: [Content organization, reading experience] +[Add other key pages specific to the project] + +2. Layout Recommendations +For each page, provide: + +Recommended Layout Pattern: Choose from the layout library below +Justification: Explain why this layout best serves the page's purpose +Key Components: List essential UI elements and their placement +Responsive Behavior: How the layout adapts across breakpoints + +Example format: +CopyHOMEPAGE +Layout: Hero Section + Card Grid +Justification: Creates immediate brand impact while showcasing multiple product categories +Key Components: +- Full-width hero with primary CTA above the fold +- 3-column product category grid (2-column on tablet, 1-column on mobile) +- Social proof section with customer testimonials +- Newsletter signup before footer +3. Navigation Strategy + +Navigation Type: [Horizontal, vertical, hamburger, etc.] +Information Architecture: How content hierarchy is reflected +Wayfinding Elements: Breadcrumbs, progress indicators, etc. +Search Implementation: Placement and functionality + +4. Interaction Design Notes + +Micro-interactions: Key hover/click behaviors +Scrolling Strategy: Standard, parallax, or specialized scrolling +Transition Effects: Page-to-page and within-page animations +Loading States: How content appears during page loads + +5. Accessibility Considerations + +Navigation Accessibility: Keyboard navigation, screen reader support +Content Hierarchy: How semantic structure supports accessibility +Visual Accessibility: Color contrast, text sizing, touch targets + +Layout Pattern Library +Content-Focused Layouts + +Single Column: Linear content flow, ideal for storytelling and mobile experiences +Two-Column: Main content with supporting sidebar, good for blogs and documentation +Three-Column: Content-rich layouts with multiple information hierarchies +Grid Layout: Organized, uniform content blocks (products, portfolio items, etc.) +Masonry Grid: Variable-height items arranged in a space-efficient grid (Pinterest style) +Nested Grids: Hierarchical grid structures with different column counts in different sections +List View: Sequential items displayed with consistent formatting, good for news feeds, search results +Alternating Sections: Contrasting full-width sections that alternate in layout and visual style + +Navigation Patterns + +Fixed Top Navigation: Horizontal menu that remains accessible while scrolling +Fixed Sidebar: Vertical navigation that stays visible during page scrolling +Hamburger/Expandable: Hidden navigation that expands when activated +Mega Menu: Expandable navigation showcasing multiple categories simultaneously +Bottom Navigation: Mobile-friendly navigation fixed to the bottom of the screen +Tabbed Navigation: Content segmented into accessible tabs +Breadcrumb Trail: Hierarchical path showing current location within site structure +Icon-Based Navigation: Visual navigation using recognizable icons (mobile apps, dashboards) +Contextual Navigation: Dynamic menus that change based on user location or behavior +Floating Action Button (FAB): Prominent circular button for primary actions (mobile interfaces) + +Visual Layout Strategies + +Hero-Centered: Dominant visual element introducing the page +Card-Based: Content organized in distinct, modular card components +F-Pattern: Following natural left-to-right, top-to-bottom reading patterns +Z-Pattern: Strategic placement of elements following a Z-shaped visual flow +Split Screen: Side-by-side content sections with equal or varying emphasis +Asymmetrical Layout: Intentionally unbalanced layout creating visual interest +Broken Grid: Overlapping elements and unconventional spacing for creative impact +Minimal White Space: Clean design emphasizing negative space around content +Full-Bleed Images: Edge-to-edge visual content without margins +Layered Layout: Content layers creating depth with overlapping elements +Rule of Thirds: Content aligned to imaginary grid dividing screen into nine equal parts + +Specialized Layouts + +Dashboard: Data-focused layout with widgets, charts, and controls +Product Detail: Featured item with supporting information and actions +E-commerce Listing: Product grid with filtering and sorting capabilities +Landing Page: Conversion-focused with progressive content and strong CTAs +Portfolio/Gallery: Visual showcase with optimal media presentation +Blog Article: Long-form content optimized for readability +Documentation: Technical information with navigation hierarchy +Onboarding Sequence: Step-by-step introduction to products or features +Comparison Layout: Side-by-side product or plan comparison +Pricing Table: Structured display of pricing tiers and features +Timeline: Chronological content display for storytelling or history +Map-Based Interface: Geographic data visualization with interactive elements +Form Layout: Optimized data collection experience +Checkout Flow: Multi-step purchase process +Account Settings: Organized user preference controls +Help Center: Support resources with search and categorization +Social Feed: Dynamic content stream with interaction elements +Video-Centric Layout: Content organization around featured video content +Print-Inspired Layout: Editorial design mimicking print publications +Event/Conference: Schedule and session information display + +Interactive Elements & Techniques + +Sticky Elements: Components that remain fixed during scrolling +Progressive Disclosure: Revealing content as needed (accordions, tabs) +Infinite Scroll: Continuous content loading as the user scrolls +Parallax Effects: Multi-layered scrolling creating depth perception +Horizontal Scrolling: Side-to-side content navigation +Modal Overlays: Focused content windows appearing above the main interface +Carousels/Sliders: Rotating content panels in limited space +Expandable Panels: Collapsible content sections for progressive disclosure +Drag-and-Drop Interfaces: Interactive elements for sorting, organizing, and customizing +Scroll-Triggered Animations: Content and effects that activate during scrolling +Microinteractions: Small animations providing feedback for user actions +Split-Page Scrolling: Different scroll behaviors in different page sections +Scroll Snapping: Content that locks to specific positions during scrolling +Skeleton Screens: Loading placeholders mimicking content structure +Interactive Storytelling: Layouts changing as users progress through narrative + +Responsive Design Patterns + +Mobile-First Layout: Designed primarily for mobile with progressive enhancement +Responsive Grid System: Fluid grid adjusting columns based on screen width +Column Drop: Multi-column layouts that stack on smaller screens +Layout Shifter: Complete layout changes between breakpoints +Mostly Fluid: Minor adjustments to fluid grid at various breakpoints +Off-Canvas Navigation: Navigation elements hidden off-screen on mobile +Priority+ Pattern: Most important navigation items visible, others in dropdown +Content Choreography: Rearranging content priority across breakpoints +Viewport-Based Typography: Font sizes relative to viewport dimensions +Container Queries: Layouts responding to parent container width rather than viewport + +Submission Format +Present your layout strategy as a comprehensive document with: + +Executive summary of your approach +Page-by-page recommendations with justifications +Navigation and interaction specifications +Accessibility implementation notes +Responsive considerations across desktop, tablet, and mobile + +[Optional: Include simple wireframe sketches or references to similar successful implementations] Link to wireframe/mockup (if generated) +Figma/XD reference (if applicable) + + `; + }, +}; + */ diff --git a/backend/src/build-system/utils/__test__/build-utils.spec.ts b/backend/src/build-system/utils/__test__/build-utils.spec.ts index 5923d1e1..7447774e 100644 --- a/backend/src/build-system/utils/__test__/build-utils.spec.ts +++ b/backend/src/build-system/utils/__test__/build-utils.spec.ts @@ -1,169 +1,169 @@ -import { BuildSequence } from 'src/build-system/types'; -import { Logger } from '@nestjs/common'; -import { ProjectInitHandler } from 'src/build-system/handlers/project-init'; -import { PRDHandler } from 'src/build-system/handlers/product-manager/product-requirements-document/prd'; -import { UXSMDHandler } from 'src/build-system/handlers/ux/sitemap-document'; -import { UXSMSHandler } from 'src/build-system/handlers/ux/sitemap-structure'; -import { UXDMDHandler } from 'src/build-system/handlers/ux/datamap'; -import { DBRequirementHandler } from 'src/build-system/handlers/database/requirements-document'; -import { FileStructureHandler } from 'src/build-system/handlers/file-manager/file-structure'; -import { UXSMSPageByPageHandler } from 'src/build-system/handlers/ux/sitemap-structure/sms-page'; -import { DBSchemaHandler } from 'src/build-system/handlers/database/schemas/schemas'; -import { FileFAHandler } from 'src/build-system/handlers/file-manager/file-arch'; -import { BackendRequirementHandler } from 'src/build-system/handlers/backend/requirements-document'; -import { BackendCodeHandler } from 'src/build-system/handlers/backend/code-generate'; -import { BackendFileReviewHandler } from 'src/build-system/handlers/backend/file-review/file-review'; -import { sortBuildSequence } from '../build-utils'; +// import { BuildSequence } from 'src/build-system/types'; +// import { Logger } from '@nestjs/common'; +// import { ProjectInitHandler } from 'src/build-system/handlers/project-init'; +// import { PRDHandler } from 'src/build-system/handlers/product-manager/product-requirements-document/prd'; +// import { UXSMDHandler } from 'src/build-system/handlers/ux/sitemap-document'; +// import { UXSMSHandler } from 'src/build-system/handlers/ux/sitemap-structure'; +// import { UXDMDHandler } from 'src/build-system/handlers/ux/datamap'; +// import { DBRequirementHandler } from 'src/build-system/handlers/database/requirements-document'; +// import { FileStructureHandler } from 'src/build-system/handlers/file-manager/file-structure'; +// import { UXSMSPageByPageHandler } from 'src/build-system/handlers/ux/sitemap-structure/sms-page'; +// import { DBSchemaHandler } from 'src/build-system/handlers/database/schemas/schemas'; +// import { FileFAHandler } from 'src/build-system/handlers/file-manager/file-arch'; +// import { BackendRequirementHandler } from 'src/build-system/handlers/backend/requirements-document'; +// import { BackendCodeHandler } from 'src/build-system/handlers/backend/code-generate'; +// import { BackendFileReviewHandler } from 'src/build-system/handlers/backend/file-review/file-review'; +// import { sortBuildSequence } from '../build-utils'; -const logger = new Logger('BuildUtilsTest'); +// const logger = new Logger('BuildUtilsTest'); -describe('Build Sequence Test', () => { - it('should execute build sequence successfully', async () => { - const sequence: BuildSequence = { - id: 'test-backend-sequence', - version: '1.0.0', - name: 'Spotify-like Music Web', - description: 'Users can play music', - databaseType: 'SQLite', - nodes: [ - { - handler: ProjectInitHandler, - name: 'Project Folders Setup', - }, - { - handler: PRDHandler, - name: 'Project Requirements Document Node', - }, - { - handler: UXSMDHandler, - name: 'UX Sitemap Document Node', - }, - { - handler: UXSMSHandler, - name: 'UX Sitemap Structure Node', - }, - { - handler: UXDMDHandler, - name: 'UX DataMap Document Node', - }, - { - handler: DBRequirementHandler, - name: 'Database Requirements Node', - }, - { - handler: FileStructureHandler, - name: 'File Structure Generation', - options: { - projectPart: 'frontend', - }, - }, - { - handler: UXSMSPageByPageHandler, - name: 'Level 2 UX Sitemap Structure Node details', - }, - { - handler: DBSchemaHandler, - name: 'Database Schemas Node', - }, - { - handler: FileFAHandler, - name: 'File Arch', - }, - { - handler: BackendRequirementHandler, - name: 'Backend Requirements Node', - }, - { - handler: BackendCodeHandler, - name: 'Backend Code Generator Node', - }, - { - handler: BackendFileReviewHandler, - name: 'Backend File Review Node', - }, - ], - }; +// describe('Build Sequence Test', () => { +// it('should execute build sequence successfully', async () => { +// const sequence: BuildSequence = { +// id: 'test-backend-sequence', +// version: '1.0.0', +// name: 'Spotify-like Music Web', +// description: 'Users can play music', +// databaseType: 'SQLite', +// nodes: [ +// { +// handler: ProjectInitHandler, +// name: 'Project Folders Setup', +// }, +// { +// handler: PRDHandler, +// name: 'Project Requirements Document Node', +// }, +// { +// handler: UXSMDHandler, +// name: 'UX Sitemap Document Node', +// }, +// { +// handler: UXSMSHandler, +// name: 'UX Sitemap Structure Node', +// }, +// { +// handler: UXDMDHandler, +// name: 'UX DataMap Document Node', +// }, +// { +// handler: DBRequirementHandler, +// name: 'Database Requirements Node', +// }, +// { +// handler: FileStructureHandler, +// name: 'File Structure Generation', +// options: { +// projectPart: 'frontend', +// }, +// }, +// { +// handler: UXSMSPageByPageHandler, +// name: 'Level 2 UX Sitemap Structure Node details', +// }, +// { +// handler: DBSchemaHandler, +// name: 'Database Schemas Node', +// }, +// { +// handler: FileFAHandler, +// name: 'File Arch', +// }, +// { +// handler: BackendRequirementHandler, +// name: 'Backend Requirements Node', +// }, +// { +// handler: BackendCodeHandler, +// name: 'Backend Code Generator Node', +// }, +// { +// handler: BackendFileReviewHandler, +// name: 'Backend File Review Node', +// }, +// ], +// }; - logger.log('Before Sorting:'); - sequence.nodes.forEach((node, index) => { - logger.log(`${index + 1}: ${node.name}`); - }); +// logger.log('Before Sorting:'); +// sequence.nodes.forEach((node, index) => { +// logger.log(`${index + 1}: ${node.name}`); +// }); - const sortedNodes = sortBuildSequence(sequence); +// const sortedNodes = sortBuildSequence(sequence); - logger.log('\nAfter Sorting:'); - sortedNodes.forEach((node, index) => { - logger.log(`${index + 1}: ${node.name}`); - }); +// logger.log('\nAfter Sorting:'); +// sortedNodes.forEach((node, index) => { +// logger.log(`${index + 1}: ${node.name}`); +// }); - logger.log('\nBefore/After Comparison (Same Index):'); - sequence.nodes.forEach((node, index) => { - const sortedNode = sortedNodes[index]; - logger.log(`Index ${index + 1}:`); - logger.log(` Before: ${node.name}`); - logger.log(` After: ${sortedNode.name}`); - }); - }, 300000); -}); +// logger.log('\nBefore/After Comparison (Same Index):'); +// sequence.nodes.forEach((node, index) => { +// const sortedNode = sortedNodes[index]; +// logger.log(`Index ${index + 1}:`); +// logger.log(` Before: ${node.name}`); +// logger.log(` After: ${sortedNode.name}`); +// }); +// }, 300000); +// }); -describe('sortBuildSequence Tests', () => { - it('should sort build sequence correctly based on dependencies', () => { - const sequence: BuildSequence = { - id: 'test-backend-sequence', - version: '1.0.0', - name: 'Spotify-like Music Web', - description: 'Users can play music', - databaseType: 'SQLite', - nodes: [ - { - handler: ProjectInitHandler, - name: 'Project Folders Setup', - description: 'Create project folders', - }, +// describe('sortBuildSequence Tests', () => { +// it('should sort build sequence correctly based on dependencies', () => { +// const sequence: BuildSequence = { +// id: 'test-backend-sequence', +// version: '1.0.0', +// name: 'Spotify-like Music Web', +// description: 'Users can play music', +// databaseType: 'SQLite', +// nodes: [ +// { +// handler: ProjectInitHandler, +// name: 'Project Folders Setup', +// description: 'Create project folders', +// }, - { - handler: PRDHandler, - name: 'Project Requirements Document Node', - }, +// { +// handler: PRDHandler, +// name: 'Project Requirements Document Node', +// }, - { - handler: UXSMDHandler, - name: 'UX Sitemap Document Node', - }, +// { +// handler: UXSMDHandler, +// name: 'UX Sitemap Document Node', +// }, - { - handler: UXSMSHandler, - name: 'UX Sitemap Structure Node', - }, - { - handler: UXDMDHandler, - name: 'UX DataMap Document Node', - }, - { - handler: UXSMSPageByPageHandler, - name: 'Level 2 UX Sitemap Structure Node details', - }, - ], - }; +// { +// handler: UXSMSHandler, +// name: 'UX Sitemap Structure Node', +// }, +// { +// handler: UXDMDHandler, +// name: 'UX DataMap Document Node', +// }, +// { +// handler: UXSMSPageByPageHandler, +// name: 'Level 2 UX Sitemap Structure Node details', +// }, +// ], +// }; - logger.log('Before Sorting:'); - sequence.nodes.forEach((node, index) => { - logger.log(`${index + 1}: ${node.name}`); - }); +// logger.log('Before Sorting:'); +// sequence.nodes.forEach((node, index) => { +// logger.log(`${index + 1}: ${node.name}`); +// }); - const sortedNodes = sortBuildSequence(sequence); +// const sortedNodes = sortBuildSequence(sequence); - logger.log('\nAfter Sorting:'); - sortedNodes.forEach((node, index) => { - logger.log(`${index + 1}: ${node.name}`); - }); +// logger.log('\nAfter Sorting:'); +// sortedNodes.forEach((node, index) => { +// logger.log(`${index + 1}: ${node.name}`); +// }); - logger.log('\nBefore/After Comparison (Same Index):'); - sequence.nodes.forEach((node, index) => { - const sortedNode = sortedNodes[index]; - logger.log(`Index ${index + 1}:`); - logger.log(` Before: ${node.name}`); - logger.log(` After: ${sortedNode.name}`); - }); - }); -}); +// logger.log('\nBefore/After Comparison (Same Index):'); +// sequence.nodes.forEach((node, index) => { +// const sortedNode = sortedNodes[index]; +// logger.log(`Index ${index + 1}:`); +// logger.log(` Before: ${node.name}`); +// logger.log(` After: ${sortedNode.name}`); +// }); +// }); +// }); diff --git a/backend/src/build-system/utils/file_generator_util.ts b/backend/src/build-system/utils/file_generator_util.ts index f97bff05..6ae849fc 100644 --- a/backend/src/build-system/utils/file_generator_util.ts +++ b/backend/src/build-system/utils/file_generator_util.ts @@ -60,7 +60,16 @@ function buildDependencyLayerGraph(jsonData: { const fileInfos: Record = {}; const nodes = new Set(); + const shouldIgnore = (filePath: string) => { + // this.logger.log(`Checking if should ignore: ${filePath}`); + return filePath.startsWith('@/components/ui/'); + }; + Object.entries(jsonData.files).forEach(([fileName, details]) => { + if (shouldIgnore(fileName)) { + return; + } + nodes.add(fileName); // Initialize the record @@ -69,8 +78,16 @@ function buildDependencyLayerGraph(jsonData: { dependsOn: [], }; + const filteredDeps = (details.dependsOn || []).filter( + (dep) => !shouldIgnore(dep), + ); + // In the JSON, "dependsOn" is an array of file paths - details.dependsOn.forEach((dep) => { + // details.dependsOn.forEach((dep) => { + // nodes.add(dep); + // fileInfos[fileName].dependsOn.push(dep); + // }); + filteredDeps.forEach((dep) => { nodes.add(dep); fileInfos[fileName].dependsOn.push(dep); }); diff --git a/backend/src/build-system/utils/files.ts b/backend/src/build-system/utils/files.ts index 29451336..355152c8 100644 --- a/backend/src/build-system/utils/files.ts +++ b/backend/src/build-system/utils/files.ts @@ -114,7 +114,7 @@ export async function readFileWithRetries( } // If we exhausted all retries, re-throw the last error - throw lastError; + return null; } /** diff --git a/backend/src/build-system/utils/strings.ts b/backend/src/build-system/utils/strings.ts index e9df675e..8e361640 100644 --- a/backend/src/build-system/utils/strings.ts +++ b/backend/src/build-system/utils/strings.ts @@ -3,6 +3,78 @@ import { ResponseTagError } from '../errors'; const logger = new Logger('common-utils'); +export const SHADCN_COMPONENT_PATHS: string[] = [ + '@/components/ui/accordion.tsx', + '@/components/ui/alert.tsx', + '@/components/ui/alert-dialog.tsx', + '@/components/ui/aspect-ratio.tsx', + '@/components/ui/avatar.tsx', + '@/components/ui/badge.tsx', + '@/components/ui/breadcrumb.tsx', + '@/components/ui/button.tsx', + '@/components/ui/calendar.tsx', + '@/components/ui/card.tsx', + '@/components/ui/carousel.tsx', + '@/components/ui/chart.tsx', + '@/components/ui/checkbox.tsx', + '@/components/ui/collapsible.tsx', + '@/components/ui/command.tsx', + '@/components/ui/context-menu.tsx', + '@/components/ui/dialog.tsx', + '@/components/ui/drawer.tsx', + '@/components/ui/dropdown-menu.tsx', + '@/components/ui/form.tsx', + '@/components/ui/hover-card.tsx', + '@/components/ui/input.tsx', + '@/components/ui/input-otp.tsx', + '@/components/ui/label.tsx', + '@/components/ui/menubar.tsx', + '@/components/ui/navigation-menu.tsx', + '@/components/ui/pagination.tsx', + '@/components/ui/popover.tsx', + '@/components/ui/progress.tsx', + '@/components/ui/radio-group.tsx', + '@/components/ui/resizable.tsx', + '@/components/ui/scroll-area.tsx', + '@/components/ui/select.tsx', + '@/components/ui/separator.tsx', + '@/components/ui/sheet.tsx', + '@/components/ui/sidebar.tsx', + '@/components/ui/skeleton.tsx', + '@/components/ui/slider.tsx', + '@/components/ui/sonner.tsx', + '@/components/ui/switch.tsx', + '@/components/ui/table.tsx', + '@/components/ui/tabs.tsx', + '@/components/ui/textarea.tsx', + '@/components/ui/toast.tsx', + '@/components/ui/toggle.tsx', + '@/components/ui/toggle-group.tsx', + '@/components/ui/tooltip.tsx', +]; + +/** + * Function to merge Paths with SHADCN UI component paths + * and write the result to a new JSON file. + */ +export function mergePaths(input: string) { + try { + // Parse the input string into a JSON object + const parsedData = JSON.parse(input) as { Paths: string[] }; + + // Merge the existing paths with the SHADCN components + const updatedPaths = { + Paths: [...parsedData.Paths, ...SHADCN_COMPONENT_PATHS], + }; + + // Convert back to JSON string with formatting + return JSON.stringify(updatedPaths, null, 2); + } catch (error) { + console.error('Error parsing JSON input:', error); + return '{}'; // Return empty object in case of an error + } +} + /** * Extract JSON data from Markdown content. * @param markdownContent The Markdown content containing the JSON. diff --git a/backend/src/build-system/virtual-dir/index.ts b/backend/src/build-system/virtual-dir/index.ts index ec64a45a..faae8ba5 100644 --- a/backend/src/build-system/virtual-dir/index.ts +++ b/backend/src/build-system/virtual-dir/index.ts @@ -1,4 +1,5 @@ import { Logger } from '@nestjs/common'; +import { SHADCN_COMPONENT_PATHS } from '../utils/strings'; export class VirtualDirectory { private filePaths: Set = new Set(); @@ -14,7 +15,7 @@ export class VirtualDirectory { return false; } - this.filePaths = new Set(structure.Paths); + this.filePaths = new Set([...structure.Paths, ...SHADCN_COMPONENT_PATHS]); return true; } catch (error) { this.logger.error('Failed to parse JSON structure:', error); diff --git a/backend/src/downloader/__tests__/download-model.spec.ts b/backend/src/downloader/__tests__/download-model.spec.ts index 8fa3053d..3a429bb1 100644 --- a/backend/src/downloader/__tests__/download-model.spec.ts +++ b/backend/src/downloader/__tests__/download-model.spec.ts @@ -1,82 +1,82 @@ -import { isIntegrationTest } from 'src/common/utils'; -import { - ConfigLoader, - ModelConfig, - EmbeddingConfig, -} from '../../config/config-loader'; -import { UniversalDownloader } from '../model-downloader'; -import { ConfigType, downloadAll, TaskType } from '../universal-utils'; +// import { isIntegrationTest } from 'src/common/utils'; +// import { +// ConfigLoader, +// ModelConfig, +// EmbeddingConfig, +// } from '../../config/config-loader'; +// import { UniversalDownloader } from '../model-downloader'; +// import { ConfigType, downloadAll, TaskType } from '../universal-utils'; -const originalIsArray = Array.isArray; +// const originalIsArray = Array.isArray; -Array.isArray = jest.fn((type: any): type is any[] => { - if ( - type && - type.constructor && - (type.constructor.name === 'Float32Array' || - type.constructor.name === 'BigInt64Array') - ) { - return true; - } - return originalIsArray(type); -}) as unknown as (arg: any) => arg is any[]; +// Array.isArray = jest.fn((type: any): type is any[] => { +// if ( +// type && +// type.constructor && +// (type.constructor.name === 'Float32Array' || +// type.constructor.name === 'BigInt64Array') +// ) { +// return true; +// } +// return originalIsArray(type); +// }) as unknown as (arg: any) => arg is any[]; -(isIntegrationTest ? describe : describe.skip)( - 'loadAllChatsModels with real model loading', - () => { - let modelConfigLoader: ConfigLoader; - let embConfigLoader: ConfigLoader; - beforeAll(async () => { - modelConfigLoader = ConfigLoader.getInstance(ConfigType.CHATS); - embConfigLoader = ConfigLoader.getInstance(ConfigType.EMBEDDINGS); - const modelConfig: ModelConfig = { - model: 'Xenova/flan-t5-small', - endpoint: 'http://localhost:11434/v1', - token: 'your-token-here', - task: 'text2text-generation', - }; - modelConfigLoader.addConfig(modelConfig); +// (isIntegrationTest ? describe : describe.skip)( +// 'loadAllChatsModels with real model loading', +// () => { +// let modelConfigLoader: ConfigLoader; +// let embConfigLoader: ConfigLoader; +// beforeAll(async () => { +// modelConfigLoader = ConfigLoader.getInstance(ConfigType.CHATS); +// embConfigLoader = ConfigLoader.getInstance(ConfigType.EMBEDDINGS); +// const modelConfig: ModelConfig = { +// model: 'Xenova/flan-t5-small', +// endpoint: 'http://localhost:11434/v1', +// token: 'your-token-here', +// task: 'text2text-generation', +// }; +// modelConfigLoader.addConfig(modelConfig); - const embConfig: EmbeddingConfig = { - model: 'fast-bge-base-en-v1.5', - endpoint: 'http://localhost:11434/v1', - token: 'your-token-here', - }; - embConfigLoader.addConfig(embConfig); - await downloadAll(); - }, 60000000); +// const embConfig: EmbeddingConfig = { +// model: 'fast-bge-base-en-v1.5', +// endpoint: 'http://localhost:11434/v1', +// token: 'your-token-here', +// }; +// embConfigLoader.addConfig(embConfig); +// await downloadAll(); +// }, 60000000); - it('should load real models specified in config', async () => { - const downloader = UniversalDownloader.getInstance(); - const chat1Model = await downloader.getLocalModel( - TaskType.CHAT, - 'Xenova/flan-t5-small', - ); - expect(chat1Model).toBeDefined(); +// it('should load real models specified in config', async () => { +// const downloader = UniversalDownloader.getInstance(); +// const chat1Model = await downloader.getLocalModel( +// TaskType.CHAT, +// 'Xenova/flan-t5-small', +// ); +// expect(chat1Model).toBeDefined(); - expect(chat1Model).toHaveProperty('model'); - expect(chat1Model).toHaveProperty('tokenizer'); +// expect(chat1Model).toHaveProperty('model'); +// expect(chat1Model).toHaveProperty('tokenizer'); - try { - const chat1Output = await chat1Model( - 'Write me a love poem about cheese.', - { - max_new_tokens: 200, - temperature: 0.9, - repetition_penalty: 2.0, - no_repeat_ngram_size: 3, - }, - ); +// try { +// const chat1Output = await chat1Model( +// 'Write me a love poem about cheese.', +// { +// max_new_tokens: 200, +// temperature: 0.9, +// repetition_penalty: 2.0, +// no_repeat_ngram_size: 3, +// }, +// ); - expect(chat1Output).toBeDefined(); - expect(chat1Output[0]).toHaveProperty('generated_text'); - } catch (error) { - // - } - }, 6000000); - }, -); +// expect(chat1Output).toBeDefined(); +// expect(chat1Output[0]).toHaveProperty('generated_text'); +// } catch (error) { +// // +// } +// }, 6000000); +// }, +// ); -afterAll(() => { - Array.isArray = originalIsArray; -}); +// afterAll(() => { +// Array.isArray = originalIsArray; +// }); diff --git a/backend/template/react-ts/components.json b/backend/template/react-ts/components.json new file mode 100644 index 00000000..13e1db0b --- /dev/null +++ b/backend/template/react-ts/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} diff --git a/backend/template/react-ts/package-lock.json b/backend/template/react-ts/package-lock.json index 3f8dc453..fd53297d 100644 --- a/backend/template/react-ts/package-lock.json +++ b/backend/template/react-ts/package-lock.json @@ -8,13 +8,58 @@ "name": "codefox", "version": "0.0.0", "dependencies": { + "@hookform/resolvers": "^4.1.0", + "@radix-ui/react-accordion": "^1.2.3", + "@radix-ui/react-alert-dialog": "^1.1.6", + "@radix-ui/react-aspect-ratio": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", + "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-context-menu": "^2.2.6", + "@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-label": "^2.1.2", + "@radix-ui/react-menubar": "^1.1.6", + "@radix-ui/react-navigation-menu": "^1.2.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-scroll-area": "^1.2.3", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.3", + "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-toast": "^1.2.6", + "@radix-ui/react-toggle": "^1.1.2", + "@radix-ui/react-toggle-group": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", "@tailwindcss/vite": "^4.0.0", "axios": "^1.7.9", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "cmdk": "^1.0.0", + "date-fns": "^3.6.0", + "embla-carousel-react": "^8.5.2", + "input-otp": "^1.4.2", + "lucide-react": "^0.445.0", + "next-themes": "^0.4.4", "react": "^18.3.1", + "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.54.2", + "react-resizable-panels": "^2.1.7", "react-router": "^6.28.2", "react-router-dom": "^7.1.5", - "tailwindcss": "^4.0.0" + "recharts": "^2.15.1", + "sonner": "^1.7.4", + "tailwind-merge": "^2.6.0", + "tailwindcss": "^4.0.0", + "tailwindcss-animate": "^1.0.7", + "vaul": "^1.1.2", + "zod": "^3.24.2" }, "devDependencies": { "@eslint/js": "^9.15.0", @@ -59,30 +104,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", - "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz", - "integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.5", + "@babel/generator": "^7.26.9", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.7", - "@babel/parser": "^7.26.7", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.26.7", - "@babel/types": "^7.26.7", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -98,13 +143,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", - "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", + "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", "dev": true, "dependencies": { - "@babel/parser": "^7.26.5", - "@babel/types": "^7.26.5", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -196,25 +241,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz", - "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", + "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", "dev": true, "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz", - "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", "dev": true, "dependencies": { - "@babel/types": "^7.26.7" + "@babel/types": "^7.26.9" }, "bin": { "parser": "bin/babel-parser.js" @@ -253,31 +298,42 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", + "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz", - "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", + "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.5", - "@babel/parser": "^7.26.7", - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7", + "@babel/generator": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -295,9 +351,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz", - "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -736,9 +792,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", - "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.15" @@ -783,9 +839,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", - "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", + "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -801,18 +857,63 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", - "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.6.tgz", + "integrity": "sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==", "dev": true, "dependencies": { - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.11.0", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" + }, + "node_modules/@hookform/resolvers": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-4.1.0.tgz", + "integrity": "sha512-fX/uHKb+OOCpACLc6enuTQsf0ZpRrKbeBBPETg5PCPLCIYV6osP2Bw6ezuclM61lH+wBF9eXcuC0+BFh9XOEnQ==", + "dependencies": { + "caniuse-lite": "^1.0.30001698" + }, + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -957,186 +1058,1449 @@ "node": ">= 8" } }, - "node_modules/@remix-run/router": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.22.0.tgz", - "integrity": "sha512-MBOl8MeOzpK0HQQQshKB7pABXbmyHizdTpqnrIseTbsv0nAepwC2ENZa1aaBExNQcpLoXmWthhak8SABLzvGPw==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.4.tgz", - "integrity": "sha512-gGi5adZWvjtJU7Axs//CWaQbQd/vGy8KGcnEaCWiyCqxWYDxwIlAHFuSe6Guoxtd0SRvSfVTDMPd5H+4KE2kKA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ] + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.4.tgz", - "integrity": "sha512-1aRlh1gqtF7vNPMnlf1vJKk72Yshw5zknR/ZAVh7zycRAGF2XBMVDAHmFQz/Zws5k++nux3LOq/Ejj1WrDR6xg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ] + "node_modules/@radix-ui/primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==" }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.4.tgz", - "integrity": "sha512-drHl+4qhFj+PV/jrQ78p9ch6A0MfNVZScl/nBps5a7u01aGf/GuBRrHnRegA9bP222CBDfjYbFdjkIJ/FurvSQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.3.tgz", + "integrity": "sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collapsible": "1.1.3", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.4.tgz", - "integrity": "sha512-hQqq/8QALU6t1+fbNmm6dwYsa0PDD4L5r3TpHx9dNl+aSEMnIksHZkSO3AVH+hBMvZhpumIGrTFj8XCOGuIXjw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.6.tgz", + "integrity": "sha512-p4XnPqgej8sZAAReCAKgz1REYZEBLR8hU9Pg27wFnCWIMc8g1ccCs0FjBcy05V15VTu8pAePw/VDYeOm/uZ6yQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dialog": "1.1.6", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.4.tgz", - "integrity": "sha512-/L0LixBmbefkec1JTeAQJP0ETzGjFtNml2gpQXA8rpLo7Md+iXQzo9kwEgzyat5Q+OG/C//2B9Fx52UxsOXbzw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ] + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.2.tgz", + "integrity": "sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.4.tgz", - "integrity": "sha512-6Rk3PLRK+b8L/M6m/x6Mfj60LhAUcLJ34oPaxufA+CfqkUrDoUPQYFdRrhqyOvtOKXLJZJwxlOLbQjNYQcRQfw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ] + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.2.tgz", + "integrity": "sha512-TaJxYoCpxJ7vfEkv2PTNox/6zzmpKXT6ewvCuf2tTOIVN45/Jahhlld29Yw4pciOXS2Xq91/rSGEdmEnUWZCqA==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.4.tgz", - "integrity": "sha512-kmT3x0IPRuXY/tNoABp2nDvI9EvdiS2JZsd4I9yOcLCCViKsP0gB38mVHOhluzx+SSVnM1KNn9k6osyXZhLoCA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.3.tgz", + "integrity": "sha512-Paen00T4P8L8gd9bNsRMw7Cbaz85oxiv+hzomsRZgFm2byltPFDtfcoqlWJ8GyZlIBWgLssJlzLCnKU0G0302g==", + "dependencies": { + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.4.tgz", - "integrity": "sha512-3iSA9tx+4PZcJH/Wnwsvx/BY4qHpit/u2YoZoXugWVfc36/4mRkgGEoRbRV7nzNBSCOgbWMeuQ27IQWgJ7tRzw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@radix-ui/react-checkbox": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.4.tgz", + "integrity": "sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.4.tgz", - "integrity": "sha512-7CwSJW+sEhM9sESEk+pEREF2JL0BmyCro8UyTq0Kyh0nu1v0QPNY3yfLPFKChzVoUmaKj8zbdgBxUhBRR+xGxg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.3.tgz", + "integrity": "sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.4.tgz", - "integrity": "sha512-GZdafB41/4s12j8Ss2izofjeFXRAAM7sHCb+S4JsI9vaONX/zQ8cXd87B9MRU/igGAJkKvmFmJJBeeT9jJ5Cbw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@radix-ui/react-collection": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.2.tgz", + "integrity": "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.4.tgz", - "integrity": "sha512-uuphLuw1X6ur11675c2twC6YxbzyLSpWggvdawTUamlsoUv81aAXRMPBC1uvQllnBGls0Qt5Siw8reSIBnbdqQ==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", + "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.4.tgz", - "integrity": "sha512-KvLEw1os2gSmD6k6QPCQMm2T9P2GYvsMZMRpMz78QpSoEevHbV/KOUbI/46/JRalhtSAYZBYLAnT9YE4i/l4vg==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.4.tgz", - "integrity": "sha512-wcpCLHGM9yv+3Dql/CI4zrY2mpQ4WFergD3c9cpRowltEh5I84pRT/EuHZsG0In4eBPPYthXnuR++HrFkeqwkA==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ] + "node_modules/@radix-ui/react-context-menu": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.6.tgz", + "integrity": "sha512-aUP99QZ3VU84NPsHeaFt4cQUNgJqFsLLOt/RbbWXszZ6MP0DpDyjkFZORr4RpAEx3sUBk+Kc8h13yGtC5Qw8dg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-menu": "2.1.6", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.4.tgz", - "integrity": "sha512-nLbfQp2lbJYU8obhRQusXKbuiqm4jSJteLwfjnunDT5ugBKdxqw1X9KWwk8xp1OMC6P5d0WbzxzhWoznuVK6XA==", - "cpu": [ - "s390x" - ], + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.6.tgz", + "integrity": "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz", + "integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.6.tgz", + "integrity": "sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.6", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz", + "integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-hover-card": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.6.tgz", + "integrity": "sha512-E4ozl35jq0VRlrdc4dhHrNSV0JqBb4Jy73WAhBEK7JoYnQ83ED5r0Rb/XdVKw89ReAJN38N492BAPBZQ57VmqQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.2.tgz", + "integrity": "sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.6.tgz", + "integrity": "sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-roving-focus": "1.1.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.6.tgz", + "integrity": "sha512-FHq7+3DlXwh/7FOM4i0G4bC4vPjiq89VEEvNF4VMLchGnaUuUbE5uKXMUCjdKaOghEEMeiKa5XCa2Pk4kteWmg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.6", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-roving-focus": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.5.tgz", + "integrity": "sha512-myMHHQUZ3ZLTi8W381/Vu43Ia0NqakkQZ2vzynMmTUtQQ9kNkjzhOwkZC9TAM5R07OZUVIQyHC06f/9JZJpvvA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.6.tgz", + "integrity": "sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz", + "integrity": "sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.4.tgz", + "integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz", + "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==", + "dependencies": { + "@radix-ui/react-slot": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.2.tgz", + "integrity": "sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA==", + "dependencies": { + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.3.tgz", + "integrity": "sha512-xtCsqt8Rp09FK50ItqEqTJ7Sxanz8EM8dnkVIhJrc/wkMMomSmXHvYbhv3E7Zx4oXh98aaLt9W679SUYXg4IDA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-roving-focus": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.2.tgz", + "integrity": "sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.3.tgz", + "integrity": "sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz", + "integrity": "sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.2.tgz", + "integrity": "sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.2.3.tgz", + "integrity": "sha512-nNrLAWLjGESnhqBqcCNW4w2nn7LxudyMzeB6VgdyAnFLC6kfQgnAjSL2v6UkQTnDctJBlxrmxfplWS4iYjdUTw==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz", + "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.3.tgz", + "integrity": "sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.3.tgz", + "integrity": "sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-roving-focus": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.6.tgz", + "integrity": "sha512-gN4dpuIVKEgpLn1z5FhzT9mYRUitbfZq9XqN/7kkBMUgFTzTG8x/KszWJugJXHcwxckY8xcKDZPz7kG3o6DsUA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.2.tgz", + "integrity": "sha512-lntKchNWx3aCHuWKiDY+8WudiegQvBpDRAYL8dKLRvKEH8VOpl0XX6SSU/bUBqIRJbcTy4+MW06Wv8vgp10rzQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.2.tgz", + "integrity": "sha512-JBm6s6aVG/nwuY5eadhU2zDi/IwYS0sDM5ZWb4nymv/hn3hZdkw+gENn0LP4iY1yCd7+bgJaCwueMYJIU3vk4A==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-roving-focus": "1.1.2", + "@radix-ui/react-toggle": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.8.tgz", + "integrity": "sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.5", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.2", + "@radix-ui/react-portal": "1.1.4", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.2.tgz", + "integrity": "sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + }, + "node_modules/@remix-run/router": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.22.0.tgz", + "integrity": "sha512-MBOl8MeOzpK0HQQQshKB7pABXbmyHizdTpqnrIseTbsv0nAepwC2ENZa1aaBExNQcpLoXmWthhak8SABLzvGPw==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", + "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", + "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", + "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", + "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", + "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", + "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", + "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", + "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", + "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", + "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", + "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", + "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", + "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", + "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", + "cpu": [ + "s390x" + ], "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.4.tgz", - "integrity": "sha512-JGejzEfVzqc/XNiCKZj14eb6s5w8DdWlnQ5tWUbs99kkdvfq9btxxVX97AaxiUX7xJTKFA0LwoS0KU8C2faZRg==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", + "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", "cpu": [ "x64" ], @@ -1146,9 +2510,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.4.tgz", - "integrity": "sha512-/iFIbhzeyZZy49ozAWJ1ZR2KW6ZdYUbQXLT4O5n1cRZRoTpwExnHLjlurDXXPKEGxiAg0ujaR9JDYKljpr2fDg==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", + "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", "cpu": [ "x64" ], @@ -1158,9 +2522,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.4.tgz", - "integrity": "sha512-qORc3UzoD5UUTneiP2Afg5n5Ti1GAW9Gp5vHPxzvAFFA3FBaum9WqGvYXGf+c7beFdOKNos31/41PRMUwh1tpA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", + "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", "cpu": [ "arm64" ], @@ -1170,9 +2534,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.4.tgz", - "integrity": "sha512-5g7E2PHNK2uvoD5bASBD9aelm44nf1w4I5FEI7MPHLWcCSrR8JragXZWgKPXk5i2FU3JFfa6CGZLw2RrGBHs2Q==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", + "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", "cpu": [ "ia32" ], @@ -1182,9 +2546,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.4.tgz", - "integrity": "sha512-p0scwGkR4kZ242xLPBuhSckrJ734frz6v9xZzD+kHVYRAkSUmdSLCIJRfql6H5//aF8Q10K+i7q8DiPfZp0b7A==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", + "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", "cpu": [ "x64" ], @@ -1194,102 +2558,162 @@ ] }, "node_modules/@tailwindcss/node": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.3.tgz", - "integrity": "sha512-QsVJokOl0pJ4AbJV33D2npvLcHGPWi5MOSZtrtE0GT3tSx+3D0JE2lokLA8yHS1x3oCY/3IyRyy7XX6tmzid7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.7.tgz", + "integrity": "sha512-dkFXufkbRB2mu3FPsW5xLAUWJyexpJA+/VtQj18k3SUiJVLdpgzBd1v1gRRcIpEJj7K5KpxBKfOXlZxT3ZZRuA==", "dependencies": { - "enhanced-resolve": "^5.18.0", + "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", - "tailwindcss": "4.0.3" + "tailwindcss": "4.0.7" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.3.tgz", - "integrity": "sha512-FFcp3VNvRjjmFA39ORM27g2mbflMQljhvM7gxBAujHxUy4LXlKa6yMF9wbHdTbPqTONiCyyOYxccvJyVyI/XBg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.7.tgz", + "integrity": "sha512-yr6w5YMgjy+B+zkJiJtIYGXW+HNYOPfRPtSs+aqLnKwdEzNrGv4ZuJh9hYJ3mcA+HMq/K1rtFV+KsEr65S558g==", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.0.7", + "@tailwindcss/oxide-darwin-arm64": "4.0.7", + "@tailwindcss/oxide-darwin-x64": "4.0.7", + "@tailwindcss/oxide-freebsd-x64": "4.0.7", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.7", + "@tailwindcss/oxide-linux-arm64-gnu": "4.0.7", + "@tailwindcss/oxide-linux-arm64-musl": "4.0.7", + "@tailwindcss/oxide-linux-x64-gnu": "4.0.7", + "@tailwindcss/oxide-linux-x64-musl": "4.0.7", + "@tailwindcss/oxide-win32-arm64-msvc": "4.0.7", + "@tailwindcss/oxide-win32-x64-msvc": "4.0.7" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.7.tgz", + "integrity": "sha512-5iQXXcAeOHBZy8ASfHFm1k0O/9wR2E3tKh6+P+ilZZbQiMgu+qrnfpBWYPc3FPuQdWiWb73069WT5D+CAfx/tg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.7.tgz", + "integrity": "sha512-7yGZtEc5IgVYylqK/2B0yVqoofk4UAbkn1ygNpIJZyrOhbymsfr8uUFCueTu2fUxmAYIfMZ8waWo2dLg/NgLgg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.7.tgz", + "integrity": "sha512-tPQDV20fBjb26yWbPqT1ZSoDChomMCiXTKn4jupMSoMCFyU7+OJvIY1ryjqBuY622dEBJ8LnCDDWsnj1lX9nNQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.7.tgz", + "integrity": "sha512-sZqJpTyTZiknU9LLHuByg5GKTW+u3FqM7q7myequAXxKOpAFiOfXpY710FuMY+gjzSapyRbDXJlsTQtCyiTo5w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], "engines": { "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.0.3", - "@tailwindcss/oxide-darwin-arm64": "4.0.3", - "@tailwindcss/oxide-darwin-x64": "4.0.3", - "@tailwindcss/oxide-freebsd-x64": "4.0.3", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.3", - "@tailwindcss/oxide-linux-arm64-gnu": "4.0.3", - "@tailwindcss/oxide-linux-arm64-musl": "4.0.3", - "@tailwindcss/oxide-linux-x64-gnu": "4.0.3", - "@tailwindcss/oxide-linux-x64-musl": "4.0.3", - "@tailwindcss/oxide-win32-arm64-msvc": "4.0.3", - "@tailwindcss/oxide-win32-x64-msvc": "4.0.3" } }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.3.tgz", - "integrity": "sha512-S8XOTQuMnpijZRlPm5HBzPJjZ28quB+40LSRHjRnQF6rRYKsvpr1qkY7dfwsetNdd+kMLOMDsvmuT8WnqqETvg==", + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.7.tgz", + "integrity": "sha512-PBgvULgeSswjd8cbZ91gdIcIDMdc3TUHV5XemEpxlqt9M8KoydJzkuB/Dt910jYdofOIaTWRL6adG9nJICvU4A==", "cpu": [ - "arm64" + "arm" ], "optional": true, "os": [ - "android" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.3.tgz", - "integrity": "sha512-smrY2DpzhXvgDhZtQlYAl8+vxJ04lv2/64C1eiRxvsRT2nkw/q+zA1/eAYKvUHat6cIuwqDku3QucmrUT6pCeg==", + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.7.tgz", + "integrity": "sha512-By/a2yeh+e9b+C67F88ndSwVJl2A3tcUDb29FbedDi+DZ4Mr07Oqw9Y1DrDrtHIDhIZ3bmmiL1dkH2YxrtV+zw==", "cpu": [ "arm64" ], "optional": true, "os": [ - "darwin" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.3.tgz", - "integrity": "sha512-NTz8x/LcGUjpZAWUxz0ZuzHao90Wj9spoQgomwB+/hgceh5gcJDfvaBYqxLFpKzVglpnbDSq1Fg0p0zI4oa5Pg==", + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.7.tgz", + "integrity": "sha512-WHYs3cpPEJb/ccyT20NOzopYQkl7JKncNBUbb77YFlwlXMVJLLV3nrXQKhr7DmZxz2ZXqjyUwsj2rdzd9stYdw==", "cpu": [ - "x64" + "arm64" ], "optional": true, "os": [ - "darwin" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.3.tgz", - "integrity": "sha512-yQc9Q0JCOp3kkAV8gKgDctXO60IkQhHpqGB+KgOccDtD5UmN6Q5+gd+lcsDyQ7N8dRuK1fAud51xQpZJgKfm7g==", + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.7.tgz", + "integrity": "sha512-7bP1UyuX9kFxbOwkeIJhBZNevKYPXB6xZI37v09fqi6rqRJR8elybwjMUHm54GVP+UTtJ14ueB1K54Dy1tIO6w==", "cpu": [ "x64" ], "optional": true, "os": [ - "freebsd" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.3.tgz", - "integrity": "sha512-e1ivVMLSnxTOU1O3npnxN16FEyWM/g3SuH2pP6udxXwa0/SnSAijRwcAYRpqIlhVKujr158S8UeHxQjC4fGl4w==", + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.7.tgz", + "integrity": "sha512-gBQIV8nL/LuhARNGeroqzXymMzzW5wQzqlteVqOVoqwEfpHOP3GMird5pGFbnpY+NP0fOlsZGrxxOPQ4W/84bQ==", "cpu": [ - "arm" + "x64" ], "optional": true, "os": [ @@ -1299,604 +2723,1050 @@ "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.3.tgz", - "integrity": "sha512-PLrToqQqX6sdJ9DmMi8IxZWWrfjc9pdi9AEEPTrtMts3Jm9HBi1WqEeF1VwZZ2aW9TXloE5OwA35zuuq1Bhb/Q==", + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.7.tgz", + "integrity": "sha512-aH530NFfx0kpQpvYMfWoeG03zGnRCMVlQG8do/5XeahYydz+6SIBxA1tl/cyITSJyWZHyVt6GVNkXeAD30v0Xg==", "cpu": [ "arm64" ], "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.3.tgz", - "integrity": "sha512-YlzRxx7N1ampfgSKzEDw0iwDkJXUInR4cgNEqmR4TzHkU2Vhg59CGPJrTI7dxOBofD8+O35R13Nk9Ytyv0JUFg==", + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.7.tgz", + "integrity": "sha512-8Cva6bbJN7ZJx320k7vxGGdU0ewmpfS5A4PudyzUuofdi8MgeINuiiWiPQ0VZCda/GX88K6qp+6UpDZNVr8HMQ==", "cpu": [ - "arm64" + "x64" ], "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.3.tgz", - "integrity": "sha512-Xfc3z/li6XkuD7Hs+Uk6pjyCXnfnd9zuQTKOyDTZJ544xc2yoMKUkuDw6Et9wb31MzU2/c0CIUpTDa71lL9KHw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], + "node_modules/@tailwindcss/vite": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.0.7.tgz", + "integrity": "sha512-GYx5sxArfIMtdZCsxfya3S/efMmf4RvfqdiLUozkhmSFBNUFnYVodatpoO/en4/BsOIGvq/RB6HwcTLn9prFnQ==", + "dependencies": { + "@tailwindcss/node": "4.0.7", + "@tailwindcss/oxide": "4.0.7", + "lightningcss": "^1.29.1", + "tailwindcss": "4.0.7" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.13.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", + "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==", + "devOptional": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "devOptional": true + }, + "node_modules/@types/react": { + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "devOptional": true, + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.1.tgz", + "integrity": "sha512-ll1StnKtBigWIGqvYDVuDmXJHVH4zLVot1yQ4fJtLpL7qacwkxJc1T0bptqw+miBQ/QfUbhl1TcQ4accW5KUyA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.24.1", + "@typescript-eslint/type-utils": "8.24.1", + "@typescript-eslint/utils": "8.24.1", + "@typescript-eslint/visitor-keys": "8.24.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.1.tgz", + "integrity": "sha512-Tqoa05bu+t5s8CTZFaGpCH2ub3QeT9YDkXbPd3uQ4SfsLoh1/vv2GEYAioPoxCWJJNsenXlC88tRjwoHNts1oQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.24.1", + "@typescript-eslint/types": "8.24.1", + "@typescript-eslint/typescript-estree": "8.24.1", + "@typescript-eslint/visitor-keys": "8.24.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.1.tgz", + "integrity": "sha512-OdQr6BNBzwRjNEXMQyaGyZzgg7wzjYKfX2ZBV3E04hUCBDv3GQCHiz9RpqdUIiVrMgJGkXm3tcEh4vFSHreS2Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.24.1", + "@typescript-eslint/visitor-keys": "8.24.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.1.tgz", + "integrity": "sha512-/Do9fmNgCsQ+K4rCz0STI7lYB4phTtEXqqCAs3gZW0pnK7lWNkvWd5iW545GSmApm4AzmQXmSqXPO565B4WVrw==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.24.1", + "@typescript-eslint/utils": "8.24.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.1.tgz", + "integrity": "sha512-9kqJ+2DkUXiuhoiYIUvIYjGcwle8pcPpdlfkemGvTObzgmYfJ5d0Qm6jwb4NBXP9W1I5tss0VIAnWFumz3mC5A==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.1.tgz", + "integrity": "sha512-UPyy4MJ/0RE648DSKQe9g0VDSehPINiejjA6ElqnFaFIhI6ZEiZAkUI0D5MCk0bQcTf/LVqZStvQ6K4lPn/BRg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.24.1", + "@typescript-eslint/visitor-keys": "8.24.1", + "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.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">= 10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.3.tgz", - "integrity": "sha512-ugKVqKzwa/cjmqSQG17aS9DYrEcQ/a5NITcgmOr3JLW4Iz64C37eoDlkC8tIepD3S/Td/ywKAolTQ8fKbjEL4g==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">= 10" + "node": ">=10" } }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.3.tgz", - "integrity": "sha512-qHPDMl+UUwsk1RMJMgAXvhraWqUUT+LR/tkXix5RA39UGxtTrHwsLIN1AhNxI5i2RFXAXfmFXDqZCdyQ4dWmAQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@typescript-eslint/utils": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.24.1.tgz", + "integrity": "sha512-OOcg3PMMQx9EXspId5iktsI3eMaXVwlhC8BvNnX6B5w9a4dVgpkQZuU8Hy67TolKcl+iFWq0XX+jbDGN4xWxjQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.24.1", + "@typescript-eslint/types": "8.24.1", + "@typescript-eslint/typescript-estree": "8.24.1" + }, "engines": { - "node": ">= 10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.3.tgz", - "integrity": "sha512-+ujwN4phBGyOsPyLgGgeCyUm4Mul+gqWVCIGuSXWgrx9xVUnf6LVXrw0BDBc9Aq1S2qMyOTX4OkCGbZeoIo8Qw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.1.tgz", + "integrity": "sha512-EwVHlp5l+2vp8CoqJm9KikPZgi3gbdZAtabKT9KPShGeOcJhsv4Zdo3oc8T8I0uKEmYoU4ItyxbptjF08enaxg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.24.1", + "eslint-visitor-keys": "^4.2.0" + }, "engines": { - "node": ">= 10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@tailwindcss/vite": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.0.3.tgz", - "integrity": "sha512-Qj6rSO+EvXnNDymloKZ11D54JJTnDrkRWJBzNHENDxjt0HtrCZJbSLIrcJ/WdaoU4othrel/oFqHpO/doxIS/Q==", + "node_modules/@vitejs/plugin-react": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "dev": true, "dependencies": { - "@tailwindcss/node": "^4.0.3", - "@tailwindcss/oxide": "^4.0.3", - "lightningcss": "^1.29.1", - "tailwindcss": "4.0.3" + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^5.2.0 || ^6" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@babel/types": "^7.20.7" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/@types/node": { - "version": "22.13.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", - "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", - "devOptional": true, + "node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "dependencies": { - "undici-types": "~6.20.0" + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, - "node_modules/@types/prop-types": { - "version": "15.7.14", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", - "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/@types/react": { - "version": "18.3.18", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", - "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@types/react-dom": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", - "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "peerDependencies": { - "@types/react": "^18.0.0" + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz", - "integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==", + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.23.0", - "@typescript-eslint/type-utils": "8.23.0", - "@typescript-eslint/utils": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "bin": { + "browserslist": "cli.js" }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz", - "integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==", - "dev": true, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dependencies": { - "@typescript-eslint/scope-manager": "8.23.0", - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/typescript-estree": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0", - "debug": "^4.3.4" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "node": ">= 0.4" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz", - "integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.0" - }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz", - "integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==", + "node_modules/caniuse-lite": { + "version": "1.0.30001700", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", + "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.23.0", - "@typescript-eslint/utils": "8.23.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@typescript-eslint/types": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", - "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "dependencies": { + "clsx": "^2.1.1" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://polar.sh/cva" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", - "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/visitor-keys": "8.23.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.0.1" - }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6" + } + }, + "node_modules/cmdk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", + "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", + "dependencies": { + "@radix-ui/react-dialog": "1.0.5", + "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", "dependencies": { - "balanced-match": "^1.0.0" + "@babel/runtime": "^7.13.10" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", "dependencies": { - "brace-expansion": "^2.0.1" + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">=16 || 14 >=14.17" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node_modules/cmdk/node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", + "dependencies": { + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", - "integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.23.0", - "@typescript-eslint/types": "8.23.0", - "@typescript-eslint/typescript-estree": "8.23.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", - "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", "dependencies": { - "@typescript-eslint/types": "8.23.0", - "eslint-visitor-keys": "^4.2.0" + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@vitejs/plugin-react": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", - "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", "dependencies": { - "@babel/core": "^7.26.0", - "@babel/plugin-transform-react-jsx-self": "^7.25.9", - "@babel/plugin-transform-react-jsx-source": "^7.25.9", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" + "node_modules/cmdk/node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", + "dependencies": { + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">=0.4.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", "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" + "@babel/runtime": "^7.13.10" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", "dependencies": { - "color-convert": "^2.0.1" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "node_modules/cmdk/node_modules/@radix-ui/react-id/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "node_modules/cmdk/node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "node_modules/cmdk/node_modules/@radix-ui/react-presence/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", "dependencies": { - "fill-range": "^7.1.1" + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" + "node_modules/cmdk/node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" + "@types/react-dom": { + "optional": true } - ], + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" }, - "bin": { - "browserslist": "cli.js" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" + "node_modules/cmdk/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001697", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz", - "integrity": "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" + "node_modules/cmdk/node_modules/@radix-ui/react-use-controllable-state/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true } - ] + } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "node_modules/cmdk/node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" }, "engines": { "node": ">=10" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/color-convert": { @@ -1959,14 +3829,132 @@ "which": "^2.0.1" }, "engines": { - "node": ">= 8" + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "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" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } }, "node_modules/debug": { "version": "4.4.0", @@ -1985,6 +3973,11 @@ } } }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2010,12 +4003,64 @@ "node": ">=0.10" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { - "version": "1.5.92", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.92.tgz", - "integrity": "sha512-BeHgmNobs05N1HMmMZ7YIuHfYBGlq/UmvlsTgg+fsbFs9xVMj+xJHFg19GN04+9Q+r8Xnh9LXqaYIyEWElnNgQ==", + "version": "1.5.102", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz", + "integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==", "dev": true }, + "node_modules/embla-carousel": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.5.2.tgz", + "integrity": "sha512-xQ9oVLrun/eCG/7ru3R+I5bJ7shsD8fFwLEY7yPe27/+fDHCNj0OT5EoG5ZbFyOxOcG6yTwW8oTz/dWyFnyGpg==" + }, + "node_modules/embla-carousel-react": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.5.2.tgz", + "integrity": "sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==", + "dependencies": { + "embla-carousel": "8.5.2", + "embla-carousel-reactive-utils": "8.5.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/embla-carousel-reactive-utils": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.5.2.tgz", + "integrity": "sha512-QC8/hYSK/pEmqEdU1IO5O+XNc/Ptmmq7uCB44vKplgLKhB/l0+yvYx0+Cv0sF6Ena8Srld5vUErZkT+yTahtDg==", + "peerDependencies": { + "embla-carousel": "8.5.2" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", @@ -2028,6 +4073,47 @@ "node": ">=10.13.0" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", @@ -2089,17 +4175,17 @@ } }, "node_modules/eslint": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", - "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", + "version": "9.20.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.1.tgz", + "integrity": "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.11.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.19.0", + "@eslint/js": "9.20.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -2160,9 +4246,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.18.tgz", - "integrity": "sha512-IRGEoFn3OKalm3hjfolEWGqoF/jPqeEYFp+C8B0WMzwGwBMvlRDQd06kghDhF0C61uJ6WfSDhEZE/sAQjduKgw==", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.19.tgz", + "integrity": "sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==", "dev": true, "peerDependencies": { "eslint": ">=8.40" @@ -2255,12 +4341,25 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-equals": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", + "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -2364,9 +4463,9 @@ } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true }, "node_modules/follow-redirects": { @@ -2389,12 +4488,13 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { @@ -2414,6 +4514,14 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2423,6 +4531,49 @@ "node": ">=6.9.0" } }, + "node_modules/get-intrinsic": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2436,9 +4587,9 @@ } }, "node_modules/globals": { - "version": "15.14.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", - "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "engines": { "node": ">=18" @@ -2447,6 +4598,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2467,6 +4629,42 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2501,6 +4699,23 @@ "node": ">=0.8.19" } }, + "node_modules/input-otp": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", + "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2858,6 +5073,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2884,6 +5104,22 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.445.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.445.0.tgz", + "integrity": "sha512-YrLf3aAHvmd4dZ8ot+mMdNFrFpJD7YRwQ2pUcBhgqbmxtrMP4xDzIorcj+8y+6kpuXBF4JB0NOCTUWIYetJjgA==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2966,12 +5202,29 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/next-themes": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.4.tgz", + "integrity": "sha512-LDQ2qIOJF0VnuVrrMSMLrWGjRMkq+0mpgl6e0juCLqdJ+oo8Q84JRWT6Wh11VDQKkMMe+dVzDKLWs5n87T+PkQ==", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3067,9 +5320,9 @@ } }, "node_modules/postcss": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", - "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", + "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", "funding": [ { "type": "opencollective", @@ -3102,6 +5355,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -3147,6 +5415,19 @@ "node": ">=0.10.0" } }, + "node_modules/react-day-picker": { + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz", + "integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "date-fns": "^2.28.0 || ^3.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -3159,6 +5440,26 @@ "react": "^18.3.1" } }, + "node_modules/react-hook-form": { + "version": "7.54.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.2.tgz", + "integrity": "sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -3168,6 +5469,60 @@ "node": ">=0.10.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-resizable-panels": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.7.tgz", + "integrity": "sha512-JtT6gI+nURzhMYQYsx8DKkx6bSoOGFp7A3CwMrOb8y5jFHFyqwo9m68UhmXRw57fRVJksFn1TSlm3ywEQ9vMgA==", + "peerDependencies": { + "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/react-router": { "version": "6.29.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.29.0.tgz", @@ -3183,11 +5538,11 @@ } }, "node_modules/react-router-dom": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.1.5.tgz", - "integrity": "sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.2.0.tgz", + "integrity": "sha512-cU7lTxETGtQRQbafJubvZKHEn5izNABxZhBY0Jlzdv0gqQhCPQt2J8aN5ZPjS6mQOXn5NnirWNh+FpE8TTYN0Q==", "dependencies": { - "react-router": "7.1.5" + "react-router": "7.2.0" }, "engines": { "node": ">=20.0.0" @@ -3198,9 +5553,9 @@ } }, "node_modules/react-router-dom/node_modules/react-router": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", - "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.2.0.tgz", + "integrity": "sha512-fXyqzPgCPZbqhrk7k3hPcCpYIlQ2ugIXDboHUzhJISFVy2DEPsmHgN588MyGmkIOv3jDgNfUE3kJi83L28s/LQ==", "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^1.0.1", @@ -3220,6 +5575,91 @@ } } }, + "node_modules/react-smooth": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "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" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "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" + } + }, + "node_modules/recharts": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.1.tgz", + "integrity": "sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==", + "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" + }, + "engines": { + "node": ">=14" + }, + "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" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3240,9 +5680,9 @@ } }, "node_modules/rollup": { - "version": "4.34.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.4.tgz", - "integrity": "sha512-spF66xoyD7rz3o08sHP7wogp1gZ6itSq22SGa/IZTcUDXDlOyrShwMwkVSB+BUxFRZZCUYqdb3KWDEOMVQZxuw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", + "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", "dependencies": { "@types/estree": "1.0.6" }, @@ -3254,25 +5694,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.4", - "@rollup/rollup-android-arm64": "4.34.4", - "@rollup/rollup-darwin-arm64": "4.34.4", - "@rollup/rollup-darwin-x64": "4.34.4", - "@rollup/rollup-freebsd-arm64": "4.34.4", - "@rollup/rollup-freebsd-x64": "4.34.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.4", - "@rollup/rollup-linux-arm-musleabihf": "4.34.4", - "@rollup/rollup-linux-arm64-gnu": "4.34.4", - "@rollup/rollup-linux-arm64-musl": "4.34.4", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.4", - "@rollup/rollup-linux-riscv64-gnu": "4.34.4", - "@rollup/rollup-linux-s390x-gnu": "4.34.4", - "@rollup/rollup-linux-x64-gnu": "4.34.4", - "@rollup/rollup-linux-x64-musl": "4.34.4", - "@rollup/rollup-win32-arm64-msvc": "4.34.4", - "@rollup/rollup-win32-ia32-msvc": "4.34.4", - "@rollup/rollup-win32-x64-msvc": "4.34.4", + "@rollup/rollup-android-arm-eabi": "4.34.8", + "@rollup/rollup-android-arm64": "4.34.8", + "@rollup/rollup-darwin-arm64": "4.34.8", + "@rollup/rollup-darwin-x64": "4.34.8", + "@rollup/rollup-freebsd-arm64": "4.34.8", + "@rollup/rollup-freebsd-x64": "4.34.8", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", + "@rollup/rollup-linux-arm-musleabihf": "4.34.8", + "@rollup/rollup-linux-arm64-gnu": "4.34.8", + "@rollup/rollup-linux-arm64-musl": "4.34.8", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", + "@rollup/rollup-linux-riscv64-gnu": "4.34.8", + "@rollup/rollup-linux-s390x-gnu": "4.34.8", + "@rollup/rollup-linux-x64-gnu": "4.34.8", + "@rollup/rollup-linux-x64-musl": "4.34.8", + "@rollup/rollup-win32-arm64-msvc": "4.34.8", + "@rollup/rollup-win32-ia32-msvc": "4.34.8", + "@rollup/rollup-win32-x64-msvc": "4.34.8", "fsevents": "~2.3.2" } }, @@ -3342,6 +5782,15 @@ "node": ">=8" } }, + "node_modules/sonner": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz", + "integrity": "sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -3374,10 +5823,27 @@ "node": ">=8" } }, + "node_modules/tailwind-merge": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", + "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.3.tgz", - "integrity": "sha512-ImmZF0Lon5RrQpsEAKGxRvHwCvMgSC4XVlFRqmbzTEDb/3wvin9zfEZrMwgsa3yqBbPqahYcVI6lulM2S7IZAA==" + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.7.tgz", + "integrity": "sha512-yH5bPPyapavo7L+547h3c4jcBXcrKwybQRjwdEIVAd9iXRvy/3T1CC6XSQEgZtRySjKfqvo3Cc0ZF1DTheuIdA==" + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } }, "node_modules/tapable": { "version": "2.2.1", @@ -3387,6 +5853,11 @@ "node": ">=6" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3411,6 +5882,11 @@ "typescript": ">=4.8.4" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "node_modules/turbo-stream": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", @@ -3442,14 +5918,14 @@ } }, "node_modules/typescript-eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.23.0.tgz", - "integrity": "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==", + "version": "8.24.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.24.1.tgz", + "integrity": "sha512-cw3rEdzDqBs70TIcb0Gdzbt6h11BSs2pS0yaq7hDWDBtCCSei1pPSUXE9qUdQ/Wm9NgFg8mKtMt1b8fTHIl1jA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.23.0", - "@typescript-eslint/parser": "8.23.0", - "@typescript-eslint/utils": "8.23.0" + "@typescript-eslint/eslint-plugin": "8.24.1", + "@typescript-eslint/parser": "8.24.1", + "@typescript-eslint/utils": "8.24.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3508,6 +5984,80 @@ "punycode": "^2.1.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/vaul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", + "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "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" + } + }, "node_modules/vite": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", @@ -3619,6 +6169,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.24.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", + "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/backend/template/react-ts/package.json b/backend/template/react-ts/package.json index 2c6d31cc..60b4587e 100644 --- a/backend/template/react-ts/package.json +++ b/backend/template/react-ts/package.json @@ -10,13 +10,59 @@ "preview": "vite preview" }, "dependencies": { + "@hookform/resolvers": "^4.1.0", + "@radix-ui/react-accordion": "^1.2.3", + "@radix-ui/react-alert-dialog": "^1.1.6", + "@radix-ui/react-aspect-ratio": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", + "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-context-menu": "^2.2.6", + "@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-label": "^2.1.2", + "@radix-ui/react-menubar": "^1.1.6", + "@radix-ui/react-navigation-menu": "^1.2.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-scroll-area": "^1.2.3", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.3", + "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-toast": "^1.2.6", + "@radix-ui/react-toggle": "^1.1.2", + "@radix-ui/react-toggle-group": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", "@tailwindcss/vite": "^4.0.0", "axios": "^1.7.9", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "cmdk": "^1.0.0", + "date-fns": "^3.6.0", + "embla-carousel-react": "^8.5.2", + "framer-motion": "^12.5.0", + "input-otp": "^1.4.2", + "lucide-react": "^0.445.0", + "next-themes": "^0.4.4", "react": "^18.3.1", + "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.54.2", + "react-resizable-panels": "^2.1.7", "react-router": "^6.28.2", "react-router-dom": "^7.1.5", - "tailwindcss": "^4.0.0" + "recharts": "^2.15.1", + "sonner": "^1.7.4", + "tailwind-merge": "^2.6.0", + "tailwindcss": "^4.0.0", + "tailwindcss-animate": "^1.0.7", + "vaul": "^1.1.2", + "zod": "^3.24.2" }, "devDependencies": { "@eslint/js": "^9.15.0", diff --git a/backend/template/react-ts/src/components/ui/accordion.tsx b/backend/template/react-ts/src/components/ui/accordion.tsx new file mode 100644 index 00000000..27effab8 --- /dev/null +++ b/backend/template/react-ts/src/components/ui/accordion.tsx @@ -0,0 +1,64 @@ +import * as React from 'react'; +import * as AccordionPrimitive from '@radix-ui/react-accordion'; +import { ChevronDownIcon } from 'lucide-react'; + +import { cn } from '@/lib/utils'; + +function Accordion({ + ...props +}: React.ComponentProps) { + return ; +} + +function AccordionItem({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AccordionTrigger({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + svg]:rotate-180', + className, + )} + {...props} + > + {children} + + + + ); +} + +function AccordionContent({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + +
{children}
+
+ ); +} + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/backend/template/react-ts/src/components/ui/alert-dialog.tsx b/backend/template/react-ts/src/components/ui/alert-dialog.tsx new file mode 100644 index 00000000..0ac251a7 --- /dev/null +++ b/backend/template/react-ts/src/components/ui/alert-dialog.tsx @@ -0,0 +1,157 @@ +'use client'; + +import * as React from 'react'; +import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'; + +import { cn } from '@/lib/utils'; +import { buttonVariants } from '@/components/ui/button'; + +function AlertDialog({ + ...props +}: React.ComponentProps) { + return ; +} + +function AlertDialogTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogPortal({ + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogContent({ + className, + ...props +}: React.ComponentProps) { + return ( + + + + + ); +} + +function AlertDialogHeader({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function AlertDialogFooter({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function AlertDialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogAction({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogCancel({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +}; diff --git a/backend/template/react-ts/src/components/ui/alert.tsx b/backend/template/react-ts/src/components/ui/alert.tsx new file mode 100644 index 00000000..e795b8d2 --- /dev/null +++ b/backend/template/react-ts/src/components/ui/alert.tsx @@ -0,0 +1,66 @@ +import * as React from 'react'; +import { cva, type VariantProps } from 'class-variance-authority'; + +import { cn } from '@/lib/utils'; + +const alertVariants = cva( + 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current', + { + variants: { + variant: { + default: 'bg-background text-foreground', + destructive: + 'border-destructive/50 text-destructive dark:text-destructive-foreground/80 dark:border-destructive [&>svg]:text-current dark:bg-destructive/50', + }, + }, + defaultVariants: { + variant: 'default', + }, + }, +); + +function Alert({ + className, + variant, + ...props +}: React.ComponentProps<'div'> & VariantProps) { + return ( +
+ ); +} + +function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function AlertDescription({ + className, + ...props +}: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +export { Alert, AlertTitle, AlertDescription }; diff --git a/backend/template/react-ts/src/components/ui/aspect-ratio.tsx b/backend/template/react-ts/src/components/ui/aspect-ratio.tsx new file mode 100644 index 00000000..e050a630 --- /dev/null +++ b/backend/template/react-ts/src/components/ui/aspect-ratio.tsx @@ -0,0 +1,9 @@ +import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio'; + +function AspectRatio({ + ...props +}: React.ComponentProps) { + return ; +} + +export { AspectRatio }; diff --git a/backend/template/react-ts/src/components/ui/avatar.tsx b/backend/template/react-ts/src/components/ui/avatar.tsx new file mode 100644 index 00000000..3b750b64 --- /dev/null +++ b/backend/template/react-ts/src/components/ui/avatar.tsx @@ -0,0 +1,53 @@ +'use client'; + +import * as React from 'react'; +import * as AvatarPrimitive from '@radix-ui/react-avatar'; + +import { cn } from '@/lib/utils'; + +function Avatar({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AvatarImage({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function AvatarFallback({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/backend/template/react-ts/src/components/ui/badge.tsx b/backend/template/react-ts/src/components/ui/badge.tsx new file mode 100644 index 00000000..930aeb4a --- /dev/null +++ b/backend/template/react-ts/src/components/ui/badge.tsx @@ -0,0 +1,46 @@ +import * as React from 'react'; +import { Slot } from '@radix-ui/react-slot'; +import { cva, type VariantProps } from 'class-variance-authority'; + +import { cn } from '@/lib/utils'; + +const badgeVariants = cva( + 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-semibold w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0 transition-[color,box-shadow]', + { + variants: { + variant: { + default: + 'border-transparent bg-primary text-primary-foreground shadow-sm [a&]:hover:bg-primary/90', + secondary: + 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90', + destructive: + 'border-transparent bg-destructive text-destructive-foreground shadow-sm [a&]:hover:bg-destructive/90', + outline: + 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground', + }, + }, + defaultVariants: { + variant: 'default', + }, + }, +); + +function Badge({ + className, + variant, + asChild = false, + ...props +}: React.ComponentProps<'span'> & + VariantProps & { asChild?: boolean }) { + const Comp = asChild ? Slot : 'span'; + + return ( + + ); +} + +export { Badge, badgeVariants }; diff --git a/backend/template/react-ts/src/components/ui/breadcrumb.tsx b/backend/template/react-ts/src/components/ui/breadcrumb.tsx new file mode 100644 index 00000000..74fa1f4d --- /dev/null +++ b/backend/template/react-ts/src/components/ui/breadcrumb.tsx @@ -0,0 +1,109 @@ +import * as React from 'react'; +import { Slot } from '@radix-ui/react-slot'; +import { ChevronRight, MoreHorizontal } from 'lucide-react'; + +import { cn } from '@/lib/utils'; + +function Breadcrumb({ ...props }: React.ComponentProps<'nav'>) { + return