wxt 0.8.4 → 0.8.6

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.
Files changed (36) hide show
  1. package/README.md +3 -2
  2. package/dist/browser.js +3 -4
  3. package/dist/chunk-FNTE2L27.js +7 -0
  4. package/dist/chunk-VFZ5667B.js +2410 -0
  5. package/dist/chunk-YUG22S6W.js +38 -0
  6. package/dist/cli.cjs +3941 -3775
  7. package/dist/cli.d.cts +2 -0
  8. package/dist/client.d.ts +5 -171
  9. package/dist/client.js +128 -131
  10. package/dist/execa-WKZHVHC5.js +2043 -0
  11. package/dist/external-9107db91.d.ts +176 -0
  12. package/dist/external-cb0967d6.d.ts +572 -0
  13. package/dist/index.cjs +2727 -2355
  14. package/dist/index.d.cts +36 -583
  15. package/dist/index.d.ts +36 -583
  16. package/dist/index.js +330 -4484
  17. package/dist/sandbox.d.ts +2 -23
  18. package/dist/sandbox.js +1 -2
  19. package/dist/testing.cjs +161 -35
  20. package/dist/testing.d.cts +7 -273
  21. package/dist/testing.d.ts +7 -273
  22. package/dist/testing.js +12 -676
  23. package/dist/{virtual-modules → virtual}/background-entrypoint.js +6 -7
  24. package/dist/{virtual-modules → virtual}/content-script-entrypoint.js +4 -5
  25. package/dist/virtual/mock-browser.js +152 -0
  26. package/dist/{virtual-modules → virtual}/reload-html.js +2 -3
  27. package/dist/{virtual-modules → virtual}/unlisted-script-entrypoint.js +2 -3
  28. package/package.json +6 -5
  29. package/dist/index.cjs.map +0 -1
  30. package/dist/index.js.map +0 -1
  31. package/dist/virtual-modules/background-entrypoint.js.map +0 -1
  32. package/dist/virtual-modules/content-script-entrypoint.js.map +0 -1
  33. package/dist/virtual-modules/fake-browser.cjs +0 -31
  34. package/dist/virtual-modules/fake-browser.js +0 -8
  35. package/dist/virtual-modules/reload-html.js.map +0 -1
  36. package/dist/virtual-modules/unlisted-script-entrypoint.js.map +0 -1
package/dist/testing.js CHANGED
@@ -1,685 +1,22 @@
1
+ import {
2
+ download,
3
+ getInternalConfig,
4
+ globals,
5
+ tsconfigPaths,
6
+ unimport,
7
+ webextensionPolyfillAlias,
8
+ webextensionPolyfillInlineDeps
9
+ } from "./chunk-VFZ5667B.js";
10
+ import "./chunk-YUG22S6W.js";
11
+
1
12
  // src/testing/fake-browser.ts
2
13
  import { fakeBrowser } from "@webext-core/fake-browser";
3
14
 
