@heroiclands/package-build 22.28.0 → 23.1.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 (156) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +1 -1
  3. package/bin/content-commands.mjs +1 -1
  4. package/ci/content-format-reference.mjs +46 -0
  5. package/docs/api.md +125 -142
  6. package/docs/authoring/assets.md +1 -1
  7. package/docs/authoring/dates-and-calendars.md +12 -6
  8. package/docs/authoring/first-note.md +1 -1
  9. package/docs/authoring/frontmatter.md +2 -2
  10. package/docs/authoring/links-and-markup.md +145 -29
  11. package/docs/commands.md +8 -10
  12. package/docs/configuration.md +13 -11
  13. package/docs/content-format.md +3 -3
  14. package/docs/guides/book.md +59 -4
  15. package/docs/guides/icons.md +4 -5
  16. package/docs/guides/packs.md +6 -0
  17. package/docs/guides/reference-pages.md +21 -1
  18. package/docs/guides/release-and-deploy.md +17 -1
  19. package/docs/guides/site.md +17 -18
  20. package/docs/reference/format-details.md +904 -275
  21. package/docs/reference/note-types.md +282 -91
  22. package/docs/reference/theme-pages.md +58 -66
  23. package/engine/address-values.mjs +124 -4
  24. package/engine/address.mjs +44 -3
  25. package/engine/anchors.mjs +103 -3
  26. package/engine/art-slots.mjs +2 -9
  27. package/engine/base-compiler.mjs +25 -6
  28. package/engine/calendar-artifacts.mjs +4 -1
  29. package/engine/calendar-notes.mjs +166 -102
  30. package/engine/content-format-check.mjs +2 -3
  31. package/engine/content-format.mjs +44 -1
  32. package/engine/content-format.yaml +84 -16
  33. package/engine/content-images.mjs +10 -1
  34. package/engine/content-index.mjs +37 -9
  35. package/engine/content-links.mjs +24 -5
  36. package/engine/content-tables.mjs +24 -3
  37. package/engine/data-keys.mjs +347 -0
  38. package/engine/derived-sections.mjs +322 -0
  39. package/engine/diagnostics.mjs +28 -0
  40. package/engine/event-fields.mjs +187 -0
  41. package/engine/event-rows.mjs +126 -0
  42. package/engine/event-views.mjs +305 -0
  43. package/engine/exported-scene.mjs +29 -53
  44. package/engine/frontmatter-lint.mjs +103 -77
  45. package/engine/frontmatter.mjs +7 -2
  46. package/engine/generate.mjs +53 -0
  47. package/engine/generated-sections.mjs +223 -0
  48. package/engine/heading-attributes.mjs +4 -2
  49. package/engine/helpers.mjs +12 -1
  50. package/engine/holdings.mjs +12 -33
  51. package/engine/ids.mjs +17 -11
  52. package/engine/index.mjs +4 -4
  53. package/engine/infobox-render.mjs +21 -6
  54. package/engine/infobox.mjs +217 -99
  55. package/engine/journals.mjs +104 -47
  56. package/engine/literature-notes.mjs +136 -0
  57. package/engine/literature-works.mjs +161 -0
  58. package/engine/map-graphviz.mjs +4 -18
  59. package/engine/markdown-expressions.mjs +116 -11
  60. package/engine/metadata-index.mjs +34 -0
  61. package/engine/near-miss.mjs +90 -0
  62. package/engine/note-addresses.mjs +75 -19
  63. package/engine/note-dates.mjs +5 -3
  64. package/engine/note-event-terms.mjs +364 -0
  65. package/engine/note-events.mjs +823 -0
  66. package/engine/note-vocabulary.mjs +195 -92
  67. package/engine/office-holders.mjs +20 -54
  68. package/engine/packagebuild-index.mjs +16 -1
  69. package/engine/pdf-build.mjs +97 -60
  70. package/engine/pdf-index.mjs +263 -0
  71. package/engine/pdf-render.mjs +47 -5
  72. package/engine/place-relation-terms.mjs +174 -0
  73. package/engine/place-relations.mjs +72 -160
  74. package/engine/rank-ladder.mjs +14 -41
  75. package/engine/reckoning-markers.mjs +2 -0
  76. package/engine/region-events.mjs +6 -12
  77. package/engine/scenes.mjs +73 -468
  78. package/engine/site-build.mjs +74 -85
  79. package/engine/site-index.mjs +3 -1
  80. package/engine/site-maps.mjs +43 -29
  81. package/engine/site-preview.mjs +40 -31
  82. package/engine/social-ties.mjs +2 -1
  83. package/engine/sql-tables.mjs +212 -9
  84. package/engine/standing-terms.mjs +145 -6
  85. package/engine/standings.mjs +37 -49
  86. package/engine/stub-lint.mjs +6 -0
  87. package/engine/web-wikilinks.mjs +21 -1
  88. package/engine/wikilink-syntax.mjs +34 -4
  89. package/engine/wikilinks.mjs +27 -2
  90. package/hugo-theme/layouts/partials/infobox/entry.html +4 -1
  91. package/hugo-theme/layouts/partials/page-body.html +0 -2
  92. package/hugo-theme/static/css/style.css +25 -55
  93. package/package.json +1 -2
  94. package/packagebuild-metadata.jsonl +13 -13
  95. package/sohl/default-item-art.mjs +6 -6
  96. package/sohl/note-schemas.mjs +8 -73
  97. package/types/engine/address-values.d.mts +50 -3
  98. package/types/engine/address.d.mts +21 -0
  99. package/types/engine/anchors.d.mts +49 -2
  100. package/types/engine/art-slots.d.mts +1 -1
  101. package/types/engine/base-compiler.d.mts +13 -4
  102. package/types/engine/calendar-notes.d.mts +7 -0
  103. package/types/engine/content-format.d.mts +52 -0
  104. package/types/engine/content-images.d.mts +5 -1
  105. package/types/engine/content-tables.d.mts +9 -1
  106. package/types/engine/data-keys.d.mts +145 -0
  107. package/types/engine/derived-sections.d.mts +73 -0
  108. package/types/engine/diagnostics.d.mts +15 -0
  109. package/types/engine/event-fields.d.mts +99 -0
  110. package/types/engine/event-rows.d.mts +12 -0
  111. package/types/engine/event-views.d.mts +67 -0
  112. package/types/engine/exported-scene.d.mts +5 -2
  113. package/types/engine/frontmatter-lint.d.mts +3 -3
  114. package/types/engine/generated-sections.d.mts +143 -0
  115. package/types/engine/holdings.d.mts +6 -20
  116. package/types/engine/ids.d.mts +15 -12
  117. package/types/engine/index.d.mts +1 -1
  118. package/types/engine/infobox.d.mts +13 -3
  119. package/types/engine/journals.d.mts +24 -11
  120. package/types/engine/literature-notes.d.mts +29 -0
  121. package/types/engine/literature-works.d.mts +67 -0
  122. package/types/engine/map-graphviz.d.mts +2 -10
  123. package/types/engine/markdown-expressions.d.mts +12 -3
  124. package/types/engine/near-miss.d.mts +42 -0
  125. package/types/engine/note-addresses.d.mts +7 -1
  126. package/types/engine/note-event-terms.d.mts +68 -0
  127. package/types/engine/note-events.d.mts +71 -0
  128. package/types/engine/note-vocabulary.d.mts +37 -8
  129. package/types/engine/office-holders.d.mts +3 -0
  130. package/types/engine/pdf-index.d.mts +35 -0
  131. package/types/engine/pdf-render.d.mts +8 -2
  132. package/types/engine/place-relation-terms.d.mts +83 -0
  133. package/types/engine/place-relations.d.mts +11 -66
  134. package/types/engine/rank-ladder.d.mts +2 -0
  135. package/types/engine/region-events.d.mts +6 -12
  136. package/types/engine/scenes.d.mts +6 -32
  137. package/types/engine/site-build.d.mts +8 -22
  138. package/types/engine/site-maps.d.mts +15 -7
  139. package/types/engine/sql-tables.d.mts +77 -2
  140. package/types/engine/standing-terms.d.mts +37 -4
  141. package/types/engine/standings.d.mts +14 -9
  142. package/types/engine/wikilink-syntax.d.mts +20 -0
  143. package/types/engine/wikilinks.d.mts +3 -2
  144. package/docs/guides/government-migration.md +0 -52
  145. package/engine/itinerary-scenes.mjs +0 -166
  146. package/engine/lore-events.mjs +0 -197
  147. package/engine/map-notes.mjs +0 -1309
  148. package/engine/map-raster.mjs +0 -51
  149. package/hugo-theme/layouts/partials/holdings/entry.html +0 -21
  150. package/hugo-theme/layouts/partials/holdings/kind-groups.html +0 -71
  151. package/hugo-theme/layouts/partials/holdings.html +0 -61
  152. package/hugo-theme/layouts/partials/place-map.html +0 -9
  153. package/types/engine/itinerary-scenes.d.mts +0 -29
  154. package/types/engine/lore-events.d.mts +0 -14
  155. package/types/engine/map-notes.d.mts +0 -297
  156. package/types/engine/map-raster.d.mts +0 -8
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The **terms of an event**: the closed value lists an event entry draws on,
3
+ * and the declaration of every key an entry and each map inside it take.
4
+ *
5
+ * A leaf module, importing nothing. The note vocabulary reads
6
+ * {@link EVENT_ENTRY} as it loads, so the frontmatter lint's inner-key check
7
+ * closes every key of an entry the way it closes every other `data:` field's;
8
+ * {@link module:engine/note-events} walks the same declaration for what the
9
+ * values mean — closed lists, Addresses, identity and order — and reaches the
10
+ * vocabulary through the Address reader.
11
+ *
12
+ * An entry is declared in the inner-key vocabulary of
13
+ * {@link module:engine/data-keys} — `fields`, `entries`, `kind`, `shape`,
14
+ * `required`, `describe` — with four properties of its own that the event
15
+ * check reads:
16
+ *
17
+ * - `oneOf` — `{name, values}`: the value is one of `values`, a closed list the
18
+ * format reference states as the vocabulary table `name`;
19
+ * - `ref`, `accepts`, `anchors`, `single`, `eventOrLore`, `calendar` on an
20
+ * Address: its default type, its accepted types, the anchor kinds it may
21
+ * name, and whether it must name exactly one event, an event or a `lore`
22
+ * note, or a calendar note;
23
+ * - `own` — the key's value is judged by the event check's own code (`id`,
24
+ * `when`, `until`, `recurs`) rather than by the walker.
25
+ *
26
+ * @module
27
+ */
28
+ /** What an event is, grouped for reading and closed for validation. */
29
+ export const EVENT_KINDS: readonly string[];
30
+ /** How far an event's history reaches. Set by hand. */
31
+ export const EVENT_DEPTHS: readonly string[];
32
+ /** What the world's evidence supports about an event. */
33
+ export const EVENT_STANDINGS: readonly string[];
34
+ /** Whether a place that felt an event knows what caused it. */
35
+ export const REACH_KNOWLEDGE: readonly string[];
36
+ /** What a participant was to an event. */
37
+ export const PARTICIPANT_ROLES: readonly string[];
38
+ /** How a later event follows from an earlier one. */
39
+ export const FOLLOWS_HOW: readonly string[];
40
+ /** How far an account agrees with the event's summary. */
41
+ export const ACCOUNT_AGREES: readonly string[];
42
+ /**
43
+ * Every closed list, by the name of the vocabulary table the format reference
44
+ * and `engine/content-format.yaml` state it under. `eventKind` is not `kind`
45
+ * because the infobox's row kinds already hold that name.
46
+ */
47
+ export const EVENT_VOCABULARIES: Readonly<{
48
+ eventKind: readonly string[];
49
+ depth: readonly string[];
50
+ standing: readonly string[];
51
+ knowledge: readonly string[];
52
+ role: readonly string[];
53
+ followsHow: readonly string[];
54
+ agrees: readonly string[];
55
+ }>;
56
+ /**
57
+ * One event entry, as an inner-key declaration: every key it takes, and every
58
+ * key of each map nested in it.
59
+ *
60
+ * @type {Readonly<{kind: "map", shape: string, fields: readonly object[]}>}
61
+ */
62
+ export const EVENT_ENTRY: Readonly<{
63
+ kind: "map";
64
+ shape: string;
65
+ fields: readonly object[];
66
+ }>;
67
+ /** Every key an event entry admits, in the order the reference documents them. */
68
+ export const EVENT_ENTRY_KEYS: any;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Resolve an Address a field outside an event writes to name one — a gear
3
+ * note's `made` or a literature note's `subjects` entry — by the rules an
4
+ * event's own `follows` is resolved by.
5
+ *
6
+ * @param {unknown} value - The authored value: a string, a tuple, or an
7
+ * {@link AddressLink}.
8
+ * @param {{ref?: string, accepts?: readonly string[], anchors?: readonly string[],
9
+ * single?: boolean}} spec - The field's declaration: `ref` the default type of
10
+ * a bare shortcode, `accepts` the types the Address may name, `anchors` the
11
+ * anchor kinds `#<anchor>` may name, and `single` whether it must name exactly
12
+ * one event.
13
+ * @param {object} index - The link index.
14
+ * @returns {{problem?: string, hit?: object, position?: number, target?: string}}
15
+ * What it names, or why it names nothing.
16
+ */
17
+ export function resolveEventReference(value: unknown, spec: {
18
+ ref?: string;
19
+ accepts?: readonly string[];
20
+ anchors?: readonly string[];
21
+ single?: boolean;
22
+ }, index: object): {
23
+ problem?: string;
24
+ hit?: object;
25
+ position?: number;
26
+ target?: string;
27
+ };
28
+ /**
29
+ * Validate a note's `data.events`, entry by entry.
30
+ *
31
+ * Registered as the `events` field's `check`, so it runs on every note whose
32
+ * type declares `events`, whatever its `subType`. Without an index the shape,
33
+ * the closed values, the identity and the dates are checked and no Address is
34
+ * resolved.
35
+ *
36
+ * @param {object} note - The note, as the link index hands it over.
37
+ * @param {{index?: object}} [options]
38
+ * @returns {object[]} Findings, each positioned at the key or value that
39
+ * earned it.
40
+ */
41
+ export function checkNoteEvents(note: object, { index }?: {
42
+ index?: object;
43
+ }): object[];
44
+ /**
45
+ * Every Address position inside one event entry, derived from the schema
46
+ * above: its path from the entry (`*` for each list item), whether it holds one
47
+ * Address or a list of them, and its default type, accepted types and anchor
48
+ * kinds. The note boundary reads these Addresses into tuples, so the published
49
+ * index writes them as it writes every other Address.
50
+ *
51
+ * @type {ReadonlyArray<{path: readonly string[], shape: "value"|"list",
52
+ * type?: string, accepts?: readonly string[], anchors?: readonly string[]}>}
53
+ */
54
+ export const EVENT_ADDRESS_POSITIONS: ReadonlyArray<{
55
+ path: readonly string[];
56
+ shape: "value" | "list";
57
+ type?: string;
58
+ accepts?: readonly string[];
59
+ anchors?: readonly string[];
60
+ }>;
61
+ import { ACCOUNT_AGREES } from "./note-event-terms.mjs";
62
+ import { EVENT_DEPTHS } from "./note-event-terms.mjs";
63
+ import { EVENT_ENTRY } from "./note-event-terms.mjs";
64
+ import { EVENT_ENTRY_KEYS } from "./note-event-terms.mjs";
65
+ import { EVENT_KINDS } from "./note-event-terms.mjs";
66
+ import { EVENT_STANDINGS } from "./note-event-terms.mjs";
67
+ import { EVENT_VOCABULARIES } from "./note-event-terms.mjs";
68
+ import { FOLLOWS_HOW } from "./note-event-terms.mjs";
69
+ import { PARTICIPANT_ROLES } from "./note-event-terms.mjs";
70
+ import { REACH_KNOWLEDGE } from "./note-event-terms.mjs";
71
+ export { ACCOUNT_AGREES, EVENT_DEPTHS, EVENT_ENTRY, EVENT_ENTRY_KEYS, EVENT_KINDS, EVENT_STANDINGS, EVENT_VOCABULARIES, FOLLOWS_HOW, PARTICIPANT_ROLES, REACH_KNOWLEDGE };
@@ -134,14 +134,18 @@ export function dataFields(type: string, vocabulary?: Readonly<Record<string, Ty
134
134
  */
135
135
  export function subTypes(type: string, vocabulary?: Readonly<Record<string, TypeVocabulary>>): readonly string[] | null | undefined;
136
136
  /**
137
- * Accepted migration input with no canonical field or emitted value.
137
+ * What happened to or at a subject — the `events` key, declared once and spread
138
+ * into every type that carries events, so the schema cannot differ between
139
+ * them. The entry's own schema and its check live in
140
+ * {@link module:engine/note-events}.
138
141
  *
139
- * Legacy affiliation domains are ignored. They never supply a government.
140
- * @param {string} type - The note type.
141
- * @param {string} key - An authored data key.
142
- * @returns {boolean} Whether the obsolete key is accepted during migration.
142
+ * Declared here rather than in that module because its imports reach back to
143
+ * this one: a function declaration is bound before either module runs, and an
144
+ * object is not.
145
+ *
146
+ * @type {DataFieldSpec}
143
147
  */
144
- export function isLegacyDataField(type: string, key: string): boolean;
148
+ export const EVENTS_FIELD: DataFieldSpec;
145
149
  /**
146
150
  * One top-level frontmatter key.
147
151
  *
@@ -389,6 +393,16 @@ export type DataFieldSpec = {
389
393
  * - Allowed Address types, separate from `ref`.
390
394
  */
391
395
  accepts?: readonly string[] | undefined;
396
+ /**
397
+ * - The anchor kinds an
398
+ * Address here may name with `#<anchor>`. Absent, an anchor is refused.
399
+ */
400
+ anchors?: readonly ("event" | "prose")[] | undefined;
401
+ /**
402
+ * - The Address names exactly one event: an
403
+ * anchor of kind `event`, or a note holding one event and no more.
404
+ */
405
+ single?: boolean | undefined;
392
406
  /**
393
407
  * - Infobox text for an explicitly authored null with a declared meaning.
394
408
  */
@@ -407,8 +421,7 @@ export type DataFieldSpec = {
407
421
  entryShape?: string | undefined;
408
422
  /**
409
423
  * - The Address's default type, an art slot declares
410
- * one — `icon` for `icon` and `tokenIcon`, `image` for `bgImage` and
411
- * `banner` — so `icon: anvil` names `icon-anvil` while a value carrying the
424
+ * one — `icon` for `icon` and `tokenIcon`, `image` for `banner` — so `icon: anvil` names `icon-anvil` while a value carrying the
412
425
  * separator states its own address. Distinct from a `FieldSpec`'s `code`
413
426
  * ({@link module :engine/field-spec}), which names a **Shortcode** instead.
414
427
  */
@@ -431,6 +444,22 @@ export type DataFieldSpec = {
431
444
  check?: ((note: object, opts: {
432
445
  index?: object;
433
446
  }) => object[]) | undefined;
447
+ /**
448
+ * - The
449
+ * keys of a value that is a map, closed to them — see
450
+ * {@link module :engine/data-keys}.
451
+ */
452
+ fields?: readonly import("./data-keys.mjs").InnerKeySpec[] | undefined;
453
+ /**
454
+ * - What one entry of a list value is, where the
455
+ * entries are not Addresses (`entryKind` says that).
456
+ */
457
+ entries?: object | undefined;
458
+ /**
459
+ * - What the value under each key of a keyed map
460
+ * is, where the keys are data rather than declared names.
461
+ */
462
+ values?: object | undefined;
434
463
  /**
435
464
  * - One line, for the author-facing reference.
436
465
  */
@@ -12,3 +12,6 @@ export function checkDatedOffices(note: object, { index }?: {
12
12
  column?: number;
13
13
  file: any;
14
14
  }[];
15
+ import { HOLDER_FIELDS } from "./standing-terms.mjs";
16
+ import { OFFICE_FIELDS } from "./standing-terms.mjs";
17
+ export { HOLDER_FIELDS, OFFICE_FIELDS };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The marker an entry heading or an authored mention carries.
3
+ *
4
+ * @param {string} slug - The address slug of the note the marker is about.
5
+ * @param {boolean} [main] - Whether this is the note's own entry.
6
+ * @returns {string} Typst markup occupying no space.
7
+ */
8
+ export function indexMarker(slug: string, main?: boolean): string;
9
+ /**
10
+ * Every term the book's index lists, in index order.
11
+ *
12
+ * @param {object[]} entries - The plan's entries.
13
+ * @returns {Array<{letter: string, name: string, slug: string, see?: string}>}
14
+ * Terms with `see` set for a cross-reference to the main name it points at.
15
+ */
16
+ export function indexTerms(entries: object[]): Array<{
17
+ letter: string;
18
+ name: string;
19
+ slug: string;
20
+ see?: string;
21
+ }>;
22
+ /**
23
+ * The Typst function definitions the markers and the chapter rely on.
24
+ *
25
+ * @returns {string} Typst source.
26
+ */
27
+ export function indexPreamble(): string;
28
+ /**
29
+ * The index chapter, ready to follow the last entry.
30
+ *
31
+ * @param {object[]} entries - The plan's entries.
32
+ * @param {string} title - The book's title, which kicks the chapter.
33
+ * @returns {string} Typst source, or "" when the book has nothing to index.
34
+ */
35
+ export function indexChapter(entries: object[], title: string): string;
@@ -99,6 +99,10 @@ export function stripHtmlComments(markdown: string): string;
99
99
  * at. Every link the book sets as a URL is resolved against it, because a
100
100
  * reader holding a PDF has no page to resolve a path against — see
101
101
  * {@link renderLink}.
102
+ * @param {boolean} [opts.generated] - Whether the Markdown is a note's
103
+ * generated sections rather than its author's text — see
104
+ * {@link module:engine/generated-sections}. Their links follow the rules
105
+ * {@link renderLink} states for generated links.
102
106
  * @returns {string} Typst markup.
103
107
  */
104
108
  export function markdownToTypst(markdown: string, opts?: {
@@ -125,6 +129,7 @@ export function markdownToTypst(markdown: string, opts?: {
125
129
  }[] | undefined;
126
130
  prepared?: boolean | undefined;
127
131
  url?: string | undefined;
132
+ generated?: boolean | undefined;
128
133
  }): string;
129
134
  /**
130
135
  * A page address as a reader of the book can follow it.
@@ -325,8 +330,9 @@ export function renderBook({ plan, bodies, title, subtitle, front, fonts, versio
325
330
  * that would have contained it, which is where a reader wants to end up anyway;
326
331
  * a link with no entry to fall back to becomes plain text. Both are reported.
327
332
  *
328
- * A declaration is a label not preceded by `#link(` — the only two places a
329
- * label appears are the heading that declares one and the link that uses one.
333
+ * A declaration is a label preceded by neither `#link(` nor `locate(` — a
334
+ * label appears in the heading that declares it, the link that uses it, and
335
+ * the page lookup a generated link prints after itself.
330
336
  *
331
337
  * @param {string} source - The assembled Typst document.
332
338
  * @param {object[]} [findings] - Collected here rather than thrown.
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The closed sets a place's `borders` and `routes` are held to, and the keys
3
+ * one entry of each carries.
4
+ *
5
+ * A leaf module, importing nothing: the note vocabulary reads the entry
6
+ * declarations as it loads, and {@link module:engine/place-relations}, which
7
+ * checks what the values mean, reaches the vocabulary through the Address
8
+ * reader.
9
+ *
10
+ * @module
11
+ */
12
+ /**
13
+ * The type a border's or a route's `to` names.
14
+ *
15
+ * It is both the default its `<type>` segment takes when an author omits it and
16
+ * the whole of the set the position accepts, which is what makes `vylar` and
17
+ * `place-vylar` the same Address and a `to` naming a `lore` note an error rather
18
+ * than a lookup that quietly finds nothing.
19
+ *
20
+ * @type {string}
21
+ */
22
+ export const RELATION_TYPE: string;
23
+ /**
24
+ * The eight compass bearings, clockwise from north.
25
+ *
26
+ * Where a neighbour or a destination lies from the place stating it. The
27
+ * order is load-bearing: {@link oppositeBearing} reads four steps around it.
28
+ *
29
+ * @type {readonly string[]}
30
+ */
31
+ export const BEARINGS: readonly string[];
32
+ /**
33
+ * The modes a route is travelled by: `land`, `boat` on a river or a lake,
34
+ * `ship` on open sea.
35
+ *
36
+ * @type {readonly string[]}
37
+ */
38
+ export const ROUTE_MODES: readonly string[];
39
+ /**
40
+ * The days markers a route may state.
41
+ *
42
+ * Each is "about this, under normal conditions": `10`, `20` and `30` are one,
43
+ * two and three ten-day weeks, `180` is many months, `360` is "who knows".
44
+ *
45
+ * @type {readonly number[]}
46
+ */
47
+ export const TRAVEL_DAYS: readonly number[];
48
+ /**
49
+ * The terrain registry, each terrain naming the modes that cross it.
50
+ *
51
+ * A land terrain is crossed by land alone; open sea by ship; a river or a lake
52
+ * by boat; a coast by all three, because a coast road and a coasting voyage
53
+ * are both journeys along it.
54
+ *
55
+ * @type {Readonly<Record<string, readonly string[]>>}
56
+ */
57
+ export const TERRAIN_MODES: Readonly<Record<string, readonly string[]>>;
58
+ /**
59
+ * The terrain names, in registry order — the closed set a `terrain` list
60
+ * draws from.
61
+ *
62
+ * @type {readonly string[]}
63
+ */
64
+ export const TERRAINS: readonly string[];
65
+ /**
66
+ * The keys a `borders` entry carries, as inner-key declarations. Both are
67
+ * required.
68
+ *
69
+ * @type {readonly import("./data-keys.mjs").InnerKeySpec[]}
70
+ */
71
+ export const BORDER_FIELDS: readonly import("./data-keys.mjs").InnerKeySpec[];
72
+ /**
73
+ * The keys a `routes` entry carries, as inner-key declarations. `to`,
74
+ * `bearing`, `mode` and `days` are required; `terrain` and `leagues` are
75
+ * optional.
76
+ *
77
+ * @type {readonly import("./data-keys.mjs").InnerKeySpec[]}
78
+ */
79
+ export const ROUTE_FIELDS: readonly import("./data-keys.mjs").InnerKeySpec[];
80
+ /** The keys a `borders` entry carries. @type {readonly string[]} */
81
+ export const BORDER_KEYS: readonly string[];
82
+ /** The keys a `routes` entry carries. @type {readonly string[]} */
83
+ export const ROUTE_KEYS: readonly string[];
@@ -38,69 +38,14 @@ export function checkBorders(note: object, { index }?: {
38
38
  export function checkRoutes(note: object, { index }?: {
39
39
  index?: object | undefined;
40
40
  }): object[];
41
- /**
42
- * The type a border's or a route's `to` names.
43
- *
44
- * It is both the default its `<type>` segment takes when an author omits it and
45
- * the whole of the set the position accepts, which is what makes `vylar` and
46
- * `place-vylar` the same Address and a `to` naming a `lore` note an error rather
47
- * than a lookup that quietly finds nothing.
48
- *
49
- * @type {string}
50
- */
51
- export const RELATION_TYPE: string;
52
- /**
53
- * The eight compass bearings, clockwise from north.
54
- *
55
- * Where a neighbour or a destination lies from the place stating it. The
56
- * order is load-bearing: {@link oppositeBearing} reads four steps around it.
57
- *
58
- * @type {readonly string[]}
59
- */
60
- export const BEARINGS: readonly string[];
61
- /**
62
- * The modes a route is travelled by: `land`, `boat` on a river or a lake,
63
- * `ship` on open sea.
64
- *
65
- * @type {readonly string[]}
66
- */
67
- export const ROUTE_MODES: readonly string[];
68
- /**
69
- * The days markers a route may state.
70
- *
71
- * Each is "about this, under normal conditions": `10`, `20` and `30` are one,
72
- * two and three ten-day weeks, `180` is many months, `360` is "who knows".
73
- *
74
- * @type {readonly number[]}
75
- */
76
- export const TRAVEL_DAYS: readonly number[];
77
- /**
78
- * The terrain registry, each terrain naming the modes that cross it.
79
- *
80
- * A land terrain is crossed by land alone; open sea by ship; a river or a lake
81
- * by boat; a coast by all three, because a coast road and a coasting voyage
82
- * are both journeys along it.
83
- *
84
- * @type {Readonly<Record<string, readonly string[]>>}
85
- */
86
- export const TERRAIN_MODES: Readonly<Record<string, readonly string[]>>;
87
- /**
88
- * The terrain names, in registry order — the closed set a `terrain` list
89
- * draws from.
90
- *
91
- * @type {readonly string[]}
92
- */
93
- export const TERRAINS: readonly string[];
94
- /**
95
- * The keys a `borders` entry may carry. Both are required.
96
- *
97
- * @type {readonly string[]}
98
- */
99
- export const BORDER_KEYS: readonly string[];
100
- /**
101
- * The keys a `routes` entry may carry. `to`, `bearing`, `mode` and `days` are
102
- * required; `terrain` and `leagues` are optional.
103
- *
104
- * @type {readonly string[]}
105
- */
106
- export const ROUTE_KEYS: readonly string[];
41
+ import { RELATION_TYPE } from "./place-relation-terms.mjs";
42
+ import { BEARINGS } from "./place-relation-terms.mjs";
43
+ import { ROUTE_MODES } from "./place-relation-terms.mjs";
44
+ import { TRAVEL_DAYS } from "./place-relation-terms.mjs";
45
+ import { TERRAIN_MODES } from "./place-relation-terms.mjs";
46
+ import { TERRAINS } from "./place-relation-terms.mjs";
47
+ import { BORDER_FIELDS } from "./place-relation-terms.mjs";
48
+ import { ROUTE_FIELDS } from "./place-relation-terms.mjs";
49
+ import { BORDER_KEYS } from "./place-relation-terms.mjs";
50
+ import { ROUTE_KEYS } from "./place-relation-terms.mjs";
51
+ export { RELATION_TYPE, BEARINGS, ROUTE_MODES, TRAVEL_DAYS, TERRAIN_MODES, TERRAINS, BORDER_FIELDS, ROUTE_FIELDS, BORDER_KEYS, ROUTE_KEYS };
@@ -38,3 +38,5 @@ export function checkRankLadder(note: {
38
38
  severity: string;
39
39
  message: string;
40
40
  }>;
41
+ export { RUNG_FIELDS };
42
+ import { RUNG_FIELDS } from "./standing-terms.mjs";
@@ -2,19 +2,13 @@
2
2
  * The curated Foundry region-event vocabulary, as plain data.
3
3
  *
4
4
  * Deliberately **plain ESM** — no TypeScript, no `@src` aliases, no Foundry —
5
- * for the same reason `../sohl/default-item-art.mjs` is: the map-note pack
6
- * compiler runs under bare `node`, outside the bundler that resolves `@src` and
7
- * strips types, and it must reject an authored region event that the runtime
8
- * would silently drop. One list here is what keeps the build-time lint and the
9
- * runtime bridge from drifting apart.
5
+ * so the Foundry runtime and any build-time consumer read one list, and the
6
+ * events a region trigger forwards cannot drift between them.
10
7
  *
11
- * It sits in this package rather than in the system's `src/` tree because the
12
- * map-note compiler that reads it is installed as a dependency, and a
13
- * relative path out of the package would resolve to garbage from
14
- * `node_modules`. The runtime reaches it back through the package's
15
- * `./engine/region-events` entry point. It is engine-side, not
16
- * SoHL-side, because any content module that authors a scene region — an
17
- * adventure module included — needs this vocabulary.
8
+ * The runtime reaches it through the package's `./engine/region-events` entry
9
+ * point. It is engine-side, not SoHL-side, because a Scene region exported
10
+ * from any content module — an adventure module included — names its events
11
+ * from this vocabulary.
18
12
  *
19
13
  * The prose explaining *why* each event is curated or excluded lives with the
20
14
  * typed re-exports in `src/entity/event/region-triggers.ts`, which is the
@@ -1,39 +1,19 @@
1
- /**
2
- * Every SoHL action name this build knows about, for the `action:` warning on a
3
- * region trigger.
4
- *
5
- * Deliberately a **superset**, gathered from the localization keys every
6
- * intrinsic action's `title:` points at and from the `shortcode:` / `executor:`
7
- * string literals the action definitions carry. A warning that fires on a real
8
- * action would be worse than one that misses a typo, so the wider net is the
9
- * right one: this only has to recognise the names that exist, not enumerate
10
- * them exactly.
11
- *
12
- * @param {string} repoRoot - The repository root.
13
- * @returns {Set<string>} The known action names.
14
- */
15
- export function collectKnownActionNames(repoRoot: string): Set<string>;
16
1
  /**
17
2
  * Scenes pack compiler.
18
3
  *
19
- * Walks the content tree and compiles every map note into one Scene, resolving
20
- * what one note says about another through an index built before any scene is
21
- * written. It also writes one Adventure per place, bundling those scenes with
22
- * the JournalEntries their prose compiled into, which is what makes a pinned
23
- * scene's id-based references resolve on import.
4
+ * Compiles every map note's exported Scene, and writes one Adventure per place
5
+ * whose scenes carry pins, bundling those scenes with the JournalEntries their
6
+ * prose compiled into.
24
7
  */
25
8
  export class Scenes extends BasePackCompiler {
26
- constructor({ contentBase, assetsBase, dest, skipDirectories, companionDests, folderResolver, repoRoot, config, packName, bundleSourceDirs, corpus, }: {
9
+ constructor({ contentBase, assetsBase, dest, skipDirectories, companionDests, folderResolver, packName, corpus, }: {
27
10
  contentBase: any;
28
11
  assetsBase: any;
29
12
  dest: any;
30
13
  skipDirectories: any;
31
14
  companionDests?: {} | undefined;
32
15
  folderResolver?: (() => null) | undefined;
33
- repoRoot?: string | undefined;
34
- config: any;
35
16
  packName: any;
36
- bundleSourceDirs?: {} | undefined;
37
17
  corpus: any;
38
18
  });
39
19
  /** @type {string} */
@@ -44,13 +24,7 @@ export class Scenes extends BasePackCompiler {
44
24
  * @type {number}
45
25
  */
46
26
  adventureCount: number;
47
- mapConfig: any;
48
- packName: any;
49
- journalSourceDirs: any;
50
- index: Map<string, object> | undefined;
51
- effectsByAddress: Map<string, object> | undefined;
52
- knownActions: Set<string> | undefined;
53
- /** place key → `{name, img, scenes: [], journal: []}` */
27
+ /** place key → `{key, name, scenes: [], journal: [], pinned}` */
54
28
  places: Map<any, any> | undefined;
55
29
  /**
56
30
  * Bundle each pinned place into an Adventure, once every map of it has
@@ -58,7 +32,7 @@ export class Scenes extends BasePackCompiler {
58
32
  *
59
33
  * @returns {Promise<void>}
60
34
  */
61
- finish(stats: any): Promise<void>;
35
+ finish(): Promise<void>;
62
36
  /** @inheritdoc */
63
37
  reportCompiled(stats: any): void;
64
38
  #private;
@@ -182,10 +182,7 @@ export function tableUniverse(pages: object[]): Map<string, object[]>;
182
182
  * about every other page, known only once the whole tree has resolved — see
183
183
  * {@link module:engine/related-pages} — so an authored value is dropped the
184
184
  * way `aliases` is, and {@link renderPages} writes the derived block once it
185
- * holds the graph. Derived geographical and government lists are dropped for the
186
- * same reason — see {@link module:engine/holdings}. **So is `map`**: the
187
- * file a place page names is the one the build drew beside it — see
188
- * {@link module:engine/site-maps} — and a page with no drawing names none.
185
+ * holds the graph.
189
186
  *
190
187
  * @param {object} page - The page.
191
188
  * @param {object} options
@@ -219,25 +216,14 @@ export function pageFrontmatter(page: object, { decorate, webSrc, artSrc }: {
219
216
  * `doc` note's `subType` may be spelled the same as another note's `type`, and
220
217
  * `doc-gear.md` and `weapongear-gear.md` are distinct.
221
218
  *
222
- * **A page that carries a file beside itself is a leaf bundle**, `<slug>/index.md`,
223
- * because that is the one shape under which Hugo hands a page its own
224
- * resources — the map from a place, inlined by the theme through
225
- * `.Resources.Get`. The directory is the page, not a section: it holds no
226
- * `_index.md`, and the page's stated `url` keeps its address exactly where the
227
- * flat file's was.
228
- *
229
219
  * @param {{slug: string}} page - The page.
230
- * @param {object} [opts]
231
- * @param {boolean} [opts.bundle=false] - Whether the page carries a resource.
232
220
  * @returns {string} The file, relative to the mount.
233
221
  */
234
222
  export function pageDestination(page: {
235
223
  slug: string;
236
- }, { bundle }?: {
237
- bundle?: boolean | undefined;
238
224
  }): string;
239
225
  /** Transform one content page without writing the site mount. */
240
- export function renderSitePage(page: any, { index, foreign, universe, pass, decorate, linkable, sqlTables, config, artIndex, figuresByAddress, }: {
226
+ export function renderSitePage(page: any, { index, foreign, universe, pass, decorate, linkable, sqlTables, config, artIndex, figuresByAddress, events, drawings, }: {
241
227
  index: any;
242
228
  foreign: any;
243
229
  universe: any;
@@ -248,6 +234,8 @@ export function renderSitePage(page: any, { index, foreign, universe, pass, deco
248
234
  config: any;
249
235
  artIndex: any;
250
236
  figuresByAddress?: Map<any, any> | undefined;
237
+ events: any;
238
+ drawings?: Map<any, any> | undefined;
251
239
  }): {
252
240
  page: any;
253
241
  body: string;
@@ -311,25 +299,23 @@ export function renderSitePage(page: any, { index, foreign, universe, pass, deco
311
299
  * point the resolver answers, and inverted once between them. Nothing is
312
300
  * resolved twice.
313
301
  *
314
- * **A map is written with its page.** The drawing from a place is made before
302
+ * **A map is set inline in its page.** The drawing from a place is made before
315
303
  * this render — see {@link module:engine/site-maps} — and handed in keyed by
316
- * page URL; the page that owns one is written as a leaf bundle, the file is
317
- * copied beside it, and the front matter names it as `map`. Every other page
318
- * is written flat, and carries no such key.
304
+ * the file name the page's **From here** section names.
319
305
  *
320
306
  * @param {object[]} pages - Every page.
321
307
  * @param {object} options - Everything the render needs. `homepages` is the
322
308
  * homepage as the index knows it — `{ fm, body, url, title }` — which takes
323
309
  * no part in the render and every part in the graph: a content page links
324
310
  * it by wikilink, and its own markdown links name content pages. `maps` is
325
- * each drawing by the URL of the page that carries it.
311
+ * each drawing by the file name a **From here** section names.
326
312
  * @returns {{written: number, byKind: Record<string, number>, tableErrors: object[],
327
313
  * wikiErrors: object[], imageErrors: object[], embedErrors: object[],
328
314
  * related: Map<string, import("./related-pages.mjs").Related>,
329
315
  * maps: number}} `related`
330
316
  * is keyed by page URL, and holds the homepage's block beside every content
331
317
  * page's, so the caller can write it on the page this render does not.
332
- * `maps` counts the pages written with one.
318
+ * `maps` counts the pages carrying a map.
333
319
  */
334
320
  export function renderPages(pages: object[], options: object): {
335
321
  written: number;