@cudoment/cudoc 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +4 -3
  2. package/dist/document.d.ts +36 -1
  3. package/dist/document.d.ts.map +1 -1
  4. package/dist/document.js +54 -3
  5. package/dist/document.js.map +1 -1
  6. package/dist/internal/core/mdx/imports.d.ts +21 -0
  7. package/dist/internal/core/mdx/imports.d.ts.map +1 -0
  8. package/dist/internal/core/mdx/imports.js +80 -0
  9. package/dist/internal/core/mdx/imports.js.map +1 -0
  10. package/dist/internal/core/mdx/index.d.ts +1 -0
  11. package/dist/internal/core/mdx/index.d.ts.map +1 -1
  12. package/dist/internal/core/mdx/index.js +1 -0
  13. package/dist/internal/core/mdx/index.js.map +1 -1
  14. package/dist/internal/core/query/sections.d.ts +6 -0
  15. package/dist/internal/core/query/sections.d.ts.map +1 -1
  16. package/dist/internal/core/query/sections.js +8 -2
  17. package/dist/internal/core/query/sections.js.map +1 -1
  18. package/dist/internal/transforms/table-column-layout/create-table.d.ts.map +1 -1
  19. package/dist/internal/transforms/table-column-layout/create-table.js +40 -17
  20. package/dist/internal/transforms/table-column-layout/create-table.js.map +1 -1
  21. package/dist/internal/transforms/table-column-layout/index.d.ts +32 -0
  22. package/dist/internal/transforms/table-column-layout/index.d.ts.map +1 -1
  23. package/dist/internal/transforms/table-column-layout/index.js +66 -0
  24. package/dist/internal/transforms/table-column-layout/index.js.map +1 -1
  25. package/dist/markdown.d.ts +8 -0
  26. package/dist/markdown.d.ts.map +1 -1
  27. package/dist/markdown.js +9 -1
  28. package/dist/markdown.js.map +1 -1
  29. package/dist/node/check.d.ts +12 -6
  30. package/dist/node/check.d.ts.map +1 -1
  31. package/dist/node/check.js +460 -79
  32. package/dist/node/check.js.map +1 -1
  33. package/dist/node/cli.js +2 -56
  34. package/dist/node/cli.js.map +1 -1
  35. package/dist/node/collect.d.ts +41 -0
  36. package/dist/node/collect.d.ts.map +1 -0
  37. package/dist/node/collect.js +351 -0
  38. package/dist/node/collect.js.map +1 -0
  39. package/dist/node/command.d.ts +23 -0
  40. package/dist/node/command.d.ts.map +1 -0
  41. package/dist/node/command.js +116 -0
  42. package/dist/node/command.js.map +1 -0
  43. package/dist/node/dataset.d.ts +14 -1
  44. package/dist/node/dataset.d.ts.map +1 -1
  45. package/dist/node/dataset.js +44 -5
  46. package/dist/node/dataset.js.map +1 -1
  47. package/dist/node/glob.d.ts +21 -0
  48. package/dist/node/glob.d.ts.map +1 -0
  49. package/dist/node/glob.js +61 -0
  50. package/dist/node/glob.js.map +1 -0
  51. package/dist/node/library.d.ts +76 -6
  52. package/dist/node/library.d.ts.map +1 -1
  53. package/dist/node/library.js +63 -137
  54. package/dist/node/library.js.map +1 -1
  55. package/dist/node/load-ast.d.ts.map +1 -1
  56. package/dist/node/load-ast.js +4 -1
  57. package/dist/node/load-ast.js.map +1 -1
  58. package/dist/node/local-target.d.ts +39 -8
  59. package/dist/node/local-target.d.ts.map +1 -1
  60. package/dist/node/local-target.js +94 -13
  61. package/dist/node/local-target.js.map +1 -1
  62. package/dist/node/prepare-embeds.d.ts +52 -3
  63. package/dist/node/prepare-embeds.d.ts.map +1 -1
  64. package/dist/node/prepare-embeds.js +134 -8
  65. package/dist/node/prepare-embeds.js.map +1 -1
  66. package/dist/node/references.d.ts +39 -0
  67. package/dist/node/references.d.ts.map +1 -0
  68. package/dist/node/references.js +101 -0
  69. package/dist/node/references.js.map +1 -0
  70. package/dist/node/replace.d.ts +65 -0
  71. package/dist/node/replace.d.ts.map +1 -0
  72. package/dist/node/replace.js +285 -0
  73. package/dist/node/replace.js.map +1 -0
  74. package/dist/node/resolve-embed.d.ts +79 -1
  75. package/dist/node/resolve-embed.d.ts.map +1 -1
  76. package/dist/node/resolve-embed.js +480 -143
  77. package/dist/node/resolve-embed.js.map +1 -1
  78. package/dist/node/roots.d.ts +78 -0
  79. package/dist/node/roots.d.ts.map +1 -0
  80. package/dist/node/roots.js +170 -0
  81. package/dist/node/roots.js.map +1 -0
  82. package/dist/node/storage.d.ts +21 -3
  83. package/dist/node/storage.d.ts.map +1 -1
  84. package/dist/node/storage.js +242 -20
  85. package/dist/node/storage.js.map +1 -1
  86. package/dist/node/watch.d.ts +86 -0
  87. package/dist/node/watch.d.ts.map +1 -0
  88. package/dist/node/watch.js +174 -0
  89. package/dist/node/watch.js.map +1 -0
  90. package/dist/paged.d.ts +34 -0
  91. package/dist/paged.d.ts.map +1 -0
  92. package/dist/paged.js +44 -0
  93. package/dist/paged.js.map +1 -0
  94. package/dist/render.d.ts +1 -1
  95. package/dist/render.d.ts.map +1 -1
  96. package/dist/render.js +14 -0
  97. package/dist/render.js.map +1 -1
  98. package/dist/sections.d.ts.map +1 -1
  99. package/dist/sections.js +7 -3
  100. package/dist/sections.js.map +1 -1
  101. package/package.json +29 -16
  102. package/styles.css +5 -2
