@baiyibai-antora/extensions 1.13.0 → 1.14.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.adoc +18 -0
- package/README.adoc +17 -1
- package/dist/extensions/attribute-distiller/index.d.ts +6 -0
- package/dist/extensions/attribute-distiller/index.d.ts.map +1 -1
- package/dist/extensions/attribute-distiller/index.js +92 -16
- package/dist/extensions/attribute-distiller/index.js.map +1 -1
- package/dist/extensions/autoterm/index.d.ts +29 -18
- package/dist/extensions/autoterm/index.d.ts.map +1 -1
- package/dist/extensions/autoterm/index.js +37 -197
- package/dist/extensions/autoterm/index.js.map +1 -1
- package/dist/extensions/cite-it/asciidoc.d.ts +29 -0
- package/dist/extensions/cite-it/asciidoc.d.ts.map +1 -0
- package/dist/extensions/cite-it/asciidoc.js +32 -0
- package/dist/extensions/cite-it/asciidoc.js.map +1 -0
- package/dist/extensions/cite-it/assembly-numbering.d.ts +202 -0
- package/dist/extensions/cite-it/assembly-numbering.d.ts.map +1 -0
- package/dist/extensions/cite-it/assembly-numbering.js +385 -0
- package/dist/extensions/cite-it/assembly-numbering.js.map +1 -0
- package/dist/extensions/cite-it/csl.d.ts +45 -0
- package/dist/extensions/cite-it/csl.d.ts.map +1 -0
- package/dist/extensions/cite-it/csl.js +139 -0
- package/dist/extensions/cite-it/csl.js.map +1 -0
- package/dist/extensions/cite-it/index.d.ts +300 -0
- package/dist/extensions/cite-it/index.d.ts.map +1 -0
- package/dist/extensions/cite-it/index.js +1098 -0
- package/dist/extensions/cite-it/index.js.map +1 -0
- package/dist/extensions/cite-it/macro.d.ts +104 -0
- package/dist/extensions/cite-it/macro.d.ts.map +1 -0
- package/dist/extensions/cite-it/macro.js +245 -0
- package/dist/extensions/cite-it/macro.js.map +1 -0
- package/dist/extensions/cite-it/registry.d.ts +64 -0
- package/dist/extensions/cite-it/registry.d.ts.map +1 -0
- package/dist/extensions/cite-it/registry.js +157 -0
- package/dist/extensions/cite-it/registry.js.map +1 -0
- package/dist/extensions/trademark-it/index.d.ts +91 -22
- package/dist/extensions/trademark-it/index.d.ts.map +1 -1
- package/dist/extensions/trademark-it/index.js +239 -242
- package/dist/extensions/trademark-it/index.js.map +1 -1
- package/dist/lib/asciidoc-conditionals.d.ts +59 -0
- package/dist/lib/asciidoc-conditionals.d.ts.map +1 -0
- package/dist/lib/asciidoc-conditionals.js +0 -0
- package/dist/lib/asciidoc-conditionals.js.map +1 -0
- package/dist/lib/asciidoc-indexterms.d.ts +126 -0
- package/dist/lib/asciidoc-indexterms.d.ts.map +1 -0
- package/dist/lib/asciidoc-indexterms.js +261 -0
- package/dist/lib/asciidoc-indexterms.js.map +1 -0
- package/dist/lib/asciidoc-table.d.ts +32 -0
- package/dist/lib/asciidoc-table.d.ts.map +1 -0
- package/dist/lib/asciidoc-table.js +55 -0
- package/dist/lib/asciidoc-table.js.map +1 -0
- package/package.json +19 -4
- package/resources/cite-it/ieee-bracket.csl +519 -0
- package/resources/cite-it/locale-en-US.xml +864 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cite-it: true first-appearance numbering for Antora Assembler-flattened
|
|
3
|
+
* (PDF) output.
|
|
4
|
+
*
|
|
5
|
+
* `@antora/pdf-extension` shells the stitched document out to the real Ruby
|
|
6
|
+
* `asciidoctor-pdf` CLI as a subprocess. Ruby never loads this package's JS
|
|
7
|
+
* `citeit:[key]` macro (asciidoc.ts), so a live-macro-only design silently
|
|
8
|
+
* fails for PDF output: the macro simply never runs. The fix needs no Ruby
|
|
9
|
+
* code at all: `@antora/assembler`'s own `produceAssemblyFile` builds the
|
|
10
|
+
* stitched document from `doc.getSourceLines()` on a Document `loadAsciiDoc`
|
|
11
|
+
* (Asciidoctor.js) just parsed, so whatever text is fed into `loadAsciiDoc`
|
|
12
|
+
* is exactly what ends up in Ruby's stdin. This module rewrites
|
|
13
|
+
* `citeit:[key]` to its final number in the page's own text before calling
|
|
14
|
+
* the real `loadAsciiDoc`, using Antora's own `replaceFunctions` extension-
|
|
15
|
+
* cooperation point (`@antora/site-generator`'s `GeneratorContext`).
|
|
16
|
+
*
|
|
17
|
+
* True first-appearance order across an assembled multi-page document is
|
|
18
|
+
* only knowable from the same page order `@antora/assembler` itself
|
|
19
|
+
* assembles in, so this module computes that order independently in Node,
|
|
20
|
+
* from the SAME navigation source assembler resolves to. This accounts for
|
|
21
|
+
* a custom assembler-profile `nav:` override, via the shared
|
|
22
|
+
* `assemblerProfiles` variable `@antora/assembler`'s own `configure.js`
|
|
23
|
+
* computes and publishes at `componentsRegistered`, well before
|
|
24
|
+
* `navigationBuilt`, rather than assuming the component-version's default
|
|
25
|
+
* navigation always applies.
|
|
26
|
+
*
|
|
27
|
+
* Scope limitation, deliberate for this version: only the DEFAULT assembler
|
|
28
|
+
* profile (the unnamed/undefined profile key) is used for numbering. A
|
|
29
|
+
* component-version with multiple assembler profiles producing multiple
|
|
30
|
+
* PDFs with genuinely different nav overrides per profile is not
|
|
31
|
+
* disambiguated: the `loader-assembler` discriminator this module (and the
|
|
32
|
+
* live macro) relies on does not itself carry which profile is being
|
|
33
|
+
* assembled. Documented, not silently mishandled: a component using more
|
|
34
|
+
* than the default profile should be verified manually before relying on
|
|
35
|
+
* cite-it's PDF numbering.
|
|
36
|
+
*/
|
|
37
|
+
interface NavigationEntry {
|
|
38
|
+
urlType?: string;
|
|
39
|
+
url?: string;
|
|
40
|
+
hash?: string;
|
|
41
|
+
unresolved?: boolean;
|
|
42
|
+
items?: NavigationEntry[];
|
|
43
|
+
}
|
|
44
|
+
interface VirtualFileSrc {
|
|
45
|
+
path?: string;
|
|
46
|
+
family?: string;
|
|
47
|
+
component?: string;
|
|
48
|
+
version?: string;
|
|
49
|
+
module?: string;
|
|
50
|
+
relative?: string;
|
|
51
|
+
contents?: Buffer | Uint8Array | string;
|
|
52
|
+
}
|
|
53
|
+
interface VirtualFile {
|
|
54
|
+
src: VirtualFileSrc;
|
|
55
|
+
contents: Buffer | Uint8Array;
|
|
56
|
+
path?: string;
|
|
57
|
+
pub?: {
|
|
58
|
+
url?: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
interface ContentCatalog {
|
|
62
|
+
getFiles: () => VirtualFile[];
|
|
63
|
+
resolveResource?: (spec: string, context?: Record<string, unknown>, defaultFamily?: string, permittedFamilies?: string[]) => VirtualFile | undefined;
|
|
64
|
+
getByPath?: (criteria: {
|
|
65
|
+
component?: string;
|
|
66
|
+
version?: string;
|
|
67
|
+
path: string;
|
|
68
|
+
}) => VirtualFile | undefined;
|
|
69
|
+
}
|
|
70
|
+
export interface ScanContext {
|
|
71
|
+
contentCatalog: ContentCatalog;
|
|
72
|
+
component: string;
|
|
73
|
+
version: string;
|
|
74
|
+
componentAttrs: Record<string, unknown>;
|
|
75
|
+
module: string;
|
|
76
|
+
/**
|
|
77
|
+
* One generated partial per category is the key design feature this
|
|
78
|
+
* carries. Different categories may be included on genuinely different
|
|
79
|
+
* pages, since a component author decides where by choosing which page
|
|
80
|
+
* includes which category's own partial. Citations correctly cross-link
|
|
81
|
+
* to whichever page actually hosts the cited entry, not just a single
|
|
82
|
+
* hardcoded bibliography page. Needed both to rewrite each partial's own
|
|
83
|
+
* citeit:[key] row labels for assembled output (rewritePartialForAssembly)
|
|
84
|
+
* and to resolve each key's own host page (findBibliographyScopes).
|
|
85
|
+
*/
|
|
86
|
+
categoryPartials: Array<{
|
|
87
|
+
section: string;
|
|
88
|
+
relative: string;
|
|
89
|
+
}>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* True first-appearance citation numbers for one component-version's
|
|
93
|
+
* assembled output: walks its pages in real assembly order, scans each in
|
|
94
|
+
* turn (comments/unset-conditionals stripped first, includes resolved,
|
|
95
|
+
* mirroring index.ts's own per-page scan exactly) for citeit:[key]
|
|
96
|
+
* occurrences in encounter order, and assigns each distinct key the next
|
|
97
|
+
* number on its first appearance across the whole ordered sequence.
|
|
98
|
+
*/
|
|
99
|
+
export declare function computeCitationNumbers(navigation: NavigationEntry[] | undefined, ctx: ScanContext): Map<string, number>;
|
|
100
|
+
/**
|
|
101
|
+
* The docname of each category's own host page, one lookup per category
|
|
102
|
+
* partial in `ctx.categoryPartials`, since different categories may
|
|
103
|
+
* genuinely live on different pages, the whole point of splitting
|
|
104
|
+
* generation per category at all. A category whose partial is not included
|
|
105
|
+
* anywhere simply does not appear in the returned map; callers already
|
|
106
|
+
* treat a missing scope as "render this citation unlinked"
|
|
107
|
+
* (rewriteCiteMarkers).
|
|
108
|
+
*
|
|
109
|
+
* The docname each key resolves to is the SCOPE PREFIX `@antora/
|
|
110
|
+
* assembler`'s own id-uniquing rewriter assigns to every anchor defined on
|
|
111
|
+
* that page, needed to build a cross-page xref target that actually
|
|
112
|
+
* resolves. See `rewriteCiteMarkers`'s own docblock for the full reasoning
|
|
113
|
+
* behind why a page-qualified xref, not a bare local id, is required here.
|
|
114
|
+
*/
|
|
115
|
+
export declare function findBibliographyScopes(navigation: NavigationEntry[] | undefined, ctx: ScanContext): Map<string, string>;
|
|
116
|
+
/**
|
|
117
|
+
* `asLink: true` (the default, used for citing pages' own body text)
|
|
118
|
+
* rewrites a citation to a real, clickable `xref:<scope>.adoc#cite-<key>[[N\]]`
|
|
119
|
+
* pointing at the bibliography entry's own anchor, producing a genuine
|
|
120
|
+
* internal PDF link rather than literal bracket text. `asLink: false` (used
|
|
121
|
+
* for the bibliography list's own row labels, which already carry that same
|
|
122
|
+
* anchor immediately to their left, see `generateCategoryPartial` in
|
|
123
|
+
* index.ts) rewrites to a plain `[N]` instead: a bibliography entry linking
|
|
124
|
+
* to itself would be pointless.
|
|
125
|
+
*
|
|
126
|
+
* The inner `]` must be escaped (`\]`) inside the xref's own attribute
|
|
127
|
+
* list: `xref:target[[N]]` looks correct but Asciidoctor's attrlist parser
|
|
128
|
+
* closes on the first unescaped `]` it finds, so the link text becomes `[N`
|
|
129
|
+
* and the trailing `]` ends up stray, unlinked, literal text right after
|
|
130
|
+
* it.
|
|
131
|
+
*
|
|
132
|
+
* `scopes`: a `Map<key, docname>` (from `findBibliographyScopes`), one
|
|
133
|
+
* entry per citation key, giving each key's own bibliography host page,
|
|
134
|
+
* not a single global scope, since different categories may genuinely live
|
|
135
|
+
* on different pages (the whole point of splitting generation per
|
|
136
|
+
* category; see `ScanContext.categoryPartials`). A citation's target names
|
|
137
|
+
* its host page explicitly (`xref:<scopes.get(key)>.adoc#cite-<key>[...]`),
|
|
138
|
+
* an ordinary, Antora-native cross-page reference, rather than a bare
|
|
139
|
+
* `xref:cite-<key>[...]`. Two other forms were tried and rejected, verified
|
|
140
|
+
* against a real multi-page assembled PDF's internal link data (`ruby
|
|
141
|
+
* -rpdf-reader`, dumping both `Annots`/`Dest` and the document's own
|
|
142
|
+
* `Names/Dests` tree):
|
|
143
|
+
*
|
|
144
|
+
* 1. A bare `xref:cite-<key>[]`: broken. `@antora/assembler` rewrites
|
|
145
|
+
* every page's own ids/xrefs sequentially as it stitches
|
|
146
|
+
* (`produce-assembly-file.js`'s `rewriteXrefs`), prefixing each with
|
|
147
|
+
* its own page's docname for uniqueness. A citation on an earlier
|
|
148
|
+
* page (the normal case, since a bibliography conventionally comes
|
|
149
|
+
* last) cites forward to a page the rewriter has not reached yet, so
|
|
150
|
+
* it cannot know the real scope and defaults to prefixing with the
|
|
151
|
+
* citing page's own scope instead. A citation on "page-two" produced
|
|
152
|
+
* a link to `page-two:::cite-lee2021`, which does not exist; the real
|
|
153
|
+
* destination is `references:::cite-lee2021` (the anchor's own host
|
|
154
|
+
* page).
|
|
155
|
+
* 2. A pre-scoped `xref:<scope>:::cite-<key>[]` (manually prepending the
|
|
156
|
+
* correct prefix): also broken, and worse. The rewriter does not
|
|
157
|
+
* recognize an already-scoped target as special, so it double-
|
|
158
|
+
* prefixes it with the citing page's own scope on top, producing
|
|
159
|
+
* `index:::references:::cite-smith2020`.
|
|
160
|
+
* 3. `xref:<scope>.adoc#cite-<key>[]` (this one, working): an ordinary
|
|
161
|
+
* inter-page Antora xref, explicitly naming its own target page,
|
|
162
|
+
* exactly how an author would write a real cross-page reference in
|
|
163
|
+
* normal, non-assembled content. Produces a real PDF `GoTo` action
|
|
164
|
+
* with `Dest="references:::cite-smith2020"`, matching the real named
|
|
165
|
+
* destination exactly.
|
|
166
|
+
*
|
|
167
|
+
* Falls back to a plain, unlinked `[N]` when a key has no entry in
|
|
168
|
+
* `scopes`: its category's host page was not found. This should not
|
|
169
|
+
* normally happen for a properly configured component, but a
|
|
170
|
+
* known-correct number with no link is a safer failure than a link known
|
|
171
|
+
* to point nowhere.
|
|
172
|
+
*/
|
|
173
|
+
export declare function rewriteCiteMarkers(text: string, numbers: Map<string, number>, asLink?: boolean, scopes?: Map<string, string> | null): string;
|
|
174
|
+
export declare function reorderBibliographyRows(text: string, numbers: Map<string, number>): string;
|
|
175
|
+
/**
|
|
176
|
+
* Rewrites the generated bibliography partial's OWN `citeit:[key]` row
|
|
177
|
+
* labels to their final `[N]` numbers, mutating the file directly in the
|
|
178
|
+
* content catalog.
|
|
179
|
+
*
|
|
180
|
+
* Needed for a reason distinct from rewriteCiteMarkers' normal call site:
|
|
181
|
+
* Antora's own include processor resolves an `include::partial$...[]`
|
|
182
|
+
* directive by reading the target file's content directly from the
|
|
183
|
+
* catalog, without recursing back through `loadAsciiDoc` for the included
|
|
184
|
+
* content. That means the loadAsciiDoc wrapper (index.ts), which only sees
|
|
185
|
+
* each page's own raw text before it is parsed, never gets a chance to
|
|
186
|
+
* rewrite text that arrives via an include inside that parse; a citing
|
|
187
|
+
* page's own `citeit:[key]` usage rewrites correctly, but the generated
|
|
188
|
+
* partial's own row labels, pulled in during the same parse, would
|
|
189
|
+
* otherwise reach Ruby unrewritten. Called once per component-version,
|
|
190
|
+
* before any assembly-time loadAsciiDoc call can run (synchronous within
|
|
191
|
+
* the same navigationBuilt handler that computes `numbers`), so the
|
|
192
|
+
* partial is already correct by the time anything tries to include it.
|
|
193
|
+
*
|
|
194
|
+
* Also reorders the partial's rows into ascending citation-number order
|
|
195
|
+
* (reorderBibliographyRows) before rewriting labels: the order the partial
|
|
196
|
+
* was generated in has no relationship to citation number (Node does not
|
|
197
|
+
* know numbers yet at generation time), and a numbered bibliography listed
|
|
198
|
+
* out of number order reads as broken to anyone looking at it.
|
|
199
|
+
*/
|
|
200
|
+
export declare function rewritePartialForAssembly(ctx: ScanContext, numbers: Map<string, number>): void;
|
|
201
|
+
export {};
|
|
202
|
+
//# sourceMappingURL=assembly-numbering.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assembly-numbering.d.ts","sourceRoot":"","sources":["../../../src/extensions/cite-it/assembly-numbering.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* cite-it: true first-appearance numbering for Antora Assembler-flattened
|
|
4
|
+
* (PDF) output.
|
|
5
|
+
*
|
|
6
|
+
* `@antora/pdf-extension` shells the stitched document out to the real Ruby
|
|
7
|
+
* `asciidoctor-pdf` CLI as a subprocess. Ruby never loads this package's JS
|
|
8
|
+
* `citeit:[key]` macro (asciidoc.ts), so a live-macro-only design silently
|
|
9
|
+
* fails for PDF output: the macro simply never runs. The fix needs no Ruby
|
|
10
|
+
* code at all: `@antora/assembler`'s own `produceAssemblyFile` builds the
|
|
11
|
+
* stitched document from `doc.getSourceLines()` on a Document `loadAsciiDoc`
|
|
12
|
+
* (Asciidoctor.js) just parsed, so whatever text is fed into `loadAsciiDoc`
|
|
13
|
+
* is exactly what ends up in Ruby's stdin. This module rewrites
|
|
14
|
+
* `citeit:[key]` to its final number in the page's own text before calling
|
|
15
|
+
* the real `loadAsciiDoc`, using Antora's own `replaceFunctions` extension-
|
|
16
|
+
* cooperation point (`@antora/site-generator`'s `GeneratorContext`).
|
|
17
|
+
*
|
|
18
|
+
* True first-appearance order across an assembled multi-page document is
|
|
19
|
+
* only knowable from the same page order `@antora/assembler` itself
|
|
20
|
+
* assembles in, so this module computes that order independently in Node,
|
|
21
|
+
* from the SAME navigation source assembler resolves to. This accounts for
|
|
22
|
+
* a custom assembler-profile `nav:` override, via the shared
|
|
23
|
+
* `assemblerProfiles` variable `@antora/assembler`'s own `configure.js`
|
|
24
|
+
* computes and publishes at `componentsRegistered`, well before
|
|
25
|
+
* `navigationBuilt`, rather than assuming the component-version's default
|
|
26
|
+
* navigation always applies.
|
|
27
|
+
*
|
|
28
|
+
* Scope limitation, deliberate for this version: only the DEFAULT assembler
|
|
29
|
+
* profile (the unnamed/undefined profile key) is used for numbering. A
|
|
30
|
+
* component-version with multiple assembler profiles producing multiple
|
|
31
|
+
* PDFs with genuinely different nav overrides per profile is not
|
|
32
|
+
* disambiguated: the `loader-assembler` discriminator this module (and the
|
|
33
|
+
* live macro) relies on does not itself carry which profile is being
|
|
34
|
+
* assembled. Documented, not silently mishandled: a component using more
|
|
35
|
+
* than the default profile should be verified manually before relying on
|
|
36
|
+
* cite-it's PDF numbering.
|
|
37
|
+
*/
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.computeCitationNumbers = computeCitationNumbers;
|
|
40
|
+
exports.findBibliographyScopes = findBibliographyScopes;
|
|
41
|
+
exports.rewriteCiteMarkers = rewriteCiteMarkers;
|
|
42
|
+
exports.reorderBibliographyRows = reorderBibliographyRows;
|
|
43
|
+
exports.rewritePartialForAssembly = rewritePartialForAssembly;
|
|
44
|
+
const macro_1 = require("./macro");
|
|
45
|
+
const index_1 = require("../trademark-it/index");
|
|
46
|
+
const index_2 = require("../autoterm/index");
|
|
47
|
+
const asciidoc_conditionals_1 = require("../../lib/asciidoc-conditionals");
|
|
48
|
+
const asciidoc_indexterms_1 = require("../../lib/asciidoc-indexterms");
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Navigation walk: which pages, in what order, does the assembled output
|
|
51
|
+
// stitch together. Mirrors @antora/assembler's own selectPagesInOutline
|
|
52
|
+
// (produce-assembly-file.js), a straightforward depth-first pre-order
|
|
53
|
+
// walk of the navigation tree, visiting each internal-URL entry before its
|
|
54
|
+
// children, deduplicating by pathname (an entry the tree references more
|
|
55
|
+
// than once, for example a shared "next steps" page linked from two spots,
|
|
56
|
+
// contributes only at its first position, matching what the real assembler
|
|
57
|
+
// itself stitches).
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
function walkNavigationForPathnames(entries, seen, out) {
|
|
60
|
+
for (const entry of entries ?? []) {
|
|
61
|
+
if (entry.urlType === 'internal' && !entry.unresolved && entry.url) {
|
|
62
|
+
const pathname = entry.hash ? entry.url.substring(0, entry.url.length - entry.hash.length) : entry.url;
|
|
63
|
+
if (!seen.has(pathname)) {
|
|
64
|
+
seen.add(pathname);
|
|
65
|
+
out.push(pathname);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
walkNavigationForPathnames(entry.items, seen, out);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The ordered list of page VirtualFiles the assembled output for
|
|
73
|
+
* `component`@`version` stitches together, resolved from `navigation`:
|
|
74
|
+
* either the component-version's default navigation, or a profile's
|
|
75
|
+
* alternate navigation, the caller decides which.
|
|
76
|
+
*/
|
|
77
|
+
function pagesInNavigationOrder(navigation, files) {
|
|
78
|
+
const pathnames = [];
|
|
79
|
+
walkNavigationForPathnames(navigation, new Set(), pathnames);
|
|
80
|
+
const pagesByUrl = new Map();
|
|
81
|
+
for (const f of files) {
|
|
82
|
+
if (f.src.family === 'page' && f.pub?.url)
|
|
83
|
+
pagesByUrl.set(f.pub.url, f);
|
|
84
|
+
}
|
|
85
|
+
const result = [];
|
|
86
|
+
for (const pathname of pathnames) {
|
|
87
|
+
const page = pagesByUrl.get(pathname);
|
|
88
|
+
if (page)
|
|
89
|
+
result.push(page);
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* True first-appearance citation numbers for one component-version's
|
|
95
|
+
* assembled output: walks its pages in real assembly order, scans each in
|
|
96
|
+
* turn (comments/unset-conditionals stripped first, includes resolved,
|
|
97
|
+
* mirroring index.ts's own per-page scan exactly) for citeit:[key]
|
|
98
|
+
* occurrences in encounter order, and assigns each distinct key the next
|
|
99
|
+
* number on its first appearance across the whole ordered sequence.
|
|
100
|
+
*/
|
|
101
|
+
function computeCitationNumbers(navigation, ctx) {
|
|
102
|
+
const numbers = new Map();
|
|
103
|
+
const files = ctx.contentCatalog.getFiles().filter((f) => f.src.component === ctx.component && f.src.version === ctx.version);
|
|
104
|
+
const pages = pagesInNavigationOrder(navigation, files);
|
|
105
|
+
// Pre-populated with the keys of files this loop is ALSO about to scan
|
|
106
|
+
// directly (pages, not every page-or-partial in the component-version):
|
|
107
|
+
// collectIncludeText checks visited.has(key) before ever reading a
|
|
108
|
+
// target's content, so a key present for any reason suppresses that
|
|
109
|
+
// include outright, not merely dedups it. trademark-it/index.ts's own
|
|
110
|
+
// scan loop pre-populates from scanFiles, the exact set it also scans
|
|
111
|
+
// directly, so pre-marking those visited only avoids double-counting.
|
|
112
|
+
// This loop only scans `pages` directly; partials are never scanned on
|
|
113
|
+
// their own here, only ever reached via include. Pre-populating from
|
|
114
|
+
// `files` (every page or partial) used to mark partials visited before
|
|
115
|
+
// any page's include was ever resolved, silently and permanently
|
|
116
|
+
// excluding their content, and any citeit:[key] inside it, from the
|
|
117
|
+
// scan on first encounter rather than deduping a real prior resolution.
|
|
118
|
+
const includeVisited = new Set();
|
|
119
|
+
for (const page of pages) {
|
|
120
|
+
includeVisited.add(`${page.src.component}@${page.src.version}:${page.src.module}:${page.src.family}$${page.src.relative}`);
|
|
121
|
+
}
|
|
122
|
+
for (const page of pages) {
|
|
123
|
+
// page.contents holds the CONVERTED HTML by navigationBuilt time:
|
|
124
|
+
// documentsConverted, which overwrites it, runs earlier in Antora's
|
|
125
|
+
// real lifecycle. @antora/assembler's own produce-assembly-file.js reads
|
|
126
|
+
// page.src.contents specifically for this reason: the raw source
|
|
127
|
+
// @antora/assembler's own enableKeepSource mechanism preserves there.
|
|
128
|
+
// This scan needs the same raw AsciiDoc source, not the rendered HTML.
|
|
129
|
+
const rawSource = page.src.contents ?? page.contents;
|
|
130
|
+
const raw = rawSource.toString('utf8');
|
|
131
|
+
const headerAttrs = (0, asciidoc_conditionals_1.pageHeaderAttributes)(raw);
|
|
132
|
+
const isDefined = (attr) => {
|
|
133
|
+
if (headerAttrs.has(attr))
|
|
134
|
+
return headerAttrs.get(attr) === true;
|
|
135
|
+
const v = ctx.componentAttrs[attr];
|
|
136
|
+
return v !== undefined && v !== null && v !== false;
|
|
137
|
+
};
|
|
138
|
+
let text = (0, index_1.stripNonContent)(raw, isDefined, []);
|
|
139
|
+
const extra = (0, index_1.collectIncludeText)(text, ctx.contentCatalog, ctx.component, ctx.version, page.src.module ?? 'ROOT', includeVisited, [], undefined, [], page.src.path ?? '');
|
|
140
|
+
if (extra)
|
|
141
|
+
text = `${text}\n${(0, index_1.stripNonContent)(extra, isDefined, [])}`;
|
|
142
|
+
// The concatenation above is not always one well-formed document: a
|
|
143
|
+
// page and its resolved include target each carrying their own
|
|
144
|
+
// `=`-level-0 title makes the combined text an invalid multi-document
|
|
145
|
+
// concatenation ("level 0 sections can only be used when doctype is
|
|
146
|
+
// book", confirmed live) before it ever reaches scanCiteKeysOrdered's
|
|
147
|
+
// own real processor.convert() call. asciidoc-indexterms.ts's scanner
|
|
148
|
+
// hit the exact same hazard first; reusing its sanitizeForScan here
|
|
149
|
+
// rather than a second, independently-maintained copy of the same fix.
|
|
150
|
+
const orderedKeys = (0, macro_1.scanCiteKeysOrdered)((0, asciidoc_indexterms_1.sanitizeForScan)(text));
|
|
151
|
+
for (const key of orderedKeys) {
|
|
152
|
+
if (!numbers.has(key))
|
|
153
|
+
numbers.set(key, numbers.size + 1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return numbers;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* The docname of each category's own host page, one lookup per category
|
|
160
|
+
* partial in `ctx.categoryPartials`, since different categories may
|
|
161
|
+
* genuinely live on different pages, the whole point of splitting
|
|
162
|
+
* generation per category at all. A category whose partial is not included
|
|
163
|
+
* anywhere simply does not appear in the returned map; callers already
|
|
164
|
+
* treat a missing scope as "render this citation unlinked"
|
|
165
|
+
* (rewriteCiteMarkers).
|
|
166
|
+
*
|
|
167
|
+
* The docname each key resolves to is the SCOPE PREFIX `@antora/
|
|
168
|
+
* assembler`'s own id-uniquing rewriter assigns to every anchor defined on
|
|
169
|
+
* that page, needed to build a cross-page xref target that actually
|
|
170
|
+
* resolves. See `rewriteCiteMarkers`'s own docblock for the full reasoning
|
|
171
|
+
* behind why a page-qualified xref, not a bare local id, is required here.
|
|
172
|
+
*/
|
|
173
|
+
function findBibliographyScopes(navigation, ctx) {
|
|
174
|
+
const scopes = new Map();
|
|
175
|
+
const files = ctx.contentCatalog.getFiles().filter((f) => f.src.component === ctx.component && f.src.version === ctx.version);
|
|
176
|
+
const pages = pagesInNavigationOrder(navigation, files);
|
|
177
|
+
const remaining = new Map(ctx.categoryPartials.map((cp) => [cp.relative, cp.section]));
|
|
178
|
+
for (const page of pages) {
|
|
179
|
+
if (remaining.size === 0)
|
|
180
|
+
break;
|
|
181
|
+
const raw = (page.src.contents ?? page.contents).toString('utf8');
|
|
182
|
+
for (const [relative, section] of [...remaining]) {
|
|
183
|
+
if ((0, index_2.includesPartial)(raw, relative)) {
|
|
184
|
+
scopes.set(section, (page.src.relative ?? '').replace(/\.[^./]+$/, ''));
|
|
185
|
+
remaining.delete(relative);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return scopes;
|
|
190
|
+
}
|
|
191
|
+
// ---------------------------------------------------------------------------
|
|
192
|
+
// Text rewrite: replace citeit:[key] with its final [N] number, applied
|
|
193
|
+
// only to assembly-time page loads (loader-assembler present), before the
|
|
194
|
+
// real loadAsciiDoc parses the page. NOT a blind regex substitution: skips
|
|
195
|
+
// occurrences inside // and //// comments (mirrors trademark-it's own
|
|
196
|
+
// stripComments logic) and occurrences wrapped in a monospace span
|
|
197
|
+
// (`citeit:[key]` or `+citeit:[key]+`), the two shapes documentation
|
|
198
|
+
// showing citeit:[key] as literal example syntax would realistically use.
|
|
199
|
+
// Deliberately narrower than a full Asciidoctor-parse-based substitution:
|
|
200
|
+
// the citeit:[key] syntax is simple and fixed enough that this scoped guard
|
|
201
|
+
// covers the realistic false-positive shapes without the cost of a second
|
|
202
|
+
// real parse on every assembly-time page load.
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
const CITE_MARKER_RE = /citeit:\[([a-zA-Z0-9][\w.:/-]*)\]/g;
|
|
205
|
+
/**
|
|
206
|
+
* `asLink: true` (the default, used for citing pages' own body text)
|
|
207
|
+
* rewrites a citation to a real, clickable `xref:<scope>.adoc#cite-<key>[[N\]]`
|
|
208
|
+
* pointing at the bibliography entry's own anchor, producing a genuine
|
|
209
|
+
* internal PDF link rather than literal bracket text. `asLink: false` (used
|
|
210
|
+
* for the bibliography list's own row labels, which already carry that same
|
|
211
|
+
* anchor immediately to their left, see `generateCategoryPartial` in
|
|
212
|
+
* index.ts) rewrites to a plain `[N]` instead: a bibliography entry linking
|
|
213
|
+
* to itself would be pointless.
|
|
214
|
+
*
|
|
215
|
+
* The inner `]` must be escaped (`\]`) inside the xref's own attribute
|
|
216
|
+
* list: `xref:target[[N]]` looks correct but Asciidoctor's attrlist parser
|
|
217
|
+
* closes on the first unescaped `]` it finds, so the link text becomes `[N`
|
|
218
|
+
* and the trailing `]` ends up stray, unlinked, literal text right after
|
|
219
|
+
* it.
|
|
220
|
+
*
|
|
221
|
+
* `scopes`: a `Map<key, docname>` (from `findBibliographyScopes`), one
|
|
222
|
+
* entry per citation key, giving each key's own bibliography host page,
|
|
223
|
+
* not a single global scope, since different categories may genuinely live
|
|
224
|
+
* on different pages (the whole point of splitting generation per
|
|
225
|
+
* category; see `ScanContext.categoryPartials`). A citation's target names
|
|
226
|
+
* its host page explicitly (`xref:<scopes.get(key)>.adoc#cite-<key>[...]`),
|
|
227
|
+
* an ordinary, Antora-native cross-page reference, rather than a bare
|
|
228
|
+
* `xref:cite-<key>[...]`. Two other forms were tried and rejected, verified
|
|
229
|
+
* against a real multi-page assembled PDF's internal link data (`ruby
|
|
230
|
+
* -rpdf-reader`, dumping both `Annots`/`Dest` and the document's own
|
|
231
|
+
* `Names/Dests` tree):
|
|
232
|
+
*
|
|
233
|
+
* 1. A bare `xref:cite-<key>[]`: broken. `@antora/assembler` rewrites
|
|
234
|
+
* every page's own ids/xrefs sequentially as it stitches
|
|
235
|
+
* (`produce-assembly-file.js`'s `rewriteXrefs`), prefixing each with
|
|
236
|
+
* its own page's docname for uniqueness. A citation on an earlier
|
|
237
|
+
* page (the normal case, since a bibliography conventionally comes
|
|
238
|
+
* last) cites forward to a page the rewriter has not reached yet, so
|
|
239
|
+
* it cannot know the real scope and defaults to prefixing with the
|
|
240
|
+
* citing page's own scope instead. A citation on "page-two" produced
|
|
241
|
+
* a link to `page-two:::cite-lee2021`, which does not exist; the real
|
|
242
|
+
* destination is `references:::cite-lee2021` (the anchor's own host
|
|
243
|
+
* page).
|
|
244
|
+
* 2. A pre-scoped `xref:<scope>:::cite-<key>[]` (manually prepending the
|
|
245
|
+
* correct prefix): also broken, and worse. The rewriter does not
|
|
246
|
+
* recognize an already-scoped target as special, so it double-
|
|
247
|
+
* prefixes it with the citing page's own scope on top, producing
|
|
248
|
+
* `index:::references:::cite-smith2020`.
|
|
249
|
+
* 3. `xref:<scope>.adoc#cite-<key>[]` (this one, working): an ordinary
|
|
250
|
+
* inter-page Antora xref, explicitly naming its own target page,
|
|
251
|
+
* exactly how an author would write a real cross-page reference in
|
|
252
|
+
* normal, non-assembled content. Produces a real PDF `GoTo` action
|
|
253
|
+
* with `Dest="references:::cite-smith2020"`, matching the real named
|
|
254
|
+
* destination exactly.
|
|
255
|
+
*
|
|
256
|
+
* Falls back to a plain, unlinked `[N]` when a key has no entry in
|
|
257
|
+
* `scopes`: its category's host page was not found. This should not
|
|
258
|
+
* normally happen for a properly configured component, but a
|
|
259
|
+
* known-correct number with no link is a safer failure than a link known
|
|
260
|
+
* to point nowhere.
|
|
261
|
+
*/
|
|
262
|
+
function rewriteCiteMarkers(text, numbers, asLink = true, scopes = null) {
|
|
263
|
+
const lines = text.split('\n');
|
|
264
|
+
let inBlockComment = false;
|
|
265
|
+
return lines
|
|
266
|
+
.map((line) => {
|
|
267
|
+
const trimmed = line.trimStart();
|
|
268
|
+
if (trimmed.startsWith('////')) {
|
|
269
|
+
inBlockComment = !inBlockComment;
|
|
270
|
+
return line;
|
|
271
|
+
}
|
|
272
|
+
if (inBlockComment || trimmed.startsWith('//'))
|
|
273
|
+
return line;
|
|
274
|
+
return line.replace(CITE_MARKER_RE, (match, key, offset) => {
|
|
275
|
+
const before = line.slice(Math.max(0, offset - 1), offset);
|
|
276
|
+
const after = line.slice(offset + match.length, offset + match.length + 1);
|
|
277
|
+
// Skip a citeit:[key] wrapped in a monospace span (`citeit:[key]`)
|
|
278
|
+
// or a passthrough (+citeit:[key]+): both are how documentation
|
|
279
|
+
// shows the macro as literal example syntax, not a real citation.
|
|
280
|
+
if ((before === '`' && after === '`') || (before === '+' && after === '+'))
|
|
281
|
+
return match;
|
|
282
|
+
const num = numbers.get(key);
|
|
283
|
+
if (num === undefined)
|
|
284
|
+
return match;
|
|
285
|
+
if (!asLink)
|
|
286
|
+
return `[${num}]`;
|
|
287
|
+
const scope = scopes?.get(key);
|
|
288
|
+
return scope ? `xref:${scope}.adoc#cite-${key}[[${num}\\]]` : `[${num}]`;
|
|
289
|
+
});
|
|
290
|
+
})
|
|
291
|
+
.join('\n');
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Reorders the generated bibliography partial's rows, within each
|
|
295
|
+
* `[horizontal]` block, into ascending citation-number order: the
|
|
296
|
+
* conventional reading order for a numbered bibliography, and NOT the
|
|
297
|
+
* order the partial was originally generated in. Node does not know
|
|
298
|
+
* citation numbers yet at that point; see `generateCategoryPartial` in
|
|
299
|
+
* index.ts. Only meaningful for assembled/PDF output, since that is the
|
|
300
|
+
* only context with numbers at all; called from the same place and at
|
|
301
|
+
* the same time as the row-label rewrite (rewritePartialForAssembly),
|
|
302
|
+
* after ordinary HTML conversion has already used the original order.
|
|
303
|
+
*
|
|
304
|
+
* A row is recognized by its leading `[[cite-<key>]]` anchor.
|
|
305
|
+
* `generateCategoryPartial` always emits one immediately before each row's
|
|
306
|
+
* label, so this matches on the anchor rather than the citeit:[key] token
|
|
307
|
+
* itself, meaning it still works whether called before or after
|
|
308
|
+
* rewriteCiteMarkers has already turned that token into its final `[N]`
|
|
309
|
+
* form. A row whose key never received a number, a ref_force entry
|
|
310
|
+
* genuinely never cited, sorts after every numbered row, in original
|
|
311
|
+
* order; this should not normally happen, since ref_force keys are
|
|
312
|
+
* always in the ordered-key list computeCitationNumbers assigns from, but
|
|
313
|
+
* is defended anyway.
|
|
314
|
+
*/
|
|
315
|
+
const ANCHOR_RE = /^\[\[cite-([\w.:/-]+)\]\]/;
|
|
316
|
+
function reorderBibliographyRows(text, numbers) {
|
|
317
|
+
const lines = text.split('\n');
|
|
318
|
+
const out = [];
|
|
319
|
+
let block = null;
|
|
320
|
+
const flush = () => {
|
|
321
|
+
if (!block)
|
|
322
|
+
return;
|
|
323
|
+
block
|
|
324
|
+
.slice()
|
|
325
|
+
.sort((a, b) => (numbers.get(a.key) ?? Infinity) - (numbers.get(b.key) ?? Infinity))
|
|
326
|
+
.forEach((row) => out.push(row.line));
|
|
327
|
+
block = null;
|
|
328
|
+
};
|
|
329
|
+
for (const line of lines) {
|
|
330
|
+
const m = line.match(ANCHOR_RE);
|
|
331
|
+
if (m) {
|
|
332
|
+
block ?? (block = []);
|
|
333
|
+
block.push({ key: m[1], line });
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
flush();
|
|
337
|
+
out.push(line);
|
|
338
|
+
}
|
|
339
|
+
flush();
|
|
340
|
+
return out.join('\n');
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Rewrites the generated bibliography partial's OWN `citeit:[key]` row
|
|
344
|
+
* labels to their final `[N]` numbers, mutating the file directly in the
|
|
345
|
+
* content catalog.
|
|
346
|
+
*
|
|
347
|
+
* Needed for a reason distinct from rewriteCiteMarkers' normal call site:
|
|
348
|
+
* Antora's own include processor resolves an `include::partial$...[]`
|
|
349
|
+
* directive by reading the target file's content directly from the
|
|
350
|
+
* catalog, without recursing back through `loadAsciiDoc` for the included
|
|
351
|
+
* content. That means the loadAsciiDoc wrapper (index.ts), which only sees
|
|
352
|
+
* each page's own raw text before it is parsed, never gets a chance to
|
|
353
|
+
* rewrite text that arrives via an include inside that parse; a citing
|
|
354
|
+
* page's own `citeit:[key]` usage rewrites correctly, but the generated
|
|
355
|
+
* partial's own row labels, pulled in during the same parse, would
|
|
356
|
+
* otherwise reach Ruby unrewritten. Called once per component-version,
|
|
357
|
+
* before any assembly-time loadAsciiDoc call can run (synchronous within
|
|
358
|
+
* the same navigationBuilt handler that computes `numbers`), so the
|
|
359
|
+
* partial is already correct by the time anything tries to include it.
|
|
360
|
+
*
|
|
361
|
+
* Also reorders the partial's rows into ascending citation-number order
|
|
362
|
+
* (reorderBibliographyRows) before rewriting labels: the order the partial
|
|
363
|
+
* was generated in has no relationship to citation number (Node does not
|
|
364
|
+
* know numbers yet at generation time), and a numbered bibliography listed
|
|
365
|
+
* out of number order reads as broken to anyone looking at it.
|
|
366
|
+
*/
|
|
367
|
+
function rewritePartialForAssembly(ctx, numbers) {
|
|
368
|
+
if (numbers.size === 0)
|
|
369
|
+
return;
|
|
370
|
+
for (const cp of ctx.categoryPartials) {
|
|
371
|
+
const partial = ctx.contentCatalog.getFiles().find((f) => f.src.component === ctx.component &&
|
|
372
|
+
f.src.version === ctx.version &&
|
|
373
|
+
f.src.family === 'partial' &&
|
|
374
|
+
f.src.module === ctx.module &&
|
|
375
|
+
f.src.relative === cp.relative);
|
|
376
|
+
if (!partial)
|
|
377
|
+
continue;
|
|
378
|
+
const before = partial.contents.toString('utf8');
|
|
379
|
+
const reordered = reorderBibliographyRows(before, numbers);
|
|
380
|
+
const after = rewriteCiteMarkers(reordered, numbers, false);
|
|
381
|
+
if (after !== before)
|
|
382
|
+
partial.contents = Buffer.from(after, 'utf8');
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=assembly-numbering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assembly-numbering.js","sourceRoot":"","sources":["../../../src/extensions/cite-it/assembly-numbering.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cite-it: CSL bibliography-entry formatting.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `citeproc` to format CSL-JSON items into bibliography-entry text
|
|
5
|
+
* for the generated partial. citeproc's own citation-cluster numbering is
|
|
6
|
+
* not used: `processCitationCluster` needs the full running cluster
|
|
7
|
+
* history passed back on every call to number correctly, making it the
|
|
8
|
+
* wrong tool for `citeit:[key]`'s per-Document counter, which already
|
|
9
|
+
* solves numbering by walking the document in natural order (see
|
|
10
|
+
* assembly-numbering.ts and macro.ts's own render-mode numbering).
|
|
11
|
+
* citeproc here formats bibliography-entry text only; the entry's
|
|
12
|
+
* number/label comes from `citeit:[key]` itself, reused as the generated
|
|
13
|
+
* partial's row label (macro.ts), so the two numbering sources agree by
|
|
14
|
+
* construction rather than by cross-checking two independent counters.
|
|
15
|
+
*
|
|
16
|
+
* `STYLES` currently bundles one entry, `ieee-bracket`. This is a scope
|
|
17
|
+
* limit, not an architectural one: `loadEngine` takes any CSL style/locale
|
|
18
|
+
* pair placed under `resources/cite-it/` and registered in `STYLES` below,
|
|
19
|
+
* so adding a style is a matter of shipping its `.csl`/`.xml` files and one
|
|
20
|
+
* new `STYLES` entry, not a design change. A `style` value not present in
|
|
21
|
+
* `STYLES` is rejected with a clear error rather than silently falling
|
|
22
|
+
* back, since a silently wrong citation style is a worse failure than a
|
|
23
|
+
* build error naming the actual gap.
|
|
24
|
+
*/
|
|
25
|
+
import type { CslJsonItem } from './registry';
|
|
26
|
+
/**
|
|
27
|
+
* Convert one citeproc bibliography entry's raw HTML fragment into AsciiDoc
|
|
28
|
+
* inline text. citeproc's output shape is two sibling <div>s per entry:
|
|
29
|
+
* `csl-left-margin` (the [N] bracket, citeproc's own numbering, discarded
|
|
30
|
+
* here since citeit:[key] supplies the real number) and `csl-right-inline`
|
|
31
|
+
* (the formatted entry text, kept). Only `csl-right-inline`'s content is
|
|
32
|
+
* used.
|
|
33
|
+
*/
|
|
34
|
+
export declare function htmlEntryToAsciiDoc(entryHtml: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Format bibliography-entry text for a set of CSL-JSON items, keyed by
|
|
37
|
+
* citation key. `items` is the full merged registry (used for
|
|
38
|
+
* `retrieveItem` cross-references between entries, for example a
|
|
39
|
+
* `container-title` shared across a collection); `keys` selects and orders
|
|
40
|
+
* which items are actually formatted and returned: order does not need to
|
|
41
|
+
* match true citation order, since citeproc's own numbering is discarded
|
|
42
|
+
* (see the module docblock).
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatBibliographyEntries(styleName: string, items: Map<string, CslJsonItem>, keys: string[]): Map<string, string>;
|
|
45
|
+
//# sourceMappingURL=csl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csl.d.ts","sourceRoot":"","sources":["../../../src/extensions/cite-it/csl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA4C9C;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EAC/B,IAAI,EAAE,MAAM,EAAE,GACb,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAerB"}
|