crewly 1.20.173 → 1.20.175
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/config/skills/orchestrator/restart-crewly/SKILL.md +11 -23
- package/config/skills/orchestrator/restart-crewly/execute.sh +7 -5
- package/dist/backend/backend/src/constants.d.ts +64 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +64 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts +67 -0
- package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/system/system-control.controller.js +183 -0
- package/dist/backend/backend/src/controllers/system/system-control.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts +0 -13
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.js +0 -87
- package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +7 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +84 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.js +4 -2
- package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +7 -0
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +6 -0
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.js +32 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts +58 -0
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.service.js +128 -52
- package/dist/backend/backend/src/services/system/auto-update.service.js.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.utils.d.ts +7 -0
- package/dist/backend/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.utils.js +14 -0
- package/dist/backend/backend/src/services/system/auto-update.utils.js.map +1 -1
- package/dist/backend/backend/src/services/system/restart-replacement.d.ts +78 -0
- package/dist/backend/backend/src/services/system/restart-replacement.d.ts.map +1 -0
- package/dist/backend/backend/src/services/system/restart-replacement.js +109 -0
- package/dist/backend/backend/src/services/system/restart-replacement.js.map +1 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.d.ts +78 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.d.ts.map +1 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.js +171 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.js.map +1 -0
- package/dist/backend/backend/src/services/system/system-control.service.d.ts +337 -0
- package/dist/backend/backend/src/services/system/system-control.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/system/system-control.service.js +574 -0
- package/dist/backend/backend/src/services/system/system-control.service.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +64 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +64 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +6 -0
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.js +32 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/cli/backend/src/services/system/auto-update.utils.d.ts +7 -0
- package/dist/cli/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
- package/dist/cli/backend/src/services/system/auto-update.utils.js +14 -0
- package/dist/cli/backend/src/services/system/auto-update.utils.js.map +1 -1
- package/frontend/dist/assets/{index-36e85ac8.js → index-0726afab.js} +281 -281
- package/frontend/dist/assets/{index-15501404.css → index-0c5449b5.css} +1 -1
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System Control Service — the owner's Upgrade and Restart buttons.
|
|
3
|
+
*
|
|
4
|
+
* Jenkins-style "safe restart" for Crewly
|
|
5
|
+
* (specs/2026-10-01-upgrade-restart-controls.md):
|
|
6
|
+
*
|
|
7
|
+
* - **Status.** Running version, latest on npm, install kind, who relaunches
|
|
8
|
+
* the backend, agents mid-turn, and the current / last action.
|
|
9
|
+
* - **Upgrade** (`when: idle | now`). npm global installs only. It reuses the
|
|
10
|
+
* AutoUpdateService install path (same prefix, same npm, same verify), then
|
|
11
|
+
* restarts. A source checkout is refused: it is updated with git.
|
|
12
|
+
* - **Restart** (`when: idle | now`). The graceful drained shutdown, exiting
|
|
13
|
+
* with RESTART_REQUESTED. When nothing is known to relaunch the backend, a
|
|
14
|
+
* detached launcher is started first so the machine never stays down.
|
|
15
|
+
* - **When idle** waits until no agent is mid-turn, capped (30 min), then
|
|
16
|
+
* goes ahead. Asking again with `now` cuts the wait short.
|
|
17
|
+
* - **One at a time.** A second request while one is running is refused,
|
|
18
|
+
* as is any request while a shutdown is already under way.
|
|
19
|
+
* - **Survives the restart.** Progress and outcome are kept in
|
|
20
|
+
* `<crewlyHome>/system-action.json`; the next boot settles the record
|
|
21
|
+
* ("Restarted at …", "Upgraded to x.y.z", or what went wrong), so the
|
|
22
|
+
* dashboard can show it after it reconnects.
|
|
23
|
+
*
|
|
24
|
+
* All I/O goes through {@link SystemControlDeps}.
|
|
25
|
+
*
|
|
26
|
+
* @module services/system/system-control.service
|
|
27
|
+
*/
|
|
28
|
+
import * as fs from 'fs';
|
|
29
|
+
import * as path from 'path';
|
|
30
|
+
import { randomUUID } from 'crypto';
|
|
31
|
+
import { PROCESS_EXIT_CODES, SYSTEM_CONTROL_CONSTANTS } from '../../constants.js';
|
|
32
|
+
import { isNewerVersion } from './auto-update.utils.js';
|
|
33
|
+
/** Statuses that mean "still running". */
|
|
34
|
+
const ACTIVE_STATUSES = new Set(['waiting-idle', 'installing', 'restarting']);
|
|
35
|
+
/**
|
|
36
|
+
* Map the AutoUpdate install kind onto the public one.
|
|
37
|
+
*
|
|
38
|
+
* @param install - Install info
|
|
39
|
+
* @returns Public kind
|
|
40
|
+
*/
|
|
41
|
+
export function toPublicInstallKind(install) {
|
|
42
|
+
if (install.kind === 'npm-global')
|
|
43
|
+
return 'npm-global';
|
|
44
|
+
if (install.kind === 'dev-checkout')
|
|
45
|
+
return 'dev-checkout';
|
|
46
|
+
return 'other';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Read the persisted action record.
|
|
50
|
+
*
|
|
51
|
+
* @param file - State file
|
|
52
|
+
* @returns The record, or null when missing / malformed
|
|
53
|
+
*/
|
|
54
|
+
export function readActionRecord(file) {
|
|
55
|
+
try {
|
|
56
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
57
|
+
return parsed && typeof parsed.id === 'string' && typeof parsed.status === 'string' ? parsed : null;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Write the action record atomically.
|
|
65
|
+
*
|
|
66
|
+
* @param file - State file
|
|
67
|
+
* @param record - Record
|
|
68
|
+
*/
|
|
69
|
+
export function writeActionRecord(file, record) {
|
|
70
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
71
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
72
|
+
fs.writeFileSync(tmp, JSON.stringify(record, null, 2), 'utf-8');
|
|
73
|
+
fs.renameSync(tmp, file);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Upgrade / restart controller for the running backend.
|
|
77
|
+
*/
|
|
78
|
+
export class SystemControlService {
|
|
79
|
+
deps;
|
|
80
|
+
static instance = null;
|
|
81
|
+
action = null;
|
|
82
|
+
stateFile;
|
|
83
|
+
/** Resolves the current idle wait early ("now" pressed while waiting) */
|
|
84
|
+
cutIdleWaitShort = null;
|
|
85
|
+
/**
|
|
86
|
+
* @param deps - Injected I/O
|
|
87
|
+
*/
|
|
88
|
+
constructor(deps) {
|
|
89
|
+
this.deps = deps;
|
|
90
|
+
this.stateFile = path.join(deps.crewlyHome, SYSTEM_CONTROL_CONSTANTS.STATE_FILE);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Register the process-wide instance.
|
|
94
|
+
*
|
|
95
|
+
* @param service - Instance, or null to clear
|
|
96
|
+
*/
|
|
97
|
+
static setInstance(service) {
|
|
98
|
+
SystemControlService.instance = service;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The process-wide instance, when the server registered one.
|
|
102
|
+
*
|
|
103
|
+
* @returns The instance or null
|
|
104
|
+
*/
|
|
105
|
+
static getInstance() {
|
|
106
|
+
return SystemControlService.instance;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Boot: settle the record a previous process left behind, so the
|
|
110
|
+
* dashboard can say "Restarted at …" / "Upgraded to x.y.z" after it
|
|
111
|
+
* reconnects.
|
|
112
|
+
*/
|
|
113
|
+
handleBoot() {
|
|
114
|
+
const record = readActionRecord(this.stateFile);
|
|
115
|
+
if (!record || !ACTIVE_STATUSES.has(record.status) || record.pid === this.deps.pid)
|
|
116
|
+
return;
|
|
117
|
+
const now = new Date(this.deps.now()).toISOString();
|
|
118
|
+
const running = this.deps.currentVersion;
|
|
119
|
+
let settled;
|
|
120
|
+
if (record.status === 'restarting') {
|
|
121
|
+
if (record.kind === 'upgrade' && record.toVersion && running !== record.toVersion) {
|
|
122
|
+
settled = {
|
|
123
|
+
...record,
|
|
124
|
+
status: 'failed',
|
|
125
|
+
message: `Crewly came back on ${running ?? 'an unknown version'} instead of ${record.toVersion}.`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
settled = {
|
|
130
|
+
...record,
|
|
131
|
+
status: 'completed',
|
|
132
|
+
message: record.kind === 'upgrade' ? `Upgraded to ${running} and restarted at ${now}.` : `Restarted at ${now}.`,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
settled = {
|
|
138
|
+
...record,
|
|
139
|
+
status: 'interrupted',
|
|
140
|
+
message: record.kind === 'upgrade'
|
|
141
|
+
? 'Crewly stopped before the upgrade finished. Nothing was installed or the install was not confirmed; try again.'
|
|
142
|
+
: 'Crewly stopped before the restart started.',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
settled = { ...settled, completedAt: now, updatedAt: now, resultVersion: running };
|
|
146
|
+
this.action = settled;
|
|
147
|
+
this.persist();
|
|
148
|
+
this.deps.logger.info('Previous upgrade/restart settled at boot', {
|
|
149
|
+
id: settled.id,
|
|
150
|
+
kind: settled.kind,
|
|
151
|
+
status: settled.status,
|
|
152
|
+
requestedBy: settled.requestedBy,
|
|
153
|
+
message: settled.message,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Whether an upgrade or restart from this process is still running.
|
|
158
|
+
*
|
|
159
|
+
* @returns True while one is
|
|
160
|
+
*/
|
|
161
|
+
isActionInProgress() {
|
|
162
|
+
return !!this.action && ACTIVE_STATUSES.has(this.action.status) && this.action.pid === this.deps.pid;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The current or last action (this boot, or the one settled at boot).
|
|
166
|
+
*
|
|
167
|
+
* @returns The record or null
|
|
168
|
+
*/
|
|
169
|
+
getAction() {
|
|
170
|
+
if (this.action)
|
|
171
|
+
return this.action;
|
|
172
|
+
return readActionRecord(this.stateFile);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* How the backend comes back after an exit.
|
|
176
|
+
*
|
|
177
|
+
* @param supervisor - Supervisor info
|
|
178
|
+
* @returns supervisor or replacement
|
|
179
|
+
*/
|
|
180
|
+
relaunchMethod(supervisor) {
|
|
181
|
+
return supervisor.willRelaunch === 'yes' ? 'supervisor' : 'replacement';
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Status for the dashboard.
|
|
185
|
+
*
|
|
186
|
+
* @param options - `refresh` re-asks the registry when the cached answer is over a minute old
|
|
187
|
+
* @returns Status
|
|
188
|
+
*/
|
|
189
|
+
async getStatus(options = {}) {
|
|
190
|
+
const { install, currentVersion } = this.deps;
|
|
191
|
+
let latest = null;
|
|
192
|
+
try {
|
|
193
|
+
latest = await this.deps.fetchLatestVersion(options.refresh ? SYSTEM_CONTROL_CONSTANTS.REGISTRY_MAX_AGE_MS : SYSTEM_CONTROL_CONSTANTS.STATUS_REGISTRY_MAX_AGE_MS);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
latest = null;
|
|
197
|
+
}
|
|
198
|
+
const updateAvailable = !!latest && !!currentVersion && isNewerVersion(latest, currentVersion);
|
|
199
|
+
const installKind = toPublicInstallKind(install);
|
|
200
|
+
const busy = this.inProgressReason();
|
|
201
|
+
const supervisor = this.deps.getSupervisor();
|
|
202
|
+
let upgradeBlockedReason = null;
|
|
203
|
+
if (installKind === 'dev-checkout')
|
|
204
|
+
upgradeBlockedReason = SYSTEM_CONTROL_CONSTANTS.MESSAGES.DEV_CHECKOUT;
|
|
205
|
+
else if (installKind === 'other')
|
|
206
|
+
upgradeBlockedReason = SYSTEM_CONTROL_CONSTANTS.MESSAGES.NOT_NPM_GLOBAL;
|
|
207
|
+
else if (busy)
|
|
208
|
+
upgradeBlockedReason = busy;
|
|
209
|
+
else if (!latest)
|
|
210
|
+
upgradeBlockedReason = SYSTEM_CONTROL_CONSTANTS.MESSAGES.REGISTRY_UNREACHABLE;
|
|
211
|
+
else if (!updateAvailable)
|
|
212
|
+
upgradeBlockedReason = `Crewly is up to date (${currentVersion}).`;
|
|
213
|
+
else if (!this.deps.getInstaller())
|
|
214
|
+
upgradeBlockedReason = SYSTEM_CONTROL_CONSTANTS.MESSAGES.UNAVAILABLE;
|
|
215
|
+
return {
|
|
216
|
+
currentVersion,
|
|
217
|
+
latestVersion: latest,
|
|
218
|
+
updateAvailable,
|
|
219
|
+
installKind,
|
|
220
|
+
packageRoot: install.packageRoot,
|
|
221
|
+
canUpgrade: upgradeBlockedReason === null,
|
|
222
|
+
upgradeBlockedReason,
|
|
223
|
+
canRestart: busy === null,
|
|
224
|
+
restartBlockedReason: busy,
|
|
225
|
+
supervisor,
|
|
226
|
+
relaunch: this.relaunchMethod(supervisor),
|
|
227
|
+
busyAgents: this.safeBusyAgents(),
|
|
228
|
+
inProgress: busy !== null,
|
|
229
|
+
action: this.getAction(),
|
|
230
|
+
bootId: this.deps.bootId,
|
|
231
|
+
startedAt: this.deps.startedAt,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Why nothing new can start right now (null when it can).
|
|
236
|
+
*
|
|
237
|
+
* @returns Owner-readable reason or null
|
|
238
|
+
*/
|
|
239
|
+
inProgressReason() {
|
|
240
|
+
if (this.isActionInProgress() && this.action) {
|
|
241
|
+
return this.action.kind === 'upgrade'
|
|
242
|
+
? `An upgrade to ${this.action.toVersion} is already in progress.`
|
|
243
|
+
: 'A restart is already in progress.';
|
|
244
|
+
}
|
|
245
|
+
if (this.deps.isShutdownInProgress())
|
|
246
|
+
return SYSTEM_CONTROL_CONSTANTS.MESSAGES.RESTART_IN_PROGRESS;
|
|
247
|
+
if (this.deps.getInstaller()?.isBusy())
|
|
248
|
+
return 'An automatic update is running right now. Try again in a few minutes.';
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Busy agents, never throwing.
|
|
253
|
+
*
|
|
254
|
+
* @returns Agents mid-turn
|
|
255
|
+
*/
|
|
256
|
+
safeBusyAgents() {
|
|
257
|
+
try {
|
|
258
|
+
return this.deps.getBusyAgents();
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Escalate a running "when idle" wait of the same kind to "now".
|
|
266
|
+
*
|
|
267
|
+
* @param kind - Requested kind
|
|
268
|
+
* @param request - Request
|
|
269
|
+
* @returns Accepted answer, or null when this is not an escalation
|
|
270
|
+
*/
|
|
271
|
+
tryEscalate(kind, request) {
|
|
272
|
+
const action = this.action;
|
|
273
|
+
if (request.when !== 'now' ||
|
|
274
|
+
!action ||
|
|
275
|
+
!this.isActionInProgress() ||
|
|
276
|
+
action.kind !== kind ||
|
|
277
|
+
action.status !== 'waiting-idle' ||
|
|
278
|
+
!this.cutIdleWaitShort) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
this.deps.logger.info(`${kind === 'upgrade' ? 'Upgrade' : 'Restart'}: "now" requested while waiting for idle`, {
|
|
282
|
+
id: action.id,
|
|
283
|
+
requestedBy: request.actor,
|
|
284
|
+
});
|
|
285
|
+
this.update({ when: 'now', message: `${request.actor} asked to go ahead now.` });
|
|
286
|
+
this.cutIdleWaitShort();
|
|
287
|
+
return { ok: true, action: this.action, escalated: true };
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Refusal for "something is already running", or null.
|
|
291
|
+
*
|
|
292
|
+
* @returns Refusal or null
|
|
293
|
+
*/
|
|
294
|
+
busyRefusal() {
|
|
295
|
+
if (this.isActionInProgress()) {
|
|
296
|
+
return { ok: false, httpStatus: 409, code: SYSTEM_CONTROL_CONSTANTS.CODES.IN_PROGRESS, error: this.inProgressReason() };
|
|
297
|
+
}
|
|
298
|
+
const reason = this.inProgressReason();
|
|
299
|
+
if (reason) {
|
|
300
|
+
return { ok: false, httpStatus: 409, code: SYSTEM_CONTROL_CONSTANTS.CODES.RESTART_IN_PROGRESS, error: reason };
|
|
301
|
+
}
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Owner pressed "Upgrade".
|
|
306
|
+
*
|
|
307
|
+
* @param request - When, and who
|
|
308
|
+
* @returns Accepted (work continues in the background) or a refusal
|
|
309
|
+
*/
|
|
310
|
+
async requestUpgrade(request) {
|
|
311
|
+
const { install, currentVersion } = this.deps;
|
|
312
|
+
if (install.kind === 'dev-checkout') {
|
|
313
|
+
this.deps.logger.info('Upgrade refused: source checkout', { requestedBy: request.actor, packageRoot: install.packageRoot });
|
|
314
|
+
return { ok: false, httpStatus: 409, code: SYSTEM_CONTROL_CONSTANTS.CODES.DEV_CHECKOUT, error: SYSTEM_CONTROL_CONSTANTS.MESSAGES.DEV_CHECKOUT };
|
|
315
|
+
}
|
|
316
|
+
if (install.kind !== 'npm-global') {
|
|
317
|
+
this.deps.logger.info('Upgrade refused: not an npm global install', { requestedBy: request.actor, detail: install.detail });
|
|
318
|
+
return { ok: false, httpStatus: 409, code: SYSTEM_CONTROL_CONSTANTS.CODES.NOT_NPM_GLOBAL, error: SYSTEM_CONTROL_CONSTANTS.MESSAGES.NOT_NPM_GLOBAL };
|
|
319
|
+
}
|
|
320
|
+
const escalated = this.tryEscalate('upgrade', request);
|
|
321
|
+
if (escalated)
|
|
322
|
+
return escalated;
|
|
323
|
+
const busy = this.busyRefusal();
|
|
324
|
+
if (busy)
|
|
325
|
+
return busy;
|
|
326
|
+
const installer = this.deps.getInstaller();
|
|
327
|
+
if (!installer) {
|
|
328
|
+
return { ok: false, httpStatus: 503, code: SYSTEM_CONTROL_CONSTANTS.CODES.UNAVAILABLE, error: SYSTEM_CONTROL_CONSTANTS.MESSAGES.UNAVAILABLE };
|
|
329
|
+
}
|
|
330
|
+
let latest = null;
|
|
331
|
+
try {
|
|
332
|
+
latest = await this.deps.fetchLatestVersion(SYSTEM_CONTROL_CONSTANTS.REGISTRY_MAX_AGE_MS);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
latest = null;
|
|
336
|
+
}
|
|
337
|
+
if (!latest) {
|
|
338
|
+
return { ok: false, httpStatus: 502, code: SYSTEM_CONTROL_CONSTANTS.CODES.REGISTRY_UNREACHABLE, error: SYSTEM_CONTROL_CONSTANTS.MESSAGES.REGISTRY_UNREACHABLE };
|
|
339
|
+
}
|
|
340
|
+
if (!currentVersion || !isNewerVersion(latest, currentVersion)) {
|
|
341
|
+
return { ok: false, httpStatus: 409, code: SYSTEM_CONTROL_CONSTANTS.CODES.UP_TO_DATE, error: `Crewly is already up to date (${currentVersion ?? latest}).` };
|
|
342
|
+
}
|
|
343
|
+
// The registry await gave another request a chance to start.
|
|
344
|
+
const raced = this.busyRefusal();
|
|
345
|
+
if (raced)
|
|
346
|
+
return raced;
|
|
347
|
+
const action = this.begin('upgrade', request, latest);
|
|
348
|
+
installer.appendLogLine(`${new Date(this.deps.now()).toISOString()} Manual upgrade to ${latest} requested by ${request.actor} (${request.when})`);
|
|
349
|
+
void this.runUpgrade(installer, latest).catch((error) => this.fail(`Upgrade crashed: ${errorText(error)}`));
|
|
350
|
+
return { ok: true, action };
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Owner pressed "Restart".
|
|
354
|
+
*
|
|
355
|
+
* @param request - When, and who
|
|
356
|
+
* @returns Accepted (work continues in the background) or a refusal
|
|
357
|
+
*/
|
|
358
|
+
async requestRestart(request) {
|
|
359
|
+
const escalated = this.tryEscalate('restart', request);
|
|
360
|
+
if (escalated)
|
|
361
|
+
return escalated;
|
|
362
|
+
const busy = this.busyRefusal();
|
|
363
|
+
if (busy)
|
|
364
|
+
return busy;
|
|
365
|
+
const action = this.begin('restart', request, null);
|
|
366
|
+
void this.runRestart().catch((error) => this.fail(`Restart crashed: ${errorText(error)}`));
|
|
367
|
+
return { ok: true, action };
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Create and persist a new action.
|
|
371
|
+
*
|
|
372
|
+
* @param kind - upgrade or restart
|
|
373
|
+
* @param request - Request
|
|
374
|
+
* @param toVersion - Upgrade target
|
|
375
|
+
* @returns The record
|
|
376
|
+
*/
|
|
377
|
+
begin(kind, request, toVersion) {
|
|
378
|
+
const now = new Date(this.deps.now()).toISOString();
|
|
379
|
+
const supervisor = this.deps.getSupervisor();
|
|
380
|
+
const label = kind === 'upgrade' ? `Upgrade to ${toVersion}` : 'Restart';
|
|
381
|
+
this.action = {
|
|
382
|
+
id: randomUUID(),
|
|
383
|
+
kind,
|
|
384
|
+
when: request.when,
|
|
385
|
+
status: request.when === 'idle' ? 'waiting-idle' : kind === 'upgrade' ? 'installing' : 'restarting',
|
|
386
|
+
requestedBy: request.actor,
|
|
387
|
+
requestedAt: now,
|
|
388
|
+
updatedAt: now,
|
|
389
|
+
fromVersion: this.deps.currentVersion,
|
|
390
|
+
toVersion,
|
|
391
|
+
pid: this.deps.pid,
|
|
392
|
+
relaunch: this.relaunchMethod(supervisor),
|
|
393
|
+
message: request.when === 'idle' ? `${label} will start when no agent is mid-turn.` : `${label} is starting.`,
|
|
394
|
+
};
|
|
395
|
+
this.persist();
|
|
396
|
+
this.deps.logger.info(`${label} requested`, {
|
|
397
|
+
id: this.action.id,
|
|
398
|
+
when: request.when,
|
|
399
|
+
requestedBy: request.actor,
|
|
400
|
+
fromVersion: this.deps.currentVersion,
|
|
401
|
+
supervisor: supervisor.kind,
|
|
402
|
+
willRelaunch: supervisor.willRelaunch,
|
|
403
|
+
});
|
|
404
|
+
return this.action;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Upgrade body: (wait for idle) → install → verify → marker → restart.
|
|
408
|
+
*
|
|
409
|
+
* @param installer - AutoUpdate install path
|
|
410
|
+
* @param version - Target
|
|
411
|
+
*/
|
|
412
|
+
async runUpgrade(installer, version) {
|
|
413
|
+
if (this.action?.when === 'idle')
|
|
414
|
+
await this.waitForIdle();
|
|
415
|
+
if (this.deps.isShutdownInProgress()) {
|
|
416
|
+
this.fail('Crewly started shutting down for another reason before the upgrade began.');
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
this.update({ status: 'installing', message: `Installing ${version}…` });
|
|
420
|
+
const attempt = await installer.installVersion(version);
|
|
421
|
+
if (!attempt.ok) {
|
|
422
|
+
this.deps.logger.warn('Manual upgrade install failed; not restarting', { version, outcome: attempt.outcome, reason: attempt.reason, ...attempt.details });
|
|
423
|
+
this.fail(`Could not install ${version}: ${attempt.reason}. Crewly keeps running ${this.deps.currentVersion}.`);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
installer.writeUpgradeMarker(this.deps.currentVersion ?? 'unknown', version);
|
|
427
|
+
const restarted = this.restartNow(`owner upgrade ${this.deps.currentVersion} -> ${version}`, `Installed ${version}. Restarting…`);
|
|
428
|
+
if (!restarted)
|
|
429
|
+
installer.clearUpgradeMarker();
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Restart body: (wait for idle) → restart.
|
|
433
|
+
*/
|
|
434
|
+
async runRestart() {
|
|
435
|
+
if (this.action?.when === 'idle')
|
|
436
|
+
await this.waitForIdle();
|
|
437
|
+
if (this.deps.isShutdownInProgress()) {
|
|
438
|
+
this.fail('Crewly started shutting down for another reason before the restart began.');
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
await this.deps.sleep(SYSTEM_CONTROL_CONSTANTS.RESPONSE_FLUSH_MS);
|
|
442
|
+
this.restartNow('owner restart', 'Restarting… agents finish their current turn first.');
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Make sure something brings the backend back, then run the graceful
|
|
446
|
+
* restart.
|
|
447
|
+
*
|
|
448
|
+
* @param reason - Shutdown reason (logs)
|
|
449
|
+
* @param message - Owner-readable progress
|
|
450
|
+
* @returns False when the restart could not be started
|
|
451
|
+
*/
|
|
452
|
+
restartNow(reason, message) {
|
|
453
|
+
const supervisor = this.deps.getSupervisor();
|
|
454
|
+
const relaunch = this.relaunchMethod(supervisor);
|
|
455
|
+
if (relaunch === 'replacement') {
|
|
456
|
+
try {
|
|
457
|
+
this.deps.spawnReplacement(supervisor.willRelaunch === 'unknown');
|
|
458
|
+
this.deps.logger.info('Started the replacement launcher; it brings Crewly back after this process exits', {
|
|
459
|
+
supervisor: supervisor.kind,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
catch (error) {
|
|
463
|
+
this.fail(`Could not arrange for Crewly to come back (${errorText(error)}), so it was not restarted.`);
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
this.update({ status: 'restarting', relaunch, message });
|
|
468
|
+
this.deps.logger.info('Restarting Crewly', { reason, relaunch, requestedBy: this.action?.requestedBy });
|
|
469
|
+
let started = false;
|
|
470
|
+
try {
|
|
471
|
+
started = this.deps.requestGracefulRestart(reason);
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
this.deps.logger.warn('Graceful restart unavailable; exiting directly', { error: errorText(error) });
|
|
475
|
+
}
|
|
476
|
+
if (!started) {
|
|
477
|
+
this.deps.logger.warn('No graceful shutdown handler; exiting with the restart code');
|
|
478
|
+
this.deps.exit(PROCESS_EXIT_CODES.RESTART_REQUESTED);
|
|
479
|
+
}
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Wait until no agent is mid-turn, at most IDLE_WAIT_CAP_MS; a later "now"
|
|
484
|
+
* request ends the wait at once.
|
|
485
|
+
*/
|
|
486
|
+
async waitForIdle() {
|
|
487
|
+
const deadline = this.deps.now() + SYSTEM_CONTROL_CONSTANTS.IDLE_WAIT_CAP_MS;
|
|
488
|
+
let cut = false;
|
|
489
|
+
const cutPromise = new Promise((resolve) => {
|
|
490
|
+
this.cutIdleWaitShort = () => {
|
|
491
|
+
cut = true;
|
|
492
|
+
resolve();
|
|
493
|
+
};
|
|
494
|
+
});
|
|
495
|
+
let lastBusy = '';
|
|
496
|
+
try {
|
|
497
|
+
for (;;) {
|
|
498
|
+
if (cut) {
|
|
499
|
+
this.update({ idleWaitEndedBy: 'now' });
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
const busy = this.safeBusyAgents().map((a) => a.session);
|
|
503
|
+
if (busy.length === 0) {
|
|
504
|
+
this.update({ idleWaitEndedBy: 'idle', waitingFor: [] });
|
|
505
|
+
this.deps.logger.info('No agent is mid-turn; going ahead', { id: this.action?.id });
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (this.deps.now() >= deadline) {
|
|
509
|
+
this.update({ idleWaitEndedBy: 'cap', waitingFor: busy });
|
|
510
|
+
this.deps.logger.info('Waited the maximum for agents to go idle; going ahead (the restart drain still lets turns finish)', {
|
|
511
|
+
id: this.action?.id,
|
|
512
|
+
busy,
|
|
513
|
+
});
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const key = busy.join(',');
|
|
517
|
+
if (key !== lastBusy) {
|
|
518
|
+
lastBusy = key;
|
|
519
|
+
this.update({ waitingFor: busy, message: `Waiting for ${busy.length} agent${busy.length === 1 ? '' : 's'} to finish: ${busy.join(', ')}.` });
|
|
520
|
+
}
|
|
521
|
+
await Promise.race([this.deps.sleep(SYSTEM_CONTROL_CONSTANTS.IDLE_POLL_MS), cutPromise]);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
finally {
|
|
525
|
+
this.cutIdleWaitShort = null;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Mark the current action failed.
|
|
530
|
+
*
|
|
531
|
+
* @param message - Owner-readable reason
|
|
532
|
+
*/
|
|
533
|
+
fail(message) {
|
|
534
|
+
if (!this.action)
|
|
535
|
+
return;
|
|
536
|
+
const now = new Date(this.deps.now()).toISOString();
|
|
537
|
+
this.update({ status: 'failed', message, completedAt: now, resultVersion: this.deps.currentVersion });
|
|
538
|
+
this.deps.logger.warn('Upgrade/restart failed', { id: this.action.id, kind: this.action.kind, message, requestedBy: this.action.requestedBy });
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Merge a patch into the current action and persist it.
|
|
542
|
+
*
|
|
543
|
+
* @param patch - Fields to change
|
|
544
|
+
*/
|
|
545
|
+
update(patch) {
|
|
546
|
+
if (!this.action)
|
|
547
|
+
return;
|
|
548
|
+
this.action = { ...this.action, ...patch, updatedAt: new Date(this.deps.now()).toISOString() };
|
|
549
|
+
this.persist();
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Write the current action (best-effort).
|
|
553
|
+
*/
|
|
554
|
+
persist() {
|
|
555
|
+
if (!this.action)
|
|
556
|
+
return;
|
|
557
|
+
try {
|
|
558
|
+
writeActionRecord(this.stateFile, this.action);
|
|
559
|
+
}
|
|
560
|
+
catch (error) {
|
|
561
|
+
this.deps.logger.warn('Could not save upgrade/restart progress', { error: errorText(error) });
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Error text.
|
|
567
|
+
*
|
|
568
|
+
* @param error - Anything thrown
|
|
569
|
+
* @returns Message
|
|
570
|
+
*/
|
|
571
|
+
function errorText(error) {
|
|
572
|
+
return error instanceof Error ? error.message : String(error);
|
|
573
|
+
}
|
|
574
|
+
//# sourceMappingURL=system-control.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-control.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/system/system-control.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AA4JxD,0CAA0C;AAC1C,MAAM,eAAe,GAAoC,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAE/G;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAoB;IACvD,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,YAAY,CAAC;IACvD,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO,cAAc,CAAC;IAC3D,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAuB,CAAC;QAChF,OAAO,MAAM,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAA0B;IACzE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IACzC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAChE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,oBAAoB;IAUH;IATrB,MAAM,CAAC,QAAQ,GAAgC,IAAI,CAAC;IACpD,MAAM,GAA8B,IAAI,CAAC;IAChC,SAAS,CAAS;IACnC,yEAAyE;IACjE,gBAAgB,GAAwB,IAAI,CAAC;IAErD;;OAEG;IACH,YAA6B,IAAuB;QAAvB,SAAI,GAAJ,IAAI,CAAmB;QACnD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAClF,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,OAAoC;QACtD,oBAAoB,CAAC,QAAQ,GAAG,OAAO,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,WAAW;QACjB,OAAO,oBAAoB,CAAC,QAAQ,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACH,UAAU;QACT,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,OAAO;QAC3F,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;QACzC,IAAI,OAA2B,CAAC;QAChC,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YACpC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,IAAI,OAAO,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;gBACnF,OAAO,GAAG;oBACT,GAAG,MAAM;oBACT,MAAM,EAAE,QAAQ;oBAChB,OAAO,EAAE,uBAAuB,OAAO,IAAI,oBAAoB,eAAe,MAAM,CAAC,SAAS,GAAG;iBACjG,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,OAAO,GAAG;oBACT,GAAG,MAAM;oBACT,MAAM,EAAE,WAAW;oBACnB,OAAO,EAAE,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,OAAO,qBAAqB,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,GAAG,GAAG;iBAC/G,CAAC;YACH,CAAC;QACF,CAAC;aAAM,CAAC;YACP,OAAO,GAAG;gBACT,GAAG,MAAM;gBACT,MAAM,EAAE,aAAa;gBACrB,OAAO,EACN,MAAM,CAAC,IAAI,KAAK,SAAS;oBACxB,CAAC,CAAC,gHAAgH;oBAClH,CAAC,CAAC,4CAA4C;aAChD,CAAC;QACH,CAAC;QACD,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;QACnF,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;QACtB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;YACjE,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;SACxB,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,kBAAkB;QACjB,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACtG,CAAC;IAED;;;;OAIG;IACH,SAAS;QACR,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC;QACpC,OAAO,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACK,cAAc,CAAC,UAA0B;QAChD,OAAO,UAAU,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,UAAiC,EAAE;QAClD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;QAC9C,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAC1C,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,mBAAmB,CAAC,CAAC,CAAC,wBAAwB,CAAC,0BAA0B,CACpH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,GAAG,IAAI,CAAC;QACf,CAAC;QACD,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC/F,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAE7C,IAAI,oBAAoB,GAAkB,IAAI,CAAC;QAC/C,IAAI,WAAW,KAAK,cAAc;YAAE,oBAAoB,GAAG,wBAAwB,CAAC,QAAQ,CAAC,YAAY,CAAC;aACrG,IAAI,WAAW,KAAK,OAAO;YAAE,oBAAoB,GAAG,wBAAwB,CAAC,QAAQ,CAAC,cAAc,CAAC;aACrG,IAAI,IAAI;YAAE,oBAAoB,GAAG,IAAI,CAAC;aACtC,IAAI,CAAC,MAAM;YAAE,oBAAoB,GAAG,wBAAwB,CAAC,QAAQ,CAAC,oBAAoB,CAAC;aAC3F,IAAI,CAAC,eAAe;YAAE,oBAAoB,GAAG,yBAAyB,cAAc,IAAI,CAAC;aACzF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAAE,oBAAoB,GAAG,wBAAwB,CAAC,QAAQ,CAAC,WAAW,CAAC;QAEzG,OAAO;YACN,cAAc;YACd,aAAa,EAAE,MAAM;YACrB,eAAe;YACf,WAAW;YACX,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE,oBAAoB,KAAK,IAAI;YACzC,oBAAoB;YACpB,UAAU,EAAE,IAAI,KAAK,IAAI;YACzB,oBAAoB,EAAE,IAAI;YAC1B,UAAU;YACV,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;YACzC,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE;YACjC,UAAU,EAAE,IAAI,KAAK,IAAI;YACzB,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE;YACxB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YACxB,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS;SAC9B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,gBAAgB;QACvB,IAAI,IAAI,CAAC,kBAAkB,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS;gBACpC,CAAC,CAAC,iBAAiB,IAAI,CAAC,MAAM,CAAC,SAAS,0BAA0B;gBAClE,CAAC,CAAC,mCAAmC,CAAC;QACxC,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE;YAAE,OAAO,wBAAwB,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACnG,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE;YAAE,OAAO,uEAAuE,CAAC;QACvH,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;OAIG;IACK,cAAc;QACrB,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACK,WAAW,CAAC,IAAsB,EAAE,OAA4B;QACvE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IACC,OAAO,CAAC,IAAI,KAAK,KAAK;YACtB,CAAC,MAAM;YACP,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC1B,MAAM,CAAC,IAAI,KAAK,IAAI;YACpB,MAAM,CAAC,MAAM,KAAK,cAAc;YAChC,CAAC,IAAI,CAAC,gBAAgB,EACrB,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,0CAA0C,EAAE;YAC9G,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,WAAW,EAAE,OAAO,CAAC,KAAK;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAAK,yBAAyB,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAA4B,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACjF,CAAC;IAED;;;;OAIG;IACK,WAAW;QAClB,IAAI,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;YAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAY,EAAE,CAAC;QACnI,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvC,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAChH,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,OAA4B;QAChD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;QAC9C,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;YAC5H,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;QACjJ,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5H,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;QACrJ,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC/I,CAAC;QACD,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,mBAAmB,CAAC,CAAC;QAC3F,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,GAAG,IAAI,CAAC;QACf,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;QACjK,CAAC;QACD,IAAI,CAAC,cAAc,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC;YAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,wBAAwB,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,iCAAiC,cAAc,IAAI,MAAM,IAAI,EAAE,CAAC;QAC9J,CAAC;QACD,6DAA6D;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACtD,SAAS,CAAC,aAAa,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,sBAAsB,MAAM,iBAAiB,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;QAClJ,KAAK,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5G,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,OAA4B;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACvD,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACpD,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3F,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,IAAsB,EAAE,OAA4B,EAAE,SAAwB;QAC3F,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,IAAI,CAAC,MAAM,GAAG;YACb,EAAE,EAAE,UAAU,EAAE;YAChB,IAAI;YACJ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY;YACnG,WAAW,EAAE,OAAO,CAAC,KAAK;YAC1B,WAAW,EAAE,GAAG;YAChB,SAAS,EAAE,GAAG;YACd,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;YACrC,SAAS;YACT,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG;YAClB,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;YACzC,OAAO,EAAE,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,wCAAwC,CAAC,CAAC,CAAC,GAAG,KAAK,eAAe;SAC7G,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,YAAY,EAAE;YAC3C,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,KAAK;YAC1B,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc;YACrC,UAAU,EAAE,UAAU,CAAC,IAAI;YAC3B,YAAY,EAAE,UAAU,CAAC,YAAY;SACrC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,UAAU,CAAC,SAA2B,EAAE,OAAe;QACpE,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,MAAM;YAAE,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3D,IAAI,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;YACvF,OAAO;QACR,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,OAAO,GAAG,EAAE,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1J,IAAI,CAAC,IAAI,CAAC,qBAAqB,OAAO,KAAK,OAAO,CAAC,MAAM,0BAA0B,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YAChH,OAAO;QACR,CAAC;QACD,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,cAAc,OAAO,OAAO,EAAE,EAAE,aAAa,OAAO,eAAe,CAAC,CAAC;QAClI,IAAI,CAAC,SAAS;YAAE,SAAS,CAAC,kBAAkB,EAAE,CAAC;IAChD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU;QACvB,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,MAAM;YAAE,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3D,IAAI,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;YACvF,OAAO;QACR,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;QAClE,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,qDAAqD,CAAC,CAAC;IACzF,CAAC;IAED;;;;;;;OAOG;IACK,UAAU,CAAC,MAAc,EAAE,OAAe;QACjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;YAChC,IAAI,CAAC;gBACJ,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC;gBAClE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kFAAkF,EAAE;oBACzG,UAAU,EAAE,UAAU,CAAC,IAAI;iBAC3B,CAAC,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,CAAC,IAAI,CAAC,8CAA8C,SAAS,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;gBACvG,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;QACxG,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC;YACJ,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gDAAgD,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtG,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YACrF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,WAAW;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,wBAAwB,CAAC,gBAAgB,CAAC;QAC7E,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,UAAU,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAChD,IAAI,CAAC,gBAAgB,GAAG,GAAG,EAAE;gBAC5B,GAAG,GAAG,IAAI,CAAC;gBACX,OAAO,EAAE,CAAC;YACX,CAAC,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC;YACJ,SAAS,CAAC;gBACT,IAAI,GAAG,EAAE,CAAC;oBACT,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;oBACxC,OAAO;gBACR,CAAC;gBACD,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBACzD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;oBACzD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;oBACpF,OAAO;gBACR,CAAC;gBACD,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;oBACjC,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mGAAmG,EAAE;wBAC1H,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;wBACnB,IAAI;qBACJ,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC3B,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACtB,QAAQ,GAAG,GAAG,CAAC;oBACf,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,eAAe,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC9I,CAAC;gBACD,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;YAC1F,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC9B,CAAC;IACF,CAAC;IAED;;;;OAIG;IACK,IAAI,CAAC,OAAe;QAC3B,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QACtG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAChJ,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,KAAkC;QAChD,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/F,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,OAAO;QACd,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,IAAI,CAAC;YACJ,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/F,CAAC;IACF,CAAC;;AAGF;;;;;GAKG;AACH,SAAS,SAAS,CAAC,KAAc;IAChC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC"}
|