@heroiclands/package-build 20.3.1 → 20.5.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 +351 -0
- package/CONTENT.md +322 -110
- package/README.md +21 -10
- package/bin/content-build.mjs +204 -92
- package/bin/package-build.mjs +48 -15
- package/config.mjs +6 -8
- package/content-config.mjs +518 -151
- package/docs/api.md +1352 -0
- package/docs/commands.md +1609 -0
- package/docs/configuration.md +1432 -0
- package/docs/content-format.md +73 -74
- package/docs/diagnostics.md +356 -0
- package/docs/getting-started.md +813 -0
- package/docs/project-setup.md +469 -0
- package/e2e.mjs +4 -4
- package/engine/actor-compiler.mjs +64 -61
- package/engine/address-charset.mjs +6 -6
- package/engine/address-diff.mjs +57 -52
- package/engine/anchored-sections.mjs +1 -1
- package/engine/anchors.mjs +1 -1
- package/engine/base-compiler.mjs +42 -38
- package/engine/bundle-notes.mjs +4 -4
- package/engine/bundles.mjs +17 -8
- package/engine/code-fences.mjs +3 -3
- package/engine/compendiums.mjs +8 -8
- package/engine/compile-corpus.mjs +4 -5
- package/engine/content-address.mjs +24 -24
- package/engine/content-charset.mjs +1 -1
- package/engine/content-format-check.mjs +24 -25
- package/engine/content-format.mjs +8 -8
- package/engine/content-html.mjs +202 -0
- package/engine/content-icons.mjs +196 -165
- package/engine/content-index.mjs +61 -40
- package/engine/content-links.mjs +74 -41
- package/engine/content-lint.mjs +64 -34
- package/engine/content-package.mjs +7 -9
- package/engine/content-slug.mjs +2 -2
- package/engine/content-tables.mjs +38 -34
- package/engine/content-tree.mjs +1 -1
- package/engine/derived-fields.mjs +174 -0
- package/engine/diagnostics.mjs +3 -4
- package/engine/document-subtypes.mjs +6 -7
- package/engine/field-reference.mjs +8 -8
- package/engine/field-spec.mjs +29 -30
- package/engine/folder-notes.mjs +18 -16
- package/engine/foreign-catalog.mjs +8 -9
- package/engine/foundry-entries.mjs +19 -20
- package/engine/frontmatter-lint.mjs +95 -103
- package/engine/frontmatter.mjs +11 -11
- package/engine/generate.mjs +44 -39
- package/engine/helpers.mjs +147 -84
- package/engine/homepage.mjs +20 -22
- package/engine/ids.mjs +15 -15
- package/engine/index-records.mjs +4 -4
- package/engine/index.mjs +26 -10
- package/engine/item-compiler.mjs +54 -29
- package/engine/item-docs.mjs +11 -13
- package/engine/item-registry.mjs +13 -13
- package/engine/journals.mjs +24 -15
- package/engine/macros.mjs +3 -3
- package/engine/map-notes.mjs +6 -6
- package/engine/metadata-index.mjs +5 -5
- package/engine/note-claims.mjs +51 -41
- package/engine/note-ids.mjs +5 -5
- package/engine/note-package.mjs +4 -4
- package/engine/note-renames.mjs +3 -3
- package/engine/note-schemas.mjs +3 -8
- package/engine/note-vocabulary.mjs +56 -54
- package/engine/pack-config.mjs +39 -25
- package/engine/pack-router.mjs +0 -0
- package/engine/pdf-build.mjs +464 -0
- package/engine/pdf-fonts.mjs +420 -0
- package/engine/pdf-render.mjs +798 -0
- package/engine/pdf-toc.mjs +525 -0
- package/engine/prose-config.mjs +9 -9
- package/engine/prose-lint.mjs +12 -13
- package/engine/region-events.mjs +2 -2
- package/engine/retired-fields.mjs +24 -22
- package/engine/runtime-only-fields.mjs +1 -1
- package/engine/scene-levels.mjs +1 -1
- package/engine/scenes.mjs +33 -25
- package/engine/schema-check.mjs +21 -21
- package/engine/schema-extract.mjs +1 -1
- package/engine/site-build.mjs +66 -50
- package/engine/site-index.mjs +17 -18
- package/engine/sql-tables.mjs +21 -13
- package/engine/subtype-registry.mjs +5 -4
- package/engine/system-block.mjs +18 -19
- package/engine/systems.mjs +2 -2
- package/engine/web-wikilinks.mjs +41 -38
- package/engine/wikilink-syntax.mjs +16 -16
- package/engine/wikilinks.mjs +40 -42
- package/hm3/actors.mjs +30 -22
- package/hm3/document-subtypes.mjs +5 -5
- package/hm3/index.mjs +2 -2
- package/hm3/item-builders.mjs +1 -1
- package/hm3/item-fields.mjs +3 -3
- package/hm3/items.mjs +28 -8
- package/hm3/template-priority.mjs +2 -2
- package/lang.mjs +3 -3
- package/manifest.mjs +17 -20
- package/package.json +1 -2
- package/release.mjs +66 -6
- package/sohl/actors.mjs +36 -28
- package/sohl/affiliation-standings.mjs +2 -2
- package/sohl/being-info.mjs +5 -5
- package/sohl/default-item-art.mjs +5 -5
- package/sohl/document-subtypes.mjs +5 -5
- package/sohl/index.mjs +3 -3
- package/sohl/item-builders.mjs +7 -7
- package/sohl/item-fields.mjs +8 -9
- package/sohl/items.mjs +28 -6
- package/sohl/kb-passes.mjs +5 -5
- package/sohl/note-schemas.mjs +12 -12
- package/sohl/skill-base.mjs +1 -1
- package/types/content-config.d.mts +91 -39
- package/types/e2e.d.mts +3 -3
- package/types/engine/actor-compiler.d.mts +45 -40
- package/types/engine/address-charset.d.mts +6 -6
- package/types/engine/address-diff.d.mts +60 -6
- package/types/engine/base-compiler.d.mts +27 -21
- package/types/engine/bundle-notes.d.mts +3 -3
- package/types/engine/bundles.d.mts +10 -1
- package/types/engine/code-fences.d.mts +3 -3
- package/types/engine/compendiums.d.mts +3 -3
- package/types/engine/compile-corpus.d.mts +1 -1
- package/types/engine/content-address.d.mts +20 -20
- package/types/engine/content-format-check.d.mts +6 -6
- package/types/engine/content-format.d.mts +2 -2
- package/types/engine/content-html.d.mts +78 -0
- package/types/engine/content-icons.d.mts +139 -92
- package/types/engine/content-index.d.mts +59 -15
- package/types/engine/content-links.d.mts +8 -8
- package/types/engine/content-lint.d.mts +8 -6
- package/types/engine/content-package.d.mts +6 -8
- package/types/engine/content-tables.d.mts +49 -18
- package/types/engine/derived-fields.d.mts +101 -0
- package/types/engine/diagnostics.d.mts +2 -2
- package/types/engine/document-subtypes.d.mts +3 -3
- package/types/engine/field-spec.d.mts +37 -39
- package/types/engine/folder-notes.d.mts +4 -5
- package/types/engine/foreign-catalog.d.mts +3 -3
- package/types/engine/foundry-entries.d.mts +6 -7
- package/types/engine/frontmatter-lint.d.mts +10 -9
- package/types/engine/frontmatter.d.mts +7 -7
- package/types/engine/generate.d.mts +7 -7
- package/types/engine/helpers.d.mts +128 -56
- package/types/engine/homepage.d.mts +16 -18
- package/types/engine/ids.d.mts +13 -13
- package/types/engine/index-records.d.mts +3 -3
- package/types/engine/index.d.mts +6 -0
- package/types/engine/item-compiler.d.mts +21 -5
- package/types/engine/item-docs.d.mts +2 -2
- package/types/engine/item-registry.d.mts +6 -6
- package/types/engine/journals.d.mts +12 -3
- package/types/engine/map-notes.d.mts +2 -2
- package/types/engine/metadata-index.d.mts +4 -4
- package/types/engine/note-claims.d.mts +30 -22
- package/types/engine/note-ids.d.mts +4 -4
- package/types/engine/note-package.d.mts +1 -1
- package/types/engine/note-renames.d.mts +3 -3
- package/types/engine/note-vocabulary.d.mts +31 -203
- package/types/engine/pack-config.d.mts +7 -7
- package/types/engine/pack-router.d.mts +1 -1
- package/types/engine/pdf-build.d.mts +42 -0
- package/types/engine/pdf-fonts.d.mts +30 -0
- package/types/engine/pdf-render.d.mts +144 -0
- package/types/engine/pdf-toc.d.mts +114 -0
- package/types/engine/prose-config.d.mts +9 -9
- package/types/engine/prose-lint.d.mts +3 -4
- package/types/engine/region-events.d.mts +2 -2
- package/types/engine/retired-fields.d.mts +10 -9
- package/types/engine/scenes.d.mts +10 -1
- package/types/engine/schema-check.d.mts +13 -13
- package/types/engine/site-build.d.mts +52 -25
- package/types/engine/site-index.d.mts +3 -4
- package/types/engine/sql-tables.d.mts +11 -5
- package/types/engine/subtype-registry.d.mts +3 -3
- package/types/engine/system-block.d.mts +3 -3
- package/types/engine/web-wikilinks.d.mts +7 -7
- package/types/engine/wikilink-syntax.d.mts +17 -17
- package/types/engine/wikilinks.d.mts +14 -14
- package/types/hm3/actors.d.mts +9 -1
- package/types/hm3/document-subtypes.d.mts +1 -1
- package/types/hm3/items.d.mts +9 -2
- package/types/hm3/template-priority.d.mts +1 -1
- package/types/manifest.d.mts +8 -8
- package/types/release.d.mts +15 -4
- package/types/sohl/actors.d.mts +12 -4
- package/types/sohl/affiliation-standings.d.mts +2 -2
- package/types/sohl/being-info.d.mts +2 -2
- package/types/sohl/document-subtypes.d.mts +1 -1
- package/types/sohl/items.d.mts +9 -2
- package/types/sohl/note-schemas.d.mts +1 -1
- package/MIGRATING.md +0 -608
|
@@ -34,7 +34,7 @@ export function deepMerge(base: any, overlay: any): any;
|
|
|
34
34
|
* vocabulary, so a reference is translated forward through the system's map
|
|
35
35
|
* before it reaches this function; see
|
|
36
36
|
* {@link SystemActorCompiler#embeddedSubtype} for why the translation goes that
|
|
37
|
-
* way and not the other
|
|
37
|
+
* way and not the other.
|
|
38
38
|
*
|
|
39
39
|
* @param {string} subType - The Foundry Item subtype.
|
|
40
40
|
* @param {string} shortcode - The item's `system.shortcode`.
|
|
@@ -43,7 +43,7 @@ export function deepMerge(base: any, overlay: any): any;
|
|
|
43
43
|
export function itemAddress(subType: string, shortcode: string): string;
|
|
44
44
|
/**
|
|
45
45
|
* The key one predefined item is held under **for the package that publishes
|
|
46
|
-
* it** — the address a `model:` naming that package resolves through
|
|
46
|
+
* it** — the address a `model:` naming that package resolves through.
|
|
47
47
|
*
|
|
48
48
|
* The unqualified {@link itemAddress} stays beside it, and the two answer
|
|
49
49
|
* different questions. A `model` that names no package means *this* one and
|
|
@@ -70,11 +70,12 @@ export function packagedItemAddress(pkg: string, subType: string, shortcode: str
|
|
|
70
70
|
* A shortcode is case-sensitive and routinely mixed — `Clb`, `LtShoe`,
|
|
71
71
|
* `HsTunic` — while an **address** is not: `readQualifier` normalises what it
|
|
72
72
|
* reads, and every canonical address is lowercase. So the moment a `model:` is
|
|
73
|
-
* read as an address
|
|
74
|
-
* `system.shortcode` is `Clb`, and an exact match cannot
|
|
73
|
+
* read as an address, `weapongear-clb` has to find the document whose
|
|
74
|
+
* `system.shortcode` is `Clb`, and an exact match cannot.
|
|
75
75
|
*
|
|
76
76
|
* Folding is safe because the fold is already the address: no two items in any
|
|
77
|
-
* published tree differ only by the case of their shortcode, and
|
|
77
|
+
* published tree differ only by the case of their shortcode, and the rule
|
|
78
|
+
* makes
|
|
78
79
|
* that impossible rather than merely true.
|
|
79
80
|
*
|
|
80
81
|
* **This is not {@link itemAddress}, and must not become it.** That one seeds
|
|
@@ -116,13 +117,13 @@ export function embeddedIdentity(item: object): string;
|
|
|
116
117
|
* four corpora holds 180 items, at which 64 bits collide with probability
|
|
117
118
|
* around 10⁻¹⁵.
|
|
118
119
|
*
|
|
119
|
-
* **It takes no index
|
|
120
|
+
* **It takes no index**. Keying on a position meant reordering a being's
|
|
120
121
|
* item list renumbered every id after the change, so a re-import created new
|
|
121
122
|
* documents beside the old ones — while nothing about those documents had
|
|
122
123
|
* changed, only their neighbours. The identity always exists or must be stated;
|
|
123
124
|
* see {@link embeddedIdentity}.
|
|
124
125
|
*
|
|
125
|
-
* Keyed by the **document subtype**, so renaming a note type
|
|
126
|
+
* Keyed by the **document subtype**, so renaming a note type leaves every
|
|
126
127
|
* embedded id where it was.
|
|
127
128
|
*
|
|
128
129
|
* @param {string} actorId - The owning actor's id.
|
|
@@ -186,7 +187,7 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
186
187
|
foreignSourceDirs: any;
|
|
187
188
|
/**
|
|
188
189
|
* Every package a `model:` may name besides this one — the dependencies
|
|
189
|
-
* whose item catalogues were supplied
|
|
190
|
+
* whose item catalogues were supplied.
|
|
190
191
|
*
|
|
191
192
|
* @returns {Set<string>} The dependency package ids.
|
|
192
193
|
*/
|
|
@@ -210,7 +211,7 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
210
211
|
* The Foundry Item subtype an embedded reference's `type` addresses.
|
|
211
212
|
*
|
|
212
213
|
* **The reference is in the note vocabulary; the address is in the
|
|
213
|
-
* document's
|
|
214
|
+
* document's**. An actor writes `(type, shortcode)` with the type an
|
|
214
215
|
* author authors, while {@link itemAddress} keys the predefined items by
|
|
215
216
|
* the subtype each compiled document carries — so exactly one of the two
|
|
216
217
|
* sides has to translate, and it is this one. The system's map is a
|
|
@@ -223,6 +224,31 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
223
224
|
* subtype, or why the reference names none.
|
|
224
225
|
*/
|
|
225
226
|
embeddedSubtype(type: string): import("./document-subtypes.mjs").ReferencedSubtype;
|
|
227
|
+
/**
|
|
228
|
+
* Read an entry's `model:` — the address of the item it is a copy of.
|
|
229
|
+
*
|
|
230
|
+
* The address grammar is the wikilink one, so a `model` is written at
|
|
231
|
+
* whatever length says what it means: `skill-wpnc` within this package,
|
|
232
|
+
* `sohl-sohl-skill-wpnc` to reach another. The system segment defaults from
|
|
233
|
+
* the block the entry sits in — `<system>.items` — which is what makes the
|
|
234
|
+
* short form name an *Item* here while the same string in body prose names
|
|
235
|
+
* a page.
|
|
236
|
+
*
|
|
237
|
+
* It replaced a top-level `shortcode:` that meant something different from
|
|
238
|
+
* the `system.shortcode` beside it and could not say which package a
|
|
239
|
+
* template came from.
|
|
240
|
+
*
|
|
241
|
+
* @param {unknown} model - The authored value.
|
|
242
|
+
* @param {number} index - The entry's position, for the message.
|
|
243
|
+
* @param {string} ctx - Diagnostic context (the actor's label).
|
|
244
|
+
* @returns {{type: string, shortcode: string, package: string|null}|null}
|
|
245
|
+
* The parsed address, or `null` after reporting why it is not one.
|
|
246
|
+
*/
|
|
247
|
+
readModel(model: unknown, index: number, ctx: string): {
|
|
248
|
+
type: string;
|
|
249
|
+
shortcode: string;
|
|
250
|
+
package: string | null;
|
|
251
|
+
} | null;
|
|
226
252
|
/**
|
|
227
253
|
* Resolve one embedded item from a `(type, shortcode?, overlay)`
|
|
228
254
|
* descriptor. If `shortcode` is given, the predefined item is fetched
|
|
@@ -230,7 +256,7 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
230
256
|
* descriptor must carry enough fields to stand alone. The embedded
|
|
231
257
|
* item's `_id` is regenerated deterministically from
|
|
232
258
|
* `(actorId, subType, shortcode, indexKey)` so re-exports are stable —
|
|
233
|
-
* from the **document subtype**, so that renaming a note type
|
|
259
|
+
* from the **document subtype**, so that renaming a note type leaves
|
|
234
260
|
* every embedded id exactly where it was.
|
|
235
261
|
* Returns null if the descriptor cannot be resolved.
|
|
236
262
|
*
|
|
@@ -239,45 +265,24 @@ export class SystemActorCompiler extends BasePackCompiler {
|
|
|
239
265
|
* @param {string} type - The **note** type the reference names.
|
|
240
266
|
* @param {string|null} shortcode - The referenced item's shortcode, or
|
|
241
267
|
* `null` for a stand-alone entry.
|
|
242
|
-
* @param {object}
|
|
268
|
+
* @param {object} overlay - The entry's remaining properties.
|
|
243
269
|
* @param {string} indexKey - Where the reference sits, for a diagnostic.
|
|
244
|
-
* It
|
|
270
|
+
* It names the entry in a message and does not reach the id.
|
|
245
271
|
* @param {string} ctx - Diagnostic context (the actor's label).
|
|
246
272
|
* @param {object} [at] - Where to locate a finding.
|
|
247
273
|
* @param {string} [at.fmKey] - The frontmatter key the reference sits
|
|
248
274
|
* under, so an unresolved one is reported at the reference rather than
|
|
249
275
|
* at the note.
|
|
276
|
+
* @param {string|null} [at.modelPackage] - The package a `model:` names,
|
|
277
|
+
* where the template comes from another package's catalogue. Given one,
|
|
278
|
+
* the packaged address is what resolves and nothing local shadows it.
|
|
250
279
|
* @returns {object|null} The embedded item, or null when it resolved to
|
|
251
280
|
* nothing — always with a finding emitted.
|
|
252
281
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
* whatever length says what it means: `skill-wpnc` within this package,
|
|
258
|
-
* `sohl-sohl-skill-wpnc` to reach another. The system segment defaults from
|
|
259
|
-
* the block the entry sits in — `<system>.items` — which is what makes the
|
|
260
|
-
* short form name an *Item* here while the same string in body prose names
|
|
261
|
-
* a page.
|
|
262
|
-
*
|
|
263
|
-
* It replaced a top-level `shortcode:` that meant something different from
|
|
264
|
-
* the `system.shortcode` beside it and could not say which package a
|
|
265
|
-
* template came from (#334).
|
|
266
|
-
*
|
|
267
|
-
* @param {unknown} model - The authored value.
|
|
268
|
-
* @param {number} index - The entry's position, for the message.
|
|
269
|
-
* @param {string} ctx - Diagnostic context (the actor's label).
|
|
270
|
-
* @returns {{type: string, shortcode: string, package: string|null}|null}
|
|
271
|
-
* The parsed address, or `null` after reporting why it is not one.
|
|
272
|
-
*/
|
|
273
|
-
readModel(model: unknown, index: number, ctx: string): {
|
|
274
|
-
type: string;
|
|
275
|
-
shortcode: string;
|
|
276
|
-
package: string | null;
|
|
277
|
-
} | null;
|
|
278
|
-
resolveEmbedded(itemsMap: any, actorId: any, type: any, shortcode: any, overlay: any, indexKey: any, ctx: any, { fmKey, modelPackage }?: {
|
|
279
|
-
modelPackage?: null | undefined;
|
|
280
|
-
}): any;
|
|
282
|
+
resolveEmbedded(itemsMap: Map<string, object>, actorId: string, type: string, shortcode: string | null, overlay: object, indexKey: string, ctx: string, { fmKey, modelPackage }?: {
|
|
283
|
+
fmKey?: string | undefined;
|
|
284
|
+
modelPackage?: string | null | undefined;
|
|
285
|
+
}): object | null;
|
|
281
286
|
#private;
|
|
282
287
|
}
|
|
283
288
|
import { BasePackCompiler } from "./base-compiler.mjs";
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export function isAddressSegment(value: unknown): boolean;
|
|
13
13
|
/**
|
|
14
|
-
* The one charset every segment of a canonical address is held to
|
|
14
|
+
* The one charset every segment of a canonical address is held to.
|
|
15
15
|
*
|
|
16
16
|
* An address is a hyphen-joined tuple — `package-system-type-shortcode`, so
|
|
17
17
|
* `sohl-none-doc-gear` — and it is read back by **counting segments**, with a
|
|
@@ -41,7 +41,7 @@ export function isAddressSegment(value: unknown): boolean;
|
|
|
41
41
|
* digits only.
|
|
42
42
|
*
|
|
43
43
|
* Case *was* deliberately unconstrained, on the reasoning that case has no
|
|
44
|
-
* bearing on the separator — which is true, and beside the point
|
|
44
|
+
* bearing on the separator — which is true, and beside the point.
|
|
45
45
|
*
|
|
46
46
|
* **Two names that differ only in case are two names nobody can tell apart.** A
|
|
47
47
|
* shortcode is how a person names a thing when writing a reference —
|
|
@@ -53,10 +53,10 @@ export function isAddressSegment(value: unknown): boolean;
|
|
|
53
53
|
* `sohl-sohl-weapongear-clb` and its `_id` derived from that. The authored name
|
|
54
54
|
* and its address disagreed, and everything downstream keys on the address —
|
|
55
55
|
* which left two notes differing only in case sharing one address, one `_id` and
|
|
56
|
-
* one URL, with nothing to report it. It also
|
|
57
|
-
*
|
|
58
|
-
* other segment, and
|
|
59
|
-
*
|
|
56
|
+
* one URL, with nothing to report it. It also forces two exceptions elsewhere:
|
|
57
|
+
* the shortcode has to be exempted from the lowercase rule pinned on every
|
|
58
|
+
* other segment, and its case has to be folded in the item catalogue because
|
|
59
|
+
* an address is lowercased when read.
|
|
60
60
|
*
|
|
61
61
|
* One case, one spelling, no exceptions. Every tree already complies but two,
|
|
62
62
|
* and nothing in any of them collides when folded.
|
|
@@ -39,9 +39,60 @@ export function readItemAddresses(dirs: readonly string[]): Map<string, {
|
|
|
39
39
|
shortcode: string;
|
|
40
40
|
file: string;
|
|
41
41
|
}>;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Every rename the tree's notes **declare**, as old address → where it went.
|
|
44
|
+
*
|
|
45
|
+
* Read from the content tree rather than from compiled output, because a
|
|
46
|
+
* declaration is authored and the compiled document does not carry it: nothing
|
|
47
|
+
* downstream consumes `renamedFrom:`, so emitting it into every pack to let one
|
|
48
|
+
* diagnostic read it back would put a build-time note in shipped data forever.
|
|
49
|
+
* The tree is already read by this module for the same reason
|
|
50
|
+
* ({@link noteFilesById}) — to place a finding where its author can fix it.
|
|
51
|
+
*
|
|
52
|
+
* **A declaration is keyed by document subtype, not by note type.** The address
|
|
53
|
+
* space is the one consumers resolve against, and it is spelled in compiled
|
|
54
|
+
* documents: `hm3` compiles a `projectile` note into a `missilegear` item,
|
|
55
|
+
* so that is the address a rename of it moves. {@link referencedSubtype} is the
|
|
56
|
+
* function that already answers this for a being's embedded `(type, shortcode)`
|
|
57
|
+
* references, so both sides read the same rule rather than a second copy of it.
|
|
58
|
+
*
|
|
59
|
+
* **An entry is emitted for every system that maps the type**, whether or not
|
|
60
|
+
* the note declares that system's block. Over-emitting is inert — the diff uses
|
|
61
|
+
* an entry only when the baseline published the old address *and* this build
|
|
62
|
+
* publishes the new one, and a system the note does not compile for satisfies
|
|
63
|
+
* neither — while asking which blocks a note declares would put a second,
|
|
64
|
+
* subtly different answer to that question in a third place.
|
|
65
|
+
*
|
|
66
|
+
* **First claim wins on a collision.** Two notes naming one predecessor is a
|
|
67
|
+
* contradiction — an address has one successor — and it is reported as an error
|
|
68
|
+
* by `engine/content-lint.mjs`, where both notes are in hand and can both be
|
|
69
|
+
* named. Picking one here keeps this a map; it is not a resolution, and nothing
|
|
70
|
+
* rests on which one it picked.
|
|
71
|
+
*
|
|
72
|
+
* @param {string} contentBase - Root of the content tree.
|
|
73
|
+
* @param {object} opts
|
|
74
|
+
* @param {readonly string[]} [opts.skipDirectories] - The corpus scope. Stated
|
|
75
|
+
* by the caller, never defaulted — see {@link addressCorpus}.
|
|
76
|
+
* @param {readonly object[]} [opts.maps] - The document-subtype maps.
|
|
77
|
+
* @param {object} [opts.config] - The resolved build configuration.
|
|
78
|
+
* @param {readonly object[]} [opts.records] - Index records the caller already
|
|
79
|
+
* derived, shared with {@link noteFilesById} so one command reads one corpus.
|
|
80
|
+
* @param {object[]} [opts.problems] - Collects the notes the index cannot
|
|
81
|
+
* record, so one of them does not abort the diff before it reports.
|
|
82
|
+
* @returns {Map<string, {to: string, file: string, shortcode: string}>} Old
|
|
83
|
+
* address → the address the declaring note publishes at now, and that note.
|
|
84
|
+
*/
|
|
85
|
+
export function declaredPredecessors(contentBase: string, { skipDirectories, maps, config, records, problems }?: {
|
|
86
|
+
skipDirectories?: readonly string[] | undefined;
|
|
87
|
+
maps?: readonly object[] | undefined;
|
|
88
|
+
config?: object | undefined;
|
|
89
|
+
records?: readonly object[] | undefined;
|
|
90
|
+
problems?: object[] | undefined;
|
|
91
|
+
}): Map<string, {
|
|
92
|
+
to: string;
|
|
93
|
+
file: string;
|
|
94
|
+
shortcode: string;
|
|
95
|
+
}>;
|
|
45
96
|
/**
|
|
46
97
|
* Every address the baseline published that this build does not.
|
|
47
98
|
*
|
|
@@ -57,7 +108,7 @@ export function declaredPredecessors(contentBase: any, { skipDirectories, maps,
|
|
|
57
108
|
* @param {Map<string, {to: string, file: string}>} [opts.predecessors] - The
|
|
58
109
|
* declared renames, from {@link declaredPredecessors}. Omitted, the diff
|
|
59
110
|
* falls back to the id join alone and reports an unpinned rename as a
|
|
60
|
-
* withdrawal, which is what it did before
|
|
111
|
+
* withdrawal, which is what it did before.
|
|
61
112
|
* @returns {Array<object>} One finding per departed address, in address order
|
|
62
113
|
* so two runs read the same. `kind` is `"renamed"` (with `to`, and `declared`
|
|
63
114
|
* when it was the note's word rather than an id match) or `"withdrawn"`.
|
|
@@ -85,12 +136,15 @@ export function diffItemAddresses(baseline: Map<string, object>, current: Map<st
|
|
|
85
136
|
* id is derived against. See {@link addressCorpus} for why that matters.
|
|
86
137
|
* @param {readonly object[]} [opts.records] - Index records the caller already
|
|
87
138
|
* derived, shared with {@link declaredPredecessors}.
|
|
139
|
+
* @param {object[]} [opts.problems] - Collects the notes the index cannot
|
|
140
|
+
* record, so one of them does not abort the diff before it reports.
|
|
88
141
|
* @returns {Map<string, string>} Document id → the note's absolute path.
|
|
89
142
|
*/
|
|
90
143
|
export function noteFilesById(contentBase: string, { skipDirectories, config, records, problems }?: {
|
|
91
144
|
skipDirectories?: readonly string[] | undefined;
|
|
92
145
|
config?: object | undefined;
|
|
93
146
|
records?: readonly object[] | undefined;
|
|
147
|
+
problems?: object[] | undefined;
|
|
94
148
|
}): Map<string, string>;
|
|
95
149
|
/**
|
|
96
150
|
* Where to send the reader for one finding.
|
|
@@ -105,7 +159,7 @@ export function noteFilesById(contentBase: string, { skipDirectories, config, re
|
|
|
105
159
|
* A **declared** rename knows its note without any lookup — the declaration is
|
|
106
160
|
* how it was found — and is reported at the `renamedFrom:` line rather than the
|
|
107
161
|
* `shortcode:` line, because that is the line the finding is about and the one
|
|
108
|
-
* the author deletes once the declaration has done its work
|
|
162
|
+
* the author deletes once the declaration has done its work.
|
|
109
163
|
*
|
|
110
164
|
* @param {object} finding - One finding from {@link diffItemAddresses}.
|
|
111
165
|
* @param {Map<string, string>} noteFiles - From {@link noteFilesById}.
|
|
@@ -126,7 +180,7 @@ export function locateAddressFinding(finding: object, noteFiles: Map<string, str
|
|
|
126
180
|
* known — and says so, rather than leaving the reader to wonder whether one was
|
|
127
181
|
* looked for.
|
|
128
182
|
*
|
|
129
|
-
* **A declared rename says it is declared
|
|
183
|
+
* **A declared rename says it is declared**. The two claims are not
|
|
130
184
|
* equally checkable: an id match is a fact in the artefacts, while a
|
|
131
185
|
* declaration is an author's word, and a reader deciding whether to trust the
|
|
132
186
|
* successor needs to know which one they have. Saying "the same document" of a
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* note is one this build **refused** — it declares a retired frontmatter field
|
|
6
6
|
* — and it is an error; a skipped one legitimately belongs to another pass, and
|
|
7
7
|
* there are thousands of those. Folding the first into the second is what let a
|
|
8
|
-
* whole tree be filtered out in silence
|
|
8
|
+
* whole tree be filtered out in silence.
|
|
9
9
|
*
|
|
10
10
|
* @typedef {object} PassStats
|
|
11
11
|
* @property {number} compiled - Notes that became a document.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* @property {number} skippedOther - Notes this pass does not claim.
|
|
14
14
|
* @property {number} declined - Notes this pack **refused** — one declaring a
|
|
15
15
|
* retired frontmatter field, or one routed to a system pack whose system it
|
|
16
|
-
* says nothing about
|
|
16
|
+
* says nothing about. Counted as errors, never as skips.
|
|
17
17
|
*/
|
|
18
18
|
/**
|
|
19
19
|
* The shared walk → filter → expand → convert → build → write → count loop.
|
|
@@ -51,7 +51,7 @@ export class BasePackCompiler {
|
|
|
51
51
|
* its generated tables expanded and its wikilinks converted.
|
|
52
52
|
*
|
|
53
53
|
* False for a pass whose output must be exactly what the author typed —
|
|
54
|
-
* the macros pass, whose `command` is executable source
|
|
54
|
+
* the macros pass, whose `command` is executable source. A pass
|
|
55
55
|
* that says so also skips building the content-wide link index it would
|
|
56
56
|
* never read.
|
|
57
57
|
*
|
|
@@ -67,7 +67,7 @@ export class BasePackCompiler {
|
|
|
67
67
|
* passes wrote — so an Actor pass must run after every Item pass, and it
|
|
68
68
|
* says so here.
|
|
69
69
|
*
|
|
70
|
-
* The generator derives the compile order from this
|
|
70
|
+
* The generator derives the compile order from this, so the order
|
|
71
71
|
* `packs:` declares is presentation only — it is the manifest's `packs`
|
|
72
72
|
* array as well, and a consumer orders that for a reader. A pass that
|
|
73
73
|
* reads another's output states the dependency once, in the class that
|
|
@@ -82,7 +82,7 @@ export class BasePackCompiler {
|
|
|
82
82
|
static readsPackOutputOf: readonly string[];
|
|
83
83
|
/**
|
|
84
84
|
* Whether this pass's document **is** a system's data, and therefore takes
|
|
85
|
-
* only notes that carry that system's block
|
|
85
|
+
* only notes that carry that system's block.
|
|
86
86
|
*
|
|
87
87
|
* A pack may declare a `system:` — `harn-ensemble` ships an `actors-hm3`
|
|
88
88
|
* and an `actors-sohl` from one tree — and the note-side half of that is
|
|
@@ -112,7 +112,7 @@ export class BasePackCompiler {
|
|
|
112
112
|
* legal on every note whatever its type, because
|
|
113
113
|
* `BLOCK_DOCUMENT_PROPERTIES` maps it onto `document.img` — so a note whose
|
|
114
114
|
* document has no such property authors it, validates, compiles, and loses
|
|
115
|
-
* the value with nothing said
|
|
115
|
+
* the value with nothing said: `Parrot` in `sohl-thalorna`
|
|
116
116
|
* had declared `img:` since long before the art rule existed and compiled
|
|
117
117
|
* `img: null` exactly as a note declaring nothing does. Naming the fields
|
|
118
118
|
* here is what lets the lint tell an inert key from a live one.
|
|
@@ -134,13 +134,19 @@ export class BasePackCompiler {
|
|
|
134
134
|
* never descends into. Required: see {@link assertStatedScope}.
|
|
135
135
|
* @param {(address: string|null) => string|null} [options.folderResolver] -
|
|
136
136
|
* Resolves a `packFolder` — a folder note's address — to the Foundry
|
|
137
|
-
* folder id it materialises as in this pack
|
|
137
|
+
* folder id it materialises as in this pack.
|
|
138
138
|
* @param {string} [options.packName] - The pack this pass writes.
|
|
139
|
+
* @param {string|null} [options.packSystem] - The system that pack declares,
|
|
140
|
+
* which decides the `_stats` it stamps and the system block a note must
|
|
141
|
+
* carry to reach it. `null` for a pack that declares none.
|
|
139
142
|
* @param {string} [options.docType] - The Foundry document type it holds.
|
|
140
143
|
* @param {{resolve: Function}} [options.router] - The pack router. Omit it
|
|
141
144
|
* — as the unit suite does — and every claimed note is compiled here.
|
|
142
145
|
* @param {boolean} [options.routingReporter] - Whether this pass reports a
|
|
143
146
|
* note of its type that routes nowhere.
|
|
147
|
+
* @param {object} [options.corpus] - The corpus this compile is running
|
|
148
|
+
* over, derived once and shared by every pass. A pass handed none derives
|
|
149
|
+
* its own in `prepare`, and reports that corpus's problems itself.
|
|
144
150
|
*/
|
|
145
151
|
constructor({ contentBase, dest, skipDirectories, folderResolver, packName, packSystem, docType, router, routingReporter, corpus, }?: {
|
|
146
152
|
contentBase: string;
|
|
@@ -148,11 +154,13 @@ export class BasePackCompiler {
|
|
|
148
154
|
skipDirectories: readonly string[];
|
|
149
155
|
folderResolver?: ((address: string | null) => string | null) | undefined;
|
|
150
156
|
packName?: string | undefined;
|
|
157
|
+
packSystem?: string | null | undefined;
|
|
151
158
|
docType?: string | undefined;
|
|
152
159
|
router?: {
|
|
153
160
|
resolve: Function;
|
|
154
161
|
} | undefined;
|
|
155
162
|
routingReporter?: boolean | undefined;
|
|
163
|
+
corpus?: object | undefined;
|
|
156
164
|
});
|
|
157
165
|
/** @type {string} */
|
|
158
166
|
contentBase: string;
|
|
@@ -163,7 +171,7 @@ export class BasePackCompiler {
|
|
|
163
171
|
/** @type {number} */
|
|
164
172
|
errorCount: number;
|
|
165
173
|
/**
|
|
166
|
-
* Emitted-`system` findings, one per `documentType|subtype|field
|
|
174
|
+
* Emitted-`system` findings, one per `documentType|subtype|field`.
|
|
167
175
|
*
|
|
168
176
|
* A key the compiler writes is on **every** document of a subtype, so
|
|
169
177
|
* reporting it where it is found would print the same sentence 3,126 times
|
|
@@ -219,10 +227,10 @@ export class BasePackCompiler {
|
|
|
219
227
|
* @type {number}
|
|
220
228
|
*/
|
|
221
229
|
unresolvedLinks: number;
|
|
222
|
-
packSystem:
|
|
223
|
-
corpus:
|
|
230
|
+
packSystem: string | null;
|
|
231
|
+
corpus: object | undefined;
|
|
224
232
|
/**
|
|
225
|
-
* The `_stats` block every entry this pass emits is stamped with
|
|
233
|
+
* The `_stats` block every entry this pass emits is stamped with.
|
|
226
234
|
*
|
|
227
235
|
* Per pack rather than per package, because a module may ship the same
|
|
228
236
|
* content for two systems — `harn-ensemble` has an `actors-hm3` pack and an
|
|
@@ -252,8 +260,7 @@ export class BasePackCompiler {
|
|
|
252
260
|
* routed *here* and carries nothing for this pack's system is an authoring
|
|
253
261
|
* mistake with a hollow document at the end of it, not a note that belongs
|
|
254
262
|
* to another pass. Skipping it quietly is how a whole tree compiles to
|
|
255
|
-
* documents nobody can use
|
|
256
|
-
* instances of.
|
|
263
|
+
* documents nobody can use.
|
|
257
264
|
*
|
|
258
265
|
* @param {object} fm - The note's frontmatter.
|
|
259
266
|
* @returns {boolean} True when the note may be compiled here; `false` when
|
|
@@ -266,7 +273,7 @@ export class BasePackCompiler {
|
|
|
266
273
|
eligibleFor(fm: object): boolean;
|
|
267
274
|
/**
|
|
268
275
|
* A refusal only this pass can make, because its subject is the note's
|
|
269
|
-
* **type
|
|
276
|
+
* **type**.
|
|
270
277
|
*
|
|
271
278
|
* The `assertNo*Field` family above it in the walk is type-agnostic by
|
|
272
279
|
* construction: it runs before `selects`, so that a note declaring a
|
|
@@ -291,7 +298,7 @@ export class BasePackCompiler {
|
|
|
291
298
|
* Whether this pass claims a note. **Required.**
|
|
292
299
|
*
|
|
293
300
|
* Called only for a note this build compiles — every note in the tree
|
|
294
|
-
* belongs to the configured content package
|
|
301
|
+
* belongs to the configured content package — so a subclass decides
|
|
295
302
|
* on `type` alone.
|
|
296
303
|
*
|
|
297
304
|
* @param {object} fm - The note's frontmatter.
|
|
@@ -368,8 +375,7 @@ export class BasePackCompiler {
|
|
|
368
375
|
column?: number;
|
|
369
376
|
}): void;
|
|
370
377
|
/**
|
|
371
|
-
* Report every `<system>.system` key the receiving subtype does not declare
|
|
372
|
-
* (#58).
|
|
378
|
+
* Report every `<system>.system` key the receiving subtype does not declare.
|
|
373
379
|
*
|
|
374
380
|
* An **error**, not a warning: Foundry drops an unknown `system` key at
|
|
375
381
|
* construction without a word, so the alternative is a document shipped
|
|
@@ -390,7 +396,7 @@ export class BasePackCompiler {
|
|
|
390
396
|
reportUndeclaredSystemData(fm: object, block: string, documentType: string, subType: string): number;
|
|
391
397
|
/**
|
|
392
398
|
* Record every `system` key the *compiled document* carries that the
|
|
393
|
-
* receiving subtype does not declare
|
|
399
|
+
* receiving subtype does not declare.
|
|
394
400
|
*
|
|
395
401
|
* The sibling of {@link BasePackCompiler#reportUndeclaredSystemData}, and
|
|
396
402
|
* the half that sees what no declaration states. A compiler writes keys of
|
|
@@ -434,7 +440,7 @@ export class BasePackCompiler {
|
|
|
434
440
|
/**
|
|
435
441
|
* Emit the collected emitted-`system` findings, once each.
|
|
436
442
|
*
|
|
437
|
-
* An **error**, for the reason
|
|
443
|
+
* An **error**, for the reason its sibling is one: the value is gone
|
|
438
444
|
* at load and the build says nothing, and severity that varied by *which
|
|
439
445
|
* part of the build wrote the key* would make the less fixable half the
|
|
440
446
|
* quieter one. What varies is the message, which says whose fix it is —
|
|
@@ -529,7 +535,7 @@ export class BasePackCompiler {
|
|
|
529
535
|
* note is one this build **refused** — it declares a retired frontmatter field
|
|
530
536
|
* — and it is an error; a skipped one legitimately belongs to another pass, and
|
|
531
537
|
* there are thousands of those. Folding the first into the second is what let a
|
|
532
|
-
* whole tree be filtered out in silence
|
|
538
|
+
* whole tree be filtered out in silence.
|
|
533
539
|
*/
|
|
534
540
|
export type PassStats = {
|
|
535
541
|
/**
|
|
@@ -547,7 +553,7 @@ export type PassStats = {
|
|
|
547
553
|
/**
|
|
548
554
|
* - Notes this pack **refused** — one declaring a
|
|
549
555
|
* retired frontmatter field, or one routed to a system pack whose system it
|
|
550
|
-
* says nothing about
|
|
556
|
+
* says nothing about. Counted as errors, never as skips.
|
|
551
557
|
*/
|
|
552
558
|
declined: number;
|
|
553
559
|
};
|
|
@@ -35,7 +35,7 @@ export function bareAddress(value: unknown): string | null;
|
|
|
35
35
|
* `### type: bundle` table puts it — the closed container, so a misspelled
|
|
36
36
|
* `content` is a finding rather than a silently empty Adventure. It is accepted
|
|
37
37
|
* at the top level too, exactly as a folder note's `parent` is: an author
|
|
38
|
-
* following
|
|
38
|
+
* following the shipped example rather than the specification should get a
|
|
39
39
|
* bundle, not a silent default.
|
|
40
40
|
*
|
|
41
41
|
* **Order is the author's**, and it is kept: an Adventure's `SetField` attaches
|
|
@@ -124,9 +124,9 @@ export function buildAdventure({ id, name, img, description, caption, folder, fl
|
|
|
124
124
|
* world's collection already holds that `_id`, then creates or updates each.
|
|
125
125
|
* Afterwards the documents live independently and the Adventure has no further
|
|
126
126
|
* role. **It is an installer** — a set of document *copies* packaged for
|
|
127
|
-
* one-shot import
|
|
127
|
+
* one-shot import.
|
|
128
128
|
*
|
|
129
|
-
* That is the whole difference from a folder
|
|
129
|
+
* That is the whole difference from a folder, which is a live grouping
|
|
130
130
|
* **by reference** that persists in the pack. A bundle carries copies and
|
|
131
131
|
* exists to be imported once, so the two are not variations on one idea.
|
|
132
132
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* the first.
|
|
9
9
|
*
|
|
10
10
|
* A **folder** document is skipped. It is emitted into every pack that holds
|
|
11
|
-
* something filed in it
|
|
11
|
+
* something filed in it, so it is not one pack's document and has no
|
|
12
12
|
* single note behind it; a bundle that wants folders is a question this pass
|
|
13
13
|
* refuses rather than guesses at — see {@link Bundles#resolveAddress}.
|
|
14
14
|
*
|
|
@@ -20,6 +20,15 @@
|
|
|
20
20
|
* pack, which reordering cannot fix.
|
|
21
21
|
*/
|
|
22
22
|
export function loadBundleSources(sourceDirs: Readonly<Record<string, readonly string[]>>): Map<string, object>;
|
|
23
|
+
/**
|
|
24
|
+
* Adventure pack compiler.
|
|
25
|
+
*
|
|
26
|
+
* Walks the content tree and compiles every `type: bundle` note into one
|
|
27
|
+
* Adventure per system, holding **copies** of the compiled documents its
|
|
28
|
+
* `contents` addresses name. Reading other passes' output is what
|
|
29
|
+
* {@link Bundles.readsPackOutputOf} declares, and what the generator orders the
|
|
30
|
+
* compile by.
|
|
31
|
+
*/
|
|
23
32
|
export class Bundles extends BasePackCompiler {
|
|
24
33
|
/**
|
|
25
34
|
* @param {object} options - As {@link BasePackCompiler}, plus:
|
|
@@ -94,12 +94,12 @@ export function matchAllOutsideCode(markdown: string, pattern: RegExp, options?:
|
|
|
94
94
|
* **Which runs count as code is {@link codeRegions}' rule, not a second copy of
|
|
95
95
|
* it.** The knowledgebase build carried its own regex once, and it was weaker in
|
|
96
96
|
* two ways that both corrupted the one page whose subject *is* link syntax — so
|
|
97
|
-
* its examples
|
|
97
|
+
* its examples are exactly the input a looser rule mangles. A
|
|
98
98
|
* single-backtick span was allowed to cross newlines, so one odd backtick paired
|
|
99
99
|
* with another paragraphs away and every span after it paired wrongly: prose was
|
|
100
100
|
* masked as code while real spans were left exposed. And only three-backtick
|
|
101
101
|
* fences were recognised, so a four-backtick example holding a three-backtick
|
|
102
|
-
* block — the documented "fences of any length" case
|
|
102
|
+
* block — the documented "fences of any length" case — leaked its
|
|
103
103
|
* contents.
|
|
104
104
|
*
|
|
105
105
|
* @param {string} body - The markdown body.
|
|
@@ -114,7 +114,7 @@ export function protectCode(body: string, transform: (masked: string) => string)
|
|
|
114
114
|
* written. Every build-time rewriter that pattern-matches a body therefore has
|
|
115
115
|
* to know where code is — otherwise a source listing that happens to contain
|
|
116
116
|
* the rewriter's syntax is silently corrupted. Wikilink conversion met this as
|
|
117
|
-
* `[[0]]` inside a fence being turned into a link
|
|
117
|
+
* `[[0]]` inside a fence being turned into a link, and it depended on
|
|
118
118
|
* the surrounding literal's shape (`[[1,2],[3,4]]` survived), so the corruption
|
|
119
119
|
* looked arbitrary.
|
|
120
120
|
*
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @param {object} opts
|
|
7
7
|
* @param {object} [opts.config] The resolved build configuration, which
|
|
8
8
|
* the two path arguments below default from. Supplying one is how a caller
|
|
9
|
-
* compiles a package other than this repository's
|
|
9
|
+
* compiles a package other than this repository's.
|
|
10
10
|
* @param {string[]} [opts.sourcePacks] Every pack compiled from the content
|
|
11
11
|
* tree, in compile order. Defaults to the configured pack directories.
|
|
12
12
|
* @param {string} [opts.stageDest] Directory the LevelDB packs are built
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
* @throws {Error} If pack JSON generation reported any error. Packs compiled
|
|
16
16
|
* from incomplete or empty JSON ship blank or short compendiums, and the
|
|
17
17
|
* omission is invisible until a player looks for content that is not there
|
|
18
|
-
*
|
|
18
|
+
* — so this is fatal, not a warning, and the caller is expected to
|
|
19
19
|
* turn it into a failing exit code.
|
|
20
20
|
* @throws {Error} If a compiled pack ships a Scene that has lost its embedded
|
|
21
|
-
* Level
|
|
21
|
+
* Level. Fatal for the same reason: Foundry reads a missing Level
|
|
22
22
|
* record as "no levels" and persists that on the next world launch, so the
|
|
23
23
|
* map image is gone before anyone notices it was ever at risk. See
|
|
24
24
|
* {@link verifyPackSceneLevels}.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @param {object} opts - Options.
|
|
5
5
|
* @param {string} opts.contentBase - Root of the content tree.
|
|
6
6
|
* @param {readonly string[]} opts.skipDirectories - The scope, stated by the
|
|
7
|
-
* caller as every corpus read requires
|
|
7
|
+
* caller as every corpus read requires.
|
|
8
8
|
* @param {object} opts.router - The pack router this compile resolved. Shared
|
|
9
9
|
* by every pass, which is what makes one link index correct for all of them.
|
|
10
10
|
* @param {object} [opts.config] - The resolved configuration.
|