Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(turbopack): hash the font file name if it exceeds our max file size #69144

Merged
merged 2 commits into from
Sep 11, 2024

Conversation

arlyon
Copy link
Contributor

@arlyon arlyon commented Aug 21, 2024

What?

When using google fonts, we import files and write them with their hash to the filesystem. Some of these fonts get very close to the file size limit which, after appending a hash onto them, causes turbo to fail with a write error.

Why?

Different operating systems have different path length requirements. In short:

  • macOS: limit per segment, longer limit for entire path length
  • unix: limit per segment, longer limit for entire path length
  • windows: hard limit of 260 chars unless using UNC

We need to respect these.

How?

A small change in the font code that rewrites filesystem paths if they approach this limit, with some buffer room. Rather than truncating I opted for a 64 bit hash because many fonts have long common prefixes. We could bump this up to 128 or higher but in practice there will be very very few files that need this code path. (bgw): This now uses a combination of truncation (for legibility/debuggability) and a 128 bit hash (for collision avoidance).

Another option is a general handler for this where reads and writes are intercepted in turbo tasks fs but I wanted to achieve a few things:

  • explicitly handle sources of problematic file names at the source, rather than having a blanket impl
  • avoid obscure hashed names appearing in our outputs generally since it makes debugging harder
  • avoid lots of hashing on reads and writes

To me it is safer to have the source ensure they are meeting the needs of the system since we can control source specific implementations.

Closes PACK-3012

@ijjk ijjk added created-by: Turbopack team PRs by the Turbopack team. Font (next/font) Related to Next.js Font Optimization. Turbopack Related to Turbopack with Next.js. labels Aug 21, 2024
@arlyon arlyon changed the title simplify font finding logic hash the font file name if it exceeds our max file size Aug 21, 2024
@arlyon arlyon marked this pull request as ready for review August 21, 2024 14:16
@arlyon arlyon force-pushed the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch from 5f85b3b to 7951fad Compare August 21, 2024 14:20
@arlyon arlyon changed the base branch from arlyon/attempt-fix-too-long-file to arlyon/font-code-refactor August 21, 2024 14:20
@ijjk
Copy link
Member

ijjk commented Aug 21, 2024

Tests Passed

@arlyon arlyon requested review from wbinnssmith and bgw August 23, 2024 17:26
@arlyon arlyon force-pushed the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch from 7951fad to ef64926 Compare August 29, 2024 12:34
@ijjk
Copy link
Member

ijjk commented Aug 29, 2024

Stats from current PR

Default Build (Increase detected ⚠️)
General
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
buildDuration 18.6s 15.8s N/A
buildDurationCached 8.5s 7.3s N/A
nodeModulesSize 358 MB 358 MB
nextStartRea..uration (ms) 433ms 433ms
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
1062.HASH.js gzip 169 B 168 B N/A
2cd9da90-HASH.js gzip 52 kB 52 kB N/A
5867-HASH.js gzip 42.5 kB 42.5 kB N/A
8503-HASH.js gzip 5.25 kB 5.25 kB N/A
framework-HASH.js gzip 56.9 kB 56.9 kB N/A
main-app-HASH.js gzip 224 B 224 B
main-HASH.js gzip 32.6 kB 32.6 kB N/A
webpack-HASH.js gzip 1.71 kB 1.71 kB N/A
Overall change 224 B 224 B
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 191 B 191 B
amp-HASH.js gzip 511 B 510 B N/A
css-HASH.js gzip 342 B 343 B N/A
dynamic-HASH.js gzip 1.84 kB 1.84 kB N/A
edge-ssr-HASH.js gzip 265 B 266 B N/A
head-HASH.js gzip 362 B 364 B N/A
hooks-HASH.js gzip 392 B 392 B
image-HASH.js gzip 4.4 kB 4.4 kB
index-HASH.js gzip 268 B 267 B N/A
link-HASH.js gzip 2.81 kB 2.81 kB N/A
routerDirect..HASH.js gzip 329 B 327 B N/A
script-HASH.js gzip 398 B 396 B N/A
withRouter-HASH.js gzip 325 B 324 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 5.28 kB 5.28 kB
Client Build Manifests
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
_buildManifest.js gzip 749 B 749 B
Overall change 749 B 749 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
index.html gzip 521 B 523 B N/A
link.html gzip 535 B 538 B N/A
withRouter.html gzip 518 B 519 B N/A
Overall change 0 B 0 B
Edge SSR bundle Size
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
edge-ssr.js gzip 128 kB 128 kB N/A
page.js gzip 180 kB 180 kB N/A
Overall change 0 B 0 B
Middleware size
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
middleware-b..fest.js gzip 671 B 667 B N/A
middleware-r..fest.js gzip 156 B 157 B N/A
middleware.js gzip 29.9 kB 29.9 kB
edge-runtime..pack.js gzip 844 B 844 B
Overall change 30.7 kB 30.7 kB
Next Runtimes
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
973-experime...dev.js gzip 322 B 322 B
973.runtime.dev.js gzip 314 B 314 B
app-page-exp...dev.js gzip 317 kB 317 kB
app-page-exp..prod.js gzip 125 kB 125 kB
app-page-tur..prod.js gzip 139 kB 139 kB
app-page-tur..prod.js gzip 134 kB 134 kB
app-page.run...dev.js gzip 305 kB 305 kB
app-page.run..prod.js gzip 121 kB 121 kB
app-route-ex...dev.js gzip 31.2 kB 31.2 kB
app-route-ex..prod.js gzip 21.1 kB 21.1 kB
app-route-tu..prod.js gzip 21.1 kB 21.1 kB
app-route-tu..prod.js gzip 20.9 kB 20.9 kB
app-route.ru...dev.js gzip 32.9 kB 32.9 kB
app-route.ru..prod.js gzip 20.9 kB 20.9 kB
pages-api-tu..prod.js gzip 9.62 kB 9.62 kB
pages-api.ru...dev.js gzip 11.5 kB 11.5 kB
pages-api.ru..prod.js gzip 9.61 kB 9.61 kB
pages-turbo...prod.js gzip 20.8 kB 20.8 kB
pages.runtim...dev.js gzip 26.4 kB 26.4 kB
pages.runtim..prod.js gzip 20.8 kB 20.8 kB
server.runti..prod.js gzip 57.7 kB 57.7 kB
Overall change 1.45 MB 1.45 MB
build cache Overall increase ⚠️
vercel/next.js canary vercel/next.js arlyon/pack-3012-file-name-too-long-os-error-63-since-142 Change
0.pack gzip 1.65 MB 1.65 MB ⚠️ +835 B
index.pack gzip 131 kB 131 kB N/A
Overall change 1.65 MB 1.65 MB ⚠️ +835 B
Diff details
Diff for page.js
@@ -15,7 +15,7 @@
       /***/
     },
 
