From 9c94f96cfd7907a7abdd59725aa4666f2d1ad36d Mon Sep 17 00:00:00 2001 From: Ualerson Date: Fri, 3 Oct 2025 14:09:19 -0300 Subject: [PATCH 01/10] undefined undefined --- .gitignore | 2 +- Back-End/Agents/ContextLayer/ai.py | 0 Back-End/Agents/GitContextLayer/ai.py | 170 + Back-End/Dockerfile | 10 - Back-End/Models/postgreSQL.py | 2 + Back-End/Modules/Geters/logs.py | 2 - Back-End/Modules/Geters/plans_data.py | 38 + Back-End/Modules/Geters/pr_diff.py | 2 - Back-End/Modules/Resolvers/github_app_auth.py | 113 + Back-End/Modules/Resolvers/user_identifier.py | 4 - .../Modules/Resolvers/verify_signature.py | 23 + Back-End/Modules/Savers/log_action.py | 10 +- Back-End/{ => TestDiscovery}/gen-prai.py | 0 Back-End/api.py | 459 +- Back-End/git_context_layer.py | 343 + Back-End/observer.py | 12 +- Back-End/requirements.txt | 4 +- Front-End/git-genius-commit/.env | 1 + Front-End/git-genius-commit/.gitignore | 24 + Front-End/git-genius-commit/README.md | 73 + Front-End/git-genius-commit/bun.lockb | Bin 0 -> 197327 bytes Front-End/git-genius-commit/components.json | 20 + Front-End/git-genius-commit/electron/main.cjs | 370 + .../git-genius-commit/electron/preload.cjs | 36 + Front-End/git-genius-commit/eslint.config.js | 26 + Front-End/git-genius-commit/index.html | 24 + .../{ => git-genius-commit}/package-lock.json | 2836 ++-- .../{ => git-genius-commit}/package.json | 40 +- Front-End/git-genius-commit/postcss.config.js | 6 + .../public/favicon.ico | Bin .../public/placeholder.svg | 0 .../{ => git-genius-commit}/public/robots.txt | 0 Front-End/{ => git-genius-commit}/src/App.css | 0 Front-End/git-genius-commit/src/App.tsx | 27 + .../src/components/CommitPreview.tsx | 87 + .../src/components/ConfigPanel.tsx | 204 + .../src/components/DiffViewer.tsx | 83 + .../src/components/RepositorySelector.tsx | 50 + .../src/components/StatusMonitor.tsx | 76 + .../src/components/ui/accordion.tsx | 52 + .../src/components/ui/alert-dialog.tsx | 104 + .../src/components/ui/alert.tsx | 43 + .../src/components/ui/aspect-ratio.tsx | 5 + .../src/components/ui/avatar.tsx | 38 + .../src/components/ui/badge.tsx | 29 + .../src/components/ui/breadcrumb.tsx | 90 + .../src/components/ui/button.tsx | 47 + .../src/components/ui/calendar.tsx | 54 + .../src/components/ui/card.tsx | 43 + .../src/components/ui/carousel.tsx | 224 + .../src/components/ui/chart.tsx | 303 + .../src/components/ui/checkbox.tsx | 26 + .../src/components/ui/collapsible.tsx | 9 + .../src/components/ui/command.tsx | 132 + .../src/components/ui/context-menu.tsx | 178 + .../src/components/ui/dialog.tsx | 95 + .../src/components/ui/drawer.tsx | 87 + .../src/components/ui/dropdown-menu.tsx | 179 + .../src/components/ui/form.tsx | 129 + .../src/components/ui/hover-card.tsx | 27 + .../src/components/ui/input-otp.tsx | 61 + .../src/components/ui/input.tsx | 22 + .../src/components/ui/label.tsx | 17 + .../src/components/ui/menubar.tsx | 207 + .../src/components/ui/navigation-menu.tsx | 120 + .../src/components/ui/pagination.tsx | 81 + .../src/components/ui/popover.tsx | 29 + .../src/components/ui/progress.tsx | 23 + .../src/components/ui/radio-group.tsx | 36 + .../src/components/ui/resizable.tsx | 37 + .../src/components/ui/scroll-area.tsx | 38 + .../src/components/ui/select.tsx | 143 + .../src/components/ui/separator.tsx | 20 + .../src/components/ui/sheet.tsx | 107 + .../src/components/ui/sidebar.tsx | 637 + .../src/components/ui/skeleton.tsx | 7 + .../src/components/ui/slider.tsx | 23 + .../src/components/ui/sonner.tsx | 27 + .../src/components/ui/switch.tsx | 27 + .../src/components/ui/table.tsx | 72 + .../src/components/ui/tabs.tsx | 53 + .../src/components/ui/textarea.tsx | 21 + .../src/components/ui/toast.tsx | 111 + .../src/components/ui/toaster.tsx | 24 + .../src/components/ui/toggle-group.tsx | 49 + .../src/components/ui/toggle.tsx | 37 + .../src/components/ui/tooltip.tsx | 28 + .../src/components/ui/use-toast.ts | 0 .../src/hooks/use-mobile.tsx | 19 + .../git-genius-commit/src/hooks/use-toast.ts | 186 + .../src/hooks/useGitOperations.ts | 199 + Front-End/git-genius-commit/src/index.css | 101 + Front-End/git-genius-commit/src/lib/utils.ts | 6 + Front-End/git-genius-commit/src/main.tsx | 5 + .../git-genius-commit/src/pages/Index.tsx | 181 + .../git-genius-commit/src/pages/NotFound.tsx | 24 + .../git-genius-commit/src/types/electron.d.ts | 10 + Front-End/git-genius-commit/src/types/git.ts | 43 + .../{ => git-genius-commit}/src/vite-env.d.ts | 0 .../git-genius-commit/tailwind.config.ts | 110 + Front-End/git-genius-commit/tsconfig.app.json | 30 + Front-End/git-genius-commit/tsconfig.json | 23 + .../git-genius-commit/tsconfig.node.json | 22 + Front-End/git-genius-commit/vite.config.ts | 18 + Front-End/{ => webpr}/.dockerignore | 0 Front-End/{ => webpr}/.env | 0 Front-End/{ => webpr}/Dockerfile | 0 Front-End/{ => webpr}/bun.lockb | Bin Front-End/{ => webpr}/components.json | 0 Front-End/{ => webpr}/eslint.config.js | 0 Front-End/{ => webpr}/index.html | 0 Front-End/webpr/package-lock.json | 11768 ++++++++++++++++ Front-End/webpr/package.json | 119 + Front-End/{ => webpr}/postcss.config.js | 0 Front-End/webpr/public/favicon.ico | Bin 0 -> 7645 bytes Front-End/{ => webpr}/public/icone.png | Bin Front-End/webpr/public/placeholder.svg | 1 + Front-End/webpr/public/robots.txt | 14 + Front-End/webpr/src/App.css | 42 + Front-End/{ => webpr}/src/App.tsx | 0 .../{ => webpr}/src/assets/hero-image.jpg | Bin Front-End/{ => webpr}/src/assets/logo.png | Bin .../src/components/ProtectedRoute.tsx | 0 .../src/components/app-sidebar.tsx | 0 .../src/components/cta-section.tsx | 0 .../src/components/features-section.tsx | 0 .../{ => webpr}/src/components/footer.tsx | 0 .../{ => webpr}/src/components/header.tsx | 0 .../src/components/hero-section.tsx | 0 .../{ => webpr}/src/components/layout.tsx | 0 .../src/components/pricing-section.tsx | 0 .../src/components/ui/accordion.tsx | 0 .../src/components/ui/alert-dialog.tsx | 0 .../{ => webpr}/src/components/ui/alert.tsx | 0 .../src/components/ui/aspect-ratio.tsx | 0 .../{ => webpr}/src/components/ui/avatar.tsx | 0 .../{ => webpr}/src/components/ui/badge.tsx | 0 .../src/components/ui/breadcrumb.tsx | 0 .../{ => webpr}/src/components/ui/button.tsx | 0 .../src/components/ui/calendar.tsx | 0 .../{ => webpr}/src/components/ui/card.tsx | 0 .../src/components/ui/carousel.tsx | 0 .../{ => webpr}/src/components/ui/chart.tsx | 0 .../src/components/ui/checkbox.tsx | 0 .../src/components/ui/collapsible.tsx | 0 .../{ => webpr}/src/components/ui/command.tsx | 0 .../src/components/ui/context-menu.tsx | 0 .../{ => webpr}/src/components/ui/dialog.tsx | 0 .../{ => webpr}/src/components/ui/drawer.tsx | 0 .../src/components/ui/dropdown-menu.tsx | 0 .../{ => webpr}/src/components/ui/form.tsx | 0 .../src/components/ui/hover-card.tsx | 0 .../src/components/ui/input-otp.tsx | 0 .../{ => webpr}/src/components/ui/input.tsx | 0 .../{ => webpr}/src/components/ui/label.tsx | 0 .../{ => webpr}/src/components/ui/menubar.tsx | 0 .../src/components/ui/navigation-menu.tsx | 0 .../src/components/ui/pagination.tsx | 0 .../{ => webpr}/src/components/ui/popover.tsx | 0 .../src/components/ui/progress.tsx | 0 .../src/components/ui/radio-group.tsx | 0 .../src/components/ui/resizable.tsx | 0 .../src/components/ui/scroll-area.tsx | 0 .../{ => webpr}/src/components/ui/select.tsx | 0 .../src/components/ui/separator.tsx | 0 .../{ => webpr}/src/components/ui/sheet.tsx | 0 .../{ => webpr}/src/components/ui/sidebar.tsx | 0 .../src/components/ui/skeleton.tsx | 0 .../{ => webpr}/src/components/ui/slider.tsx | 0 .../{ => webpr}/src/components/ui/sonner.tsx | 0 .../{ => webpr}/src/components/ui/switch.tsx | 0 .../{ => webpr}/src/components/ui/table.tsx | 0 .../{ => webpr}/src/components/ui/tabs.tsx | 0 .../src/components/ui/textarea.tsx | 0 .../{ => webpr}/src/components/ui/toast.tsx | 0 .../{ => webpr}/src/components/ui/toaster.tsx | 0 .../src/components/ui/toggle-group.tsx | 0 .../{ => webpr}/src/components/ui/toggle.tsx | 0 .../{ => webpr}/src/components/ui/tooltip.tsx | 0 .../webpr/src/components/ui/use-toast.ts | 3 + .../{ => webpr}/src/constants/landingpage.ts | 0 .../{ => webpr}/src/contexts/AuthContext.tsx | 0 .../{ => webpr}/src/hooks/use-mobile.tsx | 0 Front-End/{ => webpr}/src/hooks/use-toast.ts | 0 Front-End/{ => webpr}/src/index.css | 0 Front-End/{ => webpr}/src/lib/utils.ts | 0 Front-End/{ => webpr}/src/main.tsx | 0 Front-End/{ => webpr}/src/pages/Billing.tsx | 0 .../{ => webpr}/src/pages/CheckoutError.tsx | 0 .../{ => webpr}/src/pages/CheckoutSuccess.tsx | 0 Front-End/{ => webpr}/src/pages/Controls.tsx | 0 Front-End/{ => webpr}/src/pages/Dashboard.tsx | 0 Front-End/{ => webpr}/src/pages/Invoices.tsx | 0 .../{ => webpr}/src/pages/Landingpage.tsx | 0 Front-End/{ => webpr}/src/pages/Login.tsx | 0 Front-End/{ => webpr}/src/pages/Logs.tsx | 0 Front-End/{ => webpr}/src/pages/MyAccount.tsx | 0 Front-End/{ => webpr}/src/pages/NotFound.tsx | 0 .../{ => webpr}/src/pages/PullRequests.tsx | 0 Front-End/{ => webpr}/src/pages/Settings.tsx | 0 .../{ => webpr}/src/pages/SignupCheckout.tsx | 0 Front-End/{ => webpr}/src/pages/Workflows.tsx | 0 Front-End/webpr/src/vite-env.d.ts | 1 + Front-End/{ => webpr}/tailwind.config.ts | 0 Front-End/{ => webpr}/tsconfig.app.json | 0 Front-End/{ => webpr}/tsconfig.json | 0 Front-End/{ => webpr}/tsconfig.node.json | 0 Front-End/{ => webpr}/vite.config.ts | 0 LICENSE | 674 - build.py | 2 +- docker-compose.yml | 6 +- 211 files changed, 20039 insertions(+), 2696 deletions(-) delete mode 100644 Back-End/Agents/ContextLayer/ai.py create mode 100644 Back-End/Agents/GitContextLayer/ai.py create mode 100644 Back-End/Modules/Geters/plans_data.py create mode 100644 Back-End/Modules/Resolvers/github_app_auth.py create mode 100644 Back-End/Modules/Resolvers/verify_signature.py rename Back-End/{ => TestDiscovery}/gen-prai.py (100%) create mode 100644 Back-End/git_context_layer.py create mode 100644 Front-End/git-genius-commit/.env create mode 100644 Front-End/git-genius-commit/.gitignore create mode 100644 Front-End/git-genius-commit/README.md create mode 100644 Front-End/git-genius-commit/bun.lockb create mode 100644 Front-End/git-genius-commit/components.json create mode 100644 Front-End/git-genius-commit/electron/main.cjs create mode 100644 Front-End/git-genius-commit/electron/preload.cjs create mode 100644 Front-End/git-genius-commit/eslint.config.js create mode 100644 Front-End/git-genius-commit/index.html rename Front-End/{ => git-genius-commit}/package-lock.json (72%) rename Front-End/{ => git-genius-commit}/package.json (73%) create mode 100644 Front-End/git-genius-commit/postcss.config.js rename Front-End/{ => git-genius-commit}/public/favicon.ico (100%) rename Front-End/{ => git-genius-commit}/public/placeholder.svg (100%) rename Front-End/{ => git-genius-commit}/public/robots.txt (100%) rename Front-End/{ => git-genius-commit}/src/App.css (100%) create mode 100644 Front-End/git-genius-commit/src/App.tsx create mode 100644 Front-End/git-genius-commit/src/components/CommitPreview.tsx create mode 100644 Front-End/git-genius-commit/src/components/ConfigPanel.tsx create mode 100644 Front-End/git-genius-commit/src/components/DiffViewer.tsx create mode 100644 Front-End/git-genius-commit/src/components/RepositorySelector.tsx create mode 100644 Front-End/git-genius-commit/src/components/StatusMonitor.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/accordion.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/alert-dialog.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/alert.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/aspect-ratio.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/avatar.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/badge.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/breadcrumb.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/button.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/calendar.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/card.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/carousel.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/chart.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/checkbox.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/collapsible.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/command.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/context-menu.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/dialog.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/drawer.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/dropdown-menu.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/form.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/hover-card.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/input-otp.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/input.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/label.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/menubar.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/navigation-menu.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/pagination.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/popover.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/progress.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/radio-group.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/resizable.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/scroll-area.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/select.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/separator.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/sheet.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/sidebar.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/skeleton.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/slider.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/sonner.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/switch.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/table.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/tabs.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/textarea.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/toast.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/toaster.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/toggle-group.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/toggle.tsx create mode 100644 Front-End/git-genius-commit/src/components/ui/tooltip.tsx rename Front-End/{ => git-genius-commit}/src/components/ui/use-toast.ts (100%) create mode 100644 Front-End/git-genius-commit/src/hooks/use-mobile.tsx create mode 100644 Front-End/git-genius-commit/src/hooks/use-toast.ts create mode 100644 Front-End/git-genius-commit/src/hooks/useGitOperations.ts create mode 100644 Front-End/git-genius-commit/src/index.css create mode 100644 Front-End/git-genius-commit/src/lib/utils.ts create mode 100644 Front-End/git-genius-commit/src/main.tsx create mode 100644 Front-End/git-genius-commit/src/pages/Index.tsx create mode 100644 Front-End/git-genius-commit/src/pages/NotFound.tsx create mode 100644 Front-End/git-genius-commit/src/types/electron.d.ts create mode 100644 Front-End/git-genius-commit/src/types/git.ts rename Front-End/{ => git-genius-commit}/src/vite-env.d.ts (100%) create mode 100644 Front-End/git-genius-commit/tailwind.config.ts create mode 100644 Front-End/git-genius-commit/tsconfig.app.json create mode 100644 Front-End/git-genius-commit/tsconfig.json create mode 100644 Front-End/git-genius-commit/tsconfig.node.json create mode 100644 Front-End/git-genius-commit/vite.config.ts rename Front-End/{ => webpr}/.dockerignore (100%) rename Front-End/{ => webpr}/.env (100%) rename Front-End/{ => webpr}/Dockerfile (100%) rename Front-End/{ => webpr}/bun.lockb (100%) rename Front-End/{ => webpr}/components.json (100%) rename Front-End/{ => webpr}/eslint.config.js (100%) rename Front-End/{ => webpr}/index.html (100%) create mode 100644 Front-End/webpr/package-lock.json create mode 100644 Front-End/webpr/package.json rename Front-End/{ => webpr}/postcss.config.js (100%) create mode 100644 Front-End/webpr/public/favicon.ico rename Front-End/{ => webpr}/public/icone.png (100%) create mode 100644 Front-End/webpr/public/placeholder.svg create mode 100644 Front-End/webpr/public/robots.txt create mode 100644 Front-End/webpr/src/App.css rename Front-End/{ => webpr}/src/App.tsx (100%) rename Front-End/{ => webpr}/src/assets/hero-image.jpg (100%) rename Front-End/{ => webpr}/src/assets/logo.png (100%) rename Front-End/{ => webpr}/src/components/ProtectedRoute.tsx (100%) rename Front-End/{ => webpr}/src/components/app-sidebar.tsx (100%) rename Front-End/{ => webpr}/src/components/cta-section.tsx (100%) rename Front-End/{ => webpr}/src/components/features-section.tsx (100%) rename Front-End/{ => webpr}/src/components/footer.tsx (100%) rename Front-End/{ => webpr}/src/components/header.tsx (100%) rename Front-End/{ => webpr}/src/components/hero-section.tsx (100%) rename Front-End/{ => webpr}/src/components/layout.tsx (100%) rename Front-End/{ => webpr}/src/components/pricing-section.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/accordion.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/alert-dialog.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/alert.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/aspect-ratio.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/avatar.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/badge.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/breadcrumb.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/button.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/calendar.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/card.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/carousel.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/chart.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/checkbox.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/collapsible.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/command.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/context-menu.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/dialog.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/drawer.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/dropdown-menu.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/form.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/hover-card.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/input-otp.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/input.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/label.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/menubar.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/navigation-menu.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/pagination.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/popover.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/progress.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/radio-group.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/resizable.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/scroll-area.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/select.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/separator.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/sheet.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/sidebar.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/skeleton.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/slider.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/sonner.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/switch.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/table.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/tabs.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/textarea.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/toast.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/toaster.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/toggle-group.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/toggle.tsx (100%) rename Front-End/{ => webpr}/src/components/ui/tooltip.tsx (100%) create mode 100644 Front-End/webpr/src/components/ui/use-toast.ts rename Front-End/{ => webpr}/src/constants/landingpage.ts (100%) rename Front-End/{ => webpr}/src/contexts/AuthContext.tsx (100%) rename Front-End/{ => webpr}/src/hooks/use-mobile.tsx (100%) rename Front-End/{ => webpr}/src/hooks/use-toast.ts (100%) rename Front-End/{ => webpr}/src/index.css (100%) rename Front-End/{ => webpr}/src/lib/utils.ts (100%) rename Front-End/{ => webpr}/src/main.tsx (100%) rename Front-End/{ => webpr}/src/pages/Billing.tsx (100%) rename Front-End/{ => webpr}/src/pages/CheckoutError.tsx (100%) rename Front-End/{ => webpr}/src/pages/CheckoutSuccess.tsx (100%) rename Front-End/{ => webpr}/src/pages/Controls.tsx (100%) rename Front-End/{ => webpr}/src/pages/Dashboard.tsx (100%) rename Front-End/{ => webpr}/src/pages/Invoices.tsx (100%) rename Front-End/{ => webpr}/src/pages/Landingpage.tsx (100%) rename Front-End/{ => webpr}/src/pages/Login.tsx (100%) rename Front-End/{ => webpr}/src/pages/Logs.tsx (100%) rename Front-End/{ => webpr}/src/pages/MyAccount.tsx (100%) rename Front-End/{ => webpr}/src/pages/NotFound.tsx (100%) rename Front-End/{ => webpr}/src/pages/PullRequests.tsx (100%) rename Front-End/{ => webpr}/src/pages/Settings.tsx (100%) rename Front-End/{ => webpr}/src/pages/SignupCheckout.tsx (100%) rename Front-End/{ => webpr}/src/pages/Workflows.tsx (100%) create mode 100644 Front-End/webpr/src/vite-env.d.ts rename Front-End/{ => webpr}/tailwind.config.ts (100%) rename Front-End/{ => webpr}/tsconfig.app.json (100%) rename Front-End/{ => webpr}/tsconfig.json (100%) rename Front-End/{ => webpr}/tsconfig.node.json (100%) rename Front-End/{ => webpr}/vite.config.ts (100%) delete mode 100644 LICENSE diff --git a/.gitignore b/.gitignore index f24016eb7..1fc2621b9 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ __pycache__/ *.pyc *.cpython-39.pyc **/__pycache__/ - +Back-End/Keys/keys.env # Logs logs diff --git a/Back-End/Agents/ContextLayer/ai.py b/Back-End/Agents/ContextLayer/ai.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/Back-End/Agents/GitContextLayer/ai.py b/Back-End/Agents/GitContextLayer/ai.py new file mode 100644 index 000000000..dcb0861b6 --- /dev/null +++ b/Back-End/Agents/GitContextLayer/ai.py @@ -0,0 +1,170 @@ +# Back-End\Agents\GitContextLayer\ai.py +from agents import Agent, Runner, ModelSettings +import logging +import os +from pydantic import BaseModel +from typing import List + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger("GitContextLayer_logger") + +class CommitMessageOutput(BaseModel): + subject: str + body: str + +class CommitChunkSummary(BaseModel): + summary_points: str + +async def GenerateCommitMessageAgent( + OPENAI_API_KEY, + user_id, + diff, + files, + model = "gpt-5-nano", + MAX_INPUT_SIZE: int = 40000, + ): + os.environ['OPENAI_API_KEY'] = OPENAI_API_KEY + diff_size = len(diff.encode("utf-8")) + logger.info(f"Commit Agent - Diff size (bytes): {diff_size}") + + total_usage = { + "input": 0, "cached": 0, "reasoning": 0, "output": 0, "total": 0 + } + + if diff_size > MAX_INPUT_SIZE: + logger.info(f"Diff exceeds {MAX_INPUT_SIZE} bytes. Initiating chunking process.") + prompt_chunk_analyzer = f""" + You are part of a multi-step analysis pipeline. Your task is to analyze a CHUNK of a larger diff. + Do NOT write a final commit message. Instead, extract and list the most significant changes from this chunk as concise bullet points. + Focus only on the technical changes presented in the text provided. + Your output MUST be a valid JSON object conforming to the `CommitChunkSummary` schema. + """ + + prompt_final_summarizer = f""" + You are a Git expert responsible for synthesizing multiple analysis summaries into a final, high-quality commit message. + You will receive a list of bullet points summarizing changes from different parts of a large diff. + Your task is to consolidate these points, remove redundancy, and generate a single, cohesive commit message. + + Your output MUST be a valid JSON object conforming to the `CommitMessageOutput` schema, with: + - 'subject': A concise, imperative line (max 72 chars). + - 'body': A detailed explanation of the 'what' and 'why', based on the provided summaries. + """ + chunks = split_chunks(diff, MAX_INPUT_SIZE) + logger.info(f"Diff split into {len(chunks)} chunks.") + summaries = [] + for i, chunk in enumerate(chunks, 1): + chunk_content = f""" + Analyzing chunk {i}/{len(chunks)} of a large diff. + Modified files for context: {", ".join(files[:10])}{"..." if len(files) > 10 else ""} + + Diff Chunk: + ```diff + {chunk} + ``` + """ + agent_chunk = Agent( + name=f"CommitChunkAnalyzer_{i}", + instructions=prompt_chunk_analyzer, + model=model, + output_type=CommitChunkSummary, + model_settings=ModelSettings(include_usage=True) + ) + result = await Runner.run(agent_chunk, chunk_content, max_turns=1) + summaries.append(result.final_output.summary_points) + + usage = result.context_wrapper.usage + total_usage["input"] += usage.input_tokens + total_usage["cached"] += usage.input_tokens_details.cached_tokens + total_usage["reasoning"] += usage.output_tokens_details.reasoning_tokens + total_usage["output"] += usage.output_tokens + total_usage["total"] += usage.total_tokens + + combined_summary = f""" + Context: + - Modified files: {", ".join(files)} + + Aggregated summaries from all diff chunks: + --- + {chr(10).join(summaries)} + --- + Please synthesize this information into the final commit message. + """ + + agent_summarizer = Agent( + name="CommitSummarizer", + instructions=prompt_final_summarizer, + model=model, + output_type=CommitMessageOutput, + model_settings=ModelSettings(include_usage=True) + ) + result = await Runner.run(agent_summarizer, combined_summary, max_turns=1) + commit_message = result.final_output + + usage = result.context_wrapper.usage + total_usage["input"] += usage.input_tokens + total_usage["cached"] += usage.input_tokens_details.cached_tokens + total_usage["reasoning"] += usage.output_tokens_details.reasoning_tokens + total_usage["output"] += usage.output_tokens + total_usage["total"] += usage.total_tokens + + else: + + logger.info("Diff size is within limits. Using direct processing.") + + prompt_system_direct = f""" + You are a Git expert tasked with writing clear, informative commit messages. + Analyze the provided code changes (diff) and the list of modified files. + Your output MUST be a valid JSON object conforming to the `CommitMessageOutput` schema, with: + - 'subject': A concise, imperative line (max 72 chars). + - 'body': A detailed explanation of the 'what' and 'why' of the change. + """ + + user_content = f""" + Context for analysis: + Modified files ({len(files)}): + {chr(10).join(f"- {f}" for f in files)} + + Diff: + ```diff + {diff} + ``` + """ + + agent = Agent( + name="CommitMessageGeneratorDirect", + instructions=prompt_system_direct, + model=model, + output_type=CommitMessageOutput, + model_settings=ModelSettings(include_usage=True) + ) + result = await Runner.run(agent, user_content, max_turns=1) + commit_message = result.final_output + + usage = result.context_wrapper.usage + total_usage["input"] = usage.input_tokens + total_usage["cached"] = usage.input_tokens_details.cached_tokens + total_usage["reasoning"] = usage.output_tokens_details.reasoning_tokens + total_usage["output"] = usage.output_tokens + total_usage["total"] = usage.total_tokens + + logger.info(f"Commit Agent Final Usage: {total_usage['total']} total tokens.") + return commit_message, total_usage["input"], total_usage["cached"], total_usage["output"], total_usage["reasoning"], total_usage["total"] + + +def split_chunks(content: str, max_size: int) -> List[str]: + lines = content.splitlines(keepends=True) + chunks, current_chunk_lines = [], [] + current_size = 0 + for line in lines: + line_size = len(line.encode("utf-8")) + if current_size + line_size > max_size and current_chunk_lines: + chunks.append("".join(current_chunk_lines)) + current_chunk_lines = [line] + current_size = line_size + else: + current_chunk_lines.append(line) + current_size += line_size + if current_chunk_lines: + chunks.append("".join(current_chunk_lines)) + + return chunks \ No newline at end of file diff --git a/Back-End/Dockerfile b/Back-End/Dockerfile index 05445ba87..30019c9e1 100644 --- a/Back-End/Dockerfile +++ b/Back-End/Dockerfile @@ -1,6 +1,5 @@ FROM python:3.12-slim-bullseye -# Instalar dependências do sistema RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ curl \ @@ -14,7 +13,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libssl-dev \ && rm -rf /var/lib/apt/lists/* -# Instalar Docker CLI RUN apt-get update && apt-get install -y \ ca-certificates \ curl \ @@ -34,12 +32,9 @@ RUN apt-get update && \ curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \ apt-get install -y nodejs - -# Instalar dependências do sistema RUN apt-get update && apt-get install -y \ git -# Instala o GitHub CLI RUN apt update && apt install -y curl git && \ curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \ dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \ @@ -48,16 +43,11 @@ RUN apt update && apt install -y curl git && \ tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \ apt update && apt install -y gh -# Definir diretório de trabalho WORKDIR /app -# Copiar e instalar dependências Python COPY requirements.txt /app/ RUN pip install --no-cache-dir --upgrade pip RUN pip install --no-cache-dir -r requirements.txt -# No host ou Dockerfile do ambiente de CI RUN apt-get update && apt-get install -y docker-compose-plugin -# ou instalar a versão “standalone”: RUN apt-get install -y docker-compose -# Copiar os arquivos do projeto COPY . /app diff --git a/Back-End/Models/postgreSQL.py b/Back-End/Models/postgreSQL.py index 1f0f33ba9..d333b465d 100644 --- a/Back-End/Models/postgreSQL.py +++ b/Back-End/Models/postgreSQL.py @@ -88,9 +88,11 @@ class SystemSettings(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) + installation_id = db.Column(db.BigInteger, nullable=True) github_token = db.Column(db.Text, nullable=True) github_secret = db.Column(db.Text, nullable=True) repository_name = db.Column(db.String(255), nullable=True) + openai_api_key = db.Column(db.Text, nullable=True) webhook_url = db.Column(db.String(500), nullable=True) auto_process_prs = db.Column(db.Boolean, default=True) diff --git a/Back-End/Modules/Geters/logs.py b/Back-End/Modules/Geters/logs.py index f2625e4e8..0162464be 100644 --- a/Back-End/Modules/Geters/logs.py +++ b/Back-End/Modules/Geters/logs.py @@ -57,8 +57,6 @@ def get_audit_trail(entity=None, limit=50): .limit(limit) ) - - def get_system_health_recent(limit=50): """ Recupera registros recentes de health_check. diff --git a/Back-End/Modules/Geters/plans_data.py b/Back-End/Modules/Geters/plans_data.py new file mode 100644 index 000000000..5559e2d8b --- /dev/null +++ b/Back-End/Modules/Geters/plans_data.py @@ -0,0 +1,38 @@ + +def get_plans_data(): + return { + "Free": { + 'price': 0, + 'limit_monthly_tokens': 300000, + 'features': [ + 'PR basic automation', + '5 - 10 PRs/mo', + 'Logs basic' + ], + 'payment_link': '' + }, + "Premium": { + 'price': 15, + 'limit_monthly_tokens': 3000000, + 'features': [ + 'PR Premium automation', + '20 - 40 PRs/mo', + 'Logs advanced', + 'API access' + ], + 'payment_link': 'teste 123' + }, + "Pro": { + 'price': 29, + 'limit_monthly_tokens': 10000000, + 'features': [ + 'Everything from Premium', + '60 - 90 PRs/mo', + 'Git Context Layer', + 'Auto-Commit Intelligence', + 'Smart Threshold Detection', + 'Context-Aware Messages' + ], + 'payment_link': 'teste 123' + } + } \ No newline at end of file diff --git a/Back-End/Modules/Geters/pr_diff.py b/Back-End/Modules/Geters/pr_diff.py index a7433b934..bdc71c691 100644 --- a/Back-End/Modules/Geters/pr_diff.py +++ b/Back-End/Modules/Geters/pr_diff.py @@ -1,5 +1,4 @@ # Back-End\Modules\Geters\pr_diff.py - import requests from datetime import datetime, timedelta @@ -11,7 +10,6 @@ def fetch_pr_diff_via_api(pr_api_url: str, token: str) -> str: } response = requests.get(pr_api_url, headers=headers, timeout=120) response.raise_for_status() - files = response.json() diff_parts = [] for f in files: diff --git a/Back-End/Modules/Resolvers/github_app_auth.py b/Back-End/Modules/Resolvers/github_app_auth.py new file mode 100644 index 000000000..fbed600e7 --- /dev/null +++ b/Back-End/Modules/Resolvers/github_app_auth.py @@ -0,0 +1,113 @@ +import jwt +import time +import requests +import os +import logging +from cryptography.hazmat.primitives import serialization +from flask import current_app + +logger = logging.getLogger(__name__) + +INSTALLATION_TOKEN_CACHE = {} + + +def get_installation_token(app_id: str, private_key_content: str, installation_id: str) -> str: + """ + Gera um JWT e o usa para obter um Token de Acesso à Instalação do GitHub. + + Args: + app_id: O ID do GitHub App. + private_key_content: O conteúdo da chave privada do App (formato PEM). + installation_id: O ID da instalação para o qual gerar o token. + + Returns: + O Installation Access Token de curta duração, ou None em caso de falha. + """ + try: + # 1. Carregar a Chave Privada do App + # A chave privada deve estar no formato bytes + private_key = serialization.load_pem_private_key( + private_key_content.encode('utf-8'), + password=None + ) + + # 2. Gerar o JSON Web Token (JWT) + now = int(time.time()) + + payload = { + # Emitido em (Issued at time) - 60 segundos de desvio + 'iat': now - 60, + # Expiração (Expiration time) - 5 minutos (máx. 10 minutos) + 'exp': now + 300, + # ID do App (Issuer) + 'iss': app_id + } + + # Gerar o JWT assinado com a chave privada + jwt_token = jwt.encode( + payload, + private_key, + algorithm='RS256' + ) + + # 3. Trocar o JWT por um Token de Acesso à Instalação + url = f"https://api.github.com/app/installations/{installation_id}/access_tokens" + + headers = { + "Authorization": f"Bearer {jwt_token}", + "Accept": "application/vnd.github.v3+json" + } + + response = requests.post(url, headers=headers) + response.raise_for_status() # Lança exceção para status 4xx/5xx + + data = response.json() + access_token = data.get("token") + + return access_token + + except requests.exceptions.HTTPError as e: + logger.error(f"Erro HTTP ao obter o token de instalação: {e} - Resposta: {e.response.text}") + return None + except Exception as e: + logger.error(f"Erro ao gerar ou obter o token de instalação: {e}") + return None + +# Função auxiliar para garantir que a chave privada seja carregada com segurança +def load_private_key(private_key_path: str) -> str: + """Carrega o conteúdo da chave privada do App a partir do caminho do arquivo.""" + if not private_key_path or not os.path.exists(private_key_path): + logger.error(f"Caminho da chave privada inválido ou arquivo não encontrado: {private_key_path}") + return None + try: + with open(private_key_path, "r") as f: + # Retorna o conteúdo como uma string, para ser passado para get_installation_token + return f.read() + except Exception as e: + logger.error(f"Erro ao ler o arquivo da chave privada: {e}") + return None + + +def get_cached_installation_token(app_id: str, private_key_content: str, installation_id: str) -> str: + """ + Obtém um token de acesso de instalação usando cache para evitar a regeneração desnecessária. + O token do GitHub App dura 1 hora. O cache pode ser configurado para 50 minutos (3000 segundos) para segurança. + """ + cache_key = str(installation_id) + cached_data = INSTALLATION_TOKEN_CACHE.get(cache_key) + + # Verifica o cache + if cached_data and cached_data['expires_at'] > time.time(): + return cached_data['token'] + + # Gera um novo token + token = get_installation_token(app_id, private_key_content, installation_id) + + if token: + # Define a expiração do cache para 50 minutos (3000 segundos), pois o token real expira em 3600s + INSTALLATION_TOKEN_CACHE[cache_key] = { + 'token': token, + 'expires_at': time.time() + 3000 + } + return token + return None \ No newline at end of file diff --git a/Back-End/Modules/Resolvers/user_identifier.py b/Back-End/Modules/Resolvers/user_identifier.py index 6d19d90fa..db25a4fa6 100644 --- a/Back-End/Modules/Resolvers/user_identifier.py +++ b/Back-End/Modules/Resolvers/user_identifier.py @@ -4,7 +4,6 @@ from functools import wraps from flask import g, Flask, Response, request, jsonify import logging - from Modules.Savers.log_action import log_action from Modules.Geters.user_by_access_token import get_user_by_access_token from Models.mongoDB import ( @@ -58,18 +57,15 @@ def resolve_user_identifier(identifier): if not identifier: return None - # Se já for int try: uid = int(identifier) return User.query.get(uid) except (ValueError, TypeError): pass - # se parecer email if isinstance(identifier, str) and "@" in identifier: return User.query.filter_by(email=identifier).first() - # fallback: tenta buscar por email ignorando espaços return User.query.filter_by(email=str(identifier).strip()).first() def auth_user(logs_collection, app, email='', password=''): diff --git a/Back-End/Modules/Resolvers/verify_signature.py b/Back-End/Modules/Resolvers/verify_signature.py new file mode 100644 index 000000000..23933be4f --- /dev/null +++ b/Back-End/Modules/Resolvers/verify_signature.py @@ -0,0 +1,23 @@ +import hashlib +import hmac +def verify_signature(payload_body, signature_header, GITHUB_WEBHOOK_SECRET): + """ + Verifica X-Hub-Signature-256 (ex: 'sha256=abcdef...'). + Retorna True se válido, False caso contrário. + """ + if not signature_header: + return False + try: + algo, signature = signature_header.split("=", 1) + except ValueError: + return False + + try: + digestmod = getattr(hashlib, algo) + except AttributeError: + return False + + mac = hmac.new(GITHUB_WEBHOOK_SECRET.encode(), msg=payload_body, digestmod=digestmod) + expected = mac.hexdigest() + return hmac.compare_digest(signature, expected) + diff --git a/Back-End/Modules/Savers/log_action.py b/Back-End/Modules/Savers/log_action.py index 26651566a..37f2e26a2 100644 --- a/Back-End/Modules/Savers/log_action.py +++ b/Back-End/Modules/Savers/log_action.py @@ -21,47 +21,39 @@ def log_action(logs_collection, action, details=None, user=None, level='info'): if details is None: details = {} - # garante que details seja dict if not isinstance(details, dict): try: details = {"message": str(details)} except Exception: details = {"message": "no details"} - # assegura que exista mensagem curta if "message" not in details: - # tenta derivar mensagem de outros campos ou do action details["message"] = details.get("msg") or str(action) - # normalização de usuário user_id_val = None user_val = None if user is not None: - # se for objeto com id try: user_id_val = int(getattr(user, "id", user)) except Exception: user_val = str(user) - # if user is numeric passed as numeric_user_id if isinstance(user, int): user_id_val = user user_val = user log_entry = { - "timestamp": datetime.utcnow(), # naive UTC (vamos tratar com parser depois) + "timestamp": datetime.utcnow(), "action": action, "details": details, "level": (level or "info").upper() } - # inclui ambos campos para compatibilidade if user_id_val is not None: log_entry["user_id"] = user_id_val log_entry["user"] = user_id_val elif user_val is not None: log_entry["user"] = user_val - # normalize prNumber/pr_number if exists in details if "prNumber" in details and "pr_number" not in details: details["pr_number"] = details["prNumber"] diff --git a/Back-End/gen-prai.py b/Back-End/TestDiscovery/gen-prai.py similarity index 100% rename from Back-End/gen-prai.py rename to Back-End/TestDiscovery/gen-prai.py diff --git a/Back-End/api.py b/Back-End/api.py index ce2e5b36d..bdfb16daa 100644 --- a/Back-End/api.py +++ b/Back-End/api.py @@ -5,11 +5,14 @@ import json import logging from dotenv import load_dotenv + import stripe from decimal import Decimal from bson.json_util import dumps from datetime import datetime, timedelta, timezone -from flask import g, Flask, Response, request, jsonify, send_file +import hmac +import hashlib +from flask import g, Flask, Response, request, jsonify, send_file, abort, redirect from flask_cors import CORS from asgiref.wsgi import WsgiToAsgi from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity @@ -37,6 +40,8 @@ from Modules.Savers.log_action import log_action from Modules.Resolvers.send_email import SendEmail from Modules.Geters.user_by_email import get_user_by_email +from Modules.Geters.plans_data import get_plans_data +from Modules.Resolvers.verify_signature import verify_signature diretorio_script = os.path.dirname(os.path.abspath(__file__)) @@ -70,13 +75,19 @@ success_url = os.getenv("success_url") cancel_url = os.getenv("cancel_url") +APP_ID = os.getenv("GITHUB_APP_ID") +PRIVATE_KEY_PATH = os.getenv("GITHUB_PRIVATE_KEY_PATH") +GITHUB_WEBHOOK_SECRET = os.getenv("GITHUB_WEBHOOK_SECRET") +# PRIVATE_KEY_CONTENT = load_private_key(PRIVATE_KEY_PATH) +GITHUB_CLIENT_ID = os.getenv("GITHUB_CLIENT_ID") +GITHUB_CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET") + app = Flask(__name__) asgi_app = WsgiToAsgi(app) app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'your-secret-key-here') app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET_KEY', 'jwt-secret-string') app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=24) -# Configuração PostgreSQL app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv( 'DATABASE_URL', 'postgresql://postgres:postgres@meu_postgres2:5412/meubanco' @@ -92,10 +103,12 @@ if os.getenv("FLASK_ENV") == "development": - CORS(app, origins=os.getenv("FRONTEND_ORIGINS", "*").split(",")) + CORS(app, origins=os.getenv("FRONTEND_ORIGINS", "*").split(","), supports_credentials=True) db.init_app(app) + + @app.route('/') def index(): return jsonify({ @@ -104,44 +117,6 @@ def index(): "database": "PostgreSQL + MongoDB", "status": "running" }) - -def get_plans_data(): - return { - "Free": { - 'price': 0, - 'limit_monthly_tokens': 300000, - 'features': [ - 'PR basic automation', - '5 - 10 PRs/mo', - 'Logs basic' - ], - 'payment_link': '' - }, - "Premium": { - 'price': 15, - 'limit_monthly_tokens': 3000000, - 'features': [ - 'PR Premium automation', - '20 - 40 PRs/mo', - 'Logs advanced', - 'API access' - ], - 'payment_link': '' - }, - "Pro": { - 'price': 29, - 'limit_monthly_tokens': 10000000, - 'features': [ - 'Everything from Premium', - '60 - 90 PRs/mo', - 'Git Context Layer', - 'Auto-Commit Intelligence', - 'Smart Threshold Detection', - 'Context-Aware Messages' - ], - 'payment_link': '' - } - } @app.route('/api/public/plans-features', methods=['GET']) @limiter.limit("5 per minute") @@ -230,7 +205,6 @@ def login(): return jsonify({"error": "Erro no login"}), 500 @app.route('/api/health', methods=['GET']) -#@require_user_token(optional=False) def health_check(): """ Verifica a saúde do sistema. @@ -339,7 +313,6 @@ def health_check(): return jsonify({"error": "Erro ao executar health_check", "detail": str(e)}), 500 @app.route('/api/rate-limits', methods=['GET']) -#@require_user_token(optional=False) def get_rate_limits(): """Obter informações de rate limits""" @@ -400,13 +373,13 @@ def get_rate_limits(): return jsonify(rate_limits) @app.route('/api/settings', methods=['GET']) -#@require_user_token(optional=False) def get_settings(): """Recuperar configurações do sistema (com valores mascarados)""" - + email = request.args.get("email") + password = request.args.get("password") - user, _, status = auth_user( logs_collection, app) + user, _, status = auth_user( logs_collection, app, email, password) if status != "success" or not user: return jsonify({"error": "Usuário não autenticado ou inválido"}), 401 @@ -448,12 +421,14 @@ def get_settings(): return jsonify({'error': 'Failed to fetch settings'}), 500 @app.route('/api/settings', methods=['PUT']) -#@require_user_token(optional=False) def update_settings(): """Atualizar configurações do sistema""" data = request.get_json() + email = data.get("email") + password = data.get("password") + - user, _, status = auth_user( logs_collection, app) + user, _, status = auth_user( logs_collection, app, email, password) if status != "success" or not user: return jsonify({"error": "Usuário não autenticado ou inválido"}), 401 @@ -499,7 +474,6 @@ def update_settings(): return jsonify({'error': 'Failed to update settings'}), 500 @app.route('/api/test-connection/', methods=['GET']) -#@require_user_token(optional=False) def test_connection(service): """Testar conexão com serviços externos""" @@ -625,7 +599,6 @@ def test_connection(service): }), 500 @app.route("/api/logs", methods=["GET"]) -#@require_user_token(optional=False) def get_logs(): @@ -675,7 +648,6 @@ def get_logs(): return jsonify(adapted_logs) @app.route("/api/logs/export", methods=["GET"]) -#@require_user_token(optional=False) def export_logs(): """ Exporta logs filtrados em formato .txt @@ -736,7 +708,6 @@ def export_logs(): ) @app.route('/api/pull-requests', methods=['GET']) -#@require_user_token(optional=False) def get_pull_requests(): """Listar PRs processados com filtros e busca""" @@ -810,7 +781,6 @@ def get_pull_requests(): return jsonify({'error': 'Failed to fetch pull requests'}), 500 @app.route('/api/pull-requests/', methods=['GET']) -#@require_user_token(optional=False) def get_pull_request_details(pr_id): """Obter detalhes completos de um PR específico""" @@ -919,7 +889,7 @@ def parse_to_aware(dt): return None @app.route('/api/dashboard-data', methods=['GET']) -# #@require_user_token(optional=False) +# def get_dashboard_data(): """Obter dados agregados para o dashboard (correção focada: apenas aqui).""" @@ -1061,7 +1031,7 @@ def get_dashboard_data(): @app.route('/api/workflows', methods=['GET']) -#@require_user_token(optional=False) + def list_workflows(): """ Lista workflows (arquivos .yml/.yaml) a partir de WORKFLOWS_PATH (env) ou ./workflows. @@ -1119,7 +1089,7 @@ def list_workflows(): return jsonify({'error': 'Failed to list workflows', 'detail': str(e)}), 500 @app.route('/api/myaccount', methods=['GET']) -#@require_user_token(optional=False) + def my_account(): """ Retorna informações da conta do usuário autenticado. @@ -1152,7 +1122,7 @@ def my_account(): @app.route('/api/invoices', methods=['GET']) -#@require_user_token(optional=False) + def list_invoices(): """ Listar faturas paginadas. @@ -1198,7 +1168,7 @@ def list_invoices(): @app.route('/api/invoices/', methods=['GET']) -#@require_user_token(optional=False) + def get_invoice_detail(invoice_id): """ Detalhe da fatura (inclui linhas / itens). @@ -1227,7 +1197,7 @@ def get_invoice_detail(invoice_id): @app.route('/api/invoices//download', methods=['GET']) -#@require_user_token(optional=False) + def download_invoice(invoice_id): """ Download do PDF da fatura. @@ -1279,7 +1249,7 @@ def download_invoice(invoice_id): @app.route('/api/reprocess-pr/', methods=['POST']) -#@require_user_token(optional=False) + def reprocess_pr(pr_number): """Reprocessar um Pull Request específico""" data = request.get_json() @@ -1315,7 +1285,7 @@ def reprocess_pr(pr_number): }), 202 @app.route('/api/prai/gen', methods=['POST']) -#@require_user_token(optional=False) + def prai(): data = request.get_json() repository = data.get("repository") @@ -1406,8 +1376,6 @@ def proxy_checkout(): logger.info(f"Erro no servidor {e}") return jsonify({"error": f"Erro no servidor {e}"}), 500 -# ------------------------------------------------------------------- -# Endpoint Webhook Stripe @app.route("/webhook", methods=["POST"]) def stripe_webhook(): """ @@ -1551,183 +1519,224 @@ def stripe_webhook(): +@app.route('/api/github/callback', methods=['GET']) +def github_app_callback(): + """ + Callback após instalação/autorização do GitHub App. + - Se receber installation_id e houver user_token (query param ou header), associa a instalação ao usuário. + - Se receber 'code' (fluxo OAuth), troca por access_token e tenta associar ao usuário pelo e-mail retornado. + """ + try: + installation_id = request.args.get('installation_id') + setup_action = request.args.get('setup_action') + code = request.args.get('code') + user_token = request.args.get('X-API-TOKEN') + if installation_id: + user = None + if user_token: + user = get_user_by_access_token(user_token) + if user: + settings = SystemSettings.query.filter_by(user_id=user.id).first() + if not settings: + settings = SystemSettings(user_id=user.id) + db.session.add(settings) + settings.installation_id = int(installation_id) + settings.updated_at = datetime.utcnow() + db.session.commit() + + log_action(logs_collection, 'github_installation_linked', { + 'message': f'installation {installation_id} linked to user {user.id}', + 'installation_id': installation_id, + 'setup_action': setup_action + }, user=user.id) + return jsonify({ + "status": "success", + "message": f"Instalação do GitHub (installation_id={installation_id}) vinculada ao usuário.", + "installation_id": installation_id + }), 200 + else: + log_action(logs_collection, 'github_installation_unbound', { + 'message': f"Installation {installation_id} received but no user token provided.", + 'installation_id': installation_id, + 'setup_action': setup_action + }, level='warning') + return jsonify({ + "status": "success", + "message": f"GitHub App instalado (installation_id={installation_id}). Vincule a instalação no painel do usuário para ativar integrações.", + "installation_id": installation_id + }), 200 + + if code: + if not GITHUB_CLIENT_ID or not GITHUB_CLIENT_SECRET: + return jsonify({"status": "error", "message": "GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET não configurados"}), 500 + token_resp = requests.post( + "https://github.com/login/oauth/access_token", + headers={"Accept": "application/json"}, + json={"client_id": GITHUB_CLIENT_ID, "client_secret": GITHUB_CLIENT_SECRET, "code": code}, + timeout=10 + ) + if token_resp.status_code != 200: + logger.error("Erro ao trocar code por token: %s", token_resp.text) + return jsonify({"status": "error", "message": "Erro ao obter access_token do GitHub"}), 500 + + token_data = token_resp.json() + access_token = token_data.get("access_token") + if not access_token: + return jsonify({"status": "error", "message": "access_token não recebido do GitHub"}), 500 + + user_resp = requests.get("https://api.github.com/user", headers={"Authorization": f"Bearer {access_token}", "Accept": "application/vnd.github+json"}, timeout=10) + if user_resp.status_code != 200: + logger.error("Erro ao buscar usuário GitHub: %s", user_resp.text) + return jsonify({"status": "error", "message": "Não foi possível obter dados do usuário no GitHub"}), 500 + + gh_user = user_resp.json() + gh_email = gh_user.get("email") + + if not gh_email: + emails_resp = requests.get("https://api.github.com/user/emails", headers={"Authorization": f"Bearer {access_token}", "Accept": "application/vnd.github+json"}, timeout=10) + if emails_resp.status_code == 200: + emails = emails_resp.json() + primary = next((e for e in emails if e.get("primary") and e.get("verified")), None) + if primary: + gh_email = primary.get("email") + + if gh_email: + local_user = get_user_by_email(gh_email) + if local_user: + settings = SystemSettings.query.filter_by(user_id=local_user.id).first() + if not settings: + settings = SystemSettings(user_id=local_user.id) + db.session.add(settings) + settings.github_token = access_token + settings.updated_at = datetime.utcnow() + db.session.commit() + log_action(logs_collection, 'github_oauth_linked', { + 'message': f'GitHub OAuth linked for user {local_user.id}', + 'github_login': gh_user.get("login"), + 'email': gh_email + }, user=local_user.id) + return jsonify({"status": "success", "message": "Conta GitHub vinculada ao usuário local."}), 200 + + return jsonify({ + "status": "success", + "message": "Token GitHub recebido. Vincule manualmente no painel do usuário se necessário.", + "github_access_token": access_token + }), 200 + + return jsonify({"status": "error", "message": "Callback inválido. Forneça installation_id ou code."}), 400 + except Exception as e: + logger.exception("Erro em github_app_callback: %s", e) + log_action(logs_collection, 'github_callback_error', {'error': str(e)}, level='error') + return jsonify({"status": "error", "message": "Erro interno no callback do GitHub", "detail": str(e)}), 500 +@app.route("/webhook/github", methods=["POST"]) +def github_webhook(): + try: + signature_header = request.headers.get("X-Hub-Signature-256") or "" + if not signature_header or not verify_signature(request.data, signature_header, GITHUB_WEBHOOK_SECRET): + logger.warning("Assinatura inválida do webhook do GitHub") + abort(400, "Assinatura inválida") + event = request.headers.get("X-GitHub-Event", "ping") + payload = request.get_json(force=True, silent=True) or {} + if event == "ping": + return jsonify({"msg": "pong"}), 200 + user_token = request.headers.get("X-API-TOKEN") or request.args.get("X-API-TOKEN") + user = None + if user_token: + try: + user = get_user_by_access_token(user_token) + except Exception: + user = None + + if event == "installation": + action = payload.get("action") + installation = payload.get("installation", {}) + installation_id = installation.get("id") + account = installation.get("account", {}).get("login") + + if not installation_id: + logger.warning("Evento de instalação sem installation.id") + return "", 204 + + if action == "created": + if user: + settings = SystemSettings.query.filter_by(user_id=user.id).first() + if not settings: + settings = SystemSettings(user_id=user.id) + db.session.add(settings) + settings.installation_id = int(installation_id) + settings.updated_at = datetime.utcnow() + db.session.commit() + + log_action(logs_collection, 'github_installation_created', { + 'message': f'installation {installation_id} associated to user {user.id}', + 'installation_id': installation_id, + 'account': account + }, user=user.id) + logger.info("Installation %s associated to user %s", installation_id, user.id) + else: + log_action(logs_collection, 'github_installation_created_unbound', { + 'message': f'installation {installation_id} received with no associated user', + 'installation_id': installation_id, + 'account': account + }, level='warning') + logger.info("Installation %s received but not bound to any user", installation_id) + + elif action == "deleted": + settings = SystemSettings.query.filter_by(installation_id=installation_id).first() + if settings: + settings.installation_id = None + settings.updated_at = datetime.utcnow() + db.session.commit() + log_action(logs_collection, 'github_installation_deleted', { + 'message': f'installation {installation_id} removed', + 'installation_id': installation_id, + 'account': account + }) + logger.info("Installation %s removed from settings", installation_id) + else: + logger.info("Received installation.deleted for %s but no settings found", installation_id) + + return "", 204 + + if event == "pull_request": + action = payload.get("action") + if action in ("opened", "synchronize", "reopened"): + try: + threading.Thread(target=process_pull_request, args=(payload,)).start() + log_action(logs_collection, 'pull_request_received', { + 'message': 'Pull request event queued for processing', + 'action': action, + 'pr': (payload.get("pull_request") or {}).get("number") + }, user=(user.id if user else None)) + except Exception as e: + logger.exception("Erro ao enfileirar processamento de PR: %s", e) + log_action(logs_collection, 'pull_request_processing_error', {'error': str(e)}, level='error') + return "", 204 + + log_action(logs_collection, 'github_webhook_received', { + 'event': event, + 'payload_summary': {'keys': list(payload.keys())[:10]} + }, user=(user.id if user else None)) + + return "", 204 - - -# Endpoints nao desenvolvidos e Pendentes - -def deploy_containers_internal(triggered_by=None, source='manual'): - """Lógica interna para deploy""" - deployment_record = None - try: - # Criar registro de deployment - deployment_record = Deployment( - triggered_by=triggered_by, - source=source, - status='in_progress' - ) - db.session.add(deployment_record) - db.session.commit() - - log_action('deploy_started', { - 'deployment_id': deployment_record.id, - 'triggered_by': triggered_by, - 'source': source - }, user=triggered_by) - - # Aqui você colocaria sua lógica de deploy - # Por exemplo: build de containers, deploy para Kubernetes, etc. - - # Simular deploy - import time - time.sleep(5) - - # Atualizar status - deployment_record.status = 'completed' - deployment_record.completed_at = datetime.utcnow() - db.session.commit() - - log_action('deploy_completed', { - 'deployment_id': deployment_record.id - }, user=triggered_by) - - except Exception as e: - if deployment_record: - deployment_record.status = 'failed' - deployment_record.completed_at = datetime.utcnow() - deployment_record.error_message = str(e) - db.session.commit() - - log_action('deploy_failed', { - 'deployment_id': deployment_record.id if deployment_record else None, - 'error': str(e) - }, user=triggered_by, level='error') - -@app.route('/api/force-deploy', methods=['POST']) -def force_deploy(): - """Disparar deploy forçado""" - current_user = get_jwt_identity() - - # Verificar se usuário é admin (opcional) - # user = User.query.filter_by(username=current_user).first() - # if not user or not user.is_admin: - # return jsonify({'error': 'Admin privileges required'}), 403 - - data = request.get_json() or {} - source = data.get('source', 'manual_trigger') - - # Iniciar deploy em thread separada - thread = threading.Thread( - target=deploy_containers_internal, - args=(current_user, source) - ) - thread.daemon = True - thread.start() - - return jsonify({ - 'message': 'Deploy initiated', - 'triggered_by': current_user, - 'source': source - }), 202 - -def process_webhook_internal(payload, triggered_by=None): - """Lógica interna para processar webhook""" - try: - log_action('custom_webhook_received', { - 'payload_keys': list(payload.keys()) if isinstance(payload, dict) else 'non-dict', - 'triggered_by': triggered_by - }, user=triggered_by) - - # Aqui você colocaria sua lógica de processamento de webhook - # Similar à sua função webhookgenpr ou webhook existente - - # Simular processamento - import time - time.sleep(1) - - log_action('custom_webhook_processed', { - 'triggered_by': triggered_by - }, user=triggered_by) - - except Exception as e: - log_action('custom_webhook_error', { - 'error': str(e), - 'triggered_by': triggered_by - }, user=triggered_by, level='error') - raise - -@app.route('/api/send-custom-webhook', methods=['POST']) -def send_custom_webhook(): - """Enviar webhook customizado""" - current_user = get_jwt_identity() - - try: - payload = request.get_json() - if not payload: - return jsonify({'error': 'JSON payload required'}), 400 - - # Processar webhook em thread separada - thread = threading.Thread( - target=process_webhook_internal, - args=(payload, current_user) - ) - thread.daemon = True - thread.start() - - return jsonify({ - 'message': 'Webhook processed', - 'triggered_by': current_user - }), 200 - except Exception as e: - return jsonify({'error': str(e)}), 400 + logger.exception("Erro no webhook do GitHub: %s", e) + log_action(logs_collection, 'github_webhook_error', {'error': str(e)}, level='error') + return "", 500 -@app.route('/api/deployments', methods=['GET']) -def get_deployments(): - """Listar deployments""" - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 20, type=int) - - deployments = Deployment.query.order_by(Deployment.created_at.desc()).paginate( - page=page, per_page=per_page, error_out=False - ) - - return jsonify({ - 'deployments': [{ - 'id': dep.id, - 'status': dep.status, - 'triggered_by': dep.triggered_by, - 'source': dep.source, - 'created_at': dep.created_at.isoformat(), - 'completed_at': dep.completed_at.isoformat() if dep.completed_at else None, - 'error_message': dep.error_message - } for dep in deployments.items], - 'pagination': { - 'page': page, - 'per_page': per_page, - 'total': deployments.total, - 'pages': deployments.pages - } - }) - def initialize_database(): """Inicializar banco de dados""" with app.app_context(): db.create_all() initialize_database() - -# if __name__ == '__main__': -# debug_mode = os.getenv('FLASK_DEBUG', 'true').lower() == 'true' -# port = int(os.getenv('PORT', 5920)) - -# app.run(debug=debug_mode, host='0.0.0.0', port=port) \ No newline at end of file diff --git a/Back-End/git_context_layer.py b/Back-End/git_context_layer.py new file mode 100644 index 000000000..0900e452e --- /dev/null +++ b/Back-End/git_context_layer.py @@ -0,0 +1,343 @@ +# git_context_layer.py +""" +Git Context Layer - Automação inteligente de commits com IA +Monitora alterações locais e cria commits contextualizados automaticamente +""" + +import os +import sys +import time +import json +import asyncio +import subprocess +import threading +from pathlib import Path +from datetime import datetime +from typing import List, Dict, Set, Optional +from dataclasses import dataclass, asdict + +import anthropic +from dotenv import load_dotenv + +from Agents.GitContextLayer.ai import GenerateCommitMessageAgent + +@dataclass +class Config: + """Configurações do Git Context Layer""" + lines_threshold: int = 1 + files_threshold: int = 1 + time_threshold: int = 1 + auto_push: bool = False + require_tests: bool = False + max_file_size: int = 1_000_000 + ignored_patterns: List[str] = None + ai_model: str = "gpt-5-nano" + api_key: str = "" + load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), 'Keys', 'keys.env')) + os.chdir(os.path.join(os.path.dirname(__file__))) + + def __post_init__(self): + if self.ignored_patterns is None: + self.ignored_patterns = [ + "__pycache__", "*.pyc", "*.pyo", "*.pyd", + ".git", ".venv", "venv", "node_modules", + ".env", "*.log", ".DS_Store", "*.swp", + "build", "dist", "*.egg-info" + ] + + @classmethod + def load(cls, config_path: str = ".gitcontext.json") -> 'Config': + """Carrega configuração de arquivo""" + if os.path.exists(config_path): + with open(config_path, 'r') as f: + data = json.load(f) + return cls(**data) + return cls() + + def save(self, config_path: str = ".gitcontext.json"): + """Salva configuração em arquivo""" + with open(config_path, 'w') as f: + json.dump(asdict(self), f, indent=2) + + +class GitAnalyzer: + """Analisa alterações do Git""" + + def __init__(self, repo_path: str = "."): + self.repo_path = Path(repo_path).resolve() + + def run_git_command(self, *args) -> str: + """Executa comando git e retorna output""" + try: + result = subprocess.run( + ["git", "-C", str(self.repo_path)] + list(args), + capture_output=True, + text=True, + encoding='utf-8', + check=True + ) + return result.stdout.strip() + except subprocess.CalledProcessError as e: + print(f"❌ Erro Git: {e.stderr}") + return "" + + def get_modified_files(self) -> List[str]: + """Retorna lista de arquivos modificados""" + output = self.run_git_command("status", "--porcelain") + files = [] + for line in output.split('\n'): + if line: + status, filepath = line[:2], line[3:] + if status.strip(): + files.append(filepath) + return files + + def get_diff(self, filepath: Optional[str] = None) -> str: + """Retorna diff das alterações""" + if filepath: + return self.run_git_command("diff", "HEAD", "--", filepath) + return self.run_git_command("diff", "HEAD") + + def count_lines_changed(self) -> int: + """Conta total de linhas modificadas usando git diff --numstat.""" + output = self.run_git_command("diff", "--numstat") + + total_lines = 0 + + for line in output.split('\n'): + if line: + try: + parts = line.split('\t', 2) + if len(parts) < 3: + continue + insertions_str, deletions_str, _ = parts + if insertions_str.isdigit(): + total_lines += int(insertions_str) + if deletions_str.isdigit(): + total_lines += int(deletions_str) + + except ValueError: + continue + + return total_lines + + def git_add(self, files: List[str] = None): + """Adiciona arquivos ao staging""" + if files: + for f in files: + self.run_git_command("add", f) + else: + self.run_git_command("add", ".") + + def git_commit(self, message: str): + """Cria commit com mensagem""" + self.run_git_command("commit", "-m", message) + + def git_push(self): + """Push para repositório remoto""" + self.run_git_command("push") + + def has_tests(self) -> bool: + """Verifica se há testes no repositório""" + test_patterns = ["test_*.py", "*_test.py", "tests/"] + for pattern in test_patterns: + if list(self.repo_path.glob(f"**/{pattern}")): + return True + return False + + def run_tests(self) -> bool: + """Executa testes (pytest se disponível)""" + try: + result = subprocess.run( + ["pytest", "--tb=short"], + cwd=self.repo_path, + capture_output=True, + timeout=60 + ) + return result.returncode == 0 + except (subprocess.TimeoutExpired, FileNotFoundError): + return True # Se não tem pytest, considera ok + +class ChangeTracker: + """Rastreia alterações e acumula mudanças (apenas tempo de inatividade)""" + + def __init__(self): + # last_activity_time rastreia a última vez que *qualquer* mudança foi detectada no Git. + self.last_activity_time: float = time.time() + self.lock = threading.Lock() + + # Esta função não é mais chamada pelo Watchdog, mas é mantida por coerência + # e para uso manual, se necessário (embora não seja mais usada no fluxo). + def add_change(self, filepath: str): + """Atualiza o tempo de atividade para iniciar o contador de inatividade.""" + with self.lock: + self.last_activity_time = time.time() + + def reset(self): + """Reseta o tempo de inatividade após um commit bem-sucedido.""" + with self.lock: + self.last_activity_time = time.time() + + def should_trigger(self, config: Config, git: GitAnalyzer) -> bool: + """Verifica se deve disparar análise com base nos thresholds do Git e tempo.""" + with self.lock: + files = git.get_modified_files() + lines = git.count_lines_changed() + + current_time = time.time() + time_since_last_activity = current_time - self.last_activity_time + + # --- Lógica de Controle de Estado --- + if not files: + self.last_activity_time = current_time + return False + + if len(files) < config.files_threshold or lines < config.lines_threshold: + return False + + if time_since_last_activity < config.time_threshold: + return False + + return True + +class GitContextLayer: + """Orquestrador principal do Git Context Layer""" + + def __init__(self, config: Config, repo_path: str = "."): + self.config = config + self.git = GitAnalyzer(repo_path) + + self.tracker = ChangeTracker() + self.observer = None + self.running = False + + def start_watching(self): + """Inicia monitoramento de alterações""" + print("🚀 Git Context Layer iniciado") + print(f"📊 Thresholds: {self.config.lines_threshold} linhas, {self.config.files_threshold} arquivos") + print(f"⏱️ Tempo mínimo: {self.config.time_threshold}s") + print(f"🔒 Auto-push: {'✓' if self.config.auto_push else '✗'}") + print(f"🧪 Requer testes: {'✓' if self.config.require_tests else '✗'}") + + # VERIFICA IMEDIATAMENTE SE HÁ MUDANÇAS PENDENTES + print("\n🔍 Verificando alterações pendentes no Git...") + files = self.git.get_modified_files() + lines = self.git.count_lines_changed() + + if files: + print(f"✨ Encontradas {len(files)} arquivo(s) modificado(s) com {lines} linha(s) alterada(s)") + # Força processamento imediato se atingir thresholds + if len(files) >= self.config.files_threshold and lines >= self.config.lines_threshold: + print("🎯 Thresholds já atingidos! Processando imediatamente...\n") + self.process_changes() + self.tracker.reset() + else: + print(f"⏳ Aguardando mais mudanças (precisa {self.config.files_threshold} arquivos e {self.config.lines_threshold} linhas)") + else: + print("✓ Nenhuma alteração pendente") + + print("\n👀 Monitorando alterações contínuas...\n") + + self.running = True + + try: + while self.running: + time.sleep(5) + self._check_and_process() + except KeyboardInterrupt: + print("\n\n⏹️ Parando Git Context Layer...") + + + def _check_and_process(self): + """Verifica e processa alterações se thresholds atingidos""" + if self.tracker.should_trigger(self.config, self.git): + print("\n" + "="*60) + print("🎯 Thresholds atingidos! Iniciando análise...") + print("="*60) + + self.process_changes() + self.tracker.reset() + + def process_changes(self): + """Processa alterações: analisa, commita e faz push se configurado""" + files = self.git.get_modified_files() + if not files: + print("ℹ️ Nenhuma alteração detectada") + return + + print(f"\n📝 Arquivos modificados: {len(files)}") + for f in files[:10]: + print(f" • {f}") + if len(files) > 10: + print(f" ... e mais {len(files) - 10} arquivos") + + lines = self.git.count_lines_changed() + print(f"📊 Linhas modificadas: {lines}") + + print("\n🔒 Verificando regras de segurança...") + + for filepath in files: + full_path = self.git.repo_path / filepath + if full_path.exists() and full_path.stat().st_size > self.config.max_file_size: + print(f"⚠️ Arquivo muito grande: {filepath}") + return + + print("\n🤖 Analisando alterações com IA...") + diff = self.git.get_diff() + commit_output, *usage_stats = asyncio.run(GenerateCommitMessageAgent( + self.config.api_key, + "", + diff, + files, + self.config.ai_model, + 40000, + ) + ) + commit_message = f"{commit_output.subject}\n\n{commit_output.body}" + + print("\n💬 Mensagem de commit gerada:") + print("   " + commit_message.replace("\n", "\n   ")) + + print("\n📦 Criando staging e commit...") + self.git.git_add() + self.git.git_commit(commit_message) + print("✅ Commit criado com sucesso!") + if self.config.require_tests and self.git.has_tests(): + print("\n🧪 Executando testes...") + if not self.git.run_tests(): + print("❌ Testes falharam! Push cancelado.") + return + print("✅ Testes passaram!") + + if self.config.auto_push: + print("\n🚀 Fazendo push para repositório remoto...") + self.git.git_push() + print("✅ Push concluído!") + else: + print("\n⏸️ Auto-push desabilitado. Execute 'git push' manualmente.") + + print("\n" + "="*60) + print("✨ Processo concluído!") + print("="*60 + "\n") + + +def main(): + """Função principal""" + config = Config.load() + + config.api_key = os.getenv("OPENAI_API_KEY", "") + if not config.api_key: + print("❌ Erro: OPENAI_API_KEY não configurada") + print("Configure no arquivo .gitcontext.json ou variável de ambiente") + sys.exit(1) + + if not os.path.exists(".gitcontext.json"): + config.save() + print("📝 Arquivo de configuração criado: .gitcontext.json") + + gcl = GitContextLayer(config) + gcl.start_watching() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Back-End/observer.py b/Back-End/observer.py index b3967331b..ce4465990 100644 --- a/Back-End/observer.py +++ b/Back-End/observer.py @@ -3,11 +3,8 @@ from flask import Flask, request, abort from dotenv import load_dotenv import threading - from Modules.Resolvers.pr_process import process_pull_request from Modules.Resolvers.verify_signature import verify_signature - - logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", @@ -16,7 +13,6 @@ ] ) logger = logging.getLogger(__name__) - load_dotenv(os.path.join(os.path.dirname(__file__), "keys.env")) app = Flask(__name__) GITHUB_SECRET = os.getenv('GITHUB_SECRET', '') @@ -53,8 +49,6 @@ def webhookgenpr(): logger.info("Evento ignorado.") return 'Evento ignorado', 200 - - -if __name__ == '__main__': - logger.info("Inicialized !!!!!!") - app.run(host='0.0.0.0', port=5071) +# if __name__ == '__main__': +# logger.info("Inicialized !!!!!!") +# app.run(host='0.0.0.0', port=5071) \ No newline at end of file diff --git a/Back-End/requirements.txt b/Back-End/requirements.txt index c7f3972e5..e8e61b998 100644 --- a/Back-End/requirements.txt +++ b/Back-End/requirements.txt @@ -18,8 +18,8 @@ bcrypt==4.1.2 reportlab tiktoken - - +anthropic +watchdog celery redis google-api-python-client diff --git a/Front-End/git-genius-commit/.env b/Front-End/git-genius-commit/.env new file mode 100644 index 000000000..dcb08b627 --- /dev/null +++ b/Front-End/git-genius-commit/.env @@ -0,0 +1 @@ +VITE_BACK_END=http://localhost:5910 \ No newline at end of file diff --git a/Front-End/git-genius-commit/.gitignore b/Front-End/git-genius-commit/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/Front-End/git-genius-commit/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/Front-End/git-genius-commit/README.md b/Front-End/git-genius-commit/README.md new file mode 100644 index 000000000..8c7c7c29c --- /dev/null +++ b/Front-End/git-genius-commit/README.md @@ -0,0 +1,73 @@ +# Welcome to your Lovable project + +## Project info + +**URL**: https://lovable.dev/projects/1d94e90c-85d7-4aed-8fa2-ede2b4be6989 + +## How can I edit this code? + +There are several ways of editing your application. + +**Use Lovable** + +Simply visit the [Lovable Project](https://lovable.dev/projects/1d94e90c-85d7-4aed-8fa2-ede2b4be6989) and start prompting. + +Changes made via Lovable will be committed automatically to this repo. + +**Use your preferred IDE** + +If you want to work locally using your own IDE, you can clone this repo and push changes. Pushed changes will also be reflected in Lovable. + +The only requirement is having Node.js & npm installed - [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating) + +Follow these steps: + +```sh +# Step 1: Clone the repository using the project's Git URL. +git clone + +# Step 2: Navigate to the project directory. +cd + +# Step 3: Install the necessary dependencies. +npm i + +# Step 4: Start the development server with auto-reloading and an instant preview. +npm run dev +``` + +**Edit a file directly in GitHub** + +- Navigate to the desired file(s). +- Click the "Edit" button (pencil icon) at the top right of the file view. +- Make your changes and commit the changes. + +**Use GitHub Codespaces** + +- Navigate to the main page of your repository. +- Click on the "Code" button (green button) near the top right. +- Select the "Codespaces" tab. +- Click on "New codespace" to launch a new Codespace environment. +- Edit files directly within the Codespace and commit and push your changes once you're done. + +## What technologies are used for this project? + +This project is built with: + +- Vite +- TypeScript +- React +- shadcn-ui +- Tailwind CSS + +## How can I deploy this project? + +Simply open [Lovable](https://lovable.dev/projects/1d94e90c-85d7-4aed-8fa2-ede2b4be6989) and click on Share -> Publish. + +## Can I connect a custom domain to my Lovable project? + +Yes, you can! + +To connect a domain, navigate to Project > Settings > Domains and click Connect Domain. + +Read more here: [Setting up a custom domain](https://docs.lovable.dev/features/custom-domain#custom-domain) diff --git a/Front-End/git-genius-commit/bun.lockb b/Front-End/git-genius-commit/bun.lockb new file mode 100644 index 0000000000000000000000000000000000000000..d3914e8476ac7bcf7821f221922c3af9816eb903 GIT binary patch literal 197327 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

