@router-agent/infra 0.3.31 → 0.3.32
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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin-install.d.ts +45 -0
- package/dist/plugin-install.js +240 -0
- package/dist/plugin-install.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ export * from './logger.js';
|
|
|
8
8
|
export * from './process.js';
|
|
9
9
|
export * from './chat.js';
|
|
10
10
|
export * from './plugin-loader.js';
|
|
11
|
+
export * from './plugin-install.js';
|
|
11
12
|
export { createVisionTranscriber, type ImageInput, type ImageTranscriber, type VisionModelConfig, } from './vision.js';
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/infra/src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,oBAAoB,CAAA;AAClC,OAAO,EACL,uBAAuB,GAIxB,MAAM,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/infra/src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,OAAO,EACL,uBAAuB,GAIxB,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type Logger } from './logger.js';
|
|
2
|
+
/** npm 执行器;测试里可以注入假的实现。 */
|
|
3
|
+
export type NpmRunner = (args: string[], opts: {
|
|
4
|
+
cwd: string;
|
|
5
|
+
env: NodeJS.ProcessEnv;
|
|
6
|
+
timeoutMs: number;
|
|
7
|
+
onLine: (line: string) => void;
|
|
8
|
+
}) => Promise<number>;
|
|
9
|
+
export interface PluginInstallOptions {
|
|
10
|
+
home: string;
|
|
11
|
+
/** 纯 npm 包名,不能是本地路径。 */
|
|
12
|
+
packageName: string;
|
|
13
|
+
/** 精确版本或 'latest';缺省 latest。 */
|
|
14
|
+
version?: string;
|
|
15
|
+
env?: NodeJS.ProcessEnv;
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
onLine?: (line: string) => void;
|
|
18
|
+
logger?: Logger;
|
|
19
|
+
/** 测试注入:执行 npm,返回退出码。 */
|
|
20
|
+
runNpm?: NpmRunner;
|
|
21
|
+
}
|
|
22
|
+
export interface PluginInstallResult {
|
|
23
|
+
ok: boolean;
|
|
24
|
+
version?: string;
|
|
25
|
+
log: string[];
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 从插件入口里取出 npm 包名。
|
|
30
|
+
*
|
|
31
|
+
* 本地路径(`./x` / `/x` / `file:`)、URL 和带空格的写法都返回 undefined;
|
|
32
|
+
* 调用方据此区分「需要安装」与「重启即可生效」。
|
|
33
|
+
*/
|
|
34
|
+
export declare function npmPackageNameOf(value: string): string | undefined;
|
|
35
|
+
/** npm 全局安装的同一套命令名:Windows 上是 npm.cmd。 */
|
|
36
|
+
export declare function npmBin(): string;
|
|
37
|
+
/** 读已安装包的版本;没装或 package.json 损坏时返回 null。 */
|
|
38
|
+
export declare function installedPluginVersion(home: string, packageName: string): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* 把 npm 包安装到 `<RA_HOME>/node_modules`。
|
|
41
|
+
*
|
|
42
|
+
* 安装完成后会用插件加载器同一套解析逻辑确认包能被找到;解析不到的包
|
|
43
|
+
* 即使用 npm 装上了,服务重启时也加载不了,所以这里按失败返回。
|
|
44
|
+
*/
|
|
45
|
+
export declare function installPluginPackage(opts: PluginInstallOptions): Promise<PluginInstallResult>;
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按 npm 包名安装运行时 / 通道插件。
|
|
3
|
+
*
|
|
4
|
+
* 插件加载器以 `<RA_HOME>/config.yaml` 为锚点解析包名,所以插件必须装在
|
|
5
|
+
* `<RA_HOME>/node_modules` 下;本模块负责把配置里声明的 npm 包下载到这里,
|
|
6
|
+
* 并校验装完以后加载器确实能解析到它。
|
|
7
|
+
*/
|
|
8
|
+
import { spawn } from 'node:child_process';
|
|
9
|
+
import { mkdirSync, readFileSync, rmSync, statSync } from 'node:fs';
|
|
10
|
+
import { join, resolve } from 'node:path';
|
|
11
|
+
import { errorMessage, noopLogger } from './logger.js';
|
|
12
|
+
import { defaultPluginLoader } from './plugin-loader.js';
|
|
13
|
+
const PACKAGE_NAME_PATTERN = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i;
|
|
14
|
+
const LOCK_STALE_MS = 10 * 60_000;
|
|
15
|
+
const MAX_LOG_LINES = 200;
|
|
16
|
+
const NPM_TIMEOUT_MS = 180_000;
|
|
17
|
+
/**
|
|
18
|
+
* 从插件入口里取出 npm 包名。
|
|
19
|
+
*
|
|
20
|
+
* 本地路径(`./x` / `/x` / `file:`)、URL 和带空格的写法都返回 undefined;
|
|
21
|
+
* 调用方据此区分「需要安装」与「重启即可生效」。
|
|
22
|
+
*/
|
|
23
|
+
export function npmPackageNameOf(value) {
|
|
24
|
+
const text = value.trim();
|
|
25
|
+
if (!text || text.startsWith('.') || text.startsWith('/') || text.startsWith('file:'))
|
|
26
|
+
return undefined;
|
|
27
|
+
if (text.includes('\\') || /\s/.test(text))
|
|
28
|
+
return undefined;
|
|
29
|
+
return PACKAGE_NAME_PATTERN.test(text) ? text : undefined;
|
|
30
|
+
}
|
|
31
|
+
/** 配置里的版本号:只做最基本的注入防护,具体合法版本交给 npm 校验。 */
|
|
32
|
+
function validVersion(version) {
|
|
33
|
+
const text = version?.trim() || 'latest';
|
|
34
|
+
if (text.startsWith('-') || /\s/.test(text))
|
|
35
|
+
return 'latest';
|
|
36
|
+
return text;
|
|
37
|
+
}
|
|
38
|
+
/** npm 全局安装的同一套命令名:Windows 上是 npm.cmd。 */
|
|
39
|
+
export function npmBin() {
|
|
40
|
+
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
41
|
+
}
|
|
42
|
+
function appendLog(log, line, onLine) {
|
|
43
|
+
const text = line.trimEnd();
|
|
44
|
+
if (!text)
|
|
45
|
+
return;
|
|
46
|
+
log.push(text);
|
|
47
|
+
if (log.length > MAX_LOG_LINES)
|
|
48
|
+
log.splice(0, log.length - MAX_LOG_LINES);
|
|
49
|
+
onLine?.(text);
|
|
50
|
+
}
|
|
51
|
+
function defaultRunNpm(args, opts) {
|
|
52
|
+
return new Promise(resolvePromise => {
|
|
53
|
+
let settled = false;
|
|
54
|
+
let timedOut = false;
|
|
55
|
+
const child = spawn(npmBin(), args, {
|
|
56
|
+
cwd: opts.cwd,
|
|
57
|
+
env: { ...process.env, ...opts.env },
|
|
58
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
59
|
+
detached: process.platform !== 'win32',
|
|
60
|
+
});
|
|
61
|
+
const finish = (code) => {
|
|
62
|
+
if (settled)
|
|
63
|
+
return;
|
|
64
|
+
settled = true;
|
|
65
|
+
clearTimeout(timer);
|
|
66
|
+
resolvePromise(code);
|
|
67
|
+
};
|
|
68
|
+
const timer = setTimeout(() => {
|
|
69
|
+
timedOut = true;
|
|
70
|
+
try {
|
|
71
|
+
if (process.platform === 'win32') {
|
|
72
|
+
child.kill('SIGKILL');
|
|
73
|
+
}
|
|
74
|
+
else if (child.pid) {
|
|
75
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// 进程可能已经退出,忽略即可。
|
|
80
|
+
}
|
|
81
|
+
finish(124);
|
|
82
|
+
}, opts.timeoutMs);
|
|
83
|
+
const pipe = (stream) => {
|
|
84
|
+
let buffer = '';
|
|
85
|
+
stream.setEncoding('utf8');
|
|
86
|
+
stream.on('data', (chunk) => {
|
|
87
|
+
buffer += chunk;
|
|
88
|
+
let index;
|
|
89
|
+
while ((index = buffer.indexOf('\n')) >= 0) {
|
|
90
|
+
opts.onLine(buffer.slice(0, index));
|
|
91
|
+
buffer = buffer.slice(index + 1);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
stream.on('end', () => {
|
|
95
|
+
if (buffer)
|
|
96
|
+
opts.onLine(buffer);
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
pipe(child.stdout);
|
|
100
|
+
pipe(child.stderr);
|
|
101
|
+
child.on('error', error => {
|
|
102
|
+
opts.onLine(`${error.message}${timedOut ? '(安装超时)' : ''}`);
|
|
103
|
+
finish(127);
|
|
104
|
+
});
|
|
105
|
+
child.on('close', code => finish(code ?? (timedOut ? 124 : 1)));
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/** 安装锁目录按包名区分;同名包不允许并发写入同一个 node_modules。 */
|
|
109
|
+
function lockDirOf(home, packageName) {
|
|
110
|
+
return join(home, '.plugin-install', `${packageName.replace(/[^a-z0-9-_.]/gi, '_')}.lock`);
|
|
111
|
+
}
|
|
112
|
+
function lockIsStale(path) {
|
|
113
|
+
try {
|
|
114
|
+
const info = JSON.parse(readFileSync(join(path, 'lock.json'), 'utf8'));
|
|
115
|
+
const startedAt = info.startedAt ? Date.parse(info.startedAt) : statSync(path).mtimeMs;
|
|
116
|
+
return !Number.isFinite(startedAt) || Date.now() - startedAt > LOCK_STALE_MS;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// 锁目录存在但没有 lock.json:按目录的 mtime 判断是否陈旧。
|
|
120
|
+
try {
|
|
121
|
+
return Date.now() - statSync(path).mtimeMs > LOCK_STALE_MS;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function acquireLock(home, packageName) {
|
|
129
|
+
mkdirSync(join(home, '.plugin-install'), { recursive: true });
|
|
130
|
+
const path = lockDirOf(home, packageName);
|
|
131
|
+
try {
|
|
132
|
+
mkdirSync(path);
|
|
133
|
+
return { path };
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
if (lockIsStale(path)) {
|
|
137
|
+
try {
|
|
138
|
+
rmSync(path, { recursive: true, force: true });
|
|
139
|
+
mkdirSync(path);
|
|
140
|
+
return { path };
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// 抢锁失败,继续走「已有安装任务」分支。
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return { path, error: `已有 ${packageName} 安装任务在进行` };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function releaseLock(path) {
|
|
150
|
+
rmSync(path, { recursive: true, force: true });
|
|
151
|
+
}
|
|
152
|
+
/** 读已安装包的版本;没装或 package.json 损坏时返回 null。 */
|
|
153
|
+
export function installedPluginVersion(home, packageName) {
|
|
154
|
+
try {
|
|
155
|
+
const pkg = JSON.parse(readFileSync(join(home, 'node_modules', packageName, 'package.json'), 'utf8'));
|
|
156
|
+
return typeof pkg.version === 'string' ? pkg.version : null;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// 目录不存在 / 只装了一半 / JSON 损坏都按未安装处理。
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** 最近几行 npm 输出用于日志 detail:不写完整 stderr,避免日志过大。 */
|
|
164
|
+
function failureDetail(log, code) {
|
|
165
|
+
const tail = log.filter(line => line.trim()).slice(-3).join(' | ');
|
|
166
|
+
const text = code === 124 ? 'npm install 超时' : `npm install 退出码 ${code}`;
|
|
167
|
+
return tail ? `${text}:${tail.slice(0, 300)}` : text;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 把 npm 包安装到 `<RA_HOME>/node_modules`。
|
|
171
|
+
*
|
|
172
|
+
* 安装完成后会用插件加载器同一套解析逻辑确认包能被找到;解析不到的包
|
|
173
|
+
* 即使用 npm 装上了,服务重启时也加载不了,所以这里按失败返回。
|
|
174
|
+
*/
|
|
175
|
+
export async function installPluginPackage(opts) {
|
|
176
|
+
const log = [];
|
|
177
|
+
const logger = opts.logger ?? noopLogger;
|
|
178
|
+
const packageName = npmPackageNameOf(opts.packageName);
|
|
179
|
+
if (!packageName) {
|
|
180
|
+
return { ok: false, log, error: `不是合法的 npm 包名:${opts.packageName}` };
|
|
181
|
+
}
|
|
182
|
+
const version = validVersion(opts.version);
|
|
183
|
+
const lock = acquireLock(opts.home, packageName);
|
|
184
|
+
if (lock.error)
|
|
185
|
+
return { ok: false, log, error: lock.error };
|
|
186
|
+
logger.info('plugin:install-started', { home: opts.home, package: packageName, version });
|
|
187
|
+
try {
|
|
188
|
+
mkdirSync(opts.home, { recursive: true });
|
|
189
|
+
appendLog(log, `安装 ${packageName}@${version} → ${join(opts.home, 'node_modules')}`, opts.onLine);
|
|
190
|
+
const run = opts.runNpm ?? defaultRunNpm;
|
|
191
|
+
const args = [
|
|
192
|
+
'install',
|
|
193
|
+
'--prefix', opts.home,
|
|
194
|
+
'--no-save',
|
|
195
|
+
'--no-package-lock',
|
|
196
|
+
'--no-audit',
|
|
197
|
+
'--no-fund',
|
|
198
|
+
'--ignore-scripts',
|
|
199
|
+
`${packageName}@${version}`,
|
|
200
|
+
];
|
|
201
|
+
const code = await run(args, {
|
|
202
|
+
cwd: opts.home,
|
|
203
|
+
env: opts.env ?? {},
|
|
204
|
+
timeoutMs: opts.timeoutMs ?? NPM_TIMEOUT_MS,
|
|
205
|
+
onLine: line => appendLog(log, line, opts.onLine),
|
|
206
|
+
});
|
|
207
|
+
if (code !== 0) {
|
|
208
|
+
const error = failureDetail(log, code);
|
|
209
|
+
logger.error('plugin:install-failed', { home: opts.home, package: packageName, version, detail: error });
|
|
210
|
+
return { ok: false, log, error };
|
|
211
|
+
}
|
|
212
|
+
const installedVersion = installedPluginVersion(opts.home, packageName);
|
|
213
|
+
if (!installedVersion) {
|
|
214
|
+
const error = `安装完成但 ${join(opts.home, 'node_modules', packageName)} 不存在`;
|
|
215
|
+
logger.error('plugin:install-failed', { home: opts.home, package: packageName, version, detail: error });
|
|
216
|
+
return { ok: false, log, error };
|
|
217
|
+
}
|
|
218
|
+
// 与插件加载器完全相同的解析路径:解析不到就等于重启后加载失败。
|
|
219
|
+
try {
|
|
220
|
+
defaultPluginLoader().resolve(packageName, resolve(opts.home, 'config.yaml'));
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
const detail = `安装完成但加载器解析不到 ${packageName}:${errorMessage(error)}`.slice(0, 300);
|
|
224
|
+
logger.error('plugin:install-failed', { home: opts.home, package: packageName, version, detail });
|
|
225
|
+
return { ok: false, log: [...log, detail], error: detail };
|
|
226
|
+
}
|
|
227
|
+
appendLog(log, `安装完成:${packageName}@${installedVersion}`, opts.onLine);
|
|
228
|
+
logger.info('plugin:install-succeeded', { home: opts.home, package: packageName, version: installedVersion });
|
|
229
|
+
return { ok: true, version: installedVersion, log };
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
const detail = errorMessage(error);
|
|
233
|
+
logger.error('plugin:install-failed', { home: opts.home, package: packageName, version, detail });
|
|
234
|
+
return { ok: false, log, error: detail };
|
|
235
|
+
}
|
|
236
|
+
finally {
|
|
237
|
+
releaseLock(lock.path);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=plugin-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-install.js","sourceRoot":"","sources":["../../../../packages/infra/src/plugin-install.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACnE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAe,MAAM,aAAa,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AA+BxD,MAAM,oBAAoB,GAAG,yDAAyD,CAAA;AACtF,MAAM,aAAa,GAAG,EAAE,GAAG,MAAM,CAAA;AACjC,MAAM,aAAa,GAAG,GAAG,CAAA;AACzB,MAAM,cAAc,GAAG,OAAO,CAAA;AAE9B;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IACzB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAA;IACvG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAA;IAC5D,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AAC3D,CAAC;AAED,0CAA0C;AAC1C,SAAS,YAAY,CAAC,OAA2B;IAC/C,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,QAAQ,CAAA;IACxC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC5D,OAAO,IAAI,CAAA;AACb,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,MAAM;IACpB,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAA;AACzD,CAAC;AAED,SAAS,SAAS,CAAC,GAAa,EAAE,IAAY,EAAE,MAA+B;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;IAC3B,IAAI,CAAC,IAAI;QAAE,OAAM;IACjB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACd,IAAI,GAAG,CAAC,MAAM,GAAG,aAAa;QAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,aAAa,CAAC,CAAA;IACzE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;AAChB,CAAC;AAED,SAAS,aAAa,CAAC,IAAc,EAAE,IAKtC;IACC,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,EAAE;QAClC,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE;YAClC,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE;YACpC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SACvC,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,CAAC,IAAY,EAAQ,EAAE;YACpC,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,cAAc,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC,CAAA;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,QAAQ,GAAG,IAAI,CAAA;YACf,IAAI,CAAC;gBACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;oBACjC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBACvB,CAAC;qBAAM,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;oBACrB,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,iBAAiB;YACnB,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,CAAA;QACb,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QAClB,MAAM,IAAI,GAAG,CAAC,MAA6B,EAAQ,EAAE;YACnD,IAAI,MAAM,GAAG,EAAE,CAAA;YACf,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YAC1B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAClC,MAAM,IAAI,KAAK,CAAA;gBACf,IAAI,KAAK,CAAA;gBACT,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;oBACnC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;gBAClC,CAAC;YACH,CAAC,CAAC,CAAA;YACF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACpB,IAAI,MAAM;oBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACjC,CAAC,CAAC,CAAA;QACJ,CAAC,CAAA;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAClB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAClB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;YACxB,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YAC1D,MAAM,CAAC,GAAG,CAAC,CAAA;QACb,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,6CAA6C;AAC7C,SAAS,SAAS,CAAC,IAAY,EAAE,WAAmB;IAClD,OAAO,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;AAC5F,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAA2B,CAAA;QAChG,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAA;QACtF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,aAAa,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;QACxC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,aAAa,CAAA;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,WAAmB;IACpD,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IACzC,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,CAAA;QACf,OAAO,EAAE,IAAI,EAAE,CAAA;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;gBAC9C,SAAS,CAAC,IAAI,CAAC,CAAA;gBACf,OAAO,EAAE,IAAI,EAAE,CAAA;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB;YACxB,CAAC;QACH,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,UAAU,EAAE,CAAA;IACrD,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AAChD,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,WAAmB;IACtE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAEnG,CAAA;QACD,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;QAClC,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,iDAAiD;AACjD,SAAS,aAAa,CAAC,GAAa,EAAE,IAAY;IAChD,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,mBAAmB,IAAI,EAAE,CAAA;IACxE,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAA0B;IACnE,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAA;IACxC,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,IAAI,CAAC,WAAW,EAAE,EAAE,CAAA;IACtE,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IAChD,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;IAE5D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;IACzF,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACzC,SAAS,CAAC,GAAG,EAAE,MAAM,WAAW,IAAI,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAChG,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,aAAa,CAAA;QACxC,MAAM,IAAI,GAAG;YACX,SAAS;YACT,UAAU,EAAE,IAAI,CAAC,IAAI;YACrB,WAAW;YACX,mBAAmB;YACnB,YAAY;YACZ,WAAW;YACX,kBAAkB;YAClB,GAAG,WAAW,IAAI,OAAO,EAAE;SAC5B,CAAA;QACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE;YAC3B,GAAG,EAAE,IAAI,CAAC,IAAI;YACd,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE;YACnB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,cAAc;YAC3C,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;SAClD,CAAC,CAAA;QACF,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YACtC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;YACxG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;QAClC,CAAC;QAED,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QACvE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,MAAM,CAAA;YACzE,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;YACxG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;QAClC,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC;YACH,mBAAmB,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAA;QAC/E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,gBAAgB,WAAW,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YACjF,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;YACjG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;QAC5D,CAAC;QAED,SAAS,CAAC,GAAG,EAAE,QAAQ,WAAW,IAAI,gBAAgB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QACtE,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAA;QAC7G,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAA;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QAClC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;QACjG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IAC1C,CAAC;YAAS,CAAC;QACT,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;AACH,CAAC"}
|