@modelprofile.com/flexharness 10.13.0 → 10.14.0

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@modelprofile.com/flexharness',
6
- version: '10.13.0',
6
+ version: '10.14.0',
7
7
  description: 'The FlexHarness toolbox source repository and shared dependency catalog.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSwrQkFBK0I7SUFDckMsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
@@ -0,0 +1,39 @@
1
+ import type { IFlexCodeModeLimits, IFlexCodeRunFailure, TJsonValue } from './interfaces.js';
2
+ /** What one catalog call of a program comes to: a JSON value, or the error the program sees. */
3
+ export type TFlexCodeCallOutcome = {
4
+ ok: true;
5
+ value: TJsonValue;
6
+ } | {
7
+ ok: false;
8
+ error: TJsonValue;
9
+ };
10
+ export interface IFlexCodeHost {
11
+ /**
12
+ * Runs one catalog call of the program; `signal` aborts when the program stops. A rejection is a
13
+ * failure of the host, which stops the program and rejects `run()` with it.
14
+ */
15
+ call(method: string, params: unknown, signal: AbortSignal): Promise<TFlexCodeCallOutcome>;
16
+ /** Milliseconds the program has waited for permission decisions; they do not count as wall time. */
17
+ waitedMs?(): number;
18
+ }
19
+ export type TFlexCodeRunResult = {
20
+ ok: true;
21
+ value: TJsonValue;
22
+ calls: number;
23
+ logs?: string;
24
+ } | {
25
+ ok: false;
26
+ failure: IFlexCodeRunFailure;
27
+ };
28
+ /**
29
+ * Runs `run_code` programs in QuickJS-ng compiled to WebAssembly: every program in a WebAssembly
30
+ * instance of its own, with no globals beyond the language, `api`, `ApiError` and `console`, and
31
+ * every limit of `IFlexCodeModeLimits` enforced. Program types are stripped with amaro first.
32
+ */
33
+ export declare class FlexCodeSandbox {
34
+ private readonly engine;
35
+ private constructor();
36
+ /** Loads QuickJS and amaro, once per process. */
37
+ static load(): Promise<FlexCodeSandbox>;
38
+ run(source: string, host: IFlexCodeHost, limits: Readonly<IFlexCodeModeLimits>, signal?: AbortSignal): Promise<TFlexCodeRunResult>;
39
+ }
@@ -0,0 +1,539 @@
1
+ import * as plugins from './plugins.js';
2
+ import { FlexHarnessValidationError } from './errors.js';
3
+ const programFile = 'program.ts';
4
+ /** How long calls in flight get to settle after their program stopped and their signal aborted. */
5
+ const stopGraceMs = 5_000;
6
+ const programPrefix = 'globalThis.__flexMain = async function () {\n';
7
+ const programSuffix = '\n};';
8
+ /**
9
+ * Runs in the context before the program: it takes the host functions off the global object and
10
+ * defines `api`, `ApiError` and `console`. Only strings cross the boundary.
11
+ */
12
+ const prelude = `'use strict';
13
+ (() => {
14
+ const call = globalThis.__flexCall;
15
+ const log = globalThis.__flexLog;
16
+ const done = globalThis.__flexDone;
17
+ delete globalThis.__flexCall;
18
+ delete globalThis.__flexLog;
19
+ delete globalThis.__flexDone;
20
+ class ApiError extends Error {
21
+ constructor(details) {
22
+ const message = details && typeof details.message === 'string' ? details.message : JSON.stringify(details);
23
+ super(message);
24
+ this.name = 'ApiError';
25
+ this.details = details;
26
+ }
27
+ }
28
+ const invoke = (path, args) => {
29
+ if (!path) return Promise.reject(new TypeError('Call a method as api.<namespace>.<method>(params).'));
30
+ let params;
31
+ try {
32
+ params = JSON.stringify(args.length === 0 || args[0] === undefined ? {} : args[0]);
33
+ } catch (error) {
34
+ return Promise.reject(new TypeError('The params of ' + path + ' are not JSON: ' + error.message));
35
+ }
36
+ return call(path, params === undefined ? 'null' : params).then((text) => {
37
+ const outcome = JSON.parse(text);
38
+ if (outcome.ok) return outcome.value;
39
+ throw new ApiError(outcome.error);
40
+ });
41
+ };
42
+ const target = (path) => new Proxy(function () {}, {
43
+ get: (_target, key) => typeof key === 'string' && key !== 'then' ? target(path ? path + '.' + key : key) : undefined,
44
+ apply: (_target, _this, args) => invoke(path, args),
45
+ set: () => false,
46
+ defineProperty: () => false,
47
+ deleteProperty: () => false,
48
+ });
49
+ const format = (value) => {
50
+ if (typeof value === 'string') return value;
51
+ try {
52
+ const text = JSON.stringify(value);
53
+ return text === undefined ? String(value) : text;
54
+ } catch {
55
+ return String(value);
56
+ }
57
+ };
58
+ const writer = (level) => (...values) => { log(level, values.map(format).join(' ')); };
59
+ const fixed = (value) => ({ value, enumerable: false, writable: false, configurable: false });
60
+ Object.defineProperty(globalThis, 'api', fixed(target('')));
61
+ Object.defineProperty(globalThis, 'ApiError', fixed(ApiError));
62
+ Object.defineProperty(globalThis, 'console', fixed(Object.freeze({
63
+ log: writer('log'), info: writer('info'), warn: writer('warn'), error: writer('error'), debug: writer('debug'),
64
+ })));
65
+ const settle = (value) => {
66
+ try {
67
+ const text = JSON.stringify({ ok: true, value: value === undefined ? null : value });
68
+ return text === undefined ? JSON.stringify({ ok: true, value: null }) : text;
69
+ } catch (error) {
70
+ return JSON.stringify({ ok: false, name: 'TypeError', message: 'The return value is not JSON: ' + error.message });
71
+ }
72
+ };
73
+ const fail = (error) => JSON.stringify({
74
+ ok: false,
75
+ name: error && typeof error.name === 'string' ? error.name : 'Error',
76
+ message: error && typeof error.message === 'string' ? error.message : String(error),
77
+ stack: error && typeof error.stack === 'string' ? error.stack : '',
78
+ ...(error instanceof ApiError ? { details: error.details } : {}),
79
+ });
80
+ Object.defineProperty(globalThis, '__flexStart', {
81
+ configurable: true,
82
+ value: () => {
83
+ const main = globalThis.__flexMain;
84
+ delete globalThis.__flexStart;
85
+ delete globalThis.__flexMain;
86
+ main().then(settle, fail).then(done);
87
+ },
88
+ });
89
+ })();
90
+ `;
91
+ let enginePromise;
92
+ /**
93
+ * Runs `run_code` programs in QuickJS-ng compiled to WebAssembly: every program in a WebAssembly
94
+ * instance of its own, with no globals beyond the language, `api`, `ApiError` and `console`, and
95
+ * every limit of `IFlexCodeModeLimits` enforced. Program types are stripped with amaro first.
96
+ */
97
+ export class FlexCodeSandbox {
98
+ engine;
99
+ constructor(engine) {
100
+ this.engine = engine;
101
+ }
102
+ /** Loads QuickJS and amaro, once per process. */
103
+ static async load() {
104
+ enginePromise ??= plugins.importCodeSandboxEngine().catch((error) => {
105
+ enginePromise = undefined;
106
+ throw new FlexHarnessValidationError('Code mode needs the optional peers quickjs-emscripten-core, '
107
+ + '@jitl/quickjs-ng-wasmfile-release-sync and amaro.', { cause: error });
108
+ });
109
+ return new FlexCodeSandbox(await enginePromise);
110
+ }
111
+ run(source, host, limits, signal) {
112
+ return new CodeRun(this.engine, source, host, limits, signal).start();
113
+ }
114
+ }
115
+ class CodeRun {
116
+ engine;
117
+ source;
118
+ host;
119
+ limits;
120
+ signal;
121
+ runtime;
122
+ vm;
123
+ deferreds = new Set();
124
+ calls = new AbortController();
125
+ queue = [];
126
+ /** Host calls in flight; the run settles only after every one of them did. */
127
+ inFlight = new Set();
128
+ running = 0;
129
+ callCount = 0;
130
+ cpuMs = 0;
131
+ enteredAt;
132
+ stop;
133
+ logs = '';
134
+ logBytes = 0;
135
+ logsCut = false;
136
+ settle;
137
+ reject;
138
+ /** The outcome is decided; the run waits for its calls in flight, then settles. */
139
+ closing = false;
140
+ finished = false;
141
+ broken = false;
142
+ wallTimer;
143
+ startedAt = performance.now();
144
+ constructor(engine, source, host, limits, signal) {
145
+ this.engine = engine;
146
+ this.source = source;
147
+ this.host = host;
148
+ this.limits = limits;
149
+ this.signal = signal;
150
+ }
151
+ async start() {
152
+ if (Buffer.byteLength(this.source, 'utf8') > this.limits.maxSourceBytes) {
153
+ return this.failure({
154
+ error: 'limit_exceeded',
155
+ limit: 'source',
156
+ message: `The program is longer than ${this.limits.maxSourceBytes} bytes.`,
157
+ });
158
+ }
159
+ try {
160
+ this.program = this.engine.stripTypes(`${programPrefix}${this.source}${programSuffix}`);
161
+ }
162
+ catch (error) {
163
+ const reported = (error ?? {});
164
+ return this.failure({
165
+ error: 'syntax_error',
166
+ message: typeof reported.message === 'string' ? reported.message : 'The program cannot be parsed.',
167
+ ...(typeof reported.startLine === 'number' && reported.startLine > 1 ? { line: reported.startLine - 1 } : {}),
168
+ });
169
+ }
170
+ const outcome = new Promise((resolve, reject) => {
171
+ this.settle = resolve;
172
+ this.reject = reject;
173
+ });
174
+ const onAbort = () => this.halt({ kind: 'aborted', message: 'The program was stopped.' });
175
+ this.signal?.addEventListener('abort', onAbort, { once: true });
176
+ try {
177
+ const module = await this.engine.newModule();
178
+ // QuickJS runs on the host's stack too: start it from a fresh, shallow one.
179
+ await new Promise((resolve) => setImmediate(resolve));
180
+ if (this.signal?.aborted)
181
+ onAbort();
182
+ else {
183
+ this.armWallTimer();
184
+ this.boot(module);
185
+ }
186
+ return await outcome;
187
+ }
188
+ finally {
189
+ this.signal?.removeEventListener('abort', onAbort);
190
+ this.dispose();
191
+ }
192
+ }
193
+ program = '';
194
+ boot(module) {
195
+ const runtime = module.newRuntime();
196
+ this.runtime = runtime;
197
+ runtime.setMemoryLimit(this.limits.memoryBytes);
198
+ runtime.setMaxStackSize(this.limits.stackBytes);
199
+ runtime.setInterruptHandler(() => this.interrupted());
200
+ const vm = runtime.newContext();
201
+ this.vm = vm;
202
+ this.define('__flexCall', (pathHandle, paramsHandle) => this.bridgeCall(vm.getString(pathHandle), vm.getString(paramsHandle)));
203
+ this.define('__flexLog', (levelHandle, textHandle) => {
204
+ this.log(vm.getString(levelHandle), vm.getString(textHandle));
205
+ });
206
+ this.define('__flexDone', (textHandle) => {
207
+ this.complete(vm.getString(textHandle));
208
+ });
209
+ if (!this.evaluate(prelude, 'prelude.js', 'prelude'))
210
+ return;
211
+ if (!this.evaluate(this.program, programFile, 'parse'))
212
+ return;
213
+ if (!this.evaluate('__flexStart();', 'start.js', 'program'))
214
+ return;
215
+ this.pump();
216
+ }
217
+ define(name, implementation) {
218
+ const handle = this.vm.newFunction(name, implementation);
219
+ this.vm.setProp(this.vm.global, name, handle);
220
+ handle.dispose();
221
+ }
222
+ evaluate(code, file, phase) {
223
+ if (this.closing)
224
+ return false;
225
+ let result;
226
+ this.enter();
227
+ try {
228
+ result = this.vm.evalCode(code, file);
229
+ }
230
+ catch (error) {
231
+ this.hostThrow(error);
232
+ return false;
233
+ }
234
+ finally {
235
+ this.leave();
236
+ }
237
+ if (result.error) {
238
+ this.failWith(result.error, phase);
239
+ return false;
240
+ }
241
+ result.value.dispose();
242
+ return true;
243
+ }
244
+ /** Runs the program's pending jobs after a call settled or the program started. */
245
+ pump() {
246
+ if (this.closing || !this.runtime?.alive)
247
+ return;
248
+ let result;
249
+ this.enter();
250
+ try {
251
+ result = this.runtime.executePendingJobs();
252
+ }
253
+ catch (error) {
254
+ this.hostThrow(error);
255
+ return;
256
+ }
257
+ finally {
258
+ this.leave();
259
+ }
260
+ if (result.error)
261
+ this.failWith(result.error, 'program');
262
+ }
263
+ /**
264
+ * An exception out of the WebAssembly instance: the host's stack ran out under deep recursion, or
265
+ * the instance failed. Its state is not trusted afterwards; `dispose()` abandons it.
266
+ */
267
+ hostThrow(error) {
268
+ this.broken = true;
269
+ if (error instanceof RangeError) {
270
+ this.halt({ kind: 'limit', limit: 'stack', message: 'The program exceeded its stack.' });
271
+ return;
272
+ }
273
+ this.halt({ kind: 'host', error });
274
+ }
275
+ enter() {
276
+ this.enteredAt = performance.now();
277
+ }
278
+ leave() {
279
+ if (this.enteredAt === undefined)
280
+ return;
281
+ this.cpuMs += performance.now() - this.enteredAt;
282
+ this.enteredAt = undefined;
283
+ }
284
+ interrupted() {
285
+ if (this.stop)
286
+ return true;
287
+ if (this.enteredAt !== undefined && this.cpuMs + performance.now() - this.enteredAt > this.limits.cpuMs) {
288
+ this.stop = { kind: 'limit', limit: 'cpu', message: `The program computed for more than ${this.limits.cpuMs} ms.` };
289
+ return true;
290
+ }
291
+ return false;
292
+ }
293
+ bridgeCall(method, paramsText) {
294
+ const deferred = this.vm.newPromise();
295
+ this.deferreds.add(deferred);
296
+ this.callCount += 1;
297
+ if (this.callCount > this.limits.maxCalls) {
298
+ this.halt({
299
+ kind: 'limit',
300
+ limit: 'calls',
301
+ message: `The program made more than ${this.limits.maxCalls} calls.`,
302
+ });
303
+ return deferred.handle;
304
+ }
305
+ let params;
306
+ try {
307
+ params = JSON.parse(paramsText);
308
+ }
309
+ catch {
310
+ params = undefined;
311
+ }
312
+ const run = () => {
313
+ if (this.closing)
314
+ return;
315
+ this.running += 1;
316
+ // A settled call stops counting before the program sees its answer, which may end the program.
317
+ const settled = () => {
318
+ this.running -= 1;
319
+ this.inFlight.delete(call);
320
+ };
321
+ const call = this.host.call(method, params, this.calls.signal).then((outcome) => {
322
+ settled();
323
+ this.answer(deferred, outcome);
324
+ }, (error) => {
325
+ settled();
326
+ this.halt({ kind: 'host', error });
327
+ }).finally(() => this.queue.shift()?.());
328
+ this.inFlight.add(call);
329
+ };
330
+ if (this.running < this.limits.maxConcurrentCalls)
331
+ run();
332
+ else
333
+ this.queue.push(run);
334
+ return deferred.handle;
335
+ }
336
+ answer(deferred, outcome) {
337
+ if (this.closing || !deferred.alive)
338
+ return;
339
+ let text;
340
+ try {
341
+ text = JSON.stringify(outcome);
342
+ }
343
+ catch {
344
+ text = JSON.stringify({ ok: false, error: { error: 'failed', message: 'The result is not JSON.' } });
345
+ }
346
+ const value = this.vm.newString(text);
347
+ deferred.resolve(value);
348
+ value.dispose();
349
+ this.deferreds.delete(deferred);
350
+ this.pump();
351
+ }
352
+ log(level, text) {
353
+ if (this.logsCut || this.closing)
354
+ return;
355
+ const line = `${level === 'log' ? '' : `[${level}] `}${text}\n`;
356
+ const bytes = Buffer.byteLength(line, 'utf8');
357
+ if (this.logBytes + bytes > this.limits.maxLogBytes) {
358
+ this.logsCut = true;
359
+ this.logs += '[console output cut off]\n';
360
+ return;
361
+ }
362
+ this.logBytes += bytes;
363
+ this.logs += line;
364
+ }
365
+ complete(text) {
366
+ if (this.closing)
367
+ return;
368
+ let outcome;
369
+ try {
370
+ outcome = JSON.parse(text);
371
+ }
372
+ catch {
373
+ outcome = { ok: false, name: 'Error', message: 'The program ended without a result.' };
374
+ }
375
+ if (outcome.ok) {
376
+ const unawaited = this.running + this.queue.length;
377
+ if (unawaited > 0) {
378
+ // Calls the program did not await are not part of its result: it fails, and proposes nothing.
379
+ this.done(this.failure({
380
+ error: 'program_error',
381
+ message: `The program returned with ${unawaited} call${unawaited === 1 ? '' : 's'} it did not await; await every call.`,
382
+ }));
383
+ return;
384
+ }
385
+ this.done({
386
+ ok: true,
387
+ value: outcome.value ?? null,
388
+ calls: Math.min(this.callCount, this.limits.maxCalls),
389
+ ...(this.logs ? { logs: this.logs } : {}),
390
+ });
391
+ return;
392
+ }
393
+ this.done(this.failure(this.classify(outcome, 'program')));
394
+ }
395
+ failWith(handle, phase) {
396
+ let dumped;
397
+ // Reading the thrown value can run program code, such as a toJSON: it counts as computing.
398
+ this.enter();
399
+ try {
400
+ dumped = this.vm.dump(handle);
401
+ }
402
+ catch (error) {
403
+ if (!(error instanceof Error) || error instanceof RangeError)
404
+ this.broken = true;
405
+ dumped = undefined;
406
+ }
407
+ finally {
408
+ this.leave();
409
+ if (!this.broken && handle.alive)
410
+ handle.dispose();
411
+ }
412
+ if (phase === 'prelude' && !this.stop) {
413
+ this.halt({ kind: 'host', error: new Error(`The code mode prelude failed: ${JSON.stringify(dumped)}`) });
414
+ return;
415
+ }
416
+ const error = (dumped && typeof dumped === 'object' ? dumped : { message: String(dumped) });
417
+ this.done(this.failure(this.classify(error, phase)));
418
+ }
419
+ classify(error, phase) {
420
+ if (this.stop?.kind === 'limit')
421
+ return { error: 'limit_exceeded', limit: this.stop.limit, message: this.stop.message };
422
+ if (this.stop?.kind === 'aborted')
423
+ return { error: 'aborted', message: this.stop.message };
424
+ const message = typeof error.message === 'string' ? error.message : 'The program failed.';
425
+ if (error.name === 'InternalError' && message === 'out of memory') {
426
+ return { error: 'limit_exceeded', limit: 'memory', message: `The program used more than ${this.limits.memoryBytes} bytes of memory.` };
427
+ }
428
+ if ((error.name === 'InternalError' && message === 'stack overflow')
429
+ || (error.name === 'RangeError' && message === 'Maximum call stack size exceeded')) {
430
+ return { error: 'limit_exceeded', limit: 'stack', message: 'The program exceeded its stack.' };
431
+ }
432
+ if (error.name === 'InternalError' && message === 'interrupted') {
433
+ return { error: 'limit_exceeded', limit: 'cpu', message: `The program computed for more than ${this.limits.cpuMs} ms.` };
434
+ }
435
+ const line = /program\.ts:(\d+)/.exec(error.stack ?? '')?.[1];
436
+ return {
437
+ error: phase === 'parse' && error.name === 'SyntaxError' ? 'syntax_error' : 'program_error',
438
+ ...(typeof error.name === 'string' ? { name: error.name } : {}),
439
+ message,
440
+ ...(line && Number(line) > 1 ? { line: Number(line) - 1 } : {}),
441
+ };
442
+ }
443
+ failure(failure) {
444
+ return {
445
+ ok: false,
446
+ failure: {
447
+ ...failure,
448
+ calls: Math.min(this.callCount, this.limits.maxCalls),
449
+ ...(this.logs ? { logs: this.logs } : {}),
450
+ },
451
+ };
452
+ }
453
+ /** Stops the program from outside it: a limit, an abort, or a failure of the host. */
454
+ halt(stop) {
455
+ if (this.closing)
456
+ return;
457
+ this.stop ??= stop;
458
+ const reason = this.stop;
459
+ if (reason.kind === 'host') {
460
+ this.close(() => this.reject(reason.error));
461
+ return;
462
+ }
463
+ this.done(this.failure(reason.kind === 'limit'
464
+ ? { error: 'limit_exceeded', limit: reason.limit, message: reason.message }
465
+ : { error: 'aborted', message: reason.message }));
466
+ }
467
+ done(result) {
468
+ this.close(() => this.settle(result));
469
+ }
470
+ /**
471
+ * Decides the run's outcome. Calls not started yet never start. Calls in flight are told to stop
472
+ * through their signal, and the outcome is delivered once they settled, so no call runs on after
473
+ * its program; a host call that ignores its signal gets `stopGraceMs`, and its answer is dropped.
474
+ */
475
+ close(deliver) {
476
+ if (this.closing)
477
+ return;
478
+ this.closing = true;
479
+ this.queue.length = 0;
480
+ if (this.inFlight.size === 0) {
481
+ this.finished = true;
482
+ deliver();
483
+ return;
484
+ }
485
+ this.calls.abort();
486
+ let grace;
487
+ void Promise.race([
488
+ Promise.allSettled([...this.inFlight]),
489
+ new Promise((resolve) => {
490
+ grace = setTimeout(resolve, stopGraceMs);
491
+ }),
492
+ ]).then(() => {
493
+ clearTimeout(grace);
494
+ this.finished = true;
495
+ deliver();
496
+ });
497
+ }
498
+ armWallTimer() {
499
+ const check = () => {
500
+ if (this.closing)
501
+ return;
502
+ const elapsed = performance.now() - this.startedAt - (this.host.waitedMs?.() ?? 0);
503
+ if (elapsed > this.limits.wallMs) {
504
+ this.halt({ kind: 'limit', limit: 'wall', message: `The program ran for more than ${this.limits.wallMs} ms.` });
505
+ return;
506
+ }
507
+ this.wallTimer = setTimeout(check, Math.max(10, Math.min(250, this.limits.wallMs - elapsed)));
508
+ };
509
+ this.wallTimer = setTimeout(check, Math.max(10, Math.min(250, this.limits.wallMs)));
510
+ }
511
+ /**
512
+ * Frees the program's runtime. An instance that threw, or whose runtime cannot be freed after a
513
+ * stack overflow left objects behind, is abandoned instead: it is the program's own, and garbage
514
+ * collection reclaims its memory.
515
+ */
516
+ dispose() {
517
+ this.closing = true;
518
+ this.finished = true;
519
+ if (this.wallTimer)
520
+ clearTimeout(this.wallTimer);
521
+ this.queue.length = 0;
522
+ this.calls.abort();
523
+ if (this.broken)
524
+ return;
525
+ try {
526
+ for (const deferred of this.deferreds)
527
+ if (deferred.alive)
528
+ deferred.dispose();
529
+ this.deferreds.clear();
530
+ this.vm?.dispose();
531
+ if (this.runtime?.alive)
532
+ this.runtime.dispose();
533
+ }
534
+ catch {
535
+ this.broken = true;
536
+ }
537
+ }
538
+ }
539
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb2Rlc2FuZGJveC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuY29kZXNhbmRib3gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBeUJ6RCxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUM7QUFDakMsbUdBQW1HO0FBQ25HLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQztBQUkxQixNQUFNLGFBQWEsR0FBRywrQ0FBK0MsQ0FBQztBQUN0RSxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUM7QUFFN0I7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQThFZixDQUFDO0FBRUYsSUFBSSxhQUE4RCxDQUFDO0FBRW5FOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUNXO0lBQXJDLFlBQXFDLE1BQWtDO1FBQWxDLFdBQU0sR0FBTixNQUFNLENBQTRCO0lBQUcsQ0FBQztJQUUzRSxpREFBaUQ7SUFDMUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJO1FBQ3RCLGFBQWEsS0FBSyxPQUFPLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFjLEVBQUUsRUFBRTtZQUMzRSxhQUFhLEdBQUcsU0FBUyxDQUFDO1lBQzFCLE1BQU0sSUFBSSwwQkFBMEIsQ0FDbEMsOERBQThEO2tCQUMxRCxtREFBbUQsRUFDdkQsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQ2pCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sSUFBSSxlQUFlLENBQUMsTUFBTSxhQUFhLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRU0sR0FBRyxDQUNSLE1BQWMsRUFDZCxJQUFtQixFQUNuQixNQUFxQyxFQUNyQyxNQUFvQjtRQUVwQixPQUFPLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDeEUsQ0FBQztDQUNGO0FBRUQsTUFBTSxPQUFPO0lBMEJRO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUE3QlgsT0FBTyxDQUEyQjtJQUNsQyxFQUFFLENBQTJCO0lBQ3BCLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBbUMsQ0FBQztJQUN2RCxLQUFLLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUM5QixLQUFLLEdBQXNCLEVBQUUsQ0FBQztJQUMvQyw4RUFBOEU7SUFDN0QsUUFBUSxHQUFHLElBQUksR0FBRyxFQUFpQixDQUFDO0lBQzdDLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDWixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNWLFNBQVMsQ0FBVTtJQUNuQixJQUFJLENBQVM7SUFDYixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ1YsUUFBUSxHQUFHLENBQUMsQ0FBQztJQUNiLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDaEIsTUFBTSxDQUF3QztJQUM5QyxNQUFNLENBQTRCO0lBQzFDLG1GQUFtRjtJQUMzRSxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQ2hCLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDakIsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUNmLFNBQVMsQ0FBaUM7SUFDakMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUUvQyxZQUNtQixNQUFrQyxFQUNsQyxNQUFjLEVBQ2QsSUFBbUIsRUFDbkIsTUFBcUMsRUFDckMsTUFBK0I7UUFKL0IsV0FBTSxHQUFOLE1BQU0sQ0FBNEI7UUFDbEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFNBQUksR0FBSixJQUFJLENBQWU7UUFDbkIsV0FBTSxHQUFOLE1BQU0sQ0FBK0I7UUFDckMsV0FBTSxHQUFOLE1BQU0sQ0FBeUI7SUFDL0MsQ0FBQztJQUVHLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUNsQixLQUFLLEVBQUUsZ0JBQWdCO2dCQUN2QixLQUFLLEVBQUUsUUFBUTtnQkFDZixPQUFPLEVBQUUsOEJBQThCLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxTQUFTO2FBQzNFLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDRCxJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsYUFBYSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsYUFBYSxFQUFFLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sUUFBUSxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBd0IsQ0FBQztZQUN0RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQ2xCLEtBQUssRUFBRSxjQUFjO2dCQUNyQixPQUFPLEVBQUUsT0FBTyxRQUFRLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsK0JBQStCO2dCQUNsRyxHQUFHLENBQUMsT0FBTyxRQUFRLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2FBQzlHLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBcUIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDbEUsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUM7WUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDdkIsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsQ0FBQyxDQUFDO1FBQzFGLElBQUksQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUM3Qyw0RUFBNEU7WUFDNUUsTUFBTSxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDNUQsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU87Z0JBQUUsT0FBTyxFQUFFLENBQUM7aUJBQy9CLENBQUM7Z0JBQ0osSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BCLENBQUM7WUFDRCxPQUFPLE1BQU0sT0FBTyxDQUFDO1FBQ3ZCLENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksQ0FBQyxNQUFNLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ25ELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDO0lBQ0gsQ0FBQztJQUVPLE9BQU8sR0FBRyxFQUFFLENBQUM7SUFFYixJQUFJLENBQUMsTUFBOEI7UUFDekMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLE9BQU8sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNoRCxPQUFPLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEQsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsVUFBVSxFQUFFLFlBQVksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9ILElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxFQUFFO1lBQ25ELElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLFVBQVUsRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLENBQUM7WUFBRSxPQUFPO1FBQzdELElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQztZQUFFLE9BQU87UUFDL0QsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQztZQUFFLE9BQU87UUFDcEUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVPLE1BQU0sQ0FBQyxJQUFZLEVBQUUsY0FBb0Y7UUFDL0csTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxFQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNoRCxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVPLFFBQVEsQ0FBQyxJQUFZLEVBQUUsSUFBWSxFQUFFLEtBQWE7UUFDeEQsSUFBSSxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQy9CLElBQUksTUFBOEIsQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDYixJQUFJLENBQUM7WUFDSCxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0QixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNmLENBQUM7UUFDRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNqQixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkMsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN2QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxtRkFBbUY7SUFDM0UsSUFBSTtRQUNWLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSztZQUFFLE9BQU87UUFDakQsSUFBSSxNQUEwQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDN0MsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RCLE9BQU87UUFDVCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDZixDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsS0FBSztZQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssU0FBUyxDQUFDLEtBQWM7UUFDOUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxLQUFLLFlBQVksVUFBVSxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsQ0FBQyxDQUFDO1lBQ3pGLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRU8sS0FBSztRQUNYLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3JDLENBQUM7SUFFTyxLQUFLO1FBQ1gsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVM7WUFBRSxPQUFPO1FBQ3pDLElBQUksQ0FBQyxLQUFLLElBQUksV0FBVyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDakQsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7SUFDN0IsQ0FBQztJQUVPLFdBQVc7UUFDakIsSUFBSSxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3hHLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLHNDQUFzQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDcEgsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU8sVUFBVSxDQUFDLE1BQWMsRUFBRSxVQUFrQjtRQUNuRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsRUFBRyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDO1FBQ3BCLElBQUksSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ1IsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsS0FBSyxFQUFFLE9BQU87Z0JBQ2QsT0FBTyxFQUFFLDhCQUE4QixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsU0FBUzthQUNyRSxDQUFDLENBQUM7WUFDSCxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDekIsQ0FBQztRQUNELElBQUksTUFBZSxDQUFDO1FBQ3BCLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxNQUFNLEdBQUcsU0FBUyxDQUFDO1FBQ3JCLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxHQUFTLEVBQUU7WUFDckIsSUFBSSxJQUFJLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBQ3pCLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDO1lBQ2xCLCtGQUErRjtZQUMvRixNQUFNLE9BQU8sR0FBRyxHQUFTLEVBQUU7Z0JBQ3pCLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDO2dCQUNsQixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM3QixDQUFDLENBQUM7WUFDRixNQUFNLElBQUksR0FBa0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FDaEYsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDVixPQUFPLEVBQUUsQ0FBQztnQkFDVixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNqQyxDQUFDLEVBQ0QsQ0FBQyxLQUFjLEVBQUUsRUFBRTtnQkFDakIsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNyQyxDQUFDLENBQ0YsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN4QyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQixDQUFDLENBQUM7UUFDRixJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0I7WUFBRSxHQUFHLEVBQUUsQ0FBQzs7WUFDcEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDMUIsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQ3pCLENBQUM7SUFFTyxNQUFNLENBQUMsUUFBeUMsRUFBRSxPQUE2QjtRQUNyRixJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSztZQUFFLE9BQU87UUFDNUMsSUFBSSxJQUFZLENBQUM7UUFDakIsSUFBSSxDQUFDO1lBQ0gsSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN2RyxDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN4QixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVPLEdBQUcsQ0FBQyxLQUFhLEVBQUUsSUFBWTtRQUNyQyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBQ3pDLE1BQU0sSUFBSSxHQUFHLEdBQUcsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDO1FBQ2hFLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzlDLElBQUksSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNwRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztZQUNwQixJQUFJLENBQUMsSUFBSSxJQUFJLDRCQUE0QixDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUM7SUFDcEIsQ0FBQztJQUVPLFFBQVEsQ0FBQyxJQUFZO1FBQzNCLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBQ3pCLElBQUksT0FBNkYsQ0FBQztRQUNsRyxJQUFJLENBQUM7WUFDSCxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxxQ0FBcUMsRUFBRSxDQUFDO1FBQ3pGLENBQUM7UUFDRCxJQUFJLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNmLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDbkQsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xCLDhGQUE4RjtnQkFDOUYsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO29CQUNyQixLQUFLLEVBQUUsZUFBZTtvQkFDdEIsT0FBTyxFQUFFLDZCQUE2QixTQUFTLFFBQVEsU0FBUyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLHNDQUFzQztpQkFDeEgsQ0FBQyxDQUFDLENBQUM7Z0JBQ0osT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNSLEVBQUUsRUFBRSxJQUFJO2dCQUNSLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxJQUFJLElBQUk7Z0JBQzVCLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7Z0JBQ3JELEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUMxQyxDQUFDLENBQUM7WUFDSCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVPLFFBQVEsQ0FBQyxNQUE4QixFQUFFLEtBQWE7UUFDNUQsSUFBSSxNQUFlLENBQUM7UUFDcEIsMkZBQTJGO1FBQzNGLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxDQUFDLEtBQUssWUFBWSxLQUFLLENBQUMsSUFBSSxLQUFLLFlBQVksVUFBVTtnQkFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztZQUNqRixNQUFNLEdBQUcsU0FBUyxDQUFDO1FBQ3JCLENBQUM7Z0JBQVMsQ0FBQztZQUNULElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxLQUFLO2dCQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNyRCxDQUFDO1FBQ0QsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3pHLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUV6RixDQUFDO1FBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRU8sUUFBUSxDQUNkLEtBQTBELEVBQzFELEtBQWE7UUFFYixJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLLE9BQU87WUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN4SCxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLLFNBQVM7WUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMzRixNQUFNLE9BQU8sR0FBRyxPQUFPLEtBQUssQ0FBQyxPQUFPLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQztRQUMxRixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssZUFBZSxJQUFJLE9BQU8sS0FBSyxlQUFlLEVBQUUsQ0FBQztZQUNsRSxPQUFPLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLDhCQUE4QixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsbUJBQW1CLEVBQUUsQ0FBQztRQUN6SSxDQUFDO1FBQ0QsSUFDRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssZUFBZSxJQUFJLE9BQU8sS0FBSyxnQkFBZ0IsQ0FBQztlQUM3RCxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssWUFBWSxJQUFJLE9BQU8sS0FBSyxrQ0FBa0MsQ0FBQyxFQUNsRixDQUFDO1lBQ0QsT0FBTyxFQUFFLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxDQUFDO1FBQ2pHLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssZUFBZSxJQUFJLE9BQU8sS0FBSyxhQUFhLEVBQUUsQ0FBQztZQUNoRSxPQUFPLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLHNDQUFzQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssTUFBTSxFQUFFLENBQUM7UUFDM0gsQ0FBQztRQUNELE1BQU0sSUFBSSxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUQsT0FBTztZQUNMLEtBQUssRUFBRSxLQUFLLEtBQUssT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLGVBQWU7WUFDM0YsR0FBRyxDQUFDLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQy9ELE9BQU87WUFDUCxHQUFHLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ2hFLENBQUM7SUFDSixDQUFDO0lBRU8sT0FBTyxDQUFDLE9BQTJDO1FBQ3pELE9BQU87WUFDTCxFQUFFLEVBQUUsS0FBSztZQUNULE9BQU8sRUFBRTtnQkFDUCxHQUFHLE9BQU87Z0JBQ1YsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztnQkFDckQsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2FBQzFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxzRkFBc0Y7SUFDOUUsSUFBSSxDQUFDLElBQVc7UUFDdEIsSUFBSSxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU87UUFDekIsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUM7UUFDbkIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUN6QixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzVDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssT0FBTztZQUM1QyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUU7WUFDM0UsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRU8sSUFBSSxDQUFDLE1BQTBCO1FBQ3JDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssS0FBSyxDQUFDLE9BQW1CO1FBQy9CLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUN0QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1lBQ3JCLE9BQU8sRUFBRSxDQUFDO1lBQ1YsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25CLElBQUksS0FBZ0QsQ0FBQztRQUNyRCxLQUFLLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDaEIsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3RDLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQzVCLEtBQUssR0FBRyxVQUFVLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQzNDLENBQUMsQ0FBQztTQUNILENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ1gsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1lBQ3JCLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sWUFBWTtRQUNsQixNQUFNLEtBQUssR0FBRyxHQUFTLEVBQUU7WUFDdkIsSUFBSSxJQUFJLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBQ3pCLE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ25GLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLGlDQUFpQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDaEgsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hHLENBQUMsQ0FBQztRQUNGLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBVSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLE9BQU87UUFDYixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNyQixJQUFJLElBQUksQ0FBQyxTQUFTO1lBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQixJQUFJLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUN4QixJQUFJLENBQUM7WUFDSCxLQUFLLE1BQU0sUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTO2dCQUFFLElBQUksUUFBUSxDQUFDLEtBQUs7b0JBQUUsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzlFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUNuQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSztnQkFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xELENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNyQixDQUFDO0lBQ0gsQ0FBQztDQUNGIn0=
@@ -252,6 +252,16 @@ export declare class FlexHarness<TScope = unknown> {
252
252
  * call's part, events and permission requests carry the method's path.
253
253
  */
254
254
  private createCatalogTools;
255
+ /** A refused catalog call as the trusted error the model and the tool part show. */
256
+ private catalogCallError;
257
+ /**
258
+ * Runs a `run_code` program. Every catalog call it makes is dispatched like an `execute`
259
+ * (validation, `onCall`, the method's run with its permission requests, the output limits, error
260
+ * projection) and recorded as a tool part of its own, named by the method, with the `run_code`
261
+ * call as its parent. Proposals go to `onProposals` as one batch once the program finished; a
262
+ * program that fails proposes nothing.
263
+ */
264
+ private runCatalogProgram;
255
265
  private createBuiltInTools;
256
266
  private createRenameSessionTool;
257
267
  private createProjectTaskTool;