@dbx-tools/lakebox 0.9.154 → 0.9.158

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/lib/src/ssh.js ADDED
@@ -0,0 +1,489 @@
1
+ import { PassThrough } from "node:stream";
2
+ import { StringDecoder } from "node:string_decoder";
3
+ import { log, toError } from "@dbx-tools/shared-core";
4
+ import { createPool } from "generic-pool";
5
+ const logger = log.logger("lakebox:ssh-transport");
6
+ /** Maximum authenticated resources maintained by each SSH operation pool. */
7
+ export const SSH_POOL_MAX = 10;
8
+ /** Live SSH command that streams output and awaits to its numeric exit code. */
9
+ export class SshCommand {
10
+ command;
11
+ args;
12
+ [Symbol.toStringTag] = "SshCommand";
13
+ /** Live standard output decoded as UTF-8 strings. */
14
+ stdout;
15
+ /** Live standard error decoded as UTF-8 strings. */
16
+ stderr;
17
+ /** Completed result with captured output, timing, and timeout metadata. */
18
+ result;
19
+ /** Numeric exit code after completion. */
20
+ exitCode;
21
+ startedAt = Date.now();
22
+ stdoutStream = new PassThrough();
23
+ stderrStream = new PassThrough();
24
+ stdoutDecoder = new StringDecoder("utf8");
25
+ stderrDecoder = new StringDecoder("utf8");
26
+ abortController = new AbortController();
27
+ completion;
28
+ resolveCompletion;
29
+ rejectCompletion;
30
+ cancelBackend;
31
+ cancellation;
32
+ stdoutText = "";
33
+ stderrText = "";
34
+ settled = false;
35
+ timedOut = false;
36
+ /** Creates a command and schedules its asynchronous setup and execution. */
37
+ constructor(command, args, options, start) {
38
+ this.command = command;
39
+ this.args = args;
40
+ this.stdoutStream.setEncoding("utf8");
41
+ this.stderrStream.setEncoding("utf8");
42
+ this.stdout = this.stdoutStream;
43
+ this.stderr = this.stderrStream;
44
+ this.completion = new Promise((resolve, reject) => {
45
+ this.resolveCompletion = resolve;
46
+ this.rejectCompletion = reject;
47
+ });
48
+ this.result = this.completion.then((exitCode) => ({
49
+ success: exitCode === 0 && !this.timedOut,
50
+ exitCode,
51
+ stdout: this.stdoutText,
52
+ stderr: this.stderrText,
53
+ executionTimeMs: Date.now() - this.startedAt,
54
+ ...(this.timedOut ? { timedOut: true } : {}),
55
+ command: this.command,
56
+ args: [...this.args],
57
+ }));
58
+ void this.completion.catch(() => undefined);
59
+ void this.result.catch(() => undefined);
60
+ const externalAbort = () => {
61
+ void this.cancel().catch(() => undefined);
62
+ };
63
+ if (options.signal?.aborted)
64
+ externalAbort();
65
+ else
66
+ options.signal?.addEventListener("abort", externalAbort, { once: true });
67
+ const timeout = setTimeout(() => {
68
+ this.timedOut = true;
69
+ void this.cancel(124).catch(() => undefined);
70
+ }, options.timeoutMs);
71
+ timeout.unref?.();
72
+ const cleanup = () => {
73
+ clearTimeout(timeout);
74
+ options.signal?.removeEventListener("abort", externalAbort);
75
+ };
76
+ void this.completion.then(cleanup, cleanup);
77
+ queueMicrotask(() => {
78
+ if (this.settled)
79
+ return;
80
+ void start({
81
+ signal: this.abortController.signal,
82
+ stdout: (chunk) => this.writeOutput("stdout", chunk),
83
+ stderr: (chunk) => this.writeOutput("stderr", chunk),
84
+ setCancel: (cancel) => {
85
+ this.cancelBackend = cancel;
86
+ if (this.abortController.signal.aborted) {
87
+ void this.invokeCancel().catch(() => undefined);
88
+ }
89
+ },
90
+ follow: (command) => this.follow(command),
91
+ }).then((exitCode) => this.finish(exitCode), (error) => this.fail(error));
92
+ });
93
+ }
94
+ /** Cancel the command once. Caller cancellation resolves with exit code 130. */
95
+ cancel(exitCode = 130) {
96
+ if (this.settled)
97
+ return this.cancellation ?? Promise.resolve();
98
+ if (!this.abortController.signal.aborted)
99
+ this.abortController.abort();
100
+ const cancellation = this.invokeCancel();
101
+ this.finish(exitCode);
102
+ return cancellation;
103
+ }
104
+ then(onfulfilled, onrejected) {
105
+ return this.completion.then(onfulfilled, onrejected);
106
+ }
107
+ catch(onrejected) {
108
+ return this.completion.catch(onrejected);
109
+ }
110
+ finally(onfinally) {
111
+ return this.completion.finally(onfinally ?? undefined);
112
+ }
113
+ invokeCancel() {
114
+ if (this.cancellation)
115
+ return this.cancellation;
116
+ if (!this.cancelBackend)
117
+ return Promise.resolve();
118
+ const cancelBackend = this.cancelBackend;
119
+ this.cancellation = Promise.resolve()
120
+ .then(() => cancelBackend())
121
+ .then(() => undefined);
122
+ void this.cancellation.catch(() => undefined);
123
+ return this.cancellation;
124
+ }
125
+ writeOutput(stream, chunk) {
126
+ if (this.settled)
127
+ return;
128
+ const decoder = stream === "stdout" ? this.stdoutDecoder : this.stderrDecoder;
129
+ const value = decoder.write(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
130
+ if (!value)
131
+ return;
132
+ if (stream === "stdout") {
133
+ this.stdoutText += value;
134
+ this.stdoutStream.write(value);
135
+ }
136
+ else {
137
+ this.stderrText += value;
138
+ this.stderrStream.write(value);
139
+ }
140
+ }
141
+ async follow(command) {
142
+ this.cancelBackend = () => command.cancel();
143
+ if (this.abortController.signal.aborted) {
144
+ void this.invokeCancel().catch(() => undefined);
145
+ }
146
+ const stdout = this.pipe(command.stdout, (chunk) => this.writeOutput("stdout", chunk));
147
+ const stderr = this.pipe(command.stderr, (chunk) => this.writeOutput("stderr", chunk));
148
+ const exitCode = await command;
149
+ await Promise.all([stdout, stderr]);
150
+ return exitCode;
151
+ }
152
+ async pipe(stream, write) {
153
+ for await (const chunk of stream)
154
+ write(chunk);
155
+ }
156
+ finish(exitCode) {
157
+ if (this.settled)
158
+ return;
159
+ this.settled = true;
160
+ this.exitCode = exitCode;
161
+ this.closeOutput();
162
+ this.resolveCompletion(exitCode);
163
+ }
164
+ fail(error) {
165
+ if (this.settled)
166
+ return;
167
+ this.settled = true;
168
+ this.closeOutput();
169
+ this.rejectCompletion(error);
170
+ }
171
+ closeOutput() {
172
+ const stdoutRemainder = this.stdoutDecoder.end();
173
+ const stderrRemainder = this.stderrDecoder.end();
174
+ if (stdoutRemainder) {
175
+ this.stdoutText += stdoutRemainder;
176
+ this.stdoutStream.write(stdoutRemainder);
177
+ }
178
+ if (stderrRemainder) {
179
+ this.stderrText += stderrRemainder;
180
+ this.stderrStream.write(stderrRemainder);
181
+ }
182
+ this.stdoutStream.end();
183
+ this.stderrStream.end();
184
+ }
185
+ }
186
+ /**
187
+ * Exclusive, single-operation SSH resource pool.
188
+ *
189
+ * The command pool keeps one authenticated resource warm. Forwarding uses a
190
+ * separate zero-minimum pool so long-lived WebSockets cannot consume the warm
191
+ * command connection. Every borrowed resource is destroyed after its command
192
+ * or forwarded stream because the Databricks Russh gateway may accept only one
193
+ * operation during a connection's lifetime.
194
+ */
195
+ export class PooledSshTransport {
196
+ lifecycle;
197
+ commandPool;
198
+ forwardingPool;
199
+ activeResources = new Map();
200
+ seededResources = [];
201
+ lastCreateError;
202
+ starting;
203
+ closing;
204
+ closed = false;
205
+ constructor(lifecycle, options = {}) {
206
+ this.lifecycle = lifecycle;
207
+ const factory = {
208
+ create: async () => {
209
+ try {
210
+ const resource = this.seededResources.shift() ?? (await lifecycle.create());
211
+ this.lastCreateError = undefined;
212
+ return resource;
213
+ }
214
+ catch (error) {
215
+ this.lastCreateError = error;
216
+ throw error;
217
+ }
218
+ },
219
+ destroy: (resource) => lifecycle.destroy(resource),
220
+ validate: async (resource) => {
221
+ try {
222
+ return await lifecycle.test(resource);
223
+ }
224
+ catch {
225
+ return false;
226
+ }
227
+ },
228
+ };
229
+ const defaults = {
230
+ max: options.max ?? SSH_POOL_MAX,
231
+ acquireTimeoutMillis: options.acquireTimeoutMillis ?? 15_000,
232
+ idleTimeoutMillis: options.idleTimeoutMillis ?? 30_000,
233
+ evictionRunIntervalMillis: options.evictionRunIntervalMillis ?? 10_000,
234
+ numTestsPerEvictionRun: options.numTestsPerEvictionRun ?? 3,
235
+ testOnBorrow: true,
236
+ autostart: false,
237
+ };
238
+ this.commandPool = createPool(factory, { ...defaults, min: 1 });
239
+ this.forwardingPool = createPool(factory, { ...defaults, min: 0 });
240
+ }
241
+ /** Starts both pools and waits until one tested command resource is warm. */
242
+ start() {
243
+ if (this.closed)
244
+ return Promise.reject(new Error(`${this.kind} SSH transport is closed`));
245
+ if (this.starting)
246
+ return this.starting;
247
+ this.starting = this.startPools();
248
+ void this.starting
249
+ .catch(() => this.close())
250
+ .catch((error) => logger.warn("failed to close SSH transport after startup failure", {
251
+ kind: this.kind,
252
+ error: toError(error),
253
+ }));
254
+ return this.starting;
255
+ }
256
+ async startPools() {
257
+ if (this.closed)
258
+ throw new Error(`${this.kind} SSH transport is closed`);
259
+ const resource = await this.lifecycle.create();
260
+ if (this.closed) {
261
+ await this.lifecycle.destroy(resource);
262
+ throw new Error(`${this.kind} SSH transport is closed`);
263
+ }
264
+ this.seededResources.push(resource);
265
+ this.commandPool.start();
266
+ this.forwardingPool.start();
267
+ try {
268
+ const resource = await this.commandPool.acquire();
269
+ await this.commandPool.release(resource);
270
+ }
271
+ catch (error) {
272
+ throw this.lastCreateError ?? error;
273
+ }
274
+ }
275
+ async run(script, execution) {
276
+ const resource = await this.acquire(this.commandPool);
277
+ try {
278
+ if (execution.signal.aborted)
279
+ return 130;
280
+ return await this.runWithResource(resource, script, execution);
281
+ }
282
+ finally {
283
+ await this.destroy(this.commandPool, resource);
284
+ }
285
+ }
286
+ async connect(remoteHost, remotePort) {
287
+ const first = await this.acquire(this.forwardingPool);
288
+ try {
289
+ return await this.connectWithBorrowedResource(first, remoteHost, remotePort);
290
+ }
291
+ catch (error) {
292
+ await this.destroy(this.forwardingPool, first);
293
+ if (this.closed)
294
+ throw error;
295
+ }
296
+ const retry = await this.acquire(this.forwardingPool);
297
+ try {
298
+ return await this.connectWithBorrowedResource(retry, remoteHost, remotePort);
299
+ }
300
+ catch (error) {
301
+ await this.destroy(this.forwardingPool, retry);
302
+ throw error;
303
+ }
304
+ }
305
+ async close() {
306
+ if (this.closing)
307
+ return this.closing;
308
+ this.closed = true;
309
+ this.closing = this.closePools();
310
+ return this.closing;
311
+ }
312
+ async connectWithBorrowedResource(resource, remoteHost, remotePort) {
313
+ const stream = await this.connectWithResource(resource, remoteHost, remotePort);
314
+ let disposed = false;
315
+ const dispose = () => {
316
+ if (disposed)
317
+ return;
318
+ disposed = true;
319
+ void this.destroy(this.forwardingPool, resource);
320
+ };
321
+ stream.once("close", dispose);
322
+ stream.once("error", dispose);
323
+ if (stream.destroyed)
324
+ dispose();
325
+ return stream;
326
+ }
327
+ async acquire(pool) {
328
+ if (this.closed)
329
+ throw new Error(`${this.kind} SSH transport is closed`);
330
+ let resource;
331
+ try {
332
+ resource = await pool.acquire();
333
+ }
334
+ catch (error) {
335
+ throw this.lastCreateError ?? error;
336
+ }
337
+ this.activeResources.set(resource, pool);
338
+ if (this.closed) {
339
+ await this.destroy(pool, resource);
340
+ throw new Error(`${this.kind} SSH transport is closed`);
341
+ }
342
+ return resource;
343
+ }
344
+ async destroy(pool, resource) {
345
+ if (this.activeResources.get(resource) !== pool)
346
+ return;
347
+ this.activeResources.delete(resource);
348
+ try {
349
+ await pool.destroy(resource);
350
+ }
351
+ catch (error) {
352
+ logger.warn("failed to destroy pooled SSH resource", {
353
+ kind: this.kind,
354
+ error: toError(error),
355
+ });
356
+ }
357
+ }
358
+ async closePools() {
359
+ await this.starting?.catch(() => undefined);
360
+ const commandDrain = this.commandPool.drain();
361
+ const forwardingDrain = this.forwardingPool.drain();
362
+ await Promise.all([...this.activeResources].map(([resource, pool]) => this.destroy(pool, resource)));
363
+ await Promise.all([commandDrain, forwardingDrain]);
364
+ await Promise.all([this.commandPool.clear(), this.forwardingPool.clear()]);
365
+ }
366
+ }
367
+ /**
368
+ * Select one SSH transport from resolved policy and keep it for the session.
369
+ * Auto prefers native OpenSSH and otherwise selects ssh2.
370
+ */
371
+ export async function createSshTransport(options, overrides = {}) {
372
+ const factories = { ...defaultSshTransportFactories, ...overrides };
373
+ const sshCommand = options.sshCommand ?? "ssh";
374
+ const transportMode = options.transport ?? "auto";
375
+ if (transportMode === "ssh2") {
376
+ return factories.createSsh2(options);
377
+ }
378
+ const openSshSupported = await factories.supportsOpenSsh(sshCommand);
379
+ if (transportMode === "openssh" && !openSshSupported) {
380
+ throw new Error("Native OpenSSH with SOCKS5 forwarding is unavailable");
381
+ }
382
+ if (openSshSupported) {
383
+ return factories.createOpenSsh(options, sshCommand);
384
+ }
385
+ if (transportMode !== "auto") {
386
+ throw new Error(`Unsupported SSH transport: ${transportMode}`);
387
+ }
388
+ return factories.createSsh2(options);
389
+ }
390
+ const defaultSshTransportFactories = {
391
+ supportsOpenSsh: async (command) => {
392
+ const { supportsNativeOpenSsh } = await import("./_ssh_openssh.js");
393
+ return supportsNativeOpenSsh(command);
394
+ },
395
+ createOpenSsh: async (options, command) => {
396
+ const { OpenSshTransport } = await import("./_ssh_openssh.js");
397
+ const transport = new OpenSshTransport(options, command);
398
+ try {
399
+ await transport.start();
400
+ return transport;
401
+ }
402
+ catch (error) {
403
+ await transport.close();
404
+ throw error;
405
+ }
406
+ },
407
+ createSsh2: async (options) => {
408
+ const { Ssh2Transport } = await import("./_ssh_ssh2.js");
409
+ const transport = new Ssh2Transport(options);
410
+ try {
411
+ await transport.start();
412
+ return transport;
413
+ }
414
+ catch (error) {
415
+ await transport.close();
416
+ throw error;
417
+ }
418
+ },
419
+ };
420
+ /** @internal Builds a remote command after clearing inherited machine credentials. */
421
+ export function sshCommandScript(command, args, cwd, env, identity) {
422
+ assertSafeSshEnvironment(env);
423
+ const root = identity.kind === "root";
424
+ const home = root ? "/root" : identity.home;
425
+ const name = root ? "root" : identity.name;
426
+ const workingDirectory = cwd ?? home;
427
+ const invocation = [command, ...scrubLoginShellCommand(command, args)].map(shellQuote).join(" ");
428
+ const environment = Object.entries({
429
+ HOME: home,
430
+ USER: name,
431
+ LOGNAME: name,
432
+ SHELL: "/bin/bash",
433
+ PWD: workingDirectory,
434
+ PATH: root
435
+ ? "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
436
+ : `${home}/.local/bin:/usr/local/bin:/usr/bin:/bin`,
437
+ DATABRICKS_CONFIG_FILE: "/dev/null",
438
+ ...env,
439
+ })
440
+ .map(([key, value]) => `${environmentName(key)}=${shellQuote(value)}`)
441
+ .join(" ");
442
+ const run = `cd -- ${shellQuote(workingDirectory)} && ${invocation}`;
443
+ const sudoArgs = root ? ["-n", "-H"] : ["-n", "-H", "-u", name];
444
+ const switched = ["sudo", ...sudoArgs, "--", "env", "-i"].map(shellQuote).join(" ");
445
+ return `${SSH_AUTH_ENVIRONMENT_SCRUB}\nexec ${switched} ${environment} '/bin/sh' '-c' ${shellQuote(run)} </dev/null`;
446
+ }
447
+ function scrubLoginShellCommand(command, args) {
448
+ const executable = command.split("/").at(-1);
449
+ if (!executable || !["sh", "bash", "zsh"].includes(executable) || args[0] !== "-lc") {
450
+ return args;
451
+ }
452
+ const [flags, script, ...rest] = args;
453
+ if (script === undefined)
454
+ return args;
455
+ return [flags, `${SSH_AUTH_ENVIRONMENT_SCRUB}\n${script}`, ...rest];
456
+ }
457
+ const SSH_AUTH_ENVIRONMENT_SCRUB = `for __dbx_tools_name in $(env | sed -n 's/^\\([A-Za-z_][A-Za-z0-9_]*\\)=.*/\\1/p'); do
458
+ case "$__dbx_tools_name" in
459
+ DATABRICKS_*|SSH_AUTH_SOCK)
460
+ unset "$__dbx_tools_name"
461
+ ;;
462
+ esac
463
+ done
464
+ export DATABRICKS_CONFIG_FILE=/dev/null`;
465
+ function assertSafeSshEnvironment(env) {
466
+ for (const name of Object.keys(env ?? {})) {
467
+ if (name === "HOME" ||
468
+ name === "USER" ||
469
+ name === "LOGNAME" ||
470
+ name === "SHELL" ||
471
+ name === "PWD" ||
472
+ name === "PATH" ||
473
+ name.startsWith("SUDO_") ||
474
+ name.startsWith("DATABRICKS_") ||
475
+ name === "SSH_AUTH_SOCK") {
476
+ throw new Error("SSH environment overlays cannot replace the Lakebox identity or restore Databricks or SSH agent credentials.");
477
+ }
478
+ }
479
+ }
480
+ function shellQuote(value) {
481
+ return `'${value.replaceAll("'", "'\\''")}'`;
482
+ }
483
+ function environmentName(value) {
484
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
485
+ throw new Error(`Invalid SSH environment variable name: ${value}`);
486
+ }
487
+ return value;
488
+ }
489
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NzaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUE4QixNQUFNLGFBQWEsQ0FBQztBQUN0RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV0RCxPQUFPLEVBQUUsVUFBVSxFQUF5QyxNQUFNLGNBQWMsQ0FBQztBQUlqRixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFDbkQsNkVBQTZFO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxFQUFFLENBQUM7QUFpQi9CLGdGQUFnRjtBQUNoRixNQUFNLE9BQU8sVUFBVTtJQTZCVjtJQUNBO0lBN0JGLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLFlBQVksQ0FBQztJQUM3QyxxREFBcUQ7SUFDNUMsTUFBTSxDQUFtQztJQUNsRCxvREFBb0Q7SUFDM0MsTUFBTSxDQUFtQztJQUNsRCwyRUFBMkU7SUFDbEUsTUFBTSxDQUFnQztJQUMvQywwQ0FBMEM7SUFDMUMsUUFBUSxDQUFxQjtJQUVaLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDdkIsWUFBWSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7SUFDakMsWUFBWSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7SUFDakMsYUFBYSxHQUFHLElBQUksYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxlQUFlLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUN4QyxVQUFVLENBQWtCO0lBQ3JDLGlCQUFpQixDQUE4QjtJQUMvQyxnQkFBZ0IsQ0FBNEI7SUFD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QUFDLENBQUM7QUFDdEUsQ0FBQztBQUVELE1BQU0sMEJBQTBCLEdBQUc7Ozs7Ozs7d0NBT0ssQ0FBQztBQUV6QyxTQUFTLHdCQUF3QixDQUFDLEdBQWlEO0lBQ2pGLEtBQUssTUFBTSxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxJQUNFLElBQUksS0FBSyxNQUFNO1lBQ2YsSUFBSSxLQUFLLE1BQU07WUFDZixJQUFJLEtBQUssU0FBUztZQUNsQixJQUFJLEtBQUssT0FBTztZQUNoQixJQUFJLEtBQUssS0FBSztZQUNkLElBQUksS0FBSyxNQUFNO1lBQ2YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7WUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7WUFDOUIsSUFBSSxLQUFLLGVBQWUsRUFDeEIsQ0FBQztZQUNELE1BQU0sSUFBSSxLQUFLLENBQ2IsOEdBQThHLENBQy9HLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxLQUFhO0lBQy9CLE9BQU8sSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDO0FBQy9DLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxLQUFhO0lBQ3BDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM1QyxNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3JFLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXNzVGhyb3VnaCwgdHlwZSBEdXBsZXgsIHR5cGUgUmVhZGFibGUgfSBmcm9tIFwibm9kZTpzdHJlYW1cIjtcbmltcG9ydCB7IFN0cmluZ0RlY29kZXIgfSBmcm9tIFwibm9kZTpzdHJpbmdfZGVjb2RlclwiO1xuaW1wb3J0IHsgbG9nLCB0b0Vycm9yIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgTGFrZWJveENvbW1hbmRSZXN1bHQgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbGFrZWJveFwiO1xuaW1wb3J0IHsgY3JlYXRlUG9vbCwgdHlwZSBGYWN0b3J5LCB0eXBlIE9wdGlvbnMsIHR5cGUgUG9vbCB9IGZyb20gXCJnZW5lcmljLXBvb2xcIjtcbmltcG9ydCB0eXBlIHsgQ2xpZW50IGFzIFNzaDJDbGllbnQgfSBmcm9tIFwic3NoMlwiO1xuaW1wb3J0IHR5cGUgeyBTc2gyUGF0Y2hNb2RlLCBTc2hUcmFuc3BvcnRNb2RlIH0gZnJvbSBcIi4vdHJhbnNwb3J0LnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJsYWtlYm94OnNzaC10cmFuc3BvcnRcIik7XG4vKiogTWF4aW11bSBhdXRoZW50aWNhdGVkIHJlc291cmNlcyBtYWludGFpbmVkIGJ5IGVhY2ggU1NIIG9wZXJhdGlvbiBwb29sLiAqL1xuZXhwb3J0IGNvbnN0IFNTSF9QT09MX01BWCA9IDEwO1xuXG4vKiogT25lIGNvbW1hbmQgZXhlY3V0aW9uIHJlcXVlc3QgYWZ0ZXIgdGhlIHJlbW90ZSBzaGVsbCBzY3JpcHQgaXMgYXNzZW1ibGVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTc2hFeGVjdXRpb25PcHRpb25zIHtcbiAgdGltZW91dE1zOiBudW1iZXI7XG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xufVxuXG4vKiogVHJhbnNwb3J0IGNhbGxiYWNrcyBvd25lZCBieSBvbmUgbGl2ZSBTU0ggY29tbWFuZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3NoQ29tbWFuZEV4ZWN1dGlvbiB7XG4gIHJlYWRvbmx5IHNpZ25hbDogQWJvcnRTaWduYWw7XG4gIHN0ZG91dChjaHVuazogQnVmZmVyIHwgc3RyaW5nKTogdm9pZDtcbiAgc3RkZXJyKGNodW5rOiBCdWZmZXIgfCBzdHJpbmcpOiB2b2lkO1xuICBzZXRDYW5jZWwoY2FuY2VsOiAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPik6IHZvaWQ7XG4gIGZvbGxvdyhjb21tYW5kOiBTc2hDb21tYW5kKTogUHJvbWlzZTxudW1iZXI+O1xufVxuXG4vKiogTGl2ZSBTU0ggY29tbWFuZCB0aGF0IHN0cmVhbXMgb3V0cHV0IGFuZCBhd2FpdHMgdG8gaXRzIG51bWVyaWMgZXhpdCBjb2RlLiAqL1xuZXhwb3J0IGNsYXNzIFNzaENvbW1hbmQgaW1wbGVtZW50cyBQcm9taXNlPG51bWJlcj4ge1xuICByZWFkb25seSBbU3ltYm9sLnRvU3RyaW5nVGFnXSA9IFwiU3NoQ29tbWFuZFwiO1xuICAvKiogTGl2ZSBzdGFuZGFyZCBvdXRwdXQgZGVjb2RlZCBhcyBVVEYtOCBzdHJpbmdzLiAqL1xuICByZWFkb25seSBzdGRvdXQ6IFJlYWRhYmxlICYgQXN5bmNJdGVyYWJsZTxzdHJpbmc+O1xuICAvKiogTGl2ZSBzdGFuZGFyZCBlcnJvciBkZWNvZGVkIGFzIFVURi04IHN0cmluZ3MuICovXG4gIHJlYWRvbmx5IHN0ZGVycjogUmVhZGFibGUgJiBBc3luY0l0ZXJhYmxlPHN0cmluZz47XG4gIC8qKiBDb21wbGV0ZWQgcmVzdWx0IHdpdGggY2FwdHVyZWQgb3V0cHV0LCB0aW1pbmcsIGFuZCB0aW1lb3V0IG1ldGFkYXRhLiAqL1xuICByZWFkb25seSByZXN1bHQ6IFByb21pc2U8TGFrZWJveENvbW1hbmRSZXN1bHQ+O1xuICAvKiogTnVtZXJpYyBleGl0IGNvZGUgYWZ0ZXIgY29tcGxldGlvbi4gKi9cbiAgZXhpdENvZGU6IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Rkb3V0U3RyZWFtID0gbmV3IFBhc3NUaHJvdWdoKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RkZXJyU3RyZWFtID0gbmV3IFBhc3NUaHJvdWdoKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3Rkb3V0RGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKFwidXRmOFwiKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGRlcnJEZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoXCJ1dGY4XCIpO1xuICBwcml2YXRlIHJlYWRvbmx5IGFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21wbGV0aW9uOiBQcm9taXNlPG51bWJlcj47XG4gIHByaXZhdGUgcmVzb2x2ZUNvbXBsZXRpb24hOiAoZXhpdENvZGU6IG51bWJlcikgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWplY3RDb21wbGV0aW9uITogKGVycm9yOiB1bmtub3duKSA9PiB2b2lkO1xuICBwcml2YXRlIGNhbmNlbEJhY2tlbmQ/OiAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBjYW5jZWxsYXRpb24/OiBQcm9taXNlPHZvaWQ+O1xuICBwcml2YXRlIHN0ZG91dFRleHQgPSBcIlwiO1xuICBwcml2YXRlIHN0ZGVyclRleHQgPSBcIlwiO1xuICBwcml2YXRlIHNldHRsZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSB0aW1lZE91dCA9IGZhbHNlO1xuXG4gIC8qKiBDcmVhdGVzIGEgY29tbWFuZCBhbmQgc2NoZWR1bGVzIGl0cyBhc3luY2hyb25vdXMgc2V0dXAgYW5kIGV4ZWN1dGlvbi4gKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgY29tbWFuZDogc3RyaW5nLFxuICAgIHJlYWRvbmx5IGFyZ3M6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICAgIG9wdGlvbnM6IFNzaEV4ZWN1dGlvbk9wdGlvbnMsXG4gICAgc3RhcnQ6IChleGVjdXRpb246IFNzaENvbW1hbmRFeGVjdXRpb24pID0+IFByb21pc2U8bnVtYmVyPixcbiAgKSB7XG4gICAgdGhpcy5zdGRvdXRTdHJlYW0uc2V0RW5jb2RpbmcoXCJ1dGY4XCIpO1xuICAgIHRoaXMuc3RkZXJyU3RyZWFtLnNldEVuY29kaW5nKFwidXRmOFwiKTtcbiAgICB0aGlzLnN0ZG91dCA9IHRoaXMuc3Rkb3V0U3RyZWFtIGFzIFJlYWRhYmxlICYgQXN5bmNJdGVyYWJsZTxzdHJpbmc+O1xuICAgIHRoaXMuc3RkZXJyID0gdGhpcy5zdGRlcnJTdHJlYW0gYXMgUmVhZGFibGUgJiBBc3luY0l0ZXJhYmxlPHN0cmluZz47XG4gICAgdGhpcy5jb21wbGV0aW9uID0gbmV3IFByb21pc2U8bnVtYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnJlc29sdmVDb21wbGV0aW9uID0gcmVzb2x2ZTtcbiAgICAgIHRoaXMucmVqZWN0Q29tcGxldGlvbiA9IHJlamVjdDtcbiAgICB9KTtcbiAgICB0aGlzLnJlc3VsdCA9IHRoaXMuY29tcGxldGlvbi50aGVuKChleGl0Q29kZSkgPT4gKHtcbiAgICAgIHN1Y2Nlc3M6IGV4aXRDb2RlID09PSAwICYmICF0aGlzLnRpbWVkT3V0LFxuICAgICAgZXhpdENvZGUsXG4gICAgICBzdGRvdXQ6IHRoaXMuc3Rkb3V0VGV4dCxcbiAgICAgIHN0ZGVycjogdGhpcy5zdGRlcnJUZXh0LFxuICAgICAgZXhlY3V0aW9uVGltZU1zOiBEYXRlLm5vdygpIC0gdGhpcy5zdGFydGVkQXQsXG4gICAgICAuLi4odGhpcy50aW1lZE91dCA/IHsgdGltZWRPdXQ6IHRydWUgfSA6IHt9KSxcbiAgICAgIGNvbW1hbmQ6IHRoaXMuY29tbWFuZCxcbiAgICAgIGFyZ3M6IFsuLi50aGlzLmFyZ3NdLFxuICAgIH0pKTtcbiAgICB2b2lkIHRoaXMuY29tcGxldGlvbi5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIHZvaWQgdGhpcy5yZXN1bHQuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblxuICAgIGNvbnN0IGV4dGVybmFsQWJvcnQgPSAoKSA9PiB7XG4gICAgICB2b2lkIHRoaXMuY2FuY2VsKCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9O1xuICAgIGlmIChvcHRpb25zLnNpZ25hbD8uYWJvcnRlZCkgZXh0ZXJuYWxBYm9ydCgpO1xuICAgIGVsc2Ugb3B0aW9ucy5zaWduYWw/LmFkZEV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBleHRlcm5hbEFib3J0LCB7IG9uY2U6IHRydWUgfSk7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy50aW1lZE91dCA9IHRydWU7XG4gICAgICB2b2lkIHRoaXMuY2FuY2VsKDEyNCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9LCBvcHRpb25zLnRpbWVvdXRNcyk7XG4gICAgdGltZW91dC51bnJlZj8uKCk7XG4gICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIG9wdGlvbnMuc2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgZXh0ZXJuYWxBYm9ydCk7XG4gICAgfTtcbiAgICB2b2lkIHRoaXMuY29tcGxldGlvbi50aGVuKGNsZWFudXAsIGNsZWFudXApO1xuXG4gICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc2V0dGxlZCkgcmV0dXJuO1xuICAgICAgdm9pZCBzdGFydCh7XG4gICAgICAgIHNpZ25hbDogdGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICBzdGRvdXQ6IChjaHVuaykgPT4gdGhpcy53cml0ZU91dHB1dChcInN0ZG91dFwiLCBjaHVuayksXG4gICAgICAgIHN0ZGVycjogKGNodW5rKSA9PiB0aGlzLndyaXRlT3V0cHV0KFwic3RkZXJyXCIsIGNodW5rKSxcbiAgICAgICAgc2V0Q2FuY2VsOiAoY2FuY2VsKSA9PiB7XG4gICAgICAgICAgdGhpcy5jYW5jZWxCYWNrZW5kID0gY2FuY2VsO1xuICAgICAgICAgIGlmICh0aGlzLmFib3J0Q29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgICAgdm9pZCB0aGlzLmludm9rZUNhbmNlbCgpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmb2xsb3c6IChjb21tYW5kKSA9PiB0aGlzLmZvbGxvdyhjb21tYW5kKSxcbiAgICAgIH0pLnRoZW4oXG4gICAgICAgIChleGl0Q29kZSkgPT4gdGhpcy5maW5pc2goZXhpdENvZGUpLFxuICAgICAgICAoZXJyb3IpID0+IHRoaXMuZmFpbChlcnJvciksXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIENhbmNlbCB0aGUgY29tbWFuZCBvbmNlLiBDYWxsZXIgY2FuY2VsbGF0aW9uIHJlc29sdmVzIHdpdGggZXhpdCBjb2RlIDEzMC4gKi9cbiAgY2FuY2VsKGV4aXRDb2RlID0gMTMwKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuc2V0dGxlZCkgcmV0dXJuIHRoaXMuY2FuY2VsbGF0aW9uID8/IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmICghdGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsLmFib3J0ZWQpIHRoaXMuYWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgY29uc3QgY2FuY2VsbGF0aW9uID0gdGhpcy5pbnZva2VDYW5jZWwoKTtcbiAgICB0aGlzLmZpbmlzaChleGl0Q29kZSk7XG4gICAgcmV0dXJuIGNhbmNlbGxhdGlvbjtcbiAgfVxuXG4gIHRoZW48VFJlc3VsdDEgPSBudW1iZXIsIFRSZXN1bHQyID0gbmV2ZXI+KFxuICAgIG9uZnVsZmlsbGVkPzogKCh2YWx1ZTogbnVtYmVyKSA9PiBUUmVzdWx0MSB8IFByb21pc2VMaWtlPFRSZXN1bHQxPikgfCBudWxsLFxuICAgIG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogdW5rbm93bikgPT4gVFJlc3VsdDIgfCBQcm9taXNlTGlrZTxUUmVzdWx0Mj4pIHwgbnVsbCxcbiAgKTogUHJvbWlzZTxUUmVzdWx0MSB8IFRSZXN1bHQyPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tcGxldGlvbi50aGVuKG9uZnVsZmlsbGVkLCBvbnJlamVjdGVkKTtcbiAgfVxuXG4gIGNhdGNoPFRSZXN1bHQgPSBuZXZlcj4oXG4gICAgb25yZWplY3RlZD86ICgocmVhc29uOiB1bmtub3duKSA9PiBUUmVzdWx0IHwgUHJvbWlzZUxpa2U8VFJlc3VsdD4pIHwgbnVsbCxcbiAgKTogUHJvbWlzZTxudW1iZXIgfCBUUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuY29tcGxldGlvbi5jYXRjaChvbnJlamVjdGVkKTtcbiAgfVxuXG4gIGZpbmFsbHkob25maW5hbGx5PzogKCgpID0+IHZvaWQpIHwgbnVsbCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tcGxldGlvbi5maW5hbGx5KG9uZmluYWxseSA/PyB1bmRlZmluZWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnZva2VDYW5jZWwoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2FuY2VsbGF0aW9uKSByZXR1cm4gdGhpcy5jYW5jZWxsYXRpb247XG4gICAgaWYgKCF0aGlzLmNhbmNlbEJhY2tlbmQpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBjb25zdCBjYW5jZWxCYWNrZW5kID0gdGhpcy5jYW5jZWxCYWNrZW5kO1xuICAgIHRoaXMuY2FuY2VsbGF0aW9uID0gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IGNhbmNlbEJhY2tlbmQoKSlcbiAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgdm9pZCB0aGlzLmNhbmNlbGxhdGlvbi5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIHJldHVybiB0aGlzLmNhbmNlbGxhdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgd3JpdGVPdXRwdXQoc3RyZWFtOiBcInN0ZG91dFwiIHwgXCJzdGRlcnJcIiwgY2h1bms6IEJ1ZmZlciB8IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNldHRsZWQpIHJldHVybjtcbiAgICBjb25zdCBkZWNvZGVyID0gc3RyZWFtID09PSBcInN0ZG91dFwiID8gdGhpcy5zdGRvdXREZWNvZGVyIDogdGhpcy5zdGRlcnJEZWNvZGVyO1xuICAgIGNvbnN0IHZhbHVlID0gZGVjb2Rlci53cml0ZSh0eXBlb2YgY2h1bmsgPT09IFwic3RyaW5nXCIgPyBCdWZmZXIuZnJvbShjaHVuaykgOiBjaHVuayk7XG4gICAgaWYgKCF2YWx1ZSkgcmV0dXJuO1xuICAgIGlmIChzdHJlYW0gPT09IFwic3Rkb3V0XCIpIHtcbiAgICAgIHRoaXMuc3Rkb3V0VGV4dCArPSB2YWx1ZTtcbiAgICAgIHRoaXMuc3Rkb3V0U3RyZWFtLndyaXRlKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGRlcnJUZXh0ICs9IHZhbHVlO1xuICAgICAgdGhpcy5zdGRlcnJTdHJlYW0ud3JpdGUodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZm9sbG93KGNvbW1hbmQ6IFNzaENvbW1hbmQpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIHRoaXMuY2FuY2VsQmFja2VuZCA9ICgpID0+IGNvbW1hbmQuY2FuY2VsKCk7XG4gICAgaWYgKHRoaXMuYWJvcnRDb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICB2b2lkIHRoaXMuaW52b2tlQ2FuY2VsKCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgY29uc3Qgc3Rkb3V0ID0gdGhpcy5waXBlKGNvbW1hbmQuc3Rkb3V0LCAoY2h1bmspID0+IHRoaXMud3JpdGVPdXRwdXQoXCJzdGRvdXRcIiwgY2h1bmspKTtcbiAgICBjb25zdCBzdGRlcnIgPSB0aGlzLnBpcGUoY29tbWFuZC5zdGRlcnIsIChjaHVuaykgPT4gdGhpcy53cml0ZU91dHB1dChcInN0ZGVyclwiLCBjaHVuaykpO1xuICAgIGNvbnN0IGV4aXRDb2RlID0gYXdhaXQgY29tbWFuZDtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChbc3Rkb3V0LCBzdGRlcnJdKTtcbiAgICByZXR1cm4gZXhpdENvZGU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBpcGUoc3RyZWFtOiBBc3luY0l0ZXJhYmxlPHN0cmluZz4sIHdyaXRlOiAoY2h1bms6IHN0cmluZykgPT4gdm9pZCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2Ygc3RyZWFtKSB3cml0ZShjaHVuayk7XG4gIH1cblxuICBwcml2YXRlIGZpbmlzaChleGl0Q29kZTogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2V0dGxlZCkgcmV0dXJuO1xuICAgIHRoaXMuc2V0dGxlZCA9IHRydWU7XG4gICAgdGhpcy5leGl0Q29kZSA9IGV4aXRDb2RlO1xuICAgIHRoaXMuY2xvc2VPdXRwdXQoKTtcbiAgICB0aGlzLnJlc29sdmVDb21wbGV0aW9uKGV4aXRDb2RlKTtcbiAgfVxuXG4gIHByaXZhdGUgZmFpbChlcnJvcjogdW5rbm93bik6IHZvaWQge1xuICAgIGlmICh0aGlzLnNldHRsZWQpIHJldHVybjtcbiAgICB0aGlzLnNldHRsZWQgPSB0cnVlO1xuICAgIHRoaXMuY2xvc2VPdXRwdXQoKTtcbiAgICB0aGlzLnJlamVjdENvbXBsZXRpb24oZXJyb3IpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZU91dHB1dCgpOiB2b2lkIHtcbiAgICBjb25zdCBzdGRvdXRSZW1haW5kZXIgPSB0aGlzLnN0ZG91dERlY29kZXIuZW5kKCk7XG4gICAgY29uc3Qgc3RkZXJyUmVtYWluZGVyID0gdGhpcy5zdGRlcnJEZWNvZGVyLmVuZCgpO1xuICAgIGlmIChzdGRvdXRSZW1haW5kZXIpIHtcbiAgICAgIHRoaXMuc3Rkb3V0VGV4dCArPSBzdGRvdXRSZW1haW5kZXI7XG4gICAgICB0aGlzLnN0ZG91dFN0cmVhbS53cml0ZShzdGRvdXRSZW1haW5kZXIpO1xuICAgIH1cbiAgICBpZiAoc3RkZXJyUmVtYWluZGVyKSB7XG4gICAgICB0aGlzLnN0ZGVyclRleHQgKz0gc3RkZXJyUmVtYWluZGVyO1xuICAgICAgdGhpcy5zdGRlcnJTdHJlYW0ud3JpdGUoc3RkZXJyUmVtYWluZGVyKTtcbiAgICB9XG4gICAgdGhpcy5zdGRvdXRTdHJlYW0uZW5kKCk7XG4gICAgdGhpcy5zdGRlcnJTdHJlYW0uZW5kKCk7XG4gIH1cbn1cblxuLyoqIENvbm5lY3Rpb24gZGV0YWlscyBzaGFyZWQgYnkgbmF0aXZlIE9wZW5TU0ggYW5kIHRoZSBndWFyZGVkIHNzaDIgZmFsbGJhY2suICovXG5leHBvcnQgaW50ZXJmYWNlIFNzaFRyYW5zcG9ydE9wdGlvbnMge1xuICBob3N0OiBzdHJpbmc7XG4gIGNvbm5lY3RIb3N0OiBzdHJpbmc7XG4gIHBvcnQ6IG51bWJlcjtcbiAgdXNlcm5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZUtleVBhdGg6IHN0cmluZztcbiAga25vd25Ib3N0c1BhdGg6IHN0cmluZztcbiAgY29ubmVjdFRpbWVvdXRNczogbnVtYmVyO1xuICBzc2gyQ2xpZW50OiBTc2gyQ2xpZW50O1xuICBjcmVhdGVTc2gyQ29tbWFuZENsaWVudDogKCkgPT4gUHJvbWlzZTxTc2gyQ2xpZW50PjtcbiAgdHJhbnNwb3J0PzogU3NoVHJhbnNwb3J0TW9kZTtcbiAgc3NoMlBhdGNoPzogU3NoMlBhdGNoTW9kZTtcbiAgc3NoQ29tbWFuZD86IHN0cmluZztcbn1cblxuLyoqIFNlbGVjdGVkIGNvbW1hbmQgYW5kIHJlbW90ZSBUQ1AgdHJhbnNwb3J0IGZvciBvbmUgdmVyaWZpZWQgU1NIIGdhdGV3YXkuICovXG5leHBvcnQgaW50ZXJmYWNlIFNzaFRyYW5zcG9ydCB7XG4gIHJlYWRvbmx5IGtpbmQ6IFwib3BlbnNzaFwiIHwgXCJzc2gyXCI7XG4gIHJ1bihzY3JpcHQ6IHN0cmluZywgZXhlY3V0aW9uOiBTc2hDb21tYW5kRXhlY3V0aW9uKTogUHJvbWlzZTxudW1iZXI+O1xuICBjb25uZWN0KHJlbW90ZUhvc3Q6IHN0cmluZywgcmVtb3RlUG9ydDogbnVtYmVyKTogUHJvbWlzZTxEdXBsZXg+O1xuICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG4vKiogQXN5bmMgbGlmZWN5Y2xlIHVzZWQgYnkgYm90aCBuYXRpdmUgT3BlblNTSCBhbmQgc3NoMiBjb25uZWN0aW9uIHBvb2xzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTc2hSZXNvdXJjZUxpZmVjeWNsZTxUPiB7XG4gIGNyZWF0ZSgpOiBQcm9taXNlPFQ+O1xuICBkZXN0cm95KHJlc291cmNlOiBUKTogUHJvbWlzZTx2b2lkPjtcbiAgdGVzdChyZXNvdXJjZTogVCk6IFByb21pc2U8Ym9vbGVhbj47XG59XG5cbi8qKiBPcHRpb25hbCBwb29sIG92ZXJyaWRlcyB1c2VkIGJ5IHRyYW5zcG9ydCB0ZXN0cyBhbmQgY29uc3RyYWluZWQgcnVudGltZXMuICovXG5leHBvcnQgdHlwZSBTc2hQb29sT3B0aW9ucyA9IFBpY2s8XG4gIE9wdGlvbnMsXG4gIHwgXCJtYXhcIlxuICB8IFwiYWNxdWlyZVRpbWVvdXRNaWxsaXNcIlxuICB8IFwiaWRsZVRpbWVvdXRNaWxsaXNcIlxuICB8IFwiZXZpY3Rpb25SdW5JbnRlcnZhbE1pbGxpc1wiXG4gIHwgXCJudW1UZXN0c1BlckV2aWN0aW9uUnVuXCJcbj47XG5cbi8qKlxuICogRXhjbHVzaXZlLCBzaW5nbGUtb3BlcmF0aW9uIFNTSCByZXNvdXJjZSBwb29sLlxuICpcbiAqIFRoZSBjb21tYW5kIHBvb2wga2VlcHMgb25lIGF1dGhlbnRpY2F0ZWQgcmVzb3VyY2Ugd2FybS4gRm9yd2FyZGluZyB1c2VzIGFcbiAqIHNlcGFyYXRlIHplcm8tbWluaW11bSBwb29sIHNvIGxvbmctbGl2ZWQgV2ViU29ja2V0cyBjYW5ub3QgY29uc3VtZSB0aGUgd2FybVxuICogY29tbWFuZCBjb25uZWN0aW9uLiBFdmVyeSBib3Jyb3dlZCByZXNvdXJjZSBpcyBkZXN0cm95ZWQgYWZ0ZXIgaXRzIGNvbW1hbmRcbiAqIG9yIGZvcndhcmRlZCBzdHJlYW0gYmVjYXVzZSB0aGUgRGF0YWJyaWNrcyBSdXNzaCBnYXRld2F5IG1heSBhY2NlcHQgb25seSBvbmVcbiAqIG9wZXJhdGlvbiBkdXJpbmcgYSBjb25uZWN0aW9uJ3MgbGlmZXRpbWUuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQb29sZWRTc2hUcmFuc3BvcnQ8VD4gaW1wbGVtZW50cyBTc2hUcmFuc3BvcnQge1xuICBhYnN0cmFjdCByZWFkb25seSBraW5kOiBcIm9wZW5zc2hcIiB8IFwic3NoMlwiO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZFBvb2w6IFBvb2w8VD47XG4gIHByaXZhdGUgcmVhZG9ubHkgZm9yd2FyZGluZ1Bvb2w6IFBvb2w8VD47XG4gIHByaXZhdGUgcmVhZG9ubHkgYWN0aXZlUmVzb3VyY2VzID0gbmV3IE1hcDxULCBQb29sPFQ+PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHNlZWRlZFJlc291cmNlczogVFtdID0gW107XG4gIHByaXZhdGUgbGFzdENyZWF0ZUVycm9yOiB1bmtub3duO1xuICBwcml2YXRlIHN0YXJ0aW5nPzogUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBjbG9zaW5nPzogUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBjbG9zZWQgPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBsaWZlY3ljbGU6IFNzaFJlc291cmNlTGlmZWN5Y2xlPFQ+LFxuICAgIG9wdGlvbnM6IFNzaFBvb2xPcHRpb25zID0ge30sXG4gICkge1xuICAgIGNvbnN0IGZhY3Rvcnk6IEZhY3Rvcnk8VD4gPSB7XG4gICAgICBjcmVhdGU6IGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXNvdXJjZSA9IHRoaXMuc2VlZGVkUmVzb3VyY2VzLnNoaWZ0KCkgPz8gKGF3YWl0IGxpZmVjeWNsZS5jcmVhdGUoKSk7XG4gICAgICAgICAgdGhpcy5sYXN0Q3JlYXRlRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgcmV0dXJuIHJlc291cmNlO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMubGFzdENyZWF0ZUVycm9yID0gZXJyb3I7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBkZXN0cm95OiAocmVzb3VyY2UpID0+IGxpZmVjeWNsZS5kZXN0cm95KHJlc291cmNlKSxcbiAgICAgIHZhbGlkYXRlOiBhc3luYyAocmVzb3VyY2UpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgbGlmZWN5Y2xlLnRlc3QocmVzb3VyY2UpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCBkZWZhdWx0czogT3B0aW9ucyA9IHtcbiAgICAgIG1heDogb3B0aW9ucy5tYXggPz8gU1NIX1BPT0xfTUFYLFxuICAgICAgYWNxdWlyZVRpbWVvdXRNaWxsaXM6IG9wdGlvbnMuYWNxdWlyZVRpbWVvdXRNaWxsaXMgPz8gMTVfMDAwLFxuICAgICAgaWRsZVRpbWVvdXRNaWxsaXM6IG9wdGlvbnMuaWRsZVRpbWVvdXRNaWxsaXMgPz8gMzBfMDAwLFxuICAgICAgZXZpY3Rpb25SdW5JbnRlcnZhbE1pbGxpczogb3B0aW9ucy5ldmljdGlvblJ1bkludGVydmFsTWlsbGlzID8/IDEwXzAwMCxcbiAgICAgIG51bVRlc3RzUGVyRXZpY3Rpb25SdW46IG9wdGlvbnMubnVtVGVzdHNQZXJFdmljdGlvblJ1biA/PyAzLFxuICAgICAgdGVzdE9uQm9ycm93OiB0cnVlLFxuICAgICAgYXV0b3N0YXJ0OiBmYWxzZSxcbiAgICB9O1xuICAgIHRoaXMuY29tbWFuZFBvb2wgPSBjcmVhdGVQb29sKGZhY3RvcnksIHsgLi4uZGVmYXVsdHMsIG1pbjogMSB9KTtcbiAgICB0aGlzLmZvcndhcmRpbmdQb29sID0gY3JlYXRlUG9vbChmYWN0b3J5LCB7IC4uLmRlZmF1bHRzLCBtaW46IDAgfSk7XG4gIH1cblxuICAvKiogU3RhcnRzIGJvdGggcG9vbHMgYW5kIHdhaXRzIHVudGlsIG9uZSB0ZXN0ZWQgY29tbWFuZCByZXNvdXJjZSBpcyB3YXJtLiAqL1xuICBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5jbG9zZWQpIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYCR7dGhpcy5raW5kfSBTU0ggdHJhbnNwb3J0IGlzIGNsb3NlZGApKTtcbiAgICBpZiAodGhpcy5zdGFydGluZykgcmV0dXJuIHRoaXMuc3RhcnRpbmc7XG4gICAgdGhpcy5zdGFydGluZyA9IHRoaXMuc3RhcnRQb29scygpO1xuICAgIHZvaWQgdGhpcy5zdGFydGluZ1xuICAgICAgLmNhdGNoKCgpID0+IHRoaXMuY2xvc2UoKSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+XG4gICAgICAgIGxvZ2dlci53YXJuKFwiZmFpbGVkIHRvIGNsb3NlIFNTSCB0cmFuc3BvcnQgYWZ0ZXIgc3RhcnR1cCBmYWlsdXJlXCIsIHtcbiAgICAgICAgICBraW5kOiB0aGlzLmtpbmQsXG4gICAgICAgICAgZXJyb3I6IHRvRXJyb3IoZXJyb3IpLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRpbmc7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHN0YXJ0UG9vbHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2xvc2VkKSB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5raW5kfSBTU0ggdHJhbnNwb3J0IGlzIGNsb3NlZGApO1xuICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgdGhpcy5saWZlY3ljbGUuY3JlYXRlKCk7XG4gICAgaWYgKHRoaXMuY2xvc2VkKSB7XG4gICAgICBhd2FpdCB0aGlzLmxpZmVjeWNsZS5kZXN0cm95KHJlc291cmNlKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmtpbmR9IFNTSCB0cmFuc3BvcnQgaXMgY2xvc2VkYCk7XG4gICAgfVxuICAgIHRoaXMuc2VlZGVkUmVzb3VyY2VzLnB1c2gocmVzb3VyY2UpO1xuICAgIHRoaXMuY29tbWFuZFBvb2wuc3RhcnQoKTtcbiAgICB0aGlzLmZvcndhcmRpbmdQb29sLnN0YXJ0KCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgdGhpcy5jb21tYW5kUG9vbC5hY3F1aXJlKCk7XG4gICAgICBhd2FpdCB0aGlzLmNvbW1hbmRQb29sLnJlbGVhc2UocmVzb3VyY2UpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLmxhc3RDcmVhdGVFcnJvciA/PyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhc3luYyBydW4oc2NyaXB0OiBzdHJpbmcsIGV4ZWN1dGlvbjogU3NoQ29tbWFuZEV4ZWN1dGlvbik6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCB0aGlzLmFjcXVpcmUodGhpcy5jb21tYW5kUG9vbCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChleGVjdXRpb24uc2lnbmFsLmFib3J0ZWQpIHJldHVybiAxMzA7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5XaXRoUmVzb3VyY2UocmVzb3VyY2UsIHNjcmlwdCwgZXhlY3V0aW9uKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgdGhpcy5kZXN0cm95KHRoaXMuY29tbWFuZFBvb2wsIHJlc291cmNlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjb25uZWN0KHJlbW90ZUhvc3Q6IHN0cmluZywgcmVtb3RlUG9ydDogbnVtYmVyKTogUHJvbWlzZTxEdXBsZXg+IHtcbiAgICBjb25zdCBmaXJzdCA9IGF3YWl0IHRoaXMuYWNxdWlyZSh0aGlzLmZvcndhcmRpbmdQb29sKTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY29ubmVjdFdpdGhCb3Jyb3dlZFJlc291cmNlKGZpcnN0LCByZW1vdGVIb3N0LCByZW1vdGVQb3J0KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5kZXN0cm95KHRoaXMuZm9yd2FyZGluZ1Bvb2wsIGZpcnN0KTtcbiAgICAgIGlmICh0aGlzLmNsb3NlZCkgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIGNvbnN0IHJldHJ5ID0gYXdhaXQgdGhpcy5hY3F1aXJlKHRoaXMuZm9yd2FyZGluZ1Bvb2wpO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5jb25uZWN0V2l0aEJvcnJvd2VkUmVzb3VyY2UocmV0cnksIHJlbW90ZUhvc3QsIHJlbW90ZVBvcnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3kodGhpcy5mb3J3YXJkaW5nUG9vbCwgcmV0cnkpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY2xvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2xvc2luZykgcmV0dXJuIHRoaXMuY2xvc2luZztcbiAgICB0aGlzLmNsb3NlZCA9IHRydWU7XG4gICAgdGhpcy5jbG9zaW5nID0gdGhpcy5jbG9zZVBvb2xzKCk7XG4gICAgcmV0dXJuIHRoaXMuY2xvc2luZztcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBydW5XaXRoUmVzb3VyY2UoXG4gICAgcmVzb3VyY2U6IFQsXG4gICAgc2NyaXB0OiBzdHJpbmcsXG4gICAgZXhlY3V0aW9uOiBTc2hDb21tYW5kRXhlY3V0aW9uLFxuICApOiBQcm9taXNlPG51bWJlcj47XG5cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGNvbm5lY3RXaXRoUmVzb3VyY2UoXG4gICAgcmVzb3VyY2U6IFQsXG4gICAgcmVtb3RlSG9zdDogc3RyaW5nLFxuICAgIHJlbW90ZVBvcnQ6IG51bWJlcixcbiAgKTogUHJvbWlzZTxEdXBsZXg+O1xuXG4gIHByaXZhdGUgYXN5bmMgY29ubmVjdFdpdGhCb3Jyb3dlZFJlc291cmNlKFxuICAgIHJlc291cmNlOiBULFxuICAgIHJlbW90ZUhvc3Q6IHN0cmluZyxcbiAgICByZW1vdGVQb3J0OiBudW1iZXIsXG4gICk6IFByb21pc2U8RHVwbGV4PiB7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgdGhpcy5jb25uZWN0V2l0aFJlc291cmNlKHJlc291cmNlLCByZW1vdGVIb3N0LCByZW1vdGVQb3J0KTtcbiAgICBsZXQgZGlzcG9zZWQgPSBmYWxzZTtcbiAgICBjb25zdCBkaXNwb3NlID0gKCkgPT4ge1xuICAgICAgaWYgKGRpc3Bvc2VkKSByZXR1cm47XG4gICAgICBkaXNwb3NlZCA9IHRydWU7XG4gICAgICB2b2lkIHRoaXMuZGVzdHJveSh0aGlzLmZvcndhcmRpbmdQb29sLCByZXNvdXJjZSk7XG4gICAgfTtcbiAgICBzdHJlYW0ub25jZShcImNsb3NlXCIsIGRpc3Bvc2UpO1xuICAgIHN0cmVhbS5vbmNlKFwiZXJyb3JcIiwgZGlzcG9zZSk7XG4gICAgaWYgKHN0cmVhbS5kZXN0cm95ZWQpIGRpc3Bvc2UoKTtcbiAgICByZXR1cm4gc3RyZWFtO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhY3F1aXJlKHBvb2w6IFBvb2w8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICBpZiAodGhpcy5jbG9zZWQpIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmtpbmR9IFNTSCB0cmFuc3BvcnQgaXMgY2xvc2VkYCk7XG4gICAgbGV0IHJlc291cmNlOiBUO1xuICAgIHRyeSB7XG4gICAgICByZXNvdXJjZSA9IGF3YWl0IHBvb2wuYWNxdWlyZSgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLmxhc3RDcmVhdGVFcnJvciA/PyBlcnJvcjtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmVSZXNvdXJjZXMuc2V0KHJlc291cmNlLCBwb29sKTtcbiAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuZGVzdHJveShwb29sLCByZXNvdXJjZSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5raW5kfSBTU0ggdHJhbnNwb3J0IGlzIGNsb3NlZGApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzb3VyY2U7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRlc3Ryb3kocG9vbDogUG9vbDxUPiwgcmVzb3VyY2U6IFQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5hY3RpdmVSZXNvdXJjZXMuZ2V0KHJlc291cmNlKSAhPT0gcG9vbCkgcmV0dXJuO1xuICAgIHRoaXMuYWN0aXZlUmVzb3VyY2VzLmRlbGV0ZShyZXNvdXJjZSk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHBvb2wuZGVzdHJveShyZXNvdXJjZSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiZmFpbGVkIHRvIGRlc3Ryb3kgcG9vbGVkIFNTSCByZXNvdXJjZVwiLCB7XG4gICAgICAgIGtpbmQ6IHRoaXMua2luZCxcbiAgICAgICAgZXJyb3I6IHRvRXJyb3IoZXJyb3IpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjbG9zZVBvb2xzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuc3RhcnRpbmc/LmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgY29uc3QgY29tbWFuZERyYWluID0gdGhpcy5jb21tYW5kUG9vbC5kcmFpbigpO1xuICAgIGNvbnN0IGZvcndhcmRpbmdEcmFpbiA9IHRoaXMuZm9yd2FyZGluZ1Bvb2wuZHJhaW4oKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIFsuLi50aGlzLmFjdGl2ZVJlc291cmNlc10ubWFwKChbcmVzb3VyY2UsIHBvb2xdKSA9PiB0aGlzLmRlc3Ryb3kocG9vbCwgcmVzb3VyY2UpKSxcbiAgICApO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtjb21tYW5kRHJhaW4sIGZvcndhcmRpbmdEcmFpbl0pO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLmNvbW1hbmRQb29sLmNsZWFyKCksIHRoaXMuZm9yd2FyZGluZ1Bvb2wuY2xlYXIoKV0pO1xuICB9XG59XG5cbi8qKiBJbmplY3RhYmxlIHRyYW5zcG9ydCBjb25zdHJ1Y3RvcnMgdXNlZCB0byBpc29sYXRlIHBvbGljeSBzZWxlY3Rpb24gaW4gdGVzdHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFNzaFRyYW5zcG9ydEZhY3RvcmllcyB7XG4gIHN1cHBvcnRzT3BlblNzaChjb21tYW5kOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+O1xuICBjcmVhdGVPcGVuU3NoKG9wdGlvbnM6IFNzaFRyYW5zcG9ydE9wdGlvbnMsIGNvbW1hbmQ6IHN0cmluZyk6IFByb21pc2U8U3NoVHJhbnNwb3J0PjtcbiAgY3JlYXRlU3NoMihvcHRpb25zOiBTc2hUcmFuc3BvcnRPcHRpb25zKTogUHJvbWlzZTxTc2hUcmFuc3BvcnQ+O1xufVxuXG4vKipcbiAqIFNlbGVjdCBvbmUgU1NIIHRyYW5zcG9ydCBmcm9tIHJlc29sdmVkIHBvbGljeSBhbmQga2VlcCBpdCBmb3IgdGhlIHNlc3Npb24uXG4gKiBBdXRvIHByZWZlcnMgbmF0aXZlIE9wZW5TU0ggYW5kIG90aGVyd2lzZSBzZWxlY3RzIHNzaDIuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVTc2hUcmFuc3BvcnQoXG4gIG9wdGlvbnM6IFNzaFRyYW5zcG9ydE9wdGlvbnMsXG4gIG92ZXJyaWRlczogUGFydGlhbDxTc2hUcmFuc3BvcnRGYWN0b3JpZXM+ID0ge30sXG4pOiBQcm9taXNlPFNzaFRyYW5zcG9ydD4ge1xuICBjb25zdCBmYWN0b3JpZXMgPSB7IC4uLmRlZmF1bHRTc2hUcmFuc3BvcnRGYWN0b3JpZXMsIC4uLm92ZXJyaWRlcyB9O1xuICBjb25zdCBzc2hDb21tYW5kID0gb3B0aW9ucy5zc2hDb21tYW5kID8/IFwic3NoXCI7XG4gIGNvbnN0IHRyYW5zcG9ydE1vZGUgPSBvcHRpb25zLnRyYW5zcG9ydCA/PyBcImF1dG9cIjtcbiAgaWYgKHRyYW5zcG9ydE1vZGUgPT09IFwic3NoMlwiKSB7XG4gICAgcmV0dXJuIGZhY3Rvcmllcy5jcmVhdGVTc2gyKG9wdGlvbnMpO1xuICB9XG4gIGNvbnN0IG9wZW5Tc2hTdXBwb3J0ZWQgPSBhd2FpdCBmYWN0b3JpZXMuc3VwcG9ydHNPcGVuU3NoKHNzaENvbW1hbmQpO1xuICBpZiAodHJhbnNwb3J0TW9kZSA9PT0gXCJvcGVuc3NoXCIgJiYgIW9wZW5Tc2hTdXBwb3J0ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOYXRpdmUgT3BlblNTSCB3aXRoIFNPQ0tTNSBmb3J3YXJkaW5nIGlzIHVuYXZhaWxhYmxlXCIpO1xuICB9XG4gIGlmIChvcGVuU3NoU3VwcG9ydGVkKSB7XG4gICAgcmV0dXJuIGZhY3Rvcmllcy5jcmVhdGVPcGVuU3NoKG9wdGlvbnMsIHNzaENvbW1hbmQpO1xuICB9XG4gIGlmICh0cmFuc3BvcnRNb2RlICE9PSBcImF1dG9cIikge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgU1NIIHRyYW5zcG9ydDogJHt0cmFuc3BvcnRNb2RlfWApO1xuICB9XG4gIHJldHVybiBmYWN0b3JpZXMuY3JlYXRlU3NoMihvcHRpb25zKTtcbn1cblxuY29uc3QgZGVmYXVsdFNzaFRyYW5zcG9ydEZhY3RvcmllczogU3NoVHJhbnNwb3J0RmFjdG9yaWVzID0ge1xuICBzdXBwb3J0c09wZW5Tc2g6IGFzeW5jIChjb21tYW5kKSA9PiB7XG4gICAgY29uc3QgeyBzdXBwb3J0c05hdGl2ZU9wZW5Tc2ggfSA9IGF3YWl0IGltcG9ydChcIi4vX3NzaF9vcGVuc3NoLnRzXCIpO1xuICAgIHJldHVybiBzdXBwb3J0c05hdGl2ZU9wZW5Tc2goY29tbWFuZCk7XG4gIH0sXG4gIGNyZWF0ZU9wZW5Tc2g6IGFzeW5jIChvcHRpb25zLCBjb21tYW5kKSA9PiB7XG4gICAgY29uc3QgeyBPcGVuU3NoVHJhbnNwb3J0IH0gPSBhd2FpdCBpbXBvcnQoXCIuL19zc2hfb3BlbnNzaC50c1wiKTtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSBuZXcgT3BlblNzaFRyYW5zcG9ydChvcHRpb25zLCBjb21tYW5kKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfSxcbiAgY3JlYXRlU3NoMjogYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IFNzaDJUcmFuc3BvcnQgfSA9IGF3YWl0IGltcG9ydChcIi4vX3NzaF9zc2gyLnRzXCIpO1xuICAgIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBTc2gyVHJhbnNwb3J0KG9wdGlvbnMpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0cmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGF3YWl0IHRyYW5zcG9ydC5jbG9zZSgpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9LFxufTtcblxuLyoqXG4gKiBBY2NvdW50IHRoYXQgcnVucyBvbmUgcmVtb3RlIGNvbW1hbmQuXG4gKlxuICogYHVzZXJgIHRhcmdldHMgYSBsb2NrZWQsIG5vbi1zdWRvIExha2Vib3ggYWNjb3VudC4gYHJvb3RgIGlzIHJlc2VydmVkIGZvclxuICogZml4ZWQgcGFja2FnZS1vd25lZCBib290c3RyYXAgc2NyaXB0cyBhbmQgaXMgbmV2ZXIgcmVhY2hhYmxlIGZyb20gUkVTVCxcbiAqIGFnZW50IHRvb2xzLCBvciBzZXJ2aWNlIGRlZmluaXRpb25zLlxuICovXG5leHBvcnQgdHlwZSBTc2hDb21tYW5kSWRlbnRpdHkgPSB7IGtpbmQ6IFwidXNlclwiOyBuYW1lOiBzdHJpbmc7IGhvbWU6IHN0cmluZyB9IHwgeyBraW5kOiBcInJvb3RcIiB9O1xuXG4vKiogQGludGVybmFsIEJ1aWxkcyBhIHJlbW90ZSBjb21tYW5kIGFmdGVyIGNsZWFyaW5nIGluaGVyaXRlZCBtYWNoaW5lIGNyZWRlbnRpYWxzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNzaENvbW1hbmRTY3JpcHQoXG4gIGNvbW1hbmQ6IHN0cmluZyxcbiAgYXJnczogc3RyaW5nW10sXG4gIGN3ZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQsXG4gIGlkZW50aXR5OiBTc2hDb21tYW5kSWRlbnRpdHksXG4pOiBzdHJpbmcge1xuICBhc3NlcnRTYWZlU3NoRW52aXJvbm1lbnQoZW52KTtcbiAgY29uc3Qgcm9vdCA9IGlkZW50aXR5LmtpbmQgPT09IFwicm9vdFwiO1xuICBjb25zdCBob21lID0gcm9vdCA/IFwiL3Jvb3RcIiA6IGlkZW50aXR5LmhvbWU7XG4gIGNvbnN0IG5hbWUgPSByb290ID8gXCJyb290XCIgOiBpZGVudGl0eS5uYW1lO1xuICBjb25zdCB3b3JraW5nRGlyZWN0b3J5ID0gY3dkID8/IGhvbWU7XG4gIGNvbnN0IGludm9jYXRpb24gPSBbY29tbWFuZCwgLi4uc2NydWJMb2dpblNoZWxsQ29tbWFuZChjb21tYW5kLCBhcmdzKV0ubWFwKHNoZWxsUXVvdGUpLmpvaW4oXCIgXCIpO1xuICBjb25zdCBlbnZpcm9ubWVudCA9IE9iamVjdC5lbnRyaWVzKHtcbiAgICBIT01FOiBob21lLFxuICAgIFVTRVI6IG5hbWUsXG4gICAgTE9HTkFNRTogbmFtZSxcbiAgICBTSEVMTDogXCIvYmluL2Jhc2hcIixcbiAgICBQV0Q6IHdvcmtpbmdEaXJlY3RvcnksXG4gICAgUEFUSDogcm9vdFxuICAgICAgPyBcIi91c3IvbG9jYWwvc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL3NiaW46L3Vzci9iaW46L3NiaW46L2JpblwiXG4gICAgICA6IGAke2hvbWV9Ly5sb2NhbC9iaW46L3Vzci9sb2NhbC9iaW46L3Vzci9iaW46L2JpbmAsXG4gICAgREFUQUJSSUNLU19DT05GSUdfRklMRTogXCIvZGV2L251bGxcIixcbiAgICAuLi5lbnYsXG4gIH0pXG4gICAgLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBgJHtlbnZpcm9ubWVudE5hbWUoa2V5KX09JHtzaGVsbFF1b3RlKHZhbHVlKX1gKVxuICAgIC5qb2luKFwiIFwiKTtcbiAgY29uc3QgcnVuID0gYGNkIC0tICR7c2hlbGxRdW90ZSh3b3JraW5nRGlyZWN0b3J5KX0gJiYgJHtpbnZvY2F0aW9ufWA7XG4gIGNvbnN0IHN1ZG9BcmdzID0gcm9vdCA/IFtcIi1uXCIsIFwiLUhcIl0gOiBbXCItblwiLCBcIi1IXCIsIFwiLXVcIiwgbmFtZV07XG4gIGNvbnN0IHN3aXRjaGVkID0gW1wic3Vkb1wiLCAuLi5zdWRvQXJncywgXCItLVwiLCBcImVudlwiLCBcIi1pXCJdLm1hcChzaGVsbFF1b3RlKS5qb2luKFwiIFwiKTtcbiAgcmV0dXJuIGAke1NTSF9BVVRIX0VOVklST05NRU5UX1NDUlVCfVxcbmV4ZWMgJHtzd2l0Y2hlZH0gJHtlbnZpcm9ubWVudH0gJy9iaW4vc2gnICctYycgJHtzaGVsbFF1b3RlKHJ1bil9IDwvZGV2L251bGxgO1xufVxuXG5mdW5jdGlvbiBzY3J1YkxvZ2luU2hlbGxDb21tYW5kKGNvbW1hbmQ6IHN0cmluZywgYXJnczogc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGV4ZWN1dGFibGUgPSBjb21tYW5kLnNwbGl0KFwiL1wiKS5hdCgtMSk7XG4gIGlmICghZXhlY3V0YWJsZSB8fCAhW1wic2hcIiwgXCJiYXNoXCIsIFwienNoXCJdLmluY2x1ZGVzKGV4ZWN1dGFibGUpIHx8IGFyZ3NbMF0gIT09IFwiLWxjXCIpIHtcbiAgICByZXR1cm4gYXJncztcbiAgfVxuICBjb25zdCBbZmxhZ3MsIHNjcmlwdCwgLi4ucmVzdF0gPSBhcmdzO1xuICBpZiAoc2NyaXB0ID09PSB1bmRlZmluZWQpIHJldHVybiBhcmdzO1xuICByZXR1cm4gW2ZsYWdzLCBgJHtTU0hfQVVUSF9FTlZJUk9OTUVOVF9TQ1JVQn1cXG4ke3NjcmlwdH1gLCAuLi5yZXN0XTtcbn1cblxuY29uc3QgU1NIX0FVVEhfRU5WSVJPTk1FTlRfU0NSVUIgPSBgZm9yIF9fZGJ4X3Rvb2xzX25hbWUgaW4gJChlbnYgfCBzZWQgLW4gJ3MvXlxcXFwoW0EtWmEtel9dW0EtWmEtejAtOV9dKlxcXFwpPS4qL1xcXFwxL3AnKTsgZG9cbiAgY2FzZSBcIiRfX2RieF90b29sc19uYW1lXCIgaW5cbiAgICBEQVRBQlJJQ0tTXyp8U1NIX0FVVEhfU09DSylcbiAgICAgIHVuc2V0IFwiJF9fZGJ4X3Rvb2xzX25hbWVcIlxuICAgICAgOztcbiAgZXNhY1xuZG9uZVxuZXhwb3J0IERBVEFCUklDS1NfQ09ORklHX0ZJTEU9L2Rldi9udWxsYDtcblxuZnVuY3Rpb24gYXNzZXJ0U2FmZVNzaEVudmlyb25tZW50KGVudjogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4gfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGVudiA/PyB7fSkpIHtcbiAgICBpZiAoXG4gICAgICBuYW1lID09PSBcIkhPTUVcIiB8fFxuICAgICAgbmFtZSA9PT0gXCJVU0VSXCIgfHxcbiAgICAgIG5hbWUgPT09IFwiTE9HTkFNRVwiIHx8XG4gICAgICBuYW1lID09PSBcIlNIRUxMXCIgfHxcbiAgICAgIG5hbWUgPT09IFwiUFdEXCIgfHxcbiAgICAgIG5hbWUgPT09IFwiUEFUSFwiIHx8XG4gICAgICBuYW1lLnN0YXJ0c1dpdGgoXCJTVURPX1wiKSB8fFxuICAgICAgbmFtZS5zdGFydHNXaXRoKFwiREFUQUJSSUNLU19cIikgfHxcbiAgICAgIG5hbWUgPT09IFwiU1NIX0FVVEhfU09DS1wiXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiU1NIIGVudmlyb25tZW50IG92ZXJsYXlzIGNhbm5vdCByZXBsYWNlIHRoZSBMYWtlYm94IGlkZW50aXR5IG9yIHJlc3RvcmUgRGF0YWJyaWNrcyBvciBTU0ggYWdlbnQgY3JlZGVudGlhbHMuXCIsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzaGVsbFF1b3RlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCcke3ZhbHVlLnJlcGxhY2VBbGwoXCInXCIsIFwiJ1xcXFwnJ1wiKX0nYDtcbn1cblxuZnVuY3Rpb24gZW52aXJvbm1lbnROYW1lKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoIS9eW0EtWmEtel9dW0EtWmEtejAtOV9dKiQvLnRlc3QodmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIFNTSCBlbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lOiAke3ZhbHVlfWApO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cbiJdfQ==
@@ -1 +1 @@
1
- {"root":["../src/_ssh.ts","../src/_ssh_openssh.ts","../src/_ssh_ssh2.ts","../src/key-store.ts","../src/lifecycle.ts","../src/rest.ts","../src/session.ts","../src/transport.ts","../index.ts"],"version":"5.9.3"}
1
+ {"root":["../src/_ssh_openssh.ts","../src/_ssh_ssh2.ts","../src/key-store.ts","../src/lifecycle.ts","../src/rest.ts","../src/session.ts","../src/ssh.ts","../src/transport.ts","../index.ts"],"version":"5.9.3"}