-    /***/ 8611: /***/ (
+    /***/ 3857: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -30,7 +30,7 @@
         default: () => /* binding */ nHandler,
       });
 
-      // NAMESPACE OBJECT: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-stats19XU8Y%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
+      // NAMESPACE OBJECT: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-stats19XU8Y%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
       var page_next_edge_ssr_entry_namespaceObject = {};
       __webpack_require__.r(page_next_edge_ssr_entry_namespaceObject);
       __webpack_require__.d(page_next_edge_ssr_entry_namespaceObject, {
@@ -69,35 +69,35 @@
         tree: () => tree,
       });
 
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/web/globals.js
-      var globals = __webpack_require__(578);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/web/adapter.js + 3 modules
-      var adapter = __webpack_require__(8519);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/build/webpack/loaders/next-edge-ssr-loader/render.js + 85 modules
-      var render = __webpack_require__(2492);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/lib/incremental-cache/index.js + 3 modules
-      var incremental_cache = __webpack_require__(729);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/app-render/app-render.js + 74 modules
-      var app_render = __webpack_require__(1993);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/route-modules/app-page/module.compiled.js
-      var module_compiled = __webpack_require__(7055);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/route-kind.js
-      var route_kind = __webpack_require__(1384);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/client/components/error-boundary.js
-      var error_boundary = __webpack_require__(8292);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/app-render/entry-base.js + 9 modules
-      var entry_base = __webpack_require__(9147); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-stats19XU8Y%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/web/globals.js
+      var globals = __webpack_require__(1603);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/web/adapter.js + 3 modules
+      var adapter = __webpack_require__(6148);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/build/webpack/loaders/next-edge-ssr-loader/render.js + 85 modules
+      var render = __webpack_require__(301);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/lib/incremental-cache/index.js + 3 modules
+      var incremental_cache = __webpack_require__(6802);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/app-render/app-render.js + 74 modules
+      var app_render = __webpack_require__(1887);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/route-modules/app-page/module.compiled.js
+      var module_compiled = __webpack_require__(6217);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/route-kind.js
+      var route_kind = __webpack_require__(8636);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/client/components/error-boundary.js
+      var error_boundary = __webpack_require__(746);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/app-render/entry-base.js + 9 modules
+      var entry_base = __webpack_require__(6729); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapp-edge-ssr%2Fpage&page=%2Fapp-edge-ssr%2Fpage&pagePath=private-next-app-dir%2Fapp-edge-ssr%2Fpage.js&appDir=%2Ftmp%2Fnext-stats19XU8Y%2Fstats-app%2Fapp&appPaths=%2Fapp-edge-ssr%2Fpage&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&basePath=&assetPrefix=&nextConfigOutput=&flyingShuttle=false&preferredRegion=&middlewareConfig=e30%3D!./app/app-edge-ssr/page.js?__next_edge_ssr_entry__
       const component0 = () =>
         Promise.resolve(/* import() eager */).then(
-          __webpack_require__.bind(__webpack_require__, 6908)
+          __webpack_require__.bind(__webpack_require__, 176)
         );
       const component1 = () =>
         Promise.resolve(/* import() eager */).then(
-          __webpack_require__.bind(__webpack_require__, 4482)
+          __webpack_require__.bind(__webpack_require__, 5078)
         );
       const page2 = () =>
         Promise.resolve(/* import() eager */).then(
-          __webpack_require__.bind(__webpack_require__, 3073)
+          __webpack_require__.bind(__webpack_require__, 2934)
         );
 
       // We inject the tree and pages here so that we can use them in the route
