@hed-hog/core 0.0.400 → 0.0.401
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/dist/ai/ai.controller.d.ts +2 -0
- package/dist/ai/ai.controller.d.ts.map +1 -1
- package/dist/ai/ai.service.d.ts +86 -2
- package/dist/ai/ai.service.d.ts.map +1 -1
- package/dist/ai/ai.service.js +304 -23
- package/dist/ai/ai.service.js.map +1 -1
- package/dist/ai-instruction/ai-prompt-resolver.service.d.ts +12 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.d.ts.map +1 -1
- package/dist/ai-instruction/ai-prompt-resolver.service.js +26 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.js.map +1 -1
- package/dist/core.module.d.ts.map +1 -1
- package/dist/core.module.js +3 -0
- package/dist/core.module.js.map +1 -1
- package/dist/document-kit/document-kit.module.d.ts +3 -0
- package/dist/document-kit/document-kit.module.d.ts.map +1 -0
- package/dist/document-kit/document-kit.module.js +24 -0
- package/dist/document-kit/document-kit.module.js.map +1 -0
- package/dist/document-kit/document-kit.registry.d.ts +55 -0
- package/dist/document-kit/document-kit.registry.d.ts.map +1 -0
- package/dist/document-kit/document-kit.registry.js +91 -0
- package/dist/document-kit/document-kit.registry.js.map +1 -0
- package/dist/document-kit/document-kit.service.d.ts +49 -0
- package/dist/document-kit/document-kit.service.d.ts.map +1 -0
- package/dist/document-kit/document-kit.service.js +135 -0
- package/dist/document-kit/document-kit.service.js.map +1 -0
- package/dist/file/file.service.d.ts +15 -1
- package/dist/file/file.service.d.ts.map +1 -1
- package/dist/file/file.service.js +52 -24
- package/dist/file/file.service.js.map +1 -1
- package/dist/file/mcp-file-source.schema.d.ts.map +1 -1
- package/dist/file/mcp-file-source.schema.js +8 -5
- package/dist/file/mcp-file-source.schema.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.secrets.js +21 -0
- package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
- package/dist/integration-profile/testers/ai.testers.d.ts.map +1 -1
- package/dist/integration-profile/testers/ai.testers.js +46 -8
- package/dist/integration-profile/testers/ai.testers.js.map +1 -1
- package/dist/mcp/mcp.module.d.ts.map +1 -1
- package/dist/mcp/mcp.module.js +2 -0
- package/dist/mcp/mcp.module.js.map +1 -1
- package/dist/mcp/tools/core-access-log.mcp-tools.d.ts +17 -0
- package/dist/mcp/tools/core-access-log.mcp-tools.d.ts.map +1 -0
- package/dist/mcp/tools/core-access-log.mcp-tools.js +74 -0
- package/dist/mcp/tools/core-access-log.mcp-tools.js.map +1 -0
- package/dist/mcp/tools/core-files.mcp-tools.js +4 -4
- package/dist/mcp/tools/core-files.mcp-tools.js.map +1 -1
- package/dist/meeting/meeting-provider.registry.d.ts +72 -0
- package/dist/meeting/meeting-provider.registry.d.ts.map +1 -1
- package/dist/meeting/meeting-provider.registry.js.map +1 -1
- package/dist/oauth/oauth-token-broker.service.d.ts +50 -1
- package/dist/oauth/oauth-token-broker.service.d.ts.map +1 -1
- package/dist/oauth/oauth-token-broker.service.js +105 -3
- package/dist/oauth/oauth-token-broker.service.js.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.d.ts +6 -0
- package/dist/oauth/providers/microsoft-entra-id.provider.d.ts.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.js +30 -4
- package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
- package/dist/pdf/document/charts/chart-bar.d.ts +24 -0
- package/dist/pdf/document/charts/chart-bar.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-bar.js +117 -0
- package/dist/pdf/document/charts/chart-bar.js.map +1 -0
- package/dist/pdf/document/charts/chart-donut.d.ts +16 -0
- package/dist/pdf/document/charts/chart-donut.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-donut.js +89 -0
- package/dist/pdf/document/charts/chart-donut.js.map +1 -0
- package/dist/pdf/document/charts/chart-gauge.d.ts +15 -0
- package/dist/pdf/document/charts/chart-gauge.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-gauge.js +60 -0
- package/dist/pdf/document/charts/chart-gauge.js.map +1 -0
- package/dist/pdf/document/charts/chart-line.d.ts +29 -0
- package/dist/pdf/document/charts/chart-line.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-line.js +89 -0
- package/dist/pdf/document/charts/chart-line.js.map +1 -0
- package/dist/pdf/document/charts/chart-primitives.d.ts +64 -0
- package/dist/pdf/document/charts/chart-primitives.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-primitives.js +110 -0
- package/dist/pdf/document/charts/chart-primitives.js.map +1 -0
- package/dist/pdf/document/charts/chart-radar.d.ts +13 -0
- package/dist/pdf/document/charts/chart-radar.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-radar.js +83 -0
- package/dist/pdf/document/charts/chart-radar.js.map +1 -0
- package/dist/pdf/document/charts/chart-scale.d.ts +39 -0
- package/dist/pdf/document/charts/chart-scale.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-scale.js +118 -0
- package/dist/pdf/document/charts/chart-scale.js.map +1 -0
- package/dist/pdf/document/charts/index.d.ts +8 -0
- package/dist/pdf/document/charts/index.d.ts.map +1 -0
- package/dist/pdf/document/charts/index.js +24 -0
- package/dist/pdf/document/charts/index.js.map +1 -0
- package/dist/pdf/document/index.d.ts +8 -0
- package/dist/pdf/document/index.d.ts.map +1 -0
- package/dist/pdf/document/index.js +24 -0
- package/dist/pdf/document/index.js.map +1 -0
- package/dist/pdf/document/pdf-document.chrome.d.ts +20 -0
- package/dist/pdf/document/pdf-document.chrome.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.chrome.js +36 -0
- package/dist/pdf/document/pdf-document.chrome.js.map +1 -0
- package/dist/pdf/document/pdf-document.css.d.ts +20 -0
- package/dist/pdf/document/pdf-document.css.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.css.js +239 -0
- package/dist/pdf/document/pdf-document.css.js.map +1 -0
- package/dist/pdf/document/pdf-document.renderer.d.ts +10 -0
- package/dist/pdf/document/pdf-document.renderer.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.renderer.js +153 -0
- package/dist/pdf/document/pdf-document.renderer.js.map +1 -0
- package/dist/pdf/document/pdf-document.service.d.ts +27 -0
- package/dist/pdf/document/pdf-document.service.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.service.js +81 -0
- package/dist/pdf/document/pdf-document.service.js.map +1 -0
- package/dist/pdf/document/pdf-document.theme.d.ts +41 -0
- package/dist/pdf/document/pdf-document.theme.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.theme.js +105 -0
- package/dist/pdf/document/pdf-document.theme.js.map +1 -0
- package/dist/pdf/document/pdf-document.types.d.ts +108 -0
- package/dist/pdf/document/pdf-document.types.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.types.js +18 -0
- package/dist/pdf/document/pdf-document.types.js.map +1 -0
- package/dist/pdf/pdf.module.d.ts.map +1 -1
- package/dist/pdf/pdf.module.js +3 -2
- package/dist/pdf/pdf.module.js.map +1 -1
- package/dist/pdf/pdf.service.d.ts +69 -1
- package/dist/pdf/pdf.service.d.ts.map +1 -1
- package/dist/pdf/pdf.service.js +164 -63
- package/dist/pdf/pdf.service.js.map +1 -1
- package/dist/pdf/templates/commercial-proposal.template.d.ts +96 -0
- package/dist/pdf/templates/commercial-proposal.template.d.ts.map +1 -0
- package/dist/pdf/templates/commercial-proposal.template.js +276 -0
- package/dist/pdf/templates/commercial-proposal.template.js.map +1 -0
- package/dist/setting/favicon.controller.d.ts +26 -0
- package/dist/setting/favicon.controller.d.ts.map +1 -0
- package/dist/setting/favicon.controller.js +130 -0
- package/dist/setting/favicon.controller.js.map +1 -0
- package/dist/setting/setting.module.d.ts.map +1 -1
- package/dist/setting/setting.module.js +2 -1
- package/dist/setting/setting.module.js.map +1 -1
- package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -1
- package/dist/whatsapp-sender/whatsapp-sender.service.js +25 -2
- package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -1
- package/hedhog/data/integration_type.yaml +6 -0
- package/hedhog/data/route.yaml +8 -0
- package/hedhog/data/setting_group.yaml +52 -0
- package/hedhog/frontend/messages/en.json +54 -1
- package/hedhog/frontend/messages/pt.json +54 -1
- package/package.json +4 -4
- package/src/ai/ai-attachment.fragments.spec.ts +56 -3
- package/src/ai/ai.service.responses.spec.ts +429 -0
- package/src/ai/ai.service.ts +409 -27
- package/src/ai-instruction/ai-prompt-resolver.service.spec.ts +44 -0
- package/src/ai-instruction/ai-prompt-resolver.service.ts +29 -0
- package/src/core.module.ts +3 -0
- package/src/document-kit/document-kit.module.ts +12 -0
- package/src/document-kit/document-kit.registry.ts +125 -0
- package/src/document-kit/document-kit.service.spec.ts +156 -0
- package/src/document-kit/document-kit.service.ts +173 -0
- package/src/file/file.service.spec.ts +168 -1
- package/src/file/file.service.ts +72 -34
- package/src/file/mcp-file-source.schema.ts +8 -5
- package/src/index.ts +5 -0
- package/src/integration-profile/integration-profile.secrets.ts +21 -0
- package/src/integration-profile/testers/ai.testers.ts +70 -5
- package/src/integration-profile/testers/remaining.testers.spec.ts +65 -1
- package/src/integration-profile/testers/tester-coverage.spec.ts +10 -0
- package/src/mcp/mcp.module.ts +2 -0
- package/src/mcp/tools/core-access-log.mcp-tools.ts +66 -0
- package/src/mcp/tools/core-files.mcp-tools.ts +4 -4
- package/src/meeting/meeting-provider.registry.ts +80 -0
- package/src/oauth/oauth-token-broker.service.spec.ts +108 -0
- package/src/oauth/oauth-token-broker.service.ts +129 -2
- package/src/oauth/providers/microsoft-entra-id.provider.spec.ts +133 -0
- package/src/oauth/providers/microsoft-entra-id.provider.ts +29 -2
- package/src/pdf/document/charts/chart-bar.ts +217 -0
- package/src/pdf/document/charts/chart-donut.ts +163 -0
- package/src/pdf/document/charts/chart-gauge.ts +94 -0
- package/src/pdf/document/charts/chart-line.ts +159 -0
- package/src/pdf/document/charts/chart-primitives.ts +188 -0
- package/src/pdf/document/charts/chart-radar.ts +136 -0
- package/src/pdf/document/charts/chart-scale.spec.ts +93 -0
- package/src/pdf/document/charts/chart-scale.ts +141 -0
- package/src/pdf/document/charts/charts.spec.ts +157 -0
- package/src/pdf/document/charts/index.ts +7 -0
- package/src/pdf/document/index.ts +7 -0
- package/src/pdf/document/pdf-document.chrome.ts +38 -0
- package/src/pdf/document/pdf-document.css.ts +238 -0
- package/src/pdf/document/pdf-document.renderer.spec.ts +129 -0
- package/src/pdf/document/pdf-document.renderer.ts +215 -0
- package/src/pdf/document/pdf-document.service.ts +77 -0
- package/src/pdf/document/pdf-document.theme.ts +146 -0
- package/src/pdf/document/pdf-document.types.ts +97 -0
- package/src/pdf/pdf.module.ts +3 -2
- package/src/pdf/pdf.service.spec.ts +131 -0
- package/src/pdf/pdf.service.ts +245 -82
- package/src/pdf/templates/commercial-proposal.template.spec.ts +177 -0
- package/src/pdf/templates/commercial-proposal.template.ts +400 -0
- package/src/setting/favicon.controller.spec.ts +92 -0
- package/src/setting/favicon.controller.ts +135 -0
- package/src/setting/setting.module.ts +2 -1
- package/src/whatsapp-sender/whatsapp-sender.service.spec.ts +73 -0
- package/src/whatsapp-sender/whatsapp-sender.service.ts +32 -2
|
@@ -2,6 +2,7 @@ import { ConfigService } from '@nestjs/config';
|
|
|
2
2
|
import { BrandAssetService } from '../setting/brand-asset.service';
|
|
3
3
|
import { SettingService } from '../setting/setting.service';
|
|
4
4
|
import { PdfAreaType, PdfThemeConfig } from './interfaces/pdf-theme-config.interface';
|
|
5
|
+
import { CommercialDocumentTheme, CommercialProposalData } from './templates/commercial-proposal.template';
|
|
5
6
|
export interface PdfGenerateOptions {
|
|
6
7
|
format?: 'A4' | 'A3' | 'Letter';
|
|
7
8
|
margin?: {
|
|
@@ -16,12 +17,48 @@ export interface PdfGenerateOptions {
|
|
|
16
17
|
width?: string;
|
|
17
18
|
/** Explicit CSS page size (e.g. '1131px'). Takes precedence over `format`/`landscape` when set. */
|
|
18
19
|
height?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Turns on Chromium's own per-page header and footer. This is the only way to
|
|
22
|
+
* get a repeating accent bar and a real page number: `counter(page)` resolves
|
|
23
|
+
* to nothing outside `@page` margin boxes, so a footer rendered as flow
|
|
24
|
+
* content (like `pdfFooter()` in ./components) prints an empty page slot.
|
|
25
|
+
*
|
|
26
|
+
* The templates are mini-documents, not part of the page: they start at
|
|
27
|
+
* `font-size: 0`, need their own `print-color-adjust: exact` to keep
|
|
28
|
+
* backgrounds, and only `<span class="pageNumber">` / `<span class="totalPages">`
|
|
29
|
+
* get substituted. Keep `margin.top`/`margin.bottom` larger than the templates,
|
|
30
|
+
* or the page content prints over them.
|
|
31
|
+
*/
|
|
32
|
+
displayHeaderFooter?: boolean;
|
|
33
|
+
headerTemplate?: string;
|
|
34
|
+
footerTemplate?: string;
|
|
35
|
+
/** `page.setContent` wait condition. Defaults to 'networkidle'. */
|
|
36
|
+
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit';
|
|
37
|
+
/** Ceiling for `page.setContent`, in ms. Defaults to Playwright's own (30s). */
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
scale?: number;
|
|
40
|
+
pageRanges?: string;
|
|
41
|
+
/** Short identifier for the logs when a render fails or the queue saturates. */
|
|
42
|
+
label?: string;
|
|
19
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Builds the object handed to `page.pdf()`.
|
|
46
|
+
*
|
|
47
|
+
* Assembled key by key on purpose: a caller that passes none of the optional
|
|
48
|
+
* fields has to get exactly the object `page.pdf()` received before they
|
|
49
|
+
* existed — Chromium changes behaviour on the mere presence of some of them
|
|
50
|
+
* (`displayHeaderFooter` with a single template filled in brings back its own
|
|
51
|
+
* URL/date footer).
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildPdfPageOptions(options: PdfGenerateOptions): Record<string, unknown>;
|
|
20
54
|
export declare class PdfService {
|
|
21
55
|
private readonly settingService;
|
|
22
56
|
private readonly brandAsset;
|
|
23
57
|
private readonly configService;
|
|
24
58
|
private readonly logger;
|
|
59
|
+
/** Renders holding a Chromium right now, and the ones waiting for a slot. */
|
|
60
|
+
private activeRenders;
|
|
61
|
+
private readonly renderQueue;
|
|
25
62
|
constructor(settingService: SettingService, brandAsset: BrandAssetService, configService: ConfigService);
|
|
26
63
|
/**
|
|
27
64
|
* Resolves the active PdfThemeConfig for the given area.
|
|
@@ -30,11 +67,42 @@ export declare class PdfService {
|
|
|
30
67
|
*/
|
|
31
68
|
loadThemeConfig(area?: PdfAreaType): Promise<PdfThemeConfig>;
|
|
32
69
|
/**
|
|
33
|
-
*
|
|
70
|
+
* Theme for commercial documents (proposals and the like): the area theme
|
|
71
|
+
* plus the legal footer, partner line and font stacks of the `pdf` group.
|
|
72
|
+
* The logo is embedded as a data URI so the render does not depend on the
|
|
73
|
+
* API reaching its own public URL.
|
|
74
|
+
*/
|
|
75
|
+
loadCommercialDocumentTheme(area?: PdfAreaType): Promise<CommercialDocumentTheme>;
|
|
76
|
+
/**
|
|
77
|
+
* Renders a commercial proposal with the installation's branding. Returns
|
|
78
|
+
* the HTML too, so the caller can keep the exact source of what was printed.
|
|
79
|
+
*/
|
|
80
|
+
renderCommercialProposal(data: CommercialProposalData, area?: PdfAreaType): Promise<{
|
|
81
|
+
html: string;
|
|
82
|
+
buffer: Buffer;
|
|
83
|
+
}>;
|
|
84
|
+
private get maxConcurrency();
|
|
85
|
+
private get queueWaitMs();
|
|
86
|
+
/**
|
|
87
|
+
* Every render launches a Chromium of its own, which costs a few hundred MB.
|
|
88
|
+
* The API pod is capped well below what a burst of simultaneous report
|
|
89
|
+
* downloads would ask for, and an OOM kill takes the whole API down — not
|
|
90
|
+
* just the PDF. So renders queue, and a queue that waits too long answers a
|
|
91
|
+
* retryable 503 instead of dragging the process down with it.
|
|
92
|
+
*/
|
|
93
|
+
private acquireRenderSlot;
|
|
94
|
+
private releaseRenderSlot;
|
|
95
|
+
/**
|
|
96
|
+
* Opens a Chromium page with the HTML loaded and hands it to `run`, taking
|
|
97
|
+
* care of the slot, the viewport and the teardown.
|
|
34
98
|
*
|
|
35
99
|
* Uses dynamic `import()` via `new Function` to remain compatible with
|
|
36
100
|
* CommonJS bundle output (same pattern as operations.service.ts).
|
|
37
101
|
*/
|
|
102
|
+
private renderWithChromium;
|
|
103
|
+
/**
|
|
104
|
+
* Renders an HTML string to a PDF buffer using Playwright/Chromium.
|
|
105
|
+
*/
|
|
38
106
|
generatePdfFromHtml(html: string, options?: PdfGenerateOptions): Promise<Buffer>;
|
|
39
107
|
/**
|
|
40
108
|
* Renders an HTML string to a PNG image buffer via a Playwright/Chromium
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf.service.d.ts","sourceRoot":"","sources":["../../src/pdf/pdf.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pdf.service.d.ts","sourceRoot":"","sources":["../../src/pdf/pdf.service.ts"],"names":[],"mappings":"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"}
|
package/dist/pdf/pdf.service.js
CHANGED
|
@@ -14,10 +14,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
14
14
|
var PdfService_1;
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.PdfService = void 0;
|
|
17
|
+
exports.buildPdfPageOptions = buildPdfPageOptions;
|
|
17
18
|
const common_1 = require("@nestjs/common");
|
|
18
19
|
const config_1 = require("@nestjs/config");
|
|
19
20
|
const brand_asset_service_1 = require("../setting/brand-asset.service");
|
|
20
21
|
const setting_service_1 = require("../setting/setting.service");
|
|
22
|
+
const commercial_proposal_template_1 = require("./templates/commercial-proposal.template");
|
|
21
23
|
const hcode_institutional_template_1 = require("./templates/hcode-institutional.template");
|
|
22
24
|
const hcode_theme_1 = require("./themes/hcode.theme");
|
|
23
25
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -30,6 +32,50 @@ function parsePxSize(value, fallback) {
|
|
|
30
32
|
const match = /^([\d.]+)px$/.exec(value.trim());
|
|
31
33
|
return match ? Math.round(Number(match[1])) : fallback;
|
|
32
34
|
}
|
|
35
|
+
const ZERO_MARGIN = { top: '0', right: '0', bottom: '0', left: '0' };
|
|
36
|
+
/**
|
|
37
|
+
* With `displayHeaderFooter` on, a template left undefined makes Chromium fall
|
|
38
|
+
* back to its own — the page URL and the print date. The unused slot gets
|
|
39
|
+
* something deliberately empty instead.
|
|
40
|
+
*/
|
|
41
|
+
const EMPTY_TEMPLATE = '<span></span>';
|
|
42
|
+
const DEFAULT_MAX_CONCURRENCY = 2;
|
|
43
|
+
const DEFAULT_QUEUE_WAIT_MS = 30000;
|
|
44
|
+
/**
|
|
45
|
+
* Builds the object handed to `page.pdf()`.
|
|
46
|
+
*
|
|
47
|
+
* Assembled key by key on purpose: a caller that passes none of the optional
|
|
48
|
+
* fields has to get exactly the object `page.pdf()` received before they
|
|
49
|
+
* existed — Chromium changes behaviour on the mere presence of some of them
|
|
50
|
+
* (`displayHeaderFooter` with a single template filled in brings back its own
|
|
51
|
+
* URL/date footer).
|
|
52
|
+
*/
|
|
53
|
+
function buildPdfPageOptions(options) {
|
|
54
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
55
|
+
const pdfOptions = options.width && options.height
|
|
56
|
+
? {
|
|
57
|
+
width: options.width,
|
|
58
|
+
height: options.height,
|
|
59
|
+
printBackground: (_a = options.printBackground) !== null && _a !== void 0 ? _a : true,
|
|
60
|
+
margin: (_b = options.margin) !== null && _b !== void 0 ? _b : ZERO_MARGIN,
|
|
61
|
+
}
|
|
62
|
+
: {
|
|
63
|
+
format: (_c = options.format) !== null && _c !== void 0 ? _c : 'A4',
|
|
64
|
+
printBackground: (_d = options.printBackground) !== null && _d !== void 0 ? _d : true,
|
|
65
|
+
landscape: (_e = options.landscape) !== null && _e !== void 0 ? _e : false,
|
|
66
|
+
margin: (_f = options.margin) !== null && _f !== void 0 ? _f : ZERO_MARGIN,
|
|
67
|
+
};
|
|
68
|
+
if (options.displayHeaderFooter) {
|
|
69
|
+
pdfOptions.displayHeaderFooter = true;
|
|
70
|
+
pdfOptions.headerTemplate = (_g = options.headerTemplate) !== null && _g !== void 0 ? _g : EMPTY_TEMPLATE;
|
|
71
|
+
pdfOptions.footerTemplate = (_h = options.footerTemplate) !== null && _h !== void 0 ? _h : EMPTY_TEMPLATE;
|
|
72
|
+
}
|
|
73
|
+
if (options.scale !== undefined)
|
|
74
|
+
pdfOptions.scale = options.scale;
|
|
75
|
+
if (options.pageRanges)
|
|
76
|
+
pdfOptions.pageRanges = options.pageRanges;
|
|
77
|
+
return pdfOptions;
|
|
78
|
+
}
|
|
33
79
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
34
80
|
// Service
|
|
35
81
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -39,6 +85,9 @@ let PdfService = PdfService_1 = class PdfService {
|
|
|
39
85
|
this.brandAsset = brandAsset;
|
|
40
86
|
this.configService = configService;
|
|
41
87
|
this.logger = new common_1.Logger(PdfService_1.name);
|
|
88
|
+
/** Renders holding a Chromium right now, and the ones waiting for a slot. */
|
|
89
|
+
this.activeRenders = 0;
|
|
90
|
+
this.renderQueue = [];
|
|
42
91
|
}
|
|
43
92
|
// ── Theme config ─────────────────────────────────────────────────────────
|
|
44
93
|
/**
|
|
@@ -99,15 +148,107 @@ let PdfService = PdfService_1 = class PdfService {
|
|
|
99
148
|
};
|
|
100
149
|
}
|
|
101
150
|
}
|
|
102
|
-
// ── HTML → PDF ────────────────────────────────────────────────────────────
|
|
103
151
|
/**
|
|
104
|
-
*
|
|
152
|
+
* Theme for commercial documents (proposals and the like): the area theme
|
|
153
|
+
* plus the legal footer, partner line and font stacks of the `pdf` group.
|
|
154
|
+
* The logo is embedded as a data URI so the render does not depend on the
|
|
155
|
+
* API reaching its own public URL.
|
|
156
|
+
*/
|
|
157
|
+
async loadCommercialDocumentTheme(area = 'training') {
|
|
158
|
+
var _a, _b, _c, _d, _e;
|
|
159
|
+
const base = await this.loadThemeConfig(area);
|
|
160
|
+
let values = {};
|
|
161
|
+
try {
|
|
162
|
+
values = await this.settingService.getSettingValues([
|
|
163
|
+
'pdf-legal-footer',
|
|
164
|
+
'pdf-partner-line',
|
|
165
|
+
'pdf-font-family',
|
|
166
|
+
'pdf-font-mono',
|
|
167
|
+
]);
|
|
168
|
+
}
|
|
169
|
+
catch (_f) {
|
|
170
|
+
this.logger.warn('Could not load commercial PDF settings – using defaults.');
|
|
171
|
+
}
|
|
172
|
+
const logoOverride = base.logoOverride
|
|
173
|
+
? ((_a = (await this.brandAsset.fetchAsDataUri(base.logoOverride))) !== null && _a !== void 0 ? _a : base.logoOverride)
|
|
174
|
+
: '';
|
|
175
|
+
return Object.assign(Object.assign({}, base), { logoOverride, legalFooter: String((_b = values['pdf-legal-footer']) !== null && _b !== void 0 ? _b : '').trim(), partnerLine: String((_c = values['pdf-partner-line']) !== null && _c !== void 0 ? _c : '').trim(), fontFamily: String((_d = values['pdf-font-family']) !== null && _d !== void 0 ? _d : '').trim() || "'Inter', sans-serif", fontMono: String((_e = values['pdf-font-mono']) !== null && _e !== void 0 ? _e : '').trim() || "'JetBrains Mono', monospace" });
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Renders a commercial proposal with the installation's branding. Returns
|
|
179
|
+
* the HTML too, so the caller can keep the exact source of what was printed.
|
|
180
|
+
*/
|
|
181
|
+
async renderCommercialProposal(data, area = 'training') {
|
|
182
|
+
const theme = await this.loadCommercialDocumentTheme(area);
|
|
183
|
+
const { html, pdfOptions } = (0, commercial_proposal_template_1.commercialProposalTemplate)(data, theme);
|
|
184
|
+
const buffer = await this.generatePdfFromHtml(html, pdfOptions);
|
|
185
|
+
return { html, buffer };
|
|
186
|
+
}
|
|
187
|
+
// ── Chromium runtime ──────────────────────────────────────────────────────
|
|
188
|
+
get maxConcurrency() {
|
|
189
|
+
const raw = Number(this.configService.get('PDF_MAX_CONCURRENCY'));
|
|
190
|
+
return Number.isFinite(raw) && raw >= 1 ? Math.floor(raw) : DEFAULT_MAX_CONCURRENCY;
|
|
191
|
+
}
|
|
192
|
+
get queueWaitMs() {
|
|
193
|
+
const raw = Number(this.configService.get('PDF_QUEUE_WAIT_MS'));
|
|
194
|
+
return Number.isFinite(raw) && raw >= 0 ? Math.floor(raw) : DEFAULT_QUEUE_WAIT_MS;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Every render launches a Chromium of its own, which costs a few hundred MB.
|
|
198
|
+
* The API pod is capped well below what a burst of simultaneous report
|
|
199
|
+
* downloads would ask for, and an OOM kill takes the whole API down — not
|
|
200
|
+
* just the PDF. So renders queue, and a queue that waits too long answers a
|
|
201
|
+
* retryable 503 instead of dragging the process down with it.
|
|
202
|
+
*/
|
|
203
|
+
async acquireRenderSlot(label) {
|
|
204
|
+
if (this.activeRenders < this.maxConcurrency) {
|
|
205
|
+
this.activeRenders += 1;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
await new Promise((resolve, reject) => {
|
|
209
|
+
const entry = {
|
|
210
|
+
resolve,
|
|
211
|
+
reject,
|
|
212
|
+
timer: setTimeout(() => {
|
|
213
|
+
const index = this.renderQueue.indexOf(entry);
|
|
214
|
+
if (index >= 0)
|
|
215
|
+
this.renderQueue.splice(index, 1);
|
|
216
|
+
this.logger.warn(`PDF render queue is saturated; gave up after ${this.queueWaitMs}ms${label ? ` (${label})` : ''}.`);
|
|
217
|
+
reject(new common_1.ServiceUnavailableException('The server is busy rendering other documents. Try again in a moment.'));
|
|
218
|
+
}, this.queueWaitMs),
|
|
219
|
+
};
|
|
220
|
+
this.renderQueue.push(entry);
|
|
221
|
+
});
|
|
222
|
+
// Resolved by releaseRenderSlot, which hands its slot over without
|
|
223
|
+
// decrementing — the counter already accounts for this render.
|
|
224
|
+
}
|
|
225
|
+
let released = false;
|
|
226
|
+
return () => {
|
|
227
|
+
if (released)
|
|
228
|
+
return;
|
|
229
|
+
released = true;
|
|
230
|
+
this.releaseRenderSlot();
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
releaseRenderSlot() {
|
|
234
|
+
const next = this.renderQueue.shift();
|
|
235
|
+
if (next) {
|
|
236
|
+
clearTimeout(next.timer);
|
|
237
|
+
next.resolve();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.activeRenders = Math.max(0, this.activeRenders - 1);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Opens a Chromium page with the HTML loaded and hands it to `run`, taking
|
|
244
|
+
* care of the slot, the viewport and the teardown.
|
|
105
245
|
*
|
|
106
246
|
* Uses dynamic `import()` via `new Function` to remain compatible with
|
|
107
247
|
* CommonJS bundle output (same pattern as operations.service.ts).
|
|
108
248
|
*/
|
|
109
|
-
async
|
|
110
|
-
var _a, _b
|
|
249
|
+
async renderWithChromium(kind, html, options, run) {
|
|
250
|
+
var _a, _b;
|
|
251
|
+
const release = await this.acquireRenderSlot(options.label);
|
|
111
252
|
const executablePath = this.configService.get('CHROMIUM_EXECUTABLE_PATH');
|
|
112
253
|
const noSandbox = this.configService.get('CHROMIUM_NO_SANDBOX') === 'true';
|
|
113
254
|
const launchArgs = noSandbox
|
|
@@ -128,43 +269,39 @@ let PdfService = PdfService_1 = class PdfService {
|
|
|
128
269
|
width: parsePxSize(options.width, 794),
|
|
129
270
|
height: parsePxSize(options.height, 1123),
|
|
130
271
|
});
|
|
131
|
-
await page.setContent(html, { waitUntil: 'networkidle' });
|
|
132
|
-
|
|
133
|
-
? {
|
|
134
|
-
width: options.width,
|
|
135
|
-
height: options.height,
|
|
136
|
-
printBackground: (_a = options.printBackground) !== null && _a !== void 0 ? _a : true,
|
|
137
|
-
margin: (_b = options.margin) !== null && _b !== void 0 ? _b : { top: '0', right: '0', bottom: '0', left: '0' },
|
|
138
|
-
}
|
|
139
|
-
: {
|
|
140
|
-
format: (_c = options.format) !== null && _c !== void 0 ? _c : 'A4',
|
|
141
|
-
printBackground: (_d = options.printBackground) !== null && _d !== void 0 ? _d : true,
|
|
142
|
-
landscape: (_e = options.landscape) !== null && _e !== void 0 ? _e : false,
|
|
143
|
-
margin: (_f = options.margin) !== null && _f !== void 0 ? _f : { top: '0', right: '0', bottom: '0', left: '0' },
|
|
144
|
-
});
|
|
145
|
-
return Buffer.from(pdfBuffer);
|
|
272
|
+
await page.setContent(html, Object.assign({ waitUntil: (_a = options.waitUntil) !== null && _a !== void 0 ? _a : 'networkidle' }, (options.timeoutMs ? { timeout: options.timeoutMs } : {})));
|
|
273
|
+
return Buffer.from(await run(page));
|
|
146
274
|
}
|
|
147
275
|
catch (error) {
|
|
148
276
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
149
|
-
const errorStack = error instanceof Error ? ((
|
|
277
|
+
const errorStack = error instanceof Error ? ((_b = error.stack) !== null && _b !== void 0 ? _b : errorMessage) : String(error);
|
|
150
278
|
const missingRuntime = /Cannot find package ['"]playwright['"]|Cannot find module ['"]playwright['"]|Executable doesn't exist|browserType\.launch|Failed to launch|Please run the following command/i.test(errorMessage);
|
|
151
|
-
this.logger.error(
|
|
279
|
+
this.logger.error(`${kind} generation failed. ${errorMessage}`, errorStack);
|
|
152
280
|
if (missingRuntime) {
|
|
153
281
|
throw new common_1.InternalServerErrorException('Playwright runtime is not available. Run `pnpm --filter api run playwright:install` in the API environment.');
|
|
154
282
|
}
|
|
155
|
-
throw new common_1.InternalServerErrorException(
|
|
283
|
+
throw new common_1.InternalServerErrorException(`${kind} generation failed: ${errorMessage}`);
|
|
156
284
|
}
|
|
157
285
|
finally {
|
|
158
286
|
if (browser) {
|
|
159
287
|
try {
|
|
160
288
|
await browser.close();
|
|
161
289
|
}
|
|
162
|
-
catch (
|
|
290
|
+
catch (_c) {
|
|
163
291
|
// Ignore close errors
|
|
164
292
|
}
|
|
165
293
|
}
|
|
294
|
+
release();
|
|
166
295
|
}
|
|
167
296
|
}
|
|
297
|
+
// ── HTML → PDF ────────────────────────────────────────────────────────────
|
|
298
|
+
/**
|
|
299
|
+
* Renders an HTML string to a PDF buffer using Playwright/Chromium.
|
|
300
|
+
*/
|
|
301
|
+
async generatePdfFromHtml(html, options = {}) {
|
|
302
|
+
const pdfOptions = buildPdfPageOptions(options);
|
|
303
|
+
return this.renderWithChromium('PDF', html, options, (page) => page.pdf(pdfOptions));
|
|
304
|
+
}
|
|
168
305
|
// ── HTML → PNG image ──────────────────────────────────────────────────────
|
|
169
306
|
/**
|
|
170
307
|
* Renders an HTML string to a PNG image buffer via a Playwright/Chromium
|
|
@@ -174,48 +311,12 @@ let PdfService = PdfService_1 = class PdfService {
|
|
|
174
311
|
* certificate thumbnails on the web/app.
|
|
175
312
|
*/
|
|
176
313
|
async generateImageFromHtml(html, options = {}) {
|
|
177
|
-
var _a;
|
|
178
|
-
const executablePath = this.configService.get('CHROMIUM_EXECUTABLE_PATH');
|
|
179
|
-
const noSandbox = this.configService.get('CHROMIUM_NO_SANDBOX') === 'true';
|
|
180
|
-
const launchArgs = noSandbox
|
|
181
|
-
? ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
|
|
182
|
-
: [];
|
|
183
314
|
const width = parsePxSize(options.width, 794);
|
|
184
315
|
const height = parsePxSize(options.height, 1123);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
browser = await playwright.chromium.launch(Object.assign(Object.assign({ headless: true }, (executablePath ? { executablePath } : {})), { args: launchArgs }));
|
|
190
|
-
const page = await browser.newPage();
|
|
191
|
-
await page.setViewportSize({ width, height });
|
|
192
|
-
await page.setContent(html, { waitUntil: 'networkidle' });
|
|
193
|
-
const imageBuffer = await page.screenshot({
|
|
194
|
-
type: 'png',
|
|
195
|
-
clip: { x: 0, y: 0, width, height },
|
|
196
|
-
});
|
|
197
|
-
return Buffer.from(imageBuffer);
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
201
|
-
const errorStack = error instanceof Error ? ((_a = error.stack) !== null && _a !== void 0 ? _a : errorMessage) : String(error);
|
|
202
|
-
const missingRuntime = /Cannot find package ['"]playwright['"]|Cannot find module ['"]playwright['"]|Executable doesn't exist|browserType\.launch|Failed to launch|Please run the following command/i.test(errorMessage);
|
|
203
|
-
this.logger.error(`Image generation failed. ${errorMessage}`, errorStack);
|
|
204
|
-
if (missingRuntime) {
|
|
205
|
-
throw new common_1.InternalServerErrorException('Playwright runtime is not available. Run `pnpm --filter api run playwright:install` in the API environment.');
|
|
206
|
-
}
|
|
207
|
-
throw new common_1.InternalServerErrorException(`Image generation failed: ${errorMessage}`);
|
|
208
|
-
}
|
|
209
|
-
finally {
|
|
210
|
-
if (browser) {
|
|
211
|
-
try {
|
|
212
|
-
await browser.close();
|
|
213
|
-
}
|
|
214
|
-
catch (_b) {
|
|
215
|
-
// Ignore close errors
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
316
|
+
return this.renderWithChromium('Image', html, options, (page) => page.screenshot({
|
|
317
|
+
type: 'png',
|
|
318
|
+
clip: { x: 0, y: 0, width, height },
|
|
319
|
+
}));
|
|
219
320
|
}
|
|
220
321
|
// ── Template engine ───────────────────────────────────────────────────────
|
|
221
322
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf.service.js","sourceRoot":"","sources":["../../src/pdf/pdf.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"pdf.service.js","sourceRoot":"","sources":["../../src/pdf/pdf.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { PdfThemeConfig } from '../interfaces/pdf-theme-config.interface';
|
|
2
|
+
import type { PdfGenerateOptions } from '../pdf.service';
|
|
3
|
+
/**
|
|
4
|
+
* Branding for commercial documents: the area theme plus the lines that used to
|
|
5
|
+
* be hardcoded per company (legal footer, partner line) and the font stacks.
|
|
6
|
+
* Everything comes from the `pdf` setting group, so another installation
|
|
7
|
+
* changes the look without touching code.
|
|
8
|
+
*/
|
|
9
|
+
export interface CommercialDocumentTheme extends PdfThemeConfig {
|
|
10
|
+
/** Legal line repeated in the footer of every page (company, tax id, address). */
|
|
11
|
+
legalFooter: string;
|
|
12
|
+
/** Small line under the cover metadata (partners, certifications). */
|
|
13
|
+
partnerLine: string;
|
|
14
|
+
fontFamily: string;
|
|
15
|
+
fontMono: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Blocks a section is made of. Strings are escaped by the template; only
|
|
19
|
+
* `html` goes through as is, so the caller must hand it already sanitized.
|
|
20
|
+
*/
|
|
21
|
+
export type CommercialProposalBlock = {
|
|
22
|
+
type: 'html';
|
|
23
|
+
html: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'paragraphs';
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'list';
|
|
29
|
+
items: string[];
|
|
30
|
+
} | {
|
|
31
|
+
type: 'callout';
|
|
32
|
+
title?: string;
|
|
33
|
+
text: string;
|
|
34
|
+
tone?: 'accent' | 'neutral';
|
|
35
|
+
} | {
|
|
36
|
+
type: 'table';
|
|
37
|
+
headers: string[];
|
|
38
|
+
rows: string[][];
|
|
39
|
+
/** Per column; defaults to left. */
|
|
40
|
+
align?: Array<'left' | 'right'>;
|
|
41
|
+
} | {
|
|
42
|
+
type: 'totals';
|
|
43
|
+
rows: Array<{
|
|
44
|
+
label: string;
|
|
45
|
+
value: string;
|
|
46
|
+
emphasis?: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
};
|
|
49
|
+
export interface CommercialProposalSection {
|
|
50
|
+
/** Short uppercase label next to the number: `03 · INVESTIMENTO`. */
|
|
51
|
+
eyebrow: string;
|
|
52
|
+
/** Written as a short sentence, as the proposal standard asks. */
|
|
53
|
+
title: string;
|
|
54
|
+
blocks: CommercialProposalBlock[];
|
|
55
|
+
}
|
|
56
|
+
export interface CommercialProposalSignatory {
|
|
57
|
+
party: string;
|
|
58
|
+
name?: string;
|
|
59
|
+
role?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface CommercialProposalData {
|
|
62
|
+
locale?: string;
|
|
63
|
+
/** Mono line above the title: `PROPOSTA COMERCIAL · BRA20260865`. */
|
|
64
|
+
eyebrow: string;
|
|
65
|
+
title: string;
|
|
66
|
+
/** Second title line, printed in the accent color. */
|
|
67
|
+
titleAccent?: string;
|
|
68
|
+
subtitle?: string;
|
|
69
|
+
meta: Array<{
|
|
70
|
+
label: string;
|
|
71
|
+
value: string;
|
|
72
|
+
}>;
|
|
73
|
+
sections: CommercialProposalSection[];
|
|
74
|
+
signatureTitle?: string;
|
|
75
|
+
signatories?: CommercialProposalSignatory[];
|
|
76
|
+
/** Left side of the footer when no legal footer is configured. */
|
|
77
|
+
documentLabel?: string;
|
|
78
|
+
/** Word used between the page number and the total (`3 / 9`). */
|
|
79
|
+
pageSeparator?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface CommercialProposalRender {
|
|
82
|
+
html: string;
|
|
83
|
+
pdfOptions: PdfGenerateOptions;
|
|
84
|
+
}
|
|
85
|
+
export declare function escapePdfHtml(value: unknown): string;
|
|
86
|
+
/**
|
|
87
|
+
* Commercial proposal — cover with the metadata table, numbered sections
|
|
88
|
+
* (`01 · ESCOPO`), borderless tables, rounded cards and a footer with the
|
|
89
|
+
* legal line and `n / N` on every page.
|
|
90
|
+
*
|
|
91
|
+
* Pure function: the caller resolves the theme (see
|
|
92
|
+
* `PdfService.loadCommercialDocumentTheme`) and the data, so the same input
|
|
93
|
+
* always renders the same document.
|
|
94
|
+
*/
|
|
95
|
+
export declare function commercialProposalTemplate(data: CommercialProposalData, theme: CommercialDocumentTheme): CommercialProposalRender;
|
|
96
|
+
//# sourceMappingURL=commercial-proposal.template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commercial-proposal.template.d.ts","sourceRoot":"","sources":["../../../src/pdf/templates/commercial-proposal.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAOzD;;;;;GAKG;AACH,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC7D,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;CAAE,GAC9E;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IACjB,oCAAoC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;CACjC,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACnE,CAAC;AAEN,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,uBAAuB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,2BAA2B,EAAE,CAAC;IAC5C,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOpD;AAwFD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,sBAAsB,EAC5B,KAAK,EAAE,uBAAuB,GAC7B,wBAAwB,CA+M1B"}
|