obsidian-integration-testing 9.2.0 → 9.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -5
- package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
- package/dist/lib/cjs/eval-in-obsidian.d.cts +44 -1
- package/dist/lib/cjs/leftover-cleanup.cjs +19 -1
- package/dist/lib/cjs/leftover-cleanup.d.cts +53 -0
- package/dist/lib/cjs/library.cjs +1 -1
- package/dist/lib/cjs/namespace-bootstrap.cjs +20 -2
- package/dist/lib/cjs/obsidian-instance.cjs +5 -2
- package/dist/lib/cjs/obsidian-instance.d.cts +7 -0
- package/dist/lib/cjs/obsidian-metadata.cjs +5 -2
- package/dist/lib/cjs/parent-liveness.cjs +93 -0
- package/dist/lib/cjs/parent-liveness.d.cts +76 -0
- package/dist/lib/cjs/transport-appium.cjs +18 -2
- package/dist/lib/cjs/transport-appium.d.cts +8 -1
- package/dist/lib/cjs/transport-desktop-cdp.cjs +22 -1
- package/dist/lib/cjs/transport-desktop-cdp.d.cts +12 -0
- package/dist/lib/cjs/transport-factory.cjs +27 -13
- package/dist/lib/esm/eval-in-obsidian.d.mts +44 -1
- package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
- package/dist/lib/esm/leftover-cleanup.d.mts +53 -0
- package/dist/lib/esm/leftover-cleanup.mjs +18 -1
- package/dist/lib/esm/library.mjs +1 -1
- package/dist/lib/esm/namespace-bootstrap.mjs +20 -2
- package/dist/lib/esm/obsidian-instance.d.mts +7 -0
- package/dist/lib/esm/obsidian-instance.mjs +5 -2
- package/dist/lib/esm/obsidian-metadata.mjs +5 -2
- package/dist/lib/esm/parent-liveness.d.mts +76 -0
- package/dist/lib/esm/parent-liveness.mjs +67 -0
- package/dist/lib/esm/transport-appium.d.mts +8 -1
- package/dist/lib/esm/transport-appium.mjs +18 -2
- package/dist/lib/esm/transport-desktop-cdp.d.mts +12 -0
- package/dist/lib/esm/transport-desktop-cdp.mjs +22 -1
- package/dist/lib/esm/transport-factory.mjs +28 -15
- package/dist/obsidian-integration-testing-9.2.2.tgz +0 -0
- package/package.json +1 -1
- package/dist/obsidian-integration-testing-9.2.0.tgz +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var parent_liveness_exports = {};
|
|
20
|
+
__export(parent_liveness_exports, {
|
|
21
|
+
PARENT_LIVENESS_HOST: () => PARENT_LIVENESS_HOST,
|
|
22
|
+
buildParentLivenessWatchdogExpr: () => buildParentLivenessWatchdogExpr,
|
|
23
|
+
startParentLivenessServer: () => startParentLivenessServer
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(parent_liveness_exports);
|
|
26
|
+
var import_node_net = require("node:net");
|
|
27
|
+
const PARENT_LIVENESS_HOST = "127.0.0.1";
|
|
28
|
+
function buildParentLivenessWatchdogExpr(port) {
|
|
29
|
+
return `(function() {
|
|
30
|
+
var FLAG = '__obsidianIntegrationTestingParentLiveness';
|
|
31
|
+
if (window[FLAG]) { return 'already-armed'; }
|
|
32
|
+
var net;
|
|
33
|
+
try {
|
|
34
|
+
net = window.require('node:net');
|
|
35
|
+
} catch (nodePrefixError) {
|
|
36
|
+
try {
|
|
37
|
+
net = window.require('net');
|
|
38
|
+
} catch (barePrefixError) {
|
|
39
|
+
return 'unavailable';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
var socket = net.connect(${String(port)}, '${PARENT_LIVENESS_HOST}');
|
|
43
|
+
window[FLAG] = socket;
|
|
44
|
+
var isConnected = false;
|
|
45
|
+
socket.on('connect', function() { isConnected = true; });
|
|
46
|
+
socket.on('error', function() { /* Handled by the close listener below. */ });
|
|
47
|
+
socket.on('close', function() {
|
|
48
|
+
if (!isConnected) { return; }
|
|
49
|
+
try {
|
|
50
|
+
window.electronWindow.destroy();
|
|
51
|
+
} catch (destroyError) {
|
|
52
|
+
window.close();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return 'armed';
|
|
56
|
+
})()`;
|
|
57
|
+
}
|
|
58
|
+
async function startParentLivenessServer() {
|
|
59
|
+
const server = (0, import_node_net.createServer)((socket) => {
|
|
60
|
+
socket.unref();
|
|
61
|
+
socket.on("error", () => {
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
server.unref();
|
|
65
|
+
const port = await listenOnFreeLoopbackPort(server);
|
|
66
|
+
return {
|
|
67
|
+
close() {
|
|
68
|
+
server.close();
|
|
69
|
+
},
|
|
70
|
+
port
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async function listenOnFreeLoopbackPort(server) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
server.once("error", reject);
|
|
76
|
+
server.listen(0, PARENT_LIVENESS_HOST, () => {
|
|
77
|
+
const address = server.address();
|
|
78
|
+
if (address === null || typeof address === "string") {
|
|
79
|
+
server.close();
|
|
80
|
+
reject(new Error("Failed to determine the parent-liveness port."));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
resolve(address.port);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
88
|
+
0 && (module.exports = {
|
|
89
|
+
PARENT_LIVENESS_HOST,
|
|
90
|
+
buildParentLivenessWatchdogExpr,
|
|
91
|
+
startParentLivenessServer
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3BhcmVudC1saXZlbmVzcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRpZXMgYSBoYXJuZXNzLW93bmVkIE9ic2lkaWFuIGluc3RhbmNlJ3MgbGlmZXRpbWUgdG8gdGhlIGhhcm5lc3MgcHJvY2VzcyB0aGF0XG4gKiBsYXVuY2hlZCBpdCwgaW4gdGhlIG9uZSBkaXJlY3Rpb24gdGhlIG9wZXJhdGluZyBzeXN0ZW0gd2lsbCBub3QgZG8gZm9yIHVzLlxuICpcbiAqIFRoZSBvd25lZCBpbnN0YW5jZSBpcyBhbHJlYWR5IGEgY2hpbGQgb2YgdGhlIGhhcm5lc3MgcHJvY2VzcywgYnV0IHRoYXQgbGlua1xuICogY2FycmllcyBubyBsaWZldGltZSBndWFyYW50ZWUuIFdpbmRvd3MgbmV2ZXIgcHJvcGFnYXRlcyBhIHBhcmVudCdzIGRlYXRoIHRvXG4gKiBpdHMgY2hpbGRyZW4gXHUyMDE0IGFuIG9ycGhhbiBzaW1wbHkga2VlcHMgcnVubmluZyB3aXRoIGEgc3RhbGUgcGFyZW50IGlkIFx1MjAxNCBhbmQgb25cbiAqIFBPU0lYIGEgYFNJR0tJTExgIGFpbWVkIGF0IGEgc2luZ2xlIHBpZCBuZXZlciBjYXNjYWRlcyBlaXRoZXIuIFRoZSBpbnN0YW5jZSBpc1xuICogYWRkaXRpb25hbGx5IHNwYXduZWQgYGRldGFjaGVkYCwgc28gaXQgaXMgbm90IGV2ZW4gaW4gdGhlIGhhcm5lc3MncyBwcm9jZXNzXG4gKiBncm91cC4gVGVhcmRvd24gdGhlcmVmb3JlIHJlbGllcyBlbnRpcmVseSBvbiB0aGUgaGFybmVzcyBydW5uaW5nIGl0cyBvd25cbiAqIGNsZWFudXAgKGBraWxsUHJvY2Vzc1RyZWVgIGZyb20gYW4gYGV4aXRgL3NpZ25hbCBoYW5kbGVyKSwgd2hpY2ggaXMgZXhhY3RseVxuICogd2hhdCBhIGBTSUdLSUxMYCwgYSBUYXNrIE1hbmFnZXIga2lsbCwgb3IgYW4gSURFIHN0b3AgYnV0dG9uIGRlbmllcyBpdC4gRXZlcnlcbiAqIHN1Y2gga2lsbCBsZWFrcyBhIGhpZGRlbiBPYnNpZGlhbiBob2xkaW5nIGEgdXNlci1kYXRhIGRpciBhbmQgYSBDRFAgcG9ydCwgYW5kXG4gKiB0aGV5IGFjY3VtdWxhdGU6IHRoZSBuZXh0IHJ1biBwaWNrcyBhIGZyZXNoIHRlbXAgZGlyIGFuZCBhIGZyZWUgcG9ydCwgc29cbiAqIG5vdGhpbmcgY29sbGlkZXMgYW5kIG5vdGhpbmcgY29tcGxhaW5zLlxuICpcbiAqIFRoZSBndWFyYW50ZWVkIGZpeCBpcyBhbiBPUyBwcmltaXRpdmUgXHUyMDE0IGEgV2luZG93cyBKb2IgT2JqZWN0IHdpdGhcbiAqIGBKT0JfT0JKRUNUX0xJTUlUX0tJTExfT05fSk9CX0NMT1NFYCwgb3IgYHByY3RsKFBSX1NFVF9QREVBVEhTSUcpYCBvbiBMaW51eCBcdTIwMTRcbiAqIGJ1dCBuZWl0aGVyIGlzIHJlYWNoYWJsZSBmcm9tIE5vZGUgd2l0aG91dCBhIG5hdGl2ZSBhZGRvbiwgd2hpY2ggaXMgZmFyIHRvb1xuICogaGVhdnkgYSBkZXBlbmRlbmN5IGZvciB0aGlzIGhhcm5lc3MuXG4gKlxuICogU28gd2UgdXNlIHRoZSBvbmUgY3Jvc3MtcGxhdGZvcm0gcmVzb3VyY2UgdGhlIGtlcm5lbCAqZG9lcyogcmVjbGFpbVxuICogZGV0ZXJtaW5pc3RpY2FsbHkgb24gcHJvY2VzcyBkZWF0aDogYSBzb2NrZXQuIFRoZSBoYXJuZXNzIGxpc3RlbnMgb24gYVxuICogbG9vcGJhY2sgcG9ydCBhbmQgdGhlIGluc3RhbmNlJ3MgcmVuZGVyZXIgY29ubmVjdHMgdG8gaXQuIEhvd2V2ZXIgdGhlIGhhcm5lc3NcbiAqIGRpZXMgXHUyMDE0IGNsZWFubHksIGBTSUdLSUxMYGVkLCBvciBjcmFzaGVkIFx1MjAxNCB0aGUga2VybmVsIGNsb3NlcyBpdHMgZW5kLCB0aGVcbiAqIHJlbmRlcmVyIHNlZXMgYGNsb3NlYCwgYW5kIHRoZSB3aW5kb3cgZGVzdHJveXMgaXRzZWxmLiBObyBwb2xsaW5nLCBub1xuICogaGVhcnRiZWF0IGludGVydmFsLCBubyB0aW1lb3V0IHRvIHR1bmUuXG4gKlxuICogRGVsaWJlcmF0ZWx5IGZhaWwtb3BlbjogdGhlIHJlbmRlcmVyIG9ubHkgYXJtcyB0aGUgZGVzdHJveSBoYW5kbGVyIGFmdGVyIHRoZVxuICogY29ubmVjdGlvbiBpcyBhY3R1YWxseSBlc3RhYmxpc2hlZC4gQSB3YXRjaGRvZyB0aGF0IGNhbm5vdCByZWFjaCB0aGUgaGFybmVzc1xuICogbGVhdmVzIHRoZSBpbnN0YW5jZSBydW5uaW5nIHJhdGhlciB0aGFuIGtpbGxpbmcgYSB3aW5kb3cgdGhlIGRldmVsb3BlciBpc1xuICogd29ya2luZyBpbi5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFNlcnZlciB9IGZyb20gJ25vZGU6bmV0JztcblxuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSAnbm9kZTpuZXQnO1xuXG4vKipcbiAqIEEgbGlzdGVuaW5nIGxvb3BiYWNrIHNlcnZlciB3aG9zZSBhY2NlcHRlZCBjb25uZWN0aW9ucyBhY3QgYXMgbGl2ZW5lc3MgdG9rZW5zXG4gKiBmb3IgdGhlIGhhcm5lc3MgcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJlbnRMaXZlbmVzc1NlcnZlciB7XG4gIC8qKiBTdG9wcyBsaXN0ZW5pbmcgYW5kIGRyb3BzIGV2ZXJ5IGFjY2VwdGVkIGNvbm5lY3Rpb24uICovXG4gIGNsb3NlKCk6IHZvaWQ7XG5cbiAgLyoqIFRoZSBsb29wYmFjayBwb3J0IHRoZSByZW5kZXJlciB3YXRjaGRvZyBzaG91bGQgY29ubmVjdCBiYWNrIHRvLiAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG59XG5cbi8qKlxuICogTG9vcGJhY2sgaG9zdCB0aGUgbGl2ZW5lc3Mgc2VydmVyIGJpbmRzIHRvLiBOZXZlciBleHBvc2VkIG9mZi1tYWNoaW5lLlxuICovXG5leHBvcnQgY29uc3QgUEFSRU5UX0xJVkVORVNTX0hPU1QgPSAnMTI3LjAuMC4xJztcblxuLyoqXG4gKiBCdWlsZHMgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGVkIGluIHRoZSBvd25lZCBpbnN0YW5jZSdzIHJlbmRlcmVyIHRvIGFybSB0aGVcbiAqIHdhdGNoZG9nLlxuICpcbiAqIFdyaXR0ZW4gaW4gRVM1IHN0eWxlIChgdmFyYCwgYGZ1bmN0aW9uYCkgd2l0aCBubyBvcHRpb25hbCBjaGFpbmluZywgbWF0Y2hpbmdcbiAqIHtAbGluayBESVNNSVNTX1RSVVNUX0RJQUxPR19FWFBSfTogdGhlIHNhbWUgZXhwcmVzc2lvbiBoYXMgdG8gcGFyc2Ugb24gdGhlXG4gKiBDaHJvbWl1bSA4MC1lcmEgcmVuZGVyZXJzIG9mIHRoZSBvbGRlc3Qgc3VwcG9ydGVkIE9ic2lkaWFuIHZlcnNpb25zIChMMjYpLlxuICpcbiAqIEFybWluZyBpcyBpZGVtcG90ZW50IFx1MjAxNCBhIHNlY29uZCBldmFsdWF0aW9uIGZpbmRzIHRoZSBzdG9yZWQgc29ja2V0IGFuZFxuICogcmV0dXJucyB3aXRob3V0IG9wZW5pbmcgYW5vdGhlciBjb25uZWN0aW9uLCBzbyBhIHJldHJpZWQgcmVhZGluZXNzIHBhc3MgZG9lc1xuICogbm90IHBpbGUgdXAgc29ja2V0cy5cbiAqXG4gKiBAcGFyYW0gcG9ydCAtIFRoZSBsb29wYmFjayBwb3J0IHJldHVybmVkIGJ5IHtAbGluayBzdGFydFBhcmVudExpdmVuZXNzU2VydmVyfS5cbiAqIEByZXR1cm5zIFRoZSBleHByZXNzaW9uIHRvIGV2YWx1YXRlLCB5aWVsZGluZyBgJ2FybWVkJ2AsIGAnYWxyZWFkeS1hcm1lZCdgLCBvciBgJ3VuYXZhaWxhYmxlJ2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBhcmVudExpdmVuZXNzV2F0Y2hkb2dFeHByKHBvcnQ6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBgKGZ1bmN0aW9uKCkge1xuICB2YXIgRkxBRyA9ICdfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nUGFyZW50TGl2ZW5lc3MnO1xuICBpZiAod2luZG93W0ZMQUddKSB7IHJldHVybiAnYWxyZWFkeS1hcm1lZCc7IH1cbiAgdmFyIG5ldDtcbiAgdHJ5IHtcbiAgICBuZXQgPSB3aW5kb3cucmVxdWlyZSgnbm9kZTpuZXQnKTtcbiAgfSBjYXRjaCAobm9kZVByZWZpeEVycm9yKSB7XG4gICAgdHJ5IHtcbiAgICAgIG5ldCA9IHdpbmRvdy5yZXF1aXJlKCduZXQnKTtcbiAgICB9IGNhdGNoIChiYXJlUHJlZml4RXJyb3IpIHtcbiAgICAgIHJldHVybiAndW5hdmFpbGFibGUnO1xuICAgIH1cbiAgfVxuICB2YXIgc29ja2V0ID0gbmV0LmNvbm5lY3QoJHtTdHJpbmcocG9ydCl9LCAnJHtQQVJFTlRfTElWRU5FU1NfSE9TVH0nKTtcbiAgd2luZG93W0ZMQUddID0gc29ja2V0O1xuICB2YXIgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24oKSB7IGlzQ29ubmVjdGVkID0gdHJ1ZTsgfSk7XG4gIHNvY2tldC5vbignZXJyb3InLCBmdW5jdGlvbigpIHsgLyogSGFuZGxlZCBieSB0aGUgY2xvc2UgbGlzdGVuZXIgYmVsb3cuICovIH0pO1xuICBzb2NrZXQub24oJ2Nsb3NlJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKCFpc0Nvbm5lY3RlZCkgeyByZXR1cm47IH1cbiAgICB0cnkge1xuICAgICAgd2luZG93LmVsZWN0cm9uV2luZG93LmRlc3Ryb3koKTtcbiAgICB9IGNhdGNoIChkZXN0cm95RXJyb3IpIHtcbiAgICAgIHdpbmRvdy5jbG9zZSgpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiAnYXJtZWQnO1xufSkoKWA7XG59XG5cbi8qKlxuICogU3RhcnRzIHRoZSBsb29wYmFjayBsaXZlbmVzcyBzZXJ2ZXIgdGhlIG93bmVkIGluc3RhbmNlJ3MgcmVuZGVyZXIgY29ubmVjdHNcbiAqIGJhY2sgdG8uXG4gKlxuICogVGhlIHNlcnZlciBhbmQgZXZlcnkgYWNjZXB0ZWQgc29ja2V0IGFyZSBgdW5yZWZgZWQsIHNvIGhvbGRpbmcgYSB3YXRjaGRvZ1xuICogY29ubmVjdGlvbiBvcGVuIG5ldmVyIGtlZXBzIHRoZSBoYXJuZXNzIHByb2Nlc3MgYWxpdmUgb24gaXRzIG93biBcdTIwMTQgdGhlXG4gKiBjb25uZWN0aW9uIGlzIGEgdG9rZW4gdGhlIGtlcm5lbCByZWNsYWltcywgbm90IHdvcmsgdG8gd2FpdCBvbi5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSByZXNvbHZpbmcgdG8gdGhlIGxpc3RlbmluZyB7QGxpbmsgUGFyZW50TGl2ZW5lc3NTZXJ2ZXJ9LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQYXJlbnRMaXZlbmVzc1NlcnZlcigpOiBQcm9taXNlPFBhcmVudExpdmVuZXNzU2VydmVyPiB7XG4gIGNvbnN0IHNlcnZlciA9IGNyZWF0ZVNlcnZlcigoc29ja2V0KSA9PiB7XG4gICAgc29ja2V0LnVucmVmKCk7XG4gICAgLy8gVGhlIGNvbm5lY3Rpb24gY2FycmllcyBubyBkYXRhIFx1MjAxNCBpdCBleGlzdHMgb25seSBzbyBpdHMgY2xvc2UgaXMgb2JzZXJ2YWJsZS5cbiAgICBzb2NrZXQub24oJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgLy8gQSByZW5kZXJlciB0b3JuIGRvd24gbWlkLWNvbm5lY3Rpb24gcmVzZXRzIHJhdGhlciB0aGFuIGNsb3Nlczsgbm90IGFuIGVycm9yIGhlcmUuXG4gICAgfSk7XG4gIH0pO1xuICBzZXJ2ZXIudW5yZWYoKTtcblxuICBjb25zdCBwb3J0ID0gYXdhaXQgbGlzdGVuT25GcmVlTG9vcGJhY2tQb3J0KHNlcnZlcik7XG4gIHJldHVybiB7XG4gICAgY2xvc2UoKTogdm9pZCB7XG4gICAgICBzZXJ2ZXIuY2xvc2UoKTtcbiAgICB9LFxuICAgIHBvcnRcbiAgfTtcbn1cblxuLyoqXG4gKiBCaW5kcyB0aGUgc2VydmVyIHRvIGFuIGVwaGVtZXJhbCBsb29wYmFjayBwb3J0IGFuZCByZXBvcnRzIHdoaWNoIG9uZSBpdCBnb3QuXG4gKlxuICogQHBhcmFtIHNlcnZlciAtIFRoZSBzZXJ2ZXIgdG8gYmluZC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgYXNzaWduZWQgcG9ydC5cbiAqIEB0aHJvd3MgSWYgdGhlIHNlcnZlciByZXBvcnRzIGFuIGVycm9yIGJlZm9yZSBsaXN0ZW5pbmcsIG9yIGJpbmRzIHRvIGEgcGlwZSByYXRoZXIgdGhhbiBhIHBvcnQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxpc3Rlbk9uRnJlZUxvb3BiYWNrUG9ydChzZXJ2ZXI6IFNlcnZlcik6IFByb21pc2U8bnVtYmVyPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTxudW1iZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzZXJ2ZXIub25jZSgnZXJyb3InLCByZWplY3QpO1xuICAgIHNlcnZlci5saXN0ZW4oMCwgUEFSRU5UX0xJVkVORVNTX0hPU1QsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgaWYgKGFkZHJlc3MgPT09IG51bGwgfHwgdHlwZW9mIGFkZHJlc3MgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKCdGYWlsZWQgdG8gZGV0ZXJtaW5lIHRoZSBwYXJlbnQtbGl2ZW5lc3MgcG9ydC4nKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlc29sdmUoYWRkcmVzcy5wb3J0KTtcbiAgICB9KTtcbiAgfSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQXNDQSxzQkFBNkI7QUFpQnRCLE1BQU0sdUJBQXVCO0FBaUI3QixTQUFTLGdDQUFnQyxNQUFzQjtBQUNwRSxTQUFPO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsNkJBYW9CLE9BQU8sSUFBSSxDQUFDLE1BQU0sb0JBQW9CO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWVuRTtBQVlBLGVBQXNCLDRCQUEyRDtBQUMvRSxRQUFNLGFBQVMsOEJBQWEsQ0FBQyxXQUFXO0FBQ3RDLFdBQU8sTUFBTTtBQUViLFdBQU8sR0FBRyxTQUFTLE1BQU07QUFBQSxJQUV6QixDQUFDO0FBQUEsRUFDSCxDQUFDO0FBQ0QsU0FBTyxNQUFNO0FBRWIsUUFBTSxPQUFPLE1BQU0seUJBQXlCLE1BQU07QUFDbEQsU0FBTztBQUFBLElBQ0wsUUFBYztBQUNaLGFBQU8sTUFBTTtBQUFBLElBQ2Y7QUFBQSxJQUNBO0FBQUEsRUFDRjtBQUNGO0FBU0EsZUFBZSx5QkFBeUIsUUFBaUM7QUFDdkUsU0FBTyxJQUFJLFFBQWdCLENBQUMsU0FBUyxXQUFXO0FBQzlDLFdBQU8sS0FBSyxTQUFTLE1BQU07QUFDM0IsV0FBTyxPQUFPLEdBQUcsc0JBQXNCLE1BQU07QUFDM0MsWUFBTSxVQUFVLE9BQU8sUUFBUTtBQUMvQixVQUFJLFlBQVksUUFBUSxPQUFPLFlBQVksVUFBVTtBQUNuRCxlQUFPLE1BQU07QUFDYixlQUFPLElBQUksTUFBTSwrQ0FBK0MsQ0FBQztBQUNqRTtBQUFBLE1BQ0Y7QUFDQSxjQUFRLFFBQVEsSUFBSTtBQUFBLElBQ3RCLENBQUM7QUFBQSxFQUNILENBQUM7QUFDSDsiLAogICJuYW1lcyI6IFtdCn0K
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Ties a harness-owned Obsidian instance's lifetime to the harness process that
|
|
5
|
+
* launched it, in the one direction the operating system will not do for us.
|
|
6
|
+
*
|
|
7
|
+
* The owned instance is already a child of the harness process, but that link
|
|
8
|
+
* carries no lifetime guarantee. Windows never propagates a parent's death to
|
|
9
|
+
* its children — an orphan simply keeps running with a stale parent id — and on
|
|
10
|
+
* POSIX a `SIGKILL` aimed at a single pid never cascades either. The instance is
|
|
11
|
+
* additionally spawned `detached`, so it is not even in the harness's process
|
|
12
|
+
* group. Teardown therefore relies entirely on the harness running its own
|
|
13
|
+
* cleanup (`killProcessTree` from an `exit`/signal handler), which is exactly
|
|
14
|
+
* what a `SIGKILL`, a Task Manager kill, or an IDE stop button denies it. Every
|
|
15
|
+
* such kill leaks a hidden Obsidian holding a user-data dir and a CDP port, and
|
|
16
|
+
* they accumulate: the next run picks a fresh temp dir and a free port, so
|
|
17
|
+
* nothing collides and nothing complains.
|
|
18
|
+
*
|
|
19
|
+
* The guaranteed fix is an OS primitive — a Windows Job Object with
|
|
20
|
+
* `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`, or `prctl(PR_SET_PDEATHSIG)` on Linux —
|
|
21
|
+
* but neither is reachable from Node without a native addon, which is far too
|
|
22
|
+
* heavy a dependency for this harness.
|
|
23
|
+
*
|
|
24
|
+
* So we use the one cross-platform resource the kernel *does* reclaim
|
|
25
|
+
* deterministically on process death: a socket. The harness listens on a
|
|
26
|
+
* loopback port and the instance's renderer connects to it. However the harness
|
|
27
|
+
* dies — cleanly, `SIGKILL`ed, or crashed — the kernel closes its end, the
|
|
28
|
+
* renderer sees `close`, and the window destroys itself. No polling, no
|
|
29
|
+
* heartbeat interval, no timeout to tune.
|
|
30
|
+
*
|
|
31
|
+
* Deliberately fail-open: the renderer only arms the destroy handler after the
|
|
32
|
+
* connection is actually established. A watchdog that cannot reach the harness
|
|
33
|
+
* leaves the instance running rather than killing a window the developer is
|
|
34
|
+
* working in.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* A listening loopback server whose accepted connections act as liveness tokens
|
|
38
|
+
* for the harness process.
|
|
39
|
+
*/
|
|
40
|
+
export interface ParentLivenessServer {
|
|
41
|
+
/** Stops listening and drops every accepted connection. */
|
|
42
|
+
close(): void;
|
|
43
|
+
/** The loopback port the renderer watchdog should connect back to. */
|
|
44
|
+
readonly port: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Loopback host the liveness server binds to. Never exposed off-machine.
|
|
48
|
+
*/
|
|
49
|
+
export declare const PARENT_LIVENESS_HOST = "127.0.0.1";
|
|
50
|
+
/**
|
|
51
|
+
* Builds the expression evaluated in the owned instance's renderer to arm the
|
|
52
|
+
* watchdog.
|
|
53
|
+
*
|
|
54
|
+
* Written in ES5 style (`var`, `function`) with no optional chaining, matching
|
|
55
|
+
* {@link DISMISS_TRUST_DIALOG_EXPR}: the same expression has to parse on the
|
|
56
|
+
* Chromium 80-era renderers of the oldest supported Obsidian versions (L26).
|
|
57
|
+
*
|
|
58
|
+
* Arming is idempotent — a second evaluation finds the stored socket and
|
|
59
|
+
* returns without opening another connection, so a retried readiness pass does
|
|
60
|
+
* not pile up sockets.
|
|
61
|
+
*
|
|
62
|
+
* @param port - The loopback port returned by {@link startParentLivenessServer}.
|
|
63
|
+
* @returns The expression to evaluate, yielding `'armed'`, `'already-armed'`, or `'unavailable'`.
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildParentLivenessWatchdogExpr(port: number): string;
|
|
66
|
+
/**
|
|
67
|
+
* Starts the loopback liveness server the owned instance's renderer connects
|
|
68
|
+
* back to.
|
|
69
|
+
*
|
|
70
|
+
* The server and every accepted socket are `unref`ed, so holding a watchdog
|
|
71
|
+
* connection open never keeps the harness process alive on its own — the
|
|
72
|
+
* connection is a token the kernel reclaims, not work to wait on.
|
|
73
|
+
*
|
|
74
|
+
* @returns A {@link Promise} resolving to the listening {@link ParentLivenessServer}.
|
|
75
|
+
*/
|
|
76
|
+
export declare function startParentLivenessServer(): Promise<ParentLivenessServer>;
|
|
@@ -396,12 +396,19 @@ class AppiumTransport {
|
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
398
|
/**
|
|
399
|
-
* Removes a vault directory from the device over `adb
|
|
399
|
+
* Removes a vault directory from the device over `adb`, and CHECKS that it is
|
|
400
|
+
* actually gone.
|
|
400
401
|
*
|
|
401
402
|
* Best-effort: a failure is logged, not thrown, so a teardown problem never
|
|
402
403
|
* masks the test result. The next run's start-of-run sweep picks up whatever
|
|
403
404
|
* this could not remove.
|
|
404
405
|
*
|
|
406
|
+
* The check is the point. `rm -rf` runs with `shouldIgnoreExitCode`, so an
|
|
407
|
+
* unremoved directory used to leave no trace at all — which is how runs that
|
|
408
|
+
* passed end to end were still found to be leaking a vault apiece, invisibly,
|
|
409
|
+
* until someone counted the directories on the device by hand. A leak is now
|
|
410
|
+
* named in the log at the moment it happens.
|
|
411
|
+
*
|
|
405
412
|
* @param deviceVaultPath - The device-side vault directory path.
|
|
406
413
|
*/
|
|
407
414
|
async removeDeviceVaultDir(deviceVaultPath) {
|
|
@@ -411,6 +418,15 @@ class AppiumTransport {
|
|
|
411
418
|
["adb", "-s", this.deviceId, "shell", "rm", "-rf", deviceVaultPath],
|
|
412
419
|
{ isQuiet: true, shouldIgnoreExitCode: true, timeoutInMilliseconds: ADB_VAULT_REMOVE_TIMEOUT_IN_MILLISECONDS }
|
|
413
420
|
);
|
|
421
|
+
const listing = await (0, import_exec.exec)(
|
|
422
|
+
["adb", "-s", this.deviceId, "shell", "ls", "-d", deviceVaultPath],
|
|
423
|
+
{ isQuiet: true, shouldIgnoreExitCode: true, timeoutInMilliseconds: ADB_VAULT_REMOVE_TIMEOUT_IN_MILLISECONDS }
|
|
424
|
+
);
|
|
425
|
+
if (listing.includes(deviceVaultPath)) {
|
|
426
|
+
(0, import_log.log)(
|
|
427
|
+
`[appium-transport] Warning: ${deviceVaultPath} survived removal and is now leaked residue. The next run's start-of-run sweep will retry it.`
|
|
428
|
+
);
|
|
429
|
+
}
|
|
414
430
|
} catch (error) {
|
|
415
431
|
(0, import_log.log)(`[appium-transport] Vault directory removal failed (non-fatal): ${String(error)}`);
|
|
416
432
|
}
|
|
@@ -456,4 +472,4 @@ function extractVaultName(vaultPath) {
|
|
|
456
472
|
AppiumTransport,
|
|
457
473
|
DEFAULT_ANDROID_VAULT_BASE_PATH
|
|
458
474
|
});
|
|
459
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1hcHBpdW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBcHBpdW0gdHJhbnNwb3J0IFx1MjAxNCBldmFsdWF0ZXMgZXhwcmVzc2lvbnMgaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSB2aWEgV2ViVmlld1xuICogSmF2YVNjcmlwdCBpbmplY3Rpb24uIE1hbmFnZXMgdmF1bHQgbGlmZWN5Y2xlIHZpYSBsb2NhbFN0b3JhZ2UgYW5kIGZpbGUgcHVzaC5cbiAqXG4gKiBDb25maWd1cmVkIHZpYSBgZW52aXJvbm1lbnRPcHRpb25zLm9ic2lkaWFuVHJhbnNwb3J0YCBpbiB2aXRlc3QgY29uZmlnOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHZpdGVzdC5jb25maWcudHNcbiAqIGVudmlyb25tZW50T3B0aW9uczoge1xuICogICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICogICAgIHR5cGU6ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScsXG4gKiAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAqICAgICBhdmROYW1lOiAnb2JzaWRpYW5fdGVzdCcsXG4gKiAgIH0sXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBGb3IgQnJvd3NlclN0YWNrLCBzZXQgYGFwcGl1bVVybGAgdG8gdGhlIEJyb3dzZXJTdGFjayBodWIgVVJMXG4gKiBcdTIwMTQgdGhlIHRyYW5zcG9ydCBpdHNlbGYgaXMgaHViLWFnbm9zdGljLlxuICpcbiAqICMjIEhvdyB2YXVsdCByZWdpc3RyYXRpb24gd29ya3Mgb24gbW9iaWxlXG4gKlxuICogT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHQgcmVnaXN0cnkgaW4gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYDpcbiAqXG4gKiAtIGBtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzYCBcdTIwMTQgSlNPTiBhcnJheSBvZiByZWdpc3RlcmVkIHZhdWx0IHBhdGhzXG4gKiAtIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgIFx1MjAxNCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2YXVsdCBwYXRoXG4gKiAtIGBlbmFibGUtcGx1Z2luLTx2YXVsdFBhdGg+YCBcdTIwMTQgYFwidHJ1ZVwiYCB0byBlbmFibGUgdGhlIHBsdWdpbiBzeXN0ZW0gZm9yIHRoZSB2YXVsdFxuICpcbiAqIFRvIHJlZ2lzdGVyIGEgdmF1bHQgcHJvZ3JhbW1hdGljYWxseSAod2l0aG91dCBVSSBpbnRlcmFjdGlvbik6XG4gKlxuICogMS4gUHVzaCB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIChlLmcuIGAvc2RjYXJkL0RvY3VtZW50cy88TmFtZT4vLm9ic2lkaWFuL2FwcC5qc29uYClcbiAqIDIuIFN3aXRjaCB0byBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dFxuICogMy4gU2V0IHRoZSBsb2NhbFN0b3JhZ2UgZW50cmllc1xuICogNC4gQ2FsbCBgbG9jYXRpb24ucmVsb2FkKClgIFx1MjAxNCBPYnNpZGlhbiByZS1yZWFkcyBsb2NhbFN0b3JhZ2UgYW5kIG9wZW5zIHRoZSB2YXVsdFxuICpcbiAqIFRoaXMgYXZvaWRzIHRoZSBvbmJvYXJkaW5nIGZsb3cgZW50aXJlbHkuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBCcm93c2VyIH0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgcm0sXG4gIHdyaXRlRmlsZVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHtcbiAgQ29uc29sZUNhcHR1cmVIYW5kbGUsXG4gIE9ic2lkaWFuVHJhbnNwb3J0LFxuICBUcmFuc3BvcnRFdmFsT3B0aW9uc1xufSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuXG5pbXBvcnQgeyBleGVjIH0gZnJvbSAnLi9leGVjLmNqcyc7XG5pbXBvcnQgeyBURU1QX1ZBVUxUX0RJUl9QUkVGSVggfSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5cbi8qKlxuICogU2Vzc2lvbiBjb25uZWN0aW9uIGluZm8gcmV0dXJuZWQgYnkge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5nZXRTZXNzaW9uSW5mb30sXG4gKiB1c2VkIHRvIHJlYXR0YWNoIGZyb20gYW5vdGhlciBwcm9jZXNzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgLyoqIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuICovXG4gIGRldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBBcHBpdW0vV2ViRHJpdmVyIHNlc3Npb24gSUQuICovXG4gIHNlc3Npb25JZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBBcHBpdW0gdHJhbnNwb3J0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGl1bVRyYW5zcG9ydENvbmZpZyB7XG4gIC8qKlxuICAgKiBBcHAgcGFja2FnZSAoQW5kcm9pZCkgb3IgYnVuZGxlIElEIChpT1MpLlxuICAgKiBEZWZhdWx0cyB0byBgJ21kLm9ic2lkaWFuJ2AuXG4gICAqL1xuICBhcHBJZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFwcGl1bSBicm93c2VyL2RyaXZlciBpbnN0YW5jZS5cbiAgICogQ3JlYXRlZCBieSB0aGUgY29uc3VtZXIgdmlhIGUuZy4gV2ViRHJpdmVySU8ncyBgcmVtb3RlKClgLlxuICAgKi9cbiAgYnJvd3NlcjogQnJvd3NlcjtcblxuICAvKipcbiAgICogVGhlIGRldmljZSBVRElEIChlLmcuIGAnZW11bGF0b3ItNTU1NCdgKS5cbiAgICogVXNlZCBmb3IgYGFkYmAgY29tbWFuZHMgd2hlbiBwdXNoaW5nIGZpbGVzIHRvIHRoZSBkZXZpY2UuXG4gICAqL1xuICBkZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgdHJhbnNwb3J0IG93bnMgdGhlIEFwcGl1bSBzZXNzaW9uIGFuZCBzaG91bGQgZGVsZXRlIGl0IG9uXG4gICAqIHtAbGluayBBcHBpdW1UcmFuc3BvcnQuZGlzcG9zZX0uXG4gICAqXG4gICAqIGB0cnVlYCBmb3Igc2Vzc2lvbnMgY3JlYXRlZCB2aWEgYHJlbW90ZSgpYCAoZ2xvYmFsIHNldHVwKS5cbiAgICogYGZhbHNlYCBmb3Igc2Vzc2lvbnMgcmVhdHRhY2hlZCB2aWEgYGF0dGFjaCgpYCAodGVzdCB3b3JrZXJzKS5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICBpc1Nlc3Npb25Pd25lcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB3YWl0aW5nIGZvciBgYXBwLndvcmtzcGFjZS5sYXlvdXRSZWFkeWAgYWZ0ZXJcbiAgICogdGhlIHZhdWx0IGlzIChyZSlvcGVuZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA5MDAwMGBcbiAgICovXG4gIGxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUYXJnZXQgcGxhdGZvcm0uIERldGVybWluZXMgV2ViVmlldyBjb250ZXh0IG5hbWluZyBhbmQgZGV2aWNlIGZpbGUgcGF0aHMuXG4gICAqL1xuICBwbGF0Zm9ybTogJ2FuZHJvaWQnIHwgJ2lvcyc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgcmVnaXN0ZXJpbmcgYSB2YXVsdCBhbHNvIHBydW5lcyB0aGUgKipvdGhlcioqIGB0ZW1wLXZhdWx0LSpgXG4gICAqIHJlZ2lzdHJhdGlvbnMgZWFybGllciBydW5zIGxlZnQgaW4gT2JzaWRpYW4gTW9iaWxlJ3MgYGxvY2FsU3RvcmFnZWAuXG4gICAqXG4gICAqIFRoZSBkZXZpY2Utc2lkZSBkaXJlY3RvcmllcyBhcmUgc3dlcHQgYmVmb3JlIHRoZSBhcHAgbGF1bmNoZXMgKHNlZSB0aGVcbiAgICogZmFjdG9yeSk7IHRoaXMgcmVtb3ZlcyB0aGVpciBub3ctZGFuZ2xpbmcgcmVnaXN0cnkgZW50cmllcywgd2hpY2ggYXJlIHdoYXRcbiAgICogT2JzaWRpYW4gYWN0dWFsbHkgZW51bWVyYXRlcyBhdCBzdGFydHVwLiBVbnJlZ2lzdGVyaW5nIHRoaXMgcnVuJ3Mgb3duIHZhdWx0XG4gICAqIGlzIHVuYWZmZWN0ZWQgXHUyMDE0IHRoYXQgYWx3YXlzIGhhcHBlbnMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBCYXNlIHBhdGggb24gdGhlIGRldmljZSB3aGVyZSBPYnNpZGlhbiBzdG9yZXMgdmF1bHRzLlxuICAgKlxuICAgKiBEZWZhdWx0czpcbiAgICogLSBBbmRyb2lkOiBgL3NkY2FyZC9Eb2N1bWVudHMvYFxuICAgKiAtIGlPUzogYEBtZC5vYnNpZGlhbjpkb2N1bWVudHMvYFxuICAgKi9cbiAgdmF1bHRCYXNlUGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogVGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHdhaXRpbmcgZm9yIHRoZSBXZWJWaWV3IGNvbnRleHQgdG8gYmVjb21lIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgYDYwMDAwYFxuICAgKi9cbiAgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbn1cblxuY29uc3QgTk9fT1VUUFVUID0gJyhubyBvdXRwdXQpJztcbmNvbnN0IEFQUF9TVEFURV9GT1JFR1JPVU5EID0gNDtcbmNvbnN0IFdFQlZJRVdfQ09OVEVYVF9QUkVGSVggPSAnV0VCVklFV19tZC5vYnNpZGlhbic7XG5jb25zdCBXRUJWSUVXX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgREVGQVVMVF9XRUJWSUVXX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA2MDAwMDtcbmNvbnN0IExBWU9VVF9SRUFEWV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IERFRkFVTFRfTEFZT1VUX1JFQURZX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA5MDAwMDtcbmNvbnN0IEFQUF9SRVNUQVJUX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5jb25zdCBERUZBVUxUX0FQUF9JRCA9ICdtZC5vYnNpZGlhbic7XG5jb25zdCBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzAwMDA7XG5cbi8vIC0tLSBDb25zb2xlIGNhcHR1cmUgKExheWVyIDIgb2YgdGhlIHBsdWdpbi1sb2FkIGVycm9yIHN1cmZhY2luZywgc2VlIFQ4OCkgLS0tXG5jb25zdCBDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBRyA9ICdPSVRfQ0FQVFVSRSc7XG5jb25zdCBDT05TT0xFX0NBUFRVUkVfVEFJTF9NQVhfTEVOR1RIID0gODAwMDtcbmNvbnN0IEFEQl9MT0dfTUFSS0VSX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IExPR0NBVF9EVU1QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTAwMDA7XG4vKipcbiAqIGBhZGIgbG9nY2F0IC12IHRpbWVgIGxpbmVzIGxvb2sgbGlrZSBgTU0tREQgSEg6TU06U1MubW1tIExFVkVML1RBRyggUElEKTogbWVzc2FnZWAuXG4gKiBLZWVwIG9ubHkgdGhlIHRhZ3MgQ2hyb21pdW0vV2ViVmlldyByb3V0ZXMgSlMgYGNvbnNvbGUuKmAgb3V0cHV0IGFuZCB1bmNhdWdodFxuICogZXJyb3JzIHRvIChgY2hyb21pdW1gLCB0aGUgQ2FwYWNpdG9yIGNvbnNvbGUgYnJpZGdlLCBhbmQgbmF0aXZlIGBBbmRyb2lkUnVudGltZWApLlxuICovXG5jb25zdCBDT05TT0xFX0NBUFRVUkVfVEFHX1JFID0gL1xcLyg/OmNocm9taXVtfEFuZHJvaWRSdW50aW1lfENhcGFjaXRvclxcL0NvbnNvbGUpXFwoLztcblxuLyoqXG4gKiBCYXNlIHBhdGggb24gYW4gQW5kcm9pZCBkZXZpY2Ugd2hlcmUgT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHRzLlxuICpcbiAqIEV4cG9ydGVkIGJlY2F1c2UgdGhlIHRyYW5zcG9ydCBmYWN0b3J5IHN3ZWVwcyBsZWZ0b3ZlciB2YXVsdHMgZnJvbSBpdCBiZWZvcmVcbiAqIGEgdHJhbnNwb3J0IGV4aXN0cyAoc2VlIHRoZSByZXBvJ3MgTDMxKS5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfQU5EUk9JRF9WQVVMVF9CQVNFX1BBVEggPSAnL3NkY2FyZC9Eb2N1bWVudHMvJztcblxuY29uc3QgREVGQVVMVF9WQVVMVF9CQVNFX1BBVEg6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gIGFuZHJvaWQ6IERFRkFVTFRfQU5EUk9JRF9WQVVMVF9CQVNFX1BBVEgsXG4gIGlvczogJ0BtZC5vYnNpZGlhbjpkb2N1bWVudHMvJ1xufTtcblxuaW50ZXJmYWNlIExvYWRpbmdBcHAge1xuICB3b3Jrc3BhY2U/OiBMb2FkaW5nV29ya3NwYWNlO1xufVxuXG5pbnRlcmZhY2UgTG9hZGluZ1dvcmtzcGFjZSB7XG4gIGxheW91dFJlYWR5PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUcmFuc3BvcnQgdGhhdCBjb21tdW5pY2F0ZXMgd2l0aCBPYnNpZGlhbiBNb2JpbGUgdmlhIEFwcGl1bSBXZWJWaWV3IEpTIGluamVjdGlvbi5cbiAqXG4gKiBFdmFsdWF0ZXMgZXhwcmVzc2lvbnMgYnkgc3dpdGNoaW5nIHRvIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dCBhbmRcbiAqIGNhbGxpbmcgYGV4ZWN1dGUoKWAuIE1hbmFnZXMgdmF1bHRzIGJ5IHdyaXRpbmcgdG8gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYFxuICogKHdoaWNoIE9ic2lkaWFuIHVzZXMgYXMgaXRzIHZhdWx0IHJlZ2lzdHJ5IG9uIG1vYmlsZSkgYW5kIHB1c2hpbmcgZmlsZXMgdG8gdGhlIGRldmljZS5cbiAqL1xuZXhwb3J0IGNsYXNzIEFwcGl1bVRyYW5zcG9ydCBpbXBsZW1lbnRzIE9ic2lkaWFuVHJhbnNwb3J0IHtcbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgdHJhbnNwb3J0IGlzIGZvciBhIG1vYmlsZSBwbGF0Zm9ybS4gQWx3YXlzIGB0cnVlYCBmb3IgdGhpcyB0cmFuc3BvcnQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXNNb2JpbGUgPSB0cnVlO1xuICBwcml2YXRlIHJlYWRvbmx5IGFwcElkOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgYnJvd3NlcjogQnJvd3NlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXZpY2VJZDogc3RyaW5nO1xuICAvKipcbiAgICogVHJhY2tzIHdoZXRoZXIgdGhlIGRyaXZlciBpcyBjdXJyZW50bHkgc3dpdGNoZWQgdG8gdGhlIFdlYlZpZXcgY29udGV4dC5cbiAgICpcbiAgICogU2V0IHRvIGB0cnVlYCBhZnRlciBhIHN1Y2Nlc3NmdWwgYHN3aXRjaENvbnRleHQoV0VCVklFV19tZC5vYnNpZGlhbilgLlxuICAgKiBSZXNldCB0byBgZmFsc2VgIHdoZW4gdGhlIGNvbnRleHQgaXMga25vd24gdG8gYmUgaW52YWxpZGF0ZWRcbiAgICogKGUuZy4gYWZ0ZXIgYGxvY2F0aW9uLnJlbG9hZCgpYCBpbiB7QGxpbmsgcmVnaXN0ZXJWYXVsdH0pLlxuICAgKlxuICAgKiBXaGVuIGB0cnVlYCwge0BsaW5rIGVuc3VyZVdlYlZpZXdDb250ZXh0fSBza2lwcyB0aGUgZXhwZW5zaXZlXG4gICAqIGBnZXRDb250ZXh0cygpYCBjYWxsICh3aGljaCBydW5zIGBhZGIgc2hlbGwgY2F0IC9wcm9jL25ldC91bml4YCBhbmRcbiAgICogY2FuIHRpbWUgb3V0IG9uIHNsb3cgZW11bGF0b3JzKS5cbiAgICovXG4gIHByaXZhdGUgaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNTZXNzaW9uT3duZXI6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybTogJ2FuZHJvaWQnIHwgJ2lvcyc7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgdmF1bHRCYXNlUGF0aDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IEFwcGl1bSB0cmFuc3BvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBBcHBpdW0gdHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnOiBBcHBpdW1UcmFuc3BvcnRDb25maWcpIHtcbiAgICB0aGlzLmJyb3dzZXIgPSBjb25maWcuYnJvd3NlcjtcbiAgICB0aGlzLmRldmljZUlkID0gY29uZmlnLmRldmljZUlkO1xuICAgIHRoaXMuaXNTZXNzaW9uT3duZXIgPSBjb25maWcuaXNTZXNzaW9uT3duZXIgPz8gdHJ1ZTtcbiAgICB0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID0gY29uZmlnLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfTEFZT1VUX1JFQURZX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgdGhpcy5wbGF0Zm9ybSA9IGNvbmZpZy5wbGF0Zm9ybTtcbiAgICB0aGlzLmFwcElkID0gY29uZmlnLmFwcElkID8/IERFRkFVTFRfQVBQX0lEO1xuICAgIHRoaXMuc2hvdWxkU3dlZXBMZWZ0b3ZlcnMgPSBjb25maWcuc2hvdWxkU3dlZXBMZWZ0b3ZlcnMgPz8gdHJ1ZTtcbiAgICB0aGlzLnZhdWx0QmFzZVBhdGggPSBjb25maWcudmF1bHRCYXNlUGF0aCA/PyBERUZBVUxUX1ZBVUxUX0JBU0VfUEFUSFt0aGlzLnBsYXRmb3JtXSA/PyBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRIO1xuICAgIHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IGNvbmZpZy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfV0VCVklFV19QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICB9XG5cbiAgLyoqXG4gICAqIEJlZ2lucyBhIGNvbnNvbGUgY2FwdHVyZSBieSBzdGFtcGluZyB0aGUgZGV2aWNlIGxvZyB3aXRoIGEgdW5pcXVlIG1hcmtlci5cbiAgICpcbiAgICogVXNlcyBgYWRiIHNoZWxsIGxvZ2AgdG8gd3JpdGUgYSBtYXJrZXIgaW50byBgbG9nY2F0YCBhdCBjYXB0dXJlIHN0YXJ0IHNvIGFcbiAgICogbGF0ZXIge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5yZWFkQ29uc29sZUNhcHR1cmVTaW5jZX0gY2FuIHNsaWNlIG91dFxuICAgKiBldmVyeXRoaW5nIHRoZSBXZWJWaWV3IGxvZ2dlZCBhZnRlcndhcmRzIFx1MjAxNCB3aXRob3V0IHRoZSBpbnZhc2l2ZSBgbG9nY2F0IC1jYFxuICAgKiBidWZmZXIgY2xlYXIuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgaGFuZGxlIGNhcnJ5aW5nIHRoZSB1bmlxdWUgbWFya2VyLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGJlZ2luQ29uc29sZUNhcHR1cmUoKTogUHJvbWlzZTxDb25zb2xlQ2FwdHVyZUhhbmRsZT4ge1xuICAgIGNvbnN0IG1hcmtlciA9IGAke0NPTlNPTEVfQ0FQVFVSRV9NQVJLRVJfVEFHfV8ke3JhbmRvbVVVSUQoKX1gO1xuICAgIGF3YWl0IGV4ZWMoXG4gICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdsb2cnLCAnLXQnLCBDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBRywgbWFya2VyXSxcbiAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX0xPR19NQVJLRVJfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfVxuICAgICk7XG4gICAgcmV0dXJuIHsgbWFya2VyIH07XG4gIH1cblxuICAvKipcbiAgICogRW5kcyB0aGUgQXBwaXVtIHNlc3Npb24uXG4gICAqXG4gICAqIE9ubHkgZGVsZXRlcyB0aGUgc2Vzc2lvbiBpZiB0aGlzIHRyYW5zcG9ydCBvd25zIGl0LiBUcmFuc3BvcnRzIGNyZWF0ZWRcbiAgICogdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycyByZXVzaW5nIHRoZSBnbG9iYWwgc2V0dXAncyBzZXNzaW9uKSBza2lwXG4gICAqIGRlbGV0aW9uIHNvIHRoZSBzZXNzaW9uIHJlbWFpbnMgYXZhaWxhYmxlIGZvciB0aGUgb3duaW5nIHByb2Nlc3MuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc1Nlc3Npb25Pd25lcikge1xuICAgICAgYXdhaXQgdGhpcy5icm93c2VyLmRlbGV0ZVNlc3Npb24oKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXZhbHVhdGVzIGEgSmF2YVNjcmlwdCBleHByZXNzaW9uIGluc2lkZSBPYnNpZGlhbiBNb2JpbGUncyBXZWJWaWV3LlxuICAgKlxuICAgKiBTd2l0Y2hlcyB0byB0aGUgYFdFQlZJRVdfbWQub2JzaWRpYW5gIGNvbnRleHQsIGV4ZWN1dGVzIHRoZSBleHByZXNzaW9uLFxuICAgKiBhbmQgcmV0dXJucyB0aGUgcmVzdWx0IHN0cmluZy5cbiAgICpcbiAgICogQHBhcmFtIGV4cHJlc3Npb24gLSBUaGUgSmF2YVNjcmlwdCBleHByZXNzaW9uIHRvIGV2YWx1YXRlLlxuICAgKiBAcGFyYW0gX29wdGlvbnMgLSBFdmFsdWF0aW9uIG9wdGlvbnMgKGN3ZCBpcyBub3QgdXNlZCBvbiBtb2JpbGUgXHUyMDE0IHZhdWx0IHRhcmdldGluZyBpcyB2aWEgbG9jYWxTdG9yYWdlKS5cbiAgICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgcmVzdWx0IHN0cmluZy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBldmFsdWF0ZShleHByZXNzaW9uOiBzdHJpbmcsIF9vcHRpb25zOiBUcmFuc3BvcnRFdmFsT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVXZWJWaWV3Q29udGV4dCgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlPG51bGwgfCBzdHJpbmcgfCB1bmRlZmluZWQsIFtdPihcbiAgICAgICAgYHJldHVybiAoJHtleHByZXNzaW9ufSlgXG4gICAgICApO1xuXG4gICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQgfHwgcmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBOT19PVVRQVVQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIENvbnRleHQgbWF5IGhhdmUgYmVlbiBsb3N0IG1pZC1leGVjdXRpb24gKGUuZy4gcGFnZSByZWxvYWQpLlxuICAgICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSBmYWxzZTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzZXNzaW9uIGNvbm5lY3Rpb24gaW5mbyBuZWVkZWQgdG8gcmVhdHRhY2ggdG8gdGhpcyBzZXNzaW9uXG4gICAqIGZyb20gYW5vdGhlciBwcm9jZXNzIChlLmcuIGEgdGVzdCB3b3JrZXIpLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2Vzc2lvbiBJRCBhbmQgZGV2aWNlIElELlxuICAgKi9cbiAgcHVibGljIGdldFNlc3Npb25JbmZvKCk6IEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGV2aWNlSWQ6IHRoaXMuZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHRoaXMuYnJvd3Nlci5zZXNzaW9uSWRcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHRoYXQgdGhlIE9ic2lkaWFuIGFwcCBpcyBydW5uaW5nIGFuZCB0aGUgV2ViVmlldyBpcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBwYXJhbSBfdmF1bHRQYXRoIC0gTm90IHVzZWQgb24gbW9iaWxlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHByZWZsaWdodENoZWNrKF92YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZygnW2FwcGl1bS10cmFuc3BvcnRdIFJ1bm5pbmcgcHJlZmxpZ2h0IGNoZWNrLi4uJyk7XG4gICAgY29uc3Qgc3RhdGUgPSBhd2FpdCB0aGlzLmJyb3dzZXIucXVlcnlBcHBTdGF0ZSh0aGlzLmFwcElkKTtcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBBcHAgc3RhdGU6ICR7U3RyaW5nKHN0YXRlKX0gKG5lZWQgJHtTdHJpbmcoQVBQX1NUQVRFX0ZPUkVHUk9VTkQpfT1mb3JlZ3JvdW5kKWApO1xuICAgIGlmIChzdGF0ZSAhPT0gQVBQX1NUQVRFX0ZPUkVHUk9VTkQpIHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIEFjdGl2YXRpbmcgYXBwICR7dGhpcy5hcHBJZH0uLi5gKTtcbiAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuYWN0aXZhdGVBcHAodGhpcy5hcHBJZCk7XG4gICAgICBhd2FpdCBkZWxheShBUFBfUkVTVEFSVF9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcbiAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBQcmVmbGlnaHQgY2hlY2sgcGFzc2VkLicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1c2hlcyB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIHZpYSBjb21wcmVzc2VkIGBhZGIgcHVzaGAuXG4gICAqXG4gICAqIENyZWF0ZXMgYSB0YXIuZ3ogYXJjaGl2ZSBvZiB0aGUgbG9jYWwgdmF1bHQgZGlyZWN0b3J5LCBwdXNoZXMgaXQgdG8gdGhlXG4gICAqIGRldmljZSBhcyBhIHNpbmdsZSBmaWxlLCBhbmQgZXh0cmFjdHMgaXQgaW4tcGxhY2UuIFRoaXMgYXZvaWRzIHRoZVxuICAgKiB3ZWJkcml2ZXIgYFJhbmdlRXJyb3JgIG9uIGxhcmdlIGJhc2U2NCBwYXlsb2FkcyBhbmQgaXMgc2lnbmlmaWNhbnRseVxuICAgKiBmYXN0ZXIgdGhhbiBwZXItZmlsZSBgYnJvd3Nlci5wdXNoRmlsZSgpYCBjYWxscy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoICh1c2VkIGFzIHRoZSB2YXVsdCBkaXJlY3RvcnkgbmFtZSBvbiBkZXZpY2UpLlxuICAgKiBAcGFyYW0gX2ZpbGVzIC0gTWFwIG9mIHJlbGF0aXZlIGZpbGUgcGF0aHMgdG8gY29udGVudCBidWZmZXJzICh1bnVzZWQgXHUyMDE0IGFkYiBwdXNoZXMgdGhlIGRpcmVjdG9yeSBkaXJlY3RseSkuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcHVzaEZpbGVzKHZhdWx0UGF0aDogc3RyaW5nLCBfZmlsZXM6IFJlY29yZDxzdHJpbmcsIFVpbnQ4QXJyYXk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcbiAgICBjb25zdCBhcmNoaXZlTmFtZSA9IGB2YXVsdC0ke3JhbmRvbVVVSUQoKX0udGFyLmd6YDtcbiAgICBjb25zdCBsb2NhbEFyY2hpdmUgPSBqb2luKHRtcGRpcigpLCBhcmNoaXZlTmFtZSk7XG4gICAgY29uc3QgcmVtb3RlQXJjaGl2ZSA9IGAvZGF0YS9sb2NhbC90bXAvJHthcmNoaXZlTmFtZX1gO1xuXG4gICAgdHJ5IHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIENyZWF0aW5nIGFyY2hpdmU6ICR7bG9jYWxBcmNoaXZlfWApO1xuICAgICAgYXdhaXQgZXhlYyhbJ3RhcicsICdjemYnLCBhcmNoaXZlTmFtZSwgJy1DJywgdmF1bHRQYXRoLCAnLiddLCB7IGN3ZDogdG1wZGlyKCksIGlzUXVpZXQ6IHRydWUgfSk7XG5cbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFB1c2hpbmcgYXJjaGl2ZSB0byBkZXZpY2UgJHt0aGlzLmRldmljZUlkfS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdwdXNoJywgbG9jYWxBcmNoaXZlLCByZW1vdGVBcmNoaXZlXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBFeHRyYWN0aW5nIGFyY2hpdmUgb24gZGV2aWNlIGF0ICR7ZGV2aWNlVmF1bHRQYXRofS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdta2RpcicsICctcCcsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAndGFyJywgJ3h6ZicsIHJlbW90ZUFyY2hpdmUsICctQycsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gRmx1c2hpbmcgZmlsZXN5c3RlbSBidWZmZXJzLi4uJyk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3N5bmMnXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBDbGVhbmluZyB1cCByZW1vdGUgYXJjaGl2ZS4uLicpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdybScsIHJlbW90ZUFyY2hpdmVdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJtKGxvY2FsQXJjaGl2ZSwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRHVtcHMgYGFkYiBsb2djYXRgIGFuZCByZXR1cm5zIHRoZSBXZWJWaWV3IGNvbnNvbGUvZXJyb3Igb3V0cHV0IGxvZ2dlZFxuICAgKiBzaW5jZSB0aGUgbWFya2VyIGZyb20ge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5iZWdpbkNvbnNvbGVDYXB0dXJlfS5cbiAgICpcbiAgICogRmlsdGVycyB0byB0aGUgQ2hyb21pdW0vV2ViVmlldyB0YWdzIHRoYXQgY2FycnkgSlMgYGNvbnNvbGUuKmAgb3V0cHV0IGFuZFxuICAgKiB1bmNhdWdodCBlcnJvcnMsIGFuZCBjYXBzIHRoZSByZXN1bHQgbGVuZ3RoLiBCb3VuZGVkLCBwb3N0LWhvYyxcbiAgICogZmFpbHVyZS1wYXRoLW9ubHkgXHUyMDE0IG5ldmVyIGEgbGl2ZSBtb25pdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gaGFuZGxlIC0gVGhlIGNhcHR1cmUgaGFuZGxlIChvciBgdW5kZWZpbmVkYCB3aGVuIGNhcHR1cmUgbmV2ZXIgc3RhcnRlZCkuXG4gICAqIEByZXR1cm5zIFRoZSBjYXB0dXJlZCBjb25zb2xlL2Vycm9yIHRleHQsIG9yIGB1bmRlZmluZWRgIGlmIG5vdGhpbmcgcmVsZXZhbnQgd2FzIGxvZ2dlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWFkQ29uc29sZUNhcHR1cmVTaW5jZShoYW5kbGU6IENvbnNvbGVDYXB0dXJlSGFuZGxlIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoIWhhbmRsZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBkdW1wID0gYXdhaXQgZXhlYyhcbiAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ2xvZ2NhdCcsICctZCcsICctdicsICd0aW1lJ10sXG4gICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IExPR0NBVF9EVU1QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICApO1xuXG4gICAgY29uc3QgbWFya2VySW5kZXggPSBkdW1wLmxhc3RJbmRleE9mKGhhbmRsZS5tYXJrZXIpO1xuICAgIGNvbnN0IHJlZ2lvbiA9IG1hcmtlckluZGV4ID09PSAtMSA/IGR1bXAgOiBkdW1wLnNsaWNlKG1hcmtlckluZGV4ICsgaGFuZGxlLm1hcmtlci5sZW5ndGgpO1xuICAgIGNvbnN0IHJlbGV2YW50ID0gcmVnaW9uXG4gICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAuZmlsdGVyKChsaW5lKSA9PiBDT05TT0xFX0NBUFRVUkVfVEFHX1JFLnRlc3QobGluZSkpXG4gICAgICAuam9pbignXFxuJylcbiAgICAgIC50cmltKCk7XG5cbiAgICBpZiAoIXJlbGV2YW50KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiByZWxldmFudC5zbGljZSgtQ09OU09MRV9DQVBUVVJFX1RBSUxfTUFYX0xFTkdUSCk7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgdmF1bHQgb24gbW9iaWxlIGJ5IHB1c2hpbmcgZmlsZXMgYW5kIGNvbmZpZ3VyaW5nIGxvY2FsU3RvcmFnZS5cbiAgICpcbiAgICogVGhlIHJlZ2lzdHJhdGlvbiBmbG93OlxuICAgKiAxLiBQdXNoIGEgbWluaW1hbCBgLm9ic2lkaWFuL2FwcC5qc29uYCB0byB0aGUgZGV2aWNlIHNvIE9ic2lkaWFuIHJlY29nbml6ZXMgdGhlIHZhdWx0XG4gICAqIDIuIFN3aXRjaCB0byB0aGUgV2ViVmlldyBjb250ZXh0XG4gICAqIDMuIEFkZCB0aGUgdmF1bHQgdG8gbG9jYWxTdG9yYWdlIChgbW9iaWxlLWV4dGVybmFsLXZhdWx0c2AsIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgLFxuICAgKiAgICBgZW5hYmxlLXBsdWdpbi08cGF0aD5gKVxuICAgKiA0LiBUcmlnZ2VyIGBsb2NhdGlvbi5yZWxvYWQoKWAgc28gT2JzaWRpYW4gcmUtcmVhZHMgbG9jYWxTdG9yYWdlIGFuZCBvcGVucyB0aGUgdmF1bHRcbiAgICogNS4gV2FpdCBmb3IgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgXG4gICAqXG4gICAqIEV4aXN0aW5nIHZhdWx0IHJlZ2lzdHJhdGlvbnMgaW4gbG9jYWxTdG9yYWdlIGFyZSBwcmVzZXJ2ZWQgKGFwcGVuZCwgbm90XG4gICAqIG92ZXJ3cml0ZSkgXHUyMDE0IGV4Y2VwdCB0aGUgKipoYXJuZXNzJ3Mgb3duKiogYHRlbXAtdmF1bHQtKmAgcmVnaXN0cmF0aW9ucyBmcm9tXG4gICAqIGVhcmxpZXIgcnVucywgd2hpY2ggYXJlIHBydW5lZCB3aGVuIHtAbGluayBBcHBpdW1UcmFuc3BvcnRDb25maWcuc2hvdWxkU3dlZXBMZWZ0b3ZlcnN9XG4gICAqIGlzIG9uLiBUaGVpciBkaXJlY3RvcmllcyBhcmUgYWxyZWFkeSBnb25lICh0aGUgZmFjdG9yeSBzd2VlcHMgdGhlbSBiZWZvcmVcbiAgICogdGhlIGFwcCBsYXVuY2hlcyksIGFuZCBpdCBpcyB0aGlzIHJlZ2lzdHJ5IFx1MjAxNCBub3QgdGhlIGZpbGVzeXN0ZW0gXHUyMDE0IHRoYXRcbiAgICogT2JzaWRpYW4gZW51bWVyYXRlcyBhdCBzdGFydHVwLCBzbyBsZWF2aW5nIHRoZW0gaXMgd2hhdCBtYWtlcyBlYWNoIGZhaWxlZFxuICAgKiBydW4gc2xvdyB0aGUgbmV4dCBvbmUgZG93bi5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBSZWdpc3RlcmluZyB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcblxuICAgIC8vIFB1c2ggYSBtaW5pbWFsIC5vYnNpZGlhbiBkaXJlY3Rvcnkgc28gT2JzaWRpYW4gcmVjb2duaXplcyBpdCBhcyBhIHZhdWx0LlxuICAgIGF3YWl0IHRoaXMucHVzaE9ic2lkaWFuTWFya2VyKGRldmljZVZhdWx0UGF0aCk7XG5cbiAgICAvLyBTd2l0Y2ggdG8gV2ViVmlldyBhbmQgY29uZmlndXJlIGxvY2FsU3RvcmFnZS5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG5cbiAgICAvLyBJbnZhbGlkYXRlIGJlZm9yZSByZWxvYWQgXHUyMDE0IHRoZSBwYWdlIHdpbGwgbmF2aWdhdGUgYW5kIHRoZSBXZWJWaWV3XG4gICAgLy8gQ29udGV4dCBtYXkgYmUgdGVtcG9yYXJpbHkgdW5hdmFpbGFibGUgZHVyaW5nIHJlbG9hZC5cbiAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc3RhbGVQcmVmaXggPSB0aGlzLnNob3VsZFN3ZWVwTGVmdG92ZXJzID8gYCR7dGhpcy52YXVsdEJhc2VQYXRofSR7VEVNUF9WQVVMVF9ESVJfUFJFRklYfWAgOiAnJztcblxuICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKFxuICAgICAgKHBhdGg6IHN0cmluZywgcHJ1bmVQcmVmaXg6IHN0cmluZykgPT4ge1xuICAgICAgICBsZXQgZXhpc3RpbmcgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJykgPz8gJ1tdJykgYXMgc3RyaW5nW107XG5cbiAgICAgICAgaWYgKHBydW5lUHJlZml4KSB7XG4gICAgICAgICAgY29uc3Qgc3RhbGUgPSBleGlzdGluZy5maWx0ZXIoKHJlZ2lzdGVyZWQpID0+IHJlZ2lzdGVyZWQgIT09IHBhdGggJiYgcmVnaXN0ZXJlZC5zdGFydHNXaXRoKHBydW5lUHJlZml4KSk7XG4gICAgICAgICAgZm9yIChjb25zdCByZWdpc3RlcmVkIG9mIHN0YWxlKSB7XG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShgZW5hYmxlLXBsdWdpbi0ke3JlZ2lzdGVyZWR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV4aXN0aW5nID0gZXhpc3RpbmcuZmlsdGVyKChyZWdpc3RlcmVkKSA9PiAhc3RhbGUuaW5jbHVkZXMocmVnaXN0ZXJlZCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFleGlzdGluZy5pbmNsdWRlcyhwYXRoKSkge1xuICAgICAgICAgIGV4aXN0aW5nLnB1c2gocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnLCBKU09OLnN0cmluZ2lmeShleGlzdGluZykpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0JywgcGF0aCk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGBlbmFibGUtcGx1Z2luLSR7cGF0aH1gLCAndHJ1ZScpO1xuICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgIH0sXG4gICAgICBkZXZpY2VWYXVsdFBhdGgsXG4gICAgICBzdGFsZVByZWZpeFxuICAgICk7XG5cbiAgICAvLyBXYWl0IGZvciByZWxvYWQgKyB2YXVsdCBpbml0aWFsaXphdGlvbi5cbiAgICBhd2FpdCB0aGlzLndhaXRGb3JMYXlvdXRSZWFkeSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIGEgdmF1bHQgb24gbW9iaWxlIGJ5IHJlbW92aW5nIGl0IGZyb20gbG9jYWxTdG9yYWdlLlxuICAgKlxuICAgKiBQcmVzZXJ2ZXMgb3RoZXIgdmF1bHQgcmVnaXN0cmF0aW9ucy4gSWYgdGhlIHVucmVnaXN0ZXJlZCB2YXVsdCB3YXMgc2VsZWN0ZWQsXG4gICAqIHN3aXRjaGVzIHRvIHRoZSBmaXJzdCByZW1haW5pbmcgdmF1bHQgKG9yIGNsZWFycyB0aGUgc2VsZWN0aW9uKS5cbiAgICpcbiAgICogVGhlIHZhdWx0J3MgKipmaWxlcyBhcmUgdGhlbiByZW1vdmVkIGZyb20gdGhlIGRldmljZSBvdmVyIGBhZGJgLCB3aGV0aGVyIG9yXG4gICAqIG5vdCB0aGUgYGxvY2FsU3RvcmFnZWAgc3RlcCBzdWNjZWVkZWQqKiBcdTIwMTQgZGVsaWJlcmF0ZWx5LCBiZWNhdXNlIHRoZVxuICAgKiBgbG9jYWxTdG9yYWdlYCBzdGVwIGdvZXMgdGhyb3VnaCB0aGUgV2ViVmlldyBhbmQgYSBkZWFkIFdlYlZpZXcgaXMgZXhhY3RseVxuICAgKiB3aGF0IG1vc3QgQW5kcm9pZCBmYWlsdXJlcyBhcmUuIFJvdXRpbmcgdGhlIHJlbW92YWwgdGhyb3VnaCB0aGUgYXBwIHdhcyB3aGF0XG4gICAqIG1hZGUgZXZlcnkgZmFpbGVkIHJ1biBsZWFrIGl0cyB2YXVsdCAoYFZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6IG5vXG4gICAqIHN1Y2ggd2luZG93YCksIHNvIHRoZSBmaWxlc3lzdGVtLWxldmVsIHJlbW92YWwgbXVzdCBub3QgZGVwZW5kIG9uIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IG9uIHRoZSBob3N0IG1hY2hpbmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdW5yZWdpc3RlclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJykgPz8gJ1tdJykgYXMgc3RyaW5nW107XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gZXhpc3RpbmcuZmlsdGVyKCh2KSA9PiB2ICE9PSBwYXRoKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnLCBKU09OLnN0cmluZ2lmeShmaWx0ZXJlZCkpO1xuICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShgZW5hYmxlLXBsdWdpbi0ke3BhdGh9YCk7XG4gICAgICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0JykgPT09IHBhdGgpIHtcbiAgICAgICAgICBpZiAoZmlsdGVyZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcsIGZpbHRlcmVkWzBdID8/ICcnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSwgZGV2aWNlVmF1bHRQYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKFxuICAgICAgICBgW2FwcGl1bS10cmFuc3BvcnRdIENvdWxkIG5vdCBkZXJlZ2lzdGVyICR7ZGV2aWNlVmF1bHRQYXRofSBmcm9tIGxvY2FsU3RvcmFnZSBgXG4gICAgICAgICAgKyBgKCR7U3RyaW5nKGVycm9yKX0pOyByZW1vdmluZyBpdHMgZmlsZXMgYW55d2F5LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZW1vdmVEZXZpY2VWYXVsdERpcihkZXZpY2VWYXVsdFBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN3aXRjaGVzIHRoZSBkcml2ZXIgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0LlxuICAgKlxuICAgKiBJZiB0aGUgY29udGV4dCB3YXMgYWxyZWFkeSB2ZXJpZmllZCAoY2FjaGVkIHZpYSB7QGxpbmsgaXNJbldlYlZpZXdDb250ZXh0fSksXG4gICAqIHJldHVybnMgaW1tZWRpYXRlbHkgd2l0aG91dCBjYWxsaW5nIGBnZXRDb250ZXh0cygpYCBcdTIwMTQgd2hpY2ggcnVuc1xuICAgKiBgYWRiIHNoZWxsIGNhdCAvcHJvYy9uZXQvdW5peGAgYW5kIGNhbiB0aW1lIG91dCBvbiBzbG93IGVtdWxhdG9ycy5cbiAgICpcbiAgICogUG9sbHMgdW50aWwgdGhlIGNvbnRleHQgYmVjb21lcyBhdmFpbGFibGUgKHRoZSBhcHAgbWF5IHN0aWxsIGJlIGxvYWRpbmcpLlxuICAgKiBVc2VzIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dCBzcGVjaWZpY2FsbHkgdG8gYXZvaWQgY29ubmVjdGluZ1xuICAgKiB0byBDaHJvbWUgb3Igb3RoZXIgV2ViVmlld3Mgb24gdGhlIGRldmljZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlV2ViVmlld0NvbnRleHQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNJbldlYlZpZXdDb250ZXh0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgdGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdhaXRpbmcgZm9yICR7V0VCVklFV19DT05URVhUX1BSRUZJWH0gY29udGV4dCAodGltZW91dD0ke1N0cmluZyh0aGlzLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zKS4uLmApO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgY29uc3QgY29udGV4dHMgPSBhd2FpdCB0aGlzLmJyb3dzZXIuZ2V0Q29udGV4dHMoKTtcbiAgICAgIGNvbnN0IG9ic2lkaWFuQ29udGV4dCA9IGNvbnRleHRzLmZpbmQoKGN0eCk6IGN0eCBpcyBzdHJpbmcgPT4gdHlwZW9mIGN0eCA9PT0gJ3N0cmluZycgJiYgY3R4LnN0YXJ0c1dpdGgoV0VCVklFV19DT05URVhUX1BSRUZJWCkpO1xuXG4gICAgICBpZiAob2JzaWRpYW5Db250ZXh0KSB7XG4gICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIEZvdW5kIFdlYlZpZXcgY29udGV4dDogJHtvYnNpZGlhbkNvbnRleHR9YCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLnN3aXRjaENvbnRleHQob2JzaWRpYW5Db250ZXh0KTtcbiAgICAgICAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIHN3aXRjaENvbnRleHQgZmFpbGVkOiAke1N0cmluZyhlcnJvcil9LiBSZXNldHRpbmcgdG8gTkFUSVZFX0FQUCBiZWZvcmUgcmV0cnlpbmcuLi5gKTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLnN3aXRjaENvbnRleHQoJ05BVElWRV9BUFAnKTtcbiAgICAgICAgICB9IGNhdGNoIChyZXNldEVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBOQVRJVkVfQVBQIHJlc2V0IGFsc28gZmFpbGVkOiAke1N0cmluZyhyZXNldEVycm9yKX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gV2ViVmlldyBub3QgcmVhZHksIGF2YWlsYWJsZSBjb250ZXh0czogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0cyl9LiBSZXRyeWluZy4uLmApO1xuICAgICAgYXdhaXQgZGVsYXkoV0VCVklFV19QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBObyAke1dFQlZJRVdfQ09OVEVYVF9QUkVGSVh9IGNvbnRleHQgZm91bmQgd2l0aGluICR7U3RyaW5nKHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMuIElzIHRoZSBPYnNpZGlhbiBhcHAgZnVsbHkgbG9hZGVkP2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgaG9zdC1zaWRlIHZhdWx0IHBhdGggdG8gdGhlIGRldmljZS1zaWRlIHBhdGguXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBBYnNvbHV0ZSBwYXRoIG9uIHRoZSBob3N0IG1hY2hpbmUuXG4gICAqIEByZXR1cm5zIFRoZSBkZXZpY2Utc2lkZSB2YXVsdCBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnZhdWx0QmFzZVBhdGh9JHtleHRyYWN0VmF1bHROYW1lKHZhdWx0UGF0aCl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXNoZXMgdGhlIG1pbmltYWwgYC5vYnNpZGlhbi9hcHAuanNvbmAgdmF1bHQgbWFya2VyIHZpYSBgYWRiIHB1c2hgLlxuICAgKlxuICAgKiBgYnJvd3Nlci5wdXNoRmlsZWAgKFdlYkRyaXZlciBiYXNlNjQpIGlzIGFuIG9yZGVyIG9mIG1hZ25pdHVkZSBzbG93ZXIgb24gYVxuICAgKiBjb2xkIG9yIGxvYWRlZCBlbXVsYXRvciBcdTIwMTQgbWVhc3VyZWQgYXQgOVx1MjAxMzIxcyBwZXIgY2FsbCBmb3IgdGhpcyAyLWJ5dGUgbWFya2VyLFxuICAgKiB2ZXJzdXMgc3ViLXNlY29uZCBvdmVyIGBhZGJgLiBUaGlzIG1pcnJvcnMge0BsaW5rIHB1c2hGaWxlc30sIHdoaWNoIHN3aXRjaGVkXG4gICAqIHRvIGBhZGJgIGZvciB0aGUgc2FtZSByZWFzb24uIGBta2RpciAtcGAgZ3VhcmFudGVlcyB0aGUgcGFyZW50IGRpcmVjdG9yeS5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZVZhdWx0UGF0aCAtIFRoZSBkZXZpY2Utc2lkZSB2YXVsdCBkaXJlY3RvcnkgcGF0aC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcHVzaE9ic2lkaWFuTWFya2VyKGRldmljZVZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9jYWxNYXJrZXIgPSBqb2luKHRtcGRpcigpLCBgb2JzaWRpYW4tbWFya2VyLSR7cmFuZG9tVVVJRCgpfS5qc29uYCk7XG4gICAgY29uc3QgcmVtb3RlTWFya2VyID0gYCR7ZGV2aWNlVmF1bHRQYXRofS8ub2JzaWRpYW4vYXBwLmpzb25gO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHdyaXRlRmlsZShsb2NhbE1hcmtlciwgJ3t9JywgJ3V0Zi04Jyk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ21rZGlyJywgJy1wJywgYCR7ZGV2aWNlVmF1bHRQYXRofS8ub2JzaWRpYW5gXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdwdXNoJywgbG9jYWxNYXJrZXIsIHJlbW90ZU1hcmtlcl0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcm0obG9jYWxNYXJrZXIsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSB2YXVsdCBkaXJlY3RvcnkgZnJvbSB0aGUgZGV2aWNlIG92ZXIgYGFkYmAuXG4gICAqXG4gICAqIEJlc3QtZWZmb3J0OiBhIGZhaWx1cmUgaXMgbG9nZ2VkLCBub3QgdGhyb3duLCBzbyBhIHRlYXJkb3duIHByb2JsZW0gbmV2ZXJcbiAgICogbWFza3MgdGhlIHRlc3QgcmVzdWx0LiBUaGUgbmV4dCBydW4ncyBzdGFydC1vZi1ydW4gc3dlZXAgcGlja3MgdXAgd2hhdGV2ZXJcbiAgICogdGhpcyBjb3VsZCBub3QgcmVtb3ZlLlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlVmF1bHRQYXRoIC0gVGhlIGRldmljZS1zaWRlIHZhdWx0IGRpcmVjdG9yeSBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZW1vdmVEZXZpY2VWYXVsdERpcihkZXZpY2VWYXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBSZW1vdmluZyB2YXVsdCBkaXJlY3RvcnkgZnJvbSBkZXZpY2U6ICR7ZGV2aWNlVmF1bHRQYXRofWApO1xuICAgICAgYXdhaXQgZXhlYyhcbiAgICAgICAgWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAncm0nLCAnLXJmJywgZGV2aWNlVmF1bHRQYXRoXSxcbiAgICAgICAgeyBpc1F1aWV0OiB0cnVlLCBzaG91bGRJZ25vcmVFeGl0Q29kZTogdHJ1ZSwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFZhdWx0IGRpcmVjdG9yeSByZW1vdmFsIGZhaWxlZCAobm9uLWZhdGFsKTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB1bnRpbCBgYXBwLndvcmtzcGFjZS5sYXlvdXRSZWFkeWAgaXMgYHRydWVgIGluIHRoZSBXZWJWaWV3LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yTGF5b3V0UmVhZHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gc3RhcnQgKyB0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdhaXRpbmcgZm9yIGxheW91dCByZWFkeSAodGltZW91dD0ke1N0cmluZyh0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcykuLi5gKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGlzUmVhZHkgPSBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZSgoKTogYm9vbGVhbiA9PiB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1kZXByZWNhdGVkIC0tIFdlIG5lZWQgZ2xvYmFsIGBhcHBgIHZhcmlhYmxlLlxuICAgICAgICAgIGNvbnN0IGFwcCA9IHdpbmRvdy5hcHAgYXMgTG9hZGluZ0FwcCB8IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXR1cm4gISFhcHA/LndvcmtzcGFjZT8ubGF5b3V0UmVhZHk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoaXNSZWFkeSkge1xuICAgICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIExheW91dCBpcyByZWFkeSBhZnRlciAke1N0cmluZyhEYXRlLm5vdygpIC0gc3RhcnQpfW1zLmApO1xuICAgICAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBBcHAgbm90IHJlYWR5IHlldCAocGFnZSBtYXkgYmUgcmVsb2FkaW5nKS5cbiAgICAgIH1cblxuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gTGF5b3V0IG5vdCByZWFkeSB5ZXQgKGVsYXBzZWQ9JHtTdHJpbmcoRGF0ZS5ub3coKSAtIHN0YXJ0KX1tcykuIFJldHJ5aW5nLi4uYCk7XG4gICAgICBhd2FpdCBkZWxheShMQVlPVVRfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgT2JzaWRpYW4gbGF5b3V0IGRpZCBub3QgYmVjb21lIHJlYWR5IHdpdGhpbiAke1N0cmluZyh0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzKX1tc2ApO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZ2l2ZW4gZGVsYXkuXG4gKlxuICogQHBhcmFtIG1zIC0gVGhlIGRlbGF5IGluIG1pbGxpc2Vjb25kcy5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBkZWxheS5cbiAqL1xuZnVuY3Rpb24gZGVsYXkobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKTtcbiAgfSk7XG59XG5cbi8qKlxuICogRXh0cmFjdHMgdGhlIHZhdWx0IGRpcmVjdG9yeSBuYW1lIGZyb20gYSBob3N0LXNpZGUgdmF1bHQgcGF0aC5cbiAqXG4gKiBAcGFyYW0gdmF1bHRQYXRoIC0gQWJzb2x1dGUgcGF0aCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICogQHJldHVybnMgVGhlIGxhc3QgcGF0aCBzZWdtZW50ICh2YXVsdCBkaXJlY3RvcnkgbmFtZSkuXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RWYXVsdE5hbWUodmF1bHRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkID0gdmF1bHRQYXRoLnJlcGxhY2UoL1tcXFxcL10rJC8sICcnKTtcbiAgY29uc3QgbGFzdFNlcCA9IE1hdGgubWF4KG5vcm1hbGl6ZWQubGFzdEluZGV4T2YoJy8nKSwgbm9ybWFsaXplZC5sYXN0SW5kZXhPZignXFxcXCcpKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQuc2xpY2UobGFzdFNlcCArIDEpO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBNENBLHlCQUEyQjtBQUMzQixzQkFHTztBQUNQLHFCQUF1QjtBQUN2Qix1QkFBcUI7QUFRckIsa0JBQXFCO0FBQ3JCLDhCQUFzQztBQUN0QyxpQkFBb0I7QUEwRnBCLE1BQU0sWUFBWTtBQUNsQixNQUFNLHVCQUF1QjtBQUM3QixNQUFNLHlCQUF5QjtBQUMvQixNQUFNLHdDQUF3QztBQUM5QyxNQUFNLCtDQUErQztBQUNyRCxNQUFNLDZDQUE2QztBQUNuRCxNQUFNLG9EQUFvRDtBQUMxRCxNQUFNLG9DQUFvQztBQUMxQyxNQUFNLGlCQUFpQjtBQUN2QixNQUFNLDJDQUEyQztBQUdqRCxNQUFNLDZCQUE2QjtBQUNuQyxNQUFNLGtD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
|
|
475
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1hcHBpdW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBcHBpdW0gdHJhbnNwb3J0IFx1MjAxNCBldmFsdWF0ZXMgZXhwcmVzc2lvbnMgaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSB2aWEgV2ViVmlld1xuICogSmF2YVNjcmlwdCBpbmplY3Rpb24uIE1hbmFnZXMgdmF1bHQgbGlmZWN5Y2xlIHZpYSBsb2NhbFN0b3JhZ2UgYW5kIGZpbGUgcHVzaC5cbiAqXG4gKiBDb25maWd1cmVkIHZpYSBgZW52aXJvbm1lbnRPcHRpb25zLm9ic2lkaWFuVHJhbnNwb3J0YCBpbiB2aXRlc3QgY29uZmlnOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHZpdGVzdC5jb25maWcudHNcbiAqIGVudmlyb25tZW50T3B0aW9uczoge1xuICogICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICogICAgIHR5cGU6ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScsXG4gKiAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAqICAgICBhdmROYW1lOiAnb2JzaWRpYW5fdGVzdCcsXG4gKiAgIH0sXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBGb3IgQnJvd3NlclN0YWNrLCBzZXQgYGFwcGl1bVVybGAgdG8gdGhlIEJyb3dzZXJTdGFjayBodWIgVVJMXG4gKiBcdTIwMTQgdGhlIHRyYW5zcG9ydCBpdHNlbGYgaXMgaHViLWFnbm9zdGljLlxuICpcbiAqICMjIEhvdyB2YXVsdCByZWdpc3RyYXRpb24gd29ya3Mgb24gbW9iaWxlXG4gKlxuICogT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHQgcmVnaXN0cnkgaW4gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYDpcbiAqXG4gKiAtIGBtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzYCBcdTIwMTQgSlNPTiBhcnJheSBvZiByZWdpc3RlcmVkIHZhdWx0IHBhdGhzXG4gKiAtIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgIFx1MjAxNCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2YXVsdCBwYXRoXG4gKiAtIGBlbmFibGUtcGx1Z2luLTx2YXVsdFBhdGg+YCBcdTIwMTQgYFwidHJ1ZVwiYCB0byBlbmFibGUgdGhlIHBsdWdpbiBzeXN0ZW0gZm9yIHRoZSB2YXVsdFxuICpcbiAqIFRvIHJlZ2lzdGVyIGEgdmF1bHQgcHJvZ3JhbW1hdGljYWxseSAod2l0aG91dCBVSSBpbnRlcmFjdGlvbik6XG4gKlxuICogMS4gUHVzaCB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIChlLmcuIGAvc2RjYXJkL0RvY3VtZW50cy88TmFtZT4vLm9ic2lkaWFuL2FwcC5qc29uYClcbiAqIDIuIFN3aXRjaCB0byBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dFxuICogMy4gU2V0IHRoZSBsb2NhbFN0b3JhZ2UgZW50cmllc1xuICogNC4gQ2FsbCBgbG9jYXRpb24ucmVsb2FkKClgIFx1MjAxNCBPYnNpZGlhbiByZS1yZWFkcyBsb2NhbFN0b3JhZ2UgYW5kIG9wZW5zIHRoZSB2YXVsdFxuICpcbiAqIFRoaXMgYXZvaWRzIHRoZSBvbmJvYXJkaW5nIGZsb3cgZW50aXJlbHkuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBCcm93c2VyIH0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgcm0sXG4gIHdyaXRlRmlsZVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHtcbiAgQ29uc29sZUNhcHR1cmVIYW5kbGUsXG4gIE9ic2lkaWFuVHJhbnNwb3J0LFxuICBUcmFuc3BvcnRFdmFsT3B0aW9uc1xufSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuXG5pbXBvcnQgeyBleGVjIH0gZnJvbSAnLi9leGVjLmNqcyc7XG5pbXBvcnQgeyBURU1QX1ZBVUxUX0RJUl9QUkVGSVggfSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5cbi8qKlxuICogU2Vzc2lvbiBjb25uZWN0aW9uIGluZm8gcmV0dXJuZWQgYnkge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5nZXRTZXNzaW9uSW5mb30sXG4gKiB1c2VkIHRvIHJlYXR0YWNoIGZyb20gYW5vdGhlciBwcm9jZXNzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgLyoqIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuICovXG4gIGRldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBBcHBpdW0vV2ViRHJpdmVyIHNlc3Npb24gSUQuICovXG4gIHNlc3Npb25JZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBBcHBpdW0gdHJhbnNwb3J0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGl1bVRyYW5zcG9ydENvbmZpZyB7XG4gIC8qKlxuICAgKiBBcHAgcGFja2FnZSAoQW5kcm9pZCkgb3IgYnVuZGxlIElEIChpT1MpLlxuICAgKiBEZWZhdWx0cyB0byBgJ21kLm9ic2lkaWFuJ2AuXG4gICAqL1xuICBhcHBJZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFwcGl1bSBicm93c2VyL2RyaXZlciBpbnN0YW5jZS5cbiAgICogQ3JlYXRlZCBieSB0aGUgY29uc3VtZXIgdmlhIGUuZy4gV2ViRHJpdmVySU8ncyBgcmVtb3RlKClgLlxuICAgKi9cbiAgYnJvd3NlcjogQnJvd3NlcjtcblxuICAvKipcbiAgICogVGhlIGRldmljZSBVRElEIChlLmcuIGAnZW11bGF0b3ItNTU1NCdgKS5cbiAgICogVXNlZCBmb3IgYGFkYmAgY29tbWFuZHMgd2hlbiBwdXNoaW5nIGZpbGVzIHRvIHRoZSBkZXZpY2UuXG4gICAqL1xuICBkZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgdHJhbnNwb3J0IG93bnMgdGhlIEFwcGl1bSBzZXNzaW9uIGFuZCBzaG91bGQgZGVsZXRlIGl0IG9uXG4gICAqIHtAbGluayBBcHBpdW1UcmFuc3BvcnQuZGlzcG9zZX0uXG4gICAqXG4gICAqIGB0cnVlYCBmb3Igc2Vzc2lvbnMgY3JlYXRlZCB2aWEgYHJlbW90ZSgpYCAoZ2xvYmFsIHNldHVwKS5cbiAgICogYGZhbHNlYCBmb3Igc2Vzc2lvbnMgcmVhdHRhY2hlZCB2aWEgYGF0dGFjaCgpYCAodGVzdCB3b3JrZXJzKS5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICBpc1Nlc3Npb25Pd25lcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB3YWl0aW5nIGZvciBgYXBwLndvcmtzcGFjZS5sYXlvdXRSZWFkeWAgYWZ0ZXJcbiAgICogdGhlIHZhdWx0IGlzIChyZSlvcGVuZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA5MDAwMGBcbiAgICovXG4gIGxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUYXJnZXQgcGxhdGZvcm0uIERldGVybWluZXMgV2ViVmlldyBjb250ZXh0IG5hbWluZyBhbmQgZGV2aWNlIGZpbGUgcGF0aHMuXG4gICAqL1xuICBwbGF0Zm9ybTogJ2FuZHJvaWQnIHwgJ2lvcyc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgcmVnaXN0ZXJpbmcgYSB2YXVsdCBhbHNvIHBydW5lcyB0aGUgKipvdGhlcioqIGB0ZW1wLXZhdWx0LSpgXG4gICAqIHJlZ2lzdHJhdGlvbnMgZWFybGllciBydW5zIGxlZnQgaW4gT2JzaWRpYW4gTW9iaWxlJ3MgYGxvY2FsU3RvcmFnZWAuXG4gICAqXG4gICAqIFRoZSBkZXZpY2Utc2lkZSBkaXJlY3RvcmllcyBhcmUgc3dlcHQgYmVmb3JlIHRoZSBhcHAgbGF1bmNoZXMgKHNlZSB0aGVcbiAgICogZmFjdG9yeSk7IHRoaXMgcmVtb3ZlcyB0aGVpciBub3ctZGFuZ2xpbmcgcmVnaXN0cnkgZW50cmllcywgd2hpY2ggYXJlIHdoYXRcbiAgICogT2JzaWRpYW4gYWN0dWFsbHkgZW51bWVyYXRlcyBhdCBzdGFydHVwLiBVbnJlZ2lzdGVyaW5nIHRoaXMgcnVuJ3Mgb3duIHZhdWx0XG4gICAqIGlzIHVuYWZmZWN0ZWQgXHUyMDE0IHRoYXQgYWx3YXlzIGhhcHBlbnMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBCYXNlIHBhdGggb24gdGhlIGRldmljZSB3aGVyZSBPYnNpZGlhbiBzdG9yZXMgdmF1bHRzLlxuICAgKlxuICAgKiBEZWZhdWx0czpcbiAgICogLSBBbmRyb2lkOiBgL3NkY2FyZC9Eb2N1bWVudHMvYFxuICAgKiAtIGlPUzogYEBtZC5vYnNpZGlhbjpkb2N1bWVudHMvYFxuICAgKi9cbiAgdmF1bHRCYXNlUGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogVGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHdhaXRpbmcgZm9yIHRoZSBXZWJWaWV3IGNvbnRleHQgdG8gYmVjb21lIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQGRlZmF1bHQgYDYwMDAwYFxuICAgKi9cbiAgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbn1cblxuY29uc3QgTk9fT1VUUFVUID0gJyhubyBvdXRwdXQpJztcbmNvbnN0IEFQUF9TVEFURV9GT1JFR1JPVU5EID0gNDtcbmNvbnN0IFdFQlZJRVdfQ09OVEVYVF9QUkVGSVggPSAnV0VCVklFV19tZC5vYnNpZGlhbic7XG5jb25zdCBXRUJWSUVXX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgREVGQVVMVF9XRUJWSUVXX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA2MDAwMDtcbmNvbnN0IExBWU9VVF9SRUFEWV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IERFRkFVTFRfTEFZT1VUX1JFQURZX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA5MDAwMDtcbmNvbnN0IEFQUF9SRVNUQVJUX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5jb25zdCBERUZBVUxUX0FQUF9JRCA9ICdtZC5vYnNpZGlhbic7XG5jb25zdCBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzAwMDA7XG5cbi8vIC0tLSBDb25zb2xlIGNhcHR1cmUgKExheWVyIDIgb2YgdGhlIHBsdWdpbi1sb2FkIGVycm9yIHN1cmZhY2luZywgc2VlIFQ4OCkgLS0tXG5jb25zdCBDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBRyA9ICdPSVRfQ0FQVFVSRSc7XG5jb25zdCBDT05TT0xFX0NBUFRVUkVfVEFJTF9NQVhfTEVOR1RIID0gODAwMDtcbmNvbnN0IEFEQl9MT0dfTUFSS0VSX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IExPR0NBVF9EVU1QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTAwMDA7XG4vKipcbiAqIGBhZGIgbG9nY2F0IC12IHRpbWVgIGxpbmVzIGxvb2sgbGlrZSBgTU0tREQgSEg6TU06U1MubW1tIExFVkVML1RBRyggUElEKTogbWVzc2FnZWAuXG4gKiBLZWVwIG9ubHkgdGhlIHRhZ3MgQ2hyb21pdW0vV2ViVmlldyByb3V0ZXMgSlMgYGNvbnNvbGUuKmAgb3V0cHV0IGFuZCB1bmNhdWdodFxuICogZXJyb3JzIHRvIChgY2hyb21pdW1gLCB0aGUgQ2FwYWNpdG9yIGNvbnNvbGUgYnJpZGdlLCBhbmQgbmF0aXZlIGBBbmRyb2lkUnVudGltZWApLlxuICovXG5jb25zdCBDT05TT0xFX0NBUFRVUkVfVEFHX1JFID0gL1xcLyg/OmNocm9taXVtfEFuZHJvaWRSdW50aW1lfENhcGFjaXRvclxcL0NvbnNvbGUpXFwoLztcblxuLyoqXG4gKiBCYXNlIHBhdGggb24gYW4gQW5kcm9pZCBkZXZpY2Ugd2hlcmUgT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHRzLlxuICpcbiAqIEV4cG9ydGVkIGJlY2F1c2UgdGhlIHRyYW5zcG9ydCBmYWN0b3J5IHN3ZWVwcyBsZWZ0b3ZlciB2YXVsdHMgZnJvbSBpdCBiZWZvcmVcbiAqIGEgdHJhbnNwb3J0IGV4aXN0cyAoc2VlIHRoZSByZXBvJ3MgTDMxKS5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfQU5EUk9JRF9WQVVMVF9CQVNFX1BBVEggPSAnL3NkY2FyZC9Eb2N1bWVudHMvJztcblxuY29uc3QgREVGQVVMVF9WQVVMVF9CQVNFX1BBVEg6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gIGFuZHJvaWQ6IERFRkFVTFRfQU5EUk9JRF9WQVVMVF9CQVNFX1BBVEgsXG4gIGlvczogJ0BtZC5vYnNpZGlhbjpkb2N1bWVudHMvJ1xufTtcblxuaW50ZXJmYWNlIExvYWRpbmdBcHAge1xuICB3b3Jrc3BhY2U/OiBMb2FkaW5nV29ya3NwYWNlO1xufVxuXG5pbnRlcmZhY2UgTG9hZGluZ1dvcmtzcGFjZSB7XG4gIGxheW91dFJlYWR5PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUcmFuc3BvcnQgdGhhdCBjb21tdW5pY2F0ZXMgd2l0aCBPYnNpZGlhbiBNb2JpbGUgdmlhIEFwcGl1bSBXZWJWaWV3IEpTIGluamVjdGlvbi5cbiAqXG4gKiBFdmFsdWF0ZXMgZXhwcmVzc2lvbnMgYnkgc3dpdGNoaW5nIHRvIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dCBhbmRcbiAqIGNhbGxpbmcgYGV4ZWN1dGUoKWAuIE1hbmFnZXMgdmF1bHRzIGJ5IHdyaXRpbmcgdG8gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYFxuICogKHdoaWNoIE9ic2lkaWFuIHVzZXMgYXMgaXRzIHZhdWx0IHJlZ2lzdHJ5IG9uIG1vYmlsZSkgYW5kIHB1c2hpbmcgZmlsZXMgdG8gdGhlIGRldmljZS5cbiAqL1xuZXhwb3J0IGNsYXNzIEFwcGl1bVRyYW5zcG9ydCBpbXBsZW1lbnRzIE9ic2lkaWFuVHJhbnNwb3J0IHtcbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgdHJhbnNwb3J0IGlzIGZvciBhIG1vYmlsZSBwbGF0Zm9ybS4gQWx3YXlzIGB0cnVlYCBmb3IgdGhpcyB0cmFuc3BvcnQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXNNb2JpbGUgPSB0cnVlO1xuICBwcml2YXRlIHJlYWRvbmx5IGFwcElkOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgYnJvd3NlcjogQnJvd3NlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXZpY2VJZDogc3RyaW5nO1xuICAvKipcbiAgICogVHJhY2tzIHdoZXRoZXIgdGhlIGRyaXZlciBpcyBjdXJyZW50bHkgc3dpdGNoZWQgdG8gdGhlIFdlYlZpZXcgY29udGV4dC5cbiAgICpcbiAgICogU2V0IHRvIGB0cnVlYCBhZnRlciBhIHN1Y2Nlc3NmdWwgYHN3aXRjaENvbnRleHQoV0VCVklFV19tZC5vYnNpZGlhbilgLlxuICAgKiBSZXNldCB0byBgZmFsc2VgIHdoZW4gdGhlIGNvbnRleHQgaXMga25vd24gdG8gYmUgaW52YWxpZGF0ZWRcbiAgICogKGUuZy4gYWZ0ZXIgYGxvY2F0aW9uLnJlbG9hZCgpYCBpbiB7QGxpbmsgcmVnaXN0ZXJWYXVsdH0pLlxuICAgKlxuICAgKiBXaGVuIGB0cnVlYCwge0BsaW5rIGVuc3VyZVdlYlZpZXdDb250ZXh0fSBza2lwcyB0aGUgZXhwZW5zaXZlXG4gICAqIGBnZXRDb250ZXh0cygpYCBjYWxsICh3aGljaCBydW5zIGBhZGIgc2hlbGwgY2F0IC9wcm9jL25ldC91bml4YCBhbmRcbiAgICogY2FuIHRpbWUgb3V0IG9uIHNsb3cgZW11bGF0b3JzKS5cbiAgICovXG4gIHByaXZhdGUgaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNTZXNzaW9uT3duZXI6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybTogJ2FuZHJvaWQnIHwgJ2lvcyc7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgdmF1bHRCYXNlUGF0aDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IEFwcGl1bSB0cmFuc3BvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBBcHBpdW0gdHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnOiBBcHBpdW1UcmFuc3BvcnRDb25maWcpIHtcbiAgICB0aGlzLmJyb3dzZXIgPSBjb25maWcuYnJvd3NlcjtcbiAgICB0aGlzLmRldmljZUlkID0gY29uZmlnLmRldmljZUlkO1xuICAgIHRoaXMuaXNTZXNzaW9uT3duZXIgPSBjb25maWcuaXNTZXNzaW9uT3duZXIgPz8gdHJ1ZTtcbiAgICB0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID0gY29uZmlnLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfTEFZT1VUX1JFQURZX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgdGhpcy5wbGF0Zm9ybSA9IGNvbmZpZy5wbGF0Zm9ybTtcbiAgICB0aGlzLmFwcElkID0gY29uZmlnLmFwcElkID8/IERFRkFVTFRfQVBQX0lEO1xuICAgIHRoaXMuc2hvdWxkU3dlZXBMZWZ0b3ZlcnMgPSBjb25maWcuc2hvdWxkU3dlZXBMZWZ0b3ZlcnMgPz8gdHJ1ZTtcbiAgICB0aGlzLnZhdWx0QmFzZVBhdGggPSBjb25maWcudmF1bHRCYXNlUGF0aCA/PyBERUZBVUxUX1ZBVUxUX0JBU0VfUEFUSFt0aGlzLnBsYXRmb3JtXSA/PyBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRIO1xuICAgIHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IGNvbmZpZy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfV0VCVklFV19QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICB9XG5cbiAgLyoqXG4gICAqIEJlZ2lucyBhIGNvbnNvbGUgY2FwdHVyZSBieSBzdGFtcGluZyB0aGUgZGV2aWNlIGxvZyB3aXRoIGEgdW5pcXVlIG1hcmtlci5cbiAgICpcbiAgICogVXNlcyBgYWRiIHNoZWxsIGxvZ2AgdG8gd3JpdGUgYSBtYXJrZXIgaW50byBgbG9nY2F0YCBhdCBjYXB0dXJlIHN0YXJ0IHNvIGFcbiAgICogbGF0ZXIge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5yZWFkQ29uc29sZUNhcHR1cmVTaW5jZX0gY2FuIHNsaWNlIG91dFxuICAgKiBldmVyeXRoaW5nIHRoZSBXZWJWaWV3IGxvZ2dlZCBhZnRlcndhcmRzIFx1MjAxNCB3aXRob3V0IHRoZSBpbnZhc2l2ZSBgbG9nY2F0IC1jYFxuICAgKiBidWZmZXIgY2xlYXIuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgaGFuZGxlIGNhcnJ5aW5nIHRoZSB1bmlxdWUgbWFya2VyLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGJlZ2luQ29uc29sZUNhcHR1cmUoKTogUHJvbWlzZTxDb25zb2xlQ2FwdHVyZUhhbmRsZT4ge1xuICAgIGNvbnN0IG1hcmtlciA9IGAke0NPTlNPTEVfQ0FQVFVSRV9NQVJLRVJfVEFHfV8ke3JhbmRvbVVVSUQoKX1gO1xuICAgIGF3YWl0IGV4ZWMoXG4gICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdsb2cnLCAnLXQnLCBDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBRywgbWFya2VyXSxcbiAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX0xPR19NQVJLRVJfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfVxuICAgICk7XG4gICAgcmV0dXJuIHsgbWFya2VyIH07XG4gIH1cblxuICAvKipcbiAgICogRW5kcyB0aGUgQXBwaXVtIHNlc3Npb24uXG4gICAqXG4gICAqIE9ubHkgZGVsZXRlcyB0aGUgc2Vzc2lvbiBpZiB0aGlzIHRyYW5zcG9ydCBvd25zIGl0LiBUcmFuc3BvcnRzIGNyZWF0ZWRcbiAgICogdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycyByZXVzaW5nIHRoZSBnbG9iYWwgc2V0dXAncyBzZXNzaW9uKSBza2lwXG4gICAqIGRlbGV0aW9uIHNvIHRoZSBzZXNzaW9uIHJlbWFpbnMgYXZhaWxhYmxlIGZvciB0aGUgb3duaW5nIHByb2Nlc3MuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc1Nlc3Npb25Pd25lcikge1xuICAgICAgYXdhaXQgdGhpcy5icm93c2VyLmRlbGV0ZVNlc3Npb24oKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXZhbHVhdGVzIGEgSmF2YVNjcmlwdCBleHByZXNzaW9uIGluc2lkZSBPYnNpZGlhbiBNb2JpbGUncyBXZWJWaWV3LlxuICAgKlxuICAgKiBTd2l0Y2hlcyB0byB0aGUgYFdFQlZJRVdfbWQub2JzaWRpYW5gIGNvbnRleHQsIGV4ZWN1dGVzIHRoZSBleHByZXNzaW9uLFxuICAgKiBhbmQgcmV0dXJucyB0aGUgcmVzdWx0IHN0cmluZy5cbiAgICpcbiAgICogQHBhcmFtIGV4cHJlc3Npb24gLSBUaGUgSmF2YVNjcmlwdCBleHByZXNzaW9uIHRvIGV2YWx1YXRlLlxuICAgKiBAcGFyYW0gX29wdGlvbnMgLSBFdmFsdWF0aW9uIG9wdGlvbnMgKGN3ZCBpcyBub3QgdXNlZCBvbiBtb2JpbGUgXHUyMDE0IHZhdWx0IHRhcmdldGluZyBpcyB2aWEgbG9jYWxTdG9yYWdlKS5cbiAgICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgcmVzdWx0IHN0cmluZy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBldmFsdWF0ZShleHByZXNzaW9uOiBzdHJpbmcsIF9vcHRpb25zOiBUcmFuc3BvcnRFdmFsT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVXZWJWaWV3Q29udGV4dCgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlPG51bGwgfCBzdHJpbmcgfCB1bmRlZmluZWQsIFtdPihcbiAgICAgICAgYHJldHVybiAoJHtleHByZXNzaW9ufSlgXG4gICAgICApO1xuXG4gICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQgfHwgcmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBOT19PVVRQVVQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIENvbnRleHQgbWF5IGhhdmUgYmVlbiBsb3N0IG1pZC1leGVjdXRpb24gKGUuZy4gcGFnZSByZWxvYWQpLlxuICAgICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSBmYWxzZTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzZXNzaW9uIGNvbm5lY3Rpb24gaW5mbyBuZWVkZWQgdG8gcmVhdHRhY2ggdG8gdGhpcyBzZXNzaW9uXG4gICAqIGZyb20gYW5vdGhlciBwcm9jZXNzIChlLmcuIGEgdGVzdCB3b3JrZXIpLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2Vzc2lvbiBJRCBhbmQgZGV2aWNlIElELlxuICAgKi9cbiAgcHVibGljIGdldFNlc3Npb25JbmZvKCk6IEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGV2aWNlSWQ6IHRoaXMuZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHRoaXMuYnJvd3Nlci5zZXNzaW9uSWRcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHRoYXQgdGhlIE9ic2lkaWFuIGFwcCBpcyBydW5uaW5nIGFuZCB0aGUgV2ViVmlldyBpcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBwYXJhbSBfdmF1bHRQYXRoIC0gTm90IHVzZWQgb24gbW9iaWxlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHByZWZsaWdodENoZWNrKF92YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZygnW2FwcGl1bS10cmFuc3BvcnRdIFJ1bm5pbmcgcHJlZmxpZ2h0IGNoZWNrLi4uJyk7XG4gICAgY29uc3Qgc3RhdGUgPSBhd2FpdCB0aGlzLmJyb3dzZXIucXVlcnlBcHBTdGF0ZSh0aGlzLmFwcElkKTtcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBBcHAgc3RhdGU6ICR7U3RyaW5nKHN0YXRlKX0gKG5lZWQgJHtTdHJpbmcoQVBQX1NUQVRFX0ZPUkVHUk9VTkQpfT1mb3JlZ3JvdW5kKWApO1xuICAgIGlmIChzdGF0ZSAhPT0gQVBQX1NUQVRFX0ZPUkVHUk9VTkQpIHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIEFjdGl2YXRpbmcgYXBwICR7dGhpcy5hcHBJZH0uLi5gKTtcbiAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuYWN0aXZhdGVBcHAodGhpcy5hcHBJZCk7XG4gICAgICBhd2FpdCBkZWxheShBUFBfUkVTVEFSVF9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcbiAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBQcmVmbGlnaHQgY2hlY2sgcGFzc2VkLicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1c2hlcyB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIHZpYSBjb21wcmVzc2VkIGBhZGIgcHVzaGAuXG4gICAqXG4gICAqIENyZWF0ZXMgYSB0YXIuZ3ogYXJjaGl2ZSBvZiB0aGUgbG9jYWwgdmF1bHQgZGlyZWN0b3J5LCBwdXNoZXMgaXQgdG8gdGhlXG4gICAqIGRldmljZSBhcyBhIHNpbmdsZSBmaWxlLCBhbmQgZXh0cmFjdHMgaXQgaW4tcGxhY2UuIFRoaXMgYXZvaWRzIHRoZVxuICAgKiB3ZWJkcml2ZXIgYFJhbmdlRXJyb3JgIG9uIGxhcmdlIGJhc2U2NCBwYXlsb2FkcyBhbmQgaXMgc2lnbmlmaWNhbnRseVxuICAgKiBmYXN0ZXIgdGhhbiBwZXItZmlsZSBgYnJvd3Nlci5wdXNoRmlsZSgpYCBjYWxscy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoICh1c2VkIGFzIHRoZSB2YXVsdCBkaXJlY3RvcnkgbmFtZSBvbiBkZXZpY2UpLlxuICAgKiBAcGFyYW0gX2ZpbGVzIC0gTWFwIG9mIHJlbGF0aXZlIGZpbGUgcGF0aHMgdG8gY29udGVudCBidWZmZXJzICh1bnVzZWQgXHUyMDE0IGFkYiBwdXNoZXMgdGhlIGRpcmVjdG9yeSBkaXJlY3RseSkuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcHVzaEZpbGVzKHZhdWx0UGF0aDogc3RyaW5nLCBfZmlsZXM6IFJlY29yZDxzdHJpbmcsIFVpbnQ4QXJyYXk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcbiAgICBjb25zdCBhcmNoaXZlTmFtZSA9IGB2YXVsdC0ke3JhbmRvbVVVSUQoKX0udGFyLmd6YDtcbiAgICBjb25zdCBsb2NhbEFyY2hpdmUgPSBqb2luKHRtcGRpcigpLCBhcmNoaXZlTmFtZSk7XG4gICAgY29uc3QgcmVtb3RlQXJjaGl2ZSA9IGAvZGF0YS9sb2NhbC90bXAvJHthcmNoaXZlTmFtZX1gO1xuXG4gICAgdHJ5IHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIENyZWF0aW5nIGFyY2hpdmU6ICR7bG9jYWxBcmNoaXZlfWApO1xuICAgICAgYXdhaXQgZXhlYyhbJ3RhcicsICdjemYnLCBhcmNoaXZlTmFtZSwgJy1DJywgdmF1bHRQYXRoLCAnLiddLCB7IGN3ZDogdG1wZGlyKCksIGlzUXVpZXQ6IHRydWUgfSk7XG5cbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFB1c2hpbmcgYXJjaGl2ZSB0byBkZXZpY2UgJHt0aGlzLmRldmljZUlkfS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdwdXNoJywgbG9jYWxBcmNoaXZlLCByZW1vdGVBcmNoaXZlXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBFeHRyYWN0aW5nIGFyY2hpdmUgb24gZGV2aWNlIGF0ICR7ZGV2aWNlVmF1bHRQYXRofS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdta2RpcicsICctcCcsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAndGFyJywgJ3h6ZicsIHJlbW90ZUFyY2hpdmUsICctQycsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gRmx1c2hpbmcgZmlsZXN5c3RlbSBidWZmZXJzLi4uJyk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3N5bmMnXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBDbGVhbmluZyB1cCByZW1vdGUgYXJjaGl2ZS4uLicpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdybScsIHJlbW90ZUFyY2hpdmVdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJtKGxvY2FsQXJjaGl2ZSwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRHVtcHMgYGFkYiBsb2djYXRgIGFuZCByZXR1cm5zIHRoZSBXZWJWaWV3IGNvbnNvbGUvZXJyb3Igb3V0cHV0IGxvZ2dlZFxuICAgKiBzaW5jZSB0aGUgbWFya2VyIGZyb20ge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5iZWdpbkNvbnNvbGVDYXB0dXJlfS5cbiAgICpcbiAgICogRmlsdGVycyB0byB0aGUgQ2hyb21pdW0vV2ViVmlldyB0YWdzIHRoYXQgY2FycnkgSlMgYGNvbnNvbGUuKmAgb3V0cHV0IGFuZFxuICAgKiB1bmNhdWdodCBlcnJvcnMsIGFuZCBjYXBzIHRoZSByZXN1bHQgbGVuZ3RoLiBCb3VuZGVkLCBwb3N0LWhvYyxcbiAgICogZmFpbHVyZS1wYXRoLW9ubHkgXHUyMDE0IG5ldmVyIGEgbGl2ZSBtb25pdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gaGFuZGxlIC0gVGhlIGNhcHR1cmUgaGFuZGxlIChvciBgdW5kZWZpbmVkYCB3aGVuIGNhcHR1cmUgbmV2ZXIgc3RhcnRlZCkuXG4gICAqIEByZXR1cm5zIFRoZSBjYXB0dXJlZCBjb25zb2xlL2Vycm9yIHRleHQsIG9yIGB1bmRlZmluZWRgIGlmIG5vdGhpbmcgcmVsZXZhbnQgd2FzIGxvZ2dlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWFkQ29uc29sZUNhcHR1cmVTaW5jZShoYW5kbGU6IENvbnNvbGVDYXB0dXJlSGFuZGxlIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoIWhhbmRsZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBkdW1wID0gYXdhaXQgZXhlYyhcbiAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ2xvZ2NhdCcsICctZCcsICctdicsICd0aW1lJ10sXG4gICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IExPR0NBVF9EVU1QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICApO1xuXG4gICAgY29uc3QgbWFya2VySW5kZXggPSBkdW1wLmxhc3RJbmRleE9mKGhhbmRsZS5tYXJrZXIpO1xuICAgIGNvbnN0IHJlZ2lvbiA9IG1hcmtlckluZGV4ID09PSAtMSA/IGR1bXAgOiBkdW1wLnNsaWNlKG1hcmtlckluZGV4ICsgaGFuZGxlLm1hcmtlci5sZW5ndGgpO1xuICAgIGNvbnN0IHJlbGV2YW50ID0gcmVnaW9uXG4gICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAuZmlsdGVyKChsaW5lKSA9PiBDT05TT0xFX0NBUFRVUkVfVEFHX1JFLnRlc3QobGluZSkpXG4gICAgICAuam9pbignXFxuJylcbiAgICAgIC50cmltKCk7XG5cbiAgICBpZiAoIXJlbGV2YW50KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiByZWxldmFudC5zbGljZSgtQ09OU09MRV9DQVBUVVJFX1RBSUxfTUFYX0xFTkdUSCk7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgdmF1bHQgb24gbW9iaWxlIGJ5IHB1c2hpbmcgZmlsZXMgYW5kIGNvbmZpZ3VyaW5nIGxvY2FsU3RvcmFnZS5cbiAgICpcbiAgICogVGhlIHJlZ2lzdHJhdGlvbiBmbG93OlxuICAgKiAxLiBQdXNoIGEgbWluaW1hbCBgLm9ic2lkaWFuL2FwcC5qc29uYCB0byB0aGUgZGV2aWNlIHNvIE9ic2lkaWFuIHJlY29nbml6ZXMgdGhlIHZhdWx0XG4gICAqIDIuIFN3aXRjaCB0byB0aGUgV2ViVmlldyBjb250ZXh0XG4gICAqIDMuIEFkZCB0aGUgdmF1bHQgdG8gbG9jYWxTdG9yYWdlIChgbW9iaWxlLWV4dGVybmFsLXZhdWx0c2AsIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgLFxuICAgKiAgICBgZW5hYmxlLXBsdWdpbi08cGF0aD5gKVxuICAgKiA0LiBUcmlnZ2VyIGBsb2NhdGlvbi5yZWxvYWQoKWAgc28gT2JzaWRpYW4gcmUtcmVhZHMgbG9jYWxTdG9yYWdlIGFuZCBvcGVucyB0aGUgdmF1bHRcbiAgICogNS4gV2FpdCBmb3IgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgXG4gICAqXG4gICAqIEV4aXN0aW5nIHZhdWx0IHJlZ2lzdHJhdGlvbnMgaW4gbG9jYWxTdG9yYWdlIGFyZSBwcmVzZXJ2ZWQgKGFwcGVuZCwgbm90XG4gICAqIG92ZXJ3cml0ZSkgXHUyMDE0IGV4Y2VwdCB0aGUgKipoYXJuZXNzJ3Mgb3duKiogYHRlbXAtdmF1bHQtKmAgcmVnaXN0cmF0aW9ucyBmcm9tXG4gICAqIGVhcmxpZXIgcnVucywgd2hpY2ggYXJlIHBydW5lZCB3aGVuIHtAbGluayBBcHBpdW1UcmFuc3BvcnRDb25maWcuc2hvdWxkU3dlZXBMZWZ0b3ZlcnN9XG4gICAqIGlzIG9uLiBUaGVpciBkaXJlY3RvcmllcyBhcmUgYWxyZWFkeSBnb25lICh0aGUgZmFjdG9yeSBzd2VlcHMgdGhlbSBiZWZvcmVcbiAgICogdGhlIGFwcCBsYXVuY2hlcyksIGFuZCBpdCBpcyB0aGlzIHJlZ2lzdHJ5IFx1MjAxNCBub3QgdGhlIGZpbGVzeXN0ZW0gXHUyMDE0IHRoYXRcbiAgICogT2JzaWRpYW4gZW51bWVyYXRlcyBhdCBzdGFydHVwLCBzbyBsZWF2aW5nIHRoZW0gaXMgd2hhdCBtYWtlcyBlYWNoIGZhaWxlZFxuICAgKiBydW4gc2xvdyB0aGUgbmV4dCBvbmUgZG93bi5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBSZWdpc3RlcmluZyB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcblxuICAgIC8vIFB1c2ggYSBtaW5pbWFsIC5vYnNpZGlhbiBkaXJlY3Rvcnkgc28gT2JzaWRpYW4gcmVjb2duaXplcyBpdCBhcyBhIHZhdWx0LlxuICAgIGF3YWl0IHRoaXMucHVzaE9ic2lkaWFuTWFya2VyKGRldmljZVZhdWx0UGF0aCk7XG5cbiAgICAvLyBTd2l0Y2ggdG8gV2ViVmlldyBhbmQgY29uZmlndXJlIGxvY2FsU3RvcmFnZS5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG5cbiAgICAvLyBJbnZhbGlkYXRlIGJlZm9yZSByZWxvYWQgXHUyMDE0IHRoZSBwYWdlIHdpbGwgbmF2aWdhdGUgYW5kIHRoZSBXZWJWaWV3XG4gICAgLy8gQ29udGV4dCBtYXkgYmUgdGVtcG9yYXJpbHkgdW5hdmFpbGFibGUgZHVyaW5nIHJlbG9hZC5cbiAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc3RhbGVQcmVmaXggPSB0aGlzLnNob3VsZFN3ZWVwTGVmdG92ZXJzID8gYCR7dGhpcy52YXVsdEJhc2VQYXRofSR7VEVNUF9WQVVMVF9ESVJfUFJFRklYfWAgOiAnJztcblxuICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKFxuICAgICAgKHBhdGg6IHN0cmluZywgcHJ1bmVQcmVmaXg6IHN0cmluZykgPT4ge1xuICAgICAgICBsZXQgZXhpc3RpbmcgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJykgPz8gJ1tdJykgYXMgc3RyaW5nW107XG5cbiAgICAgICAgaWYgKHBydW5lUHJlZml4KSB7XG4gICAgICAgICAgY29uc3Qgc3RhbGUgPSBleGlzdGluZy5maWx0ZXIoKHJlZ2lzdGVyZWQpID0+IHJlZ2lzdGVyZWQgIT09IHBhdGggJiYgcmVnaXN0ZXJlZC5zdGFydHNXaXRoKHBydW5lUHJlZml4KSk7XG4gICAgICAgICAgZm9yIChjb25zdCByZWdpc3RlcmVkIG9mIHN0YWxlKSB7XG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShgZW5hYmxlLXBsdWdpbi0ke3JlZ2lzdGVyZWR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV4aXN0aW5nID0gZXhpc3RpbmcuZmlsdGVyKChyZWdpc3RlcmVkKSA9PiAhc3RhbGUuaW5jbHVkZXMocmVnaXN0ZXJlZCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFleGlzdGluZy5pbmNsdWRlcyhwYXRoKSkge1xuICAgICAgICAgIGV4aXN0aW5nLnB1c2gocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnLCBKU09OLnN0cmluZ2lmeShleGlzdGluZykpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0JywgcGF0aCk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGBlbmFibGUtcGx1Z2luLSR7cGF0aH1gLCAndHJ1ZScpO1xuICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgIH0sXG4gICAgICBkZXZpY2VWYXVsdFBhdGgsXG4gICAgICBzdGFsZVByZWZpeFxuICAgICk7XG5cbiAgICAvLyBXYWl0IGZvciByZWxvYWQgKyB2YXVsdCBpbml0aWFsaXphdGlvbi5cbiAgICBhd2FpdCB0aGlzLndhaXRGb3JMYXlvdXRSZWFkeSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIGEgdmF1bHQgb24gbW9iaWxlIGJ5IHJlbW92aW5nIGl0IGZyb20gbG9jYWxTdG9yYWdlLlxuICAgKlxuICAgKiBQcmVzZXJ2ZXMgb3RoZXIgdmF1bHQgcmVnaXN0cmF0aW9ucy4gSWYgdGhlIHVucmVnaXN0ZXJlZCB2YXVsdCB3YXMgc2VsZWN0ZWQsXG4gICAqIHN3aXRjaGVzIHRvIHRoZSBmaXJzdCByZW1haW5pbmcgdmF1bHQgKG9yIGNsZWFycyB0aGUgc2VsZWN0aW9uKS5cbiAgICpcbiAgICogVGhlIHZhdWx0J3MgKipmaWxlcyBhcmUgdGhlbiByZW1vdmVkIGZyb20gdGhlIGRldmljZSBvdmVyIGBhZGJgLCB3aGV0aGVyIG9yXG4gICAqIG5vdCB0aGUgYGxvY2FsU3RvcmFnZWAgc3RlcCBzdWNjZWVkZWQqKiBcdTIwMTQgZGVsaWJlcmF0ZWx5LCBiZWNhdXNlIHRoZVxuICAgKiBgbG9jYWxTdG9yYWdlYCBzdGVwIGdvZXMgdGhyb3VnaCB0aGUgV2ViVmlldyBhbmQgYSBkZWFkIFdlYlZpZXcgaXMgZXhhY3RseVxuICAgKiB3aGF0IG1vc3QgQW5kcm9pZCBmYWlsdXJlcyBhcmUuIFJvdXRpbmcgdGhlIHJlbW92YWwgdGhyb3VnaCB0aGUgYXBwIHdhcyB3aGF0XG4gICAqIG1hZGUgZXZlcnkgZmFpbGVkIHJ1biBsZWFrIGl0cyB2YXVsdCAoYFZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6IG5vXG4gICAqIHN1Y2ggd2luZG93YCksIHNvIHRoZSBmaWxlc3lzdGVtLWxldmVsIHJlbW92YWwgbXVzdCBub3QgZGVwZW5kIG9uIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IG9uIHRoZSBob3N0IG1hY2hpbmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdW5yZWdpc3RlclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJykgPz8gJ1tdJykgYXMgc3RyaW5nW107XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gZXhpc3RpbmcuZmlsdGVyKCh2KSA9PiB2ICE9PSBwYXRoKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnLCBKU09OLnN0cmluZ2lmeShmaWx0ZXJlZCkpO1xuICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShgZW5hYmxlLXBsdWdpbi0ke3BhdGh9YCk7XG4gICAgICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0JykgPT09IHBhdGgpIHtcbiAgICAgICAgICBpZiAoZmlsdGVyZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcsIGZpbHRlcmVkWzBdID8/ICcnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSwgZGV2aWNlVmF1bHRQYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKFxuICAgICAgICBgW2FwcGl1bS10cmFuc3BvcnRdIENvdWxkIG5vdCBkZXJlZ2lzdGVyICR7ZGV2aWNlVmF1bHRQYXRofSBmcm9tIGxvY2FsU3RvcmFnZSBgXG4gICAgICAgICAgKyBgKCR7U3RyaW5nKGVycm9yKX0pOyByZW1vdmluZyBpdHMgZmlsZXMgYW55d2F5LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZW1vdmVEZXZpY2VWYXVsdERpcihkZXZpY2VWYXVsdFBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN3aXRjaGVzIHRoZSBkcml2ZXIgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0LlxuICAgKlxuICAgKiBJZiB0aGUgY29udGV4dCB3YXMgYWxyZWFkeSB2ZXJpZmllZCAoY2FjaGVkIHZpYSB7QGxpbmsgaXNJbldlYlZpZXdDb250ZXh0fSksXG4gICAqIHJldHVybnMgaW1tZWRpYXRlbHkgd2l0aG91dCBjYWxsaW5nIGBnZXRDb250ZXh0cygpYCBcdTIwMTQgd2hpY2ggcnVuc1xuICAgKiBgYWRiIHNoZWxsIGNhdCAvcHJvYy9uZXQvdW5peGAgYW5kIGNhbiB0aW1lIG91dCBvbiBzbG93IGVtdWxhdG9ycy5cbiAgICpcbiAgICogUG9sbHMgdW50aWwgdGhlIGNvbnRleHQgYmVjb21lcyBhdmFpbGFibGUgKHRoZSBhcHAgbWF5IHN0aWxsIGJlIGxvYWRpbmcpLlxuICAgKiBVc2VzIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dCBzcGVjaWZpY2FsbHkgdG8gYXZvaWQgY29ubmVjdGluZ1xuICAgKiB0byBDaHJvbWUgb3Igb3RoZXIgV2ViVmlld3Mgb24gdGhlIGRldmljZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlV2ViVmlld0NvbnRleHQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNJbldlYlZpZXdDb250ZXh0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgdGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdhaXRpbmcgZm9yICR7V0VCVklFV19DT05URVhUX1BSRUZJWH0gY29udGV4dCAodGltZW91dD0ke1N0cmluZyh0aGlzLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zKS4uLmApO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgY29uc3QgY29udGV4dHMgPSBhd2FpdCB0aGlzLmJyb3dzZXIuZ2V0Q29udGV4dHMoKTtcbiAgICAgIGNvbnN0IG9ic2lkaWFuQ29udGV4dCA9IGNvbnRleHRzLmZpbmQoKGN0eCk6IGN0eCBpcyBzdHJpbmcgPT4gdHlwZW9mIGN0eCA9PT0gJ3N0cmluZycgJiYgY3R4LnN0YXJ0c1dpdGgoV0VCVklFV19DT05URVhUX1BSRUZJWCkpO1xuXG4gICAgICBpZiAob2JzaWRpYW5Db250ZXh0KSB7XG4gICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIEZvdW5kIFdlYlZpZXcgY29udGV4dDogJHtvYnNpZGlhbkNvbnRleHR9YCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLnN3aXRjaENvbnRleHQob2JzaWRpYW5Db250ZXh0KTtcbiAgICAgICAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIHN3aXRjaENvbnRleHQgZmFpbGVkOiAke1N0cmluZyhlcnJvcil9LiBSZXNldHRpbmcgdG8gTkFUSVZFX0FQUCBiZWZvcmUgcmV0cnlpbmcuLi5gKTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLnN3aXRjaENvbnRleHQoJ05BVElWRV9BUFAnKTtcbiAgICAgICAgICB9IGNhdGNoIChyZXNldEVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBOQVRJVkVfQVBQIHJlc2V0IGFsc28gZmFpbGVkOiAke1N0cmluZyhyZXNldEVycm9yKX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gV2ViVmlldyBub3QgcmVhZHksIGF2YWlsYWJsZSBjb250ZXh0czogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0cyl9LiBSZXRyeWluZy4uLmApO1xuICAgICAgYXdhaXQgZGVsYXkoV0VCVklFV19QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBObyAke1dFQlZJRVdfQ09OVEVYVF9QUkVGSVh9IGNvbnRleHQgZm91bmQgd2l0aGluICR7U3RyaW5nKHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMuIElzIHRoZSBPYnNpZGlhbiBhcHAgZnVsbHkgbG9hZGVkP2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgaG9zdC1zaWRlIHZhdWx0IHBhdGggdG8gdGhlIGRldmljZS1zaWRlIHBhdGguXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBBYnNvbHV0ZSBwYXRoIG9uIHRoZSBob3N0IG1hY2hpbmUuXG4gICAqIEByZXR1cm5zIFRoZSBkZXZpY2Utc2lkZSB2YXVsdCBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnZhdWx0QmFzZVBhdGh9JHtleHRyYWN0VmF1bHROYW1lKHZhdWx0UGF0aCl9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXNoZXMgdGhlIG1pbmltYWwgYC5vYnNpZGlhbi9hcHAuanNvbmAgdmF1bHQgbWFya2VyIHZpYSBgYWRiIHB1c2hgLlxuICAgKlxuICAgKiBgYnJvd3Nlci5wdXNoRmlsZWAgKFdlYkRyaXZlciBiYXNlNjQpIGlzIGFuIG9yZGVyIG9mIG1hZ25pdHVkZSBzbG93ZXIgb24gYVxuICAgKiBjb2xkIG9yIGxvYWRlZCBlbXVsYXRvciBcdTIwMTQgbWVhc3VyZWQgYXQgOVx1MjAxMzIxcyBwZXIgY2FsbCBmb3IgdGhpcyAyLWJ5dGUgbWFya2VyLFxuICAgKiB2ZXJzdXMgc3ViLXNlY29uZCBvdmVyIGBhZGJgLiBUaGlzIG1pcnJvcnMge0BsaW5rIHB1c2hGaWxlc30sIHdoaWNoIHN3aXRjaGVkXG4gICAqIHRvIGBhZGJgIGZvciB0aGUgc2FtZSByZWFzb24uIGBta2RpciAtcGAgZ3VhcmFudGVlcyB0aGUgcGFyZW50IGRpcmVjdG9yeS5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZVZhdWx0UGF0aCAtIFRoZSBkZXZpY2Utc2lkZSB2YXVsdCBkaXJlY3RvcnkgcGF0aC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcHVzaE9ic2lkaWFuTWFya2VyKGRldmljZVZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9jYWxNYXJrZXIgPSBqb2luKHRtcGRpcigpLCBgb2JzaWRpYW4tbWFya2VyLSR7cmFuZG9tVVVJRCgpfS5qc29uYCk7XG4gICAgY29uc3QgcmVtb3RlTWFya2VyID0gYCR7ZGV2aWNlVmF1bHRQYXRofS8ub2JzaWRpYW4vYXBwLmpzb25gO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHdyaXRlRmlsZShsb2NhbE1hcmtlciwgJ3t9JywgJ3V0Zi04Jyk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ21rZGlyJywgJy1wJywgYCR7ZGV2aWNlVmF1bHRQYXRofS8ub2JzaWRpYW5gXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdwdXNoJywgbG9jYWxNYXJrZXIsIHJlbW90ZU1hcmtlcl0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcm0obG9jYWxNYXJrZXIsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSB2YXVsdCBkaXJlY3RvcnkgZnJvbSB0aGUgZGV2aWNlIG92ZXIgYGFkYmAsIGFuZCBDSEVDS1MgdGhhdCBpdCBpc1xuICAgKiBhY3R1YWxseSBnb25lLlxuICAgKlxuICAgKiBCZXN0LWVmZm9ydDogYSBmYWlsdXJlIGlzIGxvZ2dlZCwgbm90IHRocm93biwgc28gYSB0ZWFyZG93biBwcm9ibGVtIG5ldmVyXG4gICAqIG1hc2tzIHRoZSB0ZXN0IHJlc3VsdC4gVGhlIG5leHQgcnVuJ3Mgc3RhcnQtb2YtcnVuIHN3ZWVwIHBpY2tzIHVwIHdoYXRldmVyXG4gICAqIHRoaXMgY291bGQgbm90IHJlbW92ZS5cbiAgICpcbiAgICogVGhlIGNoZWNrIGlzIHRoZSBwb2ludC4gYHJtIC1yZmAgcnVucyB3aXRoIGBzaG91bGRJZ25vcmVFeGl0Q29kZWAsIHNvIGFuXG4gICAqIHVucmVtb3ZlZCBkaXJlY3RvcnkgdXNlZCB0byBsZWF2ZSBubyB0cmFjZSBhdCBhbGwgXHUyMDE0IHdoaWNoIGlzIGhvdyBydW5zIHRoYXRcbiAgICogcGFzc2VkIGVuZCB0byBlbmQgd2VyZSBzdGlsbCBmb3VuZCB0byBiZSBsZWFraW5nIGEgdmF1bHQgYXBpZWNlLCBpbnZpc2libHksXG4gICAqIHVudGlsIHNvbWVvbmUgY291bnRlZCB0aGUgZGlyZWN0b3JpZXMgb24gdGhlIGRldmljZSBieSBoYW5kLiBBIGxlYWsgaXMgbm93XG4gICAqIG5hbWVkIGluIHRoZSBsb2cgYXQgdGhlIG1vbWVudCBpdCBoYXBwZW5zLlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlVmF1bHRQYXRoIC0gVGhlIGRldmljZS1zaWRlIHZhdWx0IGRpcmVjdG9yeSBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZW1vdmVEZXZpY2VWYXVsdERpcihkZXZpY2VWYXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBSZW1vdmluZyB2YXVsdCBkaXJlY3RvcnkgZnJvbSBkZXZpY2U6ICR7ZGV2aWNlVmF1bHRQYXRofWApO1xuICAgICAgYXdhaXQgZXhlYyhcbiAgICAgICAgWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAncm0nLCAnLXJmJywgZGV2aWNlVmF1bHRQYXRoXSxcbiAgICAgICAgeyBpc1F1aWV0OiB0cnVlLCBzaG91bGRJZ25vcmVFeGl0Q29kZTogdHJ1ZSwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGxpc3RpbmcgPSBhd2FpdCBleGVjKFxuICAgICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdscycsICctZCcsIGRldmljZVZhdWx0UGF0aF0sXG4gICAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX1ZBVUxUX1JFTU9WRV9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgICApO1xuXG4gICAgICBpZiAobGlzdGluZy5pbmNsdWRlcyhkZXZpY2VWYXVsdFBhdGgpKSB7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICBgW2FwcGl1bS10cmFuc3BvcnRdIFdhcm5pbmc6ICR7ZGV2aWNlVmF1bHRQYXRofSBzdXJ2aXZlZCByZW1vdmFsIGFuZCBpcyBub3cgbGVha2VkIHJlc2lkdWUuIGBcbiAgICAgICAgICAgICsgJ1RoZSBuZXh0IHJ1blxcJ3Mgc3RhcnQtb2YtcnVuIHN3ZWVwIHdpbGwgcmV0cnkgaXQuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBWYXVsdCBkaXJlY3RvcnkgcmVtb3ZhbCBmYWlsZWQgKG5vbi1mYXRhbCk6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgdW50aWwgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgIGlzIGB0cnVlYCBpbiB0aGUgV2ViVmlldy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckxheW91dFJlYWR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IHN0YXJ0ICsgdGhpcy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBXYWl0aW5nIGZvciBsYXlvdXQgcmVhZHkgKHRpbWVvdXQ9JHtTdHJpbmcodGhpcy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMpLi4uYCk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpc1JlYWR5ID0gYXdhaXQgdGhpcy5icm93c2VyLmV4ZWN1dGUoKCk6IGJvb2xlYW4gPT4ge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZGVwcmVjYXRlZCAtLSBXZSBuZWVkIGdsb2JhbCBgYXBwYCB2YXJpYWJsZS5cbiAgICAgICAgICBjb25zdCBhcHAgPSB3aW5kb3cuYXBwIGFzIExvYWRpbmdBcHAgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgcmV0dXJuICEhYXBwPy53b3Jrc3BhY2U/LmxheW91dFJlYWR5O1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGlzUmVhZHkpIHtcbiAgICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBMYXlvdXQgaXMgcmVhZHkgYWZ0ZXIgJHtTdHJpbmcoRGF0ZS5ub3coKSAtIHN0YXJ0KX1tcy5gKTtcbiAgICAgICAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gQXBwIG5vdCByZWFkeSB5ZXQgKHBhZ2UgbWF5IGJlIHJlbG9hZGluZykuXG4gICAgICB9XG5cbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIExheW91dCBub3QgcmVhZHkgeWV0IChlbGFwc2VkPSR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMpLiBSZXRyeWluZy4uLmApO1xuICAgICAgYXdhaXQgZGVsYXkoTEFZT1VUX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE9ic2lkaWFuIGxheW91dCBkaWQgbm90IGJlY29tZSByZWFkeSB3aXRoaW4gJHtTdHJpbmcodGhpcy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXNgKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGdpdmVuIGRlbGF5LlxuICpcbiAqIEBwYXJhbSBtcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgc2V0VGltZW91dChyZXNvbHZlLCBtcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSB2YXVsdCBkaXJlY3RvcnkgbmFtZSBmcm9tIGEgaG9zdC1zaWRlIHZhdWx0IHBhdGguXG4gKlxuICogQHBhcmFtIHZhdWx0UGF0aCAtIEFic29sdXRlIHBhdGggb24gdGhlIGhvc3QgbWFjaGluZS5cbiAqIEByZXR1cm5zIFRoZSBsYXN0IHBhdGggc2VnbWVudCAodmF1bHQgZGlyZWN0b3J5IG5hbWUpLlxuICovXG5mdW5jdGlvbiBleHRyYWN0VmF1bHROYW1lKHZhdWx0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHZhdWx0UGF0aC5yZXBsYWNlKC9bXFxcXC9dKyQvLCAnJyk7XG4gIGNvbnN0IGxhc3RTZXAgPSBNYXRoLm1heChub3JtYWxpemVkLmxhc3RJbmRleE9mKCcvJyksIG5vcm1hbGl6ZWQubGFzdEluZGV4T2YoJ1xcXFwnKSk7XG4gIHJldHVybiBub3JtYWxpemVkLnNsaWNlKGxhc3RTZXAgKyAxKTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQTRDQSx5QkFBMkI7QUFDM0Isc0JBR087QUFDUCxxQkFBdUI7QUFDdkIsdUJBQXFCO0FBUXJCLGtCQUFxQjtBQUNyQiw4QkFBc0M7QUFDdEMsaUJBQW9CO0FBMEZwQixNQUFNLFlBQVk7QUFDbEIsTUFBTSx1QkFBdUI7QUFDN0IsTUFBTSx5QkFBeUI7QUFDL0IsTUFBTSx3Q0FBd0M7QUFDOUMsTUFBTSwrQ0FBK0M7QUFDckQsTUFBTSw2Q0FBNkM7QUFDbkQsTUFBTSxvREFBb0Q7QUFDMUQsTUFBTSxvQ0FBb0M7QUFDMUMsTUFBTSxpQkFBaUI7QUFDdkIsTUFBTSwyQ0FBMkM7QUFH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
|
|
@@ -298,12 +298,19 @@ export declare class AppiumTransport implements ObsidianTransport {
|
|
|
298
298
|
*/
|
|
299
299
|
private pushObsidianMarker;
|
|
300
300
|
/**
|
|
301
|
-
* Removes a vault directory from the device over `adb
|
|
301
|
+
* Removes a vault directory from the device over `adb`, and CHECKS that it is
|
|
302
|
+
* actually gone.
|
|
302
303
|
*
|
|
303
304
|
* Best-effort: a failure is logged, not thrown, so a teardown problem never
|
|
304
305
|
* masks the test result. The next run's start-of-run sweep picks up whatever
|
|
305
306
|
* this could not remove.
|
|
306
307
|
*
|
|
308
|
+
* The check is the point. `rm -rf` runs with `shouldIgnoreExitCode`, so an
|
|
309
|
+
* unremoved directory used to leave no trace at all — which is how runs that
|
|
310
|
+
* passed end to end were still found to be leaking a vault apiece, invisibly,
|
|
311
|
+
* until someone counted the directories on the device by hand. A leak is now
|
|
312
|
+
* named in the log at the moment it happens.
|
|
313
|
+
*
|
|
307
314
|
* @param deviceVaultPath - The device-side vault directory path.
|
|
308
315
|
*/
|
|
309
316
|
private removeDeviceVaultDir;
|