diff --git a/app/components/ui/dark-mode-coverage.test.tsx b/app/components/ui/dark-mode-coverage.test.tsx
new file mode 100644
index 0000000..a481f4b
--- /dev/null
+++ b/app/components/ui/dark-mode-coverage.test.tsx
@@ -0,0 +1,790 @@
+import * as React from 'react'
+import { render } from '@testing-library/react'
+import { buildThemeTest } from '@/lib/test-utils'
+import { useIsMobile } from '@/hooks/use-mobile'
+
+// ---------------------------------------------------------------------------
+// Mocks
+// ---------------------------------------------------------------------------
+
+const mockTheme = { current: 'light' as string }
+
+jest.mock('next-themes', () => ({
+ ThemeProvider: ({ children }: { children: React.ReactNode }) => <>{children}>,
+ useTheme: () => ({ theme: mockTheme.current, setTheme: jest.fn() }),
+}))
+
+const mockEmblaApi = {
+ scrollPrev: jest.fn(),
+ scrollNext: jest.fn(),
+ canScrollPrev: jest.fn(() => false),
+ canScrollNext: jest.fn(() => false),
+ on: jest.fn(),
+ off: jest.fn(),
+}
+
+jest.mock('embla-carousel-react', () => ({
+ __esModule: true,
+ default: () => [jest.fn(), mockEmblaApi],
+}))
+
+beforeEach(() => {
+ mockTheme.current = 'light'
+ ;(useIsMobile as jest.Mock).mockReturnValue(false)
+})
+
+// ---------------------------------------------------------------------------
+// Simple / Atomic Components
+// ---------------------------------------------------------------------------
+
+buildThemeTest('Badge', () => Default)
+buildThemeTest('Badge (secondary)', () => Secondary)
+buildThemeTest('Badge (destructive)', () => Destructive)
+buildThemeTest('Badge (outline)', () => Outline)
+buildThemeTest('Button', () => )
+buildThemeTest('Button (destructive)', () => )
+buildThemeTest('Button (outline)', () => )
+buildThemeTest('Button (secondary)', () => )
+buildThemeTest('Button (ghost)', () => )
+buildThemeTest('Button (link)', () => )
+buildThemeTest('Input', () => )
+buildThemeTest('Textarea', () => )
+buildThemeTest('Label', () => )
+buildThemeTest('Kbd', () => Ctrl+K)
+buildThemeTest('KbdGroup', () => ⌘K)
+buildThemeTest('Skeleton', () => )
+buildThemeTest('Spinner', () => )
+buildThemeTest('Separator', () => )
+buildThemeTest('Toggle', () => Toggle)
+buildThemeTest('Checkbox', () => )
+buildThemeTest('Switch', () => )
+buildThemeTest('Slider', () => )
+buildThemeTest('Progress', () => )
+buildThemeTest('Calendar', () => )
+buildThemeTest('AspectRatio', () => (
+
+ 16:9
+
+))
+buildThemeTest('ScrollArea', () => (
+
+ Scroll content
+
+))
+
+// ---------------------------------------------------------------------------
+// Layout Components
+// ---------------------------------------------------------------------------
+
+buildThemeTest('Card', () => (
+
+
+ Card Title
+ Card description text
+
+ Main content
+ Footer
+
+))
+
+buildThemeTest('Table', () => (
+
+ List of items
+
+
+ Name
+ Value
+
+
+
+
+ Alpha
+ 100
+
+
+
+
+ Total
+ 100
+
+
+
+))
+
+buildThemeTest('Item', () => (
+
+ -
+
+ Item Title
+ Description goes here
+
+
+
+))
+
+buildThemeTest('Empty', () => (
+
+
+
+ No data found
+ Try adjusting your filters
+
+
+
+))
+
+buildThemeTest('Field', () => (
+
+ Username
+
+
+
+ Your unique display name
+
+))
+
+// ---------------------------------------------------------------------------
+// Interactive / Compound Components
+// ---------------------------------------------------------------------------
+
+buildThemeTest('Accordion', () => (
+
+
+ Section One
+ Content for section one.
+
+
+ Section Two
+ Content for section two.
+
+
+))
+
+buildThemeTest('Alert', () => (
+
+ Attention
+ This is an alert message.
+
+))
+
+buildThemeTest('Alert (destructive)', () => (
+
+ Error
+ Something went wrong.
+
+))
+
+buildThemeTest('AlertDialog', () => (
+
+
+
+ Confirm
+ Are you sure?
+
+
+ Cancel
+ Continue
+
+
+
+))
+
+buildThemeTest('Avatar', () => (
+
+ JD
+
+))
+
+buildThemeTest('Breadcrumb', () => (
+
+
+
+ Home
+
+
+
+ Section
+
+
+
+ Current
+
+
+
+))
+
+buildThemeTest('ButtonGroup', () => (
+
+
+
+
+
+))
+
+buildThemeTest('Collapsible', () => (
+
+ Toggle
+ Collapsible content
+
+))
+
+buildThemeTest('ConfirmDialog', () => (
+ {}}
+ open={false}
+ />
+))
+
+buildThemeTest('Dialog', () => (
+
+))
+
+buildThemeTest('Drawer', () => (
+
+
+
+ Drawer Title
+ Drawer description.
+
+
+
+
+))
+
+buildThemeTest('DropdownMenu', () => (
+
+
+ Profile
+ Settings
+
+ Logout
+
+
+))
+
+buildThemeTest('HoverCard', () => (
+
+ Hover card content
+
+))
+
+buildThemeTest('Menubar', () => (
+
+
+ File
+
+ New
+ Open
+
+ Exit
+
+
+
+))
+
+buildThemeTest('NavigationMenu', () => (
+
+
+
+ Item One
+
+ Link One
+
+
+
+
+))
+
+buildThemeTest('Pagination', () => (
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+
+
+
+
+))
+
+buildThemeTest('Popover', () => (
+
+ Popover content
+
+))
+
+buildThemeTest('RadioGroup', () => (
+
+
+
+
+))
+
+buildThemeTest('Select', () => (
+
+))
+
+buildThemeTest('Sheet', () => (
+
+
+
+ Sheet Title
+ Sheet description.
+
+
+
+
+))
+
+buildThemeTest('Tabs', () => (
+
+
+ Tab One
+ Tab Two
+
+ Content one
+ Content two
+
+))
+
+buildThemeTest('ToggleGroup', () => (
+
+ A
+ B
+
+))
+
+buildThemeTest('Tooltip', () => (
+
+ Hover me
+ Tooltip text
+
+))
+
+buildThemeTest('Resizable', () => (
+
+ Left panel
+
+ Right panel
+
+))
+
+buildThemeTest('InputOTP', () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+))
+
+buildThemeTest('InputGroup', () => (
+
+
+ $
+
+
+
+ .00
+
+
+))
+
+buildThemeTest('ContextMenu', () => (
+
+
+ Right-click area
+
+
+ Action
+
+ Delete
+
+
+))
+
+buildThemeTest('Carousel', () => (
+
+
+ Slide 1
+ Slide 2
+ Slide 3
+
+
+))
+
+// ---------------------------------------------------------------------------
+// Complex Custom Components
+// ---------------------------------------------------------------------------
+
+buildThemeTest('Command (with Dialog)', () => (
+
+
+
+ No results.
+
+ Item A
+ Item B
+
+
+
+))
+
+buildThemeTest('Sidebar', () => (
+
+
+
+
+
+
+
+ Navigation
+
+
+
+ Home
+
+
+ Settings
+
+
+
+
+
+
+
+
+
+
+ Page content
+
+
+))
+
+buildThemeTest('Sidebar (collapsible icon)', () => (
+
+
+
+
+
+ Menu
+
+
+
+ Home
+
+
+
+
+
+
+
+))
+
+buildThemeTest('Toaster (sonner)', () => (
+
+))
+
+buildThemeTest('ToastProvider', () => (
+
+
+
+ Notification
+ You have a new message.
+
+ View
+
+
+))
+
+buildThemeTest('Toaster (custom)', () => (
+
+))
+
+// ---------------------------------------------------------------------------
+// Form Components (require react-hook-form context)
+// ---------------------------------------------------------------------------
+
+import { useForm } from 'react-hook-form'
+
+function FormTestWrapper() {
+ const form = useForm()
+ return (
+
+ )
+}
+
+buildThemeTest('Form', () => )
+
+// ---------------------------------------------------------------------------
+// Chart Component (requires recharts)
+// ---------------------------------------------------------------------------
+
+import * as RechartsPrimitive from 'recharts'
+
+buildThemeTest('Chart', () => (
+
+
+
+
+
+))
+
+// ChartTooltipContent and ChartLegendContent are internal components that
+// must be used within a ChartContainer + recharts chart context.
+// They are implicitly tested by the main Chart test above.
+
+// ---------------------------------------------------------------------------
+// Imports (kept at bottom to avoid hoisting issues)
+// ---------------------------------------------------------------------------
+
+import { Badge } from './badge'
+import { Button } from './button'
+import { Input } from './input'
+import { Textarea } from './textarea'
+import { Label } from './label'
+import { Kbd, KbdGroup } from './kbd'
+import { Skeleton } from './skeleton'
+import { Spinner } from './spinner'
+import { Separator } from './separator'
+import { Toggle } from './toggle'
+import { Checkbox } from './checkbox'
+import { Switch } from './switch'
+import { Slider } from './slider'
+import { Progress } from './progress'
+import { Calendar } from './calendar'
+import { AspectRatio } from './aspect-ratio'
+import { ScrollArea } from './scroll-area'
+import {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardDescription,
+ CardContent,
+} from './card'
+import {
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
+} from './table'
+import {
+ ItemGroup,
+ Item,
+ ItemContent,
+ ItemTitle,
+ ItemDescription,
+} from './item'
+import {
+ Empty,
+ EmptyHeader,
+ EmptyTitle,
+ EmptyDescription,
+ EmptyContent,
+ EmptyMedia,
+} from './empty'
+import { Field, FieldLabel, FieldContent, FieldDescription } from './field'
+import {
+ Accordion,
+ AccordionItem,
+ AccordionTrigger,
+ AccordionContent,
+} from './accordion'
+import { Alert, AlertTitle, AlertDescription } from './alert'
+import {
+ AlertDialog,
+ AlertDialogContent,
+ AlertDialogHeader,
+ AlertDialogFooter,
+ AlertDialogTitle,
+ AlertDialogDescription,
+ AlertDialogAction,
+ AlertDialogCancel,
+} from './alert-dialog'
+import { Avatar, AvatarFallback } from './avatar'
+import {
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+} from './breadcrumb'
+import { ButtonGroup } from './button-group'
+import { Collapsible, CollapsibleTrigger, CollapsibleContent } from './collapsible'
+import { ConfirmDialog } from './confirm-dialog'
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogFooter,
+ DialogTitle,
+ DialogDescription,
+} from './dialog'
+import {
+ Drawer,
+ DrawerContent,
+ DrawerHeader,
+ DrawerFooter,
+ DrawerTitle,
+ DrawerDescription,
+} from './drawer'
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+} from './dropdown-menu'
+import { HoverCard, HoverCardContent } from './hover-card'
+import {
+ Menubar,
+ MenubarMenu,
+ MenubarTrigger,
+ MenubarContent,
+ MenubarItem,
+ MenubarSeparator,
+} from './menubar'
+import {
+ NavigationMenu,
+ NavigationMenuList,
+ NavigationMenuItem,
+ NavigationMenuTrigger,
+ NavigationMenuContent,
+ NavigationMenuLink,
+} from './navigation-menu'
+import {
+ Pagination,
+ PaginationContent,
+ PaginationItem,
+ PaginationLink,
+ PaginationPrevious,
+ PaginationNext,
+} from './pagination'
+import { Popover, PopoverContent } from './popover'
+import { RadioGroup, RadioGroupItem } from './radio-group'
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectLabel,
+ SelectSeparator,
+} from './select'
+import {
+ Sheet,
+ SheetContent,
+ SheetHeader,
+ SheetFooter,
+ SheetTitle,
+ SheetDescription,
+} from './sheet'
+import { Tabs, TabsList, TabsTrigger, TabsContent } from './tabs'
+import { ToggleGroup, ToggleGroupItem } from './toggle-group'
+import { Tooltip, TooltipTrigger, TooltipContent } from './tooltip'
+import {
+ ResizablePanelGroup,
+ ResizablePanel,
+ ResizableHandle,
+} from './resizable'
+import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from './input-otp'
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupText,
+ InputGroupInput,
+ InputGroupButton,
+} from './input-group'
+import {
+ ContextMenu,
+ ContextMenuTrigger,
+ ContextMenuContent,
+ ContextMenuItem,
+ ContextMenuSeparator,
+} from './context-menu'
+import { Carousel, CarouselContent, CarouselItem } from './carousel'
+import { CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from './command'
+import {
+ SidebarProvider,
+ Sidebar,
+ SidebarContent,
+ SidebarHeader,
+ SidebarFooter,
+ SidebarGroup,
+ SidebarGroupLabel,
+ SidebarGroupContent,
+ SidebarMenu,
+ SidebarMenuItem,
+ SidebarMenuButton,
+ SidebarInput,
+ SidebarInset,
+ SidebarTrigger,
+ SidebarRail,
+} from './sidebar'
+import { Toaster } from './sonner'
+import {
+ ToastProvider,
+ ToastViewport,
+ Toast,
+ ToastTitle,
+ ToastDescription,
+ ToastClose,
+ ToastAction,
+} from './toast'
+import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage } from './form'
+import { ChartContainer } from './chart'
diff --git a/app/jest.setup.ts b/app/jest.setup.ts
index 7a7c7dd..ccee83f 100644
--- a/app/jest.setup.ts
+++ b/app/jest.setup.ts
@@ -1,5 +1,9 @@
import "@testing-library/jest-dom"
+jest.mock("@/hooks/use-mobile", () => ({
+ useIsMobile: jest.fn(() => false),
+}))
+
class MockResizeObserver {
observe = jest.fn()
unobserve = jest.fn()
diff --git a/app/lib/test-utils.tsx b/app/lib/test-utils.tsx
new file mode 100644
index 0000000..a59ccf0
--- /dev/null
+++ b/app/lib/test-utils.tsx
@@ -0,0 +1,41 @@
+import * as React from 'react'
+import { render, type RenderOptions } from '@testing-library/react'
+
+export type ThemeMode = 'light' | 'dark'
+
+export function setDocumentTheme(mode: ThemeMode) {
+ if (mode === 'dark') {
+ document.documentElement.classList.add('dark')
+ } else {
+ document.documentElement.classList.remove('dark')
+ }
+}
+
+export function buildThemeTest(
+ name: string,
+ renderFn: () => React.ReactElement,
+) {
+ describe(name, () => {
+ let consoleError: jest.SpyInstance
+
+ beforeEach(() => {
+ consoleError = jest.spyOn(console, 'error').mockImplementation(() => {})
+ setDocumentTheme('light')
+ })
+
+ afterEach(() => {
+ consoleError.mockRestore()
+ })
+
+ it('renders without errors in light mode', () => {
+ render(renderFn())
+ expect(consoleError).not.toHaveBeenCalled()
+ })
+
+ it('renders without errors in dark mode', () => {
+ setDocumentTheme('dark')
+ render(renderFn())
+ expect(consoleError).not.toHaveBeenCalled()
+ })
+ })
+}
diff --git a/package-lock.json b/package-lock.json
index 3738e20..1111880 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -58,6 +58,7 @@
"sanitize-html": "^2.17.4",
"socket.io": "^4.8.3",
"swagger-ui-express": "^5.0.1",
+ "xstreamroll": "file:..",
"zod": "^3.22.4"
},
"devDependencies": {
@@ -420,7 +421,6 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
"dev": true,
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.7",
"@babel/generator": "^7.29.7",
@@ -1069,7 +1069,6 @@
}
],
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=18"
},
@@ -1093,7 +1092,6 @@
}
],
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=18"
}
@@ -2729,7 +2727,6 @@
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.22.tgz",
"integrity": "sha512-fxJ4v85nDHaqT1PmfNCQ37b/jcv2OojtXTaK1P2uAXhzLf9qq6WNUOFvxBrV4fhQek1EQoT1o9oj5xAZmv3NRw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"file-type": "20.4.1",
"iterare": "1.2.1",
@@ -2761,7 +2758,6 @@
"integrity": "sha512-6IX9+VwjiKtCjx+mXVPncpkQ5ZjKfmssOZPFexmT+6T9H9wZ3svpYACAo7+9e7Nr9DZSoRZw3pffkJP7Z0UjaA==",
"hasInstallScript": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@nuxtjs/opencollective": "0.3.2",
"fast-safe-stringify": "2.1.1",
@@ -2832,7 +2828,6 @@
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.22.tgz",
"integrity": "sha512-ySSq7Py/DFozzZdNDH67m/vHoeVdphDniWBnl6q5QVoXldDdrZIHLXLRMPayTDh5A95nt7jjJzmD4qpTbNQ6tA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"body-parser": "1.20.4",
"cors": "2.8.5",
@@ -3322,7 +3317,6 @@
"resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-10.4.22.tgz",
"integrity": "sha512-OLd4i0Faq7vgdtB5vVUrJ54hWEtcXy9poJ6n7kbbh/5ms+KffUl+wwGsbe7uSXLrkoyI8xXU6fZPkFArI+XiRg==",
"license": "MIT",
- "peer": true,
"dependencies": {
"iterare": "1.2.1",
"object-hash": "3.0.0",
@@ -3588,6 +3582,16 @@
"node": ">=8.0.0"
}
},
+ "node_modules/@paralleldrive/cuid2": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz",
+ "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@noble/hashes": "^1.1.5"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -5279,6 +5283,7 @@
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=10"
},
@@ -5292,6 +5297,7 @@
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
@@ -5306,7 +5312,8 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@testing-library/jest-dom": {
"version": "6.9.1",
@@ -5457,7 +5464,8 @@
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
@@ -5764,7 +5772,6 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz",
"integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==",
"license": "MIT",
- "peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -5801,7 +5808,6 @@
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"devOptional": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -5812,7 +5818,6 @@
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"devOptional": true,
"license": "MIT",
- "peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -5989,7 +5994,6 @@
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0",
@@ -6455,6 +6459,7 @@
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"mime-types": "^3.0.0",
"negotiator": "^1.0.0"
@@ -6468,6 +6473,7 @@
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">= 0.6"
}
@@ -6478,7 +6484,6 @@
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -6525,7 +6530,6 @@
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -7104,7 +7108,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.10.12",
"caniuse-lite": "^1.0.30001782",
@@ -7202,7 +7205,6 @@
"resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.7.6.tgz",
"integrity": "sha512-wBxnBHjDxF1RXpHCBD6HGvKER003Ts7IIm0CHpggliHzN1RZditb7rXoduE1rplc2DEFYKxhLKgFuchXMJje9w==",
"license": "MIT",
- "peer": true,
"dependencies": {
"eventemitter3": "^5.0.1",
"lodash.clonedeep": "^4.5.0",
@@ -7360,7 +7362,6 @@
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -7415,15 +7416,13 @@
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
"integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/class-validator": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.15.1.tgz",
"integrity": "sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/validator": "^13.15.3",
"libphonenumber-js": "^1.11.1",
@@ -7753,6 +7752,7 @@
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
"integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
},
@@ -8352,7 +8352,8 @@
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/dom-helpers": {
"version": "5.2.1",
@@ -8484,8 +8485,7 @@
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.5.1.tgz",
"integrity": "sha512-JUb5+FOHobSiWQ2EJNaueCNT/cQU9L6XWBbWmorWPQT9bkbk+fhsuLr8wWrzXKagO3oWszBO7MSx+GfaRk4E6A==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/embla-carousel-react": {
"version": "8.5.1",
@@ -8752,7 +8752,6 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -9163,6 +9162,7 @@
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.1",
@@ -9206,6 +9206,7 @@
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
"integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^1.0.5",
@@ -9230,6 +9231,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"ms": "^2.1.3"
},
@@ -9247,6 +9249,7 @@
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
"integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
@@ -9263,6 +9266,7 @@
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
"integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">= 0.8"
}
@@ -9271,13 +9275,15 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/express/node_modules/raw-body": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"bytes": "~3.1.2",
"http-errors": "~2.0.1",
@@ -9293,6 +9299,7 @@
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"content-type": "^2.0.0",
"media-typer": "^1.1.0",
@@ -9311,6 +9318,7 @@
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
},
@@ -9477,6 +9485,7 @@
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"debug": "^4.4.0",
"encodeurl": "^2.0.0",
@@ -9498,6 +9507,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"ms": "^2.1.3"
},
@@ -9514,7 +9524,8 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/find-up": {
"version": "4.1.0",
@@ -9699,6 +9710,7 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">= 0.8"
}
@@ -10558,7 +10570,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/is-stream": {
"version": "2.0.1",
@@ -10732,7 +10745,6 @@
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
- "peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@@ -11630,7 +11642,6 @@
"integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"cssstyle": "^4.2.1",
"data-urls": "^5.0.0",
@@ -12299,6 +12310,7 @@
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"lz-string": "bin/bin.js"
}
@@ -12383,6 +12395,7 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
},
@@ -12467,6 +12480,7 @@
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"mime-db": "^1.54.0"
},
@@ -12628,7 +12642,6 @@
"resolved": "https://registry.npmjs.org/next/-/next-16.0.10.tgz",
"integrity": "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@next/env": "16.0.10",
"@swc/helpers": "0.5.15",
@@ -13173,7 +13186,6 @@
"resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz",
"integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"pg-connection-string": "^2.12.0",
"pg-pool": "^3.13.0",
@@ -13327,7 +13339,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -13590,7 +13601,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -13631,7 +13641,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
"license": "MIT",
- "peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -13644,7 +13653,6 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.76.0.tgz",
"integrity": "sha512-eKtLGgFeSgkHqQD8J59AMZ9a4uD1D83iSIzt4YlTGD7liDen5rrjcUO1rVIGd9yC1gofryjtHbv+4ny4hkLWlw==",
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -13884,8 +13892,7 @@
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz",
"integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==",
- "license": "Apache-2.0",
- "peer": true
+ "license": "Apache-2.0"
},
"node_modules/repeat-string": {
"version": "1.6.1",
@@ -14054,6 +14061,7 @@
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"debug": "^4.4.0",
"depd": "^2.0.0",
@@ -14070,6 +14078,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"ms": "^2.1.3"
},
@@ -14086,13 +14095,15 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/router/node_modules/path-to-regexp": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
"license": "MIT",
+ "peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
@@ -14144,7 +14155,6 @@
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"tslib": "^2.1.0"
}
@@ -14246,7 +14256,6 @@
"integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -14292,6 +14301,7 @@
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"debug": "^4.4.3",
"encodeurl": "^2.0.0",
@@ -14318,6 +14328,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"ms": "^2.1.3"
},
@@ -14334,13 +14345,15 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/serve-static": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
"integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
@@ -15177,8 +15190,7 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz",
"integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/tailwindcss-animate": {
"version": "1.0.7",
@@ -15575,7 +15587,6 @@
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -15742,7 +15753,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -16052,7 +16062,6 @@
"integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.6",
@@ -16397,6 +16406,10 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/xstreamroll": {
+ "resolved": "",
+ "link": true
+ },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",