From 7d4ad9a87e25c9665bddb2e569fcf4fc0a7bcfcb Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 25 Oct 2026 02:32:58 -0600 Subject: [PATCH 1/7] Show Redact framework setup and measured client savings --- src/components/landing/RedactLanding.tsx | 339 +++++++++++++++++------ 1 file changed, 249 insertions(+), 90 deletions(-) diff --git a/src/components/landing/RedactLanding.tsx b/src/components/landing/RedactLanding.tsx index 667ecf139..a08282a98 100644 --- a/src/components/landing/RedactLanding.tsx +++ b/src/components/landing/RedactLanding.tsx @@ -1,142 +1,301 @@ +import { useState } from 'react' import { Link } from '@tanstack/react-router' import { CodeBlock } from '~/components/markdown/CodeBlock' -import { - LandingSection, - LandingSectionIntro, - LibraryLandingShell, -} from './LibraryLanding' +import { LandingSection, LibraryLandingShell } from './LibraryLanding' const repo = 'https://github.com/TanStack/redact' +const setups = [ + { + name: 'Next.js', + file: 'next.config.mjs', + guide: 'next', + detail: + 'App Router and Pages Router, with Turbopack or Webpack. Keep React installed, it still runs your server.', + code: `import { withRedact } from '@tanstack/redact/next' + +export default withRedact({ + // Your existing Next.js options +})`, + }, + { + name: 'Vinext', + file: 'vite.config.ts', + guide: 'vinext', + detail: + 'Add Redact after Vinext. Keep your Next.js imports, routes, and server React.', + code: `import { defineConfig } from 'vite' +import vinext from 'vinext' +import { redact } from '@tanstack/redact/vinext' + +export default defineConfig({ + plugins: [vinext(), redact()], +})`, + }, + { + name: 'Vite', + file: 'vite.config.ts', + guide: 'vite-plugin', + detail: + 'Keep your React or framework plugin. The Vite integration handles client and SSR builds, with optional features you can leave out.', + code: `import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { redact } from '@tanstack/redact/vite' + +export default defineConfig({ + plugins: [react(), redact()], +})`, + }, +] export default function RedactLanding() { + const [selected, setSelected] = useState(0) + const setup = setups[selected] + return ( -
+
+
+ 39.4 KB less. +
+

+ Client output in Vinext's benchmark, gzipped. +

+
+ {[ + { + name: 'Vinext + React', + size: '154.9 KB', + width: '100%', + redact: false, + }, + { + name: 'Vinext + Redact', + size: '115.5 KB', + width: '74.6%', + redact: true, + }, + ].map((row) => ( +
+
+ {row.name} + {row.size} +
+ + ))} +
+
+

+ 25.4% smaller across six builds of the same app. Includes all + emitted client JS and CSS, including lazy routes. +

+ + Measurements and timing tradeoffs ↗ + +
+
+ } + > + +
+
+

+ Bring your framework. +

+
+ {setups.map((item, index) => ( + + ))} +
+

+ {setup.detail} +

- - ≈3× smaller - - - 33.7% of React's runtime bundle size in our default benchmark - + {setup.name} setup and coverage ↗ +

+ The Next.js and Vinext release is waiting on upstream fixes.{' '} + + Track the release + + . +

+
+
+ + {setup.code} + +
+
+
+ +
+
+

+ Server Components stay with React. +

+

+ In Next.js and Vinext, the framework keeps server rendering, + Server Components, caching, and action transport. Redact picks up + in the browser, hydrates the HTML, and runs your client + components. +

+
+
+ Server + React +
+ HTML + Flight → +
+ Browser + Redact +
+
+
+
+

+ Smaller comes with a choice. +

+

+ Redact renders synchronously, without React's time slicing or + interruptible component renders. Suspended transitions can keep + the current screen visible, actions can show pending and + optimistic state, and streamed content can still arrive as it's + ready. +

- - 12.5 kB - - - nano DOM client, gzipped - + Rendering and API differences ↗
- - {`import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' -import { redact } from '@tanstack/redact/vite' - -export default defineConfig({ - plugins: [react(), redact()], -})`} -
- } - > - -
+ + +
- +

+ More than a counter demo. +

- We trade concurrent scheduling for a smaller, synchronous runtime. - Streaming SSR, hydration, and Suspense are still on board. + The compatibility suite runs real browser journeys in Chromium, + Firefox, and WebKit. Both App Router and Pages Router are in the + matrix, including apps that only use Pages Router.

- API differences ↗ + Test matrix and recorded results ↗
- - {`import { useState } from 'react' - -export function Counter() { - const [count, setCount] = useState(0) - return ( - - ) -}`} - +
    +
  • + + Navigate without losing your place. + + + Retained layouts, back and forward, shallow routing, redirects, + and canceled navigation. + +
  • +
  • + Submit, wait, and recover. + + Server Actions, pending forms, optimistic updates, uploads, and + error boundaries. + +
  • +
  • + + Pick up where the server left off. + + + Hydration, streamed Suspense, Cache Components, and Fast Refresh + that keeps state through an edit. + +
  • +
