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.
- package/README.md +3 -2
- package/dist/browser.js +3 -4
- package/dist/chunk-FNTE2L27.js +7 -0
- package/dist/chunk-VFZ5667B.js +2410 -0
- package/dist/chunk-YUG22S6W.js +38 -0
- package/dist/cli.cjs +3941 -3775
- package/dist/cli.d.cts +2 -0
- package/dist/client.d.ts +5 -171
- package/dist/client.js +128 -131
- package/dist/execa-WKZHVHC5.js +2043 -0
- package/dist/external-9107db91.d.ts +176 -0
- package/dist/external-cb0967d6.d.ts +572 -0
- package/dist/index.cjs +2727 -2355
- package/dist/index.d.cts +36 -583
- package/dist/index.d.ts +36 -583
- package/dist/index.js +330 -4484
- package/dist/sandbox.d.ts +2 -23
- package/dist/sandbox.js +1 -2
- package/dist/testing.cjs +161 -35
- package/dist/testing.d.cts +7 -273
- package/dist/testing.d.ts +7 -273
- package/dist/testing.js +12 -676
- package/dist/{virtual-modules → virtual}/background-entrypoint.js +6 -7
- package/dist/{virtual-modules → virtual}/content-script-entrypoint.js +4 -5
- package/dist/virtual/mock-browser.js +152 -0
- package/dist/{virtual-modules → virtual}/reload-html.js +2 -3
- package/dist/{virtual-modules → virtual}/unlisted-script-entrypoint.js +2 -3
- package/package.json +6 -5
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/virtual-modules/background-entrypoint.js.map +0 -1
- package/dist/virtual-modules/content-script-entrypoint.js.map +0 -1
- package/dist/virtual-modules/fake-browser.cjs +0 -31
- package/dist/virtual-modules/fake-browser.js +0 -8
- package/dist/virtual-modules/reload-html.js.map +0 -1
- 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=
|