@dbx-tools/core 0.6.88 → 0.6.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/src/config.js CHANGED
@@ -1,73 +1,45 @@
1
1
  /**
2
- * Layered configuration lookup: environment, `.env`, Databricks bundle.
2
+ * Layered configuration lookup: environment, `.env`, bundle, and `app.yaml`.
3
3
  *
4
4
  * Every package resolves settings the same way: take the caller's value, else
5
5
  * an environment variable, else a default. Local development adds two fallback
6
- * locations: `.env` files and `resources.apps.<app>.config.env` or root
7
- * `variables` in `databricks.yml`.
6
+ * locations: `.env` files, one App's `resources.apps.<app>.config.env` in
7
+ * `databricks.yml`, and literal env values in `app.yaml` / `app.yml`.
8
8
  *
9
- * Two things make it cheap to call from a hot path:
9
+ * {@link values} is LAZY (an `object.Sequence`), so `databricks bundle validate`
10
+ * is only spawned when the environment and `.env` both missed; app YAML is only
11
+ * read after the bundle source also missed.
10
12
  *
11
- * - {@link values} is LAZY (an `object.Sequence`), so `databricks bundle
12
- * validate` is only spawned when the environment and `.env` both missed.
13
- * - the parsed `.env` and bundle are cached through {@link context.cached}, so
14
- * the spawn happens once per working directory and a `cwd` change misses
15
- * rather than returning another project's config.
16
- *
17
- * Inside a deployed Databricks App both file sources are skipped by default
13
+ * Inside a deployed Databricks App all three file sources are skipped by default
18
14
  * ({@link isDatabricksAppEnv}): the platform has already turned them into real
19
15
  * environment variables, there is no bundle to validate, and the `databricks`
20
16
  * CLI is not on the image. Boolean environment overrides can force either file
21
17
  * source on or off when a tool needs different behavior.
22
18
  *
23
- * The bundle is gated on this being an AppKit project at all. `databricks bundle
24
- * validate` is a process spawn measured in seconds, and a plain library or CLI
25
- * consumer has no bundle to find, so the gate runs in three steps before the
26
- * spawn is allowed - see {@link bundleFile}:
27
- *
28
- * 1. `@databricks/appkit` is resolved WITHOUT evaluating it. It is an optional
29
- * peer, so a consumer that never installed it is not an AppKit project and
30
- * the bundle is never loaded. The probe is cached, so this costs one
31
- * resolution for the life of the process.
32
- * 2. The bundle is read (once per context) and must describe EXACTLY ONE app
33
- * with `config.env`. Nothing here says which of several apps this process
34
- * is, so an ambiguous bundle contributes nothing rather than a guess.
35
- * 3. AppKit's execution context confirms this process really is that app. The
36
- * context does not exist until AppKit boots and `getExecutionContext()`
37
- * THROWS until then, so the probe is caught and only the affirmative is
38
- * remembered - a lookup before boot still resolves, and re-confirms later
39
- * once the context is available.
40
- *
41
- * Only the single app's `config.env` is consulted. Root bundle `variables` are
42
- * not: they are authoring inputs for the bundle itself (interpolated into
43
- * targets, resources, and paths), so treating one as a process setting resolves
44
- * names the deployed app never sees.
19
+ * Only the single bundle app's `config.env` and literal app YAML `env[].value`
20
+ * entries are consulted. Root bundle `variables` are not: they are authoring
21
+ * inputs for the bundle itself (interpolated into targets, resources, and paths),
22
+ * so treating one as a process setting resolves names the deployed app never sees.
45
23
  *
46
24
  * Node-only (`child_process`, `fs`, `process`).
47
25
  *
48
26
  * @module
49
27
  */
50
- var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
51
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
52
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
53
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
54
- });
55
- }
56
- return path;
57
- };
58
28
  import { spawnSync } from "node:child_process";
59
29
  import { readFileSync } from "node:fs";
60
- import { createRequire } from "node:module";
61
30
  import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
62
31
  import { parseEnv } from "node:util";
63
- import { context, functionModule, json, log, object, string as stringModule, } from "@dbx-tools/shared-core";
32
+ import { json, log, object, string as sharedString } from "@dbx-tools/shared-core";
33
+ import { parse as parseYaml } from "yaml";
64
34
  import { z } from "zod";
65
- import { statSync } from "./file.js";
66
- import { root as resolveProjectRoot } from "./project.js";
35
+ import { cachedRecord, statSync } from "./file.js";
36
+ import { resolveWorkingDirectory, root as resolveProjectRoot } from "./project.js";
67
37
  const logger = log.logger("config");
38
+ const configFileCache = new Map();
68
39
  const DEFAULT_SCOPE = "DBX_TOOLS";
69
- const DEFAULT_SOURCES = ["env", "dotenv", "bundle"];
40
+ const DEFAULT_SOURCES = ["config", "env", "dotenv", "bundle", "app"];
70
41
  const BUNDLE_FILE_NAMES = ["databricks.yml", "databricks.yaml"];
42
+ const APP_FILE_NAMES = ["app.yaml", "app.yml"];
71
43
  const DOTENV_FILE_NAME = ".env";
