build(i18n): add next-intl routing infrastructure

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
david_bai
2026-03-27 14:04:28 +08:00
parent cf529eed64
commit 6c93b1d995
13 changed files with 558 additions and 155 deletions
+17 -7
View File
@@ -1,9 +1,12 @@
import "./globals.css";
import { hasLocale, NextIntlClientProvider } from "next-intl";
import { getMessages, setRequestLocale } from "next-intl/server";
import { notFound } from "next/navigation";
import Header from "@/components/web/Header";
import Footer from "@/components/web/Footer";
import { TranslationProvider } from "@/components/providers/TranslationProvider";
import { ThemeProvider } from "@/components/web/theme-provider";
import { getDictionary } from "@/lib/dictionary";
import { routing } from "@/i18n/routing";
import JsonLd from "@/components/seo/JsonLd";
import {
absoluteUrl,
@@ -19,7 +22,12 @@ export default async function RootLayout({
children: React.ReactNode;
params: { lang: string };
}>) {
const messages = await getDictionary(lang);
if (!hasLocale(routing.locales, lang)) {
notFound();
}
setRequestLocale(lang);
const messages = await getMessages();
const siteUrl = getSiteUrl();
const logoUrl = absoluteUrl("/logo.png", siteUrl);
const orgJson = buildOrganizationJsonLd({
@@ -48,11 +56,13 @@ export default async function RootLayout({
disableTransitionOnChange
storageKey="theme-preference"
>
<TranslationProvider messages={messages} lang={lang}>
<Header />
<div className="flex-1">{children}</div>
<Footer />
</TranslationProvider>
<NextIntlClientProvider locale={lang} messages={messages}>
<TranslationProvider>
<Header />
<div className="flex-1">{children}</div>
<Footer />
</TranslationProvider>
</NextIntlClientProvider>
</ThemeProvider>
</body>
</html>
+6 -5
View File
@@ -7,17 +7,18 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { usePathname, useRouter } from "next/navigation";
import { useLocale } from "next-intl";
import { usePathname, useRouter } from "@/i18n/navigation";
import { i18n, Locale, languageDisplayNames } from "@/constants/i18n-config";
const LanguageSwitcher = () => {
const locale = useLocale();
const pathname = usePathname();
const router = useRouter();
const switchLanguage = (locale: Locale) => {
const segments = pathname.split("/");
segments[1] = locale;
router.push(segments.join("/"));
const switchLanguage = (nextLocale: Locale) => {
if (nextLocale === locale) return;
router.replace(pathname, { locale: nextLocale });
};
return (
@@ -1,51 +1,33 @@
"use client";
import { createContext, useContext } from "react";
import { useLocale as useNextIntlLocale, useMessages as useNextIntlMessages } from "next-intl";
import type { Messages } from "@/types/messages";
import type { Locale } from "@/constants/i18n-config";
type TranslationContextValue = {
messages: Messages;
lang: string;
};
const TranslationContext = createContext<TranslationContextValue | null>(null);
interface TranslationProviderProps extends TranslationContextValue {
interface TranslationProviderProps {
children: React.ReactNode;
}
export function TranslationProvider({
children,
messages,
lang,
}: TranslationProviderProps) {
return (
<TranslationContext.Provider value={{ messages, lang }}>
{children}
</TranslationContext.Provider>
);
}
function useTranslationContext() {
const context = useContext(TranslationContext);
if (!context) {
throw new Error(
"Translation hooks must be used within TranslationProvider"
);
}
return context;
export function TranslationProvider({children}: TranslationProviderProps) {
return <>{children}</>;
}
export function useMessages() {
return useTranslationContext().messages;
return useNextIntlMessages() as Messages;
}
export function useLang() {
return useTranslationContext().lang;
return useNextIntlLocale() as Locale;
}
export function useI18n() {
return useTranslationContext();
return {
messages: useMessages(),
lang: useLang(),
} satisfies TranslationContextValue;
}
+3 -12
View File
@@ -1,16 +1,7 @@
"use client";
// Get the current language
import { usePathname } from "next/navigation";
import { i18n } from "@/constants/i18n-config";
import { useLocale as useNextIntlLocale } from "next-intl";
import type { Locale } from "@/constants/i18n-config";
export function useLocale() {
const pathname = usePathname();
const locale = pathname?.split("/")[1];
// Validate if the language is supported
if (locale && i18n.locales.includes(locale as any)) {
return locale;
}
return i18n.defaultLocale;
return useNextIntlLocale() as Locale;
}
+5
View File
@@ -0,0 +1,5 @@
import {createNavigation} from 'next-intl/navigation';
import {routing} from './routing';
export const {Link, redirect, usePathname, useRouter, getPathname} =
createNavigation(routing);
+16
View File
@@ -0,0 +1,16 @@
import {getRequestConfig} from 'next-intl/server';
import {hasLocale} from 'next-intl';
import {routing} from './routing';
import {getDictionary} from '../lib/dictionary';
export default getRequestConfig(async ({requestLocale}) => {
const requestedLocale = await requestLocale;
const locale = hasLocale(routing.locales, requestedLocale)
? requestedLocale
: routing.defaultLocale;
return {
locale,
messages: await getDictionary(locale)
};
});
+8
View File
@@ -0,0 +1,8 @@
import {defineRouting} from 'next-intl/routing';
import {i18n} from '@/constants/i18n-config';
export const routing = defineRouting({
locales: [...i18n.locales],
defaultLocale: i18n.defaultLocale,
localePrefix: 'always'
});
+3 -55
View File
@@ -1,60 +1,8 @@
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { i18n } from "@/constants/i18n-config";
import { match as matchLocale } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";
import createMiddleware from "next-intl/middleware";
import {routing} from "@/i18n/routing";
function getLocale(request: NextRequest): string {
// 1. Get Accept-Language from the request
const negotiatorHeaders: Record<string, string> = {};
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));
const locales = i18n.locales;
// 2. Use negotiator to get all supported languages
const languages = new Negotiator({ headers: negotiatorHeaders }).languages();
try {
// 3. Match the best language
const locale = matchLocale(languages, locales, i18n.defaultLocale);
return locale;
} catch (error) {
return i18n.defaultLocale;
}
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname;
// Get all search parameters
const searchParams = request.nextUrl.searchParams;
// Check if the request path already contains a language prefix
const pathnameIsMissingLocale = i18n.locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
);
// If the path has no language prefix, redirect to a path with a language prefix
if (pathnameIsMissingLocale) {
const locale = getLocale(request);
// Create a new URL, preserving the original query parameters
const newUrl = new URL(`/${locale}${pathname}`, request.url);
// Copy the original query parameters to the new URL
searchParams.forEach((value, key) => {
newUrl.searchParams.set(key, value);
});
return NextResponse.redirect(newUrl);
}
}
export default createMiddleware(routing);
export const config = {
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - Or any path that contains a dot (e.g., .png, .jpg, .svg)
*/
matcher: "/((?!api|_next/static|_next/image|favicon.ico|.*\\..*).*)",
};
+4 -1
View File
@@ -1,4 +1,5 @@
import createMDX from '@next/mdx'
import createNextIntlPlugin from 'next-intl/plugin'
const withMDX = createMDX({
extension: /\.mdx?$/,
@@ -8,6 +9,8 @@ const withMDX = createMDX({
},
})
const withNextIntl = createNextIntlPlugin('./i18n/request.ts')
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
@@ -30,4 +33,4 @@ const nextConfig = {
},
}
export default withMDX(nextConfig);
export default withNextIntl(withMDX(nextConfig));
+4 -6
View File
@@ -9,9 +9,9 @@
"lint": "next lint"
},
"dependencies": {
"@formatjs/intl-localematcher": "^0.5.10",
"@mdx-js/loader": "^3.1.0",
"@mdx-js/react": "^3.1.0",
"@next/env": "^14.2.5",
"@next/mdx": "^15.1.5",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-checkbox": "^1.1.1",
@@ -21,9 +21,9 @@
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-toast": "^1.2.2",
"@radix-ui/react-tooltip": "^1.1.2",
"@swc/helpers": "^0.5.5",
"@types/hast": "^3.0.4",
"@types/mdast": "^4.0.4",
"@types/negotiator": "^0.6.3",
"@types/node": "^20.14.13",
"@types/react-dom": "^18.3.0",
"@types/unist": "^3.0.3",
@@ -34,8 +34,8 @@
"lodash": "^4.17.21",
"lucide-react": "^0.417.0",
"mermaid": "^11.4.1",
"negotiator": "^1.0.0",
"next": "14.2.5",
"next-intl": "^4.8.3",
"next-mdx-remote": "^5.0.0",
"next-themes": "^0.3.0",
"qrcode.react": "^4.0.1",
@@ -44,10 +44,8 @@
"react-intersection-observer": "^9.16.0",
"remark-gfm": "^4.0.0",
"sharp": "^0.33.5",
"@swc/helpers": "^0.5.5",
"@next/env": "^14.2.5",
"styled-jsx": "^5.1.1",
"socket.io-client": "^4.7.5",
"styled-jsx": "^5.1.1",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7",
"unified": "^11.0.5",
+464 -38
View File
@@ -8,12 +8,9 @@ importers:
.:
dependencies:
'@formatjs/intl-localematcher':
specifier: ^0.5.10
version: 0.5.10
'@mdx-js/loader':
specifier: ^3.1.0
version: 3.1.0(acorn@8.12.1)
version: 3.1.0(acorn@8.14.0)
'@mdx-js/react':
specifier: ^3.1.0
version: 3.1.0(@types/react@18.3.22)(react@18.3.1)
@@ -22,7 +19,7 @@ importers:
version: 14.2.5
'@next/mdx':
specifier: ^15.1.5
version: 15.1.5(@mdx-js/loader@3.1.0(acorn@8.12.1))(@mdx-js/react@3.1.0(@types/react@18.3.22)(react@18.3.1))
version: 15.1.5(@mdx-js/loader@3.1.0(acorn@8.14.0))(@mdx-js/react@3.1.0(@types/react@18.3.22)(react@18.3.1))
'@radix-ui/react-accordion':
specifier: ^1.2.1
version: 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.22)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -56,9 +53,6 @@ importers:
'@types/mdast':
specifier: ^4.0.4
version: 4.0.4
'@types/negotiator':
specifier: ^0.6.3
version: 0.6.3
'@types/node':
specifier: ^20.14.13
version: 20.14.13
@@ -89,15 +83,15 @@ importers:
mermaid:
specifier: ^11.4.1
version: 11.4.1
negotiator:
specifier: ^1.0.0
version: 1.0.0
next:
specifier: 14.2.5
version: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-intl:
specifier: ^4.8.3
version: 4.8.3(@swc/helpers@0.5.5)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.5.4)
next-mdx-remote:
specifier: ^5.0.0
version: 5.0.0(@types/react@18.3.22)(acorn@8.12.1)(react@18.3.1)
version: 5.0.0(@types/react@18.3.22)(acorn@8.14.0)(react@18.3.1)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -234,8 +228,23 @@ packages:
'@floating-ui/utils@0.2.8':
resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==}
'@formatjs/intl-localematcher@0.5.10':
resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==}
'@formatjs/bigdecimal@0.2.0':
resolution: {integrity: sha512-GeaxHZbUoYvHL9tC5eltHLs+1zU70aPw0s7LwqgktIzF5oMhNY4o4deEtusJMsq7WFJF3Ye2zQEzdG8beVk73w==}
'@formatjs/ecma402-abstract@3.2.0':
resolution: {integrity: sha512-dHnqHgBo6GXYGRsepaE1wmsC2etaivOWd5VaJstZd+HI2zR3DCUjbDVZRtoPGkkXZmyHvBwrdEUuqfvzhF/DtQ==}
'@formatjs/fast-memoize@3.1.1':
resolution: {integrity: sha512-CbNbf+tlJn1baRnPkNePnBqTLxGliG6DDgNa/UtV66abwIjwsliPMOt0172tzxABYzSuxZBZfcp//qI8AvBWPg==}
'@formatjs/icu-messageformat-parser@3.5.3':
resolution: {integrity: sha512-HJWZ9S6JWey6iY5+YXE3Kd0ofWU1sC2KTTp56e1168g/xxWvVvr8k9G4fexIgwYV9wbtjY7kGYK5FjoWB3B2OQ==}
'@formatjs/icu-skeleton-parser@2.1.3':
resolution: {integrity: sha512-9mFp8TJ166ZM2pcjKwsBWXrDnOJGT7vMEScVgLygUODPOsE8S6f/FHoacvrlHK1B4dYZk8vSCNruyPU64AfgJQ==}
'@formatjs/intl-localematcher@0.8.2':
resolution: {integrity: sha512-q05KMYGJLyqFNFtIb8NhWLF5X3aK/k0wYt7dnRFuy6aLQL+vUwQ1cg5cO4qawEiINybeCPXAWlprY2mSBjSXAQ==}
'@humanwhocodes/config-array@0.11.14':
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
@@ -282,67 +291,79 @@ packages:
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-arm@1.0.5':
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.0.4':
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-x64@1.0.4':
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-linux-arm64@0.33.5':
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-arm@0.33.5':
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-linux-s390x@0.33.5':
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-linux-x64@0.33.5':
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.33.5':
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-linuxmusl-x64@0.33.5':
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-wasm32@0.33.5':
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
@@ -437,24 +458,28 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@next/swc-linux-arm64-musl@14.2.5':
resolution: {integrity: sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@next/swc-linux-x64-gnu@14.2.5':
resolution: {integrity: sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@next/swc-linux-x64-musl@14.2.5':
resolution: {integrity: sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@next/swc-win32-arm64-msvc@14.2.5':
resolution: {integrity: sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==}
@@ -486,6 +511,94 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@parcel/watcher-android-arm64@2.5.6':
resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [android]
'@parcel/watcher-darwin-arm64@2.5.6':
resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [darwin]
'@parcel/watcher-darwin-x64@2.5.6':
resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [darwin]
'@parcel/watcher-freebsd-x64@2.5.6':
resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [freebsd]
'@parcel/watcher-linux-arm-glibc@2.5.6':
resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm-musl@2.5.6':
resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-arm64-glibc@2.5.6':
resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm64-musl@2.5.6':
resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-x64-glibc@2.5.6':
resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-x64-musl@2.5.6':
resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
'@parcel/watcher-win32-arm64@2.5.6':
resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [win32]
'@parcel/watcher-win32-ia32@2.5.6':
resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==}
engines: {node: '>= 10.0.0'}
cpu: [ia32]
os: [win32]
'@parcel/watcher-win32-x64@2.5.6':
resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [win32]
'@parcel/watcher@2.5.6':
resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==}
engines: {node: '>= 10.0.0'}
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@@ -1039,15 +1152,108 @@ packages:
'@rushstack/eslint-patch@1.10.4':
resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==}
'@schummar/icu-type-parser@1.21.5':
resolution: {integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==}
'@socket.io/component-emitter@3.1.2':
resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
'@swc/core-darwin-arm64@1.15.21':
resolution: {integrity: sha512-SA8SFg9dp0qKRH8goWsax6bptFE2EdmPf2YRAQW9WoHGf3XKM1bX0nd5UdwxmC5hXsBUZAYf7xSciCler6/oyA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
'@swc/core-darwin-x64@1.15.21':
resolution: {integrity: sha512-//fOVntgowz9+V90lVsNCtyyrtbHp3jWH6Rch7MXHXbcvbLmbCTmssl5DeedUWLLGiAAW1wksBdqdGYOTjaNLw==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
'@swc/core-linux-arm-gnueabihf@1.15.21':
resolution: {integrity: sha512-meNI4Sh6h9h8DvIfEc0l5URabYMSuNvyisLmG6vnoYAS43s8ON3NJR8sDHvdP7NJTrLe0q/x2XCn6yL/BeHcZg==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
'@swc/core-linux-arm64-gnu@1.15.21':
resolution: {integrity: sha512-QrXlNQnHeXqU2EzLlnsPoWEh8/GtNJLvfMiPsDhk+ht6Xv8+vhvZ5YZ/BokNWSIZiWPKLAqR0M7T92YF5tmD3g==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@swc/core-linux-arm64-musl@1.15.21':
resolution: {integrity: sha512-8/yGCMO333ultDaMQivE5CjO6oXDPeeg1IV4sphojPkb0Pv0i6zvcRIkgp60xDB+UxLr6VgHgt+BBgqS959E9g==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@swc/core-linux-ppc64-gnu@1.15.21':
resolution: {integrity: sha512-ucW0HzPx0s1dgRvcvuLSPSA/2Kk/VYTv9st8qe1Kc22Gu0Q0rH9+6TcBTmMuNIp0Xs4BPr1uBttmbO1wEGI49Q==}
engines: {node: '>=10'}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@swc/core-linux-s390x-gnu@1.15.21':
resolution: {integrity: sha512-ulTnOGc5I7YRObE/9NreAhQg94QkiR5qNhhcUZ1iFAYjzg/JGAi1ch+s/Ixe61pMIr8bfVrF0NOaB0f8wjaAfA==}
engines: {node: '>=10'}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@swc/core-linux-x64-gnu@1.15.21':
resolution: {integrity: sha512-D0RokxtM+cPvSqJIKR6uja4hbD+scI9ezo95mBhfSyLUs9wnPPl26sLp1ZPR/EXRdYm3F3S6RUtVi+8QXhT24Q==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@swc/core-linux-x64-musl@1.15.21':
resolution: {integrity: sha512-nER8u7VeRfmU6fMDzl1NQAbbB/G7O2avmvCOwIul1uGkZ2/acbPH+DCL9h5+0yd/coNcxMBTL6NGepIew+7C2w==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@swc/core-win32-arm64-msvc@1.15.21':
resolution: {integrity: sha512-+/AgNBnjYugUA8C0Do4YzymgvnGbztv7j8HKSQLvR/DQgZPoXQ2B3PqB2mTtGh/X5DhlJWiqnunN35JUgWcAeQ==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
'@swc/core-win32-ia32-msvc@1.15.21':
resolution: {integrity: sha512-IkSZj8PX/N4HcaFhMQtzmkV8YSnuNoJ0E6OvMwFiOfejPhiKXvl7CdDsn1f4/emYEIDO3fpgZW9DTaCRMDxaDA==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
'@swc/core-win32-x64-msvc@1.15.21':
resolution: {integrity: sha512-zUyWso7OOENB6e1N1hNuNn8vbvLsTdKQ5WKLgt/JcBNfJhKy/6jmBmqI3GXk/MyvQKd5SLvP7A0F36p7TeDqvw==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@swc/core@1.15.21':
resolution: {integrity: sha512-fkk7NJcBscrR3/F8jiqlMptRHP650NxqDnspBMrRe5d8xOoCy9MLL5kOBLFXjFLfMo3KQQHhk+/jUULOMlR1uQ==}
engines: {node: '>=10'}
peerDependencies:
'@swc/helpers': '>=0.5.17'
peerDependenciesMeta:
'@swc/helpers':
optional: true
'@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
'@swc/helpers@0.5.5':
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
'@swc/types@0.1.26':
resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==}
'@types/acorn@4.0.6':
resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
@@ -1171,9 +1377,6 @@ packages:
'@types/ms@2.1.0':
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
'@types/negotiator@0.6.3':
resolution: {integrity: sha512-JkXTOdKs5MF086b/pt8C3+yVp3iDUwG635L7oCH6HvJvvr6lSUU5oe/gLXnPEfYRROHjJIPgCV6cuAg8gGkntQ==}
'@types/node@20.14.13':
resolution: {integrity: sha512-+bHoGiZb8UiQ0+WEtmph2IWQCjIqg8MDZMAV+ppRRhUZnquF5mQkP/9vpSwJClEiSM/C7fZZExPzfU0vJTyp8w==}
@@ -1886,6 +2089,7 @@ packages:
eslint@8.57.0:
resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
espree@9.6.1:
@@ -2027,15 +2231,17 @@ packages:
glob@10.3.10:
resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
engines: {node: '>=16 || 14 >=14.17'}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
glob@10.4.5:
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Glob versions prior to v9 are no longer supported
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
globals@13.24.0:
resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
@@ -2108,6 +2314,9 @@ packages:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
icu-minify@4.8.3:
resolution: {integrity: sha512-65Av7FLosNk7bPbmQx5z5XG2Y3T2GFppcjiXh4z1idHeVgQxlDpAmkGoYI0eFzAvrOnjpWTL5FmPDhsdfRMPEA==}
ignore@5.3.1:
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
@@ -2144,6 +2353,9 @@ packages:
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
engines: {node: '>=12'}
intl-messageformat@11.2.0:
resolution: {integrity: sha512-IhghAA8n4KSlXuWKzYsWyWb82JoYTzShfyvdSF85oJPnNOjvv4kAo7S7Jtkm3/vJ53C7dQNRO+Gpnj3iWgTjBQ==}
invariant@2.2.4:
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
@@ -2639,6 +2851,19 @@ packages:
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
engines: {node: '>= 0.6'}
next-intl-swc-plugin-extractor@4.8.3:
resolution: {integrity: sha512-YcaT+R9z69XkGhpDarVFWUprrCMbxgIQYPUaXoE6LGVnLjGdo8hu3gL6bramDVjNKViYY8a/pXPy7Bna0mXORg==}
next-intl@4.8.3:
resolution: {integrity: sha512-PvdBDWg+Leh7BR7GJUQbCDVVaBRn37GwDBWc9sv0rVQOJDQ5JU1rVzx9EEGuOGYo0DHAl70++9LQ7HxTawdL7w==}
peerDependencies:
next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
typescript: ^5.0.0
peerDependenciesMeta:
typescript:
optional: true
next-mdx-remote@5.0.0:
resolution: {integrity: sha512-RNNbqRpK9/dcIFZs/esQhuLA8jANqlH694yqoDBK8hkVdJUndzzGmnPHa2nyi90N4Z9VmzuSWNRpr5ItT3M7xQ==}
engines: {node: '>=14', npm: '>=7'}
@@ -2654,6 +2879,7 @@ packages:
next@14.2.5:
resolution: {integrity: sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==}
engines: {node: '>=18.17.0'}
deprecated: This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/security-update-2025-12-11 for more details.
hasBin: true
peerDependencies:
'@opentelemetry/api': ^1.1.0
@@ -2669,6 +2895,9 @@ packages:
sass:
optional: true
node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@@ -2780,6 +3009,10 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
picomatch@4.0.4:
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
engines: {node: '>=12'}
pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
@@ -2791,6 +3024,9 @@ packages:
pkg-types@1.3.1:
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
po-parser@2.1.1:
resolution: {integrity: sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==}
points-on-curve@0.2.0:
resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==}
@@ -3371,6 +3607,11 @@ packages:
'@types/react':
optional: true
use-intl@4.8.3:
resolution: {integrity: sha512-nLxlC/RH+le6g3amA508Itnn/00mE+J22ui21QhOWo5V9hCEC43+WtnRAITbJW0ztVZphev5X9gvOf2/Dk9PLA==}
peerDependencies:
react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
use-sidecar@1.1.2:
resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
engines: {node: '>=10'}
@@ -3581,9 +3822,28 @@ snapshots:
'@floating-ui/utils@0.2.8': {}
'@formatjs/intl-localematcher@0.5.10':
'@formatjs/bigdecimal@0.2.0': {}
'@formatjs/ecma402-abstract@3.2.0':
dependencies:
tslib: 2.6.3
'@formatjs/bigdecimal': 0.2.0
'@formatjs/fast-memoize': 3.1.1
'@formatjs/intl-localematcher': 0.8.2
'@formatjs/fast-memoize@3.1.1': {}
'@formatjs/icu-messageformat-parser@3.5.3':
dependencies:
'@formatjs/ecma402-abstract': 3.2.0
'@formatjs/icu-skeleton-parser': 2.1.3
'@formatjs/icu-skeleton-parser@2.1.3':
dependencies:
'@formatjs/ecma402-abstract': 3.2.0
'@formatjs/intl-localematcher@0.8.2':
dependencies:
'@formatjs/fast-memoize': 3.1.1
'@humanwhocodes/config-array@0.11.14':
dependencies:
@@ -3713,15 +3973,15 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@mdx-js/loader@3.1.0(acorn@8.12.1)':
'@mdx-js/loader@3.1.0(acorn@8.14.0)':
dependencies:
'@mdx-js/mdx': 3.1.0(acorn@8.12.1)
'@mdx-js/mdx': 3.1.0(acorn@8.14.0)
source-map: 0.7.4
transitivePeerDependencies:
- acorn
- supports-color
'@mdx-js/mdx@3.1.0(acorn@8.12.1)':
'@mdx-js/mdx@3.1.0(acorn@8.14.0)':
dependencies:
'@types/estree': 1.0.6
'@types/estree-jsx': 1.0.5
@@ -3735,7 +3995,7 @@ snapshots:
hast-util-to-jsx-runtime: 2.3.2
markdown-extensions: 2.0.0
recma-build-jsx: 1.0.0
recma-jsx: 1.0.0(acorn@8.12.1)
recma-jsx: 1.0.0(acorn@8.14.0)
recma-stringify: 1.0.0
rehype-recma: 1.0.0
remark-mdx: 3.1.0
@@ -3767,11 +4027,11 @@ snapshots:
dependencies:
glob: 10.3.10
'@next/mdx@15.1.5(@mdx-js/loader@3.1.0(acorn@8.12.1))(@mdx-js/react@3.1.0(@types/react@18.3.22)(react@18.3.1))':
'@next/mdx@15.1.5(@mdx-js/loader@3.1.0(acorn@8.14.0))(@mdx-js/react@3.1.0(@types/react@18.3.22)(react@18.3.1))':
dependencies:
source-map: 0.7.4
optionalDependencies:
'@mdx-js/loader': 3.1.0(acorn@8.12.1)
'@mdx-js/loader': 3.1.0(acorn@8.14.0)
'@mdx-js/react': 3.1.0(@types/react@18.3.22)(react@18.3.1)
'@next/swc-darwin-arm64@14.2.5':
@@ -3813,6 +4073,66 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
'@parcel/watcher-android-arm64@2.5.6':
optional: true
'@parcel/watcher-darwin-arm64@2.5.6':
optional: true
'@parcel/watcher-darwin-x64@2.5.6':
optional: true
'@parcel/watcher-freebsd-x64@2.5.6':
optional: true
'@parcel/watcher-linux-arm-glibc@2.5.6':
optional: true
'@parcel/watcher-linux-arm-musl@2.5.6':
optional: true
'@parcel/watcher-linux-arm64-glibc@2.5.6':
optional: true
'@parcel/watcher-linux-arm64-musl@2.5.6':
optional: true
'@parcel/watcher-linux-x64-glibc@2.5.6':
optional: true
'@parcel/watcher-linux-x64-musl@2.5.6':
optional: true
'@parcel/watcher-win32-arm64@2.5.6':
optional: true
'@parcel/watcher-win32-ia32@2.5.6':
optional: true
'@parcel/watcher-win32-x64@2.5.6':
optional: true
'@parcel/watcher@2.5.6':
dependencies:
detect-libc: 2.0.4
is-glob: 4.0.3
node-addon-api: 7.1.1
picomatch: 4.0.4
optionalDependencies:
'@parcel/watcher-android-arm64': 2.5.6
'@parcel/watcher-darwin-arm64': 2.5.6
'@parcel/watcher-darwin-x64': 2.5.6
'@parcel/watcher-freebsd-x64': 2.5.6
'@parcel/watcher-linux-arm-glibc': 2.5.6
'@parcel/watcher-linux-arm-musl': 2.5.6
'@parcel/watcher-linux-arm64-glibc': 2.5.6
'@parcel/watcher-linux-arm64-musl': 2.5.6
'@parcel/watcher-linux-x64-glibc': 2.5.6
'@parcel/watcher-linux-x64-musl': 2.5.6
'@parcel/watcher-win32-arm64': 2.5.6
'@parcel/watcher-win32-ia32': 2.5.6
'@parcel/watcher-win32-x64': 2.5.6
'@pkgjs/parseargs@0.11.0':
optional: true
@@ -4353,8 +4673,65 @@ snapshots:
'@rushstack/eslint-patch@1.10.4': {}
'@schummar/icu-type-parser@1.21.5': {}
'@socket.io/component-emitter@3.1.2': {}
'@swc/core-darwin-arm64@1.15.21':
optional: true
'@swc/core-darwin-x64@1.15.21':
optional: true
'@swc/core-linux-arm-gnueabihf@1.15.21':
optional: true
'@swc/core-linux-arm64-gnu@1.15.21':
optional: true
'@swc/core-linux-arm64-musl@1.15.21':
optional: true
'@swc/core-linux-ppc64-gnu@1.15.21':
optional: true
'@swc/core-linux-s390x-gnu@1.15.21':
optional: true
'@swc/core-linux-x64-gnu@1.15.21':
optional: true
'@swc/core-linux-x64-musl@1.15.21':
optional: true
'@swc/core-win32-arm64-msvc@1.15.21':
optional: true
'@swc/core-win32-ia32-msvc@1.15.21':
optional: true
'@swc/core-win32-x64-msvc@1.15.21':
optional: true
'@swc/core@1.15.21(@swc/helpers@0.5.5)':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.26
optionalDependencies:
'@swc/core-darwin-arm64': 1.15.21
'@swc/core-darwin-x64': 1.15.21
'@swc/core-linux-arm-gnueabihf': 1.15.21
'@swc/core-linux-arm64-gnu': 1.15.21
'@swc/core-linux-arm64-musl': 1.15.21
'@swc/core-linux-ppc64-gnu': 1.15.21
'@swc/core-linux-s390x-gnu': 1.15.21
'@swc/core-linux-x64-gnu': 1.15.21
'@swc/core-linux-x64-musl': 1.15.21
'@swc/core-win32-arm64-msvc': 1.15.21
'@swc/core-win32-ia32-msvc': 1.15.21
'@swc/core-win32-x64-msvc': 1.15.21
'@swc/helpers': 0.5.5
'@swc/counter@0.1.3': {}
'@swc/helpers@0.5.5':
@@ -4362,6 +4739,10 @@ snapshots:
'@swc/counter': 0.1.3
tslib: 2.6.3
'@swc/types@0.1.26':
dependencies:
'@swc/counter': 0.1.3
'@types/acorn@4.0.6':
dependencies:
'@types/estree': 1.0.6
@@ -4509,8 +4890,6 @@ snapshots:
'@types/ms@2.1.0': {}
'@types/negotiator@0.6.3': {}
'@types/node@20.14.13':
dependencies:
undici-types: 5.26.5
@@ -4579,6 +4958,10 @@ snapshots:
dependencies:
acorn: 8.12.1
acorn-jsx@5.3.2(acorn@8.14.0):
dependencies:
acorn: 8.14.0
acorn@8.12.1: {}
acorn@8.14.0: {}
@@ -5288,7 +5671,7 @@ snapshots:
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0)
eslint-plugin-react: 7.35.0(eslint@8.57.0)
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0)
@@ -5311,8 +5694,8 @@ snapshots:
debug: 4.3.6
enhanced-resolve: 5.17.1
eslint: 8.57.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.6
is-core-module: 2.15.0
@@ -5323,7 +5706,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
dependencies:
debug: 3.2.7
optionalDependencies:
@@ -5334,7 +5717,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
dependencies:
array-includes: 3.1.8
array.prototype.findlastindex: 1.2.5
@@ -5344,7 +5727,7 @@ snapshots:
doctrine: 2.1.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
hasown: 2.0.2
is-core-module: 2.15.0
is-glob: 4.0.3
@@ -5740,6 +6123,10 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
icu-minify@4.8.3:
dependencies:
'@formatjs/icu-messageformat-parser': 3.5.3
ignore@5.3.1: {}
immediate@3.0.6: {}
@@ -5770,6 +6157,12 @@ snapshots:
internmap@2.0.3: {}
intl-messageformat@11.2.0:
dependencies:
'@formatjs/ecma402-abstract': 3.2.0
'@formatjs/fast-memoize': 3.1.1
'@formatjs/icu-messageformat-parser': 3.5.3
invariant@2.2.4:
dependencies:
loose-envify: 1.4.0
@@ -6537,10 +6930,29 @@ snapshots:
negotiator@1.0.0: {}
next-mdx-remote@5.0.0(@types/react@18.3.22)(acorn@8.12.1)(react@18.3.1):
next-intl-swc-plugin-extractor@4.8.3: {}
next-intl@4.8.3(@swc/helpers@0.5.5)(next@14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.5.4):
dependencies:
'@formatjs/intl-localematcher': 0.8.2
'@parcel/watcher': 2.5.6
'@swc/core': 1.15.21(@swc/helpers@0.5.5)
icu-minify: 4.8.3
negotiator: 1.0.0
next: 14.2.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-intl-swc-plugin-extractor: 4.8.3
po-parser: 2.1.1
react: 18.3.1
use-intl: 4.8.3(react@18.3.1)
optionalDependencies:
typescript: 5.5.4
transitivePeerDependencies:
- '@swc/helpers'
next-mdx-remote@5.0.0(@types/react@18.3.22)(acorn@8.14.0)(react@18.3.1):
dependencies:
'@babel/code-frame': 7.26.2
'@mdx-js/mdx': 3.1.0(acorn@8.12.1)
'@mdx-js/mdx': 3.1.0(acorn@8.14.0)
'@mdx-js/react': 3.1.0(@types/react@18.3.22)(react@18.3.1)
react: 18.3.1
unist-util-remove: 3.1.1
@@ -6581,6 +6993,8 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
node-addon-api@7.1.1: {}
normalize-path@3.0.0: {}
object-assign@4.1.1: {}
@@ -6692,6 +7106,8 @@ snapshots:
picomatch@2.3.1: {}
picomatch@4.0.4: {}
pify@2.3.0: {}
pirates@4.0.6: {}
@@ -6702,6 +7118,8 @@ snapshots:
mlly: 1.7.4
pathe: 2.0.3
po-parser@2.1.1: {}
points-on-curve@0.2.0: {}
points-on-path@0.2.1:
@@ -6871,9 +7289,9 @@ snapshots:
estree-util-build-jsx: 3.0.1
vfile: 6.0.3
recma-jsx@1.0.0(acorn@8.12.1):
recma-jsx@1.0.0(acorn@8.14.0):
dependencies:
acorn-jsx: 5.3.2(acorn@8.12.1)
acorn-jsx: 5.3.2(acorn@8.14.0)
estree-util-to-js: 2.0.0
recma-parse: 1.0.0
recma-stringify: 1.0.0
@@ -7424,6 +7842,14 @@ snapshots:
optionalDependencies:
'@types/react': 18.3.22
use-intl@4.8.3(react@18.3.1):
dependencies:
'@formatjs/fast-memoize': 3.1.1
'@schummar/icu-type-parser': 1.21.5
icu-minify: 4.8.3
intl-messageformat: 11.2.0
react: 18.3.1
use-sidecar@1.1.2(@types/react@18.3.22)(react@18.3.1):
dependencies:
detect-node-es: 1.1.0
+16 -2
View File
@@ -1,4 +1,18 @@
import type { Messages } from "@/types/messages";
import { supportedLocales } from "@/constants/i18n-config";
declare module "lodash";
interface Window {
showDirectoryPicker?: () => Promise<FileSystemDirectoryHandle>;
declare global {
interface Window {
showDirectoryPicker?: () => Promise<FileSystemDirectoryHandle>;
}
}
declare module "next-intl" {
interface AppConfig {
Locale: (typeof supportedLocales)[number];
Messages: Messages;
}
}
export {};
+1
View File
@@ -0,0 +1 @@
declare module "lodash";