wxt 0.0.1 → 0.0.2

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/dist/cli.cjs ADDED
@@ -0,0 +1,1768 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli/index.ts
27
+ var import_cac = __toESM(require("cac"), 1);
28
+
29
+ // package.json
30
+ var version = "0.0.2";
31
+
32
+ // src/core/utils/getInternalConfig.ts
33
+ var import_node_path3 = __toESM(require("path"), 1);
34
+ var vite2 = __toESM(require("vite"), 1);
35
+ var import_consola2 = require("consola");
36
+
37
+ // src/core/utils/importTsFile.ts
38
+ var import_consola = require("consola");
39
+ var import_jiti = __toESM(require("jiti"), 1);
40
+ var import_babel = __toESM(require("jiti/dist/babel"), 1);
41
+ var import_path = require("path");
42
+ var import_unimport = require("unimport");
43
+ async function importTsFile(root, path5) {
44
+ const clientImports = await (0, import_unimport.scanExports)(
45
+ (0, import_path.resolve)(root, "node_modules/wxt/dist/client.js")
46
+ );
47
+ const jiti = (0, import_jiti.default)(__filename, {
48
+ cache: false,
49
+ esmResolve: true,
50
+ interopDefault: true,
51
+ transform(opts) {
52
+ opts.source = opts.source.replace(/^import ['"].*\.css['"];?$/gm, "");
53
+ opts.source = opts.source.replace(
54
+ /^import\s+.*\s+from ['"]webextension-polyfill['"];?$/gm,
55
+ ""
56
+ );
57
+ if (opts.filename === path5) {
58
+ const imports = clientImports.map((i) => `import { ${i.name} } from "${i.from}";`).join("\n") + "\n";
59
+ opts.source = imports + opts.source;
60
+ }
61
+ return (0, import_babel.default)(opts);
62
+ }
63
+ });
64
+ try {
65
+ return await jiti(path5);
66
+ } catch (err) {
67
+ import_consola.consola.error(`Failed to import file: ${path5}`);
68
+ throw err;
69
+ }
70
+ }
71
+
72
+ // src/core/vite-plugins/devHtmlPrerender.ts
73
+ var vite = __toESM(require("vite"), 1);
74
+
75
+ // src/core/utils/entrypoints.ts
76
+ var import_node_path = __toESM(require("path"), 1);
77
+ function getEntrypointName(entrypointsDir, inputPath) {
78
+ const relativePath = import_node_path.default.relative(entrypointsDir, inputPath);
79
+ const name = relativePath.split(/[\.\/]/, 2)[0];
80
+ return name;
81
+ }
82
+ function getEntrypointOutputFile(entrypoint, ext) {
83
+ return (0, import_node_path.resolve)(entrypoint.outputDir, `${entrypoint.name}${ext}`);
84
+ }
85
+ function getEntrypointBundlePath(entrypoint, outDir, ext) {
86
+ return (0, import_node_path.relative)(outDir, getEntrypointOutputFile(entrypoint, ext));
87
+ }
88
+
89
+ // src/core/vite-plugins/devHtmlPrerender.ts
90
+ var import_linkedom = require("linkedom");
91
+ var import_path2 = require("path");
92
+ function devHtmlPrerender(config) {
93
+ return {
94
+ apply: "build",
95
+ name: "wxt:dev-html-prerender",
96
+ config(userConfig) {
97
+ return vite.mergeConfig(
98
+ {
99
+ resolve: {
100
+ alias: {
101
+ "@wxt/reload-html": (0, import_path2.resolve)(
102
+ config.root,
103
+ "node_modules/wxt/dist/virtual-modules/reload-html.js"
104
+ )
105
+ }
106
+ }
107
+ },
108
+ userConfig
109
+ );
110
+ },
111
+ async transform(html, id) {
112
+ const server = config.server;
113
+ if (config.command !== "serve" || server == null || !id.endsWith(".html"))
114
+ return;
115
+ const originalUrl = `${server.origin}${id}`;
116
+ const name = getEntrypointName(config.entrypointsDir, id);
117
+ const url = `${server.origin}/${name}.html`;
118
+ const serverHtml = await server.transformIndexHtml(
119
+ url,
120
+ html,
121
+ originalUrl
122
+ );
123
+ const { document } = (0, import_linkedom.parseHTML)(serverHtml);
124
+ const pointToDevServer = (querySelector, attr) => {
125
+ document.querySelectorAll(querySelector).forEach((element) => {
126
+ const src = element.getAttribute(attr);
127
+ if (!src)
128
+ return;
129
+ if ((0, import_path2.isAbsolute)(src)) {
130
+ element.setAttribute(attr, server.origin + src);
131
+ } else if (src.startsWith(".")) {
132
+ const abs = (0, import_path2.resolve)((0, import_path2.dirname)(id), src);
133
+ const pathname = (0, import_path2.relative)(config.root, abs);
134
+ element.setAttribute(attr, `${server.origin}/${pathname}`);
135
+ }
136
+ });
137
+ };
138
+ pointToDevServer("script[type=module]", "src");
139
+ pointToDevServer("link[rel=stylesheet]", "href");
140
+ const reloader = document.createElement("script");
141
+ reloader.src = "@wxt/reload-html";
142
+ reloader.type = "module";
143
+ document.head.appendChild(reloader);
144
+ const newHtml = document.toString();
145
+ config.logger.debug("Transformed " + id);
146
+ config.logger.debug("Old HTML:\n" + html);
147
+ config.logger.debug("New HTML:\n" + newHtml);
148
+ return newHtml;
149
+ }
150
+ };
151
+ }
152
+
153
+ // src/core/vite-plugins/devServerGlobals.ts
154
+ function devServerGlobals(internalConfig) {
155
+ return {
156
+ name: "wxt:dev-server-globals",
157
+ config(config) {
158
+ if (internalConfig.server == null || internalConfig.command == "build")
159
+ return;
160
+ config.define ??= {};
161
+ config.define.__DEV_SERVER_PROTOCOL__ = JSON.stringify("ws:");
162
+ config.define.__DEV_SERVER_HOSTNAME__ = JSON.stringify(
163
+ internalConfig.server.hostname
164
+ );
165
+ config.define.__DEV_SERVER_PORT__ = JSON.stringify(
166
+ internalConfig.server.port
167
+ );
168
+ }
169
+ };
170
+ }
171
+
172
+ // src/core/utils/network.ts
173
+ var import_node_dns = __toESM(require("dns"), 1);
174
+
175
+ // src/core/utils/promises.ts
176
+ function withTimeout(promise, duration) {
177
+ return new Promise((res, rej) => {
178
+ const timeout = setTimeout(() => {
179
+ rej(`Promise timed out after ${duration}ms`);
180
+ }, duration);
181
+ promise.then(res).catch(rej).finally(() => clearTimeout(timeout));
182
+ });
183
+ }
184
+
185
+ // src/core/utils/network.ts
186
+ function isOffline() {
187
+ const isOffline2 = new Promise((res) => {
188
+ import_node_dns.default.resolve("google.com", (err) => {
189
+ if (err == null) {
190
+ res(false);
191
+ } else {
192
+ res(true);
193
+ }
194
+ });
195
+ });
196
+ return withTimeout(isOffline2, 1e3).catch(() => true);
197
+ }
198
+ async function isOnline() {
199
+ const offline = await isOffline();
200
+ return !offline;
201
+ }
202
+ async function fetchCached(url, config) {
203
+ let content = "";
204
+ if (await isOnline()) {
205
+ const res = await fetch(url);
206
+ if (res.status < 300) {
207
+ content = await res.text();
208
+ await config.fsCache.set(url, content);
209
+ } else {
210
+ config.logger.debug(
211
+ `Failed to download "${url}", falling back to cache...`
212
+ );
213
+ }
214
+ }
215
+ if (!content)
216
+ content = await config.fsCache.get(url) ?? "";
217
+ if (!content)
218
+ throw Error(
219
+ `Offline and "${url}" has not been cached. Try again when online.`
220
+ );
221
+ return content;
222
+ }
223
+
224
+ // src/core/vite-plugins/download.ts
225
+ function download(config) {
226
+ return {
227
+ name: "wxt:download",
228
+ resolveId(id) {
229
+ if (id.startsWith("url:"))
230
+ return "\0" + id;
231
+ },
232
+ async load(id) {
233
+ if (!id.startsWith("\0url:"))
234
+ return;
235
+ const url = id.replace("\0url:", "");
236
+ return await fetchCached(url, config);
237
+ }
238
+ };
239
+ }
240
+
241
+ // src/core/vite-plugins/multipageMove.ts
242
+ var import_node_path2 = require("path");
243
+ var import_fs_extra = __toESM(require("fs-extra"), 1);
244
+ function multipageMove(entrypoints, config) {
245
+ return {
246
+ name: "wxt:multipage-move",
247
+ async writeBundle(_, bundle) {
248
+ for (const oldBundlePath in bundle) {
249
+ const entrypoint = entrypoints.find(
250
+ (entry) => !!entry.inputPath.endsWith(oldBundlePath)
251
+ );
252
+ if (entrypoint == null) {
253
+ config.logger.debug("No entrypoint found for", oldBundlePath);
254
+ continue;
255
+ }
256
+ const newBundlePath = getEntrypointBundlePath(
257
+ entrypoint,
258
+ config.outDir,
259
+ (0, import_node_path2.extname)(oldBundlePath)
260
+ );
261
+ if (newBundlePath === oldBundlePath) {
262
+ config.logger.debug(
263
+ "HTML file is already in the correct location",
264
+ oldBundlePath
265
+ );
266
+ continue;
267
+ }
268
+ const oldAbsPath = (0, import_node_path2.resolve)(config.outDir, oldBundlePath);
269
+ const newAbsPath = (0, import_node_path2.resolve)(config.outDir, newBundlePath);
270
+ await (0, import_fs_extra.ensureDir)((0, import_node_path2.dirname)(newAbsPath));
271
+ await import_fs_extra.default.move(oldAbsPath, newAbsPath, { overwrite: true });
272
+ const renamedChunk = {
273
+ ...bundle[oldBundlePath],
274
+ fileName: newBundlePath
275
+ };
276
+ delete bundle[oldBundlePath];
277
+ bundle[newBundlePath] = renamedChunk;
278
+ }
279
+ }
280
+ };
281
+ }
282
+
283
+ // src/core/vite-plugins/unimport.ts
284
+ var import_unimport2 = require("unimport");
285
+
286
+ // src/core/utils/auto-imports.ts
287
+ var import_vite = require("vite");
288
+ function getUnimportOptions(config) {
289
+ const defaultOptions = {
290
+ debugLog: config.logger.debug,
291
+ imports: [
292
+ { name: "*", as: "browser", from: "webextension-polyfill" },
293
+ { name: "defineConfig", from: "wxt" }
294
+ ],
295
+ presets: [{ package: "wxt/client" }],
296
+ warn: config.logger.warn,
297
+ dirs: ["components", "composables", "hooks", "utils"]
298
+ };
299
+ return (0, import_vite.mergeConfig)(
300
+ defaultOptions,
301
+ config.imports
302
+ );
303
+ }
304
+
305
+ // src/core/vite-plugins/unimport.ts
306
+ function unimport(config) {
307
+ const options = getUnimportOptions(config);
308
+ const unimport2 = (0, import_unimport2.createUnimport)(options);
309
+ return {
310
+ name: "wxt:unimport",
311
+ async config() {
312
+ await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
313
+ },
314
+ async transform(code, id) {
315
+ return unimport2.injectImports(code, id);
316
+ }
317
+ };
318
+ }
319
+
320
+ // src/core/vite-plugins/virtualEntrypoint.ts
321
+ var import_fs_extra2 = __toESM(require("fs-extra"), 1);
322
+ var import_path3 = require("path");
323
+ function virtualEntrypoin(type, config) {
324
+ const virtualId = `virtual:wxt-${type}?`;
325
+ const resolvedVirtualId = `\0${virtualId}`;
326
+ return {
327
+ name: `wxt:virtual-entrypoint`,
328
+ resolveId(id) {
329
+ const index = id.indexOf(virtualId);
330
+ if (index === -1)
331
+ return;
332
+ const inputPath = id.substring(index + virtualId.length);
333
+ return resolvedVirtualId + inputPath;
334
+ },
335
+ async load(id) {
336
+ if (!id.startsWith(resolvedVirtualId))
337
+ return;
338
+ const inputPath = id.replace(resolvedVirtualId, "");
339
+ const template = await import_fs_extra2.default.readFile(
340
+ (0, import_path3.resolve)(
341
+ config.root,
342
+ `node_modules/wxt/dist/virtual-modules/${type}-entrypoint.js`
343
+ ),
344
+ "utf-8"
345
+ );
346
+ return template.replace(`virtual:user-${type}`, inputPath);
347
+ }
348
+ };
349
+ }
350
+
351
+ // src/core/utils/createFsCache.ts
352
+ var import_fs_extra3 = __toESM(require("fs-extra"), 1);
353
+ var import_path4 = require("path");
354
+ function createFsCache(wxtDir) {
355
+ const getPath = (key) => (0, import_path4.resolve)(wxtDir, "cache", encodeURIComponent(key));
356
+ return {
357
+ async set(key, value) {
358
+ const path5 = getPath(key);
359
+ await (0, import_fs_extra3.ensureDir)((0, import_path4.dirname)(path5));
360
+ await import_fs_extra3.default.writeFile(path5, value, "utf-8");
361
+ },
362
+ async get(key) {
363
+ const path5 = getPath(key);
364
+ try {
365
+ return await import_fs_extra3.default.readFile(path5, "utf-8");
366
+ } catch {
367
+ return void 0;
368
+ }
369
+ }
370
+ };
371
+ }
372
+
373
+ // src/core/utils/globals.ts
374
+ function getGlobals(config) {
375
+ return [
376
+ {
377
+ name: "__MANIFEST_VERSION__",
378
+ value: config.manifestVersion,
379
+ type: `2 | 3`
380
+ },
381
+ {
382
+ name: "__BROWSER__",
383
+ value: config.browser,
384
+ type: `"chromium" | "firefox"`
385
+ },
386
+ {
387
+ name: "__IS_CHROME__",
388
+ value: config.browser === "chrome",
389
+ type: `boolean`
390
+ },
391
+ {
392
+ name: "__IS_FIREFOX__",
393
+ value: config.browser === "firefox",
394
+ type: `boolean`
395
+ },
396
+ {
397
+ name: "__IS_SAFARI__",
398
+ value: config.browser === "safari",
399
+ type: `boolean`
400
+ },
401
+ {
402
+ name: "__IS_EDGE__",
403
+ value: config.browser === "edge",
404
+ type: `boolean`
405
+ },
406
+ {
407
+ name: "__IS_OPERA__",
408
+ value: config.browser === "opera",
409
+ type: `boolean`
410
+ },
411
+ {
412
+ name: "__COMMAND__",
413
+ value: config.command,
414
+ type: `"build" | "serve"`
415
+ }
416
+ ];
417
+ }
418
+
419
+ // src/core/utils/getInternalConfig.ts
420
+ var import_c12 = require("c12");
421
+ async function getInternalConfig(config, command) {
422
+ const root = config.root ? import_node_path3.default.resolve(config.root) : process.cwd();
423
+ const mode = config.mode ?? (command === "build" ? "production" : "development");
424
+ const browser = config.browser ?? "chrome";
425
+ const manifestVersion = config.manifestVersion ?? (browser == "firefox" ? 2 : 3);
426
+ const outBaseDir = import_node_path3.default.resolve(root, ".output");
427
+ const outDir = import_node_path3.default.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
428
+ const logger = config.logger ?? import_consola2.consola;
429
+ const baseConfig = {
430
+ root,
431
+ outDir,
432
+ outBaseDir,
433
+ storeIds: config.storeIds ?? {},
434
+ browser,
435
+ manifestVersion,
436
+ mode,
437
+ command,
438
+ logger,
439
+ vite: config.vite ?? {},
440
+ manifest: config.manifest ?? {},
441
+ imports: config.imports ?? {},
442
+ runnerConfig: await (0, import_c12.loadConfig)({
443
+ name: "web-ext",
444
+ cwd: root,
445
+ globalRc: true,
446
+ rcFile: ".webextrc",
447
+ overrides: config.runner
448
+ })
449
+ };
450
+ let userConfig = {
451
+ mode
452
+ };
453
+ if (config.configFile !== false) {
454
+ userConfig = await importTsFile(
455
+ root,
456
+ import_node_path3.default.resolve(root, config.configFile ?? "wxt.config.ts")
457
+ );
458
+ }
459
+ const merged = vite2.mergeConfig(
460
+ baseConfig,
461
+ userConfig
462
+ );
463
+ const srcDir = userConfig.srcDir ? (0, import_node_path3.resolve)(root, userConfig.srcDir) : root;
464
+ const entrypointsDir = (0, import_node_path3.resolve)(
465
+ srcDir,
466
+ userConfig.entrypointsDir ?? "entrypoints"
467
+ );
468
+ const publicDir = (0, import_node_path3.resolve)(srcDir, userConfig.publicDir ?? "public");
469
+ const wxtDir = (0, import_node_path3.resolve)(srcDir, ".wxt");
470
+ const typesDir = (0, import_node_path3.resolve)(wxtDir, "types");
471
+ const finalConfig = {
472
+ ...merged,
473
+ srcDir,
474
+ entrypointsDir,
475
+ publicDir,
476
+ wxtDir,
477
+ typesDir,
478
+ fsCache: createFsCache(wxtDir)
479
+ };
480
+ finalConfig.vite.root = root;
481
+ finalConfig.vite.configFile = false;
482
+ finalConfig.vite.logLevel = "warn";
483
+ finalConfig.vite.build ??= {};
484
+ finalConfig.vite.build.outDir = outDir;
485
+ finalConfig.vite.build.emptyOutDir = false;
486
+ finalConfig.vite.plugins ??= [];
487
+ finalConfig.vite.plugins.push(download(finalConfig));
488
+ finalConfig.vite.plugins.push(devHtmlPrerender(finalConfig));
489
+ finalConfig.vite.plugins.push(unimport(finalConfig));
490
+ finalConfig.vite.plugins.push(
491
+ virtualEntrypoin("background", finalConfig)
492
+ );
493
+ finalConfig.vite.plugins.push(
494
+ virtualEntrypoin("content-script", finalConfig)
495
+ );
496
+ finalConfig.vite.plugins.push(devServerGlobals(finalConfig));
497
+ finalConfig.vite.define ??= {};
498
+ getGlobals(finalConfig).forEach((global) => {
499
+ finalConfig.vite.define[global.name] = JSON.stringify(global.value);
500
+ });
501
+ return finalConfig;
502
+ }
503
+
504
+ // src/core/build/findEntrypoints.ts
505
+ var import_path5 = require("path");
506
+ var import_fs_extra4 = __toESM(require("fs-extra"), 1);
507
+ var import_picomatch = __toESM(require("picomatch"), 1);
508
+ var import_linkedom2 = require("linkedom");
509
+ var import_json5 = __toESM(require("json5"), 1);
510
+ var import_fast_glob = __toESM(require("fast-glob"), 1);
511
+ async function findEntrypoints(config) {
512
+ const relativePaths = await (0, import_fast_glob.default)("**/*", {
513
+ cwd: config.entrypointsDir
514
+ });
515
+ relativePaths.sort();
516
+ const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
517
+ const existingNames = {};
518
+ const entrypoints = [];
519
+ await Promise.all(
520
+ relativePaths.map(async (relativePath) => {
521
+ const path5 = (0, import_path5.resolve)(config.entrypointsDir, relativePath);
522
+ const matchingGlob = pathGlobs.find(
523
+ (glob3) => import_picomatch.default.isMatch(relativePath, glob3)
524
+ );
525
+ if (matchingGlob == null) {
526
+ return config.logger.warn(
527
+ `${relativePath} does not match any known entrypoint. Known entrypoints:
528
+ ${JSON.stringify(
529
+ PATH_GLOB_TO_TYPE_MAP,
530
+ null,
531
+ 2
532
+ )}`
533
+ );
534
+ }
535
+ const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
536
+ if (type === "ignored")
537
+ return;
538
+ let entrypoint;
539
+ switch (type) {
540
+ case "popup":
541
+ entrypoint = await getPopupEntrypoint(config, path5);
542
+ break;
543
+ case "options":
544
+ entrypoint = await getOptionsEntrypoint(config, path5);
545
+ break;
546
+ case "background":
547
+ entrypoint = await getBackgroundEntrypoint(config, path5);
548
+ break;
549
+ case "content-script":
550
+ entrypoint = await getContentScriptEntrypoint(
551
+ config,
552
+ relativePath.split(".", 2)[0],
553
+ path5
554
+ );
555
+ break;
556
+ default:
557
+ entrypoint = {
558
+ type,
559
+ name: getEntrypointName(config.entrypointsDir, path5),
560
+ inputPath: path5,
561
+ outputDir: config.outDir
562
+ };
563
+ }
564
+ const withSameName = existingNames[entrypoint.name];
565
+ if (withSameName) {
566
+ throw Error(
567
+ `Multiple entrypoints with the name "${entrypoint.name}" detected, but only one is allowed: ${[
568
+ (0, import_path5.relative)(config.root, withSameName.inputPath),
569
+ (0, import_path5.relative)(config.root, entrypoint.inputPath)
570
+ ].join(", ")}`
571
+ );
572
+ }
573
+ entrypoints.push(entrypoint);
574
+ existingNames[entrypoint.name] = entrypoint;
575
+ })
576
+ );
577
+ return entrypoints;
578
+ }
579
+ async function getPopupEntrypoint(config, path5) {
580
+ const options = {};
581
+ const content = await import_fs_extra4.default.readFile(path5, "utf-8");
582
+ const { document } = (0, import_linkedom2.parseHTML)(content);
583
+ const title = document.querySelector("title");
584
+ if (title != null)
585
+ options.defaultTitle = title.textContent ?? void 0;
586
+ const defaultIconContent = document.querySelector("meta[name='manifest.default_icon']")?.getAttribute("content");
587
+ if (defaultIconContent) {
588
+ try {
589
+ options.defaultIcon = import_json5.default.parse(defaultIconContent);
590
+ } catch (err) {
591
+ config.logger.fatal(
592
+ `Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
593
+ err
594
+ );
595
+ }
596
+ }
597
+ const mv2KeyContent = document.querySelector("meta[name='manifest.type']")?.getAttribute("content");
598
+ if (mv2KeyContent) {
599
+ options.mv2Key = mv2KeyContent === "page_action" ? "page_action" : "browser_action";
600
+ }
601
+ return {
602
+ type: "popup",
603
+ name: "popup",
604
+ options,
605
+ inputPath: path5,
606
+ outputDir: config.outDir
607
+ };
608
+ }
609
+ async function getOptionsEntrypoint(config, path5) {
610
+ const options = {};
611
+ const content = await import_fs_extra4.default.readFile(path5, "utf-8");
612
+ const { document } = (0, import_linkedom2.parseHTML)(content);
613
+ const openInTabContent = document.querySelector("meta[name='manifest.open_in_tab']")?.getAttribute("content");
614
+ if (openInTabContent) {
615
+ options.openInTab = Boolean(openInTabContent);
616
+ }
617
+ const chromeStyleContent = document.querySelector("meta[name='manifest.chrome_style']")?.getAttribute("content");
618
+ if (chromeStyleContent) {
619
+ options.chromeStyle = Boolean(chromeStyleContent);
620
+ }
621
+ const browserStyleContent = document.querySelector("meta[name='manifest.browser_style']")?.getAttribute("content");
622
+ if (browserStyleContent) {
623
+ options.browserStyle = Boolean(browserStyleContent);
624
+ }
625
+ return {
626
+ type: "options",
627
+ name: "options",
628
+ options,
629
+ inputPath: path5,
630
+ outputDir: config.outDir
631
+ };
632
+ }
633
+ async function getBackgroundEntrypoint(config, path5) {
634
+ const { main: _, ...options } = await importTsFile(config.root, path5);
635
+ if (options == null) {
636
+ throw Error("Background script does not have a default export");
637
+ }
638
+ return {
639
+ type: "background",
640
+ name: "background",
641
+ inputPath: path5,
642
+ outputDir: config.outDir,
643
+ options
644
+ };
645
+ }
646
+ async function getContentScriptEntrypoint(config, name, path5) {
647
+ const { main: _, ...options } = await importTsFile(
648
+ config.root,
649
+ path5
650
+ );
651
+ if (options == null) {
652
+ throw Error(`Content script ${name} does not have a default export`);
653
+ }
654
+ return {
655
+ type: "content-script",
656
+ name: getEntrypointName(config.entrypointsDir, path5),
657
+ inputPath: path5,
658
+ outputDir: (0, import_path5.resolve)(config.outDir, "content-scripts"),
659
+ options
660
+ };
661
+ }
662
+ var PATH_GLOB_TO_TYPE_MAP = {
663
+ "sandbox.html": "sandbox",
664
+ "sandbox/index.html": "sandbox",
665
+ "*.sandbox.html": "sandbox",
666
+ "*.sandbox/index.html": "sandbox",
667
+ "bookmarks.html": "bookmarks",
668
+ "bookmarks/index.html": "bookmarks",
669
+ "history.html": "history",
670
+ "history/index.html": "history",
671
+ "newtab.html": "newtab",
672
+ "newtab/index.html": "newtab",
673
+ "sidepanel.html": "sidepanel",
674
+ "sidepanel/index.html": "sidepanel",
675
+ "*.sidepanel.html": "sidepanel",
676
+ "*.sidepanel/index.html": "sidepanel",
677
+ "devtools.html": "devtools",
678
+ "devtools/index.html": "devtools",
679
+ "background.ts": "background",
680
+ "*.content.ts?(x)": "content-script",
681
+ "*.content/index.ts?(x)": "content-script",
682
+ "popup.html": "popup",
683
+ "popup/index.html": "popup",
684
+ "options.html": "options",
685
+ "options/index.html": "options",
686
+ "*.html": "unlisted-page",
687
+ "*/index.html": "unlisted-page",
688
+ "*.ts": "unlisted-script",
689
+ // Don't warn about any files in subdirectories, like CSS or JS entrypoints for HTML files
690
+ "*/*": "ignored"
691
+ };
692
+
693
+ // src/core/build/buildEntrypoints.ts
694
+ var vite3 = __toESM(require("vite"), 1);
695
+
696
+ // src/core/utils/removeEmptyDirs.ts
697
+ var import_fs_extra5 = __toESM(require("fs-extra"), 1);
698
+ var import_path6 = __toESM(require("path"), 1);
699
+ async function removeEmptyDirs(dir) {
700
+ const files = await import_fs_extra5.default.readdir(dir);
701
+ for (const file of files) {
702
+ const filePath = import_path6.default.join(dir, file);
703
+ const stats = await import_fs_extra5.default.stat(filePath);
704
+ if (stats.isDirectory()) {
705
+ await removeEmptyDirs(filePath);
706
+ }
707
+ }
708
+ try {
709
+ await import_fs_extra5.default.rmdir(dir);
710
+ } catch {
711
+ }
712
+ }
713
+
714
+ // src/core/build/buildEntrypoints.ts
715
+ var import_fast_glob2 = __toESM(require("fast-glob"), 1);
716
+ var import_fs_extra6 = __toESM(require("fs-extra"), 1);
717
+ var import_path7 = require("path");
718
+ async function buildEntrypoints(groups, config) {
719
+ const steps = [];
720
+ for (const group of groups) {
721
+ const step = Array.isArray(group) ? await buildMultipleEntrypoints(group, config) : await buildSingleEntrypoint(group, config);
722
+ steps.push(step);
723
+ }
724
+ const publicAssets = await copyPublicDirectory(config);
725
+ await removeEmptyDirs(config.outDir);
726
+ return { publicAssets, steps };
727
+ }
728
+ async function buildSingleEntrypoint(entrypoint, config) {
729
+ const isVirtual = ["background", "content-script"].includes(entrypoint.type);
730
+ const entry = isVirtual ? `virtual:wxt-${entrypoint.type}?${entrypoint.inputPath}` : entrypoint.inputPath;
731
+ const libMode = {
732
+ build: {
733
+ lib: {
734
+ entry,
735
+ formats: ["iife"],
736
+ name: entrypoint.name,
737
+ fileName: entrypoint.name
738
+ },
739
+ rollupOptions: {
740
+ output: {
741
+ // There's only a single output for this build, so we use the desired bundle path for the
742
+ // entry output (like "content-scripts/overlay.js")
743
+ entryFileNames: getEntrypointBundlePath(
744
+ entrypoint,
745
+ config.outDir,
746
+ ".js"
747
+ ),
748
+ // Output content script CSS to assets/ with a hash to prevent conflicts. Defaults to
749
+ // "[name].[ext]" in lib mode, which usually results in "style.css". That means multiple
750
+ // content scripts with styles would overwrite each other if it weren't changed below.
751
+ assetFileNames: `assets/${entrypoint.name}.[ext]`
752
+ }
753
+ }
754
+ }
755
+ };
756
+ const entryConfig = vite3.mergeConfig(
757
+ libMode,
758
+ config.vite
759
+ );
760
+ const result = await vite3.build(entryConfig);
761
+ return {
762
+ entrypoints: entrypoint,
763
+ chunks: getBuildOutputChunks(result)
764
+ };
765
+ }
766
+ async function buildMultipleEntrypoints(entrypoints, config) {
767
+ const multiPage = {
768
+ plugins: [multipageMove(entrypoints, config)],
769
+ build: {
770
+ rollupOptions: {
771
+ input: entrypoints.reduce((input, entry) => {
772
+ input[entry.name] = entry.inputPath;
773
+ return input;
774
+ }, {}),
775
+ output: {
776
+ // Include a hash to prevent conflicts
777
+ chunkFileNames: "chunks/[name]-[hash].js",
778
+ // Include a hash to prevent conflicts
779
+ entryFileNames: "chunks/[name]-[hash].js",
780
+ // We can't control the "name", so we need a hash to prevent conflicts
781
+ assetFileNames: "assets/[name]-[hash].[ext]"
782
+ }
783
+ }
784
+ }
785
+ };
786
+ const entryConfig = vite3.mergeConfig(
787
+ multiPage,
788
+ config.vite
789
+ );
790
+ const result = await vite3.build(entryConfig);
791
+ return {
792
+ entrypoints,
793
+ chunks: getBuildOutputChunks(result)
794
+ };
795
+ }
796
+ function getBuildOutputChunks(result) {
797
+ if ("on" in result)
798
+ throw Error("wxt does not support vite watch mode.");
799
+ if (Array.isArray(result))
800
+ return result.flatMap(({ output }) => output);
801
+ return result.output;
802
+ }
803
+ async function copyPublicDirectory(config) {
804
+ const publicAssets = [];
805
+ if (!await import_fs_extra6.default.exists(config.publicDir))
806
+ return publicAssets;
807
+ const files = await (0, import_fast_glob2.default)("**/*", { cwd: config.publicDir });
808
+ for (const file of files) {
809
+ const srcPath = (0, import_path7.resolve)(config.publicDir, file);
810
+ const outPath = (0, import_path7.resolve)(config.outDir, file);
811
+ await import_fs_extra6.default.ensureDir((0, import_path7.dirname)(outPath));
812
+ await import_fs_extra6.default.copyFile(srcPath, outPath);
813
+ publicAssets.push({
814
+ type: "asset",
815
+ fileName: file,
816
+ name: file,
817
+ needsCodeReference: false,
818
+ source: await import_fs_extra6.default.readFile(srcPath)
819
+ });
820
+ }
821
+ return publicAssets;
822
+ }
823
+
824
+ // src/core/utils/manifest.ts
825
+ var import_fs_extra7 = __toESM(require("fs-extra"), 1);
826
+ var import_path8 = require("path");
827
+
828
+ // src/core/utils/ContentSecurityPolicy.ts
829
+ var ContentSecurityPolicy = class _ContentSecurityPolicy {
830
+ static DIRECTIVE_ORDER = {
831
+ "default-src": 0,
832
+ "script-src": 1,
833
+ "object-src": 2
834
+ };
835
+ data;
836
+ constructor(csp) {
837
+ if (csp) {
838
+ const sections = csp.split(";").map((section) => section.trim());
839
+ this.data = sections.reduce((data, section) => {
840
+ const [key, ...values] = section.split(" ").map((item) => item.trim());
841
+ if (key)
842
+ data[key] = values;
843
+ return data;
844
+ }, {});
845
+ } else {
846
+ this.data = {};
847
+ }
848
+ }
849
+ /**
850
+ * Ensure a set of values are listed under a directive.
851
+ */
852
+ add(directive, ...newValues) {
853
+ const values = this.data[directive] ?? [];
854
+ newValues.forEach((newValue) => {
855
+ if (!values.includes(newValue))
856
+ values.push(newValue);
857
+ });
858
+ this.data[directive] = values;
859
+ return this;
860
+ }
861
+ toString() {
862
+ const directives = Object.entries(this.data).sort(([l], [r]) => {
863
+ const lo = _ContentSecurityPolicy.DIRECTIVE_ORDER[l] ?? 2;
864
+ const ro = _ContentSecurityPolicy.DIRECTIVE_ORDER[r] ?? 2;
865
+ return lo - ro;
866
+ });
867
+ return directives.map((entry) => entry.flat().join(" ")).join("; ") + ";";
868
+ }
869
+ };
870
+
871
+ // src/core/utils/manifest.ts
872
+ async function writeManifest(manifest, output, config) {
873
+ const str = config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
874
+ await import_fs_extra7.default.ensureDir(config.outDir);
875
+ await import_fs_extra7.default.writeFile((0, import_path8.resolve)(config.outDir, "manifest.json"), str, "utf-8");
876
+ output.publicAssets.unshift({
877
+ type: "asset",
878
+ fileName: "manifest.json",
879
+ name: "manifest",
880
+ needsCodeReference: false,
881
+ source: str
882
+ });
883
+ }
884
+ async function generateMainfest(entrypoints, buildOutput, config) {
885
+ const pkg = await getPackageJson(config);
886
+ if (pkg.version == null)
887
+ throw Error("package.json does not include a version");
888
+ if (pkg.name == null)
889
+ throw Error("package.json does not include a name");
890
+ if (pkg.description == null)
891
+ throw Error("package.json does not include a description");
892
+ const manifest = {
893
+ manifest_version: config.manifestVersion,
894
+ name: pkg.name,
895
+ short_name: pkg.shortName,
896
+ version: simplifyVersion(pkg.version),
897
+ version_name: config.browser === "firefox" ? void 0 : pkg.version,
898
+ ...config.manifest
899
+ };
900
+ addEntrypoints(manifest, entrypoints, buildOutput, config);
901
+ if (config.command === "serve")
902
+ addDevModeCsp(manifest, config);
903
+ return manifest;
904
+ }
905
+ async function getPackageJson(config) {
906
+ return await import_fs_extra7.default.readJson((0, import_path8.resolve)(config.root, "package.json"));
907
+ }
908
+ function simplifyVersion(versionName) {
909
+ const version3 = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(
910
+ versionName
911
+ )?.[1];
912
+ if (version3 == null)
913
+ throw Error(
914
+ `Cannot simplify package.json version "${versionName}" to a valid extension version, "X.Y.Z"`
915
+ );
916
+ return version3;
917
+ }
918
+ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
919
+ const entriesByType = entrypoints.reduce((map, entrypoint) => {
920
+ map[entrypoint.type] ??= [];
921
+ map[entrypoint.type]?.push(entrypoint);
922
+ return map;
923
+ }, {});
924
+ const background = entriesByType["background"]?.[0];
925
+ const bookmarks = entriesByType["bookmarks"]?.[0];
926
+ const contentScripts = entriesByType["content-script"];
927
+ const devtools = entriesByType["devtools"]?.[0];
928
+ const history = entriesByType["history"]?.[0];
929
+ const newtab = entriesByType["newtab"]?.[0];
930
+ const options = entriesByType["options"]?.[0];
931
+ const popup = entriesByType["popup"]?.[0];
932
+ const sandboxes = entriesByType["sandbox"];
933
+ const sidepanels = entriesByType["sidepanel"];
934
+ if (background) {
935
+ const script = getEntrypointBundlePath(background, config.outDir, ".js");
936
+ if (manifest.manifest_version === 3) {
937
+ manifest.background = {
938
+ type: background.options.type,
939
+ service_worker: script
940
+ };
941
+ } else {
942
+ manifest.background = {
943
+ persistent: background.options.persistent,
944
+ scripts: [script]
945
+ };
946
+ }
947
+ }
948
+ if (bookmarks) {
949
+ if (config.browser === "firefox") {
950
+ config.logger.warn(
951
+ "Bookmarks are not supported by Firefox. chrome_url_overrides.bookmarks was not added to the manifest"
952
+ );
953
+ } else {
954
+ manifest.chrome_url_overrides ??= {};
955
+ manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath(
956
+ bookmarks,
957
+ config.outDir,
958
+ ".html"
959
+ );
960
+ }
961
+ }
962
+ if (history) {
963
+ if (config.browser === "firefox") {
964
+ config.logger.warn(
965
+ "Bookmarks are not supported by Firefox. chrome_url_overrides.history was not added to the manifest"
966
+ );
967
+ } else {
968
+ manifest.chrome_url_overrides ??= {};
969
+ manifest.chrome_url_overrides.history = getEntrypointBundlePath(
970
+ history,
971
+ config.outDir,
972
+ ".html"
973
+ );
974
+ }
975
+ }
976
+ if (newtab) {
977
+ manifest.chrome_url_overrides ??= {};
978
+ manifest.chrome_url_overrides.newtab = getEntrypointBundlePath(
979
+ newtab,
980
+ config.outDir,
981
+ ".html"
982
+ );
983
+ }
984
+ if (popup) {
985
+ const default_popup = getEntrypointBundlePath(
986
+ popup,
987
+ config.outDir,
988
+ ".html"
989
+ );
990
+ const options2 = {
991
+ default_icon: popup.options.defaultIcon,
992
+ default_title: popup.options.defaultTitle
993
+ };
994
+ if (manifest.manifest_version === 3) {
995
+ manifest.action = {
996
+ ...options2,
997
+ default_popup
998
+ };
999
+ } else {
1000
+ manifest[popup.options.mv2Key ?? "browser_action"] = {
1001
+ ...options2,
1002
+ default_popup
1003
+ };
1004
+ }
1005
+ }
1006
+ if (devtools) {
1007
+ manifest.devtools_page = getEntrypointBundlePath(
1008
+ devtools,
1009
+ config.outDir,
1010
+ ".html"
1011
+ );
1012
+ }
1013
+ if (options) {
1014
+ const page = getEntrypointBundlePath(options, config.outDir, ".html");
1015
+ manifest.options_ui = {
1016
+ open_in_tab: options.options.openInTab,
1017
+ browser_style: config.browser === "firefox" ? options.options.browserStyle : void 0,
1018
+ chrome_style: config.browser !== "firefox" ? options.options.chromeStyle : void 0,
1019
+ page
1020
+ };
1021
+ }
1022
+ if (sandboxes?.length) {
1023
+ if (config.browser === "firefox") {
1024
+ config.logger.warn(
1025
+ "Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest"
1026
+ );
1027
+ } else {
1028
+ manifest.sandbox = {
1029
+ pages: sandboxes.map(
1030
+ (entry) => getEntrypointBundlePath(entry, config.outDir, ".html")
1031
+ )
1032
+ };
1033
+ }
1034
+ }
1035
+ if (sidepanels?.length) {
1036
+ const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
1037
+ const page = getEntrypointBundlePath(
1038
+ defaultSidepanel,
1039
+ config.outDir,
1040
+ ".html"
1041
+ );
1042
+ if (config.browser === "firefox") {
1043
+ manifest.sidebar_action = {
1044
+ // TODO: Add options to side panel
1045
+ // ...defaultSidepanel.options,
1046
+ default_panel: page
1047
+ };
1048
+ } else if (config.manifestVersion === 3) {
1049
+ manifest.side_panel = {
1050
+ default_path: page
1051
+ };
1052
+ } else {
1053
+ config.logger.warn(
1054
+ "Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest"
1055
+ );
1056
+ }
1057
+ }
1058
+ if (contentScripts?.length) {
1059
+ if (config.command === "serve") {
1060
+ const permissionsKey = config.manifestVersion === 2 ? "permissions" : "host_permissions";
1061
+ const hostPermissions = new Set(manifest[permissionsKey] ?? []);
1062
+ contentScripts.forEach((script) => {
1063
+ script.options.matches.forEach((matchPattern) => {
1064
+ hostPermissions.add(matchPattern);
1065
+ });
1066
+ });
1067
+ manifest[permissionsKey] = Array.from(hostPermissions).sort();
1068
+ } else {
1069
+ const hashToEntrypointsMap = contentScripts.reduce((map, script) => {
1070
+ const hash = JSON.stringify(script.options);
1071
+ if (!map.has(hash)) {
1072
+ map.set(hash, [script]);
1073
+ } else {
1074
+ map.get(hash)?.push(script);
1075
+ }
1076
+ return map;
1077
+ }, /* @__PURE__ */ new Map());
1078
+ manifest.content_scripts = Array.from(hashToEntrypointsMap.entries()).map(
1079
+ ([, scripts]) => ({
1080
+ ...scripts[0].options,
1081
+ // TOOD: Sorting css and js arrays here so we get consistent test results... but we
1082
+ // shouldn't have to. Where is the inconsistency coming from?
1083
+ css: getContentScriptCssFiles(scripts, buildOutput)?.sort(),
1084
+ js: scripts.map(
1085
+ (entry) => getEntrypointBundlePath(entry, config.outDir, ".js")
1086
+ ).sort()
1087
+ })
1088
+ );
1089
+ }
1090
+ }
1091
+ }
1092
+ function addDevModeCsp(manifest, config) {
1093
+ const permission = `http://${config.server?.hostname ?? ""}/*`;
1094
+ const allowedCsp = config.server?.origin ?? "http://localhost:*";
1095
+ if (manifest.manifest_version === 3) {
1096
+ manifest.host_permissions ??= [];
1097
+ if (!manifest.host_permissions.includes(permission))
1098
+ manifest.host_permissions.push(permission);
1099
+ } else {
1100
+ manifest.permissions ??= [];
1101
+ if (!manifest.permissions.includes(permission))
1102
+ manifest.permissions.push(permission);
1103
+ }
1104
+ const csp = new ContentSecurityPolicy(
1105
+ manifest.manifest_version === 3 ? (
1106
+ // @ts-expect-error: extension_pages is not typed
1107
+ manifest.content_security_policy?.extension_pages ?? "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
1108
+ ) : manifest.content_security_policy ?? "script-src 'self'; object-src 'self';"
1109
+ // default CSP for MV2
1110
+ );
1111
+ if (config.server)
1112
+ csp.add("script-src", allowedCsp);
1113
+ if (manifest.manifest_version === 3) {
1114
+ manifest.content_security_policy ??= {};
1115
+ manifest.content_security_policy.extension_pages = csp.toString();
1116
+ } else {
1117
+ manifest.content_security_policy = csp.toString();
1118
+ }
1119
+ }
1120
+ function getContentScriptCssFiles(contentScripts, buildOutput) {
1121
+ const css = [];
1122
+ const allChunks = buildOutput.steps.flatMap((step) => step.chunks);
1123
+ contentScripts.forEach((script) => {
1124
+ const relatedCss = allChunks.find(
1125
+ (chunk) => chunk.fileName === `assets/${script.name}.css`
1126
+ );
1127
+ if (relatedCss)
1128
+ css.push(relatedCss.fileName);
1129
+ });
1130
+ if (css.length > 0)
1131
+ return css;
1132
+ return void 0;
1133
+ }
1134
+
1135
+ // src/core/log/printBuildSummary.ts
1136
+ var import_path9 = __toESM(require("path"), 1);
1137
+
1138
+ // src/core/log/printTable.ts
1139
+ function printTable(log, rows, gap = 2) {
1140
+ if (rows.length === 0)
1141
+ return;
1142
+ const columnWidths = rows.reduce(
1143
+ (widths, row) => {
1144
+ for (let i = 0; i < Math.max(widths.length, row.length); i++) {
1145
+ widths[i] = Math.max(row[i]?.length ?? 0, widths[i] ?? 0);
1146
+ }
1147
+ return widths;
1148
+ },
1149
+ rows[0].map((column) => column.length)
1150
+ );
1151
+ let str = "";
1152
+ rows.forEach((row, i) => {
1153
+ row.forEach((col, j) => {
1154
+ str += col.padEnd(columnWidths[j], " ");
1155
+ if (j !== row.length - 1)
1156
+ str += "".padEnd(gap, " ");
1157
+ });
1158
+ if (i !== rows.length - 1)
1159
+ str += "\n";
1160
+ });
1161
+ log(str);
1162
+ }
1163
+
1164
+ // src/core/log/printBuildSummary.ts
1165
+ var import_picocolors = __toESM(require("picocolors"), 1);
1166
+ var import_fs_extra8 = __toESM(require("fs-extra"), 1);
1167
+ var import_filesize = require("filesize");
1168
+ async function printBuildSummary(output, config) {
1169
+ const chunks = [
1170
+ ...output.steps.flatMap((step) => step.chunks),
1171
+ ...output.publicAssets
1172
+ ].sort((l, r) => {
1173
+ const lWeight = CHUNK_SORT_WEIGHTS[l.fileName] ?? CHUNK_SORT_WEIGHTS[(0, import_path9.extname)(l.fileName)] ?? DEFAULT_SORT_WEIGHT;
1174
+ const rWeight = CHUNK_SORT_WEIGHTS[r.fileName] ?? CHUNK_SORT_WEIGHTS[(0, import_path9.extname)(r.fileName)] ?? DEFAULT_SORT_WEIGHT;
1175
+ const diff = lWeight - rWeight;
1176
+ if (diff !== 0)
1177
+ return diff;
1178
+ return l.fileName.localeCompare(r.fileName);
1179
+ });
1180
+ let totalSize = 0;
1181
+ const chunkRows = await Promise.all(
1182
+ chunks.map(async (chunk, i) => {
1183
+ const file = [
1184
+ (0, import_path9.relative)(process.cwd(), config.outDir) + import_path9.default.sep,
1185
+ chunk.fileName
1186
+ ];
1187
+ const ext = (0, import_path9.extname)(chunk.fileName);
1188
+ const prefix = i === chunks.length - 1 ? " \u2514\u2500" : " \u251C\u2500";
1189
+ const color = CHUNK_COLORS[ext] ?? DEFAULT_COLOR;
1190
+ const stats = await import_fs_extra8.default.lstat((0, import_path9.resolve)(config.outDir, chunk.fileName));
1191
+ totalSize += stats.size;
1192
+ const size = String((0, import_filesize.filesize)(stats.size));
1193
+ return [
1194
+ `${import_picocolors.default.gray(prefix)} ${import_picocolors.default.dim(file[0])}${color(file[1])}`,
1195
+ import_picocolors.default.dim(size)
1196
+ ];
1197
+ })
1198
+ );
1199
+ printTable(config.logger.log, chunkRows);
1200
+ config.logger.log(
1201
+ `${import_picocolors.default.cyan("\u03A3 Total size:")} ${String((0, import_filesize.filesize)(totalSize))}`
1202
+ );
1203
+ }
1204
+ var DEFAULT_SORT_WEIGHT = 100;
1205
+ var CHUNK_SORT_WEIGHTS = {
1206
+ "manifest.json": 0,
1207
+ ".html": 1,
1208
+ ".js": 2,
1209
+ ".css": 3
1210
+ };
1211
+ var DEFAULT_COLOR = import_picocolors.default.blue;
1212
+ var CHUNK_COLORS = {
1213
+ ".html": import_picocolors.default.green,
1214
+ ".css": import_picocolors.default.magenta,
1215
+ ".js": import_picocolors.default.cyan
1216
+ };
1217
+
1218
+ // src/index.ts
1219
+ var import_fs_extra10 = __toESM(require("fs-extra"), 1);
1220
+
1221
+ // src/core/build/generateTypesDir.ts
1222
+ var import_unimport3 = require("unimport");
1223
+ var import_fs_extra9 = __toESM(require("fs-extra"), 1);
1224
+ var import_path10 = require("path");
1225
+ async function generateTypesDir(entrypoints, config) {
1226
+ await import_fs_extra9.default.ensureDir(config.typesDir);
1227
+ const references = [];
1228
+ references.push(await writeImportsDeclarationFile(config));
1229
+ references.push(await writePathsDeclarationFile(entrypoints, config));
1230
+ references.push(await writeGlobalsDeclarationFile(config));
1231
+ const mainReference = await writeMainDeclarationFile(references, config);
1232
+ await writeTsConfigFile(mainReference, config);
1233
+ }
1234
+ async function writeImportsDeclarationFile(config) {
1235
+ const filePath = (0, import_path10.resolve)(config.typesDir, "imports.d.ts");
1236
+ const unimport2 = (0, import_unimport3.createUnimport)(getUnimportOptions(config));
1237
+ await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
1238
+ await import_fs_extra9.default.writeFile(
1239
+ filePath,
1240
+ ["// Generated by wxt", await unimport2.generateTypeDeclarations()].join(
1241
+ "\n"
1242
+ ) + "\n"
1243
+ );
1244
+ return filePath;
1245
+ }
1246
+ async function writePathsDeclarationFile(entrypoints, config) {
1247
+ const filePath = (0, import_path10.resolve)(config.typesDir, "paths.d.ts");
1248
+ await import_fs_extra9.default.writeFile(
1249
+ filePath,
1250
+ [
1251
+ "// Generated by wxt",
1252
+ "type EntrypointPath =",
1253
+ ...entrypoints.map((entry) => {
1254
+ const path5 = getEntrypointBundlePath(
1255
+ entry,
1256
+ config.outDir,
1257
+ entry.inputPath.endsWith(".html") ? ".html" : ".js"
1258
+ );
1259
+ return ` | "/${path5}"`;
1260
+ }).sort()
1261
+ ].join("\n") + "\n"
1262
+ );
1263
+ return filePath;
1264
+ }
1265
+ async function writeGlobalsDeclarationFile(config) {
1266
+ const filePath = (0, import_path10.resolve)(config.typesDir, "globals.d.ts");
1267
+ const globals = getGlobals(config);
1268
+ await import_fs_extra9.default.writeFile(
1269
+ filePath,
1270
+ [
1271
+ "// Generated by wxt",
1272
+ "export {}",
1273
+ "declare global {",
1274
+ ...globals.map((global) => ` const ${global.name}: ${global.type};`),
1275
+ "}"
1276
+ ].join("\n") + "\n",
1277
+ "utf-8"
1278
+ );
1279
+ return filePath;
1280
+ }
1281
+ async function writeMainDeclarationFile(references, config) {
1282
+ const dir = config.wxtDir;
1283
+ const filePath = (0, import_path10.resolve)(dir, "wxt.d.ts");
1284
+ await import_fs_extra9.default.writeFile(
1285
+ filePath,
1286
+ [
1287
+ "// Generated by wxt",
1288
+ ...references.map(
1289
+ (ref) => `/// <reference types="./${(0, import_path10.relative)(dir, ref)}" />`
1290
+ )
1291
+ ].join("\n") + "\n"
1292
+ );
1293
+ return filePath;
1294
+ }
1295
+ async function writeTsConfigFile(mainReference, config) {
1296
+ const dir = config.wxtDir;
1297
+ await import_fs_extra9.default.writeFile(
1298
+ (0, import_path10.resolve)(dir, "tsconfig.json"),
1299
+ `{
1300
+ "compilerOptions": {
1301
+ "target": "ESNext",
1302
+ "module": "ESNext",
1303
+ "moduleResolution": "Bundler",
1304
+ "noEmit": true,
1305
+ "esModuleInterop": true,
1306
+ "forceConsistentCasingInFileNames": true,
1307
+ "resolveJsonModule": true,
1308
+
1309
+ /* Type Checking */
1310
+ "strict": true,
1311
+
1312
+ /* Completeness */
1313
+ "skipLibCheck": true
1314
+ },
1315
+ "include": [
1316
+ "${(0, import_path10.relative)(dir, config.root)}/**/*",
1317
+ "./${(0, import_path10.relative)(dir, mainReference)}"
1318
+ ],
1319
+ "exclude": ["${(0, import_path10.relative)(dir, config.outBaseDir)}"]
1320
+ }`
1321
+ );
1322
+ }
1323
+
1324
+ // src/index.ts
1325
+ var import_picocolors2 = __toESM(require("picocolors"), 1);
1326
+ var vite4 = __toESM(require("vite"), 1);
1327
+
1328
+ // src/core/utils/findOpenPort.ts
1329
+ var import_node_net = __toESM(require("net"), 1);
1330
+ function findOpenPort(startPort, endPort) {
1331
+ return findOpenPortRecursive(startPort, startPort, endPort);
1332
+ }
1333
+ function findOpenPortRecursive(port, startPort, endPort) {
1334
+ return new Promise((resolve13, reject) => {
1335
+ if (port > endPort)
1336
+ return reject(
1337
+ Error(`Could not find open port between ${startPort}-${endPort}`)
1338
+ );
1339
+ const server = import_node_net.default.createServer();
1340
+ server.listen(port, () => {
1341
+ server.once("close", () => resolve13(port));
1342
+ server.close();
1343
+ });
1344
+ server.on(
1345
+ "error",
1346
+ () => resolve13(findOpenPortRecursive(port + 1, startPort, endPort))
1347
+ );
1348
+ });
1349
+ }
1350
+
1351
+ // src/core/utils/formatDuration.ts
1352
+ function formatDuration(duration) {
1353
+ if (duration < 1e3)
1354
+ return `${duration} ms`;
1355
+ if (duration < 1e4)
1356
+ return `${(duration / 1e3).toFixed(3)} s`;
1357
+ if (duration < 6e4)
1358
+ return `${(duration / 1e3).toFixed(1)} s`;
1359
+ return `${(duration / 1e3).toFixed(0)} s`;
1360
+ }
1361
+
1362
+ // src/core/runners/createWebExtRunner.ts
1363
+ function createWebExtRunner() {
1364
+ let runner;
1365
+ return {
1366
+ async openBrowser(config) {
1367
+ if (config.browser === "safari") {
1368
+ config.logger.warn("Cannot open safari automatically.");
1369
+ return;
1370
+ }
1371
+ const webExtLogger = await import("web-ext/util/logger");
1372
+ webExtLogger.consoleStream.write = ({ level, msg, name }) => {
1373
+ if (level >= ERROR_LOG_LEVEL)
1374
+ config.logger.error(name, msg);
1375
+ if (level >= WARN_LOG_LEVEL)
1376
+ config.logger.warn(msg);
1377
+ };
1378
+ const wxtUserConfig = config.runnerConfig.config;
1379
+ const userConfig = {
1380
+ console: wxtUserConfig?.openConsole,
1381
+ devtools: wxtUserConfig?.openDevtools,
1382
+ startUrl: wxtUserConfig?.startUrls,
1383
+ ...config.browser === "firefox" ? {
1384
+ firefox: wxtUserConfig?.binaries?.firefox,
1385
+ firefoxProfile: wxtUserConfig?.firefoxProfile,
1386
+ prefs: wxtUserConfig?.firefoxPrefs,
1387
+ args: wxtUserConfig?.firefoxArgs
1388
+ } : {
1389
+ chromiumBinary: wxtUserConfig?.binaries?.[config.browser],
1390
+ chromiumProfile: wxtUserConfig?.chromiumProfile,
1391
+ args: wxtUserConfig?.chromiumArgs
1392
+ }
1393
+ };
1394
+ const finalConfig = {
1395
+ ...userConfig,
1396
+ target: config.browser === "firefox" ? "firefox-desktop" : "chromium",
1397
+ sourceDir: config.outDir,
1398
+ // WXT handles reloads, so disable auto-reload behaviors in web-ext
1399
+ noReload: true,
1400
+ noInput: true
1401
+ };
1402
+ const options = {
1403
+ // Don't call `process.exit(0)` after starting web-ext
1404
+ shouldExitProgram: false
1405
+ };
1406
+ config.logger.debug("web-ext config:", finalConfig);
1407
+ config.logger.debug("web-ext options:", options);
1408
+ const webExt = await import("web-ext");
1409
+ runner = await webExt.default.cmd.run(finalConfig, options);
1410
+ },
1411
+ async closeBrowser() {
1412
+ return await runner?.exit();
1413
+ }
1414
+ };
1415
+ }
1416
+ var WARN_LOG_LEVEL = 40;
1417
+ var ERROR_LOG_LEVEL = 50;
1418
+
1419
+ // src/core/utils/groupEntrypoints.ts
1420
+ function groupEntrypoints(entrypoints) {
1421
+ const groupIndexMap = {};
1422
+ const groups = [];
1423
+ for (const entry of entrypoints) {
1424
+ const group = ENTRY_TYPE_TO_GROUP_MAP[entry.type];
1425
+ if (group === "no-group") {
1426
+ groups.push(entry);
1427
+ } else {
1428
+ let groupIndex = groupIndexMap[group];
1429
+ if (groupIndex == null) {
1430
+ groupIndex = groups.push([]) - 1;
1431
+ groupIndexMap[group] = groupIndex;
1432
+ }
1433
+ groups[groupIndex].push(entry);
1434
+ }
1435
+ }
1436
+ return groups;
1437
+ }
1438
+ var ENTRY_TYPE_TO_GROUP_MAP = {
1439
+ sandbox: "sandbox-page",
1440
+ popup: "extension-page",
1441
+ newtab: "extension-page",
1442
+ history: "extension-page",
1443
+ options: "extension-page",
1444
+ devtools: "extension-page",
1445
+ bookmarks: "extension-page",
1446
+ sidepanel: "extension-page",
1447
+ "unlisted-page": "extension-page",
1448
+ background: "no-group",
1449
+ "content-script": "no-group",
1450
+ "unlisted-script": "no-group"
1451
+ };
1452
+
1453
+ // src/core/utils/detectDevChanges.ts
1454
+ function detectDevChanges(changedFiles, currentOutput) {
1455
+ if (currentOutput == null)
1456
+ return { type: "no-change" };
1457
+ const changedSteps = new Set(
1458
+ changedFiles.flatMap(
1459
+ (changedFile) => findEffectedSteps(changedFile, currentOutput)
1460
+ )
1461
+ );
1462
+ if (changedSteps.size === 0)
1463
+ return { type: "no-change" };
1464
+ const unchangedOutput = {
1465
+ manifest: currentOutput.manifest,
1466
+ steps: [],
1467
+ publicAssets: []
1468
+ };
1469
+ const changedOutput = {
1470
+ manifest: currentOutput.manifest,
1471
+ steps: [],
1472
+ publicAssets: []
1473
+ };
1474
+ for (const step of currentOutput.steps) {
1475
+ if (changedSteps.has(step)) {
1476
+ changedOutput.steps.push(step);
1477
+ } else {
1478
+ unchangedOutput.steps.push(step);
1479
+ }
1480
+ }
1481
+ for (const asset of currentOutput.publicAssets) {
1482
+ if (changedSteps.has(asset)) {
1483
+ changedOutput.publicAssets.push(asset);
1484
+ } else {
1485
+ unchangedOutput.publicAssets.push(asset);
1486
+ }
1487
+ }
1488
+ const isOnlyHtmlChanges = !changedFiles.find(
1489
+ ([_, file]) => !file.endsWith(".html")
1490
+ );
1491
+ if (isOnlyHtmlChanges) {
1492
+ return {
1493
+ type: "html-reload",
1494
+ cachedOutput: unchangedOutput,
1495
+ rebuildGroups: changedOutput.steps.map((step) => step.entrypoints)
1496
+ };
1497
+ }
1498
+ return {
1499
+ type: "extension-reload",
1500
+ cachedOutput: unchangedOutput,
1501
+ rebuildGroups: changedOutput.steps.map((step) => step.entrypoints)
1502
+ };
1503
+ }
1504
+ function findEffectedSteps(changedFile, currentOutput) {
1505
+ const changes = [];
1506
+ const changedPath = changedFile[1];
1507
+ const isChunkEffected = (chunk) => (
1508
+ // If it's an HTML file with the same path, is is effected because HTML files need to be pre-rendered
1509
+ // TODO: use bundle path to support `<name>/index.html`?
1510
+ chunk.type === "asset" && changedPath.endsWith(chunk.fileName) || // If it's a chunk that depends on the changed file, it is effected
1511
+ chunk.type === "chunk" && chunk.moduleIds.includes(changedPath)
1512
+ );
1513
+ for (const step of currentOutput.steps) {
1514
+ const effectedChunk = step.chunks.find((chunk) => isChunkEffected(chunk));
1515
+ if (effectedChunk)
1516
+ changes.push(step);
1517
+ }
1518
+ const effectedAsset = currentOutput.publicAssets.find(
1519
+ (chunk) => isChunkEffected(chunk)
1520
+ );
1521
+ if (effectedAsset)
1522
+ changes.push(effectedAsset);
1523
+ return changes;
1524
+ }
1525
+
1526
+ // src/index.ts
1527
+ var import_async_mutex = require("async-mutex");
1528
+ var import_consola3 = require("consola");
1529
+ var import_node_path4 = require("path");
1530
+ async function build2(config) {
1531
+ const internalConfig = await getInternalConfig(config, "build");
1532
+ return await buildInternal(internalConfig);
1533
+ }
1534
+ async function createServer2(config) {
1535
+ const port = await findOpenPort(3e3, 3010);
1536
+ const hostname = "localhost";
1537
+ const origin = `http://${hostname}:${port}`;
1538
+ const serverConfig = {
1539
+ server: {
1540
+ origin
1541
+ }
1542
+ };
1543
+ let internalConfig = await getInternalConfig(
1544
+ vite4.mergeConfig(serverConfig, config ?? {}),
1545
+ "serve"
1546
+ );
1547
+ const runner = createWebExtRunner();
1548
+ let hasBuiltOnce = false;
1549
+ let currentOutput;
1550
+ const fileChangedMutex = new import_async_mutex.Mutex();
1551
+ const changeQueue = [];
1552
+ const viteServer = await vite4.createServer(internalConfig.vite);
1553
+ viteServer.watcher.on("all", async (event, path5, stats) => {
1554
+ if (!hasBuiltOnce || path5.startsWith(internalConfig.outBaseDir))
1555
+ return;
1556
+ changeQueue.push([event, path5]);
1557
+ await fileChangedMutex.runExclusive(async () => {
1558
+ const fileChanges = changeQueue.splice(0, changeQueue.length);
1559
+ const changes = detectDevChanges(fileChanges, currentOutput);
1560
+ if (changes.type === "no-change")
1561
+ return;
1562
+ import_consola3.consola.info(
1563
+ `Changed: ${Array.from(new Set(fileChanges.map((change) => change[1]))).map((file) => import_picocolors2.default.dim((0, import_node_path4.relative)(internalConfig.root, file))).join(", ")}`
1564
+ );
1565
+ const rebuiltNames = changes.rebuildGroups.flat().map((entry) => {
1566
+ return import_picocolors2.default.cyan(
1567
+ (0, import_node_path4.relative)(internalConfig.outDir, getEntrypointOutputFile(entry, ""))
1568
+ );
1569
+ }).join(import_picocolors2.default.dim(", "));
1570
+ internalConfig = await getInternalConfig(
1571
+ vite4.mergeConfig(serverConfig, config ?? {}),
1572
+ "serve"
1573
+ );
1574
+ internalConfig.server = server;
1575
+ const { output: newOutput } = await rebuild(
1576
+ internalConfig,
1577
+ // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
1578
+ changes.rebuildGroups,
1579
+ changes.cachedOutput
1580
+ );
1581
+ currentOutput = newOutput;
1582
+ switch (changes.type) {
1583
+ case "extension-reload":
1584
+ server.reloadExtension();
1585
+ import_consola3.consola.success(`Reloaded extension: ${rebuiltNames}`);
1586
+ break;
1587
+ case "html-reload":
1588
+ changes.rebuildGroups.flat().forEach((entry) => {
1589
+ const path6 = getEntrypointBundlePath(
1590
+ entry,
1591
+ internalConfig.outDir,
1592
+ ".html"
1593
+ );
1594
+ server.reloadPage(path6);
1595
+ });
1596
+ import_consola3.consola.success(`Reloaded pages: ${rebuiltNames}`);
1597
+ break;
1598
+ }
1599
+ });
1600
+ });
1601
+ const server = {
1602
+ ...viteServer,
1603
+ async listen(port2, isRestart) {
1604
+ const res = await viteServer.listen(port2, isRestart);
1605
+ if (!isRestart) {
1606
+ internalConfig.logger.success(`Started dev server @ ${origin}`);
1607
+ internalConfig.logger.info("Opening browser...");
1608
+ await runner.openBrowser(internalConfig);
1609
+ internalConfig.logger.success("Opened!");
1610
+ }
1611
+ return res;
1612
+ },
1613
+ port,
1614
+ hostname,
1615
+ origin,
1616
+ reloadExtension: () => {
1617
+ server.ws.send("wxt:reload-extension");
1618
+ },
1619
+ reloadPage: (path5) => {
1620
+ server.ws.send("wxt:reload-page", path5);
1621
+ }
1622
+ };
1623
+ internalConfig.logger.info("Created dev server");
1624
+ internalConfig.server = server;
1625
+ currentOutput = await buildInternal(internalConfig);
1626
+ hasBuiltOnce = true;
1627
+ return server;
1628
+ }
1629
+ async function buildInternal(config) {
1630
+ const verb = config.command === "serve" ? "Pre-rendering" : "Building";
1631
+ const target = `${config.browser}-mv${config.manifestVersion}`;
1632
+ config.logger.info(
1633
+ `${verb} ${import_picocolors2.default.cyan(target)} for ${import_picocolors2.default.cyan(config.mode)} with ${import_picocolors2.default.green(
1634
+ `Vite ${vite4.version}`
1635
+ )}`
1636
+ );
1637
+ const startTime = Date.now();
1638
+ await import_fs_extra10.default.rm(config.outDir, { recursive: true, force: true });
1639
+ await import_fs_extra10.default.ensureDir(config.outDir);
1640
+ const entrypoints = await findEntrypoints(config);
1641
+ const groups = groupEntrypoints(entrypoints);
1642
+ const { output } = await rebuild(config, groups);
1643
+ config.logger.success(
1644
+ `Built extension in ${formatDuration(Date.now() - startTime)}`
1645
+ );
1646
+ await printBuildSummary(output, config);
1647
+ return output;
1648
+ }
1649
+ async function rebuild(config, entrypointGroups, existingOutput = {
1650
+ steps: [],
1651
+ publicAssets: []
1652
+ }) {
1653
+ const allEntrypoints = await findEntrypoints(config);
1654
+ await generateTypesDir(allEntrypoints, config);
1655
+ const buildOutput = await buildEntrypoints(entrypointGroups, config);
1656
+ const manifest = await generateMainfest(allEntrypoints, buildOutput, config);
1657
+ const output = {
1658
+ manifest,
1659
+ ...buildOutput
1660
+ };
1661
+ await writeManifest(manifest, output, config);
1662
+ return {
1663
+ output: {
1664
+ manifest,
1665
+ steps: [...existingOutput.steps, ...output.steps],
1666
+ publicAssets: [...existingOutput.publicAssets, ...output.publicAssets]
1667
+ },
1668
+ manifest
1669
+ };
1670
+ }
1671
+
1672
+ // src/cli/utils/defineCommand.ts
1673
+ var import_consola5 = require("consola");
1674
+
1675
+ // src/core/log/printHeader.ts
1676
+ var import_picocolors3 = __toESM(require("picocolors"), 1);
1677
+ var import_consola4 = require("consola");
1678
+ function printHeader() {
1679
+ console.log();
1680
+ import_consola4.consola.log(`${import_picocolors3.default.gray("WXT")} ${import_picocolors3.default.gray(import_picocolors3.default.bold(version))}`);
1681
+ }
1682
+
1683
+ // src/cli/utils/defineCommand.ts
1684
+ function defineCommand(cb) {
1685
+ return async (...args) => {
1686
+ const startTime = Date.now();
1687
+ try {
1688
+ printHeader();
1689
+ const ongoing = await cb(...args);
1690
+ if (!ongoing)
1691
+ import_consola5.consola.success(
1692
+ `Finished in ${formatDuration(Date.now() - startTime)}`
1693
+ );
1694
+ } catch (err) {
1695
+ import_consola5.consola.fail(
1696
+ `Command failed after ${formatDuration(Date.now() - startTime)}`
1697
+ );
1698
+ import_consola5.consola.error(err);
1699
+ process.exit(1);
1700
+ }
1701
+ };
1702
+ }
1703
+
1704
+ // src/cli/commands/build.ts
1705
+ var build3 = defineCommand(async (root, flags) => {
1706
+ const mode = flags.mode ?? "production";
1707
+ const cliConfig = {
1708
+ root,
1709
+ mode,
1710
+ browser: flags.browser,
1711
+ manifestVersion: flags.mv3 ? 3 : flags.mv2 ? 2 : void 0,
1712
+ configFile: flags.config
1713
+ };
1714
+ await build2(cliConfig);
1715
+ });
1716
+
1717
+ // src/cli/commands/dev.ts
1718
+ var dev = defineCommand(async (root, flags) => {
1719
+ const mode = flags.mode ?? "development";
1720
+ const cliConfig = {
1721
+ root,
1722
+ mode,
1723
+ browser: flags.browser,
1724
+ manifestVersion: flags.mv3 ? 3 : flags.mv2 ? 2 : void 0,
1725
+ configFile: flags.config
1726
+ };
1727
+ const server = await createServer2(cliConfig);
1728
+ await server.listen(server.port);
1729
+ return true;
1730
+ });
1731
+
1732
+ // src/cli/commands/init.ts
1733
+ var import_consola6 = require("consola");
1734
+ var init = defineCommand(async (directory) => {
1735
+ import_consola6.consola.warn("wxt init: Not implemented");
1736
+ });
1737
+
1738
+ // src/cli/commands/prepare.ts
1739
+ var prepare = defineCommand(async (root, flags) => {
1740
+ const cliConfig = {
1741
+ root,
1742
+ configFile: flags.config
1743
+ };
1744
+ const config = await getInternalConfig(cliConfig, "build");
1745
+ config.logger.info("Generating types...");
1746
+ const entrypoints = await findEntrypoints(config);
1747
+ await generateTypesDir(entrypoints, config);
1748
+ });
1749
+
1750
+ // src/cli/commands/publish.ts
1751
+ var import_consola7 = require("consola");
1752
+ var publish = defineCommand(
1753
+ async (root, { config: configFile }) => {
1754
+ import_consola7.consola.warn("wxt publish: Not implemented");
1755
+ }
1756
+ );
1757
+
1758
+ // src/cli/index.ts
1759
+ var cli = (0, import_cac.default)("wxt");
1760
+ cli.help();
1761
+ cli.version(version);
1762
+ cli.command("[root]", "start dev server").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").action(dev);
1763
+ cli.command("build [root]", "build for production").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").action(build3);
1764
+ cli.command("prepare [root]", "prepare").option("-c, --config <file>", "use specified config file").action(prepare);
1765
+ cli.command("publish [root]", "publish to stores").action(publish);
1766
+ cli.command("init [directory]", "initialize a new project").action(init);
1767
+ cli.parse();
1768
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NsaS9pbmRleC50cyIsICIuLi9wYWNrYWdlLmpzb24iLCAiLi4vc3JjL2NvcmUvdXRpbHMvZ2V0SW50ZXJuYWxDb25maWcudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvaW1wb3J0VHNGaWxlLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy9kZXZIdG1sUHJlcmVuZGVyLnRzIiwgIi4uL3NyYy9jb3JlL3V0aWxzL2VudHJ5cG9pbnRzLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy9kZXZTZXJ2ZXJHbG9iYWxzLnRzIiwgIi4uL3NyYy9jb3JlL3V0aWxzL25ldHdvcmsudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvcHJvbWlzZXMudHMiLCAiLi4vc3JjL2NvcmUvdml0ZS1wbHVnaW5zL2Rvd25sb2FkLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy9tdWx0aXBhZ2VNb3ZlLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy91bmltcG9ydC50cyIsICIuLi9zcmMvY29yZS91dGlscy9hdXRvLWltcG9ydHMudHMiLCAiLi4vc3JjL2NvcmUvdml0ZS1wbHVnaW5zL3ZpcnR1YWxFbnRyeXBvaW50LnRzIiwgIi4uL3NyYy9jb3JlL3V0aWxzL2NyZWF0ZUZzQ2FjaGUudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvZ2xvYmFscy50cyIsICIuLi9zcmMvY29yZS9idWlsZC9maW5kRW50cnlwb2ludHMudHMiLCAiLi4vc3JjL2NvcmUvYnVpbGQvYnVpbGRFbnRyeXBvaW50cy50cyIsICIuLi9zcmMvY29yZS91dGlscy9yZW1vdmVFbXB0eURpcnMudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvbWFuaWZlc3QudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvQ29udGVudFNlY3VyaXR5UG9saWN5LnRzIiwgIi4uL3NyYy9jb3JlL2xvZy9wcmludEJ1aWxkU3VtbWFyeS50cyIsICIuLi9zcmMvY29yZS9sb2cvcHJpbnRUYWJsZS50cyIsICIuLi9zcmMvaW5kZXgudHMiLCAiLi4vc3JjL2NvcmUvYnVpbGQvZ2VuZXJhdGVUeXBlc0Rpci50cyIsICIuLi9zcmMvY29yZS91dGlscy9maW5kT3BlblBvcnQudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvZm9ybWF0RHVyYXRpb24udHMiLCAiLi4vc3JjL2NvcmUvcnVubmVycy9jcmVhdGVXZWJFeHRSdW5uZXIudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvZ3JvdXBFbnRyeXBvaW50cy50cyIsICIuLi9zcmMvY29yZS91dGlscy9kZXRlY3REZXZDaGFuZ2VzLnRzIiwgIi4uL3NyYy9jbGkvdXRpbHMvZGVmaW5lQ29tbWFuZC50cyIsICIuLi9zcmMvY29yZS9sb2cvcHJpbnRIZWFkZXIudHMiLCAiLi4vc3JjL2NsaS9jb21tYW5kcy9idWlsZC50cyIsICIuLi9zcmMvY2xpL2NvbW1hbmRzL2Rldi50cyIsICIuLi9zcmMvY2xpL2NvbW1hbmRzL2luaXQudHMiLCAiLi4vc3JjL2NsaS9jb21tYW5kcy9wcmVwYXJlLnRzIiwgIi4uL3NyYy9jbGkvY29tbWFuZHMvcHVibGlzaC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQgY2FjIGZyb20gJ2NhYyc7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi4vLi4vcGFja2FnZS5qc29uJztcbmltcG9ydCAqIGFzIGNvbW1hbmRzIGZyb20gJy4vY29tbWFuZHMnO1xuXG5jb25zdCBjbGkgPSBjYWMoJ3d4dCcpO1xuY2xpLmhlbHAoKTtcbmNsaS52ZXJzaW9uKHZlcnNpb24pO1xuXG4vLyBERVZcbmNsaVxuICAuY29tbWFuZCgnW3Jvb3RdJywgJ3N0YXJ0IGRldiBzZXJ2ZXInKVxuICAub3B0aW9uKCctYywgLS1jb25maWcgPGZpbGU+JywgJ3VzZSBzcGVjaWZpZWQgY29uZmlnIGZpbGUnKVxuICAub3B0aW9uKCctbSwgLS1tb2RlIDxtb2RlPicsICdzZXQgZW52IG1vZGUnKVxuICAub3B0aW9uKCctYiwgLS1icm93c2VyIDxicm93c2VyPicsICdzcGVjaWZ5IGEgYnJvd3NlcicpXG4gIC5vcHRpb24oJy0tbXYzJywgJ3RhcmdldCBtYW5pZmVzdCB2MycpXG4gIC5vcHRpb24oJy0tbXYyJywgJ3RhcmdldCBtYW5pZmVzdCB2MicpXG4gIC5hY3Rpb24oY29tbWFuZHMuZGV2KTtcblxuLy8gQlVJTERcbmNsaVxuICAuY29tbWFuZCgnYnVpbGQgW3Jvb3RdJywgJ2J1aWxkIGZvciBwcm9kdWN0aW9uJylcbiAgLm9wdGlvbignLWMsIC0tY29uZmlnIDxmaWxlPicsICd1c2Ugc3BlY2lmaWVkIGNvbmZpZyBmaWxlJylcbiAgLm9wdGlvbignLW0sIC0tbW9kZSA8bW9kZT4nLCAnc2V0IGVudiBtb2RlJylcbiAgLm9wdGlvbignLWIsIC0tYnJvd3NlciA8YnJvd3Nlcj4nLCAnc3BlY2lmeSBhIGJyb3dzZXInKVxuICAub3B0aW9uKCctLW12MycsICd0YXJnZXQgbWFuaWZlc3QgdjMnKVxuICAub3B0aW9uKCctLW12MicsICd0YXJnZXQgbWFuaWZlc3QgdjInKVxuICAuYWN0aW9uKGNvbW1hbmRzLmJ1aWxkKTtcblxuLy8gUFJFUEFSRVxuY2xpXG4gIC5jb21tYW5kKCdwcmVwYXJlIFtyb290XScsICdwcmVwYXJlJylcbiAgLm9wdGlvbignLWMsIC0tY29uZmlnIDxmaWxlPicsICd1c2Ugc3BlY2lmaWVkIGNvbmZpZyBmaWxlJylcbiAgLmFjdGlvbihjb21tYW5kcy5wcmVwYXJlKTtcblxuLy8gUFVCTElTSFxuY2xpLmNvbW1hbmQoJ3B1Ymxpc2ggW3Jvb3RdJywgJ3B1Ymxpc2ggdG8gc3RvcmVzJykuYWN0aW9uKGNvbW1hbmRzLnB1Ymxpc2gpO1xuXG4vLyBJTklUXG5jbGlcbiAgLmNvbW1hbmQoJ2luaXQgW2RpcmVjdG9yeV0nLCAnaW5pdGlhbGl6ZSBhIG5ldyBwcm9qZWN0JylcbiAgLmFjdGlvbihjb21tYW5kcy5pbml0KTtcblxuY2xpLnBhcnNlKCk7XG4iLCAie1xuICBcIm5hbWVcIjogXCJ3eHRcIixcbiAgXCJ0eXBlXCI6IFwibW9kdWxlXCIsXG4gIFwidmVyc2lvblwiOiBcIjAuMC4yXCIsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJOZXh0IGdlbiBmcmFtZXdvcmsgZm9yIGRldmVsb3Bpbmcgd2ViIGV4dGVuc2lvbnNcIixcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9ha2xpbmtlcjEvd3h0XCJcbiAgfSxcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJ2aXRlXCIsXG4gICAgXCJjaHJvbWVcIixcbiAgICBcIndlYlwiLFxuICAgIFwiZXh0ZW5zaW9uXCIsXG4gICAgXCJicm93c2VyXCIsXG4gICAgXCJidW5kbGVyXCIsXG4gICAgXCJmcmFtZXdvcmtcIlxuICBdLFxuICBcImF1dGhvclwiOiB7XG4gICAgXCJuYW1lXCI6IFwiQWFyb24gS2xpbmtlclwiLFxuICAgIFwiZW1haWxcIjogXCJhYXJvbmtsaW5rZXIxK3d4dEBnbWFpbC5jb21cIlxuICB9LFxuICBcImxpY2Vuc2VcIjogXCJNSVRcIixcbiAgXCJmaWxlc1wiOiBbXG4gICAgXCJkaXN0XCJcbiAgXSxcbiAgXCJiaW5cIjogXCJkaXN0L2NsaS5janNcIixcbiAgXCJtYWluXCI6IFwiLi9kaXN0L2luZGV4LmNqc1wiLFxuICBcIm1vZHVsZVwiOiBcIi4vZGlzdC9pbmRleC5qc1wiLFxuICBcInR5cGVzXCI6IFwiLi9kaXN0L2luZGV4LmQudHNcIixcbiAgXCJleHBvcnRzXCI6IHtcbiAgICBcIi5cIjoge1xuICAgICAgXCJyZXF1aXJlXCI6IFwiLi9kaXN0L2luZGV4LmNqc1wiLFxuICAgICAgXCJpbXBvcnRcIjogXCIuL2Rpc3QvaW5kZXguanNcIixcbiAgICAgIFwidHlwZXNcIjogXCIuL2Rpc3QvaW5kZXguZC50c1wiXG4gICAgfSxcbiAgICBcIi4vY2xpZW50XCI6IHtcbiAgICAgIFwicmVxdWlyZVwiOiBcIi4vZGlzdC9jbGllbnQuY2pzXCIsXG4gICAgICBcImltcG9ydFwiOiBcIi4vZGlzdC9jbGllbnQuanNcIixcbiAgICAgIFwidHlwZXNcIjogXCIuL2Rpc3QvY2xpZW50LmQudHNcIlxuICAgIH1cbiAgfSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcInd4dFwiOiBcInRzeCBzcmMvY2xpL2luZGV4LnRzXCIsXG4gICAgXCJidWlsZFwiOiBcInRzeCBzY3JpcHRzL2J1aWxkLnRzXCIsXG4gICAgXCJmb3JtYXRcIjogXCJwcmV0dGllciAtLXdyaXRlIC5cIixcbiAgICBcImZvcm1hdDpjaGVja1wiOiBcInByZXR0aWVyIC0td3JpdGUgLlwiLFxuICAgIFwiY29tcGlsZVwiOiBcInRzYyAtLW5vRW1pdFwiLFxuICAgIFwidGVzdFwiOiBcInZpdGVzdFwiLFxuICAgIFwidGVzdDpjb3ZlcmFnZVwiOiBcInZpdGVzdCBydW4gLS1jb3ZlcmFnZVwiLFxuICAgIFwicHJlcGFyZVwiOiBcInNpbXBsZS1naXQtaG9va3NcIixcbiAgICBcInByZXB1Ymxpc2hcIjogXCJwbnBtIC1zIGJ1aWxkXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYXN5bmMtbXV0ZXhcIjogXCJeMC40LjBcIixcbiAgICBcImMxMlwiOiBcIl4xLjQuMlwiLFxuICAgIFwiY2FjXCI6IFwiXjYuNy4xNFwiLFxuICAgIFwiY29uc29sYVwiOiBcIl4zLjEuMFwiLFxuICAgIFwiZmFzdC1nbG9iXCI6IFwiXjMuMi4xMlwiLFxuICAgIFwiZmlsZXNpemVcIjogXCJeMTAuMC43XCIsXG4gICAgXCJmcy1leHRyYVwiOiBcIl4xMS4xLjFcIixcbiAgICBcImppdGlcIjogXCJeMS4xOC4yXCIsXG4gICAgXCJqc29uNVwiOiBcIl4yLjIuM1wiLFxuICAgIFwibGlua2Vkb21cIjogXCJeMC4xNC4yNlwiLFxuICAgIFwicGljb2NvbG9yc1wiOiBcIl4xLjAuMFwiLFxuICAgIFwicGljb21hdGNoXCI6IFwiXjIuMy4xXCIsXG4gICAgXCJ1bmltcG9ydFwiOiBcIl4zLjAuOFwiLFxuICAgIFwidml0ZVwiOiBcIl40LjMuOVwiLFxuICAgIFwid2ViLWV4dFwiOiBcIl43LjYuMlwiLFxuICAgIFwid2ViZXh0ZW5zaW9uLXBvbHlmaWxsXCI6IFwiXjAuMTAuMFwiXG4gIH0sXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcIkBmYWtlci1qcy9mYWtlclwiOiBcIl44LjAuMlwiLFxuICAgIFwiQHR5cGVzL2ZzLWV4dHJhXCI6IFwiXjExLjAuMVwiLFxuICAgIFwiQHR5cGVzL2xvZGFzaC5tZXJnZVwiOiBcIl40LjYuN1wiLFxuICAgIFwiQHR5cGVzL25vZGVcIjogXCJeMjAuMy4xXCIsXG4gICAgXCJAdHlwZXMvcGljb21hdGNoXCI6IFwiXjIuMy4wXCIsXG4gICAgXCJAdHlwZXMvd2ViZXh0ZW5zaW9uLXBvbHlmaWxsXCI6IFwiXjAuMTAuMFwiLFxuICAgIFwiQHZpdGVzdC9jb3ZlcmFnZS12OFwiOiBcIl4wLjMyLjJcIixcbiAgICBcImxvZGFzaC5tZXJnZVwiOiBcIl40LjYuMlwiLFxuICAgIFwibnBtLXJ1bi1hbGxcIjogXCJeNC4xLjVcIixcbiAgICBcIm9yYVwiOiBcIl42LjMuMVwiLFxuICAgIFwicHJldHRpZXJcIjogXCJeMi44LjhcIixcbiAgICBcInByZXR0eS1xdWlja1wiOiBcIl4zLjEuM1wiLFxuICAgIFwic2ltcGxlLWdpdC1ob29rc1wiOiBcIl4yLjguMVwiLFxuICAgIFwidHN1cFwiOiBcIl43LjAuMFwiLFxuICAgIFwidHN4XCI6IFwiXjMuMTIuN1wiLFxuICAgIFwidHlwZXNjcmlwdFwiOiBcIl41LjEuM1wiLFxuICAgIFwidml0ZXN0XCI6IFwiXjAuMzIuMlwiLFxuICAgIFwid2ViZXh0ZW5zaW9uLXBvbHlmaWxsXCI6IFwiXjAuMTAuMFwiXG4gIH0sXG4gIFwicGVlckRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJ3ZWJleHRlbnNpb24tcG9seWZpbGxcIjogXCI+PTAuMTAuMFwiXG4gIH0sXG4gIFwicGFja2FnZU1hbmFnZXJcIjogXCJwbnBtQDguNi4zXCIsXG4gIFwic2ltcGxlLWdpdC1ob29rc1wiOiB7XG4gICAgXCJwcmUtY29tbWl0XCI6IFwicG5wbSBwcmV0dHktcXVpY2sgLS1zdGFnZWRcIlxuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgRXh0ZW5zaW9uUnVubmVyQ29uZmlnLFxuICBJbmxpbmVDb25maWcsXG4gIEludGVybmFsQ29uZmlnLFxuICBVc2VyQ29uZmlnLFxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgcGF0aCwgeyByZXNvbHZlIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCAqIGFzIHZpdGUgZnJvbSAndml0ZSc7XG5pbXBvcnQgeyBjb25zb2xhIH0gZnJvbSAnY29uc29sYSc7XG5pbXBvcnQgeyBpbXBvcnRUc0ZpbGUgfSBmcm9tICcuL2ltcG9ydFRzRmlsZSc7XG5pbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gJy4uL3ZpdGUtcGx1Z2lucyc7XG5pbXBvcnQgeyBjcmVhdGVGc0NhY2hlIH0gZnJvbSAnLi9jcmVhdGVGc0NhY2hlJztcbmltcG9ydCB7IGdldEdsb2JhbHMgfSBmcm9tICcuL2dsb2JhbHMnO1xuaW1wb3J0IHsgbG9hZENvbmZpZyB9IGZyb20gJ2MxMic7XG5cbi8qKlxuICogR2l2ZW4gYW4gaW5saW5lIGNvbmZpZywgZGlzY292ZXIgdGhlIGNvbmZpZyBmaWxlIGlmIG5lY2Vzc2FyeSwgbWVyZ2UgdGhlIHJlc3VsdHMsIHJlc29sdmUgYW55XG4gKiByZWxhdGl2ZSBwYXRocywgYW5kIGFwcGx5IGFueSBkZWZhdWx0cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEludGVybmFsQ29uZmlnKFxuICBjb25maWc6IElubGluZUNvbmZpZyxcbiAgY29tbWFuZDogJ2J1aWxkJyB8ICdzZXJ2ZScsXG4pOiBQcm9taXNlPEludGVybmFsQ29uZmlnPiB7XG4gIC8vIEFwcGx5IGRlZmF1bHRzIHRvIGEgYmFzZSBjb25maWdcbiAgY29uc3Qgcm9vdCA9IGNvbmZpZy5yb290ID8gcGF0aC5yZXNvbHZlKGNvbmZpZy5yb290KSA6IHByb2Nlc3MuY3dkKCk7XG4gIGNvbnN0IG1vZGUgPVxuICAgIGNvbmZpZy5tb2RlID8/IChjb21tYW5kID09PSAnYnVpbGQnID8gJ3Byb2R1Y3Rpb24nIDogJ2RldmVsb3BtZW50Jyk7XG4gIGNvbnN0IGJyb3dzZXIgPSBjb25maWcuYnJvd3NlciA/PyAnY2hyb21lJztcbiAgY29uc3QgbWFuaWZlc3RWZXJzaW9uID1cbiAgICBjb25maWcubWFuaWZlc3RWZXJzaW9uID8/IChicm93c2VyID09ICdmaXJlZm94JyA/IDIgOiAzKTtcbiAgY29uc3Qgb3V0QmFzZURpciA9IHBhdGgucmVzb2x2ZShyb290LCAnLm91dHB1dCcpO1xuICBjb25zdCBvdXREaXIgPSBwYXRoLnJlc29sdmUob3V0QmFzZURpciwgYCR7YnJvd3Nlcn0tbXYke21hbmlmZXN0VmVyc2lvbn1gKTtcbiAgY29uc3QgbG9nZ2VyID0gY29uZmlnLmxvZ2dlciA/PyBjb25zb2xhO1xuXG4gIGNvbnN0IGJhc2VDb25maWc6IEludGVybmFsQ29uZmlnTm9Vc2VyRGlycyA9IHtcbiAgICByb290LFxuICAgIG91dERpcixcbiAgICBvdXRCYXNlRGlyLFxuICAgIHN0b3JlSWRzOiBjb25maWcuc3RvcmVJZHMgPz8ge30sXG4gICAgYnJvd3NlcixcbiAgICBtYW5pZmVzdFZlcnNpb24sXG4gICAgbW9kZSxcbiAgICBjb21tYW5kLFxuICAgIGxvZ2dlcixcbiAgICB2aXRlOiBjb25maWcudml0ZSA/PyB7fSxcbiAgICBtYW5pZmVzdDogY29uZmlnLm1hbmlmZXN0ID8/IHt9LFxuICAgIGltcG9ydHM6IGNvbmZpZy5pbXBvcnRzID8/IHt9LFxuICAgIHJ1bm5lckNvbmZpZzogYXdhaXQgbG9hZENvbmZpZzxFeHRlbnNpb25SdW5uZXJDb25maWc+KHtcbiAgICAgIG5hbWU6ICd3ZWItZXh0JyxcbiAgICAgIGN3ZDogcm9vdCxcbiAgICAgIGdsb2JhbFJjOiB0cnVlLFxuICAgICAgcmNGaWxlOiAnLndlYmV4dHJjJyxcbiAgICAgIG92ZXJyaWRlczogY29uZmlnLnJ1bm5lcixcbiAgICB9KSxcbiAgfTtcblxuICAvLyBMb2FkIHVzZXIgY29uZmlnIGZyb20gZmlsZVxuICBsZXQgdXNlckNvbmZpZzogVXNlckNvbmZpZyA9IHtcbiAgICBtb2RlLFxuICB9O1xuICBpZiAoY29uZmlnLmNvbmZpZ0ZpbGUgIT09IGZhbHNlKSB7XG4gICAgdXNlckNvbmZpZyA9IGF3YWl0IGltcG9ydFRzRmlsZTxVc2VyQ29uZmlnPihcbiAgICAgIHJvb3QsXG4gICAgICBwYXRoLnJlc29sdmUocm9vdCwgY29uZmlnLmNvbmZpZ0ZpbGUgPz8gJ3d4dC5jb25maWcudHMnKSxcbiAgICApO1xuICB9XG5cbiAgLy8gTWVyZ2UgaW5saW5lIGFuZCB1c2VyIGNvbmZpZ3NcbiAgY29uc3QgbWVyZ2VkID0gdml0ZS5tZXJnZUNvbmZpZyhcbiAgICBiYXNlQ29uZmlnLFxuICAgIHVzZXJDb25maWcsXG4gICkgYXMgSW50ZXJuYWxDb25maWdOb1VzZXJEaXJzO1xuXG4gIC8vIEFwcGx5IHVzZXIgY29uZmlnIGFuZCBjcmVhdGUgZmluYWwgY29uZmlnXG4gIGNvbnN0IHNyY0RpciA9IHVzZXJDb25maWcuc3JjRGlyID8gcmVzb2x2ZShyb290LCB1c2VyQ29uZmlnLnNyY0RpcikgOiByb290O1xuICBjb25zdCBlbnRyeXBvaW50c0RpciA9IHJlc29sdmUoXG4gICAgc3JjRGlyLFxuICAgIHVzZXJDb25maWcuZW50cnlwb2ludHNEaXIgPz8gJ2VudHJ5cG9pbnRzJyxcbiAgKTtcbiAgY29uc3QgcHVibGljRGlyID0gcmVzb2x2ZShzcmNEaXIsIHVzZXJDb25maWcucHVibGljRGlyID8/ICdwdWJsaWMnKTtcbiAgY29uc3Qgd3h0RGlyID0gcmVzb2x2ZShzcmNEaXIsICcud3h0Jyk7XG4gIGNvbnN0IHR5cGVzRGlyID0gcmVzb2x2ZSh3eHREaXIsICd0eXBlcycpO1xuXG4gIGNvbnN0IGZpbmFsQ29uZmlnOiBJbnRlcm5hbENvbmZpZyA9IHtcbiAgICAuLi5tZXJnZWQsXG4gICAgc3JjRGlyLFxuICAgIGVudHJ5cG9pbnRzRGlyLFxuICAgIHB1YmxpY0RpcixcbiAgICB3eHREaXI6IHd4dERpcixcbiAgICB0eXBlc0RpcixcbiAgICBmc0NhY2hlOiBjcmVhdGVGc0NhY2hlKHd4dERpciksXG4gIH07XG5cbiAgLy8gQ3VzdG9taXplIHRoZSBkZWZhdWx0IHZpdGUgY29uZmlnXG4gIGZpbmFsQ29uZmlnLnZpdGUucm9vdCA9IHJvb3Q7XG4gIGZpbmFsQ29uZmlnLnZpdGUuY29uZmlnRmlsZSA9IGZhbHNlO1xuICBmaW5hbENvbmZpZy52aXRlLmxvZ0xldmVsID0gJ3dhcm4nO1xuXG4gIGZpbmFsQ29uZmlnLnZpdGUuYnVpbGQgPz89IHt9O1xuICBmaW5hbENvbmZpZy52aXRlLmJ1aWxkLm91dERpciA9IG91dERpcjtcbiAgZmluYWxDb25maWcudml0ZS5idWlsZC5lbXB0eU91dERpciA9IGZhbHNlO1xuXG4gIGZpbmFsQ29uZmlnLnZpdGUucGx1Z2lucyA/Pz0gW107XG4gIGZpbmFsQ29uZmlnLnZpdGUucGx1Z2lucy5wdXNoKHBsdWdpbnMuZG93bmxvYWQoZmluYWxDb25maWcpKTtcbiAgZmluYWxDb25maWcudml0ZS5wbHVnaW5zLnB1c2gocGx1Z2lucy5kZXZIdG1sUHJlcmVuZGVyKGZpbmFsQ29uZmlnKSk7XG4gIGZpbmFsQ29uZmlnLnZpdGUucGx1Z2lucy5wdXNoKHBsdWdpbnMudW5pbXBvcnQoZmluYWxDb25maWcpKTtcbiAgZmluYWxDb25maWcudml0ZS5wbHVnaW5zLnB1c2goXG4gICAgcGx1Z2lucy52aXJ0dWFsRW50cnlwb2luKCdiYWNrZ3JvdW5kJywgZmluYWxDb25maWcpLFxuICApO1xuICBmaW5hbENvbmZpZy52aXRlLnBsdWdpbnMucHVzaChcbiAgICBwbHVnaW5zLnZpcnR1YWxFbnRyeXBvaW4oJ2NvbnRlbnQtc2NyaXB0JywgZmluYWxDb25maWcpLFxuICApO1xuICBmaW5hbENvbmZpZy52aXRlLnBsdWdpbnMucHVzaChwbHVnaW5zLmRldlNlcnZlckdsb2JhbHMoZmluYWxDb25maWcpKTtcblxuICBmaW5hbENvbmZpZy52aXRlLmRlZmluZSA/Pz0ge307XG4gIGdldEdsb2JhbHMoZmluYWxDb25maWcpLmZvckVhY2goKGdsb2JhbCkgPT4ge1xuICAgIGZpbmFsQ29uZmlnLnZpdGUuZGVmaW5lIVtnbG9iYWwubmFtZV0gPSBKU09OLnN0cmluZ2lmeShnbG9iYWwudmFsdWUpO1xuICB9KTtcblxuICByZXR1cm4gZmluYWxDb25maWc7XG59XG5cbi8qKlxuICogSGVscGVyIHR5cGUgZm9yIGRlZmluaW5nIGEgYmFzZSBjb25maWcsIHNpbmNlIHVzZXItY29uZmlndXJhYmxlIGRpcmVjdG9yaWVzIG11c3QgYmUgc2V0IGFmdGVyXG4gKiByZWFkaW5nIGluIHRoZSB1c2VyIGNvbmZpZy5cbiAqL1xudHlwZSBJbnRlcm5hbENvbmZpZ05vVXNlckRpcnMgPSBPbWl0PFxuICBJbnRlcm5hbENvbmZpZyxcbiAgJ3NyY0RpcicgfCAncHVibGljRGlyJyB8ICdlbnRyeXBvaW50c0RpcicgfCAnd3h0RGlyJyB8ICd0eXBlc0RpcicgfCAnZnNDYWNoZSdcbj47XG4iLCAiaW1wb3J0IHsgY29uc29sYSB9IGZyb20gJ2NvbnNvbGEnO1xuaW1wb3J0IGNyZWF0ZUpJVEkgZnJvbSAnaml0aSc7XG5pbXBvcnQgdHJhbnNmb3JtIGZyb20gJ2ppdGkvZGlzdC9iYWJlbCc7XG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBzY2FuRXhwb3J0cyB9IGZyb20gJ3VuaW1wb3J0JztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGltcG9ydFRzRmlsZTxUPihyb290OiBzdHJpbmcsIHBhdGg6IHN0cmluZyk6IFByb21pc2U8VD4ge1xuICBjb25zdCBjbGllbnRJbXBvcnRzID0gYXdhaXQgc2NhbkV4cG9ydHMoXG4gICAgcmVzb2x2ZShyb290LCAnbm9kZV9tb2R1bGVzL3d4dC9kaXN0L2NsaWVudC5qcycpLFxuICApO1xuICBjb25zdCBqaXRpID0gY3JlYXRlSklUSShfX2ZpbGVuYW1lLCB7XG4gICAgY2FjaGU6IGZhbHNlLFxuICAgIGVzbVJlc29sdmU6IHRydWUsXG4gICAgaW50ZXJvcERlZmF1bHQ6IHRydWUsXG5cbiAgICB0cmFuc2Zvcm0ob3B0cykge1xuICAgICAgLy8gUmVtb3ZlIENTUyBpbXBvcnRzIGZyb20gdGhlIHNvdXJjZSBjb2RlIC0gSml0aSBjYW4ndCBoYW5kbGUgdGhlbS5cbiAgICAgIG9wdHMuc291cmNlID0gb3B0cy5zb3VyY2UucmVwbGFjZSgvXmltcG9ydCBbJ1wiXS4qXFwuY3NzWydcIl07PyQvZ20sICcnKTtcbiAgICAgIG9wdHMuc291cmNlID0gb3B0cy5zb3VyY2UucmVwbGFjZShcbiAgICAgICAgL15pbXBvcnRcXHMrLipcXHMrZnJvbSBbJ1wiXXdlYmV4dGVuc2lvbi1wb2x5ZmlsbFsnXCJdOz8kL2dtLFxuICAgICAgICAnJyxcbiAgICAgICk7XG5cbiAgICAgIC8vIEFwcGVuZCBhbnkgd3h0L2NsaWVudCBmdW5jdGlvbnMgc28gYmFiZWwgZG9lc24ndCBjb21wbGFpbiBhYm91dCB1bmRlZmluZWQgdmFyaWFibGVzXG4gICAgICBpZiAob3B0cy5maWxlbmFtZSA9PT0gcGF0aCkge1xuICAgICAgICAvLyBUT0RPOiBPbmx5IGFwcGVuZCBpbXBvcnQgaWYgaXQgaXNuJ3QgYWxyZWFkeSBpbXBvcnRlZFxuICAgICAgICBjb25zdCBpbXBvcnRzID1cbiAgICAgICAgICBjbGllbnRJbXBvcnRzXG4gICAgICAgICAgICAubWFwKChpKSA9PiBgaW1wb3J0IHsgJHtpLm5hbWV9IH0gZnJvbSBcIiR7aS5mcm9tfVwiO2ApXG4gICAgICAgICAgICAuam9pbignXFxuJykgKyAnXFxuJztcbiAgICAgICAgb3B0cy5zb3VyY2UgPSBpbXBvcnRzICsgb3B0cy5zb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIC8vIENhbGwgdGhlIGRlZmF1bHQgYmFiZWwgdHJhbnNmb3JtZXIgd2l0aCBvdXIgbW9kaWZpZWQgc291cmNlIGNvZGVcbiAgICAgIHJldHVybiB0cmFuc2Zvcm0ob3B0cyk7XG4gICAgfSxcbiAgfSk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGppdGkocGF0aCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNvbnNvbGEuZXJyb3IoYEZhaWxlZCB0byBpbXBvcnQgZmlsZTogJHtwYXRofWApO1xuICAgIHRocm93IGVycjtcbiAgfVxufVxuIiwgImltcG9ydCAqIGFzIHZpdGUgZnJvbSAndml0ZSc7XG5pbXBvcnQgeyBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdldEVudHJ5cG9pbnROYW1lIH0gZnJvbSAnLi4vdXRpbHMvZW50cnlwb2ludHMnO1xuaW1wb3J0IHsgcGFyc2VIVE1MIH0gZnJvbSAnbGlua2Vkb20nO1xuaW1wb3J0IHsgZGlybmFtZSwgaXNBYnNvbHV0ZSwgcmVsYXRpdmUsIHJlc29sdmUgfSBmcm9tICdwYXRoJztcblxuLyoqXG4gKiBQcmUtcmVuZGVycyB0aGUgSFRNTCBlbnRyeXBvaW50cyB3aGVuIGJ1aWxkaW5nIHRoZSBleHRlbnNpb24gdG8gY29ubmVjdCB0byB0aGUgZGV2IHNlcnZlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldkh0bWxQcmVyZW5kZXIoY29uZmlnOiBJbnRlcm5hbENvbmZpZyk6IHZpdGUuUGx1Z2luIHtcbiAgcmV0dXJuIHtcbiAgICBhcHBseTogJ2J1aWxkJyxcbiAgICBuYW1lOiAnd3h0OmRldi1odG1sLXByZXJlbmRlcicsXG4gICAgY29uZmlnKHVzZXJDb25maWcpIHtcbiAgICAgIHJldHVybiB2aXRlLm1lcmdlQ29uZmlnKFxuICAgICAgICB7XG4gICAgICAgICAgcmVzb2x2ZToge1xuICAgICAgICAgICAgYWxpYXM6IHtcbiAgICAgICAgICAgICAgJ0B3eHQvcmVsb2FkLWh0bWwnOiByZXNvbHZlKFxuICAgICAgICAgICAgICAgIGNvbmZpZy5yb290LFxuICAgICAgICAgICAgICAgICdub2RlX21vZHVsZXMvd3h0L2Rpc3QvdmlydHVhbC1tb2R1bGVzL3JlbG9hZC1odG1sLmpzJyxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgdXNlckNvbmZpZyxcbiAgICAgICk7XG4gICAgfSxcbiAgICBhc3luYyB0cmFuc2Zvcm0oaHRtbCwgaWQpIHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IGNvbmZpZy5zZXJ2ZXI7XG4gICAgICBpZiAoY29uZmlnLmNvbW1hbmQgIT09ICdzZXJ2ZScgfHwgc2VydmVyID09IG51bGwgfHwgIWlkLmVuZHNXaXRoKCcuaHRtbCcpKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGNvbnN0IG9yaWdpbmFsVXJsID0gYCR7c2VydmVyLm9yaWdpbn0ke2lkfWA7XG4gICAgICBjb25zdCBuYW1lID0gZ2V0RW50cnlwb2ludE5hbWUoY29uZmlnLmVudHJ5cG9pbnRzRGlyLCBpZCk7XG4gICAgICBjb25zdCB1cmwgPSBgJHtzZXJ2ZXIub3JpZ2lufS8ke25hbWV9Lmh0bWxgO1xuICAgICAgY29uc3Qgc2VydmVySHRtbCA9IGF3YWl0IHNlcnZlci50cmFuc2Zvcm1JbmRleEh0bWwoXG4gICAgICAgIHVybCxcbiAgICAgICAgaHRtbCxcbiAgICAgICAgb3JpZ2luYWxVcmwsXG4gICAgICApO1xuICAgICAgY29uc3QgeyBkb2N1bWVudCB9ID0gcGFyc2VIVE1MKHNlcnZlckh0bWwpO1xuXG4gICAgICBjb25zdCBwb2ludFRvRGV2U2VydmVyID0gKHF1ZXJ5U2VsZWN0b3I6IHN0cmluZywgYXR0cjogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnlTZWxlY3RvcikuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHNyYyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHIpO1xuICAgICAgICAgIGlmICghc3JjKSByZXR1cm47XG5cbiAgICAgICAgICBpZiAoaXNBYnNvbHV0ZShzcmMpKSB7XG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyLCBzZXJ2ZXIub3JpZ2luICsgc3JjKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHNyYy5zdGFydHNXaXRoKCcuJykpIHtcbiAgICAgICAgICAgIGNvbnN0IGFicyA9IHJlc29sdmUoZGlybmFtZShpZCksIHNyYyk7XG4gICAgICAgICAgICBjb25zdCBwYXRobmFtZSA9IHJlbGF0aXZlKGNvbmZpZy5yb290LCBhYnMpO1xuICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0ciwgYCR7c2VydmVyLm9yaWdpbn0vJHtwYXRobmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIHBvaW50VG9EZXZTZXJ2ZXIoJ3NjcmlwdFt0eXBlPW1vZHVsZV0nLCAnc3JjJyk7XG4gICAgICBwb2ludFRvRGV2U2VydmVyKCdsaW5rW3JlbD1zdHlsZXNoZWV0XScsICdocmVmJyk7XG5cbiAgICAgIC8vIEFkZCBhIHNjcmlwdCB0byBhZGQgcGFnZSByZWxvYWRpbmdcbiAgICAgIGNvbnN0IHJlbG9hZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICByZWxvYWRlci5zcmMgPSAnQHd4dC9yZWxvYWQtaHRtbCc7XG4gICAgICByZWxvYWRlci50eXBlID0gJ21vZHVsZSc7XG4gICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHJlbG9hZGVyKTtcblxuICAgICAgY29uc3QgbmV3SHRtbCA9IGRvY3VtZW50LnRvU3RyaW5nKCk7XG4gICAgICBjb25maWcubG9nZ2VyLmRlYnVnKCdUcmFuc2Zvcm1lZCAnICsgaWQpO1xuICAgICAgY29uZmlnLmxvZ2dlci5kZWJ1ZygnT2xkIEhUTUw6XFxuJyArIGh0bWwpO1xuICAgICAgY29uZmlnLmxvZ2dlci5kZWJ1ZygnTmV3IEhUTUw6XFxuJyArIG5ld0h0bWwpO1xuICAgICAgcmV0dXJuIG5ld0h0bWw7XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBFbnRyeXBvaW50IH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHBhdGgsIHsgcmVsYXRpdmUsIHJlc29sdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW50cnlwb2ludE5hbWUoXG4gIGVudHJ5cG9pbnRzRGlyOiBzdHJpbmcsXG4gIGlucHV0UGF0aDogc3RyaW5nLFxuICAvLyB0eXBlOiBFbnRyeXBvaW50Wyd0eXBlJ10sXG4pOiBzdHJpbmcge1xuICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKGVudHJ5cG9pbnRzRGlyLCBpbnB1dFBhdGgpO1xuICAvLyBHcmFiIHRoZSBzdHJpbmcgdXAgdG8gdGhlIGZpcnN0IC4gb3IgL1xuICBjb25zdCBuYW1lID0gcmVsYXRpdmVQYXRoLnNwbGl0KC9bXFwuXFwvXS8sIDIpWzBdO1xuXG4gIHJldHVybiBuYW1lO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW50cnlwb2ludE91dHB1dEZpbGUoXG4gIGVudHJ5cG9pbnQ6IEVudHJ5cG9pbnQsXG4gIGV4dDogc3RyaW5nLFxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJlc29sdmUoZW50cnlwb2ludC5vdXRwdXREaXIsIGAke2VudHJ5cG9pbnQubmFtZX0ke2V4dH1gKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4ncyB0aGUgZW50cnlwb2ludCdzIG91dHB1dCBwYXRoIHJlbGF0aXZlIHRvIHRoZSBvdXRwdXQgZGlyZWN0b3J5LiBVc2VkIGZvciBwYXRocyBpbiB0aGVcbiAqIG1hbmlmZXN0IGFuZCByb2xsdXAncyBidW5kbGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbnRyeXBvaW50QnVuZGxlUGF0aChcbiAgZW50cnlwb2ludDogRW50cnlwb2ludCxcbiAgb3V0RGlyOiBzdHJpbmcsXG4gIGV4dDogc3RyaW5nLFxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJlbGF0aXZlKG91dERpciwgZ2V0RW50cnlwb2ludE91dHB1dEZpbGUoZW50cnlwb2ludCwgZXh0KSk7XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAndml0ZSc7XG5pbXBvcnQgeyBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcblxuLyoqXG4gKiBEZWZpbmVzIGdsb2JhbCBjb25zdGFudHMgYWJvdXQgdGhlIGRldiBzZXJ2ZXIuIEhlbHBzIHNjcmlwdHMgY29ubmVjdCB0byB0aGUgc2VydmVyJ3Mgd2ViIHNvY2tldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldlNlcnZlckdsb2JhbHMoaW50ZXJuYWxDb25maWc6IEludGVybmFsQ29uZmlnKTogUGx1Z2luIHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnd3h0OmRldi1zZXJ2ZXItZ2xvYmFscycsXG4gICAgY29uZmlnKGNvbmZpZykge1xuICAgICAgaWYgKGludGVybmFsQ29uZmlnLnNlcnZlciA9PSBudWxsIHx8IGludGVybmFsQ29uZmlnLmNvbW1hbmQgPT0gJ2J1aWxkJylcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjb25maWcuZGVmaW5lID8/PSB7fTtcbiAgICAgIGNvbmZpZy5kZWZpbmUuX19ERVZfU0VSVkVSX1BST1RPQ09MX18gPSBKU09OLnN0cmluZ2lmeSgnd3M6Jyk7XG4gICAgICBjb25maWcuZGVmaW5lLl9fREVWX1NFUlZFUl9IT1NUTkFNRV9fID0gSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIGludGVybmFsQ29uZmlnLnNlcnZlci5ob3N0bmFtZSxcbiAgICAgICk7XG4gICAgICBjb25maWcuZGVmaW5lLl9fREVWX1NFUlZFUl9QT1JUX18gPSBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgaW50ZXJuYWxDb25maWcuc2VydmVyLnBvcnQsXG4gICAgICApO1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IGRucyBmcm9tICdub2RlOmRucyc7XG5pbXBvcnQgeyB3aXRoVGltZW91dCB9IGZyb20gJy4vcHJvbWlzZXMnO1xuaW1wb3J0IHsgSW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5cbmZ1bmN0aW9uIGlzT2ZmbGluZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgaXNPZmZsaW5lID0gbmV3IFByb21pc2U8Ym9vbGVhbj4oKHJlcykgPT4ge1xuICAgIGRucy5yZXNvbHZlKCdnb29nbGUuY29tJywgKGVycikgPT4ge1xuICAgICAgaWYgKGVyciA9PSBudWxsKSB7XG4gICAgICAgIHJlcyhmYWxzZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXModHJ1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gd2l0aFRpbWVvdXQoaXNPZmZsaW5lLCAxZTMpLmNhdGNoKCgpID0+IHRydWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNPbmxpbmUoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IG9mZmxpbmUgPSBhd2FpdCBpc09mZmxpbmUoKTtcbiAgcmV0dXJuICFvZmZsaW5lO1xufVxuXG4vKipcbiAqIEZldGNoZXMgYSBVUkwgd2l0aCBhIHNpbXBsZSBHRVQgcmVxdWVzdC4gR3JhYnMgaXQgZnJvbSBjYWNoZSBpZiBpdCBkb2Vzbid0IGV4aXN0LCBvciB0aHJvd3MgYW5cbiAqIGVycm9yIGlmIGl0IGNhbid0IGJlIHJlc29sdmVkIHZpYSB0aGUgbmV0d29yayBvciBjYWNoZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoQ2FjaGVkKFxuICB1cmw6IHN0cmluZyxcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGxldCBjb250ZW50OiBzdHJpbmcgPSAnJztcblxuICBpZiAoYXdhaXQgaXNPbmxpbmUoKSkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgaWYgKHJlcy5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNvbnRlbnQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgYXdhaXQgY29uZmlnLmZzQ2FjaGUuc2V0KHVybCwgY29udGVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoXG4gICAgICAgIGBGYWlsZWQgdG8gZG93bmxvYWQgXCIke3VybH1cIiwgZmFsbGluZyBiYWNrIHRvIGNhY2hlLi4uYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFjb250ZW50KSBjb250ZW50ID0gKGF3YWl0IGNvbmZpZy5mc0NhY2hlLmdldCh1cmwpKSA/PyAnJztcbiAgaWYgKCFjb250ZW50KVxuICAgIHRocm93IEVycm9yKFxuICAgICAgYE9mZmxpbmUgYW5kIFwiJHt1cmx9XCIgaGFzIG5vdCBiZWVuIGNhY2hlZC4gVHJ5IGFnYWluIHdoZW4gb25saW5lLmAsXG4gICAgKTtcblxuICByZXR1cm4gY29udGVudDtcbn1cbiIsICIvKipcbiAqIEFkZCBhIHRpbWVvdXQgdG8gYSBwcm9taXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aFRpbWVvdXQ8VD4oXG4gIHByb21pc2U6IFByb21pc2U8VD4sXG4gIGR1cmF0aW9uOiBudW1iZXIsXG4pOiBQcm9taXNlPFQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHJlaihgUHJvbWlzZSB0aW1lZCBvdXQgYWZ0ZXIgJHtkdXJhdGlvbn1tc2ApO1xuICAgIH0sIGR1cmF0aW9uKTtcbiAgICBwcm9taXNlXG4gICAgICAudGhlbihyZXMpXG4gICAgICAuY2F0Y2gocmVqKVxuICAgICAgLmZpbmFsbHkoKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVvdXQpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgRG9uJ3QgdXNlIGluIHByb2R1Y3Rpb24sIGp1c3QgZm9yIHRlc3RpbmcgYW5kIHNsb3dpbmcgdGhpbmdzIGRvd24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzKSA9PiBzZXRUaW1lb3V0KHJlcywgbXMpKTtcbn1cbiIsICJpbXBvcnQgeyBQbHVnaW4gfSBmcm9tICd2aXRlJztcbmltcG9ydCB7IEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZmV0Y2hDYWNoZWQgfSBmcm9tICcuLi91dGlscy9uZXR3b3JrJztcblxuLyoqXG4gKiBEb3dubG9hZHMgYW55IFVSTCBpbXBvcnRzLCBsaWtlIEdvb2dsZSBBbmFseXRpY3MsIGludG8gdmlydHVhbCBtb2R1bGVzIHNvIHRoZXkgYXJlIGJ1bmRsZWQgd2l0aFxuICogdGhlIGV4dGVuc2lvbiBpbnN0ZWFkIG9mIGRlcGVuZGluZyBvbiByZW1vdGUgY29kZSBhdCBydW50aW1lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgXCJ1cmw6aHR0cHM6Ly9nb29nbGUtdGFnbWFuYWdlci5jb20vZ3RhZz9pZD1YWVpcIjtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRvd25sb2FkKGNvbmZpZzogSW50ZXJuYWxDb25maWcpOiBQbHVnaW4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3eHQ6ZG93bmxvYWQnLFxuICAgIHJlc29sdmVJZChpZCkge1xuICAgICAgaWYgKGlkLnN0YXJ0c1dpdGgoJ3VybDonKSkgcmV0dXJuICdcXDAnICsgaWQ7XG4gICAgfSxcbiAgICBhc3luYyBsb2FkKGlkKSB7XG4gICAgICBpZiAoIWlkLnN0YXJ0c1dpdGgoJ1xcMHVybDonKSkgcmV0dXJuO1xuXG4gICAgICAvLyBMb2FkIGZpbGUgZnJvbSBuZXR3b3JrIG9yIGNhY2hlXG4gICAgICBjb25zdCB1cmwgPSBpZC5yZXBsYWNlKCdcXDB1cmw6JywgJycpO1xuICAgICAgcmV0dXJuIGF3YWl0IGZldGNoQ2FjaGVkKHVybCwgY29uZmlnKTtcbiAgICB9LFxuICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHZpdGUgZnJvbSAndml0ZSc7XG5pbXBvcnQgeyBFbnRyeXBvaW50LCBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGRpcm5hbWUsIGV4dG5hbWUsIHJlc29sdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGggfSBmcm9tICcuLi91dGlscy9lbnRyeXBvaW50cyc7XG5pbXBvcnQgZnMsIHsgZW5zdXJlRGlyIH0gZnJvbSAnZnMtZXh0cmEnO1xuXG4vKipcbiAqIEVuc3VyZXMgdGhlIEhUTUwgZmlsZXMgb3V0cHV0IGJ5IGEgbXVsdGlwYWdlIGJ1aWxkIGFyZSBpbiB0aGUgY29ycmVjdCBsb2NhdGlvbi4gVGhpcyBkb2VzIHR3b1xuICogdGhpbmdzOlxuICpcbiAqIDEuIE1vdmVzIHRoZSBITVRMIGZpbGVzIHRvIHRoZWlyIGZpbmFsIGxvY2F0aW9uIGF0IGA8b3V0RGlyPi88ZW50cnlwb2ludC5uYW1lPi5odG1sYC5cbiAqIDIuIFVwZGF0ZXMgdGhlIGJ1bmRsZSBzbyBpdCBzdW1tYXJpemVzIHRoZSBmaWxlcyBjb3JyZWN0bHkgaW4gdGhlIHJldHVybmVkIGJ1aWxkIG91dHB1dC5cbiAqXG4gKiBBc3NldHMgKEpTIGFuZCBDU1MpIGFyZSBvdXRwdXQgdG8gdGhlIGA8b3V0RGlyPi9hc3NldHNgIGRpcmVjdG9yeSwgYW5kIGRvbid0IG5lZWQgdG8gYmUgbW9kaWZpZWQuXG4gKiBIVE1MIGZpbGVzIGFjY2VzcyB0aGVtIHZpYSBhYnNvbHV0ZSBVUkxzLCBzbyB3ZSBkb24ndCBuZWVkIHRvIHVwZGF0ZSBhbnkgaW1wb3J0IHBhdGhzIGluIHRoZSBIVE1MXG4gKiBmaWxlcyBlaXRoZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtdWx0aXBhZ2VNb3ZlKFxuICBlbnRyeXBvaW50czogRW50cnlwb2ludFtdLFxuICBjb25maWc6IEludGVybmFsQ29uZmlnLFxuKTogdml0ZS5QbHVnaW4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3eHQ6bXVsdGlwYWdlLW1vdmUnLFxuICAgIGFzeW5jIHdyaXRlQnVuZGxlKF8sIGJ1bmRsZSkge1xuICAgICAgZm9yIChjb25zdCBvbGRCdW5kbGVQYXRoIGluIGJ1bmRsZSkge1xuICAgICAgICAvLyBvbGRCdW5kbGVQYXRoID0gJ2VudHJ5cG9pbnRzL3BvcHVwLmh0bWwnIG9yICdlbnRyeXBvaW50cy9vIHB0aW9ucy9pbmRleC5odG1sJ1xuXG4gICAgICAgIC8vIEZpbmQgYSBtYXRjaGluZyBlbnRyeXBvaW50IC0gb2xkQnVuZGxlUGF0aCBpcyB0aGUgc2FtZSBhcyBlbmQgZW5kIG9mIHRoZSBpbnB1dCBwYXRoLlxuICAgICAgICBjb25zdCBlbnRyeXBvaW50ID0gZW50cnlwb2ludHMuZmluZChcbiAgICAgICAgICAoZW50cnkpID0+ICEhZW50cnkuaW5wdXRQYXRoLmVuZHNXaXRoKG9sZEJ1bmRsZVBhdGgpLFxuICAgICAgICApO1xuICAgICAgICBpZiAoZW50cnlwb2ludCA9PSBudWxsKSB7XG4gICAgICAgICAgY29uZmlnLmxvZ2dlci5kZWJ1ZygnTm8gZW50cnlwb2ludCBmb3VuZCBmb3InLCBvbGRCdW5kbGVQYXRoKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgbmV3IGJ1bmRsZSBwYXRoXG4gICAgICAgIGNvbnN0IG5ld0J1bmRsZVBhdGggPSBnZXRFbnRyeXBvaW50QnVuZGxlUGF0aChcbiAgICAgICAgICBlbnRyeXBvaW50LFxuICAgICAgICAgIGNvbmZpZy5vdXREaXIsXG4gICAgICAgICAgZXh0bmFtZShvbGRCdW5kbGVQYXRoKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG5ld0J1bmRsZVBhdGggPT09IG9sZEJ1bmRsZVBhdGgpIHtcbiAgICAgICAgICBjb25maWcubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgJ0hUTUwgZmlsZSBpcyBhbHJlYWR5IGluIHRoZSBjb3JyZWN0IGxvY2F0aW9uJyxcbiAgICAgICAgICAgIG9sZEJ1bmRsZVBhdGgsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE1vdmUgZmlsZSBhbmQgdXBkYXRlIGJ1bmRsZVxuICAgICAgICAvLyBEbyB0aGlzIGluc2lkZSBhIG11dGV4IGxvY2sgc28gaXQgb25seSBydW5zIG9uZSBhdCBhIHRpbWUgZm9yIGNvbmN1cnJlbnQgbXVsdGlwYWdlIGJ1aWxkc1xuICAgICAgICBjb25zdCBvbGRBYnNQYXRoID0gcmVzb2x2ZShjb25maWcub3V0RGlyLCBvbGRCdW5kbGVQYXRoKTtcbiAgICAgICAgY29uc3QgbmV3QWJzUGF0aCA9IHJlc29sdmUoY29uZmlnLm91dERpciwgbmV3QnVuZGxlUGF0aCk7XG4gICAgICAgIGF3YWl0IGVuc3VyZURpcihkaXJuYW1lKG5ld0Fic1BhdGgpKTtcbiAgICAgICAgYXdhaXQgZnMubW92ZShvbGRBYnNQYXRoLCBuZXdBYnNQYXRoLCB7IG92ZXJ3cml0ZTogdHJ1ZSB9KTtcblxuICAgICAgICBjb25zdCByZW5hbWVkQ2h1bmsgPSB7XG4gICAgICAgICAgLi4uYnVuZGxlW29sZEJ1bmRsZVBhdGhdLFxuICAgICAgICAgIGZpbGVOYW1lOiBuZXdCdW5kbGVQYXRoLFxuICAgICAgICB9O1xuICAgICAgICBkZWxldGUgYnVuZGxlW29sZEJ1bmRsZVBhdGhdO1xuICAgICAgICBidW5kbGVbbmV3QnVuZGxlUGF0aF0gPSByZW5hbWVkQ2h1bms7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVVbmltcG9ydCB9IGZyb20gJ3VuaW1wb3J0JztcbmltcG9ydCB7IEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0VW5pbXBvcnRPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMvYXV0by1pbXBvcnRzJztcbmltcG9ydCB7IFBsdWdpbiB9IGZyb20gJ3ZpdGUnO1xuXG4vKipcbiAqIEluamVjdCBhbnkgZ2xvYmFsIGltcG9ydHMgZGVmaW5lZCBieSB1bmltcG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5pbXBvcnQoY29uZmlnOiBJbnRlcm5hbENvbmZpZyk6IFBsdWdpbiB7XG4gIGNvbnN0IG9wdGlvbnMgPSBnZXRVbmltcG9ydE9wdGlvbnMoY29uZmlnKTtcbiAgY29uc3QgdW5pbXBvcnQgPSBjcmVhdGVVbmltcG9ydChvcHRpb25zKTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3eHQ6dW5pbXBvcnQnLFxuICAgIGFzeW5jIGNvbmZpZygpIHtcbiAgICAgIGF3YWl0IHVuaW1wb3J0LnNjYW5JbXBvcnRzRnJvbURpcih1bmRlZmluZWQsIHsgY3dkOiBjb25maWcuc3JjRGlyIH0pO1xuICAgIH0sXG4gICAgYXN5bmMgdHJhbnNmb3JtKGNvZGUsIGlkKSB7XG4gICAgICByZXR1cm4gdW5pbXBvcnQuaW5qZWN0SW1wb3J0cyhjb2RlLCBpZCk7XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBVbmltcG9ydE9wdGlvbnMgfSBmcm9tICd1bmltcG9ydCc7XG5pbXBvcnQgeyBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IG1lcmdlQ29uZmlnIH0gZnJvbSAndml0ZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRVbmltcG9ydE9wdGlvbnMoXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQYXJ0aWFsPFVuaW1wb3J0T3B0aW9ucz4ge1xuICBjb25zdCBkZWZhdWx0T3B0aW9uczogUGFydGlhbDxVbmltcG9ydE9wdGlvbnM+ID0ge1xuICAgIGRlYnVnTG9nOiBjb25maWcubG9nZ2VyLmRlYnVnLFxuICAgIGltcG9ydHM6IFtcbiAgICAgIHsgbmFtZTogJyonLCBhczogJ2Jyb3dzZXInLCBmcm9tOiAnd2ViZXh0ZW5zaW9uLXBvbHlmaWxsJyB9LFxuICAgICAgeyBuYW1lOiAnZGVmaW5lQ29uZmlnJywgZnJvbTogJ3d4dCcgfSxcbiAgICBdLFxuICAgIHByZXNldHM6IFt7IHBhY2thZ2U6ICd3eHQvY2xpZW50JyB9XSxcbiAgICB3YXJuOiBjb25maWcubG9nZ2VyLndhcm4sXG4gICAgZGlyczogWydjb21wb25lbnRzJywgJ2NvbXBvc2FibGVzJywgJ2hvb2tzJywgJ3V0aWxzJ10sXG4gIH07XG5cbiAgcmV0dXJuIG1lcmdlQ29uZmlnKFxuICAgIGRlZmF1bHRPcHRpb25zLFxuICAgIGNvbmZpZy5pbXBvcnRzLFxuICApIGFzIFBhcnRpYWw8VW5pbXBvcnRPcHRpb25zPjtcbn1cbiIsICJpbXBvcnQgeyBQbHVnaW4gfSBmcm9tICd2aXRlJztcbmltcG9ydCB7IEVudHJ5cG9pbnQsIEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tICdwYXRoJztcblxuLyoqXG4gKiBXcmFwcyBhIHVzZXIncyBlbnRyeXBvaW50IHdpdGggYSB2aXR1YWwgdmVyc2lvbiB3aXRoIGFkZGl0aW9uYWwgbG9naWMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2aXJ0dWFsRW50cnlwb2luKFxuICB0eXBlOiBFbnRyeXBvaW50Wyd0eXBlJ10sXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQbHVnaW4ge1xuICBjb25zdCB2aXJ0dWFsSWQgPSBgdmlydHVhbDp3eHQtJHt0eXBlfT9gO1xuICBjb25zdCByZXNvbHZlZFZpcnR1YWxJZCA9IGBcXDAke3ZpcnR1YWxJZH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogYHd4dDp2aXJ0dWFsLWVudHJ5cG9pbnRgLFxuICAgIHJlc29sdmVJZChpZCkge1xuICAgICAgLy8gSWQgZG9lc24ndCBzdGFydCB3aXRoIHByZWZpeCwgaXQgbG9va3MgbGlrZSB0aGlzOlxuICAgICAgLy8gL3BhdGgvdG8vcHJvamVjdC92aXJ0dWFsOmJhY2tncm91bmQ/L3BhdGgvdG8vcHJvamVjdC9lbnRyeXBvaW50cy9iYWNrZ3JvdW5kLnRzXG4gICAgICBjb25zdCBpbmRleCA9IGlkLmluZGV4T2YodmlydHVhbElkKTtcbiAgICAgIGlmIChpbmRleCA9PT0gLTEpIHJldHVybjtcblxuICAgICAgY29uc3QgaW5wdXRQYXRoID0gaWQuc3Vic3RyaW5nKGluZGV4ICsgdmlydHVhbElkLmxlbmd0aCk7XG4gICAgICByZXR1cm4gcmVzb2x2ZWRWaXJ0dWFsSWQgKyBpbnB1dFBhdGg7XG4gICAgfSxcbiAgICBhc3luYyBsb2FkKGlkKSB7XG4gICAgICBpZiAoIWlkLnN0YXJ0c1dpdGgocmVzb2x2ZWRWaXJ0dWFsSWQpKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGlucHV0UGF0aCA9IGlkLnJlcGxhY2UocmVzb2x2ZWRWaXJ0dWFsSWQsICcnKTtcbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gYXdhaXQgZnMucmVhZEZpbGUoXG4gICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgY29uZmlnLnJvb3QsXG4gICAgICAgICAgYG5vZGVfbW9kdWxlcy93eHQvZGlzdC92aXJ0dWFsLW1vZHVsZXMvJHt0eXBlfS1lbnRyeXBvaW50LmpzYCxcbiAgICAgICAgKSxcbiAgICAgICAgJ3V0Zi04JyxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdGVtcGxhdGUucmVwbGFjZShgdmlydHVhbDp1c2VyLSR7dHlwZX1gLCBpbnB1dFBhdGgpO1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IGZzLCB7IGVuc3VyZURpciB9IGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IEZzQ2FjaGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBkaXJuYW1lLCByZXNvbHZlIH0gZnJvbSAncGF0aCc7XG5cbi8qKlxuICogQSBiYXNpYyBmaWxlIHN5c3RlbSBjYWNoZSBzdG9yZWQgYXQgYDxzcmNEaXI+Ly53eHQvY2FjaGUvPGtleT5gLiBKdXN0IGNhY2hlcyBhIHN0cmluZyBpbiBhXG4gKiBmaWxlIGZvciB0aGUgZ2l2ZW4ga2V5LlxuICpcbiAqIEBwYXJhbSBzcmNEaXIgQWJzb2x1dGUgcGF0aCB0byBzb3VyY2UgZGlyZWN0b3J5LiBTZWUgYEludGVybmFsQ29uZmlnLnNyY0RpcmBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZzQ2FjaGUod3h0RGlyOiBzdHJpbmcpOiBGc0NhY2hlIHtcbiAgY29uc3QgZ2V0UGF0aCA9IChrZXk6IHN0cmluZykgPT5cbiAgICByZXNvbHZlKHd4dERpciwgJ2NhY2hlJywgZW5jb2RlVVJJQ29tcG9uZW50KGtleSkpO1xuXG4gIHJldHVybiB7XG4gICAgYXN5bmMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBwYXRoID0gZ2V0UGF0aChrZXkpO1xuICAgICAgYXdhaXQgZW5zdXJlRGlyKGRpcm5hbWUocGF0aCkpO1xuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKHBhdGgsIHZhbHVlLCAndXRmLTgnKTtcbiAgICB9LFxuICAgIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgICBjb25zdCBwYXRoID0gZ2V0UGF0aChrZXkpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZzLnJlYWRGaWxlKHBhdGgsICd1dGYtOCcpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEdsb2JhbHMoXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdmFsdWU6IGFueTsgdHlwZTogc3RyaW5nIH0+IHtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBuYW1lOiAnX19NQU5JRkVTVF9WRVJTSU9OX18nLFxuICAgICAgdmFsdWU6IGNvbmZpZy5tYW5pZmVzdFZlcnNpb24sXG4gICAgICB0eXBlOiBgMiB8IDNgLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogJ19fQlJPV1NFUl9fJyxcbiAgICAgIHZhbHVlOiBjb25maWcuYnJvd3NlcixcbiAgICAgIHR5cGU6IGBcImNocm9taXVtXCIgfCBcImZpcmVmb3hcImAsXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiAnX19JU19DSFJPTUVfXycsXG4gICAgICB2YWx1ZTogY29uZmlnLmJyb3dzZXIgPT09ICdjaHJvbWUnLFxuICAgICAgdHlwZTogYGJvb2xlYW5gLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogJ19fSVNfRklSRUZPWF9fJyxcbiAgICAgIHZhbHVlOiBjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnLFxuICAgICAgdHlwZTogYGJvb2xlYW5gLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogJ19fSVNfU0FGQVJJX18nLFxuICAgICAgdmFsdWU6IGNvbmZpZy5icm93c2VyID09PSAnc2FmYXJpJyxcbiAgICAgIHR5cGU6IGBib29sZWFuYCxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6ICdfX0lTX0VER0VfXycsXG4gICAgICB2YWx1ZTogY29uZmlnLmJyb3dzZXIgPT09ICdlZGdlJyxcbiAgICAgIHR5cGU6IGBib29sZWFuYCxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6ICdfX0lTX09QRVJBX18nLFxuICAgICAgdmFsdWU6IGNvbmZpZy5icm93c2VyID09PSAnb3BlcmEnLFxuICAgICAgdHlwZTogYGJvb2xlYW5gLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogJ19fQ09NTUFORF9fJyxcbiAgICAgIHZhbHVlOiBjb25maWcuY29tbWFuZCxcbiAgICAgIHR5cGU6IGBcImJ1aWxkXCIgfCBcInNlcnZlXCJgLFxuICAgIH0sXG4gIF07XG59XG4iLCAiaW1wb3J0IHsgcmVsYXRpdmUsIHJlc29sdmUgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7XG4gIEJhY2tncm91bmRFbnRyeXBvaW50LFxuICBCYWNrZ3JvdW5kU2NyaXB0RGVmaW50aXRpb24sXG4gIENvbnRlbnRTY3JpcHREZWZpbml0aW9uLFxuICBDb250ZW50U2NyaXB0RW50cnlwb2ludCxcbiAgRW50cnlwb2ludCxcbiAgSW50ZXJuYWxDb25maWcsXG4gIE9wdGlvbnNFbnRyeXBvaW50LFxuICBQb3B1cEVudHJ5cG9pbnQsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgcGljb21hdGNoIGZyb20gJ3BpY29tYXRjaCc7XG5pbXBvcnQgeyBwYXJzZUhUTUwgfSBmcm9tICdsaW5rZWRvbSc7XG5pbXBvcnQgSlNPTjUgZnJvbSAnanNvbjUnO1xuaW1wb3J0IHsgaW1wb3J0VHNGaWxlIH0gZnJvbSAnLi4vdXRpbHMvaW1wb3J0VHNGaWxlJztcbmltcG9ydCBnbG9iIGZyb20gJ2Zhc3QtZ2xvYic7XG5pbXBvcnQgeyBnZXRFbnRyeXBvaW50TmFtZSB9IGZyb20gJy4uL3V0aWxzL2VudHJ5cG9pbnRzJztcblxuLyoqXG4gKiBSZXR1cm4gZW50cnlwb2ludHMgYW5kIHRoZWlyIGNvbmZpZ3VyYXRpb24gYnkgbG9va2luZyB0aHJvdWdoIHRoZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluZEVudHJ5cG9pbnRzKFxuICBjb25maWc6IEZpbmRFbnRyeXBvaW50c0NvbmZpZyxcbik6IFByb21pc2U8RW50cnlwb2ludFtdPiB7XG4gIGNvbnN0IHJlbGF0aXZlUGF0aHMgPSBhd2FpdCBnbG9iKCcqKi8qJywge1xuICAgIGN3ZDogY29uZmlnLmVudHJ5cG9pbnRzRGlyLFxuICB9KTtcbiAgLy8gRW5zdXJlIGNvbnNpc3RlbnQgb3V0cHV0XG4gIHJlbGF0aXZlUGF0aHMuc29ydCgpO1xuXG4gIGNvbnN0IHBhdGhHbG9icyA9IE9iamVjdC5rZXlzKFBBVEhfR0xPQl9UT19UWVBFX01BUCk7XG4gIGNvbnN0IGV4aXN0aW5nTmFtZXM6IFJlY29yZDxzdHJpbmcsIEVudHJ5cG9pbnQgfCB1bmRlZmluZWQ+ID0ge307XG5cbiAgY29uc3QgZW50cnlwb2ludHM6IEVudHJ5cG9pbnRbXSA9IFtdO1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICByZWxhdGl2ZVBhdGhzLm1hcChhc3luYyAocmVsYXRpdmVQYXRoKSA9PiB7XG4gICAgICBjb25zdCBwYXRoID0gcmVzb2x2ZShjb25maWcuZW50cnlwb2ludHNEaXIsIHJlbGF0aXZlUGF0aCk7XG4gICAgICBjb25zdCBtYXRjaGluZ0dsb2IgPSBwYXRoR2xvYnMuZmluZCgoZ2xvYikgPT5cbiAgICAgICAgcGljb21hdGNoLmlzTWF0Y2gocmVsYXRpdmVQYXRoLCBnbG9iKSxcbiAgICAgICk7XG5cbiAgICAgIGlmIChtYXRjaGluZ0dsb2IgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gY29uZmlnLmxvZ2dlci53YXJuKFxuICAgICAgICAgIGAke3JlbGF0aXZlUGF0aH0gZG9lcyBub3QgbWF0Y2ggYW55IGtub3duIGVudHJ5cG9pbnQuIEtub3duIGVudHJ5cG9pbnRzOlxcbiR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICBQQVRIX0dMT0JfVE9fVFlQRV9NQVAsXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgMixcbiAgICAgICAgICApfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHR5cGUgPSBQQVRIX0dMT0JfVE9fVFlQRV9NQVBbbWF0Y2hpbmdHbG9iXTtcbiAgICAgIGlmICh0eXBlID09PSAnaWdub3JlZCcpIHJldHVybjtcblxuICAgICAgbGV0IGVudHJ5cG9pbnQ6IEVudHJ5cG9pbnQ7XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAncG9wdXAnOlxuICAgICAgICAgIGVudHJ5cG9pbnQgPSBhd2FpdCBnZXRQb3B1cEVudHJ5cG9pbnQoY29uZmlnLCBwYXRoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnb3B0aW9ucyc6XG4gICAgICAgICAgZW50cnlwb2ludCA9IGF3YWl0IGdldE9wdGlvbnNFbnRyeXBvaW50KGNvbmZpZywgcGF0aCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2JhY2tncm91bmQnOlxuICAgICAgICAgIGVudHJ5cG9pbnQgPSBhd2FpdCBnZXRCYWNrZ3JvdW5kRW50cnlwb2ludChjb25maWcsIHBhdGgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdjb250ZW50LXNjcmlwdCc6XG4gICAgICAgICAgZW50cnlwb2ludCA9IGF3YWl0IGdldENvbnRlbnRTY3JpcHRFbnRyeXBvaW50KFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgcmVsYXRpdmVQYXRoLnNwbGl0KCcuJywgMilbMF0sXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgZW50cnlwb2ludCA9IHtcbiAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICBuYW1lOiBnZXRFbnRyeXBvaW50TmFtZShjb25maWcuZW50cnlwb2ludHNEaXIsIHBhdGgpLFxuICAgICAgICAgICAgaW5wdXRQYXRoOiBwYXRoLFxuICAgICAgICAgICAgb3V0cHV0RGlyOiBjb25maWcub3V0RGlyLFxuICAgICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHdpdGhTYW1lTmFtZSA9IGV4aXN0aW5nTmFtZXNbZW50cnlwb2ludC5uYW1lXTtcbiAgICAgIGlmICh3aXRoU2FtZU5hbWUpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgYE11bHRpcGxlIGVudHJ5cG9pbnRzIHdpdGggdGhlIG5hbWUgXCIke1xuICAgICAgICAgICAgZW50cnlwb2ludC5uYW1lXG4gICAgICAgICAgfVwiIGRldGVjdGVkLCBidXQgb25seSBvbmUgaXMgYWxsb3dlZDogJHtbXG4gICAgICAgICAgICByZWxhdGl2ZShjb25maWcucm9vdCwgd2l0aFNhbWVOYW1lLmlucHV0UGF0aCksXG4gICAgICAgICAgICByZWxhdGl2ZShjb25maWcucm9vdCwgZW50cnlwb2ludC5pbnB1dFBhdGgpLFxuICAgICAgICAgIF0uam9pbignLCAnKX1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZW50cnlwb2ludHMucHVzaChlbnRyeXBvaW50KTtcbiAgICAgIGV4aXN0aW5nTmFtZXNbZW50cnlwb2ludC5uYW1lXSA9IGVudHJ5cG9pbnQ7XG4gICAgfSksXG4gICk7XG4gIHJldHVybiBlbnRyeXBvaW50cztcbn1cblxuLyoqXG4gKiBAcGFyYW0gcGF0aCBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBwb3B1cCBIVE1MIGZpbGUuXG4gKiBAcGFyYW0gY29udGVudCBTdHJpbmcgY29udGVudHMgb2YgdGhlIGZpbGUgYXQgdGhlIHBhdGguXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFBvcHVwRW50cnlwb2ludChcbiAgY29uZmlnOiBGaW5kRW50cnlwb2ludHNDb25maWcsXG4gIHBhdGg6IHN0cmluZyxcbik6IFByb21pc2U8UG9wdXBFbnRyeXBvaW50PiB7XG4gIGNvbnN0IG9wdGlvbnM6IFBvcHVwRW50cnlwb2ludFsnb3B0aW9ucyddID0ge307XG5cbiAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhdGgsICd1dGYtOCcpO1xuICBjb25zdCB7IGRvY3VtZW50IH0gPSBwYXJzZUhUTUwoY29udGVudCk7XG5cbiAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd0aXRsZScpO1xuICBpZiAodGl0bGUgIT0gbnVsbCkgb3B0aW9ucy5kZWZhdWx0VGl0bGUgPSB0aXRsZS50ZXh0Q29udGVudCA/PyB1bmRlZmluZWQ7XG5cbiAgY29uc3QgZGVmYXVsdEljb25Db250ZW50ID0gZG9jdW1lbnRcbiAgICAucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0nbWFuaWZlc3QuZGVmYXVsdF9pY29uJ11cIilcbiAgICA/LmdldEF0dHJpYnV0ZSgnY29udGVudCcpO1xuICBpZiAoZGVmYXVsdEljb25Db250ZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIG9wdGlvbnMuZGVmYXVsdEljb24gPSBKU09ONS5wYXJzZShkZWZhdWx0SWNvbkNvbnRlbnQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uZmlnLmxvZ2dlci5mYXRhbChcbiAgICAgICAgYEZhaWxlZCB0byBwYXJzZSBkZWZhdWx0X2ljb24gbWV0YSB0YWcgY29udGVudCBhcyBKU09ONS4gY29udGVudD0ke2RlZmF1bHRJY29uQ29udGVudH1gLFxuICAgICAgICBlcnIsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG12MktleUNvbnRlbnQgPSBkb2N1bWVudFxuICAgIC5xdWVyeVNlbGVjdG9yKFwibWV0YVtuYW1lPSdtYW5pZmVzdC50eXBlJ11cIilcbiAgICA/LmdldEF0dHJpYnV0ZSgnY29udGVudCcpO1xuICBpZiAobXYyS2V5Q29udGVudCkge1xuICAgIG9wdGlvbnMubXYyS2V5ID1cbiAgICAgIG12MktleUNvbnRlbnQgPT09ICdwYWdlX2FjdGlvbicgPyAncGFnZV9hY3Rpb24nIDogJ2Jyb3dzZXJfYWN0aW9uJztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ3BvcHVwJyxcbiAgICBuYW1lOiAncG9wdXAnLFxuICAgIG9wdGlvbnMsXG4gICAgaW5wdXRQYXRoOiBwYXRoLFxuICAgIG91dHB1dERpcjogY29uZmlnLm91dERpcixcbiAgfTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gcGF0aCBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBvcHRpb25zIEhUTUwgZmlsZS5cbiAqIEBwYXJhbSBjb250ZW50IFN0cmluZyBjb250ZW50cyBvZiB0aGUgZmlsZSBhdCB0aGUgcGF0aC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0T3B0aW9uc0VudHJ5cG9pbnQoXG4gIGNvbmZpZzogRmluZEVudHJ5cG9pbnRzQ29uZmlnLFxuICBwYXRoOiBzdHJpbmcsXG4pOiBQcm9taXNlPE9wdGlvbnNFbnRyeXBvaW50PiB7XG4gIGNvbnN0IG9wdGlvbnM6IE9wdGlvbnNFbnRyeXBvaW50WydvcHRpb25zJ10gPSB7fTtcblxuICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUocGF0aCwgJ3V0Zi04Jyk7XG4gIGNvbnN0IHsgZG9jdW1lbnQgfSA9IHBhcnNlSFRNTChjb250ZW50KTtcblxuICBjb25zdCBvcGVuSW5UYWJDb250ZW50ID0gZG9jdW1lbnRcbiAgICAucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0nbWFuaWZlc3Qub3Blbl9pbl90YWInXVwiKVxuICAgID8uZ2V0QXR0cmlidXRlKCdjb250ZW50Jyk7XG4gIGlmIChvcGVuSW5UYWJDb250ZW50KSB7XG4gICAgb3B0aW9ucy5vcGVuSW5UYWIgPSBCb29sZWFuKG9wZW5JblRhYkNvbnRlbnQpO1xuICB9XG5cbiAgY29uc3QgY2hyb21lU3R5bGVDb250ZW50ID0gZG9jdW1lbnRcbiAgICAucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0nbWFuaWZlc3QuY2hyb21lX3N0eWxlJ11cIilcbiAgICA/LmdldEF0dHJpYnV0ZSgnY29udGVudCcpO1xuICBpZiAoY2hyb21lU3R5bGVDb250ZW50KSB7XG4gICAgb3B0aW9ucy5jaHJvbWVTdHlsZSA9IEJvb2xlYW4oY2hyb21lU3R5bGVDb250ZW50KTtcbiAgfVxuXG4gIGNvbnN0IGJyb3dzZXJTdHlsZUNvbnRlbnQgPSBkb2N1bWVudFxuICAgIC5xdWVyeVNlbGVjdG9yKFwibWV0YVtuYW1lPSdtYW5pZmVzdC5icm93c2VyX3N0eWxlJ11cIilcbiAgICA/LmdldEF0dHJpYnV0ZSgnY29udGVudCcpO1xuICBpZiAoYnJvd3NlclN0eWxlQ29udGVudCkge1xuICAgIG9wdGlvbnMuYnJvd3NlclN0eWxlID0gQm9vbGVhbihicm93c2VyU3R5bGVDb250ZW50KTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ29wdGlvbnMnLFxuICAgIG5hbWU6ICdvcHRpb25zJyxcbiAgICBvcHRpb25zLFxuICAgIGlucHV0UGF0aDogcGF0aCxcbiAgICBvdXRwdXREaXI6IGNvbmZpZy5vdXREaXIsXG4gIH07XG59XG5cbi8qKlxuICogQHBhcmFtIHBhdGggQWJzb2x1dGUgcGF0aCB0byB0aGUgYmFja2dyb3VuZCdzIFRTIGZpbGUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldEJhY2tncm91bmRFbnRyeXBvaW50KFxuICBjb25maWc6IEZpbmRFbnRyeXBvaW50c0NvbmZpZyxcbiAgcGF0aDogc3RyaW5nLFxuKTogUHJvbWlzZTxCYWNrZ3JvdW5kRW50cnlwb2ludD4ge1xuICBjb25zdCB7IG1haW46IF8sIC4uLm9wdGlvbnMgfSA9XG4gICAgYXdhaXQgaW1wb3J0VHNGaWxlPEJhY2tncm91bmRTY3JpcHREZWZpbnRpdGlvbj4oY29uZmlnLnJvb3QsIHBhdGgpO1xuICBpZiAob3B0aW9ucyA9PSBudWxsKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0JhY2tncm91bmQgc2NyaXB0IGRvZXMgbm90IGhhdmUgYSBkZWZhdWx0IGV4cG9ydCcpO1xuICB9XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2JhY2tncm91bmQnLFxuICAgIG5hbWU6ICdiYWNrZ3JvdW5kJyxcbiAgICBpbnB1dFBhdGg6IHBhdGgsXG4gICAgb3V0cHV0RGlyOiBjb25maWcub3V0RGlyLFxuICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gIH07XG59XG5cbi8qKlxuICogQHBhcmFtIHBhdGggQWJzb2x1dGUgcGF0aCB0byB0aGUgY29udGVudCBzY3JpcHQncyBUUyBmaWxlLlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRDb250ZW50U2NyaXB0RW50cnlwb2ludChcbiAgY29uZmlnOiBGaW5kRW50cnlwb2ludHNDb25maWcsXG4gIG5hbWU6IHN0cmluZyxcbiAgcGF0aDogc3RyaW5nLFxuKTogUHJvbWlzZTxDb250ZW50U2NyaXB0RW50cnlwb2ludD4ge1xuICBjb25zdCB7IG1haW46IF8sIC4uLm9wdGlvbnMgfSA9IGF3YWl0IGltcG9ydFRzRmlsZTxDb250ZW50U2NyaXB0RGVmaW5pdGlvbj4oXG4gICAgY29uZmlnLnJvb3QsXG4gICAgcGF0aCxcbiAgKTtcbiAgaWYgKG9wdGlvbnMgPT0gbnVsbCkge1xuICAgIHRocm93IEVycm9yKGBDb250ZW50IHNjcmlwdCAke25hbWV9IGRvZXMgbm90IGhhdmUgYSBkZWZhdWx0IGV4cG9ydGApO1xuICB9XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2NvbnRlbnQtc2NyaXB0JyxcbiAgICBuYW1lOiBnZXRFbnRyeXBvaW50TmFtZShjb25maWcuZW50cnlwb2ludHNEaXIsIHBhdGgpLFxuICAgIGlucHV0UGF0aDogcGF0aCxcbiAgICBvdXRwdXREaXI6IHJlc29sdmUoY29uZmlnLm91dERpciwgJ2NvbnRlbnQtc2NyaXB0cycpLFxuICAgIG9wdGlvbnMsXG4gIH07XG59XG5cbmNvbnN0IFBBVEhfR0xPQl9UT19UWVBFX01BUDogUmVjb3JkPHN0cmluZywgRW50cnlwb2ludFsndHlwZSddIHwgJ2lnbm9yZWQnPiA9IHtcbiAgJ3NhbmRib3guaHRtbCc6ICdzYW5kYm94JyxcbiAgJ3NhbmRib3gvaW5kZXguaHRtbCc6ICdzYW5kYm94JyxcbiAgJyouc2FuZGJveC5odG1sJzogJ3NhbmRib3gnLFxuICAnKi5zYW5kYm94L2luZGV4Lmh0bWwnOiAnc2FuZGJveCcsXG5cbiAgJ2Jvb2ttYXJrcy5odG1sJzogJ2Jvb2ttYXJrcycsXG4gICdib29rbWFya3MvaW5kZXguaHRtbCc6ICdib29rbWFya3MnLFxuXG4gICdoaXN0b3J5Lmh0bWwnOiAnaGlzdG9yeScsXG4gICdoaXN0b3J5L2luZGV4Lmh0bWwnOiAnaGlzdG9yeScsXG5cbiAgJ25ld3RhYi5odG1sJzogJ25ld3RhYicsXG4gICduZXd0YWIvaW5kZXguaHRtbCc6ICduZXd0YWInLFxuXG4gICdzaWRlcGFuZWwuaHRtbCc6ICdzaWRlcGFuZWwnLFxuICAnc2lkZXBhbmVsL2luZGV4Lmh0bWwnOiAnc2lkZXBhbmVsJyxcbiAgJyouc2lkZXBhbmVsLmh0bWwnOiAnc2lkZXBhbmVsJyxcbiAgJyouc2lkZXBhbmVsL2luZGV4Lmh0bWwnOiAnc2lkZXBhbmVsJyxcblxuICAnZGV2dG9vbHMuaHRtbCc6ICdkZXZ0b29scycsXG4gICdkZXZ0b29scy9pbmRleC5odG1sJzogJ2RldnRvb2xzJyxcblxuICAnYmFja2dyb3VuZC50cyc6ICdiYWNrZ3JvdW5kJyxcblxuICAnKi5jb250ZW50LnRzPyh4KSc6ICdjb250ZW50LXNjcmlwdCcsXG4gICcqLmNvbnRlbnQvaW5kZXgudHM/KHgpJzogJ2NvbnRlbnQtc2NyaXB0JyxcblxuICAncG9wdXAuaHRtbCc6ICdwb3B1cCcsXG4gICdwb3B1cC9pbmRleC5odG1sJzogJ3BvcHVwJyxcblxuICAnb3B0aW9ucy5odG1sJzogJ29wdGlvbnMnLFxuICAnb3B0aW9ucy9pbmRleC5odG1sJzogJ29wdGlvbnMnLFxuXG4gICcqLmh0bWwnOiAndW5saXN0ZWQtcGFnZScsXG4gICcqL2luZGV4Lmh0bWwnOiAndW5saXN0ZWQtcGFnZScsXG4gICcqLnRzJzogJ3VubGlzdGVkLXNjcmlwdCcsXG5cbiAgLy8gRG9uJ3Qgd2FybiBhYm91dCBhbnkgZmlsZXMgaW4gc3ViZGlyZWN0b3JpZXMsIGxpa2UgQ1NTIG9yIEpTIGVudHJ5cG9pbnRzIGZvciBIVE1MIGZpbGVzXG4gICcqLyonOiAnaWdub3JlZCcsXG59O1xuXG5leHBvcnQgdHlwZSBGaW5kRW50cnlwb2ludHNDb25maWcgPSBQaWNrPFxuICBJbnRlcm5hbENvbmZpZyxcbiAgJ3Jvb3QnIHwgJ2VudHJ5cG9pbnRzRGlyJyB8ICdvdXREaXInIHwgJ2xvZ2dlcicgfCAnbW9kZScgfCAnY29tbWFuZCdcbj47XG4iLCAiaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcbmltcG9ydCB7XG4gIEJ1aWxkT3V0cHV0LFxuICBCdWlsZFN0ZXBPdXRwdXQsXG4gIEVudHJ5cG9pbnQsXG4gIEVudHJ5cG9pbnRHcm91cCxcbiAgSW50ZXJuYWxDb25maWcsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSAnLi4vdml0ZS1wbHVnaW5zJztcbmltcG9ydCB7IHJlbW92ZUVtcHR5RGlycyB9IGZyb20gJy4uL3V0aWxzL3JlbW92ZUVtcHR5RGlycyc7XG5pbXBvcnQgeyBnZXRFbnRyeXBvaW50QnVuZGxlUGF0aCB9IGZyb20gJy4uL3V0aWxzL2VudHJ5cG9pbnRzJztcbmltcG9ydCBnbG9iIGZyb20gJ2Zhc3QtZ2xvYic7XG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgZGlybmFtZSwgcmVzb2x2ZSB9IGZyb20gJ3BhdGgnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVpbGRFbnRyeXBvaW50cyhcbiAgZ3JvdXBzOiBFbnRyeXBvaW50R3JvdXBbXSxcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbik6IFByb21pc2U8T21pdDxCdWlsZE91dHB1dCwgJ21hbmlmZXN0Jz4+IHtcbiAgY29uc3Qgc3RlcHM6IEJ1aWxkU3RlcE91dHB1dFtdID0gW107XG4gIGZvciAoY29uc3QgZ3JvdXAgb2YgZ3JvdXBzKSB7XG4gICAgY29uc3Qgc3RlcCA9IEFycmF5LmlzQXJyYXkoZ3JvdXApXG4gICAgICA/IGF3YWl0IGJ1aWxkTXVsdGlwbGVFbnRyeXBvaW50cyhncm91cCwgY29uZmlnKVxuICAgICAgOiBhd2FpdCBidWlsZFNpbmdsZUVudHJ5cG9pbnQoZ3JvdXAsIGNvbmZpZyk7XG4gICAgc3RlcHMucHVzaChzdGVwKTtcbiAgfVxuICBjb25zdCBwdWJsaWNBc3NldHMgPSBhd2FpdCBjb3B5UHVibGljRGlyZWN0b3J5KGNvbmZpZyk7XG5cbiAgLy8gUmVtb3ZlIGFueSBlbXB0eSBkaXJlY3RvcmllcyBmcm9tIG1vdmluZyBvdXRwdXRzIGFyb3VuZFxuICBhd2FpdCByZW1vdmVFbXB0eURpcnMoY29uZmlnLm91dERpcik7XG5cbiAgcmV0dXJuIHsgcHVibGljQXNzZXRzLCBzdGVwcyB9O1xufVxuXG4vKipcbiAqIFVzZSBWaXRlJ3MgbGliIG1vZGUgKyBJSUZFIGZvcm1hdCB0byBidW5kbGUgdGhlIGVudHJ5cG9pbnQgdG8gYSBzaW5nbGUgZmlsZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gYnVpbGRTaW5nbGVFbnRyeXBvaW50KFxuICBlbnRyeXBvaW50OiBFbnRyeXBvaW50LFxuICBjb25maWc6IEludGVybmFsQ29uZmlnLFxuKTogUHJvbWlzZTxCdWlsZFN0ZXBPdXRwdXQ+IHtcbiAgLy8gU2hvdWxkIHRoaXMgZW50cnlwb2ludCBiZSB3cmFwcGVkIGJ5IHRoZSB2aXRlLXBsdWdpbnMvdmlydHVhbEVudHJ5cG9pbnQgcGx1Z2luP1xuICBjb25zdCBpc1ZpcnR1YWwgPSBbJ2JhY2tncm91bmQnLCAnY29udGVudC1zY3JpcHQnXS5pbmNsdWRlcyhlbnRyeXBvaW50LnR5cGUpO1xuICBjb25zdCBlbnRyeSA9IGlzVmlydHVhbFxuICAgID8gYHZpcnR1YWw6d3h0LSR7ZW50cnlwb2ludC50eXBlfT8ke2VudHJ5cG9pbnQuaW5wdXRQYXRofWBcbiAgICA6IGVudHJ5cG9pbnQuaW5wdXRQYXRoO1xuXG4gIGNvbnN0IGxpYk1vZGU6IHZpdGUuSW5saW5lQ29uZmlnID0ge1xuICAgIGJ1aWxkOiB7XG4gICAgICBsaWI6IHtcbiAgICAgICAgZW50cnksXG4gICAgICAgIGZvcm1hdHM6IFsnaWlmZSddLFxuICAgICAgICBuYW1lOiBlbnRyeXBvaW50Lm5hbWUsXG4gICAgICAgIGZpbGVOYW1lOiBlbnRyeXBvaW50Lm5hbWUsXG4gICAgICB9LFxuICAgICAgcm9sbHVwT3B0aW9uczoge1xuICAgICAgICBvdXRwdXQ6IHtcbiAgICAgICAgICAvLyBUaGVyZSdzIG9ubHkgYSBzaW5nbGUgb3V0cHV0IGZvciB0aGlzIGJ1aWxkLCBzbyB3ZSB1c2UgdGhlIGRlc2lyZWQgYnVuZGxlIHBhdGggZm9yIHRoZVxuICAgICAgICAgIC8vIGVudHJ5IG91dHB1dCAobGlrZSBcImNvbnRlbnQtc2NyaXB0cy9vdmVybGF5LmpzXCIpXG4gICAgICAgICAgZW50cnlGaWxlTmFtZXM6IGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoKFxuICAgICAgICAgICAgZW50cnlwb2ludCxcbiAgICAgICAgICAgIGNvbmZpZy5vdXREaXIsXG4gICAgICAgICAgICAnLmpzJyxcbiAgICAgICAgICApLFxuICAgICAgICAgIC8vIE91dHB1dCBjb250ZW50IHNjcmlwdCBDU1MgdG8gYXNzZXRzLyB3aXRoIGEgaGFzaCB0byBwcmV2ZW50IGNvbmZsaWN0cy4gRGVmYXVsdHMgdG9cbiAgICAgICAgICAvLyBcIltuYW1lXS5bZXh0XVwiIGluIGxpYiBtb2RlLCB3aGljaCB1c3VhbGx5IHJlc3VsdHMgaW4gXCJzdHlsZS5jc3NcIi4gVGhhdCBtZWFucyBtdWx0aXBsZVxuICAgICAgICAgIC8vIGNvbnRlbnQgc2NyaXB0cyB3aXRoIHN0eWxlcyB3b3VsZCBvdmVyd3JpdGUgZWFjaCBvdGhlciBpZiBpdCB3ZXJlbid0IGNoYW5nZWQgYmVsb3cuXG4gICAgICAgICAgYXNzZXRGaWxlTmFtZXM6IGBhc3NldHMvJHtlbnRyeXBvaW50Lm5hbWV9LltleHRdYCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbiAgY29uc3QgZW50cnlDb25maWcgPSB2aXRlLm1lcmdlQ29uZmlnKFxuICAgIGxpYk1vZGUsXG4gICAgY29uZmlnLnZpdGUsXG4gICkgYXMgdml0ZS5JbmxpbmVDb25maWc7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdml0ZS5idWlsZChlbnRyeUNvbmZpZyk7XG4gIHJldHVybiB7XG4gICAgZW50cnlwb2ludHM6IGVudHJ5cG9pbnQsXG4gICAgY2h1bmtzOiBnZXRCdWlsZE91dHB1dENodW5rcyhyZXN1bHQpLFxuICB9O1xufVxuXG4vKipcbiAqIFVzZSBWaXRlJ3MgbXVsdGlwYWdlIGJ1aWxkIHRvIGJ1bmRsZSBhbGwgdGhlIGVudHJ5cG9pbnRzIGluIGEgc2luZ2xlIHN0ZXAuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGJ1aWxkTXVsdGlwbGVFbnRyeXBvaW50cyhcbiAgZW50cnlwb2ludHM6IEVudHJ5cG9pbnRbXSxcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbik6IFByb21pc2U8QnVpbGRTdGVwT3V0cHV0PiB7XG4gIGNvbnN0IG11bHRpUGFnZTogdml0ZS5JbmxpbmVDb25maWcgPSB7XG4gICAgcGx1Z2luczogW3BsdWdpbnMubXVsdGlwYWdlTW92ZShlbnRyeXBvaW50cywgY29uZmlnKV0sXG4gICAgYnVpbGQ6IHtcbiAgICAgIHJvbGx1cE9wdGlvbnM6IHtcbiAgICAgICAgaW5wdXQ6IGVudHJ5cG9pbnRzLnJlZHVjZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PigoaW5wdXQsIGVudHJ5KSA9PiB7XG4gICAgICAgICAgaW5wdXRbZW50cnkubmFtZV0gPSBlbnRyeS5pbnB1dFBhdGg7XG4gICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICB9LCB7fSksXG4gICAgICAgIG91dHB1dDoge1xuICAgICAgICAgIC8vIEluY2x1ZGUgYSBoYXNoIHRvIHByZXZlbnQgY29uZmxpY3RzXG4gICAgICAgICAgY2h1bmtGaWxlTmFtZXM6ICdjaHVua3MvW25hbWVdLVtoYXNoXS5qcycsXG4gICAgICAgICAgLy8gSW5jbHVkZSBhIGhhc2ggdG8gcHJldmVudCBjb25mbGljdHNcbiAgICAgICAgICBlbnRyeUZpbGVOYW1lczogJ2NodW5rcy9bbmFtZV0tW2hhc2hdLmpzJyxcbiAgICAgICAgICAvLyBXZSBjYW4ndCBjb250cm9sIHRoZSBcIm5hbWVcIiwgc28gd2UgbmVlZCBhIGhhc2ggdG8gcHJldmVudCBjb25mbGljdHNcbiAgICAgICAgICBhc3NldEZpbGVOYW1lczogJ2Fzc2V0cy9bbmFtZV0tW2hhc2hdLltleHRdJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBlbnRyeUNvbmZpZyA9IHZpdGUubWVyZ2VDb25maWcoXG4gICAgbXVsdGlQYWdlLFxuICAgIGNvbmZpZy52aXRlLFxuICApIGFzIHZpdGUuSW5saW5lQ29uZmlnO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZpdGUuYnVpbGQoZW50cnlDb25maWcpO1xuICByZXR1cm4ge1xuICAgIGVudHJ5cG9pbnRzLFxuICAgIGNodW5rczogZ2V0QnVpbGRPdXRwdXRDaHVua3MocmVzdWx0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0QnVpbGRPdXRwdXRDaHVua3MoXG4gIHJlc3VsdDogQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiB2aXRlLmJ1aWxkPj4sXG4pOiBCdWlsZFN0ZXBPdXRwdXRbJ2NodW5rcyddIHtcbiAgaWYgKCdvbicgaW4gcmVzdWx0KSB0aHJvdyBFcnJvcignd3h0IGRvZXMgbm90IHN1cHBvcnQgdml0ZSB3YXRjaCBtb2RlLicpO1xuICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSByZXR1cm4gcmVzdWx0LmZsYXRNYXAoKHsgb3V0cHV0IH0pID0+IG91dHB1dCk7XG4gIHJldHVybiByZXN1bHQub3V0cHV0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBjb3B5UHVibGljRGlyZWN0b3J5KFxuICBjb25maWc6IEludGVybmFsQ29uZmlnLFxuKTogUHJvbWlzZTxCdWlsZE91dHB1dFsncHVibGljQXNzZXRzJ10+IHtcbiAgY29uc3QgcHVibGljQXNzZXRzOiBCdWlsZE91dHB1dFsncHVibGljQXNzZXRzJ10gPSBbXTtcbiAgaWYgKCEoYXdhaXQgZnMuZXhpc3RzKGNvbmZpZy5wdWJsaWNEaXIpKSkgcmV0dXJuIHB1YmxpY0Fzc2V0cztcblxuICBjb25zdCBmaWxlcyA9IGF3YWl0IGdsb2IoJyoqLyonLCB7IGN3ZDogY29uZmlnLnB1YmxpY0RpciB9KTtcblxuICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICBjb25zdCBzcmNQYXRoID0gcmVzb2x2ZShjb25maWcucHVibGljRGlyLCBmaWxlKTtcbiAgICBjb25zdCBvdXRQYXRoID0gcmVzb2x2ZShjb25maWcub3V0RGlyLCBmaWxlKTtcblxuICAgIGF3YWl0IGZzLmVuc3VyZURpcihkaXJuYW1lKG91dFBhdGgpKTtcbiAgICBhd2FpdCBmcy5jb3B5RmlsZShzcmNQYXRoLCBvdXRQYXRoKTtcbiAgICBwdWJsaWNBc3NldHMucHVzaCh7XG4gICAgICB0eXBlOiAnYXNzZXQnLFxuICAgICAgZmlsZU5hbWU6IGZpbGUsXG4gICAgICBuYW1lOiBmaWxlLFxuICAgICAgbmVlZHNDb2RlUmVmZXJlbmNlOiBmYWxzZSxcbiAgICAgIHNvdXJjZTogYXdhaXQgZnMucmVhZEZpbGUoc3JjUGF0aCksXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcHVibGljQXNzZXRzO1xufVxuIiwgImltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlbW92ZUVtcHR5RGlycyhkaXI6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBmaWxlcyA9IGF3YWl0IGZzLnJlYWRkaXIoZGlyKTtcbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oZGlyLCBmaWxlKTtcbiAgICBjb25zdCBzdGF0cyA9IGF3YWl0IGZzLnN0YXQoZmlsZVBhdGgpO1xuICAgIGlmIChzdGF0cy5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICBhd2FpdCByZW1vdmVFbXB0eURpcnMoZmlsZVBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgZnMucm1kaXIoZGlyKTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gbm9vcCBvbiBmYWlsdXJlIC0gdGhpcyBtZWFucyB0aGUgZGlyZWN0b3J5IHdhcyBub3QgZW1wdHkuXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBFbnRyeXBvaW50IH0gZnJvbSAnLi4vLi4nO1xuaW1wb3J0IHsgTWFuaWZlc3QgfSBmcm9tICd3ZWJleHRlbnNpb24tcG9seWZpbGwnO1xuaW1wb3J0IHtcbiAgQmFja2dyb3VuZEVudHJ5cG9pbnQsXG4gIEJ1aWxkT3V0cHV0LFxuICBDb250ZW50U2NyaXB0RW50cnlwb2ludCxcbiAgSW50ZXJuYWxDb25maWcsXG4gIE9wdGlvbnNFbnRyeXBvaW50LFxuICBQb3B1cEVudHJ5cG9pbnQsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBnZXRFbnRyeXBvaW50QnVuZGxlUGF0aCB9IGZyb20gJy4vZW50cnlwb2ludHMnO1xuaW1wb3J0IHsgQ29udGVudFNlY3VyaXR5UG9saWN5IH0gZnJvbSAnLi9Db250ZW50U2VjdXJpdHlQb2xpY3knO1xuXG4vKipcbiAqIFdyaXRlcyB0aGUgbWFuaWZlc3QgdG8gdGhlIG91dHB1dCBkaXJlY3RvcnkgYW5kIHRoZSBidWlsZCBvdXRwdXQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZU1hbmlmZXN0KFxuICBtYW5pZmVzdDogTWFuaWZlc3QuV2ViRXh0ZW5zaW9uTWFuaWZlc3QsXG4gIG91dHB1dDogQnVpbGRPdXRwdXQsXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qgc3RyID1cbiAgICBjb25maWcubW9kZSA9PT0gJ3Byb2R1Y3Rpb24nXG4gICAgICA/IEpTT04uc3RyaW5naWZ5KG1hbmlmZXN0KVxuICAgICAgOiBKU09OLnN0cmluZ2lmeShtYW5pZmVzdCwgbnVsbCwgMik7XG5cbiAgYXdhaXQgZnMuZW5zdXJlRGlyKGNvbmZpZy5vdXREaXIpO1xuICBhd2FpdCBmcy53cml0ZUZpbGUocmVzb2x2ZShjb25maWcub3V0RGlyLCAnbWFuaWZlc3QuanNvbicpLCBzdHIsICd1dGYtOCcpO1xuXG4gIG91dHB1dC5wdWJsaWNBc3NldHMudW5zaGlmdCh7XG4gICAgdHlwZTogJ2Fzc2V0JyxcbiAgICBmaWxlTmFtZTogJ21hbmlmZXN0Lmpzb24nLFxuICAgIG5hbWU6ICdtYW5pZmVzdCcsXG4gICAgbmVlZHNDb2RlUmVmZXJlbmNlOiBmYWxzZSxcbiAgICBzb3VyY2U6IHN0cixcbiAgfSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBtYW5pZmVzdCBiYXNlZCBvbiB0aGUgY29uZmlnIGFuZCBlbnRyeXBvaW50cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlTWFpbmZlc3QoXG4gIGVudHJ5cG9pbnRzOiBFbnRyeXBvaW50W10sXG4gIGJ1aWxkT3V0cHV0OiBPbWl0PEJ1aWxkT3V0cHV0LCAnbWFuaWZlc3QnPixcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbik6IFByb21pc2U8TWFuaWZlc3QuV2ViRXh0ZW5zaW9uTWFuaWZlc3Q+IHtcbiAgY29uc3QgcGtnID0gYXdhaXQgZ2V0UGFja2FnZUpzb24oY29uZmlnKTtcbiAgaWYgKHBrZy52ZXJzaW9uID09IG51bGwpXG4gICAgdGhyb3cgRXJyb3IoJ3BhY2thZ2UuanNvbiBkb2VzIG5vdCBpbmNsdWRlIGEgdmVyc2lvbicpO1xuICBpZiAocGtnLm5hbWUgPT0gbnVsbCkgdGhyb3cgRXJyb3IoJ3BhY2thZ2UuanNvbiBkb2VzIG5vdCBpbmNsdWRlIGEgbmFtZScpO1xuICBpZiAocGtnLmRlc2NyaXB0aW9uID09IG51bGwpXG4gICAgdGhyb3cgRXJyb3IoJ3BhY2thZ2UuanNvbiBkb2VzIG5vdCBpbmNsdWRlIGEgZGVzY3JpcHRpb24nKTtcblxuICBjb25zdCBtYW5pZmVzdDogTWFuaWZlc3QuV2ViRXh0ZW5zaW9uTWFuaWZlc3QgPSB7XG4gICAgbWFuaWZlc3RfdmVyc2lvbjogY29uZmlnLm1hbmlmZXN0VmVyc2lvbixcbiAgICBuYW1lOiBwa2cubmFtZSxcbiAgICBzaG9ydF9uYW1lOiBwa2cuc2hvcnROYW1lLFxuICAgIHZlcnNpb246IHNpbXBsaWZ5VmVyc2lvbihwa2cudmVyc2lvbiksXG4gICAgdmVyc2lvbl9uYW1lOiBjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnID8gdW5kZWZpbmVkIDogcGtnLnZlcnNpb24sXG4gICAgLi4uY29uZmlnLm1hbmlmZXN0LFxuICB9O1xuXG4gIGFkZEVudHJ5cG9pbnRzKG1hbmlmZXN0LCBlbnRyeXBvaW50cywgYnVpbGRPdXRwdXQsIGNvbmZpZyk7XG5cbiAgaWYgKGNvbmZpZy5jb21tYW5kID09PSAnc2VydmUnKSBhZGREZXZNb2RlQ3NwKG1hbmlmZXN0LCBjb25maWcpO1xuXG4gIHJldHVybiBtYW5pZmVzdDtcbn1cblxuLyoqXG4gKiBSZWFkIHRoZSBwYWNrYWdlLmpzb24gZnJvbSB0aGUgY3VycmVudCBkaXJlY3RvcnkuXG4gKlxuICogVE9ETzogbG9vayBpbiByb290IGFuZCB1cCBkaXJlY3RvcmllcyB1bnRpbCBpdCdzIGZvdW5kXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFBhY2thZ2VKc29uKGNvbmZpZzogSW50ZXJuYWxDb25maWcpOiBQcm9taXNlPGFueT4ge1xuICByZXR1cm4gYXdhaXQgZnMucmVhZEpzb24ocmVzb2x2ZShjb25maWcucm9vdCwgJ3BhY2thZ2UuanNvbicpKTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIHN1ZmZpeGVzIGZyb20gdGhlIHZlcnNpb24sIGxpa2UgWC5ZLlotYWxwaGExICh3aGljaCBicm9zZXJzIGRvbid0IGFsbG93KSwgc28gaXQncyBhXG4gKiBzaW1wbGUgdmVyc2lvbiBudW1iZXIsIGxpa2UgWCBvciBYLlkgb3IgWC5ZLlosIHdoaWNoIGJyb3dzZXJzIGFsbG93LlxuICovXG5mdW5jdGlvbiBzaW1wbGlmeVZlcnNpb24odmVyc2lvbk5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIFJlZ2V4IGFkYXB0ZWQgZnJvbSBoZXJlOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL01vemlsbGEvQWRkLW9ucy9XZWJFeHRlbnNpb25zL21hbmlmZXN0Lmpzb24vdmVyc2lvbiN2ZXJzaW9uX2Zvcm1hdFxuXG4gIGNvbnN0IHZlcnNpb24gPSAvXigoMHxbMS05XVswLTldezAsOH0pKFsuXSgwfFsxLTldWzAtOV17MCw4fSkpezAsM30pLiokLy5leGVjKFxuICAgIHZlcnNpb25OYW1lLFxuICApPy5bMV07XG5cbiAgaWYgKHZlcnNpb24gPT0gbnVsbClcbiAgICB0aHJvdyBFcnJvcihcbiAgICAgIGBDYW5ub3Qgc2ltcGxpZnkgcGFja2FnZS5qc29uIHZlcnNpb24gXCIke3ZlcnNpb25OYW1lfVwiIHRvIGEgdmFsaWQgZXh0ZW5zaW9uIHZlcnNpb24sIFwiWC5ZLlpcImAsXG4gICAgKTtcblxuICByZXR1cm4gdmVyc2lvbjtcbn1cblxuZnVuY3Rpb24gYWRkRW50cnlwb2ludHMoXG4gIG1hbmlmZXN0OiBNYW5pZmVzdC5XZWJFeHRlbnNpb25NYW5pZmVzdCxcbiAgZW50cnlwb2ludHM6IEVudHJ5cG9pbnRbXSxcbiAgYnVpbGRPdXRwdXQ6IE9taXQ8QnVpbGRPdXRwdXQsICdtYW5pZmVzdCc+LFxuICBjb25maWc6IEludGVybmFsQ29uZmlnLFxuKTogdm9pZCB7XG4gIGNvbnN0IGVudHJpZXNCeVR5cGUgPSBlbnRyeXBvaW50cy5yZWR1Y2U8XG4gICAgUGFydGlhbDxSZWNvcmQ8RW50cnlwb2ludFsndHlwZSddLCBFbnRyeXBvaW50W10+PlxuICA+KChtYXAsIGVudHJ5cG9pbnQpID0+IHtcbiAgICBtYXBbZW50cnlwb2ludC50eXBlXSA/Pz0gW107XG4gICAgbWFwW2VudHJ5cG9pbnQudHlwZV0/LnB1c2goZW50cnlwb2ludCk7XG4gICAgcmV0dXJuIG1hcDtcbiAgfSwge30pO1xuXG4gIGNvbnN0IGJhY2tncm91bmQgPSBlbnRyaWVzQnlUeXBlWydiYWNrZ3JvdW5kJ10/LlswXSBhc1xuICAgIHwgQmFja2dyb3VuZEVudHJ5cG9pbnRcbiAgICB8IHVuZGVmaW5lZDtcbiAgY29uc3QgYm9va21hcmtzID0gZW50cmllc0J5VHlwZVsnYm9va21hcmtzJ10/LlswXTtcbiAgY29uc3QgY29udGVudFNjcmlwdHMgPSBlbnRyaWVzQnlUeXBlWydjb250ZW50LXNjcmlwdCddIGFzXG4gICAgfCBDb250ZW50U2NyaXB0RW50cnlwb2ludFtdXG4gICAgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IGRldnRvb2xzID0gZW50cmllc0J5VHlwZVsnZGV2dG9vbHMnXT8uWzBdO1xuICBjb25zdCBoaXN0b3J5ID0gZW50cmllc0J5VHlwZVsnaGlzdG9yeSddPy5bMF07XG4gIGNvbnN0IG5ld3RhYiA9IGVudHJpZXNCeVR5cGVbJ25ld3RhYiddPy5bMF07XG4gIGNvbnN0IG9wdGlvbnMgPSBlbnRyaWVzQnlUeXBlWydvcHRpb25zJ10/LlswXSBhc1xuICAgIHwgT3B0aW9uc0VudHJ5cG9pbnRcbiAgICB8IHVuZGVmaW5lZDtcbiAgY29uc3QgcG9wdXAgPSBlbnRyaWVzQnlUeXBlWydwb3B1cCddPy5bMF0gYXMgUG9wdXBFbnRyeXBvaW50IHwgdW5kZWZpbmVkO1xuICBjb25zdCBzYW5kYm94ZXMgPSBlbnRyaWVzQnlUeXBlWydzYW5kYm94J107XG4gIGNvbnN0IHNpZGVwYW5lbHMgPSBlbnRyaWVzQnlUeXBlWydzaWRlcGFuZWwnXTtcblxuICBpZiAoYmFja2dyb3VuZCkge1xuICAgIGNvbnN0IHNjcmlwdCA9IGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoKGJhY2tncm91bmQsIGNvbmZpZy5vdXREaXIsICcuanMnKTtcbiAgICBpZiAobWFuaWZlc3QubWFuaWZlc3RfdmVyc2lvbiA9PT0gMykge1xuICAgICAgbWFuaWZlc3QuYmFja2dyb3VuZCA9IHtcbiAgICAgICAgdHlwZTogYmFja2dyb3VuZC5vcHRpb25zLnR5cGUsXG4gICAgICAgIHNlcnZpY2Vfd29ya2VyOiBzY3JpcHQsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBtYW5pZmVzdC5iYWNrZ3JvdW5kID0ge1xuICAgICAgICBwZXJzaXN0ZW50OiBiYWNrZ3JvdW5kLm9wdGlvbnMucGVyc2lzdGVudCxcbiAgICAgICAgc2NyaXB0czogW3NjcmlwdF0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGlmIChib29rbWFya3MpIHtcbiAgICBpZiAoY29uZmlnLmJyb3dzZXIgPT09ICdmaXJlZm94Jykge1xuICAgICAgY29uZmlnLmxvZ2dlci53YXJuKFxuICAgICAgICAnQm9va21hcmtzIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IEZpcmVmb3guIGNocm9tZV91cmxfb3ZlcnJpZGVzLmJvb2ttYXJrcyB3YXMgbm90IGFkZGVkIHRvIHRoZSBtYW5pZmVzdCcsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYW5pZmVzdC5jaHJvbWVfdXJsX292ZXJyaWRlcyA/Pz0ge307XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiBib29rbWFya3MgaXMgdW50eXBlZCBpbiB3ZWJleHRlbnNpb24tcG9seWZpbGwsIGJ1dCBzdXBwb3J0ZWQgYnkgY2hyb21lXG4gICAgICBtYW5pZmVzdC5jaHJvbWVfdXJsX292ZXJyaWRlcy5ib29rbWFya3MgPSBnZXRFbnRyeXBvaW50QnVuZGxlUGF0aChcbiAgICAgICAgYm9va21hcmtzLFxuICAgICAgICBjb25maWcub3V0RGlyLFxuICAgICAgICAnLmh0bWwnLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaGlzdG9yeSkge1xuICAgIGlmIChjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnKSB7XG4gICAgICBjb25maWcubG9nZ2VyLndhcm4oXG4gICAgICAgICdCb29rbWFya3MgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgRmlyZWZveC4gY2hyb21lX3VybF9vdmVycmlkZXMuaGlzdG9yeSB3YXMgbm90IGFkZGVkIHRvIHRoZSBtYW5pZmVzdCcsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYW5pZmVzdC5jaHJvbWVfdXJsX292ZXJyaWRlcyA/Pz0ge307XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiBoaXN0b3J5IGlzIHVudHlwZWQgaW4gd2ViZXh0ZW5zaW9uLXBvbHlmaWxsLCBidXQgc3VwcG9ydGVkIGJ5IGNocm9tZVxuICAgICAgbWFuaWZlc3QuY2hyb21lX3VybF9vdmVycmlkZXMuaGlzdG9yeSA9IGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoKFxuICAgICAgICBoaXN0b3J5LFxuICAgICAgICBjb25maWcub3V0RGlyLFxuICAgICAgICAnLmh0bWwnLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBpZiAobmV3dGFiKSB7XG4gICAgbWFuaWZlc3QuY2hyb21lX3VybF9vdmVycmlkZXMgPz89IHt9O1xuICAgIG1hbmlmZXN0LmNocm9tZV91cmxfb3ZlcnJpZGVzLm5ld3RhYiA9IGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoKFxuICAgICAgbmV3dGFiLFxuICAgICAgY29uZmlnLm91dERpcixcbiAgICAgICcuaHRtbCcsXG4gICAgKTtcbiAgfVxuXG4gIGlmIChwb3B1cCkge1xuICAgIGNvbnN0IGRlZmF1bHRfcG9wdXAgPSBnZXRFbnRyeXBvaW50QnVuZGxlUGF0aChcbiAgICAgIHBvcHVwLFxuICAgICAgY29uZmlnLm91dERpcixcbiAgICAgICcuaHRtbCcsXG4gICAgKTtcbiAgICBjb25zdCBvcHRpb25zOiBNYW5pZmVzdC5BY3Rpb25NYW5pZmVzdCA9IHtcbiAgICAgIGRlZmF1bHRfaWNvbjogcG9wdXAub3B0aW9ucy5kZWZhdWx0SWNvbixcbiAgICAgIGRlZmF1bHRfdGl0bGU6IHBvcHVwLm9wdGlvbnMuZGVmYXVsdFRpdGxlLFxuICAgIH07XG4gICAgaWYgKG1hbmlmZXN0Lm1hbmlmZXN0X3ZlcnNpb24gPT09IDMpIHtcbiAgICAgIG1hbmlmZXN0LmFjdGlvbiA9IHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgZGVmYXVsdF9wb3B1cCxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIG1hbmlmZXN0W3BvcHVwLm9wdGlvbnMubXYyS2V5ID8/ICdicm93c2VyX2FjdGlvbiddID0ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBkZWZhdWx0X3BvcHVwLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBpZiAoZGV2dG9vbHMpIHtcbiAgICBtYW5pZmVzdC5kZXZ0b29sc19wYWdlID0gZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGgoXG4gICAgICBkZXZ0b29scyxcbiAgICAgIGNvbmZpZy5vdXREaXIsXG4gICAgICAnLmh0bWwnLFxuICAgICk7XG4gIH1cblxuICBpZiAob3B0aW9ucykge1xuICAgIGNvbnN0IHBhZ2UgPSBnZXRFbnRyeXBvaW50QnVuZGxlUGF0aChvcHRpb25zLCBjb25maWcub3V0RGlyLCAnLmh0bWwnKTtcbiAgICBtYW5pZmVzdC5vcHRpb25zX3VpID0ge1xuICAgICAgb3Blbl9pbl90YWI6IG9wdGlvbnMub3B0aW9ucy5vcGVuSW5UYWIsXG4gICAgICBicm93c2VyX3N0eWxlOlxuICAgICAgICBjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnID8gb3B0aW9ucy5vcHRpb25zLmJyb3dzZXJTdHlsZSA6IHVuZGVmaW5lZCxcbiAgICAgIGNocm9tZV9zdHlsZTpcbiAgICAgICAgY29uZmlnLmJyb3dzZXIgIT09ICdmaXJlZm94JyA/IG9wdGlvbnMub3B0aW9ucy5jaHJvbWVTdHlsZSA6IHVuZGVmaW5lZCxcbiAgICAgIHBhZ2UsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChzYW5kYm94ZXM/Lmxlbmd0aCkge1xuICAgIGlmIChjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnKSB7XG4gICAgICBjb25maWcubG9nZ2VyLndhcm4oXG4gICAgICAgICdTYW5kYm94ZWQgcGFnZXMgbm90IHN1cHBvcnRlZCBieSBGaXJlZm94LiBzYW5kYm94LnBhZ2VzIHdhcyBub3QgYWRkZWQgdG8gdGhlIG1hbmlmZXN0JyxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3I6IHNhbmRib3ggbm90IHR5cGVkXG4gICAgICBtYW5pZmVzdC5zYW5kYm94ID0ge1xuICAgICAgICBwYWdlczogc2FuZGJveGVzLm1hcCgoZW50cnkpID0+XG4gICAgICAgICAgZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGgoZW50cnksIGNvbmZpZy5vdXREaXIsICcuaHRtbCcpLFxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBpZiAoc2lkZXBhbmVscz8ubGVuZ3RoKSB7XG4gICAgY29uc3QgZGVmYXVsdFNpZGVwYW5lbCA9XG4gICAgICBzaWRlcGFuZWxzLmZpbmQoKGVudHJ5KSA9PiBlbnRyeS5uYW1lID09PSAnc2lkZXBhbmVsJykgPz8gc2lkZXBhbmVsc1swXTtcbiAgICBjb25zdCBwYWdlID0gZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGgoXG4gICAgICBkZWZhdWx0U2lkZXBhbmVsLFxuICAgICAgY29uZmlnLm91dERpcixcbiAgICAgICcuaHRtbCcsXG4gICAgKTtcblxuICAgIGlmIChjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnKSB7XG4gICAgICBtYW5pZmVzdC5zaWRlYmFyX2FjdGlvbiA9IHtcbiAgICAgICAgLy8gVE9ETzogQWRkIG9wdGlvbnMgdG8gc2lkZSBwYW5lbFxuICAgICAgICAvLyAuLi5kZWZhdWx0U2lkZXBhbmVsLm9wdGlvbnMsXG4gICAgICAgIGRlZmF1bHRfcGFuZWw6IHBhZ2UsXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoY29uZmlnLm1hbmlmZXN0VmVyc2lvbiA9PT0gMykge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogVW50eXBlZFxuICAgICAgbWFuaWZlc3Quc2lkZV9wYW5lbCA9IHtcbiAgICAgICAgZGVmYXVsdF9wYXRoOiBwYWdlLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnLmxvZ2dlci53YXJuKFxuICAgICAgICAnU2lkZSBwYW5lbCBub3Qgc3VwcG9ydGVkIGJ5IENocm9taXVtIHVzaW5nIE1WMi4gc2lkZV9wYW5lbC5kZWZhdWx0X3BhdGggd2FzIG5vdCBhZGRlZCB0byB0aGUgbWFuaWZlc3QnLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBpZiAoY29udGVudFNjcmlwdHM/Lmxlbmd0aCkge1xuICAgIGlmIChjb25maWcuY29tbWFuZCA9PT0gJ3NlcnZlJykge1xuICAgICAgY29uc3QgcGVybWlzc2lvbnNLZXkgPVxuICAgICAgICBjb25maWcubWFuaWZlc3RWZXJzaW9uID09PSAyID8gJ3Blcm1pc3Npb25zJyA6ICdob3N0X3Blcm1pc3Npb25zJztcbiAgICAgIGNvbnN0IGhvc3RQZXJtaXNzaW9ucyA9IG5ldyBTZXQ8c3RyaW5nPihtYW5pZmVzdFtwZXJtaXNzaW9uc0tleV0gPz8gW10pO1xuICAgICAgY29udGVudFNjcmlwdHMuZm9yRWFjaCgoc2NyaXB0KSA9PiB7XG4gICAgICAgIHNjcmlwdC5vcHRpb25zLm1hdGNoZXMuZm9yRWFjaCgobWF0Y2hQYXR0ZXJuKSA9PiB7XG4gICAgICAgICAgaG9zdFBlcm1pc3Npb25zLmFkZChtYXRjaFBhdHRlcm4pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgbWFuaWZlc3RbcGVybWlzc2lvbnNLZXldID0gQXJyYXkuZnJvbShob3N0UGVybWlzc2lvbnMpLnNvcnQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaGFzaFRvRW50cnlwb2ludHNNYXAgPSBjb250ZW50U2NyaXB0cy5yZWR1Y2UoKG1hcCwgc2NyaXB0KSA9PiB7XG4gICAgICAgIGNvbnN0IGhhc2ggPSBKU09OLnN0cmluZ2lmeShzY3JpcHQub3B0aW9ucyk7XG4gICAgICAgIGlmICghbWFwLmhhcyhoYXNoKSkge1xuICAgICAgICAgIG1hcC5zZXQoaGFzaCwgW3NjcmlwdF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1hcC5nZXQoaGFzaCk/LnB1c2goc2NyaXB0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWFwO1xuICAgICAgfSwgbmV3IE1hcDxzdHJpbmcsIENvbnRlbnRTY3JpcHRFbnRyeXBvaW50W10+KCkpO1xuXG4gICAgICBtYW5pZmVzdC5jb250ZW50X3NjcmlwdHMgPSBBcnJheS5mcm9tKGhhc2hUb0VudHJ5cG9pbnRzTWFwLmVudHJpZXMoKSkubWFwKFxuICAgICAgICAoWywgc2NyaXB0c10pID0+ICh7XG4gICAgICAgICAgLi4uc2NyaXB0c1swXS5vcHRpb25zLFxuICAgICAgICAgIC8vIFRPT0Q6IFNvcnRpbmcgY3NzIGFuZCBqcyBhcnJheXMgaGVyZSBzbyB3ZSBnZXQgY29uc2lzdGVudCB0ZXN0IHJlc3VsdHMuLi4gYnV0IHdlXG4gICAgICAgICAgLy8gc2hvdWxkbid0IGhhdmUgdG8uIFdoZXJlIGlzIHRoZSBpbmNvbnNpc3RlbmN5IGNvbWluZyBmcm9tP1xuICAgICAgICAgIGNzczogZ2V0Q29udGVudFNjcmlwdENzc0ZpbGVzKHNjcmlwdHMsIGJ1aWxkT3V0cHV0KT8uc29ydCgpLFxuICAgICAgICAgIGpzOiBzY3JpcHRzXG4gICAgICAgICAgICAubWFwKChlbnRyeSkgPT5cbiAgICAgICAgICAgICAgZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGgoZW50cnksIGNvbmZpZy5vdXREaXIsICcuanMnKSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zb3J0KCksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkRGV2TW9kZUNzcChcbiAgbWFuaWZlc3Q6IE1hbmlmZXN0LldlYkV4dGVuc2lvbk1hbmlmZXN0LFxuICBjb25maWc6IEludGVybmFsQ29uZmlnLFxuKTogdm9pZCB7XG4gIGNvbnN0IHBlcm1pc3Npb24gPSBgaHR0cDovLyR7Y29uZmlnLnNlcnZlcj8uaG9zdG5hbWUgPz8gJyd9LypgO1xuICBjb25zdCBhbGxvd2VkQ3NwID0gY29uZmlnLnNlcnZlcj8ub3JpZ2luID8/ICdodHRwOi8vbG9jYWxob3N0OionO1xuXG4gIGlmIChtYW5pZmVzdC5tYW5pZmVzdF92ZXJzaW9uID09PSAzKSB7XG4gICAgbWFuaWZlc3QuaG9zdF9wZXJtaXNzaW9ucyA/Pz0gW107XG4gICAgaWYgKCFtYW5pZmVzdC5ob3N0X3Blcm1pc3Npb25zLmluY2x1ZGVzKHBlcm1pc3Npb24pKVxuICAgICAgbWFuaWZlc3QuaG9zdF9wZXJtaXNzaW9ucy5wdXNoKHBlcm1pc3Npb24pO1xuICB9IGVsc2Uge1xuICAgIG1hbmlmZXN0LnBlcm1pc3Npb25zID8/PSBbXTtcbiAgICBpZiAoIW1hbmlmZXN0LnBlcm1pc3Npb25zLmluY2x1ZGVzKHBlcm1pc3Npb24pKVxuICAgICAgbWFuaWZlc3QucGVybWlzc2lvbnMucHVzaChwZXJtaXNzaW9uKTtcbiAgfVxuXG4gIGNvbnN0IGNzcCA9IG5ldyBDb250ZW50U2VjdXJpdHlQb2xpY3koXG4gICAgbWFuaWZlc3QubWFuaWZlc3RfdmVyc2lvbiA9PT0gM1xuICAgICAgPyAvLyBAdHMtZXhwZWN0LWVycm9yOiBleHRlbnNpb25fcGFnZXMgaXMgbm90IHR5cGVkXG4gICAgICAgIG1hbmlmZXN0LmNvbnRlbnRfc2VjdXJpdHlfcG9saWN5Py5leHRlbnNpb25fcGFnZXMgPz9cbiAgICAgICAgXCJzY3JpcHQtc3JjICdzZWxmJyAnd2FzbS11bnNhZmUtZXZhbCc7IG9iamVjdC1zcmMgJ3NlbGYnO1wiIC8vIGRlZmF1bHQgQ1NQIGZvciBNVjNcbiAgICAgIDogbWFuaWZlc3QuY29udGVudF9zZWN1cml0eV9wb2xpY3kgPz9cbiAgICAgICAgXCJzY3JpcHQtc3JjICdzZWxmJzsgb2JqZWN0LXNyYyAnc2VsZic7XCIsIC8vIGRlZmF1bHQgQ1NQIGZvciBNVjJcbiAgKTtcblxuICBpZiAoY29uZmlnLnNlcnZlcikgY3NwLmFkZCgnc2NyaXB0LXNyYycsIGFsbG93ZWRDc3ApO1xuXG4gIGlmIChtYW5pZmVzdC5tYW5pZmVzdF92ZXJzaW9uID09PSAzKSB7XG4gICAgbWFuaWZlc3QuY29udGVudF9zZWN1cml0eV9wb2xpY3kgPz89IHt9O1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3I6IGV4dGVuc2lvbl9wYWdlcyBpcyBub3QgdHlwZWRcbiAgICBtYW5pZmVzdC5jb250ZW50X3NlY3VyaXR5X3BvbGljeS5leHRlbnNpb25fcGFnZXMgPSBjc3AudG9TdHJpbmcoKTtcbiAgfSBlbHNlIHtcbiAgICBtYW5pZmVzdC5jb250ZW50X3NlY3VyaXR5X3BvbGljeSA9IGNzcC50b1N0cmluZygpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYnVuZGxlIHBhdGhzIHRvIENTUyBmaWxlcyBhc3NvY2lhdGVkIHdpdGggYSBsaXN0IG9mIGNvbnRlbnQgc2NyaXB0cywgb3IgdW5kZWZpbmVkIGlmXG4gKiB0aGVyZSBpcyBubyBhc3NvY2lhdGVkIENTUy5cbiAqL1xuZnVuY3Rpb24gZ2V0Q29udGVudFNjcmlwdENzc0ZpbGVzKFxuICBjb250ZW50U2NyaXB0czogQ29udGVudFNjcmlwdEVudHJ5cG9pbnRbXSxcbiAgYnVpbGRPdXRwdXQ6IE9taXQ8QnVpbGRPdXRwdXQsICdtYW5pZmVzdCc+LFxuKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICBjb25zdCBjc3M6IHN0cmluZ1tdID0gW107XG5cbiAgY29uc3QgYWxsQ2h1bmtzID0gYnVpbGRPdXRwdXQuc3RlcHMuZmxhdE1hcCgoc3RlcCkgPT4gc3RlcC5jaHVua3MpO1xuXG4gIGNvbnRlbnRTY3JpcHRzLmZvckVhY2goKHNjcmlwdCkgPT4ge1xuICAgIC8vIFRPRE86IG9wdGltaXplIGFuZCByZW1vdmUgbG9vcCB3aXRoIGEgbWFwXG4gICAgY29uc3QgcmVsYXRlZENzcyA9IGFsbENodW5rcy5maW5kKFxuICAgICAgKGNodW5rKSA9PiBjaHVuay5maWxlTmFtZSA9PT0gYGFzc2V0cy8ke3NjcmlwdC5uYW1lfS5jc3NgLFxuICAgICk7XG4gICAgaWYgKHJlbGF0ZWRDc3MpIGNzcy5wdXNoKHJlbGF0ZWRDc3MuZmlsZU5hbWUpO1xuICB9KTtcblxuICBpZiAoY3NzLmxlbmd0aCA+IDApIHJldHVybiBjc3M7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG4iLCAiLyoqXG4gKiBEaXJlY3RpdmUgbmFtZXMgdGhhdCBtYWtlIHVwIENTUHMuIFRoZXJlIGFyZSBtb3JlLCB0aGlzIGlzIGFsbCBJIG5lZWQgZm9yIHRoZSBwbHVnaW4uXG4gKi9cbmV4cG9ydCB0eXBlIENzcERpcmVjdGl2ZSA9ICdkZWZhdWx0LXNyYycgfCAnc2NyaXB0LXNyYycgfCAnb2JqZWN0LXNyYyc7XG5cbmV4cG9ydCBjbGFzcyBDb250ZW50U2VjdXJpdHlQb2xpY3kge1xuICBwcml2YXRlIHN0YXRpYyBESVJFQ1RJVkVfT1JERVI6IFJlY29yZDxzdHJpbmcsIG51bWJlciB8IHVuZGVmaW5lZD4gPSB7XG4gICAgJ2RlZmF1bHQtc3JjJzogMCxcbiAgICAnc2NyaXB0LXNyYyc6IDEsXG4gICAgJ29iamVjdC1zcmMnOiAyLFxuICB9O1xuXG4gIGRhdGE6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPjtcblxuICBjb25zdHJ1Y3Rvcihjc3A/OiBzdHJpbmcpIHtcbiAgICBpZiAoY3NwKSB7XG4gICAgICBjb25zdCBzZWN0aW9ucyA9IGNzcC5zcGxpdCgnOycpLm1hcCgoc2VjdGlvbikgPT4gc2VjdGlvbi50cmltKCkpO1xuICAgICAgdGhpcy5kYXRhID0gc2VjdGlvbnMucmVkdWNlPFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPj4oKGRhdGEsIHNlY3Rpb24pID0+IHtcbiAgICAgICAgY29uc3QgW2tleSwgLi4udmFsdWVzXSA9IHNlY3Rpb24uc3BsaXQoJyAnKS5tYXAoKGl0ZW0pID0+IGl0ZW0udHJpbSgpKTtcbiAgICAgICAgaWYgKGtleSkgZGF0YVtrZXldID0gdmFsdWVzO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgIH0sIHt9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kYXRhID0ge307XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZSBhIHNldCBvZiB2YWx1ZXMgYXJlIGxpc3RlZCB1bmRlciBhIGRpcmVjdGl2ZS5cbiAgICovXG4gIGFkZChkaXJlY3RpdmU6IENzcERpcmVjdGl2ZSwgLi4ubmV3VmFsdWVzOiBzdHJpbmdbXSk6IENvbnRlbnRTZWN1cml0eVBvbGljeSB7XG4gICAgY29uc3QgdmFsdWVzID0gdGhpcy5kYXRhW2RpcmVjdGl2ZV0gPz8gW107XG4gICAgbmV3VmFsdWVzLmZvckVhY2goKG5ld1ZhbHVlKSA9PiB7XG4gICAgICBpZiAoIXZhbHVlcy5pbmNsdWRlcyhuZXdWYWx1ZSkpIHZhbHVlcy5wdXNoKG5ld1ZhbHVlKTtcbiAgICB9KTtcbiAgICB0aGlzLmRhdGFbZGlyZWN0aXZlXSA9IHZhbHVlcztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZGlyZWN0aXZlcyA9IE9iamVjdC5lbnRyaWVzKHRoaXMuZGF0YSkuc29ydCgoW2xdLCBbcl0pID0+IHtcbiAgICAgIGNvbnN0IGxvID0gQ29udGVudFNlY3VyaXR5UG9saWN5LkRJUkVDVElWRV9PUkRFUltsXSA/PyAyO1xuICAgICAgY29uc3Qgcm8gPSBDb250ZW50U2VjdXJpdHlQb2xpY3kuRElSRUNUSVZFX09SREVSW3JdID8/IDI7XG4gICAgICByZXR1cm4gbG8gLSBybztcbiAgICB9KTtcbiAgICByZXR1cm4gZGlyZWN0aXZlcy5tYXAoKGVudHJ5KSA9PiBlbnRyeS5mbGF0KCkuam9pbignICcpKS5qb2luKCc7ICcpICsgJzsnO1xuICB9XG59XG4iLCAiaW1wb3J0IHBhdGgsIHsgZXh0bmFtZSwgcmVsYXRpdmUsIHJlc29sdmUgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IEJ1aWxkT3V0cHV0LCBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IHByaW50VGFibGUgfSBmcm9tICcuL3ByaW50VGFibGUnO1xuaW1wb3J0IHBjIGZyb20gJ3BpY29jb2xvcnMnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IGZpbGVzaXplIH0gZnJvbSAnZmlsZXNpemUnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJpbnRCdWlsZFN1bW1hcnkoXG4gIG91dHB1dDogQnVpbGRPdXRwdXQsXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pIHtcbiAgY29uc3QgY2h1bmtzID0gW1xuICAgIC4uLm91dHB1dC5zdGVwcy5mbGF0TWFwKChzdGVwKSA9PiBzdGVwLmNodW5rcyksXG4gICAgLi4ub3V0cHV0LnB1YmxpY0Fzc2V0cyxcbiAgXS5zb3J0KChsLCByKSA9PiB7XG4gICAgY29uc3QgbFdlaWdodCA9XG4gICAgICBDSFVOS19TT1JUX1dFSUdIVFNbbC5maWxlTmFtZV0gPz9cbiAgICAgIENIVU5LX1NPUlRfV0VJR0hUU1tleHRuYW1lKGwuZmlsZU5hbWUpXSA/P1xuICAgICAgREVGQVVMVF9TT1JUX1dFSUdIVDtcbiAgICBjb25zdCByV2VpZ2h0ID1cbiAgICAgIENIVU5LX1NPUlRfV0VJR0hUU1tyLmZpbGVOYW1lXSA/P1xuICAgICAgQ0hVTktfU09SVF9XRUlHSFRTW2V4dG5hbWUoci5maWxlTmFtZSldID8/XG4gICAgICBERUZBVUxUX1NPUlRfV0VJR0hUO1xuICAgIGNvbnN0IGRpZmYgPSBsV2VpZ2h0IC0gcldlaWdodDtcbiAgICBpZiAoZGlmZiAhPT0gMCkgcmV0dXJuIGRpZmY7XG4gICAgcmV0dXJuIGwuZmlsZU5hbWUubG9jYWxlQ29tcGFyZShyLmZpbGVOYW1lKTtcbiAgfSk7XG5cbiAgbGV0IHRvdGFsU2l6ZSA9IDA7XG5cbiAgY29uc3QgY2h1bmtSb3dzOiBzdHJpbmdbXVtdID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgY2h1bmtzLm1hcChhc3luYyAoY2h1bmssIGkpID0+IHtcbiAgICAgIGNvbnN0IGZpbGUgPSBbXG4gICAgICAgIHJlbGF0aXZlKHByb2Nlc3MuY3dkKCksIGNvbmZpZy5vdXREaXIpICsgcGF0aC5zZXAsXG4gICAgICAgIGNodW5rLmZpbGVOYW1lLFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGV4dCA9IGV4dG5hbWUoY2h1bmsuZmlsZU5hbWUpO1xuICAgICAgY29uc3QgcHJlZml4ID0gaSA9PT0gY2h1bmtzLmxlbmd0aCAtIDEgPyAnICBcdTI1MTRcdTI1MDAnIDogJyAgXHUyNTFDXHUyNTAwJztcbiAgICAgIGNvbnN0IGNvbG9yID0gQ0hVTktfQ09MT1JTW2V4dF0gPz8gREVGQVVMVF9DT0xPUjtcbiAgICAgIGNvbnN0IHN0YXRzID0gYXdhaXQgZnMubHN0YXQocmVzb2x2ZShjb25maWcub3V0RGlyLCBjaHVuay5maWxlTmFtZSkpO1xuICAgICAgdG90YWxTaXplICs9IHN0YXRzLnNpemU7XG4gICAgICBjb25zdCBzaXplID0gU3RyaW5nKGZpbGVzaXplKHN0YXRzLnNpemUpKTtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIGAke3BjLmdyYXkocHJlZml4KX0gJHtwYy5kaW0oZmlsZVswXSl9JHtjb2xvcihmaWxlWzFdKX1gLFxuICAgICAgICBwYy5kaW0oc2l6ZSksXG4gICAgICBdO1xuICAgIH0pLFxuICApO1xuXG4gIHByaW50VGFibGUoY29uZmlnLmxvZ2dlci5sb2csIGNodW5rUm93cyk7XG5cbiAgY29uZmlnLmxvZ2dlci5sb2coXG4gICAgYCR7cGMuY3lhbignXHUwM0EzIFRvdGFsIHNpemU6Jyl9ICR7U3RyaW5nKGZpbGVzaXplKHRvdGFsU2l6ZSkpfWAsXG4gICk7XG59XG5cbmNvbnN0IERFRkFVTFRfU09SVF9XRUlHSFQgPSAxMDA7XG5jb25zdCBDSFVOS19TT1JUX1dFSUdIVFM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7XG4gICdtYW5pZmVzdC5qc29uJzogMCxcbiAgJy5odG1sJzogMSxcbiAgJy5qcyc6IDIsXG4gICcuY3NzJzogMyxcbn07XG5cbmNvbnN0IERFRkFVTFRfQ09MT1IgPSBwYy5ibHVlO1xuY29uc3QgQ0hVTktfQ09MT1JTOiBSZWNvcmQ8c3RyaW5nLCAodGV4dDogc3RyaW5nKSA9PiBzdHJpbmc+ID0ge1xuICAnLmh0bWwnOiBwYy5ncmVlbixcbiAgJy5jc3MnOiBwYy5tYWdlbnRhLFxuICAnLmpzJzogcGMuY3lhbixcbn07XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIHByaW50VGFibGUoXG4gIGxvZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCxcbiAgcm93czogc3RyaW5nW11bXSxcbiAgZ2FwID0gMixcbik6IHZvaWQge1xuICBpZiAocm93cy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICBjb25zdCBjb2x1bW5XaWR0aHMgPSByb3dzLnJlZHVjZShcbiAgICAod2lkdGhzLCByb3cpID0+IHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWF0aC5tYXgod2lkdGhzLmxlbmd0aCwgcm93Lmxlbmd0aCk7IGkrKykge1xuICAgICAgICB3aWR0aHNbaV0gPSBNYXRoLm1heChyb3dbaV0/Lmxlbmd0aCA/PyAwLCB3aWR0aHNbaV0gPz8gMCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gd2lkdGhzO1xuICAgIH0sXG4gICAgcm93c1swXS5tYXAoKGNvbHVtbikgPT4gY29sdW1uLmxlbmd0aCksXG4gICk7XG5cbiAgbGV0IHN0ciA9ICcnO1xuICByb3dzLmZvckVhY2goKHJvdywgaSkgPT4ge1xuICAgIHJvdy5mb3JFYWNoKChjb2wsIGopID0+IHtcbiAgICAgIHN0ciArPSBjb2wucGFkRW5kKGNvbHVtbldpZHRoc1tqXSwgJyAnKTtcbiAgICAgIGlmIChqICE9PSByb3cubGVuZ3RoIC0gMSkgc3RyICs9ICcnLnBhZEVuZChnYXAsICcgJyk7XG4gICAgfSk7XG4gICAgaWYgKGkgIT09IHJvd3MubGVuZ3RoIC0gMSkgc3RyICs9ICdcXG4nO1xuICB9KTtcblxuICBsb2coc3RyKTtcbn1cbiIsICJpbXBvcnQge1xuICBCdWlsZE91dHB1dCxcbiAgV3h0RGV2U2VydmVyLFxuICBJbmxpbmVDb25maWcsXG4gIEludGVybmFsQ29uZmlnLFxuICBFbnRyeXBvaW50R3JvdXAsXG59IGZyb20gJy4vY29yZS90eXBlcyc7XG5pbXBvcnQgeyBnZXRJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4vY29yZS91dGlscy9nZXRJbnRlcm5hbENvbmZpZyc7XG5pbXBvcnQgeyBmaW5kRW50cnlwb2ludHMgfSBmcm9tICcuL2NvcmUvYnVpbGQvZmluZEVudHJ5cG9pbnRzJztcbmltcG9ydCB7IGJ1aWxkRW50cnlwb2ludHMgfSBmcm9tICcuL2NvcmUvYnVpbGQvYnVpbGRFbnRyeXBvaW50cyc7XG5pbXBvcnQgeyBnZW5lcmF0ZU1haW5mZXN0LCB3cml0ZU1hbmlmZXN0IH0gZnJvbSAnLi9jb3JlL3V0aWxzL21hbmlmZXN0JztcbmltcG9ydCB7IHByaW50QnVpbGRTdW1tYXJ5IH0gZnJvbSAnLi9jb3JlL2xvZy9wcmludEJ1aWxkU3VtbWFyeSc7XG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgZ2VuZXJhdGVUeXBlc0RpciB9IGZyb20gJy4vY29yZS9idWlsZC9nZW5lcmF0ZVR5cGVzRGlyJztcbmltcG9ydCBwYyBmcm9tICdwaWNvY29sb3JzJztcbmltcG9ydCAqIGFzIHZpdGUgZnJvbSAndml0ZSc7XG5pbXBvcnQgeyBmaW5kT3BlblBvcnQgfSBmcm9tICcuL2NvcmUvdXRpbHMvZmluZE9wZW5Qb3J0JztcbmltcG9ydCB7IGZvcm1hdER1cmF0aW9uIH0gZnJvbSAnLi9jb3JlL3V0aWxzL2Zvcm1hdER1cmF0aW9uJztcbmltcG9ydCB7IGNyZWF0ZVdlYkV4dFJ1bm5lciB9IGZyb20gJy4vY29yZS9ydW5uZXJzL2NyZWF0ZVdlYkV4dFJ1bm5lcic7XG5pbXBvcnQgeyBncm91cEVudHJ5cG9pbnRzIH0gZnJvbSAnLi9jb3JlL3V0aWxzL2dyb3VwRW50cnlwb2ludHMnO1xuaW1wb3J0IHsgTWFuaWZlc3QgfSBmcm9tICd3ZWJleHRlbnNpb24tcG9seWZpbGwnO1xuaW1wb3J0IHsgZGV0ZWN0RGV2Q2hhbmdlcyB9IGZyb20gJy4vY29yZS91dGlscy9kZXRlY3REZXZDaGFuZ2VzJztcbmltcG9ydCB7IE11dGV4IH0gZnJvbSAnYXN5bmMtbXV0ZXgnO1xuaW1wb3J0IHsgY29uc29sYSB9IGZyb20gJ2NvbnNvbGEnO1xuaW1wb3J0IHsgcmVsYXRpdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHtcbiAgZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGgsXG4gIGdldEVudHJ5cG9pbnRPdXRwdXRGaWxlLFxufSBmcm9tICcuL2NvcmUvdXRpbHMvZW50cnlwb2ludHMnO1xuXG5leHBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi4vcGFja2FnZS5qc29uJztcbmV4cG9ydCAqIGZyb20gJy4vY29yZS90eXBlcy9leHRlcm5hbCc7XG5leHBvcnQgKiBmcm9tICcuL2NvcmUvdXRpbHMvZGVmaW5lQ29uZmlnJztcbmV4cG9ydCAqIGZyb20gJy4vY29yZS91dGlscy9kZWZpbmVSdW5uZXJDb25maWcnO1xuXG4vKipcbiAqIEJ1bmRsZXMgdGhlIGV4dGVuc2lvbiBmb3IgcHJvZHVjdGlvbi4gUmV0dXJucyBhIHByb21pc2Ugb2YgdGhlIGJ1aWxkIHJlc3VsdC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1aWxkKGNvbmZpZzogSW5saW5lQ29uZmlnKTogUHJvbWlzZTxCdWlsZE91dHB1dD4ge1xuICBjb25zdCBpbnRlcm5hbENvbmZpZyA9IGF3YWl0IGdldEludGVybmFsQ29uZmlnKGNvbmZpZywgJ2J1aWxkJyk7XG4gIHJldHVybiBhd2FpdCBidWlsZEludGVybmFsKGludGVybmFsQ29uZmlnKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVNlcnZlcihcbiAgY29uZmlnPzogSW5saW5lQ29uZmlnLFxuKTogUHJvbWlzZTxXeHREZXZTZXJ2ZXI+IHtcbiAgY29uc3QgcG9ydCA9IGF3YWl0IGZpbmRPcGVuUG9ydCgzMDAwLCAzMDEwKTtcbiAgY29uc3QgaG9zdG5hbWUgPSAnbG9jYWxob3N0JztcbiAgY29uc3Qgb3JpZ2luID0gYGh0dHA6Ly8ke2hvc3RuYW1lfToke3BvcnR9YDtcbiAgY29uc3Qgc2VydmVyQ29uZmlnOiB2aXRlLklubGluZUNvbmZpZyA9IHtcbiAgICBzZXJ2ZXI6IHtcbiAgICAgIG9yaWdpbixcbiAgICB9LFxuICB9O1xuICBsZXQgaW50ZXJuYWxDb25maWcgPSBhd2FpdCBnZXRJbnRlcm5hbENvbmZpZyhcbiAgICB2aXRlLm1lcmdlQ29uZmlnKHNlcnZlckNvbmZpZywgY29uZmlnID8/IHt9KSxcbiAgICAnc2VydmUnLFxuICApO1xuICBjb25zdCBydW5uZXIgPSBjcmVhdGVXZWJFeHRSdW5uZXIoKTtcblxuICBsZXQgaGFzQnVpbHRPbmNlID0gZmFsc2U7XG4gIGxldCBjdXJyZW50T3V0cHV0OiBCdWlsZE91dHB1dCB8IHVuZGVmaW5lZDtcbiAgY29uc3QgZmlsZUNoYW5nZWRNdXRleCA9IG5ldyBNdXRleCgpO1xuICBjb25zdCBjaGFuZ2VRdWV1ZTogQXJyYXk8W3N0cmluZywgc3RyaW5nXT4gPSBbXTtcblxuICBjb25zdCB2aXRlU2VydmVyID0gYXdhaXQgdml0ZS5jcmVhdGVTZXJ2ZXIoaW50ZXJuYWxDb25maWcudml0ZSk7XG4gIHZpdGVTZXJ2ZXIud2F0Y2hlci5vbignYWxsJywgYXN5bmMgKGV2ZW50LCBwYXRoLCBzdGF0cykgPT4ge1xuICAgIGlmICghaGFzQnVpbHRPbmNlIHx8IHBhdGguc3RhcnRzV2l0aChpbnRlcm5hbENvbmZpZy5vdXRCYXNlRGlyKSkgcmV0dXJuO1xuICAgIGNoYW5nZVF1ZXVlLnB1c2goW2V2ZW50LCBwYXRoXSk7XG5cbiAgICBhd2FpdCBmaWxlQ2hhbmdlZE11dGV4LnJ1bkV4Y2x1c2l2ZShhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBmaWxlQ2hhbmdlcyA9IGNoYW5nZVF1ZXVlLnNwbGljZSgwLCBjaGFuZ2VRdWV1ZS5sZW5ndGgpO1xuICAgICAgY29uc3QgY2hhbmdlcyA9IGRldGVjdERldkNoYW5nZXMoZmlsZUNoYW5nZXMsIGN1cnJlbnRPdXRwdXQpO1xuXG4gICAgICBpZiAoY2hhbmdlcy50eXBlID09PSAnbm8tY2hhbmdlJykgcmV0dXJuO1xuXG4gICAgICAvLyBMb2cgdGhlIGVudHJ5cG9pbnRzIHRoYXQgd2VyZSBlZmZlY3RlZFxuICAgICAgY29uc29sYS5pbmZvKFxuICAgICAgICBgQ2hhbmdlZDogJHtBcnJheS5mcm9tKG5ldyBTZXQoZmlsZUNoYW5nZXMubWFwKChjaGFuZ2UpID0+IGNoYW5nZVsxXSkpKVxuICAgICAgICAgIC5tYXAoKGZpbGUpID0+IHBjLmRpbShyZWxhdGl2ZShpbnRlcm5hbENvbmZpZy5yb290LCBmaWxlKSkpXG4gICAgICAgICAgLmpvaW4oJywgJyl9YCxcbiAgICAgICk7XG4gICAgICBjb25zdCByZWJ1aWx0TmFtZXMgPSBjaGFuZ2VzLnJlYnVpbGRHcm91cHNcbiAgICAgICAgLmZsYXQoKVxuICAgICAgICAubWFwKChlbnRyeSkgPT4ge1xuICAgICAgICAgIHJldHVybiBwYy5jeWFuKFxuICAgICAgICAgICAgcmVsYXRpdmUoaW50ZXJuYWxDb25maWcub3V0RGlyLCBnZXRFbnRyeXBvaW50T3V0cHV0RmlsZShlbnRyeSwgJycpKSxcbiAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbihwYy5kaW0oJywgJykpO1xuXG4gICAgICAvLyBHZXQgbGF0ZXN0IGNvbmZpZyBhbmQgUmVidWlsZCBncm91cHMgd2l0aCBjaGFuZ2VzXG4gICAgICBpbnRlcm5hbENvbmZpZyA9IGF3YWl0IGdldEludGVybmFsQ29uZmlnKFxuICAgICAgICB2aXRlLm1lcmdlQ29uZmlnKHNlcnZlckNvbmZpZywgY29uZmlnID8/IHt9KSxcbiAgICAgICAgJ3NlcnZlJyxcbiAgICAgICk7XG4gICAgICBpbnRlcm5hbENvbmZpZy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgICBjb25zdCB7IG91dHB1dDogbmV3T3V0cHV0IH0gPSBhd2FpdCByZWJ1aWxkKFxuICAgICAgICBpbnRlcm5hbENvbmZpZyxcbiAgICAgICAgLy8gVE9ETzogdGhpcyBleGNsdWRlcyBuZXcgZW50cnlwb2ludHMsIHNvIHRoZXkncmUgbm90IGJ1aWx0IHVudGlsIHRoZSBkZXYgY29tbWFuZCBpcyByZXN0YXJ0ZWRcbiAgICAgICAgY2hhbmdlcy5yZWJ1aWxkR3JvdXBzLFxuICAgICAgICBjaGFuZ2VzLmNhY2hlZE91dHB1dCxcbiAgICAgICk7XG4gICAgICBjdXJyZW50T3V0cHV0ID0gbmV3T3V0cHV0O1xuXG4gICAgICAvLyBQZXJmb3JtIHJlbG9hZHNcbiAgICAgIHN3aXRjaCAoY2hhbmdlcy50eXBlKSB7XG4gICAgICAgIGNhc2UgJ2V4dGVuc2lvbi1yZWxvYWQnOlxuICAgICAgICAgIHNlcnZlci5yZWxvYWRFeHRlbnNpb24oKTtcbiAgICAgICAgICBjb25zb2xhLnN1Y2Nlc3MoYFJlbG9hZGVkIGV4dGVuc2lvbjogJHtyZWJ1aWx0TmFtZXN9YCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2h0bWwtcmVsb2FkJzpcbiAgICAgICAgICBjaGFuZ2VzLnJlYnVpbGRHcm91cHMuZmxhdCgpLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXRoID0gZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGgoXG4gICAgICAgICAgICAgIGVudHJ5LFxuICAgICAgICAgICAgICBpbnRlcm5hbENvbmZpZy5vdXREaXIsXG4gICAgICAgICAgICAgICcuaHRtbCcsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc2VydmVyLnJlbG9hZFBhZ2UocGF0aCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc29sYS5zdWNjZXNzKGBSZWxvYWRlZCBwYWdlczogJHtyZWJ1aWx0TmFtZXN9YCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICBjb25zdCBzZXJ2ZXI6IFd4dERldlNlcnZlciA9IHtcbiAgICAuLi52aXRlU2VydmVyLFxuICAgIGFzeW5jIGxpc3Rlbihwb3J0LCBpc1Jlc3RhcnQpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHZpdGVTZXJ2ZXIubGlzdGVuKHBvcnQsIGlzUmVzdGFydCk7XG5cbiAgICAgIGlmICghaXNSZXN0YXJ0KSB7XG4gICAgICAgIGludGVybmFsQ29uZmlnLmxvZ2dlci5zdWNjZXNzKGBTdGFydGVkIGRldiBzZXJ2ZXIgQCAke29yaWdpbn1gKTtcblxuICAgICAgICBpbnRlcm5hbENvbmZpZy5sb2dnZXIuaW5mbygnT3BlbmluZyBicm93c2VyLi4uJyk7XG4gICAgICAgIGF3YWl0IHJ1bm5lci5vcGVuQnJvd3NlcihpbnRlcm5hbENvbmZpZyk7XG4gICAgICAgIGludGVybmFsQ29uZmlnLmxvZ2dlci5zdWNjZXNzKCdPcGVuZWQhJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXM7XG4gICAgfSxcbiAgICBwb3J0LFxuICAgIGhvc3RuYW1lLFxuICAgIG9yaWdpbixcbiAgICByZWxvYWRFeHRlbnNpb246ICgpID0+IHtcbiAgICAgIHNlcnZlci53cy5zZW5kKCd3eHQ6cmVsb2FkLWV4dGVuc2lvbicpO1xuICAgIH0sXG4gICAgcmVsb2FkUGFnZTogKHBhdGgpID0+IHtcbiAgICAgIC8vIENhbid0IHVzZSBWaXRlJ3MgYnVpbHQtaW4gXCJmdWxsLXJlbG9hZFwiIGV2ZW50IGJlY2F1c2UgaXQgZG9lc24ndCBsaWtlIG91ciBwYXRocywgaXQgZXhwZWN0c1xuICAgICAgLy8gcGF0aHMgZW5kaW5nIGluIFwiL2luZGV4Lmh0bWxcIlxuICAgICAgc2VydmVyLndzLnNlbmQoJ3d4dDpyZWxvYWQtcGFnZScsIHBhdGgpO1xuICAgIH0sXG4gIH07XG4gIGludGVybmFsQ29uZmlnLmxvZ2dlci5pbmZvKCdDcmVhdGVkIGRldiBzZXJ2ZXInKTtcblxuICBpbnRlcm5hbENvbmZpZy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gIGN1cnJlbnRPdXRwdXQgPSBhd2FpdCBidWlsZEludGVybmFsKGludGVybmFsQ29uZmlnKTtcbiAgaGFzQnVpbHRPbmNlID0gdHJ1ZTtcblxuICByZXR1cm4gc2VydmVyO1xufVxuXG5hc3luYyBmdW5jdGlvbiBidWlsZEludGVybmFsKGNvbmZpZzogSW50ZXJuYWxDb25maWcpOiBQcm9taXNlPEJ1aWxkT3V0cHV0PiB7XG4gIGNvbnN0IHZlcmIgPSBjb25maWcuY29tbWFuZCA9PT0gJ3NlcnZlJyA/ICdQcmUtcmVuZGVyaW5nJyA6ICdCdWlsZGluZyc7XG4gIGNvbnN0IHRhcmdldCA9IGAke2NvbmZpZy5icm93c2VyfS1tdiR7Y29uZmlnLm1hbmlmZXN0VmVyc2lvbn1gO1xuICBjb25maWcubG9nZ2VyLmluZm8oXG4gICAgYCR7dmVyYn0gJHtwYy5jeWFuKHRhcmdldCl9IGZvciAke3BjLmN5YW4oY29uZmlnLm1vZGUpfSB3aXRoICR7cGMuZ3JlZW4oXG4gICAgICBgVml0ZSAke3ZpdGUudmVyc2lvbn1gLFxuICAgICl9YCxcbiAgKTtcbiAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAvLyBDbGVhbnVwXG4gIGF3YWl0IGZzLnJtKGNvbmZpZy5vdXREaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgYXdhaXQgZnMuZW5zdXJlRGlyKGNvbmZpZy5vdXREaXIpO1xuXG4gIGNvbnN0IGVudHJ5cG9pbnRzID0gYXdhaXQgZmluZEVudHJ5cG9pbnRzKGNvbmZpZyk7XG4gIGNvbnN0IGdyb3VwcyA9IGdyb3VwRW50cnlwb2ludHMoZW50cnlwb2ludHMpO1xuICBjb25zdCB7IG91dHB1dCB9ID0gYXdhaXQgcmVidWlsZChjb25maWcsIGdyb3Vwcyk7XG5cbiAgLy8gUG9zdC1idWlsZFxuICBjb25maWcubG9nZ2VyLnN1Y2Nlc3MoXG4gICAgYEJ1aWx0IGV4dGVuc2lvbiBpbiAke2Zvcm1hdER1cmF0aW9uKERhdGUubm93KCkgLSBzdGFydFRpbWUpfWAsXG4gICk7XG4gIGF3YWl0IHByaW50QnVpbGRTdW1tYXJ5KG91dHB1dCwgY29uZmlnKTtcblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVidWlsZChcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbiAgZW50cnlwb2ludEdyb3VwczogRW50cnlwb2ludEdyb3VwW10sXG4gIGV4aXN0aW5nT3V0cHV0OiBPbWl0PEJ1aWxkT3V0cHV0LCAnbWFuaWZlc3QnPiA9IHtcbiAgICBzdGVwczogW10sXG4gICAgcHVibGljQXNzZXRzOiBbXSxcbiAgfSxcbik6IFByb21pc2U8eyBvdXRwdXQ6IEJ1aWxkT3V0cHV0OyBtYW5pZmVzdDogTWFuaWZlc3QuV2ViRXh0ZW5zaW9uTWFuaWZlc3QgfT4ge1xuICAvLyBCdWlsZFxuICBjb25zdCBhbGxFbnRyeXBvaW50cyA9IGF3YWl0IGZpbmRFbnRyeXBvaW50cyhjb25maWcpO1xuICBhd2FpdCBnZW5lcmF0ZVR5cGVzRGlyKGFsbEVudHJ5cG9pbnRzLCBjb25maWcpO1xuICBjb25zdCBidWlsZE91dHB1dCA9IGF3YWl0IGJ1aWxkRW50cnlwb2ludHMoZW50cnlwb2ludEdyb3VwcywgY29uZmlnKTtcblxuICBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IGdlbmVyYXRlTWFpbmZlc3QoYWxsRW50cnlwb2ludHMsIGJ1aWxkT3V0cHV0LCBjb25maWcpO1xuICBjb25zdCBvdXRwdXQ6IEJ1aWxkT3V0cHV0ID0ge1xuICAgIG1hbmlmZXN0LFxuICAgIC4uLmJ1aWxkT3V0cHV0LFxuICB9O1xuXG4gIC8vIFdyaXRlIG1hbmlmZXN0XG4gIGF3YWl0IHdyaXRlTWFuaWZlc3QobWFuaWZlc3QsIG91dHB1dCwgY29uZmlnKTtcblxuICByZXR1cm4ge1xuICAgIG91dHB1dDoge1xuICAgICAgbWFuaWZlc3QsXG4gICAgICBzdGVwczogWy4uLmV4aXN0aW5nT3V0cHV0LnN0ZXBzLCAuLi5vdXRwdXQuc3RlcHNdLFxuICAgICAgcHVibGljQXNzZXRzOiBbLi4uZXhpc3RpbmdPdXRwdXQucHVibGljQXNzZXRzLCAuLi5vdXRwdXQucHVibGljQXNzZXRzXSxcbiAgICB9LFxuICAgIG1hbmlmZXN0LFxuICB9O1xufVxuIiwgImltcG9ydCB7IGNyZWF0ZVVuaW1wb3J0IH0gZnJvbSAndW5pbXBvcnQnO1xuaW1wb3J0IHsgRW50cnlwb2ludCwgSW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgcmVsYXRpdmUsIHJlc29sdmUgfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoIH0gZnJvbSAnLi4vdXRpbHMvZW50cnlwb2ludHMnO1xuaW1wb3J0IHsgZ2V0VW5pbXBvcnRPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMvYXV0by1pbXBvcnRzJztcbmltcG9ydCB7IGdldEdsb2JhbHMgfSBmcm9tICcuLi91dGlscy9nbG9iYWxzJztcblxuLyoqXG4gKiBHZW5lcmF0ZSBhbmQgd3JpdGUgYWxsIHRoZSBmaWxlcyBpbnNpZGUgdGhlIGBJbnRlcm5hbENvbmZpZy50eXBlc0RpcmAgZGlyZWN0b3J5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVUeXBlc0RpcihcbiAgZW50cnlwb2ludHM6IEVudHJ5cG9pbnRbXSxcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBmcy5lbnN1cmVEaXIoY29uZmlnLnR5cGVzRGlyKTtcblxuICBjb25zdCByZWZlcmVuY2VzOiBzdHJpbmdbXSA9IFtdO1xuICByZWZlcmVuY2VzLnB1c2goYXdhaXQgd3JpdGVJbXBvcnRzRGVjbGFyYXRpb25GaWxlKGNvbmZpZykpO1xuICByZWZlcmVuY2VzLnB1c2goYXdhaXQgd3JpdGVQYXRoc0RlY2xhcmF0aW9uRmlsZShlbnRyeXBvaW50cywgY29uZmlnKSk7XG4gIHJlZmVyZW5jZXMucHVzaChhd2FpdCB3cml0ZUdsb2JhbHNEZWNsYXJhdGlvbkZpbGUoY29uZmlnKSk7XG5cbiAgY29uc3QgbWFpblJlZmVyZW5jZSA9IGF3YWl0IHdyaXRlTWFpbkRlY2xhcmF0aW9uRmlsZShyZWZlcmVuY2VzLCBjb25maWcpO1xuICBhd2FpdCB3cml0ZVRzQ29uZmlnRmlsZShtYWluUmVmZXJlbmNlLCBjb25maWcpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3cml0ZUltcG9ydHNEZWNsYXJhdGlvbkZpbGUoXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUoY29uZmlnLnR5cGVzRGlyLCAnaW1wb3J0cy5kLnRzJyk7XG4gIGNvbnN0IHVuaW1wb3J0ID0gY3JlYXRlVW5pbXBvcnQoZ2V0VW5pbXBvcnRPcHRpb25zKGNvbmZpZykpO1xuXG4gIC8vIExvYWQgcHJvamVjdCBpbXBvcnRzIGludG8gdW5pbXBvcnQgbWVtb3J5IHNvIHRoZXkgYXJlIG91dHB1dCB2aWEgZ2VuZXJhdGVUeXBlRGVjbGFyYXRpb25zXG4gIGF3YWl0IHVuaW1wb3J0LnNjYW5JbXBvcnRzRnJvbURpcih1bmRlZmluZWQsIHsgY3dkOiBjb25maWcuc3JjRGlyIH0pO1xuXG4gIGF3YWl0IGZzLndyaXRlRmlsZShcbiAgICBmaWxlUGF0aCxcbiAgICBbJy8vIEdlbmVyYXRlZCBieSB3eHQnLCBhd2FpdCB1bmltcG9ydC5nZW5lcmF0ZVR5cGVEZWNsYXJhdGlvbnMoKV0uam9pbihcbiAgICAgICdcXG4nLFxuICAgICkgKyAnXFxuJyxcbiAgKTtcblxuICByZXR1cm4gZmlsZVBhdGg7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHdyaXRlUGF0aHNEZWNsYXJhdGlvbkZpbGUoXG4gIGVudHJ5cG9pbnRzOiBFbnRyeXBvaW50W10sXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUoY29uZmlnLnR5cGVzRGlyLCAncGF0aHMuZC50cycpO1xuXG4gIGF3YWl0IGZzLndyaXRlRmlsZShcbiAgICBmaWxlUGF0aCxcbiAgICBbXG4gICAgICAnLy8gR2VuZXJhdGVkIGJ5IHd4dCcsXG4gICAgICAndHlwZSBFbnRyeXBvaW50UGF0aCA9JyxcbiAgICAgIC4uLmVudHJ5cG9pbnRzXG4gICAgICAgIC5tYXAoKGVudHJ5KSA9PiB7XG4gICAgICAgICAgY29uc3QgcGF0aCA9IGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoKFxuICAgICAgICAgICAgZW50cnksXG4gICAgICAgICAgICBjb25maWcub3V0RGlyLFxuICAgICAgICAgICAgZW50cnkuaW5wdXRQYXRoLmVuZHNXaXRoKCcuaHRtbCcpID8gJy5odG1sJyA6ICcuanMnLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGAgIHwgXCIvJHtwYXRofVwiYDtcbiAgICAgICAgfSlcbiAgICAgICAgLnNvcnQoKSxcbiAgICBdLmpvaW4oJ1xcbicpICsgJ1xcbicsXG4gICk7XG5cbiAgcmV0dXJuIGZpbGVQYXRoO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3cml0ZUdsb2JhbHNEZWNsYXJhdGlvbkZpbGUoXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUoY29uZmlnLnR5cGVzRGlyLCAnZ2xvYmFscy5kLnRzJyk7XG4gIGNvbnN0IGdsb2JhbHMgPSBnZXRHbG9iYWxzKGNvbmZpZyk7XG4gIGF3YWl0IGZzLndyaXRlRmlsZShcbiAgICBmaWxlUGF0aCxcbiAgICBbXG4gICAgICAnLy8gR2VuZXJhdGVkIGJ5IHd4dCcsXG4gICAgICAnZXhwb3J0IHt9JyxcbiAgICAgICdkZWNsYXJlIGdsb2JhbCB7JyxcbiAgICAgIC4uLmdsb2JhbHMubWFwKChnbG9iYWwpID0+IGAgIGNvbnN0ICR7Z2xvYmFsLm5hbWV9OiAke2dsb2JhbC50eXBlfTtgKSxcbiAgICAgICd9JyxcbiAgICBdLmpvaW4oJ1xcbicpICsgJ1xcbicsXG4gICAgJ3V0Zi04JyxcbiAgKTtcbiAgcmV0dXJuIGZpbGVQYXRoO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3cml0ZU1haW5EZWNsYXJhdGlvbkZpbGUoXG4gIHJlZmVyZW5jZXM6IHN0cmluZ1tdLFxuICBjb25maWc6IEludGVybmFsQ29uZmlnLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgZGlyID0gY29uZmlnLnd4dERpcjtcbiAgY29uc3QgZmlsZVBhdGggPSByZXNvbHZlKGRpciwgJ3d4dC5kLnRzJyk7XG4gIGF3YWl0IGZzLndyaXRlRmlsZShcbiAgICBmaWxlUGF0aCxcbiAgICBbXG4gICAgICAnLy8gR2VuZXJhdGVkIGJ5IHd4dCcsXG4gICAgICAuLi5yZWZlcmVuY2VzLm1hcChcbiAgICAgICAgKHJlZikgPT4gYC8vLyA8cmVmZXJlbmNlIHR5cGVzPVwiLi8ke3JlbGF0aXZlKGRpciwgcmVmKX1cIiAvPmAsXG4gICAgICApLFxuICAgIF0uam9pbignXFxuJykgKyAnXFxuJyxcbiAgKTtcbiAgcmV0dXJuIGZpbGVQYXRoO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3cml0ZVRzQ29uZmlnRmlsZShcbiAgbWFpblJlZmVyZW5jZTogc3RyaW5nLFxuICBjb25maWc6IEludGVybmFsQ29uZmlnLFxuKSB7XG4gIGNvbnN0IGRpciA9IGNvbmZpZy53eHREaXI7XG4gIGF3YWl0IGZzLndyaXRlRmlsZShcbiAgICByZXNvbHZlKGRpciwgJ3RzY29uZmlnLmpzb24nKSxcbiAgICBge1xuICBcImNvbXBpbGVyT3B0aW9uc1wiOiB7XG4gICAgXCJ0YXJnZXRcIjogXCJFU05leHRcIixcbiAgICBcIm1vZHVsZVwiOiBcIkVTTmV4dFwiLFxuICAgIFwibW9kdWxlUmVzb2x1dGlvblwiOiBcIkJ1bmRsZXJcIixcbiAgICBcIm5vRW1pdFwiOiB0cnVlLFxuICAgIFwiZXNNb2R1bGVJbnRlcm9wXCI6IHRydWUsXG4gICAgXCJmb3JjZUNvbnNpc3RlbnRDYXNpbmdJbkZpbGVOYW1lc1wiOiB0cnVlLFxuICAgIFwicmVzb2x2ZUpzb25Nb2R1bGVcIjogdHJ1ZSxcblxuICAgIC8qIFR5cGUgQ2hlY2tpbmcgKi9cbiAgICBcInN0cmljdFwiOiB0cnVlLFxuXG4gICAgLyogQ29tcGxldGVuZXNzICovXG4gICAgXCJza2lwTGliQ2hlY2tcIjogdHJ1ZVxuICB9LFxuICBcImluY2x1ZGVcIjogW1xuICAgIFwiJHtyZWxhdGl2ZShkaXIsIGNvbmZpZy5yb290KX0vKiovKlwiLFxuICAgIFwiLi8ke3JlbGF0aXZlKGRpciwgbWFpblJlZmVyZW5jZSl9XCJcbiAgXSxcbiAgXCJleGNsdWRlXCI6IFtcIiR7cmVsYXRpdmUoZGlyLCBjb25maWcub3V0QmFzZURpcil9XCJdXG59YCxcbiAgKTtcbn1cbiIsICJpbXBvcnQgbmV0IGZyb20gJ25vZGU6bmV0JztcblxuLyoqXG4gKiBGaW5kcyB0aGUgZmlyc3Qgb3BlbiBwb3J0IGluIGEgcmFuZ2Ugb2YgcG9ydHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kT3BlblBvcnQoXG4gIHN0YXJ0UG9ydDogbnVtYmVyLFxuICBlbmRQb3J0OiBudW1iZXIsXG4pOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gZmluZE9wZW5Qb3J0UmVjdXJzaXZlKHN0YXJ0UG9ydCwgc3RhcnRQb3J0LCBlbmRQb3J0KTtcbn1cblxuZnVuY3Rpb24gZmluZE9wZW5Qb3J0UmVjdXJzaXZlKFxuICBwb3J0OiBudW1iZXIsXG4gIHN0YXJ0UG9ydDogbnVtYmVyLFxuICBlbmRQb3J0OiBudW1iZXIsXG4pOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGlmIChwb3J0ID4gZW5kUG9ydClcbiAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgIEVycm9yKGBDb3VsZCBub3QgZmluZCBvcGVuIHBvcnQgYmV0d2VlbiAke3N0YXJ0UG9ydH0tJHtlbmRQb3J0fWApLFxuICAgICAgKTtcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXQuY3JlYXRlU2VydmVyKCk7XG5cbiAgICBzZXJ2ZXIubGlzdGVuKHBvcnQsICgpID0+IHtcbiAgICAgIHNlcnZlci5vbmNlKCdjbG9zZScsICgpID0+IHJlc29sdmUocG9ydCkpO1xuICAgICAgc2VydmVyLmNsb3NlKCk7XG4gICAgfSk7XG4gICAgc2VydmVyLm9uKCdlcnJvcicsICgpID0+XG4gICAgICByZXNvbHZlKGZpbmRPcGVuUG9ydFJlY3Vyc2l2ZShwb3J0ICsgMSwgc3RhcnRQb3J0LCBlbmRQb3J0KSksXG4gICAgKTtcbiAgfSk7XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdER1cmF0aW9uKGR1cmF0aW9uOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAoZHVyYXRpb24gPCAxZTMpIHJldHVybiBgJHtkdXJhdGlvbn0gbXNgO1xuICBpZiAoZHVyYXRpb24gPCAxMGUzKSByZXR1cm4gYCR7KGR1cmF0aW9uIC8gMWUzKS50b0ZpeGVkKDMpfSBzYDtcbiAgaWYgKGR1cmF0aW9uIDwgNjBlMykgcmV0dXJuIGAkeyhkdXJhdGlvbiAvIDFlMykudG9GaXhlZCgxKX0gc2A7XG4gIHJldHVybiBgJHsoZHVyYXRpb24gLyAxZTMpLnRvRml4ZWQoMCl9IHNgO1xufVxuIiwgImltcG9ydCB0eXBlIHsgV2ViRXh0UnVuSW5zdGFuY2UgfSBmcm9tICd3ZWItZXh0JztcbmltcG9ydCB7IEV4dGVuc2lvblJ1bm5lciB9IGZyb20gJy4vRXh0ZW5zaW9uUnVubmVyJztcblxuLyoqXG4gKiBDcmVhdGUgYW4gYEV4dGVuc2lvblJ1bm5lcmAgYmFja2VkIGJ5IGB3ZWItZXh0YC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYkV4dFJ1bm5lcigpOiBFeHRlbnNpb25SdW5uZXIge1xuICBsZXQgcnVubmVyOiBXZWJFeHRSdW5JbnN0YW5jZSB8IHVuZGVmaW5lZDtcblxuICByZXR1cm4ge1xuICAgIGFzeW5jIG9wZW5Ccm93c2VyKGNvbmZpZykge1xuICAgICAgaWYgKGNvbmZpZy5icm93c2VyID09PSAnc2FmYXJpJykge1xuICAgICAgICBjb25maWcubG9nZ2VyLndhcm4oJ0Nhbm5vdCBvcGVuIHNhZmFyaSBhdXRvbWF0aWNhbGx5LicpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFVzZSB0aGUgcGx1Z2luJ3MgbG9nZ2VyIGluc3RlYWQgb2Ygd2ViLWV4dCdzIGJ1aWx0LWluIG9uZS5cbiAgICAgIGNvbnN0IHdlYkV4dExvZ2dlciA9IGF3YWl0IGltcG9ydCgnd2ViLWV4dC91dGlsL2xvZ2dlcicpO1xuICAgICAgd2ViRXh0TG9nZ2VyLmNvbnNvbGVTdHJlYW0ud3JpdGUgPSAoeyBsZXZlbCwgbXNnLCBuYW1lIH0pID0+IHtcbiAgICAgICAgaWYgKGxldmVsID49IEVSUk9SX0xPR19MRVZFTCkgY29uZmlnLmxvZ2dlci5lcnJvcihuYW1lLCBtc2cpO1xuICAgICAgICBpZiAobGV2ZWwgPj0gV0FSTl9MT0dfTEVWRUwpIGNvbmZpZy5sb2dnZXIud2Fybihtc2cpO1xuICAgICAgfTtcblxuICAgICAgY29uc3Qgd3h0VXNlckNvbmZpZyA9IGNvbmZpZy5ydW5uZXJDb25maWcuY29uZmlnO1xuICAgICAgY29uc3QgdXNlckNvbmZpZyA9IHtcbiAgICAgICAgY29uc29sZTogd3h0VXNlckNvbmZpZz8ub3BlbkNvbnNvbGUsXG4gICAgICAgIGRldnRvb2xzOiB3eHRVc2VyQ29uZmlnPy5vcGVuRGV2dG9vbHMsXG4gICAgICAgIHN0YXJ0VXJsOiB3eHRVc2VyQ29uZmlnPy5zdGFydFVybHMsXG4gICAgICAgIC4uLihjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIGZpcmVmb3g6IHd4dFVzZXJDb25maWc/LmJpbmFyaWVzPy5maXJlZm94LFxuICAgICAgICAgICAgICBmaXJlZm94UHJvZmlsZTogd3h0VXNlckNvbmZpZz8uZmlyZWZveFByb2ZpbGUsXG4gICAgICAgICAgICAgIHByZWZzOiB3eHRVc2VyQ29uZmlnPy5maXJlZm94UHJlZnMsXG4gICAgICAgICAgICAgIGFyZ3M6IHd4dFVzZXJDb25maWc/LmZpcmVmb3hBcmdzLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDoge1xuICAgICAgICAgICAgICBjaHJvbWl1bUJpbmFyeTogd3h0VXNlckNvbmZpZz8uYmluYXJpZXM/Lltjb25maWcuYnJvd3Nlcl0sXG4gICAgICAgICAgICAgIGNocm9taXVtUHJvZmlsZTogd3h0VXNlckNvbmZpZz8uY2hyb21pdW1Qcm9maWxlLFxuICAgICAgICAgICAgICBhcmdzOiB3eHRVc2VyQ29uZmlnPy5jaHJvbWl1bUFyZ3MsXG4gICAgICAgICAgICB9KSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGZpbmFsQ29uZmlnID0ge1xuICAgICAgICAuLi51c2VyQ29uZmlnLFxuICAgICAgICB0YXJnZXQ6IGNvbmZpZy5icm93c2VyID09PSAnZmlyZWZveCcgPyAnZmlyZWZveC1kZXNrdG9wJyA6ICdjaHJvbWl1bScsXG4gICAgICAgIHNvdXJjZURpcjogY29uZmlnLm91dERpcixcbiAgICAgICAgLy8gV1hUIGhhbmRsZXMgcmVsb2Fkcywgc28gZGlzYWJsZSBhdXRvLXJlbG9hZCBiZWhhdmlvcnMgaW4gd2ViLWV4dFxuICAgICAgICBub1JlbG9hZDogdHJ1ZSxcbiAgICAgICAgbm9JbnB1dDogdHJ1ZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAvLyBEb24ndCBjYWxsIGBwcm9jZXNzLmV4aXQoMClgIGFmdGVyIHN0YXJ0aW5nIHdlYi1leHRcbiAgICAgICAgc2hvdWxkRXhpdFByb2dyYW06IGZhbHNlLFxuICAgICAgfTtcbiAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoJ3dlYi1leHQgY29uZmlnOicsIGZpbmFsQ29uZmlnKTtcbiAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoJ3dlYi1leHQgb3B0aW9uczonLCBvcHRpb25zKTtcblxuICAgICAgY29uc3Qgd2ViRXh0ID0gYXdhaXQgaW1wb3J0KCd3ZWItZXh0Jyk7XG4gICAgICBydW5uZXIgPSBhd2FpdCB3ZWJFeHQuZGVmYXVsdC5jbWQucnVuKGZpbmFsQ29uZmlnLCBvcHRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY2xvc2VCcm93c2VyKCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJ1bm5lcj8uZXhpdCgpO1xuICAgIH0sXG4gIH07XG59XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb3ppbGxhL3dlYi1leHQvYmxvYi9lMzdlNjBhMjczODQ3OGY1MTJmMTI1NWM1MzcxMzMzMjFmMzAxNzcxL3NyYy91dGlsL2xvZ2dlci5qcyNMMTJcbmNvbnN0IFdBUk5fTE9HX0xFVkVMID0gNDA7XG5jb25zdCBFUlJPUl9MT0dfTEVWRUwgPSA1MDtcbiIsICJpbXBvcnQgeyBFbnRyeXBvaW50IH0gZnJvbSAnLi4vLi4nO1xuaW1wb3J0IHsgRW50cnlwb2ludEdyb3VwIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG4vKipcbiAqIEVudHJ5cG9pbnRzIGNhbiBiZSBidWlsZCBpbiBncm91cHMuIEhUTUwgcGFnZXMgY2FuIGFsbCBiZSBidWlsdCB0b2dldGhlciBpbiBhIHNpbmdsZSBzdGVwLCB3aGlsZVxuICogY29udGVudCBzY3JpcHRzIG11c3QgYmUgYnVpbGQgaW5kaXZpZHVhbGx5LlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgZW50cnlwb2ludHMgcHV0IGludG8gdGhlc2UgdHlwZXMgb2YgZ3JvdXBzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBFbnRyeXBvaW50cyhlbnRyeXBvaW50czogRW50cnlwb2ludFtdKTogRW50cnlwb2ludEdyb3VwW10ge1xuICBjb25zdCBncm91cEluZGV4TWFwOiBQYXJ0aWFsPFJlY29yZDxHcm91cCwgbnVtYmVyPj4gPSB7fTtcbiAgY29uc3QgZ3JvdXBzOiBFbnRyeXBvaW50R3JvdXBbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cnlwb2ludHMpIHtcbiAgICBjb25zdCBncm91cCA9IEVOVFJZX1RZUEVfVE9fR1JPVVBfTUFQW2VudHJ5LnR5cGVdO1xuICAgIGlmIChncm91cCA9PT0gJ25vLWdyb3VwJykge1xuICAgICAgZ3JvdXBzLnB1c2goZW50cnkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgZ3JvdXBJbmRleCA9IGdyb3VwSW5kZXhNYXBbZ3JvdXBdO1xuICAgICAgaWYgKGdyb3VwSW5kZXggPT0gbnVsbCkge1xuICAgICAgICBncm91cEluZGV4ID0gZ3JvdXBzLnB1c2goW10pIC0gMTtcbiAgICAgICAgZ3JvdXBJbmRleE1hcFtncm91cF0gPSBncm91cEluZGV4O1xuICAgICAgfVxuICAgICAgKGdyb3Vwc1tncm91cEluZGV4XSBhcyBFbnRyeXBvaW50W10pLnB1c2goZW50cnkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBncm91cHM7XG59XG5cbmNvbnN0IEVOVFJZX1RZUEVfVE9fR1JPVVBfTUFQOiBSZWNvcmQ8RW50cnlwb2ludFsndHlwZSddLCBHcm91cD4gPSB7XG4gIHNhbmRib3g6ICdzYW5kYm94LXBhZ2UnLFxuXG4gIHBvcHVwOiAnZXh0ZW5zaW9uLXBhZ2UnLFxuICBuZXd0YWI6ICdleHRlbnNpb24tcGFnZScsXG4gIGhpc3Rvcnk6ICdleHRlbnNpb24tcGFnZScsXG4gIG9wdGlvbnM6ICdleHRlbnNpb24tcGFnZScsXG4gIGRldnRvb2xzOiAnZXh0ZW5zaW9uLXBhZ2UnLFxuICBib29rbWFya3M6ICdleHRlbnNpb24tcGFnZScsXG4gIHNpZGVwYW5lbDogJ2V4dGVuc2lvbi1wYWdlJyxcbiAgJ3VubGlzdGVkLXBhZ2UnOiAnZXh0ZW5zaW9uLXBhZ2UnLFxuXG4gIGJhY2tncm91bmQ6ICduby1ncm91cCcsXG4gICdjb250ZW50LXNjcmlwdCc6ICduby1ncm91cCcsXG4gICd1bmxpc3RlZC1zY3JpcHQnOiAnbm8tZ3JvdXAnLFxufTtcblxudHlwZSBHcm91cCA9ICdleHRlbnNpb24tcGFnZScgfCAnc2FuZGJveC1wYWdlJyB8ICduby1ncm91cCc7XG4iLCAiaW1wb3J0IHsgQnVpbGRPdXRwdXQsIEJ1aWxkU3RlcE91dHB1dCwgRW50cnlwb2ludEdyb3VwIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcblxuLyoqXG4gKiBDb21wYXJlIHRoZSBjaGFuZ2VkIGZpbGVzIHZzIHRoZSBidWlsZCBvdXRwdXQgYW5kIGRldGVybWluZSB3aGF0IGtpbmQgb2YgcmVsb2FkIG5lZWRzIHRvIGhhcHBlbjpcbiAqXG4gKiAtIERvIG5vdGhpbmdcbiAqICAgLSBDU1Mgb3IgSlMgZmlsZSBhc3NvY2lhdGVkIHdpdGggYW4gSFRNTCBwYWdlIGlzIGNoYW5nZWQgLSB0aGlzIGlzIGhhbmRsZWQgYXV0b21hdGljYWxseSBieSB0aGVcbiAqICAgICBkZXYgc2VydmVyXG4gKiAgIC0gQ2hhbmdlIGlzbid0IHVzZWQgYnkgYW55IG9mIHRoZSBlbnRyeXBvaW50c1xuICogLSBSZWxvYWQgQ29udGVudCBzY3JpcHRcbiAqICAgLSBDU1Mgb3IgSlMgZmlsZSBhc3NvY2lhdGVkIHdpdGggYSBjb250ZW50IHNjcmlwdFxuICogICAtIEJhY2tncm91bmQgc2NyaXB0IHdpbGwgYmUgdG9sZCB0byByZWxvYWQgdGhlIGNvbnRlbnQgc2NyaXB0XG4gKiAtIFJlbG9hZCBIVE1MIGZpbGVcbiAqICAgLSBIVE1MIGZpbGUgaXRzZWxmIGlzIHNhdmVkIC0gSE1SIGRvZXNuJ3QgaGFuZGxlIHRoaXMgYmVjYXVzZSB0aGUgSFRNTCBwYWdlcyBhcmUgcHJlLXJlbmRlcmVkXG4gKiAgIC0gQ2hyb21lIGlzIE9LIHJlbG9hZGluZyB0aGUgcGFnZSB3aGVuIHRoZSBIVE1MIGZpbGUgaXMgY2hhbmdlZCB3aXRob3V0IHJlbG9hZGluZyB0aGUgd2hvbGVcbiAqICAgICBleHRlbnNpb24uIE5vdCBzdXJlIGFib3V0IGZpcmVmb3gsIHRoaXMgbWlnaHQgbmVlZCB0byBjaGFuZ2UgdG8gYW4gZXh0ZW5zaW9uIHJlbG9hZFxuICogLSBSZWxvYWQgZXh0ZW5zaW9uXG4gKiAgIC0gQmFja2dyb3VuZCBzY3JpcHQgaXMgY2hhbmdlZFxuICogICAtIE1hbmlmZXN0IGlzIGRpZmZlcmVudFxuICogLSBSZXN0YXJ0IGJyb3dzZXJcbiAqICAgLSBDb25maWcgZmlsZSBjaGFuZ2VkICh3eHQuY29uZmlnLnRzLCAuZW52LCB3ZWItZXh0LmNvbmZpZy50cywgZXRjKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0RGV2Q2hhbmdlcyhcbiAgY2hhbmdlZEZpbGVzOiBbZXZlbnQ6IHN0cmluZywgcGF0aDogc3RyaW5nXVtdLFxuICBjdXJyZW50T3V0cHV0OiBCdWlsZE91dHB1dCB8IHVuZGVmaW5lZCxcbik6IERldk1vZGVDaGFuZ2Uge1xuICBpZiAoY3VycmVudE91dHB1dCA9PSBudWxsKSByZXR1cm4geyB0eXBlOiAnbm8tY2hhbmdlJyB9O1xuXG4gIGNvbnN0IGNoYW5nZWRTdGVwcyA9IG5ldyBTZXQoXG4gICAgY2hhbmdlZEZpbGVzLmZsYXRNYXAoKGNoYW5nZWRGaWxlKSA9PlxuICAgICAgZmluZEVmZmVjdGVkU3RlcHMoY2hhbmdlZEZpbGUsIGN1cnJlbnRPdXRwdXQpLFxuICAgICksXG4gICk7XG4gIGlmIChjaGFuZ2VkU3RlcHMuc2l6ZSA9PT0gMCkgcmV0dXJuIHsgdHlwZTogJ25vLWNoYW5nZScgfTtcblxuICBjb25zdCB1bmNoYW5nZWRPdXRwdXQ6IEJ1aWxkT3V0cHV0ID0ge1xuICAgIG1hbmlmZXN0OiBjdXJyZW50T3V0cHV0Lm1hbmlmZXN0LFxuICAgIHN0ZXBzOiBbXSxcbiAgICBwdWJsaWNBc3NldHM6IFtdLFxuICB9O1xuICBjb25zdCBjaGFuZ2VkT3V0cHV0OiBCdWlsZE91dHB1dCA9IHtcbiAgICBtYW5pZmVzdDogY3VycmVudE91dHB1dC5tYW5pZmVzdCxcbiAgICBzdGVwczogW10sXG4gICAgcHVibGljQXNzZXRzOiBbXSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IHN0ZXAgb2YgY3VycmVudE91dHB1dC5zdGVwcykge1xuICAgIGlmIChjaGFuZ2VkU3RlcHMuaGFzKHN0ZXApKSB7XG4gICAgICBjaGFuZ2VkT3V0cHV0LnN0ZXBzLnB1c2goc3RlcCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuY2hhbmdlZE91dHB1dC5zdGVwcy5wdXNoKHN0ZXApO1xuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IGFzc2V0IG9mIGN1cnJlbnRPdXRwdXQucHVibGljQXNzZXRzKSB7XG4gICAgaWYgKGNoYW5nZWRTdGVwcy5oYXMoYXNzZXQpKSB7XG4gICAgICBjaGFuZ2VkT3V0cHV0LnB1YmxpY0Fzc2V0cy5wdXNoKGFzc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdW5jaGFuZ2VkT3V0cHV0LnB1YmxpY0Fzc2V0cy5wdXNoKGFzc2V0KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBpc09ubHlIdG1sQ2hhbmdlcyA9ICFjaGFuZ2VkRmlsZXMuZmluZChcbiAgICAoW18sIGZpbGVdKSA9PiAhZmlsZS5lbmRzV2l0aCgnLmh0bWwnKSxcbiAgKTtcbiAgaWYgKGlzT25seUh0bWxDaGFuZ2VzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdodG1sLXJlbG9hZCcsXG4gICAgICBjYWNoZWRPdXRwdXQ6IHVuY2hhbmdlZE91dHB1dCxcbiAgICAgIHJlYnVpbGRHcm91cHM6IGNoYW5nZWRPdXRwdXQuc3RlcHMubWFwKChzdGVwKSA9PiBzdGVwLmVudHJ5cG9pbnRzKSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnZXh0ZW5zaW9uLXJlbG9hZCcsXG4gICAgY2FjaGVkT3V0cHV0OiB1bmNoYW5nZWRPdXRwdXQsXG4gICAgcmVidWlsZEdyb3VwczogY2hhbmdlZE91dHB1dC5zdGVwcy5tYXAoKHN0ZXApID0+IHN0ZXAuZW50cnlwb2ludHMpLFxuICB9O1xufVxuXG4vKipcbiAqIEZvciBhIHNpbmdsZSBjaGFuZ2UsIHJldHVybiBhbGwgdGhlIHN0ZXAgb2YgdGhlIGJ1aWxkIG91dHB1dCB0aGF0IHdlcmUgZWZmZWN0ZWQgYnkgaXQuXG4gKi9cbmZ1bmN0aW9uIGZpbmRFZmZlY3RlZFN0ZXBzKFxuICBjaGFuZ2VkRmlsZTogW2V2ZW50OiBzdHJpbmcsIHBhdGg6IHN0cmluZ10sXG4gIGN1cnJlbnRPdXRwdXQ6IEJ1aWxkT3V0cHV0LFxuKTogRGV0ZWN0ZWRDaGFuZ2VbXSB7XG4gIGNvbnN0IGNoYW5nZXM6IERldGVjdGVkQ2hhbmdlW10gPSBbXTtcbiAgY29uc3QgY2hhbmdlZFBhdGggPSBjaGFuZ2VkRmlsZVsxXTtcblxuICBjb25zdCBpc0NodW5rRWZmZWN0ZWQgPSAoXG4gICAgY2h1bms6IHZpdGUuUm9sbHVwLk91dHB1dENodW5rIHwgdml0ZS5Sb2xsdXAuT3V0cHV0QXNzZXQsXG4gICk6IGJvb2xlYW4gPT5cbiAgICAvLyBJZiBpdCdzIGFuIEhUTUwgZmlsZSB3aXRoIHRoZSBzYW1lIHBhdGgsIGlzIGlzIGVmZmVjdGVkIGJlY2F1c2UgSFRNTCBmaWxlcyBuZWVkIHRvIGJlIHByZS1yZW5kZXJlZFxuICAgIC8vIFRPRE86IHVzZSBidW5kbGUgcGF0aCB0byBzdXBwb3J0IGA8bmFtZT4vaW5kZXguaHRtbGA/XG4gICAgKGNodW5rLnR5cGUgPT09ICdhc3NldCcgJiYgY2hhbmdlZFBhdGguZW5kc1dpdGgoY2h1bmsuZmlsZU5hbWUpKSB8fFxuICAgIC8vIElmIGl0J3MgYSBjaHVuayB0aGF0IGRlcGVuZHMgb24gdGhlIGNoYW5nZWQgZmlsZSwgaXQgaXMgZWZmZWN0ZWRcbiAgICAoY2h1bmsudHlwZSA9PT0gJ2NodW5rJyAmJiBjaHVuay5tb2R1bGVJZHMuaW5jbHVkZXMoY2hhbmdlZFBhdGgpKTtcblxuICBmb3IgKGNvbnN0IHN0ZXAgb2YgY3VycmVudE91dHB1dC5zdGVwcykge1xuICAgIGNvbnN0IGVmZmVjdGVkQ2h1bmsgPSBzdGVwLmNodW5rcy5maW5kKChjaHVuaykgPT4gaXNDaHVua0VmZmVjdGVkKGNodW5rKSk7XG4gICAgaWYgKGVmZmVjdGVkQ2h1bmspIGNoYW5nZXMucHVzaChzdGVwKTtcbiAgfVxuXG4gIGNvbnN0IGVmZmVjdGVkQXNzZXQgPSBjdXJyZW50T3V0cHV0LnB1YmxpY0Fzc2V0cy5maW5kKChjaHVuaykgPT5cbiAgICBpc0NodW5rRWZmZWN0ZWQoY2h1bmspLFxuICApO1xuICBpZiAoZWZmZWN0ZWRBc3NldCkgY2hhbmdlcy5wdXNoKGVmZmVjdGVkQXNzZXQpO1xuXG4gIHJldHVybiBjaGFuZ2VzO1xufVxuXG4vKipcbiAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHdoYXQgZmlsZXMgY2hhbmdlZCwgd2hhdCBuZWVkcyByZWJ1aWx0LCBhbmQgdGhlIHR5cGUgb2YgcmVsb2FkIHRoYXQgaXNcbiAqIHJlcXVpcmVkLlxuICovXG5leHBvcnQgdHlwZSBEZXZNb2RlQ2hhbmdlID0gTm9DaGFuZ2UgfCBIdG1sUmVsb2FkIHwgRXh0ZW5zaW9uUmVsb2FkO1xuLy8gfCBCcm93c2VyUmVzdGFydFxuLy8gfCBDb250ZW50U2NyaXB0UmVsb2FkXG5cbmludGVyZmFjZSBOb0NoYW5nZSB7XG4gIHR5cGU6ICduby1jaGFuZ2UnO1xufVxuXG5pbnRlcmZhY2UgUmVidWlsZENoYW5nZSB7XG4gIC8qKlxuICAgKiBUaGUgbGlzdCBvZiBlbnRyeXBvaW50cyB0aGF0IG5lZWQgcmVidWlsdC5cbiAgICovXG4gIHJlYnVpbGRHcm91cHM6IEVudHJ5cG9pbnRHcm91cFtdO1xuICAvKipcbiAgICogVGhlIHByZXZpb3VzIG91dHB1dCBzdHJpcHBlZCBvZiBhbnkgZmlsZXMgYXJlIGdvaW5nIHRvIGNoYW5nZS5cbiAgICovXG4gIGNhY2hlZE91dHB1dDogQnVpbGRPdXRwdXQ7XG59XG5cbmludGVyZmFjZSBIdG1sUmVsb2FkIGV4dGVuZHMgUmVidWlsZENoYW5nZSB7XG4gIHR5cGU6ICdodG1sLXJlbG9hZCc7XG59XG5cbmludGVyZmFjZSBFeHRlbnNpb25SZWxvYWQgZXh0ZW5kcyBSZWJ1aWxkQ2hhbmdlIHtcbiAgdHlwZTogJ2V4dGVuc2lvbi1yZWxvYWQnO1xufVxuXG4vLyBpbnRlcmZhY2UgQnJvd3NlclJlc3RhcnQgZXh0ZW5kcyBSZWJ1aWxkQ2hhbmdlIHtcbi8vICAgdHlwZTogJ2Jyb3dzZXItcmVzdGFydCc7XG4vLyB9XG5cbi8vIGludGVyZmFjZSBDb250ZW50U2NyaXB0UmVsb2FkIGV4dGVuZHMgUmVidWlsZENoYW5nZSB7XG4vLyAgIHR5cGU6ICdjb250ZW50LXNjcmlwdC1yZWxvYWQnO1xuLy8gfVxuXG4vKipcbiAqIFdoZW4gZmlndXJpbmcgb3V0IHdoYXQgbmVlZHMgcmVsb2FkZWQsIHRoaXMgc3RvcmVzIHRoZSBzdGVwIHRoYXQgd2FzIGNoYW5nZWQsIG9yIHRoZSBwdWJsaWNcbiAqIGRpcmVjdG9yeSBhc3NldCB0aGF0IHdhcyBjaGFuZ2VkLiBJdCBkb2Vzbid0IGtub3cgd2hhdCB0eXBlIG9mIGNoYW5nZSBpcyByZXF1aXJlZCB5ZXQuIEp1c3QgYW5cbiAqIGludGVybWVkaWF0ZSB0eXBlLlxuICovXG50eXBlIERldGVjdGVkQ2hhbmdlID0gQnVpbGRTdGVwT3V0cHV0IHwgdml0ZS5Sb2xsdXAuT3V0cHV0QXNzZXQ7XG4iLCAiaW1wb3J0IHsgY29uc29sYSB9IGZyb20gJ2NvbnNvbGEnO1xuaW1wb3J0IHsgcHJpbnRIZWFkZXIgfSBmcm9tICcuLi8uLi9jb3JlL2xvZy9wcmludEhlYWRlcic7XG5pbXBvcnQgeyBmb3JtYXREdXJhdGlvbiB9IGZyb20gJy4uLy4uL2NvcmUvdXRpbHMvZm9ybWF0RHVyYXRpb24nO1xuXG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lQ29tbWFuZDxUQXJncyBleHRlbmRzIGFueVtdPihcbiAgY2I6ICguLi5hcmdzOiBUQXJncykgPT4gdm9pZCB8IGJvb2xlYW4gfCBQcm9taXNlPHZvaWQgfCBib29sZWFuPixcbikge1xuICByZXR1cm4gYXN5bmMgKC4uLmFyZ3M6IFRBcmdzKSA9PiB7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICB0cnkge1xuICAgICAgcHJpbnRIZWFkZXIoKTtcblxuICAgICAgY29uc3Qgb25nb2luZyA9IGF3YWl0IGNiKC4uLmFyZ3MpO1xuXG4gICAgICBpZiAoIW9uZ29pbmcpXG4gICAgICAgIGNvbnNvbGEuc3VjY2VzcyhcbiAgICAgICAgICBgRmluaXNoZWQgaW4gJHtmb3JtYXREdXJhdGlvbihEYXRlLm5vdygpIC0gc3RhcnRUaW1lKX1gLFxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sYS5mYWlsKFxuICAgICAgICBgQ29tbWFuZCBmYWlsZWQgYWZ0ZXIgJHtmb3JtYXREdXJhdGlvbihEYXRlLm5vdygpIC0gc3RhcnRUaW1lKX1gLFxuICAgICAgKTtcbiAgICAgIGNvbnNvbGEuZXJyb3IoZXJyKTtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gIH07XG59XG4iLCAiaW1wb3J0IHBjIGZyb20gJ3BpY29jb2xvcnMnO1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uLy4uJztcbmltcG9ydCB7IGNvbnNvbGEgfSBmcm9tICdjb25zb2xhJztcblxuZXhwb3J0IGZ1bmN0aW9uIHByaW50SGVhZGVyKCkge1xuICBjb25zb2xlLmxvZygpO1xuICBjb25zb2xhLmxvZyhgJHtwYy5ncmF5KCdXWFQnKX0gJHtwYy5ncmF5KHBjLmJvbGQodmVyc2lvbikpfWApO1xufVxuIiwgImltcG9ydCAqIGFzIHd4dCBmcm9tICcuLi8uLic7XG5pbXBvcnQgeyBkZWZpbmVDb21tYW5kIH0gZnJvbSAnLi4vdXRpbHMvZGVmaW5lQ29tbWFuZCc7XG5cbmV4cG9ydCBjb25zdCBidWlsZCA9IGRlZmluZUNvbW1hbmQ8XG4gIFtcbiAgICByb290OiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgZmxhZ3M6IHtcbiAgICAgIG1vZGU/OiBzdHJpbmc7XG4gICAgICBjb25maWc/OiBzdHJpbmc7XG4gICAgICBicm93c2VyPzogd3h0LlRhcmdldEJyb3dzZXI7XG4gICAgICBtdjM/OiBib29sZWFuO1xuICAgICAgbXYyPzogYm9vbGVhbjtcbiAgICB9LFxuICBdXG4+KGFzeW5jIChyb290LCBmbGFncykgPT4ge1xuICBjb25zdCBtb2RlID0gZmxhZ3MubW9kZSA/PyAncHJvZHVjdGlvbic7XG4gIGNvbnN0IGNsaUNvbmZpZzogd3h0LklubGluZUNvbmZpZyA9IHtcbiAgICByb290LFxuICAgIG1vZGUsXG4gICAgYnJvd3NlcjogZmxhZ3MuYnJvd3NlcixcbiAgICBtYW5pZmVzdFZlcnNpb246IGZsYWdzLm12MyA/IDMgOiBmbGFncy5tdjIgPyAyIDogdW5kZWZpbmVkLFxuICAgIGNvbmZpZ0ZpbGU6IGZsYWdzLmNvbmZpZyxcbiAgfTtcblxuICBhd2FpdCB3eHQuYnVpbGQoY2xpQ29uZmlnKTtcbn0pO1xuIiwgImltcG9ydCAqIGFzIHd4dCBmcm9tICcuLi8uLic7XG5pbXBvcnQgeyBkZWZpbmVDb21tYW5kIH0gZnJvbSAnLi4vdXRpbHMvZGVmaW5lQ29tbWFuZCc7XG5cbmV4cG9ydCBjb25zdCBkZXYgPSBkZWZpbmVDb21tYW5kPFxuICBbXG4gICAgcm9vdDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIGZsYWdzOiB7XG4gICAgICBtb2RlPzogc3RyaW5nO1xuICAgICAgY29uZmlnPzogc3RyaW5nO1xuICAgICAgYnJvd3Nlcj86IHd4dC5UYXJnZXRCcm93c2VyO1xuICAgICAgbXYzPzogYm9vbGVhbjtcbiAgICAgIG12Mj86IGJvb2xlYW47XG4gICAgfSxcbiAgXVxuPihhc3luYyAocm9vdCwgZmxhZ3MpID0+IHtcbiAgY29uc3QgbW9kZSA9IGZsYWdzLm1vZGUgPz8gJ2RldmVsb3BtZW50JztcbiAgY29uc3QgY2xpQ29uZmlnOiB3eHQuSW5saW5lQ29uZmlnID0ge1xuICAgIHJvb3QsXG4gICAgbW9kZSxcbiAgICBicm93c2VyOiBmbGFncy5icm93c2VyLFxuICAgIG1hbmlmZXN0VmVyc2lvbjogZmxhZ3MubXYzID8gMyA6IGZsYWdzLm12MiA/IDIgOiB1bmRlZmluZWQsXG4gICAgY29uZmlnRmlsZTogZmxhZ3MuY29uZmlnLFxuICB9O1xuXG4gIGNvbnN0IHNlcnZlciA9IGF3YWl0IHd4dC5jcmVhdGVTZXJ2ZXIoY2xpQ29uZmlnKTtcbiAgYXdhaXQgc2VydmVyLmxpc3RlbihzZXJ2ZXIucG9ydCk7XG5cbiAgcmV0dXJuIHRydWU7XG59KTtcbiIsICJpbXBvcnQgeyBjb25zb2xhIH0gZnJvbSAnY29uc29sYSc7XG5pbXBvcnQgeyBkZWZpbmVDb21tYW5kIH0gZnJvbSAnLi4vdXRpbHMvZGVmaW5lQ29tbWFuZCc7XG5cbmV4cG9ydCBjb25zdCBpbml0ID0gZGVmaW5lQ29tbWFuZDxbZGlyZWN0b3J5Pzogc3RyaW5nXT4oYXN5bmMgKGRpcmVjdG9yeSkgPT4ge1xuICBjb25zb2xhLndhcm4oJ3d4dCBpbml0OiBOb3QgaW1wbGVtZW50ZWQnKTtcbn0pO1xuIiwgImltcG9ydCB7IGdldEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vLi4vY29yZS91dGlscy9nZXRJbnRlcm5hbENvbmZpZyc7XG5pbXBvcnQgeyBmaW5kRW50cnlwb2ludHMgfSBmcm9tICcuLi8uLi9jb3JlL2J1aWxkL2ZpbmRFbnRyeXBvaW50cyc7XG5pbXBvcnQgeyBnZW5lcmF0ZVR5cGVzRGlyIH0gZnJvbSAnLi4vLi4vY29yZS9idWlsZC9nZW5lcmF0ZVR5cGVzRGlyJztcbmltcG9ydCB7IGRlZmluZUNvbW1hbmQgfSBmcm9tICcuLi91dGlscy9kZWZpbmVDb21tYW5kJztcbmltcG9ydCAqIGFzIHd4dCBmcm9tICcuLi8uLic7XG5cbmV4cG9ydCBjb25zdCBwcmVwYXJlID0gZGVmaW5lQ29tbWFuZDxcbiAgW1xuICAgIHJvb3Q6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBmbGFnczoge1xuICAgICAgY29uZmlnPzogc3RyaW5nO1xuICAgIH0sXG4gIF1cbj4oYXN5bmMgKHJvb3QsIGZsYWdzKSA9PiB7XG4gIGNvbnN0IGNsaUNvbmZpZzogd3h0LklubGluZUNvbmZpZyA9IHtcbiAgICByb290LFxuICAgIGNvbmZpZ0ZpbGU6IGZsYWdzLmNvbmZpZyxcbiAgfTtcbiAgY29uc3QgY29uZmlnID0gYXdhaXQgZ2V0SW50ZXJuYWxDb25maWcoY2xpQ29uZmlnLCAnYnVpbGQnKTtcblxuICBjb25maWcubG9nZ2VyLmluZm8oJ0dlbmVyYXRpbmcgdHlwZXMuLi4nKTtcblxuICBjb25zdCBlbnRyeXBvaW50cyA9IGF3YWl0IGZpbmRFbnRyeXBvaW50cyhjb25maWcpO1xuICBhd2FpdCBnZW5lcmF0ZVR5cGVzRGlyKGVudHJ5cG9pbnRzLCBjb25maWcpO1xufSk7XG4iLCAiaW1wb3J0IHsgY29uc29sYSB9IGZyb20gJ2NvbnNvbGEnO1xuaW1wb3J0IHsgZGVmaW5lQ29tbWFuZCB9IGZyb20gJy4uL3V0aWxzL2RlZmluZUNvbW1hbmQnO1xuXG5leHBvcnQgY29uc3QgcHVibGlzaCA9IGRlZmluZUNvbW1hbmQoXG4gIGFzeW5jIChyb290OiBhbnksIHsgY29uZmlnOiBjb25maWdGaWxlIH06IGFueSkgPT4ge1xuICAgIGNvbnNvbGEud2Fybignd3h0IHB1Ymxpc2g6IE5vdCBpbXBsZW1lbnRlZCcpO1xuICB9LFxuKTtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsaUJBQWdCOzs7QUNDZCxjQUFXOzs7QUNHYixJQUFBQSxvQkFBOEI7QUFDOUIsSUFBQUMsUUFBc0I7QUFDdEIsSUFBQUMsa0JBQXdCOzs7QUNSeEIscUJBQXdCO0FBQ3hCLGtCQUF1QjtBQUN2QixtQkFBc0I7QUFDdEIsa0JBQXdCO0FBQ3hCLHNCQUE0QjtBQUU1QixlQUFzQixhQUFnQixNQUFjQyxPQUEwQjtBQUM1RSxRQUFNLGdCQUFnQixVQUFNO0FBQUEsUUFDMUIscUJBQVEsTUFBTSxpQ0FBaUM7QUFBQSxFQUNqRDtBQUNBLFFBQU0sV0FBTyxZQUFBQyxTQUFXLFlBQVk7QUFBQSxJQUNsQyxPQUFPO0FBQUEsSUFDUCxZQUFZO0FBQUEsSUFDWixnQkFBZ0I7QUFBQSxJQUVoQixVQUFVLE1BQU07QUFFZCxXQUFLLFNBQVMsS0FBSyxPQUFPLFFBQVEsZ0NBQWdDLEVBQUU7QUFDcEUsV0FBSyxTQUFTLEtBQUssT0FBTztBQUFBLFFBQ3hCO0FBQUEsUUFDQTtBQUFBLE1BQ0Y7QUFHQSxVQUFJLEtBQUssYUFBYUQsT0FBTTtBQUUxQixjQUFNLFVBQ0osY0FDRyxJQUFJLENBQUMsTUFBTSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUNuRCxLQUFLLElBQUksSUFBSTtBQUNsQixhQUFLLFNBQVMsVUFBVSxLQUFLO0FBQUEsTUFDL0I7QUFHQSxpQkFBTyxhQUFBRSxTQUFVLElBQUk7QUFBQSxJQUN2QjtBQUFBLEVBQ0YsQ0FBQztBQUNELE1BQUk7QUFDRixXQUFPLE1BQU0sS0FBS0YsS0FBSTtBQUFBLEVBQ3hCLFNBQVMsS0FBUDtBQUNBLDJCQUFRLE1BQU0sMEJBQTBCQSxPQUFNO0FBQzlDLFVBQU07QUFBQSxFQUNSO0FBQ0Y7OztBQzNDQSxXQUFzQjs7O0FDQ3RCLHVCQUF3QztBQUVqQyxTQUFTLGtC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QyxPQUFnQixHQUFHO0FBR3RCLElBQ0csUUFBUSxnQkFBZ0Isc0JBQXNCLEVBQzlDLE9BQU8sdUJBQXVCLDJCQUEyQixFQUN6RCxPQUFPLHFCQUFxQixjQUFjLEVBQzFDLE9BQU8sMkJBQTJCLG1CQUFtQixFQUNyRCxPQUFPLFNBQVMsb0JBQW9CLEVBQ3BDLE9BQU8sU0FBUyxvQkFBb0IsRUFDcEMsT0FBZ0JDLE1BQUs7QUFHeEIsSUFDRyxRQUFRLGtCQUFrQixTQUFTLEVBQ25DLE9BQU8sdUJBQXVCLDJCQUEyQixFQUN6RCxPQUFnQixPQUFPO0FBRzFCLElBQUksUUFBUSxrQkFBa0IsbUJBQW1CLEVBQUUsT0FBZ0IsT0FBTztBQUcxRSxJQUNHLFFBQVEsb0JBQW9CLDBCQUEwQixFQUN0RCxPQUFnQixJQUFJO0FBRXZCLElBQUksTUFBTTsiLAogICJuYW1lcyI6IFsiaW1wb3J0X25vZGVfcGF0aCIsICJ2aXRlIiwgImltcG9ydF9jb25zb2xhIiwgInBhdGgiLCAiY3JlYXRlSklUSSIsICJ0cmFuc2Zvcm0iLCAicGF0aCIsICJpbXBvcnRfcGF0aCIsICJpc09mZmxpbmUiLCAiZG5zIiwgImltcG9ydF9ub2RlX3BhdGgiLCAiZnMiLCAiaW1wb3J0X3VuaW1wb3J0IiwgInVuaW1wb3J0IiwgImltcG9ydF9mc19leHRyYSIsICJpbXBvcnRfcGF0aCIsICJmcyIsICJpbXBvcnRfZnNfZXh0cmEiLCAiaW1wb3J0X3BhdGgiLCAicGF0aCIsICJmcyIsICJwYXRoIiwgImltcG9ydF9wYXRoIiwgImltcG9ydF9mc19leHRyYSIsICJpbXBvcnRfbGlua2Vkb20iLCAiZ2xvYiIsICJwYXRoIiwgInBpY29tYXRjaCIsICJmcyIsICJKU09ONSIsICJ2aXRlIiwgImltcG9ydF9mc19leHRyYSIsICJpbXBvcnRfcGF0aCIsICJmcyIsICJwYXRoIiwgImltcG9ydF9mYXN0X2dsb2IiLCAiaW1wb3J0X2ZzX2V4dHJhIiwgImltcG9ydF9wYXRoIiwgImZzIiwgImdsb2IiLCAiaW1wb3J0X2ZzX2V4dHJhIiwgImltcG9ydF9wYXRoIiwgImZzIiwgInZlcnNpb24iLCAib3B0aW9ucyIsICJpbXBvcnRfcGF0aCIsICJpbXBvcnRfZnNfZXh0cmEiLCAicGF0aCIsICJmcyIsICJwYyIsICJpbXBvcnRfZnNfZXh0cmEiLCAiaW1wb3J0X3VuaW1wb3J0IiwgImltcG9ydF9mc19leHRyYSIsICJpbXBvcnRfcGF0aCIsICJmcyIsICJ1bmltcG9ydCIsICJwYXRoIiwgImltcG9ydF9waWNvY29sb3JzIiwgInZpdGUiLCAicmVzb2x2ZSIsICJuZXQiLCAiaW1wb3J0X2NvbnNvbGEiLCAiaW1wb3J0X25vZGVfcGF0aCIsICJidWlsZCIsICJjcmVhdGVTZXJ2ZXIiLCAicGF0aCIsICJwYyIsICJwb3J0IiwgImZzIiwgImltcG9ydF9jb25zb2xhIiwgImltcG9ydF9waWNvY29sb3JzIiwgImltcG9ydF9jb25zb2xhIiwgInBjIiwgImJ1aWxkIiwgImNyZWF0ZVNlcnZlciIsICJpbXBvcnRfY29uc29sYSIsICJpbXBvcnRfY29uc29sYSIsICJjYWMiLCAiYnVpbGQiXQp9Cg==