chartjs2img 0.3.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.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Find a Chromium/Chrome executable already installed on this machine.
3
+ * Checks: CHROMIUM_PATH env → Playwright cache → system Chrome → Chrome
4
+ * for Testing cache.
5
+ */
6
+ export declare function findChromiumExecutable(): string | null;
7
+ /** Download Chrome for Testing directly via fetch — no sudo, no npm/npx needed */
8
+ export declare function downloadChromeForTesting(): Promise<string>;
9
+ export declare function ensureChromiumInstalled(): Promise<string>;
10
+ //# sourceMappingURL=chromium.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromium.d.ts","sourceRoot":"","sources":["../src/chromium.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAgFtD;AAaD,kFAAkF;AAClF,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC,CAqFhE;AASD,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAyB/D"}
@@ -0,0 +1,226 @@
1
+ // Chromium procurement.
2
+ //
3
+ // Three functions, each with a tight responsibility:
4
+ // findChromiumExecutable — scan known install locations and return
5
+ // a path if Chrome/Chromium is already present. Pure wrt. the
6
+ // filesystem: it doesn't touch the network or create files.
7
+ // downloadChromeForTesting — install Chrome for Testing into the
8
+ // user-local Playwright cache. Side effects: fetch + fs write.
9
+ // ensureChromiumInstalled — orchestrator. Returns a cached path if
10
+ // called repeatedly within the same process.
11
+ //
12
+ // Split out from renderer.ts so renderer owns browser/page lifecycle,
13
+ // not platform-specific binary discovery.
14
+ import { existsSync, readdirSync, mkdirSync, writeFileSync, chmodSync, unlinkSync } from 'fs';
15
+ import { join } from 'path';
16
+ import { homedir, platform, arch } from 'os';
17
+ /**
18
+ * Find a Chromium/Chrome executable already installed on this machine.
19
+ * Checks: CHROMIUM_PATH env → Playwright cache → system Chrome → Chrome
20
+ * for Testing cache.
21
+ */
22
+ export function findChromiumExecutable() {
23
+ const os = platform();
24
+ const home = homedir();
25
+ // 1. Environment variable override
26
+ if (process.env.CHROMIUM_PATH && existsSync(process.env.CHROMIUM_PATH)) {
27
+ return process.env.CHROMIUM_PATH;
28
+ }
29
+ // 2. Scan Playwright's browser cache directories (from prior installs)
30
+ const cacheDirs = [];
31
+ if (process.env.PLAYWRIGHT_BROWSERS_PATH) {
32
+ cacheDirs.push(process.env.PLAYWRIGHT_BROWSERS_PATH);
33
+ }
34
+ if (os === 'darwin') {
35
+ cacheDirs.push(join(home, 'Library', 'Caches', 'ms-playwright'));
36
+ }
37
+ else if (os === 'linux') {
38
+ cacheDirs.push(join(home, '.cache', 'ms-playwright'));
39
+ }
40
+ else if (os === 'win32') {
41
+ cacheDirs.push(join(home, 'AppData', 'Local', 'ms-playwright'));
42
+ }
43
+ const playwrightExecPaths = {
44
+ darwin: [
45
+ 'chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',
46
+ 'chrome-mac/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',
47
+ 'chrome-mac-arm64/Chromium.app/Contents/MacOS/Chromium',
48
+ 'chrome-mac/Chromium.app/Contents/MacOS/Chromium',
49
+ ],
50
+ linux: ['chrome-linux/chrome', 'chrome-linux64/chrome', 'chrome-linux/chromium'],
51
+ win32: ['chrome-win64/chrome.exe', 'chrome-win/chrome.exe'],
52
+ };
53
+ const candidates = playwrightExecPaths[os] ?? playwrightExecPaths['linux'];
54
+ for (const cacheDir of cacheDirs) {
55
+ if (!existsSync(cacheDir))
56
+ continue;
57
+ let entries;
58
+ try {
59
+ entries = readdirSync(cacheDir)
60
+ .filter((e) => e.startsWith('chromium'))
61
+ .sort()
62
+ .reverse();
63
+ }
64
+ catch {
65
+ continue;
66
+ }
67
+ for (const entry of entries) {
68
+ for (const relPath of candidates) {
69
+ const fullPath = join(cacheDir, entry, relPath);
70
+ if (existsSync(fullPath))
71
+ return fullPath;
72
+ }
73
+ }
74
+ }
75
+ // 3. System-installed Chrome/Chromium
76
+ const systemPaths = {
77
+ darwin: [
78
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
79
+ '/Applications/Chromium.app/Contents/MacOS/Chromium',
80
+ join(home, 'Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
81
+ ],
82
+ linux: [
83
+ '/usr/bin/google-chrome-stable',
84
+ '/usr/bin/google-chrome',
85
+ '/usr/bin/chromium-browser',
86
+ '/usr/bin/chromium',
87
+ '/snap/bin/chromium',
88
+ ],
89
+ win32: [
90
+ join(process.env.PROGRAMFILES ?? 'C:\\Program Files', 'Google\\Chrome\\Application\\chrome.exe'),
91
+ join(process.env['PROGRAMFILES(X86)'] ?? 'C:\\Program Files (x86)', 'Google\\Chrome\\Application\\chrome.exe'),
92
+ join(home, 'AppData\\Local\\Google\\Chrome\\Application\\chrome.exe'),
93
+ ],
94
+ };
95
+ for (const p of systemPaths[os] ?? []) {
96
+ if (existsSync(p))
97
+ return p;
98
+ }
99
+ return null;
100
+ }
101
+ /** Chrome-for-Testing platform string for the current OS/arch, or null if unsupported */
102
+ function getCftPlatform() {
103
+ const os = platform();
104
+ const a = arch();
105
+ if (os === 'darwin')
106
+ return a === 'arm64' ? 'mac-arm64' : 'mac-x64';
107
+ if (os === 'win32')
108
+ return a === 'x64' ? 'win64' : 'win32';
109
+ // Chrome for Testing only provides linux64 (x86_64) — no linux-arm64
110
+ if (a === 'arm64' || a === 'aarch64')
111
+ return null;
112
+ return 'linux64';
113
+ }
114
+ /** Download Chrome for Testing directly via fetch — no sudo, no npm/npx needed */
115
+ export async function downloadChromeForTesting() {
116
+ const os = platform();
117
+ const cftPlatform = getCftPlatform();
118
+ if (!cftPlatform) {
119
+ throw new Error(`Chrome for Testing is not available for ${platform()}/${arch()}.\n` +
120
+ 'Install Chromium manually (e.g., apt install chromium) and set CHROMIUM_PATH.');
121
+ }
122
+ // Install into user-local cache directory (no sudo)
123
+ const home = homedir();
124
+ let installBase;
125
+ if (os === 'darwin') {
126
+ installBase = join(home, 'Library', 'Caches', 'ms-playwright');
127
+ }
128
+ else if (os === 'win32') {
129
+ installBase = join(home, 'AppData', 'Local', 'ms-playwright');
130
+ }
131
+ else {
132
+ installBase = join(home, '.cache', 'ms-playwright');
133
+ }
134
+ const installDir = join(installBase, 'chromium-cft');
135
+ mkdirSync(installDir, { recursive: true });
136
+ // Fetch latest stable download URL from Chrome for Testing API
137
+ console.log('[chromium] Fetching Chrome for Testing download info...');
138
+ const apiUrl = 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json';
139
+ const res = await fetch(apiUrl);
140
+ if (!res.ok)
141
+ throw new Error(`Failed to fetch Chrome for Testing API: ${res.status}`);
142
+ const data = (await res.json());
143
+ const entry = data.channels.Stable.downloads.chrome.find((d) => d.platform === cftPlatform);
144
+ if (!entry)
145
+ throw new Error(`No Chrome for Testing download for platform: ${cftPlatform}`);
146
+ const downloadUrl = entry.url;
147
+ const version = data.channels.Stable.version;
148
+ console.log(`[chromium] Downloading Chrome ${version} for ${cftPlatform}...`);
149
+ const dlRes = await fetch(downloadUrl);
150
+ if (!dlRes.ok)
151
+ throw new Error(`Download failed: ${dlRes.status}`);
152
+ const zipBuffer = Buffer.from(await dlRes.arrayBuffer());
153
+ const zipPath = join(installDir, 'chrome.zip');
154
+ writeFileSync(zipPath, zipBuffer);
155
+ console.log('[chromium] Extracting...');
156
+ if (os === 'win32') {
157
+ const proc = Bun.spawn(['powershell', '-Command', `Expand-Archive -Force -Path '${zipPath}' -DestinationPath '${installDir}'`], { stdout: 'inherit', stderr: 'inherit' });
158
+ if ((await proc.exited) !== 0)
159
+ throw new Error('Failed to extract (PowerShell Expand-Archive)');
160
+ }
161
+ else {
162
+ const proc = Bun.spawn(['unzip', '-o', '-q', zipPath, '-d', installDir], {
163
+ stdout: 'inherit',
164
+ stderr: 'inherit',
165
+ });
166
+ if ((await proc.exited) !== 0)
167
+ throw new Error('Failed to extract (unzip)');
168
+ }
169
+ try {
170
+ unlinkSync(zipPath);
171
+ }
172
+ catch {
173
+ /* ignore */
174
+ }
175
+ // Find the extracted executable
176
+ const execCandidates = {
177
+ darwin: [`chrome-${cftPlatform}/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing`],
178
+ linux: [`chrome-${cftPlatform}/chrome`],
179
+ win32: [`chrome-${cftPlatform}\\chrome.exe`],
180
+ };
181
+ for (const rel of execCandidates[os] ?? execCandidates['linux']) {
182
+ const fullPath = join(installDir, rel);
183
+ if (existsSync(fullPath)) {
184
+ if (os !== 'win32') {
185
+ try {
186
+ chmodSync(fullPath, 0o755);
187
+ }
188
+ catch {
189
+ /* ignore */
190
+ }
191
+ }
192
+ return fullPath;
193
+ }
194
+ }
195
+ throw new Error('Chrome was downloaded but executable not found in extracted files');
196
+ }
197
+ /**
198
+ * Return a path to a Chromium executable, installing Chrome for Testing
199
+ * on first call if no local Chrome/Chromium is discoverable. Caches the
200
+ * result for the lifetime of the process.
201
+ */
202
+ let cachedPath = null;
203
+ export async function ensureChromiumInstalled() {
204
+ if (cachedPath)
205
+ return cachedPath;
206
+ const found = findChromiumExecutable();
207
+ if (found) {
208
+ cachedPath = found;
209
+ return cachedPath;
210
+ }
211
+ console.log('[chromium] Chrome/Chromium not found. Installing Chrome for Testing...');
212
+ try {
213
+ const p = await downloadChromeForTesting();
214
+ console.log('[chromium] Chrome for Testing installed successfully');
215
+ cachedPath = p;
216
+ return cachedPath;
217
+ }
218
+ catch (err) {
219
+ const msg = err instanceof Error ? err.message : String(err);
220
+ throw new Error(`Failed to install Chrome automatically: ${msg}\n` +
221
+ 'You can install it manually:\n' +
222
+ ' - Install Google Chrome, or\n' +
223
+ ' - Set CHROMIUM_PATH env var to an existing Chrome/Chromium executable.');
224
+ }
225
+ }
226
+ //# sourceMappingURL=chromium.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromium.js","sourceRoot":"","sources":["../src/chromium.ts"],"names":[],"mappings":"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"}
package/dist/lib.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * chartjs2img — TypeScript / Node library entry.
3
+ *
4
+ * Import this file to render Chart.js configurations to images from
5
+ * any Bun / Node program:
6
+ *
7
+ * import { renderChart, closeBrowser } from 'chartjs2img'
8
+ *
9
+ * const result = await renderChart({
10
+ * chart: { type: 'bar', data: { labels: ['A','B'], datasets: [{ data: [1,2] }] } },
11
+ * width: 800, height: 600, format: 'png',
12
+ * })
13
+ * await Bun.write('chart.png', result.buffer)
14
+ * if (result.messages.length) console.warn(result.messages)
15
+ * await closeBrowser() // on process shutdown
16
+ *
17
+ * The `chartjs2img` CLI (`src/index.ts`) and the HTTP server
18
+ * (`src/server.ts`) share the same render pipeline but import it
19
+ * directly from ./renderer etc. — NOT from this file. That way the
20
+ * public surface exported here is a constraint for external consumers
21
+ * only, and internal refactoring does not have to preserve it.
22
+ *
23
+ * This module intentionally **does not** export the in-memory cache
24
+ * internals, the Puppeteer launch helpers, the HTML template, or the
25
+ * CLI argument parser. Those are implementation details; keep your
26
+ * dependency surface on the exports below so upgrades stay drop-in.
27
+ */
28
+ export { renderChart, closeBrowser, rendererStats, Renderer } from './renderer';
29
+ export type { RenderResult, ConsoleMessage, RendererConfig, RendererStats } from './renderer';
30
+ export type { RenderOptions } from './template';
31
+ export { computeHash } from './cache';
32
+ export { VERSION, NAME } from './version';
33
+ /**
34
+ * The exact Chart.js + plugin versions bundled into the rendering
35
+ * page. Frozen as a reference table so callers can expose "what's
36
+ * inside this chartjs2img?" to their own users without parsing
37
+ * `chartjs2img llm`.
38
+ */
39
+ export { LIBS as BUNDLED_LIBS } from './template';
40
+ //# sourceMappingURL=lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC/E,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG7F,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAI/C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAIrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC;;;;;GAKG;AACH,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA"}
package/dist/lib.js ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * chartjs2img — TypeScript / Node library entry.
3
+ *
4
+ * Import this file to render Chart.js configurations to images from
5
+ * any Bun / Node program:
6
+ *
7
+ * import { renderChart, closeBrowser } from 'chartjs2img'
8
+ *
9
+ * const result = await renderChart({
10
+ * chart: { type: 'bar', data: { labels: ['A','B'], datasets: [{ data: [1,2] }] } },
11
+ * width: 800, height: 600, format: 'png',
12
+ * })
13
+ * await Bun.write('chart.png', result.buffer)
14
+ * if (result.messages.length) console.warn(result.messages)
15
+ * await closeBrowser() // on process shutdown
16
+ *
17
+ * The `chartjs2img` CLI (`src/index.ts`) and the HTTP server
18
+ * (`src/server.ts`) share the same render pipeline but import it
19
+ * directly from ./renderer etc. — NOT from this file. That way the
20
+ * public surface exported here is a constraint for external consumers
21
+ * only, and internal refactoring does not have to preserve it.
22
+ *
23
+ * This module intentionally **does not** export the in-memory cache
24
+ * internals, the Puppeteer launch helpers, the HTML template, or the
25
+ * CLI argument parser. Those are implementation details; keep your
26
+ * dependency surface on the exports below so upgrades stay drop-in.
27
+ */
28
+ // Core render pipeline. Most callers just need the module-level
29
+ // renderChart / closeBrowser helpers, which back onto a lazily-created
30
+ // default Renderer. Advanced callers (test harnesses, multi-tenant
31
+ // servers that want isolated browser pools, or programs that want to
32
+ // configure concurrency per-instance) can instantiate `Renderer`
33
+ // directly.
34
+ export { renderChart, closeBrowser, rendererStats, Renderer } from './renderer';
35
+ // Deterministic hash computation — useful for building a CDN-facing
36
+ // cache layer or for deduping submissions before rendering.
37
+ export { computeHash } from './cache';
38
+ // Identification. `VERSION` is the value the CLI reports and the
39
+ // X-Powered-By HTTP header surfaces.
40
+ export { VERSION, NAME } from './version';
41
+ /**
42
+ * The exact Chart.js + plugin versions bundled into the rendering
43
+ * page. Frozen as a reference table so callers can expose "what's
44
+ * inside this chartjs2img?" to their own users without parsing
45
+ * `chartjs2img llm`.
46
+ */
47
+ export { LIBS as BUNDLED_LIBS } from './template';
48
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,gEAAgE;AAChE,uEAAuE;AACvE,mEAAmE;AACnE,qEAAqE;AACrE,iEAAiE;AACjE,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAM/E,oEAAoE;AACpE,4DAA4D;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAErC,iEAAiE;AACjE,qCAAqC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC;;;;;GAKG;AACH,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,76 @@
1
+ import { type RenderOptions } from './template';
2
+ export interface ConsoleMessage {
3
+ level: 'error' | 'warn' | 'info' | 'log';
4
+ message: string;
5
+ }
6
+ export interface RenderResult {
7
+ buffer: Buffer;
8
+ hash: string;
9
+ contentType: string;
10
+ cached: boolean;
11
+ /** Console messages (errors/warnings) from Chart.js during rendering */
12
+ messages: ConsoleMessage[];
13
+ }
14
+ export interface RendererConfig {
15
+ /** Max simultaneous renders. Defaults to CONCURRENCY env or 8. */
16
+ maxConcurrency?: number;
17
+ /**
18
+ * Hard upper bound on a single render (applied to page.goto and
19
+ * page.waitForFunction). Defaults to MAX_RENDER_TIME_SECONDS env or
20
+ * 30s. Chart rendering itself is sub-second; 30s accommodates slow
21
+ * CDN fetches of Chart.js + plugins on cold start.
22
+ */
23
+ maxRenderTimeMs?: number;
24
+ /**
25
+ * Safety-net timeout for force-closing a page if the render flow
26
+ * somehow never reaches its finally block. This is a LAST-RESORT
27
+ * leak guard, not a render budget — the per-render timeout above is
28
+ * what you want to tune for slow environments.
29
+ *
30
+ * Defaults to `maxRenderTimeMs * 2 + 10s`, which leaves room for
31
+ * both goto and waitForFunction to fail with their own timeout and
32
+ * still have the finally block clean up before this fires. Can be
33
+ * overridden via PAGE_TIMEOUT_SECONDS env for legacy operators.
34
+ */
35
+ pageSafetyNetMs?: number;
36
+ }
37
+ export interface RendererStats {
38
+ browserConnected: boolean;
39
+ concurrency: {
40
+ max: number;
41
+ active: number;
42
+ pending: number;
43
+ };
44
+ activePages: number;
45
+ /** Rendering-budget timeout (goto + waitForFunction) in seconds. */
46
+ maxRenderTimeSeconds: number;
47
+ /** Last-resort page force-close timer in seconds. Always > maxRenderTimeSeconds. */
48
+ pageSafetyNetSeconds: number;
49
+ /**
50
+ * @deprecated alias of pageSafetyNetSeconds for /health consumers
51
+ * that shipped before the field was renamed. Will be removed.
52
+ */
53
+ pageTimeoutSeconds: number;
54
+ }
55
+ export declare class Renderer {
56
+ private readonly maxConcurrency;
57
+ private readonly maxRenderTimeMs;
58
+ private readonly pageSafetyNetMs;
59
+ private readonly semaphore;
60
+ private browser;
61
+ private launching;
62
+ private launchPromise;
63
+ private readonly activePages;
64
+ constructor(config?: RendererConfig);
65
+ private launchBrowser;
66
+ private ensureBrowser;
67
+ private schedulePageCleanup;
68
+ private clearPageCleanup;
69
+ render(options: RenderOptions): Promise<RenderResult>;
70
+ close(): Promise<void>;
71
+ stats(): RendererStats;
72
+ }
73
+ export declare function renderChart(options: RenderOptions): Promise<RenderResult>;
74
+ export declare function closeBrowser(): Promise<void>;
75
+ export declare function rendererStats(): RendererStats;
76
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAaA,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AAS1D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;IACxC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,OAAO,CAAA;IACf,wEAAwE;IACxE,QAAQ,EAAE,cAAc,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7D,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,oBAAoB,EAAE,MAAM,CAAA;IAC5B,oFAAoF;IACpF,oBAAoB,EAAE,MAAM,CAAA;IAC5B;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AA+BD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IAErC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAgC;IAKrD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;gBAElD,MAAM,GAAE,cAAmB;YASzB,aAAa;YAmBb,aAAa;IA6B3B,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,gBAAgB;IAUlB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA2GrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B,KAAK,IAAI,aAAa;CAWvB;AAaD,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAE/E;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAKlD;AAED,wBAAgB,aAAa,IAAI,aAAa,CAa7C"}