y2%D`EkutC#5qcdQP^usjju5A?>EK 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 { +    const git = spawn("git", ["-C", repoPath, ...args]); +    let stdout = ""; +    let stderr = ""; + +    git.stdout.on("data", (data) => { +      stdout += data.toString(); +    }); + +    git.stderr.on("data", (data) => { +      stderr += data.toString(); +    }); + +    git.on("close", (code) => { +      if (code === 0) { +        resolve(stdout.trim()); +      } else { +        // Verifica se é um erro comum de "não é repo git" +        const gitError = stderr || `Git command failed with code ${code}`; +        if (gitError.includes('not a git repository')) { +          reject(new Error('The selected path is not a Git repository.')); +        } else { +          reject(new Error(gitError)); +        } +      } +    }); +  }); +} + +// Analisa o status do Git +async function getGitStatus(repoPath) { +  try { +    // 1. Status básico para modified files +    const porcelain = await runGitCommand(repoPath, "status", "--porcelain"); +    const files = porcelain +      .split("\n") +      .filter((line) => line.trim()) +      .map((line) => line.substring(3).trim()); // trim no nome do arquivo + +    // 2. Diff para lines changed +    const numstat = await runGitCommand(repoPath, "diff", "--numstat"); +    let linesChanged = 0; + +    numstat.split("\n").forEach((line) => { +      if (line.trim()) { +        const parts = line.split("\t"); +        if (parts.length >= 3) { +          const [insertions, deletions] = parts; +          if (!isNaN(parseInt(insertions))) linesChanged += parseInt(insertions); +          if (!isNaN(parseInt(deletions))) linesChanged += parseInt(deletions); +        } +      } +    }); + +    return { +      modified_files: files, +      lines_changed: linesChanged, +      has_changes: files.length > 0, +    }; +  } catch (error) { +    console.error("Error getting git status:", error.message); +    // Rejeita a promise para que o frontend possa exibir o erro +    throw new Error(error.message); +  } +} + +// Obtém o diff completo +async function getGitDiff(repoPath) { +  try { +    // Usamos git diff para as mudanças não staged +    return await runGitCommand(repoPath, "diff"); +  } catch (error) { +    console.error("Error getting git diff:", error.message); +    throw new Error(error.message); +  } +} + +// Executa commit +async function executeCommit(repoPath, message, autoPush = false) { +  try { +    await runGitCommand(repoPath, "add", "."); +    await runGitCommand(repoPath, "commit", "-m", message); + +    if (autoPush) { +      await runGitCommand(repoPath, "push"); +    } + +    return { success: true }; +  } catch (error) { +    console.error("Error executing commit:", error.message); +    throw error; +  } +} + +// Verifica se deve disparar análise (Lógica de Monitoramento) +async function shouldTrigger(repoPath, config) { +  const status = await getGitStatus(repoPath); + +  if (!status.has_changes) { +    monitoringState.lastActivityTime = Date.now(); +    return { shouldTrigger: false, status }; +  } + +  if ( +    status.modified_files.length < config.files_threshold || +    status.lines_changed < config.lines_threshold +  ) { +    return { shouldTrigger: false, status }; +  } + +  const timeSinceLastActivity = +    (Date.now() - monitoringState.lastActivityTime) / 1000; + +  if (timeSinceLastActivity < config.time_threshold) { +    return { shouldTrigger: false, status }; +  } + +  return { shouldTrigger: true, status }; +} + +// Envia para API e processa commit (Lógica de Monitoramento) +async function analyzeAndCommit(repoPath, config, mainWindow) { +  try { +    const status = await getGitStatus(repoPath); +    const diff = await getGitDiff(repoPath); + +    mainWindow.webContents.send("git:analyzing", { status }); +    const response = await fetch(`${backend}/api/prai/gen`, { +      method: "POST", +      headers: { +        "Content-Type": "application/json", +        'X-API-TOKEN': `${accessToken}`, +      }, +      body: JSON.stringify({ +        diff: diff, +        files: status.modified_files, +        model: config.ai_model || "gpt-5-nano", +      }), +    }); + +    if (!response.ok) { +      throw new Error(`API error: ${response.status} - ${response.statusText}`); +    } + +    const result = await response.json(); +    const commitMessage = `${result.subject}\n\n${result.body}`; + +    mainWindow.webContents.send("git:commitGenerated", { +      commit_message: commitMessage, +      status: "READY", +    }); + +    if (config.auto_commit !== false) { +      await executeCommit(repoPath, commitMessage, config.auto_push); +      mainWindow.webContents.send("git:committed", { success: true }); +    } + +    monitoringState.lastActivityTime = Date.now(); +  } catch (error) { +    console.error("Error analyzing and committing:", error.message); +    mainWindow.webContents.send("git:error", { +      error: error.message, +    }); +  } +} + + +// Inicia monitoramento (Lógica de Monitoramento) +function startMonitoring(repoPath, config, mainWindow) { + if (monitoringState.isMonitoring) { + stopMonitoring(); + } + + monitoringState.isMonitoring = true; + monitoringState.currentRepoPath = repoPath; + monitoringState.config = config; + monitoringState.lastActivityTime = Date.now(); + + // Verifica imediatamente se há mudanças pendentes + shouldTrigger(repoPath, config) + .then(({ shouldTrigger: trigger, status }) => { + // usa optional chaining para evitar crash caso mainWindow ainda não esteja definido + mainWindow?.webContents.send("git:statusUpdate", status); + + if (trigger) { + analyzeAndCommit(repoPath, config, mainWindow); + } + }) + .catch(error => { + // Trata erro no status inicial (ex: não é repo git) + mainWindow?.webContents.send("git:error", { error: error.message }); + stopMonitoring(); + }); + + // Inicia verificação periódica + monitoringState.checkInterval = setInterval(async () => { + try { + // renomeia o campo desestruturado para evitar conflito com a função shouldTrigger + const { shouldTrigger: trigger, status } = await shouldTrigger(repoPath, config); + + mainWindow?.webContents.send("git:statusUpdate", status); + + if (trigger) { + analyzeAndCommit(repoPath, config, mainWindow); + } + } catch (error) { + // Envia erro e para o monitoring se falhar periodicamente + mainWindow?.webContents.send("git:error", { error: error.message }); + stopMonitoring(); + } + }, 5000); // Verifica a cada 5 segundos + + console.log("🚀 Git Context Layer monitoring started"); +} + +// Para monitoramento (Lógica de Monitoramento) +function stopMonitoring() { +  // ... (Lógica de stopMonitoring mantida) +  if (monitoringState.checkInterval) { +    clearInterval(monitoringState.checkInterval); +    monitoringState.checkInterval = null; +  } +  monitoringState.isMonitoring = false; +  monitoringState.currentRepoPath = null; +  console.log("⏹️  Git Context Layer monitoring stopped"); +} + + +app.whenReady().then(() => { + // 1) Registra todos os IPC handlers ANTES de carregar o renderer + ipcMain.handle("dialog:selectFolder", async () => { + const { canceled, filePaths } = await dialog.showOpenDialog({ + properties: ["openDirectory"], + }); + if (canceled) return null; + return filePaths[0]; + }); + + ipcMain.handle("git:getStatus", async (event, repoPath) => { + return await getGitStatus(repoPath); + }); + + ipcMain.handle("git:getMonitoringState", () => { + return { + is_monitoring: monitoringState.isMonitoring, + }; + }); + + ipcMain.handle("git:getDiff", async (event, repoPath) => { + return await getGitDiff(repoPath); + }); + + ipcMain.handle("git:analyze", async (event, { repoPath, config }) => { + try { + const status = await getGitStatus(repoPath); + const diff = await getGitDiff(repoPath); + const response = await fetch(config.api_endpoint, { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-API-TOKEN": `${config.api_key}`, + }, + body: JSON.stringify({ + diff: diff, + files: status.modified_files, + model: config.ai_model || "gpt-5-nano", + }), + }); + + if (!response.ok) { + throw new Error(`API error: ${response.statusText}`); + } + + const result = await response.json(); + return { + commit_message: `${result.subject}\n\n${result.body}`, + status: "READY", + }; + } catch (error) { + console.error("Error analyzing:", error); + throw error; + } + }); + + ipcMain.handle("git:commit", async (event, { repoPath, message, autoPush }) => { + return await executeCommit(repoPath, message, autoPush); + }); + + ipcMain.handle("git:toggleMonitoring", async (event, { repoPath, config }) => { + if (monitoringState.isMonitoring && monitoringState.currentRepoPath === repoPath) { + stopMonitoring(); + return { is_monitoring: false }; + } else { + // Inicia e o startMonitoring usa mainWindow (que já vamos setar abaixo) + startMonitoring(repoPath, config, mainWindow); + return { is_monitoring: true }; + } + }); + + // 2) Agora criamos a janela e só então carregamos o renderer + mainWindow = createWindow(); + + if (process.env.NODE_ENV === "development") { + mainWindow.loadURL("http://localhost:4343"); + mainWindow.webContents.openDevTools(); + } else { + mainWindow.loadFile(path.join(__dirname, "..", "dist", "index.html")); + } + +}); +app.on("window-all-closed", () => { +  stopMonitoring(); +  if (process.platform !== "darwin") { +    app.quit(); +  } +}); + +app.on("activate", () => { +  if (BrowserWindow.getAllWindows().length === 0) { +    createWindow(); +  } +}); \ No newline at end of file diff --git a/Front-End/git-genius-commit/electron/preload.cjs b/Front-End/git-genius-commit/electron/preload.cjs new file mode 100644 index 000000000..84467fe83 --- /dev/null +++ b/Front-End/git-genius-commit/electron/preload.cjs @@ -0,0 +1,36 @@ +// electron/preload.cjs (apenas garanta a exportação) +const { contextBridge, ipcRenderer } = require("electron"); + +contextBridge.exposeInMainWorld("electronAPI", { + selectFolder: () => ipcRenderer.invoke("dialog:selectFolder"), + + git: { + getStatus: (repoPath) => ipcRenderer.invoke("git:getStatus", repoPath), + getMonitoringState: () => ipcRenderer.invoke("git:getMonitoringState"), + toggleMonitoring: (repoPath, config) => ipcRenderer.invoke("git:toggleMonitoring", { repoPath, config }), + analyze: (repoPath, config) => ipcRenderer.invoke("git:analyze", { repoPath, config }), + commit: (repoPath, message, autoPush) => ipcRenderer.invoke("git:commit", { repoPath, message, autoPush }), + getDiff: (repoPath) => ipcRenderer.invoke("git:getDiff", repoPath), + + onStatusUpdate: (callback) => { + ipcRenderer.removeAllListeners("git:statusUpdate"); + ipcRenderer.on("git:statusUpdate", (event, status) => callback(status)); + }, + onAnalyzing: (callback) => { + ipcRenderer.removeAllListeners("git:analyzing"); + ipcRenderer.on("git:analyzing", (event, data) => callback(data)); + }, + onCommitGenerated: (callback) => { + ipcRenderer.removeAllListeners("git:commitGenerated"); + ipcRenderer.on("git:commitGenerated", (event, data) => callback(data)); + }, + onCommitted: (callback) => { + ipcRenderer.removeAllListeners("git:committed"); + ipcRenderer.on("git:committed", (event, data) => callback(data)); + }, + onError: (callback) => { + ipcRenderer.removeAllListeners("git:error"); + ipcRenderer.on("git:error", (event, data) => callback(data)); + }, + } +}); diff --git a/Front-End/git-genius-commit/eslint.config.js b/Front-End/git-genius-commit/eslint.config.js new file mode 100644 index 000000000..40f72cc45 --- /dev/null +++ b/Front-End/git-genius-commit/eslint.config.js @@ -0,0 +1,26 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], + "@typescript-eslint/no-unused-vars": "off", + }, + }, +); diff --git a/Front-End/git-genius-commit/index.html b/Front-End/git-genius-commit/index.html new file mode 100644 index 000000000..bee23e175 --- /dev/null +++ b/Front-End/git-genius-commit/index.html @@ -0,0 +1,24 @@ + + + + + + git-genius-commit + + + + + + + + + + + + + + +

+ + + diff --git a/Front-End/package-lock.json b/Front-End/git-genius-commit/package-lock.json similarity index 72% rename from Front-End/package-lock.json rename to Front-End/git-genius-commit/package-lock.json index ae000901b..c05676c2b 100644 --- a/Front-End/package-lock.json +++ b/Front-End/git-genius-commit/package-lock.json @@ -8,78 +8,74 @@ "name": "vite_react_shadcn_ts", "version": "0.0.0", "dependencies": { - "@hookform/resolvers": "^3.9.0", - "@radix-ui/react-accordion": "^1.2.0", - "@radix-ui/react-alert-dialog": "^1.1.1", - "@radix-ui/react-aspect-ratio": "^1.1.0", - "@radix-ui/react-avatar": "^1.1.0", - "@radix-ui/react-checkbox": "^1.1.1", - "@radix-ui/react-collapsible": "^1.1.0", - "@radix-ui/react-context-menu": "^2.2.1", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-dropdown-menu": "^2.1.1", - "@radix-ui/react-hover-card": "^1.1.1", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-menubar": "^1.1.1", - "@radix-ui/react-navigation-menu": "^1.2.0", - "@radix-ui/react-popover": "^1.1.1", - "@radix-ui/react-progress": "^1.1.0", - "@radix-ui/react-radio-group": "^1.2.0", - "@radix-ui/react-scroll-area": "^1.1.0", - "@radix-ui/react-select": "^2.1.1", - "@radix-ui/react-separator": "^1.1.0", - "@radix-ui/react-slider": "^1.2.0", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-switch": "^1.1.0", - "@radix-ui/react-tabs": "^1.1.0", - "@radix-ui/react-toast": "^1.2.1", - "@radix-ui/react-toggle": "^1.1.0", - "@radix-ui/react-toggle-group": "^1.1.0", - "@radix-ui/react-tooltip": "^1.1.4", - "@stripe/stripe-js": "^7.9.0", - "@tanstack/react-query": "^5.56.2", - "axios": "^1.12.2", + "@hookform/resolvers": "^3.10.0", + "@radix-ui/react-accordion": "^1.2.11", + "@radix-ui/react-alert-dialog": "^1.1.14", + "@radix-ui/react-aspect-ratio": "^1.1.7", + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-checkbox": "^1.3.2", + "@radix-ui/react-collapsible": "^1.1.11", + "@radix-ui/react-context-menu": "^2.2.15", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-hover-card": "^1.1.14", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-menubar": "^1.1.15", + "@radix-ui/react-navigation-menu": "^1.2.13", + "@radix-ui/react-popover": "^1.1.14", + "@radix-ui/react-progress": "^1.1.7", + "@radix-ui/react-radio-group": "^1.3.7", + "@radix-ui/react-scroll-area": "^1.2.9", + "@radix-ui/react-select": "^2.2.5", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slider": "^1.3.5", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.2.5", + "@radix-ui/react-tabs": "^1.1.12", + "@radix-ui/react-toast": "^1.2.14", + "@radix-ui/react-toggle": "^1.1.9", + "@radix-ui/react-toggle-group": "^1.1.10", + "@radix-ui/react-tooltip": "^1.2.7", + "@tanstack/react-query": "^5.83.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "cmdk": "^1.0.0", + "cmdk": "^1.1.1", "date-fns": "^3.6.0", - "embla-carousel-react": "^8.3.0", - "framer-motion": "^12.23.22", - "input-otp": "^1.2.4", + "embla-carousel-react": "^8.6.0", + "input-otp": "^1.4.2", "lucide-react": "^0.462.0", "next-themes": "^0.3.0", "react": "^18.3.1", "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", - "react-hook-form": "^7.53.0", - "react-icons": "^5.5.0", - "react-resizable-panels": "^2.1.3", - "react-router-dom": "^6.26.2", - "recharts": "^2.12.7", - "sonner": "^1.5.0", - "tailwind-merge": "^2.5.2", + "react-hook-form": "^7.61.1", + "react-resizable-panels": "^2.1.9", + "react-router-dom": "^6.30.1", + "recharts": "^2.15.4", + "sonner": "^1.7.4", + "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", - "vaul": "^0.9.3", - "zod": "^3.23.8" + "vaul": "^0.9.9", + "zod": "^3.25.76" }, "devDependencies": { - "@eslint/js": "^9.9.0", - "@tailwindcss/typography": "^0.5.15", - "@types/node": "^22.5.5", - "@types/react": "^18.3.24", - "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react-swc": "^3.5.0", - "autoprefixer": "^10.4.20", - "eslint": "^9.9.0", - "eslint-plugin-react-hooks": "^5.1.0-rc.0", - "eslint-plugin-react-refresh": "^0.4.9", - "globals": "^15.9.0", - "lovable-tagger": "^1.1.7", - "postcss": "^8.4.47", - "tailwindcss": "^3.4.11", - "typescript": "^5.5.3", - "typescript-eslint": "^8.0.1", - "vite": "^5.4.1" + "@eslint/js": "^9.32.0", + "@tailwindcss/typography": "^0.5.16", + "@types/node": "^22.16.5", + "@types/react": "^18.3.23", + "@types/react-dom": "^18.3.7", + "@vitejs/plugin-react-swc": "^3.11.0", + "autoprefixer": "^10.4.21", + "eslint": "^9.32.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^15.15.0", + "lovable-tagger": "^1.1.10", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.17", + "typescript": "^5.8.3", + "typescript-eslint": "^8.38.0", + "vite": "^5.4.19" } }, "node_modules/@alloc/quick-lru": { @@ -131,13 +127,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz", + "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==", "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { "node": ">=6.9.0" } @@ -582,17 +575,20 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } @@ -611,9 +607,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { @@ -621,13 +617,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.4", + "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -635,20 +631,33 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/core": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", - "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -683,19 +692,22 @@ } }, "node_modules/@eslint/js": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", - "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -703,11 +715,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", - "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", + "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", "dev": true, + "license": "Apache-2.0", "dependencies": { + "@eslint/core": "^0.15.1", "levn": "^0.4.1" }, "engines": { @@ -715,31 +729,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", - "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", + "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.8" + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", - "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", + "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.8" + "@floating-ui/core": "^1.7.2", + "@floating-ui/utils": "^0.2.10" } }, "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==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", + "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.0.0" + "@floating-ui/dom": "^1.7.2" }, "peerDependencies": { "react": ">=16.8.0", @@ -747,24 +761,24 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", - "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, "node_modules/@hookform/resolvers": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.0.tgz", - "integrity": "sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz", + "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==", "license": "MIT", "peerDependencies": { "react-hook-form": "^7.0.0" } }, "node_modules/@humanfs/core": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", - "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -772,19 +786,33 @@ } }, "node_modules/@humanfs/node": { - "version": "0.16.5", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", - "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.0", + "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -800,9 +828,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -924,32 +952,32 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", + "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", "license": "MIT" }, "node_modules/@radix-ui/react-accordion": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.1.tgz", - "integrity": "sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.11.tgz", + "integrity": "sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collapsible": "1.1.1", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@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.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collapsible": "1.1.11", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -967,17 +995,17 @@ } }, "node_modules/@radix-ui/react-alert-dialog": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.2.tgz", - "integrity": "sha512-eGSlLzPhKO+TErxkiGcCZGuvbVMnLA1MTnyBksGOeGRGkxHiiJUujsjmNTdWTm4iHVSRaUao9/4Ur671auMghQ==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.14.tgz", + "integrity": "sha512-IOZfZ3nPvN6lXpJTBCunFQPRSvK8MDgSc1FB85xnIpUKOw9en0dJj8JmCAxV7BiZdtYlUpmrQjoTFkVYtdoWzQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dialog": "1.1.2", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.14", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -995,12 +1023,12 @@ } }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1018,12 +1046,12 @@ } }, "node_modules/@radix-ui/react-aspect-ratio": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.0.tgz", - "integrity": "sha512-dP87DM/Y7jFlPgUZTlhx6FF5CEzOiaxp2rBCKlaXlpH5Ip/9Fg5zZ9lDOQ5o/MOfUlf36eak14zoWYpgcgGoOg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1041,15 +1069,16 @@ } }, "node_modules/@radix-ui/react-avatar": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.1.tgz", - "integrity": "sha512-eoOtThOmxeoizxpX6RiEsQZ2wj5r4+zoeqAwO0cBaFQGjJwIH3dIX0OCxNrCyrrdxG+vBweMETh3VziQG7c1kw==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", "license": "MIT", "dependencies": { - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1067,19 +1096,19 @@ } }, "node_modules/@radix-ui/react-checkbox": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.2.tgz", - "integrity": "sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.2.tgz", + "integrity": "sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@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" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1097,19 +1126,19 @@ } }, "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz", - "integrity": "sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.11.tgz", + "integrity": "sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1127,15 +1156,15 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", - "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1152,25 +1181,10 @@ } } }, - "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1183,9 +1197,9 @@ } }, "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==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1198,17 +1212,17 @@ } }, "node_modules/@radix-ui/react-context-menu": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.2.tgz", - "integrity": "sha512-99EatSTpW+hRYHt7m8wdDlLtkmTovEe8Z/hnxUPV+SKuuNL5HWNhQI4QSdjZqNSgXHay2z4M3Dym73j9p2Gx5Q==", + "version": "2.2.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.15.tgz", + "integrity": "sha512-UsQUMjcYTsBjTSXw0P3GO0werEQvUY2plgRQuKoCTtkNr45q1DiL51j4m7gxhABzZ0BadoXNsIbg7F3KwiUBbw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-menu": "2.1.2", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-menu": "2.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1226,25 +1240,25 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz", - "integrity": "sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", + "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", @@ -1262,9 +1276,9 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1277,16 +1291,16 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz", - "integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1304,18 +1318,18 @@ } }, "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.2.tgz", - "integrity": "sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==", + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.15.tgz", + "integrity": "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-menu": "2.1.2", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1333,9 +1347,9 @@ } }, "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==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1348,14 +1362,14 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", - "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1373,20 +1387,20 @@ } }, "node_modules/@radix-ui/react-hover-card": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.2.tgz", - "integrity": "sha512-Y5w0qGhysvmqsIy6nQxaPa6mXNKznfoGjOfBgzOjocLxr2XlSjqBMYQQL+FfyogsMuX+m8cZyQGYhJxvxUzO4w==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.14.tgz", + "integrity": "sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1404,12 +1418,12 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1422,12 +1436,12 @@ } }, "node_modules/@radix-ui/react-label": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.0.tgz", - "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1445,29 +1459,29 @@ } }, "node_modules/@radix-ui/react-menu": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.2.tgz", - "integrity": "sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-roving-focus": "1.1.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.15.tgz", + "integrity": "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.10", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", @@ -1485,21 +1499,21 @@ } }, "node_modules/@radix-ui/react-menubar": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.2.tgz", - "integrity": "sha512-cKmj5Gte7LVyuz+8gXinxZAZECQU+N7aq5pw7kUPpx3xjnDXDbsdzHtCCD2W72bwzy74AvrqdYnKYS42ueskUQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@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.2", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-roving-focus": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.15.tgz", + "integrity": "sha512-Z71C7LGD+YDYo3TV81paUs8f3Zbmkvg6VLRQpKYfzioOE6n7fOhA3ApK/V/2Odolxjoc4ENk8AYCjohCNayd5A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1517,25 +1531,25 @@ } }, "node_modules/@radix-ui/react-navigation-menu": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.1.tgz", - "integrity": "sha512-egDo0yJD2IK8L17gC82vptkvW1jLeni1VuqCyzY727dSJdk5cDjINomouLoNk8RVF7g2aNIfENKWL4UzeU9c8Q==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@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.0" + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.13.tgz", + "integrity": "sha512-WG8wWfDiJlSF5hELjwfjSGOXcBR/ZMhBFCGYe8vERpC39CQYZeq1PQ2kaYHdye3V95d06H89KGMsVCIE4LWo3g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1553,26 +1567,26 @@ } }, "node_modules/@radix-ui/react-popover": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.2.tgz", - "integrity": "sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.14.tgz", + "integrity": "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", @@ -1590,21 +1604,21 @@ } }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", - "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", + "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@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" + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1621,29 +1635,14 @@ } } }, - "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz", - "integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1661,13 +1660,13 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", - "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1685,12 +1684,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", - "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.1.0" + "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1708,13 +1707,13 @@ } }, "node_modules/@radix-ui/react-progress": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.0.tgz", - "integrity": "sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", "license": "MIT", "dependencies": { - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1731,37 +1730,22 @@ } } }, - "node_modules/@radix-ui/react-progress/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-radio-group": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.1.tgz", - "integrity": "sha512-kdbv54g4vfRjja9DNWPMxKvXblzqbpEC8kspEkZ6dVP7kQksGCn+iZHkcCz2nb00+lPdRvxrqy4WrvvV1cNqrQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-roving-focus": "1.1.0", - "@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" + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.7.tgz", + "integrity": "sha512-9w5XhD0KPOrm92OTTE0SysH3sYzHsSTHNvZgUBo/VZ80VdYyB5RneDbc0dKpURS24IxkoFRu/hI0i4XyfFwY6g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1779,20 +1763,20 @@ } }, "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", - "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz", + "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1809,36 +1793,21 @@ } } }, - "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-scroll-area": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.0.tgz", - "integrity": "sha512-q2jMBdsJ9zB7QG6ngQNzNwlvxLQqONyL58QbEGwuyRZZb/ARQwk3uQVbCF7GvQVOtV6EU/pDxAw3zRzJZI3rpQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.9.tgz", + "integrity": "sha512-YSjEfBXnhUELsO2VzjdtYYD4CfQjvao+lhhrX5XsHD7/cyUNzljF1FHEbgTPN7LH2MClfwRMIsYlqTYpKTTe2A==", "license": "MIT", "dependencies": { - "@radix-ui/number": "1.1.0", - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1856,32 +1825,32 @@ } }, "node_modules/@radix-ui/react-select": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.2.tgz", - "integrity": "sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.0", - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@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.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.6.0" + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.5.tgz", + "integrity": "sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", @@ -1899,12 +1868,12 @@ } }, "node_modules/@radix-ui/react-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.0.tgz", - "integrity": "sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1922,22 +1891,22 @@ } }, "node_modules/@radix-ui/react-slider": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.2.1.tgz", - "integrity": "sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.0", - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-primitive": "2.0.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-use-size": "1.1.0" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.5.tgz", + "integrity": "sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1955,12 +1924,12 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -1973,18 +1942,18 @@ } }, "node_modules/@radix-ui/react-switch": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.1.tgz", - "integrity": "sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.5.tgz", + "integrity": "sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@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" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -2002,19 +1971,19 @@ } }, "node_modules/@radix-ui/react-tabs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.1.tgz", - "integrity": "sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.12.tgz", + "integrity": "sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@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.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-roving-focus": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2032,23 +2001,23 @@ } }, "node_modules/@radix-ui/react-toast": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.2.tgz", - "integrity": "sha512-Z6pqSzmAP/bFJoqMAston4eSNa+ud44NSZTiZUmUen+IOZ5nBY8kzuU5WDBVyFXPtcW6yUalOHsxM/BP6Sv8ww==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-collection": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@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.0" + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.14.tgz", + "integrity": "sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -2066,14 +2035,14 @@ } }, "node_modules/@radix-ui/react-toggle": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz", - "integrity": "sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.9.tgz", + "integrity": "sha512-ZoFkBBz9zv9GWer7wIjvdRxmh2wyc2oKWw6C6CseWd6/yq1DK/l5lJ+wnsmFwJZbBYqr02mrf8A2q/CVCuM3ZA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2091,18 +2060,18 @@ } }, "node_modules/@radix-ui/react-toggle-group": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.0.tgz", - "integrity": "sha512-PpTJV68dZU2oqqgq75Uzto5o/XfOVgkrJ9rulVmfTKxWp3HfUjHE6CP/WLRR4AzPX9HWxw7vFow2me85Yu+Naw==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.10.tgz", + "integrity": "sha512-kiU694Km3WFLTC75DdqgM/3Jauf3rD9wxeS9XtyWFKsBUeZA337lC+6uUazT7I1DhanZ5gyD5Stf8uf2dbQxOQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-direction": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-roving-focus": "1.1.0", - "@radix-ui/react-toggle": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0" + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.10", + "@radix-ui/react-toggle": "1.1.9", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2119,10 +2088,44 @@ } } }, - "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz", + "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.2", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2134,44 +2137,33 @@ } } }, - "node_modules/@radix-ui/react-tooltip": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.4.tgz", - "integrity": "sha512-QpObUH/ZlpaO4YgHSaYzrLO2VuO+ZBFFgGzjMUPwtiYnAzzNNDPJeEGRrT7qNOrWm/Jr08M1vlp+vTHtnSQ0Uw==", - "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.1", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.2", - "@radix-ui/react-presence": "1.1.1", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.0" + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", - "@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" + "react": "^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==", + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2182,13 +2174,13 @@ } } }, - "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==", + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" + "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -2200,13 +2192,13 @@ } } }, - "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==", + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" + "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", @@ -2219,9 +2211,9 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2234,9 +2226,9 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -2249,12 +2241,12 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", "license": "MIT", "dependencies": { - "@radix-ui/rect": "1.1.0" + "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -2267,12 +2259,12 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -2285,12 +2277,12 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", - "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -2308,20 +2300,27 @@ } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", "license": "MIT" }, "node_modules/@remix-run/router": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", - "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==", "license": "MIT", "engines": { "node": ">=14.0.0" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", @@ -2546,25 +2545,16 @@ "win32" ] }, - "node_modules/@stripe/stripe-js": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-7.9.0.tgz", - "integrity": "sha512-ggs5k+/0FUJcIgNY08aZTqpBTtbExkJMYMLSMwyucrhtWexVOEY1KJmhBsxf+E/Q15f5rbwBpj+t0t2AW2oCsQ==", - "license": "MIT", - "engines": { - "node": ">=12.16" - } - }, "node_modules/@swc/core": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.39.tgz", - "integrity": "sha512-jns6VFeOT49uoTKLWIEfiQqJAlyqldNAt80kAr8f7a5YjX0zgnG3RBiLMpksx4Ka4SlK4O6TJ/lumIM3Trp82g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.2.tgz", + "integrity": "sha512-YWqn+0IKXDhqVLKoac4v2tV6hJqB/wOh8/Br8zjqeqBkKa77Qb0Kw2i7LOFzjFNZbZaPH6AlMGlBwNrxaauaAg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.13" + "@swc/types": "^0.1.23" }, "engines": { "node": ">=10" @@ -2574,19 +2564,19 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.39", - "@swc/core-darwin-x64": "1.7.39", - "@swc/core-linux-arm-gnueabihf": "1.7.39", - "@swc/core-linux-arm64-gnu": "1.7.39", - "@swc/core-linux-arm64-musl": "1.7.39", - "@swc/core-linux-x64-gnu": "1.7.39", - "@swc/core-linux-x64-musl": "1.7.39", - "@swc/core-win32-arm64-msvc": "1.7.39", - "@swc/core-win32-ia32-msvc": "1.7.39", - "@swc/core-win32-x64-msvc": "1.7.39" + "@swc/core-darwin-arm64": "1.13.2", + "@swc/core-darwin-x64": "1.13.2", + "@swc/core-linux-arm-gnueabihf": "1.13.2", + "@swc/core-linux-arm64-gnu": "1.13.2", + "@swc/core-linux-arm64-musl": "1.13.2", + "@swc/core-linux-x64-gnu": "1.13.2", + "@swc/core-linux-x64-musl": "1.13.2", + "@swc/core-win32-arm64-msvc": "1.13.2", + "@swc/core-win32-ia32-msvc": "1.13.2", + "@swc/core-win32-x64-msvc": "1.13.2" }, "peerDependencies": { - "@swc/helpers": "*" + "@swc/helpers": ">=0.5.17" }, "peerDependenciesMeta": { "@swc/helpers": { @@ -2595,9 +2585,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.39.tgz", - "integrity": "sha512-o2nbEL6scMBMCTvY9OnbyVXtepLuNbdblV9oNJEFia5v5eGj9WMrnRQiylH3Wp/G2NYkW7V1/ZVW+kfvIeYe9A==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.2.tgz", + "integrity": "sha512-44p7ivuLSGFJ15Vly4ivLJjg3ARo4879LtEBAabcHhSZygpmkP8eyjyWxrH3OxkY1eRZSIJe8yRZPFw4kPXFPw==", "cpu": [ "arm64" ], @@ -2612,9 +2602,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.39.tgz", - "integrity": "sha512-qMlv3XPgtPi/Fe11VhiPDHSLiYYk2dFYl747oGsHZPq+6tIdDQjIhijXPcsUHIXYDyG7lNpODPL8cP/X1sc9MA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.2.tgz", + "integrity": "sha512-Lb9EZi7X2XDAVmuUlBm2UvVAgSCbD3qKqDCxSI4jEOddzVOpNCnyZ/xEampdngUIyDDhhJLYU9duC+Mcsv5Y+A==", "cpu": [ "x64" ], @@ -2629,9 +2619,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.39.tgz", - "integrity": "sha512-NP+JIkBs1ZKnpa3Lk2W1kBJMwHfNOxCUJXuTa2ckjFsuZ8OUu2gwdeLFkTHbR43dxGwH5UzSmuGocXeMowra/Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.2.tgz", + "integrity": "sha512-9TDe/92ee1x57x+0OqL1huG4BeljVx0nWW4QOOxp8CCK67Rpc/HHl2wciJ0Kl9Dxf2NvpNtkPvqj9+BUmM9WVA==", "cpu": [ "arm" ], @@ -2646,9 +2636,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.39.tgz", - "integrity": "sha512-cPc+/HehyHyHcvAsk3ML/9wYcpWVIWax3YBaA+ScecJpSE04l/oBHPfdqKUPslqZ+Gcw0OWnIBGJT/fBZW2ayw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.2.tgz", + "integrity": "sha512-KJUSl56DBk7AWMAIEcU83zl5mg3vlQYhLELhjwRFkGFMvghQvdqQ3zFOYa4TexKA7noBZa3C8fb24rI5sw9Exg==", "cpu": [ "arm64" ], @@ -2663,9 +2653,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.39.tgz", - "integrity": "sha512-8RxgBC6ubFem66bk9XJ0vclu3exJ6eD7x7CwDhp5AD/tulZslTYXM7oNPjEtje3xxabXuj/bEUMNvHZhQRFdqA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.2.tgz", + "integrity": "sha512-teU27iG1oyWpNh9CzcGQ48ClDRt/RCem7mYO7ehd2FY102UeTws2+OzLESS1TS1tEZipq/5xwx3FzbVgiolCiQ==", "cpu": [ "arm64" ], @@ -2680,9 +2670,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.39.tgz", - "integrity": "sha512-3gtCPEJuXLQEolo9xsXtuPDocmXQx12vewEyFFSMSjOfakuPOBmOQMa0sVL8Wwius8C1eZVeD1fgk0omMqeC+Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.2.tgz", + "integrity": "sha512-dRPsyPyqpLD0HMRCRpYALIh4kdOir8pPg4AhNQZLehKowigRd30RcLXGNVZcc31Ua8CiPI4QSgjOIxK+EQe4LQ==", "cpu": [ "x64" ], @@ -2697,9 +2687,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.39.tgz", - "integrity": "sha512-mg39pW5x/eqqpZDdtjZJxrUvQNSvJF4O8wCl37fbuFUqOtXs4TxsjZ0aolt876HXxxhsQl7rS+N4KioEMSgTZw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.2.tgz", + "integrity": "sha512-CCxETW+KkYEQDqz1SYC15YIWYheqFC+PJVOW76Maa/8yu8Biw+HTAcblKf2isrlUtK8RvrQN94v3UXkC2NzCEw==", "cpu": [ "x64" ], @@ -2714,9 +2704,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.39.tgz", - "integrity": "sha512-NZwuS0mNJowH3e9bMttr7B1fB8bW5svW/yyySigv9qmV5VcQRNz1kMlCvrCLYRsa93JnARuiaBI6FazSeG8mpA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.2.tgz", + "integrity": "sha512-Wv/QTA6PjyRLlmKcN6AmSI4jwSMRl0VTLGs57PHTqYRwwfwd7y4s2fIPJVBNbAlXd795dOEP6d/bGSQSyhOX3A==", "cpu": [ "arm64" ], @@ -2731,9 +2721,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.39.tgz", - "integrity": "sha512-qFmvv5UExbJPXhhvCVDBnjK5Duqxr048dlVB6ZCgGzbRxuarOlawCzzLK4N172230pzlAWGLgn9CWl3+N6zfHA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.2.tgz", + "integrity": "sha512-PuCdtNynEkUNbUXX/wsyUC+t4mamIU5y00lT5vJcAvco3/r16Iaxl5UCzhXYaWZSNVZMzPp9qN8NlSL8M5pPxw==", "cpu": [ "ia32" ], @@ -2748,9 +2738,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.39", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.39.tgz", - "integrity": "sha512-o+5IMqgOtj9+BEOp16atTfBgCogVak9svhBpwsbcJQp67bQbxGYhAPPDW/hZ2rpSSF7UdzbY9wudoX9G4trcuQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.2.tgz", + "integrity": "sha512-qlmMkFZJus8cYuBURx1a3YAG2G7IW44i+FEYV5/32ylKkzGNAr9tDJSA53XNnNXkAB5EXSPsOz7bn5C3JlEtdQ==", "cpu": [ "x64" ], @@ -2772,9 +2762,9 @@ "license": "Apache-2.0" }, "node_modules/@swc/types": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.13.tgz", - "integrity": "sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.23.tgz", + "integrity": "sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2782,10 +2772,11 @@ } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", - "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz", + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==", "dev": true, + "license": "MIT", "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", @@ -2793,7 +2784,7 @@ "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { @@ -2810,9 +2801,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.59.16", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.16.tgz", - "integrity": "sha512-crHn+G3ltqb5JG0oUv6q+PMz1m1YkjpASrXTU+sYWW9pLk0t2GybUHNRqYPZWhxgjPaVGC4yp92gSFEJgYEsPw==", + "version": "5.83.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.83.0.tgz", + "integrity": "sha512-0M8dA+amXUkyz5cVUm/B+zSk3xkQAcuXuz5/Q/LveT4ots2rBpPTZOzd7yJa2Utsf8D2Upl5KyjhHRY+9lB/XA==", "license": "MIT", "funding": { "type": "github", @@ -2820,12 +2811,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.59.16", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.16.tgz", - "integrity": "sha512-MuyWheG47h6ERd4PKQ6V8gDyBu3ThNG22e1fRVwvq6ap3EqsFhyuxCAwhNP/03m/mLg+DAb0upgbPaX6VB+CkQ==", + "version": "5.83.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.83.0.tgz", + "integrity": "sha512-/XGYhZ3foc5H0VM2jLSD/NyBRIOK4q9kfeml4+0x2DlL6xVuAcVEW+hTlTapAmejObg0i3eNqhkr2dT+eciwoQ==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.59.16" + "@tanstack/query-core": "5.83.0" }, "funding": { "type": "github", @@ -2913,13 +2904,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.7.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.9.tgz", - "integrity": "sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==", + "version": "22.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.5.tgz", + "integrity": "sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.21.0" } }, "node_modules/@types/prop-types": { @@ -2930,9 +2921,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.24", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.24.tgz", - "integrity": "sha512-0dLEBsA1kI3OezMBF8nSsb7Nk19ZnsyE1LLhB8r27KbgU5H4pvuqZLdtE+aUkJVoXgTVuA+iLIwmZ0TuK4tx6A==", + "version": "18.3.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", + "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2941,31 +2932,31 @@ } }, "node_modules/@types/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "devOptional": true, "license": "MIT", - "dependencies": { - "@types/react": "*" + "peerDependencies": { + "@types/react": "^18.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", - "integrity": "sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", + "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/type-utils": "8.11.0", - "@typescript-eslint/utils": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/type-utils": "8.38.0", + "@typescript-eslint/utils": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2975,26 +2966,32 @@ "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" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.38.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", - "integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", + "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/typescript-estree": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0", "debug": "^4.3.4" }, "engines": { @@ -3005,23 +3002,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", - "integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", + "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0" + "@typescript-eslint/tsconfig-utils": "^8.38.0", + "@typescript-eslint/types": "^8.38.0", + "debug": "^4.3.4" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3029,19 +3023,20 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz", - "integrity": "sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", + "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.11.0", - "@typescript-eslint/utils": "8.11.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3049,17 +3044,12 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } } }, - "node_modules/@typescript-eslint/types": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", - "integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", + "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", "dev": true, "license": "MIT", "engines": { @@ -3068,23 +3058,67 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", - "integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", + "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/utils": "8.38.0", "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", + "ts-api-utils": "^2.1.0" + }, + "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.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", + "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", + "dev": true, + "license": "MIT", + "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.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", + "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.38.0", + "@typescript-eslint/tsconfig-utils": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/visitor-keys": "8.38.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": "^1.3.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3093,16 +3127,14 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.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==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3126,16 +3158,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", - "integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", + "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/typescript-estree": "8.11.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.38.0", + "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3145,18 +3177,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", - "integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", + "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.38.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3166,36 +3199,24 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@vitejs/plugin-react-swc": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.1.tgz", - "integrity": "sha512-vgWOY0i1EROUK0Ctg1hwhtC3SdcDjZcdit4Ups4aPkDcB1jYhmo+RMYWY87cmXMhvtD5uf8lV89j2w16vkdSVg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz", + "integrity": "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==", "dev": true, "license": "MIT", "dependencies": { - "@swc/core": "^1.7.26" + "@rolldown/pluginutils": "1.0.0-beta.27", + "@swc/core": "^1.12.11" }, "peerDependencies": { - "vite": "^4 || ^5" + "vite": "^4 || ^5 || ^6 || ^7" } }, "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -3303,16 +3324,10 @@ "node": ">=10" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", "dev": true, "funding": [ { @@ -3330,11 +3345,11 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", + "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -3347,17 +3362,6 @@ "postcss": "^8.1.0" } }, - "node_modules/axios": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3377,9 +3381,9 @@ } }, "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==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -3400,9 +3404,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "funding": [ { @@ -3420,10 +3424,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -3432,19 +3436,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "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==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3465,9 +3456,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001669", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", - "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "dev": true, "funding": [ { @@ -3543,397 +3534,35 @@ "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": { - "url": "https://polar.sh/cva" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cmdk": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", - "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-dialog": "1.0.5", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "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==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": 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==", - "license": "MIT", - "dependencies": { - "@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" - }, - "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/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==", - "license": "MIT", - "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": { - "@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/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==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": 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==", - "license": "MIT", - "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": { - "@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/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==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": 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==", - "license": "MIT", - "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/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==", - "license": "MIT", - "dependencies": { - "@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/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==", - "license": "MIT", - "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 - }, - "@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==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/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==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "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==", - "license": "MIT", - "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/cmdk/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==", - "license": "MIT", - "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" + "clsx": "^2.1.1" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "funding": { + "url": "https://polar.sh/cva" } }, - "node_modules/cmdk/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==", + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">=6" } }, - "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==", + "node_modules/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", "license": "MIT", "dependencies": { - "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" + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { - "@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 - } + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "node_modules/color-convert": { @@ -3954,18 +3583,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -4175,15 +3792,6 @@ "dev": true, "license": "MIT" }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", @@ -4212,20 +3820,6 @@ "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==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4233,38 +3827,38 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.45", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.45.tgz", - "integrity": "sha512-vOzZS6uZwhhbkZbcRyiy99Wg+pYFV5hk+5YaECvx0+Z31NR3Tt5zS6dze2OepT6PCTzVzT0dIJItti+uAW5zmw==", + "version": "1.5.192", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.192.tgz", + "integrity": "sha512-rP8Ez0w7UNw/9j5eSXCe10o1g/8B1P5SM90PCCMVkIRQn2R0LEHWz4Eh9RnxkniuDe1W0cTSOB3MLlkTGDcuCg==", "dev": true, "license": "ISC" }, "node_modules/embla-carousel": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.3.0.tgz", - "integrity": "sha512-Ve8dhI4w28qBqR8J+aMtv7rLK89r1ZA5HocwFz6uMB/i5EiC7bGI7y+AM80yAVUJw3qqaZYK7clmZMUR8kM3UA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", + "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", "license": "MIT" }, "node_modules/embla-carousel-react": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.3.0.tgz", - "integrity": "sha512-P1FlinFDcIvggcErRjNuVqnUR8anyo8vLMIH8Rthgofw7Nj8qTguCa2QjFAbzxAUTQTPNNjNL7yt0BGGinVdFw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz", + "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==", "license": "MIT", "dependencies": { - "embla-carousel": "8.3.0", - "embla-carousel-reactive-utils": "8.3.0" + "embla-carousel": "8.6.0", + "embla-carousel-reactive-utils": "8.6.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.1 || ^18.0.0" + "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.3.0", - "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.3.0.tgz", - "integrity": "sha512-EYdhhJ302SC4Lmkx8GRsp0sjUhEN4WyFXPOk0kGu9OXZSRMmcBlRgTvHcq8eKJE1bXWBsOi1T83B+BSSVZSmwQ==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", + "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", "license": "MIT", "peerDependencies": { - "embla-carousel": "8.3.0" + "embla-carousel": "8.6.0" } }, "node_modules/emoji-regex": { @@ -4273,51 +3867,6 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -4381,32 +3930,33 @@ } }, "node_modules/eslint": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", - "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", + "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.7.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.13.0", - "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", + "@eslint/core": "^0.15.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.32.0", + "@eslint/plugin-kit": "^0.3.4", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4420,8 +3970,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -4442,9 +3991,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "5.1.0-rc-fb9a90fa48-20240614", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-fb9a90fa48-20240614.tgz", - "integrity": "sha512-xsiRwaDNF5wWNC4ZHLut+x/YcAxksUd9Rizt7LaEn3bV8VyYRpXnRJQlLOfYaVy9esk4DFP4zPPnoNVjq5Gc0w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", "dev": true, "license": "MIT", "engines": { @@ -4455,19 +4004,19 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.14.tgz", - "integrity": "sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA==", + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", "dev": true, "license": "MIT", "peerDependencies": { - "eslint": ">=7" + "eslint": ">=8.40" } }, "node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4482,9 +4031,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -4495,15 +4044,15 @@ } }, "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4582,9 +4131,9 @@ "license": "MIT" }, "node_modules/fast-equals": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", - "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", + "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -4704,26 +4253,6 @@ "dev": true, "license": "ISC" }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/foreground-child": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", @@ -4740,22 +4269,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -4770,33 +4283,6 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/framer-motion": { - "version": "12.23.22", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.22.tgz", - "integrity": "sha512-ZgGvdxXCw55ZYvhoZChTlG6pUuehecgvEAJz0BHoC5pQKW1EC5xf1Mul1ej5+ai+pVY0pylyFfdl45qnM1/GsA==", - "license": "MIT", - "dependencies": { - "motion-dom": "^12.23.21", - "motion-utils": "^12.23.6", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4820,30 +4306,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "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", @@ -4853,19 +4315,6 @@ "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==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -4899,9 +4348,9 @@ } }, "node_modules/glob/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==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -4923,9 +4372,9 @@ } }, "node_modules/globals": { - "version": "15.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", - "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "license": "MIT", "engines": { @@ -4935,18 +4384,6 @@ "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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -4964,33 +4401,6 @@ "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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", @@ -5014,9 +4424,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5041,13 +4451,13 @@ } }, "node_modules/input-otp": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.2.4.tgz", - "integrity": "sha512-md6rhmD+zmMnUh5crQNSQxq3keBRYvE3odbr4Qb9g2NWzQv9azi+t1a3X4TBTbh98fsGHgEEJlzbe1q860uGCA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", + "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", "license": "MIT", "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "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": { @@ -5059,15 +4469,6 @@ "node": ">=12" } }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -5300,9 +4701,9 @@ } }, "node_modules/lovable-tagger": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/lovable-tagger/-/lovable-tagger-1.1.7.tgz", - "integrity": "sha512-b1wwYbuxWGx+DuqviQGQXrgLAraK1RVbqTg6G8LYRID8FJTg4TuAeO0TJ7i6UXOF8gEzbgjhRbGZ+XAkWH2T8A==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/lovable-tagger/-/lovable-tagger-1.1.10.tgz", + "integrity": "sha512-LbYaxi6vgrqg7Sq93/cRbIM78EP+X+GUU7spx804yqB2bxfiOej8UvcZHeE4WqMjAFI2dHGhXpy8r6SnvmrzGg==", "dev": true, "license": "MIT", "dependencies": { @@ -5314,7 +4715,7 @@ "tailwindcss": "^3.4.17" }, "peerDependencies": { - "vite": "^5.0.0" + "vite": ">=5.0.0 <8.0.0" } }, "node_modules/lovable-tagger/node_modules/@esbuild/aix-ppc64": { @@ -5773,15 +5174,6 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5804,27 +5196,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5847,21 +5218,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/motion-dom": { - "version": "12.23.21", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.21.tgz", - "integrity": "sha512-5xDXx/AbhrfgsQmSE7YESMn4Dpo6x5/DTZ4Iyy4xqDvVHWvFVoV+V2Ri2S/ksx+D40wrZ7gPYiMWshkdoqNgNQ==", - "license": "MIT", - "dependencies": { - "motion-utils": "^12.23.6" - } - }, - "node_modules/motion-utils": { - "version": "12.23.6", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz", - "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==", - "license": "MIT" - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5881,9 +5237,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", @@ -5916,9 +5272,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "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, "license": "MIT" }, @@ -6106,9 +5462,9 @@ } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "funding": [ { "type": "opencollective", @@ -6125,8 +5481,8 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -6275,12 +5631,6 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -6351,9 +5701,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.53.1", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.1.tgz", - "integrity": "sha512-6aiQeBda4zjcuaugWvim9WsGqisoUk+etmFEsSUMm451/Ic8L/UAb7sRtMj3V+Hdzm6mMjU1VhiSzYUZeBm0Vg==", + "version": "7.61.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.61.1.tgz", + "integrity": "sha512-2vbXUFDYgqEgM2RcXcAT2PwDW/80QARi+PKmHy5q2KhuKvOlG8iIYgf7eIlIANR5trW9fJbP4r5aub3a4egsew==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -6366,15 +5716,6 @@ "react": "^16.8.0 || ^17 || ^18 || ^19" } }, - "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", - "license": "MIT", - "peerDependencies": { - "react": "*" - } - }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -6382,23 +5723,23 @@ "license": "MIT" }, "node_modules/react-remove-scroll": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", - "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", "license": "MIT", "dependencies": { - "react-remove-scroll-bar": "^2.3.6", - "react-style-singleton": "^2.2.1", + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" }, "engines": { "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -6407,20 +5748,20 @@ } }, "node_modules/react-remove-scroll-bar": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", - "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", "license": "MIT", "dependencies": { - "react-style-singleton": "^2.2.1", + "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "engines": { "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -6429,9 +5770,9 @@ } }, "node_modules/react-resizable-panels": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.5.tgz", - "integrity": "sha512-JMSe18rYupmx+dzYcdfWYZ93ZdxqQmLum3xWDVSUMI0UVwl9bB9gUaFmPbxYoO4G+m5sqgdXQCYQxnOysytfnw==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.9.tgz", + "integrity": "sha512-z77+X08YDIrgAes4jl8xhnUu1LNIRp4+E7cv4xHmLOxxUPO/ML7PSrE813b90vj7xvQ1lcf7g2uA9GeMZonjhQ==", "license": "MIT", "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", @@ -6439,12 +5780,12 @@ } }, "node_modules/react-router": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", - "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz", + "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.20.0" + "@remix-run/router": "1.23.0" }, "engines": { "node": ">=14.0.0" @@ -6454,13 +5795,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", - "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz", + "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==", "license": "MIT", "dependencies": { - "@remix-run/router": "1.20.0", - "react-router": "6.27.0" + "@remix-run/router": "1.23.0", + "react-router": "6.30.1" }, "engines": { "node": ">=14.0.0" @@ -6471,9 +5812,9 @@ } }, "node_modules/react-smooth": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", - "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", "license": "MIT", "dependencies": { "fast-equals": "^5.0.1", @@ -6481,26 +5822,25 @@ "react-transition-group": "^4.4.5" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "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.1", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", - "invariant": "^2.2.4", "tslib": "^2.0.0" }, "engines": { "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -6546,16 +5886,16 @@ } }, "node_modules/recharts": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.13.0.tgz", - "integrity": "sha512-sbfxjWQ+oLWSZEWmvbq/DFVdeRLqqA6d0CDjKx2PkxVVdoXo16jvENCE+u/x7HxOO+/fwx//nYRwb8p8X6s/lQ==", + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", + "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", "license": "MIT", "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", "lodash": "^4.17.21", "react-is": "^18.3.1", - "react-smooth": "^4.0.0", + "react-smooth": "^4.0.4", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" @@ -6564,8 +5904,8 @@ "node": ">=14" }, "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + "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": { @@ -6577,12 +5917,6 @@ "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==", - "license": "MIT" - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -6689,9 +6023,9 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, "license": "ISC", "bin": { @@ -6735,13 +6069,13 @@ } }, "node_modules/sonner": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.5.0.tgz", - "integrity": "sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz", + "integrity": "sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==", "license": "MIT", "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "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": { @@ -6910,9 +6244,9 @@ } }, "node_modules/tailwind-merge": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz", - "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", + "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", "license": "MIT", "funding": { "type": "github", @@ -6965,13 +6299,6 @@ "tailwindcss": ">=3.0.0 || insiders" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -7012,16 +6339,16 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-interface-checker": { @@ -7050,9 +6377,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -7064,15 +6391,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.11.0.tgz", - "integrity": "sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA==", + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.38.0.tgz", + "integrity": "sha512-FsZlrYK6bPDGoLeZRuvx2v6qrM03I0U0SnfCLPs/XCCPCFD80xU9Pg09H/K+XFa68uJuZo7l/Xhs+eDRg2l3hg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.11.0", - "@typescript-eslint/parser": "8.11.0", - "@typescript-eslint/utils": "8.11.0" + "@typescript-eslint/eslint-plugin": "8.38.0", + "@typescript-eslint/parser": "8.38.0", + "@typescript-eslint/typescript-estree": "8.38.0", + "@typescript-eslint/utils": "8.38.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7081,23 +6409,22 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -7116,7 +6443,7 @@ "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -7136,9 +6463,9 @@ } }, "node_modules/use-callback-ref": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", - "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -7147,8 +6474,8 @@ "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -7157,9 +6484,9 @@ } }, "node_modules/use-sidecar": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", @@ -7169,8 +6496,8 @@ "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -7178,6 +6505,15 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -7220,9 +6556,9 @@ } }, "node_modules/vite": { - "version": "5.4.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", - "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "version": "5.4.19", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", "dev": true, "license": "MIT", "dependencies": { @@ -7418,9 +6754,9 @@ } }, "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/Front-End/package.json b/Front-End/git-genius-commit/package.json similarity index 73% rename from Front-End/package.json rename to Front-End/git-genius-commit/package.json index 146e3646f..cfc835638 100644 --- a/Front-End/package.json +++ b/Front-End/git-genius-commit/package.json @@ -3,10 +3,17 @@ "private": true, "version": "0.0.0", "type": "module", + "main": "electron/main.cjs", "scripts": { - "dev": "vite", - "build": "vite build", - "build:dev": "vite build --mode development", + "dev:web": "vite", + "dev:electron": "cross-env NODE_ENV=development electron .", + "dev": "concurrently -k -n web,electron -c cyan,magenta \"npm run dev:web\" \"wait-on http://localhost:4343 && npm run dev:electron\"", + + "build:web": "vite build", + "build:web:dev": "vite build --mode development", + "build:electron": "electron-builder --publish never", + "dist": "npm run build:web && npm run build:electron", + "lint": "eslint .", "preview": "vite preview" }, @@ -73,6 +80,10 @@ "@types/react-dom": "^18.3.0", "@vitejs/plugin-react-swc": "^3.5.0", "autoprefixer": "^10.4.20", + "concurrently": "^9.2.1", + "cross-env": "^10.1.0", + "electron": "^38.2.0", + "electron-builder": "^26.0.12", "eslint": "^9.9.0", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.9", @@ -82,6 +93,27 @@ "tailwindcss": "^3.4.11", "typescript": "^5.5.3", "typescript-eslint": "^8.0.1", - "vite": "^5.4.1" + "vite": "^5.4.1", + "wait-on": "^9.0.1" + }, + "build": { + "appId": "com.seuapp.electron", + "productName": "ViteReactElectron", + "files": [ + "dist/**/*", + "electron/**/*" + ], + "directories": { + "buildResources": "build" + }, + "win": { + "target": "nsis" + }, + "mac": { + "target": "dmg" + }, + "linux": { + "target": "AppImage" + } } } diff --git a/Front-End/git-genius-commit/postcss.config.js b/Front-End/git-genius-commit/postcss.config.js new file mode 100644 index 000000000..2aa7205d4 --- /dev/null +++ b/Front-End/git-genius-commit/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/Front-End/public/favicon.ico b/Front-End/git-genius-commit/public/favicon.ico similarity index 100% rename from Front-End/public/favicon.ico rename to Front-End/git-genius-commit/public/favicon.ico diff --git a/Front-End/public/placeholder.svg b/Front-End/git-genius-commit/public/placeholder.svg similarity index 100% rename from Front-End/public/placeholder.svg rename to Front-End/git-genius-commit/public/placeholder.svg diff --git a/Front-End/public/robots.txt b/Front-End/git-genius-commit/public/robots.txt similarity index 100% rename from Front-End/public/robots.txt rename to Front-End/git-genius-commit/public/robots.txt diff --git a/Front-End/src/App.css b/Front-End/git-genius-commit/src/App.css similarity index 100% rename from Front-End/src/App.css rename to Front-End/git-genius-commit/src/App.css diff --git a/Front-End/git-genius-commit/src/App.tsx b/Front-End/git-genius-commit/src/App.tsx new file mode 100644 index 000000000..18daf2e90 --- /dev/null +++ b/Front-End/git-genius-commit/src/App.tsx @@ -0,0 +1,27 @@ +import { Toaster } from "@/components/ui/toaster"; +import { Toaster as Sonner } from "@/components/ui/sonner"; +import { TooltipProvider } from "@/components/ui/tooltip"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { BrowserRouter, Routes, Route } from "react-router-dom"; +import Index from "./pages/Index"; +import NotFound from "./pages/NotFound"; + +const queryClient = new QueryClient(); + +const App = () => ( + + + + + + + } /> + {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} + } /> + + + + +); + +export default App; diff --git a/Front-End/git-genius-commit/src/components/CommitPreview.tsx b/Front-End/git-genius-commit/src/components/CommitPreview.tsx new file mode 100644 index 000000000..6ba15026b --- /dev/null +++ b/Front-End/git-genius-commit/src/components/CommitPreview.tsx @@ -0,0 +1,87 @@ +import { Card } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { GitCommit, Sparkles, Copy, Check } from "lucide-react"; +import { useState } from "react"; +import { toast } from "sonner"; + +interface CommitPreviewProps { + message: string; + status: 'SUCCESS' | 'NO_CHANGES' | 'ERROR'; + onCommit: () => void; + isLoading: boolean; +} + +export const CommitPreview = ({ message, status, onCommit, isLoading }: CommitPreviewProps) => { + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + await navigator.clipboard.writeText(message); + setCopied(true); + toast.success("Message copied to clipboard"); + setTimeout(() => setCopied(false), 2000); + }; + + const getStatusColor = () => { + switch (status) { + case 'SUCCESS': + return 'text-success'; + case 'NO_CHANGES': + return 'text-warning'; + case 'ERROR': + return 'text-destructive'; + } + }; + + return ( + +
+
+
+ +
+
+

AI-Generated Commit

+

+ Status: {status} +

+
+
+ +
+ +
+ +
+ {message ? ( +
+                {message}
+              
+ ) : ( +

+ No commit message generated yet +

+ )} +
+
+ + +
+
+ ); +}; diff --git a/Front-End/git-genius-commit/src/components/ConfigPanel.tsx b/Front-End/git-genius-commit/src/components/ConfigPanel.tsx new file mode 100644 index 000000000..d113c594d --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ConfigPanel.tsx @@ -0,0 +1,204 @@ +import { useState, useEffect } from "react"; +import { Card } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Switch } from "@/components/ui/switch"; +import { Button } from "@/components/ui/button"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Settings, Save } from "lucide-react"; +import { GitConfig } from "@/types/git"; + +export const ConfigPanel = () => { + const [localConfig, setLocalConfig] = useState(null); + const [loading, setLoading] = useState(true); + const [saving, setSaving] = useState(false); + + const backend = import.meta.env.VITE_BACK_END || '' + + const accessToken = "t7gwqwkNVXRFkto97ISidO96y68CSyRMGgwcwy_Qgr0" + const email = "freitasalexandre810@gmail.com" + const password = "teste" + + // Carrega config do backend + useEffect(() => { + const fetchSettings = async () => { + try { + const res = await fetch(`${backend}/api/settings?email=${email}&password=${password}`, { + + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'X-API-TOKEN': `${accessToken}` + }, + }); + if (!res.ok) throw new Error("Erro ao carregar configurações"); + const data = await res.json(); + console.log("Config recebida:", data); + + setLocalConfig({ + api_key: data.openaiApiKey || "", + api_endpoint: data.webhookUrl || "", + ai_model: "gpt-5-mini", // default se backend não retorna + lines_threshold: 50, + files_threshold: 5, + time_threshold: 60, + auto_push: data.autoProcessPRs || false, + require_tests: data.enableLogging || false, + }); + } catch (err) { + console.error(err); + } finally { + setLoading(false); + } + }; + + fetchSettings(); + }, []); + + const handleSave = async () => { + if (!localConfig) return; + setSaving(true); + try { + const res = await fetch(`${backend}/api/settings`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + "X-API-TOKEN": accessToken, + }, + body: JSON.stringify({ + githubToken: "", // se precisar mandar, pode mapear + githubSecret: "", + repositoryName: "", + openaiApiKey: localConfig.api_key, + webhookUrl: localConfig.api_endpoint, + autoProcessPRs: localConfig.auto_push, + enableLogging: localConfig.require_tests, + logLevel: "INFO", + }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Erro ao salvar configurações"); + console.log("Config salva:", data); + } catch (err) { + console.error(err); + } finally { + setSaving(false); + } + }; + + if (!localConfig) { + return
Carregando configurações...
; + } + + return ( + +
+
+ +
+

Configuration

+
+ +
+
+ + setLocalConfig({ ...localConfig, api_key: e.target.value })} + className="font-mono text-sm bg-input border-border" + /> +
+ +
+ + setLocalConfig({ ...localConfig, api_endpoint: e.target.value })} + className="font-mono text-sm bg-input border-border" + /> +
+ +
+ + +
+ + {/* Thresholds */} +
+
+ + setLocalConfig({ ...localConfig, lines_threshold: parseInt(e.target.value) })} + /> +
+
+ + setLocalConfig({ ...localConfig, files_threshold: parseInt(e.target.value) })} + /> +
+
+ + setLocalConfig({ ...localConfig, time_threshold: parseInt(e.target.value) })} + /> +
+
+ + {/* Switches */} +
+ + setLocalConfig({ ...localConfig, auto_push: checked })} + /> +
+ +
+ + setLocalConfig({ ...localConfig, require_tests: checked })} + /> +
+ + +
+
+ ); +}; diff --git a/Front-End/git-genius-commit/src/components/DiffViewer.tsx b/Front-End/git-genius-commit/src/components/DiffViewer.tsx new file mode 100644 index 000000000..8eb5e6dad --- /dev/null +++ b/Front-End/git-genius-commit/src/components/DiffViewer.tsx @@ -0,0 +1,83 @@ +import { Card } from "@/components/ui/card"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { FileCode, Plus, Minus } from "lucide-react"; + +interface DiffViewerProps { + diff: string; + modifiedFiles: string[]; + linesChanged: number; +} + +export const DiffViewer = ({ diff, modifiedFiles, linesChanged }: DiffViewerProps) => { + const formatDiffLine = (line: string) => { + if (line.startsWith('+')) { + return ( +
+ + {line.substring(1)} +
+ ); + } + if (line.startsWith('-')) { + return ( +
+ + {line.substring(1)} +
+ ); + } + if (line.startsWith('@@')) { + return ( +
+ {line} +
+ ); + } + return ( +
+ {line} +
+ ); + }; + + return ( + +
+
+
+ +
+
+

Changes

+

+ {modifiedFiles.length} files · {linesChanged} lines changed +

+
+
+
+ +
+
+ {modifiedFiles.map((file, idx) => ( +
+ {file} +
+ ))} +
+ + +
+ {diff.split('\n').map((line, idx) => ( +
+ {formatDiffLine(line)} +
+ ))} +
+
+
+
+ ); +}; diff --git a/Front-End/git-genius-commit/src/components/RepositorySelector.tsx b/Front-End/git-genius-commit/src/components/RepositorySelector.tsx new file mode 100644 index 000000000..c4eba5cc4 --- /dev/null +++ b/Front-End/git-genius-commit/src/components/RepositorySelector.tsx @@ -0,0 +1,50 @@ +// src\components\RepositorySelector.tsx + +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { FolderGit2, Check } from "lucide-react"; + +interface RepositorySelectorProps { + onSelect: (path: string) => void; + currentPath?: string; +} + +export const RepositorySelector = ({ onSelect, currentPath }: RepositorySelectorProps) => { + const [path, setPath] = useState(currentPath || ""); + + const handleSelect = async () => { + const folderPath = await window.electronAPI.selectFolder(); + if (folderPath) { + setPath(folderPath); + onSelect(folderPath); + } + }; + + return ( + +
+
+ +
+

Repository Path

+
+ +
+ + + {path && ( +
+ Ativo: {path} +
+ )} +
+
+ ); +}; diff --git a/Front-End/git-genius-commit/src/components/StatusMonitor.tsx b/Front-End/git-genius-commit/src/components/StatusMonitor.tsx new file mode 100644 index 000000000..7aea345ad --- /dev/null +++ b/Front-End/git-genius-commit/src/components/StatusMonitor.tsx @@ -0,0 +1,76 @@ +import { Card } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { Activity, Play, Pause, RefreshCw } from "lucide-react"; +import { GitStatus } from "@/types/git"; + +interface StatusMonitorProps { + status: GitStatus; + onToggleMonitoring: () => void; + onRefresh: () => void; +} + +export const StatusMonitor = ({ status, onToggleMonitoring, onRefresh }: StatusMonitorProps) => { + return ( + +
+
+
+ +
+

Status Monitor

+
+ + {status.is_monitoring ? 'Active' : 'Paused'} + +
+ +
+
+
Modified Files
+
{status.modified_files.length}
+
+
+
Lines Changed
+
{status.lines_changed}
+
+
+ +
+ Last check: {status.last_check.toLocaleTimeString()} +
+ +
+ + +
+
+ ); +}; diff --git a/Front-End/git-genius-commit/src/components/ui/accordion.tsx b/Front-End/git-genius-commit/src/components/ui/accordion.tsx new file mode 100644 index 000000000..1e7878ced --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ui/accordion.tsx @@ -0,0 +1,52 @@ +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDown } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const Accordion = AccordionPrimitive.Root; + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = "AccordionItem"; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className, + )} + {...props} + > + {children} + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)); + +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/Front-End/git-genius-commit/src/components/ui/alert-dialog.tsx b/Front-End/git-genius-commit/src/components/ui/alert-dialog.tsx new file mode 100644 index 000000000..6dfbfb49f --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ui/alert-dialog.tsx @@ -0,0 +1,104 @@ +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"; + +const AlertDialog = AlertDialogPrimitive.Root; + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger; + +const AlertDialogPortal = AlertDialogPrimitive.Portal; + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName; + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)); +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName; + +const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( +
+); +AlertDialogHeader.displayName = "AlertDialogHeader"; + +const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( +
+); +AlertDialogFooter.displayName = "AlertDialogFooter"; + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName; + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName; + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName; + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName; + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +}; diff --git a/Front-End/git-genius-commit/src/components/ui/alert.tsx b/Front-End/git-genius-commit/src/components/ui/alert.tsx new file mode 100644 index 000000000..2efc3c8ba --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ui/alert.tsx @@ -0,0 +1,43 @@ +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 p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)); +Alert.displayName = "Alert"; + +const AlertTitle = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ), +); +AlertTitle.displayName = "AlertTitle"; + +const AlertDescription = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ), +); +AlertDescription.displayName = "AlertDescription"; + +export { Alert, AlertTitle, AlertDescription }; diff --git a/Front-End/git-genius-commit/src/components/ui/aspect-ratio.tsx b/Front-End/git-genius-commit/src/components/ui/aspect-ratio.tsx new file mode 100644 index 000000000..c9e6f4bf9 --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ui/aspect-ratio.tsx @@ -0,0 +1,5 @@ +import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"; + +const AspectRatio = AspectRatioPrimitive.Root; + +export { AspectRatio }; diff --git a/Front-End/git-genius-commit/src/components/ui/avatar.tsx b/Front-End/git-genius-commit/src/components/ui/avatar.tsx new file mode 100644 index 000000000..68d21bbf6 --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ui/avatar.tsx @@ -0,0 +1,38 @@ +import * as React from "react"; +import * as AvatarPrimitive from "@radix-ui/react-avatar"; + +import { cn } from "@/lib/utils"; + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Avatar.displayName = AvatarPrimitive.Root.displayName; + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarImage.displayName = AvatarPrimitive.Image.displayName; + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; + +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/Front-End/git-genius-commit/src/components/ui/badge.tsx b/Front-End/git-genius-commit/src/components/ui/badge.tsx new file mode 100644 index 000000000..0853c441d --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ui/badge.tsx @@ -0,0 +1,29 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const badgeVariants = cva( + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +export interface BadgeProps extends React.HTMLAttributes, VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return
; +} + +export { Badge, badgeVariants }; diff --git a/Front-End/git-genius-commit/src/components/ui/breadcrumb.tsx b/Front-End/git-genius-commit/src/components/ui/breadcrumb.tsx new file mode 100644 index 000000000..ca91ff532 --- /dev/null +++ b/Front-End/git-genius-commit/src/components/ui/breadcrumb.tsx @@ -0,0 +1,90 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode; + } +>(({ ...props }, ref) =>