@dbx-tools/appkit-mastra 0.9.93 → 0.9.99

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.
@@ -1,130 +1,134 @@
1
1
  /**
2
2
  * Mastra workspace factory for Databricks Apps.
3
3
  *
4
- * Builds a per-request {@link Workspace} with Databricks Sandbox command
5
- * execution plus a {@link CompositeFilesystem} over the NAMED skill folders
6
- * resolved for that request. A skill folder maps a name to a location plus its
7
- * readable / writable policy: a Databricks path mounted through the OBO client
8
- * on {@link MASTRA_USER_KEY}, or any {@link WorkspaceFilesystem} a consuming
9
- * library already owns. {@link DEFAULT_SKILL_FOLDERS} supplies the Assistant
10
- * trees, and `skillFolders` merges over it - same name overrides, `false`
11
- * disables, a new name adds. Optional mount resolvers contribute further
12
- * filesystems and skill scan roots on top.
4
+ * Builds native Mastra workspace configuration from Databricks paths. Paths
5
+ * mount at the same path by default, `~` resolves to the current user's
6
+ * Databricks workspace home, and `/tmp[/subpath]` resolves to stable
7
+ * user-scoped storage under the host's ephemeral temp directory.
13
8
  *
14
9
  * Databricks mounts use `@dbx-tools/databricks` {@link DatabricksFileSystem}
15
- * wrapped by {@link filesystems}; missing roots fall back to
16
- * {@link scratchFilesystem}.
10
+ * wrapped by {@link filesystems}; inaccessible roots are skipped independently.
17
11
  *
18
12
  * @module
19
13
  */
20
14
  import { createHash } from "node:crypto";
21
- import { ConfigurationError, createWorkspaceClient } from "@databricks/appkit";
15
+ import { tmpdir } from "node:os";
16
+ import { join } from "node:path";
17
+ import { ConfigurationError, createWorkspaceClient, getExecutionContext } from "@databricks/appkit";
18
+ import { pluginRegistry } from "@dbx-tools/appkit";
19
+ import { filesCache as filesCachePlugin, } from "@dbx-tools/appkit/files-cache";
22
20
  import { DatabricksFileSystem, workspaceClient } from "@dbx-tools/databricks";
23
21
  import { LocalFileSystem } from "@dbx-tools/fs";
22
+ import { match } from "@dbx-tools/path";
24
23
  import { errorUtils, log, object, stringUtils, token } from "@dbx-tools/shared-core";
25
- import { LRUCache } from "lru-cache";
26
- import { CompositeFilesystem, Workspace, } from "@mastra/core/workspace";
24
+ import { fs as sharedFS, posixPath, MemoryFileSystem, } from "@dbx-tools/shared-fs";
25
+ import { WORKSPACE_TOOLS, Workspace, } from "@mastra/core/workspace";
27
26
  import { MASTRA_SCOPES_KEY, MASTRA_USER_EMAIL_KEY, MASTRA_USER_KEY, resolveUserKey, } from "./config.js";
28
- import { filesystems, scratchFilesystem } from "./filesystems.js";
27
+ import { filesystems, MountedCompositeFilesystem, } from "./filesystems.js";
29
28
  import { MontySandbox } from "./monty-sandbox.js";
30
29
  import { DatabricksSandbox } from "./sandbox.js";
31
- import { DEFAULT_WORKSPACE_SKILL_CACHE_TTL_MS, workspaceSkillCatalogue, } from "./skill-cache.js";
32
- import { ASSISTANT_SHARED_SKILLS_PATH, userAssistantSkillsPath } from "./skill-paths.js";
30
+ import { ORGANIZATION_ASSISTANT_PATH, personalWorkspacePath } from "./skill-paths.js";
33
31
  /* ------------------------------ constants ------------------------------ */
34
32
  /** OAuth scopes that gate Databricks workspace file mounts. */
35
33
  const WORKSPACE_FILE_SCOPES = ["workspace", "workspace.workspace", "all-apis"];
34
+ const SCRATCH_MOUNT = "/tmp";
35
+ const CACHEABLE_FILESYSTEM_OPERATIONS = [
36
+ "exists",
37
+ "readFile",
38
+ "readdir",
39
+ "stat",
40
+ ];
36
41
  const logger = log.logger("mastra/workspaces");
37
- const MAX_SCOPED_WORKSPACE_FILESYSTEMS = 16;
38
- const scopedWorkspaceFilesystems = new LRUCache({
39
- max: MAX_SCOPED_WORKSPACE_FILESYSTEMS,
40
- });
41
- const workspaceCatalogueResolvers = new WeakMap();
42
+ let workspaceSourceSequence = 0;
43
+ const databricksWorkspaceOptions = new WeakMap();
42
44
  /* ------------------------------- defaults ------------------------------- */
43
45
  /**
44
- * The skill folders every workspace starts with.
45
- *
46
- * - `workspace-team` - the shared workspace Assistant tree, read-only because
47
- * writing it is a workspace-admin action.
48
- * - `workspace-team-app` - the requesting user's own Assistant tree, writable
49
- * so the app can save skills back to it. Skipped when the request carries no
50
- * user email.
46
+ * Default Databricks paths for shared and current-user Agent Skills.
51
47
  */
