diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..70a4a2b
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,15 @@
+{
+ "permissions": {
+ "allow": [
+ "PowerShell(corepack enable pnpm)",
+ "PowerShell(corepack prepare pnpm@latest --activate)",
+ "PowerShell(pnpm --version)",
+ "PowerShell(docker --version)",
+ "PowerShell(docker compose version)",
+ "PowerShell(docker exec fieldops-postgres psql -U fieldops -d fieldops -c \"\\\\dt\" 2>&1)",
+ "PowerShell(docker exec fieldops-postgres psql -U fieldops -d fieldops -c \"SELECT id, name FROM \\\\`\"Tenant\\\\`\";\" 2>&1)",
+ "PowerShell(docker exec fieldops-postgres psql -U fieldops -d fieldops -c \"SELECT email, role FROM \\\\`\"User\\\\`\";\" 2>&1)",
+ "PowerShell(docker exec fieldops-postgres psql -U fieldops -d fieldops -c \"SELECT code, name, area FROM \\\\`\"Workstation\\\\`\";\" 2>&1)"
+ ]
+ }
+}
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..d134944
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,33 @@
+# ---------------------------------------------------------------------------
+# FieldOps — environment variables
+# ---------------------------------------------------------------------------
+# Copy this file to .env (cp .env.example .env) and adjust as needed for your
+# local environment. Never commit .env.
+
+# Postgres connection string. Matches docker-compose.yml defaults.
+DATABASE_URL="postgresql://fieldops:fieldops@localhost:5432/fieldops?schema=public"
+
+# Auth.js v5 — secret used to sign session tokens.
+# In production, set this to a strong random value: `openssl rand -base64 32`.
+AUTH_SECRET="dev-secret-do-not-use-in-production-please-change-me"
+
+# Dev-only auto sign-in.
+# When set to "true", the app will silently sign in as the seed admin user
+# (admin@demo.local of the "Demo Factory" tenant) on every request that has
+# no session. This skips the login UI in local development and CI/E2E.
+#
+# !!! NEVER set this to "true" in production. !!!
+# The default of "false" here is intentional — a developer setting up locally
+# must consciously opt in by editing their .env. See README "Auth" section.
+AUTH_DEV_AUTOLOGIN="false"
+
+# Base URL of the operator-pwa app — used by Auth.js for callback URLs.
+NEXT_PUBLIC_APP_URL="http://localhost:3000"
+AUTH_URL="http://localhost:3000"
+
+# Pino log level — one of: fatal, error, warn, info, debug, trace.
+LOG_LEVEL="info"
+
+# Node environment — Next.js sets this automatically; included here for
+# packages that need it at module load time.
+NODE_ENV="development"
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..ffbc55c
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,5 @@
+engine-strict=true
+auto-install-peers=true
+strict-peer-dependencies=false
+prefer-workspace-packages=true
+link-workspace-packages=true
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..2bd5a0a
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+22
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..0c0e4dc
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,11 @@
+node_modules
+.next
+.turbo
+dist
+build
+coverage
+playwright-report
+test-results
+pnpm-lock.yaml
+*.tsbuildinfo
+packages/db/prisma/migrations
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..5e90b1f
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,12 @@
+{
+ "semi": true,
+ "singleQuote": true,
+ "trailingComma": "all",
+ "printWidth": 100,
+ "tabWidth": 2,
+ "useTabs": false,
+ "arrowParens": "always",
+ "endOfLine": "lf",
+ "plugins": ["prettier-plugin-tailwindcss"],
+ "tailwindFunctions": ["cn", "clsx", "cva"]
+}
diff --git a/apps/admin-web/app/layout.tsx b/apps/admin-web/app/layout.tsx
new file mode 100644
index 0000000..45237d1
--- /dev/null
+++ b/apps/admin-web/app/layout.tsx
@@ -0,0 +1,25 @@
+import type { Metadata } from 'next';
+
+export const metadata: Metadata = {
+ title: 'FieldOps Admin',
+ description: 'Backoffice — coming soon.',
+};
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/apps/admin-web/app/page.tsx b/apps/admin-web/app/page.tsx
new file mode 100644
index 0000000..81ac7a9
--- /dev/null
+++ b/apps/admin-web/app/page.tsx
@@ -0,0 +1,8 @@
+export default function Page() {
+ return (
+
+ FieldOps Admin
+ Coming soon.
+
+ );
+}
diff --git a/apps/admin-web/next.config.ts b/apps/admin-web/next.config.ts
new file mode 100644
index 0000000..2ae088f
--- /dev/null
+++ b/apps/admin-web/next.config.ts
@@ -0,0 +1,8 @@
+import type { NextConfig } from 'next';
+
+const config: NextConfig = {
+ reactStrictMode: true,
+ poweredByHeader: false,
+};
+
+export default config;
diff --git a/apps/admin-web/package.json b/apps/admin-web/package.json
new file mode 100644
index 0000000..ba87591
--- /dev/null
+++ b/apps/admin-web/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@repo/admin-web",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "dotenv -e ../../.env -- next dev --port 3001",
+ "build": "dotenv -e ../../.env -- next build",
+ "start": "dotenv -e ../../.env -- next start --port 3001",
+ "lint": "next lint",
+ "typecheck": "tsc --noEmit",
+ "clean": "rimraf .next .turbo node_modules"
+ },
+ "dependencies": {
+ "next": "^15.1.3",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0"
+ },
+ "devDependencies": {
+ "@repo/config": "workspace:*",
+ "@types/node": "^22.10.2",
+ "@types/react": "^19.0.2",
+ "@types/react-dom": "^19.0.2",
+ "dotenv-cli": "^8.0.0",
+ "rimraf": "^6.0.1",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/apps/admin-web/tsconfig.json b/apps/admin-web/tsconfig.json
new file mode 100644
index 0000000..469994a
--- /dev/null
+++ b/apps/admin-web/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@repo/config/tsconfig/nextjs.json",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": { "@/*": ["./*"] }
+ },
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "next-env.d.ts"],
+ "exclude": ["node_modules", ".next"]
+}
diff --git a/apps/operator-pwa/app/api/auth/[...nextauth]/route.ts b/apps/operator-pwa/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 0000000..8f4b86d
--- /dev/null
+++ b/apps/operator-pwa/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,4 @@
+import { handlers } from '@/lib/auth';
+
+export const { GET, POST } = handlers;
+export const runtime = 'nodejs';
diff --git a/apps/operator-pwa/app/api/trpc/[trpc]/route.ts b/apps/operator-pwa/app/api/trpc/[trpc]/route.ts
new file mode 100644
index 0000000..5a621cd
--- /dev/null
+++ b/apps/operator-pwa/app/api/trpc/[trpc]/route.ts
@@ -0,0 +1,25 @@
+import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
+import { appRouter, createTRPCContext } from '@repo/api';
+import { resolveUser } from '@/lib/auth';
+
+export const runtime = 'nodejs';
+
+const handler = async (req: Request) => {
+ return fetchRequestHandler({
+ endpoint: '/api/trpc',
+ req,
+ router: appRouter,
+ createContext: async () => {
+ const user = await resolveUser();
+ return createTRPCContext({ user, headers: req.headers });
+ },
+ onError({ error, path }) {
+ if (process.env.NODE_ENV === 'development') {
+ // eslint-disable-next-line no-console
+ console.error(`[trpc] ${path ?? ''}:`, error.message);
+ }
+ },
+ });
+};
+
+export { handler as GET, handler as POST };
diff --git a/apps/operator-pwa/app/globals.css b/apps/operator-pwa/app/globals.css
new file mode 100644
index 0000000..010a5f2
--- /dev/null
+++ b/apps/operator-pwa/app/globals.css
@@ -0,0 +1,58 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
+ --primary: 222.2 47.4% 11.2%;
+ --primary-foreground: 210 40% 98%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 222.2 84% 4.9%;
+ --radius: 0.5rem;
+ }
+
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
+ --primary: 210 40% 98%;
+ --primary-foreground: 222.2 47.4% 11.2%;
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 212.7 26.8% 83.9%;
+ }
+
+ * {
+ @apply border-border;
+ }
+
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/apps/operator-pwa/app/layout.tsx b/apps/operator-pwa/app/layout.tsx
new file mode 100644
index 0000000..92ce506
--- /dev/null
+++ b/apps/operator-pwa/app/layout.tsx
@@ -0,0 +1,31 @@
+import type { Metadata, Viewport } from 'next';
+import { Providers } from './providers';
+import './globals.css';
+
+export const metadata: Metadata = {
+ title: 'FieldOps — Operator',
+ description: 'Industrial operator console.',
+ manifest: '/manifest.webmanifest',
+ applicationName: 'FieldOps Operator',
+ appleWebApp: {
+ capable: true,
+ title: 'FieldOps Operator',
+ statusBarStyle: 'default',
+ },
+};
+
+export const viewport: Viewport = {
+ themeColor: '#0f172a',
+ width: 'device-width',
+ initialScale: 1,
+};
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/apps/operator-pwa/app/page.tsx b/apps/operator-pwa/app/page.tsx
new file mode 100644
index 0000000..fe3817e
--- /dev/null
+++ b/apps/operator-pwa/app/page.tsx
@@ -0,0 +1,88 @@
+import { TRPCError } from '@trpc/server';
+import { CheckCircle2, AlertCircle } from 'lucide-react';
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/ui';
+import { Alert, AlertDescription, AlertTitle } from '@repo/ui';
+import { api } from '@/lib/trpc/server';
+import { PingClient } from './ping-client';
+
+/**
+ * Smoke-test home page. Uses the RSC tRPC caller (server-side) to invoke the
+ * ping procedure end-to-end:
+ *
+ * RSC → tRPC caller → protectedProcedure → Prisma → Postgres → Tenant row
+ *
+ * If the call throws (e.g. UNAUTHORIZED because no session), the error is
+ * caught and rendered as a legible failure card.
+ */
+export default async function HomePage() {
+ let result:
+ | { ok: true; payload: Awaited> }
+ | { ok: false; message: string; code: string } = {
+ ok: false,
+ message: 'init',
+ code: 'INIT',
+ };
+
+ try {
+ const payload = await api.ping.ping();
+ result = { ok: true, payload };
+ } catch (err) {
+ if (err instanceof TRPCError) {
+ result = { ok: false, message: err.message, code: err.code };
+ } else if (err instanceof Error) {
+ result = { ok: false, message: err.message, code: 'UNKNOWN' };
+ } else {
+ result = { ok: false, message: String(err), code: 'UNKNOWN' };
+ }
+ }
+
+ return (
+
+
+ FieldOps Operator
+ Scaffold smoke test
+
+
+ {result.ok ? (
+
+
+
+
+ Connected
+
+
+ End-to-end path verified: RSC → tRPC → Prisma → Postgres.
+
+
+
+
+ Tenant:
+ {result.payload.tenant.name}
+
+
+ id: {result.payload.tenant.id}
+
+
+ at: {result.payload.timestamp}
+
+
+
+ ) : (
+
+
+ Ping failed ({result.code})
+
+ {result.message}
+
+ If this says UNAUTHORIZED, set{' '}
+ AUTH_DEV_AUTOLOGIN=true in .env for local dev,
+ or sign in via Auth.js.
+
+
+
+ )}
+
+
+
+ );
+}
diff --git a/apps/operator-pwa/app/ping-client.tsx b/apps/operator-pwa/app/ping-client.tsx
new file mode 100644
index 0000000..f16e25f
--- /dev/null
+++ b/apps/operator-pwa/app/ping-client.tsx
@@ -0,0 +1,43 @@
+'use client';
+
+import { CheckCircle2, AlertCircle, Loader2 } from 'lucide-react';
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@repo/ui';
+import { trpc } from '@/lib/trpc/client';
+
+/**
+ * Client-side ping. Demonstrates the second tRPC path: client hooks +
+ * TanStack Query. The RSC caller above the fold and this hook hit the same
+ * procedure — both must succeed for the hybrid wiring to be considered green.
+ */
+export function PingClient() {
+ const query = trpc.ping.ping.useQuery();
+
+ return (
+
+
+
+ {query.isPending ? (
+
+ ) : query.isError ? (
+
+ ) : (
+
+ )}
+ Client-side ping (useQuery)
+
+ Round-trips through /api/trpc.
+
+
+ {query.isPending && Loading…}
+ {query.isError && (
+
+ {query.error.message}
+
+ )}
+ {query.data && (
+ tenant: {query.data.tenant.name}
+ )}
+
+
+ );
+}
diff --git a/apps/operator-pwa/app/providers.tsx b/apps/operator-pwa/app/providers.tsx
new file mode 100644
index 0000000..d192733
--- /dev/null
+++ b/apps/operator-pwa/app/providers.tsx
@@ -0,0 +1,39 @@
+'use client';
+
+import { useState, type ReactNode } from 'react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { httpBatchLink } from '@trpc/client';
+import superjson from 'superjson';
+import { trpc } from '@/lib/trpc/client';
+
+function makeTrpcClient() {
+ return trpc.createClient({
+ links: [
+ httpBatchLink({
+ url: '/api/trpc',
+ transformer: superjson,
+ }),
+ ],
+ });
+}
+
+export function Providers({ children }: { children: ReactNode }) {
+ const [queryClient] = useState(
+ () =>
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ staleTime: 30 * 1000,
+ refetchOnWindowFocus: false,
+ },
+ },
+ }),
+ );
+ const [trpcClient] = useState(makeTrpcClient);
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/apps/operator-pwa/env.ts b/apps/operator-pwa/env.ts
new file mode 100644
index 0000000..e60d232
--- /dev/null
+++ b/apps/operator-pwa/env.ts
@@ -0,0 +1,36 @@
+import { createEnv } from '@t3-oss/env-nextjs';
+import { z } from 'zod';
+
+/**
+ * Zod-validated environment. Imported eagerly from next.config.ts so that
+ * missing/invalid variables fail the build instead of silently leaking
+ * `undefined` at runtime.
+ */
+export const env = createEnv({
+ server: {
+ NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
+ DATABASE_URL: z.string().url(),
+ AUTH_SECRET: z.string().min(1, 'AUTH_SECRET is required'),
+ AUTH_URL: z.string().url().optional(),
+ AUTH_DEV_AUTOLOGIN: z
+ .string()
+ .optional()
+ .transform((v) => v === 'true'),
+ LOG_LEVEL: z
+ .enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace'])
+ .default('info'),
+ },
+ client: {
+ NEXT_PUBLIC_APP_URL: z.string().url(),
+ },
+ runtimeEnv: {
+ NODE_ENV: process.env.NODE_ENV,
+ DATABASE_URL: process.env.DATABASE_URL,
+ AUTH_SECRET: process.env.AUTH_SECRET,
+ AUTH_URL: process.env.AUTH_URL,
+ AUTH_DEV_AUTOLOGIN: process.env.AUTH_DEV_AUTOLOGIN,
+ LOG_LEVEL: process.env.LOG_LEVEL,
+ NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
+ },
+ emptyStringAsUndefined: true,
+});
diff --git a/apps/operator-pwa/lib/auth.config.ts b/apps/operator-pwa/lib/auth.config.ts
new file mode 100644
index 0000000..d0a3748
--- /dev/null
+++ b/apps/operator-pwa/lib/auth.config.ts
@@ -0,0 +1,40 @@
+import type { NextAuthConfig } from 'next-auth';
+
+/**
+ * Edge-safe portion of the Auth.js config. The middleware imports THIS, never
+ * the full `auth.ts` — Credentials providers and the Prisma client are not
+ * edge-compatible, so they live exclusively in auth.ts which runs in the
+ * Node.js runtime (route handlers).
+ */
+export const authConfig = {
+ trustHost: true,
+ session: { strategy: 'jwt' },
+ pages: {
+ // No login UI in this scaffold phase. See auth.ts for the placeholder.
+ },
+ callbacks: {
+ async jwt({ token, user }) {
+ if (user) {
+ // user is the value returned from `authorize()` in the Credentials provider.
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const u = user as any;
+ token.id = u.id;
+ token.role = u.role;
+ token.tenantId = u.tenantId;
+ }
+ return token;
+ },
+ async session({ session, token }) {
+ if (token && session.user) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (session.user as any).id = token.id;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (session.user as any).role = token.role;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (session.user as any).tenantId = token.tenantId;
+ }
+ return session;
+ },
+ },
+ providers: [],
+} satisfies NextAuthConfig;
diff --git a/apps/operator-pwa/lib/auth.ts b/apps/operator-pwa/lib/auth.ts
new file mode 100644
index 0000000..4d4076d
--- /dev/null
+++ b/apps/operator-pwa/lib/auth.ts
@@ -0,0 +1,93 @@
+import NextAuth from 'next-auth';
+import Credentials from 'next-auth/providers/credentials';
+import { prisma } from '@repo/db';
+import type { SessionUser } from '@repo/api';
+import { env } from '../env';
+import { authConfig } from './auth.config';
+
+/**
+ * ============================================================================
+ * Auth.js v5 — PLACEHOLDER configuration for the scaffold phase.
+ * ============================================================================
+ *
+ * The Credentials provider below accepts ANY email that exists in the User
+ * table (seeded by `pnpm db:seed`). NO PASSWORD CHECK is performed. This is
+ * deliberately minimal — just enough to populate the tRPC context with a real
+ * Auth.js session — and MUST be replaced with real authentication before any
+ * non-dev deployment.
+ *
+ * Auto sign-in
+ * ------------
+ * See `resolveUser()` below. When AUTH_DEV_AUTOLOGIN=true, server-side code
+ * that has no session falls back to the seeded admin user. This is a back
+ * door and is gated by an explicit env flag whose default in .env.example is
+ * FALSE.
+ *
+ * !!! NEVER set AUTH_DEV_AUTOLOGIN=true in production. !!!
+ *
+ * In production with AUTH_DEV_AUTOLOGIN unset/false, requests without a
+ * signed Auth.js session resolve to user=null, and protectedProcedure throws
+ * 401.
+ * ============================================================================
+ */
+
+export const { handlers, auth, signIn, signOut } = NextAuth({
+ ...authConfig,
+ secret: env.AUTH_SECRET,
+ providers: [
+ Credentials({
+ name: 'Email (placeholder)',
+ credentials: {
+ email: { label: 'Email', type: 'email' },
+ },
+ async authorize(credentials) {
+ const email = credentials?.email;
+ if (typeof email !== 'string' || !email) return null;
+ const user = await prisma.user.findFirst({ where: { email } });
+ if (!user) return null;
+ // NO password verification — placeholder only.
+ return {
+ id: user.id,
+ email: user.email,
+ name: user.email,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ role: user.role as any,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ tenantId: user.tenantId as any,
+ };
+ },
+ }),
+ ],
+});
+
+/**
+ * Resolve the current user for server-side code (RSC, route handlers, tRPC).
+ * Single chokepoint that combines the real Auth.js session with the dev-only
+ * auto-login fallback. Application code MUST use this and not call `auth()`
+ * directly when it expects to honour AUTH_DEV_AUTOLOGIN.
+ */
+export async function resolveUser(): Promise {
+ const session = await auth();
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const u = session?.user as any;
+ if (u?.id && u?.tenantId) {
+ return { id: u.id, email: u.email, role: u.role, tenantId: u.tenantId };
+ }
+
+ if (env.AUTH_DEV_AUTOLOGIN) {
+ // Dev back door. Production guards: env flag default is false; this branch
+ // is also a no-op if the seed user doesn't exist.
+ const admin = await prisma.user.findFirst({ where: { email: 'admin@demo.local' } });
+ if (admin) {
+ return {
+ id: admin.id,
+ email: admin.email,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ role: admin.role as any,
+ tenantId: admin.tenantId,
+ };
+ }
+ }
+
+ return null;
+}
diff --git a/apps/operator-pwa/lib/trpc/client.ts b/apps/operator-pwa/lib/trpc/client.ts
new file mode 100644
index 0000000..72d6a94
--- /dev/null
+++ b/apps/operator-pwa/lib/trpc/client.ts
@@ -0,0 +1,12 @@
+'use client';
+
+import { createTRPCReact } from '@trpc/react-query';
+import type { AppRouter } from '@repo/api';
+
+/**
+ * Typed tRPC React Query hooks for client components.
+ *
+ * import { trpc } from '@/lib/trpc/client';
+ * const { data } = trpc.ping.ping.useQuery();
+ */
+export const trpc = createTRPCReact();
diff --git a/apps/operator-pwa/lib/trpc/server.ts b/apps/operator-pwa/lib/trpc/server.ts
new file mode 100644
index 0000000..7b919e0
--- /dev/null
+++ b/apps/operator-pwa/lib/trpc/server.ts
@@ -0,0 +1,30 @@
+import 'server-only';
+import { cache } from 'react';
+import { headers } from 'next/headers';
+import {
+ appRouter,
+ createCallerFactory,
+ createTRPCContext,
+ type AppRouter,
+} from '@repo/api';
+import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
+import { resolveUser } from '../auth';
+
+/**
+ * RSC-side tRPC caller. Bypasses HTTP — runs the router directly inside the
+ * server component. Use this for reads in Server Components / Server Actions.
+ *
+ * For client-side reads/mutations, see `./client.ts` (TanStack Query hooks).
+ */
+const createContext = cache(async () => {
+ const user = await resolveUser();
+ const h = await headers();
+ return createTRPCContext({ user, headers: h });
+});
+
+const createCaller = createCallerFactory(appRouter);
+
+export const api = createCaller(createContext);
+
+export type RouterInputs = inferRouterInputs;
+export type RouterOutputs = inferRouterOutputs;
diff --git a/apps/operator-pwa/middleware.ts b/apps/operator-pwa/middleware.ts
new file mode 100644
index 0000000..1289609
--- /dev/null
+++ b/apps/operator-pwa/middleware.ts
@@ -0,0 +1,17 @@
+import NextAuth from 'next-auth';
+import { authConfig } from './lib/auth.config';
+
+// Edge-runtime middleware. Uses the edge-safe authConfig (no Credentials
+// provider, no Prisma) — it only validates and refreshes the JWT cookie. The
+// full auth config with the Credentials provider lives in lib/auth.ts and
+// runs in the Node.js runtime via the route handlers.
+export default NextAuth(authConfig).auth;
+
+export const config = {
+ matcher: [
+ // Run on every path except static assets, image optimization, and the
+ // PWA manifest. The Auth.js / tRPC API routes are excluded explicitly
+ // because they handle session resolution themselves.
+ '/((?!api/auth|api/trpc|_next/static|_next/image|favicon.ico|manifest.webmanifest|icon-.*\\.svg).*)',
+ ],
+};
diff --git a/apps/operator-pwa/next.config.ts b/apps/operator-pwa/next.config.ts
new file mode 100644
index 0000000..3cac97c
--- /dev/null
+++ b/apps/operator-pwa/next.config.ts
@@ -0,0 +1,14 @@
+import type { NextConfig } from 'next';
+import './env';
+
+const config: NextConfig = {
+ transpilePackages: ['@repo/db', '@repo/api', '@repo/ui', '@repo/domain'],
+ reactStrictMode: true,
+ poweredByHeader: false,
+ // Pino uses worker_threads via pino-pretty. Next's server bundler doesn't
+ // emit the worker chunk correctly — mark these as external so they're
+ // required straight from node_modules at runtime.
+ serverExternalPackages: ['pino', 'pino-pretty'],
+};
+
+export default config;
diff --git a/apps/operator-pwa/package.json b/apps/operator-pwa/package.json
new file mode 100644
index 0000000..81a7374
--- /dev/null
+++ b/apps/operator-pwa/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "@repo/operator-pwa",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "dotenv -e ../../.env -- next dev --port 3000",
+ "build": "dotenv -e ../../.env -- next build",
+ "start": "dotenv -e ../../.env -- next start --port 3000",
+ "lint": "next lint",
+ "typecheck": "tsc --noEmit",
+ "clean": "rimraf .next .turbo node_modules"
+ },
+ "dependencies": {
+ "@repo/api": "workspace:*",
+ "@repo/db": "workspace:*",
+ "@repo/domain": "workspace:*",
+ "@repo/ui": "workspace:*",
+ "@t3-oss/env-nextjs": "^0.11.1",
+ "@tanstack/react-query": "^5.62.10",
+ "@trpc/client": "^11.0.0",
+ "@trpc/react-query": "^11.0.0",
+ "@trpc/server": "^11.0.0",
+ "lucide-react": "^0.469.0",
+ "next": "^15.1.3",
+ "next-auth": "5.0.0-beta.25",
+ "pino": "^9.5.0",
+ "pino-pretty": "^11.3.0",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "superjson": "^2.2.2",
+ "zod": "^3.24.1"
+ },
+ "devDependencies": {
+ "@repo/config": "workspace:*",
+ "@types/node": "^22.10.2",
+ "@types/react": "^19.0.2",
+ "@types/react-dom": "^19.0.2",
+ "autoprefixer": "^10.4.20",
+ "dotenv-cli": "^8.0.0",
+ "postcss": "^8.4.49",
+ "rimraf": "^6.0.1",
+ "tailwindcss": "^3.4.17",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/apps/operator-pwa/postcss.config.cjs b/apps/operator-pwa/postcss.config.cjs
new file mode 100644
index 0000000..12a703d
--- /dev/null
+++ b/apps/operator-pwa/postcss.config.cjs
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/apps/operator-pwa/public/icon-192.svg b/apps/operator-pwa/public/icon-192.svg
new file mode 100644
index 0000000..93dc106
--- /dev/null
+++ b/apps/operator-pwa/public/icon-192.svg
@@ -0,0 +1,4 @@
+
diff --git a/apps/operator-pwa/public/icon-512.svg b/apps/operator-pwa/public/icon-512.svg
new file mode 100644
index 0000000..e48e478
--- /dev/null
+++ b/apps/operator-pwa/public/icon-512.svg
@@ -0,0 +1,4 @@
+
diff --git a/apps/operator-pwa/public/icon-maskable.svg b/apps/operator-pwa/public/icon-maskable.svg
new file mode 100644
index 0000000..146a7de
--- /dev/null
+++ b/apps/operator-pwa/public/icon-maskable.svg
@@ -0,0 +1,4 @@
+
diff --git a/apps/operator-pwa/public/manifest.webmanifest b/apps/operator-pwa/public/manifest.webmanifest
new file mode 100644
index 0000000..e1dca13
--- /dev/null
+++ b/apps/operator-pwa/public/manifest.webmanifest
@@ -0,0 +1,30 @@
+{
+ "name": "FieldOps Operator",
+ "short_name": "FieldOps",
+ "description": "Industrial operator console.",
+ "start_url": "/",
+ "display": "standalone",
+ "background_color": "#0f172a",
+ "theme_color": "#0f172a",
+ "orientation": "any",
+ "icons": [
+ {
+ "src": "/icon-192.svg",
+ "sizes": "192x192",
+ "type": "image/svg+xml",
+ "purpose": "any"
+ },
+ {
+ "src": "/icon-512.svg",
+ "sizes": "512x512",
+ "type": "image/svg+xml",
+ "purpose": "any"
+ },
+ {
+ "src": "/icon-maskable.svg",
+ "sizes": "512x512",
+ "type": "image/svg+xml",
+ "purpose": "maskable"
+ }
+ ]
+}
diff --git a/apps/operator-pwa/tailwind.config.ts b/apps/operator-pwa/tailwind.config.ts
new file mode 100644
index 0000000..def781c
--- /dev/null
+++ b/apps/operator-pwa/tailwind.config.ts
@@ -0,0 +1,14 @@
+import type { Config } from 'tailwindcss';
+import preset from '@repo/config/tailwind/preset';
+
+const config: Config = {
+ presets: [preset],
+ content: [
+ './app/**/*.{ts,tsx}',
+ './components/**/*.{ts,tsx}',
+ './lib/**/*.{ts,tsx}',
+ '../../packages/ui/src/**/*.{ts,tsx}',
+ ],
+};
+
+export default config;
diff --git a/apps/operator-pwa/tsconfig.json b/apps/operator-pwa/tsconfig.json
new file mode 100644
index 0000000..54f7609
--- /dev/null
+++ b/apps/operator-pwa/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@repo/config/tsconfig/nextjs.json",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./*"]
+ }
+ },
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "next-env.d.ts"],
+ "exclude": ["node_modules", ".next"]
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..2ff1c61
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,23 @@
+name: fieldops
+
+services:
+ postgres:
+ image: postgres:16-alpine
+ container_name: fieldops-postgres
+ restart: unless-stopped
+ environment:
+ POSTGRES_USER: fieldops
+ POSTGRES_PASSWORD: fieldops
+ POSTGRES_DB: fieldops
+ ports:
+ - "5432:5432"
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U fieldops -d fieldops"]
+ interval: 5s
+ timeout: 5s
+ retries: 10
+
+volumes:
+ postgres-data:
diff --git a/e2e/package.json b/e2e/package.json
new file mode 100644
index 0000000..2d5f5e0
--- /dev/null
+++ b/e2e/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "@repo/e2e",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "test": "playwright test",
+ "test:headed": "playwright test --headed",
+ "test:ui": "playwright test --ui",
+ "report": "playwright show-report",
+ "install-browsers": "playwright install chromium",
+ "clean": "rimraf node_modules playwright-report test-results .playwright"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.49.1",
+ "@repo/config": "workspace:*",
+ "@types/node": "^22.10.2",
+ "rimraf": "^6.0.1",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts
new file mode 100644
index 0000000..1471184
--- /dev/null
+++ b/e2e/playwright.config.ts
@@ -0,0 +1,40 @@
+import { defineConfig, devices } from '@playwright/test';
+
+const PORT = 3000;
+const BASE_URL = `http://localhost:${PORT}`;
+
+export default defineConfig({
+ testDir: './tests',
+ fullyParallel: true,
+ forbidOnly: !!process.env.CI,
+ retries: process.env.CI ? 2 : 0,
+ workers: process.env.CI ? 1 : undefined,
+ reporter: [['list'], ['html', { open: 'never' }]],
+ use: {
+ baseURL: BASE_URL,
+ trace: 'retain-on-failure',
+ screenshot: 'only-on-failure',
+ },
+ projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ ],
+ webServer: {
+ // Run from the repo root so workspace resolution works.
+ command: 'pnpm --filter @repo/operator-pwa dev',
+ cwd: '..',
+ url: BASE_URL,
+ reuseExistingServer: !process.env.CI,
+ timeout: 120_000,
+ stdout: 'pipe',
+ stderr: 'pipe',
+ // Force the dev autologin on for E2E regardless of the developer's local
+ // .env. This env applies only to the child dev server, not the test
+ // process itself.
+ env: {
+ AUTH_DEV_AUTOLOGIN: 'true',
+ },
+ },
+});
diff --git a/e2e/tests/ping.spec.ts b/e2e/tests/ping.spec.ts
new file mode 100644
index 0000000..da9871b
--- /dev/null
+++ b/e2e/tests/ping.spec.ts
@@ -0,0 +1,18 @@
+import { test, expect } from '@playwright/test';
+
+test.describe('ping smoke', () => {
+ test('home page shows the seeded Demo Factory tenant', async ({ page }) => {
+ await page.goto('/');
+
+ // RSC card with the server-side ping result.
+ const success = page.getByTestId('ping-success');
+ await expect(success).toBeVisible({ timeout: 15_000 });
+
+ const tenant = page.getByTestId('tenant-name');
+ await expect(tenant).toHaveText('Demo Factory');
+
+ // Client-side hook hitting the same procedure via /api/trpc.
+ const clientTenant = page.getByTestId('ping-client-tenant');
+ await expect(clientTenant).toContainText('Demo Factory');
+ });
+});
diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json
new file mode 100644
index 0000000..b201f3b
--- /dev/null
+++ b/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@repo/config/tsconfig/base.json",
+ "compilerOptions": {
+ "noEmit": true,
+ "lib": ["ES2022", "DOM"],
+ "module": "ESNext",
+ "moduleResolution": "Bundler"
+ },
+ "include": ["**/*.ts"]
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..0310e14
--- /dev/null
+++ b/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "fieldops",
+ "version": "0.0.0",
+ "private": true,
+ "description": "FieldOps — modular industrial SaaS monorepo",
+ "packageManager": "pnpm@11.1.2",
+ "engines": {
+ "node": ">=22.0.0",
+ "pnpm": ">=11.0.0"
+ },
+ "scripts": {
+ "dev": "turbo run dev",
+ "build": "turbo run build",
+ "lint": "turbo run lint",
+ "typecheck": "turbo run typecheck",
+ "test": "turbo run test",
+ "test:e2e": "pnpm --filter @repo/e2e test",
+ "db:generate": "pnpm --filter @repo/db exec prisma generate",
+ "db:migrate": "pnpm --filter @repo/db exec prisma migrate dev",
+ "db:migrate:deploy": "pnpm --filter @repo/db exec prisma migrate deploy",
+ "db:seed": "pnpm --filter @repo/db seed",
+ "db:studio": "pnpm --filter @repo/db exec prisma studio",
+ "db:reset": "pnpm --filter @repo/db exec prisma migrate reset --force",
+ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md,yml,yaml}\"",
+ "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md,yml,yaml}\"",
+ "clean": "turbo run clean && rimraf node_modules .turbo"
+ },
+ "devDependencies": {
+ "@repo/config": "workspace:*",
+ "prettier": "^3.4.2",
+ "prettier-plugin-tailwindcss": "^0.6.9",
+ "rimraf": "^6.0.1",
+ "turbo": "^2.3.3",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/packages/api/package.json b/packages/api/package.json
new file mode 100644
index 0000000..1455121
--- /dev/null
+++ b/packages/api/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "@repo/api",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "exports": {
+ ".": "./src/index.ts",
+ "./context": "./src/context.ts",
+ "./trpc": "./src/trpc.ts"
+ },
+ "scripts": {
+ "typecheck": "tsc --noEmit",
+ "clean": "rimraf .turbo node_modules"
+ },
+ "dependencies": {
+ "@repo/db": "workspace:*",
+ "@trpc/server": "^11.0.0",
+ "pino": "^9.5.0",
+ "superjson": "^2.2.2",
+ "zod": "^3.24.1"
+ },
+ "devDependencies": {
+ "@repo/config": "workspace:*",
+ "rimraf": "^6.0.1",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/packages/api/src/context.ts b/packages/api/src/context.ts
new file mode 100644
index 0000000..899a741
--- /dev/null
+++ b/packages/api/src/context.ts
@@ -0,0 +1,45 @@
+import { prisma, tenantScoped, type TenantScopedClient, type DbClient } from '@repo/db';
+import { logger } from './logger';
+
+/**
+ * Authenticated user shape passed in by the app layer.
+ *
+ * @repo/api does NOT depend on next-auth directly — that would entangle the API
+ * layer with a specific auth implementation. Instead, the Next route handler
+ * resolves Auth.js's Session and adapts it into this minimal shape.
+ */
+export type SessionUser = {
+ id: string;
+ email: string;
+ role: 'ADMIN' | 'SUPERVISOR' | 'OPERATOR';
+ tenantId: string;
+};
+
+export type CreateContextOptions = {
+ user: SessionUser | null;
+ headers: Headers;
+};
+
+export type Context = {
+ /** Unscoped Prisma client. Use only for cross-tenant operations (e.g. login lookup). */
+ prisma: DbClient;
+ /** Tenant-scoped Prisma client. NULL when there's no authenticated tenant. */
+ db: TenantScopedClient | null;
+ /** Authenticated user, or null. */
+ user: SessionUser | null;
+ /** Tenant id (convenience). */
+ tenantId: string | null;
+ headers: Headers;
+ logger: typeof logger;
+};
+
+export async function createTRPCContext({ user, headers }: CreateContextOptions): Promise {
+ return {
+ prisma,
+ db: user ? tenantScoped(prisma, user.tenantId) : null,
+ user,
+ tenantId: user?.tenantId ?? null,
+ headers,
+ logger: logger.child({ tenantId: user?.tenantId ?? null, userId: user?.id ?? null }),
+ };
+}
diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts
new file mode 100644
index 0000000..9e70767
--- /dev/null
+++ b/packages/api/src/index.ts
@@ -0,0 +1,3 @@
+export { appRouter, type AppRouter } from './routers/_app';
+export { createTRPCContext, type Context, type SessionUser } from './context';
+export { createCallerFactory } from './trpc';
diff --git a/packages/api/src/logger.ts b/packages/api/src/logger.ts
new file mode 100644
index 0000000..2a895ef
--- /dev/null
+++ b/packages/api/src/logger.ts
@@ -0,0 +1,11 @@
+import pino from 'pino';
+
+export const logger = pino({
+ level: process.env.LOG_LEVEL ?? 'info',
+ base: undefined,
+ // Pretty-print only in development; in production emit JSON for log aggregation.
+ transport:
+ process.env.NODE_ENV === 'development'
+ ? { target: 'pino-pretty', options: { colorize: true, translateTime: 'SYS:HH:MM:ss' } }
+ : undefined,
+});
diff --git a/packages/api/src/routers/_app.ts b/packages/api/src/routers/_app.ts
new file mode 100644
index 0000000..5626270
--- /dev/null
+++ b/packages/api/src/routers/_app.ts
@@ -0,0 +1,8 @@
+import { router } from '../trpc';
+import { pingRouter } from './ping';
+
+export const appRouter = router({
+ ping: pingRouter,
+});
+
+export type AppRouter = typeof appRouter;
diff --git a/packages/api/src/routers/ping.ts b/packages/api/src/routers/ping.ts
new file mode 100644
index 0000000..a2a5387
--- /dev/null
+++ b/packages/api/src/routers/ping.ts
@@ -0,0 +1,31 @@
+import { TRPCError } from '@trpc/server';
+import { protectedProcedure, router } from '../trpc';
+
+export const pingRouter = router({
+ /**
+ * End-to-end smoke test:
+ * client → tRPC → Prisma → Postgres → tenant fetched → response.
+ * Returns the current tenant so the caller can confirm scoping works.
+ */
+ ping: protectedProcedure.query(async ({ ctx }) => {
+ // Tenant is not in TENANT_SCOPED_MODELS so the extension passes this
+ // through; we still go via ctx.db to keep call sites uniform.
+ const tenant = await ctx.db.tenant.findUnique({
+ where: { id: ctx.tenantId },
+ select: { id: true, name: true },
+ });
+
+ if (!tenant) {
+ throw new TRPCError({
+ code: 'NOT_FOUND',
+ message: `Tenant ${ctx.tenantId} not found`,
+ });
+ }
+
+ return {
+ ok: true as const,
+ tenant,
+ timestamp: new Date().toISOString(),
+ };
+ }),
+});
diff --git a/packages/api/src/trpc.ts b/packages/api/src/trpc.ts
new file mode 100644
index 0000000..1d78827
--- /dev/null
+++ b/packages/api/src/trpc.ts
@@ -0,0 +1,38 @@
+import { initTRPC, TRPCError } from '@trpc/server';
+import superjson from 'superjson';
+import { ZodError } from 'zod';
+import type { Context } from './context';
+
+const t = initTRPC.context().create({
+ transformer: superjson,
+ errorFormatter({ shape, error }) {
+ return {
+ ...shape,
+ data: {
+ ...shape.data,
+ zodError: error.cause instanceof ZodError ? error.cause.flatten() : null,
+ },
+ };
+ },
+});
+
+export const router = t.router;
+export const createCallerFactory = t.createCallerFactory;
+
+/** Public — no auth required. */
+export const publicProcedure = t.procedure;
+
+/** Protected — requires an authenticated session with a tenantId. */
+export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
+ if (!ctx.user || !ctx.db || !ctx.tenantId) {
+ throw new TRPCError({ code: 'UNAUTHORIZED', message: 'Not authenticated' });
+ }
+ return next({
+ ctx: {
+ ...ctx,
+ user: ctx.user,
+ db: ctx.db,
+ tenantId: ctx.tenantId,
+ },
+ });
+});
diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json
new file mode 100644
index 0000000..4675098
--- /dev/null
+++ b/packages/api/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@repo/config/tsconfig/base.json",
+ "compilerOptions": {
+ "noEmit": true,
+ "module": "ESNext",
+ "moduleResolution": "Bundler"
+ },
+ "include": ["src/**/*.ts"]
+}
diff --git a/packages/config/eslint/base.js b/packages/config/eslint/base.js
new file mode 100644
index 0000000..a94b2cd
--- /dev/null
+++ b/packages/config/eslint/base.js
@@ -0,0 +1,34 @@
+import js from '@eslint/js';
+import tseslint from 'typescript-eslint';
+import prettier from 'eslint-config-prettier';
+import globals from 'globals';
+
+/** @type {import("eslint").Linter.Config[]} */
+export default [
+ js.configs.recommended,
+ ...tseslint.configs.recommended,
+ prettier,
+ {
+ languageOptions: {
+ ecmaVersion: 2022,
+ sourceType: 'module',
+ globals: {
+ ...globals.node,
+ },
+ },
+ rules: {
+ '@typescript-eslint/no-unused-vars': [
+ 'error',
+ { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
+ ],
+ '@typescript-eslint/consistent-type-imports': [
+ 'warn',
+ { prefer: 'type-imports', fixStyle: 'inline-type-imports' },
+ ],
+ 'no-console': ['warn', { allow: ['warn', 'error'] }],
+ },
+ },
+ {
+ ignores: ['dist/**', '.next/**', '.turbo/**', 'node_modules/**', 'coverage/**'],
+ },
+];
diff --git a/packages/config/eslint/nextjs.js b/packages/config/eslint/nextjs.js
new file mode 100644
index 0000000..14835a3
--- /dev/null
+++ b/packages/config/eslint/nextjs.js
@@ -0,0 +1,23 @@
+import base from './base.js';
+import nextPlugin from '@next/eslint-plugin-next';
+import globals from 'globals';
+
+/** @type {import("eslint").Linter.Config[]} */
+export default [
+ ...base,
+ {
+ plugins: {
+ '@next/next': nextPlugin,
+ },
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ ...globals.node,
+ },
+ },
+ rules: {
+ ...nextPlugin.configs.recommended.rules,
+ ...nextPlugin.configs['core-web-vitals'].rules,
+ },
+ },
+];
diff --git a/packages/config/package.json b/packages/config/package.json
new file mode 100644
index 0000000..31ba570
--- /dev/null
+++ b/packages/config/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "@repo/config",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "exports": {
+ "./tsconfig/base.json": "./tsconfig/base.json",
+ "./tsconfig/nextjs.json": "./tsconfig/nextjs.json",
+ "./tsconfig/library.json": "./tsconfig/library.json",
+ "./eslint/base": "./eslint/base.js",
+ "./eslint/nextjs": "./eslint/nextjs.js",
+ "./tailwind/preset": "./tailwind/preset.cjs"
+ },
+ "files": [
+ "tsconfig",
+ "eslint",
+ "tailwind"
+ ],
+ "dependencies": {
+ "@eslint/js": "^9.17.0",
+ "@next/eslint-plugin-next": "^15.1.3",
+ "eslint": "^9.17.0",
+ "eslint-config-prettier": "^9.1.0",
+ "globals": "^15.14.0",
+ "tailwindcss": "^3.4.17",
+ "tailwindcss-animate": "^1.0.7",
+ "typescript-eslint": "^8.19.0"
+ }
+}
diff --git a/packages/config/tailwind/preset.cjs b/packages/config/tailwind/preset.cjs
new file mode 100644
index 0000000..1c2d36c
--- /dev/null
+++ b/packages/config/tailwind/preset.cjs
@@ -0,0 +1,63 @@
+/**
+ * Shared Tailwind v3 preset used by all apps and the UI package.
+ * shadcn/ui design tokens live here (HSL CSS variables consumed in globals.css).
+ */
+const animate = require('tailwindcss-animate');
+
+/** @type {import("tailwindcss").Config} */
+module.exports = {
+ darkMode: ['class'],
+ content: [],
+ theme: {
+ container: {
+ center: true,
+ padding: '1rem',
+ screens: {
+ '2xl': '1400px',
+ },
+ },
+ extend: {
+ colors: {
+ border: 'hsl(var(--border))',
+ input: 'hsl(var(--input))',
+ ring: 'hsl(var(--ring))',
+ background: 'hsl(var(--background))',
+ foreground: 'hsl(var(--foreground))',
+ primary: {
+ DEFAULT: 'hsl(var(--primary))',
+ foreground: 'hsl(var(--primary-foreground))',
+ },
+ secondary: {
+ DEFAULT: 'hsl(var(--secondary))',
+ foreground: 'hsl(var(--secondary-foreground))',
+ },
+ destructive: {
+ DEFAULT: 'hsl(var(--destructive))',
+ foreground: 'hsl(var(--destructive-foreground))',
+ },
+ muted: {
+ DEFAULT: 'hsl(var(--muted))',
+ foreground: 'hsl(var(--muted-foreground))',
+ },
+ accent: {
+ DEFAULT: 'hsl(var(--accent))',
+ foreground: 'hsl(var(--accent-foreground))',
+ },
+ popover: {
+ DEFAULT: 'hsl(var(--popover))',
+ foreground: 'hsl(var(--popover-foreground))',
+ },
+ card: {
+ DEFAULT: 'hsl(var(--card))',
+ foreground: 'hsl(var(--card-foreground))',
+ },
+ },
+ borderRadius: {
+ lg: 'var(--radius)',
+ md: 'calc(var(--radius) - 2px)',
+ sm: 'calc(var(--radius) - 4px)',
+ },
+ },
+ },
+ plugins: [animate],
+};
diff --git a/packages/config/tsconfig/base.json b/packages/config/tsconfig/base.json
new file mode 100644
index 0000000..e0805bc
--- /dev/null
+++ b/packages/config/tsconfig/base.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Base",
+ "compilerOptions": {
+ "target": "ES2022",
+ "lib": ["ES2022"],
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "moduleDetection": "force",
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "verbatimModuleSyntax": false,
+ "strict": true,
+ "noUncheckedIndexedAccess": true,
+ "noImplicitOverride": true,
+ "noFallthroughCasesInSwitch": true,
+ "forceConsistentCasingInFileNames": true,
+ "skipLibCheck": true
+ },
+ "exclude": ["node_modules", "dist", ".next", ".turbo"]
+}
diff --git a/packages/config/tsconfig/library.json b/packages/config/tsconfig/library.json
new file mode 100644
index 0000000..d6011dc
--- /dev/null
+++ b/packages/config/tsconfig/library.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Library",
+ "extends": "./base.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src/**/*.ts", "src/**/*.tsx"]
+}
diff --git a/packages/config/tsconfig/nextjs.json b/packages/config/tsconfig/nextjs.json
new file mode 100644
index 0000000..6234e3e
--- /dev/null
+++ b/packages/config/tsconfig/nextjs.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Next.js",
+ "extends": "./base.json",
+ "compilerOptions": {
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "jsx": "preserve",
+ "allowJs": true,
+ "noEmit": true,
+ "incremental": true,
+ "plugins": [{ "name": "next" }]
+ },
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules", ".next", "dist"]
+}
diff --git a/packages/db/package.json b/packages/db/package.json
new file mode 100644
index 0000000..4b46c06
--- /dev/null
+++ b/packages/db/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@repo/db",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "scripts": {
+ "postinstall": "prisma generate",
+ "seed": "tsx prisma/seed.ts",
+ "typecheck": "tsc --noEmit",
+ "clean": "rimraf .turbo node_modules"
+ },
+ "dependencies": {
+ "@prisma/client": "^6.1.0"
+ },
+ "devDependencies": {
+ "@repo/config": "workspace:*",
+ "dotenv": "^16.4.7",
+ "prisma": "^6.1.0",
+ "rimraf": "^6.0.1",
+ "tsx": "^4.19.2",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/packages/db/prisma.config.ts b/packages/db/prisma.config.ts
new file mode 100644
index 0000000..10e6d5f
--- /dev/null
+++ b/packages/db/prisma.config.ts
@@ -0,0 +1,17 @@
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { config as loadEnv } from 'dotenv';
+import { defineConfig } from 'prisma/config';
+
+// Load the repo-root .env so DATABASE_URL is visible when Prisma CLI runs
+// from inside packages/db. The .env file is intentionally kept at the repo
+// root (single source of truth, gitignored).
+const here = path.dirname(fileURLToPath(import.meta.url));
+loadEnv({ path: path.resolve(here, '../../.env') });
+
+export default defineConfig({
+ schema: path.join('prisma', 'schema.prisma'),
+ migrations: {
+ seed: 'tsx prisma/seed.ts',
+ },
+});
diff --git a/packages/db/prisma/migrations/20260516101022_init/migration.sql b/packages/db/prisma/migrations/20260516101022_init/migration.sql
new file mode 100644
index 0000000..53f4872
--- /dev/null
+++ b/packages/db/prisma/migrations/20260516101022_init/migration.sql
@@ -0,0 +1,78 @@
+-- CreateEnum
+CREATE TYPE "UserRole" AS ENUM ('ADMIN', 'SUPERVISOR', 'OPERATOR');
+
+-- CreateTable
+CREATE TABLE "Tenant" (
+ "id" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "Tenant_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "User" (
+ "id" TEXT NOT NULL,
+ "tenantId" TEXT NOT NULL,
+ "email" TEXT NOT NULL,
+ "passwordHash" TEXT,
+ "role" "UserRole" NOT NULL DEFAULT 'OPERATOR',
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "User_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Workstation" (
+ "id" TEXT NOT NULL,
+ "tenantId" TEXT NOT NULL,
+ "code" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "area" TEXT NOT NULL,
+
+ CONSTRAINT "Workstation_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "DomainEvent" (
+ "id" TEXT NOT NULL,
+ "tenantId" TEXT NOT NULL,
+ "aggregateType" TEXT NOT NULL,
+ "aggregateId" TEXT NOT NULL,
+ "eventType" TEXT NOT NULL,
+ "payload" JSONB NOT NULL,
+ "occurredAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "processedAt" TIMESTAMP(3),
+
+ CONSTRAINT "DomainEvent_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE INDEX "User_tenantId_idx" ON "User"("tenantId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "User_tenantId_email_key" ON "User"("tenantId", "email");
+
+-- CreateIndex
+CREATE INDEX "Workstation_tenantId_idx" ON "Workstation"("tenantId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Workstation_tenantId_code_key" ON "Workstation"("tenantId", "code");
+
+-- CreateIndex
+CREATE INDEX "DomainEvent_tenantId_idx" ON "DomainEvent"("tenantId");
+
+-- CreateIndex
+CREATE INDEX "DomainEvent_tenantId_processedAt_idx" ON "DomainEvent"("tenantId", "processedAt");
+
+-- CreateIndex
+CREATE INDEX "DomainEvent_tenantId_aggregateType_aggregateId_idx" ON "DomainEvent"("tenantId", "aggregateType", "aggregateId");
+
+-- AddForeignKey
+ALTER TABLE "User" ADD CONSTRAINT "User_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Workstation" ADD CONSTRAINT "Workstation_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "DomainEvent" ADD CONSTRAINT "DomainEvent_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/packages/db/prisma/migrations/migration_lock.toml b/packages/db/prisma/migrations/migration_lock.toml
new file mode 100644
index 0000000..044d57c
--- /dev/null
+++ b/packages/db/prisma/migrations/migration_lock.toml
@@ -0,0 +1,3 @@
+# Please do not edit this file manually
+# It should be added in your version-control system (e.g., Git)
+provider = "postgresql"
diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma
new file mode 100644
index 0000000..8a7ef60
--- /dev/null
+++ b/packages/db/prisma/schema.prisma
@@ -0,0 +1,74 @@
+// FieldOps — initial scaffold schema.
+//
+// All models except Tenant carry tenantId. Tenant scoping is enforced at runtime
+// by the Prisma extension in src/tenant-extension.ts — see that file's header for
+// the operations it covers and (more importantly) those it does NOT.
+
+generator client {
+ provider = "prisma-client-js"
+}
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+
+enum UserRole {
+ ADMIN
+ SUPERVISOR
+ OPERATOR
+}
+
+model Tenant {
+ id String @id @default(cuid())
+ name String
+ createdAt DateTime @default(now())
+
+ users User[]
+ workstations Workstation[]
+ events DomainEvent[]
+}
+
+model User {
+ id String @id @default(cuid())
+ tenantId String
+ email String
+ passwordHash String?
+ role UserRole @default(OPERATOR)
+ createdAt DateTime @default(now())
+
+ tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
+
+ @@unique([tenantId, email])
+ @@index([tenantId])
+}
+
+model Workstation {
+ id String @id @default(cuid())
+ tenantId String
+ code String
+ name String
+ area String
+
+ tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
+
+ @@unique([tenantId, code])
+ @@index([tenantId])
+}
+
+model DomainEvent {
+ id String @id @default(cuid())
+ tenantId String
+ aggregateType String
+ aggregateId String
+ eventType String
+ payload Json
+ occurredAt DateTime @default(now())
+ processedAt DateTime?
+
+ tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
+
+ @@index([tenantId])
+ @@index([tenantId, processedAt])
+ @@index([tenantId, aggregateType, aggregateId])
+}
diff --git a/packages/db/prisma/seed.ts b/packages/db/prisma/seed.ts
new file mode 100644
index 0000000..523dcf2
--- /dev/null
+++ b/packages/db/prisma/seed.ts
@@ -0,0 +1,55 @@
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { config as loadEnv } from 'dotenv';
+
+// Load repo-root .env so DATABASE_URL is visible when this script runs from
+// any CWD (pnpm invokes it from packages/db).
+const here = path.dirname(fileURLToPath(import.meta.url));
+loadEnv({ path: path.resolve(here, '../../../.env') });
+
+const { PrismaClient, UserRole } = await import('@prisma/client');
+const prisma = new PrismaClient();
+
+const DEMO_TENANT_NAME = 'Demo Factory';
+const DEMO_ADMIN_EMAIL = 'admin@demo.local';
+
+async function main() {
+ // Idempotent: if a prior run created the demo tenant, wipe it and recreate.
+ // Cascade deletes on the relations handle the children.
+ const existing = await prisma.tenant.findFirst({ where: { name: DEMO_TENANT_NAME } });
+ if (existing) {
+ await prisma.tenant.delete({ where: { id: existing.id } });
+ }
+
+ const tenant = await prisma.tenant.create({
+ data: { name: DEMO_TENANT_NAME },
+ });
+
+ await prisma.user.create({
+ data: {
+ tenantId: tenant.id,
+ email: DEMO_ADMIN_EMAIL,
+ role: UserRole.ADMIN,
+ },
+ });
+
+ await prisma.workstation.createMany({
+ data: [
+ { tenantId: tenant.id, code: 'WS-001', name: 'Assembly A', area: 'Floor 1' },
+ { tenantId: tenant.id, code: 'WS-002', name: 'Packaging B', area: 'Floor 2' },
+ ],
+ });
+
+ console.warn(
+ `Seed complete — tenant=${tenant.id} (${tenant.name}), admin=${DEMO_ADMIN_EMAIL}, workstations=2`,
+ );
+}
+
+main()
+ .catch((err) => {
+ console.error('Seed failed:', err);
+ process.exit(1);
+ })
+ .finally(async () => {
+ await prisma.$disconnect();
+ });
diff --git a/packages/db/src/client.ts b/packages/db/src/client.ts
new file mode 100644
index 0000000..7a7ea92
--- /dev/null
+++ b/packages/db/src/client.ts
@@ -0,0 +1,24 @@
+import { PrismaClient } from '@prisma/client';
+
+/**
+ * Singleton PrismaClient. In dev, Next's HMR causes module re-evaluation; the
+ * globalThis cache prevents leaking a new client per reload.
+ *
+ * This is the UNSCOPED root client. Application code MUST NOT use it directly
+ * for tenant-scoped reads/writes — always pass it through `tenantScoped(...)`
+ * with the tenantId from the request context.
+ */
+
+const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient };
+
+export const prisma =
+ globalForPrisma.prisma ??
+ new PrismaClient({
+ log: process.env.NODE_ENV === 'development' ? ['warn', 'error'] : ['error'],
+ });
+
+if (process.env.NODE_ENV !== 'production') {
+ globalForPrisma.prisma = prisma;
+}
+
+export type DbClient = typeof prisma;
diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts
new file mode 100644
index 0000000..47b84b0
--- /dev/null
+++ b/packages/db/src/index.ts
@@ -0,0 +1,4 @@
+export { prisma, type DbClient } from './client';
+export { tenantScoped, type TenantScopedClient } from './tenant-extension';
+export { Prisma, UserRole } from '@prisma/client';
+export type { User, Tenant, Workstation, DomainEvent } from '@prisma/client';
diff --git a/packages/db/src/tenant-extension.ts b/packages/db/src/tenant-extension.ts
new file mode 100644
index 0000000..e1a4068
--- /dev/null
+++ b/packages/db/src/tenant-extension.ts
@@ -0,0 +1,180 @@
+import type { PrismaClient } from '@prisma/client';
+
+/**
+ * ============================================================================
+ * Multi-tenant Prisma extension
+ * ============================================================================
+ *
+ * PURPOSE
+ * -------
+ * Guarantee that every read and write against a tenant-scoped model is
+ * filtered/stamped with the current tenantId, so application code can never
+ * accidentally cross tenant boundaries. Call this once per request from the
+ * tRPC context, passing the tenantId resolved from the authenticated session.
+ *
+ * const db = tenantScoped(prisma, ctx.tenantId);
+ * await db.workstation.findMany(); // implicitly WHERE tenantId = ctx.tenantId
+ *
+ * HOW TO EXTEND THIS
+ * ------------------
+ * Adding a new tenant-scoped model:
+ * 1. Add `tenantId String` + `@@index([tenantId])` in schema.prisma.
+ * 2. Add a relation to Tenant with `onDelete: Cascade`.
+ * 3. Add the model's PascalCase name to TENANT_SCOPED_MODELS below.
+ * 4. Run `pnpm db:migrate`.
+ *
+ * OPERATIONS INTERCEPTED
+ * ----------------------
+ * Reads : findFirst, findFirstOrThrow, findMany, count, aggregate, groupBy
+ * Writes : create, createMany, createManyAndReturn, update, updateMany,
+ * upsert, delete, deleteMany
+ * Special : findUnique / findUniqueOrThrow are DOWNGRADED to
+ * findFirst / findFirstOrThrow + tenantId filter.
+ *
+ * Reason: Prisma's findUnique only accepts where clauses that match
+ * a declared unique constraint. Adding tenantId to the where would
+ * either (a) require every @unique to be redeclared as
+ * @@unique([tenantId, ...]), or (b) fail Prisma's validation. The
+ * downgrade preserves tenant isolation at the cost of the runtime
+ * guarantee that the result is unique. If you specifically need
+ * "throw on multiple", use `findFirstOrThrow` with a where clause
+ * that you know is unique within the tenant (most commonly the
+ * compound `(tenantId, id)`).
+ *
+ * OPERATIONS NOT INTERCEPTED — THESE BYPASS TENANT SCOPING
+ * --------------------------------------------------------
+ * The following are intentionally left alone. They are the known holes in this
+ * guarantee and MUST be audited at PR-review time:
+ *
+ * 1. $queryRaw, $queryRawUnsafe, $executeRaw, $executeRawUnsafe
+ * Raw SQL bypasses the extension entirely. Always include the tenant
+ * filter explicitly:
+ * await db.$queryRaw`SELECT ... FROM "Workstation" WHERE "tenantId" = ${tenantId}`;
+ * Use raw SQL only for migrations, admin tooling, or aggregations the
+ * Prisma query engine cannot express.
+ *
+ * 2. $transaction (interactive callback form) when the callback receives a
+ * client OTHER than the scoped one returned by this function.
+ * The extension does not re-wrap the inner transactional client. Either:
+ * - issue all operations through the outer scoped client and use the
+ * sequential array form: `await db.$transaction([op1, op2])`, OR
+ * - if you need the interactive form, scope explicitly:
+ * await prisma.$transaction(async (tx) => {
+ * const scopedTx = tenantScoped(tx as PrismaClient, tenantId);
+ * ...
+ * });
+ *
+ * 3. Models without tenantId (currently only `Tenant`). These are passed
+ * through unchanged. Code touching Tenant must take care not to leak
+ * cross-tenant data through joins or includes from the tenant side.
+ *
+ * INVARIANTS THIS EXTENSION ENFORCES
+ * ----------------------------------
+ * - On every intercepted read, `where.tenantId` is set to the bound tenantId,
+ * OVERWRITING any tenantId the caller may have supplied. This is on purpose:
+ * callers must not be able to read other tenants' data even by mistake.
+ * - On `create` and `createMany`, the bound tenantId is injected into `data`,
+ * OVERWRITING any value the caller supplied — same reason.
+ * - On `update` and `upsert.update`, any attempt to set `tenantId` is silently
+ * dropped. Records cannot be re-homed across tenants through this path.
+ *
+ * CHANGELOG
+ * ---------
+ * 2026-05-16 — initial version (scaffold).
+ * ============================================================================
+ */
+
+const TENANT_SCOPED_MODELS = ['User', 'Workstation', 'DomainEvent'] as const;
+type TenantScopedModel = (typeof TENANT_SCOPED_MODELS)[number];
+
+function isTenantScoped(model: string | undefined): model is TenantScopedModel {
+ return !!model && (TENANT_SCOPED_MODELS as readonly string[]).includes(model);
+}
+
+function modelAccessor(model: string): string {
+ return model.charAt(0).toLowerCase() + model.slice(1);
+}
+
+export function tenantScoped(prisma: PrismaClient, tenantId: string) {
+ return prisma.$extends({
+ name: 'tenant-scope',
+ query: {
+ $allModels: {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ async $allOperations({ model, operation, args, query }: any) {
+ if (!isTenantScoped(model)) {
+ return query(args);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const a = args as any;
+
+ switch (operation) {
+ case 'findFirst':
+ case 'findFirstOrThrow':
+ case 'findMany':
+ case 'count':
+ case 'aggregate':
+ case 'groupBy':
+ case 'updateMany':
+ case 'deleteMany': {
+ a.where = { ...(a.where ?? {}), tenantId };
+ return query(a);
+ }
+
+ case 'findUnique':
+ case 'findUniqueOrThrow': {
+ // Downgrade to findFirst[OrThrow]. See header.
+ const target =
+ operation === 'findUnique' ? 'findFirst' : 'findFirstOrThrow';
+ const where = { ...(a.where ?? {}), tenantId };
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const delegate = (prisma as any)[modelAccessor(model)];
+ return delegate[target]({ ...a, where });
+ }
+
+ case 'create': {
+ a.data = { ...(a.data ?? {}), tenantId };
+ return query(a);
+ }
+
+ case 'createMany':
+ case 'createManyAndReturn': {
+ const data = a.data;
+ if (Array.isArray(data)) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ a.data = data.map((d: any) => ({ ...d, tenantId }));
+ } else {
+ a.data = { ...(data ?? {}), tenantId };
+ }
+ return query(a);
+ }
+
+ case 'update': {
+ a.where = { ...(a.where ?? {}), tenantId };
+ if (a.data && 'tenantId' in a.data) delete a.data.tenantId;
+ return query(a);
+ }
+
+ case 'upsert': {
+ a.where = { ...(a.where ?? {}), tenantId };
+ a.create = { ...(a.create ?? {}), tenantId };
+ if (a.update && 'tenantId' in a.update) delete a.update.tenantId;
+ return query(a);
+ }
+
+ case 'delete': {
+ a.where = { ...(a.where ?? {}), tenantId };
+ return query(a);
+ }
+
+ default:
+ return query(args);
+ }
+ },
+ },
+ },
+ });
+}
+
+export type TenantScopedClient = ReturnType;
diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json
new file mode 100644
index 0000000..e204062
--- /dev/null
+++ b/packages/db/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@repo/config/tsconfig/base.json",
+ "compilerOptions": {
+ "noEmit": true,
+ "module": "ESNext",
+ "moduleResolution": "Bundler"
+ },
+ "include": ["src/**/*.ts", "prisma/**/*.ts"]
+}
diff --git a/packages/domain/package.json b/packages/domain/package.json
new file mode 100644
index 0000000..1ba2b59
--- /dev/null
+++ b/packages/domain/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "@repo/domain",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "scripts": {
+ "typecheck": "tsc --noEmit",
+ "clean": "rimraf .turbo node_modules"
+ },
+ "devDependencies": {
+ "@repo/config": "workspace:*",
+ "rimraf": "^6.0.1",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/packages/domain/src/index.ts b/packages/domain/src/index.ts
new file mode 100644
index 0000000..1098afd
--- /dev/null
+++ b/packages/domain/src/index.ts
@@ -0,0 +1,4 @@
+// Pure domain logic lives here — no I/O, no framework imports.
+// Intentionally empty in this scaffold phase; populate as business rules emerge.
+
+export {};
diff --git a/packages/domain/tsconfig.json b/packages/domain/tsconfig.json
new file mode 100644
index 0000000..4675098
--- /dev/null
+++ b/packages/domain/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@repo/config/tsconfig/base.json",
+ "compilerOptions": {
+ "noEmit": true,
+ "module": "ESNext",
+ "moduleResolution": "Bundler"
+ },
+ "include": ["src/**/*.ts"]
+}
diff --git a/packages/ui/package.json b/packages/ui/package.json
new file mode 100644
index 0000000..fe3bfb5
--- /dev/null
+++ b/packages/ui/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "@repo/ui",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/index.ts",
+ "exports": {
+ ".": "./src/index.ts",
+ "./styles.css": "./src/styles.css",
+ "./lib/utils": "./src/lib/utils.ts",
+ "./components/*": "./src/components/*.tsx"
+ },
+ "scripts": {
+ "typecheck": "tsc --noEmit",
+ "clean": "rimraf .turbo node_modules"
+ },
+ "dependencies": {
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "lucide-react": "^0.469.0",
+ "tailwind-merge": "^2.5.5"
+ },
+ "peerDependencies": {
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0"
+ },
+ "devDependencies": {
+ "@repo/config": "workspace:*",
+ "@types/react": "^19.0.2",
+ "@types/react-dom": "^19.0.2",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "rimraf": "^6.0.1",
+ "typescript": "^5.7.2"
+ }
+}
diff --git a/packages/ui/src/components/alert.tsx b/packages/ui/src/components/alert.tsx
new file mode 100644
index 0000000..14ccd64
--- /dev/null
+++ b/packages/ui/src/components/alert.tsx
@@ -0,0 +1,47 @@
+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',
+ },
+ },
+);
+
+export const Alert = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes & VariantProps
+>(({ className, variant, ...props }, ref) => (
+
+));
+Alert.displayName = 'Alert';
+
+export const AlertTitle = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+AlertTitle.displayName = 'AlertTitle';
+
+export const AlertDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+AlertDescription.displayName = 'AlertDescription';
diff --git a/packages/ui/src/components/button.tsx b/packages/ui/src/components/button.tsx
new file mode 100644
index 0000000..b66d5fa
--- /dev/null
+++ b/packages/ui/src/components/button.tsx
@@ -0,0 +1,42 @@
+import * as React from 'react';
+import { cva, type VariantProps } from 'class-variance-authority';
+import { cn } from '../lib/utils';
+
+const buttonVariants = cva(
+ 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
+ {
+ variants: {
+ variant: {
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
+ destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
+ outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
+ secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
+ link: 'text-primary underline-offset-4 hover:underline',
+ },
+ size: {
+ default: 'h-10 px-4 py-2',
+ sm: 'h-9 rounded-md px-3',
+ lg: 'h-11 rounded-md px-8',
+ icon: 'h-10 w-10',
+ },
+ },
+ defaultVariants: {
+ variant: 'default',
+ size: 'default',
+ },
+ },
+);
+
+export interface ButtonProps
+ extends React.ButtonHTMLAttributes,
+ VariantProps {}
+
+export const Button = React.forwardRef(
+ ({ className, variant, size, ...props }, ref) => (
+
+ ),
+);
+Button.displayName = 'Button';
+
+export { buttonVariants };
diff --git a/packages/ui/src/components/card.tsx b/packages/ui/src/components/card.tsx
new file mode 100644
index 0000000..23e3da8
--- /dev/null
+++ b/packages/ui/src/components/card.tsx
@@ -0,0 +1,54 @@
+import * as React from 'react';
+import { cn } from '../lib/utils';
+
+export const Card = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+Card.displayName = 'Card';
+
+export const CardHeader = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+CardHeader.displayName = 'CardHeader';
+
+export const CardTitle = React.forwardRef<
+ HTMLHeadingElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardTitle.displayName = 'CardTitle';
+
+export const CardDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardDescription.displayName = 'CardDescription';
+
+export const CardContent = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+CardContent.displayName = 'CardContent';
+
+export const CardFooter = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+CardFooter.displayName = 'CardFooter';
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
new file mode 100644
index 0000000..e3b1b18
--- /dev/null
+++ b/packages/ui/src/index.ts
@@ -0,0 +1,11 @@
+export { cn } from './lib/utils';
+export { Button, buttonVariants, type ButtonProps } from './components/button';
+export {
+ Card,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+ CardContent,
+ CardFooter,
+} from './components/card';
+export { Alert, AlertTitle, AlertDescription } from './components/alert';
diff --git a/packages/ui/src/lib/utils.ts b/packages/ui/src/lib/utils.ts
new file mode 100644
index 0000000..2819a83
--- /dev/null
+++ b/packages/ui/src/lib/utils.ts
@@ -0,0 +1,6 @@
+import { clsx, type ClassValue } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
diff --git a/packages/ui/src/styles.css b/packages/ui/src/styles.css
new file mode 100644
index 0000000..d2a59ce
--- /dev/null
+++ b/packages/ui/src/styles.css
@@ -0,0 +1,61 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
+ --primary: 222.2 47.4% 11.2%;
+ --primary-foreground: 210 40% 98%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 222.2 84% 4.9%;
+ --radius: 0.5rem;
+ }
+
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
+ --primary: 210 40% 98%;
+ --primary-foreground: 222.2 47.4% 11.2%;
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 212.7 26.8% 83.9%;
+ }
+
+ * {
+ @apply border-border;
+ }
+
+ body {
+ @apply bg-background text-foreground;
+ font-feature-settings:
+ 'rlig' 1,
+ 'calt' 1;
+ }
+}
diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json
new file mode 100644
index 0000000..bb1c4b9
--- /dev/null
+++ b/packages/ui/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@repo/config/tsconfig/base.json",
+ "compilerOptions": {
+ "noEmit": true,
+ "jsx": "preserve",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "moduleResolution": "Bundler"
+ },
+ "include": ["src/**/*.ts", "src/**/*.tsx"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..05719ea
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,3663 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ devDependencies:
+ '@repo/config':
+ specifier: workspace:*
+ version: link:packages/config
+ prettier:
+ specifier: ^3.4.2
+ version: 3.8.3
+ prettier-plugin-tailwindcss:
+ specifier: ^0.6.9
+ version: 0.6.14(prettier@3.8.3)
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ turbo:
+ specifier: ^2.3.3
+ version: 2.9.14
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ apps/admin-web:
+ dependencies:
+ next:
+ specifier: ^15.1.3
+ version: 15.5.18(@playwright/test@1.60.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ react:
+ specifier: ^19.0.0
+ version: 19.2.6
+ react-dom:
+ specifier: ^19.0.0
+ version: 19.2.6(react@19.2.6)
+ devDependencies:
+ '@repo/config':
+ specifier: workspace:*
+ version: link:../../packages/config
+ '@types/node':
+ specifier: ^22.10.2
+ version: 22.19.19
+ '@types/react':
+ specifier: ^19.0.2
+ version: 19.2.14
+ '@types/react-dom':
+ specifier: ^19.0.2
+ version: 19.2.3(@types/react@19.2.14)
+ dotenv-cli:
+ specifier: ^8.0.0
+ version: 8.0.0
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ apps/operator-pwa:
+ dependencies:
+ '@repo/api':
+ specifier: workspace:*
+ version: link:../../packages/api
+ '@repo/db':
+ specifier: workspace:*
+ version: link:../../packages/db
+ '@repo/domain':
+ specifier: workspace:*
+ version: link:../../packages/domain
+ '@repo/ui':
+ specifier: workspace:*
+ version: link:../../packages/ui
+ '@t3-oss/env-nextjs':
+ specifier: ^0.11.1
+ version: 0.11.1(typescript@5.9.3)(zod@3.25.76)
+ '@tanstack/react-query':
+ specifier: ^5.62.10
+ version: 5.100.10(react@19.2.6)
+ '@trpc/client':
+ specifier: ^11.0.0
+ version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
+ '@trpc/react-query':
+ specifier: ^11.0.0
+ version: 11.17.0(@tanstack/react-query@5.100.10(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)
+ '@trpc/server':
+ specifier: ^11.0.0
+ version: 11.17.0(typescript@5.9.3)
+ lucide-react:
+ specifier: ^0.469.0
+ version: 0.469.0(react@19.2.6)
+ next:
+ specifier: ^15.1.3
+ version: 15.5.18(@playwright/test@1.60.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ next-auth:
+ specifier: 5.0.0-beta.25
+ version: 5.0.0-beta.25(next@15.5.18(@playwright/test@1.60.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)
+ pino:
+ specifier: ^9.5.0
+ version: 9.14.0
+ pino-pretty:
+ specifier: ^11.3.0
+ version: 11.3.0
+ react:
+ specifier: ^19.0.0
+ version: 19.2.6
+ react-dom:
+ specifier: ^19.0.0
+ version: 19.2.6(react@19.2.6)
+ superjson:
+ specifier: ^2.2.2
+ version: 2.2.6
+ zod:
+ specifier: ^3.24.1
+ version: 3.25.76
+ devDependencies:
+ '@repo/config':
+ specifier: workspace:*
+ version: link:../../packages/config
+ '@types/node':
+ specifier: ^22.10.2
+ version: 22.19.19
+ '@types/react':
+ specifier: ^19.0.2
+ version: 19.2.14
+ '@types/react-dom':
+ specifier: ^19.0.2
+ version: 19.2.3(@types/react@19.2.14)
+ autoprefixer:
+ specifier: ^10.4.20
+ version: 10.5.0(postcss@8.5.14)
+ dotenv-cli:
+ specifier: ^8.0.0
+ version: 8.0.0
+ postcss:
+ specifier: ^8.4.49
+ version: 8.5.14
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ tailwindcss:
+ specifier: ^3.4.17
+ version: 3.4.19(tsx@4.22.0)
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ e2e:
+ devDependencies:
+ '@playwright/test':
+ specifier: ^1.49.1
+ version: 1.60.0
+ '@repo/config':
+ specifier: workspace:*
+ version: link:../packages/config
+ '@types/node':
+ specifier: ^22.10.2
+ version: 22.19.19
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ packages/api:
+ dependencies:
+ '@repo/db':
+ specifier: workspace:*
+ version: link:../db
+ '@trpc/server':
+ specifier: ^11.0.0
+ version: 11.17.0(typescript@5.9.3)
+ pino:
+ specifier: ^9.5.0
+ version: 9.14.0
+ superjson:
+ specifier: ^2.2.2
+ version: 2.2.6
+ zod:
+ specifier: ^3.24.1
+ version: 3.25.76
+ devDependencies:
+ '@repo/config':
+ specifier: workspace:*
+ version: link:../config
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ packages/config:
+ dependencies:
+ '@eslint/js':
+ specifier: ^9.17.0
+ version: 9.39.4
+ '@next/eslint-plugin-next':
+ specifier: ^15.1.3
+ version: 15.5.18
+ eslint:
+ specifier: ^9.17.0
+ version: 9.39.4(jiti@2.7.0)
+ eslint-config-prettier:
+ specifier: ^9.1.0
+ version: 9.1.2(eslint@9.39.4(jiti@2.7.0))
+ globals:
+ specifier: ^15.14.0
+ version: 15.15.0
+ tailwindcss:
+ specifier: ^3.4.17
+ version: 3.4.19(tsx@4.22.0)
+ tailwindcss-animate:
+ specifier: ^1.0.7
+ version: 1.0.7(tailwindcss@3.4.19(tsx@4.22.0))
+ typescript-eslint:
+ specifier: ^8.19.0
+ version: 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+
+ packages/db:
+ dependencies:
+ '@prisma/client':
+ specifier: ^6.1.0
+ version: 6.19.3(prisma@6.19.3(typescript@5.9.3))(typescript@5.9.3)
+ devDependencies:
+ '@repo/config':
+ specifier: workspace:*
+ version: link:../config
+ dotenv:
+ specifier: ^16.4.7
+ version: 16.6.1
+ prisma:
+ specifier: ^6.1.0
+ version: 6.19.3(typescript@5.9.3)
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ tsx:
+ specifier: ^4.19.2
+ version: 4.22.0
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ packages/domain:
+ devDependencies:
+ '@repo/config':
+ specifier: workspace:*
+ version: link:../config
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+ packages/ui:
+ dependencies:
+ class-variance-authority:
+ specifier: ^0.7.1
+ version: 0.7.1
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ lucide-react:
+ specifier: ^0.469.0
+ version: 0.469.0(react@19.2.6)
+ tailwind-merge:
+ specifier: ^2.5.5
+ version: 2.6.1
+ devDependencies:
+ '@repo/config':
+ specifier: workspace:*
+ version: link:../config
+ '@types/react':
+ specifier: ^19.0.2
+ version: 19.2.14
+ '@types/react-dom':
+ specifier: ^19.0.2
+ version: 19.2.3(@types/react@19.2.14)
+ react:
+ specifier: ^19.0.0
+ version: 19.2.6
+ react-dom:
+ specifier: ^19.0.0
+ version: 19.2.6(react@19.2.6)
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.1.3
+ typescript:
+ specifier: ^5.7.2
+ version: 5.9.3
+
+packages:
+
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ '@auth/core@0.37.2':
+ resolution: {integrity: sha512-kUvzyvkcd6h1vpeMAojK2y7+PAV5H+0Cc9+ZlKYDFhDY31AlvsB+GW5vNO4qE3Y07KeQgvNO9U0QUx/fN62kBw==}
+ peerDependencies:
+ '@simplewebauthn/browser': ^9.0.1
+ '@simplewebauthn/server': ^9.0.2
+ nodemailer: ^6.8.0
+ peerDependenciesMeta:
+ '@simplewebauthn/browser':
+ optional: true
+ '@simplewebauthn/server':
+ optional: true
+ nodemailer:
+ optional: true
+
+ '@emnapi/runtime@1.10.0':
+ resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
+
+ '@esbuild/aix-ppc64@0.28.0':
+ resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.28.0':
+ resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.28.0':
+ resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.28.0':
+ resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.28.0':
+ resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.28.0':
+ resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.28.0':
+ resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.28.0':
+ resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.28.0':
+ resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.28.0':
+ resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.28.0':
+ resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.28.0':
+ resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.28.0':
+ resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.28.0':
+ resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.28.0':
+ resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.28.0':
+ resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.28.0':
+ resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.28.0':
+ resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.28.0':
+ resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.28.0':
+ resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.28.0':
+ resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.28.0':
+ resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.28.0':
+ resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.28.0':
+ resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.28.0':
+ resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.28.0':
+ resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@eslint-community/eslint-utils@4.9.1':
+ resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+ '@eslint-community/regexpp@4.12.2':
+ resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ '@eslint/config-array@0.21.2':
+ resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/config-helpers@0.4.2':
+ resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/core@0.17.0':
+ resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/eslintrc@3.3.5':
+ resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/js@9.39.4':
+ resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/object-schema@2.1.7':
+ resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/plugin-kit@0.4.1':
+ resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@humanfs/core@0.19.2':
+ resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/node@0.16.8':
+ resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/types@0.15.0':
+ resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/retry@0.4.3':
+ resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
+ engines: {node: '>=18.18'}
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@next/env@15.5.18':
+ resolution: {integrity: sha512-hAV85Ckd9QR6RvH04MEKwsfLTksvFpO47j9xwtoIuvuPnlwecpSi+uZTtm8HirVbtlI2Fnz//xpcSTjFdyJk+g==}
+
+ '@next/eslint-plugin-next@15.5.18':
+ resolution: {integrity: sha512-w4MYq8M26a8PNrfto0JosLf5/3ssln1rsyP96g2DkC8uFVymStM5DLSz5ElxxrPRg2XnTMnFo3kREFlhYvxhWw==}
+
+ '@next/swc-darwin-arm64@15.5.18':
+ resolution: {integrity: sha512-w0WvQf1n+txiwns/9pwIQteCJpZTbxzO2SE0FLcwuD4v0WEh1JPOjdyxWL21XwJsdpx8cFRjyzxzCS/siP7HcQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@15.5.18':
+ resolution: {integrity: sha512-znn71QmDuxm+BOaglihMZfvyySMnNljkVIY5Z2TCssBmm+WqL6c19VhtH5ktFkHa8EZ2bnTUpcNcmNSQsg67og==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@15.5.18':
+ resolution: {integrity: sha512-yPPe5MNL+igZUa+OsqQJisqSfh6oarIuA1Q0BDxljGJhRQyZeP+WRHh7rs/jZUGMh5aY0YdIjXZG0VohkKkUdw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-arm64-musl@15.5.18':
+ resolution: {integrity: sha512-glaCczEWIrHsokFZ3pP08U4BpKxwIdnT+txdOM32OBgpL9Yw4aqx8NejmgtZQZOdstQ5f0L3CasIZudzCuD+nw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-x64-gnu@15.5.18':
+ resolution: {integrity: sha512-oUfg2EgJmU3R0OCOWiokGFUTvZiPfXtriXiuF3YNxRoROCdgvTedHIzYoeKH34gsZxS/V7mHbfq2hpAHwhH1/A==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-x64-musl@15.5.18':
+ resolution: {integrity: sha512-JLxSP3KTd9iu/bvUMQxH7RJo9xKSHf55/6RPE4a6FTSZygGn7uvZbCej0AHXydwkggQGSD9UddSjwv6Xz5ESfA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-win32-arm64-msvc@15.5.18':
+ resolution: {integrity: sha512-ir1v7enP52K2HNz3tQQvwF+x7VNxBk1ciiZ18WBPvxf4C59IqdfmHPJYK3vH7rSxpuCVw/8C712wTXNAtEp+NA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@15.5.18':
+ resolution: {integrity: sha512-LIu5me6QTANCd25E7I5uIEfvgQ06RK7tvHAbYo3zCb3VpxQEPvMcSpd87NwUABDT6MbGPdEGR5VRiK4PPTJhQg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@panva/hkdf@1.2.1':
+ resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==}
+
+ '@pinojs/redact@0.4.0':
+ resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
+
+ '@playwright/test@1.60.0':
+ resolution: {integrity: sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ '@prisma/client@6.19.3':
+ resolution: {integrity: sha512-mKq3jQFhjvko5LTJFHGilsuQs+W+T3Gm451NzuTDGQxwCzwXHYnIu2zGkRoW+Exq3Rob7yp2MfzSrdIiZVhrBg==}
+ engines: {node: '>=18.18'}
+ peerDependencies:
+ prisma: '*'
+ typescript: '>=5.1.0'
+ peerDependenciesMeta:
+ prisma:
+ optional: true
+ typescript:
+ optional: true
+
+ '@prisma/config@6.19.3':
+ resolution: {integrity: sha512-CBPT44BjlQxEt8kiMEauji2WHTDoVBOKl7UlewXmUgBPnr/oPRZC3psci5chJnYmH0ivEIog2OU9PGWoki3DLQ==}
+
+ '@prisma/debug@6.19.3':
+ resolution: {integrity: sha512-ljkJ+SgpXNktLG0Q/n4JGYCkKf0f8oYLyjImS2I8e2q2WCfdRRtWER062ZV/ixaNP2M2VKlWXVJiGzZaUgbKZw==}
+
+ '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7':
+ resolution: {integrity: sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==}
+
+ '@prisma/engines@6.19.3':
+ resolution: {integrity: sha512-RSYxtlYFl5pJ8ZePgMv0lZ9IzVCOdTPOegrs2qcbAEFrBI1G33h6wyC9kjQvo0DnYEhEVY0X4LsuFHXLKQk88g==}
+
+ '@prisma/fetch-engine@6.19.3':
+ resolution: {integrity: sha512-tKtl/qco9Nt7LU5iKhpultD8O4vMCZcU2CHjNTnRrL1QvSUr5W/GcyFPjNL87GtRrwBc7ubXXD9xy4EvLvt8JA==}
+
+ '@prisma/get-platform@6.19.3':
+ resolution: {integrity: sha512-xFj1VcJ1N3MKooOQAGO0W5tsd0W2QzIvW7DD7c/8H14Zmp4jseeWAITm+w2LLoLrlhoHdPPh0NMZ8mfL6puoHA==}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@swc/helpers@0.5.15':
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+
+ '@t3-oss/env-core@0.11.1':
+ resolution: {integrity: sha512-MaxOwEoG1ntCFoKJsS7nqwgcxLW1SJw238AJwfJeaz3P/8GtkxXZsPPolsz1AdYvUTbe3XvqZ/VCdfjt+3zmKw==}
+ peerDependencies:
+ typescript: '>=5.0.0'
+ zod: ^3.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@t3-oss/env-nextjs@0.11.1':
+ resolution: {integrity: sha512-rx2XL9+v6wtOqLNJbD5eD8OezKlQD1BtC0WvvtHwBgK66jnF5+wGqtgkKK4Ygie1LVmoDClths2T4tdFmRvGrQ==}
+ peerDependencies:
+ typescript: '>=5.0.0'
+ zod: ^3.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@tanstack/query-core@5.100.10':
+ resolution: {integrity: sha512-8UR0yJR+GiQ40m3lPhUr0xbfAupe6GSQiksSBSa9SM2NjezFyxXCIA69/lz8cSoNKZLrw1/PktIyQBJcVeMi3w==}
+
+ '@tanstack/react-query@5.100.10':
+ resolution: {integrity: sha512-FLaZf2RCrA/Zgp4aiu5tG3TyasTRO7aZ99skxQpr3Hg/zXOhu6yq5FZCYQ/tRaJtM9ylnoK8tFK7PolXQadv6Q==}
+ peerDependencies:
+ react: ^18 || ^19
+
+ '@trpc/client@11.17.0':
+ resolution: {integrity: sha512-KpJBFrbKTDeVCFv/3ckL1XBBH5Yssn8hethI/rUy7GIpTj+VzjtPjykDqJpzobuVOz+d26cXCSu1t4I6MYI5Zg==}
+ hasBin: true
+ peerDependencies:
+ '@trpc/server': 11.17.0
+ typescript: '>=5.7.2'
+
+ '@trpc/react-query@11.17.0':
+ resolution: {integrity: sha512-AGcl5YAF8NnhBmyJ6PqJqKb1M5VTGSoNRNqJ3orct4o4epdcg0GWhW+qT9q6gPzs/2ImIwYCdfFpgNGdZ9yLHA==}
+ peerDependencies:
+ '@tanstack/react-query': ^5.80.3
+ '@trpc/client': 11.17.0
+ '@trpc/server': 11.17.0
+ react: '>=18.2.0'
+ typescript: '>=5.7.2'
+
+ '@trpc/server@11.17.0':
+ resolution: {integrity: sha512-jbAOUe0PpUTCYqziyu+8vYXZdDXPudZgnEhWCQ2NjKnVEjfE93RqHTt1oycZJv/HNf51YlRXfEEwSIAbb161rw==}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.7.2'
+
+ '@turbo/darwin-64@2.9.14':
+ resolution: {integrity: sha512-t7QiPflaEyBE4oayeZtSmu4mEfjgIrcNlNNl1z1dmIVPqEdtA7+CfTf8d7KXsOGPh6aNgWjKxyvQg9uGfDQF+A==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@turbo/darwin-arm64@2.9.14':
+ resolution: {integrity: sha512-d23147mC9BsCPA9mJ0h/ubcpbRgcJBXbcG3+Vq7YLhjz3IXuvQsJ1UXH8f4MD76ZjJ4m/E4aRdJV+MW88CDfbw==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@turbo/linux-64@2.9.14':
+ resolution: {integrity: sha512-P3ZKB5tuUDdDQWuAsACGUR1qv9W7BNWxdxqVJ0kZNuNNPRaVYTPPikLcp79+GiEcW3npsR+KyP38lnQiBc5aSA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@turbo/linux-arm64@2.9.14':
+ resolution: {integrity: sha512-ZRTlzcUMrrPv9ZuDzRF9n60Ym13bKeG9jDB8WjxyLhWNzV+AJQN+zdpIk3NJYf2zQsGUm1mNar2P0elRzLw25g==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@turbo/windows-64@2.9.14':
+ resolution: {integrity: sha512-exanwN6sIduZwykYeiTQj8kCmOhazP5WOz3bvXMcYtjhL6Z3iRWLewKrXCBq0bqwSP3iBMb/AerRCnHI4lx46A==}
+ cpu: [x64]
+ os: [win32]
+
+ '@turbo/windows-arm64@2.9.14':
+ resolution: {integrity: sha512-fVdCsnmYoKICsycbWuuGp6Jvi51/3G/UluFWuAUCvR8PIW5IJkAk5BM9UF8PSm0Q2IphWHFZjYEgjHsh3B9y/g==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@types/cookie@0.6.0':
+ resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/node@22.19.19':
+ resolution: {integrity: sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==}
+
+ '@types/react-dom@19.2.3':
+ resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
+ peerDependencies:
+ '@types/react': ^19.2.0
+
+ '@types/react@19.2.14':
+ resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
+
+ '@typescript-eslint/eslint-plugin@8.59.3':
+ resolution: {integrity: sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^8.59.3
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/parser@8.59.3':
+ resolution: {integrity: sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/project-service@8.59.3':
+ resolution: {integrity: sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/scope-manager@8.59.3':
+ resolution: {integrity: sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/tsconfig-utils@8.59.3':
+ resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/type-utils@8.59.3':
+ resolution: {integrity: sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/types@8.59.3':
+ resolution: {integrity: sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/typescript-estree@8.59.3':
+ resolution: {integrity: sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/utils@8.59.3':
+ resolution: {integrity: sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ '@typescript-eslint/visitor-keys@8.59.3':
+ resolution: {integrity: sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ abort-controller@3.0.0:
+ resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
+ engines: {node: '>=6.5'}
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.16.0:
+ resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv@6.15.0:
+ resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ atomic-sleep@1.0.0:
+ resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
+ engines: {node: '>=8.0.0'}
+
+ autoprefixer@10.5.0:
+ resolution: {integrity: sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
+ baseline-browser-mapping@2.10.29:
+ resolution: {integrity: sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ brace-expansion@1.1.14:
+ resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==}
+
+ brace-expansion@5.0.6:
+ resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
+ engines: {node: 18 || 20 || >=22}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.28.2:
+ resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ buffer@6.0.3:
+ resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
+
+ c12@3.1.0:
+ resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==}
+ peerDependencies:
+ magicast: ^0.3.5
+ peerDependenciesMeta:
+ magicast:
+ optional: true
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ caniuse-lite@1.0.30001792:
+ resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ citty@0.1.6:
+ resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
+
+ citty@0.2.2:
+ resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==}
+
+ class-variance-authority@0.7.1:
+ resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
+
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ colorette@2.0.20:
+ resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ confbox@0.2.4:
+ resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
+
+ consola@3.4.2:
+ resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
+ engines: {node: ^14.18.0 || >=16.10.0}
+
+ cookie@0.7.1:
+ resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
+ engines: {node: '>= 0.6'}
+
+ copy-anything@4.0.5:
+ resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
+ engines: {node: '>=18'}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ dateformat@4.6.3:
+ resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ deepmerge-ts@7.1.5:
+ resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==}
+ engines: {node: '>=16.0.0'}
+
+ defu@6.1.7:
+ resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
+
+ destr@2.0.5:
+ resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ dotenv-cli@8.0.0:
+ resolution: {integrity: sha512-aLqYbK7xKOiTMIRf1lDPbI+Y+Ip/wo5k3eyp6ePysVaSqbyxjyK3dK35BTxG+rmd7djf5q2UPs4noPNH+cj0Qw==}
+ hasBin: true
+
+ dotenv-expand@10.0.0:
+ resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==}
+ engines: {node: '>=12'}
+
+ dotenv@16.6.1:
+ resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
+ engines: {node: '>=12'}
+
+ effect@3.21.0:
+ resolution: {integrity: sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==}
+
+ electron-to-chromium@1.5.356:
+ resolution: {integrity: sha512-9NgFd7m5t5MCJ5rUSjJITUXAH9mEGlrlofnMf4YEr+pz6JlP7cWmTAH+JFmbPnaSW8koVTkuW7pacORWAnA5Yw==}
+
+ empathic@2.0.0:
+ resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==}
+ engines: {node: '>=14'}
+
+ end-of-stream@1.4.5:
+ resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.28.0:
+ resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ eslint-config-prettier@9.1.2:
+ resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==}
+ hasBin: true
+ peerDependencies:
+ eslint: '>=7.0.0'
+
+ eslint-scope@8.4.0:
+ resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@4.2.1:
+ resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-visitor-keys@5.0.1:
+ resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24}
+
+ eslint@9.39.4:
+ resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ hasBin: true
+ peerDependencies:
+ jiti: '*'
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+
+ espree@10.4.0:
+ resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ esquery@1.7.0:
+ resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ event-target-shim@5.0.1:
+ resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
+ engines: {node: '>=6'}
+
+ events@3.3.0:
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+ engines: {node: '>=0.8.x'}
+
+ exsolve@1.0.8:
+ resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
+
+ fast-check@3.23.2:
+ resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
+ engines: {node: '>=8.0.0'}
+
+ fast-copy@3.0.2:
+ resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fast-safe-stringify@2.1.1:
+ resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
+
+ fastq@1.20.1:
+ resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ file-entry-cache@8.0.0:
+ resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+ engines: {node: '>=16.0.0'}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ flat-cache@4.0.1:
+ resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+ engines: {node: '>=16'}
+
+ flatted@3.4.2:
+ resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
+
+ fraction.js@5.3.4:
+ resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
+
+ fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ giget@2.0.0:
+ resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
+ hasBin: true
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob@13.0.6:
+ resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
+ engines: {node: 18 || 20 || >=22}
+
+ globals@14.0.0:
+ resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
+ engines: {node: '>=18'}
+
+ globals@15.15.0:
+ resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==}
+ engines: {node: '>=18'}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ hasown@2.0.3:
+ resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==}
+ engines: {node: '>= 0.4'}
+
+ help-me@5.0.0:
+ resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==}
+
+ ieee754@1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ ignore@7.0.5:
+ resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
+ engines: {node: '>= 4'}
+
+ import-fresh@3.3.1:
+ resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
+ engines: {node: '>=6'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-core-module@2.16.2:
+ resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-what@5.5.0:
+ resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==}
+ engines: {node: '>=18'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jiti@1.21.7:
+ resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
+ hasBin: true
+
+ jiti@2.7.0:
+ resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
+ hasBin: true
+
+ jose@5.10.0:
+ resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==}
+
+ joycon@3.1.1:
+ resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
+ engines: {node: '>=10'}
+
+ js-yaml@4.1.1:
+ resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
+ hasBin: true
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ lilconfig@3.1.3:
+ resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ lru-cache@11.3.6:
+ resolution: {integrity: sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==}
+ engines: {node: 20 || >=22}
+
+ lucide-react@0.469.0:
+ resolution: {integrity: sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==}
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ minimatch@10.2.5:
+ resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ engines: {node: 18 || 20 || >=22}
+
+ minimatch@3.1.5:
+ resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ nanoid@3.3.12:
+ resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ next-auth@5.0.0-beta.25:
+ resolution: {integrity: sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog==}
+ peerDependencies:
+ '@simplewebauthn/browser': ^9.0.1
+ '@simplewebauthn/server': ^9.0.2
+ next: ^14.0.0-0 || ^15.0.0-0
+ nodemailer: ^6.6.5
+ react: ^18.2.0 || ^19.0.0-0
+ peerDependenciesMeta:
+ '@simplewebauthn/browser':
+ optional: true
+ '@simplewebauthn/server':
+ optional: true
+ nodemailer:
+ optional: true
+
+ next@15.5.18:
+ resolution: {integrity: sha512-eKL8zUJkX9Y5lE+RX/2YJoItVdGlIscyVyboeD9wSpp0PaGqjoA4tTpT2qPqz9ax+5IzGESyLSeZ/RCwbSZ2uQ==}
+ engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
+ node-fetch-native@1.6.7:
+ resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
+
+ node-releases@2.0.44:
+ resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ nypm@0.6.6:
+ resolution: {integrity: sha512-vRyr0r4cbBapw07Xw8xrj9Teq3o7MUD35rSaTcanDbW+aK2XHDgJFiU6ZTj2GBw7Q12ysdsyFss+Vdz4hQ0Y6Q==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ oauth4webapi@3.8.6:
+ resolution: {integrity: sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
+ ohash@2.0.11:
+ resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
+
+ on-exit-leak-free@2.1.2:
+ resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
+ engines: {node: '>=14.0.0'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@2.0.2:
+ resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
+ engines: {node: 18 || 20 || >=22}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ perfect-debounce@1.0.0:
+ resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.2:
+ resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.4:
+ resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
+ engines: {node: '>=12'}
+
+ pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
+ pino-abstract-transport@2.0.0:
+ resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
+
+ pino-pretty@11.3.0:
+ resolution: {integrity: sha512-oXwn7ICywaZPHmu3epHGU2oJX4nPmKvHvB/bwrJHlGcbEWaVcotkpyVHMKLKmiVryWYByNp0jpgAcXpFJDXJzA==}
+ hasBin: true
+
+ pino-std-serializers@7.1.0:
+ resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==}
+
+ pino@9.14.0:
+ resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==}
+ hasBin: true
+
+ pirates@4.0.7:
+ resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
+ engines: {node: '>= 6'}
+
+ pkg-types@2.3.1:
+ resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==}
+
+ playwright-core@1.60.0:
+ resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ playwright@1.60.0:
+ resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.1.0:
+ resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
+ postcss-load-config@6.0.1:
+ resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ jiti: '>=1.21.0'
+ postcss: '>=8.0.9'
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+ postcss:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.2:
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.5.14:
+ resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ preact-render-to-string@5.2.3:
+ resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==}
+ peerDependencies:
+ preact: '>=10'
+
+ preact@10.11.3:
+ resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ prettier-plugin-tailwindcss@0.6.14:
+ resolution: {integrity: sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==}
+ engines: {node: '>=14.21.3'}
+ peerDependencies:
+ '@ianvs/prettier-plugin-sort-imports': '*'
+ '@prettier/plugin-hermes': '*'
+ '@prettier/plugin-oxc': '*'
+ '@prettier/plugin-pug': '*'
+ '@shopify/prettier-plugin-liquid': '*'
+ '@trivago/prettier-plugin-sort-imports': '*'
+ '@zackad/prettier-plugin-twig': '*'
+ prettier: ^3.0
+ prettier-plugin-astro: '*'
+ prettier-plugin-css-order: '*'
+ prettier-plugin-import-sort: '*'
+ prettier-plugin-jsdoc: '*'
+ prettier-plugin-marko: '*'
+ prettier-plugin-multiline-arrays: '*'
+ prettier-plugin-organize-attributes: '*'
+ prettier-plugin-organize-imports: '*'
+ prettier-plugin-sort-imports: '*'
+ prettier-plugin-style-order: '*'
+ prettier-plugin-svelte: '*'
+ peerDependenciesMeta:
+ '@ianvs/prettier-plugin-sort-imports':
+ optional: true
+ '@prettier/plugin-hermes':
+ optional: true
+ '@prettier/plugin-oxc':
+ optional: true
+ '@prettier/plugin-pug':
+ optional: true
+ '@shopify/prettier-plugin-liquid':
+ optional: true
+ '@trivago/prettier-plugin-sort-imports':
+ optional: true
+ '@zackad/prettier-plugin-twig':
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+ prettier-plugin-css-order:
+ optional: true
+ prettier-plugin-import-sort:
+ optional: true
+ prettier-plugin-jsdoc:
+ optional: true
+ prettier-plugin-marko:
+ optional: true
+ prettier-plugin-multiline-arrays:
+ optional: true
+ prettier-plugin-organize-attributes:
+ optional: true
+ prettier-plugin-organize-imports:
+ optional: true
+ prettier-plugin-sort-imports:
+ optional: true
+ prettier-plugin-style-order:
+ optional: true
+ prettier-plugin-svelte:
+ optional: true
+
+ prettier@3.8.3:
+ resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ pretty-format@3.8.0:
+ resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
+
+ prisma@6.19.3:
+ resolution: {integrity: sha512-++ZJ0ijLrDJF6hNB4t4uxg2br3fC4H9Yc9tcbjr2fcNFP3rh/SBNrAgjhsqBU4Ght8JPrVofG/ZkXfnSfnYsFg==}
+ engines: {node: '>=18.18'}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.1.0'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ process-warning@5.0.0:
+ resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==}
+
+ process@0.11.10:
+ resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
+ engines: {node: '>= 0.6.0'}
+
+ pump@3.0.4:
+ resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ pure-rand@6.1.0:
+ resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ quick-format-unescaped@4.0.4:
+ resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
+
+ rc9@2.1.2:
+ resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
+
+ react-dom@19.2.6:
+ resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==}
+ peerDependencies:
+ react: ^19.2.6
+
+ react@19.2.6:
+ resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==}
+ engines: {node: '>=0.10.0'}
+
+ read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+
+ readable-stream@4.7.0:
+ resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ real-require@0.2.0:
+ resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
+ engines: {node: '>= 12.13.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve@1.22.12:
+ resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rimraf@6.1.3:
+ resolution: {integrity: sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ safe-stable-stringify@2.5.0:
+ resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
+ engines: {node: '>=10'}
+
+ scheduler@0.27.0:
+ resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+
+ secure-json-parse@2.7.0:
+ resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
+
+ semver@7.8.0:
+ resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ sonic-boom@4.2.1:
+ resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ split2@4.2.0:
+ resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
+ engines: {node: '>= 10.x'}
+
+ string_decoder@1.3.0:
+ resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ sucrase@3.35.1:
+ resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ superjson@2.2.6:
+ resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==}
+ engines: {node: '>=16'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ tailwind-merge@2.6.1:
+ resolution: {integrity: sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==}
+
+ tailwindcss-animate@1.0.7:
+ resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders'
+
+ tailwindcss@3.4.19:
+ resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ thread-stream@3.1.0:
+ resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==}
+
+ tinyexec@1.1.2:
+ resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.16:
+ resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
+ engines: {node: '>=12.0.0'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ ts-api-utils@2.5.0:
+ resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
+ engines: {node: '>=18.12'}
+ peerDependencies:
+ typescript: '>=4.8.4'
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tsx@4.22.0:
+ resolution: {integrity: sha512-8ccZMPD69s1AbKXx0C5ddTNZfNjwV04iIKgjZmKfKxMynEtSYcK0Lh7iQFh53fI5Yu4pb9usgAiqyPmEONaALg==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
+ turbo@2.9.14:
+ resolution: {integrity: sha512-BQqXRr4UoWI3UPFrtznCLykYHxwxWh53iCB57x092jPMjIlW1wnm3N895g5irpiXmnxUhREBB0n6+y8BHhs4nw==}
+ hasBin: true
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ typescript-eslint@8.59.3:
+ resolution: {integrity: sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: '>=4.8.4 <6.1.0'
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+ update-browserslist-db@1.2.3:
+ resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+snapshots:
+
+ '@alloc/quick-lru@5.2.0': {}
+
+ '@auth/core@0.37.2':
+ dependencies:
+ '@panva/hkdf': 1.2.1
+ '@types/cookie': 0.6.0
+ cookie: 0.7.1
+ jose: 5.10.0
+ oauth4webapi: 3.8.6
+ preact: 10.11.3
+ preact-render-to-string: 5.2.3(preact@10.11.3)
+
+ '@emnapi/runtime@1.10.0':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@esbuild/aix-ppc64@0.28.0':
+ optional: true
+
+ '@esbuild/android-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/android-arm@0.28.0':
+ optional: true
+
+ '@esbuild/android-x64@0.28.0':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/darwin-x64@0.28.0':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-arm@0.28.0':
+ optional: true
+
+ '@esbuild/linux-ia32@0.28.0':
+ optional: true
+
+ '@esbuild/linux-loong64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.28.0':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-s390x@0.28.0':
+ optional: true
+
+ '@esbuild/linux-x64@0.28.0':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.28.0':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.28.0':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/sunos-x64@0.28.0':
+ optional: true
+
+ '@esbuild/win32-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/win32-ia32@0.28.0':
+ optional: true
+
+ '@esbuild/win32-x64@0.28.0':
+ optional: true
+
+ '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.7.0))':
+ dependencies:
+ eslint: 9.39.4(jiti@2.7.0)
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/regexpp@4.12.2': {}
+
+ '@eslint/config-array@0.21.2':
+ dependencies:
+ '@eslint/object-schema': 2.1.7
+ debug: 4.4.3
+ minimatch: 3.1.5
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/config-helpers@0.4.2':
+ dependencies:
+ '@eslint/core': 0.17.0
+
+ '@eslint/core@0.17.0':
+ dependencies:
+ '@types/json-schema': 7.0.15
+
+ '@eslint/eslintrc@3.3.5':
+ dependencies:
+ ajv: 6.15.0
+ debug: 4.4.3
+ espree: 10.4.0
+ globals: 14.0.0
+ ignore: 5.3.2
+ import-fresh: 3.3.1
+ js-yaml: 4.1.1
+ minimatch: 3.1.5
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/js@9.39.4': {}
+
+ '@eslint/object-schema@2.1.7': {}
+
+ '@eslint/plugin-kit@0.4.1':
+ dependencies:
+ '@eslint/core': 0.17.0
+ levn: 0.4.1
+
+ '@humanfs/core@0.19.2':
+ dependencies:
+ '@humanfs/types': 0.15.0
+
+ '@humanfs/node@0.16.8':
+ dependencies:
+ '@humanfs/core': 0.19.2
+ '@humanfs/types': 0.15.0
+ '@humanwhocodes/retry': 0.4.3
+
+ '@humanfs/types@0.15.0': {}
+
+ '@humanwhocodes/module-importer@1.0.1': {}
+
+ '@humanwhocodes/retry@0.4.3': {}
+
+ '@img/colour@1.1.0':
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.10.0
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@next/env@15.5.18': {}
+
+ '@next/eslint-plugin-next@15.5.18':
+ dependencies:
+ fast-glob: 3.3.1
+
+ '@next/swc-darwin-arm64@15.5.18':
+ optional: true
+
+ '@next/swc-darwin-x64@15.5.18':
+ optional: true
+
+ '@next/swc-linux-arm64-gnu@15.5.18':
+ optional: true
+
+ '@next/swc-linux-arm64-musl@15.5.18':
+ optional: true
+
+ '@next/swc-linux-x64-gnu@15.5.18':
+ optional: true
+
+ '@next/swc-linux-x64-musl@15.5.18':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@15.5.18':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@15.5.18':
+ optional: true
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.20.1
+
+ '@panva/hkdf@1.2.1': {}
+
+ '@pinojs/redact@0.4.0': {}
+
+ '@playwright/test@1.60.0':
+ dependencies:
+ playwright: 1.60.0
+
+ '@prisma/client@6.19.3(prisma@6.19.3(typescript@5.9.3))(typescript@5.9.3)':
+ optionalDependencies:
+ prisma: 6.19.3(typescript@5.9.3)
+ typescript: 5.9.3
+
+ '@prisma/config@6.19.3':
+ dependencies:
+ c12: 3.1.0
+ deepmerge-ts: 7.1.5
+ effect: 3.21.0
+ empathic: 2.0.0
+ transitivePeerDependencies:
+ - magicast
+
+ '@prisma/debug@6.19.3': {}
+
+ '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': {}
+
+ '@prisma/engines@6.19.3':
+ dependencies:
+ '@prisma/debug': 6.19.3
+ '@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7
+ '@prisma/fetch-engine': 6.19.3
+ '@prisma/get-platform': 6.19.3
+
+ '@prisma/fetch-engine@6.19.3':
+ dependencies:
+ '@prisma/debug': 6.19.3
+ '@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7
+ '@prisma/get-platform': 6.19.3
+
+ '@prisma/get-platform@6.19.3':
+ dependencies:
+ '@prisma/debug': 6.19.3
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@swc/helpers@0.5.15':
+ dependencies:
+ tslib: 2.8.1
+
+ '@t3-oss/env-core@0.11.1(typescript@5.9.3)(zod@3.25.76)':
+ dependencies:
+ zod: 3.25.76
+ optionalDependencies:
+ typescript: 5.9.3
+
+ '@t3-oss/env-nextjs@0.11.1(typescript@5.9.3)(zod@3.25.76)':
+ dependencies:
+ '@t3-oss/env-core': 0.11.1(typescript@5.9.3)(zod@3.25.76)
+ zod: 3.25.76
+ optionalDependencies:
+ typescript: 5.9.3
+
+ '@tanstack/query-core@5.100.10': {}
+
+ '@tanstack/react-query@5.100.10(react@19.2.6)':
+ dependencies:
+ '@tanstack/query-core': 5.100.10
+ react: 19.2.6
+
+ '@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)':
+ dependencies:
+ '@trpc/server': 11.17.0(typescript@5.9.3)
+ typescript: 5.9.3
+
+ '@trpc/react-query@11.17.0(@tanstack/react-query@5.100.10(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)':
+ dependencies:
+ '@tanstack/react-query': 5.100.10(react@19.2.6)
+ '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3)
+ '@trpc/server': 11.17.0(typescript@5.9.3)
+ react: 19.2.6
+ typescript: 5.9.3
+
+ '@trpc/server@11.17.0(typescript@5.9.3)':
+ dependencies:
+ typescript: 5.9.3
+
+ '@turbo/darwin-64@2.9.14':
+ optional: true
+
+ '@turbo/darwin-arm64@2.9.14':
+ optional: true
+
+ '@turbo/linux-64@2.9.14':
+ optional: true
+
+ '@turbo/linux-arm64@2.9.14':
+ optional: true
+
+ '@turbo/windows-64@2.9.14':
+ optional: true
+
+ '@turbo/windows-arm64@2.9.14':
+ optional: true
+
+ '@types/cookie@0.6.0': {}
+
+ '@types/estree@1.0.9': {}
+
+ '@types/json-schema@7.0.15': {}
+
+ '@types/node@22.19.19':
+ dependencies:
+ undici-types: 6.21.0
+
+ '@types/react-dom@19.2.3(@types/react@19.2.14)':
+ dependencies:
+ '@types/react': 19.2.14
+
+ '@types/react@19.2.14':
+ dependencies:
+ csstype: 3.2.3
+
+ '@typescript-eslint/eslint-plugin@8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@eslint-community/regexpp': 4.12.2
+ '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/scope-manager': 8.59.3
+ '@typescript-eslint/type-utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/visitor-keys': 8.59.3
+ eslint: 9.39.4(jiti@2.7.0)
+ ignore: 7.0.5
+ natural-compare: 1.4.0
+ ts-api-utils: 2.5.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 8.59.3
+ '@typescript-eslint/types': 8.59.3
+ '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3)
+ '@typescript-eslint/visitor-keys': 8.59.3
+ debug: 4.4.3
+ eslint: 9.39.4(jiti@2.7.0)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/project-service@8.59.3(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3)
+ '@typescript-eslint/types': 8.59.3
+ debug: 4.4.3
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@8.59.3':
+ dependencies:
+ '@typescript-eslint/types': 8.59.3
+ '@typescript-eslint/visitor-keys': 8.59.3
+
+ '@typescript-eslint/tsconfig-utils@8.59.3(typescript@5.9.3)':
+ dependencies:
+ typescript: 5.9.3
+
+ '@typescript-eslint/type-utils@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/types': 8.59.3
+ '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ debug: 4.4.3
+ eslint: 9.39.4(jiti@2.7.0)
+ ts-api-utils: 2.5.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/types@8.59.3': {}
+
+ '@typescript-eslint/typescript-estree@8.59.3(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/project-service': 8.59.3(typescript@5.9.3)
+ '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3)
+ '@typescript-eslint/types': 8.59.3
+ '@typescript-eslint/visitor-keys': 8.59.3
+ debug: 4.4.3
+ minimatch: 10.2.5
+ semver: 7.8.0
+ tinyglobby: 0.2.16
+ ts-api-utils: 2.5.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0))
+ '@typescript-eslint/scope-manager': 8.59.3
+ '@typescript-eslint/types': 8.59.3
+ '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3)
+ eslint: 9.39.4(jiti@2.7.0)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/visitor-keys@8.59.3':
+ dependencies:
+ '@typescript-eslint/types': 8.59.3
+ eslint-visitor-keys: 5.0.1
+
+ abort-controller@3.0.0:
+ dependencies:
+ event-target-shim: 5.0.1
+
+ acorn-jsx@5.3.2(acorn@8.16.0):
+ dependencies:
+ acorn: 8.16.0
+
+ acorn@8.16.0: {}
+
+ ajv@6.15.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ any-promise@1.3.0: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.2
+
+ arg@5.0.2: {}
+
+ argparse@2.0.1: {}
+
+ atomic-sleep@1.0.0: {}
+
+ autoprefixer@10.5.0(postcss@8.5.14):
+ dependencies:
+ browserslist: 4.28.2
+ caniuse-lite: 1.0.30001792
+ fraction.js: 5.3.4
+ picocolors: 1.1.1
+ postcss: 8.5.14
+ postcss-value-parser: 4.2.0
+
+ balanced-match@1.0.2: {}
+
+ balanced-match@4.0.4: {}
+
+ base64-js@1.5.1: {}
+
+ baseline-browser-mapping@2.10.29: {}
+
+ binary-extensions@2.3.0: {}
+
+ brace-expansion@1.1.14:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ brace-expansion@5.0.6:
+ dependencies:
+ balanced-match: 4.0.4
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.28.2:
+ dependencies:
+ baseline-browser-mapping: 2.10.29
+ caniuse-lite: 1.0.30001792
+ electron-to-chromium: 1.5.356
+ node-releases: 2.0.44
+ update-browserslist-db: 1.2.3(browserslist@4.28.2)
+
+ buffer@6.0.3:
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+
+ c12@3.1.0:
+ dependencies:
+ chokidar: 4.0.3
+ confbox: 0.2.4
+ defu: 6.1.7
+ dotenv: 16.6.1
+ exsolve: 1.0.8
+ giget: 2.0.0
+ jiti: 2.7.0
+ ohash: 2.0.11
+ pathe: 2.0.3
+ perfect-debounce: 1.0.0
+ pkg-types: 2.3.1
+ rc9: 2.1.2
+
+ callsites@3.1.0: {}
+
+ camelcase-css@2.0.1: {}
+
+ caniuse-lite@1.0.30001792: {}
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
+ citty@0.1.6:
+ dependencies:
+ consola: 3.4.2
+
+ citty@0.2.2: {}
+
+ class-variance-authority@0.7.1:
+ dependencies:
+ clsx: 2.1.1
+
+ client-only@0.0.1: {}
+
+ clsx@2.1.1: {}
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ colorette@2.0.20: {}
+
+ commander@4.1.1: {}
+
+ concat-map@0.0.1: {}
+
+ confbox@0.2.4: {}
+
+ consola@3.4.2: {}
+
+ cookie@0.7.1: {}
+
+ copy-anything@4.0.5:
+ dependencies:
+ is-what: 5.5.0
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ cssesc@3.0.0: {}
+
+ csstype@3.2.3: {}
+
+ dateformat@4.6.3: {}
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ deep-is@0.1.4: {}
+
+ deepmerge-ts@7.1.5: {}
+
+ defu@6.1.7: {}
+
+ destr@2.0.5: {}
+
+ detect-libc@2.1.2:
+ optional: true
+
+ didyoumean@1.2.2: {}
+
+ dlv@1.1.3: {}
+
+ dotenv-cli@8.0.0:
+ dependencies:
+ cross-spawn: 7.0.6
+ dotenv: 16.6.1
+ dotenv-expand: 10.0.0
+ minimist: 1.2.8
+
+ dotenv-expand@10.0.0: {}
+
+ dotenv@16.6.1: {}
+
+ effect@3.21.0:
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ fast-check: 3.23.2
+
+ electron-to-chromium@1.5.356: {}
+
+ empathic@2.0.0: {}
+
+ end-of-stream@1.4.5:
+ dependencies:
+ once: 1.4.0
+
+ es-errors@1.3.0: {}
+
+ esbuild@0.28.0:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.28.0
+ '@esbuild/android-arm': 0.28.0
+ '@esbuild/android-arm64': 0.28.0
+ '@esbuild/android-x64': 0.28.0
+ '@esbuild/darwin-arm64': 0.28.0
+ '@esbuild/darwin-x64': 0.28.0
+ '@esbuild/freebsd-arm64': 0.28.0
+ '@esbuild/freebsd-x64': 0.28.0
+ '@esbuild/linux-arm': 0.28.0
+ '@esbuild/linux-arm64': 0.28.0
+ '@esbuild/linux-ia32': 0.28.0
+ '@esbuild/linux-loong64': 0.28.0
+ '@esbuild/linux-mips64el': 0.28.0
+ '@esbuild/linux-ppc64': 0.28.0
+ '@esbuild/linux-riscv64': 0.28.0
+ '@esbuild/linux-s390x': 0.28.0
+ '@esbuild/linux-x64': 0.28.0
+ '@esbuild/netbsd-arm64': 0.28.0
+ '@esbuild/netbsd-x64': 0.28.0
+ '@esbuild/openbsd-arm64': 0.28.0
+ '@esbuild/openbsd-x64': 0.28.0
+ '@esbuild/openharmony-arm64': 0.28.0
+ '@esbuild/sunos-x64': 0.28.0
+ '@esbuild/win32-arm64': 0.28.0
+ '@esbuild/win32-ia32': 0.28.0
+ '@esbuild/win32-x64': 0.28.0
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ eslint-config-prettier@9.1.2(eslint@9.39.4(jiti@2.7.0)):
+ dependencies:
+ eslint: 9.39.4(jiti@2.7.0)
+
+ eslint-scope@8.4.0:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint-visitor-keys@4.2.1: {}
+
+ eslint-visitor-keys@5.0.1: {}
+
+ eslint@9.39.4(jiti@2.7.0):
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0))
+ '@eslint-community/regexpp': 4.12.2
+ '@eslint/config-array': 0.21.2
+ '@eslint/config-helpers': 0.4.2
+ '@eslint/core': 0.17.0
+ '@eslint/eslintrc': 3.3.5
+ '@eslint/js': 9.39.4
+ '@eslint/plugin-kit': 0.4.1
+ '@humanfs/node': 0.16.8
+ '@humanwhocodes/module-importer': 1.0.1
+ '@humanwhocodes/retry': 0.4.3
+ '@types/estree': 1.0.9
+ ajv: 6.15.0
+ chalk: 4.1.2
+ cross-spawn: 7.0.6
+ debug: 4.4.3
+ escape-string-regexp: 4.0.0
+ eslint-scope: 8.4.0
+ eslint-visitor-keys: 4.2.1
+ espree: 10.4.0
+ esquery: 1.7.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 8.0.0
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ ignore: 5.3.2
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ json-stable-stringify-without-jsonify: 1.0.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.5
+ natural-compare: 1.4.0
+ optionator: 0.9.4
+ optionalDependencies:
+ jiti: 2.7.0
+ transitivePeerDependencies:
+ - supports-color
+
+ espree@10.4.0:
+ dependencies:
+ acorn: 8.16.0
+ acorn-jsx: 5.3.2(acorn@8.16.0)
+ eslint-visitor-keys: 4.2.1
+
+ esquery@1.7.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@5.3.0: {}
+
+ esutils@2.0.3: {}
+
+ event-target-shim@5.0.1: {}
+
+ events@3.3.0: {}
+
+ exsolve@1.0.8: {}
+
+ fast-check@3.23.2:
+ dependencies:
+ pure-rand: 6.1.0
+
+ fast-copy@3.0.2: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-glob@3.3.1:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-glob@3.3.3:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-levenshtein@2.0.6: {}
+
+ fast-safe-stringify@2.1.1: {}
+
+ fastq@1.20.1:
+ dependencies:
+ reusify: 1.1.0
+
+ fdir@6.5.0(picomatch@4.0.4):
+ optionalDependencies:
+ picomatch: 4.0.4
+
+ file-entry-cache@8.0.0:
+ dependencies:
+ flat-cache: 4.0.1
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ find-up@5.0.0:
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ flat-cache@4.0.1:
+ dependencies:
+ flatted: 3.4.2
+ keyv: 4.5.4
+
+ flatted@3.4.2: {}
+
+ fraction.js@5.3.4: {}
+
+ fsevents@2.3.2:
+ optional: true
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ giget@2.0.0:
+ dependencies:
+ citty: 0.1.6
+ consola: 3.4.2
+ defu: 6.1.7
+ node-fetch-native: 1.6.7
+ nypm: 0.6.6
+ pathe: 2.0.3
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob@13.0.6:
+ dependencies:
+ minimatch: 10.2.5
+ minipass: 7.1.3
+ path-scurry: 2.0.2
+
+ globals@14.0.0: {}
+
+ globals@15.15.0: {}
+
+ has-flag@4.0.0: {}
+
+ hasown@2.0.3:
+ dependencies:
+ function-bind: 1.1.2
+
+ help-me@5.0.0: {}
+
+ ieee754@1.2.1: {}
+
+ ignore@5.3.2: {}
+
+ ignore@7.0.5: {}
+
+ import-fresh@3.3.1:
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ imurmurhash@0.1.4: {}
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-core-module@2.16.2:
+ dependencies:
+ hasown: 2.0.3
+
+ is-extglob@2.1.1: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
+ is-what@5.5.0: {}
+
+ isexe@2.0.0: {}
+
+ jiti@1.21.7: {}
+
+ jiti@2.7.0: {}
+
+ jose@5.10.0: {}
+
+ joycon@3.1.1: {}
+
+ js-yaml@4.1.1:
+ dependencies:
+ argparse: 2.0.1
+
+ json-buffer@3.0.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-stable-stringify-without-jsonify@1.0.1: {}
+
+ keyv@4.5.4:
+ dependencies:
+ json-buffer: 3.0.1
+
+ levn@0.4.1:
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ lilconfig@3.1.3: {}
+
+ lines-and-columns@1.2.4: {}
+
+ locate-path@6.0.0:
+ dependencies:
+ p-locate: 5.0.0
+
+ lodash.merge@4.6.2: {}
+
+ lru-cache@11.3.6: {}
+
+ lucide-react@0.469.0(react@19.2.6):
+ dependencies:
+ react: 19.2.6
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.2
+
+ minimatch@10.2.5:
+ dependencies:
+ brace-expansion: 5.0.6
+
+ minimatch@3.1.5:
+ dependencies:
+ brace-expansion: 1.1.14
+
+ minimist@1.2.8: {}
+
+ minipass@7.1.3: {}
+
+ ms@2.1.3: {}
+
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
+ nanoid@3.3.12: {}
+
+ natural-compare@1.4.0: {}
+
+ next-auth@5.0.0-beta.25(next@15.5.18(@playwright/test@1.60.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6):
+ dependencies:
+ '@auth/core': 0.37.2
+ next: 15.5.18(@playwright/test@1.60.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ react: 19.2.6
+
+ next@15.5.18(@playwright/test@1.60.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
+ dependencies:
+ '@next/env': 15.5.18
+ '@swc/helpers': 0.5.15
+ caniuse-lite: 1.0.30001792
+ postcss: 8.4.31
+ react: 19.2.6
+ react-dom: 19.2.6(react@19.2.6)
+ styled-jsx: 5.1.6(react@19.2.6)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 15.5.18
+ '@next/swc-darwin-x64': 15.5.18
+ '@next/swc-linux-arm64-gnu': 15.5.18
+ '@next/swc-linux-arm64-musl': 15.5.18
+ '@next/swc-linux-x64-gnu': 15.5.18
+ '@next/swc-linux-x64-musl': 15.5.18
+ '@next/swc-win32-arm64-msvc': 15.5.18
+ '@next/swc-win32-x64-msvc': 15.5.18
+ '@playwright/test': 1.60.0
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
+ node-fetch-native@1.6.7: {}
+
+ node-releases@2.0.44: {}
+
+ normalize-path@3.0.0: {}
+
+ nypm@0.6.6:
+ dependencies:
+ citty: 0.2.2
+ pathe: 2.0.3
+ tinyexec: 1.1.2
+
+ oauth4webapi@3.8.6: {}
+
+ object-assign@4.1.1: {}
+
+ object-hash@3.0.0: {}
+
+ ohash@2.0.11: {}
+
+ on-exit-leak-free@2.1.2: {}
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ optionator@0.9.4:
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.5
+
+ p-limit@3.1.0:
+ dependencies:
+ yocto-queue: 0.1.0
+
+ p-locate@5.0.0:
+ dependencies:
+ p-limit: 3.1.0
+
+ package-json-from-dist@1.0.1: {}
+
+ parent-module@1.0.1:
+ dependencies:
+ callsites: 3.1.0
+
+ path-exists@4.0.0: {}
+
+ path-key@3.1.1: {}
+
+ path-parse@1.0.7: {}
+
+ path-scurry@2.0.2:
+ dependencies:
+ lru-cache: 11.3.6
+ minipass: 7.1.3
+
+ pathe@2.0.3: {}
+
+ perfect-debounce@1.0.0: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.2: {}
+
+ picomatch@4.0.4: {}
+
+ pify@2.3.0: {}
+
+ pino-abstract-transport@2.0.0:
+ dependencies:
+ split2: 4.2.0
+
+ pino-pretty@11.3.0:
+ dependencies:
+ colorette: 2.0.20
+ dateformat: 4.6.3
+ fast-copy: 3.0.2
+ fast-safe-stringify: 2.1.1
+ help-me: 5.0.0
+ joycon: 3.1.1
+ minimist: 1.2.8
+ on-exit-leak-free: 2.1.2
+ pino-abstract-transport: 2.0.0
+ pump: 3.0.4
+ readable-stream: 4.7.0
+ secure-json-parse: 2.7.0
+ sonic-boom: 4.2.1
+ strip-json-comments: 3.1.1
+
+ pino-std-serializers@7.1.0: {}
+
+ pino@9.14.0:
+ dependencies:
+ '@pinojs/redact': 0.4.0
+ atomic-sleep: 1.0.0
+ on-exit-leak-free: 2.1.2
+ pino-abstract-transport: 2.0.0
+ pino-std-serializers: 7.1.0
+ process-warning: 5.0.0
+ quick-format-unescaped: 4.0.4
+ real-require: 0.2.0
+ safe-stable-stringify: 2.5.0
+ sonic-boom: 4.2.1
+ thread-stream: 3.1.0
+
+ pirates@4.0.7: {}
+
+ pkg-types@2.3.1:
+ dependencies:
+ confbox: 0.2.4
+ exsolve: 1.0.8
+ pathe: 2.0.3
+
+ playwright-core@1.60.0: {}
+
+ playwright@1.60.0:
+ dependencies:
+ playwright-core: 1.60.0
+ optionalDependencies:
+ fsevents: 2.3.2
+
+ postcss-import@15.1.0(postcss@8.5.14):
+ dependencies:
+ postcss: 8.5.14
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.12
+
+ postcss-js@4.1.0(postcss@8.5.14):
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.5.14
+
+ postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.14)(tsx@4.22.0):
+ dependencies:
+ lilconfig: 3.1.3
+ optionalDependencies:
+ jiti: 1.21.7
+ postcss: 8.5.14
+ tsx: 4.22.0
+
+ postcss-nested@6.2.0(postcss@8.5.14):
+ dependencies:
+ postcss: 8.5.14
+ postcss-selector-parser: 6.1.2
+
+ postcss-selector-parser@6.1.2:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.4.31:
+ dependencies:
+ nanoid: 3.3.12
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ postcss@8.5.14:
+ dependencies:
+ nanoid: 3.3.12
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ preact-render-to-string@5.2.3(preact@10.11.3):
+ dependencies:
+ preact: 10.11.3
+ pretty-format: 3.8.0
+
+ preact@10.11.3: {}
+
+ prelude-ls@1.2.1: {}
+
+ prettier-plugin-tailwindcss@0.6.14(prettier@3.8.3):
+ dependencies:
+ prettier: 3.8.3
+
+ prettier@3.8.3: {}
+
+ pretty-format@3.8.0: {}
+
+ prisma@6.19.3(typescript@5.9.3):
+ dependencies:
+ '@prisma/config': 6.19.3
+ '@prisma/engines': 6.19.3
+ optionalDependencies:
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - magicast
+
+ process-warning@5.0.0: {}
+
+ process@0.11.10: {}
+
+ pump@3.0.4:
+ dependencies:
+ end-of-stream: 1.4.5
+ once: 1.4.0
+
+ punycode@2.3.1: {}
+
+ pure-rand@6.1.0: {}
+
+ queue-microtask@1.2.3: {}
+
+ quick-format-unescaped@4.0.4: {}
+
+ rc9@2.1.2:
+ dependencies:
+ defu: 6.1.7
+ destr: 2.0.5
+
+ react-dom@19.2.6(react@19.2.6):
+ dependencies:
+ react: 19.2.6
+ scheduler: 0.27.0
+
+ react@19.2.6: {}
+
+ read-cache@1.0.0:
+ dependencies:
+ pify: 2.3.0
+
+ readable-stream@4.7.0:
+ dependencies:
+ abort-controller: 3.0.0
+ buffer: 6.0.3
+ events: 3.3.0
+ process: 0.11.10
+ string_decoder: 1.3.0
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.2
+
+ readdirp@4.1.2: {}
+
+ real-require@0.2.0: {}
+
+ resolve-from@4.0.0: {}
+
+ resolve@1.22.12:
+ dependencies:
+ es-errors: 1.3.0
+ is-core-module: 2.16.2
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ reusify@1.1.0: {}
+
+ rimraf@6.1.3:
+ dependencies:
+ glob: 13.0.6
+ package-json-from-dist: 1.0.1
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ safe-buffer@5.2.1: {}
+
+ safe-stable-stringify@2.5.0: {}
+
+ scheduler@0.27.0: {}
+
+ secure-json-parse@2.7.0: {}
+
+ semver@7.8.0: {}
+
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.0
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+ optional: true
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ sonic-boom@4.2.1:
+ dependencies:
+ atomic-sleep: 1.0.0
+
+ source-map-js@1.2.1: {}
+
+ split2@4.2.0: {}
+
+ string_decoder@1.3.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ strip-json-comments@3.1.1: {}
+
+ styled-jsx@5.1.6(react@19.2.6):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.2.6
+
+ sucrase@3.35.1:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ commander: 4.1.1
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.7
+ tinyglobby: 0.2.16
+ ts-interface-checker: 0.1.13
+
+ superjson@2.2.6:
+ dependencies:
+ copy-anything: 4.0.5
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ tailwind-merge@2.6.1: {}
+
+ tailwindcss-animate@1.0.7(tailwindcss@3.4.19(tsx@4.22.0)):
+ dependencies:
+ tailwindcss: 3.4.19(tsx@4.22.0)
+
+ tailwindcss@3.4.19(tsx@4.22.0):
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.3
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.7
+ lilconfig: 3.1.3
+ micromatch: 4.0.8
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.1.1
+ postcss: 8.5.14
+ postcss-import: 15.1.0(postcss@8.5.14)
+ postcss-js: 4.1.0(postcss@8.5.14)
+ postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.14)(tsx@4.22.0)
+ postcss-nested: 6.2.0(postcss@8.5.14)
+ postcss-selector-parser: 6.1.2
+ resolve: 1.22.12
+ sucrase: 3.35.1
+ transitivePeerDependencies:
+ - tsx
+ - yaml
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
+ thread-stream@3.1.0:
+ dependencies:
+ real-require: 0.2.0
+
+ tinyexec@1.1.2: {}
+
+ tinyglobby@0.2.16:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ ts-api-utils@2.5.0(typescript@5.9.3):
+ dependencies:
+ typescript: 5.9.3
+
+ ts-interface-checker@0.1.13: {}
+
+ tslib@2.8.1: {}
+
+ tsx@4.22.0:
+ dependencies:
+ esbuild: 0.28.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ turbo@2.9.14:
+ optionalDependencies:
+ '@turbo/darwin-64': 2.9.14
+ '@turbo/darwin-arm64': 2.9.14
+ '@turbo/linux-64': 2.9.14
+ '@turbo/linux-arm64': 2.9.14
+ '@turbo/windows-64': 2.9.14
+ '@turbo/windows-arm64': 2.9.14
+
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
+
+ typescript-eslint@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.59.3(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3)
+ eslint: 9.39.4(jiti@2.7.0)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ typescript@5.9.3: {}
+
+ undici-types@6.21.0: {}
+
+ update-browserslist-db@1.2.3(browserslist@4.28.2):
+ dependencies:
+ browserslist: 4.28.2
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ util-deprecate@1.0.2: {}
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ word-wrap@1.2.5: {}
+
+ wrappy@1.0.2: {}
+
+ yocto-queue@0.1.0: {}
+
+ zod@3.25.76: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..9d48bb5
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,17 @@
+packages:
+ - "apps/*"
+ - "packages/*"
+ - "e2e"
+
+# pnpm 11 blocks postinstall scripts by default for security. We explicitly
+# approve only the packages that genuinely need them:
+# - @prisma/client / @prisma/engines / prisma: generate the Prisma client
+# and download the matching query engine binary.
+# - esbuild: prebuilt native binary; used transitively by tsx.
+# - sharp: prebuilt native binary; used by Next.js image optimization.
+allowBuilds:
+ '@prisma/client': true
+ '@prisma/engines': true
+ esbuild: true
+ prisma: true
+ sharp: true
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..05a45f6
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "strict": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "noEmit": true
+ },
+ "exclude": ["node_modules", "**/node_modules", "**/dist", "**/.next", "**/build"]
+}
diff --git a/turbo.json b/turbo.json
new file mode 100644
index 0000000..b512775
--- /dev/null
+++ b/turbo.json
@@ -0,0 +1,41 @@
+{
+ "$schema": "https://turbo.build/schema.json",
+ "globalDependencies": [".env"],
+ "globalEnv": [
+ "NODE_ENV",
+ "DATABASE_URL",
+ "AUTH_SECRET",
+ "AUTH_DEV_AUTOLOGIN",
+ "NEXT_PUBLIC_APP_URL",
+ "LOG_LEVEL"
+ ],
+ "tasks": {
+ "build": {
+ "dependsOn": ["^build"],
+ "outputs": [".next/**", "!.next/cache/**", "dist/**"]
+ },
+ "dev": {
+ "cache": false,
+ "persistent": true
+ },
+ "lint": {
+ "dependsOn": ["^build"],
+ "outputs": []
+ },
+ "typecheck": {
+ "dependsOn": ["^build"],
+ "outputs": []
+ },
+ "test": {
+ "dependsOn": ["^build"],
+ "outputs": ["coverage/**"]
+ },
+ "clean": {
+ "cache": false
+ },
+ "db:generate": {
+ "cache": false,
+ "outputs": ["node_modules/.prisma/**"]
+ }
+ }
+}