@@ -163,12 +163,12 @@
       });
 
       //# sourceMappingURL=app-page.js.map
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/lib/page-types.js
-      var page_types = __webpack_require__(5067);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/app-render/encryption-utils.js
-      var encryption_utils = __webpack_require__(9845);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/esm/server/app-render/action-utils.js
-      var action_utils = __webpack_require__(4670); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/dist/build/webpack/loaders/next-edge-ssr-loader/index.js?{"absolute500Path":"","absoluteAppPath":"next/dist/pages/_app","absoluteDocumentPath":"next/dist/pages/_document","absoluteErrorPath":"next/dist/pages/_error","absolutePagePath":"private-next-app-dir/app-edge-ssr/page.js","dev":false,"isServerComponent":true,"page":"/app-edge-ssr/page","stringifiedConfig":"eyJlbnYiOnt9LCJlc2xpbnQiOnsiaWdub3JlRHVyaW5nQnVpbGRzIjpmYWxzZX0sInR5cGVzY3JpcHQiOnsiaWdub3JlQnVpbGRFcnJvcnMiOmZhbHNlLCJ0c2NvbmZpZ1BhdGgiOiJ0c2NvbmZpZy5qc29uIn0sImRpc3REaXIiOiIubmV4dCIsImNsZWFuRGlzdERpciI6dHJ1ZSwiYXNzZXRQcmVmaXgiOiIiLCJjYWNoZU1heE1lbW9yeVNpemUiOjUyNDI4ODAwLCJjb25maWdPcmlnaW4iOiJuZXh0LmNvbmZpZy5qcyIsInVzZUZpbGVTeXN0ZW1QdWJsaWNSb3V0ZXMiOnRydWUsImdlbmVyYXRlRXRhZ3MiOnRydWUsInBhZ2VFeHRlbnNpb25zIjpbInRzeCIsInRzIiwianN4IiwianMiXSwicG93ZXJlZEJ5SGVhZGVyIjp0cnVlLCJjb21wcmVzcyI6dHJ1ZSwiaW1hZ2VzIjp7ImRldmljZVNpemVzIjpbNjQwLDc1MCw4MjgsMTA4MCwxMjAwLDE5MjAsMjA0OCwzODQwXSwiaW1hZ2VTaXplcyI6WzE2LDMyLDQ4LDY0LDk2LDEyOCwyNTYsMzg0XSwicGF0aCI6Ii9fbmV4dC9pbWFnZSIsImxvYWRlciI6ImRlZmF1bHQiLCJsb2FkZXJGaWxlIjoiIiwiZG9tYWlucyI6W10sImRpc2FibGVTdGF0aWNJbWFnZXMiOmZhbHNlLCJtaW5pbXVtQ2FjaGVUVEwiOjYwLCJmb3JtYXRzIjpbImltYWdlL3dlYnAiXSwiZGFuZ2Vyb3VzbHlBbGxvd1NWRyI6ZmFsc2UsImNvbnRlbnRTZWN1cml0eVBvbGljeSI6InNjcmlwdC1zcmMgJ25vbmUnOyBmcmFtZS1zcmMgJ25vbmUnOyBzYW5kYm94OyIsImNvbnRlbnREaXNwb3NpdGlvblR5cGUiOiJhdHRhY2htZW50IiwicmVtb3RlUGF0dGVybnMiOltdLCJ1bm9wdGltaXplZCI6ZmFsc2V9LCJkZXZJbmRpY2F0b3JzIjp7ImFwcElzclN0YXR1cyI6dHJ1ZSwiYnVpbGRBY3Rpdml0eSI6dHJ1ZSwiYnVpbGRBY3Rpdml0eVBvc2l0aW9uIjoiYm90dG9tLXJpZ2h0In0sIm9uRGVtYW5kRW50cmllcyI6eyJtYXhJbmFjdGl2ZUFnZSI6NjAwMDAsInBhZ2VzQnVmZmVyTGVuZ3RoIjo1fSwiYW1wIjp7ImNhbm9uaWNhbEJhc2UiOiIifSwiYmFzZVBhdGgiOiIiLCJzYXNzT3B0aW9ucyI6e30sInRyYWlsaW5nU2xhc2giOmZhbHNlLCJpMThuIjpudWxsLCJwcm9kdWN0aW9uQnJvd3NlclNvdXJjZU1hcHMiOmZhbHNlLCJleGNsdWRlRGVmYXVsdE1vbWVudExvY2FsZXMiOnRydWUsInNlcnZlclJ1bnRpbWVDb25maWciOnt9LCJwdWJsaWNSdW50aW1lQ29uZmlnIjp7fSwicmVhY3RQcm9kdWN0aW9uUHJvZmlsaW5nIjpmYWxzZSwicmVhY3RTdHJpY3RNb2RlIjpudWxsLCJyZWFjdE1heEhlYWRlcnNMZW5ndGgiOjYwMDAsImh0dHBBZ2VudE9wdGlvbnMiOnsia2VlcEFsaXZlIjp0cnVlfSwibG9nZ2luZyI6e30sInN0YXRpY1BhZ2VHZW5lcmF0aW9uVGltZW91dCI6NjAsIm1vZHVsYXJpemVJbXBvcnRzIjp7IkBtdWkvaWNvbnMtbWF0ZXJpYWwiOnsidHJhbnNmb3JtIjoiQG11aS9pY29ucy1tYXRlcmlhbC97e21lbWJlcn19In0sImxvZGFzaCI6eyJ0cmFuc2Zvcm0iOiJsb2Rhc2gve3ttZW1iZXJ9fSJ9fSwib3V0cHV0RmlsZVRyYWNpbmdSb290IjoiL3RtcC9uZXh0LXN0YXRzMTlYVThZL3N0YXRzLWFwcCIsImV4cGVyaW1lbnRhbCI6eyJtdWx0aVpvbmVEcmFmdE1vZGUiOmZhbHNlLCJhcHBOYXZGYWlsSGFuZGxpbmciOmZhbHNlLCJwcmVyZW5kZXJFYXJseUV4aXQiOnRydWUsInNlcnZlck1pbmlmaWNhdGlvbiI6dHJ1ZSwic2VydmVyU291cmNlTWFwcyI6ZmFsc2UsImxpbmtOb1RvdWNoU3RhcnQiOmZhbHNlLCJjYXNlU2Vuc2l0aXZlUm91dGVzIjpmYWxzZSwicHJlbG9hZEVudHJpZXNPblN0YXJ0Ijp0cnVlLCJjbGllbnRSb3V0ZXJGaWx0ZXIiOnRydWUsImNsaWVudFJvdXRlckZpbHRlclJlZGlyZWN0cyI6ZmFsc2UsImZldGNoQ2FjaGVLZXlQcmVmaXgiOiIiLCJtaWRkbGV3YXJlUHJlZmV0Y2giOiJmbGV4aWJsZSIsIm9wdGltaXN0aWNDbGllbnRDYWNoZSI6dHJ1ZSwibWFudWFsQ2xpZW50QmFzZVBhdGgiOmZhbHNlLCJjcHVzIjoxOSwibWVtb3J5QmFzZWRXb3JrZXJzQ291bnQiOmZhbHNlLCJpc3JGbHVzaFRvRGlzayI6dHJ1ZSwid29ya2VyVGhyZWFkcyI6ZmFsc2UsIm9wdGltaXplQ3NzIjpmYWxzZSwibmV4dFNjcmlwdFdvcmtlcnMiOmZhbHNlLCJzY3JvbGxSZXN0b3JhdGlvbiI6ZmFsc2UsImV4dGVybmFsRGlyIjpmYWxzZSwiZGlzYWJsZU9wdGltaXplZExvYWRpbmciOmZhbHNlLCJnemlwU2l6ZSI6dHJ1ZSwiY3JhQ29tcGF0IjpmYWxzZSwiZXNtRXh0ZXJuYWxzIjp0cnVlLCJmdWxseVNwZWNpZmllZCI6ZmFsc2UsInN3Y1RyYWNlUHJvZmlsaW5nIjpmYWxzZSwiZm9yY2VTd2NUcmFuc2Zvcm1zIjpmYWxzZSwibGFyZ2VQYWdlRGF0YUJ5dGVzIjoxMjgwMDAsInR1cmJvIjp7InJvb3QiOiIvdG1wL25leHQtc3RhdHMxOVhVOFkvc3RhdHMtYXBwIn0sInR5cGVkUm91dGVzIjpmYWxzZSwidHlwZWRFbnYiOmZhbHNlLCJwYXJhbGxlbFNlcnZlckNvbXBpbGVzIjpmYWxzZSwicGFyYWxsZWxTZXJ2ZXJCdWlsZFRyYWNlcyI6ZmFsc2UsInBwciI6ZmFsc2UsInBwckZhbGxiYWNrcyI6ZmFsc2UsIndlYnBhY2tNZW1vcnlPcHRpbWl6YXRpb25zIjpmYWxzZSwib3B0aW1pemVTZXJ2ZXJSZWFjdCI6ZmFsc2UsInVzZUVhcmx5SW1wb3J0IjpmYWxzZSwic3RhbGVUaW1lcyI6eyJkeW5hbWljIjowLCJzdGF0aWMiOjMwMH0sImFmdGVyIjpmYWxzZSwic2VydmVyQ29tcG9uZW50c0htckNhY2hlIjp0cnVlLCJzdGF0aWNHZW5lcmF0aW9uTWF4Q29uY3VycmVuY3kiOjgsInN0YXRpY0dlbmVyYXRpb25NaW5QYWdlc1BlcldvcmtlciI6MjUsImR5bmFtaWNJTyI6ZmFsc2UsIm9wdGltaXplUGFja2FnZUltcG9ydHMiOlsibHVjaWRlLXJlYWN0IiwiZGF0ZS1mbnMiLCJsb2Rhc2gtZXMiLCJyYW1kYSIsImFudGQiLCJyZWFjdC1ib290c3RyYXAiLCJhaG9va3MiLCJAYW50LWRlc2lnbi9pY29ucyIsIkBoZWFkbGVzc3VpL3JlYWN0IiwiQGhlYWRsZXNzdWktZmxvYXQvcmVhY3QiLCJAaGVyb2ljb25zL3JlYWN0LzIwL3NvbGlkIiwiQGhlcm9pY29ucy9yZWFjdC8yNC9zb2xpZCIsIkBoZXJvaWNvbnMvcmVhY3QvMjQvb3V0bGluZSIsIkB2aXN4L3Zpc3giLCJAdHJlbW9yL3JlYWN0IiwicnhqcyIsIkBtdWkvbWF0ZXJpYWwiLCJAbXVpL2ljb25zLW1hdGVyaWFsIiwicmVjaGFydHMiLCJyZWFjdC11c2UiLCJlZmZlY3QiLCJAZWZmZWN0L3NjaGVtYSIsIkBlZmZlY3QvcGxhdGZvcm0iLCJAZWZmZWN0L3BsYXRmb3JtLW5vZGUiLCJAZWZmZWN0L3BsYXRmb3JtLWJyb3dzZXIiLCJAZWZmZWN0L3BsYXRmb3JtLWJ1biIsIkBlZmZlY3Qvc3FsIiwiQGVmZmVjdC9zcWwtbXNzcWwiLCJAZWZmZWN0L3NxbC1teXNxbDIiLCJAZWZmZWN0L3NxbC1wZyIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtbm9kZSIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtYnVuIiwiQGVmZmVjdC9zcWwtc3F1bGl0ZS13YXNtIiwiQGVmZmVjdC9zcWwtc3F1bGl0ZS1yZWFjdC1uYXRpdmUiLCJAZWZmZWN0L3JwYyIsIkBlZmZlY3QvcnBjLWh0dHAiLCJAZWZmZWN0L3R5cGVjbGFzcyIsIkBlZmZlY3QvZXhwZXJpbWVudGFsIiwiQGVmZmVjdC9vcGVudGVsZW1ldHJ5IiwiQG1hdGVyaWFsLXVpL2NvcmUiLCJAbWF0ZXJpYWwtdWkvaWNvbnMiLCJAdGFibGVyL2ljb25zLXJlYWN0IiwibXVpLWNvcmUiLCJyZWFjdC1pY29ucy9haSIsInJlYWN0LWljb25zL2JpIiwicmVhY3QtaWNvbnMvYnMiLCJyZWFjdC1pY29ucy9jZyIsInJlYWN0LWljb25zL2NpIiwicmVhY3QtaWNvbnMvZGkiLCJyZWFjdC1pY29ucy9mYSIsInJlYWN0LWljb25zL2ZhNiIsInJlYWN0LWljb25zL2ZjIiwicmVhY3QtaWNvbnMvZmkiLCJyZWFjdC1pY29ucy9naSIsInJlYWN0LWljb25zL2dvIiwicmVhY3QtaWNvbnMvZ3IiLCJyZWFjdC1pY29ucy9oaSIsInJlYWN0LWljb25zL2hpMiIsInJlYWN0LWljb25zL2ltIiwicmVhY3QtaWNvbnMvaW8iLCJyZWFjdC1pY29ucy9pbzUiLCJyZWFjdC1pY29ucy9saWEiLCJyZWFjdC1pY29ucy9saWIiLCJyZWFjdC1pY29ucy9sdSIsInJlYWN0LWljb25zL21kIiwicmVhY3QtaWNvbnMvcGkiLCJyZWFjdC1pY29ucy9yaSIsInJlYWN0LWljb25zL3J4IiwicmVhY3QtaWNvbnMvc2kiLCJyZWFjdC1pY29ucy9zbCIsInJlYWN0LWljb25zL3RiIiwicmVhY3QtaWNvbnMvdGZpIiwicmVhY3QtaWNvbnMvdGkiLCJyZWFjdC1pY29ucy92c2MiLCJyZWFjdC1pY29ucy93aSJdfSwiYnVuZGxlUGFnZXNSb3V0ZXJEZXBlbmRlbmNpZXMiOmZhbHNlLCJjb25maWdGaWxlIjoiL3RtcC9uZXh0LXN0YXRzMTlYVThZL3N0YXRzLWFwcC9uZXh0LmNvbmZpZy5qcyIsImNvbmZpZ0ZpbGVOYW1lIjoibmV4dC5jb25maWcuanMifQ==","pagesType":"app","appDirLoader":"bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBwLWVkZ2Utc3NyJTJGcGFnZSZwYWdlPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZVBhdGg9cHJpdmF0ZS1uZXh0LWFwcC1kaXIlMkZhcHAtZWRnZS1zc3IlMkZwYWdlLmpzJmFwcERpcj0lMkZ0bXAlMkZuZXh0LXN0YXRzMTlYVThZJTJGc3RhdHMtYXBwJTJGYXBwJmFwcFBhdGhzPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JmZseWluZ1NodXR0bGU9ZmFsc2UmcHJlZmVycmVkUmVnaW9uPSZtaWRkbGV3YXJlQ29uZmlnPWUzMCUzRCE=","sriEnabled":false,"middlewareConfig":"e30="}!
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/lib/page-types.js
+      var page_types = __webpack_require__(7743);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/app-render/encryption-utils.js
+      var encryption_utils = __webpack_require__(659);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/esm/server/app-render/action-utils.js
+      var action_utils = __webpack_require__(778); // CONCATENATED MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/dist/build/webpack/loaders/next-edge-ssr-loader/index.js?{"absolute500Path":"","absoluteAppPath":"next/dist/pages/_app","absoluteDocumentPath":"next/dist/pages/_document","absoluteErrorPath":"next/dist/pages/_error","absolutePagePath":"private-next-app-dir/app-edge-ssr/page.js","dev":false,"isServerComponent":true,"page":"/app-edge-ssr/page","stringifiedConfig":"eyJlbnYiOnt9LCJlc2xpbnQiOnsiaWdub3JlRHVyaW5nQnVpbGRzIjpmYWxzZX0sInR5cGVzY3JpcHQiOnsiaWdub3JlQnVpbGRFcnJvcnMiOmZhbHNlLCJ0c2NvbmZpZ1BhdGgiOiJ0c2NvbmZpZy5qc29uIn0sImRpc3REaXIiOiIubmV4dCIsImNsZWFuRGlzdERpciI6dHJ1ZSwiYXNzZXRQcmVmaXgiOiIiLCJjYWNoZU1heE1lbW9yeVNpemUiOjUyNDI4ODAwLCJjb25maWdPcmlnaW4iOiJuZXh0LmNvbmZpZy5qcyIsInVzZUZpbGVTeXN0ZW1QdWJsaWNSb3V0ZXMiOnRydWUsImdlbmVyYXRlRXRhZ3MiOnRydWUsInBhZ2VFeHRlbnNpb25zIjpbInRzeCIsInRzIiwianN4IiwianMiXSwicG93ZXJlZEJ5SGVhZGVyIjp0cnVlLCJjb21wcmVzcyI6dHJ1ZSwiaW1hZ2VzIjp7ImRldmljZVNpemVzIjpbNjQwLDc1MCw4MjgsMTA4MCwxMjAwLDE5MjAsMjA0OCwzODQwXSwiaW1hZ2VTaXplcyI6WzE2LDMyLDQ4LDY0LDk2LDEyOCwyNTYsMzg0XSwicGF0aCI6Ii9fbmV4dC9pbWFnZSIsImxvYWRlciI6ImRlZmF1bHQiLCJsb2FkZXJGaWxlIjoiIiwiZG9tYWlucyI6W10sImRpc2FibGVTdGF0aWNJbWFnZXMiOmZhbHNlLCJtaW5pbXVtQ2FjaGVUVEwiOjYwLCJmb3JtYXRzIjpbImltYWdlL3dlYnAiXSwiZGFuZ2Vyb3VzbHlBbGxvd1NWRyI6ZmFsc2UsImNvbnRlbnRTZWN1cml0eVBvbGljeSI6InNjcmlwdC1zcmMgJ25vbmUnOyBmcmFtZS1zcmMgJ25vbmUnOyBzYW5kYm94OyIsImNvbnRlbnREaXNwb3NpdGlvblR5cGUiOiJhdHRhY2htZW50IiwicmVtb3RlUGF0dGVybnMiOltdLCJ1bm9wdGltaXplZCI6ZmFsc2V9LCJkZXZJbmRpY2F0b3JzIjp7ImFwcElzclN0YXR1cyI6dHJ1ZSwiYnVpbGRBY3Rpdml0eSI6dHJ1ZSwiYnVpbGRBY3Rpdml0eVBvc2l0aW9uIjoiYm90dG9tLXJpZ2h0In0sIm9uRGVtYW5kRW50cmllcyI6eyJtYXhJbmFjdGl2ZUFnZSI6NjAwMDAsInBhZ2VzQnVmZmVyTGVuZ3RoIjo1fSwiYW1wIjp7ImNhbm9uaWNhbEJhc2UiOiIifSwiYmFzZVBhdGgiOiIiLCJzYXNzT3B0aW9ucyI6e30sInRyYWlsaW5nU2xhc2giOmZhbHNlLCJpMThuIjpudWxsLCJwcm9kdWN0aW9uQnJvd3NlclNvdXJjZU1hcHMiOmZhbHNlLCJleGNsdWRlRGVmYXVsdE1vbWVudExvY2FsZXMiOnRydWUsInNlcnZlclJ1bnRpbWVDb25maWciOnt9LCJwdWJsaWNSdW50aW1lQ29uZmlnIjp7fSwicmVhY3RQcm9kdWN0aW9uUHJvZmlsaW5nIjpmYWxzZSwicmVhY3RTdHJpY3RNb2RlIjpudWxsLCJyZWFjdE1heEhlYWRlcnNMZW5ndGgiOjYwMDAsImh0dHBBZ2VudE9wdGlvbnMiOnsia2VlcEFsaXZlIjp0cnVlfSwibG9nZ2luZyI6e30sInN0YXRpY1BhZ2VHZW5lcmF0aW9uVGltZW91dCI6NjAsIm1vZHVsYXJpemVJbXBvcnRzIjp7IkBtdWkvaWNvbnMtbWF0ZXJpYWwiOnsidHJhbnNmb3JtIjoiQG11aS9pY29ucy1tYXRlcmlhbC97e21lbWJlcn19In0sImxvZGFzaCI6eyJ0cmFuc2Zvcm0iOiJsb2Rhc2gve3ttZW1iZXJ9fSJ9fSwib3V0cHV0RmlsZVRyYWNpbmdSb290IjoiL3RtcC9uZXh0LXN0YXRzMTlYVThZL3N0YXRzLWFwcCIsImV4cGVyaW1lbnRhbCI6eyJtdWx0aVpvbmVEcmFmdE1vZGUiOmZhbHNlLCJhcHBOYXZGYWlsSGFuZGxpbmciOmZhbHNlLCJwcmVyZW5kZXJFYXJseUV4aXQiOnRydWUsInNlcnZlck1pbmlmaWNhdGlvbiI6dHJ1ZSwic2VydmVyU291cmNlTWFwcyI6ZmFsc2UsImxpbmtOb1RvdWNoU3RhcnQiOmZhbHNlLCJjYXNlU2Vuc2l0aXZlUm91dGVzIjpmYWxzZSwicHJlbG9hZEVudHJpZXNPblN0YXJ0Ijp0cnVlLCJjbGllbnRSb3V0ZXJGaWx0ZXIiOnRydWUsImNsaWVudFJvdXRlckZpbHRlclJlZGlyZWN0cyI6ZmFsc2UsImZldGNoQ2FjaGVLZXlQcmVmaXgiOiIiLCJtaWRkbGV3YXJlUHJlZmV0Y2giOiJmbGV4aWJsZSIsIm9wdGltaXN0aWNDbGllbnRDYWNoZSI6dHJ1ZSwibWFudWFsQ2xpZW50QmFzZVBhdGgiOmZhbHNlLCJjcHVzIjoxOSwibWVtb3J5QmFzZWRXb3JrZXJzQ291bnQiOmZhbHNlLCJpc3JGbHVzaFRvRGlzayI6dHJ1ZSwid29ya2VyVGhyZWFkcyI6ZmFsc2UsIm9wdGltaXplQ3NzIjpmYWxzZSwibmV4dFNjcmlwdFdvcmtlcnMiOmZhbHNlLCJzY3JvbGxSZXN0b3JhdGlvbiI6ZmFsc2UsImV4dGVybmFsRGlyIjpmYWxzZSwiZGlzYWJsZU9wdGltaXplZExvYWRpbmciOmZhbHNlLCJnemlwU2l6ZSI6dHJ1ZSwiY3JhQ29tcGF0IjpmYWxzZSwiZXNtRXh0ZXJuYWxzIjp0cnVlLCJmdWxseVNwZWNpZmllZCI6ZmFsc2UsInN3Y1RyYWNlUHJvZmlsaW5nIjpmYWxzZSwiZm9yY2VTd2NUcmFuc2Zvcm1zIjpmYWxzZSwibGFyZ2VQYWdlRGF0YUJ5dGVzIjoxMjgwMDAsInR1cmJvIjp7InJvb3QiOiIvdG1wL25leHQtc3RhdHMxOVhVOFkvc3RhdHMtYXBwIn0sInR5cGVkUm91dGVzIjpmYWxzZSwidHlwZWRFbnYiOmZhbHNlLCJwYXJhbGxlbFNlcnZlckNvbXBpbGVzIjpmYWxzZSwicGFyYWxsZWxTZXJ2ZXJCdWlsZFRyYWNlcyI6ZmFsc2UsInBwciI6ZmFsc2UsInBwckZhbGxiYWNrcyI6ZmFsc2UsIndlYnBhY2tNZW1vcnlPcHRpbWl6YXRpb25zIjpmYWxzZSwib3B0aW1pemVTZXJ2ZXJSZWFjdCI6ZmFsc2UsInVzZUVhcmx5SW1wb3J0IjpmYWxzZSwic3RhbGVUaW1lcyI6eyJkeW5hbWljIjowLCJzdGF0aWMiOjMwMH0sImFmdGVyIjpmYWxzZSwic2VydmVyQ29tcG9uZW50c0htckNhY2hlIjp0cnVlLCJzdGF0aWNHZW5lcmF0aW9uTWF4Q29uY3VycmVuY3kiOjgsInN0YXRpY0dlbmVyYXRpb25NaW5QYWdlc1BlcldvcmtlciI6MjUsImR5bmFtaWNJTyI6ZmFsc2UsIm9wdGltaXplUGFja2FnZUltcG9ydHMiOlsibHVjaWRlLXJlYWN0IiwiZGF0ZS1mbnMiLCJsb2Rhc2gtZXMiLCJyYW1kYSIsImFudGQiLCJyZWFjdC1ib290c3RyYXAiLCJhaG9va3MiLCJAYW50LWRlc2lnbi9pY29ucyIsIkBoZWFkbGVzc3VpL3JlYWN0IiwiQGhlYWRsZXNzdWktZmxvYXQvcmVhY3QiLCJAaGVyb2ljb25zL3JlYWN0LzIwL3NvbGlkIiwiQGhlcm9pY29ucy9yZWFjdC8yNC9zb2xpZCIsIkBoZXJvaWNvbnMvcmVhY3QvMjQvb3V0bGluZSIsIkB2aXN4L3Zpc3giLCJAdHJlbW9yL3JlYWN0IiwicnhqcyIsIkBtdWkvbWF0ZXJpYWwiLCJAbXVpL2ljb25zLW1hdGVyaWFsIiwicmVjaGFydHMiLCJyZWFjdC11c2UiLCJlZmZlY3QiLCJAZWZmZWN0L3NjaGVtYSIsIkBlZmZlY3QvcGxhdGZvcm0iLCJAZWZmZWN0L3BsYXRmb3JtLW5vZGUiLCJAZWZmZWN0L3BsYXRmb3JtLWJyb3dzZXIiLCJAZWZmZWN0L3BsYXRmb3JtLWJ1biIsIkBlZmZlY3Qvc3FsIiwiQGVmZmVjdC9zcWwtbXNzcWwiLCJAZWZmZWN0L3NxbC1teXNxbDIiLCJAZWZmZWN0L3NxbC1wZyIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtbm9kZSIsIkBlZmZlY3Qvc3FsLXNxdWxpdGUtYnVuIiwiQGVmZmVjdC9zcWwtc3F1bGl0ZS13YXNtIiwiQGVmZmVjdC9zcWwtc3F1bGl0ZS1yZWFjdC1uYXRpdmUiLCJAZWZmZWN0L3JwYyIsIkBlZmZlY3QvcnBjLWh0dHAiLCJAZWZmZWN0L3R5cGVjbGFzcyIsIkBlZmZlY3QvZXhwZXJpbWVudGFsIiwiQGVmZmVjdC9vcGVudGVsZW1ldHJ5IiwiQG1hdGVyaWFsLXVpL2NvcmUiLCJAbWF0ZXJpYWwtdWkvaWNvbnMiLCJAdGFibGVyL2ljb25zLXJlYWN0IiwibXVpLWNvcmUiLCJyZWFjdC1pY29ucy9haSIsInJlYWN0LWljb25zL2JpIiwicmVhY3QtaWNvbnMvYnMiLCJyZWFjdC1pY29ucy9jZyIsInJlYWN0LWljb25zL2NpIiwicmVhY3QtaWNvbnMvZGkiLCJyZWFjdC1pY29ucy9mYSIsInJlYWN0LWljb25zL2ZhNiIsInJlYWN0LWljb25zL2ZjIiwicmVhY3QtaWNvbnMvZmkiLCJyZWFjdC1pY29ucy9naSIsInJlYWN0LWljb25zL2dvIiwicmVhY3QtaWNvbnMvZ3IiLCJyZWFjdC1pY29ucy9oaSIsInJlYWN0LWljb25zL2hpMiIsInJlYWN0LWljb25zL2ltIiwicmVhY3QtaWNvbnMvaW8iLCJyZWFjdC1pY29ucy9pbzUiLCJyZWFjdC1pY29ucy9saWEiLCJyZWFjdC1pY29ucy9saWIiLCJyZWFjdC1pY29ucy9sdSIsInJlYWN0LWljb25zL21kIiwicmVhY3QtaWNvbnMvcGkiLCJyZWFjdC1pY29ucy9yaSIsInJlYWN0LWljb25zL3J4IiwicmVhY3QtaWNvbnMvc2kiLCJyZWFjdC1pY29ucy9zbCIsInJlYWN0LWljb25zL3RiIiwicmVhY3QtaWNvbnMvdGZpIiwicmVhY3QtaWNvbnMvdGkiLCJyZWFjdC1pY29ucy92c2MiLCJyZWFjdC1pY29ucy93aSJdfSwiYnVuZGxlUGFnZXNSb3V0ZXJEZXBlbmRlbmNpZXMiOmZhbHNlLCJjb25maWdGaWxlIjoiL3RtcC9uZXh0LXN0YXRzMTlYVThZL3N0YXRzLWFwcC9uZXh0LmNvbmZpZy5qcyIsImNvbmZpZ0ZpbGVOYW1lIjoibmV4dC5jb25maWcuanMifQ==","pagesType":"app","appDirLoader":"bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGYXBwLWVkZ2Utc3NyJTJGcGFnZSZwYWdlPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZVBhdGg9cHJpdmF0ZS1uZXh0LWFwcC1kaXIlMkZhcHAtZWRnZS1zc3IlMkZwYWdlLmpzJmFwcERpcj0lMkZ0bXAlMkZuZXh0LXN0YXRzMTlYVThZJTJGc3RhdHMtYXBwJTJGYXBwJmFwcFBhdGhzPSUyRmFwcC1lZGdlLXNzciUyRnBhZ2UmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JmZseWluZ1NodXR0bGU9ZmFsc2UmcHJlZmVycmVkUmVnaW9uPSZtaWRkbGV3YXJlQ29uZmlnPWUzMCUzRCE=","sriEnabled":false,"middlewareConfig":"e30="}!
       var _self___RSC_MANIFEST;
 
       const incrementalCacheHandler = null;
