baxian 1.2.59 → 1.2.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/branch.d.ts.map +1 -1
- package/dist/agent/branch.js +19 -13
- package/dist/agent/branch.js.map +1 -1
- package/dist/agent/dispatch-reconciler.d.ts +45 -0
- package/dist/agent/dispatch-reconciler.d.ts.map +1 -0
- package/dist/agent/dispatch-reconciler.js +513 -0
- package/dist/agent/dispatch-reconciler.js.map +1 -0
- package/dist/agent/manager.d.ts +89 -8
- package/dist/agent/manager.d.ts.map +1 -1
- package/dist/agent/manager.js +975 -368
- package/dist/agent/manager.js.map +1 -1
- package/dist/agent/pane-streamer-manager.d.ts +70 -0
- package/dist/agent/pane-streamer-manager.d.ts.map +1 -1
- package/dist/agent/pane-streamer-manager.js +487 -5
- package/dist/agent/pane-streamer-manager.js.map +1 -1
- package/dist/agent/pane-streamer.d.ts +48 -1
- package/dist/agent/pane-streamer.d.ts.map +1 -1
- package/dist/agent/pane-streamer.js +338 -15
- package/dist/agent/pane-streamer.js.map +1 -1
- package/dist/agent/preflight.d.ts.map +1 -1
- package/dist/agent/preflight.js +18 -8
- package/dist/agent/preflight.js.map +1 -1
- package/dist/agent/repo-store.d.ts +3 -0
- package/dist/agent/repo-store.d.ts.map +1 -1
- package/dist/agent/repo-store.js +192 -67
- package/dist/agent/repo-store.js.map +1 -1
- package/dist/agent/review-transport.d.ts.map +1 -1
- package/dist/agent/review-transport.js +4 -2
- package/dist/agent/review-transport.js.map +1 -1
- package/dist/agent/tmux-probe-poller.d.ts.map +1 -1
- package/dist/agent/tmux-probe-poller.js +29 -20
- package/dist/agent/tmux-probe-poller.js.map +1 -1
- package/dist/agent/tmux.d.ts +79 -32
- package/dist/agent/tmux.d.ts.map +1 -1
- package/dist/agent/tmux.js +435 -225
- package/dist/agent/tmux.js.map +1 -1
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +10 -0
- package/dist/api/config.js.map +1 -1
- package/dist/api/projects.d.ts.map +1 -1
- package/dist/api/projects.js +186 -94
- package/dist/api/projects.js.map +1 -1
- package/dist/api/tasks.d.ts.map +1 -1
- package/dist/api/tasks.js +5 -1
- package/dist/api/tasks.js.map +1 -1
- package/dist/app.d.ts +2 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +1 -0
- package/dist/app.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +11 -3
- package/dist/cli.js.map +1 -1
- package/dist/config/hot-reload.d.ts.map +1 -1
- package/dist/config/hot-reload.js +1 -0
- package/dist/config/hot-reload.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +48 -3
- package/dist/config/loader.js.map +1 -1
- package/dist/config/validator.js +3 -0
- package/dist/config/validator.js.map +1 -1
- package/dist/errors.d.ts +2 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -1
- package/dist/errors.js.map +1 -1
- package/dist/event/handlers.d.ts.map +1 -1
- package/dist/event/handlers.js +138 -41
- package/dist/event/handlers.js.map +1 -1
- package/dist/github/pr-conversation-cache.d.ts +41 -0
- package/dist/github/pr-conversation-cache.d.ts.map +1 -0
- package/dist/github/pr-conversation-cache.js +105 -0
- package/dist/github/pr-conversation-cache.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/shared/constants.d.ts +6 -0
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +6 -0
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/types.d.ts +4 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js.map +1 -1
- package/dist/state/agent-store.d.ts +5 -1
- package/dist/state/agent-store.d.ts.map +1 -1
- package/dist/state/agent-store.js +29 -15
- package/dist/state/agent-store.js.map +1 -1
- package/dist/state/lock.d.ts +9 -0
- package/dist/state/lock.d.ts.map +1 -1
- package/dist/state/lock.js +24 -1
- package/dist/state/lock.js.map +1 -1
- package/dist/state/task-store.js +2 -2
- package/dist/state/task-store.js.map +1 -1
- package/dist/terminal/attach.d.ts +10 -1
- package/dist/terminal/attach.d.ts.map +1 -1
- package/dist/terminal/attach.js +40 -20
- package/dist/terminal/attach.js.map +1 -1
- package/dist/terminal/stream-ws.d.ts.map +1 -1
- package/dist/terminal/stream-ws.js +27 -0
- package/dist/terminal/stream-ws.js.map +1 -1
- package/dist/web/assets/{index-DfcbGriX.css → index-CwYBVTyn.css} +1 -1
- package/dist/web/assets/index-DtnDvjOU.js +16 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-DskVWe7e.js +0 -13
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import { isSpecStagePhase } from '../shared/index.js';
|
|
2
|
+
import { ApiError } from '../errors.js';
|
|
3
|
+
import { PeriodicTaskRunner } from '../timing/periodic-task-runner.js';
|
|
4
|
+
import { isRecoverableQaDispatchHold, } from './manager.js';
|
|
5
|
+
// 绑定丢失可能只是一次在途派发的 release→acquire 缝隙,驻留两周期再动手。
|
|
6
|
+
const UNBOUND_DWELL_CYCLES = 2;
|
|
7
|
+
// 这些 409 由并发接管/入口互斥产生,会随下一周期自然消解,不消耗重试额度;
|
|
8
|
+
// 其余 409(跨任务占用、不可恢复 hold、release 失败等)是持久门禁,必须计次直至升级人工。
|
|
9
|
+
const NO_COUNT_API_CODES = new Set(['dispatch-superseded', 'dispatch-in-flight']);
|
|
10
|
+
// 派发级对账兜底(#558 M2 B3):消费 TmuxProbePoller 的观察结果 + manager 的 pending 登记,
|
|
11
|
+
// 把「QA 忙碌延后的 recheck / dev 忙碌延后的 fix / 可恢复 hold / 静默失联的 review pass」
|
|
12
|
+
// 经 M1 加固的标准入口补派。所有动作带次数上限与忙碌预算,超限一次性升级 intervention。
|
|
13
|
+
// 计轮意图读取持久化的 task.reviewRoundPending,进程重启后依然精确。
|
|
14
|
+
export class DispatchReconciler {
|
|
15
|
+
periodicRunner;
|
|
16
|
+
opts;
|
|
17
|
+
attempts = new Map();
|
|
18
|
+
// 驻留计数绑定 pass 世系:外部换代后新 pass 的 release→acquire 缝隙必须重新驻留,
|
|
19
|
+
// 不得继承旧 pass 的观察周期(同一 pass 内换绑仍是同一次在途派发,token 不变)
|
|
20
|
+
unboundSeen = new Map();
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.opts = options;
|
|
23
|
+
this.periodicRunner = new PeriodicTaskRunner({
|
|
24
|
+
name: 'dispatch-reconciler',
|
|
25
|
+
intervalMs: options.intervalMs,
|
|
26
|
+
run: () => this.reconcile(),
|
|
27
|
+
onError: err => console.warn('[dispatch-reconciler] cycle failed:', err),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
replaceConfig(validated) {
|
|
31
|
+
this.opts = {
|
|
32
|
+
...this.opts,
|
|
33
|
+
busyWaitBudgetMs: validated.server.dispatchBusyWaitBudgetMs,
|
|
34
|
+
maxAttempts: validated.server.dispatchReconcileMaxAttempts,
|
|
35
|
+
};
|
|
36
|
+
this.periodicRunner.reschedule(validated.server.dispatchReconcileIntervalMs);
|
|
37
|
+
}
|
|
38
|
+
start() {
|
|
39
|
+
this.periodicRunner.start();
|
|
40
|
+
}
|
|
41
|
+
stop() {
|
|
42
|
+
this.periodicRunner.stop();
|
|
43
|
+
}
|
|
44
|
+
async pollOnce() {
|
|
45
|
+
await this.periodicRunner.runOnce();
|
|
46
|
+
}
|
|
47
|
+
async reconcile() {
|
|
48
|
+
const tasks = await this.opts.taskStore.list({});
|
|
49
|
+
// 保护集只按状态划定:git/server 模式的登记不归本 poller 消费(git dev-fix 归本 poller、
|
|
50
|
+
// git QA 归 retryPendingGitReviewDispatches),但都不得被当成孤儿清掉
|
|
51
|
+
const protectedIds = new Set();
|
|
52
|
+
for (const task of tasks) {
|
|
53
|
+
if (task.status === 'review' || task.status === 'fixing')
|
|
54
|
+
protectedIds.add(task.id);
|
|
55
|
+
}
|
|
56
|
+
await this.pruneTrackers(protectedIds);
|
|
57
|
+
for (const task of tasks) {
|
|
58
|
+
if (isSpecStagePhase(task.phase))
|
|
59
|
+
continue;
|
|
60
|
+
try {
|
|
61
|
+
if (task.status === 'review' && task.reviewMode !== 'server') {
|
|
62
|
+
await this.reconcileReview(task);
|
|
63
|
+
}
|
|
64
|
+
else if (task.status === 'fixing' && task.reviewMode !== 'server') {
|
|
65
|
+
// fix 续派与评审平台无关:github 与 git 模式共用 REQUEST_CHANGES → continueSession('fix') 链路
|
|
66
|
+
await this.reconcileFix(task);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
console.warn(`[dispatch-reconciler] task ${task.id} reconcile failed:`, err);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// 删除跟踪状态前用新鲜单读复核;list() 在 readdir/单文件故障下会缺行,快照缺席不能当不活跃。
|
|
75
|
+
async pruneTrackers(protectedIds) {
|
|
76
|
+
const tracked = new Set([
|
|
77
|
+
...this.attempts.keys(),
|
|
78
|
+
...this.unboundSeen.keys(),
|
|
79
|
+
...this.opts.manager.listPendingDispatchRetries().keys(),
|
|
80
|
+
]);
|
|
81
|
+
for (const taskId of tracked) {
|
|
82
|
+
if (protectedIds.has(taskId))
|
|
83
|
+
continue;
|
|
84
|
+
const entrySnapshot = this.opts.manager.getPendingDispatchRetry(taskId);
|
|
85
|
+
let fresh;
|
|
86
|
+
try {
|
|
87
|
+
fresh = await this.opts.taskStore.get(taskId);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.warn(`[dispatch-reconciler] prune skipped for ${taskId} (task read failed):`, err);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// get() 的 null 是确定的 ENOENT(任务已删除),按孤儿清理;读取异常才 fail closed 保留
|
|
94
|
+
if (fresh && (fresh.status === 'review' || fresh.status === 'fixing'))
|
|
95
|
+
continue;
|
|
96
|
+
this.attempts.delete(taskId);
|
|
97
|
+
this.unboundSeen.delete(taskId);
|
|
98
|
+
if (entrySnapshot) {
|
|
99
|
+
this.opts.manager.clearPendingDispatchRetryIfMatches(taskId, {
|
|
100
|
+
agentId: entrySnapshot.agentId,
|
|
101
|
+
signalToken: entrySnapshot.signalToken,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async reconcileReview(task) {
|
|
107
|
+
const qaId = task.qaAgentId;
|
|
108
|
+
if (!qaId || !task.prNumber)
|
|
109
|
+
return;
|
|
110
|
+
const anchor = task.reviewHeadAnchorSha?.toLowerCase();
|
|
111
|
+
const head = task.latestHeadSha?.toLowerCase();
|
|
112
|
+
// 明确的 anchor≠head 才让位 push 事件路径;任一缺失时 push 路径可能永不触发(poller 的
|
|
113
|
+
// push 判定要求 latestHeadSha 在场),pending/hold 这类「确定欠一次派发」的分支须自行补齐
|
|
114
|
+
if (anchor !== undefined && head !== undefined && anchor !== head)
|
|
115
|
+
return;
|
|
116
|
+
const anchorMissing = anchor === undefined || head === undefined;
|
|
117
|
+
const qaState = await this.opts.agentStore.get(qaId);
|
|
118
|
+
const entry = this.opts.manager.getPendingDispatchRetry(task.id);
|
|
119
|
+
const observation = this.opts.statusStore.get(qaId);
|
|
120
|
+
// git 模式的 hold 恢复归 sweep(durable pending 在场,60s 重试);绑定丢失与送达后
|
|
121
|
+
// 静默失联没有 durable 凭据(成功路径已清 pending),必须由对账兜底,否则永久停在 review。
|
|
122
|
+
// anchor 缺失时 git 不经 gh 探测——补派内的平台 driver 会重新锚定并 fail loud
|
|
123
|
+
const gitMode = task.reviewMode === 'git';
|
|
124
|
+
if (qaState?.taskId !== task.id) {
|
|
125
|
+
const prev = this.unboundSeen.get(task.id);
|
|
126
|
+
const seen = prev !== undefined && prev.passToken === task.signalToken ? prev.seen + 1 : 1;
|
|
127
|
+
this.unboundSeen.set(task.id, { seen, passToken: task.signalToken });
|
|
128
|
+
if (seen < UNBOUND_DWELL_CYCLES)
|
|
129
|
+
return;
|
|
130
|
+
if (anchorMissing && !gitMode && !(await this.refreshMissingHead(task, qaId)))
|
|
131
|
+
return;
|
|
132
|
+
await this.redispatchReview(task, qaId, 'qa-unbound');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.unboundSeen.delete(task.id);
|
|
136
|
+
if (qaState.status === 'awaiting_human') {
|
|
137
|
+
if (gitMode)
|
|
138
|
+
return;
|
|
139
|
+
if (!isRecoverableQaDispatchHold(qaState))
|
|
140
|
+
return;
|
|
141
|
+
// 旧 pass 残留的 pending 不得给新 pass 的 hold 重放供相位/预算:先按代清掉
|
|
142
|
+
const holdEntry = entry?.kind === 'qa-recheck' && entry.signalToken === task.signalToken ? entry : undefined;
|
|
143
|
+
if (entry !== undefined && holdEntry === undefined) {
|
|
144
|
+
this.opts.manager.clearPendingDispatchRetryIfMatches(task.id, {
|
|
145
|
+
agentId: entry.agentId,
|
|
146
|
+
signalToken: entry.signalToken,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (anchorMissing && !(await this.refreshMissingHead(task, qaId)))
|
|
150
|
+
return;
|
|
151
|
+
await this.redispatchReview(task, qaId, 'hold-recoverable', holdEntry);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (entry?.kind === 'qa-recheck') {
|
|
155
|
+
if (entry.signalToken !== task.signalToken) {
|
|
156
|
+
this.opts.manager.clearPendingDispatchRetryIfMatches(task.id, {
|
|
157
|
+
agentId: entry.agentId,
|
|
158
|
+
signalToken: entry.signalToken,
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// 一条规则:pending 每周期要么被消费,要么计入等待预算——任何不可消费的原因
|
|
163
|
+
// (不可注入/探测失败/正等人回答/观测未更新)都不得让 dispatchBusyWaitBudgetMs 失去消费点。
|
|
164
|
+
// needInputAt 在场说明该回合正等人回答(不落 awaiting_human 且静止后探测可注入),
|
|
165
|
+
// 重投 review prompt 会覆盖问题——与无登记兜底同一门禁
|
|
166
|
+
const awaitingAnswer = qaState.needInputAt !== undefined;
|
|
167
|
+
if (awaitingAnswer || !canInjectObservation(observation) || !this.observationDrivesRetry(task, observation, entry.since)) {
|
|
168
|
+
await this.alertIfBudgetExhausted(task, entry, observation, qaId, awaitingAnswer);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (anchorMissing && !gitMode && !(await this.refreshMissingHead(task, qaId)))
|
|
172
|
+
return;
|
|
173
|
+
await this.redispatchReview(task, qaId, 'pending-busy-cleared', entry, {
|
|
174
|
+
since: entry.since,
|
|
175
|
+
...(entry.budgetAlerted === true ? { budgetAlerted: true } : {}),
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// 无登记兜底(含进程重启丢内存登记):PENDING_IDLE 必须晚于本 pass 的派发时刻,
|
|
180
|
+
// 否则 QA 换绑后残留的上一任务空闲观测会把刚启动的 review 当成卡住
|
|
181
|
+
if (observation.tmuxSessionStatus === 'present'
|
|
182
|
+
&& observation.reason === 'PENDING_IDLE'
|
|
183
|
+
&& canInjectObservation(observation)
|
|
184
|
+
&& observedAfter(observation, task.reviewDispatchedAt)
|
|
185
|
+
&& !qaState.needInputAt) {
|
|
186
|
+
if (anchorMissing && !gitMode && !(await this.refreshMissingHead(task, qaId)))
|
|
187
|
+
return;
|
|
188
|
+
await this.redispatchReview(task, qaId, 'stalled-idle');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async reconcileFix(task) {
|
|
192
|
+
const devId = task.agentId;
|
|
193
|
+
if (!devId)
|
|
194
|
+
return;
|
|
195
|
+
const entry = this.opts.manager.getPendingDispatchRetry(task.id);
|
|
196
|
+
const observation = this.opts.statusStore.get(devId);
|
|
197
|
+
if (entry?.kind === 'dev-fix') {
|
|
198
|
+
if (entry.signalToken !== task.signalToken) {
|
|
199
|
+
this.opts.manager.clearPendingDispatchRetryIfMatches(task.id, {
|
|
200
|
+
agentId: entry.agentId,
|
|
201
|
+
signalToken: entry.signalToken,
|
|
202
|
+
});
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
// 登记后 dev 可能进入 hold/换绑:pending 只证明欠一次投递,投递前仍要确认 pane 可安全承接
|
|
206
|
+
const devState = await this.opts.agentStore.get(devId);
|
|
207
|
+
if (devState?.taskId !== task.id) {
|
|
208
|
+
// 绑定丢失/改派后 continueSession 无从投递,而 fixing 任务受 prune 保护:
|
|
209
|
+
// 不能静默留着一笔无人可送的 fix,按有界升级交人工(重新绑定属操作员决定,不自动改派)
|
|
210
|
+
if (await this.consumeAttempt(task, devId, 'dev-fix-unbound'))
|
|
211
|
+
this.recordAttempt(task, task.signalToken);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// hold 本身在 UI 可见,无需再升级
|
|
215
|
+
if (devState.status === 'awaiting_human')
|
|
216
|
+
return;
|
|
217
|
+
// 与 review 侧同一条规则:不可消费即计入预算(不注入但有界升级)
|
|
218
|
+
const awaitingAnswer = devState.needInputAt !== undefined;
|
|
219
|
+
if (awaitingAnswer || !canInjectObservation(observation) || !this.observationDrivesRetry(task, observation, entry.since)) {
|
|
220
|
+
await this.alertIfBudgetExhausted(task, entry, observation, devId, awaitingAnswer);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
await this.recontinueFix(task, devId, 'dev-fix-pending', entry.signalToken);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
// 'waiting' 是派生视图态不落盘;兜底以「绑定 + 非 hold + 未在等用户输入 + 观察到持续静止」判定,
|
|
227
|
+
// needInputAt 在场说明 dev 正等人回答,重投 fix prompt 会覆盖问题
|
|
228
|
+
const devState = await this.opts.agentStore.get(devId);
|
|
229
|
+
if (devState?.taskId === task.id
|
|
230
|
+
&& devState.status !== 'awaiting_human'
|
|
231
|
+
&& !devState.needInputAt
|
|
232
|
+
&& observation.tmuxSessionStatus === 'present'
|
|
233
|
+
&& observation.reason === 'PENDING_IDLE'
|
|
234
|
+
&& canInjectObservation(observation)
|
|
235
|
+
&& observedAfter(observation, task.fixDispatchedAt)
|
|
236
|
+
&& task.signalToken !== undefined) {
|
|
237
|
+
await this.recontinueFix(task, devId, 'dev-fix-stalled-idle', task.signalToken);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// 阻塞态(working/STUCK_BUSY/PENDING_HUMAN/error 探测失败/非 runtime 前台)不可注入;
|
|
241
|
+
// 阻塞超预算发一次性 intervention,事件成功落盘才按登记代 CAS 锁存告警标志。
|
|
242
|
+
async alertIfBudgetExhausted(task, entry, observation, agentId, awaitingAnswer = false) {
|
|
243
|
+
if (entry.budgetAlerted || Date.now() - entry.since <= this.opts.busyWaitBudgetMs)
|
|
244
|
+
return;
|
|
245
|
+
const emitted = await this.emitIntervention(task, agentId, {
|
|
246
|
+
phase: 'dispatch-busy-budget-exhausted',
|
|
247
|
+
kind: entry.kind,
|
|
248
|
+
busySinceMs: entry.since,
|
|
249
|
+
observationStatus: observation.tmuxSessionStatus,
|
|
250
|
+
...(awaitingAnswer ? { blockedBy: 'need-input' } : {}),
|
|
251
|
+
...(observation.reason !== undefined ? { observationReason: observation.reason } : {}),
|
|
252
|
+
...(observation.runtimeStatusHint !== undefined ? { observationHint: observation.runtimeStatusHint } : {}),
|
|
253
|
+
note: `Agent ${agentId} has stayed busy/blocked/unreachable past the dispatch wait budget; the pending ${entry.kind} stays queued. ` +
|
|
254
|
+
'Inspect the pane (answer the agent question, resolve the dialog, interrupt the turn, or restore connectivity) ' +
|
|
255
|
+
'to let the reconciler dispatch it.',
|
|
256
|
+
});
|
|
257
|
+
if (emitted) {
|
|
258
|
+
this.opts.manager.markPendingDispatchRetryBudgetAlerted(task.id, {
|
|
259
|
+
agentId: entry.agentId,
|
|
260
|
+
signalToken: entry.signalToken,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// 尝试计数绑定当前 pass 世系:reconciler 自己的补派把新 token 记入 passToken 延续计数;
|
|
265
|
+
// 任何外部换代(push / 新一轮 fix / 手工重派 / legacy 无 token → 真实 token)都重置预算。
|
|
266
|
+
attemptsFor(task) {
|
|
267
|
+
const rec = this.attempts.get(task.id);
|
|
268
|
+
if (!rec)
|
|
269
|
+
return { count: 0, alerted: false };
|
|
270
|
+
if (rec.passToken !== task.signalToken) {
|
|
271
|
+
this.attempts.delete(task.id);
|
|
272
|
+
return { count: 0, alerted: false };
|
|
273
|
+
}
|
|
274
|
+
return rec;
|
|
275
|
+
}
|
|
276
|
+
async consumeAttempt(task, agentId, action) {
|
|
277
|
+
const rec = this.attemptsFor(task);
|
|
278
|
+
if (rec.count >= this.opts.maxAttempts) {
|
|
279
|
+
if (!rec.alerted) {
|
|
280
|
+
const recovery = action === 'dev-fix-unbound'
|
|
281
|
+
? `the dev agent is no longer bound to this task, so the queued fix has no deliverable target; re-assign the dev to task ${task.id} (or cancel/retry it). Do NOT use POST /tasks/:id/review — that routes to QA and would skip the requested changes.`
|
|
282
|
+
: action.startsWith('dev-fix')
|
|
283
|
+
? 'the dev is not on an awaiting_human hold, so use Restart REPL on the dev agent (it replays the persisted fix prompt) or cancel/retry the task; do NOT use POST /tasks/:id/review — that routes to QA and would skip the requested changes.'
|
|
284
|
+
: 'inspect the QA agent and redispatch manually (Resume the agent or POST /tasks/:id/review).';
|
|
285
|
+
const emitted = await this.emitIntervention(task, agentId, {
|
|
286
|
+
phase: 'dispatch-reconcile-attempts-exhausted',
|
|
287
|
+
action,
|
|
288
|
+
attempts: rec.count,
|
|
289
|
+
note: `Automatic redispatch for task ${task.id} was attempted ${rec.count} times without the pass completing; ${recovery}`,
|
|
290
|
+
});
|
|
291
|
+
if (emitted)
|
|
292
|
+
this.attempts.set(task.id, { ...rec, alerted: true });
|
|
293
|
+
}
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
recordAttempt(task, passToken) {
|
|
299
|
+
const rec = this.attemptsFor(task);
|
|
300
|
+
this.attempts.set(task.id, {
|
|
301
|
+
...rec,
|
|
302
|
+
count: rec.count + 1,
|
|
303
|
+
alerted: rec.alerted,
|
|
304
|
+
...(passToken !== undefined ? { passToken } : {}),
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
// 同一份空闲观测只驱动一次补派:补派自身的 stable-idle/pre-inject 判定比探测精细,
|
|
308
|
+
// 判忙重排后必须等到更新的观测再动手,否则每周期空转 release/acquire/token 轮换
|
|
309
|
+
observationDrivesRetry(task, observation, sinceMs) {
|
|
310
|
+
if (!freshObservation(observation, sinceMs))
|
|
311
|
+
return false;
|
|
312
|
+
const lastDispatchAtMs = this.attemptsFor(task).lastDispatchAtMs;
|
|
313
|
+
return lastDispatchAtMs === undefined || freshObservation(observation, lastDispatchAtMs);
|
|
314
|
+
}
|
|
315
|
+
// 水位线必须与本次 pass 同代落库:attemptsFor 见 passToken 不符即整条重置,
|
|
316
|
+
// 不带世系的记录会在下一次读取时连同水位线一起被当成外部换代抹掉
|
|
317
|
+
markDispatchAttempted(task) {
|
|
318
|
+
const rec = this.attemptsFor(task);
|
|
319
|
+
this.attempts.set(task.id, {
|
|
320
|
+
...rec,
|
|
321
|
+
...(task.signalToken !== undefined ? { passToken: task.signalToken } : {}),
|
|
322
|
+
lastDispatchAtMs: Date.now(),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
recordPassLineage(task, passToken) {
|
|
326
|
+
const rec = this.attemptsFor(task);
|
|
327
|
+
this.attempts.set(task.id, { ...rec, ...(passToken !== undefined ? { passToken } : {}) });
|
|
328
|
+
}
|
|
329
|
+
async livePassToken(taskId, fallback) {
|
|
330
|
+
try {
|
|
331
|
+
const fresh = await this.opts.taskStore.get(taskId);
|
|
332
|
+
return fresh?.signalToken ?? fallback;
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
console.warn(`[dispatch-reconciler] live pass read for ${taskId} failed; keeping decision-time lineage:`, err);
|
|
336
|
+
return fallback;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
// anchor/head 缺失是可达状态(首次 fetch 失败会被吞掉),沉默等待会让 pending/hold 永久搁浅:
|
|
340
|
+
// 有界地探测 live head,成功即放行(补派自身会重新锚定并持久化),失败计次直至升级 intervention。
|
|
341
|
+
async refreshMissingHead(task, agentId) {
|
|
342
|
+
if (!(await this.consumeAttempt(task, agentId, 'anchor-refresh')))
|
|
343
|
+
return false;
|
|
344
|
+
try {
|
|
345
|
+
await this.opts.manager.fetchPrHeadSha(task.id);
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
catch (err) {
|
|
349
|
+
this.recordAttempt(task, task.signalToken);
|
|
350
|
+
console.warn(`[dispatch-reconciler] head refresh for ${task.id} failed (anchor/latestHead missing):`, err);
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
async redispatchReview(task, qaId, action, entryAtDecision, pendingBudget) {
|
|
355
|
+
if (!(await this.consumeAttempt(task, qaId, action)))
|
|
356
|
+
return;
|
|
357
|
+
this.markDispatchAttempted(task);
|
|
358
|
+
const tokenAtDecision = task.signalToken;
|
|
359
|
+
// 相位:登记时记录的原始相位优先;无登记时首轮(round=0)意味着初次 review 从未完成,按 review 重放。
|
|
360
|
+
// 计轮:读持久化的 reviewRoundPending(该轮尚未入账),补派恰好补计一次,重启后依然成立
|
|
361
|
+
const qaPhase = entryAtDecision?.qaPhase ?? (task.reviewRound === 0 ? 'review' : undefined);
|
|
362
|
+
let result;
|
|
363
|
+
let armedToken;
|
|
364
|
+
try {
|
|
365
|
+
result = await this.opts.manager.dispatchReviewToQa(task.id, {
|
|
366
|
+
bumpRound: task.reviewRoundPending === true,
|
|
367
|
+
fromStatus: ['review'],
|
|
368
|
+
...(tokenAtDecision !== undefined ? { expectSignalToken: tokenAtDecision } : {}),
|
|
369
|
+
...(qaPhase !== undefined ? { qaPhase } : {}),
|
|
370
|
+
...(pendingBudget !== undefined ? { pendingBudget } : {}),
|
|
371
|
+
onPassArmed: (armed) => { armedToken = armed; },
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
catch (err) {
|
|
375
|
+
if (err instanceof ApiError && err.status === 409 && err.code !== undefined && NO_COUNT_API_CODES.has(err.code)) {
|
|
376
|
+
console.warn(`[dispatch-reconciler] redispatch ${task.id} (${action}) superseded by a concurrent pass: ${err.message}`);
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
// 失败前 dispatch 可能已自轮换 armed pass(如 handled hold 保持新 pass):世系必须记到
|
|
380
|
+
// 失败后的实际 token,否则下周期 attemptsFor 会当外部换代重置预算,持久 hold 永不达上限
|
|
381
|
+
this.recordAttempt(task, await this.livePassToken(task.id, tokenAtDecision));
|
|
382
|
+
console.warn(`[dispatch-reconciler] redispatch ${task.id} (${action}) failed:`, err);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
const after = this.opts.manager.getPendingDispatchRetry(task.id);
|
|
386
|
+
if (after?.kind === 'qa-recheck' && after.signalToken === tokenAtDecision) {
|
|
387
|
+
// 只剩本次决策时的旧登记(未被 startSession 消费/换代),按已消费清理
|
|
388
|
+
this.opts.manager.clearPendingDispatchRetryIfMatches(task.id, {
|
|
389
|
+
agentId: after.agentId,
|
|
390
|
+
signalToken: after.signalToken,
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
else if (after?.kind === 'qa-recheck') {
|
|
394
|
+
// 补派再次遇忙的内部重排:预算已随 armedToken fence 在登记时注入(since 保持原值),
|
|
395
|
+
// 借这一点区分外部 successor——它的登记必然是新鲜 since,绝不等于原登记的旧时刻
|
|
396
|
+
const internalRequeue = pendingBudget !== undefined
|
|
397
|
+
&& after.agentId === (entryAtDecision?.agentId ?? after.agentId)
|
|
398
|
+
&& after.since === pendingBudget.since;
|
|
399
|
+
if (internalRequeue) {
|
|
400
|
+
this.recordPassLineage(task, after.signalToken);
|
|
401
|
+
console.warn(`[dispatch-reconciler] redispatch ${task.id} (${action}) queued again (QA busy)`);
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
console.warn(`[dispatch-reconciler] redispatch ${task.id} (${action}) superseded by an external pass; leaving its pending untouched`);
|
|
405
|
+
}
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
// 返回值未必仍属本次 armed pass:await 窗口内 verdict/push 可接管(REQUEST_CHANGES 还会
|
|
409
|
+
// 切 fixing 并登记 dev-fix pending)。世系只延续到可证明是本次铸造的 pass 上,
|
|
410
|
+
// 否则连同预算一并作废——否则 review 补派的次数会挡住 successor(甚至另一 kind)的补投
|
|
411
|
+
if (result.signalToken !== undefined && result.signalToken === armedToken) {
|
|
412
|
+
this.recordAttempt(task, result.signalToken);
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
console.warn(`[dispatch-reconciler] redispatch ${task.id} (${action}) delivered but the pass was taken over ` +
|
|
416
|
+
`(status=${result.status}); dropping this lineage`);
|
|
417
|
+
this.attempts.delete(task.id);
|
|
418
|
+
}
|
|
419
|
+
await this.audit(task, qaId, action);
|
|
420
|
+
}
|
|
421
|
+
async recontinueFix(task, devId, action, expectedToken) {
|
|
422
|
+
if (!(await this.consumeAttempt(task, devId, action)))
|
|
423
|
+
return;
|
|
424
|
+
this.markDispatchAttempted(task);
|
|
425
|
+
let resumed = false;
|
|
426
|
+
try {
|
|
427
|
+
// fence 延伸到最终 paste:continueSession 的多个 await 之后 pass 仍可能换代,
|
|
428
|
+
// guardBeforeInject 在 composer/paste/Enter 各点复核,漂移即放弃投递
|
|
429
|
+
resumed = await this.opts.manager.continueSession(task.id, devId, 'fix', {
|
|
430
|
+
signalToken: expectedToken,
|
|
431
|
+
guardBeforeInject: async () => {
|
|
432
|
+
const fresh = await this.opts.taskStore.get(task.id);
|
|
433
|
+
return fresh?.status === 'fixing' && fresh.signalToken === expectedToken;
|
|
434
|
+
},
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
catch (err) {
|
|
438
|
+
this.recordAttempt(task, expectedToken);
|
|
439
|
+
console.warn(`[dispatch-reconciler] fix re-continue ${task.id} (${action}) failed:`, err);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (!resumed) {
|
|
443
|
+
// 门禁拒绝(绑定/状态/Workdir/fence)同样消耗额度:持久性拒绝必须走有界升级而非每周期无限重试
|
|
444
|
+
this.recordAttempt(task, expectedToken);
|
|
445
|
+
console.warn(`[dispatch-reconciler] fix re-continue ${task.id} (${action}) skipped by dispatch gates`);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
this.opts.manager.clearPendingDispatchRetryIfMatches(task.id, { agentId: devId, signalToken: expectedToken });
|
|
449
|
+
this.recordAttempt(task, expectedToken);
|
|
450
|
+
await this.audit(task, devId, action);
|
|
451
|
+
}
|
|
452
|
+
async audit(task, agentId, action) {
|
|
453
|
+
console.log(`[dispatch-reconciler] task ${task.id}: ${action} redispatched via standard entry (agent=${agentId})`);
|
|
454
|
+
try {
|
|
455
|
+
await this.opts.eventBus.emit({
|
|
456
|
+
id: '',
|
|
457
|
+
type: 'agent.recovered',
|
|
458
|
+
timestamp: new Date().toISOString(),
|
|
459
|
+
projectId: task.projectId,
|
|
460
|
+
agentId,
|
|
461
|
+
taskId: task.id,
|
|
462
|
+
data: { reason: 'dispatch-reconciled', action },
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
catch (err) {
|
|
466
|
+
console.warn(`[dispatch-reconciler] audit emit failed for ${task.id}:`, err);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
async emitIntervention(task, agentId, data) {
|
|
470
|
+
try {
|
|
471
|
+
await this.opts.eventBus.emit({
|
|
472
|
+
id: '',
|
|
473
|
+
type: 'human.intervention',
|
|
474
|
+
timestamp: new Date().toISOString(),
|
|
475
|
+
projectId: task.projectId,
|
|
476
|
+
agentId,
|
|
477
|
+
taskId: task.id,
|
|
478
|
+
data,
|
|
479
|
+
});
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
catch (err) {
|
|
483
|
+
console.warn(`[dispatch-reconciler] intervention emit failed for ${task.id}:`, err);
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
// 只有明确的 live-runtime 空闲观测(含设计认可的 PENDING_IDLE)可以解除欠投递;
|
|
489
|
+
// 探测失败(error/PANE_PROBE_FAILED)、非 runtime 前台、菜单/冻结忙碌一律 fail closed。
|
|
490
|
+
function canInjectObservation(observation) {
|
|
491
|
+
if (observation.tmuxSessionStatus !== 'present')
|
|
492
|
+
return false;
|
|
493
|
+
if (observation.paneState !== undefined && observation.paneState !== 'live-runtime')
|
|
494
|
+
return false;
|
|
495
|
+
if (observation.runtimeStatusHint === undefined)
|
|
496
|
+
return true;
|
|
497
|
+
return observation.runtimeStatusHint === 'pending' && observation.reason === 'PENDING_IDLE';
|
|
498
|
+
}
|
|
499
|
+
function freshObservation(observation, sinceMs) {
|
|
500
|
+
if (observation.observedAt === undefined)
|
|
501
|
+
return false;
|
|
502
|
+
const observedMs = Date.parse(observation.observedAt);
|
|
503
|
+
return Number.isFinite(observedMs) && observedMs > sinceMs;
|
|
504
|
+
}
|
|
505
|
+
function observedAfter(observation, isoAnchor) {
|
|
506
|
+
if (isoAnchor === undefined)
|
|
507
|
+
return false;
|
|
508
|
+
const anchorMs = Date.parse(isoAnchor);
|
|
509
|
+
if (!Number.isFinite(anchorMs))
|
|
510
|
+
return false;
|
|
511
|
+
return freshObservation(observation, anchorMs);
|
|
512
|
+
}
|
|
513
|
+
//# sourceMappingURL=dispatch-reconciler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-reconciler.js","sourceRoot":"","sources":["../../src/agent/dispatch-reconciler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,OAAO,EAGL,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AA8BtB,+CAA+C;AAC/C,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,0CAA0C;AAC1C,uDAAuD;AACvD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAElF,uEAAuE;AACvE,qEAAqE;AACrE,sDAAsD;AACtD,gDAAgD;AAChD,MAAM,OAAO,kBAAkB;IACZ,cAAc,CAAqB;IAC5C,IAAI,CAA4B;IAChC,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IACpD,yDAAyD;IACzD,kDAAkD;IAC1C,WAAW,GAAG,IAAI,GAAG,EAAgD,CAAC;IAE9E,YAAY,OAAkC;QAC5C,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACpB,IAAI,CAAC,cAAc,GAAG,IAAI,kBAAkB,CAAC;YAC3C,IAAI,EAAE,qBAAqB;YAC3B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE;YAC3B,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,GAAG,CAAC;SACzE,CAAC,CAAC;IACL,CAAC;IAED,aAAa,CAAC,SAAuB;QACnC,IAAI,CAAC,IAAI,GAAG;YACV,GAAG,IAAI,CAAC,IAAI;YACZ,gBAAgB,EAAE,SAAS,CAAC,MAAM,CAAC,wBAAwB;YAC3D,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,4BAA4B;SAC3D,CAAC;QACF,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK;QACH,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjD,iEAAiE;QACjE,wDAAwD;QACxD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC3C,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;oBAC7D,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;gBACnC,CAAC;qBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;oBACpE,8EAA8E;oBAC9E,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,EAAE,oBAAoB,EAAE,GAAG,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;IACH,CAAC;IAED,wDAAwD;IAChD,KAAK,CAAC,aAAa,CAAC,YAAyB;QACnD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS;YAC9B,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YACvB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;YAC1B,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE;SACzD,CAAC,CAAC;QACH,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;YACvC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;YACxE,IAAI,KAAuB,CAAC;YAC5B,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,2CAA2C,MAAM,sBAAsB,EAAE,GAAG,CAAC,CAAC;gBAC3F,SAAS;YACX,CAAC;YACD,6DAA6D;YAC7D,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC;gBAAE,SAAS;YAChF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,aAAa,EAAE,CAAC;gBAClB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kCAAkC,CAAC,MAAM,EAAE;oBAC3D,OAAO,EAAE,aAAa,CAAC,OAAO;oBAC9B,WAAW,EAAE,aAAa,CAAC,WAAW;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,IAAe;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,mBAAmB,EAAE,WAAW,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;QAC/C,6DAA6D;QAC7D,+DAA+D;QAC/D,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAC1E,MAAM,aAAa,GAAG,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,CAAC;QAEjE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpD,6DAA6D;QAC7D,2DAA2D;QAC3D,0DAA0D;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC;QAE1C,IAAI,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3F,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACrE,IAAI,IAAI,GAAG,oBAAoB;gBAAE,OAAO;YACxC,IAAI,aAAa,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAAE,OAAO;YACtF,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEjC,IAAI,OAAO,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;YACxC,IAAI,OAAO;gBAAE,OAAO;YACpB,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC;gBAAE,OAAO;YAClD,qDAAqD;YACrD,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;YAC7G,IAAI,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBACnD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kCAAkC,CAAC,IAAI,CAAC,EAAE,EAAE;oBAC5D,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;iBAC/B,CAAC,CAAC;YACL,CAAC;YACD,IAAI,aAAa,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAAE,OAAO;YAC1E,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QAED,IAAI,KAAK,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kCAAkC,CAAC,IAAI,CAAC,EAAE,EAAE;oBAC5D,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;iBAC/B,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,4CAA4C;YAC5C,8DAA8D;YAC9D,yDAAyD;YACzD,qCAAqC;YACrC,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC;YACzD,IAAI,cAAc,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzH,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;gBAClF,OAAO;YACT,CAAC;YACD,IAAI,aAAa,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAAE,OAAO;YACtF,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE;gBACrE,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjE,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,mDAAmD;QACnD,yCAAyC;QACzC,IACE,WAAW,CAAC,iBAAiB,KAAK,SAAS;eACxC,WAAW,CAAC,MAAM,KAAK,cAAc;eACrC,oBAAoB,CAAC,WAAW,CAAC;eACjC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,kBAAkB,CAAC;eACnD,CAAC,OAAO,CAAC,WAAW,EACvB,CAAC;YACD,IAAI,aAAa,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAAE,OAAO;YACtF,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,IAAe;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAErD,IAAI,KAAK,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kCAAkC,CAAC,IAAI,CAAC,EAAE,EAAE;oBAC5D,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;iBAC/B,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,2DAA2D;YAC3D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACvD,IAAI,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;gBACjC,uDAAuD;gBACvD,+CAA+C;gBAC/C,IAAI,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC;oBAAE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC1G,OAAO;YACT,CAAC;YACD,uBAAuB;YACvB,IAAI,QAAQ,CAAC,MAAM,KAAK,gBAAgB;gBAAE,OAAO;YACjD,sCAAsC;YACtC,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC;YAC1D,IAAI,cAAc,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzH,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;gBACnF,OAAO;YACT,CAAC;YACD,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QAED,8DAA8D;QAC9D,iDAAiD;QACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvD,IACE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE;eACzB,QAAQ,CAAC,MAAM,KAAK,gBAAgB;eACpC,CAAC,QAAQ,CAAC,WAAW;eACrB,WAAW,CAAC,iBAAiB,KAAK,SAAS;eAC3C,WAAW,CAAC,MAAM,KAAK,cAAc;eACrC,oBAAoB,CAAC,WAAW,CAAC;eACjC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC;eAChD,IAAI,CAAC,WAAW,KAAK,SAAS,EACjC,CAAC;YACD,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,iDAAiD;IACzC,KAAK,CAAC,sBAAsB,CAClC,IAAe,EACf,KAA2B,EAC3B,WAAmC,EACnC,OAAe,EACf,cAAc,GAAG,KAAK;QAEtB,IAAI,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QAC1F,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE;YACzD,KAAK,EAAE,gCAAgC;YACvC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,KAAK;YACxB,iBAAiB,EAAE,WAAW,CAAC,iBAAiB;YAChD,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtF,GAAG,CAAC,WAAW,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,WAAW,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1G,IAAI,EAAE,SAAS,OAAO,mFAAmF,KAAK,CAAC,IAAI,iBAAiB;gBAClI,gHAAgH;gBAChH,oCAAoC;SACvC,CAAC,CAAC;QACH,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,qCAAqC,CAAC,IAAI,CAAC,EAAE,EAAE;gBAC/D,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,kEAAkE;IAC1D,WAAW,CAAC,IAAe;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9C,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACtC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,IAAe,EAAE,OAAe,EAAE,MAAuB;QACpF,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;gBACjB,MAAM,QAAQ,GAAG,MAAM,KAAK,iBAAiB;oBAC3C,CAAC,CAAC,yHAAyH,IAAI,CAAC,EAAE,oHAAoH;oBACtP,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;wBAC5B,CAAC,CAAC,4OAA4O;wBAC9O,CAAC,CAAC,4FAA4F,CAAC;gBACnG,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE;oBACzD,KAAK,EAAE,uCAAuC;oBAC9C,MAAM;oBACN,QAAQ,EAAE,GAAG,CAAC,KAAK;oBACnB,IAAI,EAAE,iCAAiC,IAAI,CAAC,EAAE,kBAAkB,GAAG,CAAC,KAAK,uCAAuC,QAAQ,EAAE;iBAC3H,CAAC,CAAC;gBACH,IAAI,OAAO;oBAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,aAAa,CAAC,IAAe,EAAE,SAA6B;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE;YACzB,GAAG,GAAG;YACN,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC;YACpB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAC;IACL,CAAC;IAED,uDAAuD;IACvD,qDAAqD;IAC7C,sBAAsB,CAAC,IAAe,EAAE,WAAmC,EAAE,OAAe;QAClG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1D,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC;QACjE,OAAO,gBAAgB,KAAK,SAAS,IAAI,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC3F,CAAC;IAED,sDAAsD;IACtD,kCAAkC;IAC1B,qBAAqB,CAAC,IAAe;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE;YACzB,GAAG,GAAG;YACN,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,gBAAgB,EAAE,IAAI,CAAC,GAAG,EAAE;SAC7B,CAAC,CAAC;IACL,CAAC;IAEO,iBAAiB,CAAC,IAAe,EAAE,SAA6B;QACtE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,MAAc,EAAE,QAA4B;QACtE,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpD,OAAO,KAAK,EAAE,WAAW,IAAI,QAAQ,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,4CAA4C,MAAM,yCAAyC,EAAE,GAAG,CAAC,CAAC;YAC/G,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,iEAAiE;IACjE,8DAA8D;IACtD,KAAK,CAAC,kBAAkB,CAAC,IAAe,EAAE,OAAe;QAC/D,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAChF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,0CAA0C,IAAI,CAAC,EAAE,sCAAsC,EAAE,GAAG,CAAC,CAAC;YAC3G,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,IAAe,EACf,IAAY,EACZ,MAAuB,EACvB,eAAsC,EACtC,aAA0D;QAE1D,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO;QAC7D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC;QACzC,gEAAgE;QAChE,uDAAuD;QACvD,MAAM,OAAO,GAAG,eAAe,EAAE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC5F,IAAI,MAAiB,CAAC;QACtB,IAAI,UAA8B,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAAE;gBAC3D,SAAS,EAAE,IAAI,CAAC,kBAAkB,KAAK,IAAI;gBAC3C,UAAU,EAAE,CAAC,QAAQ,CAAC;gBACtB,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChF,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC;aAChD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChH,OAAO,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,EAAE,KAAK,MAAM,sCAAsC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACxH,OAAO;YACT,CAAC;YACD,iEAAiE;YACjE,0DAA0D;YAC1D,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,EAAE,KAAK,MAAM,WAAW,EAAE,GAAG,CAAC,CAAC;YACrF,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjE,IAAI,KAAK,EAAE,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,WAAW,KAAK,eAAe,EAAE,CAAC;YAC1E,4CAA4C;YAC5C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kCAAkC,CAAC,IAAI,CAAC,EAAE,EAAE;gBAC5D,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;YACxC,wDAAwD;YACxD,kDAAkD;YAClD,MAAM,eAAe,GAAG,aAAa,KAAK,SAAS;mBAC9C,KAAK,CAAC,OAAO,KAAK,CAAC,eAAe,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;mBAC7D,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC,KAAK,CAAC;YACzC,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,EAAE,KAAK,MAAM,0BAA0B,CAAC,CAAC;YACjG,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,oCAAoC,IAAI,CAAC,EAAE,KAAK,MAAM,iEAAiE,CAAC,CAAC;YACxI,CAAC;YACD,OAAO;QACT,CAAC;QACD,qEAAqE;QACrE,wDAAwD;QACxD,yDAAyD;QACzD,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAC1E,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CACV,oCAAoC,IAAI,CAAC,EAAE,KAAK,MAAM,0CAA0C;gBAChG,WAAW,MAAM,CAAC,MAAM,0BAA0B,CACnD,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,IAAe,EACf,KAAa,EACb,MAAuB,EACvB,aAAqB;QAErB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO;QAC9D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC;YACH,6DAA6D;YAC7D,wDAAwD;YACxD,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;gBACvE,WAAW,EAAE,aAAa;gBAC1B,iBAAiB,EAAE,KAAK,IAAI,EAAE;oBAC5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACrD,OAAO,KAAK,EAAE,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,KAAK,aAAa,CAAC;gBAC3E,CAAC;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,yCAAyC,IAAI,CAAC,EAAE,KAAK,MAAM,WAAW,EAAE,GAAG,CAAC,CAAC;YAC1F,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,wDAAwD;YACxD,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,yCAAyC,IAAI,CAAC,EAAE,KAAK,MAAM,6BAA6B,CAAC,CAAC;YACvG,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kCAAkC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,CAAC;QAC9G,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,IAAe,EAAE,OAAe,EAAE,MAAuB;QAC3E,OAAO,CAAC,GAAG,CAAC,8BAA8B,IAAI,CAAC,EAAE,KAAK,MAAM,2CAA2C,OAAO,GAAG,CAAC,CAAC;QACnH,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC5B,EAAE,EAAE,EAAE;gBACN,IAAI,EAAE,iBAAiB;gBACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO;gBACP,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,IAAI,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE;aAChD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,+CAA+C,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,IAAe,EAAE,OAAe,EAAE,IAA6B;QAC5F,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC5B,EAAE,EAAE,EAAE;gBACN,IAAI,EAAE,oBAAoB;gBAC1B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO;gBACP,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,IAAI;aACL,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,sDAAsD,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACpF,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED,uDAAuD;AACvD,oEAAoE;AACpE,SAAS,oBAAoB,CAAC,WAAmC;IAC/D,IAAI,WAAW,CAAC,iBAAiB,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,WAAW,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW,CAAC,SAAS,KAAK,cAAc;QAAE,OAAO,KAAK,CAAC;IAClG,IAAI,WAAW,CAAC,iBAAiB,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,WAAW,CAAC,iBAAiB,KAAK,SAAS,IAAI,WAAW,CAAC,MAAM,KAAK,cAAc,CAAC;AAC9F,CAAC;AAED,SAAS,gBAAgB,CAAC,WAAmC,EAAE,OAAe;IAC5E,IAAI,WAAW,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,OAAO,CAAC;AAC7D,CAAC;AAED,SAAS,aAAa,CAAC,WAAmC,EAAE,SAA6B;IACvF,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,gBAAgB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC"}
|