reroute-js 1.0.0-alpha.33 → 1.0.0-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/cli/bin.d.ts +1 -1
- package/cli/bin.js +202 -94
- package/cli/bin.js.map +12 -11
- package/cli/index.d.ts +1 -1
- package/cli/index.js +15 -7
- package/cli/index.js.map +7 -7
- package/cli/src/cli.d.ts +1 -1
- package/cli/src/commands/analyze.d.ts +1 -1
- package/cli/src/commands/build.d.ts +1 -1
- package/cli/src/commands/dev.d.ts +1 -1
- package/cli/src/commands/gen.d.ts +1 -1
- package/cli/src/commands/gen.d.ts.map +1 -1
- package/cli/src/commands/index.d.ts +1 -1
- package/cli/src/commands/init.d.ts +1 -1
- package/cli/src/commands/lib/assets.d.ts +1 -1
- package/cli/src/commands/lib/bundler.d.ts +8 -1
- package/cli/src/commands/lib/bundler.d.ts.map +1 -1
- package/cli/src/commands/lib/command.d.ts +1 -1
- package/cli/src/commands/lib/env.d.ts +1 -1
- package/cli/src/commands/lib/images.d.ts +1 -1
- package/cli/src/commands/lib/index.d.ts +1 -1
- package/cli/src/commands/lib/log.d.ts +1 -1
- package/cli/src/commands/lib/markdown/availability.d.ts +1 -1
- package/cli/src/commands/lib/markdown/index.d.ts +1 -1
- package/cli/src/commands/lib/markdown/processor.d.ts +1 -1
- package/cli/src/commands/lib/prerender.d.ts +1 -1
- package/cli/src/commands/lib/production.d.ts +1 -1
- package/cli/src/commands/lib/routes.d.ts +40 -0
- package/cli/src/commands/lib/routes.d.ts.map +1 -0
- package/cli/src/commands/lib/server.d.ts +1 -1
- package/cli/src/commands/lib/static.d.ts +1 -1
- package/cli/src/commands/lib/streaming/analyzer.d.ts +1 -1
- package/cli/src/commands/lib/streaming/suspense.d.ts +1 -1
- package/cli/src/commands/lib/supervise.d.ts +1 -1
- package/cli/src/commands/lib/terminal-ui.d.ts +1 -1
- package/cli/src/commands/lib/theme.d.ts +1 -1
- package/cli/src/commands/lib/version.d.ts +1 -1
- package/cli/src/commands/lib/watch.d.ts +1 -1
- package/cli/src/commands/og.d.ts +1 -1
- package/cli/src/commands/start.d.ts +1 -1
- package/cli/src/commands/static-render.d.ts +1 -1
- package/cli/src/index.d.ts +1 -1
- package/core/index.d.ts +1 -1
- package/core/index.js +55 -15
- package/core/index.js.map +8 -8
- package/core/src/app-paths.d.ts +1 -1
- package/core/src/bundler/hash.d.ts +1 -1
- package/core/src/bundler/index.d.ts +1 -1
- package/core/src/config.d.ts +1 -1
- package/core/src/content/discovery.d.ts +1 -1
- package/core/src/content/index.d.ts +1 -1
- package/core/src/content/metadata.d.ts +1 -1
- package/core/src/i18n/catalog.d.ts +1 -1
- package/core/src/i18n/discover.d.ts +1 -1
- package/core/src/i18n/index.d.ts +1 -1
- package/core/src/i18n/messages.d.ts +1 -1
- package/core/src/i18n/negotiate.d.ts +1 -1
- package/core/src/i18n/pathname.d.ts +1 -1
- package/core/src/i18n/resolve.d.ts +1 -1
- package/core/src/i18n/types.d.ts +1 -1
- package/core/src/image.d.ts +1 -1
- package/core/src/index.d.ts +1 -1
- package/core/src/llms/discovery.d.ts +1 -1
- package/core/src/llms/extractor.d.ts +1 -1
- package/core/src/llms/formatter.d.ts +1 -1
- package/core/src/llms/full-generator.d.ts +1 -1
- package/core/src/llms/index-generator.d.ts +1 -1
- package/core/src/llms/index.d.ts +1 -1
- package/core/src/og/discovery.d.ts +1 -1
- package/core/src/og/index.d.ts +1 -1
- package/core/src/og/meta.d.ts +1 -1
- package/core/src/og/render.d.ts +1 -1
- package/core/src/og/types.d.ts +1 -1
- package/core/src/robots/discovery.d.ts +1 -1
- package/core/src/robots/generator.d.ts +1 -1
- package/core/src/robots/index.d.ts +1 -1
- package/core/src/robots/policies.d.ts +1 -1
- package/core/src/rss/discovery.d.ts +1 -1
- package/core/src/rss/generator.d.ts +1 -1
- package/core/src/rss/index.d.ts +1 -1
- package/core/src/sitemap/discovery.d.ts +1 -1
- package/core/src/sitemap/generator.d.ts +1 -1
- package/core/src/sitemap/index.d.ts +1 -1
- package/core/src/ssr/index.d.ts +1 -1
- package/core/src/ssr/lib/cache.d.ts +1 -1
- package/core/src/ssr/lib/cleanup.d.ts +1 -1
- package/core/src/ssr/lib/collections.d.ts +1 -1
- package/core/src/ssr/lib/compression.d.ts +1 -1
- package/core/src/ssr/lib/compute/content.d.ts +1 -1
- package/core/src/ssr/lib/compute/index.d.ts +1 -1
- package/core/src/ssr/lib/compute/layouts.d.ts +1 -1
- package/core/src/ssr/lib/compute/layouts.d.ts.map +1 -1
- package/core/src/ssr/lib/compute/routes.d.ts +1 -1
- package/core/src/ssr/lib/content-path.d.ts +1 -1
- package/core/src/ssr/lib/data.d.ts +1 -1
- package/core/src/ssr/lib/html.d.ts +1 -1
- package/core/src/ssr/lib/imports.d.ts +1 -1
- package/core/src/ssr/lib/index.d.ts +1 -1
- package/core/src/ssr/lib/layouts.d.ts +10 -2
- package/core/src/ssr/lib/layouts.d.ts.map +1 -1
- package/core/src/ssr/lib/metadata.d.ts +1 -1
- package/core/src/ssr/lib/mime.d.ts +1 -1
- package/core/src/ssr/lib/modules.d.ts +1 -1
- package/core/src/ssr/lib/path.d.ts +1 -1
- package/core/src/ssr/lib/preload.d.ts +16 -3
- package/core/src/ssr/lib/preload.d.ts.map +1 -1
- package/core/src/ssr/lib/route-match.d.ts +1 -1
- package/core/src/ssr/lib/scripts/collections.d.ts +1 -1
- package/core/src/ssr/lib/scripts/data.d.ts +1 -1
- package/core/src/ssr/lib/scripts/escape.d.ts +1 -1
- package/core/src/ssr/lib/scripts/feeds.d.ts +1 -1
- package/core/src/ssr/lib/scripts/index.d.ts +1 -1
- package/core/src/ssr/lib/seed.d.ts +1 -1
- package/core/src/ssr/lib/serialize.d.ts +1 -1
- package/core/src/ssr/lib/setup.d.ts +1 -1
- package/core/src/ssr/lib/setup.d.ts.map +1 -1
- package/core/src/ssr/lib/styles.d.ts +1 -1
- package/core/src/ssr/lib/template.d.ts +1 -1
- package/core/src/ssr/lib/types.d.ts +1 -1
- package/core/src/ssr/render.d.ts +1 -1
- package/core/src/ssr/stream.d.ts +1 -1
- package/elysia/index.d.ts +1 -1
- package/elysia/index.js +55 -15
- package/elysia/index.js.map +8 -8
- package/elysia/src/index.d.ts +1 -1
- package/elysia/src/libs/assets.d.ts +1 -1
- package/elysia/src/libs/cache.d.ts +1 -1
- package/elysia/src/libs/caching.d.ts +1 -1
- package/elysia/src/libs/devReload.d.ts +1 -1
- package/elysia/src/libs/http.d.ts +1 -1
- package/elysia/src/libs/i18n.d.ts +1 -1
- package/elysia/src/libs/image.d.ts +1 -1
- package/elysia/src/libs/index.d.ts +1 -1
- package/elysia/src/libs/llms.d.ts +1 -1
- package/elysia/src/libs/response.d.ts +1 -1
- package/elysia/src/libs/serving.d.ts +1 -1
- package/elysia/src/plugin.d.ts +1 -1
- package/elysia/src/routes/artifacts.d.ts +1 -1
- package/elysia/src/routes/content.d.ts +1 -1
- package/elysia/src/routes/image.d.ts +1 -1
- package/elysia/src/routes/index.d.ts +1 -1
- package/elysia/src/routes/internal.d.ts +1 -1
- package/elysia/src/routes/liveReloadClient.d.ts +1 -1
- package/elysia/src/routes/llms.d.ts +1 -1
- package/elysia/src/routes/og.d.ts +1 -1
- package/elysia/src/routes/redirects.d.ts +1 -1
- package/elysia/src/routes/robots.d.ts +1 -1
- package/elysia/src/routes/rss.d.ts +1 -1
- package/elysia/src/routes/search.d.ts +1 -1
- package/elysia/src/routes/sitemap.d.ts +1 -1
- package/elysia/src/routes/ssr.d.ts +1 -1
- package/elysia/src/routes/static.d.ts +1 -1
- package/elysia/src/routes/themeCssRefresh.d.ts +1 -1
- package/elysia/src/types.d.ts +1 -1
- package/package.json +1 -1
- package/react/index.d.ts +1 -1
- package/react/index.js +12 -4
- package/react/index.js.map +4 -4
- package/react/src/components/ClientOnly.d.ts +1 -1
- package/react/src/components/ContentRoute.d.ts +1 -1
- package/react/src/components/Image.d.ts +1 -1
- package/react/src/components/LazyRoute.d.ts +1 -1
- package/react/src/components/Link.d.ts +1 -1
- package/react/src/components/Markdown.d.ts +1 -1
- package/react/src/components/Outlet.d.ts +1 -1
- package/react/src/components/index.d.ts +1 -1
- package/react/src/hooks/index.d.ts +1 -1
- package/react/src/hooks/useContent.d.ts +1 -1
- package/react/src/hooks/useData.d.ts +1 -1
- package/react/src/hooks/useFeed.d.ts +1 -1
- package/react/src/hooks/useLayoutData.d.ts +1 -1
- package/react/src/hooks/useLlms.d.ts +1 -1
- package/react/src/hooks/useNavigate.d.ts +1 -1
- package/react/src/hooks/useParams.d.ts +1 -1
- package/react/src/hooks/useRouter.d.ts +1 -1
- package/react/src/hooks/useSearch.d.ts +1 -1
- package/react/src/hooks/useSearchParams.d.ts +1 -1
- package/react/src/hooks/useToc.d.ts +1 -1
- package/react/src/i18n/LocaleProvider.d.ts +1 -1
- package/react/src/i18n/helpers.d.ts +1 -1
- package/react/src/i18n/index.d.ts +1 -1
- package/react/src/index.d.ts +1 -1
- package/react/src/lib/bundle.d.ts +1 -1
- package/react/src/lib/collection.d.ts +1 -1
- package/react/src/lib/content.d.ts +1 -1
- package/react/src/lib/head.d.ts +1 -1
- package/react/src/lib/index.d.ts +2 -1
- package/react/src/lib/index.d.ts.map +1 -1
- package/react/src/lib/layouts.d.ts +11 -1
- package/react/src/lib/layouts.d.ts.map +1 -1
- package/react/src/lib/lazy-route.d.ts +1 -1
- package/react/src/lib/route-loader.d.ts +1 -1
- package/react/src/lib/static-data.d.ts +1 -1
- package/react/src/providers/ContentProvider.d.ts +1 -1
- package/react/src/providers/RerouteProvider.d.ts +1 -1
- package/react/src/providers/RouterProvider.d.ts +1 -1
- package/react/src/providers/index.d.ts +1 -1
- package/react/src/types/any.d.ts +1 -1
- package/react/src/types/index.d.ts +1 -1
- package/react/src/types/router.d.ts +1 -1
- package/telemetry/react.d.ts +1 -1
- package/telemetry/react.js +2 -2
- package/telemetry/react.js.map +1 -1
- package/telemetry/server.d.ts +1 -1
- package/telemetry/server.js +13 -5
- package/telemetry/server.js.map +7 -7
- package/telemetry/src/react/api.d.ts +1 -1
- package/telemetry/src/react/context.d.ts +1 -1
- package/telemetry/src/react/index.d.ts +1 -1
- package/telemetry/src/react/telemetry.d.ts +1 -1
- package/telemetry/src/server/context.d.ts +1 -1
- package/telemetry/src/server/headers/extractor.d.ts +1 -1
- package/telemetry/src/server/headers/index.d.ts +1 -1
- package/telemetry/src/server/headers/presets.d.ts +1 -1
- package/telemetry/src/server/index.d.ts +1 -1
- package/telemetry/src/server/instrumentation.d.ts +1 -1
- package/telemetry/src/server/plugin.d.ts +1 -1
- package/telemetry/src/server/sourcemap.d.ts +1 -1
package/README.md
CHANGED
|
@@ -130,6 +130,7 @@ Reroute is a feature-rich file-based routing framework for building fullstack Re
|
|
|
130
130
|
- `<Link>` - Client-side navigation with automatic prefetching (localizes content hrefs)
|
|
131
131
|
- `<Image>` - Optimized images with automatic format negotiation and lazy loading
|
|
132
132
|
- `<Outlet>` - Render nested route components
|
|
133
|
+
- Route groups - `routes/(app)/[layout].tsx` wraps the routes in `(app)/` with one layout, no URL segment
|
|
133
134
|
- `<ContentRoute>` - Dynamic content rendering with metadata injection
|
|
134
135
|
- `<ClientOnly>` - Client-side only rendering with optional layout preservation (className/style props)
|
|
135
136
|
- 🎭 **Providers**:
|
package/cli/bin.d.ts
CHANGED
package/cli/bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
3
|
/**
|
|
4
|
-
* reroute-js v1.0.0-alpha.
|
|
4
|
+
* reroute-js v1.0.0-alpha.35
|
|
5
5
|
*
|
|
6
6
|
* @license MIT
|
|
7
7
|
* @copyright 2026 stewones <hi@stewan.io>
|
|
@@ -68,7 +68,7 @@ async function getVersionString() {
|
|
|
68
68
|
}
|
|
69
69
|
async function getVersion() {
|
|
70
70
|
if (true) {
|
|
71
|
-
return "1.0.0-alpha.
|
|
71
|
+
return "1.0.0-alpha.35";
|
|
72
72
|
}
|
|
73
73
|
const possiblePaths = [
|
|
74
74
|
path.join(import.meta.dir, "../../../../package.json"),
|
|
@@ -86,7 +86,7 @@ async function getVersion() {
|
|
|
86
86
|
}
|
|
87
87
|
async function getCommit() {
|
|
88
88
|
if (true) {
|
|
89
|
-
return "
|
|
89
|
+
return "bb512b2";
|
|
90
90
|
}
|
|
91
91
|
return "dev";
|
|
92
92
|
}
|
|
@@ -1908,10 +1908,17 @@ function layoutCovers(pattern, pathname) {
|
|
|
1908
1908
|
return true;
|
|
1909
1909
|
return pathname === base || pathname.startsWith(`${base}/`);
|
|
1910
1910
|
}
|
|
1911
|
-
function
|
|
1911
|
+
function layoutWraps(layout, pathname, routePattern) {
|
|
1912
|
+
if (Array.isArray(layout?.routes)) {
|
|
1913
|
+
return routePattern !== undefined && layout.routes.includes(routePattern);
|
|
1914
|
+
}
|
|
1915
|
+
return layoutCovers(String(layout?.pattern || "/"), pathname);
|
|
1916
|
+
}
|
|
1917
|
+
function getMatchingLayouts(pathname, layouts, routes) {
|
|
1912
1918
|
if (!Array.isArray(layouts))
|
|
1913
1919
|
return [];
|
|
1914
|
-
|
|
1920
|
+
const routePattern = Array.isArray(routes) ? matchRoutes(routes, pathname)?.route.pattern : undefined;
|
|
1921
|
+
return layouts.filter((layout) => layoutWraps(layout, pathname, routePattern)).sort((a, b) => {
|
|
1915
1922
|
const aDepth = getPatternDepth(a?.pattern);
|
|
1916
1923
|
const bDepth = getPatternDepth(b?.pattern);
|
|
1917
1924
|
return aDepth - bDepth;
|
|
@@ -1926,6 +1933,7 @@ function createLayoutCacheKey(pattern, pathname) {
|
|
|
1926
1933
|
function createLayoutDataKey(pattern) {
|
|
1927
1934
|
return `__layout:${pattern}`;
|
|
1928
1935
|
}
|
|
1936
|
+
var init_layouts = () => {};
|
|
1929
1937
|
|
|
1930
1938
|
// packages/core/src/ssr/lib/compute/layouts.ts
|
|
1931
1939
|
async function loadLayoutSSRExport(layout, clientDir, isWatchMode) {
|
|
@@ -2025,7 +2033,8 @@ async function computeLayoutData(pathname, clientDir, _cwd, isWatchMode, options
|
|
|
2025
2033
|
const maxAgeMs = maxAge * 1000;
|
|
2026
2034
|
try {
|
|
2027
2035
|
const layouts = routesModule?.layouts;
|
|
2028
|
-
const
|
|
2036
|
+
const routes = routesModule?.routes;
|
|
2037
|
+
const matchingLayouts = getMatchingLayouts(pathname, layouts, routes);
|
|
2029
2038
|
for (const layout of matchingLayouts) {
|
|
2030
2039
|
try {
|
|
2031
2040
|
const layoutStatus = await processLayout(layout, pathname, clientDir, isWatchMode, streaming, maxAgeMs, searchParams, ssrData, pendingTasks, options.headers);
|
|
@@ -2052,9 +2061,10 @@ function mergeLayoutData(ssrData, pathname) {
|
|
|
2052
2061
|
ssrData[pathname] = layoutData;
|
|
2053
2062
|
}
|
|
2054
2063
|
}
|
|
2055
|
-
var
|
|
2064
|
+
var init_layouts2 = __esm(() => {
|
|
2056
2065
|
init_cache();
|
|
2057
2066
|
init_imports();
|
|
2067
|
+
init_layouts();
|
|
2058
2068
|
});
|
|
2059
2069
|
|
|
2060
2070
|
// packages/core/src/ssr/lib/compute/routes.ts
|
|
@@ -2346,10 +2356,10 @@ function setGlobalSSRData(data) {
|
|
|
2346
2356
|
var init_compute = __esm(() => {
|
|
2347
2357
|
init_imports();
|
|
2348
2358
|
init_content2();
|
|
2349
|
-
|
|
2359
|
+
init_layouts2();
|
|
2350
2360
|
init_routes();
|
|
2351
2361
|
init_content2();
|
|
2352
|
-
|
|
2362
|
+
init_layouts2();
|
|
2353
2363
|
init_routes();
|
|
2354
2364
|
});
|
|
2355
2365
|
|
|
@@ -2661,12 +2671,14 @@ async function loadLayoutData(pathname, clientDir, cwd, isWatchMode, searchParam
|
|
|
2661
2671
|
const allData = {};
|
|
2662
2672
|
try {
|
|
2663
2673
|
let layouts = globalThis.__REROUTE_LAYOUTS__;
|
|
2674
|
+
let routes = globalThis.__REROUTE_ROUTES__;
|
|
2664
2675
|
if (!layouts) {
|
|
2665
2676
|
const routesPath = join2(cwd, ".reroute", "routes.ts");
|
|
2666
2677
|
const m = await dynamicImport(routesPath, isWatchMode);
|
|
2667
2678
|
layouts = m?.layouts;
|
|
2679
|
+
routes = m?.routes;
|
|
2668
2680
|
}
|
|
2669
|
-
const matchingLayouts = getMatchingLayouts(pathname, layouts);
|
|
2681
|
+
const matchingLayouts = getMatchingLayouts(pathname, layouts, routes);
|
|
2670
2682
|
for (const layout of matchingLayouts) {
|
|
2671
2683
|
const result = await processLayout2(layout, pathname, clientDir, isWatchMode, searchParams);
|
|
2672
2684
|
if (result) {
|
|
@@ -2688,6 +2700,7 @@ function createLazyMarker(pathname, key) {
|
|
|
2688
2700
|
var init_data = __esm(() => {
|
|
2689
2701
|
init_content_path();
|
|
2690
2702
|
init_imports();
|
|
2703
|
+
init_layouts();
|
|
2691
2704
|
init_seed();
|
|
2692
2705
|
});
|
|
2693
2706
|
|
|
@@ -3153,7 +3166,7 @@ ${ssrHead}`);
|
|
|
3153
3166
|
async function extractLayoutMetadata(pathname, clientDir, cwd, isWatchMode, addHead, setLang, ogConfig, titleSuffix) {
|
|
3154
3167
|
try {
|
|
3155
3168
|
const m = await loadRoutesModule(cwd, isWatchMode);
|
|
3156
|
-
const matchingLayouts = getMatchingLayouts(pathname, m?.layouts);
|
|
3169
|
+
const matchingLayouts = getMatchingLayouts(pathname, m?.layouts, m?.routes);
|
|
3157
3170
|
for (const layout of matchingLayouts) {
|
|
3158
3171
|
await processLayoutForMetadata(layout, clientDir, isWatchMode, addHead, setLang, ogConfig, titleSuffix);
|
|
3159
3172
|
}
|
|
@@ -3472,10 +3485,11 @@ var init_metadata2 = __esm(() => {
|
|
|
3472
3485
|
init_compute();
|
|
3473
3486
|
init_content_path();
|
|
3474
3487
|
init_imports();
|
|
3488
|
+
init_layouts();
|
|
3475
3489
|
});
|
|
3476
3490
|
|
|
3477
3491
|
// packages/core/src/ssr/lib/preload.ts
|
|
3478
|
-
import { readdir as readdir6, stat as stat5 } from "node:fs/promises";
|
|
3492
|
+
import { readdir as readdir6, readFile, stat as stat5 } from "node:fs/promises";
|
|
3479
3493
|
async function preloadContentModule(pathname, clientDir, cwd, isWatchMode) {
|
|
3480
3494
|
let extraHead = "";
|
|
3481
3495
|
let hydrationScript = "";
|
|
@@ -3578,15 +3592,37 @@ function resetSSRAccessTracking() {
|
|
|
3578
3592
|
globalThis.__REROUTE_SSR_ACCESSED__ = {};
|
|
3579
3593
|
} catch {}
|
|
3580
3594
|
}
|
|
3581
|
-
function
|
|
3595
|
+
async function bundleImports(cwd, bundleUrl) {
|
|
3596
|
+
const key = `${cwd}:${bundleUrl}`;
|
|
3597
|
+
if (bundleImportsCache?.key === key)
|
|
3598
|
+
return bundleImportsCache.hrefs;
|
|
3599
|
+
const slash = bundleUrl.lastIndexOf("/");
|
|
3600
|
+
const base = bundleUrl.slice(0, slash + 1);
|
|
3601
|
+
const entry = bundleUrl.slice(slash + 1);
|
|
3602
|
+
let hrefs = [];
|
|
3603
|
+
try {
|
|
3604
|
+
const raw = await readFile(bundlePreloadPath(join2(cwd, ".reroute", "bundles")), "utf8");
|
|
3605
|
+
const manifest = JSON.parse(raw);
|
|
3606
|
+
if (manifest.entry === entry && Array.isArray(manifest.imports)) {
|
|
3607
|
+
hrefs = manifest.imports.filter((file) => typeof file === "string").map((file) => `${base}${file}`);
|
|
3608
|
+
}
|
|
3609
|
+
} catch {}
|
|
3610
|
+
bundleImportsCache = { key, hrefs };
|
|
3611
|
+
return hrefs;
|
|
3612
|
+
}
|
|
3613
|
+
function createBundlePreload(bundleUrl, imports = []) {
|
|
3582
3614
|
try {
|
|
3583
3615
|
if (typeof bundleUrl === "string" && bundleUrl.endsWith(".js")) {
|
|
3584
|
-
return `
|
|
3585
|
-
<link rel="modulepreload" href="${
|
|
3616
|
+
return [bundleUrl, ...imports].map((href) => `
|
|
3617
|
+
<link rel="modulepreload" href="${href}" />`).join("");
|
|
3586
3618
|
}
|
|
3587
3619
|
} catch {}
|
|
3588
3620
|
return "";
|
|
3589
3621
|
}
|
|
3622
|
+
function bundlePreloadPath(bundlesDir) {
|
|
3623
|
+
return join2(bundlesDir, "preload.json");
|
|
3624
|
+
}
|
|
3625
|
+
var bundleImportsCache = null;
|
|
3590
3626
|
var init_preload = __esm(() => {
|
|
3591
3627
|
init_imports();
|
|
3592
3628
|
});
|
|
@@ -4057,7 +4093,7 @@ async function performSSRSetupInternal(options, streaming, timeoutState) {
|
|
|
4057
4093
|
assertNotTimedOut();
|
|
4058
4094
|
resetSSRAccessTracking();
|
|
4059
4095
|
resetSSRContentResults();
|
|
4060
|
-
const bundlePreload = createBundlePreload(bundleUrl);
|
|
4096
|
+
const bundlePreload = createBundlePreload(bundleUrl, await bundleImports(cwd, bundleUrl));
|
|
4061
4097
|
const preloadResult = await withSpan("ssr.preload", async (span) => {
|
|
4062
4098
|
span.setAttribute("pathname", pathname);
|
|
4063
4099
|
const result = await preloadContentModule(pathname, clientDir, cwd, isWatchMode);
|
|
@@ -4196,6 +4232,7 @@ var init_lib = __esm(() => {
|
|
|
4196
4232
|
init_compute();
|
|
4197
4233
|
init_html();
|
|
4198
4234
|
init_imports();
|
|
4235
|
+
init_layouts();
|
|
4199
4236
|
init_metadata2();
|
|
4200
4237
|
init_modules();
|
|
4201
4238
|
init_preload();
|
|
@@ -7035,6 +7072,8 @@ __export(exports_core, {
|
|
|
7035
7072
|
buildLlmsDiscovery: () => buildLlmsDiscovery,
|
|
7036
7073
|
buildLocaleCookie: () => buildLocaleCookie,
|
|
7037
7074
|
buildSitemapLoc: () => buildSitemapLoc,
|
|
7075
|
+
bundleImports: () => bundleImports,
|
|
7076
|
+
bundlePreloadPath: () => bundlePreloadPath,
|
|
7038
7077
|
cleanupPathScopedSSRData: () => cleanupPathScopedSSRData,
|
|
7039
7078
|
clearSSRModuleStores: () => clearSSRModuleStores,
|
|
7040
7079
|
clearWatchImportCache: () => clearWatchImportCache,
|
|
@@ -7113,6 +7152,7 @@ __export(exports_core, {
|
|
|
7113
7152
|
isThenable: () => isThenable,
|
|
7114
7153
|
join: () => join2,
|
|
7115
7154
|
layoutCovers: () => layoutCovers,
|
|
7155
|
+
layoutWraps: () => layoutWraps,
|
|
7116
7156
|
listContentFiles: () => listContentFiles,
|
|
7117
7157
|
llmsAlternateLinkTag: () => llmsAlternateLinkTag,
|
|
7118
7158
|
loadCollections: () => loadCollections,
|
|
@@ -7187,6 +7227,27 @@ function getNamingConfig(options) {
|
|
|
7187
7227
|
function shouldRebuildClientBundle(filename) {
|
|
7188
7228
|
return filename.endsWith(".ts") || filename.endsWith(".tsx") || filename.endsWith(".md") || filename.endsWith(".mdx");
|
|
7189
7229
|
}
|
|
7230
|
+
function entryStaticImports(metafile, entryFile) {
|
|
7231
|
+
if (typeof metafile !== "object" || metafile === null || !("outputs" in metafile) || typeof metafile.outputs !== "object" || metafile.outputs === null) {
|
|
7232
|
+
return [];
|
|
7233
|
+
}
|
|
7234
|
+
const outputs = new Map(Object.entries(metafile.outputs).map(([path3, output]) => [fileNameOf(path3), output]));
|
|
7235
|
+
const found = [];
|
|
7236
|
+
const queue = [entryFile];
|
|
7237
|
+
for (let file = queue.shift();file !== undefined; file = queue.shift()) {
|
|
7238
|
+
for (const item of outputs.get(file)?.imports ?? []) {
|
|
7239
|
+
if (item.kind !== "import-statement" || typeof item.path !== "string")
|
|
7240
|
+
continue;
|
|
7241
|
+
const chunk = fileNameOf(item.path);
|
|
7242
|
+
if (chunk === entryFile || found.includes(chunk))
|
|
7243
|
+
continue;
|
|
7244
|
+
found.push(chunk);
|
|
7245
|
+
queue.push(chunk);
|
|
7246
|
+
}
|
|
7247
|
+
}
|
|
7248
|
+
return found;
|
|
7249
|
+
}
|
|
7250
|
+
var fileNameOf = (path3) => path3.split(/[\\/]/).pop() ?? path3;
|
|
7190
7251
|
|
|
7191
7252
|
// packages/cli/src/commands/lib/env.ts
|
|
7192
7253
|
import { existsSync as existsSync2, readFileSync } from "node:fs";
|
|
@@ -8070,6 +8131,109 @@ function isProductionMode(args = []) {
|
|
|
8070
8131
|
return hasProdFlag(args);
|
|
8071
8132
|
}
|
|
8072
8133
|
|
|
8134
|
+
// packages/cli/src/commands/lib/routes.ts
|
|
8135
|
+
function isRouteGroup(segment) {
|
|
8136
|
+
return groupSegment.test(segment);
|
|
8137
|
+
}
|
|
8138
|
+
function withoutGroups(routePath) {
|
|
8139
|
+
return routePath.split("/").filter((segment) => segment !== "" && !isRouteGroup(segment)).join("/");
|
|
8140
|
+
}
|
|
8141
|
+
function dirOf(filePath) {
|
|
8142
|
+
return filePath.split("/").slice(0, -1).join("/");
|
|
8143
|
+
}
|
|
8144
|
+
function inGroup(dir) {
|
|
8145
|
+
return dir.split("/").some(isRouteGroup);
|
|
8146
|
+
}
|
|
8147
|
+
function fileToRoute(filePath) {
|
|
8148
|
+
const isLayout = filePath.endsWith("[layout].tsx") || filePath.endsWith("[layout].ts") || filePath.endsWith("[layout].md") || filePath.endsWith("[layout].mdx");
|
|
8149
|
+
const dir = dirOf(filePath);
|
|
8150
|
+
let routePath = filePath.replace(/\.(tsx|ts|md|mdx)$/, "");
|
|
8151
|
+
if (isLayout) {
|
|
8152
|
+
const pattern2 = routePath.replace(/\[layout\]$/, "").replace(/\/$/, "");
|
|
8153
|
+
const normalizedPattern2 = pattern2 === "" ? "/" : `/${pattern2}`;
|
|
8154
|
+
return {
|
|
8155
|
+
path: routePath,
|
|
8156
|
+
pattern: normalizedPattern2,
|
|
8157
|
+
filePath,
|
|
8158
|
+
isLayout,
|
|
8159
|
+
isDynamic: false,
|
|
8160
|
+
params: [],
|
|
8161
|
+
isNotFound: false,
|
|
8162
|
+
dir
|
|
8163
|
+
};
|
|
8164
|
+
}
|
|
8165
|
+
routePath = routePath.replace(/\/index$/, "").replace(/^index$/, "");
|
|
8166
|
+
const params = [];
|
|
8167
|
+
const pattern = withoutGroups(routePath).replace(/\[([^\]]+)\]/g, (_, param) => {
|
|
8168
|
+
params.push(param);
|
|
8169
|
+
return `:${param}`;
|
|
8170
|
+
});
|
|
8171
|
+
const normalizedPattern = pattern === "" ? "/" : `/${pattern}`;
|
|
8172
|
+
const isNotFound = /(^|\/)\[404\]$/.test(routePath);
|
|
8173
|
+
let notFoundBasePattern;
|
|
8174
|
+
if (isNotFound) {
|
|
8175
|
+
const base = withoutGroups(routePath.replace(/(^|\/)\[404\]$/, ""));
|
|
8176
|
+
notFoundBasePattern = base ? `/${base}` : "/";
|
|
8177
|
+
}
|
|
8178
|
+
return {
|
|
8179
|
+
path: routePath,
|
|
8180
|
+
pattern: normalizedPattern,
|
|
8181
|
+
filePath,
|
|
8182
|
+
isLayout: false,
|
|
8183
|
+
isDynamic: params.length > 0,
|
|
8184
|
+
params,
|
|
8185
|
+
isNotFound,
|
|
8186
|
+
notFoundBasePattern,
|
|
8187
|
+
dir
|
|
8188
|
+
};
|
|
8189
|
+
}
|
|
8190
|
+
function sortRoutes(routes) {
|
|
8191
|
+
return routes.sort((a, b) => compareRouteSpecificity(a, b));
|
|
8192
|
+
}
|
|
8193
|
+
function assertUniquePatterns(routes) {
|
|
8194
|
+
const seen = new Map;
|
|
8195
|
+
for (const route of routes) {
|
|
8196
|
+
const other = seen.get(route.pattern);
|
|
8197
|
+
if (other) {
|
|
8198
|
+
throw new Error(`Routes ${other} and ${route.filePath} both serve ${route.pattern}`);
|
|
8199
|
+
}
|
|
8200
|
+
seen.set(route.pattern, route.filePath);
|
|
8201
|
+
}
|
|
8202
|
+
}
|
|
8203
|
+
function routesUnder(dir, routes) {
|
|
8204
|
+
return routes.filter((route) => route.dir === dir || route.dir.startsWith(`${dir}/`)).map((route) => route.pattern);
|
|
8205
|
+
}
|
|
8206
|
+
function generateRouteTree(files) {
|
|
8207
|
+
const routes = [];
|
|
8208
|
+
const layouts2 = [];
|
|
8209
|
+
const notFoundRoutes = [];
|
|
8210
|
+
for (const file of files) {
|
|
8211
|
+
const route = fileToRoute(file);
|
|
8212
|
+
if (route.isLayout) {
|
|
8213
|
+
layouts2.push(route);
|
|
8214
|
+
} else if (route.isNotFound) {
|
|
8215
|
+
notFoundRoutes.push(route);
|
|
8216
|
+
} else {
|
|
8217
|
+
routes.push(route);
|
|
8218
|
+
}
|
|
8219
|
+
}
|
|
8220
|
+
assertUniquePatterns(routes);
|
|
8221
|
+
for (const layout of layouts2) {
|
|
8222
|
+
if (inGroup(layout.dir))
|
|
8223
|
+
layout.routes = routesUnder(layout.dir, routes);
|
|
8224
|
+
}
|
|
8225
|
+
return {
|
|
8226
|
+
routes: sortRoutes(routes),
|
|
8227
|
+
layouts: layouts2,
|
|
8228
|
+
notFoundRoutes
|
|
8229
|
+
};
|
|
8230
|
+
}
|
|
8231
|
+
var groupSegment;
|
|
8232
|
+
var init_routes2 = __esm(() => {
|
|
8233
|
+
init_core();
|
|
8234
|
+
groupSegment = /^\(.+\)$/;
|
|
8235
|
+
});
|
|
8236
|
+
|
|
8073
8237
|
// packages/cli/src/commands/lib/streaming/analyzer.ts
|
|
8074
8238
|
import { dirname as dirname4, join as join10 } from "node:path";
|
|
8075
8239
|
function hasSSRDataExport(source) {
|
|
@@ -8309,7 +8473,7 @@ var init_theme = __esm(() => {
|
|
|
8309
8473
|
|
|
8310
8474
|
// packages/cli/src/commands/lib/watch.ts
|
|
8311
8475
|
import { createHash as createHash3 } from "node:crypto";
|
|
8312
|
-
import { readFile } from "node:fs/promises";
|
|
8476
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
8313
8477
|
import { dirname as dirname7, isAbsolute as isAbsolute2, join as join13, resolve as resolve4, sep } from "node:path";
|
|
8314
8478
|
function isWatchNoise(name) {
|
|
8315
8479
|
return name.split(/[/\\]/).some((part) => part.startsWith(".")) || /\.bust-[^/\\]+$/.test(name);
|
|
@@ -8332,7 +8496,7 @@ function createContentFingerprint(options) {
|
|
|
8332
8496
|
async changed(absPath) {
|
|
8333
8497
|
const settling = Date.now() - startedAt < settleMs;
|
|
8334
8498
|
try {
|
|
8335
|
-
const buf = await
|
|
8499
|
+
const buf = await readFile2(absPath);
|
|
8336
8500
|
gone.delete(absPath);
|
|
8337
8501
|
const hash2 = createHash3("sha1").update(buf).digest("hex");
|
|
8338
8502
|
const prev = hashes.get(absPath);
|
|
@@ -8606,69 +8770,6 @@ async function scanOgFiles(dir, base = "") {
|
|
|
8606
8770
|
}
|
|
8607
8771
|
return files;
|
|
8608
8772
|
}
|
|
8609
|
-
function fileToRoute(filePath) {
|
|
8610
|
-
const isLayout = filePath.endsWith("[layout].tsx") || filePath.endsWith("[layout].ts") || filePath.endsWith("[layout].md") || filePath.endsWith("[layout].mdx");
|
|
8611
|
-
let routePath = filePath.replace(/\.(tsx|ts|md|mdx)$/, "");
|
|
8612
|
-
if (isLayout) {
|
|
8613
|
-
const pattern2 = routePath.replace(/\[layout\]$/, "").replace(/\/$/, "");
|
|
8614
|
-
const normalizedPattern2 = pattern2 === "" ? "/" : `/${pattern2}`;
|
|
8615
|
-
return {
|
|
8616
|
-
path: routePath,
|
|
8617
|
-
pattern: normalizedPattern2,
|
|
8618
|
-
filePath,
|
|
8619
|
-
isLayout,
|
|
8620
|
-
isDynamic: false,
|
|
8621
|
-
params: [],
|
|
8622
|
-
isNotFound: false
|
|
8623
|
-
};
|
|
8624
|
-
}
|
|
8625
|
-
routePath = routePath.replace(/\/index$/, "").replace(/^index$/, "");
|
|
8626
|
-
const params = [];
|
|
8627
|
-
const pattern = routePath.replace(/\[([^\]]+)\]/g, (_, param) => {
|
|
8628
|
-
params.push(param);
|
|
8629
|
-
return `:${param}`;
|
|
8630
|
-
});
|
|
8631
|
-
const normalizedPattern = pattern === "" ? "/" : `/${pattern}`;
|
|
8632
|
-
const isNotFound = /(^|\/)\[404\]$/.test(routePath);
|
|
8633
|
-
let notFoundBasePattern;
|
|
8634
|
-
if (isNotFound) {
|
|
8635
|
-
const base = routePath.replace(/(^|\/)\[404\]$/, "").replace(/\/$/, "");
|
|
8636
|
-
notFoundBasePattern = base ? `/${base}` : "/";
|
|
8637
|
-
}
|
|
8638
|
-
return {
|
|
8639
|
-
path: routePath,
|
|
8640
|
-
pattern: normalizedPattern,
|
|
8641
|
-
filePath,
|
|
8642
|
-
isLayout: false,
|
|
8643
|
-
isDynamic: params.length > 0,
|
|
8644
|
-
params,
|
|
8645
|
-
isNotFound,
|
|
8646
|
-
notFoundBasePattern
|
|
8647
|
-
};
|
|
8648
|
-
}
|
|
8649
|
-
function sortRoutes(routes) {
|
|
8650
|
-
return routes.sort((a, b) => compareRouteSpecificity(a, b));
|
|
8651
|
-
}
|
|
8652
|
-
function generateRouteTree(files) {
|
|
8653
|
-
const routes = [];
|
|
8654
|
-
const layouts2 = [];
|
|
8655
|
-
const notFoundRoutes = [];
|
|
8656
|
-
for (const file of files) {
|
|
8657
|
-
const route = fileToRoute(file);
|
|
8658
|
-
if (route.isLayout) {
|
|
8659
|
-
layouts2.push(route);
|
|
8660
|
-
} else if (route.isNotFound) {
|
|
8661
|
-
notFoundRoutes.push(route);
|
|
8662
|
-
} else {
|
|
8663
|
-
routes.push(route);
|
|
8664
|
-
}
|
|
8665
|
-
}
|
|
8666
|
-
return {
|
|
8667
|
-
routes: sortRoutes(routes),
|
|
8668
|
-
layouts: layouts2,
|
|
8669
|
-
notFoundRoutes
|
|
8670
|
-
};
|
|
8671
|
-
}
|
|
8672
8773
|
function getImportPath(filePath, streamingMap, routesImportBase) {
|
|
8673
8774
|
const isMarkdown = /\.(md|mdx)$/.test(filePath);
|
|
8674
8775
|
if (isMarkdown) {
|
|
@@ -8746,9 +8847,11 @@ const Layout${i}Meta = _meta(Layout${i}Module);`)
|
|
|
8746
8847
|
}).join(`
|
|
8747
8848
|
`);
|
|
8748
8849
|
const layoutsArray = tree.layouts.map((l, i) => {
|
|
8850
|
+
const scope = l.routes ? `
|
|
8851
|
+
routes: ${JSON.stringify(l.routes)},` : "";
|
|
8749
8852
|
return ` {
|
|
8750
8853
|
pattern: "${l.pattern}",
|
|
8751
|
-
path: "${l.path}"
|
|
8854
|
+
path: "${l.path}",${scope}
|
|
8752
8855
|
component: Layout${i},
|
|
8753
8856
|
ssr: Layout${i}SSR,
|
|
8754
8857
|
meta: Layout${i}Meta,
|
|
@@ -9527,6 +9630,10 @@ async function buildEntrypointBundle(cwd, args = []) {
|
|
|
9527
9630
|
}
|
|
9528
9631
|
}
|
|
9529
9632
|
}));
|
|
9633
|
+
await Bun.write(bundlePreloadPath(bundlesDir), JSON.stringify({
|
|
9634
|
+
entry: entryFile,
|
|
9635
|
+
imports: entryStaticImports("metafile" in result ? result.metafile : undefined, entryFile)
|
|
9636
|
+
}));
|
|
9530
9637
|
if (shouldPreCompress && compressionCount > 0) {
|
|
9531
9638
|
const compressionDuration = performance.now() - compressionStartTime;
|
|
9532
9639
|
const timeStr = compressionDuration < 1000 ? `${compressionDuration.toFixed(0)}ms` : `${(compressionDuration / 1000).toFixed(2)}s`;
|
|
@@ -10266,6 +10373,7 @@ var init_gen = __esm(() => {
|
|
|
10266
10373
|
init_env();
|
|
10267
10374
|
init_images();
|
|
10268
10375
|
init_markdown();
|
|
10376
|
+
init_routes2();
|
|
10269
10377
|
init_analyzer();
|
|
10270
10378
|
init_suspense();
|
|
10271
10379
|
init_theme();
|
|
@@ -105638,7 +105746,7 @@ __export(exports_analyze, {
|
|
|
105638
105746
|
default: () => analyze
|
|
105639
105747
|
});
|
|
105640
105748
|
import { existsSync as existsSync14, statSync } from "node:fs";
|
|
105641
|
-
import { readdir as readdir9, readFile as
|
|
105749
|
+
import { readdir as readdir9, readFile as readFile3, stat as stat6, writeFile as writeFile2 } from "node:fs/promises";
|
|
105642
105750
|
import { basename as basename4, join as join20, relative as relative4 } from "node:path";
|
|
105643
105751
|
import Table from "cli-table3";
|
|
105644
105752
|
async function findChunkBundles(cwd) {
|
|
@@ -105900,7 +106008,7 @@ async function buildDependencyTree(entryPath, cwd) {
|
|
|
105900
106008
|
}
|
|
105901
106009
|
return node.size;
|
|
105902
106010
|
};
|
|
105903
|
-
const content2 = await
|
|
106011
|
+
const content2 = await readFile3(entryPath, "utf-8");
|
|
105904
106012
|
const modulePattern = /\/\/\s*(.+?\.(?:ts|tsx|js|jsx|mjs|cjs))\s*$/gm;
|
|
105905
106013
|
const nodeModulesNode = {
|
|
105906
106014
|
name: "node_modules",
|
|
@@ -105981,8 +106089,8 @@ async function buildTreeFromSourceMap(bundlePath, cwd) {
|
|
|
105981
106089
|
if (!existsSync14(mapPath))
|
|
105982
106090
|
return null;
|
|
105983
106091
|
const [bundle, mapJson] = await Promise.all([
|
|
105984
|
-
|
|
105985
|
-
|
|
106092
|
+
readFile3(bundlePath, "utf-8"),
|
|
106093
|
+
readFile3(mapPath, "utf-8")
|
|
105986
106094
|
]);
|
|
105987
106095
|
const map = JSON.parse(mapJson);
|
|
105988
106096
|
const sourceRoot = map.sourceRoot || "";
|
|
@@ -106141,7 +106249,7 @@ async function generateHTMLReport(stats, depTree, mainInfo, browserDepTree, brow
|
|
|
106141
106249
|
const stats2 = statSync(filePath);
|
|
106142
106250
|
if (stats2.isFile() && !file.includes(".")) {
|
|
106143
106251
|
actualServerBinarySize = stats2.size;
|
|
106144
|
-
const content2 = await
|
|
106252
|
+
const content2 = await readFile3(filePath);
|
|
106145
106253
|
actualServerBinaryGzipped = Bun.gzipSync(content2).length;
|
|
106146
106254
|
break;
|
|
106147
106255
|
}
|
|
@@ -107627,7 +107735,7 @@ async function printConsoleReport(stats, depTree, mainInfo, browserDepTree, brow
|
|
|
107627
107735
|
const stats2 = statSync(filePath);
|
|
107628
107736
|
if (stats2.isFile() && !file.includes(".")) {
|
|
107629
107737
|
actualServerBinarySize = stats2.size;
|
|
107630
|
-
const content2 = await
|
|
107738
|
+
const content2 = await readFile3(filePath);
|
|
107631
107739
|
actualServerBinaryGzipped = Bun.gzipSync(content2).length;
|
|
107632
107740
|
break;
|
|
107633
107741
|
}
|
|
@@ -107705,7 +107813,7 @@ async function analyze(args) {
|
|
|
107705
107813
|
}
|
|
107706
107814
|
try {
|
|
107707
107815
|
const browserStat = await stat6(browserEntry);
|
|
107708
|
-
const browserContent = await
|
|
107816
|
+
const browserContent = await readFile3(browserEntry);
|
|
107709
107817
|
const browserGzipped = Bun.gzipSync(browserContent).length;
|
|
107710
107818
|
browserInfo = {
|
|
107711
107819
|
name: basename4(browserEntry),
|
|
@@ -107759,7 +107867,7 @@ async function analyze(args) {
|
|
|
107759
107867
|
const packageJsonPath = join20(cwd, "package.json");
|
|
107760
107868
|
if (existsSync14(packageJsonPath)) {
|
|
107761
107869
|
try {
|
|
107762
|
-
const packageJson = JSON.parse(await
|
|
107870
|
+
const packageJson = JSON.parse(await readFile3(packageJsonPath, "utf-8"));
|
|
107763
107871
|
const runtimeDeps = packageJson.dependencies || {};
|
|
107764
107872
|
const nodeModulesNode = depTree.root.children?.find((c) => c.name === "node_modules");
|
|
107765
107873
|
if (nodeModulesNode) {
|
|
@@ -107787,7 +107895,7 @@ async function analyze(args) {
|
|
|
107787
107895
|
}
|
|
107788
107896
|
try {
|
|
107789
107897
|
const entryStat = await stat6(entry);
|
|
107790
|
-
const entryContent = await
|
|
107898
|
+
const entryContent = await readFile3(entry);
|
|
107791
107899
|
const entryGzipped = Bun.gzipSync(entryContent).length;
|
|
107792
107900
|
mainInfo = {
|
|
107793
107901
|
name: basename4(entry),
|
|
@@ -108620,7 +108728,7 @@ async function getVersionString2() {
|
|
|
108620
108728
|
}
|
|
108621
108729
|
async function getVersion2() {
|
|
108622
108730
|
if (true) {
|
|
108623
|
-
return "1.0.0-alpha.
|
|
108731
|
+
return "1.0.0-alpha.35";
|
|
108624
108732
|
}
|
|
108625
108733
|
const possiblePaths = [
|
|
108626
108734
|
path3.join(import.meta.dir, "../../../package.json"),
|
|
@@ -108637,10 +108745,10 @@ async function getVersion2() {
|
|
|
108637
108745
|
}
|
|
108638
108746
|
async function getCommit2() {
|
|
108639
108747
|
if (true) {
|
|
108640
|
-
return "
|
|
108748
|
+
return "bb512b2";
|
|
108641
108749
|
}
|
|
108642
108750
|
return "dev";
|
|
108643
108751
|
}
|
|
108644
108752
|
main();
|
|
108645
108753
|
|
|
108646
|
-
//# debugId=
|
|
108754
|
+
//# debugId=85223BABEE11283064756E2164756E21
|