for-humanity 0.5.0 → 0.7.0

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.
Files changed (145) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +1 -1
  3. package/README.md +4 -3
  4. package/dist/browser.js +9 -9
  5. package/dist/cli.css +25 -310
  6. package/dist/cli.js +177 -321
  7. package/package.json +4 -3
  8. package/src/asset/font/{jetbrains-mono/LICENSE → monoplex-kr/LICENSE.md} +61 -8
  9. package/src/asset/font/monoplex-kr/MonoplexKR-Regular.woff2 +0 -0
  10. package/src/asset/font/monoplex-kr/MonoplexKR-SemiBold.woff2 +0 -0
  11. package/src/asset/font/monoplex-kr/monoplex-kr.css +20 -0
  12. package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -3
  13. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +2 -3
  14. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +3 -4
  15. package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +6 -14
  16. package/src/component/widget/navigation/_type/navigation-data.ts +0 -12
  17. package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -4
  18. package/src/component/widget/navigation/_wg-navigation-nav-list.css +5 -136
  19. package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +10 -55
  20. package/src/component/widget/navigation/_wg-navigation-nav.css +2 -8
  21. package/src/component/widget/navigation/_wg-navigation-nav.tsx +1 -11
  22. package/src/component/widget/navigation/_wg-navigation-toc.css +12 -207
  23. package/src/component/widget/navigation/_wg-navigation-toc.tsx +39 -80
  24. package/src/component/widget/navigation/wg-navigation.tsx +10 -69
  25. package/src/component/widget/prose/wg-prose.css +0 -3
  26. package/src/component/widget/shell/wg-shell.css +1 -1
  27. package/src/constant/copy.ts +5 -5
  28. package/src/constant/font.ts +2 -12
  29. package/src/entry/browser/browser.tsx +1 -1
  30. package/src/entry/cli/_constant/crawling.ts +14 -0
  31. package/src/entry/cli/_function/create-dev-app.ts +9 -1
  32. package/src/entry/cli/_function/read-docs.ts +20 -1
  33. package/src/entry/cli/_function/to-crawling-app.ts +42 -0
  34. package/src/entry/cli/cli.test.ts +112 -9
  35. package/src/entry/cli/cli.ts +27 -22
  36. package/src/store/navigation/create-navigation-stores.test.ts +10 -28
  37. package/src/store/navigation/create-navigation-stores.ts +4 -18
  38. package/src/store/navigation/navigation-state.ts +0 -10
  39. package/src/store/navigation/navigation-storage.ts +0 -5
  40. package/src/style/token.css +11 -14
  41. package/src/type/site-config.ts +10 -1
  42. package/src/util/font/to-font-css.test.ts +2 -2
  43. package/src/util/mermaid/render-flow.js +2 -2
  44. package/src/asset/font/jetbrains-mono/jetbrains-mono-latin-wght-normal.woff2 +0 -0
  45. package/src/asset/font/jetbrains-mono/jetbrains-mono.css +0 -11
  46. package/src/asset/font/pretendard/LICENSE.txt +0 -94
  47. package/src/asset/font/pretendard/pretendardvariable-dynamic-subset.css +0 -1008
  48. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.0.woff2 +0 -0
  49. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.1.woff2 +0 -0
  50. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.10.woff2 +0 -0
  51. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.11.woff2 +0 -0
  52. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.12.woff2 +0 -0
  53. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.13.woff2 +0 -0
  54. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.14.woff2 +0 -0
  55. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.15.woff2 +0 -0
  56. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.16.woff2 +0 -0
  57. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.17.woff2 +0 -0
  58. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.18.woff2 +0 -0
  59. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.19.woff2 +0 -0
  60. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.2.woff2 +0 -0
  61. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.20.woff2 +0 -0
  62. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.21.woff2 +0 -0
  63. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.22.woff2 +0 -0
  64. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.23.woff2 +0 -0
  65. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.24.woff2 +0 -0
  66. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.25.woff2 +0 -0
  67. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.26.woff2 +0 -0
  68. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.27.woff2 +0 -0
  69. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.28.woff2 +0 -0
  70. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.29.woff2 +0 -0
  71. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.3.woff2 +0 -0
  72. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.30.woff2 +0 -0
  73. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.31.woff2 +0 -0
  74. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.32.woff2 +0 -0
  75. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.33.woff2 +0 -0
  76. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.34.woff2 +0 -0
  77. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.35.woff2 +0 -0
  78. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.36.woff2 +0 -0
  79. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.37.woff2 +0 -0
  80. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.38.woff2 +0 -0
  81. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.39.woff2 +0 -0
  82. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.4.woff2 +0 -0
  83. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.40.woff2 +0 -0
  84. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.41.woff2 +0 -0
  85. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.42.woff2 +0 -0
  86. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.43.woff2 +0 -0
  87. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.44.woff2 +0 -0
  88. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.45.woff2 +0 -0
  89. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.46.woff2 +0 -0
  90. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.47.woff2 +0 -0
  91. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.48.woff2 +0 -0
  92. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.49.woff2 +0 -0
  93. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.5.woff2 +0 -0
  94. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.50.woff2 +0 -0
  95. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.51.woff2 +0 -0
  96. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.52.woff2 +0 -0
  97. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.53.woff2 +0 -0
  98. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.54.woff2 +0 -0
  99. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.55.woff2 +0 -0
  100. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.56.woff2 +0 -0
  101. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.57.woff2 +0 -0
  102. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.58.woff2 +0 -0
  103. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.59.woff2 +0 -0
  104. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.6.woff2 +0 -0
  105. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.60.woff2 +0 -0
  106. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.61.woff2 +0 -0
  107. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.62.woff2 +0 -0
  108. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.63.woff2 +0 -0
  109. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.64.woff2 +0 -0
  110. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.65.woff2 +0 -0
  111. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.66.woff2 +0 -0
  112. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.67.woff2 +0 -0
  113. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.68.woff2 +0 -0
  114. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.69.woff2 +0 -0
  115. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.7.woff2 +0 -0
  116. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.70.woff2 +0 -0
  117. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.71.woff2 +0 -0
  118. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.72.woff2 +0 -0
  119. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.73.woff2 +0 -0
  120. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.74.woff2 +0 -0
  121. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.75.woff2 +0 -0
  122. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.76.woff2 +0 -0
  123. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.77.woff2 +0 -0
  124. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.78.woff2 +0 -0
  125. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.79.woff2 +0 -0
  126. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.8.woff2 +0 -0
  127. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.80.woff2 +0 -0
  128. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.81.woff2 +0 -0
  129. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.82.woff2 +0 -0
  130. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.83.woff2 +0 -0
  131. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.84.woff2 +0 -0
  132. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.85.woff2 +0 -0
  133. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.86.woff2 +0 -0
  134. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.87.woff2 +0 -0
  135. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.88.woff2 +0 -0
  136. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.89.woff2 +0 -0
  137. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.9.woff2 +0 -0
  138. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.90.woff2 +0 -0
  139. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.91.woff2 +0 -0
  140. package/src/component/widget/navigation/_function/to-navigation-branch-id.ts +0 -6
  141. package/src/component/widget/navigation/_wg-navigation-branch-toggle.css +0 -28
  142. package/src/component/widget/navigation/_wg-navigation-branch-toggle.tsx +0 -48
  143. package/src/store/navigation/_constant/tree.ts +0 -6
  144. package/src/store/navigation/to-navigation-tree-state.ts +0 -19
  145. package/src/store/navigation/use-navigation-tree-store.ts +0 -12
package/dist/cli.js CHANGED
@@ -4,12 +4,12 @@
4
4
  import { EventEmitter } from "node:events";
5
5
  import { existsSync as existsSync3, readFileSync as readFileSync3, watch } from "node:fs";
6
6
  import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
7
- import { basename as basename2, dirname as dirname4, extname as extname4, join as join4, relative as relative4, resolve as resolve3, sep as sep3 } from "node:path";
7
+ import { dirname as dirname4, extname as extname4, join as join4, relative as relative4, resolve as resolve3, sep as sep3 } from "node:path";
8
8
  import { fileURLToPath, pathToFileURL } from "node:url";
9
9
  import { serve } from "@hono/node-server";
10
10
  import { serveStatic } from "@hono/node-server/serve-static";
11
11
  import { debounce } from "es-toolkit";
12
- import { Hono as Hono3 } from "hono";
12
+ import { Hono as Hono4 } from "hono";
13
13
  import { toSSG } from "hono/ssg";
14
14
 
15
15
  // src/constant/asset.ts
@@ -48,9 +48,9 @@ var copy_home_missing = "\uBB38\uC11C \uD3F4\uB354\uC5D0 README.md\uB97C \uCD94\
48
48
  var copy_nav_toc_label = "On this page";