52
- export const DEFAULT_SKILL_FOLDERS = {
53
- "workspace-team": {
54
- path: ASSISTANT_SHARED_SKILLS_PATH,
48
+ export const DEFAULT_DATABRICKS_WORKSPACE_PATHS = [
49
+ {
50
+ path: ORGANIZATION_ASSISTANT_PATH,
55
51
  readable: true,
56
- writable: false,
52
+ skills: ["skills"],
53
+ writable: true,
54
+ createRoot: false,
57
55
  },
58
- "workspace-team-app": {
59
- path: ({ requestContext }) => {
60
- const email = resolveScopedEmail(requestContext);
61
- return email ? userAssistantSkillsPath(email) : undefined;
62
- },
56
+ {
57
+ path: "~",
63
58
  readable: true,
59
+ skills: [".assistant/skills"],
64
60
  writable: true,
61
+ createRoot: false,
65
62
  },
66
- };
63
+ ];
67
64
  /**
68
65
  * Create a Mastra {@link Workspace} with per-request Databricks mounts.
69
66
  *
70
- * @example Default skill folders only
67
+ * @example Default Databricks paths
71
68
  * ```ts
72
- * createWorkspace()
69
+ * databricksWorkspace()
73
70
  * ```
74
71
  *
75
- * @example Override a default, drop another, and add a location of your own
72
+ * @example Use only explicit paths
76
73
  * ```ts
77
- * createWorkspace({
78
- * skillFolders: {
79
- * "workspace-team": { path: "/Workspace/Shared/team-skills" },
80
- * "workspace-team-app": false,
81
- * runbooks: { path: "/Workspace/Shared/runbooks/skills", writable: true },
82
- * volume: { filesystem: myVolumeFilesystem },
83
- * },
74
+ * databricksWorkspace({
75
+ * assistantPaths: false,
76
+ * paths: ["~/project", "/tmp/project", "/Volumes/main/default/data"],
84
77
  * })
85
78
  * ```
86
79
  *
87
- * @example Skill folders plus a custom mount resolver
80
+ * @example Build a standard Mastra workspace yourself
88
81
  * ```ts
89
- * createWorkspace({
90
- * mounts: [
91
- * async ({ requestContext }) => ({
92
- * mounts: { "/data": myFilesystem },
93
- * skillPaths: [],
94
- * }),
95
- * ],
82
+ * new Workspace({
83
+ * ...databricksWorkspaceConfig({ paths: ["~/project"] }),
84
+ * sandbox: mySandbox,
96
85
  * })
97
86
  * ```
98
87
  */
99
- export function createWorkspace(options = {}) {
88
+ export function databricksWorkspaceConfig(options = {}) {
100
89
  const { id, name } = resolveWorkspaceIdentity(options);
101
- const skillFolders = resolveSkillFolders(options);
102
- const folderNames = Object.keys(skillFolders);
90
+ const filesystemSourceKey = `${id}:${++workspaceSourceSequence}`;
91
+ const paths = resolveDatabricksWorkspacePaths(options);
92
+ const configuredPaths = paths.length;
103
93
  const extraSkillPaths = options.extraSkillPaths ?? [];
104
- const resolvers = buildMountResolvers(skillFolders, [...(options.mounts ?? []), ...localSkillMountResolvers(extraSkillPaths)]);
94
+ const filesCache = pluginRegistry.instance(options.pluginContext, filesCachePlugin)?.exports();
95
+ const configuredCache = options.cache;
96
+ const mountFilesCache = configuredCache === false ? undefined : filesCache;
97
+ const retainFilesystemSource = mountFilesCache !== undefined &&
98
+ typeof configuredCache !== "function" &&
99
+ paths.every((path) => typeof path !== "function");
100
+ const resolvers = buildMountResolvers(paths, options.mounts, localSkillMountResolvers(extraSkillPaths), mountFilesCache, configuredCache);
105
101
  const resolveContribution = contributionResolver(resolvers);
106
- const skills = options.skills;
102
+ const resolveFilesystem = (context) => resolveWorkspaceFilesystem(resolveContribution, context, retainFilesystemSource ? mountFilesCache : undefined, filesystemSourceKey);
103
+ const skills = options.skills ??
104
+ (async ({ requestContext }) => {
105
+ const context = { requestContext };
106
+ const contribution = await resolveContribution(context);
107
+ return resolveDistinctSkillPaths(await resolveFilesystem(context), contribution.skillPaths ?? []);
108
+ });
107
109
  const checkSkillFileMtime = options.checkSkillFileMtime ?? false;
108
- const bm25 = options.bm25 !== false;
110
+ const bm25 = options.bm25 ?? true;
109
111
  const sandbox = resolveWorkspaceSandbox(options.sandbox, id, name);
112
+ const tools = workspaceTools(options.tools);
110
113
  logger.debug("workspace:create", {
111
114
  id,
112
115
  name,
113
116
  resolverCount: resolvers.length,
114
- skillFolders: folderNames,
115
- customMountResolvers: options.mounts?.length ?? 0,
117
+ configuredPaths,
118
+ customMounts: Object.keys(options.mounts ?? {}).length,
116
119
  customSkillsResolver: Boolean(options.skills),
117
120
  checkSkillFileMtime,
118
- workspaceSkillRefreshTtlMs: options.workspaceSkillRefreshTtlMs ?? DEFAULT_WORKSPACE_SKILL_CACHE_TTL_MS,
119
121
  bm25,
120
122
  extraSkillPaths: extraSkillPaths.length,
121
123
  sandbox: sandbox ? sandboxName(options.sandbox) : "disabled",
122
124
  });
123
- const workspace = new Workspace({
125
+ const { assistantPaths: _assistantPaths, paths: _paths, mounts: _mounts, skills: _skills, cache: _cache, pluginContext: _pluginContext, sandbox: _sandbox, extraSkillPaths: _extraSkillPaths, ...workspaceOptions } = options;
126
+ return {
127
+ ...workspaceOptions,
124
128
  id,
125
129
  name,
126
- filesystem: (context) => resolveWorkspaceFilesystem(resolveContribution, context),
127
- ...(skills
130
+ filesystem: resolveFilesystem,
131
+ ...(resolvers.length > 0 || options.skills
128
132
  ? {
129
133
  skills,
130
134
  checkSkillFileMtime,
@@ -137,35 +141,71 @@ export function createWorkspace(options = {}) {
137
141
  }
138
142
  : {}),
139
143
  bm25,
140
- });
141
- if (!options.skills && resolvers.length > 0) {
142
- workspaceCatalogueResolvers.set(workspace, buildSkillCatalogueResolver(resolveContribution, options.workspaceSkillRefreshTtlMs));
143
- }
144
+ tools,
145
+ };
146
+ }
147
+ /** Create a native Mastra {@link Workspace} from {@link databricksWorkspaceConfig}. */
148
+ export function databricksWorkspace(options = {}) {
149
+ const workspace = new Workspace(databricksWorkspaceConfig(options));
150
+ databricksWorkspaceOptions.set(workspace, options);
144
151
  return workspace;
145
152
  }
146
- /** Return the dbx-tools catalogue resolver attached to one workspace. */
147
- export function workspaceSkillCatalogueResolver(workspace) {
148
- return workspace ? workspaceCatalogueResolvers.get(workspace) : undefined;
153
+ /** @internal Bind a caller-created Databricks workspace to its AppKit plugin context. */
154
+ export function bindDatabricksWorkspaceContext(workspace, pluginContext) {
155
+ const options = databricksWorkspaceOptions.get(workspace);
156
+ if (!options || options.pluginContext !== undefined || pluginContext === undefined) {
157
+ return workspace;
158
+ }
159
+ return databricksWorkspace({ ...options, pluginContext });
149
160
  }
150
161
  /**
151
- * Merge the configured skill folders over {@link DEFAULT_SKILL_FOLDERS}.
152
- *
153
- * `assistantSkills: false` drops the defaults, and a `false` value removes one
154
- * entry by name.
162
+ * Resolve default and caller-provided Databricks paths in priority order.
155
163
  */
156
- export function resolveSkillFolders(options = {}) {
157
- const merged = options.assistantSkills === false ? {} : { ...DEFAULT_SKILL_FOLDERS };
158
- for (const [name, folder] of Object.entries(options.skillFolders ?? {})) {
159
- if (folder === false) {
160
- delete merged[name];
161
- }
162
- else {
163
- merged[name] = folder;
164
- }
165
- }
166
- return merged;
164
+ export function resolveDatabricksWorkspacePaths(options = {}) {
165
+ return [
166
+ ...(options.assistantPaths === false ? [] : DEFAULT_DATABRICKS_WORKSPACE_PATHS),
167
+ ...(options.paths ?? []),
168
+ ];
167
169
  }
168
170
  /* ---------------------------- private helpers ---------------------------- */
171
+ /** Require approval unless a filesystem mutation stays inside a user-owned writable root. */
172
+ function requireApprovalOutsideWritableRoots({ args, requestContext, }) {
173
+ const inputPath = args.path;
174
+ if (typeof inputPath !== "string" || !posixPath.isAbsolute(inputPath))
175
+ return true;
176
+ const normalized = posixPath.normalize(inputPath);
177
+ if (!normalized.ok)
178
+ return true;
179
+ if (posixPath.isWithinRoot(SCRATCH_MOUNT, normalized.path))
180
+ return false;
181
+ const emailValue = requestContext[MASTRA_USER_EMAIL_KEY];
182
+ const email = typeof emailValue === "string" ? stringUtils.trimToNull(emailValue) : undefined;
183
+ if (!email)
184
+ return true;
185
+ return !posixPath.isWithinRoot(personalWorkspacePath(email), normalized.path);
186
+ }
187
+ function workspaceTools(configured) {
188
+ const requireApproval = configured?.requireApproval === undefined
189
+ ? { requireApproval: requireApprovalOutsideWritableRoots }
190
+ : {};
191
+ const defaults = {
192
+ [WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: requireApproval,
193
+ [WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE]: requireApproval,
194
+ [WORKSPACE_TOOLS.FILESYSTEM.AST_EDIT]: requireApproval,
195
+ [WORKSPACE_TOOLS.FILESYSTEM.DELETE]: requireApproval,
196
+ [WORKSPACE_TOOLS.FILESYSTEM.MKDIR]: requireApproval,
197
+ };
198
+ const configuredTools = configured;
199
+ const mergedTools = Object.fromEntries(Object.entries(defaults).map(([name, defaultConfig]) => [
200
+ name,
201
+ { ...defaultConfig, ...configuredTools?.[name] },
202
+ ]));
203
+ return {
204
+ ...defaults,
205
+ ...configured,
206
+ ...mergedTools,
207
+ };
208
+ }
169
209
  function resolveWorkspaceSandbox(selection, workspaceId, workspaceName) {
170
210
  const configured = selection ?? "monty";
171
211
  if (configured === false)
@@ -224,45 +264,87 @@ function sandboxName(selection) {
224
264
  function hasWorkspaceFileScope(requestContext) {
225
265
  return token.includesAccessTokenScope(requestContext?.get(MASTRA_SCOPES_KEY), WORKSPACE_FILE_SCOPES);
226
266
  }
267
+ /** Resolve the request client and authorization-safe files-cache scope. */
268
+ async function resolveFilesCacheScope(context) {
269
+ const requestContext = context.requestContext;
270
+ const user = requestContext?.get(MASTRA_USER_KEY);
271
+ const client = user?.executionContext.client;
272
+ if (!requestContext || !user || !client)
273
+ return undefined;
274
+ return {
275
+ client,
276
+ scope: {
277
+ host: (await client.config.getHost()).toString(),
278
+ userKey: resolveUserKey(requestContext),
279
+ ...(process.env.DATABRICKS_WORKSPACE_ID?.trim()
280
+ ? { workspaceId: process.env.DATABRICKS_WORKSPACE_ID.trim() }
281
+ : {}),
282
+ },
283
+ };
284
+ }
285
+ /** Join one relative skill root to its actual composite mount path. */
286
+ function mountedSkillPath(mount, skillRoot) {
287
+ if (posixPath.isAbsolute(skillRoot)) {
288
+ throw new TypeError(`Skill path must be relative to its mount: ${skillRoot}`);
289
+ }
290
+ const normalized = posixPath.normalize(skillRoot);
291
+ if (!normalized.ok) {
292
+ throw new TypeError(`Skill path escapes its mount: ${skillRoot}`);
293
+ }
294
+ return posixPath.join(posixPath.normalizeRoot(mount), normalized.path.slice(1));
295
+ }
296
+ /** Return whether a Databricks path belongs to the writable Workspace namespace. */
297
+ function isWorkspaceRoot(root) {
298
+ const normalized = posixPath.normalizeRoot(root);
299
+ return normalized === "/Workspace" || normalized.startsWith("/Workspace/");
300
+ }
227
301
  /**
228
302
  * Mount resolver for the named skill folders.
229
303
  *
230
304
  * Gates on workspace file scope (or development mode), then mounts every
231
305
  * folder whose location resolves for this request.
232
306
  */
233
- async function resolveSkillFolderMounts(skillFolders, context) {
307
+ async function resolveSkillFolderMounts(paths, context, filesCache, cacheConfig) {
234
308
  const mounts = {};
235
- const skillSources = [];
236
309
  const skillPaths = [];
237
- const cacheKeys = [];
238
310
  const requestContext = context.requestContext;
239
- if (!requestContext || !shouldMountSkillFolders(requestContext)) {
240
- logger.debug("skill-folders:skipped", {
241
- reason: !requestContext ? "no-request-context" : "missing-workspace-scope",
242
- nodeEnv: process.env.NODE_ENV,
243
- scopes: requestContext?.get(MASTRA_SCOPES_KEY),
244
- });
245
- return { mounts, skillPaths };
246
- }
247
- const user = requestContext.get(MASTRA_USER_KEY);
248
- const client = user?.executionContext.client;
249
- const userKey = user ? resolveUserKey(requestContext) : undefined;
250
- const host = client ? (await client.config.getHost()).toString() : undefined;
251
- for (const [name, folder] of Object.entries(skillFolders)) {
252
- const resolved = await resolveSkillFolderFilesystem(name, folder, context, {
311
+ const canMountDatabricks = Boolean(requestContext && shouldMountSkillFolders(requestContext));
312
+ const scoped = canMountDatabricks ? await resolveFilesCacheScope(context) : undefined;
313
+ const client = scoped?.client;
314
+ const fileSystemCache = filesCache && scoped ? await filesCache.forScope(scoped.scope) : undefined;
315
+ for (const [index, path] of paths.entries()) {
316
+ const configured = await resolveDatabricksWorkspacePath(path, context);
317
+ if (!configured)
318
+ continue;
319
+ if (posixPath.isWithinRoot(SCRATCH_MOUNT, configured.path)) {
320
+ const mount = configured.mount ?? configured.path;
321
+ mounts[mount] = userTempFilesystem(context, configured.path);
322
+ if (configured.readable !== false) {
323
+ skillPaths.push(...(configured.skills ?? []).map((path) => mountedSkillPath(mount, path)));
324
+ }
325
+ continue;
326
+ }
327
+ if (!canMountDatabricks) {
328
+ logger.debug("workspace-path:skipped", {
329
+ path: configured.path,
330
+ reason: !requestContext ? "no-request-context" : "missing-workspace-scope",
331
+ });
332
+ continue;
333
+ }
334
+ const resolved = await resolveSkillFolderFilesystem(configured, context, cacheConfig, {
253
335
  client,
254
- host,
255
- userKey,
336
+ fileSystemCache,
256
337
  });
257
338
  if (!resolved)
258
339
  continue;
259
- const mount = folder.mount ?? `/${name}`;
340
+ const mount = configured.mount ?? resolved.root;
341
+ if (!mount) {
342
+ logger.debug("workspace-path:skipped", { index, reason: "missing-mount" });
343
+ continue;
344
+ }
260
345
  mounts[mount] = resolved.filesystem;
261
- if (resolved.cacheKey)
262
- cacheKeys.push(resolved.cacheKey);
263
- if (folder.readable !== false) {
264
- skillPaths.push(mount);
265
- skillSources.push({ ...resolved.skillSource, id: object.toStableKey({ mount, source: resolved.skillSource.id }) });
346
+ if (configured.readable !== false) {
347
+ skillPaths.push(...(configured.skills ?? ["."]).map((path) => mountedSkillPath(mount, path)));
266
348
  }
267
349
  }
268
350
  logger.debug("skill-folders:mounted", {
@@ -271,55 +353,122 @@ async function resolveSkillFolderMounts(skillFolders, context) {
271
353
  });
272
354
  return {
273
355
  mounts,
274
- skillSources,
275
356
  skillPaths,
276
- ...(cacheKeys.length === Object.keys(mounts).length && cacheKeys.length > 0
277
- ? { cacheKey: object.toStableKey(cacheKeys.sort()) }
278
- : {}),
357
+ };
358
+ }
359
+ async function resolveDatabricksWorkspacePath(value, context) {
360
+ const selected = typeof value === "function" ? await value(context) : value;
361
+ if (selected === false || selected === undefined)
362
+ return undefined;
363
+ const configured = typeof selected === "string" ? { path: selected } : selected;
364
+ const requestContext = requestContextValues(context.requestContext);
365
+ const resolvedPath = resolveHomePath(configured.path, requestContext);
366
+ if (!resolvedPath)
367
+ return undefined;
368
+ const resolvedMount = resolveHomePath(configured.mount, requestContext);
369
+ return {
370
+ ...configured,
371
+ path: resolvedPath,
372
+ ...(resolvedMount ? { mount: resolvedMount } : {}),
279
373
  };
280
374
  }
281
375
  /**
282
376
  * Resolve one skill folder to a Mastra filesystem, or `undefined` to skip it
283
377
  * for this request.
284
378
  */
285
- async function resolveSkillFolderFilesystem(name, folder, context, cache) {
286
- if (folder.filesystem !== undefined) {
287
- const filesystem = await resolveSkillFolderValue(folder.filesystem, context);
288
- return filesystem
289
- ? {
290
- filesystem,
291
- skillSource: mastraSkillSource(object.toStableKey({
292
- id: filesystem.id,
293
- name,
294
- provider: filesystem.provider,
295
- }), filesystem),
296
- }
297
- : undefined;
298
- }
379
+ async function resolveSkillFolderFilesystem(folder, context, cacheConfig, cache) {
299
380
  // A path mount needs the request's OBO client to reach the workspace.
300
- if (folder.path === undefined || !cache.client || !cache.host || !cache.userKey) {
381
+ if (!cache.client) {
301
382
  logger.debug("skill-folder:skipped", {
302
- name,
303
- reason: folder.path === undefined ? "no-location" : "missing-obo-client",
383
+ path: folder.path,
384
+ reason: "missing-obo-client",
304
385
  });
305
386
  return undefined;
306
387
  }
307
- const root = stringUtils.trimToNull(await resolveSkillFolderValue(folder.path, context));
388
+ const root = stringUtils.trimToNull(folder.path);
308
389
  if (!root)
309
390
  return undefined;
310
- return databricksFilesystem(cache.client, root, folder.writable !== true, {
311
- host: cache.host,
312
- userKey: cache.userKey,
391
+ const writable = folder.writable ?? isWorkspaceRoot(root);
392
+ const cacheOptions = cache.fileSystemCache
393
+ ? await resolveFileCacheOptions(cacheConfig, context, root, folder.readable === false ? [] : (folder.skills ?? ["."]))
394
+ : undefined;
395
+ const resolved = await databricksFilesystem(cache.client, root, !writable, folder.createRoot ?? folder.writable === true, cache.fileSystemCache, cacheOptions, {
396
+ ...(folder.description ? { description: folder.description } : {}),
397
+ ...(folder.displayName ? { displayName: folder.displayName } : {}),
313
398
  });
399
+ return resolved ? { ...resolved, root } : undefined;
314
400
  }
315
- /** Read a {@link SkillFolderValue}, calling it when it is a per-request resolver. */
316
- function resolveSkillFolderValue(value, context) {
401
+ async function resolveCacheConfig(value, context) {
317
402
  return typeof value === "function"
318
403
  ? value(context)
319
404
  : value;
320
405
  }
406
+ function requestContextValues(requestContext) {
407
+ return requestContext?.toJSON() ?? {};
408
+ }
409
+ function resolveHomePath(input, requestContext) {
410
+ const value = stringUtils.trimToNull(input);
411
+ if (!value || (value !== "~" && !value.startsWith("~/")))
412
+ return value ?? undefined;
413
+ const emailValue = requestContext[MASTRA_USER_EMAIL_KEY];
414
+ const email = typeof emailValue === "string" ? stringUtils.trimToNull(emailValue) : undefined;
415
+ if (!email)
416
+ return undefined;
417
+ const home = personalWorkspacePath(email);
418
+ return value === "~" ? home : `${home}/${value.slice(2)}`;
419
+ }
420
+ function toPolicyArray(value) {
421
+ if (value === undefined)
422
+ return [];
423
+ return Array.isArray(value) ? value : [value];
424
+ }
425
+ function cacheFilterMatches(policy, operation, path, requestContext, root) {
426
+ const operations = toPolicyArray(policy.operations ?? CACHEABLE_FILESYSTEM_OPERATIONS);
427
+ if (!operations.includes(operation))
428
+ return false;
429
+ if (policy.paths === undefined)
430
+ return true;
431
+ const inputs = [];
432
+ for (const input of toPolicyArray(policy.paths)) {
433
+ if (typeof input !== "string") {
434
+ inputs.push(input);
435
+ continue;
436
+ }
437
+ const expanded = resolveHomePath(input, requestContext);
438
+ if (!expanded)
439
+ continue;
440
+ inputs.push(!root || posixPath.isAbsolute(expanded) || expanded.startsWith("**")
441
+ ? expanded
442
+ : `${posixPath.normalizeRoot(root)}/${expanded.replace(/^\.\//, "")}`);
443
+ }
444
+ return inputs.length > 0 && match.toPathMatcher(...inputs)(path);
445
+ }
446
+ async function resolveFileCacheOptions(configured, context, root, skillPaths) {
447
+ const requestContext = requestContextValues(context.requestContext);
448
+ const resolved = await resolveCacheConfig(configured, context);
449
+ if (resolved === false)
450
+ return undefined;
451
+ if (resolved === undefined || resolved === true) {
452
+ const roots = skillPaths.map((path) => mountedSkillPath(root, path));
453
+ return {
454
+ operations: CACHEABLE_FILESYSTEM_OPERATIONS,
455
+ filter: (operation, path) => operation !== "readFile" ||
456
+ roots.some((skillRoot) => posixPath.isWithinRoot(skillRoot, path)),
457
+ };
458
+ }
459
+ const policies = toPolicyArray(resolved);
460
+ if (policies.length === 0)
461
+ return undefined;
462
+ const operations = [
463
+ ...new Set(policies.flatMap((policy) => toPolicyArray(policy.operations ?? CACHEABLE_FILESYSTEM_OPERATIONS))),
464
+ ];
465
+ return {
466
+ operations,
467
+ filter: (operation, path) => policies.some((policy) => cacheFilterMatches(policy, operation, path, requestContext, root)),
468
+ };
469
+ }
321
470
  /**
322
- * Fill in `id` and `name` when either is omitted on {@link CreateWorkspaceOptions}.
471
+ * Fill in `id` and `name` when either is omitted on {@link DatabricksWorkspaceOptions}.
323
472
  * Slugifies `name` into `id`; tokenizes `id` into a display `name`.
324
473
  */
325
474
  function resolveWorkspaceIdentity(options) {
@@ -334,26 +483,46 @@ function resolveWorkspaceIdentity(options) {
334
483
  return { id, name };
335
484
  }
336
485
  /** Collect the skill-folder resolver and any caller-supplied ones. */
337
- function buildMountResolvers(skillFolders, mounts) {
486
+ function buildMountResolvers(paths, mounts, localMounts, filesCache, cacheConfig) {
338
487
  const resolvers = [];
339
- const folderCount = Object.keys(skillFolders).length;
340
- if (folderCount > 0) {
341
- resolvers.push((context) => resolveSkillFolderMounts(skillFolders, context));
342
- }
343
- if (mounts?.length) {
344
- resolvers.push(...mounts);
488
+ const pathCount = paths.length;
489
+ if (pathCount > 0) {
490
+ resolvers.push((context) => resolveSkillFolderMounts(paths, context, filesCache, cacheConfig));
345
491
  }
492
+ if (mounts && Object.keys(mounts).length > 0)
493
+ resolvers.push(() => ({ mounts }));
494
+ resolvers.push(...localMounts);
346
495
  logger.debug("mounts:resolvers", {
347
- skillFolderCount: folderCount,
348
- customResolverCount: mounts?.length ?? 0,
496
+ pathCount,
497
+ customMountCount: Object.keys(mounts ?? {}).length,
498
+ localMountCount: localMounts.length,
349
499
  totalResolverCount: resolvers.length,
350
500
  });
351
501
  return resolvers;
352
502
  }
503
+ /** Stable user-scoped local storage under the host operating system's temp directory. */
504
+ function userTempFilesystem(context, workspacePath) {
505
+ const userKey = resolveUserKey(context.requestContext);
506
+ const digest = createHash("sha256")
507
+ .update(object.toStableKey({ package: "@dbx-tools/appkit-mastra", userKey }))
508
+ .digest("hex")
509
+ .slice(0, 16);
510
+ const normalized = posixPath.normalizeRoot(workspacePath);
511
+ const relative = normalized === SCRATCH_MOUNT ? "" : normalized.slice(`${SCRATCH_MOUNT}/`.length);
512
+ const source = new LocalFileSystem({
513
+ root: join(tmpdir(), "dbx-tools", "mastra", digest, relative),
514
+ readOnly: false,
515
+ createRoot: true,
516
+ });
517
+ return filesystems(source, {
518
+ displayName: "Temporary Files",
519
+ description: "User-scoped temporary files retained while the host keeps its ephemeral temp storage.",
520
+ });
521
+ }
353
522
  /** Mount startup-provisioned local skill roots into Mastra's workspace filesystem. */
354
523
  function localSkillMountResolvers(paths) {
355
- return [...new Set(paths.map((path) => path.trim()).filter(Boolean))].map((root, index) => {
356
- const mount = `/remote-skills/${index}`;
524
+ return [...new Set(paths.map((path) => path.trim()).filter(Boolean))].map((root) => {
525
+ const mount = posixPath.normalizeRoot(root);
357
526
  const source = new LocalFileSystem({
358
527
  root,
359
528
  readOnly: true,
@@ -362,46 +531,10 @@ function localSkillMountResolvers(paths) {
362
531
  const filesystem = filesystems(source, { readOnly: true });
363
532
  return () => ({
364
533
  mounts: { [mount]: filesystem },
365
- skillSources: [sharedSkillSource(object.toStableKey({ mount, root }), source)],
366
534
  skillPaths: [mount],
367
- cacheKey: object.toStableKey({ mount, root }),
368
535
  });
369
536
  });
370
537
  }
371
- /** Adapt a portable dbx-tools filesystem to catalogue discovery callbacks. */
372
- function sharedSkillSource(id, filesystem) {
373
- return {
374
- id,
375
- async list(path) {
376
- await filesystem.init();
377
- return (await filesystem.readdir(path)).flatMap((entry) => entry.type === "file" || entry.type === "directory"
378
- ? [
379
- {
380
- name: entry.name,
381
- type: entry.type,
382
- ...(entry.size !== undefined ? { size: entry.size } : {}),
383
- ...(entry.metadata ? { metadata: entry.metadata } : {}),
384
- },
385
- ]
386
- : []);
387
- },
388
- async read(path) {
389
- await filesystem.init();
390
- return filesystem.readFile(path, { encoding: "utf8" });
391
- },
392
- };
393
- }
394
- /** Adapt an arbitrary Mastra filesystem when no portable source is available. */
395
- function mastraSkillSource(id, filesystem) {
396
- return {
397
- id,
398
- list: (path) => filesystem.readdir(path),
399
- async read(path) {
400
- const value = await filesystem.readFile(path, { encoding: "utf8" });
401
- return typeof value === "string" ? value : value.toString("utf8");
402
- },
403
- };
404
- }
405
538
  /**
406
539
  * Gate skill-folder mounts on the request's token.
407
540
  *
@@ -413,41 +546,37 @@ function shouldMountSkillFolders(requestContext) {
413
546
  return true;
414
547
  return hasWorkspaceFileScope(requestContext);
415
548
  }
416
- /** Read the trimmed OBO user email stamped on {@link MASTRA_USER_EMAIL_KEY}. */
417
- function resolveScopedEmail(requestContext) {
418
- return stringUtils.trimToNull(requestContext?.get(MASTRA_USER_EMAIL_KEY)) ?? undefined;
419
- }
420
549
  /**
421
- * Wrap a {@link DatabricksFileSystem} as a Mastra filesystem. When the root is
422
- * missing (and {@link readOnly} so we will not create it), fall back to
423
- * {@link scratchFilesystem} so skill scans still have a writable local mount.
550
+ * Wrap a {@link DatabricksFileSystem} as a Mastra filesystem. Missing or
551
+ * inaccessible roots return `undefined` so other accessible roots remain
552
+ * usable.
424
553
  */
425
- async function databricksFilesystem(client, root, readOnly = true, cache) {
554
+ async function databricksFilesystem(client, root, readOnly = true, createRoot = !readOnly, fileSystemCache, cacheOptions, adapterOptions = {}) {
555
+ const initialClient = workspaceClient.toLegacyWorkspaceClient(client);
426
556
  const fs = new DatabricksFileSystem({
427
- client: workspaceClient.toLegacyWorkspaceClient(client),
557
+ client: () => {
558
+ try {
559
+ return workspaceClient.toLegacyWorkspaceClient(getExecutionContext().client);
560
+ }
561
+ catch {
562
+ return initialClient;
563
+ }
564
+ },
428
565
  root,
429
566
  readOnly,
430
- createRoot: !readOnly,
431
- });
432
- const cacheKey = object.toStableKey({
433
- host: cache.host,
434
- readOnly,
435
- root,
436
- userKey: cache.userKey,
567
+ createRoot,
437
568
  });
438
- const filesystem = filesystems(fs, { readOnly });
569
+ const cached = fileSystemCache && cacheOptions ? sharedFS.cache(fs, fileSystemCache, cacheOptions) : fs;
570
+ const source = verifyFirstFileSystemAccess(cached, () => fs.stat("."), root);
571
+ const filesystem = filesystems(source, { ...adapterOptions, readOnly });
439
572
  try {
440
573
  await filesystem.init();
441
574
  if (await filesystem.exists(".")) {
442
- return {
443
- cacheKey,
444
- filesystem,
445
- skillSource: sharedSkillSource(cacheKey, fs),
446
- };
575
+ return { filesystem };
447
576
  }
448
577
  }
449
578
  catch (err) {
450
- logger.debug("databricks-mount:scratch-fallback", {
579
+ logger.debug("databricks-mount:skipped", {
451
580
  root,
452
581
  readOnly,
453
582
  error: errorUtils.errorMessage(err),
@@ -455,16 +584,82 @@ async function databricksFilesystem(client, root, readOnly = true, cache) {
455
584
  }
456
585
  return undefined;
457
586
  }
587
+ function verifyFirstFileSystemAccess(filesystem, readProbe, root) {
588
+ let readCheck;
589
+ let writeVerified = false;
590
+ const boundMethods = new Map();
591
+ const readOperations = new Set(["exists", "readFile", "readdir", "stat"]);
592
+ const writeOperations = new Set([
593
+ "appendFile",
594
+ "copyFile",
595
+ "deleteFile",
596
+ "mkdir",
597
+ "moveFile",
598
+ "rmdir",
599
+ "writeFile",
600
+ ]);
601
+ const verifyRead = async () => {
602
+ readCheck ??= Promise.resolve(readProbe()).then(() => undefined);
603
+ try {
604
+ await readCheck;
605
+ }
606
+ catch (error) {
607
+ readCheck = undefined;
608
+ logger.debug("databricks-mount:read-check-failed", {
609
+ root,
610
+ error: errorUtils.errorMessage(error),
611
+ });
612
+ throw error;
613
+ }
614
+ };
615
+ return new Proxy(filesystem, {
616
+ get(target, property) {
617
+ const value = Reflect.get(target, property, target);
618
+ if (typeof value !== "function")
619
+ return value;
620
+ if (boundMethods.has(property))
621
+ return boundMethods.get(property);
622
+ const delegated = value.bind(target);
623
+ let method = delegated;
624
+ if (readOperations.has(property)) {
625
+ method = async (...args) => {
626
+ await verifyRead();
627
+ return delegated(...args);
628
+ };
629
+ }
630
+ else if (writeOperations.has(property)) {
631
+ method = async (...args) => {
632
+ try {
633
+ const result = await delegated(...args);
634
+ if (!writeVerified) {
635
+ writeVerified = true;
636
+ logger.debug("databricks-mount:write-check-passed", { root });
637
+ }
638
+ return result;
639
+ }
640
+ catch (error) {
641
+ if (!writeVerified) {
642
+ logger.debug("databricks-mount:write-check-failed", {
643
+ root,
644
+ error: errorUtils.errorMessage(error),
645
+ });
646
+ }
647
+ throw error;
648
+ }
649
+ };
650
+ }
651
+ boundMethods.set(property, method);
652
+ return method;
653
+ },
654
+ });
655
+ }
458
656
  /**
459
657
  * Run every mount resolver for one request and merge mounts plus skill paths.
460
658
  * Later resolvers overwrite mount keys from earlier ones.
461
659
  */
462
660
  async function resolveWorkspaceContribution(resolvers, context) {
463
661
  const mounts = {};
464
- const skillSources = [];
465
662
  const skillPaths = [];
466
- const cacheKeys = [];
467
- let cacheable = true;
468
663
  for (const [index, resolver] of resolvers.entries()) {
469
664
  const contribution = await resolver(context);
470
665
  logger.debug("mounts:resolver", {
@@ -473,18 +668,9 @@ async function resolveWorkspaceContribution(resolvers, context) {
473
668
  skillPaths: contribution.skillPaths ?? [],
474
669
  });
475
670
  Object.assign(mounts, contribution.mounts);
476
- if (Object.keys(contribution.mounts).length > 0) {
477
- if (contribution.cacheKey)
478
- cacheKeys.push(contribution.cacheKey);
479
- else
480
- cacheable = false;
481
- }
482
671
  if (contribution.skillPaths?.length) {
483
672
  skillPaths.push(...contribution.skillPaths);
484
673
  }
485
- if (contribution.skillSources?.length) {
486
- skillSources.push(...contribution.skillSources);
487
- }
488
674
  }
489
675
  logger.debug("mounts:merged", {
490
676
  mountKeys: Object.keys(mounts),
@@ -492,37 +678,65 @@ async function resolveWorkspaceContribution(resolvers, context) {
492
678
  });
493
679
  return {
494
680
  mounts,
495
- skillSources,
496
681
  skillPaths,
497
- ...(cacheable && cacheKeys.length > 0
498
- ? { cacheKey: object.toStableKey({ mounts: Object.keys(mounts), sources: cacheKeys }) }
499
- : {}),
500
682
  };
501
683
  }
502
684
  /**
503
685
  * Dynamic filesystem resolver passed to Mastra {@link Workspace}.
504
686
  *
505
- * Returns a {@link CompositeFilesystem} when any mount resolved; otherwise a
506
- * fresh {@link scratchFilesystem} so Mastra always has a writable local root.
687
+ * Returns a {@link CompositeFilesystem} over every path that resolved for the
688
+ * request. An empty composite exposes no implicit local storage.
507
689
  */
508
- async function resolveWorkspaceFilesystem(resolveContribution, context) {
509
- const { cacheKey, mounts } = await resolveContribution(context);
690
+ async function resolveWorkspaceFilesystem(resolveContribution, context, filesCache, sourceKey) {
691
+ const { mounts } = await resolveContribution(context);
510
692
  const mountKeys = Object.keys(mounts);
511
693
  if (mountKeys.length === 0) {
512
- logger.debug("filesystem:scratch", {
694
+ logger.debug("filesystem:empty", {
513
695
  hasRequestContext: Boolean(context.requestContext),
514
696
  });
515
- return scratchFilesystem();
697
+ return filesystems(new MemoryFileSystem({ root: "/", readOnly: true }), {
698
+ readOnly: true,
699
+ });
516
700
  }
517
701
  logger.debug("filesystem:composite", { mountKeys });
518
- if (!cacheKey)
519
- return new CompositeFilesystem({ mounts });
520
- const existing = scopedWorkspaceFilesystems.get(cacheKey);
521
- if (existing)
522
- return existing;
523
- const filesystem = new CompositeFilesystem({ mounts });
524
- scopedWorkspaceFilesystems.set(cacheKey, filesystem);
525
- return filesystem;
702
+ const load = () => new MountedCompositeFilesystem({ mounts });
703
+ if (!filesCache)
704
+ return load();
705
+ const scoped = await resolveFilesCacheScope(context);
706
+ if (!scoped)
707
+ return load();
708
+ return filesCache.forFileSystem(scoped.scope, { paths: mountKeys, key: sourceKey }, load);
709
+ }
710
+ /**
711
+ * Expand skill roots into concrete skill directories and keep the first
712
+ * same-named directory. Mastra still owns parsing, indexing, and refreshes,
713
+ * while earlier configured roots retain precedence over later roots.
714
+ */
715
+ async function resolveDistinctSkillPaths(filesystem, roots) {
716
+ const selected = new Map();
717
+ for (const root of roots) {
718
+ try {
719
+ const entries = await filesystem.readdir(root);
720
+ if (entries.some((entry) => entry.type === "file" && entry.name === "SKILL.md")) {
721
+ const name = posixPath.basename(root);
722
+ if (!selected.has(name))
723
+ selected.set(name, root);
724
+ continue;
725
+ }
726
+ for (const entry of entries) {
727
+ if (entry.type !== "directory" || selected.has(entry.name))
728
+ continue;
729
+ selected.set(entry.name, posixPath.join(root, entry.name));
730
+ }
731
+ }
732
+ catch (error) {
733
+ logger.debug("skill-root:skipped", {
734
+ root,
735
+ error: errorUtils.errorMessage(error),
736
+ });
737
+ }
738
+ }
739
+ return [...selected.values()];
526
740
  }
527
741
  /** Memoize one complete mount contribution for each request context. */
528
742
  function contributionResolver(resolvers) {
@@ -541,19 +755,4 @@ function contributionResolver(resolvers) {
541
755
  return pending;
542
756
  };
543
757
  }
544
- /** Resolve one semantic catalogue owner from a request's ordered skill roots. */
545
- function buildSkillCatalogueResolver(resolveContribution, ttlMs) {
546
- return async ({ requestContext }) => {
547
- const contribution = await resolveContribution({ requestContext });
548
- const user = requestContext?.get(MASTRA_USER_KEY);
549
- const client = user?.executionContext.client;
550
- const host = client ? (await client.config.getHost()).toString() : "local";
551
- return workspaceSkillCatalogue({
552
- host,
553
- sources: contribution.skillSources ?? [],
554
- ttlMs,
555
- userKey: user?.id ?? "service",
556
- });
557
- };
558
- }
559
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3Jrc3BhY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRS9FLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFckYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVyQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLFNBQVMsR0FLVixNQUFNLHdCQUF3QixDQUFDO0FBRWhDLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIscUJBQXFCLEVBQ3JCLGVBQWUsRUFDZixjQUFjLEdBRWYsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsaUJBQWlCLEVBQTBDLE1BQU0sY0FBYyxDQUFDO0FBQ3pGLE9BQU8sRUFDTCxvQ0FBb0MsRUFDcEMsdUJBQXVCLEdBR3hCLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLDRCQUE0QixFQUFFLHVCQUF1QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFekYsNkVBQTZFO0FBRTdFLCtEQUErRDtBQUMvRCxNQUFNLHFCQUFxQixHQUFHLENB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LEdBQUcsSUFBSSxFQUFFLGdCQUFnQixDQUFDLE1BQXFDLENBQUM7UUFDNUUsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDM0UsT0FBTyx1QkFBdUIsQ0FBQztZQUM3QixJQUFJO1lBQ0osT0FBTyxFQUFFLFlBQVksQ0FBQyxZQUFZLElBQUksRUFBRTtZQUN4QyxLQUFLO1lBQ0wsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFFLElBQUksU0FBUztTQUMvQixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNYXN0cmEgd29ya3NwYWNlIGZhY3RvcnkgZm9yIERhdGFicmlja3MgQXBwcy5cbiAqXG4gKiBCdWlsZHMgYSBwZXItcmVxdWVzdCB7QGxpbmsgV29ya3NwYWNlfSB3aXRoIERhdGFicmlja3MgU2FuZGJveCBjb21tYW5kXG4gKiBleGVjdXRpb24gcGx1cyBhIHtAbGluayBDb21wb3NpdGVGaWxlc3lzdGVtfSBvdmVyIHRoZSBOQU1FRCBza2lsbCBmb2xkZXJzXG4gKiByZXNvbHZlZCBmb3IgdGhhdCByZXF1ZXN0LiBBIHNraWxsIGZvbGRlciBtYXBzIGEgbmFtZSB0byBhIGxvY2F0aW9uIHBsdXMgaXRzXG4gKiByZWFkYWJsZSAvIHdyaXRhYmxlIHBvbGljeTogYSBEYXRhYnJpY2tzIHBhdGggbW91bnRlZCB0aHJvdWdoIHRoZSBPQk8gY2xpZW50XG4gKiBvbiB7QGxpbmsgTUFTVFJBX1VTRVJfS0VZfSwgb3IgYW55IHtAbGluayBXb3Jrc3BhY2VGaWxlc3lzdGVtfSBhIGNvbnN1bWluZ1xuICogbGlicmFyeSBhbHJlYWR5IG93bnMuIHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9IHN1cHBsaWVzIHRoZSBBc3Npc3RhbnRcbiAqIHRyZWVzLCBhbmQgYHNraWxsRm9sZGVyc2AgbWVyZ2VzIG92ZXIgaXQgLSBzYW1lIG5hbWUgb3ZlcnJpZGVzLCBgZmFsc2VgXG4gKiBkaXNhYmxlcywgYSBuZXcgbmFtZSBhZGRzLiBPcHRpb25hbCBtb3VudCByZXNvbHZlcnMgY29udHJpYnV0ZSBmdXJ0aGVyXG4gKiBmaWxlc3lzdGVtcyBhbmQgc2tpbGwgc2NhbiByb290cyBvbiB0b3AuXG4gKlxuICogRGF0YWJyaWNrcyBtb3VudHMgdXNlIGBAZGJ4LXRvb2xzL2RhdGFicmlja3NgIHtAbGluayBEYXRhYnJpY2tzRmlsZVN5c3RlbX1cbiAqIHdyYXBwZWQgYnkge0BsaW5rIGZpbGVzeXN0ZW1zfTsgbWlzc2luZyByb290cyBmYWxsIGJhY2sgdG9cbiAqIHtAbGluayBzY3JhdGNoRmlsZXN5c3RlbX0uXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcbmltcG9ydCB7IENvbmZpZ3VyYXRpb25FcnJvciwgY3JlYXRlV29ya3NwYWNlQ2xpZW50IH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzRmlsZVN5c3RlbSwgd29ya3NwYWNlQ2xpZW50IH0gZnJvbSBcIkBkYngtdG9vbHMvZGF0YWJyaWNrc1wiO1xuaW1wb3J0IHsgTG9jYWxGaWxlU3lzdGVtIH0gZnJvbSBcIkBkYngtdG9vbHMvZnNcIjtcbmltcG9ydCB7IGVycm9yVXRpbHMsIGxvZywgb2JqZWN0LCBzdHJpbmdVdGlscywgdG9rZW4gfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBGaWxlU3lzdGVtIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWZzXCI7XG5pbXBvcnQgeyBMUlVDYWNoZSB9IGZyb20gXCJscnUtY2FjaGVcIjtcbmltcG9ydCB0eXBlIHsgUmVxdWVzdENvbnRleHQgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL3JlcXVlc3QtY29udGV4dFwiO1xuaW1wb3J0IHtcbiAgQ29tcG9zaXRlRmlsZXN5c3RlbSxcbiAgV29ya3NwYWNlLFxuICB0eXBlIFNraWxsc1Jlc29sdmVyLFxuICB0eXBlIFdvcmtzcGFjZUZpbGVzeXN0ZW0sXG4gIHR5cGUgV29ya3NwYWNlU2FuZGJveCxcbiAgdHlwZSBXb3Jrc3BhY2VTYW5kYm94UmVzb2x2ZXIsXG59IGZyb20gXCJAbWFzdHJhL2NvcmUvd29ya3NwYWNlXCI7XG5cbmltcG9ydCB7XG4gIE1BU1RSQV9TQ09QRVNfS0VZLFxuICBNQVNUUkFfVVNFUl9FTUFJTF9LRVksXG4gIE1BU1RSQV9VU0VSX0tFWSxcbiAgcmVzb2x2ZVVzZXJLZXksXG4gIHR5cGUgVXNlcixcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBmaWxlc3lzdGVtcywgc2NyYXRjaEZpbGVzeXN0ZW0gfSBmcm9tIFwiLi9maWxlc3lzdGVtcy50c1wiO1xuaW1wb3J0IHsgTW9udHlTYW5kYm94IH0gZnJvbSBcIi4vbW9udHktc2FuZGJveC50c1wiO1xuaW1wb3J0IHsgRGF0YWJyaWNrc1NhbmRib3gsIHR5cGUgRGF0YWJyaWNrc1dvcmtzcGFjZVNhbmRib3hPcHRpb25zIH0gZnJvbSBcIi4vc2FuZGJveC50c1wiO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9XT1JLU1BBQ0VfU0tJTExfQ0FDSEVfVFRMX01TLFxuICB3b3Jrc3BhY2VTa2lsbENhdGFsb2d1ZSxcbiAgdHlwZSBTa2lsbENhdGFsb2d1ZVJlc29sdmVyLFxuICB0eXBlIFNraWxsQ2F0YWxvZ3VlU291cmNlLFxufSBmcm9tIFwiLi9za2lsbC1jYWNoZS50c1wiO1xuaW1wb3J0IHsgQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSCwgdXNlckFzc2lzdGFudFNraWxsc1BhdGggfSBmcm9tIFwiLi9za2lsbC1wYXRocy50c1wiO1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogT0F1dGggc2NvcGVzIHRoYXQgZ2F0ZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBmaWxlIG1vdW50cy4gKi9cbmNvbnN0IFdPUktTUEFDRV9GSUxFX1NDT1BFUyA9IFtcIndvcmtzcGFjZVwiLCBcIndvcmtzcGFjZS53b3Jrc3BhY2VcIiwgXCJhbGwtYXBpc1wiXSBhcyBjb25zdDtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1hc3RyYS93b3Jrc3BhY2VzXCIpO1xuY29uc3QgTUFYX1NDT1BFRF9XT1JLU1BBQ0VfRklMRVNZU1RFTVMgPSAxNjtcbmNvbnN0IHNjb3BlZFdvcmtzcGFjZUZpbGVzeXN0ZW1zID0gbmV3IExSVUNhY2hlPHN0cmluZywgV29ya3NwYWNlRmlsZXN5c3RlbT4oe1xuICBtYXg6IE1BWF9TQ09QRURfV09SS1NQQUNFX0ZJTEVTWVNURU1TLFxufSk7XG5jb25zdCB3b3Jrc3BhY2VDYXRhbG9ndWVSZXNvbHZlcnMgPSBuZXcgV2Vha01hcDxXb3Jrc3BhY2UsIFNraWxsQ2F0YWxvZ3VlUmVzb2x2ZXI+KCk7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBQZXItcmVxdWVzdCBjb250ZXh0IGZvciBtb3VudCBhbmQgc2tpbGwtZm9sZGVyIHJlc29sdmVycy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV29ya3NwYWNlTW91bnRDb250ZXh0IHtcbiAgcmVxdWVzdENvbnRleHQ/OiBSZXF1ZXN0Q29udGV4dDtcbn1cblxuLyoqXG4gKiBBIHNraWxsLWZvbGRlciBmaWVsZCBnaXZlbiBlaXRoZXIgZGlyZWN0bHkgb3IgYXMgYSBwZXItcmVxdWVzdCByZXNvbHZlci5cbiAqIEEgcmVzb2x2ZXIgcmV0dXJuaW5nIGB1bmRlZmluZWRgIHNraXBzIHRoZSBmb2xkZXIgZm9yIHRoYXQgcmVxdWVzdC5cbiAqL1xuZXhwb3J0IHR5cGUgU2tpbGxGb2xkZXJWYWx1ZTxUPiA9XG4gIFQgfCAoKGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCkgPT4gVCB8IHVuZGVmaW5lZCB8IFByb21pc2U8VCB8IHVuZGVmaW5lZD4pO1xuXG4vKipcbiAqIE9uZSBuYW1lZCBza2lsbC1mb2xkZXIgbG9jYXRpb24gYW5kIGl0cyByZWFkIC8gd3JpdGUgcG9saWN5LlxuICpcbiAqIEdpdmUge0BsaW5rIHBhdGh9IGZvciBhIERhdGFicmlja3Mgd29ya3NwYWNlIHRyZWUgKG1vdW50ZWQgdGhyb3VnaCB0aGVcbiAqIHJlcXVlc3QncyBPQk8gY2xpZW50KSwgb3Ige0BsaW5rIGZpbGVzeXN0ZW19IGZvciBhIG1vdW50IHRoZSBjb25zdW1lciBidWlsZHNcbiAqIGl0c2VsZi4ge0BsaW5rIGZpbGVzeXN0ZW19IHdpbnMgd2hlbiBib3RoIGFyZSBzZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2tpbGxGb2xkZXJPcHRpb25zIHtcbiAgLyoqIEFic29sdXRlIERhdGFicmlja3Mgd29ya3NwYWNlIHBhdGggZm9yIHRoaXMgZm9sZGVyLiAqL1xuICBwYXRoPzogU2tpbGxGb2xkZXJWYWx1ZTxzdHJpbmc+O1xuICAvKiogUmVhZHktbWFkZSBtb3VudCwgZm9yIGxvY2F0aW9ucyB0aGUgT0JPIGNsaWVudCBjYW5ub3QgcmVhY2guICovXG4gIGZpbGVzeXN0ZW0/OiBTa2lsbEZvbGRlclZhbHVlPFdvcmtzcGFjZUZpbGVzeXN0ZW0+O1xuICAvKipcbiAgICogU2NhbiB0aGlzIG1vdW50IGZvciBgU0tJTEwubWRgIGZpbGVzLiBEZWZhdWx0cyB0byBgdHJ1ZWA7IGBmYWxzZWAgbW91bnRzXG4gICAqIHRoZSBsb2NhdGlvbiBmb3IgZmlsZSB0b29scyB3aXRob3V0IGFkZGluZyBpdCB0byBza2lsbCBkaXNjb3ZlcnkuXG4gICAqL1xuICByZWFkYWJsZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBbGxvdyB3cml0ZXMgdG8gYSB7QGxpbmsgcGF0aH0gbW91bnQgKGFuZCBjcmVhdGUgdGhlIHJvb3Qgd2hlbiBtaXNzaW5nKS5cbiAgICogRGVmYXVsdHMgdG8gYGZhbHNlYC4gQSBzdXBwbGllZCB7QGxpbmsgZmlsZXN5c3RlbX0gY2FycmllcyBpdHMgb3duXG4gICAqIHJlYWQtb25seSBmbGFnIGluc3RlYWQuXG4gICAqL1xuICB3cml0YWJsZT86IGJvb2xlYW47XG4gIC8qKiBNb3VudCBwb2ludCBpbiB0aGUgY29tcG9zaXRlIG5hbWVzcGFjZS4gRGVmYXVsdHMgdG8gYC88bmFtZT5gLiAqL1xuICBtb3VudD86IHN0cmluZztcbn1cblxuLyoqIE1vdW50IG1hcCBwbHVzIG9wdGlvbmFsIE1hc3RyYSBza2lsbCBzY2FuIHJvb3RzIGZvciBvbmUgcmVzb2x2ZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHtcbiAgbW91bnRzOiBSZWNvcmQ8c3RyaW5nLCBXb3Jrc3BhY2VGaWxlc3lzdGVtPjtcbiAgLyoqIE9yZGVyZWQgc291cmNlIHJvb3RzIGluY2x1ZGVkIGluIGNhdGFsb2d1ZSBkaXNjb3ZlcnkuICovXG4gIHNraWxsU291cmNlcz86IFNraWxsQ2F0YWxvZ3VlU291cmNlW107XG4gIC8qKiBQYXRocyB3aXRoaW4gdGhlIGNvbXBvc2l0ZSBuYW1lc3BhY2Ugd2hlcmUgYFNLSUxMLm1kYCBmaWxlcyBhcmUgc2Nhbm5lZC4gKi9cbiAgc2tpbGxQYXRocz86IHN0cmluZ1tdO1xuICAvKipcbiAgICogU3RhYmxlIGlkZW50aXR5IGZvciB0aGlzIGNvbnRyaWJ1dGlvbi4gV2hlbiBldmVyeSBub24tZW1wdHkgY29udHJpYnV0aW9uXG4gICAqIHN1cHBsaWVzIG9uZSwgTWFzdHJhIHJldXNlcyB0aGUgcmVzb2x2ZWQgc291cmNlIGFjcm9zcyByZXF1ZXN0cy5cbiAgICovXG4gIGNhY2hlS2V5Pzogc3RyaW5nO1xufVxuXG4vKiogQ29udHJpYnV0ZXMgZmlsZXN5c3RlbSBtb3VudHMgKGFuZCBvcHRpb25hbCBza2lsbCBwYXRocykgZm9yIG9uZSByZXF1ZXN0LiAqL1xuZXhwb3J0IHR5cGUgV29ya3NwYWNlTW91bnRSZXNvbHZlciA9IChcbiAgY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0LFxuKSA9PiBXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbiB8IFByb21pc2U8V29ya3NwYWNlTW91bnRDb250cmlidXRpb24+O1xuXG4vKiogTmFtZXMgY2FycmllZCBieSB7QGxpbmsgREVGQVVMVF9TS0lMTF9GT0xERVJTfS4gKi9cbmV4cG9ydCB0eXBlIERlZmF1bHRTa2lsbEZvbGRlck5hbWUgPSBcIndvcmtzcGFjZS10ZWFtXCIgfCBcIndvcmtzcGFjZS10ZWFtLWFwcFwiO1xuXG4vKipcbiAqIFNhbmRib3ggc2VsZWN0aW9uIGZvciB7QGxpbmsgY3JlYXRlV29ya3NwYWNlfS4gRGF0YWJyaWNrcyBpcyB0aGUgZGVmYXVsdDtcbiAqIGBmYWxzZWAgZGlzYWJsZXMgY29tbWFuZCBleGVjdXRpb24sIGFuZCBhIE1hc3RyYSBwcm92aWRlciBvciByZXNvbHZlciBpcyBhblxuICogZXhwbGljaXQgcmVwbGFjZW1lbnQuXG4gKi9cbmV4cG9ydCB0eXBlIFdvcmtzcGFjZVNhbmRib3hTZWxlY3Rpb24gPVxuICB8IGZhbHNlXG4gIHwgXCJkYXRhYnJpY2tzXCJcbiAgfCBcIm1vbnR5XCJcbiAgfCBEYXRhYnJpY2tzV29ya3NwYWNlU2FuZGJveE9wdGlvbnNcbiAgfCBXb3Jrc3BhY2VTYW5kYm94XG4gIHwgV29ya3NwYWNlU2FuZGJveFJlc29sdmVyO1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIGNyZWF0ZVdvcmtzcGFjZX0uICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZVdvcmtzcGFjZU9wdGlvbnMge1xuICAvKiogV29ya3NwYWNlIGlkOyBkZXJpdmVkIGZyb20gYG5hbWVgIG9yIGBcIndvcmtzcGFjZVwiYCB3aGVuIG9taXR0ZWQuICovXG4gIGlkPzogc3RyaW5nO1xuICAvKiogRGlzcGxheSBuYW1lOyBkZXJpdmVkIGZyb20gYGlkYCB3aGVuIG9taXR0ZWQuICovXG4gIG5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTdGFydCBmcm9tIHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9LiBEZWZhdWx0cyB0byBgdHJ1ZWA7IGBmYWxzZWBcbiAgICogc3RhcnRzIGZyb20gYW4gZW1wdHkgbWFwLCBsZWF2aW5nIG9ubHkgdGhlIHtAbGluayBza2lsbEZvbGRlcnN9IGdpdmVuIGhlcmUuXG4gICAqL1xuICBhc3Npc3RhbnRTa2lsbHM/OiBib29sZWFuO1xuICAvKipcbiAgICogTmFtZWQgc2tpbGwgZm9sZGVycyBtZXJnZWQgb3ZlciB7QGxpbmsgREVGQVVMVF9TS0lMTF9GT0xERVJTfTogYSBtYXRjaGluZ1xuICAgKiBuYW1lIG92ZXJyaWRlcyB0aGF0IGRlZmF1bHQsIGBmYWxzZWAgZGlzYWJsZXMgaXQsIGFuZCBhbnkgb3RoZXIgbmFtZSBhZGRzXG4gICAqIGEgZm9sZGVyLlxuICAgKi9cbiAgc2tpbGxGb2xkZXJzPzogUmVjb3JkPHN0cmluZywgU2tpbGxGb2xkZXJPcHRpb25zIHwgZmFsc2U+O1xuICAvKiogRXh0cmEgcGVyLXJlcXVlc3QgbW91bnQgcmVzb2x2ZXJzIChydW4gYWZ0ZXIgdGhlIHNraWxsLWZvbGRlciBtb3VudHMpLiAqL1xuICBtb3VudHM/OiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW107XG4gIC8qKiBSZXBsYWNlIHRoZSBhdXRvLWJ1aWx0IGR5bmFtaWMgc2tpbGxzIHJlc29sdmVyLiAqL1xuICBza2lsbHM/OiBTa2lsbHNSZXNvbHZlcjtcbiAgLyoqIEZvcndhcmRlZCB0byBNYXN0cmEgd2hlbiBza2lsbCBkaXNjb3ZlcnkgaXMgZW5hYmxlZC4gKi9cbiAgY2hlY2tTa2lsbEZpbGVNdGltZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBSZWZyZXNoIFRUTCBmb3IgdGhlIGNvbXBsZXRlIHBhcnNlZCBza2lsbCBjYXRhbG9ndWUuIEF1eGlsaWFyeSByZWFkcyBhcmVcbiAgICogYWx3YXlzIGZyZXNoLiBEZWZhdWx0cyB0byBmaXZlIG1pbnV0ZXMuXG4gICAqL1xuICB3b3Jrc3BhY2VTa2lsbFJlZnJlc2hUdGxNcz86IG51bWJlcjtcbiAgLyoqIEVuYWJsZSBCTTI1IGtleXdvcmQgc2VhcmNoIG92ZXIgaW5kZXhlZCB3b3Jrc3BhY2UgY29udGVudC4gKi9cbiAgYm0yNT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDb21tYW5kIHNhbmRib3guIERlZmF1bHRzIHRvIE1vbnR5LiBQYXNzIGBcImRhdGFicmlja3NcImAgb3IgYW4gb3B0aW9uc1xuICAgKiBvYmplY3QgZm9yIERhdGFicmlja3MgU2FuZGJveCwgYGZhbHNlYCB0byBkaXNhYmxlIGNvbW1hbmQgZXhlY3V0aW9uLCBvciBhblxuICAgKiBleHBsaWNpdCBNYXN0cmEgc2FuZGJveC9wcm92aWRlciByZXNvbHZlci5cbiAgICovXG4gIHNhbmRib3g/OiBXb3Jrc3BhY2VTYW5kYm94U2VsZWN0aW9uO1xuICAvKipcbiAgICogRXh0cmEgTE9DQUwgc2tpbGwgcm9vdHMgbW91bnRlZCByZWFkLW9ubHkgZm9yIGV2ZXJ5IHJlcXVlc3QncyBza2lsbCBkaXNjb3ZlcnkuXG4gICAqIFVzZWQgYnkgdGhlIHBsdWdpbiB0byBzdXJmYWNlIHJlbW90ZSBza2lsbHMgcHJvdmlzaW9uZWQgdG8gYSBsb2NhbCB0ZW1wXG4gICAqIGRpciBhdCBzdGFydHVwIChzZWUgYHJlbW90ZS1za2lsbHMudHNgKS4gRGF0YWJyaWNrcy1ob3N0ZWQgcmVtb3RlIHNraWxsc1xuICAgKiBuZWVkIG5vIGVudHJ5IGhlcmUgLSB0aGV5IGxhbmQgaW4gdGhlIEFzc2lzdGFudCB0cmVlIHRoZSBidWlsdC1pbiBtb3VudFxuICAgKiBhbHJlYWR5IHNjYW5zLlxuICAgKi9cbiAgZXh0cmFTa2lsbFBhdGhzPzogc3RyaW5nW107XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gZGVmYXVsdHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKipcbiAqIFRoZSBza2lsbCBmb2xkZXJzIGV2ZXJ5IHdvcmtzcGFjZSBzdGFydHMgd2l0aC5cbiAqXG4gKiAtIGB3b3Jrc3BhY2UtdGVhbWAgLSB0aGUgc2hhcmVkIHdvcmtzcGFjZSBBc3Npc3RhbnQgdHJlZSwgcmVhZC1vbmx5IGJlY2F1c2VcbiAqICAgd3JpdGluZyBpdCBpcyBhIHdvcmtzcGFjZS1hZG1pbiBhY3Rpb24uXG4gKiAtIGB3b3Jrc3BhY2UtdGVhbS1hcHBgIC0gdGhlIHJlcXVlc3RpbmcgdXNlcidzIG93biBBc3Npc3RhbnQgdHJlZSwgd3JpdGFibGVcbiAqICAgc28gdGhlIGFwcCBjYW4gc2F2ZSBza2lsbHMgYmFjayB0byBpdC4gU2tpcHBlZCB3aGVuIHRoZSByZXF1ZXN0IGNhcnJpZXMgbm9cbiAqICAgdXNlciBlbWFpbC5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0tJTExfRk9MREVSUzogUmVhZG9ubHk8UmVjb3JkPERlZmF1bHRTa2lsbEZvbGRlck5hbWUsIFNraWxsRm9sZGVyT3B0aW9ucz4+ID0ge1xuICBcIndvcmtzcGFjZS10ZWFtXCI6IHtcbiAgICBwYXRoOiBBU1NJU1RBTlRfU0hBUkVEX1NLSUxMU19QQVRILFxuICAgIHJlYWRhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgfSxcbiAgXCJ3b3Jrc3BhY2UtdGVhbS1hcHBcIjoge1xuICAgIHBhdGg6ICh7IHJlcXVlc3RDb250ZXh0IH0pID0+IHtcbiAgICAgIGNvbnN0IGVtYWlsID0gcmVzb2x2ZVNjb3BlZEVtYWlsKHJlcXVlc3RDb250ZXh0KTtcbiAgICAgIHJldHVybiBlbWFpbCA/IHVzZXJBc3Npc3RhbnRTa2lsbHNQYXRoKGVtYWlsKSA6IHVuZGVmaW5lZDtcbiAgICB9LFxuICAgIHJlYWRhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICB9LFxufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBNYXN0cmEge0BsaW5rIFdvcmtzcGFjZX0gd2l0aCBwZXItcmVxdWVzdCBEYXRhYnJpY2tzIG1vdW50cy5cbiAqXG4gKiBAZXhhbXBsZSBEZWZhdWx0IHNraWxsIGZvbGRlcnMgb25seVxuICogYGBgdHNcbiAqIGNyZWF0ZVdvcmtzcGFjZSgpXG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZSBPdmVycmlkZSBhIGRlZmF1bHQsIGRyb3AgYW5vdGhlciwgYW5kIGFkZCBhIGxvY2F0aW9uIG9mIHlvdXIgb3duXG4gKiBgYGB0c1xuICogY3JlYXRlV29ya3NwYWNlKHtcbiAqICAgc2tpbGxGb2xkZXJzOiB7XG4gKiAgICAgXCJ3b3Jrc3BhY2UtdGVhbVwiOiB7IHBhdGg6IFwiL1dvcmtzcGFjZS9TaGFyZWQvdGVhbS1za2lsbHNcIiB9LFxuICogICAgIFwid29ya3NwYWNlLXRlYW0tYXBwXCI6IGZhbHNlLFxuICogICAgIHJ1bmJvb2tzOiB7IHBhdGg6IFwiL1dvcmtzcGFjZS9TaGFyZWQvcnVuYm9va3Mvc2tpbGxzXCIsIHdyaXRhYmxlOiB0cnVlIH0sXG4gKiAgICAgdm9sdW1lOiB7IGZpbGVzeXN0ZW06IG15Vm9sdW1lRmlsZXN5c3RlbSB9LFxuICogICB9LFxuICogfSlcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFNraWxsIGZvbGRlcnMgcGx1cyBhIGN1c3RvbSBtb3VudCByZXNvbHZlclxuICogYGBgdHNcbiAqIGNyZWF0ZVdvcmtzcGFjZSh7XG4gKiAgIG1vdW50czogW1xuICogICAgIGFzeW5jICh7IHJlcXVlc3RDb250ZXh0IH0pID0+ICh7XG4gKiAgICAgICBtb3VudHM6IHsgXCIvZGF0YVwiOiBteUZpbGVzeXN0ZW0gfSxcbiAqICAgICAgIHNraWxsUGF0aHM6IFtdLFxuICogICAgIH0pLFxuICogICBdLFxuICogfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlV29ya3NwYWNlKG9wdGlvbnM6IENyZWF0ZVdvcmtzcGFjZU9wdGlvbnMgPSB7fSk6IFdvcmtzcGFjZSB7XG4gIGNvbnN0IHsgaWQsIG5hbWUgfSA9IHJlc29sdmVXb3Jrc3BhY2VJZGVudGl0eShvcHRpb25zKTtcbiAgY29uc3Qgc2tpbGxGb2xkZXJzID0gcmVzb2x2ZVNraWxsRm9sZGVycyhvcHRpb25zKTtcbiAgY29uc3QgZm9sZGVyTmFtZXMgPSBPYmplY3Qua2V5cyhza2lsbEZvbGRlcnMpO1xuICBjb25zdCBleHRyYVNraWxsUGF0aHMgPSBvcHRpb25zLmV4dHJhU2tpbGxQYXRocyA/PyBbXTtcbiAgY29uc3QgcmVzb2x2ZXJzID0gYnVpbGRNb3VudFJlc29sdmVycyhcbiAgICBza2lsbEZvbGRlcnMsXG4gICAgWy4uLihvcHRpb25zLm1vdW50cyA/PyBbXSksIC4uLmxvY2FsU2tpbGxNb3VudFJlc29sdmVycyhleHRyYVNraWxsUGF0aHMpXSxcbiAgKTtcbiAgY29uc3QgcmVzb2x2ZUNvbnRyaWJ1dGlvbiA9IGNvbnRyaWJ1dGlvblJlc29sdmVyKHJlc29sdmVycyk7XG4gIGNvbnN0IHNraWxscyA9IG9wdGlvbnMuc2tpbGxzO1xuICBjb25zdCBjaGVja1NraWxsRmlsZU10aW1lID0gb3B0aW9ucy5jaGVja1NraWxsRmlsZU10aW1lID8/IGZhbHNlO1xuICBjb25zdCBibTI1ID0gb3B0aW9ucy5ibTI1ICE9PSBmYWxzZTtcbiAgY29uc3Qgc2FuZGJveCA9IHJlc29sdmVXb3Jrc3BhY2VTYW5kYm94KG9wdGlvbnMuc2FuZGJveCwgaWQsIG5hbWUpO1xuICBsb2dnZXIuZGVidWcoXCJ3b3Jrc3BhY2U6Y3JlYXRlXCIsIHtcbiAgICBpZCxcbiAgICBuYW1lLFxuICAgIHJlc29sdmVyQ291bnQ6IHJlc29sdmVycy5sZW5ndGgsXG4gICAgc2tpbGxGb2xkZXJzOiBmb2xkZXJOYW1lcyxcbiAgICBjdXN0b21Nb3VudFJlc29sdmVyczogb3B0aW9ucy5tb3VudHM/Lmxlbmd0aCA/PyAwLFxuICAgIGN1c3RvbVNraWxsc1Jlc29sdmVyOiBCb29sZWFuKG9wdGlvbnMuc2tpbGxzKSxcbiAgICBjaGVja1NraWxsRmlsZU10aW1lLFxuICAgIHdvcmtzcGFjZVNraWxsUmVmcmVzaFR0bE1zOlxuICAgICAgb3B0aW9ucy53b3Jrc3BhY2VTa2lsbFJlZnJlc2hUdGxNcyA/PyBERUZBVUxUX1dPUktTUEFDRV9TS0lMTF9DQUNIRV9UVExfTVMsXG4gICAgYm0yNSxcbiAgICBleHRyYVNraWxsUGF0aHM6IGV4dHJhU2tpbGxQYXRocy5sZW5ndGgsXG4gICAgc2FuZGJveDogc2FuZGJveCA/IHNhbmRib3hOYW1lKG9wdGlvbnMuc2FuZGJveCkgOiBcImRpc2FibGVkXCIsXG4gIH0pO1xuXG4gIGNvbnN0IHdvcmtzcGFjZSA9IG5ldyBXb3Jrc3BhY2Uoe1xuICAgIGlkLFxuICAgIG5hbWUsXG4gICAgZmlsZXN5c3RlbTogKGNvbnRleHQpID0+IHJlc29sdmVXb3Jrc3BhY2VGaWxlc3lzdGVtKHJlc29sdmVDb250cmlidXRpb24sIGNvbnRleHQpLFxuICAgIC4uLihza2lsbHNcbiAgICAgID8ge1xuICAgICAgICAgIHNraWxscyxcbiAgICAgICAgICBjaGVja1NraWxsRmlsZU10aW1lLFxuICAgICAgICB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4oc2FuZGJveFxuICAgICAgPyB7XG4gICAgICAgICAgc2FuZGJveCxcbiAgICAgICAgICBpbnN0cnVjdGlvbnM6IHsgZHluYW1pY1NhbmRib3g6IFwicmVzb2x2ZVwiIGFzIGNvbnN0IH0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICAgIGJtMjUsXG4gIH0pO1xuICBpZiAoIW9wdGlvbnMuc2tpbGxzICYmIHJlc29sdmVycy5sZW5ndGggPiAwKSB7XG4gICAgd29ya3NwYWNlQ2F0YWxvZ3VlUmVzb2x2ZXJzLnNldChcbiAgICAgIHdvcmtzcGFjZSxcbiAgICAgIGJ1aWxkU2tpbGxDYXRhbG9ndWVSZXNvbHZlcihyZXNvbHZlQ29udHJpYnV0aW9uLCBvcHRpb25zLndvcmtzcGFjZVNraWxsUmVmcmVzaFR0bE1zKSxcbiAgICApO1xuICB9XG4gIHJldHVybiB3b3Jrc3BhY2U7XG59XG5cbi8qKiBSZXR1cm4gdGhlIGRieC10b29scyBjYXRhbG9ndWUgcmVzb2x2ZXIgYXR0YWNoZWQgdG8gb25lIHdvcmtzcGFjZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3b3Jrc3BhY2VTa2lsbENhdGFsb2d1ZVJlc29sdmVyKFxuICB3b3Jrc3BhY2U6IFdvcmtzcGFjZSB8IHVuZGVmaW5lZCxcbik6IFNraWxsQ2F0YWxvZ3VlUmVzb2x2ZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gd29ya3NwYWNlID8gd29ya3NwYWNlQ2F0YWxvZ3VlUmVzb2x2ZXJzLmdldCh3b3Jrc3BhY2UpIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIE1lcmdlIHRoZSBjb25maWd1cmVkIHNraWxsIGZvbGRlcnMgb3ZlciB7QGxpbmsgREVGQVVMVF9TS0lMTF9GT0xERVJTfS5cbiAqXG4gKiBgYXNzaXN0YW50U2tpbGxzOiBmYWxzZWAgZHJvcHMgdGhlIGRlZmF1bHRzLCBhbmQgYSBgZmFsc2VgIHZhbHVlIHJlbW92ZXMgb25lXG4gKiBlbnRyeSBieSBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVycyhcbiAgb3B0aW9uczogUGljazxDcmVhdGVXb3Jrc3BhY2VPcHRpb25zLCBcImFzc2lzdGFudFNraWxsc1wiIHwgXCJza2lsbEZvbGRlcnNcIj4gPSB7fSxcbik6IFJlY29yZDxzdHJpbmcsIFNraWxsRm9sZGVyT3B0aW9ucz4ge1xuICBjb25zdCBtZXJnZWQ6IFJlY29yZDxzdHJpbmcsIFNraWxsRm9sZGVyT3B0aW9ucz4gPVxuICAgIG9wdGlvbnMuYXNzaXN0YW50U2tpbGxzID09PSBmYWxzZSA/IHt9IDogeyAuLi5ERUZBVUxUX1NLSUxMX0ZPTERFUlMgfTtcbiAgZm9yIChjb25zdCBbbmFtZSwgZm9sZGVyXSBvZiBPYmplY3QuZW50cmllcyhvcHRpb25zLnNraWxsRm9sZGVycyA/PyB7fSkpIHtcbiAgICBpZiAoZm9sZGVyID09PSBmYWxzZSkge1xuICAgICAgZGVsZXRlIG1lcmdlZFtuYW1lXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVyZ2VkW25hbWVdID0gZm9sZGVyO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWVyZ2VkO1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHByaXZhdGUgaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VTYW5kYm94KFxuICBzZWxlY3Rpb246IFdvcmtzcGFjZVNhbmRib3hTZWxlY3Rpb24gfCB1bmRlZmluZWQsXG4gIHdvcmtzcGFjZUlkOiBzdHJpbmcsXG4gIHdvcmtzcGFjZU5hbWU6IHN0cmluZyxcbik6IFdvcmtzcGFjZVNhbmRib3ggfCBXb3Jrc3BhY2VTYW5kYm94UmVzb2x2ZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBjb25maWd1cmVkID0gc2VsZWN0aW9uID8/IFwibW9udHlcIjtcbiAgaWYgKGNvbmZpZ3VyZWQgPT09IGZhbHNlKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAoY29uZmlndXJlZCA9PT0gXCJtb250eVwiKSByZXR1cm4gbmV3IE1vbnR5U2FuZGJveCgpO1xuICBpZiAodHlwZW9mIGNvbmZpZ3VyZWQgPT09IFwiZnVuY3Rpb25cIiB8fCBpc1NhbmRib3goY29uZmlndXJlZCkpIHJldHVybiBjb25maWd1cmVkO1xuXG4gIGNvbnN0IG9wdGlvbnM6IERhdGFicmlja3NXb3Jrc3BhY2VTYW5kYm94T3B0aW9ucyA9XG4gICAgY29uZmlndXJlZCA9PT0gXCJkYXRhYnJpY2tzXCIgPyB7IHByb3ZpZGVyOiBcImRhdGFicmlja3NcIiB9IDogY29uZmlndXJlZDtcbiAgcmV0dXJuICh7IHJlcXVlc3RDb250ZXh0IH0pID0+IHtcbiAgICBjb25zdCB1c2VyID0gcmVxdWVzdENvbnRleHQuZ2V0KE1BU1RSQV9VU0VSX0tFWSkgYXMgVXNlciB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIXVzZXIpIHtcbiAgICAgIHRocm93IENvbmZpZ3VyYXRpb25FcnJvci5yZXNvdXJjZU5vdEZvdW5kKFxuICAgICAgICBcIkRhdGFicmlja3Mgc2FuZGJveCB1c2VyIGNvbnRleHRcIixcbiAgICAgICAgXCJJbnZva2UgY29tbWFuZCB0b29scyBmcm9tIGFuIGFnZW50IHR1cm4gc2VydmVkIGJ5IHRoZSBNYXN0cmEgcGx1Z2luLlwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgY29uZmlndXJlZElkID1cbiAgICAgIHR5cGVvZiBvcHRpb25zLnNhbmRib3hJZCA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gb3B0aW9ucy5zYW5kYm94SWQoeyByZXF1ZXN0Q29udGV4dCB9KVxuICAgICAgICA6IG9wdGlvbnMuc2FuZGJveElkO1xuICAgIGNvbnN0IHNhbmRib3hJZCA9IGNvbmZpZ3VyZWRJZCA/PyBkZWZhdWx0U2FuZGJveElkKHdvcmtzcGFjZUlkLCB1c2VyLmlkKTtcbiAgICBjb25zdCBjbGllbnQgPVxuICAgICAgdHlwZW9mIG9wdGlvbnMuY2xpZW50ID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyBvcHRpb25zLmNsaWVudCh7IHJlcXVlc3RDb250ZXh0IH0pXG4gICAgICAgIDogKG9wdGlvbnMuY2xpZW50ID8/IGNyZWF0ZVdvcmtzcGFjZUNsaWVudCgpKTtcbiAgICBjb25zdCB7XG4gICAgICBwcm92aWRlcjogX3Byb3ZpZGVyLFxuICAgICAgc2FuZGJveElkOiBfc2FuZGJveElkLFxuICAgICAgY2xpZW50OiBfY2xpZW50LFxuICAgICAgLi4uc2FuZGJveE9wdGlvbnNcbiAgICB9ID0gb3B0aW9ucztcbiAgICByZXR1cm4gbmV3IERhdGFicmlja3NTYW5kYm94KHtcbiAgICAgIC4uLnNhbmRib3hPcHRpb25zLFxuICAgICAgY2xpZW50LFxuICAgICAgc2FuZGJveElkLFxuICAgICAgZGlzcGxheU5hbWU6IG9wdGlvbnMuZGlzcGxheU5hbWUgPz8gYE1hc3RyYSAke3dvcmtzcGFjZU5hbWV9YCxcbiAgICB9KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFNhbmRib3hJZCh3b3Jrc3BhY2VJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGRpZ2VzdCA9IGNyZWF0ZUhhc2goXCJzaGEyNTZcIilcbiAgICAudXBkYXRlKG9iamVjdC50b1N0YWJsZUtleSh7IHdvcmtzcGFjZUlkLCB1c2VySWQgfSkpXG4gICAgLmRpZ2VzdChcImhleFwiKVxuICAgIC5zbGljZSgwLCAzMik7XG4gIHJldHVybiBgbWFzdHJhLSR7ZGlnZXN0fWA7XG59XG5cbmZ1bmN0aW9uIGlzU2FuZGJveCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFdvcmtzcGFjZVNhbmRib3gge1xuICByZXR1cm4gQm9vbGVhbihcbiAgICB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgXCJpZFwiIGluIHZhbHVlICYmIFwicHJvdmlkZXJcIiBpbiB2YWx1ZSAmJiBcInN0YXR1c1wiIGluIHZhbHVlLFxuICApO1xufVxuXG5mdW5jdGlvbiBzYW5kYm94TmFtZShzZWxlY3Rpb246IFdvcmtzcGFjZVNhbmRib3hTZWxlY3Rpb24gfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICBpZiAoc2VsZWN0aW9uID09PSB1bmRlZmluZWQgfHwgc2VsZWN0aW9uID09PSBcIm1vbnR5XCIpIHJldHVybiBcIm1vbnR5XCI7XG4gIGlmIChzZWxlY3Rpb24gPT09IFwiZGF0YWJyaWNrc1wiKSByZXR1cm4gXCJkYXRhYnJpY2tzXCI7XG4gIGlmIChzZWxlY3Rpb24gPT09IGZhbHNlKSByZXR1cm4gXCJkaXNhYmxlZFwiO1xuICBpZiAodHlwZW9mIHNlbGVjdGlvbiA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gXCJyZXNvbHZlclwiO1xuICByZXR1cm4gaXNTYW5kYm94KHNlbGVjdGlvbikgPyBzZWxlY3Rpb24ucHJvdmlkZXIgOiAoc2VsZWN0aW9uLnByb3ZpZGVyID8/IFwiZGF0YWJyaWNrc1wiKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciB0aGUgcmVxdWVzdCB0b2tlbiBjYXJyaWVzIGEgc2NvcGUgdGhhdCBhbGxvd3Mgd29ya3NwYWNlXG4gKiBmaWxlIEFQSSBhY2Nlc3MgKGB3b3Jrc3BhY2VgIG9yIGBhbGwtYXBpc2Agb24ge0BsaW5rIE1BU1RSQV9TQ09QRVNfS0VZfSkuXG4gKi9cbmZ1bmN0aW9uIGhhc1dvcmtzcGFjZUZpbGVTY29wZShyZXF1ZXN0Q29udGV4dDogUmVxdWVzdENvbnRleHQgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgcmV0dXJuIHRva2VuLmluY2x1ZGVzQWNjZXNzVG9rZW5TY29wZShcbiAgICByZXF1ZXN0Q29udGV4dD8uZ2V0KE1BU1RSQV9TQ09QRVNfS0VZKSxcbiAgICBXT1JLU1BBQ0VfRklMRV9TQ09QRVMsXG4gICk7XG59XG5cbi8qKlxuICogTW91bnQgcmVzb2x2ZXIgZm9yIHRoZSBuYW1lZCBza2lsbCBmb2xkZXJzLlxuICpcbiAqIEdhdGVzIG9uIHdvcmtzcGFjZSBmaWxlIHNjb3BlIChvciBkZXZlbG9wbWVudCBtb2RlKSwgdGhlbiBtb3VudHMgZXZlcnlcbiAqIGZvbGRlciB3aG9zZSBsb2NhdGlvbiByZXNvbHZlcyBmb3IgdGhpcyByZXF1ZXN0LlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlU2tpbGxGb2xkZXJNb3VudHMoXG4gIHNraWxsRm9sZGVyczogUmVjb3JkPHN0cmluZywgU2tpbGxGb2xkZXJPcHRpb25zPixcbiAgY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0LFxuKTogUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4ge1xuICBjb25zdCBtb3VudHM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUZpbGVzeXN0ZW0+ID0ge307XG4gIGNvbnN0IHNraWxsU291cmNlczogU2tpbGxDYXRhbG9ndWVTb3VyY2VbXSA9IFtdO1xuICBjb25zdCBza2lsbFBhdGhzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBjYWNoZUtleXM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHJlcXVlc3RDb250ZXh0ID0gY29udGV4dC5yZXF1ZXN0Q29udGV4dDtcblxuICBpZiAoIXJlcXVlc3RDb250ZXh0IHx8ICFzaG91bGRNb3VudFNraWxsRm9sZGVycyhyZXF1ZXN0Q29udGV4dCkpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJza2lsbC1mb2xkZXJzOnNraXBwZWRcIiwge1xuICAgICAgcmVhc29uOiAhcmVxdWVzdENvbnRleHQgPyBcIm5vLXJlcXVlc3QtY29udGV4dFwiIDogXCJtaXNzaW5nLXdvcmtzcGFjZS1zY29wZVwiLFxuICAgICAgbm9kZUVudjogcHJvY2Vzcy5lbnYuTk9ERV9FTlYsXG4gICAgICBzY29wZXM6IHJlcXVlc3RDb250ZXh0Py5nZXQoTUFTVFJBX1NDT1BFU19LRVkpLFxuICAgIH0pO1xuICAgIHJldHVybiB7IG1vdW50cywgc2tpbGxQYXRocyB9O1xuICB9XG5cbiAgY29uc3QgdXNlciA9IHJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfVVNFUl9LRVkpIGFzIFVzZXIgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IGNsaWVudCA9IHVzZXI/LmV4ZWN1dGlvbkNvbnRleHQuY2xpZW50IGFzIFdvcmtzcGFjZUNsaWVudCB8IHVuZGVmaW5lZDtcbiAgY29uc3QgdXNlcktleSA9IHVzZXIgPyByZXNvbHZlVXNlcktleShyZXF1ZXN0Q29udGV4dCkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGhvc3QgPSBjbGllbnQgPyAoYXdhaXQgY2xpZW50LmNvbmZpZy5nZXRIb3N0KCkpLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBbbmFtZSwgZm9sZGVyXSBvZiBPYmplY3QuZW50cmllcyhza2lsbEZvbGRlcnMpKSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSBhd2FpdCByZXNvbHZlU2tpbGxGb2xkZXJGaWxlc3lzdGVtKG5hbWUsIGZvbGRlciwgY29udGV4dCwge1xuICAgICAgY2xpZW50LFxuICAgICAgaG9zdCxcbiAgICAgIHVzZXJLZXksXG4gICAgfSk7XG4gICAgaWYgKCFyZXNvbHZlZCkgY29udGludWU7XG4gICAgY29uc3QgbW91bnQgPSBmb2xkZXIubW91bnQgPz8gYC8ke25hbWV9YDtcbiAgICBtb3VudHNbbW91bnRdID0gcmVzb2x2ZWQuZmlsZXN5c3RlbTtcbiAgICBpZiAocmVzb2x2ZWQuY2FjaGVLZXkpIGNhY2hlS2V5cy5wdXNoKHJlc29sdmVkLmNhY2hlS2V5KTtcbiAgICBpZiAoZm9sZGVyLnJlYWRhYmxlICE9PSBmYWxzZSkge1xuICAgICAgc2tpbGxQYXRocy5wdXNoKG1vdW50KTtcbiAgICAgIHNraWxsU291cmNlcy5wdXNoKHsgLi4ucmVzb2x2ZWQuc2tpbGxTb3VyY2UsIGlkOiBvYmplY3QudG9TdGFibGVLZXkoeyBtb3VudCwgc291cmNlOiByZXNvbHZlZC5za2lsbFNvdXJjZS5pZCB9KSB9KTtcbiAgICB9XG4gIH1cblxuICBsb2dnZXIuZGVidWcoXCJza2lsbC1mb2xkZXJzOm1vdW50ZWRcIiwge1xuICAgIG1vdW50S2V5czogT2JqZWN0LmtleXMobW91bnRzKSxcbiAgICBza2lsbFBhdGhzLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIG1vdW50cyxcbiAgICBza2lsbFNvdXJjZXMsXG4gICAgc2tpbGxQYXRocyxcbiAgICAuLi4oY2FjaGVLZXlzLmxlbmd0aCA9PT0gT2JqZWN0LmtleXMobW91bnRzKS5sZW5ndGggJiYgY2FjaGVLZXlzLmxlbmd0aCA+IDBcbiAgICAgID8geyBjYWNoZUtleTogb2JqZWN0LnRvU3RhYmxlS2V5KGNhY2hlS2V5cy5zb3J0KCkpIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG4vKipcbiAqIFJlc29sdmUgb25lIHNraWxsIGZvbGRlciB0byBhIE1hc3RyYSBmaWxlc3lzdGVtLCBvciBgdW5kZWZpbmVkYCB0byBza2lwIGl0XG4gKiBmb3IgdGhpcyByZXF1ZXN0LlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlU2tpbGxGb2xkZXJGaWxlc3lzdGVtKFxuICBuYW1lOiBzdHJpbmcsXG4gIGZvbGRlcjogU2tpbGxGb2xkZXJPcHRpb25zLFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4gIGNhY2hlOiB7XG4gICAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQgfCB1bmRlZmluZWQ7XG4gICAgaG9zdDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIHVzZXJLZXk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgfSxcbik6IFByb21pc2U8XG4gIHwge1xuICAgICAgY2FjaGVLZXk/OiBzdHJpbmc7XG4gICAgICBmaWxlc3lzdGVtOiBXb3Jrc3BhY2VGaWxlc3lzdGVtO1xuICAgICAgc2tpbGxTb3VyY2U6IFNraWxsQ2F0YWxvZ3VlU291cmNlO1xuICAgIH1cbiAgfCB1bmRlZmluZWRcbj4ge1xuICBpZiAoZm9sZGVyLmZpbGVzeXN0ZW0gIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGZpbGVzeXN0ZW0gPSBhd2FpdCByZXNvbHZlU2tpbGxGb2xkZXJWYWx1ZShmb2xkZXIuZmlsZXN5c3RlbSwgY29udGV4dCk7XG4gICAgcmV0dXJuIGZpbGVzeXN0ZW1cbiAgICAgID8ge1xuICAgICAgICAgIGZpbGVzeXN0ZW0sXG4gICAgICAgICAgc2tpbGxTb3VyY2U6IG1hc3RyYVNraWxsU291cmNlKFxuICAgICAgICAgICAgb2JqZWN0LnRvU3RhYmxlS2V5KHtcbiAgICAgICAgICAgICAgaWQ6IGZpbGVzeXN0ZW0uaWQsXG4gICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgIHByb3ZpZGVyOiBmaWxlc3lzdGVtLnByb3ZpZGVyLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBmaWxlc3lzdGVtLFxuICAgICAgICAgICksXG4gICAgICAgIH1cbiAgICAgIDogdW5kZWZpbmVkO1xuICB9XG4gIC8vIEEgcGF0aCBtb3VudCBuZWVkcyB0aGUgcmVxdWVzdCdzIE9CTyBjbGllbnQgdG8gcmVhY2ggdGhlIHdvcmtzcGFjZS5cbiAgaWYgKGZvbGRlci5wYXRoID09PSB1bmRlZmluZWQgfHwgIWNhY2hlLmNsaWVudCB8fCAhY2FjaGUuaG9zdCB8fCAhY2FjaGUudXNlcktleSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInNraWxsLWZvbGRlcjpza2lwcGVkXCIsIHtcbiAgICAgIG5hbWUsXG4gICAgICByZWFzb246IGZvbGRlci5wYXRoID09PSB1bmRlZmluZWQgPyBcIm5vLWxvY2F0aW9uXCIgOiBcIm1pc3Npbmctb2JvLWNsaWVudFwiLFxuICAgIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgcm9vdCA9IHN0cmluZ1V0aWxzLnRyaW1Ub051bGwoYXdhaXQgcmVzb2x2ZVNraWxsRm9sZGVyVmFsdWUoZm9sZGVyLnBhdGgsIGNvbnRleHQpKTtcbiAgaWYgKCFyb290KSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gZGF0YWJyaWNrc0ZpbGVzeXN0ZW0oY2FjaGUuY2xpZW50LCByb290LCBmb2xkZXIud3JpdGFibGUgIT09IHRydWUsIHtcbiAgICBob3N0OiBjYWNoZS5ob3N0LFxuICAgIHVzZXJLZXk6IGNhY2hlLnVzZXJLZXksXG4gIH0pO1xufVxuXG4vKiogUmVhZCBhIHtAbGluayBTa2lsbEZvbGRlclZhbHVlfSwgY2FsbGluZyBpdCB3aGVuIGl0IGlzIGEgcGVyLXJlcXVlc3QgcmVzb2x2ZXIuICovXG5mdW5jdGlvbiByZXNvbHZlU2tpbGxGb2xkZXJWYWx1ZTxUPihcbiAgdmFsdWU6IFNraWxsRm9sZGVyVmFsdWU8VD4sXG4gIGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCxcbik6IFQgfCB1bmRlZmluZWQgfCBQcm9taXNlPFQgfCB1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgPyAodmFsdWUgYXMgKGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCkgPT4gVCB8IHVuZGVmaW5lZCB8IFByb21pc2U8VCB8IHVuZGVmaW5lZD4pKGNvbnRleHQpXG4gICAgOiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBGaWxsIGluIGBpZGAgYW5kIGBuYW1lYCB3aGVuIGVpdGhlciBpcyBvbWl0dGVkIG9uIHtAbGluayBDcmVhdGVXb3Jrc3BhY2VPcHRpb25zfS5cbiAqIFNsdWdpZmllcyBgbmFtZWAgaW50byBgaWRgOyB0b2tlbml6ZXMgYGlkYCBpbnRvIGEgZGlzcGxheSBgbmFtZWAuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VJZGVudGl0eShvcHRpb25zOiBDcmVhdGVXb3Jrc3BhY2VPcHRpb25zKToge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG59IHtcbiAgbGV0IGlkID0gb3B0aW9ucy5pZDtcbiAgbGV0IG5hbWUgPSBvcHRpb25zLm5hbWU7XG4gIGlmICghaWQpIHtcbiAgICBpZCA9IG5hbWUgPyBzdHJpbmdVdGlscy50b1NsdWcobmFtZSkgOiBcIndvcmtzcGFjZVwiO1xuICB9XG4gIGlmICghbmFtZSkge1xuICAgIG5hbWUgPSBBcnJheS5mcm9tKHN0cmluZ1V0aWxzLnRva2VuaXplKGlkKSkuam9pbihcIiBcIik7XG4gIH1cbiAgcmV0dXJuIHsgaWQsIG5hbWUgfTtcbn1cblxuLyoqIENvbGxlY3QgdGhlIHNraWxsLWZvbGRlciByZXNvbHZlciBhbmQgYW55IGNhbGxlci1zdXBwbGllZCBvbmVzLiAqL1xuZnVuY3Rpb24gYnVpbGRNb3VudFJlc29sdmVycyhcbiAgc2tpbGxGb2xkZXJzOiBSZWNvcmQ8c3RyaW5nLCBTa2lsbEZvbGRlck9wdGlvbnM+LFxuICBtb3VudHM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSB8IHVuZGVmaW5lZCxcbik6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSB7XG4gIGNvbnN0IHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdID0gW107XG4gIGNvbnN0IGZvbGRlckNvdW50ID0gT2JqZWN0LmtleXMoc2tpbGxGb2xkZXJzKS5sZW5ndGg7XG4gIGlmIChmb2xkZXJDb3VudCA+IDApIHtcbiAgICByZXNvbHZlcnMucHVzaCgoY29udGV4dCkgPT4gcmVzb2x2ZVNraWxsRm9sZGVyTW91bnRzKHNraWxsRm9sZGVycywgY29udGV4dCkpO1xuICB9XG4gIGlmIChtb3VudHM/Lmxlbmd0aCkge1xuICAgIHJlc29sdmVycy5wdXNoKC4uLm1vdW50cyk7XG4gIH1cbiAgbG9nZ2VyLmRlYnVnKFwibW91bnRzOnJlc29sdmVyc1wiLCB7XG4gICAgc2tpbGxGb2xkZXJDb3VudDogZm9sZGVyQ291bnQsXG4gICAgY3VzdG9tUmVzb2x2ZXJDb3VudDogbW91bnRzPy5sZW5ndGggPz8gMCxcbiAgICB0b3RhbFJlc29sdmVyQ291bnQ6IHJlc29sdmVycy5sZW5ndGgsXG4gIH0pO1xuICByZXR1cm4gcmVzb2x2ZXJzO1xufVxuXG4vKiogTW91bnQgc3RhcnR1cC1wcm92aXNpb25lZCBsb2NhbCBza2lsbCByb290cyBpbnRvIE1hc3RyYSdzIHdvcmtzcGFjZSBmaWxlc3lzdGVtLiAqL1xuZnVuY3Rpb24gbG9jYWxTa2lsbE1vdW50UmVzb2x2ZXJzKHBhdGhzOiByZWFkb25seSBzdHJpbmdbXSk6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSB7XG4gIHJldHVybiBbLi4ubmV3IFNldChwYXRocy5tYXAoKHBhdGgpID0+IHBhdGgudHJpbSgpKS5maWx0ZXIoQm9vbGVhbikpXS5tYXAoKHJvb3QsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgbW91bnQgPSBgL3JlbW90ZS1za2lsbHMvJHtpbmRleH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBMb2NhbEZpbGVTeXN0ZW0oe1xuICAgICAgcm9vdCxcbiAgICAgIHJlYWRPbmx5OiB0cnVlLFxuICAgICAgY3JlYXRlUm9vdDogZmFsc2UsXG4gICAgfSk7XG4gICAgY29uc3QgZmlsZXN5c3RlbSA9IGZpbGVzeXN0ZW1zKHNvdXJjZSwgeyByZWFkT25seTogdHJ1ZSB9KTtcbiAgICByZXR1cm4gKCkgPT4gKHtcbiAgICAgIG1vdW50czogeyBbbW91bnRdOiBmaWxlc3lzdGVtIH0sXG4gICAgICBza2lsbFNvdXJjZXM6IFtzaGFyZWRTa2lsbFNvdXJjZShvYmplY3QudG9TdGFibGVLZXkoeyBtb3VudCwgcm9vdCB9KSwgc291cmNlKV0sXG4gICAgICBza2lsbFBhdGhzOiBbbW91bnRdLFxuICAgICAgY2FjaGVLZXk6IG9iamVjdC50b1N0YWJsZUtleSh7IG1vdW50LCByb290IH0pLFxuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqIEFkYXB0IGEgcG9ydGFibGUgZGJ4LXRvb2xzIGZpbGVzeXN0ZW0gdG8gY2F0YWxvZ3VlIGRpc2NvdmVyeSBjYWxsYmFja3MuICovXG5mdW5jdGlvbiBzaGFyZWRTa2lsbFNvdXJjZShpZDogc3RyaW5nLCBmaWxlc3lzdGVtOiBGaWxlU3lzdGVtKTogU2tpbGxDYXRhbG9ndWVTb3VyY2Uge1xuICByZXR1cm4ge1xuICAgIGlkLFxuICAgIGFzeW5jIGxpc3QocGF0aCkge1xuICAgICAgYXdhaXQgZmlsZXN5c3RlbS5pbml0KCk7XG4gICAgICByZXR1cm4gKGF3YWl0IGZpbGVzeXN0ZW0ucmVhZGRpcihwYXRoKSkuZmxhdE1hcCgoZW50cnkpID0+XG4gICAgICAgIGVudHJ5LnR5cGUgPT09IFwiZmlsZVwiIHx8IGVudHJ5LnR5cGUgPT09IFwiZGlyZWN0b3J5XCJcbiAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG5hbWU6IGVudHJ5Lm5hbWUsXG4gICAgICAgICAgICAgICAgdHlwZTogZW50cnkudHlwZSxcbiAgICAgICAgICAgICAgICAuLi4oZW50cnkuc2l6ZSAhPT0gdW5kZWZpbmVkID8geyBzaXplOiBlbnRyeS5zaXplIH0gOiB7fSksXG4gICAgICAgICAgICAgICAgLi4uKGVudHJ5Lm1ldGFkYXRhID8geyBtZXRhZGF0YTogZW50cnkubWV0YWRhdGEgfSA6IHt9KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF1cbiAgICAgICAgICA6IFtdLFxuICAgICAgKTtcbiAgICB9LFxuICAgIGFzeW5jIHJlYWQocGF0aCkge1xuICAgICAgYXdhaXQgZmlsZXN5c3RlbS5pbml0KCk7XG4gICAgICByZXR1cm4gZmlsZXN5c3RlbS5yZWFkRmlsZShwYXRoLCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcbiAgICB9LFxuICB9O1xufVxuXG4vKiogQWRhcHQgYW4gYXJiaXRyYXJ5IE1hc3RyYSBmaWxlc3lzdGVtIHdoZW4gbm8gcG9ydGFibGUgc291cmNlIGlzIGF2YWlsYWJsZS4gKi9cbmZ1bmN0aW9uIG1hc3RyYVNraWxsU291cmNlKGlkOiBzdHJpbmcsIGZpbGVzeXN0ZW06IFdvcmtzcGFjZUZpbGVzeXN0ZW0pOiBTa2lsbENhdGFsb2d1ZVNvdXJjZSB7XG4gIHJldHVybiB7XG4gICAgaWQsXG4gICAgbGlzdDogKHBhdGgpID0+IGZpbGVzeXN0ZW0ucmVhZGRpcihwYXRoKSxcbiAgICBhc3luYyByZWFkKHBhdGgpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgZmlsZXN5c3RlbS5yZWFkRmlsZShwYXRoLCB7IGVuY29kaW5nOiBcInV0ZjhcIiB9KTtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZSA6IHZhbHVlLnRvU3RyaW5nKFwidXRmOFwiKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIEdhdGUgc2tpbGwtZm9sZGVyIG1vdW50cyBvbiB0aGUgcmVxdWVzdCdzIHRva2VuLlxuICpcbiAqIEFsd2F5cyBhbGxvd3MgbW91bnRzIGluIGRldmVsb3BtZW50OyBpbiBvdGhlciBlbnZpcm9ubWVudHMgcmVxdWlyZXNcbiAqIHtAbGluayBoYXNXb3Jrc3BhY2VGaWxlU2NvcGV9LlxuICovXG5mdW5jdGlvbiBzaG91bGRNb3VudFNraWxsRm9sZGVycyhyZXF1ZXN0Q29udGV4dDogUmVxdWVzdENvbnRleHQpOiBib29sZWFuIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcImRldmVsb3BtZW50XCIpIHJldHVybiB0cnVlO1xuICByZXR1cm4gaGFzV29ya3NwYWNlRmlsZVNjb3BlKHJlcXVlc3RDb250ZXh0KTtcbn1cblxuLyoqIFJlYWQgdGhlIHRyaW1tZWQgT0JPIHVzZXIgZW1haWwgc3RhbXBlZCBvbiB7QGxpbmsgTUFTVFJBX1VTRVJfRU1BSUxfS0VZfS4gKi9cbmZ1bmN0aW9uIHJlc29sdmVTY29wZWRFbWFpbChyZXF1ZXN0Q29udGV4dDogUmVxdWVzdENvbnRleHQgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gc3RyaW5nVXRpbHMudHJpbVRvTnVsbChyZXF1ZXN0Q29udGV4dD8uZ2V0KE1BU1RSQV9VU0VSX0VNQUlMX0tFWSkpID8/IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBXcmFwIGEge0BsaW5rIERhdGFicmlja3NGaWxlU3lzdGVtfSBhcyBhIE1hc3RyYSBmaWxlc3lzdGVtLiBXaGVuIHRoZSByb290IGlzXG4gKiBtaXNzaW5nIChhbmQge0BsaW5rIHJlYWRPbmx5fSBzbyB3ZSB3aWxsIG5vdCBjcmVhdGUgaXQpLCBmYWxsIGJhY2sgdG9cbiAqIHtAbGluayBzY3JhdGNoRmlsZXN5c3RlbX0gc28gc2tpbGwgc2NhbnMgc3RpbGwgaGF2ZSBhIHdyaXRhYmxlIGxvY2FsIG1vdW50LlxuICovXG5hc3luYyBmdW5jdGlvbiBkYXRhYnJpY2tzRmlsZXN5c3RlbShcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQsXG4gIHJvb3Q6IHN0cmluZyxcbiAgcmVhZE9ubHk6IGJvb2xlYW4gPSB0cnVlLFxuICBjYWNoZTogeyBob3N0OiBzdHJpbmc7IHVzZXJLZXk6IHN0cmluZyB9LFxuKTogUHJvbWlzZTxcbiAge1xuICAgIGNhY2hlS2V5OiBzdHJpbmc7XG4gICAgZmlsZXN5c3RlbTogV29ya3NwYWNlRmlsZXN5c3RlbTtcbiAgICBza2lsbFNvdXJjZTogU2tpbGxDYXRhbG9ndWVTb3VyY2U7XG4gIH1cbiAgfCB1bmRlZmluZWRcbj4ge1xuICBjb25zdCBmcyA9IG5ldyBEYXRhYnJpY2tzRmlsZVN5c3RlbSh7XG4gICAgY2xpZW50OiB3b3Jrc3BhY2VDbGllbnQudG9MZWdhY3lXb3Jrc3BhY2VDbGllbnQoY2xpZW50KSxcbiAgICByb290LFxuICAgIHJlYWRPbmx5LFxuICAgIGNyZWF0ZVJvb3Q6ICFyZWFkT25seSxcbiAgfSk7XG4gIGNvbnN0IGNhY2hlS2V5ID0gb2JqZWN0LnRvU3RhYmxlS2V5KHtcbiAgICBob3N0OiBjYWNoZS5ob3N0LFxuICAgIHJlYWRPbmx5LFxuICAgIHJvb3QsXG4gICAgdXNlcktleTogY2FjaGUudXNlcktleSxcbiAgfSk7XG4gIGNvbnN0IGZpbGVzeXN0ZW0gPSBmaWxlc3lzdGVtcyhmcywgeyByZWFkT25seSB9KTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmaWxlc3lzdGVtLmluaXQoKTtcbiAgICBpZiAoYXdhaXQgZmlsZXN5c3RlbS5leGlzdHMoXCIuXCIpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjYWNoZUtleSxcbiAgICAgICAgZmlsZXN5c3RlbSxcbiAgICAgICAgc2tpbGxTb3VyY2U6IHNoYXJlZFNraWxsU291cmNlKGNhY2hlS2V5LCBmcyksXG4gICAgICB9O1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiZGF0YWJyaWNrcy1tb3VudDpzY3JhdGNoLWZhbGxiYWNrXCIsIHtcbiAgICAgIHJvb3QsXG4gICAgICByZWFkT25seSxcbiAgICAgIGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUnVuIGV2ZXJ5IG1vdW50IHJlc29sdmVyIGZvciBvbmUgcmVxdWVzdCBhbmQgbWVyZ2UgbW91bnRzIHBsdXMgc2tpbGwgcGF0aHMuXG4gKiBMYXRlciByZXNvbHZlcnMgb3ZlcndyaXRlIG1vdW50IGtleXMgZnJvbSBlYXJsaWVyIG9uZXMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VDb250cmlidXRpb24oXG4gIHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdLFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pOiBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPiB7XG4gIGNvbnN0IG1vdW50czogUmVjb3JkPHN0cmluZywgV29ya3NwYWNlRmlsZXN5c3RlbT4gPSB7fTtcbiAgY29uc3Qgc2tpbGxTb3VyY2VzOiBTa2lsbENhdGFsb2d1ZVNvdXJjZVtdID0gW107XG4gIGNvbnN0IHNraWxsUGF0aHM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IGNhY2hlS2V5czogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGNhY2hlYWJsZSA9IHRydWU7XG5cbiAgZm9yIChjb25zdCBbaW5kZXgsIHJlc29sdmVyXSBvZiByZXNvbHZlcnMuZW50cmllcygpKSB7XG4gICAgY29uc3QgY29udHJpYnV0aW9uID0gYXdhaXQgcmVzb2x2ZXIoY29udGV4dCk7XG4gICAgbG9nZ2VyLmRlYnVnKFwibW91bnRzOnJlc29sdmVyXCIsIHtcbiAgICAgIGluZGV4LFxuICAgICAgbW91bnRLZXlzOiBPYmplY3Qua2V5cyhjb250cmlidXRpb24ubW91bnRzKSxcbiAgICAgIHNraWxsUGF0aHM6IGNvbnRyaWJ1dGlvbi5za2lsbFBhdGhzID8/IFtdLFxuICAgIH0pO1xuICAgIE9iamVjdC5hc3NpZ24obW91bnRzLCBjb250cmlidXRpb24ubW91bnRzKTtcbiAgICBpZiAoT2JqZWN0LmtleXMoY29udHJpYnV0aW9uLm1vdW50cykubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGNvbnRyaWJ1dGlvbi5jYWNoZUtleSkgY2FjaGVLZXlzLnB1c2goY29udHJpYnV0aW9uLmNhY2hlS2V5KTtcbiAgICAgIGVsc2UgY2FjaGVhYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmIChjb250cmlidXRpb24uc2tpbGxQYXRocz8ubGVuZ3RoKSB7XG4gICAgICBza2lsbFBhdGhzLnB1c2goLi4uY29udHJpYnV0aW9uLnNraWxsUGF0aHMpO1xuICAgIH1cbiAgICBpZiAoY29udHJpYnV0aW9uLnNraWxsU291cmNlcz8ubGVuZ3RoKSB7XG4gICAgICBza2lsbFNvdXJjZXMucHVzaCguLi5jb250cmlidXRpb24uc2tpbGxTb3VyY2VzKTtcbiAgICB9XG4gIH1cblxuICBsb2dnZXIuZGVidWcoXCJtb3VudHM6bWVyZ2VkXCIsIHtcbiAgICBtb3VudEtleXM6IE9iamVjdC5rZXlzKG1vdW50cyksXG4gICAgc2tpbGxQYXRocyxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBtb3VudHMsXG4gICAgc2tpbGxTb3VyY2VzLFxuICAgIHNraWxsUGF0aHMsXG4gICAgLi4uKGNhY2hlYWJsZSAmJiBjYWNoZUtleXMubGVuZ3RoID4gMFxuICAgICAgPyB7IGNhY2hlS2V5OiBvYmplY3QudG9TdGFibGVLZXkoeyBtb3VudHM6IE9iamVjdC5rZXlzKG1vdW50cyksIHNvdXJjZXM6IGNhY2hlS2V5cyB9KSB9XG4gICAgICA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEeW5hbWljIGZpbGVzeXN0ZW0gcmVzb2x2ZXIgcGFzc2VkIHRvIE1hc3RyYSB7QGxpbmsgV29ya3NwYWNlfS5cbiAqXG4gKiBSZXR1cm5zIGEge0BsaW5rIENvbXBvc2l0ZUZpbGVzeXN0ZW19IHdoZW4gYW55IG1vdW50IHJlc29sdmVkOyBvdGhlcndpc2UgYVxuICogZnJlc2gge0BsaW5rIHNjcmF0Y2hGaWxlc3lzdGVtfSBzbyBNYXN0cmEgYWx3YXlzIGhhcyBhIHdyaXRhYmxlIGxvY2FsIHJvb3QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VGaWxlc3lzdGVtKFxuICByZXNvbHZlQ29udHJpYnV0aW9uOiAoY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0KSA9PiBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPixcbiAgY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0LFxuKTogUHJvbWlzZTxXb3Jrc3BhY2VGaWxlc3lzdGVtPiB7XG4gIGNvbnN0IHsgY2FjaGVLZXksIG1vdW50cyB9ID0gYXdhaXQgcmVzb2x2ZUNvbnRyaWJ1dGlvbihjb250ZXh0KTtcbiAgY29uc3QgbW91bnRLZXlzID0gT2JqZWN0LmtleXMobW91bnRzKTtcbiAgaWYgKG1vdW50S2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBsb2dnZXIuZGVidWcoXCJmaWxlc3lzdGVtOnNjcmF0Y2hcIiwge1xuICAgICAgaGFzUmVxdWVzdENvbnRleHQ6IEJvb2xlYW4oY29udGV4dC5yZXF1ZXN0Q29udGV4dCksXG4gICAgfSk7XG4gICAgcmV0dXJuIHNjcmF0Y2hGaWxlc3lzdGVtKCk7XG4gIH1cbiAgbG9nZ2VyLmRlYnVnKFwiZmlsZXN5c3RlbTpjb21wb3NpdGVcIiwgeyBtb3VudEtleXMgfSk7XG4gIGlmICghY2FjaGVLZXkpIHJldHVybiBuZXcgQ29tcG9zaXRlRmlsZXN5c3RlbSh7IG1vdW50cyB9KTtcbiAgY29uc3QgZXhpc3RpbmcgPSBzY29wZWRXb3Jrc3BhY2VGaWxlc3lzdGVtcy5nZXQoY2FjaGVLZXkpO1xuICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZztcbiAgY29uc3QgZmlsZXN5c3RlbSA9IG5ldyBDb21wb3NpdGVGaWxlc3lzdGVtKHsgbW91bnRzIH0pO1xuICBzY29wZWRXb3Jrc3BhY2VGaWxlc3lzdGVtcy5zZXQoY2FjaGVLZXksIGZpbGVzeXN0ZW0pO1xuICByZXR1cm4gZmlsZXN5c3RlbTtcbn1cblxuLyoqIE1lbW9pemUgb25lIGNvbXBsZXRlIG1vdW50IGNvbnRyaWJ1dGlvbiBmb3IgZWFjaCByZXF1ZXN0IGNvbnRleHQuICovXG5mdW5jdGlvbiBjb250cmlidXRpb25SZXNvbHZlcihcbiAgcmVzb2x2ZXJzOiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW10sXG4pOiAoY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0KSA9PiBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPiB7XG4gIGNvbnN0IHNjb3BlZCA9IG5ldyBXZWFrTWFwPFJlcXVlc3RDb250ZXh0LCBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPj4oKTtcbiAgbGV0IHVuc2NvcGVkOiBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPiB8IHVuZGVmaW5lZDtcbiAgcmV0dXJuIChjb250ZXh0KSA9PiB7XG4gICAgaWYgKCFjb250ZXh0LnJlcXVlc3RDb250ZXh0KSB7XG4gICAgICB1bnNjb3BlZCA/Pz0gcmVzb2x2ZVdvcmtzcGFjZUNvbnRyaWJ1dGlvbihyZXNvbHZlcnMsIGNvbnRleHQpO1xuICAgICAgcmV0dXJuIHVuc2NvcGVkO1xuICAgIH1cbiAgICBjb25zdCBleGlzdGluZyA9IHNjb3BlZC5nZXQoY29udGV4dC5yZXF1ZXN0Q29udGV4dCk7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3Rpbmc7XG4gICAgY29uc3QgcGVuZGluZyA9IHJlc29sdmVXb3Jrc3BhY2VDb250cmlidXRpb24ocmVzb2x2ZXJzLCBjb250ZXh0KTtcbiAgICBzY29wZWQuc2V0KGNvbnRleHQucmVxdWVzdENvbnRleHQsIHBlbmRpbmcpO1xuICAgIHJldHVybiBwZW5kaW5nO1xuICB9O1xufVxuXG4vKiogUmVzb2x2ZSBvbmUgc2VtYW50aWMgY2F0YWxvZ3VlIG93bmVyIGZyb20gYSByZXF1ZXN0J3Mgb3JkZXJlZCBza2lsbCByb290cy4gKi9cbmZ1bmN0aW9uIGJ1aWxkU2tpbGxDYXRhbG9ndWVSZXNvbHZlcihcbiAgcmVzb2x2ZUNvbnRyaWJ1dGlvbjogKGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCkgPT4gUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4sXG4gIHR0bE1zOiBudW1iZXIgfCB1bmRlZmluZWQsXG4pOiBTa2lsbENhdGFsb2d1ZVJlc29sdmVyIHtcbiAgcmV0dXJuIGFzeW5jICh7IHJlcXVlc3RDb250ZXh0IH0pID0+IHtcbiAgICBjb25zdCBjb250cmlidXRpb24gPSBhd2FpdCByZXNvbHZlQ29udHJpYnV0aW9uKHsgcmVxdWVzdENvbnRleHQgfSk7XG4gICAgY29uc3QgdXNlciA9IHJlcXVlc3RDb250ZXh0Py5nZXQoTUFTVFJBX1VTRVJfS0VZKSBhcyBVc2VyIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGNsaWVudCA9IHVzZXI/LmV4ZWN1dGlvbkNvbnRleHQuY2xpZW50IGFzIFdvcmtzcGFjZUNsaWVudCB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBob3N0ID0gY2xpZW50ID8gKGF3YWl0IGNsaWVudC5jb25maWcuZ2V0SG9zdCgpKS50b1N0cmluZygpIDogXCJsb2NhbFwiO1xuICAgIHJldHVybiB3b3Jrc3BhY2VTa2lsbENhdGFsb2d1ZSh7XG4gICAgICBob3N0LFxuICAgICAgc291cmNlczogY29udHJpYnV0aW9uLnNraWxsU291cmNlcyA/PyBbXSxcbiAgICAgIHR0bE1zLFxuICAgICAgdXNlcktleTogdXNlcj8uaWQgPz8gXCJzZXJ2aWNlXCIsXG4gICAgfSk7XG4gIH07XG59XG4iXX0=
758
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3Jrc3BhY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7R0FZRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNqQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXBHLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsVUFBVSxJQUFJLGdCQUFnQixHQUcvQixNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQXVCLE1BQU0saUJBQWlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRixPQUFPLEVBQ0wsRUFBRSxJQUFJLFFBQVEsRUFDZCxTQUFTLEVBS1QsZ0JBQWdCLEdBQ2pCLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsT0FBTyxFQUNMLGVBQWUsRUFDZixTQUFTLEdBU1YsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLHFCQUFxQixFQUNyQixlQUFlLEVBQ2YsY0FBYyxHQUVmLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFDTCxXQUFXLEVBQ1gsMEJBQTBCLEdBRTNCLE1BQU0sa0JB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QztBQUVELHdFQUF3RTtBQUN4RSxTQUFTLG9CQUFvQixDQUMzQixTQUFtQztJQUVuQyxNQUFNLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBdUQsQ0FBQztJQUNsRixJQUFJLFFBQXlELENBQUM7SUFDOUQsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQ2pCLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDNUIsUUFBUSxLQUFLLDRCQUE0QixDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUM5RCxPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDcEQsSUFBSSxRQUFRO1lBQUUsT0FBTyxRQUFRLENBQUM7UUFDOUIsTUFBTSxPQUFPLEdBQUcsNEJBQTRCLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM1QyxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNYXN0cmEgd29ya3NwYWNlIGZhY3RvcnkgZm9yIERhdGFicmlja3MgQXBwcy5cbiAqXG4gKiBCdWlsZHMgbmF0aXZlIE1hc3RyYSB3b3Jrc3BhY2UgY29uZmlndXJhdGlvbiBmcm9tIERhdGFicmlja3MgcGF0aHMuIFBhdGhzXG4gKiBtb3VudCBhdCB0aGUgc2FtZSBwYXRoIGJ5IGRlZmF1bHQsIGB+YCByZXNvbHZlcyB0byB0aGUgY3VycmVudCB1c2VyJ3NcbiAqIERhdGFicmlja3Mgd29ya3NwYWNlIGhvbWUsIGFuZCBgL3RtcFsvc3VicGF0aF1gIHJlc29sdmVzIHRvIHN0YWJsZVxuICogdXNlci1zY29wZWQgc3RvcmFnZSB1bmRlciB0aGUgaG9zdCdzIGVwaGVtZXJhbCB0ZW1wIGRpcmVjdG9yeS5cbiAqXG4gKiBEYXRhYnJpY2tzIG1vdW50cyB1c2UgYEBkYngtdG9vbHMvZGF0YWJyaWNrc2Age0BsaW5rIERhdGFicmlja3NGaWxlU3lzdGVtfVxuICogd3JhcHBlZCBieSB7QGxpbmsgZmlsZXN5c3RlbXN9OyBpbmFjY2Vzc2libGUgcm9vdHMgYXJlIHNraXBwZWQgaW5kZXBlbmRlbnRseS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBDb25maWd1cmF0aW9uRXJyb3IsIGNyZWF0ZVdvcmtzcGFjZUNsaWVudCwgZ2V0RXhlY3V0aW9uQ29udGV4dCB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB0eXBlIHsgV29ya3NwYWNlQ2xpZW50IH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHsgcGx1Z2luUmVnaXN0cnkgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7XG4gIGZpbGVzQ2FjaGUgYXMgZmlsZXNDYWNoZVBsdWdpbixcbiAgdHlwZSBGaWxlc0NhY2hlRXhwb3J0cyxcbiAgdHlwZSBGaWxlc0NhY2hlU2NvcGUsXG59IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdC9maWxlcy1jYWNoZVwiO1xuaW1wb3J0IHsgRGF0YWJyaWNrc0ZpbGVTeXN0ZW0sIHdvcmtzcGFjZUNsaWVudCB9IGZyb20gXCJAZGJ4LXRvb2xzL2RhdGFicmlja3NcIjtcbmltcG9ydCB7IExvY2FsRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL2ZzXCI7XG5pbXBvcnQgeyBtYXRjaCwgdHlwZSBQYXRoTWF0Y2hJbnB1dCB9IGZyb20gXCJAZGJ4LXRvb2xzL3BhdGhcIjtcbmltcG9ydCB7IGVycm9yVXRpbHMsIGxvZywgb2JqZWN0LCBzdHJpbmdVdGlscywgdG9rZW4gfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgZnMgYXMgc2hhcmVkRlMsXG4gIHBvc2l4UGF0aCxcbiAgdHlwZSBDYWNoZWFibGVGaWxlU3lzdGVtT3BlcmF0aW9uLFxuICB0eXBlIEZpbGVTeXN0ZW0sXG4gIHR5cGUgRmlsZVN5c3RlbUNhY2hlLFxuICB0eXBlIEZpbGVTeXN0ZW1DYWNoZU9wdGlvbnMsXG4gIE1lbW9yeUZpbGVTeXN0ZW0sXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1mc1wiO1xuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0Q29udGV4dCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvcmVxdWVzdC1jb250ZXh0XCI7XG5pbXBvcnQge1xuICBXT1JLU1BBQ0VfVE9PTFMsXG4gIFdvcmtzcGFjZSxcbiAgdHlwZSBTa2lsbHNSZXNvbHZlcixcbiAgdHlwZSBUb29sQ29uZmlnV2l0aEFyZ3NDb250ZXh0LFxuICB0eXBlIFdvcmtzcGFjZUNvbmZpZyxcbiAgdHlwZSBXb3Jrc3BhY2VGaWxlc3lzdGVtLFxuICB0eXBlIFdvcmtzcGFjZVNhbmRib3gsXG4gIHR5cGUgV29ya3NwYWNlU2FuZGJveFJlc29sdmVyLFxuICB0eXBlIFdvcmtzcGFjZVRvb2xDb25maWcsXG4gIHR5cGUgV29ya3NwYWNlVG9vbHNDb25maWcsXG59IGZyb20gXCJAbWFzdHJhL2NvcmUvd29ya3NwYWNlXCI7XG5cbmltcG9ydCB7XG4gIE1BU1RSQV9TQ09QRVNfS0VZLFxuICBNQVNUUkFfVVNFUl9FTUFJTF9LRVksXG4gIE1BU1RSQV9VU0VSX0tFWSxcbiAgcmVzb2x2ZVVzZXJLZXksXG4gIHR5cGUgVXNlcixcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQge1xuICBmaWxlc3lzdGVtcyxcbiAgTW91bnRlZENvbXBvc2l0ZUZpbGVzeXN0ZW0sXG4gIHR5cGUgTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXJPcHRpb25zLFxufSBmcm9tIFwiLi9maWxlc3lzdGVtcy50c1wiO1xuaW1wb3J0IHsgTW9udHlTYW5kYm94IH0gZnJvbSBcIi4vbW9udHktc2FuZGJveC50c1wiO1xuaW1wb3J0IHsgRGF0YWJyaWNrc1NhbmRib3gsIHR5cGUgRGF0YWJyaWNrc1dvcmtzcGFjZVNhbmRib3hPcHRpb25zIH0gZnJvbSBcIi4vc2FuZGJveC50c1wiO1xuaW1wb3J0IHsgT1JHQU5JWkFUSU9OX0FTU0lTVEFOVF9QQVRILCBwZXJzb25hbFdvcmtzcGFjZVBhdGggfSBmcm9tIFwiLi9za2lsbC1wYXRocy50c1wiO1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogT0F1dGggc2NvcGVzIHRoYXQgZ2F0ZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBmaWxlIG1vdW50cy4gKi9cbmNvbnN0IFdPUktTUEFDRV9GSUxFX1NDT1BFUyA9IFtcIndvcmtzcGFjZVwiLCBcIndvcmtzcGFjZS53b3Jrc3BhY2VcIiwgXCJhbGwtYXBpc1wiXSBhcyBjb25zdDtcbmNvbnN0IFNDUkFUQ0hfTU9VTlQgPSBcIi90bXBcIjtcbmNvbnN0IENBQ0hFQUJMRV9GSUxFU1lTVEVNX09QRVJBVElPTlMgPSBbXG4gIFwiZXhpc3RzXCIsXG4gIFwicmVhZEZpbGVcIixcbiAgXCJyZWFkZGlyXCIsXG4gIFwic3RhdFwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgQ2FjaGVhYmxlRmlsZVN5c3RlbU9wZXJhdGlvbltdO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibWFzdHJhL3dvcmtzcGFjZXNcIik7XG5sZXQgd29ya3NwYWNlU291cmNlU2VxdWVuY2UgPSAwO1xuY29uc3QgZGF0YWJyaWNrc1dvcmtzcGFjZU9wdGlvbnMgPSBuZXcgV2Vha01hcDxXb3Jrc3BhY2UsIERhdGFicmlja3NXb3Jrc3BhY2VPcHRpb25zPigpO1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogUGVyLXJlcXVlc3QgY29udGV4dCBmb3IgbW91bnQgYW5kIHNraWxsLWZvbGRlciByZXNvbHZlcnMuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFicmlja3NXb3Jrc3BhY2VDb250ZXh0IHtcbiAgcmVxdWVzdENvbnRleHQ/OiBSZXF1ZXN0Q29udGV4dDtcbn1cblxuLyoqXG4gKiBPbmUgRGF0YWJyaWNrcyBwYXRoIG1vdW50ZWQgaW50byBhIE1hc3RyYSB3b3Jrc3BhY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGhPcHRpb25zIHtcbiAgLyoqIEFic29sdXRlIERhdGFicmlja3MgcGF0aCBvciBgfmAgc2hvcnRjdXQgZm9yIHRoZSBjdXJyZW50IHVzZXIncyB3b3Jrc3BhY2UgaG9tZS4gKi9cbiAgcGF0aDogc3RyaW5nO1xuICAvKiogSHVtYW4tZnJpZW5kbHkgbW91bnQgbmFtZSBzaG93biBpbiBmaWxlc3lzdGVtIGxpc3RpbmdzLiAqL1xuICBkaXNwbGF5TmFtZT86IHN0cmluZztcbiAgLyoqIE1vdW50IGRlc2NyaXB0aW9uIHNob3duIGluIGZpbGVzeXN0ZW0gbGlzdGluZ3MgYW5kIHdvcmtzcGFjZSBpbnN0cnVjdGlvbnMuICovXG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogU2NhbiB0aGlzIG1vdW50IGZvciBgU0tJTEwubWRgIGZpbGVzLiBEZWZhdWx0cyB0byBgdHJ1ZWA7IGBmYWxzZWAgbW91bnRzXG4gICAqIHRoZSBsb2NhdGlvbiBmb3IgZmlsZSB0b29scyB3aXRob3V0IGFkZGluZyBpdCB0byBza2lsbCBkaXNjb3ZlcnkuXG4gICAqL1xuICByZWFkYWJsZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBTa2lsbCByb290cyByZWxhdGl2ZSB0byB0aGlzIGZpbGVzeXN0ZW0gcm9vdC4gRGVmYXVsdHMgdG8gYFtcIi5cIl1gLlxuICAgKiBFYWNoIHBhdGggaXMgam9pbmVkIHRvIHRoZSBhY3R1YWwgbW91bnQgcGF0aCBiZWZvcmUgTWFzdHJhIHNjYW5zIGl0LlxuICAgKi9cbiAgc2tpbGxzPzogcmVhZG9ubHkgc3RyaW5nW107XG4gIC8qKlxuICAgKiBBbGxvdyB3cml0ZSBhdHRlbXB0cyB0byBhIHtAbGluayBwYXRofSBtb3VudC4gRGVmYXVsdHMgdG8gYHRydWVgIGZvclxuICAgKiBgL1dvcmtzcGFjZWAgcm9vdHMgYW5kIGBmYWxzZWAgZWxzZXdoZXJlLiBEYXRhYnJpY2tzIHBlcm1pc3Npb25zIHN0aWxsXG4gICAqIGRldGVybWluZSB3aGV0aGVyIGVhY2ggbXV0YXRpb24gc3VjY2VlZHMuXG4gICAqL1xuICB3cml0YWJsZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDcmVhdGUgYSB3cml0YWJsZSB7QGxpbmsgcGF0aH0gcm9vdCB3aGVuIG1pc3NpbmcuIERlZmF1bHRzIHRvXG4gICAqIHtAbGluayB3cml0YWJsZX07IHNldCBgZmFsc2VgIGZvciBwcmUtZXhpc3Rpbmcgcm9vdHMgd2l0aCBjb25kaXRpb25hbCBhY2Nlc3MuXG4gICAqL1xuICBjcmVhdGVSb290PzogYm9vbGVhbjtcbiAgLyoqIE1vdW50IHBvaW50IGluIHRoZSBjb21wb3NpdGUgbmFtZXNwYWNlLiBEYXRhYnJpY2tzIHBhdGhzIGRlZmF1bHQgdG8gdGhlaXIgYWN0dWFsIHJvb3QuICovXG4gIG1vdW50Pzogc3RyaW5nO1xufVxuXG4vKiogU3RyaW5nIHNob3J0aGFuZCBvciBmdWxsIG9wdGlvbnMgZm9yIG9uZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBwYXRoLiAqL1xuZXhwb3J0IHR5cGUgRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGggPSBzdHJpbmcgfCBEYXRhYnJpY2tzV29ya3NwYWNlUGF0aE9wdGlvbnM7XG5cbi8qKiBGaXhlZCBvciByZXF1ZXN0LWRlcGVuZGVudCBEYXRhYnJpY2tzIHBhdGggZW50cnkuICovXG5leHBvcnQgdHlwZSBEYXRhYnJpY2tzV29ya3NwYWNlUGF0aFZhbHVlID1cbiAgfCBEYXRhYnJpY2tzV29ya3NwYWNlUGF0aFxuICB8IGZhbHNlXG4gIHwgKChcbiAgICAgIGNvbnRleHQ6IERhdGFicmlja3NXb3Jrc3BhY2VDb250ZXh0LFxuICAgICkgPT5cbiAgICAgIHwgRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGhcbiAgICAgIHwgZmFsc2VcbiAgICAgIHwgdW5kZWZpbmVkXG4gICAgICB8IFByb21pc2U8RGF0YWJyaWNrc1dvcmtzcGFjZVBhdGggfCBmYWxzZSB8IHVuZGVmaW5lZD4pO1xuXG4vKiogT3BlcmF0aW9ucyBhbmQgcGF0aCBnbG9icyBjYWNoZWQgYnkgdGhlIERhdGFicmlja3MgZmlsZXN5c3RlbSBzaG9ydGN1dC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJyaWNrc1dvcmtzcGFjZUNhY2hlRmlsdGVyIHtcbiAgLyoqIENhY2hlZCBmaWxlc3lzdGVtIG9wZXJhdGlvbnMuIE9taXQgZm9yIGBleGlzdHNgLCBgcmVhZEZpbGVgLCBgcmVhZGRpcmAsIGFuZCBgc3RhdGAuICovXG4gIG9wZXJhdGlvbnM/OiBDYWNoZWFibGVGaWxlU3lzdGVtT3BlcmF0aW9uIHwgcmVhZG9ubHkgQ2FjaGVhYmxlRmlsZVN5c3RlbU9wZXJhdGlvbltdO1xuICAvKiogQWJzb2x1dGUgb3Igcm9vdC1yZWxhdGl2ZSBnbG9icyBhbmQgcHJlZGljYXRlcy4gYH5gIGV4cGFuZHMgcGVyIHJlcXVlc3QuICovXG4gIHBhdGhzPzogUGF0aE1hdGNoSW5wdXQgfCByZWFkb25seSBQYXRoTWF0Y2hJbnB1dFtdO1xufVxuXG4vKiogRml4ZWQgb3IgcmVxdWVzdC1kZXBlbmRlbnQgZmlsZXN5c3RlbSBjYWNoZSBzZWxlY3Rpb24uICovXG5leHBvcnQgdHlwZSBEYXRhYnJpY2tzV29ya3NwYWNlQ2FjaGUgPVxuICB8IGJvb2xlYW5cbiAgfCBEYXRhYnJpY2tzV29ya3NwYWNlQ2FjaGVGaWx0ZXJcbiAgfCByZWFkb25seSBEYXRhYnJpY2tzV29ya3NwYWNlQ2FjaGVGaWx0ZXJbXVxuICB8ICgoXG4gICAgICBjb250ZXh0OiBEYXRhYnJpY2tzV29ya3NwYWNlQ29udGV4dCxcbiAgICApID0+XG4gICAgICB8IGJvb2xlYW5cbiAgICAgIHwgRGF0YWJyaWNrc1dvcmtzcGFjZUNhY2hlRmlsdGVyXG4gICAgICB8IHJlYWRvbmx5IERhdGFicmlja3NXb3Jrc3BhY2VDYWNoZUZpbHRlcltdXG4gICAgICB8IHVuZGVmaW5lZFxuICAgICAgfCBQcm9taXNlPFxuICAgICAgICAgIHwgYm9vbGVhblxuICAgICAgICAgIHwgRGF0YWJyaWNrc1dvcmtzcGFjZUNhY2hlRmlsdGVyXG4gICAgICAgICAgfCByZWFkb25seSBEYXRhYnJpY2tzV29ya3NwYWNlQ2FjaGVGaWx0ZXJbXVxuICAgICAgICAgIHwgdW5kZWZpbmVkXG4gICAgICAgID4pO1xuXG4vKiogTW91bnQgbWFwIHBsdXMgb3B0aW9uYWwgTWFzdHJhIHNraWxsIHNjYW4gcm9vdHMgcmVzb2x2ZWQgZm9yIG9uZSByZXF1ZXN0LiAqL1xuaW50ZXJmYWNlIFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHtcbiAgbW91bnRzOiBSZWNvcmQ8c3RyaW5nLCBXb3Jrc3BhY2VGaWxlc3lzdGVtPjtcbiAgLyoqIFBhdGhzIHdpdGhpbiB0aGUgY29tcG9zaXRlIG5hbWVzcGFjZSB3aGVyZSBgU0tJTEwubWRgIGZpbGVzIGFyZSBzY2FubmVkLiAqL1xuICBza2lsbFBhdGhzPzogc3RyaW5nW107XG59XG5cbi8qKiBJbnRlcm5hbCBmaWxlc3lzdGVtIGNvbnRyaWJ1dGlvbiByZXNvbHZlci4gKi9cbnR5cGUgV29ya3NwYWNlTW91bnRSZXNvbHZlciA9IChcbiAgY29udGV4dDogRGF0YWJyaWNrc1dvcmtzcGFjZUNvbnRleHQsXG4pID0+IFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHwgUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj47XG5cbi8qKlxuICogU2FuZGJveCBzZWxlY3Rpb24gZm9yIHtAbGluayBkYXRhYnJpY2tzV29ya3NwYWNlfS4gTW9udHkgaXMgdGhlIGRlZmF1bHQ7XG4gKiBgZmFsc2VgIGRpc2FibGVzIGNvbW1hbmQgZXhlY3V0aW9uLCBhbmQgYSBNYXN0cmEgcHJvdmlkZXIgb3IgcmVzb2x2ZXIgaXMgYW5cbiAqIGV4cGxpY2l0IHJlcGxhY2VtZW50LlxuICovXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VTYW5kYm94U2VsZWN0aW9uID1cbiAgfCBmYWxzZVxuICB8IFwiZGF0YWJyaWNrc1wiXG4gIHwgXCJtb250eVwiXG4gIHwgRGF0YWJyaWNrc1dvcmtzcGFjZVNhbmRib3hPcHRpb25zXG4gIHwgV29ya3NwYWNlU2FuZGJveFxuICB8IFdvcmtzcGFjZVNhbmRib3hSZXNvbHZlcjtcblxuLyoqIE5hdGl2ZSBNYXN0cmEgd29ya3NwYWNlIG9wdGlvbnMgcGx1cyBEYXRhYnJpY2tzIHBhdGggc2hvcnRjdXRzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhYnJpY2tzV29ya3NwYWNlT3B0aW9uc1xuICBleHRlbmRzIE9taXQ8V29ya3NwYWNlQ29uZmlnLCBcImZpbGVzeXN0ZW1cIiB8IFwibW91bnRzXCIgfCBcInNhbmRib3hcIiB8IFwic2tpbGxzXCI+IHtcbiAgLyoqXG4gICAqIFN0YXJ0IGZyb20ge0BsaW5rIERFRkFVTFRfREFUQUJSSUNLU19XT1JLU1BBQ0VfUEFUSFN9LiBEZWZhdWx0cyB0byBgdHJ1ZWAuXG4gICAqL1xuICBhc3Npc3RhbnRQYXRocz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBEYXRhYnJpY2tzIHBhdGhzIGFwcGVuZGVkIGFmdGVyIHRoZSBkZWZhdWx0cy4gQSBzdHJpbmcgaXMgc2hvcnRoYW5kIGZvclxuICAgKiBgeyBwYXRoIH1gOyBhIHJlc29sdmVyIG1heSByZXR1cm4gZWl0aGVyIGZvcm0gcGVyIHJlcXVlc3QuXG4gICAqL1xuICBwYXRocz86IHJlYWRvbmx5IERhdGFicmlja3NXb3Jrc3BhY2VQYXRoVmFsdWVbXTtcbiAgLyoqIE5hdGl2ZSBNYXN0cmEgZmlsZXN5c3RlbXMgY29tcG9zZWQgYmVzaWRlIHRoZSBEYXRhYnJpY2tzIHBhdGhzLiAqL1xuICBtb3VudHM/OiBSZWNvcmQ8c3RyaW5nLCBXb3Jrc3BhY2VGaWxlc3lzdGVtPjtcbiAgLyoqIFJlcGxhY2UgdGhlIGF1dG8tYnVpbHQgZHluYW1pYyBza2lsbHMgcmVzb2x2ZXIuICovXG4gIHNraWxscz86IFNraWxsc1Jlc29sdmVyO1xuICAvKiogRmlsZXN5c3RlbSBjYWNoZSBmaWx0ZXJzLiBJZ25vcmVkIHdoZW4gdGhlIEFwcEtpdCBmaWxlcy1jYWNoZSBwbHVnaW4gaXMgYWJzZW50LiAqL1xuICBjYWNoZT86IERhdGFicmlja3NXb3Jrc3BhY2VDYWNoZTtcbiAgLyoqIEFwcEtpdCBwbHVnaW4gY29udGV4dCB1c2VkIHRvIGRpc2NvdmVyIG9wdGlvbmFsIHNpYmxpbmcgY2FwYWJpbGl0aWVzLiAqL1xuICBwbHVnaW5Db250ZXh0PzogcGx1Z2luUmVnaXN0cnkuUGx1Z2luQ29udGV4dExpa2U7XG4gIC8qKlxuICAgKiBDb21tYW5kIHNhbmRib3guIERlZmF1bHRzIHRvIE1vbnR5LiBQYXNzIGBcImRhdGFicmlja3NcImAgb3IgYW4gb3B0aW9uc1xuICAgKiBvYmplY3QgZm9yIERhdGFicmlja3MgU2FuZGJveCwgYGZhbHNlYCB0byBkaXNhYmxlIGNvbW1hbmQgZXhlY3V0aW9uLCBvciBhblxuICAgKiBleHBsaWNpdCBNYXN0cmEgc2FuZGJveC9wcm92aWRlciByZXNvbHZlci5cbiAgICovXG4gIHNhbmRib3g/OiBXb3Jrc3BhY2VTYW5kYm94U2VsZWN0aW9uO1xuICAvKipcbiAgICogRXh0cmEgTE9DQUwgc2tpbGwgcm9vdHMgbW91bnRlZCByZWFkLW9ubHkgZm9yIGV2ZXJ5IHJlcXVlc3QncyBza2lsbCBkaXNjb3ZlcnkuXG4gICAqIFVzZWQgYnkgdGhlIHBsdWdpbiB0byBzdXJmYWNlIHJlbW90ZSBza2lsbHMgcHJvdmlzaW9uZWQgdG8gYSBsb2NhbCB0ZW1wXG4gICAqIGRpciBhdCBzdGFydHVwIChzZWUgYHJlbW90ZS1za2lsbHMudHNgKS4gRGF0YWJyaWNrcy1ob3N0ZWQgcmVtb3RlIHNraWxsc1xuICAgKiBuZWVkIG5vIGVudHJ5IGhlcmUgLSB0aGV5IGxhbmQgaW4gdGhlIEFzc2lzdGFudCB0cmVlIHRoZSBidWlsdC1pbiBtb3VudFxuICAgKiBhbHJlYWR5IHNjYW5zLlxuICAgKi9cbiAgZXh0cmFTa2lsbFBhdGhzPzogc3RyaW5nW107XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gZGVmYXVsdHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKipcbiAqIERlZmF1bHQgRGF0YWJyaWNrcyBwYXRocyBmb3Igc2hhcmVkIGFuZCBjdXJyZW50LXVzZXIgQWdlbnQgU2tpbGxzLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9EQVRBQlJJQ0tTX1dPUktTUEFDRV9QQVRIUzogcmVhZG9ubHkgRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGhPcHRpb25zW10gPSBbXG4gIHtcbiAgICBwYXRoOiBPUkdBTklaQVRJT05fQVNTSVNUQU5UX1BBVEgsXG4gICAgcmVhZGFibGU6IHRydWUsXG4gICAgc2tpbGxzOiBbXCJza2lsbHNcIl0sXG4gICAgd3JpdGFibGU6IHRydWUsXG4gICAgY3JlYXRlUm9vdDogZmFsc2UsXG4gIH0sXG4gIHtcbiAgICBwYXRoOiBcIn5cIixcbiAgICByZWFkYWJsZTogdHJ1ZSxcbiAgICBza2lsbHM6IFtcIi5hc3Npc3RhbnQvc2tpbGxzXCJdLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGNyZWF0ZVJvb3Q6IGZhbHNlLFxuICB9LFxuXTtcblxuLyoqXG4gKiBDcmVhdGUgYSBNYXN0cmEge0BsaW5rIFdvcmtzcGFjZX0gd2l0aCBwZXItcmVxdWVzdCBEYXRhYnJpY2tzIG1vdW50cy5cbiAqXG4gKiBAZXhhbXBsZSBEZWZhdWx0IERhdGFicmlja3MgcGF0aHNcbiAqIGBgYHRzXG4gKiBkYXRhYnJpY2tzV29ya3NwYWNlKClcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFVzZSBvbmx5IGV4cGxpY2l0IHBhdGhzXG4gKiBgYGB0c1xuICogZGF0YWJyaWNrc1dvcmtzcGFjZSh7XG4gKiAgIGFzc2lzdGFudFBhdGhzOiBmYWxzZSxcbiAqICAgcGF0aHM6IFtcIn4vcHJvamVjdFwiLCBcIi90bXAvcHJvamVjdFwiLCBcIi9Wb2x1bWVzL21haW4vZGVmYXVsdC9kYXRhXCJdLFxuICogfSlcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIEJ1aWxkIGEgc3RhbmRhcmQgTWFzdHJhIHdvcmtzcGFjZSB5b3Vyc2VsZlxuICogYGBgdHNcbiAqIG5ldyBXb3Jrc3BhY2Uoe1xuICogICAuLi5kYXRhYnJpY2tzV29ya3NwYWNlQ29uZmlnKHsgcGF0aHM6IFtcIn4vcHJvamVjdFwiXSB9KSxcbiAqICAgc2FuZGJveDogbXlTYW5kYm94LFxuICogfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGF0YWJyaWNrc1dvcmtzcGFjZUNvbmZpZyhcbiAgb3B0aW9uczogRGF0YWJyaWNrc1dvcmtzcGFjZU9wdGlvbnMgPSB7fSxcbik6IFdvcmtzcGFjZUNvbmZpZyB7XG4gIGNvbnN0IHsgaWQsIG5hbWUgfSA9IHJlc29sdmVXb3Jrc3BhY2VJZGVudGl0eShvcHRpb25zKTtcbiAgY29uc3QgZmlsZXN5c3RlbVNvdXJjZUtleSA9IGAke2lkfTokeysrd29ya3NwYWNlU291cmNlU2VxdWVuY2V9YDtcbiAgY29uc3QgcGF0aHMgPSByZXNvbHZlRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGhzKG9wdGlvbnMpO1xuICBjb25zdCBjb25maWd1cmVkUGF0aHMgPSBwYXRocy5sZW5ndGg7XG4gIGNvbnN0IGV4dHJhU2tpbGxQYXRocyA9IG9wdGlvbnMuZXh0cmFTa2lsbFBhdGhzID8/IFtdO1xuICBjb25zdCBmaWxlc0NhY2hlID0gcGx1Z2luUmVnaXN0cnkuaW5zdGFuY2Uob3B0aW9ucy5wbHVnaW5Db250ZXh0LCBmaWxlc0NhY2hlUGx1Z2luKT8uZXhwb3J0cygpO1xuICBjb25zdCBjb25maWd1cmVkQ2FjaGUgPSBvcHRpb25zLmNhY2hlO1xuICBjb25zdCBtb3VudEZpbGVzQ2FjaGUgPSBjb25maWd1cmVkQ2FjaGUgPT09IGZhbHNlID8gdW5kZWZpbmVkIDogZmlsZXNDYWNoZTtcbiAgY29uc3QgcmV0YWluRmlsZXN5c3RlbVNvdXJjZSA9XG4gICAgbW91bnRGaWxlc0NhY2hlICE9PSB1bmRlZmluZWQgJiZcbiAgICB0eXBlb2YgY29uZmlndXJlZENhY2hlICE9PSBcImZ1bmN0aW9uXCIgJiZcbiAgICBwYXRocy5ldmVyeSgocGF0aCkgPT4gdHlwZW9mIHBhdGggIT09IFwiZnVuY3Rpb25cIik7XG4gIGNvbnN0IHJlc29sdmVycyA9IGJ1aWxkTW91bnRSZXNvbHZlcnMoXG4gICAgcGF0aHMsXG4gICAgb3B0aW9ucy5tb3VudHMsXG4gICAgbG9jYWxTa2lsbE1vdW50UmVzb2x2ZXJzKGV4dHJhU2tpbGxQYXRocyksXG4gICAgbW91bnRGaWxlc0NhY2hlLFxuICAgIGNvbmZpZ3VyZWRDYWNoZSxcbiAgKTtcbiAgY29uc3QgcmVzb2x2ZUNvbnRyaWJ1dGlvbiA9IGNvbnRyaWJ1dGlvblJlc29sdmVyKHJlc29sdmVycyk7XG4gIGNvbnN0IHJlc29sdmVGaWxlc3lzdGVtID0gKGNvbnRleHQ6IERhdGFicmlja3NXb3Jrc3BhY2VDb250ZXh0KSA9PlxuICAgIHJlc29sdmVXb3Jrc3BhY2VGaWxlc3lzdGVtKFxuICAgICAgcmVzb2x2ZUNvbnRyaWJ1dGlvbixcbiAgICAgIGNvbnRleHQsXG4gICAgICByZXRhaW5GaWxlc3lzdGVtU291cmNlID8gbW91bnRGaWxlc0NhY2hlIDogdW5kZWZpbmVkLFxuICAgICAgZmlsZXN5c3RlbVNvdXJjZUtleSxcbiAgICApO1xuICBjb25zdCBza2lsbHM6IFNraWxsc1Jlc29sdmVyID1cbiAgICBvcHRpb25zLnNraWxscyA/P1xuICAgIChhc3luYyAoeyByZXF1ZXN0Q29udGV4dCB9KSA9PiB7XG4gICAgICBjb25zdCBjb250ZXh0ID0geyByZXF1ZXN0Q29udGV4dCB9O1xuICAgICAgY29uc3QgY29udHJpYnV0aW9uID0gYXdhaXQgcmVzb2x2ZUNvbnRyaWJ1dGlvbihjb250ZXh0KTtcbiAgICAgIHJldHVybiByZXNvbHZlRGlzdGluY3RTa2lsbFBhdGhzKFxuICAgICAgICBhd2FpdCByZXNvbHZlRmlsZXN5c3RlbShjb250ZXh0KSxcbiAgICAgICAgY29udHJpYnV0aW9uLnNraWxsUGF0aHMgPz8gW10sXG4gICAgICApO1xuICAgIH0pO1xuICBjb25zdCBjaGVja1NraWxsRmlsZU10aW1lID0gb3B0aW9ucy5jaGVja1NraWxsRmlsZU10aW1lID8/IGZhbHNlO1xuICBjb25zdCBibTI1ID0gb3B0aW9ucy5ibTI1ID8/IHRydWU7XG4gIGNvbnN0IHNhbmRib3ggPSByZXNvbHZlV29ya3NwYWNlU2FuZGJveChvcHRpb25zLnNhbmRib3gsIGlkLCBuYW1lKTtcbiAgY29uc3QgdG9vbHMgPSB3b3Jrc3BhY2VUb29scyhvcHRpb25zLnRvb2xzKTtcbiAgbG9nZ2VyLmRlYnVnKFwid29ya3NwYWNlOmNyZWF0ZVwiLCB7XG4gICAgaWQsXG4gICAgbmFtZSxcbiAgICByZXNvbHZlckNvdW50OiByZXNvbHZlcnMubGVuZ3RoLFxuICAgIGNvbmZpZ3VyZWRQYXRocyxcbiAgICBjdXN0b21Nb3VudHM6IE9iamVjdC5rZXlzKG9wdGlvbnMubW91bnRzID8/IHt9KS5sZW5ndGgsXG4gICAgY3VzdG9tU2tpbGxzUmVzb2x2ZXI6IEJvb2xlYW4ob3B0aW9ucy5za2lsbHMpLFxuICAgIGNoZWNrU2tpbGxGaWxlTXRpbWUsXG4gICAgYm0yNSxcbiAgICBleHRyYVNraWxsUGF0aHM6IGV4dHJhU2tpbGxQYXRocy5sZW5ndGgsXG4gICAgc2FuZGJveDogc2FuZGJveCA/IHNhbmRib3hOYW1lKG9wdGlvbnMuc2FuZGJveCkgOiBcImRpc2FibGVkXCIsXG4gIH0pO1xuXG4gIGNvbnN0IHtcbiAgICBhc3Npc3RhbnRQYXRoczogX2Fzc2lzdGFudFBhdGhzLFxuICAgIHBhdGhzOiBfcGF0aHMsXG4gICAgbW91bnRzOiBfbW91bnRzLFxuICAgIHNraWxsczogX3NraWxscyxcbiAgICBjYWNoZTogX2NhY2hlLFxuICAgIHBsdWdpbkNvbnRleHQ6IF9wbHVnaW5Db250ZXh0LFxuICAgIHNhbmRib3g6IF9zYW5kYm94LFxuICAgIGV4dHJhU2tpbGxQYXRoczogX2V4dHJhU2tpbGxQYXRocyxcbiAgICAuLi53b3Jrc3BhY2VPcHRpb25zXG4gIH0gPSBvcHRpb25zO1xuICByZXR1cm4ge1xuICAgIC4uLndvcmtzcGFjZU9wdGlvbnMsXG4gICAgaWQsXG4gICAgbmFtZSxcbiAgICBmaWxlc3lzdGVtOiByZXNvbHZlRmlsZXN5c3RlbSxcbiAgICAuLi4ocmVzb2x2ZXJzLmxlbmd0aCA+IDAgfHwgb3B0aW9ucy5za2lsbHNcbiAgICAgID8ge1xuICAgICAgICAgIHNraWxscyxcbiAgICAgICAgICBjaGVja1NraWxsRmlsZU10aW1lLFxuICAgICAgICB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4oc2FuZGJveFxuICAgICAgPyB7XG4gICAgICAgICAgc2FuZGJveCxcbiAgICAgICAgICBpbnN0cnVjdGlvbnM6IHsgZHluYW1pY1NhbmRib3g6IFwicmVzb2x2ZVwiIGFzIGNvbnN0IH0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICAgIGJtMjUsXG4gICAgdG9vbHMsXG4gIH07XG59XG5cbi8qKiBDcmVhdGUgYSBuYXRpdmUgTWFzdHJhIHtAbGluayBXb3Jrc3BhY2V9IGZyb20ge0BsaW5rIGRhdGFicmlja3NXb3Jrc3BhY2VDb25maWd9LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRhdGFicmlja3NXb3Jrc3BhY2Uob3B0aW9uczogRGF0YWJyaWNrc1dvcmtzcGFjZU9wdGlvbnMgPSB7fSk6IFdvcmtzcGFjZSB7XG4gIGNvbnN0IHdvcmtzcGFjZSA9IG5ldyBXb3Jrc3BhY2UoZGF0YWJyaWNrc1dvcmtzcGFjZUNvbmZpZyhvcHRpb25zKSk7XG4gIGRhdGFicmlja3NXb3Jrc3BhY2VPcHRpb25zLnNldCh3b3Jrc3BhY2UsIG9wdGlvbnMpO1xuICByZXR1cm4gd29ya3NwYWNlO1xufVxuXG4vKiogQGludGVybmFsIEJpbmQgYSBjYWxsZXItY3JlYXRlZCBEYXRhYnJpY2tzIHdvcmtzcGFjZSB0byBpdHMgQXBwS2l0IHBsdWdpbiBjb250ZXh0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbmREYXRhYnJpY2tzV29ya3NwYWNlQ29udGV4dChcbiAgd29ya3NwYWNlOiBXb3Jrc3BhY2UsXG4gIHBsdWdpbkNvbnRleHQ6IHBsdWdpblJlZ2lzdHJ5LlBsdWdpbkNvbnRleHRMaWtlIHwgdW5kZWZpbmVkLFxuKTogV29ya3NwYWNlIHtcbiAgY29uc3Qgb3B0aW9ucyA9IGRhdGFicmlja3NXb3Jrc3BhY2VPcHRpb25zLmdldCh3b3Jrc3BhY2UpO1xuICBpZiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5wbHVnaW5Db250ZXh0ICE9PSB1bmRlZmluZWQgfHwgcGx1Z2luQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHdvcmtzcGFjZTtcbiAgfVxuICByZXR1cm4gZGF0YWJyaWNrc1dvcmtzcGFjZSh7IC4uLm9wdGlvbnMsIHBsdWdpbkNvbnRleHQgfSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBkZWZhdWx0IGFuZCBjYWxsZXItcHJvdmlkZWQgRGF0YWJyaWNrcyBwYXRocyBpbiBwcmlvcml0eSBvcmRlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVEYXRhYnJpY2tzV29ya3NwYWNlUGF0aHMoXG4gIG9wdGlvbnM6IFBpY2s8RGF0YWJyaWNrc1dvcmtzcGFjZU9wdGlvbnMsIFwiYXNzaXN0YW50UGF0aHNcIiB8IFwicGF0aHNcIj4gPSB7fSxcbik6IERhdGFicmlja3NXb3Jrc3BhY2VQYXRoVmFsdWVbXSB7XG4gIHJldHVybiBbXG4gICAgLi4uKG9wdGlvbnMuYXNzaXN0YW50UGF0aHMgPT09IGZhbHNlID8gW10gOiBERUZBVUxUX0RBVEFCUklDS1NfV09SS1NQQUNFX1BBVEhTKSxcbiAgICAuLi4ob3B0aW9ucy5wYXRocyA/PyBbXSksXG4gIF07XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcHJpdmF0ZSBoZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqIFJlcXVpcmUgYXBwcm92YWwgdW5sZXNzIGEgZmlsZXN5c3RlbSBtdXRhdGlvbiBzdGF5cyBpbnNpZGUgYSB1c2VyLW93bmVkIHdyaXRhYmxlIHJvb3QuICovXG5mdW5jdGlvbiByZXF1aXJlQXBwcm92YWxPdXRzaWRlV3JpdGFibGVSb290cyh7XG4gIGFyZ3MsXG4gIHJlcXVlc3RDb250ZXh0LFxufTogVG9vbENvbmZpZ1dpdGhBcmdzQ29udGV4dCk6IGJvb2xlYW4ge1xuICBjb25zdCBpbnB1dFBhdGggPSBhcmdzLnBhdGg7XG4gIGlmICh0eXBlb2YgaW5wdXRQYXRoICE9PSBcInN0cmluZ1wiIHx8ICFwb3NpeFBhdGguaXNBYnNvbHV0ZShpbnB1dFBhdGgpKSByZXR1cm4gdHJ1ZTtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHBvc2l4UGF0aC5ub3JtYWxpemUoaW5wdXRQYXRoKTtcbiAgaWYgKCFub3JtYWxpemVkLm9rKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKHBvc2l4UGF0aC5pc1dpdGhpblJvb3QoU0NSQVRDSF9NT1VOVCwgbm9ybWFsaXplZC5wYXRoKSkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBlbWFpbFZhbHVlID0gcmVxdWVzdENvbnRleHRbTUFTVFJBX1VTRVJfRU1BSUxfS0VZXTtcbiAgY29uc3QgZW1haWwgPSB0eXBlb2YgZW1haWxWYWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHN0cmluZ1V0aWxzLnRyaW1Ub051bGwoZW1haWxWYWx1ZSkgOiB1bmRlZmluZWQ7XG4gIGlmICghZW1haWwpIHJldHVybiB0cnVlO1xuICByZXR1cm4gIXBvc2l4UGF0aC5pc1dpdGhpblJvb3QocGVyc29uYWxXb3Jrc3BhY2VQYXRoKGVtYWlsKSwgbm9ybWFsaXplZC5wYXRoKTtcbn1cblxuZnVuY3Rpb24gd29ya3NwYWNlVG9vbHMoY29uZmlndXJlZDogV29ya3NwYWNlVG9vbHNDb25maWcgfCB1bmRlZmluZWQpOiBXb3Jrc3BhY2VUb29sc0NvbmZpZyB7XG4gIGNvbnN0IHJlcXVpcmVBcHByb3ZhbDogV29ya3NwYWNlVG9vbENvbmZpZyA9XG4gICAgY29uZmlndXJlZD8ucmVxdWlyZUFwcHJvdmFsID09PSB1bmRlZmluZWRcbiAgICAgID8geyByZXF1aXJlQXBwcm92YWw6IHJlcXVpcmVBcHByb3ZhbE91dHNpZGVXcml0YWJsZVJvb3RzIH1cbiAgICAgIDoge307XG4gIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgIFtXT1JLU1BBQ0VfVE9PTFMuRklMRVNZU1RFTS5XUklURV9GSUxFXTogcmVxdWlyZUFwcHJvdmFsLFxuICAgIFtXT1JLU1BBQ0VfVE9PTFMuRklMRVNZU1RFTS5FRElUX0ZJTEVdOiByZXF1aXJlQXBwcm92YWwsXG4gICAgW1dPUktTUEFDRV9UT09MUy5GSUxFU1lTVEVNLkFTVF9FRElUXTogcmVxdWlyZUFwcHJvdmFsLFxuICAgIFtXT1JLU1BBQ0VfVE9PTFMuRklMRVNZU1RFTS5ERUxFVEVdOiByZXF1aXJlQXBwcm92YWwsXG4gICAgW1dPUktTUEFDRV9UT09MUy5GSUxFU1lTVEVNLk1LRElSXTogcmVxdWlyZUFwcHJvdmFsLFxuICB9IHNhdGlzZmllcyBXb3Jrc3BhY2VUb29sc0NvbmZpZztcbiAgY29uc3QgY29uZmlndXJlZFRvb2xzID0gY29uZmlndXJlZCBhc1xuICAgIFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZVRvb2xDb25maWcgfCB1bmRlZmluZWQ+PiB8IHVuZGVmaW5lZDtcbiAgY29uc3QgbWVyZ2VkVG9vbHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgT2JqZWN0LmVudHJpZXMoZGVmYXVsdHMpLm1hcCgoW25hbWUsIGRlZmF1bHRDb25maWddKSA9PiBbXG4gICAgICBuYW1lLFxuICAgICAgeyAuLi5kZWZhdWx0Q29uZmlnLCAuLi5jb25maWd1cmVkVG9vbHM/LltuYW1lXSB9LFxuICAgIF0pLFxuICApO1xuICByZXR1cm4ge1xuICAgIC4uLmRlZmF1bHRzLFxuICAgIC4uLmNvbmZpZ3VyZWQsXG4gICAgLi4ubWVyZ2VkVG9vbHMsXG4gIH07XG59XG5mdW5jdGlvbiByZXNvbHZlV29ya3NwYWNlU2FuZGJveChcbiAgc2VsZWN0aW9uOiBXb3Jrc3BhY2VTYW5kYm94U2VsZWN0aW9uIHwgdW5kZWZpbmVkLFxuICB3b3Jrc3BhY2VJZDogc3RyaW5nLFxuICB3b3Jrc3BhY2VOYW1lOiBzdHJpbmcsXG4pOiBXb3Jrc3BhY2VTYW5kYm94IHwgV29ya3NwYWNlU2FuZGJveFJlc29sdmVyIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgY29uZmlndXJlZCA9IHNlbGVjdGlvbiA/PyBcIm1vbnR5XCI7XG4gIGlmIChjb25maWd1cmVkID09PSBmYWxzZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKGNvbmZpZ3VyZWQgPT09IFwibW9udHlcIikgcmV0dXJuIG5ldyBNb250eVNhbmRib3goKTtcbiAgaWYgKHR5cGVvZiBjb25maWd1cmVkID09PSBcImZ1bmN0aW9uXCIgfHwgaXNTYW5kYm94KGNvbmZpZ3VyZWQpKSByZXR1cm4gY29uZmlndXJlZDtcblxuICBjb25zdCBvcHRpb25zOiBEYXRhYnJpY2tzV29ya3NwYWNlU2FuZGJveE9wdGlvbnMgPVxuICAgIGNvbmZpZ3VyZWQgPT09IFwiZGF0YWJyaWNrc1wiID8geyBwcm92aWRlcjogXCJkYXRhYnJpY2tzXCIgfSA6IGNvbmZpZ3VyZWQ7XG4gIHJldHVybiAoeyByZXF1ZXN0Q29udGV4dCB9KSA9PiB7XG4gICAgY29uc3QgdXNlciA9IHJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfVVNFUl9LRVkpIGFzIFVzZXIgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBDb25maWd1cmF0aW9uRXJyb3IucmVzb3VyY2VOb3RGb3VuZChcbiAgICAgICAgXCJEYXRhYnJpY2tzIHNhbmRib3ggdXNlciBjb250ZXh0XCIsXG4gICAgICAgIFwiSW52b2tlIGNvbW1hbmQgdG9vbHMgZnJvbSBhbiBhZ2VudCB0dXJuIHNlcnZlZCBieSB0aGUgTWFzdHJhIHBsdWdpbi5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZ3VyZWRJZCA9XG4gICAgICB0eXBlb2Ygb3B0aW9ucy5zYW5kYm94SWQgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IG9wdGlvbnMuc2FuZGJveElkKHsgcmVxdWVzdENvbnRleHQgfSlcbiAgICAgICAgOiBvcHRpb25zLnNhbmRib3hJZDtcbiAgICBjb25zdCBzYW5kYm94SWQgPSBjb25maWd1cmVkSWQgPz8gZGVmYXVsdFNhbmRib3hJZCh3b3Jrc3BhY2VJZCwgdXNlci5pZCk7XG4gICAgY29uc3QgY2xpZW50ID1cbiAgICAgIHR5cGVvZiBvcHRpb25zLmNsaWVudCA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gb3B0aW9ucy5jbGllbnQoeyByZXF1ZXN0Q29udGV4dCB9KVxuICAgICAgICA6IChvcHRpb25zLmNsaWVudCA/PyBjcmVhdGVXb3Jrc3BhY2VDbGllbnQoKSk7XG4gICAgY29uc3Qge1xuICAgICAgcHJvdmlkZXI6IF9wcm92aWRlcixcbiAgICAgIHNhbmRib3hJZDogX3NhbmRib3hJZCxcbiAgICAgIGNsaWVudDogX2NsaWVudCxcbiAgICAgIC4uLnNhbmRib3hPcHRpb25zXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgcmV0dXJuIG5ldyBEYXRhYnJpY2tzU2FuZGJveCh7XG4gICAgICAuLi5zYW5kYm94T3B0aW9ucyxcbiAgICAgIGNsaWVudCxcbiAgICAgIHNhbmRib3hJZCxcbiAgICAgIGRpc3BsYXlOYW1lOiBvcHRpb25zLmRpc3BsYXlOYW1lID8/IGBNYXN0cmEgJHt3b3Jrc3BhY2VOYW1lfWAsXG4gICAgfSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRTYW5kYm94SWQod29ya3NwYWNlSWQ6IHN0cmluZywgdXNlcklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBkaWdlc3QgPSBjcmVhdGVIYXNoKFwic2hhMjU2XCIpXG4gICAgLnVwZGF0ZShvYmplY3QudG9TdGFibGVLZXkoeyB3b3Jrc3BhY2VJZCwgdXNlcklkIH0pKVxuICAgIC5kaWdlc3QoXCJoZXhcIilcbiAgICAuc2xpY2UoMCwgMzIpO1xuICByZXR1cm4gYG1hc3RyYS0ke2RpZ2VzdH1gO1xufVxuXG5mdW5jdGlvbiBpc1NhbmRib3godmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBXb3Jrc3BhY2VTYW5kYm94IHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIFwiaWRcIiBpbiB2YWx1ZSAmJiBcInByb3ZpZGVyXCIgaW4gdmFsdWUgJiYgXCJzdGF0dXNcIiBpbiB2YWx1ZSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2FuZGJveE5hbWUoc2VsZWN0aW9uOiBXb3Jrc3BhY2VTYW5kYm94U2VsZWN0aW9uIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgaWYgKHNlbGVjdGlvbiA9PT0gdW5kZWZpbmVkIHx8IHNlbGVjdGlvbiA9PT0gXCJtb250eVwiKSByZXR1cm4gXCJtb250eVwiO1xuICBpZiAoc2VsZWN0aW9uID09PSBcImRhdGFicmlja3NcIikgcmV0dXJuIFwiZGF0YWJyaWNrc1wiO1xuICBpZiAoc2VsZWN0aW9uID09PSBmYWxzZSkgcmV0dXJuIFwiZGlzYWJsZWRcIjtcbiAgaWYgKHR5cGVvZiBzZWxlY3Rpb24gPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFwicmVzb2x2ZXJcIjtcbiAgcmV0dXJuIGlzU2FuZGJveChzZWxlY3Rpb24pID8gc2VsZWN0aW9uLnByb3ZpZGVyIDogKHNlbGVjdGlvbi5wcm92aWRlciA/PyBcImRhdGFicmlja3NcIik7XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgdGhlIHJlcXVlc3QgdG9rZW4gY2FycmllcyBhIHNjb3BlIHRoYXQgYWxsb3dzIHdvcmtzcGFjZVxuICogZmlsZSBBUEkgYWNjZXNzIChgd29ya3NwYWNlYCBvciBgYWxsLWFwaXNgIG9uIHtAbGluayBNQVNUUkFfU0NPUEVTX0tFWX0pLlxuICovXG5mdW5jdGlvbiBoYXNXb3Jrc3BhY2VGaWxlU2NvcGUocmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0IHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiB0b2tlbi5pbmNsdWRlc0FjY2Vzc1Rva2VuU2NvcGUoXG4gICAgcmVxdWVzdENvbnRleHQ/LmdldChNQVNUUkFfU0NPUEVTX0tFWSksXG4gICAgV09SS1NQQUNFX0ZJTEVfU0NPUEVTLFxuICApO1xufVxuXG4vKiogUmVzb2x2ZSB0aGUgcmVxdWVzdCBjbGllbnQgYW5kIGF1dGhvcml6YXRpb24tc2FmZSBmaWxlcy1jYWNoZSBzY29wZS4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVGaWxlc0NhY2hlU2NvcGUoY29udGV4dDogRGF0YWJyaWNrc1dvcmtzcGFjZUNvbnRleHQpOiBQcm9taXNlPFxuICB8IHtcbiAgICAgIGNsaWVudDogV29ya3NwYWNlQ2xpZW50O1xuICAgICAgc2NvcGU6IEZpbGVzQ2FjaGVTY29wZTtcbiAgICB9XG4gIHwgdW5kZWZpbmVkXG4+IHtcbiAgY29uc3QgcmVxdWVzdENvbnRleHQgPSBjb250ZXh0LnJlcXVlc3RDb250ZXh0O1xuICBjb25zdCB1c2VyID0gcmVxdWVzdENvbnRleHQ/LmdldChNQVNUUkFfVVNFUl9LRVkpIGFzIFVzZXIgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IGNsaWVudCA9IHVzZXI/LmV4ZWN1dGlvbkNvbnRleHQuY2xpZW50IGFzIFdvcmtzcGFjZUNsaWVudCB8IHVuZGVmaW5lZDtcbiAgaWYgKCFyZXF1ZXN0Q29udGV4dCB8fCAhdXNlciB8fCAhY2xpZW50KSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIGNsaWVudCxcbiAgICBzY29wZToge1xuICAgICAgaG9zdDogKGF3YWl0IGNsaWVudC5jb25maWcuZ2V0SG9zdCgpKS50b1N0cmluZygpLFxuICAgICAgdXNlcktleTogcmVzb2x2ZVVzZXJLZXkocmVxdWVzdENvbnRleHQpLFxuICAgICAgLi4uKHByb2Nlc3MuZW52LkRBVEFCUklDS1NfV09SS1NQQUNFX0lEPy50cmltKClcbiAgICAgICAgPyB7IHdvcmtzcGFjZUlkOiBwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX1dPUktTUEFDRV9JRC50cmltKCkgfVxuICAgICAgICA6IHt9KSxcbiAgICB9LFxuICB9O1xufVxuXG4vKiogSm9pbiBvbmUgcmVsYXRpdmUgc2tpbGwgcm9vdCB0byBpdHMgYWN0dWFsIGNvbXBvc2l0ZSBtb3VudCBwYXRoLiAqL1xuZnVuY3Rpb24gbW91bnRlZFNraWxsUGF0aChtb3VudDogc3RyaW5nLCBza2lsbFJvb3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChwb3NpeFBhdGguaXNBYnNvbHV0ZShza2lsbFJvb3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgU2tpbGwgcGF0aCBtdXN0IGJlIHJlbGF0aXZlIHRvIGl0cyBtb3VudDogJHtza2lsbFJvb3R9YCk7XG4gIH1cbiAgY29uc3Qgbm9ybWFsaXplZCA9IHBvc2l4UGF0aC5ub3JtYWxpemUoc2tpbGxSb290KTtcbiAgaWYgKCFub3JtYWxpemVkLm9rKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgU2tpbGwgcGF0aCBlc2NhcGVzIGl0cyBtb3VudDogJHtza2lsbFJvb3R9YCk7XG4gIH1cbiAgcmV0dXJuIHBvc2l4UGF0aC5qb2luKHBvc2l4UGF0aC5ub3JtYWxpemVSb290KG1vdW50KSwgbm9ybWFsaXplZC5wYXRoLnNsaWNlKDEpKTtcbn1cblxuLyoqIFJldHVybiB3aGV0aGVyIGEgRGF0YWJyaWNrcyBwYXRoIGJlbG9uZ3MgdG8gdGhlIHdyaXRhYmxlIFdvcmtzcGFjZSBuYW1lc3BhY2UuICovXG5mdW5jdGlvbiBpc1dvcmtzcGFjZVJvb3Qocm9vdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBwb3NpeFBhdGgubm9ybWFsaXplUm9vdChyb290KTtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQgPT09IFwiL1dvcmtzcGFjZVwiIHx8IG5vcm1hbGl6ZWQuc3RhcnRzV2l0aChcIi9Xb3Jrc3BhY2UvXCIpO1xufVxuXG4vKipcbiAqIE1vdW50IHJlc29sdmVyIGZvciB0aGUgbmFtZWQgc2tpbGwgZm9sZGVycy5cbiAqXG4gKiBHYXRlcyBvbiB3b3Jrc3BhY2UgZmlsZSBzY29wZSAob3IgZGV2ZWxvcG1lbnQgbW9kZSksIHRoZW4gbW91bnRzIGV2ZXJ5XG4gKiBmb2xkZXIgd2hvc2UgbG9jYXRpb24gcmVzb2x2ZXMgZm9yIHRoaXMgcmVxdWVzdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVyTW91bnRzKFxuICBwYXRoczogcmVhZG9ubHkgRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGhWYWx1ZVtdLFxuICBjb250ZXh0OiBEYXRhYnJpY2tzV29ya3NwYWNlQ29udGV4dCxcbiAgZmlsZXNDYWNoZTogRmlsZXNDYWNoZUV4cG9ydHMgfCB1bmRlZmluZWQsXG4gIGNhY2hlQ29uZmlnOiBEYXRhYnJpY2tzV29ya3NwYWNlQ2FjaGUgfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPiB7XG4gIGNvbnN0IG1vdW50czogUmVjb3JkPHN0cmluZywgV29ya3NwYWNlRmlsZXN5c3RlbT4gPSB7fTtcbiAgY29uc3Qgc2tpbGxQYXRoczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgcmVxdWVzdENvbnRleHQgPSBjb250ZXh0LnJlcXVlc3RDb250ZXh0O1xuXG4gIGNvbnN0IGNhbk1vdW50RGF0YWJyaWNrcyA9IEJvb2xlYW4ocmVxdWVzdENvbnRleHQgJiYgc2hvdWxkTW91bnRTa2lsbEZvbGRlcnMocmVxdWVzdENvbnRleHQpKTtcbiAgY29uc3Qgc2NvcGVkID0gY2FuTW91bnREYXRhYnJpY2tzID8gYXdhaXQgcmVzb2x2ZUZpbGVzQ2FjaGVTY29wZShjb250ZXh0KSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgY2xpZW50ID0gc2NvcGVkPy5jbGllbnQ7XG4gIGNvbnN0IGZpbGVTeXN0ZW1DYWNoZSA9XG4gICAgZmlsZXNDYWNoZSAmJiBzY29wZWQgPyBhd2FpdCBmaWxlc0NhY2hlLmZvclNjb3BlKHNjb3BlZC5zY29wZSkgOiB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBbaW5kZXgsIHBhdGhdIG9mIHBhdGhzLmVudHJpZXMoKSkge1xuICAgIGNvbnN0IGNvbmZpZ3VyZWQgPSBhd2FpdCByZXNvbHZlRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGgocGF0aCwgY29udGV4dCk7XG4gICAgaWYgKCFjb25maWd1cmVkKSBjb250aW51ZTtcbiAgICBpZiAocG9zaXhQYXRoLmlzV2l0aGluUm9vdChTQ1JBVENIX01PVU5ULCBjb25maWd1cmVkLnBhdGgpKSB7XG4gICAgICBjb25zdCBtb3VudCA9IGNvbmZpZ3VyZWQubW91bnQgPz8gY29uZmlndXJlZC5wYXRoO1xuICAgICAgbW91bnRzW21vdW50XSA9IHVzZXJUZW1wRmlsZXN5c3RlbShjb250ZXh0LCBjb25maWd1cmVkLnBhdGgpO1xuICAgICAgaWYgKGNvbmZpZ3VyZWQucmVhZGFibGUgIT09IGZhbHNlKSB7XG4gICAgICAgIHNraWxsUGF0aHMucHVzaChcbiAgICAgICAgICAuLi4oY29uZmlndXJlZC5za2lsbHMgPz8gW10pLm1hcCgocGF0aCkgPT4gbW91bnRlZFNraWxsUGF0aChtb3VudCwgcGF0aCkpLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICghY2FuTW91bnREYXRhYnJpY2tzKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJ3b3Jrc3BhY2UtcGF0aDpza2lwcGVkXCIsIHtcbiAgICAgICAgcGF0aDogY29uZmlndXJlZC5wYXRoLFxuICAgICAgICByZWFzb246ICFyZXF1ZXN0Q29udGV4dCA/IFwibm8tcmVxdWVzdC1jb250ZXh0XCIgOiBcIm1pc3Npbmctd29ya3NwYWNlLXNjb3BlXCIsXG4gICAgICB9KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCByZXNvbHZlZCA9IGF3YWl0IHJlc29sdmVTa2lsbEZvbGRlckZpbGVzeXN0ZW0oY29uZmlndXJlZCwgY29udGV4dCwgY2FjaGVDb25maWcsIHtcbiAgICAgIGNsaWVudCxcbiAgICAgIGZpbGVTeXN0ZW1DYWNoZSxcbiAgICB9KTtcbiAgICBpZiAoIXJlc29sdmVkKSBjb250aW51ZTtcbiAgICBjb25zdCBtb3VudCA9IGNvbmZpZ3VyZWQubW91bnQgPz8gcmVzb2x2ZWQucm9vdDtcbiAgICBpZiAoIW1vdW50KSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJ3b3Jrc3BhY2UtcGF0aDpza2lwcGVkXCIsIHsgaW5kZXgsIHJlYXNvbjogXCJtaXNzaW5nLW1vdW50XCIgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbW91bnRzW21vdW50XSA9IHJlc29sdmVkLmZpbGVzeXN0ZW07XG4gICAgaWYgKGNvbmZpZ3VyZWQucmVhZGFibGUgIT09IGZhbHNlKSB7XG4gICAgICBza2lsbFBhdGhzLnB1c2goLi4uKGNvbmZpZ3VyZWQuc2tpbGxzID8/IFtcIi5cIl0pLm1hcCgocGF0aCkgPT4gbW91bnRlZFNraWxsUGF0aChtb3VudCwgcGF0aCkpKTtcbiAgICB9XG4gIH1cblxuICBsb2dnZXIuZGVidWcoXCJza2lsbC1mb2xkZXJzOm1vdW50ZWRcIiwge1xuICAgIG1vdW50S2V5czogT2JqZWN0LmtleXMobW91bnRzKSxcbiAgICBza2lsbFBhdGhzLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIG1vdW50cyxcbiAgICBza2lsbFBhdGhzLFxuICB9O1xufVxuXG5pbnRlcmZhY2UgUmVzb2x2ZWREYXRhYnJpY2tzV29ya3NwYWNlUGF0aCB7XG4gIHBhdGg6IHN0cmluZztcbiAgZGlzcGxheU5hbWU/OiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICByZWFkYWJsZT86IGJvb2xlYW47XG4gIHNraWxscz86IHJlYWRvbmx5IHN0cmluZ1tdO1xuICB3cml0YWJsZT86IGJvb2xlYW47XG4gIGNyZWF0ZVJvb3Q/OiBib29sZWFuO1xuICBtb3VudD86IHN0cmluZztcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZURhdGFicmlja3NXb3Jrc3BhY2VQYXRoKFxuICB2YWx1ZTogRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGhWYWx1ZSxcbiAgY29udGV4dDogRGF0YWJyaWNrc1dvcmtzcGFjZUNvbnRleHQsXG4pOiBQcm9taXNlPFJlc29sdmVkRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGggfCB1bmRlZmluZWQ+IHtcbiAgY29uc3Qgc2VsZWN0ZWQgPSB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIiA/IGF3YWl0IHZhbHVlKGNvbnRleHQpIDogdmFsdWU7XG4gIGlmIChzZWxlY3RlZCA9PT0gZmFsc2UgfHwgc2VsZWN0ZWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgY29uZmlndXJlZCA9IHR5cGVvZiBzZWxlY3RlZCA9PT0gXCJzdHJpbmdcIiA/IHsgcGF0aDogc2VsZWN0ZWQgfSA6IHNlbGVjdGVkO1xuICBjb25zdCByZXF1ZXN0Q29udGV4dCA9IHJlcXVlc3RDb250ZXh0VmFsdWVzKGNvbnRleHQucmVxdWVzdENvbnRleHQpO1xuICBjb25zdCByZXNvbHZlZFBhdGggPSByZXNvbHZlSG9tZVBhdGgoY29uZmlndXJlZC5wYXRoLCByZXF1ZXN0Q29udGV4dCk7XG4gIGlmICghcmVzb2x2ZWRQYXRoKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCByZXNvbHZlZE1vdW50ID0gcmVzb2x2ZUhvbWVQYXRoKGNvbmZpZ3VyZWQubW91bnQsIHJlcXVlc3RDb250ZXh0KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5jb25maWd1cmVkLFxuICAgIHBhdGg6IHJlc29sdmVkUGF0aCxcbiAgICAuLi4ocmVzb2x2ZWRNb3VudCA/IHsgbW91bnQ6IHJlc29sdmVkTW91bnQgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIG9uZSBza2lsbCBmb2xkZXIgdG8gYSBNYXN0cmEgZmlsZXN5c3RlbSwgb3IgYHVuZGVmaW5lZGAgdG8gc2tpcCBpdFxuICogZm9yIHRoaXMgcmVxdWVzdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVyRmlsZXN5c3RlbShcbiAgZm9sZGVyOiBSZXNvbHZlZERhdGFicmlja3NXb3Jrc3BhY2VQYXRoLFxuICBjb250ZXh0OiBEYXRhYnJpY2tzV29ya3NwYWNlQ29udGV4dCxcbiAgY2FjaGVDb25maWc6IERhdGFicmlja3NXb3Jrc3BhY2VDYWNoZSB8IHVuZGVmaW5lZCxcbiAgY2FjaGU6IHtcbiAgICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCB8IHVuZGVmaW5lZDtcbiAgICBmaWxlU3lzdGVtQ2FjaGU6IEZpbGVTeXN0ZW1DYWNoZSB8IHVuZGVmaW5lZDtcbiAgfSxcbik6IFByb21pc2U8XG4gIHwge1xuICAgICAgZmlsZXN5c3RlbTogV29ya3NwYWNlRmlsZXN5c3RlbTtcbiAgICAgIHJvb3Q/OiBzdHJpbmc7XG4gICAgfVxuICB8IHVuZGVmaW5lZFxuPiB7XG4gIC8vIEEgcGF0aCBtb3VudCBuZWVkcyB0aGUgcmVxdWVzdCdzIE9CTyBjbGllbnQgdG8gcmVhY2ggdGhlIHdvcmtzcGFjZS5cbiAgaWYgKCFjYWNoZS5jbGllbnQpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJza2lsbC1mb2xkZXI6c2tpcHBlZFwiLCB7XG4gICAgICBwYXRoOiBmb2xkZXIucGF0aCxcbiAgICAgIHJlYXNvbjogXCJtaXNzaW5nLW9iby1jbGllbnRcIixcbiAgICB9KTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJvb3QgPSBzdHJpbmdVdGlscy50cmltVG9OdWxsKGZvbGRlci5wYXRoKTtcbiAgaWYgKCFyb290KSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCB3cml0YWJsZSA9IGZvbGRlci53cml0YWJsZSA/PyBpc1dvcmtzcGFjZVJvb3Qocm9vdCk7XG4gIGNvbnN0IGNhY2hlT3B0aW9ucyA9IGNhY2hlLmZpbGVTeXN0ZW1DYWNoZVxuICAgID8gYXdhaXQgcmVzb2x2ZUZpbGVDYWNoZU9wdGlvbnMoXG4gICAgICAgIGNhY2hlQ29uZmlnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICByb290LFxuICAgICAgICBmb2xkZXIucmVhZGFibGUgPT09IGZhbHNlID8gW10gOiAoZm9sZGVyLnNraWxscyA/PyBbXCIuXCJdKSxcbiAgICAgIClcbiAgICA6IHVuZGVmaW5lZDtcbiAgY29uc3QgcmVzb2x2ZWQgPSBhd2FpdCBkYXRhYnJpY2tzRmlsZXN5c3RlbShcbiAgICBjYWNoZS5jbGllbnQsXG4gICAgcm9vdCxcbiAgICAhd3JpdGFibGUsXG4gICAgZm9sZGVyLmNyZWF0ZVJvb3QgPz8gZm9sZGVyLndyaXRhYmxlID09PSB0cnVlLFxuICAgIGNhY2hlLmZpbGVTeXN0ZW1DYWNoZSxcbiAgICBjYWNoZU9wdGlvbnMsXG4gICAge1xuICAgICAgLi4uKGZvbGRlci5kZXNjcmlwdGlvbiA/IHsgZGVzY3JpcHRpb246IGZvbGRlci5kZXNjcmlwdGlvbiB9IDoge30pLFxuICAgICAgLi4uKGZvbGRlci5kaXNwbGF5TmFtZSA/IHsgZGlzcGxheU5hbWU6IGZvbGRlci5kaXNwbGF5TmFtZSB9IDoge30pLFxuICAgIH0sXG4gICk7XG4gIHJldHVybiByZXNvbHZlZCA/IHsgLi4ucmVzb2x2ZWQsIHJvb3QgfSA6IHVuZGVmaW5lZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUNhY2hlQ29uZmlnKFxuICB2YWx1ZTogRGF0YWJyaWNrc1dvcmtzcGFjZUNhY2hlIHwgdW5kZWZpbmVkLFxuICBjb250ZXh0OiBEYXRhYnJpY2tzV29ya3NwYWNlQ29udGV4dCxcbik6IFByb21pc2U8XG4gIHwgYm9vbGVhblxuICB8IERhdGFicmlja3NXb3Jrc3BhY2VDYWNoZUZpbHRlclxuICB8IHJlYWRvbmx5IERhdGFicmlja3NXb3Jrc3BhY2VDYWNoZUZpbHRlcltdXG4gIHwgdW5kZWZpbmVkXG4+IHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgPyB2YWx1ZShjb250ZXh0KVxuICAgIDogdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RDb250ZXh0VmFsdWVzKHJlcXVlc3RDb250ZXh0OiBSZXF1ZXN0Q29udGV4dCB8IHVuZGVmaW5lZCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIHJlcXVlc3RDb250ZXh0Py50b0pTT04oKSA/PyB7fTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUhvbWVQYXRoKFxuICBpbnB1dDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICByZXF1ZXN0Q29udGV4dDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCB2YWx1ZSA9IHN0cmluZ1V0aWxzLnRyaW1Ub051bGwoaW5wdXQpO1xuICBpZiAoIXZhbHVlIHx8ICh2YWx1ZSAhPT0gXCJ+XCIgJiYgIXZhbHVlLnN0YXJ0c1dpdGgoXCJ+L1wiKSkpIHJldHVybiB2YWx1ZSA/PyB1bmRlZmluZWQ7XG4gIGNvbnN0IGVtYWlsVmFsdWUgPSByZXF1ZXN0Q29udGV4dFtNQVNUUkFfVVNFUl9FTUFJTF9LRVldO1xuICBjb25zdCBlbWFpbCA9IHR5cGVvZiBlbWFpbFZhbHVlID09PSBcInN0cmluZ1wiID8gc3RyaW5nVXRpbHMudHJpbVRvTnVsbChlbWFpbFZhbHVlKSA6IHVuZGVmaW5lZDtcbiAgaWYgKCFlbWFpbCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgaG9tZSA9IHBlcnNvbmFsV29ya3NwYWNlUGF0aChlbWFpbCk7XG4gIHJldHVybiB2YWx1ZSA9PT0gXCJ+XCIgPyBob21lIDogYCR7aG9tZX0vJHt2YWx1ZS5zbGljZSgyKX1gO1xufVxuXG5mdW5jdGlvbiB0b1BvbGljeUFycmF5PFQ+KHZhbHVlOiBUIHwgcmVhZG9ubHkgVFtdIHwgdW5kZWZpbmVkKTogcmVhZG9ubHkgVFtdIHtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBbXTtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpID8gKHZhbHVlIGFzIHJlYWRvbmx5IFRbXSkgOiBbdmFsdWUgYXMgVF07XG59XG5cbmZ1bmN0aW9uIGNhY2hlRmlsdGVyTWF0Y2hlcyhcbiAgcG9saWN5OiBEYXRhYnJpY2tzV29ya3NwYWNlQ2FjaGVGaWx0ZXIsXG4gIG9wZXJhdGlvbjogQ2FjaGVhYmxlRmlsZVN5c3RlbU9wZXJhdGlvbixcbiAgcGF0aDogc3RyaW5nLFxuICByZXF1ZXN0Q29udGV4dDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHJvb3Q/OiBzdHJpbmcsXG4pOiBib29sZWFuIHtcbiAgY29uc3Qgb3BlcmF0aW9ucyA9IHRvUG9saWN5QXJyYXkocG9saWN5Lm9wZXJhdGlvbnMgPz8gQ0FDSEVBQkxFX0ZJTEVTWVNURU1fT1BFUkFUSU9OUyk7XG4gIGlmICghb3BlcmF0aW9ucy5pbmNsdWRlcyhvcGVyYXRpb24pKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwb2xpY3kucGF0aHMgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRydWU7XG4gIGNvbnN0IGlucHV0czogUGF0aE1hdGNoSW5wdXRbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGlucHV0IG9mIHRvUG9saWN5QXJyYXk8UGF0aE1hdGNoSW5wdXQ+KHBvbGljeS5wYXRocykpIHtcbiAgICBpZiAodHlwZW9mIGlucHV0ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICBpbnB1dHMucHVzaChpbnB1dCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgZXhwYW5kZWQgPSByZXNvbHZlSG9tZVBhdGgoaW5wdXQsIHJlcXVlc3RDb250ZXh0KTtcbiAgICBpZiAoIWV4cGFuZGVkKSBjb250aW51ZTtcbiAgICBpbnB1dHMucHVzaChcbiAgICAgICFyb290IHx8IHBvc2l4UGF0aC5pc0Fic29sdXRlKGV4cGFuZGVkKSB8fCBleHBhbmRlZC5zdGFydHNXaXRoKFwiKipcIilcbiAgICAgICAgPyBleHBhbmRlZFxuICAgICAgICA6IGAke3Bvc2l4UGF0aC5ub3JtYWxpemVSb290KHJvb3QpfS8ke2V4cGFuZGVkLnJlcGxhY2UoL15cXC5cXC8vLCBcIlwiKX1gLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGlucHV0cy5sZW5ndGggPiAwICYmIG1hdGNoLnRvUGF0aE1hdGNoZXIoLi4uaW5wdXRzKShwYXRoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUZpbGVDYWNoZU9wdGlvbnMoXG4gIGNvbmZpZ3VyZWQ6IERhdGFicmlja3NXb3Jrc3BhY2VDYWNoZSB8IHVuZGVmaW5lZCxcbiAgY29udGV4dDogRGF0YWJyaWNrc1dvcmtzcGFjZUNvbnRleHQsXG4gIHJvb3Q6IHN0cmluZyxcbiAgc2tpbGxQYXRoczogcmVhZG9ubHkgc3RyaW5nW10sXG4pOiBQcm9taXNlPEZpbGVTeXN0ZW1DYWNoZU9wdGlvbnMgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgcmVxdWVzdENvbnRleHQgPSByZXF1ZXN0Q29udGV4dFZhbHVlcyhjb250ZXh0LnJlcXVlc3RDb250ZXh0KTtcbiAgY29uc3QgcmVzb2x2ZWQgPSBhd2FpdCByZXNvbHZlQ2FjaGVDb25maWcoY29uZmlndXJlZCwgY29udGV4dCk7XG4gIGlmIChyZXNvbHZlZCA9PT0gZmFsc2UpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChyZXNvbHZlZCA9PT0gdW5kZWZpbmVkIHx8IHJlc29sdmVkID09PSB0cnVlKSB7XG4gICAgY29uc3Qgcm9vdHMgPSBza2lsbFBhdGhzLm1hcCgocGF0aCkgPT4gbW91bnRlZFNraWxsUGF0aChyb290LCBwYXRoKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wZXJhdGlvbnM6IENBQ0hFQUJMRV9GSUxFU1lTVEVNX09QRVJBVElPTlMsXG4gICAgICBmaWx0ZXI6IChvcGVyYXRpb24sIHBhdGgpID0+XG4gICAgICAgIG9wZXJhdGlvbiAhPT0gXCJyZWFkRmlsZVwiIHx8XG4gICAgICAgIHJvb3RzLnNvbWUoKHNraWxsUm9vdCkgPT4gcG9zaXhQYXRoLmlzV2l0aGluUm9vdChza2lsbFJvb3QsIHBhdGgpKSxcbiAgICB9O1xuICB9XG4gIGNvbnN0IHBvbGljaWVzID0gdG9Qb2xpY3lBcnJheShyZXNvbHZlZCk7XG4gIGlmIChwb2xpY2llcy5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IG9wZXJhdGlvbnMgPSBbXG4gICAgLi4ubmV3IFNldChcbiAgICAgIHBvbGljaWVzLmZsYXRNYXAoKHBvbGljeSkgPT5cbiAgICAgICAgdG9Qb2xpY3lBcnJheShwb2xpY3kub3BlcmF0aW9ucyA/PyBDQUNIRUFCTEVfRklMRVNZU1RFTV9PUEVSQVRJT05TKSxcbiAgICAgICksXG4gICAgKSxcbiAgXTtcbiAgcmV0dXJuIHtcbiAgICBvcGVyYXRpb25zLFxuICAgIGZpbHRlcjogKG9wZXJhdGlvbiwgcGF0aCkgPT5cbiAgICAgIHBvbGljaWVzLnNvbWUoKHBvbGljeSkgPT5cbiAgICAgICAgY2FjaGVGaWx0ZXJNYXRjaGVzKFxuICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICBvcGVyYXRpb24sXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICByZXF1ZXN0Q29udGV4dCxcbiAgICAgICAgICByb290LFxuICAgICAgICApLFxuICAgICAgKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBGaWxsIGluIGBpZGAgYW5kIGBuYW1lYCB3aGVuIGVpdGhlciBpcyBvbWl0dGVkIG9uIHtAbGluayBEYXRhYnJpY2tzV29ya3NwYWNlT3B0aW9uc30uXG4gKiBTbHVnaWZpZXMgYG5hbWVgIGludG8gYGlkYDsgdG9rZW5pemVzIGBpZGAgaW50byBhIGRpc3BsYXkgYG5hbWVgLlxuICovXG5mdW5jdGlvbiByZXNvbHZlV29ya3NwYWNlSWRlbnRpdHkob3B0aW9uczogRGF0YWJyaWNrc1dvcmtzcGFjZU9wdGlvbnMpOiB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbn0ge1xuICBsZXQgaWQgPSBvcHRpb25zLmlkO1xuICBsZXQgbmFtZSA9IG9wdGlvbnMubmFtZTtcbiAgaWYgKCFpZCkge1xuICAgIGlkID0gbmFtZSA/IHN0cmluZ1V0aWxzLnRvU2x1ZyhuYW1lKSA6IFwid29ya3NwYWNlXCI7XG4gIH1cbiAgaWYgKCFuYW1lKSB7XG4gICAgbmFtZSA9IEFycmF5LmZyb20oc3RyaW5nVXRpbHMudG9rZW5pemUoaWQpKS5qb2luKFwiIFwiKTtcbiAgfVxuICByZXR1cm4geyBpZCwgbmFtZSB9O1xufVxuXG4vKiogQ29sbGVjdCB0aGUgc2tpbGwtZm9sZGVyIHJlc29sdmVyIGFuZCBhbnkgY2FsbGVyLXN1cHBsaWVkIG9uZXMuICovXG5mdW5jdGlvbiBidWlsZE1vdW50UmVzb2x2ZXJzKFxuICBwYXRoczogcmVhZG9ubHkgRGF0YWJyaWNrc1dvcmtzcGFjZVBhdGhWYWx1ZVtdLFxuICBtb3VudHM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUZpbGVzeXN0ZW0+IHwgdW5kZWZpbmVkLFxuICBsb2NhbE1vdW50czogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdLFxuICBmaWxlc0NhY2hlOiBGaWxlc0NhY2hlRXhwb3J0cyB8IHVuZGVmaW5lZCxcbiAgY2FjaGVDb25maWc6IERhdGFicmlja3NXb3Jrc3BhY2VDYWNoZSB8IHVuZGVmaW5lZCxcbik6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSB7XG4gIGNvbnN0IHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdID0gW107XG4gIGNvbnN0IHBhdGhDb3VudCA9IHBhdGhzLmxlbmd0aDtcbiAgaWYgKHBhdGhDb3VudCA+IDApIHtcbiAgICByZXNvbHZlcnMucHVzaCgoY29udGV4dCkgPT5cbiAgICAgIHJlc29sdmVTa2lsbEZvbGRlck1vdW50cyhwYXRocywgY29udGV4dCwgZmlsZXNDYWNoZSwgY2FjaGVDb25maWcpLFxuICAgICk7XG4gIH1cbiAgaWYgKG1vdW50cyAmJiBPYmplY3Qua2V5cyhtb3VudHMpLmxlbmd0aCA+IDApIHJlc29sdmVycy5wdXNoKCgpID0+ICh7IG1vdW50cyB9KSk7XG4gIHJlc29sdmVycy5wdXNoKC4uLmxvY2FsTW91bnRzKTtcbiAgbG9nZ2VyLmRlYnVnKFwibW91bnRzOnJlc29sdmVyc1wiLCB7XG4gICAgcGF0aENvdW50LFxuICAgIGN1c3RvbU1vdW50Q291bnQ6IE9iamVjdC5rZXlzKG1vdW50cyA/PyB7fSkubGVuZ3RoLFxuICAgIGxvY2FsTW91bnRDb3VudDogbG9jYWxNb3VudHMubGVuZ3RoLFxuICAgIHRvdGFsUmVzb2x2ZXJDb3VudDogcmVzb2x2ZXJzLmxlbmd0aCxcbiAgfSk7XG4gIHJldHVybiByZXNvbHZlcnM7XG59XG5cbi8qKiBTdGFibGUgdXNlci1zY29wZWQgbG9jYWwgc3RvcmFnZSB1bmRlciB0aGUgaG9zdCBvcGVyYXRpbmcgc3lzdGVtJ3MgdGVtcCBkaXJlY3RvcnkuICovXG5mdW5jdGlvbiB1c2VyVGVtcEZpbGVzeXN0ZW0oXG4gIGNvbnRleHQ6IERhdGFicmlja3NXb3Jrc3BhY2VDb250ZXh0LFxuICB3b3Jrc3BhY2VQYXRoOiBzdHJpbmcsXG4pOiBXb3Jrc3BhY2VGaWxlc3lzdGVtIHtcbiAgY29uc3QgdXNlcktleSA9IHJlc29sdmVVc2VyS2V5KGNvbnRleHQucmVxdWVzdENvbnRleHQpO1xuICBjb25zdCBkaWdlc3QgPSBjcmVhdGVIYXNoKFwic2hhMjU2XCIpXG4gICAgLnVwZGF0ZShvYmplY3QudG9TdGFibGVLZXkoeyBwYWNrYWdlOiBcIkBkYngtdG9vbHMvYXBwa2l0LW1hc3RyYVwiLCB1c2VyS2V5IH0pKVxuICAgIC5kaWdlc3QoXCJoZXhcIilcbiAgICAuc2xpY2UoMCwgMTYpO1xuICBjb25zdCBub3JtYWxpemVkID0gcG9zaXhQYXRoLm5vcm1hbGl6ZVJvb3Qod29ya3NwYWNlUGF0aCk7XG4gIGNvbnN0IHJlbGF0aXZlID0gbm9ybWFsaXplZCA9PT0gU0NSQVRDSF9NT1VOVCA/IFwiXCIgOiBub3JtYWxpemVkLnNsaWNlKGAke1NDUkFUQ0hfTU9VTlR9L2AubGVuZ3RoKTtcbiAgY29uc3Qgc291cmNlID0gbmV3IExvY2FsRmlsZVN5c3RlbSh7XG4gICAgcm9vdDogam9pbih0bXBkaXIoKSwgXCJkYngtdG9vbHNcIiwgXCJtYXN0cmFcIiwgZGlnZXN0LCByZWxhdGl2ZSksXG4gICAgcmVhZE9ubHk6IGZhbHNlLFxuICAgIGNyZWF0ZVJvb3Q6IHRydWUsXG4gIH0pO1xuICByZXR1cm4gZmlsZXN5c3RlbXMoc291cmNlLCB7XG4gICAgZGlzcGxheU5hbWU6IFwiVGVtcG9yYXJ5IEZpbGVzXCIsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICBcIlVzZXItc2NvcGVkIHRlbXBvcmFyeSBmaWxlcyByZXRhaW5lZCB3aGlsZSB0aGUgaG9zdCBrZWVwcyBpdHMgZXBoZW1lcmFsIHRlbXAgc3RvcmFnZS5cIixcbiAgfSk7XG59XG5cbi8qKiBNb3VudCBzdGFydHVwLXByb3Zpc2lvbmVkIGxvY2FsIHNraWxsIHJvb3RzIGludG8gTWFzdHJhJ3Mgd29ya3NwYWNlIGZpbGVzeXN0ZW0uICovXG5mdW5jdGlvbiBsb2NhbFNraWxsTW91bnRSZXNvbHZlcnMocGF0aHM6IHJlYWRvbmx5IHN0cmluZ1tdKTogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdIHtcbiAgcmV0dXJuIFsuLi5uZXcgU2V0KHBhdGhzLm1hcCgocGF0aCkgPT4gcGF0aC50cmltKCkpLmZpbHRlcihCb29sZWFuKSldLm1hcCgocm9vdCkgPT4ge1xuICAgIGNvbnN0IG1vdW50ID0gcG9zaXhQYXRoLm5vcm1hbGl6ZVJvb3Qocm9vdCk7XG4gICAgY29uc3Qgc291cmNlID0gbmV3IExvY2FsRmlsZVN5c3RlbSh7XG4gICAgICByb290LFxuICAgICAgcmVhZE9ubHk6IHRydWUsXG4gICAgICBjcmVhdGVSb290OiBmYWxzZSxcbiAgICB9KTtcbiAgICBjb25zdCBmaWxlc3lzdGVtID0gZmlsZXN5c3RlbXMoc291cmNlLCB7IHJlYWRPbmx5OiB0cnVlIH0pO1xuICAgIHJldHVybiAoKSA9PiAoe1xuICAgICAgbW91bnRzOiB7IFttb3VudF06IGZpbGVzeXN0ZW0gfSxcbiAgICAgIHNraWxsUGF0aHM6IFttb3VudF0sXG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEdhdGUgc2tpbGwtZm9sZGVyIG1vdW50cyBvbiB0aGUgcmVxdWVzdCdzIHRva2VuLlxuICpcbiAqIEFsd2F5cyBhbGxvd3MgbW91bnRzIGluIGRldmVsb3BtZW50OyBpbiBvdGhlciBlbnZpcm9ubWVudHMgcmVxdWlyZXNcbiAqIHtAbGluayBoYXNXb3Jrc3BhY2VGaWxlU2NvcGV9LlxuICovXG5mdW5jdGlvbiBzaG91bGRNb3VudFNraWxsRm9sZGVycyhyZXF1ZXN0Q29udGV4dDogUmVxdWVzdENvbnRleHQpOiBib29sZWFuIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcImRldmVsb3BtZW50XCIpIHJldHVybiB0cnVlO1xuICByZXR1cm4gaGFzV29ya3NwYWNlRmlsZVNjb3BlKHJlcXVlc3RDb250ZXh0KTtcbn1cblxuLyoqXG4gKiBXcmFwIGEge0BsaW5rIERhdGFicmlja3NGaWxlU3lzdGVtfSBhcyBhIE1hc3RyYSBmaWxlc3lzdGVtLiBNaXNzaW5nIG9yXG4gKiBpbmFjY2Vzc2libGUgcm9vdHMgcmV0dXJuIGB1bmRlZmluZWRgIHNvIG90aGVyIGFjY2Vzc2libGUgcm9vdHMgcmVtYWluXG4gKiB1c2FibGUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRhdGFicmlja3NGaWxlc3lzdGVtKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCxcbiAgcm9vdDogc3RyaW5nLFxuICByZWFkT25seTogYm9vbGVhbiA9IHRydWUsXG4gIGNyZWF0ZVJvb3Q6IGJvb2xlYW4gPSAhcmVhZE9ubHksXG4gIGZpbGVTeXN0ZW1DYWNoZT86IEZpbGVTeXN0ZW1DYWNoZSxcbiAgY2FjaGVPcHRpb25zPzogRmlsZVN5c3RlbUNhY2hlT3B0aW9ucyxcbiAgYWRhcHRlck9wdGlvbnM6IFBpY2s8TWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXJPcHRpb25zLCBcImRlc2NyaXB0aW9uXCIgfCBcImRpc3BsYXlOYW1lXCI+ID0ge30sXG4pOiBQcm9taXNlPFxuICB8IHtcbiAgICAgIGZpbGVzeXN0ZW06IFdvcmtzcGFjZUZpbGVzeXN0ZW07XG4gICAgfVxuICB8IHVuZGVmaW5lZFxuPiB7XG4gIGNvbnN0IGluaXRpYWxDbGllbnQgPSB3b3Jrc3BhY2VDbGllbnQudG9MZWdhY3lXb3Jrc3BhY2VDbGllbnQoY2xpZW50KTtcbiAgY29uc3QgZnMgPSBuZXcgRGF0YWJyaWNrc0ZpbGVTeXN0ZW0oe1xuICAgIGNsaWVudDogKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHdvcmtzcGFjZUNsaWVudC50b0xlZ2FjeVdvcmtzcGFjZUNsaWVudChnZXRFeGVjdXRpb25Db250ZXh0KCkuY2xpZW50KTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gaW5pdGlhbENsaWVudDtcbiAgICAgIH1cbiAgICB9LFxuICAgIHJvb3QsXG4gICAgcmVhZE9ubHksXG4gICAgY3JlYXRlUm9vdCxcbiAgfSk7XG4gIGNvbnN0IGNhY2hlZCA9XG4gICAgZmlsZVN5c3RlbUNhY2hlICYmIGNhY2hlT3B0aW9ucyA/IHNoYXJlZEZTLmNhY2hlKGZzLCBmaWxlU3lzdGVtQ2FjaGUsIGNhY2hlT3B0aW9ucykgOiBmcztcbiAgY29uc3Qgc291cmNlID0gdmVyaWZ5Rmlyc3RGaWxlU3lzdGVtQWNjZXNzKGNhY2hlZCwgKCkgPT4gZnMuc3RhdChcIi5cIiksIHJvb3QpO1xuICBjb25zdCBmaWxlc3lzdGVtID0gZmlsZXN5c3RlbXMoc291cmNlLCB7IC4uLmFkYXB0ZXJPcHRpb25zLCByZWFkT25seSB9KTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBmaWxlc3lzdGVtLmluaXQoKTtcbiAgICBpZiAoYXdhaXQgZmlsZXN5c3RlbS5leGlzdHMoXCIuXCIpKSB7XG4gICAgICByZXR1cm4geyBmaWxlc3lzdGVtIH07XG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJkYXRhYnJpY2tzLW1vdW50OnNraXBwZWRcIiwge1xuICAgICAgcm9vdCxcbiAgICAgIHJlYWRPbmx5LFxuICAgICAgZXJyb3I6IGVycm9yVXRpbHMuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gdmVyaWZ5Rmlyc3RGaWxlU3lzdGVtQWNjZXNzPFRGaWxlU3lzdGVtIGV4dGVuZHMgRmlsZVN5c3RlbT4oXG4gIGZpbGVzeXN0ZW06IFRGaWxlU3lzdGVtLFxuICByZWFkUHJvYmU6ICgpID0+IFByb21pc2U8dW5rbm93bj4sXG4gIHJvb3Q6IHN0cmluZyxcbik6IFRGaWxlU3lzdGVtIHtcbiAgbGV0IHJlYWRDaGVjazogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcbiAgbGV0IHdyaXRlVmVyaWZpZWQgPSBmYWxzZTtcbiAgY29uc3QgYm91bmRNZXRob2RzID0gbmV3IE1hcDxQcm9wZXJ0eUtleSwgdW5rbm93bj4oKTtcbiAgY29uc3QgcmVhZE9wZXJhdGlvbnMgPSBuZXcgU2V0PFByb3BlcnR5S2V5PihbXCJleGlzdHNcIiwgXCJyZWFkRmlsZVwiLCBcInJlYWRkaXJcIiwgXCJzdGF0XCJdKTtcbiAgY29uc3Qgd3JpdGVPcGVyYXRpb25zID0gbmV3IFNldDxQcm9wZXJ0eUtleT4oW1xuICAgIFwiYXBwZW5kRmlsZVwiLFxuICAgIFwiY29weUZpbGVcIixcbiAgICBcImRlbGV0ZUZpbGVcIixcbiAgICBcIm1rZGlyXCIsXG4gICAgXCJtb3ZlRmlsZVwiLFxuICAgIFwicm1kaXJcIixcbiAgICBcIndyaXRlRmlsZVwiLFxuICBdKTtcbiAgY29uc3QgdmVyaWZ5UmVhZCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICByZWFkQ2hlY2sgPz89IFByb21pc2UucmVzb2x2ZShyZWFkUHJvYmUoKSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCByZWFkQ2hlY2s7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJlYWRDaGVjayA9IHVuZGVmaW5lZDtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcImRhdGFicmlja3MtbW91bnQ6cmVhZC1jaGVjay1mYWlsZWRcIiwge1xuICAgICAgICByb290LFxuICAgICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyb3IpLFxuICAgICAgfSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG5ldyBQcm94eShmaWxlc3lzdGVtLCB7XG4gICAgZ2V0KHRhcmdldCwgcHJvcGVydHkpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wZXJ0eSwgdGFyZ2V0KTtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHZhbHVlO1xuICAgICAgaWYgKGJvdW5kTWV0aG9kcy5oYXMocHJvcGVydHkpKSByZXR1cm4gYm91bmRNZXRob2RzLmdldChwcm9wZXJ0eSk7XG4gICAgICBjb25zdCBkZWxlZ2F0ZWQgPSB2YWx1ZS5iaW5kKHRhcmdldCkgYXMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdW5rbm93bjtcbiAgICAgIGxldCBtZXRob2QgPSBkZWxlZ2F0ZWQ7XG4gICAgICBpZiAocmVhZE9wZXJhdGlvbnMuaGFzKHByb3BlcnR5KSkge1xuICAgICAgICBtZXRob2QgPSBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgICAgYXdhaXQgdmVyaWZ5UmVhZCgpO1xuICAgICAgICAgIHJldHVybiBkZWxlZ2F0ZWQoLi4uYXJncyk7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHdyaXRlT3BlcmF0aW9ucy5oYXMocHJvcGVydHkpKSB7XG4gICAgICAgIG1ldGhvZCA9IGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZGVsZWdhdGVkKC4uLmFyZ3MpO1xuICAgICAgICAgICAgaWYgKCF3cml0ZVZlcmlmaWVkKSB7XG4gICAgICAgICAgICAgIHdyaXRlVmVyaWZpZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoXCJkYXRhYnJpY2tzLW1vdW50OndyaXRlLWNoZWNrLXBhc3NlZFwiLCB7IHJvb3QgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlVmVyaWZpZWQpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKFwiZGF0YWJyaWNrcy1tb3VudDp3cml0ZS1jaGVjay1mYWlsZWRcIiwge1xuICAgICAgICAgICAgICAgIHJvb3QsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yVXRpbHMuZXJyb3JNZXNzYWdlKGVycm9yKSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBib3VuZE1ldGhvZHMuc2V0KHByb3BlcnR5LCBtZXRob2QpO1xuICAgICAgcmV0dXJuIG1ldGhvZDtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBSdW4gZXZlcnkgbW91bnQgcmVzb2x2ZXIgZm9yIG9uZSByZXF1ZXN0IGFuZCBtZXJnZSBtb3VudHMgcGx1cyBza2lsbCBwYXRocy5cbiAqIExhdGVyIHJlc29sdmVycyBvdmVyd3JpdGUgbW91bnQga2V5cyBmcm9tIGVhcmxpZXIgb25lcy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVdvcmtzcGFjZUNvbnRyaWJ1dGlvbihcbiAgcmVzb2x2ZXJzOiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW10sXG4gIGNvbnRleHQ6IERhdGFicmlja3NXb3Jrc3BhY2VDb250ZXh0LFxuKTogUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4ge1xuICBjb25zdCBtb3VudHM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUZpbGVzeXN0ZW0+ID0ge307XG4gIGNvbnN0IHNraWxsUGF0aHM6IHN0cmluZ1tdID0gW107XG5cbiAgZm9yIChjb25zdCBbaW5kZXgsIHJlc29sdmVyXSBvZiByZXNvbHZlcnMuZW50cmllcygpKSB7XG4gICAgY29uc3QgY29udHJpYnV0aW9uID0gYXdhaXQgcmVzb2x2ZXIoY29udGV4dCk7XG4gICAgbG9nZ2VyLmRlYnVnKFwibW91bnRzOnJlc29sdmVyXCIsIHtcbiAgICAgIGluZGV4LFxuICAgICAgbW91bnRLZXlzOiBPYmplY3Qua2V5cyhjb250cmlidXRpb24ubW91bnRzKSxcbiAgICAgIHNraWxsUGF0aHM6IGNvbnRyaWJ1dGlvbi5za2lsbFBhdGhzID8/IFtdLFxuICAgIH0pO1xuICAgIE9iamVjdC5hc3NpZ24obW91bnRzLCBjb250cmlidXRpb24ubW91bnRzKTtcbiAgICBpZiAoY29udHJpYnV0aW9uLnNraWxsUGF0aHM/Lmxlbmd0aCkge1xuICAgICAgc2tpbGxQYXRocy5wdXNoKC4uLmNvbnRyaWJ1dGlvbi5za2lsbFBhdGhzKTtcbiAgICB9XG4gIH1cblxuICBsb2dnZXIuZGVidWcoXCJtb3VudHM6bWVyZ2VkXCIsIHtcbiAgICBtb3VudEtleXM6IE9iamVjdC5rZXlzKG1vdW50cyksXG4gICAgc2tpbGxQYXRocyxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBtb3VudHMsXG4gICAgc2tpbGxQYXRocyxcbiAgfTtcbn1cblxuLyoqXG4gKiBEeW5hbWljIGZpbGVzeXN0ZW0gcmVzb2x2ZXIgcGFzc2VkIHRvIE1hc3RyYSB7QGxpbmsgV29ya3NwYWNlfS5cbiAqXG4gKiBSZXR1cm5zIGEge0BsaW5rIENvbXBvc2l0ZUZpbGVzeXN0ZW19IG92ZXIgZXZlcnkgcGF0aCB0aGF0IHJlc29sdmVkIGZvciB0aGVcbiAqIHJlcXVlc3QuIEFuIGVtcHR5IGNvbXBvc2l0ZSBleHBvc2VzIG5vIGltcGxpY2l0IGxvY2FsIHN0b3JhZ2UuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VGaWxlc3lzdGVtKFxuICByZXNvbHZlQ29udHJpYnV0aW9uOiAoY29udGV4dDogRGF0YWJyaWNrc1dvcmtzcGFjZUNvbnRleHQpID0+IFByb21pc2U8V29ya3NwYWNlTW91bnRDb250cmlidXRpb24+LFxuICBjb250ZXh0OiBEYXRhYnJpY2tzV29ya3NwYWNlQ29udGV4dCxcbiAgZmlsZXNDYWNoZT86IEZpbGVzQ2FjaGVFeHBvcnRzLFxuICBzb3VyY2VLZXk/OiBzdHJpbmcsXG4pOiBQcm9taXNlPFdvcmtzcGFjZUZpbGVzeXN0ZW0+IHtcbiAgY29uc3QgeyBtb3VudHMgfSA9IGF3YWl0IHJlc29sdmVDb250cmlidXRpb24oY29udGV4dCk7XG4gIGNvbnN0IG1vdW50S2V5cyA9IE9iamVjdC5rZXlzKG1vdW50cyk7XG4gIGlmIChtb3VudEtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiZmlsZXN5c3RlbTplbXB0eVwiLCB7XG4gICAgICBoYXNSZXF1ZXN0Q29udGV4dDogQm9vbGVhbihjb250ZXh0LnJlcXVlc3RDb250ZXh0KSxcbiAgICB9KTtcbiAgICByZXR1cm4gZmlsZXN5c3RlbXMobmV3IE1lbW9yeUZpbGVTeXN0ZW0oeyByb290OiBcIi9cIiwgcmVhZE9ubHk6IHRydWUgfSksIHtcbiAgICAgIHJlYWRPbmx5OiB0cnVlLFxuICAgIH0pO1xuICB9XG4gIGxvZ2dlci5kZWJ1ZyhcImZpbGVzeXN0ZW06Y29tcG9zaXRlXCIsIHsgbW91bnRLZXlzIH0pO1xuICBjb25zdCBsb2FkID0gKCkgPT4gbmV3IE1vdW50ZWRDb21wb3NpdGVGaWxlc3lzdGVtKHsgbW91bnRzIH0pO1xuICBpZiAoIWZpbGVzQ2FjaGUpIHJldHVybiBsb2FkKCk7XG4gIGNvbnN0IHNjb3BlZCA9IGF3YWl0IHJlc29sdmVGaWxlc0NhY2hlU2NvcGUoY29udGV4dCk7XG4gIGlmICghc2NvcGVkKSByZXR1cm4gbG9hZCgpO1xuICByZXR1cm4gZmlsZXNDYWNoZS5mb3JGaWxlU3lzdGVtKHNjb3BlZC5zY29wZSwgeyBwYXRoczogbW91bnRLZXlzLCBrZXk6IHNvdXJjZUtleSB9LCBsb2FkKTtcbn1cblxuLyoqXG4gKiBFeHBhbmQgc2tpbGwgcm9vdHMgaW50byBjb25jcmV0ZSBza2lsbCBkaXJlY3RvcmllcyBhbmQga2VlcCB0aGUgZmlyc3RcbiAqIHNhbWUtbmFtZWQgZGlyZWN0b3J5LiBNYXN0cmEgc3RpbGwgb3ducyBwYXJzaW5nLCBpbmRleGluZywgYW5kIHJlZnJlc2hlcyxcbiAqIHdoaWxlIGVhcmxpZXIgY29uZmlndXJlZCByb290cyByZXRhaW4gcHJlY2VkZW5jZSBvdmVyIGxhdGVyIHJvb3RzLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlRGlzdGluY3RTa2lsbFBhdGhzKFxuICBmaWxlc3lzdGVtOiBXb3Jrc3BhY2VGaWxlc3lzdGVtLFxuICByb290czogcmVhZG9ubHkgc3RyaW5nW10sXG4pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gIGNvbnN0IHNlbGVjdGVkID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCByb290IG9mIHJvb3RzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGVudHJpZXMgPSBhd2FpdCBmaWxlc3lzdGVtLnJlYWRkaXIocm9vdCk7XG4gICAgICBpZiAoZW50cmllcy5zb21lKChlbnRyeSkgPT4gZW50cnkudHlwZSA9PT0gXCJmaWxlXCIgJiYgZW50cnkubmFtZSA9PT0gXCJTS0lMTC5tZFwiKSkge1xuICAgICAgICBjb25zdCBuYW1lID0gcG9zaXhQYXRoLmJhc2VuYW1lKHJvb3QpO1xuICAgICAgICBpZiAoIXNlbGVjdGVkLmhhcyhuYW1lKSkgc2VsZWN0ZWQuc2V0KG5hbWUsIHJvb3QpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBpZiAoZW50cnkudHlwZSAhPT0gXCJkaXJlY3RvcnlcIiB8fCBzZWxlY3RlZC5oYXMoZW50cnkubmFtZSkpIGNvbnRpbnVlO1xuICAgICAgICBzZWxlY3RlZC5zZXQoZW50cnkubmFtZSwgcG9zaXhQYXRoLmpvaW4ocm9vdCwgZW50cnkubmFtZSkpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJza2lsbC1yb290OnNraXBwZWRcIiwge1xuICAgICAgICByb290LFxuICAgICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyb3IpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBbLi4uc2VsZWN0ZWQudmFsdWVzKCldO1xufVxuXG4vKiogTWVtb2l6ZSBvbmUgY29tcGxldGUgbW91bnQgY29udHJpYnV0aW9uIGZvciBlYWNoIHJlcXVlc3QgY29udGV4dC4gKi9cbmZ1bmN0aW9uIGNvbnRyaWJ1dGlvblJlc29sdmVyKFxuICByZXNvbHZlcnM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSxcbik6IChjb250ZXh0OiBEYXRhYnJpY2tzV29ya3NwYWNlQ29udGV4dCkgPT4gUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4ge1xuICBjb25zdCBzY29wZWQgPSBuZXcgV2Vha01hcDxSZXF1ZXN0Q29udGV4dCwgUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4+KCk7XG4gIGxldCB1bnNjb3BlZDogUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4gfCB1bmRlZmluZWQ7XG4gIHJldHVybiAoY29udGV4dCkgPT4ge1xuICAgIGlmICghY29udGV4dC5yZXF1ZXN0Q29udGV4dCkge1xuICAgICAgdW5zY29wZWQgPz89IHJlc29sdmVXb3Jrc3BhY2VDb250cmlidXRpb24ocmVzb2x2ZXJzLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiB1bnNjb3BlZDtcbiAgICB9XG4gICAgY29uc3QgZXhpc3RpbmcgPSBzY29wZWQuZ2V0KGNvbnRleHQucmVxdWVzdENvbnRleHQpO1xuICAgIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nO1xuICAgIGNvbnN0IHBlbmRpbmcgPSByZXNvbHZlV29ya3NwYWNlQ29udHJpYnV0aW9uKHJlc29sdmVycywgY29udGV4dCk7XG4gICAgc2NvcGVkLnNldChjb250ZXh0LnJlcXVlc3RDb250ZXh0LCBwZW5kaW5nKTtcbiAgICByZXR1cm4gcGVuZGluZztcbiAgfTtcbn1cbiJdfQ==