for-humanity 0.11.0 → 0.13.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.
- package/CHANGELOG.md +33 -0
- package/README.md +16 -9
- package/dist/browser.js +16 -16
- package/dist/cli.css +2 -941
- package/dist/cli.js +92 -2290
- package/dist/config.js +1 -0
- package/dist/constant/copy.d.ts +100 -0
- package/dist/constant/site.d.ts +20 -0
- package/dist/constant/status.d.ts +19 -0
- package/dist/copy-C1uzvEnr.js +103 -0
- package/dist/group-path-XAThmzvC.js +10 -0
- package/dist/load-site-CbpLEhwu.js +2379 -0
- package/dist/logger-Dv1i9xSV.js +9 -0
- package/dist/mermaid/THIRD-PARTY-NOTICES.txt +3134 -0
- package/dist/mermaid/chunk--TN-qHgG.js +2 -0
- package/dist/mermaid/chunk-0kM1Lv4D.js +2 -0
- package/dist/mermaid/chunk-3FHei3pH.js +2001 -0
- package/dist/mermaid/chunk-3_2p2GqN.js +2 -0
- package/dist/mermaid/chunk-6HLei9i0.js +84 -0
- package/dist/mermaid/chunk-7Sz3kAwl.js +2214 -0
- package/dist/mermaid/chunk-7Tarqbpa.js +18047 -0
- package/dist/mermaid/chunk-9kkt8lzL.js +10 -0
- package/dist/mermaid/chunk-B--pNBQF.js +884 -0
- package/dist/mermaid/chunk-B4F-pysn.js +4241 -0
- package/dist/mermaid/chunk-B58sEIY_.js +14 -0
- package/dist/mermaid/chunk-B9_UWzSH.js +1517 -0
- package/dist/mermaid/chunk-BB8uZHwY.js +75 -0
- package/dist/mermaid/chunk-BFfk0LEc.js +717 -0
- package/dist/mermaid/chunk-BKri0qr7.js +89 -0
- package/dist/mermaid/chunk-BL404pH5.js +26 -0
- package/dist/mermaid/chunk-BLeiQSWo.js +354 -0
- package/dist/mermaid/chunk-BOmH_UFd.js +2 -0
- package/dist/mermaid/chunk-BSej9Nhy.js +1361 -0
- package/dist/mermaid/chunk-BYzrzvCI.js +12 -0
- package/dist/mermaid/chunk-BariMtWr.js +3020 -0
- package/dist/mermaid/chunk-BcrBoMwH.js +2352 -0
- package/dist/mermaid/chunk-Bok8z-Yo.js +67 -0
- package/dist/mermaid/chunk-BpTHLKQM.js +1970 -0
- package/dist/mermaid/chunk-BqjuxRsC.js +733 -0
- package/dist/mermaid/chunk-BuvPd-s5.js +1073 -0
- package/dist/mermaid/chunk-BvVehae3.js +5069 -0
- package/dist/mermaid/chunk-C-JABYpd.js +3075 -0
- package/dist/mermaid/chunk-C9XlTm4w.js +2 -0
- package/dist/mermaid/chunk-CApNbSU9.js +6 -0
- package/dist/mermaid/chunk-CCM2AH-C.js +9 -0
- package/dist/mermaid/chunk-CD1E0F_N.js +2 -0
- package/dist/mermaid/chunk-CDWvKG7D.js +2 -0
- package/dist/mermaid/chunk-CEVPpC1F.js +34 -0
- package/dist/mermaid/chunk-CLDr12lf.js +47504 -0
- package/dist/mermaid/chunk-CLVYqOBI.js +61 -0
- package/dist/mermaid/chunk-CLeOkFb5.js +15 -0
- package/dist/mermaid/chunk-CLgRAtOz.js +37 -0
- package/dist/mermaid/chunk-CMqFNUBl.js +134 -0
- package/dist/mermaid/chunk-CTPaBJXB.js +2 -0
- package/dist/mermaid/chunk-CVi6IGBL.js +2 -0
- package/dist/mermaid/chunk-CWV_EN-4.js +4745 -0
- package/dist/mermaid/chunk-CZ0dAs3g.js +2 -0
- package/dist/mermaid/chunk-C_YGy4Fn.js +236 -0
- package/dist/mermaid/chunk-CcVH22Yt.js +100 -0
- package/dist/mermaid/chunk-CgG6CD9_.js +7175 -0
- package/dist/mermaid/chunk-CgOP6IDB.js +3397 -0
- package/dist/mermaid/chunk-Cgg2UTSf.js +13 -0
- package/dist/mermaid/chunk-ChJfJJ1A.js +214 -0
- package/dist/mermaid/chunk-Ck5XRA46.js +447 -0
- package/dist/mermaid/chunk-Ckuw16cl.js +203 -0
- package/dist/mermaid/chunk-CpAbRCbF.js +1880 -0
- package/dist/mermaid/chunk-CuYekbSv.js +2 -0
- package/dist/mermaid/chunk-CwS4wZ5a.js +2 -0
- package/dist/mermaid/chunk-D-bcrBO3.js +82 -0
- package/dist/mermaid/chunk-D3IEAkCW.js +76 -0
- package/dist/mermaid/chunk-D8XfBJ_K.js +645 -0
- package/dist/mermaid/chunk-D9Ddd9y4.js +2228 -0
- package/dist/mermaid/chunk-DBh1mIbK.js +12 -0
- package/dist/mermaid/chunk-DD6Df6Ic.js +5 -0
- package/dist/mermaid/chunk-DGVDaXjx.js +8 -0
- package/dist/mermaid/chunk-DK9KqIXj.js +632 -0
- package/dist/mermaid/chunk-DORnIAsy.js +4487 -0
- package/dist/mermaid/chunk-DU69_VcF.js +363 -0
- package/dist/mermaid/chunk-DVNvSFoz.js +2144 -0
- package/dist/mermaid/chunk-DZe-4kde.js +20 -0
- package/dist/mermaid/chunk-D_a06Rz4.js +287 -0
- package/dist/mermaid/chunk-DfyFJJi2.js +972 -0
- package/dist/mermaid/chunk-DhKYPp1Z.js +2 -0
- package/dist/mermaid/chunk-DjFqgNTG.js +94 -0
- package/dist/mermaid/chunk-DmbDDrr-.js +65 -0
- package/dist/mermaid/chunk-DpuxlyL_.js +696 -0
- package/dist/mermaid/chunk-DqGhppWe.js +2 -0
- package/dist/mermaid/chunk-DqPZxHXa.js +5 -0
- package/dist/mermaid/chunk-Dt_1Jyif.js +293 -0
- package/dist/mermaid/chunk-DyQBE_NW.js +1935 -0
- package/dist/mermaid/chunk-JckyC4mW.js +1009 -0
- package/dist/mermaid/chunk-K7Myuj2-.js +1334 -0
- package/dist/mermaid/chunk-KuPYb48V.js +275 -0
- package/dist/mermaid/chunk-MFVRUoO0.js +4020 -0
- package/dist/mermaid/chunk-MbInCS_6.js +28 -0
- package/dist/mermaid/chunk-MexOLyKV.js +355 -0
- package/dist/mermaid/chunk-NnbDtJzg.js +21856 -0
- package/dist/mermaid/chunk-SGpOYZbI.js +2139 -0
- package/dist/mermaid/chunk-TbxLDlcU.js +198 -0
- package/dist/mermaid/chunk-TftHqGLg.js +490 -0
- package/dist/mermaid/chunk-UjQ8vA_Z.js +4138 -0
- package/dist/mermaid/chunk-YgmVTKqc.js +16 -0
- package/dist/mermaid/chunk-_a9EZE1v.js +1798 -0
- package/dist/mermaid/chunk-dTb8jqeP.js +2 -0
- package/dist/mermaid/chunk-fFdMfF8S.js +2240 -0
- package/dist/mermaid/chunk-feYbMzBj.js +1267 -0
- package/dist/mermaid/chunk-g3Pn8DkW.js +46 -0
- package/dist/mermaid/chunk-hM77LvCb.js +19832 -0
- package/dist/mermaid/chunk-hUDb-eAW.js +527 -0
- package/dist/mermaid/chunk-tpABtZ-3.js +4252 -0
- package/dist/mermaid/chunk-xIbz3oFK.js +59 -0
- package/dist/mermaid/chunk-yBz-vst0.js +976 -0
- package/dist/mermaid/mermaid-BhtR3wyB.js +1145 -0
- package/dist/run-site-command-C80YoNOe.js +129 -0
- package/dist/site-config-bllORGpm.js +90 -0
- package/dist/site.js +1 -0
- package/dist/start-dev-server-C4_Lu1nZ.js +176 -0
- package/dist/to-change-queue-DbEnZGNK.js +34 -0
- package/dist/to-error-message-pF6_7wGK.js +16 -0
- package/dist/type/group-path.d.ts +7 -0
- package/dist/type/site-config.d.ts +57 -0
- package/package.json +34 -17
- package/src/component/widget/cursor-face/_constant/cursor-face.ts +0 -14
- package/src/component/widget/cursor-face/wg-cursor-face.css +0 -15
- package/src/component/widget/cursor-face/wg-cursor-face.tsx +0 -153
- package/src/component/widget/navigation/_constant/locale.ts +0 -9
- package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -33
- package/src/component/widget/navigation/_constant/navigation.ts +0 -9
- package/src/component/widget/navigation/_constant/reading-line.ts +0 -4
- package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +0 -59
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts +0 -15
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts +0 -70
- package/src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts +0 -15
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +0 -18
- package/src/component/widget/navigation/_function/to-navigation-json.ts +0 -8
- package/src/component/widget/navigation/_function/to-toc-groups.ts +0 -38
- package/src/component/widget/navigation/_type/doc-branch.ts +0 -11
- package/src/component/widget/navigation/_type/doc-group.ts +0 -24
- package/src/component/widget/navigation/_type/navigation-data.ts +0 -75
- package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -17
- package/src/component/widget/navigation/_type/toc-group.ts +0 -39
- package/src/component/widget/navigation/_wg-navigation-nav-list.css +0 -48
- package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +0 -61
- package/src/component/widget/navigation/_wg-navigation-nav.css +0 -21
- package/src/component/widget/navigation/_wg-navigation-nav.tsx +0 -33
- package/src/component/widget/navigation/_wg-navigation-scroll.tsx +0 -117
- package/src/component/widget/navigation/_wg-navigation-toc.css +0 -91
- package/src/component/widget/navigation/_wg-navigation-toc.tsx +0 -114
- package/src/component/widget/navigation/wg-navigation.css +0 -282
- package/src/component/widget/navigation/wg-navigation.tsx +0 -420
- package/src/component/widget/prose/_constant/heading-highlight.ts +0 -4
- package/src/component/widget/prose/_constant/section.ts +0 -7
- package/src/component/widget/prose/_constant/status.ts +0 -9
- package/src/component/widget/prose/_function/has-block-content.ts +0 -30
- package/src/component/widget/prose/_function/rehype-head.ts +0 -31
- package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +0 -20
- package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +0 -21
- package/src/component/widget/prose/_function/rehype-tables.ts +0 -22
- package/src/component/widget/prose/_function/remark-blocks.ts +0 -112
- package/src/component/widget/prose/_function/remark-flow.ts +0 -26
- package/src/component/widget/prose/_function/remark-links.ts +0 -33
- package/src/component/widget/prose/_function/remark-parts.ts +0 -26
- package/src/component/widget/prose/_function/remark-status.ts +0 -59
- package/src/component/widget/prose/_function/remark-swatch.ts +0 -16
- package/src/component/widget/prose/_function/remark-unknown-directives.ts +0 -25
- package/src/component/widget/prose/wg-prose.css +0 -454
- package/src/component/widget/prose/wg-prose.tsx +0 -43
- package/src/component/widget/shell/wg-shell.css +0 -63
- package/src/component/widget/shell/wg-shell.tsx +0 -88
- package/src/component/widget/shell-controls/wg-shell-controls.css +0 -4
- package/src/component/widget/shell-controls/wg-shell-controls.tsx +0 -170
- package/src/constant/asset.ts +0 -63
- package/src/constant/copy.ts +0 -133
- package/src/constant/doc.ts +0 -13
- package/src/constant/font.ts +0 -34
- package/src/constant/site.ts +0 -24
- package/src/constant/status.ts +0 -15
- package/src/entry/browser/browser.tsx +0 -22
- package/src/entry/cli/_constant/cli.ts +0 -19
- package/src/entry/cli/_constant/crawling.ts +0 -14
- package/src/entry/cli/_constant/snippet.ts +0 -21
- package/src/entry/cli/_function/create-app.tsx +0 -57
- package/src/entry/cli/_function/create-dev-app.ts +0 -87
- package/src/entry/cli/_function/create-processor/_rehype-assets.ts +0 -70
- package/src/entry/cli/_function/create-processor/_rehype-heading-ids.ts +0 -34
- package/src/entry/cli/_function/create-processor/_remark-report.ts +0 -15
- package/src/entry/cli/_function/create-processor/_remark-snippets.ts +0 -117
- package/src/entry/cli/_function/create-processor/_shiki-transformers.ts +0 -55
- package/src/entry/cli/_function/create-processor/create-processor.ts +0 -64
- package/src/entry/cli/_function/read-docs.ts +0 -128
- package/src/entry/cli/_function/read-home.ts +0 -32
- package/src/entry/cli/_function/to-crawling-app.ts +0 -42
- package/src/entry/cli/cli.test.ts +0 -782
- package/src/entry/cli/cli.ts +0 -206
- package/src/env.d.ts +0 -6
- package/src/page/doc/pg-doc.tsx +0 -35
- package/src/page/home/pg-home.tsx +0 -40
- package/src/store/navigation/create-navigation-stores.test.ts +0 -74
- package/src/store/navigation/create-navigation-stores.ts +0 -59
- package/src/store/navigation/navigation-state.ts +0 -36
- package/src/store/navigation/navigation-storage.ts +0 -9
- package/src/store/navigation/to-navigation-scroll-state.ts +0 -42
- package/src/style/base.css +0 -28
- package/src/style/token.css +0 -186
- package/src/type/doc-content.ts +0 -15
- package/src/type/doc-data.ts +0 -38
- package/src/type/doc-file-data.ts +0 -21
- package/src/type/doc-heading.ts +0 -17
- package/src/type/doc-outline.ts +0 -16
- package/src/type/doc-section.ts +0 -9
- package/src/type/doc.ts +0 -20
- package/src/type/group-path.ts +0 -7
- package/src/type/site-assets.ts +0 -25
- package/src/type/site-config.ts +0 -73
- package/src/type/vfile-data.d.ts +0 -10
- package/src/util/async/to-change-queue.test.ts +0 -58
- package/src/util/async/to-change-queue.ts +0 -43
- package/src/util/dom/find-hash-target.ts +0 -18
- package/src/util/dom/reveal-hash-target.ts +0 -15
- package/src/util/error/to-error-message.ts +0 -10
- package/src/util/file/to-asset-path.ts +0 -26
- package/src/util/font/to-font-css.test.ts +0 -41
- package/src/util/font/to-font-css.ts +0 -28
- package/src/util/mermaid/render-flow.js +0 -321
package/dist/cli.js
CHANGED
|
@@ -1,2293 +1,95 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/entry/cli/cli.ts
|
|
4
|
-
import { EventEmitter } from "node:events";
|
|
5
|
-
import { existsSync as existsSync4, readFileSync as readFileSync4, watch } from "node:fs";
|
|
6
|
-
import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
|
|
7
|
-
import { dirname as dirname5, extname as extname5, join as join4, relative as relative5, resolve as resolve4, sep as sep4 } from "node:path";
|
|
8
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
|
-
import { serve } from "@hono/node-server";
|
|
10
|
-
import { serveStatic } from "@hono/node-server/serve-static";
|
|
11
|
-
import { debounce } from "es-toolkit";
|
|
12
|
-
import { Hono as Hono4 } from "hono";
|
|
13
|
-
import { toSSG } from "hono/ssg";
|
|
14
|
-
|
|
15
|
-
// src/constant/asset.ts
|
|
16
|
-
var asset_dir = "_fh";
|
|
17
|
-
var asset_style_path = `/${asset_dir}/style.css`;
|
|
18
|
-
var asset_font_dir = `/${asset_dir}/fonts`;
|
|
19
|
-
var asset_reload_path = `/${asset_dir}/reload`;
|
|
20
|
-
var asset_favicon_path = "/favicon.svg";
|
|
21
|
-
var asset_content_types = {
|
|
22
|
-
".css": "text/css; charset=utf-8",
|
|
23
|
-
".js": "text/javascript; charset=utf-8",
|
|
24
|
-
".woff2": "font/woff2",
|
|
25
|
-
".svg": "image/svg+xml",
|
|
26
|
-
".png": "image/png",
|
|
27
|
-
".jpg": "image/jpeg",
|
|
28
|
-
".jpeg": "image/jpeg",
|
|
29
|
-
".gif": "image/gif",
|
|
30
|
-
".webp": "image/webp",
|
|
31
|
-
".avif": "image/avif",
|
|
32
|
-
".pdf": "application/pdf",
|
|
33
|
-
".csv": "text/csv; charset=utf-8",
|
|
34
|
-
".txt": "text/plain; charset=utf-8",
|
|
35
|
-
".zip": "application/zip"
|
|
36
|
-
};
|
|
37
|
-
var asset_content_type_default = "application/octet-stream";
|
|
38
|
-
var asset_media_dir = `/${asset_dir}/media`;
|
|
39
|
-
var asset_media_extensions = /* @__PURE__ */ new Set([".svg", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".avif", ".pdf", ".csv", ".txt", ".zip"]);
|
|
40
|
-
|
|
41
|
-
// src/constant/copy.ts
|
|
42
|
-
var copy_site_title_default = "for humanity";
|
|
43
|
-
var copy_nav_aria_label = "Document navigation";
|
|
44
|
-
var copy_nav_open = "Open navigation";
|
|
45
|
-
var copy_nav_close = "Close navigation";
|
|
46
|
-
var copy_nav_title = "Navigation";
|
|
47
|
-
var copy_home_missing = "\uBB38\uC11C \uD3F4\uB354\uC5D0 README.md\uB97C \uCD94\uAC00\uD558\uBA74 \uC774\uACF3\uC5D0 \uD648 \uD654\uBA74\uC73C\uB85C \uD45C\uC2DC\uB429\uB2C8\uB2E4.";
|
|
48
|
-
var copy_nav_toc_label = "On this page";
|
|
49
|
-
var copy_error_home_clash = "\uD648 README\uAC00 \uACB9\uCE5C\uB2E4";
|
|
50
|
-
var copy_error_prefix = "for-humanity";
|
|
51
|
-
var copy_error_unknown_command = "\uBAA8\uB974\uB294 \uBA85\uB839\uC774\uB2E4";
|
|
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
|
-
var copy_error_frontmatter = "frontmatter\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
|
|
55
|
-
var copy_error_navigation_clash = "navigation\uC758 \uBB36\uC74C\uC774 \uACB9\uCE5C\uB2E4";
|
|
56
|
-
var copy_error_doc_id = "\uBB38\uC11C id\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uB294 \uACBD\uB85C";
|
|
57
|
-
var copy_error_doc_id_clash = "\uBB38\uC11C id\uAC00 \uACB9\uCE5C\uB2E4";
|
|
58
|
-
var copy_error_doc_parent_missing = "\uBD80\uBAA8 \uBB38\uC11C\uAC00 \uC5C6\uB2E4";
|
|
59
|
-
var copy_error_doc_parent_cycle = "\uBB38\uC11C parent\uAC00 \uC21C\uD658\uD55C\uB2E4";
|
|
60
|
-
var copy_error_doc_parent_group = "\uBD80\uBAA8 \uBB38\uC11C\uC640 group\uC774 \uB2E4\uB974\uB2E4";
|
|
61
|
-
var copy_error_flow = "\uD750\uB984\uB3C4\uB97C \uADF8\uB9AC\uC9C0 \uBABB\uD588\uB2E4";
|
|
62
|
-
var copy_error_unknown_directive = "\uBAA8\uB974\uB294 \uBD80\uD488\uC774\uB2E4";
|
|
63
|
-
var copy_error_directive_syntax = "\uBD80\uD488 \uBB38\uBC95\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
|
|
64
|
-
var copy_warn_broken_link = "\uC5C6\uB294 \uBB38\uC11C\uB85C \uAC74 \uB9C1\uD06C\uB2E4";
|
|
65
|
-
var copy_warn_unknown_status = "\uC124\uC815\uC5D0 \uC5C6\uB294 \uC0C1\uD0DC \uBB38\uAD6C\uB2E4";
|
|
66
|
-
var copy_error_asset = "\uC790\uC6D0\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
|
|
67
|
-
var copy_error_snippet = "\uCF54\uB4DC \uC2A4\uB2C8\uD3AB\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
|
|
68
|
-
|
|
69
|
-
// src/constant/font.ts
|
|
70
|
-
var font_mono_css = "src/asset/font/monoplex-kr/monoplex-kr.css";
|
|
71
|
-
var font_body_css = "src/asset/font/ibm-plex-sans-kr/ibm-plex-sans-kr.css";
|
|
72
|
-
var font_brand_css = "src/asset/font/architects-daughter/architects-daughter.css";
|
|
73
|
-
var font_display_strategy = "optional";
|
|
74
|
-
var font_hash_length = 12;
|
|
75
|
-
var font_cache_control = "public, max-age=31536000, immutable";
|
|
76
|
-
|
|
77
|
-
// src/constant/site.ts
|
|
78
|
-
var site_config_absent = {};
|
|
79
|
-
var site_navigation_default = [];
|
|
80
|
-
var site_port_default = 4321;
|
|
81
|
-
var site_port_min = 1;
|
|
82
|
-
var site_port_max = 65535;
|
|
83
|
-
|
|
84
|
-
// src/entry/cli/_constant/cli.ts
|
|
85
|
-
var cli_default_command = "dev";
|
|
86
|
-
var cli_default_docs_dir = ".";
|
|
87
|
-
var cli_config_file_name = "for-humanity.config.mjs";
|
|
88
|
-
var cli_reload_delay_ms = 150;
|
|
89
|
-
|
|
90
|
-
// src/entry/cli/_constant/crawling.ts
|
|
91
|
-
var crawling_robots_path = "/robots.txt";
|
|
92
|
-
var crawling_sitemap_path = "/sitemap.xml";
|
|
93
|
-
var crawling_reserved_roots = [crawling_robots_path.slice(1), crawling_sitemap_path.slice(1)];
|
|
94
|
-
|
|
95
|
-
// src/entry/cli/_function/create-app.tsx
|
|
96
|
-
import { Hono } from "hono";
|
|
97
|
-
import { html } from "hono/html";
|
|
98
|
-
import { ssgParams } from "hono/ssg";
|
|
99
|
-
|
|
100
|
-
// src/component/widget/prose/wg-prose.tsx
|
|
101
|
-
import clsx from "clsx";
|
|
102
|
-
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
103
|
-
var WgProse = (props) => {
|
|
104
|
-
if (props.html !== void 0) {
|
|
105
|
-
return /* @__PURE__ */ jsx("article", { className: clsx("wg_prose__root"), dangerouslySetInnerHTML: { __html: props.html } });
|
|
106
|
-
}
|
|
107
|
-
return /* @__PURE__ */ jsx("article", { className: clsx("wg_prose__root"), children: props.head !== void 0 && /* @__PURE__ */ jsxs("header", { className: clsx("wg_prose__head"), children: [
|
|
108
|
-
/* @__PURE__ */ jsx("h1", { children: props.head.title }),
|
|
109
|
-
props.head.lead !== void 0 && /* @__PURE__ */ jsx("p", { children: props.head.lead })
|
|
110
|
-
] }) });
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// src/component/widget/shell/wg-shell.tsx
|
|
114
|
-
import clsx9 from "clsx";
|
|
115
|
-
|
|
116
|
-
// src/component/widget/navigation/_constant/locale.ts
|
|
117
|
-
var locale_doc_name = "en";
|
|
118
|
-
var locale_doc_group = "ko";
|
|
119
|
-
|
|
120
|
-
// src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts
|
|
121
|
-
var toDocBranches = (options) => {
|
|
122
|
-
return options.docs.toSorted((a, b) => a.data.order - b.data.order || a.data.name.localeCompare(b.data.name, locale_doc_name) || a.id.localeCompare(b.id, locale_doc_name)).map((doc) => {
|
|
123
|
-
const children = options.children.get(doc.id);
|
|
124
|
-
return { ...doc, children: children === void 0 ? void 0 : toDocBranches({ docs: children, children: options.children }) };
|
|
125
|
-
});
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts
|
|
129
|
-
var toDocGroupBranches = (options) => {
|
|
130
|
-
return [
|
|
131
|
-
...Map.groupBy(
|
|
132
|
-
options.docs.filter((doc) => doc.data.group.length > options.path.length),
|
|
133
|
-
(doc) => doc.data.group[options.path.length]
|
|
134
|
-
)
|
|
135
|
-
].map(([name, docs]) => {
|
|
136
|
-
const path = [...options.path, name];
|
|
137
|
-
return {
|
|
138
|
-
name,
|
|
139
|
-
path,
|
|
140
|
-
docs,
|
|
141
|
-
position: options.positions.get(JSON.stringify(path)) ?? options.unlistedPosition
|
|
142
|
-
};
|
|
143
|
-
}).toSorted((a, b) => a.position - b.position || a.name.localeCompare(b.name, locale_doc_group)).map((group) => {
|
|
144
|
-
return {
|
|
145
|
-
name: group.name,
|
|
146
|
-
path: group.path,
|
|
147
|
-
docs: toDocBranches({
|
|
148
|
-
docs: group.docs.filter((doc) => doc.data.group.length === group.path.length && doc.data.parent === void 0),
|
|
149
|
-
children: options.children
|
|
150
|
-
}),
|
|
151
|
-
groups: toDocGroupBranches({
|
|
152
|
-
docs: group.docs,
|
|
153
|
-
children: options.children,
|
|
154
|
-
path: group.path,
|
|
155
|
-
positions: options.positions,
|
|
156
|
-
unlistedPosition: options.unlistedPosition
|
|
157
|
-
})
|
|
158
|
-
};
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
// src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts
|
|
163
|
-
var toDocGroups = (options) => {
|
|
164
|
-
const positions = new Map(options.navigation.flatMap((path, index) => path.map((_name, depth) => [JSON.stringify(path.slice(0, depth + 1)), index])).toReversed());
|
|
165
|
-
const children = Map.groupBy(options.docs, (doc) => doc.data.parent);
|
|
166
|
-
return toDocGroupBranches({ docs: options.docs, children, path: [], positions, unlistedPosition: options.navigation.length });
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
// src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts
|
|
170
|
-
var toNavigationDocument = (options) => ({
|
|
171
|
-
id: options.doc.id,
|
|
172
|
-
name: options.doc.data.name,
|
|
173
|
-
label: options.doc.data.label,
|
|
174
|
-
active: options.doc.id === options.current,
|
|
175
|
-
children: options.doc.children === void 0 ? [] : options.doc.children.map((doc) => toNavigationDocument({ ...options, doc }))
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts
|
|
179
|
-
var toNavigationGroup = (options) => ({
|
|
180
|
-
name: options.group.name,
|
|
181
|
-
path: options.group.path,
|
|
182
|
-
docs: options.group.docs.map((doc) => toNavigationDocument({ doc, current: options.current })),
|
|
183
|
-
groups: options.group.groups.map((group) => toNavigationGroup({ ...options, group }))
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// src/component/widget/navigation/_function/to-toc-groups.ts
|
|
187
|
-
import { takeWhile } from "es-toolkit/array";
|
|
188
|
-
|
|
189
|
-
// src/component/widget/prose/_constant/section.ts
|
|
190
|
-
var section_heading_depth = {
|
|
191
|
-
section: 2,
|
|
192
|
-
sub: 3
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// src/component/widget/navigation/_function/to-toc-groups.ts
|
|
196
|
-
var toTocGroups = (outline) => {
|
|
197
|
-
const entries = outline.headings.filter((heading) => heading.depth === section_heading_depth.section || heading.depth === section_heading_depth.sub).map((heading, index) => ({ heading, section: outline.sections[index] }));
|
|
198
|
-
const sections = entries.flatMap(
|
|
199
|
-
(entry, index) => entry.heading.depth === section_heading_depth.section ? [
|
|
200
|
-
{
|
|
201
|
-
heading: entry.heading,
|
|
202
|
-
part: entry.section.part,
|
|
203
|
-
subs: takeWhile(entries.slice(index + 1), (sub) => sub.heading.depth !== section_heading_depth.section).map((sub) => ({
|
|
204
|
-
heading: sub.heading
|
|
205
|
-
}))
|
|
206
|
-
}
|
|
207
|
-
] : []
|
|
208
|
-
);
|
|
209
|
-
return sections.flatMap(
|
|
210
|
-
(section, index) => index === 0 || section.part !== void 0 ? [
|
|
211
|
-
{
|
|
212
|
-
part: section.part,
|
|
213
|
-
sections: [section, ...takeWhile(sections.slice(index + 1), (next) => next.part === void 0)]
|
|
214
|
-
}
|
|
215
|
-
] : []
|
|
216
|
-
);
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
// src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts
|
|
220
|
-
var toNavigationData = (options) => ({
|
|
221
|
-
title: options.site.title,
|
|
222
|
-
groups: toDocGroups({ docs: options.docs, navigation: options.site.navigation }).map((group) => toNavigationGroup({ group, current: options.current })),
|
|
223
|
-
outline: options.outline === void 0 ? [] : toTocGroups(options.outline),
|
|
224
|
-
home: options.current === void 0,
|
|
225
|
-
cursorFace: options.site.cursorFace
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
// src/component/widget/navigation/_function/to-navigation-json.ts
|
|
229
|
-
var toNavigationJson = (data) => {
|
|
230
|
-
return JSON.stringify(data).replaceAll("<", "\\u003c").replaceAll("\u2028", "\\u2028").replaceAll("\u2029", "\\u2029");
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
// src/component/widget/shell-controls/wg-shell-controls.tsx
|
|
234
|
-
import clsx8 from "clsx";
|
|
235
|
-
import { Fragment as Fragment3, useEffect, useLayoutEffect as useLayoutEffect5, useRef as useRef4 } from "hono/jsx";
|
|
236
|
-
|
|
237
|
-
// src/component/widget/cursor-face/wg-cursor-face.tsx
|
|
238
|
-
import clsx2 from "clsx";
|
|
239
|
-
import { useLayoutEffect, useRef } from "hono/jsx";
|
|
240
|
-
|
|
241
|
-
// src/component/widget/cursor-face/_constant/cursor-face.ts
|
|
242
|
-
var cursor_face_offset_px = 16;
|
|
243
|
-
var cursor_face_size_px = 24;
|
|
244
|
-
var cursor_face_storage_key = "fh-cursor-face";
|
|
245
|
-
|
|
246
|
-
// src/component/widget/cursor-face/wg-cursor-face.tsx
|
|
247
|
-
import { jsx as jsx2 } from "hono/jsx/jsx-runtime";
|
|
248
|
-
var WgCursorFace = (props) => {
|
|
249
|
-
const faceRef = useRef(null);
|
|
250
|
-
const mediaRef = useRef(null);
|
|
251
|
-
const positionRef = useRef({ x: 0, y: 0, frame: 0 });
|
|
252
|
-
const handleCursorHide = () => {
|
|
253
|
-
cancelAnimationFrame(positionRef.current.frame);
|
|
254
|
-
positionRef.current.frame = 0;
|
|
255
|
-
faceRef.current?.classList.remove("wg_cursorFace__root--visible");
|
|
256
|
-
};
|
|
257
|
-
const handleCursorMediaChange = () => {
|
|
258
|
-
if (!mediaRef.current?.matches) handleCursorHide();
|
|
259
|
-
};
|
|
260
|
-
const renderCursorFace = () => {
|
|
261
|
-
if (positionRef.current.frame !== 0) return;
|
|
262
|
-
positionRef.current.frame = requestAnimationFrame(() => {
|
|
263
|
-
positionRef.current.frame = 0;
|
|
264
|
-
const face = faceRef.current;
|
|
265
|
-
if (face === null) return;
|
|
266
|
-
face.style.transform = `translate3d(
|
|
267
|
-
${Math.max(0, Math.min(positionRef.current.x + cursor_face_offset_px, document.documentElement.clientWidth - face.width - cursor_face_offset_px))}px,
|
|
268
|
-
${Math.max(0, Math.min(positionRef.current.y + cursor_face_offset_px, document.documentElement.clientHeight - face.height - cursor_face_offset_px))}px,
|
|
269
|
-
0
|
|
270
|
-
)`;
|
|
271
|
-
face.classList.add("wg_cursorFace__root--visible");
|
|
272
|
-
});
|
|
273
|
-
};
|
|
274
|
-
const handleDocumentPointer = (event) => {
|
|
275
|
-
if (!mediaRef.current?.matches || event.pointerType !== "mouse") {
|
|
276
|
-
handleCursorHide();
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
positionRef.current.x = event.clientX;
|
|
280
|
-
positionRef.current.y = event.clientY;
|
|
281
|
-
renderCursorFace();
|
|
282
|
-
};
|
|
283
|
-
const handleCursorResize = () => {
|
|
284
|
-
if (faceRef.current?.classList.contains("wg_cursorFace__root--visible")) renderCursorFace();
|
|
285
|
-
};
|
|
286
|
-
const handlePageHide = () => {
|
|
287
|
-
if (!faceRef.current?.classList.contains("wg_cursorFace__root--visible")) return;
|
|
288
|
-
try {
|
|
289
|
-
sessionStorage.setItem(cursor_face_storage_key, JSON.stringify({ x: positionRef.current.x, y: positionRef.current.y }));
|
|
290
|
-
} catch {
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
const handlePageShow = () => {
|
|
294
|
-
try {
|
|
295
|
-
const stored = sessionStorage.getItem(cursor_face_storage_key);
|
|
296
|
-
sessionStorage.removeItem(cursor_face_storage_key);
|
|
297
|
-
if (stored === null || !mediaRef.current?.matches) return;
|
|
298
|
-
const point = JSON.parse(stored);
|
|
299
|
-
if (typeof point === "object" && point !== null && "x" in point && "y" in point && typeof point.x === "number" && typeof point.y === "number" && Number.isFinite(point.x) && Number.isFinite(point.y)) {
|
|
300
|
-
positionRef.current.x = point.x;
|
|
301
|
-
positionRef.current.y = point.y;
|
|
302
|
-
renderCursorFace();
|
|
303
|
-
}
|
|
304
|
-
} catch {
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
useLayoutEffect(() => {
|
|
308
|
-
if (!props.ready) return;
|
|
309
|
-
const lifetime = new AbortController();
|
|
310
|
-
const media = matchMedia("(hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)");
|
|
311
|
-
mediaRef.current = media;
|
|
312
|
-
handlePageShow();
|
|
313
|
-
document.addEventListener("pointermove", handleDocumentPointer, { passive: true, signal: lifetime.signal });
|
|
314
|
-
document.addEventListener("pointerdown", handleDocumentPointer, { passive: true, signal: lifetime.signal });
|
|
315
|
-
document.documentElement.addEventListener("pointerleave", handleCursorHide, { signal: lifetime.signal });
|
|
316
|
-
addEventListener("blur", handleCursorHide, { signal: lifetime.signal });
|
|
317
|
-
addEventListener("resize", handleCursorResize, { signal: lifetime.signal });
|
|
318
|
-
addEventListener("pagehide", handlePageHide, { signal: lifetime.signal });
|
|
319
|
-
addEventListener("pageshow", handlePageShow, { signal: lifetime.signal });
|
|
320
|
-
media.addEventListener("change", handleCursorMediaChange, { signal: lifetime.signal });
|
|
321
|
-
return () => {
|
|
322
|
-
lifetime.abort();
|
|
323
|
-
mediaRef.current = null;
|
|
324
|
-
handleCursorHide();
|
|
325
|
-
};
|
|
326
|
-
}, [props.ready]);
|
|
327
|
-
return /* @__PURE__ */ jsx2(
|
|
328
|
-
"img",
|
|
329
|
-
{
|
|
330
|
-
ref: props.ready ? faceRef : void 0,
|
|
331
|
-
className: clsx2("wg_cursorFace__root"),
|
|
332
|
-
src: asset_favicon_path,
|
|
333
|
-
width: cursor_face_size_px,
|
|
334
|
-
height: cursor_face_size_px,
|
|
335
|
-
alt: "",
|
|
336
|
-
"aria-hidden": "true",
|
|
337
|
-
draggable: false,
|
|
338
|
-
"data-cursor-face": ""
|
|
339
|
-
}
|
|
340
|
-
);
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
// src/component/widget/navigation/wg-navigation.tsx
|
|
344
|
-
import clsx7 from "clsx";
|
|
345
|
-
import { Fragment as Fragment2, useLayoutEffect as useLayoutEffect4, useRef as useRef3, useState as useState3 } from "hono/jsx";
|
|
346
|
-
import { flushSync } from "hono/jsx/dom";
|
|
347
|
-
|
|
348
|
-
// src/component/widget/navigation/_constant/navigation.ts
|
|
349
|
-
var navigation_mobile_query = "(width < 1024px)";
|
|
350
|
-
var navigation_wide_query = "(width >= 1360px)";
|
|
351
|
-
|
|
352
|
-
// src/component/widget/navigation/_function/restore-navigation-scroll.ts
|
|
353
|
-
var restoreNavigationScroll = (options) => {
|
|
354
|
-
const navigation = document.querySelector("[data-navigation]");
|
|
355
|
-
const documents = document.querySelector('[data-navigation-scroll="documents"]');
|
|
356
|
-
const outline = document.querySelector('[data-navigation-scroll="outline"]');
|
|
357
|
-
if (!navigation || !documents || !outline) return;
|
|
358
|
-
navigation.dataset.navigationLayout = options.layout;
|
|
359
|
-
try {
|
|
360
|
-
const value = sessionStorage.getItem(options.key);
|
|
361
|
-
const stored = value === null ? void 0 : JSON.parse(value);
|
|
362
|
-
const state = typeof stored === "object" && stored !== null && "version" in stored && stored.version === options.version && "state" in stored ? options.toState(stored.state) : { positions: {} };
|
|
363
|
-
const legacy = sessionStorage.getItem(`${options.key}:${options.layout === "drawer" ? "drawer" : "desktop"}`);
|
|
364
|
-
const previous = state.positions[options.layout] === void 0 && legacy !== null ? options.toState({ positions: { [options.layout]: JSON.parse(legacy) } }).positions[options.layout] : void 0;
|
|
365
|
-
const position = state.positions[options.layout] ?? previous;
|
|
366
|
-
const signature = [...navigation.querySelectorAll(".wg_navigationNav__root a[href]")].map((link) => `${link.pathname}:${link.textContent}`).join("\n");
|
|
367
|
-
if (position === void 0 || position.navigation !== signature) return;
|
|
368
|
-
documents.scrollTop = position.documents;
|
|
369
|
-
if (position.pathname === location.pathname) outline.scrollTop = position.outline;
|
|
370
|
-
} catch {
|
|
371
|
-
}
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
// src/component/widget/navigation/_wg-navigation-nav.tsx
|
|
375
|
-
import clsx4 from "clsx";
|
|
376
|
-
|
|
377
|
-
// src/component/widget/navigation/_wg-navigation-nav-list.tsx
|
|
378
|
-
import clsx3 from "clsx";
|
|
379
|
-
import { Fragment } from "hono/jsx";
|
|
380
|
-
import { jsx as jsx3, jsxs as jsxs2 } from "hono/jsx/jsx-runtime";
|
|
381
|
-
var WgNavigationNavList = (props) => {
|
|
382
|
-
const entries = [
|
|
383
|
-
...props.group.docs.map((doc) => ({ kind: "document", key: `doc:${doc.id}`, doc })),
|
|
384
|
-
...props.group.groups.map((group) => ({ kind: "group", key: `group:${JSON.stringify(group.path)}`, group }))
|
|
385
|
-
];
|
|
386
|
-
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: [
|
|
387
|
-
entry.kind === "document" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
388
|
-
/* @__PURE__ */ jsx3(
|
|
389
|
-
"a",
|
|
390
|
-
{
|
|
391
|
-
className: clsx3("wg_navigationNavList__link", { "wg_navigationNavList__link--active": entry.doc.active }),
|
|
392
|
-
href: `/${entry.doc.id}/`,
|
|
393
|
-
title: entry.doc.label,
|
|
394
|
-
"aria-current": entry.doc.active ? "page" : void 0,
|
|
395
|
-
children: entry.doc.name
|
|
396
|
-
}
|
|
397
|
-
),
|
|
398
|
-
entry.doc.children.length > 0 && /* @__PURE__ */ jsx3(WgNavigationNavList, { group: { name: entry.doc.name, path: props.group.path, docs: entry.doc.children, groups: [] } })
|
|
399
|
-
] }),
|
|
400
|
-
entry.kind === "group" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
401
|
-
/* @__PURE__ */ jsx3("span", { className: clsx3("wg_navigationNavList__branch"), children: entry.group.name }),
|
|
402
|
-
/* @__PURE__ */ jsx3(WgNavigationNavList, { group: entry.group })
|
|
403
|
-
] })
|
|
404
|
-
] }, entry.key)) });
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
// src/component/widget/navigation/_wg-navigation-nav.tsx
|
|
408
|
-
import { jsx as jsx4, jsxs as jsxs3 } from "hono/jsx/jsx-runtime";
|
|
409
|
-
var WgNavigationNav = (props) => {
|
|
410
|
-
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: [
|
|
411
|
-
/* @__PURE__ */ jsx4("div", { className: clsx4("wg_navigationNav__group"), children: group.name }),
|
|
412
|
-
/* @__PURE__ */ jsx4(WgNavigationNavList, { group })
|
|
413
|
-
] }, JSON.stringify(group.path))) }) });
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
// src/component/widget/navigation/_wg-navigation-scroll.tsx
|
|
417
|
-
import clsx5 from "clsx";
|
|
418
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "hono/jsx";
|
|
419
|
-
import { jsx as jsx5 } from "hono/jsx/jsx-runtime";
|
|
420
|
-
var WgNavigationScroll = (props) => {
|
|
421
|
-
const [overflow, setOverflow] = useState({ above: false, below: false });
|
|
422
|
-
const frameRef = useRef2(0);
|
|
423
|
-
const updateOverflow = () => {
|
|
424
|
-
frameRef.current = 0;
|
|
425
|
-
if (props.portRef.current === null) return;
|
|
426
|
-
const above = props.portRef.current.scrollTop > 1;
|
|
427
|
-
const below = props.portRef.current.scrollHeight - props.portRef.current.clientHeight - props.portRef.current.scrollTop > 1;
|
|
428
|
-
setOverflow((state) => state.above === above && state.below === below ? state : { above, below });
|
|
429
|
-
};
|
|
430
|
-
const scheduleOverflow = () => {
|
|
431
|
-
if (frameRef.current === 0) frameRef.current = requestAnimationFrame(updateOverflow);
|
|
432
|
-
};
|
|
433
|
-
const handlePortScroll = (_event) => {
|
|
434
|
-
props.onScroll?.();
|
|
435
|
-
scheduleOverflow();
|
|
436
|
-
};
|
|
437
|
-
useLayoutEffect2(() => {
|
|
438
|
-
if (!props.ready || props.portRef.current === null) return;
|
|
439
|
-
const observer = new ResizeObserver(scheduleOverflow);
|
|
440
|
-
observer.observe(props.portRef.current);
|
|
441
|
-
if (props.portRef.current.firstElementChild !== null) observer.observe(props.portRef.current.firstElementChild);
|
|
442
|
-
let active = true;
|
|
443
|
-
addEventListener("pageshow", scheduleOverflow);
|
|
444
|
-
if (props.portRef.current.isConnected) {
|
|
445
|
-
updateOverflow();
|
|
446
|
-
} else {
|
|
447
|
-
queueMicrotask(() => {
|
|
448
|
-
if (active) updateOverflow();
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
return () => {
|
|
452
|
-
active = false;
|
|
453
|
-
observer.disconnect();
|
|
454
|
-
removeEventListener("pageshow", scheduleOverflow);
|
|
455
|
-
cancelAnimationFrame(frameRef.current);
|
|
456
|
-
frameRef.current = 0;
|
|
457
|
-
};
|
|
458
|
-
}, [props.portRef, props.ready]);
|
|
459
|
-
useLayoutEffect2(() => {
|
|
460
|
-
if (props.ready && props.portRef.current?.isConnected) updateOverflow();
|
|
461
|
-
}, [props.children, props.ready]);
|
|
462
|
-
return (
|
|
463
|
-
// biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: 부모의 링크 이벤트 위임이며 자식 a·button의 네이티브 키보드 동작을 그대로 소비한다
|
|
464
|
-
/* @__PURE__ */ jsx5(
|
|
465
|
-
"div",
|
|
466
|
-
{
|
|
467
|
-
ref: props.ready ? props.portRef : void 0,
|
|
468
|
-
className: clsx5(
|
|
469
|
-
"wg_navigation__scroll",
|
|
470
|
-
props.kind === "documents" && "wg_navigation__documents",
|
|
471
|
-
props.kind === "outline" && "wg_navigation__headings",
|
|
472
|
-
props.ready && "wg_navigation__scroll--ready",
|
|
473
|
-
props.ready && overflow.above && "wg_navigation__scroll--above",
|
|
474
|
-
props.ready && overflow.below && "wg_navigation__scroll--below"
|
|
475
|
-
),
|
|
476
|
-
"data-navigation-scroll": props.kind,
|
|
477
|
-
onClick: props.onClick,
|
|
478
|
-
onScroll: handlePortScroll,
|
|
479
|
-
children: props.children
|
|
480
|
-
}
|
|
481
|
-
)
|
|
482
|
-
);
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
// src/component/widget/navigation/_wg-navigation-toc.tsx
|
|
486
|
-
import clsx6 from "clsx";
|
|
487
|
-
import { useLayoutEffect as useLayoutEffect3, useState as useState2 } from "hono/jsx";
|
|
488
|
-
|
|
489
|
-
// src/component/widget/navigation/_constant/reading-line.ts
|
|
490
|
-
var reading_line_slack_px = 1;
|
|
491
|
-
|
|
492
|
-
// src/util/dom/find-hash-target.ts
|
|
493
|
-
var findHashTarget = (hash) => {
|
|
494
|
-
if (!hash) {
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
try {
|
|
498
|
-
return document.getElementById(decodeURIComponent(hash.slice(1)));
|
|
499
|
-
} catch (error) {
|
|
500
|
-
if (error instanceof URIError) {
|
|
501
|
-
return null;
|
|
502
|
-
}
|
|
503
|
-
throw error;
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
// src/component/widget/navigation/_wg-navigation-toc.tsx
|
|
508
|
-
import { jsx as jsx6, jsxs as jsxs4 } from "hono/jsx/jsx-runtime";
|
|
509
|
-
var WgNavigationToc = (props) => {
|
|
510
|
-
const [currentSlug, setCurrentSlug] = useState2();
|
|
511
|
-
useLayoutEffect3(() => {
|
|
512
|
-
const sections = props.groups.flatMap((group) => group.sections);
|
|
513
|
-
const headings = sections.flatMap((section) => [section.heading, ...section.subs.map((sub) => sub.heading)]);
|
|
514
|
-
const frame = { id: 0 };
|
|
515
|
-
const updateCurrentHeading = () => {
|
|
516
|
-
frame.id = 0;
|
|
517
|
-
const visible = headings.flatMap((heading) => {
|
|
518
|
-
const target = findHashTarget(`#${heading.slug}`);
|
|
519
|
-
return target?.checkVisibility() ? [{ slug: heading.slug, top: target.getBoundingClientRect().top - Number.parseFloat(getComputedStyle(target).scrollMarginTop) }] : [];
|
|
520
|
-
});
|
|
521
|
-
setCurrentSlug(visible.findLast((heading) => heading.top <= reading_line_slack_px)?.slug ?? visible[0]?.slug);
|
|
522
|
-
};
|
|
523
|
-
const handleReadingPositionChange = () => {
|
|
524
|
-
if (frame.id === 0) frame.id = requestAnimationFrame(updateCurrentHeading);
|
|
525
|
-
};
|
|
526
|
-
addEventListener("scroll", handleReadingPositionChange, { passive: true });
|
|
527
|
-
addEventListener("resize", handleReadingPositionChange);
|
|
528
|
-
addEventListener("toggle", handleReadingPositionChange, true);
|
|
529
|
-
addEventListener("pageshow", handleReadingPositionChange);
|
|
530
|
-
document.addEventListener("DOMContentLoaded", handleReadingPositionChange);
|
|
531
|
-
if (document.readyState !== "loading") updateCurrentHeading();
|
|
532
|
-
return () => {
|
|
533
|
-
cancelAnimationFrame(frame.id);
|
|
534
|
-
removeEventListener("scroll", handleReadingPositionChange);
|
|
535
|
-
removeEventListener("resize", handleReadingPositionChange);
|
|
536
|
-
removeEventListener("toggle", handleReadingPositionChange, true);
|
|
537
|
-
removeEventListener("pageshow", handleReadingPositionChange);
|
|
538
|
-
document.removeEventListener("DOMContentLoaded", handleReadingPositionChange);
|
|
539
|
-
};
|
|
540
|
-
}, [props.groups]);
|
|
541
|
-
return /* @__PURE__ */ jsxs4("nav", { className: clsx6("wg_navigationToc__root"), "aria-label": copy_nav_toc_label, children: [
|
|
542
|
-
/* @__PURE__ */ jsx6("div", { className: clsx6("wg_navigationToc__label"), children: copy_nav_toc_label }),
|
|
543
|
-
props.groups.map((group) => /* @__PURE__ */ jsxs4("div", { className: clsx6("wg_navigationToc__groupSection", { "wg_navigationToc__groupSection--named": group.part !== void 0 }), children: [
|
|
544
|
-
group.part !== void 0 && /* @__PURE__ */ jsx6("div", { className: clsx6("wg_navigationToc__group"), children: group.part }),
|
|
545
|
-
/* @__PURE__ */ jsx6("ul", { className: clsx6("wg_navigationToc__list"), children: group.sections.map((section) => /* @__PURE__ */ jsxs4("li", { className: clsx6("wg_navigationToc__item"), children: [
|
|
546
|
-
/* @__PURE__ */ jsx6(
|
|
547
|
-
"a",
|
|
548
|
-
{
|
|
549
|
-
className: clsx6("wg_navigationToc__link", { "wg_navigationToc__link--active": section.heading.slug === currentSlug }),
|
|
550
|
-
href: `#${section.heading.slug}`,
|
|
551
|
-
"data-toc-link": "",
|
|
552
|
-
"aria-current": section.heading.slug === currentSlug ? "location" : void 0,
|
|
553
|
-
children: section.heading.text
|
|
554
|
-
}
|
|
555
|
-
),
|
|
556
|
-
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(
|
|
557
|
-
"a",
|
|
558
|
-
{
|
|
559
|
-
className: clsx6("wg_navigationToc__subLink", { "wg_navigationToc__subLink--active": sub.heading.slug === currentSlug }),
|
|
560
|
-
href: `#${sub.heading.slug}`,
|
|
561
|
-
"data-toc-sub-link": "",
|
|
562
|
-
"aria-current": sub.heading.slug === currentSlug ? "location" : void 0,
|
|
563
|
-
children: sub.heading.text
|
|
564
|
-
}
|
|
565
|
-
) }, sub.heading.slug)) })
|
|
566
|
-
] }, section.heading.slug)) })
|
|
567
|
-
] }, group.sections[0].heading.slug))
|
|
568
|
-
] });
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
// src/store/navigation/navigation-storage.ts
|
|
572
|
-
var navigation_storage_version = 1;
|
|
573
|
-
var navigation_scroll_storage_key = "for-humanity:navigation-scroll";
|
|
574
|
-
|
|
575
|
-
// src/store/navigation/to-navigation-scroll-state.ts
|
|
576
|
-
var toNavigationScrollState = (value) => {
|
|
577
|
-
const toPosition = (position) => {
|
|
578
|
-
if (typeof position !== "object" || position === null || !("navigation" in position) || typeof position.navigation !== "string" || !("pathname" in position) || typeof position.pathname !== "string" || !("documents" in position) || typeof position.documents !== "number" || !Number.isFinite(position.documents) || position.documents < 0 || !("outline" in position) || typeof position.outline !== "number" || !Number.isFinite(position.outline) || position.outline < 0) {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
return { navigation: position.navigation, pathname: position.pathname, documents: position.documents, outline: position.outline };
|
|
582
|
-
};
|
|
583
|
-
if (typeof value !== "object" || value === null || !("positions" in value) || typeof value.positions !== "object" || value.positions === null) {
|
|
584
|
-
return { positions: {} };
|
|
585
|
-
}
|
|
586
|
-
const positions = {
|
|
587
|
-
wide: toPosition("wide" in value.positions ? value.positions.wide : void 0),
|
|
588
|
-
desktop: toPosition("desktop" in value.positions ? value.positions.desktop : void 0),
|
|
589
|
-
drawer: toPosition("drawer" in value.positions ? value.positions.drawer : void 0)
|
|
590
|
-
};
|
|
591
|
-
return { positions: Object.fromEntries(Object.entries(positions).filter((entry) => entry[1] !== void 0)) };
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
// src/util/dom/reveal-hash-target.ts
|
|
595
|
-
var revealHashTarget = (hash) => {
|
|
596
|
-
const target = findHashTarget(hash);
|
|
597
|
-
for (let fold = target?.closest("details"); fold; fold = fold.parentElement?.closest("details")) {
|
|
598
|
-
fold.open = true;
|
|
599
|
-
}
|
|
600
|
-
return target;
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
// src/component/widget/navigation/wg-navigation.tsx
|
|
604
|
-
import { jsx as jsx7, jsxs as jsxs5 } from "hono/jsx/jsx-runtime";
|
|
605
|
-
var WgNavigation = (props) => {
|
|
606
|
-
const [layout, setLayout] = useState3(() => {
|
|
607
|
-
if (props.stores === void 0) return "desktop";
|
|
608
|
-
if (matchMedia(navigation_mobile_query).matches) return "drawer";
|
|
609
|
-
return matchMedia(navigation_wide_query).matches ? "wide" : "desktop";
|
|
610
|
-
});
|
|
611
|
-
const [drawerOpen, setDrawerOpen] = useState3(false);
|
|
612
|
-
const navigationRef = useRef3(null);
|
|
613
|
-
const documentsRef = useRef3(null);
|
|
614
|
-
const drawerNavigationRef = useRef3(null);
|
|
615
|
-
const drawerDocumentsRef = useRef3(null);
|
|
616
|
-
const outlineRef = useRef3(null);
|
|
617
|
-
const dialogRef = useRef3(null);
|
|
618
|
-
const openButtonRef = useRef3(null);
|
|
619
|
-
const brandRef = useRef3(null);
|
|
620
|
-
const mobileRef = useRef3(null);
|
|
621
|
-
const wideRef = useRef3(null);
|
|
622
|
-
const layoutRef = useRef3(layout);
|
|
623
|
-
const focusRef = useRef3(null);
|
|
624
|
-
const restorePendingRef = useRef3(true);
|
|
625
|
-
const getNavigationLayout = () => {
|
|
626
|
-
if (mobileRef.current === null || wideRef.current === null) return layoutRef.current;
|
|
627
|
-
if (mobileRef.current.matches) return "drawer";
|
|
628
|
-
return wideRef.current.matches ? "wide" : "desktop";
|
|
629
|
-
};
|
|
630
|
-
const getNavigationPort = () => {
|
|
631
|
-
return layoutRef.current === "drawer" ? drawerNavigationRef.current : navigationRef.current;
|
|
632
|
-
};
|
|
633
|
-
const getDocumentsPort = () => {
|
|
634
|
-
return layoutRef.current === "drawer" ? drawerDocumentsRef.current : documentsRef.current;
|
|
635
|
-
};
|
|
636
|
-
const getNavigationSignature = () => {
|
|
637
|
-
const navigation = getNavigationPort();
|
|
638
|
-
if (navigation === null) return void 0;
|
|
639
|
-
return [...navigation.querySelectorAll(".wg_navigationNav__root a[href]")].map((link) => `${link.pathname}:${link.textContent}`).join("\n");
|
|
640
|
-
};
|
|
641
|
-
const saveScroll = () => {
|
|
642
|
-
const documents = getDocumentsPort();
|
|
643
|
-
if (props.stores === void 0 || documents === null || outlineRef.current === null || restorePendingRef.current || layoutRef.current !== getNavigationLayout() || layoutRef.current === "drawer" && dialogRef.current?.open !== true) {
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
|
-
const signature = getNavigationSignature();
|
|
647
|
-
if (signature === void 0) return;
|
|
648
|
-
const navigationPosition = {
|
|
649
|
-
navigation: signature,
|
|
650
|
-
pathname: location.pathname,
|
|
651
|
-
documents: documents.scrollTop,
|
|
652
|
-
outline: outlineRef.current.scrollTop
|
|
653
|
-
};
|
|
654
|
-
props.stores.scroll.setState((state) => ({
|
|
655
|
-
positions: {
|
|
656
|
-
...state.positions,
|
|
657
|
-
[layoutRef.current]: navigationPosition
|
|
658
|
-
}
|
|
659
|
-
}));
|
|
660
|
-
};
|
|
661
|
-
const restoreScroll = () => {
|
|
662
|
-
layoutRef.current = getNavigationLayout();
|
|
663
|
-
const documents = getDocumentsPort();
|
|
664
|
-
const navigation = getNavigationPort();
|
|
665
|
-
if (props.stores === void 0 || documents === null || outlineRef.current === null || navigation === null) return;
|
|
666
|
-
if (layoutRef.current === "drawer" && dialogRef.current?.open !== true) return;
|
|
667
|
-
const signature = getNavigationSignature();
|
|
668
|
-
if (signature === void 0) return;
|
|
669
|
-
const position = props.stores.scroll.getState().positions[layoutRef.current];
|
|
670
|
-
documents.scrollTop = 0;
|
|
671
|
-
outlineRef.current.scrollTop = 0;
|
|
672
|
-
if (position === void 0) {
|
|
673
|
-
restoreNavigationScroll({ key: navigation_scroll_storage_key, version: navigation_storage_version, layout: layoutRef.current, toState: toNavigationScrollState });
|
|
674
|
-
} else if (position.navigation === signature) {
|
|
675
|
-
documents.scrollTop = position.documents;
|
|
676
|
-
if (position.pathname === location.pathname) outlineRef.current.scrollTop = position.outline;
|
|
677
|
-
}
|
|
678
|
-
navigation.dataset.navigationLayout = layoutRef.current;
|
|
679
|
-
restorePendingRef.current = false;
|
|
680
|
-
saveScroll();
|
|
681
|
-
documents.dispatchEvent(new Event("scroll"));
|
|
682
|
-
outlineRef.current.dispatchEvent(new Event("scroll"));
|
|
683
|
-
};
|
|
684
|
-
const handleDrawerClose = (_event) => {
|
|
685
|
-
if (dialogRef.current?.open === true) return;
|
|
686
|
-
document.body.classList.remove("wg_shell__root--drawerOpen");
|
|
687
|
-
setDrawerOpen(false);
|
|
688
|
-
};
|
|
689
|
-
const closeNavigation = () => {
|
|
690
|
-
saveScroll();
|
|
691
|
-
dialogRef.current?.close();
|
|
692
|
-
document.body.classList.remove("wg_shell__root--drawerOpen");
|
|
693
|
-
setDrawerOpen(false);
|
|
694
|
-
};
|
|
695
|
-
const handleOpenButtonClick = (_event) => {
|
|
696
|
-
if (getNavigationLayout() !== "drawer" || dialogRef.current === null || dialogRef.current.open) return;
|
|
697
|
-
dialogRef.current.showModal();
|
|
698
|
-
document.body.classList.add("wg_shell__root--drawerOpen");
|
|
699
|
-
setDrawerOpen(true);
|
|
700
|
-
restoreScroll();
|
|
701
|
-
};
|
|
702
|
-
const handleCloseButtonClick = (_event) => {
|
|
703
|
-
closeNavigation();
|
|
704
|
-
};
|
|
705
|
-
const handleDrawerCancel = (event) => {
|
|
706
|
-
event.preventDefault();
|
|
707
|
-
closeNavigation();
|
|
708
|
-
};
|
|
709
|
-
const handleDrawerClick = (event) => {
|
|
710
|
-
if (dialogRef.current === null || event.target !== dialogRef.current) return;
|
|
711
|
-
const bounds = dialogRef.current.getBoundingClientRect();
|
|
712
|
-
if (event.clientX < bounds.left || event.clientX > bounds.right || event.clientY < bounds.top || event.clientY > bounds.bottom) closeNavigation();
|
|
713
|
-
};
|
|
714
|
-
const handleNavigationClick = (event) => {
|
|
715
|
-
saveScroll();
|
|
716
|
-
if (dialogRef.current?.open !== true || event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || !(event.target instanceof Element)) {
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
const link = event.target.closest("a[href]");
|
|
720
|
-
if (!(link instanceof HTMLAnchorElement) || link.target !== "" && link.target !== "_self" || link.hasAttribute("download")) return;
|
|
721
|
-
closeNavigation();
|
|
722
|
-
if (link.origin === location.origin && link.pathname === location.pathname && link.search === location.search && link.hash) {
|
|
723
|
-
const target = revealHashTarget(link.hash);
|
|
724
|
-
if (target !== null) {
|
|
725
|
-
target.tabIndex = -1;
|
|
726
|
-
target.focus({ preventScroll: true });
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
};
|
|
730
|
-
const handleLayoutChange = () => {
|
|
731
|
-
const nextLayout = getNavigationLayout();
|
|
732
|
-
if (nextLayout === layoutRef.current) return;
|
|
733
|
-
if (document.activeElement instanceof HTMLElement) {
|
|
734
|
-
focusRef.current = {
|
|
735
|
-
navigation: document.activeElement.closest("[data-navigation]") !== null,
|
|
736
|
-
drawer: document.activeElement === openButtonRef.current || document.activeElement.closest("[data-navigation-drawer]") !== null,
|
|
737
|
-
href: document.activeElement.getAttribute("href")
|
|
738
|
-
};
|
|
739
|
-
}
|
|
740
|
-
if (nextLayout !== "drawer") closeNavigation();
|
|
741
|
-
restorePendingRef.current = true;
|
|
742
|
-
layoutRef.current = nextLayout;
|
|
743
|
-
flushSync(() => setLayout(nextLayout));
|
|
744
|
-
};
|
|
745
|
-
const handlePageShow = (event) => {
|
|
746
|
-
if (!event.persisted || props.stores === void 0) return;
|
|
747
|
-
restorePendingRef.current = true;
|
|
748
|
-
flushSync(() => props.stores?.scroll.persist.rehydrate());
|
|
749
|
-
handleLayoutChange();
|
|
750
|
-
restoreScroll();
|
|
751
|
-
};
|
|
752
|
-
useLayoutEffect4(() => {
|
|
753
|
-
if (props.stores === void 0) return;
|
|
754
|
-
mobileRef.current = matchMedia(navigation_mobile_query);
|
|
755
|
-
wideRef.current = matchMedia(navigation_wide_query);
|
|
756
|
-
mobileRef.current.addEventListener("change", handleLayoutChange);
|
|
757
|
-
wideRef.current.addEventListener("change", handleLayoutChange);
|
|
758
|
-
addEventListener("pagehide", saveScroll);
|
|
759
|
-
addEventListener("pageshow", handlePageShow);
|
|
760
|
-
return () => {
|
|
761
|
-
mobileRef.current?.removeEventListener("change", handleLayoutChange);
|
|
762
|
-
wideRef.current?.removeEventListener("change", handleLayoutChange);
|
|
763
|
-
mobileRef.current = null;
|
|
764
|
-
wideRef.current = null;
|
|
765
|
-
removeEventListener("pagehide", saveScroll);
|
|
766
|
-
removeEventListener("pageshow", handlePageShow);
|
|
767
|
-
document.body.classList.remove("wg_shell__root--drawerOpen");
|
|
768
|
-
};
|
|
769
|
-
}, [props.stores]);
|
|
770
|
-
useLayoutEffect4(() => {
|
|
771
|
-
if (props.stores === void 0) return;
|
|
772
|
-
let active = true;
|
|
773
|
-
const restoreNavigation = () => {
|
|
774
|
-
if (!active) return;
|
|
775
|
-
restoreScroll();
|
|
776
|
-
if (focusRef.current === null) return;
|
|
777
|
-
const navigation = getNavigationPort();
|
|
778
|
-
if (layout === "drawer") {
|
|
779
|
-
if (focusRef.current.navigation) openButtonRef.current?.focus({ preventScroll: true });
|
|
780
|
-
} else if (focusRef.current.navigation && navigation !== null) {
|
|
781
|
-
const href = focusRef.current.href;
|
|
782
|
-
const target = [...navigation.querySelectorAll("a[href]")].find((element) => element.getAttribute("href") === href);
|
|
783
|
-
target?.focus({ preventScroll: true });
|
|
784
|
-
} else if (focusRef.current.drawer) {
|
|
785
|
-
brandRef.current?.focus({ preventScroll: true });
|
|
786
|
-
}
|
|
787
|
-
focusRef.current = null;
|
|
788
|
-
};
|
|
789
|
-
if (getDocumentsPort()?.isConnected) {
|
|
790
|
-
restoreNavigation();
|
|
791
|
-
} else {
|
|
792
|
-
queueMicrotask(restoreNavigation);
|
|
793
|
-
}
|
|
794
|
-
return () => {
|
|
795
|
-
active = false;
|
|
796
|
-
};
|
|
797
|
-
}, [layout, props.stores]);
|
|
798
|
-
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
799
|
-
/* @__PURE__ */ jsxs5("div", { className: clsx7("wg_navigation__sidebar", props.stores !== void 0 && "wg_navigation__sidebar--navigationReady"), children: [
|
|
800
|
-
/* @__PURE__ */ jsxs5("div", { className: clsx7("wg_navigation__brandRow"), children: [
|
|
801
|
-
/* @__PURE__ */ jsx7(
|
|
802
|
-
"a",
|
|
803
|
-
{
|
|
804
|
-
ref: props.stores === void 0 ? void 0 : brandRef,
|
|
805
|
-
className: clsx7("wg_navigation__brand"),
|
|
806
|
-
href: "/",
|
|
807
|
-
"aria-current": props.data.home ? "page" : void 0,
|
|
808
|
-
children: props.data.title
|
|
809
|
-
}
|
|
810
|
-
),
|
|
811
|
-
/* @__PURE__ */ jsx7(
|
|
812
|
-
"button",
|
|
813
|
-
{
|
|
814
|
-
ref: props.stores === void 0 ? void 0 : openButtonRef,
|
|
815
|
-
className: clsx7("wg_navigation__menuToggle", props.stores !== void 0 && layout === "drawer" && "wg_navigation__menuToggle--visible"),
|
|
816
|
-
type: "button",
|
|
817
|
-
"aria-label": copy_nav_open,
|
|
818
|
-
"aria-controls": "fh-navigation-drawer",
|
|
819
|
-
"aria-expanded": String(drawerOpen),
|
|
820
|
-
"data-navigation-open": "",
|
|
821
|
-
onClick: handleOpenButtonClick,
|
|
822
|
-
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" }) })
|
|
823
|
-
}
|
|
824
|
-
)
|
|
825
|
-
] }),
|
|
826
|
-
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 }) }) })
|
|
827
|
-
] }),
|
|
828
|
-
/* @__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 }) }) }) }),
|
|
829
|
-
/* @__PURE__ */ jsxs5(
|
|
830
|
-
"dialog",
|
|
831
|
-
{
|
|
832
|
-
ref: props.stores === void 0 ? void 0 : dialogRef,
|
|
833
|
-
className: clsx7("wg_navigation__drawer"),
|
|
834
|
-
id: "fh-navigation-drawer",
|
|
835
|
-
"aria-labelledby": "fh-navigation-title",
|
|
836
|
-
"data-navigation-drawer": "",
|
|
837
|
-
onClose: handleDrawerClose,
|
|
838
|
-
onCancel: handleDrawerCancel,
|
|
839
|
-
onClick: handleDrawerClick,
|
|
840
|
-
children: [
|
|
841
|
-
/* @__PURE__ */ jsxs5("div", { className: clsx7("wg_navigation__drawerHeader"), children: [
|
|
842
|
-
/* @__PURE__ */ jsx7("h2", { className: clsx7("wg_navigation__drawerTitle"), id: "fh-navigation-title", children: copy_nav_title }),
|
|
843
|
-
/* @__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" }) }) })
|
|
844
|
-
] }),
|
|
845
|
-
/* @__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(
|
|
846
|
-
WgNavigationScroll,
|
|
847
|
-
{
|
|
848
|
-
portRef: drawerDocumentsRef,
|
|
849
|
-
kind: "documents",
|
|
850
|
-
ready: props.stores !== void 0,
|
|
851
|
-
onScroll: saveScroll,
|
|
852
|
-
onClick: handleNavigationClick,
|
|
853
|
-
children: /* @__PURE__ */ jsx7(WgNavigationNav, { groups: props.data.groups })
|
|
854
|
-
}
|
|
855
|
-
) }) })
|
|
856
|
-
]
|
|
857
|
-
}
|
|
858
|
-
)
|
|
859
|
-
] });
|
|
860
|
-
};
|
|
861
|
-
|
|
862
|
-
// src/component/widget/prose/_constant/heading-highlight.ts
|
|
863
|
-
var heading_highlight_hold_ms = 3e3;
|
|
864
|
-
|
|
865
|
-
// src/component/widget/shell-controls/wg-shell-controls.tsx
|
|
866
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "hono/jsx/jsx-runtime";
|
|
867
|
-
var WgShellControls = (props) => {
|
|
868
|
-
const headingRef = useRef4(null);
|
|
869
|
-
const timerRef = useRef4(0);
|
|
870
|
-
const arrivalRef = useRef4(null);
|
|
871
|
-
const lifetimeRef = useRef4(null);
|
|
872
|
-
const userScrollRef = useRef4(null);
|
|
873
|
-
const clearHeadingHighlight = () => {
|
|
874
|
-
clearTimeout(timerRef.current);
|
|
875
|
-
timerRef.current = 0;
|
|
876
|
-
arrivalRef.current?.abort();
|
|
877
|
-
arrivalRef.current = null;
|
|
878
|
-
headingRef.current?.classList.remove("wg_prose__headingText--highlighted");
|
|
879
|
-
headingRef.current = null;
|
|
880
|
-
};
|
|
881
|
-
const handleHighlightArrival = (event) => {
|
|
882
|
-
if (event.target !== document) return;
|
|
883
|
-
clearTimeout(timerRef.current);
|
|
884
|
-
arrivalRef.current?.abort();
|
|
885
|
-
arrivalRef.current = null;
|
|
886
|
-
timerRef.current = window.setTimeout(clearHeadingHighlight, heading_highlight_hold_ms);
|
|
887
|
-
};
|
|
888
|
-
const highlightHeading = (target) => {
|
|
889
|
-
clearHeadingHighlight();
|
|
890
|
-
headingRef.current = target === null ? null : target.querySelector(".wg_prose__headingText");
|
|
891
|
-
if (headingRef.current === null) return;
|
|
892
|
-
headingRef.current.classList.add("wg_prose__headingText--highlighted");
|
|
893
|
-
timerRef.current = window.setTimeout(clearHeadingHighlight, heading_highlight_hold_ms);
|
|
894
|
-
arrivalRef.current = new AbortController();
|
|
895
|
-
document.addEventListener("scrollend", handleHighlightArrival, { signal: arrivalRef.current.signal });
|
|
896
|
-
};
|
|
897
|
-
const handleHashClick = (event) => {
|
|
898
|
-
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
899
|
-
const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
|
|
900
|
-
if (link instanceof HTMLAnchorElement && (link.target === "" || link.target === "_self") && !link.hasAttribute("download") && link.origin === location.origin && link.pathname === location.pathname && link.search === location.search && link.hash) {
|
|
901
|
-
const target = revealHashTarget(link.hash);
|
|
902
|
-
if (link.hash === location.hash) highlightHeading(target);
|
|
903
|
-
}
|
|
904
|
-
};
|
|
905
|
-
const handleHashChange = () => {
|
|
906
|
-
const target = revealHashTarget(location.hash);
|
|
907
|
-
target?.scrollIntoView();
|
|
908
|
-
highlightHeading(target);
|
|
909
|
-
};
|
|
910
|
-
const handleUserScroll = () => {
|
|
911
|
-
userScrollRef.current?.abort();
|
|
912
|
-
};
|
|
913
|
-
const handlePageLoad = async () => {
|
|
914
|
-
const lifetime = lifetimeRef.current;
|
|
915
|
-
const hash = location.hash;
|
|
916
|
-
const target = revealHashTarget(hash);
|
|
917
|
-
await document.fonts.ready;
|
|
918
|
-
if (lifetime === null || lifetime.signal.aborted) return;
|
|
919
|
-
if (target !== null && !userScrollRef.current?.signal.aborted && hash === location.hash) {
|
|
920
|
-
target.scrollIntoView({ behavior: "instant" });
|
|
921
|
-
highlightHeading(target);
|
|
922
|
-
}
|
|
923
|
-
document.documentElement.style.removeProperty("scroll-behavior");
|
|
924
|
-
};
|
|
925
|
-
const handleBodyReady = () => {
|
|
926
|
-
revealHashTarget(location.hash);
|
|
927
|
-
if (document.readyState === "complete") void handlePageLoad();
|
|
928
|
-
};
|
|
929
|
-
useLayoutEffect5(() => {
|
|
930
|
-
const lifetime = new AbortController();
|
|
931
|
-
lifetimeRef.current = lifetime;
|
|
932
|
-
userScrollRef.current = new AbortController();
|
|
933
|
-
document.documentElement.style.scrollBehavior = "auto";
|
|
934
|
-
document.addEventListener("click", handleHashClick, { signal: lifetime.signal });
|
|
935
|
-
addEventListener("hashchange", handleHashChange, { signal: lifetime.signal });
|
|
936
|
-
addEventListener("load", handlePageLoad, { once: true, signal: lifetime.signal });
|
|
937
|
-
for (const type of ["wheel", "touchmove", "keydown", "mousedown"]) {
|
|
938
|
-
addEventListener(type, handleUserScroll, { once: true, passive: true, signal: lifetime.signal });
|
|
939
|
-
}
|
|
940
|
-
if (document.readyState === "loading") {
|
|
941
|
-
document.addEventListener("DOMContentLoaded", handleBodyReady, { once: true, signal: lifetime.signal });
|
|
942
|
-
} else {
|
|
943
|
-
handleBodyReady();
|
|
944
|
-
}
|
|
945
|
-
return () => {
|
|
946
|
-
lifetime.abort();
|
|
947
|
-
lifetimeRef.current = null;
|
|
948
|
-
userScrollRef.current?.abort();
|
|
949
|
-
userScrollRef.current = null;
|
|
950
|
-
clearHeadingHighlight();
|
|
951
|
-
document.documentElement.style.removeProperty("scroll-behavior");
|
|
952
|
-
};
|
|
953
|
-
}, []);
|
|
954
|
-
useEffect(() => {
|
|
955
|
-
if (!props.reload || lifetimeRef.current === null) return;
|
|
956
|
-
const source = new EventSource(asset_reload_path);
|
|
957
|
-
source.onmessage = () => location.reload();
|
|
958
|
-
return () => source.close();
|
|
959
|
-
}, [props.reload]);
|
|
960
|
-
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
961
|
-
/* @__PURE__ */ jsx8("div", { className: clsx8("wg_shellControls__navigation"), children: /* @__PURE__ */ jsx8(WgNavigation, { data: props.data, stores: props.stores }) }),
|
|
962
|
-
props.data.cursorFace && /* @__PURE__ */ jsx8(WgCursorFace, { ready: props.stores !== void 0 })
|
|
963
|
-
] });
|
|
964
|
-
};
|
|
965
|
-
|
|
966
|
-
// src/component/widget/shell/wg-shell.tsx
|
|
967
|
-
import { jsx as jsx9, jsxs as jsxs7 } from "hono/jsx/jsx-runtime";
|
|
968
|
-
var WgShell = (props) => {
|
|
969
|
-
const navigationData = toNavigationData({ site: props.site, docs: props.docs, current: props.current, outline: props.outline });
|
|
970
|
-
return /* @__PURE__ */ jsxs7("html", { lang: "ko", children: [
|
|
971
|
-
/* @__PURE__ */ jsxs7("head", { children: [
|
|
972
|
-
/* @__PURE__ */ jsx9("meta", { charSet: "utf-8" }),
|
|
973
|
-
/* @__PURE__ */ jsx9("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
|
|
974
|
-
props.site.description !== void 0 && /* @__PURE__ */ jsx9("meta", { name: "description", content: props.site.description }),
|
|
975
|
-
/* @__PURE__ */ jsx9("title", { children: props.title === void 0 ? props.site.title : `${props.title} \xB7 ${props.site.title}` }),
|
|
976
|
-
/* @__PURE__ */ jsx9("link", { rel: "icon", href: asset_favicon_path, type: "image/svg+xml" }),
|
|
977
|
-
/* @__PURE__ */ jsx9("style", { dangerouslySetInnerHTML: { __html: props.assets.fontCss } }),
|
|
978
|
-
props.assets.preload.map((href) => /* @__PURE__ */ jsx9("link", { rel: "preload", href, as: "font", type: "font/woff2", crossOrigin: "" }, href)),
|
|
979
|
-
/* @__PURE__ */ jsx9("link", { rel: "stylesheet", href: props.assets.stylePath })
|
|
980
|
-
] }),
|
|
981
|
-
/* @__PURE__ */ jsxs7("body", { className: clsx9("wg_shell__root"), children: [
|
|
982
|
-
/* @__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 }) }),
|
|
983
|
-
/* @__PURE__ */ jsx9("script", { type: "application/json", id: "fh-navigation-data", dangerouslySetInnerHTML: { __html: toNavigationJson(navigationData) } }),
|
|
984
|
-
/* @__PURE__ */ jsx9("script", { dangerouslySetInnerHTML: { __html: props.assets.browserScript } }),
|
|
985
|
-
/* @__PURE__ */ jsx9("main", { className: clsx9("wg_shell__main"), children: props.children })
|
|
986
|
-
] })
|
|
987
|
-
] });
|
|
988
|
-
};
|
|
989
|
-
|
|
990
|
-
// src/page/doc/pg-doc.tsx
|
|
991
|
-
import { jsx as jsx10 } from "hono/jsx/jsx-runtime";
|
|
992
|
-
var PgDoc = (props) => {
|
|
993
|
-
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 }) });
|
|
994
|
-
};
|
|
995
|
-
|
|
996
|
-
// src/page/home/pg-home.tsx
|
|
997
|
-
import { jsx as jsx11 } from "hono/jsx/jsx-runtime";
|
|
998
|
-
var PgHome = (props) => {
|
|
999
|
-
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 }) });
|
|
1000
|
-
};
|
|
1001
|
-
|
|
1002
|
-
// src/entry/cli/_function/create-app.tsx
|
|
1003
|
-
import { jsx as jsx12 } from "hono/jsx/jsx-runtime";
|
|
1004
|
-
var toHtml = (page) => {
|
|
1005
|
-
return html`<!DOCTYPE html>${page}`;
|
|
1006
|
-
};
|
|
1007
|
-
var createApp = (options) => {
|
|
1008
|
-
const app = new Hono();
|
|
1009
|
-
app.get("/", (c) => c.html(toHtml(/* @__PURE__ */ jsx12(PgHome, { site: options.site, docs: options.store.docs, assets: options.assets, home: options.store.home }))));
|
|
1010
|
-
app.get(
|
|
1011
|
-
"/:slug{.+}/",
|
|
1012
|
-
ssgParams(() => options.store.docs.map((doc) => ({ slug: doc.id }))),
|
|
1013
|
-
(c) => {
|
|
1014
|
-
const doc = options.store.docs.find((entry) => entry.id === c.req.param("slug"));
|
|
1015
|
-
return doc === void 0 ? c.notFound() : c.html(toHtml(/* @__PURE__ */ jsx12(PgDoc, { site: options.site, docs: options.store.docs, assets: options.assets, doc })));
|
|
1016
|
-
}
|
|
1017
|
-
);
|
|
1018
|
-
return app;
|
|
1019
|
-
};
|
|
1020
|
-
|
|
1021
|
-
// src/entry/cli/_function/create-dev-app.ts
|
|
2
|
+
import { t as logger } from "./logger-Dv1i9xSV.js";
|
|
1022
3
|
import { readFile } from "node:fs/promises";
|
|
1023
|
-
import {
|
|
1024
|
-
import {
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
};
|
|
1112
|
-
|
|
1113
|
-
// src/component/widget/prose/_function/rehype-sections/rehype-sections.ts
|
|
1114
|
-
var rehypeSections = () => (tree, file) => {
|
|
1115
|
-
if (file.data.fh === void 0) {
|
|
1116
|
-
return;
|
|
1117
|
-
}
|
|
1118
|
-
file.data.fh.sections = toSectionHeadings(tree).map(
|
|
1119
|
-
(heading) => ({
|
|
1120
|
-
part: typeof heading.properties.dataPart === "string" ? heading.properties.dataPart : void 0
|
|
1121
|
-
})
|
|
1122
|
-
);
|
|
1123
|
-
};
|
|
1124
|
-
|
|
1125
|
-
// src/component/widget/prose/_function/rehype-tables.ts
|
|
1126
|
-
import { SKIP, visit } from "unist-util-visit";
|
|
1127
|
-
var rehypeTables = () => (tree) => {
|
|
1128
|
-
visit(tree, "element", (node, index, parent) => {
|
|
1129
|
-
if (node.tagName !== "table" || parent === void 0 || index === void 0) {
|
|
1130
|
-
return;
|
|
1131
|
-
}
|
|
1132
|
-
parent.children[index] = {
|
|
1133
|
-
type: "element",
|
|
1134
|
-
tagName: "div",
|
|
1135
|
-
properties: { className: ["wg_prose__table"] },
|
|
1136
|
-
children: [node]
|
|
1137
|
-
};
|
|
1138
|
-
return [SKIP, index + 1];
|
|
1139
|
-
});
|
|
1140
|
-
};
|
|
1141
|
-
|
|
1142
|
-
// src/component/widget/prose/_function/remark-blocks.ts
|
|
1143
|
-
import { toString as toPlainText } from "mdast-util-to-string";
|
|
1144
|
-
import { visit as visit2 } from "unist-util-visit";
|
|
1145
|
-
|
|
1146
|
-
// src/component/widget/prose/_function/has-block-content.ts
|
|
1147
|
-
var hasBlockContent = (node) => {
|
|
1148
|
-
if (node.type === "definition") {
|
|
1149
|
-
return false;
|
|
1150
|
-
}
|
|
1151
|
-
if (node.type === "html") {
|
|
1152
|
-
return node.value.replace(/<!--(?:>|->|[\s\S]*?(?:--!?>|$))/g, "").trim() !== "";
|
|
1153
|
-
}
|
|
1154
|
-
if ("value" in node) {
|
|
1155
|
-
return node.value.trim() !== "";
|
|
1156
|
-
}
|
|
1157
|
-
if (node.type === "table" || node.type === "textDirective") {
|
|
1158
|
-
return true;
|
|
1159
|
-
}
|
|
1160
|
-
if ("children" in node) {
|
|
1161
|
-
return node.children.some(hasBlockContent);
|
|
1162
|
-
}
|
|
1163
|
-
return true;
|
|
1164
|
-
};
|
|
1165
|
-
|
|
1166
|
-
// src/component/widget/prose/_function/remark-blocks.ts
|
|
1167
|
-
var remarkBlocks = () => (tree, file) => {
|
|
1168
|
-
const source = String(file.value);
|
|
1169
|
-
visit2(tree, (node, _index, parent) => {
|
|
1170
|
-
if (node.type === "leafDirective" && node.name === "part" && parent?.type !== "root") {
|
|
1171
|
-
file.fail(`${copy_error_directive_syntax}: part \xB7 \uBB38\uC11C \uCD5C\uC0C1\uC704\uC5D0 \uC791\uC131`, node);
|
|
1172
|
-
}
|
|
1173
|
-
if (node.type !== "containerDirective" && node.type !== "leafDirective" && node.type !== "textDirective") {
|
|
1174
|
-
return;
|
|
1175
|
-
}
|
|
1176
|
-
if (node.name !== "note" && node.name !== "details") {
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
|
-
if (node.type !== "containerDirective") {
|
|
1180
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 ::: \uBE14\uB85D\uC73C\uB85C \uC791\uC131`, node);
|
|
1181
|
-
}
|
|
1182
|
-
const label = node.children.at(0);
|
|
1183
|
-
if (label?.type !== "paragraph" || label.data?.directiveLabel !== true || label.children.some((child) => child.type !== "text")) {
|
|
1184
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uC77C\uBC18 \uD14D\uC2A4\uD2B8 \uC81C\uBAA9 \uD544\uC218`, node);
|
|
1185
|
-
}
|
|
1186
|
-
const title = toPlainText(label).trim();
|
|
1187
|
-
if (title === "") {
|
|
1188
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBE44\uC5B4 \uC788\uC9C0 \uC54A\uC740 \uC81C\uBAA9 \uD544\uC218`, node);
|
|
1189
|
-
}
|
|
1190
|
-
if (!node.children.slice(1).some(hasBlockContent)) {
|
|
1191
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBCF8\uBB38 \uD544\uC218`, node);
|
|
1192
|
-
}
|
|
1193
|
-
const unsupported = node.attributes ? Object.keys(node.attributes).find((key) => node.name !== "details" || key !== "open") : void 0;
|
|
1194
|
-
if (unsupported !== void 0) {
|
|
1195
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBBF8\uC9C0\uC6D0 \uC18D\uC131 ${unsupported}`, node);
|
|
1196
|
-
}
|
|
1197
|
-
const open = node.attributes?.open;
|
|
1198
|
-
const attributeSource = source.slice(label.position?.end.offset, node.position?.end.offset).split(/\r?\n/, 1)[0].trim();
|
|
1199
|
-
if (attributeSource !== "" && (node.name !== "details" || !/^\{[ \t]*open[ \t]*\}$/.test(attributeSource))) {
|
|
1200
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uD5C8\uC6A9 \uC18D\uC131\uC740 Details\uC758 {open}, \uB098\uBA38\uC9C0\uB294 \uC0DD\uB7B5`, node);
|
|
1201
|
-
}
|
|
1202
|
-
const original = source.slice(node.position?.start.offset, node.position?.end.offset);
|
|
1203
|
-
const opening = /^(:{3,})/.exec(original);
|
|
1204
|
-
const closing = /(?:^|\n)[ \t>]*(:{3,})[ \t]*\r?$/.exec(original);
|
|
1205
|
-
if (opening === null || closing === null || closing.index + closing[0].length !== original.length || closing[1].length < opening[1].length || node.position?.end.offset === node.children.at(-1)?.position?.end.offset) {
|
|
1206
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBE14\uB85D\uC744 \uB2EB\uB294 fence \uD544\uC218`, node);
|
|
1207
|
-
}
|
|
1208
|
-
visit2(node, "heading", (heading) => {
|
|
1209
|
-
if (heading.depth <= section_heading_depth.section) {
|
|
1210
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 #\xB7## \uC81C\uBAA9\uC740 \uBD80\uD488 \uBC16\uC5D0 \uC791\uC131`, heading);
|
|
1211
|
-
}
|
|
1212
|
-
});
|
|
1213
|
-
visit2(node, "code", (code) => {
|
|
1214
|
-
const originalCode = source.slice(code.position?.start.offset, code.position?.end.offset);
|
|
1215
|
-
const codeOpening = /^ {0,3}(`{3,}|~{3,})/.exec(originalCode);
|
|
1216
|
-
const codeClosing = /(?:^|\n)[ \t>]*(`{3,}|~{3,})[ \t]*\r?$/.exec(originalCode);
|
|
1217
|
-
if (codeOpening !== null && (codeClosing === null || codeClosing.index + codeClosing[0].length !== originalCode.length || codeClosing[1][0] !== codeOpening[1][0] || codeClosing[1].length < codeOpening[1].length)) {
|
|
1218
|
-
file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uCF54\uB4DC fence\uB97C \uB2EB\uACE0, \uCF54\uB4DC \uC548\uC758 :\uBCF4\uB2E4 \uAE34 \uBC14\uAE65 fence \uC0AC\uC6A9`, code);
|
|
1219
|
-
}
|
|
1220
|
-
});
|
|
1221
|
-
label.children = [{ type: "text", value: title }];
|
|
1222
|
-
label.data = {
|
|
1223
|
-
...label.data,
|
|
1224
|
-
hName: node.name === "note" ? "strong" : "summary",
|
|
1225
|
-
hProperties: { className: [node.name === "note" ? "wg_prose__noteTitle" : "wg_prose__detailsSummary"] }
|
|
1226
|
-
};
|
|
1227
|
-
node.data = {
|
|
1228
|
-
...node.data,
|
|
1229
|
-
hName: node.name === "note" ? "aside" : "details",
|
|
1230
|
-
hProperties: node.name === "note" ? { className: ["wg_prose__note"], ariaLabel: title } : { className: ["wg_prose__details"], open: open === "" }
|
|
1231
|
-
};
|
|
1232
|
-
});
|
|
1233
|
-
};
|
|
1234
|
-
|
|
1235
|
-
// src/component/widget/prose/_function/remark-flow.ts
|
|
1236
|
-
import { visit as visit3 } from "unist-util-visit";
|
|
1237
|
-
|
|
1238
|
-
// src/util/mermaid/render-flow.js
|
|
1239
|
-
import { renderMermaidASCII } from "beautiful-mermaid";
|
|
1240
|
-
var esc = (s) => String(s == null ? "" : s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1241
|
-
var ASCII_OPT = { paddingX: 3, paddingY: 2, boxBorderPadding: 1, colorMode: "none" };
|
|
1242
|
-
var WIDE = /[ᄀ-ᇿ -〿-가-一-鿿-ヿ-⦆]/;
|
|
1243
|
-
var ZW = "\u200B";
|
|
1244
|
-
var widenCjk = (src) => src.replace(new RegExp(WIDE.source, "g"), (c) => c + ZW);
|
|
1245
|
-
var LINES = {
|
|
1246
|
-
"\u2500": "LR",
|
|
1247
|
-
"\u2502": "UD",
|
|
1248
|
-
"\u250C": "RD",
|
|
1249
|
-
"\u2510": "LD",
|
|
1250
|
-
"\u2514": "RU",
|
|
1251
|
-
"\u2518": "LU",
|
|
1252
|
-
"\u251C": "UDR",
|
|
1253
|
-
"\u2524": "UDL",
|
|
1254
|
-
"\u252C": "LRD",
|
|
1255
|
-
"\u2534": "LRU",
|
|
1256
|
-
"\u253C": "LRUD",
|
|
1257
|
-
"\u256D": "RDr",
|
|
1258
|
-
"\u256E": "LDr",
|
|
1259
|
-
"\u2570": "RUr",
|
|
1260
|
-
"\u256F": "LUr",
|
|
1261
|
-
"\u2550": "LRb",
|
|
1262
|
-
"\u2551": "UDb",
|
|
1263
|
-
"\u2554": "RDb",
|
|
1264
|
-
"\u2557": "LDb",
|
|
1265
|
-
"\u255A": "RUb",
|
|
1266
|
-
"\u255D": "LUb",
|
|
1267
|
-
"\u255F": "UDRb",
|
|
1268
|
-
"\u2562": "UDLb",
|
|
1269
|
-
"\u254C": "LRd",
|
|
1270
|
-
"\u254E": "UDd"
|
|
1271
|
-
};
|
|
1272
|
-
var ARROWS = { "\u25BA": "R", "\u25C4": "L", "\u25BC": "D", "\u25B2": "U", "\u25B6": "R", "\u25C0": "L" };
|
|
1273
|
-
var isWall = (chr) => chr === "\u2502" || chr === "\u25C7" || chr === "\u251C" || chr === "\u2524";
|
|
1274
|
-
var isHBorder = (chr) => chr !== void 0 && chr !== " " && chr !== ZW && (LINES[chr] !== void 0 || chr === "\u25C7");
|
|
1275
|
-
function widenLabelGaps(rows) {
|
|
1276
|
-
const width = Math.max.apply(null, rows.map((r) => r.length));
|
|
1277
|
-
let grid = rows.map((r) => r.padEnd(width));
|
|
1278
|
-
const H = new Set("\u2500\u252C\u2534\u251C\u2524\u253C\u25C7\u250C\u2510\u2514\u2518\u256D\u256E\u2570\u256F\u2550\u254C\u25BA\u25C4\u25B6\u25C0\u2554\u2557\u255A\u255D\u255F\u2562".split(""));
|
|
1279
|
-
const ANCHOR = new Set("\u251C\u2524\u252C\u2534\u253C\u2514\u2518\u250C\u2510\u256D\u256E\u2570\u256F".split(""));
|
|
1280
|
-
const END = new Set("\u25BA\u25B6\u25C4\u25C0\u2524\u251C\u252C\u2534\u253C\u2510\u2518\u250C\u2514\u256E\u256F\u256D\u2570\u2502".split(""));
|
|
1281
|
-
const isTxt = (chr) => chr !== void 0 && chr !== " " && chr !== ZW && chr !== "\u2502" && !H.has(chr);
|
|
1282
|
-
const txtish = (chr) => isTxt(chr) || chr === ZW;
|
|
1283
|
-
const splittable = (col) => grid.every((r) => !(txtish(r[col - 1]) && txtish(r[col])));
|
|
1284
|
-
const filler = (r, col) => {
|
|
1285
|
-
const l = r[col - 1], rt = r[col];
|
|
1286
|
-
if (l === void 0 || rt === void 0) return " ";
|
|
1287
|
-
if ((H.has(l) || txtish(l)) && (H.has(rt) || rt === "\u2502" || txtish(rt)) && !(txtish(l) && txtish(rt))) {
|
|
1288
|
-
if (!(H.has(l) || H.has(rt))) return " ";
|
|
1289
|
-
return l === "\u254C" || rt === "\u254C" ? "\u254C" : "\u2500";
|
|
1290
|
-
}
|
|
1291
|
-
return " ";
|
|
1292
|
-
};
|
|
1293
|
-
const runs = (row) => {
|
|
1294
|
-
const out = [];
|
|
1295
|
-
for (const m of row.matchAll(/(─*)((?:[가-힣A-Za-z0-9]?)+)(─*)/g)) {
|
|
1296
|
-
if (m[2].length === 0) continue;
|
|
1297
|
-
const before = row[m.index - 1], after = row[m.index + m[0].length];
|
|
1298
|
-
const leftOk = m[1].length > 0 || ANCHOR.has(before);
|
|
1299
|
-
const rightOk = m[3].length > 0 || END.has(after);
|
|
1300
|
-
if (leftOk && rightOk && (m[1].length + m[3].length > 0 || ANCHOR.has(before) && END.has(after))) {
|
|
1301
|
-
out.push({ start: m.index, label: m[2], left: m[1].length, right: m[3].length, end: m.index + m[0].length });
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
return out;
|
|
1305
|
-
};
|
|
1306
|
-
const want = 6;
|
|
1307
|
-
const inserts = [];
|
|
1308
|
-
grid.forEach((row) => {
|
|
1309
|
-
for (const run of runs(row)) {
|
|
1310
|
-
const missing = want - (run.left + run.right);
|
|
1311
|
-
if (missing > 0) inserts.push({ at: run.end, alt: run.start + run.left, n: missing });
|
|
1312
|
-
}
|
|
1313
|
-
});
|
|
1314
|
-
inserts.sort((x, y) => y.at - x.at);
|
|
1315
|
-
for (const ins of inserts) {
|
|
1316
|
-
const candidates = [ins.at, ins.at + 1, ins.at + 2, ins.alt, ins.alt - 1];
|
|
1317
|
-
const col = candidates.find((c) => c > 0 && c < width + 40 && splittable(c));
|
|
1318
|
-
if (col === void 0) continue;
|
|
1319
|
-
grid = grid.map((r) => r.slice(0, col) + filler(r, col).repeat(ins.n) + r.slice(col));
|
|
1320
|
-
}
|
|
1321
|
-
return grid.map((row) => {
|
|
1322
|
-
let out = row;
|
|
1323
|
-
for (const run of runs(row).reverse()) {
|
|
1324
|
-
const total = run.left + run.right, l = Math.floor(total / 2), rgt = total - l;
|
|
1325
|
-
out = out.slice(0, run.start) + "\u2500".repeat(l) + run.label + "\u2500".repeat(rgt) + out.slice(run.end);
|
|
1326
|
-
}
|
|
1327
|
-
return out;
|
|
1328
|
-
});
|
|
1329
|
-
}
|
|
1330
|
-
function gridToSvg(ascii) {
|
|
1331
|
-
const cw = 6.336, ch = 17, fs = 12;
|
|
1332
|
-
const rows = widenLabelGaps(ascii.replace(/\s+$/, "").split("\n"));
|
|
1333
|
-
const cols = Math.max.apply(null, rows.map((r) => r.length));
|
|
1334
|
-
const f = (n) => n.toFixed(1);
|
|
1335
|
-
let path = "", bold = "", dashed = "", arcs = "", tris = "", marks = "", dots = "", texts = "";
|
|
1336
|
-
const isText = (chr) => chr !== void 0 && chr !== " " && chr !== ZW && LINES[chr] === void 0 && ARROWS[chr] === void 0 && chr !== "\u25C7";
|
|
1337
|
-
const center = (c) => c * cw + cw / 2;
|
|
1338
|
-
const textWidth = (chars) => chars.reduce((w, chr) => w + (WIDE.test(chr) ? cw * 2 : cw), 0);
|
|
1339
|
-
rows.forEach((row, r) => {
|
|
1340
|
-
const cy = r * ch + ch / 2, y0 = r * ch, y1 = y0 + ch;
|
|
1341
|
-
let run = null;
|
|
1342
|
-
const skip = /* @__PURE__ */ new Set();
|
|
1343
|
-
for (let c = 0; c < row.length; c++) {
|
|
1344
|
-
if (!isText(row[c]) || skip.has(c)) continue;
|
|
1345
|
-
let e = c;
|
|
1346
|
-
while (e < row.length && (isText(row[e]) || row[e] === ZW || row[e] === " " && isText(row[e + 1]))) e++;
|
|
1347
|
-
if (row[c - 1] === "\u2500" && row[e] === "\u2500") {
|
|
1348
|
-
const below = rows[r + 1] || "", above = rows[r - 1] || "";
|
|
1349
|
-
let exit = null;
|
|
1350
|
-
for (let k = c - 2; k < e + 2 && exit === null; k++) {
|
|
1351
|
-
if (below[k] === "\u2502" || below[k] === "\u25BC") exit = { k, dir: 1 };
|
|
1352
|
-
else if (above[k] === "\u2502" || above[k] === "\u25B2") exit = { k, dir: -1 };
|
|
1353
|
-
}
|
|
1354
|
-
if (exit) {
|
|
1355
|
-
const kx = center(exit.k), chars2 = row.slice(c, e).split("").filter((chr) => chr !== ZW);
|
|
1356
|
-
path += "M" + f(c * cw) + " " + f(cy) + "H" + f(e * cw) + " ";
|
|
1357
|
-
path += "M" + f(kx) + " " + f(cy) + "V" + f(exit.dir > 0 ? y1 : y0) + " ";
|
|
1358
|
-
texts += '<text x="' + f(kx + cw * 0.8 + textWidth(chars2) / 2) + '" y="' + f(cy + exit.dir * ch + fs * 0.35) + '">' + esc(chars2.join("")) + "</text>";
|
|
1359
|
-
for (let k = c; k < e; k++) skip.add(k);
|
|
1360
|
-
c = e - 1;
|
|
1361
|
-
continue;
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
let l = c - 1, rr = e;
|
|
1365
|
-
while (l >= 0 && row[l] === " ") l--;
|
|
1366
|
-
while (rr < row.length && row[rr] === " ") rr++;
|
|
1367
|
-
const onLine = (row[l] === "\u2500" || row[l] === "\u251C") && (row[rr] === "\u2500" || ARROWS[row[rr]] !== void 0 || row[rr] === "\u2524");
|
|
1368
|
-
if (!onLine) {
|
|
1369
|
-
c = e - 1;
|
|
1370
|
-
continue;
|
|
1371
|
-
}
|
|
1372
|
-
let L = l;
|
|
1373
|
-
while (L - 1 >= 0 && row[L - 1] === "\u2500") L--;
|
|
1374
|
-
let segStart = L * cw, drawStart = L * cw;
|
|
1375
|
-
if (row[L] === "\u251C" || row[L - 1] === "\u251C") {
|
|
1376
|
-
const j = row[L] === "\u251C" ? L : L - 1;
|
|
1377
|
-
const above = rows[r - 1] ? rows[r - 1][j] : " ", below = rows[r + 1] ? rows[r + 1][j] : " ";
|
|
1378
|
-
const junction = above !== void 0 && LINES[above] !== void 0 && /[UD]/.test(LINES[above]) || below !== void 0 && LINES[below] !== void 0 && /[UD]/.test(LINES[below]);
|
|
1379
|
-
if (junction) {
|
|
1380
|
-
segStart = center(j);
|
|
1381
|
-
drawStart = center(j);
|
|
1382
|
-
for (let m = j + 1; m < L; m++) skip.add(m);
|
|
1383
|
-
} else {
|
|
1384
|
-
let k = j - 1;
|
|
1385
|
-
while (k >= 0 && row[k] === " ") k--;
|
|
1386
|
-
segStart = isWall(row[k]) ? center(k) : center(j);
|
|
1387
|
-
drawStart = segStart;
|
|
1388
|
-
for (let m = j; m < L; m++) skip.add(m);
|
|
1389
|
-
}
|
|
1390
|
-
} else if (LINES[row[L - 1]] !== void 0 || isWall(row[L - 1])) {
|
|
1391
|
-
segStart = center(L - 1);
|
|
1392
|
-
}
|
|
1393
|
-
let R = rr;
|
|
1394
|
-
while (R + 1 < row.length && row[R + 1] === "\u2500") R++;
|
|
1395
|
-
let segEnd = (R + 1) * cw, drawEnd = (R + 1) * cw;
|
|
1396
|
-
if (ARROWS[row[R]] !== void 0) {
|
|
1397
|
-
drawEnd = R * cw;
|
|
1398
|
-
segEnd = isWall(row[R + 1]) ? center(R + 1) : center(R) + cw * 0.45;
|
|
1399
|
-
R--;
|
|
1400
|
-
} else if (ARROWS[row[R + 1]] !== void 0) {
|
|
1401
|
-
drawEnd = (R + 1) * cw;
|
|
1402
|
-
segEnd = isWall(row[R + 2]) ? center(R + 2) : center(R + 1) + cw * 0.45;
|
|
1403
|
-
} else if (LINES[row[R + 1]] !== void 0 || isWall(row[R + 1])) {
|
|
1404
|
-
segEnd = center(R + 1);
|
|
1405
|
-
}
|
|
1406
|
-
const chars = row.slice(c, e).split("").filter((chr) => chr !== ZW);
|
|
1407
|
-
const mid = (segStart + segEnd) / 2, half = textWidth(chars) / 2 + 5;
|
|
1408
|
-
path += "M" + f(drawStart) + " " + f(cy) + "H" + f(mid - half) + " ";
|
|
1409
|
-
path += "M" + f(mid + half) + " " + f(cy) + "H" + f(drawEnd) + " ";
|
|
1410
|
-
texts += '<text x="' + f(mid) + '" y="' + f(cy + fs * 0.35) + '">' + esc(chars.join("")) + "</text>";
|
|
1411
|
-
for (let k = L; k <= R; k++) skip.add(k);
|
|
1412
|
-
c = e - 1;
|
|
1413
|
-
}
|
|
1414
|
-
const wall = (chr) => chr === "\u2502" || chr === "\u25C7" || chr === "\u251C" || chr === "\u2524";
|
|
1415
|
-
const walls = (from, to) => {
|
|
1416
|
-
let l = from - 1, rgt = to;
|
|
1417
|
-
while (l >= 0 && (row[l] === " " || row[l] === ZW)) l--;
|
|
1418
|
-
while (rgt < row.length && (row[rgt] === " " || row[rgt] === ZW)) rgt++;
|
|
1419
|
-
return wall(row[l] || "") && wall(row[rgt] || "") ? [l, rgt] : null;
|
|
1420
|
-
};
|
|
1421
|
-
const lift = (box) => {
|
|
1422
|
-
const col = run.start;
|
|
1423
|
-
let top = r - 1, bottom = r + 1;
|
|
1424
|
-
while (top >= 0 && !isHBorder((rows[top] || "")[col])) top--;
|
|
1425
|
-
while (bottom < rows.length && !isHBorder((rows[bottom] || "")[col])) bottom++;
|
|
1426
|
-
const corner = (chr) => chr !== void 0 && chr !== "\u2500" && chr !== "\u2550" && chr !== "\u254C" && (LINES[chr] !== void 0 || chr === "\u25C7");
|
|
1427
|
-
if (top < 0 || bottom >= rows.length || !corner((rows[top] || "")[box[0]]) || !corner((rows[bottom] || "")[box[0]])) return 0;
|
|
1428
|
-
let labelRows = 0;
|
|
1429
|
-
for (let k = top + 1; k < bottom; k++) {
|
|
1430
|
-
const inner = (rows[k] || "").slice(box[0] + 1, box[1]).split(ZW).join("").trim();
|
|
1431
|
-
if (inner.length > 0) labelRows++;
|
|
1432
|
-
}
|
|
1433
|
-
return (bottom - top - 1 - labelRows) % 2 === 1 ? -ch / 2 : 0;
|
|
1434
|
-
};
|
|
1435
|
-
const flush = () => {
|
|
1436
|
-
if (!run) return;
|
|
1437
|
-
const box = walls(run.start, run.end);
|
|
1438
|
-
const y = f(cy + fs * 0.35 + (box ? lift(box) : 0));
|
|
1439
|
-
const x = box ? f(((box[0] + 1) * cw + box[1] * cw) / 2) : run.wide ? f((run.start * cw + run.end * cw) / 2) : run.xs.join(" ");
|
|
1440
|
-
texts += '<text x="' + x + '" y="' + y + '">' + esc(run.chars.join("")) + "</text>";
|
|
1441
|
-
run = null;
|
|
1442
|
-
};
|
|
1443
|
-
for (let c = 0; c < row.length; c++) {
|
|
1444
|
-
const chr = row[c];
|
|
1445
|
-
const cx = c * cw + cw / 2, x0 = c * cw, x1 = x0 + cw;
|
|
1446
|
-
if (skip.has(c)) {
|
|
1447
|
-
flush();
|
|
1448
|
-
continue;
|
|
1449
|
-
}
|
|
1450
|
-
if (chr === ZW) {
|
|
1451
|
-
if (run) run.end = c + 1;
|
|
1452
|
-
continue;
|
|
1453
|
-
}
|
|
1454
|
-
if (chr === " ") {
|
|
1455
|
-
const next = row[c + 1];
|
|
1456
|
-
const joins = run && next !== void 0 && next !== " " && next !== ZW && !LINES[next] && !ARROWS[next] && next !== "\u25C7";
|
|
1457
|
-
if (!joins) {
|
|
1458
|
-
flush();
|
|
1459
|
-
continue;
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
const above = rows[r - 1] ? rows[r - 1][c] : " ", below = rows[r + 1] ? rows[r + 1][c] : " ";
|
|
1463
|
-
const vertical = (v) => v !== void 0 && LINES[v] !== void 0 && /[UD]/.test(LINES[v]) || v === "\u25C7";
|
|
1464
|
-
if ((chr === "\u251C" || chr === "\u2524") && !vertical(above) && !vertical(below)) {
|
|
1465
|
-
flush();
|
|
1466
|
-
let l = c - 1, rgt = c + 1;
|
|
1467
|
-
while (l >= 0 && row[l] === " ") l--;
|
|
1468
|
-
while (rgt < row.length && row[rgt] === " ") rgt++;
|
|
1469
|
-
const gapL = isWall(row[l]) ? l * cw + cw / 2 : x0;
|
|
1470
|
-
const gapR = isWall(row[rgt]) ? rgt * cw + cw / 2 : x1;
|
|
1471
|
-
path += "M" + f(gapL) + " " + f(cy) + "H" + f(gapR) + " ";
|
|
1472
|
-
continue;
|
|
1473
|
-
}
|
|
1474
|
-
const ln = LINES[chr];
|
|
1475
|
-
if (ln) {
|
|
1476
|
-
flush();
|
|
1477
|
-
if (ln.indexOf("r") >= 0) {
|
|
1478
|
-
const ax = ln.indexOf("L") >= 0 ? x0 : x1, by = ln.indexOf("U") >= 0 ? y0 : y1;
|
|
1479
|
-
arcs += "M" + f(ax) + " " + f(cy) + "Q" + f(cx) + " " + f(cy) + " " + f(cx) + " " + f(by) + " ";
|
|
1480
|
-
} else {
|
|
1481
|
-
let seg = "";
|
|
1482
|
-
if (ln.indexOf("L") >= 0) seg += "M" + f(isWall(row[c - 1]) ? x0 - cw / 2 : x0) + " " + f(cy) + "H" + f(cx) + " ";
|
|
1483
|
-
if (ln.indexOf("R") >= 0) seg += "M" + f(cx) + " " + f(cy) + "H" + f(isWall(row[c + 1]) ? x1 + cw / 2 : x1) + " ";
|
|
1484
|
-
if (ln.indexOf("U") >= 0) seg += "M" + f(cx) + " " + f(y0) + "V" + f(cy) + " ";
|
|
1485
|
-
if (ln.indexOf("D") >= 0) seg += "M" + f(cx) + " " + f(cy) + "V" + f(y1) + " ";
|
|
1486
|
-
if (ln.indexOf("b") >= 0) bold += seg;
|
|
1487
|
-
else if (ln.indexOf("d") >= 0) dashed += seg;
|
|
1488
|
-
else path += seg;
|
|
1489
|
-
}
|
|
1490
|
-
continue;
|
|
1491
|
-
}
|
|
1492
|
-
const ar = ARROWS[chr];
|
|
1493
|
-
if (ar) {
|
|
1494
|
-
flush();
|
|
1495
|
-
const w = cw * 0.9, h = ch * 0.42;
|
|
1496
|
-
const tipR = isWall(row[c + 1]) ? x1 + cw / 2 : cx + w / 2, tipL = isWall(row[c - 1]) ? x0 - cw / 2 : cx - w / 2;
|
|
1497
|
-
const tipD = isHBorder(below) ? y1 + ch / 2 : cy + h / 2, tipU = isHBorder(above) ? y0 - ch / 2 : cy - h / 2;
|
|
1498
|
-
if (ar === "R") {
|
|
1499
|
-
path += "M" + f(x0) + " " + f(cy) + "H" + f(tipR - w) + " ";
|
|
1500
|
-
tris += "M" + f(tipR - w) + " " + f(cy - h / 2) + "L" + f(tipR) + " " + f(cy) + "L" + f(tipR - w) + " " + f(cy + h / 2) + "Z ";
|
|
1501
|
-
}
|
|
1502
|
-
if (ar === "L") {
|
|
1503
|
-
path += "M" + f(tipL + w) + " " + f(cy) + "H" + f(x1) + " ";
|
|
1504
|
-
tris += "M" + f(tipL + w) + " " + f(cy - h / 2) + "L" + f(tipL) + " " + f(cy) + "L" + f(tipL + w) + " " + f(cy + h / 2) + "Z ";
|
|
1505
|
-
}
|
|
1506
|
-
if (ar === "D") {
|
|
1507
|
-
path += "M" + f(cx) + " " + f(y0) + "V" + f(tipD - h) + " ";
|
|
1508
|
-
tris += "M" + f(cx - w / 2) + " " + f(tipD - h) + "L" + f(cx + w / 2) + " " + f(tipD - h) + "L" + f(cx) + " " + f(tipD) + "Z ";
|
|
1509
|
-
}
|
|
1510
|
-
if (ar === "U") {
|
|
1511
|
-
path += "M" + f(cx) + " " + f(tipU + h) + "V" + f(y1) + " ";
|
|
1512
|
-
tris += "M" + f(cx - w / 2) + " " + f(tipU + h) + "L" + f(cx + w / 2) + " " + f(tipU + h) + "L" + f(cx) + " " + f(tipU) + "Z ";
|
|
1513
|
-
}
|
|
1514
|
-
continue;
|
|
1515
|
-
}
|
|
1516
|
-
if (chr === "\u25C7") {
|
|
1517
|
-
flush();
|
|
1518
|
-
const w = cw * 0.8, h = ch * 0.4;
|
|
1519
|
-
marks += "M" + f(cx) + " " + f(cy - h / 2) + "L" + f(cx + w / 2) + " " + f(cy) + "L" + f(cx) + " " + f(cy + h / 2) + "L" + f(cx - w / 2) + " " + f(cy) + "Z ";
|
|
1520
|
-
continue;
|
|
1521
|
-
}
|
|
1522
|
-
if (chr === "\u25CF") {
|
|
1523
|
-
flush();
|
|
1524
|
-
const rr = cw * 0.45;
|
|
1525
|
-
dots += "M" + f(cx - rr) + " " + f(cy) + "a" + f(rr) + " " + f(rr) + " 0 1 0 " + f(rr * 2) + " 0a" + f(rr) + " " + f(rr) + " 0 1 0 " + f(-rr * 2) + " 0Z ";
|
|
1526
|
-
continue;
|
|
1527
|
-
}
|
|
1528
|
-
if (chr === "\u25B3") {
|
|
1529
|
-
flush();
|
|
1530
|
-
const w = cw * 0.9, h = ch * 0.42;
|
|
1531
|
-
marks += "M" + f(cx) + " " + f(cy - h / 2) + "L" + f(cx + w / 2) + " " + f(cy + h / 2) + "L" + f(cx - w / 2) + " " + f(cy + h / 2) + "Z ";
|
|
1532
|
-
path += "M" + f(cx) + " " + f(cy + h / 2) + "V" + f(y1) + " ";
|
|
1533
|
-
continue;
|
|
1534
|
-
}
|
|
1535
|
-
if (!run) run = { start: c, end: c + 1, xs: [], chars: [], wide: false };
|
|
1536
|
-
run.end = c + 1;
|
|
1537
|
-
run.xs.push(f(cx));
|
|
1538
|
-
run.chars.push(chr);
|
|
1539
|
-
if (WIDE.test(chr)) run.wide = true;
|
|
1540
|
-
}
|
|
1541
|
-
flush();
|
|
1542
|
-
});
|
|
1543
|
-
const W = f(cols * cw), H = f(rows.length * ch);
|
|
1544
|
-
return '<svg xmlns="http://www.w3.org/2000/svg" class="ascii-flow" viewBox="0 0 ' + W + " " + H + '" width="' + W + '" height="' + H + '"><path d="' + path + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="1"/><path d="' + bold + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="2"/><path d="' + dashed + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="1" stroke-dasharray="3 3"/><path d="' + arcs + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="1"/><path d="' + tris + '" fill="var(--app-color-text-muted)"/><path d="' + dots + '" fill="var(--app-color-text-muted)"/><path d="' + marks + '" fill="var(--app-color-surface)" stroke="var(--app-color-text-muted)" stroke-width="1"/><g font-family="var(--app-font-mono)" font-size="' + fs + '" text-anchor="middle" fill="var(--app-color-text)">' + texts + "</g></svg>";
|
|
1545
|
-
}
|
|
1546
|
-
var renderFlow = (source) => gridToSvg(renderMermaidASCII(widenCjk(source), ASCII_OPT));
|
|
1547
|
-
|
|
1548
|
-
// src/component/widget/prose/_function/remark-flow.ts
|
|
1549
|
-
var remarkFlow = () => (tree, file) => {
|
|
1550
|
-
visit3(tree, "code", (node, index, parent) => {
|
|
1551
|
-
if (node.lang !== "mermaid" || parent === void 0 || index === void 0) {
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
try {
|
|
1555
|
-
parent.children[index] = {
|
|
1556
|
-
type: "html",
|
|
1557
|
-
value: `<div class="wg_prose__flow">${renderFlow(node.value)}</div>`
|
|
1558
|
-
};
|
|
1559
|
-
} catch (error) {
|
|
1560
|
-
file.fail(`${copy_error_flow}: ${error instanceof Error ? error.message : String(error)}`, node);
|
|
1561
|
-
}
|
|
1562
|
-
});
|
|
1563
|
-
};
|
|
1564
|
-
|
|
1565
|
-
// src/component/widget/prose/_function/remark-links.ts
|
|
1566
|
-
import { existsSync } from "node:fs";
|
|
1567
|
-
import { dirname, posix, relative, resolve } from "node:path";
|
|
1568
|
-
import { visit as visit4 } from "unist-util-visit";
|
|
1569
|
-
var remarkLinks = (options) => (tree, file) => {
|
|
1570
|
-
const here = dirname(relative(options.root, file.path));
|
|
1571
|
-
visit4(tree, (node) => {
|
|
1572
|
-
if (node.type !== "link" && node.type !== "definition") {
|
|
1573
|
-
return;
|
|
1574
|
-
}
|
|
1575
|
-
const match = /^(?![a-z]+:|\/|#)([^#?]+)(\.mdx?)([?#].*|)$/i.exec(node.url);
|
|
1576
|
-
if (match) {
|
|
1577
|
-
if (!existsSync(resolve(dirname(file.path), `${match[1]}${match[2]}`))) {
|
|
1578
|
-
file.message(`${copy_warn_broken_link}: ${node.url}`, node);
|
|
1579
|
-
}
|
|
1580
|
-
const target = posix.join(here, `${match[1]}${match[2]}`).toLowerCase();
|
|
1581
|
-
node.url = target === "readme.md" ? `/${match[3]}` : `/${posix.join(here, match[1]).toLowerCase()}/${match[3]}`;
|
|
1582
|
-
}
|
|
1583
|
-
});
|
|
1584
|
-
};
|
|
1585
|
-
|
|
1586
|
-
// src/component/widget/prose/_function/remark-parts.ts
|
|
1587
|
-
import { toString as toPlainText2 } from "mdast-util-to-string";
|
|
1588
|
-
var remarkParts = () => (tree) => {
|
|
1589
|
-
for (const [index, node] of tree.children.entries()) {
|
|
1590
|
-
if (node.type !== "leafDirective" || node.name !== "part") {
|
|
1591
|
-
continue;
|
|
1592
|
-
}
|
|
1593
|
-
const section = tree.children.slice(index + 1).find((next) => next.type === "heading" && next.depth === section_heading_depth.section);
|
|
1594
|
-
node.data = { hName: "div", hProperties: { className: ["wg_prose__part"] } };
|
|
1595
|
-
if (section) {
|
|
1596
|
-
section.data = {
|
|
1597
|
-
...section.data,
|
|
1598
|
-
hProperties: { ...section.data?.hProperties, dataPart: toPlainText2(node).trim() }
|
|
1599
|
-
};
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
};
|
|
1603
|
-
|
|
1604
|
-
// src/component/widget/prose/_function/remark-status.ts
|
|
1605
|
-
import { escape as escapeHtml, escapeRegExp } from "es-toolkit/string";
|
|
1606
|
-
import { findAndReplace } from "mdast-util-find-and-replace";
|
|
1607
|
-
|
|
1608
|
-
// src/component/widget/prose/_constant/status.ts
|
|
1609
|
-
var status_date_pattern = String.raw`\d{4}-\d{2}-\d{2}`;
|
|
1610
|
-
var status_candidate_pattern = new RegExp(String.raw`\([^()\n]*${status_date_pattern}\)`, "g");
|
|
1611
|
-
|
|
1612
|
-
// src/component/widget/prose/_function/remark-status.ts
|
|
1613
|
-
var remarkStatus = (options) => {
|
|
1614
|
-
const statuses = options.status.toSorted((a, b) => b.phrase.length - a.phrase.length);
|
|
1615
|
-
const phrases = statuses.map((item) => [escapeRegExp(item.phrase), ...item.date ? [`(?: ${status_date_pattern})?`] : []].join("")).join("|");
|
|
1616
|
-
const pattern = new RegExp(String.raw`\((${phrases})\)|(${phrases})`, "g");
|
|
1617
|
-
const ignore = ["link", "linkReference", "heading"];
|
|
1618
|
-
return (tree, file) => {
|
|
1619
|
-
findAndReplace(
|
|
1620
|
-
tree,
|
|
1621
|
-
[
|
|
1622
|
-
pattern,
|
|
1623
|
-
(_match, inParens, bare) => {
|
|
1624
|
-
const text = inParens ?? bare;
|
|
1625
|
-
const item = statuses.find((status) => text?.startsWith(status.phrase));
|
|
1626
|
-
if (text === void 0 || item === void 0) {
|
|
1627
|
-
return false;
|
|
1628
|
-
}
|
|
1629
|
-
return {
|
|
1630
|
-
type: "html",
|
|
1631
|
-
value: `<span class="wg_prose__pill wg_prose__pill--${item.kind}">${escapeHtml(text)}</span>`
|
|
1632
|
-
};
|
|
1633
|
-
}
|
|
1634
|
-
],
|
|
1635
|
-
{ ignore }
|
|
1636
|
-
);
|
|
1637
|
-
findAndReplace(
|
|
1638
|
-
tree,
|
|
1639
|
-
[
|
|
1640
|
-
status_candidate_pattern,
|
|
1641
|
-
(match, info) => {
|
|
1642
|
-
file.message(
|
|
1643
|
-
`${copy_warn_unknown_status}: ${match}`,
|
|
1644
|
-
info.stack.findLast((node) => node.position !== void 0)
|
|
1645
|
-
);
|
|
1646
|
-
return false;
|
|
1647
|
-
}
|
|
1648
|
-
],
|
|
1649
|
-
{ ignore }
|
|
1650
|
-
);
|
|
1651
|
-
};
|
|
1652
|
-
};
|
|
1653
|
-
|
|
1654
|
-
// src/component/widget/prose/_function/remark-swatch.ts
|
|
1655
|
-
import { visit as visit5 } from "unist-util-visit";
|
|
1656
|
-
var remarkSwatch = () => (tree) => {
|
|
1657
|
-
visit5(tree, "inlineCode", (node) => {
|
|
1658
|
-
if (/^#[0-9a-f]{3,8}$/i.test(node.value.trim())) {
|
|
1659
|
-
node.data = {
|
|
1660
|
-
hProperties: { className: ["wg_prose__color"], style: `--wg-prose-chip-color: ${node.value.trim()}` }
|
|
1661
|
-
};
|
|
1662
|
-
}
|
|
1663
|
-
});
|
|
1664
|
-
};
|
|
1665
|
-
|
|
1666
|
-
// src/component/widget/prose/_function/remark-unknown-directives.ts
|
|
1667
|
-
import { SKIP as SKIP2, visit as visit6 } from "unist-util-visit";
|
|
1668
|
-
var remarkUnknownDirectives = () => (tree, file) => {
|
|
1669
|
-
visit6(tree, (node, index, parent) => {
|
|
1670
|
-
if (node.type === "textDirective" && parent !== void 0 && index !== void 0) {
|
|
1671
|
-
parent.children[index] = {
|
|
1672
|
-
type: "text",
|
|
1673
|
-
value: String(file.value).slice(node.position?.start.offset, node.position?.end.offset)
|
|
1674
|
-
};
|
|
1675
|
-
return SKIP2;
|
|
1676
|
-
}
|
|
1677
|
-
if ((node.type === "leafDirective" || node.type === "containerDirective") && node.data?.hName === void 0) {
|
|
1678
|
-
file.fail(`${copy_error_unknown_directive}: ${node.name}`, node);
|
|
1679
|
-
}
|
|
1680
|
-
});
|
|
1681
|
-
};
|
|
1682
|
-
|
|
1683
|
-
// src/entry/cli/_function/create-processor/_rehype-assets.ts
|
|
1684
|
-
import { existsSync as existsSync2, realpathSync, statSync } from "node:fs";
|
|
1685
|
-
import { dirname as dirname2, extname as extname2, isAbsolute, relative as relative2, resolve as resolve2, sep } from "node:path";
|
|
1686
|
-
import { visit as visit7 } from "unist-util-visit";
|
|
1687
|
-
|
|
1688
|
-
// src/util/file/to-asset-path.ts
|
|
1689
|
-
import { createHash } from "node:crypto";
|
|
1690
|
-
import { readFileSync } from "node:fs";
|
|
1691
|
-
import { posix as posix2 } from "node:path";
|
|
1692
|
-
var toAssetPath = (options) => {
|
|
1693
|
-
const extension = posix2.extname(options.path);
|
|
1694
|
-
return `${posix2.dirname(options.path)}/${posix2.basename(options.path, extension)}.${createHash("sha256").update(readFileSync(options.file)).digest("hex")}${extension}`;
|
|
1695
|
-
};
|
|
1696
|
-
|
|
1697
|
-
// src/entry/cli/_function/create-processor/_rehype-assets.ts
|
|
1698
|
-
var rehypeAssets = (options) => (tree, file) => {
|
|
1699
|
-
visit7(tree, "element", (node) => {
|
|
1700
|
-
const property = node.tagName === "img" ? "src" : "href";
|
|
1701
|
-
const url = node.properties[property];
|
|
1702
|
-
if (node.tagName !== "img" && node.tagName !== "a" || typeof url !== "string" || /^(?:[a-z][a-z\d+.-]*:|\/|#)/i.test(url)) {
|
|
1703
|
-
return;
|
|
1704
|
-
}
|
|
1705
|
-
const match = /^([^?#]+)([?#].*)?$/.exec(url);
|
|
1706
|
-
if (match === null) {
|
|
1707
|
-
return;
|
|
1708
|
-
}
|
|
1709
|
-
const path = decodeURIComponent(match[1]);
|
|
1710
|
-
const extension = extname2(path).toLowerCase();
|
|
1711
|
-
if (!asset_media_extensions.has(extension)) {
|
|
1712
|
-
if (node.tagName === "img") {
|
|
1713
|
-
file.fail(`${copy_error_asset}: \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC774\uBBF8\uC9C0 \uD615\uC2DD \xB7 ${url}`, node);
|
|
1714
|
-
}
|
|
1715
|
-
return;
|
|
1716
|
-
}
|
|
1717
|
-
const target = resolve2(dirname2(file.path), path);
|
|
1718
|
-
const location2 = relative2(options.root, target);
|
|
1719
|
-
if (location2 === ".." || location2.startsWith(`..${sep}`) || isAbsolute(location2)) {
|
|
1720
|
-
file.fail(`${copy_error_asset}: \uBB38\uC11C \uD3F4\uB354 \uBC16 \xB7 ${url}`, node);
|
|
1721
|
-
}
|
|
1722
|
-
if (!existsSync2(target)) {
|
|
1723
|
-
file.fail(`${copy_error_asset}: \uD30C\uC77C\uC774 \uC5C6\uB2E4 \xB7 ${url}`, node);
|
|
1724
|
-
}
|
|
1725
|
-
const actual = realpathSync(target);
|
|
1726
|
-
const actualLocation = relative2(realpathSync(options.root), actual);
|
|
1727
|
-
if (actualLocation === ".." || actualLocation.startsWith(`..${sep}`) || isAbsolute(actualLocation) || !statSync(actual).isFile()) {
|
|
1728
|
-
file.fail(`${copy_error_asset}: \uBB38\uC11C \uD3F4\uB354 \uBC16\uC774\uAC70\uB098 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uB2E4 \xB7 ${url}`, node);
|
|
1729
|
-
}
|
|
1730
|
-
const assetUrl = toAssetPath({ path: `${asset_media_dir}/asset${extension}`, file: actual });
|
|
1731
|
-
options.files.set(assetUrl, actual);
|
|
1732
|
-
node.properties[property] = match[2] === void 0 ? assetUrl : `${assetUrl}${match[2]}`;
|
|
1733
|
-
});
|
|
1734
|
-
};
|
|
1735
|
-
|
|
1736
|
-
// src/entry/cli/_function/create-processor/_rehype-heading-ids.ts
|
|
1737
|
-
import Slugger from "github-slugger";
|
|
1738
|
-
import { toString as toPlainText3 } from "hast-util-to-string";
|
|
1739
|
-
import { visit as visit8 } from "unist-util-visit";
|
|
1740
|
-
var rehypeHeadingIds = () => (tree, file) => {
|
|
1741
|
-
const slugger = new Slugger();
|
|
1742
|
-
const headings = [];
|
|
1743
|
-
visit8(tree, "element", (node) => {
|
|
1744
|
-
const depth = /^h([1-6])$/.exec(node.tagName)?.[1];
|
|
1745
|
-
if (depth === void 0) {
|
|
1746
|
-
return;
|
|
1747
|
-
}
|
|
1748
|
-
const text = toPlainText3(node);
|
|
1749
|
-
node.properties.id = typeof node.properties.id === "string" ? node.properties.id : slugger.slug(text);
|
|
1750
|
-
headings.push({ depth: Number(depth), slug: node.properties.id, text });
|
|
1751
|
-
node.children = [{ type: "element", tagName: "span", properties: { className: ["wg_prose__headingText"] }, children: node.children }];
|
|
1752
|
-
});
|
|
1753
|
-
if (file.data.fh) {
|
|
1754
|
-
file.data.fh.headings = headings;
|
|
1755
|
-
}
|
|
1756
|
-
};
|
|
1757
|
-
|
|
1758
|
-
// src/entry/cli/_function/create-processor/_remark-report.ts
|
|
1759
|
-
import { relative as relative3 } from "node:path";
|
|
1760
|
-
var remarkReport = (options) => (_tree, file) => {
|
|
1761
|
-
const path = relative3(options.root, file.path);
|
|
1762
|
-
for (const message of file.messages) {
|
|
1763
|
-
console.warn(`${message.line === void 0 ? path : `${path}:${message.line}`} ${message.reason}`);
|
|
1764
|
-
}
|
|
1765
|
-
};
|
|
1766
|
-
|
|
1767
|
-
// src/entry/cli/_function/create-processor/_remark-snippets.ts
|
|
1768
|
-
import { existsSync as existsSync3, readFileSync as readFileSync2, realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
|
|
1769
|
-
import { dirname as dirname3, extname as extname3, isAbsolute as isAbsolute2, relative as relative4, resolve as resolve3, sep as sep2 } from "node:path";
|
|
1770
|
-
import { visit as visit9 } from "unist-util-visit";
|
|
1771
|
-
|
|
1772
|
-
// src/entry/cli/_constant/snippet.ts
|
|
1773
|
-
var snippet_pattern = /^<<<\s+(\S+?)(?:#([\w-]+))?(?:\s+(.+?))?\s*$/;
|
|
1774
|
-
var snippet_region_pattern = /^\s*\S*\s*#(end)?region\s+([\w-]+)/;
|
|
1775
|
-
var snippet_language_by_extension = {
|
|
1776
|
-
".cjs": "js",
|
|
1777
|
-
".md": "markdown",
|
|
1778
|
-
".mjs": "js",
|
|
1779
|
-
".mts": "ts",
|
|
1780
|
-
".txt": "text",
|
|
1781
|
-
".yml": "yaml"
|
|
1782
|
-
};
|
|
1783
|
-
|
|
1784
|
-
// src/entry/cli/_function/create-processor/_remark-snippets.ts
|
|
1785
|
-
var toSnippetBody = (source, region) => {
|
|
1786
|
-
const lines = source.replace(/\r\n/g, "\n").split("\n");
|
|
1787
|
-
let inside = region === void 0;
|
|
1788
|
-
let found = region === void 0;
|
|
1789
|
-
const kept = [];
|
|
1790
|
-
for (const line of lines) {
|
|
1791
|
-
const marker = snippet_region_pattern.exec(line);
|
|
1792
|
-
if (marker !== null) {
|
|
1793
|
-
if (region !== void 0 && marker[2] === region) {
|
|
1794
|
-
inside = marker[1] === void 0;
|
|
1795
|
-
found = true;
|
|
1796
|
-
}
|
|
1797
|
-
continue;
|
|
1798
|
-
}
|
|
1799
|
-
if (inside) {
|
|
1800
|
-
kept.push(line);
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
if (!found) {
|
|
1804
|
-
return void 0;
|
|
1805
|
-
}
|
|
1806
|
-
while (kept.length > 0 && kept[0]?.trim() === "") {
|
|
1807
|
-
kept.shift();
|
|
1808
|
-
}
|
|
1809
|
-
while (kept.length > 0 && kept.at(-1)?.trim() === "") {
|
|
1810
|
-
kept.pop();
|
|
1811
|
-
}
|
|
1812
|
-
const indents = kept.filter((line) => line.trim() !== "").map((line) => line.length - line.trimStart().length);
|
|
1813
|
-
const indent = indents.length === 0 ? 0 : Math.min(...indents);
|
|
1814
|
-
return kept.map((line) => line.slice(Math.min(indent, line.length - line.trimStart().length))).join("\n");
|
|
1815
|
-
};
|
|
1816
|
-
var remarkSnippets = (options) => (tree, file) => {
|
|
1817
|
-
visit9(tree, "paragraph", (node, index, parent) => {
|
|
1818
|
-
const [child] = node.children;
|
|
1819
|
-
if (node.children.length !== 1 || child === void 0 || child.type !== "text" || parent === void 0 || index === void 0) {
|
|
1820
|
-
return;
|
|
1821
|
-
}
|
|
1822
|
-
const match = snippet_pattern.exec(child.value.trim());
|
|
1823
|
-
if (match === null) {
|
|
1824
|
-
return;
|
|
1825
|
-
}
|
|
1826
|
-
const [, path = "", region, meta] = match;
|
|
1827
|
-
const target = resolve3(dirname3(file.path), path);
|
|
1828
|
-
const location2 = relative4(options.root, target);
|
|
1829
|
-
if (location2 === ".." || location2.startsWith(`..${sep2}`) || isAbsolute2(location2)) {
|
|
1830
|
-
file.fail(`${copy_error_snippet}: \uBB38\uC11C \uD3F4\uB354 \uBC16 \xB7 ${path}`, node);
|
|
1831
|
-
}
|
|
1832
|
-
if (!existsSync3(target)) {
|
|
1833
|
-
file.fail(`${copy_error_snippet}: \uD30C\uC77C\uC774 \uC5C6\uB2E4 \xB7 ${path}`, node);
|
|
1834
|
-
}
|
|
1835
|
-
const actual = realpathSync2(target);
|
|
1836
|
-
const actualLocation = relative4(realpathSync2(options.root), actual);
|
|
1837
|
-
if (actualLocation === ".." || actualLocation.startsWith(`..${sep2}`) || isAbsolute2(actualLocation) || !statSync2(actual).isFile()) {
|
|
1838
|
-
file.fail(`${copy_error_snippet}: \uBB38\uC11C \uD3F4\uB354 \uBC16\uC774\uAC70\uB098 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uB2E4 \xB7 ${path}`, node);
|
|
1839
|
-
}
|
|
1840
|
-
const body = toSnippetBody(readFileSync2(actual, "utf8"), region);
|
|
1841
|
-
if (body === void 0) {
|
|
1842
|
-
file.fail(`${copy_error_snippet}: region \uC774 \uC5C6\uB2E4 \xB7 ${path}#${region}`, node);
|
|
1843
|
-
return;
|
|
1844
|
-
}
|
|
1845
|
-
const extension = extname3(actual).toLowerCase();
|
|
1846
|
-
const lang = snippet_language_by_extension[extension] === void 0 ? extension.slice(1) : snippet_language_by_extension[extension];
|
|
1847
|
-
options.snippets.add(actual);
|
|
1848
|
-
parent.children.splice(index, 1, { type: "code", lang, meta: meta === void 0 ? null : meta, value: body });
|
|
1849
|
-
});
|
|
1850
|
-
};
|
|
1851
|
-
|
|
1852
|
-
// src/entry/cli/_function/create-processor/_shiki-transformers.ts
|
|
1853
|
-
import {
|
|
1854
|
-
transformerMetaHighlight,
|
|
1855
|
-
transformerNotationDiff,
|
|
1856
|
-
transformerNotationErrorLevel,
|
|
1857
|
-
transformerNotationHighlight,
|
|
1858
|
-
transformerNotationWordHighlight
|
|
1859
|
-
} from "@shikijs/transformers";
|
|
1860
|
-
var lineNumbers = {
|
|
1861
|
-
name: "for-humanity:line-numbers",
|
|
1862
|
-
pre(node) {
|
|
1863
|
-
const meta = this.options.meta?.__raw;
|
|
1864
|
-
if (typeof meta === "string" && /\bline-numbers\b/.test(meta)) {
|
|
1865
|
-
this.addClassToHast(node, "wg_prose__lineNumbers");
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
};
|
|
1869
|
-
var tone = {
|
|
1870
|
-
name: "for-humanity:code-tone",
|
|
1871
|
-
pre(node) {
|
|
1872
|
-
const meta = this.options.meta?.__raw;
|
|
1873
|
-
if (typeof meta !== "string") {
|
|
1874
|
-
return;
|
|
1875
|
-
}
|
|
1876
|
-
for (const word of ["bad", "good"]) {
|
|
1877
|
-
if (new RegExp(`\\b${word}\\b`).test(meta)) {
|
|
1878
|
-
this.addClassToHast(node, `wg_prose__code--${word}`);
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
};
|
|
1883
|
-
var shikiTransformers = [
|
|
1884
|
-
transformerNotationHighlight({ matchAlgorithm: "v3" }),
|
|
1885
|
-
transformerNotationErrorLevel({ matchAlgorithm: "v3" }),
|
|
1886
|
-
transformerNotationDiff({ matchAlgorithm: "v3" }),
|
|
1887
|
-
transformerNotationWordHighlight({ matchAlgorithm: "v3" }),
|
|
1888
|
-
transformerMetaHighlight(),
|
|
1889
|
-
lineNumbers,
|
|
1890
|
-
tone
|
|
1891
|
-
];
|
|
1892
|
-
|
|
1893
|
-
// src/entry/cli/_function/create-processor/create-processor.ts
|
|
1894
|
-
var createProcessor = (options) => {
|
|
1895
|
-
return unified().use(remarkParse).use(remarkFrontmatter, ["yaml"]).use(remarkGfm).use(remarkSnippets, { root: options.root, snippets: options.snippets ?? /* @__PURE__ */ new Set() }).use(remarkSmartypants).use(remarkDirective).use(remarkBlocks).use(remarkParts).use(remarkFlow).use(remarkStatus, { status: options.site.status }).use(remarkSwatch).use(remarkLinks, { root: options.root }).use(remarkUnknownDirectives).use(remarkReport, { root: options.root }).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeShiki, { theme: createCssVariablesTheme({ name: "for-humanity", variablePrefix: "--app-code-" }), transformers: shikiTransformers }).use(rehypeHead).use(rehypeHeadingIds).use(rehypeSections).use(rehypeTables).use(rehypeRaw).use(rehypeAssets, { root: options.root, files: options.files ?? /* @__PURE__ */ new Map() }).use(rehypeStringify, { allowDangerousHtml: true });
|
|
1896
|
-
};
|
|
1897
|
-
|
|
1898
|
-
// src/entry/cli/_function/read-docs.ts
|
|
1899
|
-
import { readdir, readFile as readFile2 } from "node:fs/promises";
|
|
1900
|
-
import { join, posix as posix3, sep as sep3 } from "node:path";
|
|
1901
|
-
import { VFile } from "vfile";
|
|
1902
|
-
import { parse as parseYaml } from "yaml";
|
|
1903
|
-
|
|
1904
|
-
// src/type/doc-data.ts
|
|
1905
|
-
import { z as z2 } from "zod";
|
|
1906
|
-
|
|
1907
|
-
// src/constant/doc.ts
|
|
1908
|
-
var doc_type = {
|
|
1909
|
-
document: "document",
|
|
1910
|
-
blueprint: "blueprint"
|
|
1911
|
-
};
|
|
1912
|
-
var doc_order_default = Number.MAX_SAFE_INTEGER;
|
|
1913
|
-
|
|
1914
|
-
// src/type/group-path.ts
|
|
1915
|
-
import { z } from "zod";
|
|
1916
|
-
var groupPathSchema = z.union([z.string().trim().min(1), z.array(z.string().trim().min(1)).min(1)]).transform((path) => typeof path === "string" ? [path] : path);
|
|
1917
|
-
|
|
1918
|
-
// src/type/doc-data.ts
|
|
1919
|
-
var docDataSchema = z2.object({
|
|
1920
|
-
/**
|
|
1921
|
-
* 문서 이름 · 제목·목록 · 같은 첫 글자 허용
|
|
1922
|
-
*/
|
|
1923
|
-
name: z2.string().trim().min(1),
|
|
1924
|
-
/**
|
|
1925
|
-
* 짧은 문서 설명 · 사이드바 툴팁
|
|
1926
|
-
*/
|
|
1927
|
-
label: z2.string(),
|
|
1928
|
-
/**
|
|
1929
|
-
* 기존 type 값 호환 · 생략 권장, 렌더링 차이 없음
|
|
1930
|
-
*/
|
|
1931
|
-
type: z2.enum(doc_type).default(doc_type.document),
|
|
1932
|
-
/**
|
|
1933
|
-
* 사이드바의 문서 묶음 경로 · 문자열도 배열로 정규화
|
|
1934
|
-
*/
|
|
1935
|
-
group: groupPathSchema,
|
|
1936
|
-
/**
|
|
1937
|
-
* 같은 묶음 안의 부모 문서 id · 확장자 제외, ./·../ 상대 경로도 허용
|
|
1938
|
-
*/
|
|
1939
|
-
parent: z2.string().trim().min(1).optional(),
|
|
1940
|
-
/**
|
|
1941
|
-
* 묶음 안의 읽는 순서 · 미지정 문서는 뒤에서 이름순
|
|
1942
|
-
*/
|
|
1943
|
-
order: z2.number().int().nonnegative().default(doc_order_default)
|
|
1944
|
-
});
|
|
1945
|
-
|
|
1946
|
-
// src/entry/cli/_function/read-docs.ts
|
|
1947
|
-
var readDocs = async (options) => {
|
|
1948
|
-
const paths = (await readdir(options.root, { recursive: true })).filter(
|
|
1949
|
-
(path) => /\.mdx?$/i.test(path) && !/^(readme|agents|claude)\.md$/i.test(path) && !path.split(sep3).includes("node_modules") && !path.startsWith(`dist${sep3}`)
|
|
1950
|
-
);
|
|
1951
|
-
const docs = await Promise.all(
|
|
1952
|
-
paths.map(async (path) => {
|
|
1953
|
-
const id = path.replace(/\.mdx?$/i, "").split(sep3).join("/").toLowerCase();
|
|
1954
|
-
const segments = id.split("/");
|
|
1955
|
-
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)) {
|
|
1956
|
-
throw new Error(`${copy_error_doc_id}: ${path}`);
|
|
1957
|
-
}
|
|
1958
|
-
const source = await readFile2(join(options.root, path), "utf8");
|
|
1959
|
-
const file = new VFile({ value: source.replace(/^\uFEFF/, ""), path: join(options.root, path) });
|
|
1960
|
-
const tree = options.processor.parse(file);
|
|
1961
|
-
const frontmatter = tree.children[0];
|
|
1962
|
-
const parsed = docDataSchema.safeParse(frontmatter?.type === "yaml" ? parseYaml(frontmatter.value) : {});
|
|
1963
|
-
if (!parsed.success) {
|
|
1964
|
-
throw new Error(`${copy_error_frontmatter}: ${path}: ${parsed.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join(", ")}`);
|
|
1965
|
-
}
|
|
1966
|
-
const data = {
|
|
1967
|
-
...parsed.data,
|
|
1968
|
-
parent: parsed.data.parent !== void 0 && /^\.\.?\//.test(parsed.data.parent) ? posix3.join(posix3.dirname(id), parsed.data.parent) : parsed.data.parent
|
|
1969
|
-
};
|
|
1970
|
-
const fh = { frontmatter: data, headings: [], sections: [] };
|
|
1971
|
-
file.data.fh = fh;
|
|
1972
|
-
tree.children = tree.children.filter((node) => node.type !== "yaml");
|
|
1973
|
-
const rendered = await options.processor.run(tree, file);
|
|
1974
|
-
return {
|
|
1975
|
-
id,
|
|
1976
|
-
data,
|
|
1977
|
-
ancestors: [],
|
|
1978
|
-
html: options.processor.stringify(rendered, file),
|
|
1979
|
-
outline: { headings: fh.headings, sections: fh.sections }
|
|
1980
|
-
};
|
|
1981
|
-
})
|
|
1982
|
-
);
|
|
1983
|
-
const duplicateIds = [...Map.groupBy(docs, (doc) => doc.id)].filter((entry) => entry[1].length > 1);
|
|
1984
|
-
if (duplicateIds.length > 0) {
|
|
1985
|
-
throw new Error(`${copy_error_doc_id_clash}: ${duplicateIds.map((entry) => entry[0]).join(", ")}`);
|
|
1986
|
-
}
|
|
1987
|
-
const docsById = new Map(docs.map((doc) => [doc.id, doc]));
|
|
1988
|
-
return docs.map((doc) => {
|
|
1989
|
-
const ancestors = /* @__PURE__ */ new Set([doc.id]);
|
|
1990
|
-
for (let parentId = doc.data.parent; parentId !== void 0; ) {
|
|
1991
|
-
const parent = docsById.get(parentId);
|
|
1992
|
-
if (parent === void 0) {
|
|
1993
|
-
throw new Error(`${copy_error_doc_parent_missing}: ${doc.id} \u2192 ${parentId}`);
|
|
1994
|
-
}
|
|
1995
|
-
if (ancestors.has(parent.id)) {
|
|
1996
|
-
throw new Error(`${copy_error_doc_parent_cycle}: ${[...ancestors, parent.id].join(" \u2192 ")}`);
|
|
1997
|
-
}
|
|
1998
|
-
if (JSON.stringify(parent.data.group) !== JSON.stringify(doc.data.group)) {
|
|
1999
|
-
throw new Error(`${copy_error_doc_parent_group}: ${doc.id} \u2192 ${parent.id}`);
|
|
2000
|
-
}
|
|
2001
|
-
ancestors.add(parent.id);
|
|
2002
|
-
parentId = parent.data.parent;
|
|
2003
|
-
}
|
|
2004
|
-
return { ...doc, ancestors: [...ancestors].slice(1).toReversed() };
|
|
2005
|
-
});
|
|
2006
|
-
};
|
|
2007
|
-
|
|
2008
|
-
// src/entry/cli/_function/read-home.ts
|
|
2009
|
-
import { readdir as readdir2, readFile as readFile3 } from "node:fs/promises";
|
|
2010
|
-
import { join as join2 } from "node:path";
|
|
2011
|
-
import { VFile as VFile2 } from "vfile";
|
|
2012
|
-
var readHome = async (options) => {
|
|
2013
|
-
const paths = (await readdir2(options.root)).filter((path2) => path2.toLowerCase() === "readme.md");
|
|
2014
|
-
if (paths.length > 1) {
|
|
2015
|
-
throw new Error(`${copy_error_home_clash}: ${paths.join(", ")}`);
|
|
2016
|
-
}
|
|
2017
|
-
if (paths.length === 0) {
|
|
2018
|
-
return void 0;
|
|
2019
|
-
}
|
|
2020
|
-
const path = join2(options.root, paths[0]);
|
|
2021
|
-
const fh = { headings: [], sections: [] };
|
|
2022
|
-
const file = new VFile2({ value: (await readFile3(path, "utf8")).replace(/^\uFEFF/, ""), path, data: { fh } });
|
|
2023
|
-
await options.processor.process(file);
|
|
2024
|
-
return { html: String(file), outline: { headings: fh.headings, sections: fh.sections } };
|
|
2025
|
-
};
|
|
2026
|
-
|
|
2027
|
-
// src/entry/cli/_function/to-crawling-app.ts
|
|
2028
|
-
import { Hono as Hono3 } from "hono";
|
|
2029
|
-
import { html as html2 } from "hono/html";
|
|
2030
|
-
var toCrawlingApp = (params) => {
|
|
2031
|
-
const app = new Hono3();
|
|
2032
|
-
app.get(crawling_robots_path, (c) => c.text(`User-agent: *
|
|
2033
|
-
Allow: /
|
|
2034
|
-
|
|
2035
|
-
Sitemap: ${params.url}${crawling_sitemap_path}
|
|
2036
|
-
`));
|
|
2037
|
-
app.get(
|
|
2038
|
-
crawling_sitemap_path,
|
|
2039
|
-
(_c) => new Response(
|
|
2040
|
-
html2`<?xml version="1.0" encoding="UTF-8"?>
|
|
2041
|
-
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
2042
|
-
<url><loc>${params.url}/</loc></url>
|
|
2043
|
-
${params.store.docs.map((doc) => html2`<url><loc>${params.url}/${doc.id.split("/").map(encodeURIComponent).join("/")}/</loc></url>`)}
|
|
2044
|
-
</urlset>`.toString(),
|
|
2045
|
-
{ headers: { "Content-Type": "application/xml; charset=utf-8" } }
|
|
2046
|
-
)
|
|
2047
|
-
);
|
|
2048
|
-
return app;
|
|
2049
|
-
};
|
|
2050
|
-
|
|
2051
|
-
// src/type/site-config.ts
|
|
2052
|
-
import { z as z3 } from "zod";
|
|
2053
|
-
|
|
2054
|
-
// src/constant/status.ts
|
|
2055
|
-
var status_kind = {
|
|
2056
|
-
verified: "verified",
|
|
2057
|
-
unverified: "unverified"
|
|
2058
|
-
};
|
|
2059
|
-
var status_default_phrases = [
|
|
2060
|
-
{ phrase: "\uD655\uC778\uB428", kind: status_kind.verified, date: true },
|
|
2061
|
-
{ phrase: "\uD655\uC778\uB418\uC9C0 \uC54A\uC558\uB2E4", kind: status_kind.unverified }
|
|
2062
|
-
];
|
|
2063
|
-
|
|
2064
|
-
// src/type/site-config.ts
|
|
2065
|
-
var siteConfigSchema = z3.object({
|
|
2066
|
-
/**
|
|
2067
|
-
* 사이드바 이름과 탭 제목
|
|
2068
|
-
*/
|
|
2069
|
-
title: z3.string().default(copy_site_title_default),
|
|
2070
|
-
/**
|
|
2071
|
-
* HTML 설명 메타데이터 · 선택
|
|
2072
|
-
*/
|
|
2073
|
-
description: z3.string().optional(),
|
|
2074
|
-
/**
|
|
2075
|
-
* 공개 사이트 루트 URL · 지정할 때만 robots.txt와 sitemap.xml 생성
|
|
2076
|
-
*/
|
|
2077
|
-
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(),
|
|
2078
|
-
/**
|
|
2079
|
-
* dev·preview 서버 포트 · 같은 기계에서 문서 프로젝트 둘을 나란히 띄울 때 한쪽에 지정
|
|
2080
|
-
*/
|
|
2081
|
-
port: z3.int().min(site_port_min).max(site_port_max).default(site_port_default),
|
|
2082
|
-
/**
|
|
2083
|
-
* 데스크톱 커서 옆 픽셀 얼굴 · 기본 꺼짐 · favicon 은 설정과 무관
|
|
2084
|
-
*/
|
|
2085
|
-
cursorFace: z3.boolean().default(false),
|
|
2086
|
-
/**
|
|
2087
|
-
* 탐색 묶음 경로의 읽는 순서 · 미지정 형제 묶음은 뒤에서 이름순
|
|
2088
|
-
*/
|
|
2089
|
-
navigation: z3.array(groupPathSchema).refine((groups) => new Set(groups.map((path) => JSON.stringify(path))).size === groups.length, copy_error_navigation_clash).default(site_navigation_default.map((name) => [name])),
|
|
2090
|
-
/**
|
|
2091
|
-
* 본문에서 상태 표지로 표시할 문구
|
|
2092
|
-
*/
|
|
2093
|
-
status: z3.array(
|
|
2094
|
-
z3.object({
|
|
2095
|
-
/**
|
|
2096
|
-
* 찾을 문구 원문
|
|
2097
|
-
*/
|
|
2098
|
-
phrase: z3.string().min(1).refine((phrase) => phrase.trim().length > 0),
|
|
2099
|
-
/**
|
|
2100
|
-
* 상태 표지의 색 종류
|
|
2101
|
-
*/
|
|
2102
|
-
kind: z3.enum(status_kind),
|
|
2103
|
-
/**
|
|
2104
|
-
* 문구 뒤의 YYYY-MM-DD 날짜 포함 여부
|
|
2105
|
-
*/
|
|
2106
|
-
date: z3.boolean().optional()
|
|
2107
|
-
})
|
|
2108
|
-
).default(status_default_phrases)
|
|
4
|
+
import { defineCommand, runMain } from "citty";
|
|
5
|
+
import { z } from "zod/mini";
|
|
6
|
+
//#region src/entry/cli/_constant/cli.ts
|
|
7
|
+
/**
|
|
8
|
+
* 문서 폴더 생략 시 현재 폴더
|
|
9
|
+
*/
|
|
10
|
+
var cli_docs_args = { dir: {
|
|
11
|
+
type: "positional",
|
|
12
|
+
description: "문서 폴더",
|
|
13
|
+
default: "."
|
|
14
|
+
} };
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/entry/cli/cli.ts
|
|
17
|
+
var main = defineCommand({
|
|
18
|
+
/**
|
|
19
|
+
* 설치한 패키지의 명령 이름과 버전
|
|
20
|
+
*/
|
|
21
|
+
meta: async () => {
|
|
22
|
+
const content = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
|
|
23
|
+
return {
|
|
24
|
+
...z.object({
|
|
25
|
+
name: z.string(),
|
|
26
|
+
version: z.string()
|
|
27
|
+
}).parse(content),
|
|
28
|
+
description: "Markdown 문서 사이트 개발·빌드·미리보기"
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
default: "dev",
|
|
32
|
+
/**
|
|
33
|
+
* Citty의 미지정 옵션 허용을 제한하는 CLI 입력 경계
|
|
34
|
+
*/
|
|
35
|
+
setup: (context) => {
|
|
36
|
+
const option = Object.keys(context.args).find((key) => key !== "_");
|
|
37
|
+
if (option !== void 0) {
|
|
38
|
+
logger.error(`지원하지 않는 옵션: ${option}. --help로 사용법을 확인하세요`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
subCommands: {
|
|
43
|
+
dev: defineCommand({
|
|
44
|
+
meta: {
|
|
45
|
+
name: "dev",
|
|
46
|
+
description: "문서 변경을 반영하는 개발 서버"
|
|
47
|
+
},
|
|
48
|
+
args: cli_docs_args,
|
|
49
|
+
/**
|
|
50
|
+
* 도움말 조회와 분리한 사이트 실행
|
|
51
|
+
*/
|
|
52
|
+
run: async (context) => {
|
|
53
|
+
await (await import("./run-site-command-C80YoNOe.js")).runSiteCommand({
|
|
54
|
+
command: "dev",
|
|
55
|
+
args: context.args
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}),
|
|
59
|
+
build: defineCommand({
|
|
60
|
+
meta: {
|
|
61
|
+
name: "build",
|
|
62
|
+
description: "문서 폴더의 dist에 정적 사이트 생성"
|
|
63
|
+
},
|
|
64
|
+
args: cli_docs_args,
|
|
65
|
+
/**
|
|
66
|
+
* 도움말 조회와 분리한 사이트 실행
|
|
67
|
+
*/
|
|
68
|
+
run: async (context) => {
|
|
69
|
+
await (await import("./run-site-command-C80YoNOe.js")).runSiteCommand({
|
|
70
|
+
command: "build",
|
|
71
|
+
args: context.args
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}),
|
|
75
|
+
preview: defineCommand({
|
|
76
|
+
meta: {
|
|
77
|
+
name: "preview",
|
|
78
|
+
description: "빌드한 정적 사이트의 로컬 미리보기"
|
|
79
|
+
},
|
|
80
|
+
args: cli_docs_args,
|
|
81
|
+
/**
|
|
82
|
+
* 도움말 조회와 분리한 사이트 실행
|
|
83
|
+
*/
|
|
84
|
+
run: async (context) => {
|
|
85
|
+
await (await import("./run-site-command-C80YoNOe.js")).runSiteCommand({
|
|
86
|
+
command: "preview",
|
|
87
|
+
args: context.args
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
}
|
|
2109
92
|
});
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
const state = { requested: 0, completed: 0, running: false };
|
|
2114
|
-
return async () => {
|
|
2115
|
-
state.requested += 1;
|
|
2116
|
-
if (state.running) {
|
|
2117
|
-
return;
|
|
2118
|
-
}
|
|
2119
|
-
state.running = true;
|
|
2120
|
-
try {
|
|
2121
|
-
while (state.completed !== state.requested) {
|
|
2122
|
-
const requested = state.requested;
|
|
2123
|
-
try {
|
|
2124
|
-
await options.run();
|
|
2125
|
-
} catch (error) {
|
|
2126
|
-
options.onError(error);
|
|
2127
|
-
} finally {
|
|
2128
|
-
state.completed = requested;
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
} finally {
|
|
2132
|
-
state.running = false;
|
|
2133
|
-
}
|
|
2134
|
-
};
|
|
2135
|
-
};
|
|
2136
|
-
|
|
2137
|
-
// src/util/error/to-error-message.ts
|
|
2138
|
-
var toErrorMessage = (error) => {
|
|
2139
|
-
if (error instanceof Error && "file" in error && typeof error.file === "string" && "line" in error && typeof error.line === "number") {
|
|
2140
|
-
return `${error.file}:${error.line}: ${error.message}`;
|
|
2141
|
-
}
|
|
2142
|
-
return error instanceof Error ? error.message : String(error);
|
|
2143
|
-
};
|
|
2144
|
-
|
|
2145
|
-
// src/util/font/to-font-css.ts
|
|
2146
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
2147
|
-
import { readFileSync as readFileSync3 } from "node:fs";
|
|
2148
|
-
import { basename, dirname as dirname4, extname as extname4, join as join3 } from "node:path";
|
|
2149
|
-
var toFontCss = (options) => {
|
|
2150
|
-
const files = /* @__PURE__ */ new Map();
|
|
2151
|
-
const css = [...readFileSync3(options.css, "utf8").matchAll(/@font-face\s*\{[^}]*\}/g)].map(
|
|
2152
|
-
(match) => match[0].replace(/font-display:\s*[^;]+;/g, `font-display: ${font_display_strategy};`).replace(/url\(([^)]+)\)/g, (_match, relativeUrl) => {
|
|
2153
|
-
const file = join3(dirname4(options.css), relativeUrl);
|
|
2154
|
-
const extension = extname4(file);
|
|
2155
|
-
const hash = createHash2("sha256").update(readFileSync3(file)).digest("hex").slice(0, font_hash_length);
|
|
2156
|
-
const url = `${options.fontDir}/${basename(file, extension)}.${hash}${extension}`;
|
|
2157
|
-
files.set(url, file);
|
|
2158
|
-
return `url(${url})`;
|
|
2159
|
-
})
|
|
2160
|
-
).join("\n");
|
|
2161
|
-
return { css, files };
|
|
2162
|
-
};
|
|
2163
|
-
|
|
2164
|
-
// src/entry/cli/cli.ts
|
|
2165
|
-
var commands = ["dev", "build", "preview"];
|
|
2166
|
-
var [command = cli_default_command, docsDir = cli_default_docs_dir] = process.argv.slice(2);
|
|
2167
|
-
var main = async () => {
|
|
2168
|
-
if (!commands.includes(command)) {
|
|
2169
|
-
throw new Error(`${copy_error_unknown_command}: ${command} (${commands.join(", ")})`);
|
|
2170
|
-
}
|
|
2171
|
-
const kitRoot = fileURLToPath(new URL("../", import.meta.url));
|
|
2172
|
-
const docsRoot = resolve4(docsDir);
|
|
2173
|
-
const outDir = join4(docsRoot, "dist");
|
|
2174
|
-
const configFile = join4(docsRoot, cli_config_file_name);
|
|
2175
|
-
const parsedConfig = siteConfigSchema.safeParse(existsSync4(configFile) ? (await import(pathToFileURL(configFile).href)).default : site_config_absent);
|
|
2176
|
-
if (!parsedConfig.success) {
|
|
2177
|
-
throw new Error(`${copy_error_config}: ${parsedConfig.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join(", ")}`);
|
|
2178
|
-
}
|
|
2179
|
-
const siteConfig = parsedConfig.data;
|
|
2180
|
-
if (command === "preview") {
|
|
2181
|
-
const app2 = new Hono4();
|
|
2182
|
-
app2.use(
|
|
2183
|
-
"/*",
|
|
2184
|
-
serveStatic({
|
|
2185
|
-
root: relative5(process.cwd(), outDir),
|
|
2186
|
-
onFound: (_path, c) => {
|
|
2187
|
-
if (c.req.path.startsWith(`${asset_font_dir}/`)) {
|
|
2188
|
-
c.header("Cache-Control", font_cache_control);
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
})
|
|
2192
|
-
);
|
|
2193
|
-
serve({ fetch: app2.fetch, port: siteConfig.port }, (info) => console.log(`http://localhost:${info.port}/`));
|
|
2194
|
-
return;
|
|
2195
|
-
}
|
|
2196
|
-
const mono = toFontCss({ css: join4(kitRoot, font_mono_css), fontDir: asset_font_dir });
|
|
2197
|
-
const body = toFontCss({ css: join4(kitRoot, font_body_css), fontDir: asset_font_dir });
|
|
2198
|
-
const brand = toFontCss({ css: join4(kitRoot, font_brand_css), fontDir: asset_font_dir });
|
|
2199
|
-
const fontCss = [mono.css, body.css, brand.css].join("\n");
|
|
2200
|
-
const stylePath = toAssetPath({ path: asset_style_path, file: join4(kitRoot, "dist/cli.css") });
|
|
2201
|
-
const browserScript = readFileSync4(join4(kitRoot, "dist/browser.js"), "utf8");
|
|
2202
|
-
const kitFiles = new Map([
|
|
2203
|
-
[stylePath, join4(kitRoot, "dist/cli.css")],
|
|
2204
|
-
[asset_favicon_path, join4(kitRoot, "src/asset/favicon.svg")],
|
|
2205
|
-
...mono.files,
|
|
2206
|
-
...body.files,
|
|
2207
|
-
...brand.files
|
|
2208
|
-
]);
|
|
2209
|
-
const files = new Map(kitFiles);
|
|
2210
|
-
const snippets = /* @__PURE__ */ new Set();
|
|
2211
|
-
const processor = createProcessor({ site: siteConfig, root: docsRoot, files, snippets });
|
|
2212
|
-
const [docs, home] = await Promise.all([
|
|
2213
|
-
readDocs({ root: docsRoot, processor, reserved: siteConfig.url === void 0 ? void 0 : crawling_reserved_roots }),
|
|
2214
|
-
readHome({ root: docsRoot, processor })
|
|
2215
|
-
]);
|
|
2216
|
-
const store = { docs, home };
|
|
2217
|
-
const crawling = siteConfig.url === void 0 ? void 0 : toCrawlingApp({ url: siteConfig.url, store });
|
|
2218
|
-
const app = createApp({
|
|
2219
|
-
site: siteConfig,
|
|
2220
|
-
store,
|
|
2221
|
-
assets: { stylePath, browserScript, fontCss, preload: [...brand.files.keys(), ...mono.files.keys(), ...body.files.keys()], reload: command === "dev" }
|
|
2222
|
-
});
|
|
2223
|
-
if (command === "build") {
|
|
2224
|
-
await rm(outDir, { recursive: true, force: true });
|
|
2225
|
-
const result = await toSSG(app, { writeFile, mkdir }, { dir: outDir });
|
|
2226
|
-
if (!result.success) {
|
|
2227
|
-
throw result.error;
|
|
2228
|
-
}
|
|
2229
|
-
const crawlerResult = crawling === void 0 ? void 0 : await toSSG(crawling, { writeFile, mkdir }, { dir: outDir });
|
|
2230
|
-
if (crawlerResult?.success === false) {
|
|
2231
|
-
throw crawlerResult.error;
|
|
2232
|
-
}
|
|
2233
|
-
for (const [url, file] of files) {
|
|
2234
|
-
await mkdir(dirname5(join4(outDir, url)), { recursive: true });
|
|
2235
|
-
await copyFile(file, join4(outDir, url));
|
|
2236
|
-
}
|
|
2237
|
-
console.log(
|
|
2238
|
-
`${crawlerResult === void 0 ? result.files.length : result.files.length + crawlerResult.files.length} files, ${files.size} assets \u2192 ${relative5(process.cwd(), outDir)}`
|
|
2239
|
-
);
|
|
2240
|
-
return;
|
|
2241
|
-
}
|
|
2242
|
-
const reload = new EventEmitter();
|
|
2243
|
-
let generation = 0;
|
|
2244
|
-
serve({ fetch: createDevApp({ pages: app, crawling, files, reload }).fetch, port: siteConfig.port }, (info) => console.log(`http://localhost:${info.port}/`));
|
|
2245
|
-
const reloadDocs = debounce(
|
|
2246
|
-
toChangeQueue({
|
|
2247
|
-
run: async () => {
|
|
2248
|
-
const currentGeneration = generation;
|
|
2249
|
-
const nextFiles = new Map(kitFiles);
|
|
2250
|
-
const nextSnippets = /* @__PURE__ */ new Set();
|
|
2251
|
-
const nextProcessor = createProcessor({ site: siteConfig, root: docsRoot, files: nextFiles, snippets: nextSnippets });
|
|
2252
|
-
const [docs2, home2] = await Promise.all([
|
|
2253
|
-
readDocs({ root: docsRoot, processor: nextProcessor, reserved: siteConfig.url === void 0 ? void 0 : crawling_reserved_roots }),
|
|
2254
|
-
readHome({ root: docsRoot, processor: nextProcessor })
|
|
2255
|
-
]);
|
|
2256
|
-
if (currentGeneration !== generation) {
|
|
2257
|
-
return;
|
|
2258
|
-
}
|
|
2259
|
-
files.clear();
|
|
2260
|
-
for (const entry of nextFiles) {
|
|
2261
|
-
files.set(...entry);
|
|
2262
|
-
}
|
|
2263
|
-
snippets.clear();
|
|
2264
|
-
for (const entry of nextSnippets) {
|
|
2265
|
-
snippets.add(entry);
|
|
2266
|
-
}
|
|
2267
|
-
store.docs = docs2;
|
|
2268
|
-
store.home = home2;
|
|
2269
|
-
reload.emit("change");
|
|
2270
|
-
},
|
|
2271
|
-
onError: (error) => console.error(`${copy_error_prefix}: ${toErrorMessage(error)}`)
|
|
2272
|
-
}),
|
|
2273
|
-
cli_reload_delay_ms
|
|
2274
|
-
);
|
|
2275
|
-
const handleDocsChange = (_event, filename) => {
|
|
2276
|
-
if (filename !== null) {
|
|
2277
|
-
const segments = filename.split(sep4);
|
|
2278
|
-
const isSnippet = snippets.has(join4(docsRoot, filename));
|
|
2279
|
-
if (segments.includes("dist") || segments.includes("node_modules") || !isSnippet && !/\.mdx?$/i.test(filename) && !asset_media_extensions.has(extname5(filename).toLowerCase())) {
|
|
2280
|
-
return;
|
|
2281
|
-
}
|
|
2282
|
-
}
|
|
2283
|
-
generation += 1;
|
|
2284
|
-
reloadDocs();
|
|
2285
|
-
};
|
|
2286
|
-
watch(docsRoot, { recursive: true }, handleDocsChange);
|
|
2287
|
-
};
|
|
2288
|
-
try {
|
|
2289
|
-
await main();
|
|
2290
|
-
} catch (error) {
|
|
2291
|
-
console.error(`${copy_error_prefix}: ${toErrorMessage(error)}`);
|
|
2292
|
-
process.exit(1);
|
|
2293
|
-
}
|
|
93
|
+
await runMain(main);
|
|
94
|
+
//#endregion
|
|
95
|
+
export {};
|