@aruzone/aze-forge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +408 -0
- package/dist/acceptance.d.ts +48 -0
- package/dist/acceptance.js +180 -0
- package/dist/acceptance.js.map +1 -0
- package/dist/assets.d.ts +19 -0
- package/dist/assets.js +509 -0
- package/dist/assets.js.map +1 -0
- package/dist/atomic-write.d.ts +1 -0
- package/dist/atomic-write.js +23 -0
- package/dist/atomic-write.js.map +1 -0
- package/dist/callout.d.ts +27 -0
- package/dist/callout.js +78 -0
- package/dist/callout.js.map +1 -0
- package/dist/capabilities-json.d.ts +4 -0
- package/dist/capabilities-json.js +225 -0
- package/dist/capabilities-json.js.map +1 -0
- package/dist/capabilities.d.ts +110 -0
- package/dist/capabilities.js +270 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1096 -0
- package/dist/cli.js.map +1 -0
- package/dist/compiler.d.ts +3 -0
- package/dist/compiler.js +1034 -0
- package/dist/compiler.js.map +1 -0
- package/dist/configuration-error.d.ts +4 -0
- package/dist/configuration-error.js +9 -0
- package/dist/configuration-error.js.map +1 -0
- package/dist/diagnostics-json.d.ts +23 -0
- package/dist/diagnostics-json.js +143 -0
- package/dist/diagnostics-json.js.map +1 -0
- package/dist/diagnostics.d.ts +16 -0
- package/dist/diagnostics.js +154 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/equation.d.ts +74 -0
- package/dist/equation.js +485 -0
- package/dist/equation.js.map +1 -0
- package/dist/font.d.ts +19 -0
- package/dist/font.js +75 -0
- package/dist/font.js.map +1 -0
- package/dist/format.d.ts +2 -0
- package/dist/format.js +308 -0
- package/dist/format.js.map +1 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.js +189 -0
- package/dist/hash.js.map +1 -0
- package/dist/help.d.ts +9 -0
- package/dist/help.js +102 -0
- package/dist/help.js.map +1 -0
- package/dist/html-fragment.d.ts +7 -0
- package/dist/html-fragment.js +70 -0
- package/dist/html-fragment.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +14 -0
- package/dist/markdown.js +425 -0
- package/dist/markdown.js.map +1 -0
- package/dist/mermaid-browser.d.ts +43 -0
- package/dist/mermaid-browser.js +358 -0
- package/dist/mermaid-browser.js.map +1 -0
- package/dist/mermaid.d.ts +84 -0
- package/dist/mermaid.js +740 -0
- package/dist/mermaid.js.map +1 -0
- package/dist/model.d.ts +406 -0
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -0
- package/dist/parse.d.ts +3 -0
- package/dist/parse.js +1374 -0
- package/dist/parse.js.map +1 -0
- package/dist/preview-server.d.ts +39 -0
- package/dist/preview-server.js +156 -0
- package/dist/preview-server.js.map +1 -0
- package/dist/preview-shell.d.ts +29 -0
- package/dist/preview-shell.js +102 -0
- package/dist/preview-shell.js.map +1 -0
- package/dist/reference-validation.d.ts +7 -0
- package/dist/reference-validation.js +42 -0
- package/dist/reference-validation.js.map +1 -0
- package/dist/registry.d.ts +29 -0
- package/dist/registry.js +384 -0
- package/dist/registry.js.map +1 -0
- package/dist/render-html.d.ts +24 -0
- package/dist/render-html.js +149 -0
- package/dist/render-html.js.map +1 -0
- package/dist/render-pdf.d.ts +64 -0
- package/dist/render-pdf.js +503 -0
- package/dist/render-pdf.js.map +1 -0
- package/dist/render-png.d.ts +32 -0
- package/dist/render-png.js +427 -0
- package/dist/render-png.js.map +1 -0
- package/dist/render-svg.d.ts +23 -0
- package/dist/render-svg.js +243 -0
- package/dist/render-svg.js.map +1 -0
- package/dist/runtime-support.d.ts +26 -0
- package/dist/runtime-support.js +62 -0
- package/dist/runtime-support.js.map +1 -0
- package/dist/source-map.d.ts +12 -0
- package/dist/source-map.js +75 -0
- package/dist/source-map.js.map +1 -0
- package/dist/table.d.ts +22 -0
- package/dist/table.js +90 -0
- package/dist/table.js.map +1 -0
- package/dist/theme.d.ts +6 -0
- package/dist/theme.js +89 -0
- package/dist/theme.js.map +1 -0
- package/dist/tool-version.d.ts +3 -0
- package/dist/tool-version.js +3 -0
- package/dist/tool-version.js.map +1 -0
- package/dist/type-guards.d.ts +1 -0
- package/dist/type-guards.js +4 -0
- package/dist/type-guards.js.map +1 -0
- package/dist/validate-document.d.ts +2 -0
- package/dist/validate-document.js +248 -0
- package/dist/validate-document.js.map +1 -0
- package/dist/version.d.ts +37 -0
- package/dist/version.js +111 -0
- package/dist/version.js.map +1 -0
- package/dist/watch-dependencies.d.ts +15 -0
- package/dist/watch-dependencies.js +93 -0
- package/dist/watch-dependencies.js.map +1 -0
- package/dist/watch-events.d.ts +51 -0
- package/dist/watch-events.js +27 -0
- package/dist/watch-events.js.map +1 -0
- package/dist/watch-loop.d.ts +39 -0
- package/dist/watch-loop.js +117 -0
- package/dist/watch-loop.js.map +1 -0
- package/package.json +70 -0
- package/schemas/acceptance.json +104 -0
- package/schemas/capabilities.json +491 -0
- package/schemas/diagnostics.json +219 -0
- package/schemas/version.json +167 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Browser } from "puppeteer-core";
|
|
2
|
+
import type { AnyBlockRenderer, Artifact, AssetManifestEntry, ContentHash, RendererDescriptor, Theme } from "./model.js";
|
|
3
|
+
import type { HtmlLayout } from "./render-html.js";
|
|
4
|
+
export declare const PDF_RENDERER_ID: "pdf";
|
|
5
|
+
export declare const PDF_RENDERER_VERSION: "1.0.0";
|
|
6
|
+
export declare const PDF_MIME_TYPE: "application/pdf";
|
|
7
|
+
export declare const PDF_PROFILE: "azeforge.pdf.paged/v1";
|
|
8
|
+
export declare const PDF_SERIALIZER: "azeforge-pdf/v1";
|
|
9
|
+
export declare const PDF_REQUIRED_CAPABILITIES: readonly ["pdf-paged"];
|
|
10
|
+
export declare const PDF_MAX_BYTES: number;
|
|
11
|
+
export declare const PDF_MAX_PAGES = 200;
|
|
12
|
+
export declare const PDF_MAX_HTML_BYTES: number;
|
|
13
|
+
export declare const PDF_PRINT_TIMEOUT_MS = 30000;
|
|
14
|
+
/**
|
|
15
|
+
* Renderer temporary-storage budget. It is accounted statically, not
|
|
16
|
+
* metered: settled HTML is capped at 64 MiB in and canonical PDF at
|
|
17
|
+
* 128 MiB out before publication, so browser profile, decoded images,
|
|
18
|
+
* and print spool stay an order of magnitude under budget by
|
|
19
|
+
* construction. The caps below are the enforcement.
|
|
20
|
+
*/
|
|
21
|
+
export declare const PDF_MAX_TEMP_BYTES: number;
|
|
22
|
+
export declare const pdfBlockRenderers: readonly AnyBlockRenderer[];
|
|
23
|
+
export interface PdfBrowserCapability {
|
|
24
|
+
readonly launch: () => Promise<Browser>;
|
|
25
|
+
}
|
|
26
|
+
export declare const pinnedPdfBrowserCapability: PdfBrowserCapability;
|
|
27
|
+
export declare const pdfRendererDescriptor: RendererDescriptor;
|
|
28
|
+
export declare class PdfArtifactLimitError extends Error {
|
|
29
|
+
readonly byteLength: number;
|
|
30
|
+
constructor(byteLength: number, detail?: string);
|
|
31
|
+
}
|
|
32
|
+
export interface PdfPageGeometry {
|
|
33
|
+
readonly widthPt: number;
|
|
34
|
+
readonly heightPt: number;
|
|
35
|
+
readonly marginPt: number;
|
|
36
|
+
readonly pageCss: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function pdfPageGeometryForTheme(theme: Theme): PdfPageGeometry;
|
|
39
|
+
/**
|
|
40
|
+
* Paged print CSS layered over the shared continuous layout CSS. Normal
|
|
41
|
+
* document flow owns pagination: headings stay with following content,
|
|
42
|
+
* prose observes widows/orphans, table headers repeat with row splits,
|
|
43
|
+
* fenced code splits between visual lines, equations/diagrams/images stay
|
|
44
|
+
* atomic, long callouts split between children, and dark-presentation
|
|
45
|
+
* level-one headings start new sections.
|
|
46
|
+
*/
|
|
47
|
+
export declare function pdfPagedCss(theme: Theme): string;
|
|
48
|
+
export interface PdfCanonicalIdentity {
|
|
49
|
+
readonly title: string;
|
|
50
|
+
readonly authors: readonly string[];
|
|
51
|
+
readonly documentId: string;
|
|
52
|
+
}
|
|
53
|
+
export interface CanonicalPdf {
|
|
54
|
+
readonly bytes: Uint8Array;
|
|
55
|
+
readonly pageCount: number;
|
|
56
|
+
readonly pageWidthPt: number;
|
|
57
|
+
readonly pageHeightPt: number;
|
|
58
|
+
}
|
|
59
|
+
export declare function canonicalizePdf(raw: Uint8Array, identity: PdfCanonicalIdentity): CanonicalPdf;
|
|
60
|
+
export interface PdfDocumentInfo {
|
|
61
|
+
readonly title: string;
|
|
62
|
+
readonly authors: readonly string[];
|
|
63
|
+
}
|
|
64
|
+
export declare function renderPdf(layout: HtmlLayout, contentHash: ContentHash, theme: Theme, assetManifest: readonly AssetManifestEntry[], browserCapability: PdfBrowserCapability, info: PdfDocumentInfo): Promise<Artifact>;
|
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
import { arch, platform } from "node:os";
|
|
2
|
+
import { calloutHtmlBlockRenderer } from "./callout.js";
|
|
3
|
+
import { equationHtmlBlockRenderer } from "./equation.js";
|
|
4
|
+
import { assetManifestHash } from "./assets.js";
|
|
5
|
+
import { artifactBytesHash, canonicalJson, sha256 } from "./hash.js";
|
|
6
|
+
import { CHROME_HEADLESS_SHELL_VERSION, launchPinnedBrowser, throwIfDeniedBrowserRequest, } from "./mermaid-browser.js";
|
|
7
|
+
import { mermaidHtmlBlockRenderer } from "./mermaid.js";
|
|
8
|
+
import { tableHtmlBlockRenderer } from "./table.js";
|
|
9
|
+
export const PDF_RENDERER_ID = "pdf";
|
|
10
|
+
export const PDF_RENDERER_VERSION = "1.0.0";
|
|
11
|
+
export const PDF_MIME_TYPE = "application/pdf";
|
|
12
|
+
export const PDF_PROFILE = "azeforge.pdf.paged/v1";
|
|
13
|
+
export const PDF_SERIALIZER = "azeforge-pdf/v1";
|
|
14
|
+
const PDF_PRODUCER = `AzeForge pdf/1.0.0 (HeadlessChrome/${CHROME_HEADLESS_SHELL_VERSION})`;
|
|
15
|
+
const PDF_CREATOR = "AzeForge";
|
|
16
|
+
export const PDF_REQUIRED_CAPABILITIES = Object.freeze(["pdf-paged"]);
|
|
17
|
+
export const PDF_MAX_BYTES = 128 * 1024 * 1024;
|
|
18
|
+
export const PDF_MAX_PAGES = 200;
|
|
19
|
+
export const PDF_MAX_HTML_BYTES = 64 * 1024 * 1024;
|
|
20
|
+
export const PDF_PRINT_TIMEOUT_MS = 30_000;
|
|
21
|
+
const ALLOWED_REQUEST = /^(?:about:blank|data:(?:font\/woff2|image\/(?:png|jpeg|svg\+xml));base64,)/;
|
|
22
|
+
const ATOMIC_SELECTOR = ".aze-equation,.aze-mermaid,figure,img";
|
|
23
|
+
/**
|
|
24
|
+
* Renderer temporary-storage budget. It is accounted statically, not
|
|
25
|
+
* metered: settled HTML is capped at 64 MiB in and canonical PDF at
|
|
26
|
+
* 128 MiB out before publication, so browser profile, decoded images,
|
|
27
|
+
* and print spool stay an order of magnitude under budget by
|
|
28
|
+
* construction. The caps below are the enforcement.
|
|
29
|
+
*/
|
|
30
|
+
export const PDF_MAX_TEMP_BYTES = 512 * 1024 * 1024;
|
|
31
|
+
/**
|
|
32
|
+
* Interim floor for the §10 minimum-readable-graphic-label contract.
|
|
33
|
+
* Atomic graphics shrink proportionally to fit the page, but never below
|
|
34
|
+
* half their authored size: the Theme model carries no per-theme minimum
|
|
35
|
+
* label size, so anything needing a smaller scale errors instead of
|
|
36
|
+
* shrinking into unreadability.
|
|
37
|
+
*/
|
|
38
|
+
const PDF_MIN_ATOMIC_SCALE = 0.5;
|
|
39
|
+
function pdfBlockRenderer(renderer) {
|
|
40
|
+
return Object.freeze({
|
|
41
|
+
descriptor: Object.freeze({
|
|
42
|
+
...renderer.descriptor,
|
|
43
|
+
id: renderer.descriptor.id.replace(".html/", ".pdf/"),
|
|
44
|
+
rendererId: PDF_RENDERER_ID,
|
|
45
|
+
}),
|
|
46
|
+
render: renderer.render,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
export const pdfBlockRenderers = Object.freeze([
|
|
50
|
+
pdfBlockRenderer(equationHtmlBlockRenderer),
|
|
51
|
+
pdfBlockRenderer(calloutHtmlBlockRenderer),
|
|
52
|
+
pdfBlockRenderer(mermaidHtmlBlockRenderer),
|
|
53
|
+
pdfBlockRenderer(tableHtmlBlockRenderer),
|
|
54
|
+
]);
|
|
55
|
+
export const pinnedPdfBrowserCapability = Object.freeze({
|
|
56
|
+
launch: launchPinnedBrowser,
|
|
57
|
+
});
|
|
58
|
+
export const pdfRendererDescriptor = Object.freeze({
|
|
59
|
+
id: PDF_RENDERER_ID,
|
|
60
|
+
version: PDF_RENDERER_VERSION,
|
|
61
|
+
formats: Object.freeze(["pdf"]),
|
|
62
|
+
capabilities: Object.freeze(["browser"]),
|
|
63
|
+
});
|
|
64
|
+
export class PdfArtifactLimitError extends Error {
|
|
65
|
+
byteLength;
|
|
66
|
+
constructor(byteLength, detail) {
|
|
67
|
+
super(detail ??
|
|
68
|
+
`PDF Artifact is ${byteLength} bytes; the limit is ${PDF_MAX_BYTES} bytes.`);
|
|
69
|
+
this.name = "PdfArtifactLimitError";
|
|
70
|
+
this.byteLength = byteLength;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const PT_PER_MM = 72 / 25.4;
|
|
74
|
+
const PX_PER_PT = 96 / 72;
|
|
75
|
+
function roundPt(value) {
|
|
76
|
+
return Math.round(value * 1000) / 1000;
|
|
77
|
+
}
|
|
78
|
+
export function pdfPageGeometryForTheme(theme) {
|
|
79
|
+
if (theme.id === "academic") {
|
|
80
|
+
return {
|
|
81
|
+
widthPt: roundPt(210 * PT_PER_MM),
|
|
82
|
+
heightPt: roundPt(297 * PT_PER_MM),
|
|
83
|
+
marginPt: roundPt(22 * PT_PER_MM),
|
|
84
|
+
pageCss: "size:A4;margin:22mm",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (theme.id === "dark-presentation") {
|
|
88
|
+
return {
|
|
89
|
+
widthPt: roundPt(13.333 * 72),
|
|
90
|
+
heightPt: roundPt(7.5 * 72),
|
|
91
|
+
marginPt: roundPt(0.5 * 72),
|
|
92
|
+
pageCss: "size:13.333in 7.5in;margin:0.5in",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
widthPt: roundPt(210 * PT_PER_MM),
|
|
97
|
+
heightPt: roundPt(297 * PT_PER_MM),
|
|
98
|
+
marginPt: roundPt(18 * PT_PER_MM),
|
|
99
|
+
pageCss: "size:A4;margin:18mm",
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function pdfContentHeightCssPx(geometry) {
|
|
103
|
+
return (geometry.heightPt - geometry.marginPt * 2) * PX_PER_PT;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Paged print CSS layered over the shared continuous layout CSS. Normal
|
|
107
|
+
* document flow owns pagination: headings stay with following content,
|
|
108
|
+
* prose observes widows/orphans, table headers repeat with row splits,
|
|
109
|
+
* fenced code splits between visual lines, equations/diagrams/images stay
|
|
110
|
+
* atomic, long callouts split between children, and dark-presentation
|
|
111
|
+
* level-one headings start new sections.
|
|
112
|
+
*/
|
|
113
|
+
export function pdfPagedCss(theme) {
|
|
114
|
+
const geometry = pdfPageGeometryForTheme(theme);
|
|
115
|
+
const sectionBreak = theme.id === "dark-presentation"
|
|
116
|
+
? "article>h1:not(:first-child){break-before:page}"
|
|
117
|
+
: "";
|
|
118
|
+
return (`@page{${geometry.pageCss}}` +
|
|
119
|
+
"html,body,main,article{print-color-adjust:exact;-webkit-print-color-adjust:exact}" +
|
|
120
|
+
"h1,h2,h3,h4,h5,h6{break-after:avoid;break-inside:avoid}" +
|
|
121
|
+
"p,li{orphans:3;widows:3}" +
|
|
122
|
+
"thead{display:table-header-group}tr{break-inside:avoid}" +
|
|
123
|
+
"pre{break-inside:auto}" +
|
|
124
|
+
".aze-equation,.aze-mermaid,figure,img{break-inside:avoid}" +
|
|
125
|
+
".aze-callout{break-inside:auto}" +
|
|
126
|
+
sectionBreak);
|
|
127
|
+
}
|
|
128
|
+
function pdfLiteral(value) {
|
|
129
|
+
return value.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
|
|
130
|
+
}
|
|
131
|
+
function pdfHexText(value) {
|
|
132
|
+
const little = Buffer.from(value, "utf16le");
|
|
133
|
+
const big = Buffer.alloc(little.length + 2);
|
|
134
|
+
big[0] = 0xfe;
|
|
135
|
+
big[1] = 0xff;
|
|
136
|
+
for (let index = 0; index < little.length; index += 2) {
|
|
137
|
+
big[index + 2] = little[index + 1];
|
|
138
|
+
big[index + 3] = little[index];
|
|
139
|
+
}
|
|
140
|
+
return big.toString("hex").toUpperCase();
|
|
141
|
+
}
|
|
142
|
+
const PDF_WHITESPACE = new Set(["\0", "\t", "\n", "\f", "\r", " "]);
|
|
143
|
+
function skipPdfWhitespace(text, position) {
|
|
144
|
+
while (position < text.length && PDF_WHITESPACE.has(text[position])) {
|
|
145
|
+
position += 1;
|
|
146
|
+
}
|
|
147
|
+
return position;
|
|
148
|
+
}
|
|
149
|
+
function splitPdfObjects(text, xrefOffset) {
|
|
150
|
+
const objects = [];
|
|
151
|
+
const first = /(\d+) (\d+) obj/.exec(text);
|
|
152
|
+
if (first === null || first.index === undefined) {
|
|
153
|
+
throw new Error("The PDF has no indirect objects.");
|
|
154
|
+
}
|
|
155
|
+
let position = first.index;
|
|
156
|
+
while (position < xrefOffset) {
|
|
157
|
+
position = skipPdfWhitespace(text, position);
|
|
158
|
+
if (position >= xrefOffset)
|
|
159
|
+
break;
|
|
160
|
+
const header = /(\d+) (\d+) obj/.exec(text.slice(position, position + 32));
|
|
161
|
+
if (header === null || header[1] === undefined || header[2] === undefined) {
|
|
162
|
+
throw new Error("The PDF object numbering is not deterministic.");
|
|
163
|
+
}
|
|
164
|
+
const num = Number(header[1]);
|
|
165
|
+
const gen = Number(header[2]);
|
|
166
|
+
const dictStart = position + header[0].length;
|
|
167
|
+
const window = text.slice(dictStart, Math.min(dictStart + 65536, xrefOffset));
|
|
168
|
+
const streamIndex = (() => {
|
|
169
|
+
const match = /stream(?:\r\n|\n|\r)/.exec(window);
|
|
170
|
+
return match?.index;
|
|
171
|
+
})();
|
|
172
|
+
const endIndex = window.indexOf("endobj");
|
|
173
|
+
if (streamIndex !== undefined && (endIndex === -1 || streamIndex < endIndex)) {
|
|
174
|
+
const lengthMatch = /\/Length\s+(\d+)/.exec(window.slice(0, streamIndex));
|
|
175
|
+
const streamEol = /stream(?:\r\n|\n|\r)/.exec(window.slice(streamIndex))?.[0];
|
|
176
|
+
if (lengthMatch?.[1] !== undefined && streamEol !== undefined) {
|
|
177
|
+
const dataStart = dictStart + streamIndex + streamEol.length;
|
|
178
|
+
const dataEnd = dataStart + Number(lengthMatch[1]);
|
|
179
|
+
const tail = text.slice(dataEnd, dataEnd + 16);
|
|
180
|
+
const endMatch = /(?:\r\n|\n|\r)?endstream/.exec(tail);
|
|
181
|
+
if (endMatch !== null && endMatch.index !== undefined) {
|
|
182
|
+
const endObjAt = text.indexOf("endobj", dataEnd + endMatch.index);
|
|
183
|
+
if (endObjAt !== -1 && endObjAt < xrefOffset) {
|
|
184
|
+
objects.push({ num, gen, raw: text.slice(position, endObjAt + 6) });
|
|
185
|
+
position = endObjAt + 6;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
throw new Error("The PDF object stream could not be parsed deterministically.");
|
|
191
|
+
}
|
|
192
|
+
if (endIndex === -1) {
|
|
193
|
+
throw new Error("The PDF object stream could not be parsed deterministically.");
|
|
194
|
+
}
|
|
195
|
+
const endObjAt = dictStart + endIndex;
|
|
196
|
+
objects.push({ num, gen, raw: text.slice(position, endObjAt + 6) });
|
|
197
|
+
position = endObjAt + 6;
|
|
198
|
+
}
|
|
199
|
+
return objects;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Deterministic PDF post-processing over pinned-browser bytes. Chromium
|
|
203
|
+
* leaves only wall-clock CreationDate/ModDate nondeterministic; this
|
|
204
|
+
* rebuilds the Info dictionary without dates, pins versioned
|
|
205
|
+
* producer/creator plus semantic title/authors, derives the trailer
|
|
206
|
+
* document ID from the full render identity, strips XMP metadata the P0
|
|
207
|
+
* profile does not claim, and rebuilds the cross-reference table so
|
|
208
|
+
* identical renders hash identically.
|
|
209
|
+
* Blink also emits per-session structure-tree element IDs (`/ID (node…)`);
|
|
210
|
+
* these are replaced with deterministic per-object IDs so identical renders
|
|
211
|
+
* hash identically.
|
|
212
|
+
*/
|
|
213
|
+
function isPdfDocumentId(value) {
|
|
214
|
+
return /^[0-9a-f]{32}$/.test(value);
|
|
215
|
+
}
|
|
216
|
+
export function canonicalizePdf(raw, identity) {
|
|
217
|
+
if (!isPdfDocumentId(identity.documentId)) {
|
|
218
|
+
throw new Error("The PDF document ID must be 32 lowercase hex characters.");
|
|
219
|
+
}
|
|
220
|
+
if (raw.byteLength > PDF_MAX_BYTES) {
|
|
221
|
+
throw new PdfArtifactLimitError(raw.byteLength);
|
|
222
|
+
}
|
|
223
|
+
const text = Buffer.from(raw).toString("latin1");
|
|
224
|
+
if (!text.startsWith("%PDF-")) {
|
|
225
|
+
throw new Error("The PDF header is invalid.");
|
|
226
|
+
}
|
|
227
|
+
const startxrefAt = text.lastIndexOf("startxref");
|
|
228
|
+
if (startxrefAt === -1) {
|
|
229
|
+
throw new Error("The PDF is missing its cross-reference offset.");
|
|
230
|
+
}
|
|
231
|
+
const xrefOffset = Number.parseInt(text.slice(startxrefAt + 9), 10);
|
|
232
|
+
if (!Number.isInteger(xrefOffset) || xrefOffset <= 0 || xrefOffset >= raw.byteLength) {
|
|
233
|
+
throw new Error("The PDF cross-reference offset is invalid.");
|
|
234
|
+
}
|
|
235
|
+
const trailerMatch = /trailer([\s\S]*?)startxref/.exec(text.slice(xrefOffset, startxrefAt + 32));
|
|
236
|
+
if (trailerMatch?.[1] === undefined) {
|
|
237
|
+
throw new Error("The PDF is missing its trailer dictionary.");
|
|
238
|
+
}
|
|
239
|
+
const trailer = trailerMatch[1];
|
|
240
|
+
const sizeMatch = /\/Size\s+(\d+)/.exec(trailer);
|
|
241
|
+
const rootMatch = /\/Root\s+(\d+) (\d+) R/.exec(trailer);
|
|
242
|
+
const infoMatch = /\/Info\s+(\d+) (\d+) R/.exec(trailer);
|
|
243
|
+
if (sizeMatch?.[1] === undefined ||
|
|
244
|
+
rootMatch?.[1] === undefined ||
|
|
245
|
+
rootMatch?.[2] === undefined ||
|
|
246
|
+
infoMatch?.[1] === undefined ||
|
|
247
|
+
infoMatch?.[2] === undefined) {
|
|
248
|
+
throw new Error("The PDF trailer must reference its Size, Root, and Info.");
|
|
249
|
+
}
|
|
250
|
+
const size = Number(sizeMatch[1]);
|
|
251
|
+
const rootNum = Number(rootMatch[1]);
|
|
252
|
+
const rootGen = Number(rootMatch[2]);
|
|
253
|
+
const infoNum = Number(infoMatch[1]);
|
|
254
|
+
const infoGen = Number(infoMatch[2]);
|
|
255
|
+
const pageMatch = /\/Type\s*\/Pages\b[\s\S]{0,500}?\/Count\s+(\d+)/.exec(text);
|
|
256
|
+
if (pageMatch?.[1] === undefined) {
|
|
257
|
+
throw new Error("The PDF page tree is missing its page count.");
|
|
258
|
+
}
|
|
259
|
+
const pageCount = Number(pageMatch[1]);
|
|
260
|
+
if (!Number.isInteger(pageCount) || pageCount < 1) {
|
|
261
|
+
throw new Error("The PDF page count is invalid.");
|
|
262
|
+
}
|
|
263
|
+
if (pageCount > PDF_MAX_PAGES) {
|
|
264
|
+
throw new PdfArtifactLimitError(raw.byteLength, `PDF Artifact has ${pageCount} pages; the limit is ${PDF_MAX_PAGES} pages.`);
|
|
265
|
+
}
|
|
266
|
+
const objects = splitPdfObjects(text, xrefOffset);
|
|
267
|
+
const byNumber = new Map(objects.map((object) => [object.num, object]));
|
|
268
|
+
if (!byNumber.has(infoNum)) {
|
|
269
|
+
throw new Error("The PDF is missing its document Info dictionary.");
|
|
270
|
+
}
|
|
271
|
+
const rootObject = byNumber.get(rootNum);
|
|
272
|
+
if (rootObject === undefined) {
|
|
273
|
+
throw new Error("The PDF is missing its document catalog.");
|
|
274
|
+
}
|
|
275
|
+
let catalog = rootObject.raw;
|
|
276
|
+
const metadataMatch = /\/Metadata\s+(\d+) (\d+) R/.exec(catalog);
|
|
277
|
+
const droppedMetadata = metadataMatch?.[1] === undefined ? undefined : Number(metadataMatch[1]);
|
|
278
|
+
if (droppedMetadata !== undefined) {
|
|
279
|
+
catalog = catalog.replace(/\s*\/Metadata\s+\d+ \d+ R/, "");
|
|
280
|
+
}
|
|
281
|
+
const authorEntry = identity.authors.length === 0
|
|
282
|
+
? ""
|
|
283
|
+
: `\n/Author <${pdfHexText(identity.authors.join(", "))}>`;
|
|
284
|
+
const infoRaw = `${infoNum} ${infoGen} obj\n<</Title <${pdfHexText(identity.title)}>${authorEntry}` +
|
|
285
|
+
`\n/Creator (${pdfLiteral(PDF_CREATOR)})\n/Producer (${pdfLiteral(PDF_PRODUCER)})>>\nendobj`;
|
|
286
|
+
const headerEnd = text.indexOf(`${objects[0]?.num} ${objects[0]?.gen} obj`);
|
|
287
|
+
const header = text.slice(0, headerEnd);
|
|
288
|
+
const chunks = [header];
|
|
289
|
+
const offsets = new Map();
|
|
290
|
+
let position = header.length;
|
|
291
|
+
const emit = (num, rawObject) => {
|
|
292
|
+
offsets.set(num, position);
|
|
293
|
+
const chunk = `${rawObject}\n`;
|
|
294
|
+
chunks.push(chunk);
|
|
295
|
+
position += chunk.length;
|
|
296
|
+
};
|
|
297
|
+
// Blink numbers structure-tree element IDs per browser session. Map each
|
|
298
|
+
// session-local node token to its defining object number so both
|
|
299
|
+
// definitions (`/ID (node…)`) and references (`/Headers [(node…)]`)
|
|
300
|
+
// rewrite to the same deterministic ID.
|
|
301
|
+
const structIdByNode = new Map();
|
|
302
|
+
for (const object of objects) {
|
|
303
|
+
for (const match of object.raw.matchAll(/\/ID \(node(\d+)\)/g)) {
|
|
304
|
+
structIdByNode.set(match[1], object.num);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
for (const object of objects) {
|
|
308
|
+
if (object.num === droppedMetadata)
|
|
309
|
+
continue;
|
|
310
|
+
if (object.num === infoNum) {
|
|
311
|
+
emit(object.num, infoRaw);
|
|
312
|
+
}
|
|
313
|
+
else if (object.num === rootNum) {
|
|
314
|
+
emit(object.num, catalog);
|
|
315
|
+
}
|
|
316
|
+
else if (object.raw.includes("/Type /StructElem") && object.raw.includes("(node")) {
|
|
317
|
+
emit(object.num, object.raw.replace(/\(node(\d+)\)/g, (_, digits) => {
|
|
318
|
+
const defining = structIdByNode.get(digits);
|
|
319
|
+
return defining === undefined ? `(node${digits})` : `(azeforge-struct-${defining})`;
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
emit(object.num, object.raw);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const xrefAt = position;
|
|
327
|
+
let xref = `xref\n0 ${size}\n0000000000 65535 f \n`;
|
|
328
|
+
for (let num = 1; num < size; num += 1) {
|
|
329
|
+
const offset = offsets.get(num);
|
|
330
|
+
xref +=
|
|
331
|
+
offset === undefined
|
|
332
|
+
? "0000000000 00000 f \n"
|
|
333
|
+
: `${String(offset).padStart(10, "0")} 00000 n \n`;
|
|
334
|
+
}
|
|
335
|
+
const trailerOut = `trailer\n<</Size ${size}\n/Root ${rootNum} ${rootGen} R` +
|
|
336
|
+
`\n/Info ${infoNum} ${infoGen} R\n/ID [<${identity.documentId}><${identity.documentId}>]>>\n` +
|
|
337
|
+
`startxref\n${xrefAt}\n%%EOF\n`;
|
|
338
|
+
const out = `${chunks.join("")}${xref}${trailerOut}`;
|
|
339
|
+
const bytes = Uint8Array.from(Buffer.from(out, "latin1"));
|
|
340
|
+
if (bytes.byteLength > PDF_MAX_BYTES) {
|
|
341
|
+
throw new PdfArtifactLimitError(bytes.byteLength);
|
|
342
|
+
}
|
|
343
|
+
const boxMatch = /\/MediaBox\s*\[\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*\]/.exec(text);
|
|
344
|
+
if (boxMatch?.[1] === undefined || boxMatch?.[2] === undefined || boxMatch?.[3] === undefined || boxMatch?.[4] === undefined) {
|
|
345
|
+
throw new Error("The PDF pages are missing their media boxes.");
|
|
346
|
+
}
|
|
347
|
+
const pageWidthPt = roundPt(Number(boxMatch[3]) - Number(boxMatch[1]));
|
|
348
|
+
const pageHeightPt = roundPt(Number(boxMatch[4]) - Number(boxMatch[2]));
|
|
349
|
+
if (!Number.isFinite(pageWidthPt) || !Number.isFinite(pageHeightPt) || pageWidthPt <= 0 || pageHeightPt <= 0) {
|
|
350
|
+
throw new Error("The PDF media box is invalid.");
|
|
351
|
+
}
|
|
352
|
+
return { bytes, pageCount, pageWidthPt, pageHeightPt };
|
|
353
|
+
}
|
|
354
|
+
function settlePagedHtml(layout, theme) {
|
|
355
|
+
return (`<!doctype html><html lang="und"><head><meta charset="utf-8"><title>${layout.title}</title>` +
|
|
356
|
+
`<style>${layout.css}${pdfPagedCss(theme)}*{animation:none!important;transition:none!important;caret-color:transparent!important}</style></head>` +
|
|
357
|
+
`<body>${layout.body}</body></html>`);
|
|
358
|
+
}
|
|
359
|
+
async function printPagedPdf(browser, html, geometry, contentHeightPx) {
|
|
360
|
+
const context = await browser.createBrowserContext();
|
|
361
|
+
try {
|
|
362
|
+
const page = await context.newPage();
|
|
363
|
+
await page.setViewport({
|
|
364
|
+
width: Math.ceil(geometry.widthPt * PX_PER_PT),
|
|
365
|
+
height: Math.ceil(geometry.heightPt * PX_PER_PT),
|
|
366
|
+
deviceScaleFactor: 1,
|
|
367
|
+
});
|
|
368
|
+
let deniedRequest;
|
|
369
|
+
await page.setRequestInterception(true);
|
|
370
|
+
page.on("request", (request) => {
|
|
371
|
+
const url = request.url();
|
|
372
|
+
if (ALLOWED_REQUEST.test(url)) {
|
|
373
|
+
void request.continue();
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
deniedRequest ??= url;
|
|
377
|
+
void request.abort("blockedbyclient");
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
await page.setContent(html, { waitUntil: "domcontentloaded" });
|
|
381
|
+
const overflow = await page.evaluate(async (input) => {
|
|
382
|
+
await document.fonts.ready;
|
|
383
|
+
await Promise.all([...document.images].map((image) => image.complete ? Promise.resolve() : image.decode()));
|
|
384
|
+
const settle = async () => {
|
|
385
|
+
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
386
|
+
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
387
|
+
};
|
|
388
|
+
const measure = () => {
|
|
389
|
+
const tallest = [];
|
|
390
|
+
for (const element of document.querySelectorAll(input.selector)) {
|
|
391
|
+
const box = element.getBoundingClientRect();
|
|
392
|
+
if (Number.isFinite(box.height) && box.height > input.limit) {
|
|
393
|
+
const scale = Math.floor((input.limit / box.height) * 1000) / 1000;
|
|
394
|
+
if (scale >= input.floor) {
|
|
395
|
+
element.style.setProperty("zoom", String(scale));
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
tallest.push(Math.round(box.height));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return tallest;
|
|
403
|
+
};
|
|
404
|
+
await settle();
|
|
405
|
+
const refused = measure();
|
|
406
|
+
if (refused.length === 0) {
|
|
407
|
+
await settle();
|
|
408
|
+
return measure();
|
|
409
|
+
}
|
|
410
|
+
return refused;
|
|
411
|
+
}, { limit: contentHeightPx, selector: ATOMIC_SELECTOR, floor: PDF_MIN_ATOMIC_SCALE });
|
|
412
|
+
throwIfDeniedBrowserRequest(deniedRequest);
|
|
413
|
+
if (overflow.length > 0) {
|
|
414
|
+
throw new PdfArtifactLimitError(Buffer.byteLength(html, "utf8"), `Atomic PDF content is ${Math.max(...overflow)}px tall at the minimum readable scale; the page content box is ${Math.floor(contentHeightPx)}px tall. Split or shrink the atomic content.`);
|
|
415
|
+
}
|
|
416
|
+
const pdf = await page.pdf({
|
|
417
|
+
preferCSSPageSize: true,
|
|
418
|
+
printBackground: true,
|
|
419
|
+
tagged: false,
|
|
420
|
+
outline: true,
|
|
421
|
+
timeout: PDF_PRINT_TIMEOUT_MS,
|
|
422
|
+
waitForFonts: true,
|
|
423
|
+
});
|
|
424
|
+
return Uint8Array.from(pdf);
|
|
425
|
+
}
|
|
426
|
+
finally {
|
|
427
|
+
await context.close();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
export async function renderPdf(layout, contentHash, theme, assetManifest, browserCapability, info) {
|
|
431
|
+
const geometry = pdfPageGeometryForTheme(theme);
|
|
432
|
+
const html = settlePagedHtml(layout, theme);
|
|
433
|
+
const htmlBytes = new TextEncoder().encode(html);
|
|
434
|
+
if (htmlBytes.byteLength > PDF_MAX_HTML_BYTES) {
|
|
435
|
+
throw new PdfArtifactLimitError(htmlBytes.byteLength);
|
|
436
|
+
}
|
|
437
|
+
const browser = await browserCapability.launch();
|
|
438
|
+
let raw;
|
|
439
|
+
try {
|
|
440
|
+
raw = await printPagedPdf(browser, html, geometry, pdfContentHeightCssPx(geometry));
|
|
441
|
+
}
|
|
442
|
+
finally {
|
|
443
|
+
await browser.close();
|
|
444
|
+
}
|
|
445
|
+
const rendererFingerprint = sha256(canonicalJson({
|
|
446
|
+
renderer: {
|
|
447
|
+
id: PDF_RENDERER_ID,
|
|
448
|
+
version: PDF_RENDERER_VERSION,
|
|
449
|
+
serializer: PDF_SERIALIZER,
|
|
450
|
+
},
|
|
451
|
+
profile: PDF_PROFILE,
|
|
452
|
+
layoutEngine: `HeadlessChrome/${CHROME_HEADLESS_SHELL_VERSION}`,
|
|
453
|
+
platform: { os: platform(), architecture: arch() },
|
|
454
|
+
requiredCapabilities: PDF_REQUIRED_CAPABILITIES,
|
|
455
|
+
pageGeometry: {
|
|
456
|
+
widthPt: geometry.widthPt,
|
|
457
|
+
heightPt: geometry.heightPt,
|
|
458
|
+
marginPt: geometry.marginPt,
|
|
459
|
+
},
|
|
460
|
+
...layout.fingerprintDependencies,
|
|
461
|
+
}));
|
|
462
|
+
const identityHash = sha256(canonicalJson({
|
|
463
|
+
contentHash,
|
|
464
|
+
assetManifestHash: assetManifestHash(assetManifest),
|
|
465
|
+
rendererFingerprint,
|
|
466
|
+
title: info.title,
|
|
467
|
+
authors: [...info.authors],
|
|
468
|
+
}));
|
|
469
|
+
const hex = identityHash.slice("sha256:".length);
|
|
470
|
+
const documentId = hex.slice(0, 32);
|
|
471
|
+
if (!isPdfDocumentId(documentId)) {
|
|
472
|
+
throw new Error("The PDF document identity is invalid.");
|
|
473
|
+
}
|
|
474
|
+
const { bytes, pageCount, pageWidthPt, pageHeightPt } = canonicalizePdf(raw, {
|
|
475
|
+
title: info.title,
|
|
476
|
+
authors: info.authors,
|
|
477
|
+
documentId,
|
|
478
|
+
});
|
|
479
|
+
const pageGeometry = {
|
|
480
|
+
widthPt: pageWidthPt,
|
|
481
|
+
heightPt: pageHeightPt,
|
|
482
|
+
marginPt: geometry.marginPt,
|
|
483
|
+
};
|
|
484
|
+
return {
|
|
485
|
+
bytes,
|
|
486
|
+
metadata: {
|
|
487
|
+
format: "pdf",
|
|
488
|
+
mimeType: PDF_MIME_TYPE,
|
|
489
|
+
profile: PDF_PROFILE,
|
|
490
|
+
byteLength: bytes.byteLength,
|
|
491
|
+
contentHash,
|
|
492
|
+
assetManifestHash: assetManifestHash(assetManifest),
|
|
493
|
+
rendererFingerprint,
|
|
494
|
+
artifactHash: artifactBytesHash(bytes),
|
|
495
|
+
theme: { id: theme.id, version: theme.version },
|
|
496
|
+
cssDimensions: { ...theme.geometry },
|
|
497
|
+
pageCount,
|
|
498
|
+
pageGeometry,
|
|
499
|
+
requiredCapabilities: PDF_REQUIRED_CAPABILITIES,
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
//# sourceMappingURL=render-pdf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-pdf.js","sourceRoot":"","sources":["../src/render-pdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAWxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,CAAC,MAAM,eAAe,GAAG,KAAc,CAAC;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAgB,CAAC;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,iBAA0B,CAAC;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAgC,CAAC;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAG,iBAA0B,CAAC;AACzD,MAAM,YAAY,GAAG,sCAAsC,6BAA6B,GAAY,CAAC;AACrG,MAAM,WAAW,GAAG,UAAmB,CAAC;AACxC,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,CAAU,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAC/C,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AACjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AACnD,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAC3C,MAAM,eAAe,GAAG,4EAA4E,CAAC;AACrG,MAAM,eAAe,GAAG,uCAAuC,CAAC;AAChE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AACpD;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,SAAS,gBAAgB,CAAC,QAA0B;IAClD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;YACxB,GAAG,QAAQ,CAAC,UAAU;YACtB,EAAE,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC;YACrD,UAAU,EAAE,eAAe;SAC5B,CAAC;QACF,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAqB,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAgC,MAAM,CAAC,MAAM,CAAC;IAC1E,gBAAgB,CAAC,yBAAyB,CAAC;IAC3C,gBAAgB,CAAC,wBAAwB,CAAC;IAC1C,gBAAgB,CAAC,wBAAwB,CAAC;IAC1C,gBAAgB,CAAC,sBAAsB,CAAC;CACzC,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,0BAA0B,GAAyB,MAAM,CAAC,MAAM,CAAC;IAC5E,MAAM,EAAE,mBAAmB;CAC5B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAuB,MAAM,CAAC,MAAM,CAAC;IACrE,EAAE,EAAE,eAAe;IACnB,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAU,CAAC;IACxC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAU,CAAC;CAClD,CAAC,CAAC;AAEH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,UAAU,CAAS;IAE5B,YAAY,UAAkB,EAAE,MAAe;QAC7C,KAAK,CACH,MAAM;YACJ,mBAAmB,UAAU,wBAAwB,aAAa,SAAS,CAC9E,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AASD,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC;AAC5B,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,CAAC;AAE1B,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACzC,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAC,KAAY;IAClD,IAAI,KAAK,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;QAC5B,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;YACjC,QAAQ,EAAE,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;YAClC,QAAQ,EAAE,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC;YACjC,OAAO,EAAE,qBAAqB;SAC/B,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,EAAE,KAAK,mBAAmB,EAAE,CAAC;QACrC,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;YAC7B,QAAQ,EAAE,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC;YAC3B,QAAQ,EAAE,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC;YAC3B,OAAO,EAAE,kCAAkC;SAC5C,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;QACjC,QAAQ,EAAE,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;QAClC,QAAQ,EAAE,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC;QACjC,OAAO,EAAE,qBAAqB;KAC/B,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAyB;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;AACjE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,YAAY,GAChB,KAAK,CAAC,EAAE,KAAK,mBAAmB;QAC9B,CAAC,CAAC,iDAAiD;QACnD,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,CACL,SAAS,QAAQ,CAAC,OAAO,GAAG;QAC5B,mFAAmF;QACnF,yDAAyD;QACzD,0BAA0B;QAC1B,yDAAyD;QACzD,wBAAwB;QACxB,2DAA2D;QAC3D,iCAAiC;QACjC,YAAY,CACb,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5C,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACd,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAW,CAAC;QAC7C,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAW,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;AAC3C,CAAC;AAQD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAEpE,SAAS,iBAAiB,CAAC,IAAY,EAAE,QAAgB;IACvD,OAAO,QAAQ,GAAG,IAAI,CAAC,MAAM,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAW,CAAC,EAAE,CAAC;QAC9E,QAAQ,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,UAAkB;IACvD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;IAC3B,OAAO,QAAQ,GAAG,UAAU,EAAE,CAAC;QAC7B,QAAQ,GAAG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,QAAQ,IAAI,UAAU;YAAE,MAAM;QAClC,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3E,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;QAC9E,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClD,OAAO,KAAK,EAAE,KAAK,CAAC;QACtB,CAAC,CAAC,EAAE,CAAC;QACL,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,WAAW,KAAK,SAAS,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC;YAC7E,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;YAC1E,MAAM,SAAS,GAAG,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9E,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC9D,MAAM,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC;gBAC7D,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC;gBAC/C,MAAM,QAAQ,GAAG,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;oBAClE,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;wBAC7C,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;wBACpE,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC;wBACxB,SAAS;oBACX,CAAC;gBACH,CAAC;YACH,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAClF,CAAC;QACD,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QACpE,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAeD;;;;;;;;;;;GAWG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AACD,MAAM,UAAU,eAAe,CAC7B,GAAe,EACf,QAA8B;IAE9B,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,GAAG,aAAa,EAAE,CAAC;QACnC,MAAM,IAAI,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IAClD,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,IAAI,UAAU,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACrF,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,YAAY,GAAG,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;IACjG,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzD,IACE,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;QAC5B,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;QAC5B,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;QAC5B,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS;QAC5B,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAC5B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAErC,MAAM,SAAS,GAAG,iDAAiD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,SAAS,GAAG,aAAa,EAAE,CAAC;QAC9B,MAAM,IAAI,qBAAqB,CAC7B,GAAG,CAAC,UAAU,EACd,oBAAoB,SAAS,wBAAwB,aAAa,SAAS,CAC5E,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACxE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC;IAC7B,MAAM,aAAa,GAAG,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,eAAe,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAChG,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,WAAW,GACf,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAC3B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,cAAc,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;IAC/D,MAAM,OAAO,GACX,GAAG,OAAO,IAAI,OAAO,mBAAmB,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE;QACnF,eAAe,UAAU,CAAC,WAAW,CAAC,iBAAiB,UAAU,CAAC,YAAY,CAAC,aAAa,CAAC;IAE/F,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACxC,MAAM,MAAM,GAAa,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,SAAiB,EAAQ,EAAE;QACpD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,GAAG,SAAS,IAAI,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC,CAAC;IACF,yEAAyE;IACzE,iEAAiE;IACjE,oEAAoE;IACpE,wCAAwC;IACxC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IACjD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAC/D,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,GAAG,KAAK,eAAe;YAAE,SAAS;QAC7C,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACpF,IAAI,CACF,MAAM,CAAC,GAAG,EACV,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAc,EAAE,EAAE;gBACzD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC5C,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,MAAM,GAAG,CAAC,CAAC,CAAC,oBAAoB,QAAQ,GAAG,CAAC;YACtF,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC;IACxB,IAAI,IAAI,GAAG,WAAW,IAAI,yBAAyB,CAAC;IACpD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI;YACF,MAAM,KAAK,SAAS;gBAClB,CAAC,CAAC,uBAAuB;gBACzB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,aAAa,CAAC;IACzD,CAAC;IACD,MAAM,UAAU,GACd,oBAAoB,IAAI,WAAW,OAAO,IAAI,OAAO,IAAI;QACzD,WAAW,OAAO,IAAI,OAAO,aAAa,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,QAAQ;QAC7F,cAAc,MAAM,WAAW,CAAC;IAClC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,UAAU,EAAE,CAAC;IACrD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,UAAU,GAAG,aAAa,EAAE,CAAC;QACrC,MAAM,IAAI,qBAAqB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,QAAQ,GAAG,sDAAsD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnF,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC7H,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,WAAW,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QAC7G,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,eAAe,CAAC,MAAkB,EAAE,KAAY;IACvD,OAAO,CACL,sEAAsE,MAAM,CAAC,KAAK,UAAU;QAC5F,UAAU,MAAM,CAAC,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,wGAAwG;QACjJ,SAAS,MAAM,CAAC,IAAI,gBAAgB,CACrC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAAgB,EAChB,IAAY,EACZ,QAAyB,EACzB,eAAuB;IAEvB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,oBAAoB,EAAE,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,IAAI,CAAC,WAAW,CAAC;YACrB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC;YAC9C,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC;YAChD,iBAAiB,EAAE,CAAC;SACrB,CAAC,CAAC;QACH,IAAI,aAAiC,CAAC;QACtC,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAoB,EAAE,EAAE;YAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAC1B,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9B,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,aAAa,KAAK,GAAG,CAAC;gBACtB,KAAK,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACxC,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAClC,KAAK,EAAE,KAAyD,EAAE,EAAE;YAClE,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;YAC3B,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACjC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CACpD,CACF,CAAC;YACF,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;gBACvC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC7E,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC/E,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,GAAa,EAAE;gBAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChE,MAAM,GAAG,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;oBAC5C,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;wBAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;wBACnE,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;4BACxB,OAAuB,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;wBACpE,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;wBACvC,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC,CAAC;YACF,MAAM,MAAM,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;YAC1B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,MAAM,EAAE,CAAC;gBACf,OAAO,OAAO,EAAE,CAAC;YACnB,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,EACD,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,oBAAoB,EAAE,CACnF,CAAC;QACF,2BAA2B,CAAC,aAAa,CAAC,CAAC;QAC3C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,qBAAqB,CAC7B,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,EAC/B,yBAAyB,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,kEAAkE,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,8CAA8C,CAC1L,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC;YACzB,iBAAiB,EAAE,IAAI;YACvB,eAAe,EAAE,IAAI;YACrB,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,oBAAoB;YAC7B,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAkB,EAClB,WAAwB,EACxB,KAAY,EACZ,aAA4C,EAC5C,iBAAuC,EACvC,IAAqB;IAErB,MAAM,QAAQ,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,SAAS,CAAC,UAAU,GAAG,kBAAkB,EAAE,CAAC;QAC9C,MAAM,IAAI,qBAAqB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,CAAC;IACjD,IAAI,GAAe,CAAC;IACpB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtF,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IACD,MAAM,mBAAmB,GAAG,MAAM,CAChC,aAAa,CAAC;QACZ,QAAQ,EAAE;YACR,EAAE,EAAE,eAAe;YACnB,OAAO,EAAE,oBAAoB;YAC7B,UAAU,EAAE,cAAc;SAC3B;QACD,OAAO,EAAE,WAAW;QACpB,YAAY,EAAE,kBAAkB,6BAA6B,EAAE;QAC/D,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE;QAClD,oBAAoB,EAAE,yBAAyB;QAC/C,YAAY,EAAE;YACZ,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;SAC5B;QACD,GAAI,MAAM,CAAC,uBAA+D;KAC3E,CAAC,CACH,CAAC;IACF,MAAM,YAAY,GAAG,MAAM,CACzB,aAAa,CAAC;QACZ,WAAW;QACX,iBAAiB,EAAE,iBAAiB,CAAC,aAAa,CAAC;QACnD,mBAAmB;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;KAC3B,CAAC,CACH,CAAC;IACF,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,eAAe,CAAC,GAAG,EAAE;QAC3E,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU;KACX,CAAC,CAAC;IACH,MAAM,YAAY,GAAG;QACnB,OAAO,EAAE,WAAW;QACpB,QAAQ,EAAE,YAAY;QACtB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;KAC5B,CAAC;IACF,OAAO;QACL,KAAK;QACL,QAAQ,EAAE;YACR,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,aAAa;YACvB,OAAO,EAAE,WAAW;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW;YACX,iBAAiB,EAAE,iBAAiB,CAAC,aAAa,CAAC;YACnD,mBAAmB;YACnB,YAAY,EAAE,iBAAiB,CAAC,KAAK,CAAC;YACtC,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;YAC/C,aAAa,EAAE,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE;YACpC,SAAS;YACT,YAAY;YACZ,oBAAoB,EAAE,yBAAyB;SAChD;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Browser } from "puppeteer-core";
|
|
2
|
+
import type { AnyBlockRenderer, Artifact, AssetManifestEntry, ContentHash, RendererDescriptor, Theme } from "./model.js";
|
|
3
|
+
import type { HtmlLayout } from "./render-html.js";
|
|
4
|
+
export declare const PNG_RENDERER_ID: "png";
|
|
5
|
+
export declare const PNG_RENDERER_VERSION: "1.0.0";
|
|
6
|
+
export declare const PNG_MIME_TYPE: "image/png";
|
|
7
|
+
export declare const PNG_PROFILE: "azeforge.png.continuous/v1";
|
|
8
|
+
export declare const PNG_SERIALIZER: "azeforge-png/v1";
|
|
9
|
+
export declare const PNG_DEVICE_SCALE_FACTOR: 2;
|
|
10
|
+
export declare const PNG_MAX_BYTES: number;
|
|
11
|
+
export declare const PNG_MAX_CSS_HEIGHT_PX = 100000;
|
|
12
|
+
export declare const PNG_MAX_PIXEL_DIMENSION = 32768;
|
|
13
|
+
export declare const PNG_MAX_PIXELS = 50000000;
|
|
14
|
+
export declare const PNG_REQUIRED_CAPABILITIES: readonly ["png-continuous", "srgb"];
|
|
15
|
+
export declare const pngBlockRenderers: readonly AnyBlockRenderer[];
|
|
16
|
+
export interface PngBrowserCapability {
|
|
17
|
+
readonly launch: () => Promise<Browser>;
|
|
18
|
+
}
|
|
19
|
+
export declare const pinnedPngBrowserCapability: PngBrowserCapability;
|
|
20
|
+
export declare const pngRendererDescriptor: RendererDescriptor;
|
|
21
|
+
export declare class PngArtifactLimitError extends Error {
|
|
22
|
+
readonly byteLength: number;
|
|
23
|
+
constructor(byteLength: number);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Deterministic PNG normalization: keeps the IHDR geometry, strips every
|
|
27
|
+
* unstable or private ancillary chunk, emits one fixed sRGB chunk, and
|
|
28
|
+
* re-encodes IDAT with fixed filtering and compression. Same decoded
|
|
29
|
+
* pixels always produce identical bytes.
|
|
30
|
+
*/
|
|
31
|
+
export declare function normalizePng(bytes: Uint8Array): Uint8Array;
|
|
32
|
+
export declare function renderPng(layout: HtmlLayout, contentHash: ContentHash, theme: Theme, assetManifest: readonly AssetManifestEntry[], browserCapability: PngBrowserCapability): Promise<Artifact>;
|