@@ -1,145 +1,53 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { compileDocument } from "../markdown.js";
4
- import { collectSections } from "../sections.js";
5
- import { findHeadingByAnchorId, findSectionEnd, } from "../internal/core/query/sections.js";
6
- import { buildExportedAst, resolveExportAstOptions } from "./export-ast.js";
7
3
  import { validateAstContract } from "../internal/core/ast/validate.js";
8
- import { hash, posix, safePath, sourceFiles, publishDirectory, writeJson, } from "./storage.js";
4
+ import { hash, safePath, publishDirectory } from "./storage.js";
5
+ import { resolveRoots } from "./roots.js";
6
+ import { collectLibrary, collectLibraryAsync, LIBRARY_SCHEMA_VERSION, } from "./collect.js";
7
+ export { resolveRoots, documentIdOf, libraryPathOf, sourceFileOf, } from "./roots.js";
8
+ export { LIBRARY_SCHEMA_VERSION } from "./collect.js";
9
+ /**
10
+ * Compiles every document and publishes the library to `outDir`, replacing
11
+ * what was there in one step. Prepared embeds are not part of it: a separate
12
+ * `prepareEmbeds` adds `embeds.json`, and `collectDocuments` does both into
13
+ * one publication.
14
+ */
15
+ export function buildDocuments(options) {
16
+ const collection = collectLibrary(options);
17
+ publishDirectory(collection.inputs, collection.outDir, collection.write);
18
+ return collection.library;
19
+ }
9
20
  /** Collect async framework compilers before publishing or resolving any embeds. */
10
21
  export async function buildDocumentsAsync(options) {
11
- const { compiler, ...rest } = options;
12
- const compiled = new Map();
13
- for (const filePath of sourceFiles(options.sourceRoot)) {
14
- const source = fs.readFileSync(filePath, "utf8");
15
- const id = posix(path.relative(options.sourceRoot, filePath)).replace(/\.mdx?$/i, "");
16
- const format = path.extname(filePath).toLowerCase() === ".mdx" ? "mdx" : "md";
17
- compiled.set(id, {
18
- source,
19
- result: await compiler(source, {
20
- id,
21
- filePath,
22
- options: { ...rest, format },
23
- }),
24
- });
25
- }
26
- const library = buildDocuments({
27
- ...rest,
28
- compiler(source, context) {
29
- const cached = compiled.get(context.id);
30
- if (!cached || cached.source !== source)
31
- throw new Error(`cudoc: source changed during collection: ${context.id}`);
32
- return cached.result;
33
- },
34
- });
35
- delete library.compiler;
36
- library.asyncCompiler = compiler;
37
- return library;
38
- }
39
- export function snapshotSource(text, tree, format) {
40
- const sections = {};
41
- for (const section of collectSections(tree)) {
42
- const nodes = section.tree.children;
43
- const location = findHeadingByAnchorId(tree, section.anchorId);
44
- const siblings = location.parent.children;
45
- const endIndex = findSectionEnd(location.parent, location.index, section.heading.depth);
46
- const start = section.heading.position?.start.offset;
47
- const end = siblings[endIndex]?.position?.start.offset ??
48
- location.parent.position?.end.offset ??
49
- text.length;
50
- const ownEnd = siblings
51
- .slice(location.index + 1, endIndex)
52
- .find((n) => n.type === "heading")?.position?.start.offset ?? end;
53
- if (start === undefined || end === undefined)
54
- continue;
55
- const dependencies = nodes
56
- .filter((n) => ["definition", "footnoteDefinition"].includes(n.type) && n.position)
57
- .map((n) => [n.position.start.offset, n.position.end.offset]);
58
- sections[section.anchorId] = { start, end, ownEnd, dependencies };
59
- }
60
- return { text, hash: hash(text), format, sections };
22
+ const collection = await collectLibraryAsync(options);
23
+ publishDirectory(collection.inputs, collection.outDir, collection.write);
24
+ return collection.library;
61
25
  }
