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