@lexbuild/usc 1.9.4 → 1.10.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/README.md +81 -41
- package/dist/index.d.ts +46 -7
- package/dist/index.js +50 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
1
|
# @lexbuild/usc
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@lexbuild/usc)
|
|
4
|
-
[](https://github.com/chris-c-thomas/LexBuild)
|
|
4
|
+
[](https://github.com/chris-c-thomas/LexBuild/blob/main/LICENSE)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Converts official [USLM XML](https://uscode.house.gov/download/resources/USLM-User-Guide.pdf) from the [Office of the Law Revision Counsel](https://uscode.house.gov/) (OLRC) into structured Markdown optimized for AI, RAG pipelines, and semantic search. Includes a downloader that auto-detects the latest OLRC release point.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
> **Tip:** For command-line usage, install [`@lexbuild/cli`](https://www.npmjs.com/package/@lexbuild/cli) instead. This package is the programmatic API.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
npm install @lexbuild/usc
|
|
14
|
+
# or
|
|
15
|
+
pnpm add @lexbuild/usc
|
|
14
16
|
```
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
**Peer dependency:** [`@lexbuild/core`](https://www.npmjs.com/package/@lexbuild/core) (installed automatically via workspace protocol in the monorepo).
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Download and Convert
|
|
19
23
|
|
|
20
24
|
```ts
|
|
21
|
-
import { convertTitle } from "@lexbuild/usc";
|
|
25
|
+
import { downloadTitles, convertTitle } from "@lexbuild/usc";
|
|
26
|
+
|
|
27
|
+
// Download Title 1 (auto-detects latest OLRC release point)
|
|
28
|
+
const download = await downloadTitles({
|
|
29
|
+
outputDir: "./downloads/usc/xml",
|
|
30
|
+
titles: [1],
|
|
31
|
+
});
|
|
32
|
+
console.log(`Release point: ${download.releasePoint}`);
|
|
22
33
|
|
|
34
|
+
// Convert to section-level Markdown
|
|
23
35
|
const result = await convertTitle({
|
|
24
36
|
input: "./downloads/usc/xml/usc01.xml",
|
|
25
37
|
output: "./output",
|
|
26
|
-
granularity: "section",
|
|
38
|
+
granularity: "section",
|
|
27
39
|
linkStyle: "plaintext",
|
|
28
40
|
includeSourceCredits: true,
|
|
29
41
|
includeNotes: true,
|
|
@@ -33,29 +45,28 @@ const result = await convertTitle({
|
|
|
33
45
|
dryRun: false,
|
|
34
46
|
});
|
|
35
47
|
|
|
36
|
-
console.log(
|
|
37
|
-
console.log(`Chapters: ${result.chapterCount}`);
|
|
38
|
-
console.log(`Estimated tokens: ${result.totalTokenEstimate}`);
|
|
48
|
+
console.log(`${result.sectionsWritten} sections, ${result.totalTokenEstimate} est. tokens`);
|
|
39
49
|
```
|
|
40
50
|
|
|
41
|
-
###
|
|
51
|
+
### Release Point Detection
|
|
42
52
|
|
|
43
53
|
```ts
|
|
44
|
-
import {
|
|
54
|
+
import { detectLatestReleasePoint } from "@lexbuild/usc";
|
|
45
55
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
56
|
+
const info = await detectLatestReleasePoint();
|
|
57
|
+
if (info) {
|
|
58
|
+
console.log(`Latest: ${info.releasePoint}`); // e.g., "119-80"
|
|
59
|
+
console.log(`Description: ${info.description}`); // e.g., "Public Law 119-80 (03/15/2026)"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Pin a Specific Release Point
|
|
51
64
|
|
|
52
|
-
|
|
53
|
-
const
|
|
65
|
+
```ts
|
|
66
|
+
const result = await downloadTitles({
|
|
54
67
|
outputDir: "./downloads/usc/xml",
|
|
68
|
+
releasePoint: "119-73not60", // Override auto-detection
|
|
55
69
|
});
|
|
56
|
-
|
|
57
|
-
console.log(`Downloaded ${result.files.length} files`);
|
|
58
|
-
console.log(`Release point: ${result.releasePoint}`);
|
|
59
70
|
```
|
|
60
71
|
|
|
61
72
|
## API Reference
|
|
@@ -64,40 +75,69 @@ console.log(`Release point: ${result.releasePoint}`);
|
|
|
64
75
|
|
|
65
76
|
| Export | Description |
|
|
66
77
|
|--------|-------------|
|
|
67
|
-
| `convertTitle(options)` | Convert a USC XML file to
|
|
68
|
-
| `downloadTitles(options)` | Download USC XML from OLRC |
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
78
|
+
| `convertTitle(options)` | Convert a USC XML file to Markdown at any granularity |
|
|
79
|
+
| `downloadTitles(options)` | Download USC XML from OLRC (auto-detects latest release point) |
|
|
80
|
+
| `detectLatestReleasePoint()` | Scrape the OLRC download page for the current release point |
|
|
81
|
+
| `buildDownloadUrl(titleNumber, releasePoint)` | Build download URL for a single title zip |
|
|
82
|
+
| `buildAllTitlesUrl(releasePoint)` | Build download URL for the bulk all-titles zip |
|
|
83
|
+
| `releasePointToPath(releasePoint)` | Convert `"119-73not60"` → `"119/73not60"` |
|
|
84
|
+
| `isAllTitles(titles)` | Check if a title list covers all 54 USC titles |
|
|
73
85
|
|
|
74
86
|
### Types
|
|
75
87
|
|
|
76
88
|
| Export | Description |
|
|
77
89
|
|--------|-------------|
|
|
78
|
-
| `ConvertOptions` | Options for `convertTitle()` |
|
|
79
|
-
| `ConvertResult` |
|
|
80
|
-
| `DownloadOptions` | Options for `downloadTitles()` |
|
|
81
|
-
| `DownloadResult` |
|
|
82
|
-
| `DownloadedFile` |
|
|
83
|
-
| `DownloadError` |
|
|
90
|
+
| `ConvertOptions` | Options for `convertTitle()` — input, output, granularity, link style, note filters |
|
|
91
|
+
| `ConvertResult` | Conversion result — sections written, chapters, files, token estimate, memory |
|
|
92
|
+
| `DownloadOptions` | Options for `downloadTitles()` — output dir, titles, optional release point |
|
|
93
|
+
| `DownloadResult` | Download result — release point used, files, errors |
|
|
94
|
+
| `DownloadedFile` | Single downloaded file metadata (title number, path, size) |
|
|
95
|
+
| `DownloadError` | Failed download metadata (title number, error message) |
|
|
96
|
+
| `ReleasePointInfo` | Detected release point with human-readable description |
|
|
84
97
|
|
|
85
98
|
### Constants
|
|
86
99
|
|
|
87
100
|
| Export | Description |
|
|
88
101
|
|--------|-------------|
|
|
89
|
-
| `
|
|
90
|
-
| `USC_TITLE_NUMBERS` | Array of valid title numbers
|
|
102
|
+
| `FALLBACK_RELEASE_POINT` | Hardcoded fallback used when auto-detection fails |
|
|
103
|
+
| `USC_TITLE_NUMBERS` | Array of valid title numbers `[1, 2, ..., 54]` |
|
|
91
104
|
|
|
92
105
|
## Output
|
|
93
106
|
|
|
94
|
-
Each title produces Markdown files with YAML frontmatter. The
|
|
107
|
+
Each title produces Markdown files with YAML frontmatter. The structure depends on granularity:
|
|
95
108
|
|
|
96
|
-
| Granularity | Output |
|
|
109
|
+
| Granularity | Output Path | Sidecar Files |
|
|
97
110
|
|---|---|---|
|
|
98
|
-
| `section` (default) | `title-
|
|
99
|
-
| `chapter` | `title-
|
|
100
|
-
| `title` | `title-
|
|
111
|
+
| `section` (default) | `usc/title-01/chapter-01/section-1.md` | `_meta.json` per chapter + title, `README.md` per title |
|
|
112
|
+
| `chapter` | `usc/title-01/chapter-01/chapter-01.md` | `_meta.json` per title, `README.md` per title |
|
|
113
|
+
| `title` | `usc/title-01.md` | Enriched frontmatter only |
|
|
114
|
+
|
|
115
|
+
## Data Source
|
|
116
|
+
|
|
117
|
+
XML is downloaded from the OLRC at [uscode.house.gov](https://uscode.house.gov/download/download.shtml). Release points are published multiple times per month as new public laws are enacted. The downloader auto-detects the latest release point from the OLRC download page; use `--release-point` (CLI) or `releasePoint` (API) to pin a specific version.
|
|
118
|
+
|
|
119
|
+
## Compatibility
|
|
120
|
+
|
|
121
|
+
- **Node.js** >= 22
|
|
122
|
+
- **ESM only** — no CommonJS build
|
|
123
|
+
- **TypeScript** — ships `.d.ts` type declarations
|
|
124
|
+
|
|
125
|
+
## Monorepo Context
|
|
126
|
+
|
|
127
|
+
Part of the [LexBuild](https://github.com/chris-c-thomas/LexBuild) monorepo. Depends on `@lexbuild/core` for XML parsing, AST types, and Markdown rendering.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pnpm turbo build --filter=@lexbuild/usc
|
|
131
|
+
pnpm turbo test --filter=@lexbuild/usc
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Related Packages
|
|
135
|
+
|
|
136
|
+
| Package | Description |
|
|
137
|
+
|---------|-------------|
|
|
138
|
+
| [`@lexbuild/cli`](https://www.npmjs.com/package/@lexbuild/cli) | CLI tool — the easiest way to use LexBuild |
|
|
139
|
+
| [`@lexbuild/core`](https://www.npmjs.com/package/@lexbuild/core) | Shared parsing, AST, and rendering infrastructure |
|
|
140
|
+
| [`@lexbuild/ecfr`](https://www.npmjs.com/package/@lexbuild/ecfr) | eCFR (Code of Federal Regulations) converter |
|
|
101
141
|
|
|
102
142
|
## License
|
|
103
143
|
|
package/dist/index.d.ts
CHANGED
|
@@ -56,15 +56,21 @@ declare function convertTitle(options: ConvertOptions): Promise<ConvertResult>;
|
|
|
56
56
|
*
|
|
57
57
|
* Downloads USC title XML zip files from the Office of the Law Revision Counsel
|
|
58
58
|
* and extracts them to a local directory.
|
|
59
|
+
*
|
|
60
|
+
* By default, auto-detects the latest release point from the OLRC download page.
|
|
61
|
+
* Falls back to a hardcoded release point if detection fails.
|
|
59
62
|
*/
|
|
60
63
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* Update this value when OLRC publishes a new release point.
|
|
64
|
-
* The release point appears in download URLs and identifies which
|
|
65
|
-
* public laws are incorporated. Format: "{congress}-{law}[not{excluded}]"
|
|
64
|
+
* Fallback OLRC release point, used when auto-detection fails.
|
|
66
65
|
*
|
|
67
|
-
*
|
|
66
|
+
* The downloader auto-detects the latest release point from the OLRC
|
|
67
|
+
* download page. This constant is only used as a last resort if the
|
|
68
|
+
* page is unreachable or its format changes.
|
|
69
|
+
*/
|
|
70
|
+
declare const FALLBACK_RELEASE_POINT = "119-73not60";
|
|
71
|
+
/**
|
|
72
|
+
* @deprecated Use `FALLBACK_RELEASE_POINT` instead.
|
|
73
|
+
* Kept for backward compatibility with existing consumers.
|
|
68
74
|
*/
|
|
69
75
|
declare const CURRENT_RELEASE_POINT = "119-73not60";
|
|
70
76
|
/** Valid USC title numbers (1-54) */
|
|
@@ -112,6 +118,9 @@ interface DownloadError {
|
|
|
112
118
|
/**
|
|
113
119
|
* Download USC title XML files from OLRC.
|
|
114
120
|
*
|
|
121
|
+
* Auto-detects the latest release point from the OLRC download page unless
|
|
122
|
+
* an explicit release point is provided via `options.releasePoint`.
|
|
123
|
+
*
|
|
115
124
|
* When all 54 titles are requested, uses the bulk `uscAll` zip for a single
|
|
116
125
|
* HTTP round-trip instead of 54 individual requests. Falls back to per-title
|
|
117
126
|
* downloads if the bulk download fails.
|
|
@@ -137,4 +146,34 @@ declare function buildAllTitlesUrl(releasePoint: string): string;
|
|
|
137
146
|
*/
|
|
138
147
|
declare function releasePointToPath(releasePoint: string): string;
|
|
139
148
|
|
|
140
|
-
|
|
149
|
+
/**
|
|
150
|
+
* OLRC release point detection.
|
|
151
|
+
*
|
|
152
|
+
* Scrapes the OLRC download page to detect the latest release point,
|
|
153
|
+
* eliminating the need to hardcode release point identifiers.
|
|
154
|
+
*/
|
|
155
|
+
/** Detected release point information */
|
|
156
|
+
interface ReleasePointInfo {
|
|
157
|
+
/** Release point identifier (e.g., "119-73not60") */
|
|
158
|
+
releasePoint: string;
|
|
159
|
+
/** Human-readable description (e.g., "Public Law 119-73 (01/23/2026) , except 119-60") */
|
|
160
|
+
description: string;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Detect the latest OLRC release point by scraping the download page.
|
|
164
|
+
*
|
|
165
|
+
* Uses two extraction strategies for redundancy:
|
|
166
|
+
* 1. Parse the release point from download URL hrefs (most reliable)
|
|
167
|
+
* 2. Fall back to parsing the release point info heading
|
|
168
|
+
*
|
|
169
|
+
* Returns `null` if the page cannot be fetched or parsed.
|
|
170
|
+
*/
|
|
171
|
+
declare function detectLatestReleasePoint(): Promise<ReleasePointInfo | null>;
|
|
172
|
+
/**
|
|
173
|
+
* Parse the release point from OLRC download page HTML.
|
|
174
|
+
*
|
|
175
|
+
* Exported for testing — prefer `detectLatestReleasePoint()` for production use.
|
|
176
|
+
*/
|
|
177
|
+
declare function parseReleasePointFromHtml(html: string): ReleasePointInfo | null;
|
|
178
|
+
|
|
179
|
+
export { CURRENT_RELEASE_POINT, type ConvertOptions, type ConvertResult, type DownloadError, type DownloadOptions, type DownloadResult, type DownloadedFile, FALLBACK_RELEASE_POINT, type ReleasePointInfo, USC_TITLE_NUMBERS, buildAllTitlesUrl, buildDownloadUrl, convertTitle, detectLatestReleasePoint, downloadTitles, isAllTitles, parseReleasePointFromHtml, releasePointToPath };
|
package/dist/index.js
CHANGED
|
@@ -732,7 +732,48 @@ import { join as join2 } from "path";
|
|
|
732
732
|
import { pipeline } from "stream/promises";
|
|
733
733
|
import { Readable } from "stream";
|
|
734
734
|
import { open as yauzlOpen } from "yauzl";
|
|
735
|
-
|
|
735
|
+
|
|
736
|
+
// src/release-points.ts
|
|
737
|
+
var OLRC_DOWNLOAD_PAGE = "https://uscode.house.gov/download/download.shtml";
|
|
738
|
+
async function detectLatestReleasePoint() {
|
|
739
|
+
let html;
|
|
740
|
+
try {
|
|
741
|
+
const response = await fetch(OLRC_DOWNLOAD_PAGE);
|
|
742
|
+
if (!response.ok) return null;
|
|
743
|
+
html = await response.text();
|
|
744
|
+
} catch {
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
return parseReleasePointFromHtml(html);
|
|
748
|
+
}
|
|
749
|
+
function parseReleasePointFromHtml(html) {
|
|
750
|
+
const urlMatch = /xml_uscAll@([\w-]+)\.zip/.exec(html);
|
|
751
|
+
if (urlMatch?.[1]) {
|
|
752
|
+
const releasePoint = urlMatch[1];
|
|
753
|
+
const description = parseDescription(html);
|
|
754
|
+
return { releasePoint, description };
|
|
755
|
+
}
|
|
756
|
+
const singleUrlMatch = /xml_usc\d{2}@([\w-]+)\.zip/.exec(html);
|
|
757
|
+
if (singleUrlMatch?.[1]) {
|
|
758
|
+
const releasePoint = singleUrlMatch[1];
|
|
759
|
+
const description = parseDescription(html);
|
|
760
|
+
return { releasePoint, description };
|
|
761
|
+
}
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
function parseDescription(html) {
|
|
765
|
+
const marker = 'class="releasepointinformation">';
|
|
766
|
+
const startIdx = html.indexOf(marker);
|
|
767
|
+
if (startIdx === -1) return "";
|
|
768
|
+
const contentStart = startIdx + marker.length;
|
|
769
|
+
const endIdx = html.indexOf("</h3>", contentStart);
|
|
770
|
+
if (endIdx === -1) return "";
|
|
771
|
+
return html.slice(contentStart, endIdx).trim();
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/downloader.ts
|
|
775
|
+
var FALLBACK_RELEASE_POINT = "119-73not60";
|
|
776
|
+
var CURRENT_RELEASE_POINT = FALLBACK_RELEASE_POINT;
|
|
736
777
|
var OLRC_BASE_URL = "https://uscode.house.gov/download/releasepoints/us/pl";
|
|
737
778
|
var USC_TITLE_NUMBERS = Array.from({ length: 54 }, (_, i) => i + 1);
|
|
738
779
|
function isAllTitles(titles) {
|
|
@@ -740,7 +781,11 @@ function isAllTitles(titles) {
|
|
|
740
781
|
return unique.size === 54 && USC_TITLE_NUMBERS.every((n) => unique.has(n));
|
|
741
782
|
}
|
|
742
783
|
async function downloadTitles(options) {
|
|
743
|
-
|
|
784
|
+
let releasePoint = options.releasePoint;
|
|
785
|
+
if (!releasePoint) {
|
|
786
|
+
const detected = await detectLatestReleasePoint();
|
|
787
|
+
releasePoint = detected?.releasePoint ?? FALLBACK_RELEASE_POINT;
|
|
788
|
+
}
|
|
744
789
|
const titles = options.titles ?? USC_TITLE_NUMBERS;
|
|
745
790
|
await mkdir2(options.outputDir, { recursive: true });
|
|
746
791
|
if (options.titles === void 0 || isAllTitles(titles)) {
|
|
@@ -935,12 +980,15 @@ async function downloadAndExtractAllTitles(releasePoint, outputDir) {
|
|
|
935
980
|
}
|
|
936
981
|
export {
|
|
937
982
|
CURRENT_RELEASE_POINT,
|
|
983
|
+
FALLBACK_RELEASE_POINT,
|
|
938
984
|
USC_TITLE_NUMBERS,
|
|
939
985
|
buildAllTitlesUrl,
|
|
940
986
|
buildDownloadUrl,
|
|
941
987
|
convertTitle,
|
|
988
|
+
detectLatestReleasePoint,
|
|
942
989
|
downloadTitles,
|
|
943
990
|
isAllTitles,
|
|
991
|
+
parseReleasePointFromHtml,
|
|
944
992
|
releasePointToPath
|
|
945
993
|
};
|
|
946
994
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/converter.ts","../src/downloader.ts"],"sourcesContent":["/**\n * USC Converter — orchestrates the full conversion pipeline for a single USC XML file.\n *\n * Creates a ReadStream → SAX Parser → AST Builder (emit at section) →\n * Markdown Renderer + Frontmatter → File Writer.\n */\n\nimport { createReadStream } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { basename } from \"node:path\";\nimport {\n XMLParser,\n ASTBuilder,\n renderDocument,\n renderSection,\n renderNode,\n generateFrontmatter,\n createLinkResolver,\n FORMAT_VERSION,\n GENERATOR,\n BIG_LEVELS,\n writeFile,\n mkdir,\n} from \"@lexbuild/core\";\nimport type {\n LevelNode,\n ASTNode,\n EmitContext,\n FrontmatterData,\n RenderOptions,\n NotesFilter,\n AncestorInfo,\n LinkResolver,\n} from \"@lexbuild/core\";\n\n/** Options for converting a USC XML file */\nexport interface ConvertOptions {\n /** Path to the input XML file */\n input: string;\n /** Output directory root */\n output: string;\n /** Output granularity: \"section\" (one file per section), \"chapter\" (sections inline), or \"title\" (entire title) */\n granularity: \"section\" | \"chapter\" | \"title\";\n /** How to render cross-references */\n linkStyle: \"relative\" | \"canonical\" | \"plaintext\";\n /** Include source credits in output */\n includeSourceCredits: boolean;\n /** Include notes in output. True = all notes (default). False = no notes. */\n includeNotes: boolean;\n /** Include editorial notes only (when includeNotes is false) */\n includeEditorialNotes: boolean;\n /** Include statutory notes only (when includeNotes is false) */\n includeStatutoryNotes: boolean;\n /** Include amendment history notes only (when includeNotes is false) */\n includeAmendments: boolean;\n /** Dry-run mode: parse and report structure without writing files */\n dryRun: boolean;\n}\n\n/** Result of a conversion */\nexport interface ConvertResult {\n /** Number of sections written (or that would be written in dry-run) */\n sectionsWritten: number;\n /** Output paths of all written files (empty in dry-run) */\n files: string[];\n /** Title number extracted from metadata */\n titleNumber: string;\n /** Title name extracted from metadata */\n titleName: string;\n /** Whether this was a dry run */\n dryRun: boolean;\n /** Chapter count */\n chapterCount: number;\n /** Estimated total tokens */\n totalTokenEstimate: number;\n /** Peak resident set size in bytes during conversion */\n peakMemoryBytes: number;\n}\n\n/** Default convert options */\nconst DEFAULTS: Omit<ConvertOptions, \"input\" | \"output\"> = {\n granularity: \"section\",\n linkStyle: \"plaintext\",\n includeSourceCredits: true,\n includeNotes: true,\n includeEditorialNotes: false,\n includeStatutoryNotes: false,\n includeAmendments: false,\n dryRun: false,\n};\n\n/** Metadata collected for a written section (used to build _meta.json) */\ninterface SectionMeta {\n identifier: string;\n number: string;\n name: string;\n /** Filename only (e.g., \"section-3598.md\" or \"section-3598-2.md\" for duplicates) */\n fileName: string;\n /** File path relative to the title directory (e.g., \"chapter-01/section-1.md\") */\n relativeFile: string;\n /** Content length in characters (for token estimation) */\n contentLength: number;\n hasNotes: boolean;\n status: string;\n /** Chapter identifier this section belongs to */\n chapterIdentifier: string;\n chapterNumber: string;\n chapterName: string;\n}\n\n/** A collected section ready to be written */\ninterface CollectedSection {\n node: LevelNode;\n context: EmitContext;\n}\n\n/**\n * Convert a single USC XML file to section-level Markdown files.\n */\nexport async function convertTitle(options: ConvertOptions): Promise<ConvertResult> {\n const opts = { ...DEFAULTS, ...options };\n const files: string[] = [];\n let peakMemory = process.memoryUsage.rss();\n let titleLevelTokenEstimate: number | undefined;\n\n // Collect emitted nodes during parsing (synchronous), write after parsing completes\n const collected: CollectedSection[] = [];\n\n // Set up the AST builder — emit level depends on granularity\n const emitAt =\n opts.granularity === \"title\"\n ? (\"title\" as const)\n : opts.granularity === \"chapter\"\n ? (\"chapter\" as const)\n : (\"section\" as const);\n const builder = new ASTBuilder({\n emitAt,\n onEmit: (node, context) => {\n collected.push({ node, context });\n },\n });\n\n // Set up the XML parser\n const parser = new XMLParser();\n parser.on(\"openElement\", (name, attrs) => builder.onOpenElement(name, attrs));\n parser.on(\"closeElement\", (name) => builder.onCloseElement(name));\n parser.on(\"text\", (text) => builder.onText(text));\n\n // Parse the XML file\n const stream = createReadStream(opts.input, \"utf-8\");\n await parser.parseStream(stream);\n peakMemory = Math.max(peakMemory, process.memoryUsage.rss());\n\n const sectionMetas: SectionMeta[] = [];\n const meta = builder.getDocumentMeta();\n\n if (opts.dryRun) {\n // Dry-run: collect metadata without writing files\n for (const { node, context } of collected) {\n if (opts.granularity === \"title\") {\n // Walk title tree → chapters → sections\n collectSectionMetasFromTree(node, context, sectionMetas);\n } else if (opts.granularity === \"chapter\") {\n // Recursively extract section metadata from chapter children (including nested big levels)\n collectChapterSectionsDryRun(node, node, context, sectionMetas);\n } else {\n if (node.numValue) {\n sectionMetas.push(buildSectionMetaDryRun(node, null, context));\n }\n }\n }\n } else if (opts.granularity === \"title\") {\n // Title-level: each emitted node is an entire title\n let titleTokenEstimate = 0;\n for (const { node, context } of collected) {\n const result = await writeWholeTitle(node, context, opts);\n files.push(result.filePath);\n titleTokenEstimate += result.totalTokenEstimate;\n for (const m of result.sectionMetas) {\n sectionMetas.push(m);\n }\n }\n // Store the accurate title-level estimate for use in ConvertResult\n titleLevelTokenEstimate = titleTokenEstimate;\n } else if (opts.granularity === \"chapter\") {\n // Chapter-level: each emitted node is a chapter containing sections\n for (const { node, context } of collected) {\n const result = await writeChapter(node, context, opts);\n if (result) {\n files.push(result.filePath);\n for (const m of result.sectionMetas) {\n sectionMetas.push(m);\n }\n }\n }\n } else {\n // Section-level with relative links: need two-pass for link resolver\n // Track duplicate section numbers per chapter to disambiguate filenames\n const sectionCounts = new Map<string, number>();\n const suffixes: (string | undefined)[] = [];\n for (const { node, context } of collected) {\n const sectionNum = node.numValue;\n if (!sectionNum) {\n suffixes.push(undefined);\n continue;\n }\n const chapterDir = buildChapterDir(context) ?? \"__root__\";\n const key = `${chapterDir}/${sectionNum}`;\n const count = (sectionCounts.get(key) ?? 0) + 1;\n sectionCounts.set(key, count);\n suffixes.push(count > 1 ? `-${count}` : undefined);\n }\n\n const linkResolver = createLinkResolver();\n for (const [i, { node, context }] of collected.entries()) {\n const sectionNum = node.numValue;\n if (sectionNum && node.identifier) {\n const filePath = buildOutputPath(context, sectionNum, opts.output, suffixes[i]);\n // For duplicates, register with the XML element @id to disambiguate\n const regId = suffixes[i] ? `${node.identifier}#${suffixes[i]}` : node.identifier;\n linkResolver.register(regId, filePath);\n // Always register the first occurrence under the canonical identifier\n if (!suffixes[i]) {\n linkResolver.register(node.identifier, filePath);\n }\n }\n }\n\n for (const [i, { node, context }] of collected.entries()) {\n const result = await writeSection(node, context, opts, linkResolver, suffixes[i]);\n if (result) {\n files.push(result.filePath);\n sectionMetas.push(result.meta);\n }\n }\n }\n\n // Extract the title heading from the first collected node\n const firstCollected = collected[0];\n const titleHeading = firstCollected\n ? opts.granularity === \"title\"\n ? firstCollected.node.heading?.trim()\n : findAncestor(firstCollected.context.ancestors, \"title\")?.heading?.trim()\n : undefined;\n\n // Generate _meta.json and README.md files (skip in dry-run)\n if (!opts.dryRun) {\n await writeMetaFiles(sectionMetas, meta, opts, titleHeading);\n }\n\n // Final memory sample\n peakMemory = Math.max(peakMemory, process.memoryUsage.rss());\n\n // Compute stats\n const chapterIds = new Set(sectionMetas.map((s) => s.chapterIdentifier).filter(Boolean));\n // For title granularity, use the accurate estimate from the full rendered body\n // (includes structural headings); for other modes, sum per-section content lengths\n const totalTokens =\n titleLevelTokenEstimate ??\n sectionMetas.reduce((sum, s) => sum + Math.ceil(s.contentLength / 4), 0);\n\n return {\n sectionsWritten:\n opts.dryRun || opts.granularity === \"title\" || opts.granularity === \"chapter\"\n ? sectionMetas.length\n : files.length,\n files,\n titleNumber: meta.docNumber ?? \"unknown\",\n titleName: titleHeading ?? meta.dcTitle ?? \"Unknown Title\",\n dryRun: opts.dryRun,\n chapterCount: chapterIds.size,\n totalTokenEstimate: totalTokens,\n peakMemoryBytes: peakMemory,\n };\n}\n\n/** Result of writing a single section */\ninterface WriteSectionResult {\n filePath: string;\n meta: SectionMeta;\n}\n\n/**\n * Write a single section to disk.\n * Returns the file path and metadata, or null if the section was skipped.\n */\nasync function writeSection(\n node: LevelNode,\n context: EmitContext,\n options: ConvertOptions,\n linkResolver?: LinkResolver | undefined,\n /** Disambiguation suffix for duplicate section numbers (e.g., \"-2\") */\n dupSuffix?: string | undefined,\n): Promise<WriteSectionResult | null> {\n const sectionNum = node.numValue;\n if (!sectionNum) return null;\n\n // Build the output file path (with optional duplicate suffix)\n const filePath = buildOutputPath(context, sectionNum, options.output, dupSuffix);\n\n // Build frontmatter data\n const frontmatter = buildFrontmatter(node, context);\n\n // Build notes filter\n const notesFilter = buildNotesFilter(options);\n\n // Build render options with link resolver for relative links\n const renderOpts: RenderOptions = {\n headingOffset: 0,\n linkStyle: options.linkStyle,\n resolveLink: linkResolver\n ? (identifier: string) => linkResolver.resolve(identifier, filePath)\n : undefined,\n notesFilter,\n };\n\n // Optionally strip source credits\n const sectionNode = options.includeSourceCredits ? node : stripSourceCredits(node);\n\n // Render the document\n const markdown = renderDocument(sectionNode, frontmatter, renderOpts);\n\n // Ensure the directory exists and write the file\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, markdown, \"utf-8\");\n\n // Collect metadata\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"0\";\n const chapterAncestor = findAncestor(context.ancestors, \"chapter\");\n const chapterDir = chapterAncestor?.numValue ? `chapter-${padTwo(chapterAncestor.numValue)}` : \"\";\n const sectionFileName = `section-${sectionNum}${dupSuffix ?? \"\"}.md`;\n const relativeFile = chapterDir ? `${chapterDir}/${sectionFileName}` : sectionFileName;\n\n const hasNotes = node.children.some((c) => c.type === \"notesContainer\" || c.type === \"note\");\n\n const sectionMeta: SectionMeta = {\n identifier: node.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: node.heading?.trim() ?? \"\",\n fileName: sectionFileName,\n relativeFile,\n contentLength: markdown.length,\n hasNotes,\n status: node.status ?? \"current\",\n chapterIdentifier: chapterAncestor?.identifier ?? \"\",\n chapterNumber: chapterAncestor?.numValue ?? \"0\",\n chapterName: chapterAncestor?.heading?.trim() ?? \"\",\n };\n\n return { filePath, meta: sectionMeta };\n}\n\n/**\n * Generate _meta.json files at title and chapter levels.\n */\nasync function writeMetaFiles(\n sectionMetas: SectionMeta[],\n docMeta: {\n dcTitle?: string | undefined;\n docNumber?: string | undefined;\n positivelaw?: boolean | undefined;\n docPublicationName?: string | undefined;\n created?: string | undefined;\n identifier?: string | undefined;\n },\n options: ConvertOptions,\n titleHeading?: string | undefined,\n): Promise<void> {\n if (sectionMetas.length === 0) return;\n if (options.granularity === \"title\") return;\n\n const docNum = docMeta.docNumber ?? \"0\";\n const titleDirName = buildTitleDirFromDocNumber(docNum);\n const titleDir = join(options.output, \"usc\", titleDirName);\n const currency = parseCurrency(docMeta.docPublicationName ?? \"\");\n\n // Group sections by chapter\n const chapterMap = new Map<string, SectionMeta[]>();\n for (const sm of sectionMetas) {\n const key = sm.chapterIdentifier || \"__no_chapter__\";\n let arr = chapterMap.get(key);\n if (!arr) {\n arr = [];\n chapterMap.set(key, arr);\n }\n arr.push(sm);\n }\n\n // Write chapter-level _meta.json files\n const chapterEntries: Array<{\n identifier: string;\n number: number;\n name: string;\n directory: string;\n sections: Array<{\n identifier: string;\n number: string;\n name: string;\n file: string;\n token_estimate: number;\n has_notes: boolean;\n status: string;\n }>;\n }> = [];\n\n for (const [chapterId, chapterSections] of chapterMap) {\n if (chapterId === \"__no_chapter__\") continue;\n\n const first = chapterSections[0];\n if (!first) continue;\n\n const chapterDir = `chapter-${padTwo(first.chapterNumber)}`;\n\n const sections = chapterSections.map((sm) => ({\n identifier: sm.identifier,\n number: sm.number,\n name: sm.name,\n file: sm.fileName,\n token_estimate: Math.ceil(sm.contentLength / 4),\n has_notes: sm.hasNotes,\n status: sm.status,\n }));\n\n const chapterMeta = {\n format_version: FORMAT_VERSION,\n identifier: chapterId,\n chapter_number: parseIntSafe(first.chapterNumber),\n chapter_name: first.chapterName,\n title_number: parseIntSafe(docNum),\n section_count: sections.length,\n sections,\n };\n\n const chapterMetaPath = join(titleDir, chapterDir, \"_meta.json\");\n await mkdir(dirname(chapterMetaPath), { recursive: true });\n await writeFile(chapterMetaPath, JSON.stringify(chapterMeta, null, 2) + \"\\n\", \"utf-8\");\n\n chapterEntries.push({\n identifier: chapterId,\n number: parseIntSafe(first.chapterNumber),\n name: first.chapterName,\n directory: chapterDir,\n sections,\n });\n }\n\n // Write title-level _meta.json\n const totalTokens = sectionMetas.reduce((sum, sm) => sum + Math.ceil(sm.contentLength / 4), 0);\n\n const releasePoint = parseFullReleasePoint(docMeta.docPublicationName ?? \"\");\n\n const titleMeta = {\n format_version: FORMAT_VERSION,\n generator: GENERATOR,\n generated_at: new Date().toISOString(),\n identifier: docMeta.identifier ?? `/us/usc/t${docNum}`,\n title_number: parseIntSafe(docNum),\n title_name: titleHeading ?? docMeta.dcTitle ?? \"\",\n positive_law: docMeta.positivelaw ?? false,\n currency,\n release_point: releasePoint,\n source_xml: basename(options.input),\n granularity: options.granularity,\n stats: {\n chapter_count: chapterEntries.length,\n section_count: sectionMetas.length,\n total_files: sectionMetas.length,\n total_tokens_estimate: totalTokens,\n },\n chapters: chapterEntries,\n };\n\n const titleMetaPath = join(titleDir, \"_meta.json\");\n await mkdir(dirname(titleMetaPath), { recursive: true });\n await writeFile(titleMetaPath, JSON.stringify(titleMeta, null, 2) + \"\\n\", \"utf-8\");\n\n // Write title-level README.md\n const readmePath = join(titleDir, \"README.md\");\n const readme = generateTitleReadme(titleMeta);\n await writeFile(readmePath, readme, \"utf-8\");\n}\n\n/**\n * Generate a human-readable README.md for a title output directory.\n */\nfunction generateTitleReadme(meta: {\n title_number: number;\n title_name: string;\n positive_law: boolean;\n currency: string;\n granularity: string;\n stats: {\n chapter_count: number;\n section_count: number;\n total_tokens_estimate: number;\n };\n chapters: Array<{\n number: number;\n name: string;\n directory: string;\n sections: Array<{\n number: string;\n name: string;\n file: string;\n status: string;\n }>;\n }>;\n}): string {\n const lines: string[] = [];\n\n lines.push(`# Title ${meta.title_number} — ${meta.title_name}`);\n lines.push(\"\");\n lines.push(`| | |`);\n lines.push(`| --- | --- |`);\n lines.push(`| **Positive Law** | ${meta.positive_law ? \"Yes\" : \"No\"} |`);\n lines.push(`| **Currency** | ${meta.currency || \"unknown\"} |`);\n lines.push(`| **Chapters** | ${meta.stats.chapter_count} |`);\n lines.push(`| **Sections** | ${meta.stats.section_count.toLocaleString()} |`);\n lines.push(`| **Est. Tokens** | ${meta.stats.total_tokens_estimate.toLocaleString()} |`);\n lines.push(`| **Granularity** | ${meta.granularity} |`);\n lines.push(\"\");\n\n // Chapter listing\n lines.push(\"## Chapters\");\n lines.push(\"\");\n\n for (const ch of meta.chapters) {\n const sectionCount = ch.sections.length;\n lines.push(`### Chapter ${ch.number} — ${ch.name}`);\n lines.push(\"\");\n lines.push(\n `${sectionCount} section${sectionCount !== 1 ? \"s\" : \"\"} · [${ch.directory}/](${ch.directory}/)`,\n );\n lines.push(\"\");\n }\n\n // Footer\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(`Generated by [LexBuild](https://github.com/chris-c-thomas/LexBuild)`);\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\n/** Result of writing a chapter file */\ninterface WriteChapterResult {\n filePath: string;\n sectionMetas: SectionMeta[];\n}\n\n/**\n * Write a chapter-level file (all sections inlined).\n * The emitted node is a chapter LevelNode whose children include section LevelNodes.\n */\nasync function writeChapter(\n chapterNode: LevelNode,\n context: EmitContext,\n options: ConvertOptions,\n): Promise<WriteChapterResult | null> {\n const chapterNum = chapterNode.numValue;\n if (!chapterNum) return null;\n\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"0\";\n const titleDir = `title-${padTwo(titleNum)}`;\n const chapterDir = `chapter-${padTwo(chapterNum)}`;\n const chapterFile = `chapter-${padTwo(chapterNum)}.md`;\n const filePath = join(options.output, \"usc\", titleDir, chapterDir, chapterFile);\n\n // Build chapter-level frontmatter\n const titleAncestor = findAncestor(context.ancestors, \"title\");\n const meta = context.documentMeta;\n const chapterName = chapterNode.heading?.trim() ?? \"\";\n const titleName = titleAncestor?.heading?.trim() ?? meta.dcTitle ?? \"\";\n const currency = parseCurrency(meta.docPublicationName ?? \"\");\n const lastUpdated = parseDate(meta.created ?? \"\");\n\n const fmData: FrontmatterData = {\n source: \"usc\",\n legal_status: meta.positivelaw ? \"official_legal_evidence\" : \"official_prima_facie\",\n identifier: chapterNode.identifier ?? `/us/usc/t${titleNum}/ch${chapterNum}`,\n title: `${titleNum} USC Chapter ${chapterNum} - ${chapterName}`,\n title_number: parseIntSafe(titleNum),\n title_name: titleName,\n section_number: chapterNum,\n section_name: chapterName,\n chapter_number: parseIntSafe(chapterNum),\n chapter_name: chapterName,\n positive_law: meta.positivelaw ?? false,\n currency,\n last_updated: lastUpdated,\n };\n\n const notesFilter = buildNotesFilter(options);\n const renderOpts: RenderOptions = {\n headingOffset: 0,\n linkStyle: options.linkStyle,\n notesFilter,\n };\n\n // Build the chapter Markdown: heading + each section rendered with H2\n const parts: string[] = [];\n parts.push(generateFrontmatter(fmData));\n parts.push(\"\");\n parts.push(`# Chapter ${chapterNum} — ${chapterName}`);\n\n // Collect section metas and render chapter children recursively\n const sectionMetas: SectionMeta[] = [];\n\n renderChapterChildren(\n chapterNode,\n 2,\n options,\n renderOpts,\n parts,\n sectionMetas,\n titleNum,\n chapterNode.identifier ?? \"\",\n chapterNum,\n chapterName,\n chapterFile,\n );\n\n const markdown = parts.join(\"\\n\") + \"\\n\";\n\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, markdown, \"utf-8\");\n\n return { filePath, sectionMetas };\n}\n\n/**\n * Recursively render children of a chapter node, traversing intermediate big levels\n * (subchapter, part, etc.) to find and render all nested sections.\n */\nfunction renderChapterChildren(\n node: LevelNode,\n headingLevel: number,\n options: ConvertOptions,\n renderOpts: RenderOptions,\n parts: string[],\n sectionMetas: SectionMeta[],\n titleNum: string,\n chapterIdentifier: string,\n chapterNum: string,\n chapterName: string,\n chapterFile: string,\n): void {\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n const sectionOpts: RenderOptions = {\n ...renderOpts,\n headingOffset: Math.min(headingLevel - 1, 5),\n };\n const sectionNode = options.includeSourceCredits ? child : stripSourceCredits(child);\n const sectionMd = renderSection(sectionNode, sectionOpts);\n parts.push(\"\");\n parts.push(sectionMd);\n\n const sectionNum = child.numValue ?? \"0\";\n const hasNotes = child.children.some((c) => c.type === \"notesContainer\" || c.type === \"note\");\n sectionMetas.push({\n identifier: child.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: child.heading?.trim() ?? \"\",\n fileName: `section-${sectionNum}.md`,\n relativeFile: `chapter-${padTwo(chapterNum)}/${chapterFile}`,\n contentLength: sectionMd.length,\n hasNotes,\n status: child.status ?? \"current\",\n chapterIdentifier,\n chapterNumber: chapterNum,\n chapterName,\n });\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n // Intermediate big level (subchapter, part, etc.) — emit heading and recurse\n const numDisplay = child.num ?? \"\";\n const heading = child.heading ? ` ${child.heading}` : \"\";\n parts.push(\"\");\n if (headingLevel <= 5) {\n const prefix = \"#\".repeat(headingLevel);\n parts.push(`${prefix} ${numDisplay}${heading}`);\n } else {\n parts.push(`**${numDisplay}${heading}**`);\n }\n\n renderChapterChildren(\n child,\n headingLevel + 1,\n options,\n renderOpts,\n parts,\n sectionMetas,\n titleNum,\n chapterIdentifier,\n chapterNum,\n chapterName,\n chapterFile,\n );\n } else {\n // Content, notes, toc, etc. — render inline\n const rendered = renderNode(child as ASTNode, renderOpts);\n if (rendered) {\n parts.push(\"\");\n parts.push(rendered);\n }\n }\n }\n}\n\n/** Result of writing a title-level file */\ninterface WriteTitleResult {\n filePath: string;\n sectionMetas: SectionMeta[];\n /** Token estimate based on full rendered body (including structural headings) */\n totalTokenEstimate: number;\n}\n\n/**\n * Write a title-level file (entire title as a single Markdown document).\n * The emitted node is the title LevelNode with all children.\n */\nasync function writeWholeTitle(\n titleNode: LevelNode,\n context: EmitContext,\n options: ConvertOptions,\n): Promise<WriteTitleResult> {\n const meta = context.documentMeta;\n const docNum = meta.docNumber ?? titleNode.numValue ?? \"0\";\n const titleNum = docNum.replace(/a$/i, \"\");\n const titleName = titleNode.heading?.trim() ?? meta.dcTitle ?? \"\";\n const currency = parseCurrency(meta.docPublicationName ?? \"\");\n const lastUpdated = parseDate(meta.created ?? \"\");\n\n const notesFilter = buildNotesFilter(options);\n const renderOpts: RenderOptions = {\n headingOffset: 0,\n linkStyle: options.linkStyle,\n notesFilter,\n };\n\n // Render title children recursively, collecting section metas\n const sectionMetas: SectionMeta[] = [];\n const bodyParts = renderTitleChildren(titleNode, 2, options, renderOpts, sectionMetas, titleNum);\n\n // Build the title Markdown body first so we can measure its total length\n const bodyMarkdownParts: string[] = [];\n const numDisplay = titleNode.num ?? \"\";\n const headingText = titleNode.heading ? ` ${titleNode.heading}` : \"\";\n bodyMarkdownParts.push(`# ${numDisplay}${headingText}`);\n bodyMarkdownParts.push(...bodyParts);\n const bodyMarkdown = bodyMarkdownParts.join(\"\\n\");\n\n // Build enriched frontmatter for title-level output\n // Use full body length (not just section content) for accurate token estimate\n const fmData: FrontmatterData = {\n source: \"usc\",\n legal_status: meta.positivelaw ? \"official_legal_evidence\" : \"official_prima_facie\",\n identifier: titleNode.identifier ?? meta.identifier ?? `/us/usc/t${titleNum}`,\n title: `Title ${titleNum} — ${titleName}`,\n title_number: parseIntSafe(titleNum),\n title_name: titleName,\n positive_law: meta.positivelaw ?? false,\n currency,\n last_updated: lastUpdated,\n chapter_count: new Set(sectionMetas.map((s) => s.chapterIdentifier).filter(Boolean)).size,\n section_count: sectionMetas.length,\n total_token_estimate: Math.ceil(bodyMarkdown.length / 4),\n };\n\n // Assemble final Markdown: frontmatter + body\n const markdown = generateFrontmatter(fmData) + \"\\n\\n\" + bodyMarkdown + \"\\n\";\n\n // Output path: output/usc/title-NN.md (or title-NN-appendix.md for appendix titles)\n const titleFile = `${buildTitleDirFromDocNumber(docNum)}.md`;\n const filePath = join(options.output, \"usc\", titleFile);\n\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, markdown, \"utf-8\");\n\n const totalTokenEstimate = Math.ceil(bodyMarkdown.length / 4);\n return { filePath, sectionMetas, totalTokenEstimate };\n}\n\n/**\n * Recursively render children of a big-level node for title-level output.\n * Returns an array of Markdown parts (each preceded by blank line).\n * Collects SectionMeta for each section encountered.\n */\nfunction renderTitleChildren(\n node: LevelNode,\n headingLevel: number,\n options: ConvertOptions,\n renderOpts: RenderOptions,\n sectionMetas: SectionMeta[],\n titleNum: string,\n currentChapter?: LevelNode | undefined,\n): string[] {\n const parts: string[] = [];\n\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n // Render section at current heading level\n // renderSection adds 1 to headingOffset, so subtract 1 to land at headingLevel\n const sectionOpts: RenderOptions = {\n ...renderOpts,\n headingOffset: Math.min(headingLevel - 1, 5),\n };\n const sectionNode = options.includeSourceCredits ? child : stripSourceCredits(child);\n const sectionMd = renderSection(sectionNode, sectionOpts);\n parts.push(\"\");\n parts.push(sectionMd);\n\n // Collect section metadata\n const sectionNum = child.numValue ?? \"0\";\n const hasNotes = child.children.some((c) => c.type === \"notesContainer\" || c.type === \"note\");\n sectionMetas.push({\n identifier: child.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: child.heading?.trim() ?? \"\",\n fileName: `section-${sectionNum}.md`,\n relativeFile: `section-${sectionNum}.md`,\n contentLength: sectionMd.length,\n hasNotes,\n status: child.status ?? \"current\",\n chapterIdentifier: currentChapter?.identifier ?? \"\",\n chapterNumber: currentChapter?.numValue ?? \"0\",\n chapterName: currentChapter?.heading?.trim() ?? \"\",\n });\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n // Big-level child: emit heading, then recurse\n // Structural headings cap at H5; H6 is reserved for sections.\n // Beyond H5, fall back to bold text so sections remain visually distinct.\n const numDisplay = child.num ?? \"\";\n const heading = child.heading ? ` ${child.heading}` : \"\";\n parts.push(\"\");\n if (headingLevel <= 5) {\n const prefix = \"#\".repeat(headingLevel);\n parts.push(`${prefix} ${numDisplay}${heading}`);\n } else {\n parts.push(`**${numDisplay}${heading}**`);\n }\n\n // Track the chapter ancestor for section metadata\n const nextChapter = child.levelType === \"chapter\" ? child : currentChapter;\n\n const childParts = renderTitleChildren(\n child,\n headingLevel + 1,\n options,\n renderOpts,\n sectionMetas,\n titleNum,\n nextChapter,\n );\n parts.push(...childParts);\n } else {\n // Content, notes, toc, etc. — render inline\n const rendered = renderNode(child as ASTNode, renderOpts);\n if (rendered) {\n parts.push(\"\");\n parts.push(rendered);\n }\n }\n }\n\n return parts;\n}\n\n/**\n * Recursively walk a title-level AST tree and collect SectionMeta for dry-run.\n */\n/**\n * Recursively collect SectionMeta from a chapter node for dry-run,\n * traversing intermediate big levels (subchapter, part, etc.).\n */\nfunction collectChapterSectionsDryRun(\n node: LevelNode,\n chapterNode: LevelNode,\n context: EmitContext,\n sectionMetas: SectionMeta[],\n): void {\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n sectionMetas.push(buildSectionMetaDryRun(child, chapterNode, context));\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n collectChapterSectionsDryRun(child, chapterNode, context, sectionMetas);\n }\n }\n}\n\nfunction collectSectionMetasFromTree(\n node: LevelNode,\n context: EmitContext,\n sectionMetas: SectionMeta[],\n currentChapter?: LevelNode | undefined,\n): void {\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n sectionMetas.push(buildSectionMetaDryRun(child, currentChapter ?? null, context));\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n const nextChapter = child.levelType === \"chapter\" ? child : currentChapter;\n collectSectionMetasFromTree(child, context, sectionMetas, nextChapter);\n }\n }\n}\n\nfunction buildOutputPath(\n context: EmitContext,\n sectionNum: string,\n outputRoot: string,\n /** Disambiguation suffix for duplicate section numbers (e.g., \"-2\") */\n dupSuffix?: string | undefined,\n): string {\n const titleDir = buildTitleDir(context);\n const chapterDir = buildChapterDir(context);\n const sectionFile = `section-${sectionNum}${dupSuffix ?? \"\"}.md`;\n\n if (chapterDir) {\n return join(outputRoot, \"usc\", titleDir, chapterDir, sectionFile);\n }\n\n return join(outputRoot, \"usc\", titleDir, sectionFile);\n}\n\n/**\n * Build the title directory name from context.\n * Handles appendix titles: docNumber \"5a\" → \"title-05-appendix\"\n */\nfunction buildTitleDir(context: EmitContext): string {\n // Check for appendix via docNumber (e.g., \"5a\", \"11a\")\n const docNum = context.documentMeta.docNumber ?? \"\";\n const appendixMatch = /^(\\d+)a$/i.exec(docNum);\n if (appendixMatch?.[1]) {\n return `title-${padTwo(appendixMatch[1])}-appendix`;\n }\n\n // Check for appendix ancestor\n const appendixAncestor = findAncestor(context.ancestors, \"appendix\");\n if (appendixAncestor) {\n const num = appendixAncestor.numValue ?? docNum;\n const numericPart = /^(\\d+)/.exec(num);\n if (numericPart?.[1]) {\n return `title-${padTwo(numericPart[1])}-appendix`;\n }\n }\n\n // Normal title\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"00\";\n return `title-${padTwo(titleNum)}`;\n}\n\n/**\n * Build the chapter directory name from context.\n * Handles chapter equivalents: compiledAct, reorganizationPlan.\n */\nfunction buildChapterDir(context: EmitContext): string | undefined {\n // Standard chapter\n const chapterNum = findAncestor(context.ancestors, \"chapter\")?.numValue;\n if (chapterNum) return `chapter-${padTwo(chapterNum)}`;\n\n // Compiled act as chapter equivalent\n const compiledAct = findAncestor(context.ancestors, \"compiledAct\");\n if (compiledAct) {\n const heading = compiledAct.heading?.trim() ?? \"\";\n // Use a slug of the heading as directory name\n const slug = heading\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 50);\n return slug || \"compiled-act\";\n }\n\n // Reorganization plan as chapter equivalent\n const reorgPlan = findAncestor(context.ancestors, \"reorganizationPlan\");\n if (reorgPlan) {\n const heading = reorgPlan.heading?.trim() ?? \"\";\n const slug = heading\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 50);\n return slug || \"reorganization-plan\";\n }\n\n // Reorganization plans container\n const reorgPlans = findAncestor(context.ancestors, \"reorganizationPlans\");\n if (reorgPlans) {\n return \"reorganization-plans\";\n }\n\n return undefined;\n}\n\n/**\n * Build FrontmatterData from the emitted section node and context.\n */\nfunction buildFrontmatter(node: LevelNode, context: EmitContext): FrontmatterData {\n const meta = context.documentMeta;\n const titleAncestor =\n findAncestor(context.ancestors, \"title\") ?? findAncestor(context.ancestors, \"appendix\");\n const chapterAncestor =\n findAncestor(context.ancestors, \"chapter\") ??\n findAncestor(context.ancestors, \"compiledAct\") ??\n findAncestor(context.ancestors, \"reorganizationPlan\");\n const subchapterAncestor = findAncestor(context.ancestors, \"subchapter\");\n const partAncestor = findAncestor(context.ancestors, \"part\");\n\n const docNum = meta.docNumber ?? titleAncestor?.numValue ?? \"0\";\n const titleNum = parseIntSafe(docNum.replace(/a$/i, \"\"));\n const sectionNum = node.numValue ?? \"0\";\n const sectionName = node.heading?.trim() ?? \"\";\n const titleName = titleAncestor?.heading?.trim() ?? meta.dcTitle ?? \"\";\n\n // Build the human-readable title: \"1 USC § 1 - Section Name\"\n const displayTitle = `${titleNum} USC § ${sectionNum} - ${sectionName}`;\n\n // Extract source credit text from the section's children\n const sourceCredit = extractSourceCreditText(node);\n\n // Parse currency from docPublicationName (e.g., \"Online@119-73not60\" → \"119-73\")\n const currency = parseCurrency(meta.docPublicationName ?? \"\");\n\n // Parse last_updated from created timestamp\n const lastUpdated = parseDate(meta.created ?? \"\");\n\n const fm: FrontmatterData = {\n source: \"usc\",\n legal_status: meta.positivelaw ? \"official_legal_evidence\" : \"official_prima_facie\",\n identifier: node.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n title: displayTitle,\n title_number: titleNum,\n title_name: titleName,\n section_number: sectionNum,\n section_name: sectionName,\n positive_law: meta.positivelaw ?? false,\n currency,\n last_updated: lastUpdated,\n };\n\n if (chapterAncestor?.numValue) {\n fm.chapter_number = parseIntSafe(chapterAncestor.numValue);\n }\n if (chapterAncestor?.heading) {\n fm.chapter_name = chapterAncestor.heading.trim();\n }\n if (subchapterAncestor?.numValue) {\n fm.subchapter_number = subchapterAncestor.numValue;\n }\n if (subchapterAncestor?.heading) {\n fm.subchapter_name = subchapterAncestor.heading.trim();\n }\n if (partAncestor?.numValue) {\n fm.part_number = partAncestor.numValue;\n }\n if (partAncestor?.heading) {\n fm.part_name = partAncestor.heading.trim();\n }\n if (sourceCredit) {\n fm.source_credit = sourceCredit;\n }\n if (node.status) {\n fm.status = node.status;\n }\n\n return fm;\n}\n\n// ---------------------------------------------------------------------------\n// Utility functions\n// ---------------------------------------------------------------------------\n\n/**\n * Build SectionMeta from AST node without rendering (for dry-run mode).\n */\nfunction buildSectionMetaDryRun(\n sectionNode: LevelNode,\n chapterNode: LevelNode | null,\n context: EmitContext,\n): SectionMeta {\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"0\";\n const chapterAncestor = chapterNode\n ? {\n numValue: chapterNode.numValue,\n heading: chapterNode.heading,\n identifier: chapterNode.identifier,\n }\n : findAncestor(context.ancestors, \"chapter\");\n const sectionNum = sectionNode.numValue ?? \"0\";\n const chapterNum = chapterAncestor?.numValue ?? \"0\";\n const chapterDir = chapterNum !== \"0\" ? `chapter-${padTwo(chapterNum)}` : \"\";\n\n const hasNotes = sectionNode.children.some(\n (c) => c.type === \"notesContainer\" || c.type === \"note\",\n );\n\n // Rough content length estimate from AST text nodes\n let contentLength = 0;\n const walk = (node: {\n children?: readonly { text?: string | undefined; children?: readonly unknown[] }[] | undefined;\n text?: string | undefined;\n }): void => {\n if (node.text) contentLength += node.text.length;\n if (node.children) {\n for (const child of node.children) {\n walk(child as typeof node);\n }\n }\n };\n walk(sectionNode as unknown as Parameters<typeof walk>[0]);\n\n const sectionFileName = `section-${sectionNum}.md`;\n return {\n identifier: sectionNode.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: sectionNode.heading?.trim() ?? \"\",\n fileName: sectionFileName,\n relativeFile: chapterDir ? `${chapterDir}/${sectionFileName}` : sectionFileName,\n contentLength,\n hasNotes,\n status: sectionNode.status ?? \"current\",\n chapterIdentifier: chapterAncestor?.identifier ?? \"\",\n chapterNumber: chapterNum,\n chapterName: chapterAncestor?.heading?.trim() ?? \"\",\n };\n}\n\nfunction buildNotesFilter(options: ConvertOptions): NotesFilter | undefined {\n // Default: include all notes\n if (options.includeNotes) return undefined;\n\n // No notes at all\n if (\n !options.includeEditorialNotes &&\n !options.includeStatutoryNotes &&\n !options.includeAmendments\n ) {\n return { editorial: false, statutory: false, amendments: false };\n }\n\n // Selective inclusion\n return {\n editorial: options.includeEditorialNotes,\n statutory: options.includeStatutoryNotes,\n amendments: options.includeAmendments,\n };\n}\n\nfunction findAncestor(\n ancestors: readonly AncestorInfo[],\n levelType: string,\n): AncestorInfo | undefined {\n return ancestors.find((a) => a.levelType === levelType);\n}\n\n/**\n * Build title directory name from docNumber.\n * \"5\" → \"title-05\", \"5a\" → \"title-05-appendix\"\n */\nfunction buildTitleDirFromDocNumber(docNum: string): string {\n const appendixMatch = /^(\\d+)a$/i.exec(docNum);\n if (appendixMatch?.[1]) {\n return `title-${padTwo(appendixMatch[1])}-appendix`;\n }\n return `title-${padTwo(docNum)}`;\n}\n\nfunction padTwo(num: string): string {\n const n = parseInt(num, 10);\n if (isNaN(n)) return num;\n return n.toString().padStart(2, \"0\");\n}\n\n/**\n * Parse an integer safely, returning 0 if invalid.\n */\nfunction parseIntSafe(s: string): number {\n const n = parseInt(s, 10);\n return isNaN(n) ? 0 : n;\n}\n\n/**\n * Extract source credit plain text from a section node's children.\n */\nfunction extractSourceCreditText(node: LevelNode): string | undefined {\n for (const child of node.children) {\n if (child.type === \"sourceCredit\") {\n return child.children.map((inline) => inlineToText(inline)).join(\"\");\n }\n }\n return undefined;\n}\n\n/**\n * Recursively extract plain text from an InlineNode.\n */\nfunction inlineToText(node: {\n readonly type: \"inline\";\n text?: string | undefined;\n children?: readonly { readonly type: \"inline\"; text?: string | undefined }[] | undefined;\n}): string {\n if (node.text) return node.text;\n if (node.children) {\n return node.children.map((c) => c.text ?? \"\").join(\"\");\n }\n return \"\";\n}\n\n/**\n * Parse currency/release point from docPublicationName.\n * Example: \"Online@119-73not60\" → \"119-73\"\n */\nfunction parseCurrency(pubName: string): string {\n // Try to extract the release point pattern (e.g., \"119-73\")\n const match = /(\\d+-\\d+)/.exec(pubName);\n if (match?.[1]) return match[1];\n return pubName || \"unknown\";\n}\n\n/**\n * Parse the full release point string from docPublicationName, including exclusion suffix.\n * Example: \"Online@119-73not60\" → \"119-73not60\"\n */\nfunction parseFullReleasePoint(pubName: string): string {\n const match = /(\\d+-\\d+(?:not\\d+)?)/.exec(pubName);\n if (match?.[1]) return match[1];\n return pubName || \"unknown\";\n}\n\n/**\n * Parse a date string to ISO date format (YYYY-MM-DD).\n */\nfunction parseDate(dateStr: string): string {\n if (!dateStr) return \"unknown\";\n // Handle ISO timestamp: \"2025-12-03T10:11:39\" → \"2025-12-03\"\n const datePart = dateStr.split(\"T\")[0];\n return datePart ?? dateStr;\n}\n\n/**\n * Create a copy of a section node with source credit children removed.\n */\nfunction stripSourceCredits(node: LevelNode): LevelNode {\n return {\n ...node,\n children: node.children.filter((c) => c.type !== \"sourceCredit\"),\n };\n}\n","/**\n * OLRC U.S. Code XML downloader.\n *\n * Downloads USC title XML zip files from the Office of the Law Revision Counsel\n * and extracts them to a local directory.\n */\n\nimport { createWriteStream } from \"node:fs\";\nimport { mkdir, stat, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { Readable } from \"node:stream\";\nimport { open as yauzlOpen } from \"yauzl\";\nimport type { ZipFile, Entry } from \"yauzl\";\n\n// ---------------------------------------------------------------------------\n// Release point configuration\n// ---------------------------------------------------------------------------\n\n/**\n * Current OLRC release point.\n *\n * Update this value when OLRC publishes a new release point.\n * The release point appears in download URLs and identifies which\n * public laws are incorporated. Format: \"{congress}-{law}[not{excluded}]\"\n *\n * Check https://uscode.house.gov/download/download.shtml for the latest.\n */\nexport const CURRENT_RELEASE_POINT = \"119-73not60\";\n\n/** OLRC base URL for release point downloads */\nconst OLRC_BASE_URL = \"https://uscode.house.gov/download/releasepoints/us/pl\";\n\n/** Valid USC title numbers (1-54) */\nexport const USC_TITLE_NUMBERS = Array.from({ length: 54 }, (_, i) => i + 1);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether a list of title numbers covers all 54 USC titles.\n *\n * Handles arbitrary ordering and duplicates.\n */\nexport function isAllTitles(titles: number[]): boolean {\n const unique = new Set(titles);\n return unique.size === 54 && USC_TITLE_NUMBERS.every((n) => unique.has(n));\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Options for downloading USC XML files */\nexport interface DownloadOptions {\n /** Directory to save downloaded XML files */\n outputDir: string;\n /** Specific title numbers to download, or undefined for all */\n titles?: number[] | undefined;\n /** Release point override (default: CURRENT_RELEASE_POINT) */\n releasePoint?: string | undefined;\n}\n\n/** Result of a download operation */\nexport interface DownloadResult {\n /** Release point used */\n releasePoint: string;\n /** Files successfully downloaded and extracted */\n files: DownloadedFile[];\n /** Titles that failed to download */\n errors: DownloadError[];\n}\n\n/** A successfully downloaded file */\nexport interface DownloadedFile {\n /** Title number */\n titleNumber: number;\n /** Path to the extracted XML file */\n filePath: string;\n /** Size in bytes */\n size: number;\n}\n\n/** A failed download */\nexport interface DownloadError {\n /** Title number */\n titleNumber: number;\n /** Error message */\n message: string;\n}\n\n/**\n * Download USC title XML files from OLRC.\n *\n * When all 54 titles are requested, uses the bulk `uscAll` zip for a single\n * HTTP round-trip instead of 54 individual requests. Falls back to per-title\n * downloads if the bulk download fails.\n */\nexport async function downloadTitles(options: DownloadOptions): Promise<DownloadResult> {\n const releasePoint = options.releasePoint ?? CURRENT_RELEASE_POINT;\n const titles = options.titles ?? USC_TITLE_NUMBERS;\n\n await mkdir(options.outputDir, { recursive: true });\n\n // Use bulk zip when all 54 titles are requested\n if (options.titles === undefined || isAllTitles(titles)) {\n try {\n const files = await downloadAndExtractAllTitles(releasePoint, options.outputDir);\n return { releasePoint, files, errors: [] };\n } catch {\n // Fall back to per-title downloads\n }\n }\n\n const files: DownloadedFile[] = [];\n const errors: DownloadError[] = [];\n\n for (const titleNum of titles) {\n try {\n const file = await downloadAndExtractTitle(titleNum, releasePoint, options.outputDir);\n files.push(file);\n } catch (err) {\n errors.push({\n titleNumber: titleNum,\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { releasePoint, files, errors };\n}\n\n// ---------------------------------------------------------------------------\n// URL construction\n// ---------------------------------------------------------------------------\n\n/**\n * Build the download URL for a single title's XML zip.\n *\n * Format: {base}/pl/{releasePointPath}/xml_usc{NN}@{releasePoint}.zip\n *\n * The release point path splits the release point into directory segments.\n * For \"119-73not60\", the path is \"119/73not60\".\n */\nexport function buildDownloadUrl(titleNumber: number, releasePoint: string): string {\n const paddedTitle = titleNumber.toString().padStart(2, \"0\");\n const rpPath = releasePointToPath(releasePoint);\n return `${OLRC_BASE_URL}/${rpPath}/xml_usc${paddedTitle}@${releasePoint}.zip`;\n}\n\n/**\n * Build the download URL for all titles in a single zip.\n */\nexport function buildAllTitlesUrl(releasePoint: string): string {\n const rpPath = releasePointToPath(releasePoint);\n return `${OLRC_BASE_URL}/${rpPath}/xml_uscAll@${releasePoint}.zip`;\n}\n\n/**\n * Convert a release point string to a URL path segment.\n * \"119-73not60\" → \"119/73not60\"\n * \"119-43\" → \"119/43\"\n */\nexport function releasePointToPath(releasePoint: string): string {\n // Split on the first hyphen only\n const dashIndex = releasePoint.indexOf(\"-\");\n if (dashIndex === -1) return releasePoint;\n return `${releasePoint.slice(0, dashIndex)}/${releasePoint.slice(dashIndex + 1)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Download and extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Download a single title's zip and extract the XML file.\n */\nasync function downloadAndExtractTitle(\n titleNumber: number,\n releasePoint: string,\n outputDir: string,\n): Promise<DownloadedFile> {\n const url = buildDownloadUrl(titleNumber, releasePoint);\n const paddedTitle = titleNumber.toString().padStart(2, \"0\");\n const zipPath = join(outputDir, `usc${paddedTitle}.zip`);\n const xmlFileName = `usc${paddedTitle}.xml`;\n const xmlPath = join(outputDir, xmlFileName);\n\n // Download the zip file\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText} for ${url}`);\n }\n\n if (!response.body) {\n throw new Error(`No response body for ${url}`);\n }\n\n // Write zip to disk\n const fileStream = createWriteStream(zipPath);\n // ReadableStream type mismatch between DOM and Node — cast to `never` to bridge\n await pipeline(Readable.fromWeb(response.body as never), fileStream);\n\n // Extract XML from zip\n await extractXmlFromZip(zipPath, xmlFileName, xmlPath);\n\n // Clean up zip file\n await unlink(zipPath);\n\n // Get file size\n const fileStat = await stat(xmlPath);\n\n return {\n titleNumber,\n filePath: xmlPath,\n size: fileStat.size,\n };\n}\n\n/**\n * Extract a specific XML file from a zip archive.\n */\nfunction extractXmlFromZip(\n zipPath: string,\n targetFileName: string,\n outputPath: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n yauzlOpen(zipPath, { lazyEntries: true }, (err, zipFile) => {\n if (err) {\n reject(new Error(`Failed to open zip: ${err.message}`));\n return;\n }\n if (!zipFile) {\n reject(new Error(\"Failed to open zip: no zipFile returned\"));\n return;\n }\n\n let found = false;\n\n zipFile.on(\"entry\", (entry: Entry) => {\n // Look for the target XML file (might be at root or in a subdirectory)\n const fileName = entry.fileName.split(\"/\").pop() ?? entry.fileName;\n if (fileName === targetFileName || entry.fileName.endsWith(`.xml`)) {\n found = true;\n extractEntry(zipFile, entry, outputPath)\n .then(() => {\n zipFile.close();\n resolve();\n })\n .catch((extractErr) => {\n zipFile.close();\n reject(extractErr);\n });\n } else {\n zipFile.readEntry();\n }\n });\n\n zipFile.on(\"end\", () => {\n if (!found) {\n reject(new Error(`${targetFileName} not found in zip`));\n }\n });\n\n zipFile.on(\"error\", (zipErr: Error) => {\n reject(new Error(`Zip error: ${zipErr.message}`));\n });\n\n zipFile.readEntry();\n });\n });\n}\n\n/**\n * Extract a single zip entry to a file.\n */\nfunction extractEntry(zipFile: ZipFile, entry: Entry, outputPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n zipFile.openReadStream(entry, (err, readStream) => {\n if (err) {\n reject(new Error(`Failed to read zip entry: ${err.message}`));\n return;\n }\n if (!readStream) {\n reject(new Error(\"No read stream for zip entry\"));\n return;\n }\n\n const writeStream = createWriteStream(outputPath);\n readStream.pipe(writeStream);\n\n writeStream.on(\"finish\", () => resolve());\n writeStream.on(\"error\", (writeErr) => reject(new Error(`Write error: ${writeErr.message}`)));\n readStream.on(\"error\", (readErr) => reject(new Error(`Read error: ${readErr.message}`)));\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Bulk download (all titles in one zip)\n// ---------------------------------------------------------------------------\n\n/** Regex matching USC XML filenames like usc01.xml, usc54.xml */\nconst USC_XML_RE = /^(?:.*\\/)?usc(\\d{2})\\.xml$/;\n\n/**\n * Extract all `usc{NN}.xml` files from a bulk zip archive.\n *\n * Returns an array of `{ titleNumber, filePath }` for each extracted file.\n */\nfunction extractAllXmlFromZip(\n zipPath: string,\n outputDir: string,\n): Promise<{ titleNumber: number; filePath: string }[]> {\n return new Promise((resolve, reject) => {\n yauzlOpen(zipPath, { lazyEntries: true }, (err, zipFile) => {\n if (err) {\n reject(new Error(`Failed to open zip: ${err.message}`));\n return;\n }\n if (!zipFile) {\n reject(new Error(\"Failed to open zip: no zipFile returned\"));\n return;\n }\n\n const extracted: { titleNumber: number; filePath: string }[] = [];\n let pending = 0;\n let ended = false;\n\n const maybeResolve = (): void => {\n if (ended && pending === 0) {\n resolve(extracted);\n }\n };\n\n zipFile.on(\"entry\", (entry: Entry) => {\n const match = USC_XML_RE.exec(entry.fileName);\n if (match) {\n const titleNum = parseInt(match[1] ?? \"0\", 10);\n const outPath = join(outputDir, `usc${match[1] ?? \"00\"}.xml`);\n pending++;\n\n extractEntry(zipFile, entry, outPath)\n .then(() => {\n extracted.push({ titleNumber: titleNum, filePath: outPath });\n pending--;\n // Continue reading entries after extraction completes\n zipFile.readEntry();\n maybeResolve();\n })\n .catch((extractErr) => {\n zipFile.close();\n reject(extractErr);\n });\n } else {\n zipFile.readEntry();\n }\n });\n\n zipFile.on(\"end\", () => {\n ended = true;\n maybeResolve();\n });\n\n zipFile.on(\"error\", (zipErr: Error) => {\n reject(new Error(`Zip error: ${zipErr.message}`));\n });\n\n zipFile.readEntry();\n });\n });\n}\n\n/**\n * Download the bulk all-titles zip and extract every `usc{NN}.xml` file.\n */\nasync function downloadAndExtractAllTitles(\n releasePoint: string,\n outputDir: string,\n): Promise<DownloadedFile[]> {\n const url = buildAllTitlesUrl(releasePoint);\n const zipPath = join(outputDir, \"uscAll.zip\");\n\n // Download the zip file\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText} for ${url}`);\n }\n\n if (!response.body) {\n throw new Error(`No response body for ${url}`);\n }\n\n // Write zip to disk\n const fileStream = createWriteStream(zipPath);\n await pipeline(Readable.fromWeb(response.body as never), fileStream);\n\n // Extract all XML files from zip\n const extracted = await extractAllXmlFromZip(zipPath, outputDir);\n\n // Clean up zip file\n await unlink(zipPath);\n\n // Stat each extracted file and build results\n const files: DownloadedFile[] = [];\n for (const { titleNumber, filePath } of extracted) {\n const fileStat = await stat(filePath);\n files.push({ titleNumber, filePath, size: fileStat.size });\n }\n\n // Sort by title number for consistent ordering\n files.sort((a, b) => a.titleNumber - b.titleNumber);\n\n return files;\n}\n"],"mappings":"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","names":["mkdir","join","files"]}
|
|
1
|
+
{"version":3,"sources":["../src/converter.ts","../src/downloader.ts","../src/release-points.ts"],"sourcesContent":["/**\n * USC Converter — orchestrates the full conversion pipeline for a single USC XML file.\n *\n * Creates a ReadStream → SAX Parser → AST Builder (emit at section) →\n * Markdown Renderer + Frontmatter → File Writer.\n */\n\nimport { createReadStream } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { basename } from \"node:path\";\nimport {\n XMLParser,\n ASTBuilder,\n renderDocument,\n renderSection,\n renderNode,\n generateFrontmatter,\n createLinkResolver,\n FORMAT_VERSION,\n GENERATOR,\n BIG_LEVELS,\n writeFile,\n mkdir,\n} from \"@lexbuild/core\";\nimport type {\n LevelNode,\n ASTNode,\n EmitContext,\n FrontmatterData,\n RenderOptions,\n NotesFilter,\n AncestorInfo,\n LinkResolver,\n} from \"@lexbuild/core\";\n\n/** Options for converting a USC XML file */\nexport interface ConvertOptions {\n /** Path to the input XML file */\n input: string;\n /** Output directory root */\n output: string;\n /** Output granularity: \"section\" (one file per section), \"chapter\" (sections inline), or \"title\" (entire title) */\n granularity: \"section\" | \"chapter\" | \"title\";\n /** How to render cross-references */\n linkStyle: \"relative\" | \"canonical\" | \"plaintext\";\n /** Include source credits in output */\n includeSourceCredits: boolean;\n /** Include notes in output. True = all notes (default). False = no notes. */\n includeNotes: boolean;\n /** Include editorial notes only (when includeNotes is false) */\n includeEditorialNotes: boolean;\n /** Include statutory notes only (when includeNotes is false) */\n includeStatutoryNotes: boolean;\n /** Include amendment history notes only (when includeNotes is false) */\n includeAmendments: boolean;\n /** Dry-run mode: parse and report structure without writing files */\n dryRun: boolean;\n}\n\n/** Result of a conversion */\nexport interface ConvertResult {\n /** Number of sections written (or that would be written in dry-run) */\n sectionsWritten: number;\n /** Output paths of all written files (empty in dry-run) */\n files: string[];\n /** Title number extracted from metadata */\n titleNumber: string;\n /** Title name extracted from metadata */\n titleName: string;\n /** Whether this was a dry run */\n dryRun: boolean;\n /** Chapter count */\n chapterCount: number;\n /** Estimated total tokens */\n totalTokenEstimate: number;\n /** Peak resident set size in bytes during conversion */\n peakMemoryBytes: number;\n}\n\n/** Default convert options */\nconst DEFAULTS: Omit<ConvertOptions, \"input\" | \"output\"> = {\n granularity: \"section\",\n linkStyle: \"plaintext\",\n includeSourceCredits: true,\n includeNotes: true,\n includeEditorialNotes: false,\n includeStatutoryNotes: false,\n includeAmendments: false,\n dryRun: false,\n};\n\n/** Metadata collected for a written section (used to build _meta.json) */\ninterface SectionMeta {\n identifier: string;\n number: string;\n name: string;\n /** Filename only (e.g., \"section-3598.md\" or \"section-3598-2.md\" for duplicates) */\n fileName: string;\n /** File path relative to the title directory (e.g., \"chapter-01/section-1.md\") */\n relativeFile: string;\n /** Content length in characters (for token estimation) */\n contentLength: number;\n hasNotes: boolean;\n status: string;\n /** Chapter identifier this section belongs to */\n chapterIdentifier: string;\n chapterNumber: string;\n chapterName: string;\n}\n\n/** A collected section ready to be written */\ninterface CollectedSection {\n node: LevelNode;\n context: EmitContext;\n}\n\n/**\n * Convert a single USC XML file to section-level Markdown files.\n */\nexport async function convertTitle(options: ConvertOptions): Promise<ConvertResult> {\n const opts = { ...DEFAULTS, ...options };\n const files: string[] = [];\n let peakMemory = process.memoryUsage.rss();\n let titleLevelTokenEstimate: number | undefined;\n\n // Collect emitted nodes during parsing (synchronous), write after parsing completes\n const collected: CollectedSection[] = [];\n\n // Set up the AST builder — emit level depends on granularity\n const emitAt =\n opts.granularity === \"title\"\n ? (\"title\" as const)\n : opts.granularity === \"chapter\"\n ? (\"chapter\" as const)\n : (\"section\" as const);\n const builder = new ASTBuilder({\n emitAt,\n onEmit: (node, context) => {\n collected.push({ node, context });\n },\n });\n\n // Set up the XML parser\n const parser = new XMLParser();\n parser.on(\"openElement\", (name, attrs) => builder.onOpenElement(name, attrs));\n parser.on(\"closeElement\", (name) => builder.onCloseElement(name));\n parser.on(\"text\", (text) => builder.onText(text));\n\n // Parse the XML file\n const stream = createReadStream(opts.input, \"utf-8\");\n await parser.parseStream(stream);\n peakMemory = Math.max(peakMemory, process.memoryUsage.rss());\n\n const sectionMetas: SectionMeta[] = [];\n const meta = builder.getDocumentMeta();\n\n if (opts.dryRun) {\n // Dry-run: collect metadata without writing files\n for (const { node, context } of collected) {\n if (opts.granularity === \"title\") {\n // Walk title tree → chapters → sections\n collectSectionMetasFromTree(node, context, sectionMetas);\n } else if (opts.granularity === \"chapter\") {\n // Recursively extract section metadata from chapter children (including nested big levels)\n collectChapterSectionsDryRun(node, node, context, sectionMetas);\n } else {\n if (node.numValue) {\n sectionMetas.push(buildSectionMetaDryRun(node, null, context));\n }\n }\n }\n } else if (opts.granularity === \"title\") {\n // Title-level: each emitted node is an entire title\n let titleTokenEstimate = 0;\n for (const { node, context } of collected) {\n const result = await writeWholeTitle(node, context, opts);\n files.push(result.filePath);\n titleTokenEstimate += result.totalTokenEstimate;\n for (const m of result.sectionMetas) {\n sectionMetas.push(m);\n }\n }\n // Store the accurate title-level estimate for use in ConvertResult\n titleLevelTokenEstimate = titleTokenEstimate;\n } else if (opts.granularity === \"chapter\") {\n // Chapter-level: each emitted node is a chapter containing sections\n for (const { node, context } of collected) {\n const result = await writeChapter(node, context, opts);\n if (result) {\n files.push(result.filePath);\n for (const m of result.sectionMetas) {\n sectionMetas.push(m);\n }\n }\n }\n } else {\n // Section-level with relative links: need two-pass for link resolver\n // Track duplicate section numbers per chapter to disambiguate filenames\n const sectionCounts = new Map<string, number>();\n const suffixes: (string | undefined)[] = [];\n for (const { node, context } of collected) {\n const sectionNum = node.numValue;\n if (!sectionNum) {\n suffixes.push(undefined);\n continue;\n }\n const chapterDir = buildChapterDir(context) ?? \"__root__\";\n const key = `${chapterDir}/${sectionNum}`;\n const count = (sectionCounts.get(key) ?? 0) + 1;\n sectionCounts.set(key, count);\n suffixes.push(count > 1 ? `-${count}` : undefined);\n }\n\n const linkResolver = createLinkResolver();\n for (const [i, { node, context }] of collected.entries()) {\n const sectionNum = node.numValue;\n if (sectionNum && node.identifier) {\n const filePath = buildOutputPath(context, sectionNum, opts.output, suffixes[i]);\n // For duplicates, register with the XML element @id to disambiguate\n const regId = suffixes[i] ? `${node.identifier}#${suffixes[i]}` : node.identifier;\n linkResolver.register(regId, filePath);\n // Always register the first occurrence under the canonical identifier\n if (!suffixes[i]) {\n linkResolver.register(node.identifier, filePath);\n }\n }\n }\n\n for (const [i, { node, context }] of collected.entries()) {\n const result = await writeSection(node, context, opts, linkResolver, suffixes[i]);\n if (result) {\n files.push(result.filePath);\n sectionMetas.push(result.meta);\n }\n }\n }\n\n // Extract the title heading from the first collected node\n const firstCollected = collected[0];\n const titleHeading = firstCollected\n ? opts.granularity === \"title\"\n ? firstCollected.node.heading?.trim()\n : findAncestor(firstCollected.context.ancestors, \"title\")?.heading?.trim()\n : undefined;\n\n // Generate _meta.json and README.md files (skip in dry-run)\n if (!opts.dryRun) {\n await writeMetaFiles(sectionMetas, meta, opts, titleHeading);\n }\n\n // Final memory sample\n peakMemory = Math.max(peakMemory, process.memoryUsage.rss());\n\n // Compute stats\n const chapterIds = new Set(sectionMetas.map((s) => s.chapterIdentifier).filter(Boolean));\n // For title granularity, use the accurate estimate from the full rendered body\n // (includes structural headings); for other modes, sum per-section content lengths\n const totalTokens =\n titleLevelTokenEstimate ??\n sectionMetas.reduce((sum, s) => sum + Math.ceil(s.contentLength / 4), 0);\n\n return {\n sectionsWritten:\n opts.dryRun || opts.granularity === \"title\" || opts.granularity === \"chapter\"\n ? sectionMetas.length\n : files.length,\n files,\n titleNumber: meta.docNumber ?? \"unknown\",\n titleName: titleHeading ?? meta.dcTitle ?? \"Unknown Title\",\n dryRun: opts.dryRun,\n chapterCount: chapterIds.size,\n totalTokenEstimate: totalTokens,\n peakMemoryBytes: peakMemory,\n };\n}\n\n/** Result of writing a single section */\ninterface WriteSectionResult {\n filePath: string;\n meta: SectionMeta;\n}\n\n/**\n * Write a single section to disk.\n * Returns the file path and metadata, or null if the section was skipped.\n */\nasync function writeSection(\n node: LevelNode,\n context: EmitContext,\n options: ConvertOptions,\n linkResolver?: LinkResolver | undefined,\n /** Disambiguation suffix for duplicate section numbers (e.g., \"-2\") */\n dupSuffix?: string | undefined,\n): Promise<WriteSectionResult | null> {\n const sectionNum = node.numValue;\n if (!sectionNum) return null;\n\n // Build the output file path (with optional duplicate suffix)\n const filePath = buildOutputPath(context, sectionNum, options.output, dupSuffix);\n\n // Build frontmatter data\n const frontmatter = buildFrontmatter(node, context);\n\n // Build notes filter\n const notesFilter = buildNotesFilter(options);\n\n // Build render options with link resolver for relative links\n const renderOpts: RenderOptions = {\n headingOffset: 0,\n linkStyle: options.linkStyle,\n resolveLink: linkResolver\n ? (identifier: string) => linkResolver.resolve(identifier, filePath)\n : undefined,\n notesFilter,\n };\n\n // Optionally strip source credits\n const sectionNode = options.includeSourceCredits ? node : stripSourceCredits(node);\n\n // Render the document\n const markdown = renderDocument(sectionNode, frontmatter, renderOpts);\n\n // Ensure the directory exists and write the file\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, markdown, \"utf-8\");\n\n // Collect metadata\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"0\";\n const chapterAncestor = findAncestor(context.ancestors, \"chapter\");\n const chapterDir = chapterAncestor?.numValue ? `chapter-${padTwo(chapterAncestor.numValue)}` : \"\";\n const sectionFileName = `section-${sectionNum}${dupSuffix ?? \"\"}.md`;\n const relativeFile = chapterDir ? `${chapterDir}/${sectionFileName}` : sectionFileName;\n\n const hasNotes = node.children.some((c) => c.type === \"notesContainer\" || c.type === \"note\");\n\n const sectionMeta: SectionMeta = {\n identifier: node.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: node.heading?.trim() ?? \"\",\n fileName: sectionFileName,\n relativeFile,\n contentLength: markdown.length,\n hasNotes,\n status: node.status ?? \"current\",\n chapterIdentifier: chapterAncestor?.identifier ?? \"\",\n chapterNumber: chapterAncestor?.numValue ?? \"0\",\n chapterName: chapterAncestor?.heading?.trim() ?? \"\",\n };\n\n return { filePath, meta: sectionMeta };\n}\n\n/**\n * Generate _meta.json files at title and chapter levels.\n */\nasync function writeMetaFiles(\n sectionMetas: SectionMeta[],\n docMeta: {\n dcTitle?: string | undefined;\n docNumber?: string | undefined;\n positivelaw?: boolean | undefined;\n docPublicationName?: string | undefined;\n created?: string | undefined;\n identifier?: string | undefined;\n },\n options: ConvertOptions,\n titleHeading?: string | undefined,\n): Promise<void> {\n if (sectionMetas.length === 0) return;\n if (options.granularity === \"title\") return;\n\n const docNum = docMeta.docNumber ?? \"0\";\n const titleDirName = buildTitleDirFromDocNumber(docNum);\n const titleDir = join(options.output, \"usc\", titleDirName);\n const currency = parseCurrency(docMeta.docPublicationName ?? \"\");\n\n // Group sections by chapter\n const chapterMap = new Map<string, SectionMeta[]>();\n for (const sm of sectionMetas) {\n const key = sm.chapterIdentifier || \"__no_chapter__\";\n let arr = chapterMap.get(key);\n if (!arr) {\n arr = [];\n chapterMap.set(key, arr);\n }\n arr.push(sm);\n }\n\n // Write chapter-level _meta.json files\n const chapterEntries: Array<{\n identifier: string;\n number: number;\n name: string;\n directory: string;\n sections: Array<{\n identifier: string;\n number: string;\n name: string;\n file: string;\n token_estimate: number;\n has_notes: boolean;\n status: string;\n }>;\n }> = [];\n\n for (const [chapterId, chapterSections] of chapterMap) {\n if (chapterId === \"__no_chapter__\") continue;\n\n const first = chapterSections[0];\n if (!first) continue;\n\n const chapterDir = `chapter-${padTwo(first.chapterNumber)}`;\n\n const sections = chapterSections.map((sm) => ({\n identifier: sm.identifier,\n number: sm.number,\n name: sm.name,\n file: sm.fileName,\n token_estimate: Math.ceil(sm.contentLength / 4),\n has_notes: sm.hasNotes,\n status: sm.status,\n }));\n\n const chapterMeta = {\n format_version: FORMAT_VERSION,\n identifier: chapterId,\n chapter_number: parseIntSafe(first.chapterNumber),\n chapter_name: first.chapterName,\n title_number: parseIntSafe(docNum),\n section_count: sections.length,\n sections,\n };\n\n const chapterMetaPath = join(titleDir, chapterDir, \"_meta.json\");\n await mkdir(dirname(chapterMetaPath), { recursive: true });\n await writeFile(chapterMetaPath, JSON.stringify(chapterMeta, null, 2) + \"\\n\", \"utf-8\");\n\n chapterEntries.push({\n identifier: chapterId,\n number: parseIntSafe(first.chapterNumber),\n name: first.chapterName,\n directory: chapterDir,\n sections,\n });\n }\n\n // Write title-level _meta.json\n const totalTokens = sectionMetas.reduce((sum, sm) => sum + Math.ceil(sm.contentLength / 4), 0);\n\n const releasePoint = parseFullReleasePoint(docMeta.docPublicationName ?? \"\");\n\n const titleMeta = {\n format_version: FORMAT_VERSION,\n generator: GENERATOR,\n generated_at: new Date().toISOString(),\n identifier: docMeta.identifier ?? `/us/usc/t${docNum}`,\n title_number: parseIntSafe(docNum),\n title_name: titleHeading ?? docMeta.dcTitle ?? \"\",\n positive_law: docMeta.positivelaw ?? false,\n currency,\n release_point: releasePoint,\n source_xml: basename(options.input),\n granularity: options.granularity,\n stats: {\n chapter_count: chapterEntries.length,\n section_count: sectionMetas.length,\n total_files: sectionMetas.length,\n total_tokens_estimate: totalTokens,\n },\n chapters: chapterEntries,\n };\n\n const titleMetaPath = join(titleDir, \"_meta.json\");\n await mkdir(dirname(titleMetaPath), { recursive: true });\n await writeFile(titleMetaPath, JSON.stringify(titleMeta, null, 2) + \"\\n\", \"utf-8\");\n\n // Write title-level README.md\n const readmePath = join(titleDir, \"README.md\");\n const readme = generateTitleReadme(titleMeta);\n await writeFile(readmePath, readme, \"utf-8\");\n}\n\n/**\n * Generate a human-readable README.md for a title output directory.\n */\nfunction generateTitleReadme(meta: {\n title_number: number;\n title_name: string;\n positive_law: boolean;\n currency: string;\n granularity: string;\n stats: {\n chapter_count: number;\n section_count: number;\n total_tokens_estimate: number;\n };\n chapters: Array<{\n number: number;\n name: string;\n directory: string;\n sections: Array<{\n number: string;\n name: string;\n file: string;\n status: string;\n }>;\n }>;\n}): string {\n const lines: string[] = [];\n\n lines.push(`# Title ${meta.title_number} — ${meta.title_name}`);\n lines.push(\"\");\n lines.push(`| | |`);\n lines.push(`| --- | --- |`);\n lines.push(`| **Positive Law** | ${meta.positive_law ? \"Yes\" : \"No\"} |`);\n lines.push(`| **Currency** | ${meta.currency || \"unknown\"} |`);\n lines.push(`| **Chapters** | ${meta.stats.chapter_count} |`);\n lines.push(`| **Sections** | ${meta.stats.section_count.toLocaleString()} |`);\n lines.push(`| **Est. Tokens** | ${meta.stats.total_tokens_estimate.toLocaleString()} |`);\n lines.push(`| **Granularity** | ${meta.granularity} |`);\n lines.push(\"\");\n\n // Chapter listing\n lines.push(\"## Chapters\");\n lines.push(\"\");\n\n for (const ch of meta.chapters) {\n const sectionCount = ch.sections.length;\n lines.push(`### Chapter ${ch.number} — ${ch.name}`);\n lines.push(\"\");\n lines.push(\n `${sectionCount} section${sectionCount !== 1 ? \"s\" : \"\"} · [${ch.directory}/](${ch.directory}/)`,\n );\n lines.push(\"\");\n }\n\n // Footer\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(`Generated by [LexBuild](https://github.com/chris-c-thomas/LexBuild)`);\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\n/** Result of writing a chapter file */\ninterface WriteChapterResult {\n filePath: string;\n sectionMetas: SectionMeta[];\n}\n\n/**\n * Write a chapter-level file (all sections inlined).\n * The emitted node is a chapter LevelNode whose children include section LevelNodes.\n */\nasync function writeChapter(\n chapterNode: LevelNode,\n context: EmitContext,\n options: ConvertOptions,\n): Promise<WriteChapterResult | null> {\n const chapterNum = chapterNode.numValue;\n if (!chapterNum) return null;\n\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"0\";\n const titleDir = `title-${padTwo(titleNum)}`;\n const chapterDir = `chapter-${padTwo(chapterNum)}`;\n const chapterFile = `chapter-${padTwo(chapterNum)}.md`;\n const filePath = join(options.output, \"usc\", titleDir, chapterDir, chapterFile);\n\n // Build chapter-level frontmatter\n const titleAncestor = findAncestor(context.ancestors, \"title\");\n const meta = context.documentMeta;\n const chapterName = chapterNode.heading?.trim() ?? \"\";\n const titleName = titleAncestor?.heading?.trim() ?? meta.dcTitle ?? \"\";\n const currency = parseCurrency(meta.docPublicationName ?? \"\");\n const lastUpdated = parseDate(meta.created ?? \"\");\n\n const fmData: FrontmatterData = {\n source: \"usc\",\n legal_status: meta.positivelaw ? \"official_legal_evidence\" : \"official_prima_facie\",\n identifier: chapterNode.identifier ?? `/us/usc/t${titleNum}/ch${chapterNum}`,\n title: `${titleNum} USC Chapter ${chapterNum} - ${chapterName}`,\n title_number: parseIntSafe(titleNum),\n title_name: titleName,\n section_number: chapterNum,\n section_name: chapterName,\n chapter_number: parseIntSafe(chapterNum),\n chapter_name: chapterName,\n positive_law: meta.positivelaw ?? false,\n currency,\n last_updated: lastUpdated,\n };\n\n const notesFilter = buildNotesFilter(options);\n const renderOpts: RenderOptions = {\n headingOffset: 0,\n linkStyle: options.linkStyle,\n notesFilter,\n };\n\n // Build the chapter Markdown: heading + each section rendered with H2\n const parts: string[] = [];\n parts.push(generateFrontmatter(fmData));\n parts.push(\"\");\n parts.push(`# Chapter ${chapterNum} — ${chapterName}`);\n\n // Collect section metas and render chapter children recursively\n const sectionMetas: SectionMeta[] = [];\n\n renderChapterChildren(\n chapterNode,\n 2,\n options,\n renderOpts,\n parts,\n sectionMetas,\n titleNum,\n chapterNode.identifier ?? \"\",\n chapterNum,\n chapterName,\n chapterFile,\n );\n\n const markdown = parts.join(\"\\n\") + \"\\n\";\n\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, markdown, \"utf-8\");\n\n return { filePath, sectionMetas };\n}\n\n/**\n * Recursively render children of a chapter node, traversing intermediate big levels\n * (subchapter, part, etc.) to find and render all nested sections.\n */\nfunction renderChapterChildren(\n node: LevelNode,\n headingLevel: number,\n options: ConvertOptions,\n renderOpts: RenderOptions,\n parts: string[],\n sectionMetas: SectionMeta[],\n titleNum: string,\n chapterIdentifier: string,\n chapterNum: string,\n chapterName: string,\n chapterFile: string,\n): void {\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n const sectionOpts: RenderOptions = {\n ...renderOpts,\n headingOffset: Math.min(headingLevel - 1, 5),\n };\n const sectionNode = options.includeSourceCredits ? child : stripSourceCredits(child);\n const sectionMd = renderSection(sectionNode, sectionOpts);\n parts.push(\"\");\n parts.push(sectionMd);\n\n const sectionNum = child.numValue ?? \"0\";\n const hasNotes = child.children.some((c) => c.type === \"notesContainer\" || c.type === \"note\");\n sectionMetas.push({\n identifier: child.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: child.heading?.trim() ?? \"\",\n fileName: `section-${sectionNum}.md`,\n relativeFile: `chapter-${padTwo(chapterNum)}/${chapterFile}`,\n contentLength: sectionMd.length,\n hasNotes,\n status: child.status ?? \"current\",\n chapterIdentifier,\n chapterNumber: chapterNum,\n chapterName,\n });\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n // Intermediate big level (subchapter, part, etc.) — emit heading and recurse\n const numDisplay = child.num ?? \"\";\n const heading = child.heading ? ` ${child.heading}` : \"\";\n parts.push(\"\");\n if (headingLevel <= 5) {\n const prefix = \"#\".repeat(headingLevel);\n parts.push(`${prefix} ${numDisplay}${heading}`);\n } else {\n parts.push(`**${numDisplay}${heading}**`);\n }\n\n renderChapterChildren(\n child,\n headingLevel + 1,\n options,\n renderOpts,\n parts,\n sectionMetas,\n titleNum,\n chapterIdentifier,\n chapterNum,\n chapterName,\n chapterFile,\n );\n } else {\n // Content, notes, toc, etc. — render inline\n const rendered = renderNode(child as ASTNode, renderOpts);\n if (rendered) {\n parts.push(\"\");\n parts.push(rendered);\n }\n }\n }\n}\n\n/** Result of writing a title-level file */\ninterface WriteTitleResult {\n filePath: string;\n sectionMetas: SectionMeta[];\n /** Token estimate based on full rendered body (including structural headings) */\n totalTokenEstimate: number;\n}\n\n/**\n * Write a title-level file (entire title as a single Markdown document).\n * The emitted node is the title LevelNode with all children.\n */\nasync function writeWholeTitle(\n titleNode: LevelNode,\n context: EmitContext,\n options: ConvertOptions,\n): Promise<WriteTitleResult> {\n const meta = context.documentMeta;\n const docNum = meta.docNumber ?? titleNode.numValue ?? \"0\";\n const titleNum = docNum.replace(/a$/i, \"\");\n const titleName = titleNode.heading?.trim() ?? meta.dcTitle ?? \"\";\n const currency = parseCurrency(meta.docPublicationName ?? \"\");\n const lastUpdated = parseDate(meta.created ?? \"\");\n\n const notesFilter = buildNotesFilter(options);\n const renderOpts: RenderOptions = {\n headingOffset: 0,\n linkStyle: options.linkStyle,\n notesFilter,\n };\n\n // Render title children recursively, collecting section metas\n const sectionMetas: SectionMeta[] = [];\n const bodyParts = renderTitleChildren(titleNode, 2, options, renderOpts, sectionMetas, titleNum);\n\n // Build the title Markdown body first so we can measure its total length\n const bodyMarkdownParts: string[] = [];\n const numDisplay = titleNode.num ?? \"\";\n const headingText = titleNode.heading ? ` ${titleNode.heading}` : \"\";\n bodyMarkdownParts.push(`# ${numDisplay}${headingText}`);\n bodyMarkdownParts.push(...bodyParts);\n const bodyMarkdown = bodyMarkdownParts.join(\"\\n\");\n\n // Build enriched frontmatter for title-level output\n // Use full body length (not just section content) for accurate token estimate\n const fmData: FrontmatterData = {\n source: \"usc\",\n legal_status: meta.positivelaw ? \"official_legal_evidence\" : \"official_prima_facie\",\n identifier: titleNode.identifier ?? meta.identifier ?? `/us/usc/t${titleNum}`,\n title: `Title ${titleNum} — ${titleName}`,\n title_number: parseIntSafe(titleNum),\n title_name: titleName,\n positive_law: meta.positivelaw ?? false,\n currency,\n last_updated: lastUpdated,\n chapter_count: new Set(sectionMetas.map((s) => s.chapterIdentifier).filter(Boolean)).size,\n section_count: sectionMetas.length,\n total_token_estimate: Math.ceil(bodyMarkdown.length / 4),\n };\n\n // Assemble final Markdown: frontmatter + body\n const markdown = generateFrontmatter(fmData) + \"\\n\\n\" + bodyMarkdown + \"\\n\";\n\n // Output path: output/usc/title-NN.md (or title-NN-appendix.md for appendix titles)\n const titleFile = `${buildTitleDirFromDocNumber(docNum)}.md`;\n const filePath = join(options.output, \"usc\", titleFile);\n\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, markdown, \"utf-8\");\n\n const totalTokenEstimate = Math.ceil(bodyMarkdown.length / 4);\n return { filePath, sectionMetas, totalTokenEstimate };\n}\n\n/**\n * Recursively render children of a big-level node for title-level output.\n * Returns an array of Markdown parts (each preceded by blank line).\n * Collects SectionMeta for each section encountered.\n */\nfunction renderTitleChildren(\n node: LevelNode,\n headingLevel: number,\n options: ConvertOptions,\n renderOpts: RenderOptions,\n sectionMetas: SectionMeta[],\n titleNum: string,\n currentChapter?: LevelNode | undefined,\n): string[] {\n const parts: string[] = [];\n\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n // Render section at current heading level\n // renderSection adds 1 to headingOffset, so subtract 1 to land at headingLevel\n const sectionOpts: RenderOptions = {\n ...renderOpts,\n headingOffset: Math.min(headingLevel - 1, 5),\n };\n const sectionNode = options.includeSourceCredits ? child : stripSourceCredits(child);\n const sectionMd = renderSection(sectionNode, sectionOpts);\n parts.push(\"\");\n parts.push(sectionMd);\n\n // Collect section metadata\n const sectionNum = child.numValue ?? \"0\";\n const hasNotes = child.children.some((c) => c.type === \"notesContainer\" || c.type === \"note\");\n sectionMetas.push({\n identifier: child.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: child.heading?.trim() ?? \"\",\n fileName: `section-${sectionNum}.md`,\n relativeFile: `section-${sectionNum}.md`,\n contentLength: sectionMd.length,\n hasNotes,\n status: child.status ?? \"current\",\n chapterIdentifier: currentChapter?.identifier ?? \"\",\n chapterNumber: currentChapter?.numValue ?? \"0\",\n chapterName: currentChapter?.heading?.trim() ?? \"\",\n });\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n // Big-level child: emit heading, then recurse\n // Structural headings cap at H5; H6 is reserved for sections.\n // Beyond H5, fall back to bold text so sections remain visually distinct.\n const numDisplay = child.num ?? \"\";\n const heading = child.heading ? ` ${child.heading}` : \"\";\n parts.push(\"\");\n if (headingLevel <= 5) {\n const prefix = \"#\".repeat(headingLevel);\n parts.push(`${prefix} ${numDisplay}${heading}`);\n } else {\n parts.push(`**${numDisplay}${heading}**`);\n }\n\n // Track the chapter ancestor for section metadata\n const nextChapter = child.levelType === \"chapter\" ? child : currentChapter;\n\n const childParts = renderTitleChildren(\n child,\n headingLevel + 1,\n options,\n renderOpts,\n sectionMetas,\n titleNum,\n nextChapter,\n );\n parts.push(...childParts);\n } else {\n // Content, notes, toc, etc. — render inline\n const rendered = renderNode(child as ASTNode, renderOpts);\n if (rendered) {\n parts.push(\"\");\n parts.push(rendered);\n }\n }\n }\n\n return parts;\n}\n\n/**\n * Recursively walk a title-level AST tree and collect SectionMeta for dry-run.\n */\n/**\n * Recursively collect SectionMeta from a chapter node for dry-run,\n * traversing intermediate big levels (subchapter, part, etc.).\n */\nfunction collectChapterSectionsDryRun(\n node: LevelNode,\n chapterNode: LevelNode,\n context: EmitContext,\n sectionMetas: SectionMeta[],\n): void {\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n sectionMetas.push(buildSectionMetaDryRun(child, chapterNode, context));\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n collectChapterSectionsDryRun(child, chapterNode, context, sectionMetas);\n }\n }\n}\n\nfunction collectSectionMetasFromTree(\n node: LevelNode,\n context: EmitContext,\n sectionMetas: SectionMeta[],\n currentChapter?: LevelNode | undefined,\n): void {\n for (const child of node.children) {\n if (child.type === \"level\" && child.levelType === \"section\") {\n sectionMetas.push(buildSectionMetaDryRun(child, currentChapter ?? null, context));\n } else if (child.type === \"level\" && BIG_LEVELS.has(child.levelType)) {\n const nextChapter = child.levelType === \"chapter\" ? child : currentChapter;\n collectSectionMetasFromTree(child, context, sectionMetas, nextChapter);\n }\n }\n}\n\nfunction buildOutputPath(\n context: EmitContext,\n sectionNum: string,\n outputRoot: string,\n /** Disambiguation suffix for duplicate section numbers (e.g., \"-2\") */\n dupSuffix?: string | undefined,\n): string {\n const titleDir = buildTitleDir(context);\n const chapterDir = buildChapterDir(context);\n const sectionFile = `section-${sectionNum}${dupSuffix ?? \"\"}.md`;\n\n if (chapterDir) {\n return join(outputRoot, \"usc\", titleDir, chapterDir, sectionFile);\n }\n\n return join(outputRoot, \"usc\", titleDir, sectionFile);\n}\n\n/**\n * Build the title directory name from context.\n * Handles appendix titles: docNumber \"5a\" → \"title-05-appendix\"\n */\nfunction buildTitleDir(context: EmitContext): string {\n // Check for appendix via docNumber (e.g., \"5a\", \"11a\")\n const docNum = context.documentMeta.docNumber ?? \"\";\n const appendixMatch = /^(\\d+)a$/i.exec(docNum);\n if (appendixMatch?.[1]) {\n return `title-${padTwo(appendixMatch[1])}-appendix`;\n }\n\n // Check for appendix ancestor\n const appendixAncestor = findAncestor(context.ancestors, \"appendix\");\n if (appendixAncestor) {\n const num = appendixAncestor.numValue ?? docNum;\n const numericPart = /^(\\d+)/.exec(num);\n if (numericPart?.[1]) {\n return `title-${padTwo(numericPart[1])}-appendix`;\n }\n }\n\n // Normal title\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"00\";\n return `title-${padTwo(titleNum)}`;\n}\n\n/**\n * Build the chapter directory name from context.\n * Handles chapter equivalents: compiledAct, reorganizationPlan.\n */\nfunction buildChapterDir(context: EmitContext): string | undefined {\n // Standard chapter\n const chapterNum = findAncestor(context.ancestors, \"chapter\")?.numValue;\n if (chapterNum) return `chapter-${padTwo(chapterNum)}`;\n\n // Compiled act as chapter equivalent\n const compiledAct = findAncestor(context.ancestors, \"compiledAct\");\n if (compiledAct) {\n const heading = compiledAct.heading?.trim() ?? \"\";\n // Use a slug of the heading as directory name\n const slug = heading\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 50);\n return slug || \"compiled-act\";\n }\n\n // Reorganization plan as chapter equivalent\n const reorgPlan = findAncestor(context.ancestors, \"reorganizationPlan\");\n if (reorgPlan) {\n const heading = reorgPlan.heading?.trim() ?? \"\";\n const slug = heading\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 50);\n return slug || \"reorganization-plan\";\n }\n\n // Reorganization plans container\n const reorgPlans = findAncestor(context.ancestors, \"reorganizationPlans\");\n if (reorgPlans) {\n return \"reorganization-plans\";\n }\n\n return undefined;\n}\n\n/**\n * Build FrontmatterData from the emitted section node and context.\n */\nfunction buildFrontmatter(node: LevelNode, context: EmitContext): FrontmatterData {\n const meta = context.documentMeta;\n const titleAncestor =\n findAncestor(context.ancestors, \"title\") ?? findAncestor(context.ancestors, \"appendix\");\n const chapterAncestor =\n findAncestor(context.ancestors, \"chapter\") ??\n findAncestor(context.ancestors, \"compiledAct\") ??\n findAncestor(context.ancestors, \"reorganizationPlan\");\n const subchapterAncestor = findAncestor(context.ancestors, \"subchapter\");\n const partAncestor = findAncestor(context.ancestors, \"part\");\n\n const docNum = meta.docNumber ?? titleAncestor?.numValue ?? \"0\";\n const titleNum = parseIntSafe(docNum.replace(/a$/i, \"\"));\n const sectionNum = node.numValue ?? \"0\";\n const sectionName = node.heading?.trim() ?? \"\";\n const titleName = titleAncestor?.heading?.trim() ?? meta.dcTitle ?? \"\";\n\n // Build the human-readable title: \"1 USC § 1 - Section Name\"\n const displayTitle = `${titleNum} USC § ${sectionNum} - ${sectionName}`;\n\n // Extract source credit text from the section's children\n const sourceCredit = extractSourceCreditText(node);\n\n // Parse currency from docPublicationName (e.g., \"Online@119-73not60\" → \"119-73\")\n const currency = parseCurrency(meta.docPublicationName ?? \"\");\n\n // Parse last_updated from created timestamp\n const lastUpdated = parseDate(meta.created ?? \"\");\n\n const fm: FrontmatterData = {\n source: \"usc\",\n legal_status: meta.positivelaw ? \"official_legal_evidence\" : \"official_prima_facie\",\n identifier: node.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n title: displayTitle,\n title_number: titleNum,\n title_name: titleName,\n section_number: sectionNum,\n section_name: sectionName,\n positive_law: meta.positivelaw ?? false,\n currency,\n last_updated: lastUpdated,\n };\n\n if (chapterAncestor?.numValue) {\n fm.chapter_number = parseIntSafe(chapterAncestor.numValue);\n }\n if (chapterAncestor?.heading) {\n fm.chapter_name = chapterAncestor.heading.trim();\n }\n if (subchapterAncestor?.numValue) {\n fm.subchapter_number = subchapterAncestor.numValue;\n }\n if (subchapterAncestor?.heading) {\n fm.subchapter_name = subchapterAncestor.heading.trim();\n }\n if (partAncestor?.numValue) {\n fm.part_number = partAncestor.numValue;\n }\n if (partAncestor?.heading) {\n fm.part_name = partAncestor.heading.trim();\n }\n if (sourceCredit) {\n fm.source_credit = sourceCredit;\n }\n if (node.status) {\n fm.status = node.status;\n }\n\n return fm;\n}\n\n// ---------------------------------------------------------------------------\n// Utility functions\n// ---------------------------------------------------------------------------\n\n/**\n * Build SectionMeta from AST node without rendering (for dry-run mode).\n */\nfunction buildSectionMetaDryRun(\n sectionNode: LevelNode,\n chapterNode: LevelNode | null,\n context: EmitContext,\n): SectionMeta {\n const titleNum = findAncestor(context.ancestors, \"title\")?.numValue ?? \"0\";\n const chapterAncestor = chapterNode\n ? {\n numValue: chapterNode.numValue,\n heading: chapterNode.heading,\n identifier: chapterNode.identifier,\n }\n : findAncestor(context.ancestors, \"chapter\");\n const sectionNum = sectionNode.numValue ?? \"0\";\n const chapterNum = chapterAncestor?.numValue ?? \"0\";\n const chapterDir = chapterNum !== \"0\" ? `chapter-${padTwo(chapterNum)}` : \"\";\n\n const hasNotes = sectionNode.children.some(\n (c) => c.type === \"notesContainer\" || c.type === \"note\",\n );\n\n // Rough content length estimate from AST text nodes\n let contentLength = 0;\n const walk = (node: {\n children?: readonly { text?: string | undefined; children?: readonly unknown[] }[] | undefined;\n text?: string | undefined;\n }): void => {\n if (node.text) contentLength += node.text.length;\n if (node.children) {\n for (const child of node.children) {\n walk(child as typeof node);\n }\n }\n };\n walk(sectionNode as unknown as Parameters<typeof walk>[0]);\n\n const sectionFileName = `section-${sectionNum}.md`;\n return {\n identifier: sectionNode.identifier ?? `/us/usc/t${titleNum}/s${sectionNum}`,\n number: sectionNum,\n name: sectionNode.heading?.trim() ?? \"\",\n fileName: sectionFileName,\n relativeFile: chapterDir ? `${chapterDir}/${sectionFileName}` : sectionFileName,\n contentLength,\n hasNotes,\n status: sectionNode.status ?? \"current\",\n chapterIdentifier: chapterAncestor?.identifier ?? \"\",\n chapterNumber: chapterNum,\n chapterName: chapterAncestor?.heading?.trim() ?? \"\",\n };\n}\n\nfunction buildNotesFilter(options: ConvertOptions): NotesFilter | undefined {\n // Default: include all notes\n if (options.includeNotes) return undefined;\n\n // No notes at all\n if (\n !options.includeEditorialNotes &&\n !options.includeStatutoryNotes &&\n !options.includeAmendments\n ) {\n return { editorial: false, statutory: false, amendments: false };\n }\n\n // Selective inclusion\n return {\n editorial: options.includeEditorialNotes,\n statutory: options.includeStatutoryNotes,\n amendments: options.includeAmendments,\n };\n}\n\nfunction findAncestor(\n ancestors: readonly AncestorInfo[],\n levelType: string,\n): AncestorInfo | undefined {\n return ancestors.find((a) => a.levelType === levelType);\n}\n\n/**\n * Build title directory name from docNumber.\n * \"5\" → \"title-05\", \"5a\" → \"title-05-appendix\"\n */\nfunction buildTitleDirFromDocNumber(docNum: string): string {\n const appendixMatch = /^(\\d+)a$/i.exec(docNum);\n if (appendixMatch?.[1]) {\n return `title-${padTwo(appendixMatch[1])}-appendix`;\n }\n return `title-${padTwo(docNum)}`;\n}\n\nfunction padTwo(num: string): string {\n const n = parseInt(num, 10);\n if (isNaN(n)) return num;\n return n.toString().padStart(2, \"0\");\n}\n\n/**\n * Parse an integer safely, returning 0 if invalid.\n */\nfunction parseIntSafe(s: string): number {\n const n = parseInt(s, 10);\n return isNaN(n) ? 0 : n;\n}\n\n/**\n * Extract source credit plain text from a section node's children.\n */\nfunction extractSourceCreditText(node: LevelNode): string | undefined {\n for (const child of node.children) {\n if (child.type === \"sourceCredit\") {\n return child.children.map((inline) => inlineToText(inline)).join(\"\");\n }\n }\n return undefined;\n}\n\n/**\n * Recursively extract plain text from an InlineNode.\n */\nfunction inlineToText(node: {\n readonly type: \"inline\";\n text?: string | undefined;\n children?: readonly { readonly type: \"inline\"; text?: string | undefined }[] | undefined;\n}): string {\n if (node.text) return node.text;\n if (node.children) {\n return node.children.map((c) => c.text ?? \"\").join(\"\");\n }\n return \"\";\n}\n\n/**\n * Parse currency/release point from docPublicationName.\n * Example: \"Online@119-73not60\" → \"119-73\"\n */\nfunction parseCurrency(pubName: string): string {\n // Try to extract the release point pattern (e.g., \"119-73\")\n const match = /(\\d+-\\d+)/.exec(pubName);\n if (match?.[1]) return match[1];\n return pubName || \"unknown\";\n}\n\n/**\n * Parse the full release point string from docPublicationName, including exclusion suffix.\n * Example: \"Online@119-73not60\" → \"119-73not60\"\n */\nfunction parseFullReleasePoint(pubName: string): string {\n const match = /(\\d+-\\d+(?:not\\d+)?)/.exec(pubName);\n if (match?.[1]) return match[1];\n return pubName || \"unknown\";\n}\n\n/**\n * Parse a date string to ISO date format (YYYY-MM-DD).\n */\nfunction parseDate(dateStr: string): string {\n if (!dateStr) return \"unknown\";\n // Handle ISO timestamp: \"2025-12-03T10:11:39\" → \"2025-12-03\"\n const datePart = dateStr.split(\"T\")[0];\n return datePart ?? dateStr;\n}\n\n/**\n * Create a copy of a section node with source credit children removed.\n */\nfunction stripSourceCredits(node: LevelNode): LevelNode {\n return {\n ...node,\n children: node.children.filter((c) => c.type !== \"sourceCredit\"),\n };\n}\n","/**\n * OLRC U.S. Code XML downloader.\n *\n * Downloads USC title XML zip files from the Office of the Law Revision Counsel\n * and extracts them to a local directory.\n *\n * By default, auto-detects the latest release point from the OLRC download page.\n * Falls back to a hardcoded release point if detection fails.\n */\n\nimport { createWriteStream } from \"node:fs\";\nimport { mkdir, stat, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { Readable } from \"node:stream\";\nimport { open as yauzlOpen } from \"yauzl\";\nimport type { ZipFile, Entry } from \"yauzl\";\nimport { detectLatestReleasePoint } from \"./release-points.js\";\n\n// ---------------------------------------------------------------------------\n// Release point configuration\n// ---------------------------------------------------------------------------\n\n/**\n * Fallback OLRC release point, used when auto-detection fails.\n *\n * The downloader auto-detects the latest release point from the OLRC\n * download page. This constant is only used as a last resort if the\n * page is unreachable or its format changes.\n */\nexport const FALLBACK_RELEASE_POINT = \"119-73not60\";\n\n/**\n * @deprecated Use `FALLBACK_RELEASE_POINT` instead.\n * Kept for backward compatibility with existing consumers.\n */\nexport const CURRENT_RELEASE_POINT = FALLBACK_RELEASE_POINT;\n\n/** OLRC base URL for release point downloads */\nconst OLRC_BASE_URL = \"https://uscode.house.gov/download/releasepoints/us/pl\";\n\n/** Valid USC title numbers (1-54) */\nexport const USC_TITLE_NUMBERS = Array.from({ length: 54 }, (_, i) => i + 1);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether a list of title numbers covers all 54 USC titles.\n *\n * Handles arbitrary ordering and duplicates.\n */\nexport function isAllTitles(titles: number[]): boolean {\n const unique = new Set(titles);\n return unique.size === 54 && USC_TITLE_NUMBERS.every((n) => unique.has(n));\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Options for downloading USC XML files */\nexport interface DownloadOptions {\n /** Directory to save downloaded XML files */\n outputDir: string;\n /** Specific title numbers to download, or undefined for all */\n titles?: number[] | undefined;\n /** Release point override (default: CURRENT_RELEASE_POINT) */\n releasePoint?: string | undefined;\n}\n\n/** Result of a download operation */\nexport interface DownloadResult {\n /** Release point used */\n releasePoint: string;\n /** Files successfully downloaded and extracted */\n files: DownloadedFile[];\n /** Titles that failed to download */\n errors: DownloadError[];\n}\n\n/** A successfully downloaded file */\nexport interface DownloadedFile {\n /** Title number */\n titleNumber: number;\n /** Path to the extracted XML file */\n filePath: string;\n /** Size in bytes */\n size: number;\n}\n\n/** A failed download */\nexport interface DownloadError {\n /** Title number */\n titleNumber: number;\n /** Error message */\n message: string;\n}\n\n/**\n * Download USC title XML files from OLRC.\n *\n * Auto-detects the latest release point from the OLRC download page unless\n * an explicit release point is provided via `options.releasePoint`.\n *\n * When all 54 titles are requested, uses the bulk `uscAll` zip for a single\n * HTTP round-trip instead of 54 individual requests. Falls back to per-title\n * downloads if the bulk download fails.\n */\nexport async function downloadTitles(options: DownloadOptions): Promise<DownloadResult> {\n let releasePoint = options.releasePoint;\n if (!releasePoint) {\n const detected = await detectLatestReleasePoint();\n releasePoint = detected?.releasePoint ?? FALLBACK_RELEASE_POINT;\n }\n const titles = options.titles ?? USC_TITLE_NUMBERS;\n\n await mkdir(options.outputDir, { recursive: true });\n\n // Use bulk zip when all 54 titles are requested\n if (options.titles === undefined || isAllTitles(titles)) {\n try {\n const files = await downloadAndExtractAllTitles(releasePoint, options.outputDir);\n return { releasePoint, files, errors: [] };\n } catch {\n // Fall back to per-title downloads\n }\n }\n\n const files: DownloadedFile[] = [];\n const errors: DownloadError[] = [];\n\n for (const titleNum of titles) {\n try {\n const file = await downloadAndExtractTitle(titleNum, releasePoint, options.outputDir);\n files.push(file);\n } catch (err) {\n errors.push({\n titleNumber: titleNum,\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { releasePoint, files, errors };\n}\n\n// ---------------------------------------------------------------------------\n// URL construction\n// ---------------------------------------------------------------------------\n\n/**\n * Build the download URL for a single title's XML zip.\n *\n * Format: {base}/pl/{releasePointPath}/xml_usc{NN}@{releasePoint}.zip\n *\n * The release point path splits the release point into directory segments.\n * For \"119-73not60\", the path is \"119/73not60\".\n */\nexport function buildDownloadUrl(titleNumber: number, releasePoint: string): string {\n const paddedTitle = titleNumber.toString().padStart(2, \"0\");\n const rpPath = releasePointToPath(releasePoint);\n return `${OLRC_BASE_URL}/${rpPath}/xml_usc${paddedTitle}@${releasePoint}.zip`;\n}\n\n/**\n * Build the download URL for all titles in a single zip.\n */\nexport function buildAllTitlesUrl(releasePoint: string): string {\n const rpPath = releasePointToPath(releasePoint);\n return `${OLRC_BASE_URL}/${rpPath}/xml_uscAll@${releasePoint}.zip`;\n}\n\n/**\n * Convert a release point string to a URL path segment.\n * \"119-73not60\" → \"119/73not60\"\n * \"119-43\" → \"119/43\"\n */\nexport function releasePointToPath(releasePoint: string): string {\n // Split on the first hyphen only\n const dashIndex = releasePoint.indexOf(\"-\");\n if (dashIndex === -1) return releasePoint;\n return `${releasePoint.slice(0, dashIndex)}/${releasePoint.slice(dashIndex + 1)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Download and extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Download a single title's zip and extract the XML file.\n */\nasync function downloadAndExtractTitle(\n titleNumber: number,\n releasePoint: string,\n outputDir: string,\n): Promise<DownloadedFile> {\n const url = buildDownloadUrl(titleNumber, releasePoint);\n const paddedTitle = titleNumber.toString().padStart(2, \"0\");\n const zipPath = join(outputDir, `usc${paddedTitle}.zip`);\n const xmlFileName = `usc${paddedTitle}.xml`;\n const xmlPath = join(outputDir, xmlFileName);\n\n // Download the zip file\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText} for ${url}`);\n }\n\n if (!response.body) {\n throw new Error(`No response body for ${url}`);\n }\n\n // Write zip to disk\n const fileStream = createWriteStream(zipPath);\n // ReadableStream type mismatch between DOM and Node — cast to `never` to bridge\n await pipeline(Readable.fromWeb(response.body as never), fileStream);\n\n // Extract XML from zip\n await extractXmlFromZip(zipPath, xmlFileName, xmlPath);\n\n // Clean up zip file\n await unlink(zipPath);\n\n // Get file size\n const fileStat = await stat(xmlPath);\n\n return {\n titleNumber,\n filePath: xmlPath,\n size: fileStat.size,\n };\n}\n\n/**\n * Extract a specific XML file from a zip archive.\n */\nfunction extractXmlFromZip(\n zipPath: string,\n targetFileName: string,\n outputPath: string,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n yauzlOpen(zipPath, { lazyEntries: true }, (err, zipFile) => {\n if (err) {\n reject(new Error(`Failed to open zip: ${err.message}`));\n return;\n }\n if (!zipFile) {\n reject(new Error(\"Failed to open zip: no zipFile returned\"));\n return;\n }\n\n let found = false;\n\n zipFile.on(\"entry\", (entry: Entry) => {\n // Look for the target XML file (might be at root or in a subdirectory)\n const fileName = entry.fileName.split(\"/\").pop() ?? entry.fileName;\n if (fileName === targetFileName || entry.fileName.endsWith(`.xml`)) {\n found = true;\n extractEntry(zipFile, entry, outputPath)\n .then(() => {\n zipFile.close();\n resolve();\n })\n .catch((extractErr) => {\n zipFile.close();\n reject(extractErr);\n });\n } else {\n zipFile.readEntry();\n }\n });\n\n zipFile.on(\"end\", () => {\n if (!found) {\n reject(new Error(`${targetFileName} not found in zip`));\n }\n });\n\n zipFile.on(\"error\", (zipErr: Error) => {\n reject(new Error(`Zip error: ${zipErr.message}`));\n });\n\n zipFile.readEntry();\n });\n });\n}\n\n/**\n * Extract a single zip entry to a file.\n */\nfunction extractEntry(zipFile: ZipFile, entry: Entry, outputPath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n zipFile.openReadStream(entry, (err, readStream) => {\n if (err) {\n reject(new Error(`Failed to read zip entry: ${err.message}`));\n return;\n }\n if (!readStream) {\n reject(new Error(\"No read stream for zip entry\"));\n return;\n }\n\n const writeStream = createWriteStream(outputPath);\n readStream.pipe(writeStream);\n\n writeStream.on(\"finish\", () => resolve());\n writeStream.on(\"error\", (writeErr) => reject(new Error(`Write error: ${writeErr.message}`)));\n readStream.on(\"error\", (readErr) => reject(new Error(`Read error: ${readErr.message}`)));\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Bulk download (all titles in one zip)\n// ---------------------------------------------------------------------------\n\n/** Regex matching USC XML filenames like usc01.xml, usc54.xml */\nconst USC_XML_RE = /^(?:.*\\/)?usc(\\d{2})\\.xml$/;\n\n/**\n * Extract all `usc{NN}.xml` files from a bulk zip archive.\n *\n * Returns an array of `{ titleNumber, filePath }` for each extracted file.\n */\nfunction extractAllXmlFromZip(\n zipPath: string,\n outputDir: string,\n): Promise<{ titleNumber: number; filePath: string }[]> {\n return new Promise((resolve, reject) => {\n yauzlOpen(zipPath, { lazyEntries: true }, (err, zipFile) => {\n if (err) {\n reject(new Error(`Failed to open zip: ${err.message}`));\n return;\n }\n if (!zipFile) {\n reject(new Error(\"Failed to open zip: no zipFile returned\"));\n return;\n }\n\n const extracted: { titleNumber: number; filePath: string }[] = [];\n let pending = 0;\n let ended = false;\n\n const maybeResolve = (): void => {\n if (ended && pending === 0) {\n resolve(extracted);\n }\n };\n\n zipFile.on(\"entry\", (entry: Entry) => {\n const match = USC_XML_RE.exec(entry.fileName);\n if (match) {\n const titleNum = parseInt(match[1] ?? \"0\", 10);\n const outPath = join(outputDir, `usc${match[1] ?? \"00\"}.xml`);\n pending++;\n\n extractEntry(zipFile, entry, outPath)\n .then(() => {\n extracted.push({ titleNumber: titleNum, filePath: outPath });\n pending--;\n // Continue reading entries after extraction completes\n zipFile.readEntry();\n maybeResolve();\n })\n .catch((extractErr) => {\n zipFile.close();\n reject(extractErr);\n });\n } else {\n zipFile.readEntry();\n }\n });\n\n zipFile.on(\"end\", () => {\n ended = true;\n maybeResolve();\n });\n\n zipFile.on(\"error\", (zipErr: Error) => {\n reject(new Error(`Zip error: ${zipErr.message}`));\n });\n\n zipFile.readEntry();\n });\n });\n}\n\n/**\n * Download the bulk all-titles zip and extract every `usc{NN}.xml` file.\n */\nasync function downloadAndExtractAllTitles(\n releasePoint: string,\n outputDir: string,\n): Promise<DownloadedFile[]> {\n const url = buildAllTitlesUrl(releasePoint);\n const zipPath = join(outputDir, \"uscAll.zip\");\n\n // Download the zip file\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText} for ${url}`);\n }\n\n if (!response.body) {\n throw new Error(`No response body for ${url}`);\n }\n\n // Write zip to disk\n const fileStream = createWriteStream(zipPath);\n await pipeline(Readable.fromWeb(response.body as never), fileStream);\n\n // Extract all XML files from zip\n const extracted = await extractAllXmlFromZip(zipPath, outputDir);\n\n // Clean up zip file\n await unlink(zipPath);\n\n // Stat each extracted file and build results\n const files: DownloadedFile[] = [];\n for (const { titleNumber, filePath } of extracted) {\n const fileStat = await stat(filePath);\n files.push({ titleNumber, filePath, size: fileStat.size });\n }\n\n // Sort by title number for consistent ordering\n files.sort((a, b) => a.titleNumber - b.titleNumber);\n\n return files;\n}\n","/**\n * OLRC release point detection.\n *\n * Scrapes the OLRC download page to detect the latest release point,\n * eliminating the need to hardcode release point identifiers.\n */\n\n/** OLRC download page URL */\nconst OLRC_DOWNLOAD_PAGE = \"https://uscode.house.gov/download/download.shtml\";\n\n/** Detected release point information */\nexport interface ReleasePointInfo {\n /** Release point identifier (e.g., \"119-73not60\") */\n releasePoint: string;\n /** Human-readable description (e.g., \"Public Law 119-73 (01/23/2026) , except 119-60\") */\n description: string;\n}\n\n/**\n * Detect the latest OLRC release point by scraping the download page.\n *\n * Uses two extraction strategies for redundancy:\n * 1. Parse the release point from download URL hrefs (most reliable)\n * 2. Fall back to parsing the release point info heading\n *\n * Returns `null` if the page cannot be fetched or parsed.\n */\nexport async function detectLatestReleasePoint(): Promise<ReleasePointInfo | null> {\n let html: string;\n try {\n const response = await fetch(OLRC_DOWNLOAD_PAGE);\n if (!response.ok) return null;\n html = await response.text();\n } catch {\n return null;\n }\n\n return parseReleasePointFromHtml(html);\n}\n\n/**\n * Parse the release point from OLRC download page HTML.\n *\n * Exported for testing — prefer `detectLatestReleasePoint()` for production use.\n */\nexport function parseReleasePointFromHtml(html: string): ReleasePointInfo | null {\n // Strategy 1: Extract from download URL hrefs\n // Links look like: href=\"...xml_uscAll@119-73not60.zip\"\n const urlMatch = /xml_uscAll@([\\w-]+)\\.zip/.exec(html);\n if (urlMatch?.[1]) {\n const releasePoint = urlMatch[1];\n const description = parseDescription(html);\n return { releasePoint, description };\n }\n\n // Strategy 2: Extract from any single-title download URL\n // Links look like: href=\"...xml_usc01@119-73not60.zip\"\n const singleUrlMatch = /xml_usc\\d{2}@([\\w-]+)\\.zip/.exec(html);\n if (singleUrlMatch?.[1]) {\n const releasePoint = singleUrlMatch[1];\n const description = parseDescription(html);\n return { releasePoint, description };\n }\n\n return null;\n}\n\n/**\n * Parse the human-readable description from the release point heading.\n *\n * Uses indexOf-based extraction (not regex) to avoid polynomial backtracking\n * on untrusted HTML input.\n *\n * The heading looks like:\n * `<h3 class=\"releasepointinformation\">Public Law 119-73 (01/23/2026) , except 119-60</h3>`\n */\nfunction parseDescription(html: string): string {\n const marker = 'class=\"releasepointinformation\">';\n const startIdx = html.indexOf(marker);\n if (startIdx === -1) return \"\";\n const contentStart = startIdx + marker.length;\n const endIdx = html.indexOf(\"</h3>\", contentStart);\n if (endIdx === -1) return \"\";\n return html.slice(contentStart, endIdx).trim();\n}\n"],"mappings":";AAOA,SAAS,wBAAwB;AACjC,SAAS,MAAM,eAAe;AAC9B,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAyDP,IAAM,WAAqD;AAAA,EACzD,aAAa;AAAA,EACb,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,cAAc;AAAA,EACd,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,QAAQ;AACV;AA8BA,eAAsB,aAAa,SAAiD;AAClF,QAAM,OAAO,EAAE,GAAG,UAAU,GAAG,QAAQ;AACvC,QAAM,QAAkB,CAAC;AACzB,MAAI,aAAa,QAAQ,YAAY,IAAI;AACzC,MAAI;AAGJ,QAAM,YAAgC,CAAC;AAGvC,QAAM,SACJ,KAAK,gBAAgB,UAChB,UACD,KAAK,gBAAgB,YAClB,YACA;AACT,QAAM,UAAU,IAAI,WAAW;AAAA,IAC7B;AAAA,IACA,QAAQ,CAAC,MAAM,YAAY;AACzB,gBAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,IAClC;AAAA,EACF,CAAC;AAGD,QAAM,SAAS,IAAI,UAAU;AAC7B,SAAO,GAAG,eAAe,CAAC,MAAM,UAAU,QAAQ,cAAc,MAAM,KAAK,CAAC;AAC5E,SAAO,GAAG,gBAAgB,CAAC,SAAS,QAAQ,eAAe,IAAI,CAAC;AAChE,SAAO,GAAG,QAAQ,CAAC,SAAS,QAAQ,OAAO,IAAI,CAAC;AAGhD,QAAM,SAAS,iBAAiB,KAAK,OAAO,OAAO;AACnD,QAAM,OAAO,YAAY,MAAM;AAC/B,eAAa,KAAK,IAAI,YAAY,QAAQ,YAAY,IAAI,CAAC;AAE3D,QAAM,eAA8B,CAAC;AACrC,QAAM,OAAO,QAAQ,gBAAgB;AAErC,MAAI,KAAK,QAAQ;AAEf,eAAW,EAAE,MAAM,QAAQ,KAAK,WAAW;AACzC,UAAI,KAAK,gBAAgB,SAAS;AAEhC,oCAA4B,MAAM,SAAS,YAAY;AAAA,MACzD,WAAW,KAAK,gBAAgB,WAAW;AAEzC,qCAA6B,MAAM,MAAM,SAAS,YAAY;AAAA,MAChE,OAAO;AACL,YAAI,KAAK,UAAU;AACjB,uBAAa,KAAK,uBAAuB,MAAM,MAAM,OAAO,CAAC;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,KAAK,gBAAgB,SAAS;AAEvC,QAAI,qBAAqB;AACzB,eAAW,EAAE,MAAM,QAAQ,KAAK,WAAW;AACzC,YAAM,SAAS,MAAM,gBAAgB,MAAM,SAAS,IAAI;AACxD,YAAM,KAAK,OAAO,QAAQ;AAC1B,4BAAsB,OAAO;AAC7B,iBAAW,KAAK,OAAO,cAAc;AACnC,qBAAa,KAAK,CAAC;AAAA,MACrB;AAAA,IACF;AAEA,8BAA0B;AAAA,EAC5B,WAAW,KAAK,gBAAgB,WAAW;AAEzC,eAAW,EAAE,MAAM,QAAQ,KAAK,WAAW;AACzC,YAAM,SAAS,MAAM,aAAa,MAAM,SAAS,IAAI;AACrD,UAAI,QAAQ;AACV,cAAM,KAAK,OAAO,QAAQ;AAC1B,mBAAW,KAAK,OAAO,cAAc;AACnC,uBAAa,KAAK,CAAC;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AAGL,UAAM,gBAAgB,oBAAI,IAAoB;AAC9C,UAAM,WAAmC,CAAC;AAC1C,eAAW,EAAE,MAAM,QAAQ,KAAK,WAAW;AACzC,YAAM,aAAa,KAAK;AACxB,UAAI,CAAC,YAAY;AACf,iBAAS,KAAK,MAAS;AACvB;AAAA,MACF;AACA,YAAM,aAAa,gBAAgB,OAAO,KAAK;AAC/C,YAAM,MAAM,GAAG,UAAU,IAAI,UAAU;AACvC,YAAM,SAAS,cAAc,IAAI,GAAG,KAAK,KAAK;AAC9C,oBAAc,IAAI,KAAK,KAAK;AAC5B,eAAS,KAAK,QAAQ,IAAI,IAAI,KAAK,KAAK,MAAS;AAAA,IACnD;AAEA,UAAM,eAAe,mBAAmB;AACxC,eAAW,CAAC,GAAG,EAAE,MAAM,QAAQ,CAAC,KAAK,UAAU,QAAQ,GAAG;AACxD,YAAM,aAAa,KAAK;AACxB,UAAI,cAAc,KAAK,YAAY;AACjC,cAAM,WAAW,gBAAgB,SAAS,YAAY,KAAK,QAAQ,SAAS,CAAC,CAAC;AAE9E,cAAM,QAAQ,SAAS,CAAC,IAAI,GAAG,KAAK,UAAU,IAAI,SAAS,CAAC,CAAC,KAAK,KAAK;AACvE,qBAAa,SAAS,OAAO,QAAQ;AAErC,YAAI,CAAC,SAAS,CAAC,GAAG;AAChB,uBAAa,SAAS,KAAK,YAAY,QAAQ;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAEA,eAAW,CAAC,GAAG,EAAE,MAAM,QAAQ,CAAC,KAAK,UAAU,QAAQ,GAAG;AACxD,YAAM,SAAS,MAAM,aAAa,MAAM,SAAS,MAAM,cAAc,SAAS,CAAC,CAAC;AAChF,UAAI,QAAQ;AACV,cAAM,KAAK,OAAO,QAAQ;AAC1B,qBAAa,KAAK,OAAO,IAAI;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,iBAAiB,UAAU,CAAC;AAClC,QAAM,eAAe,iBACjB,KAAK,gBAAgB,UACnB,eAAe,KAAK,SAAS,KAAK,IAClC,aAAa,eAAe,QAAQ,WAAW,OAAO,GAAG,SAAS,KAAK,IACzE;AAGJ,MAAI,CAAC,KAAK,QAAQ;AAChB,UAAM,eAAe,cAAc,MAAM,MAAM,YAAY;AAAA,EAC7D;AAGA,eAAa,KAAK,IAAI,YAAY,QAAQ,YAAY,IAAI,CAAC;AAG3D,QAAM,aAAa,IAAI,IAAI,aAAa,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,OAAO,CAAC;AAGvF,QAAM,cACJ,2BACA,aAAa,OAAO,CAAC,KAAK,MAAM,MAAM,KAAK,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC;AAEzE,SAAO;AAAA,IACL,iBACE,KAAK,UAAU,KAAK,gBAAgB,WAAW,KAAK,gBAAgB,YAChE,aAAa,SACb,MAAM;AAAA,IACZ;AAAA,IACA,aAAa,KAAK,aAAa;AAAA,IAC/B,WAAW,gBAAgB,KAAK,WAAW;AAAA,IAC3C,QAAQ,KAAK;AAAA,IACb,cAAc,WAAW;AAAA,IACzB,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,EACnB;AACF;AAYA,eAAe,aACb,MACA,SACA,SACA,cAEA,WACoC;AACpC,QAAM,aAAa,KAAK;AACxB,MAAI,CAAC,WAAY,QAAO;AAGxB,QAAM,WAAW,gBAAgB,SAAS,YAAY,QAAQ,QAAQ,SAAS;AAG/E,QAAM,cAAc,iBAAiB,MAAM,OAAO;AAGlD,QAAM,cAAc,iBAAiB,OAAO;AAG5C,QAAM,aAA4B;AAAA,IAChC,eAAe;AAAA,IACf,WAAW,QAAQ;AAAA,IACnB,aAAa,eACT,CAAC,eAAuB,aAAa,QAAQ,YAAY,QAAQ,IACjE;AAAA,IACJ;AAAA,EACF;AAGA,QAAM,cAAc,QAAQ,uBAAuB,OAAO,mBAAmB,IAAI;AAGjF,QAAM,WAAW,eAAe,aAAa,aAAa,UAAU;AAGpE,QAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,QAAM,UAAU,UAAU,UAAU,OAAO;AAG3C,QAAM,WAAW,aAAa,QAAQ,WAAW,OAAO,GAAG,YAAY;AACvE,QAAM,kBAAkB,aAAa,QAAQ,WAAW,SAAS;AACjE,QAAM,aAAa,iBAAiB,WAAW,WAAW,OAAO,gBAAgB,QAAQ,CAAC,KAAK;AAC/F,QAAM,kBAAkB,WAAW,UAAU,GAAG,aAAa,EAAE;AAC/D,QAAM,eAAe,aAAa,GAAG,UAAU,IAAI,eAAe,KAAK;AAEvE,QAAM,WAAW,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,SAAS,MAAM;AAE3F,QAAM,cAA2B;AAAA,IAC/B,YAAY,KAAK,cAAc,YAAY,QAAQ,KAAK,UAAU;AAAA,IAClE,QAAQ;AAAA,IACR,MAAM,KAAK,SAAS,KAAK,KAAK;AAAA,IAC9B,UAAU;AAAA,IACV;AAAA,IACA,eAAe,SAAS;AAAA,IACxB;AAAA,IACA,QAAQ,KAAK,UAAU;AAAA,IACvB,mBAAmB,iBAAiB,cAAc;AAAA,IAClD,eAAe,iBAAiB,YAAY;AAAA,IAC5C,aAAa,iBAAiB,SAAS,KAAK,KAAK;AAAA,EACnD;AAEA,SAAO,EAAE,UAAU,MAAM,YAAY;AACvC;AAKA,eAAe,eACb,cACA,SAQA,SACA,cACe;AACf,MAAI,aAAa,WAAW,EAAG;AAC/B,MAAI,QAAQ,gBAAgB,QAAS;AAErC,QAAM,SAAS,QAAQ,aAAa;AACpC,QAAM,eAAe,2BAA2B,MAAM;AACtD,QAAM,WAAW,KAAK,QAAQ,QAAQ,OAAO,YAAY;AACzD,QAAM,WAAW,cAAc,QAAQ,sBAAsB,EAAE;AAG/D,QAAM,aAAa,oBAAI,IAA2B;AAClD,aAAW,MAAM,cAAc;AAC7B,UAAM,MAAM,GAAG,qBAAqB;AACpC,QAAI,MAAM,WAAW,IAAI,GAAG;AAC5B,QAAI,CAAC,KAAK;AACR,YAAM,CAAC;AACP,iBAAW,IAAI,KAAK,GAAG;AAAA,IACzB;AACA,QAAI,KAAK,EAAE;AAAA,EACb;AAGA,QAAM,iBAcD,CAAC;AAEN,aAAW,CAAC,WAAW,eAAe,KAAK,YAAY;AACrD,QAAI,cAAc,iBAAkB;AAEpC,UAAM,QAAQ,gBAAgB,CAAC;AAC/B,QAAI,CAAC,MAAO;AAEZ,UAAM,aAAa,WAAW,OAAO,MAAM,aAAa,CAAC;AAEzD,UAAM,WAAW,gBAAgB,IAAI,CAAC,QAAQ;AAAA,MAC5C,YAAY,GAAG;AAAA,MACf,QAAQ,GAAG;AAAA,MACX,MAAM,GAAG;AAAA,MACT,MAAM,GAAG;AAAA,MACT,gBAAgB,KAAK,KAAK,GAAG,gBAAgB,CAAC;AAAA,MAC9C,WAAW,GAAG;AAAA,MACd,QAAQ,GAAG;AAAA,IACb,EAAE;AAEF,UAAM,cAAc;AAAA,MAClB,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,gBAAgB,aAAa,MAAM,aAAa;AAAA,MAChD,cAAc,MAAM;AAAA,MACpB,cAAc,aAAa,MAAM;AAAA,MACjC,eAAe,SAAS;AAAA,MACxB;AAAA,IACF;AAEA,UAAM,kBAAkB,KAAK,UAAU,YAAY,YAAY;AAC/D,UAAM,MAAM,QAAQ,eAAe,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,UAAM,UAAU,iBAAiB,KAAK,UAAU,aAAa,MAAM,CAAC,IAAI,MAAM,OAAO;AAErF,mBAAe,KAAK;AAAA,MAClB,YAAY;AAAA,MACZ,QAAQ,aAAa,MAAM,aAAa;AAAA,MACxC,MAAM,MAAM;AAAA,MACZ,WAAW;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,cAAc,aAAa,OAAO,CAAC,KAAK,OAAO,MAAM,KAAK,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC;AAE7F,QAAM,eAAe,sBAAsB,QAAQ,sBAAsB,EAAE;AAE3E,QAAM,YAAY;AAAA,IAChB,gBAAgB;AAAA,IAChB,WAAW;AAAA,IACX,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,YAAY,QAAQ,cAAc,YAAY,MAAM;AAAA,IACpD,cAAc,aAAa,MAAM;AAAA,IACjC,YAAY,gBAAgB,QAAQ,WAAW;AAAA,IAC/C,cAAc,QAAQ,eAAe;AAAA,IACrC;AAAA,IACA,eAAe;AAAA,IACf,YAAY,SAAS,QAAQ,KAAK;AAAA,IAClC,aAAa,QAAQ;AAAA,IACrB,OAAO;AAAA,MACL,eAAe,eAAe;AAAA,MAC9B,eAAe,aAAa;AAAA,MAC5B,aAAa,aAAa;AAAA,MAC1B,uBAAuB;AAAA,IACzB;AAAA,IACA,UAAU;AAAA,EACZ;AAEA,QAAM,gBAAgB,KAAK,UAAU,YAAY;AACjD,QAAM,MAAM,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAM,UAAU,eAAe,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI,MAAM,OAAO;AAGjF,QAAM,aAAa,KAAK,UAAU,WAAW;AAC7C,QAAM,SAAS,oBAAoB,SAAS;AAC5C,QAAM,UAAU,YAAY,QAAQ,OAAO;AAC7C;AAKA,SAAS,oBAAoB,MAsBlB;AACT,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,WAAW,KAAK,YAAY,WAAM,KAAK,UAAU,EAAE;AAC9D,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,OAAO;AAClB,QAAM,KAAK,eAAe;AAC1B,QAAM,KAAK,wBAAwB,KAAK,eAAe,QAAQ,IAAI,IAAI;AACvE,QAAM,KAAK,oBAAoB,KAAK,YAAY,SAAS,IAAI;AAC7D,QAAM,KAAK,oBAAoB,KAAK,MAAM,aAAa,IAAI;AAC3D,QAAM,KAAK,oBAAoB,KAAK,MAAM,cAAc,eAAe,CAAC,IAAI;AAC5E,QAAM,KAAK,uBAAuB,KAAK,MAAM,sBAAsB,eAAe,CAAC,IAAI;AACvF,QAAM,KAAK,uBAAuB,KAAK,WAAW,IAAI;AACtD,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,EAAE;AAEb,aAAW,MAAM,KAAK,UAAU;AAC9B,UAAM,eAAe,GAAG,SAAS;AACjC,UAAM,KAAK,eAAe,GAAG,MAAM,WAAM,GAAG,IAAI,EAAE;AAClD,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJ,GAAG,YAAY,WAAW,iBAAiB,IAAI,MAAM,EAAE,UAAO,GAAG,SAAS,MAAM,GAAG,SAAS;AAAA,IAC9F;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,qEAAqE;AAChF,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AACxB;AAYA,eAAe,aACb,aACA,SACA,SACoC;AACpC,QAAM,aAAa,YAAY;AAC/B,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,WAAW,aAAa,QAAQ,WAAW,OAAO,GAAG,YAAY;AACvE,QAAM,WAAW,SAAS,OAAO,QAAQ,CAAC;AAC1C,QAAM,aAAa,WAAW,OAAO,UAAU,CAAC;AAChD,QAAM,cAAc,WAAW,OAAO,UAAU,CAAC;AACjD,QAAM,WAAW,KAAK,QAAQ,QAAQ,OAAO,UAAU,YAAY,WAAW;AAG9E,QAAM,gBAAgB,aAAa,QAAQ,WAAW,OAAO;AAC7D,QAAM,OAAO,QAAQ;AACrB,QAAM,cAAc,YAAY,SAAS,KAAK,KAAK;AACnD,QAAM,YAAY,eAAe,SAAS,KAAK,KAAK,KAAK,WAAW;AACpE,QAAM,WAAW,cAAc,KAAK,sBAAsB,EAAE;AAC5D,QAAM,cAAc,UAAU,KAAK,WAAW,EAAE;AAEhD,QAAM,SAA0B;AAAA,IAC9B,QAAQ;AAAA,IACR,cAAc,KAAK,cAAc,4BAA4B;AAAA,IAC7D,YAAY,YAAY,cAAc,YAAY,QAAQ,MAAM,UAAU;AAAA,IAC1E,OAAO,GAAG,QAAQ,gBAAgB,UAAU,MAAM,WAAW;AAAA,IAC7D,cAAc,aAAa,QAAQ;AAAA,IACnC,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,gBAAgB,aAAa,UAAU;AAAA,IACvC,cAAc;AAAA,IACd,cAAc,KAAK,eAAe;AAAA,IAClC;AAAA,IACA,cAAc;AAAA,EAChB;AAEA,QAAM,cAAc,iBAAiB,OAAO;AAC5C,QAAM,aAA4B;AAAA,IAChC,eAAe;AAAA,IACf,WAAW,QAAQ;AAAA,IACnB;AAAA,EACF;AAGA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,oBAAoB,MAAM,CAAC;AACtC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,aAAa,UAAU,WAAM,WAAW,EAAE;AAGrD,QAAM,eAA8B,CAAC;AAErC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,cAAc;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,KAAK,IAAI,IAAI;AAEpC,QAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,QAAM,UAAU,UAAU,UAAU,OAAO;AAE3C,SAAO,EAAE,UAAU,aAAa;AAClC;AAMA,SAAS,sBACP,MACA,cACA,SACA,YACA,OACA,cACA,UACA,mBACA,YACA,aACA,aACM;AACN,aAAW,SAAS,KAAK,UAAU;AACjC,QAAI,MAAM,SAAS,WAAW,MAAM,cAAc,WAAW;AAC3D,YAAM,cAA6B;AAAA,QACjC,GAAG;AAAA,QACH,eAAe,KAAK,IAAI,eAAe,GAAG,CAAC;AAAA,MAC7C;AACA,YAAM,cAAc,QAAQ,uBAAuB,QAAQ,mBAAmB,KAAK;AACnF,YAAM,YAAY,cAAc,aAAa,WAAW;AACxD,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,SAAS;AAEpB,YAAM,aAAa,MAAM,YAAY;AACrC,YAAM,WAAW,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,SAAS,MAAM;AAC5F,mBAAa,KAAK;AAAA,QAChB,YAAY,MAAM,cAAc,YAAY,QAAQ,KAAK,UAAU;AAAA,QACnE,QAAQ;AAAA,QACR,MAAM,MAAM,SAAS,KAAK,KAAK;AAAA,QAC/B,UAAU,WAAW,UAAU;AAAA,QAC/B,cAAc,WAAW,OAAO,UAAU,CAAC,IAAI,WAAW;AAAA,QAC1D,eAAe,UAAU;AAAA,QACzB;AAAA,QACA,QAAQ,MAAM,UAAU;AAAA,QACxB;AAAA,QACA,eAAe;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH,WAAW,MAAM,SAAS,WAAW,WAAW,IAAI,MAAM,SAAS,GAAG;AAEpE,YAAM,aAAa,MAAM,OAAO;AAChC,YAAM,UAAU,MAAM,UAAU,IAAI,MAAM,OAAO,KAAK;AACtD,YAAM,KAAK,EAAE;AACb,UAAI,gBAAgB,GAAG;AACrB,cAAM,SAAS,IAAI,OAAO,YAAY;AACtC,cAAM,KAAK,GAAG,MAAM,IAAI,UAAU,GAAG,OAAO,EAAE;AAAA,MAChD,OAAO;AACL,cAAM,KAAK,KAAK,UAAU,GAAG,OAAO,IAAI;AAAA,MAC1C;AAEA;AAAA,QACE;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AAEL,YAAM,WAAW,WAAW,OAAkB,UAAU;AACxD,UAAI,UAAU;AACZ,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAcA,eAAe,gBACb,WACA,SACA,SAC2B;AAC3B,QAAM,OAAO,QAAQ;AACrB,QAAM,SAAS,KAAK,aAAa,UAAU,YAAY;AACvD,QAAM,WAAW,OAAO,QAAQ,OAAO,EAAE;AACzC,QAAM,YAAY,UAAU,SAAS,KAAK,KAAK,KAAK,WAAW;AAC/D,QAAM,WAAW,cAAc,KAAK,sBAAsB,EAAE;AAC5D,QAAM,cAAc,UAAU,KAAK,WAAW,EAAE;AAEhD,QAAM,cAAc,iBAAiB,OAAO;AAC5C,QAAM,aAA4B;AAAA,IAChC,eAAe;AAAA,IACf,WAAW,QAAQ;AAAA,IACnB;AAAA,EACF;AAGA,QAAM,eAA8B,CAAC;AACrC,QAAM,YAAY,oBAAoB,WAAW,GAAG,SAAS,YAAY,cAAc,QAAQ;AAG/F,QAAM,oBAA8B,CAAC;AACrC,QAAM,aAAa,UAAU,OAAO;AACpC,QAAM,cAAc,UAAU,UAAU,IAAI,UAAU,OAAO,KAAK;AAClE,oBAAkB,KAAK,KAAK,UAAU,GAAG,WAAW,EAAE;AACtD,oBAAkB,KAAK,GAAG,SAAS;AACnC,QAAM,eAAe,kBAAkB,KAAK,IAAI;AAIhD,QAAM,SAA0B;AAAA,IAC9B,QAAQ;AAAA,IACR,cAAc,KAAK,cAAc,4BAA4B;AAAA,IAC7D,YAAY,UAAU,cAAc,KAAK,cAAc,YAAY,QAAQ;AAAA,IAC3E,OAAO,SAAS,QAAQ,WAAM,SAAS;AAAA,IACvC,cAAc,aAAa,QAAQ;AAAA,IACnC,YAAY;AAAA,IACZ,cAAc,KAAK,eAAe;AAAA,IAClC;AAAA,IACA,cAAc;AAAA,IACd,eAAe,IAAI,IAAI,aAAa,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,OAAO,CAAC,EAAE;AAAA,IACrF,eAAe,aAAa;AAAA,IAC5B,sBAAsB,KAAK,KAAK,aAAa,SAAS,CAAC;AAAA,EACzD;AAGA,QAAM,WAAW,oBAAoB,MAAM,IAAI,SAAS,eAAe;AAGvE,QAAM,YAAY,GAAG,2BAA2B,MAAM,CAAC;AACvD,QAAM,WAAW,KAAK,QAAQ,QAAQ,OAAO,SAAS;AAEtD,QAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,QAAM,UAAU,UAAU,UAAU,OAAO;AAE3C,QAAM,qBAAqB,KAAK,KAAK,aAAa,SAAS,CAAC;AAC5D,SAAO,EAAE,UAAU,cAAc,mBAAmB;AACtD;AAOA,SAAS,oBACP,MACA,cACA,SACA,YACA,cACA,UACA,gBACU;AACV,QAAM,QAAkB,CAAC;AAEzB,aAAW,SAAS,KAAK,UAAU;AACjC,QAAI,MAAM,SAAS,WAAW,MAAM,cAAc,WAAW;AAG3D,YAAM,cAA6B;AAAA,QACjC,GAAG;AAAA,QACH,eAAe,KAAK,IAAI,eAAe,GAAG,CAAC;AAAA,MAC7C;AACA,YAAM,cAAc,QAAQ,uBAAuB,QAAQ,mBAAmB,KAAK;AACnF,YAAM,YAAY,cAAc,aAAa,WAAW;AACxD,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,SAAS;AAGpB,YAAM,aAAa,MAAM,YAAY;AACrC,YAAM,WAAW,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,SAAS,MAAM;AAC5F,mBAAa,KAAK;AAAA,QAChB,YAAY,MAAM,cAAc,YAAY,QAAQ,KAAK,UAAU;AAAA,QACnE,QAAQ;AAAA,QACR,MAAM,MAAM,SAAS,KAAK,KAAK;AAAA,QAC/B,UAAU,WAAW,UAAU;AAAA,QAC/B,cAAc,WAAW,UAAU;AAAA,QACnC,eAAe,UAAU;AAAA,QACzB;AAAA,QACA,QAAQ,MAAM,UAAU;AAAA,QACxB,mBAAmB,gBAAgB,cAAc;AAAA,QACjD,eAAe,gBAAgB,YAAY;AAAA,QAC3C,aAAa,gBAAgB,SAAS,KAAK,KAAK;AAAA,MAClD,CAAC;AAAA,IACH,WAAW,MAAM,SAAS,WAAW,WAAW,IAAI,MAAM,SAAS,GAAG;AAIpE,YAAM,aAAa,MAAM,OAAO;AAChC,YAAM,UAAU,MAAM,UAAU,IAAI,MAAM,OAAO,KAAK;AACtD,YAAM,KAAK,EAAE;AACb,UAAI,gBAAgB,GAAG;AACrB,cAAM,SAAS,IAAI,OAAO,YAAY;AACtC,cAAM,KAAK,GAAG,MAAM,IAAI,UAAU,GAAG,OAAO,EAAE;AAAA,MAChD,OAAO;AACL,cAAM,KAAK,KAAK,UAAU,GAAG,OAAO,IAAI;AAAA,MAC1C;AAGA,YAAM,cAAc,MAAM,cAAc,YAAY,QAAQ;AAE5D,YAAM,aAAa;AAAA,QACjB;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,KAAK,GAAG,UAAU;AAAA,IAC1B,OAAO;AAEL,YAAM,WAAW,WAAW,OAAkB,UAAU;AACxD,UAAI,UAAU;AACZ,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AASA,SAAS,6BACP,MACA,aACA,SACA,cACM;AACN,aAAW,SAAS,KAAK,UAAU;AACjC,QAAI,MAAM,SAAS,WAAW,MAAM,cAAc,WAAW;AAC3D,mBAAa,KAAK,uBAAuB,OAAO,aAAa,OAAO,CAAC;AAAA,IACvE,WAAW,MAAM,SAAS,WAAW,WAAW,IAAI,MAAM,SAAS,GAAG;AACpE,mCAA6B,OAAO,aAAa,SAAS,YAAY;AAAA,IACxE;AAAA,EACF;AACF;AAEA,SAAS,4BACP,MACA,SACA,cACA,gBACM;AACN,aAAW,SAAS,KAAK,UAAU;AACjC,QAAI,MAAM,SAAS,WAAW,MAAM,cAAc,WAAW;AAC3D,mBAAa,KAAK,uBAAuB,OAAO,kBAAkB,MAAM,OAAO,CAAC;AAAA,IAClF,WAAW,MAAM,SAAS,WAAW,WAAW,IAAI,MAAM,SAAS,GAAG;AACpE,YAAM,cAAc,MAAM,cAAc,YAAY,QAAQ;AAC5D,kCAA4B,OAAO,SAAS,cAAc,WAAW;AAAA,IACvE;AAAA,EACF;AACF;AAEA,SAAS,gBACP,SACA,YACA,YAEA,WACQ;AACR,QAAM,WAAW,cAAc,OAAO;AACtC,QAAM,aAAa,gBAAgB,OAAO;AAC1C,QAAM,cAAc,WAAW,UAAU,GAAG,aAAa,EAAE;AAE3D,MAAI,YAAY;AACd,WAAO,KAAK,YAAY,OAAO,UAAU,YAAY,WAAW;AAAA,EAClE;AAEA,SAAO,KAAK,YAAY,OAAO,UAAU,WAAW;AACtD;AAMA,SAAS,cAAc,SAA8B;AAEnD,QAAM,SAAS,QAAQ,aAAa,aAAa;AACjD,QAAM,gBAAgB,YAAY,KAAK,MAAM;AAC7C,MAAI,gBAAgB,CAAC,GAAG;AACtB,WAAO,SAAS,OAAO,cAAc,CAAC,CAAC,CAAC;AAAA,EAC1C;AAGA,QAAM,mBAAmB,aAAa,QAAQ,WAAW,UAAU;AACnE,MAAI,kBAAkB;AACpB,UAAM,MAAM,iBAAiB,YAAY;AACzC,UAAM,cAAc,SAAS,KAAK,GAAG;AACrC,QAAI,cAAc,CAAC,GAAG;AACpB,aAAO,SAAS,OAAO,YAAY,CAAC,CAAC,CAAC;AAAA,IACxC;AAAA,EACF;AAGA,QAAM,WAAW,aAAa,QAAQ,WAAW,OAAO,GAAG,YAAY;AACvE,SAAO,SAAS,OAAO,QAAQ,CAAC;AAClC;AAMA,SAAS,gBAAgB,SAA0C;AAEjE,QAAM,aAAa,aAAa,QAAQ,WAAW,SAAS,GAAG;AAC/D,MAAI,WAAY,QAAO,WAAW,OAAO,UAAU,CAAC;AAGpD,QAAM,cAAc,aAAa,QAAQ,WAAW,aAAa;AACjE,MAAI,aAAa;AACf,UAAM,UAAU,YAAY,SAAS,KAAK,KAAK;AAE/C,UAAM,OAAO,QACV,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,UAAU,EAAE,EACpB,MAAM,GAAG,EAAE;AACd,WAAO,QAAQ;AAAA,EACjB;AAGA,QAAM,YAAY,aAAa,QAAQ,WAAW,oBAAoB;AACtE,MAAI,WAAW;AACb,UAAM,UAAU,UAAU,SAAS,KAAK,KAAK;AAC7C,UAAM,OAAO,QACV,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,UAAU,EAAE,EACpB,MAAM,GAAG,EAAE;AACd,WAAO,QAAQ;AAAA,EACjB;AAGA,QAAM,aAAa,aAAa,QAAQ,WAAW,qBAAqB;AACxE,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,SAAS,iBAAiB,MAAiB,SAAuC;AAChF,QAAM,OAAO,QAAQ;AACrB,QAAM,gBACJ,aAAa,QAAQ,WAAW,OAAO,KAAK,aAAa,QAAQ,WAAW,UAAU;AACxF,QAAM,kBACJ,aAAa,QAAQ,WAAW,SAAS,KACzC,aAAa,QAAQ,WAAW,aAAa,KAC7C,aAAa,QAAQ,WAAW,oBAAoB;AACtD,QAAM,qBAAqB,aAAa,QAAQ,WAAW,YAAY;AACvE,QAAM,eAAe,aAAa,QAAQ,WAAW,MAAM;AAE3D,QAAM,SAAS,KAAK,aAAa,eAAe,YAAY;AAC5D,QAAM,WAAW,aAAa,OAAO,QAAQ,OAAO,EAAE,CAAC;AACvD,QAAM,aAAa,KAAK,YAAY;AACpC,QAAM,cAAc,KAAK,SAAS,KAAK,KAAK;AAC5C,QAAM,YAAY,eAAe,SAAS,KAAK,KAAK,KAAK,WAAW;AAGpE,QAAM,eAAe,GAAG,QAAQ,aAAU,UAAU,MAAM,WAAW;AAGrE,QAAM,eAAe,wBAAwB,IAAI;AAGjD,QAAM,WAAW,cAAc,KAAK,sBAAsB,EAAE;AAG5D,QAAM,cAAc,UAAU,KAAK,WAAW,EAAE;AAEhD,QAAM,KAAsB;AAAA,IAC1B,QAAQ;AAAA,IACR,cAAc,KAAK,cAAc,4BAA4B;AAAA,IAC7D,YAAY,KAAK,cAAc,YAAY,QAAQ,KAAK,UAAU;AAAA,IAClE,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,cAAc,KAAK,eAAe;AAAA,IAClC;AAAA,IACA,cAAc;AAAA,EAChB;AAEA,MAAI,iBAAiB,UAAU;AAC7B,OAAG,iBAAiB,aAAa,gBAAgB,QAAQ;AAAA,EAC3D;AACA,MAAI,iBAAiB,SAAS;AAC5B,OAAG,eAAe,gBAAgB,QAAQ,KAAK;AAAA,EACjD;AACA,MAAI,oBAAoB,UAAU;AAChC,OAAG,oBAAoB,mBAAmB;AAAA,EAC5C;AACA,MAAI,oBAAoB,SAAS;AAC/B,OAAG,kBAAkB,mBAAmB,QAAQ,KAAK;AAAA,EACvD;AACA,MAAI,cAAc,UAAU;AAC1B,OAAG,cAAc,aAAa;AAAA,EAChC;AACA,MAAI,cAAc,SAAS;AACzB,OAAG,YAAY,aAAa,QAAQ,KAAK;AAAA,EAC3C;AACA,MAAI,cAAc;AAChB,OAAG,gBAAgB;AAAA,EACrB;AACA,MAAI,KAAK,QAAQ;AACf,OAAG,SAAS,KAAK;AAAA,EACnB;AAEA,SAAO;AACT;AASA,SAAS,uBACP,aACA,aACA,SACa;AACb,QAAM,WAAW,aAAa,QAAQ,WAAW,OAAO,GAAG,YAAY;AACvE,QAAM,kBAAkB,cACpB;AAAA,IACE,UAAU,YAAY;AAAA,IACtB,SAAS,YAAY;AAAA,IACrB,YAAY,YAAY;AAAA,EAC1B,IACA,aAAa,QAAQ,WAAW,SAAS;AAC7C,QAAM,aAAa,YAAY,YAAY;AAC3C,QAAM,aAAa,iBAAiB,YAAY;AAChD,QAAM,aAAa,eAAe,MAAM,WAAW,OAAO,UAAU,CAAC,KAAK;AAE1E,QAAM,WAAW,YAAY,SAAS;AAAA,IACpC,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,SAAS;AAAA,EACnD;AAGA,MAAI,gBAAgB;AACpB,QAAM,OAAO,CAAC,SAGF;AACV,QAAI,KAAK,KAAM,kBAAiB,KAAK,KAAK;AAC1C,QAAI,KAAK,UAAU;AACjB,iBAAW,SAAS,KAAK,UAAU;AACjC,aAAK,KAAoB;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACA,OAAK,WAAoD;AAEzD,QAAM,kBAAkB,WAAW,UAAU;AAC7C,SAAO;AAAA,IACL,YAAY,YAAY,cAAc,YAAY,QAAQ,KAAK,UAAU;AAAA,IACzE,QAAQ;AAAA,IACR,MAAM,YAAY,SAAS,KAAK,KAAK;AAAA,IACrC,UAAU;AAAA,IACV,cAAc,aAAa,GAAG,UAAU,IAAI,eAAe,KAAK;AAAA,IAChE;AAAA,IACA;AAAA,IACA,QAAQ,YAAY,UAAU;AAAA,IAC9B,mBAAmB,iBAAiB,cAAc;AAAA,IAClD,eAAe;AAAA,IACf,aAAa,iBAAiB,SAAS,KAAK,KAAK;AAAA,EACnD;AACF;AAEA,SAAS,iBAAiB,SAAkD;AAE1E,MAAI,QAAQ,aAAc,QAAO;AAGjC,MACE,CAAC,QAAQ,yBACT,CAAC,QAAQ,yBACT,CAAC,QAAQ,mBACT;AACA,WAAO,EAAE,WAAW,OAAO,WAAW,OAAO,YAAY,MAAM;AAAA,EACjE;AAGA,SAAO;AAAA,IACL,WAAW,QAAQ;AAAA,IACnB,WAAW,QAAQ;AAAA,IACnB,YAAY,QAAQ;AAAA,EACtB;AACF;AAEA,SAAS,aACP,WACA,WAC0B;AAC1B,SAAO,UAAU,KAAK,CAAC,MAAM,EAAE,cAAc,SAAS;AACxD;AAMA,SAAS,2BAA2B,QAAwB;AAC1D,QAAM,gBAAgB,YAAY,KAAK,MAAM;AAC7C,MAAI,gBAAgB,CAAC,GAAG;AACtB,WAAO,SAAS,OAAO,cAAc,CAAC,CAAC,CAAC;AAAA,EAC1C;AACA,SAAO,SAAS,OAAO,MAAM,CAAC;AAChC;AAEA,SAAS,OAAO,KAAqB;AACnC,QAAM,IAAI,SAAS,KAAK,EAAE;AAC1B,MAAI,MAAM,CAAC,EAAG,QAAO;AACrB,SAAO,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AACrC;AAKA,SAAS,aAAa,GAAmB;AACvC,QAAM,IAAI,SAAS,GAAG,EAAE;AACxB,SAAO,MAAM,CAAC,IAAI,IAAI;AACxB;AAKA,SAAS,wBAAwB,MAAqC;AACpE,aAAW,SAAS,KAAK,UAAU;AACjC,QAAI,MAAM,SAAS,gBAAgB;AACjC,aAAO,MAAM,SAAS,IAAI,CAAC,WAAW,aAAa,MAAM,CAAC,EAAE,KAAK,EAAE;AAAA,IACrE;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,aAAa,MAIX;AACT,MAAI,KAAK,KAAM,QAAO,KAAK;AAC3B,MAAI,KAAK,UAAU;AACjB,WAAO,KAAK,SAAS,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE;AAAA,EACvD;AACA,SAAO;AACT;AAMA,SAAS,cAAc,SAAyB;AAE9C,QAAM,QAAQ,YAAY,KAAK,OAAO;AACtC,MAAI,QAAQ,CAAC,EAAG,QAAO,MAAM,CAAC;AAC9B,SAAO,WAAW;AACpB;AAMA,SAAS,sBAAsB,SAAyB;AACtD,QAAM,QAAQ,uBAAuB,KAAK,OAAO;AACjD,MAAI,QAAQ,CAAC,EAAG,QAAO,MAAM,CAAC;AAC9B,SAAO,WAAW;AACpB;AAKA,SAAS,UAAU,SAAyB;AAC1C,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,WAAW,QAAQ,MAAM,GAAG,EAAE,CAAC;AACrC,SAAO,YAAY;AACrB;AAKA,SAAS,mBAAmB,MAA4B;AACtD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,KAAK,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,cAAc;AAAA,EACjE;AACF;;;ACttCA,SAAS,yBAAyB;AAClC,SAAS,SAAAA,QAAO,MAAM,cAAc;AACpC,SAAS,QAAAC,aAAY;AACrB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,QAAQ,iBAAiB;;;ACPlC,IAAM,qBAAqB;AAmB3B,eAAsB,2BAA6D;AACjF,MAAI;AACJ,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,kBAAkB;AAC/C,QAAI,CAAC,SAAS,GAAI,QAAO;AACzB,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,SAAO,0BAA0B,IAAI;AACvC;AAOO,SAAS,0BAA0B,MAAuC;AAG/E,QAAM,WAAW,2BAA2B,KAAK,IAAI;AACrD,MAAI,WAAW,CAAC,GAAG;AACjB,UAAM,eAAe,SAAS,CAAC;AAC/B,UAAM,cAAc,iBAAiB,IAAI;AACzC,WAAO,EAAE,cAAc,YAAY;AAAA,EACrC;AAIA,QAAM,iBAAiB,6BAA6B,KAAK,IAAI;AAC7D,MAAI,iBAAiB,CAAC,GAAG;AACvB,UAAM,eAAe,eAAe,CAAC;AACrC,UAAM,cAAc,iBAAiB,IAAI;AACzC,WAAO,EAAE,cAAc,YAAY;AAAA,EACrC;AAEA,SAAO;AACT;AAWA,SAAS,iBAAiB,MAAsB;AAC9C,QAAM,SAAS;AACf,QAAM,WAAW,KAAK,QAAQ,MAAM;AACpC,MAAI,aAAa,GAAI,QAAO;AAC5B,QAAM,eAAe,WAAW,OAAO;AACvC,QAAM,SAAS,KAAK,QAAQ,SAAS,YAAY;AACjD,MAAI,WAAW,GAAI,QAAO;AAC1B,SAAO,KAAK,MAAM,cAAc,MAAM,EAAE,KAAK;AAC/C;;;ADtDO,IAAM,yBAAyB;AAM/B,IAAM,wBAAwB;AAGrC,IAAM,gBAAgB;AAGf,IAAM,oBAAoB,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC;AAWpE,SAAS,YAAY,QAA2B;AACrD,QAAM,SAAS,IAAI,IAAI,MAAM;AAC7B,SAAO,OAAO,SAAS,MAAM,kBAAkB,MAAM,CAAC,MAAM,OAAO,IAAI,CAAC,CAAC;AAC3E;AAsDA,eAAsB,eAAe,SAAmD;AACtF,MAAI,eAAe,QAAQ;AAC3B,MAAI,CAAC,cAAc;AACjB,UAAM,WAAW,MAAM,yBAAyB;AAChD,mBAAe,UAAU,gBAAgB;AAAA,EAC3C;AACA,QAAM,SAAS,QAAQ,UAAU;AAEjC,QAAMC,OAAM,QAAQ,WAAW,EAAE,WAAW,KAAK,CAAC;AAGlD,MAAI,QAAQ,WAAW,UAAa,YAAY,MAAM,GAAG;AACvD,QAAI;AACF,YAAMC,SAAQ,MAAM,4BAA4B,cAAc,QAAQ,SAAS;AAC/E,aAAO,EAAE,cAAc,OAAAA,QAAO,QAAQ,CAAC,EAAE;AAAA,IAC3C,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,QAA0B,CAAC;AACjC,QAAM,SAA0B,CAAC;AAEjC,aAAW,YAAY,QAAQ;AAC7B,QAAI;AACF,YAAM,OAAO,MAAM,wBAAwB,UAAU,cAAc,QAAQ,SAAS;AACpF,YAAM,KAAK,IAAI;AAAA,IACjB,SAAS,KAAK;AACZ,aAAO,KAAK;AAAA,QACV,aAAa;AAAA,QACb,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC1D,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,EAAE,cAAc,OAAO,OAAO;AACvC;AAcO,SAAS,iBAAiB,aAAqB,cAA8B;AAClF,QAAM,cAAc,YAAY,SAAS,EAAE,SAAS,GAAG,GAAG;AAC1D,QAAM,SAAS,mBAAmB,YAAY;AAC9C,SAAO,GAAG,aAAa,IAAI,MAAM,WAAW,WAAW,IAAI,YAAY;AACzE;AAKO,SAAS,kBAAkB,cAA8B;AAC9D,QAAM,SAAS,mBAAmB,YAAY;AAC9C,SAAO,GAAG,aAAa,IAAI,MAAM,eAAe,YAAY;AAC9D;AAOO,SAAS,mBAAmB,cAA8B;AAE/D,QAAM,YAAY,aAAa,QAAQ,GAAG;AAC1C,MAAI,cAAc,GAAI,QAAO;AAC7B,SAAO,GAAG,aAAa,MAAM,GAAG,SAAS,CAAC,IAAI,aAAa,MAAM,YAAY,CAAC,CAAC;AACjF;AASA,eAAe,wBACb,aACA,cACA,WACyB;AACzB,QAAM,MAAM,iBAAiB,aAAa,YAAY;AACtD,QAAM,cAAc,YAAY,SAAS,EAAE,SAAS,GAAG,GAAG;AAC1D,QAAM,UAAUC,MAAK,WAAW,MAAM,WAAW,MAAM;AACvD,QAAM,cAAc,MAAM,WAAW;AACrC,QAAM,UAAUA,MAAK,WAAW,WAAW;AAG3C,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,QAAQ,GAAG,EAAE;AAAA,EAC9E;AAEA,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI,MAAM,wBAAwB,GAAG,EAAE;AAAA,EAC/C;AAGA,QAAM,aAAa,kBAAkB,OAAO;AAE5C,QAAM,SAAS,SAAS,QAAQ,SAAS,IAAa,GAAG,UAAU;AAGnE,QAAM,kBAAkB,SAAS,aAAa,OAAO;AAGrD,QAAM,OAAO,OAAO;AAGpB,QAAM,WAAW,MAAM,KAAK,OAAO;AAEnC,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AAAA,IACV,MAAM,SAAS;AAAA,EACjB;AACF;AAKA,SAAS,kBACP,SACA,gBACA,YACe;AACf,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAU,SAAS,EAAE,aAAa,KAAK,GAAG,CAAC,KAAK,YAAY;AAC1D,UAAI,KAAK;AACP,eAAO,IAAI,MAAM,uBAAuB,IAAI,OAAO,EAAE,CAAC;AACtD;AAAA,MACF;AACA,UAAI,CAAC,SAAS;AACZ,eAAO,IAAI,MAAM,yCAAyC,CAAC;AAC3D;AAAA,MACF;AAEA,UAAI,QAAQ;AAEZ,cAAQ,GAAG,SAAS,CAAC,UAAiB;AAEpC,cAAM,WAAW,MAAM,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK,MAAM;AAC1D,YAAI,aAAa,kBAAkB,MAAM,SAAS,SAAS,MAAM,GAAG;AAClE,kBAAQ;AACR,uBAAa,SAAS,OAAO,UAAU,EACpC,KAAK,MAAM;AACV,oBAAQ,MAAM;AACd,oBAAQ;AAAA,UACV,CAAC,EACA,MAAM,CAAC,eAAe;AACrB,oBAAQ,MAAM;AACd,mBAAO,UAAU;AAAA,UACnB,CAAC;AAAA,QACL,OAAO;AACL,kBAAQ,UAAU;AAAA,QACpB;AAAA,MACF,CAAC;AAED,cAAQ,GAAG,OAAO,MAAM;AACtB,YAAI,CAAC,OAAO;AACV,iBAAO,IAAI,MAAM,GAAG,cAAc,mBAAmB,CAAC;AAAA,QACxD;AAAA,MACF,CAAC;AAED,cAAQ,GAAG,SAAS,CAAC,WAAkB;AACrC,eAAO,IAAI,MAAM,cAAc,OAAO,OAAO,EAAE,CAAC;AAAA,MAClD,CAAC;AAED,cAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AACH;AAKA,SAAS,aAAa,SAAkB,OAAc,YAAmC;AACvF,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAQ,eAAe,OAAO,CAAC,KAAK,eAAe;AACjD,UAAI,KAAK;AACP,eAAO,IAAI,MAAM,6BAA6B,IAAI,OAAO,EAAE,CAAC;AAC5D;AAAA,MACF;AACA,UAAI,CAAC,YAAY;AACf,eAAO,IAAI,MAAM,8BAA8B,CAAC;AAChD;AAAA,MACF;AAEA,YAAM,cAAc,kBAAkB,UAAU;AAChD,iBAAW,KAAK,WAAW;AAE3B,kBAAY,GAAG,UAAU,MAAM,QAAQ,CAAC;AACxC,kBAAY,GAAG,SAAS,CAAC,aAAa,OAAO,IAAI,MAAM,gBAAgB,SAAS,OAAO,EAAE,CAAC,CAAC;AAC3F,iBAAW,GAAG,SAAS,CAAC,YAAY,OAAO,IAAI,MAAM,eAAe,QAAQ,OAAO,EAAE,CAAC,CAAC;AAAA,IACzF,CAAC;AAAA,EACH,CAAC;AACH;AAOA,IAAM,aAAa;AAOnB,SAAS,qBACP,SACA,WACsD;AACtD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAU,SAAS,EAAE,aAAa,KAAK,GAAG,CAAC,KAAK,YAAY;AAC1D,UAAI,KAAK;AACP,eAAO,IAAI,MAAM,uBAAuB,IAAI,OAAO,EAAE,CAAC;AACtD;AAAA,MACF;AACA,UAAI,CAAC,SAAS;AACZ,eAAO,IAAI,MAAM,yCAAyC,CAAC;AAC3D;AAAA,MACF;AAEA,YAAM,YAAyD,CAAC;AAChE,UAAI,UAAU;AACd,UAAI,QAAQ;AAEZ,YAAM,eAAe,MAAY;AAC/B,YAAI,SAAS,YAAY,GAAG;AAC1B,kBAAQ,SAAS;AAAA,QACnB;AAAA,MACF;AAEA,cAAQ,GAAG,SAAS,CAAC,UAAiB;AACpC,cAAM,QAAQ,WAAW,KAAK,MAAM,QAAQ;AAC5C,YAAI,OAAO;AACT,gBAAM,WAAW,SAAS,MAAM,CAAC,KAAK,KAAK,EAAE;AAC7C,gBAAM,UAAUA,MAAK,WAAW,MAAM,MAAM,CAAC,KAAK,IAAI,MAAM;AAC5D;AAEA,uBAAa,SAAS,OAAO,OAAO,EACjC,KAAK,MAAM;AACV,sBAAU,KAAK,EAAE,aAAa,UAAU,UAAU,QAAQ,CAAC;AAC3D;AAEA,oBAAQ,UAAU;AAClB,yBAAa;AAAA,UACf,CAAC,EACA,MAAM,CAAC,eAAe;AACrB,oBAAQ,MAAM;AACd,mBAAO,UAAU;AAAA,UACnB,CAAC;AAAA,QACL,OAAO;AACL,kBAAQ,UAAU;AAAA,QACpB;AAAA,MACF,CAAC;AAED,cAAQ,GAAG,OAAO,MAAM;AACtB,gBAAQ;AACR,qBAAa;AAAA,MACf,CAAC;AAED,cAAQ,GAAG,SAAS,CAAC,WAAkB;AACrC,eAAO,IAAI,MAAM,cAAc,OAAO,OAAO,EAAE,CAAC;AAAA,MAClD,CAAC;AAED,cAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AACH;AAKA,eAAe,4BACb,cACA,WAC2B;AAC3B,QAAM,MAAM,kBAAkB,YAAY;AAC1C,QAAM,UAAUA,MAAK,WAAW,YAAY;AAG5C,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,QAAQ,GAAG,EAAE;AAAA,EAC9E;AAEA,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI,MAAM,wBAAwB,GAAG,EAAE;AAAA,EAC/C;AAGA,QAAM,aAAa,kBAAkB,OAAO;AAC5C,QAAM,SAAS,SAAS,QAAQ,SAAS,IAAa,GAAG,UAAU;AAGnE,QAAM,YAAY,MAAM,qBAAqB,SAAS,SAAS;AAG/D,QAAM,OAAO,OAAO;AAGpB,QAAM,QAA0B,CAAC;AACjC,aAAW,EAAE,aAAa,SAAS,KAAK,WAAW;AACjD,UAAM,WAAW,MAAM,KAAK,QAAQ;AACpC,UAAM,KAAK,EAAE,aAAa,UAAU,MAAM,SAAS,KAAK,CAAC;AAAA,EAC3D;AAGA,QAAM,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,EAAE,WAAW;AAElD,SAAO;AACT;","names":["mkdir","join","mkdir","files","join"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lexbuild/usc",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Federal U.S. Code specific element handlers and downloader for LexBuild",
|
|
5
5
|
"author": "Chris Thomas",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"yauzl": "^3.2.1",
|
|
46
|
-
"@lexbuild/core": "1.
|
|
46
|
+
"@lexbuild/core": "1.10.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/node": "^25.3.2",
|