@dsh-enhanced/plugin-control-plane 0.1.32 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +352 -4
- package/bin/dsh-local-release-adapter.js +80 -16
- package/bin/dsh-npm-registry-adapter.js +613 -0
- package/bin/dsh-source-adoption-authority.js +12 -0
- package/bin/dsh-source-approval-authority.js +16 -0
- package/bin/dsh-source-release-authority.js +12 -0
- package/bin/dsh-systemd-host-attestor.js +707 -0
- package/bin/dsh-task-observation-authority.js +15 -0
- package/lib/adapter-process.d.ts +23 -0
- package/lib/adapter-process.d.ts.map +1 -0
- package/lib/adapter-process.js +305 -0
- package/lib/adapter-process.js.map +1 -0
- package/lib/adoption-coordinator.d.ts +63 -0
- package/lib/adoption-coordinator.d.ts.map +1 -0
- package/lib/adoption-coordinator.js +241 -0
- package/lib/adoption-coordinator.js.map +1 -0
- package/lib/adoption-handoff.d.ts +16 -0
- package/lib/adoption-handoff.d.ts.map +1 -0
- package/lib/adoption-handoff.js +11 -0
- package/lib/adoption-handoff.js.map +1 -0
- package/lib/attestation.d.ts.map +1 -1
- package/lib/attestation.js +49 -1
- package/lib/attestation.js.map +1 -1
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +29 -2
- package/lib/catalog.js.map +1 -1
- package/lib/cli.d.ts +33 -9
- package/lib/cli.d.ts.map +1 -1
- package/lib/cli.js +624 -178
- package/lib/cli.js.map +1 -1
- package/lib/deployment-readiness.d.ts +38 -0
- package/lib/deployment-readiness.d.ts.map +1 -0
- package/lib/deployment-readiness.js +154 -0
- package/lib/deployment-readiness.js.map +1 -0
- package/lib/effect-blocked-replay.d.ts +81 -0
- package/lib/effect-blocked-replay.d.ts.map +1 -0
- package/lib/effect-blocked-replay.js +259 -0
- package/lib/effect-blocked-replay.js.map +1 -0
- package/lib/errors.d.ts +6 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +9 -0
- package/lib/errors.js.map +1 -0
- package/lib/foreground-deployment-runtime.d.ts +20 -0
- package/lib/foreground-deployment-runtime.d.ts.map +1 -0
- package/lib/foreground-deployment-runtime.js +79 -0
- package/lib/foreground-deployment-runtime.js.map +1 -0
- package/lib/foreground-deployment.d.ts +17 -0
- package/lib/foreground-deployment.d.ts.map +1 -0
- package/lib/foreground-deployment.js +43 -0
- package/lib/foreground-deployment.js.map +1 -0
- package/lib/host-attestor.d.ts +1 -1
- package/lib/host-attestor.d.ts.map +1 -1
- package/lib/host-attestor.js +51 -57
- package/lib/host-attestor.js.map +1 -1
- package/lib/index.d.ts +25 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -2
- package/lib/index.js.map +1 -1
- package/lib/npm-publish.d.ts +25 -0
- package/lib/npm-publish.d.ts.map +1 -0
- package/lib/npm-publish.js +280 -0
- package/lib/npm-publish.js.map +1 -0
- package/lib/owner-task-gap-types.d.ts +21 -0
- package/lib/owner-task-gap-types.d.ts.map +1 -0
- package/lib/owner-task-gap-types.js +2 -0
- package/lib/owner-task-gap-types.js.map +1 -0
- package/lib/owner-task-gaps.d.ts +24 -0
- package/lib/owner-task-gaps.d.ts.map +1 -0
- package/lib/owner-task-gaps.js +74 -0
- package/lib/owner-task-gaps.js.map +1 -0
- package/lib/post-activation.d.ts +33 -0
- package/lib/post-activation.d.ts.map +1 -0
- package/lib/post-activation.js +219 -0
- package/lib/post-activation.js.map +1 -0
- package/lib/registry-fetch.d.ts +50 -0
- package/lib/registry-fetch.d.ts.map +1 -0
- package/lib/registry-fetch.js +267 -0
- package/lib/registry-fetch.js.map +1 -0
- package/lib/release.d.ts +4 -4
- package/lib/release.d.ts.map +1 -1
- package/lib/release.js +142 -56
- package/lib/release.js.map +1 -1
- package/lib/replay-endpoint-protocol.d.ts +65 -0
- package/lib/replay-endpoint-protocol.d.ts.map +1 -0
- package/lib/replay-endpoint-protocol.js +183 -0
- package/lib/replay-endpoint-protocol.js.map +1 -0
- package/lib/replay-endpoint.d.ts +7 -0
- package/lib/replay-endpoint.d.ts.map +1 -0
- package/lib/replay-endpoint.js +193 -0
- package/lib/replay-endpoint.js.map +1 -0
- package/lib/replay-grant.d.ts +62 -0
- package/lib/replay-grant.d.ts.map +1 -0
- package/lib/replay-grant.js +208 -0
- package/lib/replay-grant.js.map +1 -0
- package/lib/replay-journal.d.ts +25 -0
- package/lib/replay-journal.d.ts.map +1 -0
- package/lib/replay-journal.js +275 -0
- package/lib/replay-journal.js.map +1 -0
- package/lib/runtime-observer-protocol.d.ts +63 -0
- package/lib/runtime-observer-protocol.d.ts.map +1 -0
- package/lib/runtime-observer-protocol.js +280 -0
- package/lib/runtime-observer-protocol.js.map +1 -0
- package/lib/runtime-observer.d.ts +8 -0
- package/lib/runtime-observer.d.ts.map +1 -0
- package/lib/runtime-observer.js +182 -0
- package/lib/runtime-observer.js.map +1 -0
- package/lib/service.d.ts +145 -1
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +734 -6
- package/lib/service.js.map +1 -1
- package/lib/source-adoption-authority.d.ts +65 -0
- package/lib/source-adoption-authority.d.ts.map +1 -0
- package/lib/source-adoption-authority.js +271 -0
- package/lib/source-adoption-authority.js.map +1 -0
- package/lib/source-adoption-runner.d.ts +28 -0
- package/lib/source-adoption-runner.d.ts.map +1 -0
- package/lib/source-adoption-runner.js +197 -0
- package/lib/source-adoption-runner.js.map +1 -0
- package/lib/source-approval-authority.d.ts +50 -0
- package/lib/source-approval-authority.d.ts.map +1 -0
- package/lib/source-approval-authority.js +412 -0
- package/lib/source-approval-authority.js.map +1 -0
- package/lib/source-approval-client.d.ts +32 -0
- package/lib/source-approval-client.d.ts.map +1 -0
- package/lib/source-approval-client.js +175 -0
- package/lib/source-approval-client.js.map +1 -0
- package/lib/source-build.d.ts +60 -0
- package/lib/source-build.d.ts.map +1 -0
- package/lib/source-build.js +311 -0
- package/lib/source-build.js.map +1 -0
- package/lib/source-context.d.ts +24 -0
- package/lib/source-context.d.ts.map +1 -0
- package/lib/source-context.js +99 -0
- package/lib/source-context.js.map +1 -0
- package/lib/source-job-types.d.ts +87 -0
- package/lib/source-job-types.d.ts.map +1 -0
- package/lib/source-job-types.js +2 -0
- package/lib/source-job-types.js.map +1 -0
- package/lib/source-jobs.d.ts +113 -0
- package/lib/source-jobs.d.ts.map +1 -0
- package/lib/source-jobs.js +535 -0
- package/lib/source-jobs.js.map +1 -0
- package/lib/source-release-authority.d.ts +35 -0
- package/lib/source-release-authority.d.ts.map +1 -0
- package/lib/source-release-authority.js +271 -0
- package/lib/source-release-authority.js.map +1 -0
- package/lib/source-release-client.d.ts +10 -0
- package/lib/source-release-client.d.ts.map +1 -0
- package/lib/source-release-client.js +24 -0
- package/lib/source-release-client.js.map +1 -0
- package/lib/source-release-runner.d.ts +31 -0
- package/lib/source-release-runner.d.ts.map +1 -0
- package/lib/source-release-runner.js +125 -0
- package/lib/source-release-runner.js.map +1 -0
- package/lib/source-versioning.d.ts +24 -0
- package/lib/source-versioning.d.ts.map +1 -0
- package/lib/source-versioning.js +213 -0
- package/lib/source-versioning.js.map +1 -0
- package/lib/source-workspace.d.ts +117 -0
- package/lib/source-workspace.d.ts.map +1 -0
- package/lib/source-workspace.js +458 -0
- package/lib/source-workspace.js.map +1 -0
- package/lib/sqlite.d.ts +1 -1
- package/lib/sqlite.d.ts.map +1 -1
- package/lib/sqlite.js +509 -7
- package/lib/sqlite.js.map +1 -1
- package/lib/store.d.ts +229 -6
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +2431 -383
- package/lib/store.js.map +1 -1
- package/lib/task-observation-authority.d.ts +29 -0
- package/lib/task-observation-authority.d.ts.map +1 -0
- package/lib/task-observation-authority.js +370 -0
- package/lib/task-observation-authority.js.map +1 -0
- package/lib/task-observation-client.d.ts +4 -0
- package/lib/task-observation-client.d.ts.map +1 -0
- package/lib/task-observation-client.js +20 -0
- package/lib/task-observation-client.js.map +1 -0
- package/lib/task-observation-runtime.d.ts +59 -0
- package/lib/task-observation-runtime.d.ts.map +1 -0
- package/lib/task-observation-runtime.js +331 -0
- package/lib/task-observation-runtime.js.map +1 -0
- package/lib/task-observation-store.d.ts +17 -0
- package/lib/task-observation-store.d.ts.map +1 -0
- package/lib/task-observation-store.js +115 -0
- package/lib/task-observation-store.js.map +1 -0
- package/lib/task-observation-types.d.ts +67 -0
- package/lib/task-observation-types.d.ts.map +1 -0
- package/lib/task-observation-types.js +2 -0
- package/lib/task-observation-types.js.map +1 -0
- package/lib/trust.d.ts +3 -0
- package/lib/trust.d.ts.map +1 -1
- package/lib/trust.js +0 -0
- package/lib/trust.js.map +1 -1
- package/lib/types.d.ts +275 -8
- package/lib/types.d.ts.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +40 -5
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { realpath } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, resolve } from 'node:path';
|
|
3
|
+
import { parseApprovalReceipt } from './approval.js';
|
|
4
|
+
import { ControlledProcessError, executeControlledProcess } from './adapter-process.js';
|
|
5
|
+
import { openTrustedExecutable, verifyOpenTrustedExecutable } from './trust.js';
|
|
6
|
+
const ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,159}$/u;
|
|
7
|
+
const DIGEST = /^[a-f0-9]{64}$/u;
|
|
8
|
+
const MAX_INPUT_BYTES = 8_192;
|
|
9
|
+
const MAX_OUTPUT_BYTES = 65_536;
|
|
10
|
+
export class SourceApprovalClientError extends Error {
|
|
11
|
+
code;
|
|
12
|
+
constructor(code, message) {
|
|
13
|
+
super(`plugin-control-plane source-approval-client[${code}]: ${message}`);
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.name = 'SourceApprovalClientError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function object(value, label) {
|
|
19
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
20
|
+
throw new SourceApprovalClientError('INVALID_CONFIG', `${label} must be an object`);
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function exactKeys(value, fields, label) {
|
|
24
|
+
if (Object.keys(value).sort().join(',') !== [...fields].sort().join(',')) {
|
|
25
|
+
throw new SourceApprovalClientError('INVALID_CONFIG', `${label} has unknown or missing fields`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function canonicalPath(value, label) {
|
|
29
|
+
if (typeof value !== 'string' || value.length === 0 || Buffer.byteLength(value) > 2_000
|
|
30
|
+
|| value.normalize('NFC') !== value || value.trim() !== value || [...value].some(character => {
|
|
31
|
+
const point = character.codePointAt(0);
|
|
32
|
+
return point <= 0x1f || point === 0x7f;
|
|
33
|
+
}) || !isAbsolute(value) || resolve(value) !== value) {
|
|
34
|
+
throw new SourceApprovalClientError('INVALID_CONFIG', `${label} must be an absolute canonical path`);
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
function sha256(value, label) {
|
|
39
|
+
if (typeof value !== 'string' || !DIGEST.test(value))
|
|
40
|
+
throw new SourceApprovalClientError('INVALID_CONFIG', `${label} must be a lowercase sha256 digest`);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
function executable(value, label) {
|
|
44
|
+
const item = object(value, label);
|
|
45
|
+
exactKeys(item, ['path', 'sha256'], label);
|
|
46
|
+
return Object.freeze({ path: canonicalPath(item.path, `${label}.path`), sha256: sha256(item.sha256, `${label}.sha256`) });
|
|
47
|
+
}
|
|
48
|
+
export function validateSourceApprovalClientConfig(value) {
|
|
49
|
+
const item = object(value, 'source approval client config');
|
|
50
|
+
const allowed = new Set(['executable', 'interpreter', 'configPath', 'timeoutMs']);
|
|
51
|
+
if (Object.keys(item).some(key => !allowed.has(key)) || !('executable' in item) || !('configPath' in item) || !('timeoutMs' in item)) {
|
|
52
|
+
throw new SourceApprovalClientError('INVALID_CONFIG', 'source approval client config has unknown or missing fields');
|
|
53
|
+
}
|
|
54
|
+
executable(item.executable, 'executable');
|
|
55
|
+
if (item.interpreter !== undefined)
|
|
56
|
+
executable(item.interpreter, 'interpreter');
|
|
57
|
+
canonicalPath(item.configPath, 'configPath');
|
|
58
|
+
if (!Number.isSafeInteger(item.timeoutMs) || Number(item.timeoutMs) < 1 || Number(item.timeoutMs) > 10_000) {
|
|
59
|
+
throw new SourceApprovalClientError('INVALID_CONFIG', 'timeoutMs must be an integer from 1 through 10000');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function assertRequest(value) {
|
|
63
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)
|
|
64
|
+
|| Object.keys(value).sort().join(',') !== ['planDigest', 'planId', 'protocol', 'sourceReferenceDigest'].join(',')) {
|
|
65
|
+
throw new SourceApprovalClientError('FAILED', 'source approval request is invalid');
|
|
66
|
+
}
|
|
67
|
+
const item = value;
|
|
68
|
+
if (!['dsh-source-approval/v1', 'dsh-source-release-authorization/v1', 'dsh-source-adoption/v1'].includes(String(item.protocol)) || typeof item.planId !== 'string' || typeof item.planDigest !== 'string'
|
|
69
|
+
|| typeof item.sourceReferenceDigest !== 'string' || !ID.test(item.planId)
|
|
70
|
+
|| !DIGEST.test(item.planDigest) || !DIGEST.test(item.sourceReferenceDigest)) {
|
|
71
|
+
throw new SourceApprovalClientError('FAILED', 'source approval request is invalid');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function assertNotAborted(signal) {
|
|
75
|
+
if (signal?.aborted)
|
|
76
|
+
throw new SourceApprovalClientError('ABORTED', 'source approval request was aborted');
|
|
77
|
+
}
|
|
78
|
+
async function execute(executable, interpreter, configPath, input, timeoutMs, signal) {
|
|
79
|
+
if (process.platform !== 'linux')
|
|
80
|
+
throw new SourceApprovalClientError('FAILED', 'descriptor-pinned source approval requires Linux');
|
|
81
|
+
try {
|
|
82
|
+
await realpath('/proc/self/fd');
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new SourceApprovalClientError('FAILED', 'descriptor-pinned source approval requires /proc/self/fd');
|
|
86
|
+
}
|
|
87
|
+
const command = interpreter === undefined ? '/proc/self/fd/3' : '/proc/self/fd/4';
|
|
88
|
+
const args = interpreter === undefined ? ['--config', configPath] : ['/proc/self/fd/3', '--config', configPath];
|
|
89
|
+
const stdio = ['pipe', 'pipe', 'ignore', executable.handle.fd];
|
|
90
|
+
if (interpreter !== undefined)
|
|
91
|
+
stdio.push(interpreter.handle.fd);
|
|
92
|
+
try {
|
|
93
|
+
return await executeControlledProcess({ command, args,
|
|
94
|
+
// The authority reads its own owner-private config. No caller
|
|
95
|
+
// environment, credentials, or model/provider settings cross this edge.
|
|
96
|
+
env: { LANG: 'C', LC_ALL: 'C', TZ: 'UTC', PATH: '/usr/bin:/bin' },
|
|
97
|
+
stdio, stdin: input, timeoutMs, maximumOutput: MAX_OUTPUT_BYTES, ...(signal ? { signal } : {}) });
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (!(error instanceof ControlledProcessError))
|
|
101
|
+
throw error;
|
|
102
|
+
if (error.code === 'ABORTED')
|
|
103
|
+
throw new SourceApprovalClientError('ABORTED', 'source authority request was aborted');
|
|
104
|
+
if (error.code === 'TIMEOUT')
|
|
105
|
+
throw new SourceApprovalClientError('TIMEOUT', 'source approval authority exceeded its deadline');
|
|
106
|
+
if (error.code === 'OUTPUT_LIMIT')
|
|
107
|
+
throw new SourceApprovalClientError('OUTPUT_LIMIT', 'source approval authority exceeded its output bound');
|
|
108
|
+
throw new SourceApprovalClientError('FAILED', error.code === 'NON_ZERO'
|
|
109
|
+
? 'source approval authority returned a non-zero status' : 'source approval authority could not be safely reclaimed');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Shared descriptor-pinned transport; protocol-specific wrappers validate the receipt.
|
|
113
|
+
export async function requestSourceAuthorityReceipt(config, request, parseReceipt, signal) {
|
|
114
|
+
assertRequest(request);
|
|
115
|
+
return requestPinnedAuthorityReceipt(config, request, parseReceipt, signal);
|
|
116
|
+
}
|
|
117
|
+
export async function requestPinnedAuthorityReceipt(config, request, parseReceipt, signal) {
|
|
118
|
+
validateSourceApprovalClientConfig(config);
|
|
119
|
+
assertNotAborted(signal);
|
|
120
|
+
const input = JSON.stringify(request);
|
|
121
|
+
if (Buffer.byteLength(input) > MAX_INPUT_BYTES)
|
|
122
|
+
throw new SourceApprovalClientError('FAILED', 'source approval request exceeds its input bound');
|
|
123
|
+
let executable;
|
|
124
|
+
let interpreter;
|
|
125
|
+
try {
|
|
126
|
+
executable = await openTrustedExecutable(config.executable.path, config.executable.sha256);
|
|
127
|
+
interpreter = config.interpreter === undefined ? undefined
|
|
128
|
+
: await openTrustedExecutable(config.interpreter.path, config.interpreter.sha256);
|
|
129
|
+
assertNotAborted(signal);
|
|
130
|
+
const output = await execute(executable, interpreter, config.configPath, input, config.timeoutMs, signal);
|
|
131
|
+
await verifyOpenTrustedExecutable(executable);
|
|
132
|
+
if (interpreter !== undefined)
|
|
133
|
+
await verifyOpenTrustedExecutable(interpreter);
|
|
134
|
+
assertNotAborted(signal);
|
|
135
|
+
let parsed;
|
|
136
|
+
try {
|
|
137
|
+
parsed = JSON.parse(output);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
throw new SourceApprovalClientError('FAILED', 'source approval authority did not return one JSON receipt');
|
|
141
|
+
}
|
|
142
|
+
return parseReceipt(parsed);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (error instanceof SourceApprovalClientError)
|
|
146
|
+
throw error;
|
|
147
|
+
throw new SourceApprovalClientError('EXECUTABLE_CHANGED', 'source approval executable descriptor identity could not be retained');
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
try {
|
|
151
|
+
await interpreter?.handle.close();
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
await executable?.handle.close();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export async function requestSourceApproval(config, request, signal) {
|
|
159
|
+
if (request?.protocol !== 'dsh-source-approval/v1')
|
|
160
|
+
throw new SourceApprovalClientError('FAILED', 'source approval request protocol is invalid');
|
|
161
|
+
return requestSourceAuthorityReceipt(config, request, parsed => {
|
|
162
|
+
let receipt;
|
|
163
|
+
try {
|
|
164
|
+
receipt = parseApprovalReceipt(parsed);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
throw new SourceApprovalClientError('FAILED', 'source approval authority returned an invalid approval receipt');
|
|
168
|
+
}
|
|
169
|
+
if (receipt.decision !== 'approved' || receipt.planId !== request.planId || receipt.planDigest !== request.planDigest) {
|
|
170
|
+
throw new SourceApprovalClientError('FAILED', 'source approval receipt is not an approval for this exact plan and digest');
|
|
171
|
+
}
|
|
172
|
+
return receipt;
|
|
173
|
+
}, signal);
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=source-approval-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-approval-client.js","sourceRoot":"","sources":["../src/source-approval-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { SourcePreparedEvidence } from './types.js';
|
|
2
|
+
export interface SourceBuildConfig {
|
|
3
|
+
/** Canonical owner-controlled docker client. */
|
|
4
|
+
dockerPath: string;
|
|
5
|
+
/** Image pinned by manifest reference or a local immutable image content ID. */
|
|
6
|
+
image: string;
|
|
7
|
+
timeoutMs: number;
|
|
8
|
+
memoryMiB: number;
|
|
9
|
+
cpus: number;
|
|
10
|
+
pidsLimit: number;
|
|
11
|
+
workspaceMiB: number;
|
|
12
|
+
outputBytes: number;
|
|
13
|
+
/** Host-owned package/runtime version bump before the checked tree is frozen. */
|
|
14
|
+
versioning?: 'patch';
|
|
15
|
+
/** Owner-only opt-in for the larger, full-repository check budget. */
|
|
16
|
+
profile?: 'standard' | 'repository';
|
|
17
|
+
/** Writable /tmp tmpfs size. Defaults to 32 MiB for standard, 2048 MiB for repository. */
|
|
18
|
+
temporaryMiB?: number;
|
|
19
|
+
/** Explicit owner opt-in for nested unprivileged sandboxes. Relaxes Docker's
|
|
20
|
+
* system-path masks, hides /sys, and requires the pinned seccomp/runtime. */
|
|
21
|
+
repositorySandbox?: {
|
|
22
|
+
seccompPath: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface SourceBuildResult {
|
|
26
|
+
treeDigest: string;
|
|
27
|
+
patchDigest: string;
|
|
28
|
+
checkedAt: number;
|
|
29
|
+
evidence: SourcePreparedEvidence;
|
|
30
|
+
}
|
|
31
|
+
/** Exact in-container command recorded in prepared source evidence. */
|
|
32
|
+
export declare const PREPARED_SOURCE_BUILD_SCRIPT = "set -eu; checked() { phase=\"$1\"; shift; if \"$@\" >\"/tmp/$phase.log\" 2>&1; then return 0; else code=$?; printf \"source build phase failed: %s\\n\" \"$phase\" >&2; tail -c 8192 \"/tmp/$phase.log\" >&2; return \"$code\"; fi; }; umask 077; mkdir -p /workspace; tar -x -C /workspace; cd /workspace; checked install pnpm install --offline --frozen-lockfile --ignore-scripts; checked check pnpm check; mkdir -p /workspace/.dsh-pack; cd \"$PLUGIN_ROOT\"; checked pack pnpm pack --pack-destination /workspace/.dsh-pack; set -- /workspace/.dsh-pack/*.tgz; test \"$#\" = 1; pack=\"$1\"; printf \"DSH_PREPARED_PACK\\t%s\\t%s\\t%s\\t%s\\t%s\\n\" \"${pack##*/}\" \"$(wc -c < \"$pack\" | tr -d \" \")\" \"$(sha256sum \"$pack\" | cut -d \" \" -f1)\" \"$(node --version)\" \"$(pnpm --version)\"";
|
|
33
|
+
export declare function validateSourceBuildConfig(config: SourceBuildConfig): void;
|
|
34
|
+
/**
|
|
35
|
+
* Archive an exact temporary-index tree into a disposable, mount-free Docker
|
|
36
|
+
* container. No repository, state directory, socket, credential, environment
|
|
37
|
+
* value, or Host path crosses the boundary: the sole input is tar on stdin.
|
|
38
|
+
*/
|
|
39
|
+
export declare function runDockerPreparedChecks(input: {
|
|
40
|
+
config: SourceBuildConfig;
|
|
41
|
+
worktree: string;
|
|
42
|
+
baseCommit: string;
|
|
43
|
+
name: string;
|
|
44
|
+
scope: readonly string[];
|
|
45
|
+
environment: NodeJS.ProcessEnv;
|
|
46
|
+
signal: AbortSignal;
|
|
47
|
+
assertCurrent: () => Promise<void>;
|
|
48
|
+
preparedAt: number;
|
|
49
|
+
/** Frozen before resource acquisition by the durable Host job. */
|
|
50
|
+
sourceJob?: {
|
|
51
|
+
id: string;
|
|
52
|
+
containerName: string;
|
|
53
|
+
};
|
|
54
|
+
}): Promise<SourceBuildResult>;
|
|
55
|
+
/** Reconcile only a labeled, image-bound durable container, then prove absence. */
|
|
56
|
+
export declare function removeSourceJobContainer(config: SourceBuildConfig, job: {
|
|
57
|
+
id: string;
|
|
58
|
+
containerName: string;
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
//# sourceMappingURL=source-build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-build.d.ts","sourceRoot":"","sources":["../src/source-build.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAExD,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAA;IAClB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sEAAsE;IACtE,OAAO,CAAC,EAAE,UAAU,GAAG,YAAY,CAAA;IACnC,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;iFAC6E;IAC7E,iBAAiB,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,sBAAsB,CAAA;CACjC;AAMD,uEAAuE;AACvE,eAAO,MAAM,4BAA4B,oxBAA4uB,CAAA;AAYrxB,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CA2BzE;AAiDD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,KAAK,EAAE;IACnD,MAAM,EAAE,iBAAiB,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,WAAW,EAAE,MAAM,CAAC,UAAU,CAAA;IAC9B,MAAM,EAAE,WAAW,CAAA;IACnB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,SAAS,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAA;CAClD,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkG7B;AAED,mFAAmF;AACnF,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBnI"}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { chmod, lstat, mkdtemp, readFile, realpath, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
|
+
import { ControlPlaneCliError } from './errors.js';
|
|
7
|
+
import { checkedSourceSnapshot, runLocalCommand } from './source-workspace.js';
|
|
8
|
+
const imageDigest = /^(?:[a-z0-9][a-z0-9._:/-]*@)?sha256:[a-f0-9]{64}$/u;
|
|
9
|
+
const marker = /^DSH_PREPARED_PACK\t([^\t\n]+)\t([0-9]+)\t([a-f0-9]{64})\t([^\t\n]+)\t([^\t\n]+)$/mu;
|
|
10
|
+
const repositorySeccompSha256 = 'b1e4b5b709578785bd2aff4a3a344301997571ad0e8ae5747aec176571ddc342';
|
|
11
|
+
/** Exact in-container command recorded in prepared source evidence. */
|
|
12
|
+
export const PREPARED_SOURCE_BUILD_SCRIPT = 'set -eu; checked() { phase="$1"; shift; if "$@" >"/tmp/$phase.log" 2>&1; then return 0; else code=$?; printf "source build phase failed: %s\\n" "$phase" >&2; tail -c 8192 "/tmp/$phase.log" >&2; return "$code"; fi; }; umask 077; mkdir -p /workspace; tar -x -C /workspace; cd /workspace; checked install pnpm install --offline --frozen-lockfile --ignore-scripts; checked check pnpm check; mkdir -p /workspace/.dsh-pack; cd "$PLUGIN_ROOT"; checked pack pnpm pack --pack-destination /workspace/.dsh-pack; set -- /workspace/.dsh-pack/*.tgz; test "$#" = 1; pack="$1"; printf "DSH_PREPARED_PACK\\t%s\\t%s\\t%s\\t%s\\t%s\\n" "${pack##*/}" "$(wc -c < "$pack" | tr -d " ")" "$(sha256sum "$pack" | cut -d " " -f1)" "$(node --version)" "$(pnpm --version)"';
|
|
13
|
+
function sourceBuildLimits(config) {
|
|
14
|
+
const profile = config.profile ?? 'standard';
|
|
15
|
+
return { profile, temporaryMiB: config.temporaryMiB ?? (profile === 'repository' ? 2_048 : 32) };
|
|
16
|
+
}
|
|
17
|
+
export function validateSourceBuildConfig(config) {
|
|
18
|
+
if (config === null || typeof config !== 'object' || Array.isArray(config) || (config.profile !== undefined && config.profile !== 'standard' && config.profile !== 'repository')
|
|
19
|
+
|| (config.versioning !== undefined && config.versioning !== 'patch')
|
|
20
|
+
|| (config.temporaryMiB !== undefined && !Number.isSafeInteger(config.temporaryMiB))
|
|
21
|
+
|| (config.repositorySandbox !== undefined && (config.profile !== 'repository' || typeof config.repositorySandbox !== 'object' || config.repositorySandbox === null
|
|
22
|
+
|| Array.isArray(config.repositorySandbox) || Object.getPrototypeOf(config.repositorySandbox) !== Object.prototype
|
|
23
|
+
|| Object.keys(config.repositorySandbox).length !== 1 || Object.keys(config.repositorySandbox)[0] !== 'seccompPath'
|
|
24
|
+
|| typeof config.repositorySandbox.seccompPath !== 'string' || !config.repositorySandbox.seccompPath.startsWith('/') || config.repositorySandbox.seccompPath.includes('\0')))
|
|
25
|
+
|| typeof config.image !== 'string' || config.image.length > 256 || !imageDigest.test(config.image) || typeof config.dockerPath !== 'string' || !config.dockerPath.startsWith('/') || config.dockerPath.includes('\0')
|
|
26
|
+
|| !Number.isSafeInteger(config.timeoutMs) || config.timeoutMs < 60_000
|
|
27
|
+
|| !Number.isSafeInteger(config.memoryMiB) || config.memoryMiB < 128
|
|
28
|
+
|| !Number.isSafeInteger(config.pidsLimit) || config.pidsLimit < 16
|
|
29
|
+
|| !Number.isFinite(config.cpus) || config.cpus < 0.25
|
|
30
|
+
|| !Number.isSafeInteger(config.workspaceMiB) || config.workspaceMiB < 64
|
|
31
|
+
|| !Number.isSafeInteger(config.outputBytes) || config.outputBytes < 4096 || config.outputBytes > 1_048_576) {
|
|
32
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'source build configuration is invalid');
|
|
33
|
+
}
|
|
34
|
+
const limits = sourceBuildLimits(config);
|
|
35
|
+
const repository = limits.profile === 'repository';
|
|
36
|
+
if (config.timeoutMs > (repository ? 1_800_000 : 240_000)
|
|
37
|
+
|| config.memoryMiB > (repository ? 16_384 : 4_096)
|
|
38
|
+
|| config.pidsLimit > (repository ? 1_024 : 512)
|
|
39
|
+
|| config.cpus > (repository ? 16 : 4)
|
|
40
|
+
|| config.workspaceMiB > (repository ? 8_192 : 2_048)
|
|
41
|
+
|| limits.temporaryMiB < 32 || limits.temporaryMiB > (repository ? 4_096 : 32)) {
|
|
42
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'source build configuration is invalid');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function snapshotRepositorySeccomp(config, temporary) {
|
|
46
|
+
const sandbox = config.repositorySandbox;
|
|
47
|
+
if (sandbox === undefined)
|
|
48
|
+
return undefined;
|
|
49
|
+
if (process.platform !== 'linux' || process.arch !== 'x64')
|
|
50
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'repository seccomp requires linux x64');
|
|
51
|
+
const canonical = await realpath(sandbox.seccompPath);
|
|
52
|
+
if (canonical !== resolve(sandbox.seccompPath))
|
|
53
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'repository seccomp profile must be canonical');
|
|
54
|
+
const before = await lstat(canonical);
|
|
55
|
+
const parent = await lstat(dirname(canonical));
|
|
56
|
+
const uid = process.getuid?.();
|
|
57
|
+
if (!before.isFile() || before.isSymbolicLink() || before.size > 65_536 || (before.mode & 0o022) !== 0
|
|
58
|
+
|| !parent.isDirectory() || parent.isSymbolicLink() || (parent.mode & 0o022) !== 0
|
|
59
|
+
|| (uid !== undefined && before.uid !== 0 && before.uid !== uid)) {
|
|
60
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'repository seccomp profile is not an owner-safe bounded regular file');
|
|
61
|
+
}
|
|
62
|
+
const bytes = await readFile(canonical);
|
|
63
|
+
const after = await lstat(canonical);
|
|
64
|
+
if (after.dev !== before.dev || after.ino !== before.ino || after.size !== before.size || after.mtimeMs !== before.mtimeMs || after.ctimeMs !== before.ctimeMs) {
|
|
65
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'repository seccomp profile changed while being read');
|
|
66
|
+
}
|
|
67
|
+
const digest = createHash('sha256').update(bytes).digest('hex');
|
|
68
|
+
if (digest !== repositorySeccompSha256)
|
|
69
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'repository seccomp profile digest is not approved');
|
|
70
|
+
const path = join(temporary, 'repository-seccomp.json');
|
|
71
|
+
await writeFile(path, bytes, { mode: 0o600 });
|
|
72
|
+
await chmod(path, 0o600);
|
|
73
|
+
return { path, digest };
|
|
74
|
+
}
|
|
75
|
+
async function verifiedDockerPath(path) {
|
|
76
|
+
const canonical = await realpath(path);
|
|
77
|
+
const executable = await lstat(canonical);
|
|
78
|
+
const parent = await lstat(dirname(canonical));
|
|
79
|
+
const uid = process.getuid?.();
|
|
80
|
+
if (resolve(path) !== canonical || !executable.isFile() || executable.isSymbolicLink() || (executable.mode & 0o111) === 0
|
|
81
|
+
|| (executable.mode & 0o022) !== 0 || !parent.isDirectory() || parent.isSymbolicLink() || (parent.mode & 0o002) !== 0
|
|
82
|
+
|| (uid !== undefined && executable.uid !== 0 && executable.uid !== uid)) {
|
|
83
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'source build docker client is not a canonical owner-safe executable');
|
|
84
|
+
}
|
|
85
|
+
return canonical;
|
|
86
|
+
}
|
|
87
|
+
async function sourceTree(worktree, baseCommit, scope, environment) {
|
|
88
|
+
const temporary = await mkdtemp(join(tmpdir(), 'dsh-source-build-index-'));
|
|
89
|
+
try {
|
|
90
|
+
const env = { ...environment, GIT_INDEX_FILE: join(temporary, 'index') };
|
|
91
|
+
await runLocalCommand('git', ['read-tree', baseCommit], worktree, env);
|
|
92
|
+
await runLocalCommand('git', ['--literal-pathspecs', 'add', '--all', '--', ...scope], worktree, env);
|
|
93
|
+
const tree = (await runLocalCommand('git', ['write-tree'], worktree, env, { capture: true })).trim();
|
|
94
|
+
if (!/^[a-f0-9]{40}$/u.test(tree))
|
|
95
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'temporary source tree is invalid');
|
|
96
|
+
return { tree, temporary, cleanup: async () => { await rm(temporary, { recursive: true, force: true }); } };
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
await rm(temporary, { recursive: true, force: true });
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Archive an exact temporary-index tree into a disposable, mount-free Docker
|
|
105
|
+
* container. No repository, state directory, socket, credential, environment
|
|
106
|
+
* value, or Host path crosses the boundary: the sole input is tar on stdin.
|
|
107
|
+
*/
|
|
108
|
+
export async function runDockerPreparedChecks(input) {
|
|
109
|
+
if (input.sourceJob !== undefined && (!/^source-job-[a-f0-9]{64}$/u.test(input.sourceJob.id)
|
|
110
|
+
|| input.sourceJob.containerName !== `dsh-${input.sourceJob.id}`))
|
|
111
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'invalid durable container identity');
|
|
112
|
+
validateSourceBuildConfig(input.config);
|
|
113
|
+
const limits = sourceBuildLimits(input.config);
|
|
114
|
+
const dockerPath = await verifiedDockerPath(input.config.dockerPath);
|
|
115
|
+
await input.assertCurrent();
|
|
116
|
+
if (input.config.repositorySandbox !== undefined) {
|
|
117
|
+
const version = await dockerControl(dockerPath, ['version', '--format', '{{.Server.Version}}/{{.Server.Os}}/{{.Server.Arch}}'], input.signal);
|
|
118
|
+
if (version.code !== 0 || version.stdout.trim() !== '29.4.1/linux/amd64')
|
|
119
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'repository seccomp requires approved Docker runtime 29.4.1/linux/amd64');
|
|
120
|
+
await input.assertCurrent();
|
|
121
|
+
}
|
|
122
|
+
const snapshot = await sourceTree(input.worktree, input.baseCommit, input.scope, input.environment);
|
|
123
|
+
let before;
|
|
124
|
+
let packageVersion;
|
|
125
|
+
let seccomp;
|
|
126
|
+
try {
|
|
127
|
+
seccomp = await snapshotRepositorySeccomp(input.config, snapshot.temporary);
|
|
128
|
+
before = await checkedSourceSnapshot(input.worktree, input.baseCommit, input.scope, input.environment, snapshot.tree);
|
|
129
|
+
const packageJson = await runLocalCommand('git', ['show', `${snapshot.tree}:plugins/${input.name}/package.json`], input.worktree, input.environment, { capture: true, maximumOutput: 65_536 });
|
|
130
|
+
const value = JSON.parse(packageJson)?.version;
|
|
131
|
+
if (typeof value !== 'string' || !/^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u.test(value)) {
|
|
132
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'source package version is invalid');
|
|
133
|
+
}
|
|
134
|
+
packageVersion = value;
|
|
135
|
+
await input.assertCurrent();
|
|
136
|
+
input.signal.throwIfAborted();
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
await snapshot.cleanup();
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
const container = input.sourceJob?.containerName ?? `dsh-source-prepare-${randomUUID()}`;
|
|
143
|
+
if (input.sourceJob !== undefined) {
|
|
144
|
+
try {
|
|
145
|
+
const existing = await dockerControl(dockerPath, ['container', 'ls', '--all', '--quiet', '--filter', `name=^/${container}$`], input.signal);
|
|
146
|
+
if (existing.code !== 0 || existing.stdout.trim() !== '')
|
|
147
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'durable source container already exists or cannot be inspected');
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
await snapshot.cleanup();
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const script = PREPARED_SOURCE_BUILD_SCRIPT;
|
|
155
|
+
const args = ['run', '-i', '--pull', 'never', '--name', container, '--label', `dsh.source.tree=${snapshot.tree}`, ...(input.sourceJob === undefined ? [] : ['--label', `dsh.source.job=${input.sourceJob.id}`]), ...(seccomp === undefined ? [] : ['--label', `dsh.source.seccomp.sha256=${seccomp.digest}`]), '--network', 'none', '--read-only', '--cap-drop', 'ALL',
|
|
156
|
+
'--security-opt', 'no-new-privileges', '--user', '65534:65534', '--pids-limit', String(input.config.pidsLimit),
|
|
157
|
+
'--memory', `${input.config.memoryMiB}m`, '--memory-swap', `${input.config.memoryMiB}m`, '--cpus', String(input.config.cpus),
|
|
158
|
+
'--tmpfs', `/workspace:rw,nosuid,nodev,mode=1777,size=${input.config.workspaceMiB}m${limits.profile === 'repository' ? ',exec' : ''}`, '--tmpfs', `/tmp:rw,nosuid,nodev,mode=1777,size=${limits.temporaryMiB}m${limits.profile === 'repository' ? ',exec' : ''}`,
|
|
159
|
+
'--workdir', '/workspace', '--env', `PLUGIN_ROOT=plugins/${input.name}`, '--env', 'HOME=/tmp', '--env', 'PATH=/usr/local/bin:/usr/bin:/bin',
|
|
160
|
+
...(limits.profile === 'repository' ? ['--env', 'CI=true', '--env', 'VITEST_MAX_WORKERS=1'] : []),
|
|
161
|
+
// Docker's masked proc submounts prevent procfs mounts in a child user
|
|
162
|
+
// namespace. This opt-in removes those system-path masks; an empty /sys
|
|
163
|
+
// compensates for sysfs exposure, but does not restore the /proc masks.
|
|
164
|
+
...(seccomp === undefined ? [] : ['--security-opt', `seccomp=${seccomp.path}`,
|
|
165
|
+
'--security-opt', 'systempaths=unconfined', '--tmpfs', '/sys:ro,nosuid,nodev,noexec,size=1m']),
|
|
166
|
+
'--entrypoint', '/bin/sh', input.config.image, '-ceu', script];
|
|
167
|
+
const git = spawn('/usr/bin/git', ['archive', '--format=tar', snapshot.tree], { cwd: input.worktree, env: input.environment, stdio: ['ignore', 'pipe', 'pipe'], shell: false });
|
|
168
|
+
const docker = spawn(dockerPath, args, { stdio: ['pipe', 'pipe', 'pipe'], shell: false, env: { PATH: '/usr/bin:/bin' } });
|
|
169
|
+
git.stderr.resume();
|
|
170
|
+
docker.stdin.on('error', () => { });
|
|
171
|
+
git.stdout.pipe(docker.stdin);
|
|
172
|
+
const dockerDone = new Promise((resolvePromise, reject) => { docker.once('error', reject); docker.once('close', resolvePromise); });
|
|
173
|
+
const gitDone = new Promise((resolvePromise, reject) => { git.once('error', reject); git.once('close', code => code === 0 ? resolvePromise() : reject(new ControlPlaneCliError('EXECUTOR_FAILED', `source archive exited ${code}`))); });
|
|
174
|
+
let stdout = '';
|
|
175
|
+
let stdoutBytes = 0;
|
|
176
|
+
let stderr = '';
|
|
177
|
+
let overflow = false;
|
|
178
|
+
let timedOut = false;
|
|
179
|
+
const add = (target, chunk) => {
|
|
180
|
+
if (target === 'err') {
|
|
181
|
+
stderr = (stderr + chunk.toString('utf8')).slice(-4096);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const remaining = input.config.outputBytes - stdoutBytes;
|
|
185
|
+
if (remaining > 0)
|
|
186
|
+
stdout += chunk.subarray(0, remaining).toString('utf8');
|
|
187
|
+
stdoutBytes += chunk.length;
|
|
188
|
+
if (stdoutBytes > input.config.outputBytes) {
|
|
189
|
+
overflow = true;
|
|
190
|
+
stop();
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
docker.stdout.on('data', (chunk) => add('out', chunk));
|
|
194
|
+
docker.stderr.on('data', (chunk) => add('err', chunk));
|
|
195
|
+
const stop = () => { git.kill('SIGKILL'); docker.kill('SIGKILL'); };
|
|
196
|
+
const abort = () => { timedOut = true; stop(); };
|
|
197
|
+
input.signal.addEventListener('abort', abort, { once: true });
|
|
198
|
+
const timer = setTimeout(abort, input.config.timeoutMs);
|
|
199
|
+
if (input.signal.aborted)
|
|
200
|
+
abort();
|
|
201
|
+
const started = Date.now();
|
|
202
|
+
try {
|
|
203
|
+
const [code] = await Promise.all([dockerDone, gitDone]);
|
|
204
|
+
await input.assertCurrent();
|
|
205
|
+
if (timedOut || input.signal.aborted)
|
|
206
|
+
throw new ControlPlaneCliError('EXECUTOR_TIMEOUT', 'isolated source build was cancelled or exceeded its deadline');
|
|
207
|
+
if (overflow)
|
|
208
|
+
throw new ControlPlaneCliError('EXECUTOR_OUTPUT_LIMIT', 'isolated source build exceeded its output bound');
|
|
209
|
+
if (code !== 0)
|
|
210
|
+
throw new ControlPlaneCliError('EXECUTOR_FAILED', `isolated source build failed (${code}): ${stderr.trimEnd()}`);
|
|
211
|
+
const match = marker.exec(stdout);
|
|
212
|
+
if (match !== null && stdout.trim() !== match[0])
|
|
213
|
+
throw new ControlPlaneCliError('EXECUTOR_FAILED', 'isolated source build emitted unexpected evidence output');
|
|
214
|
+
if (match === null)
|
|
215
|
+
throw new ControlPlaneCliError('EXECUTOR_FAILED', 'isolated source build did not emit its pack evidence marker');
|
|
216
|
+
const checked = await checkedSourceSnapshot(input.worktree, input.baseCommit, input.scope, input.environment);
|
|
217
|
+
if (checked.checkedTreeDigest !== before.checkedTreeDigest || checked.checkedPatchDigest !== before.checkedPatchDigest) {
|
|
218
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'prepared source changed while its isolated build was running');
|
|
219
|
+
}
|
|
220
|
+
const logDigest = createHash('sha256').update(stdout).update('\0').update(stderr).digest('hex');
|
|
221
|
+
const checkedAt = Date.now();
|
|
222
|
+
return { treeDigest: checked.checkedTreeDigest, patchDigest: checked.checkedPatchDigest, checkedAt,
|
|
223
|
+
evidence: Object.freeze({ schemaVersion: 1, kind: 'dsh-source-prepared-evidence',
|
|
224
|
+
environment: Object.freeze({ npmConfigIgnoreScripts: true, frozenLockfile: true, offline: true, nodeVersion: match[4], pnpmVersion: match[5] }),
|
|
225
|
+
commands: Object.freeze([{ command: 'docker', args: Object.freeze([...args]), exitCode: 0, durationMs: Date.now() - started, logDigest }]),
|
|
226
|
+
pack: Object.freeze({ name: match[1], sizeBytes: Number(match[2]), sha256: match[3], version: packageVersion }), preparedAt: input.preparedAt }) };
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
clearTimeout(timer);
|
|
230
|
+
input.signal.removeEventListener('abort', abort);
|
|
231
|
+
stop();
|
|
232
|
+
await Promise.allSettled([dockerDone, gitDone]);
|
|
233
|
+
try {
|
|
234
|
+
// Failed inspect is ambiguous (daemon loss also exits nonzero). Require
|
|
235
|
+
// a successful exact-name listing from the daemon to prove absence.
|
|
236
|
+
if (input.sourceJob === undefined)
|
|
237
|
+
await ensureContainerRemoved(dockerPath, container);
|
|
238
|
+
else
|
|
239
|
+
await removeSourceJobContainer(input.config, input.sourceJob);
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
await snapshot.cleanup();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/** Reconcile only a labeled, image-bound durable container, then prove absence. */
|
|
247
|
+
export async function removeSourceJobContainer(config, job) {
|
|
248
|
+
if (!/^source-job-[a-f0-9]{64}$/u.test(job.id) || job.containerName !== `dsh-${job.id}`)
|
|
249
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'invalid durable container identity');
|
|
250
|
+
validateSourceBuildConfig(config);
|
|
251
|
+
const path = await verifiedDockerPath(config.dockerPath);
|
|
252
|
+
const list = () => dockerControl(path, ['container', 'ls', '--all', '--quiet', '--filter', `name=^/${job.containerName}$`]);
|
|
253
|
+
const before = await list();
|
|
254
|
+
if (before.code !== 0)
|
|
255
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'durable container absence is unproven');
|
|
256
|
+
if (before.stdout.trim() !== '') {
|
|
257
|
+
const inspected = await dockerControl(path, ['inspect', '--format', '[{{json .Id}},{{json .Name}},{{json .Config.Image}},{{json (index .Config.Labels "dsh.source.job")}}]', job.containerName]);
|
|
258
|
+
if (inspected.code !== 0)
|
|
259
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'durable container identity is unproven');
|
|
260
|
+
const value = JSON.parse(inspected.stdout);
|
|
261
|
+
if (!Array.isArray(value) || value.length !== 4 || typeof value[0] !== 'string' || !/^[a-f0-9]{64}$/u.test(value[0])
|
|
262
|
+
|| value[1] !== `/${job.containerName}` || value[2] !== config.image || value[3] !== job.id)
|
|
263
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'durable container ownership mismatch');
|
|
264
|
+
await dockerControl(path, ['rm', '-f', value[0]]);
|
|
265
|
+
}
|
|
266
|
+
const after = await list();
|
|
267
|
+
if (after.code !== 0 || after.stdout.trim() !== '')
|
|
268
|
+
throw new ControlPlaneCliError('SOURCE_BOUNDARY', 'durable container cleanup is unproven');
|
|
269
|
+
}
|
|
270
|
+
async function dockerControl(path, args, signal) {
|
|
271
|
+
signal?.throwIfAborted();
|
|
272
|
+
return new Promise((resolvePromise, reject) => {
|
|
273
|
+
const child = spawn(path, args, { stdio: ['ignore', 'pipe', 'ignore'], shell: false, env: { PATH: '/usr/bin:/bin' } });
|
|
274
|
+
let stdout = '';
|
|
275
|
+
let bytes = 0;
|
|
276
|
+
let failed = false;
|
|
277
|
+
const abort = () => { child.kill('SIGKILL'); };
|
|
278
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
279
|
+
if (signal?.aborted)
|
|
280
|
+
abort();
|
|
281
|
+
const timer = setTimeout(() => { failed = true; child.kill('SIGKILL'); }, 5_000);
|
|
282
|
+
const cleanup = () => { clearTimeout(timer); signal?.removeEventListener('abort', abort); };
|
|
283
|
+
child.stdout.on('data', (chunk) => {
|
|
284
|
+
bytes += chunk.length;
|
|
285
|
+
if (bytes > 4_096) {
|
|
286
|
+
failed = true;
|
|
287
|
+
child.kill('SIGKILL');
|
|
288
|
+
}
|
|
289
|
+
else
|
|
290
|
+
stdout += chunk.toString('utf8');
|
|
291
|
+
});
|
|
292
|
+
child.once('error', () => { cleanup(); reject(new ControlPlaneCliError('EXECUTOR_FAILED', 'source build control client could not start')); });
|
|
293
|
+
child.once('close', code => {
|
|
294
|
+
cleanup();
|
|
295
|
+
if (signal?.aborted)
|
|
296
|
+
reject(new ControlPlaneCliError('EXECUTOR_TIMEOUT', 'source build control query was cancelled'));
|
|
297
|
+
else if (failed)
|
|
298
|
+
reject(new ControlPlaneCliError('EXECUTOR_FAILED', 'source build control query exceeded its resource bound'));
|
|
299
|
+
else
|
|
300
|
+
resolvePromise({ code, stdout });
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
async function ensureContainerRemoved(path, container) {
|
|
305
|
+
await dockerControl(path, ['rm', '-f', container]);
|
|
306
|
+
const remaining = await dockerControl(path, ['container', 'ls', '--all', '--quiet', '--filter', `name=^/${container}$`]);
|
|
307
|
+
if (remaining.code !== 0 || remaining.stdout.trim() !== '') {
|
|
308
|
+
throw new ControlPlaneCliError('EXECUTOR_FAILED', 'isolated source build container cleanup could not prove quiescence');
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=source-build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-build.js","sourceRoot":"","sources":["../src/source-build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC3F,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAgC9E,MAAM,WAAW,GAAG,oDAAoD,CAAA;AACxE,MAAM,MAAM,GAAG,qFAAqF,CAAA;AACpG,MAAM,uBAAuB,GAAG,kEAAkE,CAAA;AAElG,uEAAuE;AACvE,MAAM,CAAC,MAAM,4BAA4B,GAAG,yuBAAyuB,CAAA;AAOrxB,SAAS,iBAAiB,CAAC,MAAyB;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,UAAU,CAAA;IAC5C,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;AAClG,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAyB;IACjE,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU,IAAI,MAAM,CAAC,OAAO,KAAK,YAAY,CAAC;WAC3K,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC;WAClE,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;WACjF,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,YAAY,IAAI,OAAO,MAAM,CAAC,iBAAiB,KAAK,QAAQ,IAAI,MAAM,CAAC,iBAAiB,KAAK,IAAI;eAC9J,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,MAAM,CAAC,SAAS;eAC/G,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa;eAChH,OAAO,MAAM,CAAC,iBAAiB,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;WAC5K,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;WACnN,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM;WACpE,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG;WACjE,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,EAAE;WAChE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,IAAI;WACnD,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,YAAY,GAAG,EAAE;WACtE,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC,WAAW,GAAG,IAAI,IAAI,MAAM,CAAC,WAAW,GAAG,SAAS,EAAE,CAAC;QAC9G,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,uCAAuC,CAAC,CAAA;IAC5F,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;IACxC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,KAAK,YAAY,CAAA;IAClD,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;WACpD,MAAM,CAAC,SAAS,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;WAChD,MAAM,CAAC,SAAS,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;WAC7C,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;WACnC,MAAM,CAAC,YAAY,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;WAClD,MAAM,CAAC,YAAY,GAAG,EAAE,IAAI,MAAM,CAAC,YAAY,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,uCAAuC,CAAC,CAAA;IAC5F,CAAC;AACH,CAAC;AAED,KAAK,UAAU,yBAAyB,CAAC,MAAyB,EAAE,SAAiB;IACnF,MAAM,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAA;IACxC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC3C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK;QAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,uCAAuC,CAAC,CAAA;IACtJ,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACrD,IAAI,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,8CAA8C,CAAC,CAAA;IACjJ,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAAC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAA;IACrH,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,MAAM,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;WACjG,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;WAC/E,CAAC,GAAG,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,sEAAsE,CAAC,CAAA;IAC3H,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAA;IACpC,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/J,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,qDAAqD,CAAC,CAAA;IAC1G,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC/D,IAAI,MAAM,KAAK,uBAAuB;QAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,mDAAmD,CAAC,CAAA;IAC9I,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAA;IACvD,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAAC,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACvE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;AACzB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,IAAY;IAC5C,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAAC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAA;IACzH,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,UAAU,CAAC,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;WACpH,CAAC,UAAU,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;WAClH,CAAC,GAAG,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,KAAK,CAAC,IAAI,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,qEAAqE,CAAC,CAAA;IAC1H,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAwB,EAAE,WAA8B;IACtH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,yBAAyB,CAAC,CAAC,CAAA;IAC1E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,GAAG,WAAW,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAA;QACxE,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAA;QACtE,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAA;QACpG,MAAM,IAAI,GAAG,CAAC,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACpG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,kCAAkC,CAAC,CAAA;QACxH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA,CAAC,CAAC,EAAE,CAAA;IAC5G,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,MAAM,KAAK,CAAA;IAAC,CAAC;AACxF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAY7C;IACC,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;WACvF,KAAK,CAAC,SAAS,CAAC,aAAa,KAAK,OAAO,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,oCAAoC,CAAC,CAAA;IAC5J,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAAC,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAAC,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAAC,MAAM,KAAK,CAAC,aAAa,EAAE,CAAA;IAC1L,IAAI,KAAK,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACjD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,qDAAqD,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QAC7I,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,oBAAoB;YAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,wEAAwE,CAAC,CAAA;QACrM,MAAM,KAAK,CAAC,aAAa,EAAE,CAAA;IAC7B,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;IACnG,IAAI,MAAyD,CAAA;IAC7D,IAAI,cAAsB,CAAA;IAC1B,IAAI,OAAqD,CAAA;IACzD,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,yBAAyB,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;QAC3E,MAAM,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;QACrH,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,YAAY,KAAK,CAAC,IAAI,eAAe,CAAC,EAC9G,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAA;QAC9E,MAAM,KAAK,GAAa,IAAI,CAAC,KAAK,CAAC,WAAW,CAA2B,EAAE,OAAO,CAAA;QAClF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,oEAAoE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACnH,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,mCAAmC,CAAC,CAAA;QACxF,CAAC;QACD,cAAc,GAAG,KAAK,CAAA;QACtB,MAAM,KAAK,CAAC,aAAa,EAAE,CAAA;QAC3B,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAAC,MAAM,KAAK,CAAA;IAAC,CAAC;IACzD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,EAAE,aAAa,IAAI,sBAAsB,UAAU,EAAE,EAAE,CAAA;IACxF,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,SAAS,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;YAC3I,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,gEAAgE,CAAC,CAAA;QAC/K,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;YAAC,MAAM,KAAK,CAAA;QAAC,CAAC;IAC3D,CAAC;IACD,MAAM,MAAM,GAAG,4BAA4B,CAAA;IAC3C,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,kBAAkB,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,6BAA6B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK;QACpW,gBAAgB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;QAC9G,UAAU,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5H,SAAS,EAAE,6CAA6C,KAAK,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,uCAAuC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QAChQ,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,uBAAuB,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,mCAAmC;QAC3I,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,uEAAuE;QACvE,wEAAwE;QACxE,wEAAwE;QACxE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,WAAW,OAAO,CAAC,IAAI,EAAE;YAC3E,gBAAgB,EAAE,wBAAwB,EAAE,SAAS,EAAE,qCAAqC,CAAC,CAAC;QAChG,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAChE,MAAM,GAAG,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;IAC/K,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,CAAC,CAAA;IACzH,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAA;IACnB,MAAM,CAAC,KAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAqD,CAAC,CAAC,CAAA;IACtF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAM,CAAC,CAAA;IAC9B,MAAM,UAAU,GAAG,IAAI,OAAO,CAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IACjJ,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,yBAAyB,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAC7O,IAAI,MAAM,GAAG,EAAE,CAAC;IAAC,IAAI,WAAW,GAAG,CAAC,CAAC;IAAC,IAAI,MAAM,GAAG,EAAE,CAAC;IAAC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAAC,IAAI,QAAQ,GAAG,KAAK,CAAA;IACjG,MAAM,GAAG,GAAG,CAAC,MAAqB,EAAE,KAAa,EAAQ,EAAE;QACzD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YAAC,MAAM,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;YAAC,OAAM;QAAC,CAAC;QACzF,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,GAAG,WAAW,CAAA;QACxD,IAAI,SAAS,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAC1E,WAAW,IAAI,KAAK,CAAC,MAAM,CAAA;QAC3B,IAAI,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAAC,QAAQ,GAAG,IAAI,CAAC;YAAC,IAAI,EAAE,CAAA;QAAC,CAAC;IACzE,CAAC,CAAA;IACD,MAAM,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAAC,MAAM,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;IAChI,MAAM,IAAI,GAAG,GAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA,CAAC,CAAC,CAAA;IACxE,MAAM,KAAK,GAAG,GAAS,EAAE,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA,CAAC,CAAC,CAAA;IACrD,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACvD,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;QAAE,KAAK,EAAE,CAAA;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;QACvD,MAAM,KAAK,CAAC,aAAa,EAAE,CAAA;QAC3B,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,IAAI,oBAAoB,CAAC,kBAAkB,EAAE,8DAA8D,CAAC,CAAA;QACxJ,IAAI,QAAQ;YAAE,MAAM,IAAI,oBAAoB,CAAC,uBAAuB,EAAE,iDAAiD,CAAC,CAAA;QACxH,IAAI,IAAI,KAAK,CAAC;YAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,iCAAiC,IAAI,MAAM,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QAChI,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACjC,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,0DAA0D,CAAC,CAAA;QAC/J,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,6DAA6D,CAAC,CAAA;QACpI,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;QAC7G,IAAI,OAAO,CAAC,iBAAiB,KAAK,MAAM,CAAC,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,KAAK,MAAM,CAAC,kBAAkB,EAAE,CAAC;YACvH,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,8DAA8D,CAAC,CAAA;QACnH,CAAC;QACD,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,iBAAiB,EAAE,WAAW,EAAE,OAAO,CAAC,kBAAkB,EAAE,SAAS;YAChG,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,8BAA8B;gBAC9E,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,sBAAsB,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC;gBACjJ,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAU,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;gBACnJ,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE,CAAA;IAC1J,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;QAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAAC,IAAI,EAAE,CAAA;QAC7E,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;QAC/C,IAAI,CAAC;YACH,wEAAwE;YACxE,oEAAoE;YACpE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;gBAAE,MAAM,sBAAsB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;;gBACjF,MAAM,wBAAwB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;QACpE,CAAC;gBAAS,CAAC;YAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAA;QAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAyB,EAAE,GAA0C;IAClH,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,aAAa,KAAK,OAAO,GAAG,CAAC,EAAE,EAAE;QAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,oCAAoC,CAAC,CAAA;IAChL,yBAAyB,CAAC,MAAM,CAAC,CAAA;IACjC,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACxD,MAAM,IAAI,GAAG,GAAqD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC,CAAA;IAC7K,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAA;IAC3B,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,uCAAuC,CAAC,CAAA;IACjH,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,uGAAuG,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,CAAA;QAChM,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,wCAAwC,CAAC,CAAA;QACrH,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;eAC/G,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,aAAa,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,sCAAsC,CAAC,CAAA;QACxL,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAA;IAC1B,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,uCAAuC,CAAC,CAAA;AAChJ,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,IAAc,EAAE,MAAoB;IAC7E,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,CAAC,CAAA;QACtH,IAAI,MAAM,GAAG,EAAE,CAAC;QAAC,IAAI,KAAK,GAAG,CAAC,CAAC;QAAC,IAAI,MAAM,GAAG,KAAK,CAAA;QAClD,MAAM,KAAK,GAAG,GAAS,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA,CAAC,CAAC,CAAA;QACnD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QACxD,IAAI,MAAM,EAAE,OAAO;YAAE,KAAK,EAAE,CAAA;QAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;QAC/E,MAAM,OAAO,GAAG,GAAS,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA,CAAC,CAAC,CAAA;QAChG,KAAK,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAA;YACrB,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;gBAAC,MAAM,GAAG,IAAI,CAAC;gBAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAAC,CAAC;;gBACtD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QACvC,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,6CAA6C,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;QAC5I,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;YACzB,OAAO,EAAE,CAAA;YACT,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAM,CAAC,IAAI,oBAAoB,CAAC,kBAAkB,EAAE,0CAA0C,CAAC,CAAC,CAAA;iBAChH,IAAI,MAAM;gBAAE,MAAM,CAAC,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,wDAAwD,CAAC,CAAC,CAAA;;gBACzH,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;QACvC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,IAAY,EAAE,SAAiB;IACnE,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,SAAS,GAAG,CAAC,CAAC,CAAA;IACxH,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,oBAAoB,CAAC,iBAAiB,EAAE,oEAAoE,CAAC,CAAA;IACzH,CAAC;AACH,CAAC"}
|