diff --git a/apps/next-app-router/README.md b/apps/next-app-router/README.md new file mode 100644 index 00000000000..2b9094e1f2f --- /dev/null +++ b/apps/next-app-router/README.md @@ -0,0 +1 @@ +# Dont get excited, it doesnt work. diff --git a/apps/next-app-router/next-app-router-4000/.eslintrc.json b/apps/next-app-router/next-app-router-4000/.eslintrc.json new file mode 100644 index 00000000000..bffb357a712 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/apps/next-app-router/next-app-router-4000/.gitignore b/apps/next-app-router/next-app-router-4000/.gitignore new file mode 100644 index 00000000000..6d1ed289361 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +/.yarn + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env* +!.env*.example + +# vercel +.vercel + +# typescript +*.tsbuildinfo diff --git a/apps/next-app-router/next-app-router-4000/.npmrc b/apps/next-app-router/next-app-router-4000/.npmrc new file mode 100644 index 00000000000..cffe8cdef13 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/.npmrc @@ -0,0 +1 @@ +save-exact=true diff --git a/apps/next-app-router/next-app-router-4000/.prettierignore b/apps/next-app-router/next-app-router-4000/.prettierignore new file mode 100644 index 00000000000..a66d7e1f76d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/.prettierignore @@ -0,0 +1,2 @@ +.next +pnpm-lock.yaml diff --git a/apps/next-app-router/next-app-router-4000/app/api/categories/category.d.ts b/apps/next-app-router/next-app-router-4000/app/api/categories/category.d.ts new file mode 100644 index 00000000000..dccaa7448d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/api/categories/category.d.ts @@ -0,0 +1,6 @@ +export type Category = { + name: string; + slug: string; + count: number; + parent: string | null; +}; diff --git a/apps/next-app-router/next-app-router-4000/app/api/categories/getCategories.ts b/apps/next-app-router/next-app-router-4000/app/api/categories/getCategories.ts new file mode 100644 index 00000000000..989a293429c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/api/categories/getCategories.ts @@ -0,0 +1,52 @@ +import { notFound } from 'next/navigation'; +import type { Category } from './category'; + +// `server-only` guarantees any modules that import code in file +// will never run on the client. Even though this particular API +// doesn't currently use sensitive environment variables, it's +// good practice to add `server-only` preemptively. +import 'server-only'; + +export async function getCategories({ parent }: { parent?: string } = {}) { + const res = await fetch( + `https://app-playground-api.vercel.app/api/categories${ + parent ? `?parent=${parent}` : '' + }`, + ); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const categories = (await res.json()) as Category[]; + + if (categories.length === 0) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return categories; +} + +export async function getCategory({ slug }: { slug: string }) { + const res = await fetch( + `https://app-playground-api.vercel.app/api/categories${ + slug ? `?slug=${slug}` : '' + }`, + ); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const category = (await res.json()) as Category; + + if (!category) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return category; +} diff --git a/apps/next-app-router/next-app-router-4000/app/api/og/Inter-SemiBold.ttf b/apps/next-app-router/next-app-router-4000/app/api/og/Inter-SemiBold.ttf new file mode 100644 index 00000000000..278ceaa36ba Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/app/api/og/Inter-SemiBold.ttf differ diff --git a/apps/next-app-router/next-app-router-4000/app/api/og/route.tsx b/apps/next-app-router/next-app-router-4000/app/api/og/route.tsx new file mode 100644 index 00000000000..48c1bfaebdc --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/api/og/route.tsx @@ -0,0 +1,656 @@ +import type { NextRequest } from 'next/server'; +import { ImageResponse } from 'next/og'; +import type { ReactElement } from 'react'; + +export const runtime = 'edge'; + +const interSemiBold = fetch( + new URL('./Inter-SemiBold.ttf', import.meta.url), +).then((res) => res.arrayBuffer()); + +export async function GET(req: NextRequest): Promise { + try { + const { searchParams } = new URL(req.url); + const isLight = req.headers.get('Sec-CH-Prefers-Color-Scheme') === 'light'; + + const title = searchParams.has('title') + ? searchParams.get('title') + : 'App Router Playground'; + + return new ImageResponse( + ( +
+ {isLight ? : } +
+ {title} +
+
+ ), + { + width: 843, + height: 441, + fonts: [ + { + name: 'Inter', + data: await interSemiBold, + style: 'normal', + weight: 400, + }, + ], + }, + ); + } catch (e) { + if (!(e instanceof Error)) throw e; + + // eslint-disable-next-line no-console + console.log(e.message); + return new Response(`Failed to generate the image`, { + status: 500, + }); + } +} + +function LightSvg(): ReactElement { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +function DarkSvg(): ReactElement { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/api/products/product.d.ts b/apps/next-app-router/next-app-router-4000/app/api/products/product.d.ts new file mode 100644 index 00000000000..c279cf7637d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/api/products/product.d.ts @@ -0,0 +1,37 @@ +export type Product = { + id: string; + stock: number; + rating: number; + name: string; + description: string; + price: Price; + isBestSeller: boolean; + leadTime: number; + image?: string; + imageBlur?: string; + discount?: Discount; + usedPrice?: UsedPrice; +}; + +type Price = { + amount: number; + currency: Currency; + scale: number; +}; + +type Currency = { + code: string; + base: number; + exponent: number; +}; + +type Discount = { + percent: number; + expires?: number; +}; + +type UsedPrice = { + amount: number; + currency: Currency; + scale: number; +}; diff --git a/apps/next-app-router/next-app-router-4000/app/api/revalidate/route.ts b/apps/next-app-router/next-app-router-4000/app/api/revalidate/route.ts new file mode 100644 index 00000000000..fc676f685cb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/api/revalidate/route.ts @@ -0,0 +1,16 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { revalidatePath, revalidateTag } from 'next/cache'; + +export async function GET(request: NextRequest) { + const path = request.nextUrl.searchParams.get('path') || '/isr/[id]'; + const collection = + request.nextUrl.searchParams.get('collection') || 'collection'; + revalidatePath(path); + revalidateTag(collection); + console.log('revalidated', path, collection); + return NextResponse.json({ + revalidated: true, + now: Date.now(), + cache: 'no-store', + }); +} diff --git a/apps/next-app-router/next-app-router-4000/app/api/reviews/getReviews.ts b/apps/next-app-router/next-app-router-4000/app/api/reviews/getReviews.ts new file mode 100644 index 00000000000..a42b409ee00 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/api/reviews/getReviews.ts @@ -0,0 +1,26 @@ +import { notFound } from 'next/navigation'; +import type { Review } from './review'; + +// `server-only` guarantees any modules that import code in file +// will never run on the client. Even though this particular api +// doesn't currently use sensitive environment variables, it's +// good practise to add `server-only` preemptively. +import 'server-only'; + +export async function getReviews() { + const res = await fetch(`https://app-playground-api.vercel.app/api/reviews`); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const reviews = (await res.json()) as Review[]; + + if (reviews.length === 0) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return reviews; +} diff --git a/apps/next-app-router/next-app-router-4000/app/api/reviews/review.d.ts b/apps/next-app-router/next-app-router-4000/app/api/reviews/review.d.ts new file mode 100644 index 00000000000..0135e4d2dd2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/api/reviews/review.d.ts @@ -0,0 +1,6 @@ +export type Review = { + id: string; + name: string; + rating: number; + text: string; +}; diff --git a/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..3b2e5d0eaf6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,23 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { notFound } from 'next/navigation'; +import { Counter } from '../../context-click-counter'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( + +
+

+ {category.name} +

+ + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..514d27900fe --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/layout.tsx @@ -0,0 +1,37 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; +import { Counter } from '../context-click-counter'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( + +
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/page.tsx new file mode 100644 index 00000000000..121a5be9fb4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/context/[categorySlug]/page.tsx @@ -0,0 +1,22 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { Counter } from '../context-click-counter'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( + +
+

+ All {category.name} +

+ + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/context/context-click-counter.tsx b/apps/next-app-router/next-app-router-4000/app/context/context-click-counter.tsx new file mode 100644 index 00000000000..a59be8aeb2f --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/context/context-click-counter.tsx @@ -0,0 +1,47 @@ +'use client'; + +import { useCounter } from './counter-context'; +import React from 'react'; +import { Boundary } from '#/ui/boundary'; +import dynamic from 'next/dynamic'; +const Button = dynamic(() => import('remote_4001/Button'), { ssr: true }); + +const ContextClickCounter = () => { + const [count, setCount] = useCounter(); + + return ( + + + + + ); +}; + +export const Counter = () => { + const [count] = useCounter(); + + return ( + +
+ {count} Clicks +
+
+ ); +}; + +export default ContextClickCounter; diff --git a/apps/next-app-router/next-app-router-4000/app/context/counter-context.tsx b/apps/next-app-router/next-app-router-4000/app/context/counter-context.tsx new file mode 100644 index 00000000000..999c04477e9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/context/counter-context.tsx @@ -0,0 +1,24 @@ +'use client'; + +import React from 'react'; + +const CounterContext = React.createContext< + [number, React.Dispatch>] | undefined +>(undefined); + +export function CounterProvider({ children }: { children: React.ReactNode }) { + const [count, setCount] = React.useState(0); + return ( + + {children} + + ); +} + +export function useCounter() { + const context = React.useContext(CounterContext); + if (context === undefined) { + throw new Error('useCounter must be used within a CounterProvider'); + } + return context; +} diff --git a/apps/next-app-router/next-app-router-4000/app/context/layout.tsx b/apps/next-app-router/next-app-router-4000/app/context/layout.tsx new file mode 100644 index 00000000000..8caed20a1c4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/context/layout.tsx @@ -0,0 +1,66 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; +import { CounterProvider } from 'app/context/counter-context'; +import React from 'react'; +import ContextClickCounter from './context-click-counter'; + +const title = 'Client Context'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + return ( + + + + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> +
+ + +
{children}
+
+
+
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/context/page.tsx b/apps/next-app-router/next-app-router-4000/app/context/page.tsx new file mode 100644 index 00000000000..4828d0a6c68 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/context/page.tsx @@ -0,0 +1,30 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Client Context

+ +
    +
  • + This example uses context to share state between Client Components + that cross the Server/Client Component boundary. +
  • +
  • + Try incrementing the counter and navigating between pages. Note how + the counter state is shared across the app even though they are inside + different layouts and pages that are Server Components. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/[subCategorySlug]/error.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/[subCategorySlug]/error.tsx new file mode 100644 index 00000000000..bed2b1c2525 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/[subCategorySlug]/error.tsx @@ -0,0 +1,26 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import Button from 'remote_4001/Button'; +import React from 'react'; + +export default function Error({ error, reset }: any) { + React.useEffect(() => { + console.log('logging error:', error); + }, [error]); + + return ( + +
+

Error

+

{error?.message}

+
+ +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..0917d305fcb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,25 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import BuggyButton from '#/ui/buggy-button'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ + + +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/error.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/error.tsx new file mode 100644 index 00000000000..a3b35cc8051 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/error.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import Button from 'remote_4001/Button'; +import React from 'react'; + +export default function Error({ error, reset }: any) { + React.useEffect(() => { + console.log('logging error:', error); + }, [error]); + + return ( + +
+

Error

+

{error?.message}

+
+ +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..02934ebc6cf --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/layout.tsx @@ -0,0 +1,42 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/page.tsx new file mode 100644 index 00000000000..1cb6382c394 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/page.tsx @@ -0,0 +1,27 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import BuggyButton from '#/ui/buggy-button'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ + + +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/[categorySlug]/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/error.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/error.tsx new file mode 100644 index 00000000000..70a7ef16ecb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/error.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import Button from 'remote_4001/Button'; +import React from 'react'; + +export default function Error({ error, reset }: any) { + React.useEffect(() => { + console.log('logging error:', error); + }, [error]); + + return ( + +
+

Error

+

{error?.message}

+
+ +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/layout.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/layout.tsx new file mode 100644 index 00000000000..506e7d4ba89 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Error Handling'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/page.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/page.tsx new file mode 100644 index 00000000000..8852aa4337c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/page.tsx @@ -0,0 +1,34 @@ +import BuggyButton from '#/ui/buggy-button'; +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Error Handling

+ +
    +
  • + error.js defines the error boundary for a route segment + and the children below it. It can be used to show specific error + information, and functionality to attempt to recover from the error. +
  • +
  • + Trying navigation pages and triggering an error inside nested layouts. + Notice how the error is isolated to that segment, while the rest of + the app remains interactive. +
  • +
+ +
+ + + + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/error-handling/template.tsx b/apps/next-app-router/next-app-router-4000/app/error-handling/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/error-handling/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/favicon.ico b/apps/next-app-router/next-app-router-4000/app/favicon.ico new file mode 100644 index 00000000000..af98450595e Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/app/favicon.ico differ diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..72ad9f58087 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,17 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { HooksClient } from '#/app/hooks/_components/router-context'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..1ba58575f65 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/layout.tsx @@ -0,0 +1,43 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { LayoutHooks } from '#/app/hooks/_components/router-context-layout'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ + + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/page.tsx new file mode 100644 index 00000000000..a518e7c3c52 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/page.tsx @@ -0,0 +1,19 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { HooksClient } from '#/app/hooks/_components/router-context'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/[categorySlug]/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/_components/router-context-layout.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/_components/router-context-layout.tsx new file mode 100644 index 00000000000..ce4c8118548 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/_components/router-context-layout.tsx @@ -0,0 +1,29 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import { + useSelectedLayoutSegment, + useSelectedLayoutSegments, +} from 'next/navigation'; + +export function LayoutHooks() { + const selectedLayoutSegment = useSelectedLayoutSegment(); + const selectedLayoutSegments = useSelectedLayoutSegments(); + + return selectedLayoutSegment ? ( + +
+
+          {JSON.stringify(
+            {
+              useSelectedLayoutSegment: selectedLayoutSegment,
+              useSelectedLayoutSegments: selectedLayoutSegments,
+            },
+            null,
+            2,
+          )}
+        
+
+
+ ) : null; +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/_components/router-context.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/_components/router-context.tsx new file mode 100644 index 00000000000..42fe045c2ed --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/_components/router-context.tsx @@ -0,0 +1,40 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import { + useParams, + usePathname, + useSearchParams, + useSelectedLayoutSegment, + useSelectedLayoutSegments, +} from 'next/navigation'; + +export function HooksClient() { + const pathname = usePathname(); + const params = useParams(); + const selectedLayoutSegment = useSelectedLayoutSegment(); + const selectedLayoutSegments = useSelectedLayoutSegments(); + const searchParams = useSearchParams(); + + return ( + +
+
+          {JSON.stringify(
+            {
+              usePathname: pathname,
+              useParams: params,
+              useSearchParams: searchParams
+                ? Object.fromEntries(searchParams.entries())
+                : {},
+              useSelectedLayoutSegment: selectedLayoutSegment,
+              useSelectedLayoutSegments: selectedLayoutSegments,
+            },
+            null,
+            2,
+          )}
+        
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/layout.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/layout.tsx new file mode 100644 index 00000000000..ac30b428cd1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/layout.tsx @@ -0,0 +1,50 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { LayoutHooks } from '#/app/hooks/_components/router-context-layout'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Hooks'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ + + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/page.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/page.tsx new file mode 100644 index 00000000000..c216fb991d6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/page.tsx @@ -0,0 +1,32 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+
+

Client Component Hooks

+ +
    +
  • + Next.js provides a number of hooks for accessing routing information + from client components. +
  • +
  • + Try navigating each page and observing the output of each hook + called from the current routes layout.js and{' '} + page.js files. +
  • +
+ +
+ + Docs + + + Code + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/template.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/hooks/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/isr/[id]/page.tsx b/apps/next-app-router/next-app-router-4000/app/isr/[id]/page.tsx new file mode 100644 index 00000000000..c95d3484f70 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/isr/[id]/page.tsx @@ -0,0 +1,30 @@ +import { RenderingInfo } from '#/ui/rendering-info'; + +export const dynamicParams = true; + +export async function generateStaticParams() { + return [{ id: '1' }, { id: '2' }, { id: '3' }]; +} + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + const res = await fetch( + `https://jsonplaceholder.typicode.com/posts/${params.id}`, + { next: { revalidate: 60, tags: ['collection'] } }, + ); + const data = (await res.json()) as { title: string; body: string }; + + return ( +
+
+

+ {data.title} +

+

{data.body}

+
+
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/isr/layout.tsx b/apps/next-app-router/next-app-router-4000/app/isr/layout.tsx new file mode 100644 index 00000000000..7cf3e34bd8e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/isr/layout.tsx @@ -0,0 +1,35 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Incremental Static Regeneration (ISR)'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + const ids = [{ id: '1' }, { id: '2' }, { id: '3' }]; + + return ( +
+ ({ + text: `Post ${x.id}`, + slug: x.id, + })), + ]} + /> + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/isr/loading.tsx b/apps/next-app-router/next-app-router-4000/app/isr/loading.tsx new file mode 100644 index 00000000000..2c150f871d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/isr/loading.tsx @@ -0,0 +1,5 @@ +import { RenderingPageSkeleton } from '#/ui/rendering-page-skeleton'; + +export default function Loading() { + return ; +} diff --git a/apps/next-app-router/next-app-router-4000/app/isr/page.tsx b/apps/next-app-router/next-app-router-4000/app/isr/page.tsx new file mode 100644 index 00000000000..d90ff0298bb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/isr/page.tsx @@ -0,0 +1,30 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Incremental Static Regeneration

+ +
    +
  • In this example, three posts fetch data using granular ISR.
  • +
  • Caches responses are fresh for 60 seconds.
  • +
  • + Try navigating to each post and noting the timestamp of when the page + was rendered. Refresh the page after 60 seconds to trigger a + revalidation for the next request. Refresh again to see the + revalidated page. +
  • +
  • Note that the fetch cache can be persisted across builds.
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/isr/template.tsx b/apps/next-app-router/next-app-router-4000/app/isr/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/isr/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/layout.tsx b/apps/next-app-router/next-app-router-4000/app/layout.tsx new file mode 100644 index 00000000000..ed79b53661a --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layout.tsx @@ -0,0 +1,53 @@ +import '#/styles/globals.css'; +import { AddressBar } from '#/ui/address-bar'; +import Byline from '#/ui/byline'; +// import { GlobalNav } from 'remote_4001/GlobalNav(rsc)'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: { + default: 'Next.js App Router', + template: '%s | Next.js App Router', + }, + metadataBase: new URL('https://app-router.vercel.app'), + description: + 'A playground to explore new Next.js App Router features such as nested layouts, instant loading states, streaming, and component level data fetching.', + openGraph: { + title: 'Next.js App Router Playground', + description: + 'A playground to explore new Next.js App Router features such as nested layouts, instant loading states, streaming, and component level data fetching.', + images: [`/api/og?title=Next.js App Router`], + }, + twitter: { + card: 'summary_large_image', + }, +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + {/**/} + +
+
+
+
+ +
+
+ +
+
{children}
+
+ +
+
+ + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..4bbfae6d332 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,21 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..548d0baae9c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/layout.tsx @@ -0,0 +1,40 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/page.tsx new file mode 100644 index 00000000000..672e25359c6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/page.tsx @@ -0,0 +1,23 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layouts/[categorySlug]/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/layouts/layout.tsx b/apps/next-app-router/next-app-router-4000/app/layouts/layout.tsx new file mode 100644 index 00000000000..108ba315b9e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layouts/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Nested Layouts'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/layouts/page.tsx b/apps/next-app-router/next-app-router-4000/app/layouts/page.tsx new file mode 100644 index 00000000000..f636922b482 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layouts/page.tsx @@ -0,0 +1,27 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Layouts

+ +
    +
  • + A layout is UI that is shared between multiple pages. On navigation, + layouts preserve state, remain interactive, and do not re-render. Two + or more layouts can also be nested. +
  • +
  • Try navigating between categories and sub categories.
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/layouts/template.tsx b/apps/next-app-router/next-app-router-4000/app/layouts/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/layouts/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/loading/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/loading/[categorySlug]/page.tsx new file mode 100644 index 00000000000..1c1476a5a6c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/loading/[categorySlug]/page.tsx @@ -0,0 +1,43 @@ +import type { Category } from '#/app/api/categories/category'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const res = await fetch( + // We intentionally delay the response to simulate a slow data + // request that would benefit from `loading.js` + `https://app-playground-api.vercel.app/api/categories?delay=1000&slug=${params.categorySlug}`, + { + // We intentionally disable Next.js Cache to better demo + // `loading.js` + cache: 'no-cache', + }, + ); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const category = (await res.json()) as Category; + + if (!category) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/loading/layout.tsx b/apps/next-app-router/next-app-router-4000/app/loading/layout.tsx new file mode 100644 index 00000000000..0a38bb59e20 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/loading/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import { notFound } from 'next/navigation'; +import React from 'react'; + +const title = 'Loading'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/loading/loading.tsx b/apps/next-app-router/next-app-router-4000/app/loading/loading.tsx new file mode 100644 index 00000000000..7cd327a15f3 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/loading/loading.tsx @@ -0,0 +1,17 @@ +import { SkeletonCard } from '#/ui/skeleton-card'; +export default function Loading() { + return ( +
+

Loading...

+ +
+ + + + + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/loading/page.tsx b/apps/next-app-router/next-app-router-4000/app/loading/page.tsx new file mode 100644 index 00000000000..544dbea59ed --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/loading/page.tsx @@ -0,0 +1,35 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Instant Loading States

+ +
    +
  • + This example has an artificial delay when "fetching" data + for each category page. loading.js is used to show a + loading skeleton immediately while data for category page loads before + being streamed in. +
  • +
  • + Shared layouts remain interactive while nested layouts or pages load. + Try clicking the counter while the children load. +
  • +
  • + Navigation is interruptible. Try navigating to one category, then + clicking a second category before the first one has loaded. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/loading/template.tsx b/apps/next-app-router/next-app-router-4000/app/loading/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/loading/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found.tsx b/apps/next-app-router/next-app-router-4000/app/not-found.tsx new file mode 100644 index 00000000000..51b3d5ad4e4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/[subCategorySlug]/not-found.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/[subCategorySlug]/not-found.tsx new file mode 100644 index 00000000000..6bf5c5b3ceb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/[subCategorySlug]/not-found.tsx @@ -0,0 +1,16 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Sub Category Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..ed9d0322965 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,26 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + // - `getCategory()` returns `notFound()` if the fetched data is `null` or `undefined`. + // - `notFound()` renders the closest `not-found.tsx` in the route segment hierarchy. + // - For `layout.js`, the closest `not-found.tsx` starts from the parent segment. + // - For `page.js`, the closest `not-found.tsx` starts from the same segment. + // - Learn more: https://nextjs.org/docs/app/building-your-application/routing#component-hierarchy. + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..13caeb5571e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/layout.tsx @@ -0,0 +1,51 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + // - `getCategory()` returns `notFound()` if the fetched data is `null` or `undefined`. + // - `notFound()` renders the closest `not-found.tsx` in the route segment hierarchy. + // - For `layout.js`, the closest `not-found.tsx` starts from the parent segment. + // - For `page.js`, the closest `not-found.tsx` starts from the same segment. + // - Learn more: https://nextjs.org/docs/app/building-your-application/routing#component-hierarchy. + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+
+ ({ + text: x.name, + slug: x.slug, + })), + { + text: 'Subcategory That Does Not Exist', + slug: 'does-not-exist', + }, + ]} + /> + +
+ +
+
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/not-found.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/not-found.tsx new file mode 100644 index 00000000000..4f789bdc9d1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Category Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/page.tsx new file mode 100644 index 00000000000..f2f91ecc632 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/page.tsx @@ -0,0 +1,28 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + // - `getCategory()` returns `notFound()` if the fetched data is `null` or `undefined`. + // - `notFound()` renders the closest `not-found.tsx` in the route segment hierarchy. + // - For `layout.js`, the closest `not-found.tsx` starts from the parent segment. + // - For `page.js`, the closest `not-found.tsx` starts from the same segment. + // - Learn more: https://nextjs.org/docs/app/building-your-application/routing#component-hierarchy. + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/[categorySlug]/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/layout.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/layout.tsx new file mode 100644 index 00000000000..87df3e0297b --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/layout.tsx @@ -0,0 +1,51 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Not Found'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { + text: 'Category That Does Not Exist', + slug: 'does-not-exist', + }, + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/not-found.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/not-found.tsx new file mode 100644 index 00000000000..6fd919d0777 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/page.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/page.tsx new file mode 100644 index 00000000000..42bc8b3d535 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/page.tsx @@ -0,0 +1,54 @@ +import { ExternalLink } from '#/ui/external-link'; +import Link from 'next/link'; + +export default function Page() { + return ( +
+

Not Found

+ +
    +
  • + + + not-found.js + + {' '} + file is used to render UI when the{' '} + + + notFound() + + {' '} + function is thrown within a route segment. +
  • +
  • + In this example, when fetching the data we return{' '} + notFound() for{' '} + Categories and{' '} + + Sub Categories + {' '} + that do not exist. This renders the closest appropriate{' '} + not-found.js. +
  • +
  • + + Note: not-found.js currently only renders when + triggered by the notFound() function. We're + working on support for catching unmatched routes (404). + +
  • +
+ +
+ + Docs + + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/not-found/template.tsx b/apps/next-app-router/next-app-router-4000/app/not-found/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/not-found/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/page.tsx b/apps/next-app-router/next-app-router-4000/app/page.tsx new file mode 100644 index 00000000000..0c8b03c0c0e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/page.tsx @@ -0,0 +1,47 @@ +import { demos } from '#/lib/demos'; +import Link from 'next/link'; +import dynamic from 'next/dynamic'; +const Button = dynamic(() => import('remote_4001/Button'), { ssr: true }); + +export default function Page() { + return ( +
+ +

Examples

+ +
+ {demos.map((section) => { + return ( +
+
+ {section.name} +
+ +
+ {section.items.map((item) => { + return ( + +
+ {item.name} +
+ + {item.description ? ( +
+ {item.description} +
+ ) : null} + + ); + })} +
+
+ ); + })} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/default.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/default.tsx new file mode 100644 index 00000000000..2d141a3d32b --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/default.tsx @@ -0,0 +1,47 @@ +import { CurrentRoute } from '#/app/parallel-routes/_ui/current-route'; +import { Boundary } from '#/ui/boundary'; +import Link from 'next/link'; + +export default function Default() { + return ( + +
+

Default UI

+ +

+ Default UI is rendered because the @audience slot{' '} + does not contain a route segment that matches the + current{' '} + + / + {' '} + route. +

+ +
    +
  • + + @audience/ + + /page.js + {' '} + does not exist. +
  • + +
  • + @audience/default.js exists. +
  • +
+ +
+ + Home + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/demographics/page.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/demographics/page.tsx new file mode 100644 index 00000000000..94fb886c860 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/demographics/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Demographics

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/layout.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/layout.tsx new file mode 100644 index 00000000000..de0189c5aad --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/layout.tsx @@ -0,0 +1,29 @@ +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + +
+ + + {children} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/page.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/page.tsx new file mode 100644 index 00000000000..3af70b68693 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Home

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/subscribers/page.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/subscribers/page.tsx new file mode 100644 index 00000000000..2f1df01665c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@audience/subscribers/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Subscribers

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/default.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/default.tsx new file mode 100644 index 00000000000..04054c9dd82 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/default.tsx @@ -0,0 +1,46 @@ +import { CurrentRoute } from '#/app/parallel-routes/_ui/current-route'; +import { Boundary } from '#/ui/boundary'; +import Link from 'next/link'; + +export default function Default() { + return ( + +
+

Default UI

+ +

+ Default UI is rendered because the @views slot{' '} + does not contain a route segment that matches the + current{' '} + + / + {' '} + route. +

+ +
    +
  • + + @views/ + + /page.js + {' '} + does not exist. +
  • + +
  • + @views/default.js exists. +
  • +
+
+ + Home + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/impressions/page.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/impressions/page.tsx new file mode 100644 index 00000000000..014ffc879a8 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/impressions/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Impressions

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/layout.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/layout.tsx new file mode 100644 index 00000000000..53d028c9375 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/layout.tsx @@ -0,0 +1,28 @@ +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + +
+ + {children} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/page.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/page.tsx new file mode 100644 index 00000000000..c8f222581aa --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Home

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/view-duration/page.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/view-duration/page.tsx new file mode 100644 index 00000000000..a95983c9491 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/@views/view-duration/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

View Duration

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/_ui/current-route.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/_ui/current-route.tsx new file mode 100644 index 00000000000..ca756b54acc --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/_ui/current-route.tsx @@ -0,0 +1,9 @@ +'use client'; + +import { usePathname } from 'next/navigation'; + +export function CurrentRoute({ slice = 2 }: { slice?: number }) { + const pathname = usePathname(); + + return <>{pathname?.split('/').slice(slice).join('/')}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/default.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/default.tsx new file mode 100644 index 00000000000..bc636c13e67 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/default.tsx @@ -0,0 +1,54 @@ +import { CurrentRoute } from '#/app/parallel-routes/_ui/current-route'; +import { Boundary } from '#/ui/boundary'; +import Link from 'next/link'; + +export default function Default() { + return ( + +
+

Default UI

+ +

+ Default UI is rendered because the implicit @children{' '} + slot does not contain a route segment that matches + the current{' '} + + / + {' '} + route. +

+ +
    +
  • + + parallel-routes/ + + /page.js + {' '} + OR{' '} + + parallel-routes/@children/ + + /page.js + {' '} + do not exist. +
  • + +
  • + parallel-routes/default.js OR{' '} + parallel-routes/@children/default.js exists. +
  • +
+ +
+ + Home + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/layout.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/layout.tsx new file mode 100644 index 00000000000..db0f3ad8ea9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/layout.tsx @@ -0,0 +1,32 @@ +const title = 'Parallel Routes'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ + children, + audience, + views, +}: { + children: React.ReactNode; + audience: React.ReactNode; + views: React.ReactNode; +}) { + return ( +
+
+ {children} + +
+ {audience} + {views} +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/not-found.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/not-found.tsx new file mode 100644 index 00000000000..0a093b49d74 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/parallel-routes/page.tsx b/apps/next-app-router/next-app-router-4000/app/parallel-routes/page.tsx new file mode 100644 index 00000000000..f681f4e6af2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/parallel-routes/page.tsx @@ -0,0 +1,52 @@ +import { Boundary } from '#/ui/boundary'; +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( + +
+

Parallel Routes

+
    +
  • + Parallel Routes allow you to simultaneously or conditionally render + multiple pages, with independent navigation, in the same layout. +
  • +
  • + Parallel Routes can be used for advanced routing patterns like{' '} + + Conditional Routes + {' '} + and{' '} + + Intercepted Routes + + . +
  • +
  • + Try using the tabs in one parallel route to navigate. Notice the URL + changes but the unaffected parallel route is preserved. +
  • +
  • + Try using the browser's backwards and forwards navigation. + Notice the browser's URL history state and active UI state is + correctly synced. +
  • +
  • + Try navigating to a tab in one parallel route and refreshing the + browser. Notice you can choose what UI to show parallel routes that + don't match the initial URL. +
  • +
+
+ + Docs + + + + Code + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/active-links/_components/nav-links.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/_components/nav-links.tsx new file mode 100644 index 00000000000..4b6ce37cab1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/_components/nav-links.tsx @@ -0,0 +1,34 @@ +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import clsx from 'clsx'; + +export function NavLinks({ + links, +}: { + links: { href: string; name: string }[]; +}) { + // Alternatively, you could use `useParams` or `useSelectedLayoutSegment(s)` + const pathname = usePathname(); + + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/active-links/community/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/community/page.tsx new file mode 100644 index 00000000000..c068b02d3b2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/community/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Community

; +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/active-links/layout.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/layout.tsx new file mode 100644 index 00000000000..ab5017e9e85 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/layout.tsx @@ -0,0 +1,32 @@ +import { NavLinks } from '#/app/patterns/active-links/_components/nav-links'; +import { NextLogoDark } from '#/ui/next-logo'; +import Image from 'next/image'; +import Link from 'next/link'; + +export default function Layout({ children }: { children: React.ReactNode }) { + // Hardcoded links or fetched from db + const links = [ + { href: '/patterns/active-links', name: 'Home' }, + { href: '/patterns/active-links/profile', name: 'Profile' }, + { href: '/patterns/active-links/community', name: 'Community' }, + { href: '/patterns/active-links/settings', name: 'Settings' }, + ]; + + return ( +
+
+ + + User + +
+
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/active-links/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/page.tsx new file mode 100644 index 00000000000..17c847eeb0c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Home

; +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/active-links/profile/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/profile/page.tsx new file mode 100644 index 00000000000..d22888e45d7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/profile/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Profile

; +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/active-links/settings/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/settings/page.tsx new file mode 100644 index 00000000000..ab769269f16 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/active-links/settings/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Settings

; +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/@slot/[...all]/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/@slot/[...all]/page.tsx new file mode 100644 index 00000000000..24a98c10136 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/@slot/[...all]/page.tsx @@ -0,0 +1,25 @@ +import { Breadcrumbs } from '#/app/patterns/breadcrumbs/_components/breadcrumbs'; + +export default async function Page(props: { + params: Promise<{ + all: string[]; + }>; +}) { + const params = await props.params; + + const { all } = params; + + // Note: you could fetch breadcrumb data based on params here + // e.g. title, slug, children/siblings (for dropdowns) + const items = [ + { + text: 'Home', + href: '/patterns/breadcrumbs', + }, + ...all.map((param) => ({ + text: param, + href: `/patterns/breadcrumbs/${param}`, + })), + ]; + return ; +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/@slot/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/@slot/page.tsx new file mode 100644 index 00000000000..212e9b903e3 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/@slot/page.tsx @@ -0,0 +1,13 @@ +import { Breadcrumbs } from '#/app/patterns/breadcrumbs/_components/breadcrumbs'; + +// Note: Next.js doesn't currently support optional catchAll segments in parallel routes. +// In the mean time, this file will match the "/breadcrumb" route. +export default function Page() { + const items = [ + { + text: 'Home', + href: '/patterns/breadcrumbs', + }, + ]; + return ; +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..4bbfae6d332 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,21 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..cfef26af394 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/layout.tsx @@ -0,0 +1,35 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/page.tsx new file mode 100644 index 00000000000..672e25359c6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/[categorySlug]/page.tsx @@ -0,0 +1,23 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/_components/breadcrumbs.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/_components/breadcrumbs.tsx new file mode 100644 index 00000000000..452724b1d0f --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/_components/breadcrumbs.tsx @@ -0,0 +1,31 @@ +import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import Link from 'next/link'; +import { Fragment } from 'react'; + +export function Breadcrumbs({ + items, +}: { + items: { text: string; href: string }[]; +}) { + return ( +
+ {items.map((item, i) => { + return ( + + {i === 0 ? null : ( + + )} + + + {item.text} + + + ); + })} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/layout.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/layout.tsx new file mode 100644 index 00000000000..e100c42f805 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Breadcrumbs with Parallel Routes'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, + slot, +}: { + children: React.ReactNode; + slot: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+ {slot} + +
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> +
+ + {children} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/page.tsx new file mode 100644 index 00000000000..579a2c5f6ac --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/breadcrumbs/page.tsx @@ -0,0 +1,43 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

+ Shared server-side UI that depends on URL information +

+ +
    +
  • + Typically, when you have shared UI, you'd put it inside a layout. + However, layouts do not receive searchParams and{' '} + params lower than their segment. This is a challenge for + shared UI like breadcrumbs that depends on the URL information. +
  • +
  • + For simple cases, you can move the UI to Client Components and use + router hooks such as usePathname and{' '} + useSearchParams. +
  • +
  • + This example shows how to use Parallel Routes and a{' '} + page.js in a catch all route to have pockets of shared UI + across your app. +
  • +
  • + Try navigating between categories and sub categories. Notice the + breadcrumbs can derive URL information. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/layout.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/layout.tsx new file mode 100644 index 00000000000..d9758696867 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/layout.tsx @@ -0,0 +1,13 @@ +const title = 'Snippets'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/page.tsx new file mode 100644 index 00000000000..c630e1c5f6c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/page.tsx @@ -0,0 +1,56 @@ +import { ExternalLink } from '#/ui/external-link'; +import Link from 'next/link'; + +const items = [ + { + name: 'Active links', + slug: 'active-links', + description: 'Update the style of the current active link', + }, + { + name: 'Breadcrumbs', + slug: 'breadcrumbs', + description: 'Shared server-side Breadcrumb UI using Parallel Routes', + }, + { + name: 'Updating URL search params', + slug: 'search-params', + description: 'Update searchParams using `useRouter` and ``', + }, +]; + +export default function Page() { + return ( +
+

Patterns

+ +
+ {items.map((item) => { + return ( + +
+ {item.name} +
+ + {item.description ? ( +
+ {item.description} +
+ ) : null} + + ); + })} +
+ +
+ + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/search-params/active-link.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/search-params/active-link.tsx new file mode 100644 index 00000000000..f22ccbf9364 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/search-params/active-link.tsx @@ -0,0 +1,30 @@ +'use client'; + +import clsx from 'clsx'; +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; + +export default function ActiveLink({ + isActive, + searchParams, + children, +}: { + isActive: boolean; + searchParams: string; + children: React.ReactNode; +}) { + const pathname = usePathname(); + + return ( + + {children} + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/search-params/client.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/search-params/client.tsx new file mode 100644 index 00000000000..a72f89e5a7c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/search-params/client.tsx @@ -0,0 +1,82 @@ +'use client'; + +import clsx from 'clsx'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useCallback, useMemo } from 'react'; + +export default function Client({ + options, +}: { + options: { + name: string; + value: string; + items: string[]; + }[]; +}) { + const searchParams = useSearchParams()!; + const pathname = usePathname(); + const router = useRouter(); + + const selectedOptions = useMemo(() => { + // Get the initial selected options from the URL's searchParams + const params = new URLSearchParams(searchParams); + + // Preselect the first value of each option if its not + // included in the current searchParams + options.forEach((option) => { + if (!searchParams.has(option.value)) { + params.set(option.value, option.items[0]); + } + }); + + return params; + }, [searchParams, options]); + + const updateSearchParam = useCallback( + (name: string, value: string) => { + // Merge the current searchParams with the new param set + const params = new URLSearchParams(searchParams); + params.set(name, value); + + // Perform a new navigation to the updated URL. The current `page.js` will + // receive a new `searchParams` prop with the updated values. + router.push(pathname + '?' + params.toString()); // or router.replace() + }, + [router, pathname, searchParams], + ); + + return ( + <> +
+ {options.map((option) => ( +
+
{option.name}
+ +
+ {option.items.map((item) => { + const isActive = selectedOptions.get(option.value) === item; + + return ( + + ); + })} +
+
+ ))} +
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/patterns/search-params/page.tsx b/apps/next-app-router/next-app-router-4000/app/patterns/search-params/page.tsx new file mode 100644 index 00000000000..fa94328726f --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/patterns/search-params/page.tsx @@ -0,0 +1,106 @@ +import { Boundary } from '#/ui/boundary'; +import { ExternalLink } from '#/ui/external-link'; +import { Suspense } from 'react'; +import ActiveLink from './active-link'; +import Client from './client'; + +const options = [ + { + name: 'Sort', + value: 'sort', + items: ['asc', 'desc'], + }, + { + name: 'Page', + value: 'page', + items: ['1', '2', '3'], + }, + { + name: 'Items Per Page', + value: 'perPage', + items: ['10', '25', '100'], + }, +]; + +export const dynamic = 'force-dynamic'; + +export default async function Page(props: { searchParams: Promise }) { + const searchParams = await props.searchParams; + return ( +
+

+ Updating searchParams +

+

+ The useSearchParams hook returns a read only version of{' '} + URLSearchParams. You can use{' '} + useRouter() or <Link> to set new{' '} + searchParams. After a navigation is performed, the current{' '} + page.js will receive an updated searchParams{' '} + prop. +

+
+
+ +

+ Using useRouter() +

+ + + + +
+ + + Docs + +
+ +
+ +

+ Using <Link> +

+ +
+ {options.map((option) => { + return ( +
+
{option.name}
+ +
+ {option.items.map((item, i) => { + const isActive = + // set the first item as active if no search param is set + (!searchParams[option.value] && i === 0) || + // otherwise check if the current item is the active one + item === searchParams[option.value]; + + // create new searchParams object for easier manipulation + const params = new URLSearchParams(searchParams); + params.set(option.value, item); + return ( + + {item} + + ); + })} +
+
+ ); + })} +
+
+ + + Docs + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/checkout/page.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/checkout/page.tsx new file mode 100644 index 00000000000..80dc7c2458e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/checkout/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Checkout

; +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/layout.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/layout.tsx new file mode 100644 index 00000000000..7054058ef16 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/layout.tsx @@ -0,0 +1,23 @@ +import { Boundary } from '#/ui/boundary'; +import { TabNavItem } from '#/ui/tab-nav-item'; +import React from 'react'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + +
+
+
+ Back +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/template.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(checkout)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/layout.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/layout.tsx new file mode 100644 index 00000000000..bcc0006a866 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/layout.tsx @@ -0,0 +1,46 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { text: 'Checkout', slug: 'checkout' }, + { text: 'Blog', slug: 'blog' }, + ]} + /> + +
+ +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/page.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/page.tsx new file mode 100644 index 00000000000..b3b778e397a --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/page.tsx @@ -0,0 +1,38 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Route Groups

+ +
    +
  • + This example uses Route Groups to create layouts for different + sections of the app without affecting the URL structure. +
  • +
  • + Try navigating pages and noting the different layouts used for each + section. +
  • +
  • Route groups can be used to:
  • +
      +
    • Opt a route segment out of a shared layout.
    • +
    • Organize routes without affecting the URL structure.
    • +
    • + Create multiple root layouts by partitioning the top level of the + application. +
    • +
    +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/template.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(main)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/blog/page.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/blog/page.tsx new file mode 100644 index 00000000000..1b1a8a4e52b --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/blog/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Blog

; +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/layout.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/layout.tsx new file mode 100644 index 00000000000..2417ef5e4f8 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/layout.tsx @@ -0,0 +1,46 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { text: 'Checkout', slug: 'checkout' }, + { text: 'Blog', slug: 'blog' }, + ]} + /> + +
+ +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/template.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(marketing)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..ca6da06338b --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,22 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..69b74e3a8bb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/layout.tsx @@ -0,0 +1,39 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/page.tsx new file mode 100644 index 00000000000..df3bd10827f --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/page.tsx @@ -0,0 +1,22 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/[categorySlug]/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/layout.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/layout.tsx new file mode 100644 index 00000000000..7884628bc29 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/layout.tsx @@ -0,0 +1,42 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { text: 'Checkout', slug: 'checkout' }, + { text: 'Blog', slug: 'blog' }, + ]} + /> + +
+ +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/template.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/(shop)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/route-groups/layout.tsx b/apps/next-app-router/next-app-router-4000/app/route-groups/layout.tsx new file mode 100644 index 00000000000..8c5355869d9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/route-groups/layout.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +const title = 'Route Groups'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssg/[id]/page.tsx b/apps/next-app-router/next-app-router-4000/app/ssg/[id]/page.tsx new file mode 100644 index 00000000000..4e2c40d37ca --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssg/[id]/page.tsx @@ -0,0 +1,35 @@ +import { RenderingInfo } from '#/ui/rendering-info'; +import { notFound } from 'next/navigation'; + +export async function generateStaticParams() { + // Generate two pages at build time and the rest (3-100) on-demand + return [{ id: '1' }, { id: '2' }]; +} + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + if (Number(params.id) >= 100) { + notFound(); + } + + const res = await fetch( + `https://jsonplaceholder.typicode.com/posts/${params.id}`, + ); + const data = (await res.json()) as { title: string; body: string }; + + const isOnDemand = Number(params.id) >= 3; + + return ( +
+
+

+ {data.title} +

+

{data.body}

+
+
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssg/layout.tsx b/apps/next-app-router/next-app-router-4000/app/ssg/layout.tsx new file mode 100644 index 00000000000..3ca03680c4e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssg/layout.tsx @@ -0,0 +1,28 @@ +import { Tab } from '#/ui/tab'; +import React from 'react'; +import { RandomPostTab } from './random-post-tab'; + +const title = 'Static Data'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+
+ + + + +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssg/loading.tsx b/apps/next-app-router/next-app-router-4000/app/ssg/loading.tsx new file mode 100644 index 00000000000..2c150f871d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssg/loading.tsx @@ -0,0 +1,5 @@ +import { RenderingPageSkeleton } from '#/ui/rendering-page-skeleton'; + +export default function Loading() { + return ; +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssg/page.tsx b/apps/next-app-router/next-app-router-4000/app/ssg/page.tsx new file mode 100644 index 00000000000..3133fa73b3d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssg/page.tsx @@ -0,0 +1,31 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Static Data

+ +
    +
  • By default, data fetching in Next.js is cached static.
  • +
  • This example statically caches data fetches for Post 1 and 2.
  • +
  • + A random third post is fetched on-demand the first time it is + requested. +
  • +
  • + Try navigating to each post and noting the timestamp of when the page + was rendered. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssg/random-post-tab.tsx b/apps/next-app-router/next-app-router-4000/app/ssg/random-post-tab.tsx new file mode 100644 index 00000000000..3d92f7aecf1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssg/random-post-tab.tsx @@ -0,0 +1,32 @@ +'use client'; + +import { Tab } from '#/ui/tab'; +import clsx from 'clsx'; +import React, { useEffect } from 'react'; + +const randomNumber = (min: number, max: number) => + Math.floor(Math.random() * (max - min + 1) + min); + +export function RandomPostTab({ path }: { path: string }) { + const [post, setPost] = React.useState( + null, + ); + + useEffect(() => { + const randomId = String(randomNumber(3, 100)); + setPost({ text: `Post ${randomId} (On Demand)`, slug: randomId }); + }, []); + + return ( +
+ {post ? ( + + ) : null} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssg/template.tsx b/apps/next-app-router/next-app-router-4000/app/ssg/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssg/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssr/[id]/page.tsx b/apps/next-app-router/next-app-router-4000/app/ssr/[id]/page.tsx new file mode 100644 index 00000000000..c4e89fae45d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssr/[id]/page.tsx @@ -0,0 +1,24 @@ +import { RenderingInfo } from '#/ui/rendering-info'; + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + const res = await fetch( + `https://jsonplaceholder.typicode.com/posts/${params.id}`, + { cache: 'no-store' }, + ); + const data = (await res.json()) as { title: string; body: string }; + + return ( +
+
+

+ {data.title} +

+

{data.body}

+
+
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssr/layout.tsx b/apps/next-app-router/next-app-router-4000/app/ssr/layout.tsx new file mode 100644 index 00000000000..3ed3464f0b7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssr/layout.tsx @@ -0,0 +1,34 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Dynamic Data'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; +export default function Layout({ children }: { children: React.ReactNode }) { + const ids = [{ id: '1' }, { id: '2' }, { id: '3' }]; + + return ( +
+ ({ + text: `Post ${x.id}`, + slug: x.id, + })), + ]} + /> + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssr/loading.tsx b/apps/next-app-router/next-app-router-4000/app/ssr/loading.tsx new file mode 100644 index 00000000000..2c150f871d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssr/loading.tsx @@ -0,0 +1,5 @@ +import { RenderingPageSkeleton } from '#/ui/rendering-page-skeleton'; + +export default function Loading() { + return ; +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssr/page.tsx b/apps/next-app-router/next-app-router-4000/app/ssr/page.tsx new file mode 100644 index 00000000000..a7b057a676f --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssr/page.tsx @@ -0,0 +1,29 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Dynamic Data

+ +
    +
  • + Dynamic, or server-rendered data, is fetched fresh on each request. +
  • +
  • In this example, the post responses are explicitly not cached.
  • +
  • + Try navigating to each post and noting the timestamp of when the page + was rendered. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/ssr/template.tsx b/apps/next-app-router/next-app-router-4000/app/ssr/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/ssr/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/add-to-cart.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/add-to-cart.tsx new file mode 100644 index 00000000000..1f0ddd20f68 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/add-to-cart.tsx @@ -0,0 +1,56 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { useTransition } from 'react'; +import { useCartCount } from './cart-count-context'; + +export function AddToCart({ initialCartCount }: { initialCartCount: number }) { + const router = useRouter(); + const [isPending, startTransition] = useTransition(); + + const [, setOptimisticCartCount] = useCartCount(); + + const addToCart = () => { + setOptimisticCartCount(initialCartCount + 1); + + // update the cart count cookie + document.cookie = `_cart_count=${initialCartCount + 1}; path=/; max-age=${ + 60 * 60 * 24 * 30 + }};`; + + // Normally you would also send a request to the server to add the item + // to the current users cart + // await fetch(`https://api.acme.com/...`); + + // Use a transition and isPending to create inline loading UI + startTransition(() => { + setOptimisticCartCount(null); + + // Refresh the current route and fetch new data from the server without + // losing client-side browser or React state. + router.refresh(); + + // We're working on more fine-grained data mutation and revalidation: + // https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions + }); + }; + + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/cart-count-context.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/cart-count-context.tsx new file mode 100644 index 00000000000..83fff442f0b --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/cart-count-context.tsx @@ -0,0 +1,36 @@ +'use client'; + +import React, { useState } from 'react'; + +const CartCountContext = React.createContext< + [number, React.Dispatch>] | undefined +>(undefined); + +export function CartCountProvider({ + children, + initialCartCount, +}: { + children: React.ReactNode; + initialCartCount: number; +}) { + const [optimisticCartCount, setOptimisticCartCount] = useState( + null, + ); + + const count = + optimisticCartCount !== null ? optimisticCartCount : initialCartCount; + + return ( + + {children} + + ); +} + +export function useCartCount() { + const context = React.useContext(CartCountContext); + if (context === undefined) { + throw new Error('useCartCount must be used within a CartCountProvider'); + } + return context; +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/cart-count.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/cart-count.tsx new file mode 100644 index 00000000000..cc740ba9830 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/cart-count.tsx @@ -0,0 +1,8 @@ +'use client'; + +import { useCartCount } from './cart-count-context'; + +export function CartCount() { + const [count] = useCartCount(); + return {count}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/header.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/header.tsx new file mode 100644 index 00000000000..9c097ff8b08 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/header.tsx @@ -0,0 +1,53 @@ +import { NextLogoLight } from '#/ui/next-logo'; +import { + MagnifyingGlassIcon, + ShoppingCartIcon, +} from '@heroicons/react/24/solid'; +import Image from 'next/image'; +import Link from 'next/link'; +import { CartCount } from './cart-count'; + +export function Header() { + return ( +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+ +
+
+ +
+ +
+
+ + User +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/pricing.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/pricing.tsx new file mode 100644 index 00000000000..d252fddaedb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/pricing.tsx @@ -0,0 +1,84 @@ +import type { Product } from '#/app/api/products/product'; +import { Ping } from '#/ui/ping'; +import { ProductEstimatedArrival } from '#/ui/product-estimated-arrival'; +import { ProductLowStockWarning } from '#/ui/product-low-stock-warning'; +import { ProductPrice } from '#/ui/product-price'; +import { ProductSplitPayments } from '#/ui/product-split-payments'; +import { ProductUsedPrice } from '#/ui/product-used-price'; +import { dinero, type DineroSnapshot } from 'dinero.js'; +import { Suspense } from 'react'; +import { AddToCart } from './add-to-cart'; + +function LoadingDots() { + return ( +
+ + + • + + + • + + + • + + +
+ ); +} + +async function UserSpecificDetails({ productId }: { productId: string }) { + const data = await fetch( + `https://app-playground-api.vercel.app/api/products?id=${productId}&delay=500&filter=price,usedPrice,leadTime,stock`, + { + // We intentionally disable Next.js Cache to better demo + // streaming + cache: 'no-store', + }, + ); + + const product = (await data.json()) as Product; + + const price = dinero(product.price as DineroSnapshot); + + return ( + <> + + {product.usedPrice ? ( + + ) : null} + + {product.stock <= 1 ? ( + + ) : null} + + ); +} + +export function Pricing({ + product, + cartCount, +}: { + product: Product; + cartCount: string; +}) { + const price = dinero(product.price as DineroSnapshot); + + return ( +
+ + +
+
+ +
+
+ + }> + + + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/recommended-products.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/recommended-products.tsx new file mode 100644 index 00000000000..09c72f3e3c1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/recommended-products.tsx @@ -0,0 +1,65 @@ +import { Product } from '#/app/api/products/product'; +import { ProductCard } from '#/ui/product-card'; + +export async function RecommendedProducts({ + path, + data, +}: { + path: string; + data: Promise; +}) { + const products = (await data.then((res) => res.json())) as Product[]; + + return ( +
+
+
+ Recommended Products for You +
+
+ Based on your preferences and shopping habits +
+
+
+ {products.map((product) => ( +
+ +
+ ))} +
+
+ ); +} + +const shimmer = `relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_1.5s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent`; + +function ProductSkeleton() { + return ( +
+
+ +
+
+
+
+
+ ); +} + +export function RecommendedProductsSkeleton() { + return ( +
+
+
+
+
+ +
+ + + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/reviews.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/reviews.tsx new file mode 100644 index 00000000000..ab45a45bfb5 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/reviews.tsx @@ -0,0 +1,43 @@ +import type { Review } from '#/app/api/reviews/review'; +import { ProductReviewCard } from '#/ui/product-review-card'; + +export async function Reviews({ data }: { data: Promise }) { + const reviews = (await data.then((res) => res.json())) as Review[]; + + return ( +
+
Customer Reviews
+
+ {reviews.map((review) => { + return ; + })} +
+
+ ); +} + +const shimmer = `relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_1.5s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent`; + +function Skeleton() { + return ( +
+
+
+
+
+
+ ); +} + +export function ReviewsSkeleton() { + return ( +
+
+ +
+ + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/_components/single-product.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/_components/single-product.tsx new file mode 100644 index 00000000000..139bd6be3dd --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/_components/single-product.tsx @@ -0,0 +1,76 @@ +import { Pricing } from '#/app/streaming/_components/pricing'; +import type { Product } from '#/app/api/products/product'; +import { ProductRating } from '#/ui/product-rating'; +import { cookies } from 'next/headers'; +import Image from 'next/image'; + +export const SingleProduct = async ({ data }: { data: Promise }) => { + const product = (await data.then((res) => res.json())) as Product; + + // Get the cart count from the users cookies and pass it to the client + // AddToCart component + const cartCount = (await cookies()).get('_cart_count')?.value || '0'; + + return ( +
+
+
+ {product.name} + +
+
+ {product.name} +
+
+ {product.name} +
+
+ {product.name} +
+
+
+
+ +
+
+ {product.name} +
+ + + +
+

{product.description}

+

{product.description}

+
+
+ +
+ +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/edge/layout.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/edge/layout.tsx new file mode 100644 index 00000000000..6a482c4aa27 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/edge/layout.tsx @@ -0,0 +1,46 @@ +import { Boundary } from '#/ui/boundary'; +import { cookies } from 'next/headers'; +import React from 'react'; +import { CartCountProvider } from '../_components/cart-count-context'; +import { Header } from '../_components/header'; + +export const metadata = { + title: 'Streaming (Edge Runtime)', +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const cartCount = Number((await cookies()).get('_cart_count')?.value || '0'); + + return ( + <> +
+
    +
  • + Primary product information is loaded first as part of the initial + response. +
  • +
  • + Secondary, more personalized details (that might be slower) like + ship date, other recommended products, and customer reviews are + progressively streamed in. +
  • +
  • Try refreshing or navigating to other recommended products.
  • +
+
+ + + +
+
+ + {children} +
+
+
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/edge/product/[id]/page.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/edge/product/[id]/page.tsx new file mode 100644 index 00000000000..be56a674d40 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/edge/product/[id]/page.tsx @@ -0,0 +1,66 @@ +import { + RecommendedProducts, + RecommendedProductsSkeleton, +} from '#/app/streaming/_components/recommended-products'; +import { Reviews, ReviewsSkeleton } from '#/app/streaming/_components/reviews'; +import { SingleProduct } from '#/app/streaming/_components/single-product'; +import { Ping } from '#/ui/ping'; +import { Suspense } from 'react'; + +export const runtime = 'edge'; + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + return ( +
+ + +
+
+ +
+
+ + }> + + + +
+
+ +
+
+ + }> + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/layout.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/layout.tsx new file mode 100644 index 00000000000..a6b84433e3e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/layout.tsx @@ -0,0 +1,45 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Streaming'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+
+ +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/node/layout.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/node/layout.tsx new file mode 100644 index 00000000000..9d389013731 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/node/layout.tsx @@ -0,0 +1,45 @@ +import { Boundary } from '#/ui/boundary'; +import { cookies } from 'next/headers'; +import React from 'react'; +import { CartCountProvider } from '../_components/cart-count-context'; +import { Header } from '../_components/header'; + +export const metadata = { + title: 'Streaming (Node Runtime)', +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const cartCount = Number((await cookies()).get('_cart_count')?.value || '0'); + + return ( + <> +
+
    +
  • + Primary product information is loaded first as part of the initial + response. +
  • +
  • + Secondary, more personalized details (that might be slower) like + ship date, other recommended products, and customer reviews are + progressively streamed in. +
  • +
  • Try refreshing or navigating to other recommended products.
  • +
+
+ + +
+
+ + {children} +
+
+
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/node/product/[id]/page.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/node/product/[id]/page.tsx new file mode 100644 index 00000000000..b40f468f1ca --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/node/product/[id]/page.tsx @@ -0,0 +1,64 @@ +import { + RecommendedProducts, + RecommendedProductsSkeleton, +} from '#/app/streaming/_components/recommended-products'; +import { Reviews, ReviewsSkeleton } from '#/app/streaming/_components/reviews'; +import { SingleProduct } from '#/app/streaming/_components/single-product'; +import { Ping } from '#/ui/ping'; +import { Suspense } from 'react'; + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + return ( +
+ + +
+
+ +
+
+ + }> + + + +
+
+ +
+
+ + }> + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/streaming/page.tsx b/apps/next-app-router/next-app-router-4000/app/streaming/page.tsx new file mode 100644 index 00000000000..4aa68dc9551 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/streaming/page.tsx @@ -0,0 +1,38 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default async function Page() { + return ( +
+

Streaming with Suspense

+ +
    +
  • + Streaming allows you to progressively render and send units of the UI + from the server to the client. +
  • + +
  • + This allows the user to see and interact with the most essential parts + of the page while the rest of the content loads - instead of waiting + for the whole page to load before they can interact with anything. +
  • + +
  • Streaming works with both Edge and Node runtimes.
  • + +
  • + Try streaming by selecting a runtime in the + navigation above. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/css-modules/page.tsx b/apps/next-app-router/next-app-router-4000/app/styling/css-modules/page.tsx new file mode 100644 index 00000000000..a9cf5e25820 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/css-modules/page.tsx @@ -0,0 +1,27 @@ +'use client'; + +import styles from './styles.module.css'; + +const SkeletonCard = () => ( +
+
+
+
+
+
+); + +export default function Page() { + return ( +
+

+ Styled with CSS Modules +

+
+ + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/css-modules/styles.module.css b/apps/next-app-router/next-app-router-4000/app/styling/css-modules/styles.module.css new file mode 100644 index 00000000000..c434f7b160a --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/css-modules/styles.module.css @@ -0,0 +1,54 @@ +.container { + display: grid; + grid-template-columns: repeat(1, minmax(0, 1fr)); + gap: 1.5rem /* 24px */; +} + +@media (min-width: 1024px) { + .container { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +.skeleton { + padding: 1rem /* 16px */; + border-radius: 1rem /* 16px */; + background-color: rgb(24 24 27 / 0.8); +} + +.skeleton-img, +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + border-radius: 0.5rem /* 8px */; +} + +.skeleton-img { + height: 3.5rem /* 56px */; + background-color: rgb(63 63 70 / 1); +} + +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; +} + +.skeleton-btn { + background-color: rgb(121 40 202 / 1); + width: 25%; +} + +.skeleton-line-one, +.skeleton-line-two { + background-color: rgb(63 63 70 / 1); +} + +.skeleton-line-one { + width: 91.666667%; +} + +.skeleton-line-two { + width: 66.666667%; +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/global-css/page.tsx b/apps/next-app-router/next-app-router-4000/app/styling/global-css/page.tsx new file mode 100644 index 00000000000..aa39cc31044 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/global-css/page.tsx @@ -0,0 +1,25 @@ +import './styles.css'; + +const SkeletonCard = () => ( +
+
+
+
+
+
+); + +export default function Page() { + return ( +
+

+ Styled with a Global CSS Stylesheet +

+
+ + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/global-css/styles.css b/apps/next-app-router/next-app-router-4000/app/styling/global-css/styles.css new file mode 100644 index 00000000000..c7b408ef9fc --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/global-css/styles.css @@ -0,0 +1,54 @@ +.container { + display: grid; + grid-template-columns: repeat(1, minmax(0, 1fr)); + gap: 1.5rem /* 24px */; +} + +@media (min-width: 1024px) { + .container { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +.skeleton { + padding: 1rem /* 16px */; + border-radius: 1rem /* 16px */; + background-color: rgb(24 24 27 / 0.8); +} + +.skeleton-img, +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + border-radius: 0.5rem /* 8px */; +} + +.skeleton-img { + height: 3.5rem /* 56px */; + background-color: rgb(63 63 70 / 1); +} + +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; +} + +.skeleton-btn { + background-color: rgb(245 166 35 / 1); + width: 25%; +} + +.skeleton-line-one, +.skeleton-line-two { + background-color: rgb(63 63 70 / 1); +} + +.skeleton-line-one { + width: 91.666667%; +} + +.skeleton-line-two { + width: 66.666667%; +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/layout.tsx b/apps/next-app-router/next-app-router-4000/app/styling/layout.tsx new file mode 100644 index 00000000000..a49a612b565 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/layout.tsx @@ -0,0 +1,52 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Styling'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +const items = [ + { + text: 'Global CSS', + slug: 'global-css', + }, + { + text: 'CSS Modules', + slug: 'css-modules', + }, + { + text: 'Styled Components', + slug: 'styled-components', + }, + { + text: 'Styled JSX', + slug: 'styled-jsx', + }, + { + text: 'Tailwind CSS', + slug: 'tailwind', + }, +]; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/page.tsx b/apps/next-app-router/next-app-router-4000/app/styling/page.tsx new file mode 100644 index 00000000000..fc2df59e419 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/page.tsx @@ -0,0 +1,23 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Styling

+ +
    +
  • This example shows different styling solutions.
  • +
+ +
+ + Docs + + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/styled-components/layout.tsx b/apps/next-app-router/next-app-router-4000/app/styling/styled-components/layout.tsx new file mode 100644 index 00000000000..bc3ce606379 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/styled-components/layout.tsx @@ -0,0 +1,5 @@ +import StyledComponentsRegistry from './registry'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/styled-components/page.tsx b/apps/next-app-router/next-app-router-4000/app/styling/styled-components/page.tsx new file mode 100644 index 00000000000..dc1f3f35c1d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/styled-components/page.tsx @@ -0,0 +1,69 @@ +'use client'; + +import styled from 'styled-components'; + +const Container = styled.div` + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1.5rem /* 24px */; +`; + +const SkeletonInner = styled.div` + padding: 1rem /* 16px */; + background-color: rgb(24 24 27 / 0.8); + border-radius: 1rem /* 16px */; +`; + +const SkeletonImg = styled.div` + height: 3.5rem /* 56px */; + border-radius: 0.5rem /* 8px */; + background-color: rgb(63 63 70 / 1); +`; + +const SkeletonBtn = styled.div` + margin-top: 0.75rem /* 12px */; + width: 25%; + height: 0.75rem /* 12px */; + border-radius: 0.5rem /* 8px */; + background-color: rgb(255 0 128 / 1); +`; + +const SkeletonLineOne = styled.div` + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; + width: 91.666667%; + border-radius: 0.5rem /* 8px */; + background-color: rgb(63 63 70 / 1); +`; + +const SkeletonLineTwo = styled.div` + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; + width: 66.666667%; + border-radius: 0.5rem /* 8px */; + background-color: rgb(63 63 70 / 1); +`; + +const Skeleton = () => ( + + + + + + +); + +export default function Page() { + return ( +
+

+ Styled with Styled Components +

+ + + + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/styled-components/registry.tsx b/apps/next-app-router/next-app-router-4000/app/styling/styled-components/registry.tsx new file mode 100644 index 00000000000..79346eae087 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/styled-components/registry.tsx @@ -0,0 +1,29 @@ +'use client'; + +import React, { useState } from 'react'; +import { useServerInsertedHTML } from 'next/navigation'; +import { ServerStyleSheet, StyleSheetManager } from 'styled-components'; + +export default function StyledComponentsRegistry({ + children, +}: { + children: React.ReactNode; +}) { + // Only create stylesheet once with lazy initial state + // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()); + + useServerInsertedHTML(() => { + const styles = styledComponentsStyleSheet.getStyleElement(); + styledComponentsStyleSheet.instance.clearTag(); + return <>{styles}; + }); + + if (typeof window !== 'undefined') return <>{children}; + + return ( + + {children} + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/layout.tsx b/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/layout.tsx new file mode 100644 index 00000000000..0072c517b27 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/layout.tsx @@ -0,0 +1,5 @@ +import StyledJsxRegistry from './registry'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/page.tsx b/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/page.tsx new file mode 100644 index 00000000000..60f514a285c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/page.tsx @@ -0,0 +1,85 @@ +'use client'; + +const SkeletonCard = () => ( + <> +
+
+
+
+
+
+ + +); + +export default function Page() { + return ( +
+

+ Styled with Styled JSX +

+
+ + + +
+ + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/registry.tsx b/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/registry.tsx new file mode 100644 index 00000000000..c2936d07169 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/styled-jsx/registry.tsx @@ -0,0 +1,23 @@ +'use client'; + +import React, { useState } from 'react'; +import { useServerInsertedHTML } from 'next/navigation'; +import { StyleRegistry, createStyleRegistry } from 'styled-jsx'; + +export default function StyledJsxRegistry({ + children, +}: { + children: React.ReactNode; +}) { + // Only create stylesheet once with lazy initial state + // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + const [jsxStyleRegistry] = useState(() => createStyleRegistry()); + + useServerInsertedHTML(() => { + const styles = jsxStyleRegistry.styles(); + jsxStyleRegistry.flush(); + return <>{styles}; + }); + + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/tailwind/page.tsx b/apps/next-app-router/next-app-router-4000/app/styling/tailwind/page.tsx new file mode 100644 index 00000000000..7ead53333fa --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/tailwind/page.tsx @@ -0,0 +1,24 @@ +const SkeletonCard = () => ( +
+
+
+
+
+
+); + +export default function Page() { + return ( +
+

+ Styled with Tailwind CSS +

+ +
+ + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/app/styling/template.tsx b/apps/next-app-router/next-app-router-4000/app/styling/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/app/styling/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4000/lib/demos.ts b/apps/next-app-router/next-app-router-4000/lib/demos.ts new file mode 100644 index 00000000000..79a1d38ff7d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/lib/demos.ts @@ -0,0 +1,106 @@ +export type Item = { + name: string; + slug: string; + description?: string; +}; + +export const demos: { name: string; items: Item[] }[] = [ + { + name: 'Layouts', + items: [ + { + name: 'Nested Layouts', + slug: 'layouts', + description: 'Create UI that is shared across routes', + }, + { + name: 'Grouped Layouts', + slug: 'route-groups', + description: 'Organize routes without affecting URL paths', + }, + { + name: 'Parallel Routes', + slug: 'parallel-routes', + description: 'Render multiple pages in the same layout', + }, + ], + }, + { + name: 'File Conventions', + items: [ + { + name: 'Loading', + slug: 'loading', + description: + 'Create meaningful Loading UI for specific parts of an app', + }, + { + name: 'Error', + slug: 'error-handling', + description: 'Create Error UI for specific parts of an app', + }, + { + name: 'Not Found', + slug: 'not-found', + description: 'Create Not Found UI for specific parts of an app', + }, + ], + }, + { + name: 'Data Fetching', + items: [ + { + name: 'Streaming with Suspense', + slug: 'streaming', + description: + 'Streaming data fetching from the server with React Suspense', + }, + { + name: 'Static Data', + slug: 'ssg', + description: 'Generate static pages', + }, + { + name: 'Dynamic Data', + slug: 'ssr', + description: 'Server-render pages', + }, + { + name: 'Incremental Static Regeneration', + slug: 'isr', + description: 'Get the best of both worlds between static & dynamic', + }, + ], + }, + { + name: 'Components', + items: [ + { + name: 'Client Context', + slug: 'context', + description: + 'Pass context between Client Components that cross Server/Client Component boundary', + }, + ], + }, + { + name: 'Misc', + items: [ + { + name: 'Patterns', + slug: 'patterns', + description: 'A collection of useful App Router patterns', + }, + { + name: 'Client Component Hooks', + slug: 'hooks', + description: 'Preview the routing hooks available in Client Components', + }, + { + name: 'CSS and CSS-in-JS', + slug: 'styling', + description: 'Preview the supported styling solutions', + }, + ], + }, +]; diff --git a/apps/next-app-router/next-app-router-4000/next-env.d.ts b/apps/next-app-router/next-app-router-4000/next-env.d.ts new file mode 100644 index 00000000000..40c3d68096c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/apps/next-app-router/next-app-router-4000/next.config.js b/apps/next-app-router/next-app-router-4000/next.config.js new file mode 100644 index 00000000000..da2ee672d59 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/next.config.js @@ -0,0 +1,72 @@ +const { withNx } = require('@nx/next/plugins/with-nx'); +const NextFederationPlugin = require('@module-federation/nextjs-mf'); + +/** + * @type {import('@nx/next/plugins/with-nx').WithNxOptions} + **/ +const nextConfig = { + nx: { + // Set this to true if you would like to to use SVGR + // See: https://github.com/gregberge/svgr + svgr: false, + }, + port: 4000, + webpack(config, options) { + const { isServer } = options; + config.watchOptions = { + ignored: ['**/node_modules/**', '**/@mf-types/**'], + }; + // used for testing build output snapshots + const remotes = { + remote_4001: `remote_4001@http://localhost:4001/_next/static/${ + isServer ? 'ssr' : 'chunks' + }/remoteEntry.js`, + checkout: `checkout@http://localhost:4000/_next/static/${ + isServer ? 'ssr' : 'chunks' + }/remoteEntry.js`, + home_app: `home_app@http://localhost:4000/_next/static/${ + isServer ? 'ssr' : 'chunks' + }/remoteEntry.js`, + shop: `shop@http://localhost:4000/_next/static/${ + isServer ? 'ssr' : 'chunks' + }/remoteEntry.js`, + }; + + config.plugins.push( + new NextFederationPlugin({ + name: 'home_app', + filename: 'static/chunks/remoteEntry.js', + remotes: { + remote_4001: remotes.remote_4001, + shop: remotes.shop, + checkout: remotes.checkout, + }, + shared: { + // 'react': { + // singleton: true, + // requiredVersion: false + // }, + // 'react-dom': { + // singleton: true, + // requiredVersion: false + // } + }, + extraOptions: { + // debug: false, + // exposePages: true, + // enableImageLoaderFix: true, + // enableUrlLoaderFix: true, + }, + }), + ); + config.plugins.push({ + name: 'xxx', + apply(compiler) { + compiler.options.devtool = false; + }, + }); + return config; + }, +}; + +module.exports = withNx(nextConfig); diff --git a/apps/next-app-router/next-app-router-4000/package.json b/apps/next-app-router/next-app-router-4000/package.json new file mode 100644 index 00000000000..55521bcf4d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/package.json @@ -0,0 +1,52 @@ +{ + "private": true, + "scripts": { + "build": "next build", + "dev": "NEXT_PRIVATE_LOCAL_WEBPACK=true next dev -p 4000", + "lint": "next lint", + "lint-staged": "lint-staged", + "prettier": "prettier --write --ignore-unknown .", + "prettier:check": "prettier --check --ignore-unknown .", + "start": "next start", + "test": "pnpm prettier:check && pnpm lint" + }, + "git": { + "pre-commit": "lint-staged" + }, + "lint-staged": { + "*": "prettier --write --ignore-unknown" + }, + "dependencies": { + "@heroicons/react": "2.1.3", + "clsx": "2.1.1", + "date-fns": "3.6.0", + "dinero.js": "2.0.0-alpha.10", + "ms": "3.0.0-canary.1", + "next": "15.0.0-canary.193", + "react": "19.0.0-rc-cd22717c-20241013", + "react-dom": "19.0.0-rc-cd22717c-20241013", + "server-only": "0.0.1", + "styled-components": "6.1.8", + "use-count-up": "3.0.1", + "vercel": "34.0.0", + "@module-federation/nextjs-mf": "workspace:*" + }, + "devDependencies": { + "@tailwindcss/forms": "0.5.7", + "@tailwindcss/typography": "0.5.12", + "@types/ms": "0.7.34", + "@types/node": "20.12.7", + "@types/react": "npm:types-react@19.0.0-rc.1", + "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1", + "@vercel/git-hooks": "1.0.0", + "autoprefixer": "10.4.19", + "eslint": "9.0.0", + "eslint-config-next": "14.2.2", + "lint-staged": "15.2.2", + "postcss": "8.4.38", + "prettier": "3.2.5", + "prettier-plugin-tailwindcss": "0.5.14", + "tailwindcss": "3.4.3", + "typescript": "5.4.5" + } +} diff --git a/apps/next-app-router/next-app-router-4000/pnpm-lock.yaml b/apps/next-app-router/next-app-router-4000/pnpm-lock.yaml new file mode 100644 index 00000000000..a441c20e752 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/pnpm-lock.yaml @@ -0,0 +1,5027 @@ +lockfileVersion: '6.0' + +dependencies: + '@heroicons/react': + specifier: 2.1.3 + version: 2.1.3(react@19.0.0-rc-cd22717c-20241013) + clsx: + specifier: 2.1.1 + version: 2.1.1 + date-fns: + specifier: 3.6.0 + version: 3.6.0 + dinero.js: + specifier: 2.0.0-alpha.10 + version: 2.0.0-alpha.10 + ms: + specifier: 3.0.0-canary.1 + version: 3.0.0-canary.1 + next: + specifier: 15.0.0-canary.193 + version: 15.0.0-canary.193(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013) + react: + specifier: 19.0.0-rc-cd22717c-20241013 + version: 19.0.0-rc-cd22717c-20241013 + react-dom: + specifier: 19.0.0-rc-cd22717c-20241013 + version: 19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013) + server-only: + specifier: 0.0.1 + version: 0.0.1 + styled-components: + specifier: 6.1.8 + version: 6.1.8(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013) + use-count-up: + specifier: 3.0.1 + version: 3.0.1(react@19.0.0-rc-cd22717c-20241013) + vercel: + specifier: 34.0.0 + version: 34.0.0 + +devDependencies: + '@tailwindcss/forms': + specifier: 0.5.7 + version: 0.5.7(tailwindcss@3.4.3) + '@tailwindcss/typography': + specifier: 0.5.12 + version: 0.5.12(tailwindcss@3.4.3) + '@types/ms': + specifier: 0.7.34 + version: 0.7.34 + '@types/node': + specifier: 20.12.7 + version: 20.12.7 + '@types/react': + specifier: npm:types-react@19.0.0-rc.1 + version: /types-react@19.0.0-rc.1 + '@types/react-dom': + specifier: npm:types-react-dom@19.0.0-rc.1 + version: /types-react-dom@19.0.0-rc.1 + '@vercel/git-hooks': + specifier: 1.0.0 + version: 1.0.0 + autoprefixer: + specifier: 10.4.19 + version: 10.4.19(postcss@8.4.38) + eslint: + specifier: 9.0.0 + version: 9.0.0 + eslint-config-next: + specifier: 14.2.2 + version: 14.2.2(eslint@9.0.0)(typescript@5.4.5) + lint-staged: + specifier: 15.2.2 + version: 15.2.2 + postcss: + specifier: 8.4.38 + version: 8.4.38 + prettier: + specifier: 3.2.5 + version: 3.2.5 + prettier-plugin-tailwindcss: + specifier: 0.5.14 + version: 0.5.14(prettier@3.2.5) + tailwindcss: + specifier: 3.4.3 + version: 3.4.3 + typescript: + specifier: 5.4.5 + version: 5.4.5 + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + dev: true + + /@babel/runtime@7.24.4: + resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: true + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: false + + /@dinero.js/calculator-number@2.0.0-alpha.10: + resolution: {integrity: sha512-EdKG0yykukigfdq+TsxZ9r0Wrg5flYAncKWSfr2snWDXurFsg8JE0oazVraCBA3Vb5LN4vGuFEpTFTH+dIrRCg==} + dependencies: + '@dinero.js/core': 2.0.0-alpha.10 + dev: false + + /@dinero.js/core@2.0.0-alpha.10: + resolution: {integrity: sha512-vjeGXQbNvDXlXK54zaWDydEXyFAvLDj6LCfwO4CTZJIqn3+PaXakaEd5S0AXC6hluPatxnQa5J63x3WQ/Imrjw==} + dependencies: + '@dinero.js/currencies': 2.0.0-alpha.10 + dev: false + + /@dinero.js/currencies@2.0.0-alpha.10: + resolution: {integrity: sha512-IDKaAh0YcJh700uLCrvWtIRCl5sItc3S2rk4IfVJBbms3j+NBDOlVFJnwru+UrMh7VpqU9GlZRsHcHf0NxYE9A==} + dev: false + + /@edge-runtime/format@2.2.1: + resolution: {integrity: sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/node-utils@2.3.0: + resolution: {integrity: sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/ponyfill@2.4.2: + resolution: {integrity: sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/primitives@4.1.0: + resolution: {integrity: sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/vm@3.2.0: + resolution: {integrity: sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==} + engines: {node: '>=16'} + dependencies: + '@edge-runtime/primitives': 4.1.0 + dev: false + + /@emnapi/runtime@1.3.1: + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + requiresBuild: true + dependencies: + tslib: 2.5.0 + dev: false + optional: true + + /@emotion/is-prop-valid@1.2.1: + resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} + dependencies: + '@emotion/memoize': 0.8.1 + dev: false + + /@emotion/memoize@0.8.1: + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + dev: false + + /@emotion/unitless@0.8.0: + resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} + dev: false + + /@eslint-community/eslint-utils@4.4.0(eslint@9.0.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 9.0.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@3.0.2: + resolution: {integrity: sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 10.0.1 + globals: 14.0.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@9.0.0: + resolution: {integrity: sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@fastify/busboy@2.1.1: + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + dev: false + + /@heroicons/react@2.1.3(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-fEcPfo4oN345SoqdlCDdSa4ivjaKbk0jTd+oubcgNxnNgAfzysfwWfQUr+51wigiWHQQRiZNd1Ao0M5Y3M2EGg==} + peerDependencies: + react: '>= 16' + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + dev: false + + /@humanwhocodes/config-array@0.12.3: + resolution: {integrity: sha512-jsNnTBlMWuTpDkeE3on7+dWJi0D6fdDfeANj/w7MpS8ztROCoLvIO2nG0CcFj+E4k8j4QrSTh4Oryi3i2G669g==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.3: + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + dev: true + + /@img/sharp-darwin-arm64@0.33.5: + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.33.5: + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.0.4: + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.0.4: + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.0.4: + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.0.5: + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.0.4: + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.0.4: + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.0.4: + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.0.4: + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-wasm32@0.33.5: + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 1.3.1 + dev: false + optional: true + + /@img/sharp-win32-ia32@0.33.5: + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.33.5: + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@mapbox/node-pre-gyp@1.0.11: + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + dependencies: + detect-libc: 2.0.3 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.6.3 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@next/env@15.0.0-canary.193: + resolution: {integrity: sha512-GBCLGuoPKHF6H/bmtALmKEV/+IsIToVelkM8eZpVDGfWtL03KueC6mUZdhF1trBZenGW3Ly1j0N872koPUcAlw==} + dev: false + + /@next/eslint-plugin-next@14.2.2: + resolution: {integrity: sha512-q+Ec2648JtBpKiu/FSJm8HAsFXlNvioHeBCbTP12T1SGcHYwhqHULSfQgFkPgHDu3kzNp2Kem4J54bK4rPQ5SQ==} + dependencies: + glob: 10.3.10 + dev: true + + /@next/swc-darwin-arm64@15.0.0-canary.193: + resolution: {integrity: sha512-CRq2GfI7r5CcAY1ITTb4FZpK8UTGLrNdYelTuv9zcSe4EhuNb7Qp14XfGGL9LV39ZkP5ypcVHYhkrNbfiL3VuQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-x64@15.0.0-canary.193: + resolution: {integrity: sha512-+0W+NW4JhdcCDwuy8qd/p/zQ7TlfGJ6qSYzamq7nZ+KFWWSJqmBDzTzNfKPxPgdtfHaVyQIN1ThSEJtrah3+dA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-gnu@15.0.0-canary.193: + resolution: {integrity: sha512-5RawIR+D7KPI/trRdKudCWPYu98eF6f2js00tctF8jOUvpGs5M06RKvp+DKzgPLxaZIxAq+YIycS/F9E88LECA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-musl@15.0.0-canary.193: + resolution: {integrity: sha512-IdHsXwzkmyMfOE2Ff0C3qeivgnP00l6t+kzoDymv1ldXd9f03T+XgtUtcTWKnVDEKqyBVuKgZHpAm/0JtRvhWg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-gnu@15.0.0-canary.193: + resolution: {integrity: sha512-sOvYkCYNUiR/nq5bQuCc/zXqx6jqmRhL8+PxcOTmIQ9YdSsd9oT/ENZzJ4Bf0MiKGyLC7YpjE6ybTUl5TjlvJA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-musl@15.0.0-canary.193: + resolution: {integrity: sha512-tHNzv1CRFP7fVNsQWyhvoVhnLIn6W8OqtUPS9k33X7WRYCRp+bGJQjefPV4Ht+mBNN3oM51uMtKn7EJ6wizrjw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-arm64-msvc@15.0.0-canary.193: + resolution: {integrity: sha512-RwXjqOXKMF4oiXbQfcTcRfoYUaTl+3xpK6Phz8BnWTeFn0PNUdDZnvUswq4RTZZEAaCw479R35KcnR8SJh/OWw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-x64-msvc@15.0.0-canary.193: + resolution: {integrity: sha512-Ib3U2QIzdVOxWa4ChBIbjaEJjg2xDgA71g7/kEMwRTXds8EuKRu9HVwErb+23nxiKiRFEKx9GKTGHURHEKvlJw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + + /@rollup/pluginutils@4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: false + + /@rushstack/eslint-patch@1.10.2: + resolution: {integrity: sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==} + dev: true + + /@sinclair/typebox@0.25.24: + resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} + dev: false + + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/helpers@0.5.13: + resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + dependencies: + tslib: 2.5.0 + dev: false + + /@tailwindcss/forms@0.5.7(tailwindcss@3.4.3): + resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} + peerDependencies: + tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' + dependencies: + mini-svg-data-uri: 1.4.4 + tailwindcss: 3.4.3 + dev: true + + /@tailwindcss/typography@0.5.12(tailwindcss@3.4.3): + resolution: {integrity: sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 3.4.3 + dev: true + + /@tootallnate/once@2.0.0: + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + dev: false + + /@ts-morph/common@0.11.1: + resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} + dependencies: + fast-glob: 3.3.2 + minimatch: 3.1.2 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + dev: false + + /@tsconfig/node10@1.0.11: + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + dev: false + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: false + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: false + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: false + + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + dev: false + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + dev: true + + /@types/node@14.18.33: + resolution: {integrity: sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==} + dev: false + + /@types/node@20.12.7: + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + dependencies: + undici-types: 5.26.5 + dev: true + + /@types/prop-types@15.7.5: + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + dev: true + + /@types/react@18.2.79: + resolution: {integrity: sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==} + dependencies: + '@types/prop-types': 15.7.5 + csstype: 3.1.2 + dev: true + + /@types/stylis@4.2.0: + resolution: {integrity: sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==} + dev: false + + /@typescript-eslint/parser@7.2.0(eslint@9.0.0)(typescript@5.4.5): + resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 7.2.0 + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.4 + eslint: 9.0.0 + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@7.2.0: + resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + dev: true + + /@typescript-eslint/types@7.2.0: + resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.5): + resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/visitor-keys@7.2.0: + resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 7.2.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@vercel/build-utils@7.11.0: + resolution: {integrity: sha512-UFrx1hNIjNJJkd0NZrYfaOrmcWhQmrVsbKe9o3L9jX9J1iufG685wIZ9tFCKKC0Fa2HWbNDNzNxrE5SCAS2lyA==} + dev: false + + /@vercel/error-utils@2.0.2: + resolution: {integrity: sha512-Sj0LFafGpYr6pfCqrQ82X6ukRl5qpmVrHM/191kNYFqkkB9YkjlMAj6QcEsvCG259x4QZ7Tya++0AB85NDPbKQ==} + dev: false + + /@vercel/fun@1.1.0: + resolution: {integrity: sha512-SpuPAo+MlAYMtcMcC0plx7Tv4Mp7SQhJJj1iIENlOnABL24kxHpL09XLQMGzZIzIW7upR8c3edwgfpRtp+dhVw==} + engines: {node: '>= 10'} + dependencies: + '@tootallnate/once': 2.0.0 + async-listen: 1.2.0 + debug: 4.1.1 + execa: 3.2.0 + fs-extra: 8.1.0 + generic-pool: 3.4.2 + micro: 9.3.5-canary.3 + ms: 2.1.1 + node-fetch: 2.6.7 + path-match: 1.2.4 + promisepipe: 3.0.0 + semver: 7.3.5 + stat-mode: 0.3.0 + stream-to-promise: 2.2.0 + tar: 4.4.18 + tree-kill: 1.2.2 + uid-promise: 1.0.0 + uuid: 3.3.2 + xdg-app-paths: 5.1.0 + yauzl-promise: 2.1.3 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/gatsby-plugin-vercel-analytics@1.0.11: + resolution: {integrity: sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==} + dependencies: + web-vitals: 0.2.4 + dev: false + + /@vercel/gatsby-plugin-vercel-builder@2.0.24: + resolution: {integrity: sha512-b02ifu8WCmz4ARjkC9AyuOxpXa0Tmh0uIbDDYvyvDRpvohQY53eC3sXKVOejnmQbi9KojkaJsQRvMTBRh9BUHA==} + dependencies: + '@sinclair/typebox': 0.25.24 + '@vercel/build-utils': 7.11.0 + '@vercel/routing-utils': 3.1.0 + esbuild: 0.14.47 + etag: 1.8.1 + fs-extra: 11.1.0 + dev: false + + /@vercel/git-hooks@1.0.0: + resolution: {integrity: sha512-OxDFAAdyiJ/H0b8zR9rFCu3BIb78LekBXOphOYG3snV4ULhKFX387pBPpqZ9HLiRTejBWBxYEahkw79tuIgdAA==} + requiresBuild: true + dev: true + + /@vercel/go@3.1.1: + resolution: {integrity: sha512-mrzomNYltxkjvtUmaYry5YEyvwTz6c/QQHE5Gr/pPGRIniUiP6T6OFOJ49RBN7e6pRXaNzHPVuidiuBhvHh5+Q==} + dev: false + + /@vercel/hydrogen@1.0.2: + resolution: {integrity: sha512-/Q2MKk1GfOuZAnkE9jQexjtUQqanbY65R+xtJWd9yKIgwcfRI1hxiNH3uXyVM5AvLoY+fxxULkSuxDtUKpkJpQ==} + dependencies: + '@vercel/static-config': 3.0.0 + ts-morph: 12.0.0 + dev: false + + /@vercel/next@4.2.0: + resolution: {integrity: sha512-2KSXdPHpfPWaf0tKTBxOWvdc8e9TPNARjmqtgYUsrl1TVaBNFsZ0GV0kWaVLEw4o7CWfREt8ZY064sNVb1BcAQ==} + dependencies: + '@vercel/nft': 0.26.4 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/nft@0.26.4: + resolution: {integrity: sha512-j4jCOOXke2t8cHZCIxu1dzKLHLcFmYzC3yqAK6MfZznOL1QIJKd0xcFsXK3zcqzU7ScsE2zWkiMMNHGMHgp+FA==} + engines: {node: '>=16'} + hasBin: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.11 + '@rollup/pluginutils': 4.2.1 + acorn: 8.11.3 + acorn-import-attributes: 1.9.5(acorn@8.11.3) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + node-gyp-build: 4.8.0 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/node@3.0.26: + resolution: {integrity: sha512-PoyacnoylwpE3+7RFUVHJlbPqtneTCEJVXXx4n8g9ARgUDSRSCwFpJOhiFQon2sS2YtfCzsJa29Z9dAZQedDcQ==} + dependencies: + '@edge-runtime/node-utils': 2.3.0 + '@edge-runtime/primitives': 4.1.0 + '@edge-runtime/vm': 3.2.0 + '@types/node': 14.18.33 + '@vercel/build-utils': 7.11.0 + '@vercel/error-utils': 2.0.2 + '@vercel/nft': 0.26.4 + '@vercel/static-config': 3.0.0 + async-listen: 3.0.0 + cjs-module-lexer: 1.2.3 + edge-runtime: 2.5.9 + es-module-lexer: 1.4.1 + esbuild: 0.14.47 + etag: 1.8.1 + node-fetch: 2.6.9 + path-to-regexp: 6.2.1 + ts-morph: 12.0.0 + ts-node: 10.9.1(@types/node@14.18.33)(typescript@4.9.5) + typescript: 4.9.5 + undici: 5.26.5 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - encoding + - supports-color + dev: false + + /@vercel/python@4.1.1: + resolution: {integrity: sha512-EbAdKOZ0hPd5b59tLt7R3RQK1azNvuZTrCFRAVHNjqcIHNCmrSvjag5zBGn7Memkk8qWb3+CgBw9K/3LJKei0w==} + dev: false + + /@vercel/redwood@2.0.8: + resolution: {integrity: sha512-hAu7SYXDt+W7kscjtQ5NsuNflXH+QB5/xAdA6FRSS/e41lG6Xq6pqLMDobqq4BR7E2PpppVDw2DUx9KzPNoeEw==} + dependencies: + '@vercel/nft': 0.26.4 + '@vercel/routing-utils': 3.1.0 + semver: 6.3.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/remix-builder@2.1.5: + resolution: {integrity: sha512-VaDhsNg/1lZ7h6GJnaykActeZTRtFQz45qDNwKrHM+Nw5/ocwTun9sCJZY/ziECUNuQEJv95z3wUDhNweG+/9w==} + dependencies: + '@vercel/error-utils': 2.0.2 + '@vercel/nft': 0.26.4 + '@vercel/static-config': 3.0.0 + ts-morph: 12.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/routing-utils@3.1.0: + resolution: {integrity: sha512-Ci5xTjVTJY/JLZXpCXpLehMft97i9fH34nu9PGav6DtwkVUF6TOPX86U0W0niQjMZ5n6/ZP0BwcJK2LOozKaGw==} + dependencies: + path-to-regexp: 6.1.0 + optionalDependencies: + ajv: 6.12.6 + dev: false + + /@vercel/ruby@2.0.5: + resolution: {integrity: sha512-Gfm8HDech41vf+EPleRzgoJUnDTJerKgckMm4KX0JT860gV9XBMSOWYH7eMWHmMza104+HRCWL7wT6OlpftF2Q==} + dev: false + + /@vercel/static-build@2.4.6: + resolution: {integrity: sha512-LCmEBXRse7Bt46fo4OUzkq6RL1Q26oMWvmbFsW5uKi6bkT8asU1U5/zw9PQTeFQjGRL2vkUi22fGXF6XHuuqsA==} + dependencies: + '@vercel/gatsby-plugin-vercel-analytics': 1.0.11 + '@vercel/gatsby-plugin-vercel-builder': 2.0.24 + '@vercel/static-config': 3.0.0 + ts-morph: 12.0.0 + dev: false + + /@vercel/static-config@3.0.0: + resolution: {integrity: sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw==} + dependencies: + ajv: 8.6.3 + json-schema-to-ts: 1.6.4 + ts-morph: 12.0.0 + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: false + + /acorn-import-attributes@1.9.5(acorn@8.11.3): + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: false + + /acorn-jsx@5.3.2(acorn@8.11.3): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.3 + dev: true + + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + dev: false + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + /ajv@8.6.3: + resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: false + + /ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + /aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: false + + /are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + dev: false + + /arg@4.1.0: + resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} + dev: false + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: false + + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + dependencies: + dequal: 2.0.3 + dev: true + + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + dev: true + + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.tosorted@1.1.3: + resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + dev: true + + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + dev: true + + /ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + dev: true + + /async-listen@1.2.0: + resolution: {integrity: sha512-CcEtRh/oc9Jc4uWeUwdpG/+Mb2YUHKmdaTf0gUr7Wa+bfp4xx70HOb3RuSTJMvqKNB1TkdTfjLdrcz2X4rkkZA==} + dev: false + + /async-listen@3.0.0: + resolution: {integrity: sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==} + engines: {node: '>= 14'} + dev: false + + /async-listen@3.0.1: + resolution: {integrity: sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==} + engines: {node: '>= 14'} + dev: false + + /async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + dev: false + + /autoprefixer@10.4.19(postcss@8.4.38): + resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.23.0 + caniuse-lite: 1.0.30001611 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + dev: true + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 + dev: true + + /axe-core@4.7.0: + resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + engines: {node: '>=4'} + dev: true + + /axobject-query@3.2.1: + resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + dependencies: + dequal: 2.0.3 + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001611 + electron-to-chromium: 1.4.740 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.23.0) + dev: true + + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: false + + /busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: false + + /bytes@3.1.0: + resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} + engines: {node: '>= 0.8'} + dev: false + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: true + + /camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + dev: false + + /caniuse-lite@1.0.30001611: + resolution: {integrity: sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==} + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + + /chokidar@3.3.1: + resolution: {integrity: sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.3.0 + optionalDependencies: + fsevents: 2.1.3 + dev: false + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: false + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: false + + /cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + dev: false + + /cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: true + + /cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + dependencies: + slice-ansi: 5.0.0 + string-width: 7.1.0 + dev: true + + /client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false + + /clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + dev: false + + /code-block-writer@10.1.1: + resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==} + dev: false + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false + optional: true + + /color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: false + + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: false + optional: true + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + dev: true + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: false + + /content-type@1.0.4: + resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} + engines: {node: '>= 0.6'} + dev: false + + /convert-hrtime@3.0.0: + resolution: {integrity: sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==} + engines: {node: '>=8'} + dev: false + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + /css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + dev: false + + /css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + dev: false + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + + /damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + + /data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + dev: false + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /debug@4.1.1: + resolution: {integrity: sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==} + deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dev: true + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: false + + /depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + dev: false + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + dev: false + + /didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: false + + /dinero.js@2.0.0-alpha.10: + resolution: {integrity: sha512-EDiOZanmJBJnFfiz5cUL/I2UI7EXQ0jXf18srqgO7sQhChyBbN39b5sf6T4fq4Oj3f4/6x2L96YPUbMRcUmd/A==} + dependencies: + '@dinero.js/calculator-number': 2.0.0-alpha.10 + '@dinero.js/core': 2.0.0-alpha.10 + '@dinero.js/currencies': 2.0.0-alpha.10 + dev: false + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /edge-runtime@2.5.9: + resolution: {integrity: sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==} + engines: {node: '>=16'} + hasBin: true + dependencies: + '@edge-runtime/format': 2.2.1 + '@edge-runtime/ponyfill': 2.4.2 + '@edge-runtime/vm': 3.2.0 + async-listen: 3.0.1 + mri: 1.2.0 + picocolors: 1.0.0 + pretty-ms: 7.0.1 + signal-exit: 4.0.2 + time-span: 4.0.0 + dev: false + + /electron-to-chromium@1.4.740: + resolution: {integrity: sha512-Yvg5i+iyv7Xm18BRdVPVm8lc7kgxM3r6iwqCH2zB7QZy1kZRNmd0Zqm0zcD9XoFREE5/5rwIuIAOT+/mzGcnZg==} + dev: true + + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /end-of-stream@1.1.0: + resolution: {integrity: sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==} + dependencies: + once: 1.3.3 + dev: false + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: false + + /enhanced-resolve@5.16.0: + resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + + /es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + + /es-iterator-helpers@1.0.18: + resolution: {integrity: sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + globalthis: 1.0.3 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + iterator.prototype: 1.1.2 + safe-array-concat: 1.1.2 + dev: true + + /es-module-lexer@1.4.1: + resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + dev: false + + /es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: true + + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.2 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild-android-64@0.14.47: + resolution: {integrity: sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-android-arm64@0.14.47: + resolution: {integrity: sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-64@0.14.47: + resolution: {integrity: sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-arm64@0.14.47: + resolution: {integrity: sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-64@0.14.47: + resolution: {integrity: sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-arm64@0.14.47: + resolution: {integrity: sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-32@0.14.47: + resolution: {integrity: sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-64@0.14.47: + resolution: {integrity: sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm64@0.14.47: + resolution: {integrity: sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm@0.14.47: + resolution: {integrity: sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-mips64le@0.14.47: + resolution: {integrity: sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-ppc64le@0.14.47: + resolution: {integrity: sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-riscv64@0.14.47: + resolution: {integrity: sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-s390x@0.14.47: + resolution: {integrity: sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-netbsd-64@0.14.47: + resolution: {integrity: sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-openbsd-64@0.14.47: + resolution: {integrity: sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-sunos-64@0.14.47: + resolution: {integrity: sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-32@0.14.47: + resolution: {integrity: sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-64@0.14.47: + resolution: {integrity: sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-arm64@0.14.47: + resolution: {integrity: sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild@0.14.47: + resolution: {integrity: sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.47 + esbuild-android-arm64: 0.14.47 + esbuild-darwin-64: 0.14.47 + esbuild-darwin-arm64: 0.14.47 + esbuild-freebsd-64: 0.14.47 + esbuild-freebsd-arm64: 0.14.47 + esbuild-linux-32: 0.14.47 + esbuild-linux-64: 0.14.47 + esbuild-linux-arm: 0.14.47 + esbuild-linux-arm64: 0.14.47 + esbuild-linux-mips64le: 0.14.47 + esbuild-linux-ppc64le: 0.14.47 + esbuild-linux-riscv64: 0.14.47 + esbuild-linux-s390x: 0.14.47 + esbuild-netbsd-64: 0.14.47 + esbuild-openbsd-64: 0.14.47 + esbuild-sunos-64: 0.14.47 + esbuild-windows-32: 0.14.47 + esbuild-windows-64: 0.14.47 + esbuild-windows-arm64: 0.14.47 + dev: false + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-next@14.2.2(eslint@9.0.0)(typescript@5.4.5): + resolution: {integrity: sha512-12/uFc0KX+wUs7EDpOUGKMXBXZJiBVGdK5/m/QgXOCg2mQ0bQWoKSWNrCeOg7Vum6Kw1d1TW453W6xh+GbHquw==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@next/eslint-plugin-next': 14.2.2 + '@rushstack/eslint-patch': 1.10.2 + '@typescript-eslint/parser': 7.2.0(eslint@9.0.0)(typescript@5.4.5) + eslint: 9.0.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@9.0.0) + eslint-plugin-react: 7.34.1(eslint@9.0.0) + eslint-plugin-react-hooks: 4.6.0(eslint@9.0.0) + typescript: 5.4.5 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0): + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + dependencies: + debug: 4.3.4 + enhanced-resolve: 5.16.0 + eslint: 9.0.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.3 + is-core-module: 2.13.1 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 7.2.0(eslint@9.0.0)(typescript@5.4.5) + debug: 3.2.7 + eslint: 9.0.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0) + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 7.2.0(eslint@9.0.0)(typescript@5.4.5) + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.0.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jsx-a11y@6.8.0(eslint@9.0.0): + resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + '@babel/runtime': 7.24.4 + aria-query: 5.3.0 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + ast-types-flow: 0.0.8 + axe-core: 4.7.0 + axobject-query: 3.2.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + es-iterator-helpers: 1.0.18 + eslint: 9.0.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + dev: true + + /eslint-plugin-react-hooks@4.6.0(eslint@9.0.0): + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 9.0.0 + dev: true + + /eslint-plugin-react@7.34.1(eslint@9.0.0): + resolution: {integrity: sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.2 + array.prototype.toreversed: 1.1.2 + array.prototype.tosorted: 1.1.3 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.18 + eslint: 9.0.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.hasown: 1.1.4 + object.values: 1.2.0 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.11 + dev: true + + /eslint-scope@8.0.1: + resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /eslint@9.0.0: + resolution: {integrity: sha512-IMryZ5SudxzQvuod6rUdIUz29qFItWx281VhtFVc2Psy/ZhlCeD/5DT6lBIJ4H3G+iamGJoTln1v+QSuPw0p7Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.0.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 3.0.2 + '@eslint/js': 9.0.0 + '@humanwhocodes/config-array': 0.12.3 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + escape-string-regexp: 4.0.0 + eslint-scope: 8.0.1 + eslint-visitor-keys: 4.0.0 + espree: 10.0.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@10.0.1: + resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 4.0.0 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: false + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: false + + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: true + + /events-intercept@2.0.0: + resolution: {integrity: sha512-blk1va0zol9QOrdZt0rFXo5KMkNPVSp92Eju/Qz8THwKWKRKeE0T8Br/1aW6+Edkyq9xHYgYxn2QtOnUKPUp+Q==} + dev: false + + /execa@3.2.0: + resolution: {integrity: sha512-kJJfVbI/lZE1PZYDI5VPxp8zXPO9rtxOkhpZ0jMKha56AI9y2gGVC6bkukStQf0ka5Rh15BA5m7cCCH4jmHqkw==} + engines: {node: ^8.12.0 || >=9.7.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + p-finally: 2.0.1 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: false + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + dependencies: + reusify: 1.0.4 + + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: false + + /file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + dependencies: + flat-cache: 4.0.1 + dev: true + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + dev: true + + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + dev: true + + /fs-extra@11.1.0: + resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: false + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: false + + /fs-minipass@1.2.7: + resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} + dependencies: + minipass: 2.9.0 + dev: false + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: false + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: false + + /fsevents@2.1.3: + resolution: {integrity: sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + deprecated: '"Please update to latest v2.3 or v2.2"' + requiresBuild: true + dev: false + optional: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + + /generic-pool@3.4.2: + resolution: {integrity: sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag==} + engines: {node: '>= 4'} + dev: false + + /get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + dev: true + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + dev: true + + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: false + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + dev: true + + /get-tsconfig@4.7.3: + resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + dev: true + + /glob@10.3.12: + resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: false + + /globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + dev: true + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: false + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /http-errors@1.4.0: + resolution: {integrity: sha512-oLjPqve1tuOl5aRhv8GK5eHpqP1C9fb+Ol+XTLjKfLltE44zdDbEdjPSbU7Ch5rSNsVFqZn97SrMmZLdu1/YMw==} + engines: {node: '>= 0.6'} + dependencies: + inherits: 2.0.1 + statuses: 1.5.0 + dev: false + + /http-errors@1.7.3: + resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} + engines: {node: '>= 0.6'} + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.1.1 + statuses: 1.5.0 + toidentifier: 1.0.0 + dev: false + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + dev: false + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: false + + /inherits@2.0.1: + resolution: {integrity: sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==} + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + dev: true + + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: false + optional: true + + /is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.2 + dev: true + + /is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + dependencies: + is-typed-array: 1.1.13 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + + /is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + dependencies: + get-east-asian-width: 1.2.0 + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + dev: true + + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + dev: true + + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.15 + dev: true + + /is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: false + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 + dev: true + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-schema-to-ts@1.6.4: + resolution: {integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==} + dependencies: + '@types/json-schema': 7.0.15 + ts-toolbelt: 6.15.5 + dev: false + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: false + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + dev: true + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /language-subtag-registry@0.3.22: + resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + dev: true + + /language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + dependencies: + language-subtag-registry: 0.3.22 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + dev: true + + /lilconfig@3.1.1: + resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} + engines: {node: '>=14'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /lint-staged@15.2.2: + resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==} + engines: {node: '>=18.12.0'} + hasBin: true + dependencies: + chalk: 5.3.0 + commander: 11.1.0 + debug: 4.3.4 + execa: 8.0.1 + lilconfig: 3.0.0 + listr2: 8.0.1 + micromatch: 4.0.5 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /listr2@8.0.1: + resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} + engines: {node: '>=18.0.0'} + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.0.0 + rfdc: 1.3.1 + wrap-ansi: 9.0.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.castarray@4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} + dependencies: + ansi-escapes: 6.2.1 + cli-cursor: 4.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + dev: true + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.1 + dev: false + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: false + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + /micro@9.3.5-canary.3: + resolution: {integrity: sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==} + engines: {node: '>= 8.0.0'} + hasBin: true + dependencies: + arg: 4.1.0 + content-type: 1.0.4 + raw-body: 2.4.1 + dev: false + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /mini-svg-data-uri@1.4.4: + resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + hasBin: true + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + /minipass@2.9.0: + resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} + dependencies: + safe-buffer: 5.2.1 + yallist: 3.1.1 + dev: false + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: false + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: false + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /minizlib@1.3.3: + resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} + dependencies: + minipass: 2.9.0 + dev: false + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: false + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: false + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: false + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: false + + /ms@2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + dev: false + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /ms@3.0.0-canary.1: + resolution: {integrity: sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==} + engines: {node: '>=12.13'} + dev: false + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /next@15.0.0-canary.193(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-X17zCn32Tl2lpnYoNFcGlTAkDGAyXGNpnsu6HJec/vrTA5ogi+TArSgorGQdXnKCAR+GnwSn/Um3S46VUvcCxw==} + engines: {node: '>=18.18.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-cd22717c-20241013 + react-dom: ^18.2.0 || 19.0.0-rc-cd22717c-20241013 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + dependencies: + '@next/env': 15.0.0-canary.193 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.13 + busboy: 1.6.0 + caniuse-lite: 1.0.30001611 + postcss: 8.4.31 + react: 19.0.0-rc-cd22717c-20241013 + react-dom: 19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013) + styled-jsx: 5.1.6(react@19.0.0-rc-cd22717c-20241013) + optionalDependencies: + '@next/swc-darwin-arm64': 15.0.0-canary.193 + '@next/swc-darwin-x64': 15.0.0-canary.193 + '@next/swc-linux-arm64-gnu': 15.0.0-canary.193 + '@next/swc-linux-arm64-musl': 15.0.0-canary.193 + '@next/swc-linux-x64-gnu': 15.0.0-canary.193 + '@next/swc-linux-x64-musl': 15.0.0-canary.193 + '@next/swc-win32-arm64-msvc': 15.0.0-canary.193 + '@next/swc-win32-x64-msvc': 15.0.0-canary.193 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + + /node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-fetch@2.6.9: + resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp-build@4.8.0: + resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} + hasBin: true + dev: false + + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + + /nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: false + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + /normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: false + + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + + /npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: false + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + dev: true + + /object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /once@1.3.3: + resolution: {integrity: sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /os-paths@4.4.0: + resolution: {integrity: sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==} + engines: {node: '>= 6.0'} + dev: false + + /p-finally@2.0.1: + resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} + engines: {node: '>=8'} + dev: false + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-ms@2.1.0: + resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} + engines: {node: '>=6'} + dev: false + + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: false + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: false + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-match@1.2.4: + resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==} + dependencies: + http-errors: 1.4.0 + path-to-regexp: 1.8.0 + dev: false + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + dev: true + + /path-to-regexp@1.8.0: + resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + dependencies: + isarray: 0.0.1 + dev: false + + /path-to-regexp@6.1.0: + resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==} + dev: false + + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: false + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: false + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-import@15.1.0(postcss@8.4.38): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + dev: true + + /postcss-js@4.0.1(postcss@8.4.38): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.38 + dev: true + + /postcss-load-config@4.0.2(postcss@8.4.38): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 3.1.1 + postcss: 8.4.38 + yaml: 2.4.1 + dev: true + + /postcss-nested@6.0.1(postcss@8.4.38): + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.38 + postcss-selector-parser: 6.0.16 + dev: true + + /postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-selector-parser@6.0.16: + resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: false + + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier-plugin-tailwindcss@0.5.14(prettier@3.2.5): + resolution: {integrity: sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig-melody': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig-melody': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + dependencies: + prettier: 3.2.5 + dev: true + + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /pretty-ms@7.0.1: + resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} + engines: {node: '>=10'} + dependencies: + parse-ms: 2.1.0 + dev: false + + /promisepipe@3.0.0: + resolution: {integrity: sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==} + dev: false + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: false + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + /raw-body@2.4.1: + resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.0 + http-errors: 1.7.3 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + + /react-dom@19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-NzjTBOXygonUxLRQuUUW5V2QLGkAcyUwJoS8+UWxs089paMvQQfoRD51w65Ovgd2OEQ8Rm3HWx+82fvXiT0czQ==} + peerDependencies: + react: 19.0.0-rc-cd22717c-20241013 + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + scheduler: 0.25.0-rc-cd22717c-20241013 + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react@19.0.0-rc-cd22717c-20241013: + resolution: {integrity: sha512-k28GszmyQ1tX/JmeLGZINq5KXiNy/MmN0fCAtcwF8a9INDyVYG0zATCRGJwaPB9WixmkuwPv1BfB1QBfJC7cNg==} + engines: {node: '>=0.10.0'} + dev: false + + /read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /readdirp@3.3.0: + resolution: {integrity: sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: false + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.3 + which-builtin-type: 1.1.3 + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: true + + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: false + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + /rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: false + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + + /safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + + /scheduler@0.25.0-rc-cd22717c-20241013: + resolution: {integrity: sha512-MnsFR57bKcrYslnbCUsaUG0qBuAArk92VxE0zu6A2Usz38iIuL2uZLunqKlP1W47MF33GrRGDj1sXdPbFKIZfw==} + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + /semver@7.3.5: + resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + dev: false + + /server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + dev: false + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + dev: true + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + dev: true + + /setprototypeof@1.1.1: + resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} + dev: false + + /shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + dev: false + + /sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + dev: false + optional: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + /signal-exit@4.0.2: + resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} + engines: {node: '>=14'} + dev: false + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + dependencies: + is-arrayish: 0.3.2 + dev: false + optional: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + + /slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + dev: true + + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + /stat-mode@0.3.0: + resolution: {integrity: sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==} + dev: false + + /statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + dev: false + + /stream-to-array@2.3.0: + resolution: {integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==} + dependencies: + any-promise: 1.3.0 + dev: false + + /stream-to-promise@2.2.0: + resolution: {integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==} + dependencies: + any-promise: 1.3.0 + end-of-stream: 1.1.0 + stream-to-array: 2.3.0 + dev: false + + /streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: false + + /string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + dev: true + + /string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 + dev: true + + /string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: false + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /styled-components@6.1.8(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==} + engines: {node: '>= 16'} + peerDependencies: + react: '>= 16.8.0' + react-dom: '>= 16.8.0' + dependencies: + '@emotion/is-prop-valid': 1.2.1 + '@emotion/unitless': 0.8.0 + '@types/stylis': 4.2.0 + css-to-react-native: 3.2.0 + csstype: 3.1.2 + postcss: 8.4.31 + react: 19.0.0-rc-cd22717c-20241013 + react-dom: 19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013) + shallowequal: 1.1.0 + stylis: 4.3.1 + tslib: 2.5.0 + dev: false + + /styled-jsx@5.1.6(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + client-only: 0.0.1 + react: 19.0.0-rc-cd22717c-20241013 + dev: false + + /stylis@4.3.1: + resolution: {integrity: sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==} + dev: false + + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.3.12 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /tailwindcss@3.4.3: + resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.0 + lilconfig: 2.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.38 + postcss-import: 15.1.0(postcss@8.4.38) + postcss-js: 4.0.1(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-nested: 6.0.1(postcss@8.4.38) + postcss-selector-parser: 6.0.16 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + dev: true + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + + /tar@4.4.18: + resolution: {integrity: sha512-ZuOtqqmkV9RE1+4odd+MhBpibmCxNP6PJhH/h2OqNuotTX7/XHPZQJv2pKvWMplFH9SIZZhitehh6vBH6LO8Pg==} + engines: {node: '>=4.5'} + dependencies: + chownr: 1.1.4 + fs-minipass: 1.2.7 + minipass: 2.9.0 + minizlib: 1.3.3 + mkdirp: 0.5.6 + safe-buffer: 5.2.1 + yallist: 3.1.1 + dev: false + + /tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: false + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /time-span@4.0.0: + resolution: {integrity: sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==} + engines: {node: '>=10'} + dependencies: + convert-hrtime: 3.0.0 + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /toidentifier@1.0.0: + resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} + engines: {node: '>=0.6'} + dev: false + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: false + + /ts-api-utils@1.3.0(typescript@5.4.5): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.4.5 + dev: true + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + + /ts-morph@12.0.0: + resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} + dependencies: + '@ts-morph/common': 0.11.1 + code-block-writer: 10.1.1 + dev: false + + /ts-node@10.9.1(@types/node@14.18.33)(typescript@4.9.5): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 14.18.33 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + + /ts-toolbelt@6.15.5: + resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} + dev: false + + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + dev: false + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + dev: true + + /types-react-dom@19.0.0-rc.1: + resolution: {integrity: sha512-VSLZJl8VXCD0fAWp7DUTFUDCcZ8DVXOQmjhJMD03odgeFmu14ZQJHCXeETm3BEAhJqfgJaFkLnGkQv88sRx0fQ==} + dependencies: + '@types/react': 18.2.79 + dev: true + + /types-react@19.0.0-rc.1: + resolution: {integrity: sha512-RshndUfqTW6K3STLPis8BtAYCGOkMbtvYsi90gmVNDZBXUyUc5juf2PE9LfS/JmOlUIRO8cWTS/1MTnmhjDqyQ==} + dependencies: + csstype: 3.1.2 + dev: true + + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: false + + /typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /uid-promise@1.0.0: + resolution: {integrity: sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==} + dev: false + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /undici@5.26.5: + resolution: {integrity: sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==} + engines: {node: '>=14.0'} + dependencies: + '@fastify/busboy': 2.1.1 + dev: false + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: false + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: false + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: false + + /update-browserslist-db@1.0.13(browserslist@4.23.0): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.2 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + + /use-count-up@3.0.1(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-jlVsXJYje6jh+xwQaCEYrwHoB+nRyillNEmr21bhe9kw7tpRzyrSq9jQs9UOlo+8hCFkuOmjUihL3IjEK/piVg==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + use-elapsed-time: 3.0.2(react@19.0.0-rc-cd22717c-20241013) + dev: false + + /use-elapsed-time@3.0.2(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-2EY9lJ5DWbAvT8wWiEp6Ztnl46DjXz2j78uhWbXaz/bg3OfpbgVucCAlcN8Bih6hTJfFTdVYX9L6ySMn5py/wQ==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + /uuid@3.3.2: + resolution: {integrity: sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: false + + /vercel@34.0.0: + resolution: {integrity: sha512-0Gewf/gB/UDnkGA/wyAzf3wxXuDqCvPFKFkAcByV3PuoCF5j71MqjV3GpFC0rQREF7CZZflFMhoaQO70a9x/fA==} + engines: {node: '>= 16'} + hasBin: true + dependencies: + '@vercel/build-utils': 7.11.0 + '@vercel/fun': 1.1.0 + '@vercel/go': 3.1.1 + '@vercel/hydrogen': 1.0.2 + '@vercel/next': 4.2.0 + '@vercel/node': 3.0.26 + '@vercel/python': 4.1.1 + '@vercel/redwood': 2.0.8 + '@vercel/remix-builder': 2.1.5 + '@vercel/ruby': 2.0.5 + '@vercel/static-build': 2.4.6 + chokidar: 3.3.1 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - encoding + - supports-color + dev: false + + /web-vitals@0.2.4: + resolution: {integrity: sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + dev: true + + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: false + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + + /wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + string-width: 7.1.0 + strip-ansi: 7.1.0 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: false + + /xdg-app-paths@5.1.0: + resolution: {integrity: sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==} + engines: {node: '>=6'} + dependencies: + xdg-portable: 7.3.0 + dev: false + + /xdg-portable@7.3.0: + resolution: {integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==} + engines: {node: '>= 6.0'} + dependencies: + os-paths: 4.4.0 + dev: false + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + engines: {node: '>= 14'} + dev: true + + /yaml@2.4.1: + resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} + engines: {node: '>= 14'} + hasBin: true + dev: true + + /yauzl-clone@1.0.4: + resolution: {integrity: sha512-igM2RRCf3k8TvZoxR2oguuw4z1xasOnA31joCqHIyLkeWrvAc2Jgay5ISQ2ZplinkoGaJ6orCz56Ey456c5ESA==} + engines: {node: '>=6'} + dependencies: + events-intercept: 2.0.0 + dev: false + + /yauzl-promise@2.1.3: + resolution: {integrity: sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA==} + engines: {node: '>=6'} + dependencies: + yauzl: 2.10.0 + yauzl-clone: 1.0.4 + dev: false + + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: false + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: false + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/apps/next-app-router/next-app-router-4000/postcss.config.js b/apps/next-app-router/next-app-router-4000/postcss.config.js new file mode 100644 index 00000000000..12a703d900d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/apps/next-app-router/next-app-router-4000/prettier.config.js b/apps/next-app-router/next-app-router-4000/prettier.config.js new file mode 100644 index 00000000000..4a079f6109c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/prettier.config.js @@ -0,0 +1,9 @@ +module.exports = { + arrowParens: 'always', + semi: true, + trailingComma: 'all', + singleQuote: true, + // pnpm doesn't support plugin autoloading + // https://github.com/tailwindlabs/prettier-plugin-tailwindcss#installation + // plugins: ['prettier-plugin-tailwindcss'], +}; diff --git a/apps/next-app-router/next-app-router-4000/project.json b/apps/next-app-router/next-app-router-4000/project.json new file mode 100644 index 00000000000..63f23344afd --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/project.json @@ -0,0 +1,84 @@ +{ + "name": "next-app-router-4000", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/next-app-router-4000", + "projectType": "application", + "tags": [], + "targets": { + "build": { + "executor": "@nx/next:build", + "defaultConfiguration": "production", + "options": { + "outputPath": "apps/next-app-router-4000" + }, + "configurations": { + "development": { + "outputPath": "apps/next-app-router-4000" + }, + "production": {} + }, + "dependsOn": [ + { + "target": "build", + "dependencies": true + } + ] + }, + "serve": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm dev", + "cwd": "apps/next-app-router-4000" + }, + "dependsOn": [ + { + "target": "build", + "dependencies": true + } + ] + }, + "export": { + "executor": "@nx/next:export", + "options": { + "buildTarget": "next-app-router-4000:build:production" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/next-app-router-4000/**/*.{ts,tsx,js,jsx}"] + } + }, + "e2e": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/next-app-router-4000/cypress.config.ts", + "testingType": "e2e", + "baseUrl": "http://localhost:4000", + "key": "27e40c91-5ac3-4433-8a87-651d10f51cf6" + }, + "configurations": { + "production": { + "devServerTarget": "next-app-router-4000:serve:production" + } + } + }, + "test:e2e": { + "executor": "nx:run-commands", + "options": { + "parallel": true, + "commands": [ + { + "command": "lsof -i :4000 || nx run next-app-router-4000:serve", + "forwardAllArgs": false + }, + { + "command": "sleep 4 && nx run next-app-router-4000:e2e", + "forwardAllArgs": true + } + ] + } + } + } +} diff --git a/apps/next-app-router/next-app-router-4000/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg b/apps/next-app-router/next-app-router-4000/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg new file mode 100644 index 00000000000..9d5daa0f5bd Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4000/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg b/apps/next-app-router/next-app-router-4000/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg new file mode 100644 index 00000000000..40f4ffd5c7f Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4000/public/grid.svg b/apps/next-app-router/next-app-router-4000/public/grid.svg new file mode 100644 index 00000000000..d467ad6de0d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/public/grid.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/next-app-router/next-app-router-4000/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg b/apps/next-app-router/next-app-router-4000/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg new file mode 100644 index 00000000000..527bbb514fc Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4000/public/nextjs-icon-light-background.png b/apps/next-app-router/next-app-router-4000/public/nextjs-icon-light-background.png new file mode 100644 index 00000000000..659139c1819 Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/public/nextjs-icon-light-background.png differ diff --git a/apps/next-app-router/next-app-router-4000/public/patrick-OIFgeLnjwrM-unsplash.jpg b/apps/next-app-router/next-app-router-4000/public/patrick-OIFgeLnjwrM-unsplash.jpg new file mode 100644 index 00000000000..e19a4a1bf82 Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/public/patrick-OIFgeLnjwrM-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4000/public/prince-akachi-LWkFHEGpleE-unsplash.jpg b/apps/next-app-router/next-app-router-4000/public/prince-akachi-LWkFHEGpleE-unsplash.jpg new file mode 100644 index 00000000000..146a680434d Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/public/prince-akachi-LWkFHEGpleE-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4000/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg b/apps/next-app-router/next-app-router-4000/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg new file mode 100644 index 00000000000..ca2d17463c5 Binary files /dev/null and b/apps/next-app-router/next-app-router-4000/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4000/readme.md b/apps/next-app-router/next-app-router-4000/readme.md new file mode 100644 index 00000000000..c6db1f9845e --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/readme.md @@ -0,0 +1,28 @@ +# Next.js App Router Playground + +Next.js recently introduced the App Router with support for: + +- **Layouts:** Easily share UI while preserving state and avoiding re-renders. +- **Server Components:** Making server-first the default for the most dynamic applications. +- **Streaming:** Display instant loading states and stream in updates. +- **Suspense for Data Fetching:** `async`/`await` support and the `use` hook for component-level fetching. + +The App Router can coexist with the existing `pages` directory for incremental adoption. While you **don't need to use the App Router** when upgrading to Next.js 13, we're laying the foundations to build complex interfaces while shipping less JavaScript. + +## Running Locally + +1. Install dependencies: + +```sh +pnpm install +``` + +2. Start the dev server: + +```sh +pnpm dev +``` + +## Documentation + +https://nextjs.org/docs diff --git a/apps/next-app-router/next-app-router-4000/styles/globals.css b/apps/next-app-router/next-app-router-4000/styles/globals.css new file mode 100644 index 00000000000..b5c61c95671 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/styles/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/apps/next-app-router/next-app-router-4000/tailwind.config.ts b/apps/next-app-router/next-app-router-4000/tailwind.config.ts new file mode 100644 index 00000000000..1dc84971594 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/tailwind.config.ts @@ -0,0 +1,90 @@ +import colors from 'tailwindcss/colors'; +import { Config } from 'tailwindcss'; + +export default { + content: [ + './app/**/*.{js,ts,jsx,tsx,mdx}', + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './ui/**/*.{js,ts,jsx,tsx,mdx}', + ], + future: { + hoverOnlyWhenSupported: true, + }, + darkMode: 'class', + theme: { + extend: { + // https://vercel.com/design/color + colors: { + gray: colors.zinc, + 'gray-1000': 'rgb(17,17,19)', + 'gray-1100': 'rgb(10,10,11)', + vercel: { + pink: '#FF0080', + blue: '#0070F3', + cyan: '#50E3C2', + orange: '#F5A623', + violet: '#7928CA', + }, + }, + backgroundImage: ({ theme }) => ({ + 'vc-border-gradient': `radial-gradient(at left top, ${theme( + 'colors.gray.500', + )}, 50px, ${theme('colors.gray.800')} 50%)`, + }), + keyframes: ({ theme }) => ({ + rerender: { + '0%': { + ['border-color']: theme('colors.vercel.pink'), + }, + '40%': { + ['border-color']: theme('colors.vercel.pink'), + }, + }, + highlight: { + '0%': { + background: theme('colors.vercel.pink'), + color: theme('colors.white'), + }, + '40%': { + background: theme('colors.vercel.pink'), + color: theme('colors.white'), + }, + }, + loading: { + '0%': { + opacity: '.2', + }, + '20%': { + opacity: '1', + transform: 'translateX(1px)', + }, + to: { + opacity: '.2', + }, + }, + shimmer: { + '100%': { + transform: 'translateX(100%)', + }, + }, + translateXReset: { + '100%': { + transform: 'translateX(0)', + }, + }, + fadeToTransparent: { + '0%': { + opacity: '1', + }, + '40%': { + opacity: '1', + }, + '100%': { + opacity: '0', + }, + }, + }), + }, + }, + plugins: [require('@tailwindcss/typography'), require('@tailwindcss/forms')], +} satisfies Config; diff --git a/apps/next-app-router/next-app-router-4000/tsconfig.json b/apps/next-app-router/next-app-router-4000/tsconfig.json new file mode 100644 index 00000000000..399d25eda35 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "baseUrl": ".", + "paths": { + "#/*": ["./*"] + }, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/apps/next-app-router/next-app-router-4000/ui/address-bar.tsx b/apps/next-app-router/next-app-router-4000/ui/address-bar.tsx new file mode 100644 index 00000000000..03ce8f4d941 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/address-bar.tsx @@ -0,0 +1,92 @@ +'use client'; + +import React, { Suspense } from 'react'; +import { usePathname, useSearchParams } from 'next/navigation'; + +function Params() { + const searchParams = useSearchParams()!; + + return searchParams.toString().length !== 0 ? ( +
+ ? + {Array.from(searchParams.entries()).map(([key, value], index) => { + return ( + + {index !== 0 ? & : null} + + + {key} + + = + + {value} + + + + ); + })} +
+ ) : null; +} + +export function AddressBar() { + const pathname = usePathname(); + + return ( +
+
+ + + +
+
+
+ acme.com +
+ {pathname ? ( + <> + / + {pathname + .split('/') + .slice(2) + .map((segment) => { + return ( + + + + {segment} + + + + / + + ); + })} + + ) : null} + + + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/boundary.tsx b/apps/next-app-router/next-app-router-4000/ui/boundary.tsx new file mode 100644 index 00000000000..fbc18226ac3 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/boundary.tsx @@ -0,0 +1,82 @@ +import clsx from 'clsx'; +import React from 'react'; + +const Label = ({ + children, + animateRerendering, + color, +}: { + children: React.ReactNode; + animateRerendering?: boolean; + color?: 'default' | 'pink' | 'blue' | 'violet' | 'cyan' | 'orange'; +}) => { + return ( +
+ {children} +
+ ); +}; +export const Boundary = ({ + children, + labels = ['children'], + size = 'default', + color = 'default', + animateRerendering = true, +}: { + children: React.ReactNode; + labels?: string[]; + size?: 'small' | 'default'; + color?: 'default' | 'pink' | 'blue' | 'violet' | 'cyan' | 'orange'; + animateRerendering?: boolean; +}) => { + return ( +
+
+ {labels.map((label) => { + return ( + + ); + })} +
+ + {children} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/buggy-button.tsx b/apps/next-app-router/next-app-router-4000/ui/buggy-button.tsx new file mode 100644 index 00000000000..3a0906605d6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/buggy-button.tsx @@ -0,0 +1,23 @@ +'use client'; + +import Button from 'remote_4001/Button'; +import React from 'react'; + +export default function BuggyButton() { + const [clicked, setClicked] = React.useState(false); + + if (clicked) { + throw new Error('Oh no! Something went wrong.'); + } + + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/button.tsx b/apps/next-app-router/next-app-router-4000/ui/button.tsx new file mode 100644 index 00000000000..8aafa7e7a92 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/button.tsx @@ -0,0 +1,20 @@ +import clsx from 'clsx'; + +export default function Button({ + kind = 'default', + ...props +}: React.ButtonHTMLAttributes & { + kind?: 'default' | 'error'; +}) { + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/component-tree.tsx b/apps/next-app-router/next-app-router-4000/ui/component-tree.tsx new file mode 100644 index 00000000000..3f3e43ee353 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/component-tree.tsx @@ -0,0 +1,162 @@ +import { Boundary } from '#/ui/boundary'; +import CountUp from '#/ui/count-up'; +import clsx from 'clsx'; + +type Item = { + name: string; + type: 'server' | 'client'; + size: number; + children?: Item[]; +}; + +const List = ({ items, depth }: { items: Item[]; depth: number }) => { + return ( +
+ {items.map((item, i) => { + const isLast = i === items.length - 1; + + return ( +
+
+
+ {'<'} + {item.name} + {'>'} +
+ +
+ + {item.type === 'client' ? ( + item.size / 1000 + ) : ( + + )} + {' '} + KB +
+
+ + {item.children ? ( + + ) : null} +
+ ); + })} +
+ ); +}; + +// Calculate the total bundle size of a specific component type (client or +// server) in a tree +const sum = (items: Item[], componentType: Item['type']): number => + items.reduce( + (total, item) => + // running total + total + + // add the current component size if it's type is componentType + ((item.type === componentType ? item.size : 0) || 0) + + // add the total size of children components recursively + (item?.children ? sum(item.children, componentType) : 0), + 0, + ); + +export const ComponentTree = ({ items }: { items: Item[] }) => { + const clientTotal = sum(items, 'client'); + const serverTotal = sum(items, 'server'); + const clientDeltaAsPercent = Math.round( + (clientTotal / (clientTotal + serverTotal)) * 100, + ); + + return ( + +
+
+
+ +
+ +
+
+
+
+ {' '} + KB +
+
Bundle Size
+
+ +
+
+
+
+ +
+
+
+ {''} +
+
Client Component
+
+ +
+
+ {''} +
+
Server Component
+
+
+
+
+
+ Note: The component bundle sizes are not yet accurate. +
+
+ + ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/count-up.tsx b/apps/next-app-router/next-app-router-4000/ui/count-up.tsx new file mode 100644 index 00000000000..7a2cf99bb09 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/count-up.tsx @@ -0,0 +1,25 @@ +'use client'; + +import { useCountUp } from 'use-count-up'; + +const CountUp = ({ + start, + end, + duration = 1, +}: { + start: number; + end: number; + duration?: number; +}) => { + const { value } = useCountUp({ + isCounting: true, + end, + start, + duration, + decimalPlaces: 1, + }); + + return {value}; +}; + +export default CountUp; diff --git a/apps/next-app-router/next-app-router-4000/ui/external-link.tsx b/apps/next-app-router/next-app-router-4000/ui/external-link.tsx new file mode 100644 index 00000000000..662994170e0 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/external-link.tsx @@ -0,0 +1,20 @@ +import { ArrowRightIcon } from '@heroicons/react/24/outline'; + +export const ExternalLink = ({ + children, + href, +}: { + children: React.ReactNode; + href: string; +}) => { + return ( + +
{children}
+ + +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/footer.tsx b/apps/next-app-router/next-app-router-4000/ui/footer.tsx new file mode 100644 index 00000000000..3ac838b2f36 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/footer.tsx @@ -0,0 +1,41 @@ +'use client'; + +export default function Footer({ + reactVersion, + nextVersion, +}: { + reactVersion: string; + nextVersion: string; +}) { + return ( +
+ + + + Powered by + + + + + +
+
React: {reactVersion}
+
Next: {nextVersion}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/global-nav.tsx b/apps/next-app-router/next-app-router-4000/ui/global-nav.tsx new file mode 100644 index 00000000000..5be9ca6ea55 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/global-nav.tsx @@ -0,0 +1,100 @@ +'use client'; + +import { demos, type Item } from '#/lib/demos'; +import { NextLogoDark } from '#/ui/next-logo'; +import Link from 'next/link'; +import { useSelectedLayoutSegment } from 'next/navigation'; +import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/solid'; +import clsx from 'clsx'; +import { useState } from 'react'; + +export function GlobalNav() { + const [isOpen, setIsOpen] = useState(false); + const close = () => setIsOpen(false); + + return ( +
+
+ +
+ +
+ +

+ App Router +

+ +
+ + +
+ +
+
+ ); +} + +function GlobalNavItem({ + item, + close, +}: { + item: Item; + close: () => false | void; +}) { + const segment = useSelectedLayoutSegment(); + const isActive = item.slug === segment; + + return ( + + {item.name} + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/header.tsx b/apps/next-app-router/next-app-router-4000/ui/header.tsx new file mode 100644 index 00000000000..8a7c055505a --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/header.tsx @@ -0,0 +1,43 @@ +'use client'; + +import styled from 'styled-components'; + +const HeadContainer = styled.header` + position: relative; + height: 64px; + align-items: center; + padding: 0px 8px; + margin-bottom: 48px; + display: flex; + border: 0 solid #e5e7eb; + color: rgb(244 244 245); + grid-column-start: 2; + grid-column-end: 4; +`; + +const Title = styled.span` + margin: 0 8px; +`; + +const NextJsLogo = (props: any) => ( + + + +); + +export default function Header() { + return ( + + + The React Framework + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/mobile-nav-toggle.tsx b/apps/next-app-router/next-app-router-4000/ui/mobile-nav-toggle.tsx new file mode 100644 index 00000000000..35d77f602a4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/mobile-nav-toggle.tsx @@ -0,0 +1,64 @@ +'use client'; + +import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/solid'; +import clsx from 'clsx'; +import React from 'react'; + +const MobileNavContext = React.createContext< + [boolean, React.Dispatch>] | undefined +>(undefined); + +export function MobileNavContextProvider({ + children, +}: { + children: React.ReactNode; +}) { + const [isOpen, setIsOpen] = React.useState(false); + return ( + + {children} + + ); +} + +export function useMobileNavToggle() { + const context = React.useContext(MobileNavContext); + if (context === undefined) { + throw new Error( + 'useMobileNavToggle must be used within a MobileNavContextProvider', + ); + } + return context; +} + +export function MobileNavToggle({ children }: { children: React.ReactNode }) { + const [isOpen, setIsOpen] = useMobileNavToggle(); + + return ( + <> + + +
+ {children} +
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/next-logo.tsx b/apps/next-app-router/next-app-router-4000/ui/next-logo.tsx new file mode 100644 index 00000000000..69bec7145ce --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/next-logo.tsx @@ -0,0 +1,117 @@ +export function NextLogoLight() { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} + +export function NextLogoDark() { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/ping.tsx b/apps/next-app-router/next-app-router-4000/ui/ping.tsx new file mode 100644 index 00000000000..40768a77ec7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/ping.tsx @@ -0,0 +1,8 @@ +export function Ping() { + return ( + + + + + ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/product-best-seller.tsx b/apps/next-app-router/next-app-router-4000/ui/product-best-seller.tsx new file mode 100644 index 00000000000..d6e10134705 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-best-seller.tsx @@ -0,0 +1,7 @@ +export const ProductBestSeller = () => { + return ( +
+ Best Seller +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-card.tsx b/apps/next-app-router/next-app-router-4000/ui/product-card.tsx new file mode 100644 index 00000000000..d10188de451 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-card.tsx @@ -0,0 +1,63 @@ +import { Product } from '#/app/api/products/product'; +import { ProductBestSeller } from '#/ui/product-best-seller'; +import { ProductEstimatedArrival } from '#/ui/product-estimated-arrival'; +import { ProductLowStockWarning } from '#/ui/product-low-stock-warning'; +import { ProductPrice } from '#/ui/product-price'; +import { ProductRating } from '#/ui/product-rating'; +import { ProductUsedPrice } from '#/ui/product-used-price'; +import { dinero, type DineroSnapshot } from 'dinero.js'; +import Image from 'next/image'; +import Link from 'next/link'; + +export const ProductCard = ({ + product, + href, +}: { + product: Product; + href: string; +}) => { + const price = dinero(product.price as DineroSnapshot); + + return ( + +
+
+ {product.isBestSeller ? ( +
+ +
+ ) : null} + {product.name} +
+ +
+ {product.name} +
+ + {product.rating ? : null} + + + + {/* */} + + {product.usedPrice ? ( + + ) : null} + + + + {product.stock <= 1 ? ( + + ) : null} +
+ + ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-currency-symbol.tsx b/apps/next-app-router/next-app-router-4000/ui/product-currency-symbol.tsx new file mode 100644 index 00000000000..b9d60ace40d --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-currency-symbol.tsx @@ -0,0 +1,27 @@ +import { toFormat, type Dinero } from 'dinero.js'; + +export const ProductCurrencySymbol = ({ + dinero, +}: { + dinero: Dinero; +}) => { + let symbol = ''; + switch (toFormat(dinero, ({ currency }) => currency.code)) { + case 'GBP': { + symbol = '£'; + break; + } + + case 'EUR': { + symbol = '€'; + break; + } + + default: { + symbol = '$'; + break; + } + } + + return <>{symbol}; +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-deal.tsx b/apps/next-app-router/next-app-router-4000/ui/product-deal.tsx new file mode 100644 index 00000000000..981dfb1f39f --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-deal.tsx @@ -0,0 +1,36 @@ +import { ProductCurrencySymbol } from '#/ui/product-currency-symbol'; +import { toUnit, type Dinero } from 'dinero.js'; + +export const ProductDeal = ({ + price: priceRaw, + discount: discountRaw, +}: { + price: Dinero; + discount: { + amount: Dinero; + }; +}) => { + const discount = toUnit(discountRaw.amount); + const price = toUnit(priceRaw); + const percent = Math.round(100 - (discount / price) * 100); + + return ( +
+
+ -{percent}% +
+
+
+ +
+
+ {discount} +
+
+
+ + {price} +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-estimated-arrival.tsx b/apps/next-app-router/next-app-router-4000/ui/product-estimated-arrival.tsx new file mode 100644 index 00000000000..1b236d4dd41 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-estimated-arrival.tsx @@ -0,0 +1,24 @@ +import { add, format, isTomorrow } from 'date-fns'; + +export const ProductEstimatedArrival = ({ + leadTime, + hasDeliveryTime = false, +}: { + leadTime: number; + hasDeliveryTime?: boolean; +}) => { + const date = add(new Date(), { + days: leadTime, + }); + + return ( +
+ Get it{' '} + + {isTomorrow(date) ? 'tomorrow, ' : null} + {format(date, 'MMM d')} + + {hasDeliveryTime ? <> by 5pm : null} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-lightening-deal.tsx b/apps/next-app-router/next-app-router-4000/ui/product-lightening-deal.tsx new file mode 100644 index 00000000000..d316d020757 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-lightening-deal.tsx @@ -0,0 +1,28 @@ +import { ProductDeal } from '#/ui/product-deal'; +import { add, formatDistanceToNow } from 'date-fns'; +import { type Dinero } from 'dinero.js'; + +export const ProductLighteningDeal = ({ + price, + discount, +}: { + price: Dinero; + discount: { + amount: Dinero; + expires?: number; + }; +}) => { + const date = add(new Date(), { days: discount.expires }); + + return ( + <> +
+
+ Expires in {formatDistanceToNow(date)} +
+
+ + + + ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-low-stock-warning.tsx b/apps/next-app-router/next-app-router-4000/ui/product-low-stock-warning.tsx new file mode 100644 index 00000000000..26ac0d5e626 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-low-stock-warning.tsx @@ -0,0 +1,13 @@ +export const ProductLowStockWarning = ({ stock }: { stock: number }) => { + if (stock > 3) { + return null; + } + + if (stock === 0) { + return
Out of stock
; + } + + return ( +
Only {stock} left in stock
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-price.tsx b/apps/next-app-router/next-app-router-4000/ui/product-price.tsx new file mode 100644 index 00000000000..597086e5f74 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-price.tsx @@ -0,0 +1,52 @@ +import { Product } from '#/app/api/products/product'; +import { ProductCurrencySymbol } from '#/ui/product-currency-symbol'; +import { ProductDeal } from '#/ui/product-deal'; +import { ProductLighteningDeal } from '#/ui/product-lightening-deal'; +import { multiply, toUnit, type Dinero } from 'dinero.js'; + +function isDiscount(obj: any): obj is { percent: number; expires?: number } { + return typeof obj?.percent === 'number'; +} + +function formatDiscount( + price: Dinero, + discountRaw: Product['discount'], +) { + return isDiscount(discountRaw) + ? { + amount: multiply(price, { + amount: discountRaw.percent, + scale: 2, + }), + expires: discountRaw.expires, + } + : undefined; +} + +export const ProductPrice = ({ + price, + discount: discountRaw, +}: { + price: Dinero; + discount: Product['discount']; +}) => { + const discount = formatDiscount(price, discountRaw); + + if (discount) { + if (discount?.expires && typeof discount.expires === 'number') { + return ; + } + return ; + } + + return ( +
+
+ +
+
+ {toUnit(price)} +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-rating.tsx b/apps/next-app-router/next-app-router-4000/ui/product-rating.tsx new file mode 100644 index 00000000000..cc37450378c --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-rating.tsx @@ -0,0 +1,17 @@ +import { StarIcon } from '@heroicons/react/24/solid'; +import clsx from 'clsx'; + +export const ProductRating = ({ rating }: { rating: number }) => { + return ( +
+ {Array.from({ length: 5 }).map((_, i) => { + return ( + + ); + })} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-review-card.tsx b/apps/next-app-router/next-app-router-4000/ui/product-review-card.tsx new file mode 100644 index 00000000000..0dae85c2dbb --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-review-card.tsx @@ -0,0 +1,19 @@ +import type { Review } from '#/app/api/reviews/review'; +import { ProductRating } from '#/ui/product-rating'; + +export const ProductReviewCard = ({ review }: { review: Review }) => { + return ( +
+
+
+
+
{review.name}
+
+ + {review.rating ? : null} +
+ +
{review.text}
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-split-payments.tsx b/apps/next-app-router/next-app-router-4000/ui/product-split-payments.tsx new file mode 100644 index 00000000000..b1248cc5a8b --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-split-payments.tsx @@ -0,0 +1,17 @@ +import { ProductCurrencySymbol } from '#/ui/product-currency-symbol'; +import { allocate, toUnit, up, type Dinero } from 'dinero.js'; + +export const ProductSplitPayments = ({ price }: { price: Dinero }) => { + // only offer split payments for more expensive items + if (toUnit(price) < 150) { + return null; + } + + const [perMonth] = allocate(price, [1, 2]); + return ( +
+ Or + {toUnit(perMonth, { digits: 0, round: up })}/month for 3 months +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/product-used-price.tsx b/apps/next-app-router/next-app-router-4000/ui/product-used-price.tsx new file mode 100644 index 00000000000..db57ed0e65f --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/product-used-price.tsx @@ -0,0 +1,19 @@ +import { Product } from '#/app/api/products/product'; +import { dinero, toUnit, up, type DineroSnapshot } from 'dinero.js'; + +export const ProductUsedPrice = ({ + usedPrice: usedPriceRaw, +}: { + usedPrice: Product['usedPrice']; +}) => { + const usedPrice = dinero(usedPriceRaw as DineroSnapshot); + + return ( +
+
More buying choices
+
+ ${toUnit(usedPrice, { digits: 0, round: up })} (used) +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/rendered-time-ago.tsx b/apps/next-app-router/next-app-router-4000/ui/rendered-time-ago.tsx new file mode 100644 index 00000000000..d7c78d1c6b8 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/rendered-time-ago.tsx @@ -0,0 +1,56 @@ +'use client'; + +import ms from 'ms'; +import { useEffect, useRef, useState } from 'react'; + +// https://github.com/streamich/react-use/blob/master/src/useInterval.ts +const useInterval = (callback: Function, delay?: number | null) => { + const savedCallback = useRef(() => {}); + + useEffect(() => { + savedCallback.current = callback; + }); + + useEffect(() => { + if (delay !== null) { + const interval = setInterval(() => savedCallback.current(), delay || 0); + return () => clearInterval(interval); + } + + return undefined; + }, [delay]); +}; + +export function RenderedTimeAgo({ timestamp }: { timestamp: number }) { + const [msAgo, setMsAgo] = useState(0); + + // update on page change + useEffect(() => { + setMsAgo(Date.now() - timestamp); + }, [timestamp]); + + // update every second + useInterval(() => { + setMsAgo(Date.now() - timestamp); + }, 1000); + + return ( +
+ {msAgo ? ( + <> + + {msAgo >= 1000 ? ms(msAgo) : '0s'} + {' '} + ago + + ) : null} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/rendering-info.tsx b/apps/next-app-router/next-app-router-4000/ui/rendering-info.tsx new file mode 100644 index 00000000000..3048985b506 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/rendering-info.tsx @@ -0,0 +1,34 @@ +import { RenderedTimeAgo } from '#/ui/rendered-time-ago'; + +export function RenderingInfo({ + type, +}: { + type: 'ssg' | 'ssgod' | 'ssr' | 'isr'; +}) { + let msg = ''; + switch (type) { + case 'ssg': + msg = 'Statically pre-rendered at build time'; + break; + case 'ssgod': + msg = 'Statically rendered on demand'; + break; + case 'isr': + msg = + 'Statically pre-rendered at build time and periodically revalidated'; + break; + case 'ssr': + msg = 'Dynamically rendered at request time'; + break; + } + + return ( +
+
{msg}
+ +
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/rendering-page-skeleton.tsx b/apps/next-app-router/next-app-router-4000/ui/rendering-page-skeleton.tsx new file mode 100644 index 00000000000..ae8225a0cc9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/rendering-page-skeleton.tsx @@ -0,0 +1,18 @@ +const shimmer = `relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_1.5s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent`; + +export function RenderingPageSkeleton() { + return ( +
+
+
+
+
+
+
+
+
+
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4000/ui/section-link.tsx b/apps/next-app-router/next-app-router-4000/ui/section-link.tsx new file mode 100644 index 00000000000..48f4b2edda4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/section-link.tsx @@ -0,0 +1,18 @@ +import Link from 'next/link'; + +export const SectionLink = ({ + children, + href, + text, +}: { + children: React.ReactNode; + href: string; + text: string; +}) => ( + +
+ {children} +
+
{text}
+ +); diff --git a/apps/next-app-router/next-app-router-4000/ui/skeleton-card.tsx b/apps/next-app-router/next-app-router-4000/ui/skeleton-card.tsx new file mode 100644 index 00000000000..09e205e6f72 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/skeleton-card.tsx @@ -0,0 +1,16 @@ +import clsx from 'clsx'; + +export const SkeletonCard = ({ isLoading }: { isLoading?: boolean }) => ( +
+
+
+
+
+
+
+); diff --git a/apps/next-app-router/next-app-router-4000/ui/tab-group.tsx b/apps/next-app-router/next-app-router-4000/ui/tab-group.tsx new file mode 100644 index 00000000000..fb20c54f07b --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/tab-group.tsx @@ -0,0 +1,31 @@ +import { Tab } from '#/ui/tab'; + +export type Item = { + text: string; + slug?: string; + segment?: string; + parallelRoutesKey?: string; +}; + +export const TabGroup = ({ + path, + parallelRoutesKey, + items, +}: { + path: string; + parallelRoutesKey?: string; + items: Item[]; +}) => { + return ( +
+ {items.map((item) => ( + + ))} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/tab-nav-item.tsx b/apps/next-app-router/next-app-router-4000/ui/tab-nav-item.tsx new file mode 100644 index 00000000000..ad0b10e09e7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/tab-nav-item.tsx @@ -0,0 +1,25 @@ +import clsx from 'clsx'; +import Link from 'next/link'; + +export const TabNavItem = ({ + children, + href, + isActive, +}: { + children: React.ReactNode; + href: string; + isActive?: boolean; +}) => { + return ( + + {children} + + ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/tab.tsx b/apps/next-app-router/next-app-router-4000/ui/tab.tsx new file mode 100644 index 00000000000..9fa051cb726 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/tab.tsx @@ -0,0 +1,39 @@ +'use client'; + +import type { Item } from '#/ui/tab-group'; +import clsx from 'clsx'; +import Link from 'next/link'; +import { useSelectedLayoutSegment } from 'next/navigation'; + +export const Tab = ({ + path, + parallelRoutesKey, + item, +}: { + path: string; + parallelRoutesKey?: string; + item: Item; +}) => { + const segment = useSelectedLayoutSegment(parallelRoutesKey); + + const href = item.slug ? path + '/' + item.slug : path; + const isActive = + // Example home pages e.g. `/layouts` + (!item.slug && segment === null) || + segment === item.segment || + // Nested pages e.g. `/layouts/electronics` + segment === item.slug; + + return ( + + {item.text} + + ); +}; diff --git a/apps/next-app-router/next-app-router-4000/ui/vercel-logo.tsx b/apps/next-app-router/next-app-router-4000/ui/vercel-logo.tsx new file mode 100644 index 00000000000..6550d288430 --- /dev/null +++ b/apps/next-app-router/next-app-router-4000/ui/vercel-logo.tsx @@ -0,0 +1,11 @@ +export function VercelLogo() { + return ( + + + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/.eslintrc.json b/apps/next-app-router/next-app-router-4001/.eslintrc.json new file mode 100644 index 00000000000..bffb357a712 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/apps/next-app-router/next-app-router-4001/.gitignore b/apps/next-app-router/next-app-router-4001/.gitignore new file mode 100644 index 00000000000..6d1ed289361 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +/.yarn + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env* +!.env*.example + +# vercel +.vercel + +# typescript +*.tsbuildinfo diff --git a/apps/next-app-router/next-app-router-4001/.npmrc b/apps/next-app-router/next-app-router-4001/.npmrc new file mode 100644 index 00000000000..cffe8cdef13 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/.npmrc @@ -0,0 +1 @@ +save-exact=true diff --git a/apps/next-app-router/next-app-router-4001/.prettierignore b/apps/next-app-router/next-app-router-4001/.prettierignore new file mode 100644 index 00000000000..a66d7e1f76d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/.prettierignore @@ -0,0 +1,2 @@ +.next +pnpm-lock.yaml diff --git a/apps/next-app-router/next-app-router-4001/app/api/categories/category.d.ts b/apps/next-app-router/next-app-router-4001/app/api/categories/category.d.ts new file mode 100644 index 00000000000..dccaa7448d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/api/categories/category.d.ts @@ -0,0 +1,6 @@ +export type Category = { + name: string; + slug: string; + count: number; + parent: string | null; +}; diff --git a/apps/next-app-router/next-app-router-4001/app/api/categories/getCategories.ts b/apps/next-app-router/next-app-router-4001/app/api/categories/getCategories.ts new file mode 100644 index 00000000000..989a293429c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/api/categories/getCategories.ts @@ -0,0 +1,52 @@ +import { notFound } from 'next/navigation'; +import type { Category } from './category'; + +// `server-only` guarantees any modules that import code in file +// will never run on the client. Even though this particular API +// doesn't currently use sensitive environment variables, it's +// good practice to add `server-only` preemptively. +import 'server-only'; + +export async function getCategories({ parent }: { parent?: string } = {}) { + const res = await fetch( + `https://app-playground-api.vercel.app/api/categories${ + parent ? `?parent=${parent}` : '' + }`, + ); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const categories = (await res.json()) as Category[]; + + if (categories.length === 0) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return categories; +} + +export async function getCategory({ slug }: { slug: string }) { + const res = await fetch( + `https://app-playground-api.vercel.app/api/categories${ + slug ? `?slug=${slug}` : '' + }`, + ); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const category = (await res.json()) as Category; + + if (!category) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return category; +} diff --git a/apps/next-app-router/next-app-router-4001/app/api/og/Inter-SemiBold.ttf b/apps/next-app-router/next-app-router-4001/app/api/og/Inter-SemiBold.ttf new file mode 100644 index 00000000000..278ceaa36ba Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/app/api/og/Inter-SemiBold.ttf differ diff --git a/apps/next-app-router/next-app-router-4001/app/api/og/route.tsx b/apps/next-app-router/next-app-router-4001/app/api/og/route.tsx new file mode 100644 index 00000000000..48c1bfaebdc --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/api/og/route.tsx @@ -0,0 +1,656 @@ +import type { NextRequest } from 'next/server'; +import { ImageResponse } from 'next/og'; +import type { ReactElement } from 'react'; + +export const runtime = 'edge'; + +const interSemiBold = fetch( + new URL('./Inter-SemiBold.ttf', import.meta.url), +).then((res) => res.arrayBuffer()); + +export async function GET(req: NextRequest): Promise { + try { + const { searchParams } = new URL(req.url); + const isLight = req.headers.get('Sec-CH-Prefers-Color-Scheme') === 'light'; + + const title = searchParams.has('title') + ? searchParams.get('title') + : 'App Router Playground'; + + return new ImageResponse( + ( +
+ {isLight ? : } +
+ {title} +
+
+ ), + { + width: 843, + height: 441, + fonts: [ + { + name: 'Inter', + data: await interSemiBold, + style: 'normal', + weight: 400, + }, + ], + }, + ); + } catch (e) { + if (!(e instanceof Error)) throw e; + + // eslint-disable-next-line no-console + console.log(e.message); + return new Response(`Failed to generate the image`, { + status: 500, + }); + } +} + +function LightSvg(): ReactElement { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +function DarkSvg(): ReactElement { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/api/products/product.d.ts b/apps/next-app-router/next-app-router-4001/app/api/products/product.d.ts new file mode 100644 index 00000000000..c279cf7637d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/api/products/product.d.ts @@ -0,0 +1,37 @@ +export type Product = { + id: string; + stock: number; + rating: number; + name: string; + description: string; + price: Price; + isBestSeller: boolean; + leadTime: number; + image?: string; + imageBlur?: string; + discount?: Discount; + usedPrice?: UsedPrice; +}; + +type Price = { + amount: number; + currency: Currency; + scale: number; +}; + +type Currency = { + code: string; + base: number; + exponent: number; +}; + +type Discount = { + percent: number; + expires?: number; +}; + +type UsedPrice = { + amount: number; + currency: Currency; + scale: number; +}; diff --git a/apps/next-app-router/next-app-router-4001/app/api/revalidate/route.ts b/apps/next-app-router/next-app-router-4001/app/api/revalidate/route.ts new file mode 100644 index 00000000000..fc676f685cb --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/api/revalidate/route.ts @@ -0,0 +1,16 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { revalidatePath, revalidateTag } from 'next/cache'; + +export async function GET(request: NextRequest) { + const path = request.nextUrl.searchParams.get('path') || '/isr/[id]'; + const collection = + request.nextUrl.searchParams.get('collection') || 'collection'; + revalidatePath(path); + revalidateTag(collection); + console.log('revalidated', path, collection); + return NextResponse.json({ + revalidated: true, + now: Date.now(), + cache: 'no-store', + }); +} diff --git a/apps/next-app-router/next-app-router-4001/app/api/reviews/getReviews.ts b/apps/next-app-router/next-app-router-4001/app/api/reviews/getReviews.ts new file mode 100644 index 00000000000..a42b409ee00 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/api/reviews/getReviews.ts @@ -0,0 +1,26 @@ +import { notFound } from 'next/navigation'; +import type { Review } from './review'; + +// `server-only` guarantees any modules that import code in file +// will never run on the client. Even though this particular api +// doesn't currently use sensitive environment variables, it's +// good practise to add `server-only` preemptively. +import 'server-only'; + +export async function getReviews() { + const res = await fetch(`https://app-playground-api.vercel.app/api/reviews`); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const reviews = (await res.json()) as Review[]; + + if (reviews.length === 0) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return reviews; +} diff --git a/apps/next-app-router/next-app-router-4001/app/api/reviews/review.d.ts b/apps/next-app-router/next-app-router-4001/app/api/reviews/review.d.ts new file mode 100644 index 00000000000..0135e4d2dd2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/api/reviews/review.d.ts @@ -0,0 +1,6 @@ +export type Review = { + id: string; + name: string; + rating: number; + text: string; +}; diff --git a/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..3b2e5d0eaf6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,23 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { notFound } from 'next/navigation'; +import { Counter } from '../../context-click-counter'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( + +
+

+ {category.name} +

+ + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..514d27900fe --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/layout.tsx @@ -0,0 +1,37 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; +import { Counter } from '../context-click-counter'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( + +
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/page.tsx new file mode 100644 index 00000000000..121a5be9fb4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/context/[categorySlug]/page.tsx @@ -0,0 +1,22 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { Counter } from '../context-click-counter'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( + +
+

+ All {category.name} +

+ + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/context/context-click-counter.tsx b/apps/next-app-router/next-app-router-4001/app/context/context-click-counter.tsx new file mode 100644 index 00000000000..0a36ee3aaea --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/context/context-click-counter.tsx @@ -0,0 +1,44 @@ +'use client'; + +import { useCounter } from './counter-context'; +import React from 'react'; +import { Boundary } from '#/ui/boundary'; + +const ContextClickCounter = () => { + const [count, setCount] = useCounter(); + + return ( + + + + ); +}; + +export const Counter = () => { + const [count] = useCounter(); + + return ( + +
+ {count} Clicks +
+
+ ); +}; + +export default ContextClickCounter; diff --git a/apps/next-app-router/next-app-router-4001/app/context/counter-context.tsx b/apps/next-app-router/next-app-router-4001/app/context/counter-context.tsx new file mode 100644 index 00000000000..999c04477e9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/context/counter-context.tsx @@ -0,0 +1,24 @@ +'use client'; + +import React from 'react'; + +const CounterContext = React.createContext< + [number, React.Dispatch>] | undefined +>(undefined); + +export function CounterProvider({ children }: { children: React.ReactNode }) { + const [count, setCount] = React.useState(0); + return ( + + {children} + + ); +} + +export function useCounter() { + const context = React.useContext(CounterContext); + if (context === undefined) { + throw new Error('useCounter must be used within a CounterProvider'); + } + return context; +} diff --git a/apps/next-app-router/next-app-router-4001/app/context/layout.tsx b/apps/next-app-router/next-app-router-4001/app/context/layout.tsx new file mode 100644 index 00000000000..8caed20a1c4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/context/layout.tsx @@ -0,0 +1,66 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; +import { CounterProvider } from 'app/context/counter-context'; +import React from 'react'; +import ContextClickCounter from './context-click-counter'; + +const title = 'Client Context'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + return ( + + + + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> +
+ + +
{children}
+
+
+
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/context/page.tsx b/apps/next-app-router/next-app-router-4001/app/context/page.tsx new file mode 100644 index 00000000000..4828d0a6c68 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/context/page.tsx @@ -0,0 +1,30 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Client Context

+ +
    +
  • + This example uses context to share state between Client Components + that cross the Server/Client Component boundary. +
  • +
  • + Try incrementing the counter and navigating between pages. Note how + the counter state is shared across the app even though they are inside + different layouts and pages that are Server Components. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/demo/page.tsx b/apps/next-app-router/next-app-router-4001/app/demo/page.tsx new file mode 100644 index 00000000000..25a589d1919 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/demo/page.tsx @@ -0,0 +1,93 @@ +//@ts-check +'use client'; + +import dynamic from 'next/dynamic'; + +// Dynamically import remote components +const Button = dynamic(() => import('remote_4001/Button'), { ssr: true }); +const Header = dynamic(() => import('remote_4001/Header'), { ssr: true }); +const ProductCard = dynamic(() => import('remote_4001/ProductCard'), { + ssr: true, +}); +const TabGroup = dynamic(() => import('remote_4001/TabGroup'), { ssr: true }); +const TabNavItem = dynamic(() => import('remote_4001/TabNavItem'), { + ssr: true, +}); +const CountUp = dynamic(() => import('remote_4001/CountUp'), { ssr: true }); +const RenderingInfo = dynamic(() => import('remote_4001/RenderingInfo'), { + ssr: true, +}); + +export default function DemoPage() { + return ( +
+
+ +
+

Remote Components Demo

+ +
+

Basic UI Components

+
+ + +
+
+ +
+

Navigation Components

+ + + Tab 1 + + + Tab 2 + + + Tab 3 + + +
+ +
+

Product Components

+
+ + +
+
+ +
+

Interactive Components

+
+
+

Count Up Animation

+ +
+
+

Rendering Information

+ +
+
+
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/[subCategorySlug]/error.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/[subCategorySlug]/error.tsx new file mode 100644 index 00000000000..ee8f211cb20 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/[subCategorySlug]/error.tsx @@ -0,0 +1,26 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import Button from '#/ui/button'; +import React from 'react'; + +export default function Error({ error, reset }: any) { + React.useEffect(() => { + console.log('logging error:', error); + }, [error]); + + return ( + +
+

Error

+

{error?.message}

+
+ +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..0917d305fcb --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,25 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import BuggyButton from '#/ui/buggy-button'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ + + +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/error.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/error.tsx new file mode 100644 index 00000000000..088c06aeb4f --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/error.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import Button from '#/ui/button'; +import React from 'react'; + +export default function Error({ error, reset }: any) { + React.useEffect(() => { + console.log('logging error:', error); + }, [error]); + + return ( + +
+

Error

+

{error?.message}

+
+ +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..02934ebc6cf --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/layout.tsx @@ -0,0 +1,42 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/page.tsx new file mode 100644 index 00000000000..1cb6382c394 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/page.tsx @@ -0,0 +1,27 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import BuggyButton from '#/ui/buggy-button'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ + + +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/[categorySlug]/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/error.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/error.tsx new file mode 100644 index 00000000000..24218e4aed8 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/error.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import Button from '#/ui/button'; +import React from 'react'; + +export default function Error({ error, reset }: any) { + React.useEffect(() => { + console.log('logging error:', error); + }, [error]); + + return ( + +
+

Error

+

{error?.message}

+
+ +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/layout.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/layout.tsx new file mode 100644 index 00000000000..506e7d4ba89 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Error Handling'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/page.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/page.tsx new file mode 100644 index 00000000000..8852aa4337c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/page.tsx @@ -0,0 +1,34 @@ +import BuggyButton from '#/ui/buggy-button'; +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Error Handling

+ +
    +
  • + error.js defines the error boundary for a route segment + and the children below it. It can be used to show specific error + information, and functionality to attempt to recover from the error. +
  • +
  • + Trying navigation pages and triggering an error inside nested layouts. + Notice how the error is isolated to that segment, while the rest of + the app remains interactive. +
  • +
+ +
+ + + + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/error-handling/template.tsx b/apps/next-app-router/next-app-router-4001/app/error-handling/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/error-handling/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/favicon.ico b/apps/next-app-router/next-app-router-4001/app/favicon.ico new file mode 100644 index 00000000000..af98450595e Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/app/favicon.ico differ diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..72ad9f58087 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,17 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { HooksClient } from '#/app/hooks/_components/router-context'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..1ba58575f65 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/layout.tsx @@ -0,0 +1,43 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { LayoutHooks } from '#/app/hooks/_components/router-context-layout'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ + + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/page.tsx new file mode 100644 index 00000000000..a518e7c3c52 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/page.tsx @@ -0,0 +1,19 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { HooksClient } from '#/app/hooks/_components/router-context'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/[categorySlug]/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/_components/router-context-layout.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/_components/router-context-layout.tsx new file mode 100644 index 00000000000..ce4c8118548 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/_components/router-context-layout.tsx @@ -0,0 +1,29 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import { + useSelectedLayoutSegment, + useSelectedLayoutSegments, +} from 'next/navigation'; + +export function LayoutHooks() { + const selectedLayoutSegment = useSelectedLayoutSegment(); + const selectedLayoutSegments = useSelectedLayoutSegments(); + + return selectedLayoutSegment ? ( + +
+
+          {JSON.stringify(
+            {
+              useSelectedLayoutSegment: selectedLayoutSegment,
+              useSelectedLayoutSegments: selectedLayoutSegments,
+            },
+            null,
+            2,
+          )}
+        
+
+
+ ) : null; +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/_components/router-context.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/_components/router-context.tsx new file mode 100644 index 00000000000..42fe045c2ed --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/_components/router-context.tsx @@ -0,0 +1,40 @@ +'use client'; + +import { Boundary } from '#/ui/boundary'; +import { + useParams, + usePathname, + useSearchParams, + useSelectedLayoutSegment, + useSelectedLayoutSegments, +} from 'next/navigation'; + +export function HooksClient() { + const pathname = usePathname(); + const params = useParams(); + const selectedLayoutSegment = useSelectedLayoutSegment(); + const selectedLayoutSegments = useSelectedLayoutSegments(); + const searchParams = useSearchParams(); + + return ( + +
+
+          {JSON.stringify(
+            {
+              usePathname: pathname,
+              useParams: params,
+              useSearchParams: searchParams
+                ? Object.fromEntries(searchParams.entries())
+                : {},
+              useSelectedLayoutSegment: selectedLayoutSegment,
+              useSelectedLayoutSegments: selectedLayoutSegments,
+            },
+            null,
+            2,
+          )}
+        
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/layout.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/layout.tsx new file mode 100644 index 00000000000..ac30b428cd1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/layout.tsx @@ -0,0 +1,50 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { LayoutHooks } from '#/app/hooks/_components/router-context-layout'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Hooks'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ + + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/page.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/page.tsx new file mode 100644 index 00000000000..c216fb991d6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/page.tsx @@ -0,0 +1,32 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+
+

Client Component Hooks

+ +
    +
  • + Next.js provides a number of hooks for accessing routing information + from client components. +
  • +
  • + Try navigating each page and observing the output of each hook + called from the current routes layout.js and{' '} + page.js files. +
  • +
+ +
+ + Docs + + + Code + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/hooks/template.tsx b/apps/next-app-router/next-app-router-4001/app/hooks/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/hooks/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/isr/[id]/page.tsx b/apps/next-app-router/next-app-router-4001/app/isr/[id]/page.tsx new file mode 100644 index 00000000000..c95d3484f70 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/isr/[id]/page.tsx @@ -0,0 +1,30 @@ +import { RenderingInfo } from '#/ui/rendering-info'; + +export const dynamicParams = true; + +export async function generateStaticParams() { + return [{ id: '1' }, { id: '2' }, { id: '3' }]; +} + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + const res = await fetch( + `https://jsonplaceholder.typicode.com/posts/${params.id}`, + { next: { revalidate: 60, tags: ['collection'] } }, + ); + const data = (await res.json()) as { title: string; body: string }; + + return ( +
+
+

+ {data.title} +

+

{data.body}

+
+
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/isr/layout.tsx b/apps/next-app-router/next-app-router-4001/app/isr/layout.tsx new file mode 100644 index 00000000000..7cf3e34bd8e --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/isr/layout.tsx @@ -0,0 +1,35 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Incremental Static Regeneration (ISR)'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + const ids = [{ id: '1' }, { id: '2' }, { id: '3' }]; + + return ( +
+ ({ + text: `Post ${x.id}`, + slug: x.id, + })), + ]} + /> + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/isr/loading.tsx b/apps/next-app-router/next-app-router-4001/app/isr/loading.tsx new file mode 100644 index 00000000000..2c150f871d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/isr/loading.tsx @@ -0,0 +1,5 @@ +import { RenderingPageSkeleton } from '#/ui/rendering-page-skeleton'; + +export default function Loading() { + return ; +} diff --git a/apps/next-app-router/next-app-router-4001/app/isr/page.tsx b/apps/next-app-router/next-app-router-4001/app/isr/page.tsx new file mode 100644 index 00000000000..d90ff0298bb --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/isr/page.tsx @@ -0,0 +1,30 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Incremental Static Regeneration

+ +
    +
  • In this example, three posts fetch data using granular ISR.
  • +
  • Caches responses are fresh for 60 seconds.
  • +
  • + Try navigating to each post and noting the timestamp of when the page + was rendered. Refresh the page after 60 seconds to trigger a + revalidation for the next request. Refresh again to see the + revalidated page. +
  • +
  • Note that the fetch cache can be persisted across builds.
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/isr/template.tsx b/apps/next-app-router/next-app-router-4001/app/isr/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/isr/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/layout.tsx b/apps/next-app-router/next-app-router-4001/app/layout.tsx new file mode 100644 index 00000000000..ba6662a2c6a --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layout.tsx @@ -0,0 +1,53 @@ +import '#/styles/globals.css'; +import { AddressBar } from '#/ui/address-bar'; +import Byline from '#/ui/byline'; +import { GlobalNav } from '#/ui/global-nav'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: { + default: 'Next.js App Router', + template: '%s | Next.js App Router', + }, + metadataBase: new URL('https://app-router.vercel.app'), + description: + 'A playground to explore new Next.js App Router features such as nested layouts, instant loading states, streaming, and component level data fetching.', + openGraph: { + title: 'Next.js App Router Playground', + description: + 'A playground to explore new Next.js App Router features such as nested layouts, instant loading states, streaming, and component level data fetching.', + images: [`/api/og?title=Next.js App Router`], + }, + twitter: { + card: 'summary_large_image', + }, +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + +
+
+
+
+ +
+
+ +
+
{children}
+
+ +
+
+ + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..4bbfae6d332 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,21 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..548d0baae9c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/layout.tsx @@ -0,0 +1,40 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/page.tsx new file mode 100644 index 00000000000..672e25359c6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/page.tsx @@ -0,0 +1,23 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layouts/[categorySlug]/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/layouts/layout.tsx b/apps/next-app-router/next-app-router-4001/app/layouts/layout.tsx new file mode 100644 index 00000000000..108ba315b9e --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layouts/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Nested Layouts'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/layouts/page.tsx b/apps/next-app-router/next-app-router-4001/app/layouts/page.tsx new file mode 100644 index 00000000000..f636922b482 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layouts/page.tsx @@ -0,0 +1,27 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Layouts

+ +
    +
  • + A layout is UI that is shared between multiple pages. On navigation, + layouts preserve state, remain interactive, and do not re-render. Two + or more layouts can also be nested. +
  • +
  • Try navigating between categories and sub categories.
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/layouts/template.tsx b/apps/next-app-router/next-app-router-4001/app/layouts/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/layouts/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/loading/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/loading/[categorySlug]/page.tsx new file mode 100644 index 00000000000..1c1476a5a6c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/loading/[categorySlug]/page.tsx @@ -0,0 +1,43 @@ +import type { Category } from '#/app/api/categories/category'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const res = await fetch( + // We intentionally delay the response to simulate a slow data + // request that would benefit from `loading.js` + `https://app-playground-api.vercel.app/api/categories?delay=1000&slug=${params.categorySlug}`, + { + // We intentionally disable Next.js Cache to better demo + // `loading.js` + cache: 'no-cache', + }, + ); + + if (!res.ok) { + // Render the closest `error.js` Error Boundary + throw new Error('Something went wrong!'); + } + + const category = (await res.json()) as Category; + + if (!category) { + // Render the closest `not-found.js` Error Boundary + notFound(); + } + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/loading/layout.tsx b/apps/next-app-router/next-app-router-4001/app/loading/layout.tsx new file mode 100644 index 00000000000..0a38bb59e20 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/loading/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import { notFound } from 'next/navigation'; +import React from 'react'; + +const title = 'Loading'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/loading/loading.tsx b/apps/next-app-router/next-app-router-4001/app/loading/loading.tsx new file mode 100644 index 00000000000..7cd327a15f3 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/loading/loading.tsx @@ -0,0 +1,17 @@ +import { SkeletonCard } from '#/ui/skeleton-card'; +export default function Loading() { + return ( +
+

Loading...

+ +
+ + + + + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/loading/page.tsx b/apps/next-app-router/next-app-router-4001/app/loading/page.tsx new file mode 100644 index 00000000000..544dbea59ed --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/loading/page.tsx @@ -0,0 +1,35 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Instant Loading States

+ +
    +
  • + This example has an artificial delay when "fetching" data + for each category page. loading.js is used to show a + loading skeleton immediately while data for category page loads before + being streamed in. +
  • +
  • + Shared layouts remain interactive while nested layouts or pages load. + Try clicking the counter while the children load. +
  • +
  • + Navigation is interruptible. Try navigating to one category, then + clicking a second category before the first one has loaded. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/loading/template.tsx b/apps/next-app-router/next-app-router-4001/app/loading/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/loading/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found.tsx b/apps/next-app-router/next-app-router-4001/app/not-found.tsx new file mode 100644 index 00000000000..51b3d5ad4e4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/[subCategorySlug]/not-found.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/[subCategorySlug]/not-found.tsx new file mode 100644 index 00000000000..6bf5c5b3ceb --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/[subCategorySlug]/not-found.tsx @@ -0,0 +1,16 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Sub Category Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..ed9d0322965 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,26 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + // - `getCategory()` returns `notFound()` if the fetched data is `null` or `undefined`. + // - `notFound()` renders the closest `not-found.tsx` in the route segment hierarchy. + // - For `layout.js`, the closest `not-found.tsx` starts from the parent segment. + // - For `page.js`, the closest `not-found.tsx` starts from the same segment. + // - Learn more: https://nextjs.org/docs/app/building-your-application/routing#component-hierarchy. + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..13caeb5571e --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/layout.tsx @@ -0,0 +1,51 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + // - `getCategory()` returns `notFound()` if the fetched data is `null` or `undefined`. + // - `notFound()` renders the closest `not-found.tsx` in the route segment hierarchy. + // - For `layout.js`, the closest `not-found.tsx` starts from the parent segment. + // - For `page.js`, the closest `not-found.tsx` starts from the same segment. + // - Learn more: https://nextjs.org/docs/app/building-your-application/routing#component-hierarchy. + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+
+ ({ + text: x.name, + slug: x.slug, + })), + { + text: 'Subcategory That Does Not Exist', + slug: 'does-not-exist', + }, + ]} + /> + +
+ +
+
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/not-found.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/not-found.tsx new file mode 100644 index 00000000000..4f789bdc9d1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Category Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/page.tsx new file mode 100644 index 00000000000..f2f91ecc632 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/page.tsx @@ -0,0 +1,28 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + // - `getCategory()` returns `notFound()` if the fetched data is `null` or `undefined`. + // - `notFound()` renders the closest `not-found.tsx` in the route segment hierarchy. + // - For `layout.js`, the closest `not-found.tsx` starts from the parent segment. + // - For `page.js`, the closest `not-found.tsx` starts from the same segment. + // - Learn more: https://nextjs.org/docs/app/building-your-application/routing#component-hierarchy. + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/[categorySlug]/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/layout.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/layout.tsx new file mode 100644 index 00000000000..87df3e0297b --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/layout.tsx @@ -0,0 +1,51 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Not Found'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { + text: 'Category That Does Not Exist', + slug: 'does-not-exist', + }, + ]} + /> + +
+ +
+
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/not-found.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/not-found.tsx new file mode 100644 index 00000000000..6fd919d0777 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/page.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/page.tsx new file mode 100644 index 00000000000..42bc8b3d535 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/page.tsx @@ -0,0 +1,54 @@ +import { ExternalLink } from '#/ui/external-link'; +import Link from 'next/link'; + +export default function Page() { + return ( +
+

Not Found

+ +
    +
  • + + + not-found.js + + {' '} + file is used to render UI when the{' '} + + + notFound() + + {' '} + function is thrown within a route segment. +
  • +
  • + In this example, when fetching the data we return{' '} + notFound() for{' '} + Categories and{' '} + + Sub Categories + {' '} + that do not exist. This renders the closest appropriate{' '} + not-found.js. +
  • +
  • + + Note: not-found.js currently only renders when + triggered by the notFound() function. We're + working on support for catching unmatched routes (404). + +
  • +
+ +
+ + Docs + + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/not-found/template.tsx b/apps/next-app-router/next-app-router-4001/app/not-found/template.tsx new file mode 100644 index 00000000000..de11d76dc30 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/not-found/template.tsx @@ -0,0 +1,5 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/page.tsx b/apps/next-app-router/next-app-router-4001/app/page.tsx new file mode 100644 index 00000000000..da496ca4858 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/page.tsx @@ -0,0 +1,44 @@ +import { demos } from '#/lib/demos'; +import Link from 'next/link'; + +export default function Page() { + return ( +
+

Examples

+ +
+ {demos.map((section) => { + return ( +
+
+ {section.name} +
+ +
+ {section.items.map((item) => { + return ( + +
+ {item.name} +
+ + {item.description ? ( +
+ {item.description} +
+ ) : null} + + ); + })} +
+
+ ); + })} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/default.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/default.tsx new file mode 100644 index 00000000000..2d141a3d32b --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/default.tsx @@ -0,0 +1,47 @@ +import { CurrentRoute } from '#/app/parallel-routes/_ui/current-route'; +import { Boundary } from '#/ui/boundary'; +import Link from 'next/link'; + +export default function Default() { + return ( + +
+

Default UI

+ +

+ Default UI is rendered because the @audience slot{' '} + does not contain a route segment that matches the + current{' '} + + / + {' '} + route. +

+ +
    +
  • + + @audience/ + + /page.js + {' '} + does not exist. +
  • + +
  • + @audience/default.js exists. +
  • +
+ +
+ + Home + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/demographics/page.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/demographics/page.tsx new file mode 100644 index 00000000000..94fb886c860 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/demographics/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Demographics

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/layout.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/layout.tsx new file mode 100644 index 00000000000..de0189c5aad --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/layout.tsx @@ -0,0 +1,29 @@ +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + +
+ + + {children} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/page.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/page.tsx new file mode 100644 index 00000000000..3af70b68693 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Home

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/subscribers/page.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/subscribers/page.tsx new file mode 100644 index 00000000000..2f1df01665c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@audience/subscribers/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Subscribers

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/default.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/default.tsx new file mode 100644 index 00000000000..04054c9dd82 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/default.tsx @@ -0,0 +1,46 @@ +import { CurrentRoute } from '#/app/parallel-routes/_ui/current-route'; +import { Boundary } from '#/ui/boundary'; +import Link from 'next/link'; + +export default function Default() { + return ( + +
+

Default UI

+ +

+ Default UI is rendered because the @views slot{' '} + does not contain a route segment that matches the + current{' '} + + / + {' '} + route. +

+ +
    +
  • + + @views/ + + /page.js + {' '} + does not exist. +
  • + +
  • + @views/default.js exists. +
  • +
+
+ + Home + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/impressions/page.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/impressions/page.tsx new file mode 100644 index 00000000000..014ffc879a8 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/impressions/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Impressions

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/layout.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/layout.tsx new file mode 100644 index 00000000000..53d028c9375 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/layout.tsx @@ -0,0 +1,28 @@ +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + +
+ + {children} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/page.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/page.tsx new file mode 100644 index 00000000000..c8f222581aa --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

Home

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/view-duration/page.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/view-duration/page.tsx new file mode 100644 index 00000000000..a95983c9491 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/@views/view-duration/page.tsx @@ -0,0 +1,11 @@ +import { Boundary } from '#/ui/boundary'; + +export default function Page() { + return ( + +
+

View Duration

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/_ui/current-route.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/_ui/current-route.tsx new file mode 100644 index 00000000000..ca756b54acc --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/_ui/current-route.tsx @@ -0,0 +1,9 @@ +'use client'; + +import { usePathname } from 'next/navigation'; + +export function CurrentRoute({ slice = 2 }: { slice?: number }) { + const pathname = usePathname(); + + return <>{pathname?.split('/').slice(slice).join('/')}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/default.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/default.tsx new file mode 100644 index 00000000000..bc636c13e67 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/default.tsx @@ -0,0 +1,54 @@ +import { CurrentRoute } from '#/app/parallel-routes/_ui/current-route'; +import { Boundary } from '#/ui/boundary'; +import Link from 'next/link'; + +export default function Default() { + return ( + +
+

Default UI

+ +

+ Default UI is rendered because the implicit @children{' '} + slot does not contain a route segment that matches + the current{' '} + + / + {' '} + route. +

+ +
    +
  • + + parallel-routes/ + + /page.js + {' '} + OR{' '} + + parallel-routes/@children/ + + /page.js + {' '} + do not exist. +
  • + +
  • + parallel-routes/default.js OR{' '} + parallel-routes/@children/default.js exists. +
  • +
+ +
+ + Home + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/layout.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/layout.tsx new file mode 100644 index 00000000000..db0f3ad8ea9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/layout.tsx @@ -0,0 +1,32 @@ +const title = 'Parallel Routes'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ + children, + audience, + views, +}: { + children: React.ReactNode; + audience: React.ReactNode; + views: React.ReactNode; +}) { + return ( +
+
+ {children} + +
+ {audience} + {views} +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/not-found.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/not-found.tsx new file mode 100644 index 00000000000..0a093b49d74 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/not-found.tsx @@ -0,0 +1,13 @@ +import { Boundary } from '#/ui/boundary'; + +export default function NotFound() { + return ( + +
+

Not Found

+ +

Could not find requested resource

+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/parallel-routes/page.tsx b/apps/next-app-router/next-app-router-4001/app/parallel-routes/page.tsx new file mode 100644 index 00000000000..f681f4e6af2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/parallel-routes/page.tsx @@ -0,0 +1,52 @@ +import { Boundary } from '#/ui/boundary'; +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( + +
+

Parallel Routes

+
    +
  • + Parallel Routes allow you to simultaneously or conditionally render + multiple pages, with independent navigation, in the same layout. +
  • +
  • + Parallel Routes can be used for advanced routing patterns like{' '} + + Conditional Routes + {' '} + and{' '} + + Intercepted Routes + + . +
  • +
  • + Try using the tabs in one parallel route to navigate. Notice the URL + changes but the unaffected parallel route is preserved. +
  • +
  • + Try using the browser's backwards and forwards navigation. + Notice the browser's URL history state and active UI state is + correctly synced. +
  • +
  • + Try navigating to a tab in one parallel route and refreshing the + browser. Notice you can choose what UI to show parallel routes that + don't match the initial URL. +
  • +
+
+ + Docs + + + + Code + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/active-links/_components/nav-links.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/_components/nav-links.tsx new file mode 100644 index 00000000000..4b6ce37cab1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/_components/nav-links.tsx @@ -0,0 +1,34 @@ +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import clsx from 'clsx'; + +export function NavLinks({ + links, +}: { + links: { href: string; name: string }[]; +}) { + // Alternatively, you could use `useParams` or `useSelectedLayoutSegment(s)` + const pathname = usePathname(); + + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/active-links/community/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/community/page.tsx new file mode 100644 index 00000000000..c068b02d3b2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/community/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Community

; +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/active-links/layout.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/layout.tsx new file mode 100644 index 00000000000..ab5017e9e85 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/layout.tsx @@ -0,0 +1,32 @@ +import { NavLinks } from '#/app/patterns/active-links/_components/nav-links'; +import { NextLogoDark } from '#/ui/next-logo'; +import Image from 'next/image'; +import Link from 'next/link'; + +export default function Layout({ children }: { children: React.ReactNode }) { + // Hardcoded links or fetched from db + const links = [ + { href: '/patterns/active-links', name: 'Home' }, + { href: '/patterns/active-links/profile', name: 'Profile' }, + { href: '/patterns/active-links/community', name: 'Community' }, + { href: '/patterns/active-links/settings', name: 'Settings' }, + ]; + + return ( +
+
+ + + User + +
+
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/active-links/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/page.tsx new file mode 100644 index 00000000000..17c847eeb0c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Home

; +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/active-links/profile/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/profile/page.tsx new file mode 100644 index 00000000000..d22888e45d7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/profile/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Profile

; +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/active-links/settings/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/settings/page.tsx new file mode 100644 index 00000000000..ab769269f16 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/active-links/settings/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Settings

; +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/@slot/[...all]/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/@slot/[...all]/page.tsx new file mode 100644 index 00000000000..24a98c10136 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/@slot/[...all]/page.tsx @@ -0,0 +1,25 @@ +import { Breadcrumbs } from '#/app/patterns/breadcrumbs/_components/breadcrumbs'; + +export default async function Page(props: { + params: Promise<{ + all: string[]; + }>; +}) { + const params = await props.params; + + const { all } = params; + + // Note: you could fetch breadcrumb data based on params here + // e.g. title, slug, children/siblings (for dropdowns) + const items = [ + { + text: 'Home', + href: '/patterns/breadcrumbs', + }, + ...all.map((param) => ({ + text: param, + href: `/patterns/breadcrumbs/${param}`, + })), + ]; + return ; +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/@slot/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/@slot/page.tsx new file mode 100644 index 00000000000..212e9b903e3 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/@slot/page.tsx @@ -0,0 +1,13 @@ +import { Breadcrumbs } from '#/app/patterns/breadcrumbs/_components/breadcrumbs'; + +// Note: Next.js doesn't currently support optional catchAll segments in parallel routes. +// In the mean time, this file will match the "/breadcrumb" route. +export default function Page() { + const items = [ + { + text: 'Home', + href: '/patterns/breadcrumbs', + }, + ]; + return ; +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..4bbfae6d332 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,21 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..cfef26af394 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/layout.tsx @@ -0,0 +1,35 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/page.tsx new file mode 100644 index 00000000000..672e25359c6 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/[categorySlug]/page.tsx @@ -0,0 +1,23 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/_components/breadcrumbs.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/_components/breadcrumbs.tsx new file mode 100644 index 00000000000..452724b1d0f --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/_components/breadcrumbs.tsx @@ -0,0 +1,31 @@ +import { ChevronRightIcon } from '@heroicons/react/24/outline'; +import Link from 'next/link'; +import { Fragment } from 'react'; + +export function Breadcrumbs({ + items, +}: { + items: { text: string; href: string }[]; +}) { + return ( +
+ {items.map((item, i) => { + return ( + + {i === 0 ? null : ( + + )} + + + {item.text} + + + ); + })} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/layout.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/layout.tsx new file mode 100644 index 00000000000..e100c42f805 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/layout.tsx @@ -0,0 +1,47 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Breadcrumbs with Parallel Routes'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, + slot, +}: { + children: React.ReactNode; + slot: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( +
+ {slot} + +
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> +
+ + {children} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/page.tsx new file mode 100644 index 00000000000..579a2c5f6ac --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/breadcrumbs/page.tsx @@ -0,0 +1,43 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

+ Shared server-side UI that depends on URL information +

+ +
    +
  • + Typically, when you have shared UI, you'd put it inside a layout. + However, layouts do not receive searchParams and{' '} + params lower than their segment. This is a challenge for + shared UI like breadcrumbs that depends on the URL information. +
  • +
  • + For simple cases, you can move the UI to Client Components and use + router hooks such as usePathname and{' '} + useSearchParams. +
  • +
  • + This example shows how to use Parallel Routes and a{' '} + page.js in a catch all route to have pockets of shared UI + across your app. +
  • +
  • + Try navigating between categories and sub categories. Notice the + breadcrumbs can derive URL information. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/layout.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/layout.tsx new file mode 100644 index 00000000000..d9758696867 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/layout.tsx @@ -0,0 +1,13 @@ +const title = 'Snippets'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/page.tsx new file mode 100644 index 00000000000..c630e1c5f6c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/page.tsx @@ -0,0 +1,56 @@ +import { ExternalLink } from '#/ui/external-link'; +import Link from 'next/link'; + +const items = [ + { + name: 'Active links', + slug: 'active-links', + description: 'Update the style of the current active link', + }, + { + name: 'Breadcrumbs', + slug: 'breadcrumbs', + description: 'Shared server-side Breadcrumb UI using Parallel Routes', + }, + { + name: 'Updating URL search params', + slug: 'search-params', + description: 'Update searchParams using `useRouter` and ``', + }, +]; + +export default function Page() { + return ( +
+

Patterns

+ +
+ {items.map((item) => { + return ( + +
+ {item.name} +
+ + {item.description ? ( +
+ {item.description} +
+ ) : null} + + ); + })} +
+ +
+ + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/search-params/active-link.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/search-params/active-link.tsx new file mode 100644 index 00000000000..f22ccbf9364 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/search-params/active-link.tsx @@ -0,0 +1,30 @@ +'use client'; + +import clsx from 'clsx'; +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; + +export default function ActiveLink({ + isActive, + searchParams, + children, +}: { + isActive: boolean; + searchParams: string; + children: React.ReactNode; +}) { + const pathname = usePathname(); + + return ( + + {children} + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/search-params/client.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/search-params/client.tsx new file mode 100644 index 00000000000..a72f89e5a7c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/search-params/client.tsx @@ -0,0 +1,82 @@ +'use client'; + +import clsx from 'clsx'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useCallback, useMemo } from 'react'; + +export default function Client({ + options, +}: { + options: { + name: string; + value: string; + items: string[]; + }[]; +}) { + const searchParams = useSearchParams()!; + const pathname = usePathname(); + const router = useRouter(); + + const selectedOptions = useMemo(() => { + // Get the initial selected options from the URL's searchParams + const params = new URLSearchParams(searchParams); + + // Preselect the first value of each option if its not + // included in the current searchParams + options.forEach((option) => { + if (!searchParams.has(option.value)) { + params.set(option.value, option.items[0]); + } + }); + + return params; + }, [searchParams, options]); + + const updateSearchParam = useCallback( + (name: string, value: string) => { + // Merge the current searchParams with the new param set + const params = new URLSearchParams(searchParams); + params.set(name, value); + + // Perform a new navigation to the updated URL. The current `page.js` will + // receive a new `searchParams` prop with the updated values. + router.push(pathname + '?' + params.toString()); // or router.replace() + }, + [router, pathname, searchParams], + ); + + return ( + <> +
+ {options.map((option) => ( +
+
{option.name}
+ +
+ {option.items.map((item) => { + const isActive = selectedOptions.get(option.value) === item; + + return ( + + ); + })} +
+
+ ))} +
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/patterns/search-params/page.tsx b/apps/next-app-router/next-app-router-4001/app/patterns/search-params/page.tsx new file mode 100644 index 00000000000..fa94328726f --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/patterns/search-params/page.tsx @@ -0,0 +1,106 @@ +import { Boundary } from '#/ui/boundary'; +import { ExternalLink } from '#/ui/external-link'; +import { Suspense } from 'react'; +import ActiveLink from './active-link'; +import Client from './client'; + +const options = [ + { + name: 'Sort', + value: 'sort', + items: ['asc', 'desc'], + }, + { + name: 'Page', + value: 'page', + items: ['1', '2', '3'], + }, + { + name: 'Items Per Page', + value: 'perPage', + items: ['10', '25', '100'], + }, +]; + +export const dynamic = 'force-dynamic'; + +export default async function Page(props: { searchParams: Promise }) { + const searchParams = await props.searchParams; + return ( +
+

+ Updating searchParams +

+

+ The useSearchParams hook returns a read only version of{' '} + URLSearchParams. You can use{' '} + useRouter() or <Link> to set new{' '} + searchParams. After a navigation is performed, the current{' '} + page.js will receive an updated searchParams{' '} + prop. +

+
+
+ +

+ Using useRouter() +

+ + + + +
+ + + Docs + +
+ +
+ +

+ Using <Link> +

+ +
+ {options.map((option) => { + return ( +
+
{option.name}
+ +
+ {option.items.map((item, i) => { + const isActive = + // set the first item as active if no search param is set + (!searchParams[option.value] && i === 0) || + // otherwise check if the current item is the active one + item === searchParams[option.value]; + + // create new searchParams object for easier manipulation + const params = new URLSearchParams(searchParams); + params.set(option.value, item); + return ( + + {item} + + ); + })} +
+
+ ); + })} +
+
+ + + Docs + +
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/checkout/page.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/checkout/page.tsx new file mode 100644 index 00000000000..80dc7c2458e --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/checkout/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Checkout

; +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/layout.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/layout.tsx new file mode 100644 index 00000000000..7054058ef16 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/layout.tsx @@ -0,0 +1,23 @@ +import { Boundary } from '#/ui/boundary'; +import { TabNavItem } from '#/ui/tab-nav-item'; +import React from 'react'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + +
+
+
+ Back +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/template.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(checkout)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/layout.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/layout.tsx new file mode 100644 index 00000000000..bcc0006a866 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/layout.tsx @@ -0,0 +1,46 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { text: 'Checkout', slug: 'checkout' }, + { text: 'Blog', slug: 'blog' }, + ]} + /> + +
+ +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/page.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/page.tsx new file mode 100644 index 00000000000..b3b778e397a --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/page.tsx @@ -0,0 +1,38 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Route Groups

+ +
    +
  • + This example uses Route Groups to create layouts for different + sections of the app without affecting the URL structure. +
  • +
  • + Try navigating pages and noting the different layouts used for each + section. +
  • +
  • Route groups can be used to:
  • +
      +
    • Opt a route segment out of a shared layout.
    • +
    • Organize routes without affecting the URL structure.
    • +
    • + Create multiple root layouts by partitioning the top level of the + application. +
    • +
    +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/template.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(main)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/blog/page.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/blog/page.tsx new file mode 100644 index 00000000000..1b1a8a4e52b --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/blog/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

Blog

; +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/layout.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/layout.tsx new file mode 100644 index 00000000000..2417ef5e4f8 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/layout.tsx @@ -0,0 +1,46 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { text: 'Checkout', slug: 'checkout' }, + { text: 'Blog', slug: 'blog' }, + ]} + /> + +
+ +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/template.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(marketing)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/[subCategorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/[subCategorySlug]/page.tsx new file mode 100644 index 00000000000..ca6da06338b --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/[subCategorySlug]/page.tsx @@ -0,0 +1,22 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; +import { notFound } from 'next/navigation'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string; subCategorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.subCategorySlug }); + + return ( +
+

{category.name}

+ +
+ {Array.from({ length: category.count }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/layout.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/layout.tsx new file mode 100644 index 00000000000..69b74e3a8bb --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/layout.tsx @@ -0,0 +1,39 @@ +import { getCategories, getCategory } from '#/app/api/categories/getCategories'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; + +export default async function Layout(props: { + children: React.ReactNode; + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + + const { children } = props; + + const category = await getCategory({ slug: params.categorySlug }); + const categories = await getCategories({ parent: params.categorySlug }); + + return ( +
+
+ ({ + text: x.name, + slug: x.slug, + })), + ]} + /> + +
+ +
+
+
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/page.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/page.tsx new file mode 100644 index 00000000000..df3bd10827f --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/page.tsx @@ -0,0 +1,22 @@ +import { getCategory } from '#/app/api/categories/getCategories'; +import { SkeletonCard } from '#/ui/skeleton-card'; + +export default async function Page(props: { + params: Promise<{ categorySlug: string }>; +}) { + const params = await props.params; + const category = await getCategory({ slug: params.categorySlug }); + return ( +
+

+ All {category.name} +

+ +
+ {Array.from({ length: 9 }).map((_, i) => ( + + ))} +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/template.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/[categorySlug]/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/layout.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/layout.tsx new file mode 100644 index 00000000000..7884628bc29 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/layout.tsx @@ -0,0 +1,42 @@ +import { getCategories } from '#/app/api/categories/getCategories'; +import { Boundary } from '#/ui/boundary'; +import { ClickCounter } from '#/ui/click-counter'; +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const categories = await getCategories(); + + return ( + +
+
+ ({ + text: x.name, + slug: x.slug, + })), + { text: 'Checkout', slug: 'checkout' }, + { text: 'Blog', slug: 'blog' }, + ]} + /> + +
+ +
+
+ +
{children}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/template.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/(shop)/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/route-groups/layout.tsx b/apps/next-app-router/next-app-router-4001/app/route-groups/layout.tsx new file mode 100644 index 00000000000..8c5355869d9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/route-groups/layout.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +const title = 'Route Groups'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssg/[id]/page.tsx b/apps/next-app-router/next-app-router-4001/app/ssg/[id]/page.tsx new file mode 100644 index 00000000000..4e2c40d37ca --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssg/[id]/page.tsx @@ -0,0 +1,35 @@ +import { RenderingInfo } from '#/ui/rendering-info'; +import { notFound } from 'next/navigation'; + +export async function generateStaticParams() { + // Generate two pages at build time and the rest (3-100) on-demand + return [{ id: '1' }, { id: '2' }]; +} + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + if (Number(params.id) >= 100) { + notFound(); + } + + const res = await fetch( + `https://jsonplaceholder.typicode.com/posts/${params.id}`, + ); + const data = (await res.json()) as { title: string; body: string }; + + const isOnDemand = Number(params.id) >= 3; + + return ( +
+
+

+ {data.title} +

+

{data.body}

+
+
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssg/layout.tsx b/apps/next-app-router/next-app-router-4001/app/ssg/layout.tsx new file mode 100644 index 00000000000..3ca03680c4e --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssg/layout.tsx @@ -0,0 +1,28 @@ +import { Tab } from '#/ui/tab'; +import React from 'react'; +import { RandomPostTab } from './random-post-tab'; + +const title = 'Static Data'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+
+ + + + +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssg/loading.tsx b/apps/next-app-router/next-app-router-4001/app/ssg/loading.tsx new file mode 100644 index 00000000000..2c150f871d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssg/loading.tsx @@ -0,0 +1,5 @@ +import { RenderingPageSkeleton } from '#/ui/rendering-page-skeleton'; + +export default function Loading() { + return ; +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssg/page.tsx b/apps/next-app-router/next-app-router-4001/app/ssg/page.tsx new file mode 100644 index 00000000000..3133fa73b3d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssg/page.tsx @@ -0,0 +1,31 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Static Data

+ +
    +
  • By default, data fetching in Next.js is cached static.
  • +
  • This example statically caches data fetches for Post 1 and 2.
  • +
  • + A random third post is fetched on-demand the first time it is + requested. +
  • +
  • + Try navigating to each post and noting the timestamp of when the page + was rendered. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssg/random-post-tab.tsx b/apps/next-app-router/next-app-router-4001/app/ssg/random-post-tab.tsx new file mode 100644 index 00000000000..3d92f7aecf1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssg/random-post-tab.tsx @@ -0,0 +1,32 @@ +'use client'; + +import { Tab } from '#/ui/tab'; +import clsx from 'clsx'; +import React, { useEffect } from 'react'; + +const randomNumber = (min: number, max: number) => + Math.floor(Math.random() * (max - min + 1) + min); + +export function RandomPostTab({ path }: { path: string }) { + const [post, setPost] = React.useState( + null, + ); + + useEffect(() => { + const randomId = String(randomNumber(3, 100)); + setPost({ text: `Post ${randomId} (On Demand)`, slug: randomId }); + }, []); + + return ( +
+ {post ? ( + + ) : null} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssg/template.tsx b/apps/next-app-router/next-app-router-4001/app/ssg/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssg/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssr/[id]/page.tsx b/apps/next-app-router/next-app-router-4001/app/ssr/[id]/page.tsx new file mode 100644 index 00000000000..c4e89fae45d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssr/[id]/page.tsx @@ -0,0 +1,24 @@ +import { RenderingInfo } from '#/ui/rendering-info'; + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + const res = await fetch( + `https://jsonplaceholder.typicode.com/posts/${params.id}`, + { cache: 'no-store' }, + ); + const data = (await res.json()) as { title: string; body: string }; + + return ( +
+
+

+ {data.title} +

+

{data.body}

+
+
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssr/layout.tsx b/apps/next-app-router/next-app-router-4001/app/ssr/layout.tsx new file mode 100644 index 00000000000..3ed3464f0b7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssr/layout.tsx @@ -0,0 +1,34 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Dynamic Data'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; +export default function Layout({ children }: { children: React.ReactNode }) { + const ids = [{ id: '1' }, { id: '2' }, { id: '3' }]; + + return ( +
+ ({ + text: `Post ${x.id}`, + slug: x.id, + })), + ]} + /> + +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssr/loading.tsx b/apps/next-app-router/next-app-router-4001/app/ssr/loading.tsx new file mode 100644 index 00000000000..2c150f871d2 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssr/loading.tsx @@ -0,0 +1,5 @@ +import { RenderingPageSkeleton } from '#/ui/rendering-page-skeleton'; + +export default function Loading() { + return ; +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssr/page.tsx b/apps/next-app-router/next-app-router-4001/app/ssr/page.tsx new file mode 100644 index 00000000000..a7b057a676f --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssr/page.tsx @@ -0,0 +1,29 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Dynamic Data

+ +
    +
  • + Dynamic, or server-rendered data, is fetched fresh on each request. +
  • +
  • In this example, the post responses are explicitly not cached.
  • +
  • + Try navigating to each post and noting the timestamp of when the page + was rendered. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/ssr/template.tsx b/apps/next-app-router/next-app-router-4001/app/ssr/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/ssr/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/add-to-cart.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/add-to-cart.tsx new file mode 100644 index 00000000000..1f0ddd20f68 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/add-to-cart.tsx @@ -0,0 +1,56 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { useTransition } from 'react'; +import { useCartCount } from './cart-count-context'; + +export function AddToCart({ initialCartCount }: { initialCartCount: number }) { + const router = useRouter(); + const [isPending, startTransition] = useTransition(); + + const [, setOptimisticCartCount] = useCartCount(); + + const addToCart = () => { + setOptimisticCartCount(initialCartCount + 1); + + // update the cart count cookie + document.cookie = `_cart_count=${initialCartCount + 1}; path=/; max-age=${ + 60 * 60 * 24 * 30 + }};`; + + // Normally you would also send a request to the server to add the item + // to the current users cart + // await fetch(`https://api.acme.com/...`); + + // Use a transition and isPending to create inline loading UI + startTransition(() => { + setOptimisticCartCount(null); + + // Refresh the current route and fetch new data from the server without + // losing client-side browser or React state. + router.refresh(); + + // We're working on more fine-grained data mutation and revalidation: + // https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions + }); + }; + + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/cart-count-context.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/cart-count-context.tsx new file mode 100644 index 00000000000..83fff442f0b --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/cart-count-context.tsx @@ -0,0 +1,36 @@ +'use client'; + +import React, { useState } from 'react'; + +const CartCountContext = React.createContext< + [number, React.Dispatch>] | undefined +>(undefined); + +export function CartCountProvider({ + children, + initialCartCount, +}: { + children: React.ReactNode; + initialCartCount: number; +}) { + const [optimisticCartCount, setOptimisticCartCount] = useState( + null, + ); + + const count = + optimisticCartCount !== null ? optimisticCartCount : initialCartCount; + + return ( + + {children} + + ); +} + +export function useCartCount() { + const context = React.useContext(CartCountContext); + if (context === undefined) { + throw new Error('useCartCount must be used within a CartCountProvider'); + } + return context; +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/cart-count.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/cart-count.tsx new file mode 100644 index 00000000000..cc740ba9830 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/cart-count.tsx @@ -0,0 +1,8 @@ +'use client'; + +import { useCartCount } from './cart-count-context'; + +export function CartCount() { + const [count] = useCartCount(); + return {count}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/header.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/header.tsx new file mode 100644 index 00000000000..9c097ff8b08 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/header.tsx @@ -0,0 +1,53 @@ +import { NextLogoLight } from '#/ui/next-logo'; +import { + MagnifyingGlassIcon, + ShoppingCartIcon, +} from '@heroicons/react/24/solid'; +import Image from 'next/image'; +import Link from 'next/link'; +import { CartCount } from './cart-count'; + +export function Header() { + return ( +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+ +
+
+ +
+ +
+
+ + User +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/pricing.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/pricing.tsx new file mode 100644 index 00000000000..d252fddaedb --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/pricing.tsx @@ -0,0 +1,84 @@ +import type { Product } from '#/app/api/products/product'; +import { Ping } from '#/ui/ping'; +import { ProductEstimatedArrival } from '#/ui/product-estimated-arrival'; +import { ProductLowStockWarning } from '#/ui/product-low-stock-warning'; +import { ProductPrice } from '#/ui/product-price'; +import { ProductSplitPayments } from '#/ui/product-split-payments'; +import { ProductUsedPrice } from '#/ui/product-used-price'; +import { dinero, type DineroSnapshot } from 'dinero.js'; +import { Suspense } from 'react'; +import { AddToCart } from './add-to-cart'; + +function LoadingDots() { + return ( +
+ + + • + + + • + + + • + + +
+ ); +} + +async function UserSpecificDetails({ productId }: { productId: string }) { + const data = await fetch( + `https://app-playground-api.vercel.app/api/products?id=${productId}&delay=500&filter=price,usedPrice,leadTime,stock`, + { + // We intentionally disable Next.js Cache to better demo + // streaming + cache: 'no-store', + }, + ); + + const product = (await data.json()) as Product; + + const price = dinero(product.price as DineroSnapshot); + + return ( + <> + + {product.usedPrice ? ( + + ) : null} + + {product.stock <= 1 ? ( + + ) : null} + + ); +} + +export function Pricing({ + product, + cartCount, +}: { + product: Product; + cartCount: string; +}) { + const price = dinero(product.price as DineroSnapshot); + + return ( +
+ + +
+
+ +
+
+ + }> + + + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/recommended-products.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/recommended-products.tsx new file mode 100644 index 00000000000..09c72f3e3c1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/recommended-products.tsx @@ -0,0 +1,65 @@ +import { Product } from '#/app/api/products/product'; +import { ProductCard } from '#/ui/product-card'; + +export async function RecommendedProducts({ + path, + data, +}: { + path: string; + data: Promise; +}) { + const products = (await data.then((res) => res.json())) as Product[]; + + return ( +
+
+
+ Recommended Products for You +
+
+ Based on your preferences and shopping habits +
+
+
+ {products.map((product) => ( +
+ +
+ ))} +
+
+ ); +} + +const shimmer = `relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_1.5s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent`; + +function ProductSkeleton() { + return ( +
+
+ +
+
+
+
+
+ ); +} + +export function RecommendedProductsSkeleton() { + return ( +
+
+
+
+
+ +
+ + + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/reviews.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/reviews.tsx new file mode 100644 index 00000000000..ab45a45bfb5 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/reviews.tsx @@ -0,0 +1,43 @@ +import type { Review } from '#/app/api/reviews/review'; +import { ProductReviewCard } from '#/ui/product-review-card'; + +export async function Reviews({ data }: { data: Promise }) { + const reviews = (await data.then((res) => res.json())) as Review[]; + + return ( +
+
Customer Reviews
+
+ {reviews.map((review) => { + return ; + })} +
+
+ ); +} + +const shimmer = `relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_1.5s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent`; + +function Skeleton() { + return ( +
+
+
+
+
+
+ ); +} + +export function ReviewsSkeleton() { + return ( +
+
+ +
+ + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/_components/single-product.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/_components/single-product.tsx new file mode 100644 index 00000000000..139bd6be3dd --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/_components/single-product.tsx @@ -0,0 +1,76 @@ +import { Pricing } from '#/app/streaming/_components/pricing'; +import type { Product } from '#/app/api/products/product'; +import { ProductRating } from '#/ui/product-rating'; +import { cookies } from 'next/headers'; +import Image from 'next/image'; + +export const SingleProduct = async ({ data }: { data: Promise }) => { + const product = (await data.then((res) => res.json())) as Product; + + // Get the cart count from the users cookies and pass it to the client + // AddToCart component + const cartCount = (await cookies()).get('_cart_count')?.value || '0'; + + return ( +
+
+
+ {product.name} + +
+
+ {product.name} +
+
+ {product.name} +
+
+ {product.name} +
+
+
+
+ +
+
+ {product.name} +
+ + + +
+

{product.description}

+

{product.description}

+
+
+ +
+ +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/edge/layout.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/edge/layout.tsx new file mode 100644 index 00000000000..6a482c4aa27 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/edge/layout.tsx @@ -0,0 +1,46 @@ +import { Boundary } from '#/ui/boundary'; +import { cookies } from 'next/headers'; +import React from 'react'; +import { CartCountProvider } from '../_components/cart-count-context'; +import { Header } from '../_components/header'; + +export const metadata = { + title: 'Streaming (Edge Runtime)', +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const cartCount = Number((await cookies()).get('_cart_count')?.value || '0'); + + return ( + <> +
+
    +
  • + Primary product information is loaded first as part of the initial + response. +
  • +
  • + Secondary, more personalized details (that might be slower) like + ship date, other recommended products, and customer reviews are + progressively streamed in. +
  • +
  • Try refreshing or navigating to other recommended products.
  • +
+
+ + + +
+
+ + {children} +
+
+
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/edge/product/[id]/page.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/edge/product/[id]/page.tsx new file mode 100644 index 00000000000..be56a674d40 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/edge/product/[id]/page.tsx @@ -0,0 +1,66 @@ +import { + RecommendedProducts, + RecommendedProductsSkeleton, +} from '#/app/streaming/_components/recommended-products'; +import { Reviews, ReviewsSkeleton } from '#/app/streaming/_components/reviews'; +import { SingleProduct } from '#/app/streaming/_components/single-product'; +import { Ping } from '#/ui/ping'; +import { Suspense } from 'react'; + +export const runtime = 'edge'; + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + return ( +
+ + +
+
+ +
+
+ + }> + + + +
+
+ +
+
+ + }> + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/layout.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/layout.tsx new file mode 100644 index 00000000000..a6b84433e3e --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/layout.tsx @@ -0,0 +1,45 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Streaming'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+
+ +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/node/layout.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/node/layout.tsx new file mode 100644 index 00000000000..9d389013731 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/node/layout.tsx @@ -0,0 +1,45 @@ +import { Boundary } from '#/ui/boundary'; +import { cookies } from 'next/headers'; +import React from 'react'; +import { CartCountProvider } from '../_components/cart-count-context'; +import { Header } from '../_components/header'; + +export const metadata = { + title: 'Streaming (Node Runtime)', +}; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + const cartCount = Number((await cookies()).get('_cart_count')?.value || '0'); + + return ( + <> +
+
    +
  • + Primary product information is loaded first as part of the initial + response. +
  • +
  • + Secondary, more personalized details (that might be slower) like + ship date, other recommended products, and customer reviews are + progressively streamed in. +
  • +
  • Try refreshing or navigating to other recommended products.
  • +
+
+ + +
+
+ + {children} +
+
+
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/node/product/[id]/page.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/node/product/[id]/page.tsx new file mode 100644 index 00000000000..b40f468f1ca --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/node/product/[id]/page.tsx @@ -0,0 +1,64 @@ +import { + RecommendedProducts, + RecommendedProductsSkeleton, +} from '#/app/streaming/_components/recommended-products'; +import { Reviews, ReviewsSkeleton } from '#/app/streaming/_components/reviews'; +import { SingleProduct } from '#/app/streaming/_components/single-product'; +import { Ping } from '#/ui/ping'; +import { Suspense } from 'react'; + +export default async function Page(props: { params: Promise<{ id: string }> }) { + const params = await props.params; + return ( +
+ + +
+
+ +
+
+ + }> + + + +
+
+ +
+
+ + }> + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/streaming/page.tsx b/apps/next-app-router/next-app-router-4001/app/streaming/page.tsx new file mode 100644 index 00000000000..4aa68dc9551 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/streaming/page.tsx @@ -0,0 +1,38 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default async function Page() { + return ( +
+

Streaming with Suspense

+ +
    +
  • + Streaming allows you to progressively render and send units of the UI + from the server to the client. +
  • + +
  • + This allows the user to see and interact with the most essential parts + of the page while the rest of the content loads - instead of waiting + for the whole page to load before they can interact with anything. +
  • + +
  • Streaming works with both Edge and Node runtimes.
  • + +
  • + Try streaming by selecting a runtime in the + navigation above. +
  • +
+ +
+ + Docs + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/css-modules/page.tsx b/apps/next-app-router/next-app-router-4001/app/styling/css-modules/page.tsx new file mode 100644 index 00000000000..a9cf5e25820 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/css-modules/page.tsx @@ -0,0 +1,27 @@ +'use client'; + +import styles from './styles.module.css'; + +const SkeletonCard = () => ( +
+
+
+
+
+
+); + +export default function Page() { + return ( +
+

+ Styled with CSS Modules +

+
+ + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/css-modules/styles.module.css b/apps/next-app-router/next-app-router-4001/app/styling/css-modules/styles.module.css new file mode 100644 index 00000000000..c434f7b160a --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/css-modules/styles.module.css @@ -0,0 +1,54 @@ +.container { + display: grid; + grid-template-columns: repeat(1, minmax(0, 1fr)); + gap: 1.5rem /* 24px */; +} + +@media (min-width: 1024px) { + .container { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +.skeleton { + padding: 1rem /* 16px */; + border-radius: 1rem /* 16px */; + background-color: rgb(24 24 27 / 0.8); +} + +.skeleton-img, +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + border-radius: 0.5rem /* 8px */; +} + +.skeleton-img { + height: 3.5rem /* 56px */; + background-color: rgb(63 63 70 / 1); +} + +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; +} + +.skeleton-btn { + background-color: rgb(121 40 202 / 1); + width: 25%; +} + +.skeleton-line-one, +.skeleton-line-two { + background-color: rgb(63 63 70 / 1); +} + +.skeleton-line-one { + width: 91.666667%; +} + +.skeleton-line-two { + width: 66.666667%; +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/global-css/page.tsx b/apps/next-app-router/next-app-router-4001/app/styling/global-css/page.tsx new file mode 100644 index 00000000000..aa39cc31044 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/global-css/page.tsx @@ -0,0 +1,25 @@ +import './styles.css'; + +const SkeletonCard = () => ( +
+
+
+
+
+
+); + +export default function Page() { + return ( +
+

+ Styled with a Global CSS Stylesheet +

+
+ + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/global-css/styles.css b/apps/next-app-router/next-app-router-4001/app/styling/global-css/styles.css new file mode 100644 index 00000000000..c7b408ef9fc --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/global-css/styles.css @@ -0,0 +1,54 @@ +.container { + display: grid; + grid-template-columns: repeat(1, minmax(0, 1fr)); + gap: 1.5rem /* 24px */; +} + +@media (min-width: 1024px) { + .container { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +.skeleton { + padding: 1rem /* 16px */; + border-radius: 1rem /* 16px */; + background-color: rgb(24 24 27 / 0.8); +} + +.skeleton-img, +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + border-radius: 0.5rem /* 8px */; +} + +.skeleton-img { + height: 3.5rem /* 56px */; + background-color: rgb(63 63 70 / 1); +} + +.skeleton-btn, +.skeleton-line-one, +.skeleton-line-two { + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; +} + +.skeleton-btn { + background-color: rgb(245 166 35 / 1); + width: 25%; +} + +.skeleton-line-one, +.skeleton-line-two { + background-color: rgb(63 63 70 / 1); +} + +.skeleton-line-one { + width: 91.666667%; +} + +.skeleton-line-two { + width: 66.666667%; +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/layout.tsx b/apps/next-app-router/next-app-router-4001/app/styling/layout.tsx new file mode 100644 index 00000000000..a49a612b565 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/layout.tsx @@ -0,0 +1,52 @@ +import { TabGroup } from '#/ui/tab-group'; +import React from 'react'; + +const title = 'Styling'; + +export const metadata = { + title, + openGraph: { + title, + images: [`/api/og?title=${title}`], + }, +}; + +const items = [ + { + text: 'Global CSS', + slug: 'global-css', + }, + { + text: 'CSS Modules', + slug: 'css-modules', + }, + { + text: 'Styled Components', + slug: 'styled-components', + }, + { + text: 'Styled JSX', + slug: 'styled-jsx', + }, + { + text: 'Tailwind CSS', + slug: 'tailwind', + }, +]; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/page.tsx b/apps/next-app-router/next-app-router-4001/app/styling/page.tsx new file mode 100644 index 00000000000..fc2df59e419 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/page.tsx @@ -0,0 +1,23 @@ +import { ExternalLink } from '#/ui/external-link'; + +export default function Page() { + return ( +
+

Styling

+ +
    +
  • This example shows different styling solutions.
  • +
+ +
+ + Docs + + + + Code + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/styled-components/layout.tsx b/apps/next-app-router/next-app-router-4001/app/styling/styled-components/layout.tsx new file mode 100644 index 00000000000..bc3ce606379 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/styled-components/layout.tsx @@ -0,0 +1,5 @@ +import StyledComponentsRegistry from './registry'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/styled-components/page.tsx b/apps/next-app-router/next-app-router-4001/app/styling/styled-components/page.tsx new file mode 100644 index 00000000000..dc1f3f35c1d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/styled-components/page.tsx @@ -0,0 +1,69 @@ +'use client'; + +import styled from 'styled-components'; + +const Container = styled.div` + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1.5rem /* 24px */; +`; + +const SkeletonInner = styled.div` + padding: 1rem /* 16px */; + background-color: rgb(24 24 27 / 0.8); + border-radius: 1rem /* 16px */; +`; + +const SkeletonImg = styled.div` + height: 3.5rem /* 56px */; + border-radius: 0.5rem /* 8px */; + background-color: rgb(63 63 70 / 1); +`; + +const SkeletonBtn = styled.div` + margin-top: 0.75rem /* 12px */; + width: 25%; + height: 0.75rem /* 12px */; + border-radius: 0.5rem /* 8px */; + background-color: rgb(255 0 128 / 1); +`; + +const SkeletonLineOne = styled.div` + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; + width: 91.666667%; + border-radius: 0.5rem /* 8px */; + background-color: rgb(63 63 70 / 1); +`; + +const SkeletonLineTwo = styled.div` + margin-top: 0.75rem /* 12px */; + height: 0.75rem /* 12px */; + width: 66.666667%; + border-radius: 0.5rem /* 8px */; + background-color: rgb(63 63 70 / 1); +`; + +const Skeleton = () => ( + + + + + + +); + +export default function Page() { + return ( +
+

+ Styled with Styled Components +

+ + + + + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/styled-components/registry.tsx b/apps/next-app-router/next-app-router-4001/app/styling/styled-components/registry.tsx new file mode 100644 index 00000000000..79346eae087 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/styled-components/registry.tsx @@ -0,0 +1,29 @@ +'use client'; + +import React, { useState } from 'react'; +import { useServerInsertedHTML } from 'next/navigation'; +import { ServerStyleSheet, StyleSheetManager } from 'styled-components'; + +export default function StyledComponentsRegistry({ + children, +}: { + children: React.ReactNode; +}) { + // Only create stylesheet once with lazy initial state + // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()); + + useServerInsertedHTML(() => { + const styles = styledComponentsStyleSheet.getStyleElement(); + styledComponentsStyleSheet.instance.clearTag(); + return <>{styles}; + }); + + if (typeof window !== 'undefined') return <>{children}; + + return ( + + {children} + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/layout.tsx b/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/layout.tsx new file mode 100644 index 00000000000..0072c517b27 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/layout.tsx @@ -0,0 +1,5 @@ +import StyledJsxRegistry from './registry'; + +export default function Layout({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/page.tsx b/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/page.tsx new file mode 100644 index 00000000000..60f514a285c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/page.tsx @@ -0,0 +1,85 @@ +'use client'; + +const SkeletonCard = () => ( + <> +
+
+
+
+
+
+ + +); + +export default function Page() { + return ( +
+

+ Styled with Styled JSX +

+
+ + + +
+ + +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/registry.tsx b/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/registry.tsx new file mode 100644 index 00000000000..c2936d07169 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/styled-jsx/registry.tsx @@ -0,0 +1,23 @@ +'use client'; + +import React, { useState } from 'react'; +import { useServerInsertedHTML } from 'next/navigation'; +import { StyleRegistry, createStyleRegistry } from 'styled-jsx'; + +export default function StyledJsxRegistry({ + children, +}: { + children: React.ReactNode; +}) { + // Only create stylesheet once with lazy initial state + // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state + const [jsxStyleRegistry] = useState(() => createStyleRegistry()); + + useServerInsertedHTML(() => { + const styles = jsxStyleRegistry.styles(); + jsxStyleRegistry.flush(); + return <>{styles}; + }); + + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/tailwind/page.tsx b/apps/next-app-router/next-app-router-4001/app/styling/tailwind/page.tsx new file mode 100644 index 00000000000..7ead53333fa --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/tailwind/page.tsx @@ -0,0 +1,24 @@ +const SkeletonCard = () => ( +
+
+
+
+
+
+); + +export default function Page() { + return ( +
+

+ Styled with Tailwind CSS +

+ +
+ + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/app/styling/template.tsx b/apps/next-app-router/next-app-router-4001/app/styling/template.tsx new file mode 100644 index 00000000000..ad002f10437 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/app/styling/template.tsx @@ -0,0 +1,6 @@ +import { Boundary } from '#/ui/boundary'; +import React from 'react'; + +export default function Template({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/apps/next-app-router/next-app-router-4001/lib/demos.ts b/apps/next-app-router/next-app-router-4001/lib/demos.ts new file mode 100644 index 00000000000..79a1d38ff7d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/lib/demos.ts @@ -0,0 +1,106 @@ +export type Item = { + name: string; + slug: string; + description?: string; +}; + +export const demos: { name: string; items: Item[] }[] = [ + { + name: 'Layouts', + items: [ + { + name: 'Nested Layouts', + slug: 'layouts', + description: 'Create UI that is shared across routes', + }, + { + name: 'Grouped Layouts', + slug: 'route-groups', + description: 'Organize routes without affecting URL paths', + }, + { + name: 'Parallel Routes', + slug: 'parallel-routes', + description: 'Render multiple pages in the same layout', + }, + ], + }, + { + name: 'File Conventions', + items: [ + { + name: 'Loading', + slug: 'loading', + description: + 'Create meaningful Loading UI for specific parts of an app', + }, + { + name: 'Error', + slug: 'error-handling', + description: 'Create Error UI for specific parts of an app', + }, + { + name: 'Not Found', + slug: 'not-found', + description: 'Create Not Found UI for specific parts of an app', + }, + ], + }, + { + name: 'Data Fetching', + items: [ + { + name: 'Streaming with Suspense', + slug: 'streaming', + description: + 'Streaming data fetching from the server with React Suspense', + }, + { + name: 'Static Data', + slug: 'ssg', + description: 'Generate static pages', + }, + { + name: 'Dynamic Data', + slug: 'ssr', + description: 'Server-render pages', + }, + { + name: 'Incremental Static Regeneration', + slug: 'isr', + description: 'Get the best of both worlds between static & dynamic', + }, + ], + }, + { + name: 'Components', + items: [ + { + name: 'Client Context', + slug: 'context', + description: + 'Pass context between Client Components that cross Server/Client Component boundary', + }, + ], + }, + { + name: 'Misc', + items: [ + { + name: 'Patterns', + slug: 'patterns', + description: 'A collection of useful App Router patterns', + }, + { + name: 'Client Component Hooks', + slug: 'hooks', + description: 'Preview the routing hooks available in Client Components', + }, + { + name: 'CSS and CSS-in-JS', + slug: 'styling', + description: 'Preview the supported styling solutions', + }, + ], + }, +]; diff --git a/apps/next-app-router/next-app-router-4001/license.md b/apps/next-app-router/next-app-router-4001/license.md new file mode 100644 index 00000000000..ec9dcd99d17 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/license.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2024 Vercel, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/apps/next-app-router/next-app-router-4001/next-env.d.ts b/apps/next-app-router/next-app-router-4001/next-env.d.ts new file mode 100644 index 00000000000..40c3d68096c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/apps/next-app-router/next-app-router-4001/next.config.js b/apps/next-app-router/next-app-router-4001/next.config.js new file mode 100644 index 00000000000..714745c649c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/next.config.js @@ -0,0 +1,75 @@ +const { withNx } = require('@nx/next/plugins/with-nx'); +const NextFederationPlugin = require('@module-federation/nextjs-mf'); + +/** + * @type {import('@nx/next/plugins/with-nx').WithNxOptions} + **/ +const nextConfig = { + nx: { + // Set this to true if you would like to to use SVGR + // See: https://github.com/gregberge/svgr + svgr: false, + }, + webpack(config, options) { + const { isServer } = options; + config.watchOptions = { + ignored: ['**/node_modules/**', '**/@mf-types/**'], + }; + config.plugins.push( + new NextFederationPlugin({ + name: 'remote_4001', + filename: 'static/chunks/remoteEntry.js', + exposes: { + // Core UI Components + './Button': './ui/button', + // './Header': isServer ? './ui/header?rsc' : './ui/header?shared', + './Footer': './ui/footer', + // './GlobalNav(rsc)': isServer ? './ui/global-nav?rsc' : './ui/global-nav', + // './GlobalNav(ssr)': isServer ? './ui/global-nav?ssr' : './ui/global-nav', + './GlobalNav': './ui/global-nav', + // + // // Product Related Components + // './ProductCard': './ui/product-card', + // './ProductPrice': './ui/product-price', + // './ProductRating': './ui/product-rating', + // './ProductDeal': './ui/product-deal', + // + // // Navigation Components + // './TabGroup': './ui/tab-group', + // './TabNavItem': './ui/tab-nav-item', + // + // // Utility Components + // './Boundary': './ui/boundary', + // './CountUp': './ui/count-up', + // './RenderedTimeAgo': './ui/rendered-time-ago', + // './RenderingInfo': './ui/rendering-info' + }, + shared: { + // 'react': { + // singleton: true, + // requiredVersion: false + // }, + // 'react-dom': { + // singleton: true, + // requiredVersion: false + // } + }, + extraOptions: { + debug: false, + exposePages: true, + enableImageLoaderFix: true, + enableUrlLoaderFix: true, + }, + }), + ); + config.plugins.push({ + name: 'xxx', + apply(compiler) { + compiler.options.devtool = false; + }, + }); + return config; + }, +}; + +module.exports = withNx(nextConfig); diff --git a/apps/next-app-router/next-app-router-4001/package.json b/apps/next-app-router/next-app-router-4001/package.json new file mode 100644 index 00000000000..8eac0648797 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/package.json @@ -0,0 +1,52 @@ +{ + "private": true, + "scripts": { + "build": "next build", + "dev": "NEXT_PRIVATE_LOCAL_WEBPACK=true next dev -p 4001", + "lint": "next lint", + "lint-staged": "lint-staged", + "prettier": "prettier --write --ignore-unknown .", + "prettier:check": "prettier --check --ignore-unknown .", + "start": "next start", + "test": "pnpm prettier:check && pnpm lint" + }, + "git": { + "pre-commit": "lint-staged" + }, + "lint-staged": { + "*": "prettier --write --ignore-unknown" + }, + "dependencies": { + "@heroicons/react": "2.1.3", + "clsx": "2.1.1", + "date-fns": "3.6.0", + "dinero.js": "2.0.0-alpha.10", + "ms": "3.0.0-canary.1", + "next": "15.0.0-canary.193", + "react": "19.0.0-rc-cd22717c-20241013", + "react-dom": "19.0.0-rc-cd22717c-20241013", + "server-only": "0.0.1", + "styled-components": "6.1.8", + "use-count-up": "3.0.1", + "vercel": "34.0.0", + "@module-federation/nextjs-mf": "workspace:*" + }, + "devDependencies": { + "@tailwindcss/forms": "0.5.7", + "@tailwindcss/typography": "0.5.12", + "@types/ms": "0.7.34", + "@types/node": "20.12.7", + "@types/react": "npm:types-react@19.0.0-rc.1", + "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1", + "@vercel/git-hooks": "1.0.0", + "autoprefixer": "10.4.19", + "eslint": "9.0.0", + "eslint-config-next": "14.2.2", + "lint-staged": "15.2.2", + "postcss": "8.4.38", + "prettier": "3.2.5", + "prettier-plugin-tailwindcss": "0.5.14", + "tailwindcss": "3.4.3", + "typescript": "5.4.5" + } +} diff --git a/apps/next-app-router/next-app-router-4001/pnpm-lock.yaml b/apps/next-app-router/next-app-router-4001/pnpm-lock.yaml new file mode 100644 index 00000000000..a441c20e752 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/pnpm-lock.yaml @@ -0,0 +1,5027 @@ +lockfileVersion: '6.0' + +dependencies: + '@heroicons/react': + specifier: 2.1.3 + version: 2.1.3(react@19.0.0-rc-cd22717c-20241013) + clsx: + specifier: 2.1.1 + version: 2.1.1 + date-fns: + specifier: 3.6.0 + version: 3.6.0 + dinero.js: + specifier: 2.0.0-alpha.10 + version: 2.0.0-alpha.10 + ms: + specifier: 3.0.0-canary.1 + version: 3.0.0-canary.1 + next: + specifier: 15.0.0-canary.193 + version: 15.0.0-canary.193(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013) + react: + specifier: 19.0.0-rc-cd22717c-20241013 + version: 19.0.0-rc-cd22717c-20241013 + react-dom: + specifier: 19.0.0-rc-cd22717c-20241013 + version: 19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013) + server-only: + specifier: 0.0.1 + version: 0.0.1 + styled-components: + specifier: 6.1.8 + version: 6.1.8(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013) + use-count-up: + specifier: 3.0.1 + version: 3.0.1(react@19.0.0-rc-cd22717c-20241013) + vercel: + specifier: 34.0.0 + version: 34.0.0 + +devDependencies: + '@tailwindcss/forms': + specifier: 0.5.7 + version: 0.5.7(tailwindcss@3.4.3) + '@tailwindcss/typography': + specifier: 0.5.12 + version: 0.5.12(tailwindcss@3.4.3) + '@types/ms': + specifier: 0.7.34 + version: 0.7.34 + '@types/node': + specifier: 20.12.7 + version: 20.12.7 + '@types/react': + specifier: npm:types-react@19.0.0-rc.1 + version: /types-react@19.0.0-rc.1 + '@types/react-dom': + specifier: npm:types-react-dom@19.0.0-rc.1 + version: /types-react-dom@19.0.0-rc.1 + '@vercel/git-hooks': + specifier: 1.0.0 + version: 1.0.0 + autoprefixer: + specifier: 10.4.19 + version: 10.4.19(postcss@8.4.38) + eslint: + specifier: 9.0.0 + version: 9.0.0 + eslint-config-next: + specifier: 14.2.2 + version: 14.2.2(eslint@9.0.0)(typescript@5.4.5) + lint-staged: + specifier: 15.2.2 + version: 15.2.2 + postcss: + specifier: 8.4.38 + version: 8.4.38 + prettier: + specifier: 3.2.5 + version: 3.2.5 + prettier-plugin-tailwindcss: + specifier: 0.5.14 + version: 0.5.14(prettier@3.2.5) + tailwindcss: + specifier: 3.4.3 + version: 3.4.3 + typescript: + specifier: 5.4.5 + version: 5.4.5 + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + dev: true + + /@babel/runtime@7.24.4: + resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: true + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: false + + /@dinero.js/calculator-number@2.0.0-alpha.10: + resolution: {integrity: sha512-EdKG0yykukigfdq+TsxZ9r0Wrg5flYAncKWSfr2snWDXurFsg8JE0oazVraCBA3Vb5LN4vGuFEpTFTH+dIrRCg==} + dependencies: + '@dinero.js/core': 2.0.0-alpha.10 + dev: false + + /@dinero.js/core@2.0.0-alpha.10: + resolution: {integrity: sha512-vjeGXQbNvDXlXK54zaWDydEXyFAvLDj6LCfwO4CTZJIqn3+PaXakaEd5S0AXC6hluPatxnQa5J63x3WQ/Imrjw==} + dependencies: + '@dinero.js/currencies': 2.0.0-alpha.10 + dev: false + + /@dinero.js/currencies@2.0.0-alpha.10: + resolution: {integrity: sha512-IDKaAh0YcJh700uLCrvWtIRCl5sItc3S2rk4IfVJBbms3j+NBDOlVFJnwru+UrMh7VpqU9GlZRsHcHf0NxYE9A==} + dev: false + + /@edge-runtime/format@2.2.1: + resolution: {integrity: sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/node-utils@2.3.0: + resolution: {integrity: sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/ponyfill@2.4.2: + resolution: {integrity: sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/primitives@4.1.0: + resolution: {integrity: sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==} + engines: {node: '>=16'} + dev: false + + /@edge-runtime/vm@3.2.0: + resolution: {integrity: sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==} + engines: {node: '>=16'} + dependencies: + '@edge-runtime/primitives': 4.1.0 + dev: false + + /@emnapi/runtime@1.3.1: + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + requiresBuild: true + dependencies: + tslib: 2.5.0 + dev: false + optional: true + + /@emotion/is-prop-valid@1.2.1: + resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} + dependencies: + '@emotion/memoize': 0.8.1 + dev: false + + /@emotion/memoize@0.8.1: + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + dev: false + + /@emotion/unitless@0.8.0: + resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} + dev: false + + /@eslint-community/eslint-utils@4.4.0(eslint@9.0.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 9.0.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@3.0.2: + resolution: {integrity: sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 10.0.1 + globals: 14.0.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@9.0.0: + resolution: {integrity: sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@fastify/busboy@2.1.1: + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + dev: false + + /@heroicons/react@2.1.3(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-fEcPfo4oN345SoqdlCDdSa4ivjaKbk0jTd+oubcgNxnNgAfzysfwWfQUr+51wigiWHQQRiZNd1Ao0M5Y3M2EGg==} + peerDependencies: + react: '>= 16' + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + dev: false + + /@humanwhocodes/config-array@0.12.3: + resolution: {integrity: sha512-jsNnTBlMWuTpDkeE3on7+dWJi0D6fdDfeANj/w7MpS8ztROCoLvIO2nG0CcFj+E4k8j4QrSTh4Oryi3i2G669g==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.3: + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + dev: true + + /@img/sharp-darwin-arm64@0.33.5: + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + dev: false + optional: true + + /@img/sharp-darwin-x64@0.33.5: + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-libvips-darwin-arm64@1.0.4: + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-darwin-x64@1.0.4: + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm64@1.0.4: + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-arm@1.0.5: + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-s390x@1.0.4: + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linux-x64@1.0.4: + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-arm64@1.0.4: + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-libvips-linuxmusl-x64@1.0.4: + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + dev: false + optional: true + + /@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] + requiresBuild: true + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + dev: false + optional: true + + /@img/sharp-wasm32@0.33.5: + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + requiresBuild: true + dependencies: + '@emnapi/runtime': 1.3.1 + dev: false + optional: true + + /@img/sharp-win32-ia32@0.33.5: + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@img/sharp-win32-x64@0.33.5: + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@mapbox/node-pre-gyp@1.0.11: + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + dependencies: + detect-libc: 2.0.3 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.6.3 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@next/env@15.0.0-canary.193: + resolution: {integrity: sha512-GBCLGuoPKHF6H/bmtALmKEV/+IsIToVelkM8eZpVDGfWtL03KueC6mUZdhF1trBZenGW3Ly1j0N872koPUcAlw==} + dev: false + + /@next/eslint-plugin-next@14.2.2: + resolution: {integrity: sha512-q+Ec2648JtBpKiu/FSJm8HAsFXlNvioHeBCbTP12T1SGcHYwhqHULSfQgFkPgHDu3kzNp2Kem4J54bK4rPQ5SQ==} + dependencies: + glob: 10.3.10 + dev: true + + /@next/swc-darwin-arm64@15.0.0-canary.193: + resolution: {integrity: sha512-CRq2GfI7r5CcAY1ITTb4FZpK8UTGLrNdYelTuv9zcSe4EhuNb7Qp14XfGGL9LV39ZkP5ypcVHYhkrNbfiL3VuQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-darwin-x64@15.0.0-canary.193: + resolution: {integrity: sha512-+0W+NW4JhdcCDwuy8qd/p/zQ7TlfGJ6qSYzamq7nZ+KFWWSJqmBDzTzNfKPxPgdtfHaVyQIN1ThSEJtrah3+dA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-gnu@15.0.0-canary.193: + resolution: {integrity: sha512-5RawIR+D7KPI/trRdKudCWPYu98eF6f2js00tctF8jOUvpGs5M06RKvp+DKzgPLxaZIxAq+YIycS/F9E88LECA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-arm64-musl@15.0.0-canary.193: + resolution: {integrity: sha512-IdHsXwzkmyMfOE2Ff0C3qeivgnP00l6t+kzoDymv1ldXd9f03T+XgtUtcTWKnVDEKqyBVuKgZHpAm/0JtRvhWg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-gnu@15.0.0-canary.193: + resolution: {integrity: sha512-sOvYkCYNUiR/nq5bQuCc/zXqx6jqmRhL8+PxcOTmIQ9YdSsd9oT/ENZzJ4Bf0MiKGyLC7YpjE6ybTUl5TjlvJA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-linux-x64-musl@15.0.0-canary.193: + resolution: {integrity: sha512-tHNzv1CRFP7fVNsQWyhvoVhnLIn6W8OqtUPS9k33X7WRYCRp+bGJQjefPV4Ht+mBNN3oM51uMtKn7EJ6wizrjw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-arm64-msvc@15.0.0-canary.193: + resolution: {integrity: sha512-RwXjqOXKMF4oiXbQfcTcRfoYUaTl+3xpK6Phz8BnWTeFn0PNUdDZnvUswq4RTZZEAaCw479R35KcnR8SJh/OWw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@next/swc-win32-x64-msvc@15.0.0-canary.193: + resolution: {integrity: sha512-Ib3U2QIzdVOxWa4ChBIbjaEJjg2xDgA71g7/kEMwRTXds8EuKRu9HVwErb+23nxiKiRFEKx9GKTGHURHEKvlJw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + + /@rollup/pluginutils@4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: false + + /@rushstack/eslint-patch@1.10.2: + resolution: {integrity: sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==} + dev: true + + /@sinclair/typebox@0.25.24: + resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} + dev: false + + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/helpers@0.5.13: + resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + dependencies: + tslib: 2.5.0 + dev: false + + /@tailwindcss/forms@0.5.7(tailwindcss@3.4.3): + resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} + peerDependencies: + tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' + dependencies: + mini-svg-data-uri: 1.4.4 + tailwindcss: 3.4.3 + dev: true + + /@tailwindcss/typography@0.5.12(tailwindcss@3.4.3): + resolution: {integrity: sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 3.4.3 + dev: true + + /@tootallnate/once@2.0.0: + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + dev: false + + /@ts-morph/common@0.11.1: + resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} + dependencies: + fast-glob: 3.3.2 + minimatch: 3.1.2 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + dev: false + + /@tsconfig/node10@1.0.11: + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + dev: false + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: false + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: false + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: false + + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + dev: false + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + dev: true + + /@types/node@14.18.33: + resolution: {integrity: sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==} + dev: false + + /@types/node@20.12.7: + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + dependencies: + undici-types: 5.26.5 + dev: true + + /@types/prop-types@15.7.5: + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + dev: true + + /@types/react@18.2.79: + resolution: {integrity: sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==} + dependencies: + '@types/prop-types': 15.7.5 + csstype: 3.1.2 + dev: true + + /@types/stylis@4.2.0: + resolution: {integrity: sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==} + dev: false + + /@typescript-eslint/parser@7.2.0(eslint@9.0.0)(typescript@5.4.5): + resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 7.2.0 + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.4 + eslint: 9.0.0 + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@7.2.0: + resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + dev: true + + /@typescript-eslint/types@7.2.0: + resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.5): + resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/visitor-keys@7.2.0: + resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 7.2.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@vercel/build-utils@7.11.0: + resolution: {integrity: sha512-UFrx1hNIjNJJkd0NZrYfaOrmcWhQmrVsbKe9o3L9jX9J1iufG685wIZ9tFCKKC0Fa2HWbNDNzNxrE5SCAS2lyA==} + dev: false + + /@vercel/error-utils@2.0.2: + resolution: {integrity: sha512-Sj0LFafGpYr6pfCqrQ82X6ukRl5qpmVrHM/191kNYFqkkB9YkjlMAj6QcEsvCG259x4QZ7Tya++0AB85NDPbKQ==} + dev: false + + /@vercel/fun@1.1.0: + resolution: {integrity: sha512-SpuPAo+MlAYMtcMcC0plx7Tv4Mp7SQhJJj1iIENlOnABL24kxHpL09XLQMGzZIzIW7upR8c3edwgfpRtp+dhVw==} + engines: {node: '>= 10'} + dependencies: + '@tootallnate/once': 2.0.0 + async-listen: 1.2.0 + debug: 4.1.1 + execa: 3.2.0 + fs-extra: 8.1.0 + generic-pool: 3.4.2 + micro: 9.3.5-canary.3 + ms: 2.1.1 + node-fetch: 2.6.7 + path-match: 1.2.4 + promisepipe: 3.0.0 + semver: 7.3.5 + stat-mode: 0.3.0 + stream-to-promise: 2.2.0 + tar: 4.4.18 + tree-kill: 1.2.2 + uid-promise: 1.0.0 + uuid: 3.3.2 + xdg-app-paths: 5.1.0 + yauzl-promise: 2.1.3 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/gatsby-plugin-vercel-analytics@1.0.11: + resolution: {integrity: sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==} + dependencies: + web-vitals: 0.2.4 + dev: false + + /@vercel/gatsby-plugin-vercel-builder@2.0.24: + resolution: {integrity: sha512-b02ifu8WCmz4ARjkC9AyuOxpXa0Tmh0uIbDDYvyvDRpvohQY53eC3sXKVOejnmQbi9KojkaJsQRvMTBRh9BUHA==} + dependencies: + '@sinclair/typebox': 0.25.24 + '@vercel/build-utils': 7.11.0 + '@vercel/routing-utils': 3.1.0 + esbuild: 0.14.47 + etag: 1.8.1 + fs-extra: 11.1.0 + dev: false + + /@vercel/git-hooks@1.0.0: + resolution: {integrity: sha512-OxDFAAdyiJ/H0b8zR9rFCu3BIb78LekBXOphOYG3snV4ULhKFX387pBPpqZ9HLiRTejBWBxYEahkw79tuIgdAA==} + requiresBuild: true + dev: true + + /@vercel/go@3.1.1: + resolution: {integrity: sha512-mrzomNYltxkjvtUmaYry5YEyvwTz6c/QQHE5Gr/pPGRIniUiP6T6OFOJ49RBN7e6pRXaNzHPVuidiuBhvHh5+Q==} + dev: false + + /@vercel/hydrogen@1.0.2: + resolution: {integrity: sha512-/Q2MKk1GfOuZAnkE9jQexjtUQqanbY65R+xtJWd9yKIgwcfRI1hxiNH3uXyVM5AvLoY+fxxULkSuxDtUKpkJpQ==} + dependencies: + '@vercel/static-config': 3.0.0 + ts-morph: 12.0.0 + dev: false + + /@vercel/next@4.2.0: + resolution: {integrity: sha512-2KSXdPHpfPWaf0tKTBxOWvdc8e9TPNARjmqtgYUsrl1TVaBNFsZ0GV0kWaVLEw4o7CWfREt8ZY064sNVb1BcAQ==} + dependencies: + '@vercel/nft': 0.26.4 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/nft@0.26.4: + resolution: {integrity: sha512-j4jCOOXke2t8cHZCIxu1dzKLHLcFmYzC3yqAK6MfZznOL1QIJKd0xcFsXK3zcqzU7ScsE2zWkiMMNHGMHgp+FA==} + engines: {node: '>=16'} + hasBin: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.11 + '@rollup/pluginutils': 4.2.1 + acorn: 8.11.3 + acorn-import-attributes: 1.9.5(acorn@8.11.3) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + node-gyp-build: 4.8.0 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/node@3.0.26: + resolution: {integrity: sha512-PoyacnoylwpE3+7RFUVHJlbPqtneTCEJVXXx4n8g9ARgUDSRSCwFpJOhiFQon2sS2YtfCzsJa29Z9dAZQedDcQ==} + dependencies: + '@edge-runtime/node-utils': 2.3.0 + '@edge-runtime/primitives': 4.1.0 + '@edge-runtime/vm': 3.2.0 + '@types/node': 14.18.33 + '@vercel/build-utils': 7.11.0 + '@vercel/error-utils': 2.0.2 + '@vercel/nft': 0.26.4 + '@vercel/static-config': 3.0.0 + async-listen: 3.0.0 + cjs-module-lexer: 1.2.3 + edge-runtime: 2.5.9 + es-module-lexer: 1.4.1 + esbuild: 0.14.47 + etag: 1.8.1 + node-fetch: 2.6.9 + path-to-regexp: 6.2.1 + ts-morph: 12.0.0 + ts-node: 10.9.1(@types/node@14.18.33)(typescript@4.9.5) + typescript: 4.9.5 + undici: 5.26.5 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - encoding + - supports-color + dev: false + + /@vercel/python@4.1.1: + resolution: {integrity: sha512-EbAdKOZ0hPd5b59tLt7R3RQK1azNvuZTrCFRAVHNjqcIHNCmrSvjag5zBGn7Memkk8qWb3+CgBw9K/3LJKei0w==} + dev: false + + /@vercel/redwood@2.0.8: + resolution: {integrity: sha512-hAu7SYXDt+W7kscjtQ5NsuNflXH+QB5/xAdA6FRSS/e41lG6Xq6pqLMDobqq4BR7E2PpppVDw2DUx9KzPNoeEw==} + dependencies: + '@vercel/nft': 0.26.4 + '@vercel/routing-utils': 3.1.0 + semver: 6.3.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/remix-builder@2.1.5: + resolution: {integrity: sha512-VaDhsNg/1lZ7h6GJnaykActeZTRtFQz45qDNwKrHM+Nw5/ocwTun9sCJZY/ziECUNuQEJv95z3wUDhNweG+/9w==} + dependencies: + '@vercel/error-utils': 2.0.2 + '@vercel/nft': 0.26.4 + '@vercel/static-config': 3.0.0 + ts-morph: 12.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@vercel/routing-utils@3.1.0: + resolution: {integrity: sha512-Ci5xTjVTJY/JLZXpCXpLehMft97i9fH34nu9PGav6DtwkVUF6TOPX86U0W0niQjMZ5n6/ZP0BwcJK2LOozKaGw==} + dependencies: + path-to-regexp: 6.1.0 + optionalDependencies: + ajv: 6.12.6 + dev: false + + /@vercel/ruby@2.0.5: + resolution: {integrity: sha512-Gfm8HDech41vf+EPleRzgoJUnDTJerKgckMm4KX0JT860gV9XBMSOWYH7eMWHmMza104+HRCWL7wT6OlpftF2Q==} + dev: false + + /@vercel/static-build@2.4.6: + resolution: {integrity: sha512-LCmEBXRse7Bt46fo4OUzkq6RL1Q26oMWvmbFsW5uKi6bkT8asU1U5/zw9PQTeFQjGRL2vkUi22fGXF6XHuuqsA==} + dependencies: + '@vercel/gatsby-plugin-vercel-analytics': 1.0.11 + '@vercel/gatsby-plugin-vercel-builder': 2.0.24 + '@vercel/static-config': 3.0.0 + ts-morph: 12.0.0 + dev: false + + /@vercel/static-config@3.0.0: + resolution: {integrity: sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw==} + dependencies: + ajv: 8.6.3 + json-schema-to-ts: 1.6.4 + ts-morph: 12.0.0 + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: false + + /acorn-import-attributes@1.9.5(acorn@8.11.3): + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: false + + /acorn-jsx@5.3.2(acorn@8.11.3): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.3 + dev: true + + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + dev: false + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + /ajv@8.6.3: + resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: false + + /ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + /aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: false + + /are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + dev: false + + /arg@4.1.0: + resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} + dev: false + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: false + + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + dependencies: + dequal: 2.0.3 + dev: true + + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + dev: true + + /array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.tosorted@1.1.3: + resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + dev: true + + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + dev: true + + /ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + dev: true + + /async-listen@1.2.0: + resolution: {integrity: sha512-CcEtRh/oc9Jc4uWeUwdpG/+Mb2YUHKmdaTf0gUr7Wa+bfp4xx70HOb3RuSTJMvqKNB1TkdTfjLdrcz2X4rkkZA==} + dev: false + + /async-listen@3.0.0: + resolution: {integrity: sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==} + engines: {node: '>= 14'} + dev: false + + /async-listen@3.0.1: + resolution: {integrity: sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==} + engines: {node: '>= 14'} + dev: false + + /async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + dev: false + + /autoprefixer@10.4.19(postcss@8.4.38): + resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.23.0 + caniuse-lite: 1.0.30001611 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + dev: true + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 + dev: true + + /axe-core@4.7.0: + resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + engines: {node: '>=4'} + dev: true + + /axobject-query@3.2.1: + resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + dependencies: + dequal: 2.0.3 + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001611 + electron-to-chromium: 1.4.740 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.23.0) + dev: true + + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: false + + /busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: false + + /bytes@3.1.0: + resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} + engines: {node: '>= 0.8'} + dev: false + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: true + + /camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + dev: false + + /caniuse-lite@1.0.30001611: + resolution: {integrity: sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==} + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + + /chokidar@3.3.1: + resolution: {integrity: sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.3.0 + optionalDependencies: + fsevents: 2.1.3 + dev: false + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: false + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: false + + /cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + dev: false + + /cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: true + + /cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + dependencies: + slice-ansi: 5.0.0 + string-width: 7.1.0 + dev: true + + /client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false + + /clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + dev: false + + /code-block-writer@10.1.1: + resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==} + dev: false + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false + optional: true + + /color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: false + + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: false + optional: true + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + dev: true + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: false + + /content-type@1.0.4: + resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} + engines: {node: '>= 0.6'} + dev: false + + /convert-hrtime@3.0.0: + resolution: {integrity: sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==} + engines: {node: '>=8'} + dev: false + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + /css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + dev: false + + /css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + dev: false + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + + /damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + + /data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + dev: true + + /date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + dev: false + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /debug@4.1.1: + resolution: {integrity: sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==} + deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + dev: true + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: false + + /depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + dev: false + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + dev: false + + /didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: false + + /dinero.js@2.0.0-alpha.10: + resolution: {integrity: sha512-EDiOZanmJBJnFfiz5cUL/I2UI7EXQ0jXf18srqgO7sQhChyBbN39b5sf6T4fq4Oj3f4/6x2L96YPUbMRcUmd/A==} + dependencies: + '@dinero.js/calculator-number': 2.0.0-alpha.10 + '@dinero.js/core': 2.0.0-alpha.10 + '@dinero.js/currencies': 2.0.0-alpha.10 + dev: false + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /edge-runtime@2.5.9: + resolution: {integrity: sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==} + engines: {node: '>=16'} + hasBin: true + dependencies: + '@edge-runtime/format': 2.2.1 + '@edge-runtime/ponyfill': 2.4.2 + '@edge-runtime/vm': 3.2.0 + async-listen: 3.0.1 + mri: 1.2.0 + picocolors: 1.0.0 + pretty-ms: 7.0.1 + signal-exit: 4.0.2 + time-span: 4.0.0 + dev: false + + /electron-to-chromium@1.4.740: + resolution: {integrity: sha512-Yvg5i+iyv7Xm18BRdVPVm8lc7kgxM3r6iwqCH2zB7QZy1kZRNmd0Zqm0zcD9XoFREE5/5rwIuIAOT+/mzGcnZg==} + dev: true + + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /end-of-stream@1.1.0: + resolution: {integrity: sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==} + dependencies: + once: 1.3.3 + dev: false + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: false + + /enhanced-resolve@5.16.0: + resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + dev: true + + /es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + + /es-iterator-helpers@1.0.18: + resolution: {integrity: sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + globalthis: 1.0.3 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + iterator.prototype: 1.1.2 + safe-array-concat: 1.1.2 + dev: true + + /es-module-lexer@1.4.1: + resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + dev: false + + /es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: true + + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: true + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.2 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild-android-64@0.14.47: + resolution: {integrity: sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-android-arm64@0.14.47: + resolution: {integrity: sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-64@0.14.47: + resolution: {integrity: sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-darwin-arm64@0.14.47: + resolution: {integrity: sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-64@0.14.47: + resolution: {integrity: sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-freebsd-arm64@0.14.47: + resolution: {integrity: sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-32@0.14.47: + resolution: {integrity: sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-64@0.14.47: + resolution: {integrity: sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm64@0.14.47: + resolution: {integrity: sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-arm@0.14.47: + resolution: {integrity: sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-mips64le@0.14.47: + resolution: {integrity: sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-ppc64le@0.14.47: + resolution: {integrity: sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-riscv64@0.14.47: + resolution: {integrity: sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-linux-s390x@0.14.47: + resolution: {integrity: sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /esbuild-netbsd-64@0.14.47: + resolution: {integrity: sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-openbsd-64@0.14.47: + resolution: {integrity: sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /esbuild-sunos-64@0.14.47: + resolution: {integrity: sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-32@0.14.47: + resolution: {integrity: sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-64@0.14.47: + resolution: {integrity: sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild-windows-arm64@0.14.47: + resolution: {integrity: sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /esbuild@0.14.47: + resolution: {integrity: sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.47 + esbuild-android-arm64: 0.14.47 + esbuild-darwin-64: 0.14.47 + esbuild-darwin-arm64: 0.14.47 + esbuild-freebsd-64: 0.14.47 + esbuild-freebsd-arm64: 0.14.47 + esbuild-linux-32: 0.14.47 + esbuild-linux-64: 0.14.47 + esbuild-linux-arm: 0.14.47 + esbuild-linux-arm64: 0.14.47 + esbuild-linux-mips64le: 0.14.47 + esbuild-linux-ppc64le: 0.14.47 + esbuild-linux-riscv64: 0.14.47 + esbuild-linux-s390x: 0.14.47 + esbuild-netbsd-64: 0.14.47 + esbuild-openbsd-64: 0.14.47 + esbuild-sunos-64: 0.14.47 + esbuild-windows-32: 0.14.47 + esbuild-windows-64: 0.14.47 + esbuild-windows-arm64: 0.14.47 + dev: false + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-next@14.2.2(eslint@9.0.0)(typescript@5.4.5): + resolution: {integrity: sha512-12/uFc0KX+wUs7EDpOUGKMXBXZJiBVGdK5/m/QgXOCg2mQ0bQWoKSWNrCeOg7Vum6Kw1d1TW453W6xh+GbHquw==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@next/eslint-plugin-next': 14.2.2 + '@rushstack/eslint-patch': 1.10.2 + '@typescript-eslint/parser': 7.2.0(eslint@9.0.0)(typescript@5.4.5) + eslint: 9.0.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@9.0.0) + eslint-plugin-react: 7.34.1(eslint@9.0.0) + eslint-plugin-react-hooks: 4.6.0(eslint@9.0.0) + typescript: 5.4.5 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0): + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + dependencies: + debug: 4.3.4 + enhanced-resolve: 5.16.0 + eslint: 9.0.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.3 + is-core-module: 2.13.1 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 7.2.0(eslint@9.0.0)(typescript@5.4.5) + debug: 3.2.7 + eslint: 9.0.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@9.0.0) + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 7.2.0(eslint@9.0.0)(typescript@5.4.5) + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.0.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.0.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jsx-a11y@6.8.0(eslint@9.0.0): + resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + '@babel/runtime': 7.24.4 + aria-query: 5.3.0 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + ast-types-flow: 0.0.8 + axe-core: 4.7.0 + axobject-query: 3.2.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + es-iterator-helpers: 1.0.18 + eslint: 9.0.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + dev: true + + /eslint-plugin-react-hooks@4.6.0(eslint@9.0.0): + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 9.0.0 + dev: true + + /eslint-plugin-react@7.34.1(eslint@9.0.0): + resolution: {integrity: sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.2 + array.prototype.toreversed: 1.1.2 + array.prototype.tosorted: 1.1.3 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.18 + eslint: 9.0.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.hasown: 1.1.4 + object.values: 1.2.0 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.11 + dev: true + + /eslint-scope@8.0.1: + resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /eslint@9.0.0: + resolution: {integrity: sha512-IMryZ5SudxzQvuod6rUdIUz29qFItWx281VhtFVc2Psy/ZhlCeD/5DT6lBIJ4H3G+iamGJoTln1v+QSuPw0p7Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.0.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 3.0.2 + '@eslint/js': 9.0.0 + '@humanwhocodes/config-array': 0.12.3 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + escape-string-regexp: 4.0.0 + eslint-scope: 8.0.1 + eslint-visitor-keys: 4.0.0 + espree: 10.0.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@10.0.1: + resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 4.0.0 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: false + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: false + + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: true + + /events-intercept@2.0.0: + resolution: {integrity: sha512-blk1va0zol9QOrdZt0rFXo5KMkNPVSp92Eju/Qz8THwKWKRKeE0T8Br/1aW6+Edkyq9xHYgYxn2QtOnUKPUp+Q==} + dev: false + + /execa@3.2.0: + resolution: {integrity: sha512-kJJfVbI/lZE1PZYDI5VPxp8zXPO9rtxOkhpZ0jMKha56AI9y2gGVC6bkukStQf0ka5Rh15BA5m7cCCH4jmHqkw==} + engines: {node: ^8.12.0 || >=9.7.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + p-finally: 2.0.1 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: false + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + dependencies: + reusify: 1.0.4 + + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: false + + /file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + dependencies: + flat-cache: 4.0.1 + dev: true + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + dev: true + + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + dev: true + + /fs-extra@11.1.0: + resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: false + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: false + + /fs-minipass@1.2.7: + resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} + dependencies: + minipass: 2.9.0 + dev: false + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: false + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: false + + /fsevents@2.1.3: + resolution: {integrity: sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + deprecated: '"Please update to latest v2.3 or v2.2"' + requiresBuild: true + dev: false + optional: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + + /generic-pool@3.4.2: + resolution: {integrity: sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag==} + engines: {node: '>= 4'} + dev: false + + /get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + dev: true + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + dev: true + + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: false + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + dev: true + + /get-tsconfig@4.7.3: + resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + dev: true + + /glob@10.3.12: + resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: false + + /globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + dev: true + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: false + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /http-errors@1.4.0: + resolution: {integrity: sha512-oLjPqve1tuOl5aRhv8GK5eHpqP1C9fb+Ol+XTLjKfLltE44zdDbEdjPSbU7Ch5rSNsVFqZn97SrMmZLdu1/YMw==} + engines: {node: '>= 0.6'} + dependencies: + inherits: 2.0.1 + statuses: 1.5.0 + dev: false + + /http-errors@1.7.3: + resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} + engines: {node: '>= 0.6'} + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.1.1 + statuses: 1.5.0 + toidentifier: 1.0.0 + dev: false + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + dev: false + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: false + + /inherits@2.0.1: + resolution: {integrity: sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==} + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + dev: true + + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: false + optional: true + + /is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.2 + dev: true + + /is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + dependencies: + is-typed-array: 1.1.13 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + + /is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + dependencies: + get-east-asian-width: 1.2.0 + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + dev: true + + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: true + + /is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + dev: true + + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.15 + dev: true + + /is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.7 + dev: true + + /is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + dev: true + + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: false + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 + dev: true + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-schema-to-ts@1.6.4: + resolution: {integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==} + dependencies: + '@types/json-schema': 7.0.15 + ts-toolbelt: 6.15.5 + dev: false + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: false + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + dev: true + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /language-subtag-registry@0.3.22: + resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + dev: true + + /language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + dependencies: + language-subtag-registry: 0.3.22 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + dev: true + + /lilconfig@3.1.1: + resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} + engines: {node: '>=14'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /lint-staged@15.2.2: + resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==} + engines: {node: '>=18.12.0'} + hasBin: true + dependencies: + chalk: 5.3.0 + commander: 11.1.0 + debug: 4.3.4 + execa: 8.0.1 + lilconfig: 3.0.0 + listr2: 8.0.1 + micromatch: 4.0.5 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /listr2@8.0.1: + resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} + engines: {node: '>=18.0.0'} + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.0.0 + rfdc: 1.3.1 + wrap-ansi: 9.0.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.castarray@4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} + dependencies: + ansi-escapes: 6.2.1 + cli-cursor: 4.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + dev: true + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.1 + dev: false + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: false + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + /micro@9.3.5-canary.3: + resolution: {integrity: sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==} + engines: {node: '>= 8.0.0'} + hasBin: true + dependencies: + arg: 4.1.0 + content-type: 1.0.4 + raw-body: 2.4.1 + dev: false + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /mini-svg-data-uri@1.4.4: + resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + hasBin: true + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + /minipass@2.9.0: + resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} + dependencies: + safe-buffer: 5.2.1 + yallist: 3.1.1 + dev: false + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: false + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: false + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /minizlib@1.3.3: + resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} + dependencies: + minipass: 2.9.0 + dev: false + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: false + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: false + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: false + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: false + + /ms@2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + dev: false + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /ms@3.0.0-canary.1: + resolution: {integrity: sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==} + engines: {node: '>=12.13'} + dev: false + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /next@15.0.0-canary.193(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-X17zCn32Tl2lpnYoNFcGlTAkDGAyXGNpnsu6HJec/vrTA5ogi+TArSgorGQdXnKCAR+GnwSn/Um3S46VUvcCxw==} + engines: {node: '>=18.18.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-cd22717c-20241013 + react-dom: ^18.2.0 || 19.0.0-rc-cd22717c-20241013 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + dependencies: + '@next/env': 15.0.0-canary.193 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.13 + busboy: 1.6.0 + caniuse-lite: 1.0.30001611 + postcss: 8.4.31 + react: 19.0.0-rc-cd22717c-20241013 + react-dom: 19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013) + styled-jsx: 5.1.6(react@19.0.0-rc-cd22717c-20241013) + optionalDependencies: + '@next/swc-darwin-arm64': 15.0.0-canary.193 + '@next/swc-darwin-x64': 15.0.0-canary.193 + '@next/swc-linux-arm64-gnu': 15.0.0-canary.193 + '@next/swc-linux-arm64-musl': 15.0.0-canary.193 + '@next/swc-linux-x64-gnu': 15.0.0-canary.193 + '@next/swc-linux-x64-musl': 15.0.0-canary.193 + '@next/swc-win32-arm64-msvc': 15.0.0-canary.193 + '@next/swc-win32-x64-msvc': 15.0.0-canary.193 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + + /node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-fetch@2.6.9: + resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp-build@4.8.0: + resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} + hasBin: true + dev: false + + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + + /nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: false + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + /normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: false + + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + + /npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: false + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + dev: true + + /object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /once@1.3.3: + resolution: {integrity: sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /os-paths@4.4.0: + resolution: {integrity: sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==} + engines: {node: '>= 6.0'} + dev: false + + /p-finally@2.0.1: + resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} + engines: {node: '>=8'} + dev: false + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-ms@2.1.0: + resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} + engines: {node: '>=6'} + dev: false + + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: false + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: false + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-match@1.2.4: + resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==} + dependencies: + http-errors: 1.4.0 + path-to-regexp: 1.8.0 + dev: false + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + dev: true + + /path-to-regexp@1.8.0: + resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + dependencies: + isarray: 0.0.1 + dev: false + + /path-to-regexp@6.1.0: + resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==} + dev: false + + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: false + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: false + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-import@15.1.0(postcss@8.4.38): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + dev: true + + /postcss-js@4.0.1(postcss@8.4.38): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.38 + dev: true + + /postcss-load-config@4.0.2(postcss@8.4.38): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 3.1.1 + postcss: 8.4.38 + yaml: 2.4.1 + dev: true + + /postcss-nested@6.0.1(postcss@8.4.38): + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.38 + postcss-selector-parser: 6.0.16 + dev: true + + /postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-selector-parser@6.0.16: + resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: false + + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier-plugin-tailwindcss@0.5.14(prettier@3.2.5): + resolution: {integrity: sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig-melody': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig-melody': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + dependencies: + prettier: 3.2.5 + dev: true + + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /pretty-ms@7.0.1: + resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} + engines: {node: '>=10'} + dependencies: + parse-ms: 2.1.0 + dev: false + + /promisepipe@3.0.0: + resolution: {integrity: sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==} + dev: false + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: false + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + /raw-body@2.4.1: + resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.0 + http-errors: 1.7.3 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + + /react-dom@19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-NzjTBOXygonUxLRQuUUW5V2QLGkAcyUwJoS8+UWxs089paMvQQfoRD51w65Ovgd2OEQ8Rm3HWx+82fvXiT0czQ==} + peerDependencies: + react: 19.0.0-rc-cd22717c-20241013 + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + scheduler: 0.25.0-rc-cd22717c-20241013 + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react@19.0.0-rc-cd22717c-20241013: + resolution: {integrity: sha512-k28GszmyQ1tX/JmeLGZINq5KXiNy/MmN0fCAtcwF8a9INDyVYG0zATCRGJwaPB9WixmkuwPv1BfB1QBfJC7cNg==} + engines: {node: '>=0.10.0'} + dev: false + + /read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /readdirp@3.3.0: + resolution: {integrity: sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: false + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.3 + which-builtin-type: 1.1.3 + dev: true + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: true + + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: false + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + /rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: false + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + + /safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + + /scheduler@0.25.0-rc-cd22717c-20241013: + resolution: {integrity: sha512-MnsFR57bKcrYslnbCUsaUG0qBuAArk92VxE0zu6A2Usz38iIuL2uZLunqKlP1W47MF33GrRGDj1sXdPbFKIZfw==} + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + /semver@7.3.5: + resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + dev: false + + /server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + dev: false + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + dev: true + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + dev: true + + /setprototypeof@1.1.1: + resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} + dev: false + + /shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + dev: false + + /sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + dev: false + optional: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + /signal-exit@4.0.2: + resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} + engines: {node: '>=14'} + dev: false + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + dependencies: + is-arrayish: 0.3.2 + dev: false + optional: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + + /slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + dev: true + + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + /stat-mode@0.3.0: + resolution: {integrity: sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==} + dev: false + + /statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + dev: false + + /stream-to-array@2.3.0: + resolution: {integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==} + dependencies: + any-promise: 1.3.0 + dev: false + + /stream-to-promise@2.2.0: + resolution: {integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==} + dependencies: + any-promise: 1.3.0 + end-of-stream: 1.1.0 + stream-to-array: 2.3.0 + dev: false + + /streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: false + + /string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + + /string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + dev: true + + /string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 + dev: true + + /string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: false + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /styled-components@6.1.8(react-dom@19.0.0-rc-cd22717c-20241013)(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==} + engines: {node: '>= 16'} + peerDependencies: + react: '>= 16.8.0' + react-dom: '>= 16.8.0' + dependencies: + '@emotion/is-prop-valid': 1.2.1 + '@emotion/unitless': 0.8.0 + '@types/stylis': 4.2.0 + css-to-react-native: 3.2.0 + csstype: 3.1.2 + postcss: 8.4.31 + react: 19.0.0-rc-cd22717c-20241013 + react-dom: 19.0.0-rc-cd22717c-20241013(react@19.0.0-rc-cd22717c-20241013) + shallowequal: 1.1.0 + stylis: 4.3.1 + tslib: 2.5.0 + dev: false + + /styled-jsx@5.1.6(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + client-only: 0.0.1 + react: 19.0.0-rc-cd22717c-20241013 + dev: false + + /stylis@4.3.1: + resolution: {integrity: sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==} + dev: false + + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.3.12 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /tailwindcss@3.4.3: + resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.0 + lilconfig: 2.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.38 + postcss-import: 15.1.0(postcss@8.4.38) + postcss-js: 4.0.1(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-nested: 6.0.1(postcss@8.4.38) + postcss-selector-parser: 6.0.16 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + dev: true + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + + /tar@4.4.18: + resolution: {integrity: sha512-ZuOtqqmkV9RE1+4odd+MhBpibmCxNP6PJhH/h2OqNuotTX7/XHPZQJv2pKvWMplFH9SIZZhitehh6vBH6LO8Pg==} + engines: {node: '>=4.5'} + dependencies: + chownr: 1.1.4 + fs-minipass: 1.2.7 + minipass: 2.9.0 + minizlib: 1.3.3 + mkdirp: 0.5.6 + safe-buffer: 5.2.1 + yallist: 3.1.1 + dev: false + + /tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: false + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /time-span@4.0.0: + resolution: {integrity: sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==} + engines: {node: '>=10'} + dependencies: + convert-hrtime: 3.0.0 + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /toidentifier@1.0.0: + resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} + engines: {node: '>=0.6'} + dev: false + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: false + + /ts-api-utils@1.3.0(typescript@5.4.5): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.4.5 + dev: true + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + + /ts-morph@12.0.0: + resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} + dependencies: + '@ts-morph/common': 0.11.1 + code-block-writer: 10.1.1 + dev: false + + /ts-node@10.9.1(@types/node@14.18.33)(typescript@4.9.5): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 14.18.33 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: false + + /ts-toolbelt@6.15.5: + resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} + dev: false + + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + dev: false + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + dev: true + + /typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + dev: true + + /types-react-dom@19.0.0-rc.1: + resolution: {integrity: sha512-VSLZJl8VXCD0fAWp7DUTFUDCcZ8DVXOQmjhJMD03odgeFmu14ZQJHCXeETm3BEAhJqfgJaFkLnGkQv88sRx0fQ==} + dependencies: + '@types/react': 18.2.79 + dev: true + + /types-react@19.0.0-rc.1: + resolution: {integrity: sha512-RshndUfqTW6K3STLPis8BtAYCGOkMbtvYsi90gmVNDZBXUyUc5juf2PE9LfS/JmOlUIRO8cWTS/1MTnmhjDqyQ==} + dependencies: + csstype: 3.1.2 + dev: true + + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: false + + /typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /uid-promise@1.0.0: + resolution: {integrity: sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==} + dev: false + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /undici@5.26.5: + resolution: {integrity: sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==} + engines: {node: '>=14.0'} + dependencies: + '@fastify/busboy': 2.1.1 + dev: false + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: false + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: false + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: false + + /update-browserslist-db@1.0.13(browserslist@4.23.0): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.2 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + + /use-count-up@3.0.1(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-jlVsXJYje6jh+xwQaCEYrwHoB+nRyillNEmr21bhe9kw7tpRzyrSq9jQs9UOlo+8hCFkuOmjUihL3IjEK/piVg==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + use-elapsed-time: 3.0.2(react@19.0.0-rc-cd22717c-20241013) + dev: false + + /use-elapsed-time@3.0.2(react@19.0.0-rc-cd22717c-20241013): + resolution: {integrity: sha512-2EY9lJ5DWbAvT8wWiEp6Ztnl46DjXz2j78uhWbXaz/bg3OfpbgVucCAlcN8Bih6hTJfFTdVYX9L6ySMn5py/wQ==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 19.0.0-rc-cd22717c-20241013 + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + /uuid@3.3.2: + resolution: {integrity: sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: false + + /vercel@34.0.0: + resolution: {integrity: sha512-0Gewf/gB/UDnkGA/wyAzf3wxXuDqCvPFKFkAcByV3PuoCF5j71MqjV3GpFC0rQREF7CZZflFMhoaQO70a9x/fA==} + engines: {node: '>= 16'} + hasBin: true + dependencies: + '@vercel/build-utils': 7.11.0 + '@vercel/fun': 1.1.0 + '@vercel/go': 3.1.1 + '@vercel/hydrogen': 1.0.2 + '@vercel/next': 4.2.0 + '@vercel/node': 3.0.26 + '@vercel/python': 4.1.1 + '@vercel/redwood': 2.0.8 + '@vercel/remix-builder': 2.1.5 + '@vercel/ruby': 2.0.5 + '@vercel/static-build': 2.4.6 + chokidar: 3.3.1 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - encoding + - supports-color + dev: false + + /web-vitals@0.2.4: + resolution: {integrity: sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + dev: true + + /which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + dev: true + + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: false + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: true + + /wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + dependencies: + ansi-styles: 6.2.1 + string-width: 7.1.0 + strip-ansi: 7.1.0 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: false + + /xdg-app-paths@5.1.0: + resolution: {integrity: sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==} + engines: {node: '>=6'} + dependencies: + xdg-portable: 7.3.0 + dev: false + + /xdg-portable@7.3.0: + resolution: {integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==} + engines: {node: '>= 6.0'} + dependencies: + os-paths: 4.4.0 + dev: false + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + engines: {node: '>= 14'} + dev: true + + /yaml@2.4.1: + resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} + engines: {node: '>= 14'} + hasBin: true + dev: true + + /yauzl-clone@1.0.4: + resolution: {integrity: sha512-igM2RRCf3k8TvZoxR2oguuw4z1xasOnA31joCqHIyLkeWrvAc2Jgay5ISQ2ZplinkoGaJ6orCz56Ey456c5ESA==} + engines: {node: '>=6'} + dependencies: + events-intercept: 2.0.0 + dev: false + + /yauzl-promise@2.1.3: + resolution: {integrity: sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA==} + engines: {node: '>=6'} + dependencies: + yauzl: 2.10.0 + yauzl-clone: 1.0.4 + dev: false + + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: false + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: false + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/apps/next-app-router/next-app-router-4001/postcss.config.js b/apps/next-app-router/next-app-router-4001/postcss.config.js new file mode 100644 index 00000000000..12a703d900d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/apps/next-app-router/next-app-router-4001/prettier.config.js b/apps/next-app-router/next-app-router-4001/prettier.config.js new file mode 100644 index 00000000000..4a079f6109c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/prettier.config.js @@ -0,0 +1,9 @@ +module.exports = { + arrowParens: 'always', + semi: true, + trailingComma: 'all', + singleQuote: true, + // pnpm doesn't support plugin autoloading + // https://github.com/tailwindlabs/prettier-plugin-tailwindcss#installation + // plugins: ['prettier-plugin-tailwindcss'], +}; diff --git a/apps/next-app-router/next-app-router-4001/project.json b/apps/next-app-router/next-app-router-4001/project.json new file mode 100644 index 00000000000..cba17d562e1 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/project.json @@ -0,0 +1,84 @@ +{ + "name": "next-app-router-4001", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/next-app-router-4001", + "projectType": "application", + "tags": [], + "targets": { + "build": { + "executor": "@nx/next:build", + "defaultConfiguration": "production", + "options": { + "outputPath": "apps/next-app-router-4001" + }, + "configurations": { + "development": { + "outputPath": "apps/next-app-router-4001" + }, + "production": {} + }, + "dependsOn": [ + { + "target": "build", + "dependencies": true + } + ] + }, + "serve": { + "executor": "nx:run-commands", + "options": { + "command": "pnpm dev", + "cwd": "apps/next-app-router-4001" + }, + "dependsOn": [ + { + "target": "build", + "dependencies": true + } + ] + }, + "export": { + "executor": "@nx/next:export", + "options": { + "buildTarget": "next-app-router-4001:build:production" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/next-app-router-4001/**/*.{ts,tsx,js,jsx}"] + } + }, + "e2e": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/next-app-router-4001/cypress.config.ts", + "testingType": "e2e", + "baseUrl": "http://localhost:4001", + "key": "27e40c91-5ac3-4433-8a87-651d10f51cf6" + }, + "configurations": { + "production": { + "devServerTarget": "next-app-router-4001:serve:production" + } + } + }, + "test:e2e": { + "executor": "nx:run-commands", + "options": { + "parallel": true, + "commands": [ + { + "command": "lsof -i :4001 || nx run next-app-router-4001:serve", + "forwardAllArgs": false + }, + { + "command": "sleep 4 && nx run next-app-router-4001:e2e", + "forwardAllArgs": true + } + ] + } + } + } +} diff --git a/apps/next-app-router/next-app-router-4001/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg b/apps/next-app-router/next-app-router-4001/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg new file mode 100644 index 00000000000..9d5daa0f5bd Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4001/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg b/apps/next-app-router/next-app-router-4001/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg new file mode 100644 index 00000000000..40f4ffd5c7f Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4001/public/grid.svg b/apps/next-app-router/next-app-router-4001/public/grid.svg new file mode 100644 index 00000000000..d467ad6de0d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/public/grid.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/next-app-router/next-app-router-4001/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg b/apps/next-app-router/next-app-router-4001/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg new file mode 100644 index 00000000000..527bbb514fc Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4001/public/nextjs-icon-light-background.png b/apps/next-app-router/next-app-router-4001/public/nextjs-icon-light-background.png new file mode 100644 index 00000000000..659139c1819 Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/public/nextjs-icon-light-background.png differ diff --git a/apps/next-app-router/next-app-router-4001/public/patrick-OIFgeLnjwrM-unsplash.jpg b/apps/next-app-router/next-app-router-4001/public/patrick-OIFgeLnjwrM-unsplash.jpg new file mode 100644 index 00000000000..e19a4a1bf82 Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/public/patrick-OIFgeLnjwrM-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4001/public/prince-akachi-LWkFHEGpleE-unsplash.jpg b/apps/next-app-router/next-app-router-4001/public/prince-akachi-LWkFHEGpleE-unsplash.jpg new file mode 100644 index 00000000000..146a680434d Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/public/prince-akachi-LWkFHEGpleE-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4001/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg b/apps/next-app-router/next-app-router-4001/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg new file mode 100644 index 00000000000..ca2d17463c5 Binary files /dev/null and b/apps/next-app-router/next-app-router-4001/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg differ diff --git a/apps/next-app-router/next-app-router-4001/readme.md b/apps/next-app-router/next-app-router-4001/readme.md new file mode 100644 index 00000000000..c6db1f9845e --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/readme.md @@ -0,0 +1,28 @@ +# Next.js App Router Playground + +Next.js recently introduced the App Router with support for: + +- **Layouts:** Easily share UI while preserving state and avoiding re-renders. +- **Server Components:** Making server-first the default for the most dynamic applications. +- **Streaming:** Display instant loading states and stream in updates. +- **Suspense for Data Fetching:** `async`/`await` support and the `use` hook for component-level fetching. + +The App Router can coexist with the existing `pages` directory for incremental adoption. While you **don't need to use the App Router** when upgrading to Next.js 13, we're laying the foundations to build complex interfaces while shipping less JavaScript. + +## Running Locally + +1. Install dependencies: + +```sh +pnpm install +``` + +2. Start the dev server: + +```sh +pnpm dev +``` + +## Documentation + +https://nextjs.org/docs diff --git a/apps/next-app-router/next-app-router-4001/styles/globals.css b/apps/next-app-router/next-app-router-4001/styles/globals.css new file mode 100644 index 00000000000..b5c61c95671 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/styles/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/apps/next-app-router/next-app-router-4001/tailwind.config.ts b/apps/next-app-router/next-app-router-4001/tailwind.config.ts new file mode 100644 index 00000000000..1dc84971594 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/tailwind.config.ts @@ -0,0 +1,90 @@ +import colors from 'tailwindcss/colors'; +import { Config } from 'tailwindcss'; + +export default { + content: [ + './app/**/*.{js,ts,jsx,tsx,mdx}', + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './ui/**/*.{js,ts,jsx,tsx,mdx}', + ], + future: { + hoverOnlyWhenSupported: true, + }, + darkMode: 'class', + theme: { + extend: { + // https://vercel.com/design/color + colors: { + gray: colors.zinc, + 'gray-1000': 'rgb(17,17,19)', + 'gray-1100': 'rgb(10,10,11)', + vercel: { + pink: '#FF0080', + blue: '#0070F3', + cyan: '#50E3C2', + orange: '#F5A623', + violet: '#7928CA', + }, + }, + backgroundImage: ({ theme }) => ({ + 'vc-border-gradient': `radial-gradient(at left top, ${theme( + 'colors.gray.500', + )}, 50px, ${theme('colors.gray.800')} 50%)`, + }), + keyframes: ({ theme }) => ({ + rerender: { + '0%': { + ['border-color']: theme('colors.vercel.pink'), + }, + '40%': { + ['border-color']: theme('colors.vercel.pink'), + }, + }, + highlight: { + '0%': { + background: theme('colors.vercel.pink'), + color: theme('colors.white'), + }, + '40%': { + background: theme('colors.vercel.pink'), + color: theme('colors.white'), + }, + }, + loading: { + '0%': { + opacity: '.2', + }, + '20%': { + opacity: '1', + transform: 'translateX(1px)', + }, + to: { + opacity: '.2', + }, + }, + shimmer: { + '100%': { + transform: 'translateX(100%)', + }, + }, + translateXReset: { + '100%': { + transform: 'translateX(0)', + }, + }, + fadeToTransparent: { + '0%': { + opacity: '1', + }, + '40%': { + opacity: '1', + }, + '100%': { + opacity: '0', + }, + }, + }), + }, + }, + plugins: [require('@tailwindcss/typography'), require('@tailwindcss/forms')], +} satisfies Config; diff --git a/apps/next-app-router/next-app-router-4001/tsconfig.json b/apps/next-app-router/next-app-router-4001/tsconfig.json new file mode 100644 index 00000000000..399d25eda35 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "baseUrl": ".", + "paths": { + "#/*": ["./*"] + }, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/apps/next-app-router/next-app-router-4001/ui/address-bar.tsx b/apps/next-app-router/next-app-router-4001/ui/address-bar.tsx new file mode 100644 index 00000000000..03ce8f4d941 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/address-bar.tsx @@ -0,0 +1,92 @@ +'use client'; + +import React, { Suspense } from 'react'; +import { usePathname, useSearchParams } from 'next/navigation'; + +function Params() { + const searchParams = useSearchParams()!; + + return searchParams.toString().length !== 0 ? ( +
+ ? + {Array.from(searchParams.entries()).map(([key, value], index) => { + return ( + + {index !== 0 ? & : null} + + + {key} + + = + + {value} + + + + ); + })} +
+ ) : null; +} + +export function AddressBar() { + const pathname = usePathname(); + + return ( +
+
+ + + +
+
+
+ acme.com +
+ {pathname ? ( + <> + / + {pathname + .split('/') + .slice(2) + .map((segment) => { + return ( + + + + {segment} + + + + / + + ); + })} + + ) : null} + + + + +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/boundary.tsx b/apps/next-app-router/next-app-router-4001/ui/boundary.tsx new file mode 100644 index 00000000000..fbc18226ac3 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/boundary.tsx @@ -0,0 +1,82 @@ +import clsx from 'clsx'; +import React from 'react'; + +const Label = ({ + children, + animateRerendering, + color, +}: { + children: React.ReactNode; + animateRerendering?: boolean; + color?: 'default' | 'pink' | 'blue' | 'violet' | 'cyan' | 'orange'; +}) => { + return ( +
+ {children} +
+ ); +}; +export const Boundary = ({ + children, + labels = ['children'], + size = 'default', + color = 'default', + animateRerendering = true, +}: { + children: React.ReactNode; + labels?: string[]; + size?: 'small' | 'default'; + color?: 'default' | 'pink' | 'blue' | 'violet' | 'cyan' | 'orange'; + animateRerendering?: boolean; +}) => { + return ( +
+
+ {labels.map((label) => { + return ( + + ); + })} +
+ + {children} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/buggy-button.tsx b/apps/next-app-router/next-app-router-4001/ui/buggy-button.tsx new file mode 100644 index 00000000000..b2190b2a2f9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/buggy-button.tsx @@ -0,0 +1,23 @@ +'use client'; + +import Button from '#/ui/button'; +import React from 'react'; + +export default function BuggyButton() { + const [clicked, setClicked] = React.useState(false); + + if (clicked) { + throw new Error('Oh no! Something went wrong.'); + } + + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/button.tsx b/apps/next-app-router/next-app-router-4001/ui/button.tsx new file mode 100644 index 00000000000..8aafa7e7a92 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/button.tsx @@ -0,0 +1,20 @@ +import clsx from 'clsx'; + +export default function Button({ + kind = 'default', + ...props +}: React.ButtonHTMLAttributes & { + kind?: 'default' | 'error'; +}) { + return ( + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/component-tree.tsx b/apps/next-app-router/next-app-router-4001/ui/component-tree.tsx new file mode 100644 index 00000000000..3f3e43ee353 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/component-tree.tsx @@ -0,0 +1,162 @@ +import { Boundary } from '#/ui/boundary'; +import CountUp from '#/ui/count-up'; +import clsx from 'clsx'; + +type Item = { + name: string; + type: 'server' | 'client'; + size: number; + children?: Item[]; +}; + +const List = ({ items, depth }: { items: Item[]; depth: number }) => { + return ( +
+ {items.map((item, i) => { + const isLast = i === items.length - 1; + + return ( +
+
+
+ {'<'} + {item.name} + {'>'} +
+ +
+ + {item.type === 'client' ? ( + item.size / 1000 + ) : ( + + )} + {' '} + KB +
+
+ + {item.children ? ( + + ) : null} +
+ ); + })} +
+ ); +}; + +// Calculate the total bundle size of a specific component type (client or +// server) in a tree +const sum = (items: Item[], componentType: Item['type']): number => + items.reduce( + (total, item) => + // running total + total + + // add the current component size if it's type is componentType + ((item.type === componentType ? item.size : 0) || 0) + + // add the total size of children components recursively + (item?.children ? sum(item.children, componentType) : 0), + 0, + ); + +export const ComponentTree = ({ items }: { items: Item[] }) => { + const clientTotal = sum(items, 'client'); + const serverTotal = sum(items, 'server'); + const clientDeltaAsPercent = Math.round( + (clientTotal / (clientTotal + serverTotal)) * 100, + ); + + return ( + +
+
+
+ +
+ +
+
+
+
+ {' '} + KB +
+
Bundle Size
+
+ +
+
+
+
+ +
+
+
+ {''} +
+
Client Component
+
+ +
+
+ {''} +
+
Server Component
+
+
+
+
+
+ Note: The component bundle sizes are not yet accurate. +
+
+ + ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/count-up.tsx b/apps/next-app-router/next-app-router-4001/ui/count-up.tsx new file mode 100644 index 00000000000..7a2cf99bb09 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/count-up.tsx @@ -0,0 +1,25 @@ +'use client'; + +import { useCountUp } from 'use-count-up'; + +const CountUp = ({ + start, + end, + duration = 1, +}: { + start: number; + end: number; + duration?: number; +}) => { + const { value } = useCountUp({ + isCounting: true, + end, + start, + duration, + decimalPlaces: 1, + }); + + return {value}; +}; + +export default CountUp; diff --git a/apps/next-app-router/next-app-router-4001/ui/external-link.tsx b/apps/next-app-router/next-app-router-4001/ui/external-link.tsx new file mode 100644 index 00000000000..662994170e0 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/external-link.tsx @@ -0,0 +1,20 @@ +import { ArrowRightIcon } from '@heroicons/react/24/outline'; + +export const ExternalLink = ({ + children, + href, +}: { + children: React.ReactNode; + href: string; +}) => { + return ( + +
{children}
+ + +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/footer.tsx b/apps/next-app-router/next-app-router-4001/ui/footer.tsx new file mode 100644 index 00000000000..3ac838b2f36 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/footer.tsx @@ -0,0 +1,41 @@ +'use client'; + +export default function Footer({ + reactVersion, + nextVersion, +}: { + reactVersion: string; + nextVersion: string; +}) { + return ( +
+ + + + Powered by + + + + + +
+
React: {reactVersion}
+
Next: {nextVersion}
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/global-nav.tsx b/apps/next-app-router/next-app-router-4001/ui/global-nav.tsx new file mode 100644 index 00000000000..5be9ca6ea55 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/global-nav.tsx @@ -0,0 +1,100 @@ +'use client'; + +import { demos, type Item } from '#/lib/demos'; +import { NextLogoDark } from '#/ui/next-logo'; +import Link from 'next/link'; +import { useSelectedLayoutSegment } from 'next/navigation'; +import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/solid'; +import clsx from 'clsx'; +import { useState } from 'react'; + +export function GlobalNav() { + const [isOpen, setIsOpen] = useState(false); + const close = () => setIsOpen(false); + + return ( +
+
+ +
+ +
+ +

+ App Router +

+ +
+ + +
+ +
+
+ ); +} + +function GlobalNavItem({ + item, + close, +}: { + item: Item; + close: () => false | void; +}) { + const segment = useSelectedLayoutSegment(); + const isActive = item.slug === segment; + + return ( + + {item.name} + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/header.tsx b/apps/next-app-router/next-app-router-4001/ui/header.tsx new file mode 100644 index 00000000000..8a7c055505a --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/header.tsx @@ -0,0 +1,43 @@ +'use client'; + +import styled from 'styled-components'; + +const HeadContainer = styled.header` + position: relative; + height: 64px; + align-items: center; + padding: 0px 8px; + margin-bottom: 48px; + display: flex; + border: 0 solid #e5e7eb; + color: rgb(244 244 245); + grid-column-start: 2; + grid-column-end: 4; +`; + +const Title = styled.span` + margin: 0 8px; +`; + +const NextJsLogo = (props: any) => ( + + + +); + +export default function Header() { + return ( + + + The React Framework + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/mobile-nav-toggle.tsx b/apps/next-app-router/next-app-router-4001/ui/mobile-nav-toggle.tsx new file mode 100644 index 00000000000..35d77f602a4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/mobile-nav-toggle.tsx @@ -0,0 +1,64 @@ +'use client'; + +import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/solid'; +import clsx from 'clsx'; +import React from 'react'; + +const MobileNavContext = React.createContext< + [boolean, React.Dispatch>] | undefined +>(undefined); + +export function MobileNavContextProvider({ + children, +}: { + children: React.ReactNode; +}) { + const [isOpen, setIsOpen] = React.useState(false); + return ( + + {children} + + ); +} + +export function useMobileNavToggle() { + const context = React.useContext(MobileNavContext); + if (context === undefined) { + throw new Error( + 'useMobileNavToggle must be used within a MobileNavContextProvider', + ); + } + return context; +} + +export function MobileNavToggle({ children }: { children: React.ReactNode }) { + const [isOpen, setIsOpen] = useMobileNavToggle(); + + return ( + <> + + +
+ {children} +
+ + ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/next-logo.tsx b/apps/next-app-router/next-app-router-4001/ui/next-logo.tsx new file mode 100644 index 00000000000..69bec7145ce --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/next-logo.tsx @@ -0,0 +1,117 @@ +export function NextLogoLight() { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} + +export function NextLogoDark() { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/ping.tsx b/apps/next-app-router/next-app-router-4001/ui/ping.tsx new file mode 100644 index 00000000000..40768a77ec7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/ping.tsx @@ -0,0 +1,8 @@ +export function Ping() { + return ( + + + + + ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/product-best-seller.tsx b/apps/next-app-router/next-app-router-4001/ui/product-best-seller.tsx new file mode 100644 index 00000000000..d6e10134705 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-best-seller.tsx @@ -0,0 +1,7 @@ +export const ProductBestSeller = () => { + return ( +
+ Best Seller +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-card.tsx b/apps/next-app-router/next-app-router-4001/ui/product-card.tsx new file mode 100644 index 00000000000..d10188de451 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-card.tsx @@ -0,0 +1,63 @@ +import { Product } from '#/app/api/products/product'; +import { ProductBestSeller } from '#/ui/product-best-seller'; +import { ProductEstimatedArrival } from '#/ui/product-estimated-arrival'; +import { ProductLowStockWarning } from '#/ui/product-low-stock-warning'; +import { ProductPrice } from '#/ui/product-price'; +import { ProductRating } from '#/ui/product-rating'; +import { ProductUsedPrice } from '#/ui/product-used-price'; +import { dinero, type DineroSnapshot } from 'dinero.js'; +import Image from 'next/image'; +import Link from 'next/link'; + +export const ProductCard = ({ + product, + href, +}: { + product: Product; + href: string; +}) => { + const price = dinero(product.price as DineroSnapshot); + + return ( + +
+
+ {product.isBestSeller ? ( +
+ +
+ ) : null} + {product.name} +
+ +
+ {product.name} +
+ + {product.rating ? : null} + + + + {/* */} + + {product.usedPrice ? ( + + ) : null} + + + + {product.stock <= 1 ? ( + + ) : null} +
+ + ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-currency-symbol.tsx b/apps/next-app-router/next-app-router-4001/ui/product-currency-symbol.tsx new file mode 100644 index 00000000000..b9d60ace40d --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-currency-symbol.tsx @@ -0,0 +1,27 @@ +import { toFormat, type Dinero } from 'dinero.js'; + +export const ProductCurrencySymbol = ({ + dinero, +}: { + dinero: Dinero; +}) => { + let symbol = ''; + switch (toFormat(dinero, ({ currency }) => currency.code)) { + case 'GBP': { + symbol = '£'; + break; + } + + case 'EUR': { + symbol = '€'; + break; + } + + default: { + symbol = '$'; + break; + } + } + + return <>{symbol}; +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-deal.tsx b/apps/next-app-router/next-app-router-4001/ui/product-deal.tsx new file mode 100644 index 00000000000..981dfb1f39f --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-deal.tsx @@ -0,0 +1,36 @@ +import { ProductCurrencySymbol } from '#/ui/product-currency-symbol'; +import { toUnit, type Dinero } from 'dinero.js'; + +export const ProductDeal = ({ + price: priceRaw, + discount: discountRaw, +}: { + price: Dinero; + discount: { + amount: Dinero; + }; +}) => { + const discount = toUnit(discountRaw.amount); + const price = toUnit(priceRaw); + const percent = Math.round(100 - (discount / price) * 100); + + return ( +
+
+ -{percent}% +
+
+
+ +
+
+ {discount} +
+
+
+ + {price} +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-estimated-arrival.tsx b/apps/next-app-router/next-app-router-4001/ui/product-estimated-arrival.tsx new file mode 100644 index 00000000000..1b236d4dd41 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-estimated-arrival.tsx @@ -0,0 +1,24 @@ +import { add, format, isTomorrow } from 'date-fns'; + +export const ProductEstimatedArrival = ({ + leadTime, + hasDeliveryTime = false, +}: { + leadTime: number; + hasDeliveryTime?: boolean; +}) => { + const date = add(new Date(), { + days: leadTime, + }); + + return ( +
+ Get it{' '} + + {isTomorrow(date) ? 'tomorrow, ' : null} + {format(date, 'MMM d')} + + {hasDeliveryTime ? <> by 5pm : null} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-lightening-deal.tsx b/apps/next-app-router/next-app-router-4001/ui/product-lightening-deal.tsx new file mode 100644 index 00000000000..d316d020757 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-lightening-deal.tsx @@ -0,0 +1,28 @@ +import { ProductDeal } from '#/ui/product-deal'; +import { add, formatDistanceToNow } from 'date-fns'; +import { type Dinero } from 'dinero.js'; + +export const ProductLighteningDeal = ({ + price, + discount, +}: { + price: Dinero; + discount: { + amount: Dinero; + expires?: number; + }; +}) => { + const date = add(new Date(), { days: discount.expires }); + + return ( + <> +
+
+ Expires in {formatDistanceToNow(date)} +
+
+ + + + ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-low-stock-warning.tsx b/apps/next-app-router/next-app-router-4001/ui/product-low-stock-warning.tsx new file mode 100644 index 00000000000..26ac0d5e626 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-low-stock-warning.tsx @@ -0,0 +1,13 @@ +export const ProductLowStockWarning = ({ stock }: { stock: number }) => { + if (stock > 3) { + return null; + } + + if (stock === 0) { + return
Out of stock
; + } + + return ( +
Only {stock} left in stock
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-price.tsx b/apps/next-app-router/next-app-router-4001/ui/product-price.tsx new file mode 100644 index 00000000000..597086e5f74 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-price.tsx @@ -0,0 +1,52 @@ +import { Product } from '#/app/api/products/product'; +import { ProductCurrencySymbol } from '#/ui/product-currency-symbol'; +import { ProductDeal } from '#/ui/product-deal'; +import { ProductLighteningDeal } from '#/ui/product-lightening-deal'; +import { multiply, toUnit, type Dinero } from 'dinero.js'; + +function isDiscount(obj: any): obj is { percent: number; expires?: number } { + return typeof obj?.percent === 'number'; +} + +function formatDiscount( + price: Dinero, + discountRaw: Product['discount'], +) { + return isDiscount(discountRaw) + ? { + amount: multiply(price, { + amount: discountRaw.percent, + scale: 2, + }), + expires: discountRaw.expires, + } + : undefined; +} + +export const ProductPrice = ({ + price, + discount: discountRaw, +}: { + price: Dinero; + discount: Product['discount']; +}) => { + const discount = formatDiscount(price, discountRaw); + + if (discount) { + if (discount?.expires && typeof discount.expires === 'number') { + return ; + } + return ; + } + + return ( +
+
+ +
+
+ {toUnit(price)} +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-rating.tsx b/apps/next-app-router/next-app-router-4001/ui/product-rating.tsx new file mode 100644 index 00000000000..cc37450378c --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-rating.tsx @@ -0,0 +1,17 @@ +import { StarIcon } from '@heroicons/react/24/solid'; +import clsx from 'clsx'; + +export const ProductRating = ({ rating }: { rating: number }) => { + return ( +
+ {Array.from({ length: 5 }).map((_, i) => { + return ( + + ); + })} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-review-card.tsx b/apps/next-app-router/next-app-router-4001/ui/product-review-card.tsx new file mode 100644 index 00000000000..0dae85c2dbb --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-review-card.tsx @@ -0,0 +1,19 @@ +import type { Review } from '#/app/api/reviews/review'; +import { ProductRating } from '#/ui/product-rating'; + +export const ProductReviewCard = ({ review }: { review: Review }) => { + return ( +
+
+
+
+
{review.name}
+
+ + {review.rating ? : null} +
+ +
{review.text}
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-split-payments.tsx b/apps/next-app-router/next-app-router-4001/ui/product-split-payments.tsx new file mode 100644 index 00000000000..b1248cc5a8b --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-split-payments.tsx @@ -0,0 +1,17 @@ +import { ProductCurrencySymbol } from '#/ui/product-currency-symbol'; +import { allocate, toUnit, up, type Dinero } from 'dinero.js'; + +export const ProductSplitPayments = ({ price }: { price: Dinero }) => { + // only offer split payments for more expensive items + if (toUnit(price) < 150) { + return null; + } + + const [perMonth] = allocate(price, [1, 2]); + return ( +
+ Or + {toUnit(perMonth, { digits: 0, round: up })}/month for 3 months +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/product-used-price.tsx b/apps/next-app-router/next-app-router-4001/ui/product-used-price.tsx new file mode 100644 index 00000000000..db57ed0e65f --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/product-used-price.tsx @@ -0,0 +1,19 @@ +import { Product } from '#/app/api/products/product'; +import { dinero, toUnit, up, type DineroSnapshot } from 'dinero.js'; + +export const ProductUsedPrice = ({ + usedPrice: usedPriceRaw, +}: { + usedPrice: Product['usedPrice']; +}) => { + const usedPrice = dinero(usedPriceRaw as DineroSnapshot); + + return ( +
+
More buying choices
+
+ ${toUnit(usedPrice, { digits: 0, round: up })} (used) +
+
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/rendered-time-ago.tsx b/apps/next-app-router/next-app-router-4001/ui/rendered-time-ago.tsx new file mode 100644 index 00000000000..d7c78d1c6b8 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/rendered-time-ago.tsx @@ -0,0 +1,56 @@ +'use client'; + +import ms from 'ms'; +import { useEffect, useRef, useState } from 'react'; + +// https://github.com/streamich/react-use/blob/master/src/useInterval.ts +const useInterval = (callback: Function, delay?: number | null) => { + const savedCallback = useRef(() => {}); + + useEffect(() => { + savedCallback.current = callback; + }); + + useEffect(() => { + if (delay !== null) { + const interval = setInterval(() => savedCallback.current(), delay || 0); + return () => clearInterval(interval); + } + + return undefined; + }, [delay]); +}; + +export function RenderedTimeAgo({ timestamp }: { timestamp: number }) { + const [msAgo, setMsAgo] = useState(0); + + // update on page change + useEffect(() => { + setMsAgo(Date.now() - timestamp); + }, [timestamp]); + + // update every second + useInterval(() => { + setMsAgo(Date.now() - timestamp); + }, 1000); + + return ( +
+ {msAgo ? ( + <> + + {msAgo >= 1000 ? ms(msAgo) : '0s'} + {' '} + ago + + ) : null} +
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/rendering-info.tsx b/apps/next-app-router/next-app-router-4001/ui/rendering-info.tsx new file mode 100644 index 00000000000..3048985b506 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/rendering-info.tsx @@ -0,0 +1,34 @@ +import { RenderedTimeAgo } from '#/ui/rendered-time-ago'; + +export function RenderingInfo({ + type, +}: { + type: 'ssg' | 'ssgod' | 'ssr' | 'isr'; +}) { + let msg = ''; + switch (type) { + case 'ssg': + msg = 'Statically pre-rendered at build time'; + break; + case 'ssgod': + msg = 'Statically rendered on demand'; + break; + case 'isr': + msg = + 'Statically pre-rendered at build time and periodically revalidated'; + break; + case 'ssr': + msg = 'Dynamically rendered at request time'; + break; + } + + return ( +
+
{msg}
+ +
+ +
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/rendering-page-skeleton.tsx b/apps/next-app-router/next-app-router-4001/ui/rendering-page-skeleton.tsx new file mode 100644 index 00000000000..ae8225a0cc9 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/rendering-page-skeleton.tsx @@ -0,0 +1,18 @@ +const shimmer = `relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_1.5s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent`; + +export function RenderingPageSkeleton() { + return ( +
+
+
+
+
+
+
+
+
+
+
+
+ ); +} diff --git a/apps/next-app-router/next-app-router-4001/ui/section-link.tsx b/apps/next-app-router/next-app-router-4001/ui/section-link.tsx new file mode 100644 index 00000000000..48f4b2edda4 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/section-link.tsx @@ -0,0 +1,18 @@ +import Link from 'next/link'; + +export const SectionLink = ({ + children, + href, + text, +}: { + children: React.ReactNode; + href: string; + text: string; +}) => ( + +
+ {children} +
+
{text}
+ +); diff --git a/apps/next-app-router/next-app-router-4001/ui/skeleton-card.tsx b/apps/next-app-router/next-app-router-4001/ui/skeleton-card.tsx new file mode 100644 index 00000000000..09e205e6f72 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/skeleton-card.tsx @@ -0,0 +1,16 @@ +import clsx from 'clsx'; + +export const SkeletonCard = ({ isLoading }: { isLoading?: boolean }) => ( +
+
+
+
+
+
+
+); diff --git a/apps/next-app-router/next-app-router-4001/ui/tab-group.tsx b/apps/next-app-router/next-app-router-4001/ui/tab-group.tsx new file mode 100644 index 00000000000..fb20c54f07b --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/tab-group.tsx @@ -0,0 +1,31 @@ +import { Tab } from '#/ui/tab'; + +export type Item = { + text: string; + slug?: string; + segment?: string; + parallelRoutesKey?: string; +}; + +export const TabGroup = ({ + path, + parallelRoutesKey, + items, +}: { + path: string; + parallelRoutesKey?: string; + items: Item[]; +}) => { + return ( +
+ {items.map((item) => ( + + ))} +
+ ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/tab-nav-item.tsx b/apps/next-app-router/next-app-router-4001/ui/tab-nav-item.tsx new file mode 100644 index 00000000000..ad0b10e09e7 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/tab-nav-item.tsx @@ -0,0 +1,25 @@ +import clsx from 'clsx'; +import Link from 'next/link'; + +export const TabNavItem = ({ + children, + href, + isActive, +}: { + children: React.ReactNode; + href: string; + isActive?: boolean; +}) => { + return ( + + {children} + + ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/tab.tsx b/apps/next-app-router/next-app-router-4001/ui/tab.tsx new file mode 100644 index 00000000000..9fa051cb726 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/tab.tsx @@ -0,0 +1,39 @@ +'use client'; + +import type { Item } from '#/ui/tab-group'; +import clsx from 'clsx'; +import Link from 'next/link'; +import { useSelectedLayoutSegment } from 'next/navigation'; + +export const Tab = ({ + path, + parallelRoutesKey, + item, +}: { + path: string; + parallelRoutesKey?: string; + item: Item; +}) => { + const segment = useSelectedLayoutSegment(parallelRoutesKey); + + const href = item.slug ? path + '/' + item.slug : path; + const isActive = + // Example home pages e.g. `/layouts` + (!item.slug && segment === null) || + segment === item.segment || + // Nested pages e.g. `/layouts/electronics` + segment === item.slug; + + return ( + + {item.text} + + ); +}; diff --git a/apps/next-app-router/next-app-router-4001/ui/vercel-logo.tsx b/apps/next-app-router/next-app-router-4001/ui/vercel-logo.tsx new file mode 100644 index 00000000000..6550d288430 --- /dev/null +++ b/apps/next-app-router/next-app-router-4001/ui/vercel-logo.tsx @@ -0,0 +1,11 @@ +export function VercelLogo() { + return ( + + + + ); +} diff --git a/squadron.yaml b/squadron.yaml deleted file mode 100644 index 82e262575a9..00000000000 --- a/squadron.yaml +++ /dev/null @@ -1,68 +0,0 @@ -projects: - - name: 'bridge' - path: 'packages/bridge' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'core' - path: 'packages/core' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'dts-plugin' - path: 'packages/dts-plugin' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'enhanced' - path: 'packages/enhanced' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'enhanced-rspack' - path: 'packages/enhanced-rspack' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'esbuild' - path: 'packages/esbuild' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'managers' - path: 'packages/managers' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'manifest' - path: 'packages/manifest' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'node' - path: 'packages/node' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'nextjs-mf' - path: 'packages/nextjs-mf' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'rspack' - path: 'packages/rspack' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'runtime' - path: 'packages/runtime' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' - - name: 'sdk' - path: 'packages/sdk' - pathFilters: - - '**/src/**/*.{ts,tsx}' - - '**/src/**/*.{js,jsx}' -experiments: - anthropic: true