49
49
  var copy_error_home_clash = "\uD648 README\uAC00 \uACB9\uCE5C\uB2E4";
50
50
  var copy_error_prefix = "for-humanity";
51
- var copy_error_font_preload = "Missing bundled font for preload";
52
51
  var copy_error_unknown_command = "\uBAA8\uB974\uB294 \uBA85\uB839\uC774\uB2E4";
53
52
  var copy_error_config = "\uC124\uC815\uC774 \uD2C0\uB838\uB2E4";
53
+ var copy_error_site_url = "url\uC740 \uC0AC\uC6A9\uC790 \uC815\uBCF4\xB7\uD558\uC704 \uACBD\uB85C\xB7query\xB7hash\uAC00 \uC5C6\uB294 HTTP(S) \uC0AC\uC774\uD2B8 \uB8E8\uD2B8\uC5EC\uC57C \uD55C\uB2E4";
54
54
  var copy_error_frontmatter = "frontmatter\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
55
55
  var copy_error_navigation_clash = "navigation\uC758 \uBB36\uC74C\uC774 \uACB9\uCE5C\uB2E4";
56
56
  var copy_error_doc_id = "\uBB38\uC11C id\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uB294 \uACBD\uB85C";
@@ -66,10 +66,8 @@ var copy_warn_unknown_status = "\uC124\uC815\uC5D0 \uC5C6\uB294 \uC0C1\uD0DC \uB
66
66
  var copy_error_asset = "\uC790\uC6D0\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
67
67
 
68
68
  // src/constant/font.ts
69
- var font_sans_css = "src/asset/font/pretendard/pretendardvariable-dynamic-subset.css";
70
- var font_mono_css = "src/asset/font/jetbrains-mono/jetbrains-mono.css";
69
+ var font_mono_css = "src/asset/font/monoplex-kr/monoplex-kr.css";
71
70
  var font_brand_css = "src/asset/font/architects-daughter/architects-daughter.css";
72
- var font_sans_preload_file = "PretendardVariable.subset.91.woff2";
73
71
  var font_display_strategy = "optional";
74
72
  var font_hash_length = 12;
75
73
  var font_cache_control = "public, max-age=31536000, immutable";
@@ -85,6 +83,11 @@ var cli_config_file_name = "for-humanity.config.mjs";
85
83
  var cli_dev_port = 4321;
86
84
  var cli_reload_delay_ms = 150;
87
85
 
86
+ // src/entry/cli/_constant/crawling.ts
87
+ var crawling_robots_path = "/robots.txt";
88
+ var crawling_sitemap_path = "/sitemap.xml";
89
+ var crawling_reserved_roots = [crawling_robots_path.slice(1), crawling_sitemap_path.slice(1)];
90
+
88
91
  // src/entry/cli/_function/create-app.tsx
89
92
  import { Hono } from "hono";
90
93
  import { html } from "hono/html";
@@ -104,7 +107,7 @@ var WgProse = (props) => {
104
107
  };
105
108
 
106
109
  // src/component/widget/shell/wg-shell.tsx
107
- import clsx10 from "clsx";
110
+ import clsx9 from "clsx";
108
111
 
109
112
  // src/component/widget/navigation/_constant/locale.ts
110
113
  var locale_doc_name = "en";
@@ -165,7 +168,6 @@ var toNavigationDocument = (options) => ({
165
168
  name: options.doc.data.name,
166
169
  label: options.doc.data.label,
167
170
  active: options.doc.id === options.current,
168
- current: options.doc.id === options.current || options.ancestors.has(options.doc.id),
169
171
  children: options.doc.children === void 0 ? [] : options.doc.children.map((doc) => toNavigationDocument({ ...options, doc }))
170
172
  });
171
173
 
