obsidian-integration-testing 16.0.0 → 17.0.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/dist/lib/cjs/adb.cjs +2 -2
- package/dist/lib/cjs/adb.d.cts +10 -0
- package/dist/lib/cjs/avd-name-channel.cjs +74 -0
- package/dist/lib/cjs/avd-name-channel.d.cts +152 -0
- package/dist/lib/cjs/avd-probe-verdict.cjs +11 -4
- package/dist/lib/cjs/avd-probe-verdict.d.cts +7 -0
- package/dist/lib/cjs/device-screenshot.cjs +1 -1
- package/dist/lib/cjs/device-screenshot.d.cts +3 -1
- package/dist/lib/cjs/emulator-backend.cjs +22 -1
- package/dist/lib/cjs/emulator-backend.d.cts +81 -0
- package/dist/lib/cjs/emulator-reclaim.cjs +78 -34
- package/dist/lib/cjs/emulator-reclaim.d.cts +57 -9
- package/dist/lib/cjs/enable-plugin.cjs +17 -8
- package/dist/lib/cjs/enable-plugin.d.cts +3 -1
- package/dist/lib/cjs/host-process-query-verdict.cjs +103 -0
- package/dist/lib/cjs/host-process-query-verdict.d.cts +196 -0
- package/dist/lib/cjs/index.cjs +14 -1
- package/dist/lib/cjs/index.d.cts +3 -1
- package/dist/lib/cjs/launched-device-selection.cjs +46 -0
- package/dist/lib/cjs/launched-device-selection.d.cts +112 -0
- package/dist/lib/cjs/library.cjs +1 -1
- package/dist/lib/cjs/paint-out-status-bar.cjs +170 -0
- package/dist/lib/cjs/paint-out-status-bar.d.cts +236 -0
- package/dist/lib/cjs/port-owner-query-verdict.cjs +94 -0
- package/dist/lib/cjs/port-owner-query-verdict.d.cts +161 -0
- package/dist/lib/cjs/resolve-emulator-device-id.cjs +27 -4
- package/dist/lib/cjs/sharp-loader.cjs +1 -1
- package/dist/lib/cjs/sharp-loader.d.cts +67 -2
- package/dist/lib/cjs/soft-keyboard-geometry.cjs +12 -2
- package/dist/lib/cjs/soft-keyboard-geometry.d.cts +17 -2
- package/dist/lib/cjs/soft-keyboard.cjs +130 -28
- package/dist/lib/cjs/soft-keyboard.d.cts +65 -6
- package/dist/lib/cjs/transport-appium.cjs +74 -4
- package/dist/lib/cjs/transport-appium.d.cts +49 -2
- package/dist/lib/cjs/transport-factory.cjs +162 -42
- package/dist/lib/esm/adb.d.mts +10 -0
- package/dist/lib/esm/adb.mjs +2 -2
- package/dist/lib/esm/avd-name-channel.d.mts +152 -0
- package/dist/lib/esm/avd-name-channel.mjs +45 -0
- package/dist/lib/esm/avd-probe-verdict.d.mts +7 -0
- package/dist/lib/esm/avd-probe-verdict.mjs +15 -4
- package/dist/lib/esm/device-screenshot.d.mts +3 -1
- package/dist/lib/esm/device-screenshot.mjs +1 -1
- package/dist/lib/esm/emulator-backend.d.mts +81 -0
- package/dist/lib/esm/emulator-backend.mjs +19 -1
- package/dist/lib/esm/emulator-reclaim.d.mts +57 -9
- package/dist/lib/esm/emulator-reclaim.mjs +84 -36
- package/dist/lib/esm/enable-plugin.d.mts +3 -1
- package/dist/lib/esm/enable-plugin.mjs +17 -8
- package/dist/lib/esm/host-process-query-verdict.d.mts +196 -0
- package/dist/lib/esm/host-process-query-verdict.mjs +74 -0
- package/dist/lib/esm/index.d.mts +3 -1
- package/dist/lib/esm/index.mjs +15 -1
- package/dist/lib/esm/launched-device-selection.d.mts +112 -0
- package/dist/lib/esm/launched-device-selection.mjs +21 -0
- package/dist/lib/esm/library.mjs +1 -1
- package/dist/lib/esm/paint-out-status-bar.d.mts +236 -0
- package/dist/lib/esm/paint-out-status-bar.mjs +142 -0
- package/dist/lib/esm/port-owner-query-verdict.d.mts +161 -0
- package/dist/lib/esm/port-owner-query-verdict.mjs +73 -0
- package/dist/lib/esm/resolve-emulator-device-id.mjs +32 -4
- package/dist/lib/esm/sharp-loader.d.mts +67 -2
- package/dist/lib/esm/sharp-loader.mjs +1 -1
- package/dist/lib/esm/soft-keyboard-geometry.d.mts +17 -2
- package/dist/lib/esm/soft-keyboard-geometry.mjs +11 -2
- package/dist/lib/esm/soft-keyboard.d.mts +65 -6
- package/dist/lib/esm/soft-keyboard.mjs +131 -28
- package/dist/lib/esm/transport-appium.d.mts +49 -2
- package/dist/lib/esm/transport-appium.mjs +74 -4
- package/dist/lib/esm/transport-factory.mjs +176 -44
- package/package.json +1 -1
|
@@ -24,6 +24,49 @@
|
|
|
24
24
|
* integration-only `transport-factory` so the parsing and the selection stay
|
|
25
25
|
* unit-testable.
|
|
26
26
|
*/
|
|
27
|
+
/**
|
|
28
|
+
* Parameters for {@link checkIsNoMatchReported}.
|
|
29
|
+
*/
|
|
30
|
+
export interface CheckIsNoMatchReportedParams {
|
|
31
|
+
/**
|
|
32
|
+
The query's stdout.
|
|
33
|
+
*/
|
|
34
|
+
readonly output: string;
|
|
35
|
+
/**
|
|
36
|
+
The query that produced it.
|
|
37
|
+
*/
|
|
38
|
+
readonly query: EmulatorProcessQuery;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* One command that lists (some of) the host's emulator processes.
|
|
42
|
+
*/
|
|
43
|
+
export interface EmulatorProcessQuery {
|
|
44
|
+
/**
|
|
45
|
+
The executable.
|
|
46
|
+
*/
|
|
47
|
+
readonly command: string;
|
|
48
|
+
/**
|
|
49
|
+
Its arguments.
|
|
50
|
+
*/
|
|
51
|
+
readonly commandArguments: readonly string[];
|
|
52
|
+
/**
|
|
53
|
+
Whether the command asks only for emulator image names rather than for every process on the host — which is what makes an empty answer legitimate.
|
|
54
|
+
*/
|
|
55
|
+
readonly isFiltered: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parameters for {@link parseEmulatorProcessQueryOutput}.
|
|
59
|
+
*/
|
|
60
|
+
export interface ParseEmulatorProcessQueryOutputParams {
|
|
61
|
+
/**
|
|
62
|
+
The query's stdout.
|
|
63
|
+
*/
|
|
64
|
+
readonly output: string;
|
|
65
|
+
/**
|
|
66
|
+
The query that produced it.
|
|
67
|
+
*/
|
|
68
|
+
readonly query: EmulatorProcessQuery;
|
|
69
|
+
}
|
|
27
70
|
/**
|
|
28
71
|
* One process from a host process listing.
|
|
29
72
|
*/
|
|
@@ -50,6 +93,44 @@ export interface SelectEmulatorBackendPidsParams {
|
|
|
50
93
|
*/
|
|
51
94
|
readonly processes: readonly ProcessListEntry[];
|
|
52
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Builds the commands that list the host's emulator processes.
|
|
98
|
+
*
|
|
99
|
+
* **On Windows the query is filtered to the emulator image names, and that is a
|
|
100
|
+
* measured decision.** A whole-host `tasklist` does per-process work for every
|
|
101
|
+
* row, so it pays the host's contention once per process: during an emulator
|
|
102
|
+
* boot it measured p50 2.9s and max 92.2s over ~530 rows, and with every core
|
|
103
|
+
* saturated one call stalled for 120.9s — until the load exited — where the
|
|
104
|
+
* filtered call never exceeded 505ms (2026-09-23, n=8 each). The per-row cost is
|
|
105
|
+
* work the filter skips, so the filtered query does not inherit it.
|
|
106
|
+
*
|
|
107
|
+
* **On POSIX the whole-host `ps` is kept.** It reads `/proc` and was never
|
|
108
|
+
* measured slow, and a whole-host listing keeps the invariant that zero rows
|
|
109
|
+
* means a failed query — which `pgrep`'s exit 1 on no match would muddy.
|
|
110
|
+
*
|
|
111
|
+
* @param platform - The host platform, e.g. `process.platform`.
|
|
112
|
+
* @returns The queries to run; their parsed rows together are the answer.
|
|
113
|
+
*/
|
|
114
|
+
export declare function buildEmulatorProcessQueries(platform: NodeJS.Platform): EmulatorProcessQuery[];
|
|
115
|
+
/**
|
|
116
|
+
* Checks whether a query affirmatively reported that nothing matched.
|
|
117
|
+
*
|
|
118
|
+
* Only a **filtered** query can say that: a whole-host listing always has rows,
|
|
119
|
+
* so an empty one is never an answer. A filtered query that printed nothing at
|
|
120
|
+
* all is not an answer either — silence and "no emulator is running" must stay
|
|
121
|
+
* distinguishable, or a failed query reads as a host with no emulator on it.
|
|
122
|
+
*
|
|
123
|
+
* @param params - The query and its stdout.
|
|
124
|
+
* @returns Whether the query's output carries its own no-match notice.
|
|
125
|
+
*/
|
|
126
|
+
export declare function checkIsNoMatchReported(params: CheckIsNoMatchReportedParams): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Parses the output of one of {@link buildEmulatorProcessQueries}' commands.
|
|
129
|
+
*
|
|
130
|
+
* @param params - The query and its stdout.
|
|
131
|
+
* @returns One entry per parsable row, in listed order.
|
|
132
|
+
*/
|
|
133
|
+
export declare function parseEmulatorProcessQueryOutput(params: ParseEmulatorProcessQueryOutputParams): ProcessListEntry[];
|
|
53
134
|
/**
|
|
54
135
|
* Parses `ps -eo pid=,comm=` output.
|
|
55
136
|
*
|
|
@@ -39,12 +39,13 @@ var import_node_process = __toESM(require("node:process"), 1);
|
|
|
39
39
|
var import_adb_device_list = require("./adb-device-list.cjs");
|
|
40
40
|
var import_emulator_backend = require("./emulator-backend.cjs");
|
|
41
41
|
var import_emulator_marker = require("./emulator-marker.cjs");
|
|
42
|
+
var import_host_process_query_verdict = require("./host-process-query-verdict.cjs");
|
|
42
43
|
var import_kill_process_tree = require("./kill-process-tree.cjs");
|
|
43
44
|
var import_process_liveness = require("./process-liveness.cjs");
|
|
44
45
|
var import_teardown_verdict = require("./teardown-verdict.cjs");
|
|
45
46
|
const ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS = 5e3;
|
|
46
47
|
const ADB_DUMPSYS_MAX_BUFFER_IN_BYTES = 8388608;
|
|
47
|
-
const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS =
|
|
48
|
+
const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS = 12e4;
|
|
48
49
|
const EMULATOR_ESCALATED_STOP_TIMEOUT_IN_MILLISECONDS = 5e3;
|
|
49
50
|
const EMULATOR_STOP_POLL_INTERVAL_IN_MILLISECONDS = 500;
|
|
50
51
|
const EMULATOR_STOP_TIMEOUT_IN_MILLISECONDS = 2e4;
|
|
@@ -84,34 +85,41 @@ class EmulatorReclaimer {
|
|
|
84
85
|
});
|
|
85
86
|
}
|
|
86
87
|
/**
|
|
87
|
-
* Lists every process
|
|
88
|
+
* Lists the host's emulator processes — every process whose image name could
|
|
89
|
+
* be the launcher or a QEMU backend, and on POSIX every process on the host.
|
|
88
90
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
91
|
+
* On Windows this is two **filtered** `tasklist` calls rather than one
|
|
92
|
+
* whole-host listing (`buildEmulatorProcessQueries` carries the measurement
|
|
93
|
+
* that made the switch), run in parallel. A filtered call may legitimately
|
|
94
|
+
* find nothing, but only when it says so: a clean exit with neither a row nor
|
|
95
|
+
* `tasklist`'s own no-match notice is still a failed query, and comes back as
|
|
96
|
+
* `undefined` exactly like one that did not run — never as an empty list a
|
|
97
|
+
* caller could read as "no emulator is running".
|
|
93
98
|
*
|
|
94
|
-
*
|
|
99
|
+
* Each failed call logs **one** line, from `host-process-query-verdict.ts`,
|
|
100
|
+
* naming which way it failed. The predecessor logged two contradictory ones
|
|
101
|
+
* for a single failure — `could not list host processes` immediately followed
|
|
102
|
+
* by `listed no processes` — because a failed call resolved `''`, which then
|
|
103
|
+
* parsed to zero rows and tripped the zero-row check as well.
|
|
104
|
+
*
|
|
105
|
+
* **If any call fails, the whole answer is `undefined`**, and a failed call's
|
|
106
|
+
* partial stdout is parsed but never returned: the owned PID set is the
|
|
107
|
+
* difference between two answers, so a half answer — one image name's
|
|
108
|
+
* processes without the other's, or a truncated listing — would both miss a
|
|
109
|
+
* process this run owns and claim one it does not, and killing a process the
|
|
110
|
+
* run does not own is the one thing **L46** forbids. The row count goes into
|
|
111
|
+
* the log instead, as the evidence that the command was working.
|
|
112
|
+
*
|
|
113
|
+
* @returns The host's emulator processes, or `undefined` when a query failed.
|
|
95
114
|
*/
|
|
96
|
-
async
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (error) {
|
|
105
|
-
this.log(`Warning: could not list host processes (\`${query.command}\`): ${error.message}`);
|
|
106
|
-
}
|
|
107
|
-
resolve(error ? "" : stdout);
|
|
108
|
-
}
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
const processes = parseHostProcessList(output);
|
|
112
|
-
if (processes.length === 0) {
|
|
113
|
-
this.log(`Warning: \`${query.command}\` listed no processes.`);
|
|
114
|
-
return void 0;
|
|
115
|
+
async queryEmulatorProcesses() {
|
|
116
|
+
const answers = await Promise.all((0, import_emulator_backend.buildEmulatorProcessQueries)(import_node_process.default.platform).map((query) => this.runEmulatorProcessQuery(query)));
|
|
117
|
+
const processes = [];
|
|
118
|
+
for (const answer of answers) {
|
|
119
|
+
if (answer === void 0) {
|
|
120
|
+
return void 0;
|
|
121
|
+
}
|
|
122
|
+
processes.push(...answer);
|
|
115
123
|
}
|
|
116
124
|
return processes;
|
|
117
125
|
}
|
|
@@ -134,7 +142,7 @@ class EmulatorReclaimer {
|
|
|
134
142
|
if (markers.length === 0) {
|
|
135
143
|
return;
|
|
136
144
|
}
|
|
137
|
-
const processes = await this.
|
|
145
|
+
const processes = await this.queryEmulatorProcesses();
|
|
138
146
|
if (processes === void 0) {
|
|
139
147
|
this.log(`Cannot judge ${String(markers.length)} emulator marker(s) without a host process listing; leaving them for a later run.`);
|
|
140
148
|
return;
|
|
@@ -274,6 +282,48 @@ class EmulatorReclaimer {
|
|
|
274
282
|
ownedEmulatorPids: (0, import_emulator_marker.selectLiveMarkedPids)(marker, liveEmulatorPids)
|
|
275
283
|
});
|
|
276
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Runs one of the emulator process queries and classifies how it ended.
|
|
287
|
+
*
|
|
288
|
+
* @param query - The query.
|
|
289
|
+
* @returns Its parsed rows, or `undefined` when it failed.
|
|
290
|
+
*/
|
|
291
|
+
async runEmulatorProcessQuery(query) {
|
|
292
|
+
const startedAtInMilliseconds = Date.now();
|
|
293
|
+
const result = await new Promise((resolve) => {
|
|
294
|
+
(0, import_node_child_process.execFile)(
|
|
295
|
+
query.command,
|
|
296
|
+
[...query.commandArguments],
|
|
297
|
+
{ maxBuffer: ADB_DUMPSYS_MAX_BUFFER_IN_BYTES, timeout: HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS },
|
|
298
|
+
(error, stdout, stderr) => {
|
|
299
|
+
resolve({ error, standardError: stderr, standardOutput: stdout });
|
|
300
|
+
}
|
|
301
|
+
);
|
|
302
|
+
});
|
|
303
|
+
const processes = (0, import_emulator_backend.parseEmulatorProcessQueryOutput)({ output: result.standardOutput, query });
|
|
304
|
+
const outcome = (0, import_host_process_query_verdict.resolveHostProcessQueryOutcome)({
|
|
305
|
+
errorCode: result.error?.code ?? null,
|
|
306
|
+
hasFailed: result.error !== null,
|
|
307
|
+
hasReportedNoMatch: (0, import_emulator_backend.checkIsNoMatchReported)({ output: result.standardOutput, query }),
|
|
308
|
+
isKilled: result.error?.killed ?? false,
|
|
309
|
+
rowCount: processes.length,
|
|
310
|
+
standardError: result.standardError
|
|
311
|
+
});
|
|
312
|
+
const message = (0, import_host_process_query_verdict.buildHostProcessQueryMessage)({
|
|
313
|
+
command: [query.command, ...query.commandArguments].join(" "),
|
|
314
|
+
elapsedInMilliseconds: Date.now() - startedAtInMilliseconds,
|
|
315
|
+
exitCode: typeof result.error?.code === "number" ? result.error.code : null,
|
|
316
|
+
outcome,
|
|
317
|
+
partialRowCount: processes.length,
|
|
318
|
+
signal: result.error?.signal ?? null,
|
|
319
|
+
standardError: result.standardError,
|
|
320
|
+
timeoutInMilliseconds: HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS
|
|
321
|
+
});
|
|
322
|
+
if (message !== void 0) {
|
|
323
|
+
this.log(message);
|
|
324
|
+
}
|
|
325
|
+
return outcome === "listed" ? processes : void 0;
|
|
326
|
+
}
|
|
277
327
|
/**
|
|
278
328
|
* Polls until this run's emulator is gone, or the budget elapses.
|
|
279
329
|
*
|
|
@@ -293,15 +343,9 @@ class EmulatorReclaimer {
|
|
|
293
343
|
return false;
|
|
294
344
|
}
|
|
295
345
|
}
|
|
296
|
-
function buildHostProcessQuery() {
|
|
297
|
-
return import_node_process.default.platform === "win32" ? { command: "tasklist", commandArguments: ["/FO", "CSV", "/NH"] } : { command: "ps", commandArguments: ["-eo", "pid=,comm="] };
|
|
298
|
-
}
|
|
299
346
|
function describeMarkedEmulator(marker) {
|
|
300
347
|
return marker.deviceId === void 0 ? `AVD "${marker.avdName}" (no device: it was still booting when it was recorded)` : `AVD "${marker.avdName}" on device ${marker.deviceId}`;
|
|
301
348
|
}
|
|
302
|
-
function parseHostProcessList(output) {
|
|
303
|
-
return import_node_process.default.platform === "win32" ? (0, import_emulator_backend.parseWindowsTaskList)(output) : (0, import_emulator_backend.parsePosixProcessList)(output);
|
|
304
|
-
}
|
|
305
349
|
// Annotate the CommonJS export names for ESM import in node:
|
|
306
350
|
0 && (module.exports = {
|
|
307
351
|
ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS,
|
|
@@ -309,4 +353,4 @@ function parseHostProcessList(output) {
|
|
|
309
353
|
EmulatorReclaimer,
|
|
310
354
|
HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS
|
|
311
355
|
});
|
|
312
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VtdWxhdG9yLXJlY2xhaW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTdG9wcyB0aGUgZW11bGF0b3JzIHRoaXMgaGFybmVzcyBzdGFydGVkLCBhbmQgKip2ZXJpZmllcyoqIGVhY2ggc3RvcCBcdTIwMTQgdGhlXG4gKiBtYXJrZXItZHJpdmVuIGhhbGYgb2YgZW11bGF0b3Igb3duZXJzaGlwIChgZW11bGF0b3ItbWFya2VyLnRzYCwgKipMNTYqKikuXG4gKlxuICogSXQgbGl2ZXMgYXBhcnQgZnJvbSBgdHJhbnNwb3J0LWZhY3RvcnkudHNgIHNvIHRoYXQgYSBwcm9jZXNzIHdpdGggbm8gYnVzaW5lc3NcbiAqIGxvYWRpbmcgdGhlIHdob2xlIHRyYW5zcG9ydCBzdGFjayBjYW4gc3RpbGwgc3RvcCBhbiBlbXVsYXRvciBjb3JyZWN0bHkuIFRoYXRcbiAqIHByb2Nlc3MgaXMgdGhlIGVtdWxhdG9yIHJlYXBlciAoYGVtdWxhdG9yLXJlYXBlci50c2ApOiBpdCBydW5zIGRldGFjaGVkIGZyb21cbiAqIGFueSB0ZXN0IHJ1bm5lciwgYW5kIGluIHRoaXMgcmVwbydzIG93biBzdWl0ZXMgaXQgcnVucyBzdHJhaWdodCBmcm9tIHNvdXJjZVxuICogdW5kZXIgTm9kZSdzIHR5cGUgc3RyaXBwaW5nLCB3aGVyZSBhIG1vZHVsZSByZWFkaW5nIHRoZSBidWlsZC10aW1lXG4gKiBgT0JTSURJQU5fTUVUQURBVEFgIGdsb2JhbCBcdTIwMTQgd2hpY2ggdGhlIGZhY3RvcnkncyBpbXBvcnQgZ3JhcGggcmVhY2hlcyBcdTIwMTRcbiAqIGNhbm5vdCBsb2FkIGF0IGFsbC4gU28gbm90aGluZyB0aGlzIG1vZHVsZSBpbXBvcnRzIG1heSByZWFjaCBpdCBlaXRoZXIuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgZW11bGF0b3IgbWFuYWdlbWVudCBjb3ZlcmVkIGJ5IHRoZSBBbmRyb2lkIGludGVncmF0aW9uIHN1aXRlLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuXG5pbXBvcnQgeyBleGVjRmlsZSB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgdHlwZSB7IFByb2Nlc3NMaXN0RW50cnkgfSBmcm9tICcuL2VtdWxhdG9yLWJhY2tlbmQuY2pzJztcbmltcG9ydCB0eXBlIHsgRW11bGF0b3JNYXJrZXIgfSBmcm9tICcuL2VtdWxhdG9yLW1hcmtlci5janMnO1xuXG5pbXBvcnQgeyBjaGVja0lzRGV2aWNlTGlzdGVkIH0gZnJvbSAnLi9hZGItZGV2aWNlLWxpc3QuY2pzJztcbmltcG9ydCB7XG4gIHBhcnNlUG9zaXhQcm9jZXNzTGlzdCxcbiAgcGFyc2VXaW5kb3dzVGFza0xpc3QsXG4gIHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHNcbn0gZnJvbSAnLi9lbXVsYXRvci1iYWNrZW5kLmNqcyc7XG5pbXBvcnQge1xuICBjbGVhckVtdWxhdG9yTWFya2VyLFxuICBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkLFxuICBsaXN0RW11bGF0b3JNYXJrZXJzLFxuICByZXNvbHZlRW11bGF0b3JNYXJrZXJWZXJkaWN0LFxuICBzZWxlY3RMaXZlTWFya2VkUGlkc1xufSBmcm9tICcuL2VtdWxhdG9yLW1hcmtlci5janMnO1xuaW1wb3J0IHtcbiAga2lsbFByb2Nlc3NUcmVlLFxuICBraWxsUHJvY2Vzc1RyZWVCeVBpZFxufSBmcm9tICcuL2tpbGwtcHJvY2Vzcy10cmVlLmNqcyc7XG5pbXBvcnQgeyBjaGVja0lzUHJvY2Vzc0FsaXZlIH0gZnJvbSAnLi9wcm9jZXNzLWxpdmVuZXNzLmNqcyc7XG5pbXBvcnQge1xuICBidWlsZFRlYXJkb3duTWVzc2FnZSxcbiAgcmVzb2x2ZVRlYXJkb3duT3V0Y29tZVxufSBmcm9tICcuL3RlYXJkb3duLXZlcmRpY3QuY2pzJztcblxuLyoqXG4gKiBCdWRnZXQgZm9yIG9uZSBxdWljayBgYWRiYCBjYWxsIFx1MjAxNCBgYWRiIGRldmljZXNgLCBhIGNvbnNvbGUgY29tbWFuZC5cbiAqL1xuZXhwb3J0IGNvbnN0IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA1MDAwO1xuXG4vKlxuICogYGR1bXBzeXMgY29ubmVjdGl2aXR5YCBpcyBmYXIgbGFyZ2VyIHRoYW4gdGhlIG90aGVyIHByb2Jlcycgb3V0cHV0LCBhbmQgTm9kZSdzXG4gKiBkZWZhdWx0IDEgTWlCIGBtYXhCdWZmZXJgIHdvdWxkIGZhaWwgdGhlIGNhbGwgcmF0aGVyIHRoYW4gdHJ1bmNhdGUgaXQgXHUyMDE0IHdoaWNoXG4gKiB3b3VsZCByZWFkIGFzIFwibm90IHJlYWR5XCIgZm9yZXZlciBhbmQgYnVybiB0aGUgd2hvbGUgbmV0d29yayBidWRnZXQuIEEgaG9zdFxuICogcHJvY2VzcyBsaXN0aW5nIHNoYXJlcyB0aGUgc2FtZSBjZWlsaW5nLlxuICovXG5leHBvcnQgY29uc3QgQURCX0RVTVBTWVNfTUFYX0JVRkZFUl9JTl9CWVRFUyA9IDhfMzg4XzYwODtcblxuLypcbiAqIDMwcywgbm90IHRoZSAxMHMgYSBgdGFza2xpc3RgIGNvc3RzIG9uIGFuIGlkbGUgaG9zdDogdGhpcyBxdWVyeSBydW5zIGluIHRoZVxuICogc2FtZSBwb3N0LWJvb3QgY29udGVudGlvbiB3aW5kb3cgdGhhdCBpbmZsYXRlcyBldmVyeSBgYWRiYCByb3VuZC10cmlwIDI1LTUweFxuICogKEw0NSksIGFuZCB0aGUgZmlyc3QgZW5kLXRvLWVuZCBydW4gb3ZlcnJhbiBhIDEwcyBidWRnZXQgdGhlcmUgXHUyMDE0IHNpbGVudGx5XG4gKiBkaXNhcm1pbmcgdGhlIHRlYXJkb3duIGVzY2FsYXRpb24uIFNpemVkIGxpa2UgYEFEQl9EVU1QU1lTX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTYCxcbiAqIGZvciB0aGUgc2FtZSByZWFzb24uXG4gKi9cbmV4cG9ydCBjb25zdCBIT1NUX1BST0NFU1NfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG5cbmNvbnN0IEVNVUxBVE9SX0VTQ0FMQVRFRF9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IEVNVUxBVE9SX1NUT1BfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMjBfMDAwO1xuY29uc3QgTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQgPSAxMDAwO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBFbXVsYXRvclJlY2xhaW1lci5yZWNsYWltTGVmdG92ZXJFbXVsYXRvcnN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyUmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzUGFyYW1zIHtcbiAgLyoqXG4gIEFuIEFWRCB3aG9zZSBsZWZ0b3ZlciBpcyBsZWZ0IGFsb25lIFx1MjAxNCB0aGUgb25lIGEgcHJlZmxpZ2h0IGlzIGFib3V0IHRvIGFkb3B0IGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBleGNlcHRBdmROYW1lPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBgJ3ByZWZsaWdodCdgIHNwYXJlcyBhbiBlbXVsYXRvciBhbm90aGVyIGxpdmUgaGFybmVzcyBwcm9jZXNzIHN0aWxsIG93bnMuXG4gICAqIGAnZW5kLW9mLXJ1bidgIGRvZXMgbm90OiB0aGUgY2FsbGVyIGhvbGRzIHRoZSBgYW5kcm9pZGAgbG9jayB3aXRoIG5vIHJ1biBpblxuICAgKiBmbGlnaHQgXHUyMDE0IHRoZSBydW4ncyBvd24gZ2xvYmFsIHRlYXJkb3duLCBvciB0aGUgZW11bGF0b3IgcmVhcGVyIGFmdGVyIHRoZVxuICAgKiBydW4gaXMgZ29uZSBcdTIwMTQgc28gdGhhdCBvd25lciBjYW4gb25seSBiZSBvbmUgb2YgdGhlIGZpbmlzaGVkIHJ1bidzXG4gICAqIHByb2Nlc3Nlcywgd2hpY2ggbm8gbG9uZ2VyIGhhcyBhIHR1cm4gdG8gc3RvcCBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHNjb3BlOiAnZW5kLW9mLXJ1bicgfCAncHJlZmxpZ2h0Jztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgRW11bGF0b3JSZWNsYWltZXIuc3RvcEVtdWxhdG9yfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lclN0b3BFbXVsYXRvclBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQVZEIG5hbWUsIG5hbWVkIGluIHRoZSB3YXJuaW5nIHNvIHRoZSBsZWZ0b3ZlciBpcyBpZGVudGlmaWFibGUsIGFuZCB0aGUga2V5IG9mIGl0cyBtYXJrZXIuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgdGhlIGVtdWxhdG9yIGlzIHNlcnZpbmcsIHNodXQgZG93biBvdmVyIGl0cyBjb25zb2xlIGFuZCBwb2xsZWRcbiAgICogdG8gZGVjaWRlIHdoZXRoZXIgaXQgYWN0dWFsbHkgc3RvcHBlZC4gYHVuZGVmaW5lZGAgd2hlbiB0aGUgZW11bGF0b3IgZmFpbGVkXG4gICAqIGJlZm9yZSBhbnkgZGV2aWNlIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBlbXVsYXRvciBsYXVuY2hlciBwcm9jZXNzIHRoaXMgcnVuIHNwYXduZWQuIGB1bmRlZmluZWRgIGZvciBhIGxlZnRvdmVyXG4gICAqIHRoaXMgcnVuIHRvb2sgb3Zlciwgd2hvc2UgbGF1bmNoZXIgYmVsb25nZWQgdG8gYW5vdGhlciBwcm9jZXNzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JQcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgUElEcyB0aGlzIHJ1biBvd25zLCBlc2NhbGF0ZWQgdG8gd2hlbiB0aGUgY29uc29sZSBhbmQgdGhlIGxhdW5jaGVyJ3MgdHJlZSBraWxsIGxlYXZlIG9uZSBiZWhpbmQuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKlxuICogQSBob3N0IGNvbW1hbmQgYW5kIGl0cyBhcmd1bWVudHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSG9zdENvbW1hbmRRdWVyeSB7XG4gIC8qKlxuICBUaGUgZXhlY3V0YWJsZSB0byBydW4uXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBjb21tYW5kJ3MgYXJndW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZEFyZ3VtZW50czogc3RyaW5nW107XG59XG5cbmludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lckNoZWNrSXNFbXVsYXRvckdvbmVQYXJhbXMge1xuICAvKipcbiAgVGhlIGRldmljZSB0aGUgZW11bGF0b3Igc2VydmVzLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vbmUgZXZlciBhcHBlYXJlZCBcdTIwMTQgdGhlIFBJRHMgYXJlIHRoZW4gdGhlIG9ubHkgcHJvb2YuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIFBJRHMgdGhpcyBydW4gb3ducy5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyV2FpdEZvckVtdWxhdG9yU3RvcHBlZFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgZGV2aWNlIHRoZSBlbXVsYXRvciBzZXJ2ZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gbm9uZSBldmVyIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgLyoqXG4gIEhvdyBsb25nIHRvIHdhaXQgZm9yIHRoZSBlbXVsYXRvciB0byBkaXNhcHBlYXIsIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZpbmRzLCBzdG9wcyBhbmQgdmVyaWZpZXMgdGhlIGhhcm5lc3MncyBlbXVsYXRvcnMsIHJlcG9ydGluZyB0aHJvdWdoIHRoZVxuICogY2FsbGVyJ3MgbG9nIHNvIGVhY2ggY2FsbGVyIGtlZXBzIGl0cyBvd24gcHJlZml4LlxuICovXG5leHBvcnQgY2xhc3MgRW11bGF0b3JSZWNsYWltZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlY2xhaW1lciB0aGF0IHJlcG9ydHMgdW5kZXIgdGhlIGNhbGxlcidzIG93biBsb2cgcHJlZml4LlxuICAgKlxuICAgKiBAcGFyYW0gbG9nIC0gUmVjZWl2ZXMgZXZlcnkgcHJvZ3Jlc3MgYW5kIHZlcmRpY3QgbGluZS5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihsb2c6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGBhZGIgZGV2aWNlc2AgYW5kIHJldHVybnMgaXRzIHJhdyBzdGRvdXQuXG4gICAqXG4gICAqIFRoZSByYXcgbGlzdGluZyBpcyB3aGF0IHRlYXJkb3duIG5lZWRzOiBgZ2V0Q29ubmVjdGVkRGV2aWNlSWRzYCBrZWVwcyBvbmx5XG4gICAqIHRoZSBgZGV2aWNlYCBzdGF0ZSwgYW5kIGFuIGVtdWxhdG9yIG9uIGl0cyB3YXkgb3V0IGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlXG4gICAqIHN0aWxsIGhvbGRpbmcgdGhlIEFWRCBcdTIwMTQgc2VlIGBhZGItZGV2aWNlLWxpc3QudHNgLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgcmF3IGBhZGIgZGV2aWNlc2Agb3V0cHV0LlxuICAgKiBAdGhyb3dzIElmIGFkYiBjb3VsZCBub3QgYmUgcnVuIGF0IGFsbC5cbiAgICovXG4gIHB1YmxpYyBnZXREZXZpY2VzT3V0cHV0KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZXhlY0ZpbGUoJ2FkYicsIFsnZGV2aWNlcyddLCB7IHRpbWVvdXQ6IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSwgKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gcnVuICdhZGIgZGV2aWNlcyc6ICR7ZXJyb3IubWVzc2FnZX0uIElzIEFEQiBpbnN0YWxsZWQgYW5kIGluIFBBVEg/YCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RkZXJyKSB7XG4gICAgICAgICAgdGhpcy5sb2coYEFEQiBzdGRlcnI6ICR7c3RkZXJyLnRyaW0oKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHN0ZG91dCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyBldmVyeSBwcm9jZXNzIG9uIHRoZSBob3N0LlxuICAgKlxuICAgKiBBIGhvc3QgYWx3YXlzIGhhcyBwcm9jZXNzZXMsIHNvIGEgbGlzdGluZyB0aGF0IHBhcnNlcyB0byAqKnplcm8qKiByb3dzIGlzIGFcbiAgICogZmFpbGVkIHF1ZXJ5IGhvd2V2ZXIgaXQgZXhpdGVkLCBhbmQgY29tZXMgYmFjayBhcyBgdW5kZWZpbmVkYCBleGFjdGx5IGxpa2VcbiAgICogb25lIHRoYXQgZGlkIG5vdCBydW4gXHUyMDE0IG5ldmVyIGFzIGFuIGVtcHR5IGxpc3QgYSBjYWxsZXIgY291bGQgcmVhZCBhcyBcIm5vXG4gICAqIGVtdWxhdG9yIGlzIHJ1bm5pbmdcIi5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGhvc3QncyBwcm9jZXNzZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlIGxpc3RpbmcgZmFpbGVkLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHF1ZXJ5SG9zdFByb2Nlc3NlcygpOiBQcm9taXNlPFByb2Nlc3NMaXN0RW50cnlbXSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHF1ZXJ5ID0gYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5KCk7XG4gICAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoXG4gICAgICAgIHF1ZXJ5LmNvbW1hbmQsXG4gICAgICAgIHF1ZXJ5LmNvbW1hbmRBcmd1bWVudHMsXG4gICAgICAgIHsgbWF4QnVmZmVyOiBBREJfRFVNUFNZU19NQVhfQlVGRkVSX0lOX0JZVEVTLCB0aW1lb3V0OiBIT1NUX1BST0NFU1NfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSxcbiAgICAgICAgKGVycm9yLCBzdGRvdXQpID0+IHtcbiAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKGBXYXJuaW5nOiBjb3VsZCBub3QgbGlzdCBob3N0IHByb2Nlc3NlcyAoXFxgJHtxdWVyeS5jb21tYW5kfVxcYCk6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShlcnJvciA/ICcnIDogc3Rkb3V0KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IHBhcnNlSG9zdFByb2Nlc3NMaXN0KG91dHB1dCk7XG4gICAgaWYgKHByb2Nlc3Nlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMubG9nKGBXYXJuaW5nOiBcXGAke3F1ZXJ5LmNvbW1hbmR9XFxgIGxpc3RlZCBubyBwcm9jZXNzZXMuYCk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9jZXNzZXM7XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgdGhlIGVtdWxhdG9ycyB0aGlzIGhhcm5lc3Mgc3RhcnRlZCB0aGF0IG5vIGxpdmUgcnVuIGlzIHJlc3BvbnNpYmxlXG4gICAqIGZvciwgYW5kIGRyb3BzIHRoZSBtYXJrZXJzIHRoYXQgbm8gbG9uZ2VyIGRlc2NyaWJlIGEgcnVubmluZyBlbXVsYXRvci5cbiAgICpcbiAgICogT25seSBldmVyIGFjdHMgb24gYSAqKm1hcmtlci12ZXJpZmllZCoqIGVtdWxhdG9yOiBvbmUgd2hvc2UgbWFya2VyIG5hbWVzIGFcbiAgICogUElEIHRoYXQgaXMgc3RpbGwgYSBsaXZlIGVtdWxhdG9yIHByb2Nlc3MuIEFuIGVtdWxhdG9yIHdpdGhvdXQgYSBtYXJrZXIgXHUyMDE0XG4gICAqIGJvb3RlZCBieSBoYW5kLCBieSBDSSwgb3IgYnkgYW5vdGhlciB0b29sIFx1MjAxNCBpcyBuZXZlciB0b3VjaGVkLCB3aGljaCBrZWVwc1xuICAgKiB0aGUgTDQ2IGxpbmU6IG5ldmVyIGEgYHFlbXUqYCBzd2VlcC5cbiAgICpcbiAgICogQ2FsbGVycyBtdXN0IGhvbGQgdGhlIGBhbmRyb2lkYCBzZXR1cCBsb2NrIChMNyksIHdoaWNoIGlzIHdoYXQgbWFrZXMgYVxuICAgKiBsZWZ0b3ZlciBzYWZlIHRvIHN0b3A6IG5vIG90aGVyIEFuZHJvaWQgcnVuIGNhbiBiZSBtaWQtZmxpZ2h0IG9uIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gV2hpY2ggQVZEIHRvIGxlYXZlIGFsb25lLCBhbmQgd2hldGhlciB0aGlzIHJ1biBpcyBlbmRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJSZWNsYWltTGVmdG92ZXJFbXVsYXRvcnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYXJrZXJzID0gbGlzdEVtdWxhdG9yTWFya2VycygpLmZpbHRlcigobWFya2VyKSA9PiBtYXJrZXIuYXZkTmFtZSAhPT0gcGFyYW1zLmV4Y2VwdEF2ZE5hbWUpO1xuICAgIGlmIChtYXJrZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IGF3YWl0IHRoaXMucXVlcnlIb3N0UHJvY2Vzc2VzKCk7XG4gICAgaWYgKHByb2Nlc3NlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBXaXRob3V0IGEgbGlzdGluZyBldmVyeSBtYXJrZXIgd291bGQgcmVhZCBhcyBzdGFsZSwgYW5kIGRlbGV0aW5nIHRoZW0gd291bGQgbGVhdmUgdGhlIGxlZnRvdmVycyBpbXBvc3NpYmxlIHRvIGNvbnZpY3QuXG4gICAgICB0aGlzLmxvZyhgQ2Fubm90IGp1ZGdlICR7U3RyaW5nKG1hcmtlcnMubGVuZ3RoKX0gZW11bGF0b3IgbWFya2VyKHMpIHdpdGhvdXQgYSBob3N0IHByb2Nlc3MgbGlzdGluZzsgbGVhdmluZyB0aGVtIGZvciBhIGxhdGVyIHJ1bi5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsaXZlRW11bGF0b3JQaWRzID0gc2VsZWN0RW11bGF0b3JCYWNrZW5kUGlkcyh7IGtub3duUGlkczogW10sIHByb2Nlc3NlcyB9KTtcbiAgICBmb3IgKGNvbnN0IG1hcmtlciBvZiBtYXJrZXJzKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9yKG1hcmtlciwgbGl2ZUVtdWxhdG9yUGlkcywgcGFyYW1zLnNjb3BlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgYW4gZW11bGF0b3IgdGhpcyBoYXJuZXNzIG93bnMsIGFuZCAqKnZlcmlmaWVzKiogaXQgc3RvcHBlZC5cbiAgICpcbiAgICogVGhlIGNvbnNvbGUgc2h1dGRvd24gZ29lcyBmaXJzdCBiZWNhdXNlIGl0IGlzIHRoZSBvbmx5IHBhdGggdGhhdCByZWxlYXNlc1xuICAgKiB0aGUgQVZEJ3MgYG11bHRpaW5zdGFuY2UubG9ja2A7IGEgYHRhc2traWxsYCBsZWF2ZXMgdGhlIGxvY2sgYmVoaW5kLCBhbmQgYVxuICAgKiBzdGFsZSBsb2NrIGlzIHdoYXQgbWFrZXMgdGhlIG5leHQgcnVuIGZhaWwgd2l0aCBgUnVubmluZyBtdWx0aXBsZSBlbXVsYXRvcnNcbiAgICogd2l0aCB0aGUgc2FtZSBBVkRgIFx1MjAxNCBhIEZBVEFMIHRoZSBlbXVsYXRvciB3cml0ZXMgdG8gaXRzIG93biBzdGRvdXQsIHdoZXJlXG4gICAqIG5vYm9keSBzZWVzIGl0LlxuICAgKlxuICAgKiBXb3JrcyB3aXRob3V0IGEgbGF1bmNoZXIgaGFuZGxlIHRvbzogYSBsZWZ0b3ZlciB0aGlzIHJ1biB0b29rIG92ZXIgaGFzIG9ubHlcbiAgICogaXRzIFBJRHMsIHdoaWNoIGlzIGFsbCB0aGUgZXNjYWxhdGlvbiBiZWxvdyBldmVyIG5lZWRlZC4gVGhlIG1hcmtlciBnb2VzXG4gICAqIG9ubHkgd2l0aCBhICoqdmVyaWZpZWQqKiBzdG9wLCBzbyBhbiBlbXVsYXRvciB0aGF0IG91dGxpdmVkIHRoaXMgYXR0ZW1wdFxuICAgKiBzdGF5cyBjb252aWN0YWJsZSBieSB0aGUgbmV4dCBvbmUuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZW11bGF0b3IgcHJvY2VzcywgdGhlIGRldmljZSBpdCBzZXJ2ZXMgYW5kIHRoZSBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc3RvcEVtdWxhdG9yKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJTdG9wRW11bGF0b3JQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocGFyYW1zLmRldmljZUlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMua2lsbEVtdWxhdG9yQ29uc29sZShwYXJhbXMuZGV2aWNlSWQpO1xuICAgIH1cbiAgICBpZiAocGFyYW1zLmVtdWxhdG9yUHJvY2Vzcykge1xuICAgICAga2lsbFByb2Nlc3NUcmVlKHBhcmFtcy5lbXVsYXRvclByb2Nlc3MpO1xuICAgIH1cblxuICAgIGNvbnN0IHdhaXRQYXJhbXM6IEVtdWxhdG9yUmVjbGFpbWVyV2FpdEZvckVtdWxhdG9yU3RvcHBlZFBhcmFtcyA9IHtcbiAgICAgIGRldmljZUlkOiBwYXJhbXMuZGV2aWNlSWQsXG4gICAgICBvd25lZEVtdWxhdG9yUGlkczogcGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gICAgfTtcblxuICAgIGxldCBoYXNFc2NhbGF0ZWQgPSBmYWxzZTtcbiAgICBsZXQgaXNTdG9wcGVkID0gYXdhaXQgdGhpcy53YWl0Rm9yRW11bGF0b3JTdG9wcGVkKHdhaXRQYXJhbXMpO1xuXG4gICAgaWYgKCFpc1N0b3BwZWQpIHtcbiAgICAgIGNvbnN0IHN1cnZpdmluZ1BpZHMgPSBwYXJhbXMub3duZWRFbXVsYXRvclBpZHMuZmlsdGVyKChwaWQpID0+IGNoZWNrSXNQcm9jZXNzQWxpdmUocGlkKSk7XG4gICAgICBpZiAoc3Vydml2aW5nUGlkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGhhc0VzY2FsYXRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgIGBBdXRvLXN0YXJ0ZWQgZW11bGF0b3Igb3V0bGl2ZWQgaXRzIGNvbnNvbGUgc2h1dGRvd24gYW5kIHRoZSBsYXVuY2hlcidzIHByb2Nlc3MgdHJlZTsgZXNjYWxhdGluZyB0byB0aGUgZW11bGF0b3IgUElEKHMpIHRoaXMgcnVuIG93bnM6IFske3N1cnZpdmluZ1BpZHMuam9pbignLCAnKX1dLmBcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBwaWQgb2Ygc3Vydml2aW5nUGlkcykge1xuICAgICAgICAgIGtpbGxQcm9jZXNzVHJlZUJ5UGlkKHBpZCk7XG4gICAgICAgIH1cbiAgICAgICAgaXNTdG9wcGVkID0gYXdhaXQgdGhpcy53YWl0Rm9yRW11bGF0b3JTdG9wcGVkKHsgLi4ud2FpdFBhcmFtcywgdGltZW91dEluTWlsbGlzZWNvbmRzOiBFTVVMQVRPUl9FU0NBTEFURURfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxvZyhidWlsZFRlYXJkb3duTWVzc2FnZSh7XG4gICAgICBldmlkZW5jZTogcGFyYW1zLmRldmljZUlkID09PSB1bmRlZmluZWQgPyBgQVZEIFwiJHtwYXJhbXMuYXZkTmFtZX1cImAgOiBgQVZEIFwiJHtwYXJhbXMuYXZkTmFtZX1cIiBvbiBkZXZpY2UgJHtwYXJhbXMuZGV2aWNlSWR9YCxcbiAgICAgIG91dGNvbWU6IHJlc29sdmVUZWFyZG93bk91dGNvbWUoeyBoYXNFc2NhbGF0ZWQsIGlzU3RvcHBlZCB9KSxcbiAgICAgIHN1YmplY3Q6ICdBdXRvLXN0YXJ0ZWQgZW11bGF0b3InLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gICAgfSkpO1xuXG4gICAgaWYgKGlzU3RvcHBlZCkge1xuICAgICAgY2xlYXJFbXVsYXRvck1hcmtlcklmU3RvcHBlZChwYXJhbXMuYXZkTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlY2lkZXMgd2hldGhlciB0aGUgZW11bGF0b3IgdGhpcyBydW4gc3RhcnRlZCBpcyByZWFsbHkgZ29uZS5cbiAgICpcbiAgICogVHdvIGluZGVwZW5kZW50IHByb29mcywgY2hlYXBlc3QgZmlyc3Q6IG5vbmUgb2YgdGhlIFBJRHMgdGhpcyBydW4gb3ducyBpc1xuICAgKiBhbGl2ZSwgYW5kIHRoZSBkZXZpY2Ugbm8gbG9uZ2VyIGFwcGVhcnMgaW4gYGFkYiBkZXZpY2VzYCAqKmluIGFueSBzdGF0ZSoqIChhXG4gICAqIGR5aW5nIGVtdWxhdG9yIGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlIGl0IHN0aWxsIGhvbGRzIHRoZSBBVkQpLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGRldmljZSBhbmQgdGhlIFBJRHMgdGhpcyBydW4gb3ducy5cbiAgICogQHJldHVybnMgYHRydWVgIHdoZW4gbm90aGluZyBvZiB0aGlzIHJ1bidzIGVtdWxhdG9yIGlzIGxlZnQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNoZWNrSXNFbXVsYXRvckdvbmUocGFyYW1zOiBFbXVsYXRvclJlY2xhaW1lckNoZWNrSXNFbXVsYXRvckdvbmVQYXJhbXMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAocGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLnNvbWUoKHBpZCkgPT4gY2hlY2tJc1Byb2Nlc3NBbGl2ZShwaWQpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZGV2aWNlSWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAhY2hlY2tJc0RldmljZUxpc3RlZCh7IGRldmljZUlkOiBwYXJhbXMuZGV2aWNlSWQsIGRldmljZXNPdXRwdXQ6IGF3YWl0IHRoaXMuZ2V0RGV2aWNlc091dHB1dCgpIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvKlxuICAgICAgICogQW4gYWRiIHRoYXQgY2Fubm90IHJ1biBpcyBub3QgZXZpZGVuY2UgYWJvdXQgdGhlIGVtdWxhdG9yIFx1MjAxNCBhbmQgdGhlIFBJRFxuICAgICAgICogcHJvYmUgYWJvdmUgaGFzIGFscmVhZHkgc2FpZCB0aGlzIHJ1bidzIHByb2Nlc3NlcyBhcmUgZ29uZSwgd2hpY2ggaXMgdGhlXG4gICAgICAgKiBzdHJvbmdlciBvZiB0aGUgdHdvIHByb29mcy5cbiAgICAgICAqL1xuICAgICAgdGhpcy5sb2coYENvdWxkIG5vdCByZS1jaGVjayBjb25uZWN0ZWQgZGV2aWNlcyB3aGlsZSBzdG9wcGluZyB0aGUgZW11bGF0b3I6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFza3MgdGhlIGVtdWxhdG9yIHRvIHNodXQgaXRzZWxmIGRvd24gb3ZlciBpdHMgY29uc29sZS5cbiAgICpcbiAgICogUHJlZmVycmVkIG92ZXIga2lsbGluZyB0aGUgcHJvY2VzcyBvdXRyaWdodCBiZWNhdXNlIGl0IGlzIHRoZSBwYXRoIHRoYXRcbiAgICogcmVsZWFzZXMgdGhlIEFWRCdzIGBtdWx0aWluc3RhbmNlLmxvY2tgLiBCZXN0LWVmZm9ydDogYSBjb25zb2xlIHRoYXQgZG9lc1xuICAgKiBub3QgYW5zd2VyIGlzIHJlcG9ydGVkIGFuZCB0aGUgY2FsbGVyIGZhbGxzIHRocm91Z2ggdG8gdGhlIGtpbGwuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBlbXVsYXRvcidzIGRldmljZSBJRC5cbiAgICovXG4gIHByaXZhdGUga2lsbEVtdWxhdG9yQ29uc29sZShkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZSgnYWRiJywgWyctcycsIGRldmljZUlkLCAnZW11JywgJ2tpbGwnXSwgeyB0aW1lb3V0OiBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sIChlcnJvciwgc3Rkb3V0KSA9PiB7XG4gICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICA/IGBFbXVsYXRvciBjb25zb2xlIHNodXRkb3duIGZvciAke2RldmljZUlkfSBkaWQgbm90IGFuc3dlcjogJHtlcnJvci5tZXNzYWdlfWBcbiAgICAgICAgICAgIDogYEVtdWxhdG9yIGNvbnNvbGUgc2h1dGRvd24gZm9yICR7ZGV2aWNlSWR9OiAke3N0ZG91dC50cmltKCl9YFxuICAgICAgICApO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3RzIG9uIG9uZSBlbXVsYXRvciBtYXJrZXIgZm9yIHtAbGluayByZWNsYWltTGVmdG92ZXJFbXVsYXRvcnN9LlxuICAgKlxuICAgKiBAcGFyYW0gbWFya2VyIC0gVGhlIG1hcmtlciB0byBqdWRnZS5cbiAgICogQHBhcmFtIGxpdmVFbXVsYXRvclBpZHMgLSBUaGUgZW11bGF0b3IgcHJvY2Vzc2VzIGN1cnJlbnRseSBydW5uaW5nIG9uIHRoZSBob3N0LlxuICAgKiBAcGFyYW0gc2NvcGUgLSBXaGV0aGVyIGFuIGVtdWxhdG9yIGFub3RoZXIgbGl2ZSBoYXJuZXNzIHByb2Nlc3Mgb3ducyBpcyBzcGFyZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9yKG1hcmtlcjogRW11bGF0b3JNYXJrZXIsIGxpdmVFbXVsYXRvclBpZHM6IHJlYWRvbmx5IG51bWJlcltdLCBzY29wZTogRW11bGF0b3JSZWNsYWltZXJSZWNsYWltTGVmdG92ZXJFbXVsYXRvcnNQYXJhbXNbJ3Njb3BlJ10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB2ZXJkaWN0ID0gcmVzb2x2ZUVtdWxhdG9yTWFya2VyVmVyZGljdCh7XG4gICAgICBjdXJyZW50UGlkOiBwcm9jZXNzLnBpZCxcbiAgICAgIGlzT3duZXJBbGl2ZTogY2hlY2tJc1Byb2Nlc3NBbGl2ZShtYXJrZXIub3duZXJQaWQpLFxuICAgICAgbGl2ZUVtdWxhdG9yUGlkcyxcbiAgICAgIG1hcmtlclxuICAgIH0pO1xuXG4gICAgaWYgKHZlcmRpY3QgPT09ICdzdGFsZS1tYXJrZXInKSB7XG4gICAgICB0aGlzLmxvZyhgRHJvcHBpbmcgdGhlIGVtdWxhdG9yIG1hcmtlciBmb3IgQVZEIFwiJHttYXJrZXIuYXZkTmFtZX1cIjogbm9uZSBvZiBpdHMgUElEcyBbJHttYXJrZXIub3duZWRFbXVsYXRvclBpZHMuam9pbignLCAnKX1dIGlzIGEgcnVubmluZyBlbXVsYXRvciBhbnkgbW9yZS5gKTtcbiAgICAgIGNsZWFyRW11bGF0b3JNYXJrZXIobWFya2VyLmF2ZE5hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogQSBtYXJrZXIgd3JpdHRlbiBhdCBsYXVuY2ggaGFzIG5vIGRldmljZSB5ZXQ6IHRoZSBlbXVsYXRvciB3YXMgc3RpbGxcbiAgICAgKiBib290aW5nIHdoZW4gd2hhdGV2ZXIgcmVjb3JkZWQgaXQgc3RvcHBlZCBsb29raW5nLiBUaGUgc3RvcCBiZWxvdyByZWFkc1xuICAgICAqIHRoYXQgYWJzZW5jZSBjb3JyZWN0bHkgXHUyMDE0IG5vIGNvbnNvbGUgdG8gc2h1dCBkb3duLCB0aGUgb3duZWQgUElEcyBhcmUgdGhlXG4gICAgICogd2hvbGUgb2YgdGhlIGV2aWRlbmNlIFx1MjAxNCBzbyBpdCBpcyBkZXNjcmliZWQgcmF0aGVyIHRoYW4gcGFwZXJlZCBvdmVyLlxuICAgICAqL1xuICAgIGNvbnN0IGV2aWRlbmNlID0gZGVzY3JpYmVNYXJrZWRFbXVsYXRvcihtYXJrZXIpO1xuXG4gICAgaWYgKHZlcmRpY3QgPT09ICdpbi11c2UtYnktbGl2ZS1ydW4nICYmIHNjb3BlID09PSAncHJlZmxpZ2h0Jykge1xuICAgICAgdGhpcy5sb2coYExlYXZpbmcgdGhlIGVtdWxhdG9yIGZvciAke2V2aWRlbmNlfSBhbG9uZTogdGhlIGhhcm5lc3MgcHJvY2VzcyB0aGF0IG93bnMgaXQgKFBJRCAke1N0cmluZyhtYXJrZXIub3duZXJQaWQpfSkgaXMgc3RpbGwgcnVubmluZy5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhZ2VJblNlY29uZHMgPSBNYXRoLnJvdW5kKChEYXRlLm5vdygpIC0gbWFya2VyLnN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzKSAvIE1JTExJU0VDT05EU19QRVJfU0VDT05EKTtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBTdG9wcGluZyB0aGUgZW11bGF0b3IgZm9yICR7ZXZpZGVuY2V9OiB0aGlzIGhhcm5lc3Mgc3RhcnRlZCBpdCAke1N0cmluZyhhZ2VJblNlY29uZHMpfXMgYWdvLCBhbmQgbm8gbGl2ZSBydW4gaXMgbGVmdCB0byBzdG9wIGl0LmBcbiAgICApO1xuICAgIGF3YWl0IHRoaXMuc3RvcEVtdWxhdG9yKHtcbiAgICAgIGF2ZE5hbWU6IG1hcmtlci5hdmROYW1lLFxuICAgICAgZGV2aWNlSWQ6IG1hcmtlci5kZXZpY2VJZCxcbiAgICAgIG93bmVkRW11bGF0b3JQaWRzOiBzZWxlY3RMaXZlTWFya2VkUGlkcyhtYXJrZXIsIGxpdmVFbXVsYXRvclBpZHMpXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgdW50aWwgdGhpcyBydW4ncyBlbXVsYXRvciBpcyBnb25lLCBvciB0aGUgYnVkZ2V0IGVsYXBzZXMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZGV2aWNlLCB0aGUgUElEcyB0aGlzIHJ1biBvd25zLCBhbmQgdGhlIGJ1ZGdldC5cbiAgICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIGVtdWxhdG9yIGRpc2FwcGVhcmVkIHdpdGhpbiB0aGUgYnVkZ2V0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yRW11bGF0b3JTdG9wcGVkKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJXYWl0Rm9yRW11bGF0b3JTdG9wcGVkUGFyYW1zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgcGFyYW1zLnRpbWVvdXRJbk1pbGxpc2Vjb25kcztcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGlmIChhd2FpdCB0aGlzLmNoZWNrSXNFbXVsYXRvckdvbmUocGFyYW1zKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBFTVVMQVRPUl9TVE9QX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgcGxhdGZvcm0ncyBcImxpc3QgZXZlcnkgcHJvY2Vzc1wiIHF1ZXJ5LlxuICpcbiAqIEByZXR1cm5zIFRoZSBjb21tYW5kIGFuZCBhcmd1bWVudHMgdG8gcnVuLlxuICovXG5mdW5jdGlvbiBidWlsZEhvc3RQcm9jZXNzUXVlcnkoKTogSG9zdENvbW1hbmRRdWVyeSB7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInXG4gICAgPyB7IGNvbW1hbmQ6ICd0YXNrbGlzdCcsIGNvbW1hbmRBcmd1bWVudHM6IFsnL0ZPJywgJ0NTVicsICcvTkgnXSB9XG4gICAgOiB7IGNvbW1hbmQ6ICdwcycsIGNvbW1hbmRBcmd1bWVudHM6IFsnLWVvJywgJ3BpZD0sY29tbT0nXSB9O1xufVxuXG4vKipcbiAqIE5hbWVzIHRoZSBlbXVsYXRvciBhIG1hcmtlciBkZXNjcmliZXMsIGZvciB0aGUgbG9nLlxuICpcbiAqIEBwYXJhbSBtYXJrZXIgLSBUaGUgbWFya2VyLlxuICogQHJldHVybnMgVGhlIEFWRCBhbmQgaXRzIGRldmljZSwgb3IgdGhlIEFWRCBhbG9uZSBmb3IgYSBsYXVuY2ggdGhhdCBoYWQgbm90IHByb2R1Y2VkIGEgZGV2aWNlIHlldC5cbiAqL1xuZnVuY3Rpb24gZGVzY3JpYmVNYXJrZWRFbXVsYXRvcihtYXJrZXI6IEVtdWxhdG9yTWFya2VyKTogc3RyaW5nIHtcbiAgcmV0dXJuIG1hcmtlci5kZXZpY2VJZCA9PT0gdW5kZWZpbmVkXG4gICAgPyBgQVZEIFwiJHttYXJrZXIuYXZkTmFtZX1cIiAobm8gZGV2aWNlOiBpdCB3YXMgc3RpbGwgYm9vdGluZyB3aGVuIGl0IHdhcyByZWNvcmRlZClgXG4gICAgOiBgQVZEIFwiJHttYXJrZXIuYXZkTmFtZX1cIiBvbiBkZXZpY2UgJHttYXJrZXIuZGV2aWNlSWR9YDtcbn1cblxuLyoqXG4gKiBQYXJzZXMgYSBob3N0IHByb2Nlc3MgbGlzdGluZyB3aXRoIHRoZSBwbGF0Zm9ybSdzIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0gb3V0cHV0IC0gUmF3IHN0ZG91dCBvZiB7QGxpbmsgYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5fSdzIGNvbW1hbmQuXG4gKiBAcmV0dXJucyBUaGUgbGlzdGVkIHByb2Nlc3Nlcy5cbiAqL1xuZnVuY3Rpb24gcGFyc2VIb3N0UHJvY2Vzc0xpc3Qob3V0cHV0OiBzdHJpbmcpOiBQcm9jZXNzTGlzdEVudHJ5W10ge1xuICByZXR1cm4gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyA/IHBhcnNlV2luZG93c1Rhc2tMaXN0KG91dHB1dCkgOiBwYXJzZVBvc2l4UHJvY2Vzc0xpc3Qob3V0cHV0KTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBbUJBLGdDQUF5QjtBQUN6QiwwQkFBb0I7QUFLcEIsNkJBQW9DO0FBQ3BDLDhCQUlPO0FBQ1AsNkJBTU87QUFDUCwrQkFHTztBQUNQLDhCQUFvQztBQUNwQyw4QkFHTztBQUtBLE1BQU0sMkNBQTJDO0FBUWpELE1BQU0sa0NBQWtDO0FBU3hDLE1BQU0sNkNB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
|
|
356
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VtdWxhdG9yLXJlY2xhaW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTdG9wcyB0aGUgZW11bGF0b3JzIHRoaXMgaGFybmVzcyBzdGFydGVkLCBhbmQgKip2ZXJpZmllcyoqIGVhY2ggc3RvcCBcdTIwMTQgdGhlXG4gKiBtYXJrZXItZHJpdmVuIGhhbGYgb2YgZW11bGF0b3Igb3duZXJzaGlwIChgZW11bGF0b3ItbWFya2VyLnRzYCwgKipMNTYqKikuXG4gKlxuICogSXQgbGl2ZXMgYXBhcnQgZnJvbSBgdHJhbnNwb3J0LWZhY3RvcnkudHNgIHNvIHRoYXQgYSBwcm9jZXNzIHdpdGggbm8gYnVzaW5lc3NcbiAqIGxvYWRpbmcgdGhlIHdob2xlIHRyYW5zcG9ydCBzdGFjayBjYW4gc3RpbGwgc3RvcCBhbiBlbXVsYXRvciBjb3JyZWN0bHkuIFRoYXRcbiAqIHByb2Nlc3MgaXMgdGhlIGVtdWxhdG9yIHJlYXBlciAoYGVtdWxhdG9yLXJlYXBlci50c2ApOiBpdCBydW5zIGRldGFjaGVkIGZyb21cbiAqIGFueSB0ZXN0IHJ1bm5lciwgYW5kIGluIHRoaXMgcmVwbydzIG93biBzdWl0ZXMgaXQgcnVucyBzdHJhaWdodCBmcm9tIHNvdXJjZVxuICogdW5kZXIgTm9kZSdzIHR5cGUgc3RyaXBwaW5nLCB3aGVyZSBhIG1vZHVsZSByZWFkaW5nIHRoZSBidWlsZC10aW1lXG4gKiBgT0JTSURJQU5fTUVUQURBVEFgIGdsb2JhbCBcdTIwMTQgd2hpY2ggdGhlIGZhY3RvcnkncyBpbXBvcnQgZ3JhcGggcmVhY2hlcyBcdTIwMTRcbiAqIGNhbm5vdCBsb2FkIGF0IGFsbC4gU28gbm90aGluZyB0aGlzIG1vZHVsZSBpbXBvcnRzIG1heSByZWFjaCBpdCBlaXRoZXIuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgZW11bGF0b3IgbWFuYWdlbWVudCBjb3ZlcmVkIGJ5IHRoZSBBbmRyb2lkIGludGVncmF0aW9uIHN1aXRlLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBDaGlsZFByb2Nlc3MsXG4gIEV4ZWNGaWxlRXhjZXB0aW9uXG59IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5cbmltcG9ydCB7IGV4ZWNGaWxlIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB0eXBlIHtcbiAgRW11bGF0b3JQcm9jZXNzUXVlcnksXG4gIFByb2Nlc3NMaXN0RW50cnlcbn0gZnJvbSAnLi9lbXVsYXRvci1iYWNrZW5kLmNqcyc7XG5pbXBvcnQgdHlwZSB7IEVtdWxhdG9yTWFya2VyIH0gZnJvbSAnLi9lbXVsYXRvci1tYXJrZXIuY2pzJztcblxuaW1wb3J0IHsgY2hlY2tJc0RldmljZUxpc3RlZCB9IGZyb20gJy4vYWRiLWRldmljZS1saXN0LmNqcyc7XG5pbXBvcnQge1xuICBidWlsZEVtdWxhdG9yUHJvY2Vzc1F1ZXJpZXMsXG4gIGNoZWNrSXNOb01hdGNoUmVwb3J0ZWQsXG4gIHBhcnNlRW11bGF0b3JQcm9jZXNzUXVlcnlPdXRwdXQsXG4gIHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHNcbn0gZnJvbSAnLi9lbXVsYXRvci1iYWNrZW5kLmNqcyc7XG5pbXBvcnQge1xuICBjbGVhckVtdWxhdG9yTWFya2VyLFxuICBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkLFxuICBsaXN0RW11bGF0b3JNYXJrZXJzLFxuICByZXNvbHZlRW11bGF0b3JNYXJrZXJWZXJkaWN0LFxuICBzZWxlY3RMaXZlTWFya2VkUGlkc1xufSBmcm9tICcuL2VtdWxhdG9yLW1hcmtlci5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5TWVzc2FnZSxcbiAgcmVzb2x2ZUhvc3RQcm9jZXNzUXVlcnlPdXRjb21lXG59IGZyb20gJy4vaG9zdC1wcm9jZXNzLXF1ZXJ5LXZlcmRpY3QuY2pzJztcbmltcG9ydCB7XG4gIGtpbGxQcm9jZXNzVHJlZSxcbiAga2lsbFByb2Nlc3NUcmVlQnlQaWRcbn0gZnJvbSAnLi9raWxsLXByb2Nlc3MtdHJlZS5janMnO1xuaW1wb3J0IHsgY2hlY2tJc1Byb2Nlc3NBbGl2ZSB9IGZyb20gJy4vcHJvY2Vzcy1saXZlbmVzcy5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRUZWFyZG93bk1lc3NhZ2UsXG4gIHJlc29sdmVUZWFyZG93bk91dGNvbWVcbn0gZnJvbSAnLi90ZWFyZG93bi12ZXJkaWN0LmNqcyc7XG5cbi8qKlxuICogQnVkZ2V0IGZvciBvbmUgcXVpY2sgYGFkYmAgY2FsbCBcdTIwMTQgYGFkYiBkZXZpY2VzYCwgYSBjb25zb2xlIGNvbW1hbmQuXG4gKi9cbmV4cG9ydCBjb25zdCBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcblxuLypcbiAqIGBkdW1wc3lzIGNvbm5lY3Rpdml0eWAgaXMgZmFyIGxhcmdlciB0aGFuIHRoZSBvdGhlciBwcm9iZXMnIG91dHB1dCwgYW5kIE5vZGUnc1xuICogZGVmYXVsdCAxIE1pQiBgbWF4QnVmZmVyYCB3b3VsZCBmYWlsIHRoZSBjYWxsIHJhdGhlciB0aGFuIHRydW5jYXRlIGl0IFx1MjAxNCB3aGljaFxuICogd291bGQgcmVhZCBhcyBcIm5vdCByZWFkeVwiIGZvcmV2ZXIgYW5kIGJ1cm4gdGhlIHdob2xlIG5ldHdvcmsgYnVkZ2V0LiBBIGhvc3RcbiAqIHByb2Nlc3MgbGlzdGluZyBzaGFyZXMgdGhlIHNhbWUgY2VpbGluZy5cbiAqL1xuZXhwb3J0IGNvbnN0IEFEQl9EVU1QU1lTX01BWF9CVUZGRVJfSU5fQllURVMgPSA4XzM4OF82MDg7XG5cbi8qXG4gKiAxMjBzLCBub3QgdGhlIH4xcyBhIHdob2xlLWhvc3QgYHRhc2tsaXN0YCBjb3N0cyBvbiBhbiBpZGxlIGhvc3Q6IHRoaXMgcXVlcnlcbiAqIHJ1bnMgaW4gdGhlIHNhbWUgcG9zdC1ib290IGNvbnRlbnRpb24gd2luZG93IHRoYXQgaW5mbGF0ZXMgZXZlcnkgYGFkYmBcbiAqIHJvdW5kLXRyaXAgMjUtNTB4IChMNDUpLCBhbmQgYXMgYSB3aG9sZS1ob3N0IGxpc3RpbmcgaXQgd2FzIHRoZSBtb3N0XG4gKiBjb250ZW50aW9uLXNlbnNpdGl2ZSBjYWxsIHRoZSBoYXJuZXNzIG1hZGUgXHUyMDE0IGl0IHdhbGtlZCBldmVyeSBwcm9jZXNzIG9uIHRoZVxuICogaG9zdCwgc28gaXQgcGFpZCB0aGUgaG9zdCdzIHNsb3dkb3duIH41NDAgdGltZXMgb3Zlci5cbiAqXG4gKiBUaGUgdHdvIGVhcmxpZXIgbnVtYmVycyB3ZXJlIGJvdGggZ3Vlc3NlcywgYW5kIGJvdGggd2VyZSB0b28gc21hbGwuIDEwcyB3YXNcbiAqIG92ZXJydW4gb24gdGhlIGZpcnN0IGVuZC10by1lbmQgcnVuLiAzMHMgdGhlbiBmYWlsZWQgKipldmVyeSoqIEFuZHJvaWQgcnVuXG4gKiBmcm9tIG9uZSBob3N0IChtZWFzdXJlZCAyMDI2LTA5LTIwIGFjcm9zcyB0aHJlZSBydW5zIGFuZCB0d28gQVZEcyksIGVhY2ggdGltZVxuICoga2lsbGluZyB0aGUgY2hpbGQgYXQgfjMwcyB3aXRoIG5vdGhpbmcgb24gc3RkZXJyIFx1MjAxNCB0aGUgc2hhcGUgdGhhdCByZWFkcyBhcyBhblxuICogdW5leHBsYWluZWQgc3Bhd24gZmFpbHVyZSBhbmQgc2lsZW50bHkgZGlzYXJtcyB0aGUgZXNjYWxhdGlvbi5cbiAqXG4gKiBTbyB0aGlzIG9uZSBpcyBtZWFzdXJlZCBpbnN0ZWFkLiBUcmFjZWQgd2l0aCBubyBidWRnZXQgYXQgYWxsIGR1cmluZyBhblxuICogZW11bGF0b3IgYm9vdCBvbiB0aGF0IGhvc3QgKDIwMjYtMDktMjMsIG49NDApOiBwNTAgMi45cywgcDc1IDQuNHMsIHA5MCAxNy44cyxcbiAqIHA5NSAyOS4xcywgbWF4ICoqOTIuMnMqKi4gRXZlcnkgb25lIG9mIHRoZSA0MCBjb21wbGV0ZWQgdGhlIGZ1bGwgfjUzMC1yb3dcbiAqIGxpc3RpbmcgYW5kIGV4aXRlZCB3aXRoaW4gNTVtcyBvZiBpdHMgbGFzdCByb3csIHNvIG5vbmUgb2YgdGhlbSB3YXMgaHVuZyBcdTIwMTRcbiAqIHRoZSBjb3N0IGlzIHNwcmVhZCBhY3Jvc3MgdGhlIHJvd3MsIGluIDEuMC0yLjdzIHBhdXNlcyBvbiBpbmRpdmlkdWFsXG4gKiBwcm9jZXNzZXMuIDMwcyB0aGVyZWZvcmUgY3V0IG9mZiB0aGUgdG9wIDIuNSUgb2YgYSBkaXN0cmlidXRpb24gd2hvc2UgdGFpbFxuICogcmVhY2hlcyA5MnMsIGFuZCBhIHJlYWwgcnVuIFx1MjAxNCB3aGljaCBib290cyB0aGUgZW11bGF0b3IsIHN0YXJ0cyBBcHBpdW0sXG4gKiBpbnN0YWxscyB0aGUgYXBwIGFuZCBydW5zIFZpdGVzdCBhdCBvbmNlIFx1MjAxNCBpcyBtb3JlIGNvbnRlbmRlZCB0aGFuIHRoYXQgdHJhY2UuXG4gKlxuICogMTIwcyBpcyB+MS4zeCB0aGUgd29yc3Qgb2JzZXJ2ZWQgY2FsbCwgYW5kIGNvc3RzIG5vdGhpbmcgYXQgdGhlIG1lZGlhbi5cbiAqXG4gKiAqKlRoYXQgdGFpbCBiZWxvbmdlZCB0byB0aGUgd2hvbGUtaG9zdCBsaXN0aW5nLCB3aGljaCBXaW5kb3dzIG5vIGxvbmdlclxuICogbWFrZXMuKiogVGhlIHF1ZXJ5IGlzIG5vdyBmaWx0ZXJlZCB0byB0aGUgZW11bGF0b3IgaW1hZ2UgbmFtZXNcbiAqIChgYnVpbGRFbXVsYXRvclByb2Nlc3NRdWVyaWVzYCksIGFuZCB0aGUgZmlsdGVyZWQgY2FsbCBza2lwcyB0aGUgcGVyLXByb2Nlc3NcbiAqIHdvcmsgdGhlIHRhaWwgd2FzIG1hZGUgb2Y6IHdpdGggZXZlcnkgY29yZSBzYXR1cmF0ZWQgaXQgbmV2ZXIgZXhjZWVkZWQgNTA1bXNcbiAqIHdoZXJlIHRoZSB3aG9sZS1ob3N0IGNhbGwgc3RhbGxlZCBmb3IgMTIwLjlzLiBUaGUgYnVkZ2V0IHN0YXlzIGF0IDEyMHMgYXMgYVxuICogY2VpbGluZyByYXRoZXIgdGhhbiBhIGZvcmVjYXN0IFx1MjAxNCBpdCBjb3N0cyBub3RoaW5nIHdoZW4gdGhlIGNhbGwgaXMgZmFzdCwgYW5kXG4gKiBQT1NJWCBzdGlsbCBsaXN0cyB0aGUgd2hvbGUgaG9zdC4gSWYgYSBmaWx0ZXJlZCBjYWxsIGV2ZXIgb3ZlcnJ1bnMgaXQsIHRoZVxuICogbmV4dCBzdGVwIGlzIG5vdCBhIGZpZnRoIG51bWJlciBidXQgZGVyaXZpbmcgb3duZXJzaGlwIHdpdGhvdXQgYSBwcm9jZXNzXG4gKiBsaXN0aW5nIGF0IGFsbC5cbiAqL1xuZXhwb3J0IGNvbnN0IEhPU1RfUFJPQ0VTU19RVUVSWV9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEyMF8wMDA7XG5cbmNvbnN0IEVNVUxBVE9SX0VTQ0FMQVRFRF9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IEVNVUxBVE9SX1NUT1BfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMjBfMDAwO1xuY29uc3QgTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQgPSAxMDAwO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBFbXVsYXRvclJlY2xhaW1lci5yZWNsYWltTGVmdG92ZXJFbXVsYXRvcnN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyUmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzUGFyYW1zIHtcbiAgLyoqXG4gIEFuIEFWRCB3aG9zZSBsZWZ0b3ZlciBpcyBsZWZ0IGFsb25lIFx1MjAxNCB0aGUgb25lIGEgcHJlZmxpZ2h0IGlzIGFib3V0IHRvIGFkb3B0IGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBleGNlcHRBdmROYW1lPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBgJ3ByZWZsaWdodCdgIHNwYXJlcyBhbiBlbXVsYXRvciBhbm90aGVyIGxpdmUgaGFybmVzcyBwcm9jZXNzIHN0aWxsIG93bnMuXG4gICAqIGAnZW5kLW9mLXJ1bidgIGRvZXMgbm90OiB0aGUgY2FsbGVyIGhvbGRzIHRoZSBgYW5kcm9pZGAgbG9jayB3aXRoIG5vIHJ1biBpblxuICAgKiBmbGlnaHQgXHUyMDE0IHRoZSBydW4ncyBvd24gZ2xvYmFsIHRlYXJkb3duLCBvciB0aGUgZW11bGF0b3IgcmVhcGVyIGFmdGVyIHRoZVxuICAgKiBydW4gaXMgZ29uZSBcdTIwMTQgc28gdGhhdCBvd25lciBjYW4gb25seSBiZSBvbmUgb2YgdGhlIGZpbmlzaGVkIHJ1bidzXG4gICAqIHByb2Nlc3Nlcywgd2hpY2ggbm8gbG9uZ2VyIGhhcyBhIHR1cm4gdG8gc3RvcCBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHNjb3BlOiAnZW5kLW9mLXJ1bicgfCAncHJlZmxpZ2h0Jztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgRW11bGF0b3JSZWNsYWltZXIuc3RvcEVtdWxhdG9yfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lclN0b3BFbXVsYXRvclBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQVZEIG5hbWUsIG5hbWVkIGluIHRoZSB3YXJuaW5nIHNvIHRoZSBsZWZ0b3ZlciBpcyBpZGVudGlmaWFibGUsIGFuZCB0aGUga2V5IG9mIGl0cyBtYXJrZXIuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgdGhlIGVtdWxhdG9yIGlzIHNlcnZpbmcsIHNodXQgZG93biBvdmVyIGl0cyBjb25zb2xlIGFuZCBwb2xsZWRcbiAgICogdG8gZGVjaWRlIHdoZXRoZXIgaXQgYWN0dWFsbHkgc3RvcHBlZC4gYHVuZGVmaW5lZGAgd2hlbiB0aGUgZW11bGF0b3IgZmFpbGVkXG4gICAqIGJlZm9yZSBhbnkgZGV2aWNlIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBlbXVsYXRvciBsYXVuY2hlciBwcm9jZXNzIHRoaXMgcnVuIHNwYXduZWQuIGB1bmRlZmluZWRgIGZvciBhIGxlZnRvdmVyXG4gICAqIHRoaXMgcnVuIHRvb2sgb3Zlciwgd2hvc2UgbGF1bmNoZXIgYmVsb25nZWQgdG8gYW5vdGhlciBwcm9jZXNzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JQcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgUElEcyB0aGlzIHJ1biBvd25zLCBlc2NhbGF0ZWQgdG8gd2hlbiB0aGUgY29uc29sZSBhbmQgdGhlIGxhdW5jaGVyJ3MgdHJlZSBraWxsIGxlYXZlIG9uZSBiZWhpbmQuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKlxuICogQSBob3N0IGNvbW1hbmQgYW5kIGl0cyBhcmd1bWVudHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSG9zdENvbW1hbmRRdWVyeSB7XG4gIC8qKlxuICBUaGUgZXhlY3V0YWJsZSB0byBydW4uXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBjb21tYW5kJ3MgYXJndW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZEFyZ3VtZW50czogc3RyaW5nW107XG59XG5cbi8qKlxuICogRXZlcnl0aGluZyBvbmUgaG9zdCBwcm9jZXNzIGxpc3RpbmcgbGVmdCBiZWhpbmQsIGtlcHQgdG9nZXRoZXIgc28gdGhlXG4gKiBjbGFzc2lmaWNhdGlvbiBzZWVzIHRoZSB3aG9sZSBwaWN0dXJlLlxuICpcbiAqIGBleGVjRmlsZWAncyBjYWxsYmFjayBkaXNjYXJkcyBub3RoaW5nIGhlcmUgXHUyMDE0IG5vdCBzdGRlcnIsIGFuZCBub3QgYSAqZmFpbGVkKlxuICogY2FsbCdzIHBhcnRpYWwgc3Rkb3V0LiBUaGUgb2xkIGNvZGUga2VwdCBvbmx5IGBlcnJvci5tZXNzYWdlYCwgd2hpY2ggZm9yXG4gKiBgZXhlY0ZpbGVgIGlzIGBDb21tYW5kIGZhaWxlZDogPGNtZD5gIHBsdXMgc3RkZXJyLCBzbyBhIGtpbGxlZCBjaGlsZCAoZW1wdHlcbiAqIHN0ZGVycikgcHJvZHVjZWQgYSBsaW5lIG5hbWluZyB0aGUgY29tbWFuZCBhbmQgbm90aGluZyBlbHNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhvc3RQcm9jZXNzUXVlcnlSZXN1bHQge1xuICAvKipcbiAgYGV4ZWNGaWxlYCdzIGVycm9yLCBvciBgbnVsbGAgd2hlbiB0aGUgbGlzdGluZyBzdWNjZWVkZWQuXG4gICAqL1xuICByZWFkb25seSBlcnJvcjogRXhlY0ZpbGVFeGNlcHRpb24gfCBudWxsO1xuXG4gIC8qKlxuICBXaGF0ZXZlciB0aGUgY2hpbGQgd3JvdGUgdG8gc3RkZXJyLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhbmRhcmRFcnJvcjogc3RyaW5nO1xuXG4gIC8qKlxuICBXaGF0ZXZlciB0aGUgY2hpbGQgd3JvdGUgdG8gc3Rkb3V0IFx1MjAxNCBhIHBhcnRpYWwgbGlzdGluZyB3aGVuIHRoZSBjYWxsIGZhaWxlZCBwYXJ0LXdheS5cbiAgICovXG4gIHJlYWRvbmx5IHN0YW5kYXJkT3V0cHV0OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lckNoZWNrSXNFbXVsYXRvckdvbmVQYXJhbXMge1xuICAvKipcbiAgVGhlIGRldmljZSB0aGUgZW11bGF0b3Igc2VydmVzLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vbmUgZXZlciBhcHBlYXJlZCBcdTIwMTQgdGhlIFBJRHMgYXJlIHRoZW4gdGhlIG9ubHkgcHJvb2YuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIFBJRHMgdGhpcyBydW4gb3ducy5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyV2FpdEZvckVtdWxhdG9yU3RvcHBlZFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgZGV2aWNlIHRoZSBlbXVsYXRvciBzZXJ2ZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gbm9uZSBldmVyIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgLyoqXG4gIEhvdyBsb25nIHRvIHdhaXQgZm9yIHRoZSBlbXVsYXRvciB0byBkaXNhcHBlYXIsIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZpbmRzLCBzdG9wcyBhbmQgdmVyaWZpZXMgdGhlIGhhcm5lc3MncyBlbXVsYXRvcnMsIHJlcG9ydGluZyB0aHJvdWdoIHRoZVxuICogY2FsbGVyJ3MgbG9nIHNvIGVhY2ggY2FsbGVyIGtlZXBzIGl0cyBvd24gcHJlZml4LlxuICovXG5leHBvcnQgY2xhc3MgRW11bGF0b3JSZWNsYWltZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlY2xhaW1lciB0aGF0IHJlcG9ydHMgdW5kZXIgdGhlIGNhbGxlcidzIG93biBsb2cgcHJlZml4LlxuICAgKlxuICAgKiBAcGFyYW0gbG9nIC0gUmVjZWl2ZXMgZXZlcnkgcHJvZ3Jlc3MgYW5kIHZlcmRpY3QgbGluZS5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihsb2c6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGBhZGIgZGV2aWNlc2AgYW5kIHJldHVybnMgaXRzIHJhdyBzdGRvdXQuXG4gICAqXG4gICAqIFRoZSByYXcgbGlzdGluZyBpcyB3aGF0IHRlYXJkb3duIG5lZWRzOiBgZ2V0Q29ubmVjdGVkRGV2aWNlSWRzYCBrZWVwcyBvbmx5XG4gICAqIHRoZSBgZGV2aWNlYCBzdGF0ZSwgYW5kIGFuIGVtdWxhdG9yIG9uIGl0cyB3YXkgb3V0IGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlXG4gICAqIHN0aWxsIGhvbGRpbmcgdGhlIEFWRCBcdTIwMTQgc2VlIGBhZGItZGV2aWNlLWxpc3QudHNgLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgcmF3IGBhZGIgZGV2aWNlc2Agb3V0cHV0LlxuICAgKiBAdGhyb3dzIElmIGFkYiBjb3VsZCBub3QgYmUgcnVuIGF0IGFsbC5cbiAgICovXG4gIHB1YmxpYyBnZXREZXZpY2VzT3V0cHV0KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZXhlY0ZpbGUoJ2FkYicsIFsnZGV2aWNlcyddLCB7IHRpbWVvdXQ6IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSwgKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gcnVuICdhZGIgZGV2aWNlcyc6ICR7ZXJyb3IubWVzc2FnZX0uIElzIEFEQiBpbnN0YWxsZWQgYW5kIGluIFBBVEg/YCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RkZXJyKSB7XG4gICAgICAgICAgdGhpcy5sb2coYEFEQiBzdGRlcnI6ICR7c3RkZXJyLnRyaW0oKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHN0ZG91dCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyB0aGUgaG9zdCdzIGVtdWxhdG9yIHByb2Nlc3NlcyBcdTIwMTQgZXZlcnkgcHJvY2VzcyB3aG9zZSBpbWFnZSBuYW1lIGNvdWxkXG4gICAqIGJlIHRoZSBsYXVuY2hlciBvciBhIFFFTVUgYmFja2VuZCwgYW5kIG9uIFBPU0lYIGV2ZXJ5IHByb2Nlc3Mgb24gdGhlIGhvc3QuXG4gICAqXG4gICAqIE9uIFdpbmRvd3MgdGhpcyBpcyB0d28gKipmaWx0ZXJlZCoqIGB0YXNrbGlzdGAgY2FsbHMgcmF0aGVyIHRoYW4gb25lXG4gICAqIHdob2xlLWhvc3QgbGlzdGluZyAoYGJ1aWxkRW11bGF0b3JQcm9jZXNzUXVlcmllc2AgY2FycmllcyB0aGUgbWVhc3VyZW1lbnRcbiAgICogdGhhdCBtYWRlIHRoZSBzd2l0Y2gpLCBydW4gaW4gcGFyYWxsZWwuIEEgZmlsdGVyZWQgY2FsbCBtYXkgbGVnaXRpbWF0ZWx5XG4gICAqIGZpbmQgbm90aGluZywgYnV0IG9ubHkgd2hlbiBpdCBzYXlzIHNvOiBhIGNsZWFuIGV4aXQgd2l0aCBuZWl0aGVyIGEgcm93IG5vclxuICAgKiBgdGFza2xpc3RgJ3Mgb3duIG5vLW1hdGNoIG5vdGljZSBpcyBzdGlsbCBhIGZhaWxlZCBxdWVyeSwgYW5kIGNvbWVzIGJhY2sgYXNcbiAgICogYHVuZGVmaW5lZGAgZXhhY3RseSBsaWtlIG9uZSB0aGF0IGRpZCBub3QgcnVuIFx1MjAxNCBuZXZlciBhcyBhbiBlbXB0eSBsaXN0IGFcbiAgICogY2FsbGVyIGNvdWxkIHJlYWQgYXMgXCJubyBlbXVsYXRvciBpcyBydW5uaW5nXCIuXG4gICAqXG4gICAqIEVhY2ggZmFpbGVkIGNhbGwgbG9ncyAqKm9uZSoqIGxpbmUsIGZyb20gYGhvc3QtcHJvY2Vzcy1xdWVyeS12ZXJkaWN0LnRzYCxcbiAgICogbmFtaW5nIHdoaWNoIHdheSBpdCBmYWlsZWQuIFRoZSBwcmVkZWNlc3NvciBsb2dnZWQgdHdvIGNvbnRyYWRpY3Rvcnkgb25lc1xuICAgKiBmb3IgYSBzaW5nbGUgZmFpbHVyZSBcdTIwMTQgYGNvdWxkIG5vdCBsaXN0IGhvc3QgcHJvY2Vzc2VzYCBpbW1lZGlhdGVseSBmb2xsb3dlZFxuICAgKiBieSBgbGlzdGVkIG5vIHByb2Nlc3Nlc2AgXHUyMDE0IGJlY2F1c2UgYSBmYWlsZWQgY2FsbCByZXNvbHZlZCBgJydgLCB3aGljaCB0aGVuXG4gICAqIHBhcnNlZCB0byB6ZXJvIHJvd3MgYW5kIHRyaXBwZWQgdGhlIHplcm8tcm93IGNoZWNrIGFzIHdlbGwuXG4gICAqXG4gICAqICoqSWYgYW55IGNhbGwgZmFpbHMsIHRoZSB3aG9sZSBhbnN3ZXIgaXMgYHVuZGVmaW5lZGAqKiwgYW5kIGEgZmFpbGVkIGNhbGwnc1xuICAgKiBwYXJ0aWFsIHN0ZG91dCBpcyBwYXJzZWQgYnV0IG5ldmVyIHJldHVybmVkOiB0aGUgb3duZWQgUElEIHNldCBpcyB0aGVcbiAgICogZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBhbnN3ZXJzLCBzbyBhIGhhbGYgYW5zd2VyIFx1MjAxNCBvbmUgaW1hZ2UgbmFtZSdzXG4gICAqIHByb2Nlc3NlcyB3aXRob3V0IHRoZSBvdGhlcidzLCBvciBhIHRydW5jYXRlZCBsaXN0aW5nIFx1MjAxNCB3b3VsZCBib3RoIG1pc3MgYVxuICAgKiBwcm9jZXNzIHRoaXMgcnVuIG93bnMgYW5kIGNsYWltIG9uZSBpdCBkb2VzIG5vdCwgYW5kIGtpbGxpbmcgYSBwcm9jZXNzIHRoZVxuICAgKiBydW4gZG9lcyBub3Qgb3duIGlzIHRoZSBvbmUgdGhpbmcgKipMNDYqKiBmb3JiaWRzLiBUaGUgcm93IGNvdW50IGdvZXMgaW50b1xuICAgKiB0aGUgbG9nIGluc3RlYWQsIGFzIHRoZSBldmlkZW5jZSB0aGF0IHRoZSBjb21tYW5kIHdhcyB3b3JraW5nLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgaG9zdCdzIGVtdWxhdG9yIHByb2Nlc3Nlcywgb3IgYHVuZGVmaW5lZGAgd2hlbiBhIHF1ZXJ5IGZhaWxlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBxdWVyeUVtdWxhdG9yUHJvY2Vzc2VzKCk6IFByb21pc2U8UHJvY2Vzc0xpc3RFbnRyeVtdIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgYW5zd2VycyA9IGF3YWl0IFByb21pc2UuYWxsKGJ1aWxkRW11bGF0b3JQcm9jZXNzUXVlcmllcyhwcm9jZXNzLnBsYXRmb3JtKS5tYXAoKHF1ZXJ5KSA9PiB0aGlzLnJ1bkVtdWxhdG9yUHJvY2Vzc1F1ZXJ5KHF1ZXJ5KSkpO1xuICAgIGNvbnN0IHByb2Nlc3NlczogUHJvY2Vzc0xpc3RFbnRyeVtdID0gW107XG4gICAgZm9yIChjb25zdCBhbnN3ZXIgb2YgYW5zd2Vycykge1xuICAgICAgaWYgKGFuc3dlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBwcm9jZXNzZXMucHVzaCguLi5hbnN3ZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9jZXNzZXM7XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgdGhlIGVtdWxhdG9ycyB0aGlzIGhhcm5lc3Mgc3RhcnRlZCB0aGF0IG5vIGxpdmUgcnVuIGlzIHJlc3BvbnNpYmxlXG4gICAqIGZvciwgYW5kIGRyb3BzIHRoZSBtYXJrZXJzIHRoYXQgbm8gbG9uZ2VyIGRlc2NyaWJlIGEgcnVubmluZyBlbXVsYXRvci5cbiAgICpcbiAgICogT25seSBldmVyIGFjdHMgb24gYSAqKm1hcmtlci12ZXJpZmllZCoqIGVtdWxhdG9yOiBvbmUgd2hvc2UgbWFya2VyIG5hbWVzIGFcbiAgICogUElEIHRoYXQgaXMgc3RpbGwgYSBsaXZlIGVtdWxhdG9yIHByb2Nlc3MuIEFuIGVtdWxhdG9yIHdpdGhvdXQgYSBtYXJrZXIgXHUyMDE0XG4gICAqIGJvb3RlZCBieSBoYW5kLCBieSBDSSwgb3IgYnkgYW5vdGhlciB0b29sIFx1MjAxNCBpcyBuZXZlciB0b3VjaGVkLCB3aGljaCBrZWVwc1xuICAgKiB0aGUgTDQ2IGxpbmU6IG5ldmVyIGEgYHFlbXUqYCBzd2VlcC5cbiAgICpcbiAgICogQ2FsbGVycyBtdXN0IGhvbGQgdGhlIGBhbmRyb2lkYCBzZXR1cCBsb2NrIChMNyksIHdoaWNoIGlzIHdoYXQgbWFrZXMgYVxuICAgKiBsZWZ0b3ZlciBzYWZlIHRvIHN0b3A6IG5vIG90aGVyIEFuZHJvaWQgcnVuIGNhbiBiZSBtaWQtZmxpZ2h0IG9uIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gV2hpY2ggQVZEIHRvIGxlYXZlIGFsb25lLCBhbmQgd2hldGhlciB0aGlzIHJ1biBpcyBlbmRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJSZWNsYWltTGVmdG92ZXJFbXVsYXRvcnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYXJrZXJzID0gbGlzdEVtdWxhdG9yTWFya2VycygpLmZpbHRlcigobWFya2VyKSA9PiBtYXJrZXIuYXZkTmFtZSAhPT0gcGFyYW1zLmV4Y2VwdEF2ZE5hbWUpO1xuICAgIGlmIChtYXJrZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IGF3YWl0IHRoaXMucXVlcnlFbXVsYXRvclByb2Nlc3NlcygpO1xuICAgIGlmIChwcm9jZXNzZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gV2l0aG91dCBhIGxpc3RpbmcgZXZlcnkgbWFya2VyIHdvdWxkIHJlYWQgYXMgc3RhbGUsIGFuZCBkZWxldGluZyB0aGVtIHdvdWxkIGxlYXZlIHRoZSBsZWZ0b3ZlcnMgaW1wb3NzaWJsZSB0byBjb252aWN0LlxuICAgICAgdGhpcy5sb2coYENhbm5vdCBqdWRnZSAke1N0cmluZyhtYXJrZXJzLmxlbmd0aCl9IGVtdWxhdG9yIG1hcmtlcihzKSB3aXRob3V0IGEgaG9zdCBwcm9jZXNzIGxpc3Rpbmc7IGxlYXZpbmcgdGhlbSBmb3IgYSBsYXRlciBydW4uYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbGl2ZUVtdWxhdG9yUGlkcyA9IHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHMoeyBrbm93blBpZHM6IFtdLCBwcm9jZXNzZXMgfSk7XG4gICAgZm9yIChjb25zdCBtYXJrZXIgb2YgbWFya2Vycykge1xuICAgICAgYXdhaXQgdGhpcy5yZWNsYWltTGVmdG92ZXJFbXVsYXRvcihtYXJrZXIsIGxpdmVFbXVsYXRvclBpZHMsIHBhcmFtcy5zY29wZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0b3BzIGFuIGVtdWxhdG9yIHRoaXMgaGFybmVzcyBvd25zLCBhbmQgKip2ZXJpZmllcyoqIGl0IHN0b3BwZWQuXG4gICAqXG4gICAqIFRoZSBjb25zb2xlIHNodXRkb3duIGdvZXMgZmlyc3QgYmVjYXVzZSBpdCBpcyB0aGUgb25seSBwYXRoIHRoYXQgcmVsZWFzZXNcbiAgICogdGhlIEFWRCdzIGBtdWx0aWluc3RhbmNlLmxvY2tgOyBhIGB0YXNra2lsbGAgbGVhdmVzIHRoZSBsb2NrIGJlaGluZCwgYW5kIGFcbiAgICogc3RhbGUgbG9jayBpcyB3aGF0IG1ha2VzIHRoZSBuZXh0IHJ1biBmYWlsIHdpdGggYFJ1bm5pbmcgbXVsdGlwbGUgZW11bGF0b3JzXG4gICAqIHdpdGggdGhlIHNhbWUgQVZEYCBcdTIwMTQgYSBGQVRBTCB0aGUgZW11bGF0b3Igd3JpdGVzIHRvIGl0cyBvd24gc3Rkb3V0LCB3aGVyZVxuICAgKiBub2JvZHkgc2VlcyBpdC5cbiAgICpcbiAgICogV29ya3Mgd2l0aG91dCBhIGxhdW5jaGVyIGhhbmRsZSB0b286IGEgbGVmdG92ZXIgdGhpcyBydW4gdG9vayBvdmVyIGhhcyBvbmx5XG4gICAqIGl0cyBQSURzLCB3aGljaCBpcyBhbGwgdGhlIGVzY2FsYXRpb24gYmVsb3cgZXZlciBuZWVkZWQuIFRoZSBtYXJrZXIgZ29lc1xuICAgKiBvbmx5IHdpdGggYSAqKnZlcmlmaWVkKiogc3RvcCwgc28gYW4gZW11bGF0b3IgdGhhdCBvdXRsaXZlZCB0aGlzIGF0dGVtcHRcbiAgICogc3RheXMgY29udmljdGFibGUgYnkgdGhlIG5leHQgb25lLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVtdWxhdG9yIHByb2Nlc3MsIHRoZSBkZXZpY2UgaXQgc2VydmVzIGFuZCB0aGUgUElEcyB0aGlzIHJ1biBvd25zLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHN0b3BFbXVsYXRvcihwYXJhbXM6IEVtdWxhdG9yUmVjbGFpbWVyU3RvcEVtdWxhdG9yUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHBhcmFtcy5kZXZpY2VJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmtpbGxFbXVsYXRvckNvbnNvbGUocGFyYW1zLmRldmljZUlkKTtcbiAgICB9XG4gICAgaWYgKHBhcmFtcy5lbXVsYXRvclByb2Nlc3MpIHtcbiAgICAgIGtpbGxQcm9jZXNzVHJlZShwYXJhbXMuZW11bGF0b3JQcm9jZXNzKTtcbiAgICB9XG5cbiAgICBjb25zdCB3YWl0UGFyYW1zOiBFbXVsYXRvclJlY2xhaW1lcldhaXRGb3JFbXVsYXRvclN0b3BwZWRQYXJhbXMgPSB7XG4gICAgICBkZXZpY2VJZDogcGFyYW1zLmRldmljZUlkLFxuICAgICAgb3duZWRFbXVsYXRvclBpZHM6IHBhcmFtcy5vd25lZEVtdWxhdG9yUGlkcyxcbiAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogRU1VTEFUT1JfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH07XG5cbiAgICBsZXQgaGFzRXNjYWxhdGVkID0gZmFsc2U7XG4gICAgbGV0IGlzU3RvcHBlZCA9IGF3YWl0IHRoaXMud2FpdEZvckVtdWxhdG9yU3RvcHBlZCh3YWl0UGFyYW1zKTtcblxuICAgIGlmICghaXNTdG9wcGVkKSB7XG4gICAgICBjb25zdCBzdXJ2aXZpbmdQaWRzID0gcGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLmZpbHRlcigocGlkKSA9PiBjaGVja0lzUHJvY2Vzc0FsaXZlKHBpZCkpO1xuICAgICAgaWYgKHN1cnZpdmluZ1BpZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBoYXNFc2NhbGF0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICBgQXV0by1zdGFydGVkIGVtdWxhdG9yIG91dGxpdmVkIGl0cyBjb25zb2xlIHNodXRkb3duIGFuZCB0aGUgbGF1bmNoZXIncyBwcm9jZXNzIHRyZWU7IGVzY2FsYXRpbmcgdG8gdGhlIGVtdWxhdG9yIFBJRChzKSB0aGlzIHJ1biBvd25zOiBbJHtzdXJ2aXZpbmdQaWRzLmpvaW4oJywgJyl9XS5gXG4gICAgICAgICk7XG4gICAgICAgIGZvciAoY29uc3QgcGlkIG9mIHN1cnZpdmluZ1BpZHMpIHtcbiAgICAgICAgICBraWxsUHJvY2Vzc1RyZWVCeVBpZChwaWQpO1xuICAgICAgICB9XG4gICAgICAgIGlzU3RvcHBlZCA9IGF3YWl0IHRoaXMud2FpdEZvckVtdWxhdG9yU3RvcHBlZCh7IC4uLndhaXRQYXJhbXMsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogRU1VTEFUT1JfRVNDQUxBVEVEX1NUT1BfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYnVpbGRUZWFyZG93bk1lc3NhZ2Uoe1xuICAgICAgZXZpZGVuY2U6IHBhcmFtcy5kZXZpY2VJZCA9PT0gdW5kZWZpbmVkID8gYEFWRCBcIiR7cGFyYW1zLmF2ZE5hbWV9XCJgIDogYEFWRCBcIiR7cGFyYW1zLmF2ZE5hbWV9XCIgb24gZGV2aWNlICR7cGFyYW1zLmRldmljZUlkfWAsXG4gICAgICBvdXRjb21lOiByZXNvbHZlVGVhcmRvd25PdXRjb21lKHsgaGFzRXNjYWxhdGVkLCBpc1N0b3BwZWQgfSksXG4gICAgICBzdWJqZWN0OiAnQXV0by1zdGFydGVkIGVtdWxhdG9yJyxcbiAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogRU1VTEFUT1JfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH0pKTtcblxuICAgIGlmIChpc1N0b3BwZWQpIHtcbiAgICAgIGNsZWFyRW11bGF0b3JNYXJrZXJJZlN0b3BwZWQocGFyYW1zLmF2ZE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNpZGVzIHdoZXRoZXIgdGhlIGVtdWxhdG9yIHRoaXMgcnVuIHN0YXJ0ZWQgaXMgcmVhbGx5IGdvbmUuXG4gICAqXG4gICAqIFR3byBpbmRlcGVuZGVudCBwcm9vZnMsIGNoZWFwZXN0IGZpcnN0OiBub25lIG9mIHRoZSBQSURzIHRoaXMgcnVuIG93bnMgaXNcbiAgICogYWxpdmUsIGFuZCB0aGUgZGV2aWNlIG5vIGxvbmdlciBhcHBlYXJzIGluIGBhZGIgZGV2aWNlc2AgKippbiBhbnkgc3RhdGUqKiAoYVxuICAgKiBkeWluZyBlbXVsYXRvciBhbnN3ZXJzIGBvZmZsaW5lYCB3aGlsZSBpdCBzdGlsbCBob2xkcyB0aGUgQVZEKS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBkZXZpY2UgYW5kIHRoZSBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIG5vdGhpbmcgb2YgdGhpcyBydW4ncyBlbXVsYXRvciBpcyBsZWZ0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0lzRW11bGF0b3JHb25lKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJDaGVja0lzRW11bGF0b3JHb25lUGFyYW1zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHBhcmFtcy5vd25lZEVtdWxhdG9yUGlkcy5zb21lKChwaWQpID0+IGNoZWNrSXNQcm9jZXNzQWxpdmUocGlkKSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmRldmljZUlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gIWNoZWNrSXNEZXZpY2VMaXN0ZWQoeyBkZXZpY2VJZDogcGFyYW1zLmRldmljZUlkLCBkZXZpY2VzT3V0cHV0OiBhd2FpdCB0aGlzLmdldERldmljZXNPdXRwdXQoKSB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgLypcbiAgICAgICAqIEFuIGFkYiB0aGF0IGNhbm5vdCBydW4gaXMgbm90IGV2aWRlbmNlIGFib3V0IHRoZSBlbXVsYXRvciBcdTIwMTQgYW5kIHRoZSBQSURcbiAgICAgICAqIHByb2JlIGFib3ZlIGhhcyBhbHJlYWR5IHNhaWQgdGhpcyBydW4ncyBwcm9jZXNzZXMgYXJlIGdvbmUsIHdoaWNoIGlzIHRoZVxuICAgICAgICogc3Ryb25nZXIgb2YgdGhlIHR3byBwcm9vZnMuXG4gICAgICAgKi9cbiAgICAgIHRoaXMubG9nKGBDb3VsZCBub3QgcmUtY2hlY2sgY29ubmVjdGVkIGRldmljZXMgd2hpbGUgc3RvcHBpbmcgdGhlIGVtdWxhdG9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBc2tzIHRoZSBlbXVsYXRvciB0byBzaHV0IGl0c2VsZiBkb3duIG92ZXIgaXRzIGNvbnNvbGUuXG4gICAqXG4gICAqIFByZWZlcnJlZCBvdmVyIGtpbGxpbmcgdGhlIHByb2Nlc3Mgb3V0cmlnaHQgYmVjYXVzZSBpdCBpcyB0aGUgcGF0aCB0aGF0XG4gICAqIHJlbGVhc2VzIHRoZSBBVkQncyBgbXVsdGlpbnN0YW5jZS5sb2NrYC4gQmVzdC1lZmZvcnQ6IGEgY29uc29sZSB0aGF0IGRvZXNcbiAgICogbm90IGFuc3dlciBpcyByZXBvcnRlZCBhbmQgdGhlIGNhbGxlciBmYWxscyB0aHJvdWdoIHRvIHRoZSBraWxsLlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgZW11bGF0b3IncyBkZXZpY2UgSUQuXG4gICAqL1xuICBwcml2YXRlIGtpbGxFbXVsYXRvckNvbnNvbGUoZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoJ2FkYicsIFsnLXMnLCBkZXZpY2VJZCwgJ2VtdScsICdraWxsJ10sIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LCAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgPyBgRW11bGF0b3IgY29uc29sZSBzaHV0ZG93biBmb3IgJHtkZXZpY2VJZH0gZGlkIG5vdCBhbnN3ZXI6ICR7ZXJyb3IubWVzc2FnZX1gXG4gICAgICAgICAgICA6IGBFbXVsYXRvciBjb25zb2xlIHNodXRkb3duIGZvciAke2RldmljZUlkfTogJHtzdGRvdXQudHJpbSgpfWBcbiAgICAgICAgKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWN0cyBvbiBvbmUgZW11bGF0b3IgbWFya2VyIGZvciB7QGxpbmsgcmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzfS5cbiAgICpcbiAgICogQHBhcmFtIG1hcmtlciAtIFRoZSBtYXJrZXIgdG8ganVkZ2UuXG4gICAqIEBwYXJhbSBsaXZlRW11bGF0b3JQaWRzIC0gVGhlIGVtdWxhdG9yIHByb2Nlc3NlcyBjdXJyZW50bHkgcnVubmluZyBvbiB0aGUgaG9zdC5cbiAgICogQHBhcmFtIHNjb3BlIC0gV2hldGhlciBhbiBlbXVsYXRvciBhbm90aGVyIGxpdmUgaGFybmVzcyBwcm9jZXNzIG93bnMgaXMgc3BhcmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWNsYWltTGVmdG92ZXJFbXVsYXRvcihtYXJrZXI6IEVtdWxhdG9yTWFya2VyLCBsaXZlRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXSwgc2NvcGU6IEVtdWxhdG9yUmVjbGFpbWVyUmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzUGFyYW1zWydzY29wZSddKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdmVyZGljdCA9IHJlc29sdmVFbXVsYXRvck1hcmtlclZlcmRpY3Qoe1xuICAgICAgY3VycmVudFBpZDogcHJvY2Vzcy5waWQsXG4gICAgICBpc093bmVyQWxpdmU6IGNoZWNrSXNQcm9jZXNzQWxpdmUobWFya2VyLm93bmVyUGlkKSxcbiAgICAgIGxpdmVFbXVsYXRvclBpZHMsXG4gICAgICBtYXJrZXJcbiAgICB9KTtcblxuICAgIGlmICh2ZXJkaWN0ID09PSAnc3RhbGUtbWFya2VyJykge1xuICAgICAgdGhpcy5sb2coYERyb3BwaW5nIHRoZSBlbXVsYXRvciBtYXJrZXIgZm9yIEFWRCBcIiR7bWFya2VyLmF2ZE5hbWV9XCI6IG5vbmUgb2YgaXRzIFBJRHMgWyR7bWFya2VyLm93bmVkRW11bGF0b3JQaWRzLmpvaW4oJywgJyl9XSBpcyBhIHJ1bm5pbmcgZW11bGF0b3IgYW55IG1vcmUuYCk7XG4gICAgICBjbGVhckVtdWxhdG9yTWFya2VyKG1hcmtlci5hdmROYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIEEgbWFya2VyIHdyaXR0ZW4gYXQgbGF1bmNoIGhhcyBubyBkZXZpY2UgeWV0OiB0aGUgZW11bGF0b3Igd2FzIHN0aWxsXG4gICAgICogYm9vdGluZyB3aGVuIHdoYXRldmVyIHJlY29yZGVkIGl0IHN0b3BwZWQgbG9va2luZy4gVGhlIHN0b3AgYmVsb3cgcmVhZHNcbiAgICAgKiB0aGF0IGFic2VuY2UgY29ycmVjdGx5IFx1MjAxNCBubyBjb25zb2xlIHRvIHNodXQgZG93biwgdGhlIG93bmVkIFBJRHMgYXJlIHRoZVxuICAgICAqIHdob2xlIG9mIHRoZSBldmlkZW5jZSBcdTIwMTQgc28gaXQgaXMgZGVzY3JpYmVkIHJhdGhlciB0aGFuIHBhcGVyZWQgb3Zlci5cbiAgICAgKi9cbiAgICBjb25zdCBldmlkZW5jZSA9IGRlc2NyaWJlTWFya2VkRW11bGF0b3IobWFya2VyKTtcblxuICAgIGlmICh2ZXJkaWN0ID09PSAnaW4tdXNlLWJ5LWxpdmUtcnVuJyAmJiBzY29wZSA9PT0gJ3ByZWZsaWdodCcpIHtcbiAgICAgIHRoaXMubG9nKGBMZWF2aW5nIHRoZSBlbXVsYXRvciBmb3IgJHtldmlkZW5jZX0gYWxvbmU6IHRoZSBoYXJuZXNzIHByb2Nlc3MgdGhhdCBvd25zIGl0IChQSUQgJHtTdHJpbmcobWFya2VyLm93bmVyUGlkKX0pIGlzIHN0aWxsIHJ1bm5pbmcuYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYWdlSW5TZWNvbmRzID0gTWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIG1hcmtlci5zdGFydGVkQXRJbk1pbGxpc2Vjb25kcykgLyBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORCk7XG4gICAgdGhpcy5sb2coXG4gICAgICBgU3RvcHBpbmcgdGhlIGVtdWxhdG9yIGZvciAke2V2aWRlbmNlfTogdGhpcyBoYXJuZXNzIHN0YXJ0ZWQgaXQgJHtTdHJpbmcoYWdlSW5TZWNvbmRzKX1zIGFnbywgYW5kIG5vIGxpdmUgcnVuIGlzIGxlZnQgdG8gc3RvcCBpdC5gXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLnN0b3BFbXVsYXRvcih7XG4gICAgICBhdmROYW1lOiBtYXJrZXIuYXZkTmFtZSxcbiAgICAgIGRldmljZUlkOiBtYXJrZXIuZGV2aWNlSWQsXG4gICAgICBvd25lZEVtdWxhdG9yUGlkczogc2VsZWN0TGl2ZU1hcmtlZFBpZHMobWFya2VyLCBsaXZlRW11bGF0b3JQaWRzKVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgb25lIG9mIHRoZSBlbXVsYXRvciBwcm9jZXNzIHF1ZXJpZXMgYW5kIGNsYXNzaWZpZXMgaG93IGl0IGVuZGVkLlxuICAgKlxuICAgKiBAcGFyYW0gcXVlcnkgLSBUaGUgcXVlcnkuXG4gICAqIEByZXR1cm5zIEl0cyBwYXJzZWQgcm93cywgb3IgYHVuZGVmaW5lZGAgd2hlbiBpdCBmYWlsZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJ1bkVtdWxhdG9yUHJvY2Vzc1F1ZXJ5KHF1ZXJ5OiBFbXVsYXRvclByb2Nlc3NRdWVyeSk6IFByb21pc2U8UHJvY2Vzc0xpc3RFbnRyeVtdIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3Qgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG5ldyBQcm9taXNlPEhvc3RQcm9jZXNzUXVlcnlSZXN1bHQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgcXVlcnkuY29tbWFuZCxcbiAgICAgICAgWy4uLnF1ZXJ5LmNvbW1hbmRBcmd1bWVudHNdLFxuICAgICAgICB7IG1heEJ1ZmZlcjogQURCX0RVTVBTWVNfTUFYX0JVRkZFUl9JTl9CWVRFUywgdGltZW91dDogSE9TVF9QUk9DRVNTX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sXG4gICAgICAgIChlcnJvciwgc3Rkb3V0LCBzdGRlcnIpID0+IHtcbiAgICAgICAgICByZXNvbHZlKHsgZXJyb3IsIHN0YW5kYXJkRXJyb3I6IHN0ZGVyciwgc3RhbmRhcmRPdXRwdXQ6IHN0ZG91dCB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IHBhcnNlRW11bGF0b3JQcm9jZXNzUXVlcnlPdXRwdXQoeyBvdXRwdXQ6IHJlc3VsdC5zdGFuZGFyZE91dHB1dCwgcXVlcnkgfSk7XG4gICAgY29uc3Qgb3V0Y29tZSA9IHJlc29sdmVIb3N0UHJvY2Vzc1F1ZXJ5T3V0Y29tZSh7XG4gICAgICBlcnJvckNvZGU6IHJlc3VsdC5lcnJvcj8uY29kZSA/PyBudWxsLFxuICAgICAgaGFzRmFpbGVkOiByZXN1bHQuZXJyb3IgIT09IG51bGwsXG4gICAgICBoYXNSZXBvcnRlZE5vTWF0Y2g6IGNoZWNrSXNOb01hdGNoUmVwb3J0ZWQoeyBvdXRwdXQ6IHJlc3VsdC5zdGFuZGFyZE91dHB1dCwgcXVlcnkgfSksXG4gICAgICBpc0tpbGxlZDogcmVzdWx0LmVycm9yPy5raWxsZWQgPz8gZmFsc2UsXG4gICAgICByb3dDb3VudDogcHJvY2Vzc2VzLmxlbmd0aCxcbiAgICAgIHN0YW5kYXJkRXJyb3I6IHJlc3VsdC5zdGFuZGFyZEVycm9yXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXNzYWdlID0gYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5TWVzc2FnZSh7XG4gICAgICBjb21tYW5kOiBbcXVlcnkuY29tbWFuZCwgLi4ucXVlcnkuY29tbWFuZEFyZ3VtZW50c10uam9pbignICcpLFxuICAgICAgZWxhcHNlZEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMsXG4gICAgICBleGl0Q29kZTogdHlwZW9mIHJlc3VsdC5lcnJvcj8uY29kZSA9PT0gJ251bWJlcicgPyByZXN1bHQuZXJyb3IuY29kZSA6IG51bGwsXG4gICAgICBvdXRjb21lLFxuICAgICAgcGFydGlhbFJvd0NvdW50OiBwcm9jZXNzZXMubGVuZ3RoLFxuICAgICAgc2lnbmFsOiByZXN1bHQuZXJyb3I/LnNpZ25hbCA/PyBudWxsLFxuICAgICAgc3RhbmRhcmRFcnJvcjogcmVzdWx0LnN0YW5kYXJkRXJyb3IsXG4gICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEhPU1RfUFJPQ0VTU19RVUVSWV9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH0pO1xuICAgIGlmIChtZXNzYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nKG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRjb21lID09PSAnbGlzdGVkJyA/IHByb2Nlc3NlcyA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB1bnRpbCB0aGlzIHJ1bidzIGVtdWxhdG9yIGlzIGdvbmUsIG9yIHRoZSBidWRnZXQgZWxhcHNlcy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBkZXZpY2UsIHRoZSBQSURzIHRoaXMgcnVuIG93bnMsIGFuZCB0aGUgYnVkZ2V0LlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgZW11bGF0b3IgZGlzYXBwZWFyZWQgd2l0aGluIHRoZSBidWRnZXQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JFbXVsYXRvclN0b3BwZWQocGFyYW1zOiBFbXVsYXRvclJlY2xhaW1lcldhaXRGb3JFbXVsYXRvclN0b3BwZWRQYXJhbXMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBwYXJhbXMudGltZW91dEluTWlsbGlzZWNvbmRzO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgaWYgKGF3YWl0IHRoaXMuY2hlY2tJc0VtdWxhdG9yR29uZShwYXJhbXMpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEVNVUxBVE9SX1NUT1BfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogTmFtZXMgdGhlIGVtdWxhdG9yIGEgbWFya2VyIGRlc2NyaWJlcywgZm9yIHRoZSBsb2cuXG4gKlxuICogQHBhcmFtIG1hcmtlciAtIFRoZSBtYXJrZXIuXG4gKiBAcmV0dXJucyBUaGUgQVZEIGFuZCBpdHMgZGV2aWNlLCBvciB0aGUgQVZEIGFsb25lIGZvciBhIGxhdW5jaCB0aGF0IGhhZCBub3QgcHJvZHVjZWQgYSBkZXZpY2UgeWV0LlxuICovXG5mdW5jdGlvbiBkZXNjcmliZU1hcmtlZEVtdWxhdG9yKG1hcmtlcjogRW11bGF0b3JNYXJrZXIpOiBzdHJpbmcge1xuICByZXR1cm4gbWFya2VyLmRldmljZUlkID09PSB1bmRlZmluZWRcbiAgICA/IGBBVkQgXCIke21hcmtlci5hdmROYW1lfVwiIChubyBkZXZpY2U6IGl0IHdhcyBzdGlsbCBib290aW5nIHdoZW4gaXQgd2FzIHJlY29yZGVkKWBcbiAgICA6IGBBVkQgXCIke21hcmtlci5hdmROYW1lfVwiIG9uIGRldmljZSAke21hcmtlci5kZXZpY2VJZH1gO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFzQkEsZ0NBQXlCO0FBQ3pCLDBCQUFvQjtBQVFwQiw2QkFBb0M7QUFDcEMsOEJBS087QUFDUCw2QkFNTztBQUNQLHdDQUdPO0FBQ1AsK0JBR087QUFDUCw4QkFBb0M7QUFDcEMsOEJBR087QUFLQSxNQUFNLDJDQUEyQztBQVFqRCxNQUFNLGtDQUFrQztBQW9DeEMsTUFBTSw2Q0FBNkM7QUFFMUQsTUFBTSxrREFBa0Q7QUFDeEQsTUFBTSw4Q0FBOEM7QUFDcEQsTUFBTSx3Q0FBd0M7QUFDOUMsTUFBTSwwQkFBMEI7QUEySHpCLE1BQU0sa0JBQWtCO0FBQUEsRUFDWjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9WLFlBQVksS0FBZ0M7QUFDakQsU0FBSyxNQUFNO0FBQUEsRUFDYjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFZTyxtQkFBb0M7QUFDekMsV0FBTyxJQUFJLFFBQWdCLENBQUMsU0FBUyxXQUFXO0FBQzlDLDhDQUFTLE9BQU8sQ0FBQyxTQUFTLEdBQUcsRUFBRSxTQUFTLHlDQUF5QyxHQUFHLENBQUMsT0FBTyxRQUFRLFdBQVc7QUFDN0csWUFBSSxPQUFPO0FBQ1QsaUJBQU8sSUFBSSxNQUFNLGdDQUFnQyxNQUFNLE9BQU8saUNB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
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
* `OBSIDIAN_METADATA` global — which the factory's import graph reaches —
|
|
13
13
|
* cannot load at all. So nothing this module imports may reach it either.
|
|
14
14
|
*/
|
|
15
|
-
import type { ChildProcess } from 'node:child_process';
|
|
15
|
+
import type { ChildProcess, ExecFileException } from 'node:child_process';
|
|
16
16
|
import type { ProcessListEntry } from './emulator-backend.cjs';
|
|
17
17
|
/**
|
|
18
18
|
* Budget for one quick `adb` call — `adb devices`, a console command.
|
|
19
19
|
*/
|
|
20
20
|
export declare const ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS = 5000;
|
|
21
21
|
export declare const ADB_DUMPSYS_MAX_BUFFER_IN_BYTES = 8388608;
|
|
22
|
-
export declare const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS =
|
|
22
|
+
export declare const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS = 120000;
|
|
23
23
|
/**
|
|
24
24
|
* Parameters for {@link EmulatorReclaimer.reclaimLeftoverEmulators}.
|
|
25
25
|
*/
|
|
@@ -74,6 +74,29 @@ export interface HostCommandQuery {
|
|
|
74
74
|
*/
|
|
75
75
|
readonly commandArguments: string[];
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Everything one host process listing left behind, kept together so the
|
|
79
|
+
* classification sees the whole picture.
|
|
80
|
+
*
|
|
81
|
+
* `execFile`'s callback discards nothing here — not stderr, and not a *failed*
|
|
82
|
+
* call's partial stdout. The old code kept only `error.message`, which for
|
|
83
|
+
* `execFile` is `Command failed: <cmd>` plus stderr, so a killed child (empty
|
|
84
|
+
* stderr) produced a line naming the command and nothing else.
|
|
85
|
+
*/
|
|
86
|
+
export interface HostProcessQueryResult {
|
|
87
|
+
/**
|
|
88
|
+
`execFile`'s error, or `null` when the listing succeeded.
|
|
89
|
+
*/
|
|
90
|
+
readonly error: ExecFileException | null;
|
|
91
|
+
/**
|
|
92
|
+
Whatever the child wrote to stderr.
|
|
93
|
+
*/
|
|
94
|
+
readonly standardError: string;
|
|
95
|
+
/**
|
|
96
|
+
Whatever the child wrote to stdout — a partial listing when the call failed part-way.
|
|
97
|
+
*/
|
|
98
|
+
readonly standardOutput: string;
|
|
99
|
+
}
|
|
77
100
|
/**
|
|
78
101
|
* Finds, stops and verifies the harness's emulators, reporting through the
|
|
79
102
|
* caller's log so each caller keeps its own prefix.
|
|
@@ -98,16 +121,34 @@ export declare class EmulatorReclaimer {
|
|
|
98
121
|
*/
|
|
99
122
|
getDevicesOutput(): Promise<string>;
|
|
100
123
|
/**
|
|
101
|
-
* Lists every process
|
|
124
|
+
* Lists the host's emulator processes — every process whose image name could
|
|
125
|
+
* be the launcher or a QEMU backend, and on POSIX every process on the host.
|
|
126
|
+
*
|
|
127
|
+
* On Windows this is two **filtered** `tasklist` calls rather than one
|
|
128
|
+
* whole-host listing (`buildEmulatorProcessQueries` carries the measurement
|
|
129
|
+
* that made the switch), run in parallel. A filtered call may legitimately
|
|
130
|
+
* find nothing, but only when it says so: a clean exit with neither a row nor
|
|
131
|
+
* `tasklist`'s own no-match notice is still a failed query, and comes back as
|
|
132
|
+
* `undefined` exactly like one that did not run — never as an empty list a
|
|
133
|
+
* caller could read as "no emulator is running".
|
|
134
|
+
*
|
|
135
|
+
* Each failed call logs **one** line, from `host-process-query-verdict.ts`,
|
|
136
|
+
* naming which way it failed. The predecessor logged two contradictory ones
|
|
137
|
+
* for a single failure — `could not list host processes` immediately followed
|
|
138
|
+
* by `listed no processes` — because a failed call resolved `''`, which then
|
|
139
|
+
* parsed to zero rows and tripped the zero-row check as well.
|
|
102
140
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
141
|
+
* **If any call fails, the whole answer is `undefined`**, and a failed call's
|
|
142
|
+
* partial stdout is parsed but never returned: the owned PID set is the
|
|
143
|
+
* difference between two answers, so a half answer — one image name's
|
|
144
|
+
* processes without the other's, or a truncated listing — would both miss a
|
|
145
|
+
* process this run owns and claim one it does not, and killing a process the
|
|
146
|
+
* run does not own is the one thing **L46** forbids. The row count goes into
|
|
147
|
+
* the log instead, as the evidence that the command was working.
|
|
107
148
|
*
|
|
108
|
-
* @returns The host's processes, or `undefined` when
|
|
149
|
+
* @returns The host's emulator processes, or `undefined` when a query failed.
|
|
109
150
|
*/
|
|
110
|
-
|
|
151
|
+
queryEmulatorProcesses(): Promise<ProcessListEntry[] | undefined>;
|
|
111
152
|
/**
|
|
112
153
|
* Stops the emulators this harness started that no live run is responsible
|
|
113
154
|
* for, and drops the markers that no longer describe a running emulator.
|
|
@@ -169,6 +210,13 @@ export declare class EmulatorReclaimer {
|
|
|
169
210
|
* @param scope - Whether an emulator another live harness process owns is spared.
|
|
170
211
|
*/
|
|
171
212
|
private reclaimLeftoverEmulator;
|
|
213
|
+
/**
|
|
214
|
+
* Runs one of the emulator process queries and classifies how it ended.
|
|
215
|
+
*
|
|
216
|
+
* @param query - The query.
|
|
217
|
+
* @returns Its parsed rows, or `undefined` when it failed.
|
|
218
|
+
*/
|
|
219
|
+
private runEmulatorProcessQuery;
|
|
172
220
|
/**
|
|
173
221
|
* Polls until this run's emulator is gone, or the budget elapses.
|
|
174
222
|
*
|
|
@@ -42,6 +42,7 @@ async function enablePluginWithErrorCapture({ app, pluginId }) {
|
|
|
42
42
|
throw error;
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
+
const ourLoadPlugin = app.plugins.loadPlugin;
|
|
45
46
|
const capturedConsole = [];
|
|
46
47
|
const formatHolder = globalThis;
|
|
47
48
|
function formatArgument(argument) {
|
|
@@ -62,14 +63,16 @@ async function enablePluginWithErrorCapture({ app, pluginId }) {
|
|
|
62
63
|
}
|
|
63
64
|
const origConsoleError = console.error;
|
|
64
65
|
const origConsoleWarn = console.warn;
|
|
65
|
-
|
|
66
|
+
function ourConsoleError(...input) {
|
|
66
67
|
recordConsole(...input);
|
|
67
68
|
origConsoleError.apply(console, input);
|
|
68
|
-
}
|
|
69
|
-
|
|
69
|
+
}
|
|
70
|
+
function ourConsoleWarn(...input) {
|
|
70
71
|
recordConsole(...input);
|
|
71
72
|
origConsoleWarn.apply(console, input);
|
|
72
|
-
}
|
|
73
|
+
}
|
|
74
|
+
console.error = ourConsoleError;
|
|
75
|
+
console.warn = ourConsoleWarn;
|
|
73
76
|
function onWindowError(event) {
|
|
74
77
|
capturedConsole.push(event.error instanceof Error ? formatArgument(event.error) : event.message);
|
|
75
78
|
}
|
|
@@ -81,9 +84,15 @@ async function enablePluginWithErrorCapture({ app, pluginId }) {
|
|
|
81
84
|
try {
|
|
82
85
|
await app.plugins.enablePluginAndSave(pluginId);
|
|
83
86
|
} finally {
|
|
84
|
-
app.plugins.loadPlugin
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
if (app.plugins.loadPlugin === ourLoadPlugin) {
|
|
88
|
+
app.plugins.loadPlugin = origLoadPlugin;
|
|
89
|
+
}
|
|
90
|
+
if (console.error === ourConsoleError) {
|
|
91
|
+
console.error = origConsoleError;
|
|
92
|
+
}
|
|
93
|
+
if (console.warn === ourConsoleWarn) {
|
|
94
|
+
console.warn = origConsoleWarn;
|
|
95
|
+
}
|
|
87
96
|
globalThis.removeEventListener("error", onWindowError);
|
|
88
97
|
globalThis.removeEventListener("unhandledrejection", onUnhandledRejection);
|
|
89
98
|
}
|
|
@@ -108,4 +117,4 @@ function getGenericPluginLoadFailureMessage(pluginId) {
|
|
|
108
117
|
enablePluginWithErrorCapture,
|
|
109
118
|
getGenericPluginLoadFailureMessage
|
|
110
119
|
});
|
|
111
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VuYWJsZS1wbHVnaW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTaGFyZWQgaGVscGVyIGZvciBlbmFibGluZyBhbiBPYnNpZGlhbiBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICogVXNlZCBieSBib3RoIHRoZSBnbG9iYWwgc2V0dXAgYW5kIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgdHlwZSB7IENvbW1vbkFyZ3VtZW50cyB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5janMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmFibGVQbHVnaW5QYXJhbXMge1xuICAvKipcbiAgICogVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZW5hYmxpbmcgYSBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVuYWJsZVBsdWdpblJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgZXJyb3IgbWVzc2FnZSBjYXB0dXJlZCBieSB0aGUgYGxvYWRQbHVnaW5gIG1vbmtleS1wYXRjaCwgb3IgYHVuZGVmaW5lZGBcbiAgICogd2hlbiB0aGUgcGF0Y2ggc2F3IG5vIHRocm93LiBXaGVuIE9ic2lkaWFuIHN3YWxsb3dzIHRoZSBlcnJvciAqYmVmb3JlKiB0aGVcbiAgICogcGF0Y2ggKGxlYXZpbmcgdGhpcyBlbXB0eSkgYnV0IHRoZSBwbHVnaW4gc3RpbGwgZmFpbGVkIHRvIGxvYWQsIHRoZSByZWFsXG4gICAqIGNhdXNlIFx1MjAxNCBpZiBpdCByZWFjaGVkIHRoZSByZW5kZXJlciBjb25zb2xlIFx1MjAxNCBpcyBpbiB7QGxpbmsgRW5hYmxlUGx1Z2luUmVzdWx0LnJlbmRlcmVyQ29uc29sZUVycm9yc30uXG4gICAqL1xuICByZWFkb25seSBlcnJvck1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgcGx1Z2luIGlzIGluIHRoZSBlbmFibGVkIHNldCBhZnRlciB0aGUgZW5hYmxlIGF0dGVtcHQuXG4gICAqIEEgcGx1Z2luIGNhbiBiZSBcImVuYWJsZWRcIiAoY29uZmlndXJlZCkgYnV0IG5vdCBcImxvYWRlZFwiIChmYWlsZWQgdG8gaW5pdGlhbGl6ZSkuXG4gICAqL1xuICByZWFkb25seSBpc0VuYWJsZWQ6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHBsdWdpbiBpbnN0YW5jZSBhY3R1YWxseSBleGlzdHMgaW4gYGFwcC5wbHVnaW5zLnBsdWdpbnNgLlxuICAgKiBUaGlzIGlzIHRoZSBkZWZpbml0aXZlIGNoZWNrIFx1MjAxNCBhIHBsdWdpbiB0aGF0IGlzIGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQgaGFzIGZhaWxlZC5cbiAgICovXG4gIHJlYWRvbmx5IGlzTG9hZGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb25zb2xlL2Vycm9yIG91dHB1dCBjYXB0dXJlZCBpbiB0aGUgcmVuZGVyZXIgZHVyaW5nIHRoZSBlbmFibGUgd2luZG93IFx1MjAxNFxuICAgKiBwb3B1bGF0ZWQgKipvbmx5Kiogd2hlbiB0aGUgcGx1Z2luIGZhaWxlZCB0byBsb2FkIGFuZCB0aGUgbW9ua2V5LXBhdGNoIHNhd1xuICAgKiBubyB0aHJvdyAoYCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkYCksIGkuZS4gZXhhY3RseSB0aGUgY2FzZSB0aGF0IHdvdWxkXG4gICAqIG90aGVyd2lzZSBzdXJmYWNlIHRoZSBnZW5lcmljIHtAbGluayBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlfSB0ZXh0LlxuICAgKiBgdW5kZWZpbmVkYCBvdGhlcndpc2UgKGluY2x1ZGluZyBvbiBzdWNjZXNzIGFuZCB3aGVuIHtAbGluayBFbmFibGVQbHVnaW5SZXN1bHQuZXJyb3JNZXNzYWdlfSBhbHJlYWR5IGhhcyB0aGUgZXJyb3IpLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVuZGVyZXJDb25zb2xlRXJyb3JzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nIHtcbiAgZXJyb3JUb1N0cmluZzogKGVycm9yOiB1bmtub3duKSA9PiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdIb2xkZXIge1xuICBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nOiBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBwbHVnaW4gaW5zaWRlIE9ic2lkaWFuIGFuZCBjYXB0dXJlcyBhbnkgbG9hZCBlcnJvci5cbiAqXG4gKiBNb25rZXktcGF0Y2hlcyBgYXBwLnBsdWdpbnMubG9hZFBsdWdpbmAgdG8gaW50ZXJjZXB0IGVycm9ycyBiZWZvcmVcbiAqIE9ic2lkaWFuJ3MgYGVuYWJsZVBsdWdpbmAgdHJ5LWNhdGNoIHN3YWxsb3dzIHRoZW0uIFRoZSBvcmlnaW5hbCBtZXRob2RcbiAqIGlzIGFsd2F5cyByZXN0b3JlZCBpbiBhIGBmaW5hbGx5YCBibG9jay5cbiAqXG4gKiBEZXNpZ25lZCB0byBiZSBwYXNzZWQgYXMgdGhlIGBjYWxsYmFja2AgYXJndW1lbnQgdG8ge0BsaW5rIGV2YWxJbk9ic2lkaWFufS5cbiAqXG4gKiBAcGFyYW0gaW5wdXQgLSBUaGUgY29tbW9uIGlucHV0IHBsdXMgdGhlIHBsdWdpbiBJRC5cbiAqIEBwYXJhbSBpbnB1dC5hcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIGlucHV0LnBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICogQHJldHVybnMgVGhlIGVuYWJsZSByZXN1bHQgd2l0aCBlcnJvciBtZXNzYWdlIGFuZCBlbmFibGVkIHN0YXR1cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUoeyBhcHAsIHBsdWdpbklkIH06IENvbW1vbkFyZ3VtZW50cyAmIEVuYWJsZVBsdWdpblBhcmFtcyk6IFByb21pc2U8RW5hYmxlUGx1Z2luUmVzdWx0PiB7XG4gIGlmICghYXBwLnBsdWdpbnMuaXNFbmFibGVkKCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5zZXRFbmFibGUodHJ1ZSk7XG4gIH1cblxuICAvKlxuICAgKiBGb3JjZSBhIGdlbnVpbmUgcmVsb2FkIHdoZW4gcmV0cnlpbmcuIElmIGEgcHJpb3IgYXR0ZW1wdCBsZWZ0IHRoZSBwbHVnaW4gaW5cbiAgICogdGhlIGVuYWJsZWQgc2V0IGJ1dCBub3QgbG9hZGVkICh0aGUgY29sZC1ib290IHJhY2UpLCBhIHBsYWluIHJlLWVuYWJsZSBjYW5cbiAgICogc2hvcnQtY2lyY3VpdCBvbiBzb21lIE9ic2lkaWFuIHZlcnNpb25zIHdpdGhvdXQgcmUtYXR0ZW1wdGluZyB0aGUgbG9hZC5cbiAgICogRnVsbHkgcmVzZXQgdGhlIGVuYWJsZWQgc3RhdGUgZmlyc3Qgc28gdGhlIGBlbmFibGVQbHVnaW5BbmRTYXZlYCBiZWxvdyBpcyBhXG4gICAqIHJlYWwgZnJlc2ggZW5hYmxlICsgbG9hZC4gTm8tb3Agb24gdGhlIGZpcnN0IGF0dGVtcHQgKG5vdCB5ZXQgZW5hYmxlZCkuXG4gICAqL1xuICBpZiAoYXBwLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKHBsdWdpbklkKSAmJiAhT2JqZWN0Lmhhc093bihhcHAucGx1Z2lucy5wbHVnaW5zLCBwbHVnaW5JZCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5kaXNhYmxlUGx1Z2luQW5kU2F2ZShwbHVnaW5JZCk7XG4gIH1cblxuICBsZXQgZXJyb3JNZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2QgLS0gSW50ZW50aW9uYWwgbW9ua2V5LXBhdGNoOyByZXN0b3JlZCBpbiBmaW5hbGx5LlxuICBjb25zdCBvcmlnTG9hZFBsdWdpbiA9IGFwcC5wbHVnaW5zLmxvYWRQbHVnaW47XG4gIGFwcC5wbHVnaW5zLmxvYWRQbHVnaW4gPSBhc3luYyBmdW5jdGlvbiBsb2FkUGx1Z2luKGlkOiBzdHJpbmcsIGlzVXNlckVuYWJsZWQ/OiBib29sZWFuKTogUHJvbWlzZTxQbHVnaW4+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb3JpZ0xvYWRQbHVnaW4uY2FsbCh0aGlzLCBpZCwgaXNVc2VyRW5hYmxlZCk7XG4gICAgICBlcnJvck1lc3NhZ2UgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gQXBwcm92ZWQgZG91YmxlIGNhc3Q6IGBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nYCBpcyBvdXIgaW50ZXJuYWwgV2luZG93IGF1Z21lbnRhdGlvbiwgaW50ZW50aW9uYWxseSBrZXB0IGxvY2FsIChub3QgZGVjbGFyZWQgZ2xvYmFsbHkpIHRvIGF2b2lkIGxlYWtpbmcgaW50byBjb25zdW1lciB0eXBlcy5cbiAgICAgIGNvbnN0IGhvbGRlciA9IGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyBQYXJ0aWFsPEludGVncmF0aW9uVGVzdGluZ0hvbGRlcj47XG4gICAgICBlcnJvck1lc3NhZ2UgPSBob2xkZXIuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZz8uZXJyb3JUb1N0cmluZyhlcnJvcikgPz8gU3RyaW5nKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfTtcblxuICAvKlxuICAgKiBMYXllciAxIFx1MjAxNCBjYXB0dXJlIHRoZSByZW5kZXJlciBjb25zb2xlICsgdW5jYXVnaHQgZXJyb3JzIGZvciB0aGUgZHVyYXRpb24gb2ZcbiAgICogdGhlIGVuYWJsZS4gSWYgT2JzaWRpYW4gc3dhbGxvd3MgdGhlIGxvYWQgZXJyb3IgYmVmb3JlIHRoZSBtb25rZXktcGF0Y2ggYWJvdmVcbiAgICogc2VlcyBpdCAobGVhdmluZyBgZXJyb3JNZXNzYWdlYCBlbXB0eSksIHRoZSByZWFsIGNhdXNlIGlzIHR5cGljYWxseSBzdGlsbFxuICAgKiBgY29uc29sZS5lcnJvcmAnZCwgc28gY2FwdHVyaW5nIGl0IGhlcmUgc3VyZmFjZXMgaXQgaW4gcGxhY2Ugb2YgdGhlIGdlbmVyaWNcbiAgICogZmFsbGJhY2suIFdvcmtzIG9uIGRlc2t0b3AgYW5kIEFuZHJvaWQgYWxpa2Ugc2luY2UgdGhpcyB3aG9sZSBmdW5jdGlvbiBpc1xuICAgKiBzZXJpYWxpemVkIGFuZCBpbmplY3RlZCBpbnRvIHRoZSByZW5kZXJlci5cbiAgICovXG4gIGNvbnN0IGNhcHR1cmVkQ29uc29sZTogc3RyaW5nW10gPSBbXTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4IC0tIEFwcHJvdmVkIGRvdWJsZSBjYXN0LCBzYW1lIHJhdGlvbmFsZSBhcyBhYm92ZS5cbiAgY29uc3QgZm9ybWF0SG9sZGVyID0gZ2xvYmFsVGhpcyBhcyB1bmtub3duIGFzIFBhcnRpYWw8SW50ZWdyYXRpb25UZXN0aW5nSG9sZGVyPjtcbiAgZnVuY3Rpb24gZm9ybWF0QXJndW1lbnQoYXJndW1lbnQ6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGlmIChhcmd1bWVudCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gZm9ybWF0SG9sZGVyLl9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3Rpbmc/LmVycm9yVG9TdHJpbmcoYXJndW1lbnQpID8/IFN0cmluZyhhcmd1bWVudCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnQ7XG4gICAgfVxuICAgIGlmIChhcmd1bWVudCA9PT0gdW5kZWZpbmVkIHx8IGFyZ3VtZW50ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKGFyZ3VtZW50KTtcbiAgICB9XG4gICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KGFyZ3VtZW50KTtcbiAgICByZXR1cm4ganNvbiA/PyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJndW1lbnQpO1xuICB9XG4gIGZ1bmN0aW9uIHJlY29yZENvbnNvbGUoLi4uaW5wdXQ6IHVua25vd25bXSk6IHZvaWQge1xuICAgIGNhcHR1cmVkQ29uc29sZS5wdXNoKGlucHV0Lm1hcCgoYXJndW1lbnQpID0+IGZvcm1hdEFyZ3VtZW50KGFyZ3VtZW50KSkuam9pbignICcpKTtcbiAgfVxuICBjb25zdCBvcmlnQ29uc29sZUVycm9yID0gY29uc29sZS5lcnJvcjtcbiAgY29uc3Qgb3JpZ0NvbnNvbGVXYXJuID0gY29uc29sZS53YXJuO1xuICBjb25zb2xlLmVycm9yID0gKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkID0+IHtcbiAgICByZWNvcmRDb25zb2xlKC4uLmlucHV0KTtcbiAgICBvcmlnQ29uc29sZUVycm9yLmFwcGx5KGNvbnNvbGUsIGlucHV0KTtcbiAgfTtcbiAgY29uc29sZS53YXJuID0gKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkID0+IHtcbiAgICByZWNvcmRDb25zb2xlKC4uLmlucHV0KTtcbiAgICBvcmlnQ29uc29sZVdhcm4uYXBwbHkoY29uc29sZSwgaW5wdXQpO1xuICB9O1xuICBmdW5jdGlvbiBvbldpbmRvd0Vycm9yKGV2ZW50OiBFcnJvckV2ZW50KTogdm9pZCB7XG4gICAgY2FwdHVyZWRDb25zb2xlLnB1c2goZXZlbnQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGZvcm1hdEFyZ3VtZW50KGV2ZW50LmVycm9yKSA6IGV2ZW50Lm1lc3NhZ2UpO1xuICB9XG4gIGZ1bmN0aW9uIG9uVW5oYW5kbGVkUmVqZWN0aW9uKGV2ZW50OiBQcm9taXNlUmVqZWN0aW9uRXZlbnQpOiB2b2lkIHtcbiAgICBjYXB0dXJlZENvbnNvbGUucHVzaChmb3JtYXRBcmd1bWVudChldmVudC5yZWFzb24pKTtcbiAgfVxuICBnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgb25XaW5kb3dFcnJvcik7XG4gIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigndW5oYW5kbGVkcmVqZWN0aW9uJywgb25VbmhhbmRsZWRSZWplY3Rpb24pO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgYXBwLnBsdWdpbnMuZW5hYmxlUGx1Z2luQW5kU2F2ZShwbHVnaW5JZCk7XG4gIH0gZmluYWxseSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXMgLS0gSW50ZW50aW9uYWwgcmVzdG9yZSBvZiBtb25rZXktcGF0Y2guXG4gICAgYXBwLnBsdWdpbnMubG9hZFBsdWdpbiA9IG9yaWdMb2FkUGx1Z2luO1xuICAgIGNvbnNvbGUuZXJyb3IgPSBvcmlnQ29uc29sZUVycm9yO1xuICAgIGNvbnNvbGUud2FybiA9IG9yaWdDb25zb2xlV2FybjtcbiAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgb25XaW5kb3dFcnJvcik7XG4gICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd1bmhhbmRsZWRyZWplY3Rpb24nLCBvblVuaGFuZGxlZFJlamVjdGlvbik7XG4gIH1cblxuICBjb25zdCBpc0xvYWRlZCA9IE9iamVjdC5oYXNPd24oYXBwLnBsdWdpbnMucGx1Z2lucywgcGx1Z2luSWQpO1xuXG4gIGxldCByZW5kZXJlckNvbnNvbGVFcnJvcnM6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaWYgKCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkKSB7XG4gICAgY29uc3Qgam9pbmVkID0gY2FwdHVyZWRDb25zb2xlLmpvaW4oJ1xcbicpLnRyaW0oKTtcbiAgICByZW5kZXJlckNvbnNvbGVFcnJvcnMgPSBqb2luZWQgfHwgdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvck1lc3NhZ2UsXG4gICAgaXNFbmFibGVkOiBhcHAucGx1Z2lucy5lbmFibGVkUGx1Z2lucy5oYXMocGx1Z2luSWQpLFxuICAgIGlzTG9hZGVkLFxuICAgIHJlbmRlcmVyQ29uc29sZUVycm9yc1xuICB9O1xufVxuXG4vKipcbiAqIFRoZSBnZW5lcmljIGxhc3QtcmVzb3J0IG1lc3NhZ2Ugc2hvd24gd2hlbiBhIHBsdWdpbiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0XG4gKiBub3QgbG9hZGVkIGFuZCBubyByZWFsIGVycm9yIGNvdWxkIGJlIGNhcHR1cmVkIChuZWl0aGVyIHRoZSBgbG9hZFBsdWdpbmBcbiAqIG1vbmtleS1wYXRjaCBub3IgdGhlIHJlbmRlcmVyIGNvbnNvbGUgbm9yLCBvbiBBbmRyb2lkLCBgYWRiIGxvZ2NhdGAgc3VyZmFjZWQgYVxuICogY2F1c2UpLlxuICpcbiAqIEhvc3Qtc2lkZSBoZWxwZXIgXHUyMDE0IHVzZWQgYnkgdGhlIHNldHVwIG9yY2hlc3RyYXRpb24gdG8gY29tcG9zZSB0aGUgZmluYWxcbiAqIGZhaWx1cmUgbWVzc2FnZSwgc28gdGhlIHJlbmRlcmVyLWluamVjdGVkIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfVxuICogc3RheXMgc2VsZi1jb250YWluZWQuXG4gKlxuICogQHBhcmFtIHBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdGhhdCBmYWlsZWQgdG8gbG9hZC5cbiAqIEByZXR1cm5zIFRoZSBnZW5lcmljIGZhaWx1cmUgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0IG5vdCBsb2FkZWQuIGBcbiAgICArICdPYnNpZGlhbiBtYXkgaGF2ZSBjYXVnaHQgdGhlIGVycm9yIGJlZm9yZSB0aGUgbW9ua2V5LXBhdGNoLiAnXG4gICAgKyAnQ2hlY2sgdGhlIE9ic2lkaWFuIGNvbnNvbGUgZm9yIGRldGFpbHMuJztcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQStFQSxlQUFzQiw2QkFBNkIsRUFBRSxLQUFLLFNBQVMsR0FBc0U7QUFDdkksTUFBSSxDQUFDLElBQUksUUFBUSxVQUFVLEdBQUc7QUFDNUIsVUFBTSxJQUFJLFFBQVEsVUFBVSxJQUFJO0FBQUEsRUFDbEM7QUFTQSxNQUFJLElBQUksUUFBUSxlQUFlLElBQUksUUFBUSxLQUFLLENBQUMsT0FBTyxPQUFPLElBQUksUUFBUSxTQUFTLFFBQVEsR0FBRztBQUM3RixVQUFNLElBQUksUUFBUSxxQkFBcUIsUUFBUTtBQUFBLEVBQ2pEO0FBRUEsTUFBSTtBQUVKLFFBQU0saUJBQWlCLElBQUksUUFBUTtBQUNuQyxNQUFJLFFBQVEsYUFBYSxlQUFlLFdBQVcsSUFBWSxlQUEwQztBQUN2RyxRQUFJO0FBQ0YsWUFBTSxTQUFTLE1BQU0sZUFBZSxLQUFLLE1BQU0sSUFBSSxhQUFhO0FBQ2hFLHFCQUFlO0FBQ2YsYUFBTztBQUFBLElBQ1QsU0FBUyxPQUFPO0FBRWQsWUFBTSxTQUFTO0FBQ2YscUJBQWUsT0FBTyw4QkFBOEIsY0FBYyxLQUFLLEtBQUssT0FBTyxLQUFLO0FBQ3hGLFlBQU07QUFBQSxJQUNSO0FBQUEsRUFDRjtBQVVBLFFBQU0sa0JBQTRCLENBQUM7QUFFbkMsUUFBTSxlQUFlO0FBQ3JCLFdBQVMsZUFBZSxVQUEyQjtBQUNqRCxRQUFJLG9CQUFvQixPQUFPO0FBQzdCLGFBQU8sYUFBYSw4QkFBOEIsY0FBYyxRQUFRLEtBQUssT0FBTyxRQUFRO0FBQUEsSUFDOUY7QUFDQSxRQUFJLE9BQU8sYUFBYSxVQUFVO0FBQ2hDLGFBQU87QUFBQSxJQUNUO0FBQ0EsUUFBSSxhQUFhLFVBQWEsYUFBYSxNQUFNO0FBQy9DLGFBQU8sT0FBTyxRQUFRO0FBQUEsSUFDeEI7QUFDQSxVQUFNLE9BQU8sS0FBSyxVQUFVLFFBQVE7QUFDcEMsV0FBTyxRQUFRLE9BQU8sVUFBVSxTQUFTLEtBQUssUUFBUTtBQUFBLEVBQ3hEO0FBQ0EsV0FBUyxpQkFBaUIsT0FBd0I7QUFDaEQsb0JBQWdCLEtBQUssTUFBTSxJQUFJLENBQUMsYUFBYSxlQUFlLFFBQVEsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDO0FBQUEsRUFDbEY7QUFDQSxRQUFNLG1CQUFtQixRQUFRO0FBQ2pDLFFBQU0sa0JBQWtCLFFBQVE7QUFDaEMsVUFBUSxRQUFRLElBQUksVUFBMkI7QUFDN0Msa0JBQWMsR0FBRyxLQUFLO0FBQ3RCLHFCQUFpQixNQUFNLFNBQVMsS0FBSztBQUFBLEVBQ3ZDO0FBQ0EsVUFBUSxPQUFPLElBQUksVUFBMkI7QUFDNUMsa0JBQWMsR0FBRyxLQUFLO0FBQ3RCLG9CQUFnQixNQUFNLFNBQVMsS0FBSztBQUFBLEVBQ3RDO0FBQ0EsV0FBUyxjQUFjLE9BQXlCO0FBQzlDLG9CQUFnQixLQUFLLE1BQU0saUJBQWlCLFFBQVEsZUFBZSxNQUFNLEtBQUssSUFBSSxNQUFNLE9BQU87QUFBQSxFQUNqRztBQUNBLFdBQVMscUJBQXFCLE9BQW9DO0FBQ2hFLG9CQUFnQixLQUFLLGVBQWUsTUFBTSxNQUFNLENBQUM7QUFBQSxFQUNuRDtBQUNBLGFBQVcsaUJBQWlCLFNBQVMsYUFBYTtBQUNsRCxhQUFXLGlCQUFpQixzQkFBc0Isb0JBQW9CO0FBRXRFLE1BQUk7QUFDRixVQUFNLElBQUksUUFBUSxvQkFBb0IsUUFBUTtBQUFBLEVBQ2hELFVBQUU7QUFFQSxRQUFJLFFBQVEsYUFBYTtBQUN6QixZQUFRLFFBQVE7QUFDaEIsWUFBUSxPQUFPO0FBQ2YsZUFBVyxvQkFBb0IsU0FBUyxhQUFhO0FBQ3JELGVBQVcsb0JBQW9CLHNCQUFzQixvQkFBb0I7QUFBQSxFQUMzRTtBQUVBLFFBQU0sV0FBVyxPQUFPLE9BQU8sSUFBSSxRQUFRLFNBQVMsUUFBUTtBQUU1RCxNQUFJO0FBQ0osTUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVU7QUFDOUIsVUFBTSxTQUFTLGdCQUFnQixLQUFLLElBQUksRUFBRSxLQUFLO0FBQy9DLDRCQUF3QixVQUFVO0FBQUEsRUFDcEM7QUFFQSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsV0FBVyxJQUFJLFFBQVEsZUFBZSxJQUFJLFFBQVE7QUFBQSxJQUNsRDtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7QUFlTyxTQUFTLG1DQUFtQyxVQUEwQjtBQUMzRSxTQUFPLFdBQVcsUUFBUTtBQUc1QjsiLAogICJuYW1lcyI6IFtdCn0K
|
|
120
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VuYWJsZS1wbHVnaW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTaGFyZWQgaGVscGVyIGZvciBlbmFibGluZyBhbiBPYnNpZGlhbiBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICogVXNlZCBieSBib3RoIHRoZSBnbG9iYWwgc2V0dXAgYW5kIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgdHlwZSB7IENvbW1vbkFyZ3VtZW50cyB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5janMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmFibGVQbHVnaW5QYXJhbXMge1xuICAvKipcbiAgICogVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZW5hYmxpbmcgYSBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVuYWJsZVBsdWdpblJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgZXJyb3IgbWVzc2FnZSBjYXB0dXJlZCBieSB0aGUgYGxvYWRQbHVnaW5gIG1vbmtleS1wYXRjaCwgb3IgYHVuZGVmaW5lZGBcbiAgICogd2hlbiB0aGUgcGF0Y2ggc2F3IG5vIHRocm93LiBXaGVuIE9ic2lkaWFuIHN3YWxsb3dzIHRoZSBlcnJvciAqYmVmb3JlKiB0aGVcbiAgICogcGF0Y2ggKGxlYXZpbmcgdGhpcyBlbXB0eSkgYnV0IHRoZSBwbHVnaW4gc3RpbGwgZmFpbGVkIHRvIGxvYWQsIHRoZSByZWFsXG4gICAqIGNhdXNlIFx1MjAxNCBpZiBpdCByZWFjaGVkIHRoZSByZW5kZXJlciBjb25zb2xlIFx1MjAxNCBpcyBpbiB7QGxpbmsgRW5hYmxlUGx1Z2luUmVzdWx0LnJlbmRlcmVyQ29uc29sZUVycm9yc30uXG4gICAqL1xuICByZWFkb25seSBlcnJvck1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgcGx1Z2luIGlzIGluIHRoZSBlbmFibGVkIHNldCBhZnRlciB0aGUgZW5hYmxlIGF0dGVtcHQuXG4gICAqIEEgcGx1Z2luIGNhbiBiZSBcImVuYWJsZWRcIiAoY29uZmlndXJlZCkgYnV0IG5vdCBcImxvYWRlZFwiIChmYWlsZWQgdG8gaW5pdGlhbGl6ZSkuXG4gICAqL1xuICByZWFkb25seSBpc0VuYWJsZWQ6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHBsdWdpbiBpbnN0YW5jZSBhY3R1YWxseSBleGlzdHMgaW4gYGFwcC5wbHVnaW5zLnBsdWdpbnNgLlxuICAgKiBUaGlzIGlzIHRoZSBkZWZpbml0aXZlIGNoZWNrIFx1MjAxNCBhIHBsdWdpbiB0aGF0IGlzIGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQgaGFzIGZhaWxlZC5cbiAgICovXG4gIHJlYWRvbmx5IGlzTG9hZGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb25zb2xlL2Vycm9yIG91dHB1dCBjYXB0dXJlZCBpbiB0aGUgcmVuZGVyZXIgZHVyaW5nIHRoZSBlbmFibGUgd2luZG93IFx1MjAxNFxuICAgKiBwb3B1bGF0ZWQgKipvbmx5Kiogd2hlbiB0aGUgcGx1Z2luIGZhaWxlZCB0byBsb2FkIGFuZCB0aGUgbW9ua2V5LXBhdGNoIHNhd1xuICAgKiBubyB0aHJvdyAoYCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkYCksIGkuZS4gZXhhY3RseSB0aGUgY2FzZSB0aGF0IHdvdWxkXG4gICAqIG90aGVyd2lzZSBzdXJmYWNlIHRoZSBnZW5lcmljIHtAbGluayBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlfSB0ZXh0LlxuICAgKiBgdW5kZWZpbmVkYCBvdGhlcndpc2UgKGluY2x1ZGluZyBvbiBzdWNjZXNzIGFuZCB3aGVuIHtAbGluayBFbmFibGVQbHVnaW5SZXN1bHQuZXJyb3JNZXNzYWdlfSBhbHJlYWR5IGhhcyB0aGUgZXJyb3IpLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVuZGVyZXJDb25zb2xlRXJyb3JzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nIHtcbiAgZXJyb3JUb1N0cmluZzogKGVycm9yOiB1bmtub3duKSA9PiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdIb2xkZXIge1xuICBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nOiBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBwbHVnaW4gaW5zaWRlIE9ic2lkaWFuIGFuZCBjYXB0dXJlcyBhbnkgbG9hZCBlcnJvci5cbiAqXG4gKiBNb25rZXktcGF0Y2hlcyBgYXBwLnBsdWdpbnMubG9hZFBsdWdpbmAgdG8gaW50ZXJjZXB0IGVycm9ycyBiZWZvcmVcbiAqIE9ic2lkaWFuJ3MgYGVuYWJsZVBsdWdpbmAgdHJ5LWNhdGNoIHN3YWxsb3dzIHRoZW0uIFRoZSBvcmlnaW5hbCBtZXRob2RcbiAqIGlzIHJlc3RvcmVkIGluIGEgYGZpbmFsbHlgIGJsb2NrIFx1MjAxNCBidXQgb25seSB3aGlsZSB0aGUgcGF0Y2ggdGhpcyBmdW5jdGlvblxuICogaW5zdGFsbGVkIGlzIHN0aWxsIHRoZSBvbmUgaW4gcGxhY2UsIHNvIGEgcGx1Z2luIHRoYXQgcGF0Y2hlZCB0aGUgc2FtZSBzbG90XG4gKiBkdXJpbmcgaXRzIG93biBsb2FkIGtlZXBzIGl0cyBwYXRjaC5cbiAqXG4gKiBEZXNpZ25lZCB0byBiZSBwYXNzZWQgYXMgdGhlIGBjYWxsYmFja2AgYXJndW1lbnQgdG8ge0BsaW5rIGV2YWxJbk9ic2lkaWFufS5cbiAqXG4gKiBAcGFyYW0gaW5wdXQgLSBUaGUgY29tbW9uIGlucHV0IHBsdXMgdGhlIHBsdWdpbiBJRC5cbiAqIEBwYXJhbSBpbnB1dC5hcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIGlucHV0LnBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICogQHJldHVybnMgVGhlIGVuYWJsZSByZXN1bHQgd2l0aCBlcnJvciBtZXNzYWdlIGFuZCBlbmFibGVkIHN0YXR1cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUoeyBhcHAsIHBsdWdpbklkIH06IENvbW1vbkFyZ3VtZW50cyAmIEVuYWJsZVBsdWdpblBhcmFtcyk6IFByb21pc2U8RW5hYmxlUGx1Z2luUmVzdWx0PiB7XG4gIGlmICghYXBwLnBsdWdpbnMuaXNFbmFibGVkKCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5zZXRFbmFibGUodHJ1ZSk7XG4gIH1cblxuICAvKlxuICAgKiBGb3JjZSBhIGdlbnVpbmUgcmVsb2FkIHdoZW4gcmV0cnlpbmcuIElmIGEgcHJpb3IgYXR0ZW1wdCBsZWZ0IHRoZSBwbHVnaW4gaW5cbiAgICogdGhlIGVuYWJsZWQgc2V0IGJ1dCBub3QgbG9hZGVkICh0aGUgY29sZC1ib290IHJhY2UpLCBhIHBsYWluIHJlLWVuYWJsZSBjYW5cbiAgICogc2hvcnQtY2lyY3VpdCBvbiBzb21lIE9ic2lkaWFuIHZlcnNpb25zIHdpdGhvdXQgcmUtYXR0ZW1wdGluZyB0aGUgbG9hZC5cbiAgICogRnVsbHkgcmVzZXQgdGhlIGVuYWJsZWQgc3RhdGUgZmlyc3Qgc28gdGhlIGBlbmFibGVQbHVnaW5BbmRTYXZlYCBiZWxvdyBpcyBhXG4gICAqIHJlYWwgZnJlc2ggZW5hYmxlICsgbG9hZC4gTm8tb3Agb24gdGhlIGZpcnN0IGF0dGVtcHQgKG5vdCB5ZXQgZW5hYmxlZCkuXG4gICAqL1xuICBpZiAoYXBwLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKHBsdWdpbklkKSAmJiAhT2JqZWN0Lmhhc093bihhcHAucGx1Z2lucy5wbHVnaW5zLCBwbHVnaW5JZCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5kaXNhYmxlUGx1Z2luQW5kU2F2ZShwbHVnaW5JZCk7XG4gIH1cblxuICBsZXQgZXJyb3JNZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2QgLS0gSW50ZW50aW9uYWwgbW9ua2V5LXBhdGNoOyByZXN0b3JlZCBpbiBmaW5hbGx5LlxuICBjb25zdCBvcmlnTG9hZFBsdWdpbiA9IGFwcC5wbHVnaW5zLmxvYWRQbHVnaW47XG4gIGFwcC5wbHVnaW5zLmxvYWRQbHVnaW4gPSBhc3luYyBmdW5jdGlvbiBsb2FkUGx1Z2luKGlkOiBzdHJpbmcsIGlzVXNlckVuYWJsZWQ/OiBib29sZWFuKTogUHJvbWlzZTxQbHVnaW4+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb3JpZ0xvYWRQbHVnaW4uY2FsbCh0aGlzLCBpZCwgaXNVc2VyRW5hYmxlZCk7XG4gICAgICBlcnJvck1lc3NhZ2UgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gQXBwcm92ZWQgZG91YmxlIGNhc3Q6IGBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nYCBpcyBvdXIgaW50ZXJuYWwgV2luZG93IGF1Z21lbnRhdGlvbiwgaW50ZW50aW9uYWxseSBrZXB0IGxvY2FsIChub3QgZGVjbGFyZWQgZ2xvYmFsbHkpIHRvIGF2b2lkIGxlYWtpbmcgaW50byBjb25zdW1lciB0eXBlcy5cbiAgICAgIGNvbnN0IGhvbGRlciA9IGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyBQYXJ0aWFsPEludGVncmF0aW9uVGVzdGluZ0hvbGRlcj47XG4gICAgICBlcnJvck1lc3NhZ2UgPSBob2xkZXIuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZz8uZXJyb3JUb1N0cmluZyhlcnJvcikgPz8gU3RyaW5nKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfTtcbiAgLypcbiAgICogUmVhZCB0aGUgd3JhcHBlciBiYWNrIHNvIHRoZSBgZmluYWxseWAgY2FuIHRlbGwgXCJzdGlsbCBvdXJzXCIgZnJvbSBcInNvbWVvbmUgcGF0Y2hlZCBvdmVyIHVzXCIuIEFzc2lnbmluZ1xuICAgKiBpdCB0aHJvdWdoIGBhcHAucGx1Z2lucy5sb2FkUGx1Z2luYCByYXRoZXIgdGhhbiBkZWNsYXJpbmcgaXQgc3RhbmRhbG9uZSBpcyB3aGF0IHR5cGVzIGl0cyBgdGhpc2AuXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kIC0tIFJlYWRpbmcgYmFjayB0aGUgcGF0Y2gganVzdCBpbnN0YWxsZWQsIHRvIHJlc3RvcmUgaXQgY29uZGl0aW9uYWxseS5cbiAgY29uc3Qgb3VyTG9hZFBsdWdpbiA9IGFwcC5wbHVnaW5zLmxvYWRQbHVnaW47XG5cbiAgLypcbiAgICogTGF5ZXIgMSBcdTIwMTQgY2FwdHVyZSB0aGUgcmVuZGVyZXIgY29uc29sZSArIHVuY2F1Z2h0IGVycm9ycyBmb3IgdGhlIGR1cmF0aW9uIG9mXG4gICAqIHRoZSBlbmFibGUuIElmIE9ic2lkaWFuIHN3YWxsb3dzIHRoZSBsb2FkIGVycm9yIGJlZm9yZSB0aGUgbW9ua2V5LXBhdGNoIGFib3ZlXG4gICAqIHNlZXMgaXQgKGxlYXZpbmcgYGVycm9yTWVzc2FnZWAgZW1wdHkpLCB0aGUgcmVhbCBjYXVzZSBpcyB0eXBpY2FsbHkgc3RpbGxcbiAgICogYGNvbnNvbGUuZXJyb3JgJ2QsIHNvIGNhcHR1cmluZyBpdCBoZXJlIHN1cmZhY2VzIGl0IGluIHBsYWNlIG9mIHRoZSBnZW5lcmljXG4gICAqIGZhbGxiYWNrLiBXb3JrcyBvbiBkZXNrdG9wIGFuZCBBbmRyb2lkIGFsaWtlIHNpbmNlIHRoaXMgd2hvbGUgZnVuY3Rpb24gaXNcbiAgICogc2VyaWFsaXplZCBhbmQgaW5qZWN0ZWQgaW50byB0aGUgcmVuZGVyZXIuXG4gICAqL1xuICBjb25zdCBjYXB0dXJlZENvbnNvbGU6IHN0cmluZ1tdID0gW107XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCAtLSBBcHByb3ZlZCBkb3VibGUgY2FzdCwgc2FtZSByYXRpb25hbGUgYXMgYWJvdmUuXG4gIGNvbnN0IGZvcm1hdEhvbGRlciA9IGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyBQYXJ0aWFsPEludGVncmF0aW9uVGVzdGluZ0hvbGRlcj47XG4gIGZ1bmN0aW9uIGZvcm1hdEFyZ3VtZW50KGFyZ3VtZW50OiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBpZiAoYXJndW1lbnQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgcmV0dXJuIGZvcm1hdEhvbGRlci5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nPy5lcnJvclRvU3RyaW5nKGFyZ3VtZW50KSA/PyBTdHJpbmcoYXJndW1lbnQpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50O1xuICAgIH1cbiAgICBpZiAoYXJndW1lbnQgPT09IHVuZGVmaW5lZCB8fCBhcmd1bWVudCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFN0cmluZyhhcmd1bWVudCk7XG4gICAgfVxuICAgIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShhcmd1bWVudCk7XG4gICAgcmV0dXJuIGpzb24gPz8gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3VtZW50KTtcbiAgfVxuICBmdW5jdGlvbiByZWNvcmRDb25zb2xlKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBjYXB0dXJlZENvbnNvbGUucHVzaChpbnB1dC5tYXAoKGFyZ3VtZW50KSA9PiBmb3JtYXRBcmd1bWVudChhcmd1bWVudCkpLmpvaW4oJyAnKSk7XG4gIH1cbiAgY29uc3Qgb3JpZ0NvbnNvbGVFcnJvciA9IGNvbnNvbGUuZXJyb3I7XG4gIGNvbnN0IG9yaWdDb25zb2xlV2FybiA9IGNvbnNvbGUud2FybjtcbiAgZnVuY3Rpb24gb3VyQ29uc29sZUVycm9yKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkIHtcbiAgICByZWNvcmRDb25zb2xlKC4uLmlucHV0KTtcbiAgICBvcmlnQ29uc29sZUVycm9yLmFwcGx5KGNvbnNvbGUsIGlucHV0KTtcbiAgfVxuICBmdW5jdGlvbiBvdXJDb25zb2xlV2FybiguLi5pbnB1dDogdW5rbm93bltdKTogdm9pZCB7XG4gICAgcmVjb3JkQ29uc29sZSguLi5pbnB1dCk7XG4gICAgb3JpZ0NvbnNvbGVXYXJuLmFwcGx5KGNvbnNvbGUsIGlucHV0KTtcbiAgfVxuICBjb25zb2xlLmVycm9yID0gb3VyQ29uc29sZUVycm9yO1xuICBjb25zb2xlLndhcm4gPSBvdXJDb25zb2xlV2FybjtcbiAgZnVuY3Rpb24gb25XaW5kb3dFcnJvcihldmVudDogRXJyb3JFdmVudCk6IHZvaWQge1xuICAgIGNhcHR1cmVkQ29uc29sZS5wdXNoKGV2ZW50LmVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBmb3JtYXRBcmd1bWVudChldmVudC5lcnJvcikgOiBldmVudC5tZXNzYWdlKTtcbiAgfVxuICBmdW5jdGlvbiBvblVuaGFuZGxlZFJlamVjdGlvbihldmVudDogUHJvbWlzZVJlamVjdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgY2FwdHVyZWRDb25zb2xlLnB1c2goZm9ybWF0QXJndW1lbnQoZXZlbnQucmVhc29uKSk7XG4gIH1cbiAgZ2xvYmFsVGhpcy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIG9uV2luZG93RXJyb3IpO1xuICBnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoJ3VuaGFuZGxlZHJlamVjdGlvbicsIG9uVW5oYW5kbGVkUmVqZWN0aW9uKTtcblxuICB0cnkge1xuICAgIGF3YWl0IGFwcC5wbHVnaW5zLmVuYWJsZVBsdWdpbkFuZFNhdmUocGx1Z2luSWQpO1xuICB9IGZpbmFsbHkge1xuICAgIC8qXG4gICAgICogUmVzdG9yZSBPTkxZIHdoYXQgdGhpcyBmdW5jdGlvbiBpbnN0YWxsZWQuIFRoZSBwbHVnaW4gdW5kZXIgdGVzdCBsb2FkcyBJTlNJREUgdGhlIGB0cnlgIGFib3ZlLCBzbyBpdHNcbiAgICAgKiBgb25sb2FkYCBydW5zIGJlZm9yZSB0aGlzIGxpbmUgXHUyMDE0IGFuZCBhIHBsdWdpbiB0aGF0IG1vbmtleS1wYXRjaGVzIGFueSBvZiB0aGVzZSB0aHJlZSBzbG90cyB0aGVyZSB3cml0ZXNcbiAgICAgKiBhbiBvd24gcHJvcGVydHkgb3ZlciBvdXJzICh0aGUgc2hhcGUgYG1vbmtleS1hcm91bmRgIHByb2R1Y2VzKS4gQW4gdW5jb25kaXRpb25hbCByZXN0b3JlIHB1dHMgYmFjayB0aGVcbiAgICAgKiB2YWx1ZSByZWFkIGJlZm9yZSB0aGF0IHBsdWdpbiBleGlzdGVkLCBkZWxldGluZyBpdHMgcGF0Y2ggd2l0aCBubyBlcnJvciBhbmQgbm8gd2FybmluZzsgYGxvYWRQbHVnaW5gIGlzXG4gICAgICogdGhlIG9ubHkgY29tcGxldGUgc2VhbSBmb3Igb2JzZXJ2aW5nIGBhcHAucGx1Z2lucy5wbHVnaW5zYCBtb3ZlLCBzbyBhIHBsdWdpbiByZWFjaGluZyBmb3IgaXQgaXMgb3JkaW5hcnlcbiAgICAgKiByYXRoZXIgdGhhbiBleG90aWMuIFRoZSBndWFyZCBpcyBgbW9ua2V5LWFyb3VuZGAncyBvd24gdW5pbnN0YWxsZXIgZGlzY2lwbGluZSAoYGlmIChvYmpbbWV0aG9kXSA9PT1cbiAgICAgKiB3cmFwcGVyKWApOiB3aGVuIHNvbWVvbmUgcGF0Y2hlZCBvdmVyIHVzLCBsZWF2aW5nIHRoZSBjaGFpbiBhbG9uZSBpcyB0aGUgY29ycmVjdCBuby1vcCBcdTIwMTQgb3VyIHdyYXBwZXIgaXNcbiAgICAgKiBzdGlsbCBpbiBpdCwgb25lIGxldmVsIGRvd24sIGFuZCB1bndpbmRzIHdoZW4gdGhhdCBwbHVnaW4gdW5wYXRjaGVzLlxuICAgICAqL1xuICAgIGlmIChhcHAucGx1Z2lucy5sb2FkUGx1Z2luID09PSBvdXJMb2FkUGx1Z2luKSB7XG4gICAgICBhcHAucGx1Z2lucy5sb2FkUGx1Z2luID0gb3JpZ0xvYWRQbHVnaW47XG4gICAgfVxuICAgIGlmIChjb25zb2xlLmVycm9yID09PSBvdXJDb25zb2xlRXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IgPSBvcmlnQ29uc29sZUVycm9yO1xuICAgIH1cbiAgICBpZiAoY29uc29sZS53YXJuID09PSBvdXJDb25zb2xlV2Fybikge1xuICAgICAgY29uc29sZS53YXJuID0gb3JpZ0NvbnNvbGVXYXJuO1xuICAgIH1cbiAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgb25XaW5kb3dFcnJvcik7XG4gICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd1bmhhbmRsZWRyZWplY3Rpb24nLCBvblVuaGFuZGxlZFJlamVjdGlvbik7XG4gIH1cblxuICBjb25zdCBpc0xvYWRlZCA9IE9iamVjdC5oYXNPd24oYXBwLnBsdWdpbnMucGx1Z2lucywgcGx1Z2luSWQpO1xuXG4gIGxldCByZW5kZXJlckNvbnNvbGVFcnJvcnM6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaWYgKCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkKSB7XG4gICAgY29uc3Qgam9pbmVkID0gY2FwdHVyZWRDb25zb2xlLmpvaW4oJ1xcbicpLnRyaW0oKTtcbiAgICByZW5kZXJlckNvbnNvbGVFcnJvcnMgPSBqb2luZWQgfHwgdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvck1lc3NhZ2UsXG4gICAgaXNFbmFibGVkOiBhcHAucGx1Z2lucy5lbmFibGVkUGx1Z2lucy5oYXMocGx1Z2luSWQpLFxuICAgIGlzTG9hZGVkLFxuICAgIHJlbmRlcmVyQ29uc29sZUVycm9yc1xuICB9O1xufVxuXG4vKipcbiAqIFRoZSBnZW5lcmljIGxhc3QtcmVzb3J0IG1lc3NhZ2Ugc2hvd24gd2hlbiBhIHBsdWdpbiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0XG4gKiBub3QgbG9hZGVkIGFuZCBubyByZWFsIGVycm9yIGNvdWxkIGJlIGNhcHR1cmVkIChuZWl0aGVyIHRoZSBgbG9hZFBsdWdpbmBcbiAqIG1vbmtleS1wYXRjaCBub3IgdGhlIHJlbmRlcmVyIGNvbnNvbGUgbm9yLCBvbiBBbmRyb2lkLCBgYWRiIGxvZ2NhdGAgc3VyZmFjZWQgYVxuICogY2F1c2UpLlxuICpcbiAqIEhvc3Qtc2lkZSBoZWxwZXIgXHUyMDE0IHVzZWQgYnkgdGhlIHNldHVwIG9yY2hlc3RyYXRpb24gdG8gY29tcG9zZSB0aGUgZmluYWxcbiAqIGZhaWx1cmUgbWVzc2FnZSwgc28gdGhlIHJlbmRlcmVyLWluamVjdGVkIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfVxuICogc3RheXMgc2VsZi1jb250YWluZWQuXG4gKlxuICogQHBhcmFtIHBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdGhhdCBmYWlsZWQgdG8gbG9hZC5cbiAqIEByZXR1cm5zIFRoZSBnZW5lcmljIGZhaWx1cmUgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0IG5vdCBsb2FkZWQuIGBcbiAgICArICdPYnNpZGlhbiBtYXkgaGF2ZSBjYXVnaHQgdGhlIGVycm9yIGJlZm9yZSB0aGUgbW9ua2V5LXBhdGNoLiAnXG4gICAgKyAnQ2hlY2sgdGhlIE9ic2lkaWFuIGNvbnNvbGUgZm9yIGRldGFpbHMuJztcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWlGQSxlQUFzQiw2QkFBNkIsRUFBRSxLQUFLLFNBQVMsR0FBc0U7QUFDdkksTUFBSSxDQUFDLElBQUksUUFBUSxVQUFVLEdBQUc7QUFDNUIsVUFBTSxJQUFJLFFBQVEsVUFBVSxJQUFJO0FBQUEsRUFDbEM7QUFTQSxNQUFJLElBQUksUUFBUSxlQUFlLElBQUksUUFBUSxLQUFLLENBQUMsT0FBTyxPQUFPLElBQUksUUFBUSxTQUFTLFFBQVEsR0FBRztBQUM3RixVQUFNLElBQUksUUFBUSxxQkFBcUIsUUFBUTtBQUFBLEVBQ2pEO0FBRUEsTUFBSTtBQUVKLFFBQU0saUJBQWlCLElBQUksUUFBUTtBQUNuQyxNQUFJLFFBQVEsYUFBYSxlQUFlLFdBQVcsSUFBWSxlQUEwQztBQUN2RyxRQUFJO0FBQ0YsWUFBTSxTQUFTLE1BQU0sZUFBZSxLQUFLLE1BQU0sSUFBSSxhQUFhO0FBQ2hFLHFCQUFlO0FBQ2YsYUFBTztBQUFBLElBQ1QsU0FBUyxPQUFPO0FBRWQsWUFBTSxTQUFTO0FBQ2YscUJBQWUsT0FBTyw4QkFBOEIsY0FBYyxLQUFLLEtBQUssT0FBTyxLQUFLO0FBQ3hGLFlBQU07QUFBQSxJQUNSO0FBQUEsRUFDRjtBQU1BLFFBQU0sZ0JBQWdCLElBQUksUUFBUTtBQVVsQyxRQUFNLGtCQUE0QixDQUFDO0FBRW5DLFFBQU0sZUFBZTtBQUNyQixXQUFTLGVBQWUsVUFBMkI7QUFDakQsUUFBSSxvQkFBb0IsT0FBTztBQUM3QixhQUFPLGFBQWEsOEJBQThCLGNBQWMsUUFBUSxLQUFLLE9BQU8sUUFBUTtBQUFBLElBQzlGO0FBQ0EsUUFBSSxPQUFPLGFBQWEsVUFBVTtBQUNoQyxhQUFPO0FBQUEsSUFDVDtBQUNBLFFBQUksYUFBYSxVQUFhLGFBQWEsTUFBTTtBQUMvQyxhQUFPLE9BQU8sUUFBUTtBQUFBLElBQ3hCO0FBQ0EsVUFBTSxPQUFPLEtBQUssVUFBVSxRQUFRO0FBQ3BDLFdBQU8sUUFBUSxPQUFPLFVBQVUsU0FBUyxLQUFLLFFBQVE7QUFBQSxFQUN4RDtBQUNBLFdBQVMsaUJBQWlCLE9BQXdCO0FBQ2hELG9CQUFnQixLQUFLLE1BQU0sSUFBSSxDQUFDLGFBQWEsZUFBZSxRQUFRLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQztBQUFBLEVBQ2xGO0FBQ0EsUUFBTSxtQkFBbUIsUUFBUTtBQUNqQyxRQUFNLGtCQUFrQixRQUFRO0FBQ2hDLFdBQVMsbUJBQW1CLE9BQXdCO0FBQ2xELGtCQUFjLEdBQUcsS0FBSztBQUN0QixxQkFBaUIsTUFBTSxTQUFTLEtBQUs7QUFBQSxFQUN2QztBQUNBLFdBQVMsa0JBQWtCLE9BQXdCO0FBQ2pELGtCQUFjLEdBQUcsS0FBSztBQUN0QixvQkFBZ0IsTUFBTSxTQUFTLEtBQUs7QUFBQSxFQUN0QztBQUNBLFVBQVEsUUFBUTtBQUNoQixVQUFRLE9BQU87QUFDZixXQUFTLGNBQWMsT0FBeUI7QUFDOUMsb0JBQWdCLEtBQUssTUFBTSxpQkFBaUIsUUFBUSxlQUFlLE1BQU0sS0FBSyxJQUFJLE1BQU0sT0FBTztBQUFBLEVBQ2pHO0FBQ0EsV0FBUyxxQkFBcUIsT0FBb0M7QUFDaEUsb0JBQWdCLEtBQUssZUFBZSxNQUFNLE1BQU0sQ0FBQztBQUFBLEVBQ25EO0FBQ0EsYUFBVyxpQkFBaUIsU0FBUyxhQUFhO0FBQ2xELGFBQVcsaUJBQWlCLHNCQUFzQixvQkFBb0I7QUFFdEUsTUFBSTtBQUNGLFVBQU0sSUFBSSxRQUFRLG9CQUFvQixRQUFRO0FBQUEsRUFDaEQsVUFBRTtBQVdBLFFBQUksSUFBSSxRQUFRLGVBQWUsZUFBZTtBQUM1QyxVQUFJLFFBQVEsYUFBYTtBQUFBLElBQzNCO0FBQ0EsUUFBSSxRQUFRLFVBQVUsaUJBQWlCO0FBQ3JDLGNBQVEsUUFBUTtBQUFBLElBQ2xCO0FBQ0EsUUFBSSxRQUFRLFNBQVMsZ0JBQWdCO0FBQ25DLGNBQVEsT0FBTztBQUFBLElBQ2pCO0FBQ0EsZUFBVyxvQkFBb0IsU0FBUyxhQUFhO0FBQ3JELGVBQVcsb0JBQW9CLHNCQUFzQixvQkFBb0I7QUFBQSxFQUMzRTtBQUVBLFFBQU0sV0FBVyxPQUFPLE9BQU8sSUFBSSxRQUFRLFNBQVMsUUFBUTtBQUU1RCxNQUFJO0FBQ0osTUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVU7QUFDOUIsVUFBTSxTQUFTLGdCQUFnQixLQUFLLElBQUksRUFBRSxLQUFLO0FBQy9DLDRCQUF3QixVQUFVO0FBQUEsRUFDcEM7QUFFQSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsV0FBVyxJQUFJLFFBQVEsZUFBZSxJQUFJLFFBQVE7QUFBQSxJQUNsRDtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7QUFlTyxTQUFTLG1DQUFtQyxVQUEwQjtBQUMzRSxTQUFPLFdBQVcsUUFBUTtBQUc1QjsiLAogICJuYW1lcyI6IFtdCn0K
|