spine-rigc 2.58.0 → 2.58.1
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/README.md +1 -1
- package/docs/AUTHORING.md +15 -8
- package/package.json +1 -1
- package/skills/rigc/SKILL.md +8 -5
- package/skills/rigc-face/SKILL.md +8 -5
- package/skills/rigc-ingest/SKILL.md +8 -5
- package/skills/rigc-motion/SKILL.md +8 -5
- package/skills/rigc-rigging/SKILL.md +8 -5
- package/src/cli/core_commands.ts +6 -5
- package/src/cli/shared.ts +9 -4
- package/src/guide.ts +6 -3
package/README.md
CHANGED
|
@@ -612,7 +612,7 @@ commands take it and what its default is.
|
|
|
612
612
|
| `bonedist --candidate … --reference … --bones …` | per-frame, per-bone world-transform distance against another skeleton — the ladder's stage 3, run on its own. `--bones <correspondence.json \| identity>` is required rather than defaulted: a candidate is entitled to its own bone names, so the pairing is stated |
|
|
613
613
|
| `check --candidate <dir> --frames <dir> [--out <dir>]` | the candidate against reference pictures — the only instrument here that can see a *wrong animation*. `--out` also writes, for every frame the table lists, the picture its figures came from: reference, candidate, difference and overlay at native size |
|
|
614
614
|
| `bench <rung> --candidate <dir>` | one rung of the benchmark ladder |
|
|
615
|
-
| `guide <RULE>` / `guide §<n>[.<m>[.<k>]]` | the guide's row for the rule a failure line names — every `FAIL` line, `vote --record` refusal
|
|
615
|
+
| `guide <RULE>` / `guide §<n>[.<m>[.<k>]] [--all]` | the guide's row for the rule a failure line names — every `FAIL` line, `vote --record` refusal, `ingest` finding and coded compile error ends with ` (see rigc guide <RULE>)`; only legacy uncoded library errors point at `§5.1` — or a section's heading, own prose and subsection index, read from the installed `docs/AUTHORING.md` when it runs. `--all` includes the subsection bodies; a leaf prints its full text either way. Sizes describe full ledger spans. `--all` with a rule is refused, exit 2; an unknown name is refused with the nearest real ones, exit 1 |
|
|
616
616
|
| `skills install [--dir …] [--copy]` | links every agent skill the package ships into `.agents/skills` (or `--dir`) as relative symlinks, or copies them with `--copy` — where Codex, Gemini CLI and Antigravity look. A second run has nothing to do; an entry already there that is not this command's is refused by name and nothing is written |
|
|
617
617
|
|
|
618
618
|
`diff`, `bonedist`, `check` and `bench` measure against something you were given; the
|
package/docs/AUTHORING.md
CHANGED
|
@@ -296,7 +296,8 @@ for `vote` (default `ballot.html`).
|
|
|
296
296
|
|
|
297
297
|
`guide` reads this page rather than a rig: `rigc guide <RULE>` prints the row of §5
|
|
298
298
|
(or of `docs/INGEST.md`'s finding-code table) for the rule a failure line names, and
|
|
299
|
-
`rigc guide §<n>`
|
|
299
|
+
`rigc guide §<n>` its heading, own prose and subsection index; `--all` also prints
|
|
300
|
+
the subsections' bodies. A leaf prints its full text either way — §5 says when to reach for it.
|
|
300
301
|
|
|
301
302
|
`skills install` is the other command that is not about a rig: it puts the agent
|
|
302
303
|
skills the package ships where an agent host looks for them. Run it through the
|
|
@@ -6787,14 +6788,18 @@ Failures arrive in two layers, and they read differently.
|
|
|
6787
6788
|
` (see rigc guide <RULE>)` — a gate's `FAIL` line, a `vote --record` refusal and an
|
|
6788
6789
|
`ingest` finding. `rigc guide <RULE>` prints that rule's row(s), each under the file,
|
|
6789
6790
|
the section and the heading it sits in, read from the shipped guide when it runs;
|
|
6790
|
-
`rigc guide §<n>` prints
|
|
6791
|
-
sizes
|
|
6792
|
-
|
|
6791
|
+
`rigc guide §<n>` prints the section's heading, its own prose and an index of its
|
|
6792
|
+
subsections with their sizes. `rigc guide §<n> --all` also prints those subsections'
|
|
6793
|
+
bodies; a section without subsections prints its full text either way. The header
|
|
6794
|
+
and index sizes describe the full spans in this ledger, including subsection bodies.
|
|
6795
|
+
`rigc guide §<n>.<m>` addresses the m-th `###` under it and `rigc guide §<n>.<m>.<k>` the
|
|
6796
|
+
k-th `####` under that; both take `--all` too — so a citation such as §4.5.1 here is a command. A name the
|
|
6793
6797
|
guide does not have is refused by a rule of its own — `GUIDE_RULE_KNOWN` with the
|
|
6794
6798
|
three nearest real names, `GUIDE_SECTION_KNOWN` with the sections that do exist —
|
|
6795
|
-
on stderr, exit 1 (§5.5). A compile error
|
|
6796
|
-
|
|
6797
|
-
` (see rigc guide §5.1)
|
|
6799
|
+
on stderr, exit 1 (§5.5). A compile error carries a stable `CE_` code and points
|
|
6800
|
+
at that code's one row in §5.1. Only a legacy uncoded library error ends with
|
|
6801
|
+
` (see rigc guide §5.1)`. `--all` takes a section address; with a rule name it is
|
|
6802
|
+
a usage refusal, exit 2 — omit it to read the row.
|
|
6798
6803
|
|
|
6799
6804
|
📥 **A third surface is `ingest`'s, and it is not a failure at all.** What a skeleton
|
|
6800
6805
|
holds and the spec format cannot say is **recorded** rather than refused — one coded
|
|
@@ -6830,7 +6835,9 @@ Library callers may still construct an uncoded `CompileError`; only that legacy
|
|
|
6830
6835
|
case points at `§5.1`. `NotImplementedError` keeps its class and the same pointer.
|
|
6831
6836
|
|
|
6832
6837
|
Use `rigc guide §5.1.<k>` for a whole numbered `####` group; every group is at most
|
|
6833
|
-
30,000 UTF-8 bytes including the command's heading.
|
|
6838
|
+
30,000 UTF-8 bytes including the command's heading. `rigc guide §5.1` prints this
|
|
6839
|
+
introduction and the group index, also at most 30,000 printed UTF-8 bytes;
|
|
6840
|
+
`rigc guide §5.1 --all` explicitly asks for every group's body. The guide remains one ledger:
|
|
6834
6841
|
the command reads these rows at call time, without a generated copy. Unknown
|
|
6835
6842
|
codes are refused with the three nearest real names and exit 1. `<value>` and
|
|
6836
6843
|
other angle-bracket placeholders below stand for values supplied by the input;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spine-rigc",
|
|
3
|
-
"version": "2.58.
|
|
3
|
+
"version": "2.58.1",
|
|
4
4
|
"description": "AI-authored 2D rigging and animation, verified before it is written. rigc compiles a rig spec into skeleton data in the Spine 4.3 format, gates it with named assertions held to a spine-core round trip's verdicts, and emits nothing that fails. Ships as an agent skill.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/skills/rigc/SKILL.md
CHANGED
|
@@ -16,11 +16,14 @@ whole interface, and this skill only says which of them to open.
|
|
|
16
16
|
|
|
17
17
|
📖 **A failure line ends with the command that prints its row of the guide** —
|
|
18
18
|
` (see rigc guide <RULE>)`. Run that command first, before reading anything else:
|
|
19
|
-
it prints that rule's row of the shipped guide and nothing else
|
|
20
|
-
(and `§<n>.<m>`, `§<n>.<m>.<k>`)
|
|
21
|
-
|
|
22
|
-
prints
|
|
23
|
-
|
|
19
|
+
it prints that rule's row of the shipped guide and nothing else. `rigc guide §<n>`
|
|
20
|
+
(and `§<n>.<m>`, `§<n>.<m>.<k>`) prints the section's heading, own prose and
|
|
21
|
+
subsection index from `docs/AUTHORING.md`; add `--all` to include subsection
|
|
22
|
+
bodies. A leaf prints its full text either way. Sizes describe full ledger spans;
|
|
23
|
+
`--all` with a rule name is refused, exit 2. A compile error points at its stable
|
|
24
|
+
`CE_` code row. `rigc guide §5.1.<k>` prints a numbered compile-error group of
|
|
25
|
+
at most 30,000 UTF-8 bytes, and `rigc guide §5.1` prints the introduction and
|
|
26
|
+
index within that same limit; only legacy uncoded library errors point at `§5.1`.
|
|
24
27
|
|
|
25
28
|
## Non-negotiables
|
|
26
29
|
|
|
@@ -14,11 +14,14 @@ it will not do for you.
|
|
|
14
14
|
|
|
15
15
|
📖 **A failure line ends with the command that prints its row of the guide** —
|
|
16
16
|
` (see rigc guide <RULE>)`. Run that command first, before reading anything else:
|
|
17
|
-
it prints that rule's row of the shipped guide and nothing else
|
|
18
|
-
(and `§<n>.<m>`, `§<n>.<m>.<k>`)
|
|
19
|
-
|
|
20
|
-
prints
|
|
21
|
-
|
|
17
|
+
it prints that rule's row of the shipped guide and nothing else. `rigc guide §<n>`
|
|
18
|
+
(and `§<n>.<m>`, `§<n>.<m>.<k>`) prints the section's heading, own prose and
|
|
19
|
+
subsection index from `docs/AUTHORING.md`; add `--all` to include subsection
|
|
20
|
+
bodies. A leaf prints its full text either way. Sizes describe full ledger spans;
|
|
21
|
+
`--all` with a rule name is refused, exit 2. A compile error points at its stable
|
|
22
|
+
`CE_` code row. `rigc guide §5.1.<k>` prints a numbered compile-error group of
|
|
23
|
+
at most 30,000 UTF-8 bytes, and `rigc guide §5.1` prints the introduction and
|
|
24
|
+
index within that same limit; only legacy uncoded library errors point at `§5.1`.
|
|
22
25
|
|
|
23
26
|
## Non-negotiables
|
|
24
27
|
|
|
@@ -15,11 +15,14 @@ not do for you.
|
|
|
15
15
|
|
|
16
16
|
📖 **A failure line ends with the command that prints its row of the guide** —
|
|
17
17
|
` (see rigc guide <RULE>)`. Run that command first, before reading anything else:
|
|
18
|
-
it prints that rule's row of the shipped guide and nothing else
|
|
19
|
-
(and `§<n>.<m>`, `§<n>.<m>.<k>`)
|
|
20
|
-
|
|
21
|
-
prints
|
|
22
|
-
|
|
18
|
+
it prints that rule's row of the shipped guide and nothing else. `rigc guide §<n>`
|
|
19
|
+
(and `§<n>.<m>`, `§<n>.<m>.<k>`) prints the section's heading, own prose and
|
|
20
|
+
subsection index from `docs/AUTHORING.md`; add `--all` to include subsection
|
|
21
|
+
bodies. A leaf prints its full text either way. Sizes describe full ledger spans;
|
|
22
|
+
`--all` with a rule name is refused, exit 2. A compile error points at its stable
|
|
23
|
+
`CE_` code row. `rigc guide §5.1.<k>` prints a numbered compile-error group of
|
|
24
|
+
at most 30,000 UTF-8 bytes, and `rigc guide §5.1` prints the introduction and
|
|
25
|
+
index within that same limit; only legacy uncoded library errors point at `§5.1`.
|
|
23
26
|
|
|
24
27
|
## Non-negotiables
|
|
25
28
|
|
|
@@ -15,11 +15,14 @@ not do for you.
|
|
|
15
15
|
|
|
16
16
|
📖 **A failure line ends with the command that prints its row of the guide** —
|
|
17
17
|
` (see rigc guide <RULE>)`. Run that command first, before reading anything else:
|
|
18
|
-
it prints that rule's row of the shipped guide and nothing else
|
|
19
|
-
(and `§<n>.<m>`, `§<n>.<m>.<k>`)
|
|
20
|
-
|
|
21
|
-
prints
|
|
22
|
-
|
|
18
|
+
it prints that rule's row of the shipped guide and nothing else. `rigc guide §<n>`
|
|
19
|
+
(and `§<n>.<m>`, `§<n>.<m>.<k>`) prints the section's heading, own prose and
|
|
20
|
+
subsection index from `docs/AUTHORING.md`; add `--all` to include subsection
|
|
21
|
+
bodies. A leaf prints its full text either way. Sizes describe full ledger spans;
|
|
22
|
+
`--all` with a rule name is refused, exit 2. A compile error points at its stable
|
|
23
|
+
`CE_` code row. `rigc guide §5.1.<k>` prints a numbered compile-error group of
|
|
24
|
+
at most 30,000 UTF-8 bytes, and `rigc guide §5.1` prints the introduction and
|
|
25
|
+
index within that same limit; only legacy uncoded library errors point at `§5.1`.
|
|
23
26
|
|
|
24
27
|
## Non-negotiables
|
|
25
28
|
|
|
@@ -14,11 +14,14 @@ will not do for you.
|
|
|
14
14
|
|
|
15
15
|
📖 **A failure line ends with the command that prints its row of the guide** —
|
|
16
16
|
` (see rigc guide <RULE>)`. Run that command first, before reading anything else:
|
|
17
|
-
it prints that rule's row of the shipped guide and nothing else
|
|
18
|
-
(and `§<n>.<m>`, `§<n>.<m>.<k>`)
|
|
19
|
-
|
|
20
|
-
prints
|
|
21
|
-
|
|
17
|
+
it prints that rule's row of the shipped guide and nothing else. `rigc guide §<n>`
|
|
18
|
+
(and `§<n>.<m>`, `§<n>.<m>.<k>`) prints the section's heading, own prose and
|
|
19
|
+
subsection index from `docs/AUTHORING.md`; add `--all` to include subsection
|
|
20
|
+
bodies. A leaf prints its full text either way. Sizes describe full ledger spans;
|
|
21
|
+
`--all` with a rule name is refused, exit 2. A compile error points at its stable
|
|
22
|
+
`CE_` code row. `rigc guide §5.1.<k>` prints a numbered compile-error group of
|
|
23
|
+
at most 30,000 UTF-8 bytes, and `rigc guide §5.1` prints the introduction and
|
|
24
|
+
index within that same limit; only legacy uncoded library errors point at `§5.1`.
|
|
22
25
|
|
|
23
26
|
## Non-negotiables
|
|
24
27
|
|
package/src/cli/core_commands.ts
CHANGED
|
@@ -2017,27 +2017,28 @@ export function cmdSkills(flags: Record<string, string>, positional: string[]):
|
|
|
2017
2017
|
// ---------------------------------------------------------------------------
|
|
2018
2018
|
|
|
2019
2019
|
/**
|
|
2020
|
-
* `rigc guide <RULE>` / `rigc guide §<n>[.<m>]`: a slice of the `docs/AUTHORING.md`
|
|
2020
|
+
* `rigc guide <RULE>` / `rigc guide §<n>[.<m>[.<k>]] [--all]`: a slice of the `docs/AUTHORING.md`
|
|
2021
2021
|
* this package ships, read now — never a copy (`src/guide.ts` says why). A
|
|
2022
2022
|
* finding code's table is read from the shipped document it lives in, and the
|
|
2023
2023
|
* answer names that file.
|
|
2024
2024
|
*/
|
|
2025
2025
|
export function cmdGuide(flags: Record<string, string>, positional: string[]): void {
|
|
2026
|
-
const flagged = Object.keys(flags);
|
|
2027
|
-
if (flagged.length > 0) throw new UsageError(`guide takes
|
|
2026
|
+
const flagged = Object.keys(flags).filter((flag) => flag !== 'all');
|
|
2027
|
+
if (flagged.length > 0) throw new UsageError(`guide takes only --all, and ${flagged.map((f) => `--${f}`).join(', ')} was given — name one rule or one §section`);
|
|
2028
2028
|
if (positional.length !== 1) {
|
|
2029
2029
|
throw new UsageError(
|
|
2030
2030
|
positional.length === 0
|
|
2031
|
-
? 'guide takes one rule name — the one a failure line names before its colon — or one §<n> / §<n>.<m>'
|
|
2031
|
+
? 'guide takes one rule name — the one a failure line names before its colon — or one §<n> / §<n>.<m> / §<n>.<m>.<k>'
|
|
2032
2032
|
: `guide takes one rule name or one §section, and ${positional.length} were given: ${positional.map((p) => JSON.stringify(p)).join(', ')}`,
|
|
2033
2033
|
);
|
|
2034
2034
|
}
|
|
2035
|
+
if (flags.all !== undefined && !positional[0].startsWith('§')) throw new UsageError(`guide --all takes a §section, and ${JSON.stringify(positional[0])} is a rule name — omit --all to read its row`);
|
|
2035
2036
|
const elsewhere: Record<string, string> = {};
|
|
2036
2037
|
for (const table of GUIDE_RULE_TABLES_ELSEWHERE) {
|
|
2037
2038
|
const path = join(PACKAGE_ROOT, table.file);
|
|
2038
2039
|
if (existsSync(path)) elsewhere[table.file] = readFileSync(path, 'utf8');
|
|
2039
2040
|
}
|
|
2040
|
-
const answer = guideAnswer(positional[0], { guide: readFileSync(join(PACKAGE_ROOT, GUIDE_FILE), 'utf8'), elsewhere });
|
|
2041
|
+
const answer = guideAnswer(positional[0], { guide: readFileSync(join(PACKAGE_ROOT, GUIDE_FILE), 'utf8'), elsewhere }, { all: flags.all !== undefined });
|
|
2041
2042
|
if (!answer.ok) throw new GuideError(refusalLine(answer.rule, answer.detail));
|
|
2042
2043
|
for (const line of answer.lines) console.log(line);
|
|
2043
2044
|
}
|
package/src/cli/shared.ts
CHANGED
|
@@ -132,7 +132,7 @@ export { PACKAGE_ROOT, readPackageMeta, readVersion };
|
|
|
132
132
|
* needs a value` (issue #328). `CLI10`/`CLI11` in `selftest.ts` now hold the two
|
|
133
133
|
* halves together by reading `--help` rather than by naming a flag.
|
|
134
134
|
*/
|
|
135
|
-
const BOOLEAN_FLAGS = new Set(['all-frames', 'all-bones', 'help', 'copy-images', 'again', 'pack', 'copy', 'geometry', 'folds', 'accept-skeleton-differences', 'keep-pages', 'dim']);
|
|
135
|
+
const BOOLEAN_FLAGS = new Set(['all', 'all-frames', 'all-bones', 'help', 'copy-images', 'again', 'pack', 'copy', 'geometry', 'folds', 'accept-skeleton-differences', 'keep-pages', 'dim']);
|
|
136
136
|
|
|
137
137
|
/**
|
|
138
138
|
* The flags a command is allowed to spell more than once.
|
|
@@ -1164,6 +1164,7 @@ const FLAG_MEANINGS: Record<string, string> = {
|
|
|
1164
1164
|
ballot: `the ballot the --record'd vote answers (default \`${DEFAULT_BALLOT}\`); its embedded manifest is what the vote is checked against`,
|
|
1165
1165
|
ledger: `the append-only JSONL the vote lands in (default \`${DEFAULT_LEDGER}\`)`,
|
|
1166
1166
|
again: 'record a second vote on a ballot the ledger already has; without it, a repeat is refused rather than doubled',
|
|
1167
|
+
all: 'guide §section only: include its subsection bodies; without it, a section with subsections prints its heading, own prose and subsection index; a leaf prints its full text either way',
|
|
1167
1168
|
dir:
|
|
1168
1169
|
`the directory to install into, resolved against your working directory (default \`${DEFAULT_SKILLS_DIR}\`, the ` +
|
|
1169
1170
|
'workspace directory Codex, Gemini CLI and Antigravity read skills from)',
|
|
@@ -1858,13 +1859,17 @@ export const COMMANDS: CommandDoc[] = [
|
|
|
1858
1859
|
spineFormat: false,
|
|
1859
1860
|
usage: [
|
|
1860
1861
|
'rigc guide <RULE> (the guide\'s row for the rule a failure line names — the line ends with this command)',
|
|
1861
|
-
'rigc guide §<n> | §<n>.<m> | §<n>.<m>.<k> (
|
|
1862
|
+
'rigc guide §<n> | §<n>.<m> | §<n>.<m>.<k> [--all] (a section\'s own prose and subsection index; --all includes their bodies)',
|
|
1862
1863
|
],
|
|
1863
|
-
flags: [],
|
|
1864
|
+
flags: ['all'],
|
|
1864
1865
|
notes: [
|
|
1865
1866
|
'guide reads the docs/AUTHORING.md this command ships with, at the moment it runs, and',
|
|
1866
1867
|
'prints a slice of it — the row(s) whose first cell names the rule, each under the',
|
|
1867
|
-
'file, section and heading it sits in, or
|
|
1868
|
+
'file, section and heading it sits in, or a section\'s heading, own prose and child index.',
|
|
1869
|
+
'§<n> is ## <n>., §<n>.<m> the m-th ### under it, §<n>.<m>.<k> the k-th #### under that.',
|
|
1870
|
+
'--all includes the subsection bodies; a leaf prints its full text either way. The',
|
|
1871
|
+
'header and index sizes describe full ledger spans. --all with a rule is refused.',
|
|
1872
|
+
'An ingest finding',
|
|
1868
1873
|
'code\'s row lives in docs/INGEST.md\'s finding-code table, and its answer names that',
|
|
1869
1874
|
'file. A name the guide does not have is refused with the nearest real names, exit 1.',
|
|
1870
1875
|
],
|
package/src/guide.ts
CHANGED
|
@@ -380,10 +380,12 @@ function childrenOf(sections: readonly GuideSection[], address: string | null):
|
|
|
380
380
|
*
|
|
381
381
|
* - a rule: per row, `docs/AUTHORING.md §<addr>, line <N> — under "<heading>"`, then the row verbatim;
|
|
382
382
|
* - a section: `docs/AUTHORING.md §<addr> "<title>", lines <a>–<b>, <X.X> KB`, then — when it has children — one
|
|
383
|
-
* `§<addr> <X.X KB> <title>` line per child, then
|
|
383
|
+
* `§<addr> <X.X KB> <title>` line per child, then its heading and own prose;
|
|
384
|
+
* `all` includes its children's bodies too. A leaf is always printed verbatim.
|
|
385
|
+
* The header and index sizes describe the full ledger spans, not the shortened answer;
|
|
384
386
|
* - an unknown rule or section: a refusal by `GUIDE_RULE_KNOWN` / `GUIDE_SECTION_KNOWN`.
|
|
385
387
|
*/
|
|
386
|
-
export function guideAnswer(asked: string, texts: GuideTexts): GuideAnswer {
|
|
388
|
+
export function guideAnswer(asked: string, texts: GuideTexts, options: { all?: boolean } = {}): GuideAnswer {
|
|
387
389
|
const sections = guideSections(texts.guide);
|
|
388
390
|
if (asked.startsWith('§')) {
|
|
389
391
|
const address = asked.slice(1);
|
|
@@ -401,10 +403,11 @@ export function guideAnswer(asked: string, texts: GuideTexts): GuideAnswer {
|
|
|
401
403
|
detail: `"${asked}" — no such section; the deepest that exists is ${where}, whose sections are: ${kids.length === 0 ? 'none' : kids.join(', ')}`,
|
|
402
404
|
};
|
|
403
405
|
}
|
|
404
|
-
const body = texts.guide.split('\n').slice(section.firstLine - 1, section.lastLine).join('\n').replace(/\n+$/, '');
|
|
405
406
|
const lines = [`${GUIDE_FILE} §${section.address} "${section.heading.title}", lines ${section.firstLine}–${section.lastLine}, ${kb(section.end - section.start)}`];
|
|
406
407
|
// A chapter lists its ###, a ### its #### — each with the address that prints it, its size and its title.
|
|
407
408
|
const subs = childrenOf(sections, section.address);
|
|
409
|
+
const lastLine = !options.all && subs.length > 0 ? subs[0].firstLine - 1 : section.lastLine;
|
|
410
|
+
const body = texts.guide.split('\n').slice(section.firstLine - 1, lastLine).join('\n').replace(/\n+$/, '');
|
|
408
411
|
const wide = Math.max(0, ...subs.map((sub) => sub.address.length + 1));
|
|
409
412
|
const wideKb = Math.max(0, ...subs.map((sub) => kb(sub.end - sub.start).length));
|
|
410
413
|
for (const sub of subs) lines.push(`${`§${sub.address}`.padEnd(wide)} ${kb(sub.end - sub.start).padStart(wideKb)} ${sub.heading.title}`);
|