4
- // src/core/utils/entrypoints.ts
5
- import path, { relative, resolve } from "node:path";
6
-
7
- // src/core/utils/paths.ts
8
- import * as vite from "vite";
9
- function normalizePath2(path4) {
10
- return vite.normalizePath(path4);
11
- }
12
- var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
13
- var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
14
-
15
- // src/core/utils/entrypoints.ts
16
- function getEntrypointName(entrypointsDir, inputPath) {
17
- const relativePath = path.relative(entrypointsDir, inputPath);
18
- const name = relativePath.split(/[\.\/\\]/, 2)[0];
19
- return name;
20
- }
21
-
22
- // src/core/vite-plugins/devHtmlPrerender.ts
23
- import { parseHTML } from "linkedom";
24
- import { dirname, isAbsolute, relative as relative2, resolve as resolve2 } from "path";
25
- var reactRefreshPreamble = "";
26
- function devHtmlPrerender(config) {
27
- const htmlReloadId = "@wxt/reload-html";
28
- const resolvedHtmlReloadId = resolve2(
29
- config.root,
30
- "node_modules/wxt/dist/virtual-modules/reload-html.js"
31
- );
32
- const virtualReactRefreshId = "@wxt/virtual-react-refresh";
33
- const resolvedVirtualReactRefreshId = "\0" + virtualReactRefreshId;
34
- return [
35
- {
36
- apply: "build",
37
- name: "wxt:dev-html-prerender",
38
- config() {
39
- return {
40
- resolve: {
41
- alias: {
42
- [htmlReloadId]: resolvedHtmlReloadId
43
- }
44
- }
45
- };
46
- },
47
- // Convert scripts like src="./main.tsx" -> src="http://localhost:3000/entrypoints/popup/main.tsx"
48
- // before the paths are replaced with their bundled path
49
- transform(code, id) {
50
- const server = config.server;
51
- if (config.command !== "serve" || server == null || !id.endsWith(".html"))
52
- return;
53
- const { document } = parseHTML(code);
54
- const pointToDevServer = (querySelector, attr) => {
55
- document.querySelectorAll(querySelector).forEach((element) => {
56
- const src = element.getAttribute(attr);
57
- if (!src)
58
- return;
59
- if (isAbsolute(src)) {
60
- element.setAttribute(attr, server.origin + src);
61
- } else if (src.startsWith(".")) {
62
- const abs = resolve2(dirname(id), src);
63
- const pathname = relative2(config.root, abs);
64
- element.setAttribute(attr, `${server.origin}/${pathname}`);
65
- }
66
- });
67
- };
68
- pointToDevServer("script[type=module]", "src");
69
- pointToDevServer("link[rel=stylesheet]", "href");
70
- const reloader = document.createElement("script");
71
- reloader.src = htmlReloadId;
72
- reloader.type = "module";
73
- document.head.appendChild(reloader);
74
- const newHtml = document.toString();
75
- config.logger.debug("transform " + id);
76
- config.logger.debug("Old HTML:\n" + code);
77
- config.logger.debug("New HTML:\n" + newHtml);
78
- return newHtml;
79
- },
80
- // Pass the HTML through the dev server to add dev-mode specific code
81
- async transformIndexHtml(html, ctx) {
82
- const server = config.server;
83
- if (config.command !== "serve" || server == null)
84
- return;
85
- const originalUrl = `${server.origin}${ctx.path}`;
86
- const name = getEntrypointName(config.entrypointsDir, ctx.filename);
87
- const url = `${server.origin}/${name}.html`;
88
- const serverHtml = await server.transformIndexHtml(
89
- url,
90
- html,
91
- originalUrl
92
- );
93
- const { document } = parseHTML(serverHtml);
94
- const reactRefreshScript = Array.from(
95
- document.querySelectorAll("script[type=module]")
96
- ).find((script) => script.innerHTML.includes("@react-refresh"));
97
- if (reactRefreshScript) {
98
- reactRefreshPreamble = reactRefreshScript.innerHTML;
99
- const virtualScript = document.createElement("script");
100
- virtualScript.type = "module";
101
- virtualScript.src = `${server.origin}/${virtualReactRefreshId}`;
102
- reactRefreshScript.replaceWith(virtualScript);
103
- }
104
- const viteClientScript = document.querySelector(
105
- "script[src='/@vite/client']"
106
- );
107
- if (viteClientScript) {
108
- viteClientScript.src = `${server.origin}${viteClientScript.src}`;
109
- }
110
- const newHtml = document.toString();
111
- config.logger.debug("transformIndexHtml " + ctx.filename);
112
- config.logger.debug("Old HTML:\n" + html);
113
- config.logger.debug("New HTML:\n" + newHtml);
114
- return newHtml;
115
- }
116
- },
117
- {
118
- name: "wxt:virtualize-react-refresh",
119
- apply: "serve",
120
- resolveId(id) {
121
- if (id === `/${virtualReactRefreshId}`) {
122
- return resolvedVirtualReactRefreshId;
123
- }
124
- if (id.startsWith("/chunks/")) {
125
- return "\0noop";
126
- }
127
- },
128
- load(id) {
129
- if (id === resolvedVirtualReactRefreshId) {
130
- return reactRefreshPreamble;
131
- }
132
- if (id === "\0noop") {
133
- return "";
134
- }
135
- }
136
- }
137
- ];
138
- }
139
-
140
- // src/core/vite-plugins/devServerGlobals.ts
141
- function devServerGlobals(internalConfig) {
142
- return {
143
- name: "wxt:dev-server-globals",
144
- config() {
145
- if (internalConfig.server == null || internalConfig.command == "build")
146
- return;
147
- return {
148
- define: {
149
- __DEV_SERVER_PROTOCOL__: JSON.stringify("ws:"),
150
- __DEV_SERVER_HOSTNAME__: JSON.stringify(
151
- internalConfig.server.hostname
152
- ),
153
- __DEV_SERVER_PORT__: JSON.stringify(internalConfig.server.port)
154
- }
155
- };
156
- }
157
- };
158
- }
159
-
160
- // src/core/utils/network.ts
161
- import dns from "node:dns";
162
-
163
- // src/core/utils/promises.ts
164
- function withTimeout(promise, duration) {
165
- return new Promise((res, rej) => {
166
- const timeout = setTimeout(() => {
167
- rej(`Promise timed out after ${duration}ms`);
168
- }, duration);
169
- promise.then(res).catch(rej).finally(() => clearTimeout(timeout));
170
- });
171
- }
172
-
173
- // src/core/utils/network.ts
174
- function isOffline() {
175
- const isOffline2 = new Promise((res) => {
176
- dns.resolve("google.com", (err) => {
177
- if (err == null) {
178
- res(false);
179
- } else {
180
- res(true);
181
- }
182
- });
183
- });
184
- return withTimeout(isOffline2, 1e3).catch(() => true);
185
- }
186
- async function isOnline() {
187
- const offline = await isOffline();
188
- return !offline;
189
- }
190
- async function fetchCached(url, config) {
191
- let content = "";
192
- if (await isOnline()) {
193
- const res = await fetch(url);
194
- if (res.status < 300) {
195
- content = await res.text();
196
- await config.fsCache.set(url, content);
197
- } else {
198
- config.logger.debug(
199
- `Failed to download "${url}", falling back to cache...`
200
- );
201
- }
202
- }
203
- if (!content)
204
- content = await config.fsCache.get(url) ?? "";
205
- if (!content)
206
- throw Error(
207
- `Offline and "${url}" has not been cached. Try again when online.`
208
- );
209
- return content;
210
- }
211
-
212
- // src/core/vite-plugins/download.ts
213
- function download(config) {
214
- return {
215
- name: "wxt:download",
216
- resolveId(id) {
217
- if (id.startsWith("url:"))
218
- return "\0" + id;
219
- },
220
- async load(id) {
221
- if (!id.startsWith("\0url:"))
222
- return;
223
- const url = id.replace("\0url:", "");
224
- return await fetchCached(url, config);
225
- }
226
- };
227
- }
228
-
229
- // src/core/vite-plugins/multipageMove.ts
230
- import fs, { ensureDir } from "fs-extra";
231
-
232
- // src/core/vite-plugins/unimport.ts
233
- import { createUnimport } from "unimport";
234
-
235
- // src/core/utils/auto-imports.ts
236
- import { mergeConfig } from "vite";
237
- function getUnimportOptions(config) {
238
- if (config.imports === false)
239
- return false;
240
- const defaultOptions = {
241
- debugLog: config.logger.debug,
242
- imports: [
243
- { name: "defineConfig", from: "wxt" },
244
- { name: "fakeBrowser", from: "wxt/testing" }
245
- ],
246
- presets: [
247
- { package: "wxt/client" },
248
- { package: "wxt/browser" },
249
- { package: "wxt/sandbox" }
250
- ],
251
- warn: config.logger.warn,
252
- dirs: ["components", "composables", "hooks", "utils"]
253
- };
254
- return mergeConfig(
255
- defaultOptions,
256
- config.imports
257
- );
258
- }
259
-
260
- // src/core/vite-plugins/unimport.ts
261
- import { extname } from "path";
262
- var ENABLED_EXTENSIONS = {
263
- ".js": true,
264
- ".jsx": true,
265
- ".ts": true,
266
- ".tsx": true,
267
- ".vue": true,
268
- ".svelte": true
269
- };
270
- function unimport(config) {
271
- const options = getUnimportOptions(config);
272
- if (options === false)
273
- return [];
274
- const unimport2 = createUnimport(options);
275
- return {
276
- name: "wxt:unimport",
277
- async config() {
278
- await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
279
- },
280
- async transform(code, id) {
281
- const ext = extname(id);
282
- if (ENABLED_EXTENSIONS[ext])
283
- return unimport2.injectImports(code, id);
284
- }
285
- };
286
- }
287
-
288
- // src/core/vite-plugins/virtualEntrypoint.ts
289
- import fs2 from "fs-extra";
290
- import { resolve as resolve3 } from "path";
291
- function virtualEntrypoint(type, config) {
292
- const virtualId = `virtual:wxt-${type}?`;
293
- const resolvedVirtualId = `\0${virtualId}`;
294
- return {
295
- name: `wxt:virtual-entrypoint`,
296
- resolveId(id) {
297
- const index = id.indexOf(virtualId);
298
- if (index === -1)
299
- return;
300
- const inputPath = normalizePath2(id.substring(index + virtualId.length));
301
- return resolvedVirtualId + inputPath;
302
- },
303
- async load(id) {
304
- if (!id.startsWith(resolvedVirtualId))
305
- return;
306
- const inputPath = id.replace(resolvedVirtualId, "");
307
- const template = await fs2.readFile(
308
- resolve3(
309
- config.root,
310
- `node_modules/wxt/dist/virtual-modules/${type}-entrypoint.js`
311
- ),
312
- "utf-8"
313
- );
314
- return template.replace(`virtual:user-${type}`, inputPath);
315
- }
316
- };
317
- }
318
-
319
- // src/core/vite-plugins/tsconfigPaths.ts
320
- function tsconfigPaths(config) {
321
- return {
322
- name: "wxt:aliases",
323
- async config() {
324
- return {
325
- resolve: {
326
- alias: {
327
- "@@": config.root,
328
- "~~": config.root,
329
- "@": config.srcDir,
330
- "~": config.srcDir
331
- }
332
- }
333
- };
334
- }
335
- };
336
- }
337
-
338
- // src/core/vite-plugins/noopBackground.ts
339
- function noopBackground() {
340
- const virtualModuleId = VIRTUAL_NOOP_BACKGROUND_MODULE_ID;
341
- const resolvedVirtualModuleId = "\0" + virtualModuleId;
342
- return {
343
- name: "wxt:noop-background",
344
- resolveId(id) {
345
- if (id === virtualModuleId)
346
- return resolvedVirtualModuleId;
347
- },
348
- load(id) {
349
- if (id === resolvedVirtualModuleId) {
350
- return `import { defineBackground } from 'wxt/client';
351
- export default defineBackground(() => void 0)`;
352
- }
353
- }
354
- };
355
- }
356
- var VIRTUAL_NOOP_BACKGROUND_MODULE_ID = "virtual:user-background";
357
-
358
- // src/core/vite-plugins/bundleAnalysis.ts
359
- import { visualizer } from "rollup-plugin-visualizer";
360
- var increment = 0;
361
- function bundleAnalysis() {
362
- return visualizer({
363
- emitFile: true,
364
- template: "raw-data",
365
- filename: `stats-${increment++}.json`
366
- });
367
- }
368
-
369
- // src/core/utils/globals.ts
370
- function getGlobals(config) {
371
- return [
372
- {
373
- name: surroundInUnderscore("MANIFEST_VERSION"),
374
- value: config.manifestVersion,
375
- type: `2 | 3`
376
- },
377
- {
378
- name: surroundInUnderscore("BROWSER"),
379
- value: config.browser,
380
- type: `string`
381
- },
382
- {
383
- name: surroundInUnderscore("IS_CHROME"),
384
- value: config.browser === "chrome",
385
- type: `boolean`
386
- },
387
- {
388
- name: surroundInUnderscore("IS_FIREFOX"),
389
- value: config.browser === "firefox",
390
- type: `boolean`
391
- },
392
- {
393
- name: surroundInUnderscore("IS_SAFARI"),
394
- value: config.browser === "safari",
395
- type: `boolean`
396
- },
397
- {
398
- name: surroundInUnderscore("IS_EDGE"),
399
- value: config.browser === "edge",
400
- type: `boolean`
401
- },
402
- {
403
- name: surroundInUnderscore("IS_OPERA"),
404
- value: config.browser === "opera",
405
- type: `boolean`
406
- },
407
- {
408
- name: surroundInUnderscore("COMMAND"),
409
- value: config.command,
410
- type: `"build" | "serve"`
411
- }
412
- ];
413
- }
414
- function surroundInUnderscore(name) {
415
- return `__${name}__`;
416
- }
417
-
418
- // src/core/vite-plugins/globals.ts
419
- function globals(config) {
420
- return {
421
- name: "wxt:globals",
422
- config() {
423
- const define = {};
424
- for (const global of getGlobals(config)) {
425
- define[global.name] = JSON.stringify(global.value);
426
- }
427
- return {
428
- define
429
- };
430
- }
431
- };
432
- }
433
-
434
- // src/core/vite-plugins/webextensionPolyfillAlias.ts
435
- import path2 from "node:path";
436
- function webextensionPolyfillAlias(config) {
437
- return {
438
- name: "wxt:webextension-polyfill-test-alias",
439
- config() {
440
- return {
441
- resolve: {
442
- alias: {
443
- "webextension-polyfill": path2.resolve(
444
- config.root,
445
- "node_modules/wxt/dist/virtual-modules/fake-browser"
446
- )
447
- }
448
- }
449
- };
450
- }
451
- };
452
- }
453
-
454
- // src/core/utils/getInternalConfig.ts
455
- import { loadConfig } from "c12";
456
- import path3 from "node:path";
457
- import * as vite2 from "vite";
458
-
459
- // src/core/utils/createFsCache.ts
460
- import fs4, { ensureDir as ensureDir2 } from "fs-extra";
461
- import { dirname as dirname2, resolve as resolve4 } from "path";
462
-
463
- // src/core/utils/fs.ts
464
- import fs3 from "fs-extra";
465
- async function writeFileIfDifferent(file, newContents) {
466
- const existingContents = await fs3.readFile(file, "utf-8").catch(() => void 0);
467
- if (existingContents !== newContents) {
468
- await fs3.writeFile(file, newContents);
469
- }
470
- }
471
-
472
- // src/core/utils/createFsCache.ts
473
- function createFsCache(wxtDir) {
474
- const getPath = (key) => resolve4(wxtDir, "cache", encodeURIComponent(key));
475
- return {
476
- async set(key, value) {
477
- const path4 = getPath(key);
478
- await ensureDir2(dirname2(path4));
479
- await writeFileIfDifferent(path4, value);
480
- },
481
- async get(key) {
482
- const path4 = getPath(key);
483
- try {
484
- return await fs4.readFile(path4, "utf-8");
485
- } catch {
486
- return void 0;
487
- }
488
- }
489
- };
490
- }
491
-
492
- // src/core/utils/getInternalConfig.ts
493
- import consola, { LogLevels } from "consola";
494
- async function getInternalConfig(inlineConfig, command) {
495
- let userConfig = {};
496
- let userConfigMetadata;
497
- if (inlineConfig.configFile !== false) {
498
- const { config: loadedConfig, ...metadata } = await loadConfig({
499
- name: "wxt",
500
- cwd: inlineConfig.root ?? process.cwd(),
501
- rcFile: false
502
- });
503
- userConfig = loadedConfig ?? {};
504
- userConfigMetadata = metadata;
505
- }
506
- const mergedConfig = mergeInlineConfig(inlineConfig, userConfig);
507
- const debug = mergedConfig.debug ?? false;
508
- const logger = mergedConfig.logger ?? consola;
509
- if (debug)
510
- logger.level = LogLevels.debug;
511
- const browser = mergedConfig.browser ?? "chrome";
512
- const manifestVersion = mergedConfig.manifestVersion ?? (browser === "firefox" || browser === "safari" ? 2 : 3);
513
- const mode = mergedConfig.mode ?? (command === "build" ? "production" : "development");
514
- const env = { browser, command, manifestVersion, mode };
515
- const root = path3.resolve(
516
- inlineConfig.root ?? userConfig.root ?? process.cwd()
517
- );
518
- const wxtDir = path3.resolve(root, ".wxt");
519
- const srcDir = path3.resolve(root, mergedConfig.srcDir ?? root);
520
- const entrypointsDir = path3.resolve(
521
- srcDir,
522
- mergedConfig.entrypointsDir ?? "entrypoints"
523
- );
524
- const publicDir = path3.resolve(srcDir, mergedConfig.publicDir ?? "public");
525
- const typesDir = path3.resolve(wxtDir, "types");
526
- const outBaseDir = path3.resolve(root, ".output");
527
- const outDir = path3.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
528
- const runnerConfig = await loadConfig({
529
- name: "web-ext",
530
- cwd: root,
531
- globalRc: true,
532
- rcFile: ".webextrc",
533
- overrides: inlineConfig.runner,
534
- defaults: userConfig.runner
535
- });
536
- const finalConfig = {
537
- browser,
538
- command,
539
- debug,
540
- entrypointsDir,
541
- env,
542
- fsCache: createFsCache(wxtDir),
543
- imports: mergedConfig.imports ?? {},
544
- logger,
545
- manifest: await resolveManifestConfig(env, mergedConfig.manifest),
546
- manifestVersion,
547
- mode,
548
- outBaseDir,
549
- outDir,
550
- publicDir,
551
- root,
552
- runnerConfig,
553
- srcDir,
554
- typesDir,
555
- vite: () => ({}),
556
- // Real value added after this object is initialized.
557
- wxtDir,
558
- zip: resolveInternalZipConfig(root, mergedConfig),
559
- transformManifest(manifest) {
560
- userConfig.transformManifest?.(manifest);
561
- inlineConfig.transformManifest?.(manifest);
562
- },
563
- analysis: {
564
- enabled: mergedConfig.analysis?.enabled ?? false,
565
- template: mergedConfig.analysis?.template ?? "treemap"
566
- },
567
- userConfigMetadata: userConfigMetadata ?? {}
568
- };
569
- finalConfig.vite = (env2) => resolveInternalViteConfig(env2, mergedConfig, finalConfig);
570
- return finalConfig;
571
- }
572
- async function resolveManifestConfig(env, manifest) {
573
- return await (typeof manifest === "function" ? manifest(env) : manifest ?? {});
574
- }
575
- function mergeInlineConfig(inlineConfig, userConfig) {
576
- let imports;
577
- if (inlineConfig.imports === false || userConfig.imports === false) {
578
- imports = false;
579
- } else if (userConfig.imports == null && inlineConfig.imports == null) {
580
- imports = void 0;
581
- } else {
582
- imports = vite2.mergeConfig(
583
- userConfig.imports ?? {},
584
- inlineConfig.imports ?? {}
585
- );
586
- }
587
- const manifest = async (env) => {
588
- const user = await resolveManifestConfig(env, userConfig.manifest);
589
- const inline = await resolveManifestConfig(env, inlineConfig.manifest);
590
- return vite2.mergeConfig(user, inline);
591
- };
592
- const viteConfig = async (env) => {
593
- const user = await userConfig.vite?.(env);
594
- const inline = await inlineConfig.vite?.(env);
595
- return vite2.mergeConfig(user ?? {}, inline ?? {});
596
- };
597
- const runner = vite2.mergeConfig(
598
- userConfig.runner ?? {},
599
- inlineConfig.runner ?? {}
600
- );
601
- const zip = vite2.mergeConfig(
602
- userConfig.zip ?? {},
603
- inlineConfig.zip ?? {}
604
- );
605
- return {
606
- root: inlineConfig.root ?? userConfig.root,
607
- browser: inlineConfig.browser ?? userConfig.browser,
608
- manifestVersion: inlineConfig.manifestVersion ?? userConfig.manifestVersion,
609
- configFile: inlineConfig.configFile,
610
- debug: inlineConfig.debug ?? userConfig.debug,
611
- entrypointsDir: inlineConfig.entrypointsDir ?? userConfig.entrypointsDir,
612
- imports,
613
- logger: inlineConfig.logger ?? userConfig.logger,
614
- manifest,
615
- mode: inlineConfig.mode ?? userConfig.mode,
616
- publicDir: inlineConfig.publicDir ?? userConfig.publicDir,
617
- runner,
618
- srcDir: inlineConfig.srcDir ?? userConfig.srcDir,
619
- vite: viteConfig,
620
- zip,
621
- analysis: {
622
- enabled: inlineConfig.analysis?.enabled ?? userConfig.analysis?.enabled,
623
- template: inlineConfig.analysis?.template ?? userConfig.analysis?.template
624
- }
625
- };
626
- }
627
- function resolveInternalZipConfig(root, mergedConfig) {
628
- return {
629
- sourcesTemplate: "{{name}}-{{version}}-sources.zip",
630
- artifactTemplate: "{{name}}-{{version}}-{{browser}}.zip",
631
- sourcesRoot: root,
632
- ...mergedConfig.zip,
633
- ignoredSources: [
634
- "**/node_modules",
635
- // WXT files
636
- "**/web-ext.config.ts",
637
- // Hidden files
638
- "**/.*",
639
- // Tests
640
- "**/__tests__/**",
641
- "**/*.+(test|spec).?(c|m)+(j|t)s?(x)",
642
- // From user
643
- ...mergedConfig.zip?.ignoredSources ?? []
644
- ]
645
- };
646
- }
647
- async function resolveInternalViteConfig(env, mergedConfig, finalConfig) {
648
- const internalVite = await mergedConfig.vite?.(env) ?? {};
649
- internalVite.root = finalConfig.root;
650
- internalVite.configFile = false;
651
- internalVite.logLevel = "warn";
652
- internalVite.mode = env.mode;
653
- internalVite.build ??= {};
654
- internalVite.build.outDir = finalConfig.outDir;
655
- internalVite.build.emptyOutDir = false;
656
- internalVite.plugins ??= [];
657
- internalVite.plugins.push(download(finalConfig));
658
- internalVite.plugins.push(devHtmlPrerender(finalConfig));
659
- internalVite.plugins.push(unimport(finalConfig));
660
- internalVite.plugins.push(
661
- virtualEntrypoint("background", finalConfig)
662
- );
663
- internalVite.plugins.push(
664
- virtualEntrypoint("content-script", finalConfig)
665
- );
666
- internalVite.plugins.push(
667
- virtualEntrypoint("unlisted-script", finalConfig)
668
- );
669
- internalVite.plugins.push(devServerGlobals(finalConfig));
670
- internalVite.plugins.push(tsconfigPaths(finalConfig));
671
- internalVite.plugins.push(noopBackground());
672
- if (finalConfig.analysis.enabled) {
673
- internalVite.plugins.push(bundleAnalysis());
674
- }
675
- internalVite.plugins.push(globals(finalConfig));
676
- return internalVite;
677
- }
678
-
679
15
  // src/testing/wxt-vitest-plugin.ts