- -
- -
- - {`// A client-rendered app without class components + +
+
+

+ Vite apps can go smaller still. +

+

+ Leave out features your app doesn't use, or start with nano and + add them back. Next.js and Vinext use the full runtime so their + framework features stay available. +

+ + Choose your Vite features ↗ + +
+ + {`// A client-rendered app without class components redact({ features: { hydration: false, classComponents: false }, }) // All optional features off, then context enabled redact({ preset: 'nano', features: { context: true } })`} - -
-
- - -
- -
-

- Debugging tools belong in development, so we leave them out of - your production build. All of this adds zero bytes to what your - users download. -

- - React DevTools support ↗ - -
+
From 75811c51afcc759cf6777c746d099a129b1e2034 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 25 Oct 2026 03:19:03 -0600 Subject: [PATCH 2/7] docs: prepare Redact Next.js and Vinext launch --- launch/redact-next-vinext.md | 105 +++++++++++++++++++++++++++++++ src/blog/redact-nextjs-vinext.md | 79 +++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 launch/redact-next-vinext.md create mode 100644 src/blog/redact-nextjs-vinext.md diff --git a/launch/redact-next-vinext.md b/launch/redact-next-vinext.md new file mode 100644 index 000000000..12b1bcc2f --- /dev/null +++ b/launch/redact-next-vinext.md @@ -0,0 +1,105 @@ +# Redact Next.js and Vinext launch + +Prepared October 25, 2026. Publication is on hold. The announcement, release summary, and posts below are for use after the published package passes the existing release gates. No announcement has been sent or scheduled. + +The audience is developers who already use React with Next.js, Vinext, or Vite and want smaller client bundles without rewriting their components. Lead with framework support, then show the measured size difference and explain the scheduling tradeoff. + +## Release dependencies + +| Dependency | Status on October 25 | Required next step | +| ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------- | +| [Redact release](https://github.com/TanStack/redact/pull/52) | Held by required framework checks | Pass the complete matrices with published, unpatched dependencies | +| [Cloudflare security fix](https://github.com/cloudflare/workers-sdk/pull/16476) | Merged | Verify patched stable packages are published and used by the fixture | +| [Cloudflare development evaluator](https://github.com/cloudflare/workers-sdk/pull/16466) | Open | Merge, publish, and verify the real Worker development journeys | +| [Vinext dependency optimizer](https://github.com/cloudflare/vinext/pull/4268) | Open | Merge, publish, and verify installed-package behavior | +| [Vinext Pages data redirects](https://github.com/cloudflare/vinext/pull/4299) | Open | Merge, publish, and verify Pages navigation state | +| [Next.js 16.2 source backport](https://github.com/tannerlinsley/next.js/tree/taren/backport-next-162-development-cache) | Tested, awaiting upstream acceptance | Obtain a published 16.2 patch, then pass the original Firefox cases | + +Cloudflare's development fix has 87 successful checks and three skipped checks on commit `6ae1ed8`. npm still serves Cloudflare Vite plugin 1.65.0, Wrangler 4.152.0, and Vinext 1.3.0 as of 09:16 UTC on October 25. The patched stable tooling has not shipped. + +The [upstream evidence](https://github.com/TanStack/redact/blob/taren/stable-framework-support/benchmarks/upstream/README.md) tracks the full diagnostic history. A merged fix or a passing source backport does not clear the published-package gate. Preserve the current supported versions, all tests, and both size limits. + +## Publish in this order + +1. Update fixture pins to the upstream releases containing the fixes. Run the existing complete package, browser, framework, deployment, and hosted checks. Confirm the default Vite bundle stays at or below 23,335 gzip bytes and the full client stays at or below 28,183. +2. Merge the compatibility PR after its required checks pass. Let Changesets create the version PR, validate and merge it through the normal workflow, and verify the resulting npm version and exports. Install it in fresh consumers and confirm both documented integrations work. The expected minor release is 0.2.0, confirm the actual version from automation. +3. Reconcile the final published versions and evidence with the docs, landing page, and announcement. If the dependency or runtime changes affect the measured app, refresh the benchmark before reusing its numbers. Remove the pending-release paragraph from `RedactLanding.tsx`, remove the draft notice from the article, set its actual publication date, and set `draft: false`. Keep the statement about synchronous rendering. +4. Publish the [website PR](https://github.com/TanStack/tanstack.com/pull/1422). Verify the live landing page, both setup guides, the benchmark link, and the announcement before directing readers to them. +5. Use the release summary and publish the X thread below. Each launch link points back to TanStack. +6. During the first day, collect reproducible reports with framework version, router, bundler, development or production mode, and native React behavior. Link existing issues where possible. Fix root causes through the normal release process. +7. Two or three days later, share the side-by-side Next.js journey. A week later, publish a real app's measured result if one is available, including route, compression, dependencies, and scheduling tradeoffs. Keep the measured Vinext fixture clearly identified until then. + +## Announcement + +The website draft is [Redact for Next.js and Vinext](../src/blog/redact-nextjs-vinext.md). Its intended URL is `https://tanstack.com/blog/redact-nextjs-vinext`. The draft remains unlisted, but this site's draft URLs can be opened directly, so its visible release notice stays in place until launch. + +The existing landing page is the main launch destination: `https://tanstack.com/redact/latest`. Framework setup stays in the existing docs. GitHub release notes link to those same guides and evidence. + +## Release summary + +Redact adds stable browser integrations for Next.js and Vinext, covering App Router and Pages Router. Keep your React imports and dependencies. Native React continues to handle server rendering and Server Components, while Redact hydrates and renders in the browser. + +In the measured Vinext app, Redact reduced all emitted client JavaScript and CSS from 154.9 KB to 115.5 KB gzip, including lazy routes. Production builds took about 18 ms longer. Browser rendering and hydration speed were not measured. Redact renders synchronously, without React's time slicing or interruptible component renders. + +[Next.js setup](https://tanstack.com/redact/latest/docs/next) · [Vinext setup](https://tanstack.com/redact/latest/docs/vinext) · [Compatibility](https://tanstack.com/redact/latest/docs/compatibility) · [Benchmark](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md) + +## X thread + +Post 1: + +```text +Redact now supports Next.js and Vinext, including App Router and Pages Router. + +Keep your components and React imports, use a smaller browser runtime. React stays on the server. + +https://tanstack.com/redact/latest?utm_source=x&utm_medium=social&utm_campaign=redact-next-vinext +``` + +Post 2: + +```text +In Vinext's benchmark app, Redact cut emitted client JS + CSS from 154.9 KB to 115.5 KB gzip. That's 25.4% smaller across six builds. + +This includes lazy routes, not one page's download. Builds took 18 ms longer. We didn't measure browser rendering speed. +``` + +Post 3: + +```text +Redact renders synchronously, without React's time slicing or interruptible renders. A heavy render can still delay input. + +Suspended transitions, pending forms, and optimistic state are covered. The scheduling tradeoff matters, so try your own busiest screen. +``` + +## Journey follow-up + +Use the existing `pnpm example:next:journey` demo from the released Redact source. Show React and Redact side by side through navigation, an optimistic save, validation, comments, and returning to the original page. Keep the renderer labels visible and record actual browser behavior at normal playback speed. This demonstrates behavior, not latency or frame-rate equivalence. + +Caption: + +```text +Same Next.js app, React and Redact side by side: navigation, an optimistic save, server validation, comments, and back again. + +The comparison app is in the repo so you can run it yourself. + +https://tanstack.com/blog/redact-nextjs-vinext?utm_source=x&utm_medium=social&utm_campaign=redact-next-vinext +``` + +After release, an optional shared walkthrough with a Vinext contributor could use this same demo and the reproducible benchmark. The invitation should ask for their technical perspective, with no implied endorsement. Prepare any outreach for explicit approval before sending it. + +## Measure adoption + +Use the site's existing page views and campaign parameters. Compare the seven days after launch with the preceding seven days for Redact landing visits and visits to the Next.js and Vinext guides. Track confirmed compatibility reports and their resolution separately. npm downloads provide background context, they do not identify which framework someone used or prove a successful migration. + +## Claim checks + +| Claim | Evidence and limit | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 39.4 KB / 25.4% less output | [Vinext benchmark](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md), same app and dependencies, all emitted client JS and CSS including lazy routes, six builds | +| 39.2 KB / 27.2% less entry output | Same report, browser entry plus eager JavaScript imports, not every possible route request | +| Next.js savings | App-specific. The benchmark's 74.5 KB comparison changes both framework and renderer, so it cannot establish Redact-only savings in Next.js | +| Performance | The measured build was 1.9% slower, startup differences were inconclusive, browser and server rendering speed were not measured | +| Framework coverage | [Next.js report](https://github.com/TanStack/redact/blob/main/benchmarks/NEXT_COVERAGE.md) and [Vinext report](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_COVERAGE.md), all required cases must pass before the stable announcement | +| Rendering tradeoff | [Compatibility guide](https://tanstack.com/redact/latest/docs/compatibility), synchronous rendering with no time slicing or interruptible component renders | + +Reply to requests for a universal Next.js percentage with the app-specific distinction above. Reply to scheduling questions with the actual rendering tradeoff. Avoid claims of universal React parity or faster hydration. diff --git a/src/blog/redact-nextjs-vinext.md b/src/blog/redact-nextjs-vinext.md new file mode 100644 index 000000000..f49b3ffe2 --- /dev/null +++ b/src/blog/redact-nextjs-vinext.md @@ -0,0 +1,79 @@ +--- +title: Redact for Next.js and Vinext +published: 2026-10-25 +draft: true +excerpt: Keep your React components and imports, use a smaller browser runtime. App Router and Pages Router, with React still running on the server. +authors: + - Tanner Linsley +library: redact +--- + +> This announcement is a draft. The release is waiting on upstream fixes and the complete compatibility checks. [Follow the release](https://github.com/TanStack/redact/pull/52). + +Redact's Next.js and Vinext integrations let you keep your components, hooks, and React imports while swapping in a smaller browser runtime. That includes App Router and Pages Router, even if your app only uses Pages Router. + +React still handles server rendering and Server Components. Your framework still owns routing, caching, and Server Action transport. Redact hydrates the HTML and runs your client components in the browser. + +## 39.4 KB less client output + +We ran Vinext's benchmark suite with React and Redact on the same app, with the same dependencies, for six measured rounds each. + +| Gzipped client output | React | Redact | +| ------------------------------------------ | -------: | -------: | +| All emitted JavaScript and CSS | 154.9 KB | 115.5 KB | +| Browser entry and eager JavaScript imports | 144.2 KB | 105.0 KB | + +That's **25.4% less total client output**, with identical sizes across all six builds. The total includes lazy routes, so it isn't the download for a single page. KB here means 1,000 bytes. + +These are Vinext measurements. They don't establish the savings for every Next.js app. The [full report](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md) includes the workloads, versions, raw results, and a separate Next.js baseline. + +The build took about 18 ms longer with Redact, a 1.9% increase. Startup differences were inconclusive. This suite didn't time browser rendering, hydration, responsiveness, or production SSR throughput. + +## Add the integration + +Install `@tanstack/redact` and keep your React dependencies. Your component imports stay the same. + +For Next.js, wrap your existing configuration: + +```js +// next.config.mjs +import { withRedact } from '@tanstack/redact/next' + +export default withRedact({ + // Your existing Next.js options +}) +``` + +The wrapper configures Turbopack and Webpack. The accepted release lines are Next.js 15.5 and 16.0 through 16.4. Prereleases and untested minor versions are rejected. The [Next.js guide](/redact/latest/docs/next) has the pinned versions and coverage details. + +For Vinext, add Redact after `vinext()`: + +```js +// vite.config.ts +import { defineConfig } from 'vite' +import vinext from 'vinext' +import { redact } from '@tanstack/redact/vinext' + +export default defineConfig({ + plugins: [vinext(), redact()], +}) +``` + +Keep React, React DOM, and React Server DOM installed. Both framework integrations leave the server on React, so don't change `jsxImportSource` to Redact. See the [Vinext guide](/redact/latest/docs/vinext) for its dependency pins. Existing Vite apps can keep using the [Vite integration](/redact/latest/docs/vite-plugin). + +## What happens when the app gets busy? + +Redact renders synchronously. It doesn't have React's time slicing or interruptible component renders, so a long render can still hold up input. If your app relies on that scheduling behavior, this is a tradeoff to evaluate in your own app. + +Suspended transitions can keep the current screen visible. Forms can show pending state, optimistic changes can commit or roll back, and streamed content can arrive as it's ready. The [compatibility guide](/redact/latest/docs/compatibility) spells out the differences. + +The browser suites exercise hydration and DOM identity, navigation and history, streamed Suspense, Server Actions, optimistic state, Cache Components, errors, and Fast Refresh. They use native React controls and run in Chromium, Firefox, and WebKit. The full reports show every configuration and retain failures: [Next.js](https://github.com/TanStack/redact/blob/main/benchmarks/NEXT_COVERAGE.md), [Vinext](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_COVERAGE.md). + +To compare an actual user journey, the repository includes the same Next.js app running with React and Redact side by side. It walks through navigation, an optimistic save, server validation, comments, and returning to the original page. From a repository checkout, run: + +```sh +pnpm install +pnpm example:next:journey +``` + +Open the local URL printed by the runner, then use the [framework setup guides](/redact/latest/docs/installation) to try Redact in your own app. From b0fa9b2cfc979855edbbe76be7d88768ff7530be Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 25 Oct 2026 05:48:58 -0600 Subject: [PATCH 3/7] docs: prepare the verified Redact framework launch --- launch/redact-next-vinext.md | 39 +++++++++++++----------- src/blog/redact-nextjs-vinext.md | 4 +-- src/components/landing/RedactLanding.tsx | 22 +++++++------ 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/launch/redact-next-vinext.md b/launch/redact-next-vinext.md index 12b1bcc2f..081884f79 100644 --- a/launch/redact-next-vinext.md +++ b/launch/redact-next-vinext.md @@ -1,34 +1,37 @@ # Redact Next.js and Vinext launch -Prepared October 25, 2026. Publication is on hold. The announcement, release summary, and posts below are for use after the published package passes the existing release gates. No announcement has been sent or scheduled. +Prepared October 25, 2026. The announcement, release summary, and posts below are ready for publication after the package is released and its published integrations are verified. No announcement has been sent or scheduled. The audience is developers who already use React with Next.js, Vinext, or Vite and want smaller client bundles without rewriting their components. Lead with framework support, then show the measured size difference and explain the scheduling tradeoff. -## Release dependencies +## Release checks -| Dependency | Status on October 25 | Required next step | -| ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------- | -| [Redact release](https://github.com/TanStack/redact/pull/52) | Held by required framework checks | Pass the complete matrices with published, unpatched dependencies | -| [Cloudflare security fix](https://github.com/cloudflare/workers-sdk/pull/16476) | Merged | Verify patched stable packages are published and used by the fixture | -| [Cloudflare development evaluator](https://github.com/cloudflare/workers-sdk/pull/16466) | Open | Merge, publish, and verify the real Worker development journeys | -| [Vinext dependency optimizer](https://github.com/cloudflare/vinext/pull/4268) | Open | Merge, publish, and verify installed-package behavior | -| [Vinext Pages data redirects](https://github.com/cloudflare/vinext/pull/4299) | Open | Merge, publish, and verify Pages navigation state | -| [Next.js 16.2 source backport](https://github.com/tannerlinsley/next.js/tree/taren/backport-next-162-development-cache) | Tested, awaiting upstream acceptance | Obtain a published 16.2 patch, then pass the original Firefox cases | +The release candidate now carries maintained framework corrections in Redact. It does not require another upstream release. The existing required checks still decide readiness. -Cloudflare's development fix has 87 successful checks and three skipped checks on commit `6ae1ed8`. npm still serves Cloudflare Vite plugin 1.65.0, Wrangler 4.152.0, and Vinext 1.3.0 as of 09:16 UTC on October 25. The patched stable tooling has not shipped. +| Check | Current evidence | Required next step | +| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| [Redact release](https://github.com/TanStack/redact/pull/52) | 1,859 runtime tests, types, packaging, and all 38 size gates pass | Require the final PR and publication checks to pass | +| Next.js compatibility | All 162 configurations and 2,694 scenarios pass across six versions | Retain the required complete matrix gate | +| Vinext and Cloudflare | All 102 local configurations and 1,410 scenarios pass, plus all 18 hosted configurations and 282 scenarios | Retain the final package and lockfile evidence | +| Dependency security | Undici 7.30.1 and fflate 0.7.5 pass their regressions, final consumer audit has zero vulnerabilities | Retain both documented overrides and the final lockfile | +| Landing page and announcement | Final benchmark and compatibility evidence incorporated | Publish after the package is available and verify the live pages | -The [upstream evidence](https://github.com/TanStack/redact/blob/taren/stable-framework-support/benchmarks/upstream/README.md) tracks the full diagnostic history. A merged fix or a passing source backport does not clear the published-package gate. Preserve the current supported versions, all tests, and both size limits. +The final benchmark retains the 39.4 KB gzip client saving. Production build times are effectively equal; local development startup improved by 2.2% for App Router and 4.9% for the large Pages fixture. Browser rendering speed was not measured. + +The [adapter docs](https://github.com/TanStack/redact/blob/taren/stable-framework-support/docs/vinext.md) explain the owned Cloudflare integration and package-manager overrides. The [upstream evidence](https://github.com/TanStack/redact/blob/taren/stable-framework-support/benchmarks/upstream/README.md) preserves the original failures and contributions. Keep all supported versions, tests, and size limits. ## Publish in this order -1. Update fixture pins to the upstream releases containing the fixes. Run the existing complete package, browser, framework, deployment, and hosted checks. Confirm the default Vite bundle stays at or below 23,335 gzip bytes and the full client stays at or below 28,183. -2. Merge the compatibility PR after its required checks pass. Let Changesets create the version PR, validate and merge it through the normal workflow, and verify the resulting npm version and exports. Install it in fresh consumers and confirm both documented integrations work. The expected minor release is 0.2.0, confirm the actual version from automation. -3. Reconcile the final published versions and evidence with the docs, landing page, and announcement. If the dependency or runtime changes affect the measured app, refresh the benchmark before reusing its numbers. Remove the pending-release paragraph from `RedactLanding.tsx`, remove the draft notice from the article, set its actual publication date, and set `draft: false`. Keep the statement about synchronous rendering. +1. Confirm the final PR passes its existing required checks and retains the complete package, browser, framework, deployment, and hosted evidence, using its maintained adapters and documented dependency overrides. Confirm the default Vite bundle stays at or below 23,335 gzip bytes and the full client stays at or below 28,183. +2. Merge the compatibility PR after its required checks pass. Let Changesets create the version PR, validate and merge it through the normal workflow, and verify the resulting npm version and exports. Install it in fresh consumers and confirm both documented integrations work. Changesets currently plans version 0.2.0, confirm the actual version from the release PR. +3. Reconcile the final published versions and evidence with the docs, landing page, and announcement. If the dependency or runtime changes affect the measured app, refresh the benchmark before reusing its numbers. Remove the pending-release paragraph from `RedactLanding.tsx`, remove the unpublished-release notice from the article, set its actual publication date, and set `draft: false`. Keep the statement about synchronous rendering. 4. Publish the [website PR](https://github.com/TanStack/tanstack.com/pull/1422). Verify the live landing page, both setup guides, the benchmark link, and the announcement before directing readers to them. 5. Use the release summary and publish the X thread below. Each launch link points back to TanStack. 6. During the first day, collect reproducible reports with framework version, router, bundler, development or production mode, and native React behavior. Link existing issues where possible. Fix root causes through the normal release process. 7. Two or three days later, share the side-by-side Next.js journey. A week later, publish a real app's measured result if one is available, including route, compression, dependencies, and scheduling tradeoffs. Keep the measured Vinext fixture clearly identified until then. +The final preview was reviewed at 390 px and 1280 px with the frozen candidate. Framework tabs, hot edits, content rebuilds, and fresh server renders passed. Website type and lint checks pass. + ## Announcement The website draft is [Redact for Next.js and Vinext](../src/blog/redact-nextjs-vinext.md). Its intended URL is `https://tanstack.com/blog/redact-nextjs-vinext`. The draft remains unlisted, but this site's draft URLs can be opened directly, so its visible release notice stays in place until launch. @@ -39,7 +42,7 @@ The existing landing page is the main launch destination: `https://tanstack.com/ Redact adds stable browser integrations for Next.js and Vinext, covering App Router and Pages Router. Keep your React imports and dependencies. Native React continues to handle server rendering and Server Components, while Redact hydrates and renders in the browser. -In the measured Vinext app, Redact reduced all emitted client JavaScript and CSS from 154.9 KB to 115.5 KB gzip, including lazy routes. Production builds took about 18 ms longer. Browser rendering and hydration speed were not measured. Redact renders synchronously, without React's time slicing or interruptible component renders. +In the measured Vinext app, Redact reduced all emitted client JavaScript and CSS from 154.9 KB to 115.5 KB gzip, including lazy routes. Production build times were effectively equal. Browser rendering and hydration speed were not measured. Redact renders synchronously, without React's time slicing or interruptible component renders. [Next.js setup](https://tanstack.com/redact/latest/docs/next) · [Vinext setup](https://tanstack.com/redact/latest/docs/vinext) · [Compatibility](https://tanstack.com/redact/latest/docs/compatibility) · [Benchmark](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md) @@ -60,7 +63,7 @@ Post 2: ```text In Vinext's benchmark app, Redact cut emitted client JS + CSS from 154.9 KB to 115.5 KB gzip. That's 25.4% smaller across six builds. -This includes lazy routes, not one page's download. Builds took 18 ms longer. We didn't measure browser rendering speed. +This includes lazy routes, not one page's download. Build times were effectively equal. Browser rendering speed wasn't measured. ``` Post 3: @@ -98,7 +101,7 @@ Use the site's existing page views and campaign parameters. Compare the seven da | 39.4 KB / 25.4% less output | [Vinext benchmark](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md), same app and dependencies, all emitted client JS and CSS including lazy routes, six builds | | 39.2 KB / 27.2% less entry output | Same report, browser entry plus eager JavaScript imports, not every possible route request | | Next.js savings | App-specific. The benchmark's 74.5 KB comparison changes both framework and renderer, so it cannot establish Redact-only savings in Next.js | -| Performance | The measured build was 1.9% slower, startup differences were inconclusive, browser and server rendering speed were not measured | +| Performance | Build times were effectively equal. Local startup was 2.2% faster for App Router and 4.9% faster for the large Pages fixture. Browser and server rendering speed were not measured | | Framework coverage | [Next.js report](https://github.com/TanStack/redact/blob/main/benchmarks/NEXT_COVERAGE.md) and [Vinext report](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_COVERAGE.md), all required cases must pass before the stable announcement | | Rendering tradeoff | [Compatibility guide](https://tanstack.com/redact/latest/docs/compatibility), synchronous rendering with no time slicing or interruptible component renders | diff --git a/src/blog/redact-nextjs-vinext.md b/src/blog/redact-nextjs-vinext.md index f49b3ffe2..0526cb46a 100644 --- a/src/blog/redact-nextjs-vinext.md +++ b/src/blog/redact-nextjs-vinext.md @@ -8,7 +8,7 @@ authors: library: redact --- -> This announcement is a draft. The release is waiting on upstream fixes and the complete compatibility checks. [Follow the release](https://github.com/TanStack/redact/pull/52). +> This release isn't published yet. [Follow the release](https://github.com/TanStack/redact/pull/52). Redact's Next.js and Vinext integrations let you keep your components, hooks, and React imports while swapping in a smaller browser runtime. That includes App Router and Pages Router, even if your app only uses Pages Router. @@ -27,7 +27,7 @@ That's **25.4% less total client output**, with identical sizes across all six b These are Vinext measurements. They don't establish the savings for every Next.js app. The [full report](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md) includes the workloads, versions, raw results, and a separate Next.js baseline. -The build took about 18 ms longer with Redact, a 1.9% increase. Startup differences were inconclusive. This suite didn't time browser rendering, hydration, responsiveness, or production SSR throughput. +Production build times were effectively equal. Development startup was 2.2% faster for App Router and 4.9% faster for the large Pages fixture in this local run. This suite didn't time browser rendering, hydration, responsiveness, or production SSR throughput. ## Add the integration diff --git a/src/components/landing/RedactLanding.tsx b/src/components/landing/RedactLanding.tsx index a08282a98..fb5bc0a29 100644 --- a/src/components/landing/RedactLanding.tsx +++ b/src/components/landing/RedactLanding.tsx @@ -145,16 +145,18 @@ export default function RedactLanding() { > {setup.name} setup and coverage ↗ -

- The Next.js and Vinext release is waiting on upstream fixes.{' '} - - Track the release - - . -

+ {setup.name !== 'Vite' && ( +

+ The Next.js and Vinext release isn't published yet.{' '} + + Track the release + + . +

+ )}
From 7a2a8e76db5c94972984742aab363a21fa66fdc9 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 25 Oct 2026 11:22:14 -0600 Subject: [PATCH 4/7] feat: compare Redact bundle savings across four frameworks --- launch/benchmarks/redact-frameworks/README.md | 43 ++ .../redact-frameworks/browser-checks.json | 93 +++++ .../benchmarks/redact-frameworks/measure.mjs | 266 ++++++++++++ .../benchmarks/redact-frameworks/package.json | 23 ++ .../benchmarks/redact-frameworks/results.json | 387 ++++++++++++++++++ launch/benchmarks/redact-frameworks/serve.mjs | 112 +++++ .../redact-frameworks/server-checks.json | 46 +++ launch/redact-next-vinext.md | 16 +- src/components/landing/LibraryLanding.tsx | 2 +- src/components/landing/RedactLanding.tsx | 120 ++++-- src/data/redact-framework-sizes.json | 26 ++ 11 files changed, 1084 insertions(+), 50 deletions(-) create mode 100644 launch/benchmarks/redact-frameworks/README.md create mode 100644 launch/benchmarks/redact-frameworks/browser-checks.json create mode 100644 launch/benchmarks/redact-frameworks/measure.mjs create mode 100644 launch/benchmarks/redact-frameworks/package.json create mode 100644 launch/benchmarks/redact-frameworks/results.json create mode 100644 launch/benchmarks/redact-frameworks/serve.mjs create mode 100644 launch/benchmarks/redact-frameworks/server-checks.json create mode 100644 src/data/redact-framework-sizes.json diff --git a/launch/benchmarks/redact-frameworks/README.md b/launch/benchmarks/redact-frameworks/README.md new file mode 100644 index 000000000..23591de14 --- /dev/null +++ b/launch/benchmarks/redact-frameworks/README.md @@ -0,0 +1,43 @@ +# React and Redact client bundles + +Measured October 25, 2026 with the same counter component, controlled input, and CSS in four single-route apps. Each pair changes only the renderer integration. The landing page uses these measurements, with one shared scale for all eight bars. + +| Framework | React | Redact | Saved | +| -------------- | -------: | -------: | -------------: | +| TanStack Start | 109.3 KB | 62.3 KB | 47.0 KB, 43.0% | +| Vite | 68.3 KB | 20.1 KB | 48.1 KB, 70.5% | +| Vinext | 138.1 KB | 98.8 KB | 39.3 KB, 28.5% | +| Next.js | 175.6 KB | 139.9 KB | 35.7 KB, 20.4% | + +These are starter app measurements. A larger app has its own routes, dependencies, and chunk layout, so its percentage will differ. The separate [Vinext benchmark](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md) measures a larger workload over six rounds and saves 39.4 KB, or 25.4%. + +## What the numbers include + +Each file is compressed separately with Node's default `gzipSync`, then the sizes are added. We count all emitted client JavaScript and CSS, including lazy chunks and framework polyfills. KB means 1,000 bytes. These totals are not the download for a single navigation. HTML, inline scripts and Flight payloads, images, source maps, and server output are excluded. + +Start and Vite use Redact's default Vite integration. Start sets `ssr.noExternal: true` in both builds. This lets Vite transform React imports inside server dependencies as well as application code. Without it, Node can load an external dependency with native React alongside application code using Redact. Next.js uses `withRedact` with Turbopack. Vinext uses the maintained integration in both modes, with `renderer: 'react'` or `renderer: 'redact'`, so both builds receive the same platform corrections. Next.js and Vinext keep native React on the server. No presets, feature flags, minifier settings, or application code are changed between the two builds of a framework. + +This is one clean production build per variant, measuring bytes rather than speed. All eight builds were opened in the browser and checked for client startup, a counter update, a controlled input update, and the expected renderer. Start, Vinext, and Next.js were also checked for server-rendered content before JavaScript ran. See [browser checks](./browser-checks.json) and [server checks](./server-checks.json). + +## Versions and source + +- React and React DOM 19.3.1 in every app. +- TanStack Start 1.168.60 and Router 1.170.41. +- Vite 8.3.5, React plugin 6.1.2, and RSC plugin 0.5.38. +- Vinext 1.3.0 and Next.js 16.4.3. +- Node 24.22.0, macOS arm64. +- Redact's 0.2.0 release candidate at [1666d37](https://github.com/TanStack/redact/tree/1666d37ba48c9fbb02e88769ca03d9234a640a76). Its package still identifies itself as 0.1.5 until Changesets versions the release. Tarball SHA-256: `6f8592d92061ab3845b11a5635a2853ec5ba61b600f7ca213cfa42b510ec1099`. + +[Raw results](./results.json) include every emitted file's size and SHA-256, package versions, component and CSS hashes, and the dependency lockfile hash. The [page data](../../../src/data/redact-framework-sizes.json) retains exact byte totals, and the UI calculates its KB, percentages, and bar lengths from those totals. + +## Reproduce + +Use a new directory, copy this folder's `package.json` and `package-lock.json` into it, and place the candidate tarball there as `redact.tgz`. Then run with Node 24.22.0: + +```sh +npm ci --no-audit --no-fund +node /path/to/measure.mjs "$PWD" +node /path/to/serve.mjs "$PWD" +``` + +`measure.mjs` generates every fixture from source, builds React then Redact for each framework, records `results.json`, and preserves all eight builds. `serve.mjs` opens local production previews on ports 4380 through 4387, in the order Start, Vite, Vinext, and Next.js, React first in each pair. The small Node HTTP bridge for Start and Vite is only a preview harness and is not part of the measured output. diff --git a/launch/benchmarks/redact-frameworks/browser-checks.json b/launch/benchmarks/redact-frameworks/browser-checks.json new file mode 100644 index 000000000..f20ff99b5 --- /dev/null +++ b/launch/benchmarks/redact-frameworks/browser-checks.json @@ -0,0 +1,93 @@ +{ + "browser": "Codex in-app browser", + "results": [ + { + "framework": "Start", + "renderer": "react", + "passed": true, + "checks": [ + "hydration", + "counter update", + "controlled input", + "renderer identity" + ] + }, + { + "framework": "Start", + "renderer": "redact", + "passed": true, + "checks": [ + "hydration", + "counter update", + "controlled input", + "renderer identity" + ] + }, + { + "framework": "Vite", + "renderer": "react", + "passed": true, + "checks": [ + "client mount", + "counter update", + "controlled input", + "renderer identity" + ] + }, + { + "framework": "Vite", + "renderer": "redact", + "passed": true, + "checks": [ + "client mount", + "counter update", + "controlled input", + "renderer identity" + ] + }, + { + "framework": "Vinext", + "renderer": "react", + "passed": true, + "checks": [ + "hydration", + "counter update", + "controlled input", + "renderer identity" + ] + }, + { + "framework": "Vinext", + "renderer": "redact", + "passed": true, + "checks": [ + "hydration", + "counter update", + "controlled input", + "renderer identity" + ] + }, + { + "framework": "Next.js", + "renderer": "react", + "passed": true, + "checks": [ + "hydration", + "counter update", + "controlled input", + "renderer identity" + ] + }, + { + "framework": "Next.js", + "renderer": "redact", + "passed": true, + "checks": [ + "hydration", + "counter update", + "controlled input", + "renderer identity" + ] + } + ] +} diff --git a/launch/benchmarks/redact-frameworks/measure.mjs b/launch/benchmarks/redact-frameworks/measure.mjs new file mode 100644 index 000000000..ec25c426c --- /dev/null +++ b/launch/benchmarks/redact-frameworks/measure.mjs @@ -0,0 +1,266 @@ +import assert from 'node:assert/strict' +import { createHash } from 'node:crypto' +import { spawn } from 'node:child_process' +import { createWriteStream } from 'node:fs' +import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises' +import { dirname, join, resolve } from 'node:path' +import { gzipSync } from 'node:zlib' + +// Run inside an isolated directory with the pinned dependencies installed. +const root = resolve(process.argv[2]) +const hash = (bytes) => createHash('sha256').update(bytes).digest('hex') +const counter = `'use client' +import { useEffect, useState } from 'react' + +export default function Counter() { + const [count, setCount] = useState(0) + const [name, setName] = useState('friend') + useEffect(() => { + document.documentElement.dataset.ready = 'true' + document.documentElement.dataset.runtime = Reflect.get(globalThis, Symbol.for('@tanstack/redact.ReactSharedInternals')) ? 'redact' : 'react' + }, []) + return
+

Hello, {name}.

+ + +
+} +` +const css = `body { margin: 0; font: 18px system-ui, sans-serif; color: #202020; background: #faf9f6; } +main { max-width: 32rem; margin: 4rem auto; padding: 1.5rem; } +label { display: grid; gap: .5rem; } +input, button { font: inherit; padding: .6rem; } +button { margin-top: 1.5rem; cursor: pointer; } +` +const packageJSON = JSON.parse( + await readFile(join(root, 'package.json'), 'utf8'), +) +const packageVersions = {} +for (const name of Object.keys(packageJSON.dependencies)) { + packageVersions[name] = JSON.parse( + await readFile(join(root, 'node_modules', name, 'package.json'), 'utf8'), + ).version +} +const report = { + recordedAt: new Date().toISOString(), + node: process.version, + zlib: process.versions.zlib, + packageVersions, + lockSha256: hash(await readFile(join(root, 'package-lock.json'))), + redactTarballSha256: hash(await readFile(join(root, 'redact.tgz'))), + counterSha256: hash(counter), + cssSha256: hash(css), + method: + 'Same single-route counter and controlled input in all four frameworks. Production client builds with default optimization settings. Start bundles its server dependencies through Vite in both variants so React imports inside dependencies are transformed too. Sum of gzipSync bytes for every emitted client .js and .css file, compressed separately. Includes lazy chunks and framework polyfills. Excludes server output, HTML, inline scripts, maps, and images. Each chart compares the same framework and dependencies, changing only its Redact integration. KB means 1,000 bytes. These are starter apps, not a promise for every app or a browser speed measurement.', + results: [], +} + +async function write(app, file, text) { + const path = join(app, file) + await mkdir(dirname(path), { recursive: true }) + await writeFile(path, text) +} + +async function run(app, renderer, executable, args) { + const log = createWriteStream(join(app, `${renderer}.log`)) + const child = spawn( + process.execPath, + [join(root, 'node_modules', executable), ...args], + { + cwd: app, + env: { + ...process.env, + NODE_ENV: 'production', + RENDERER: renderer, + NEXT_TELEMETRY_DISABLED: '1', + }, + stdio: ['ignore', 'pipe', 'pipe'], + }, + ) + child.stdout.pipe(log) + child.stderr.pipe(log) + await new Promise((accept, reject) => { + child.on('error', reject) + child.on('exit', (code) => + code === 0 + ? accept() + : reject( + new Error(`${app}/${renderer} exited ${code}; see ${renderer}.log`), + ), + ) + }) + log.end() +} + +async function files(directory, prefix = '') { + const result = [] + for (const entry of (await readdir(directory, { withFileTypes: true })).sort( + (a, b) => a.name.localeCompare(b.name), + )) { + const path = join(directory, entry.name) + if (entry.isDirectory()) + result.push(...(await files(path, `${prefix}${entry.name}/`))) + else if (/\.(js|css)$/.test(entry.name)) { + const bytes = await readFile(path) + result.push({ + path: `${prefix}${entry.name}`, + bytes: bytes.length, + gzipBytes: gzipSync(bytes).length, + sha256: hash(bytes), + }) + } + } + return result +} + +for (const framework of ['Start', 'Vite', 'Vinext', 'Next.js']) { + const id = framework === 'Next.js' ? 'next' : framework.toLowerCase() + const app = join(root, id) + await write(app, 'package.json', '{"private":true,"type":"module"}\n') + await write(app, 'Counter.jsx', counter) + await write(app, 'style.css', css) + if (framework === 'Start') { + await write( + app, + 'vite.config.mjs', + `import { defineConfig } from 'vite' +import { tanstackStart } from '@tanstack/react-start/plugin/vite' +import react from '@vitejs/plugin-react' +import { redact } from '@tanstack/redact/vite' +export default defineConfig({ + ssr: { noExternal: true }, + plugins: [tanstackStart(), react(), ...(process.env.RENDERER === 'redact' ? [redact()] : [])], +}) +`, + ) + await write( + app, + 'src/router.tsx', + `import { createRouter } from '@tanstack/react-router' +import { routeTree } from './routeTree.gen' +export function getRouter() { return createRouter({ routeTree }) } +`, + ) + await write( + app, + 'src/routes/__root.tsx', + `import { createRootRoute, HeadContent, Outlet, Scripts } from '@tanstack/react-router' +import '../../style.css' +export const Route = createRootRoute({ + head: () => ({ meta: [{ charSet: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { title: 'Bundle comparison' }] }), + component: () => , +}) +`, + ) + await write( + app, + 'src/routes/index.tsx', + `import { createFileRoute } from '@tanstack/react-router' +import Counter from '../../Counter.jsx' +export const Route = createFileRoute('/')({ component: Counter }) +`, + ) + } else if (framework === 'Vite') { + await write( + app, + 'vite.config.mjs', + `import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import { redact } from '@tanstack/redact/vite' +export default defineConfig({ plugins: [react(), ...(process.env.RENDERER === 'redact' ? [redact()] : [])] }) +`, + ) + await write( + app, + 'index.html', + 'Bundle comparison
\n', + ) + await write( + app, + 'main.jsx', + `import { createRoot } from 'react-dom/client' +import Counter from './Counter.jsx' +import './style.css' +createRoot(document.getElementById('root')).render() +`, + ) + } else { + await write( + app, + 'app/layout.jsx', + `import '../style.css' +export const metadata = { title: 'Bundle comparison' } +export default function Layout({ children }) { return {children} } +`, + ) + await write( + app, + 'app/page.jsx', + `import Counter from '../Counter.jsx' +export default function Page() { return } +`, + ) + if (framework === 'Vinext') { + await write( + app, + 'vite.config.mjs', + `import { defineConfig } from 'vite' +import vinext from 'vinext' +import { redact } from '@tanstack/redact/vinext' +export default defineConfig({ plugins: [vinext(), redact({ renderer: process.env.RENDERER })] }) +`, + ) + } else { + await write( + app, + 'next.config.mjs', + `import { withRedact } from '@tanstack/redact/next' +const config = { agentRules: false, distDir: '.next-' + process.env.RENDERER, turbopack: { root: ${JSON.stringify(root)} } } +export default process.env.RENDERER === 'redact' ? withRedact(config) : config +`, + ) + } + } + + for (const renderer of ['react', 'redact']) { + console.log(`Building ${framework} + ${renderer}`) + await run( + app, + renderer, + framework === 'Next.js' ? 'next/dist/bin/next' : 'vite/bin/vite.js', + framework === 'Next.js' ? ['build', '--turbopack'] : ['build'], + ) + const output = + framework === 'Next.js' + ? `.next-${renderer}/static` + : framework === 'Vite' + ? 'dist' + : 'dist/client' + const emitted = await files(join(app, output)) + assert(emitted.length > 0, `${framework}/${renderer}: no output`) + const result = { + framework, + renderer, + gzipBytes: emitted.reduce((sum, file) => sum + file.gzipBytes, 0), + files: emitted, + } + report.results.push(result) + await writeFile( + join(root, `${id}-${renderer}.json`), + JSON.stringify(result, null, 2) + '\n', + ) + console.log( + `${framework} + ${renderer}: ${result.gzipBytes} gzip bytes across ${emitted.length} files`, + ) + // Preserve both complete builds for browser verification after measurement. + if (framework !== 'Next.js') { + const { rename } = await import('node:fs/promises') + await rename(join(app, 'dist'), join(app, `dist-${renderer}`)) + } + } +} +await writeFile( + join(root, 'results.json'), + JSON.stringify(report, null, 2) + '\n', +) +console.log(`Saved ${join(root, 'results.json')}`) diff --git a/launch/benchmarks/redact-frameworks/package.json b/launch/benchmarks/redact-frameworks/package.json new file mode 100644 index 000000000..1c3d70d2d --- /dev/null +++ b/launch/benchmarks/redact-frameworks/package.json @@ -0,0 +1,23 @@ +{ + "name": "redact-framework-bundle-comparison", + "private": true, + "type": "module", + "dependencies": { + "@tanstack/redact": "file:./redact.tgz", + "@tanstack/react-start": "1.168.60", + "@tanstack/react-router": "1.170.41", + "@vitejs/plugin-react": "6.1.2", + "@vitejs/plugin-rsc": "0.5.38", + "vite": "8.3.5", + "vinext": "1.3.0", + "next": "16.4.3", + "react": "19.3.1", + "react-dom": "19.3.1", + "react-server-dom-webpack": "19.3.1" + }, + "overrides": { + "satori": { + "fflate": "0.7.5" + } + } +} diff --git a/launch/benchmarks/redact-frameworks/results.json b/launch/benchmarks/redact-frameworks/results.json new file mode 100644 index 000000000..54ef8001d --- /dev/null +++ b/launch/benchmarks/redact-frameworks/results.json @@ -0,0 +1,387 @@ +{ + "recordedAt": "2026-10-25T17:15:08.787Z", + "node": "v24.22.0", + "zlib": "1.3.2.1-motley-285e94b", + "packageVersions": { + "@tanstack/redact": "0.1.5", + "@tanstack/react-start": "1.168.60", + "@tanstack/react-router": "1.170.41", + "@vitejs/plugin-react": "6.1.2", + "@vitejs/plugin-rsc": "0.5.38", + "vite": "8.3.5", + "vinext": "1.3.0", + "next": "16.4.3", + "react": "19.3.1", + "react-dom": "19.3.1", + "react-server-dom-webpack": "19.3.1" + }, + "lockSha256": "d2e54fc68484ee9162bdf8e96b8a8a2a7c64798d26643da8c428fbbeb9ed37bd", + "redactTarballSha256": "6f8592d92061ab3845b11a5635a2853ec5ba61b600f7ca213cfa42b510ec1099", + "counterSha256": "642b7bf7693281301e2d3b42826b679b40f03cd723be41b0aaea9fa190727ca1", + "cssSha256": "bed31695998ef8641c353a5f356dbadc243b4669edf6fc631fe7b647c1674643", + "method": "Same single-route counter and controlled input in all four frameworks. Production client builds with default optimization settings. Start bundles its server dependencies through Vite in both variants so React imports inside dependencies are transformed too. Sum of gzipSync bytes for every emitted client .js and .css file, compressed separately. Includes lazy chunks and framework polyfills. Excludes server output, HTML, inline scripts, maps, and images. Each chart compares the same framework and dependencies, changing only its Redact integration. KB means 1,000 bytes. These are starter apps, not a promise for every app or a browser speed measurement.", + "results": [ + { + "framework": "Start", + "renderer": "react", + "gzipBytes": 109332, + "files": [ + { + "path": "assets/index-BrYQuRTz.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + }, + { + "path": "assets/index-DRX4Zrgs.js", + "bytes": 340498, + "gzipBytes": 108737, + "sha256": "94ea91e2860d9d7d1c211ec2235820a5a075988d40cfb73c2b3d435e26c4bd03" + }, + { + "path": "assets/routes-C2u07YtP.js", + "bytes": 654, + "gzipBytes": 406, + "sha256": "358e4f1a683163fafb895be75d73a7f24dd98096219ae0aa885af517feebbc18" + } + ] + }, + { + "framework": "Start", + "renderer": "redact", + "gzipBytes": 62306, + "files": [ + { + "path": "assets/index-BrYQuRTz.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + }, + { + "path": "assets/index-YaFU_fDe.js", + "bytes": 175102, + "gzipBytes": 61747, + "sha256": "02ef8216f40fbccd7479b2ae44a8fd181d96c78cef890a17db99daac47e15b77" + }, + { + "path": "assets/routes-BriNhCEG.js", + "bytes": 557, + "gzipBytes": 370, + "sha256": "b4792fb5a32a7ef7500bd04dfaec09a340dcf32a31df1fcd4cf8d385c591b239" + } + ] + }, + { + "framework": "Vite", + "renderer": "react", + "gzipBytes": 68255, + "files": [ + { + "path": "assets/index-5qRXaobH.js", + "bytes": 220014, + "gzipBytes": 68066, + "sha256": "2c8edc1ee66dcbc45d84342617af6a8f3573638b9e0fbf05b313d5537ad83987" + }, + { + "path": "assets/index-BrYQuRTz.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + } + ] + }, + { + "framework": "Vite", + "renderer": "redact", + "gzipBytes": 20130, + "files": [ + { + "path": "assets/index-BrYQuRTz.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + }, + { + "path": "assets/index-C0gPNSb1.js", + "bytes": 52375, + "gzipBytes": 19941, + "sha256": "86bd8f065184938aef60435697fcbf2f21da37a2251979d221e0089307db7be7" + } + ] + }, + { + "framework": "Vinext", + "renderer": "react", + "gzipBytes": 138094, + "files": [ + { + "path": "_next/static/95aa7be8-9659-4ff0-9197-de663bea07f7/_buildManifest.js", + "bytes": 176, + "gzipBytes": 139, + "sha256": "4cce301fe69e28d6463904ecf618427e95091bf3584ea347d8ca55d1077e1fb6" + }, + { + "path": "_next/static/95aa7be8-9659-4ff0-9197-de663bea07f7/_ssgManifest.js", + "bytes": 76, + "gzipBytes": 60, + "sha256": "653f3e53e89b4f8548ff86c19e92bb3c6b84b6be7485a320b1e00893ed877479" + }, + { + "path": "_next/static/chunks/B-sJivER.js", + "bytes": 665, + "gzipBytes": 407, + "sha256": "40ea3f3de7430f0cc44fba9834ac35543d1f1cd9d2235aaf6057473035773a99" + }, + { + "path": "_next/static/chunks/Clt7SkQq.js", + "bytes": 111220, + "gzipBytes": 32922, + "sha256": "35f71b2385a3e82b074274b8097e3ed1d3a93a6ed772b4ab25f32ef5c58aeb18" + }, + { + "path": "_next/static/chunks/CLvDmS2G.js", + "bytes": 219245, + "gzipBytes": 67635, + "sha256": "cf4fb3342b0de9ff6879cf17b5260a49c01c0e469cfc7538353cc74ecc5227ee" + }, + { + "path": "_next/static/chunks/DAuS5Ms1.js", + "bytes": 462, + "gzipBytes": 319, + "sha256": "f1537b2a59727be3fcbac7ef88ba2a6d827a367908cb64bda80cfe9764cb76e6" + }, + { + "path": "_next/static/chunks/P4Ex1D39.js", + "bytes": 120070, + "gzipBytes": 35698, + "sha256": "386c55beea34f25fe9fb1b2f77d33437fc7ccba3281f563a89070f206a6adcb2" + }, + { + "path": "_next/static/chunks/SFcG4F4c.js", + "bytes": 493, + "gzipBytes": 296, + "sha256": "32ddf8acccac05adf5bc5887354e8fda90c3693d616f858da1aff5292c37f95d" + }, + { + "path": "_next/static/chunks/XKyaHtl9.js", + "bytes": 726, + "gzipBytes": 429, + "sha256": "548d1dbf321e7d2ae804fcc158b588706a7c52f8ca175de1490c6ccb4dbe55b7" + }, + { + "path": "_next/static/css/BrYQuRTz.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + } + ] + }, + { + "framework": "Vinext", + "renderer": "redact", + "gzipBytes": 98779, + "files": [ + { + "path": "_next/static/chunks/BWaJ3C7D.js", + "bytes": 911, + "gzipBytes": 512, + "sha256": "d0e9044430006c5bb48f477501a5af465f0a6377d2fcd7495aa215b8b75aaee3" + }, + { + "path": "_next/static/chunks/CuqyvnFh.js", + "bytes": 194434, + "gzipBytes": 63996, + "sha256": "a7fae7b28c75542354609f33b2c4fc8ed5aab3bdf660f81dcc4302ad815b3a2d" + }, + { + "path": "_next/static/chunks/k_GZEp2z.js", + "bytes": 110723, + "gzipBytes": 32946, + "sha256": "fc14e80d3da2ff0c4369db4ebfb046a92b9efdd027c2c1a6579d41dfa92673a8" + }, + { + "path": "_next/static/chunks/NgGSeAlS.js", + "bytes": 389, + "gzipBytes": 275, + "sha256": "96197de2e87cd7008c617d34a81c5641cce29a32663e04cdc1ab0c58fab56b09" + }, + { + "path": "_next/static/chunks/SFcG4F4c.js", + "bytes": 493, + "gzipBytes": 296, + "sha256": "32ddf8acccac05adf5bc5887354e8fda90c3693d616f858da1aff5292c37f95d" + }, + { + "path": "_next/static/chunks/ufvIKhwg.js", + "bytes": 557, + "gzipBytes": 366, + "sha256": "e1eb7f56da7d9943f000fc252c3856f8637e57b4670290de631240d64b662e88" + }, + { + "path": "_next/static/css/BrYQuRTz.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + }, + { + "path": "_next/static/d4219925-835c-4b0a-8dbd-ce21fce7e7e1/_buildManifest.js", + "bytes": 176, + "gzipBytes": 139, + "sha256": "4cce301fe69e28d6463904ecf618427e95091bf3584ea347d8ca55d1077e1fb6" + }, + { + "path": "_next/static/d4219925-835c-4b0a-8dbd-ce21fce7e7e1/_ssgManifest.js", + "bytes": 76, + "gzipBytes": 60, + "sha256": "653f3e53e89b4f8548ff86c19e92bb3c6b84b6be7485a320b1e00893ed877479" + } + ] + }, + { + "framework": "Next.js", + "renderer": "react", + "gzipBytes": 175610, + "files": [ + { + "path": "chunks/0cz1d0mv5g_q7.js", + "bytes": 112594, + "gzipBytes": 39627, + "sha256": "0973c1d64c88adc8e3c950410cb58b288f72118d5965b78049438deb8f2f9683" + }, + { + "path": "chunks/0r-yur70-ku2o.js", + "bytes": 185420, + "gzipBytes": 49697, + "sha256": "db703d2a75d3d6852ec11fccc98e0ede3f7334b71a38648c117a78c8cdab6c71" + }, + { + "path": "chunks/0umf92h1sb77c.js", + "bytes": 13822, + "gzipBytes": 3514, + "sha256": "c410d0f2543e080768fc14f73b2bd1fdf103e26956e9730390b5e41c4fb5ff8b" + }, + { + "path": "chunks/1h67tk3d-mtce.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + }, + { + "path": "chunks/3_cq_sktxv4mr.js", + "bytes": 734, + "gzipBytes": 448, + "sha256": "06447fd094c8341a5c8adf3d09625f29a48f45eec960b49487cff17ec8c7cc7f" + }, + { + "path": "chunks/3cfn99dbrcvvp.js", + "bytes": 16898, + "gzipBytes": 5942, + "sha256": "ce93ca628abb25d17ebc40e5db225cc2b25ca3415910428f5dab7aa049ab506b" + }, + { + "path": "chunks/3wbm-994r45kr.js", + "bytes": 229820, + "gzipBytes": 71969, + "sha256": "0112d166f239984294780810c159749ca06e78e3f1ce5db35ab98f31b95c9d5c" + }, + { + "path": "chunks/turbopack-3-ry682tkyiqk.js", + "bytes": 10030, + "gzipBytes": 3940, + "sha256": "8bbb58cbfd4633c1d828c6bc37bc32abc768a149c01b1dfc4f5131fd81274551" + }, + { + "path": "NdnK0xH5LMQwOKWJEoBdU/_buildManifest.js", + "bytes": 219, + "gzipBytes": 154, + "sha256": "9476e0afd3f9da68a64e6ec58631191fd3eaca62c9f5a377e7517fe9a89e59ea" + }, + { + "path": "NdnK0xH5LMQwOKWJEoBdU/_clientMiddlewareManifest.js", + "bytes": 96, + "gzipBytes": 66, + "sha256": "5483e3295dc35dfe29ea932efc85341c916f10ff78ff5b0e965e003710893a4a" + }, + { + "path": "NdnK0xH5LMQwOKWJEoBdU/_ssgManifest.js", + "bytes": 80, + "gzipBytes": 64, + "sha256": "678f6ce2cb80b1fe72fc67e7412be6e2ab6ada083111b64f7c40d35e3cba5e00" + } + ] + }, + { + "framework": "Next.js", + "renderer": "redact", + "gzipBytes": 139872, + "files": [ + { + "path": "chunks/0cz1d0mv5g_q7.js", + "bytes": 112594, + "gzipBytes": 39627, + "sha256": "0973c1d64c88adc8e3c950410cb58b288f72118d5965b78049438deb8f2f9683" + }, + { + "path": "chunks/0umf92h1sb77c.js", + "bytes": 13822, + "gzipBytes": 3514, + "sha256": "c410d0f2543e080768fc14f73b2bd1fdf103e26956e9730390b5e41c4fb5ff8b" + }, + { + "path": "chunks/1h67tk3d-mtce.css", + "bytes": 241, + "gzipBytes": 189, + "sha256": "62ea65329a5844dfb94c95ad3d0bb666da2e998f50a88229d86a72d5b72390d4" + }, + { + "path": "chunks/2t30ztv8lkon0.js", + "bytes": 259589, + "gzipBytes": 78369, + "sha256": "bbe1bb90b3c86e999c92352cff6b2acb1785358052457c99c37fba4afd5b7ff1" + }, + { + "path": "chunks/3b6hrt7qzi8f_.js", + "bytes": 698, + "gzipBytes": 434, + "sha256": "9111af282f07948fbe49f245e8e90f8c3abb0b4a31e13a5e9bb079eb532171f5" + }, + { + "path": "chunks/3ghqzq9l61sxn.js", + "bytes": 20331, + "gzipBytes": 6299, + "sha256": "663397057434f8c1178b8c713b58edd90e4142a5092dc04072431db27b18f6ee" + }, + { + "path": "chunks/3ldo0kwpv0iin.js", + "bytes": 23371, + "gzipBytes": 7216, + "sha256": "b47f6cbc5c85edceaacb5b45d63785160dcb3fce74e4e323a3a5a2a6a5a44f81" + }, + { + "path": "chunks/turbopack-3-ry682tkyiqk.js", + "bytes": 10030, + "gzipBytes": 3940, + "sha256": "8bbb58cbfd4633c1d828c6bc37bc32abc768a149c01b1dfc4f5131fd81274551" + }, + { + "path": "I5aaZFtg_xGKQHYGMZiI5/_buildManifest.js", + "bytes": 219, + "gzipBytes": 154, + "sha256": "9476e0afd3f9da68a64e6ec58631191fd3eaca62c9f5a377e7517fe9a89e59ea" + }, + { + "path": "I5aaZFtg_xGKQHYGMZiI5/_clientMiddlewareManifest.js", + "bytes": 96, + "gzipBytes": 66, + "sha256": "5483e3295dc35dfe29ea932efc85341c916f10ff78ff5b0e965e003710893a4a" + }, + { + "path": "I5aaZFtg_xGKQHYGMZiI5/_ssgManifest.js", + "bytes": 80, + "gzipBytes": 64, + "sha256": "678f6ce2cb80b1fe72fc67e7412be6e2ab6ada083111b64f7c40d35e3cba5e00" + } + ] + } + ] +} diff --git a/launch/benchmarks/redact-frameworks/serve.mjs b/launch/benchmarks/redact-frameworks/serve.mjs new file mode 100644 index 000000000..d7e377e7e --- /dev/null +++ b/launch/benchmarks/redact-frameworks/serve.mjs @@ -0,0 +1,112 @@ +import { spawn } from 'node:child_process' +import { createServer } from 'node:http' +import { readFile } from 'node:fs/promises' +import { join, resolve } from 'node:path' +import { Readable } from 'node:stream' +import { fileURLToPath, pathToFileURL } from 'node:url' + +const root = resolve(process.argv[2]) +const framework = process.argv[3] +const renderer = process.argv[4] +const port = Number(process.argv[5]) + +if (!framework) { + const children = [] + let nextPort = 4380 + for (const name of ['start', 'vite', 'vinext', 'next']) { + for (const runtime of ['react', 'redact']) { + const serverPort = nextPort++ + children.push( + spawn( + process.execPath, + [ + fileURLToPath(import.meta.url), + root, + name, + runtime, + String(serverPort), + ], + { + env: { ...process.env, NODE_ENV: 'production', RENDERER: runtime }, + stdio: 'inherit', + }, + ), + ) + console.log(`${name}/${runtime}: http://127.0.0.1:${serverPort}`) + } + } + for (const signal of ['SIGINT', 'SIGTERM']) { + process.on(signal, () => { + for (const child of children) child.kill(signal) + }) + } +} else if (framework === 'next') { + process.chdir(join(root, framework)) + process.argv = [ + process.execPath, + join(root, 'node_modules/next/dist/bin/next'), + 'start', + '--hostname', + '127.0.0.1', + '--port', + String(port), + ] + await import(pathToFileURL(process.argv[1]).href) +} else if (framework === 'vinext') { + process.chdir(join(root, framework)) + const { startProdServer } = await import( + pathToFileURL(join(root, 'node_modules/vinext/dist/server/prod-server.js')) + .href + ) + await startProdServer({ + port, + host: '127.0.0.1', + outDir: join(root, framework, `dist-${renderer}`), + }) +} else { + const dist = join(root, framework, `dist-${renderer}`) + const publicRoot = framework === 'start' ? join(dist, 'client') : dist + const handler = + framework === 'start' + ? (await import(pathToFileURL(join(dist, 'server/server.js')).href)) + .default + : null + createServer(async (request, response) => { + try { + const url = new URL(request.url, `http://127.0.0.1:${port}`) + if ( + url.pathname.startsWith('/assets/') || + (framework === 'vite' && url.pathname === '/') + ) { + const asset = resolve( + publicRoot, + '.' + (url.pathname === '/' ? '/index.html' : url.pathname), + ) + if (!asset.startsWith(publicRoot + '/')) { + response.writeHead(400).end() + return + } + const body = await readFile(asset) + response.setHeader( + 'Content-Type', + asset.endsWith('.js') + ? 'text/javascript' + : asset.endsWith('.css') + ? 'text/css' + : 'text/html', + ) + response.end(body) + } else if (handler) { + const result = await handler.fetch( + new Request(url, { headers: request.headers }), + ) + response.writeHead(result.status, Object.fromEntries(result.headers)) + if (result.body) Readable.fromWeb(result.body).pipe(response) + else response.end() + } else response.writeHead(404).end() + } catch (error) { + console.error(error) + response.writeHead(500).end(String(error)) + } + }).listen(port, '127.0.0.1') +} diff --git a/launch/benchmarks/redact-frameworks/server-checks.json b/launch/benchmarks/redact-frameworks/server-checks.json new file mode 100644 index 000000000..2c8dee4ca --- /dev/null +++ b/launch/benchmarks/redact-frameworks/server-checks.json @@ -0,0 +1,46 @@ +{ + "results": [ + { + "framework": "Start", + "renderer": "react", + "status": 200, + "passed": true, + "checks": ["server-rendered greeting", "counter", "controlled input"] + }, + { + "framework": "Start", + "renderer": "redact", + "status": 200, + "passed": true, + "checks": ["server-rendered greeting", "counter", "controlled input"] + }, + { + "framework": "Vinext", + "renderer": "react", + "status": 200, + "passed": true, + "checks": ["server-rendered greeting", "counter", "controlled input"] + }, + { + "framework": "Vinext", + "renderer": "redact", + "status": 200, + "passed": true, + "checks": ["server-rendered greeting", "counter", "controlled input"] + }, + { + "framework": "Next.js", + "renderer": "react", + "status": 200, + "passed": true, + "checks": ["server-rendered greeting", "counter", "controlled input"] + }, + { + "framework": "Next.js", + "renderer": "redact", + "status": 200, + "passed": true, + "checks": ["server-rendered greeting", "counter", "controlled input"] + } + ] +} diff --git a/launch/redact-next-vinext.md b/launch/redact-next-vinext.md index 081884f79..d7a113a65 100644 --- a/launch/redact-next-vinext.md +++ b/launch/redact-next-vinext.md @@ -96,13 +96,13 @@ Use the site's existing page views and campaign parameters. Compare the seven da ## Claim checks -| Claim | Evidence and limit | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 39.4 KB / 25.4% less output | [Vinext benchmark](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md), same app and dependencies, all emitted client JS and CSS including lazy routes, six builds | -| 39.2 KB / 27.2% less entry output | Same report, browser entry plus eager JavaScript imports, not every possible route request | -| Next.js savings | App-specific. The benchmark's 74.5 KB comparison changes both framework and renderer, so it cannot establish Redact-only savings in Next.js | -| Performance | Build times were effectively equal. Local startup was 2.2% faster for App Router and 4.9% faster for the large Pages fixture. Browser and server rendering speed were not measured | -| Framework coverage | [Next.js report](https://github.com/TanStack/redact/blob/main/benchmarks/NEXT_COVERAGE.md) and [Vinext report](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_COVERAGE.md), all required cases must pass before the stable announcement | -| Rendering tradeoff | [Compatibility guide](https://tanstack.com/redact/latest/docs/compatibility), synchronous rendering with no time slicing or interruptible component renders | +| Claim | Evidence and limit | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 39.4 KB / 25.4% less output | [Vinext benchmark](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_BENCHMARKS.md), same app and dependencies, all emitted client JS and CSS including lazy routes, six builds | +| 39.2 KB / 27.2% less entry output | Same report, browser entry plus eager JavaScript imports, not every possible route request | +| Starter app bundle charts | [Four-framework measurements](./benchmarks/redact-frameworks/README.md), same counter and input: Start saves 47.0 KB / 43.0%, Vite 48.1 KB / 70.5%, Vinext 39.3 KB / 28.5%, and Next.js 35.7 KB / 20.4%. All emitted client JS and CSS, gzip, one production build per variant. | +| Performance | Build times were effectively equal. Local startup was 2.2% faster for App Router and 4.9% faster for the large Pages fixture. Browser and server rendering speed were not measured | +| Framework coverage | [Next.js report](https://github.com/TanStack/redact/blob/main/benchmarks/NEXT_COVERAGE.md) and [Vinext report](https://github.com/TanStack/redact/blob/main/benchmarks/VINEXT_COVERAGE.md), all required cases must pass before the stable announcement | +| Rendering tradeoff | [Compatibility guide](https://tanstack.com/redact/latest/docs/compatibility), synchronous rendering with no time slicing or interruptible component renders | Reply to requests for a universal Next.js percentage with the app-specific distinction above. Reply to scheduling questions with the actual rendering tradeoff. Avoid claims of universal React parity or faster hydration. diff --git a/src/components/landing/LibraryLanding.tsx b/src/components/landing/LibraryLanding.tsx index c07bb2a9e..85c0d0e5a 100644 --- a/src/components/landing/LibraryLanding.tsx +++ b/src/components/landing/LibraryLanding.tsx @@ -264,7 +264,7 @@ export function LibraryLandingShell({ className={ stackHero ? 'grid items-start gap-12' - : 'grid items-start gap-12 xl:min-h-116 xl:grid-cols-[minmax(25rem,0.82fr)_minmax(34rem,1.18fr)] xl:gap-10' + : 'grid items-start gap-12 xl:min-h-116 xl:grid-cols-[minmax(0,0.82fr)_minmax(0,1.18fr)] xl:gap-10' } >
[ + item.reactBytes, + item.redactBytes, + ]), +) +const kb = (bytes: number) => (bytes / 1000).toFixed(1) const setups = [ { name: 'Next.js', @@ -29,6 +37,22 @@ import { redact } from '@tanstack/redact/vinext' export default defineConfig({ plugins: [vinext(), redact()], +})`, + }, + { + name: 'Start', + file: 'vite.config.ts', + guide: 'vite-plugin', + detail: + 'Add Redact after Start and React. Bundle server dependencies so their React imports use the same runtime as your app.', + code: `import { defineConfig } from 'vite' +import { tanstackStart } from '@tanstack/react-start/plugin/vite' +import react from '@vitejs/plugin-react' +import { redact } from '@tanstack/redact/vite' + +export default defineConfig({ + ssr: { noExternal: true }, + plugins: [tanstackStart(), react(), redact()], })`, }, { @@ -55,56 +79,70 @@ export default function RedactLanding() { -
- 39.4 KB less. -
-

- Client output in Vinext's benchmark, gzipped. -

-
- {[ - { - name: 'Vinext + React', - size: '154.9 KB', - width: '100%', - redact: false, - }, - { - name: 'Vinext + Redact', - size: '115.5 KB', - width: '74.6%', - redact: true, - }, - ].map((row) => ( -
-
- {row.name} - {row.size} +
+
+ {bundleSizes.comparisons.map((item) => ( +
+
+

+ {item.framework === 'Start' + ? 'TanStack Start' + : item.framework} +

+

+ {kb(item.reactBytes - item.redactBytes)} KB less +

+

+ {((1 - item.redactBytes / item.reactBytes) * 100).toFixed( + 1, + )} + % smaller +

+
+
+ {[ + { name: 'React', bytes: item.reactBytes, redact: false }, + { name: 'Redact', bytes: item.redactBytes, redact: true }, + ].map((row) => ( +
+
+ {row.name} + + {kb(row.bytes)} KB + +
+ + ))}
- +
))}
-
+

- 25.4% smaller across six builds of the same app. Includes all - emitted client JS and CSS, including lazy routes. + Same counter app, production client JS + CSS, gzipped. Includes + every emitted chunk. Shared scale, 1 KB = 1,000 bytes.

- Measurements and timing tradeoffs ↗ + Versions, source, and measurements ↗ -
- +
+ } > @@ -145,7 +183,7 @@ export default function RedactLanding() { > {setup.name} setup and coverage ↗ - {setup.name !== 'Vite' && ( + {(setup.name === 'Next.js' || setup.name === 'Vinext') && (

The Next.js and Vinext release isn't published yet.{' '} Date: Sun, 25 Oct 2026 11:22:47 -0600 Subject: [PATCH 5/7] docs: retain the framework benchmark dependency lock --- .gitignore | 1 + .../redact-frameworks/package-lock.json | 3826 +++++++++++++++++ 2 files changed, 3827 insertions(+) create mode 100644 launch/benchmarks/redact-frameworks/package-lock.json diff --git a/.gitignore b/.gitignore index 2f5bf34ce..139de3d2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules .pnpm-store/ package-lock.json +!launch/benchmarks/redact-frameworks/package-lock.json yarn.lock .tanstack .DS_Store diff --git a/launch/benchmarks/redact-frameworks/package-lock.json b/launch/benchmarks/redact-frameworks/package-lock.json new file mode 100644 index 000000000..719c23066 --- /dev/null +++ b/launch/benchmarks/redact-frameworks/package-lock.json @@ -0,0 +1,3826 @@ +{ + "name": "redact-framework-bundle-comparison", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "redact-framework-bundle-comparison", + "dependencies": { + "@tanstack/react-router": "1.170.41", + "@tanstack/react-start": "1.168.60", + "@tanstack/redact": "file:./redact.tgz", + "@vitejs/plugin-react": "6.1.2", + "@vitejs/plugin-rsc": "0.5.38", + "next": "16.4.3", + "react": "19.3.1", + "react-dom": "19.3.1", + "react-server-dom-webpack": "19.3.1", + "vinext": "1.3.0", + "vite": "8.3.5" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.11", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.11.tgz", + "integrity": "sha512-snZbO7MEDOof+hvNa97EjEY7qD7h2kwvQr5AJC3ZhQudKW5dnej6k3kP9NQV88hJwaS8vDqRLFo9rivLEhle2g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.10.tgz", + "integrity": "sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.11.tgz", + "integrity": "sha512-OZ6+oaK7GMyg3IfCpj8JOmn8n+w2rJbDT0LLfVDTLb1ZFeKDh3AiNELgCMUw175IJHSkLl74hG0M0VLsvx+gag==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.11" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.10.tgz", + "integrity": "sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.9", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.11.tgz", + "integrity": "sha512-WCsemW40Cpc6gouC1SrY6PBaZ+oLRlEVY9XBvZBI7il/HyUrb2nJ505wE1MHEFyDZNnrWDEuy4jL50WVHfTTSQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.11", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.5.tgz", + "integrity": "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.5.tgz", + "integrity": "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.4" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.5.tgz", + "integrity": "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.4.tgz", + "integrity": "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.4.tgz", + "integrity": "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.4.tgz", + "integrity": "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.4.tgz", + "integrity": "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.4.tgz", + "integrity": "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.4.tgz", + "integrity": "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.4.tgz", + "integrity": "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.4.tgz", + "integrity": "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.4.tgz", + "integrity": "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.4.tgz", + "integrity": "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.5.tgz", + "integrity": "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.5.tgz", + "integrity": "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.5.tgz", + "integrity": "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.5.tgz", + "integrity": "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.5.tgz", + "integrity": "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.5.tgz", + "integrity": "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.5.tgz", + "integrity": "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.5.tgz", + "integrity": "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.5.tgz", + "integrity": "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.5.tgz", + "integrity": "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.5.tgz", + "integrity": "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.5.tgz", + "integrity": "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.5.tgz", + "integrity": "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next/env": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.4.3.tgz", + "integrity": "sha512-a7tz1QCcWWkwC/rPJcPMJk/UNRu9CFhDd3OHYE5hddbJrs8BqRTalxI6GlKCWEGzRLHN+S/B7a4PAHCtm25aBQ==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.4.3.tgz", + "integrity": "sha512-4yq5EXBt+VDtAZwTyfijaFp5D2C5oz3Ikw5a2kiX2K9nw72vrZX2q5UuAlkPtUMO1tQz6JTKpaKWjS7OOefTDQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.4.3.tgz", + "integrity": "sha512-1Rvkn/LUhnEF8WxnRkOrqGhbwXui1bkWFxONKIbN+r7C+9KHDSZ+iUoj4CzymVMWUyZIyx9szcb9+kbKhD500A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.4.3.tgz", + "integrity": "sha512-dCKpXErGg3abUM6t5JTJV/ottVBTStJB5lRJTbgdUdQaQ+jNHiK56Hsc0YAEg/rinSh42hYG3HWiYmEMdilnxg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.4.3.tgz", + "integrity": "sha512-WwYbhWkhYBvBtib1K4W0kL8MW2snBD2A5b3SN4vPpqalZbZs5+bQ1yzAdepVoOqrFfEW3dmREy4Zs1MrWcrFbw==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.4.3.tgz", + "integrity": "sha512-QymWvfUwDEC5/lpJOsxX5VAbyoR2D13+2Jsjz4be7gT4LPqEgdpkeLIR/HFfCLgKzoMhpJbp6I/JnogyNZHcaA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.4.3.tgz", + "integrity": "sha512-Vmjd9D7DpA4Vv3cUlr82QWgJD/BQZmns801vtC5VWHg6jCIA4a5vMKpQnfrM2pyCrp2eV0ENdUg4PlN3bAc2Yw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.4.3.tgz", + "integrity": "sha512-lG1pPdPLk7gTyGb00n5JIMLdBJgjb+UEhSdZvFbhUMg0DyC6z4B7RnpSKF9VCd4imkLObVbXOFA0kFCpw7yFow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.4.3.tgz", + "integrity": "sha512-NmQC9RkJdnPXRaMxtkCzobB3teVjqF33oSOnwDfi+XYGWWYpt+xlGK3mtktSKLbdjwaWbJu2OkkMiRFGUUncKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@oozcitak/dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-2.0.2.tgz", + "integrity": "sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w==", + "license": "MIT", + "dependencies": { + "@oozcitak/infra": "^2.0.2", + "@oozcitak/url": "^3.0.0", + "@oozcitak/util": "^10.0.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oozcitak/infra": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-2.0.2.tgz", + "integrity": "sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA==", + "license": "MIT", + "dependencies": { + "@oozcitak/util": "^10.0.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oozcitak/url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-3.0.0.tgz", + "integrity": "sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ==", + "license": "MIT", + "dependencies": { + "@oozcitak/infra": "^2.0.2", + "@oozcitak/util": "^10.0.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oozcitak/util": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-10.0.0.tgz", + "integrity": "sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA==", + "license": "MIT", + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.155.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz", + "integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@resvg/resvg-wasm": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@resvg/resvg-wasm/-/resvg-wasm-2.4.1.tgz", + "integrity": "sha512-yi6R0HyHtsoWTRA06Col4WoDs7SvlXU3DLMNP2bdAgs7HK18dTEVl1weXgxRzi8gwLteGUbIg29zulxIB3GSdg==", + "license": "MPL-2.0", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz", + "integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz", + "integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz", + "integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz", + "integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz", + "integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz", + "integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz", + "integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz", + "integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz", + "integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz", + "integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz", + "integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz", + "integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz", + "integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz", + "integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz", + "integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "license": "MIT" + }, + "node_modules/@shuding/opentype.js": { + "version": "1.4.0-beta.0", + "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz", + "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==", + "license": "MIT", + "dependencies": { + "fflate": "^0.7.3", + "string.prototype.codepointat": "^0.2.1" + }, + "bin": { + "ot": "bin/ot" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tanstack/history": { + "version": "1.162.4", + "resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.162.4.tgz", + "integrity": "sha512-utTS5L2OkeYUzXGohL1Z8sefu1GLNOJcxe8Hd6iIdc/Xo1K1nDB2JEp4iSFhvYh33xKC9V91TxrS8qfrpoKobQ==", + "license": "MIT", + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-router": { + "version": "1.170.41", + "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.170.41.tgz", + "integrity": "sha512-Mpvw8Wm5MGDbTqI8Yc9flLKxbOHwoWocv0H2aGKcgw2a017oK5nZWqa954P+DrUx/8fI98YNywnHP5XcD3tQ9w==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.162.4", + "@tanstack/react-store": "^0.11.2", + "@tanstack/router-core": "1.171.34", + "isbot": "^5.1.22" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-start": { + "version": "1.168.60", + "resolved": "https://registry.npmjs.org/@tanstack/react-start/-/react-start-1.168.60.tgz", + "integrity": "sha512-WMOM0Xlh2lPbVlbjYM6uOxOpiaWRPvODm/dwkLsGKq5tjyHOHZmKckJgwlrZl7OQUqFlOZHYj8bKUTgoeg8cUQ==", + "license": "MIT", + "dependencies": { + "@tanstack/react-router": "1.170.41", + "@tanstack/react-start-client": "1.168.39", + "@tanstack/react-start-rsc": "0.1.59", + "@tanstack/react-start-server": "1.167.46", + "@tanstack/router-utils": "1.162.3", + "@tanstack/start-client-core": "1.170.34", + "@tanstack/start-plugin-core": "1.171.49", + "@tanstack/start-server-core": "1.169.39", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rsbuild/core": "^2.0.0", + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0", + "vite": ">=7.0.0" + }, + "peerDependenciesMeta": { + "@rsbuild/core": { + "optional": true + }, + "@vitejs/plugin-rsc": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@tanstack/react-start-client": { + "version": "1.168.39", + "resolved": "https://registry.npmjs.org/@tanstack/react-start-client/-/react-start-client-1.168.39.tgz", + "integrity": "sha512-Uby0uo37JlQgUKHU0snDwH9nYiEeAjm9+7pUOFgycU/UszEILC2SO2DSCoNnCMuHKj9z+4URKzBYIP2exT9+wg==", + "license": "MIT", + "dependencies": { + "@tanstack/react-router": "1.170.41", + "@tanstack/router-core": "1.171.34", + "@tanstack/start-client-core": "1.170.34" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-start-rsc": { + "version": "0.1.59", + "resolved": "https://registry.npmjs.org/@tanstack/react-start-rsc/-/react-start-rsc-0.1.59.tgz", + "integrity": "sha512-M2Lqxkk5C1zQncQs5paqX+/OLdOht51pg6D84YfLMrNsjhU/nzb6wd92MIja0mi5i23+L+fxLLjQYR2DObjBlw==", + "license": "MIT", + "dependencies": { + "@tanstack/react-router": "1.170.41", + "@tanstack/router-core": "1.171.34", + "@tanstack/router-utils": "1.162.3", + "@tanstack/start-client-core": "1.170.34", + "@tanstack/start-fn-stubs": "1.162.0", + "@tanstack/start-plugin-core": "1.171.49", + "@tanstack/start-storage-context": "1.167.36", + "pathe": "^2.0.3" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rspack/core": ">=2.0.0-0", + "@vitejs/plugin-rsc": ">=0.5.30", + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0", + "react-server-dom-rspack": ">=0.0.2" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "@vitejs/plugin-rsc": { + "optional": true + }, + "react-server-dom-rspack": { + "optional": true + } + } + }, + "node_modules/@tanstack/react-start-server": { + "version": "1.167.46", + "resolved": "https://registry.npmjs.org/@tanstack/react-start-server/-/react-start-server-1.167.46.tgz", + "integrity": "sha512-K7z8xBOEdp8u5CZCxWrbS0tFtk5XZGMdhssLeZlRZKlLDbX7BKLdMtJ7th5sR6QVt9MTUAg3LcoqvJMPSFF+lg==", + "license": "MIT", + "dependencies": { + "@tanstack/react-router": "1.170.41", + "@tanstack/router-core": "1.171.34", + "@tanstack/start-server-core": "1.169.39" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-store": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.11.2.tgz", + "integrity": "sha512-oj5O5DmiMWE+ih+SioX2ayC1kbK7d3fpLx0B75fPJr9nY3zU+hoW010yr64qXsY/9fyiLVE2bn5mGNV3owm8RQ==", + "license": "MIT", + "dependencies": { + "@tanstack/store": "0.11.2", + "use-sync-external-store": "^1.6.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/redact": { + "version": "0.1.5", + "resolved": "file:redact.tgz", + "integrity": "sha512-0NyNmFAZcouLIoTYY2Z/Jz4CEnlujTZhhbwlmSxicU930Qi7LGl171JoOCyLnXdTVnATmfz0U5cEfnhxrS4J3A==", + "peerDependencies": { + "@cloudflare/vite-plugin": "1.65.0", + "next": "~15.5.0 || ~16.0.0 || ~16.1.0 || ~16.2.0 || ~16.3.0 || ~16.4.0", + "vinext": "~1.3.0", + "vite": ">=5" + }, + "peerDependenciesMeta": { + "@cloudflare/vite-plugin": { + "optional": true + }, + "next": { + "optional": true + }, + "vinext": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@tanstack/router-core": { + "version": "1.171.34", + "resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.171.34.tgz", + "integrity": "sha512-X+19pGuuLVPvvAvPYw9v/+ktRk5cCll8AtfpBpOhDRmVgUMrfqze0467xtq8YRVVs/mmo5rVtWn/7Tp32RDBKw==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.162.4", + "cookie-es": "^3.0.0", + "seroval": "^1.6.7", + "seroval-plugins": "^1.6.7" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/router-generator": { + "version": "1.167.40", + "resolved": "https://registry.npmjs.org/@tanstack/router-generator/-/router-generator-1.167.40.tgz", + "integrity": "sha512-WkEueqEvsBBudzO0fx1nWfOmRNW8OAvBoVABTGls9bAWzjdC+KDGHvjCNrvn88ofs1F6gqL8aWnzKCbxW3dCyQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8", + "@tanstack/router-core": "1.171.34", + "@tanstack/router-utils": "1.162.3", + "@tanstack/virtual-file-routes": "1.162.0", + "jiti": "^2.7.0", + "magic-string": "^0.30.21", + "prettier": "^3.9.6", + "zod": "^4.5.4" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/router-plugin": { + "version": "1.168.42", + "resolved": "https://registry.npmjs.org/@tanstack/router-plugin/-/router-plugin-1.168.42.tgz", + "integrity": "sha512-vAR5WXJh/ErseEWQftDhsJcr2c++ucRQ6FbqN3ygMO44+ZxxRfW3sIpZmddHROVSmBk8jc6MrwjTPNjVhd62Vw==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "@tanstack/router-core": "1.171.34", + "@tanstack/router-generator": "1.167.40", + "@tanstack/router-utils": "1.162.3", + "chokidar": "^5.0.0", + "unplugin": "^3.3.0", + "zod": "^4.5.4" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rsbuild/core": ">=1.0.2 || ^2.0.0", + "@tanstack/react-router": "^1.170.41", + "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", + "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", + "webpack": ">=5.92.0" + }, + "peerDependenciesMeta": { + "@rsbuild/core": { + "optional": true + }, + "@tanstack/react-router": { + "optional": true + }, + "vite": { + "optional": true + }, + "vite-plugin-solid": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@tanstack/router-utils": { + "version": "1.162.3", + "resolved": "https://registry.npmjs.org/@tanstack/router-utils/-/router-utils-1.162.3.tgz", + "integrity": "sha512-Icb0xGuG1+54IV0WMLRcc3ErTx2HeJWyPG661FkQ8UT6guoBq1FJjFRqlG/JS0xi4mFFkBhvwO7tbLa32f3yxA==", + "license": "MIT", + "dependencies": { + "@babel/generator": "^7.29.8", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "ansis": "^4.3.1", + "babel-dead-code-elimination": "^1.0.12", + "diff": "^8.0.4", + "pathe": "^2.0.3", + "tinyglobby": "^0.2.17" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-client-core": { + "version": "1.170.34", + "resolved": "https://registry.npmjs.org/@tanstack/start-client-core/-/start-client-core-1.170.34.tgz", + "integrity": "sha512-LfwZSbau2MLLZ/uPAoO+NC9fK3J66c0wLhnNQqIa+Goqw7bXPjkHwlsjY7evlUz1AnyhhQ1Qab95v+VmP0TZ9A==", + "license": "MIT", + "dependencies": { + "@tanstack/router-core": "1.171.34", + "@tanstack/start-fn-stubs": "1.162.0", + "@tanstack/start-storage-context": "1.167.36", + "seroval": "^1.6.7" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-fn-stubs": { + "version": "1.162.0", + "resolved": "https://registry.npmjs.org/@tanstack/start-fn-stubs/-/start-fn-stubs-1.162.0.tgz", + "integrity": "sha512-QWfUZ3Yo923tdQn38LyKMU8rcTw69zc+T4dAvgTWV4O56SqFRsGfS0lSWIMhJRwXIx/bvdi7nTUBDdZtTHtpTQ==", + "license": "MIT", + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-plugin-core": { + "version": "1.171.49", + "resolved": "https://registry.npmjs.org/@tanstack/start-plugin-core/-/start-plugin-core-1.171.49.tgz", + "integrity": "sha512-HPOb7LnMc71k38cd5uvMybPPUU/Q/56KvSqQzSWz7cps1ZDFXaxUM6EFaFHLCdgTWqGexNGDdRE+sUVPVBM4Xg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "7.29.7", + "@babel/core": "^7.29.7", + "@babel/types": "^7.29.8", + "@jridgewell/remapping": "^2.3.5", + "@tanstack/router-core": "1.171.34", + "@tanstack/router-generator": "1.167.40", + "@tanstack/router-plugin": "1.168.42", + "@tanstack/router-utils": "1.162.3", + "@tanstack/start-server-core": "1.169.39", + "exsolve": "^1.1.1", + "lightningcss": "^1.33.0", + "pathe": "^2.0.3", + "picomatch": "^4.0.7", + "seroval": "^1.6.7", + "source-map": "^0.7.6", + "srvx": "^0.11.22", + "tinyglobby": "^0.2.17", + "ufo": "^1.6.4", + "vitefu": "^1.1.3", + "xmlbuilder2": "^4.0.3", + "zod": "^4.5.4" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@rsbuild/core": "^2.0.0", + "vite": ">=7.0.0" + }, + "peerDependenciesMeta": { + "@rsbuild/core": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@tanstack/start-server-core": { + "version": "1.169.39", + "resolved": "https://registry.npmjs.org/@tanstack/start-server-core/-/start-server-core-1.169.39.tgz", + "integrity": "sha512-pqqkxhXY46nuFSYt6TsMGyABiplUzHFHndKAlRRGC0fWDrJCH1koWxVMoxySa51ZETV79f/z73b5UZ1jfIkXwQ==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.162.4", + "@tanstack/router-core": "1.171.34", + "@tanstack/start-client-core": "1.170.34", + "@tanstack/start-storage-context": "1.167.36", + "fetchdts": "^0.1.6", + "h3-v2": "npm:h3@2.0.1-rc.20", + "seroval": "^1.6.7" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/start-storage-context": { + "version": "1.167.36", + "resolved": "https://registry.npmjs.org/@tanstack/start-storage-context/-/start-storage-context-1.167.36.tgz", + "integrity": "sha512-x+xCXK2GtFzY6NbXqAg8YpU6cwAjDfMeYSNzxfGzntpjbwBRHHrXeC/kYUnBBQCV7wK4kJ8vBBQGP0OyYTasUg==", + "license": "MIT", + "dependencies": { + "@tanstack/router-core": "1.171.34" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/store": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.11.2.tgz", + "integrity": "sha512-sJ4mjol8uQsHV0gOJzzjwXfh2Fwm+Sz0+8deqiTm4jGbMdjzNSW+xZCFm0kUa870uhd8yi+DpKnZb5Kc4apa0Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/virtual-file-routes": { + "version": "1.162.0", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-file-routes/-/virtual-file-routes-1.162.0.tgz", + "integrity": "sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==", + "license": "MIT", + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/@unpic/core": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@unpic/core/-/core-1.0.3.tgz", + "integrity": "sha512-aum9YNVUGso7MjGLD0Rp/08kywCGLqZ03/q6VQBFFakDBOXWEc8D4kPGcZ8v5wEnGRex3lE+++bOuucBp3KJ/w==", + "license": "MIT", + "dependencies": { + "unpic": "^4.2.2" + } + }, + "node_modules/@unpic/react": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@unpic/react/-/react-1.0.2.tgz", + "integrity": "sha512-5RmRfELwTF8w+4zjtQGqjpvX+RU2VLvis3xDCS1O2uWk0PZN2cvatL+3/KAR3mshAuRrkFGTX1XwyAezSXaoCA==", + "license": "MIT", + "dependencies": { + "@unpic/core": "^1.0.3" + }, + "peerDependencies": { + "next": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "next": { + "optional": true + } + } + }, + "node_modules/@vercel/og": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@vercel/og/-/og-1.0.3.tgz", + "integrity": "sha512-/iYJ34PDu4lty1TXdL86qHEw8viveHTllG1PWLuJX8tSFfqKL7kyVJeUORJmQ250bHB0h+alcalXUlza3c/NSA==", + "license": "MPL-2.0", + "dependencies": { + "@resvg/resvg-wasm": "2.4.1", + "satori": "0.33.5" + }, + "engines": { + "node": ">=22" + }, + "optionalDependencies": { + "sharp": "^0.35.3" + } + }, + "node_modules/@vinext/types": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vinext/types/-/types-1.0.1.tgz", + "integrity": "sha512-zH4WbVl47rNGxG8Y7XoWJAc8e0VQFQ+r8Cuh0crv1L2SuNovDD3jMtxQDjzoS1b9hYaZXbds0CjRo5tSm7F9Zw==", + "license": "MIT", + "engines": { + "node": ">=22" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.2.tgz", + "integrity": "sha512-fhJNGUdscQa4HkI0xFxwonWyhnVReCPDbXI7FH7jmzpnVCrFQI7PRrhWecO263610vOrs9tr2Y4xcf8uAdFxbw==", + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.152.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "oxc-transform-react": { + "optional": true + } + } + }, + "node_modules/@vitejs/plugin-rsc": { + "version": "0.5.38", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-rsc/-/plugin-rsc-0.5.38.tgz", + "integrity": "sha512-SoiRBJBVd3Qg6Frnvdk6LwugJYlQKgee+uqySxKz5T/KsCZUgdw529Klzg4IDJuP/EOfsIJ2YiOKAFY8tnr1kg==", + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1", + "es-module-lexer": "^3.0.3", + "estree-walker": "^3.0.3", + "magic-string": "^1.4.3", + "obug": "^3.0.0", + "srvx": "^1.0.5", + "strip-literal": "^4.0.0", + "turbo-stream": "^3.2.1", + "vitefu": "^1.1.3" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*", + "react-server-dom-webpack": "*", + "vite": "*" + }, + "peerDependenciesMeta": { + "react-server-dom-webpack": { + "optional": true + } + } + }, + "node_modules/@vitejs/plugin-rsc/node_modules/magic-string": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.3.tgz", + "integrity": "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.6.0" + } + }, + "node_modules/@vitejs/plugin-rsc/node_modules/srvx": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/srvx/-/srvx-1.0.7.tgz", + "integrity": "sha512-8h30Qy2cpYkcXgByHNpV4+jp609bU3ic7MqnfyLQ2Fpa8BgjIaI2zfsDKAIbwm8DcYDrCLqm5izF5KeL2nxdvg==", + "license": "MIT", + "bin": { + "srvx": "bin/srvx.mjs" + }, + "engines": { + "node": ">=20.16.0" + } + }, + "node_modules/acorn": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-loose": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.5.2.tgz", + "integrity": "sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansis": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.4.0.tgz", + "integrity": "sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/babel-dead-code-elimination": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.12.tgz", + "integrity": "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" + } + }, + "node_modules/base64-js": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", + "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.32", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.32.tgz", + "integrity": "sha512-UvuxFU9P3hM29LrQdwu0cD6w6/+SFr+UlB9s/knI7+O2rK9xFxKUwSDWxGdbbqQ9/V7BJ5s0NI5nQAE4uJp3gQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.29.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.4.tgz", + "integrity": "sha512-2TcbbiwXEq+N0kD36tykpCfyyQigUXmuwNQbnPp4Xk4PX9JOqVIKjJlIDjpH7uY6tmRGoAd+apeT1p60T8wsdA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.29", + "caniuse-lite": "^1.0.30001816", + "electron-to-chromium": "^1.5.459", + "node-releases": "^2.0.59", + "update-browserslist-db": "^1.3.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001819", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001819.tgz", + "integrity": "sha512-LFUqIIAwpzsIuevnKnsR9qnStBcgzPShTX61lBwN9uFkkf8o8zLiebEjbW8AYtZiF+1YKDWfdt/pWDtMuG8Xwg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==", + "license": "MIT" + }, + "node_modules/css-background-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz", + "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==", + "license": "MIT" + }, + "node_modules/css-box-shadow": { + "version": "1.0.0-3", + "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz", + "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==", + "license": "MIT" + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-gradient-parser": { + "version": "0.0.17", + "resolved": "https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.17.tgz", + "integrity": "sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.464", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.464.tgz", + "integrity": "sha512-nRa65aFge40viPAKxMKULIY8tcXKwKboJWNn4RoKwyWXJ6SP7BnrDGKUTzc64818jIciH0PK7LSF8QzZes19GA==", + "license": "ISC" + }, + "node_modules/emoji-regex-xs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz", + "integrity": "sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/es-module-lexer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-3.0.4.tgz", + "integrity": "sha512-BldNY5mwkVu+cQ5Ymn3e6hB9Sx8XHx4ZevWbiUyZbfKxJxYO27Hf0wfzkxIaD5CAJMaGl3YspKELj0ff/7nCMA==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/exsolve": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.3.tgz", + "integrity": "sha512-kuzL9zherLQoqDeQaS55AiiIg1kb4KYXaSusTtgZTPlvKP2gGCI82LNmBNh5RjDVUXIcmgx+/Mx7vPwRzBbhJA==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetchdts": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/fetchdts/-/fetchdts-0.1.7.tgz", + "integrity": "sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==", + "license": "MIT" + }, + "node_modules/fflate": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.5.tgz", + "integrity": "sha512-QieYf//cis6ywHNi5qW1+PXPQ4bC+XVJAtS4AXIML8P76GroEiOxm/oQtn1f02UkJY1+KsXMJcC+R2v/Eg4G3g==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/h3-v2": { + "name": "h3", + "version": "2.0.1-rc.20", + "resolved": "https://registry.npmjs.org/h3/-/h3-2.0.1-rc.20.tgz", + "integrity": "sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==", + "license": "MIT", + "dependencies": { + "rou3": "^0.8.1", + "srvx": "^0.11.13" + }, + "bin": { + "h3": "bin/h3.mjs" + }, + "engines": { + "node": ">=20.11.1" + }, + "peerDependencies": { + "crossws": "^0.4.1" + }, + "peerDependenciesMeta": { + "crossws": { + "optional": true + } + } + }, + "node_modules/harfbuzzjs": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/harfbuzzjs/-/harfbuzzjs-0.10.0.tgz", + "integrity": "sha512-SN8LVwCOzvTq3OPNd0+EAghgXugItz56wst567D1vs7LnnKGWprhi3EG58aVOBwhN8HEbQxL4I9NDWkcXUutRw==", + "license": "MIT" + }, + "node_modules/hex-rgb": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz", + "integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ipaddr.js": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.5.0.tgz", + "integrity": "sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isbot": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/isbot/-/isbot-5.2.2.tgz", + "integrity": "sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w==", + "license": "Unlicense", + "engines": { + "node": ">=18" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/linebreak": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz", + "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==", + "license": "MIT", + "dependencies": { + "base64-js": "0.0.8", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/next": { + "version": "16.4.3", + "resolved": "https://registry.npmjs.org/next/-/next-16.4.3.tgz", + "integrity": "sha512-OqxKTGi9u80FydydsMNYNjnuje9Au+kvHlt2GZ//ftdpDHm1dxKqAaENoOOTX5wKzn+9vaKUNIfZeyZUuLhCnA==", + "license": "MIT", + "dependencies": { + "@next/env": "16.4.3", + "@swc/helpers": "0.5.23", + "baseline-browser-mapping": "^2.9.19", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.5.23", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.4.3", + "@next/swc-darwin-x64": "16.4.3", + "@next/swc-linux-arm64-gnu": "16.4.3", + "@next/swc-linux-arm64-musl": "16.4.3", + "@next/swc-linux-x64-gnu": "16.4.3", + "@next/swc-linux-x64-musl": "16.4.3", + "@next/swc-win32-arm64-msvc": "16.4.3", + "@next/swc-win32-x64-msvc": "16.4.3", + "sharp": "^0.35.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.60", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.60.tgz", + "integrity": "sha512-OmO8+GM1JUZqXET720VrJCwkjUCXmCMQm0Z3UDDRbfNLHS4NEAvY60j5jiFv0tkKw2PNNlqOLhahVmwJIOLDIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/obug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/obug/-/obug-3.0.0.tgz", + "integrity": "sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==", + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" + }, + "node_modules/parse-css-color": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz", + "integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.1.4", + "hex-rgb": "^4.1.0" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/prettier": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.10.tgz", + "integrity": "sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.1.tgz", + "integrity": "sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.1.tgz", + "integrity": "sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.1" + } + }, + "node_modules/react-server-dom-webpack": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-server-dom-webpack/-/react-server-dom-webpack-19.3.1.tgz", + "integrity": "sha512-I1Smf6Yc+389rFWPwyYjvCQVK1XFWpb2M9gvgYgfpbZ+LPqkZtb0tT9Fwdk0K+wknK2E+ns82lC0DCYLnXCVGA==", + "license": "MIT", + "dependencies": { + "acorn-loose": "^8.3.0", + "neo-async": "^2.6.1", + "webpack-sources": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^19.3.1", + "react-dom": "^19.3.1", + "webpack": "^5.59.0" + } + }, + "node_modules/readdirp": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", + "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rolldown": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz", + "integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.155.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.15", + "@rolldown/binding-android-arm64": "1.2.15", + "@rolldown/binding-darwin-arm64": "1.2.15", + "@rolldown/binding-darwin-x64": "1.2.15", + "@rolldown/binding-freebsd-x64": "1.2.15", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.15", + "@rolldown/binding-linux-arm64-gnu": "1.2.15", + "@rolldown/binding-linux-arm64-musl": "1.2.15", + "@rolldown/binding-linux-ppc64-gnu": "1.2.15", + "@rolldown/binding-linux-s390x-gnu": "1.2.15", + "@rolldown/binding-linux-x64-gnu": "1.2.15", + "@rolldown/binding-linux-x64-musl": "1.2.15", + "@rolldown/binding-openharmony-arm64": "1.2.15", + "@rolldown/binding-win32-arm64-msvc": "1.2.15", + "@rolldown/binding-win32-x64-msvc": "1.2.15" + } + }, + "node_modules/rou3": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.8.1.tgz", + "integrity": "sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==", + "license": "MIT" + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/satori": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/satori/-/satori-0.33.5.tgz", + "integrity": "sha512-PNW6ktrQ8SM6kk7u4aOuTkkUewkzyTOrj+QeEzXSsnNMAdff4ire9CAqIz8+4C3rCiBtK8QTELv52AZEd1PbRw==", + "license": "MPL-2.0", + "dependencies": { + "@shuding/opentype.js": "1.4.0-beta.0", + "css-background-parser": "^0.1.0", + "css-box-shadow": "1.0.0-3", + "css-gradient-parser": "^0.0.17", + "css-to-react-native": "^3.0.0", + "emoji-regex-xs": "^2.0.1", + "escape-html": "^1.0.3", + "fflate": "0.7.3", + "harfbuzzjs": "0.10.0", + "linebreak": "^1.1.0", + "parse-css-color": "^0.2.1", + "postcss-value-parser": "^4.2.0", + "yoga-layout": "^3.2.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/seroval": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.7.2.tgz", + "integrity": "sha512-NPOYrDVbvtuTo5m9InqKE7O6wBASON46OabjyqLUGPvoXNDYp0pReuFYkqOQwGsoj1OpZVj6mIdnRRgt5O1/gQ==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/seroval-plugins": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.7.2.tgz", + "integrity": "sha512-ud8kMCGLHmGkW9YtVDluJtqTukSx/4YBqtmPAvAz/HxbIwhwMeZU52imxeyZ1zoAXtqBDiaLwSasbnK9DptrDg==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "seroval": "^1.0" + } + }, + "node_modules/sharp": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.5.tgz", + "integrity": "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.5", + "@img/sharp-darwin-x64": "0.35.5", + "@img/sharp-freebsd-wasm32": "0.35.5", + "@img/sharp-libvips-darwin-arm64": "1.3.4", + "@img/sharp-libvips-darwin-x64": "1.3.4", + "@img/sharp-libvips-linux-arm": "1.3.4", + "@img/sharp-libvips-linux-arm64": "1.3.4", + "@img/sharp-libvips-linux-ppc64": "1.3.4", + "@img/sharp-libvips-linux-riscv64": "1.3.4", + "@img/sharp-libvips-linux-s390x": "1.3.4", + "@img/sharp-libvips-linux-x64": "1.3.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", + "@img/sharp-libvips-linuxmusl-x64": "1.3.4", + "@img/sharp-linux-arm": "0.35.5", + "@img/sharp-linux-arm64": "0.35.5", + "@img/sharp-linux-ppc64": "0.35.5", + "@img/sharp-linux-riscv64": "0.35.5", + "@img/sharp-linux-s390x": "0.35.5", + "@img/sharp-linux-x64": "0.35.5", + "@img/sharp-linuxmusl-arm64": "0.35.5", + "@img/sharp-linuxmusl-x64": "0.35.5", + "@img/sharp-webcontainers-wasm32": "0.35.5", + "@img/sharp-win32-arm64": "0.35.5", + "@img/sharp-win32-ia32": "0.35.5", + "@img/sharp-win32-x64": "0.35.5" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/srvx": { + "version": "0.11.22", + "resolved": "https://registry.npmjs.org/srvx/-/srvx-0.11.22.tgz", + "integrity": "sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==", + "license": "MIT", + "bin": { + "srvx": "bin/srvx.mjs" + }, + "engines": { + "node": ">=20.16.0" + } + }, + "node_modules/string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==", + "license": "MIT" + }, + "node_modules/strip-literal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-4.0.0.tgz", + "integrity": "sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==", + "license": "MIT", + "dependencies": { + "js-tokens": "^10.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "license": "MIT" + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/turbo-stream": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-3.2.1.tgz", + "integrity": "sha512-BaX0eWz3IrypOVDFqPv3VGD6uZZW8y3oFAOJqZQ+oopmOyQ8/xNm7IMwAJFvxax2DBa8zSk+/AeqA6D6b1PXGg==", + "license": "MIT" + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "license": "MIT" + }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "license": "MIT", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "node_modules/unpic": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/unpic/-/unpic-4.2.2.tgz", + "integrity": "sha512-z6T2ScMgRV2y2H8MwwhY5xHZWXhUx/YxtOCGJwfURSl7ypVy4HpLIMWoIZKnnxQa/RKzM0kg8hUh0paIrpLfvw==", + "license": "MIT" + }, + "node_modules/unplugin": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.4.0.tgz", + "integrity": "sha512-9skdIFlCsPdFV7wUfZxNsFInlW+7nJmGu2gkTu0OUhF56aXGsHab9x52/QhdJ4lC7ZDPWTxbiC4ANqVlsuaW3w==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "picomatch": "^4.0.7", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@farmfe/core": "*", + "@rsbuild/core": "*", + "@rspack/core": "*", + "bun-types-no-globals": "*", + "esbuild": "*", + "rolldown": "*", + "rollup": "*", + "unloader": "*", + "vite": "*", + "webpack": "*" + }, + "peerDependenciesMeta": { + "@farmfe/core": { + "optional": true + }, + "@rsbuild/core": { + "optional": true + }, + "@rspack/core": { + "optional": true + }, + "bun-types-no-globals": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "rolldown": { + "optional": true + }, + "rollup": { + "optional": true + }, + "unloader": { + "optional": true + }, + "vite": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.7.0.tgz", + "integrity": "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vinext": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/vinext/-/vinext-1.3.0.tgz", + "integrity": "sha512-VIZ2hCdOu3gpxN2qRGEzHmY+srewGqkQuLIjsgNLua2lDkXETcr6ShHqFNOyrS4TMtzqiq8KZ7Sl3HefdkDFGg==", + "license": "MIT", + "dependencies": { + "@unpic/react": "^1.0.2", + "@vercel/og": "1.0.3", + "@vinext/types": "^1.0.1", + "ipaddr.js": "^2.1.0", + "magic-string": "^0.30.21", + "vite-plugin-commonjs": "^0.10.4", + "web-vitals": "^4.2.4" + }, + "bin": { + "vinext": "dist/cli.js" + }, + "engines": { + "node": ">=22" + }, + "peerDependencies": { + "@mdx-js/rollup": "^3.0.0", + "@vitejs/plugin-react": "^5.1.4 || ^6.0.0", + "@vitejs/plugin-rsc": "^0.5.37", + "react": "^19.3.1", + "react-dom": "^19.3.1", + "react-server-dom-webpack": "^19.3.1", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@mdx-js/rollup": { + "optional": true + }, + "@vitejs/plugin-rsc": { + "optional": true + }, + "react-server-dom-webpack": { + "optional": true + } + } + }, + "node_modules/vite": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz", + "integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==", + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.30", + "rolldown": "~1.2.14", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1 || ^0.8.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-commonjs": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/vite-plugin-commonjs/-/vite-plugin-commonjs-0.10.4.tgz", + "integrity": "sha512-eWQuvQKCcx0QYB5e5xfxBNjQKyrjEWZIR9UOkOV6JAgxVhtbZvCOF+FNC2ZijBJ3U3Px04ZMMyyMyFBVWIJ5+g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.12.1", + "magic-string": "^0.30.11", + "vite-plugin-dynamic-import": "^1.6.0" + } + }, + "node_modules/vite-plugin-dynamic-import": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-plugin-dynamic-import/-/vite-plugin-dynamic-import-1.6.0.tgz", + "integrity": "sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg==", + "license": "MIT", + "dependencies": { + "acorn": "^8.12.1", + "es-module-lexer": "^1.5.4", + "fast-glob": "^3.3.2", + "magic-string": "^0.30.11" + } + }, + "node_modules/vite-plugin-dynamic-import/node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.5.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.31.tgz", + "integrity": "sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.20", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, + "node_modules/webpack-sources": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.6.0.tgz", + "integrity": "sha512-EIMmPVvNI0CYXyRPp34F2Qk7W37/BZVZIofS6LAUnrNjCVahS+hO4mxwFJDjQjODTGZDtVzLYoN2+1dYkhk9qA==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "license": "MIT" + }, + "node_modules/xmlbuilder2": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-4.0.3.tgz", + "integrity": "sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA==", + "license": "MIT", + "dependencies": { + "@oozcitak/dom": "^2.0.2", + "@oozcitak/infra": "^2.0.2", + "@oozcitak/util": "^10.0.0", + "js-yaml": "^4.1.1" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yoga-layout": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", + "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", + "license": "MIT" + }, + "node_modules/zod": { + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} From 2c04946ef5ee9756ac1d6e48f06b1e5b371006b9 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 25 Oct 2026 11:24:16 -0600 Subject: [PATCH 6/7] docs: pin the charts to their published measurement evidence --- src/components/landing/RedactLanding.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/landing/RedactLanding.tsx b/src/components/landing/RedactLanding.tsx index fc6a95817..b1ffb8671 100644 --- a/src/components/landing/RedactLanding.tsx +++ b/src/components/landing/RedactLanding.tsx @@ -136,7 +136,7 @@ export default function RedactLanding() { every emitted chunk. Shared scale, 1 KB = 1,000 bytes.

Versions, source, and measurements ↗ From 0e11147a8e93bd8680a71254ebbf31800186a470 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sun, 25 Oct 2026 12:34:36 -0600 Subject: [PATCH 7/7] Refine Redact framework bundle charts --- public/images/frameworks/README.md | 7 ++ public/images/frameworks/next.ico | Bin 0 -> 15086 bytes public/images/frameworks/vinext.ico | Bin 0 -> 34494 bytes public/images/frameworks/vite.svg | 130 +++++++++++++++++++++++ src/components/landing/RedactLanding.tsx | 65 ++++++++---- 5 files changed, 179 insertions(+), 23 deletions(-) create mode 100644 public/images/frameworks/README.md create mode 100644 public/images/frameworks/next.ico create mode 100644 public/images/frameworks/vinext.ico create mode 100644 public/images/frameworks/vite.svg diff --git a/public/images/frameworks/README.md b/public/images/frameworks/README.md new file mode 100644 index 000000000..700c7a68e --- /dev/null +++ b/public/images/frameworks/README.md @@ -0,0 +1,7 @@ +# Framework icons + +- `vite.svg`: [Vite's official icon](https://github.com/vitejs/vite/blob/main/docs/public/logo-without-border.svg). +- `vinext.ico`: [Vinext's site favicon](https://github.com/cloudflare/vinext/blob/main/apps/web/app/favicon.ico). +- `next.ico`: [Next.js's site favicon](https://nextjs.org/favicon.ico). + +TanStack Start uses the site's existing `/favicon-light.svg`. diff --git a/public/images/frameworks/next.ico b/public/images/frameworks/next.ico new file mode 100644 index 0000000000000000000000000000000000000000..af98450595e8b8efd9e505cddc5ed705b665a4d8 GIT binary patch literal 15086 zcmdU$XN*0PW5y#)gXL_h{3FkJ#X`oXpI?bB5#G)w~S7Qa+`W<1AB#X3C=?&UhvAO=|S+ zQpCR%R9`2h-z)7_x}fw(>6KDpfVd}*GI-!c2H9UDrKwS>=#NU@Ddj7@Q4*g7FEYrY z16}AW?v$zq+9+i!-B+T1{bG*9hmHqIUn`*-8^w`osM0?vVJi}rWb@IzKnYt#l~PpE zZq^t6O{HGFdQ!P^WzlxPHWGIHcd>D{}x={sTUg9&WW6602m zQnBH6>!yx}4jn2B7A%n2vuDesNt2{;dd zh7B@$^l0CFc@ZrPKrArsz@`@AQzbS#)CVarSbb!I8ty{PH zk}X}jv}9#v$)iV)Gb-#m>4qUO6)cT2PV3 zpI*Is$&Ww&XxZfC$&*s6RxM+zLWK&_s8J(BjQt6=fsGRsIez?@ix)2jvEROZTiUm8 zAGA}oYE|jjv7_)^<8Q|B8-jA4x_+h43HdwG`akQZ{rmR^u|IqEOoj~`7J{KpojS(< z>D#xjnZIoEL8L15HMT(z#WR80C=8eJ6m1l4LW@cu}s8OTj^Upsw@4?*W6SJES z?6iS9&)0pV`lp_$Z=3e*+h^9ZUK>rCG?5uIW|;4L`0(N0^@=YH0qjNg{kCh@PHx@0 zWueQ33l}2#^Q~LAHa;_LgYTK1p6(a3o6pAd+gv_56 zTeSG07MmF9|6)G^Q&#}`NMn_Um~~0isUI6)0h8ZU;`^Lf>f{vqND)`@P9?$9TK1fc;tCyQ6!+t!2dtUtke$_><;tw&q0@ECem?{wl!rS3|>b6OetkXT}@W?k_+rGrYh zl>Vi}m;6*0c#P>*l+@N$%>EBBFmQe{Fc#%OC9f_nmD)f~S=dohhj8vYl zv6`=x&=pVWsLX#+q8mig9W$TUxvt*}bzk7L-lNk`>Y+?Gm163T#zTyXvm=~)sb0N0 zaaweuJ6Zx`(zaEHG-%L3KK=Al6T>DZPhLQGq zy?Yqg@b-sP&7-d+WX~-}jDPy{>9TCuG9i8(A^wLgY}(XWZ-_f3WuJ2&?4j-5yH}Ph zSrTpU9$VNX@qMmWifEgC6yB+S|Ng&-_q*kY6P-PKR*oJ$D&4wui>NOkgH3F=P`Ve$ z3oFArk%&op&JP9oiCbR3eqHX}yJupw-hGKM`tJs8Gp0rz*J9ak*s!6TKY!j}B<@Qe z2xHHihfO=4d&@$equD1uh)vR!D_5jhvt}W(F>o+n#QfeP*=Ky4KYza26Uxue7xt`( zwGs1UFEoa2%CXJd6_q!V{lS9=%abQh(nAuU?8F#8U%^agA*f5vUU zO`A5Rzftd-H*XGp=j=}sgJvHomR>El^LJEU_xn@7oB=$3{5YoN^y$-PoVT`!UrwAj z(d>cRyeL=eJNUAXP0n?!TD8j9&dbY_&Ye4l$oA~n)9gP*+v9QJq3wP5KkQGLGDTj# zd};PI#*Q5uVjI0fh76HSn>LxVdoDY_;0u&tn{OaexyiTnfB*h{;fw|QLCcpf4;xpW zFkyme8_o^J(yQeMlzfjrrqcE2$dM!Fd_g$&SWBkEa^gaG!|Jt={ z=KFH#39++i(IT_Yx^(H%ko++GcKr1<|Ih~0rcI04uj!BQ`Z)V#=O2Y;=E9`s-!ShO zsSe!pFZPSf|L}>y>wkcu$o#Ju7{d8q*e4a4|Eapd)ji*PB>xlpq$2UZRgc#`wqyC< z*e8K8>Gg-|00V0nbj5maWeG|22l`3AlJ{NwJ|l|`ufMHXz7k^tYsg%g=)+?N8;M_9LtdS2KI3UcQZk+)cWFG|X4L^R?nKNgM zJp7#1#y{fx7Zcyn1ijH<*t+zGuIF{p8Z6OUCbF zJuqm{AfqFUdUSJ))2_z+s>OeFWelDY)Ji4$N2uccI^tDkzj4ezJD0s z6WNgVqu%*n4eJGq6%4dL{ChgGeu>7EL-^0_?g*h+#L_?w5JASe8m?7?5sEOR!;qdrsz4+_H`c0ii`f50T z*SGxQAD;xoLsJ9dpVL(_c$O;uJ69D2r6KWMz!W714e`P{UHoN%CMImxhf~|t_|41y zJxeX*GGak0_pue>x*uMym7NKimvY-L+pYDEmCqSJe~(_U;-Jwlq?ibGW$Zr-NCh`GFfmdFnC~9j((XT|hp^<4RFO4%8suT=I3XNZ} zF4Hudle`Hgf^%AKBhC{m-YVBFANPsik`^m(T%7616lDIG7UnZnJU?f8I9;rGtK39n z;!G1)CQPfdZl)*QaQAVe(`t+@sfMFx%$^&L8BxPgpPBQond(eA-n>*NawyQ4-Vn~u z0YBNOiF+1fY@HRV7si(9Z;xFS%6E=u$>2X5<`bI^>Z0PbDIQ#Q_Wi-{kdqBq-io84}~xhQy?GA+d0WCj222O(uj- zGsV1ph8VY17Y`JL`B`|t$fGtsTw~-6nXOK{VU({rS^4}PbnL4(#H$

J9~q8;*U z<|R&jDJs|gnv8rnZNHBL;uR|2dcXErtR2}?W6F01>nOp4r;YYkzv9!~vWjSTZhwBa zTRKs=Q{Vj3dcAPQ9^;9+ka;PW>!hFXIa{>>zZvbTzV=mL=0QpKa$XQsCY08hpX!e#A9p;bC73AAX%mI0vz{ERy6VLpeMNIv~xJ3NV+a z>zL0JPp{R*AFcVXvu?ttR~S!G8{9WJuqsyFoksY?m=!_s_Ue$B@I^>`xIQGN;M-b=Y-!BUw&(dx%iHFa?RQKc-aZFJJKkp z{bt*EG{mAUR(y|fezE==T~@#Ts3C5fSHB(ZFVgnXT$$>pKyskA7+#zneZ)LfY&oQd zzi(XfzjcnLZ#f?3o$F^g^yT{8kmLaUJ(6r)(bAJH zE;#o%i&8L*E&X z&QNE6{8ebkkU8qKWNG*n)^P(N^I~VYsp1Dt8XfT6uO>sodtZc}OSQge`OxPFC0ak$ ztBddsu=`iE@=}SLw@rHh-<@^w=y-CT`YC+_r&4|*dFXp_YV}7K5SiDJ`pJxMPSy<4PzboF|X4!P_q}j%)9W0qsd)PSfMRI5UlE7siD}CB< zD$f-z1pUb-{b-05TW45b+z{=P4*ijISo)JTyy}#3?Q6?|1x*z;R_O&hPMQVdx9LfR zDdk2!$pW@x{q4PTT9=Z0-j;1hjQw>xeHxx)9ZFQ4F~e)QQEW=0*_p^VtUcDK=H;-V z=;Pd)n*s4-u#XUuwj(C;IJi<_nFnBTgLjuZrGagrDJ^__9_DQ zFcG#lv2^I*8S^^iRj`(N)((f|?}RS=CD<1gZqdX{>=nTNMaiAAt2!uqa&eW^fs zVkPzs*6h;->@Vb+J^HC!H{W{15U}qQdruew>xfKx#NGn>r8rV&itva!f5vUo z$6B%{+TFpP|6rfsqeRA#bfuv_LwjlQ#++xr(2F!ft_w@LS$|w@A$5w@%WavnyfX-C zEd8d|4Abw{ALvX$nLZJF$7D|~>2uLceZkfxv`cgBNj_oIpJDx>HoOXb0s1TMmHWG4 z{h>WQ^y4Co_1!F;;r?pR!HHIf9@#kdKikn>QM&Xak#feb4eiAKYu?gtjDa|Z&$*MuxZ1*QpA~!b-WZcYb~|KHf2a=F@aMVo!=@!hysa~C{o(taM~xdFnXWGW z`D@{Qw$5+(k7CRl^TOibL@86|sgXK%4QxPR8`;jGC(b?^6?e7`(`!NQ51db-GZonX zx&(Qoj=_esJ=vWmq8Evzd3u35*-1|#IB1P%AEM127w;bL(2?oTExglfkJZXO=%nhm zWKDTk-V(R?khi5HR!^F-%kFi%(~c}P)zXxza(p7ygP?auNW!s$7JJ?1!Z;>mi> zyxI30Pp~Fnw#A%hVA*d`gl0m{?NDSyK6$v!}g{C_E;mQYzz(FcEspR_BrwLCi9GC#}IiF(icvj z1(4(_We!?woZ|>OaiSOZ5jw*>G*LX$BK5_hh4HM1Br}q)6&UAs;CQK1j&yc>Q^z@V z#)%VMeDB1meQ?ihmJK-5!n$Jj1)@LOgRA{nf24j`vaW}_^2p~+6-V-=x>?SQJD~j> zak8x#TKsYQHHj_}ow36CB7c@WK})t-ulFvRj6s?ohmyhv|>0 zXYtC&^fPBW5RUrJE8PLjL^jc!QJ4=qBp4zo4Z%_?9Yfed!6FK0<1J_s#94U>ab6yz zD>%9(;YGwpJ`AS_mRbjC_Yy_ zG^QT-^jnl1=Mwp3CBIALmz8`k zk#AP=za)9zq>&A*^usjU!TXXpynh9sNaQyb?V!Xf)UsmdT(nI)UP3(j?rJmD9-o*1az`;)KR1m^^IE!1jo zE-1ohEz5%RpfP0DpZd)@o1jZT^7C6)5& z|0U?6b7=8ofbWH}!*yndRCuR6RHt3TZOK&FfzmIvw&XZ;}=5rMo+jiotYYF~WWDLf|o^+0q>2EANT5IH7 z|GMQrJd3`Mac*-ncuO0f@#M6=Qt#0*%lZNA@Z-MAP!+xtcRQFeR|6 zv3z7AKfVRi?jzXU{-l4K59-}AL4RY*#9D0|d=po>X-?-o&M;4HES;ImUv^mUBF~p* z;9UWK!4=jSsify}ndI4BHpYkk@Hd*)^vzrzRr8RS`-|Mv$>n$uifq&bYA$TG5%`sT!QodFOm42vLo(_0A;OT&;1D+0eI^gMmrvsi2q+JIf((Jj& zUjZ)q?;5&d!czHIX~wWJeBVO)bqN304aKyO{v6=hf&4b$YHh(QE!fq9A`J0AIF*!a zDE=46g3>_*$%haN!lMKJFbC8TL=DJ>i)x`OAGOd`3daz1)lhM`^l&nXXU)(50g1C5 AfdBvi literal 0 HcmV?d00001 diff --git a/public/images/frameworks/vite.svg b/public/images/frameworks/vite.svg new file mode 100644 index 000000000..0f2bdacd0 --- /dev/null +++ b/public/images/frameworks/vite.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/landing/RedactLanding.tsx b/src/components/landing/RedactLanding.tsx index b1ffb8671..cf0709980 100644 --- a/src/components/landing/RedactLanding.tsx +++ b/src/components/landing/RedactLanding.tsx @@ -12,6 +12,12 @@ const largestBundle = Math.max( ]), ) const kb = (bytes: number) => (bytes / 1000).toFixed(1) +const frameworkLogos = new Map([ + ['Start', '/favicon-light.svg'], + ['Vite', '/images/frameworks/vite.svg'], + ['Vinext', '/images/frameworks/vinext.ico'], + ['Next.js', '/images/frameworks/next.ico'], +]) const setups = [ { name: 'Next.js', @@ -89,8 +95,15 @@ export default function RedactLanding() {
{bundleSizes.comparisons.map((item) => (
-
-

+
+

+ {item.framework === 'Start' ? 'TanStack Start' : item.framework} @@ -105,43 +118,49 @@ export default function RedactLanding() { % smaller

-
+
{[ { name: 'React', bytes: item.reactBytes, redact: false }, { name: 'Redact', bytes: item.redactBytes, redact: true }, ].map((row) => (
-
- {row.name} - - {kb(row.bytes)} KB - + +
+
+ +
- ))}

))}
-
+

} >