├── .gitignore
├── .prettierrc
├── README.md
├── app
├── favicon.ico
├── layout.tsx
├── not-found.tsx
├── opengraph-image.png
├── page.tsx
├── styles.tsx
└── twitter-image.png
├── components
├── add-to-cart.tsx
├── byline.tsx
├── cart-count-context.tsx
├── cart-count.tsx
├── header.tsx
├── next-logo.tsx
├── ping.tsx
├── pricing.tsx
├── product-best-seller.tsx
├── product-card.tsx
├── product-currency-symbol.tsx
├── product-deal.tsx
├── product-estimated-arrival.tsx
├── product-lightening-deal.tsx
├── product-low-stock-warning.tsx
├── product-price.tsx
├── product-rating.tsx
├── product-review-card.tsx
├── product-split-payments.tsx
├── product-used-price.tsx
├── recommended-products.tsx
├── reviews.tsx
├── sidebar.tsx
├── single-product.tsx
└── vercel-logo.tsx
├── lib
└── delay.ts
├── next-env.d.ts
├── next.config.js
├── package.json
├── pnpm-lock.yaml
├── postcss.config.js
├── public
├── alexander-andrews-brAkTCdnhW8-unsplash.jpg
├── eniko-kis-KsLPTsYaqIQ-unsplash.jpg
├── grid.svg
├── guillaume-coupy-6HuoHgK7FN8-unsplash.jpg
├── nextjs-icon-light-background.png
├── patrick-OIFgeLnjwrM-unsplash.jpg
├── prince-akachi-LWkFHEGpleE-unsplash.jpg
└── yoann-siloine-_T4w3JDm6ug-unsplash.jpg
├── tailwind.config.ts
├── tsconfig.json
└── types
├── product.d.ts
└── review.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | /.yarn
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 | .pnpm-debug.log*
28 |
29 | # local env files
30 | .env*
31 | !.env*.example
32 |
33 | # vercel
34 | .vercel
35 |
36 | # typescript
37 | *.tsbuildinfo
38 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Next.js Partial Prerendering
2 |
3 | This is a demo of [Next.js](https://nextjs.org) using [Partial Prerendering](https://nextjs.org/docs/app/api-reference/next-config-js/ppr).
4 |
5 | This template uses the new Next.js [App Router](https://nextjs.org/docs/app). This includes support for enhanced layouts, colocation of components, tests, and styles, component-level data fetching, and more.
6 |
7 | It also uses the experimental Partial Prerendering feature available in Next.js 14. Partial Prerendering combines ultra-quick static edge delivery with fully dynamic capabilities and we believe it has the potential to [become the default rendering model for web applications](https://vercel.com/blog/partial-prerendering-with-next-js-creating-a-new-default-rendering-model), bringing together the best of static site generation and dynamic delivery.
8 |
9 | > ⚠️ Please note that PPR is an experimental technology that is not recommended for production. You may run into some DX issues, especially on larger code bases.
10 |
11 | ## How it works
12 |
13 | The index route `/` uses Partial Prerendering through:
14 |
15 | 1. Enabling the experimental flag in `next.config.js`.
16 |
17 | ```js
18 | experimental: {
19 | ppr: true,
20 | },
21 | ```
22 |
23 | 2. Using ` ` to wrap Dynamic content.
24 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/app/favicon.ico
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import { CartCountProvider } from "#/components/cart-count-context";
2 | import { Header } from "#/components/header";
3 | import { Sidebar } from "#/components/sidebar";
4 | import { Metadata } from "next";
5 | import { GlobalStyles } from "./styles";
6 |
7 | export const metadata: Metadata = {
8 | metadataBase: new URL("https://partialprerendering.com"),
9 | title: "Next.js Partial Prerendering",
10 | description: "A demo of Next.js using Partial Prerendering.",
11 | openGraph: {
12 | title: "Next.js Partial Prerendering",
13 | description: "A demo of Next.js using Partial Prerendering.",
14 | },
15 | twitter: {
16 | card: "summary_large_image",
17 | },
18 | };
19 |
20 | export default function RootLayout({
21 | children,
22 | }: {
23 | children: React.ReactNode;
24 | }) {
25 | return (
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | {children}
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | export default function NotFound() {
2 | return (
3 |
4 |
Not Found
5 |
Could not find requested resource
6 |
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/app/opengraph-image.png
--------------------------------------------------------------------------------
/app/page.tsx:
--------------------------------------------------------------------------------
1 | import { Suspense } from 'react';
2 | import {
3 | RecommendedProducts,
4 | RecommendedProductsSkeleton,
5 | } from '#/components/recommended-products';
6 | import { Reviews, ReviewsSkeleton } from '#/components/reviews';
7 | import { SingleProduct } from '#/components/single-product';
8 | import { Ping } from '#/components/ping';
9 |
10 | export default function Page() {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
}>
18 |
19 |
20 |
21 |
22 |
23 |
}>
24 |
25 |
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/app/styles.tsx:
--------------------------------------------------------------------------------
1 | export function GlobalStyles() {
2 | return (
3 |
8 | );
9 | }
10 |
11 | const styles = JSON.parse(
12 | "\"/*\\n! tailwindcss v3.4.5 | MIT License | https://tailwindcss.com\\n*/*,:after,:before{box-sizing:border-box;border:0 solid #e4e4e7}:after,:before{--tw-content:\\\"\\\"}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#a1a1aa}input::placeholder,textarea::placeholder{color:#a1a1aa}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],input:where(:not([type])),select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#71717a;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem;--tw-shadow:0 0 #0000}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,input:where(:not([type])):focus,select:focus,textarea:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:#2563eb}input::-moz-placeholder,textarea::-moz-placeholder{color:#71717a;opacity:1}input::placeholder,textarea::placeholder{color:#71717a;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-top:0;padding-bottom:0}select{background-image:url(\\\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2371717a' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e\\\");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple],[size]:where(select:not([size=\\\"1\\\"])){background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#71717a;border-width:1px;--tw-shadow:0 0 #0000}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}[type=checkbox]:checked,[type=radio]:checked{border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}[type=checkbox]:checked{background-image:url(\\\"data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e\\\")}@media (forced-colors:active){[type=checkbox]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=radio]:checked{background-image:url(\\\"data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e\\\")}@media (forced-colors:active){[type=radio]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=radio]:checked:focus,[type=radio]:checked:hover{border-color:transparent;background-color:currentColor}[type=checkbox]:indeterminate{background-image:url(\\\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e\\\");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}@media (forced-colors:active){[type=checkbox]:indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{border-color:transparent;background-color:currentColor}[type=file]{background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);text-decoration:underline;font-weight:500}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=\\\"1\\\"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{font-weight:400;color:var(--tw-prose-counters)}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.25em}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-style:italic;color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:\\\"\\\\201C\\\"\\\"\\\\201D\\\"\\\"\\\\2018\\\"\\\"\\\\2019\\\";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:900;color:inherit}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:800;color:inherit}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:700;color:inherit}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){display:block;margin-top:2em;margin-bottom:2em}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:500;font-family:inherit;color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);font-size:.875em;border-radius:.3125rem;padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;padding-inline-start:.375em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-weight:600;font-size:.875em}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:\\\"`\\\"}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:\\\"`\\\"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);overflow-x:auto;font-weight:400;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding-top:.8571429em;padding-inline-end:1.1428571em;padding-bottom:.8571429em;padding-inline-start:1.1428571em}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){width:100%;table-layout:auto;text-align:start;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:600;vertical-align:bottom;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose{--tw-prose-body:#374151;--tw-prose-headings:#111827;--tw-prose-lead:#4b5563;--tw-prose-links:#111827;--tw-prose-bold:#111827;--tw-prose-counters:#6b7280;--tw-prose-bullets:#d1d5db;--tw-prose-hr:#e5e7eb;--tw-prose-quotes:#111827;--tw-prose-quote-borders:#e5e7eb;--tw-prose-captions:#6b7280;--tw-prose-kbd:#111827;--tw-prose-kbd-shadows:17 24 39;--tw-prose-code:#111827;--tw-prose-pre-code:#e5e7eb;--tw-prose-pre-bg:#1f2937;--tw-prose-th-borders:#d1d5db;--tw-prose-td-borders:#e5e7eb;--tw-prose-invert-body:#d1d5db;--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:#9ca3af;--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:#9ca3af;--tw-prose-invert-bullets:#4b5563;--tw-prose-invert-hr:#374151;--tw-prose-invert-quotes:#f3f4f6;--tw-prose-invert-quote-borders:#374151;--tw-prose-invert-captions:#9ca3af;--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:#d1d5db;--tw-prose-invert-pre-bg:rgba(0,0,0,.5);--tw-prose-invert-th-borders:#4b5563;--tw-prose-invert-td-borders:#374151;font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.5714286em;padding-inline-end:.5714286em;padding-bottom:.5714286em;padding-inline-start:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-sm{font-size:.875rem;line-height:1.7142857}.prose-sm :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.2857143em;line-height:1.5555556;margin-top:.8888889em;margin-bottom:.8888889em}.prose-sm :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.3333333em;margin-bottom:1.3333333em;padding-inline-start:1.1111111em}.prose-sm :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:2.1428571em;margin-top:0;margin-bottom:.8em;line-height:1.2}.prose-sm :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.4285714em;margin-top:1.6em;margin-bottom:.8em;line-height:1.4}.prose-sm :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:1.2857143em;margin-top:1.5555556em;margin-bottom:.4444444em;line-height:1.5555556}.prose-sm :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.4285714em;margin-bottom:.5714286em;line-height:1.4285714}.prose-sm :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;border-radius:.3125rem;padding-top:.1428571em;padding-inline-end:.3571429em;padding-bottom:.1428571em;padding-inline-start:.3571429em}.prose-sm :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em}.prose-sm :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.9em}.prose-sm :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8888889em}.prose-sm :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.6666667;margin-top:1.6666667em;margin-bottom:1.6666667em;border-radius:.25rem;padding-top:.6666667em;padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em;padding-inline-start:1.5714286em}.prose-sm :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em;padding-inline-start:1.5714286em}.prose-sm :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.2857143em;margin-bottom:.2857143em}.prose-sm :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.4285714em}.prose-sm :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.4285714em}.prose-sm :where(.prose-sm>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm :where(.prose-sm>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(.prose-sm>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.1428571em}.prose-sm :where(.prose-sm>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(.prose-sm>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.1428571em}.prose-sm :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.1428571em}.prose-sm :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.2857143em;padding-inline-start:1.5714286em}.prose-sm :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2.8571429em;margin-bottom:2.8571429em}.prose-sm :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.5}.prose-sm :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.6666667em;padding-inline-end:1em;padding-bottom:.6666667em;padding-inline-start:1em}.prose-sm :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.8571429em;line-height:1.3333333;margin-top:.6666667em}.prose-sm :where(.prose-sm>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(.prose-sm>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-invert{--tw-prose-body:var(--tw-prose-invert-body);--tw-prose-headings:var(--tw-prose-invert-headings);--tw-prose-lead:var(--tw-prose-invert-lead);--tw-prose-links:var(--tw-prose-invert-links);--tw-prose-bold:var(--tw-prose-invert-bold);--tw-prose-counters:var(--tw-prose-invert-counters);--tw-prose-bullets:var(--tw-prose-invert-bullets);--tw-prose-hr:var(--tw-prose-invert-hr);--tw-prose-quotes:var(--tw-prose-invert-quotes);--tw-prose-quote-borders:var(--tw-prose-invert-quote-borders);--tw-prose-captions:var(--tw-prose-invert-captions);--tw-prose-kbd:var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows:var(--tw-prose-invert-kbd-shadows);--tw-prose-code:var(--tw-prose-invert-code);--tw-prose-pre-code:var(--tw-prose-invert-pre-code);--tw-prose-pre-bg:var(--tw-prose-invert-pre-bg);--tw-prose-th-borders:var(--tw-prose-invert-th-borders);--tw-prose-td-borders:var(--tw-prose-invert-td-borders)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.-left-4{left:-1rem}.-right-1{right:-.25rem}.-top-1{top:-.25rem}.bottom-0{bottom:0}.bottom-3{bottom:.75rem}.left-0{left:0}.left-2{left:.5rem}.right-0{right:0}.right-2{right:.5rem}.top-0{top:0}.top-1{top:.25rem}.top-1\\\\.5{top:.375rem}.top-14{top:3.5rem}.top-2{top:.5rem}.z-10{z-index:10}.z-20{z-index:20}.col-span-2{grid-column:span 2/span 2}.col-span-4{grid-column:span 4/span 4}.col-span-full{grid-column:1/-1}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-px{margin-top:1px}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-\\\\[11px\\\\]{height:11px}.h-\\\\[167px\\\\]{height:167px}.h-full{height:100%}.w-1\\\\/2{width:50%}.w-1\\\\/3{width:33.333333%}.w-1\\\\/6{width:16.666667%}.w-10{width:2.5rem}.w-16{width:4rem}.w-2\\\\/5{width:40%}.w-2\\\\/6{width:33.333333%}.w-4{width:1rem}.w-4\\\\/6{width:66.666667%}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-\\\\[11px\\\\]{width:11px}.w-full{width:100%}.max-w-4xl{max-width:56rem}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.animate-\\\\[loading_1\\\\.4s_ease-in-out_0\\\\.2s_infinite\\\\]{animation:loading 1.4s ease-in-out .2s infinite}.animate-\\\\[loading_1\\\\.4s_ease-in-out_0\\\\.4s_infinite\\\\]{animation:loading 1.4s ease-in-out .4s infinite}@keyframes loading{0%{opacity:.2}20%{opacity:1;transform:translateX(1px)}to{opacity:.2}}.animate-\\\\[loading_1\\\\.4s_ease-in-out_infinite\\\\]{animation:loading 1.4s ease-in-out infinite}@keyframes ping{75%,to{transform:scale(2);opacity:0}}.animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-6{gap:1.5rem}.gap-x-1{-moz-column-gap:.25rem;column-gap:.25rem}.gap-x-1\\\\.5{-moz-column-gap:.375rem;column-gap:.375rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-2\\\\.5{-moz-column-gap:.625rem;column-gap:.625rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.space-x-0\\\\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.125rem * var(--tw-space-x-reverse));margin-left:calc(.125rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.5rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-scroll{overflow-y:scroll}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-\\\\[3px\\\\]{border-width:3px}.border-b{border-bottom-width:1px}.border-none{border-style:none}.border-gray-800{--tw-border-opacity:1;border-color:rgb(39 39 42/var(--tw-border-opacity))}.border-white{--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}.border-white\\\\/30{border-color:hsla(0,0%,100%,.3)}.border-r-transparent{border-right-color:transparent}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-gray-1100{--tw-bg-opacity:1;background-color:rgb(10 10 11/var(--tw-bg-opacity))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(82 82 91/var(--tw-bg-opacity))}.bg-gray-700{--tw-bg-opacity:1;background-color:rgb(63 63 70/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(39 39 42/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity))}.bg-vercel-blue{--tw-bg-opacity:1;background-color:rgb(0 112 243/var(--tw-bg-opacity))}.bg-vercel-cyan{--tw-bg-opacity:1;background-color:rgb(80 227 194/var(--tw-bg-opacity))}.bg-vercel-pink{--tw-bg-opacity:1;background-color:rgb(255 0 128/var(--tw-bg-opacity))}.bg-\\\\[url\\\\(\\\\'\\\\/grid\\\\.svg\\\\'\\\\)\\\\]{background-image:url(/grid.svg)}.bg-vc-border-gradient{background-image:radial-gradient(at left top,#71717a,50px,#27272a 50%)}.p-3{padding:.75rem}.p-3\\\\.5{padding:.875rem}.p-px{padding:1px}.px-1\\\\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-20{padding-bottom:5rem}.pb-36{padding-bottom:9rem}.pb-\\\\[5px\\\\]{padding-bottom:5px}.pl-10{padding-left:2.5rem}.pl-3{padding-left:.75rem}.pt-20{padding-top:5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-5{line-height:1.25rem}.leading-snug{line-height:1.375}.tracking-wide{letter-spacing:.025em}.text-cyan-800{--tw-text-opacity:1;color:rgb(21 94 117/var(--tw-text-opacity))}.text-gray-100{--tw-text-opacity:1;color:rgb(244 244 245/var(--tw-text-opacity))}.text-gray-200{--tw-text-opacity:1;color:rgb(228 228 231/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(212 212 216/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity))}.text-vercel-cyan{--tw-text-opacity:1;color:rgb(80 227 194/var(--tw-text-opacity))}.text-vercel-pink{--tw-text-opacity:1;color:rgb(255 0 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.decoration-dotted{text-decoration-style:dotted}.underline-offset-4{text-underline-offset:4px}.opacity-75{opacity:.75}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-black\\\\/20{--tw-shadow-color:rgba(0,0,0,.2);--tw-shadow:var(--tw-shadow-colored)}.blur{--tw-blur:blur(8px)}.blur,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.\\\\[color-scheme\\\\:dark\\\\]{color-scheme:dark}.before\\\\:absolute:before{content:var(--tw-content);position:absolute}.before\\\\:inset-0:before{content:var(--tw-content);inset:0}.before\\\\:-translate-x-full:before{content:var(--tw-content);--tw-translate-x:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes shimmer{to{content:var(--tw-content);transform:translateX(100%)}}.before\\\\:animate-\\\\[shimmer_1\\\\.5s_infinite\\\\]:before{content:var(--tw-content);animation:shimmer 1.5s infinite}.before\\\\:bg-gradient-to-r:before{content:var(--tw-content);background-image:linear-gradient(to right,var(--tw-gradient-stops))}.before\\\\:from-transparent:before{content:var(--tw-content);--tw-gradient-from:transparent var(--tw-gradient-from-position);--tw-gradient-to:transparent var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.before\\\\:via-white\\\\/10:before{content:var(--tw-content);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),hsla(0,0%,100%,.1) var(--tw-gradient-via-position),var(--tw-gradient-to)}.before\\\\:to-transparent:before{content:var(--tw-content);--tw-gradient-to:transparent var(--tw-gradient-to-position)}@media (hover:hover) and (pointer:fine){.hover\\\\:bg-vercel-blue\\\\/90:hover{background-color:rgba(0,112,243,.9)}.hover\\\\:text-gray-300:hover{--tw-text-opacity:1;color:rgb(212 212 216/var(--tw-text-opacity))}.hover\\\\:text-gray-50:hover{--tw-text-opacity:1;color:rgb(250 250 250/var(--tw-text-opacity))}.hover\\\\:opacity-70:hover{opacity:.7}}.focus\\\\:border-vercel-pink:focus{--tw-border-opacity:1;border-color:rgb(255 0 128/var(--tw-border-opacity))}.focus\\\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\\\:ring-vercel-pink:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(255 0 128/var(--tw-ring-opacity))}.disabled\\\\:text-white\\\\/70:disabled{color:hsla(0,0%,100%,.7)}@media (hover:hover) and (pointer:fine){.group:hover .group-hover\\\\:text-gray-400{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity))}.group:hover .group-hover\\\\:text-vercel-cyan{--tw-text-opacity:1;color:rgb(80 227 194/var(--tw-text-opacity))}.group:hover .group-hover\\\\:opacity-80{opacity:.8}}@media (min-width:640px){.sm\\\\:block{display:block}}@media (min-width:768px){.md\\\\:order-1{order:1}.md\\\\:order-2{order:2}.md\\\\:order-3{order:3}.md\\\\:col-span-1{grid-column:span 1/span 1}.md\\\\:col-span-2{grid-column:span 2/span 2}}@media (min-width:1024px){.lg\\\\:static{position:static}.lg\\\\:bottom-0{bottom:0}.lg\\\\:z-auto{z-index:auto}.lg\\\\:col-span-1{grid-column:span 1/span 1}.lg\\\\:block{display:block}.lg\\\\:hidden{display:none}.lg\\\\:h-auto{height:auto}.lg\\\\:w-72{width:18rem}.lg\\\\:space-y-14>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(3.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(3.5rem * var(--tw-space-y-reverse))}.lg\\\\:border-b-0{border-bottom-width:0}.lg\\\\:border-r{border-right-width:1px}.lg\\\\:border-gray-800{--tw-border-opacity:1;border-color:rgb(39 39 42/var(--tw-border-opacity))}.lg\\\\:p-6{padding:1.5rem}.lg\\\\:px-5{padding-left:1.25rem;padding-right:1.25rem}.lg\\\\:px-8{padding-left:2rem;padding-right:2rem}.lg\\\\:py-3{padding-top:.75rem;padding-bottom:.75rem}.lg\\\\:py-4{padding-top:1rem;padding-bottom:1rem}.lg\\\\:py-8{padding-top:2rem;padding-bottom:2rem}.lg\\\\:pl-72{padding-left:18rem}.lg\\\\:text-2xl{font-size:1.5rem;line-height:2rem}}\""
13 | );
14 |
--------------------------------------------------------------------------------
/app/twitter-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/app/twitter-image.png
--------------------------------------------------------------------------------
/components/add-to-cart.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useRouter } from 'next/navigation';
4 | import { useTransition } from 'react';
5 | import { useCartCount } from '#/components/cart-count-context';
6 |
7 | export function AddToCart({ initialCartCount }: { initialCartCount: number }) {
8 | const router = useRouter();
9 | const [isPending, startTransition] = useTransition();
10 |
11 | const [, setOptimisticCartCount] = useCartCount(initialCartCount);
12 |
13 | const addToCart = () => {
14 | setOptimisticCartCount(initialCartCount + 1);
15 |
16 | // update the cart count cookie
17 | document.cookie = `_cart_count=${initialCartCount + 1}; path=/; max-age=${
18 | 60 * 60 * 24 * 30
19 | }};`;
20 |
21 | // Normally you would also send a request to the server to add the item
22 | // to the current users cart
23 | // await fetch(`https://api.acme.com/...`);
24 |
25 | // Use a transition and isPending to create inline loading UI
26 | startTransition(() => {
27 | setOptimisticCartCount(null);
28 |
29 | // Refresh the current route and fetch new data from the server without
30 | // losing client-side browser or React state.
31 | router.refresh();
32 |
33 | // We're working on more fine-grained data mutation and revalidation:
34 | // https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
35 | });
36 | };
37 |
38 | return (
39 |
44 | Add to Cart
45 | {isPending ? (
46 |
47 |
51 |
Loading...
52 |
53 | ) : null}
54 |
55 | );
56 | }
57 |
--------------------------------------------------------------------------------
/components/byline.tsx:
--------------------------------------------------------------------------------
1 | import { VercelLogo } from '#/components/vercel-logo';
2 |
3 | export default function Byline({ className }: { className: string }) {
4 | return (
5 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/components/cart-count-context.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import React, { useState } from 'react';
4 |
5 | const CartCountContext = React.createContext<
6 | | [null | number, React.Dispatch>]
7 | | undefined
8 | >(undefined);
9 |
10 | export function CartCountProvider({ children }: { children: React.ReactNode }) {
11 | const [optimisticCartCount, setOptimisticCartCount] = useState(
12 | null,
13 | );
14 |
15 | return (
16 |
19 | {children}
20 |
21 | );
22 | }
23 |
24 | export function useCartCount(
25 | initialCount: number,
26 | ): [null | number, React.Dispatch>] {
27 | const context = React.useContext(CartCountContext);
28 | if (context === undefined) {
29 | throw new Error('useCartCount must be used within a CartCountProvider');
30 | }
31 | if (context[0] === null) {
32 | return [initialCount, context[1]];
33 | }
34 | return context;
35 | }
36 |
--------------------------------------------------------------------------------
/components/cart-count.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useCartCount } from '#/components/cart-count-context';
4 |
5 | export function CartCount({ initialCartCount }: { initialCartCount: number }) {
6 | const [count] = useCartCount(initialCartCount);
7 | return {count} ;
8 | }
9 |
--------------------------------------------------------------------------------
/components/header.tsx:
--------------------------------------------------------------------------------
1 | import { NextLogo } from '#/components/next-logo';
2 | import {
3 | MagnifyingGlassIcon,
4 | ShoppingCartIcon,
5 | } from '@heroicons/react/24/solid';
6 | import Image from 'next/image';
7 | import { CartCount } from '#/components/cart-count';
8 | import { cookies } from 'next/headers';
9 | import { Suspense } from 'react';
10 |
11 | async function CartCountFromCookies() {
12 | const cartCount = Number(cookies().get('_cart_count')?.value || '0');
13 | return ;
14 | }
15 |
16 | export function Header() {
17 | return (
18 |
19 |
20 |
21 |
22 |
23 |
24 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | }>
44 |
45 |
46 |
47 |
48 |
49 |
57 |
58 |
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/components/next-logo.tsx:
--------------------------------------------------------------------------------
1 | export function NextLogo() {
2 | return (
3 |
4 |
12 |
13 |
14 |
15 |
16 |
20 |
27 |
28 |
29 |
37 |
38 |
39 |
40 |
48 |
49 |
50 |
51 |
52 |
53 | );
54 | }
55 |
--------------------------------------------------------------------------------
/components/ping.tsx:
--------------------------------------------------------------------------------
1 | export function Ping() {
2 | return (
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/components/pricing.tsx:
--------------------------------------------------------------------------------
1 | import type { Product } from '#/types/product';
2 | import { Ping } from '#/components/ping';
3 | import { ProductEstimatedArrival } from '#/components/product-estimated-arrival';
4 | import { ProductLowStockWarning } from '#/components/product-low-stock-warning';
5 | import { ProductPrice } from '#/components/product-price';
6 | import { ProductSplitPayments } from '#/components/product-split-payments';
7 | import { ProductUsedPrice } from '#/components/product-used-price';
8 | import { dinero, type DineroSnapshot } from 'dinero.js';
9 | import { Suspense } from 'react';
10 | import { AddToCart } from '#/components/add-to-cart';
11 | import { delayShippingEstimate, withDelay } from '#/lib/delay';
12 | import { cookies } from 'next/headers';
13 |
14 | async function AddToCartFromCookies() {
15 | // Get the cart count from the users cookies and pass it to the client
16 | // AddToCart component
17 | const cartCount = Number(cookies().get('_cart_count')?.value || '0');
18 | return ;
19 | }
20 |
21 | function LoadingDots() {
22 | return (
23 |
24 |
25 |
26 | •
27 |
28 |
29 | •
30 |
31 |
32 | •
33 |
34 |
35 |
36 | );
37 | }
38 |
39 | async function UserSpecificDetails({ productId }: { productId: string }) {
40 | const data = await withDelay(
41 | fetch(
42 | `https://app-router-api.vercel.app/api/products?id=${productId}&filter=price,usedPrice,leadTime,stock`,
43 | {
44 | // We intentionally disable Next.js Cache to better demo
45 | // streaming
46 | cache: 'no-store',
47 | }
48 | ),
49 | delayShippingEstimate
50 | );
51 |
52 | const product = (await data.json()) as Product;
53 |
54 | const price = dinero(product.price as DineroSnapshot);
55 |
56 | return (
57 | <>
58 |
59 | {product.usedPrice ? (
60 |
61 | ) : null}
62 |
63 | {product.stock <= 1 ? (
64 |
65 | ) : null}
66 | >
67 | );
68 | }
69 |
70 | export function Pricing({ product }: { product: Product }) {
71 | const price = dinero(product.price as DineroSnapshot);
72 |
73 | return (
74 |
75 |
76 |
77 |
78 |
79 |
}>
80 |
81 |
82 |
83 |
}>
84 |
85 |
86 |
87 | );
88 | }
89 |
--------------------------------------------------------------------------------
/components/product-best-seller.tsx:
--------------------------------------------------------------------------------
1 | export const ProductBestSeller = () => {
2 | return (
3 |
4 | Best Seller
5 |
6 | );
7 | };
8 |
--------------------------------------------------------------------------------
/components/product-card.tsx:
--------------------------------------------------------------------------------
1 | import { Product } from '#/types/product';
2 | import { ProductBestSeller } from '#/components/product-best-seller';
3 | import { ProductEstimatedArrival } from '#/components/product-estimated-arrival';
4 | import { ProductLowStockWarning } from '#/components/product-low-stock-warning';
5 | import { ProductPrice } from '#/components/product-price';
6 | import { ProductRating } from '#/components/product-rating';
7 | import { ProductUsedPrice } from '#/components/product-used-price';
8 | import { dinero, type DineroSnapshot } from 'dinero.js';
9 | import Image from 'next/image';
10 |
11 | export const ProductCard = ({ product }: { product: Product }) => {
12 | const price = dinero(product.price as DineroSnapshot);
13 |
14 | return (
15 |
16 |
17 |
18 | {product.isBestSeller ? (
19 |
22 | ) : null}
23 |
32 |
33 |
34 |
35 | {product.name}
36 |
37 |
38 | {product.rating ?
: null}
39 |
40 |
41 |
42 | {product.usedPrice ? (
43 |
44 | ) : null}
45 |
46 |
47 |
48 | {product.stock <= 1 ? (
49 |
50 | ) : null}
51 |
52 |
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/components/product-currency-symbol.tsx:
--------------------------------------------------------------------------------
1 | import { toFormat, type Dinero } from 'dinero.js';
2 |
3 | export const ProductCurrencySymbol = ({
4 | dinero,
5 | }: {
6 | dinero: Dinero;
7 | }) => {
8 | let symbol = '';
9 | switch (toFormat(dinero, ({ currency }) => currency.code)) {
10 | case 'GBP': {
11 | symbol = '£';
12 | break;
13 | }
14 |
15 | case 'EUR': {
16 | symbol = '€';
17 | break;
18 | }
19 |
20 | default: {
21 | symbol = '$';
22 | break;
23 | }
24 | }
25 |
26 | return <>{symbol}>;
27 | };
28 |
--------------------------------------------------------------------------------
/components/product-deal.tsx:
--------------------------------------------------------------------------------
1 | import { ProductCurrencySymbol } from '#/components/product-currency-symbol';
2 | import { toUnit, type Dinero } from 'dinero.js';
3 |
4 | export const ProductDeal = ({
5 | price: priceRaw,
6 | discount: discountRaw,
7 | }: {
8 | price: Dinero;
9 | discount: {
10 | amount: Dinero;
11 | };
12 | }) => {
13 | const discount = toUnit(discountRaw.amount);
14 | const price = toUnit(priceRaw);
15 | const percent = Math.round(100 - (discount / price) * 100);
16 |
17 | return (
18 |
19 |
20 | -{percent}%
21 |
22 |
23 |
26 |
27 | {discount}
28 |
29 |
30 |
34 |
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/components/product-estimated-arrival.tsx:
--------------------------------------------------------------------------------
1 | import { add, format, isTomorrow } from 'date-fns';
2 |
3 | export const ProductEstimatedArrival = ({
4 | leadTime,
5 | hasDeliveryTime = false,
6 | }: {
7 | leadTime: number;
8 | hasDeliveryTime?: boolean;
9 | }) => {
10 | const date = add(new Date(), {
11 | days: leadTime,
12 | });
13 |
14 | return (
15 |
16 | Get it{' '}
17 |
18 | {isTomorrow(date) ? 'tomorrow, ' : null}
19 | {format(date, 'MMM d')}
20 |
21 | {hasDeliveryTime ? <> by 5pm> : null}
22 |
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/components/product-lightening-deal.tsx:
--------------------------------------------------------------------------------
1 | import { ProductDeal } from '#/components/product-deal';
2 | import { add, formatDistanceToNow } from 'date-fns';
3 | import { type Dinero } from 'dinero.js';
4 |
5 | export const ProductLighteningDeal = ({
6 | price,
7 | discount,
8 | }: {
9 | price: Dinero;
10 | discount: {
11 | amount: Dinero;
12 | expires?: number;
13 | };
14 | }) => {
15 | const date = add(new Date(), { days: discount.expires });
16 |
17 | return (
18 | <>
19 |
20 |
21 | Expires in {formatDistanceToNow(date)}
22 |
23 |
24 |
25 |
26 | >
27 | );
28 | };
29 |
--------------------------------------------------------------------------------
/components/product-low-stock-warning.tsx:
--------------------------------------------------------------------------------
1 | export const ProductLowStockWarning = ({ stock }: { stock: number }) => {
2 | if (stock > 3) {
3 | return null;
4 | }
5 |
6 | if (stock === 0) {
7 | return Out of stock
;
8 | }
9 |
10 | return (
11 | Only {stock} left in stock
12 | );
13 | };
14 |
--------------------------------------------------------------------------------
/components/product-price.tsx:
--------------------------------------------------------------------------------
1 | import { Product } from '#/types/product';
2 | import { ProductCurrencySymbol } from '#/components/product-currency-symbol';
3 | import { ProductDeal } from '#/components/product-deal';
4 | import { ProductLighteningDeal } from '#/components/product-lightening-deal';
5 | import { multiply, toUnit, type Dinero } from 'dinero.js';
6 |
7 | function isDiscount(obj: any): obj is { percent: number; expires?: number } {
8 | return typeof obj?.percent === 'number';
9 | }
10 |
11 | function formatDiscount(
12 | price: Dinero,
13 | discountRaw: Product['discount'],
14 | ) {
15 | return isDiscount(discountRaw)
16 | ? {
17 | amount: multiply(price, {
18 | amount: discountRaw.percent,
19 | scale: 2,
20 | }),
21 | expires: discountRaw.expires,
22 | }
23 | : undefined;
24 | }
25 |
26 | export const ProductPrice = ({
27 | price,
28 | discount: discountRaw,
29 | }: {
30 | price: Dinero;
31 | discount: Product['discount'];
32 | }) => {
33 | const discount = formatDiscount(price, discountRaw);
34 |
35 | if (discount) {
36 | if (discount?.expires && typeof discount.expires === 'number') {
37 | return ;
38 | }
39 | return ;
40 | }
41 |
42 | return (
43 |
44 |
47 |
48 | {toUnit(price)}
49 |
50 |
51 | );
52 | };
53 |
--------------------------------------------------------------------------------
/components/product-rating.tsx:
--------------------------------------------------------------------------------
1 | import { StarIcon } from '@heroicons/react/24/solid';
2 | import clsx from 'clsx';
3 |
4 | export const ProductRating = ({ rating }: { rating: number }) => {
5 | return (
6 |
7 | {Array.from({ length: 5 }).map((_, i) => {
8 | return (
9 |
13 | );
14 | })}
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/components/product-review-card.tsx:
--------------------------------------------------------------------------------
1 | import type { Review } from '#/types/review';
2 | import { ProductRating } from '#/components/product-rating';
3 |
4 | export const ProductReviewCard = ({ review }: { review: Review }) => {
5 | return (
6 |
7 |
8 |
9 |
10 |
{review.name}
11 |
12 |
13 | {review.rating ?
: null}
14 |
15 |
16 |
{review.text}
17 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/components/product-split-payments.tsx:
--------------------------------------------------------------------------------
1 | import { ProductCurrencySymbol } from '#/components/product-currency-symbol';
2 | import { allocate, toUnit, up, type Dinero } from 'dinero.js';
3 |
4 | export const ProductSplitPayments = ({ price }: { price: Dinero }) => {
5 | // only offer split payments for more expensive items
6 | if (toUnit(price) < 150) {
7 | return null;
8 | }
9 |
10 | const [perMonth] = allocate(price, [1, 2]);
11 | return (
12 |
13 | Or
14 | {toUnit(perMonth, { digits: 0, round: up })}/month for 3 months
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/components/product-used-price.tsx:
--------------------------------------------------------------------------------
1 | import { Product } from '#/types/product';
2 | import { dinero, toUnit, up, type DineroSnapshot } from 'dinero.js';
3 |
4 | export const ProductUsedPrice = ({
5 | usedPrice: usedPriceRaw,
6 | }: {
7 | usedPrice: Product['usedPrice'];
8 | }) => {
9 | const usedPrice = dinero(usedPriceRaw as DineroSnapshot);
10 |
11 | return (
12 |
13 |
More buying choices
14 |
15 | ${toUnit(usedPrice, { digits: 0, round: up })} (used)
16 |
17 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/components/recommended-products.tsx:
--------------------------------------------------------------------------------
1 | import { Product } from '#/types/product';
2 | import { ProductCard } from '#/components/product-card';
3 | import { delayRecommendedProducts, withDelay } from '#/lib/delay';
4 |
5 | export async function RecommendedProducts() {
6 | let products: Product[] = await withDelay(
7 | fetch(
8 | // We intentionally delay the response to simulate a slow data
9 | // request that would benefit from streaming
10 | `https://app-router-api.vercel.app/api/products?filter=1`,
11 | {
12 | // We intentionally disable Next.js Cache to better demo
13 | // streaming
14 | cache: 'no-store',
15 | }
16 | ).then((res) => res.json()),
17 | delayRecommendedProducts
18 | );
19 |
20 | return (
21 |
22 |
23 |
24 | Recommended Products for You
25 |
26 |
27 | Based on your preferences and shopping habits
28 |
29 |
30 |
31 | {products.map((product) => (
32 |
35 | ))}
36 |
37 |
38 | );
39 | }
40 |
41 | 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`;
42 |
43 | function ProductSkeleton() {
44 | return (
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | );
54 | }
55 |
56 | export function RecommendedProductsSkeleton() {
57 | return (
58 |
71 | );
72 | }
73 |
--------------------------------------------------------------------------------
/components/reviews.tsx:
--------------------------------------------------------------------------------
1 | import type { Review } from '#/types/review';
2 | import { ProductReviewCard } from '#/components/product-review-card';
3 | import { delayReviews, withDelay } from '#/lib/delay';
4 |
5 | export async function Reviews() {
6 | let reviews: Review[] = await withDelay(
7 | fetch(
8 | // We intentionally delay the response to simulate a slow data
9 | // request that would benefit from streaming
10 | `https://app-router-api.vercel.app/api/reviews`,
11 | {
12 | // We intentionally disable Next.js Cache to better demo
13 | // streaming
14 | cache: 'no-store',
15 | }
16 | ).then((res) => res.json()),
17 | delayReviews
18 | );
19 |
20 | return (
21 |
22 |
Customer Reviews
23 |
24 | {reviews.map((review) => {
25 | return
;
26 | })}
27 |
28 |
29 | );
30 | }
31 |
32 | 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`;
33 |
34 | function Skeleton() {
35 | return (
36 |
42 | );
43 | }
44 |
45 | export function ReviewsSkeleton() {
46 | return (
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/components/sidebar.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { NextLogo } from '#/components/next-logo';
4 | import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/solid';
5 |
6 | import clsx from 'clsx';
7 | import { useState } from 'react';
8 | import Byline from '#/components/byline';
9 | import {
10 | delayRecommendedProducts,
11 | delayReviews,
12 | delayShippingEstimate,
13 | } from '#/lib/delay';
14 |
15 | export function Sidebar() {
16 | const [isOpen, setIsOpen] = useState(false);
17 |
18 | return (
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Partial Prerendering
28 |
29 |
30 |
31 |
setIsOpen(!isOpen)}
35 | >
36 |
37 | Menu
38 |
39 | {isOpen ? (
40 |
41 | ) : (
42 |
43 | )}
44 |
45 |
46 |
52 |
53 |
54 |
55 | Pink dots {' '}
56 | denote artificially delayed responses for demo purposes:
57 |
58 |
59 | Shipping estimate → {delayShippingEstimate}ms
60 | Recommended products → {delayRecommendedProducts}ms
61 | Reviews → {delayReviews}ms
62 |
63 |
64 |
65 |
66 |
70 | Partial Prerendering
71 | {' '}
72 | combines ultra-quick static edge delivery with fully dynamic
73 | capabilities. This is different from how your application behaves
74 | today, where entire routes are either fully static or dynamic.
75 |
76 |
How it works:
77 |
78 |
79 | A static route shell is served immediately, this makes
80 | the initial load fast.
81 |
82 |
83 | The shell leaves holes where dynamic content (that might
84 | be slower) will be streamed in to minimize the perceived overall
85 | page load time.
86 |
87 |
88 | The async holes are loaded in parallel, reducing the overall load
89 | time of the page.
90 |
91 |
92 |
93 | Try refreshing the page to restart the demo.
94 |
95 |
96 |
97 |
98 |
99 | );
100 | }
101 |
--------------------------------------------------------------------------------
/components/single-product.tsx:
--------------------------------------------------------------------------------
1 | import { Pricing } from "#/components/pricing";
2 | import type { Product } from "#/types/product";
3 | import { ProductRating } from "#/components/product-rating";
4 | import Image from "next/image";
5 |
6 | export async function SingleProduct() {
7 | const product: Product = await fetch(
8 | `https://app-router-api.vercel.app/api/products?id=1`
9 | ).then((res) => res.json());
10 |
11 | return (
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
36 |
37 |
38 |
46 |
47 |
48 |
56 |
57 |
58 |
59 |
60 |
61 |
64 |
65 |
66 |
67 | {product.name}
68 |
69 |
70 |
71 |
72 |
73 |
{product.description}
74 |
{product.description}
75 |
76 |
77 |
78 | );
79 | }
80 |
--------------------------------------------------------------------------------
/components/vercel-logo.tsx:
--------------------------------------------------------------------------------
1 | export function VercelLogo() {
2 | return (
3 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/lib/delay.ts:
--------------------------------------------------------------------------------
1 | // Times are in milliseconds
2 | export const delayShippingEstimate = 200;
3 | export const delayRecommendedProducts = 500;
4 | export const delayReviews = 600;
5 |
6 | export async function withDelay(
7 | promise: Promise,
8 | delay: number
9 | ): Promise {
10 | // Ensure we throw if this throws
11 | const ret = await promise;
12 | return new Promise((resolve) => {
13 | setTimeout(() => {
14 | resolve(ret);
15 | }, delay);
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | experimental: {
4 | ppr: true,
5 | },
6 | };
7 |
8 | module.exports = nextConfig;
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "build": "next build",
5 | "dev": "next dev --turbo",
6 | "start": "next start"
7 | },
8 | "dependencies": {
9 | "@heroicons/react": "2.1.5",
10 | "clsx": "2.1.1",
11 | "date-fns": "3.6.0",
12 | "dinero.js": "2.0.0-alpha.8",
13 | "geist": "1.3.1",
14 | "next": "15.0.0-canary.67",
15 | "react": "19.0.0-rc-8b08e99e-20240713",
16 | "react-dom": "19.0.0-rc-8b08e99e-20240713"
17 | },
18 | "devDependencies": {
19 | "@tailwindcss/forms": "0.5.7",
20 | "@tailwindcss/typography": "0.5.13",
21 | "@types/node": "20.14.10",
22 | "@types/react": "18.3.3",
23 | "@types/react-dom": "18.3.0",
24 | "autoprefixer": "10.4.19",
25 | "postcss": "8.4.39",
26 | "tailwindcss": "3.4.5",
27 | "typescript": "5.5.3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | '@heroicons/react':
12 | specifier: 2.1.5
13 | version: 2.1.5(react@19.0.0-rc-8b08e99e-20240713)
14 | clsx:
15 | specifier: 2.1.1
16 | version: 2.1.1
17 | date-fns:
18 | specifier: 3.6.0
19 | version: 3.6.0
20 | dinero.js:
21 | specifier: 2.0.0-alpha.8
22 | version: 2.0.0-alpha.8
23 | geist:
24 | specifier: 1.3.1
25 | version: 1.3.1(next@15.0.0-canary.67(react-dom@19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713))(react@19.0.0-rc-8b08e99e-20240713))
26 | next:
27 | specifier: 15.0.0-canary.67
28 | version: 15.0.0-canary.67(react-dom@19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713))(react@19.0.0-rc-8b08e99e-20240713)
29 | react:
30 | specifier: 19.0.0-rc-8b08e99e-20240713
31 | version: 19.0.0-rc-8b08e99e-20240713
32 | react-dom:
33 | specifier: 19.0.0-rc-8b08e99e-20240713
34 | version: 19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713)
35 | devDependencies:
36 | '@tailwindcss/forms':
37 | specifier: 0.5.7
38 | version: 0.5.7(tailwindcss@3.4.5)
39 | '@tailwindcss/typography':
40 | specifier: 0.5.13
41 | version: 0.5.13(tailwindcss@3.4.5)
42 | '@types/node':
43 | specifier: 20.14.10
44 | version: 20.14.10
45 | '@types/react':
46 | specifier: 18.3.3
47 | version: 18.3.3
48 | '@types/react-dom':
49 | specifier: 18.3.0
50 | version: 18.3.0
51 | autoprefixer:
52 | specifier: 10.4.19
53 | version: 10.4.19(postcss@8.4.39)
54 | postcss:
55 | specifier: 8.4.39
56 | version: 8.4.39
57 | tailwindcss:
58 | specifier: 3.4.5
59 | version: 3.4.5
60 | typescript:
61 | specifier: 5.5.3
62 | version: 5.5.3
63 |
64 | packages:
65 |
66 | '@alloc/quick-lru@5.2.0':
67 | resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
68 | engines: {node: '>=10'}
69 |
70 | '@dinero.js/calculator-number@2.0.0-alpha.8':
71 | resolution: {integrity: sha512-/L+N7g5DjcS6wlMb2hcOXWBKW2TGiG+vZDZr9ow0nsHUTdwtMarL1bmBH9fGldHhH2XsxcrjN9H+036yeNzh3Q==}
72 |
73 | '@dinero.js/core@2.0.0-alpha.8':
74 | resolution: {integrity: sha512-3jaw2j6J/SshlCZz5KhHkh8zP47HRmt9RpnjR0BJs2awpweVuZIyyX9qzGVUEVpml9IwzQ1U+YdXevhOxtcDgg==}
75 |
76 | '@dinero.js/currencies@2.0.0-alpha.8':
77 | resolution: {integrity: sha512-zApiqtuuPwjiM9LJA5/kNcT48VSHRiz2/mktkXjIpfxrJKzthXybUAgEenExIH6dYhLDgVmsLQZtZFOsdYl0Ag==}
78 |
79 | '@emnapi/runtime@1.2.0':
80 | resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==}
81 |
82 | '@heroicons/react@2.1.5':
83 | resolution: {integrity: sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==}
84 | peerDependencies:
85 | react: '>= 16'
86 |
87 | '@img/sharp-darwin-arm64@0.33.4':
88 | resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==}
89 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
90 | cpu: [arm64]
91 | os: [darwin]
92 |
93 | '@img/sharp-darwin-x64@0.33.4':
94 | resolution: {integrity: sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==}
95 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
96 | cpu: [x64]
97 | os: [darwin]
98 |
99 | '@img/sharp-libvips-darwin-arm64@1.0.2':
100 | resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==}
101 | engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
102 | cpu: [arm64]
103 | os: [darwin]
104 |
105 | '@img/sharp-libvips-darwin-x64@1.0.2':
106 | resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==}
107 | engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
108 | cpu: [x64]
109 | os: [darwin]
110 |
111 | '@img/sharp-libvips-linux-arm64@1.0.2':
112 | resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==}
113 | engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
114 | cpu: [arm64]
115 | os: [linux]
116 |
117 | '@img/sharp-libvips-linux-arm@1.0.2':
118 | resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==}
119 | engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
120 | cpu: [arm]
121 | os: [linux]
122 |
123 | '@img/sharp-libvips-linux-s390x@1.0.2':
124 | resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==}
125 | engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
126 | cpu: [s390x]
127 | os: [linux]
128 |
129 | '@img/sharp-libvips-linux-x64@1.0.2':
130 | resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==}
131 | engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
132 | cpu: [x64]
133 | os: [linux]
134 |
135 | '@img/sharp-libvips-linuxmusl-arm64@1.0.2':
136 | resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==}
137 | engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
138 | cpu: [arm64]
139 | os: [linux]
140 |
141 | '@img/sharp-libvips-linuxmusl-x64@1.0.2':
142 | resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==}
143 | engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
144 | cpu: [x64]
145 | os: [linux]
146 |
147 | '@img/sharp-linux-arm64@0.33.4':
148 | resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==}
149 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
150 | cpu: [arm64]
151 | os: [linux]
152 |
153 | '@img/sharp-linux-arm@0.33.4':
154 | resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==}
155 | engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
156 | cpu: [arm]
157 | os: [linux]
158 |
159 | '@img/sharp-linux-s390x@0.33.4':
160 | resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==}
161 | engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
162 | cpu: [s390x]
163 | os: [linux]
164 |
165 | '@img/sharp-linux-x64@0.33.4':
166 | resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==}
167 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
168 | cpu: [x64]
169 | os: [linux]
170 |
171 | '@img/sharp-linuxmusl-arm64@0.33.4':
172 | resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==}
173 | engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
174 | cpu: [arm64]
175 | os: [linux]
176 |
177 | '@img/sharp-linuxmusl-x64@0.33.4':
178 | resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==}
179 | engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
180 | cpu: [x64]
181 | os: [linux]
182 |
183 | '@img/sharp-wasm32@0.33.4':
184 | resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==}
185 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
186 | cpu: [wasm32]
187 |
188 | '@img/sharp-win32-ia32@0.33.4':
189 | resolution: {integrity: sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==}
190 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
191 | cpu: [ia32]
192 | os: [win32]
193 |
194 | '@img/sharp-win32-x64@0.33.4':
195 | resolution: {integrity: sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==}
196 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
197 | cpu: [x64]
198 | os: [win32]
199 |
200 | '@isaacs/cliui@8.0.2':
201 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
202 | engines: {node: '>=12'}
203 |
204 | '@jridgewell/gen-mapping@0.3.5':
205 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
206 | engines: {node: '>=6.0.0'}
207 |
208 | '@jridgewell/resolve-uri@3.1.2':
209 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
210 | engines: {node: '>=6.0.0'}
211 |
212 | '@jridgewell/set-array@1.2.1':
213 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
214 | engines: {node: '>=6.0.0'}
215 |
216 | '@jridgewell/sourcemap-codec@1.5.0':
217 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
218 |
219 | '@jridgewell/trace-mapping@0.3.25':
220 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
221 |
222 | '@next/env@15.0.0-canary.67':
223 | resolution: {integrity: sha512-PkVYpfGi4fHxlFST2MSDl4RptW1t4WaLSoDK+/X3EUvU0i2gDZoi9ktZ/29Sh1XjlY8moFPWsqUsbLmsZWVVvQ==}
224 |
225 | '@next/swc-darwin-arm64@15.0.0-canary.67':
226 | resolution: {integrity: sha512-w+SNDkXH/XBRdHgcAvoBc3zEktjSd2IlJ3Mt/To5ceYo/776CIc1c9bU+DEfjqtMwkNXqPZmBJqblolp2qbOqQ==}
227 | engines: {node: '>= 10'}
228 | cpu: [arm64]
229 | os: [darwin]
230 |
231 | '@next/swc-darwin-x64@15.0.0-canary.67':
232 | resolution: {integrity: sha512-/Wp1rLJjO5RvYidj4By0h2qnccHGPhWKpC9cDdNn6XwiMTYbA3YbrsWJPZsJt1vcfQ+TZgN6YPVFO7/XSJqz2w==}
233 | engines: {node: '>= 10'}
234 | cpu: [x64]
235 | os: [darwin]
236 |
237 | '@next/swc-linux-arm64-gnu@15.0.0-canary.67':
238 | resolution: {integrity: sha512-TvgVRLN/p2P5ZVCqDKKPEzYJ8qKLUrf8U1yejTh1SYaMDK1Rz0I0roRXQQFYfRhAv3l5QmdFZbx98ZI5/IQjhA==}
239 | engines: {node: '>= 10'}
240 | cpu: [arm64]
241 | os: [linux]
242 |
243 | '@next/swc-linux-arm64-musl@15.0.0-canary.67':
244 | resolution: {integrity: sha512-EgExLdxjjUrTkvfsw//fX/bmZY8xl6ZrP9VqwhmHOFCAp5MDJi29bSbx0oYCcUPhsThAmqbno90Mu7JMfU4JeA==}
245 | engines: {node: '>= 10'}
246 | cpu: [arm64]
247 | os: [linux]
248 |
249 | '@next/swc-linux-x64-gnu@15.0.0-canary.67':
250 | resolution: {integrity: sha512-tMEcNBtNjI+wfKM4fJOps3PzKbDswly08GAycI9BiuugNKpG1RPEHqbyfo27C6nQf5I7u7r7S55qJ4KZfHPTxA==}
251 | engines: {node: '>= 10'}
252 | cpu: [x64]
253 | os: [linux]
254 |
255 | '@next/swc-linux-x64-musl@15.0.0-canary.67':
256 | resolution: {integrity: sha512-y8g3Afo+AkM9M1R2qLSjRKdDBsSzgd7CnUXT6OtxsaEsHwBAz9BBeANwo26Tc0K82U23Ev4uj7XS/Dr3jG5Row==}
257 | engines: {node: '>= 10'}
258 | cpu: [x64]
259 | os: [linux]
260 |
261 | '@next/swc-win32-arm64-msvc@15.0.0-canary.67':
262 | resolution: {integrity: sha512-SZr5EoYk9pQHPuwmDJUEwyQIbCPFEo8zdV+7gpTx3NZgmdDtgoG+gsct/ya9hLvP8sMw9x6gl+0YacSMd1lQNA==}
263 | engines: {node: '>= 10'}
264 | cpu: [arm64]
265 | os: [win32]
266 |
267 | '@next/swc-win32-ia32-msvc@15.0.0-canary.67':
268 | resolution: {integrity: sha512-u4gm/gCUU+e8Y77LoTRo3yfzh/qIQg3FmGTw4vB/WYBNcfU8xm02CL0SZtgePzLLia0WsETW3cgoNPQPr3ae+w==}
269 | engines: {node: '>= 10'}
270 | cpu: [ia32]
271 | os: [win32]
272 |
273 | '@next/swc-win32-x64-msvc@15.0.0-canary.67':
274 | resolution: {integrity: sha512-nfJVGjNh9d2V81mzCPq8cQ2w/YMAI6V2OejepR/jBKxZ+n0PJKrUHf52e+Ubak8bZOIvxKqaOj4WaceOljqNMQ==}
275 | engines: {node: '>= 10'}
276 | cpu: [x64]
277 | os: [win32]
278 |
279 | '@nodelib/fs.scandir@2.1.5':
280 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
281 | engines: {node: '>= 8'}
282 |
283 | '@nodelib/fs.stat@2.0.5':
284 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
285 | engines: {node: '>= 8'}
286 |
287 | '@nodelib/fs.walk@1.2.8':
288 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
289 | engines: {node: '>= 8'}
290 |
291 | '@pkgjs/parseargs@0.11.0':
292 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
293 | engines: {node: '>=14'}
294 |
295 | '@swc/helpers@0.5.11':
296 | resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==}
297 |
298 | '@tailwindcss/forms@0.5.7':
299 | resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==}
300 | peerDependencies:
301 | tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1'
302 |
303 | '@tailwindcss/typography@0.5.13':
304 | resolution: {integrity: sha512-ADGcJ8dX21dVVHIwTRgzrcunY6YY9uSlAHHGVKvkA+vLc5qLwEszvKts40lx7z0qc4clpjclwLeK5rVCV2P/uw==}
305 | peerDependencies:
306 | tailwindcss: '>=3.0.0 || insiders'
307 |
308 | '@types/node@20.14.10':
309 | resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
310 |
311 | '@types/prop-types@15.7.12':
312 | resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
313 |
314 | '@types/react-dom@18.3.0':
315 | resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
316 |
317 | '@types/react@18.3.3':
318 | resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==}
319 |
320 | ansi-regex@5.0.1:
321 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
322 | engines: {node: '>=8'}
323 |
324 | ansi-regex@6.0.1:
325 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
326 | engines: {node: '>=12'}
327 |
328 | ansi-styles@4.3.0:
329 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
330 | engines: {node: '>=8'}
331 |
332 | ansi-styles@6.2.1:
333 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
334 | engines: {node: '>=12'}
335 |
336 | any-promise@1.3.0:
337 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
338 |
339 | anymatch@3.1.3:
340 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
341 | engines: {node: '>= 8'}
342 |
343 | arg@5.0.2:
344 | resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
345 |
346 | autoprefixer@10.4.19:
347 | resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
348 | engines: {node: ^10 || ^12 || >=14}
349 | hasBin: true
350 | peerDependencies:
351 | postcss: ^8.1.0
352 |
353 | balanced-match@1.0.2:
354 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
355 |
356 | binary-extensions@2.3.0:
357 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
358 | engines: {node: '>=8'}
359 |
360 | brace-expansion@2.0.1:
361 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
362 |
363 | braces@3.0.3:
364 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
365 | engines: {node: '>=8'}
366 |
367 | browserslist@4.23.2:
368 | resolution: {integrity: sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==}
369 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
370 | hasBin: true
371 |
372 | busboy@1.6.0:
373 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
374 | engines: {node: '>=10.16.0'}
375 |
376 | camelcase-css@2.0.1:
377 | resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
378 | engines: {node: '>= 6'}
379 |
380 | caniuse-lite@1.0.30001642:
381 | resolution: {integrity: sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==}
382 |
383 | chokidar@3.6.0:
384 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
385 | engines: {node: '>= 8.10.0'}
386 |
387 | client-only@0.0.1:
388 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
389 |
390 | clsx@2.1.1:
391 | resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
392 | engines: {node: '>=6'}
393 |
394 | color-convert@2.0.1:
395 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
396 | engines: {node: '>=7.0.0'}
397 |
398 | color-name@1.1.4:
399 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
400 |
401 | color-string@1.9.1:
402 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
403 |
404 | color@4.2.3:
405 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
406 | engines: {node: '>=12.5.0'}
407 |
408 | commander@4.1.1:
409 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
410 | engines: {node: '>= 6'}
411 |
412 | cross-spawn@7.0.3:
413 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
414 | engines: {node: '>= 8'}
415 |
416 | cssesc@3.0.0:
417 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
418 | engines: {node: '>=4'}
419 | hasBin: true
420 |
421 | csstype@3.1.3:
422 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
423 |
424 | date-fns@3.6.0:
425 | resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==}
426 |
427 | detect-libc@2.0.3:
428 | resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
429 | engines: {node: '>=8'}
430 |
431 | didyoumean@1.2.2:
432 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
433 |
434 | dinero.js@2.0.0-alpha.8:
435 | resolution: {integrity: sha512-6bl+g6oh6iQ6vPR5Pd4qr7D+P5e51GYRUT3jl8HYqYeejYC5sd9OVTTbXC3WU7L25mAIbOm+diiTVz1rL4QLwg==}
436 |
437 | dlv@1.1.3:
438 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
439 |
440 | eastasianwidth@0.2.0:
441 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
442 |
443 | electron-to-chromium@1.4.830:
444 | resolution: {integrity: sha512-TrPKKH20HeN0J1LHzsYLs2qwXrp8TF4nHdu4sq61ozGbzMpWhI7iIOPYPPkxeq1azMT9PZ8enPFcftbs/Npcjg==}
445 |
446 | emoji-regex@8.0.0:
447 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
448 |
449 | emoji-regex@9.2.2:
450 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
451 |
452 | escalade@3.1.2:
453 | resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
454 | engines: {node: '>=6'}
455 |
456 | fast-glob@3.3.2:
457 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
458 | engines: {node: '>=8.6.0'}
459 |
460 | fastq@1.17.1:
461 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
462 |
463 | fill-range@7.1.1:
464 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
465 | engines: {node: '>=8'}
466 |
467 | foreground-child@3.2.1:
468 | resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==}
469 | engines: {node: '>=14'}
470 |
471 | fraction.js@4.3.7:
472 | resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
473 |
474 | fsevents@2.3.3:
475 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
476 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
477 | os: [darwin]
478 |
479 | function-bind@1.1.2:
480 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
481 |
482 | geist@1.3.1:
483 | resolution: {integrity: sha512-Q4gC1pBVPN+D579pBaz0TRRnGA4p9UK6elDY/xizXdFk/g4EKR5g0I+4p/Kj6gM0SajDBZ/0FvDV9ey9ud7BWw==}
484 | peerDependencies:
485 | next: '>=13.2.0'
486 |
487 | glob-parent@5.1.2:
488 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
489 | engines: {node: '>= 6'}
490 |
491 | glob-parent@6.0.2:
492 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
493 | engines: {node: '>=10.13.0'}
494 |
495 | glob@10.4.5:
496 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
497 | hasBin: true
498 |
499 | graceful-fs@4.2.11:
500 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
501 |
502 | hasown@2.0.2:
503 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
504 | engines: {node: '>= 0.4'}
505 |
506 | is-arrayish@0.3.2:
507 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
508 |
509 | is-binary-path@2.1.0:
510 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
511 | engines: {node: '>=8'}
512 |
513 | is-core-module@2.15.0:
514 | resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==}
515 | engines: {node: '>= 0.4'}
516 |
517 | is-extglob@2.1.1:
518 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
519 | engines: {node: '>=0.10.0'}
520 |
521 | is-fullwidth-code-point@3.0.0:
522 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
523 | engines: {node: '>=8'}
524 |
525 | is-glob@4.0.3:
526 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
527 | engines: {node: '>=0.10.0'}
528 |
529 | is-number@7.0.0:
530 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
531 | engines: {node: '>=0.12.0'}
532 |
533 | isexe@2.0.0:
534 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
535 |
536 | jackspeak@3.4.3:
537 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
538 |
539 | jiti@1.21.6:
540 | resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
541 | hasBin: true
542 |
543 | lilconfig@2.1.0:
544 | resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
545 | engines: {node: '>=10'}
546 |
547 | lilconfig@3.1.2:
548 | resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
549 | engines: {node: '>=14'}
550 |
551 | lines-and-columns@1.2.4:
552 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
553 |
554 | lodash.castarray@4.4.0:
555 | resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
556 |
557 | lodash.isplainobject@4.0.6:
558 | resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
559 |
560 | lodash.merge@4.6.2:
561 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
562 |
563 | lru-cache@10.4.3:
564 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
565 |
566 | merge2@1.4.1:
567 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
568 | engines: {node: '>= 8'}
569 |
570 | micromatch@4.0.7:
571 | resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
572 | engines: {node: '>=8.6'}
573 |
574 | mini-svg-data-uri@1.4.4:
575 | resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
576 | hasBin: true
577 |
578 | minimatch@9.0.5:
579 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
580 | engines: {node: '>=16 || 14 >=14.17'}
581 |
582 | minipass@7.1.2:
583 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
584 | engines: {node: '>=16 || 14 >=14.17'}
585 |
586 | mz@2.7.0:
587 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
588 |
589 | nanoid@3.3.7:
590 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
591 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
592 | hasBin: true
593 |
594 | next@15.0.0-canary.67:
595 | resolution: {integrity: sha512-t6TK98DaoVLfhMF5S3EhSyLjsDh06UjEiYGPScSft9DIdmY0SIjOFOHUVBuZ3Mt+oeuhSyZHs4q5G0+KLvxiSA==}
596 | engines: {node: '>=18.18.0'}
597 | hasBin: true
598 | peerDependencies:
599 | '@opentelemetry/api': ^1.1.0
600 | '@playwright/test': ^1.41.2
601 | babel-plugin-react-compiler: '*'
602 | react: 19.0.0-rc.0
603 | react-dom: 19.0.0-rc.0
604 | sass: ^1.3.0
605 | peerDependenciesMeta:
606 | '@opentelemetry/api':
607 | optional: true
608 | '@playwright/test':
609 | optional: true
610 | babel-plugin-react-compiler:
611 | optional: true
612 | sass:
613 | optional: true
614 |
615 | node-releases@2.0.17:
616 | resolution: {integrity: sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==}
617 |
618 | normalize-path@3.0.0:
619 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
620 | engines: {node: '>=0.10.0'}
621 |
622 | normalize-range@0.1.2:
623 | resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
624 | engines: {node: '>=0.10.0'}
625 |
626 | object-assign@4.1.1:
627 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
628 | engines: {node: '>=0.10.0'}
629 |
630 | object-hash@3.0.0:
631 | resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
632 | engines: {node: '>= 6'}
633 |
634 | package-json-from-dist@1.0.0:
635 | resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
636 |
637 | path-key@3.1.1:
638 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
639 | engines: {node: '>=8'}
640 |
641 | path-parse@1.0.7:
642 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
643 |
644 | path-scurry@1.11.1:
645 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
646 | engines: {node: '>=16 || 14 >=14.18'}
647 |
648 | picocolors@1.0.1:
649 | resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
650 |
651 | picomatch@2.3.1:
652 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
653 | engines: {node: '>=8.6'}
654 |
655 | pify@2.3.0:
656 | resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
657 | engines: {node: '>=0.10.0'}
658 |
659 | pirates@4.0.6:
660 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
661 | engines: {node: '>= 6'}
662 |
663 | postcss-import@15.1.0:
664 | resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
665 | engines: {node: '>=14.0.0'}
666 | peerDependencies:
667 | postcss: ^8.0.0
668 |
669 | postcss-js@4.0.1:
670 | resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
671 | engines: {node: ^12 || ^14 || >= 16}
672 | peerDependencies:
673 | postcss: ^8.4.21
674 |
675 | postcss-load-config@4.0.2:
676 | resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
677 | engines: {node: '>= 14'}
678 | peerDependencies:
679 | postcss: '>=8.0.9'
680 | ts-node: '>=9.0.0'
681 | peerDependenciesMeta:
682 | postcss:
683 | optional: true
684 | ts-node:
685 | optional: true
686 |
687 | postcss-nested@6.0.1:
688 | resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
689 | engines: {node: '>=12.0'}
690 | peerDependencies:
691 | postcss: ^8.2.14
692 |
693 | postcss-selector-parser@6.0.10:
694 | resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
695 | engines: {node: '>=4'}
696 |
697 | postcss-selector-parser@6.1.1:
698 | resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==}
699 | engines: {node: '>=4'}
700 |
701 | postcss-value-parser@4.2.0:
702 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
703 |
704 | postcss@8.4.31:
705 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
706 | engines: {node: ^10 || ^12 || >=14}
707 |
708 | postcss@8.4.39:
709 | resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
710 | engines: {node: ^10 || ^12 || >=14}
711 |
712 | queue-microtask@1.2.3:
713 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
714 |
715 | react-dom@19.0.0-rc-8b08e99e-20240713:
716 | resolution: {integrity: sha512-nTbNXc5LVuFh+CwsmwogdYzHumZb9LVtWr1pE3DFHjY3y2VM/bYg8d00Vn6WWqQ8js3PY1w150NEEax4CrtsTA==}
717 | peerDependencies:
718 | react: 19.0.0-rc-8b08e99e-20240713
719 |
720 | react@19.0.0-rc-8b08e99e-20240713:
721 | resolution: {integrity: sha512-j56t3i/sMNftehdO/cA0kFeKDh9Pi1FxKba6u0sRgzZ73HVWii64oUbFxkUmf6I/C9uCmovY3HnFpT7/0UTIaw==}
722 | engines: {node: '>=0.10.0'}
723 |
724 | read-cache@1.0.0:
725 | resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
726 |
727 | readdirp@3.6.0:
728 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
729 | engines: {node: '>=8.10.0'}
730 |
731 | resolve@1.22.8:
732 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
733 | hasBin: true
734 |
735 | reusify@1.0.4:
736 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
737 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
738 |
739 | run-parallel@1.2.0:
740 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
741 |
742 | scheduler@0.25.0-rc-8b08e99e-20240713:
743 | resolution: {integrity: sha512-vPAQ9hTVeh54O7K7nTH5rIr060XI2E5xXSLOeiDpZVjtZW9DhZMjq4L82aI8J5EZPwYlWH69SdKBwFMIleNkUQ==}
744 |
745 | semver@7.6.3:
746 | resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
747 | engines: {node: '>=10'}
748 | hasBin: true
749 |
750 | sharp@0.33.4:
751 | resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==}
752 | engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
753 |
754 | shebang-command@2.0.0:
755 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
756 | engines: {node: '>=8'}
757 |
758 | shebang-regex@3.0.0:
759 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
760 | engines: {node: '>=8'}
761 |
762 | signal-exit@4.1.0:
763 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
764 | engines: {node: '>=14'}
765 |
766 | simple-swizzle@0.2.2:
767 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
768 |
769 | source-map-js@1.2.0:
770 | resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
771 | engines: {node: '>=0.10.0'}
772 |
773 | streamsearch@1.1.0:
774 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
775 | engines: {node: '>=10.0.0'}
776 |
777 | string-width@4.2.3:
778 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
779 | engines: {node: '>=8'}
780 |
781 | string-width@5.1.2:
782 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
783 | engines: {node: '>=12'}
784 |
785 | strip-ansi@6.0.1:
786 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
787 | engines: {node: '>=8'}
788 |
789 | strip-ansi@7.1.0:
790 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
791 | engines: {node: '>=12'}
792 |
793 | styled-jsx@5.1.6:
794 | resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
795 | engines: {node: '>= 12.0.0'}
796 | peerDependencies:
797 | '@babel/core': '*'
798 | babel-plugin-macros: '*'
799 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
800 | peerDependenciesMeta:
801 | '@babel/core':
802 | optional: true
803 | babel-plugin-macros:
804 | optional: true
805 |
806 | sucrase@3.35.0:
807 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
808 | engines: {node: '>=16 || 14 >=14.17'}
809 | hasBin: true
810 |
811 | supports-preserve-symlinks-flag@1.0.0:
812 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
813 | engines: {node: '>= 0.4'}
814 |
815 | tailwindcss@3.4.5:
816 | resolution: {integrity: sha512-DlTxttYcogpDfx3tf/8jfnma1nfAYi2cBUYV2YNoPPecwmO3YGiFlOX9D8tGAu+EDF38ryBzvrDKU/BLMsUwbw==}
817 | engines: {node: '>=14.0.0'}
818 | hasBin: true
819 |
820 | thenify-all@1.6.0:
821 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
822 | engines: {node: '>=0.8'}
823 |
824 | thenify@3.3.1:
825 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
826 |
827 | to-regex-range@5.0.1:
828 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
829 | engines: {node: '>=8.0'}
830 |
831 | ts-interface-checker@0.1.13:
832 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
833 |
834 | tslib@2.6.3:
835 | resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
836 |
837 | typescript@5.5.3:
838 | resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
839 | engines: {node: '>=14.17'}
840 | hasBin: true
841 |
842 | undici-types@5.26.5:
843 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
844 |
845 | update-browserslist-db@1.1.0:
846 | resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
847 | hasBin: true
848 | peerDependencies:
849 | browserslist: '>= 4.21.0'
850 |
851 | util-deprecate@1.0.2:
852 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
853 |
854 | which@2.0.2:
855 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
856 | engines: {node: '>= 8'}
857 | hasBin: true
858 |
859 | wrap-ansi@7.0.0:
860 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
861 | engines: {node: '>=10'}
862 |
863 | wrap-ansi@8.1.0:
864 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
865 | engines: {node: '>=12'}
866 |
867 | yaml@2.4.5:
868 | resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==}
869 | engines: {node: '>= 14'}
870 | hasBin: true
871 |
872 | snapshots:
873 |
874 | '@alloc/quick-lru@5.2.0': {}
875 |
876 | '@dinero.js/calculator-number@2.0.0-alpha.8':
877 | dependencies:
878 | '@dinero.js/core': 2.0.0-alpha.8
879 |
880 | '@dinero.js/core@2.0.0-alpha.8':
881 | dependencies:
882 | '@dinero.js/currencies': 2.0.0-alpha.8
883 |
884 | '@dinero.js/currencies@2.0.0-alpha.8': {}
885 |
886 | '@emnapi/runtime@1.2.0':
887 | dependencies:
888 | tslib: 2.6.3
889 | optional: true
890 |
891 | '@heroicons/react@2.1.5(react@19.0.0-rc-8b08e99e-20240713)':
892 | dependencies:
893 | react: 19.0.0-rc-8b08e99e-20240713
894 |
895 | '@img/sharp-darwin-arm64@0.33.4':
896 | optionalDependencies:
897 | '@img/sharp-libvips-darwin-arm64': 1.0.2
898 | optional: true
899 |
900 | '@img/sharp-darwin-x64@0.33.4':
901 | optionalDependencies:
902 | '@img/sharp-libvips-darwin-x64': 1.0.2
903 | optional: true
904 |
905 | '@img/sharp-libvips-darwin-arm64@1.0.2':
906 | optional: true
907 |
908 | '@img/sharp-libvips-darwin-x64@1.0.2':
909 | optional: true
910 |
911 | '@img/sharp-libvips-linux-arm64@1.0.2':
912 | optional: true
913 |
914 | '@img/sharp-libvips-linux-arm@1.0.2':
915 | optional: true
916 |
917 | '@img/sharp-libvips-linux-s390x@1.0.2':
918 | optional: true
919 |
920 | '@img/sharp-libvips-linux-x64@1.0.2':
921 | optional: true
922 |
923 | '@img/sharp-libvips-linuxmusl-arm64@1.0.2':
924 | optional: true
925 |
926 | '@img/sharp-libvips-linuxmusl-x64@1.0.2':
927 | optional: true
928 |
929 | '@img/sharp-linux-arm64@0.33.4':
930 | optionalDependencies:
931 | '@img/sharp-libvips-linux-arm64': 1.0.2
932 | optional: true
933 |
934 | '@img/sharp-linux-arm@0.33.4':
935 | optionalDependencies:
936 | '@img/sharp-libvips-linux-arm': 1.0.2
937 | optional: true
938 |
939 | '@img/sharp-linux-s390x@0.33.4':
940 | optionalDependencies:
941 | '@img/sharp-libvips-linux-s390x': 1.0.2
942 | optional: true
943 |
944 | '@img/sharp-linux-x64@0.33.4':
945 | optionalDependencies:
946 | '@img/sharp-libvips-linux-x64': 1.0.2
947 | optional: true
948 |
949 | '@img/sharp-linuxmusl-arm64@0.33.4':
950 | optionalDependencies:
951 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.2
952 | optional: true
953 |
954 | '@img/sharp-linuxmusl-x64@0.33.4':
955 | optionalDependencies:
956 | '@img/sharp-libvips-linuxmusl-x64': 1.0.2
957 | optional: true
958 |
959 | '@img/sharp-wasm32@0.33.4':
960 | dependencies:
961 | '@emnapi/runtime': 1.2.0
962 | optional: true
963 |
964 | '@img/sharp-win32-ia32@0.33.4':
965 | optional: true
966 |
967 | '@img/sharp-win32-x64@0.33.4':
968 | optional: true
969 |
970 | '@isaacs/cliui@8.0.2':
971 | dependencies:
972 | string-width: 5.1.2
973 | string-width-cjs: string-width@4.2.3
974 | strip-ansi: 7.1.0
975 | strip-ansi-cjs: strip-ansi@6.0.1
976 | wrap-ansi: 8.1.0
977 | wrap-ansi-cjs: wrap-ansi@7.0.0
978 |
979 | '@jridgewell/gen-mapping@0.3.5':
980 | dependencies:
981 | '@jridgewell/set-array': 1.2.1
982 | '@jridgewell/sourcemap-codec': 1.5.0
983 | '@jridgewell/trace-mapping': 0.3.25
984 |
985 | '@jridgewell/resolve-uri@3.1.2': {}
986 |
987 | '@jridgewell/set-array@1.2.1': {}
988 |
989 | '@jridgewell/sourcemap-codec@1.5.0': {}
990 |
991 | '@jridgewell/trace-mapping@0.3.25':
992 | dependencies:
993 | '@jridgewell/resolve-uri': 3.1.2
994 | '@jridgewell/sourcemap-codec': 1.5.0
995 |
996 | '@next/env@15.0.0-canary.67': {}
997 |
998 | '@next/swc-darwin-arm64@15.0.0-canary.67':
999 | optional: true
1000 |
1001 | '@next/swc-darwin-x64@15.0.0-canary.67':
1002 | optional: true
1003 |
1004 | '@next/swc-linux-arm64-gnu@15.0.0-canary.67':
1005 | optional: true
1006 |
1007 | '@next/swc-linux-arm64-musl@15.0.0-canary.67':
1008 | optional: true
1009 |
1010 | '@next/swc-linux-x64-gnu@15.0.0-canary.67':
1011 | optional: true
1012 |
1013 | '@next/swc-linux-x64-musl@15.0.0-canary.67':
1014 | optional: true
1015 |
1016 | '@next/swc-win32-arm64-msvc@15.0.0-canary.67':
1017 | optional: true
1018 |
1019 | '@next/swc-win32-ia32-msvc@15.0.0-canary.67':
1020 | optional: true
1021 |
1022 | '@next/swc-win32-x64-msvc@15.0.0-canary.67':
1023 | optional: true
1024 |
1025 | '@nodelib/fs.scandir@2.1.5':
1026 | dependencies:
1027 | '@nodelib/fs.stat': 2.0.5
1028 | run-parallel: 1.2.0
1029 |
1030 | '@nodelib/fs.stat@2.0.5': {}
1031 |
1032 | '@nodelib/fs.walk@1.2.8':
1033 | dependencies:
1034 | '@nodelib/fs.scandir': 2.1.5
1035 | fastq: 1.17.1
1036 |
1037 | '@pkgjs/parseargs@0.11.0':
1038 | optional: true
1039 |
1040 | '@swc/helpers@0.5.11':
1041 | dependencies:
1042 | tslib: 2.6.3
1043 |
1044 | '@tailwindcss/forms@0.5.7(tailwindcss@3.4.5)':
1045 | dependencies:
1046 | mini-svg-data-uri: 1.4.4
1047 | tailwindcss: 3.4.5
1048 |
1049 | '@tailwindcss/typography@0.5.13(tailwindcss@3.4.5)':
1050 | dependencies:
1051 | lodash.castarray: 4.4.0
1052 | lodash.isplainobject: 4.0.6
1053 | lodash.merge: 4.6.2
1054 | postcss-selector-parser: 6.0.10
1055 | tailwindcss: 3.4.5
1056 |
1057 | '@types/node@20.14.10':
1058 | dependencies:
1059 | undici-types: 5.26.5
1060 |
1061 | '@types/prop-types@15.7.12': {}
1062 |
1063 | '@types/react-dom@18.3.0':
1064 | dependencies:
1065 | '@types/react': 18.3.3
1066 |
1067 | '@types/react@18.3.3':
1068 | dependencies:
1069 | '@types/prop-types': 15.7.12
1070 | csstype: 3.1.3
1071 |
1072 | ansi-regex@5.0.1: {}
1073 |
1074 | ansi-regex@6.0.1: {}
1075 |
1076 | ansi-styles@4.3.0:
1077 | dependencies:
1078 | color-convert: 2.0.1
1079 |
1080 | ansi-styles@6.2.1: {}
1081 |
1082 | any-promise@1.3.0: {}
1083 |
1084 | anymatch@3.1.3:
1085 | dependencies:
1086 | normalize-path: 3.0.0
1087 | picomatch: 2.3.1
1088 |
1089 | arg@5.0.2: {}
1090 |
1091 | autoprefixer@10.4.19(postcss@8.4.39):
1092 | dependencies:
1093 | browserslist: 4.23.2
1094 | caniuse-lite: 1.0.30001642
1095 | fraction.js: 4.3.7
1096 | normalize-range: 0.1.2
1097 | picocolors: 1.0.1
1098 | postcss: 8.4.39
1099 | postcss-value-parser: 4.2.0
1100 |
1101 | balanced-match@1.0.2: {}
1102 |
1103 | binary-extensions@2.3.0: {}
1104 |
1105 | brace-expansion@2.0.1:
1106 | dependencies:
1107 | balanced-match: 1.0.2
1108 |
1109 | braces@3.0.3:
1110 | dependencies:
1111 | fill-range: 7.1.1
1112 |
1113 | browserslist@4.23.2:
1114 | dependencies:
1115 | caniuse-lite: 1.0.30001642
1116 | electron-to-chromium: 1.4.830
1117 | node-releases: 2.0.17
1118 | update-browserslist-db: 1.1.0(browserslist@4.23.2)
1119 |
1120 | busboy@1.6.0:
1121 | dependencies:
1122 | streamsearch: 1.1.0
1123 |
1124 | camelcase-css@2.0.1: {}
1125 |
1126 | caniuse-lite@1.0.30001642: {}
1127 |
1128 | chokidar@3.6.0:
1129 | dependencies:
1130 | anymatch: 3.1.3
1131 | braces: 3.0.3
1132 | glob-parent: 5.1.2
1133 | is-binary-path: 2.1.0
1134 | is-glob: 4.0.3
1135 | normalize-path: 3.0.0
1136 | readdirp: 3.6.0
1137 | optionalDependencies:
1138 | fsevents: 2.3.3
1139 |
1140 | client-only@0.0.1: {}
1141 |
1142 | clsx@2.1.1: {}
1143 |
1144 | color-convert@2.0.1:
1145 | dependencies:
1146 | color-name: 1.1.4
1147 |
1148 | color-name@1.1.4: {}
1149 |
1150 | color-string@1.9.1:
1151 | dependencies:
1152 | color-name: 1.1.4
1153 | simple-swizzle: 0.2.2
1154 | optional: true
1155 |
1156 | color@4.2.3:
1157 | dependencies:
1158 | color-convert: 2.0.1
1159 | color-string: 1.9.1
1160 | optional: true
1161 |
1162 | commander@4.1.1: {}
1163 |
1164 | cross-spawn@7.0.3:
1165 | dependencies:
1166 | path-key: 3.1.1
1167 | shebang-command: 2.0.0
1168 | which: 2.0.2
1169 |
1170 | cssesc@3.0.0: {}
1171 |
1172 | csstype@3.1.3: {}
1173 |
1174 | date-fns@3.6.0: {}
1175 |
1176 | detect-libc@2.0.3:
1177 | optional: true
1178 |
1179 | didyoumean@1.2.2: {}
1180 |
1181 | dinero.js@2.0.0-alpha.8:
1182 | dependencies:
1183 | '@dinero.js/calculator-number': 2.0.0-alpha.8
1184 | '@dinero.js/core': 2.0.0-alpha.8
1185 | '@dinero.js/currencies': 2.0.0-alpha.8
1186 |
1187 | dlv@1.1.3: {}
1188 |
1189 | eastasianwidth@0.2.0: {}
1190 |
1191 | electron-to-chromium@1.4.830: {}
1192 |
1193 | emoji-regex@8.0.0: {}
1194 |
1195 | emoji-regex@9.2.2: {}
1196 |
1197 | escalade@3.1.2: {}
1198 |
1199 | fast-glob@3.3.2:
1200 | dependencies:
1201 | '@nodelib/fs.stat': 2.0.5
1202 | '@nodelib/fs.walk': 1.2.8
1203 | glob-parent: 5.1.2
1204 | merge2: 1.4.1
1205 | micromatch: 4.0.7
1206 |
1207 | fastq@1.17.1:
1208 | dependencies:
1209 | reusify: 1.0.4
1210 |
1211 | fill-range@7.1.1:
1212 | dependencies:
1213 | to-regex-range: 5.0.1
1214 |
1215 | foreground-child@3.2.1:
1216 | dependencies:
1217 | cross-spawn: 7.0.3
1218 | signal-exit: 4.1.0
1219 |
1220 | fraction.js@4.3.7: {}
1221 |
1222 | fsevents@2.3.3:
1223 | optional: true
1224 |
1225 | function-bind@1.1.2: {}
1226 |
1227 | geist@1.3.1(next@15.0.0-canary.67(react-dom@19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713))(react@19.0.0-rc-8b08e99e-20240713)):
1228 | dependencies:
1229 | next: 15.0.0-canary.67(react-dom@19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713))(react@19.0.0-rc-8b08e99e-20240713)
1230 |
1231 | glob-parent@5.1.2:
1232 | dependencies:
1233 | is-glob: 4.0.3
1234 |
1235 | glob-parent@6.0.2:
1236 | dependencies:
1237 | is-glob: 4.0.3
1238 |
1239 | glob@10.4.5:
1240 | dependencies:
1241 | foreground-child: 3.2.1
1242 | jackspeak: 3.4.3
1243 | minimatch: 9.0.5
1244 | minipass: 7.1.2
1245 | package-json-from-dist: 1.0.0
1246 | path-scurry: 1.11.1
1247 |
1248 | graceful-fs@4.2.11: {}
1249 |
1250 | hasown@2.0.2:
1251 | dependencies:
1252 | function-bind: 1.1.2
1253 |
1254 | is-arrayish@0.3.2:
1255 | optional: true
1256 |
1257 | is-binary-path@2.1.0:
1258 | dependencies:
1259 | binary-extensions: 2.3.0
1260 |
1261 | is-core-module@2.15.0:
1262 | dependencies:
1263 | hasown: 2.0.2
1264 |
1265 | is-extglob@2.1.1: {}
1266 |
1267 | is-fullwidth-code-point@3.0.0: {}
1268 |
1269 | is-glob@4.0.3:
1270 | dependencies:
1271 | is-extglob: 2.1.1
1272 |
1273 | is-number@7.0.0: {}
1274 |
1275 | isexe@2.0.0: {}
1276 |
1277 | jackspeak@3.4.3:
1278 | dependencies:
1279 | '@isaacs/cliui': 8.0.2
1280 | optionalDependencies:
1281 | '@pkgjs/parseargs': 0.11.0
1282 |
1283 | jiti@1.21.6: {}
1284 |
1285 | lilconfig@2.1.0: {}
1286 |
1287 | lilconfig@3.1.2: {}
1288 |
1289 | lines-and-columns@1.2.4: {}
1290 |
1291 | lodash.castarray@4.4.0: {}
1292 |
1293 | lodash.isplainobject@4.0.6: {}
1294 |
1295 | lodash.merge@4.6.2: {}
1296 |
1297 | lru-cache@10.4.3: {}
1298 |
1299 | merge2@1.4.1: {}
1300 |
1301 | micromatch@4.0.7:
1302 | dependencies:
1303 | braces: 3.0.3
1304 | picomatch: 2.3.1
1305 |
1306 | mini-svg-data-uri@1.4.4: {}
1307 |
1308 | minimatch@9.0.5:
1309 | dependencies:
1310 | brace-expansion: 2.0.1
1311 |
1312 | minipass@7.1.2: {}
1313 |
1314 | mz@2.7.0:
1315 | dependencies:
1316 | any-promise: 1.3.0
1317 | object-assign: 4.1.1
1318 | thenify-all: 1.6.0
1319 |
1320 | nanoid@3.3.7: {}
1321 |
1322 | next@15.0.0-canary.67(react-dom@19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713))(react@19.0.0-rc-8b08e99e-20240713):
1323 | dependencies:
1324 | '@next/env': 15.0.0-canary.67
1325 | '@swc/helpers': 0.5.11
1326 | busboy: 1.6.0
1327 | caniuse-lite: 1.0.30001642
1328 | graceful-fs: 4.2.11
1329 | postcss: 8.4.31
1330 | react: 19.0.0-rc-8b08e99e-20240713
1331 | react-dom: 19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713)
1332 | styled-jsx: 5.1.6(react@19.0.0-rc-8b08e99e-20240713)
1333 | optionalDependencies:
1334 | '@next/swc-darwin-arm64': 15.0.0-canary.67
1335 | '@next/swc-darwin-x64': 15.0.0-canary.67
1336 | '@next/swc-linux-arm64-gnu': 15.0.0-canary.67
1337 | '@next/swc-linux-arm64-musl': 15.0.0-canary.67
1338 | '@next/swc-linux-x64-gnu': 15.0.0-canary.67
1339 | '@next/swc-linux-x64-musl': 15.0.0-canary.67
1340 | '@next/swc-win32-arm64-msvc': 15.0.0-canary.67
1341 | '@next/swc-win32-ia32-msvc': 15.0.0-canary.67
1342 | '@next/swc-win32-x64-msvc': 15.0.0-canary.67
1343 | sharp: 0.33.4
1344 | transitivePeerDependencies:
1345 | - '@babel/core'
1346 | - babel-plugin-macros
1347 |
1348 | node-releases@2.0.17: {}
1349 |
1350 | normalize-path@3.0.0: {}
1351 |
1352 | normalize-range@0.1.2: {}
1353 |
1354 | object-assign@4.1.1: {}
1355 |
1356 | object-hash@3.0.0: {}
1357 |
1358 | package-json-from-dist@1.0.0: {}
1359 |
1360 | path-key@3.1.1: {}
1361 |
1362 | path-parse@1.0.7: {}
1363 |
1364 | path-scurry@1.11.1:
1365 | dependencies:
1366 | lru-cache: 10.4.3
1367 | minipass: 7.1.2
1368 |
1369 | picocolors@1.0.1: {}
1370 |
1371 | picomatch@2.3.1: {}
1372 |
1373 | pify@2.3.0: {}
1374 |
1375 | pirates@4.0.6: {}
1376 |
1377 | postcss-import@15.1.0(postcss@8.4.39):
1378 | dependencies:
1379 | postcss: 8.4.39
1380 | postcss-value-parser: 4.2.0
1381 | read-cache: 1.0.0
1382 | resolve: 1.22.8
1383 |
1384 | postcss-js@4.0.1(postcss@8.4.39):
1385 | dependencies:
1386 | camelcase-css: 2.0.1
1387 | postcss: 8.4.39
1388 |
1389 | postcss-load-config@4.0.2(postcss@8.4.39):
1390 | dependencies:
1391 | lilconfig: 3.1.2
1392 | yaml: 2.4.5
1393 | optionalDependencies:
1394 | postcss: 8.4.39
1395 |
1396 | postcss-nested@6.0.1(postcss@8.4.39):
1397 | dependencies:
1398 | postcss: 8.4.39
1399 | postcss-selector-parser: 6.1.1
1400 |
1401 | postcss-selector-parser@6.0.10:
1402 | dependencies:
1403 | cssesc: 3.0.0
1404 | util-deprecate: 1.0.2
1405 |
1406 | postcss-selector-parser@6.1.1:
1407 | dependencies:
1408 | cssesc: 3.0.0
1409 | util-deprecate: 1.0.2
1410 |
1411 | postcss-value-parser@4.2.0: {}
1412 |
1413 | postcss@8.4.31:
1414 | dependencies:
1415 | nanoid: 3.3.7
1416 | picocolors: 1.0.1
1417 | source-map-js: 1.2.0
1418 |
1419 | postcss@8.4.39:
1420 | dependencies:
1421 | nanoid: 3.3.7
1422 | picocolors: 1.0.1
1423 | source-map-js: 1.2.0
1424 |
1425 | queue-microtask@1.2.3: {}
1426 |
1427 | react-dom@19.0.0-rc-8b08e99e-20240713(react@19.0.0-rc-8b08e99e-20240713):
1428 | dependencies:
1429 | react: 19.0.0-rc-8b08e99e-20240713
1430 | scheduler: 0.25.0-rc-8b08e99e-20240713
1431 |
1432 | react@19.0.0-rc-8b08e99e-20240713: {}
1433 |
1434 | read-cache@1.0.0:
1435 | dependencies:
1436 | pify: 2.3.0
1437 |
1438 | readdirp@3.6.0:
1439 | dependencies:
1440 | picomatch: 2.3.1
1441 |
1442 | resolve@1.22.8:
1443 | dependencies:
1444 | is-core-module: 2.15.0
1445 | path-parse: 1.0.7
1446 | supports-preserve-symlinks-flag: 1.0.0
1447 |
1448 | reusify@1.0.4: {}
1449 |
1450 | run-parallel@1.2.0:
1451 | dependencies:
1452 | queue-microtask: 1.2.3
1453 |
1454 | scheduler@0.25.0-rc-8b08e99e-20240713: {}
1455 |
1456 | semver@7.6.3:
1457 | optional: true
1458 |
1459 | sharp@0.33.4:
1460 | dependencies:
1461 | color: 4.2.3
1462 | detect-libc: 2.0.3
1463 | semver: 7.6.3
1464 | optionalDependencies:
1465 | '@img/sharp-darwin-arm64': 0.33.4
1466 | '@img/sharp-darwin-x64': 0.33.4
1467 | '@img/sharp-libvips-darwin-arm64': 1.0.2
1468 | '@img/sharp-libvips-darwin-x64': 1.0.2
1469 | '@img/sharp-libvips-linux-arm': 1.0.2
1470 | '@img/sharp-libvips-linux-arm64': 1.0.2
1471 | '@img/sharp-libvips-linux-s390x': 1.0.2
1472 | '@img/sharp-libvips-linux-x64': 1.0.2
1473 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.2
1474 | '@img/sharp-libvips-linuxmusl-x64': 1.0.2
1475 | '@img/sharp-linux-arm': 0.33.4
1476 | '@img/sharp-linux-arm64': 0.33.4
1477 | '@img/sharp-linux-s390x': 0.33.4
1478 | '@img/sharp-linux-x64': 0.33.4
1479 | '@img/sharp-linuxmusl-arm64': 0.33.4
1480 | '@img/sharp-linuxmusl-x64': 0.33.4
1481 | '@img/sharp-wasm32': 0.33.4
1482 | '@img/sharp-win32-ia32': 0.33.4
1483 | '@img/sharp-win32-x64': 0.33.4
1484 | optional: true
1485 |
1486 | shebang-command@2.0.0:
1487 | dependencies:
1488 | shebang-regex: 3.0.0
1489 |
1490 | shebang-regex@3.0.0: {}
1491 |
1492 | signal-exit@4.1.0: {}
1493 |
1494 | simple-swizzle@0.2.2:
1495 | dependencies:
1496 | is-arrayish: 0.3.2
1497 | optional: true
1498 |
1499 | source-map-js@1.2.0: {}
1500 |
1501 | streamsearch@1.1.0: {}
1502 |
1503 | string-width@4.2.3:
1504 | dependencies:
1505 | emoji-regex: 8.0.0
1506 | is-fullwidth-code-point: 3.0.0
1507 | strip-ansi: 6.0.1
1508 |
1509 | string-width@5.1.2:
1510 | dependencies:
1511 | eastasianwidth: 0.2.0
1512 | emoji-regex: 9.2.2
1513 | strip-ansi: 7.1.0
1514 |
1515 | strip-ansi@6.0.1:
1516 | dependencies:
1517 | ansi-regex: 5.0.1
1518 |
1519 | strip-ansi@7.1.0:
1520 | dependencies:
1521 | ansi-regex: 6.0.1
1522 |
1523 | styled-jsx@5.1.6(react@19.0.0-rc-8b08e99e-20240713):
1524 | dependencies:
1525 | client-only: 0.0.1
1526 | react: 19.0.0-rc-8b08e99e-20240713
1527 |
1528 | sucrase@3.35.0:
1529 | dependencies:
1530 | '@jridgewell/gen-mapping': 0.3.5
1531 | commander: 4.1.1
1532 | glob: 10.4.5
1533 | lines-and-columns: 1.2.4
1534 | mz: 2.7.0
1535 | pirates: 4.0.6
1536 | ts-interface-checker: 0.1.13
1537 |
1538 | supports-preserve-symlinks-flag@1.0.0: {}
1539 |
1540 | tailwindcss@3.4.5:
1541 | dependencies:
1542 | '@alloc/quick-lru': 5.2.0
1543 | arg: 5.0.2
1544 | chokidar: 3.6.0
1545 | didyoumean: 1.2.2
1546 | dlv: 1.1.3
1547 | fast-glob: 3.3.2
1548 | glob-parent: 6.0.2
1549 | is-glob: 4.0.3
1550 | jiti: 1.21.6
1551 | lilconfig: 2.1.0
1552 | micromatch: 4.0.7
1553 | normalize-path: 3.0.0
1554 | object-hash: 3.0.0
1555 | picocolors: 1.0.1
1556 | postcss: 8.4.39
1557 | postcss-import: 15.1.0(postcss@8.4.39)
1558 | postcss-js: 4.0.1(postcss@8.4.39)
1559 | postcss-load-config: 4.0.2(postcss@8.4.39)
1560 | postcss-nested: 6.0.1(postcss@8.4.39)
1561 | postcss-selector-parser: 6.1.1
1562 | resolve: 1.22.8
1563 | sucrase: 3.35.0
1564 | transitivePeerDependencies:
1565 | - ts-node
1566 |
1567 | thenify-all@1.6.0:
1568 | dependencies:
1569 | thenify: 3.3.1
1570 |
1571 | thenify@3.3.1:
1572 | dependencies:
1573 | any-promise: 1.3.0
1574 |
1575 | to-regex-range@5.0.1:
1576 | dependencies:
1577 | is-number: 7.0.0
1578 |
1579 | ts-interface-checker@0.1.13: {}
1580 |
1581 | tslib@2.6.3: {}
1582 |
1583 | typescript@5.5.3: {}
1584 |
1585 | undici-types@5.26.5: {}
1586 |
1587 | update-browserslist-db@1.1.0(browserslist@4.23.2):
1588 | dependencies:
1589 | browserslist: 4.23.2
1590 | escalade: 3.1.2
1591 | picocolors: 1.0.1
1592 |
1593 | util-deprecate@1.0.2: {}
1594 |
1595 | which@2.0.2:
1596 | dependencies:
1597 | isexe: 2.0.0
1598 |
1599 | wrap-ansi@7.0.0:
1600 | dependencies:
1601 | ansi-styles: 4.3.0
1602 | string-width: 4.2.3
1603 | strip-ansi: 6.0.1
1604 |
1605 | wrap-ansi@8.1.0:
1606 | dependencies:
1607 | ansi-styles: 6.2.1
1608 | string-width: 5.1.2
1609 | strip-ansi: 7.1.0
1610 |
1611 | yaml@2.4.5: {}
1612 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg
--------------------------------------------------------------------------------
/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg
--------------------------------------------------------------------------------
/public/grid.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg
--------------------------------------------------------------------------------
/public/nextjs-icon-light-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/public/nextjs-icon-light-background.png
--------------------------------------------------------------------------------
/public/patrick-OIFgeLnjwrM-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/public/patrick-OIFgeLnjwrM-unsplash.jpg
--------------------------------------------------------------------------------
/public/prince-akachi-LWkFHEGpleE-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/public/prince-akachi-LWkFHEGpleE-unsplash.jpg
--------------------------------------------------------------------------------
/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vercel-labs/next-partial-prerendering/89a7ef8ca8804dc0d49c72199970a7c548d66b9c/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import colors from 'tailwindcss/colors';
2 | import { Config } from 'tailwindcss';
3 |
4 | export default {
5 | content: [
6 | './app/**/*.{js,ts,jsx,tsx,mdx}',
7 | './components/**/*.{js,ts,jsx,tsx,mdx}',
8 | ],
9 | future: {
10 | hoverOnlyWhenSupported: true,
11 | },
12 | darkMode: 'class',
13 | theme: {
14 | extend: {
15 | // https://vercel.com/design/color
16 | colors: {
17 | gray: colors.zinc,
18 | 'gray-1000': 'rgb(17,17,19)',
19 | 'gray-1100': 'rgb(10,10,11)',
20 | vercel: {
21 | pink: '#FF0080',
22 | blue: '#0070F3',
23 | cyan: '#50E3C2',
24 | orange: '#F5A623',
25 | violet: '#7928CA',
26 | },
27 | },
28 | backgroundImage: ({ theme }) => ({
29 | 'vc-border-gradient': `radial-gradient(at left top, ${theme(
30 | 'colors.gray.500',
31 | )}, 50px, ${theme('colors.gray.800')} 50%)`,
32 | }),
33 | keyframes: ({ theme }) => ({
34 | rerender: {
35 | '0%': {
36 | ['border-color']: theme('colors.vercel.pink'),
37 | },
38 | '40%': {
39 | ['border-color']: theme('colors.vercel.pink'),
40 | },
41 | },
42 | highlight: {
43 | '0%': {
44 | background: theme('colors.vercel.pink'),
45 | color: theme('colors.white'),
46 | },
47 | '40%': {
48 | background: theme('colors.vercel.pink'),
49 | color: theme('colors.white'),
50 | },
51 | },
52 | loading: {
53 | '0%': {
54 | opacity: '.2',
55 | },
56 | '20%': {
57 | opacity: '1',
58 | transform: 'translateX(1px)',
59 | },
60 | to: {
61 | opacity: '.2',
62 | },
63 | },
64 | shimmer: {
65 | '100%': {
66 | transform: 'translateX(100%)',
67 | },
68 | },
69 | translateXReset: {
70 | '100%': {
71 | transform: 'translateX(0)',
72 | },
73 | },
74 | fadeToTransparent: {
75 | '0%': {
76 | opacity: '1',
77 | },
78 | '40%': {
79 | opacity: '1',
80 | },
81 | '100%': {
82 | opacity: '0',
83 | },
84 | },
85 | }),
86 | },
87 | },
88 | plugins: [require('@tailwindcss/typography'), require('@tailwindcss/forms')],
89 | } satisfies Config;
90 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "baseUrl": ".",
18 | "paths": {
19 | "#/*": ["./*"]
20 | },
21 | "plugins": [
22 | {
23 | "name": "next"
24 | }
25 | ]
26 | },
27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
28 | "exclude": ["node_modules"]
29 | }
30 |
--------------------------------------------------------------------------------
/types/product.d.ts:
--------------------------------------------------------------------------------
1 | export type Product = {
2 | id: string;
3 | stock: number;
4 | rating: number;
5 | name: string;
6 | description: string;
7 | price: Price;
8 | isBestSeller: boolean;
9 | leadTime: number;
10 | image?: string;
11 | imageBlur?: string;
12 | discount?: Discount;
13 | usedPrice?: UsedPrice;
14 | };
15 |
16 | type Price = {
17 | amount: number;
18 | currency: Currency;
19 | scale: number;
20 | };
21 |
22 | type Currency = {
23 | code: string;
24 | base: number;
25 | exponent: number;
26 | };
27 |
28 | type Discount = {
29 | percent: number;
30 | expires?: number;
31 | };
32 |
33 | type UsedPrice = {
34 | amount: number;
35 | currency: Currency;
36 | scale: number;
37 | };
38 |
--------------------------------------------------------------------------------
/types/review.d.ts:
--------------------------------------------------------------------------------
1 | export type Review = {
2 | id: string;
3 | name: string;
4 | rating: number;
5 | text: string;
6 | };
7 |
--------------------------------------------------------------------------------