diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fe22c1..26fb4da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,26 @@ Todas as mudanças notáveis deste projeto serão documentadas neste arquivo. O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/), e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/). +## [1.3.0] - 2026-02-06 + +### Adicionado + +- Indexes compostos em `lancamentos`: `(userId, period, transactionType)` e `(pagadorId, period)` +- Cache cross-request no dashboard via `unstable_cache` com tag `"dashboard"` e TTL de 120s +- Invalidação automática do cache do dashboard via `revalidateTag("dashboard")` em mutations financeiras +- Helper `getAdminPagadorId()` com `React.cache()` para lookup cacheado do admin pagador + +### Alterado + +- Eliminados ~20 JOINs com tabela `pagadores` nos fetchers do dashboard (substituídos por filtro direto com `pagadorId`) +- Consolidadas queries de income-expense-balance: 12 queries → 1 (GROUP BY period + transactionType) +- Consolidadas queries de payment-status: 2 queries → 1 (GROUP BY transactionType) +- Consolidadas queries de expenses/income-by-category: 4 queries → 2 (GROUP BY categoriaId + period) +- Scan de métricas limitado a 24 meses ao invés de histórico completo +- Auth session deduplicada por request via `React.cache()` +- Widgets de dashboard ajustados para aceitar `Date | string` (compatibilidade com serialização do `unstable_cache`) +- `CLAUDE.md` otimizado de ~1339 linhas para ~140 linhas + ## [1.2.6] - 2025-02-04 ### Alterado diff --git a/app/(dashboard)/lancamentos/actions.ts b/app/(dashboard)/lancamentos/actions.ts index 4ad9829..be0e658 100644 --- a/app/(dashboard)/lancamentos/actions.ts +++ b/app/(dashboard)/lancamentos/actions.ts @@ -395,7 +395,10 @@ const buildShares = ({ ) { return [ { pagadorId, amountCents: primarySplitAmountCents }, - { pagadorId: secondaryPagadorId, amountCents: secondarySplitAmountCents }, + { + pagadorId: secondaryPagadorId, + amountCents: secondarySplitAmountCents, + }, ]; } diff --git a/components/contas/transfer-dialog.tsx b/components/contas/transfer-dialog.tsx index 94319af..09ecdd0 100644 --- a/components/contas/transfer-dialog.tsx +++ b/components/contas/transfer-dialog.tsx @@ -67,9 +67,7 @@ export function TransferDialog({ ); // Source account info - const fromAccount = accounts.find( - (account) => account.id === fromAccountId, - ); + const fromAccount = accounts.find((account) => account.id === fromAccountId); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); diff --git a/components/dashboard/purchases-by-category-widget.tsx b/components/dashboard/purchases-by-category-widget.tsx index 91f6c9d..d5eed7f 100644 --- a/components/dashboard/purchases-by-category-widget.tsx +++ b/components/dashboard/purchases-by-category-widget.tsx @@ -19,7 +19,8 @@ type PurchasesByCategoryWidgetProps = { data: PurchasesByCategoryData; }; -const formatTransactionDate = (date: Date) => { +const formatTransactionDate = (date: Date | string) => { + const d = date instanceof Date ? date : new Date(date); const formatter = new Intl.DateTimeFormat("pt-BR", { weekday: "short", day: "2-digit", @@ -27,7 +28,7 @@ const formatTransactionDate = (date: Date) => { timeZone: "UTC", }); - const formatted = formatter.format(date); + const formatted = formatter.format(d); // Capitaliza a primeira letra do dia da semana return formatted.charAt(0).toUpperCase() + formatted.slice(1); }; diff --git a/components/dashboard/recent-transactions-widget.tsx b/components/dashboard/recent-transactions-widget.tsx index c72b771..083e256 100644 --- a/components/dashboard/recent-transactions-widget.tsx +++ b/components/dashboard/recent-transactions-widget.tsx @@ -8,7 +8,8 @@ type RecentTransactionsWidgetProps = { data: RecentTransactionsData; }; -const formatTransactionDate = (date: Date) => { +const formatTransactionDate = (date: Date | string) => { + const d = date instanceof Date ? date : new Date(date); const formatter = new Intl.DateTimeFormat("pt-BR", { weekday: "short", day: "2-digit", @@ -16,7 +17,7 @@ const formatTransactionDate = (date: Date) => { timeZone: "UTC", }); - const formatted = formatter.format(date); + const formatted = formatter.format(d); // Capitaliza a primeira letra do dia da semana return formatted.charAt(0).toUpperCase() + formatted.slice(1); }; diff --git a/components/dashboard/section-cards.tsx b/components/dashboard/section-cards.tsx index 192c3ee..1b42ebc 100644 --- a/components/dashboard/section-cards.tsx +++ b/components/dashboard/section-cards.tsx @@ -14,7 +14,6 @@ import { CardTitle, } from "@/components/ui/card"; import type { DashboardCardMetrics } from "@/lib/dashboard/metrics"; -import { title_font } from "@/public/fonts/font_index"; import MoneyValues from "../money-values"; type SectionCardsProps = { @@ -61,9 +60,7 @@ const getPercentChange = (current: number, previous: number): string => { export function SectionCards({ metrics }: SectionCardsProps) { return ( -
+
{CARDS.map(({ label, key, icon: Icon }) => { const metric = metrics[key]; const trend = getTrend(metric.current, metric.previous); diff --git a/components/dashboard/top-expenses-widget.tsx b/components/dashboard/top-expenses-widget.tsx index 926c0cd..85078de 100644 --- a/components/dashboard/top-expenses-widget.tsx +++ b/components/dashboard/top-expenses-widget.tsx @@ -16,7 +16,8 @@ type TopExpensesWidgetProps = { cardOnlyExpenses: TopExpensesData; }; -const formatTransactionDate = (date: Date) => { +const formatTransactionDate = (date: Date | string) => { + const d = date instanceof Date ? date : new Date(date); const formatter = new Intl.DateTimeFormat("pt-BR", { weekday: "short", day: "2-digit", @@ -24,7 +25,7 @@ const formatTransactionDate = (date: Date) => { timeZone: "UTC", }); - const formatted = formatter.format(date); + const formatted = formatter.format(d); // Capitaliza a primeira letra do dia da semana return formatted.charAt(0).toUpperCase() + formatted.slice(1); }; diff --git a/components/lancamentos/table/lancamentos-table.tsx b/components/lancamentos/table/lancamentos-table.tsx index 9a310e4..314b0d9 100644 --- a/components/lancamentos/table/lancamentos-table.tsx +++ b/components/lancamentos/table/lancamentos-table.tsx @@ -72,7 +72,6 @@ import { getAvatarSrc } from "@/lib/pagadores/utils"; import { formatDate } from "@/lib/utils/date"; import { getConditionIcon, getPaymentMethodIcon } from "@/lib/utils/icons"; import { cn } from "@/lib/utils/ui"; -import { title_font } from "@/public/fonts/font_index"; import { LancamentosExport } from "../lancamentos-export"; import { EstabelecimentoLogo } from "../shared/estabelecimento-logo"; import type { @@ -928,7 +927,7 @@ export function LancamentosTable({ <>
- + {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( diff --git a/components/month-picker/month-navigation.tsx b/components/month-picker/month-navigation.tsx index f918c11..792621d 100644 --- a/components/month-picker/month-navigation.tsx +++ b/components/month-picker/month-navigation.tsx @@ -89,7 +89,7 @@ export default function MonthNavigation() {
diff --git a/components/relatorios/cartoes/card-category-breakdown.tsx b/components/relatorios/cartoes/card-category-breakdown.tsx index d863a36..818d7a4 100644 --- a/components/relatorios/cartoes/card-category-breakdown.tsx +++ b/components/relatorios/cartoes/card-category-breakdown.tsx @@ -7,7 +7,6 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { WidgetEmptyState } from "@/components/widget-empty-state"; import type { CardDetailData } from "@/lib/relatorios/cartoes-report"; -import { title_font } from "@/public/fonts/font_index"; type CardCategoryBreakdownProps = { data: CardDetailData["categoryBreakdown"]; @@ -18,9 +17,7 @@ export function CardCategoryBreakdown({ data }: CardCategoryBreakdownProps) { return ( - + Gastos por Categoria @@ -41,9 +38,7 @@ export function CardCategoryBreakdown({ data }: CardCategoryBreakdownProps) { return ( - + Gastos por Categoria diff --git a/components/relatorios/cartoes/card-invoice-status.tsx b/components/relatorios/cartoes/card-invoice-status.tsx index ff31357..e00d1bc 100644 --- a/components/relatorios/cartoes/card-invoice-status.tsx +++ b/components/relatorios/cartoes/card-invoice-status.tsx @@ -10,7 +10,6 @@ import { } from "@/components/ui/tooltip"; import type { CardDetailData } from "@/lib/relatorios/cartoes-report"; import { cn } from "@/lib/utils"; -import { title_font } from "@/public/fonts/font_index"; type CardInvoiceStatusProps = { data: CardDetailData["invoiceStatus"]; @@ -75,9 +74,7 @@ export function CardInvoiceStatus({ data }: CardInvoiceStatusProps) { return ( - + Faturas diff --git a/components/relatorios/cartoes/card-top-expenses.tsx b/components/relatorios/cartoes/card-top-expenses.tsx index 7536b42..67b28c8 100644 --- a/components/relatorios/cartoes/card-top-expenses.tsx +++ b/components/relatorios/cartoes/card-top-expenses.tsx @@ -7,7 +7,6 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { WidgetEmptyState } from "@/components/widget-empty-state"; import type { CardDetailData } from "@/lib/relatorios/cartoes-report"; -import { title_font } from "@/public/fonts/font_index"; type CardTopExpensesProps = { data: CardDetailData["topExpenses"]; @@ -18,9 +17,7 @@ export function CardTopExpenses({ data }: CardTopExpensesProps) { return ( - + Top 10 Gastos do Mês @@ -43,9 +40,7 @@ export function CardTopExpenses({ data }: CardTopExpensesProps) { return ( - + Top 10 Gastos do Mês diff --git a/components/relatorios/cartoes/card-usage-chart.tsx b/components/relatorios/cartoes/card-usage-chart.tsx index a162fc3..0a3f629 100644 --- a/components/relatorios/cartoes/card-usage-chart.tsx +++ b/components/relatorios/cartoes/card-usage-chart.tsx @@ -17,7 +17,6 @@ import { ChartTooltip, } from "@/components/ui/chart"; import type { CardDetailData } from "@/lib/relatorios/cartoes-report"; -import { title_font } from "@/public/fonts/font_index"; type CardUsageChartProps = { data: CardDetailData["monthlyUsage"]; @@ -82,9 +81,7 @@ export function CardUsageChart({ data, limit, card }: CardUsageChartProps) {
- + Histórico de Uso diff --git a/components/relatorios/category-report-table.tsx b/components/relatorios/category-report-table.tsx index 6fae5d8..807b0fe 100644 --- a/components/relatorios/category-report-table.tsx +++ b/components/relatorios/category-report-table.tsx @@ -1,7 +1,10 @@ "use client"; import { useMemo } from "react"; -import type { CategoryReportData, CategoryReportItem } from "@/lib/relatorios/types"; +import type { + CategoryReportData, + CategoryReportItem, +} from "@/lib/relatorios/types"; import { CategoryTable } from "./category-table"; interface CategoryReportTableProps { diff --git a/components/sidebar/app-sidebar.tsx b/components/sidebar/app-sidebar.tsx index a43fa95..55169b7 100644 --- a/components/sidebar/app-sidebar.tsx +++ b/components/sidebar/app-sidebar.tsx @@ -78,9 +78,6 @@ function LogoContent() { const isCollapsed = state === "collapsed"; return ( - + ); } diff --git a/components/top-estabelecimentos/establishments-list.tsx b/components/top-estabelecimentos/establishments-list.tsx index f6cf585..cc9eb29 100644 --- a/components/top-estabelecimentos/establishments-list.tsx +++ b/components/top-estabelecimentos/establishments-list.tsx @@ -6,7 +6,6 @@ import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { WidgetEmptyState } from "@/components/widget-empty-state"; import type { TopEstabelecimentosData } from "@/lib/top-estabelecimentos/fetch-data"; -import { title_font } from "@/public/fonts/font_index"; import { Progress } from "../ui/progress"; type EstablishmentsListProps = { @@ -32,9 +31,7 @@ export function EstablishmentsList({ return ( - + Top Estabelecimentos @@ -55,9 +52,7 @@ export function EstablishmentsList({ return ( - + Top Estabelecimentos por Frequência diff --git a/components/top-estabelecimentos/top-categories.tsx b/components/top-estabelecimentos/top-categories.tsx index aae24dc..8648fa7 100644 --- a/components/top-estabelecimentos/top-categories.tsx +++ b/components/top-estabelecimentos/top-categories.tsx @@ -6,7 +6,6 @@ import MoneyValues from "@/components/money-values"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { WidgetEmptyState } from "@/components/widget-empty-state"; import type { TopEstabelecimentosData } from "@/lib/top-estabelecimentos/fetch-data"; -import { title_font } from "@/public/fonts/font_index"; import { Progress } from "../ui/progress"; type TopCategoriesProps = { @@ -18,9 +17,7 @@ export function TopCategories({ categories }: TopCategoriesProps) { return ( - + Principais Categorias @@ -41,9 +38,7 @@ export function TopCategories({ categories }: TopCategoriesProps) { return ( - + Principais Categorias diff --git a/components/widget-card.tsx b/components/widget-card.tsx index b548d2e..a164b49 100644 --- a/components/widget-card.tsx +++ b/components/widget-card.tsx @@ -14,7 +14,6 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog"; -import { title_font } from "@/public/fonts/font_index"; import { Button } from "./ui/button"; const OVERFLOW_THRESHOLD_PX = 16; @@ -79,9 +78,7 @@ export default function WidgetCard({
- + {icon} {title} diff --git a/db/schema.ts b/db/schema.ts index bfa0d29..c1ce02f 100644 --- a/db/schema.ts +++ b/db/schema.ts @@ -591,6 +591,17 @@ export const lancamentos = pgTable( table.userId, table.period, ), + // Índice composto userId + period + transactionType (cobre maioria das queries do dashboard) + userIdPeriodTypeIdx: index("lancamentos_user_id_period_type_idx").on( + table.userId, + table.period, + table.transactionType, + ), + // Índice para queries por pagador + period (invoice/breakdown queries) + pagadorIdPeriodIdx: index("lancamentos_pagador_id_period_idx").on( + table.pagadorId, + table.period, + ), // Índice para queries ordenadas por data de compra userIdPurchaseDateIdx: index("lancamentos_user_id_purchase_date_idx").on( table.userId, diff --git a/drizzle/0015_concerned_kat_farrell.sql b/drizzle/0015_concerned_kat_farrell.sql new file mode 100644 index 0000000..3bc6560 --- /dev/null +++ b/drizzle/0015_concerned_kat_farrell.sql @@ -0,0 +1,2 @@ +CREATE INDEX "lancamentos_user_id_period_type_idx" ON "lancamentos" USING btree ("user_id","periodo","tipo_transacao");--> statement-breakpoint +CREATE INDEX "lancamentos_pagador_id_period_idx" ON "lancamentos" USING btree ("pagador_id","periodo"); \ No newline at end of file diff --git a/drizzle/meta/0015_snapshot.json b/drizzle/meta/0015_snapshot.json new file mode 100644 index 0000000..1b966ae --- /dev/null +++ b/drizzle/meta/0015_snapshot.json @@ -0,0 +1,2303 @@ +{ + "id": "af9b35da-2ada-4fbf-bcce-b371ce7117bf", + "prevId": "4ae67d34-81ae-418b-ac5b-e53b57753da1", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "accountId": { + "name": "accountId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "providerId": { + "name": "providerId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "accessToken": { + "name": "accessToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refreshToken": { + "name": "refreshToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idToken": { + "name": "idToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accessTokenExpiresAt": { + "name": "accessTokenExpiresAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refreshTokenExpiresAt": { + "name": "refreshTokenExpiresAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "account_userId_user_id_fk": { + "name": "account_userId_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.anotacoes": { + "name": "anotacoes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "titulo": { + "name": "titulo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "descricao": { + "name": "descricao", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tipo": { + "name": "tipo", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'nota'" + }, + "tasks": { + "name": "tasks", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "arquivada": { + "name": "arquivada", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "anotacoes_user_id_user_id_fk": { + "name": "anotacoes_user_id_user_id_fk", + "tableFrom": "anotacoes", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.antecipacoes_parcelas": { + "name": "antecipacoes_parcelas", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "series_id": { + "name": "series_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "periodo_antecipacao": { + "name": "periodo_antecipacao", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "data_antecipacao": { + "name": "data_antecipacao", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "parcelas_antecipadas": { + "name": "parcelas_antecipadas", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "valor_total": { + "name": "valor_total", + "type": "numeric(12, 2)", + "primaryKey": false, + "notNull": true + }, + "qtde_parcelas": { + "name": "qtde_parcelas", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "desconto": { + "name": "desconto", + "type": "numeric(12, 2)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "lancamento_id": { + "name": "lancamento_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "pagador_id": { + "name": "pagador_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "categoria_id": { + "name": "categoria_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "anotacao": { + "name": "anotacao", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "antecipacoes_parcelas_series_id_idx": { + "name": "antecipacoes_parcelas_series_id_idx", + "columns": [ + { + "expression": "series_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "antecipacoes_parcelas_user_id_idx": { + "name": "antecipacoes_parcelas_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "antecipacoes_parcelas_lancamento_id_lancamentos_id_fk": { + "name": "antecipacoes_parcelas_lancamento_id_lancamentos_id_fk", + "tableFrom": "antecipacoes_parcelas", + "tableTo": "lancamentos", + "columnsFrom": [ + "lancamento_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "antecipacoes_parcelas_pagador_id_pagadores_id_fk": { + "name": "antecipacoes_parcelas_pagador_id_pagadores_id_fk", + "tableFrom": "antecipacoes_parcelas", + "tableTo": "pagadores", + "columnsFrom": [ + "pagador_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "antecipacoes_parcelas_categoria_id_categorias_id_fk": { + "name": "antecipacoes_parcelas_categoria_id_categorias_id_fk", + "tableFrom": "antecipacoes_parcelas", + "tableTo": "categorias", + "columnsFrom": [ + "categoria_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "antecipacoes_parcelas_user_id_user_id_fk": { + "name": "antecipacoes_parcelas_user_id_user_id_fk", + "tableFrom": "antecipacoes_parcelas", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cartoes": { + "name": "cartoes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "nome": { + "name": "nome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dt_fechamento": { + "name": "dt_fechamento", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dt_vencimento": { + "name": "dt_vencimento", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "anotacao": { + "name": "anotacao", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "limite": { + "name": "limite", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": false + }, + "bandeira": { + "name": "bandeira", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "conta_id": { + "name": "conta_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "cartoes_user_id_status_idx": { + "name": "cartoes_user_id_status_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "cartoes_user_id_user_id_fk": { + "name": "cartoes_user_id_user_id_fk", + "tableFrom": "cartoes", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "cartoes_conta_id_contas_id_fk": { + "name": "cartoes_conta_id_contas_id_fk", + "tableFrom": "cartoes", + "tableTo": "contas", + "columnsFrom": [ + "conta_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.categorias": { + "name": "categorias", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "nome": { + "name": "nome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tipo": { + "name": "tipo", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "icone": { + "name": "icone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "categorias_user_id_type_idx": { + "name": "categorias_user_id_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "tipo", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "categorias_user_id_user_id_fk": { + "name": "categorias_user_id_user_id_fk", + "tableFrom": "categorias", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.compartilhamentos_pagador": { + "name": "compartilhamentos_pagador", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "pagador_id": { + "name": "pagador_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shared_with_user_id": { + "name": "shared_with_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'read'" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "compartilhamentos_pagador_unique": { + "name": "compartilhamentos_pagador_unique", + "columns": [ + { + "expression": "pagador_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "shared_with_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "compartilhamentos_pagador_pagador_id_pagadores_id_fk": { + "name": "compartilhamentos_pagador_pagador_id_pagadores_id_fk", + "tableFrom": "compartilhamentos_pagador", + "tableTo": "pagadores", + "columnsFrom": [ + "pagador_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "compartilhamentos_pagador_shared_with_user_id_user_id_fk": { + "name": "compartilhamentos_pagador_shared_with_user_id_user_id_fk", + "tableFrom": "compartilhamentos_pagador", + "tableTo": "user", + "columnsFrom": [ + "shared_with_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "compartilhamentos_pagador_created_by_user_id_user_id_fk": { + "name": "compartilhamentos_pagador_created_by_user_id_user_id_fk", + "tableFrom": "compartilhamentos_pagador", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contas": { + "name": "contas", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "nome": { + "name": "nome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tipo_conta": { + "name": "tipo_conta", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "anotacao": { + "name": "anotacao", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "saldo_inicial": { + "name": "saldo_inicial", + "type": "numeric(12, 2)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "excluir_do_saldo": { + "name": "excluir_do_saldo", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "excluir_saldo_inicial_receitas": { + "name": "excluir_saldo_inicial_receitas", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "contas_user_id_status_idx": { + "name": "contas_user_id_status_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contas_user_id_user_id_fk": { + "name": "contas_user_id_user_id_fk", + "tableFrom": "contas", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.faturas": { + "name": "faturas", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "status_pagamento": { + "name": "status_pagamento", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "periodo": { + "name": "periodo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cartao_id": { + "name": "cartao_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "faturas_user_id_period_idx": { + "name": "faturas_user_id_period_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "periodo", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "faturas_cartao_id_period_idx": { + "name": "faturas_cartao_id_period_idx", + "columns": [ + { + "expression": "cartao_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "periodo", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "faturas_user_id_user_id_fk": { + "name": "faturas_user_id_user_id_fk", + "tableFrom": "faturas", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "faturas_cartao_id_cartoes_id_fk": { + "name": "faturas_cartao_id_cartoes_id_fk", + "tableFrom": "faturas", + "tableTo": "cartoes", + "columnsFrom": [ + "cartao_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.insights_salvos": { + "name": "insights_salvos", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period": { + "name": "period", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model_id": { + "name": "model_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "insights_salvos_user_period_idx": { + "name": "insights_salvos_user_period_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "insights_salvos_user_id_user_id_fk": { + "name": "insights_salvos_user_id_user_id_fk", + "tableFrom": "insights_salvos", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.lancamentos": { + "name": "lancamentos", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "condicao": { + "name": "condicao", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "nome": { + "name": "nome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "forma_pagamento": { + "name": "forma_pagamento", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "anotacao": { + "name": "anotacao", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "valor": { + "name": "valor", + "type": "numeric(12, 2)", + "primaryKey": false, + "notNull": true + }, + "data_compra": { + "name": "data_compra", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "tipo_transacao": { + "name": "tipo_transacao", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "qtde_parcela": { + "name": "qtde_parcela", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "periodo": { + "name": "periodo", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "parcela_atual": { + "name": "parcela_atual", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "qtde_recorrencia": { + "name": "qtde_recorrencia", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "data_vencimento": { + "name": "data_vencimento", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "dt_pagamento_boleto": { + "name": "dt_pagamento_boleto", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "realizado": { + "name": "realizado", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "dividido": { + "name": "dividido", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "antecipado": { + "name": "antecipado", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "antecipacao_id": { + "name": "antecipacao_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cartao_id": { + "name": "cartao_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "conta_id": { + "name": "conta_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "categoria_id": { + "name": "categoria_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "pagador_id": { + "name": "pagador_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "series_id": { + "name": "series_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "transfer_id": { + "name": "transfer_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "lancamentos_user_id_period_idx": { + "name": "lancamentos_user_id_period_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "periodo", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "lancamentos_user_id_period_type_idx": { + "name": "lancamentos_user_id_period_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "periodo", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "tipo_transacao", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "lancamentos_pagador_id_period_idx": { + "name": "lancamentos_pagador_id_period_idx", + "columns": [ + { + "expression": "pagador_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "periodo", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "lancamentos_user_id_purchase_date_idx": { + "name": "lancamentos_user_id_purchase_date_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "data_compra", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "lancamentos_series_id_idx": { + "name": "lancamentos_series_id_idx", + "columns": [ + { + "expression": "series_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "lancamentos_transfer_id_idx": { + "name": "lancamentos_transfer_id_idx", + "columns": [ + { + "expression": "transfer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "lancamentos_user_id_condition_idx": { + "name": "lancamentos_user_id_condition_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "condicao", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "lancamentos_cartao_id_period_idx": { + "name": "lancamentos_cartao_id_period_idx", + "columns": [ + { + "expression": "cartao_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "periodo", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "lancamentos_antecipacao_id_antecipacoes_parcelas_id_fk": { + "name": "lancamentos_antecipacao_id_antecipacoes_parcelas_id_fk", + "tableFrom": "lancamentos", + "tableTo": "antecipacoes_parcelas", + "columnsFrom": [ + "antecipacao_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "lancamentos_user_id_user_id_fk": { + "name": "lancamentos_user_id_user_id_fk", + "tableFrom": "lancamentos", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "lancamentos_cartao_id_cartoes_id_fk": { + "name": "lancamentos_cartao_id_cartoes_id_fk", + "tableFrom": "lancamentos", + "tableTo": "cartoes", + "columnsFrom": [ + "cartao_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "lancamentos_conta_id_contas_id_fk": { + "name": "lancamentos_conta_id_contas_id_fk", + "tableFrom": "lancamentos", + "tableTo": "contas", + "columnsFrom": [ + "conta_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "lancamentos_categoria_id_categorias_id_fk": { + "name": "lancamentos_categoria_id_categorias_id_fk", + "tableFrom": "lancamentos", + "tableTo": "categorias", + "columnsFrom": [ + "categoria_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "lancamentos_pagador_id_pagadores_id_fk": { + "name": "lancamentos_pagador_id_pagadores_id_fk", + "tableFrom": "lancamentos", + "tableTo": "pagadores", + "columnsFrom": [ + "pagador_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.orcamentos": { + "name": "orcamentos", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "valor": { + "name": "valor", + "type": "numeric(10, 2)", + "primaryKey": false, + "notNull": true + }, + "periodo": { + "name": "periodo", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "categoria_id": { + "name": "categoria_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "orcamentos_user_id_period_idx": { + "name": "orcamentos_user_id_period_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "periodo", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "orcamentos_user_id_user_id_fk": { + "name": "orcamentos_user_id_user_id_fk", + "tableFrom": "orcamentos", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "orcamentos_categoria_id_categorias_id_fk": { + "name": "orcamentos_categoria_id_categorias_id_fk", + "tableFrom": "orcamentos", + "tableTo": "categorias", + "columnsFrom": [ + "categoria_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pagadores": { + "name": "pagadores", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "nome": { + "name": "nome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "anotacao": { + "name": "anotacao", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_auto_send": { + "name": "is_auto_send", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "share_code": { + "name": "share_code", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "substr(encode(gen_random_bytes(24), 'base64'), 1, 24)" + }, + "last_mail": { + "name": "last_mail", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "pagadores_share_code_key": { + "name": "pagadores_share_code_key", + "columns": [ + { + "expression": "share_code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "pagadores_user_id_status_idx": { + "name": "pagadores_user_id_status_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "pagadores_user_id_role_idx": { + "name": "pagadores_user_id_role_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "role", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "pagadores_user_id_user_id_fk": { + "name": "pagadores_user_id_user_id_fk", + "tableFrom": "pagadores", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pre_lancamentos": { + "name": "pre_lancamentos", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_app": { + "name": "source_app", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_app_name": { + "name": "source_app_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "original_title": { + "name": "original_title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "original_text": { + "name": "original_text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notification_timestamp": { + "name": "notification_timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "parsed_name": { + "name": "parsed_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "parsed_amount": { + "name": "parsed_amount", + "type": "numeric(12, 2)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "lancamento_id": { + "name": "lancamento_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "processed_at": { + "name": "processed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "discarded_at": { + "name": "discarded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "pre_lancamentos_user_id_status_idx": { + "name": "pre_lancamentos_user_id_status_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "pre_lancamentos_user_id_created_at_idx": { + "name": "pre_lancamentos_user_id_created_at_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "pre_lancamentos_user_id_user_id_fk": { + "name": "pre_lancamentos_user_id_user_id_fk", + "tableFrom": "pre_lancamentos", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "pre_lancamentos_lancamento_id_lancamentos_id_fk": { + "name": "pre_lancamentos_lancamento_id_lancamentos_id_fk", + "tableFrom": "pre_lancamentos", + "tableTo": "lancamentos", + "columnsFrom": [ + "lancamento_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.preferencias_usuario": { + "name": "preferencias_usuario", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "disable_magnetlines": { + "name": "disable_magnetlines", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "dashboard_widgets": { + "name": "dashboard_widgets", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "preferencias_usuario_user_id_user_id_fk": { + "name": "preferencias_usuario_user_id_user_id_fk", + "tableFrom": "preferencias_usuario", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "preferencias_usuario_user_id_unique": { + "name": "preferencias_usuario_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "ipAddress": { + "name": "ipAddress", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userAgent": { + "name": "userAgent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tokens_api": { + "name": "tokens_api", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_prefix": { + "name": "token_prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_used_ip": { + "name": "last_used_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tokens_api_user_id_idx": { + "name": "tokens_api_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "tokens_api_token_hash_idx": { + "name": "tokens_api_token_hash_idx", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "tokens_api_user_id_user_id_fk": { + "name": "tokens_api_user_id_user_id_fk", + "tableFrom": "tokens_api", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "emailVerified": { + "name": "emailVerified", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 55ce2ac..614d6e7 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -1,111 +1,118 @@ { - "version": "7", - "dialect": "postgresql", - "entries": [ - { - "idx": 0, - "version": "7", - "when": 1762993507299, - "tag": "0000_flashy_manta", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1765199006435, - "tag": "0001_young_mister_fear", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1765200545692, - "tag": "0002_slimy_flatman", - "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1767102605526, - "tag": "0003_green_korg", - "breakpoints": true - }, - { - "idx": 4, - "version": "7", - "when": 1767104066872, - "tag": "0004_acoustic_mach_iv", - "breakpoints": true - }, - { - "idx": 5, - "version": "7", - "when": 1767106121811, - "tag": "0005_adorable_bruce_banner", - "breakpoints": true - }, - { - "idx": 6, - "version": "7", - "when": 1767107487318, - "tag": "0006_youthful_mister_fear", - "breakpoints": true - }, - { - "idx": 7, - "version": "7", - "when": 1767118780033, - "tag": "0007_sturdy_kate_bishop", - "breakpoints": true - }, - { - "idx": 8, - "version": "7", - "when": 1767125796314, - "tag": "0008_fat_stick", - "breakpoints": true - }, - { - "idx": 9, - "version": "7", - "when": 1768925100873, - "tag": "0009_add_dashboard_widgets", - "breakpoints": true - }, - { - "idx": 10, - "version": "7", - "when": 1769369834242, - "tag": "0010_lame_psynapse", - "breakpoints": true - }, - { - "idx": 11, - "version": "7", - "when": 1769447087678, - "tag": "0011_remove_unused_inbox_columns", - "breakpoints": true - }, - { - "idx": 12, - "version": "7", - "when": 1769533200000, - "tag": "0012_rename_tables_to_portuguese", - "breakpoints": true - }, - { - "idx": 13, - "version": "7", - "when": 1769523352777, - "tag": "0013_fancy_rick_jones", - "breakpoints": true - }, - { - "idx": 14, - "version": "7", - "when": 1769619226903, - "tag": "0014_yielding_jack_flag", - "breakpoints": true - } - ] -} + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1762993507299, + "tag": "0000_flashy_manta", + "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1765199006435, + "tag": "0001_young_mister_fear", + "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1765200545692, + "tag": "0002_slimy_flatman", + "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1767102605526, + "tag": "0003_green_korg", + "breakpoints": true + }, + { + "idx": 4, + "version": "7", + "when": 1767104066872, + "tag": "0004_acoustic_mach_iv", + "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1767106121811, + "tag": "0005_adorable_bruce_banner", + "breakpoints": true + }, + { + "idx": 6, + "version": "7", + "when": 1767107487318, + "tag": "0006_youthful_mister_fear", + "breakpoints": true + }, + { + "idx": 7, + "version": "7", + "when": 1767118780033, + "tag": "0007_sturdy_kate_bishop", + "breakpoints": true + }, + { + "idx": 8, + "version": "7", + "when": 1767125796314, + "tag": "0008_fat_stick", + "breakpoints": true + }, + { + "idx": 9, + "version": "7", + "when": 1768925100873, + "tag": "0009_add_dashboard_widgets", + "breakpoints": true + }, + { + "idx": 10, + "version": "7", + "when": 1769369834242, + "tag": "0010_lame_psynapse", + "breakpoints": true + }, + { + "idx": 11, + "version": "7", + "when": 1769447087678, + "tag": "0011_remove_unused_inbox_columns", + "breakpoints": true + }, + { + "idx": 12, + "version": "7", + "when": 1769533200000, + "tag": "0012_rename_tables_to_portuguese", + "breakpoints": true + }, + { + "idx": 13, + "version": "7", + "when": 1769523352777, + "tag": "0013_fancy_rick_jones", + "breakpoints": true + }, + { + "idx": 14, + "version": "7", + "when": 1769619226903, + "tag": "0014_yielding_jack_flag", + "breakpoints": true + }, + { + "idx": 15, + "version": "7", + "when": 1770332054481, + "tag": "0015_concerned_kat_farrell", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/lib/actions/helpers.ts b/lib/actions/helpers.ts index 681da2b..69e2f0d 100644 --- a/lib/actions/helpers.ts +++ b/lib/actions/helpers.ts @@ -1,4 +1,4 @@ -import { revalidatePath } from "next/cache"; +import { revalidatePath, revalidateTag } from "next/cache"; import { z } from "zod"; import { getUser } from "@/lib/auth/server"; import type { ActionResult } from "./types"; @@ -35,14 +35,30 @@ export const revalidateConfig = { inbox: ["/pre-lancamentos", "/lancamentos", "/dashboard"], } as const; +/** Entities whose mutations should invalidate the dashboard cache */ +const DASHBOARD_ENTITIES: ReadonlySet = new Set([ + "lancamentos", + "contas", + "cartoes", + "orcamentos", + "pagadores", + "inbox", +]); + /** - * Revalidates paths for a specific entity + * Revalidates paths for a specific entity. + * Also invalidates the dashboard "use cache" tag for financial entities. * @param entity - The entity type */ export function revalidateForEntity( entity: keyof typeof revalidateConfig, ): void { revalidateConfig[entity].forEach((path) => revalidatePath(path)); + + // Invalidate dashboard cache for financial mutations + if (DASHBOARD_ENTITIES.has(entity)) { + revalidateTag("dashboard"); + } } /** diff --git a/lib/auth/server.ts b/lib/auth/server.ts index 947a8b9..567c70c 100644 --- a/lib/auth/server.ts +++ b/lib/auth/server.ts @@ -1,14 +1,23 @@ import { headers } from "next/headers"; import { redirect } from "next/navigation"; +import { cache } from "react"; import { auth } from "@/lib/auth/config"; +/** + * Cached session fetch - deduplicates auth calls within a single request. + * Layout + page calling getUser() will only hit auth once. + */ +const getSessionCached = cache(async () => { + return auth.api.getSession({ headers: await headers() }); +}); + /** * Gets the current authenticated user * @returns User object * @throws Redirects to /login if user is not authenticated */ export async function getUser() { - const session = await auth.api.getSession({ headers: await headers() }); + const session = await getSessionCached(); if (!session?.user) { redirect("/login"); @@ -23,7 +32,7 @@ export async function getUser() { * @throws Redirects to /login if user is not authenticated */ export async function getUserId() { - const session = await auth.api.getSession({ headers: await headers() }); + const session = await getSessionCached(); if (!session?.user) { redirect("/login"); @@ -38,7 +47,7 @@ export async function getUserId() { * @throws Redirects to /login if user is not authenticated */ export async function getUserSession() { - const session = await auth.api.getSession({ headers: await headers() }); + const session = await getSessionCached(); if (!session?.user) { redirect("/login"); @@ -53,5 +62,5 @@ export async function getUserSession() { * @note This function does not redirect if user is not authenticated */ export async function getOptionalUserSession() { - return auth.api.getSession({ headers: await headers() }); + return getSessionCached(); } diff --git a/lib/dashboard/boletos.ts b/lib/dashboard/boletos.ts index 0fe418d..1d28c97 100644 --- a/lib/dashboard/boletos.ts +++ b/lib/dashboard/boletos.ts @@ -1,9 +1,10 @@ "use server"; import { and, asc, eq } from "drizzle-orm"; -import { lancamentos, pagadores } from "@/db/schema"; +import { lancamentos } from "@/db/schema"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; const PAYMENT_METHOD_BOLETO = "Boleto"; @@ -51,6 +52,11 @@ export async function fetchDashboardBoletos( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { boletos: [], totalPendingAmount: 0, pendingCount: 0 }; + } + const rows = await db .select({ id: lancamentos.id, @@ -61,13 +67,12 @@ export async function fetchDashboardBoletos( isSettled: lancamentos.isSettled, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.paymentMethod, PAYMENT_METHOD_BOLETO), - eq(pagadores.role, "admin"), + eq(lancamentos.pagadorId, adminPagadorId), ), ) .orderBy( diff --git a/lib/dashboard/categories/expenses-by-category.ts b/lib/dashboard/categories/expenses-by-category.ts index 87130ae..70c5de0 100644 --- a/lib/dashboard/categories/expenses-by-category.ts +++ b/lib/dashboard/categories/expenses-by-category.ts @@ -1,9 +1,10 @@ -import { and, eq, isNull, or, sql } from "drizzle-orm"; -import { categorias, lancamentos, orcamentos, pagadores } from "@/db/schema"; +import { and, eq, inArray, isNull, or, sql } from "drizzle-orm"; +import { categorias, lancamentos, orcamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; +import { calculatePercentageChange } from "@/lib/utils/math"; import { getPreviousPeriod } from "@/lib/utils/period"; export type CategoryExpenseItem = { @@ -24,138 +25,129 @@ export type ExpensesByCategoryData = { previousTotal: number; }; -const calculatePercentageChange = ( - current: number, - previous: number, -): number | null => { - const EPSILON = 0.01; // Considera valores menores que 1 centavo como zero - - if (Math.abs(previous) < EPSILON) { - if (Math.abs(current) < EPSILON) return null; - return current > 0 ? 100 : -100; - } - - const change = ((current - previous) / Math.abs(previous)) * 100; - - // Protege contra valores absurdos (retorna null se > 1 milhão %) - return Number.isFinite(change) && Math.abs(change) < 1000000 ? change : null; -}; - export async function fetchExpensesByCategory( userId: string, period: string, ): Promise { const previousPeriod = getPreviousPeriod(period); - // Busca despesas do período atual agrupadas por categoria - const currentPeriodRows = await db - .select({ - categoryId: categorias.id, - categoryName: categorias.name, - categoryIcon: categorias.icon, - total: sql`coalesce(sum(${lancamentos.amount}), 0)`, - budgetAmount: orcamentos.amount, - }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .innerJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) - .leftJoin( - orcamentos, - and( - eq(orcamentos.categoriaId, categorias.id), - eq(orcamentos.period, period), - eq(orcamentos.userId, userId), - ), - ) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, period), - eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), - eq(categorias.type, "despesa"), - or( - isNull(lancamentos.note), - sql`${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { categories: [], currentTotal: 0, previousTotal: 0 }; + } + + // Single query: GROUP BY categoriaId + period for both current and previous periods + const [rows, budgetRows] = await Promise.all([ + db + .select({ + categoryId: categorias.id, + categoryName: categorias.name, + categoryIcon: categorias.icon, + period: lancamentos.period, + total: sql`coalesce(sum(${lancamentos.amount}), 0)`, + }) + .from(lancamentos) + .innerJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) + .where( + and( + eq(lancamentos.userId, userId), + eq(lancamentos.pagadorId, adminPagadorId), + inArray(lancamentos.period, [period, previousPeriod]), + eq(lancamentos.transactionType, "Despesa"), + eq(categorias.type, "despesa"), + or( + isNull(lancamentos.note), + sql`${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, + ), ), + ) + .groupBy( + categorias.id, + categorias.name, + categorias.icon, + lancamentos.period, ), - ) - .groupBy( - categorias.id, - categorias.name, - categorias.icon, - orcamentos.amount, - ); + db + .select({ + categoriaId: orcamentos.categoriaId, + amount: orcamentos.amount, + }) + .from(orcamentos) + .where(and(eq(orcamentos.userId, userId), eq(orcamentos.period, period))), + ]); - // Busca despesas do período anterior agrupadas por categoria - const previousPeriodRows = await db - .select({ - categoryId: categorias.id, - total: sql`coalesce(sum(${lancamentos.amount}), 0)`, - }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .innerJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, previousPeriod), - eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), - eq(categorias.type, "despesa"), - or( - isNull(lancamentos.note), - sql`${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, - ), - ), - ) - .groupBy(categorias.id); + // Build budget lookup + const budgetMap = new Map(); + for (const row of budgetRows) { + if (row.categoriaId) { + budgetMap.set(row.categoriaId, toNumber(row.amount)); + } + } - // Cria um mapa do período anterior para busca rápida - const previousMap = new Map(); - let previousTotal = 0; + // Build category data from grouped results + const categoryMap = new Map< + string, + { + name: string; + icon: string | null; + current: number; + previous: number; + } + >(); + + for (const row of rows) { + const entry = categoryMap.get(row.categoryId) ?? { + name: row.categoryName, + icon: row.categoryIcon, + current: 0, + previous: 0, + }; - for (const row of previousPeriodRows) { const amount = Math.abs(toNumber(row.total)); - previousMap.set(row.categoryId, amount); - previousTotal += amount; + if (row.period === period) { + entry.current = amount; + } else { + entry.previous = amount; + } + categoryMap.set(row.categoryId, entry); } - // Calcula o total do período atual + // Calculate totals let currentTotal = 0; - for (const row of currentPeriodRows) { - currentTotal += Math.abs(toNumber(row.total)); + let previousTotal = 0; + for (const entry of categoryMap.values()) { + currentTotal += entry.current; + previousTotal += entry.previous; } - // Monta os dados de cada categoria - const categories: CategoryExpenseItem[] = currentPeriodRows.map((row) => { - const currentAmount = Math.abs(toNumber(row.total)); - const previousAmount = previousMap.get(row.categoryId) ?? 0; + // Build result + const categories: CategoryExpenseItem[] = []; + for (const [categoryId, entry] of categoryMap) { const percentageChange = calculatePercentageChange( - currentAmount, - previousAmount, + entry.current, + entry.previous, ); const percentageOfTotal = - currentTotal > 0 ? (currentAmount / currentTotal) * 100 : 0; + currentTotal > 0 ? (entry.current / currentTotal) * 100 : 0; - const budgetAmount = row.budgetAmount ? toNumber(row.budgetAmount) : null; + const budgetAmount = budgetMap.get(categoryId) ?? null; const budgetUsedPercentage = budgetAmount && budgetAmount > 0 - ? (currentAmount / budgetAmount) * 100 + ? (entry.current / budgetAmount) * 100 : null; - return { - categoryId: row.categoryId, - categoryName: row.categoryName, - categoryIcon: row.categoryIcon, - currentAmount, - previousAmount, + categories.push({ + categoryId, + categoryName: entry.name, + categoryIcon: entry.icon, + currentAmount: entry.current, + previousAmount: entry.previous, percentageChange, percentageOfTotal, budgetAmount, budgetUsedPercentage, - }; - }); + }); + } // Ordena por valor atual (maior para menor) categories.sort((a, b) => b.currentAmount - a.currentAmount); diff --git a/lib/dashboard/categories/income-by-category.ts b/lib/dashboard/categories/income-by-category.ts index 0d34b73..d544d1f 100644 --- a/lib/dashboard/categories/income-by-category.ts +++ b/lib/dashboard/categories/income-by-category.ts @@ -1,17 +1,11 @@ -import { and, eq, isNull, ne, or, sql } from "drizzle-orm"; -import { - categorias, - contas, - lancamentos, - orcamentos, - pagadores, -} from "@/db/schema"; +import { and, eq, inArray, isNull, ne, or, sql } from "drizzle-orm"; +import { categorias, contas, lancamentos, orcamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; import { calculatePercentageChange } from "@/lib/utils/math"; import { safeToNumber } from "@/lib/utils/number"; import { getPreviousPeriod } from "@/lib/utils/period"; @@ -40,131 +34,130 @@ export async function fetchIncomeByCategory( ): Promise { const previousPeriod = getPreviousPeriod(period); - // Busca receitas do período atual agrupadas por categoria - const currentPeriodRows = await db - .select({ - categoryId: categorias.id, - categoryName: categorias.name, - categoryIcon: categorias.icon, - total: sql`coalesce(sum(${lancamentos.amount}), 0)`, - budgetAmount: orcamentos.amount, - }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .innerJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) - .leftJoin(contas, eq(lancamentos.contaId, contas.id)) - .leftJoin( - orcamentos, - and( - eq(orcamentos.categoriaId, categorias.id), - eq(orcamentos.period, period), - eq(orcamentos.userId, userId), - ), - ) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, period), - eq(lancamentos.transactionType, "Receita"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), - eq(categorias.type, "receita"), - or( - isNull(lancamentos.note), - sql`${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, - ), - // Excluir saldos iniciais se a conta tiver o flag ativo - or( - ne(lancamentos.note, INITIAL_BALANCE_NOTE), - isNull(contas.excludeInitialBalanceFromIncome), - eq(contas.excludeInitialBalanceFromIncome, false), - ), - ), - ) - .groupBy( - categorias.id, - categorias.name, - categorias.icon, - orcamentos.amount, - ); + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { categories: [], currentTotal: 0, previousTotal: 0 }; + } - // Busca receitas do período anterior agrupadas por categoria - const previousPeriodRows = await db - .select({ - categoryId: categorias.id, - total: sql`coalesce(sum(${lancamentos.amount}), 0)`, - }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .innerJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) - .leftJoin(contas, eq(lancamentos.contaId, contas.id)) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, previousPeriod), - eq(lancamentos.transactionType, "Receita"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), - eq(categorias.type, "receita"), - or( - isNull(lancamentos.note), - sql`${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, - ), - // Excluir saldos iniciais se a conta tiver o flag ativo - or( - ne(lancamentos.note, INITIAL_BALANCE_NOTE), - isNull(contas.excludeInitialBalanceFromIncome), - eq(contas.excludeInitialBalanceFromIncome, false), + // Single query: GROUP BY categoriaId + period for both current and previous periods + const [rows, budgetRows] = await Promise.all([ + db + .select({ + categoryId: categorias.id, + categoryName: categorias.name, + categoryIcon: categorias.icon, + period: lancamentos.period, + total: sql`coalesce(sum(${lancamentos.amount}), 0)`, + }) + .from(lancamentos) + .innerJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) + .leftJoin(contas, eq(lancamentos.contaId, contas.id)) + .where( + and( + eq(lancamentos.userId, userId), + eq(lancamentos.pagadorId, adminPagadorId), + inArray(lancamentos.period, [period, previousPeriod]), + eq(lancamentos.transactionType, "Receita"), + eq(categorias.type, "receita"), + or( + isNull(lancamentos.note), + sql`${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, + ), + // Excluir saldos iniciais se a conta tiver o flag ativo + or( + ne(lancamentos.note, INITIAL_BALANCE_NOTE), + isNull(contas.excludeInitialBalanceFromIncome), + eq(contas.excludeInitialBalanceFromIncome, false), + ), ), + ) + .groupBy( + categorias.id, + categorias.name, + categorias.icon, + lancamentos.period, ), - ) - .groupBy(categorias.id); + db + .select({ + categoriaId: orcamentos.categoriaId, + amount: orcamentos.amount, + }) + .from(orcamentos) + .where(and(eq(orcamentos.userId, userId), eq(orcamentos.period, period))), + ]); - // Cria um mapa do período anterior para busca rápida - const previousMap = new Map(); - let previousTotal = 0; + // Build budget lookup + const budgetMap = new Map(); + for (const row of budgetRows) { + if (row.categoriaId) { + budgetMap.set(row.categoriaId, safeToNumber(row.amount)); + } + } + + // Build category data from grouped results + const categoryMap = new Map< + string, + { + name: string; + icon: string | null; + current: number; + previous: number; + } + >(); + + for (const row of rows) { + const entry = categoryMap.get(row.categoryId) ?? { + name: row.categoryName, + icon: row.categoryIcon, + current: 0, + previous: 0, + }; - for (const row of previousPeriodRows) { const amount = Math.abs(safeToNumber(row.total)); - previousMap.set(row.categoryId, amount); - previousTotal += amount; + if (row.period === period) { + entry.current = amount; + } else { + entry.previous = amount; + } + categoryMap.set(row.categoryId, entry); } - // Calcula o total do período atual + // Calculate totals let currentTotal = 0; - for (const row of currentPeriodRows) { - currentTotal += Math.abs(safeToNumber(row.total)); + let previousTotal = 0; + for (const entry of categoryMap.values()) { + currentTotal += entry.current; + previousTotal += entry.previous; } - // Monta os dados de cada categoria - const categories: CategoryIncomeItem[] = currentPeriodRows.map((row) => { - const currentAmount = Math.abs(safeToNumber(row.total)); - const previousAmount = previousMap.get(row.categoryId) ?? 0; + // Build result + const categories: CategoryIncomeItem[] = []; + for (const [categoryId, entry] of categoryMap) { const percentageChange = calculatePercentageChange( - currentAmount, - previousAmount, + entry.current, + entry.previous, ); const percentageOfTotal = - currentTotal > 0 ? (currentAmount / currentTotal) * 100 : 0; + currentTotal > 0 ? (entry.current / currentTotal) * 100 : 0; - const budgetAmount = row.budgetAmount - ? safeToNumber(row.budgetAmount) - : null; + const budgetAmount = budgetMap.get(categoryId) ?? null; const budgetUsedPercentage = budgetAmount && budgetAmount > 0 - ? (currentAmount / budgetAmount) * 100 + ? (entry.current / budgetAmount) * 100 : null; - return { - categoryId: row.categoryId, - categoryName: row.categoryName, - categoryIcon: row.categoryIcon, - currentAmount, - previousAmount, + categories.push({ + categoryId, + categoryName: entry.name, + categoryIcon: entry.icon, + currentAmount: entry.current, + previousAmount: entry.previous, percentageChange, percentageOfTotal, budgetAmount, budgetUsedPercentage, - }; - }); + }); + } // Ordena por valor atual (maior para menor) categories.sort((a, b) => b.currentAmount - a.currentAmount); diff --git a/lib/dashboard/expenses/installment-expenses.ts b/lib/dashboard/expenses/installment-expenses.ts index 849933d..aef40a1 100644 --- a/lib/dashboard/expenses/installment-expenses.ts +++ b/lib/dashboard/expenses/installment-expenses.ts @@ -1,12 +1,12 @@ import { and, desc, eq, isNull, or, sql } from "drizzle-orm"; -import { lancamentos, pagadores } from "@/db/schema"; +import { lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type InstallmentExpense = { id: string; @@ -28,6 +28,11 @@ export async function fetchInstallmentExpenses( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { expenses: [] }; + } + const rows = await db .select({ id: lancamentos.id, @@ -41,7 +46,6 @@ export async function fetchInstallmentExpenses( period: lancamentos.period, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), @@ -49,7 +53,7 @@ export async function fetchInstallmentExpenses( eq(lancamentos.transactionType, "Despesa"), eq(lancamentos.condition, "Parcelado"), eq(lancamentos.isAnticipated, false), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), or( isNull(lancamentos.note), and( diff --git a/lib/dashboard/expenses/recurring-expenses.ts b/lib/dashboard/expenses/recurring-expenses.ts index 63486a1..2a4c6b9 100644 --- a/lib/dashboard/expenses/recurring-expenses.ts +++ b/lib/dashboard/expenses/recurring-expenses.ts @@ -1,12 +1,12 @@ import { and, desc, eq, isNull, or, sql } from "drizzle-orm"; -import { lancamentos, pagadores } from "@/db/schema"; +import { lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type RecurringExpense = { id: string; @@ -24,6 +24,11 @@ export async function fetchRecurringExpenses( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { expenses: [] }; + } + const results = await db .select({ id: lancamentos.id, @@ -33,14 +38,13 @@ export async function fetchRecurringExpenses( recurrenceCount: lancamentos.recurrenceCount, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Despesa"), eq(lancamentos.condition, "Recorrente"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), or( isNull(lancamentos.note), and( diff --git a/lib/dashboard/expenses/top-expenses.ts b/lib/dashboard/expenses/top-expenses.ts index d722b78..9176861 100644 --- a/lib/dashboard/expenses/top-expenses.ts +++ b/lib/dashboard/expenses/top-expenses.ts @@ -1,12 +1,12 @@ import { and, asc, eq, isNull, or, sql } from "drizzle-orm"; -import { cartoes, contas, lancamentos, pagadores } from "@/db/schema"; +import { cartoes, contas, lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type TopExpense = { id: string; @@ -26,11 +26,16 @@ export async function fetchTopExpenses( period: string, cardOnly: boolean = false, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { expenses: [] }; + } + const conditions = [ eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), or( isNull(lancamentos.note), and( @@ -60,7 +65,6 @@ export async function fetchTopExpenses( accountLogo: contas.logo, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .leftJoin(cartoes, eq(lancamentos.cartaoId, cartoes.id)) .leftJoin(contas, eq(lancamentos.contaId, contas.id)) .where(and(...conditions)) diff --git a/lib/dashboard/fetch-dashboard-data.ts b/lib/dashboard/fetch-dashboard-data.ts index 27664b7..c66fbb0 100644 --- a/lib/dashboard/fetch-dashboard-data.ts +++ b/lib/dashboard/fetch-dashboard-data.ts @@ -1,3 +1,4 @@ +import { unstable_cache } from "next/cache"; import { fetchDashboardAccounts } from "./accounts"; import { fetchDashboardBoletos } from "./boletos"; import { fetchExpensesByCategory } from "./categories/expenses-by-category"; @@ -17,7 +18,7 @@ import { fetchPurchasesByCategory } from "./purchases-by-category"; import { fetchRecentTransactions } from "./recent-transactions"; import { fetchTopEstablishments } from "./top-establishments"; -export async function fetchDashboardData(userId: string, period: string) { +async function fetchDashboardDataInternal(userId: string, period: string) { const [ metrics, accountsSnapshot, @@ -83,4 +84,20 @@ export async function fetchDashboardData(userId: string, period: string) { }; } +/** + * Cached dashboard data fetcher. + * Uses unstable_cache with tags for revalidation on mutations. + * Cache is keyed by userId + period, and invalidated via "dashboard" tag. + */ +export function fetchDashboardData(userId: string, period: string) { + return unstable_cache( + () => fetchDashboardDataInternal(userId, period), + [`dashboard-${userId}-${period}`], + { + tags: ["dashboard", `dashboard-${userId}`], + revalidate: 120, + }, + )(); +} + export type DashboardData = Awaited>; diff --git a/lib/dashboard/income-expense-balance.ts b/lib/dashboard/income-expense-balance.ts index 0de36e6..8c4fd29 100644 --- a/lib/dashboard/income-expense-balance.ts +++ b/lib/dashboard/income-expense-balance.ts @@ -1,11 +1,12 @@ -import { and, eq, isNull, ne, or, sql } from "drizzle-orm"; -import { contas, lancamentos, pagadores } from "@/db/schema"; +import { and, eq, inArray, isNull, ne, or, sql } from "drizzle-orm"; +import { contas, lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type MonthData = { month: string; @@ -66,83 +67,67 @@ export async function fetchIncomeExpenseBalance( userId: string, currentPeriod: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { months: [] }; + } + const periods = generateLast6Months(currentPeriod); - const results = await Promise.all( - periods.map(async (period) => { - // Busca receitas do período - const [incomeRow] = await db - .select({ - total: sql` - coalesce( - sum(${lancamentos.amount}), - 0 - ) - `, - }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .leftJoin(contas, eq(lancamentos.contaId, contas.id)) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, period), - eq(lancamentos.transactionType, "Receita"), - eq(pagadores.role, "admin"), - sql`(${lancamentos.note} IS NULL OR ${ - lancamentos.note - } NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`})`, - // Excluir saldos iniciais se a conta tiver o flag ativo - or( - ne(lancamentos.note, INITIAL_BALANCE_NOTE), - isNull(contas.excludeInitialBalanceFromIncome), - eq(contas.excludeInitialBalanceFromIncome, false), - ), - ), - ); + // Single query: GROUP BY period + transactionType instead of 12 separate queries + const rows = await db + .select({ + period: lancamentos.period, + transactionType: lancamentos.transactionType, + total: sql`coalesce(sum(${lancamentos.amount}), 0)`, + }) + .from(lancamentos) + .leftJoin(contas, eq(lancamentos.contaId, contas.id)) + .where( + and( + eq(lancamentos.userId, userId), + eq(lancamentos.pagadorId, adminPagadorId), + inArray(lancamentos.period, periods), + inArray(lancamentos.transactionType, ["Receita", "Despesa"]), + sql`(${lancamentos.note} IS NULL OR ${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`})`, + // Excluir saldos iniciais se a conta tiver o flag ativo + or( + ne(lancamentos.note, INITIAL_BALANCE_NOTE), + isNull(contas.excludeInitialBalanceFromIncome), + eq(contas.excludeInitialBalanceFromIncome, false), + ), + ), + ) + .groupBy(lancamentos.period, lancamentos.transactionType); - // Busca despesas do período - const [expenseRow] = await db - .select({ - total: sql` - coalesce( - sum(${lancamentos.amount}), - 0 - ) - `, - }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, period), - eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, "admin"), - sql`(${lancamentos.note} IS NULL OR ${ - lancamentos.note - } NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`})`, - ), - ); + // Build lookup from query results + const dataMap = new Map(); + for (const row of rows) { + if (!row.period) continue; + const entry = dataMap.get(row.period) ?? { income: 0, expense: 0 }; + const total = Math.abs(toNumber(row.total)); + if (row.transactionType === "Receita") { + entry.income = total; + } else if (row.transactionType === "Despesa") { + entry.expense = total; + } + dataMap.set(row.period, entry); + } - const income = Math.abs(toNumber(incomeRow?.total)); - const expense = Math.abs(toNumber(expenseRow?.total)); - const balance = income - expense; + // Build result array preserving period order + const months = periods.map((period) => { + const entry = dataMap.get(period) ?? { income: 0, expense: 0 }; + const [, monthPart] = period.split("-"); + const monthLabel = MONTH_LABELS[monthPart ?? "01"] ?? monthPart; - const [, monthPart] = period.split("-"); - const monthLabel = MONTH_LABELS[monthPart ?? "01"] ?? monthPart; + return { + month: period, + monthLabel: monthLabel ?? "", + income: entry.income, + expense: entry.expense, + balance: entry.income - entry.expense, + }; + }); - return { - month: period, - monthLabel: monthLabel ?? "", - income, - expense, - balance, - }; - }), - ); - - return { - months: results, - }; + return { months }; } diff --git a/lib/dashboard/metrics.ts b/lib/dashboard/metrics.ts index 77afe6e..28e1ec9 100644 --- a/lib/dashboard/metrics.ts +++ b/lib/dashboard/metrics.ts @@ -2,6 +2,7 @@ import { and, asc, eq, + gte, ilike, isNull, lte, @@ -10,15 +11,16 @@ import { or, sum, } from "drizzle-orm"; -import { contas, lancamentos, pagadores } from "@/db/schema"; +import { contas, lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; import { safeToNumber } from "@/lib/utils/number"; import { + addMonthsToPeriod, buildPeriodRange, comparePeriods, getPreviousPeriod, @@ -80,6 +82,21 @@ export async function fetchDashboardCardMetrics( ): Promise { const previousPeriod = getPreviousPeriod(period); + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { + period, + previousPeriod, + receitas: { current: 0, previous: 0 }, + despesas: { current: 0, previous: 0 }, + balanco: { current: 0, previous: 0 }, + previsto: { current: 0, previous: 0 }, + }; + } + + // Limitar scan histórico a 24 meses para evitar scans progressivamente mais lentos + const startPeriod = addMonthsToPeriod(period, -24); + const rows = await db .select({ period: lancamentos.period, @@ -87,13 +104,13 @@ export async function fetchDashboardCardMetrics( totalAmount: sum(lancamentos.amount).as("total"), }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .leftJoin(contas, eq(lancamentos.contaId, contas.id)) .where( and( eq(lancamentos.userId, userId), + eq(lancamentos.pagadorId, adminPagadorId), + gte(lancamentos.period, startPeriod), lte(lancamentos.period, period), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), ne(lancamentos.transactionType, TRANSFERENCIA), or( isNull(lancamentos.note), @@ -129,12 +146,12 @@ export async function fetchDashboardCardMetrics( const earliestPeriod = periodTotals.size > 0 ? Array.from(periodTotals.keys()).sort()[0] : period; - const startPeriod = + const startRangePeriod = comparePeriods(earliestPeriod, previousPeriod) <= 0 ? earliestPeriod : previousPeriod; - const periodRange = buildPeriodRange(startPeriod, period); + const periodRange = buildPeriodRange(startRangePeriod, period); const forecastByPeriod = new Map(); let runningForecast = 0; diff --git a/lib/dashboard/notifications.ts b/lib/dashboard/notifications.ts index be7af51..02c1eef 100644 --- a/lib/dashboard/notifications.ts +++ b/lib/dashboard/notifications.ts @@ -1,9 +1,10 @@ "use server"; import { and, eq, lt, sql } from "drizzle-orm"; -import { cartoes, faturas, lancamentos, pagadores } from "@/db/schema"; +import { cartoes, faturas, lancamentos } from "@/db/schema"; import { db } from "@/lib/db"; import { INVOICE_PAYMENT_STATUS } from "@/lib/faturas"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type NotificationType = "overdue" | "due_soon"; @@ -138,6 +139,8 @@ export async function fetchDashboardNotifications( const today = normalizeDate(new Date()); const DAYS_THRESHOLD = 5; + const adminPagadorId = await getAdminPagadorId(userId); + // Buscar faturas pendentes de períodos anteriores // Apenas faturas com registro na tabela (períodos antigos devem ter sido finalizados) const overdueInvoices = await db @@ -210,7 +213,17 @@ export async function fetchDashboardNotifications( faturas.paymentStatus, ); - // Buscar boletos não pagos + // Buscar boletos não pagos (usando pagadorId direto ao invés de JOIN) + const boletosConditions = [ + eq(lancamentos.userId, userId), + eq(lancamentos.paymentMethod, PAYMENT_METHOD_BOLETO), + eq(lancamentos.isSettled, false), + ]; + + if (adminPagadorId) { + boletosConditions.push(eq(lancamentos.pagadorId, adminPagadorId)); + } + const boletosRows = await db .select({ id: lancamentos.id, @@ -220,15 +233,7 @@ export async function fetchDashboardNotifications( period: lancamentos.period, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.paymentMethod, PAYMENT_METHOD_BOLETO), - eq(lancamentos.isSettled, false), - eq(pagadores.role, "admin"), - ), - ); + .where(and(...boletosConditions)); const notifications: DashboardNotification[] = []; diff --git a/lib/dashboard/payments/payment-conditions.ts b/lib/dashboard/payments/payment-conditions.ts index b6926b0..6d0e784 100644 --- a/lib/dashboard/payments/payment-conditions.ts +++ b/lib/dashboard/payments/payment-conditions.ts @@ -1,12 +1,12 @@ import { and, eq, isNull, or, sql } from "drizzle-orm"; -import { lancamentos, pagadores } from "@/db/schema"; +import { lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type PaymentConditionSummary = { condition: string; @@ -23,6 +23,11 @@ export async function fetchPaymentConditions( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { conditions: [] }; + } + const rows = await db .select({ condition: lancamentos.condition, @@ -30,13 +35,12 @@ export async function fetchPaymentConditions( transactions: sql`count(${lancamentos.id})`, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), or( isNull(lancamentos.note), and( diff --git a/lib/dashboard/payments/payment-methods.ts b/lib/dashboard/payments/payment-methods.ts index f000c7a..4ebcf4c 100644 --- a/lib/dashboard/payments/payment-methods.ts +++ b/lib/dashboard/payments/payment-methods.ts @@ -1,12 +1,12 @@ import { and, eq, isNull, or, sql } from "drizzle-orm"; -import { lancamentos, pagadores } from "@/db/schema"; +import { lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type PaymentMethodSummary = { paymentMethod: string; @@ -23,6 +23,11 @@ export async function fetchPaymentMethods( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { methods: [] }; + } + const rows = await db .select({ paymentMethod: lancamentos.paymentMethod, @@ -30,13 +35,12 @@ export async function fetchPaymentMethods( transactions: sql`count(${lancamentos.id})`, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), or( isNull(lancamentos.note), and( diff --git a/lib/dashboard/payments/payment-status.ts b/lib/dashboard/payments/payment-status.ts index 8b079cc..32542d3 100644 --- a/lib/dashboard/payments/payment-status.ts +++ b/lib/dashboard/payments/payment-status.ts @@ -1,8 +1,9 @@ -import { and, eq, sql } from "drizzle-orm"; -import { lancamentos, pagadores } from "@/db/schema"; +import { and, eq, inArray, sql } from "drizzle-orm"; +import { lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type PaymentStatusCategory = { total: number; @@ -15,106 +16,67 @@ export type PaymentStatusData = { expenses: PaymentStatusCategory; }; +const emptyCategory = (): PaymentStatusCategory => ({ + total: 0, + confirmed: 0, + pending: 0, +}); + export async function fetchPaymentStatus( userId: string, period: string, ): Promise { - // Busca receitas confirmadas e pendentes para o período do pagador admin - // Exclui lançamentos de pagamento de fatura (para evitar contagem duplicada) - const incomeResult = await db + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { income: emptyCategory(), expenses: emptyCategory() }; + } + + // Single query: GROUP BY transactionType instead of 2 separate queries + const rows = await db .select({ + transactionType: lancamentos.transactionType, confirmed: sql` - coalesce( - sum( - case - when ${lancamentos.isSettled} = true then ${lancamentos.amount} - else 0 - end - ), - 0 - ) - `, + coalesce( + sum(case when ${lancamentos.isSettled} = true then ${lancamentos.amount} else 0 end), + 0 + ) + `, pending: sql` - coalesce( - sum( - case - when ${lancamentos.isSettled} = false or ${lancamentos.isSettled} is null then ${lancamentos.amount} - else 0 - end - ), - 0 - ) - `, + coalesce( + sum(case when ${lancamentos.isSettled} = false or ${lancamentos.isSettled} is null then ${lancamentos.amount} else 0 end), + 0 + ) + `, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .where( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), - eq(lancamentos.transactionType, "Receita"), - eq(pagadores.role, "admin"), + eq(lancamentos.pagadorId, adminPagadorId), + inArray(lancamentos.transactionType, ["Receita", "Despesa"]), sql`(${lancamentos.note} IS NULL OR ${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`})`, ), - ); + ) + .groupBy(lancamentos.transactionType); - // Busca despesas confirmadas e pendentes para o período do pagador admin - // Exclui lançamentos de pagamento de fatura (para evitar contagem duplicada) - const expensesResult = await db - .select({ - confirmed: sql` - coalesce( - sum( - case - when ${lancamentos.isSettled} = true then ${lancamentos.amount} - else 0 - end - ), - 0 - ) - `, - pending: sql` - coalesce( - sum( - case - when ${lancamentos.isSettled} = false or ${lancamentos.isSettled} is null then ${lancamentos.amount} - else 0 - end - ), - 0 - ) - `, - }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) - .where( - and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, period), - eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, "admin"), - sql`(${lancamentos.note} IS NULL OR ${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`})`, - ), - ); + const result = { income: emptyCategory(), expenses: emptyCategory() }; - const incomeData = incomeResult[0] ?? { confirmed: 0, pending: 0 }; - const confirmedIncome = toNumber(incomeData.confirmed); - const pendingIncome = toNumber(incomeData.pending); + for (const row of rows) { + const confirmed = toNumber(row.confirmed); + const pending = toNumber(row.pending); + const category = { + total: confirmed + pending, + confirmed, + pending, + }; - const expensesData = expensesResult[0] ?? { confirmed: 0, pending: 0 }; - const confirmedExpenses = toNumber(expensesData.confirmed); - const pendingExpenses = toNumber(expensesData.pending); + if (row.transactionType === "Receita") { + result.income = category; + } else if (row.transactionType === "Despesa") { + result.expenses = category; + } + } - return { - income: { - total: confirmedIncome + pendingIncome, - confirmed: confirmedIncome, - pending: pendingIncome, - }, - expenses: { - total: confirmedExpenses + pendingExpenses, - confirmed: confirmedExpenses, - pending: pendingExpenses, - }, - }; + return result; } diff --git a/lib/dashboard/purchases-by-category.ts b/lib/dashboard/purchases-by-category.ts index 9f6cb31..5892b7d 100644 --- a/lib/dashboard/purchases-by-category.ts +++ b/lib/dashboard/purchases-by-category.ts @@ -1,18 +1,12 @@ import { and, desc, eq, inArray, isNull, or, sql } from "drizzle-orm"; -import { - cartoes, - categorias, - contas, - lancamentos, - pagadores, -} from "@/db/schema"; +import { cartoes, categorias, contas, lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type CategoryOption = { id: string; @@ -51,6 +45,11 @@ export async function fetchPurchasesByCategory( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { categories: [], transactionsByCategory: {} }; + } + const transactionsRows = await db .select({ id: lancamentos.id, @@ -64,7 +63,6 @@ export async function fetchPurchasesByCategory( accountLogo: contas.logo, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .innerJoin(categorias, eq(lancamentos.categoriaId, categorias.id)) .leftJoin(cartoes, eq(lancamentos.cartaoId, cartoes.id)) .leftJoin(contas, eq(lancamentos.contaId, contas.id)) @@ -72,7 +70,7 @@ export async function fetchPurchasesByCategory( and( eq(lancamentos.userId, userId), eq(lancamentos.period, period), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), inArray(categorias.type, ["despesa", "receita"]), or( isNull(lancamentos.note), diff --git a/lib/dashboard/recent-transactions.ts b/lib/dashboard/recent-transactions.ts index 11165aa..29bb8df 100644 --- a/lib/dashboard/recent-transactions.ts +++ b/lib/dashboard/recent-transactions.ts @@ -1,12 +1,12 @@ import { and, desc, eq, isNull, or, sql } from "drizzle-orm"; -import { cartoes, contas, lancamentos, pagadores } from "@/db/schema"; +import { cartoes, contas, lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type RecentTransaction = { id: string; @@ -25,6 +25,11 @@ export async function fetchRecentTransactions( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { transactions: [] }; + } + const results = await db .select({ id: lancamentos.id, @@ -36,7 +41,6 @@ export async function fetchRecentTransactions( note: lancamentos.note, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .leftJoin(cartoes, eq(lancamentos.cartaoId, cartoes.id)) .leftJoin(contas, eq(lancamentos.contaId, contas.id)) .where( @@ -44,7 +48,7 @@ export async function fetchRecentTransactions( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), or( isNull(lancamentos.note), and( diff --git a/lib/dashboard/top-establishments.ts b/lib/dashboard/top-establishments.ts index c87957e..69fd1ac 100644 --- a/lib/dashboard/top-establishments.ts +++ b/lib/dashboard/top-establishments.ts @@ -1,12 +1,12 @@ import { and, eq, isNull, or, sql } from "drizzle-orm"; -import { cartoes, contas, lancamentos, pagadores } from "@/db/schema"; +import { cartoes, contas, lancamentos } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, INITIAL_BALANCE_NOTE, } from "@/lib/accounts/constants"; import { toNumber } from "@/lib/dashboard/common"; import { db } from "@/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; +import { getAdminPagadorId } from "@/lib/pagadores/get-admin-id"; export type TopEstablishment = { id: string; @@ -38,6 +38,11 @@ export async function fetchTopEstablishments( userId: string, period: string, ): Promise { + const adminPagadorId = await getAdminPagadorId(userId); + if (!adminPagadorId) { + return { establishments: [] }; + } + const rows = await db .select({ name: lancamentos.name, @@ -46,7 +51,6 @@ export async function fetchTopEstablishments( logo: sql`max(coalesce(${cartoes.logo}, ${contas.logo}))`, }) .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) .leftJoin(cartoes, eq(lancamentos.cartaoId, cartoes.id)) .leftJoin(contas, eq(lancamentos.contaId, contas.id)) .where( @@ -54,7 +58,7 @@ export async function fetchTopEstablishments( eq(lancamentos.userId, userId), eq(lancamentos.period, period), eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(lancamentos.pagadorId, adminPagadorId), or( isNull(lancamentos.note), and( diff --git a/lib/pagadores/get-admin-id.ts b/lib/pagadores/get-admin-id.ts new file mode 100644 index 0000000..f858dcb --- /dev/null +++ b/lib/pagadores/get-admin-id.ts @@ -0,0 +1,25 @@ +import { and, eq } from "drizzle-orm"; +import { cache } from "react"; +import { pagadores } from "@/db/schema"; +import { db } from "@/lib/db"; +import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; + +/** + * Returns the admin pagador ID for a user (cached per request via React.cache). + * Eliminates the need for JOIN with pagadores in ~20 dashboard queries. + */ +export const getAdminPagadorId = cache( + async (userId: string): Promise => { + const [row] = await db + .select({ id: pagadores.id }) + .from(pagadores) + .where( + and( + eq(pagadores.userId, userId), + eq(pagadores.role, PAGADOR_ROLE_ADMIN), + ), + ) + .limit(1); + return row?.id ?? null; + }, +); diff --git a/package.json b/package.json index 755061c..545ea62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opensheets", - "version": "1.2.6", + "version": "1.3.0", "private": true, "scripts": { "dev": "next dev --turbopack", @@ -27,8 +27,8 @@ "docker:rebuild": "docker compose up --build --force-recreate" }, "dependencies": { - "@ai-sdk/anthropic": "^3.0.35", - "@ai-sdk/google": "^3.0.20", + "@ai-sdk/anthropic": "^3.0.37", + "@ai-sdk/google": "^3.0.21", "@ai-sdk/openai": "^3.0.25", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", @@ -59,7 +59,7 @@ "@tanstack/react-table": "8.21.3", "@vercel/analytics": "^1.6.1", "@vercel/speed-insights": "^1.3.1", - "ai": "^6.0.67", + "ai": "^6.0.73", "babel-plugin-react-compiler": "^1.0.0", "better-auth": "1.4.18", "class-variance-authority": "0.7.1", @@ -67,7 +67,7 @@ "cmdk": "^1.1.1", "date-fns": "^4.1.0", "drizzle-orm": "0.45.1", - "jspdf": "^4.0.0", + "jspdf": "^4.1.0", "jspdf-autotable": "^5.0.7", "next": "16.1.6", "next-themes": "0.4.6", @@ -84,13 +84,13 @@ "zod": "4.3.6" }, "devDependencies": { - "@biomejs/biome": "2.3.13", + "@biomejs/biome": "2.3.14", "@tailwindcss/postcss": "4.1.18", - "@types/node": "25.1.0", + "@types/node": "25.2.1", "@types/pg": "^8.16.0", - "@types/react": "19.2.10", + "@types/react": "19.2.13", "@types/react-dom": "19.2.3", - "dotenv": "^17.2.3", + "dotenv": "^17.2.4", "drizzle-kit": "0.31.8", "tailwindcss": "4.1.18", "tsx": "4.21.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d92c763..6c73898 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,11 +9,11 @@ importers: .: dependencies: '@ai-sdk/anthropic': - specifier: ^3.0.35 - version: 3.0.35(zod@4.3.6) + specifier: ^3.0.37 + version: 3.0.37(zod@4.3.6) '@ai-sdk/google': - specifier: ^3.0.20 - version: 3.0.20(zod@4.3.6) + specifier: ^3.0.21 + version: 3.0.21(zod@4.3.6) '@ai-sdk/openai': specifier: ^3.0.25 version: 3.0.25(zod@4.3.6) @@ -28,70 +28,70 @@ importers: version: 3.2.2(react@19.2.4) '@openrouter/ai-sdk-provider': specifier: ^2.1.1 - version: 2.1.1(ai@6.0.67(zod@4.3.6))(zod@4.3.6) + version: 2.1.1(ai@6.0.73(zod@4.3.6))(zod@4.3.6) '@radix-ui/react-accordion': specifier: ^1.2.12 - version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-alert-dialog': specifier: 1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-avatar': specifier: 1.1.11 - version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-checkbox': specifier: 1.3.3 - version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-collapsible': specifier: 1.1.12 - version: 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-dialog': specifier: 1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-dropdown-menu': specifier: 2.1.16 - version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-hover-card': specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-label': specifier: 2.1.8 - version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-popover': specifier: ^1.1.15 - version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-progress': specifier: 1.1.8 - version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-radio-group': specifier: ^1.3.8 - version: 1.3.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.3.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-scroll-area': specifier: ^1.2.10 - version: 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-select': specifier: 2.2.6 - version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-separator': specifier: 1.1.8 - version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-slot': specifier: 1.2.4 - version: 1.2.4(@types/react@19.2.10)(react@19.2.4) + version: 1.2.4(@types/react@19.2.13)(react@19.2.4) '@radix-ui/react-switch': specifier: 1.2.6 - version: 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-tabs': specifier: 1.1.13 - version: 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-toggle': specifier: 1.1.10 - version: 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-toggle-group': specifier: 1.1.11 - version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-tooltip': specifier: 1.2.8 - version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@remixicon/react': specifier: 4.9.0 version: 4.9.0(react@19.2.4) @@ -105,8 +105,8 @@ importers: specifier: ^1.3.1 version: 1.3.1(next@16.1.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) ai: - specifier: ^6.0.67 - version: 6.0.67(zod@4.3.6) + specifier: ^6.0.73 + version: 6.0.73(zod@4.3.6) babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 @@ -121,7 +121,7 @@ importers: version: 2.1.1 cmdk: specifier: ^1.1.1 - version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) date-fns: specifier: ^4.1.0 version: 4.1.0 @@ -129,11 +129,11 @@ importers: specifier: 0.45.1 version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.16.0)(kysely@0.28.11)(pg@8.18.0) jspdf: - specifier: ^4.0.0 - version: 4.0.0 + specifier: ^4.1.0 + version: 4.1.0 jspdf-autotable: specifier: ^5.0.7 - version: 5.0.7(jspdf@4.0.0) + version: 5.0.7(jspdf@4.1.0) next: specifier: 16.1.6 version: 16.1.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -154,7 +154,7 @@ importers: version: 19.2.4(react@19.2.4) recharts: specifier: 3.7.0 - version: 3.7.0(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1) + version: 3.7.0(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1) resend: specifier: ^6.9.1 version: 6.9.1 @@ -166,7 +166,7 @@ importers: version: 3.4.0 vaul: specifier: 1.1.2 - version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) xlsx: specifier: ^0.18.5 version: 0.18.5 @@ -175,26 +175,26 @@ importers: version: 4.3.6 devDependencies: '@biomejs/biome': - specifier: 2.3.13 - version: 2.3.13 + specifier: 2.3.14 + version: 2.3.14 '@tailwindcss/postcss': specifier: 4.1.18 version: 4.1.18 '@types/node': - specifier: 25.1.0 - version: 25.1.0 + specifier: 25.2.1 + version: 25.2.1 '@types/pg': specifier: ^8.16.0 version: 8.16.0 '@types/react': - specifier: 19.2.10 - version: 19.2.10 + specifier: 19.2.13 + version: 19.2.13 '@types/react-dom': specifier: 19.2.3 - version: 19.2.3(@types/react@19.2.10) + version: 19.2.3(@types/react@19.2.13) dotenv: - specifier: ^17.2.3 - version: 17.2.3 + specifier: ^17.2.4 + version: 17.2.4 drizzle-kit: specifier: 0.31.8 version: 0.31.8 @@ -210,20 +210,20 @@ importers: packages: - '@ai-sdk/anthropic@3.0.35': - resolution: {integrity: sha512-Y3g/5uVj621XSB9lGF7WrD7qR+orhV5xpaYkRF8kfj2j4W7e7BBGIvxcdsCf85FjJbc6tKQdNTZ84ZEqT3Y5TQ==} + '@ai-sdk/anthropic@3.0.37': + resolution: {integrity: sha512-tEgcJPw+a6obbF+SHrEiZsx3DNxOHqeY8bK4IpiNsZ8YPZD141R34g3lEAaQnmNN5mGsEJ8SXoEDabuzi8wFJQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/gateway@3.0.32': - resolution: {integrity: sha512-7clZRr07P9rpur39t1RrbIe7x8jmwnwUWI8tZs+BvAfX3NFgdSVGGIaT7bTz2pb08jmLXzTSDbrOTqAQ7uBkBQ==} + '@ai-sdk/gateway@3.0.36': + resolution: {integrity: sha512-2r1Q6azvqMYxQ1hqfWZmWg4+8MajoldD/ty65XdhCaCoBfvDu7trcvxXDfTSU+3/wZ1JIDky46SWYFOHnTbsBw==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/google@3.0.20': - resolution: {integrity: sha512-bVGsulEr6JiipAFlclo9bjL5WaUV0iCSiiekLt+PY6pwmtJeuU2GaD9DoE3OqR8LN2W779mU13IhVEzlTupf8g==} + '@ai-sdk/google@3.0.21': + resolution: {integrity: sha512-qQuvcbDqDPZojtoT45UFCQVH2w3m6KJKKjqJduUsvhN5ZqOXste0h4HgHK8hwGuDfv96Jr9QQEpspbgp6iu5Uw==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -285,59 +285,59 @@ packages: '@better-fetch/fetch@1.1.21': resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==} - '@biomejs/biome@2.3.13': - resolution: {integrity: sha512-Fw7UsV0UAtWIBIm0M7g5CRerpu1eKyKAXIazzxhbXYUyMkwNrkX/KLkGI7b+uVDQ5cLUMfOC9vR60q9IDYDstA==} + '@biomejs/biome@2.3.14': + resolution: {integrity: sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.3.13': - resolution: {integrity: sha512-0OCwP0/BoKzyJHnFdaTk/i7hIP9JHH9oJJq6hrSCPmJPo8JWcJhprK4gQlhFzrwdTBAW4Bjt/RmCf3ZZe59gwQ==} + '@biomejs/cli-darwin-arm64@2.3.14': + resolution: {integrity: sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.3.13': - resolution: {integrity: sha512-AGr8OoemT/ejynbIu56qeil2+F2WLkIjn2d8jGK1JkchxnMUhYOfnqc9sVzcRxpG9Ycvw4weQ5sprRvtb7Yhcw==} + '@biomejs/cli-darwin-x64@2.3.14': + resolution: {integrity: sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.3.13': - resolution: {integrity: sha512-TUdDCSY+Eo/EHjhJz7P2GnWwfqet+lFxBZzGHldrvULr59AgahamLs/N85SC4+bdF86EhqDuuw9rYLvLFWWlXA==} + '@biomejs/cli-linux-arm64-musl@2.3.14': + resolution: {integrity: sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [musl] - '@biomejs/cli-linux-arm64@2.3.13': - resolution: {integrity: sha512-xvOiFkrDNu607MPMBUQ6huHmBG1PZLOrqhtK6pXJW3GjfVqJg0Z/qpTdhXfcqWdSZHcT+Nct2fOgewZvytESkw==} + '@biomejs/cli-linux-arm64@2.3.14': + resolution: {integrity: sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.3.13': - resolution: {integrity: sha512-0bdwFVSbbM//Sds6OjtnmQGp4eUjOTt6kHvR/1P0ieR9GcTUAlPNvPC3DiavTqq302W34Ae2T6u5VVNGuQtGlQ==} + '@biomejs/cli-linux-x64-musl@2.3.14': + resolution: {integrity: sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [musl] - '@biomejs/cli-linux-x64@2.3.13': - resolution: {integrity: sha512-s+YsZlgiXNq8XkgHs6xdvKDFOj/bwTEevqEY6rC2I3cBHbxXYU1LOZstH3Ffw9hE5tE1sqT7U23C00MzkXztMw==} + '@biomejs/cli-linux-x64@2.3.14': + resolution: {integrity: sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [glibc] - '@biomejs/cli-win32-arm64@2.3.13': - resolution: {integrity: sha512-QweDxY89fq0VvrxME+wS/BXKmqMrOTZlN9SqQ79kQSIc3FrEwvW/PvUegQF6XIVaekncDykB5dzPqjbwSKs9DA==} + '@biomejs/cli-win32-arm64@2.3.14': + resolution: {integrity: sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.3.13': - resolution: {integrity: sha512-trDw2ogdM2lyav9WFQsdsfdVy1dvZALymRpgmWsvSez0BJzBjulhOT/t+wyKeh3pZWvwP3VMs1SoOKwO3wecMQ==} + '@biomejs/cli-win32-x64@2.3.14': + resolution: {integrity: sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -387,8 +387,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.2': - resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -405,8 +405,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.2': - resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -423,8 +423,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.2': - resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -441,8 +441,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.2': - resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -459,8 +459,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.2': - resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -477,8 +477,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.2': - resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -495,8 +495,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.2': - resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -513,8 +513,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.2': - resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -531,8 +531,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.2': - resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -549,8 +549,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.2': - resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -567,8 +567,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.2': - resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -585,8 +585,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.2': - resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -603,8 +603,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.2': - resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -621,8 +621,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.2': - resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -639,8 +639,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.2': - resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -657,8 +657,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.2': - resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -675,8 +675,8 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.2': - resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -687,8 +687,8 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.27.2': - resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -705,8 +705,8 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.2': - resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -717,8 +717,8 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.2': - resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -735,8 +735,8 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.2': - resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -747,8 +747,8 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.27.2': - resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -765,8 +765,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.2': - resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -783,8 +783,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.2': - resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -801,8 +801,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.2': - resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -819,8 +819,8 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.2': - resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1822,8 +1822,8 @@ packages: '@types/d3-timer@3.0.2': resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} - '@types/node@25.1.0': - resolution: {integrity: sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==} + '@types/node@25.2.1': + resolution: {integrity: sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==} '@types/pako@2.0.4': resolution: {integrity: sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==} @@ -1839,8 +1839,8 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.10': - resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==} + '@types/react@19.2.13': + resolution: {integrity: sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ==} '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -1908,8 +1908,8 @@ packages: resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} engines: {node: '>=0.8'} - ai@6.0.67: - resolution: {integrity: sha512-xBnTcByHCj3OcG6V8G1s6zvSEqK0Bdiu+IEXYcpGrve1iGFFRgcrKeZtr/WAW/7gupnSvBbDF24BEv1OOfqi1g==} + ai@6.0.73: + resolution: {integrity: sha512-p2/ICXIjAM4+bIFHEkAB+l58zq+aTmxAkotsb6doNt/CEms72zt6gxv2ky1fQDwU4ecMOcmMh78VJUSEKECzlg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -2002,8 +2002,8 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - caniuse-lite@1.0.30001766: - resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} + caniuse-lite@1.0.30001769: + resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} canvg@3.0.11: resolution: {integrity: sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==} @@ -2139,8 +2139,8 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dotenv@17.2.3: - resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + dotenv@17.2.4: + resolution: {integrity: sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==} engines: {node: '>=12'} drizzle-kit@0.31.8: @@ -2243,8 +2243,8 @@ packages: resolution: {integrity: sha512-EuJWwlHPZ1LbADuKTClvHtwbaFn4rOD+dRAbWysqEOXRc2Uui0hJInNJrsdH0c+OhJA4nrCBdSkW4DD5YxAo6A==} engines: {node: '>=8.10.0'} - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -2269,8 +2269,8 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.27.2: - resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} engines: {node: '>=18'} hasBin: true @@ -2303,8 +2303,8 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} - get-tsconfig@4.13.1: - resolution: {integrity: sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==} + get-tsconfig@4.13.5: + resolution: {integrity: sha512-v4/4xAEpBRp6SvCkWhnGCaLkJf9IwWzrsygJPxD/+p2/xPE3C5m2fA9FD0Ry9tG+Rqqq3gBzHSl6y1/T9V/tMQ==} graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2360,8 +2360,8 @@ packages: peerDependencies: jspdf: ^2 || ^3 || ^4 - jspdf@4.0.0: - resolution: {integrity: sha512-w12U97Z6edKd2tXDn3LzTLg7C7QLJlx0BPfM3ecjK2BckUl9/81vZ+r5gK4/3KQdhAcEZhENUxRhtgYBj75MqQ==} + jspdf@4.1.0: + resolution: {integrity: sha512-xd1d/XRkwqnsq6FP3zH1Q+Ejqn2ULIJeDZ+FTKpaabVpZREjsJKRJwuokTNgdqOU+fl55KgbvgZ1pRTSWCP2kQ==} kysely@0.28.11: resolution: {integrity: sha512-zpGIFg0HuoC893rIjYX1BETkVWdDnzTzF5e0kWXJFg5lE0k1/LfNWBejrcnOFu8Q2Rfq/hTDTU7XLUM8QOrpzg==} @@ -2695,8 +2695,8 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true @@ -2861,20 +2861,20 @@ packages: snapshots: - '@ai-sdk/anthropic@3.0.35(zod@4.3.6)': + '@ai-sdk/anthropic@3.0.37(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.7 '@ai-sdk/provider-utils': 4.0.13(zod@4.3.6) zod: 4.3.6 - '@ai-sdk/gateway@3.0.32(zod@4.3.6)': + '@ai-sdk/gateway@3.0.36(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.7 '@ai-sdk/provider-utils': 4.0.13(zod@4.3.6) '@vercel/oidc': 3.1.0 zod: 4.3.6 - '@ai-sdk/google@3.0.20(zod@4.3.6)': + '@ai-sdk/google@3.0.21(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.7 '@ai-sdk/provider-utils': 4.0.13(zod@4.3.6) @@ -2931,39 +2931,39 @@ snapshots: '@better-fetch/fetch@1.1.21': {} - '@biomejs/biome@2.3.13': + '@biomejs/biome@2.3.14': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.3.13 - '@biomejs/cli-darwin-x64': 2.3.13 - '@biomejs/cli-linux-arm64': 2.3.13 - '@biomejs/cli-linux-arm64-musl': 2.3.13 - '@biomejs/cli-linux-x64': 2.3.13 - '@biomejs/cli-linux-x64-musl': 2.3.13 - '@biomejs/cli-win32-arm64': 2.3.13 - '@biomejs/cli-win32-x64': 2.3.13 + '@biomejs/cli-darwin-arm64': 2.3.14 + '@biomejs/cli-darwin-x64': 2.3.14 + '@biomejs/cli-linux-arm64': 2.3.14 + '@biomejs/cli-linux-arm64-musl': 2.3.14 + '@biomejs/cli-linux-x64': 2.3.14 + '@biomejs/cli-linux-x64-musl': 2.3.14 + '@biomejs/cli-win32-arm64': 2.3.14 + '@biomejs/cli-win32-x64': 2.3.14 - '@biomejs/cli-darwin-arm64@2.3.13': + '@biomejs/cli-darwin-arm64@2.3.14': optional: true - '@biomejs/cli-darwin-x64@2.3.13': + '@biomejs/cli-darwin-x64@2.3.14': optional: true - '@biomejs/cli-linux-arm64-musl@2.3.13': + '@biomejs/cli-linux-arm64-musl@2.3.14': optional: true - '@biomejs/cli-linux-arm64@2.3.13': + '@biomejs/cli-linux-arm64@2.3.14': optional: true - '@biomejs/cli-linux-x64-musl@2.3.13': + '@biomejs/cli-linux-x64-musl@2.3.14': optional: true - '@biomejs/cli-linux-x64@2.3.13': + '@biomejs/cli-linux-x64@2.3.14': optional: true - '@biomejs/cli-win32-arm64@2.3.13': + '@biomejs/cli-win32-arm64@2.3.14': optional: true - '@biomejs/cli-win32-x64@2.3.13': + '@biomejs/cli-win32-x64@2.3.14': optional: true '@date-fns/tz@1.4.1': {} @@ -3008,12 +3008,12 @@ snapshots: '@esbuild-kit/esm-loader@2.6.5': dependencies: '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.13.1 + get-tsconfig: 4.13.5 '@esbuild/aix-ppc64@0.25.12': optional: true - '@esbuild/aix-ppc64@0.27.2': + '@esbuild/aix-ppc64@0.27.3': optional: true '@esbuild/android-arm64@0.18.20': @@ -3022,7 +3022,7 @@ snapshots: '@esbuild/android-arm64@0.25.12': optional: true - '@esbuild/android-arm64@0.27.2': + '@esbuild/android-arm64@0.27.3': optional: true '@esbuild/android-arm@0.18.20': @@ -3031,7 +3031,7 @@ snapshots: '@esbuild/android-arm@0.25.12': optional: true - '@esbuild/android-arm@0.27.2': + '@esbuild/android-arm@0.27.3': optional: true '@esbuild/android-x64@0.18.20': @@ -3040,7 +3040,7 @@ snapshots: '@esbuild/android-x64@0.25.12': optional: true - '@esbuild/android-x64@0.27.2': + '@esbuild/android-x64@0.27.3': optional: true '@esbuild/darwin-arm64@0.18.20': @@ -3049,7 +3049,7 @@ snapshots: '@esbuild/darwin-arm64@0.25.12': optional: true - '@esbuild/darwin-arm64@0.27.2': + '@esbuild/darwin-arm64@0.27.3': optional: true '@esbuild/darwin-x64@0.18.20': @@ -3058,7 +3058,7 @@ snapshots: '@esbuild/darwin-x64@0.25.12': optional: true - '@esbuild/darwin-x64@0.27.2': + '@esbuild/darwin-x64@0.27.3': optional: true '@esbuild/freebsd-arm64@0.18.20': @@ -3067,7 +3067,7 @@ snapshots: '@esbuild/freebsd-arm64@0.25.12': optional: true - '@esbuild/freebsd-arm64@0.27.2': + '@esbuild/freebsd-arm64@0.27.3': optional: true '@esbuild/freebsd-x64@0.18.20': @@ -3076,7 +3076,7 @@ snapshots: '@esbuild/freebsd-x64@0.25.12': optional: true - '@esbuild/freebsd-x64@0.27.2': + '@esbuild/freebsd-x64@0.27.3': optional: true '@esbuild/linux-arm64@0.18.20': @@ -3085,7 +3085,7 @@ snapshots: '@esbuild/linux-arm64@0.25.12': optional: true - '@esbuild/linux-arm64@0.27.2': + '@esbuild/linux-arm64@0.27.3': optional: true '@esbuild/linux-arm@0.18.20': @@ -3094,7 +3094,7 @@ snapshots: '@esbuild/linux-arm@0.25.12': optional: true - '@esbuild/linux-arm@0.27.2': + '@esbuild/linux-arm@0.27.3': optional: true '@esbuild/linux-ia32@0.18.20': @@ -3103,7 +3103,7 @@ snapshots: '@esbuild/linux-ia32@0.25.12': optional: true - '@esbuild/linux-ia32@0.27.2': + '@esbuild/linux-ia32@0.27.3': optional: true '@esbuild/linux-loong64@0.18.20': @@ -3112,7 +3112,7 @@ snapshots: '@esbuild/linux-loong64@0.25.12': optional: true - '@esbuild/linux-loong64@0.27.2': + '@esbuild/linux-loong64@0.27.3': optional: true '@esbuild/linux-mips64el@0.18.20': @@ -3121,7 +3121,7 @@ snapshots: '@esbuild/linux-mips64el@0.25.12': optional: true - '@esbuild/linux-mips64el@0.27.2': + '@esbuild/linux-mips64el@0.27.3': optional: true '@esbuild/linux-ppc64@0.18.20': @@ -3130,7 +3130,7 @@ snapshots: '@esbuild/linux-ppc64@0.25.12': optional: true - '@esbuild/linux-ppc64@0.27.2': + '@esbuild/linux-ppc64@0.27.3': optional: true '@esbuild/linux-riscv64@0.18.20': @@ -3139,7 +3139,7 @@ snapshots: '@esbuild/linux-riscv64@0.25.12': optional: true - '@esbuild/linux-riscv64@0.27.2': + '@esbuild/linux-riscv64@0.27.3': optional: true '@esbuild/linux-s390x@0.18.20': @@ -3148,7 +3148,7 @@ snapshots: '@esbuild/linux-s390x@0.25.12': optional: true - '@esbuild/linux-s390x@0.27.2': + '@esbuild/linux-s390x@0.27.3': optional: true '@esbuild/linux-x64@0.18.20': @@ -3157,13 +3157,13 @@ snapshots: '@esbuild/linux-x64@0.25.12': optional: true - '@esbuild/linux-x64@0.27.2': + '@esbuild/linux-x64@0.27.3': optional: true '@esbuild/netbsd-arm64@0.25.12': optional: true - '@esbuild/netbsd-arm64@0.27.2': + '@esbuild/netbsd-arm64@0.27.3': optional: true '@esbuild/netbsd-x64@0.18.20': @@ -3172,13 +3172,13 @@ snapshots: '@esbuild/netbsd-x64@0.25.12': optional: true - '@esbuild/netbsd-x64@0.27.2': + '@esbuild/netbsd-x64@0.27.3': optional: true '@esbuild/openbsd-arm64@0.25.12': optional: true - '@esbuild/openbsd-arm64@0.27.2': + '@esbuild/openbsd-arm64@0.27.3': optional: true '@esbuild/openbsd-x64@0.18.20': @@ -3187,13 +3187,13 @@ snapshots: '@esbuild/openbsd-x64@0.25.12': optional: true - '@esbuild/openbsd-x64@0.27.2': + '@esbuild/openbsd-x64@0.27.3': optional: true '@esbuild/openharmony-arm64@0.25.12': optional: true - '@esbuild/openharmony-arm64@0.27.2': + '@esbuild/openharmony-arm64@0.27.3': optional: true '@esbuild/sunos-x64@0.18.20': @@ -3202,7 +3202,7 @@ snapshots: '@esbuild/sunos-x64@0.25.12': optional: true - '@esbuild/sunos-x64@0.27.2': + '@esbuild/sunos-x64@0.27.3': optional: true '@esbuild/win32-arm64@0.18.20': @@ -3211,7 +3211,7 @@ snapshots: '@esbuild/win32-arm64@0.25.12': optional: true - '@esbuild/win32-arm64@0.27.2': + '@esbuild/win32-arm64@0.27.3': optional: true '@esbuild/win32-ia32@0.18.20': @@ -3220,7 +3220,7 @@ snapshots: '@esbuild/win32-ia32@0.25.12': optional: true - '@esbuild/win32-ia32@0.27.2': + '@esbuild/win32-ia32@0.27.3': optional: true '@esbuild/win32-x64@0.18.20': @@ -3229,7 +3229,7 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true - '@esbuild/win32-x64@0.27.2': + '@esbuild/win32-x64@0.27.3': optional: true '@floating-ui/core@1.7.4': @@ -3395,9 +3395,9 @@ snapshots: '@noble/hashes@2.0.1': {} - '@openrouter/ai-sdk-provider@2.1.1(ai@6.0.67(zod@4.3.6))(zod@4.3.6)': + '@openrouter/ai-sdk-provider@2.1.1(ai@6.0.73(zod@4.3.6))(zod@4.3.6)': dependencies: - ai: 6.0.67(zod@4.3.6) + ai: 6.0.73(zod@4.3.6) zod: 4.3.6 '@opentelemetry/api@1.9.0': {} @@ -3406,596 +3406,596 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-avatar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-avatar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-context': 1.1.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-context': 1.1.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-context@1.1.2(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-context@1.1.2(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-context@1.1.3(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-context@1.1.3(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) aria-hidden: 1.2.6 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.10)(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.13)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-direction@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-direction@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-id@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-id@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) aria-hidden: 1.2.6 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.10)(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.13)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) aria-hidden: 1.2.6 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.10)(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.13)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.13)(react@19.2.4) '@radix-ui/rect': 1.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-slot': 1.2.4(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-progress@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-progress@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-context': 1.1.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-context': 1.1.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) aria-hidden: 1.2.6 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-remove-scroll: 2.7.2(@types/react@19.2.10)(react@19.2.4) + react-remove-scroll: 2.7.2(@types/react@19.2.13)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-slot@1.2.3(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-slot@1.2.3(@types/react@19.2.13)(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-slot@1.2.4(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-slot@1.2.4(@types/react@19.2.13)(react@19.2.4)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.13)(react@19.2.4)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.13)(react@19.2.4)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-is-hydrated@0.1.0(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: '@radix-ui/rect': 1.1.1 react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.10)(react@19.2.4)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.13)(react@19.2.4)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.13)(react@19.2.4) react: 19.2.4 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 - '@types/react-dom': 19.2.3(@types/react@19.2.10) + '@types/react': 19.2.13 + '@types/react-dom': 19.2.3(@types/react@19.2.13) '@radix-ui/rect@1.1.1': {} - '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.10)(react@19.2.4)(redux@5.0.1))(react@19.2.4)': + '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.13)(react@19.2.4)(redux@5.0.1))(react@19.2.4)': dependencies: '@standard-schema/spec': 1.1.0 '@standard-schema/utils': 0.3.0 @@ -4005,7 +4005,7 @@ snapshots: reselect: 5.1.1 optionalDependencies: react: 19.2.4 - react-redux: 9.2.0(@types/react@19.2.10)(react@19.2.4)(redux@5.0.1) + react-redux: 9.2.0(@types/react@19.2.13)(react@19.2.4)(redux@5.0.1) '@remixicon/react@4.9.0(react@19.2.4)': dependencies: @@ -4029,7 +4029,7 @@ snapshots: '@tailwindcss/node@4.1.18': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.19.0 jiti: 2.6.1 lightningcss: 1.30.2 magic-string: 0.30.21 @@ -4127,7 +4127,7 @@ snapshots: '@types/d3-timer@3.0.2': {} - '@types/node@25.1.0': + '@types/node@25.2.1': dependencies: undici-types: 7.16.0 @@ -4135,18 +4135,18 @@ snapshots: '@types/pg@8.16.0': dependencies: - '@types/node': 25.1.0 + '@types/node': 25.2.1 pg-protocol: 1.11.0 pg-types: 2.2.0 '@types/raf@3.4.3': optional: true - '@types/react-dom@19.2.3(@types/react@19.2.10)': + '@types/react-dom@19.2.3(@types/react@19.2.13)': dependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - '@types/react@19.2.10': + '@types/react@19.2.13': dependencies: csstype: 3.2.3 @@ -4175,9 +4175,9 @@ snapshots: adler-32@1.3.1: {} - ai@6.0.67(zod@4.3.6): + ai@6.0.73(zod@4.3.6): dependencies: - '@ai-sdk/gateway': 3.0.32(zod@4.3.6) + '@ai-sdk/gateway': 3.0.36(zod@4.3.6) '@ai-sdk/provider': 3.0.7 '@ai-sdk/provider-utils': 4.0.13(zod@4.3.6) '@opentelemetry/api': 1.9.0 @@ -4229,7 +4229,7 @@ snapshots: buffer-from@1.1.2: {} - caniuse-lite@1.0.30001766: {} + caniuse-lite@1.0.30001769: {} canvg@3.0.11: dependencies: @@ -4256,12 +4256,12 @@ snapshots: clsx@2.1.1: {} - cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.4) - '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.13)(react@19.2.4) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) transitivePeerDependencies: @@ -4361,7 +4361,7 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 - dotenv@17.2.3: {} + dotenv@17.2.4: {} drizzle-kit@0.31.8: dependencies: @@ -4381,7 +4381,7 @@ snapshots: encoding-japanese@2.2.0: {} - enhanced-resolve@5.18.4: + enhanced-resolve@5.19.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.0 @@ -4451,34 +4451,34 @@ snapshots: '@esbuild/win32-ia32': 0.25.12 '@esbuild/win32-x64': 0.25.12 - esbuild@0.27.2: + esbuild@0.27.3: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.2 - '@esbuild/android-arm': 0.27.2 - '@esbuild/android-arm64': 0.27.2 - '@esbuild/android-x64': 0.27.2 - '@esbuild/darwin-arm64': 0.27.2 - '@esbuild/darwin-x64': 0.27.2 - '@esbuild/freebsd-arm64': 0.27.2 - '@esbuild/freebsd-x64': 0.27.2 - '@esbuild/linux-arm': 0.27.2 - '@esbuild/linux-arm64': 0.27.2 - '@esbuild/linux-ia32': 0.27.2 - '@esbuild/linux-loong64': 0.27.2 - '@esbuild/linux-mips64el': 0.27.2 - '@esbuild/linux-ppc64': 0.27.2 - '@esbuild/linux-riscv64': 0.27.2 - '@esbuild/linux-s390x': 0.27.2 - '@esbuild/linux-x64': 0.27.2 - '@esbuild/netbsd-arm64': 0.27.2 - '@esbuild/netbsd-x64': 0.27.2 - '@esbuild/openbsd-arm64': 0.27.2 - '@esbuild/openbsd-x64': 0.27.2 - '@esbuild/openharmony-arm64': 0.27.2 - '@esbuild/sunos-x64': 0.27.2 - '@esbuild/win32-arm64': 0.27.2 - '@esbuild/win32-ia32': 0.27.2 - '@esbuild/win32-x64': 0.27.2 + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 eventemitter3@5.0.4: {} @@ -4501,7 +4501,7 @@ snapshots: get-nonce@1.0.1: {} - get-tsconfig@4.13.1: + get-tsconfig@4.13.5: dependencies: resolve-pkg-maps: 1.0.0 @@ -4552,11 +4552,11 @@ snapshots: json-schema@0.4.0: {} - jspdf-autotable@5.0.7(jspdf@4.0.0): + jspdf-autotable@5.0.7(jspdf@4.1.0): dependencies: - jspdf: 4.0.0 + jspdf: 4.1.0 - jspdf@4.0.0: + jspdf@4.1.0: dependencies: '@babel/runtime': 7.28.6 fast-png: 6.4.0 @@ -4668,7 +4668,7 @@ snapshots: '@next/env': 16.1.6 '@swc/helpers': 0.5.15 baseline-browser-mapping: 2.9.19 - caniuse-lite: 1.0.30001766 + caniuse-lite: 1.0.30001769 postcss: 8.4.31 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -4783,47 +4783,47 @@ snapshots: react-is@16.13.1: {} - react-redux@9.2.0(@types/react@19.2.10)(react@19.2.4)(redux@5.0.1): + react-redux@9.2.0(@types/react@19.2.13)(react@19.2.4)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 react: 19.2.4 use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 redux: 5.0.1 - react-remove-scroll-bar@2.3.8(@types/react@19.2.10)(react@19.2.4): + react-remove-scroll-bar@2.3.8(@types/react@19.2.13)(react@19.2.4): dependencies: react: 19.2.4 - react-style-singleton: 2.2.3(@types/react@19.2.10)(react@19.2.4) + react-style-singleton: 2.2.3(@types/react@19.2.13)(react@19.2.4) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - react-remove-scroll@2.7.2(@types/react@19.2.10)(react@19.2.4): + react-remove-scroll@2.7.2(@types/react@19.2.13)(react@19.2.4): dependencies: react: 19.2.4 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.10)(react@19.2.4) - react-style-singleton: 2.2.3(@types/react@19.2.10)(react@19.2.4) + react-remove-scroll-bar: 2.3.8(@types/react@19.2.13)(react@19.2.4) + react-style-singleton: 2.2.3(@types/react@19.2.13)(react@19.2.4) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.10)(react@19.2.4) - use-sidecar: 1.1.3(@types/react@19.2.10)(react@19.2.4) + use-callback-ref: 1.3.3(@types/react@19.2.13)(react@19.2.4) + use-sidecar: 1.1.3(@types/react@19.2.13)(react@19.2.4) optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - react-style-singleton@2.2.3(@types/react@19.2.10)(react@19.2.4): + react-style-singleton@2.2.3(@types/react@19.2.13)(react@19.2.4): dependencies: get-nonce: 1.0.1 react: 19.2.4 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 react@19.2.4: {} - recharts@3.7.0(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1): + recharts@3.7.0(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1): dependencies: - '@reduxjs/toolkit': 2.11.2(react-redux@9.2.0(@types/react@19.2.10)(react@19.2.4)(redux@5.0.1))(react@19.2.4) + '@reduxjs/toolkit': 2.11.2(react-redux@9.2.0(@types/react@19.2.13)(react@19.2.4)(redux@5.0.1))(react@19.2.4) clsx: 2.1.1 decimal.js-light: 2.5.1 es-toolkit: 1.44.0 @@ -4832,7 +4832,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) react-is: 16.13.1 - react-redux: 9.2.0(@types/react@19.2.10)(react@19.2.4)(redux@5.0.1) + react-redux: 9.2.0(@types/react@19.2.13)(react@19.2.4)(redux@5.0.1) reselect: 5.1.1 tiny-invariant: 1.3.3 use-sync-external-store: 1.6.0(react@19.2.4) @@ -4872,7 +4872,7 @@ snapshots: dependencies: parseley: 0.12.1 - semver@7.7.3: + semver@7.7.4: optional: true set-cookie-parser@2.7.2: {} @@ -4881,7 +4881,7 @@ snapshots: dependencies: '@img/colour': 1.0.0 detect-libc: 2.1.2 - semver: 7.7.3 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -4969,8 +4969,8 @@ snapshots: tsx@4.21.0: dependencies: - esbuild: 0.27.2 - get-tsconfig: 4.13.1 + esbuild: 0.27.3 + get-tsconfig: 4.13.5 optionalDependencies: fsevents: 2.3.3 @@ -4980,20 +4980,20 @@ snapshots: undici-types@7.16.0: {} - use-callback-ref@1.3.3(@types/react@19.2.10)(react@19.2.4): + use-callback-ref@1.3.3(@types/react@19.2.13)(react@19.2.4): dependencies: react: 19.2.4 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 - use-sidecar@1.1.3(@types/react@19.2.10)(react@19.2.4): + use-sidecar@1.1.3(@types/react@19.2.13)(react@19.2.4): dependencies: detect-node-es: 1.1.0 react: 19.2.4 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.10 + '@types/react': 19.2.13 use-sync-external-store@1.6.0(react@19.2.4): dependencies: @@ -5006,9 +5006,9 @@ snapshots: uuid@10.0.0: {} - vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) transitivePeerDependencies: diff --git a/public/fonts/anthropicSans.woff2 b/public/fonts/anthropicSans.woff2 new file mode 100644 index 0000000..eddbf30 Binary files /dev/null and b/public/fonts/anthropicSans.woff2 differ diff --git a/public/fonts/font_index.ts b/public/fonts/font_index.ts index 42df970..4f3e7ce 100644 --- a/public/fonts/font_index.ts +++ b/public/fonts/font_index.ts @@ -16,8 +16,12 @@ const ai_sans = localFont({ display: "swap", }); +const anthropic_sans = localFont({ + src: "./anthropicSans.woff2", + display: "swap", +}); + const main_font = ai_sans; const money_font = ai_sans; -const title_font = ai_sans; -export { main_font, money_font, title_font }; +export { main_font, money_font };