1 | import assert from "assert";
|
2 | import cri from "chrome-remote-interface";
|
3 | import { SourceType } from "istanbulize";
|
4 | import { InspectorServer } from "node-inspector-server";
|
5 | export async function spawnInspected(file, args, options) {
|
6 | const processCovs = [];
|
7 | const srv = await InspectorServer.open();
|
8 | return new Promise((resolve, reject) => {
|
9 | srv
|
10 | .subscribe(async (ev) => {
|
11 | try {
|
12 | // if (ev.rootProcess !== undefined && options.onRootProcess !== undefined) {
|
13 | // options.onRootProcess(ev.rootProcess);
|
14 | // }
|
15 | // const args: ReadonlyArray<string> = ["--inspect=0", ...ev.args];
|
16 | // const proxy: ChildProcessProxy = ev.proxySpawn(args);
|
17 | // const debuggerPort: number = await getDebuggerPort(proxy);
|
18 | const processCov = await getCoverage(ev.url, options.filter, options.timeout);
|
19 | processCovs.push(processCov);
|
20 | }
|
21 | catch (err) {
|
22 | reject(err);
|
23 | }
|
24 | }, reject, () => resolve(processCovs));
|
25 | const child = srv.spawn(file, args, options);
|
26 | if (options.onRootProcess !== undefined) {
|
27 | options.onRootProcess(child);
|
28 | }
|
29 | child.on("close", () => {
|
30 | srv.closeSync();
|
31 | });
|
32 | });
|
33 | }
|
34 | async function getCoverage(url, filter, timeout) {
|
35 | return new Promise(async (resolve, reject) => {
|
36 | const timeoutId = timeout !== undefined ? setTimeout(onTimeout, timeout) : undefined;
|
37 | let session;
|
38 | let mainExecutionContextId;
|
39 | const scriptIdToMeta = new Map();
|
40 | let state = "WaitingForMainContext"; // TODO: enum
|
41 | try {
|
42 | session = await cri({ target: url });
|
43 | session.once("Runtime.executionContextCreated", onMainContextCreation);
|
44 | session.on("Runtime.executionContextDestroyed", onContextDestruction);
|
45 | session.on("Debugger.scriptParsed", onScriptParsed);
|
46 | await session.Profiler.enable();
|
47 | await session.Profiler.startPreciseCoverage({ callCount: true, detailed: true });
|
48 | await session.Debugger.enable();
|
49 | await session.Runtime.enable();
|
50 | await session.Runtime.runIfWaitingForDebugger();
|
51 | }
|
52 | catch (err) {
|
53 | removeListeners();
|
54 | reject(err);
|
55 | }
|
56 | function onMainContextCreation(ev) {
|
57 | assert(state === "WaitingForMainContext");
|
58 | mainExecutionContextId = ev.context.id;
|
59 | state = "WaitingForMainContextDestruction";
|
60 | }
|
61 | function onScriptParsed(ev) {
|
62 | const collect = filter !== undefined ? filter(ev) : true;
|
63 | if (collect) {
|
64 | let sourceType = SourceType.Script;
|
65 | if (ev.isModule !== undefined) {
|
66 | sourceType = ev.isModule ? SourceType.Module : SourceType.Script;
|
67 | }
|
68 | let sourceMapUrl;
|
69 | if (ev.sourceMapURL !== undefined && ev.sourceMapURL !== "") {
|
70 | sourceMapUrl = ev.sourceMapURL;
|
71 | }
|
72 | scriptIdToMeta.set(ev.scriptId, {
|
73 | sourceType,
|
74 | sourceMapUrl,
|
75 | });
|
76 | }
|
77 | }
|
78 | async function onContextDestruction(ev) {
|
79 | assert(state === "WaitingForMainContextDestruction");
|
80 | if (ev.executionContextId !== mainExecutionContextId) {
|
81 | return;
|
82 | }
|
83 | state = "WaitingForCoverage";
|
84 | try {
|
85 | // await session.Profiler.stopPreciseCoverage();
|
86 | await session.HeapProfiler.collectGarbage();
|
87 | const { result: scriptCovs } = await session.Profiler.takePreciseCoverage();
|
88 | const result = [];
|
89 | for (const scriptCov of scriptCovs) {
|
90 | const meta = scriptIdToMeta.get(scriptCov.scriptId);
|
91 | if (meta === undefined) {
|
92 | // `undefined` means that the script was filtered out.
|
93 | continue;
|
94 | }
|
95 | const { scriptSource } = await session.Debugger.getScriptSource({ scriptId: scriptCov.scriptId });
|
96 | result.push(Object.assign(Object.assign(Object.assign({}, scriptCov), { sourceText: scriptSource }), meta));
|
97 | }
|
98 | resolve({ result });
|
99 | }
|
100 | catch (err) {
|
101 | reject(err);
|
102 | }
|
103 | finally {
|
104 | removeListeners();
|
105 | }
|
106 | }
|
107 | function onTimeout() {
|
108 | removeListeners();
|
109 | reject(new Error("Unable to get V8 coverage (timeout)"));
|
110 | }
|
111 | function removeListeners() {
|
112 | if (session === undefined) {
|
113 | // Failure before the session is created
|
114 | return;
|
115 | }
|
116 | session.removeListener("Runtime.executionContextCreated", onMainContextCreation);
|
117 | session.removeListener("Runtime.executionContextDestroyed", onContextDestruction);
|
118 | session.removeListener("Runtime.scriptParsed", onScriptParsed);
|
119 | if (timeoutId !== undefined) {
|
120 | clearTimeout(timeoutId);
|
121 | }
|
122 | session.close();
|
123 | }
|
124 | });
|
125 | }
|
126 |
|
127 | //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIl9zcmMvc3Bhd24taW5zcGVjdGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUU1QixPQUFPLEdBQUcsTUFBTSx5QkFBeUIsQ0FBQztBQUcxQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBbUIsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUF3QnpFLE1BQU0sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUNsQyxJQUFZLEVBQ1osSUFBMkIsRUFDM0IsT0FBOEI7SUFFOUIsTUFBTSxXQUFXLEdBQXFCLEVBQUUsQ0FBQztJQUV6QyxNQUFNLEdBQUcsR0FBb0IsTUFBTSxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFMUQsT0FBTyxJQUFJLE9BQU8sQ0FBbUIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDdkQsR0FBRzthQUNBLFNBQVMsQ0FDUixLQUFLLEVBQUUsRUFBbUIsRUFBRSxFQUFFO1lBQzVCLElBQUk7Z0JBQ0YsNkVBQTZFO2dCQUM3RSwyQ0FBMkM7Z0JBQzNDLElBQUk7Z0JBQ0osbUVBQW1FO2dCQUNuRSx3REFBd0Q7Z0JBQ3hELDZEQUE2RDtnQkFDN0QsTUFBTSxVQUFVLEdBQW1CLE1BQU0sV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzlGLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDOUI7WUFBQyxPQUFPLEdBQUcsRUFBRTtnQkFDWixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDYjtRQUNILENBQUMsRUFDRCxNQUFNLEVBQ04sR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUMzQixDQUFDO1FBRUosTUFBTSxLQUFLLEdBQW9CLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFF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LE9BQU8sR0FBRyxFQUFFO2dCQUNaLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNiO29CQUFTO2dCQUNSLGVBQWUsRUFBRSxDQUFDO2FBQ25CO1FBQ0gsQ0FBQztRQUVELFNBQVMsU0FBUztZQUNoQixlQUFlLEVBQUUsQ0FBQztZQUNsQixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCxTQUFTLGVBQWU7WUFDdEIsSUFBSSxPQUFPLEtBQUssU0FBUyxFQUFFO2dCQUN6Qix3Q0FBd0M7Z0JBQ3hDLE9BQU87YUFDUjtZQUVBLE9BQXNDLENBQUMsY0FBYyxDQUFDLGlDQUFpQyxFQUFFLHFCQUFxQixDQUFDLENBQUM7WUFDaEgsT0FBc0MsQ0FBQyxjQUFjLENBQUMsbUNBQW1DLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztZQUNqSCxPQUFzQyxDQUFDLGNBQWMsQ0FBQyxzQkFBc0IsRUFBRSxjQUFjLENBQUMsQ0FBQztZQUMvRixJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUU7Z0JBQzNCLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQzthQUN6QjtZQUNBLE9BQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwiZmlsZSI6InNwYXduLWluc3BlY3RlZC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFByb2Nlc3NDb3YsIFNjcmlwdENvdiB9IGZyb20gXCJAYzg4L3Y4LWNvdmVyYWdlXCI7XG5pbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCBjcCBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IGNyaSBmcm9tIFwiY2hyb21lLXJlbW90ZS1pbnRlcmZhY2VcIjtcbmltcG9ydCBQcm90b2NvbCBmcm9tIFwiZGV2dG9vbHMtcHJvdG9jb2xcIjtcbmltcG9ydCBldmVudHMgZnJvbSBcImV2ZW50c1wiO1xuaW1wb3J0IHsgU291cmNlVHlwZSB9IGZyb20gXCJpc3RhbmJ1bGl6ZVwiO1xuaW1wb3J0IHsgSW5zcGVjdG9yQ2xpZW50LCBJbnNwZWN0b3JTZXJ2ZXIgfSBmcm9tIFwibm9kZS1pbnNwZWN0b3Itc2VydmVyXCI7XG5pbXBvcnQgeyBDb3ZlcmFnZUZpbHRlciB9IGZyb20gXCIuL2ZpbHRlclwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNjcmlwdE1ldGEge1xuICBzb3VyY2VUZXh0OiBzdHJpbmc7XG4gIHNvdXJjZVR5cGU6IFNvdXJjZVR5cGU7XG4gIHNvdXJjZU1hcFVybD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSaWNoU2NyaXB0Q292IGV4dGVuZHMgU2NyaXB0Q292LCBTY3JpcHRNZXRhIHtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSaWNoUHJvY2Vzc0NvdiBleHRlbmRzIFByb2Nlc3NDb3Yge1xuICByZXN1bHQ6IFJpY2hTY3JpcHRDb3ZbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTcGF3bkluc3BlY3RlZE9wdGlvbnMgZXh0ZW5kcyBjcC5TcGF3bk9wdGlvbnMge1xuICBmaWx0ZXI/OiBDb3ZlcmFnZUZpbHRlcjtcblxuICB0aW1lb3V0PzogbnVtYmVyO1xuXG4gIG9uUm9vdFByb2Nlc3M/KHByb2Nlc3M6IGNwLkNoaWxkUHJvY2Vzcyk6IGFueTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNwYXduSW5zcGVjdGVkKFxuICBmaWxlOiBzdHJpbmcsXG4gIGFyZ3M6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPixcbiAgb3B0aW9uczogU3Bhd25JbnNwZWN0ZWRPcHRpb25zLFxuKTogUHJvbWlzZTxSaWNoUHJvY2Vzc0NvdltdPiB7XG4gIGNvbnN0IHByb2Nlc3NDb3ZzOiBSaWNoUHJvY2Vzc0NvdltdID0gW107XG5cbiAgY29uc3Qgc3J2OiBJbnNwZWN0b3JTZXJ2ZXIgPSBhd2FpdCBJbnNwZWN0b3JTZXJ2ZXIub3BlbigpO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZTxSaWNoUHJvY2Vzc0NvdltdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgc3J2XG4gICAgICAuc3Vic2NyaWJlKFxuICAgICAgICBhc3luYyAoZXY6IEluc3BlY3RvckNsaWVudCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBpZiAoZXYucm9vdFByb2Nlc3MgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLm9uUm9vdFByb2Nlc3MgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gICBvcHRpb25zLm9uUm9vdFByb2Nlc3MoZXYucm9vdFByb2Nlc3MpO1xuICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgLy8gY29uc3QgYXJnczogUmVhZG9ubHlBcnJheTxzdHJpbmc+ID0gW1wiLS1pbnNwZWN0PTBcIiwgLi4uZXYuYXJnc107XG4gICAgICAgICAgICAvLyBjb25zdCBwcm94eTogQ2hpbGRQcm9jZXNzUHJveHkgPSBldi5wcm94eVNwYXduKGFyZ3MpO1xuICAgICAgICAgICAgLy8gY29uc3QgZGVidWdnZXJQb3J0OiBudW1iZXIgPSBhd2FpdCBnZXREZWJ1Z2dlclBvcnQocHJveHkpO1xuICAgICAgICAgICAgY29uc3QgcHJvY2Vzc0NvdjogUmljaFByb2Nlc3NDb3YgPSBhd2FpdCBnZXRDb3ZlcmFnZShldi51cmwsIG9wdGlvbnMuZmlsdGVyLCBvcHRpb25zLnRpbWVvdXQpO1xuICAgICAgICAgICAgcHJvY2Vzc0NvdnMucHVzaChwcm9jZXNzQ292KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgcmVqZWN0LFxuICAgICAgICAoKSA9PiByZXNvbHZlKHByb2Nlc3NDb3ZzKSxcbiAgICAgICk7XG5cbiAgICBjb25zdCBjaGlsZDogY3AuQ2hpbGRQcm9jZXNzID0gc3J2LnNwYXduKGZpbGUsIGFyZ3MsIG9wdGlvbnMpO1xuICAgIGlmIChvcHRpb25zLm9uUm9vdFByb2Nlc3MgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9ucy5vblJvb3RQcm9jZXNzKGNoaWxkKTtcbiAgICB9XG5cbiAgICBjaGlsZC5vbihcImNsb3NlXCIsICgpID0+IHtcbiAgICAgIHNydi5jbG9zZVN5bmMoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldENvdmVyYWdlKHVybDogc3RyaW5nLCBmaWx0ZXI/OiBDb3ZlcmFnZUZpbHRlciwgdGltZW91dD86IG51bWJlcik6IFByb21pc2U8UmljaFByb2Nlc3NDb3Y+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPFJpY2hQcm9jZXNzQ292Pihhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgdGltZW91dElkOiBOb2RlSlMuVGltZXIgfCB1bmRlZmluZWQgPSB0aW1lb3V0ICE9PSB1bmRlZmluZWQgPyBzZXRUaW1lb3V0KG9uVGltZW91dCwgdGltZW91dCkgOiB1bmRlZmluZWQ7XG4gICAgbGV0IHNlc3Npb246IGFueTtcbiAgICBsZXQgbWFpbkV4ZWN1dGlvbkNvbnRleHRJZDogUHJvdG9jb2wuUnVudGltZS5FeGVjdXRpb25Db250ZXh0SWQgfCB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc2NyaXB0SWRUb01ldGE6IE1hcDxQcm90b2NvbC5SdW50aW1lLlNjcmlwdElkLCBQYXJ0aWFsPFNjcmlwdE1ldGE+PiA9IG5ldyBNYXAoKTtcbiAgICBsZXQgc3RhdGU6IHN0cmluZyA9IFwiV2FpdGluZ0Zvck1haW5Db250ZXh0XCI7IC8vIFRPRE86IGVudW1cbiAgICB0cnkge1xuICAgICAgc2Vzc2lvbiA9IGF3YWl0IGNyaSh7dGFyZ2V0OiB1cmx9KTtcbiAgICAgIChzZXNzaW9uIGFzIGFueSBhcyBldmVudHMuRXZlbnRFbWl0dGVyKS5vbmNlKFwiUnVudGltZS5leGVjdXRpb25Db250ZXh0Q3JlYXRlZFwiLCBvbk1haW5Db250ZXh0Q3JlYXRpb24pO1xuICAgICAgKHNlc3Npb24gYXMgYW55IGFzIGV2ZW50cy5FdmVudEVtaXR0ZXIpLm9uKFwiUnVudGltZS5leGVjdXRpb25Db250ZXh0RGVzdHJveWVkXCIsIG9uQ29udGV4dERlc3RydWN0aW9uKTtcbiAgICAgIChzZXNzaW9uIGFzIGFueSBhcyBldmVudHMuRXZlbnRFbWl0dGVyKS5vbihcIkRlYnVnZ2VyLnNjcmlwdFBhcnNlZFwiLCBvblNjcmlwdFBhcnNlZCk7XG5cbiAgICAgIGF3YWl0IHNlc3Npb24uUHJvZmlsZXIuZW5hYmxlKCk7XG4gICAgICBhd2FpdCBzZXNzaW9uLlByb2ZpbGVyLnN0YXJ0UHJlY2lzZUNvdmVyYWdlKHtjYWxsQ291bnQ6IHRydWUsIGRldGFpbGVkOiB0cnVlfSk7XG4gICAgICBhd2FpdCBzZXNzaW9uLkRlYnVnZ2VyLmVuYWJsZSgpO1xuICAgICAgYXdhaXQgc2Vzc2lvbi5SdW50aW1lLmVuYWJsZSgpO1xuICAgICAgYXdhaXQgc2Vzc2lvbi5SdW50aW1lLnJ1bklmV2FpdGluZ0ZvckRlYnVnZ2VyKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZW1vdmVMaXN0ZW5lcnMoKTtcbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uTWFpbkNvbnRleHRDcmVhdGlvbihldjogUHJvdG9jb2wuUnVudGltZS5FeGVjdXRpb25Db250ZXh0Q3JlYXRlZEV2ZW50KSB7XG4gICAgICBhc3NlcnQoc3RhdGUgPT09IFwiV2FpdGluZ0Zvck1haW5Db250ZXh0XCIpO1xuICAgICAgbWFpbkV4ZWN1dGlvbkNvbnRleHRJZCA9IGV2LmNvbnRleHQuaWQ7XG4gICAgICBzdGF0ZSA9IFwiV2FpdGluZ0Zvck1haW5Db250ZXh0RGVzdHJ1Y3Rpb25cIjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvblNjcmlwdFBhcnNlZChldjogUHJvdG9jb2wuRGVidWdnZXIuU2NyaXB0UGFyc2VkRXZlbnQpIHtcbiAgICAgIGNvbnN0IGNvbGxlY3Q6IGJvb2xlYW4gPSBmaWx0ZXIgIT09IHVuZGVmaW5lZCA/IGZpbHRlcihldikgOiB0cnVlO1xuICAgICAgaWYgKGNvbGxlY3QpIHtcbiAgICAgICAgbGV0IHNvdXJjZVR5cGU6IFNvdXJjZVR5cGUgPSBTb3VyY2VUeXBlLlNjcmlwdDtcbiAgICAgICAgaWYgKGV2LmlzTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBzb3VyY2VUeXBlID0gZXYuaXNNb2R1bGUgPyBTb3VyY2VUeXBlLk1vZHVsZSA6IFNvdXJjZVR5cGUuU2NyaXB0O1xuICAgICAgICB9XG4gICAgICAgIGxldCBzb3VyY2VNYXBVcmw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGV2LnNvdXJjZU1hcFVSTCAhPT0gdW5kZWZpbmVkICYmIGV2LnNvdXJjZU1hcFVSTCAhPT0gXCJcIikge1xuICAgICAgICAgIHNvdXJjZU1hcFVybCA9IGV2LnNvdXJjZU1hcFVSTDtcbiAgICAgICAgfVxuICAgICAgICBzY3JpcHRJZFRvTWV0YS5zZXQoXG4gICAgICAgICAgZXYuc2NyaXB0SWQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgc291cmNlVHlwZSxcbiAgICAgICAgICAgIHNvdXJjZU1hcFVybCxcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGZ1bmN0aW9uIG9uQ29udGV4dERlc3RydWN0aW9uKGV2OiBQcm90b2NvbC5SdW50aW1lLkV4ZWN1dGlvbkNvbnRleHREZXN0cm95ZWRFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgYXNzZXJ0KHN0YXRlID09PSBcIldhaXRpbmdGb3JNYWluQ29udGV4dERlc3RydWN0aW9uXCIpO1xuICAgICAgaWYgKGV2LmV4ZWN1dGlvbkNvbnRleHRJZCAhPT0gbWFpbkV4ZWN1dGlvbkNvbnRleHRJZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzdGF0ZSA9IFwiV2FpdGluZ0ZvckNvdmVyYWdlXCI7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIGF3YWl0IHNlc3Npb24uUHJvZmlsZXIuc3RvcFByZWNpc2VDb3ZlcmFnZSgpO1xuICAgICAgICBhd2FpdCBzZXNzaW9uLkhlYXBQcm9maWxlci5jb2xsZWN0R2FyYmFnZSgpO1xuICAgICAgICBjb25zdCB7cmVzdWx0OiBzY3JpcHRDb3ZzfSA9IGF3YWl0IHNlc3Npb24uUHJvZmlsZXIudGFrZVByZWNpc2VDb3ZlcmFnZSgpO1xuICAgICAgICBjb25zdCByZXN1bHQ6IFJpY2hTY3JpcHRDb3ZbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHNjcmlwdENvdiBvZiBzY3JpcHRDb3ZzKSB7XG4gICAgICAgICAgY29uc3QgbWV0YTogUGFydGlhbDxTY3JpcHRNZXRhPiB8IHVuZGVmaW5lZCA9IHNjcmlwdElkVG9NZXRhLmdldChzY3JpcHRDb3Yuc2NyaXB0SWQpO1xuICAgICAgICAgIGlmIChtZXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIGB1bmRlZmluZWRgIG1lYW5zIHRoYXQgdGhlIHNjcmlwdCB3YXMgZmlsdGVyZWQgb3V0LlxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHtzY3JpcHRTb3VyY2V9ID0gYXdhaXQgc2Vzc2lvbi5EZWJ1Z2dlci5nZXRTY3JpcHRTb3VyY2Uoe3NjcmlwdElkOiBzY3JpcHRDb3Yuc2NyaXB0SWR9KTtcbiAgICAgICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgICAgICAuLi5zY3JpcHRDb3YsXG4gICAgICAgICAgICBzb3VyY2VUZXh0OiBzY3JpcHRTb3VyY2UsXG4gICAgICAgICAgICAuLi5tZXRhLFxuICAgICAgICAgIH0gYXMgUmljaFNjcmlwdENvdik7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZSh7cmVzdWx0fSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICByZW1vdmVMaXN0ZW5lcnMoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvblRpbWVvdXQoKTogdm9pZCB7XG4gICAgICByZW1vdmVMaXN0ZW5lcnMoKTtcbiAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJVbmFibGUgdG8gZ2V0IFY4IGNvdmVyYWdlICh0aW1lb3V0KVwiKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXJzKCk6IHZvaWQge1xuICAgICAgaWYgKHNlc3Npb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBGYWlsdXJlIGJlZm9yZSB0aGUgc2Vzc2lvbiBpcyBjcmVhdGVkXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgKHNlc3Npb24gYXMgYW55IGFzIGV2ZW50cy5FdmVudEVtaXR0ZXIpLnJlbW92ZUxpc3RlbmVyKFwiUnVudGltZS5leGVjdXRpb25Db250ZXh0Q3JlYXRlZFwiLCBvbk1haW5Db250ZXh0Q3JlYXRpb24pO1xuICAgICAgKHNlc3Npb24gYXMgYW55IGFzIGV2ZW50cy5FdmVudEVtaXR0ZXIpLnJlbW92ZUxpc3RlbmVyKFwiUnVudGltZS5leGVjdXRpb25Db250ZXh0RGVzdHJveWVkXCIsIG9uQ29udGV4dERlc3RydWN0aW9uKTtcbiAgICAgIChzZXNzaW9uIGFzIGFueSBhcyBldmVudHMuRXZlbnRFbWl0dGVyKS5yZW1vdmVMaXN0ZW5lcihcIlJ1bnRpbWUuc2NyaXB0UGFyc2VkXCIsIG9uU2NyaXB0UGFyc2VkKTtcbiAgICAgIGlmICh0aW1lb3V0SWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIH1cbiAgICAgIChzZXNzaW9uIGFzIGFueSkuY2xvc2UoKTtcbiAgICB9XG4gIH0pO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==
|