62
- export function buildDocuments({ sourceRoot, outDir = ".cudoc/documents", compiler, compilerId, routeBase = "/", routeSuffix = "", routes = {}, ...options }) {
63
- if (options.host &&
64
- !["markdown", "html", "next"].includes(options.host) &&
65
- !compiler)
66
- throw new Error(`cudoc: ${options.host} collection requires its host compiler`);
67
- if (compiler && !compilerId)
68
- throw new Error("cudoc: compilerId is required with a custom compiler");
69
- const documents = [];
70
- const ids = new Set();
71
- for (const filePath of sourceFiles(sourceRoot)) {
72
- const sourcePath = posix(path.relative(sourceRoot, filePath));
73
- const id = sourcePath.replace(/\.mdx?$/i, "");
74
- if (ids.has(id.toLowerCase()))
75
- throw new Error(`cudoc: duplicate document output: ${sourcePath}`);
76
- ids.add(id.toLowerCase());
77
- const text = fs.readFileSync(filePath, "utf8");
78
- const format = path.extname(filePath).toLowerCase() === ".mdx" ? "mdx" : "md";
79
- const config = { ...options, format };
80
- const compiled = compiler
81
- ? compiler(text, { id, filePath, options: config })
82
- : compileDocument(text, config);
83
- for (const diagnostic of compiled.diagnostics)
84
- process.stderr.write(`${sourcePath}:${diagnostic.position?.start.line ?? 1}: ${diagnostic.code}: ${diagnostic.message}\n`);
85
- const source = snapshotSource(text, compiled.tree, format);
86
- const tree = buildExportedAst(compiled.tree, resolveExportAstOptions());
87
- documents.push({
88
- id,
89
- sourcePath,
90
- route: routes[id] ?? `${routeBase.replace(/\/$/, "")}/${id}${routeSuffix}`,
91
- tree,
92
- source,
93
- frontmatter: compiled.frontmatter,
94
- });
26
+ const loaded = new Map();
27
+ /**
28
+ * Reads a published library back. `roots` restores where the documents live
29
+ * on disk, which replacement and asset resolution need; a single directory is
30
+ * the shorthand for one root at the top. The bases given have to be the ones
31
+ * the library was collected with, because ids were derived from them.
32
+ */
33
+ export function loadLibrary(outDir = ".cudoc/documents", compiler, roots, options = {}) {
34
+ const manifestText = fs.readFileSync(path.join(outDir, "manifest.json"), "utf8");
35
+ const key = path.resolve(outDir);
36
+ const cached = options.cache ? loaded.get(key) : undefined;
37
+ if (cached && cached.manifest === manifestText) {
38
+ const resolved = roots === undefined
39
+ ? undefined
40
+ : resolveLoadedRoots(roots, cached.library);
41
+ return {
42
+ ...cached.library,
43
+ compiler,
44
+ ...(resolved ? { roots: resolved } : {}),
45
+ };
95
46
  }
96
- const configuration = hash(JSON.stringify({
97
- options,
98
- routeBase,
99
- routeSuffix,
100
- routes,
101
- compilerId: compilerId ?? "cudoc-markdown-v1",
102
- }));
103
- const urls = new Set();
104
- for (const document of documents) {
105
- if (!document.route.startsWith("/") ||
106
- document.route.startsWith("//") ||
107
- /[?#]/.test(document.route))
108
- throw new Error(`cudoc: document route must be a root-relative pathname: ${document.route}`);
109
- if (urls.has(document.route))
110
- throw new Error(`cudoc: duplicate document route: ${document.route}`);
111
- urls.add(document.route);
112
- }
113
- const library = {
114
- documents,
115
- options,
116
- configuration,
117
- compiler,
118
- sourceRoot: path.resolve(sourceRoot),
119
- };
120
- publishDirectory(sourceRoot, outDir, (staging) => {
121
- for (const doc of documents) {
122
- writeJson(safePath(staging, `documents/${doc.id}.json`), doc.tree);
123
- writeJson(safePath(staging, `sources/${doc.id}.json`), doc.source);
124
- }
125
- writeJson(path.join(staging, "manifest.json"), {
126
- schemaVersion: 1,
127
- configuration,
128
- options,
129
- compilerId,
130
- documents: documents.map(({ tree, source, ...doc }) => ({
131
- ...doc,
132
- hash: source.hash,
133
- astHash: hash(JSON.stringify(tree)),
134
- snapshotHash: hash(JSON.stringify(source)),
135
- })),
136
- });
137
- });
138
- return library;
139
- }
140
- export function loadLibrary(outDir = ".cudoc/documents", compiler, sourceRoot) {
141
- const manifest = JSON.parse(fs.readFileSync(path.join(outDir, "manifest.json"), "utf8"));
142
- if (manifest.schemaVersion !== 1 || !Array.isArray(manifest.documents))
47
+ const manifest = JSON.parse(manifestText);
48
+ if (manifest.schemaVersion !== LIBRARY_SCHEMA_VERSION ||
49
+ !Array.isArray(manifest.documents) ||
50
+ !Array.isArray(manifest.roots))
143
51
  throw new Error("cudoc: incompatible document manifest; rebuild documents");
144
52
  const documents = manifest.documents.map((entry) => {
145
53
  const tree = JSON.parse(fs.readFileSync(safePath(outDir, `documents/${entry.id}.json`), "utf8"));
@@ -152,12 +60,30 @@ export function loadLibrary(outDir = ".cudoc/documents", compiler, sourceRoot) {
152
60
  throw new Error(`cudoc: stored document hash mismatch: ${entry.id}`);
153
61
  return { ...entry, tree, source };
154
62
  });
155
- return {
63
+ const library = {
156
64
  documents,
157
65
  options: manifest.options,
158
66
  configuration: manifest.configuration,
67
+ bases: manifest.roots.map((root) => root.base),
68
+ };
69
+ const resolved = roots === undefined ? undefined : resolveLoadedRoots(roots, library);
70
+ if (options.cache)
71
+ loaded.set(key, { manifest: manifestText, library });
72
+ return {
73
+ ...library,
159
74
  compiler,
160
- sourceRoot: sourceRoot ? path.resolve(sourceRoot) : undefined,
75
+ ...(resolved ? { roots: resolved } : {}),
161
76
  };
162
77
  }
78
+ /** The roots a caller gives a loaded library, checked against the bases it was collected with. */
79
+ function resolveLoadedRoots(roots, library) {
80
+ const resolved = resolveRoots(typeof roots === "string" ? { sourceRoot: roots } : { roots });
81
+ const stored = [...(library.bases ?? [])].sort();
82
+ const given = resolved.map((root) => root.base).sort();
83
+ if (JSON.stringify(stored) !== JSON.stringify(given))
84
+ throw new Error(`cudoc: roots do not match the library; it was collected with bases [${stored
85
+ .map((base) => JSON.stringify(base))
86
+ .join(", ")}]`);
87
+ return resolved;
88
+ }
163
89
  //# sourceMappingURL=library.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/node/library.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/node/library.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"load-ast.d.ts","sourceRoot":"","sources":["../../src/node/load-ast.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AACrE,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAErE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExD;;;GAGG;AACH,eAAO,MAAM,OAAO,GAClB,cAAc,MAAM,EACpB,UAAS,cAAc,GAAG,WAAgB,KACzC,oBAWF,CAAA"}
1
+ {"version":3,"file":"load-ast.d.ts","sourceRoot":"","sources":["../../src/node/load-ast.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AACrE,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExD;;;GAGG;AACH,eAAO,MAAM,OAAO,GAClB,cAAc,MAAM,EACpB,UAAS,cAAc,GAAG,WAAgB,KACzC,oBAYF,CAAA"}
@@ -2,6 +2,7 @@
2
2
  import path from "node:path";
3
3
  import { resolvePathOptions, } from "./paths.js";
4
4
  import { loadAstFile } from "./load-ast-file.js";
5
+ import { safePath } from "./storage.js";
5
6
  export { loadAstFile } from "./load-ast-file.js";
6
7
  /**
7
8
  * Loads the document stored for a source-relative document path, such as
@@ -11,7 +12,9 @@ export const loadAst = (documentPath, options = {}) => {
11
12
  const pathOptions = resolvePathOptions(options);
12
13
  const projectRoot = pathOptions.cwd ?? process.cwd();
13
14
  const normalized = documentPath.replace(/^[/\\]+/, "").replace(/\.json$/i, "");
14
- const filePath = path.join(projectRoot, pathOptions.outDir, `${normalized}.json`);
15
+ // A document path names a file inside the output directory, never beside
16
+ // it: `../../secrets` is refused rather than read.
17
+ const filePath = safePath(path.join(projectRoot, pathOptions.outDir), `${normalized}.json`);
15
18
  return loadAstFile(filePath, options);
16
19
  };
17
20
  //# sourceMappingURL=load-ast.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-ast.js","sourceRoot":"","sources":["../../src/node/load-ast.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EACL,kBAAkB,GAGnB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAAuB,MAAM,oBAAoB,CAAA;AAErE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,YAAoB,EACpB,UAAwC,EAAE,EACpB,EAAE;IACxB,MAAM,WAAW,GAAwB,kBAAkB,CAAC,OAAO,CAAC,CAAA;IACpE,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACpD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,WAAW,EACX,WAAW,CAAC,MAAM,EAClB,GAAG,UAAU,OAAO,CACrB,CAAA;IAED,OAAO,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;AACvC,CAAC,CAAA"}
1
+ {"version":3,"file":"load-ast.js","sourceRoot":"","sources":["../../src/node/load-ast.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EACL,kBAAkB,GAGnB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAAuB,MAAM,oBAAoB,CAAA;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,YAAoB,EACpB,UAAwC,EAAE,EACpB,EAAE;IACxB,MAAM,WAAW,GAAwB,kBAAkB,CAAC,OAAO,CAAC,CAAA;IACpE,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACpD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAC9E,yEAAyE;IACzE,mDAAmD;IACnD,MAAM,QAAQ,GAAG,QAAQ,CACvB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1C,GAAG,UAAU,OAAO,CACrB,CAAA;IAED,OAAO,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;AACvC,CAAC,CAAA"}
@@ -5,9 +5,14 @@
5
5
  * it does not. Both go through here so a document cannot pass one and fail the
6
6
  * other: a link the checker calls resolvable is a link the exporter can copy.
7
7
  */
8
+ import { type ResolvedRoot } from "./roots.js";
8
9
  export type LocalTargetRoots = {
9
- /** The document source root. A document-relative path resolves here first. */
10
- sourceRoot: string;
10
+ /**
11
+ * The roots documents were collected from. A document-relative path
12
+ * resolves in the library's own coordinates first, so it reaches a file
13
+ * under whichever root holds that library path.
14
+ */
15
+ roots: readonly ResolvedRoot[];
11
16
  /** Extra roots holding host assets, such as `public` or `static`. */
12
17
  assetDirs?: string[];
13
18
  /**
@@ -15,6 +20,12 @@ export type LocalTargetRoots = {
15
20
  * routing. Defaults to identity for a site served from the domain root.
16
21
  */
17
22
  withoutBase?: (pathname: string) => string;
23
+ /**
24
+ * Root-relative path prefixes that another application serves on the same
25
+ * host, such as `/sdk`. A link into one is external: not checked, not
26
+ * copied, not rewritten.
27
+ */
28
+ externalPaths?: string[];
18
29
  };
19
30
  export type LocalTarget = {
20
31
  kind: "external";
@@ -29,15 +40,35 @@ export type LocalTarget = {
29
40
  relative: string;
30
41
  suffix: string;
31
42
  };
43
+ /** A fragment, a scheme or a protocol-relative URL: nothing on this disk. */
44
+ export declare const externalUrl: (url: string) => boolean;
45
+ /**
46
+ * Whether a root-relative URL falls under one of the configured external
47
+ * prefixes. `/sdk` covers `/sdk` and `/sdk/…`, not `/sdk-tools`.
48
+ */
49
+ export declare function isExternalPath(url: string, prefixes: readonly string[] | undefined): boolean;
32
50
  /**
33
51
  * Resolves one URL against the document that carries it.
34
52
  *
35
- * A fragment, scheme or protocol-relative URL is external and left alone. A
36
- * document-relative path resolves against `sourceRoot`; a root-relative one is
37
- * also tried against each asset directory, after the deployment base is
38
- * removed. A path that escapes every root is reported as missing rather than
39
- * resolved, so the caller names the link and its document instead of a
40
- * traversal that means nothing to an author.
53
+ * A fragment, scheme or protocol-relative URL is external and left alone, and
54
+ * so is a root-relative one under an external prefix. A document-relative
55
+ * path resolves against the library path of its document, and a root-relative
56
+ * one against the library itself; both then reach disk through the roots. A
57
+ * root-relative path is also tried against each asset directory, after the
58
+ * deployment base is removed. A path that escapes every root is reported as
59
+ * missing rather than resolved, so the caller names the link and its document
60
+ * instead of a traversal that means nothing to an author.
41
61
  */
42
62
  export declare function resolveLocalTarget(url: string, documentSourcePath: string, roots: LocalTargetRoots): LocalTarget;
63
+ /**
64
+ * The candidates of a `srcset`, read as the HTML standard reads them: a URL
65
+ * runs to the next white space, so a comma inside it, as in a data URL,
66
+ * belongs to it, and commas the URL ends with are separators; the descriptors
67
+ * run to the next comma outside parentheses. Empty candidates, left by a
68
+ * stray comma, are skipped as browsers skip them.
69
+ */
70
+ export declare const parseSrcSet: (value: string) => {
71
+ url: string;
72
+ descriptor: string;
73
+ }[];
43
74
  //# sourceMappingURL=local-target.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-target.d.ts","sourceRoot":"","sources":["../../src/node/local-target.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3C,CAAA;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAWzD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,EAC1B,KAAK,EAAE,gBAAgB,GACtB,WAAW,CAwBb"}
1
+ {"version":3,"file":"local-target.d.ts","sourceRoot":"","sources":["../../src/node/local-target.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAG9D,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;OAIG;IACH,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAA;IAC1C;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAWzD,6EAA6E;AAC7E,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,OACK,CAAA;AAE/C;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACtC,OAAO,CAUT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,EAC1B,KAAK,EAAE,gBAAgB,GACtB,WAAW,CAsCb;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,OAAO,MAAM,KACZ;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAwCrC,CAAA"}
@@ -8,6 +8,8 @@
8
8
  import fs from "node:fs";
9
9
  import path from "node:path";
10
10
  import { safePath } from "./storage.js";
11
+ import { candidateFiles } from "./roots.js";
12
+ import { EXTERNAL_URL, decodeComponent } from "./references.js";
11
13
  /** `safePath`, but a path escaping its root is a non-match rather than a throw. */
12
14
  const containedPath = (root, relative) => {
13
15
  try {
@@ -17,36 +19,115 @@ const containedPath = (root, relative) => {
17
19
  return undefined;
18
20
  }
19
21
  };
22
+ /** A fragment, a scheme or a protocol-relative URL: nothing on this disk. */
23
+ export const externalUrl = (url) => url.startsWith("#") || EXTERNAL_URL.test(url);
24
+ /**
25
+ * Whether a root-relative URL falls under one of the configured external
26
+ * prefixes. `/sdk` covers `/sdk` and `/sdk/…`, not `/sdk-tools`.
27
+ */
28
+ export function isExternalPath(url, prefixes) {
29
+ if (!prefixes?.length || !url.startsWith("/") || url.startsWith("//"))
30
+ return false;
31
+ const pathname = url.match(/^[^?#]*/)[0];
32
+ return prefixes.some((prefix) => {
33
+ const clean = `/${prefix.replace(/^\/+|\/+$/g, "")}`;
34
+ return (clean !== "/" && (pathname === clean || pathname.startsWith(`${clean}/`)));
35
+ });
36
+ }
20
37
  /**
21
38
  * Resolves one URL against the document that carries it.
22
39
  *
23
- * A fragment, scheme or protocol-relative URL is external and left alone. A
24
- * document-relative path resolves against `sourceRoot`; a root-relative one is
25
- * also tried against each asset directory, after the deployment base is
26
- * removed. A path that escapes every root is reported as missing rather than
27
- * resolved, so the caller names the link and its document instead of a
28
- * traversal that means nothing to an author.
40
+ * A fragment, scheme or protocol-relative URL is external and left alone, and
41
+ * so is a root-relative one under an external prefix. A document-relative
42
+ * path resolves against the library path of its document, and a root-relative
43
+ * one against the library itself; both then reach disk through the roots. A
44
+ * root-relative path is also tried against each asset directory, after the
45
+ * deployment base is removed. A path that escapes every root is reported as
46
+ * missing rather than resolved, so the caller names the link and its document
47
+ * instead of a traversal that means nothing to an author.
29
48
  */
30
49
  export function resolveLocalTarget(url, documentSourcePath, roots) {
31
- if (/^(?:#|[a-z][\w+.-]*:|\/\/)/i.test(url))
50
+ if (externalUrl(url) || isExternalPath(url, roots.externalPaths))
32
51
  return { kind: "external", url };
33
52
  const [, pathname, suffix] = url.match(/^([^?#]*)(.*)$/);
34
- const decoded = decodeURIComponent(pathname);
53
+ const decoded = decodeComponent(pathname);
35
54
  const relative = path.posix.normalize(decoded.startsWith("/")
36
55
  ? decoded.slice(1)
37
56
  : path.posix.join(path.posix.dirname(documentSourcePath), decoded));
38
57
  const withoutBase = roots.withoutBase ?? ((value) => value);
39
58
  const rootPath = withoutBase(decoded.startsWith("/") ? decoded : `/${relative}`).replace(/^\//, "");
40
59
  const candidates = [
41
- { root: roots.sourceRoot, relative },
42
- ...(roots.assetDirs ?? []).map((root) => ({ root, relative: rootPath })),
60
+ ...candidateFiles(roots.roots, relative).map((source) => ({
61
+ relative,
62
+ source,
63
+ })),
64
+ ...(roots.assetDirs ?? []).flatMap((root) => {
65
+ const source = containedPath(root, rootPath);
66
+ return source ? [{ relative: rootPath, source }] : [];
67
+ }),
43
68
  ];
44
69
  for (const candidate of candidates) {
45
- const source = containedPath(candidate.root, candidate.relative);
46
- if (!source || !fs.existsSync(source) || !fs.statSync(source).isFile())
70
+ if (!fs.existsSync(candidate.source) ||
71
+ !fs.statSync(candidate.source).isFile())
47
72
  continue;
48
- return { kind: "resolved", relative: candidate.relative, source, suffix };
73
+ return {
74
+ kind: "resolved",
75
+ relative: candidate.relative,
76
+ source: candidate.source,
77
+ suffix,
78
+ };
49
79
  }
50
80
  return { kind: "missing", relative, suffix };
51
81
  }
82
+ /**
83
+ * The candidates of a `srcset`, read as the HTML standard reads them: a URL
84
+ * runs to the next white space, so a comma inside it, as in a data URL,
85
+ * belongs to it, and commas the URL ends with are separators; the descriptors
86
+ * run to the next comma outside parentheses. Empty candidates, left by a
87
+ * stray comma, are skipped as browsers skip them.
88
+ */
89
+ export const parseSrcSet = (value) => {
90
+ const candidates = [];
91
+ // ASCII white space only: a no-break or ideographic space is part of a URL.
92
+ const space = (character) => character === " " ||
93
+ character === "\t" ||
94
+ character === "\n" ||
95
+ character === "\f" ||
96
+ character === "\r";
97
+ let index = 0;
98
+ while (index < value.length) {
99
+ while (index < value.length &&
100
+ (space(value[index]) || value[index] === ","))
101
+ index++;
102
+ const start = index;
103
+ while (index < value.length && !space(value[index]))
104
+ index++;
105
+ let url = value.slice(start, index);
106
+ let descriptor = "";
107
+ if (url.endsWith(","))
108
+ url = url.replace(/,+$/, "");
109
+ else {
110
+ const from = index;
111
+ let inParens = false;
112
+ while (index < value.length) {
113
+ const character = value[index];
114
+ if (character === "(")
115
+ inParens = true;
116
+ else if (character === ")")
117
+ inParens = false;
118
+ else if (character === "," && !inParens)
119
+ break;
120
+ index++;
121
+ }
122
+ descriptor = value
123
+ .slice(from, index)
124
+ .split(/[\t\n\f\r ]+/)
125
+ .filter(Boolean)
126
+ .join(" ");
127
+ }
128
+ if (url)
129
+ candidates.push({ url, descriptor });
130
+ }
131
+ return candidates;
132
+ };
52
133
  //# sourceMappingURL=local-target.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-target.js","sourceRoot":"","sources":["../../src/node/local-target.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAmBvC,mFAAmF;AACnF,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,EAAE;IACvD,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAAW,EACX,kBAA0B,EAC1B,KAAuB;IAEvB,IAAI,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAA;IAC7E,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAE,CAAA;IACzD,MAAM,OAAO,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAA;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CACnC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QACrB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC,CACrE,CAAA;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,CAAA;IACnE,MAAM,QAAQ,GAAG,WAAW,CAC1B,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CACnD,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACpB,MAAM,UAAU,GAAG;QACjB,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,QAAQ,EAAE;QACpC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;KACzE,CAAA;IACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAA;QAChE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE;YACpE,SAAQ;QACV,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;IAC3E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;AAC9C,CAAC"}
1
+ {"version":3,"file":"local-target.js","sourceRoot":"","sources":["../../src/node/local-target.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,62 @@
1
1
  import type { Root } from "mdast";
2
2
  import type { Library } from "./library.js";
3
3
  export type PreparedEmbeds = {
4
- schemaVersion: 1;
4
+ schemaVersion: 2;
5
5
  configuration: string;
6
6
  sourceHashes: Record<string, string>;
7
7
  blocks: Record<string, Root>;
8
+ /**
9
+ * The documents each block read, by block key: the sources named in its
10
+ * fence and in every embed nested in them. `["*"]` marks a block that ran
11
+ * an extractor, which may read anything.
12
+ */
13
+ dependencies: Record<string, string[]>;
8
14
  };
9
15
  export declare const embedKey: (documentId: string, value: string, index: number) => string;
10
- /** Run after collection and before the host build. No asynchronous compiler is needed at render time. */
11
- export declare function prepareEmbeds(library: Library, outDir?: string): Promise<PreparedEmbeds>;
16
+ export type PrepareEmbedsOptions = {
17
+ /**
18
+ * The result of an earlier preparation. A block is taken from it unresolved
19
+ * when the configuration, the set of documents, the embedding document and
20
+ * every document the block depends on are unchanged.
21
+ */
22
+ previous?: PreparedEmbeds;
23
+ };
24
+ /**
25
+ * Run after collection and before the host build. No asynchronous compiler is
26
+ * needed at render time.
27
+ *
28
+ * Every block is resolved before anything is written, so one pass names every
29
+ * embed that cannot be prepared, each with its document and block number: a
30
+ * single failure as an error whose `cause` is the resolver's, and several as
31
+ * one `AggregateError` whose message lists them. Nothing is written when any
32
+ * block fails.
33
+ */
34
+ export declare function prepareEmbeds(library: Library, outDir?: string, options?: PrepareEmbedsOptions): Promise<PreparedEmbeds>;
35
+ /**
36
+ * Reads the prepared embeds a host compiles a page with, checked against the
37
+ * page's own source and against the library they were prepared from.
38
+ *
39
+ * A host asks once per page, or once per block, so the two files are parsed
40
+ * once and kept while neither changes on disk; publishing replaces both, so a
41
+ * new collection is read on the next call. The result is shared between
42
+ * calls: a caller copies a block before putting it in its own tree.
43
+ */
12
44
  export declare function readPreparedEmbeds(outDir: string, documentId: string, source: string): PreparedEmbeds;
45
+ /** The embedding document a host is compiling, as `expandPreparedEmbeds` needs it. */
46
+ export type PreparedTarget = {
47
+ /** Where the library and its `embeds.json` were published. */
48
+ outDir: string;
49
+ documentId: string;
50
+ /** The document's source as collected, which the preparation must match. */
51
+ source: string;
52
+ };
53
+ /**
54
+ * Replaces every `cudoc-embed` fence in `tree` with its prepared block, in
55
+ * document order, the way a host build does. The tree is modified in place
56
+ * and returned. `target` is read when the first fence is met, so a document
57
+ * with no embeds needs no library at all; a function defers the work of
58
+ * finding it until then. `onBlock` sees each block's copy before it is
59
+ * spliced in.
60
+ */
61
+ export declare function expandPreparedEmbeds(tree: Root, target: PreparedTarget | (() => PreparedTarget), onBlock?: (block: Root, documentId: string) => void): Root;
13
62
  //# sourceMappingURL=prepare-embeds.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepare-embeds.d.ts","sourceRoot":"","sources":["../../src/node/prepare-embeds.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;CAC7B,CAAA;AACD,eAAO,MAAM,QAAQ,GAAI,YAAY,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,WAChC,CAAA;AAEzC,yGAAyG;AACzG,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,MAAM,SAAqB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAkCzB;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,cAAc,CAuBhB"}
1
+ {"version":3,"file":"prepare-embeds.d.ts","sourceRoot":"","sources":["../../src/node/prepare-embeds.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAC5B;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CACvC,CAAA;AACD,eAAO,MAAM,QAAQ,GAAI,YAAY,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,WAChC,CAAA;AAEzC,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAA;CAC1B,CAAA;AAyBD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,MAAM,SAAqB,EAC3B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,CAAC,CAwFzB;AAeD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,cAAc,CA6BhB;AAED,sFAAsF;AACtF,MAAM,MAAM,cAAc,GAAG;IAC3B,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,cAAc,GAAG,CAAC,MAAM,cAAc,CAAC,EAC/C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,GAClD,IAAI,CA8BN"}