680
16
  function WxtVitest(inlineConfig) {
681
17
  return getInternalConfig(inlineConfig ?? {}, "serve").then((config) => [
682
18
  webextensionPolyfillAlias(config),
19
+ webextensionPolyfillInlineDeps(),
683
20
  unimport(config),
684
21
  globals(config),
685
22
  download(config),
@@ -690,4 +27,3 @@ export {
690
27
  WxtVitest,
691
28
  fakeBrowser
692
29
  };
693
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3Rlc3RpbmcvZmFrZS1icm93c2VyLnRzIiwgIi4uL3NyYy9jb3JlL3V0aWxzL2VudHJ5cG9pbnRzLnRzIiwgIi4uL3NyYy9jb3JlL3V0aWxzL3BhdGhzLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy9kZXZIdG1sUHJlcmVuZGVyLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy9kZXZTZXJ2ZXJHbG9iYWxzLnRzIiwgIi4uL3NyYy9jb3JlL3V0aWxzL25ldHdvcmsudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvcHJvbWlzZXMudHMiLCAiLi4vc3JjL2NvcmUvdml0ZS1wbHVnaW5zL2Rvd25sb2FkLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy9tdWx0aXBhZ2VNb3ZlLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy91bmltcG9ydC50cyIsICIuLi9zcmMvY29yZS91dGlscy9hdXRvLWltcG9ydHMudHMiLCAiLi4vc3JjL2NvcmUvdml0ZS1wbHVnaW5zL3ZpcnR1YWxFbnRyeXBvaW50LnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy90c2NvbmZpZ1BhdGhzLnRzIiwgIi4uL3NyYy9jb3JlL3ZpdGUtcGx1Z2lucy9ub29wQmFja2dyb3VuZC50cyIsICIuLi9zcmMvY29yZS92aXRlLXBsdWdpbnMvYnVuZGxlQW5hbHlzaXMudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvZ2xvYmFscy50cyIsICIuLi9zcmMvY29yZS92aXRlLXBsdWdpbnMvZ2xvYmFscy50cyIsICIuLi9zcmMvY29yZS92aXRlLXBsdWdpbnMvd2ViZXh0ZW5zaW9uUG9seWZpbGxBbGlhcy50cyIsICIuLi9zcmMvY29yZS91dGlscy9nZXRJbnRlcm5hbENvbmZpZy50cyIsICIuLi9zcmMvY29yZS91dGlscy9jcmVhdGVGc0NhY2hlLnRzIiwgIi4uL3NyYy9jb3JlL3V0aWxzL2ZzLnRzIiwgIi4uL3NyYy90ZXN0aW5nL3d4dC12aXRlc3QtcGx1Z2luLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJleHBvcnQgeyBmYWtlQnJvd3NlciwgdHlwZSBGYWtlQnJvd3NlciB9IGZyb20gJ0B3ZWJleHQtY29yZS9mYWtlLWJyb3dzZXInO1xuIiwgImltcG9ydCB7IEVudHJ5cG9pbnQsIFBlckJyb3dzZXJPcHRpb24sIFRhcmdldEJyb3dzZXIgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgcGF0aCwgeyByZWxhdGl2ZSwgcmVzb2x2ZSB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBub3JtYWxpemVQYXRoIH0gZnJvbSAnLi9wYXRocyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbnRyeXBvaW50TmFtZShcbiAgZW50cnlwb2ludHNEaXI6IHN0cmluZyxcbiAgaW5wdXRQYXRoOiBzdHJpbmcsXG4gIC8vIHR5cGU6IEVudHJ5cG9pbnRbJ3R5cGUnXSxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHJlbGF0aXZlUGF0aCA9IHBhdGgucmVsYXRpdmUoZW50cnlwb2ludHNEaXIsIGlucHV0UGF0aCk7XG4gIC8vIEdyYWIgdGhlIHN0cmluZyB1cCB0byB0aGUgZmlyc3QgLiBvciAvIG9yIFxcXFxcbiAgY29uc3QgbmFtZSA9IHJlbGF0aXZlUGF0aC5zcGxpdCgvW1xcLlxcL1xcXFxdLywgMilbMF07XG5cbiAgcmV0dXJuIG5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbnRyeXBvaW50T3V0cHV0RmlsZShcbiAgZW50cnlwb2ludDogRW50cnlwb2ludCxcbiAgZXh0OiBzdHJpbmcsXG4pOiBzdHJpbmcge1xuICByZXR1cm4gcmVzb2x2ZShlbnRyeXBvaW50Lm91dHB1dERpciwgYCR7ZW50cnlwb2ludC5uYW1lfSR7ZXh0fWApO1xufVxuXG4vKipcbiAqIFJldHVybidzIHRoZSBlbnRyeXBvaW50J3Mgb3V0cHV0IHBhdGggcmVsYXRpdmUgdG8gdGhlIG91dHB1dCBkaXJlY3RvcnkuIFVzZWQgZm9yIHBhdGhzIGluIHRoZVxuICogbWFuaWZlc3QgYW5kIHJvbGx1cCdzIGJ1bmRsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoKFxuICBlbnRyeXBvaW50OiBFbnRyeXBvaW50LFxuICBvdXREaXI6IHN0cmluZyxcbiAgZXh0OiBzdHJpbmcsXG4pOiBzdHJpbmcge1xuICByZXR1cm4gbm9ybWFsaXplUGF0aChcbiAgICByZWxhdGl2ZShvdXREaXIsIGdldEVudHJ5cG9pbnRPdXRwdXRGaWxlKGVudHJ5cG9pbnQsIGV4dCkpLFxuICApO1xufVxuXG4vKipcbiAqIEdpdmVuIGFuIGVudHJ5cG9pbnQgb3B0aW9uLCByZXNvbHZlIGl0J3MgdmFsdWUgYmFzZWQgb24gYSB0YXJnZXQgYnJvd3Nlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVQZXJCcm93c2VyT3B0aW9uPFQ+KFxuICBvcHRpb246IFBlckJyb3dzZXJPcHRpb248VD4sXG4gIGJyb3dzZXI6IFRhcmdldEJyb3dzZXIsXG4pOiBUIHtcbiAgaWYgKHR5cGVvZiBvcHRpb24gPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KG9wdGlvbikpXG4gICAgcmV0dXJuIChvcHRpb24gYXMgYW55KVticm93c2VyXTtcbiAgcmV0dXJuIG9wdGlvbjtcbn1cbiIsICJpbXBvcnQgbm9kZVBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCAqIGFzIHZpdGUgZnJvbSAndml0ZSc7XG5cbi8qKlxuICogQ29udmVydHMgc3lzdGVtIHBhdGhzIHRvIG5vcm1hbGl6ZWQgYnVuZGxlciBwYXRoLiBPbiB3aW5kb3dzIGFuZCB1bml4LCB0aGlzIHJldHVybnMgcGF0aHMgd2l0aCAvXG4gKiBpbnN0ZWFkIG9mIFxcLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdml0ZS5ub3JtYWxpemVQYXRoKHBhdGgpO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgbm9ybWFsaXplZCBwYXRoLCBjb252ZXJ0IGl0IHRvIHRoZSBzeXN0ZW0gcGF0aCBzdHlsZS4gT24gV2luZG93cywgc3dpdGNoIHRvIFxcLCBvdGhlcndpc2UgdXNlIC8uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bm5vcm1hbGl6ZVBhdGgocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5vZGVQYXRoLm5vcm1hbGl6ZShwYXRoKTtcbn1cblxuZXhwb3J0IGNvbnN0IENTU19FWFRFTlNJT05TID0gWydjc3MnLCAnc2NzcycsICdzYXNzJywgJ2xlc3MnLCAnc3R5bCcsICdzdHlsdXMnXTtcblxuLy8gLm1vZHVsZS5jc3MgZmlsZXMgYXJlIG5vdCBzdXBwb3J0ZWQgYmVjYXVzZSB0aGVzZSBhcmUgZ2xvYmFsIENTUyBmaWxlcywgc28gdXNpbmcgQ1NTIG1vZHVsZXMgZG9lc24ndCBtYWtlIHNlbnNlLlxuZXhwb3J0IGNvbnN0IENTU19FWFRFTlNJT05TX1BBVFRFUk4gPSBgKygke0NTU19FWFRFTlNJT05TLmpvaW4oJ3wnKX0pYDtcbiIsICJpbXBvcnQgKiBhcyB2aXRlIGZyb20gJ3ZpdGUnO1xuaW1wb3J0IHsgSW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRFbnRyeXBvaW50TmFtZSB9IGZyb20gJy4uL3V0aWxzL2VudHJ5cG9pbnRzJztcbmltcG9ydCB7IHBhcnNlSFRNTCB9IGZyb20gJ2xpbmtlZG9tJztcbmltcG9ydCB7IGRpcm5hbWUsIGlzQWJzb2x1dGUsIHJlbGF0aXZlLCByZXNvbHZlIH0gZnJvbSAncGF0aCc7XG5cbi8vIENhY2hlIHRoZSBwcmVhbWJsZSBzY3JpcHQgZm9yIGFsbCBkZXZIdG1sUHJlcmVuZGVyIHBsdWdpbnMsIG5vdCBqdXN0IG9uZVxubGV0IHJlYWN0UmVmcmVzaFByZWFtYmxlID0gJyc7XG5cbi8qKlxuICogUHJlLXJlbmRlcnMgdGhlIEhUTUwgZW50cnlwb2ludHMgd2hlbiBidWlsZGluZyB0aGUgZXh0ZW5zaW9uIHRvIGNvbm5lY3QgdG8gdGhlIGRldiBzZXJ2ZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXZIdG1sUHJlcmVuZGVyKGNvbmZpZzogSW50ZXJuYWxDb25maWcpOiB2aXRlLlBsdWdpbk9wdGlvbiB7XG4gIGNvbnN0IGh0bWxSZWxvYWRJZCA9ICdAd3h0L3JlbG9hZC1odG1sJztcbiAgY29uc3QgcmVzb2x2ZWRIdG1sUmVsb2FkSWQgPSByZXNvbHZlKFxuICAgIGNvbmZpZy5yb290LFxuICAgICdub2RlX21vZHVsZXMvd3h0L2Rpc3QvdmlydHVhbC1tb2R1bGVzL3JlbG9hZC1odG1sLmpzJyxcbiAgKTtcbiAgY29uc3QgdmlydHVhbFJlYWN0UmVmcmVzaElkID0gJ0B3eHQvdmlydHVhbC1yZWFjdC1yZWZyZXNoJztcbiAgY29uc3QgcmVzb2x2ZWRWaXJ0dWFsUmVhY3RSZWZyZXNoSWQgPSAnXFwwJyArIHZpcnR1YWxSZWFjdFJlZnJlc2hJZDtcblxuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIGFwcGx5OiAnYnVpbGQnLFxuICAgICAgbmFtZTogJ3d4dDpkZXYtaHRtbC1wcmVyZW5kZXInLFxuICAgICAgY29uZmlnKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHJlc29sdmU6IHtcbiAgICAgICAgICAgIGFsaWFzOiB7XG4gICAgICAgICAgICAgIFtodG1sUmVsb2FkSWRdOiByZXNvbHZlZEh0bWxSZWxvYWRJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICAvLyBDb252ZXJ0IHNjcmlwdHMgbGlrZSBzcmM9XCIuL21haW4udHN4XCIgLT4gc3JjPVwiaHR0cDovL2xvY2FsaG9zdDozMDAwL2VudHJ5cG9pbnRzL3BvcHVwL21haW4udHN4XCJcbiAgICAgIC8vIGJlZm9yZSB0aGUgcGF0aHMgYXJlIHJlcGxhY2VkIHdpdGggdGhlaXIgYnVuZGxlZCBwYXRoXG4gICAgICB0cmFuc2Zvcm0oY29kZSwgaWQpIHtcbiAgICAgICAgY29uc3Qgc2VydmVyID0gY29uZmlnLnNlcnZlcjtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGNvbmZpZy5jb21tYW5kICE9PSAnc2VydmUnIHx8XG4gICAgICAgICAgc2VydmVyID09IG51bGwgfHxcbiAgICAgICAgICAhaWQuZW5kc1dpdGgoJy5odG1sJylcbiAgICAgICAgKVxuICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCB7IGRvY3VtZW50IH0gPSBwYXJzZUhUTUwoY29kZSk7XG5cbiAgICAgICAgY29uc3QgcG9pbnRUb0RldlNlcnZlciA9IChcbiAgICAgICAgICBxdWVyeVNlbGVjdG9yOiBzdHJpbmcsXG4gICAgICAgICAgYXR0cjogc3RyaW5nLFxuICAgICAgICApOiB2b2lkID0+IHtcbiAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5U2VsZWN0b3IpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNyYyA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHIpO1xuICAgICAgICAgICAgaWYgKCFzcmMpIHJldHVybjtcblxuICAgICAgICAgICAgaWYgKGlzQWJzb2x1dGUoc3JjKSkge1xuICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyLCBzZXJ2ZXIub3JpZ2luICsgc3JjKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3JjLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgICAgICAgICAgICBjb25zdCBhYnMgPSByZXNvbHZlKGRpcm5hbWUoaWQpLCBzcmMpO1xuICAgICAgICAgICAgICBjb25zdCBwYXRobmFtZSA9IHJlbGF0aXZlKGNvbmZpZy5yb290LCBhYnMpO1xuICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyLCBgJHtzZXJ2ZXIub3JpZ2lufS8ke3BhdGhuYW1lfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBwb2ludFRvRGV2U2VydmVyKCdzY3JpcHRbdHlwZT1tb2R1bGVdJywgJ3NyYycpO1xuICAgICAgICBwb2ludFRvRGV2U2VydmVyKCdsaW5rW3JlbD1zdHlsZXNoZWV0XScsICdocmVmJyk7XG5cbiAgICAgICAgLy8gQWRkIGEgc2NyaXB0IHRvIGFkZCBwYWdlIHJlbG9hZGluZ1xuICAgICAgICBjb25zdCByZWxvYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICByZWxvYWRlci5zcmMgPSBodG1sUmVsb2FkSWQ7XG4gICAgICAgIHJlbG9hZGVyLnR5cGUgPSAnbW9kdWxlJztcbiAgICAgICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChyZWxvYWRlcik7XG5cbiAgICAgICAgY29uc3QgbmV3SHRtbCA9IGRvY3VtZW50LnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoJ3RyYW5zZm9ybSAnICsgaWQpO1xuICAgICAgICBjb25maWcubG9nZ2VyLmRlYnVnKCdPbGQgSFRNTDpcXG4nICsgY29kZSk7XG4gICAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoJ05ldyBIVE1MOlxcbicgKyBuZXdIdG1sKTtcbiAgICAgICAgcmV0dXJuIG5ld0h0bWw7XG4gICAgICB9LFxuXG4gICAgICAvLyBQYXNzIHRoZSBIVE1MIHRocm91Z2ggdGhlIGRldiBzZXJ2ZXIgdG8gYWRkIGRldi1tb2RlIHNwZWNpZmljIGNvZGVcbiAgICAgIGFzeW5jIHRyYW5zZm9ybUluZGV4SHRtbChodG1sLCBjdHgpIHtcbiAgICAgICAgY29uc3Qgc2VydmVyID0gY29uZmlnLnNlcnZlcjtcbiAgICAgICAgaWYgKGNvbmZpZy5jb21tYW5kICE9PSAnc2VydmUnIHx8IHNlcnZlciA9PSBudWxsKSByZXR1cm47XG5cbiAgICAgICAgY29uc3Qgb3JpZ2luYWxVcmwgPSBgJHtzZXJ2ZXIub3JpZ2lufSR7Y3R4LnBhdGh9YDtcbiAgICAgICAgY29uc3QgbmFtZSA9IGdldEVudHJ5cG9pbnROYW1lKGNvbmZpZy5lbnRyeXBvaW50c0RpciwgY3R4LmZpbGVuYW1lKTtcbiAgICAgICAgY29uc3QgdXJsID0gYCR7c2VydmVyLm9yaWdpbn0vJHtuYW1lfS5odG1sYDtcbiAgICAgICAgY29uc3Qgc2VydmVySHRtbCA9IGF3YWl0IHNlcnZlci50cmFuc2Zvcm1JbmRleEh0bWwoXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIGh0bWwsXG4gICAgICAgICAgb3JpZ2luYWxVcmwsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHsgZG9jdW1lbnQgfSA9IHBhcnNlSFRNTChzZXJ2ZXJIdG1sKTtcblxuICAgICAgICAvLyBSZWFjdCBwYWdlcyBpbmNsdWRlIGEgcHJlYW1ibGUgYXMgYW4gdW5zYWZlLWlubGluZSB0eXBlPVwibW9kdWxlXCIgc2NyaXB0IHRvIGVuYWJsZSBmYXN0IHJlZnJlc2gsIGFzIHNob3duIGhlcmU6XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS93eHQtZGV2L3d4dC9pc3N1ZXMvMTU3I2lzc3VlY29tbWVudC0xNzU2NDk3NjE2XG4gICAgICAgIC8vIFNpbmNlIHVuc2FmZS1pbmxpbmUgc2NyaXB0cyBhcmUgYmxvY2tlZCBieSBNVjMgQ1NQcywgd2UgbmVlZCB0byB2aXJ0dWFsaXplIGl0LlxuICAgICAgICBjb25zdCByZWFjdFJlZnJlc2hTY3JpcHQgPSBBcnJheS5mcm9tKFxuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ3NjcmlwdFt0eXBlPW1vZHVsZV0nKSxcbiAgICAgICAgKS5maW5kKChzY3JpcHQpID0+IHNjcmlwdC5pbm5lckhUTUwuaW5jbHVkZXMoJ0ByZWFjdC1yZWZyZXNoJykpO1xuICAgICAgICBpZiAocmVhY3RSZWZyZXNoU2NyaXB0KSB7XG4gICAgICAgICAgLy8gU2F2ZSBwcmVhbWJsZSB0byBzZXJ2ZSBmcm9tIHNlcnZlclxuICAgICAgICAgIHJlYWN0UmVmcmVzaFByZWFtYmxlID0gcmVhY3RSZWZyZXNoU2NyaXB0LmlubmVySFRNTDtcblxuICAgICAgICAgIC8vIFJlcGxhY2UgdW5zYWZlIGlubGluZSBzY3JpcHRcbiAgICAgICAgICBjb25zdCB2aXJ0dWFsU2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgdmlydHVhbFNjcmlwdC50eXBlID0gJ21vZHVsZSc7XG4gICAgICAgICAgdmlydHVhbFNjcmlwdC5zcmMgPSBgJHtzZXJ2ZXIub3JpZ2lufS8ke3ZpcnR1YWxSZWFjdFJlZnJlc2hJZH1gO1xuICAgICAgICAgIHJlYWN0UmVmcmVzaFNjcmlwdC5yZXBsYWNlV2l0aCh2aXJ0dWFsU2NyaXB0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoYW5nZSAvQHZpdGUvY2xpZW50IC0+IGh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC9Adml0ZS9jbGllbnRcbiAgICAgICAgY29uc3Qgdml0ZUNsaWVudFNjcmlwdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTFNjcmlwdEVsZW1lbnQ+KFxuICAgICAgICAgIFwic2NyaXB0W3NyYz0nL0B2aXRlL2NsaWVudCddXCIsXG4gICAgICAgICk7XG4gICAgICAgIGlmICh2aXRlQ2xpZW50U2NyaXB0KSB7XG4gICAgICAgICAgdml0ZUNsaWVudFNjcmlwdC5zcmMgPSBgJHtzZXJ2ZXIub3JpZ2lufSR7dml0ZUNsaWVudFNjcmlwdC5zcmN9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ld0h0bWwgPSBkb2N1bWVudC50b1N0cmluZygpO1xuICAgICAgICBjb25maWcubG9nZ2VyLmRlYnVnKCd0cmFuc2Zvcm1JbmRleEh0bWwgJyArIGN0eC5maWxlbmFtZSk7XG4gICAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoJ09sZCBIVE1MOlxcbicgKyBodG1sKTtcbiAgICAgICAgY29uZmlnLmxvZ2dlci5kZWJ1ZygnTmV3IEhUTUw6XFxuJyArIG5ld0h0bWwpO1xuICAgICAgICByZXR1cm4gbmV3SHRtbDtcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiAnd3h0OnZpcnR1YWxpemUtcmVhY3QtcmVmcmVzaCcsXG4gICAgICBhcHBseTogJ3NlcnZlJyxcbiAgICAgIHJlc29sdmVJZChpZCkge1xuICAgICAgICBpZiAoaWQgPT09IGAvJHt2aXJ0dWFsUmVhY3RSZWZyZXNoSWR9YCkge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlZFZpcnR1YWxSZWFjdFJlZnJlc2hJZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZ25vcmUgY2h1bmsgY29udGVudHMgd2hlbiBwcmUtcmVuZGVyaW5nXG4gICAgICAgIGlmIChpZC5zdGFydHNXaXRoKCcvY2h1bmtzLycpKSB7XG4gICAgICAgICAgcmV0dXJuICdcXDBub29wJztcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGxvYWQoaWQpIHtcbiAgICAgICAgaWYgKGlkID09PSByZXNvbHZlZFZpcnR1YWxSZWFjdFJlZnJlc2hJZCkge1xuICAgICAgICAgIHJldHVybiByZWFjdFJlZnJlc2hQcmVhbWJsZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaWQgPT09ICdcXDBub29wJykge1xuICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICBdO1xufVxuIiwgImltcG9ydCB7IFBsdWdpbiB9IGZyb20gJ3ZpdGUnO1xuaW1wb3J0IHsgSW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5cbi8qKlxuICogRGVmaW5lcyBnbG9iYWwgY29uc3RhbnRzIGFib3V0IHRoZSBkZXYgc2VydmVyLiBIZWxwcyBzY3JpcHRzIGNvbm5lY3QgdG8gdGhlIHNlcnZlcidzIHdlYiBzb2NrZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXZTZXJ2ZXJHbG9iYWxzKGludGVybmFsQ29uZmlnOiBJbnRlcm5hbENvbmZpZyk6IFBsdWdpbiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ3d4dDpkZXYtc2VydmVyLWdsb2JhbHMnLFxuICAgIGNvbmZpZygpIHtcbiAgICAgIGlmIChpbnRlcm5hbENvbmZpZy5zZXJ2ZXIgPT0gbnVsbCB8fCBpbnRlcm5hbENvbmZpZy5jb21tYW5kID09ICdidWlsZCcpXG4gICAgICAgIHJldHVybjtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGVmaW5lOiB7XG4gICAgICAgICAgX19ERVZfU0VSVkVSX1BST1RPQ09MX186IEpTT04uc3RyaW5naWZ5KCd3czonKSxcbiAgICAgICAgICBfX0RFVl9TRVJWRVJfSE9TVE5BTUVfXzogSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICBpbnRlcm5hbENvbmZpZy5zZXJ2ZXIuaG9zdG5hbWUsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBfX0RFVl9TRVJWRVJfUE9SVF9fOiBKU09OLnN0cmluZ2lmeShpbnRlcm5hbENvbmZpZy5zZXJ2ZXIucG9ydCksXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IGRucyBmcm9tICdub2RlOmRucyc7XG5pbXBvcnQgeyB3aXRoVGltZW91dCB9IGZyb20gJy4vcHJvbWlzZXMnO1xuaW1wb3J0IHsgSW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5cbmZ1bmN0aW9uIGlzT2ZmbGluZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgaXNPZmZsaW5lID0gbmV3IFByb21pc2U8Ym9vbGVhbj4oKHJlcykgPT4ge1xuICAgIGRucy5yZXNvbHZlKCdnb29nbGUuY29tJywgKGVycikgPT4ge1xuICAgICAgaWYgKGVyciA9PSBudWxsKSB7XG4gICAgICAgIHJlcyhmYWxzZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXModHJ1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gd2l0aFRpbWVvdXQoaXNPZmZsaW5lLCAxZTMpLmNhdGNoKCgpID0+IHRydWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNPbmxpbmUoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IG9mZmxpbmUgPSBhd2FpdCBpc09mZmxpbmUoKTtcbiAgcmV0dXJuICFvZmZsaW5lO1xufVxuXG4vKipcbiAqIEZldGNoZXMgYSBVUkwgd2l0aCBhIHNpbXBsZSBHRVQgcmVxdWVzdC4gR3JhYnMgaXQgZnJvbSBjYWNoZSBpZiBpdCBkb2Vzbid0IGV4aXN0LCBvciB0aHJvd3MgYW5cbiAqIGVycm9yIGlmIGl0IGNhbid0IGJlIHJlc29sdmVkIHZpYSB0aGUgbmV0d29yayBvciBjYWNoZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoQ2FjaGVkKFxuICB1cmw6IHN0cmluZyxcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGxldCBjb250ZW50OiBzdHJpbmcgPSAnJztcblxuICBpZiAoYXdhaXQgaXNPbmxpbmUoKSkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgaWYgKHJlcy5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNvbnRlbnQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgYXdhaXQgY29uZmlnLmZzQ2FjaGUuc2V0KHVybCwgY29udGVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoXG4gICAgICAgIGBGYWlsZWQgdG8gZG93bmxvYWQgXCIke3VybH1cIiwgZmFsbGluZyBiYWNrIHRvIGNhY2hlLi4uYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFjb250ZW50KSBjb250ZW50ID0gKGF3YWl0IGNvbmZpZy5mc0NhY2hlLmdldCh1cmwpKSA/PyAnJztcbiAgaWYgKCFjb250ZW50KVxuICAgIHRocm93IEVycm9yKFxuICAgICAgYE9mZmxpbmUgYW5kIFwiJHt1cmx9XCIgaGFzIG5vdCBiZWVuIGNhY2hlZC4gVHJ5IGFnYWluIHdoZW4gb25saW5lLmAsXG4gICAgKTtcblxuICByZXR1cm4gY29udGVudDtcbn1cbiIsICIvKipcbiAqIEFkZCBhIHRpbWVvdXQgdG8gYSBwcm9taXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aFRpbWVvdXQ8VD4oXG4gIHByb21pc2U6IFByb21pc2U8VD4sXG4gIGR1cmF0aW9uOiBudW1iZXIsXG4pOiBQcm9taXNlPFQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHJlaihgUHJvbWlzZSB0aW1lZCBvdXQgYWZ0ZXIgJHtkdXJhdGlvbn1tc2ApO1xuICAgIH0sIGR1cmF0aW9uKTtcbiAgICBwcm9taXNlXG4gICAgICAudGhlbihyZXMpXG4gICAgICAuY2F0Y2gocmVqKVxuICAgICAgLmZpbmFsbHkoKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVvdXQpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgRG9uJ3QgdXNlIGluIHByb2R1Y3Rpb24sIGp1c3QgZm9yIHRlc3RpbmcgYW5kIHNsb3dpbmcgdGhpbmdzIGRvd24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzKSA9PiBzZXRUaW1lb3V0KHJlcywgbXMpKTtcbn1cbiIsICJpbXBvcnQgeyBQbHVnaW4gfSBmcm9tICd2aXRlJztcbmltcG9ydCB7IEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZmV0Y2hDYWNoZWQgfSBmcm9tICcuLi91dGlscy9uZXR3b3JrJztcblxuLyoqXG4gKiBEb3dubG9hZHMgYW55IFVSTCBpbXBvcnRzLCBsaWtlIEdvb2dsZSBBbmFseXRpY3MsIGludG8gdmlydHVhbCBtb2R1bGVzIHNvIHRoZXkgYXJlIGJ1bmRsZWQgd2l0aFxuICogdGhlIGV4dGVuc2lvbiBpbnN0ZWFkIG9mIGRlcGVuZGluZyBvbiByZW1vdGUgY29kZSBhdCBydW50aW1lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgXCJ1cmw6aHR0cHM6Ly9nb29nbGUtdGFnbWFuYWdlci5jb20vZ3RhZz9pZD1YWVpcIjtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRvd25sb2FkKGNvbmZpZzogSW50ZXJuYWxDb25maWcpOiBQbHVnaW4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3eHQ6ZG93bmxvYWQnLFxuICAgIHJlc29sdmVJZChpZCkge1xuICAgICAgaWYgKGlkLnN0YXJ0c1dpdGgoJ3VybDonKSkgcmV0dXJuICdcXDAnICsgaWQ7XG4gICAgfSxcbiAgICBhc3luYyBsb2FkKGlkKSB7XG4gICAgICBpZiAoIWlkLnN0YXJ0c1dpdGgoJ1xcMHVybDonKSkgcmV0dXJuO1xuXG4gICAgICAvLyBMb2FkIGZpbGUgZnJvbSBuZXR3b3JrIG9yIGNhY2hlXG4gICAgICBjb25zdCB1cmwgPSBpZC5yZXBsYWNlKCdcXDB1cmw6JywgJycpO1xuICAgICAgcmV0dXJuIGF3YWl0IGZldGNoQ2FjaGVkKHVybCwgY29uZmlnKTtcbiAgICB9LFxuICB9O1xufVxuIiwgImltcG9ydCAqIGFzIHZpdGUgZnJvbSAndml0ZSc7XG5pbXBvcnQgeyBFbnRyeXBvaW50LCBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGRpcm5hbWUsIGV4dG5hbWUsIHJlc29sdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgZ2V0RW50cnlwb2ludEJ1bmRsZVBhdGggfSBmcm9tICcuLi91dGlscy9lbnRyeXBvaW50cyc7XG5pbXBvcnQgZnMsIHsgZW5zdXJlRGlyIH0gZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgbm9ybWFsaXplUGF0aCB9IGZyb20gJy4uL3V0aWxzL3BhdGhzJztcblxuLyoqXG4gKiBFbnN1cmVzIHRoZSBIVE1MIGZpbGVzIG91dHB1dCBieSBhIG11bHRpcGFnZSBidWlsZCBhcmUgaW4gdGhlIGNvcnJlY3QgbG9jYXRpb24uIFRoaXMgZG9lcyB0d29cbiAqIHRoaW5nczpcbiAqXG4gKiAxLiBNb3ZlcyB0aGUgSE1UTCBmaWxlcyB0byB0aGVpciBmaW5hbCBsb2NhdGlvbiBhdCBgPG91dERpcj4vPGVudHJ5cG9pbnQubmFtZT4uaHRtbGAuXG4gKiAyLiBVcGRhdGVzIHRoZSBidW5kbGUgc28gaXQgc3VtbWFyaXplcyB0aGUgZmlsZXMgY29ycmVjdGx5IGluIHRoZSByZXR1cm5lZCBidWlsZCBvdXRwdXQuXG4gKlxuICogQXNzZXRzIChKUyBhbmQgQ1NTKSBhcmUgb3V0cHV0IHRvIHRoZSBgPG91dERpcj4vYXNzZXRzYCBkaXJlY3RvcnksIGFuZCBkb24ndCBuZWVkIHRvIGJlIG1vZGlmaWVkLlxuICogSFRNTCBmaWxlcyBhY2Nlc3MgdGhlbSB2aWEgYWJzb2x1dGUgVVJMcywgc28gd2UgZG9uJ3QgbmVlZCB0byB1cGRhdGUgYW55IGltcG9ydCBwYXRocyBpbiB0aGUgSFRNTFxuICogZmlsZXMgZWl0aGVyLlxuICpcbiAqIFRISVMgUExVR0lOIFNIT1VMRCBPTkxZIEJFIEFQUExJRUQgVE8gTVVMVElQQUdFIEJVSUxEUy4gSXQgc2hvdWxkIG5vdCBiZSBhZGRlZCB0byBldmVyeSBidWlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGFnZU1vdmUoXG4gIGVudHJ5cG9pbnRzOiBFbnRyeXBvaW50W10sXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiB2aXRlLlBsdWdpbiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ3d4dDptdWx0aXBhZ2UtbW92ZScsXG4gICAgYXN5bmMgd3JpdGVCdW5kbGUoXywgYnVuZGxlKSB7XG4gICAgICBmb3IgKGNvbnN0IG9sZEJ1bmRsZVBhdGggaW4gYnVuZGxlKSB7XG4gICAgICAgIC8vIG9sZEJ1bmRsZVBhdGggPSAnZW50cnlwb2ludHMvcG9wdXAuaHRtbCcgb3IgJ2VudHJ5cG9pbnRzL29wdGlvbnMvaW5kZXguaHRtbCdcblxuICAgICAgICAvLyBGaW5kIGEgbWF0Y2hpbmcgZW50cnlwb2ludCAtIG9sZEJ1bmRsZVBhdGggaXMgdGhlIHNhbWUgYXMgZW5kIGVuZCBvZiB0aGUgaW5wdXQgcGF0aC5cbiAgICAgICAgY29uc3QgZW50cnlwb2ludCA9IGVudHJ5cG9pbnRzLmZpbmQoXG4gICAgICAgICAgKGVudHJ5KSA9PiAhIW5vcm1hbGl6ZVBhdGgoZW50cnkuaW5wdXRQYXRoKS5lbmRzV2l0aChvbGRCdW5kbGVQYXRoKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGVudHJ5cG9pbnQgPT0gbnVsbCkge1xuICAgICAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICBgTm8gZW50cnlwb2ludCBmb3VuZCBmb3IgJHtvbGRCdW5kbGVQYXRofSwgbGVhdmluZyBpbiBjaHVua3MgZGlyZWN0b3J5YCxcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHRoZSBuZXcgYnVuZGxlIHBhdGhcbiAgICAgICAgY29uc3QgbmV3QnVuZGxlUGF0aCA9IGdldEVudHJ5cG9pbnRCdW5kbGVQYXRoKFxuICAgICAgICAgIGVudHJ5cG9pbnQsXG4gICAgICAgICAgY29uZmlnLm91dERpcixcbiAgICAgICAgICBleHRuYW1lKG9sZEJ1bmRsZVBhdGgpLFxuICAgICAgICApO1xuICAgICAgICBpZiAobmV3QnVuZGxlUGF0aCA9PT0gb2xkQnVuZGxlUGF0aCkge1xuICAgICAgICAgIGNvbmZpZy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICAnSFRNTCBmaWxlIGlzIGFscmVhZHkgaW4gdGhlIGNvcnJlY3QgbG9jYXRpb24nLFxuICAgICAgICAgICAgb2xkQnVuZGxlUGF0aCxcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTW92ZSBmaWxlIGFuZCB1cGRhdGUgYnVuZGxlXG4gICAgICAgIC8vIERvIHRoaXMgaW5zaWRlIGEgbXV0ZXggbG9jayBzbyBpdCBvbmx5IHJ1bnMgb25lIGF0IGEgdGltZSBmb3IgY29uY3VycmVudCBtdWx0aXBhZ2UgYnVpbGRzXG4gICAgICAgIGNvbnN0IG9sZEFic1BhdGggPSByZXNvbHZlKGNvbmZpZy5vdXREaXIsIG9sZEJ1bmRsZVBhdGgpO1xuICAgICAgICBjb25zdCBuZXdBYnNQYXRoID0gcmVzb2x2ZShjb25maWcub3V0RGlyLCBuZXdCdW5kbGVQYXRoKTtcbiAgICAgICAgYXdhaXQgZW5zdXJlRGlyKGRpcm5hbWUobmV3QWJzUGF0aCkpO1xuICAgICAgICBhd2FpdCBmcy5tb3ZlKG9sZEFic1BhdGgsIG5ld0Fic1BhdGgsIHsgb3ZlcndyaXRlOiB0cnVlIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlbmFtZWRDaHVuayA9IHtcbiAgICAgICAgICAuLi5idW5kbGVbb2xkQnVuZGxlUGF0aF0sXG4gICAgICAgICAgZmlsZU5hbWU6IG5ld0J1bmRsZVBhdGgsXG4gICAgICAgIH07XG4gICAgICAgIGRlbGV0ZSBidW5kbGVbb2xkQnVuZGxlUGF0aF07XG4gICAgICAgIGJ1bmRsZVtuZXdCdW5kbGVQYXRoXSA9IHJlbmFtZWRDaHVuaztcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuIiwgImltcG9ydCB7IGNyZWF0ZVVuaW1wb3J0IH0gZnJvbSAndW5pbXBvcnQnO1xuaW1wb3J0IHsgSW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRVbmltcG9ydE9wdGlvbnMgfSBmcm9tICcuLi91dGlscy9hdXRvLWltcG9ydHMnO1xuaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcbmltcG9ydCB7IGV4dG5hbWUgfSBmcm9tICdwYXRoJztcblxuY29uc3QgRU5BQkxFRF9FWFRFTlNJT05TOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuIHwgdW5kZWZpbmVkPiA9IHtcbiAgJy5qcyc6IHRydWUsXG4gICcuanN4JzogdHJ1ZSxcbiAgJy50cyc6IHRydWUsXG4gICcudHN4JzogdHJ1ZSxcbiAgJy52dWUnOiB0cnVlLFxuICAnLnN2ZWx0ZSc6IHRydWUsXG59O1xuXG4vKipcbiAqIEluamVjdCBhbnkgZ2xvYmFsIGltcG9ydHMgZGVmaW5lZCBieSB1bmltcG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5pbXBvcnQoY29uZmlnOiBJbnRlcm5hbENvbmZpZyk6IHZpdGUuUGx1Z2luT3B0aW9uIHtcbiAgY29uc3Qgb3B0aW9ucyA9IGdldFVuaW1wb3J0T3B0aW9ucyhjb25maWcpO1xuICBpZiAob3B0aW9ucyA9PT0gZmFsc2UpIHJldHVybiBbXTtcblxuICBjb25zdCB1bmltcG9ydCA9IGNyZWF0ZVVuaW1wb3J0KG9wdGlvbnMpO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ3d4dDp1bmltcG9ydCcsXG4gICAgYXN5bmMgY29uZmlnKCkge1xuICAgICAgYXdhaXQgdW5pbXBvcnQuc2NhbkltcG9ydHNGcm9tRGlyKHVuZGVmaW5lZCwgeyBjd2Q6IGNvbmZpZy5zcmNEaXIgfSk7XG4gICAgfSxcbiAgICBhc3luYyB0cmFuc2Zvcm0oY29kZSwgaWQpIHtcbiAgICAgIGNvbnN0IGV4dCA9IGV4dG5hbWUoaWQpO1xuICAgICAgaWYgKEVOQUJMRURfRVhURU5TSU9OU1tleHRdKSByZXR1cm4gdW5pbXBvcnQuaW5qZWN0SW1wb3J0cyhjb2RlLCBpZCk7XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBVbmltcG9ydE9wdGlvbnMgfSBmcm9tICd1bmltcG9ydCc7XG5pbXBvcnQgeyBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IG1lcmdlQ29uZmlnIH0gZnJvbSAndml0ZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRVbmltcG9ydE9wdGlvbnMoXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQYXJ0aWFsPFVuaW1wb3J0T3B0aW9ucyB8IGZhbHNlPiB7XG4gIGlmIChjb25maWcuaW1wb3J0cyA9PT0gZmFsc2UpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBkZWZhdWx0T3B0aW9uczogUGFydGlhbDxVbmltcG9ydE9wdGlvbnM+ID0ge1xuICAgIGRlYnVnTG9nOiBjb25maWcubG9nZ2VyLmRlYnVnLFxuICAgIGltcG9ydHM6IFtcbiAgICAgIHsgbmFtZTogJ2RlZmluZUNvbmZpZycsIGZyb206ICd3eHQnIH0sXG4gICAgICB7IG5hbWU6ICdmYWtlQnJvd3NlcicsIGZyb206ICd3eHQvdGVzdGluZycgfSxcbiAgICBdLFxuICAgIHByZXNldHM6IFtcbiAgICAgIHsgcGFja2FnZTogJ3d4dC9jbGllbnQnIH0sXG4gICAgICB7IHBhY2thZ2U6ICd3eHQvYnJvd3NlcicgfSxcbiAgICAgIHsgcGFja2FnZTogJ3d4dC9zYW5kYm94JyB9LFxuICAgIF0sXG4gICAgd2FybjogY29uZmlnLmxvZ2dlci53YXJuLFxuICAgIGRpcnM6IFsnY29tcG9uZW50cycsICdjb21wb3NhYmxlcycsICdob29rcycsICd1dGlscyddLFxuICB9O1xuXG4gIHJldHVybiBtZXJnZUNvbmZpZyhcbiAgICBkZWZhdWx0T3B0aW9ucyxcbiAgICBjb25maWcuaW1wb3J0cyxcbiAgKSBhcyBQYXJ0aWFsPFVuaW1wb3J0T3B0aW9ucz47XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAndml0ZSc7XG5pbXBvcnQgeyBFbnRyeXBvaW50LCBJbnRlcm5hbENvbmZpZyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBub3JtYWxpemVQYXRoIH0gZnJvbSAnLi4vdXRpbHMvcGF0aHMnO1xuXG4vKipcbiAqIFdyYXBzIGEgdXNlcidzIGVudHJ5cG9pbnQgd2l0aCBhIHZpdHVhbCB2ZXJzaW9uIHdpdGggYWRkaXRpb25hbCBsb2dpYy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZpcnR1YWxFbnRyeXBvaW50KFxuICB0eXBlOiBFbnRyeXBvaW50Wyd0eXBlJ10sXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiBQbHVnaW4ge1xuICBjb25zdCB2aXJ0dWFsSWQgPSBgdmlydHVhbDp3eHQtJHt0eXBlfT9gO1xuICBjb25zdCByZXNvbHZlZFZpcnR1YWxJZCA9IGBcXDAke3ZpcnR1YWxJZH1gO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogYHd4dDp2aXJ0dWFsLWVudHJ5cG9pbnRgLFxuICAgIHJlc29sdmVJZChpZCkge1xuICAgICAgLy8gSWQgZG9lc24ndCBzdGFydCB3aXRoIHByZWZpeCwgaXQgbG9va3MgbGlrZSB0aGlzOlxuICAgICAgLy8gL3BhdGgvdG8vcHJvamVjdC92aXJ0dWFsOmJhY2tncm91bmQ/L3BhdGgvdG8vcHJvamVjdC9lbnRyeXBvaW50cy9iYWNrZ3JvdW5kLnRzXG4gICAgICBjb25zdCBpbmRleCA9IGlkLmluZGV4T2YodmlydHVhbElkKTtcbiAgICAgIGlmIChpbmRleCA9PT0gLTEpIHJldHVybjtcblxuICAgICAgY29uc3QgaW5wdXRQYXRoID0gbm9ybWFsaXplUGF0aChpZC5zdWJzdHJpbmcoaW5kZXggKyB2aXJ0dWFsSWQubGVuZ3RoKSk7XG4gICAgICByZXR1cm4gcmVzb2x2ZWRWaXJ0dWFsSWQgKyBpbnB1dFBhdGg7XG4gICAgfSxcbiAgICBhc3luYyBsb2FkKGlkKSB7XG4gICAgICBpZiAoIWlkLnN0YXJ0c1dpdGgocmVzb2x2ZWRWaXJ0dWFsSWQpKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGlucHV0UGF0aCA9IGlkLnJlcGxhY2UocmVzb2x2ZWRWaXJ0dWFsSWQsICcnKTtcbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gYXdhaXQgZnMucmVhZEZpbGUoXG4gICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgY29uZmlnLnJvb3QsXG4gICAgICAgICAgYG5vZGVfbW9kdWxlcy93eHQvZGlzdC92aXJ0dWFsLW1vZHVsZXMvJHt0eXBlfS1lbnRyeXBvaW50LmpzYCxcbiAgICAgICAgKSxcbiAgICAgICAgJ3V0Zi04JyxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdGVtcGxhdGUucmVwbGFjZShgdmlydHVhbDp1c2VyLSR7dHlwZX1gLCBpbnB1dFBhdGgpO1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgSW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgKiBhcyB2aXRlIGZyb20gJ3ZpdGUnO1xuXG5leHBvcnQgZnVuY3Rpb24gdHNjb25maWdQYXRocyhjb25maWc6IEludGVybmFsQ29uZmlnKTogdml0ZS5QbHVnaW4ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3eHQ6YWxpYXNlcycsXG4gICAgYXN5bmMgY29uZmlnKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzb2x2ZToge1xuICAgICAgICAgIGFsaWFzOiB7XG4gICAgICAgICAgICAnQEAnOiBjb25maWcucm9vdCxcbiAgICAgICAgICAgICd+fic6IGNvbmZpZy5yb290LFxuICAgICAgICAgICAgJ0AnOiBjb25maWcuc3JjRGlyLFxuICAgICAgICAgICAgJ34nOiBjb25maWcuc3JjRGlyLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAndml0ZSc7XG5cbi8qKlxuICogSW4gZGV2IG1vZGUsIGlmIHRoZXJlJ3Mgbm90IGEgYmFja2dyb3VuZCBzY3JpcHQgbGlzdGVkLCB3ZSBuZWVkIHRvIGFkZCBvbmUuXG4gKlxuICogVGhpcyBkZWZpbmUncyBhIHZpcnR1YWwgbW9kdWxlIHRoYXQgaXMgYmFzaWNhbGx5IGp1c3QgYSBub29wLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9vcEJhY2tncm91bmQoKTogUGx1Z2luIHtcbiAgY29uc3QgdmlydHVhbE1vZHVsZUlkID0gVklSVFVBTF9OT09QX0JBQ0tHUk9VTkRfTU9EVUxFX0lEO1xuICBjb25zdCByZXNvbHZlZFZpcnR1YWxNb2R1bGVJZCA9ICdcXDAnICsgdmlydHVhbE1vZHVsZUlkO1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3eHQ6bm9vcC1iYWNrZ3JvdW5kJyxcbiAgICByZXNvbHZlSWQoaWQpIHtcbiAgICAgIGlmIChpZCA9PT0gdmlydHVhbE1vZHVsZUlkKSByZXR1cm4gcmVzb2x2ZWRWaXJ0dWFsTW9kdWxlSWQ7XG4gICAgfSxcbiAgICBsb2FkKGlkKSB7XG4gICAgICBpZiAoaWQgPT09IHJlc29sdmVkVmlydHVhbE1vZHVsZUlkKSB7XG4gICAgICAgIHJldHVybiBgaW1wb3J0IHsgZGVmaW5lQmFja2dyb3VuZCB9IGZyb20gJ3d4dC9jbGllbnQnO1xcbmV4cG9ydCBkZWZhdWx0IGRlZmluZUJhY2tncm91bmQoKCkgPT4gdm9pZCAwKWA7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGNvbnN0IFZJUlRVQUxfTk9PUF9CQUNLR1JPVU5EX01PRFVMRV9JRCA9ICd2aXJ0dWFsOnVzZXItYmFja2dyb3VuZCc7XG4iLCAiaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcbmltcG9ydCB7IHZpc3VhbGl6ZXIgfSBmcm9tICdyb2xsdXAtcGx1Z2luLXZpc3VhbGl6ZXInO1xuXG5sZXQgaW5jcmVtZW50ID0gMDtcblxuZXhwb3J0IGZ1bmN0aW9uIGJ1bmRsZUFuYWx5c2lzKCk6IHZpdGUuUGx1Z2luIHtcbiAgcmV0dXJuIHZpc3VhbGl6ZXIoe1xuICAgIGVtaXRGaWxlOiB0cnVlLFxuICAgIHRlbXBsYXRlOiAncmF3LWRhdGEnLFxuICAgIGZpbGVuYW1lOiBgc3RhdHMtJHtpbmNyZW1lbnQrK30uanNvbmAsXG4gIH0pIGFzIHZpdGUuUGx1Z2luO1xufVxuIiwgImltcG9ydCB7IEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R2xvYmFscyhcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbik6IEFycmF5PHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogYW55OyB0eXBlOiBzdHJpbmcgfT4ge1xuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIG5hbWU6IHN1cnJvdW5kSW5VbmRlcnNjb3JlKCdNQU5JRkVTVF9WRVJTSU9OJyksXG4gICAgICB2YWx1ZTogY29uZmlnLm1hbmlmZXN0VmVyc2lvbixcbiAgICAgIHR5cGU6IGAyIHwgM2AsXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBzdXJyb3VuZEluVW5kZXJzY29yZSgnQlJPV1NFUicpLFxuICAgICAgdmFsdWU6IGNvbmZpZy5icm93c2VyLFxuICAgICAgdHlwZTogYHN0cmluZ2AsXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiBzdXJyb3VuZEluVW5kZXJzY29yZSgnSVNfQ0hST01FJyksXG4gICAgICB2YWx1ZTogY29uZmlnLmJyb3dzZXIgPT09ICdjaHJvbWUnLFxuICAgICAgdHlwZTogYGJvb2xlYW5gLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogc3Vycm91bmRJblVuZGVyc2NvcmUoJ0lTX0ZJUkVGT1gnKSxcbiAgICAgIHZhbHVlOiBjb25maWcuYnJvd3NlciA9PT0gJ2ZpcmVmb3gnLFxuICAgICAgdHlwZTogYGJvb2xlYW5gLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogc3Vycm91bmRJblVuZGVyc2NvcmUoJ0lTX1NBRkFSSScpLFxuICAgICAgdmFsdWU6IGNvbmZpZy5icm93c2VyID09PSAnc2FmYXJpJyxcbiAgICAgIHR5cGU6IGBib29sZWFuYCxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IHN1cnJvdW5kSW5VbmRlcnNjb3JlKCdJU19FREdFJyksXG4gICAgICB2YWx1ZTogY29uZmlnLmJyb3dzZXIgPT09ICdlZGdlJyxcbiAgICAgIHR5cGU6IGBib29sZWFuYCxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IHN1cnJvdW5kSW5VbmRlcnNjb3JlKCdJU19PUEVSQScpLFxuICAgICAgdmFsdWU6IGNvbmZpZy5icm93c2VyID09PSAnb3BlcmEnLFxuICAgICAgdHlwZTogYGJvb2xlYW5gLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogc3Vycm91bmRJblVuZGVyc2NvcmUoJ0NPTU1BTkQnKSxcbiAgICAgIHZhbHVlOiBjb25maWcuY29tbWFuZCxcbiAgICAgIHR5cGU6IGBcImJ1aWxkXCIgfCBcInNlcnZlXCJgLFxuICAgIH0sXG4gIF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbnRyeXBvaW50R2xvYmFscyhcbiAgY29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbiAgZW50cnlwb2ludE5hbWU6IHN0cmluZyxcbikge1xuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIG5hbWU6IHN1cnJvdW5kSW5VbmRlcnNjb3JlKCdFTlRSWVBPSU5UJyksXG4gICAgICB2YWx1ZTogZW50cnlwb2ludE5hbWUsXG4gICAgICB0eXBlOiBgc3RyaW5nYCxcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIERvbid0IGhhcmRjb2RlIHRoZSBjb21wbGV0ZSBuYW1lIHNvIHRoYXQgdGhlIHN0cmluZyBsaXR0ZXJhbHMgaW4gdGhpcyBmaWxlIGFyZW4ndCByZXBsYWNlZCBkdXJpbmdcbiAqIHRlc3RzICh3aGljaCBjYXVzZXMgc3ludGF4IGVycm9ycyksIG9ubHkgZHVyaW5nIGJ1aWxkcy5cbiAqL1xuZnVuY3Rpb24gc3Vycm91bmRJblVuZGVyc2NvcmUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBfXyR7bmFtZX1fX2A7XG59XG4iLCAiaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcbmltcG9ydCB7IEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0R2xvYmFscyB9IGZyb20gJy4uL3V0aWxzL2dsb2JhbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2xvYmFscyhjb25maWc6IEludGVybmFsQ29uZmlnKTogdml0ZS5QbHVnaW5PcHRpb24ge1xuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3eHQ6Z2xvYmFscycsXG4gICAgY29uZmlnKCkge1xuICAgICAgY29uc3QgZGVmaW5lOiB2aXRlLklubGluZUNvbmZpZ1snZGVmaW5lJ10gPSB7fTtcbiAgICAgIGZvciAoY29uc3QgZ2xvYmFsIG9mIGdldEdsb2JhbHMoY29uZmlnKSkge1xuICAgICAgICBkZWZpbmVbZ2xvYmFsLm5hbWVdID0gSlNPTi5zdHJpbmdpZnkoZ2xvYmFsLnZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRlZmluZSxcbiAgICAgIH07XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcbmltcG9ydCB7IEludGVybmFsQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYWxpYXMgdG8gcmVkaXJlY3QgXCJ3ZWJleHRlbnNpb24tcG9seWZpbGxcIiBpbXBvcnRzIHRvIFdYVCdzIGBmYWtlQnJvd3NlcmAuXG4gKlxuICogVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIGR1cmluZyB0ZXN0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdlYmV4dGVuc2lvblBvbHlmaWxsQWxpYXMoXG4gIGNvbmZpZzogSW50ZXJuYWxDb25maWcsXG4pOiB2aXRlLlBsdWdpbk9wdGlvbiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ3d4dDp3ZWJleHRlbnNpb24tcG9seWZpbGwtdGVzdC1hbGlhcycsXG4gICAgY29uZmlnKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVzb2x2ZToge1xuICAgICAgICAgIGFsaWFzOiB7XG4gICAgICAgICAgICAnd2ViZXh0ZW5zaW9uLXBvbHlmaWxsJzogcGF0aC5yZXNvbHZlKFxuICAgICAgICAgICAgICBjb25maWcucm9vdCxcbiAgICAgICAgICAgICAgJ25vZGVfbW9kdWxlcy93eHQvZGlzdC92aXJ0dWFsLW1vZHVsZXMvZmFrZS1icm93c2VyJyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBsb2FkQ29uZmlnIH0gZnJvbSAnYzEyJztcbmltcG9ydCB7XG4gIElubGluZUNvbmZpZyxcbiAgSW50ZXJuYWxDb25maWcsXG4gIFVzZXJDb25maWcsXG4gIENvbmZpZ0VudixcbiAgVXNlck1hbmlmZXN0Rm4sXG4gIFVzZXJNYW5pZmVzdCxcbiAgV3h0Vml0ZUNvbmZpZyxcbiAgRXh0ZW5zaW9uUnVubmVyQ29uZmlnLFxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcbmltcG9ydCB7IGNyZWF0ZUZzQ2FjaGUgfSBmcm9tICcuL2NyZWF0ZUZzQ2FjaGUnO1xuaW1wb3J0IGNvbnNvbGEsIHsgTG9nTGV2ZWxzIH0gZnJvbSAnY29uc29sYSc7XG5pbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gJy4uL3ZpdGUtcGx1Z2lucyc7XG5cbi8qKlxuICogR2l2ZW4gYW4gaW5saW5lIGNvbmZpZywgZGlzY292ZXIgdGhlIGNvbmZpZyBmaWxlIGlmIG5lY2Vzc2FyeSwgbWVyZ2UgdGhlIHJlc3VsdHMsIHJlc29sdmUgYW55XG4gKiByZWxhdGl2ZSBwYXRocywgYW5kIGFwcGx5IGFueSBkZWZhdWx0cy5cbiAqXG4gKiBJbmxpbmUgY29uZmlnIGFsd2F5cyBoYXMgcHJpb3JpdHkgb3ZlciB1c2VyIGNvbmZpZy4gQ2xpIGZsYWdzIGFyZSBwYXNzZWQgYXMgaW5saW5lIGNvbmZpZyBpZiBzZXQuXG4gKiBJZiB1bnNldCwgdW5kZWZpbmVkIGlzIHBhc3NlZCBpbiwgbGV0dGluZyB0aGlzIGZ1bmN0aW9uIGRlY2lkZSBkZWZhdWx0IHZhbHVlcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEludGVybmFsQ29uZmlnKFxuICBpbmxpbmVDb25maWc6IElubGluZUNvbmZpZyxcbiAgY29tbWFuZDogJ2J1aWxkJyB8ICdzZXJ2ZScsXG4pOiBQcm9taXNlPEludGVybmFsQ29uZmlnPiB7XG4gIC8vIExvYWQgdXNlciBjb25maWdcblxuICBsZXQgdXNlckNvbmZpZzogVXNlckNvbmZpZyA9IHt9O1xuICBsZXQgdXNlckNvbmZpZ01ldGFkYXRhOiBJbnRlcm5hbENvbmZpZ1sndXNlckNvbmZpZ01ldGFkYXRhJ10gfCB1bmRlZmluZWQ7XG4gIGlmIChpbmxpbmVDb25maWcuY29uZmlnRmlsZSAhPT0gZmFsc2UpIHtcbiAgICBjb25zdCB7IGNvbmZpZzogbG9hZGVkQ29uZmlnLCAuLi5tZXRhZGF0YSB9ID0gYXdhaXQgbG9hZENvbmZpZzxVc2VyQ29uZmlnPih7XG4gICAgICBuYW1lOiAnd3h0JyxcbiAgICAgIGN3ZDogaW5saW5lQ29uZmlnLnJvb3QgPz8gcHJvY2Vzcy5jd2QoKSxcbiAgICAgIHJjRmlsZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdXNlckNvbmZpZyA9IGxvYWRlZENvbmZpZyA/PyB7fTtcbiAgICB1c2VyQ29uZmlnTWV0YWRhdGEgPSBtZXRhZGF0YTtcbiAgfVxuXG4gIC8vIE1lcmdlIGl0IGludG8gdGhlIGlubGluZSBjb25maWdcblxuICBjb25zdCBtZXJnZWRDb25maWcgPSBtZXJnZUlubGluZUNvbmZpZyhpbmxpbmVDb25maWcsIHVzZXJDb25maWcpO1xuXG4gIC8vIEFwcGx5IGRlZmF1bHRzIHRvIG1ha2UgaW50ZXJuYWwgY29uZmlnLlxuXG4gIGNvbnN0IGRlYnVnID0gbWVyZ2VkQ29uZmlnLmRlYnVnID8/IGZhbHNlO1xuICBjb25zdCBsb2dnZXIgPSBtZXJnZWRDb25maWcubG9nZ2VyID8/IGNvbnNvbGE7XG4gIGlmIChkZWJ1ZykgbG9nZ2VyLmxldmVsID0gTG9nTGV2ZWxzLmRlYnVnO1xuXG4gIGNvbnN0IGJyb3dzZXIgPSBtZXJnZWRDb25maWcuYnJvd3NlciA/PyAnY2hyb21lJztcbiAgY29uc3QgbWFuaWZlc3RWZXJzaW9uID1cbiAgICBtZXJnZWRDb25maWcubWFuaWZlc3RWZXJzaW9uID8/XG4gICAgKGJyb3dzZXIgPT09ICdmaXJlZm94JyB8fCBicm93c2VyID09PSAnc2FmYXJpJyA/IDIgOiAzKTtcbiAgY29uc3QgbW9kZSA9XG4gICAgbWVyZ2VkQ29uZmlnLm1vZGUgPz8gKGNvbW1hbmQgPT09ICdidWlsZCcgPyAncHJvZHVjdGlvbicgOiAnZGV2ZWxvcG1lbnQnKTtcbiAgY29uc3QgZW52OiBDb25maWdFbnYgPSB7IGJyb3dzZXIsIGNvbW1hbmQsIG1hbmlmZXN0VmVyc2lvbiwgbW9kZSB9O1xuXG4gIGNvbnN0IHJvb3QgPSBwYXRoLnJlc29sdmUoXG4gICAgaW5saW5lQ29uZmlnLnJvb3QgPz8gdXNlckNvbmZpZy5yb290ID8/IHByb2Nlc3MuY3dkKCksXG4gICk7XG4gIGNvbnN0IHd4dERpciA9IHBhdGgucmVzb2x2ZShyb290LCAnLnd4dCcpO1xuICBjb25zdCBzcmNEaXIgPSBwYXRoLnJlc29sdmUocm9vdCwgbWVyZ2VkQ29uZmlnLnNyY0RpciA/PyByb290KTtcbiAgY29uc3QgZW50cnlwb2ludHNEaXIgPSBwYXRoLnJlc29sdmUoXG4gICAgc3JjRGlyLFxuICAgIG1lcmdlZENvbmZpZy5lbnRyeXBvaW50c0RpciA/PyAnZW50cnlwb2ludHMnLFxuICApO1xuICBjb25zdCBwdWJsaWNEaXIgPSBwYXRoLnJlc29sdmUoc3JjRGlyLCBtZXJnZWRDb25maWcucHVibGljRGlyID8/ICdwdWJsaWMnKTtcbiAgY29uc3QgdHlwZXNEaXIgPSBwYXRoLnJlc29sdmUod3h0RGlyLCAndHlwZXMnKTtcbiAgY29uc3Qgb3V0QmFzZURpciA9IHBhdGgucmVzb2x2ZShyb290LCAnLm91dHB1dCcpO1xuICBjb25zdCBvdXREaXIgPSBwYXRoLnJlc29sdmUob3V0QmFzZURpciwgYCR7YnJvd3Nlcn0tbXYke21hbmlmZXN0VmVyc2lvbn1gKTtcblxuICBjb25zdCBydW5uZXJDb25maWcgPSBhd2FpdCBsb2FkQ29uZmlnPEV4dGVuc2lvblJ1bm5lckNvbmZpZz4oe1xuICAgIG5hbWU6ICd3ZWItZXh0JyxcbiAgICBjd2Q6IHJvb3QsXG4gICAgZ2xvYmFsUmM6IHRydWUsXG4gICAgcmNGaWxlOiAnLndlYmV4dHJjJyxcbiAgICBvdmVycmlkZXM6IGlubGluZUNvbmZpZy5ydW5uZXIsXG4gICAgZGVmYXVsdHM6IHVzZXJDb25maWcucnVubmVyLFxuICB9KTtcblxuICBjb25zdCBmaW5hbENvbmZpZzogSW50ZXJuYWxDb25maWcgPSB7XG4gICAgYnJvd3NlcixcbiAgICBjb21tYW5kLFxuICAgIGRlYnVnLFxuICAgIGVudHJ5cG9pbnRzRGlyLFxuICAgIGVudixcbiAgICBmc0NhY2hlOiBjcmVhdGVGc0NhY2hlKHd4dERpciksXG4gICAgaW1wb3J0czogbWVyZ2VkQ29uZmlnLmltcG9ydHMgPz8ge30sXG4gICAgbG9nZ2VyLFxuICAgIG1hbmlmZXN0OiBhd2FpdCByZXNvbHZlTWFuaWZlc3RDb25maWcoZW52LCBtZXJnZWRDb25maWcubWFuaWZlc3QpLFxuICAgIG1hbmlmZXN0VmVyc2lvbixcbiAgICBtb2RlLFxuICAgIG91dEJhc2VEaXIsXG4gICAgb3V0RGlyLFxuICAgIHB1YmxpY0RpcixcbiAgICByb290LFxuICAgIHJ1bm5lckNvbmZpZyxcbiAgICBzcmNEaXIsXG4gICAgdHlwZXNEaXIsXG4gICAgdml0ZTogKCkgPT4gKHt9KSwgLy8gUmVhbCB2YWx1ZSBhZGRlZCBhZnRlciB0aGlzIG9iamVjdCBpcyBpbml0aWFsaXplZC5cbiAgICB3eHREaXIsXG4gICAgemlwOiByZXNvbHZlSW50ZXJuYWxaaXBDb25maWcocm9vdCwgbWVyZ2VkQ29uZmlnKSxcbiAgICB0cmFuc2Zvcm1NYW5pZmVzdChtYW5pZmVzdCkge1xuICAgICAgdXNlckNvbmZpZy50cmFuc2Zvcm1NYW5pZmVzdD8uKG1hbmlmZXN0KTtcbiAgICAgIGlubGluZUNvbmZpZy50cmFuc2Zvcm1NYW5pZmVzdD8uKG1hbmlmZXN0KTtcbiAgICB9LFxuICAgIGFuYWx5c2lzOiB7XG4gICAgICBlbmFibGVkOiBtZXJnZWRDb25maWcuYW5hbHlzaXM/LmVuYWJsZWQgPz8gZmFsc2UsXG4gICAgICB0ZW1wbGF0ZTogbWVyZ2VkQ29uZmlnLmFuYWx5c2lzPy50ZW1wbGF0ZSA/PyAndHJlZW1hcCcsXG4gICAgfSxcbiAgICB1c2VyQ29uZmlnTWV0YWRhdGE6IHVzZXJDb25maWdNZXRhZGF0YSA/PyB7fSxcbiAgfTtcblxuICBmaW5hbENvbmZpZy52aXRlID0gKGVudikgPT5cbiAgICByZXNvbHZlSW50ZXJuYWxWaXRlQ29uZmlnKGVudiwgbWVyZ2VkQ29uZmlnLCBmaW5hbENvbmZpZyk7XG5cbiAgcmV0dXJuIGZpbmFsQ29uZmlnO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlTWFuaWZlc3RDb25maWcoXG4gIGVudjogQ29uZmlnRW52LFxuICBtYW5pZmVzdDogVXNlck1hbmlmZXN0IHwgUHJvbWlzZTxVc2VyTWFuaWZlc3Q+IHwgVXNlck1hbmlmZXN0Rm4gfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFVzZXJNYW5pZmVzdD4ge1xuICByZXR1cm4gYXdhaXQgKHR5cGVvZiBtYW5pZmVzdCA9PT0gJ2Z1bmN0aW9uJ1xuICAgID8gbWFuaWZlc3QoZW52KVxuICAgIDogbWFuaWZlc3QgPz8ge30pO1xufVxuXG4vKipcbiAqIE1lcmdlIHRoZSBpbmxpbmUgY29uZmlnIGFuZCB1c2VyIGNvbmZpZy4gSW5saW5lIGNvbmZpZyBpcyBnaXZlbiBwcmlvcml0eS4gRGVmYXVsdHMgYXJlIG5vdCBhcHBsaWVkIGhlcmUuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlSW5saW5lQ29uZmlnKFxuICBpbmxpbmVDb25maWc6IElubGluZUNvbmZpZyxcbiAgdXNlckNvbmZpZzogVXNlckNvbmZpZyxcbik6IElubGluZUNvbmZpZyB7XG4gIGxldCBpbXBvcnRzOiBJbmxpbmVDb25maWdbJ2ltcG9ydHMnXTtcbiAgaWYgKGlubGluZUNvbmZpZy5pbXBvcnRzID09PSBmYWxzZSB8fCB1c2VyQ29uZmlnLmltcG9ydHMgPT09IGZhbHNlKSB7XG4gICAgaW1wb3J0cyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKHVzZXJDb25maWcuaW1wb3J0cyA9PSBudWxsICYmIGlubGluZUNvbmZpZy5pbXBvcnRzID09IG51bGwpIHtcbiAgICBpbXBvcnRzID0gdW5kZWZpbmVkO1xuICB9IGVsc2Uge1xuICAgIGltcG9ydHMgPSB2aXRlLm1lcmdlQ29uZmlnKFxuICAgICAgdXNlckNvbmZpZy5pbXBvcnRzID8/IHt9LFxuICAgICAgaW5saW5lQ29uZmlnLmltcG9ydHMgPz8ge30sXG4gICAgKTtcbiAgfVxuICBjb25zdCBtYW5pZmVzdDogVXNlck1hbmlmZXN0Rm4gPSBhc3luYyAoZW52KSA9PiB7XG4gICAgY29uc3QgdXNlciA9IGF3YWl0IHJlc29sdmVNYW5pZmVzdENvbmZpZyhlbnYsIHVzZXJDb25maWcubWFuaWZlc3QpO1xuICAgIGNvbnN0IGlubGluZSA9IGF3YWl0IHJlc29sdmVNYW5pZmVzdENvbmZpZyhlbnYsIGlubGluZUNvbmZpZy5tYW5pZmVzdCk7XG4gICAgcmV0dXJuIHZpdGUubWVyZ2VDb25maWcodXNlciwgaW5saW5lKTtcbiAgfTtcbiAgY29uc3Qgdml0ZUNvbmZpZyA9IGFzeW5jIChlbnY6IENvbmZpZ0Vudik6IFByb21pc2U8V3h0Vml0ZUNvbmZpZz4gPT4ge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB1c2VyQ29uZmlnLnZpdGU/LihlbnYpO1xuICAgIGNvbnN0IGlubGluZSA9IGF3YWl0IGlubGluZUNvbmZpZy52aXRlPy4oZW52KTtcbiAgICByZXR1cm4gdml0ZS5tZXJnZUNvbmZpZyh1c2VyID8/IHt9LCBpbmxpbmUgPz8ge30pO1xuICB9O1xuICBjb25zdCBydW5uZXI6IElubGluZUNvbmZpZ1sncnVubmVyJ10gPSB2aXRlLm1lcmdlQ29uZmlnKFxuICAgIHVzZXJDb25maWcucnVubmVyID8/IHt9LFxuICAgIGlubGluZUNvbmZpZy5ydW5uZXIgPz8ge30sXG4gICk7XG4gIGNvbnN0IHppcDogSW5saW5lQ29uZmlnWyd6aXAnXSA9IHZpdGUubWVyZ2VDb25maWcoXG4gICAgdXNlckNvbmZpZy56aXAgPz8ge30sXG4gICAgaW5saW5lQ29uZmlnLnppcCA/PyB7fSxcbiAgKTtcblxuICByZXR1cm4ge1xuICAgIHJvb3Q6IGlubGluZUNvbmZpZy5yb290ID8/IHVzZXJDb25maWcucm9vdCxcbiAgICBicm93c2VyOiBpbmxpbmVDb25maWcuYnJvd3NlciA/PyB1c2VyQ29uZmlnLmJyb3dzZXIsXG4gICAgbWFuaWZlc3RWZXJzaW9uOiBpbmxpbmVDb25maWcubWFuaWZlc3RWZXJzaW9uID8/IHVzZXJDb25maWcubWFuaWZlc3RWZXJzaW9uLFxuICAgIGNvbmZpZ0ZpbGU6IGlubGluZUNvbmZpZy5jb25maWdGaWxlLFxuICAgIGRlYnVnOiBpbmxpbmVDb25maWcuZGVidWcgPz8gdXNlckNvbmZpZy5kZWJ1ZyxcbiAgICBlbnRyeXBvaW50c0RpcjogaW5saW5lQ29uZmlnLmVudHJ5cG9pbnRzRGlyID8/IHVzZXJDb25maWcuZW50cnlwb2ludHNEaXIsXG4gICAgaW1wb3J0cyxcbiAgICBsb2dnZXI6IGlubGluZUNvbmZpZy5sb2dnZXIgPz8gdXNlckNvbmZpZy5sb2dnZXIsXG4gICAgbWFuaWZlc3QsXG4gICAgbW9kZTogaW5saW5lQ29uZmlnLm1vZGUgPz8gdXNlckNvbmZpZy5tb2RlLFxuICAgIHB1YmxpY0RpcjogaW5saW5lQ29uZmlnLnB1YmxpY0RpciA/PyB1c2VyQ29uZmlnLnB1YmxpY0RpcixcbiAgICBydW5uZXIsXG4gICAgc3JjRGlyOiBpbmxpbmVDb25maWcuc3JjRGlyID8/IHVzZXJDb25maWcuc3JjRGlyLFxuICAgIHZpdGU6IHZpdGVDb25maWcsXG4gICAgemlwLFxuICAgIGFuYWx5c2lzOiB7XG4gICAgICBlbmFibGVkOiBpbmxpbmVDb25maWcuYW5hbHlzaXM/LmVuYWJsZWQgPz8gdXNlckNvbmZpZy5hbmFseXNpcz8uZW5hYmxlZCxcbiAgICAgIHRlbXBsYXRlOlxuICAgICAgICBpbmxpbmVDb25maWcuYW5hbHlzaXM/LnRlbXBsYXRlID8/IHVzZXJDb25maWcuYW5hbHlzaXM/LnRlbXBsYXRlLFxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVJbnRlcm5hbFppcENvbmZpZyhcbiAgcm9vdDogc3RyaW5nLFxuICBtZXJnZWRDb25maWc6IElubGluZUNvbmZpZyxcbik6IEludGVybmFsQ29uZmlnWyd6aXAnXSB7XG4gIHJldHVybiB7XG4gICAgc291cmNlc1RlbXBsYXRlOiAne3tuYW1lfX0te3t2ZXJzaW9ufX0tc291cmNlcy56aXAnLFxuICAgIGFydGlmYWN0VGVtcGxhdGU6ICd7e25hbWV9fS17e3ZlcnNpb259fS17e2Jyb3dzZXJ9fS56aXAnLFxuICAgIHNvdXJjZXNSb290OiByb290LFxuICAgIC4uLm1lcmdlZENvbmZpZy56aXAsXG4gICAgaWdub3JlZFNvdXJjZXM6IFtcbiAgICAgICcqKi9ub2RlX21vZHVsZXMnLFxuICAgICAgLy8gV1hUIGZpbGVzXG4gICAgICAnKiovd2ViLWV4dC5jb25maWcudHMnLFxuICAgICAgLy8gSGlkZGVuIGZpbGVzXG4gICAgICAnKiovLionLFxuICAgICAgLy8gVGVzdHNcbiAgICAgICcqKi9fX3Rlc3RzX18vKionLFxuICAgICAgJyoqLyouKyh0ZXN0fHNwZWMpLj8oY3xtKSsoanx0KXM/KHgpJyxcbiAgICAgIC8vIEZyb20gdXNlclxuICAgICAgLi4uKG1lcmdlZENvbmZpZy56aXA/Lmlnbm9yZWRTb3VyY2VzID8/IFtdKSxcbiAgICBdLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlSW50ZXJuYWxWaXRlQ29uZmlnKFxuICBlbnY6IENvbmZpZ0VudixcbiAgbWVyZ2VkQ29uZmlnOiBJbmxpbmVDb25maWcsXG4gIGZpbmFsQ29uZmlnOiBJbnRlcm5hbENvbmZpZyxcbikge1xuICBjb25zdCBpbnRlcm5hbFZpdGU6IHZpdGUuSW5saW5lQ29uZmlnID1cbiAgICAoYXdhaXQgbWVyZ2VkQ29uZmlnLnZpdGU/LihlbnYpKSA/PyB7fTtcblxuICBpbnRlcm5hbFZpdGUucm9vdCA9IGZpbmFsQ29uZmlnLnJvb3Q7XG4gIGludGVybmFsVml0ZS5jb25maWdGaWxlID0gZmFsc2U7XG4gIGludGVybmFsVml0ZS5sb2dMZXZlbCA9ICd3YXJuJztcbiAgaW50ZXJuYWxWaXRlLm1vZGUgPSBlbnYubW9kZTtcblxuICBpbnRlcm5hbFZpdGUuYnVpbGQgPz89IHt9O1xuICBpbnRlcm5hbFZpdGUuYnVpbGQub3V0RGlyID0gZmluYWxDb25maWcub3V0RGlyO1xuICBpbnRlcm5hbFZpdGUuYnVpbGQuZW1wdHlPdXREaXIgPSBmYWxzZTtcblxuICBpbnRlcm5hbFZpdGUucGx1Z2lucyA/Pz0gW107XG4gIGludGVybmFsVml0ZS5wbHVnaW5zLnB1c2gocGx1Z2lucy5kb3dubG9hZChmaW5hbENvbmZpZykpO1xuICBpbnRlcm5hbFZpdGUucGx1Z2lucy5wdXNoKHBsdWdpbnMuZGV2SHRtbFByZXJlbmRlcihmaW5hbENvbmZpZykpO1xuICBpbnRlcm5hbFZpdGUucGx1Z2lucy5wdXNoKHBsdWdpbnMudW5pbXBvcnQoZmluYWxDb25maWcpKTtcbiAgaW50ZXJuYWxWaXRlLnBsdWdpbnMucHVzaChcbiAgICBwbHVnaW5zLnZpcnR1YWxFbnRyeXBvaW50KCdiYWNrZ3JvdW5kJywgZmluYWxDb25maWcpLFxuICApO1xuICBpbnRlcm5hbFZpdGUucGx1Z2lucy5wdXNoKFxuICAgIHBsdWdpbnMudmlydHVhbEVudHJ5cG9pbnQoJ2NvbnRlbnQtc2NyaXB0JywgZmluYWxDb25maWcpLFxuICApO1xuICBpbnRlcm5hbFZpdGUucGx1Z2lucy5wdXNoKFxuICAgIHBsdWdpbnMudmlydHVhbEVudHJ5cG9pbnQoJ3VubGlzdGVkLXNjcmlwdCcsIGZpbmFsQ29uZmlnKSxcbiAgKTtcbiAgaW50ZXJuYWxWaXRlLnBsdWdpbnMucHVzaChwbHVnaW5zLmRldlNlcnZlckdsb2JhbHMoZmluYWxDb25maWcpKTtcbiAgaW50ZXJuYWxWaXRlLnBsdWdpbnMucHVzaChwbHVnaW5zLnRzY29uZmlnUGF0aHMoZmluYWxDb25maWcpKTtcbiAgaW50ZXJuYWxWaXRlLnBsdWdpbnMucHVzaChwbHVnaW5zLm5vb3BCYWNrZ3JvdW5kKCkpO1xuICBpZiAoZmluYWxDb25maWcuYW5hbHlzaXMuZW5hYmxlZCkge1xuICAgIGludGVybmFsVml0ZS5wbHVnaW5zLnB1c2gocGx1Z2lucy5idW5kbGVBbmFseXNpcygpKTtcbiAgfVxuICBpbnRlcm5hbFZpdGUucGx1Z2lucy5wdXNoKHBsdWdpbnMuZ2xvYmFscyhmaW5hbENvbmZpZykpO1xuXG4gIHJldHVybiBpbnRlcm5hbFZpdGU7XG59XG4iLCAiaW1wb3J0IGZzLCB7IGVuc3VyZURpciB9IGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCB7IEZzQ2FjaGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBkaXJuYW1lLCByZXNvbHZlIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyB3cml0ZUZpbGVJZkRpZmZlcmVudCB9IGZyb20gJy4vZnMnO1xuXG4vKipcbiAqIEEgYmFzaWMgZmlsZSBzeXN0ZW0gY2FjaGUgc3RvcmVkIGF0IGA8c3JjRGlyPi8ud3h0L2NhY2hlLzxrZXk+YC4gSnVzdCBjYWNoZXMgYSBzdHJpbmcgaW4gYVxuICogZmlsZSBmb3IgdGhlIGdpdmVuIGtleS5cbiAqXG4gKiBAcGFyYW0gc3JjRGlyIEFic29sdXRlIHBhdGggdG8gc291cmNlIGRpcmVjdG9yeS4gU2VlIGBJbnRlcm5hbENvbmZpZy5zcmNEaXJgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVGc0NhY2hlKHd4dERpcjogc3RyaW5nKTogRnNDYWNoZSB7XG4gIGNvbnN0IGdldFBhdGggPSAoa2V5OiBzdHJpbmcpID0+XG4gICAgcmVzb2x2ZSh3eHREaXIsICdjYWNoZScsIGVuY29kZVVSSUNvbXBvbmVudChrZXkpKTtcblxuICByZXR1cm4ge1xuICAgIGFzeW5jIHNldChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgY29uc3QgcGF0aCA9IGdldFBhdGgoa2V5KTtcbiAgICAgIGF3YWl0IGVuc3VyZURpcihkaXJuYW1lKHBhdGgpKTtcbiAgICAgIGF3YWl0IHdyaXRlRmlsZUlmRGlmZmVyZW50KHBhdGgsIHZhbHVlKTtcbiAgICB9LFxuICAgIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgICBjb25zdCBwYXRoID0gZ2V0UGF0aChrZXkpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZzLnJlYWRGaWxlKHBhdGgsICd1dGYtOCcpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnO1xuXG4vKipcbiAqIE9ubHkgd3JpdGUgdGhlIGNvbnRlbnRzIHRvIGEgZmlsZSBpZiBpdCByZXN1bHRzIGluIGEgY2hhbmdlLiBUaGlzIHByZXZlbnRzIHVubmVjZXNzYXJ5IGZpbGVcbiAqIHdhdGNoZXJzIGZyb20gYmVpbmcgdHJpZ2dlcmVkLCBsaWtlIFdYVCdzIGRldiBzZXJ2ZXIgb3IgdGhlIFRTIGxhbmd1YWdlIHNlcnZlciBpbiBlZGl0b3JzLlxuICpcbiAqIEBwYXJhbSBmaWxlIFRoZSBmaWxlIHRvIHdyaXRlIHRvLlxuICogQHBhcmFtIG5ld0NvbnRlbnRzIFRoZSBuZXcgdGV4dCBjb250ZW50IHRvIHdyaXRlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVGaWxlSWZEaWZmZXJlbnQoXG4gIGZpbGU6IHN0cmluZyxcbiAgbmV3Q29udGVudHM6IHN0cmluZyxcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBleGlzdGluZ0NvbnRlbnRzID0gYXdhaXQgZnNcbiAgICAucmVhZEZpbGUoZmlsZSwgJ3V0Zi04JylcbiAgICAuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblxuICBpZiAoZXhpc3RpbmdDb250ZW50cyAhPT0gbmV3Q29udGVudHMpIHtcbiAgICBhd2FpdCBmcy53cml0ZUZpbGUoZmlsZSwgbmV3Q29udGVudHMpO1xuICB9XG59XG4iLCAiaW1wb3J0ICogYXMgdml0ZSBmcm9tICd2aXRlJztcbmltcG9ydCB7XG4gIHVuaW1wb3J0LFxuICBkb3dubG9hZCxcbiAgdHNjb25maWdQYXRocyxcbiAgZ2xvYmFscyxcbiAgd2ViZXh0ZW5zaW9uUG9seWZpbGxBbGlhcyxcbn0gZnJvbSAnLi4vY29yZS92aXRlLXBsdWdpbnMnO1xuaW1wb3J0IHsgZ2V0SW50ZXJuYWxDb25maWcgfSBmcm9tICcuLi9jb3JlL3V0aWxzL2dldEludGVybmFsQ29uZmlnJztcbmltcG9ydCB7IElubGluZUNvbmZpZyB9IGZyb20gJy4uL2NvcmUvdHlwZXMnO1xuXG4vKipcbiAqIFZpdGUgcGx1Z2luIHRoYXQgY29uZmlndXJlcyBWaXRlc3Qgd2l0aCBldmVyeXRoaW5nIHJlcXVpcmVkIHRvIHRlc3QgYSBXWFQgZXh0ZW5zaW9uLCBiYXNlZCBvbiB0aGUgYDxyb290Pi93eHQuY29uZmlnLnRzYFxuICpcbiAqIGBgYHRzXG4gKiAvLyB2aXRlc3QuY29uZmlnLnRzXG4gKiBpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlc3QvY29uZmlnJztcbiAqIGltcG9ydCB7IEF1dG9JbXBvcnQgfSBmcm9tICd3eHQvdGVzdGluZyc7XG4gKlxuICogZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAqICAgcGx1Z2luczogW0F1dG9JbXBvcnQoKV0sXG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBpbmxpbmVDb25maWcgQ3VzdG9taXplIFdYVCdzIGNvbmZpZyBmb3IgdGVzdGluZy4gQW55IGNvbmZpZyBzcGVjaWZpZWQgaGVyZSBvdmVycmlkZXMgdGhlIGNvbmZpZyBmcm9tIHlvdXIgYHd4dC5jb25maWcudHNgIGZpbGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXeHRWaXRlc3QoaW5saW5lQ29uZmlnPzogSW5saW5lQ29uZmlnKTogdml0ZS5QbHVnaW5PcHRpb24ge1xuICByZXR1cm4gZ2V0SW50ZXJuYWxDb25maWcoaW5saW5lQ29uZmlnID8/IHt9LCAnc2VydmUnKS50aGVuKChjb25maWcpID0+IFtcbiAgICB3ZWJleHRlbnNpb25Qb2x5ZmlsbEFsaWFzKGNvbmZpZyksXG4gICAgdW5pbXBvcnQoY29uZmlnKSxcbiAgICBnbG9iYWxzKGNvbmZpZyksXG4gICAgZG93bmxvYWQoY29uZmlnKSxcbiAgICB0c2NvbmZpZ1BhdGhzKGNvbmZpZyksXG4gIF0pO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFBLFNBQVMsbUJBQXFDOzs7QUNDOUMsT0FBTyxRQUFRLFVBQVUsZUFBZTs7O0FDQXhDLFlBQVksVUFBVTtBQU1mLFNBQVNBLGVBQWNDLE9BQXNCO0FBQ2xELFNBQVksbUJBQWNBLEtBQUk7QUFDaEM7QUFTTyxJQUFNLGlCQUFpQixDQUFDLE9BQU8sUUFBUSxRQUFRLFFBQVEsUUFBUSxRQUFRO0FBR3ZFLElBQU0seUJBQXlCLEtBQUssZUFBZSxLQUFLLEdBQUcsQ0FBQzs7O0FEakI1RCxTQUFTLGtCQUNkLGdCQUNBLFdBRVE7QUFDUixRQUFNLGVBQWUsS0FBSyxTQUFTLGdCQUFnQixTQUFTO0FBRTVELFFBQU0sT0FBTyxhQUFhLE1BQU0sWUFBWSxDQUFDLEVBQUUsQ0FBQztBQUVoRCxTQUFPO0FBQ1Q7OztBRVhBLFNBQVMsaUJBQWlCO0FBQzFCLFNBQVMsU0FBUyxZQUFZLFlBQUFDLFdBQVUsV0FBQUMsZ0JBQWU7QUFHdkQsSUFBSSx1QkFBdUI7QUFLcEIsU0FBUyxpQkFBaUIsUUFBMkM7QUFDMUUsUUFBTSxlQUFlO0FBQ3JCLFFBQU0sdUJBQXVCQTtBQUFBLElBQzNCLE9BQU87QUFBQSxJQUNQO0FBQUEsRUFDRjtBQUNBLFFBQU0sd0JBQXdCO0FBQzlCLFFBQU0sZ0NBQWdDLE9BQU87QUFFN0MsU0FBTztBQUFBLElBQ0w7QUFBQSxNQUNFLE9BQU87QUFBQSxNQUNQLE1BQU07QUFBQSxNQUNOLFNBQVM7QUFDUCxlQUFPO0FBQUEsVUFDTCxTQUFTO0FBQUEsWUFDUCxPQUFPO0FBQUEsY0FDTCxDQUFDLFlBQVksR0FBRztBQUFBLFlBQ2xCO0FBQUEsVUFDRjtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUE7QUFBQTtBQUFBLE1B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QUFRLFdBQVcsQ0FBQztBQUV0RCxTQUFPO0FBQ1Q7OztBR3JPTyxTQUFTLFVBQVUsY0FBZ0Q7QUFDeEUsU0FBTyxrQkFBa0IsZ0JBQWdCLENBQUMsR0FBRyxPQUFPLEVBQUUsS0FBSyxDQUFDLFdBQVc7QUFBQSxJQUNyRSwwQkFBMEIsTUFBTTtBQUFBLElBQ2hDLFNBQVMsTUFBTTtBQUFBLElBQ2YsUUFBUSxNQUFNO0FBQUEsSUFDZCxTQUFTLE1BQU07QUFBQSxJQUNmLGNBQWMsTUFBTTtBQUFBLEVBQ3RCLENBQUM7QUFDSDsiLAogICJuYW1lcyI6IFsibm9ybWFsaXplUGF0aCIsICJwYXRoIiwgInJlbGF0aXZlIiwgInJlc29sdmUiLCAiaXNPZmZsaW5lIiwgInVuaW1wb3J0IiwgImZzIiwgInJlc29sdmUiLCAibm9ybWFsaXplUGF0aCIsICJmcyIsICJyZXNvbHZlIiwgInBhdGgiLCAicGF0aCIsICJ2aXRlIiwgImZzIiwgImVuc3VyZURpciIsICJkaXJuYW1lIiwgInJlc29sdmUiLCAiZnMiLCAicmVzb2x2ZSIsICJwYXRoIiwgImVuc3VyZURpciIsICJkaXJuYW1lIiwgImZzIiwgInBhdGgiLCAiZW52Il0KfQo=