72
44
  const NODE_ENV_ALTERNATIVES = {
73
45
  production: ["prod"],
@@ -76,56 +48,153 @@ const NODE_ENV_ALTERNATIVES = {
76
48
  /** Highest valid TCP port number. */
77
49
  export const MAX_TCP_PORT = 65_535;
78
50
  /** Boolean environment override for {@link isDatabricksAppEnv}. */
79
- export const DATABRICKS_APP_ENV_KEY = "DBX_TOOLS_DATABRICKS_APP_ENV";
51
+ const DATABRICKS_APP_ENV_KEY = "DBX_TOOLS_DATABRICKS_APP_ENV";
80
52
  /** Boolean environment override for project `.env` reads. */
81
- export const CONFIG_DOTENV_KEY = "DBX_TOOLS_CONFIG_DOTENV";
53
+ const CONFIG_DOTENV_KEY = "DBX_TOOLS_CONFIG_DOTENV";
82
54
  /** Boolean environment override for Databricks bundle reads. */
83
- export const CONFIG_BUNDLE_KEY = "DBX_TOOLS_CONFIG_BUNDLE";
84
- /**
85
- * The OPTIONAL AppKit peer whose presence marks this as a Databricks App
86
- * project. Held as a constant so the resolve probe and the lazy import name it
87
- * once, and so neither site carries a literal a bundler would try to follow.
88
- */
89
- const APPKIT_MODULE = "@databricks/appkit";
90
- /**
91
- * Whether AppKit's execution context has EVER been observed. Latching is the
92
- * point: a context confirms this process is the bundle's app, and that fact does
93
- * not stop being true when a later lookup happens outside a request scope.
94
- */
95
- let appKitContext = false;
96
- /** Flattened App `config.env` per parsed bundle - see {@link bundleApp}. */
97
- const BUNDLE_APP_CACHE = new WeakMap();
55
+ const CONFIG_BUNDLE_KEY = "DBX_TOOLS_CONFIG_BUNDLE";
56
+ /** Boolean environment override for Databricks App YAML reads. */
57
+ const CONFIG_APP_KEY = "DBX_TOOLS_CONFIG_APP";
98
58
  /** Exact process-environment lookup for callers that do not read local config files. */
99
59
  export const ENV_ONLY = { scope: [], sources: "env" };
100
- export const bundleValue = z
60
+ export const valueSchema = z
101
61
  .string()
102
- .transform((value) => value.trim())
103
- .refine((value) => value.length > 0)
62
+ .trim()
63
+ .min(1)
104
64
  .refine((value) => !/\$\{[^}]+\}/.test(value), {
105
65
  message: "Interpolated values are not allowed",
106
66
  });
107
- /**
108
- * The GENERIC shape of a bundle resource: a name, and whatever else the resource
109
- * type carries. Deliberately unopinionated and `passthrough()` - the concrete
110
- * resource kinds (`sql_warehouse`, `genie_space`, `postgres`, ...) are
111
- * Databricks-App concepts that belong to the package that resolves them, so
112
- * node-appkit `.extend()`s this rather than this module knowing about them.
113
- */
114
- export const bundleResourceSchema = z.object({ name: bundleValue.optional() }).passthrough();
67
+ const portValueSchema = z.preprocess((input) => object.toNumber(input), z.number().int().min(1).max(MAX_TCP_PORT));
68
+ const positiveNumberValue = z.preprocess((input) => object.toNumber(input), z.number().positive());
69
+ const positiveIntValue = positiveNumberValue.transform(Math.floor);
70
+ const workspaceHostSchema = valueSchema.refine((host) => {
71
+ try {
72
+ return ["http:", "https:"].includes(new URL(host).protocol);
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }, { message: "Must be an HTTP(S) URL" });
78
+ const databricksAppEnvSchema = z.object({
79
+ DATABRICKS_APP_NAME: valueSchema,
80
+ DATABRICKS_HOST: workspaceHostSchema,
81
+ DATABRICKS_APP_PORT: portValueSchema,
82
+ });
83
+ /** A named bundle or App resource; concrete resource fields pass through. */
84
+ export const bundleResourceSchema = z.object({ name: valueSchema.optional() }).passthrough();
115
85
  export const bundleEnvEntrySchema = z.object({
116
- name: bundleValue.optional(),
86
+ name: valueSchema.optional(),
117
87
  value: z.string().optional(),
118
- value_from: bundleValue.optional(),
88
+ value_from: valueSchema.optional(),
119
89
  });
120
90
  export const bundleAppSchema = z.object({
121
- name: bundleValue.optional(),
122
- source_code_path: z.string().optional(),
91
+ name: valueSchema.optional(),
123
92
  config: z.object({ env: z.array(bundleEnvEntrySchema).optional() }).optional(),
124
93
  resources: z.array(bundleResourceSchema).optional(),
125
94
  });
126
- const bundleAppsSchema = z.object({
95
+ export const appEnvEntrySchema = z.object({
96
+ name: valueSchema,
97
+ value: z.string().optional(),
98
+ valueFrom: valueSchema.optional(),
99
+ });
100
+ export const appSchema = z.object({
101
+ env: z.array(appEnvEntrySchema).optional(),
102
+ resources: z.array(bundleResourceSchema).optional(),
103
+ });
104
+ const bundleConfigSchema = z.object({
127
105
  resources: z.object({ apps: z.record(z.string(), bundleAppSchema).optional() }).optional(),
128
106
  });
107
+ /** Flatten the single bundle App's `config.env`, resolving resource references. */
108
+ export function flattenBundleEnv(data) {
109
+ const parsed = bundleConfigSchema.safeParse(data);
110
+ if (!parsed.success)
111
+ return {};
112
+ const apps = Object.values(parsed.data.resources?.apps ?? {});
113
+ if (apps.length !== 1)
114
+ return {};
115
+ const app = apps[0];
116
+ const resources = new Map((app?.resources ?? [])
117
+ .filter((resource) => resource.name)
118
+ .map((resource) => [resource.name, resource]));
119
+ const result = {};
120
+ for (const entry of app?.config?.env ?? []) {
121
+ if (!entry.name)
122
+ continue;
123
+ const literal = valueSchema.safeParse(entry.value);
124
+ if (literal.success) {
125
+ result[entry.name] = literal.data;
126
+ continue;
127
+ }
128
+ const referenced = entry.value_from
129
+ ? resourceValue(resources.get(entry.value_from))
130
+ : undefined;
131
+ if (referenced)
132
+ result[entry.name] = referenced;
133
+ }
134
+ return result;
135
+ }
136
+ /** Flatten `app.yaml` env entries, resolving `valueFrom` resource references. */
137
+ export function flattenAppEnv(data) {
138
+ const parsed = appSchema.safeParse(data);
139
+ if (!parsed.success)
140
+ return {};
141
+ const resources = new Map((parsed.data.resources ?? [])
142
+ .filter((resource) => resource.name)
143
+ .map((resource) => [resource.name, resource]));
144
+ const result = {};
145
+ for (const entry of parsed.data.env ?? []) {
146
+ const literal = valueSchema.safeParse(entry.value);
147
+ if (literal.success) {
148
+ result[entry.name] = literal.data;
149
+ continue;
150
+ }
151
+ const referenced = entry.valueFrom ? resourceValue(resources.get(entry.valueFrom)) : undefined;
152
+ if (referenced)
153
+ result[entry.name] = referenced;
154
+ }
155
+ return result;
156
+ }
157
+ function resourceValue(resource) {
158
+ for (const path of [
159
+ ["sql_warehouse", "id"],
160
+ ["genie_space", "space_id"],
161
+ ["postgres", "endpoint"],
162
+ ["postgres", "database"],
163
+ ["postgres", "branch"],
164
+ ]) {
165
+ let value = resource;
166
+ for (const part of path)
167
+ value = object.isRecord(value) ? value[part] : undefined;
168
+ const parsed = valueSchema.safeParse(value);
169
+ if (parsed.success)
170
+ return parsed.data;
171
+ }
172
+ return undefined;
173
+ }
174
+ /** Walk a dot-separated path through parsed bundle data. */
175
+ export function getBundlePath(data, path) {
176
+ const parts = path.split(".").filter(Boolean);
177
+ if (parts.length === 0)
178
+ return undefined;
179
+ let current = data;
180
+ for (let index = 0; index < parts.length; index++) {
181
+ if (!object.isRecord(current))
182
+ return undefined;
183
+ const next = current[parts[index]];
184
+ if (index === parts.length - 1) {
185
+ const direct = valueSchema.safeParse(next);
186
+ if (direct.success)
187
+ return direct.data;
188
+ if (object.isRecord(next)) {
189
+ const nested = valueSchema.safeParse(next.value);
190
+ return nested.success ? nested.data : undefined;
191
+ }
192
+ return undefined;
193
+ }
194
+ current = next;
195
+ }
196
+ return undefined;
197
+ }
129
198
  /**
130
199
  * Detect a Databricks App runtime from its required name, host, and port.
131
200
  *
@@ -138,59 +207,68 @@ export function isDatabricksAppEnv(source = process.env) {
138
207
  const override = object.toBoolean(source[DATABRICKS_APP_ENV_KEY]);
139
208
  if (override !== undefined)
140
209
  return override;
141
- const appName = source.DATABRICKS_APP_NAME?.trim();
142
- const host = source.DATABRICKS_HOST?.trim();
143
- const port = source.DATABRICKS_APP_PORT?.trim();
144
- if (!appName || !host || !port)
145
- return false;
146
- try {
147
- if (!["http:", "https:"].includes(new URL(host).protocol))
148
- return false;
149
- }
150
- catch {
151
- return false;
152
- }
153
- const portNumber = object.toNumber(port);
154
- return (portNumber !== undefined &&
155
- Number.isInteger(portNumber) &&
156
- portNumber >= 1 &&
157
- portNumber <= MAX_TCP_PORT);
210
+ const parsed = databricksAppEnvSchema.safeParse(source);
211
+ return parsed.success;
212
+ }
213
+ /** Exact, uppercase, and tokenized-uppercase names for a human-friendly key. */
214
+ export function environmentKeys(name) {
215
+ const trimmed = name.trim();
216
+ if (!trimmed)
217
+ return [];
218
+ return object
219
+ .sequence(trimmed, trimmed.toUpperCase(), Array.from(sharedString.tokenize(trimmed)).join("_").toUpperCase())
220
+ .filter(Boolean)
221
+ .distinct()
222
+ .toArray();
158
223
  }
159
224
  /** Candidate names in scope, prefix, and input precedence order. */
160
225
  function keys(input, options = {}) {
161
- const scopes = object.sequence(options.scope ?? DEFAULT_SCOPE).toArray();
162
- const prefixes = options.prefix === undefined ? [] : object.sequence(options.prefix).toArray();
163
- return [
164
- ...object
165
- .sequence(input)
166
- .flatMap((key) => {
167
- const prefixed = prefixes.length > 0 ? prefixes.map((prefix) => join(prefix, key)) : [key];
168
- return [
169
- ...scopes.flatMap((scope) => prefixed.map((key) => join(scope, key))),
170
- ...prefixed,
171
- key,
172
- ];
173
- })
174
- .filter((key) => key.length > 0)
175
- .distinct(),
176
- ];
226
+ const scopes = object
227
+ .sequence(options.scope ?? DEFAULT_SCOPE)
228
+ .map(sharedString.trimToEmpty)
229
+ .filter(Boolean)
230
+ .distinct()
231
+ .toArray();
232
+ const prefixes = options.prefix === undefined
233
+ ? []
234
+ : object
235
+ .sequence(options.prefix)
236
+ .map(sharedString.trimToEmpty)
237
+ .filter(Boolean)
238
+ .distinct()
239
+ .toArray();
240
+ return object
241
+ .sequence(input)
242
+ .map(sharedString.trimToEmpty)
243
+ .filter(Boolean)
244
+ .distinct()
245
+ .flatMap((key) => {
246
+ const prefixed = prefixes.length > 0 ? prefixes.map((prefix) => `${prefix}_${key}`) : [key];
247
+ return [
248
+ ...scopes.flatMap((scope) => prefixed.map((name) => `${scope}_${name}`)),
249
+ ...prefixed,
250
+ key,
251
+ ];
252
+ })
253
+ .distinct()
254
+ .toArray();
177
255
  }
178
256
  /**
179
257
  * Every value that resolves for `input`, in source-then-key precedence order,
180
258
  * as a LAZY sequence: nothing past the first consumed element is read, so
181
- * `values(key).first()` never spawns the Databricks CLI when the environment
259
+ * `values(key).at(0)` never spawns the Databricks CLI when the environment
182
260
  * already answered.
183
261
  *
184
262
  */
185
263
  function values(input, options = {}) {
186
264
  const candidates = keys(input, options);
187
- const sources = object.sequence(options.sources ?? DEFAULT_SOURCES);
265
+ const sources = configSources(options);
188
266
  return object.sequence({
189
267
  *[Symbol.iterator]() {
190
268
  for (const source of sources) {
191
- for (const map of read(source, options.cwd)) {
269
+ for (const map of read(source, options)) {
192
270
  for (const key of candidates) {
193
- const value = stringModule.trimToNull(map[key]);
271
+ const value = configMapValue(map[key]);
194
272
  if (value !== null)
195
273
  yield { key, source, value };
196
274
  }
@@ -199,6 +277,26 @@ function values(input, options = {}) {
199
277
  },
200
278
  });
201
279
  }
280
+ function configSources(options) {
281
+ const sources = [
282
+ ...object.sequence(options.sources ?? DEFAULT_SOURCES).distinct(),
283
+ ];
284
+ if (options.data !== undefined && options.sources !== undefined && !sources.includes("config")) {
285
+ sources.push("config");
286
+ }
287
+ return sources;
288
+ }
289
+ function configMapValue(value) {
290
+ if (Array.isArray(value)) {
291
+ for (const entry of value) {
292
+ const resolved = sharedString.trimToNull(entry);
293
+ if (resolved !== null)
294
+ return resolved;
295
+ }
296
+ return null;
297
+ }
298
+ return sharedString.trimToNull(value);
299
+ }
202
300
  /**
203
301
  * The first value that resolves for `input`, or `undefined`.
204
302
  *
@@ -208,6 +306,10 @@ function values(input, options = {}) {
208
306
  export function text(input, options = {}) {
209
307
  return values(input, options).at(0)?.value;
210
308
  }
309
+ /** Resolve a human-friendly name through {@link environmentKeys} and {@link text}. */
310
+ export function resolveValue(name, options = {}) {
311
+ return text(environmentKeys(name), options);
312
+ }
211
313
  /**
212
314
  * The PRIMARY (fully-scoped) name for `input` - what to print in a log line or an
213
315
  * error, so the message names the variable a reader should set. Do not index
@@ -224,7 +326,7 @@ export function name(input, options = {}) {
224
326
  * Known long and short names are interchangeable; unknown names pass through.
225
327
  */
226
328
  function nodeEnvNames(nodeEnv) {
227
- const name = stringModule.trimToNull(nodeEnv)?.toLowerCase();
329
+ const name = sharedString.trimToNull(nodeEnv)?.toLowerCase();
228
330
  if (!name || !/^[a-z0-9_-]+$/.test(name))
229
331
  return [];
230
332
  for (const [canonical, alternatives] of Object.entries(NODE_ENV_ALTERNATIVES)) {
@@ -235,12 +337,6 @@ function nodeEnvNames(nodeEnv) {
235
337
  }
236
338
  return [name];
237
339
  }
238
- function join(...parts) {
239
- return parts
240
- .map((part) => part.trim())
241
- .filter(Boolean)
242
- .join("_");
243
- }
244
340
  /**
245
341
  * Resolve a string: `configured` when non-empty, else {@link text}, else `undefined`.
246
342
  *
@@ -251,7 +347,7 @@ function join(...parts) {
251
347
  * config.string(options.host, "SMTP_HOST");
252
348
  */
253
349
  export function string(configured, input, options) {
254
- return stringModule.trimToNull(configured) ?? text(input, options);
350
+ return sharedString.trimToNull(configured) ?? text(input, options);
255
351
  }
256
352
  /**
257
353
  * Resolve a boolean through `object.toBoolean`. `undefined` when neither source
@@ -265,7 +361,11 @@ export function boolean(configured, input, options) {
265
361
  * Use {@link positiveInt} for a count, port, or timeout.
266
362
  */
267
363
  export function positiveNumber(configured, input, fallback, options) {
268
- return toPositiveNumber(configured) ?? toPositiveNumber(text(input, options)) ?? fallback;
364
+ const fromConfig = positiveNumberValue.safeParse(configured);
365
+ if (fromConfig.success)
366
+ return fromConfig.data;
367
+ const fromSources = positiveNumberValue.safeParse(text(input, options));
368
+ return fromSources.success ? fromSources.data : fallback;
269
369
  }
270
370
  /**
271
371
  * Resolve a positive integer (a port, a timeout, a page size), floored. A
@@ -273,226 +373,123 @@ export function positiveNumber(configured, input, fallback, options) {
273
373
  * these are ceilings where a sane default beats a boot failure.
274
374
  */
275
375
  export function positiveInt(configured, input, fallback, options) {
276
- const resolved = positiveNumber(configured, input, fallback, options);
277
- return Math.floor(resolved);
376
+ const fromConfig = positiveIntValue.safeParse(configured);
377
+ if (fromConfig.success)
378
+ return fromConfig.data;
379
+ const fromSources = positiveIntValue.safeParse(text(input, options));
380
+ return fromSources.success ? fromSources.data : Math.floor(fallback);
381
+ }
382
+ /**
383
+ * Resolve a TCP port between 1 and {@link MAX_TCP_PORT}. Invalid configured or
384
+ * sourced values fall back to the caller's default, which may be a sentinel
385
+ * such as `0` when the caller uses one.
386
+ */
387
+ export function port(configured, input, fallback, options) {
388
+ const fromConfig = portValueSchema.safeParse(configured);
389
+ if (fromConfig.success)
390
+ return fromConfig.data;
391
+ const fromSources = portValueSchema.safeParse(text(input, options));
392
+ return fromSources.success ? fromSources.data : fallback;
278
393
  }
279
394
  /**
280
395
  * Resolve a list through `string.parseList`, so an array from typed config and a
281
396
  * `"a, b c"` string normalize identically. `[]` when neither source has entries.
282
397
  */
283
398
  export function list(configured, input, transform, options) {
284
- const fromConfig = stringModule.parseList(configured, transform);
399
+ const fromConfig = sharedString.parseList(configured, transform);
285
400
  return fromConfig.length > 0
286
401
  ? fromConfig
287
- : stringModule.parseList(text(input, options), transform);
288
- }
289
- function toPositiveNumber(value) {
290
- const parsed = object.toNumber(value);
291
- return parsed !== undefined && parsed > 0 ? parsed : undefined;
402
+ : sharedString.parseList(text(input, options), transform);
292
403
  }
293
404
  /**
294
405
  * The Databricks bundle output for `cwd` - `databricks bundle validate --output
295
406
  * json` run from the directory holding `databricks.yml`, with the config file's
296
407
  * path. A non-zero validation may still return partial JSON with usable App
297
- * config. `undefined` when bundle reads are disabled, this is not an AppKit
298
- * project, the bundle does not describe exactly one app with `config.env`, there
299
- * is no bundle, or the CLI produces no JSON.
408
+ * config. `undefined` when bundle reads are disabled, the process is production
409
+ * or a deployed App without an explicit override, there is no bundle, or the
410
+ * CLI produces no JSON.
300
411
  *
301
- * The spawn is guarded because it is expensive and usually pointless. In order:
302
- * `@databricks/appkit` must be RESOLVABLE (no AppKit, no bundle - and the probe
303
- * never evaluates the module); the bundle must describe exactly ONE app carrying
304
- * `config.env`; and AppKit's execution context must confirm this process is that
305
- * app. Only the confirmation is remembered, so a lookup during boot - before any
306
- * context exists - still resolves from the bundle and re-confirms later.
412
+ * Parsed validation output is cached by bundle path and Databricks profile.
307
413
  *
308
- * Cached once per resolved working-directory context and
309
- * `DATABRICKS_CONFIG_PROFILE` through {@link context.cached}, so repeated
310
- * lookups do not rerun validation and changing either cannot return another
311
- * context's bundle.
312
414
  */
313
415
  export function bundleFile(cwd) {
314
- const production = process.env.NODE_ENV?.trim().toLowerCase() === "production";
315
416
  const override = object.toBoolean(process.env[CONFIG_BUNDLE_KEY]);
316
417
  if (override === false)
317
418
  return undefined;
318
- // An explicit `true` is the escape hatch for a tool that wants the bundle
319
- // without being the app (`dbx` commands, tests), so it skips the AppKit gate
320
- // entirely - but not the App/production defaults, which it also overrides.
321
- if (override === undefined) {
322
- if (production || isDatabricksAppEnv())
323
- return undefined;
324
- if (!appKitInstalled())
325
- return undefined;
419
+ if (override === undefined &&
420
+ (process.env.NODE_ENV?.trim().toLowerCase() === "production" || isDatabricksAppEnv())) {
421
+ return undefined;
326
422
  }
327
- const profile = stringModule.trimToNull(process.env.DATABRICKS_CONFIG_PROFILE);
328
- const file = cachedConfig(["bundle", profile ?? ""], cwd, (resolved) => loadBundleFile(resolved, profile));
329
- if (override !== undefined || file === undefined)
330
- return file;
331
- // Already confirmed: this process is the app, and that does not stop being
332
- // true, so skip re-deriving the gate on every lookup.
333
- if (appKitContext)
334
- return file;
335
- // The app must be unambiguous. `bundleApp` is what decides "exactly one app
336
- // with `config.env`", so an empty map IS the ambiguous or app-less bundle and
337
- // needs no separate check.
338
- if (Object.keys(bundleApp(file.data)).length === 0)
423
+ const resolved = resolveWorkingDirectory(cwd);
424
+ return loadBundleFile(resolved, sharedString.trimToNull(process.env.DATABRICKS_CONFIG_PROFILE));
425
+ }
426
+ /** The parsed `app.yaml` / `app.yml` for `cwd`, when local App config reads are enabled. */
427
+ export function appFile(cwd) {
428
+ const enabled = object.toBoolean(process.env[CONFIG_APP_KEY]) ?? !isDatabricksAppEnv();
429
+ if (!enabled)
339
430
  return undefined;
340
- confirmAppKitContext();
341
- return file;
431
+ return loadAppFile(resolveWorkingDirectory(cwd));
342
432
  }
343
- /**
344
- * The single App's literal `config.env` entries, flattened to `name -> value`.
345
- *
346
- * A `value_from` entry names a bundle resource whose id is known after
347
- * deployment, and reading it needs the resource vocabulary this module
348
- * deliberately does not have - node-appkit resolves those against its extended
349
- * {@link bundleResourceSchema}. An `apps` block with more than one app is
350
- * ambiguous (nothing here says which app this process is), so it yields nothing
351
- * rather than a guess.
352
- *
353
- * Memoized against the parsed bundle it came from, because both the gate in
354
- * {@link bundleFile} and the lookup in {@link read} ask the same question of the
355
- * same cached object - validating that payload twice per lookup would be pure
356
- * waste. A `WeakMap` keeps the entry alive exactly as long as the bundle is.
357
- */
358
- function bundleApp(input) {
359
- if (!object.isRecord(input))
360
- return bundleAppEntries(input);
361
- const cached = BUNDLE_APP_CACHE.get(input);
362
- if (cached)
363
- return cached;
364
- const result = bundleAppEntries(input);
365
- BUNDLE_APP_CACHE.set(input, result);
366
- return result;
433
+ /** The single bundle App's resolved environment, when available. */
434
+ function bundleEnvironment(options) {
435
+ const data = sourceData(options.bundleData) ?? bundleFile(options.cwd)?.data;
436
+ return data ? flattenBundleEnv(data) : undefined;
367
437
  }
368
- /** {@link bundleApp} without the memoization, so the cache has one filler. */
369
- function bundleAppEntries(input) {
370
- const parsed = bundleAppsSchema.safeParse(input);
371
- if (!parsed.success)
372
- return {};
373
- const apps = parsed.data.resources?.apps;
374
- if (!apps)
375
- return {};
376
- const names = Object.keys(apps);
377
- if (names.length !== 1)
378
- return {};
379
- const entries = apps[names[0]]?.config?.env ?? [];
380
- const result = {};
381
- for (const entry of entries) {
382
- if (!entry.name)
383
- continue;
384
- const value = resolvedString(entry.value);
385
- if (value !== null)
386
- result[entry.name] = value;
387
- }
388
- return result;
438
+ function appEnvironment(options) {
439
+ const data = sourceData(options.appData) ?? appFile(options.cwd)?.data;
440
+ return data ? flattenAppEnv(data) : undefined;
389
441
  }
390
- /**
391
- * Whether `@databricks/appkit` can be RESOLVED from this process, cached for its
392
- * lifetime.
393
- *
394
- * Resolution, not import: this answers "is this an AppKit project" without
395
- * evaluating the module, so the cheap negative (a plain library or CLI consumer
396
- * that never installed the optional peer) costs one path lookup and never boots
397
- * AppKit as a side effect of reading config. A runtime with no `createRequire`
398
- * (a browser bundle that reached this Node-only module anyway) reports absent.
399
- */
400
- const appKitInstalled = functionModule.memoize(() => {
401
- try {
402
- // Indirect specifier: a bundler must not try to follow an OPTIONAL peer that
403
- // a browser build has no way to resolve.
404
- const specifier = APPKIT_MODULE;
405
- createRequire(import.meta.url).resolve(specifier);
406
- return true;
407
- }
408
- catch {
409
- return false;
410
- }
411
- });
412
- /**
413
- * AppKit's execution context once it exists, or `undefined`.
414
- *
415
- * Lazily imported (and `@vite-ignore`d) because `@databricks/appkit` is an
416
- * OPTIONAL peer this module must never make required. The import is only
417
- * attempted once {@link appKitInstalled} says there is something to import, and a
418
- * failure resolves to `undefined` rather than rejecting - a missing peer is the
419
- * expected path, not an error.
420
- *
421
- * `getExecutionContext()` THROWS until AppKit has booted, so the call is caught
422
- * and only a real context is reported. The module handle is memoized; the
423
- * context lookup is not, so a call before boot answers "not yet" and a later one
424
- * still sees the context.
425
- */
426
- const appKitModule = functionModule.memoize(async () => {
427
- if (!appKitInstalled())
442
+ function sourceData(source) {
443
+ if (!source)
428
444
  return undefined;
429
- const specifier = APPKIT_MODULE;
430
- return (await import(__rewriteRelativeImportExtension(/* @vite-ignore */ specifier)).catch(() => undefined));
431
- });
432
- /**
433
- * Latch {@link appKitContext} once AppKit's execution context exists.
434
- *
435
- * Fire-and-forget, because the caller is a SYNCHRONOUS lookup and the check
436
- * needs a lazy import. The affirmative is all that is stored: AppKit's context
437
- * does not exist until it boots, and `getExecutionContext()` throws until then,
438
- * so remembering a negative would permanently disable the bundle for a process
439
- * that is seconds away from having one. Every call before the latch closes
440
- * re-attempts, which is what makes "not available yet" retry rather than stick.
441
- */
442
- function confirmAppKitContext() {
443
- void appKitModule()
444
- .then((appkit) => {
445
- if (!appkit)
446
- return;
447
- try {
448
- if (appkit.getExecutionContext()?.client)
449
- appKitContext = true;
450
- }
451
- catch {
452
- // AppKit has not booted yet; a later call re-checks.
453
- }
454
- })
455
- .catch(() => undefined);
456
- }
457
- /** A non-empty bundle value with every `${...}` interpolation resolved. */
458
- function resolvedString(value) {
459
- const parsed = bundleValue.safeParse(value);
460
- return parsed.success ? parsed.data : null;
445
+ if ("path" in source && typeof source.path === "string" && object.isRecord(source.data)) {
446
+ return source.data;
447
+ }
448
+ return source;
461
449
  }
462
- /** Parsed `.env` for `cwd`, or `{}`. Read once per resolved context. */
450
+ /** Parsed `.env` for `cwd`, or `{}`; parsed file data is cached by path. */
463
451
  function dotenv(cwd) {
464
- if (!fileSourceEnabled(CONFIG_DOTENV_KEY))
452
+ const enabled = object.toBoolean(process.env[CONFIG_DOTENV_KEY]) ?? !isDatabricksAppEnv();
453
+ if (!enabled)
465
454
  return {};
466
- const environments = nodeEnvNames(process.env.NODE_ENV);
467
- return cachedConfig(["dotenv", ...environments], cwd, (resolved) => loadDotenv(resolved, environments));
455
+ const resolved = resolveWorkingDirectory(cwd);
456
+ return loadDotenv(resolved, nodeEnvNames(process.env.NODE_ENV));
468
457
  }
469
- /** Cache every target directory separately within the active process context. */
470
- function cachedConfig(name, cwd, loader) {
471
- const active = context.getContext() ?? "";
472
- const resolved = resolve(cwd ?? ".");
473
- return context.cached(["config", active, resolved, ...name], () => loader(resolved));
474
- }
475
- /**
476
- * Maps for one source in precedence order. Bundle App config and root variables
477
- * stay separate so a first-match lookup does not parse variables after an App
478
- * value resolves.
479
- */
480
- function read(source, cwd) {
458
+ /** Maps for one source in precedence order. */
459
+ function read(source, options) {
481
460
  return object.sequence({
482
461
  *[Symbol.iterator]() {
483
462
  switch (source) {
463
+ case "config": {
464
+ const data = options.data;
465
+ if (Array.isArray(data)) {
466
+ yield* data;
467
+ }
468
+ else if (data !== undefined) {
469
+ yield data;
470
+ }
471
+ break;
472
+ }
484
473
  case "env":
485
474
  yield process.env;
486
475
  break;
487
476
  case "dotenv":
488
- yield dotenv(cwd);
477
+ yield dotenv(options.cwd);
489
478
  break;
490
479
  case "bundle": {
491
- const bundle = bundleFile(cwd);
492
- if (bundle)
493
- yield bundleApp(bundle.data);
480
+ const environment = bundleEnvironment(options);
481
+ if (environment)
482
+ yield environment;
494
483
  break;
495
484
  }
485
+ case "app": {
486
+ const environment = appEnvironment(options);
487
+ if (environment)
488
+ yield environment;
489
+ break;
490
+ }
491
+ default:
492
+ throw new TypeError(`Unknown config source: ${source}`);
496
493
  }
497
494
  },
498
495
  });
@@ -503,6 +500,9 @@ function read(source, cwd) {
503
500
  */
504
501
  function findConfigFile(cwd, names) {
505
502
  const start = resolve(cwd);
503
+ const key = JSON.stringify([start, ...names]);
504
+ if (configFileCache.has(key))
505
+ return configFileCache.get(key);
506
506
  const root = resolveProjectRoot(start);
507
507
  const pathFromRoot = root ? relative(root, start) : undefined;
508
508
  const boundary = root &&
@@ -515,61 +515,81 @@ function findConfigFile(cwd, names) {
515
515
  for (let dir = start;; dir = dirname(dir)) {
516
516
  for (const name of names) {
517
517
  const path = resolve(dir, name);
518
- if (statSync(path)?.isFile())
518
+ if (statSync(path)?.isFile()) {
519
+ configFileCache.set(key, path);
519
520
  return path;
521
+ }
520
522
  }
521
523
  if (boundary === undefined || dir === boundary)
522
524
  break;
523
525
  }
526
+ configFileCache.set(key, undefined);
524
527
  return undefined;
525
528
  }
526
- /** A recognized source override, else the caller's automatic default. */
527
- function fileSourceEnabled(key, fallback = !isDatabricksAppEnv()) {
528
- return object.toBoolean(process.env[key]) ?? fallback;
529
- }
530
529
  function loadDotenv(cwd, environments) {
531
530
  const names = [...environments.map((name) => `${DOTENV_FILE_NAME}.${name}`), DOTENV_FILE_NAME];
532
531
  const path = findConfigFile(cwd, names);
533
532
  if (!path)
534
533
  return {};
535
- try {
536
- return parseEnv(readFileSync(path, "utf8"));
537
- }
538
- catch {
539
- logger.warn("failed to read dotenv file", { path });
540
- return {};
541
- }
534
+ return (cachedRecord(JSON.stringify(["dotenv", path]), () => {
535
+ try {
536
+ return parseEnv(readFileSync(path, "utf8"));
537
+ }
538
+ catch {
539
+ logger.warn("failed to read dotenv file", { path });
540
+ return {};
541
+ }
542
+ }) ?? {});
542
543
  }
543
544
  function loadBundleFile(cwd, profile) {
544
545
  const path = findConfigFile(cwd, BUNDLE_FILE_NAMES);
545
546
  if (!path)
546
547
  return undefined;
547
- const args = [
548
- "bundle",
549
- "validate",
550
- "--output",
551
- "json",
552
- ...(profile === null ? [] : ["--profile", profile]),
553
- ];
554
- const result = spawnSync("databricks", args, {
555
- cwd: resolve(path, ".."),
556
- encoding: "utf8",
557
- stdio: ["ignore", "pipe", "pipe"],
548
+ const data = cachedRecord(JSON.stringify(["bundle", path, profile]), () => {
549
+ const args = [
550
+ "bundle",
551
+ "validate",
552
+ "--output",
553
+ "json",
554
+ ...(profile === null ? [] : ["--profile", profile]),
555
+ ];
556
+ const result = spawnSync("databricks", args, {
557
+ cwd: resolve(path, ".."),
558
+ encoding: "utf8",
559
+ stdio: ["ignore", "pipe", "pipe"],
560
+ });
561
+ const output = sharedString.trimToNull(result.stdout);
562
+ const error = sharedString.trimToNull(result.stderr);
563
+ if (output === null) {
564
+ logger.debug("bundle validate produced no JSON", { path, status: result.status, error });
565
+ return undefined;
566
+ }
567
+ const parsed = json.parseRecord(output);
568
+ if (!parsed) {
569
+ logger.warn("failed to parse bundle validate output", { path, status: result.status });
570
+ return undefined;
571
+ }
572
+ if (result.status !== 0) {
573
+ logger.debug("using partial bundle output", { path, status: result.status, error });
574
+ }
575
+ return parsed;
558
576
  });
559
- const output = stringModule.trimToNull(result.stdout);
560
- const error = stringModule.trimToNull(result.stderr);
561
- if (output === null) {
562
- logger.debug("bundle validate produced no JSON", { path, status: result.status, error });
563
- return undefined;
564
- }
565
- const data = json.parseRecord(output);
566
- if (!data) {
567
- logger.warn("failed to parse bundle validate output", { path, status: result.status });
577
+ return data === undefined ? undefined : { path, data };
578
+ }
579
+ function loadAppFile(cwd) {
580
+ const path = findConfigFile(cwd, APP_FILE_NAMES);
581
+ if (!path)
568
582
  return undefined;
569
- }
570
- if (result.status !== 0) {
571
- logger.debug("using partial bundle output", { path, status: result.status, error });
572
- }
573
- return { path, data };
583
+ const data = cachedRecord(JSON.stringify(["app", path]), () => {
584
+ try {
585
+ const parsed = parseYaml(readFileSync(path, "utf8"));
586
+ return object.isRecord(parsed) ? parsed : undefined;
587
+ }
588
+ catch {
589
+ logger.warn("failed to parse app yaml", { path });
590
+ return undefined;
591
+ }
592
+ });
593
+ return data === undefined ? undefined : { path, data };
574
594
  }
575
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0RHOzs7Ozs7Ozs7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUNMLE9BQU8sRUFDUCxjQUFjLEVBQ2QsSUFBSSxFQUNKLEdBQUcsRUFDSCxNQUFNLEVBQ04sTUFBTSxJQUFJLFlBQVksR0FDdkIsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLElBQUksSUFBSSxrQkFBa0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUUxRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBaUNwQyxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUM7QUFDbEMsTUFBTSxlQUFlLEdBQTRCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM3RSxNQUFNLGlCQUFpQixHQUFHLENBQUMsZ0JBQWdCLEVBQUUsaUJBQWlCLENBQVUsQ0FBQztBQUN6RSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQztBQUNo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LENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JELElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3BCLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN6RixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0QyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN2RixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN0RixDQUFDO0lBQ0QsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUN4QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMYXllcmVkIGNvbmZpZ3VyYXRpb24gbG9va3VwOiBlbnZpcm9ubWVudCwgYC5lbnZgLCBEYXRhYnJpY2tzIGJ1bmRsZS5cbiAqXG4gKiBFdmVyeSBwYWNrYWdlIHJlc29sdmVzIHNldHRpbmdzIHRoZSBzYW1lIHdheTogdGFrZSB0aGUgY2FsbGVyJ3MgdmFsdWUsIGVsc2VcbiAqIGFuIGVudmlyb25tZW50IHZhcmlhYmxlLCBlbHNlIGEgZGVmYXVsdC4gTG9jYWwgZGV2ZWxvcG1lbnQgYWRkcyB0d28gZmFsbGJhY2tcbiAqIGxvY2F0aW9uczogYC5lbnZgIGZpbGVzIGFuZCBgcmVzb3VyY2VzLmFwcHMuPGFwcD4uY29uZmlnLmVudmAgb3Igcm9vdFxuICogYHZhcmlhYmxlc2AgaW4gYGRhdGFicmlja3MueW1sYC5cbiAqXG4gKiBUd28gdGhpbmdzIG1ha2UgaXQgY2hlYXAgdG8gY2FsbCBmcm9tIGEgaG90IHBhdGg6XG4gKlxuICogICAtIHtAbGluayB2YWx1ZXN9IGlzIExBWlkgKGFuIGBvYmplY3QuU2VxdWVuY2VgKSwgc28gYGRhdGFicmlja3MgYnVuZGxlXG4gKiAgICAgdmFsaWRhdGVgIGlzIG9ubHkgc3Bhd25lZCB3aGVuIHRoZSBlbnZpcm9ubWVudCBhbmQgYC5lbnZgIGJvdGggbWlzc2VkLlxuICogICAtIHRoZSBwYXJzZWQgYC5lbnZgIGFuZCBidW5kbGUgYXJlIGNhY2hlZCB0aHJvdWdoIHtAbGluayBjb250ZXh0LmNhY2hlZH0sIHNvXG4gKiAgICAgdGhlIHNwYXduIGhhcHBlbnMgb25jZSBwZXIgd29ya2luZyBkaXJlY3RvcnkgYW5kIGEgYGN3ZGAgY2hhbmdlIG1pc3Nlc1xuICogICAgIHJhdGhlciB0aGFuIHJldHVybmluZyBhbm90aGVyIHByb2plY3QncyBjb25maWcuXG4gKlxuICogSW5zaWRlIGEgZGVwbG95ZWQgRGF0YWJyaWNrcyBBcHAgYm90aCBmaWxlIHNvdXJjZXMgYXJlIHNraXBwZWQgYnkgZGVmYXVsdFxuICogKHtAbGluayBpc0RhdGFicmlja3NBcHBFbnZ9KTogdGhlIHBsYXRmb3JtIGhhcyBhbHJlYWR5IHR1cm5lZCB0aGVtIGludG8gcmVhbFxuICogZW52aXJvbm1lbnQgdmFyaWFibGVzLCB0aGVyZSBpcyBubyBidW5kbGUgdG8gdmFsaWRhdGUsIGFuZCB0aGUgYGRhdGFicmlja3NgXG4gKiBDTEkgaXMgbm90IG9uIHRoZSBpbWFnZS4gQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZXMgY2FuIGZvcmNlIGVpdGhlciBmaWxlXG4gKiBzb3VyY2Ugb24gb3Igb2ZmIHdoZW4gYSB0b29sIG5lZWRzIGRpZmZlcmVudCBiZWhhdmlvci5cbiAqXG4gKiBUaGUgYnVuZGxlIGlzIGdhdGVkIG9uIHRoaXMgYmVpbmcgYW4gQXBwS2l0IHByb2plY3QgYXQgYWxsLiBgZGF0YWJyaWNrcyBidW5kbGVcbiAqIHZhbGlkYXRlYCBpcyBhIHByb2Nlc3Mgc3Bhd24gbWVhc3VyZWQgaW4gc2Vjb25kcywgYW5kIGEgcGxhaW4gbGlicmFyeSBvciBDTElcbiAqIGNvbnN1bWVyIGhhcyBubyBidW5kbGUgdG8gZmluZCwgc28gdGhlIGdhdGUgcnVucyBpbiB0aHJlZSBzdGVwcyBiZWZvcmUgdGhlXG4gKiBzcGF3biBpcyBhbGxvd2VkIC0gc2VlIHtAbGluayBidW5kbGVGaWxlfTpcbiAqXG4gKiAgIDEuIGBAZGF0YWJyaWNrcy9hcHBraXRgIGlzIHJlc29sdmVkIFdJVEhPVVQgZXZhbHVhdGluZyBpdC4gSXQgaXMgYW4gb3B0aW9uYWxcbiAqICAgICAgcGVlciwgc28gYSBjb25zdW1lciB0aGF0IG5ldmVyIGluc3RhbGxlZCBpdCBpcyBub3QgYW4gQXBwS2l0IHByb2plY3QgYW5kXG4gKiAgICAgIHRoZSBidW5kbGUgaXMgbmV2ZXIgbG9hZGVkLiBUaGUgcHJvYmUgaXMgY2FjaGVkLCBzbyB0aGlzIGNvc3RzIG9uZVxuICogICAgICByZXNvbHV0aW9uIGZvciB0aGUgbGlmZSBvZiB0aGUgcHJvY2Vzcy5cbiAqICAgMi4gVGhlIGJ1bmRsZSBpcyByZWFkIChvbmNlIHBlciBjb250ZXh0KSBhbmQgbXVzdCBkZXNjcmliZSBFWEFDVExZIE9ORSBhcHBcbiAqICAgICAgd2l0aCBgY29uZmlnLmVudmAuIE5vdGhpbmcgaGVyZSBzYXlzIHdoaWNoIG9mIHNldmVyYWwgYXBwcyB0aGlzIHByb2Nlc3NcbiAqICAgICAgaXMsIHNvIGFuIGFtYmlndW91cyBidW5kbGUgY29udHJpYnV0ZXMgbm90aGluZyByYXRoZXIgdGhhbiBhIGd1ZXNzLlxuICogICAzLiBBcHBLaXQncyBleGVjdXRpb24gY29udGV4dCBjb25maXJtcyB0aGlzIHByb2Nlc3MgcmVhbGx5IGlzIHRoYXQgYXBwLiBUaGVcbiAqICAgICAgY29udGV4dCBkb2VzIG5vdCBleGlzdCB1bnRpbCBBcHBLaXQgYm9vdHMgYW5kIGBnZXRFeGVjdXRpb25Db250ZXh0KClgXG4gKiAgICAgIFRIUk9XUyB1bnRpbCB0aGVuLCBzbyB0aGUgcHJvYmUgaXMgY2F1Z2h0IGFuZCBvbmx5IHRoZSBhZmZpcm1hdGl2ZSBpc1xuICogICAgICByZW1lbWJlcmVkIC0gYSBsb29rdXAgYmVmb3JlIGJvb3Qgc3RpbGwgcmVzb2x2ZXMsIGFuZCByZS1jb25maXJtcyBsYXRlclxuICogICAgICBvbmNlIHRoZSBjb250ZXh0IGlzIGF2YWlsYWJsZS5cbiAqXG4gKiBPbmx5IHRoZSBzaW5nbGUgYXBwJ3MgYGNvbmZpZy5lbnZgIGlzIGNvbnN1bHRlZC4gUm9vdCBidW5kbGUgYHZhcmlhYmxlc2AgYXJlXG4gKiBub3Q6IHRoZXkgYXJlIGF1dGhvcmluZyBpbnB1dHMgZm9yIHRoZSBidW5kbGUgaXRzZWxmIChpbnRlcnBvbGF0ZWQgaW50b1xuICogdGFyZ2V0cywgcmVzb3VyY2VzLCBhbmQgcGF0aHMpLCBzbyB0cmVhdGluZyBvbmUgYXMgYSBwcm9jZXNzIHNldHRpbmcgcmVzb2x2ZXNcbiAqIG5hbWVzIHRoZSBkZXBsb3llZCBhcHAgbmV2ZXIgc2Vlcy5cbiAqXG4gKiBOb2RlLW9ubHkgKGBjaGlsZF9wcm9jZXNzYCwgYGZzYCwgYHByb2Nlc3NgKS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgc3Bhd25TeW5jIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGlzQWJzb2x1dGUsIHJlbGF0aXZlLCByZXNvbHZlLCBzZXAgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBwYXJzZUVudiB9IGZyb20gXCJub2RlOnV0aWxcIjtcbmltcG9ydCB7XG4gIGNvbnRleHQsXG4gIGZ1bmN0aW9uTW9kdWxlLFxuICBqc29uLFxuICBsb2csXG4gIG9iamVjdCxcbiAgc3RyaW5nIGFzIHN0cmluZ01vZHVsZSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBzdGF0U3luYyB9IGZyb20gXCIuL2ZpbGUudHNcIjtcbmltcG9ydCB7IHJvb3QgYXMgcmVzb2x2ZVByb2plY3RSb290IH0gZnJvbSBcIi4vcHJvamVjdC50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiY29uZmlnXCIpO1xuXG5leHBvcnQgdHlwZSBDb25maWdLZXkgPSBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXTtcblxuLyoqIFdoZXJlIGEgdmFsdWUgbWF5IGNvbWUgZnJvbSwgY29uc3VsdGVkIGluIHRoZSBvcmRlciBnaXZlbi4gKi9cbmV4cG9ydCB0eXBlIENvbmZpZ1NvdXJjZSA9IFwiZW52XCIgfCBcImRvdGVudlwiIHwgXCJidW5kbGVcIjtcblxuZXhwb3J0IGludGVyZmFjZSBDb25maWdPcHRpb25zIHtcbiAgLyoqXG4gICAqIE91dGVybW9zdCBuYW1lc3BhY2VzIHRyaWVkIGJlZm9yZSBlYWNoIGtleS4gRGVmYXVsdHMgdG8gYERCWF9UT09MU2AuXG4gICAqL1xuICBzY29wZT86IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuICAvKiogQ2FwYWJpbGl0eSBuYW1lc3BhY2VzIGluc2VydGVkIGFmdGVyIHRoZSBzY29wZSBhbmQgYmVmb3JlIGVhY2gga2V5LiAqL1xuICBwcmVmaXg/OiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqIERpcmVjdG9yeSB0byByZXNvbHZlIGAuZW52YCBhbmQgdGhlIGJ1bmRsZSBmcm9tLiBEZWZhdWx0OiBgcHJvY2Vzcy5jd2QoKWAuICovXG4gIGN3ZD86IHN0cmluZztcbiAgLyoqIFNvdXJjZXMgaW4gcHJlY2VkZW5jZSBvcmRlci4gRGVmYXVsdDogYGVudmAsIGBkb3RlbnZgLCBgYnVuZGxlYC4gKi9cbiAgc291cmNlcz86IENvbmZpZ1NvdXJjZSB8IHJlYWRvbmx5IENvbmZpZ1NvdXJjZVtdO1xufVxuXG4vKiogT25lIHJlc29sdmVkIHZhbHVlLCB0YWdnZWQgd2l0aCB0aGUga2V5IGFuZCBzb3VyY2UgaXQgY2FtZSBmcm9tLiAqL1xuaW50ZXJmYWNlIENvbmZpZ1ZhbHVlIHtcbiAga2V5OiBzdHJpbmc7XG4gIHNvdXJjZTogQ29uZmlnU291cmNlO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG4vKiogQSBjb25maWcgZmlsZSBmb3VuZCBvbiBkaXNrLCB3aXRoIGl0cyBwYXJzZWQgY29udGVudHMuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpZ0ZpbGUge1xuICBwYXRoOiBzdHJpbmc7XG4gIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG5jb25zdCBERUZBVUxUX1NDT1BFID0gXCJEQlhfVE9PTFNcIjtcbmNvbnN0IERFRkFVTFRfU09VUkNFUzogcmVhZG9ubHkgQ29uZmlnU291cmNlW10gPSBbXCJlbnZcIiwgXCJkb3RlbnZcIiwgXCJidW5kbGVcIl07XG5jb25zdCBCVU5ETEVfRklMRV9OQU1FUyA9IFtcImRhdGFicmlja3MueW1sXCIsIFwiZGF0YWJyaWNrcy55YW1sXCJdIGFzIGNvbnN0O1xuY29uc3QgRE9URU5WX0ZJTEVfTkFNRSA9IFwiLmVudlwiO1xuY29uc3QgTk9ERV9FTlZfQUxURVJOQVRJVkVTID0ge1xuICBwcm9kdWN0aW9uOiBbXCJwcm9kXCJdLFxuICBkZXZlbG9wbWVudDogW1wiZGV2XCJdLFxufSBhcyBjb25zdCBzYXRpc2ZpZXMgUmVjb3JkPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+O1xuXG4vKiogSGlnaGVzdCB2YWxpZCBUQ1AgcG9ydCBudW1iZXIuICovXG5leHBvcnQgY29uc3QgTUFYX1RDUF9QT1JUID0gNjVfNTM1O1xuXG4vKiogQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZSBmb3Ige0BsaW5rIGlzRGF0YWJyaWNrc0FwcEVudn0uICovXG5leHBvcnQgY29uc3QgREFUQUJSSUNLU19BUFBfRU5WX0tFWSA9IFwiREJYX1RPT0xTX0RBVEFCUklDS1NfQVBQX0VOVlwiO1xuXG4vKiogQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZSBmb3IgcHJvamVjdCBgLmVudmAgcmVhZHMuICovXG5leHBvcnQgY29uc3QgQ09ORklHX0RPVEVOVl9LRVkgPSBcIkRCWF9UT09MU19DT05GSUdfRE9URU5WXCI7XG5cbi8qKiBCb29sZWFuIGVudmlyb25tZW50IG92ZXJyaWRlIGZvciBEYXRhYnJpY2tzIGJ1bmRsZSByZWFkcy4gKi9cbmV4cG9ydCBjb25zdCBDT05GSUdfQlVORExFX0tFWSA9IFwiREJYX1RPT0xTX0NPTkZJR19CVU5ETEVcIjtcblxuLyoqXG4gKiBUaGUgT1BUSU9OQUwgQXBwS2l0IHBlZXIgd2hvc2UgcHJlc2VuY2UgbWFya3MgdGhpcyBhcyBhIERhdGFicmlja3MgQXBwXG4gKiBwcm9qZWN0LiBIZWxkIGFzIGEgY29uc3RhbnQgc28gdGhlIHJlc29sdmUgcHJvYmUgYW5kIHRoZSBsYXp5IGltcG9ydCBuYW1lIGl0XG4gKiBvbmNlLCBhbmQgc28gbmVpdGhlciBzaXRlIGNhcnJpZXMgYSBsaXRlcmFsIGEgYnVuZGxlciB3b3VsZCB0cnkgdG8gZm9sbG93LlxuICovXG5jb25zdCBBUFBLSVRfTU9EVUxFID0gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcblxuLyoqXG4gKiBUaGUgb25lIHRoaW5nIHRoaXMgbW9kdWxlIG5lZWRzIGZyb20gQXBwS2l0OiB3aGV0aGVyIGEgcmVhbCBleGVjdXRpb24gY29udGV4dFxuICogaXMgYWN0aXZlLiBUeXBlZCBzdHJ1Y3R1cmFsbHkgc28gYW4gT1BUSU9OQUwgcGVlciBuZXZlciBiZWNvbWVzIGEgdHlwZVxuICogZGVwZW5kZW5jeSwgYW5kIGBjbGllbnRgIGlzIGB1bmtub3duYCBiZWNhdXNlIGl0cyBwcmVzZW5jZSBpcyBhbGwgdGhhdCBpcyByZWFkLlxuICovXG50eXBlIEFwcEtpdE1vZHVsZSA9IHtcbiAgZ2V0RXhlY3V0aW9uQ29udGV4dCgpOiB7IGNsaWVudD86IHVua25vd24gfSB8IHVuZGVmaW5lZDtcbn07XG5cbi8qKlxuICogV2hldGhlciBBcHBLaXQncyBleGVjdXRpb24gY29udGV4dCBoYXMgRVZFUiBiZWVuIG9ic2VydmVkLiBMYXRjaGluZyBpcyB0aGVcbiAqIHBvaW50OiBhIGNvbnRleHQgY29uZmlybXMgdGhpcyBwcm9jZXNzIGlzIHRoZSBidW5kbGUncyBhcHAsIGFuZCB0aGF0IGZhY3QgZG9lc1xuICogbm90IHN0b3AgYmVpbmcgdHJ1ZSB3aGVuIGEgbGF0ZXIgbG9va3VwIGhhcHBlbnMgb3V0c2lkZSBhIHJlcXVlc3Qgc2NvcGUuXG4gKi9cbmxldCBhcHBLaXRDb250ZXh0ID0gZmFsc2U7XG5cbi8qKiBGbGF0dGVuZWQgQXBwIGBjb25maWcuZW52YCBwZXIgcGFyc2VkIGJ1bmRsZSAtIHNlZSB7QGxpbmsgYnVuZGxlQXBwfS4gKi9cbmNvbnN0IEJVTkRMRV9BUFBfQ0FDSEUgPSBuZXcgV2Vha01hcDxvYmplY3QsIFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KCk7XG5cbi8qKiBFeGFjdCBwcm9jZXNzLWVudmlyb25tZW50IGxvb2t1cCBmb3IgY2FsbGVycyB0aGF0IGRvIG5vdCByZWFkIGxvY2FsIGNvbmZpZyBmaWxlcy4gKi9cbmV4cG9ydCBjb25zdCBFTlZfT05MWSA9IHsgc2NvcGU6IFtdIGFzIGNvbnN0LCBzb3VyY2VzOiBcImVudlwiIGFzIGNvbnN0IH07XG5cbmV4cG9ydCBjb25zdCBidW5kbGVWYWx1ZSA9IHpcbiAgLnN0cmluZygpXG4gIC50cmFuc2Zvcm0oKHZhbHVlOiBzdHJpbmcpID0+IHZhbHVlLnRyaW0oKSlcbiAgLnJlZmluZSgodmFsdWU6IHN0cmluZykgPT4gdmFsdWUubGVuZ3RoID4gMClcbiAgLnJlZmluZSgodmFsdWU6IHN0cmluZykgPT4gIS9cXCRcXHtbXn1dK1xcfS8udGVzdCh2YWx1ZSksIHtcbiAgICBtZXNzYWdlOiBcIkludGVycG9sYXRlZCB2YWx1ZXMgYXJlIG5vdCBhbGxvd2VkXCIsXG4gIH0pO1xuXG4vKipcbiAqIFRoZSBHRU5FUklDIHNoYXBlIG9mIGEgYnVuZGxlIHJlc291cmNlOiBhIG5hbWUsIGFuZCB3aGF0ZXZlciBlbHNlIHRoZSByZXNvdXJjZVxuICogdHlwZSBjYXJyaWVzLiBEZWxpYmVyYXRlbHkgdW5vcGluaW9uYXRlZCBhbmQgYHBhc3N0aHJvdWdoKClgIC0gdGhlIGNvbmNyZXRlXG4gKiByZXNvdXJjZSBraW5kcyAoYHNxbF93YXJlaG91c2VgLCBgZ2VuaWVfc3BhY2VgLCBgcG9zdGdyZXNgLCAuLi4pIGFyZVxuICogRGF0YWJyaWNrcy1BcHAgY29uY2VwdHMgdGhhdCBiZWxvbmcgdG8gdGhlIHBhY2thZ2UgdGhhdCByZXNvbHZlcyB0aGVtLCBzb1xuICogbm9kZS1hcHBraXQgYC5leHRlbmQoKWBzIHRoaXMgcmF0aGVyIHRoYW4gdGhpcyBtb2R1bGUga25vd2luZyBhYm91dCB0aGVtLlxuICovXG5leHBvcnQgY29uc3QgYnVuZGxlUmVzb3VyY2VTY2hlbWEgPSB6Lm9iamVjdCh7IG5hbWU6IGJ1bmRsZVZhbHVlLm9wdGlvbmFsKCkgfSkucGFzc3Rocm91Z2goKTtcblxuZXhwb3J0IGNvbnN0IGJ1bmRsZUVudkVudHJ5U2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiBidW5kbGVWYWx1ZS5vcHRpb25hbCgpLFxuICB2YWx1ZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB2YWx1ZV9mcm9tOiBidW5kbGVWYWx1ZS5vcHRpb25hbCgpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBidW5kbGVBcHBTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG5hbWU6IGJ1bmRsZVZhbHVlLm9wdGlvbmFsKCksXG4gIHNvdXJjZV9jb2RlX3BhdGg6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgY29uZmlnOiB6Lm9iamVjdCh7IGVudjogei5hcnJheShidW5kbGVFbnZFbnRyeVNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxuICByZXNvdXJjZXM6IHouYXJyYXkoYnVuZGxlUmVzb3VyY2VTY2hlbWEpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgYnVuZGxlQXBwc1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgcmVzb3VyY2VzOiB6Lm9iamVjdCh7IGFwcHM6IHoucmVjb3JkKHouc3RyaW5nKCksIGJ1bmRsZUFwcFNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxufSk7XG5cbi8qKlxuICogRGV0ZWN0IGEgRGF0YWJyaWNrcyBBcHAgcnVudGltZSBmcm9tIGl0cyByZXF1aXJlZCBuYW1lLCBob3N0LCBhbmQgcG9ydC5cbiAqXG4gKiBgREJYX1RPT0xTX0RBVEFCUklDS1NfQVBQX0VOVmAgdGFrZXMgcHJlY2VkZW5jZSB3aGVuIGl0IGNvbnRhaW5zIGEgcmVjb2duaXplZFxuICogYm9vbGVhbiB2YWx1ZS4gVGhpcyBsZXRzIGxvY2FsIHRvb2xzIGVtdWxhdGUgdGhlIGRlcGxveWVkIHJ1bnRpbWUgKGB0cnVlYCkgb3JcbiAqIGxldHMgdW51c3VhbCBkZXBsb3llZCBwcm9jZXNzZXMgcmV0YWluIGxvY2FsIGNvbmZpZyBsb29rdXAgKGBmYWxzZWApLiBBblxuICogYWJzZW50IG9yIHVucmVjb2duaXplZCBvdmVycmlkZSBmYWxscyBiYWNrIHRvIHN0cnVjdHVyYWwgZGV0ZWN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRhYnJpY2tzQXBwRW52KFxuICBzb3VyY2U6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gPSBwcm9jZXNzLmVudixcbik6IGJvb2xlYW4ge1xuICBjb25zdCBvdmVycmlkZSA9IG9iamVjdC50b0Jvb2xlYW4oc291cmNlW0RBVEFCUklDS1NfQVBQX0VOVl9LRVldKTtcbiAgaWYgKG92ZXJyaWRlICE9PSB1bmRlZmluZWQpIHJldHVybiBvdmVycmlkZTtcbiAgY29uc3QgYXBwTmFtZSA9IHNvdXJjZS5EQVRBQlJJQ0tTX0FQUF9OQU1FPy50cmltKCk7XG4gIGNvbnN0IGhvc3QgPSBzb3VyY2UuREFUQUJSSUNLU19IT1NUPy50cmltKCk7XG4gIGNvbnN0IHBvcnQgPSBzb3VyY2UuREFUQUJSSUNLU19BUFBfUE9SVD8udHJpbSgpO1xuICBpZiAoIWFwcE5hbWUgfHwgIWhvc3QgfHwgIXBvcnQpIHJldHVybiBmYWxzZTtcbiAgdHJ5IHtcbiAgICBpZiAoIVtcImh0dHA6XCIsIFwiaHR0cHM6XCJdLmluY2x1ZGVzKG5ldyBVUkwoaG9zdCkucHJvdG9jb2wpKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBwb3J0TnVtYmVyID0gb2JqZWN0LnRvTnVtYmVyKHBvcnQpO1xuICByZXR1cm4gKFxuICAgIHBvcnROdW1iZXIgIT09IHVuZGVmaW5lZCAmJlxuICAgIE51bWJlci5pc0ludGVnZXIocG9ydE51bWJlcikgJiZcbiAgICBwb3J0TnVtYmVyID49IDEgJiZcbiAgICBwb3J0TnVtYmVyIDw9IE1BWF9UQ1BfUE9SVFxuICApO1xufVxuXG4vKiogQ2FuZGlkYXRlIG5hbWVzIGluIHNjb3BlLCBwcmVmaXgsIGFuZCBpbnB1dCBwcmVjZWRlbmNlIG9yZGVyLiAqL1xuZnVuY3Rpb24ga2V5cyhpbnB1dDogQ29uZmlnS2V5LCBvcHRpb25zOiBQaWNrPENvbmZpZ09wdGlvbnMsIFwic2NvcGVcIiB8IFwicHJlZml4XCI+ID0ge30pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHNjb3BlcyA9IG9iamVjdC5zZXF1ZW5jZShvcHRpb25zLnNjb3BlID8/IERFRkFVTFRfU0NPUEUpLnRvQXJyYXkoKTtcbiAgY29uc3QgcHJlZml4ZXMgPSBvcHRpb25zLnByZWZpeCA9PT0gdW5kZWZpbmVkID8gW10gOiBvYmplY3Quc2VxdWVuY2Uob3B0aW9ucy5wcmVmaXgpLnRvQXJyYXkoKTtcbiAgcmV0dXJuIFtcbiAgICAuLi5vYmplY3RcbiAgICAgIC5zZXF1ZW5jZShpbnB1dClcbiAgICAgIC5mbGF0TWFwKChrZXkpID0+IHtcbiAgICAgICAgY29uc3QgcHJlZml4ZWQgPSBwcmVmaXhlcy5sZW5ndGggPiAwID8gcHJlZml4ZXMubWFwKChwcmVmaXgpID0+IGpvaW4ocHJlZml4LCBrZXkpKSA6IFtrZXldO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIC4uLnNjb3Blcy5mbGF0TWFwKChzY29wZSkgPT4gcHJlZml4ZWQubWFwKChrZXkpID0+IGpvaW4oc2NvcGUsIGtleSkpKSxcbiAgICAgICAgICAuLi5wcmVmaXhlZCxcbiAgICAgICAgICBrZXksXG4gICAgICAgIF07XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoa2V5KSA9PiBrZXkubGVuZ3RoID4gMClcbiAgICAgIC5kaXN0aW5jdCgpLFxuICBdO1xufVxuXG4vKipcbiAqIEV2ZXJ5IHZhbHVlIHRoYXQgcmVzb2x2ZXMgZm9yIGBpbnB1dGAsIGluIHNvdXJjZS10aGVuLWtleSBwcmVjZWRlbmNlIG9yZGVyLFxuICogYXMgYSBMQVpZIHNlcXVlbmNlOiBub3RoaW5nIHBhc3QgdGhlIGZpcnN0IGNvbnN1bWVkIGVsZW1lbnQgaXMgcmVhZCwgc29cbiAqIGB2YWx1ZXMoa2V5KS5maXJzdCgpYCBuZXZlciBzcGF3bnMgdGhlIERhdGFicmlja3MgQ0xJIHdoZW4gdGhlIGVudmlyb25tZW50XG4gKiBhbHJlYWR5IGFuc3dlcmVkLlxuICpcbiAqL1xuZnVuY3Rpb24gdmFsdWVzKGlucHV0OiBDb25maWdLZXksIG9wdGlvbnM6IENvbmZpZ09wdGlvbnMgPSB7fSk6IG9iamVjdC5TZXF1ZW5jZTxDb25maWdWYWx1ZT4ge1xuICBjb25zdCBjYW5kaWRhdGVzID0ga2V5cyhpbnB1dCwgb3B0aW9ucyk7XG4gIGNvbnN0IHNvdXJjZXMgPSBvYmplY3Quc2VxdWVuY2U8Q29uZmlnU291cmNlPihvcHRpb25zLnNvdXJjZXMgPz8gREVGQVVMVF9TT1VSQ0VTKTtcbiAgcmV0dXJuIG9iamVjdC5zZXF1ZW5jZSh7XG4gICAgKltTeW1ib2wuaXRlcmF0b3JdKCk6IEdlbmVyYXRvcjxDb25maWdWYWx1ZT4ge1xuICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICBmb3IgKGNvbnN0IG1hcCBvZiByZWFkKHNvdXJjZSwgb3B0aW9ucy5jd2QpKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgY2FuZGlkYXRlcykge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzdHJpbmdNb2R1bGUudHJpbVRvTnVsbChtYXBba2V5XSk7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHlpZWxkIHsga2V5LCBzb3VyY2UsIHZhbHVlIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogVGhlIGZpcnN0IHZhbHVlIHRoYXQgcmVzb2x2ZXMgZm9yIGBpbnB1dGAsIG9yIGB1bmRlZmluZWRgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBkb21haW4gPSBjb25maWcudGV4dChbXCJUVU5ORUxfUFVCTElDX0RPTUFJTlwiLCBcIlBVQkxJQ19ET01BSU5cIl0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGV4dChpbnB1dDogQ29uZmlnS2V5LCBvcHRpb25zOiBDb25maWdPcHRpb25zID0ge30pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdmFsdWVzKGlucHV0LCBvcHRpb25zKS5hdCgwKT8udmFsdWU7XG59XG5cbi8qKlxuICogVGhlIFBSSU1BUlkgKGZ1bGx5LXNjb3BlZCkgbmFtZSBmb3IgYGlucHV0YCAtIHdoYXQgdG8gcHJpbnQgaW4gYSBsb2cgbGluZSBvciBhblxuICogZXJyb3IsIHNvIHRoZSBtZXNzYWdlIG5hbWVzIHRoZSB2YXJpYWJsZSBhIHJlYWRlciBzaG91bGQgc2V0LiBEbyBub3QgaW5kZXhcbiAqIGBrZXlzKC4uLilbMF1gIGZvciB0aGlzIGlmIGBpbnB1dGAgbWF5IGJlIGEgYmFyZSBzdHJpbmcuXG4gKlxuICogQGV4YW1wbGVcbiAqIGxvZ2dlci53YXJuKGAke2NvbmZpZy5uYW1lKEpXVF9TRUNSRVRfRU5WKX0gaXMgbm90IHNldGApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gbmFtZShcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgb3B0aW9uczogUGljazxDb25maWdPcHRpb25zLCBcInNjb3BlXCIgfCBcInByZWZpeFwiPiA9IHt9LFxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIGtleXMoaW5wdXQsIG9wdGlvbnMpWzBdID8/IFwiXCI7XG59XG5cbi8qKlxuICogU2FmZSBgLmVudi48bmFtZT5gIHN1ZmZpeGVzIGZvciBhIE5vZGUgZW52aXJvbm1lbnQsIGV4YWN0IHNwZWxsaW5nIGZpcnN0LlxuICogS25vd24gbG9uZyBhbmQgc2hvcnQgbmFtZXMgYXJlIGludGVyY2hhbmdlYWJsZTsgdW5rbm93biBuYW1lcyBwYXNzIHRocm91Z2guXG4gKi9cbmZ1bmN0aW9uIG5vZGVFbnZOYW1lcyhub2RlRW52OiB1bmtub3duKTogc3RyaW5nW10ge1xuICBjb25zdCBuYW1lID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwobm9kZUVudik/LnRvTG93ZXJDYXNlKCk7XG4gIGlmICghbmFtZSB8fCAhL15bYS16MC05Xy1dKyQvLnRlc3QobmFtZSkpIHJldHVybiBbXTtcbiAgZm9yIChjb25zdCBbY2Fub25pY2FsLCBhbHRlcm5hdGl2ZXNdIG9mIE9iamVjdC5lbnRyaWVzKE5PREVfRU5WX0FMVEVSTkFUSVZFUykpIHtcbiAgICBjb25zdCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gPSBhbHRlcm5hdGl2ZXM7XG4gICAgaWYgKG5hbWUgPT09IGNhbm9uaWNhbCB8fCBuYW1lcy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgcmV0dXJuIFsuLi5vYmplY3Quc2VxdWVuY2UobmFtZSwgY2Fub25pY2FsLCBhbHRlcm5hdGl2ZXMpLmRpc3RpbmN0KCldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gW25hbWVdO1xufVxuXG5mdW5jdGlvbiBqb2luKC4uLnBhcnRzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIHJldHVybiBwYXJ0c1xuICAgIC5tYXAoKHBhcnQpID0+IHBhcnQudHJpbSgpKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAuam9pbihcIl9cIik7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHN0cmluZzogYGNvbmZpZ3VyZWRgIHdoZW4gbm9uLWVtcHR5LCBlbHNlIHtAbGluayB0ZXh0fSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqXG4gKiBUaGUgY29lcmNpb24gcnVsZXMgYXJlIGRlbGliZXJhdGVseSBsb29zZSAoYG9uYCAvIGB5ZXNgIC8gYDFgIGFyZSBhbGxcbiAqIGB0cnVlYCkgYmVjYXVzZSB2YWx1ZXMgbWF5IGNvbWUgZnJvbSBhIGZpbGUgYSBodW1hbiB0eXBlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uZmlnLnN0cmluZyhvcHRpb25zLmhvc3QsIFwiU01UUF9IT1NUXCIpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nKFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBzdHJpbmdNb2R1bGUudHJpbVRvTnVsbChjb25maWd1cmVkKSA/PyB0ZXh0KGlucHV0LCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgYm9vbGVhbiB0aHJvdWdoIGBvYmplY3QudG9Cb29sZWFuYC4gYHVuZGVmaW5lZGAgd2hlbiBuZWl0aGVyIHNvdXJjZVxuICogaXMgaW50ZXJwcmV0YWJsZSwgc28gdGhlIGNhbGxlciBwaWNrcyBhIGRlZmF1bHQgd2l0aCBgPz9gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYm9vbGVhbihcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIG9iamVjdC50b0Jvb2xlYW4oY29uZmlndXJlZCkgPz8gb2JqZWN0LnRvQm9vbGVhbih0ZXh0KGlucHV0LCBvcHRpb25zKSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHBvc2l0aXZlIG51bWJlciB0aGF0IG1heSBiZSBmcmFjdGlvbmFsIChhIHNjb3JlIHRocmVzaG9sZCwgYSByYXRpbykuXG4gKiBVc2Uge0BsaW5rIHBvc2l0aXZlSW50fSBmb3IgYSBjb3VudCwgcG9ydCwgb3IgdGltZW91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlTnVtYmVyKFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBmYWxsYmFjazogbnVtYmVyLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIHJldHVybiB0b1Bvc2l0aXZlTnVtYmVyKGNvbmZpZ3VyZWQpID8/IHRvUG9zaXRpdmVOdW1iZXIodGV4dChpbnB1dCwgb3B0aW9ucykpID8/IGZhbGxiYWNrO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBwb3NpdGl2ZSBpbnRlZ2VyIChhIHBvcnQsIGEgdGltZW91dCwgYSBwYWdlIHNpemUpLCBmbG9vcmVkLiBBXG4gKiBub24tbnVtZXJpYyBvciBub24tcG9zaXRpdmUgdmFsdWUgaXMgdHJlYXRlZCBhcyBBQlNFTlQgcmF0aGVyIHRoYW4gZmF0YWwgLVxuICogdGhlc2UgYXJlIGNlaWxpbmdzIHdoZXJlIGEgc2FuZSBkZWZhdWx0IGJlYXRzIGEgYm9vdCBmYWlsdXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9zaXRpdmVJbnQoXG4gIGNvbmZpZ3VyZWQ6IHVua25vd24sXG4gIGlucHV0OiBDb25maWdLZXksXG4gIGZhbGxiYWNrOiBudW1iZXIsXG4gIG9wdGlvbnM/OiBDb25maWdPcHRpb25zLFxuKTogbnVtYmVyIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBwb3NpdGl2ZU51bWJlcihjb25maWd1cmVkLCBpbnB1dCwgZmFsbGJhY2ssIG9wdGlvbnMpO1xuICByZXR1cm4gTWF0aC5mbG9vcihyZXNvbHZlZCk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGxpc3QgdGhyb3VnaCBgc3RyaW5nLnBhcnNlTGlzdGAsIHNvIGFuIGFycmF5IGZyb20gdHlwZWQgY29uZmlnIGFuZCBhXG4gKiBgXCJhLCBiIGNcImAgc3RyaW5nIG5vcm1hbGl6ZSBpZGVudGljYWxseS4gYFtdYCB3aGVuIG5laXRoZXIgc291cmNlIGhhcyBlbnRyaWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGlzdChcbiAgY29uZmlndXJlZDogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQgfCBudWxsLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICB0cmFuc2Zvcm0/OiAoZW50cnk6IHN0cmluZykgPT4gc3RyaW5nLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgZnJvbUNvbmZpZyA9IHN0cmluZ01vZHVsZS5wYXJzZUxpc3QoY29uZmlndXJlZCwgdHJhbnNmb3JtKTtcbiAgcmV0dXJuIGZyb21Db25maWcubGVuZ3RoID4gMFxuICAgID8gZnJvbUNvbmZpZ1xuICAgIDogc3RyaW5nTW9kdWxlLnBhcnNlTGlzdCh0ZXh0KGlucHV0LCBvcHRpb25zKSwgdHJhbnNmb3JtKTtcbn1cblxuZnVuY3Rpb24gdG9Qb3NpdGl2ZU51bWJlcih2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHBhcnNlZCA9IG9iamVjdC50b051bWJlcih2YWx1ZSk7XG4gIHJldHVybiBwYXJzZWQgIT09IHVuZGVmaW5lZCAmJiBwYXJzZWQgPiAwID8gcGFyc2VkIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFRoZSBEYXRhYnJpY2tzIGJ1bmRsZSBvdXRwdXQgZm9yIGBjd2RgIC0gYGRhdGFicmlja3MgYnVuZGxlIHZhbGlkYXRlIC0tb3V0cHV0XG4gKiBqc29uYCBydW4gZnJvbSB0aGUgZGlyZWN0b3J5IGhvbGRpbmcgYGRhdGFicmlja3MueW1sYCwgd2l0aCB0aGUgY29uZmlnIGZpbGUnc1xuICogcGF0aC4gQSBub24temVybyB2YWxpZGF0aW9uIG1heSBzdGlsbCByZXR1cm4gcGFydGlhbCBKU09OIHdpdGggdXNhYmxlIEFwcFxuICogY29uZmlnLiBgdW5kZWZpbmVkYCB3aGVuIGJ1bmRsZSByZWFkcyBhcmUgZGlzYWJsZWQsIHRoaXMgaXMgbm90IGFuIEFwcEtpdFxuICogcHJvamVjdCwgdGhlIGJ1bmRsZSBkb2VzIG5vdCBkZXNjcmliZSBleGFjdGx5IG9uZSBhcHAgd2l0aCBgY29uZmlnLmVudmAsIHRoZXJlXG4gKiBpcyBubyBidW5kbGUsIG9yIHRoZSBDTEkgcHJvZHVjZXMgbm8gSlNPTi5cbiAqXG4gKiBUaGUgc3Bhd24gaXMgZ3VhcmRlZCBiZWNhdXNlIGl0IGlzIGV4cGVuc2l2ZSBhbmQgdXN1YWxseSBwb2ludGxlc3MuIEluIG9yZGVyOlxuICogYEBkYXRhYnJpY2tzL2FwcGtpdGAgbXVzdCBiZSBSRVNPTFZBQkxFIChubyBBcHBLaXQsIG5vIGJ1bmRsZSAtIGFuZCB0aGUgcHJvYmVcbiAqIG5ldmVyIGV2YWx1YXRlcyB0aGUgbW9kdWxlKTsgdGhlIGJ1bmRsZSBtdXN0IGRlc2NyaWJlIGV4YWN0bHkgT05FIGFwcCBjYXJyeWluZ1xuICogYGNvbmZpZy5lbnZgOyBhbmQgQXBwS2l0J3MgZXhlY3V0aW9uIGNvbnRleHQgbXVzdCBjb25maXJtIHRoaXMgcHJvY2VzcyBpcyB0aGF0XG4gKiBhcHAuIE9ubHkgdGhlIGNvbmZpcm1hdGlvbiBpcyByZW1lbWJlcmVkLCBzbyBhIGxvb2t1cCBkdXJpbmcgYm9vdCAtIGJlZm9yZSBhbnlcbiAqIGNvbnRleHQgZXhpc3RzIC0gc3RpbGwgcmVzb2x2ZXMgZnJvbSB0aGUgYnVuZGxlIGFuZCByZS1jb25maXJtcyBsYXRlci5cbiAqXG4gKiBDYWNoZWQgb25jZSBwZXIgcmVzb2x2ZWQgd29ya2luZy1kaXJlY3RvcnkgY29udGV4dCBhbmRcbiAqIGBEQVRBQlJJQ0tTX0NPTkZJR19QUk9GSUxFYCB0aHJvdWdoIHtAbGluayBjb250ZXh0LmNhY2hlZH0sIHNvIHJlcGVhdGVkXG4gKiBsb29rdXBzIGRvIG5vdCByZXJ1biB2YWxpZGF0aW9uIGFuZCBjaGFuZ2luZyBlaXRoZXIgY2Fubm90IHJldHVybiBhbm90aGVyXG4gKiBjb250ZXh0J3MgYnVuZGxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVuZGxlRmlsZShjd2Q/OiBzdHJpbmcgfCBudWxsKTogQ29uZmlnRmlsZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHByb2R1Y3Rpb24gPSBwcm9jZXNzLmVudi5OT0RFX0VOVj8udHJpbSgpLnRvTG93ZXJDYXNlKCkgPT09IFwicHJvZHVjdGlvblwiO1xuICBjb25zdCBvdmVycmlkZSA9IG9iamVjdC50b0Jvb2xlYW4ocHJvY2Vzcy5lbnZbQ09ORklHX0JVTkRMRV9LRVldKTtcbiAgaWYgKG92ZXJyaWRlID09PSBmYWxzZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgLy8gQW4gZXhwbGljaXQgYHRydWVgIGlzIHRoZSBlc2NhcGUgaGF0Y2ggZm9yIGEgdG9vbCB0aGF0IHdhbnRzIHRoZSBidW5kbGVcbiAgLy8gd2l0aG91dCBiZWluZyB0aGUgYXBwIChgZGJ4YCBjb21tYW5kcywgdGVzdHMpLCBzbyBpdCBza2lwcyB0aGUgQXBwS2l0IGdhdGVcbiAgLy8gZW50aXJlbHkgLSBidXQgbm90IHRoZSBBcHAvcHJvZHVjdGlvbiBkZWZhdWx0cywgd2hpY2ggaXQgYWxzbyBvdmVycmlkZXMuXG4gIGlmIChvdmVycmlkZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHByb2R1Y3Rpb24gfHwgaXNEYXRhYnJpY2tzQXBwRW52KCkpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFhcHBLaXRJbnN0YWxsZWQoKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBwcm9maWxlID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19DT05GSUdfUFJPRklMRSk7XG4gIGNvbnN0IGZpbGUgPSBjYWNoZWRDb25maWcoW1wiYnVuZGxlXCIsIHByb2ZpbGUgPz8gXCJcIl0sIGN3ZCwgKHJlc29sdmVkKSA9PlxuICAgIGxvYWRCdW5kbGVGaWxlKHJlc29sdmVkLCBwcm9maWxlKSxcbiAgKTtcbiAgaWYgKG92ZXJyaWRlICE9PSB1bmRlZmluZWQgfHwgZmlsZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmlsZTtcbiAgLy8gQWxyZWFkeSBjb25maXJtZWQ6IHRoaXMgcHJvY2VzcyBpcyB0aGUgYXBwLCBhbmQgdGhhdCBkb2VzIG5vdCBzdG9wIGJlaW5nXG4gIC8vIHRydWUsIHNvIHNraXAgcmUtZGVyaXZpbmcgdGhlIGdhdGUgb24gZXZlcnkgbG9va3VwLlxuICBpZiAoYXBwS2l0Q29udGV4dCkgcmV0dXJuIGZpbGU7XG4gIC8vIFRoZSBhcHAgbXVzdCBiZSB1bmFtYmlndW91cy4gYGJ1bmRsZUFwcGAgaXMgd2hhdCBkZWNpZGVzIFwiZXhhY3RseSBvbmUgYXBwXG4gIC8vIHdpdGggYGNvbmZpZy5lbnZgXCIsIHNvIGFuIGVtcHR5IG1hcCBJUyB0aGUgYW1iaWd1b3VzIG9yIGFwcC1sZXNzIGJ1bmRsZSBhbmRcbiAgLy8gbmVlZHMgbm8gc2VwYXJhdGUgY2hlY2suXG4gIGlmIChPYmplY3Qua2V5cyhidW5kbGVBcHAoZmlsZS5kYXRhKSkubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25maXJtQXBwS2l0Q29udGV4dCgpO1xuICByZXR1cm4gZmlsZTtcbn1cblxuLyoqXG4gKiBUaGUgc2luZ2xlIEFwcCdzIGxpdGVyYWwgYGNvbmZpZy5lbnZgIGVudHJpZXMsIGZsYXR0ZW5lZCB0byBgbmFtZSAtPiB2YWx1ZWAuXG4gKlxuICogQSBgdmFsdWVfZnJvbWAgZW50cnkgbmFtZXMgYSBidW5kbGUgcmVzb3VyY2Ugd2hvc2UgaWQgaXMga25vd24gYWZ0ZXJcbiAqIGRlcGxveW1lbnQsIGFuZCByZWFkaW5nIGl0IG5lZWRzIHRoZSByZXNvdXJjZSB2b2NhYnVsYXJ5IHRoaXMgbW9kdWxlXG4gKiBkZWxpYmVyYXRlbHkgZG9lcyBub3QgaGF2ZSAtIG5vZGUtYXBwa2l0IHJlc29sdmVzIHRob3NlIGFnYWluc3QgaXRzIGV4dGVuZGVkXG4gKiB7QGxpbmsgYnVuZGxlUmVzb3VyY2VTY2hlbWF9LiBBbiBgYXBwc2AgYmxvY2sgd2l0aCBtb3JlIHRoYW4gb25lIGFwcCBpc1xuICogYW1iaWd1b3VzIChub3RoaW5nIGhlcmUgc2F5cyB3aGljaCBhcHAgdGhpcyBwcm9jZXNzIGlzKSwgc28gaXQgeWllbGRzIG5vdGhpbmdcbiAqIHJhdGhlciB0aGFuIGEgZ3Vlc3MuXG4gKlxuICogTWVtb2l6ZWQgYWdhaW5zdCB0aGUgcGFyc2VkIGJ1bmRsZSBpdCBjYW1lIGZyb20sIGJlY2F1c2UgYm90aCB0aGUgZ2F0ZSBpblxuICoge0BsaW5rIGJ1bmRsZUZpbGV9IGFuZCB0aGUgbG9va3VwIGluIHtAbGluayByZWFkfSBhc2sgdGhlIHNhbWUgcXVlc3Rpb24gb2YgdGhlXG4gKiBzYW1lIGNhY2hlZCBvYmplY3QgLSB2YWxpZGF0aW5nIHRoYXQgcGF5bG9hZCB0d2ljZSBwZXIgbG9va3VwIHdvdWxkIGJlIHB1cmVcbiAqIHdhc3RlLiBBIGBXZWFrTWFwYCBrZWVwcyB0aGUgZW50cnkgYWxpdmUgZXhhY3RseSBhcyBsb25nIGFzIHRoZSBidW5kbGUgaXMuXG4gKi9cbmZ1bmN0aW9uIGJ1bmRsZUFwcChpbnB1dDogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBpZiAoIW9iamVjdC5pc1JlY29yZChpbnB1dCkpIHJldHVybiBidW5kbGVBcHBFbnRyaWVzKGlucHV0KTtcbiAgY29uc3QgY2FjaGVkID0gQlVORExFX0FQUF9DQUNIRS5nZXQoaW5wdXQpO1xuICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkO1xuICBjb25zdCByZXN1bHQgPSBidW5kbGVBcHBFbnRyaWVzKGlucHV0KTtcbiAgQlVORExFX0FQUF9DQUNIRS5zZXQoaW5wdXQsIHJlc3VsdCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKiB7QGxpbmsgYnVuZGxlQXBwfSB3aXRob3V0IHRoZSBtZW1vaXphdGlvbiwgc28gdGhlIGNhY2hlIGhhcyBvbmUgZmlsbGVyLiAqL1xuZnVuY3Rpb24gYnVuZGxlQXBwRW50cmllcyhpbnB1dDogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBwYXJzZWQgPSBidW5kbGVBcHBzU2NoZW1hLnNhZmVQYXJzZShpbnB1dCk7XG4gIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHJldHVybiB7fTtcbiAgY29uc3QgYXBwcyA9IHBhcnNlZC5kYXRhLnJlc291cmNlcz8uYXBwcztcbiAgaWYgKCFhcHBzKSByZXR1cm4ge307XG4gIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoYXBwcyk7XG4gIGlmIChuYW1lcy5sZW5ndGggIT09IDEpIHJldHVybiB7fTtcbiAgY29uc3QgZW50cmllcyA9IGFwcHNbbmFtZXNbMF0hXT8uY29uZmlnPy5lbnYgPz8gW107XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICBpZiAoIWVudHJ5Lm5hbWUpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHZhbHVlID0gcmVzb2x2ZWRTdHJpbmcoZW50cnkudmFsdWUpO1xuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkgcmVzdWx0W2VudHJ5Lm5hbWVdID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGBAZGF0YWJyaWNrcy9hcHBraXRgIGNhbiBiZSBSRVNPTFZFRCBmcm9tIHRoaXMgcHJvY2VzcywgY2FjaGVkIGZvciBpdHNcbiAqIGxpZmV0aW1lLlxuICpcbiAqIFJlc29sdXRpb24sIG5vdCBpbXBvcnQ6IHRoaXMgYW5zd2VycyBcImlzIHRoaXMgYW4gQXBwS2l0IHByb2plY3RcIiB3aXRob3V0XG4gKiBldmFsdWF0aW5nIHRoZSBtb2R1bGUsIHNvIHRoZSBjaGVhcCBuZWdhdGl2ZSAoYSBwbGFpbiBsaWJyYXJ5IG9yIENMSSBjb25zdW1lclxuICogdGhhdCBuZXZlciBpbnN0YWxsZWQgdGhlIG9wdGlvbmFsIHBlZXIpIGNvc3RzIG9uZSBwYXRoIGxvb2t1cCBhbmQgbmV2ZXIgYm9vdHNcbiAqIEFwcEtpdCBhcyBhIHNpZGUgZWZmZWN0IG9mIHJlYWRpbmcgY29uZmlnLiBBIHJ1bnRpbWUgd2l0aCBubyBgY3JlYXRlUmVxdWlyZWBcbiAqIChhIGJyb3dzZXIgYnVuZGxlIHRoYXQgcmVhY2hlZCB0aGlzIE5vZGUtb25seSBtb2R1bGUgYW55d2F5KSByZXBvcnRzIGFic2VudC5cbiAqL1xuY29uc3QgYXBwS2l0SW5zdGFsbGVkID0gZnVuY3Rpb25Nb2R1bGUubWVtb2l6ZSgoKTogYm9vbGVhbiA9PiB7XG4gIHRyeSB7XG4gICAgLy8gSW5kaXJlY3Qgc3BlY2lmaWVyOiBhIGJ1bmRsZXIgbXVzdCBub3QgdHJ5IHRvIGZvbGxvdyBhbiBPUFRJT05BTCBwZWVyIHRoYXRcbiAgICAvLyBhIGJyb3dzZXIgYnVpbGQgaGFzIG5vIHdheSB0byByZXNvbHZlLlxuICAgIGNvbnN0IHNwZWNpZmllciA9IEFQUEtJVF9NT0RVTEU7XG4gICAgY3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpLnJlc29sdmUoc3BlY2lmaWVyKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59KTtcblxuLyoqXG4gKiBBcHBLaXQncyBleGVjdXRpb24gY29udGV4dCBvbmNlIGl0IGV4aXN0cywgb3IgYHVuZGVmaW5lZGAuXG4gKlxuICogTGF6aWx5IGltcG9ydGVkIChhbmQgYEB2aXRlLWlnbm9yZWBkKSBiZWNhdXNlIGBAZGF0YWJyaWNrcy9hcHBraXRgIGlzIGFuXG4gKiBPUFRJT05BTCBwZWVyIHRoaXMgbW9kdWxlIG11c3QgbmV2ZXIgbWFrZSByZXF1aXJlZC4gVGhlIGltcG9ydCBpcyBvbmx5XG4gKiBhdHRlbXB0ZWQgb25jZSB7QGxpbmsgYXBwS2l0SW5zdGFsbGVkfSBzYXlzIHRoZXJlIGlzIHNvbWV0aGluZyB0byBpbXBvcnQsIGFuZCBhXG4gKiBmYWlsdXJlIHJlc29sdmVzIHRvIGB1bmRlZmluZWRgIHJhdGhlciB0aGFuIHJlamVjdGluZyAtIGEgbWlzc2luZyBwZWVyIGlzIHRoZVxuICogZXhwZWN0ZWQgcGF0aCwgbm90IGFuIGVycm9yLlxuICpcbiAqIGBnZXRFeGVjdXRpb25Db250ZXh0KClgIFRIUk9XUyB1bnRpbCBBcHBLaXQgaGFzIGJvb3RlZCwgc28gdGhlIGNhbGwgaXMgY2F1Z2h0XG4gKiBhbmQgb25seSBhIHJlYWwgY29udGV4dCBpcyByZXBvcnRlZC4gVGhlIG1vZHVsZSBoYW5kbGUgaXMgbWVtb2l6ZWQ7IHRoZVxuICogY29udGV4dCBsb29rdXAgaXMgbm90LCBzbyBhIGNhbGwgYmVmb3JlIGJvb3QgYW5zd2VycyBcIm5vdCB5ZXRcIiBhbmQgYSBsYXRlciBvbmVcbiAqIHN0aWxsIHNlZXMgdGhlIGNvbnRleHQuXG4gKi9cbmNvbnN0IGFwcEtpdE1vZHVsZSA9IGZ1bmN0aW9uTW9kdWxlLm1lbW9pemUoYXN5bmMgKCk6IFByb21pc2U8QXBwS2l0TW9kdWxlIHwgdW5kZWZpbmVkPiA9PiB7XG4gIGlmICghYXBwS2l0SW5zdGFsbGVkKCkpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHNwZWNpZmllciA9IEFQUEtJVF9NT0RVTEU7XG4gIHJldHVybiAoYXdhaXQgaW1wb3J0KC8qIEB2aXRlLWlnbm9yZSAqLyBzcGVjaWZpZXIpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCkpIGFzXG4gICAgQXBwS2l0TW9kdWxlIHwgdW5kZWZpbmVkO1xufSk7XG5cbi8qKlxuICogTGF0Y2gge0BsaW5rIGFwcEtpdENvbnRleHR9IG9uY2UgQXBwS2l0J3MgZXhlY3V0aW9uIGNvbnRleHQgZXhpc3RzLlxuICpcbiAqIEZpcmUtYW5kLWZvcmdldCwgYmVjYXVzZSB0aGUgY2FsbGVyIGlzIGEgU1lOQ0hST05PVVMgbG9va3VwIGFuZCB0aGUgY2hlY2tcbiAqIG5lZWRzIGEgbGF6eSBpbXBvcnQuIFRoZSBhZmZpcm1hdGl2ZSBpcyBhbGwgdGhhdCBpcyBzdG9yZWQ6IEFwcEtpdCdzIGNvbnRleHRcbiAqIGRvZXMgbm90IGV4aXN0IHVudGlsIGl0IGJvb3RzLCBhbmQgYGdldEV4ZWN1dGlvbkNvbnRleHQoKWAgdGhyb3dzIHVudGlsIHRoZW4sXG4gKiBzbyByZW1lbWJlcmluZyBhIG5lZ2F0aXZlIHdvdWxkIHBlcm1hbmVudGx5IGRpc2FibGUgdGhlIGJ1bmRsZSBmb3IgYSBwcm9jZXNzXG4gKiB0aGF0IGlzIHNlY29uZHMgYXdheSBmcm9tIGhhdmluZyBvbmUuIEV2ZXJ5IGNhbGwgYmVmb3JlIHRoZSBsYXRjaCBjbG9zZXNcbiAqIHJlLWF0dGVtcHRzLCB3aGljaCBpcyB3aGF0IG1ha2VzIFwibm90IGF2YWlsYWJsZSB5ZXRcIiByZXRyeSByYXRoZXIgdGhhbiBzdGljay5cbiAqL1xuZnVuY3Rpb24gY29uZmlybUFwcEtpdENvbnRleHQoKTogdm9pZCB7XG4gIHZvaWQgYXBwS2l0TW9kdWxlKClcbiAgICAudGhlbigoYXBwa2l0KSA9PiB7XG4gICAgICBpZiAoIWFwcGtpdCkgcmV0dXJuO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGFwcGtpdC5nZXRFeGVjdXRpb25Db250ZXh0KCk/LmNsaWVudCkgYXBwS2l0Q29udGV4dCA9IHRydWU7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gQXBwS2l0IGhhcyBub3QgYm9vdGVkIHlldDsgYSBsYXRlciBjYWxsIHJlLWNoZWNrcy5cbiAgICAgIH1cbiAgICB9KVxuICAgIC5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xufVxuXG4vKiogQSBub24tZW1wdHkgYnVuZGxlIHZhbHVlIHdpdGggZXZlcnkgYCR7Li4ufWAgaW50ZXJwb2xhdGlvbiByZXNvbHZlZC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVkU3RyaW5nKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHBhcnNlZCA9IGJ1bmRsZVZhbHVlLnNhZmVQYXJzZSh2YWx1ZSk7XG4gIHJldHVybiBwYXJzZWQuc3VjY2VzcyA/IHBhcnNlZC5kYXRhIDogbnVsbDtcbn1cblxuLyoqIFBhcnNlZCBgLmVudmAgZm9yIGBjd2RgLCBvciBge31gLiBSZWFkIG9uY2UgcGVyIHJlc29sdmVkIGNvbnRleHQuICovXG5mdW5jdGlvbiBkb3RlbnYoY3dkPzogc3RyaW5nIHwgbnVsbCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBpZiAoIWZpbGVTb3VyY2VFbmFibGVkKENPTkZJR19ET1RFTlZfS0VZKSkgcmV0dXJuIHt9O1xuICBjb25zdCBlbnZpcm9ubWVudHMgPSBub2RlRW52TmFtZXMocHJvY2Vzcy5lbnYuTk9ERV9FTlYpO1xuICByZXR1cm4gY2FjaGVkQ29uZmlnKFtcImRvdGVudlwiLCAuLi5lbnZpcm9ubWVudHNdLCBjd2QsIChyZXNvbHZlZCkgPT5cbiAgICBsb2FkRG90ZW52KHJlc29sdmVkLCBlbnZpcm9ubWVudHMpLFxuICApO1xufVxuXG4vKiogQ2FjaGUgZXZlcnkgdGFyZ2V0IGRpcmVjdG9yeSBzZXBhcmF0ZWx5IHdpdGhpbiB0aGUgYWN0aXZlIHByb2Nlc3MgY29udGV4dC4gKi9cbmZ1bmN0aW9uIGNhY2hlZENvbmZpZzxUPihcbiAgbmFtZTogcmVhZG9ubHkgc3RyaW5nW10sXG4gIGN3ZDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgbG9hZGVyOiAocmVzb2x2ZWQ6IHN0cmluZykgPT4gVCxcbik6IFQge1xuICBjb25zdCBhY3RpdmUgPSBjb250ZXh0LmdldENvbnRleHQoKSA/PyBcIlwiO1xuICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmUoY3dkID8/IFwiLlwiKTtcbiAgcmV0dXJuIGNvbnRleHQuY2FjaGVkKFtcImNvbmZpZ1wiLCBhY3RpdmUsIHJlc29sdmVkLCAuLi5uYW1lXSwgKCkgPT4gbG9hZGVyKHJlc29sdmVkKSk7XG59XG5cbi8qKlxuICogTWFwcyBmb3Igb25lIHNvdXJjZSBpbiBwcmVjZWRlbmNlIG9yZGVyLiBCdW5kbGUgQXBwIGNvbmZpZyBhbmQgcm9vdCB2YXJpYWJsZXNcbiAqIHN0YXkgc2VwYXJhdGUgc28gYSBmaXJzdC1tYXRjaCBsb29rdXAgZG9lcyBub3QgcGFyc2UgdmFyaWFibGVzIGFmdGVyIGFuIEFwcFxuICogdmFsdWUgcmVzb2x2ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlYWQoXG4gIHNvdXJjZTogQ29uZmlnU291cmNlLFxuICBjd2Q/OiBzdHJpbmcsXG4pOiBvYmplY3QuU2VxdWVuY2U8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPj4ge1xuICByZXR1cm4gb2JqZWN0LnNlcXVlbmNlKHtcbiAgICAqW1N5bWJvbC5pdGVyYXRvcl0oKTogR2VuZXJhdG9yPFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4+IHtcbiAgICAgIHN3aXRjaCAoc291cmNlKSB7XG4gICAgICAgIGNhc2UgXCJlbnZcIjpcbiAgICAgICAgICB5aWVsZCBwcm9jZXNzLmVudjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImRvdGVudlwiOlxuICAgICAgICAgIHlpZWxkIGRvdGVudihjd2QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiYnVuZGxlXCI6IHtcbiAgICAgICAgICBjb25zdCBidW5kbGUgPSBidW5kbGVGaWxlKGN3ZCk7XG4gICAgICAgICAgaWYgKGJ1bmRsZSkgeWllbGQgYnVuZGxlQXBwKGJ1bmRsZS5kYXRhKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIExvY2F0ZSBgbmFtZXNgIGZyb20gYGN3ZGAgb3V0d2FyZC4gYGN3ZGAgaXRzZWxmIGlzIGNoZWNrZWQgYmVmb3JlIHRoZVxuICogZGlzY292ZXJlZCBwcm9qZWN0IHJvb3RzIHNvIGEgcGFja2FnZS1sb2NhbCBmaWxlIHdpbnMgb3ZlciB0aGUgd29ya3NwYWNlJ3MuXG4gKi9cbmZ1bmN0aW9uIGZpbmRDb25maWdGaWxlKGN3ZDogc3RyaW5nLCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBzdGFydCA9IHJlc29sdmUoY3dkKTtcbiAgY29uc3Qgcm9vdCA9IHJlc29sdmVQcm9qZWN0Um9vdChzdGFydCk7XG4gIGNvbnN0IHBhdGhGcm9tUm9vdCA9IHJvb3QgPyByZWxhdGl2ZShyb290LCBzdGFydCkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGJvdW5kYXJ5ID1cbiAgICByb290ICYmXG4gICAgcGF0aEZyb21Sb290ICE9PSB1bmRlZmluZWQgJiZcbiAgICAhaXNBYnNvbHV0ZShwYXRoRnJvbVJvb3QpICYmXG4gICAgcGF0aEZyb21Sb290ICE9PSBcIi4uXCIgJiZcbiAgICAhcGF0aEZyb21Sb290LnN0YXJ0c1dpdGgoYC4uJHtzZXB9YClcbiAgICAgID8gcm9vdFxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGZvciAobGV0IGRpciA9IHN0YXJ0OyA7IGRpciA9IGRpcm5hbWUoZGlyKSkge1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgICAgY29uc3QgcGF0aCA9IHJlc29sdmUoZGlyLCBuYW1lKTtcbiAgICAgIGlmIChzdGF0U3luYyhwYXRoKT8uaXNGaWxlKCkpIHJldHVybiBwYXRoO1xuICAgIH1cbiAgICBpZiAoYm91bmRhcnkgPT09IHVuZGVmaW5lZCB8fCBkaXIgPT09IGJvdW5kYXJ5KSBicmVhaztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKiogQSByZWNvZ25pemVkIHNvdXJjZSBvdmVycmlkZSwgZWxzZSB0aGUgY2FsbGVyJ3MgYXV0b21hdGljIGRlZmF1bHQuICovXG5mdW5jdGlvbiBmaWxlU291cmNlRW5hYmxlZChrZXk6IHN0cmluZywgZmFsbGJhY2s6IGJvb2xlYW4gPSAhaXNEYXRhYnJpY2tzQXBwRW52KCkpOiBib29sZWFuIHtcbiAgcmV0dXJuIG9iamVjdC50b0Jvb2xlYW4ocHJvY2Vzcy5lbnZba2V5XSkgPz8gZmFsbGJhY2s7XG59XG5cbmZ1bmN0aW9uIGxvYWREb3RlbnYoXG4gIGN3ZDogc3RyaW5nLFxuICBlbnZpcm9ubWVudHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IG5hbWVzID0gWy4uLmVudmlyb25tZW50cy5tYXAoKG5hbWUpID0+IGAke0RPVEVOVl9GSUxFX05BTUV9LiR7bmFtZX1gKSwgRE9URU5WX0ZJTEVfTkFNRV07XG4gIGNvbnN0IHBhdGggPSBmaW5kQ29uZmlnRmlsZShjd2QsIG5hbWVzKTtcbiAgaWYgKCFwYXRoKSByZXR1cm4ge307XG4gIHRyeSB7XG4gICAgcmV0dXJuIHBhcnNlRW52KHJlYWRGaWxlU3luYyhwYXRoLCBcInV0ZjhcIikpO1xuICB9IGNhdGNoIHtcbiAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byByZWFkIGRvdGVudiBmaWxlXCIsIHsgcGF0aCB9KTtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9hZEJ1bmRsZUZpbGUoY3dkOiBzdHJpbmcsIHByb2ZpbGU6IHN0cmluZyB8IG51bGwpOiBDb25maWdGaWxlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGF0aCA9IGZpbmRDb25maWdGaWxlKGN3ZCwgQlVORExFX0ZJTEVfTkFNRVMpO1xuICBpZiAoIXBhdGgpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgXCJidW5kbGVcIixcbiAgICBcInZhbGlkYXRlXCIsXG4gICAgXCItLW91dHB1dFwiLFxuICAgIFwianNvblwiLFxuICAgIC4uLihwcm9maWxlID09PSBudWxsID8gW10gOiBbXCItLXByb2ZpbGVcIiwgcHJvZmlsZV0pLFxuICBdO1xuICBjb25zdCByZXN1bHQgPSBzcGF3blN5bmMoXCJkYXRhYnJpY2tzXCIsIGFyZ3MsIHtcbiAgICBjd2Q6IHJlc29sdmUocGF0aCwgXCIuLlwiKSxcbiAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgc3RkaW86IFtcImlnbm9yZVwiLCBcInBpcGVcIiwgXCJwaXBlXCJdLFxuICB9KTtcbiAgY29uc3Qgb3V0cHV0ID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocmVzdWx0LnN0ZG91dCk7XG4gIGNvbnN0IGVycm9yID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocmVzdWx0LnN0ZGVycik7XG4gIGlmIChvdXRwdXQgPT09IG51bGwpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJidW5kbGUgdmFsaWRhdGUgcHJvZHVjZWQgbm8gSlNPTlwiLCB7IHBhdGgsIHN0YXR1czogcmVzdWx0LnN0YXR1cywgZXJyb3IgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBkYXRhID0ganNvbi5wYXJzZVJlY29yZChvdXRwdXQpO1xuICBpZiAoIWRhdGEpIHtcbiAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byBwYXJzZSBidW5kbGUgdmFsaWRhdGUgb3V0cHV0XCIsIHsgcGF0aCwgc3RhdHVzOiByZXN1bHQuc3RhdHVzIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHJlc3VsdC5zdGF0dXMgIT09IDApIHtcbiAgICBsb2dnZXIuZGVidWcoXCJ1c2luZyBwYXJ0aWFsIGJ1bmRsZSBvdXRwdXRcIiwgeyBwYXRoLCBzdGF0dXM6IHJlc3VsdC5zdGF0dXMsIGVycm9yIH0pO1xuICB9XG4gIHJldHVybiB7IHBhdGgsIGRhdGEgfTtcbn1cbiJdfQ==
595
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2QyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN4RSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLElBQUksWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbkYsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUMsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUN4QixPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNuRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsSUFBSSxJQUFJLGtCQUFrQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRW5GLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDcEMsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7QUEwQzlELE1BQU0sYUFBYSxHQUFHLFdBQVcsQ0FBQztBQUNsQyxNQUFNLGVBQWUsR0FBNEIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDOUYsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLGdCQUFnQixFQUFFLGlCQUFpQixDQUFV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QUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3RELENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxNQUFNLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNsRCxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDekQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGF5ZXJlZCBjb25maWd1cmF0aW9uIGxvb2t1cDogZW52aXJvbm1lbnQsIGAuZW52YCwgYnVuZGxlLCBhbmQgYGFwcC55YW1sYC5cbiAqXG4gKiBFdmVyeSBwYWNrYWdlIHJlc29sdmVzIHNldHRpbmdzIHRoZSBzYW1lIHdheTogdGFrZSB0aGUgY2FsbGVyJ3MgdmFsdWUsIGVsc2VcbiAqIGFuIGVudmlyb25tZW50IHZhcmlhYmxlLCBlbHNlIGEgZGVmYXVsdC4gTG9jYWwgZGV2ZWxvcG1lbnQgYWRkcyB0d28gZmFsbGJhY2tcbiAqIGxvY2F0aW9uczogYC5lbnZgIGZpbGVzLCBvbmUgQXBwJ3MgYHJlc291cmNlcy5hcHBzLjxhcHA+LmNvbmZpZy5lbnZgIGluXG4gKiBgZGF0YWJyaWNrcy55bWxgLCBhbmQgbGl0ZXJhbCBlbnYgdmFsdWVzIGluIGBhcHAueWFtbGAgLyBgYXBwLnltbGAuXG4gKlxuICoge0BsaW5rIHZhbHVlc30gaXMgTEFaWSAoYW4gYG9iamVjdC5TZXF1ZW5jZWApLCBzbyBgZGF0YWJyaWNrcyBidW5kbGUgdmFsaWRhdGVgXG4gKiBpcyBvbmx5IHNwYXduZWQgd2hlbiB0aGUgZW52aXJvbm1lbnQgYW5kIGAuZW52YCBib3RoIG1pc3NlZDsgYXBwIFlBTUwgaXMgb25seVxuICogcmVhZCBhZnRlciB0aGUgYnVuZGxlIHNvdXJjZSBhbHNvIG1pc3NlZC5cbiAqXG4gKiBJbnNpZGUgYSBkZXBsb3llZCBEYXRhYnJpY2tzIEFwcCBhbGwgdGhyZWUgZmlsZSBzb3VyY2VzIGFyZSBza2lwcGVkIGJ5IGRlZmF1bHRcbiAqICh7QGxpbmsgaXNEYXRhYnJpY2tzQXBwRW52fSk6IHRoZSBwbGF0Zm9ybSBoYXMgYWxyZWFkeSB0dXJuZWQgdGhlbSBpbnRvIHJlYWxcbiAqIGVudmlyb25tZW50IHZhcmlhYmxlcywgdGhlcmUgaXMgbm8gYnVuZGxlIHRvIHZhbGlkYXRlLCBhbmQgdGhlIGBkYXRhYnJpY2tzYFxuICogQ0xJIGlzIG5vdCBvbiB0aGUgaW1hZ2UuIEJvb2xlYW4gZW52aXJvbm1lbnQgb3ZlcnJpZGVzIGNhbiBmb3JjZSBlaXRoZXIgZmlsZVxuICogc291cmNlIG9uIG9yIG9mZiB3aGVuIGEgdG9vbCBuZWVkcyBkaWZmZXJlbnQgYmVoYXZpb3IuXG4gKlxuICogT25seSB0aGUgc2luZ2xlIGJ1bmRsZSBhcHAncyBgY29uZmlnLmVudmAgYW5kIGxpdGVyYWwgYXBwIFlBTUwgYGVudltdLnZhbHVlYFxuICogZW50cmllcyBhcmUgY29uc3VsdGVkLiBSb290IGJ1bmRsZSBgdmFyaWFibGVzYCBhcmUgbm90OiB0aGV5IGFyZSBhdXRob3JpbmdcbiAqIGlucHV0cyBmb3IgdGhlIGJ1bmRsZSBpdHNlbGYgKGludGVycG9sYXRlZCBpbnRvIHRhcmdldHMsIHJlc291cmNlcywgYW5kIHBhdGhzKSxcbiAqIHNvIHRyZWF0aW5nIG9uZSBhcyBhIHByb2Nlc3Mgc2V0dGluZyByZXNvbHZlcyBuYW1lcyB0aGUgZGVwbG95ZWQgYXBwIG5ldmVyIHNlZXMuXG4gKlxuICogTm9kZS1vbmx5IChgY2hpbGRfcHJvY2Vzc2AsIGBmc2AsIGBwcm9jZXNzYCkuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHNwYXduU3luYyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBkaXJuYW1lLCBpc0Fic29sdXRlLCByZWxhdGl2ZSwgcmVzb2x2ZSwgc2VwIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgcGFyc2VFbnYgfSBmcm9tIFwibm9kZTp1dGlsXCI7XG5pbXBvcnQgeyBqc29uLCBsb2csIG9iamVjdCwgc3RyaW5nIGFzIHNoYXJlZFN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBwYXJzZSBhcyBwYXJzZVlhbWwgfSBmcm9tIFwieWFtbFwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IGNhY2hlZFJlY29yZCwgc3RhdFN5bmMgfSBmcm9tIFwiLi9maWxlLnRzXCI7XG5pbXBvcnQgeyByZXNvbHZlV29ya2luZ0RpcmVjdG9yeSwgcm9vdCBhcyByZXNvbHZlUHJvamVjdFJvb3QgfSBmcm9tIFwiLi9wcm9qZWN0LnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJjb25maWdcIik7XG5jb25zdCBjb25maWdGaWxlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPigpO1xuXG50eXBlIENvbmZpZ0tleSA9IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG5leHBvcnQgdHlwZSBDb25maWdNYXBWYWx1ZSA9IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgbnVsbCB8IHVuZGVmaW5lZDtcbmV4cG9ydCB0eXBlIENvbmZpZ0RhdGEgPSBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBDb25maWdNYXBWYWx1ZT4+O1xuXG4vKiogV2hlcmUgYSB2YWx1ZSBtYXkgY29tZSBmcm9tLCBjb25zdWx0ZWQgaW4gdGhlIG9yZGVyIGdpdmVuLiAqL1xuZXhwb3J0IHR5cGUgQ29uZmlnU291cmNlID0gXCJjb25maWdcIiB8IFwiZW52XCIgfCBcImRvdGVudlwiIHwgXCJidW5kbGVcIiB8IFwiYXBwXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBPdXRlcm1vc3QgbmFtZXNwYWNlcyB0cmllZCBiZWZvcmUgZWFjaCBrZXkuIERlZmF1bHRzIHRvIGBEQlhfVE9PTFNgLlxuICAgKi9cbiAgc2NvcGU/OiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqIENhcGFiaWxpdHkgbmFtZXNwYWNlcyBpbnNlcnRlZCBhZnRlciB0aGUgc2NvcGUgYW5kIGJlZm9yZSBlYWNoIGtleS4gKi9cbiAgcHJlZml4Pzogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW107XG4gIC8qKiBDb25zdGFudCBjb25maWcgbWFwcyByZWFkIGJ5IHRoZSBgY29uZmlnYCBzb3VyY2UuICovXG4gIGRhdGE/OiBDb25maWdEYXRhIHwgcmVhZG9ubHkgQ29uZmlnRGF0YVtdO1xuICAvKiogUGFyc2VkIGJ1bmRsZSBkYXRhIHVzZWQgaW5zdGVhZCBvZiBsb2FkaW5nIGBkYXRhYnJpY2tzLnltbGAuICovXG4gIGJ1bmRsZURhdGE/OiBDb25maWdGaWxlIHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIC8qKiBQYXJzZWQgYXBwIFlBTUwgZGF0YSB1c2VkIGluc3RlYWQgb2YgbG9hZGluZyBgYXBwLnlhbWxgLiAqL1xuICBhcHBEYXRhPzogQ29uZmlnRmlsZSB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAvKiogU291cmNlcyBpbiBwcmVjZWRlbmNlIG9yZGVyLiBEZWZhdWx0OiBgY29uZmlnYCwgYGVudmAsIGBkb3RlbnZgLCBgYnVuZGxlYCwgYGFwcGAuICovXG4gIHNvdXJjZXM/OiBDb25maWdTb3VyY2UgfCByZWFkb25seSBDb25maWdTb3VyY2VbXTtcbiAgLyoqIERpcmVjdG9yeSB0byByZXNvbHZlIGAuZW52YCBhbmQgdGhlIGJ1bmRsZSBmcm9tLiBEZWZhdWx0OiBgcHJvY2Vzcy5jd2QoKWAuICovXG4gIGN3ZD86IHN0cmluZztcbn1cblxuLyoqIE9uZSByZXNvbHZlZCB2YWx1ZSwgdGFnZ2VkIHdpdGggdGhlIGtleSBhbmQgc291cmNlIGl0IGNhbWUgZnJvbS4gKi9cbmludGVyZmFjZSBDb25maWdWYWx1ZSB7XG4gIGtleTogc3RyaW5nO1xuICBzb3VyY2U6IENvbmZpZ1NvdXJjZTtcbiAgdmFsdWU6IHN0cmluZztcbn1cblxuLyoqIEEgY29uZmlnIGZpbGUgZm91bmQgb24gZGlzaywgd2l0aCBpdHMgcGFyc2VkIGNvbnRlbnRzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb25maWdGaWxlIHtcbiAgcGF0aDogc3RyaW5nO1xuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuY29uc3QgREVGQVVMVF9TQ09QRSA9IFwiREJYX1RPT0xTXCI7XG5jb25zdCBERUZBVUxUX1NPVVJDRVM6IHJlYWRvbmx5IENvbmZpZ1NvdXJjZVtdID0gW1wiY29uZmlnXCIsIFwiZW52XCIsIFwiZG90ZW52XCIsIFwiYnVuZGxlXCIsIFwiYXBwXCJdO1xuY29uc3QgQlVORExFX0ZJTEVfTkFNRVMgPSBbXCJkYXRhYnJpY2tzLnltbFwiLCBcImRhdGFicmlja3MueWFtbFwiXSBhcyBjb25zdDtcbmNvbnN0IEFQUF9GSUxFX05BTUVTID0gW1wiYXBwLnlhbWxcIiwgXCJhcHAueW1sXCJdIGFzIGNvbnN0O1xuY29uc3QgRE9URU5WX0ZJTEVfTkFNRSA9IFwiLmVudlwiO1xuY29uc3QgTk9ERV9FTlZfQUxURVJOQVRJVkVTID0ge1xuICBwcm9kdWN0aW9uOiBbXCJwcm9kXCJdLFxuICBkZXZlbG9wbWVudDogW1wiZGV2XCJdLFxufSBhcyBjb25zdCBzYXRpc2ZpZXMgUmVjb3JkPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+O1xuXG4vKiogSGlnaGVzdCB2YWxpZCBUQ1AgcG9ydCBudW1iZXIuICovXG5leHBvcnQgY29uc3QgTUFYX1RDUF9QT1JUID0gNjVfNTM1O1xuXG4vKiogQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZSBmb3Ige0BsaW5rIGlzRGF0YWJyaWNrc0FwcEVudn0uICovXG5jb25zdCBEQVRBQlJJQ0tTX0FQUF9FTlZfS0VZID0gXCJEQlhfVE9PTFNfREFUQUJSSUNLU19BUFBfRU5WXCI7XG5cbi8qKiBCb29sZWFuIGVudmlyb25tZW50IG92ZXJyaWRlIGZvciBwcm9qZWN0IGAuZW52YCByZWFkcy4gKi9cbmNvbnN0IENPTkZJR19ET1RFTlZfS0VZID0gXCJEQlhfVE9PTFNfQ09ORklHX0RPVEVOVlwiO1xuXG4vKiogQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZSBmb3IgRGF0YWJyaWNrcyBidW5kbGUgcmVhZHMuICovXG5jb25zdCBDT05GSUdfQlVORExFX0tFWSA9IFwiREJYX1RPT0xTX0NPTkZJR19CVU5ETEVcIjtcblxuLyoqIEJvb2xlYW4gZW52aXJvbm1lbnQgb3ZlcnJpZGUgZm9yIERhdGFicmlja3MgQXBwIFlBTUwgcmVhZHMuICovXG5jb25zdCBDT05GSUdfQVBQX0tFWSA9IFwiREJYX1RPT0xTX0NPTkZJR19BUFBcIjtcblxuLyoqIEV4YWN0IHByb2Nlc3MtZW52aXJvbm1lbnQgbG9va3VwIGZvciBjYWxsZXJzIHRoYXQgZG8gbm90IHJlYWQgbG9jYWwgY29uZmlnIGZpbGVzLiAqL1xuZXhwb3J0IGNvbnN0IEVOVl9PTkxZID0geyBzY29wZTogW10gYXMgY29uc3QsIHNvdXJjZXM6IFwiZW52XCIgYXMgY29uc3QgfTtcblxuZXhwb3J0IGNvbnN0IHZhbHVlU2NoZW1hID0gelxuICAuc3RyaW5nKClcbiAgLnRyaW0oKVxuICAubWluKDEpXG4gIC5yZWZpbmUoKHZhbHVlOiBzdHJpbmcpID0+ICEvXFwkXFx7W159XStcXH0vLnRlc3QodmFsdWUpLCB7XG4gICAgbWVzc2FnZTogXCJJbnRlcnBvbGF0ZWQgdmFsdWVzIGFyZSBub3QgYWxsb3dlZFwiLFxuICB9KTtcblxuY29uc3QgcG9ydFZhbHVlU2NoZW1hID0gei5wcmVwcm9jZXNzKFxuICAoaW5wdXQpID0+IG9iamVjdC50b051bWJlcihpbnB1dCksXG4gIHoubnVtYmVyKCkuaW50KCkubWluKDEpLm1heChNQVhfVENQX1BPUlQpLFxuKTtcblxuY29uc3QgcG9zaXRpdmVOdW1iZXJWYWx1ZSA9IHoucHJlcHJvY2VzcygoaW5wdXQpID0+IG9iamVjdC50b051bWJlcihpbnB1dCksIHoubnVtYmVyKCkucG9zaXRpdmUoKSk7XG5jb25zdCBwb3NpdGl2ZUludFZhbHVlID0gcG9zaXRpdmVOdW1iZXJWYWx1ZS50cmFuc2Zvcm0oTWF0aC5mbG9vcik7XG5cbmNvbnN0IHdvcmtzcGFjZUhvc3RTY2hlbWEgPSB2YWx1ZVNjaGVtYS5yZWZpbmUoXG4gIChob3N0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBbXCJodHRwOlwiLCBcImh0dHBzOlwiXS5pbmNsdWRlcyhuZXcgVVJMKGhvc3QpLnByb3RvY29sKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0sXG4gIHsgbWVzc2FnZTogXCJNdXN0IGJlIGFuIEhUVFAoUykgVVJMXCIgfSxcbik7XG5cbmNvbnN0IGRhdGFicmlja3NBcHBFbnZTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIERBVEFCUklDS1NfQVBQX05BTUU6IHZhbHVlU2NoZW1hLFxuICBEQVRBQlJJQ0tTX0hPU1Q6IHdvcmtzcGFjZUhvc3RTY2hlbWEsXG4gIERBVEFCUklDS1NfQVBQX1BPUlQ6IHBvcnRWYWx1ZVNjaGVtYSxcbn0pO1xuXG4vKiogQSBuYW1lZCBidW5kbGUgb3IgQXBwIHJlc291cmNlOyBjb25jcmV0ZSByZXNvdXJjZSBmaWVsZHMgcGFzcyB0aHJvdWdoLiAqL1xuZXhwb3J0IGNvbnN0IGJ1bmRsZVJlc291cmNlU2NoZW1hID0gei5vYmplY3QoeyBuYW1lOiB2YWx1ZVNjaGVtYS5vcHRpb25hbCgpIH0pLnBhc3N0aHJvdWdoKCk7XG5cbmV4cG9ydCBjb25zdCBidW5kbGVFbnZFbnRyeVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgbmFtZTogdmFsdWVTY2hlbWEub3B0aW9uYWwoKSxcbiAgdmFsdWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgdmFsdWVfZnJvbTogdmFsdWVTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgYnVuZGxlQXBwU2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiB2YWx1ZVNjaGVtYS5vcHRpb25hbCgpLFxuICBjb25maWc6IHoub2JqZWN0KHsgZW52OiB6LmFycmF5KGJ1bmRsZUVudkVudHJ5U2NoZW1hKS5vcHRpb25hbCgpIH0pLm9wdGlvbmFsKCksXG4gIHJlc291cmNlczogei5hcnJheShidW5kbGVSZXNvdXJjZVNjaGVtYSkub3B0aW9uYWwoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgYXBwRW52RW50cnlTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG5hbWU6IHZhbHVlU2NoZW1hLFxuICB2YWx1ZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB2YWx1ZUZyb206IHZhbHVlU2NoZW1hLm9wdGlvbmFsKCksXG59KTtcblxuZXhwb3J0IGNvbnN0IGFwcFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgZW52OiB6LmFycmF5KGFwcEVudkVudHJ5U2NoZW1hKS5vcHRpb25hbCgpLFxuICByZXNvdXJjZXM6IHouYXJyYXkoYnVuZGxlUmVzb3VyY2VTY2hlbWEpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgYnVuZGxlQ29uZmlnU2NoZW1hID0gei5vYmplY3Qoe1xuICByZXNvdXJjZXM6IHoub2JqZWN0KHsgYXBwczogei5yZWNvcmQoei5zdHJpbmcoKSwgYnVuZGxlQXBwU2NoZW1hKS5vcHRpb25hbCgpIH0pLm9wdGlvbmFsKCksXG59KTtcblxuLyoqIEZsYXR0ZW4gdGhlIHNpbmdsZSBidW5kbGUgQXBwJ3MgYGNvbmZpZy5lbnZgLCByZXNvbHZpbmcgcmVzb3VyY2UgcmVmZXJlbmNlcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuQnVuZGxlRW52KGRhdGE6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgcGFyc2VkID0gYnVuZGxlQ29uZmlnU2NoZW1hLnNhZmVQYXJzZShkYXRhKTtcbiAgaWYgKCFwYXJzZWQuc3VjY2VzcykgcmV0dXJuIHt9O1xuICBjb25zdCBhcHBzID0gT2JqZWN0LnZhbHVlcyhwYXJzZWQuZGF0YS5yZXNvdXJjZXM/LmFwcHMgPz8ge30pO1xuICBpZiAoYXBwcy5sZW5ndGggIT09IDEpIHJldHVybiB7fTtcbiAgY29uc3QgYXBwID0gYXBwc1swXTtcbiAgY29uc3QgcmVzb3VyY2VzID0gbmV3IE1hcChcbiAgICAoYXBwPy5yZXNvdXJjZXMgPz8gW10pXG4gICAgICAuZmlsdGVyKChyZXNvdXJjZSkgPT4gcmVzb3VyY2UubmFtZSlcbiAgICAgIC5tYXAoKHJlc291cmNlKSA9PiBbcmVzb3VyY2UubmFtZSEsIHJlc291cmNlXSBhcyBjb25zdCksXG4gICk7XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGFwcD8uY29uZmlnPy5lbnYgPz8gW10pIHtcbiAgICBpZiAoIWVudHJ5Lm5hbWUpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGxpdGVyYWwgPSB2YWx1ZVNjaGVtYS5zYWZlUGFyc2UoZW50cnkudmFsdWUpO1xuICAgIGlmIChsaXRlcmFsLnN1Y2Nlc3MpIHtcbiAgICAgIHJlc3VsdFtlbnRyeS5uYW1lXSA9IGxpdGVyYWwuZGF0YTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCByZWZlcmVuY2VkID0gZW50cnkudmFsdWVfZnJvbVxuICAgICAgPyByZXNvdXJjZVZhbHVlKHJlc291cmNlcy5nZXQoZW50cnkudmFsdWVfZnJvbSkpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBpZiAocmVmZXJlbmNlZCkgcmVzdWx0W2VudHJ5Lm5hbWVdID0gcmVmZXJlbmNlZDtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKiogRmxhdHRlbiBgYXBwLnlhbWxgIGVudiBlbnRyaWVzLCByZXNvbHZpbmcgYHZhbHVlRnJvbWAgcmVzb3VyY2UgcmVmZXJlbmNlcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuQXBwRW52KGRhdGE6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgcGFyc2VkID0gYXBwU2NoZW1hLnNhZmVQYXJzZShkYXRhKTtcbiAgaWYgKCFwYXJzZWQuc3VjY2VzcykgcmV0dXJuIHt9O1xuICBjb25zdCByZXNvdXJjZXMgPSBuZXcgTWFwKFxuICAgIChwYXJzZWQuZGF0YS5yZXNvdXJjZXMgPz8gW10pXG4gICAgICAuZmlsdGVyKChyZXNvdXJjZSkgPT4gcmVzb3VyY2UubmFtZSlcbiAgICAgIC5tYXAoKHJlc291cmNlKSA9PiBbcmVzb3VyY2UubmFtZSEsIHJlc291cmNlXSBhcyBjb25zdCksXG4gICk7XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHBhcnNlZC5kYXRhLmVudiA/PyBbXSkge1xuICAgIGNvbnN0IGxpdGVyYWwgPSB2YWx1ZVNjaGVtYS5zYWZlUGFyc2UoZW50cnkudmFsdWUpO1xuICAgIGlmIChsaXRlcmFsLnN1Y2Nlc3MpIHtcbiAgICAgIHJlc3VsdFtlbnRyeS5uYW1lXSA9IGxpdGVyYWwuZGF0YTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCByZWZlcmVuY2VkID0gZW50cnkudmFsdWVGcm9tID8gcmVzb3VyY2VWYWx1ZShyZXNvdXJjZXMuZ2V0KGVudHJ5LnZhbHVlRnJvbSkpIDogdW5kZWZpbmVkO1xuICAgIGlmIChyZWZlcmVuY2VkKSByZXN1bHRbZW50cnkubmFtZV0gPSByZWZlcmVuY2VkO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHJlc291cmNlVmFsdWUocmVzb3VyY2U6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBmb3IgKGNvbnN0IHBhdGggb2YgW1xuICAgIFtcInNxbF93YXJlaG91c2VcIiwgXCJpZFwiXSxcbiAgICBbXCJnZW5pZV9zcGFjZVwiLCBcInNwYWNlX2lkXCJdLFxuICAgIFtcInBvc3RncmVzXCIsIFwiZW5kcG9pbnRcIl0sXG4gICAgW1wicG9zdGdyZXNcIiwgXCJkYXRhYmFzZVwiXSxcbiAgICBbXCJwb3N0Z3Jlc1wiLCBcImJyYW5jaFwiXSxcbiAgXSBhcyBjb25zdCkge1xuICAgIGxldCB2YWx1ZSA9IHJlc291cmNlO1xuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXRoKSB2YWx1ZSA9IG9iamVjdC5pc1JlY29yZCh2YWx1ZSkgPyB2YWx1ZVtwYXJ0XSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBwYXJzZWQgPSB2YWx1ZVNjaGVtYS5zYWZlUGFyc2UodmFsdWUpO1xuICAgIGlmIChwYXJzZWQuc3VjY2VzcykgcmV0dXJuIHBhcnNlZC5kYXRhO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBXYWxrIGEgZG90LXNlcGFyYXRlZCBwYXRoIHRocm91Z2ggcGFyc2VkIGJ1bmRsZSBkYXRhLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEJ1bmRsZVBhdGgoZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIHBhdGg6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdChcIi5cIikuZmlsdGVyKEJvb2xlYW4pO1xuICBpZiAocGFydHMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICBsZXQgY3VycmVudDogdW5rbm93biA9IGRhdGE7XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwYXJ0cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICBpZiAoIW9iamVjdC5pc1JlY29yZChjdXJyZW50KSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBuZXh0ID0gY3VycmVudFtwYXJ0c1tpbmRleF0hXTtcbiAgICBpZiAoaW5kZXggPT09IHBhcnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgIGNvbnN0IGRpcmVjdCA9IHZhbHVlU2NoZW1hLnNhZmVQYXJzZShuZXh0KTtcbiAgICAgIGlmIChkaXJlY3Quc3VjY2VzcykgcmV0dXJuIGRpcmVjdC5kYXRhO1xuICAgICAgaWYgKG9iamVjdC5pc1JlY29yZChuZXh0KSkge1xuICAgICAgICBjb25zdCBuZXN0ZWQgPSB2YWx1ZVNjaGVtYS5zYWZlUGFyc2UobmV4dC52YWx1ZSk7XG4gICAgICAgIHJldHVybiBuZXN0ZWQuc3VjY2VzcyA/IG5lc3RlZC5kYXRhIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY3VycmVudCA9IG5leHQ7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBEZXRlY3QgYSBEYXRhYnJpY2tzIEFwcCBydW50aW1lIGZyb20gaXRzIHJlcXVpcmVkIG5hbWUsIGhvc3QsIGFuZCBwb3J0LlxuICpcbiAqIGBEQlhfVE9PTFNfREFUQUJSSUNLU19BUFBfRU5WYCB0YWtlcyBwcmVjZWRlbmNlIHdoZW4gaXQgY29udGFpbnMgYSByZWNvZ25pemVkXG4gKiBib29sZWFuIHZhbHVlLiBUaGlzIGxldHMgbG9jYWwgdG9vbHMgZW11bGF0ZSB0aGUgZGVwbG95ZWQgcnVudGltZSAoYHRydWVgKSBvclxuICogbGV0cyB1bnVzdWFsIGRlcGxveWVkIHByb2Nlc3NlcyByZXRhaW4gbG9jYWwgY29uZmlnIGxvb2t1cCAoYGZhbHNlYCkuIEFuXG4gKiBhYnNlbnQgb3IgdW5yZWNvZ25pemVkIG92ZXJyaWRlIGZhbGxzIGJhY2sgdG8gc3RydWN0dXJhbCBkZXRlY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGFicmlja3NBcHBFbnYoXG4gIHNvdXJjZTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiA9IHByb2Nlc3MuZW52LFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IG92ZXJyaWRlID0gb2JqZWN0LnRvQm9vbGVhbihzb3VyY2VbREFUQUJSSUNLU19BUFBfRU5WX0tFWV0pO1xuICBpZiAob3ZlcnJpZGUgIT09IHVuZGVmaW5lZCkgcmV0dXJuIG92ZXJyaWRlO1xuICBjb25zdCBwYXJzZWQgPSBkYXRhYnJpY2tzQXBwRW52U2NoZW1hLnNhZmVQYXJzZShzb3VyY2UpO1xuICByZXR1cm4gcGFyc2VkLnN1Y2Nlc3M7XG59XG5cbi8qKiBFeGFjdCwgdXBwZXJjYXNlLCBhbmQgdG9rZW5pemVkLXVwcGVyY2FzZSBuYW1lcyBmb3IgYSBodW1hbi1mcmllbmRseSBrZXkuICovXG5leHBvcnQgZnVuY3Rpb24gZW52aXJvbm1lbnRLZXlzKG5hbWU6IHN0cmluZyk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgY29uc3QgdHJpbW1lZCA9IG5hbWUudHJpbSgpO1xuICBpZiAoIXRyaW1tZWQpIHJldHVybiBbXTtcbiAgcmV0dXJuIG9iamVjdFxuICAgIC5zZXF1ZW5jZShcbiAgICAgIHRyaW1tZWQsXG4gICAgICB0cmltbWVkLnRvVXBwZXJDYXNlKCksXG4gICAgICBBcnJheS5mcm9tKHNoYXJlZFN0cmluZy50b2tlbml6ZSh0cmltbWVkKSkuam9pbihcIl9cIikudG9VcHBlckNhc2UoKSxcbiAgICApXG4gICAgLmZpbHRlcihCb29sZWFuKVxuICAgIC5kaXN0aW5jdCgpXG4gICAgLnRvQXJyYXkoKTtcbn1cblxuLyoqIENhbmRpZGF0ZSBuYW1lcyBpbiBzY29wZSwgcHJlZml4LCBhbmQgaW5wdXQgcHJlY2VkZW5jZSBvcmRlci4gKi9cbmZ1bmN0aW9uIGtleXMoXG4gIGlucHV0OiBDb25maWdLZXksXG4gIG9wdGlvbnM6IFBpY2s8Q29uZmlnT3B0aW9ucywgXCJzY29wZVwiIHwgXCJwcmVmaXhcIj4gPSB7fSxcbik6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgY29uc3Qgc2NvcGVzID0gb2JqZWN0XG4gICAgLnNlcXVlbmNlKG9wdGlvbnMuc2NvcGUgPz8gREVGQVVMVF9TQ09QRSlcbiAgICAubWFwKHNoYXJlZFN0cmluZy50cmltVG9FbXB0eSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLmRpc3RpbmN0KClcbiAgICAudG9BcnJheSgpO1xuICBjb25zdCBwcmVmaXhlcyA9XG4gICAgb3B0aW9ucy5wcmVmaXggPT09IHVuZGVmaW5lZFxuICAgICAgPyBbXVxuICAgICAgOiBvYmplY3RcbiAgICAgICAgICAuc2VxdWVuY2Uob3B0aW9ucy5wcmVmaXgpXG4gICAgICAgICAgLm1hcChzaGFyZWRTdHJpbmcudHJpbVRvRW1wdHkpXG4gICAgICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgICAgIC5kaXN0aW5jdCgpXG4gICAgICAgICAgLnRvQXJyYXkoKTtcbiAgcmV0dXJuIG9iamVjdFxuICAgIC5zZXF1ZW5jZShpbnB1dClcbiAgICAubWFwKHNoYXJlZFN0cmluZy50cmltVG9FbXB0eSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLmRpc3RpbmN0KClcbiAgICAuZmxhdE1hcCgoa2V5KSA9PiB7XG4gICAgICBjb25zdCBwcmVmaXhlZCA9IHByZWZpeGVzLmxlbmd0aCA+IDAgPyBwcmVmaXhlcy5tYXAoKHByZWZpeCkgPT4gYCR7cHJlZml4fV8ke2tleX1gKSA6IFtrZXldO1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgLi4uc2NvcGVzLmZsYXRNYXAoKHNjb3BlKSA9PiBwcmVmaXhlZC5tYXAoKG5hbWUpID0+IGAke3Njb3BlfV8ke25hbWV9YCkpLFxuICAgICAgICAuLi5wcmVmaXhlZCxcbiAgICAgICAga2V5LFxuICAgICAgXTtcbiAgICB9KVxuICAgIC5kaXN0aW5jdCgpXG4gICAgLnRvQXJyYXkoKTtcbn1cblxuLyoqXG4gKiBFdmVyeSB2YWx1ZSB0aGF0IHJlc29sdmVzIGZvciBgaW5wdXRgLCBpbiBzb3VyY2UtdGhlbi1rZXkgcHJlY2VkZW5jZSBvcmRlcixcbiAqIGFzIGEgTEFaWSBzZXF1ZW5jZTogbm90aGluZyBwYXN0IHRoZSBmaXJzdCBjb25zdW1lZCBlbGVtZW50IGlzIHJlYWQsIHNvXG4gKiBgdmFsdWVzKGtleSkuYXQoMClgIG5ldmVyIHNwYXducyB0aGUgRGF0YWJyaWNrcyBDTEkgd2hlbiB0aGUgZW52aXJvbm1lbnRcbiAqIGFscmVhZHkgYW5zd2VyZWQuXG4gKlxuICovXG5mdW5jdGlvbiB2YWx1ZXMoaW5wdXQ6IENvbmZpZ0tleSwgb3B0aW9uczogQ29uZmlnT3B0aW9ucyA9IHt9KTogb2JqZWN0LlNlcXVlbmNlPENvbmZpZ1ZhbHVlPiB7XG4gIGNvbnN0IGNhbmRpZGF0ZXMgPSBrZXlzKGlucHV0LCBvcHRpb25zKTtcbiAgY29uc3Qgc291cmNlcyA9IGNvbmZpZ1NvdXJjZXMob3B0aW9ucyk7XG4gIHJldHVybiBvYmplY3Quc2VxdWVuY2Uoe1xuICAgICpbU3ltYm9sLml0ZXJhdG9yXSgpOiBHZW5lcmF0b3I8Q29uZmlnVmFsdWU+IHtcbiAgICAgIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBtYXAgb2YgcmVhZChzb3VyY2UsIG9wdGlvbnMpKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgY2FuZGlkYXRlcykge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdNYXBWYWx1ZShtYXBba2V5XSk7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHlpZWxkIHsga2V5LCBzb3VyY2UsIHZhbHVlIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbmZpZ1NvdXJjZXMob3B0aW9uczogQ29uZmlnT3B0aW9ucyk6IHJlYWRvbmx5IENvbmZpZ1NvdXJjZVtdIHtcbiAgY29uc3Qgc291cmNlczogQ29uZmlnU291cmNlW10gPSBbXG4gICAgLi4ub2JqZWN0LnNlcXVlbmNlPENvbmZpZ1NvdXJjZT4ob3B0aW9ucy5zb3VyY2VzID8/IERFRkFVTFRfU09VUkNFUykuZGlzdGluY3QoKSxcbiAgXTtcbiAgaWYgKG9wdGlvbnMuZGF0YSAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMuc291cmNlcyAhPT0gdW5kZWZpbmVkICYmICFzb3VyY2VzLmluY2x1ZGVzKFwiY29uZmlnXCIpKSB7XG4gICAgc291cmNlcy5wdXNoKFwiY29uZmlnXCIpO1xuICB9XG4gIHJldHVybiBzb3VyY2VzO1xufVxuXG5mdW5jdGlvbiBjb25maWdNYXBWYWx1ZSh2YWx1ZTogQ29uZmlnTWFwVmFsdWUgfCB1bmtub3duKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGZvciAoY29uc3QgZW50cnkgb2YgdmFsdWUpIHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gc2hhcmVkU3RyaW5nLnRyaW1Ub051bGwoZW50cnkpO1xuICAgICAgaWYgKHJlc29sdmVkICE9PSBudWxsKSByZXR1cm4gcmVzb2x2ZWQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBzaGFyZWRTdHJpbmcudHJpbVRvTnVsbCh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIGZpcnN0IHZhbHVlIHRoYXQgcmVzb2x2ZXMgZm9yIGBpbnB1dGAsIG9yIGB1bmRlZmluZWRgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBkb21haW4gPSBjb25maWcudGV4dChbXCJUVU5ORUxfUFVCTElDX0RPTUFJTlwiLCBcIlBVQkxJQ19ET01BSU5cIl0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGV4dChpbnB1dDogQ29uZmlnS2V5LCBvcHRpb25zOiBDb25maWdPcHRpb25zID0ge30pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdmFsdWVzKGlucHV0LCBvcHRpb25zKS5hdCgwKT8udmFsdWU7XG59XG5cbi8qKiBSZXNvbHZlIGEgaHVtYW4tZnJpZW5kbHkgbmFtZSB0aHJvdWdoIHtAbGluayBlbnZpcm9ubWVudEtleXN9IGFuZCB7QGxpbmsgdGV4dH0uICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVZhbHVlKG5hbWU6IHN0cmluZywgb3B0aW9uczogQ29uZmlnT3B0aW9ucyA9IHt9KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHRleHQoZW52aXJvbm1lbnRLZXlzKG5hbWUpLCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBUaGUgUFJJTUFSWSAoZnVsbHktc2NvcGVkKSBuYW1lIGZvciBgaW5wdXRgIC0gd2hhdCB0byBwcmludCBpbiBhIGxvZyBsaW5lIG9yIGFuXG4gKiBlcnJvciwgc28gdGhlIG1lc3NhZ2UgbmFtZXMgdGhlIHZhcmlhYmxlIGEgcmVhZGVyIHNob3VsZCBzZXQuIERvIG5vdCBpbmRleFxuICogYGtleXMoLi4uKVswXWAgZm9yIHRoaXMgaWYgYGlucHV0YCBtYXkgYmUgYSBiYXJlIHN0cmluZy5cbiAqXG4gKiBAZXhhbXBsZVxuICogbG9nZ2VyLndhcm4oYCR7Y29uZmlnLm5hbWUoSldUX1NFQ1JFVF9FTlYpfSBpcyBub3Qgc2V0YCk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuYW1lKFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBvcHRpb25zOiBQaWNrPENvbmZpZ09wdGlvbnMsIFwic2NvcGVcIiB8IFwicHJlZml4XCI+ID0ge30sXG4pOiBzdHJpbmcge1xuICByZXR1cm4ga2V5cyhpbnB1dCwgb3B0aW9ucylbMF0gPz8gXCJcIjtcbn1cblxuLyoqXG4gKiBTYWZlIGAuZW52LjxuYW1lPmAgc3VmZml4ZXMgZm9yIGEgTm9kZSBlbnZpcm9ubWVudCwgZXhhY3Qgc3BlbGxpbmcgZmlyc3QuXG4gKiBLbm93biBsb25nIGFuZCBzaG9ydCBuYW1lcyBhcmUgaW50ZXJjaGFuZ2VhYmxlOyB1bmtub3duIG5hbWVzIHBhc3MgdGhyb3VnaC5cbiAqL1xuZnVuY3Rpb24gbm9kZUVudk5hbWVzKG5vZGVFbnY6IHVua25vd24pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG5hbWUgPSBzaGFyZWRTdHJpbmcudHJpbVRvTnVsbChub2RlRW52KT8udG9Mb3dlckNhc2UoKTtcbiAgaWYgKCFuYW1lIHx8ICEvXlthLXowLTlfLV0rJC8udGVzdChuYW1lKSkgcmV0dXJuIFtdO1xuICBmb3IgKGNvbnN0IFtjYW5vbmljYWwsIGFsdGVybmF0aXZlc10gb2YgT2JqZWN0LmVudHJpZXMoTk9ERV9FTlZfQUxURVJOQVRJVkVTKSkge1xuICAgIGNvbnN0IG5hbWVzOiByZWFkb25seSBzdHJpbmdbXSA9IGFsdGVybmF0aXZlcztcbiAgICBpZiAobmFtZSA9PT0gY2Fub25pY2FsIHx8IG5hbWVzLmluY2x1ZGVzKG5hbWUpKSB7XG4gICAgICByZXR1cm4gWy4uLm9iamVjdC5zZXF1ZW5jZShuYW1lLCBjYW5vbmljYWwsIGFsdGVybmF0aXZlcykuZGlzdGluY3QoKV07XG4gICAgfVxuICB9XG4gIHJldHVybiBbbmFtZV07XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHN0cmluZzogYGNvbmZpZ3VyZWRgIHdoZW4gbm9uLWVtcHR5LCBlbHNlIHtAbGluayB0ZXh0fSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqXG4gKiBUaGUgY29lcmNpb24gcnVsZXMgYXJlIGRlbGliZXJhdGVseSBsb29zZSAoYG9uYCAvIGB5ZXNgIC8gYDFgIGFyZSBhbGxcbiAqIGB0cnVlYCkgYmVjYXVzZSB2YWx1ZXMgbWF5IGNvbWUgZnJvbSBhIGZpbGUgYSBodW1hbiB0eXBlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uZmlnLnN0cmluZyhvcHRpb25zLmhvc3QsIFwiU01UUF9IT1NUXCIpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nKFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBzaGFyZWRTdHJpbmcudHJpbVRvTnVsbChjb25maWd1cmVkKSA/PyB0ZXh0KGlucHV0LCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgYm9vbGVhbiB0aHJvdWdoIGBvYmplY3QudG9Cb29sZWFuYC4gYHVuZGVmaW5lZGAgd2hlbiBuZWl0aGVyIHNvdXJjZVxuICogaXMgaW50ZXJwcmV0YWJsZSwgc28gdGhlIGNhbGxlciBwaWNrcyBhIGRlZmF1bHQgd2l0aCBgPz9gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYm9vbGVhbihcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIG9iamVjdC50b0Jvb2xlYW4oY29uZmlndXJlZCkgPz8gb2JqZWN0LnRvQm9vbGVhbih0ZXh0KGlucHV0LCBvcHRpb25zKSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHBvc2l0aXZlIG51bWJlciB0aGF0IG1heSBiZSBmcmFjdGlvbmFsIChhIHNjb3JlIHRocmVzaG9sZCwgYSByYXRpbykuXG4gKiBVc2Uge0BsaW5rIHBvc2l0aXZlSW50fSBmb3IgYSBjb3VudCwgcG9ydCwgb3IgdGltZW91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlTnVtYmVyKFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBmYWxsYmFjazogbnVtYmVyLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIGNvbnN0IGZyb21Db25maWcgPSBwb3NpdGl2ZU51bWJlclZhbHVlLnNhZmVQYXJzZShjb25maWd1cmVkKTtcbiAgaWYgKGZyb21Db25maWcuc3VjY2VzcykgcmV0dXJuIGZyb21Db25maWcuZGF0YTtcbiAgY29uc3QgZnJvbVNvdXJjZXMgPSBwb3NpdGl2ZU51bWJlclZhbHVlLnNhZmVQYXJzZSh0ZXh0KGlucHV0LCBvcHRpb25zKSk7XG4gIHJldHVybiBmcm9tU291cmNlcy5zdWNjZXNzID8gZnJvbVNvdXJjZXMuZGF0YSA6IGZhbGxiYWNrO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBwb3NpdGl2ZSBpbnRlZ2VyIChhIHBvcnQsIGEgdGltZW91dCwgYSBwYWdlIHNpemUpLCBmbG9vcmVkLiBBXG4gKiBub24tbnVtZXJpYyBvciBub24tcG9zaXRpdmUgdmFsdWUgaXMgdHJlYXRlZCBhcyBBQlNFTlQgcmF0aGVyIHRoYW4gZmF0YWwgLVxuICogdGhlc2UgYXJlIGNlaWxpbmdzIHdoZXJlIGEgc2FuZSBkZWZhdWx0IGJlYXRzIGEgYm9vdCBmYWlsdXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9zaXRpdmVJbnQoXG4gIGNvbmZpZ3VyZWQ6IHVua25vd24sXG4gIGlucHV0OiBDb25maWdLZXksXG4gIGZhbGxiYWNrOiBudW1iZXIsXG4gIG9wdGlvbnM/OiBDb25maWdPcHRpb25zLFxuKTogbnVtYmVyIHtcbiAgY29uc3QgZnJvbUNvbmZpZyA9IHBvc2l0aXZlSW50VmFsdWUuc2FmZVBhcnNlKGNvbmZpZ3VyZWQpO1xuICBpZiAoZnJvbUNvbmZpZy5zdWNjZXNzKSByZXR1cm4gZnJvbUNvbmZpZy5kYXRhO1xuICBjb25zdCBmcm9tU291cmNlcyA9IHBvc2l0aXZlSW50VmFsdWUuc2FmZVBhcnNlKHRleHQoaW5wdXQsIG9wdGlvbnMpKTtcbiAgcmV0dXJuIGZyb21Tb3VyY2VzLnN1Y2Nlc3MgPyBmcm9tU291cmNlcy5kYXRhIDogTWF0aC5mbG9vcihmYWxsYmFjayk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIFRDUCBwb3J0IGJldHdlZW4gMSBhbmQge0BsaW5rIE1BWF9UQ1BfUE9SVH0uIEludmFsaWQgY29uZmlndXJlZCBvclxuICogc291cmNlZCB2YWx1ZXMgZmFsbCBiYWNrIHRvIHRoZSBjYWxsZXIncyBkZWZhdWx0LCB3aGljaCBtYXkgYmUgYSBzZW50aW5lbFxuICogc3VjaCBhcyBgMGAgd2hlbiB0aGUgY2FsbGVyIHVzZXMgb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9ydChcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgZmFsbGJhY2s6IG51bWJlcixcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBudW1iZXIge1xuICBjb25zdCBmcm9tQ29uZmlnID0gcG9ydFZhbHVlU2NoZW1hLnNhZmVQYXJzZShjb25maWd1cmVkKTtcbiAgaWYgKGZyb21Db25maWcuc3VjY2VzcykgcmV0dXJuIGZyb21Db25maWcuZGF0YTtcbiAgY29uc3QgZnJvbVNvdXJjZXMgPSBwb3J0VmFsdWVTY2hlbWEuc2FmZVBhcnNlKHRleHQoaW5wdXQsIG9wdGlvbnMpKTtcbiAgcmV0dXJuIGZyb21Tb3VyY2VzLnN1Y2Nlc3MgPyBmcm9tU291cmNlcy5kYXRhIDogZmFsbGJhY2s7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGxpc3QgdGhyb3VnaCBgc3RyaW5nLnBhcnNlTGlzdGAsIHNvIGFuIGFycmF5IGZyb20gdHlwZWQgY29uZmlnIGFuZCBhXG4gKiBgXCJhLCBiIGNcImAgc3RyaW5nIG5vcm1hbGl6ZSBpZGVudGljYWxseS4gYFtdYCB3aGVuIG5laXRoZXIgc291cmNlIGhhcyBlbnRyaWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGlzdChcbiAgY29uZmlndXJlZDogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQgfCBudWxsLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICB0cmFuc2Zvcm0/OiAoZW50cnk6IHN0cmluZykgPT4gc3RyaW5nLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgZnJvbUNvbmZpZyA9IHNoYXJlZFN0cmluZy5wYXJzZUxpc3QoY29uZmlndXJlZCwgdHJhbnNmb3JtKTtcbiAgcmV0dXJuIGZyb21Db25maWcubGVuZ3RoID4gMFxuICAgID8gZnJvbUNvbmZpZ1xuICAgIDogc2hhcmVkU3RyaW5nLnBhcnNlTGlzdCh0ZXh0KGlucHV0LCBvcHRpb25zKSwgdHJhbnNmb3JtKTtcbn1cblxuLyoqXG4gKiBUaGUgRGF0YWJyaWNrcyBidW5kbGUgb3V0cHV0IGZvciBgY3dkYCAtIGBkYXRhYnJpY2tzIGJ1bmRsZSB2YWxpZGF0ZSAtLW91dHB1dFxuICoganNvbmAgcnVuIGZyb20gdGhlIGRpcmVjdG9yeSBob2xkaW5nIGBkYXRhYnJpY2tzLnltbGAsIHdpdGggdGhlIGNvbmZpZyBmaWxlJ3NcbiAqIHBhdGguIEEgbm9uLXplcm8gdmFsaWRhdGlvbiBtYXkgc3RpbGwgcmV0dXJuIHBhcnRpYWwgSlNPTiB3aXRoIHVzYWJsZSBBcHBcbiAqIGNvbmZpZy4gYHVuZGVmaW5lZGAgd2hlbiBidW5kbGUgcmVhZHMgYXJlIGRpc2FibGVkLCB0aGUgcHJvY2VzcyBpcyBwcm9kdWN0aW9uXG4gKiBvciBhIGRlcGxveWVkIEFwcCB3aXRob3V0IGFuIGV4cGxpY2l0IG92ZXJyaWRlLCB0aGVyZSBpcyBubyBidW5kbGUsIG9yIHRoZVxuICogQ0xJIHByb2R1Y2VzIG5vIEpTT04uXG4gKlxuICogUGFyc2VkIHZhbGlkYXRpb24gb3V0cHV0IGlzIGNhY2hlZCBieSBidW5kbGUgcGF0aCBhbmQgRGF0YWJyaWNrcyBwcm9maWxlLlxuICpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1bmRsZUZpbGUoY3dkPzogc3RyaW5nIHwgbnVsbCk6IENvbmZpZ0ZpbGUgfCB1bmRlZmluZWQge1xuICBjb25zdCBvdmVycmlkZSA9IG9iamVjdC50b0Jvb2xlYW4ocHJvY2Vzcy5lbnZbQ09ORklHX0JVTkRMRV9LRVldKTtcbiAgaWYgKG92ZXJyaWRlID09PSBmYWxzZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKFxuICAgIG92ZXJyaWRlID09PSB1bmRlZmluZWQgJiZcbiAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlY/LnRyaW0oKS50b0xvd2VyQ2FzZSgpID09PSBcInByb2R1Y3Rpb25cIiB8fCBpc0RhdGFicmlja3NBcHBFbnYoKSlcbiAgKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVXb3JraW5nRGlyZWN0b3J5KGN3ZCk7XG4gIHJldHVybiBsb2FkQnVuZGxlRmlsZShyZXNvbHZlZCwgc2hhcmVkU3RyaW5nLnRyaW1Ub051bGwocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19DT05GSUdfUFJPRklMRSkpO1xufVxuXG4vKiogVGhlIHBhcnNlZCBgYXBwLnlhbWxgIC8gYGFwcC55bWxgIGZvciBgY3dkYCwgd2hlbiBsb2NhbCBBcHAgY29uZmlnIHJlYWRzIGFyZSBlbmFibGVkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcEZpbGUoY3dkPzogc3RyaW5nIHwgbnVsbCk6IENvbmZpZ0ZpbGUgfCB1bmRlZmluZWQge1xuICBjb25zdCBlbmFibGVkID0gb2JqZWN0LnRvQm9vbGVhbihwcm9jZXNzLmVudltDT05GSUdfQVBQX0tFWV0pID8/ICFpc0RhdGFicmlja3NBcHBFbnYoKTtcbiAgaWYgKCFlbmFibGVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gbG9hZEFwcEZpbGUocmVzb2x2ZVdvcmtpbmdEaXJlY3RvcnkoY3dkKSk7XG59XG5cbi8qKiBUaGUgc2luZ2xlIGJ1bmRsZSBBcHAncyByZXNvbHZlZCBlbnZpcm9ubWVudCwgd2hlbiBhdmFpbGFibGUuICovXG5mdW5jdGlvbiBidW5kbGVFbnZpcm9ubWVudChvcHRpb25zOiBDb25maWdPcHRpb25zKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRhdGEgPSBzb3VyY2VEYXRhKG9wdGlvbnMuYnVuZGxlRGF0YSkgPz8gYnVuZGxlRmlsZShvcHRpb25zLmN3ZCk/LmRhdGE7XG4gIHJldHVybiBkYXRhID8gZmxhdHRlbkJ1bmRsZUVudihkYXRhKSA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gYXBwRW52aXJvbm1lbnQob3B0aW9uczogQ29uZmlnT3B0aW9ucyk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQge1xuICBjb25zdCBkYXRhID0gc291cmNlRGF0YShvcHRpb25zLmFwcERhdGEpID8/IGFwcEZpbGUob3B0aW9ucy5jd2QpPy5kYXRhO1xuICByZXR1cm4gZGF0YSA/IGZsYXR0ZW5BcHBFbnYoZGF0YSkgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHNvdXJjZURhdGEoXG4gIHNvdXJjZTogQ29uZmlnRmlsZSB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkLFxuKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQge1xuICBpZiAoIXNvdXJjZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKFwicGF0aFwiIGluIHNvdXJjZSAmJiB0eXBlb2Ygc291cmNlLnBhdGggPT09IFwic3RyaW5nXCIgJiYgb2JqZWN0LmlzUmVjb3JkKHNvdXJjZS5kYXRhKSkge1xuICAgIHJldHVybiBzb3VyY2UuZGF0YTtcbiAgfVxuICByZXR1cm4gc291cmNlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG4vKiogUGFyc2VkIGAuZW52YCBmb3IgYGN3ZGAsIG9yIGB7fWA7IHBhcnNlZCBmaWxlIGRhdGEgaXMgY2FjaGVkIGJ5IHBhdGguICovXG5mdW5jdGlvbiBkb3RlbnYoY3dkPzogc3RyaW5nIHwgbnVsbCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBlbmFibGVkID0gb2JqZWN0LnRvQm9vbGVhbihwcm9jZXNzLmVudltDT05GSUdfRE9URU5WX0tFWV0pID8/ICFpc0RhdGFicmlja3NBcHBFbnYoKTtcbiAgaWYgKCFlbmFibGVkKSByZXR1cm4ge307XG4gIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZVdvcmtpbmdEaXJlY3RvcnkoY3dkKTtcbiAgcmV0dXJuIGxvYWREb3RlbnYocmVzb2x2ZWQsIG5vZGVFbnZOYW1lcyhwcm9jZXNzLmVudi5OT0RFX0VOVikpO1xufVxuXG4vKiogTWFwcyBmb3Igb25lIHNvdXJjZSBpbiBwcmVjZWRlbmNlIG9yZGVyLiAqL1xuZnVuY3Rpb24gcmVhZChcbiAgc291cmNlOiBDb25maWdTb3VyY2UsXG4gIG9wdGlvbnM6IENvbmZpZ09wdGlvbnMsXG4pOiBvYmplY3QuU2VxdWVuY2U8UmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+PiB7XG4gIHJldHVybiBvYmplY3Quc2VxdWVuY2Uoe1xuICAgICpbU3ltYm9sLml0ZXJhdG9yXSgpOiBHZW5lcmF0b3I8UmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+PiB7XG4gICAgICBzd2l0Y2ggKHNvdXJjZSkge1xuICAgICAgICBjYXNlIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gb3B0aW9ucy5kYXRhO1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICB5aWVsZCogZGF0YTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGRhdGEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgeWllbGQgZGF0YSBhcyBDb25maWdEYXRhO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIFwiZW52XCI6XG4gICAgICAgICAgeWllbGQgcHJvY2Vzcy5lbnY7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJkb3RlbnZcIjpcbiAgICAgICAgICB5aWVsZCBkb3RlbnYob3B0aW9ucy5jd2QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiYnVuZGxlXCI6IHtcbiAgICAgICAgICBjb25zdCBlbnZpcm9ubWVudCA9IGJ1bmRsZUVudmlyb25tZW50KG9wdGlvbnMpO1xuICAgICAgICAgIGlmIChlbnZpcm9ubWVudCkgeWllbGQgZW52aXJvbm1lbnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcImFwcFwiOiB7XG4gICAgICAgICAgY29uc3QgZW52aXJvbm1lbnQgPSBhcHBFbnZpcm9ubWVudChvcHRpb25zKTtcbiAgICAgICAgICBpZiAoZW52aXJvbm1lbnQpIHlpZWxkIGVudmlyb25tZW50O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVW5rbm93biBjb25maWcgc291cmNlOiAke3NvdXJjZX1gKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBMb2NhdGUgYG5hbWVzYCBmcm9tIGBjd2RgIG91dHdhcmQuIGBjd2RgIGl0c2VsZiBpcyBjaGVja2VkIGJlZm9yZSB0aGVcbiAqIGRpc2NvdmVyZWQgcHJvamVjdCByb290cyBzbyBhIHBhY2thZ2UtbG9jYWwgZmlsZSB3aW5zIG92ZXIgdGhlIHdvcmtzcGFjZSdzLlxuICovXG5mdW5jdGlvbiBmaW5kQ29uZmlnRmlsZShjd2Q6IHN0cmluZywgbmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc3RhcnQgPSByZXNvbHZlKGN3ZCk7XG4gIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFtzdGFydCwgLi4ubmFtZXNdKTtcbiAgaWYgKGNvbmZpZ0ZpbGVDYWNoZS5oYXMoa2V5KSkgcmV0dXJuIGNvbmZpZ0ZpbGVDYWNoZS5nZXQoa2V5KTtcbiAgY29uc3Qgcm9vdCA9IHJlc29sdmVQcm9qZWN0Um9vdChzdGFydCk7XG4gIGNvbnN0IHBhdGhGcm9tUm9vdCA9IHJvb3QgPyByZWxhdGl2ZShyb290LCBzdGFydCkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGJvdW5kYXJ5ID1cbiAgICByb290ICYmXG4gICAgcGF0aEZyb21Sb290ICE9PSB1bmRlZmluZWQgJiZcbiAgICAhaXNBYnNvbHV0ZShwYXRoRnJvbVJvb3QpICYmXG4gICAgcGF0aEZyb21Sb290ICE9PSBcIi4uXCIgJiZcbiAgICAhcGF0aEZyb21Sb290LnN0YXJ0c1dpdGgoYC4uJHtzZXB9YClcbiAgICAgID8gcm9vdFxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGZvciAobGV0IGRpciA9IHN0YXJ0OyA7IGRpciA9IGRpcm5hbWUoZGlyKSkge1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgICAgY29uc3QgcGF0aCA9IHJlc29sdmUoZGlyLCBuYW1lKTtcbiAgICAgIGlmIChzdGF0U3luYyhwYXRoKT8uaXNGaWxlKCkpIHtcbiAgICAgICAgY29uZmlnRmlsZUNhY2hlLnNldChrZXksIHBhdGgpO1xuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGJvdW5kYXJ5ID09PSB1bmRlZmluZWQgfHwgZGlyID09PSBib3VuZGFyeSkgYnJlYWs7XG4gIH1cbiAgY29uZmlnRmlsZUNhY2hlLnNldChrZXksIHVuZGVmaW5lZCk7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxvYWREb3RlbnYoXG4gIGN3ZDogc3RyaW5nLFxuICBlbnZpcm9ubWVudHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IG5hbWVzID0gWy4uLmVudmlyb25tZW50cy5tYXAoKG5hbWUpID0+IGAke0RPVEVOVl9GSUxFX05BTUV9LiR7bmFtZX1gKSwgRE9URU5WX0ZJTEVfTkFNRV07XG4gIGNvbnN0IHBhdGggPSBmaW5kQ29uZmlnRmlsZShjd2QsIG5hbWVzKTtcbiAgaWYgKCFwYXRoKSByZXR1cm4ge307XG4gIHJldHVybiAoXG4gICAgY2FjaGVkUmVjb3JkKEpTT04uc3RyaW5naWZ5KFtcImRvdGVudlwiLCBwYXRoXSksICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBwYXJzZUVudihyZWFkRmlsZVN5bmMocGF0aCwgXCJ1dGY4XCIpKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byByZWFkIGRvdGVudiBmaWxlXCIsIHsgcGF0aCB9KTtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgfVxuICAgIH0pID8/IHt9XG4gICk7XG59XG5cbmZ1bmN0aW9uIGxvYWRCdW5kbGVGaWxlKGN3ZDogc3RyaW5nLCBwcm9maWxlOiBzdHJpbmcgfCBudWxsKTogQ29uZmlnRmlsZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHBhdGggPSBmaW5kQ29uZmlnRmlsZShjd2QsIEJVTkRMRV9GSUxFX05BTUVTKTtcbiAgaWYgKCFwYXRoKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBkYXRhID0gY2FjaGVkUmVjb3JkKEpTT04uc3RyaW5naWZ5KFtcImJ1bmRsZVwiLCBwYXRoLCBwcm9maWxlXSksICgpID0+IHtcbiAgICBjb25zdCBhcmdzID0gW1xuICAgICAgXCJidW5kbGVcIixcbiAgICAgIFwidmFsaWRhdGVcIixcbiAgICAgIFwiLS1vdXRwdXRcIixcbiAgICAgIFwianNvblwiLFxuICAgICAgLi4uKHByb2ZpbGUgPT09IG51bGwgPyBbXSA6IFtcIi0tcHJvZmlsZVwiLCBwcm9maWxlXSksXG4gICAgXTtcbiAgICBjb25zdCByZXN1bHQgPSBzcGF3blN5bmMoXCJkYXRhYnJpY2tzXCIsIGFyZ3MsIHtcbiAgICAgIGN3ZDogcmVzb2x2ZShwYXRoLCBcIi4uXCIpLFxuICAgICAgZW5jb2Rpbmc6IFwidXRmOFwiLFxuICAgICAgc3RkaW86IFtcImlnbm9yZVwiLCBcInBpcGVcIiwgXCJwaXBlXCJdLFxuICAgIH0pO1xuICAgIGNvbnN0IG91dHB1dCA9IHNoYXJlZFN0cmluZy50cmltVG9OdWxsKHJlc3VsdC5zdGRvdXQpO1xuICAgIGNvbnN0IGVycm9yID0gc2hhcmVkU3RyaW5nLnRyaW1Ub051bGwocmVzdWx0LnN0ZGVycik7XG4gICAgaWYgKG91dHB1dCA9PT0gbnVsbCkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwiYnVuZGxlIHZhbGlkYXRlIHByb2R1Y2VkIG5vIEpTT05cIiwgeyBwYXRoLCBzdGF0dXM6IHJlc3VsdC5zdGF0dXMsIGVycm9yIH0pO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkID0ganNvbi5wYXJzZVJlY29yZChvdXRwdXQpO1xuICAgIGlmICghcGFyc2VkKSB7XG4gICAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byBwYXJzZSBidW5kbGUgdmFsaWRhdGUgb3V0cHV0XCIsIHsgcGF0aCwgc3RhdHVzOiByZXN1bHQuc3RhdHVzIH0pO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC5zdGF0dXMgIT09IDApIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcInVzaW5nIHBhcnRpYWwgYnVuZGxlIG91dHB1dFwiLCB7IHBhdGgsIHN0YXR1czogcmVzdWx0LnN0YXR1cywgZXJyb3IgfSk7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH0pO1xuICByZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogeyBwYXRoLCBkYXRhIH07XG59XG5cbmZ1bmN0aW9uIGxvYWRBcHBGaWxlKGN3ZDogc3RyaW5nKTogQ29uZmlnRmlsZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHBhdGggPSBmaW5kQ29uZmlnRmlsZShjd2QsIEFQUF9GSUxFX05BTUVTKTtcbiAgaWYgKCFwYXRoKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBkYXRhID0gY2FjaGVkUmVjb3JkKEpTT04uc3RyaW5naWZ5KFtcImFwcFwiLCBwYXRoXSksICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkID0gcGFyc2VZYW1sKHJlYWRGaWxlU3luYyhwYXRoLCBcInV0ZjhcIikpO1xuICAgICAgcmV0dXJuIG9iamVjdC5pc1JlY29yZChwYXJzZWQpID8gcGFyc2VkIDogdW5kZWZpbmVkO1xuICAgIH0gY2F0Y2gge1xuICAgICAgbG9nZ2VyLndhcm4oXCJmYWlsZWQgdG8gcGFyc2UgYXBwIHlhbWxcIiwgeyBwYXRoIH0pO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogeyBwYXRoLCBkYXRhIH07XG59XG4iXX0=