@@ -432,50 +432,50 @@
       /***/
     },
 
-    /***/ 8706: /***/ (
+    /***/ 527: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 8585)
+        __webpack_require__.bind(__webpack_require__, 753)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 9467)
+        __webpack_require__.bind(__webpack_require__, 6866)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 1744)
+        __webpack_require__.bind(__webpack_require__, 7099)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 9329)
+        __webpack_require__.bind(__webpack_require__, 2064)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 7969)
+        __webpack_require__.bind(__webpack_require__, 7531)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 4252)
+        __webpack_require__.bind(__webpack_require__, 8704)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 5685)
+        __webpack_require__.bind(__webpack_require__, 1335)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 853)
+        __webpack_require__.bind(__webpack_require__, 2618)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 1843)
+        __webpack_require__.bind(__webpack_require__, 7794)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 8149)
+        __webpack_require__.bind(__webpack_require__, 7094)
       );
 
       /***/
     },
 
-    /***/ 5315: /***/ () => {
+    /***/ 9641: /***/ () => {
       /***/
     },
 
-    /***/ 3073: /***/ (
+    /***/ 2934: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -495,7 +495,7 @@
       /***/
     },
 
-    /***/ 6908: /***/ (
+    /***/ 176: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -507,7 +507,7 @@
         /* harmony export */
       });
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
-        __webpack_require__(7669);
+        __webpack_require__(2843);
 
       function RootLayout({ children }) {
         return /*#__PURE__*/ (0,
@@ -526,7 +526,7 @@
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
-    /******/ __webpack_require__.O(0, [319, 704], () => __webpack_exec__(8611));
+    /******/ __webpack_require__.O(0, [819, 397], () => __webpack_exec__(3857));
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ (_ENTRIES = typeof _ENTRIES === "undefined" ? {} : _ENTRIES)[
       "middleware_app/app-edge-ssr/page"
Diff for middleware.js

Diff too large to display

Diff for edge-ssr.js

Diff too large to display

Diff for image-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [8358],
   {
-    /***/ 8908: /***/ (
+    /***/ 8176: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -9,7 +9,7 @@
       (window.__NEXT_P = window.__NEXT_P || []).push([
         "/image",
         function () {
-          return __webpack_require__(2111);
+          return __webpack_require__(934);
         },
       ]);
       if (false) {
@@ -18,7 +18,7 @@
       /***/
     },
 
-    /***/ 6308: /***/ (module, exports, __webpack_require__) => {
+    /***/ 5057: /***/ (module, exports, __webpack_require__) => {
       "use strict";
       /* __next_internal_client_entry_do_not_use__  cjs */
       Object.defineProperty(exports, "__esModule", {
@@ -40,17 +40,17 @@
         __webpack_require__(1955)
       );
       const _head = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(2383)
+        __webpack_require__(7163)
       );
-      const _getimgprops = __webpack_require__(5640);
-      const _imageconfig = __webpack_require__(2758);
-      const _imageconfigcontextsharedruntime = __webpack_require__(899);
-      const _warnonce = __webpack_require__(3878);
-      const _routercontextsharedruntime = __webpack_require__(869);
+      const _getimgprops = __webpack_require__(5447);
+      const _imageconfig = __webpack_require__(1650);
+      const _imageconfigcontextsharedruntime = __webpack_require__(1953);
+      const _warnonce = __webpack_require__(5054);
+      const _routercontextsharedruntime = __webpack_require__(4445);
       const _imageloader = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(6501)
+        __webpack_require__(7406)
       );
-      const _usemergedref = __webpack_require__(3994);
+      const _usemergedref = __webpack_require__(3303);
       // This is replaced by webpack define plugin
       const configEnv = {
         deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
@@ -371,7 +371,7 @@
       /***/
     },
 
-    /***/ 3994: /***/ (module, exports, __webpack_require__) => {
+    /***/ 3303: /***/ (module, exports, __webpack_require__) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -440,7 +440,7 @@
       /***/
     },
 
-    /***/ 5640: /***/ (
+    /***/ 5447: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -456,9 +456,9 @@
           return getImgProps;
         },
       });
-      const _warnonce = __webpack_require__(3878);
-      const _imageblursvg = __webpack_require__(4317);
-      const _imageconfig = __webpack_require__(2758);
+      const _warnonce = __webpack_require__(5054);
+      const _imageblursvg = __webpack_require__(1731);
+      const _imageconfig = __webpack_require__(1650);
       const VALID_LOADING_VALUES =
         /* unused pure expression or super */ null && [
           "lazy",
@@ -830,7 +830,7 @@
       /***/
     },
 
-    /***/ 4317: /***/ (__unused_webpack_module, exports) => {
+    /***/ 1731: /***/ (__unused_webpack_module, exports) => {
       "use strict";
       /**
        * A shared function, used on both client and server, to generate a SVG blur placeholder.
@@ -885,7 +885,7 @@
       /***/
     },
 
-    /***/ 8580: /***/ (
+    /***/ 9833: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -912,10 +912,10 @@
         },
       });
       const _interop_require_default = __webpack_require__(9608);
-      const _getimgprops = __webpack_require__(5640);
-      const _imagecomponent = __webpack_require__(6308);
+      const _getimgprops = __webpack_require__(5447);
+      const _imagecomponent = __webpack_require__(5057);
       const _imageloader = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(6501)
+        __webpack_require__(7406)
       );
       function getImageProps(imgProps) {
         const { props } = (0, _getimgprops.getImgProps)(imgProps, {
@@ -947,7 +947,7 @@
       /***/
     },
 
-    /***/ 6501: /***/ (__unused_webpack_module, exports) => {
+    /***/ 7406: /***/ (__unused_webpack_module, exports) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -982,7 +982,7 @@
       /***/
     },
 
-    /***/ 2111: /***/ (
+    /***/ 934: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -999,8 +999,8 @@
 
       // EXTERNAL MODULE: ./node_modules/.pnpm/react@19.0.0-rc-7771d3a7-20240827/node_modules/react/jsx-runtime.js
       var jsx_runtime = __webpack_require__(5815);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_h4bgdqagqtli4q7bnw2ajnn4vm/node_modules/next/image.js
-      var next_image = __webpack_require__(1878);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.0.0-rc-7771d3a7-20240827_re_qz7eh3ruj3cscolfxbcb265hza/node_modules/next/image.js
+      var next_image = __webpack_require__(7649);
       var image_default = /*#__PURE__*/ __webpack_require__.n(next_image); // CONCATENATED MODULE: ./pages/nextjs.png
       /* harmony default export */ const nextjs = {
         src: "/_next/static/media/nextjs.cae0b805.png",
@@ -1030,12 +1030,12 @@
       /***/
     },
 
-    /***/ 1878: /***/ (
+    /***/ 7649: /***/ (
       module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      module.exports = __webpack_require__(8580);
+      module.exports = __webpack_require__(9833);
 
       /***/
     },
@@ -1045,7 +1045,7 @@
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [2888, 9774, 179], () =>
-      __webpack_exec__(8908)
+      __webpack_exec__(8176)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for 5867-HASH.js

Diff too large to display

Commit: e6d1fba

@arlyon arlyon force-pushed the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch from ef64926 to 4131c78 Compare August 29, 2024 14:59
@arlyon arlyon force-pushed the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch from 4131c78 to 44c1845 Compare August 29, 2024 15:38
@arlyon arlyon force-pushed the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch from 44c1845 to c554900 Compare August 29, 2024 16:59
Copy link
Member

timneutkens commented Sep 5, 2024

Merge activity

  • Sep 5, 4:31 PM EDT: @timneutkens started a stack merge that includes this pull request via Graphite.
  • Sep 5, 4:34 PM EDT: Graphite rebased this pull request as part of a merge.
  • Sep 5, 4:40 PM EDT: Graphite couldn't merge this PR because it was not satisfying all requirements (Failed CI: 'thank you, next', 'build / build', 'build-native / build', 'stable - x86_64-unknown-linux-gnu - node@16', 'test unit (18) / build', 'test unit (20) / build', 'test cargo unit / build', 'test cargo benches / Test', 'rust check / build', 'rustdoc check / build', 'test next-swc wasm / build').

@timneutkens timneutkens changed the base branch from arlyon/font-code-refactor to graphite-base/69144 September 5, 2024 20:32
@timneutkens timneutkens changed the base branch from graphite-base/69144 to canary September 5, 2024 20:32
@timneutkens timneutkens force-pushed the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch from c554900 to 3d8b882 Compare September 5, 2024 20:33
arlyon and others added 2 commits September 10, 2024 13:02
- Move the truncation/hashing logic into `turbo-tasks-fs`. This still
  requires manually calling it after constructing a `FileSystemPath` (we
  can't do this automatically because we only want to do it on output
  paths), but at least it's in a central place for the other callsites
  that may need to use this.

- Instead of depending on `MAX_FILE_NAME_LENGTH_UNIX`, which is
  platform-specific, declare a platform-agnostic
  `MAX_SAFE_FILE_NAME_LENGTH` constant.

- Preserve as much of the original filename as possible, and only use
  the hash as a suffix. This should aid in debugging.

- Use a 128-bit hash. That's UUID-length, which should pretty strongly
  guarantee that there are no collisions (and xxh3 promises strong
  non-cryptographic collision avoidance). While it's unlikely, it's
  plausible that we could have collisions of a 64-bit hash, which could
  cause very broken behavior.

- Measure the extension length, and just bail out if it's too long (this
  shouldn't happen?).
@bgw bgw force-pushed the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch from 3d8b882 to e6d1fba Compare September 10, 2024 23:10
@bgw
Copy link
Member

bgw commented Sep 10, 2024

I've made some pretty significant changes in a second commit that I've added to this PR, so I'm re-requesting review:

  • Move the truncation/hashing logic into turbo-tasks-fs. This still requires manually calling it after constructing a FileSystemPath (we can't do this automatically because we only want to do it on output paths), but at least it's in a central place for the other callsites that may need to use this.

  • Instead of depending on MAX_FILE_NAME_LENGTH_UNIX, which is platform-specific, declare a platform-agnostic MAX_SAFE_FILE_NAME_LENGTH constant.

  • Preserve as much of the original filename as possible, and only use the hash as a suffix. This should aid in debugging.

  • Use a 128-bit hash. That's UUID-length, which should pretty strongly guarantee that there are no collisions (and xxh3 promises strong non-cryptographic collision avoidance). While it's unlikely, it's plausible that we could have collisions of a 64-bit hash, which could cause very broken behavior.

  • Measure the extension length, and just bail out if it's too long (this shouldn't happen?).

@bgw bgw requested a review from mischnic September 10, 2024 23:13
@bgw bgw changed the title hash the font file name if it exceeds our max file size feat(turbopack): hash the font file name if it exceeds our max file size Sep 10, 2024
@bgw bgw merged commit ee48ef7 into canary Sep 11, 2024
111 checks passed
@bgw bgw deleted the arlyon/pack-3012-file-name-too-long-os-error-63-since-142 branch September 11, 2024 21:01
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
created-by: Turbopack team PRs by the Turbopack team. Font (next/font) Related to Next.js Font Optimization. locked Turbopack Related to Turbopack with Next.js.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants