@dbx-tools/appkit-mastra 0.6.9 → 0.6.10
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/README.md +21 -20
- package/index.ts +12 -27
- package/lib/index.d.ts +12 -27
- package/lib/index.js +12 -27
- package/lib/src/config.d.ts +8 -9
- package/lib/src/config.js +2 -2
- package/lib/src/databricks-aitools.d.ts +17 -27
- package/lib/src/databricks-aitools.js +56 -54
- package/lib/src/filesystems.d.ts +52 -170
- package/lib/src/filesystems.js +168 -888
- package/lib/src/plugin.js +2 -2
- package/lib/src/remote-skills.d.ts +4 -4
- package/lib/src/remote-skills.js +63 -35
- package/lib/src/workspaces.d.ts +4 -0
- package/lib/src/workspaces.js +37 -13
- package/package.json +13 -10
- package/src/config.ts +9 -10
- package/src/databricks-aitools.ts +67 -67
- package/src/filesystems.ts +225 -970
- package/src/plugin.ts +1 -1
- package/src/remote-skills.ts +69 -38
- package/src/workspaces.ts +41 -16
package/lib/src/filesystems.js
CHANGED
|
@@ -1,446 +1,73 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Mastra
|
|
2
|
+
* Mastra workspace filesystem adapters.
|
|
3
3
|
*
|
|
4
|
-
* {@link
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Path helpers ({@link normalizeDatabricksBasePath}, {@link isDbfsPath}, …)
|
|
10
|
-
* are exported for tests and callers that need to reason about Databricks
|
|
11
|
-
* paths without constructing a filesystem.
|
|
4
|
+
* {@link filesystems} wraps any portable `@dbx-tools/shared-fs` {@link FileSystem}
|
|
5
|
+
* (local disk, Databricks, memory, …) as a Mastra {@link MastraFilesystem}.
|
|
6
|
+
* {@link scratchFilesystem} always returns a fresh {@link localFS.tmpFS} mount
|
|
7
|
+
* (random id root) when Mastra needs a filesystem and no other mount resolved.
|
|
12
8
|
*
|
|
13
9
|
* @module
|
|
14
10
|
*/
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { error, functionModule, hash, log } from "@dbx-tools/shared-core";
|
|
11
|
+
import { localFS } from "@dbx-tools/fs";
|
|
12
|
+
import { FileSystemError, posixPath } from "@dbx-tools/shared-fs";
|
|
18
13
|
import { DirectoryNotEmptyError, DirectoryNotFoundError, FileExistsError, FileNotFoundError, IsDirectoryError, MastraFilesystem, NotDirectoryError, PermissionError, WorkspaceReadOnlyError, } from "@mastra/core/workspace";
|
|
19
|
-
/* ------------------------------ constants ------------------------------ */
|
|
20
|
-
const DBFS_READ_CHUNK_BYTES = 1024 * 1024;
|
|
21
|
-
const DBFS_PUT_MAX_BYTES = 1024 * 1024;
|
|
22
|
-
const EMPTY_FILESYSTEM_EPOCH = new Date(0);
|
|
23
|
-
/** Mastra error constructor for a known SDK filesystem failure, if any. */
|
|
24
|
-
function filesystemSdkErrorType(err) {
|
|
25
|
-
if (err) {
|
|
26
|
-
const ctx = error.errorContext(err);
|
|
27
|
-
if (ctx.notAccessible) {
|
|
28
|
-
return FileNotFoundError;
|
|
29
|
-
}
|
|
30
|
-
else if (ctx.hasMessage("already", "exists")) {
|
|
31
|
-
return FileExistsError;
|
|
32
|
-
}
|
|
33
|
-
else if (ctx.hasMessage("not", "directory")) {
|
|
34
|
-
return NotDirectoryError;
|
|
35
|
-
}
|
|
36
|
-
else if (ctx.hasMessage("not", "file")) {
|
|
37
|
-
return IsDirectoryError;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
const logger = log.logger("mastra/filesystems");
|
|
43
|
-
/* ------------------------- exported path helpers ------------------------- */
|
|
44
|
-
/** Normalize a Databricks base path (POSIX, no trailing slash). */
|
|
45
|
-
export function normalizeDatabricksBasePath(basePath) {
|
|
46
|
-
const trimmed = basePath.trim();
|
|
47
|
-
if (!trimmed.startsWith("/")) {
|
|
48
|
-
throw ValidationError.invalidValue("basePath", basePath, "an absolute Databricks path, e.g. /Volumes/catalog/schema/volume");
|
|
49
|
-
}
|
|
50
|
-
return trimmed.replace(/\/+$/, "") || "/";
|
|
51
|
-
}
|
|
52
|
-
/** True when `absolutePath` is served by DBFS rather than the UC Files API. */
|
|
53
|
-
export function isDbfsPath(absolutePath) {
|
|
54
|
-
return absolutePath === "/dbfs" || absolutePath.startsWith("/dbfs/");
|
|
55
|
-
}
|
|
56
|
-
/** True when `absolutePath` is a Databricks workspace object path. */
|
|
57
|
-
export function isWorkspaceFilesPath(absolutePath) {
|
|
58
|
-
return (absolutePath === "/Workspace" ||
|
|
59
|
-
absolutePath.startsWith("/Workspace/") ||
|
|
60
|
-
absolutePath.startsWith("/Users/") ||
|
|
61
|
-
absolutePath.startsWith("/Repos/"));
|
|
62
|
-
}
|
|
63
14
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
15
|
+
* Wrap a portable {@link FileSystem} as a Mastra {@link MastraFilesystem}.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { filesystems } from "@dbx-tools/appkit-mastra";
|
|
20
|
+
* import { DatabricksFileSystem } from "@dbx-tools/databricks";
|
|
21
|
+
* import { localFS } from "@dbx-tools/fs";
|
|
22
|
+
*
|
|
23
|
+
* const volume = filesystems.filesystems(
|
|
24
|
+
* new DatabricksFileSystem({ root: "/Volumes/main/default/assets" }),
|
|
25
|
+
* );
|
|
26
|
+
* const scratch = filesystems.filesystems(localFS.tmpFS("agent-job"));
|
|
27
|
+
* ```
|
|
66
28
|
*/
|
|
67
|
-
export function
|
|
68
|
-
|
|
69
|
-
const trimmed = inputPath.trim();
|
|
70
|
-
if (!trimmed || trimmed === "/")
|
|
71
|
-
return root;
|
|
72
|
-
const normalized = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
73
|
-
if (normalized === root || normalized.startsWith(`${root}/`)) {
|
|
74
|
-
return path.normalize(normalized);
|
|
75
|
-
}
|
|
76
|
-
return path.normalize(path.join(root, normalized));
|
|
29
|
+
export function filesystems(fs, options = {}) {
|
|
30
|
+
return new MastraFileSystemAdapter(fs, options);
|
|
77
31
|
}
|
|
78
|
-
/** Map an absolute Databricks path back to the workspace namespace. */
|
|
79
|
-
export function toDatabricksWorkspacePath(basePath, absolutePath) {
|
|
80
|
-
const root = normalizeDatabricksBasePath(basePath);
|
|
81
|
-
const normalized = path.normalize(absolutePath);
|
|
82
|
-
if (normalized === root)
|
|
83
|
-
return "/";
|
|
84
|
-
if (normalized.startsWith(`${root}/`)) {
|
|
85
|
-
return normalized.slice(root.length) || "/";
|
|
86
|
-
}
|
|
87
|
-
return normalized;
|
|
88
|
-
}
|
|
89
|
-
/* ---------------------------- private helpers ---------------------------- */
|
|
90
|
-
/** Pick the Databricks Files API backend for an absolute path. */
|
|
91
|
-
function resolveFilesBackend(absolutePath) {
|
|
92
|
-
if (isDbfsPath(absolutePath))
|
|
93
|
-
return "dbfs";
|
|
94
|
-
if (isWorkspaceFilesPath(absolutePath))
|
|
95
|
-
return "workspace";
|
|
96
|
-
return "uc-files";
|
|
97
|
-
}
|
|
98
|
-
/** Run the handler that matches `absolutePath`'s Databricks backend. */
|
|
99
|
-
async function dispatchFilesBackend(absolutePath, handlers) {
|
|
100
|
-
const backend = resolveFilesBackend(absolutePath);
|
|
101
|
-
if (backend === "dbfs")
|
|
102
|
-
return handlers.dbfs();
|
|
103
|
-
if (backend === "workspace")
|
|
104
|
-
return handlers.workspace();
|
|
105
|
-
return handlers.ucFiles();
|
|
106
|
-
}
|
|
107
|
-
/** Return `buffer` as a string when `encoding` is set, otherwise unchanged. */
|
|
108
|
-
function formatReadResult(buffer, encoding) {
|
|
109
|
-
return encoding ? buffer.toString(encoding) : buffer;
|
|
110
|
-
}
|
|
111
|
-
/** Drain a fetch `ReadableStream` into a single `Buffer`. */
|
|
112
|
-
async function readResponseBody(contents) {
|
|
113
|
-
if (!contents)
|
|
114
|
-
return Buffer.alloc(0);
|
|
115
|
-
const reader = contents.getReader();
|
|
116
|
-
const chunks = [];
|
|
117
|
-
while (true) {
|
|
118
|
-
const { done, value } = await reader.read();
|
|
119
|
-
if (done)
|
|
120
|
-
break;
|
|
121
|
-
if (value)
|
|
122
|
-
chunks.push(value);
|
|
123
|
-
}
|
|
124
|
-
return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)));
|
|
125
|
-
}
|
|
126
|
-
/** Coerce Mastra {@link FileContent} to a `Buffer`. */
|
|
127
|
-
function toBuffer(content) {
|
|
128
|
-
if (typeof content === "string")
|
|
129
|
-
return Buffer.from(content, "utf8");
|
|
130
|
-
return Buffer.from(content);
|
|
131
|
-
}
|
|
132
|
-
/** Decode a DBFS read payload from base64. */
|
|
133
|
-
function decodeDbfsPayload(data) {
|
|
134
|
-
if (!data)
|
|
135
|
-
return Buffer.alloc(0);
|
|
136
|
-
return Buffer.from(data, "base64");
|
|
137
|
-
}
|
|
138
|
-
/** Wrap a `Buffer` as a one-shot `ReadableStream` for UC file uploads. */
|
|
139
|
-
function bufferToReadableStream(buffer) {
|
|
140
|
-
return new ReadableStream({
|
|
141
|
-
start(controller) {
|
|
142
|
-
controller.enqueue(new Uint8Array(buffer));
|
|
143
|
-
controller.close();
|
|
144
|
-
},
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
/** Parse an HTTP date header; returns epoch when missing or invalid. */
|
|
148
|
-
function parseHttpDate(value) {
|
|
149
|
-
if (!value)
|
|
150
|
-
return new Date(0);
|
|
151
|
-
const parsed = Date.parse(value);
|
|
152
|
-
return Number.isFinite(parsed) ? new Date(parsed) : new Date(0);
|
|
153
|
-
}
|
|
154
|
-
/* ---------------- DatabricksWorkspaceFilesystem ---------------- */
|
|
155
32
|
/**
|
|
156
|
-
* Mastra
|
|
157
|
-
* {@link
|
|
158
|
-
*
|
|
159
|
-
* Workspace paths are absolute within the namespace (`/notes.md` maps to
|
|
160
|
-
* `<basePath>/notes.md`). Unity Catalog volumes use the Files API;
|
|
161
|
-
* `/dbfs/...` paths use DBFS.
|
|
33
|
+
* Thin Mastra {@link MastraFilesystem} adapter over a `@dbx-tools/shared-fs`
|
|
34
|
+
* {@link FileSystem}. Identity fields are getters that read the source on
|
|
35
|
+
* access; construction does not snapshot them.
|
|
162
36
|
*/
|
|
163
|
-
export class
|
|
164
|
-
id;
|
|
165
|
-
name = "DatabricksWorkspaceFilesystem";
|
|
166
|
-
provider = "databricks";
|
|
167
|
-
basePath;
|
|
37
|
+
export class MastraFileSystemAdapter extends MastraFilesystem {
|
|
168
38
|
status = "pending";
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
* @param options.readOnly - When omitted, {@link init} probes write access.
|
|
180
|
-
*/
|
|
181
|
-
constructor(options) {
|
|
182
|
-
super({ name: "DatabricksWorkspaceFilesystem", ...options });
|
|
183
|
-
this.id = options.id ?? `databricks-fs-${hash.fnvHash(options.basePath)}`;
|
|
184
|
-
this.client = options.client ?? getExecutionContext().client;
|
|
185
|
-
this.basePath = normalizeDatabricksBasePath(options.basePath);
|
|
186
|
-
this.mkdirs = options.mkdirs ?? "try";
|
|
187
|
-
this._readOnly = options.readOnly;
|
|
39
|
+
fs;
|
|
40
|
+
options;
|
|
41
|
+
constructor(fs, options = {}) {
|
|
42
|
+
super({
|
|
43
|
+
name: options.name ?? "MastraFileSystemAdapter",
|
|
44
|
+
onInit: options.onInit,
|
|
45
|
+
onDestroy: options.onDestroy,
|
|
46
|
+
});
|
|
47
|
+
this.fs = fs;
|
|
48
|
+
this.options = options;
|
|
188
49
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
resolvePath(inputPath) {
|
|
192
|
-
const resolved = resolveDatabricksAbsolutePath(this.basePath, inputPath);
|
|
193
|
-
if (resolved !== this.basePath && !resolved.startsWith(`${this.basePath}/`)) {
|
|
194
|
-
throw new PermissionError(inputPath, "access");
|
|
195
|
-
}
|
|
196
|
-
return resolved;
|
|
50
|
+
get id() {
|
|
51
|
+
return this.options.id ?? this.fs.id;
|
|
197
52
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return toDatabricksWorkspacePath(this.basePath, absolutePath);
|
|
53
|
+
get name() {
|
|
54
|
+
return this.options.name ?? "MastraFileSystemAdapter";
|
|
201
55
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (this.readOnly) {
|
|
205
|
-
throw new WorkspaceReadOnlyError(operation);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
/** Map SDK / HTTP errors to Mastra workspace filesystem errors. */
|
|
209
|
-
rethrow(err, inputPath) {
|
|
210
|
-
const workspacePath = inputPath.startsWith("/")
|
|
211
|
-
? inputPath
|
|
212
|
-
: this.workspacePath(this.resolvePath(inputPath));
|
|
213
|
-
const ErrorType = filesystemSdkErrorType(err);
|
|
214
|
-
if (ErrorType) {
|
|
215
|
-
throw new ErrorType(workspacePath);
|
|
216
|
-
}
|
|
217
|
-
// The upstream message is logged rather than raised: it reaches the model
|
|
218
|
-
// (and from there the chat transcript) as the tool's failure text.
|
|
219
|
-
logger.warn("operation-failed", {
|
|
220
|
-
path: workspacePath,
|
|
221
|
-
error: error.errorMessage(err),
|
|
222
|
-
});
|
|
223
|
-
throw new ExecutionError(`Databricks filesystem operation failed for ${workspacePath}`, {
|
|
224
|
-
cause: error.toError(err),
|
|
225
|
-
context: { path: workspacePath },
|
|
226
|
-
});
|
|
56
|
+
get provider() {
|
|
57
|
+
return this.options.provider ?? this.fs.backend;
|
|
227
58
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
* Probe whether {@link basePath} exists and cache the result on
|
|
231
|
-
* {@link _basePathMissing}.
|
|
232
|
-
*/
|
|
233
|
-
async resolveBasePathStatus() {
|
|
234
|
-
if (this._basePathMissing !== undefined)
|
|
235
|
-
return;
|
|
236
|
-
try {
|
|
237
|
-
await this.assertAbsoluteReadable(this.basePath);
|
|
238
|
-
this._basePathMissing = false;
|
|
239
|
-
}
|
|
240
|
-
catch (err) {
|
|
241
|
-
if (error.errorContext(err).notAccessible) {
|
|
242
|
-
this._basePathMissing = true;
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
this.rethrow(err, "/");
|
|
246
|
-
}
|
|
59
|
+
get readOnly() {
|
|
60
|
+
return this.options.readOnly === true || this.fs.readOnly;
|
|
247
61
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
await this.resolveBasePathStatus();
|
|
251
|
-
return this._basePathMissing ? emptyFilesystem() : undefined;
|
|
62
|
+
get basePath() {
|
|
63
|
+
return this.fs.root;
|
|
252
64
|
}
|
|
253
65
|
async init() {
|
|
254
|
-
await this.
|
|
255
|
-
if (this._basePathMissing) {
|
|
256
|
-
if (this.mkdirs === false) {
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
try {
|
|
260
|
-
await this.mkdirAbsolute(this.basePath);
|
|
261
|
-
this._basePathMissing = false;
|
|
262
|
-
if (this._readOnly === undefined) {
|
|
263
|
-
this._readOnly = false;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
catch (err) {
|
|
267
|
-
if (this.mkdirs === true) {
|
|
268
|
-
this.rethrow(err, "/");
|
|
269
|
-
}
|
|
270
|
-
logger.debug("mkdirs:try-failed", {
|
|
271
|
-
basePath: this.basePath,
|
|
272
|
-
error: error.errorMessage(err),
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
if (this._readOnly === undefined) {
|
|
278
|
-
await this.probeReadOnly();
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Write and delete a ephemeral probe file to detect read-only access when
|
|
283
|
-
* {@link DatabricksWorkspaceFilesystemOptions.readOnly} was not set.
|
|
284
|
-
*
|
|
285
|
-
* @returns `true` when the probe write (and cleanup) succeeded.
|
|
286
|
-
*/
|
|
287
|
-
async probeReadOnly() {
|
|
288
|
-
const absolutePath = this.resolvePath(`/.__dbx_fs_probe_${hash.id()}`);
|
|
289
|
-
try {
|
|
290
|
-
await this.writeAbsolute(absolutePath, Buffer.from("probe\n"), true);
|
|
291
|
-
this._readOnly = false;
|
|
292
|
-
}
|
|
293
|
-
catch {
|
|
294
|
-
this._readOnly = true;
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
try {
|
|
298
|
-
await this.deleteAbsoluteFile(absolutePath);
|
|
299
|
-
}
|
|
300
|
-
catch {
|
|
301
|
-
// Writable; leave a hidden probe file rather than failing init.
|
|
302
|
-
}
|
|
303
|
-
return true;
|
|
66
|
+
await this.fs.init();
|
|
304
67
|
}
|
|
305
68
|
async destroy() {
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
/* --- backend I/O --- */
|
|
309
|
-
/** Probe that `absolutePath` exists (file or directory metadata). */
|
|
310
|
-
async assertAbsoluteReadable(absolutePath) {
|
|
311
|
-
await dispatchFilesBackend(absolutePath, {
|
|
312
|
-
dbfs: () => this.client.dbfs.getStatus({ path: absolutePath }),
|
|
313
|
-
workspace: () => this.client.workspace.getStatus({ path: absolutePath }),
|
|
314
|
-
ucFiles: () => this.client.files.getDirectoryMetadata({ directory_path: absolutePath }),
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
/** Read the full contents of `absolutePath` from the matching backend. */
|
|
318
|
-
async readAbsolute(absolutePath) {
|
|
319
|
-
return dispatchFilesBackend(absolutePath, {
|
|
320
|
-
dbfs: () => this.readDbfsFile(absolutePath),
|
|
321
|
-
workspace: () => this.readWorkspaceFile(absolutePath),
|
|
322
|
-
ucFiles: async () => {
|
|
323
|
-
const response = await this.client.files.download({ file_path: absolutePath });
|
|
324
|
-
return readResponseBody(response.contents);
|
|
325
|
-
},
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
/** Write `buffer` to `absolutePath` on the matching backend. */
|
|
329
|
-
async writeAbsolute(absolutePath, buffer, overwrite) {
|
|
330
|
-
await dispatchFilesBackend(absolutePath, {
|
|
331
|
-
dbfs: () => this.writeDbfsFile(absolutePath, buffer, overwrite),
|
|
332
|
-
workspace: () => this.writeWorkspaceFile(absolutePath, buffer, overwrite),
|
|
333
|
-
ucFiles: () => this.uploadUcFile(absolutePath, buffer, overwrite),
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
/** Upload a buffer to a Unity Catalog Files API path. */
|
|
337
|
-
uploadUcFile(absolutePath, buffer, overwrite) {
|
|
338
|
-
return this.client.files.upload({
|
|
339
|
-
file_path: absolutePath,
|
|
340
|
-
contents: bufferToReadableStream(buffer),
|
|
341
|
-
overwrite,
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
/** Delete a single file at `absolutePath` (non-recursive). */
|
|
345
|
-
async deleteAbsoluteFile(absolutePath) {
|
|
346
|
-
await dispatchFilesBackend(absolutePath, {
|
|
347
|
-
dbfs: () => this.client.dbfs.delete({ path: absolutePath, recursive: false }),
|
|
348
|
-
workspace: () => this.client.workspace.delete({ path: absolutePath, recursive: false }),
|
|
349
|
-
ucFiles: () => this.client.files.delete({ file_path: absolutePath }),
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Delete a file or directory at `absolutePath`.
|
|
354
|
-
*
|
|
355
|
-
* DBFS and workspace APIs accept `recursive`; UC volumes recurse manually.
|
|
356
|
-
*/
|
|
357
|
-
async deleteAbsolutePath(absolutePath, recursive) {
|
|
358
|
-
await dispatchFilesBackend(absolutePath, {
|
|
359
|
-
dbfs: async () => {
|
|
360
|
-
await this.client.dbfs.delete({ path: absolutePath, recursive });
|
|
361
|
-
},
|
|
362
|
-
workspace: async () => {
|
|
363
|
-
await this.client.workspace.delete({ path: absolutePath, recursive });
|
|
364
|
-
},
|
|
365
|
-
ucFiles: async () => {
|
|
366
|
-
if (recursive) {
|
|
367
|
-
await this.deleteUcDirectoryRecursive(absolutePath);
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
const children = await this.listAbsoluteDirectory(absolutePath);
|
|
371
|
-
if (children.length > 0) {
|
|
372
|
-
throw new DirectoryNotEmptyError(this.workspacePath(absolutePath));
|
|
373
|
-
}
|
|
374
|
-
await this.client.files.deleteDirectory({ directory_path: absolutePath });
|
|
375
|
-
},
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
/** Create `absolutePath` and any missing parents on the matching backend. */
|
|
379
|
-
async mkdirAbsolute(absolutePath) {
|
|
380
|
-
await dispatchFilesBackend(absolutePath, {
|
|
381
|
-
dbfs: () => this.client.dbfs.mkdirs({ path: absolutePath }),
|
|
382
|
-
workspace: () => this.client.workspace.mkdirs({ path: absolutePath }),
|
|
383
|
-
ucFiles: () => this.client.files.createDirectory({ directory_path: absolutePath }),
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
async readDbfsFile(absolutePath) {
|
|
387
|
-
const chunks = [];
|
|
388
|
-
let offset = 0;
|
|
389
|
-
while (true) {
|
|
390
|
-
const response = await this.client.dbfs.read({
|
|
391
|
-
path: absolutePath,
|
|
392
|
-
offset,
|
|
393
|
-
length: DBFS_READ_CHUNK_BYTES,
|
|
394
|
-
});
|
|
395
|
-
const chunk = decodeDbfsPayload(response.data);
|
|
396
|
-
if (chunk.length === 0)
|
|
397
|
-
break;
|
|
398
|
-
chunks.push(chunk);
|
|
399
|
-
offset += chunk.length;
|
|
400
|
-
if (chunk.length < DBFS_READ_CHUNK_BYTES)
|
|
401
|
-
break;
|
|
402
|
-
}
|
|
403
|
-
return Buffer.concat(chunks);
|
|
404
|
-
}
|
|
405
|
-
async readWorkspaceFile(absolutePath) {
|
|
406
|
-
const response = await this.client.workspace.export({
|
|
407
|
-
path: absolutePath,
|
|
408
|
-
format: "AUTO",
|
|
409
|
-
});
|
|
410
|
-
return decodeDbfsPayload(response.content);
|
|
411
|
-
}
|
|
412
|
-
async writeDbfsFile(absolutePath, buffer, overwrite) {
|
|
413
|
-
if (buffer.length <= DBFS_PUT_MAX_BYTES) {
|
|
414
|
-
await this.client.dbfs.put({
|
|
415
|
-
path: absolutePath,
|
|
416
|
-
contents: buffer.toString("base64"),
|
|
417
|
-
overwrite,
|
|
418
|
-
});
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
const created = await this.client.dbfs.create({ path: absolutePath, overwrite });
|
|
422
|
-
const handle = created.handle;
|
|
423
|
-
if (handle === undefined) {
|
|
424
|
-
throw ExecutionError.missingData("DBFS upload handle");
|
|
425
|
-
}
|
|
426
|
-
for (let offset = 0; offset < buffer.length; offset += DBFS_PUT_MAX_BYTES) {
|
|
427
|
-
const slice = buffer.subarray(offset, offset + DBFS_PUT_MAX_BYTES);
|
|
428
|
-
await this.client.dbfs.addBlock({
|
|
429
|
-
handle,
|
|
430
|
-
data: slice.toString("base64"),
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
await this.client.dbfs.close({ handle });
|
|
434
|
-
}
|
|
435
|
-
async writeWorkspaceFile(absolutePath, buffer, overwrite) {
|
|
436
|
-
await this.client.workspace.import({
|
|
437
|
-
path: absolutePath,
|
|
438
|
-
format: "AUTO",
|
|
439
|
-
content: buffer.toString("base64"),
|
|
440
|
-
overwrite,
|
|
441
|
-
});
|
|
69
|
+
await this.fs.close();
|
|
442
70
|
}
|
|
443
|
-
/* --- MastraFilesystem API --- */
|
|
444
71
|
getInfo() {
|
|
445
72
|
return {
|
|
446
73
|
id: this.id,
|
|
@@ -448,511 +75,164 @@ export class DatabricksWorkspaceFilesystem extends MastraFilesystem {
|
|
|
448
75
|
provider: this.provider,
|
|
449
76
|
status: this.status,
|
|
450
77
|
readOnly: this.readOnly,
|
|
451
|
-
metadata: {
|
|
78
|
+
metadata: { root: this.fs.root, backend: this.fs.backend },
|
|
452
79
|
};
|
|
453
80
|
}
|
|
454
81
|
getInstructions() {
|
|
455
82
|
return [
|
|
456
|
-
`Files
|
|
457
|
-
"Workspace paths are absolute within this
|
|
458
|
-
"Workspace paths use `/Workspace/...`, `/Users/...`, or `/Repos/...` base paths.",
|
|
459
|
-
"Unity Catalog volumes use `/Volumes/<catalog>/<schema>/<volume>/...` base paths.",
|
|
83
|
+
`Files are served by a ${this.fs.backend} filesystem rooted at ${this.fs.root}.`,
|
|
84
|
+
"Workspace paths are absolute within this mount (for example `/notes/report.md`).",
|
|
460
85
|
].join(" ");
|
|
461
86
|
}
|
|
462
|
-
/** Map a workspace-relative path to the backing Databricks absolute path. */
|
|
463
|
-
resolveAbsolutePath(inputPath) {
|
|
464
|
-
return this.resolvePath(inputPath);
|
|
465
|
-
}
|
|
466
|
-
/** Read file contents from the workspace namespace. */
|
|
467
87
|
async readFile(inputPath, options) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
const buffer = await this.readAbsolute(absolutePath);
|
|
475
|
-
return formatReadResult(buffer, options?.encoding);
|
|
476
|
-
}
|
|
477
|
-
catch (err) {
|
|
478
|
-
this.rethrow(err, inputPath);
|
|
479
|
-
}
|
|
88
|
+
return this.delegate(inputPath, async () => {
|
|
89
|
+
if (options?.encoding) {
|
|
90
|
+
return this.fs.readFile(inputPath, { encoding: options.encoding });
|
|
91
|
+
}
|
|
92
|
+
return Buffer.from(await this.fs.readFile(inputPath));
|
|
93
|
+
});
|
|
480
94
|
}
|
|
481
|
-
/** Write file contents into the workspace namespace. */
|
|
482
95
|
async writeFile(inputPath, content, options) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
return empty.writeFile(inputPath, content, options);
|
|
487
|
-
this.assertWritable("writeFile");
|
|
488
|
-
const absolutePath = this.resolvePath(inputPath);
|
|
489
|
-
const buffer = toBuffer(content);
|
|
490
|
-
const overwrite = options?.overwrite ?? true;
|
|
491
|
-
try {
|
|
492
|
-
if (!overwrite && (await this.exists(inputPath))) {
|
|
493
|
-
throw new FileExistsError(inputPath);
|
|
96
|
+
return this.delegateWrite("writeFile", inputPath, async () => {
|
|
97
|
+
if (options?.recursive === false) {
|
|
98
|
+
await this.assertParentExists(inputPath);
|
|
494
99
|
}
|
|
495
|
-
await this.
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
throw err;
|
|
500
|
-
this.rethrow(err, inputPath);
|
|
501
|
-
}
|
|
100
|
+
await this.fs.writeFile(inputPath, content, {
|
|
101
|
+
overwrite: options?.overwrite ?? true,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
502
104
|
}
|
|
503
|
-
/** Append to an existing file, creating it when missing. */
|
|
504
105
|
async appendFile(inputPath, content) {
|
|
505
|
-
|
|
506
|
-
const empty = await this.emptyFallback();
|
|
507
|
-
if (empty)
|
|
508
|
-
return empty.appendFile(inputPath, content);
|
|
509
|
-
this.assertWritable("appendFile");
|
|
510
|
-
const existing = (await this.exists(inputPath))
|
|
511
|
-
? await this.readFile(inputPath)
|
|
512
|
-
: Buffer.alloc(0);
|
|
513
|
-
const merged = Buffer.concat([
|
|
514
|
-
Buffer.isBuffer(existing) ? existing : Buffer.from(existing, "utf8"),
|
|
515
|
-
toBuffer(content),
|
|
516
|
-
]);
|
|
517
|
-
await this.writeFile(inputPath, merged, { overwrite: true });
|
|
106
|
+
return this.delegateWrite("appendFile", inputPath, () => this.fs.appendFile(inputPath, content));
|
|
518
107
|
}
|
|
519
|
-
/** Delete a file in the workspace namespace. */
|
|
520
108
|
async deleteFile(inputPath, options) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
this.assertWritable("deleteFile");
|
|
526
|
-
const absolutePath = this.resolvePath(inputPath);
|
|
527
|
-
try {
|
|
528
|
-
if (!(await this.exists(inputPath))) {
|
|
529
|
-
if (options?.force)
|
|
530
|
-
return;
|
|
531
|
-
throw new FileNotFoundError(inputPath);
|
|
532
|
-
}
|
|
533
|
-
const entry = await this.stat(inputPath);
|
|
534
|
-
if (entry.type === "directory") {
|
|
535
|
-
throw new IsDirectoryError(inputPath);
|
|
536
|
-
}
|
|
537
|
-
await this.deleteAbsoluteFile(absolutePath);
|
|
538
|
-
}
|
|
539
|
-
catch (err) {
|
|
540
|
-
if (err instanceof FileNotFoundError || err instanceof IsDirectoryError)
|
|
541
|
-
throw err;
|
|
542
|
-
this.rethrow(err, inputPath);
|
|
543
|
-
}
|
|
109
|
+
return this.delegateWrite("deleteFile", inputPath, () => this.fs.deleteFile(inputPath, {
|
|
110
|
+
force: options?.force,
|
|
111
|
+
recursive: options?.recursive,
|
|
112
|
+
}));
|
|
544
113
|
}
|
|
545
|
-
/** Copy a file within the workspace namespace. */
|
|
546
114
|
async copyFile(src, dest, options) {
|
|
547
|
-
|
|
548
|
-
const empty = await this.emptyFallback();
|
|
549
|
-
if (empty)
|
|
550
|
-
return empty.copyFile(src, dest, options);
|
|
551
|
-
this.assertWritable("copyFile");
|
|
552
|
-
const overwrite = options?.overwrite ?? true;
|
|
553
|
-
if (!overwrite && (await this.exists(dest))) {
|
|
554
|
-
throw new FileExistsError(dest);
|
|
555
|
-
}
|
|
556
|
-
const content = await this.readFile(src);
|
|
557
|
-
await this.writeFile(dest, content, { overwrite: true });
|
|
115
|
+
return this.delegateWrite("copyFile", dest, () => this.fs.copyFile(src, dest, { overwrite: options?.overwrite ?? true }));
|
|
558
116
|
}
|
|
559
|
-
/** Move or rename a file within the workspace namespace. */
|
|
560
117
|
async moveFile(src, dest, options) {
|
|
561
|
-
|
|
562
|
-
const empty = await this.emptyFallback();
|
|
563
|
-
if (empty)
|
|
564
|
-
return empty.moveFile(src, dest, options);
|
|
565
|
-
this.assertWritable("moveFile");
|
|
566
|
-
const srcAbsolute = this.resolvePath(src);
|
|
567
|
-
const destAbsolute = this.resolvePath(dest);
|
|
568
|
-
const overwrite = options?.overwrite ?? true;
|
|
569
|
-
try {
|
|
570
|
-
if (!overwrite && (await this.exists(dest))) {
|
|
571
|
-
throw new FileExistsError(dest);
|
|
572
|
-
}
|
|
573
|
-
if (resolveFilesBackend(srcAbsolute) === "dbfs" &&
|
|
574
|
-
resolveFilesBackend(destAbsolute) === "dbfs") {
|
|
575
|
-
await this.client.dbfs.move({
|
|
576
|
-
source_path: srcAbsolute,
|
|
577
|
-
destination_path: destAbsolute,
|
|
578
|
-
});
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
await this.copyFile(src, dest, { overwrite: true });
|
|
582
|
-
await this.deleteFile(src, { force: true });
|
|
583
|
-
}
|
|
584
|
-
catch (err) {
|
|
585
|
-
if (err instanceof FileExistsError)
|
|
586
|
-
throw err;
|
|
587
|
-
this.rethrow(err, dest);
|
|
588
|
-
}
|
|
118
|
+
return this.delegateWrite("moveFile", dest, () => this.fs.moveFile(src, dest, { overwrite: options?.overwrite ?? true }));
|
|
589
119
|
}
|
|
590
|
-
/** Create a directory in the workspace namespace. */
|
|
591
120
|
async mkdir(inputPath, options) {
|
|
592
|
-
|
|
593
|
-
const empty = await this.emptyFallback();
|
|
594
|
-
if (empty)
|
|
595
|
-
return empty.mkdir(inputPath, options);
|
|
596
|
-
this.assertWritable("mkdir");
|
|
597
|
-
const absolutePath = this.resolvePath(inputPath);
|
|
598
|
-
try {
|
|
599
|
-
await this.mkdirAbsolute(absolutePath);
|
|
600
|
-
if (!options?.recursive) {
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
catch (err) {
|
|
605
|
-
this.rethrow(err, inputPath);
|
|
606
|
-
}
|
|
121
|
+
return this.delegateWrite("mkdir", inputPath, () => this.fs.mkdir(inputPath, { recursive: options?.recursive }));
|
|
607
122
|
}
|
|
608
|
-
/** Remove a directory from the workspace namespace. */
|
|
609
123
|
async rmdir(inputPath, options) {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
this.assertWritable("rmdir");
|
|
615
|
-
const absolutePath = this.resolvePath(inputPath);
|
|
616
|
-
try {
|
|
617
|
-
if (!(await this.exists(inputPath))) {
|
|
618
|
-
if (options?.force)
|
|
619
|
-
return;
|
|
620
|
-
throw new DirectoryNotFoundError(inputPath);
|
|
621
|
-
}
|
|
622
|
-
const entry = await this.stat(inputPath);
|
|
623
|
-
if (entry.type !== "directory") {
|
|
624
|
-
throw new NotDirectoryError(inputPath);
|
|
625
|
-
}
|
|
626
|
-
await this.deleteAbsolutePath(absolutePath, options?.recursive ?? false);
|
|
627
|
-
}
|
|
628
|
-
catch (err) {
|
|
629
|
-
if (err instanceof DirectoryNotFoundError ||
|
|
630
|
-
err instanceof NotDirectoryError ||
|
|
631
|
-
err instanceof DirectoryNotEmptyError) {
|
|
632
|
-
throw err;
|
|
633
|
-
}
|
|
634
|
-
this.rethrow(err, inputPath);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
/**
|
|
638
|
-
* Recursively delete a Unity Catalog directory tree.
|
|
639
|
-
*
|
|
640
|
-
* DBFS and workspace trees use native recursive delete via
|
|
641
|
-
* {@link deleteAbsolutePath} instead.
|
|
642
|
-
*/
|
|
643
|
-
async deleteUcDirectoryRecursive(absolutePath) {
|
|
644
|
-
for (const child of await this.listAbsoluteDirectory(absolutePath)) {
|
|
645
|
-
const childAbsolute = path.join(absolutePath, child.name);
|
|
646
|
-
if (child.type === "directory") {
|
|
647
|
-
await this.deleteUcDirectoryRecursive(childAbsolute);
|
|
648
|
-
}
|
|
649
|
-
else {
|
|
650
|
-
await this.deleteAbsoluteFile(childAbsolute);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
await this.client.files.deleteDirectory({ directory_path: absolutePath });
|
|
124
|
+
return this.delegateWrite("rmdir", inputPath, () => this.fs.rmdir(inputPath, {
|
|
125
|
+
force: options?.force,
|
|
126
|
+
recursive: options?.recursive,
|
|
127
|
+
}), { preferDirectory: true });
|
|
654
128
|
}
|
|
655
|
-
/* --- directory listing --- */
|
|
656
|
-
/** List entries in a workspace directory. */
|
|
657
129
|
async readdir(inputPath, options) {
|
|
658
|
-
await this.
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
try {
|
|
664
|
-
const entries = await this.listAbsoluteDirectory(absolutePath);
|
|
665
|
-
const filtered = this.filterEntries(entries, options);
|
|
666
|
-
if (!options?.recursive)
|
|
667
|
-
return filtered;
|
|
668
|
-
return await this.readDirectoryRecursive(absolutePath, options, 0);
|
|
669
|
-
}
|
|
670
|
-
catch (err) {
|
|
671
|
-
this.rethrow(err, inputPath);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
async readDirectoryRecursive(absolutePath, options, depth, relativePrefix = "") {
|
|
675
|
-
const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
|
|
676
|
-
const entries = this.filterEntries(await this.listAbsoluteDirectory(absolutePath), options);
|
|
677
|
-
const collected = [];
|
|
678
|
-
for (const entry of entries) {
|
|
679
|
-
const relativeName = relativePrefix ? path.join(relativePrefix, entry.name) : entry.name;
|
|
680
|
-
collected.push({ ...entry, name: relativeName });
|
|
681
|
-
if (entry.type !== "directory" || depth >= maxDepth)
|
|
682
|
-
continue;
|
|
683
|
-
collected.push(...(await this.readDirectoryRecursive(path.join(absolutePath, entry.name), options, depth + 1, relativeName)));
|
|
684
|
-
}
|
|
685
|
-
return collected;
|
|
686
|
-
}
|
|
687
|
-
async listAbsoluteDirectory(absolutePath) {
|
|
688
|
-
return dispatchFilesBackend(absolutePath, {
|
|
689
|
-
dbfs: async () => {
|
|
690
|
-
const entries = [];
|
|
691
|
-
for await (const info of this.client.dbfs.list({ path: absolutePath })) {
|
|
692
|
-
entries.push({
|
|
693
|
-
name: path.basename(info.path ?? ""),
|
|
694
|
-
type: info.is_dir ? "directory" : "file",
|
|
695
|
-
size: info.file_size,
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
return entries;
|
|
699
|
-
},
|
|
700
|
-
workspace: async () => {
|
|
701
|
-
const entries = [];
|
|
702
|
-
for await (const info of this.client.workspace.list({ path: absolutePath })) {
|
|
703
|
-
entries.push({
|
|
704
|
-
name: path.basename(info.path ?? ""),
|
|
705
|
-
type: info.object_type === "DIRECTORY" ? "directory" : "file",
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
return entries;
|
|
709
|
-
},
|
|
710
|
-
ucFiles: async () => {
|
|
711
|
-
const entries = [];
|
|
712
|
-
for await (const entry of this.client.files.listDirectoryContents({
|
|
713
|
-
directory_path: absolutePath,
|
|
714
|
-
})) {
|
|
715
|
-
entries.push({
|
|
716
|
-
name: entry.name ?? path.basename(entry.path ?? ""),
|
|
717
|
-
type: entry.is_directory ? "directory" : "file",
|
|
718
|
-
size: entry.file_size,
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
|
-
return entries;
|
|
722
|
-
},
|
|
723
|
-
});
|
|
724
|
-
}
|
|
725
|
-
/** Apply Mastra list filters (`extension`, etc.) to directory entries. */
|
|
726
|
-
filterEntries(entries, options) {
|
|
727
|
-
if (!options?.extension)
|
|
728
|
-
return entries;
|
|
729
|
-
const extensions = Array.isArray(options.extension) ? options.extension : [options.extension];
|
|
730
|
-
const normalized = extensions.map((ext) => ext.startsWith(".") ? ext.toLowerCase() : `.${ext.toLowerCase()}`);
|
|
731
|
-
return entries.filter((entry) => {
|
|
732
|
-
if (entry.type !== "file")
|
|
733
|
-
return true;
|
|
734
|
-
const lower = entry.name.toLowerCase();
|
|
735
|
-
return normalized.some((ext) => lower.endsWith(ext));
|
|
736
|
-
});
|
|
130
|
+
return this.delegate(inputPath, async () => (await this.fs.readdir(inputPath, {
|
|
131
|
+
recursive: options?.recursive,
|
|
132
|
+
maxDepth: options?.maxDepth,
|
|
133
|
+
extension: options?.extension,
|
|
134
|
+
})).map(toMastraEntry), { preferDirectory: true });
|
|
737
135
|
}
|
|
738
|
-
/* --- metadata --- */
|
|
739
|
-
/** Return whether `inputPath` exists in the workspace namespace. */
|
|
740
136
|
async exists(inputPath) {
|
|
741
137
|
await this.ensureReady();
|
|
742
|
-
|
|
743
|
-
if (empty)
|
|
744
|
-
return empty.exists(inputPath);
|
|
745
|
-
try {
|
|
746
|
-
await this.stat(inputPath);
|
|
747
|
-
return true;
|
|
748
|
-
}
|
|
749
|
-
catch (err) {
|
|
750
|
-
if (err instanceof FileNotFoundError)
|
|
751
|
-
return false;
|
|
752
|
-
throw err;
|
|
753
|
-
}
|
|
138
|
+
return this.fs.exists(inputPath);
|
|
754
139
|
}
|
|
755
|
-
/** Return file or directory metadata for `inputPath`. */
|
|
756
140
|
async stat(inputPath) {
|
|
141
|
+
return this.delegate(inputPath, async () => toMastraStat(await this.fs.stat(inputPath), inputPath));
|
|
142
|
+
}
|
|
143
|
+
async delegate(path, op, options) {
|
|
757
144
|
await this.ensureReady();
|
|
758
|
-
const empty = await this.emptyFallback();
|
|
759
|
-
if (empty)
|
|
760
|
-
return empty.stat(inputPath);
|
|
761
|
-
const absolutePath = this.resolvePath(inputPath);
|
|
762
|
-
const workspacePath = this.workspacePath(absolutePath);
|
|
763
145
|
try {
|
|
764
|
-
return await
|
|
765
|
-
dbfs: async () => {
|
|
766
|
-
const info = await this.client.dbfs.getStatus({ path: absolutePath });
|
|
767
|
-
return {
|
|
768
|
-
name: path.basename(info.path ?? absolutePath),
|
|
769
|
-
path: workspacePath,
|
|
770
|
-
type: info.is_dir ? "directory" : "file",
|
|
771
|
-
size: info.file_size ?? 0,
|
|
772
|
-
createdAt: new Date(info.modification_time ?? 0),
|
|
773
|
-
modifiedAt: new Date(info.modification_time ?? 0),
|
|
774
|
-
};
|
|
775
|
-
},
|
|
776
|
-
workspace: async () => {
|
|
777
|
-
const info = await this.client.workspace.getStatus({ path: absolutePath });
|
|
778
|
-
return {
|
|
779
|
-
name: path.basename(info.path ?? absolutePath),
|
|
780
|
-
path: workspacePath,
|
|
781
|
-
type: info.object_type === "DIRECTORY" ? "directory" : "file",
|
|
782
|
-
size: 0,
|
|
783
|
-
createdAt: new Date(info.created_at ?? 0),
|
|
784
|
-
modifiedAt: new Date(info.modified_at ?? 0),
|
|
785
|
-
};
|
|
786
|
-
},
|
|
787
|
-
ucFiles: () => this.statUcAbsolute(absolutePath, workspacePath, inputPath),
|
|
788
|
-
});
|
|
146
|
+
return await op();
|
|
789
147
|
}
|
|
790
148
|
catch (err) {
|
|
791
|
-
this.rethrow(err,
|
|
149
|
+
this.rethrow(err, path, options);
|
|
792
150
|
}
|
|
793
151
|
}
|
|
794
|
-
/**
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
async statUcAbsolute(absolutePath, workspacePath, inputPath) {
|
|
799
|
-
try {
|
|
800
|
-
const metadata = await this.client.files.getMetadata({
|
|
801
|
-
file_path: absolutePath,
|
|
802
|
-
});
|
|
803
|
-
return {
|
|
804
|
-
name: path.basename(absolutePath),
|
|
805
|
-
path: workspacePath,
|
|
806
|
-
type: "file",
|
|
807
|
-
size: Number(metadata["content-length"] ?? 0),
|
|
808
|
-
createdAt: parseHttpDate(metadata["last-modified"]),
|
|
809
|
-
modifiedAt: parseHttpDate(metadata["last-modified"]),
|
|
810
|
-
mimeType: metadata["content-type"],
|
|
811
|
-
};
|
|
812
|
-
}
|
|
813
|
-
catch (fileErr) {
|
|
814
|
-
if (!error.errorContext(fileErr).notAccessible) {
|
|
815
|
-
this.rethrow(fileErr, inputPath);
|
|
816
|
-
}
|
|
817
|
-
await this.client.files.getDirectoryMetadata({
|
|
818
|
-
directory_path: absolutePath,
|
|
819
|
-
});
|
|
820
|
-
return {
|
|
821
|
-
name: path.basename(absolutePath),
|
|
822
|
-
path: workspacePath,
|
|
823
|
-
type: "directory",
|
|
824
|
-
size: 0,
|
|
825
|
-
createdAt: new Date(0),
|
|
826
|
-
modifiedAt: new Date(0),
|
|
827
|
-
};
|
|
152
|
+
/** {@link delegate} for a mutation: refuse a read-only mount before doing any work. */
|
|
153
|
+
delegateWrite(operation, path, op, options) {
|
|
154
|
+
if (this.readOnly) {
|
|
155
|
+
throw new WorkspaceReadOnlyError(operation);
|
|
828
156
|
}
|
|
157
|
+
return this.delegate(path, op, options);
|
|
829
158
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
159
|
+
/** When Mastra asks for non-recursive writes, require the parent directory. */
|
|
160
|
+
async assertParentExists(inputPath) {
|
|
161
|
+
const parent = posixPath.dirname(normalizeWorkspacePath(inputPath));
|
|
162
|
+
if (parent === "/" || (await this.fs.exists(parent)))
|
|
163
|
+
return;
|
|
164
|
+
throw new DirectoryNotFoundError(parent);
|
|
165
|
+
}
|
|
166
|
+
rethrow(err, inputPath, options) {
|
|
167
|
+
if (err instanceof FileNotFoundError ||
|
|
168
|
+
err instanceof DirectoryNotFoundError ||
|
|
169
|
+
err instanceof FileExistsError ||
|
|
170
|
+
err instanceof IsDirectoryError ||
|
|
171
|
+
err instanceof NotDirectoryError ||
|
|
172
|
+
err instanceof DirectoryNotEmptyError ||
|
|
173
|
+
err instanceof PermissionError ||
|
|
174
|
+
err instanceof WorkspaceReadOnlyError) {
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
if (err instanceof FileSystemError) {
|
|
178
|
+
throw mapSharedError(err, inputPath, options?.preferDirectory === true);
|
|
179
|
+
}
|
|
180
|
+
throw err;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** Fresh writable local temp mount on a root unique to this call. */
|
|
184
|
+
export function scratchFilesystem() {
|
|
185
|
+
return filesystems(localFS.scratchFS("mastra"));
|
|
186
|
+
}
|
|
187
|
+
/** Map a shared-fs error code onto the matching Mastra filesystem error. */
|
|
188
|
+
function mapSharedError(err, inputPath, preferDirectory) {
|
|
189
|
+
const path = err.path ?? inputPath;
|
|
190
|
+
switch (err.code) {
|
|
191
|
+
case "NOT_FOUND":
|
|
192
|
+
return preferDirectory ? new DirectoryNotFoundError(path) : new FileNotFoundError(path);
|
|
193
|
+
case "ALREADY_EXISTS":
|
|
194
|
+
return new FileExistsError(path);
|
|
195
|
+
case "NOT_DIRECTORY":
|
|
196
|
+
return new NotDirectoryError(path);
|
|
197
|
+
case "IS_DIRECTORY":
|
|
198
|
+
return new IsDirectoryError(path);
|
|
199
|
+
case "DIRECTORY_NOT_EMPTY":
|
|
200
|
+
return new DirectoryNotEmptyError(path);
|
|
201
|
+
case "PERMISSION_DENIED":
|
|
202
|
+
return new PermissionError(path, err.message);
|
|
203
|
+
case "READ_ONLY":
|
|
204
|
+
return new WorkspaceReadOnlyError(err.message);
|
|
205
|
+
default:
|
|
206
|
+
return err;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function toMastraEntry(entry) {
|
|
210
|
+
return {
|
|
211
|
+
name: entry.name,
|
|
212
|
+
type: entry.type === "directory" ? "directory" : "file",
|
|
213
|
+
size: entry.size,
|
|
214
|
+
isSymlink: entry.type === "symbolic-link",
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function toMastraStat(stat, inputPath) {
|
|
218
|
+
const epoch = new Date(0);
|
|
219
|
+
return {
|
|
220
|
+
name: stat.name,
|
|
221
|
+
path: normalizeWorkspacePath(stat.path || inputPath),
|
|
222
|
+
type: stat.type === "directory" ? "directory" : "file",
|
|
223
|
+
size: stat.size ?? 0,
|
|
224
|
+
createdAt: stat.createdAt ?? epoch,
|
|
225
|
+
modifiedAt: stat.modifiedAt ?? epoch,
|
|
226
|
+
mimeType: stat.mimeType,
|
|
227
|
+
};
|
|
841
228
|
}
|
|
842
229
|
/**
|
|
843
|
-
*
|
|
844
|
-
*
|
|
230
|
+
* Mastra namespace path (`/a/b`). A `..` that would escape clamps to the root
|
|
231
|
+
* rather than throwing - the wrapped filesystem enforces containment itself,
|
|
232
|
+
* and a mount should not fail a listing over a stray segment.
|
|
845
233
|
*/
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
provider = "empty";
|
|
850
|
-
readOnly = true;
|
|
851
|
-
status = "pending";
|
|
852
|
-
constructor() {
|
|
853
|
-
super({ name: "EmptyFilesystem" });
|
|
854
|
-
}
|
|
855
|
-
async init() {
|
|
856
|
-
// No remote or on-disk resources to provision.
|
|
857
|
-
}
|
|
858
|
-
async destroy() {
|
|
859
|
-
// Stateless; nothing to release.
|
|
860
|
-
}
|
|
861
|
-
getInfo() {
|
|
862
|
-
return {
|
|
863
|
-
id: this.id,
|
|
864
|
-
name: this.name,
|
|
865
|
-
provider: this.provider,
|
|
866
|
-
status: this.status,
|
|
867
|
-
readOnly: this.readOnly,
|
|
868
|
-
};
|
|
869
|
-
}
|
|
870
|
-
getInstructions() {
|
|
871
|
-
return "This filesystem is empty and read-only.";
|
|
872
|
-
}
|
|
873
|
-
rootStat() {
|
|
874
|
-
return {
|
|
875
|
-
name: "/",
|
|
876
|
-
path: "/",
|
|
877
|
-
type: "directory",
|
|
878
|
-
size: 0,
|
|
879
|
-
createdAt: EMPTY_FILESYSTEM_EPOCH,
|
|
880
|
-
modifiedAt: EMPTY_FILESYSTEM_EPOCH,
|
|
881
|
-
};
|
|
882
|
-
}
|
|
883
|
-
assertWritable(operation) {
|
|
884
|
-
throw new WorkspaceReadOnlyError(operation);
|
|
885
|
-
}
|
|
886
|
-
async readFile(inputPath, _options) {
|
|
887
|
-
await this.ensureReady();
|
|
888
|
-
const normalized = normalizeEmptyFilesystemPath(inputPath);
|
|
889
|
-
if (normalized === "/") {
|
|
890
|
-
throw new IsDirectoryError(normalized);
|
|
891
|
-
}
|
|
892
|
-
throw new FileNotFoundError(normalized);
|
|
893
|
-
}
|
|
894
|
-
async writeFile(_inputPath, _content, _options) {
|
|
895
|
-
await this.ensureReady();
|
|
896
|
-
this.assertWritable("writeFile");
|
|
897
|
-
}
|
|
898
|
-
async appendFile(_inputPath, _content) {
|
|
899
|
-
await this.ensureReady();
|
|
900
|
-
this.assertWritable("appendFile");
|
|
901
|
-
}
|
|
902
|
-
async deleteFile(inputPath, options) {
|
|
903
|
-
await this.ensureReady();
|
|
904
|
-
const normalized = normalizeEmptyFilesystemPath(inputPath);
|
|
905
|
-
if (normalized === "/") {
|
|
906
|
-
throw new IsDirectoryError(normalized);
|
|
907
|
-
}
|
|
908
|
-
if (options?.force)
|
|
909
|
-
return;
|
|
910
|
-
throw new FileNotFoundError(normalized);
|
|
911
|
-
}
|
|
912
|
-
async copyFile(src, _dest, _options) {
|
|
913
|
-
await this.ensureReady();
|
|
914
|
-
const normalizedSrc = normalizeEmptyFilesystemPath(src);
|
|
915
|
-
if (normalizedSrc !== "/") {
|
|
916
|
-
throw new FileNotFoundError(normalizedSrc);
|
|
917
|
-
}
|
|
918
|
-
throw new IsDirectoryError(normalizedSrc);
|
|
919
|
-
}
|
|
920
|
-
async moveFile(src, dest, options) {
|
|
921
|
-
await this.copyFile(src, dest, options);
|
|
922
|
-
}
|
|
923
|
-
async mkdir(_inputPath, _options) {
|
|
924
|
-
await this.ensureReady();
|
|
925
|
-
this.assertWritable("mkdir");
|
|
926
|
-
}
|
|
927
|
-
async rmdir(inputPath, options) {
|
|
928
|
-
await this.ensureReady();
|
|
929
|
-
const normalized = normalizeEmptyFilesystemPath(inputPath);
|
|
930
|
-
if (normalized === "/") {
|
|
931
|
-
throw new DirectoryNotEmptyError(normalized);
|
|
932
|
-
}
|
|
933
|
-
if (options?.force)
|
|
934
|
-
return;
|
|
935
|
-
throw new DirectoryNotFoundError(normalized);
|
|
936
|
-
}
|
|
937
|
-
async readdir(inputPath, _options) {
|
|
938
|
-
await this.ensureReady();
|
|
939
|
-
const normalized = normalizeEmptyFilesystemPath(inputPath);
|
|
940
|
-
if (normalized === "/")
|
|
941
|
-
return [];
|
|
942
|
-
throw new DirectoryNotFoundError(normalized);
|
|
943
|
-
}
|
|
944
|
-
async exists(inputPath) {
|
|
945
|
-
await this.ensureReady();
|
|
946
|
-
return normalizeEmptyFilesystemPath(inputPath) === "/";
|
|
947
|
-
}
|
|
948
|
-
async stat(inputPath) {
|
|
949
|
-
await this.ensureReady();
|
|
950
|
-
const normalized = normalizeEmptyFilesystemPath(inputPath);
|
|
951
|
-
if (normalized === "/")
|
|
952
|
-
return this.rootStat();
|
|
953
|
-
throw new FileNotFoundError(normalized);
|
|
954
|
-
}
|
|
234
|
+
function normalizeWorkspacePath(inputPath) {
|
|
235
|
+
const result = posixPath.normalize(inputPath);
|
|
236
|
+
return result.ok ? result.path : "/";
|
|
955
237
|
}
|
|
956
|
-
/** Memoized singleton empty read-only filesystem for no-op mounts. */
|
|
957
|
-
export const emptyFilesystem = functionModule.memoize(() => new EmptyFilesystem());
|
|
958
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZXN5c3RlbXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmlsZXN5c3RlbXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUVILE9BQU8sRUFBRSxLQUFLLElBQUksSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFMUYsT0FBTyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzFFLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZixpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLHNCQUFzQixHQUN2QixNQUFNLHdCQUF3QixDQUFDO0FBZWhDLDZFQUE2RTtBQUU3RSxNQUFNLHFCQUFxQixHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDMUMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3ZDLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFM0MsMkVBQTJFO0FBQzNFLFNBQVMsc0JBQXNCLENBQUMsR0FBWTtJQUMxQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ1IsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQyxJQUFJLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN0QixPQUFPLGlCQUFpQixDQUFDO1FBQzNCLENBQUM7YUFBTSxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDL0MsT0FBTyxlQUFlLENBQUM7UUFDekIsQ0FBQzthQUFNLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUM5QyxPQUFPLGlCQUFpQixDQUFDO1FBQzNCLENBQUM7YUFBTSxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDekMsT0FBTyxnQkFBZ0IsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUE4QmhELCtFQUErRTtBQUUvRSxtRUFBbUU7QUFDbkUsTUFBTSxVQUFVLDJCQUEyQixDQUFDLFFBQWdCO0lBQzFELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzdCLE1BQU0sZUFBZSxDQUFDLFlBQVksQ0FDaEMsVUFBVSxFQUNWLFFBQVEsRUFDUixrRUFBa0UsQ0FDbkUsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FBQztBQUM1QyxDQUFDO0FBRUQsK0VBQStFO0FBQy9FLE1BQU0sVUFBVSxVQUFVLENBQUMsWUFBb0I7SUFDN0MsT0FBTyxZQUFZLEtBQUssT0FBTyxJQUFJLFlBQVksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDdkUsQ0FBQztBQUVELHNFQUFzRTtBQUN0RSxNQUFNLFVBQVUsb0JBQW9CLENBQUMsWUFBb0I7SUFDdkQsT0FBTyxDQUNMLFlBQVksS0FBSyxZQUFZO1FBQzdCLFlBQVksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1FBQ3RDLFlBQVksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDO1FBQ2xDLFlBQVksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQ25DLENBQUM7QUFDSixDQUFDO0FBV0Q7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLDZCQUE2QixDQUFDLFFBQWdCLEVBQUUsU0FBaUI7SUFDL0UsTUFBTSxJQUFJLEdBQUcsMkJBQTJCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkQsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2pDLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxLQUFLLEdBQUc7UUFBRSxPQUFPLElBQUksQ0FBQztJQUM3QyxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7SUFDckUsSUFBSSxVQUFVLEtBQUssSUFBSSxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDN0QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBRUQsdUVBQXVFO0FBQ3ZFLE1BQU0sVUFBVSx5QkFBeUIsQ0FBQyxRQUFnQixFQUFFLFlBQW9CO0lBQzlFLE1BQU0sSUFBSSxHQUFHLDJCQUEyQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25ELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDaEQsSUFBSSxVQUFVLEtBQUssSUFBSTtRQUFFLE9BQU8sR0FBRyxDQUFDO0lBQ3BDLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0QyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQztJQUM5QyxDQUFDO0lBQ0QsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQztBQUVELCtFQUErRTtBQUUvRSxrRUFBa0U7QUFDbEUsU0FBUyxtQkFBbUIsQ0FBQyxZQUFvQjtJQUMvQyxJQUFJLFVBQVUsQ0FBQyxZQUFZLENBQUM7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUM1QyxJQUFJLG9CQUFvQixDQUFDLFlBQVksQ0FBQztRQUFFLE9BQU8sV0FBVyxDQUFDO0lBQzNELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCx3RUFBd0U7QUFDeEUsS0FBSyxVQUFVLG9CQUFvQixDQUNqQyxZQUFvQixFQUNwQixRQUFpQztJQUVqQyxNQUFNLE9BQU8sR0FBRyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNsRCxJQUFJLE9BQU8sS0FBSyxNQUFNO1FBQUUsT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDL0MsSUFBSSxPQUFPLEtBQUssV0FBVztRQUFFLE9BQU8sUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3pELE9BQU8sUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQzVCLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsU0FBUyxnQkFBZ0IsQ0FBQyxNQUFjLEVBQUUsUUFBeUI7SUFDakUsT0FBTyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUN2RCxDQUFDO0FBRUQsNkRBQTZEO0FBQzdELEtBQUssVUFBVSxnQkFBZ0IsQ0FDN0IsUUFBMkQ7SUFFM0QsSUFBSSxDQUFDLFFBQVE7UUFBRSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3BDLE1BQU0sTUFBTSxHQUFpQixFQUFFLENBQUM7SUFDaEMsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUNaLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUMsSUFBSSxJQUFJO1lBQUUsTUFBTTtRQUNoQixJQUFJLEtBQUs7WUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQUVELHVEQUF1RDtBQUN2RCxTQUFTLFFBQVEsQ0FBQyxPQUFvQjtJQUNwQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVE7UUFBRSxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3JFLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQsOENBQThDO0FBQzlDLFNBQVMsaUJBQWlCLENBQUMsSUFBd0I7SUFDakQsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztBQUNyQyxDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLFNBQVMsc0JBQXNCLENBQUMsTUFBYztJQUM1QyxPQUFPLElBQUksY0FBYyxDQUFhO1FBQ3BDLEtBQUssQ0FBQyxVQUFVO1lBQ2QsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzNDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNyQixDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELHdFQUF3RTtBQUN4RSxTQUFTLGFBQWEsQ0FBQyxLQUF5QjtJQUM5QyxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0IsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsRSxDQUFDO0FBRUQscUVBQXFFO0FBRXJFOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sNkJBQThCLFNBQVEsZ0JBQWdCO0lBQ3hELEVBQUUsQ0FBUztJQUNYLElBQUksR0FBRywrQkFBK0IsQ0FBQztJQUN2QyxRQUFRLEdBQUcsWUFBWSxDQUFDO0lBQ3hCLFFBQVEsQ0FBUztJQUMxQixNQUFNLEdBQW1CLFNBQVMsQ0FBQztJQUVsQixNQUFNLENBQWtCO0lBQ3hCLE1BQU0sQ0FBdUI7SUFDdEMsU0FBUyxDQUFzQjtJQUMvQixnQkFBZ0IsQ0FBc0I7SUFFOUMsSUFBSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsWUFBWSxPQUE2QztRQUN2RCxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsK0JBQStCLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsSUFBSSxpQkFBaUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUMxRSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksbUJBQW1CLEVBQUUsQ0FBQyxNQUFNLENBQUM7UUFDN0QsSUFBSSxDQUFDLFFBQVEsR0FBRywyQkFBMkIsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQztRQUN0QyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7SUFDcEMsQ0FBQztJQUVELDZCQUE2QjtJQUU3Qiw0RUFBNEU7SUFDcEUsV0FBVyxDQUFDLFNBQWlCO1FBQ25DLE1BQU0sUUFBUSxHQUFHLDZCQUE2QixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDekUsSUFBSSxRQUFRLEtBQUssSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzVFLE1BQU0sSUFBSSxlQUFlLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsc0VBQXNFO0lBQzlELGFBQWEsQ0FBQyxZQUFvQjtRQUN4QyxPQUFPLHlCQUF5QixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELDhDQUE4QztJQUN0QyxjQUFjLENBQUMsU0FBaUI7UUFDdEMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlDLENBQUM7SUFDSCxDQUFDO0lBRUQsbUVBQW1FO0lBQzNELE9BQU8sQ0FBQyxHQUFZLEVBQUUsU0FBaUI7UUFDN0MsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7WUFDN0MsQ0FBQyxDQUFDLFNBQVM7WUFDWCxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDcEQsTUFBTSxTQUFTLEdBQUcsc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUMsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUNELDBFQUEwRTtRQUMxRSxtRUFBbUU7UUFDbkUsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUM5QixJQUFJLEVBQUUsYUFBYTtZQUNuQixLQUFLLEVBQUUsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUM7U0FDL0IsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxJQUFJLGNBQWMsQ0FBQyw4Q0FBOEMsYUFBYSxFQUFFLEVBQUU7WUFDdEYsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO1lBQ3pCLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUU7U0FDakMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHVCQUF1QjtJQUV2Qjs7O09BR0c7SUFDSyxLQUFLLENBQUMscUJBQXFCO1FBQ2pDLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLFNBQVM7WUFBRSxPQUFPO1FBQ2hELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNqRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUMxQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO2dCQUM3QixPQUFPO1lBQ1QsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDO0lBRUQseUVBQXlFO0lBQ2pFLEtBQUssQ0FBQyxhQUFhO1FBQ3pCLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDL0QsQ0FBQztJQUVRLEtBQUssQ0FBQyxJQUFJO1FBQ2pCLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFFbkMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxQixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQzFCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7Z0JBQzlCLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDakMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7Z0JBQ3pCLENBQUM7WUFDSCxDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxFQUFFLENBQUM7b0JBQ3pCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUN6QixDQUFDO2dCQUNELE1BQU0sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUU7b0JBQ2hDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtvQkFDdkIsS0FBSyxFQUFFLEtBQUssQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDO2lCQUMvQixDQUFDLENBQUM7WUFDTCxDQUFDO1lBQ0QsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLEtBQUssQ0FBQyxhQUFhO1FBQ3pCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsb0JBQW9CLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3JFLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUN0QixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsZ0VBQWdFO1FBQ2xFLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFUSxLQUFLLENBQUMsT0FBTztRQUNwQixtREFBbUQ7SUFDckQsQ0FBQztJQUVELHlCQUF5QjtJQUV6QixxRUFBcUU7SUFDN0QsS0FBSyxDQUFDLHNCQUFzQixDQUFDLFlBQW9CO1FBQ3ZELE1BQU0sb0JBQW9CLENBQUMsWUFBWSxFQUFFO1lBQ3ZDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUM7WUFDOUQsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQztZQUN4RSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLENBQUM7U0FDeEYsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDBFQUEwRTtJQUNsRSxLQUFLLENBQUMsWUFBWSxDQUFDLFlBQW9CO1FBQzdDLE9BQU8sb0JBQW9CLENBQUMsWUFBWSxFQUFFO1lBQ3hDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQztZQUMzQyxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQztZQUNyRCxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ2xCLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7Z0JBQy9FLE9BQU8sZ0JBQWdCLENBQ3JCLFFBQVEsQ0FBQyxRQUE2RCxDQUN2RSxDQUFDO1lBQ0osQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxnRUFBZ0U7SUFDeEQsS0FBSyxDQUFDLGFBQWEsQ0FDekIsWUFBb0IsRUFDcEIsTUFBYyxFQUNkLFNBQWtCO1FBRWxCLE1BQU0sb0JBQW9CLENBQUMsWUFBWSxFQUFFO1lBQ3ZDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDO1lBQy9ELFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUM7WUFDekUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUM7U0FDbEUsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHlEQUF5RDtJQUNqRCxZQUFZLENBQUMsWUFBb0IsRUFBRSxNQUFjLEVBQUUsU0FBa0I7UUFDM0UsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDOUIsU0FBUyxFQUFFLFlBQVk7WUFDdkIsUUFBUSxFQUFFLHNCQUFzQixDQUFDLE1BQU0sQ0FBVTtZQUNqRCxTQUFTO1NBQ1YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDhEQUE4RDtJQUN0RCxLQUFLLENBQUMsa0JBQWtCLENBQUMsWUFBb0I7UUFDbkQsTUFBTSxvQkFBb0IsQ0FBQyxZQUFZLEVBQUU7WUFDdkMsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQzdFLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUN2RixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxDQUFDO1NBQ3JFLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssS0FBSyxDQUFDLGtCQUFrQixDQUFDLFlBQW9CLEVBQUUsU0FBa0I7UUFDdkUsTUFBTSxvQkFBb0IsQ0FBQyxZQUFZLEVBQUU7WUFDdkMsSUFBSSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNmLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLENBQUM7WUFDRCxTQUFTLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ3BCLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ3hFLENBQUM7WUFDRCxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ2xCLElBQUksU0FBUyxFQUFFLENBQUM7b0JBQ2QsTUFBTSxJQUFJLENBQUMsMEJBQTBCLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3BELE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDaEUsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUN4QixNQUFNLElBQUksc0JBQXNCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUNyRSxDQUFDO2dCQUNELE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7WUFDNUUsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCw2RUFBNkU7SUFDckUsS0FBSyxDQUFDLGFBQWEsQ0FBQyxZQUFvQjtRQUM5QyxNQUFNLG9CQUFvQixDQUFDLFlBQVksRUFBRTtZQUN2QyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDO1lBQzNELFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUM7WUFDckUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsQ0FBQztTQUNuRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVksQ0FBQyxZQUFvQjtRQUM3QyxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFDNUIsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUNaLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUMzQyxJQUFJLEVBQUUsWUFBWTtnQkFDbEIsTUFBTTtnQkFDTixNQUFNLEVBQUUscUJBQXFCO2FBQzlCLENBQUMsQ0FBQztZQUNILE1BQU0sS0FBSyxHQUFHLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFBRSxNQUFNO1lBQzlCLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUM7WUFDdkIsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLHFCQUFxQjtnQkFBRSxNQUFNO1FBQ2xELENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxZQUFvQjtRQUNsRCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztZQUNsRCxJQUFJLEVBQUUsWUFBWTtZQUNsQixNQUFNLEVBQUUsTUFBTTtTQUNmLENBQUMsQ0FBQztRQUNILE9BQU8saUJBQWlCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFTyxLQUFLLENBQUMsYUFBYSxDQUN6QixZQUFvQixFQUNwQixNQUFjLEVBQ2QsU0FBa0I7UUFFbEIsSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLGtCQUFrQixFQUFFLENBQUM7WUFDeEMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7Z0JBQ3pCLElBQUksRUFBRSxZQUFZO2dCQUNsQixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7Z0JBQ25DLFNBQVM7YUFDVixDQUFDLENBQUM7WUFDSCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ2pGLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDOUIsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDekIsTUFBTSxjQUFjLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDekQsQ0FBQztRQUNELEtBQUssSUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFFLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1lBQzFFLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO2dCQUM5QixNQUFNO2dCQUNOLElBQUksRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQzthQUMvQixDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFTyxLQUFLLENBQUMsa0JBQWtCLENBQzlCLFlBQW9CLEVBQ3BCLE1BQWMsRUFDZCxTQUFrQjtRQUVsQixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztZQUNqQyxJQUFJLEVBQUUsWUFBWTtZQUNsQixNQUFNLEVBQUUsTUFBTTtZQUNkLE9BQU8sRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztZQUNsQyxTQUFTO1NBQ1YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtDQUFrQztJQUVsQyxPQUFPO1FBQ0wsT0FBTztZQUNMLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtZQUNYLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtZQUNmLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN2QixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ3ZCLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFO1NBQ3RDLENBQUM7SUFDSixDQUFDO0lBRUQsZUFBZTtRQUNiLE9BQU87WUFDTCxrQ0FBa0MsSUFBSSxDQUFDLFFBQVEsR0FBRztZQUNsRCxpRkFBaUY7WUFDakYsaUZBQWlGO1lBQ2pGLGtGQUFrRjtTQUNuRixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNkLENBQUM7SUFFRCw2RUFBNkU7SUFDN0UsbUJBQW1CLENBQUMsU0FBaUI7UUFDbkMsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCx1REFBdUQ7SUFDdkQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFpQixFQUFFLE9BQXFCO1FBQ3JELE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3pDLElBQUksS0FBSztZQUFFLE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDckQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDckQsT0FBTyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0IsQ0FBQztJQUNILENBQUM7SUFFRCx3REFBd0Q7SUFDeEQsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFpQixFQUFFLE9BQW9CLEVBQUUsT0FBc0I7UUFDN0UsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekMsSUFBSSxLQUFLO1lBQUUsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNqQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNqQyxNQUFNLFNBQVMsR0FBRyxPQUFPLEVBQUUsU0FBUyxJQUFJLElBQUksQ0FBQztRQUM3QyxJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDakQsTUFBTSxJQUFJLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN2QyxDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDNUQsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLEdBQUcsWUFBWSxlQUFlO2dCQUFFLE1BQU0sR0FBRyxDQUFDO1lBQzlDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQsNERBQTREO0lBQzVELEtBQUssQ0FBQyxVQUFVLENBQUMsU0FBaUIsRUFBRSxPQUFvQjtRQUN0RCxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN6QyxJQUFJLEtBQUs7WUFBRSxPQUFPLEtBQUssQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbEMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDN0MsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7WUFDaEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUMzQixNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztZQUNwRSxRQUFRLENBQUMsT0FBTyxDQUFDO1NBQ2xCLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVELGdEQUFnRDtJQUNoRCxLQUFLLENBQUMsVUFBVSxDQUFDLFNBQWlCLEVBQUUsT0FBdUI7UUFDekQsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekMsSUFBSSxLQUFLO1lBQUUsT0FBTyxLQUFLLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxPQUFPLEVBQUUsS0FBSztvQkFBRSxPQUFPO2dCQUMzQixNQUFNLElBQUksaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDekMsQ0FBQztZQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6QyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQy9CLE1BQU0sSUFBSSxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN4QyxDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLEdBQUcsWUFBWSxpQkFBaUIsSUFBSSxHQUFHLFlBQVksZ0JBQWdCO2dCQUFFLE1BQU0sR0FBRyxDQUFDO1lBQ25GLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQsa0RBQWtEO0lBQ2xELEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBVyxFQUFFLElBQVksRUFBRSxPQUFxQjtRQUM3RCxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN6QyxJQUFJLEtBQUs7WUFBRSxPQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sU0FBUyxHQUFHLE9BQU8sRUFBRSxTQUFTLElBQUksSUFBSSxDQUFDO1FBQzdDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzVDLE1BQU0sSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCw0REFBNEQ7SUFDNUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFXLEVBQUUsSUFBWSxFQUFFLE9BQXFCO1FBQzdELE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3pDLElBQUksS0FBSztZQUFFLE9BQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVDLE1BQU0sU0FBUyxHQUFHLE9BQU8sRUFBRSxTQUFTLElBQUksSUFBSSxDQUFDO1FBQzdDLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM1QyxNQUFNLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xDLENBQUM7WUFDRCxJQUNFLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxLQUFLLE1BQU07Z0JBQzNDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxLQUFLLE1BQU0sRUFDNUMsQ0FBQztnQkFDRCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztvQkFDMUIsV0FBVyxFQUFFLFdBQVc7b0JBQ3hCLGdCQUFnQixFQUFFLFlBQVk7aUJBQy9CLENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBQ1QsQ0FBQztZQUNELE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDcEQsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxHQUFHLFlBQVksZUFBZTtnQkFBRSxNQUFNLEdBQUcsQ0FBQztZQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztJQUVELHFEQUFxRDtJQUNyRCxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQWlCLEVBQUUsT0FBaUM7UUFDOUQsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekMsSUFBSSxLQUFLO1lBQUUsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUM7Z0JBQ3hCLE9BQU87WUFDVCxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVELHVEQUF1RDtJQUN2RCxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQWlCLEVBQUUsT0FBdUI7UUFDcEQsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekMsSUFBSSxLQUFLO1lBQUUsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxPQUFPLEVBQUUsS0FBSztvQkFBRSxPQUFPO2dCQUMzQixNQUFNLElBQUksc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDOUMsQ0FBQztZQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6QyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQy9CLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6QyxDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLE9BQU8sRUFBRSxTQUFTLElBQUksS0FBSyxDQUFDLENBQUM7UUFDM0UsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUNFLEdBQUcsWUFBWSxzQkFBc0I7Z0JBQ3JDLEdBQUcsWUFBWSxpQkFBaUI7Z0JBQ2hDLEdBQUcsWUFBWSxzQkFBc0IsRUFDckMsQ0FBQztnQkFDRCxNQUFNLEdBQUcsQ0FBQztZQUNaLENBQUM7WUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssS0FBSyxDQUFDLDBCQUEwQixDQUFDLFlBQW9CO1FBQzNELEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUNuRSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUQsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO2dCQUMvQixNQUFNLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN2RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDL0MsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFRCwrQkFBK0I7SUFFL0IsNkNBQTZDO0lBQzdDLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBaUIsRUFBRSxPQUFxQjtRQUNwRCxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN6QyxJQUFJLEtBQUs7WUFBRSxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3BELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDL0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLE9BQU8sRUFBRSxTQUFTO2dCQUFFLE9BQU8sUUFBUSxDQUFDO1lBQ3pDLE9BQU8sTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsWUFBWSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyRSxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLHNCQUFzQixDQUNsQyxZQUFvQixFQUNwQixPQUFvQixFQUNwQixLQUFhLEVBQ2IsY0FBYyxHQUFHLEVBQUU7UUFFbkIsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsaUJBQWlCLENBQUM7UUFDOUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM1RixNQUFNLFNBQVMsR0FBZ0IsRUFBRSxDQUFDO1FBQ2xDLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxFQUFFLENBQUM7WUFDNUIsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDekYsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxXQUFXLElBQUksS0FBSyxJQUFJLFFBQVE7Z0JBQUUsU0FBUztZQUM5RCxTQUFTLENBQUMsSUFBSSxDQUNaLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUNuQyxPQUFPLEVBQ1AsS0FBSyxHQUFHLENBQUMsRUFDVCxZQUFZLENBQ2IsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVPLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxZQUFvQjtRQUN0RCxPQUFPLG9CQUFvQixDQUFDLFlBQVksRUFBRTtZQUN4QyxJQUFJLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ2YsTUFBTSxPQUFPLEdBQWdCLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxLQUFLLEVBQUUsTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFDdkUsT0FBTyxDQUFDLElBQUksQ0FBQzt3QkFDWCxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQzt3QkFDcEMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTTt3QkFDeEMsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTO3FCQUNyQixDQUFDLENBQUM7Z0JBQ0wsQ0FBQztnQkFDRCxPQUFPLE9BQU8sQ0FBQztZQUNqQixDQUFDO1lBQ0QsU0FBUyxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNwQixNQUFNLE9BQU8sR0FBZ0IsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLEtBQUssRUFBRSxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxDQUFDO29CQUM1RSxPQUFPLENBQUMsSUFBSSxDQUFDO3dCQUNYLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO3dCQUNwQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTTtxQkFDOUQsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBQ0QsT0FBTyxPQUFPLENBQUM7WUFDakIsQ0FBQztZQUNELE9BQU8sRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDbEIsTUFBTSxPQUFPLEdBQWdCLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxLQUFLLEVBQUUsTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUM7b0JBQ2hFLGNBQWMsRUFBRSxZQUFZO2lCQUM3QixDQUFDLEVBQUUsQ0FBQztvQkFDSCxPQUFPLENBQUMsSUFBSSxDQUFDO3dCQUNYLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7d0JBQ25ELElBQUksRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU07d0JBQy9DLElBQUksRUFBRSxLQUFLLENBQUMsU0FBUztxQkFDdEIsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBQ0QsT0FBTyxPQUFPLENBQUM7WUFDakIsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCwwRUFBMEU7SUFDbEUsYUFBYSxDQUFDLE9BQW9CLEVBQUUsT0FBcUI7UUFDL0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxTQUFTO1lBQUUsT0FBTyxPQUFPLENBQUM7UUFDeEMsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlGLE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUN4QyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQ2xFLENBQUM7UUFDRixPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUM5QixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssTUFBTTtnQkFBRSxPQUFPLElBQUksQ0FBQztZQUN2QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHNCQUFzQjtJQUV0QixvRUFBb0U7SUFDcEUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFpQjtRQUM1QixNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN6QyxJQUFJLEtBQUs7WUFBRSxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLEdBQUcsWUFBWSxpQkFBaUI7Z0JBQUUsT0FBTyxLQUFLLENBQUM7WUFDbkQsTUFBTSxHQUFHLENBQUM7UUFDWixDQUFDO0lBQ0gsQ0FBQztJQUVELHlEQUF5RDtJQUN6RCxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQWlCO1FBQzFCLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3pDLElBQUksS0FBSztZQUFFLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLG9CQUFvQixDQUFDLFlBQVksRUFBRTtnQkFDOUMsSUFBSSxFQUFFLEtBQUssSUFBSSxFQUFFO29CQUNmLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7b0JBQ3RFLE9BQU87d0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxZQUFZLENBQUM7d0JBQzlDLElBQUksRUFBRSxhQUFhO3dCQUNuQixJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUUsV0FBcUIsQ0FBQyxDQUFDLENBQUUsTUFBZ0I7d0JBQzlELElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUM7d0JBQ3pCLFNBQVMsRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDO3dCQUNoRCxVQUFVLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixJQUFJLENBQUMsQ0FBQztxQkFDbEQsQ0FBQztnQkFDSixDQUFDO2dCQUNELFNBQVMsRUFBRSxLQUFLLElBQUksRUFBRTtvQkFDcEIsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztvQkFDM0UsT0FBTzt3QkFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQzt3QkFDOUMsSUFBSSxFQUFFLGFBQWE7d0JBQ25CLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVyxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUUsV0FBcUIsQ0FBQyxDQUFDLENBQUUsTUFBZ0I7d0JBQ25GLElBQUksRUFBRSxDQUFDO3dCQUNQLFNBQVMsRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQzt3QkFDekMsVUFBVSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDO3FCQUM1QyxDQUFDO2dCQUNKLENBQUM7Z0JBQ0QsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUM7YUFDM0UsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLEtBQUssQ0FBQyxjQUFjLENBQzFCLFlBQW9CLEVBQ3BCLGFBQXFCLEVBQ3JCLFNBQWlCO1FBRWpCLElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO2dCQUNuRCxTQUFTLEVBQUUsWUFBWTthQUN4QixDQUFDLENBQUM7WUFDSCxPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQztnQkFDakMsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLElBQUksRUFBRSxNQUFlO2dCQUNyQixJQUFJLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDN0MsU0FBUyxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ25ELFVBQVUsRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUNwRCxRQUFRLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQzthQUNuQyxDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sT0FBTyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQy9DLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ25DLENBQUM7WUFDRCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO2dCQUMzQyxjQUFjLEVBQUUsWUFBWTthQUM3QixDQUFDLENBQUM7WUFDSCxPQUFPO2dCQUNMLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQztnQkFDakMsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLElBQUksRUFBRSxXQUFvQjtnQkFDMUIsSUFBSSxFQUFFLENBQUM7Z0JBQ1AsU0FBUyxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDdEIsVUFBVSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQzthQUN4QixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7Q0FDRjtBQUVELDhFQUE4RTtBQUU5RSxvRUFBb0U7QUFDcEUsU0FBUyw0QkFBNEIsQ0FBQyxTQUFpQjtJQUNyRCxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDakMsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLEtBQUssR0FBRztRQUFFLE9BQU8sR0FBRyxDQUFDO0lBQzVDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztRQUN6QixDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDbEMsT0FBTyxVQUFVLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztBQUMvQyxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxlQUFnQixTQUFRLGdCQUFnQjtJQUNuQyxFQUFFLEdBQUcsVUFBVSxDQUFDO0lBQ2hCLElBQUksR0FBRyxpQkFBaUIsQ0FBQztJQUN6QixRQUFRLEdBQUcsT0FBTyxDQUFDO0lBQ25CLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDekIsTUFBTSxHQUFtQixTQUFTLENBQUM7SUFFbkM7UUFDRSxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNqQiwrQ0FBK0M7SUFDakQsQ0FBQztJQUVRLEtBQUssQ0FBQyxPQUFPO1FBQ3BCLGlDQUFpQztJQUNuQyxDQUFDO0lBRUQsT0FBTztRQUNMLE9BQU87WUFDTCxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDWCxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtTQUN4QixDQUFDO0lBQ0osQ0FBQztJQUVELGVBQWU7UUFDYixPQUFPLHlDQUF5QyxDQUFDO0lBQ25ELENBQUM7SUFFTyxRQUFRO1FBQ2QsT0FBTztZQUNMLElBQUksRUFBRSxHQUFHO1lBQ1QsSUFBSSxFQUFFLEdBQUc7WUFDVCxJQUFJLEVBQUUsV0FBVztZQUNqQixJQUFJLEVBQUUsQ0FBQztZQUNQLFNBQVMsRUFBRSxzQkFBc0I7WUFDakMsVUFBVSxFQUFFLHNCQUFzQjtTQUNuQyxDQUFDO0lBQ0osQ0FBQztJQUVPLGNBQWMsQ0FBQyxTQUFpQjtRQUN0QyxNQUFNLElBQUksc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVRLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBaUIsRUFBRSxRQUFzQjtRQUMvRCxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLFVBQVUsR0FBRyw0QkFBNEIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzRCxJQUFJLFVBQVUsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUNELE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRVEsS0FBSyxDQUFDLFNBQVMsQ0FDdEIsVUFBa0IsRUFDbEIsUUFBcUIsRUFDckIsUUFBdUI7UUFFdkIsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRVEsS0FBSyxDQUFDLFVBQVUsQ0FBQyxVQUFrQixFQUFFLFFBQXFCO1FBQ2pFLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVRLEtBQUssQ0FBQyxVQUFVLENBQUMsU0FBaUIsRUFBRSxPQUF1QjtRQUNsRSxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLFVBQVUsR0FBRyw0QkFBNEIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzRCxJQUFJLFVBQVUsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUNELElBQUksT0FBTyxFQUFFLEtBQUs7WUFBRSxPQUFPO1FBQzNCLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRVEsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFXLEVBQUUsS0FBYSxFQUFFLFFBQXNCO1FBQ3hFLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sYUFBYSxHQUFHLDRCQUE0QixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3hELElBQUksYUFBYSxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzFCLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsTUFBTSxJQUFJLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFUSxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQVcsRUFBRSxJQUFZLEVBQUUsT0FBcUI7UUFDdEUsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVRLEtBQUssQ0FBQyxLQUFLLENBQUMsVUFBa0IsRUFBRSxRQUFrQztRQUN6RSxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFUSxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQWlCLEVBQUUsT0FBdUI7UUFDN0QsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsTUFBTSxVQUFVLEdBQUcsNEJBQTRCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsSUFBSSxVQUFVLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDdkIsTUFBTSxJQUFJLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFDRCxJQUFJLE9BQU8sRUFBRSxLQUFLO1lBQUUsT0FBTztRQUMzQixNQUFNLElBQUksc0JBQXNCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVRLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBaUIsRUFBRSxRQUFzQjtRQUM5RCxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLFVBQVUsR0FBRyw0QkFBNEIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzRCxJQUFJLFVBQVUsS0FBSyxHQUFHO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDbEMsTUFBTSxJQUFJLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFUSxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQWlCO1FBQ3JDLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sNEJBQTRCLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxDQUFDO0lBQ3pELENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQWlCO1FBQ25DLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sVUFBVSxHQUFHLDRCQUE0QixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNELElBQUksVUFBVSxLQUFLLEdBQUc7WUFBRSxPQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMvQyxNQUFNLElBQUksaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztDQUNGO0FBRUQsc0VBQXNFO0FBQ3RFLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksZUFBZSxFQUFFLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTWFzdHJhIHtAbGluayBXb3Jrc3BhY2VGaWxlc3lzdGVtfSBpbXBsZW1lbnRhdGlvbnMgZm9yIERhdGFicmlja3MgQXBwcy5cbiAqXG4gKiB7QGxpbmsgRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW19IG1hcHMgYSBNYXN0cmEgd29ya3NwYWNlIG5hbWVzcGFjZSBvbnRvXG4gKiBhbiBhYnNvbHV0ZSBEYXRhYnJpY2tzIHBhdGggKFVuaXR5IENhdGFsb2cgdm9sdW1lLCB3b3Jrc3BhY2Ugb2JqZWN0IHRyZWUsIG9yXG4gKiBEQkZTKS4ge0BsaW5rIGVtcHR5RmlsZXN5c3RlbX0gaXMgYSByZWFkLW9ubHkgbm8tb3AgbW91bnQgdXNlZCB3aGVuIG5vXG4gKiBkeW5hbWljIG1vdW50cyByZXNvbHZlIGZvciBhIHJlcXVlc3QuXG4gKlxuICogUGF0aCBoZWxwZXJzICh7QGxpbmsgbm9ybWFsaXplRGF0YWJyaWNrc0Jhc2VQYXRofSwge0BsaW5rIGlzRGJmc1BhdGh9LCDigKYpXG4gKiBhcmUgZXhwb3J0ZWQgZm9yIHRlc3RzIGFuZCBjYWxsZXJzIHRoYXQgbmVlZCB0byByZWFzb24gYWJvdXQgRGF0YWJyaWNrc1xuICogcGF0aHMgd2l0aG91dCBjb25zdHJ1Y3RpbmcgYSBmaWxlc3lzdGVtLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBwb3NpeCBhcyBwYXRoIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgRXhlY3V0aW9uRXJyb3IsIGdldEV4ZWN1dGlvbkNvbnRleHQsIFZhbGlkYXRpb25FcnJvciB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IFdvcmtzcGFjZUNsaWVudCB9IGZyb20gXCJAZGF0YWJyaWNrcy9zZGstZXhwZXJpbWVudGFsXCI7XG5pbXBvcnQgeyBlcnJvciwgZnVuY3Rpb25Nb2R1bGUsIGhhc2gsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQge1xuICBEaXJlY3RvcnlOb3RFbXB0eUVycm9yLFxuICBEaXJlY3RvcnlOb3RGb3VuZEVycm9yLFxuICBGaWxlRXhpc3RzRXJyb3IsXG4gIEZpbGVOb3RGb3VuZEVycm9yLFxuICBJc0RpcmVjdG9yeUVycm9yLFxuICBNYXN0cmFGaWxlc3lzdGVtLFxuICBOb3REaXJlY3RvcnlFcnJvcixcbiAgUGVybWlzc2lvbkVycm9yLFxuICBXb3Jrc3BhY2VSZWFkT25seUVycm9yLFxufSBmcm9tIFwiQG1hc3RyYS9jb3JlL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHR5cGUge1xuICBDb3B5T3B0aW9ucyxcbiAgRmlsZUNvbnRlbnQsXG4gIEZpbGVFbnRyeSxcbiAgRmlsZVN0YXQsXG4gIEZpbGVzeXN0ZW1JbmZvLFxuICBMaXN0T3B0aW9ucyxcbiAgTWFzdHJhRmlsZXN5c3RlbU9wdGlvbnMsXG4gIFByb3ZpZGVyU3RhdHVzLFxuICBSZWFkT3B0aW9ucyxcbiAgUmVtb3ZlT3B0aW9ucyxcbiAgV3JpdGVPcHRpb25zLFxufSBmcm9tIFwiQG1hc3RyYS9jb3JlL3dvcmtzcGFjZVwiO1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5jb25zdCBEQkZTX1JFQURfQ0hVTktfQllURVMgPSAxMDI0ICogMTAyNDtcbmNvbnN0IERCRlNfUFVUX01BWF9CWVRFUyA9IDEwMjQgKiAxMDI0O1xuY29uc3QgRU1QVFlfRklMRVNZU1RFTV9FUE9DSCA9IG5ldyBEYXRlKDApO1xuXG4vKiogTWFzdHJhIGVycm9yIGNvbnN0cnVjdG9yIGZvciBhIGtub3duIFNESyBmaWxlc3lzdGVtIGZhaWx1cmUsIGlmIGFueS4gKi9cbmZ1bmN0aW9uIGZpbGVzeXN0ZW1TZGtFcnJvclR5cGUoZXJyOiB1bmtub3duKTogKG5ldyAocGF0aDogc3RyaW5nKSA9PiBFcnJvcikgfCB1bmRlZmluZWQge1xuICBpZiAoZXJyKSB7XG4gICAgY29uc3QgY3R4ID0gZXJyb3IuZXJyb3JDb250ZXh0KGVycik7XG4gICAgaWYgKGN0eC5ub3RBY2Nlc3NpYmxlKSB7XG4gICAgICByZXR1cm4gRmlsZU5vdEZvdW5kRXJyb3I7XG4gICAgfSBlbHNlIGlmIChjdHguaGFzTWVzc2FnZShcImFscmVhZHlcIiwgXCJleGlzdHNcIikpIHtcbiAgICAgIHJldHVybiBGaWxlRXhpc3RzRXJyb3I7XG4gICAgfSBlbHNlIGlmIChjdHguaGFzTWVzc2FnZShcIm5vdFwiLCBcImRpcmVjdG9yeVwiKSkge1xuICAgICAgcmV0dXJuIE5vdERpcmVjdG9yeUVycm9yO1xuICAgIH0gZWxzZSBpZiAoY3R4Lmhhc01lc3NhZ2UoXCJub3RcIiwgXCJmaWxlXCIpKSB7XG4gICAgICByZXR1cm4gSXNEaXJlY3RvcnlFcnJvcjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1hc3RyYS9maWxlc3lzdGVtc1wiKTtcblxuLyoqIEhvdyB7QGxpbmsgRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW0uaW5pdH0gaGFuZGxlcyBhIG1pc3Npbmcge0BsaW5rIGJhc2VQYXRofS4gKi9cbmV4cG9ydCB0eXBlIERhdGFicmlja3NNa2RpcnNNb2RlID0gYm9vbGVhbiB8IFwidHJ5XCI7XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW19LiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhYnJpY2tzV29ya3NwYWNlRmlsZXN5c3RlbU9wdGlvbnMgZXh0ZW5kcyBNYXN0cmFGaWxlc3lzdGVtT3B0aW9ucyB7XG4gIC8qKiBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhpcyBmaWxlc3lzdGVtIGluc3RhbmNlLiAqL1xuICBpZD86IHN0cmluZztcbiAgLyoqIEF1dGgtc2NvcGVkIERhdGFicmlja3Mgd29ya3NwYWNlIGNsaWVudC4gKi9cbiAgY2xpZW50PzogV29ya3NwYWNlQ2xpZW50O1xuICAvKipcbiAgICogQWJzb2x1dGUgRGF0YWJyaWNrcyBwYXRoIHRoYXQgcm9vdHMgdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UsIGUuZy5cbiAgICogYC9Wb2x1bWVzL2NhdGFsb2cvc2NoZW1hL3ZvbHVtZWAgb3IgYC9kYmZzL0ZpbGVTdG9yZS9zaGFyZWRgLlxuICAgKi9cbiAgYmFzZVBhdGg6IHN0cmluZztcbiAgLyoqXG4gICAqIFdoZW4gdGhlIHtAbGluayBiYXNlUGF0aH0gaXMgbWlzc2luZyBhdCB7QGxpbmsgaW5pdH0sIGNyZWF0ZSBpdCB3aXRoIHRoZVxuICAgKiBtYXRjaGluZyBEYXRhYnJpY2tzIGBta2RpcnNgIEFQSS4gYFwidHJ5XCJgIChkZWZhdWx0KSBsb2dzIGF0IGRlYnVnIGFuZFxuICAgKiBmYWxscyBiYWNrIHRvIGFuIGVtcHR5IHJlYWQtb25seSBuYW1lc3BhY2Ugb24gZmFpbHVyZTsgYHRydWVgIGZhaWxzIGluaXQ7XG4gICAqIGBmYWxzZWAgc2tpcHMgY3JlYXRpb24gYW5kIHVzZXMgdGhlIGVtcHR5IG5hbWVzcGFjZS5cbiAgICpcbiAgICogQSBzdWNjZXNzZnVsIG1rZGlyIGFsc28gc2F0aXNmaWVzIHRoZSB3cml0ZS1hY2Nlc3MgcHJvYmUgd2hlblxuICAgKiB7QGxpbmsgcmVhZE9ubHl9IGlzIG9taXR0ZWQuXG4gICAqL1xuICBta2RpcnM/OiBEYXRhYnJpY2tzTWtkaXJzTW9kZTtcbiAgLyoqIEJsb2NrIHdyaXRlcyB3aGlsZSBzdGlsbCBhbGxvd2luZyByZWFkcy4gV2hlbiBvbWl0dGVkLCB7QGxpbmsgaW5pdH0gcHJvYmVzIHdyaXRlIGFjY2Vzcy4gKi9cbiAgcmVhZE9ubHk/OiBib29sZWFuO1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGV4cG9ydGVkIHBhdGggaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBOb3JtYWxpemUgYSBEYXRhYnJpY2tzIGJhc2UgcGF0aCAoUE9TSVgsIG5vIHRyYWlsaW5nIHNsYXNoKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEYXRhYnJpY2tzQmFzZVBhdGgoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHRyaW1tZWQgPSBiYXNlUGF0aC50cmltKCk7XG4gIGlmICghdHJpbW1lZC5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgIHRocm93IFZhbGlkYXRpb25FcnJvci5pbnZhbGlkVmFsdWUoXG4gICAgICBcImJhc2VQYXRoXCIsXG4gICAgICBiYXNlUGF0aCxcbiAgICAgIFwiYW4gYWJzb2x1dGUgRGF0YWJyaWNrcyBwYXRoLCBlLmcuIC9Wb2x1bWVzL2NhdGFsb2cvc2NoZW1hL3ZvbHVtZVwiLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHRyaW1tZWQucmVwbGFjZSgvXFwvKyQvLCBcIlwiKSB8fCBcIi9cIjtcbn1cblxuLyoqIFRydWUgd2hlbiBgYWJzb2x1dGVQYXRoYCBpcyBzZXJ2ZWQgYnkgREJGUyByYXRoZXIgdGhhbiB0aGUgVUMgRmlsZXMgQVBJLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGJmc1BhdGgoYWJzb2x1dGVQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGFic29sdXRlUGF0aCA9PT0gXCIvZGJmc1wiIHx8IGFic29sdXRlUGF0aC5zdGFydHNXaXRoKFwiL2RiZnMvXCIpO1xufVxuXG4vKiogVHJ1ZSB3aGVuIGBhYnNvbHV0ZVBhdGhgIGlzIGEgRGF0YWJyaWNrcyB3b3Jrc3BhY2Ugb2JqZWN0IHBhdGguICovXG5leHBvcnQgZnVuY3Rpb24gaXNXb3Jrc3BhY2VGaWxlc1BhdGgoYWJzb2x1dGVQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBhYnNvbHV0ZVBhdGggPT09IFwiL1dvcmtzcGFjZVwiIHx8XG4gICAgYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgoXCIvV29ya3NwYWNlL1wiKSB8fFxuICAgIGFic29sdXRlUGF0aC5zdGFydHNXaXRoKFwiL1VzZXJzL1wiKSB8fFxuICAgIGFic29sdXRlUGF0aC5zdGFydHNXaXRoKFwiL1JlcG9zL1wiKVxuICApO1xufVxuXG50eXBlIEZpbGVzQmFja2VuZCA9IFwiZGJmc1wiIHwgXCJ3b3Jrc3BhY2VcIiB8IFwidWMtZmlsZXNcIjtcblxuLyoqIFBlci1iYWNrZW5kIGFzeW5jIGhhbmRsZXIgdXNlZCBieSB7QGxpbmsgZGlzcGF0Y2hGaWxlc0JhY2tlbmR9LiAqL1xudHlwZSBGaWxlc0JhY2tlbmRIYW5kbGVyczxUID0gdW5rbm93bj4gPSB7XG4gIGRiZnM6ICgpID0+IFByb21pc2U8VD47XG4gIHdvcmtzcGFjZTogKCkgPT4gUHJvbWlzZTxUPjtcbiAgdWNGaWxlczogKCkgPT4gUHJvbWlzZTxUPjtcbn07XG5cbi8qKlxuICogUmVzb2x2ZSBhIHdvcmtzcGFjZS1yZWxhdGl2ZSBwYXRoIHRvIGFuIGFic29sdXRlIERhdGFicmlja3MgcGF0aCB1bmRlclxuICogYGJhc2VQYXRoYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVEYXRhYnJpY2tzQWJzb2x1dGVQYXRoKGJhc2VQYXRoOiBzdHJpbmcsIGlucHV0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgcm9vdCA9IG5vcm1hbGl6ZURhdGFicmlja3NCYXNlUGF0aChiYXNlUGF0aCk7XG4gIGNvbnN0IHRyaW1tZWQgPSBpbnB1dFBhdGgudHJpbSgpO1xuICBpZiAoIXRyaW1tZWQgfHwgdHJpbW1lZCA9PT0gXCIvXCIpIHJldHVybiByb290O1xuICBjb25zdCBub3JtYWxpemVkID0gdHJpbW1lZC5zdGFydHNXaXRoKFwiL1wiKSA/IHRyaW1tZWQgOiBgLyR7dHJpbW1lZH1gO1xuICBpZiAobm9ybWFsaXplZCA9PT0gcm9vdCB8fCBub3JtYWxpemVkLnN0YXJ0c1dpdGgoYCR7cm9vdH0vYCkpIHtcbiAgICByZXR1cm4gcGF0aC5ub3JtYWxpemUobm9ybWFsaXplZCk7XG4gIH1cbiAgcmV0dXJuIHBhdGgubm9ybWFsaXplKHBhdGguam9pbihyb290LCBub3JtYWxpemVkKSk7XG59XG5cbi8qKiBNYXAgYW4gYWJzb2x1dGUgRGF0YWJyaWNrcyBwYXRoIGJhY2sgdG8gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG5leHBvcnQgZnVuY3Rpb24gdG9EYXRhYnJpY2tzV29ya3NwYWNlUGF0aChiYXNlUGF0aDogc3RyaW5nLCBhYnNvbHV0ZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJvb3QgPSBub3JtYWxpemVEYXRhYnJpY2tzQmFzZVBhdGgoYmFzZVBhdGgpO1xuICBjb25zdCBub3JtYWxpemVkID0gcGF0aC5ub3JtYWxpemUoYWJzb2x1dGVQYXRoKTtcbiAgaWYgKG5vcm1hbGl6ZWQgPT09IHJvb3QpIHJldHVybiBcIi9cIjtcbiAgaWYgKG5vcm1hbGl6ZWQuc3RhcnRzV2l0aChgJHtyb290fS9gKSkge1xuICAgIHJldHVybiBub3JtYWxpemVkLnNsaWNlKHJvb3QubGVuZ3RoKSB8fCBcIi9cIjtcbiAgfVxuICByZXR1cm4gbm9ybWFsaXplZDtcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBwcml2YXRlIGhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogUGljayB0aGUgRGF0YWJyaWNrcyBGaWxlcyBBUEkgYmFja2VuZCBmb3IgYW4gYWJzb2x1dGUgcGF0aC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVGaWxlc0JhY2tlbmQoYWJzb2x1dGVQYXRoOiBzdHJpbmcpOiBGaWxlc0JhY2tlbmQge1xuICBpZiAoaXNEYmZzUGF0aChhYnNvbHV0ZVBhdGgpKSByZXR1cm4gXCJkYmZzXCI7XG4gIGlmIChpc1dvcmtzcGFjZUZpbGVzUGF0aChhYnNvbHV0ZVBhdGgpKSByZXR1cm4gXCJ3b3Jrc3BhY2VcIjtcbiAgcmV0dXJuIFwidWMtZmlsZXNcIjtcbn1cblxuLyoqIFJ1biB0aGUgaGFuZGxlciB0aGF0IG1hdGNoZXMgYGFic29sdXRlUGF0aGAncyBEYXRhYnJpY2tzIGJhY2tlbmQuICovXG5hc3luYyBmdW5jdGlvbiBkaXNwYXRjaEZpbGVzQmFja2VuZDxUPihcbiAgYWJzb2x1dGVQYXRoOiBzdHJpbmcsXG4gIGhhbmRsZXJzOiBGaWxlc0JhY2tlbmRIYW5kbGVyczxUPixcbik6IFByb21pc2U8VD4ge1xuICBjb25zdCBiYWNrZW5kID0gcmVzb2x2ZUZpbGVzQmFja2VuZChhYnNvbHV0ZVBhdGgpO1xuICBpZiAoYmFja2VuZCA9PT0gXCJkYmZzXCIpIHJldHVybiBoYW5kbGVycy5kYmZzKCk7XG4gIGlmIChiYWNrZW5kID09PSBcIndvcmtzcGFjZVwiKSByZXR1cm4gaGFuZGxlcnMud29ya3NwYWNlKCk7XG4gIHJldHVybiBoYW5kbGVycy51Y0ZpbGVzKCk7XG59XG5cbi8qKiBSZXR1cm4gYGJ1ZmZlcmAgYXMgYSBzdHJpbmcgd2hlbiBgZW5jb2RpbmdgIGlzIHNldCwgb3RoZXJ3aXNlIHVuY2hhbmdlZC4gKi9cbmZ1bmN0aW9uIGZvcm1hdFJlYWRSZXN1bHQoYnVmZmVyOiBCdWZmZXIsIGVuY29kaW5nPzogQnVmZmVyRW5jb2RpbmcpOiBzdHJpbmcgfCBCdWZmZXIge1xuICByZXR1cm4gZW5jb2RpbmcgPyBidWZmZXIudG9TdHJpbmcoZW5jb2RpbmcpIDogYnVmZmVyO1xufVxuXG4vKiogRHJhaW4gYSBmZXRjaCBgUmVhZGFibGVTdHJlYW1gIGludG8gYSBzaW5nbGUgYEJ1ZmZlcmAuICovXG5hc3luYyBmdW5jdGlvbiByZWFkUmVzcG9uc2VCb2R5KFxuICBjb250ZW50czogZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiB8IHVuZGVmaW5lZCxcbik6IFByb21pc2U8QnVmZmVyPiB7XG4gIGlmICghY29udGVudHMpIHJldHVybiBCdWZmZXIuYWxsb2MoMCk7XG4gIGNvbnN0IHJlYWRlciA9IGNvbnRlbnRzLmdldFJlYWRlcigpO1xuICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgaWYgKGRvbmUpIGJyZWFrO1xuICAgIGlmICh2YWx1ZSkgY2h1bmtzLnB1c2godmFsdWUpO1xuICB9XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KGNodW5rcy5tYXAoKGNodW5rKSA9PiBCdWZmZXIuZnJvbShjaHVuaykpKTtcbn1cblxuLyoqIENvZXJjZSBNYXN0cmEge0BsaW5rIEZpbGVDb250ZW50fSB0byBhIGBCdWZmZXJgLiAqL1xuZnVuY3Rpb24gdG9CdWZmZXIoY29udGVudDogRmlsZUNvbnRlbnQpOiBCdWZmZXIge1xuICBpZiAodHlwZW9mIGNvbnRlbnQgPT09IFwic3RyaW5nXCIpIHJldHVybiBCdWZmZXIuZnJvbShjb250ZW50LCBcInV0ZjhcIik7XG4gIHJldHVybiBCdWZmZXIuZnJvbShjb250ZW50KTtcbn1cblxuLyoqIERlY29kZSBhIERCRlMgcmVhZCBwYXlsb2FkIGZyb20gYmFzZTY0LiAqL1xuZnVuY3Rpb24gZGVjb2RlRGJmc1BheWxvYWQoZGF0YTogc3RyaW5nIHwgdW5kZWZpbmVkKTogQnVmZmVyIHtcbiAgaWYgKCFkYXRhKSByZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuICByZXR1cm4gQnVmZmVyLmZyb20oZGF0YSwgXCJiYXNlNjRcIik7XG59XG5cbi8qKiBXcmFwIGEgYEJ1ZmZlcmAgYXMgYSBvbmUtc2hvdCBgUmVhZGFibGVTdHJlYW1gIGZvciBVQyBmaWxlIHVwbG9hZHMuICovXG5mdW5jdGlvbiBidWZmZXJUb1JlYWRhYmxlU3RyZWFtKGJ1ZmZlcjogQnVmZmVyKTogZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4oe1xuICAgIHN0YXJ0KGNvbnRyb2xsZXIpIHtcbiAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShuZXcgVWludDhBcnJheShidWZmZXIpKTtcbiAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIFBhcnNlIGFuIEhUVFAgZGF0ZSBoZWFkZXI7IHJldHVybnMgZXBvY2ggd2hlbiBtaXNzaW5nIG9yIGludmFsaWQuICovXG5mdW5jdGlvbiBwYXJzZUh0dHBEYXRlKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBEYXRlIHtcbiAgaWYgKCF2YWx1ZSkgcmV0dXJuIG5ldyBEYXRlKDApO1xuICBjb25zdCBwYXJzZWQgPSBEYXRlLnBhcnNlKHZhbHVlKTtcbiAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShwYXJzZWQpID8gbmV3IERhdGUocGFyc2VkKSA6IG5ldyBEYXRlKDApO1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tIERhdGFicmlja3NXb3Jrc3BhY2VGaWxlc3lzdGVtIC0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqXG4gKiBNYXN0cmEgZmlsZXN5c3RlbSBwcm92aWRlciB0aGF0IHJlYWRzIGFuZCB3cml0ZXMgdGhyb3VnaCBhIERhdGFicmlja3NcbiAqIHtAbGluayBXb3Jrc3BhY2VDbGllbnR9LlxuICpcbiAqIFdvcmtzcGFjZSBwYXRocyBhcmUgYWJzb2x1dGUgd2l0aGluIHRoZSBuYW1lc3BhY2UgKGAvbm90ZXMubWRgIG1hcHMgdG9cbiAqIGA8YmFzZVBhdGg+L25vdGVzLm1kYCkuIFVuaXR5IENhdGFsb2cgdm9sdW1lcyB1c2UgdGhlIEZpbGVzIEFQSTtcbiAqIGAvZGJmcy8uLi5gIHBhdGhzIHVzZSBEQkZTLlxuICovXG5leHBvcnQgY2xhc3MgRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW0gZXh0ZW5kcyBNYXN0cmFGaWxlc3lzdGVtIHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbmFtZSA9IFwiRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW1cIjtcbiAgcmVhZG9ubHkgcHJvdmlkZXIgPSBcImRhdGFicmlja3NcIjtcbiAgcmVhZG9ubHkgYmFzZVBhdGg6IHN0cmluZztcbiAgc3RhdHVzOiBQcm92aWRlclN0YXR1cyA9IFwicGVuZGluZ1wiO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWtkaXJzOiBEYXRhYnJpY2tzTWtkaXJzTW9kZTtcbiAgcHJpdmF0ZSBfcmVhZE9ubHk6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgX2Jhc2VQYXRoTWlzc2luZzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICBnZXQgcmVhZE9ubHkoKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRPbmx5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBvcHRpb25zLmNsaWVudCAtIERlZmF1bHRzIHRvIHRoZSBBcHBLaXQgZXhlY3V0aW9uLWNvbnRleHQgY2xpZW50LlxuICAgKiBAcGFyYW0gb3B0aW9ucy5ta2RpcnMgLSBEZWZhdWx0IGBcInRyeVwiYDsgc2VlIHtAbGluayBEYXRhYnJpY2tzTWtkaXJzTW9kZX0uXG4gICAqIEBwYXJhbSBvcHRpb25zLnJlYWRPbmx5IC0gV2hlbiBvbWl0dGVkLCB7QGxpbmsgaW5pdH0gcHJvYmVzIHdyaXRlIGFjY2Vzcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IERhdGFicmlja3NXb3Jrc3BhY2VGaWxlc3lzdGVtT3B0aW9ucykge1xuICAgIHN1cGVyKHsgbmFtZTogXCJEYXRhYnJpY2tzV29ya3NwYWNlRmlsZXN5c3RlbVwiLCAuLi5vcHRpb25zIH0pO1xuICAgIHRoaXMuaWQgPSBvcHRpb25zLmlkID8/IGBkYXRhYnJpY2tzLWZzLSR7aGFzaC5mbnZIYXNoKG9wdGlvbnMuYmFzZVBhdGgpfWA7XG4gICAgdGhpcy5jbGllbnQgPSBvcHRpb25zLmNsaWVudCA/PyBnZXRFeGVjdXRpb25Db250ZXh0KCkuY2xpZW50O1xuICAgIHRoaXMuYmFzZVBhdGggPSBub3JtYWxpemVEYXRhYnJpY2tzQmFzZVBhdGgob3B0aW9ucy5iYXNlUGF0aCk7XG4gICAgdGhpcy5ta2RpcnMgPSBvcHRpb25zLm1rZGlycyA/PyBcInRyeVwiO1xuICAgIHRoaXMuX3JlYWRPbmx5ID0gb3B0aW9ucy5yZWFkT25seTtcbiAgfVxuXG4gIC8qIC0tLSBwYXRoIHJlc29sdXRpb24gLS0tICovXG5cbiAgLyoqIFJlc29sdmUgYW5kIHNhbmRib3ggYSB3b3Jrc3BhY2UtcmVsYXRpdmUgcGF0aCB1bmRlciB7QGxpbmsgYmFzZVBhdGh9LiAqL1xuICBwcml2YXRlIHJlc29sdmVQYXRoKGlucHV0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVEYXRhYnJpY2tzQWJzb2x1dGVQYXRoKHRoaXMuYmFzZVBhdGgsIGlucHV0UGF0aCk7XG4gICAgaWYgKHJlc29sdmVkICE9PSB0aGlzLmJhc2VQYXRoICYmICFyZXNvbHZlZC5zdGFydHNXaXRoKGAke3RoaXMuYmFzZVBhdGh9L2ApKSB7XG4gICAgICB0aHJvdyBuZXcgUGVybWlzc2lvbkVycm9yKGlucHV0UGF0aCwgXCJhY2Nlc3NcIik7XG4gICAgfVxuICAgIHJldHVybiByZXNvbHZlZDtcbiAgfVxuXG4gIC8qKiBNYXAgYSBEYXRhYnJpY2tzIGFic29sdXRlIHBhdGggYmFjayB0byB0aGUgd29ya3NwYWNlIG5hbWVzcGFjZS4gKi9cbiAgcHJpdmF0ZSB3b3Jrc3BhY2VQYXRoKGFic29sdXRlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdG9EYXRhYnJpY2tzV29ya3NwYWNlUGF0aCh0aGlzLmJhc2VQYXRoLCBhYnNvbHV0ZVBhdGgpO1xuICB9XG5cbiAgLyoqIFRocm93IHdoZW4gdGhlIGZpbGVzeXN0ZW0gaXMgcmVhZC1vbmx5LiAqL1xuICBwcml2YXRlIGFzc2VydFdyaXRhYmxlKG9wZXJhdGlvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVhZE9ubHkpIHtcbiAgICAgIHRocm93IG5ldyBXb3Jrc3BhY2VSZWFkT25seUVycm9yKG9wZXJhdGlvbik7XG4gICAgfVxuICB9XG5cbiAgLyoqIE1hcCBTREsgLyBIVFRQIGVycm9ycyB0byBNYXN0cmEgd29ya3NwYWNlIGZpbGVzeXN0ZW0gZXJyb3JzLiAqL1xuICBwcml2YXRlIHJldGhyb3coZXJyOiB1bmtub3duLCBpbnB1dFBhdGg6IHN0cmluZyk6IG5ldmVyIHtcbiAgICBjb25zdCB3b3Jrc3BhY2VQYXRoID0gaW5wdXRQYXRoLnN0YXJ0c1dpdGgoXCIvXCIpXG4gICAgICA/IGlucHV0UGF0aFxuICAgICAgOiB0aGlzLndvcmtzcGFjZVBhdGgodGhpcy5yZXNvbHZlUGF0aChpbnB1dFBhdGgpKTtcbiAgICBjb25zdCBFcnJvclR5cGUgPSBmaWxlc3lzdGVtU2RrRXJyb3JUeXBlKGVycik7XG4gICAgaWYgKEVycm9yVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yVHlwZSh3b3Jrc3BhY2VQYXRoKTtcbiAgICB9XG4gICAgLy8gVGhlIHVwc3RyZWFtIG1lc3NhZ2UgaXMgbG9nZ2VkIHJhdGhlciB0aGFuIHJhaXNlZDogaXQgcmVhY2hlcyB0aGUgbW9kZWxcbiAgICAvLyAoYW5kIGZyb20gdGhlcmUgdGhlIGNoYXQgdHJhbnNjcmlwdCkgYXMgdGhlIHRvb2wncyBmYWlsdXJlIHRleHQuXG4gICAgbG9nZ2VyLndhcm4oXCJvcGVyYXRpb24tZmFpbGVkXCIsIHtcbiAgICAgIHBhdGg6IHdvcmtzcGFjZVBhdGgsXG4gICAgICBlcnJvcjogZXJyb3IuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgfSk7XG4gICAgdGhyb3cgbmV3IEV4ZWN1dGlvbkVycm9yKGBEYXRhYnJpY2tzIGZpbGVzeXN0ZW0gb3BlcmF0aW9uIGZhaWxlZCBmb3IgJHt3b3Jrc3BhY2VQYXRofWAsIHtcbiAgICAgIGNhdXNlOiBlcnJvci50b0Vycm9yKGVyciksXG4gICAgICBjb250ZXh0OiB7IHBhdGg6IHdvcmtzcGFjZVBhdGggfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qIC0tLSBsaWZlY3ljbGUgLS0tICovXG5cbiAgLyoqXG4gICAqIFByb2JlIHdoZXRoZXIge0BsaW5rIGJhc2VQYXRofSBleGlzdHMgYW5kIGNhY2hlIHRoZSByZXN1bHQgb25cbiAgICoge0BsaW5rIF9iYXNlUGF0aE1pc3Npbmd9LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXNvbHZlQmFzZVBhdGhTdGF0dXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuX2Jhc2VQYXRoTWlzc2luZyAhPT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYXNzZXJ0QWJzb2x1dGVSZWFkYWJsZSh0aGlzLmJhc2VQYXRoKTtcbiAgICAgIHRoaXMuX2Jhc2VQYXRoTWlzc2luZyA9IGZhbHNlO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVycm9yLmVycm9yQ29udGV4dChlcnIpLm5vdEFjY2Vzc2libGUpIHtcbiAgICAgICAgdGhpcy5fYmFzZVBhdGhNaXNzaW5nID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXRocm93KGVyciwgXCIvXCIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBEZWxlZ2F0ZSB0byB7QGxpbmsgZW1wdHlGaWxlc3lzdGVtfSB3aGVuIHRoZSBiYXNlIHBhdGggaXMgbWlzc2luZy4gKi9cbiAgcHJpdmF0ZSBhc3luYyBlbXB0eUZhbGxiYWNrKCk6IFByb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgZW1wdHlGaWxlc3lzdGVtPiB8IHVuZGVmaW5lZD4ge1xuICAgIGF3YWl0IHRoaXMucmVzb2x2ZUJhc2VQYXRoU3RhdHVzKCk7XG4gICAgcmV0dXJuIHRoaXMuX2Jhc2VQYXRoTWlzc2luZyA/IGVtcHR5RmlsZXN5c3RlbSgpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnJlc29sdmVCYXNlUGF0aFN0YXR1cygpO1xuXG4gICAgaWYgKHRoaXMuX2Jhc2VQYXRoTWlzc2luZykge1xuICAgICAgaWYgKHRoaXMubWtkaXJzID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLm1rZGlyQWJzb2x1dGUodGhpcy5iYXNlUGF0aCk7XG4gICAgICAgIHRoaXMuX2Jhc2VQYXRoTWlzc2luZyA9IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5fcmVhZE9ubHkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMuX3JlYWRPbmx5ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAodGhpcy5ta2RpcnMgPT09IHRydWUpIHtcbiAgICAgICAgICB0aGlzLnJldGhyb3coZXJyLCBcIi9cIik7XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwibWtkaXJzOnRyeS1mYWlsZWRcIiwge1xuICAgICAgICAgIGJhc2VQYXRoOiB0aGlzLmJhc2VQYXRoLFxuICAgICAgICAgIGVycm9yOiBlcnJvci5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlYWRPbmx5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMucHJvYmVSZWFkT25seSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZSBhbmQgZGVsZXRlIGEgZXBoZW1lcmFsIHByb2JlIGZpbGUgdG8gZGV0ZWN0IHJlYWQtb25seSBhY2Nlc3Mgd2hlblxuICAgKiB7QGxpbmsgRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW1PcHRpb25zLnJlYWRPbmx5fSB3YXMgbm90IHNldC5cbiAgICpcbiAgICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIHByb2JlIHdyaXRlIChhbmQgY2xlYW51cCkgc3VjY2VlZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9iZVJlYWRPbmx5KCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGgoYC8uX19kYnhfZnNfcHJvYmVfJHtoYXNoLmlkKCl9YCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMud3JpdGVBYnNvbHV0ZShhYnNvbHV0ZVBhdGgsIEJ1ZmZlci5mcm9tKFwicHJvYmVcXG5cIiksIHRydWUpO1xuICAgICAgdGhpcy5fcmVhZE9ubHkgPSBmYWxzZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMuX3JlYWRPbmx5ID0gdHJ1ZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuZGVsZXRlQWJzb2x1dGVGaWxlKGFic29sdXRlUGF0aCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBXcml0YWJsZTsgbGVhdmUgYSBoaWRkZW4gcHJvYmUgZmlsZSByYXRoZXIgdGhhbiBmYWlsaW5nIGluaXQuXG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgZGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBSZW1vdGUgZmlsZXN5c3RlbTsgbm90aGluZyB0byB0ZWFyIGRvd24gbG9jYWxseS5cbiAgfVxuXG4gIC8qIC0tLSBiYWNrZW5kIEkvTyAtLS0gKi9cblxuICAvKiogUHJvYmUgdGhhdCBgYWJzb2x1dGVQYXRoYCBleGlzdHMgKGZpbGUgb3IgZGlyZWN0b3J5IG1ldGFkYXRhKS4gKi9cbiAgcHJpdmF0ZSBhc3luYyBhc3NlcnRBYnNvbHV0ZVJlYWRhYmxlKGFic29sdXRlUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgZGlzcGF0Y2hGaWxlc0JhY2tlbmQoYWJzb2x1dGVQYXRoLCB7XG4gICAgICBkYmZzOiAoKSA9PiB0aGlzLmNsaWVudC5kYmZzLmdldFN0YXR1cyh7IHBhdGg6IGFic29sdXRlUGF0aCB9KSxcbiAgICAgIHdvcmtzcGFjZTogKCkgPT4gdGhpcy5jbGllbnQud29ya3NwYWNlLmdldFN0YXR1cyh7IHBhdGg6IGFic29sdXRlUGF0aCB9KSxcbiAgICAgIHVjRmlsZXM6ICgpID0+IHRoaXMuY2xpZW50LmZpbGVzLmdldERpcmVjdG9yeU1ldGFkYXRhKHsgZGlyZWN0b3J5X3BhdGg6IGFic29sdXRlUGF0aCB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBSZWFkIHRoZSBmdWxsIGNvbnRlbnRzIG9mIGBhYnNvbHV0ZVBhdGhgIGZyb20gdGhlIG1hdGNoaW5nIGJhY2tlbmQuICovXG4gIHByaXZhdGUgYXN5bmMgcmVhZEFic29sdXRlKGFic29sdXRlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICByZXR1cm4gZGlzcGF0Y2hGaWxlc0JhY2tlbmQoYWJzb2x1dGVQYXRoLCB7XG4gICAgICBkYmZzOiAoKSA9PiB0aGlzLnJlYWREYmZzRmlsZShhYnNvbHV0ZVBhdGgpLFxuICAgICAgd29ya3NwYWNlOiAoKSA9PiB0aGlzLnJlYWRXb3Jrc3BhY2VGaWxlKGFic29sdXRlUGF0aCksXG4gICAgICB1Y0ZpbGVzOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuZmlsZXMuZG93bmxvYWQoeyBmaWxlX3BhdGg6IGFic29sdXRlUGF0aCB9KTtcbiAgICAgICAgcmV0dXJuIHJlYWRSZXNwb25zZUJvZHkoXG4gICAgICAgICAgcmVzcG9uc2UuY29udGVudHMgYXMgZ2xvYmFsVGhpcy5SZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiB8IHVuZGVmaW5lZCxcbiAgICAgICAgKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKiogV3JpdGUgYGJ1ZmZlcmAgdG8gYGFic29sdXRlUGF0aGAgb24gdGhlIG1hdGNoaW5nIGJhY2tlbmQuICovXG4gIHByaXZhdGUgYXN5bmMgd3JpdGVBYnNvbHV0ZShcbiAgICBhYnNvbHV0ZVBhdGg6IHN0cmluZyxcbiAgICBidWZmZXI6IEJ1ZmZlcixcbiAgICBvdmVyd3JpdGU6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IGRpc3BhdGNoRmlsZXNCYWNrZW5kKGFic29sdXRlUGF0aCwge1xuICAgICAgZGJmczogKCkgPT4gdGhpcy53cml0ZURiZnNGaWxlKGFic29sdXRlUGF0aCwgYnVmZmVyLCBvdmVyd3JpdGUpLFxuICAgICAgd29ya3NwYWNlOiAoKSA9PiB0aGlzLndyaXRlV29ya3NwYWNlRmlsZShhYnNvbHV0ZVBhdGgsIGJ1ZmZlciwgb3ZlcndyaXRlKSxcbiAgICAgIHVjRmlsZXM6ICgpID0+IHRoaXMudXBsb2FkVWNGaWxlKGFic29sdXRlUGF0aCwgYnVmZmVyLCBvdmVyd3JpdGUpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFVwbG9hZCBhIGJ1ZmZlciB0byBhIFVuaXR5IENhdGFsb2cgRmlsZXMgQVBJIHBhdGguICovXG4gIHByaXZhdGUgdXBsb2FkVWNGaWxlKGFic29sdXRlUGF0aDogc3RyaW5nLCBidWZmZXI6IEJ1ZmZlciwgb3ZlcndyaXRlOiBib29sZWFuKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50LmZpbGVzLnVwbG9hZCh7XG4gICAgICBmaWxlX3BhdGg6IGFic29sdXRlUGF0aCxcbiAgICAgIGNvbnRlbnRzOiBidWZmZXJUb1JlYWRhYmxlU3RyZWFtKGJ1ZmZlcikgYXMgbmV2ZXIsXG4gICAgICBvdmVyd3JpdGUsXG4gICAgfSk7XG4gIH1cblxuICAvKiogRGVsZXRlIGEgc2luZ2xlIGZpbGUgYXQgYGFic29sdXRlUGF0aGAgKG5vbi1yZWN1cnNpdmUpLiAqL1xuICBwcml2YXRlIGFzeW5jIGRlbGV0ZUFic29sdXRlRmlsZShhYnNvbHV0ZVBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IGRpc3BhdGNoRmlsZXNCYWNrZW5kKGFic29sdXRlUGF0aCwge1xuICAgICAgZGJmczogKCkgPT4gdGhpcy5jbGllbnQuZGJmcy5kZWxldGUoeyBwYXRoOiBhYnNvbHV0ZVBhdGgsIHJlY3Vyc2l2ZTogZmFsc2UgfSksXG4gICAgICB3b3Jrc3BhY2U6ICgpID0+IHRoaXMuY2xpZW50LndvcmtzcGFjZS5kZWxldGUoeyBwYXRoOiBhYnNvbHV0ZVBhdGgsIHJlY3Vyc2l2ZTogZmFsc2UgfSksXG4gICAgICB1Y0ZpbGVzOiAoKSA9PiB0aGlzLmNsaWVudC5maWxlcy5kZWxldGUoeyBmaWxlX3BhdGg6IGFic29sdXRlUGF0aCB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYSBmaWxlIG9yIGRpcmVjdG9yeSBhdCBgYWJzb2x1dGVQYXRoYC5cbiAgICpcbiAgICogREJGUyBhbmQgd29ya3NwYWNlIEFQSXMgYWNjZXB0IGByZWN1cnNpdmVgOyBVQyB2b2x1bWVzIHJlY3Vyc2UgbWFudWFsbHkuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlbGV0ZUFic29sdXRlUGF0aChhYnNvbHV0ZVBhdGg6IHN0cmluZywgcmVjdXJzaXZlOiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgZGlzcGF0Y2hGaWxlc0JhY2tlbmQoYWJzb2x1dGVQYXRoLCB7XG4gICAgICBkYmZzOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LmRiZnMuZGVsZXRlKHsgcGF0aDogYWJzb2x1dGVQYXRoLCByZWN1cnNpdmUgfSk7XG4gICAgICB9LFxuICAgICAgd29ya3NwYWNlOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LndvcmtzcGFjZS5kZWxldGUoeyBwYXRoOiBhYnNvbHV0ZVBhdGgsIHJlY3Vyc2l2ZSB9KTtcbiAgICAgIH0sXG4gICAgICB1Y0ZpbGVzOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmIChyZWN1cnNpdmUpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZVVjRGlyZWN0b3J5UmVjdXJzaXZlKGFic29sdXRlUGF0aCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gYXdhaXQgdGhpcy5saXN0QWJzb2x1dGVEaXJlY3RvcnkoYWJzb2x1dGVQYXRoKTtcbiAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRGlyZWN0b3J5Tm90RW1wdHlFcnJvcih0aGlzLndvcmtzcGFjZVBhdGgoYWJzb2x1dGVQYXRoKSk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZmlsZXMuZGVsZXRlRGlyZWN0b3J5KHsgZGlyZWN0b3J5X3BhdGg6IGFic29sdXRlUGF0aCB9KTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKiogQ3JlYXRlIGBhYnNvbHV0ZVBhdGhgIGFuZCBhbnkgbWlzc2luZyBwYXJlbnRzIG9uIHRoZSBtYXRjaGluZyBiYWNrZW5kLiAqL1xuICBwcml2YXRlIGFzeW5jIG1rZGlyQWJzb2x1dGUoYWJzb2x1dGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBkaXNwYXRjaEZpbGVzQmFja2VuZChhYnNvbHV0ZVBhdGgsIHtcbiAgICAgIGRiZnM6ICgpID0+IHRoaXMuY2xpZW50LmRiZnMubWtkaXJzKHsgcGF0aDogYWJzb2x1dGVQYXRoIH0pLFxuICAgICAgd29ya3NwYWNlOiAoKSA9PiB0aGlzLmNsaWVudC53b3Jrc3BhY2UubWtkaXJzKHsgcGF0aDogYWJzb2x1dGVQYXRoIH0pLFxuICAgICAgdWNGaWxlczogKCkgPT4gdGhpcy5jbGllbnQuZmlsZXMuY3JlYXRlRGlyZWN0b3J5KHsgZGlyZWN0b3J5X3BhdGg6IGFic29sdXRlUGF0aCB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVhZERiZnNGaWxlKGFic29sdXRlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCBjaHVua3M6IEJ1ZmZlcltdID0gW107XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuZGJmcy5yZWFkKHtcbiAgICAgICAgcGF0aDogYWJzb2x1dGVQYXRoLFxuICAgICAgICBvZmZzZXQsXG4gICAgICAgIGxlbmd0aDogREJGU19SRUFEX0NIVU5LX0JZVEVTLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBjaHVuayA9IGRlY29kZURiZnNQYXlsb2FkKHJlc3BvbnNlLmRhdGEpO1xuICAgICAgaWYgKGNodW5rLmxlbmd0aCA9PT0gMCkgYnJlYWs7XG4gICAgICBjaHVua3MucHVzaChjaHVuayk7XG4gICAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgaWYgKGNodW5rLmxlbmd0aCA8IERCRlNfUkVBRF9DSFVOS19CWVRFUykgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBCdWZmZXIuY29uY2F0KGNodW5rcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlYWRXb3Jrc3BhY2VGaWxlKGFic29sdXRlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LndvcmtzcGFjZS5leHBvcnQoe1xuICAgICAgcGF0aDogYWJzb2x1dGVQYXRoLFxuICAgICAgZm9ybWF0OiBcIkFVVE9cIixcbiAgICB9KTtcbiAgICByZXR1cm4gZGVjb2RlRGJmc1BheWxvYWQocmVzcG9uc2UuY29udGVudCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdyaXRlRGJmc0ZpbGUoXG4gICAgYWJzb2x1dGVQYXRoOiBzdHJpbmcsXG4gICAgYnVmZmVyOiBCdWZmZXIsXG4gICAgb3ZlcndyaXRlOiBib29sZWFuLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCA8PSBEQkZTX1BVVF9NQVhfQllURVMpIHtcbiAgICAgIGF3YWl0IHRoaXMuY2xpZW50LmRiZnMucHV0KHtcbiAgICAgICAgcGF0aDogYWJzb2x1dGVQYXRoLFxuICAgICAgICBjb250ZW50czogYnVmZmVyLnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICAgICBvdmVyd3JpdGUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY3JlYXRlZCA9IGF3YWl0IHRoaXMuY2xpZW50LmRiZnMuY3JlYXRlKHsgcGF0aDogYWJzb2x1dGVQYXRoLCBvdmVyd3JpdGUgfSk7XG4gICAgY29uc3QgaGFuZGxlID0gY3JlYXRlZC5oYW5kbGU7XG4gICAgaWYgKGhhbmRsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBFeGVjdXRpb25FcnJvci5taXNzaW5nRGF0YShcIkRCRlMgdXBsb2FkIGhhbmRsZVwiKTtcbiAgICB9XG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYnVmZmVyLmxlbmd0aDsgb2Zmc2V0ICs9IERCRlNfUFVUX01BWF9CWVRFUykge1xuICAgICAgY29uc3Qgc2xpY2UgPSBidWZmZXIuc3ViYXJyYXkob2Zmc2V0LCBvZmZzZXQgKyBEQkZTX1BVVF9NQVhfQllURVMpO1xuICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGJmcy5hZGRCbG9jayh7XG4gICAgICAgIGhhbmRsZSxcbiAgICAgICAgZGF0YTogc2xpY2UudG9TdHJpbmcoXCJiYXNlNjRcIiksXG4gICAgICB9KTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5jbGllbnQuZGJmcy5jbG9zZSh7IGhhbmRsZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd3JpdGVXb3Jrc3BhY2VGaWxlKFxuICAgIGFic29sdXRlUGF0aDogc3RyaW5nLFxuICAgIGJ1ZmZlcjogQnVmZmVyLFxuICAgIG92ZXJ3cml0ZTogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jbGllbnQud29ya3NwYWNlLmltcG9ydCh7XG4gICAgICBwYXRoOiBhYnNvbHV0ZVBhdGgsXG4gICAgICBmb3JtYXQ6IFwiQVVUT1wiLFxuICAgICAgY29udGVudDogYnVmZmVyLnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICAgb3ZlcndyaXRlLFxuICAgIH0pO1xuICB9XG5cbiAgLyogLS0tIE1hc3RyYUZpbGVzeXN0ZW0gQVBJIC0tLSAqL1xuXG4gIGdldEluZm8oKTogRmlsZXN5c3RlbUluZm88eyBiYXNlUGF0aDogc3RyaW5nIH0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBwcm92aWRlcjogdGhpcy5wcm92aWRlcixcbiAgICAgIHN0YXR1czogdGhpcy5zdGF0dXMsXG4gICAgICByZWFkT25seTogdGhpcy5yZWFkT25seSxcbiAgICAgIG1ldGFkYXRhOiB7IGJhc2VQYXRoOiB0aGlzLmJhc2VQYXRoIH0sXG4gICAgfTtcbiAgfVxuXG4gIGdldEluc3RydWN0aW9ucygpOiBzdHJpbmcge1xuICAgIHJldHVybiBbXG4gICAgICBgRmlsZXMgbGl2ZSBpbiBEYXRhYnJpY2tzIHVuZGVyICR7dGhpcy5iYXNlUGF0aH0uYCxcbiAgICAgIFwiV29ya3NwYWNlIHBhdGhzIGFyZSBhYnNvbHV0ZSB3aXRoaW4gdGhpcyByb290IChmb3IgZXhhbXBsZSBgL25vdGVzL3JlcG9ydC5tZGApLlwiLFxuICAgICAgXCJXb3Jrc3BhY2UgcGF0aHMgdXNlIGAvV29ya3NwYWNlLy4uLmAsIGAvVXNlcnMvLi4uYCwgb3IgYC9SZXBvcy8uLi5gIGJhc2UgcGF0aHMuXCIsXG4gICAgICBcIlVuaXR5IENhdGFsb2cgdm9sdW1lcyB1c2UgYC9Wb2x1bWVzLzxjYXRhbG9nPi88c2NoZW1hPi88dm9sdW1lPi8uLi5gIGJhc2UgcGF0aHMuXCIsXG4gICAgXS5qb2luKFwiIFwiKTtcbiAgfVxuXG4gIC8qKiBNYXAgYSB3b3Jrc3BhY2UtcmVsYXRpdmUgcGF0aCB0byB0aGUgYmFja2luZyBEYXRhYnJpY2tzIGFic29sdXRlIHBhdGguICovXG4gIHJlc29sdmVBYnNvbHV0ZVBhdGgoaW5wdXRQYXRoOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmVQYXRoKGlucHV0UGF0aCk7XG4gIH1cblxuICAvKiogUmVhZCBmaWxlIGNvbnRlbnRzIGZyb20gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG4gIGFzeW5jIHJlYWRGaWxlKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogUmVhZE9wdGlvbnMpOiBQcm9taXNlPHN0cmluZyB8IEJ1ZmZlcj4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICBjb25zdCBlbXB0eSA9IGF3YWl0IHRoaXMuZW1wdHlGYWxsYmFjaygpO1xuICAgIGlmIChlbXB0eSkgcmV0dXJuIGVtcHR5LnJlYWRGaWxlKGlucHV0UGF0aCwgb3B0aW9ucyk7XG4gICAgY29uc3QgYWJzb2x1dGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aChpbnB1dFBhdGgpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCB0aGlzLnJlYWRBYnNvbHV0ZShhYnNvbHV0ZVBhdGgpO1xuICAgICAgcmV0dXJuIGZvcm1hdFJlYWRSZXN1bHQoYnVmZmVyLCBvcHRpb25zPy5lbmNvZGluZyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLnJldGhyb3coZXJyLCBpbnB1dFBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBXcml0ZSBmaWxlIGNvbnRlbnRzIGludG8gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG4gIGFzeW5jIHdyaXRlRmlsZShpbnB1dFBhdGg6IHN0cmluZywgY29udGVudDogRmlsZUNvbnRlbnQsIG9wdGlvbnM/OiBXcml0ZU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KCk7XG4gICAgY29uc3QgZW1wdHkgPSBhd2FpdCB0aGlzLmVtcHR5RmFsbGJhY2soKTtcbiAgICBpZiAoZW1wdHkpIHJldHVybiBlbXB0eS53cml0ZUZpbGUoaW5wdXRQYXRoLCBjb250ZW50LCBvcHRpb25zKTtcbiAgICB0aGlzLmFzc2VydFdyaXRhYmxlKFwid3JpdGVGaWxlXCIpO1xuICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGgoaW5wdXRQYXRoKTtcbiAgICBjb25zdCBidWZmZXIgPSB0b0J1ZmZlcihjb250ZW50KTtcbiAgICBjb25zdCBvdmVyd3JpdGUgPSBvcHRpb25zPy5vdmVyd3JpdGUgPz8gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgaWYgKCFvdmVyd3JpdGUgJiYgKGF3YWl0IHRoaXMuZXhpc3RzKGlucHV0UGF0aCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBGaWxlRXhpc3RzRXJyb3IoaW5wdXRQYXRoKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMud3JpdGVBYnNvbHV0ZShhYnNvbHV0ZVBhdGgsIGJ1ZmZlciwgb3ZlcndyaXRlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBGaWxlRXhpc3RzRXJyb3IpIHRocm93IGVycjtcbiAgICAgIHRoaXMucmV0aHJvdyhlcnIsIGlucHV0UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEFwcGVuZCB0byBhbiBleGlzdGluZyBmaWxlLCBjcmVhdGluZyBpdCB3aGVuIG1pc3NpbmcuICovXG4gIGFzeW5jIGFwcGVuZEZpbGUoaW5wdXRQYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IEZpbGVDb250ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpO1xuICAgIGNvbnN0IGVtcHR5ID0gYXdhaXQgdGhpcy5lbXB0eUZhbGxiYWNrKCk7XG4gICAgaWYgKGVtcHR5KSByZXR1cm4gZW1wdHkuYXBwZW5kRmlsZShpbnB1dFBhdGgsIGNvbnRlbnQpO1xuICAgIHRoaXMuYXNzZXJ0V3JpdGFibGUoXCJhcHBlbmRGaWxlXCIpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gKGF3YWl0IHRoaXMuZXhpc3RzKGlucHV0UGF0aCkpXG4gICAgICA/IGF3YWl0IHRoaXMucmVhZEZpbGUoaW5wdXRQYXRoKVxuICAgICAgOiBCdWZmZXIuYWxsb2MoMCk7XG4gICAgY29uc3QgbWVyZ2VkID0gQnVmZmVyLmNvbmNhdChbXG4gICAgICBCdWZmZXIuaXNCdWZmZXIoZXhpc3RpbmcpID8gZXhpc3RpbmcgOiBCdWZmZXIuZnJvbShleGlzdGluZywgXCJ1dGY4XCIpLFxuICAgICAgdG9CdWZmZXIoY29udGVudCksXG4gICAgXSk7XG4gICAgYXdhaXQgdGhpcy53cml0ZUZpbGUoaW5wdXRQYXRoLCBtZXJnZWQsIHsgb3ZlcndyaXRlOiB0cnVlIH0pO1xuICB9XG5cbiAgLyoqIERlbGV0ZSBhIGZpbGUgaW4gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG4gIGFzeW5jIGRlbGV0ZUZpbGUoaW5wdXRQYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBSZW1vdmVPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpO1xuICAgIGNvbnN0IGVtcHR5ID0gYXdhaXQgdGhpcy5lbXB0eUZhbGxiYWNrKCk7XG4gICAgaWYgKGVtcHR5KSByZXR1cm4gZW1wdHkuZGVsZXRlRmlsZShpbnB1dFBhdGgsIG9wdGlvbnMpO1xuICAgIHRoaXMuYXNzZXJ0V3JpdGFibGUoXCJkZWxldGVGaWxlXCIpO1xuICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGgoaW5wdXRQYXRoKTtcbiAgICB0cnkge1xuICAgICAgaWYgKCEoYXdhaXQgdGhpcy5leGlzdHMoaW5wdXRQYXRoKSkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LmZvcmNlKSByZXR1cm47XG4gICAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFcnJvcihpbnB1dFBhdGgpO1xuICAgICAgfVxuICAgICAgY29uc3QgZW50cnkgPSBhd2FpdCB0aGlzLnN0YXQoaW5wdXRQYXRoKTtcbiAgICAgIGlmIChlbnRyeS50eXBlID09PSBcImRpcmVjdG9yeVwiKSB7XG4gICAgICAgIHRocm93IG5ldyBJc0RpcmVjdG9yeUVycm9yKGlucHV0UGF0aCk7XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmRlbGV0ZUFic29sdXRlRmlsZShhYnNvbHV0ZVBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEZpbGVOb3RGb3VuZEVycm9yIHx8IGVyciBpbnN0YW5jZW9mIElzRGlyZWN0b3J5RXJyb3IpIHRocm93IGVycjtcbiAgICAgIHRoaXMucmV0aHJvdyhlcnIsIGlucHV0UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIENvcHkgYSBmaWxlIHdpdGhpbiB0aGUgd29ya3NwYWNlIG5hbWVzcGFjZS4gKi9cbiAgYXN5bmMgY29weUZpbGUoc3JjOiBzdHJpbmcsIGRlc3Q6IHN0cmluZywgb3B0aW9ucz86IENvcHlPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpO1xuICAgIGNvbnN0IGVtcHR5ID0gYXdhaXQgdGhpcy5lbXB0eUZhbGxiYWNrKCk7XG4gICAgaWYgKGVtcHR5KSByZXR1cm4gZW1wdHkuY29weUZpbGUoc3JjLCBkZXN0LCBvcHRpb25zKTtcbiAgICB0aGlzLmFzc2VydFdyaXRhYmxlKFwiY29weUZpbGVcIik7XG4gICAgY29uc3Qgb3ZlcndyaXRlID0gb3B0aW9ucz8ub3ZlcndyaXRlID8/IHRydWU7XG4gICAgaWYgKCFvdmVyd3JpdGUgJiYgKGF3YWl0IHRoaXMuZXhpc3RzKGRlc3QpKSkge1xuICAgICAgdGhyb3cgbmV3IEZpbGVFeGlzdHNFcnJvcihkZXN0KTtcbiAgICB9XG4gICAgY29uc3QgY29udGVudCA9IGF3YWl0IHRoaXMucmVhZEZpbGUoc3JjKTtcbiAgICBhd2FpdCB0aGlzLndyaXRlRmlsZShkZXN0LCBjb250ZW50LCB7IG92ZXJ3cml0ZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIC8qKiBNb3ZlIG9yIHJlbmFtZSBhIGZpbGUgd2l0aGluIHRoZSB3b3Jrc3BhY2UgbmFtZXNwYWNlLiAqL1xuICBhc3luYyBtb3ZlRmlsZShzcmM6IHN0cmluZywgZGVzdDogc3RyaW5nLCBvcHRpb25zPzogQ29weU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KCk7XG4gICAgY29uc3QgZW1wdHkgPSBhd2FpdCB0aGlzLmVtcHR5RmFsbGJhY2soKTtcbiAgICBpZiAoZW1wdHkpIHJldHVybiBlbXB0eS5tb3ZlRmlsZShzcmMsIGRlc3QsIG9wdGlvbnMpO1xuICAgIHRoaXMuYXNzZXJ0V3JpdGFibGUoXCJtb3ZlRmlsZVwiKTtcbiAgICBjb25zdCBzcmNBYnNvbHV0ZSA9IHRoaXMucmVzb2x2ZVBhdGgoc3JjKTtcbiAgICBjb25zdCBkZXN0QWJzb2x1dGUgPSB0aGlzLnJlc29sdmVQYXRoKGRlc3QpO1xuICAgIGNvbnN0IG92ZXJ3cml0ZSA9IG9wdGlvbnM/Lm92ZXJ3cml0ZSA/PyB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBpZiAoIW92ZXJ3cml0ZSAmJiAoYXdhaXQgdGhpcy5leGlzdHMoZGVzdCkpKSB7XG4gICAgICAgIHRocm93IG5ldyBGaWxlRXhpc3RzRXJyb3IoZGVzdCk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIHJlc29sdmVGaWxlc0JhY2tlbmQoc3JjQWJzb2x1dGUpID09PSBcImRiZnNcIiAmJlxuICAgICAgICByZXNvbHZlRmlsZXNCYWNrZW5kKGRlc3RBYnNvbHV0ZSkgPT09IFwiZGJmc1wiXG4gICAgICApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGJmcy5tb3ZlKHtcbiAgICAgICAgICBzb3VyY2VfcGF0aDogc3JjQWJzb2x1dGUsXG4gICAgICAgICAgZGVzdGluYXRpb25fcGF0aDogZGVzdEFic29sdXRlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5jb3B5RmlsZShzcmMsIGRlc3QsIHsgb3ZlcndyaXRlOiB0cnVlIH0pO1xuICAgICAgYXdhaXQgdGhpcy5kZWxldGVGaWxlKHNyYywgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBGaWxlRXhpc3RzRXJyb3IpIHRocm93IGVycjtcbiAgICAgIHRoaXMucmV0aHJvdyhlcnIsIGRlc3QpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDcmVhdGUgYSBkaXJlY3RvcnkgaW4gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG4gIGFzeW5jIG1rZGlyKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogeyByZWN1cnNpdmU/OiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KCk7XG4gICAgY29uc3QgZW1wdHkgPSBhd2FpdCB0aGlzLmVtcHR5RmFsbGJhY2soKTtcbiAgICBpZiAoZW1wdHkpIHJldHVybiBlbXB0eS5ta2RpcihpbnB1dFBhdGgsIG9wdGlvbnMpO1xuICAgIHRoaXMuYXNzZXJ0V3JpdGFibGUoXCJta2RpclwiKTtcbiAgICBjb25zdCBhYnNvbHV0ZVBhdGggPSB0aGlzLnJlc29sdmVQYXRoKGlucHV0UGF0aCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMubWtkaXJBYnNvbHV0ZShhYnNvbHV0ZVBhdGgpO1xuICAgICAgaWYgKCFvcHRpb25zPy5yZWN1cnNpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5yZXRocm93KGVyciwgaW5wdXRQYXRoKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmVtb3ZlIGEgZGlyZWN0b3J5IGZyb20gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG4gIGFzeW5jIHJtZGlyKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogUmVtb3ZlT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICBjb25zdCBlbXB0eSA9IGF3YWl0IHRoaXMuZW1wdHlGYWxsYmFjaygpO1xuICAgIGlmIChlbXB0eSkgcmV0dXJuIGVtcHR5LnJtZGlyKGlucHV0UGF0aCwgb3B0aW9ucyk7XG4gICAgdGhpcy5hc3NlcnRXcml0YWJsZShcInJtZGlyXCIpO1xuICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGgoaW5wdXRQYXRoKTtcbiAgICB0cnkge1xuICAgICAgaWYgKCEoYXdhaXQgdGhpcy5leGlzdHMoaW5wdXRQYXRoKSkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LmZvcmNlKSByZXR1cm47XG4gICAgICAgIHRocm93IG5ldyBEaXJlY3RvcnlOb3RGb3VuZEVycm9yKGlucHV0UGF0aCk7XG4gICAgICB9XG4gICAgICBjb25zdCBlbnRyeSA9IGF3YWl0IHRoaXMuc3RhdChpbnB1dFBhdGgpO1xuICAgICAgaWYgKGVudHJ5LnR5cGUgIT09IFwiZGlyZWN0b3J5XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IE5vdERpcmVjdG9yeUVycm9yKGlucHV0UGF0aCk7XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmRlbGV0ZUFic29sdXRlUGF0aChhYnNvbHV0ZVBhdGgsIG9wdGlvbnM/LnJlY3Vyc2l2ZSA/PyBmYWxzZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGVyciBpbnN0YW5jZW9mIERpcmVjdG9yeU5vdEZvdW5kRXJyb3IgfHxcbiAgICAgICAgZXJyIGluc3RhbmNlb2YgTm90RGlyZWN0b3J5RXJyb3IgfHxcbiAgICAgICAgZXJyIGluc3RhbmNlb2YgRGlyZWN0b3J5Tm90RW1wdHlFcnJvclxuICAgICAgKSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIHRoaXMucmV0aHJvdyhlcnIsIGlucHV0UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlY3Vyc2l2ZWx5IGRlbGV0ZSBhIFVuaXR5IENhdGFsb2cgZGlyZWN0b3J5IHRyZWUuXG4gICAqXG4gICAqIERCRlMgYW5kIHdvcmtzcGFjZSB0cmVlcyB1c2UgbmF0aXZlIHJlY3Vyc2l2ZSBkZWxldGUgdmlhXG4gICAqIHtAbGluayBkZWxldGVBYnNvbHV0ZVBhdGh9IGluc3RlYWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlbGV0ZVVjRGlyZWN0b3J5UmVjdXJzaXZlKGFic29sdXRlUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBhd2FpdCB0aGlzLmxpc3RBYnNvbHV0ZURpcmVjdG9yeShhYnNvbHV0ZVBhdGgpKSB7XG4gICAgICBjb25zdCBjaGlsZEFic29sdXRlID0gcGF0aC5qb2luKGFic29sdXRlUGF0aCwgY2hpbGQubmFtZSk7XG4gICAgICBpZiAoY2hpbGQudHlwZSA9PT0gXCJkaXJlY3RvcnlcIikge1xuICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZVVjRGlyZWN0b3J5UmVjdXJzaXZlKGNoaWxkQWJzb2x1dGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdGhpcy5kZWxldGVBYnNvbHV0ZUZpbGUoY2hpbGRBYnNvbHV0ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGF3YWl0IHRoaXMuY2xpZW50LmZpbGVzLmRlbGV0ZURpcmVjdG9yeSh7IGRpcmVjdG9yeV9wYXRoOiBhYnNvbHV0ZVBhdGggfSk7XG4gIH1cblxuICAvKiAtLS0gZGlyZWN0b3J5IGxpc3RpbmcgLS0tICovXG5cbiAgLyoqIExpc3QgZW50cmllcyBpbiBhIHdvcmtzcGFjZSBkaXJlY3RvcnkuICovXG4gIGFzeW5jIHJlYWRkaXIoaW5wdXRQYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBMaXN0T3B0aW9ucyk6IFByb21pc2U8RmlsZUVudHJ5W10+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KCk7XG4gICAgY29uc3QgZW1wdHkgPSBhd2FpdCB0aGlzLmVtcHR5RmFsbGJhY2soKTtcbiAgICBpZiAoZW1wdHkpIHJldHVybiBlbXB0eS5yZWFkZGlyKGlucHV0UGF0aCwgb3B0aW9ucyk7XG4gICAgY29uc3QgYWJzb2x1dGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aChpbnB1dFBhdGgpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgdGhpcy5saXN0QWJzb2x1dGVEaXJlY3RvcnkoYWJzb2x1dGVQYXRoKTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gdGhpcy5maWx0ZXJFbnRyaWVzKGVudHJpZXMsIG9wdGlvbnMpO1xuICAgICAgaWYgKCFvcHRpb25zPy5yZWN1cnNpdmUpIHJldHVybiBmaWx0ZXJlZDtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlYWREaXJlY3RvcnlSZWN1cnNpdmUoYWJzb2x1dGVQYXRoLCBvcHRpb25zLCAwKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMucmV0aHJvdyhlcnIsIGlucHV0UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWFkRGlyZWN0b3J5UmVjdXJzaXZlKFxuICAgIGFic29sdXRlUGF0aDogc3RyaW5nLFxuICAgIG9wdGlvbnM6IExpc3RPcHRpb25zLFxuICAgIGRlcHRoOiBudW1iZXIsXG4gICAgcmVsYXRpdmVQcmVmaXggPSBcIlwiLFxuICApOiBQcm9taXNlPEZpbGVFbnRyeVtdPiB7XG4gICAgY29uc3QgbWF4RGVwdGggPSBvcHRpb25zLm1heERlcHRoID8/IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICBjb25zdCBlbnRyaWVzID0gdGhpcy5maWx0ZXJFbnRyaWVzKGF3YWl0IHRoaXMubGlzdEFic29sdXRlRGlyZWN0b3J5KGFic29sdXRlUGF0aCksIG9wdGlvbnMpO1xuICAgIGNvbnN0IGNvbGxlY3RlZDogRmlsZUVudHJ5W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGNvbnN0IHJlbGF0aXZlTmFtZSA9IHJlbGF0aXZlUHJlZml4ID8gcGF0aC5qb2luKHJlbGF0aXZlUHJlZml4LCBlbnRyeS5uYW1lKSA6IGVudHJ5Lm5hbWU7XG4gICAgICBjb2xsZWN0ZWQucHVzaCh7IC4uLmVudHJ5LCBuYW1lOiByZWxhdGl2ZU5hbWUgfSk7XG4gICAgICBpZiAoZW50cnkudHlwZSAhPT0gXCJkaXJlY3RvcnlcIiB8fCBkZXB0aCA+PSBtYXhEZXB0aCkgY29udGludWU7XG4gICAgICBjb2xsZWN0ZWQucHVzaChcbiAgICAgICAgLi4uKGF3YWl0IHRoaXMucmVhZERpcmVjdG9yeVJlY3Vyc2l2ZShcbiAgICAgICAgICBwYXRoLmpvaW4oYWJzb2x1dGVQYXRoLCBlbnRyeS5uYW1lKSxcbiAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgIGRlcHRoICsgMSxcbiAgICAgICAgICByZWxhdGl2ZU5hbWUsXG4gICAgICAgICkpLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbGxlY3RlZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbGlzdEFic29sdXRlRGlyZWN0b3J5KGFic29sdXRlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxGaWxlRW50cnlbXT4ge1xuICAgIHJldHVybiBkaXNwYXRjaEZpbGVzQmFja2VuZChhYnNvbHV0ZVBhdGgsIHtcbiAgICAgIGRiZnM6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgZW50cmllczogRmlsZUVudHJ5W10gPSBbXTtcbiAgICAgICAgZm9yIGF3YWl0IChjb25zdCBpbmZvIG9mIHRoaXMuY2xpZW50LmRiZnMubGlzdCh7IHBhdGg6IGFic29sdXRlUGF0aCB9KSkge1xuICAgICAgICAgIGVudHJpZXMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBwYXRoLmJhc2VuYW1lKGluZm8ucGF0aCA/PyBcIlwiKSxcbiAgICAgICAgICAgIHR5cGU6IGluZm8uaXNfZGlyID8gXCJkaXJlY3RvcnlcIiA6IFwiZmlsZVwiLFxuICAgICAgICAgICAgc2l6ZTogaW5mby5maWxlX3NpemUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVudHJpZXM7XG4gICAgICB9LFxuICAgICAgd29ya3NwYWNlOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVudHJpZXM6IEZpbGVFbnRyeVtdID0gW107XG4gICAgICAgIGZvciBhd2FpdCAoY29uc3QgaW5mbyBvZiB0aGlzLmNsaWVudC53b3Jrc3BhY2UubGlzdCh7IHBhdGg6IGFic29sdXRlUGF0aCB9KSkge1xuICAgICAgICAgIGVudHJpZXMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBwYXRoLmJhc2VuYW1lKGluZm8ucGF0aCA/PyBcIlwiKSxcbiAgICAgICAgICAgIHR5cGU6IGluZm8ub2JqZWN0X3R5cGUgPT09IFwiRElSRUNUT1JZXCIgPyBcImRpcmVjdG9yeVwiIDogXCJmaWxlXCIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVudHJpZXM7XG4gICAgICB9LFxuICAgICAgdWNGaWxlczogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBlbnRyaWVzOiBGaWxlRW50cnlbXSA9IFtdO1xuICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IGVudHJ5IG9mIHRoaXMuY2xpZW50LmZpbGVzLmxpc3REaXJlY3RvcnlDb250ZW50cyh7XG4gICAgICAgICAgZGlyZWN0b3J5X3BhdGg6IGFic29sdXRlUGF0aCxcbiAgICAgICAgfSkpIHtcbiAgICAgICAgICBlbnRyaWVzLnB1c2goe1xuICAgICAgICAgICAgbmFtZTogZW50cnkubmFtZSA/PyBwYXRoLmJhc2VuYW1lKGVudHJ5LnBhdGggPz8gXCJcIiksXG4gICAgICAgICAgICB0eXBlOiBlbnRyeS5pc19kaXJlY3RvcnkgPyBcImRpcmVjdG9yeVwiIDogXCJmaWxlXCIsXG4gICAgICAgICAgICBzaXplOiBlbnRyeS5maWxlX3NpemUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVudHJpZXM7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIEFwcGx5IE1hc3RyYSBsaXN0IGZpbHRlcnMgKGBleHRlbnNpb25gLCBldGMuKSB0byBkaXJlY3RvcnkgZW50cmllcy4gKi9cbiAgcHJpdmF0ZSBmaWx0ZXJFbnRyaWVzKGVudHJpZXM6IEZpbGVFbnRyeVtdLCBvcHRpb25zPzogTGlzdE9wdGlvbnMpOiBGaWxlRW50cnlbXSB7XG4gICAgaWYgKCFvcHRpb25zPy5leHRlbnNpb24pIHJldHVybiBlbnRyaWVzO1xuICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMuZXh0ZW5zaW9uKSA/IG9wdGlvbnMuZXh0ZW5zaW9uIDogW29wdGlvbnMuZXh0ZW5zaW9uXTtcbiAgICBjb25zdCBub3JtYWxpemVkID0gZXh0ZW5zaW9ucy5tYXAoKGV4dCkgPT5cbiAgICAgIGV4dC5zdGFydHNXaXRoKFwiLlwiKSA/IGV4dC50b0xvd2VyQ2FzZSgpIDogYC4ke2V4dC50b0xvd2VyQ2FzZSgpfWAsXG4gICAgKTtcbiAgICByZXR1cm4gZW50cmllcy5maWx0ZXIoKGVudHJ5KSA9PiB7XG4gICAgICBpZiAoZW50cnkudHlwZSAhPT0gXCJmaWxlXCIpIHJldHVybiB0cnVlO1xuICAgICAgY29uc3QgbG93ZXIgPSBlbnRyeS5uYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICByZXR1cm4gbm9ybWFsaXplZC5zb21lKChleHQpID0+IGxvd2VyLmVuZHNXaXRoKGV4dCkpO1xuICAgIH0pO1xuICB9XG5cbiAgLyogLS0tIG1ldGFkYXRhIC0tLSAqL1xuXG4gIC8qKiBSZXR1cm4gd2hldGhlciBgaW5wdXRQYXRoYCBleGlzdHMgaW4gdGhlIHdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG4gIGFzeW5jIGV4aXN0cyhpbnB1dFBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICBjb25zdCBlbXB0eSA9IGF3YWl0IHRoaXMuZW1wdHlGYWxsYmFjaygpO1xuICAgIGlmIChlbXB0eSkgcmV0dXJuIGVtcHR5LmV4aXN0cyhpbnB1dFBhdGgpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnN0YXQoaW5wdXRQYXRoKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEZpbGVOb3RGb3VuZEVycm9yKSByZXR1cm4gZmFsc2U7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJldHVybiBmaWxlIG9yIGRpcmVjdG9yeSBtZXRhZGF0YSBmb3IgYGlucHV0UGF0aGAuICovXG4gIGFzeW5jIHN0YXQoaW5wdXRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPEZpbGVTdGF0PiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpO1xuICAgIGNvbnN0IGVtcHR5ID0gYXdhaXQgdGhpcy5lbXB0eUZhbGxiYWNrKCk7XG4gICAgaWYgKGVtcHR5KSByZXR1cm4gZW1wdHkuc3RhdChpbnB1dFBhdGgpO1xuICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGgoaW5wdXRQYXRoKTtcbiAgICBjb25zdCB3b3Jrc3BhY2VQYXRoID0gdGhpcy53b3Jrc3BhY2VQYXRoKGFic29sdXRlUGF0aCk7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBkaXNwYXRjaEZpbGVzQmFja2VuZChhYnNvbHV0ZVBhdGgsIHtcbiAgICAgICAgZGJmczogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGluZm8gPSBhd2FpdCB0aGlzLmNsaWVudC5kYmZzLmdldFN0YXR1cyh7IHBhdGg6IGFic29sdXRlUGF0aCB9KTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogcGF0aC5iYXNlbmFtZShpbmZvLnBhdGggPz8gYWJzb2x1dGVQYXRoKSxcbiAgICAgICAgICAgIHBhdGg6IHdvcmtzcGFjZVBhdGgsXG4gICAgICAgICAgICB0eXBlOiBpbmZvLmlzX2RpciA/IChcImRpcmVjdG9yeVwiIGFzIGNvbnN0KSA6IChcImZpbGVcIiBhcyBjb25zdCksXG4gICAgICAgICAgICBzaXplOiBpbmZvLmZpbGVfc2l6ZSA/PyAwLFxuICAgICAgICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZShpbmZvLm1vZGlmaWNhdGlvbl90aW1lID8/IDApLFxuICAgICAgICAgICAgbW9kaWZpZWRBdDogbmV3IERhdGUoaW5mby5tb2RpZmljYXRpb25fdGltZSA/PyAwKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICB3b3Jrc3BhY2U6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBpbmZvID0gYXdhaXQgdGhpcy5jbGllbnQud29ya3NwYWNlLmdldFN0YXR1cyh7IHBhdGg6IGFic29sdXRlUGF0aCB9KTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogcGF0aC5iYXNlbmFtZShpbmZvLnBhdGggPz8gYWJzb2x1dGVQYXRoKSxcbiAgICAgICAgICAgIHBhdGg6IHdvcmtzcGFjZVBhdGgsXG4gICAgICAgICAgICB0eXBlOiBpbmZvLm9iamVjdF90eXBlID09PSBcIkRJUkVDVE9SWVwiID8gKFwiZGlyZWN0b3J5XCIgYXMgY29uc3QpIDogKFwiZmlsZVwiIGFzIGNvbnN0KSxcbiAgICAgICAgICAgIHNpemU6IDAsXG4gICAgICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKGluZm8uY3JlYXRlZF9hdCA/PyAwKSxcbiAgICAgICAgICAgIG1vZGlmaWVkQXQ6IG5ldyBEYXRlKGluZm8ubW9kaWZpZWRfYXQgPz8gMCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgdWNGaWxlczogKCkgPT4gdGhpcy5zdGF0VWNBYnNvbHV0ZShhYnNvbHV0ZVBhdGgsIHdvcmtzcGFjZVBhdGgsIGlucHV0UGF0aCksXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMucmV0aHJvdyhlcnIsIGlucHV0UGF0aCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXQgYSBVbml0eSBDYXRhbG9nIHBhdGggYnkgcHJvYmluZyBmaWxlIG1ldGFkYXRhIGZpcnN0LCB0aGVuXG4gICAqIGRpcmVjdG9yeSBtZXRhZGF0YS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc3RhdFVjQWJzb2x1dGUoXG4gICAgYWJzb2x1dGVQYXRoOiBzdHJpbmcsXG4gICAgd29ya3NwYWNlUGF0aDogc3RyaW5nLFxuICAgIGlucHV0UGF0aDogc3RyaW5nLFxuICApOiBQcm9taXNlPEZpbGVTdGF0PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gYXdhaXQgdGhpcy5jbGllbnQuZmlsZXMuZ2V0TWV0YWRhdGEoe1xuICAgICAgICBmaWxlX3BhdGg6IGFic29sdXRlUGF0aCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogcGF0aC5iYXNlbmFtZShhYnNvbHV0ZVBhdGgpLFxuICAgICAgICBwYXRoOiB3b3Jrc3BhY2VQYXRoLFxuICAgICAgICB0eXBlOiBcImZpbGVcIiBhcyBjb25zdCxcbiAgICAgICAgc2l6ZTogTnVtYmVyKG1ldGFkYXRhW1wiY29udGVudC1sZW5ndGhcIl0gPz8gMCksXG4gICAgICAgIGNyZWF0ZWRBdDogcGFyc2VIdHRwRGF0ZShtZXRhZGF0YVtcImxhc3QtbW9kaWZpZWRcIl0pLFxuICAgICAgICBtb2RpZmllZEF0OiBwYXJzZUh0dHBEYXRlKG1ldGFkYXRhW1wibGFzdC1tb2RpZmllZFwiXSksXG4gICAgICAgIG1pbWVUeXBlOiBtZXRhZGF0YVtcImNvbnRlbnQtdHlwZVwiXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZmlsZUVycikge1xuICAgICAgaWYgKCFlcnJvci5lcnJvckNvbnRleHQoZmlsZUVycikubm90QWNjZXNzaWJsZSkge1xuICAgICAgICB0aGlzLnJldGhyb3coZmlsZUVyciwgaW5wdXRQYXRoKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuY2xpZW50LmZpbGVzLmdldERpcmVjdG9yeU1ldGFkYXRhKHtcbiAgICAgICAgZGlyZWN0b3J5X3BhdGg6IGFic29sdXRlUGF0aCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogcGF0aC5iYXNlbmFtZShhYnNvbHV0ZVBhdGgpLFxuICAgICAgICBwYXRoOiB3b3Jrc3BhY2VQYXRoLFxuICAgICAgICB0eXBlOiBcImRpcmVjdG9yeVwiIGFzIGNvbnN0LFxuICAgICAgICBzaXplOiAwLFxuICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKDApLFxuICAgICAgICBtb2RpZmllZEF0OiBuZXcgRGF0ZSgwKSxcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBlbXB0eSBmaWxlc3lzdGVtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogTm9ybWFsaXplIHBhdGhzIGZvciB0aGUgaW4tbWVtb3J5IGVtcHR5IGZpbGVzeXN0ZW0gbmFtZXNwYWNlLiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRW1wdHlGaWxlc3lzdGVtUGF0aChpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHRyaW1tZWQgPSBpbnB1dFBhdGgudHJpbSgpO1xuICBpZiAoIXRyaW1tZWQgfHwgdHJpbW1lZCA9PT0gXCIuXCIpIHJldHVybiBcIi9cIjtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHRyaW1tZWQuc3RhcnRzV2l0aChcIi9cIilcbiAgICA/IHBhdGgubm9ybWFsaXplKHRyaW1tZWQpXG4gICAgOiBwYXRoLm5vcm1hbGl6ZShgLyR7dHJpbW1lZH1gKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQgPT09IFwiLlwiID8gXCIvXCIgOiBub3JtYWxpemVkO1xufVxuXG4vKipcbiAqIFJlYWQtb25seSBpbi1tZW1vcnkge0BsaW5rIFdvcmtzcGFjZUZpbGVzeXN0ZW19IHdpdGggYSBzaW5nbGUgZW1wdHkgcm9vdC5cbiAqIFVzZSB7QGxpbmsgZW1wdHlGaWxlc3lzdGVtfSByYXRoZXIgdGhhbiBjb25zdHJ1Y3RpbmcgZGlyZWN0bHkuXG4gKi9cbmNsYXNzIEVtcHR5RmlsZXN5c3RlbSBleHRlbmRzIE1hc3RyYUZpbGVzeXN0ZW0ge1xuICByZWFkb25seSBpZCA9IFwiZW1wdHktZnNcIjtcbiAgcmVhZG9ubHkgbmFtZSA9IFwiRW1wdHlGaWxlc3lzdGVtXCI7XG4gIHJlYWRvbmx5IHByb3ZpZGVyID0gXCJlbXB0eVwiO1xuICByZWFkb25seSByZWFkT25seSA9IHRydWU7XG4gIHN0YXR1czogUHJvdmlkZXJTdGF0dXMgPSBcInBlbmRpbmdcIjtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcih7IG5hbWU6IFwiRW1wdHlGaWxlc3lzdGVtXCIgfSk7XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBpbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIE5vIHJlbW90ZSBvciBvbi1kaXNrIHJlc291cmNlcyB0byBwcm92aXNpb24uXG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBkZXN0cm95KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFN0YXRlbGVzczsgbm90aGluZyB0byByZWxlYXNlLlxuICB9XG5cbiAgZ2V0SW5mbygpOiBGaWxlc3lzdGVtSW5mbyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgcHJvdmlkZXI6IHRoaXMucHJvdmlkZXIsXG4gICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzLFxuICAgICAgcmVhZE9ubHk6IHRoaXMucmVhZE9ubHksXG4gICAgfTtcbiAgfVxuXG4gIGdldEluc3RydWN0aW9ucygpOiBzdHJpbmcge1xuICAgIHJldHVybiBcIlRoaXMgZmlsZXN5c3RlbSBpcyBlbXB0eSBhbmQgcmVhZC1vbmx5LlwiO1xuICB9XG5cbiAgcHJpdmF0ZSByb290U3RhdCgpOiBGaWxlU3RhdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IFwiL1wiLFxuICAgICAgcGF0aDogXCIvXCIsXG4gICAgICB0eXBlOiBcImRpcmVjdG9yeVwiLFxuICAgICAgc2l6ZTogMCxcbiAgICAgIGNyZWF0ZWRBdDogRU1QVFlfRklMRVNZU1RFTV9FUE9DSCxcbiAgICAgIG1vZGlmaWVkQXQ6IEVNUFRZX0ZJTEVTWVNURU1fRVBPQ0gsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXNzZXJ0V3JpdGFibGUob3BlcmF0aW9uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aHJvdyBuZXcgV29ya3NwYWNlUmVhZE9ubHlFcnJvcihvcGVyYXRpb24pO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgcmVhZEZpbGUoaW5wdXRQYXRoOiBzdHJpbmcsIF9vcHRpb25zPzogUmVhZE9wdGlvbnMpOiBQcm9taXNlPHN0cmluZyB8IEJ1ZmZlcj4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplRW1wdHlGaWxlc3lzdGVtUGF0aChpbnB1dFBhdGgpO1xuICAgIGlmIChub3JtYWxpemVkID09PSBcIi9cIikge1xuICAgICAgdGhyb3cgbmV3IElzRGlyZWN0b3J5RXJyb3Iobm9ybWFsaXplZCk7XG4gICAgfVxuICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFcnJvcihub3JtYWxpemVkKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIHdyaXRlRmlsZShcbiAgICBfaW5wdXRQYXRoOiBzdHJpbmcsXG4gICAgX2NvbnRlbnQ6IEZpbGVDb250ZW50LFxuICAgIF9vcHRpb25zPzogV3JpdGVPcHRpb25zLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KCk7XG4gICAgdGhpcy5hc3NlcnRXcml0YWJsZShcIndyaXRlRmlsZVwiKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIGFwcGVuZEZpbGUoX2lucHV0UGF0aDogc3RyaW5nLCBfY29udGVudDogRmlsZUNvbnRlbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KCk7XG4gICAgdGhpcy5hc3NlcnRXcml0YWJsZShcImFwcGVuZEZpbGVcIik7XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBkZWxldGVGaWxlKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogUmVtb3ZlT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplRW1wdHlGaWxlc3lzdGVtUGF0aChpbnB1dFBhdGgpO1xuICAgIGlmIChub3JtYWxpemVkID09PSBcIi9cIikge1xuICAgICAgdGhyb3cgbmV3IElzRGlyZWN0b3J5RXJyb3Iobm9ybWFsaXplZCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zPy5mb3JjZSkgcmV0dXJuO1xuICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFcnJvcihub3JtYWxpemVkKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIGNvcHlGaWxlKHNyYzogc3RyaW5nLCBfZGVzdDogc3RyaW5nLCBfb3B0aW9ucz86IENvcHlPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRTcmMgPSBub3JtYWxpemVFbXB0eUZpbGVzeXN0ZW1QYXRoKHNyYyk7XG4gICAgaWYgKG5vcm1hbGl6ZWRTcmMgIT09IFwiL1wiKSB7XG4gICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXJyb3Iobm9ybWFsaXplZFNyYyk7XG4gICAgfVxuICAgIHRocm93IG5ldyBJc0RpcmVjdG9yeUVycm9yKG5vcm1hbGl6ZWRTcmMpO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgbW92ZUZpbGUoc3JjOiBzdHJpbmcsIGRlc3Q6IHN0cmluZywgb3B0aW9ucz86IENvcHlPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jb3B5RmlsZShzcmMsIGRlc3QsIG9wdGlvbnMpO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgbWtkaXIoX2lucHV0UGF0aDogc3RyaW5nLCBfb3B0aW9ucz86IHsgcmVjdXJzaXZlPzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpO1xuICAgIHRoaXMuYXNzZXJ0V3JpdGFibGUoXCJta2RpclwiKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIHJtZGlyKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogUmVtb3ZlT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplRW1wdHlGaWxlc3lzdGVtUGF0aChpbnB1dFBhdGgpO1xuICAgIGlmIChub3JtYWxpemVkID09PSBcIi9cIikge1xuICAgICAgdGhyb3cgbmV3IERpcmVjdG9yeU5vdEVtcHR5RXJyb3Iobm9ybWFsaXplZCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zPy5mb3JjZSkgcmV0dXJuO1xuICAgIHRocm93IG5ldyBEaXJlY3RvcnlOb3RGb3VuZEVycm9yKG5vcm1hbGl6ZWQpO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgcmVhZGRpcihpbnB1dFBhdGg6IHN0cmluZywgX29wdGlvbnM/OiBMaXN0T3B0aW9ucyk6IFByb21pc2U8RmlsZUVudHJ5W10+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KCk7XG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUVtcHR5RmlsZXN5c3RlbVBhdGgoaW5wdXRQYXRoKTtcbiAgICBpZiAobm9ybWFsaXplZCA9PT0gXCIvXCIpIHJldHVybiBbXTtcbiAgICB0aHJvdyBuZXcgRGlyZWN0b3J5Tm90Rm91bmRFcnJvcihub3JtYWxpemVkKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIGV4aXN0cyhpbnB1dFBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICByZXR1cm4gbm9ybWFsaXplRW1wdHlGaWxlc3lzdGVtUGF0aChpbnB1dFBhdGgpID09PSBcIi9cIjtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIHN0YXQoaW5wdXRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPEZpbGVTdGF0PiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVFbXB0eUZpbGVzeXN0ZW1QYXRoKGlucHV0UGF0aCk7XG4gICAgaWYgKG5vcm1hbGl6ZWQgPT09IFwiL1wiKSByZXR1cm4gdGhpcy5yb290U3RhdCgpO1xuICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFcnJvcihub3JtYWxpemVkKTtcbiAgfVxufVxuXG4vKiogTWVtb2l6ZWQgc2luZ2xldG9uIGVtcHR5IHJlYWQtb25seSBmaWxlc3lzdGVtIGZvciBuby1vcCBtb3VudHMuICovXG5leHBvcnQgY29uc3QgZW1wdHlGaWxlc3lzdGVtID0gZnVuY3Rpb25Nb2R1bGUubWVtb2l6ZSgoKSA9PiBuZXcgRW1wdHlGaWxlc3lzdGVtKCkpO1xuIl19
|
|
238
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZXN5c3RlbXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmlsZXN5c3RlbXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBRUgsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBTWxFLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZixpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLHNCQUFzQixHQUN2QixNQUFNLHdCQUF3QixDQUFDO0FBb0NoQzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQ3pCLEVBQWMsRUFDZCxVQUEwQyxFQUFFO0lBRTVDLE9BQU8sSUFBSSx1QkFBdUIsQ0FBQyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDbEQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sdUJBQXdCLFNBQVEsZ0JBQWdCO0lBQzNELE1BQU0sR0FBbUIsU0FBUyxDQUFDO0lBRWxCLEVBQUUsQ0FBYTtJQUNmLE9BQU8sQ0FBaUM7SUFFekQsWUFBWSxFQUFjLEVBQUUsVUFBMEMsRUFBRTtRQUN0RSxLQUFLLENBQUM7WUFDSixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSx5QkFBeUI7WUFDL0MsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUztTQUM3QixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFJLEVBQUU7UUFDSixPQUFPLElBQUksQ0FBQyxPQUFP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QUksSUFBSSxDQUFDO1FBQ3BCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxJQUFJLEtBQUs7UUFDbEMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLElBQUksS0FBSztRQUNwQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7S0FDeEIsQ0FBQztBQUNKLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxTQUFpQjtJQUMvQyxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzlDLE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQ3ZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1hc3RyYSB3b3Jrc3BhY2UgZmlsZXN5c3RlbSBhZGFwdGVycy5cbiAqXG4gKiB7QGxpbmsgZmlsZXN5c3RlbXN9IHdyYXBzIGFueSBwb3J0YWJsZSBgQGRieC10b29scy9zaGFyZWQtZnNgIHtAbGluayBGaWxlU3lzdGVtfVxuICogKGxvY2FsIGRpc2ssIERhdGFicmlja3MsIG1lbW9yeSwg4oCmKSBhcyBhIE1hc3RyYSB7QGxpbmsgTWFzdHJhRmlsZXN5c3RlbX0uXG4gKiB7QGxpbmsgc2NyYXRjaEZpbGVzeXN0ZW19IGFsd2F5cyByZXR1cm5zIGEgZnJlc2gge0BsaW5rIGxvY2FsRlMudG1wRlN9IG1vdW50XG4gKiAocmFuZG9tIGlkIHJvb3QpIHdoZW4gTWFzdHJhIG5lZWRzIGEgZmlsZXN5c3RlbSBhbmQgbm8gb3RoZXIgbW91bnQgcmVzb2x2ZWQuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGxvY2FsRlMgfSBmcm9tIFwiQGRieC10b29scy9mc1wiO1xuaW1wb3J0IHsgRmlsZVN5c3RlbUVycm9yLCBwb3NpeFBhdGggfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtZnNcIjtcbmltcG9ydCB0eXBlIHtcbiAgRmlsZUVudHJ5IGFzIFNoYXJlZEZpbGVFbnRyeSxcbiAgRmlsZVN0YXQgYXMgU2hhcmVkRmlsZVN0YXQsXG4gIEZpbGVTeXN0ZW0sXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1mc1wiO1xuaW1wb3J0IHtcbiAgRGlyZWN0b3J5Tm90RW1wdHlFcnJvcixcbiAgRGlyZWN0b3J5Tm90Rm91bmRFcnJvcixcbiAgRmlsZUV4aXN0c0Vycm9yLFxuICBGaWxlTm90Rm91bmRFcnJvcixcbiAgSXNEaXJlY3RvcnlFcnJvcixcbiAgTWFzdHJhRmlsZXN5c3RlbSxcbiAgTm90RGlyZWN0b3J5RXJyb3IsXG4gIFBlcm1pc3Npb25FcnJvcixcbiAgV29ya3NwYWNlUmVhZE9ubHlFcnJvcixcbn0gZnJvbSBcIkBtYXN0cmEvY29yZS93b3Jrc3BhY2VcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ29weU9wdGlvbnMsXG4gIEZpbGVDb250ZW50LFxuICBGaWxlRW50cnksXG4gIEZpbGVTdGF0LFxuICBGaWxlc3lzdGVtSW5mbyxcbiAgTGlzdE9wdGlvbnMsXG4gIE1hc3RyYUZpbGVzeXN0ZW1PcHRpb25zLFxuICBQcm92aWRlclN0YXR1cyxcbiAgUmVhZE9wdGlvbnMsXG4gIFJlbW92ZU9wdGlvbnMsXG4gIFdyaXRlT3B0aW9ucyxcbn0gZnJvbSBcIkBtYXN0cmEvY29yZS93b3Jrc3BhY2VcIjtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBmaWxlc3lzdGVtc30gLyB7QGxpbmsgTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXJ9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBNYXN0cmFGaWxlU3lzdGVtQWRhcHRlck9wdGlvbnMgZXh0ZW5kcyBNYXN0cmFGaWxlc3lzdGVtT3B0aW9ucyB7XG4gIC8qKiBPdmVycmlkZSB0aGUgTWFzdHJhIGZpbGVzeXN0ZW0gaWQuIERlZmF1bHRzIHRvIHRoZSBzb3VyY2Uge0BsaW5rIEZpbGVTeXN0ZW0uaWR9LiAqL1xuICBpZD86IHN0cmluZztcblxuICAvKiogT3ZlcnJpZGUgdGhlIE1hc3RyYSBkaXNwbGF5IG5hbWUuIERlZmF1bHRzIHRvIGBNYXN0cmFGaWxlU3lzdGVtQWRhcHRlcmAuICovXG4gIG5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSBNYXN0cmEgcHJvdmlkZXIgaWQuIERlZmF1bHRzIHRvIHRoZSBzb3VyY2VcbiAgICoge0BsaW5rIEZpbGVTeXN0ZW0uYmFja2VuZH0uXG4gICAqL1xuICBwcm92aWRlcj86IHN0cmluZztcblxuICAvKipcbiAgICogRm9yY2UgcmVhZC1vbmx5IG1vdW50cyBldmVuIHdoZW4gdGhlIHNvdXJjZSBmaWxlc3lzdGVtIGFsbG93cyB3cml0ZXMuXG4gICAqIFRoZSBzb3VyY2Uge0BsaW5rIEZpbGVTeXN0ZW0ucmVhZE9ubHl9IGZsYWcgc3RpbGwgYXBwbGllcyBlaXRoZXIgd2F5LlxuICAgKi9cbiAgcmVhZE9ubHk/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFdyYXAgYSBwb3J0YWJsZSB7QGxpbmsgRmlsZVN5c3RlbX0gYXMgYSBNYXN0cmEge0BsaW5rIE1hc3RyYUZpbGVzeXN0ZW19LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgZmlsZXN5c3RlbXMgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXQtbWFzdHJhXCI7XG4gKiBpbXBvcnQgeyBEYXRhYnJpY2tzRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL2RhdGFicmlja3NcIjtcbiAqIGltcG9ydCB7IGxvY2FsRlMgfSBmcm9tIFwiQGRieC10b29scy9mc1wiO1xuICpcbiAqIGNvbnN0IHZvbHVtZSA9IGZpbGVzeXN0ZW1zLmZpbGVzeXN0ZW1zKFxuICogICBuZXcgRGF0YWJyaWNrc0ZpbGVTeXN0ZW0oeyByb290OiBcIi9Wb2x1bWVzL21haW4vZGVmYXVsdC9hc3NldHNcIiB9KSxcbiAqICk7XG4gKiBjb25zdCBzY3JhdGNoID0gZmlsZXN5c3RlbXMuZmlsZXN5c3RlbXMobG9jYWxGUy50bXBGUyhcImFnZW50LWpvYlwiKSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGVzeXN0ZW1zKFxuICBmczogRmlsZVN5c3RlbSxcbiAgb3B0aW9uczogTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXJPcHRpb25zID0ge30sXG4pOiBNYXN0cmFGaWxlU3lzdGVtQWRhcHRlciB7XG4gIHJldHVybiBuZXcgTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXIoZnMsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIFRoaW4gTWFzdHJhIHtAbGluayBNYXN0cmFGaWxlc3lzdGVtfSBhZGFwdGVyIG92ZXIgYSBgQGRieC10b29scy9zaGFyZWQtZnNgXG4gKiB7QGxpbmsgRmlsZVN5c3RlbX0uIElkZW50aXR5IGZpZWxkcyBhcmUgZ2V0dGVycyB0aGF0IHJlYWQgdGhlIHNvdXJjZSBvblxuICogYWNjZXNzOyBjb25zdHJ1Y3Rpb24gZG9lcyBub3Qgc25hcHNob3QgdGhlbS5cbiAqL1xuZXhwb3J0IGNsYXNzIE1hc3RyYUZpbGVTeXN0ZW1BZGFwdGVyIGV4dGVuZHMgTWFzdHJhRmlsZXN5c3RlbSB7XG4gIHN0YXR1czogUHJvdmlkZXJTdGF0dXMgPSBcInBlbmRpbmdcIjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGZzOiBGaWxlU3lzdGVtO1xuICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IE1hc3RyYUZpbGVTeXN0ZW1BZGFwdGVyT3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihmczogRmlsZVN5c3RlbSwgb3B0aW9uczogTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXJPcHRpb25zID0ge30pIHtcbiAgICBzdXBlcih7XG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUgPz8gXCJNYXN0cmFGaWxlU3lzdGVtQWRhcHRlclwiLFxuICAgICAgb25Jbml0OiBvcHRpb25zLm9uSW5pdCxcbiAgICAgIG9uRGVzdHJveTogb3B0aW9ucy5vbkRlc3Ryb3ksXG4gICAgfSk7XG4gICAgdGhpcy5mcyA9IGZzO1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICBnZXQgaWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmlkID8/IHRoaXMuZnMuaWQ7XG4gIH1cblxuICBnZXQgbmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMubmFtZSA/PyBcIk1hc3RyYUZpbGVTeXN0ZW1BZGFwdGVyXCI7XG4gIH1cblxuICBnZXQgcHJvdmlkZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnByb3ZpZGVyID8/IHRoaXMuZnMuYmFja2VuZDtcbiAgfVxuXG4gIGdldCByZWFkT25seSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnJlYWRPbmx5ID09PSB0cnVlIHx8IHRoaXMuZnMucmVhZE9ubHk7XG4gIH1cblxuICBnZXQgYmFzZVBhdGgoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5mcy5yb290O1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgaW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmZzLmluaXQoKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIGRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5mcy5jbG9zZSgpO1xuICB9XG5cbiAgZ2V0SW5mbygpOiBGaWxlc3lzdGVtSW5mbzx7IHJvb3Q6IHN0cmluZzsgYmFja2VuZDogc3RyaW5nIH0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBwcm92aWRlcjogdGhpcy5wcm92aWRlcixcbiAgICAgIHN0YXR1czogdGhpcy5zdGF0dXMsXG4gICAgICByZWFkT25seTogdGhpcy5yZWFkT25seSxcbiAgICAgIG1ldGFkYXRhOiB7IHJvb3Q6IHRoaXMuZnMucm9vdCwgYmFja2VuZDogdGhpcy5mcy5iYWNrZW5kIH0sXG4gICAgfTtcbiAgfVxuXG4gIGdldEluc3RydWN0aW9ucygpOiBzdHJpbmcge1xuICAgIHJldHVybiBbXG4gICAgICBgRmlsZXMgYXJlIHNlcnZlZCBieSBhICR7dGhpcy5mcy5iYWNrZW5kfSBmaWxlc3lzdGVtIHJvb3RlZCBhdCAke3RoaXMuZnMucm9vdH0uYCxcbiAgICAgIFwiV29ya3NwYWNlIHBhdGhzIGFyZSBhYnNvbHV0ZSB3aXRoaW4gdGhpcyBtb3VudCAoZm9yIGV4YW1wbGUgYC9ub3Rlcy9yZXBvcnQubWRgKS5cIixcbiAgICBdLmpvaW4oXCIgXCIpO1xuICB9XG5cbiAgYXN5bmMgcmVhZEZpbGUoaW5wdXRQYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBSZWFkT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nIHwgQnVmZmVyPiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZWdhdGUoaW5wdXRQYXRoLCBhc3luYyAoKSA9PiB7XG4gICAgICBpZiAob3B0aW9ucz8uZW5jb2RpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnMucmVhZEZpbGUoaW5wdXRQYXRoLCB7IGVuY29kaW5nOiBvcHRpb25zLmVuY29kaW5nIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGF3YWl0IHRoaXMuZnMucmVhZEZpbGUoaW5wdXRQYXRoKSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyB3cml0ZUZpbGUoaW5wdXRQYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IEZpbGVDb250ZW50LCBvcHRpb25zPzogV3JpdGVPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVXcml0ZShcIndyaXRlRmlsZVwiLCBpbnB1dFBhdGgsIGFzeW5jICgpID0+IHtcbiAgICAgIGlmIChvcHRpb25zPy5yZWN1cnNpdmUgPT09IGZhbHNlKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYXNzZXJ0UGFyZW50RXhpc3RzKGlucHV0UGF0aCk7XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmZzLndyaXRlRmlsZShpbnB1dFBhdGgsIGNvbnRlbnQsIHtcbiAgICAgICAgb3ZlcndyaXRlOiBvcHRpb25zPy5vdmVyd3JpdGUgPz8gdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgYXBwZW5kRmlsZShpbnB1dFBhdGg6IHN0cmluZywgY29udGVudDogRmlsZUNvbnRlbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZVdyaXRlKFwiYXBwZW5kRmlsZVwiLCBpbnB1dFBhdGgsICgpID0+XG4gICAgICB0aGlzLmZzLmFwcGVuZEZpbGUoaW5wdXRQYXRoLCBjb250ZW50KSxcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlRmlsZShpbnB1dFBhdGg6IHN0cmluZywgb3B0aW9ucz86IFJlbW92ZU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZVdyaXRlKFwiZGVsZXRlRmlsZVwiLCBpbnB1dFBhdGgsICgpID0+XG4gICAgICB0aGlzLmZzLmRlbGV0ZUZpbGUoaW5wdXRQYXRoLCB7XG4gICAgICAgIGZvcmNlOiBvcHRpb25zPy5mb3JjZSxcbiAgICAgICAgcmVjdXJzaXZlOiBvcHRpb25zPy5yZWN1cnNpdmUsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgY29weUZpbGUoc3JjOiBzdHJpbmcsIGRlc3Q6IHN0cmluZywgb3B0aW9ucz86IENvcHlPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVXcml0ZShcImNvcHlGaWxlXCIsIGRlc3QsICgpID0+XG4gICAgICB0aGlzLmZzLmNvcHlGaWxlKHNyYywgZGVzdCwgeyBvdmVyd3JpdGU6IG9wdGlvbnM/Lm92ZXJ3cml0ZSA/PyB0cnVlIH0pLFxuICAgICk7XG4gIH1cblxuICBhc3luYyBtb3ZlRmlsZShzcmM6IHN0cmluZywgZGVzdDogc3RyaW5nLCBvcHRpb25zPzogQ29weU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZVdyaXRlKFwibW92ZUZpbGVcIiwgZGVzdCwgKCkgPT5cbiAgICAgIHRoaXMuZnMubW92ZUZpbGUoc3JjLCBkZXN0LCB7IG92ZXJ3cml0ZTogb3B0aW9ucz8ub3ZlcndyaXRlID8/IHRydWUgfSksXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIG1rZGlyKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogeyByZWN1cnNpdmU/OiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZVdyaXRlKFwibWtkaXJcIiwgaW5wdXRQYXRoLCAoKSA9PlxuICAgICAgdGhpcy5mcy5ta2RpcihpbnB1dFBhdGgsIHsgcmVjdXJzaXZlOiBvcHRpb25zPy5yZWN1cnNpdmUgfSksXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHJtZGlyKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogUmVtb3ZlT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmRlbGVnYXRlV3JpdGUoXG4gICAgICBcInJtZGlyXCIsXG4gICAgICBpbnB1dFBhdGgsXG4gICAgICAoKSA9PlxuICAgICAgICB0aGlzLmZzLnJtZGlyKGlucHV0UGF0aCwge1xuICAgICAgICAgIGZvcmNlOiBvcHRpb25zPy5mb3JjZSxcbiAgICAgICAgICByZWN1cnNpdmU6IG9wdGlvbnM/LnJlY3Vyc2l2ZSxcbiAgICAgICAgfSksXG4gICAgICB7IHByZWZlckRpcmVjdG9yeTogdHJ1ZSB9LFxuICAgICk7XG4gIH1cblxuICBhc3luYyByZWFkZGlyKGlucHV0UGF0aDogc3RyaW5nLCBvcHRpb25zPzogTGlzdE9wdGlvbnMpOiBQcm9taXNlPEZpbGVFbnRyeVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZWdhdGUoXG4gICAgICBpbnB1dFBhdGgsXG4gICAgICBhc3luYyAoKSA9PlxuICAgICAgICAoXG4gICAgICAgICAgYXdhaXQgdGhpcy5mcy5yZWFkZGlyKGlucHV0UGF0aCwge1xuICAgICAgICAgICAgcmVjdXJzaXZlOiBvcHRpb25zPy5yZWN1cnNpdmUsXG4gICAgICAgICAgICBtYXhEZXB0aDogb3B0aW9ucz8ubWF4RGVwdGgsXG4gICAgICAgICAgICBleHRlbnNpb246IG9wdGlvbnM/LmV4dGVuc2lvbixcbiAgICAgICAgICB9KVxuICAgICAgICApLm1hcCh0b01hc3RyYUVudHJ5KSxcbiAgICAgIHsgcHJlZmVyRGlyZWN0b3J5OiB0cnVlIH0sXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGV4aXN0cyhpbnB1dFBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICByZXR1cm4gdGhpcy5mcy5leGlzdHMoaW5wdXRQYXRoKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXQoaW5wdXRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPEZpbGVTdGF0PiB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZWdhdGUoaW5wdXRQYXRoLCBhc3luYyAoKSA9PlxuICAgICAgdG9NYXN0cmFTdGF0KGF3YWl0IHRoaXMuZnMuc3RhdChpbnB1dFBhdGgpLCBpbnB1dFBhdGgpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRlbGVnYXRlPFQ+KFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBvcDogKCkgPT4gUHJvbWlzZTxUPixcbiAgICBvcHRpb25zPzogeyBwcmVmZXJEaXJlY3Rvcnk/OiBib29sZWFuIH0sXG4gICk6IFByb21pc2U8VD4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IG9wKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLnJldGhyb3coZXJyLCBwYXRoLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKioge0BsaW5rIGRlbGVnYXRlfSBmb3IgYSBtdXRhdGlvbjogcmVmdXNlIGEgcmVhZC1vbmx5IG1vdW50IGJlZm9yZSBkb2luZyBhbnkgd29yay4gKi9cbiAgcHJpdmF0ZSBkZWxlZ2F0ZVdyaXRlKFxuICAgIG9wZXJhdGlvbjogc3RyaW5nLFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBvcDogKCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgICBvcHRpb25zPzogeyBwcmVmZXJEaXJlY3Rvcnk/OiBib29sZWFuIH0sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnJlYWRPbmx5KSB7XG4gICAgICB0aHJvdyBuZXcgV29ya3NwYWNlUmVhZE9ubHlFcnJvcihvcGVyYXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZShwYXRoLCBvcCwgb3B0aW9ucyk7XG4gIH1cblxuICAvKiogV2hlbiBNYXN0cmEgYXNrcyBmb3Igbm9uLXJlY3Vyc2l2ZSB3cml0ZXMsIHJlcXVpcmUgdGhlIHBhcmVudCBkaXJlY3RvcnkuICovXG4gIHByaXZhdGUgYXN5bmMgYXNzZXJ0UGFyZW50RXhpc3RzKGlucHV0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcGFyZW50ID0gcG9zaXhQYXRoLmRpcm5hbWUobm9ybWFsaXplV29ya3NwYWNlUGF0aChpbnB1dFBhdGgpKTtcbiAgICBpZiAocGFyZW50ID09PSBcIi9cIiB8fCAoYXdhaXQgdGhpcy5mcy5leGlzdHMocGFyZW50KSkpIHJldHVybjtcbiAgICB0aHJvdyBuZXcgRGlyZWN0b3J5Tm90Rm91bmRFcnJvcihwYXJlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXRocm93KGVycjogdW5rbm93biwgaW5wdXRQYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiB7IHByZWZlckRpcmVjdG9yeT86IGJvb2xlYW4gfSk6IG5ldmVyIHtcbiAgICBpZiAoXG4gICAgICBlcnIgaW5zdGFuY2VvZiBGaWxlTm90Rm91bmRFcnJvciB8fFxuICAgICAgZXJyIGluc3RhbmNlb2YgRGlyZWN0b3J5Tm90Rm91bmRFcnJvciB8fFxuICAgICAgZXJyIGluc3RhbmNlb2YgRmlsZUV4aXN0c0Vycm9yIHx8XG4gICAgICBlcnIgaW5zdGFuY2VvZiBJc0RpcmVjdG9yeUVycm9yIHx8XG4gICAgICBlcnIgaW5zdGFuY2VvZiBOb3REaXJlY3RvcnlFcnJvciB8fFxuICAgICAgZXJyIGluc3RhbmNlb2YgRGlyZWN0b3J5Tm90RW1wdHlFcnJvciB8fFxuICAgICAgZXJyIGluc3RhbmNlb2YgUGVybWlzc2lvbkVycm9yIHx8XG4gICAgICBlcnIgaW5zdGFuY2VvZiBXb3Jrc3BhY2VSZWFkT25seUVycm9yXG4gICAgKSB7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuXG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEZpbGVTeXN0ZW1FcnJvcikge1xuICAgICAgdGhyb3cgbWFwU2hhcmVkRXJyb3IoZXJyLCBpbnB1dFBhdGgsIG9wdGlvbnM/LnByZWZlckRpcmVjdG9yeSA9PT0gdHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbi8qKiBGcmVzaCB3cml0YWJsZSBsb2NhbCB0ZW1wIG1vdW50IG9uIGEgcm9vdCB1bmlxdWUgdG8gdGhpcyBjYWxsLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcmF0Y2hGaWxlc3lzdGVtKCk6IE1hc3RyYUZpbGVTeXN0ZW1BZGFwdGVyIHtcbiAgcmV0dXJuIGZpbGVzeXN0ZW1zKGxvY2FsRlMuc2NyYXRjaEZTKFwibWFzdHJhXCIpKTtcbn1cblxuLyoqIE1hcCBhIHNoYXJlZC1mcyBlcnJvciBjb2RlIG9udG8gdGhlIG1hdGNoaW5nIE1hc3RyYSBmaWxlc3lzdGVtIGVycm9yLiAqL1xuZnVuY3Rpb24gbWFwU2hhcmVkRXJyb3IoZXJyOiBGaWxlU3lzdGVtRXJyb3IsIGlucHV0UGF0aDogc3RyaW5nLCBwcmVmZXJEaXJlY3Rvcnk6IGJvb2xlYW4pOiBFcnJvciB7XG4gIGNvbnN0IHBhdGggPSBlcnIucGF0aCA/PyBpbnB1dFBhdGg7XG4gIHN3aXRjaCAoZXJyLmNvZGUpIHtcbiAgICBjYXNlIFwiTk9UX0ZPVU5EXCI6XG4gICAgICByZXR1cm4gcHJlZmVyRGlyZWN0b3J5ID8gbmV3IERpcmVjdG9yeU5vdEZvdW5kRXJyb3IocGF0aCkgOiBuZXcgRmlsZU5vdEZvdW5kRXJyb3IocGF0aCk7XG4gICAgY2FzZSBcIkFMUkVBRFlfRVhJU1RTXCI6XG4gICAgICByZXR1cm4gbmV3IEZpbGVFeGlzdHNFcnJvcihwYXRoKTtcbiAgICBjYXNlIFwiTk9UX0RJUkVDVE9SWVwiOlxuICAgICAgcmV0dXJuIG5ldyBOb3REaXJlY3RvcnlFcnJvcihwYXRoKTtcbiAgICBjYXNlIFwiSVNfRElSRUNUT1JZXCI6XG4gICAgICByZXR1cm4gbmV3IElzRGlyZWN0b3J5RXJyb3IocGF0aCk7XG4gICAgY2FzZSBcIkRJUkVDVE9SWV9OT1RfRU1QVFlcIjpcbiAgICAgIHJldHVybiBuZXcgRGlyZWN0b3J5Tm90RW1wdHlFcnJvcihwYXRoKTtcbiAgICBjYXNlIFwiUEVSTUlTU0lPTl9ERU5JRURcIjpcbiAgICAgIHJldHVybiBuZXcgUGVybWlzc2lvbkVycm9yKHBhdGgsIGVyci5tZXNzYWdlKTtcbiAgICBjYXNlIFwiUkVBRF9PTkxZXCI6XG4gICAgICByZXR1cm4gbmV3IFdvcmtzcGFjZVJlYWRPbmx5RXJyb3IoZXJyLm1lc3NhZ2UpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZXJyO1xuICB9XG59XG5cbmZ1bmN0aW9uIHRvTWFzdHJhRW50cnkoZW50cnk6IFNoYXJlZEZpbGVFbnRyeSk6IEZpbGVFbnRyeSB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogZW50cnkubmFtZSxcbiAgICB0eXBlOiBlbnRyeS50eXBlID09PSBcImRpcmVjdG9yeVwiID8gXCJkaXJlY3RvcnlcIiA6IFwiZmlsZVwiLFxuICAgIHNpemU6IGVudHJ5LnNpemUsXG4gICAgaXNTeW1saW5rOiBlbnRyeS50eXBlID09PSBcInN5bWJvbGljLWxpbmtcIixcbiAgfTtcbn1cblxuZnVuY3Rpb24gdG9NYXN0cmFTdGF0KHN0YXQ6IFNoYXJlZEZpbGVTdGF0LCBpbnB1dFBhdGg6IHN0cmluZyk6IEZpbGVTdGF0IHtcbiAgY29uc3QgZXBvY2ggPSBuZXcgRGF0ZSgwKTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBzdGF0Lm5hbWUsXG4gICAgcGF0aDogbm9ybWFsaXplV29ya3NwYWNlUGF0aChzdGF0LnBhdGggfHwgaW5wdXRQYXRoKSxcbiAgICB0eXBlOiBzdGF0LnR5cGUgPT09IFwiZGlyZWN0b3J5XCIgPyBcImRpcmVjdG9yeVwiIDogXCJmaWxlXCIsXG4gICAgc2l6ZTogc3RhdC5zaXplID8/IDAsXG4gICAgY3JlYXRlZEF0OiBzdGF0LmNyZWF0ZWRBdCA/PyBlcG9jaCxcbiAgICBtb2RpZmllZEF0OiBzdGF0Lm1vZGlmaWVkQXQgPz8gZXBvY2gsXG4gICAgbWltZVR5cGU6IHN0YXQubWltZVR5cGUsXG4gIH07XG59XG5cbi8qKlxuICogTWFzdHJhIG5hbWVzcGFjZSBwYXRoIChgL2EvYmApLiBBIGAuLmAgdGhhdCB3b3VsZCBlc2NhcGUgY2xhbXBzIHRvIHRoZSByb290XG4gKiByYXRoZXIgdGhhbiB0aHJvd2luZyAtIHRoZSB3cmFwcGVkIGZpbGVzeXN0ZW0gZW5mb3JjZXMgY29udGFpbm1lbnQgaXRzZWxmLFxuICogYW5kIGEgbW91bnQgc2hvdWxkIG5vdCBmYWlsIGEgbGlzdGluZyBvdmVyIGEgc3RyYXkgc2VnbWVudC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplV29ya3NwYWNlUGF0aChpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJlc3VsdCA9IHBvc2l4UGF0aC5ub3JtYWxpemUoaW5wdXRQYXRoKTtcbiAgcmV0dXJuIHJlc3VsdC5vayA/IHJlc3VsdC5wYXRoIDogXCIvXCI7XG59XG4iXX0=
|