@@ -173,8 +175,7 @@ var toNavigationDocument = (options) => ({
173
175
  var toNavigationGroup = (options) => ({
174
176
  name: options.group.name,
175
177
  path: options.group.path,
176
- current: options.group.path.every((name, index) => name === options.currentGroup?.[index]),
177
- docs: options.group.docs.map((doc) => toNavigationDocument({ doc, current: options.current, ancestors: options.ancestors })),
178
+ docs: options.group.docs.map((doc) => toNavigationDocument({ doc, current: options.current })),
178
179
  groups: options.group.groups.map((group) => toNavigationGroup({ ...options, group }))
179
180
  });
180
181
 
@@ -212,19 +213,12 @@ var toTocGroups = (outline) => {
212
213
  };
213
214
 
214
215
  // src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts
215
- var toNavigationData = (options) => {
216
- const currentDoc = options.docs.find((doc) => doc.id === options.current);
217
- const ancestors = new Set(currentDoc?.ancestors);
218
- return {
219
- title: options.site.title,
220
- groups: toDocGroups({ docs: options.docs, navigation: options.site.navigation }).map(
221
- (group) => toNavigationGroup({ group, current: options.current, ancestors, currentGroup: currentDoc?.data.group })
222
- ),
223
- outline: options.outline === void 0 ? [] : toTocGroups(options.outline),
224
- pageId: options.current === void 0 ? "/" : options.current,
225
- home: options.current === void 0
226
- };
227
- };
216
+ var toNavigationData = (options) => ({
217
+ title: options.site.title,
218
+ groups: toDocGroups({ docs: options.docs, navigation: options.site.navigation }).map((group) => toNavigationGroup({ group, current: options.current })),
219
+ outline: options.outline === void 0 ? [] : toTocGroups(options.outline),
220
+ home: options.current === void 0
221
+ });
228
222
 
229
223
  // src/component/widget/navigation/_function/to-navigation-json.ts
230
224
  var toNavigationJson = (data) => {
@@ -232,7 +226,7 @@ var toNavigationJson = (data) => {
232
226
  };
233
227
 
234
228
  // src/component/widget/shell-controls/wg-shell-controls.tsx
235
- import clsx9 from "clsx";
229
+ import clsx8 from "clsx";
236
230
  import { Fragment as Fragment3, useEffect, useLayoutEffect as useLayoutEffect5, useRef as useRef4 } from "hono/jsx";
237
231
 
238
232
  // src/component/widget/cursor-face/wg-cursor-face.tsx
@@ -342,7 +336,7 @@ var WgCursorFace = (props) => {
342
336
  };
343
337
 
344
338
  // src/component/widget/navigation/wg-navigation.tsx
345
- import clsx8 from "clsx";
339
+ import clsx7 from "clsx";
346
340
  import { Fragment as Fragment2, useLayoutEffect as useLayoutEffect4, useRef as useRef3, useState as useState3 } from "hono/jsx";
347
341
  import { flushSync } from "hono/jsx/dom";
348
342
 
@@ -373,119 +367,51 @@ var restoreNavigationScroll = (options) => {
373
367
  };
374
368
 
375
369
  // src/component/widget/navigation/_wg-navigation-nav.tsx
376
- import clsx5 from "clsx";
377
-
378
- // src/component/widget/navigation/_wg-navigation-branch-toggle.tsx
379
- import clsx3 from "clsx";
380
-
381
- // src/component/widget/navigation/_function/to-navigation-branch-id.ts
382
- var toNavigationBranchId = (key) => {
383
- return `fh-branch-${encodeURIComponent(key)}`;
384
- };
385
-
386
- // src/component/widget/navigation/_wg-navigation-branch-toggle.tsx
387
- import { jsx as jsx3 } from "hono/jsx/jsx-runtime";
388
- var WgNavigationBranchToggle = (props) => {
389
- const handleToggleClick = () => props.onToggle?.(props.branchKey);
390
- return /* @__PURE__ */ jsx3(
391
- "button",
392
- {
393
- className: clsx3("wg_navigationBranchToggle__root"),
394
- type: "button",
395
- "aria-label": `${props.collapsed[props.branchKey] === true ? "Expand" : "Collapse"} ${props.label}`,
396
- "aria-expanded": String(props.collapsed[props.branchKey] !== true),
397
- "aria-controls": toNavigationBranchId(props.branchKey),
398
- "data-navigation-toggle": props.branchKey,
399
- "data-navigation-label": props.label,
400
- hidden: props.onToggle === void 0,
401
- onClick: handleToggleClick,
402
- children: props.collapsed[props.branchKey] === true ? "+" : "\u2212"
403
- }
404
- );
405
- };
370
+ import clsx4 from "clsx";
406
371
 
407
372
  // src/component/widget/navigation/_wg-navigation-nav-list.tsx
408
- import clsx4 from "clsx";
373
+ import clsx3 from "clsx";
409
374
  import { Fragment } from "hono/jsx";
410
- import { jsx as jsx4, jsxs as jsxs2 } from "hono/jsx/jsx-runtime";
375
+ import { jsx as jsx3, jsxs as jsxs2 } from "hono/jsx/jsx-runtime";
411
376
  var WgNavigationNavList = (props) => {
412
377
  const entries = [
413
- ...props.group.docs.map((doc) => {
414
- const active = doc.active;
415
- return { kind: "document", key: `doc:${doc.id}`, doc, active, current: doc.current };
416
- }),
417
- ...props.group.groups.map((group) => ({
418
- kind: "group",
419
- key: `group:${JSON.stringify(group.path)}`,
420
- group,
421
- current: group.current
422
- }))
378
+ ...props.group.docs.map((doc) => ({ kind: "document", key: `doc:${doc.id}`, doc })),
379
+ ...props.group.groups.map((group) => ({ kind: "group", key: `group:${JSON.stringify(group.path)}`, group }))
423
380
  ];
424
- const currentIndex = entries.findIndex((entry) => entry.current);
425
- return /* @__PURE__ */ jsx4(
426
- "ul",
427
- {
428
- className: clsx4("wg_navigationNavList__root"),
429
- "aria-label": props.group.name,
430
- id: toNavigationBranchId(props.branchKey),
431
- hidden: props.collapsed[props.branchKey] === true,
432
- children: entries.map((entry, index) => /* @__PURE__ */ jsxs2(
433
- "li",
381
+ return /* @__PURE__ */ jsx3("ul", { className: clsx3("wg_navigationNavList__root"), "aria-label": props.group.name, children: entries.map((entry) => /* @__PURE__ */ jsxs2("li", { className: clsx3("wg_navigationNavList__item"), children: [
382
+ entry.kind === "document" && /* @__PURE__ */ jsxs2(Fragment, { children: [
383
+ /* @__PURE__ */ jsx3(
384
+ "a",
434
385
  {
435
- className: clsx4("wg_navigationNavList__item", {
436
- "wg_navigationNavList__item--trail": index < currentIndex,
437
- "wg_navigationNavList__item--current": entry.current
438
- }),
439
- children: [
440
- entry.kind === "document" && /* @__PURE__ */ jsxs2(Fragment, { children: [
441
- /* @__PURE__ */ jsx4(
442
- "a",
443
- {
444
- className: clsx4("wg_navigationNavList__link", { "wg_navigationNavList__link--active": entry.active }),
445
- href: `/${entry.doc.id}/`,
446
- title: entry.doc.label,
447
- "aria-current": entry.active ? "page" : void 0,
448
- children: entry.doc.name
449
- }
450
- ),
451
- entry.doc.children.length > 0 && /* @__PURE__ */ jsx4(WgNavigationBranchToggle, { branchKey: entry.key, label: entry.doc.name, collapsed: props.collapsed, onToggle: props.onToggle }),
452
- entry.doc.children.length > 0 && /* @__PURE__ */ jsx4(
453
- WgNavigationNavList,
454
- {
455
- group: { name: entry.doc.name, path: props.group.path, current: entry.current, docs: entry.doc.children, groups: [] },
456
- collapsed: props.collapsed,
457
- onToggle: props.onToggle,
458
- branchKey: entry.key
459
- }
460
- )
461
- ] }),
462
- entry.kind === "group" && /* @__PURE__ */ jsxs2(Fragment, { children: [
463
- /* @__PURE__ */ jsx4("span", { className: clsx4("wg_navigationNavList__branch"), children: entry.group.name }),
464
- /* @__PURE__ */ jsx4(WgNavigationBranchToggle, { branchKey: entry.key, label: entry.group.name, collapsed: props.collapsed, onToggle: props.onToggle }),
465
- /* @__PURE__ */ jsx4(WgNavigationNavList, { group: entry.group, collapsed: props.collapsed, onToggle: props.onToggle, branchKey: entry.key })
466
- ] })
467
- ]
468
- },
469
- entry.key
470
- ))
471
- }
472
- );
386
+ className: clsx3("wg_navigationNavList__link", { "wg_navigationNavList__link--active": entry.doc.active }),
387
+ href: `/${entry.doc.id}/`,
388
+ title: entry.doc.label,
389
+ "aria-current": entry.doc.active ? "page" : void 0,
390
+ children: entry.doc.name
391
+ }
392
+ ),
393
+ entry.doc.children.length > 0 && /* @__PURE__ */ jsx3(WgNavigationNavList, { group: { name: entry.doc.name, path: props.group.path, docs: entry.doc.children, groups: [] } })
394
+ ] }),
395
+ entry.kind === "group" && /* @__PURE__ */ jsxs2(Fragment, { children: [
396
+ /* @__PURE__ */ jsx3("span", { className: clsx3("wg_navigationNavList__branch"), children: entry.group.name }),
397
+ /* @__PURE__ */ jsx3(WgNavigationNavList, { group: entry.group })
398
+ ] })
399
+ ] }, entry.key)) });
473
400
  };
474
401
 
475
402
  // src/component/widget/navigation/_wg-navigation-nav.tsx
476
- import { jsx as jsx5, jsxs as jsxs3 } from "hono/jsx/jsx-runtime";
403
+ import { jsx as jsx4, jsxs as jsxs3 } from "hono/jsx/jsx-runtime";
477
404
  var WgNavigationNav = (props) => {
478
- return /* @__PURE__ */ jsx5("nav", { className: clsx5("wg_navigationNav__root"), "aria-label": copy_nav_aria_label, children: /* @__PURE__ */ jsx5("div", { className: clsx5("wg_navigationNav__docs"), children: props.groups.map((group) => /* @__PURE__ */ jsxs3("section", { className: clsx5("wg_navigationNav__docGroup"), "aria-label": group.name, children: [
479
- /* @__PURE__ */ jsx5("div", { className: clsx5("wg_navigationNav__group"), children: group.name }),
480
- /* @__PURE__ */ jsx5(WgNavigationBranchToggle, { branchKey: `group:${JSON.stringify(group.path)}`, label: group.name, collapsed: props.collapsed, onToggle: props.onToggle }),
481
- /* @__PURE__ */ jsx5(WgNavigationNavList, { group, branchKey: `group:${JSON.stringify(group.path)}`, collapsed: props.collapsed, onToggle: props.onToggle })
405
+ return /* @__PURE__ */ jsx4("nav", { className: clsx4("wg_navigationNav__root"), "aria-label": copy_nav_aria_label, children: /* @__PURE__ */ jsx4("div", { className: clsx4("wg_navigationNav__docs"), children: props.groups.map((group) => /* @__PURE__ */ jsxs3("section", { className: clsx4("wg_navigationNav__docGroup"), "aria-label": group.name, children: [
406
+ /* @__PURE__ */ jsx4("div", { className: clsx4("wg_navigationNav__group"), children: group.name }),
407
+ /* @__PURE__ */ jsx4(WgNavigationNavList, { group })
482
408
  ] }, JSON.stringify(group.path))) }) });
483
409
  };
484
410
 
485
411
  // src/component/widget/navigation/_wg-navigation-scroll.tsx
486
- import clsx6 from "clsx";
412
+ import clsx5 from "clsx";
487
413
  import { useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "hono/jsx";
488
- import { jsx as jsx6 } from "hono/jsx/jsx-runtime";
414
+ import { jsx as jsx5 } from "hono/jsx/jsx-runtime";
489
415
  var WgNavigationScroll = (props) => {
490
416
  const [overflow, setOverflow] = useState({ above: false, below: false });
491
417
  const frameRef = useRef2(0);
@@ -530,11 +456,11 @@ var WgNavigationScroll = (props) => {
530
456
  }, [props.children, props.ready]);
531
457
  return (
532
458
  // biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: 부모의 링크 이벤트 위임이며 자식 a·button의 네이티브 키보드 동작을 그대로 소비한다
533
- /* @__PURE__ */ jsx6(
459
+ /* @__PURE__ */ jsx5(
534
460
  "div",
535
461
  {
536
462
  ref: props.ready ? props.portRef : void 0,
537
- className: clsx6(
463
+ className: clsx5(
538
464
  "wg_navigation__scroll",
539
465
  props.kind === "documents" && "wg_navigation__documents",
540
466
  props.kind === "outline" && "wg_navigation__headings",
@@ -552,7 +478,7 @@ var WgNavigationScroll = (props) => {
552
478
  };
553
479
 
554
480
  // src/component/widget/navigation/_wg-navigation-toc.tsx
555
- import clsx7 from "clsx";
481
+ import clsx6 from "clsx";
556
482
  import { useLayoutEffect as useLayoutEffect3, useState as useState2 } from "hono/jsx";
557
483
 
558
484
  // src/component/widget/navigation/_constant/reading-line.ts
@@ -574,7 +500,7 @@ var findHashTarget = (hash) => {
574
500
  };
575
501
 
576
502
  // src/component/widget/navigation/_wg-navigation-toc.tsx
577
- import { jsx as jsx7, jsxs as jsxs4 } from "hono/jsx/jsx-runtime";
503
+ import { jsx as jsx6, jsxs as jsxs4 } from "hono/jsx/jsx-runtime";
578
504
  var WgNavigationToc = (props) => {
579
505
  const [currentSlug, setCurrentSlug] = useState2();
580
506
  useLayoutEffect3(() => {
@@ -607,75 +533,37 @@ var WgNavigationToc = (props) => {
607
533
  document.removeEventListener("DOMContentLoaded", handleReadingPositionChange);
608
534
  };
609
535
  }, [props.groups]);
610
- return /* @__PURE__ */ jsxs4("nav", { className: clsx7("wg_navigationToc__root"), "aria-label": copy_nav_toc_label, children: [
611
- /* @__PURE__ */ jsx7("div", { className: clsx7("wg_navigationToc__label"), children: copy_nav_toc_label }),
612
- props.groups.map((group) => {
613
- const currentIndex = group.sections.findIndex((section) => section.heading.slug === currentSlug || section.subs.some((sub) => sub.heading.slug === currentSlug));
614
- const partKey = `outline:${props.pageId}:part:${group.sections[0].heading.slug}`;
615
- return /* @__PURE__ */ jsxs4(
616
- "div",
617
- {
618
- className: clsx7("wg_navigationToc__groupSection", { "wg_navigationToc__groupSection--named": group.part !== void 0 }),
619
- children: [
620
- group.part !== void 0 && /* @__PURE__ */ jsx7("div", { className: clsx7("wg_navigationToc__group"), children: group.part }),
621
- group.part !== void 0 && /* @__PURE__ */ jsx7(WgNavigationBranchToggle, { branchKey: partKey, label: group.part, collapsed: props.collapsed, onToggle: props.onToggle }),
622
- /* @__PURE__ */ jsx7("ul", { className: clsx7("wg_navigationToc__list"), id: toNavigationBranchId(partKey), hidden: props.collapsed[partKey] === true, children: group.sections.map((section, index) => {
623
- const currentSubIndex = section.subs.findIndex((sub) => sub.heading.slug === currentSlug);
624
- const sectionKey = `outline:${props.pageId}:heading:${section.heading.slug}`;
625
- return /* @__PURE__ */ jsxs4(
626
- "li",
627
- {
628
- className: clsx7("wg_navigationToc__item", {
629
- "wg_navigationToc__item--trail": index < currentIndex,
630
- "wg_navigationToc__item--current": index === currentIndex
631
- }),
632
- children: [
633
- /* @__PURE__ */ jsx7(
634
- "a",
635
- {
636
- className: clsx7("wg_navigationToc__link", { "wg_navigationToc__link--active": section.heading.slug === currentSlug }),
637
- href: `#${section.heading.slug}`,
638
- "data-toc-link": "",
639
- "aria-current": section.heading.slug === currentSlug ? "location" : void 0,
640
- children: section.heading.text
641
- }
642
- ),
643
- section.subs.length > 0 && /* @__PURE__ */ jsx7(WgNavigationBranchToggle, { branchKey: sectionKey, label: section.heading.text, collapsed: props.collapsed, onToggle: props.onToggle }),
644
- section.subs.length > 0 && /* @__PURE__ */ jsx7("ul", { className: clsx7("wg_navigationToc__sub"), id: toNavigationBranchId(sectionKey), hidden: props.collapsed[sectionKey] === true, children: section.subs.map((sub, subIndex) => /* @__PURE__ */ jsx7(
645
- "li",
646
- {
647
- className: clsx7("wg_navigationToc__subItem", {
648
- "wg_navigationToc__subItem--trail": subIndex < currentSubIndex,
649
- "wg_navigationToc__subItem--current": subIndex === currentSubIndex
650
- }),
651
- children: /* @__PURE__ */ jsx7(
652
- "a",
653
- {
654
- className: clsx7("wg_navigationToc__subLink", { "wg_navigationToc__subLink--active": sub.heading.slug === currentSlug }),
655
- href: `#${sub.heading.slug}`,
656
- "data-toc-sub-link": "",
657
- "aria-current": sub.heading.slug === currentSlug ? "location" : void 0,
658
- children: sub.heading.text
659
- }
660
- )
661
- },
662
- sub.heading.slug
663
- )) })
664
- ]
665
- },
666
- section.heading.slug
667
- );
668
- }) })
669
- ]
670
- },
671
- group.sections[0].heading.slug
672
- );
673
- })
536
+ return /* @__PURE__ */ jsxs4("nav", { className: clsx6("wg_navigationToc__root"), "aria-label": copy_nav_toc_label, children: [
537
+ /* @__PURE__ */ jsx6("div", { className: clsx6("wg_navigationToc__label"), children: copy_nav_toc_label }),
538
+ props.groups.map((group) => /* @__PURE__ */ jsxs4("div", { className: clsx6("wg_navigationToc__groupSection", { "wg_navigationToc__groupSection--named": group.part !== void 0 }), children: [
539
+ group.part !== void 0 && /* @__PURE__ */ jsx6("div", { className: clsx6("wg_navigationToc__group"), children: group.part }),
540
+ /* @__PURE__ */ jsx6("ul", { className: clsx6("wg_navigationToc__list"), children: group.sections.map((section) => /* @__PURE__ */ jsxs4("li", { className: clsx6("wg_navigationToc__item"), children: [
541
+ /* @__PURE__ */ jsx6(
542
+ "a",
543
+ {
544
+ className: clsx6("wg_navigationToc__link", { "wg_navigationToc__link--active": section.heading.slug === currentSlug }),
545
+ href: `#${section.heading.slug}`,
546
+ "data-toc-link": "",
547
+ "aria-current": section.heading.slug === currentSlug ? "location" : void 0,
548
+ children: section.heading.text
549
+ }
550
+ ),
551
+ section.subs.length > 0 && /* @__PURE__ */ jsx6("ul", { className: clsx6("wg_navigationToc__sub"), children: section.subs.map((sub) => /* @__PURE__ */ jsx6("li", { className: clsx6("wg_navigationToc__subItem"), children: /* @__PURE__ */ jsx6(
552
+ "a",
553
+ {
554
+ className: clsx6("wg_navigationToc__subLink", { "wg_navigationToc__subLink--active": sub.heading.slug === currentSlug }),
555
+ href: `#${sub.heading.slug}`,
556
+ "data-toc-sub-link": "",
557
+ "aria-current": sub.heading.slug === currentSlug ? "location" : void 0,
558
+ children: sub.heading.text
559
+ }
560
+ ) }, sub.heading.slug)) })
561
+ ] }, section.heading.slug)) })
562
+ ] }, group.sections[0].heading.slug))
674
563
  ] });
675
564
  };
676
565
 
677
566
  // src/store/navigation/navigation-storage.ts
678
- var navigation_tree_storage_key = "for-humanity:navigation-tree";
679
567
  var navigation_storage_version = 1;
680
568
  var navigation_scroll_storage_key = "for-humanity:navigation-scroll";
681
569
 
@@ -698,20 +586,6 @@ var toNavigationScrollState = (value) => {
698
586
  return { positions: Object.fromEntries(Object.entries(positions).filter((entry) => entry[1] !== void 0)) };
699
587
  };
700
588
 
701
- // src/store/navigation/use-navigation-tree-store.ts
702
- import { useSyncExternalStore } from "hono/jsx";
703
-
704
- // src/store/navigation/_constant/tree.ts
705
- var tree_server_state = { collapsed: {} };
706
-
707
- // src/store/navigation/use-navigation-tree-store.ts
708
- var useNavigationTreeStore = (tree) => {
709
- const subscribe = tree === void 0 ? () => () => {
710
- } : tree.subscribe;
711
- const getSnapshot = tree === void 0 ? () => tree_server_state : tree.getState;
712
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
713
- };
714
-
715
589
  // src/util/dom/reveal-hash-target.ts
716
590
  var revealHashTarget = (hash) => {
717
591
  const target = findHashTarget(hash);
@@ -722,9 +596,8 @@ var revealHashTarget = (hash) => {
722
596
  };
723
597
 
724
598
  // src/component/widget/navigation/wg-navigation.tsx
725
- import { jsx as jsx8, jsxs as jsxs5 } from "hono/jsx/jsx-runtime";
599
+ import { jsx as jsx7, jsxs as jsxs5 } from "hono/jsx/jsx-runtime";
726
600
  var WgNavigation = (props) => {
727
- const navigationTreeStore = useNavigationTreeStore(props.stores?.tree);
728
601
  const [layout, setLayout] = useState3(() => {
729
602
  if (props.stores === void 0) return "desktop";
730
603
  if (matchMedia(navigation_mobile_query).matches) return "drawer";
@@ -803,9 +676,6 @@ var WgNavigation = (props) => {
803
676
  documents.dispatchEvent(new Event("scroll"));
804
677
  outlineRef.current.dispatchEvent(new Event("scroll"));
805
678
  };
806
- const handleBranchToggle = (key) => {
807
- props.stores?.tree.setState((state) => ({ collapsed: { ...state.collapsed, [key]: state.collapsed[key] !== true } }));
808
- };
809
679
  const handleDrawerClose = (_event) => {
810
680
  if (dialogRef.current?.open === true) return;
811
681
  document.body.classList.remove("wg_shell__root--drawerOpen");
@@ -859,7 +729,6 @@ var WgNavigation = (props) => {
859
729
  focusRef.current = {
860
730
  navigation: document.activeElement.closest("[data-navigation]") !== null,
861
731
  drawer: document.activeElement === openButtonRef.current || document.activeElement.closest("[data-navigation-drawer]") !== null,
862
- branch: document.activeElement.getAttribute("data-navigation-toggle"),
863
732
  href: document.activeElement.getAttribute("href")
864
733
  };
865
734
  }
@@ -871,28 +740,10 @@ var WgNavigation = (props) => {
871
740
  const handlePageShow = (event) => {
872
741
  if (!event.persisted || props.stores === void 0) return;
873
742
  restorePendingRef.current = true;
874
- flushSync(() => {
875
- props.stores?.tree.persist.rehydrate();
876
- props.stores?.scroll.persist.rehydrate();
877
- });
743
+ flushSync(() => props.stores?.scroll.persist.rehydrate());
878
744
  handleLayoutChange();
879
745
  restoreScroll();
880
746
  };
881
- const handleStorageChange = (event) => {
882
- if (event.key === navigation_tree_storage_key || event.key === null) {
883
- flushSync(() => props.stores?.tree.persist.rehydrate());
884
- }
885
- };
886
- const handleTreeChange = (state) => {
887
- if (!(document.activeElement instanceof HTMLElement)) return;
888
- for (const button of document.querySelectorAll("[data-navigation-toggle]")) {
889
- const key = button.dataset.navigationToggle;
890
- const controls = button.getAttribute("aria-controls");
891
- if (key === void 0 || controls === null || state.collapsed[key] !== true) continue;
892
- const branch = document.getElementById(controls);
893
- if (branch?.contains(document.activeElement)) button.focus({ preventScroll: true });
894
- }
895
- };
896
747
  useLayoutEffect4(() => {
897
748
  if (props.stores === void 0) return;
898
749
  mobileRef.current = matchMedia(navigation_mobile_query);
@@ -901,8 +752,6 @@ var WgNavigation = (props) => {
901
752
  wideRef.current.addEventListener("change", handleLayoutChange);
902
753
  addEventListener("pagehide", saveScroll);
903
754
  addEventListener("pageshow", handlePageShow);
904
- addEventListener("storage", handleStorageChange);
905
- const unsubscribeTree = props.stores.tree.subscribe(handleTreeChange);
906
755
  return () => {
907
756
  mobileRef.current?.removeEventListener("change", handleLayoutChange);
908
757
  wideRef.current?.removeEventListener("change", handleLayoutChange);
@@ -910,8 +759,6 @@ var WgNavigation = (props) => {
910
759
  wideRef.current = null;
911
760
  removeEventListener("pagehide", saveScroll);
912
761
  removeEventListener("pageshow", handlePageShow);
913
- removeEventListener("storage", handleStorageChange);
914
- unsubscribeTree();
915
762
  document.body.classList.remove("wg_shell__root--drawerOpen");
916
763
  };
917
764
  }, [props.stores]);
@@ -926,10 +773,8 @@ var WgNavigation = (props) => {
926
773
  if (layout === "drawer") {
927
774
  if (focusRef.current.navigation) openButtonRef.current?.focus({ preventScroll: true });
928
775
  } else if (focusRef.current.navigation && navigation !== null) {
929
- const target = [...navigation.querySelectorAll("a[href], button")].find((element) => {
930
- if (focusRef.current === null) return false;
931
- return focusRef.current.branch !== null ? element.getAttribute("data-navigation-toggle") === focusRef.current.branch : focusRef.current.href !== null && element.getAttribute("href") === focusRef.current.href;
932
- });
776
+ const href = focusRef.current.href;
777
+ const target = [...navigation.querySelectorAll("a[href]")].find((element) => element.getAttribute("href") === href);
933
778
  target?.focus({ preventScroll: true });
934
779
  } else if (focusRef.current.drawer) {
935
780
  brandRef.current?.focus({ preventScroll: true });
@@ -946,56 +791,41 @@ var WgNavigation = (props) => {
946
791
  };
947
792
  }, [layout, props.stores]);
948
793
  return /* @__PURE__ */ jsxs5(Fragment2, { children: [
949
- /* @__PURE__ */ jsxs5("div", { className: clsx8("wg_navigation__sidebar", props.stores !== void 0 && "wg_navigation__sidebar--navigationReady"), children: [
950
- /* @__PURE__ */ jsxs5("div", { className: clsx8("wg_navigation__brandRow"), children: [
951
- /* @__PURE__ */ jsx8(
794
+ /* @__PURE__ */ jsxs5("div", { className: clsx7("wg_navigation__sidebar", props.stores !== void 0 && "wg_navigation__sidebar--navigationReady"), children: [
795
+ /* @__PURE__ */ jsxs5("div", { className: clsx7("wg_navigation__brandRow"), children: [
796
+ /* @__PURE__ */ jsx7(
952
797
  "a",
953
798
  {
954
799
  ref: props.stores === void 0 ? void 0 : brandRef,
955
- className: clsx8("wg_navigation__brand"),
800
+ className: clsx7("wg_navigation__brand"),
956
801
  href: "/",
957
802
  "aria-current": props.data.home ? "page" : void 0,
958
803
  children: props.data.title
959
804
  }
960
805
  ),
961
- /* @__PURE__ */ jsx8(
806
+ /* @__PURE__ */ jsx7(
962
807
  "button",
963
808
  {
964
809
  ref: props.stores === void 0 ? void 0 : openButtonRef,
965
- className: clsx8("wg_navigation__menuToggle", props.stores !== void 0 && layout === "drawer" && "wg_navigation__menuToggle--visible"),
810
+ className: clsx7("wg_navigation__menuToggle", props.stores !== void 0 && layout === "drawer" && "wg_navigation__menuToggle--visible"),
966
811
  type: "button",
967
812
  "aria-label": copy_nav_open,
968
813
  "aria-controls": "fh-navigation-drawer",
969
814
  "aria-expanded": String(drawerOpen),
970
815
  "data-navigation-open": "",
971
816
  onClick: handleOpenButtonClick,
972
- children: /* @__PURE__ */ jsx8("svg", { className: clsx8("wg_navigation__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx8("path", { d: "M4 6h16M4 12h16M4 18h16" }) })
817
+ children: /* @__PURE__ */ jsx7("svg", { className: clsx7("wg_navigation__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx7("path", { d: "M4 6h16M4 12h16M4 18h16" }) })
973
818
  }
974
819
  )
975
820
  ] }),
976
- layout !== "drawer" && /* @__PURE__ */ jsx8("div", { ref: props.stores === void 0 ? void 0 : navigationRef, className: clsx8("wg_navigation__navigation"), "data-navigation": "", children: /* @__PURE__ */ jsx8(WgNavigationScroll, { portRef: documentsRef, kind: "documents", ready: props.stores !== void 0, onScroll: saveScroll, onClick: handleNavigationClick, children: /* @__PURE__ */ jsx8(
977
- WgNavigationNav,
978
- {
979
- groups: props.data.groups,
980
- collapsed: navigationTreeStore.collapsed,
981
- onToggle: props.stores === void 0 ? void 0 : handleBranchToggle
982
- }
983
- ) }) })
821
+ layout !== "drawer" && /* @__PURE__ */ jsx7("div", { ref: props.stores === void 0 ? void 0 : navigationRef, className: clsx7("wg_navigation__navigation"), "data-navigation": "", children: /* @__PURE__ */ jsx7(WgNavigationScroll, { portRef: documentsRef, kind: "documents", ready: props.stores !== void 0, onScroll: saveScroll, onClick: handleNavigationClick, children: /* @__PURE__ */ jsx7(WgNavigationNav, { groups: props.data.groups }) }) })
984
822
  ] }),
985
- /* @__PURE__ */ jsx8("aside", { className: clsx8("wg_navigation__tocRail"), "data-navigation-rail": "", children: /* @__PURE__ */ jsx8("div", { className: clsx8("wg_navigation__outline"), "data-navigation-outline": "", children: /* @__PURE__ */ jsx8(WgNavigationScroll, { portRef: outlineRef, kind: "outline", ready: props.stores !== void 0, onScroll: saveScroll, onClick: handleNavigationClick, children: props.data.outline.length > 0 && /* @__PURE__ */ jsx8(
986
- WgNavigationToc,
987
- {
988
- groups: props.data.outline,
989
- pageId: props.data.pageId,
990
- collapsed: navigationTreeStore.collapsed,
991
- onToggle: props.stores === void 0 ? void 0 : handleBranchToggle
992
- }
993
- ) }) }) }),
823
+ /* @__PURE__ */ jsx7("aside", { className: clsx7("wg_navigation__tocRail"), "data-navigation-rail": "", children: /* @__PURE__ */ jsx7("div", { className: clsx7("wg_navigation__outline"), "data-navigation-outline": "", children: /* @__PURE__ */ jsx7(WgNavigationScroll, { portRef: outlineRef, kind: "outline", ready: props.stores !== void 0, onScroll: saveScroll, onClick: handleNavigationClick, children: props.data.outline.length > 0 && /* @__PURE__ */ jsx7(WgNavigationToc, { groups: props.data.outline }) }) }) }),
994
824
  /* @__PURE__ */ jsxs5(
995
825
  "dialog",
996
826
  {
997
827
  ref: props.stores === void 0 ? void 0 : dialogRef,
998
- className: clsx8("wg_navigation__drawer"),
828
+ className: clsx7("wg_navigation__drawer"),
999
829
  id: "fh-navigation-drawer",
1000
830
  "aria-labelledby": "fh-navigation-title",
1001
831
  "data-navigation-drawer": "",
@@ -1003,11 +833,11 @@ var WgNavigation = (props) => {
1003
833
  onCancel: handleDrawerCancel,
1004
834
  onClick: handleDrawerClick,
1005
835
  children: [
1006
- /* @__PURE__ */ jsxs5("div", { className: clsx8("wg_navigation__drawerHeader"), children: [
1007
- /* @__PURE__ */ jsx8("h2", { className: clsx8("wg_navigation__drawerTitle"), id: "fh-navigation-title", children: copy_nav_title }),
1008
- /* @__PURE__ */ jsx8("button", { className: clsx8("wg_navigation__drawerClose"), type: "button", "aria-label": copy_nav_close, "data-navigation-close": "", onClick: handleCloseButtonClick, children: /* @__PURE__ */ jsx8("svg", { className: clsx8("wg_navigation__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx8("path", { d: "m6 6 12 12M18 6 6 18" }) }) })
836
+ /* @__PURE__ */ jsxs5("div", { className: clsx7("wg_navigation__drawerHeader"), children: [
837
+ /* @__PURE__ */ jsx7("h2", { className: clsx7("wg_navigation__drawerTitle"), id: "fh-navigation-title", children: copy_nav_title }),
838
+ /* @__PURE__ */ jsx7("button", { className: clsx7("wg_navigation__drawerClose"), type: "button", "aria-label": copy_nav_close, "data-navigation-close": "", onClick: handleCloseButtonClick, children: /* @__PURE__ */ jsx7("svg", { className: clsx7("wg_navigation__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx7("path", { d: "m6 6 12 12M18 6 6 18" }) }) })
1009
839
  ] }),
1010
- /* @__PURE__ */ jsx8("div", { className: clsx8("wg_navigation__drawerContent"), "data-navigation-content": "", children: layout === "drawer" && /* @__PURE__ */ jsx8("div", { ref: props.stores === void 0 ? void 0 : drawerNavigationRef, className: clsx8("wg_navigation__navigation"), "data-navigation": "", children: /* @__PURE__ */ jsx8(
840
+ /* @__PURE__ */ jsx7("div", { className: clsx7("wg_navigation__drawerContent"), "data-navigation-content": "", children: layout === "drawer" && /* @__PURE__ */ jsx7("div", { ref: props.stores === void 0 ? void 0 : drawerNavigationRef, className: clsx7("wg_navigation__navigation"), "data-navigation": "", children: /* @__PURE__ */ jsx7(
1011
841
  WgNavigationScroll,
1012
842
  {
1013
843
  portRef: drawerDocumentsRef,
@@ -1015,14 +845,7 @@ var WgNavigation = (props) => {
1015
845
  ready: props.stores !== void 0,
1016
846
  onScroll: saveScroll,
1017
847
  onClick: handleNavigationClick,
1018
- children: /* @__PURE__ */ jsx8(
1019
- WgNavigationNav,
1020
- {
1021
- groups: props.data.groups,
1022
- collapsed: navigationTreeStore.collapsed,
1023
- onToggle: props.stores === void 0 ? void 0 : handleBranchToggle
1024
- }
1025
- )
848
+ children: /* @__PURE__ */ jsx7(WgNavigationNav, { groups: props.data.groups })
1026
849
  }
1027
850
  ) }) })
1028
851
  ]
@@ -1035,7 +858,7 @@ var WgNavigation = (props) => {
1035
858
  var heading_highlight_hold_ms = 3e3;
1036
859
 
1037
860
  // src/component/widget/shell-controls/wg-shell-controls.tsx
1038
- import { jsx as jsx9, jsxs as jsxs6 } from "hono/jsx/jsx-runtime";
861
+ import { jsx as jsx8, jsxs as jsxs6 } from "hono/jsx/jsx-runtime";
1039
862
  var WgShellControls = (props) => {
1040
863
  const headingRef = useRef4(null);
1041
864
  const timerRef = useRef4(0);
@@ -1130,61 +953,61 @@ var WgShellControls = (props) => {
1130
953
  return () => source.close();
1131
954
  }, [props.reload]);
1132
955
  return /* @__PURE__ */ jsxs6(Fragment3, { children: [
1133
- /* @__PURE__ */ jsx9("div", { className: clsx9("wg_shellControls__navigation"), children: /* @__PURE__ */ jsx9(WgNavigation, { data: props.data, stores: props.stores }) }),
1134
- /* @__PURE__ */ jsx9(WgCursorFace, { ready: props.stores !== void 0 })
956
+ /* @__PURE__ */ jsx8("div", { className: clsx8("wg_shellControls__navigation"), children: /* @__PURE__ */ jsx8(WgNavigation, { data: props.data, stores: props.stores }) }),
957
+ /* @__PURE__ */ jsx8(WgCursorFace, { ready: props.stores !== void 0 })
1135
958
  ] });
1136
959
  };
1137
960
 
1138
961
  // src/component/widget/shell/wg-shell.tsx
1139
- import { jsx as jsx10, jsxs as jsxs7 } from "hono/jsx/jsx-runtime";
962
+ import { jsx as jsx9, jsxs as jsxs7 } from "hono/jsx/jsx-runtime";
1140
963
  var WgShell = (props) => {
1141
964
  const navigationData = toNavigationData({ site: props.site, docs: props.docs, current: props.current, outline: props.outline });
1142
965
  return /* @__PURE__ */ jsxs7("html", { lang: "ko", children: [
1143
966
  /* @__PURE__ */ jsxs7("head", { children: [
1144
- /* @__PURE__ */ jsx10("meta", { charSet: "utf-8" }),
1145
- /* @__PURE__ */ jsx10("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
1146
- props.site.description !== void 0 && /* @__PURE__ */ jsx10("meta", { name: "description", content: props.site.description }),
1147
- /* @__PURE__ */ jsx10("title", { children: props.title === void 0 ? props.site.title : `${props.title} \xB7 ${props.site.title}` }),
1148
- /* @__PURE__ */ jsx10("link", { rel: "icon", href: asset_favicon_path, type: "image/svg+xml" }),
1149
- /* @__PURE__ */ jsx10("style", { dangerouslySetInnerHTML: { __html: props.assets.fontCss } }),
1150
- props.assets.preload.map((href) => /* @__PURE__ */ jsx10("link", { rel: "preload", href, as: "font", type: "font/woff2", crossOrigin: "" }, href)),
1151
- /* @__PURE__ */ jsx10("link", { rel: "stylesheet", href: props.assets.stylePath })
967
+ /* @__PURE__ */ jsx9("meta", { charSet: "utf-8" }),
968
+ /* @__PURE__ */ jsx9("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
969
+ props.site.description !== void 0 && /* @__PURE__ */ jsx9("meta", { name: "description", content: props.site.description }),
970
+ /* @__PURE__ */ jsx9("title", { children: props.title === void 0 ? props.site.title : `${props.title} \xB7 ${props.site.title}` }),
971
+ /* @__PURE__ */ jsx9("link", { rel: "icon", href: asset_favicon_path, type: "image/svg+xml" }),
972
+ /* @__PURE__ */ jsx9("style", { dangerouslySetInnerHTML: { __html: props.assets.fontCss } }),
973
+ props.assets.preload.map((href) => /* @__PURE__ */ jsx9("link", { rel: "preload", href, as: "font", type: "font/woff2", crossOrigin: "" }, href)),
974
+ /* @__PURE__ */ jsx9("link", { rel: "stylesheet", href: props.assets.stylePath })
1152
975
  ] }),
1153
- /* @__PURE__ */ jsxs7("body", { className: clsx10("wg_shell__root"), children: [
1154
- /* @__PURE__ */ jsx10("div", { className: clsx10("wg_shell__browserRoot"), "data-shell-browser-root": "", "data-shell-reload": props.assets.reload ? "" : void 0, children: /* @__PURE__ */ jsx10(WgShellControls, { data: navigationData, reload: props.assets.reload }) }),
1155
- /* @__PURE__ */ jsx10("script", { type: "application/json", id: "fh-navigation-data", dangerouslySetInnerHTML: { __html: toNavigationJson(navigationData) } }),
1156
- /* @__PURE__ */ jsx10("script", { dangerouslySetInnerHTML: { __html: props.assets.browserScript } }),
1157
- /* @__PURE__ */ jsx10("main", { className: clsx10("wg_shell__main"), children: props.children })
976
+ /* @__PURE__ */ jsxs7("body", { className: clsx9("wg_shell__root"), children: [
977
+ /* @__PURE__ */ jsx9("div", { className: clsx9("wg_shell__browserRoot"), "data-shell-browser-root": "", "data-shell-reload": props.assets.reload ? "" : void 0, children: /* @__PURE__ */ jsx9(WgShellControls, { data: navigationData, reload: props.assets.reload }) }),
978
+ /* @__PURE__ */ jsx9("script", { type: "application/json", id: "fh-navigation-data", dangerouslySetInnerHTML: { __html: toNavigationJson(navigationData) } }),
979
+ /* @__PURE__ */ jsx9("script", { dangerouslySetInnerHTML: { __html: props.assets.browserScript } }),
980
+ /* @__PURE__ */ jsx9("main", { className: clsx9("wg_shell__main"), children: props.children })
1158
981
  ] })
1159
982
  ] });
1160
983
  };
1161
984
 
1162
985
  // src/page/doc/pg-doc.tsx
1163
- import { jsx as jsx11 } from "hono/jsx/jsx-runtime";
986
+ import { jsx as jsx10 } from "hono/jsx/jsx-runtime";
1164
987
  var PgDoc = (props) => {
1165
- return /* @__PURE__ */ jsx11(WgShell, { site: props.site, docs: props.docs, assets: props.assets, title: props.doc.data.name, current: props.doc.id, outline: props.doc.outline, children: /* @__PURE__ */ jsx11(WgProse, { html: props.doc.html }) });
988
+ return /* @__PURE__ */ jsx10(WgShell, { site: props.site, docs: props.docs, assets: props.assets, title: props.doc.data.name, current: props.doc.id, outline: props.doc.outline, children: /* @__PURE__ */ jsx10(WgProse, { html: props.doc.html }) });
1166
989
  };
1167
990
 
1168
991
  // src/page/home/pg-home.tsx
1169
- import { jsx as jsx12 } from "hono/jsx/jsx-runtime";
992
+ import { jsx as jsx11 } from "hono/jsx/jsx-runtime";
1170
993
  var PgHome = (props) => {
1171
- return /* @__PURE__ */ jsx12(WgShell, { site: props.site, docs: props.docs, assets: props.assets, outline: props.home?.outline, children: props.home === void 0 ? /* @__PURE__ */ jsx12(WgProse, { head: { title: props.site.title, lead: copy_home_missing } }) : /* @__PURE__ */ jsx12(WgProse, { html: props.home.html }) });
994
+ return /* @__PURE__ */ jsx11(WgShell, { site: props.site, docs: props.docs, assets: props.assets, outline: props.home?.outline, children: props.home === void 0 ? /* @__PURE__ */ jsx11(WgProse, { head: { title: props.site.title, lead: copy_home_missing } }) : /* @__PURE__ */ jsx11(WgProse, { html: props.home.html }) });
1172
995
  };
1173
996
 
1174
997
  // src/entry/cli/_function/create-app.tsx
1175
- import { jsx as jsx13 } from "hono/jsx/jsx-runtime";
998
+ import { jsx as jsx12 } from "hono/jsx/jsx-runtime";
1176
999
  var toHtml = (page) => {
1177
1000
  return html`<!DOCTYPE html>${page}`;
1178
1001
  };
1179
1002
  var createApp = (options) => {
1180
1003
  const app = new Hono();
1181
- app.get("/", (c) => c.html(toHtml(/* @__PURE__ */ jsx13(PgHome, { site: options.site, docs: options.store.docs, assets: options.assets, home: options.store.home }))));
1004
+ app.get("/", (c) => c.html(toHtml(/* @__PURE__ */ jsx12(PgHome, { site: options.site, docs: options.store.docs, assets: options.assets, home: options.store.home }))));
1182
1005
  app.get(
1183
1006
  "/:slug{.+}/",
1184
1007
  ssgParams(() => options.store.docs.map((doc) => ({ slug: doc.id }))),
1185
1008
  (c) => {
1186
1009
  const doc = options.store.docs.find((entry) => entry.id === c.req.param("slug"));
1187
- return doc === void 0 ? c.notFound() : c.html(toHtml(/* @__PURE__ */ jsx13(PgDoc, { site: options.site, docs: options.store.docs, assets: options.assets, doc })));
1010
+ return doc === void 0 ? c.notFound() : c.html(toHtml(/* @__PURE__ */ jsx12(PgDoc, { site: options.site, docs: options.store.docs, assets: options.assets, doc })));
1188
1011
  }
1189
1012
  );
1190
1013
  return app;
@@ -1227,6 +1050,9 @@ var createDevApp = (options) => {
1227
1050
  );
1228
1051
  app.get(`/${asset_dir}/*`, handleAsset);
1229
1052
  app.get(asset_favicon_path, handleAsset);
1053
+ if (options.crawling !== void 0) {
1054
+ app.on("GET", [crawling_robots_path, crawling_sitemap_path], (c) => options.crawling?.fetch(c.req.raw, c.env) ?? c.notFound());
1055
+ }
1230
1056
  app.all("/*", (c) => options.pages.fetch(c.req.raw, c.env));
1231
1057
  return app;
1232
1058
  };
@@ -1497,14 +1323,14 @@ function widenLabelGaps(rows) {
1497
1323
  });
1498
1324
  }
1499
1325
  function gridToSvg(ascii) {
1500
- const cw = 7.2, ch = 17, fs = 12;
1326
+ const cw = 6.336, ch = 17, fs = 12;
1501
1327
  const rows = widenLabelGaps(ascii.replace(/\s+$/, "").split("\n"));
1502
1328
  const cols = Math.max.apply(null, rows.map((r) => r.length));
1503
1329
  const f = (n) => n.toFixed(1);
1504
1330
  let path = "", bold = "", dashed = "", arcs = "", tris = "", marks = "", dots = "", texts = "";
1505
1331
  const isText = (chr) => chr !== void 0 && chr !== " " && chr !== ZW && LINES[chr] === void 0 && ARROWS[chr] === void 0 && chr !== "\u25C7";
1506
1332
  const center = (c) => c * cw + cw / 2;
1507
- const textWidth = (chars) => chars.reduce((w, chr) => w + (WIDE.test(chr) ? fs : cw), 0);
1333
+ const textWidth = (chars) => chars.reduce((w, chr) => w + (WIDE.test(chr) ? cw * 2 : cw), 0);
1508
1334
  rows.forEach((row, r) => {
1509
1335
  const cy = r * ch + ch / 2, y0 = r * ch, y1 = y0 + ch;
1510
1336
  let run = null;
@@ -1995,7 +1821,7 @@ var readDocs = async (options) => {
1995
1821
  paths.map(async (path) => {
1996
1822
  const id = path.replace(/\.mdx?$/i, "").split(sep2).join("/").toLowerCase();
1997
1823
  const segments = id.split("/");
1998
- if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || segment === "index.html") || /[#?%*:\\]/.test(id) || /[\p{Cc}]/u.test(id) || segments[0] === asset_dir || segments[0] === asset_favicon_path.slice(1)) {
1824
+ if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || segment === "index.html") || /[#?%*:\\]/.test(id) || /[\p{Cc}]/u.test(id) || options.reserved?.includes(segments[0]) === true || segments[0] === asset_dir || segments[0] === asset_favicon_path.slice(1)) {
1999
1825
  throw new Error(`${copy_error_doc_id}: ${path}`);
2000
1826
  }
2001
1827
  const source = await readFile2(join(options.root, path), "utf8");
@@ -2067,6 +1893,30 @@ var readHome = async (options) => {
2067
1893
  return { html: String(file), outline: { headings: fh.headings, sections: fh.sections } };
2068
1894
  };
2069
1895
 
1896
+ // src/entry/cli/_function/to-crawling-app.ts
1897
+ import { Hono as Hono3 } from "hono";
1898
+ import { html as html2 } from "hono/html";
1899
+ var toCrawlingApp = (params) => {
1900
+ const app = new Hono3();
1901
+ app.get(crawling_robots_path, (c) => c.text(`User-agent: *
1902
+ Allow: /
1903
+
1904
+ Sitemap: ${params.url}${crawling_sitemap_path}
1905
+ `));
1906
+ app.get(
1907
+ crawling_sitemap_path,
1908
+ (_c) => new Response(
1909
+ html2`<?xml version="1.0" encoding="UTF-8"?>
1910
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
1911
+ <url><loc>${params.url}/</loc></url>
1912
+ ${params.store.docs.map((doc) => html2`<url><loc>${params.url}/${doc.id.split("/").map(encodeURIComponent).join("/")}/</loc></url>`)}
1913
+ </urlset>`.toString(),
1914
+ { headers: { "Content-Type": "application/xml; charset=utf-8" } }
1915
+ )
1916
+ );
1917
+ return app;
1918
+ };
1919
+
2070
1920
  // src/type/site-config.ts
2071
1921
  import { z as z3 } from "zod";
2072
1922
 
@@ -2090,6 +1940,10 @@ var siteConfigSchema = z3.object({
2090
1940
  * HTML 설명 메타데이터 · 선택
2091
1941
  */
2092
1942
  description: z3.string().optional(),
1943
+ /**
1944
+ * 공개 사이트 루트 URL · 지정할 때만 robots.txt와 sitemap.xml 생성
1945
+ */
1946
+ url: z3.url({ protocol: /^https?$/ }).transform((value) => new URL(value)).refine((value) => value.username === "" && value.password === "" && value.pathname === "/" && value.search === "" && value.hash === "", copy_error_site_url).transform((value) => value.origin).optional(),
2093
1947
  /**
2094
1948
  * 탐색 묶음 경로의 읽는 순서 · 미지정 형제 묶음은 뒤에서 이름순
2095
1949
  */
@@ -2179,7 +2033,7 @@ var main = async () => {
2179
2033
  const docsRoot = resolve3(docsDir);
2180
2034
  const outDir = join4(docsRoot, "dist");
2181
2035
  if (command === "preview") {
2182
- const app2 = new Hono3();
2036
+ const app2 = new Hono4();
2183
2037
  app2.use(
2184
2038
  "/*",
2185
2039
  serveStatic({
@@ -2200,31 +2054,24 @@ var main = async () => {
2200
2054
  throw new Error(`${copy_error_config}: ${parsedConfig.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join(", ")}`);
2201
2055
  }
2202
2056
  const siteConfig = parsedConfig.data;
2203
- const sans = toFontCss({ css: join4(kitRoot, font_sans_css), fontDir: asset_font_dir });
2204
2057
  const mono = toFontCss({ css: join4(kitRoot, font_mono_css), fontDir: asset_font_dir });
2205
2058
  const brand = toFontCss({ css: join4(kitRoot, font_brand_css), fontDir: asset_font_dir });
2206
- const sansPreload = [...sans.files].find((entry) => basename2(entry[1]) === font_sans_preload_file);
2207
- if (sansPreload === void 0) {
2208
- throw new Error(`${copy_error_font_preload}: ${font_sans_preload_file}`);
2209
- }
2210
- const fontCss = [sans.css, mono.css, brand.css].join("\n");
2059
+ const fontCss = [mono.css, brand.css].join("\n");
2211
2060
  const stylePath = toAssetPath({ path: asset_style_path, file: join4(kitRoot, "dist/cli.css") });
2212
2061
  const browserScript = readFileSync3(join4(kitRoot, "dist/browser.js"), "utf8");
2213
- const kitFiles = new Map([
2214
- [stylePath, join4(kitRoot, "dist/cli.css")],
2215
- [asset_favicon_path, join4(kitRoot, "src/asset/favicon.svg")],
2216
- ...sans.files,
2217
- ...mono.files,
2218
- ...brand.files
2219
- ]);
2062
+ const kitFiles = new Map([[stylePath, join4(kitRoot, "dist/cli.css")], [asset_favicon_path, join4(kitRoot, "src/asset/favicon.svg")], ...mono.files, ...brand.files]);
2220
2063
  const files = new Map(kitFiles);
2221
2064
  const processor = createProcessor({ site: siteConfig, root: docsRoot, files });
2222
- const [docs, home] = await Promise.all([readDocs({ root: docsRoot, processor }), readHome({ root: docsRoot, processor })]);
2065
+ const [docs, home] = await Promise.all([
2066
+ readDocs({ root: docsRoot, processor, reserved: siteConfig.url === void 0 ? void 0 : crawling_reserved_roots }),
2067
+ readHome({ root: docsRoot, processor })
2068
+ ]);
2223
2069
  const store = { docs, home };
2070
+ const crawling = siteConfig.url === void 0 ? void 0 : toCrawlingApp({ url: siteConfig.url, store });
2224
2071
  const app = createApp({
2225
2072
  site: siteConfig,
2226
2073
  store,
2227
- assets: { stylePath, browserScript, fontCss, preload: [...brand.files.keys(), sansPreload[0], ...mono.files.keys()], reload: command === "dev" }
2074
+ assets: { stylePath, browserScript, fontCss, preload: [...brand.files.keys(), ...mono.files.keys()], reload: command === "dev" }
2228
2075
  });
2229
2076
  if (command === "build") {
2230
2077
  await rm(outDir, { recursive: true, force: true });
@@ -2232,23 +2079,32 @@ var main = async () => {
2232
2079
  if (!result.success) {
2233
2080
  throw result.error;
2234
2081
  }
2082
+ const crawlerResult = crawling === void 0 ? void 0 : await toSSG(crawling, { writeFile, mkdir }, { dir: outDir });
2083
+ if (crawlerResult?.success === false) {
2084
+ throw crawlerResult.error;
2085
+ }
2235
2086
  for (const [url, file] of files) {
2236
2087
  await mkdir(dirname4(join4(outDir, url)), { recursive: true });
2237
2088
  await copyFile(file, join4(outDir, url));
2238
2089
  }
2239
- console.log(`${result.files.length} pages, ${files.size} assets \u2192 ${relative4(process.cwd(), outDir)}`);
2090
+ console.log(
2091
+ `${crawlerResult === void 0 ? result.files.length : result.files.length + crawlerResult.files.length} files, ${files.size} assets \u2192 ${relative4(process.cwd(), outDir)}`
2092
+ );
2240
2093
  return;
2241
2094
  }
2242
2095
  const reload = new EventEmitter();
2243
2096
  let generation = 0;
2244
- serve({ fetch: createDevApp({ pages: app, files, reload }).fetch, port: cli_dev_port }, (info) => console.log(`http://localhost:${info.port}/`));
2097
+ serve({ fetch: createDevApp({ pages: app, crawling, files, reload }).fetch, port: cli_dev_port }, (info) => console.log(`http://localhost:${info.port}/`));
2245
2098
  const reloadDocs = debounce(
2246
2099
  toChangeQueue({
2247
2100
  run: async () => {
2248
2101
  const currentGeneration = generation;
2249
2102
  const nextFiles = new Map(kitFiles);
2250
2103
  const nextProcessor = createProcessor({ site: siteConfig, root: docsRoot, files: nextFiles });
2251
- const [docs2, home2] = await Promise.all([readDocs({ root: docsRoot, processor: nextProcessor }), readHome({ root: docsRoot, processor: nextProcessor })]);
2104
+ const [docs2, home2] = await Promise.all([
2105
+ readDocs({ root: docsRoot, processor: nextProcessor, reserved: siteConfig.url === void 0 ? void 0 : crawling_reserved_roots }),
2106
+ readHome({ root: docsRoot, processor: nextProcessor })
2107
+ ]);
2252
2108
  if (currentGeneration !== generation) {
2253
2109
  return;
2254
2110
  }