obsidian-integration-testing 16.0.0 → 17.0.1

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.
Files changed (77) hide show
  1. package/dist/lib/cjs/adb.cjs +2 -2
  2. package/dist/lib/cjs/adb.d.cts +10 -0
  3. package/dist/lib/cjs/avd-name-channel.cjs +74 -0
  4. package/dist/lib/cjs/avd-name-channel.d.cts +152 -0
  5. package/dist/lib/cjs/avd-probe-verdict.cjs +11 -4
  6. package/dist/lib/cjs/avd-probe-verdict.d.cts +7 -0
  7. package/dist/lib/cjs/device-screenshot.cjs +1 -1
  8. package/dist/lib/cjs/device-screenshot.d.cts +3 -1
  9. package/dist/lib/cjs/emulator-backend.cjs +22 -1
  10. package/dist/lib/cjs/emulator-backend.d.cts +81 -0
  11. package/dist/lib/cjs/emulator-reclaim.cjs +78 -34
  12. package/dist/lib/cjs/emulator-reclaim.d.cts +57 -9
  13. package/dist/lib/cjs/enable-plugin.cjs +17 -8
  14. package/dist/lib/cjs/enable-plugin.d.cts +3 -1
  15. package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
  16. package/dist/lib/cjs/eval-in-obsidian.d.cts +12 -0
  17. package/dist/lib/cjs/host-process-query-verdict.cjs +103 -0
  18. package/dist/lib/cjs/host-process-query-verdict.d.cts +196 -0
  19. package/dist/lib/cjs/index.cjs +14 -1
  20. package/dist/lib/cjs/index.d.cts +3 -1
  21. package/dist/lib/cjs/launched-device-selection.cjs +46 -0
  22. package/dist/lib/cjs/launched-device-selection.d.cts +112 -0
  23. package/dist/lib/cjs/library.cjs +1 -1
  24. package/dist/lib/cjs/namespace-bootstrap.cjs +62 -1
  25. package/dist/lib/cjs/paint-out-status-bar.cjs +170 -0
  26. package/dist/lib/cjs/paint-out-status-bar.d.cts +236 -0
  27. package/dist/lib/cjs/port-owner-query-verdict.cjs +94 -0
  28. package/dist/lib/cjs/port-owner-query-verdict.d.cts +161 -0
  29. package/dist/lib/cjs/resolve-emulator-device-id.cjs +27 -4
  30. package/dist/lib/cjs/sharp-loader.cjs +1 -1
  31. package/dist/lib/cjs/sharp-loader.d.cts +67 -2
  32. package/dist/lib/cjs/soft-keyboard-geometry.cjs +12 -2
  33. package/dist/lib/cjs/soft-keyboard-geometry.d.cts +17 -2
  34. package/dist/lib/cjs/soft-keyboard.cjs +130 -28
  35. package/dist/lib/cjs/soft-keyboard.d.cts +65 -6
  36. package/dist/lib/cjs/transport-appium.cjs +74 -4
  37. package/dist/lib/cjs/transport-appium.d.cts +49 -2
  38. package/dist/lib/cjs/transport-factory.cjs +162 -42
  39. package/dist/lib/esm/adb.d.mts +10 -0
  40. package/dist/lib/esm/adb.mjs +2 -2
  41. package/dist/lib/esm/avd-name-channel.d.mts +152 -0
  42. package/dist/lib/esm/avd-name-channel.mjs +45 -0
  43. package/dist/lib/esm/avd-probe-verdict.d.mts +7 -0
  44. package/dist/lib/esm/avd-probe-verdict.mjs +15 -4
  45. package/dist/lib/esm/device-screenshot.d.mts +3 -1
  46. package/dist/lib/esm/device-screenshot.mjs +1 -1
  47. package/dist/lib/esm/emulator-backend.d.mts +81 -0
  48. package/dist/lib/esm/emulator-backend.mjs +19 -1
  49. package/dist/lib/esm/emulator-reclaim.d.mts +57 -9
  50. package/dist/lib/esm/emulator-reclaim.mjs +84 -36
  51. package/dist/lib/esm/enable-plugin.d.mts +3 -1
  52. package/dist/lib/esm/enable-plugin.mjs +17 -8
  53. package/dist/lib/esm/eval-in-obsidian.d.mts +12 -0
  54. package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
  55. package/dist/lib/esm/host-process-query-verdict.d.mts +196 -0
  56. package/dist/lib/esm/host-process-query-verdict.mjs +74 -0
  57. package/dist/lib/esm/index.d.mts +3 -1
  58. package/dist/lib/esm/index.mjs +15 -1
  59. package/dist/lib/esm/launched-device-selection.d.mts +112 -0
  60. package/dist/lib/esm/launched-device-selection.mjs +21 -0
  61. package/dist/lib/esm/library.mjs +1 -1
  62. package/dist/lib/esm/namespace-bootstrap.mjs +62 -1
  63. package/dist/lib/esm/paint-out-status-bar.d.mts +236 -0
  64. package/dist/lib/esm/paint-out-status-bar.mjs +142 -0
  65. package/dist/lib/esm/port-owner-query-verdict.d.mts +161 -0
  66. package/dist/lib/esm/port-owner-query-verdict.mjs +73 -0
  67. package/dist/lib/esm/resolve-emulator-device-id.mjs +32 -4
  68. package/dist/lib/esm/sharp-loader.d.mts +67 -2
  69. package/dist/lib/esm/sharp-loader.mjs +1 -1
  70. package/dist/lib/esm/soft-keyboard-geometry.d.mts +17 -2
  71. package/dist/lib/esm/soft-keyboard-geometry.mjs +11 -2
  72. package/dist/lib/esm/soft-keyboard.d.mts +65 -6
  73. package/dist/lib/esm/soft-keyboard.mjs +131 -28
  74. package/dist/lib/esm/transport-appium.d.mts +49 -2
  75. package/dist/lib/esm/transport-appium.mjs +74 -4
  76. package/dist/lib/esm/transport-factory.mjs +176 -44
  77. package/package.json +1 -1
@@ -45,6 +45,7 @@ var import_appium_dependencies = require("./appium-dependencies.cjs");
45
45
  var import_appium_server_marker = require("./appium-server-marker.cjs");
46
46
  var import_appium_session_config = require("./appium-session-config.cjs");
47
47
  var import_avd_list = require("./avd-list.cjs");
48
+ var import_avd_name_channel = require("./avd-name-channel.cjs");
48
49
  var import_avd_probe_verdict = require("./avd-probe-verdict.cjs");
49
50
  var import_compatibility_options = require("./compatibility-options.cjs");
50
51
  var import_config_directory = require("./config-directory.cjs");
@@ -62,6 +63,7 @@ var import_incompatible_installer_version_error = require("./incompatible-instal
62
63
  var import_installer_compatibility = require("./installer-compatibility.cjs");
63
64
  var import_integration_setup_failed_error = require("./integration-setup-failed-error.cjs");
64
65
  var import_kill_process_tree = require("./kill-process-tree.cjs");
66
+ var import_launched_device_selection = require("./launched-device-selection.cjs");
65
67
  var import_leftover_cleanup = require("./leftover-cleanup.cjs");
66
68
  var import_log = require("./log.cjs");
67
69
  var import_normalize_optional_properties = require("./normalize-optional-properties.cjs");
@@ -73,6 +75,7 @@ var import_obsidian_version_switch = require("./obsidian-version-switch.cjs");
73
75
  var import_obsidian_version = require("./obsidian-version.cjs");
74
76
  var import_owned_instance_exit_marker = require("./owned-instance-exit-marker.cjs");
75
77
  var import_owned_instance_exited_error = require("./owned-instance-exited-error.cjs");
78
+ var import_port_owner_query_verdict = require("./port-owner-query-verdict.cjs");
76
79
  var import_port_owner = require("./port-owner.cjs");
77
80
  var import_process_exit_message = require("./process-exit-message.cjs");
78
81
  var import_process_liveness = require("./process-liveness.cjs");
@@ -115,6 +118,7 @@ const MILLISECONDS_PER_SECOND = 1e3;
115
118
  const NETWORK_READY_POLL_INTERVAL_IN_MILLISECONDS = 2e3;
116
119
  const NEW_COMMAND_TIMEOUT_IN_SECONDS = 300;
117
120
  const PAGE_LOAD_TIMEOUT_IN_MILLISECONDS = 3e5;
121
+ const PORT_OWNER_QUERY_TIMEOUT_IN_MILLISECONDS = 3e4;
118
122
  const SERVER_INSTALL_TIMEOUT_IN_MILLISECONDS = 12e4;
119
123
  const SERVER_LAUNCH_TIMEOUT_IN_MILLISECONDS = 12e4;
120
124
  const SYNC_TEARDOWN_QUERY_TIMEOUT_IN_MILLISECONDS = 5e3;
@@ -157,6 +161,30 @@ class AppiumTransportFactory {
157
161
  startedAtInMilliseconds
158
162
  });
159
163
  }
164
+ /**
165
+ * Asks one device for its AVD name over one channel.
166
+ *
167
+ * Reports *whether the command came back* alongside what it printed, because
168
+ * the sequencing in `avd-name-channel.ts` turns on that difference: a channel
169
+ * that answered an empty property is alive and worth asking again with the
170
+ * other key, while one that never came back is not.
171
+ *
172
+ * @param deviceId - The device to ask.
173
+ * @param channel - The channel to ask it over.
174
+ * @returns What that channel answered.
175
+ */
176
+ askDeviceForAvdName(deviceId, channel) {
177
+ return new Promise((resolve) => {
178
+ (0, import_node_child_process.execFile)(
179
+ "adb",
180
+ (0, import_avd_name_channel.buildAvdNameChannelArguments)({ channel, deviceId }),
181
+ { timeout: import_emulator_reclaim.ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS },
182
+ (error, stdout) => {
183
+ resolve(error ? { didRespond: false, reportedAvdName: "" } : { didRespond: true, reportedAvdName: (0, import_avd_name_channel.parseAvdNameAnswer)(stdout) });
184
+ }
185
+ );
186
+ });
187
+ }
160
188
  async attachToExistingSession(sessionId, deviceId, options) {
161
189
  const url = new URL(options.appiumUrl);
162
190
  const port = Number(url.port);
@@ -661,7 +689,7 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
661
689
  const isRecordedFromLaunch = this.recordEmulatorLaunch({ avdName, emulator, launchedAtInMilliseconds, preLaunchEmulatorPids: emulatorPidsBefore });
662
690
  let actualDeviceId;
663
691
  try {
664
- actualDeviceId = await this.waitForNewDevice(deviceIdsBefore, emulator, timeouts, (deviceId) => {
692
+ actualDeviceId = await this.waitForNewDevice(avdName, deviceIdsBefore, emulator, timeouts, (deviceId) => {
665
693
  this.recordEmulatorLaunchDevice({ avdName, deviceId, launchedAtInMilliseconds });
666
694
  });
667
695
  } catch (error) {
@@ -805,12 +833,18 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
805
833
  * failing the run it is cleaning up for. **It says so, loudly** — an empty set
806
834
  * that means "no backend to own" and one that means "the query failed" are
807
835
  * otherwise the same log line, and the second silently disarms the escalation.
808
- * That is not hypothetical: the first end-to-end run of this code logged
836
+ *
837
+ * That is not hypothetical, and it has now happened twice for the same reason:
838
+ * the budget was a guess. The first end-to-end run of this code logged
809
839
  * `owned emulator PIDs: []` for a launch whose backend was demonstrably there,
810
- * because `tasklist` overran a 10s budget on a host the wedged emulator had
840
+ * because `tasklist` overran a **10s** budget on a host the wedged emulator had
811
841
  * already slowed to the point where every `adb` call was timing out too — the
812
- * same contention **L45** sizes `ADB_DUMPSYS_TIMEOUT_IN_MILLISECONDS` for, and
813
- * the same "wrong budget silently disables the check" shape.
842
+ * same contention **L45** sizes `ADB_DUMPSYS_TIMEOUT_IN_MILLISECONDS` for. Its
843
+ * replacement, 30s, then did the same thing on **every** Android run from one
844
+ * host. `HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS` carries the measurement
845
+ * that replaced the guessing, and `host-process-query-verdict.ts` carries the
846
+ * reporting that makes the next overrun say which failure it was instead of
847
+ * printing a bare `Command failed:` with nothing after it.
814
848
  *
815
849
  * A host always has processes, so a listing that parses to **zero** rows is a
816
850
  * failed query however it exited, and is reported like one.
@@ -819,7 +853,7 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
819
853
  * @returns The emulator PIDs not in `knownPids`.
820
854
  */
821
855
  async listEmulatorBackendPids(knownPids) {
822
- const processes = await this.emulators.queryHostProcesses();
856
+ const processes = await this.emulators.queryEmulatorProcesses();
823
857
  if (processes === void 0) {
824
858
  this.log(
825
859
  "Warning: the host process listing failed, so this run cannot identify the emulator backend it owns. Teardown will fall back to `adb devices` alone and will have no PID to escalate to."
@@ -848,21 +882,46 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
848
882
  * nothing, while a socket still answering on the port is direct evidence of
849
883
  * what survived.
850
884
  *
885
+ * A query that failed still yields an empty list — the escalation is
886
+ * best-effort — but it is never silent: `lsof`'s own "nothing holds the port"
887
+ * is an answer, while a timeout or a crash is logged by name, because an
888
+ * empty list from either disarms the escalation without saying so.
889
+ *
851
890
  * @param port - The port to query.
852
- * @returns The listening PIDs, or an empty list when the query could not be run.
891
+ * @returns The listening PIDs, or an empty list when nothing holds the port or the query failed.
853
892
  */
854
- listPortOwnerPids(port) {
893
+ async listPortOwnerPids(port) {
855
894
  const query = buildPortOwnerQuery(port);
856
- return new Promise((resolve) => {
895
+ const startedAtInMilliseconds = Date.now();
896
+ const result = await new Promise((resolve) => {
857
897
  (0, import_node_child_process.execFile)(
858
898
  query.command,
859
899
  query.commandArguments,
860
- { maxBuffer: import_emulator_reclaim.ADB_DUMPSYS_MAX_BUFFER_IN_BYTES, timeout: import_emulator_reclaim.HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS },
861
- (error, stdout) => {
862
- resolve(parsePortOwnerPids({ output: error ? "" : stdout, port }));
900
+ { maxBuffer: import_emulator_reclaim.ADB_DUMPSYS_MAX_BUFFER_IN_BYTES, timeout: PORT_OWNER_QUERY_TIMEOUT_IN_MILLISECONDS },
901
+ (error, stdout, stderr) => {
902
+ resolve({ error, standardError: stderr, standardOutput: stdout });
863
903
  }
864
904
  );
865
905
  });
906
+ const outcome = (0, import_port_owner_query_verdict.resolvePortOwnerQueryOutcome)({
907
+ errorCode: result.error?.code ?? null,
908
+ hasFailed: result.error !== null,
909
+ isKilled: result.error?.killed ?? false,
910
+ platform: import_node_process.default.platform,
911
+ standardError: result.standardError,
912
+ standardOutput: result.standardOutput
913
+ });
914
+ this.logPortOwnerQueryFailure({
915
+ command: [query.command, ...query.commandArguments].join(" "),
916
+ elapsedInMilliseconds: Date.now() - startedAtInMilliseconds,
917
+ exitCode: typeof result.error?.code === "number" ? result.error.code : null,
918
+ outcome,
919
+ port,
920
+ signal: result.error?.signal ?? null,
921
+ standardError: result.standardError,
922
+ timeoutInMilliseconds: PORT_OWNER_QUERY_TIMEOUT_IN_MILLISECONDS
923
+ });
924
+ return result.error === null ? parsePortOwnerPids({ output: result.standardOutput, port }) : [];
866
925
  }
867
926
  /**
868
927
  * Synchronous {@link listPortOwnerPids}, for the `process.on('exit')` teardown
@@ -873,11 +932,14 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
873
932
  * exit handler for half a minute on a contended host. Giving up loses the
874
933
  * escalation, which the sync path's log already admits it cannot confirm.
875
934
  *
935
+ * A failure is classified and logged the same way as the async path's.
936
+ *
876
937
  * @param port - The port to query.
877
- * @returns The listening PIDs, or an empty list when the query could not be run in time.
938
+ * @returns The listening PIDs, or an empty list when nothing holds the port or the query failed.
878
939
  */
879
940
  listPortOwnerPidsSync(port) {
880
941
  const query = buildPortOwnerQuery(port);
942
+ const startedAtInMilliseconds = Date.now();
881
943
  try {
882
944
  const output = (0, import_node_child_process.execFileSync)(query.command, query.commandArguments, {
883
945
  encoding: "utf-8",
@@ -885,13 +947,35 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
885
947
  timeout: SYNC_TEARDOWN_QUERY_TIMEOUT_IN_MILLISECONDS
886
948
  });
887
949
  return parsePortOwnerPids({ output, port });
888
- } catch {
950
+ } catch (error) {
951
+ const failure = (0, import_port_owner_query_verdict.normalizeSyncExecError)(error);
952
+ this.logPortOwnerQueryFailure({
953
+ command: [query.command, ...query.commandArguments].join(" "),
954
+ elapsedInMilliseconds: Date.now() - startedAtInMilliseconds,
955
+ exitCode: failure.exitCode,
956
+ outcome: (0, import_port_owner_query_verdict.resolvePortOwnerQueryOutcome)({ ...failure, hasFailed: true, platform: import_node_process.default.platform }),
957
+ port,
958
+ signal: failure.signal,
959
+ standardError: failure.standardError,
960
+ timeoutInMilliseconds: SYNC_TEARDOWN_QUERY_TIMEOUT_IN_MILLISECONDS
961
+ });
889
962
  return [];
890
963
  }
891
964
  }
892
965
  log(message) {
893
966
  (0, import_log.log)(`[transport-factory:${this.type}] ${message}`);
894
967
  }
968
+ /**
969
+ * Logs the port-owner query's failure, if it failed.
970
+ *
971
+ * @param params - The outcome and what the child left behind.
972
+ */
973
+ logPortOwnerQueryFailure(params) {
974
+ const message = (0, import_port_owner_query_verdict.buildPortOwnerQueryMessage)(params);
975
+ if (message !== void 0) {
976
+ this.log(message);
977
+ }
978
+ }
895
979
  /**
896
980
  * Logs how old the snapshot a run has opted into resuming is.
897
981
  *
@@ -912,35 +996,42 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
912
996
  this.log((0, import_emulator_snapshot.buildSnapshotAgeMessage)({ avdName, savedAt }));
913
997
  }
914
998
  /**
915
- * Reads one emulator's AVD name from its console, retrying once.
999
+ * Reads one emulator's AVD name, over the guest property first and its
1000
+ * console only as a fallback, retrying the whole sequence once.
1001
+ *
1002
+ * The retry is what makes the refusal proportionate: each attempt's budget is
1003
+ * 5s, and a second look costs less than a colliding launch does. What it must
1004
+ * never do is report a non-answer as an answer — the discarded `_error` this
1005
+ * replaces resolved `''`, which compared unequal to the wanted AVD and so read
1006
+ * as a definite "some other AVD".
916
1007
  *
917
- * The retry is what makes the refusal proportionate: the probe's whole budget
918
- * is 5s, and a second look costs less than a colliding launch does. What it
919
- * must never do is report a non-answer as an answer — the discarded `_error`
920
- * this replaces resolved `''`, which compared unequal to the wanted AVD and so
921
- * read as a definite "some other AVD".
1008
+ * **Which channel it asks is the other half.** The console is a separate TCP
1009
+ * port that wedges on its own, so keying the refusal on it made one
1010
+ * unresponsive emulator — routinely another project's — block every Android
1011
+ * run on the machine. The property travels `adbd`, the channel this run needs
1012
+ * anyway; see `avd-name-channel.ts`.
922
1013
  *
923
1014
  * @param deviceId - The emulator to ask.
924
- * @returns The AVD name it answered, or `undefined` when it did not answer.
1015
+ * @returns The AVD name it answered, or `undefined` when no channel answered.
925
1016
  */
926
1017
  async probeAvdName(deviceId) {
1018
+ const propertyCommand = (0, import_avd_name_channel.describeAdbCommand)((0, import_avd_name_channel.buildAvdNameChannelArguments)({ channel: import_avd_name_channel.FIRST_AVD_NAME_CHANNEL, deviceId }));
1019
+ const consoleCommand = (0, import_avd_name_channel.describeAdbCommand)((0, import_avd_name_channel.buildAvdNameChannelArguments)({ channel: "console", deviceId }));
927
1020
  for (let attempt = 1; attempt <= AVD_PROBE_ATTEMPT_COUNT; attempt++) {
928
- const answer = await new Promise((resolve) => {
929
- (0, import_node_child_process.execFile)(
930
- "adb",
931
- ["-s", deviceId, "emu", "avd", "name"],
932
- { timeout: import_emulator_reclaim.ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS },
933
- (error, stdout) => {
934
- resolve(error ? void 0 : stdout.split("\n", 1)[0]?.trim());
1021
+ let channel = import_avd_name_channel.FIRST_AVD_NAME_CHANNEL;
1022
+ while (channel !== void 0) {
1023
+ const answer = await this.askDeviceForAvdName(deviceId, channel);
1024
+ if (answer.reportedAvdName.length > 0) {
1025
+ if (channel !== import_avd_name_channel.FIRST_AVD_NAME_CHANNEL) {
1026
+ this.log(`Device ${deviceId} answered \`${(0, import_avd_name_channel.describeAdbCommand)((0, import_avd_name_channel.buildAvdNameChannelArguments)({ channel, deviceId }))}\`.`);
935
1027
  }
936
- );
937
- });
938
- if (answer !== void 0 && answer.length > 0) {
939
- return answer;
1028
+ return answer.reportedAvdName;
1029
+ }
1030
+ channel = (0, import_avd_name_channel.resolveNextAvdNameChannel)({ channel, didChannelRespond: answer.didRespond });
940
1031
  }
941
1032
  if (attempt < AVD_PROBE_ATTEMPT_COUNT) {
942
1033
  this.log(
943
- `Device ${deviceId} did not answer \`adb -s ${deviceId} emu avd name\` within ${String(import_emulator_reclaim.ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS)}ms; retrying once.`
1034
+ `Device ${deviceId} identified itself over neither \`${propertyCommand}\` nor \`${consoleCommand}\` within ${String(import_emulator_reclaim.ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS)}ms each; retrying once.`
944
1035
  );
945
1036
  }
946
1037
  }
@@ -1074,7 +1165,7 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
1074
1165
  * Worth its own write because the console shutdown is the only stop that
1075
1166
  * releases the AVD's `multiinstance.lock` (**L46**), and it needs a device to
1076
1167
  * talk to. Deliberately **no** host process listing here: that query is
1077
- * budgeted at {@link HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS} for exactly
1168
+ * budgeted at `HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS` (120s) for exactly
1078
1169
  * this contended window, and spending it inside the boot path would eat the
1079
1170
  * readiness budgets that follow. The backend PIDs arrive with the success
1080
1171
  * write, one listing, as before.
@@ -1594,7 +1685,7 @@ Booting a fresh emulator and trying once more (attempt ${String(attempt + 1)} of
1594
1685
  if (!marker) {
1595
1686
  return [];
1596
1687
  }
1597
- const processes = await this.emulators.queryHostProcesses();
1688
+ const processes = await this.emulators.queryEmulatorProcesses();
1598
1689
  if (processes === void 0) {
1599
1690
  this.log(`Cannot tell whether AVD "${avdName}" is a leftover this harness started without a host process listing; reusing it without taking it over.`);
1600
1691
  return [];
@@ -1867,23 +1958,52 @@ ${outputTail}` : "";
1867
1958
  * Waits for the emulator this run launched to produce a device, and for that
1868
1959
  * device to become usable.
1869
1960
  *
1961
+ * Only an emulator serving `avdName` is taken: a handset, or another emulator,
1962
+ * that comes online during the boot is logged and ignored — see
1963
+ * `launched-device-selection.ts`.
1964
+ *
1965
+ * @param avdName - The AVD this run launched.
1870
1966
  * @param deviceIdsBefore - The devices connected before the launch.
1871
1967
  * @param emulator - The launcher, polled for an early exit.
1872
1968
  * @param timeouts - The two post-boot readiness budgets.
1873
1969
  * @param onDeviceAppeared - Called with the new device the moment it is listed, before the readiness gates.
1874
1970
  * @returns The new device's id.
1875
1971
  */
1876
- async waitForNewDevice(deviceIdsBefore, emulator, timeouts, onDeviceAppeared) {
1972
+ async waitForNewDevice(avdName, deviceIdsBefore, emulator, timeouts, onDeviceAppeared) {
1877
1973
  this.log(
1878
1974
  `Waiting for a new device to appear in ADB (timeout: ${String(EMULATOR_BOOT_TIMEOUT_IN_MILLISECONDS)}ms, poll: ${String(EMULATOR_BOOT_POLL_INTERVAL_IN_MILLISECONDS)}ms)...`
1879
1975
  );
1880
1976
  const deadline = Date.now() + EMULATOR_BOOT_TIMEOUT_IN_MILLISECONDS;
1977
+ const ignoredDeviceIds = /* @__PURE__ */ new Set();
1881
1978
  while (Date.now() < deadline) {
1882
- const currentIds = await this.getConnectedDeviceIds();
1883
- const newIds = currentIds.filter((id) => !deviceIdsBefore.includes(id));
1884
- if (newIds.length > 0) {
1885
- const actualDeviceId = newIds[0] ?? "";
1886
- this.log(`Device ${actualDeviceId} appeared in ADB, waiting for boot to complete...`);
1979
+ const { emulatorDeviceIds, nonEmulatorDeviceIds } = (0, import_launched_device_selection.splitNewDevices)({
1980
+ connectedDeviceIds: await this.getConnectedDeviceIds(),
1981
+ deviceIdsBefore
1982
+ });
1983
+ for (const deviceId of nonEmulatorDeviceIds) {
1984
+ if (ignoredDeviceIds.has(deviceId)) {
1985
+ continue;
1986
+ }
1987
+ ignoredDeviceIds.add(deviceId);
1988
+ this.log(`Device ${deviceId} came online during the emulator boot but is not an emulator; ignoring it.`);
1989
+ }
1990
+ const candidates = [];
1991
+ for (const deviceId of emulatorDeviceIds) {
1992
+ if (!ignoredDeviceIds.has(deviceId)) {
1993
+ candidates.push({ deviceId, probedAvdName: await this.probeAvdName(deviceId) });
1994
+ }
1995
+ }
1996
+ const launched = (0, import_launched_device_selection.resolveLaunchedDevice)({ avdName, candidates });
1997
+ for (const deviceId of launched.otherAvdDeviceIds) {
1998
+ ignoredDeviceIds.add(deviceId);
1999
+ this.log(`Device ${deviceId} came online during the emulator boot but serves another AVD, not "${avdName}"; ignoring it.`);
2000
+ }
2001
+ if (launched.unansweredDeviceIds.length > 0) {
2002
+ this.log(`Device(s) ${launched.unansweredDeviceIds.join(", ")} did not say which AVD they serve yet; asking again on the next poll.`);
2003
+ }
2004
+ if (launched.deviceId !== void 0) {
2005
+ const actualDeviceId = launched.deviceId;
2006
+ this.log(`Device ${actualDeviceId} appeared in ADB, serving AVD "${avdName}"; waiting for boot to complete...`);
1887
2007
  onDeviceAppeared(actualDeviceId);
1888
2008
  await this.waitForBoot(actualDeviceId, deadline, emulator);
1889
2009
  await this.waitForDeviceReady(actualDeviceId, timeouts);
@@ -2107,4 +2227,4 @@ function stripForbiddenFetchHeaders(requestOptions) {
2107
2227
  getOrCreateTransport,
2108
2228
  stopHarnessStartedEmulators
2109
2229
  });
2110
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1mYWN0b3J5LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRmFjdG9yeSBmb3IgY3JlYXRpbmcgdHJhbnNwb3J0IGluc3RhbmNlcyBmcm9tIHtAbGluayBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnN9LlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGZhY3RvcnkgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgQ2hpbGRQcm9jZXNzIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB0eXBlIHtcbiAgYXR0YWNoLFxuICByZW1vdGVcbn0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQge1xuICBleGVjRmlsZSxcbiAgZXhlY0ZpbGVTeW5jLFxuICBzcGF3blxufSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBta2R0ZW1wU3luYyxcbiAgc3RhdFN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgaHR0cCBmcm9tICdub2RlOmh0dHAnO1xuaW1wb3J0IHtcbiAgaG9tZWRpcixcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgdHlwZSB7IEFwcGl1bVNlcnZlck1hcmtlciB9IGZyb20gJy4vYXBwaXVtLXNlcnZlci1tYXJrZXIuY2pzJztcbmltcG9ydCB0eXBlIHsgQXZkUHJvYmVSZXN1bHQgfSBmcm9tICcuL2F2ZC1wcm9iZS12ZXJkaWN0LmNqcyc7XG5pbXBvcnQgdHlwZSB7IEVtdWxhdG9yTGl2ZW5lc3NQcm9iZU91dGNvbWUgfSBmcm9tICcuL2VtdWxhdG9yLWxpdmVuZXNzLmNqcyc7XG5pbXBvcnQgdHlwZSB7IEhvc3RDb21tYW5kUXVlcnkgfSBmcm9tICcuL2VtdWxhdG9yLXJlY2xhaW0uY2pzJztcbmltcG9ydCB0eXBlIHsgSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB9IGZyb20gJy4vaW5zdGFsbGVyLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB0eXBlIHsgUHJvY2Vzc0V4aXRJbmZvIH0gZnJvbSAnLi9wcm9jZXNzLWV4aXQtbWVzc2FnZS5janMnO1xuaW1wb3J0IHR5cGUge1xuICBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnLFxuICBPd25lZEluc3RhbmNlQ29uZmlnXG59IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLmNqcyc7XG5pbXBvcnQgdHlwZSB7XG4gIE9ic2lkaWFuQW5kcm9pZEFwcGl1bVRyYW5zcG9ydE9wdGlvbnMsXG4gIE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyxcbiAgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMuY2pzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuaW1wb3J0IHR5cGUgeyBXZWRnZWRBcHBpdW1TZXJ2ZXJSZXBvcnRSZWFzb24gfSBmcm9tICcuL3dlZGdlZC1hcHBpdW0tc2VydmVyLmNqcyc7XG5cbmltcG9ydCB7XG4gIGNoZWNrSXNEZXZpY2VMaXN0ZWQsXG4gIGxpc3RPbmxpbmVEZXZpY2VJZHMsXG4gIHBhcnNlQWRiRGV2aWNlc1xufSBmcm9tICcuL2FkYi1kZXZpY2UtbGlzdC5janMnO1xuaW1wb3J0IHsgcmVzb2x2ZUVtdWxhdG9yQmluYXJ5UGF0aCB9IGZyb20gJy4vYW5kcm9pZC1zZGsuY2pzJztcbmltcG9ydCB7XG4gIGNoZWNrSXNBcHBpdW1Ecml2ZXJJbnN0YWxsZWQsXG4gIFVJQVVUT01BVE9SMl9EUklWRVJfTkFNRSxcbiAgd2lsbEF1dG9JbnN0YWxsQXBwaXVtRGVwZW5kZW5jaWVzXG59IGZyb20gJy4vYXBwaXVtLWRlcGVuZGVuY2llcy5janMnO1xuaW1wb3J0IHtcbiAgY2hlY2tJc0hhcm5lc3NPd25lZEFwcGl1bVNlcnZlcixcbiAgY2xlYXJBcHBpdW1TZXJ2ZXJNYXJrZXIsXG4gIHJlYWRBcHBpdW1TZXJ2ZXJNYXJrZXIsXG4gIHJlY29yZEFwcGl1bVNlcnZlclN0b3BBdHRlbXB0LFxuICB3cml0ZUFwcGl1bVNlcnZlck1hcmtlclxufSBmcm9tICcuL2FwcGl1bS1zZXJ2ZXItbWFya2VyLmNqcyc7XG5pbXBvcnQge1xuICByZXNvbHZlQXBwaXVtU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMsXG4gIHJlc29sdmVTY3JpcHRUaW1lb3V0SW5NaWxsaXNlY29uZHMsXG4gIHJlc29sdmVTZXNzaW9uQ29ubmVjdGlvblJldHJ5VGltZW91dEluTWlsbGlzZWNvbmRzXG59IGZyb20gJy4vYXBwaXVtLXNlc3Npb24tY29uZmlnLmNqcyc7XG5pbXBvcnQge1xuICBjaGVja0F2ZEV4aXN0cyxcbiAgbGlzdEF2YWlsYWJsZUF2ZHNcbn0gZnJvbSAnLi9hdmQtbGlzdC5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRBdmRQcm9iZVN1bW1hcnksXG4gIGJ1aWxkVW5yZWFkYWJsZURldmljZXNNZXNzYWdlLFxuICBjaGVja0lzRW11bGF0b3JEZXZpY2VJZCxcbiAgY2xhc3NpZnlBdmRQcm9iZSxcbiAgcmVzb2x2ZUF2ZFByb2JlVmVyZGljdFxufSBmcm9tICcuL2F2ZC1wcm9iZS12ZXJkaWN0LmNqcyc7XG5pbXBvcnQge1xuICByZXNvbHZlSW5zdGFsbGVyQ29tcGF0aWJpbGl0eUFjdGlvbixcbiAgd2lsbFRocm93T25JbmNvbXBhdGlibGVJbnN0YWxsZXIsXG4gIHdpbGxUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrLFxuICB3aWxsV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3Vlc1xufSBmcm9tICcuL2NvbXBhdGliaWxpdHktb3B0aW9ucy5janMnO1xuaW1wb3J0IHsgYXNzZXJ0VmFsaWRDb25maWdEaXJlY3RvcnkgfSBmcm9tICcuL2NvbmZpZy1kaXJlY3RvcnkuY2pzJztcbmltcG9ydCB7IGdldFNldHVwRXJyb3IgfSBmcm9tICcuL2NvbnRleHQtcHJvdmlkZXIuY2pzJztcbmltcG9ydCB7XG4gIGNoZWNrRGV2aWNlSWRsZSxcbiAgY2hlY2tOZXR3b3JrVmFsaWRhdGVkLFxuICByZXNvbHZlRGV2aWNlSWRsZVRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgcmVzb2x2ZU5ldHdvcmtSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kc1xufSBmcm9tICcuL2RldmljZS1yZWFkaW5lc3MuY2pzJztcbmltcG9ydCB7XG4gIGJ1aWxkRW11bGF0b3JBcmd1bWVudHMsXG4gIGJ1aWxkRW11bGF0b3JFbnZpcm9ubWVudCxcbiAgTkVUU0lNX0xPR19GSUxURVJcbn0gZnJvbSAnLi9lbXVsYXRvci1hcmd1bWVudHMuY2pzJztcbmltcG9ydCB7IHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHMgfSBmcm9tICcuL2VtdWxhdG9yLWJhY2tlbmQuY2pzJztcbmltcG9ydCB7XG4gIGJ1aWxkRW11bGF0b3JMaXZlbmVzc01lc3NhZ2UsXG4gIHJlc29sdmVFbXVsYXRvckxpdmVuZXNzVmVyZGljdFxufSBmcm9tICcuL2VtdWxhdG9yLWxpdmVuZXNzLmNqcyc7XG5pbXBvcnQge1xuICBjaGVja0lzTWFya2VkRW11bGF0b3JSdW5uaW5nLFxuICBjbGVhckVtdWxhdG9yTWFya2VyLFxuICBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkLFxuICByZWFkRW11bGF0b3JNYXJrZXIsXG4gIHJlc29sdmVFbXVsYXRvck1hcmtlclZlcmRpY3QsXG4gIHNlbGVjdExpdmVNYXJrZWRQaWRzLFxuICB3cml0ZUVtdWxhdG9yTWFya2VyXG59IGZyb20gJy4vZW11bGF0b3ItbWFya2VyLmNqcyc7XG5pbXBvcnQgeyBzcGF3bkVtdWxhdG9yUmVhcGVyIH0gZnJvbSAnLi9lbXVsYXRvci1yZWFwZXIuY2pzJztcbmltcG9ydCB7XG4gIEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMsXG4gIEFEQl9EVU1QU1lTX01BWF9CVUZGRVJfSU5fQllURVMsXG4gIEVtdWxhdG9yUmVjbGFpbWVyLFxuICBIT1NUX1BST0NFU1NfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbn0gZnJvbSAnLi9lbXVsYXRvci1yZWNsYWltLmNqcyc7XG5pbXBvcnQge1xuICBidWlsZEF2ZFNuYXBzaG90RGlyZWN0b3J5Q2FuZGlkYXRlcyxcbiAgYnVpbGRTbmFwc2hvdEFnZU1lc3NhZ2Vcbn0gZnJvbSAnLi9lbXVsYXRvci1zbmFwc2hvdC5janMnO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJy4vZXhlYy5janMnO1xuaW1wb3J0IHsgSW5jb21wYXRpYmxlSW5zdGFsbGVyVmVyc2lvbkVycm9yIH0gZnJvbSAnLi9pbmNvbXBhdGlibGUtaW5zdGFsbGVyLXZlcnNpb24tZXJyb3IuY2pzJztcbmltcG9ydCB7IHJlc29sdmVJbnN0YWxsZXJDb21wYXRpYmlsaXR5IH0gZnJvbSAnLi9pbnN0YWxsZXItY29tcGF0aWJpbGl0eS5janMnO1xuaW1wb3J0IHsgSW50ZWdyYXRpb25TZXR1cEZhaWxlZEVycm9yIH0gZnJvbSAnLi9pbnRlZ3JhdGlvbi1zZXR1cC1mYWlsZWQtZXJyb3IuY2pzJztcbmltcG9ydCB7XG4gIGtpbGxQcm9jZXNzVHJlZSxcbiAga2lsbFByb2Nlc3NUcmVlQnlQaWRcbn0gZnJvbSAnLi9raWxsLXByb2Nlc3MtdHJlZS5janMnO1xuaW1wb3J0IHtcbiAgSEFSTkVTU19URU1QX0RJUl9OQU1FLFxuICBPV05FRF9VU0VSX0RBVEFfRElSX1BSRUZJWCxcbiAgc3dlZXBEZXZpY2VMZWZ0b3ZlcnMsXG4gIHdpbGxTd2VlcExlZnRvdmVyc1xufSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQgeyBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXMgfSBmcm9tICcuL25vcm1hbGl6ZS1vcHRpb25hbC1wcm9wZXJ0aWVzLmNqcyc7XG5pbXBvcnQgeyBnZXRPYnNpZGlhbkNvbmZpZ0RpcmVjdG9yeSB9IGZyb20gJy4vb2JzaWRpYW4tY29uZmlnLmNqcyc7XG5pbXBvcnQgeyByZXNvbHZlT2JzaWRpYW5FeGVjdXRhYmxlIH0gZnJvbSAnLi9vYnNpZGlhbi1leGVjdXRhYmxlLmNqcyc7XG5pbXBvcnQge1xuICBkZXRlY3RJbnN0YWxsZWRTaGVsbFZlcnNpb24sXG4gIGVuc3VyZVNoZWxsQ2FjaGVkXG59IGZyb20gJy4vb2JzaWRpYW4taW5zdGFsbGVyLmNqcyc7XG5pbXBvcnQgeyBnZXRWZXJzaW9uTWV0YWRhdGEgfSBmcm9tICcuL29ic2lkaWFuLW1ldGFkYXRhLmNqcyc7XG5pbXBvcnQge1xuICBlbnN1cmVBc2FyQ2FjaGVkLFxuICBmaW5kTmV3ZXN0QXNhcixcbiAgcmVzb2x2ZUNvbmNyZXRlVmVyc2lvblxufSBmcm9tICcuL29ic2lkaWFuLXZlcnNpb24tc3dpdGNoLmNqcyc7XG5pbXBvcnQgeyBjb21wYXJlVmVyc2lvbnMgfSBmcm9tICcuL29ic2lkaWFuLXZlcnNpb24uY2pzJztcbmltcG9ydCB7IHJlYWRPd25lZEluc3RhbmNlRXhpdE1hcmtlciB9IGZyb20gJy4vb3duZWQtaW5zdGFuY2UtZXhpdC1tYXJrZXIuY2pzJztcbmltcG9ydCB7IGJ1aWxkT3duZWRJbnN0YW5jZUV4aXRlZEVycm9yRnJvbU1hcmtlciB9IGZyb20gJy4vb3duZWQtaW5zdGFuY2UtZXhpdGVkLWVycm9yLmNqcyc7XG5pbXBvcnQge1xuICBwYXJzZVBvc2l4THNvZlBpZHMsXG4gIHBhcnNlV2luZG93c05ldHN0YXRQaWRzXG59IGZyb20gJy4vcG9ydC1vd25lci5janMnO1xuaW1wb3J0IHtcbiAgYXBwZW5kUHJvY2Vzc091dHB1dFRhaWwsXG4gIGJ1aWxkUHJvY2Vzc0V4aXRNZXNzYWdlXG59IGZyb20gJy4vcHJvY2Vzcy1leGl0LW1lc3NhZ2UuY2pzJztcbmltcG9ydCB7IGNoZWNrSXNQcm9jZXNzQWxpdmUgfSBmcm9tICcuL3Byb2Nlc3MtbGl2ZW5lc3MuY2pzJztcbmltcG9ydCB7IHJlc29sdmVEZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMgfSBmcm9tICcuL3JlbmRlcmVyLWJvb3QtZGV0ZWN0aW9uLmNqcyc7XG5pbXBvcnQge1xuICByZXNvbHZlQXBwaXVtU3Bhd25GbGFncyxcbiAgcmVzb2x2ZUVtdWxhdG9yU3Bhd25GbGFnc1xufSBmcm9tICcuL3NwYXduLW9wdGlvbnMuY2pzJztcbmltcG9ydCB7XG4gIGJ1aWxkVGVhcmRvd25NZXNzYWdlLFxuICByZXNvbHZlVGVhcmRvd25PdXRjb21lXG59IGZyb20gJy4vdGVhcmRvd24tdmVyZGljdC5janMnO1xuaW1wb3J0IHtcbiAgQXBwaXVtVHJhbnNwb3J0LFxuICBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRIXG59IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5janMnO1xuaW1wb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLmNqcyc7XG5pbXBvcnQge1xuICBhc3NlcnROZXZlcixcbiAgZW5zdXJlTm9uTnVsbGFibGVcbn0gZnJvbSAnLi90eXBlLWd1YXJkcy5janMnO1xuaW1wb3J0IHtcbiAgc2hvdWxkSGlkZUFwcGl1bUNvbnNvbGUsXG4gIHNob3VsZEhpZGVFbXVsYXRvcldpbmRvd1xufSBmcm9tICcuL3Zpc2liaWxpdHkuY2pzJztcbmltcG9ydCB7XG4gIGJ1aWxkV2VkZ2VkQXBwaXVtU2VydmVyTWVzc2FnZSxcbiAgY2hlY2tJc0FwcGl1bVN0YXR1c1JlYWR5LFxuICByZXNvbHZlV2VkZ2VkQXBwaXVtU2VydmVyUmVtZWR5XG59IGZyb20gJy4vd2VkZ2VkLWFwcGl1bS1zZXJ2ZXIuY2pzJztcblxuY29uc3QgQVBQX1BBQ0tBR0UgPSAnbWQub2JzaWRpYW4nO1xuY29uc3QgQVBQX0FDVElWSVRZID0gYCR7QVBQX1BBQ0tBR0V9Lk1haW5BY3Rpdml0eWA7XG4vKlxuICogSG93IG1hbnkgdGltZXMgdGhlIEFWRCBhZG9wdGlvbiBwcm9iZSBhc2tzIGEgZGV2aWNlIHdoaWNoIEFWRCBpdCBpcyBzZXJ2aW5nLlxuICogT25lIHJldHJ5LCBiZWNhdXNlIHRoZSBhbHRlcm5hdGl2ZSB0byBhbiBhbnN3ZXIgaXMgcmVmdXNpbmcgdG8gbGF1bmNoOiBhXG4gKiBzZWNvbmQgNXMgbG9vayBpcyBmYXIgY2hlYXBlciB0aGFuIGVpdGhlciBhIGZhbHNlIHJlZnVzYWwgb3IgdGhlIGNvbGxpZGluZ1xuICogbGF1bmNoIGEgZGlzY2FyZGVkIHRpbWVvdXQgdXNlZCB0byBhdXRob3JpemUgKHNlZSBgYXZkLXByb2JlLXZlcmRpY3QudHNgKS5cbiAqL1xuY29uc3QgQVZEX1BST0JFX0FUVEVNUFRfQ09VTlQgPSAyO1xuLypcbiAqIFRoZSBjb25uZWN0aXZpdHkgZHVtcCBnZXRzIGEgYnVkZ2V0IG9mIGl0cyBPV04sIHdlbGwgYWJvdmUgdGhlIDVzIHRoZSBvdGhlclxuICogcHJvYmVzIHNoYXJlIFx1MjAxNCBub3QgYmVjYXVzZSB0aGUgZHVtcCBpcyBzbG93IChtZWFzdXJlZCAwLjktMi40cyBvbiBhIHJlc3BvbnNpdmVcbiAqIGd1ZXN0LCBhbG9uZ3NpZGUgYGdldHByb3BgJ3MgMC43LTIuMXMpLCBidXQgYmVjYXVzZSBpdCBydW5zIGluIHRoZSB3aW5kb3dcbiAqIHdoZXJlIHJlc2lkdWFsIHBvc3QtYm9vdCBjb250ZW50aW9uIHN0aWxsIGluZmxhdGVzIGV2ZXJ5IGBhZGJgIHJvdW5kLXRyaXBcbiAqIDI1LTUweCAoTDE5KS4gQXQgNXMgaXQgb3ZlcnJhbiBvbiBFVkVSWSBwb2xsIG9mIHRoZSBmaXJzdCBlbmQtdG8tZW5kIHJ1bixcbiAqIGFuZCBhbiBvdmVycnVuIGlzIHJlcG9ydGVkIGFzIFwibm8gbmV0d29ya1wiLCBzbyB0b28gc21hbGwgYSBidWRnZXQgZG9lcyBub3RcbiAqIGRlZ3JhZGUgdGhpcyBnYXRlIFx1MjAxNCBpdCBzaWxlbnRseSBkaXNhYmxlcyBpdCB3aGlsZSB0aGUgZ2F0ZSBjbGFpbXMgdGhlXG4gKiBvcHBvc2l0ZS4gMzBzIGlzIH4xNXggdGhlIGlkbGUgY29zdCwgd2hpY2ggaXMgdGhhdCBpbmZsYXRpb24gd2l0aCByb29tLlxuICovXG5jb25zdCBBREJfRFVNUFNZU19USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDMwXzAwMDtcbmNvbnN0IEFQUElVTV9DT05ORUNUSU9OX1JFVFJZX0NPVU5UID0gMztcbmNvbnN0IEFQUElVTV9FU0NBTEFURURfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDUwMDA7XG5jb25zdCBBUFBJVU1fT1VUUFVUX1RBSUxfTUFYX0xFTkdUSCA9IDgwMDA7XG5jb25zdCBBUFBJVU1fUFJFRkxJR0hUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IEFQUElVTV9TVEFSVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IEFQUElVTV9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTVfMDAwO1xuY29uc3QgQURCX1ZBVUxUX1NXRUVQX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzBfMDAwO1xuLy8gQXBwaXVtIGluc2VjdXJlIGZlYXR1cmUgbGV0dGluZyB0aGUgVWlBdXRvbWF0b3IyIGRyaXZlciBhdXRvLWRvd25sb2FkIGFcbi8vIGNocm9tZWRyaXZlciBtYXRjaGluZyBPYnNpZGlhbidzIFdlYlZpZXcgQ2hyb21lIHZlcnNpb24uIEVuYWJsaW5nIGl0IG9uIHRoZVxuLy8gQXBwaXVtIHNlcnZlciAoaXQgaGFzIG5vIGVmZmVjdCBhcyBhIGNhcGFiaWxpdHkpIGF2b2lkcyB0aGUgZmFpbHVyZVxuLy8gXCJObyBDaHJvbWVkcml2ZXIgZm91bmQgdGhhdCBjYW4gYXV0b21hdGUgQ2hyb21lIC4uLlwiLlxuY29uc3QgQ0hST01FRFJJVkVSX0FVVE9ET1dOTE9BRF9GRUFUVVJFID0gJ3VpYXV0b21hdG9yMjpjaHJvbWVkcml2ZXJfYXV0b2Rvd25sb2FkJztcbmNvbnN0IERFRkFVTFRfVFJBTlNQT1JUX1RZUEUgPSAnb2JzaWRpYW4tY2RwJztcbmNvbnN0IEFORFJPSURfQVBQSVVNX1RSQU5TUE9SVF9UWVBFOiBPYnNpZGlhbkFuZHJvaWRBcHBpdW1UcmFuc3BvcnRPcHRpb25zWyd0eXBlJ10gPSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nO1xuY29uc3QgREVWSUNFX0lETEVfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAyMDAwO1xuLypcbiAqIEJ1ZGdldCBmb3IgZWFjaCBvZiB0aGUgdHdvIGxpdmVuZXNzIHByb2JlcyB0YWtlbiBpbW1lZGlhdGVseSBiZWZvcmUgdGhlXG4gKiBzZXNzaW9uIChzZWUgYGVtdWxhdG9yLWxpdmVuZXNzLnRzYCkuIFdlbGwgYWJvdmUgdGhlIDVzIHRoZSBwcmVmbGlnaHQgcHJvYmVzXG4gKiBzaGFyZSwgYmVjYXVzZSB0aGlzIG9uZSBydW5zIGluIHRoZSBwb3N0LWJvb3QgY29udGVudGlvbiB3aW5kb3cgdGhhdCBpbmZsYXRlc1xuICogZXZlcnkgYGFkYmAgcm91bmQtdHJpcCAyNS01MHggKEw0NSkgXHUyMDE0IGFuZCBoZXJlIGEgZmFsc2UgXCJubyBhbnN3ZXJcIiB3b3VsZFxuICogYWJvcnQgYSBydW4gdGhhdCB3YXMgYWJvdXQgdG8gd29yaywgd2hpY2ggaXMgYSB3b3JzZSBlcnJvciB0aGFuIHdhaXRpbmcuXG4gKiAxNXMgaXMgd2hhdCB0aGUgc2l4IGhhbmQtYm9vdHMgdGhhdCBtZWFzdXJlZCB0aGUgd2VkZ2UgdXNlZCwgYW5kIG5vIGhlYWx0aHlcbiAqIGd1ZXN0IGNhbWUgY2xvc2UgdG8gaXQ6IHRoZSBmYWlsdXJlcyBodW5nIGluZGVmaW5pdGVseSByYXRoZXIgdGhhbiBhbnN3ZXJpbmdcbiAqIHNsb3dseS5cbiAqL1xuY29uc3QgREVWSUNFX0xJVkVORVNTX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTVfMDAwO1xuLypcbiAqIEhvdyBtYW55IHRpbWVzIGVhY2ggbGl2ZW5lc3MgcHJvYmUgaXMgYXNrZWQgYmVmb3JlIGl0cyBzaWxlbmNlIGlzIGJlbGlldmVkLlxuICogT25lIHJldHJ5LCBtYXRjaGluZyBgQVZEX1BST0JFX0FUVEVNUFRfQ09VTlRgIGFuZCBmb3IgdGhlIHNhbWUgcmVhc29uOiB0aGVcbiAqIHZlcmRpY3QgYWJvcnRzIHRoZSBydW4sIHNvIGEgc2Vjb25kIGxvb2sgaXMgZmFyIGNoZWFwZXIgdGhhbiBhIHdyb25nIGNhbGwuXG4gKi9cbmNvbnN0IERFVklDRV9MSVZFTkVTU19BVFRFTVBUX0NPVU5UID0gMjtcbi8qXG4gKiBIb3cgbWFueSBlbXVsYXRvcnMgYSBydW4gbWF5IGJvb3QgYmVmb3JlIGdpdmluZyB1cC4gT25lIHJldHJ5OiB0aGUgd2VkZ2UgdGhhdFxuICogbW90aXZhdGVzIGl0IGlzIG5vdCBkZXRlcm1pbmlzdGljIFx1MjAxNCBtZWFzdXJlZCAyMDI2LTA5LTA1LCBhIGZpcnN0IGVtdWxhdG9yIHdlbnRcbiAqIHF1aWV0IDEyOXMgaW4gYW5kIHRoZSByZXBsYWNlbWVudCBib290ZWQgMTFzIGxhdGVyIHJhbiB0aGUgd2hvbGUgc3VpdGUgXHUyMDE0IGJ1dCBhXG4gKiBjb2xkIGJvb3QgY29zdHMgfjkwLTIyMHMsIHNvIGEgc2Vjb25kIGZhaWx1cmUgaXMgd2hlcmUgdGhlIHJ1biBzaG91bGQgc3RvcCBhbmRcbiAqIHNheSBzbyByYXRoZXIgdGhhbiBrZWVwIHBheWluZy5cbiAqL1xuY29uc3QgRU1VTEFUT1JfQk9PVF9BVFRFTVBUX0NPVU5UID0gMjtcbmNvbnN0IEVNVUxBVE9SX0JPT1RfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAyMDAwO1xuY29uc3QgRU1VTEFUT1JfQk9PVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEyMF8wMDA7XG5jb25zdCBFTVVMQVRPUl9MSVNUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTBfMDAwO1xuY29uc3QgRU1VTEFUT1JfT1VUUFVUX1RBSUxfTUFYX0xFTkdUSCA9IDgwMDA7XG5jb25zdCBIVFRQX01VTFRJUExFX0NIT0lDRVMgPSAzMDA7XG5jb25zdCBIVFRQX09LID0gMjAwO1xuLy8gVGhlIFczQyBkZWZhdWx0LCByZXN0YXRlZCBiZWNhdXNlIGB0aW1lb3V0c2AgaXMgc2V0IGFzIGEgd2hvbGUgYmFnOyBubyBlbGVtZW50IGlzIGV2ZXIgbG9jYXRlZCBpbXBsaWNpdGx5IGhlcmUuXG5jb25zdCBJTVBMSUNJVF9XQUlUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMDtcbmNvbnN0IEtFWUNPREVfTUVOVSA9IDgyO1xuY29uc3QgS0VZQ09ERV9XQUtFVVAgPSAyMjQ7XG5jb25zdCBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORCA9IDEwMDA7XG5jb25zdCBORVRXT1JLX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gMjAwMDtcbi8qXG4gKiBIb3cgbG9uZyB0aGUgc2VydmVyIHdhaXRzIGZvciBhIG5ldyBjb21tYW5kIGJlZm9yZSBhc3N1bWluZyB0aGUgY2xpZW50IHF1aXRcbiAqIGFuZCBlbmRpbmcgdGhlIHNlc3Npb24uIEFwcGl1bSByZWFkcyBgbmV3Q29tbWFuZFRpbWVvdXRgIGluIFNFQ09ORFMsIHdoaWNoIHRoZVxuICogbmFtZSB0aGlzIGNvbnN0YW50IHVzZWQgdG8gY2FycnkgKGBDT01NQU5EX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTYCkgZ290XG4gKiB3cm9uZyBcdTIwMTQgdGhlIHZhbHVlIHdhcyBhbHdheXMgdGhlIGludGVuZGVkIGZpdmUgbWludXRlcywgYW5kIG9ubHkgdGhlIHVuaXQgaW5cbiAqIHRoZSBuYW1lIHdhcyBhIGxpZS4gSXQgaXMgdW5yZWxhdGVkIHRvIHRoZSBwZXItc2NyaXB0IGNhcCwgd2hpY2ggaXNcbiAqIGB0aW1lb3V0cy5zY3JpcHRgLlxuICovXG5jb25zdCBORVdfQ09NTUFORF9USU1FT1VUX0lOX1NFQ09ORFMgPSAzMDA7XG4vLyBUaGUgVzNDIGRlZmF1bHQsIHJlc3RhdGVkIGZvciB0aGUgc2FtZSByZWFzb24gYXMgdGhlIGltcGxpY2l0IHdhaXQgYWJvdmUuXG5jb25zdCBQQUdFX0xPQURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMDBfMDAwO1xuY29uc3QgU0VSVkVSX0lOU1RBTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxMjBfMDAwO1xuY29uc3QgU0VSVkVSX0xBVU5DSF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEyMF8wMDA7XG4vKlxuICogVGhlIHN5bmMgdGVhcmRvd24gcnVucyBpbnNpZGUgYHByb2Nlc3Mub24oJ2V4aXQnKWAsIHNvIHRoaXMgcXVlcnkgYmxvY2tzIHRoZVxuICogZXhpdCBpdHNlbGYuIFNob3J0IG9uIHB1cnBvc2U6IGxvc2luZyB0aGUgZXNjYWxhdGlvbiBpcyBiZXR0ZXIgdGhhbiBob2xkaW5nXG4gKiB0aGUgaGFuZGxlciBmb3IgdGhlIGFzeW5jIHBhdGgncyAzMHMsIGFuZCB0aGUgc3luYyBsb2cgbmV2ZXIgY2xhaW1zIGFcbiAqIHZlcmlmaWVkIHN0b3AgYW55d2F5LlxuICovXG5jb25zdCBTWU5DX1RFQVJET1dOX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcblxuLyoqXG4gKiBIb3cgdGhlIHJlcXVlc3RlZCBhcHAgKGFzYXIpIHZlcnNpb24gd2lsbCBiZSBhcHBsaWVkIHRvIGFuIG93bmVkIGluc3RhbmNlOyBhdFxuICogbW9zdCBvbmUgZmllbGQgaXMgc2V0IChzZWUge0BsaW5rIHJlc29sdmVBc2FyUGxhbn0pLlxuICovXG5pbnRlcmZhY2UgQXNhclBsYW4ge1xuICAvKipcbiAgVGhlIHVzZXIncyBuZXdlc3QgaW5zdGFsbGVkIGFzYXIgdG8gcHJvdmlzaW9uIGFzLWlzIChubyBkb3dubG9hZCkuXG4gICAqL1xuICByZWFkb25seSBhc2FyPzogT3duZWRJbnN0YW5jZUNvbmZpZ1snYXNhciddO1xuXG4gIC8qKlxuICBUaGUgYXBwIHZlcnNpb24gdG8gZG93bmxvYWQgYW5kIGFzYXItc3dhcCBvbnRvIHRoZSBzaGVsbC5cbiAgICovXG4gIHJlYWRvbmx5IGFzYXJWZXJzaW9uVG9Td2FwPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgYXBwIHZlcnNpb24gd2hvc2Ugb3duIGluc3RhbGxlciBzaGVsbCB0byBkb3dubG9hZCAoYSBkb3duZ3JhZGUpLlxuICAgKi9cbiAgcmVhZG9ubHkgZG93bmdyYWRlSW5zdGFsbGVyVmVyc2lvbj86IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBPdXRjb21lIG9mIG9uZSBgZHVtcHN5cyBjb25uZWN0aXZpdHlgIHByb2JlOiBleGFjdGx5IG9uZSBmaWVsZCBpcyBzZXQuXG4gKlxuICogQSBmYWlsZWQgcHJvYmUgY2FycmllcyAqKndoeSoqIGl0IGZhaWxlZCByYXRoZXIgdGhhbiBjb2xsYXBzaW5nIGludG8gXCJub1xuICogb3V0cHV0XCIsIGJlY2F1c2UgdGhlIHR3byBmYWlsdXJlcyBsb29rIG5vdGhpbmcgYWxpa2UgaW4gcHJhY3RpY2UgYW5kIG9ubHkgb25lXG4gKiBvZiB0aGVtIGlzIHdvcnRoIHdhaXRpbmcgb3V0IFx1MjAxNCBhIDMwcyB0aW1lb3V0IGlzIGEgY29udGVuZGVkIGd1ZXN0LCB3aGlsZSBhblxuICogaW5zdGFudCBgZXJyb3I6IGNsb3NlZGAgaXMgYSBkZWFkIG9uZS5cbiAqL1xuaW50ZXJmYWNlIENvbm5lY3Rpdml0eVByb2JlUmVzdWx0IHtcbiAgLyoqXG4gIFdoeSB0aGUgcHJvYmUgZmFpbGVkLCBzZXQgaWZmIGl0IGRpZCBub3QgYW5zd2VyLlxuICAgKi9cbiAgcmVhZG9ubHkgZmFpbHVyZVJlYXNvbj86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIHJhdyBkdW1wLCBzZXQgaWZmIHRoZSBwcm9iZSBhbnN3ZXJlZC5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dD86IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGUgdHdvIHBvc3QtYm9vdCByZWFkaW5lc3MgYnVkZ2V0cywgY2FycmllZCB0b2dldGhlciBzbyB0aGUgc3RhcnRlZC1kZXZpY2VcbiAqIGFuZCByZXVzZWQtZGV2aWNlIGJyYW5jaGVzIGNhbm5vdCBkcmlmdCBhcGFydCBvbiB3aGljaCBnYXRlcyB0aGV5IHJ1bi5cbiAqL1xuaW50ZXJmYWNlIERldmljZVJlYWRpbmVzc1RpbWVvdXRzIHtcbiAgLyoqXG4gIFJlc29sdmVkIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgcG9zdC1ib290IGRldmljZS1pZGxlIHdhaXQgKGAwYCBza2lwcyBpdCkuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFJlc29sdmVkIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgbmV0d29yay1yZWFkeSB3YWl0IChgMGAgc2tpcHMgaXQpLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIGVtdWxhdG9yJ3MgY2FwdHVyZWQgb3V0cHV0LCBjYXJyaWVkIHBhc3QgYm9vdCBzbyBhIGZhaWx1cmUgZHVyaW5nIHNlc3Npb25cbiAqIGNyZWF0aW9uIGNhbiBzdGlsbCBxdW90ZSBpdC5cbiAqXG4gKiBCb290IHVzZWQgdG8gYmUgdGhlIGVuZCBvZiB0aGUgZW11bGF0b3IncyB1c2VmdWxuZXNzIGFzIGEgd2l0bmVzczogdGhlIGNhcHR1cmVcbiAqIHdhcyBmcm96ZW4gdGhlIG1vbWVudCBhIGRldmljZSBhcHBlYXJlZCwgYW5kIG5vdGhpbmcgcmVhZCBpdCBhZ2Fpbi4gQnV0IHRoZVxuICogbGluZXMgdGhhdCBleHBsYWluIGEgd2VkZ2UgXHUyMDE0IGBkZXRlY3RlZCBhIGhhbmdpbmcgdGhyZWFkICdRRU1VMiBtYWluIGxvb3AnYCxcbiAqIG5ldHNpbSdzIGBVbmFibGUgdG8gcmVjb25uZWN0IHRvIHBhY2tldCBzdHJlYW1lcmAgXHUyMDE0IGFyZSBwcmludGVkICphZnRlciogdGhhdCxcbiAqIHdoaWxlIHRoZSBoYXJuZXNzIGlzIGluc2lkZSBgZXN0YWJsaXNoU2Vzc2lvbmAuIFNvIHRoZSB3aW5kb3cgbm93IGNsb3NlcyB3aGVuXG4gKiB0aGUgc2Vzc2lvbiBpcyBlc3RhYmxpc2hlZCByYXRoZXIgdGhhbiB3aGVuIHRoZSBkZXZpY2UgYXBwZWFycywgYW5kIHRoaXMgcGFpclxuICogaXMgd2hhdCB0aGUgc2Vzc2lvbiBwYXRoIG5lZWRzIHRvIGhvbGQgdG8gZG8gdGhhdCAoc2VlIGBlbXVsYXRvci1saXZlbmVzcy50c2ApLlxuICovXG5pbnRlcmZhY2UgRW11bGF0b3JDYXB0dXJlIHtcbiAgLyoqXG4gIFJldHVybnMgdGhlIGNhcHR1cmVkIHN0ZG91dCtzdGRlcnIgdGFpbCAoYm91bmRlZCB0byB0aGUgbW9zdCByZWNlbnQgb3V0cHV0KS5cbiAgICovXG4gIHJlYWRvbmx5IHJlYWQ6ICgpID0+IHN0cmluZztcblxuICAvKipcbiAgRnJlZXplcyB0aGUgdGFpbC4gQ2FsbGVkIG9uY2UgdGhlIHNlc3Npb24gaXMgZXN0YWJsaXNoZWQgYW5kIHRoZSBlbXVsYXRvciBoYXMgbm90aGluZyBsZWZ0IHRvIGV4cGxhaW4uXG4gICAqL1xuICByZWFkb25seSBzdG9wOiAoKSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBBcHBpdW1UcmFuc3BvcnRGYWN0b3J5LmVuc3VyZURldmljZUNvbm5lY3RlZH0uXG4gKi9cbmludGVyZmFjZSBFbnN1cmVEZXZpY2VDb25uZWN0ZWRQYXJhbXMge1xuICAvKipcbiAgQVZEIG5hbWUgdG8gY29ubmVjdCB0byAoc3RhcnRpbmcgYSBuZXcgZW11bGF0b3IgaWYgbm90IGFscmVhZHkgcnVubmluZykuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFJlc29sdmVkIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgcG9zdC1ib290IGRldmljZS1pZGxlIHdhaXQgKGAwYCBza2lwcyBpdCkuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGF1dG8tc3RhcnRlZCBlbXVsYXRvciB3aW5kb3cgaXMgc2hvd24gKG9taXR0ZWQgXHUyMTkyIGhpZGRlbikuXG4gICAqL1xuICByZWFkb25seSBpc0VtdWxhdG9yVmlzaWJsZT86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFJlc29sdmVkIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgbmV0d29yay1yZWFkeSB3YWl0IChgMGAgc2tpcHMgaXQpLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGF1dG8tc3RhcnRlZCBlbXVsYXRvciBtYXkgcmVzdW1lIGFuZCByZWZyZXNoIHRoZSBBVkQncyBib290IHNuYXBzaG90IChvbWl0dGVkIFx1MjE5MiBjb2xkIGJvb3QpLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkUmV1c2VFbXVsYXRvclNuYXBzaG90PzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2Yge0BsaW5rIEFwcGl1bVRyYW5zcG9ydEZhY3RvcnkuZW5zdXJlRGV2aWNlQ29ubmVjdGVkfS5cbiAqL1xuaW50ZXJmYWNlIEVuc3VyZURldmljZUNvbm5lY3RlZFJlc3VsdCB7XG4gIC8qKlxuICBUaGUgYWN0dWFsIGRldmljZSBJRCB0aGF0IGlzIGNvbm5lY3RlZCAobWF5IGRpZmZlciBmcm9tIHRoZSByZXF1ZXN0ZWQgb25lKS5cbiAgICovXG4gIHJlYWRvbmx5IGFjdHVhbERldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBlbXVsYXRvcidzIG91dHB1dCBjYXB0dXJlLCB3aGVuIHRoaXMgcnVuIHN0YXJ0ZWQgaXQuIEFic2VudCBmb3IgYW5cbiAgICogYWRvcHRlZCBkZXZpY2UsIHdob3NlIGVtdWxhdG9yIHRoaXMgcnVuIG5ldmVyIHNwYXduZWQgYW5kIHdob3NlIG91dHB1dCBpdFxuICAgKiB0aGVyZWZvcmUgbmV2ZXIgaGFkLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JDYXB0dXJlPzogRW11bGF0b3JDYXB0dXJlIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgcHJvY2VzcywgaWYgb25lIHdhcyBhdXRvLXN0YXJ0ZWQuXG4gICAqL1xuICByZWFkb25seSBlbXVsYXRvclByb2Nlc3M/OiBDaGlsZFByb2Nlc3MgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBlbXVsYXRvciBwcm9jZXNzZXMgdGhpcyBydW4gaXMgcmVzcG9uc2libGUgZm9yIGtpbGxpbmcgXHUyMDE0IHRoZSBsYXVuY2hlclxuICAgKiBwbHVzIHRoZSBRRU1VIGJhY2tlbmQgaXQgZm9ya2VkLCBpZGVudGlmaWVkIGJ5IGRpZmZpbmcgdGhlIGhvc3QncyBwcm9jZXNzXG4gICAqIGxpc3QgYWNyb3NzIHRoZSBsYXVuY2guIEVtcHR5IHdoZW4gdGhlIGRldmljZSB3YXMgcmV1c2VkIHJhdGhlciB0aGFuXG4gICAqIHN0YXJ0ZWQuIFNlZSBgZW11bGF0b3ItYmFja2VuZC50c2AgZm9yIHdoeSB0aGUgbGF1bmNoZXIncyBQSUQgYWxvbmUgaXMgbm90XG4gICAqIGVub3VnaC5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeS5lc3RhYmxpc2hTZXNzaW9ufS5cbiAqL1xuaW50ZXJmYWNlIEVzdGFibGlzaFNlc3Npb25QYXJhbXMge1xuICAvKipcbiAgVGhlIEFuZHJvaWQgcGFja2FnZSB0aGUgc2Vzc2lvbiBkcml2ZXMuXG4gICAqL1xuICByZWFkb25seSBhcHBJZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgbWFya2VyIG9mIHRoZSBhZG9wdGVkIHNlcnZlciwgd2hlbiBhbiBlYXJsaWVyIHJ1biBvZiB0aGlzIGhhcm5lc3MgbGVmdCBvbmUuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1TZXJ2ZXJNYXJrZXI6IEFwcGl1bVNlcnZlck1hcmtlciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIGEgcmVwbGFjZW1lbnQgQXBwaXVtIHNlcnZlciB0byBiZWNvbWUgcmVhZHkuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgZGV2aWNlIHRoZSBzZXNzaW9uIGlzIGVzdGFibGlzaGVkIGFnYWluc3QuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICBXaGV0aGVyIHRoZSBzZXJ2ZXIgd2FzIGFkb3B0ZWQgcmF0aGVyIHRoYW4gc3RhcnRlZCBieSB0aGlzIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IGlzQWRvcHRlZFNlcnZlcjogYm9vbGVhbjtcblxuICAvKipcbiAgV2hldGhlciBhIHJlcGxhY2VtZW50IHNlcnZlcidzIGNvbnNvbGUgd2luZG93IGlzIHNob3duIChvbWl0dGVkIFx1MjE5MiBoaWRkZW4pLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNBcHBpdW1Db25zb2xlVmlzaWJsZT86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0gc2VydmVyIHBvcnQuXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG5cbiAgLyoqXG4gIFJlc29sdmVkIHBlci1zY3JpcHQgKHBlci1gZXZhbEluT2JzaWRpYW5gKSBjYXAgaW4gbWlsbGlzZWNvbmRzLCBzZW50IGFzIHRoZSBXM0MgYHRpbWVvdXRzLnNjcmlwdGAgY2FwYWJpbGl0eS5cbiAgICovXG4gIHJlYWRvbmx5IHNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICBSZXNvbHZlZCBXZWJEcml2ZXJJTyBjb25uZWN0aW9uIHJldHJ5IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgcmVhZG9ubHkgc2Vzc2lvbkNvbm5lY3Rpb25SZXRyeVRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICBXaGV0aGVyIEFwcGl1bSBhdXRvLXN0YXJ0IGlzIGFsbG93ZWQgXHUyMDE0IGEgYGZhbHNlYCBoZXJlIGFsc28gZm9yYmlkcyByZXBsYWNpbmcgYSB3ZWRnZWQgc2VydmVyLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkQXV0b1N0YXJ0QXBwaXVtPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIEFwcGl1bSBzZXJ2ZXIgVVJMLlxuICAgKi9cbiAgcmVhZG9ubHkgdXJsOiBVUkw7XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIHtAbGluayBBcHBpdW1UcmFuc3BvcnRGYWN0b3J5LmVzdGFibGlzaFNlc3Npb259LlxuICovXG5pbnRlcmZhY2UgRXN0YWJsaXNoU2Vzc2lvblJlc3VsdCB7XG4gIC8qKlxuICBUaGUgcmVwbGFjZW1lbnQgQXBwaXVtIHNlcnZlciBwcm9jZXNzLCB3aGVuIGEgd2VkZ2VkIG9uZSBoYWQgdG8gYmUgcmVzdGFydGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgYXBwaXVtUHJvY2Vzcz86IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVzdGFibGlzaGVkIHNlc3Npb24uXG4gICAqL1xuICByZWFkb25seSBicm93c2VyOiBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIHJlbW90ZT4+O1xufVxuXG4vKipcbiAqIFRoZSBsb2NhbGx5LWluc3RhbGxlZCBPYnNpZGlhbiBzaGVsbCByZXNvbHZlZCBieSB7QGxpbmsgcmVzb2x2ZUluc3RhbGxlZFNoZWxsT3JOdWxsfS5cbiAqL1xuaW50ZXJmYWNlIEluc3RhbGxlZFNoZWxsIHtcbiAgLyoqXG4gIEFic29sdXRlIHBhdGggdG8gdGhlIGluc3RhbGxlZCBzaGVsbCBleGVjdXRhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhlUGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgZGV0ZWN0ZWQgc2hlbGwgdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAgd2hlbiBpdCBjYW5ub3QgYmUgZGV0ZXJtaW5lZC5cbiAgICovXG4gIHJlYWRvbmx5IHNoZWxsVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEEgc3Bhd25lZCBjaGlsZCBwcm9jZXNzICh0aGUgQW5kcm9pZCBlbXVsYXRvciBvciB0aGUgQXBwaXVtIHNlcnZlcikgdG9nZXRoZXJcbiAqIHdpdGggaGVscGVycyB0byBpbnNwZWN0IGl0cyBjYXB0dXJlZCBvdXRwdXQgYW5kIGV4aXQgc3RhdHVzLlxuICovXG5pbnRlcmZhY2UgUGFyc2VQb3J0T3duZXJQaWRzUGFyYW1zIHtcbiAgLyoqXG4gIFJhdyBzdGRvdXQgb2YgdGhlIHBsYXRmb3JtJ3MgcG9ydCBxdWVyeS5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgcG9ydCB0aGF0IHdhcyBxdWVyaWVkLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUHJvY2Vzc0xhdW5jaCB7XG4gIC8qKlxuICBUaGUgc3Bhd25lZCBwcm9jZXNzLlxuICAgKi9cbiAgcHJvY2VzczogQ2hpbGRQcm9jZXNzO1xuXG4gIC8qKlxuICBSZXR1cm5zIHRoZSBleGl0IC8gc3Bhd24tZmFpbHVyZSBkZXRhaWxzIG9uY2UgdGhlIHByb2Nlc3MgaXMgbm8gbG9uZ2VyIHJ1bm5pbmcsIG90aGVyd2lzZSBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHJlYWRFeGl0SW5mbzogKCkgPT4gUHJvY2Vzc0V4aXRJbmZvIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBSZXR1cm5zIHRoZSBjYXB0dXJlZCBzdGRvdXQrc3RkZXJyIChib3VuZGVkIHRvIHRoZSBtb3N0IHJlY2VudCBvdXRwdXQpLlxuICAgKi9cbiAgcmVhZE91dHB1dDogKCkgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICBTdG9wcyBhY2N1bXVsYXRpbmcgb3V0cHV0LiBDYWxsIG9uY2Ugc3RhcnR1cCBoYXMgc3VjY2VlZGVkLlxuICAgKi9cbiAgc3RvcENhcHR1cmU6ICgpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIEFwcGl1bVRyYW5zcG9ydEZhY3Rvcnkuc3RhcnRBcHBpdW1BbmRFbXVsYXRvcn0uXG4gKi9cbmludGVyZmFjZSBSZWNsYWltVW5zdG9wcGVkQXBwaXVtU2VydmVyUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBtYXJrZXIgdGhhdCBwcm92ZXMgdGhlIGxlZnRvdmVyIGlzIHRoaXMgaGFybmVzcydzIG93bi5cbiAgICovXG4gIHJlYWRvbmx5IG1hcmtlcjogQXBwaXVtU2VydmVyTWFya2VyO1xuXG4gIC8qKlxuICBUaGUgcG9ydCBpdCBpcyBob2xkaW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuXG4gIC8qKlxuICBXaGV0aGVyIHRoaXMgcnVuIGlzIGFsbG93ZWQgdG8gc3RhcnQgYSByZXBsYWNlbWVudC5cbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZEF1dG9TdGFydEFwcGl1bT86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBzZXJ2ZXIncyBVUkwuXG4gICAqL1xuICByZWFkb25seSB1cmw6IFVSTDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeS5yZWNvcmRFbXVsYXRvckxhdW5jaERldmljZX0uXG4gKi9cbmludGVyZmFjZSBSZWNvcmRFbXVsYXRvckxhdW5jaERldmljZVBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQVZEIHdob3NlIGxhdW5jaCB3YXMgcmVjb3JkZWQuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBkZXZpY2UgdGhhdCBoYXMganVzdCBhcHBlYXJlZCBpbiBBREIuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICBXaGVuIHRoZSBlbXVsYXRvciB3YXMgbGF1bmNoZWQgXHUyMDE0IHdoYXQgaWRlbnRpZmllcyB0aGUgbGF1bmNoIHRoaXMgZGV2aWNlIGJlbG9uZ3MgdG8uXG4gICAqL1xuICByZWFkb25seSBsYXVuY2hlZEF0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeS5yZWNvcmRFbXVsYXRvckxhdW5jaH0uXG4gKi9cbmludGVyZmFjZSBSZWNvcmRFbXVsYXRvckxhdW5jaFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQVZEIGJlaW5nIHN0YXJ0ZWQuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBsYXVuY2hlciBqdXN0IHNwYXduZWQgZm9yIGl0LlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3I6IFByb2Nlc3NMYXVuY2g7XG5cbiAgLyoqXG4gIFdoZW4gaXQgd2FzIGxhdW5jaGVkLCB3aGljaCBldmVyeSBsYXRlciB3cml0ZSBvZiB0aGlzIG1hcmtlciBrZWVwcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgcHJvY2Vzc2VzIHRoYXQgcHJlZGF0ZSB0aGUgbGF1bmNoLCBzbyB0aGUgYmFja2VuZCBpdCBmb3JrcyBjYW4gYmUgaWRlbnRpZmllZCB3aXRob3V0IGEgc2Vjb25kIHNuYXBzaG90LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJlTGF1bmNoRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuaW50ZXJmYWNlIFN0YXJ0QXBwaXVtQW5kRW11bGF0b3JQYXJhbXMge1xuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBhdXRvLXN0YXJ0ZWQgQXBwaXVtIHNlcnZlciB0byBiZWNvbWUgcmVhZHkuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgQXBwaXVtIHNlcnZlciBVUkwuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1Vcmw6IFVSTDtcblxuICAvKipcbiAgQVZEIG5hbWUgdG8gc3RhcnQuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFJlc29sdmVkIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgcG9zdC1ib290IGRldmljZS1pZGxlIHdhaXQgKGAwYCBza2lwcyBpdCkuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGF1dG8tc3RhcnRlZCBBcHBpdW0gc2VydmVyIGNvbnNvbGUgd2luZG93IGlzIHNob3duIChvbWl0dGVkIFx1MjE5MiBoaWRkZW4pLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNBcHBpdW1Db25zb2xlVmlzaWJsZT86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIGF1dG8tc3RhcnRlZCBlbXVsYXRvciB3aW5kb3cgaXMgc2hvd24gKG9taXR0ZWQgXHUyMTkyIGhpZGRlbikuXG4gICAqL1xuICByZWFkb25seSBpc0VtdWxhdG9yVmlzaWJsZT86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFJlc29sdmVkIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB0aGUgbmV0d29yay1yZWFkeSB3YWl0IChgMGAgc2tpcHMgaXQpLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0gc2VydmVyIHBvcnQuXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG5cbiAgLyoqXG4gIFdoZXRoZXIgbWlzc2luZyBBcHBpdW0gZGVwZW5kZW5jaWVzIG1heSBiZSBhdXRvLWluc3RhbGxlZCBiZWZvcmUgdGhlIHNlcnZlciBpcyBhdXRvLXN0YXJ0ZWQuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRBdXRvSW5zdGFsbEFwcGl1bURlcGVuZGVuY2llczogYm9vbGVhbjtcblxuICAvKipcbiAgV2hldGhlciBBcHBpdW0gYXV0by1zdGFydCBpcyBhbGxvd2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkQXV0b1N0YXJ0QXBwaXVtPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgV2hldGhlciB0aGUgYXV0by1zdGFydGVkIGVtdWxhdG9yIG1heSByZXN1bWUgYW5kIHJlZnJlc2ggdGhlIEFWRCdzIGJvb3Qgc25hcHNob3QgKG9taXR0ZWQgXHUyMTkyIGNvbGQgYm9vdCkuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRSZXVzZUVtdWxhdG9yU25hcHNob3Q/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeS5zdGFydEFwcGl1bUFuZEVtdWxhdG9yfS5cbiAqL1xuaW50ZXJmYWNlIFN0YXJ0QXBwaXVtQW5kRW11bGF0b3JSZXN1bHQge1xuICAvKipcbiAgVGhlIGFjdHVhbCBkZXZpY2UgSUQgdGhhdCBpcyBjb25uZWN0ZWQgKG1heSBkaWZmZXIgZnJvbSB0aGUgcmVxdWVzdGVkIG9uZSkuXG4gICAqL1xuICByZWFkb25seSBhY3R1YWxEZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgQXBwaXVtIHNlcnZlciBwcm9jZXNzLCBpZiBvbmUgd2FzIGF1dG8tc3RhcnRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVByb2Nlc3M/OiBDaGlsZFByb2Nlc3MgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBhZG9wdGVkIHNlcnZlcidzIG1hcmtlciwgd2hlbiBhbiBlYXJsaWVyIHJ1biBvZiB0aGlzIGhhcm5lc3MgbGVmdCBvbmUuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1TZXJ2ZXJNYXJrZXI/OiBBcHBpdW1TZXJ2ZXJNYXJrZXIgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvcidzIG91dHB1dCBjYXB0dXJlLCB3aGVuIHRoaXMgcnVuIHN0YXJ0ZWQgaXQuXG4gICAqL1xuICByZWFkb25seSBlbXVsYXRvckNhcHR1cmU/OiBFbXVsYXRvckNhcHR1cmUgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBwcm9jZXNzLCBpZiBvbmUgd2FzIGF1dG8tc3RhcnRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGVtdWxhdG9yUHJvY2Vzcz86IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciBhbiBhbHJlYWR5LWxpc3RlbmluZyBzZXJ2ZXIgd2FzIGFkb3B0ZWQgcmF0aGVyIHRoYW4gc3RhcnRlZCBieSB0aGlzXG4gICAqIHJ1bi4gT25seSBhbiBhZG9wdGVkIHNlcnZlciBjYW4gYmUgdGhlIHN0YWxlIG9uZSBgd2VkZ2VkLWFwcGl1bS1zZXJ2ZXIudHNgXG4gICAqIGRlc2NyaWJlcy5cbiAgICovXG4gIHJlYWRvbmx5IGlzQWRvcHRlZEFwcGl1bVNlcnZlcjogYm9vbGVhbjtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIHByb2Nlc3NlcyB0aGlzIHJ1biBpcyByZXNwb25zaWJsZSBmb3Iga2lsbGluZzsgZW1wdHkgd2hlbiB0aGUgZGV2aWNlIHdhcyByZXVzZWQuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIEFwcGl1bVRyYW5zcG9ydEZhY3Rvcnkuc3dlZXBEZXZpY2VMZWZ0b3ZlclZhdWx0c30uXG4gKi9cbmludGVyZmFjZSBTdG9wQXV0b1N0YXJ0ZWRBcHBpdW1TZXJ2ZXJQYXJhbXMge1xuICAvKipcbiAgVGhlIHNlcnZlciBwcm9jZXNzIHRoaXMgcnVuIHNwYXduZWQuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1Qcm9jZXNzOiBDaGlsZFByb2Nlc3M7XG5cbiAgLyoqXG4gIFRoZSBwb3J0IGl0IHdhcyBzdGFydGVkIG9uLCB3aG9zZSBtYXJrZXIgaXMgY2xlYXJlZCBvciBzdGFtcGVkIGJ5IHRoZSBvdXRjb21lLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgc2VydmVyJ3MgVVJMLCBwb2xsZWQgdG8gZGVjaWRlIHdoZXRoZXIgaXQgYWN0dWFsbHkgc3RvcHBlZC5cbiAgICovXG4gIHJlYWRvbmx5IHVybDogVVJMO1xufVxuXG5pbnRlcmZhY2UgU3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBBcHBpdW0gc2VydmVyIHByb2Nlc3MsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBvbmUuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1Qcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgQVZEIG5hbWUsIGZvciB0aGUgZW11bGF0b3IncyB3YXJuaW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgYXZkTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgZGV2aWNlIHRoZSBlbXVsYXRvciBpcyBzZXJ2aW5nLCB3aGVuIHRoaXMgcnVuIHN0YXJ0ZWQgb25lLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBsYXVuY2hlciBwcm9jZXNzLCB3aGVuIHRoaXMgcnVuIHN0YXJ0ZWQgb25lLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JQcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgUElEcyB0aGlzIHJ1biBvd25zIFx1MjAxNCBzdGFydGVkLCBvciB0YWtlbiBvdmVyIGFzIGEgbGVmdG92ZXIuIE5vbi1lbXB0eSBtZWFucyB0aGUgZW11bGF0b3IgaXMgdGhpcyBydW4ncyB0byBzdG9wLlxuICAgKi9cbiAgcmVhZG9ubHkgb3duZWRFbXVsYXRvclBpZHM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gIC8qKlxuICBUaGUgQXBwaXVtIHBvcnQuXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0gc2VydmVyIFVSTC5cbiAgICovXG4gIHJlYWRvbmx5IHVybDogVVJMO1xufVxuXG5pbnRlcmZhY2UgU3RvcEVtdWxhdG9yQWZ0ZXJGYWlsZWRTdGFydFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQVZEIHRoZSBlbXVsYXRvciB3YXMgc3RhcnRlZCBmb3IuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBvbmxpbmUgZGV2aWNlcyBsaXN0ZWQgYmVmb3JlIHRoZSBsYXVuY2guXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZHNCZWZvcmU6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICBUaGUgbGF1bmNoIHRoYXQgZmFpbGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3I6IFByb2Nlc3NMYXVuY2g7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBwcm9jZXNzZXMgdGhhdCBwcmVkYXRlIHRoZSBsYXVuY2gsIGFuZCBhcmUgdGhlcmVmb3JlIG5vdCB0aGlzIHJ1bidzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JQaWRzQmVmb3JlOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuaW50ZXJmYWNlIFN3ZWVwRGV2aWNlTGVmdG92ZXJWYXVsdHNQYXJhbXMge1xuICAvKipcbiAgVGhlIGRldmljZSBVRElEIHRvIHN3ZWVwLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgVGhlIGRldmljZS1zaWRlIGRpcmVjdG9yeSBPYnNpZGlhbiBNb2JpbGUgc3RvcmVzIGl0cyB2YXVsdHMgaW4uXG4gICAqL1xuICByZWFkb25seSB2YXVsdEJhc2VQYXRoOiBzdHJpbmc7XG59XG5cbmxldCBjYWNoZWRUcmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0IHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZXNvbHZlQW5kUmVwb3J0Q29tcGF0aWJpbGl0eX0uXG4gKi9cbmludGVyZmFjZSBSZXNvbHZlQW5kUmVwb3J0Q29tcGF0aWJpbGl0eVBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgYXBwIChhc2FyKSB2ZXJzaW9uIHRoYXQgd2lsbCBiZSBzd2FwcGVkIG9udG8gdGhlIHNoZWxsLCBvciBgdW5kZWZpbmVkYFxuICAgKiB3aGVuIG5vIGFzYXItc3dhcCB3aWxsIGhhcHBlbiAobm90aGluZyBpcyBjaGVja2VkIHRoZW4pLlxuICAgKi9cbiAgcmVhZG9ubHkgYXBwVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgcmVzb2x2ZWQgaW5zdGFsbGVyL3NoZWxsIHZlcnNpb24sIG9yIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFsbGVyVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGFuIGAndW5ydW5uYWJsZSdgIHZlcmRpY3QgdGhyb3dzIHtAbGluayBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3J9XG4gICAqIChgdHJ1ZWApIG9yIHByb2NlZWRzIHRvIGxhdW5jaCB3aXRoIHRoZSB2ZXJkaWN0IHN1cmZhY2VkIGFzIGRhdGEgKGBmYWxzZWApLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcjogYm9vbGVhbjtcblxuICAvKipcbiAgV2hldGhlciBhIGAnbmFnZ2VkJ2AgKG9yIHByb2NlZWRpbmctYCd1bnJ1bm5hYmxlJ2ApIHZlcmRpY3QgaXMgbG9nZ2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlczogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGUgc2xpY2Ugb2YgYHdlYmRyaXZlcmlvYCdzIHN1cmZhY2UgdGhlIEFwcGl1bSBmYWN0b3J5IGNhbGxzLCBuYW1lZCBzbyB0aGVcbiAqIGxhenkgbG9hZCBoYXMgYSByZXR1cm4gdHlwZSB3aXRob3V0IGEgc3RhdGljIGltcG9ydCBvZiB0aGUgbW9kdWxlIGl0c2VsZi5cbiAqL1xuaW50ZXJmYWNlIFdlYmRyaXZlcmlvTW9kdWxlIHtcbiAgLyoqXG4gIFJlYXR0YWNoZXMgdG8gYW4gZXhpc3RpbmcgV2ViRHJpdmVyIHNlc3Npb24uXG4gICAqL1xuICByZWFkb25seSBhdHRhY2g6IHR5cGVvZiBhdHRhY2g7XG5cbiAgLyoqXG4gIENyZWF0ZXMgYSBuZXcgV2ViRHJpdmVyIHNlc3Npb24uXG4gICAqL1xuICByZWFkb25seSByZW1vdGU6IHR5cGVvZiByZW1vdGU7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFsbCBBcHBpdW0gdHJhbnNwb3J0IGNyZWF0aW9uIGxvZ2ljLCBpbmNsdWRpbmcgQXBwaXVtIHNlcnZlclxuICogc3RhcnR1cCwgZW11bGF0b3IgbWFuYWdlbWVudCwgYW5kIFdlYkRyaXZlcklPIHNlc3Npb24gZXN0YWJsaXNobWVudC5cbiAqXG4gKiBVc2luZyBhIGNsYXNzIGF2b2lkcyB0aHJlYWRpbmcgdGhlIHRyYW5zcG9ydCBgdHlwZWAgbGFiZWwgdGhyb3VnaCBldmVyeVxuICogaGVscGVyIGZ1bmN0aW9uIFx1MjAxNCBgdGhpcy5sb2coKWAgYXV0b21hdGljYWxseSBwcmVmaXhlcyBpdC5cbiAqL1xuY2xhc3MgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW11bGF0b3JzOiBFbXVsYXRvclJlY2xhaW1lcjtcbiAgcHJpdmF0ZSByZWFkb25seSB0eXBlOiBzdHJpbmc7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZykge1xuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgdGhpcy5lbXVsYXRvcnMgPSBuZXcgRW11bGF0b3JSZWNsYWltZXIoKG1lc3NhZ2UpID0+IHtcbiAgICAgIHRoaXMubG9nKG1lc3NhZ2UpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gQXBwaXVtIHRyYW5zcG9ydCBieSBlc3RhYmxpc2hpbmcgYSBXZWJEcml2ZXJJTyBzZXNzaW9uLlxuICAgKlxuICAgKiBJZiBgb3B0aW9ucy5zZXNzaW9uSWRgIGlzIHByZXNlbnQsIHJlYXR0YWNoZXMgdG8gdGhlIGV4aXN0aW5nIHNlc3Npb25cbiAgICogaW5zdGVhZCBvZiBjcmVhdGluZyBhIG5ldyBvbmUuIFRoaXMgYXZvaWRzIGR1cGxpY2F0ZSBBcHBpdW0vQURCIGNvbm5lY3Rpb25zXG4gICAqIHdoZW4gdGVzdCB3b3JrZXJzIHJldXNlIHRoZSBnbG9iYWwgc2V0dXAncyBzZXNzaW9uLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIEFuZHJvaWQgQXBwaXVtIHRyYW5zcG9ydCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyBBIGNvbmZpZ3VyZWQgQXBwaXVtIHRyYW5zcG9ydC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBjcmVhdGUob3B0aW9uczogT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgICByZXR1cm4gb3B0aW9ucy5zZXNzaW9uSWQgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLmRldmljZUlkICE9PSB1bmRlZmluZWQgPyB0aGlzLmF0dGFjaFRvRXhpc3RpbmdTZXNzaW9uKG9wdGlvbnMuc2Vzc2lvbklkLCBvcHRpb25zLmRldmljZUlkLCBvcHRpb25zKSA6IHRoaXMuY3JlYXRlTmV3U2Vzc2lvbihvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcm1zIHRoZSBlbXVsYXRvciByZWFwZXIgKGBlbXVsYXRvci1yZWFwZXIudHNgKSBmb3IgYW4gZW11bGF0b3IgdGhpcyBydW4gaGFzXG4gICAqIGp1c3QgcmVjb3JkZWQgYXMgaXRzIG93bi5cbiAgICpcbiAgICogQHBhcmFtIGF2ZE5hbWUgLSBUaGUgQVZEIHdob3NlIG1hcmtlciB3YXMganVzdCB3cml0dGVuLlxuICAgKiBAcGFyYW0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgLSBUaGUgZW11bGF0b3IncyBsYXVuY2ggdGltZSwgYXMgdGhlIG1hcmtlciByZWNvcmRzIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBhcm1FbXVsYXRvclJlYXBlcihhdmROYW1lOiBzdHJpbmcsIHN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzOiBudW1iZXIpOiB2b2lkIHtcbiAgICBzcGF3bkVtdWxhdG9yUmVhcGVyKHtcbiAgICAgIGF2ZE5hbWUsXG4gICAgICBsb2c6IChtZXNzYWdlKSA9PiB7XG4gICAgICAgIHRoaXMubG9nKG1lc3NhZ2UpO1xuICAgICAgfSxcbiAgICAgIHN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGF0dGFjaFRvRXhpc3RpbmdTZXNzaW9uKFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIGRldmljZUlkOiBzdHJpbmcsXG4gICAgb3B0aW9uczogT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9uc1xuICApOiBQcm9taXNlPE9ic2lkaWFuVHJhbnNwb3J0PiB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTChvcHRpb25zLmFwcGl1bVVybCk7XG4gICAgY29uc3QgcG9ydCA9IE51bWJlcih1cmwucG9ydCk7XG4gICAgY29uc3QgYXBwSWQgPSBvcHRpb25zLmFwcElkID8/IEFQUF9QQUNLQUdFO1xuXG4gICAgdGhpcy5sb2coYFJlYXR0YWNoaW5nIHRvIGV4aXN0aW5nIEFwcGl1bSBzZXNzaW9uICR7c2Vzc2lvbklkfSAoZGV2aWNlPSR7ZGV2aWNlSWR9KWApO1xuXG4gICAgY29uc3QgeyBhdHRhY2ggfSA9IGF3YWl0IGltcG9ydFdlYmRyaXZlcmlvKCk7XG4gICAgY29uc3QgYnJvd3NlciA9IGF3YWl0IGF0dGFjaCh7XG4gICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgcGxhdGZvcm1OYW1lOiAnQW5kcm9pZCdcbiAgICAgIH0sXG4gICAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgICAgbG9nTGV2ZWw6ICd3YXJuJyxcbiAgICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICAgIHBvcnQsXG4gICAgICBzZXNzaW9uSWQsXG4gICAgICB0cmFuc2Zvcm1SZXF1ZXN0OiBzdHJpcEZvcmJpZGRlbkZldGNoSGVhZGVyc1xuICAgIH0pO1xuXG4gICAgdGhpcy5sb2coJ1JlYXR0YWNoZWQgdG8gQXBwaXVtIHNlc3Npb24uJyk7XG5cbiAgICByZXR1cm4gbmV3IEFwcGl1bVRyYW5zcG9ydCh7XG4gICAgICBhcHBJZCxcbiAgICAgIGJyb3dzZXIsXG4gICAgICBkZXZpY2VJZCxcbiAgICAgIGlzU2Vzc2lvbk93bmVyOiBmYWxzZSxcbiAgICAgIHBsYXRmb3JtOiAnYW5kcm9pZCcsXG4gICAgICAvLyBUaGUgc2Vzc2lvbiB0aGlzIHJlYXR0YWNoZXMgdG8gd2FzIGNyZWF0ZWQgd2l0aCB0aGUgc2FtZSByZXNvbHV0aW9uLCBzbyB0aGUgbnVtYmVyIHJlcG9ydGVkIG9uIGFcbiAgICAgIC8vIHNjcmlwdCB0aW1lb3V0IGlzIHRoZSBvbmUgdGhhdCBzZXNzaW9uIGlzIGFjdHVhbGx5IGVuZm9yY2luZy5cbiAgICAgIHNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcmVzb2x2ZVNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgIHNob3VsZFN3ZWVwTGVmdG92ZXJzOiB3aWxsU3dlZXBMZWZ0b3ZlcnMob3B0aW9ucyksXG4gICAgICAuLi4ob3B0aW9ucy5hcHBTdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG9wdGlvbnMuYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSksXG4gICAgICAuLi4ob3B0aW9ucy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG9wdGlvbnMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSksXG4gICAgICAuLi4ob3B0aW9ucy52YXVsdEJhc2VQYXRoICE9PSB1bmRlZmluZWQgJiYgeyB2YXVsdEJhc2VQYXRoOiBvcHRpb25zLnZhdWx0QmFzZVBhdGggfSksXG4gICAgICAuLi4ob3B0aW9ucy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzICE9PSB1bmRlZmluZWQgJiYgeyB3ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSlcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRXZWRnZWRNZXNzYWdlKHBhcmFtczogRXN0YWJsaXNoU2Vzc2lvblBhcmFtcywgcmVhc29uOiBXZWRnZWRBcHBpdW1TZXJ2ZXJSZXBvcnRSZWFzb24pOiBzdHJpbmcge1xuICAgIGNvbnN0IG1hcmtlciA9IHBhcmFtcy5hcHBpdW1TZXJ2ZXJNYXJrZXI7XG4gICAgcmV0dXJuIGJ1aWxkV2VkZ2VkQXBwaXVtU2VydmVyTWVzc2FnZSh7XG4gICAgICBhcHBpdW1PcmlnaW46IHBhcmFtcy51cmwub3JpZ2luLFxuICAgICAgZGV2aWNlSWQ6IHBhcmFtcy5kZXZpY2VJZCxcbiAgICAgIHJlYXNvbixcbiAgICAgIC4uLihtYXJrZXIgIT09IHVuZGVmaW5lZCAmJiB7XG4gICAgICAgIHNlcnZlckFnZUluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpIC0gbWFya2VyLnN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzLFxuICAgICAgICBzZXJ2ZXJQaWQ6IG1hcmtlci5waWRcbiAgICAgIH0pXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUHJlZmxpZ2h0IHByb2JlIGZvciBhbiBhbHJlYWR5LXJ1bm5pbmcgc2VydmVyLlxuICAgKlxuICAgKiBMaXZlbmVzcyBpcyBub3QgcmVhZGluZXNzOiByZXNvbHZpbmcgb24gKmFueSogcmVzcG9uc2UgYWRvcHRzIGEgc2VydmVyIHRoYXRcbiAgICogaXMgcmVmdXNpbmcgc2Vzc2lvbnMgKGEgbm9uLTJ4eCBgL3N0YXR1c2AsIG9yIG9uZSB0aGF0IHJlcG9ydHMgaXRzZWxmXG4gICAqIHNodXR0aW5nIGRvd24pIGV4YWN0bHkgbGlrZSBhIGhlYWx0aHkgb25lLiBSZWplY3RpbmcgaW5zdGVhZCBoYW5kcyB0aG9zZVxuICAgKiBjYXNlcyB0byB0aGUgYXV0by1zdGFydCBwYXRoLiBJdCBjYW5ub3QgY2F0Y2ggdGhlIHdlZGdlZCBzZXJ2ZXIgb2ZcbiAgICogYHdlZGdlZC1hcHBpdW0tc2VydmVyLnRzYCBcdTIwMTQgdGhhdCBvbmUgYW5zd2VycyBgcmVhZHk6IHRydWVgIFx1MjAxNCB3aGljaCBpcyB3aHlcbiAgICogdGhlIHdlZGdlIGlzIHJlY29nbml6ZWQgZnJvbSB0aGUgZmFpbGVkIHNlc3Npb24gaW5zdGVhZC5cbiAgICpcbiAgICogQHBhcmFtIHVybCAtIFRoZSBBcHBpdW0gc2VydmVyIFVSTC5cbiAgICovXG4gIHByaXZhdGUgY2hlY2tBcHBpdW1SZWFjaGFibGUodXJsOiBVUkwpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdHVzVXJsID0gbmV3IFVSTCgnL3N0YXR1cycsIHVybCk7XG4gICAgICAvKlxuICAgICAgICogYGFnZW50OiBmYWxzZWAgXHUyMDE0IG5ldmVyIGEgcG9vbGVkIHNvY2tldC4gVGhlIGdsb2JhbCBhZ2VudCBrZWVwcyBzb2NrZXRzXG4gICAgICAgKiBhbGl2ZSBwZXIgaG9zdDpwb3J0LCBzbyBhIHByb2JlIGFmdGVyIGEgc2VydmVyIG9uIHRoYXQgcG9ydCB3YXMgcmVwbGFjZWRcbiAgICAgICAqIGNhbiByZXVzZSB0aGUgZGVhZCBzb2NrZXQgYW5kIGZhaWwgd2l0aCBgRUNPTk5SRVNFVGAgcmVnYXJkbGVzcyBvZiB3aGF0XG4gICAgICAgKiBpcyBsaXN0ZW5pbmcgbm93LiBUaGF0IHdvdWxkIG1ha2UgYHdhaXRGb3JBcHBpdW1TdG9wcGVkYCBjYWxsIGEgbGl2ZVxuICAgICAgICogc2VydmVyIGRlYWQsIGFuZCBpdCBpcyBleGFjdGx5IHRoZSBzZXF1ZW5jZSB0aGUgd2VkZ2VkLXNlcnZlciByZXN0YXJ0XG4gICAgICAgKiBwZXJmb3Jtcy4gQSBmcmVzaCBzb2NrZXQgcGVyIHByb2JlIGNvc3RzIG5vdGhpbmcgYXQgdGhpcyBmcmVxdWVuY3kuXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBodHRwLmdldChzdGF0dXNVcmwsIHsgYWdlbnQ6IGZhbHNlLCB0aW1lb3V0OiBBUFBJVU1fUFJFRkxJR0hUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sIChyZXNwb25zZSkgPT4ge1xuICAgICAgICBjb25zdCBzdGF0dXNDb2RlID0gcmVzcG9uc2Uuc3RhdHVzQ29kZSA/PyAwO1xuICAgICAgICBpZiAoc3RhdHVzQ29kZSA8IEhUVFBfT0sgfHwgc3RhdHVzQ29kZSA+PSBIVFRQX01VTFRJUExFX0NIT0lDRVMpIHtcbiAgICAgICAgICByZXNwb25zZS5yZXN1bWUoKTtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn0gYW5zd2VyZWQgL3N0YXR1cyB3aXRoIEhUVFAgJHtTdHJpbmcoc3RhdHVzQ29kZSl9OyBpdCBpcyBub3QgYWNjZXB0aW5nIHNlc3Npb25zLmApKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5zZXRFbmNvZGluZygndXRmLTgnKTtcbiAgICAgICAgbGV0IGJvZHkgPSAnJztcbiAgICAgICAgcmVzcG9uc2Uub24oJ2RhdGEnLCAoY2h1bms6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGJvZHkgKz0gY2h1bms7XG4gICAgICAgIH0pO1xuICAgICAgICByZXNwb25zZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGlmIChjaGVja0lzQXBwaXVtU3RhdHVzUmVhZHkoYm9keSkpIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn0gcmVwb3J0cyBpdCBpcyBub3QgcmVhZHkgdG8gYWNjZXB0IG5ldyBjb25uZWN0aW9ucy5gKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICByZXF1ZXN0Lm9uKCd0aW1lb3V0JywgKCkgPT4ge1xuICAgICAgICByZXF1ZXN0LmRlc3Ryb3koKTtcbiAgICAgICAgcmVqZWN0KFxuICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn0gZGlkIG5vdCByZXNwb25kIHdpdGhpbiAke1N0cmluZyhBUFBJVU1fUFJFRkxJR0hUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcy4gSXMgdGhlIEFwcGl1bSBzZXJ2ZXIgcnVubmluZz9gXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXF1ZXN0Lm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgICByZWplY3QoXG4gICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgYENhbm5vdCByZWFjaCBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn06ICR7ZXJyb3IubWVzc2FnZX0uIElzIHRoZSBBcHBpdW0gc2VydmVyIHJ1bm5pbmc/YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIG91dCB0aGUgQXBwaXVtIHBvcnQgYW5kIHJlcG9ydHMgd2hldGhlciBpdCB3ZW50IHF1aWV0LCByYXRoZXIgdGhhblxuICAgKiB0aHJvd2luZyBhcyB7QGxpbmsgd2FpdEZvckFwcGl1bVN0b3BwZWR9IGRvZXMuXG4gICAqXG4gICAqIEBwYXJhbSB1cmwgLSBUaGUgQXBwaXVtIHNlcnZlciBVUkwuXG4gICAqIEBwYXJhbSB0aW1lb3V0SW5NaWxsaXNlY29uZHMgLSBIb3cgbG9uZyB0byB3YWl0LlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiBub3RoaW5nIGFuc3dlcnMgb24gdGhlIHBvcnQgYW55IG1vcmUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNoZWNrSXNBcHBpdW1TdG9wcGVkKHVybDogVVJMLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JBcHBpdW1TdG9wcGVkKHVybCwgdGltZW91dEluTWlsbGlzZWNvbmRzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgd2hldGhlciBhZGIgc3RpbGwgbGlzdHMgdGhlIGRldmljZSAqKmluIGFueSBzdGF0ZSoqLCB3aXRob3V0IGxldHRpbmdcbiAgICogYW4gYWRiIHRoYXQgaXRzZWxmIGZhaWxzIGNvdW50IGFzIGV2aWRlbmNlLlxuICAgKlxuICAgKiBBbnkgc3RhdGUsIG5vdCBqdXN0IGBkZXZpY2VgOiBhIGR5aW5nIGVtdWxhdG9yIGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlIGl0IGlzXG4gICAqIHN0aWxsIHRoZSB0aGluZyB0aGF0IGlzIHdyb25nICh0aGUgZGlzdGluY3Rpb24gYGFkYi1kZXZpY2UtbGlzdC50c2AgZHJhd3NcbiAgICogZm9yIHRlYXJkb3duLCBhbmQgdGhlIHJlYXNvbmluZyBjYXJyaWVzIG92ZXIpLiBSZWFkaW5nIGBvZmZsaW5lYCBhcyBnb25lXG4gICAqIGhlcmUgd291bGQgcmVwb3J0IGBkZXZpY2UtZ29uZWAgZm9yIHdoYXQgaXMgcmVhbGx5IGEgd2VkZ2UsIHNlbmRpbmcgdGhlXG4gICAqIHJlYWRlciB0byBsb29rIGZvciBhIHZhbmlzaGVkIGVtdWxhdG9yIHRoYXQgaXMgaW4gZmFjdCBzdGlsbCBzaXR0aW5nIHRoZXJlLlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgZGV2aWNlIHRvIGxvb2sgZm9yLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiBpdCBpcyBsaXN0ZWQ7IGBmYWxzZWAgd2hlbiBpdCBpcyBub3QsIG9yIGFkYiBjb3VsZCBub3QgYmUgcnVuLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0lzRGV2aWNlTGlzdGVkUXVpZXRseShkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBjaGVja0lzRGV2aWNlTGlzdGVkKHsgZGV2aWNlSWQsIGRldmljZXNPdXRwdXQ6IGF3YWl0IHRoaXMuZW11bGF0b3JzLmdldERldmljZXNPdXRwdXQoKSB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgdGhpcy5sb2coYENvdWxkIG5vdCByZS1jaGVjayB0aGUgZGV2aWNlIGxpc3Rpbmc6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY29ubmVjdFNlc3Npb24ocGFyYW1zOiBFc3RhYmxpc2hTZXNzaW9uUGFyYW1zKTogUHJvbWlzZTxBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIHJlbW90ZT4+PiB7XG4gICAgY29uc3QgeyByZW1vdGUgfSA9IGF3YWl0IGltcG9ydFdlYmRyaXZlcmlvKCk7XG4gICAgcmV0dXJuIHJlbW90ZSh7XG4gICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgJ2FwcGl1bTphcHBBY3Rpdml0eSc6IEFQUF9BQ1RJVklUWSxcbiAgICAgICAgJ2FwcGl1bTphcHBQYWNrYWdlJzogcGFyYW1zLmFwcElkLFxuICAgICAgICAnYXBwaXVtOmF1dG9HcmFudFBlcm1pc3Npb25zJzogdHJ1ZSxcbiAgICAgICAgJ2FwcGl1bTphdXRvbWF0aW9uTmFtZSc6ICdVaUF1dG9tYXRvcjInLFxuICAgICAgICAnYXBwaXVtOm5ld0NvbW1hbmRUaW1lb3V0JzogTkVXX0NPTU1BTkRfVElNRU9VVF9JTl9TRUNPTkRTLFxuICAgICAgICAnYXBwaXVtOm5vUmVzZXQnOiB0cnVlLFxuICAgICAgICAnYXBwaXVtOnVkaWQnOiBwYXJhbXMuZGV2aWNlSWQsXG4gICAgICAgICdhcHBpdW06dWlhdXRvbWF0b3IyU2VydmVySW5zdGFsbFRpbWVvdXQnOiBTRVJWRVJfSU5TVEFMTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgJ2FwcGl1bTp1aWF1dG9tYXRvcjJTZXJ2ZXJMYXVuY2hUaW1lb3V0JzogU0VSVkVSX0xBVU5DSF9USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgJ3BsYXRmb3JtTmFtZSc6ICdBbmRyb2lkJyxcbiAgICAgICAgLypcbiAgICAgICAgICogYHNjcmlwdGAgaXMgZGVjbGFyZWQgc28gdGhlIHBlci1jbG9zdXJlIGNhcCBpcyBhIG51bWJlciB0aGlzIGhhcm5lc3Mgb3ducyBhbmQgc3RhdGVzLCBidXQgdGhlXG4gICAgICAgICAqIERlY2xhcmF0aW9uIGlzIE5PVCB3aGF0IGVuZm9yY2VzIGl0OiBVaUF1dG9tYXRvcjIgd2FzIG1lYXN1cmVkIGFjY2VwdGluZyB0aGlzLCByZXBvcnRpbmcgaXRcbiAgICAgICAgICogQmFjayBhcyAzMDAwMCBmcm9tIHRoZSBXZWJWaWV3IGNvbnRleHQsIGFuZCBuZXZlciBhY3Rpbmcgb24gaXQgXHUyMDE0IG92ZXItY2FwIGNsb3N1cmVzIHJhbiBwYXN0IGFcbiAgICAgICAgICogNjBzIGNlaWxpbmcgd2l0aG91dCBvbmUgYHNjcmlwdCB0aW1lb3V0YC4gYEFwcGl1bVRyYW5zcG9ydC5ldmFsdWF0ZWAgZW5mb3JjZXMgdGhlIHNhbWUgbnVtYmVyXG4gICAgICAgICAqIE5vZGUtc2lkZSwgYW5kIHRoaXMgc3RheXMgYmVjYXVzZSBpdCBpcyBmcmVlLCBpdCBpcyB0aGUgaG9uZXN0IGRlY2xhcmF0aW9uIG9mIHRoZSBpbnRlbmRlZFxuICAgICAgICAgKiBCdWRnZXQsIGFuZCBpdCB3b3VsZCBzdGFydCB3b3JraW5nIG9uIGl0cyBvd24gaWYgYSBmdXR1cmUgZHJpdmVyIGhvbm91cmVkIGl0LiBUaGUgb3RoZXIgdHdvIGFyZVxuICAgICAgICAgKiBSZXN0YXRlZCBhdCB0aGVpciBXM0MgZGVmYXVsdHMgb25seSBiZWNhdXNlIHRoZSBjYXBhYmlsaXR5IGlzIGFsbC1vci1ub3RoaW5nIFx1MjAxNCBXZWJEcml2ZXJJTydzXG4gICAgICAgICAqIGBUaW1lb3V0c2AgdHlwZSBoYXMgbm8gcGFydGlhbCBmb3JtIFx1MjAxNCBzbyB0aGV5IGNoYW5nZSBub3RoaW5nLlxuICAgICAgICAgKi9cbiAgICAgICAgJ3RpbWVvdXRzJzoge1xuICAgICAgICAgIGltcGxpY2l0OiBJTVBMSUNJVF9XQUlUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTLFxuICAgICAgICAgIHBhZ2VMb2FkOiBQQUdFX0xPQURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICAgICAgc2NyaXB0OiBwYXJhbXMuc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjb25uZWN0aW9uUmV0cnlDb3VudDogQVBQSVVNX0NPTk5FQ1RJT05fUkVUUllfQ09VTlQsXG4gICAgICBjb25uZWN0aW9uUmV0cnlUaW1lb3V0OiBwYXJhbXMuc2Vzc2lvbkNvbm5lY3Rpb25SZXRyeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgICAgIGhvc3RuYW1lOiBwYXJhbXMudXJsLmhvc3RuYW1lLFxuICAgICAgbG9nTGV2ZWw6ICd3YXJuJyxcbiAgICAgIHBhdGg6IHBhcmFtcy51cmwucGF0aG5hbWUsXG4gICAgICBwb3J0OiBwYXJhbXMucG9ydCxcbiAgICAgIHRyYW5zZm9ybVJlcXVlc3Q6IHN0cmlwRm9yYmlkZGVuRmV0Y2hIZWFkZXJzXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNyZWF0ZU5ld1Nlc3Npb24ob3B0aW9uczogT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgICB0aGlzLmxvZyhgQ3JlYXRpbmcgQXBwaXVtVHJhbnNwb3J0ICh1cmw9JHtvcHRpb25zLmFwcGl1bVVybH0sIGF2ZD0ke29wdGlvbnMuYXZkTmFtZX0pYCk7XG5cbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKG9wdGlvbnMuYXBwaXVtVXJsKTtcblxuICAgIGNvbnN0IHBvcnQgPSBOdW1iZXIodXJsLnBvcnQpO1xuICAgIGlmIChOdW1iZXIuaXNOYU4ocG9ydCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgcG9ydCBpbiBhcHBpdW1Vcmw6ICR7dXJsLnBvcnR9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgYXBwSWQgPSBvcHRpb25zLmFwcElkID8/IEFQUF9QQUNLQUdFO1xuXG4gICAgbGV0IGFjdHVhbERldmljZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgbGV0IGFwcGl1bVByb2Nlc3M6IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZW11bGF0b3JQcm9jZXNzOiBDaGlsZFByb2Nlc3MgfCB1bmRlZmluZWQ7XG4gICAgbGV0IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXSA9IFtdO1xuXG4gICAgbGV0IHJlc3VsdDogU3RhcnRBcHBpdW1BbmRFbXVsYXRvclJlc3VsdCB8IHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICAvKlxuICAgICAgICogUHJvdmlzaW9uLCB0aGVuIGNoZWNrIHRoZSBkZXZpY2UgaXMgc3RpbGwgYW5zd2VyaW5nIFx1MjAxNCBhbmQgd2hlbiBpdCBpcyBub3RcbiAgICAgICAqIGFuZCB0aGUgZW11bGF0b3IgaXMgb3VycywgYm9vdCBhIGZyZXNoIG9uZSBpbnN0ZWFkIG9mIGNhcnJ5aW5nIG9uLlxuICAgICAgICpcbiAgICAgICAqIEEgd2VkZ2UgaXMgTk9UIGRldGVybWluaXN0aWMsIHdoaWNoIGlzIHdoYXQganVzdGlmaWVzIHRoZSByZXRyeS4gSW4gdGhlXG4gICAgICAgKiBydW4gdGhhdCBwcm92ZWQgaXQgKDIwMjYtMDktMDUpIHRoZSBmaXJzdCBlbXVsYXRvciB3ZW50IHF1aWV0IDEyOXMgaW4gYW5kXG4gICAgICAgKiB0aGUgc2Vjb25kLCBib290ZWQgMTFzIGxhdGVyIGZyb20gdGhlIHNhbWUgQVZEIHdpdGggdGhlIHNhbWUgYXJndW1lbnRzLFxuICAgICAgICogZXN0YWJsaXNoZWQgYSBzZXNzaW9uIGFuZCBkcm92ZSB0aGUgV2ViVmlldyB0byBjb21wbGV0aW9uLiBBbiBlYXJsaWVyXG4gICAgICAgKiBkcmFmdCBvZiB0aGlzIHdvcmsgYXJndWVkIHRoZSBvcHBvc2l0ZSBmcm9tIHRoZSBoYW5kLWJvb3QgZGF0YSBcdTIwMTQgdGhhdCBhXG4gICAgICAgKiByZS1ib290IGJ1eXMgdGhlIHNhbWUgZmFpbHVyZSA5MHMgbGF0ZXIgXHUyMDE0IGFuZCB0aGF0IHdhcyBzaW1wbHkgd3Jvbmc6XG4gICAgICAgKiBldmVyeSBoYW5kLWJvb3Qgd2FzIGEgZmlyc3QgYm9vdCwgc28gdGhlIGRhdGEgc2FpZCBub3RoaW5nIGFib3V0IHNlY29uZFxuICAgICAgICogb25lcy5cbiAgICAgICAqL1xuICAgICAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gRU1VTEFUT1JfQk9PVF9BVFRFTVBUX0NPVU5UOyBhdHRlbXB0KyspIHtcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgdGhpcy5zdGFydEFwcGl1bUFuZEVtdWxhdG9yKHtcbiAgICAgICAgICBhcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcmVzb2x2ZUFwcGl1bVN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzKG9wdGlvbnMpLFxuICAgICAgICAgIGFwcGl1bVVybDogdXJsLFxuICAgICAgICAgIGF2ZE5hbWU6IG9wdGlvbnMuYXZkTmFtZSxcbiAgICAgICAgICBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlRGV2aWNlSWRsZVRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgICBpc0FwcGl1bUNvbnNvbGVWaXNpYmxlOiBvcHRpb25zLmlzQXBwaXVtQ29uc29sZVZpc2libGUsXG4gICAgICAgICAgaXNFbXVsYXRvclZpc2libGU6IG9wdGlvbnMuaXNFbXVsYXRvclZpc2libGUsXG4gICAgICAgICAgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlTmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzKG9wdGlvbnMpLFxuICAgICAgICAgIHBvcnQsXG4gICAgICAgICAgc2hvdWxkQXV0b0luc3RhbGxBcHBpdW1EZXBlbmRlbmNpZXM6IHdpbGxBdXRvSW5zdGFsbEFwcGl1bURlcGVuZGVuY2llcyhvcHRpb25zKSxcbiAgICAgICAgICBzaG91bGRBdXRvU3RhcnRBcHBpdW06IG9wdGlvbnMuc2hvdWxkQXV0b1N0YXJ0QXBwaXVtLFxuICAgICAgICAgIHNob3VsZFJldXNlRW11bGF0b3JTbmFwc2hvdDogb3B0aW9ucy5zaG91bGRSZXVzZUVtdWxhdG9yU25hcHNob3RcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLypcbiAgICAgICAgICogT25seSBldmVyIFJFUExBQ0UgdGhpcyBoYW5kbGUsIG5ldmVyIGNsZWFyIGl0LiBUaGUgcmV0cnkgbGVhdmVzIHRoaXNcbiAgICAgICAgICogcnVuJ3MgQXBwaXVtIHNlcnZlciBydW5uaW5nIGFuZCBzd2FwcyBvbmx5IHRoZSBlbXVsYXRvciwgc28gdGhlIHNlY29uZFxuICAgICAgICAgKiBwYXNzIGZpbmRzIHRoYXQgc2VydmVyIHJlYWNoYWJsZSwgQURPUFRTIGl0LCBhbmQgcmV0dXJucyBubyBwcm9jZXNzXG4gICAgICAgICAqIGhhbmRsZS4gV3JpdGluZyB0aGF0IGB1bmRlZmluZWRgIG92ZXIgdGhlIGhhbmRsZSBmcm9tIHRoZSBmaXJzdCBwYXNzXG4gICAgICAgICAqIHdvdWxkIG9ycGhhbiB0aGUgdmVyeSBzZXJ2ZXIgdGhpcyBydW4gc3RhcnRlZCBcdTIwMTQgdGhlIGxlYWsgTDQ2IGV4aXN0cyB0b1xuICAgICAgICAgKiBwcmV2ZW50LCByZWludHJvZHVjZWQgYnkgdGhlIHJldHJ5LlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHJlc3VsdC5hcHBpdW1Qcm9jZXNzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBhcHBpdW1Qcm9jZXNzID0gcmVzdWx0LmFwcGl1bVByb2Nlc3M7XG4gICAgICAgIH1cbiAgICAgICAgZW11bGF0b3JQcm9jZXNzID0gcmVzdWx0LmVtdWxhdG9yUHJvY2VzcztcbiAgICAgICAgb3duZWRFbXVsYXRvclBpZHMgPSByZXN1bHQub3duZWRFbXVsYXRvclBpZHM7XG4gICAgICAgIGFjdHVhbERldmljZUlkID0gcmVzdWx0LmFjdHVhbERldmljZUlkO1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIEJlZm9yZSBgcmVtb3RlKClgIGxhdW5jaGVzIE9ic2lkaWFuIFx1MjAxNCB0aGUgbGFzdCBwb2ludCBhdCB3aGljaCBub3RoaW5nXG4gICAgICAgICAqIGhhcyB0byBlbnVtZXJhdGUgdGhlIGRldmljZSdzIHZhdWx0cyB5ZXQuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAod2lsbFN3ZWVwTGVmdG92ZXJzKG9wdGlvbnMpKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5zd2VlcERldmljZUxlZnRvdmVyVmF1bHRzKHtcbiAgICAgICAgICAgIGRldmljZUlkOiBhY3R1YWxEZXZpY2VJZCxcbiAgICAgICAgICAgIHZhdWx0QmFzZVBhdGg6IG9wdGlvbnMudmF1bHRCYXNlUGF0aCA/PyBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRIXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKlxuICAgICAgICAgKiBUaGUgbGFzdCBwb2ludCBhdCB3aGljaCBhIGRldmljZSB0aGF0IGhhcyBnb25lIHF1aWV0IGNhbiBzdGlsbCBiZVxuICAgICAgICAgKiByZXBvcnRlZCBhcyBpdHNlbGYuIFBhc3QgaGVyZSB0aGUgZmFpbHVyZSBiZWxvbmdzIHRvIEFwcGl1bSwgd2hpY2ggY2FuXG4gICAgICAgICAqIG9ubHkgc2F5IHRoZSBkZXZpY2UgaXMgXCJub3QgaW4gdGhlIGxpc3Qgb2YgY29ubmVjdGVkIGRldmljZXNcIiBcdTIwMTQgYW5cbiAgICAgICAgICogZXJyb3IgdGhhdCBuYW1lcyB0aGUgb25lIHRoaW5nIHRoYXQgaXMgbm90IHdyb25nLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZGlhZ25vc2lzID0gYXdhaXQgdGhpcy5kaWFnbm9zZURldmljZShhY3R1YWxEZXZpY2VJZCwgcmVzdWx0LmVtdWxhdG9yQ2FwdHVyZSk7XG4gICAgICAgIGlmIChkaWFnbm9zaXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgLypcbiAgICAgICAgICogT25seSBhbiBlbXVsYXRvciB0aGlzIHJ1biBvd25zIG1heSBiZSByZXBsYWNlZCBcdTIwMTQgb25lIGl0IHN0YXJ0ZWQsIG9yIGFcbiAgICAgICAgICogbGVmdG92ZXIgb2YgdGhpcyBoYXJuZXNzIGl0IHRvb2sgb3Zlci4gQSBkZXZpY2UgdGhhdCB3YXMgbWVyZWx5XG4gICAgICAgICAqIGFkb3B0ZWQgKGBvd25lZEVtdWxhdG9yUGlkc2AgZW1wdHkpIGlzIHNvbWVib2R5IGVsc2UncyB0byByZXN0YXJ0IFx1MjAxNFxuICAgICAgICAgKiB0aGUgc2FtZSBvd25lcnNoaXAgbGluZSB0ZWFyZG93biBkcmF3cyBpbiBuZXZlciBzd2VlcGluZyBgcWVtdSpgLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3Qgb3duZWRFbXVsYXRvclByb2Nlc3MgPSBlbXVsYXRvclByb2Nlc3M7XG4gICAgICAgIGNvbnN0IGNhblJldHJ5ID0gYXR0ZW1wdCA8IEVNVUxBVE9SX0JPT1RfQVRURU1QVF9DT1VOVCAmJiBvd25lZEVtdWxhdG9yUGlkcy5sZW5ndGggPiAwO1xuICAgICAgICBpZiAoIWNhblJldHJ5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRpYWdub3Npcyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvZyhgJHtkaWFnbm9zaXN9XFxuXFxuQm9vdGluZyBhIGZyZXNoIGVtdWxhdG9yIGFuZCB0cnlpbmcgb25jZSBtb3JlIChhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQgKyAxKX0gb2YgJHtTdHJpbmcoRU1VTEFUT1JfQk9PVF9BVFRFTVBUX0NPVU5UKX0pLmApO1xuICAgICAgICAvKlxuICAgICAgICAgKiBEaXNvd24gQkVGT1JFIHN0b3BwaW5nLCBub3QgYWZ0ZXI6IHRoaXMgcnVuIGhhbmRzIHRoZSBlbXVsYXRvciBvdmVyIHRvXG4gICAgICAgICAqIGBzdG9wRW11bGF0b3JgIGFuZCBtdXN0IG5vdCBzdGlsbCBiZSBob2xkaW5nIGl0IGlmIHRoYXQgdGhyb3dzLCBvciB0aGVcbiAgICAgICAgICogb3V0ZXIgY2F0Y2gncyB0ZWFyZG93biB3b3VsZCBnbyBhZnRlciB0aGUgc2FtZSBwcm9jZXNzZXMgYSBzZWNvbmRcbiAgICAgICAgICogdGltZS5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGRvb21lZERldmljZUlkID0gYWN0dWFsRGV2aWNlSWQ7XG4gICAgICAgIGNvbnN0IGRvb21lZFBpZHMgPSBvd25lZEVtdWxhdG9yUGlkcztcbiAgICAgICAgZW11bGF0b3JQcm9jZXNzID0gdW5kZWZpbmVkO1xuICAgICAgICBvd25lZEVtdWxhdG9yUGlkcyA9IFtdO1xuICAgICAgICBhY3R1YWxEZXZpY2VJZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgYXdhaXQgdGhpcy5lbXVsYXRvcnMuc3RvcEVtdWxhdG9yKHtcbiAgICAgICAgICBhdmROYW1lOiBvcHRpb25zLmF2ZE5hbWUsXG4gICAgICAgICAgZGV2aWNlSWQ6IGRvb21lZERldmljZUlkLFxuICAgICAgICAgIGVtdWxhdG9yUHJvY2Vzczogb3duZWRFbXVsYXRvclByb2Nlc3MsXG4gICAgICAgICAgb3duZWRFbXVsYXRvclBpZHM6IGRvb21lZFBpZHNcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCB8fCBhY3R1YWxEZXZpY2VJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IHByb3Zpc2lvbiBhbiBBbmRyb2lkIGRldmljZSBmb3IgQVZEIFwiJHtvcHRpb25zLmF2ZE5hbWV9XCIuYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNlc3Npb25SZXN1bHQgPSBhd2FpdCB0aGlzLmVzdGFibGlzaFNlc3Npb25PckRpYWdub3NlRGV2aWNlKHJlc3VsdC5lbXVsYXRvckNhcHR1cmUsIHtcbiAgICAgICAgYXBwSWQsXG4gICAgICAgIGFwcGl1bVNlcnZlck1hcmtlcjogcmVzdWx0LmFwcGl1bVNlcnZlck1hcmtlcixcbiAgICAgICAgYXBwaXVtU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IHJlc29sdmVBcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgZGV2aWNlSWQ6IGFjdHVhbERldmljZUlkLFxuICAgICAgICBpc0Fkb3B0ZWRTZXJ2ZXI6IHJlc3VsdC5pc0Fkb3B0ZWRBcHBpdW1TZXJ2ZXIsXG4gICAgICAgIGlzQXBwaXVtQ29uc29sZVZpc2libGU6IG9wdGlvbnMuaXNBcHBpdW1Db25zb2xlVmlzaWJsZSxcbiAgICAgICAgcG9ydCxcbiAgICAgICAgc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlU2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzKG9wdGlvbnMpLFxuICAgICAgICBzZXNzaW9uQ29ubmVjdGlvblJldHJ5VGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlU2Vzc2lvbkNvbm5lY3Rpb25SZXRyeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgc2hvdWxkQXV0b1N0YXJ0QXBwaXVtOiBvcHRpb25zLnNob3VsZEF1dG9TdGFydEFwcGl1bSxcbiAgICAgICAgdXJsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgYnJvd3NlciA9IHNlc3Npb25SZXN1bHQuYnJvd3NlcjtcbiAgICAgIC8vIEEgd2VkZ2VkIGFkb3B0ZWQgc2VydmVyIGlzIHJlcGxhY2VkIGJ5IG9uZSB0aGlzIHJ1biBvd25zLCBzbyBpdCBtdXN0IGJlIHRvcm4gZG93biBsaWtlIGFueSBvdGhlciBhdXRvLXN0YXJ0ZWQgc2VydmVyLlxuICAgICAgaWYgKHNlc3Npb25SZXN1bHQuYXBwaXVtUHJvY2VzcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGFwcGl1bVByb2Nlc3MgPSBzZXNzaW9uUmVzdWx0LmFwcGl1bVByb2Nlc3M7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubG9nKCdBcHBpdW0gc2Vzc2lvbiBlc3RhYmxpc2hlZC4nKTtcbiAgICAgIC8qXG4gICAgICAgKiBUaGUgZW11bGF0b3IgaGFzIG5vdGhpbmcgbGVmdCB0byBleHBsYWluLCBzbyBmcmVlemUgaXRzIHRhaWwgaGVyZSByYXRoZXJcbiAgICAgICAqIHRoYW4gYXQgYm9vdC4gRXZlcnl0aGluZyB1cCB0byB0aGlzIGxpbmUgXHUyMDE0IGluY2x1ZGluZyB0aGUgd2luZG93IGluIHdoaWNoXG4gICAgICAgKiBhIHdlZGdlIHN1cmZhY2VzIFx1MjAxNCBpcyBub3cgaW5zaWRlIHRoZSBjYXB0dXJlZCBvdXRwdXQuXG4gICAgICAgKi9cbiAgICAgIHJlc3VsdC5lbXVsYXRvckNhcHR1cmU/LnN0b3AoKTtcbiAgICAgIGNvbnN0IGFwcGl1bVRyYW5zcG9ydCA9IG5ldyBBcHBpdW1UcmFuc3BvcnQoe1xuICAgICAgICBhcHBJZCxcbiAgICAgICAgYnJvd3NlcixcbiAgICAgICAgZGV2aWNlSWQ6IGFjdHVhbERldmljZUlkLFxuICAgICAgICBwbGF0Zm9ybTogJ2FuZHJvaWQnLFxuICAgICAgICAvLyBUaGUgc2FtZSBudW1iZXIgdGhlIHNlc3Npb24gd2FzIGNyZWF0ZWQgd2l0aCBhYm92ZSwgc28gYSBzY3JpcHQgdGltZW91dCByZXBvcnRzIHRoZSBjYXAgdGhhdCBraWxsZWQgaXQuXG4gICAgICAgIHNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcmVzb2x2ZVNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM6IHdpbGxTd2VlcExlZnRvdmVycyhvcHRpb25zKSxcbiAgICAgICAgLi4uKG9wdGlvbnMuYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMgIT09IHVuZGVmaW5lZCAmJiB7IGFwcFN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zLmFwcFN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzIH0pLFxuICAgICAgICAuLi4ob3B0aW9ucy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG9wdGlvbnMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSksXG4gICAgICAgIC4uLihvcHRpb25zLnZhdWx0QmFzZVBhdGggIT09IHVuZGVmaW5lZCAmJiB7IHZhdWx0QmFzZVBhdGg6IG9wdGlvbnMudmF1bHRCYXNlUGF0aCB9KSxcbiAgICAgICAgLi4uKG9wdGlvbnMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kczogb3B0aW9ucy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzIH0pXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgb3JpZ2luYWxEaXNwb3NlID0gYXBwaXVtVHJhbnNwb3J0LmRpc3Bvc2UuYmluZChhcHBpdW1UcmFuc3BvcnQpO1xuICAgICAgY29uc3QgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydCA9IGFwcGl1bVRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydC5kaXNwb3NlID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IG9yaWdpbmFsRGlzcG9zZSgpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuc3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzVmVyaWZpZWQoYnVpbGRTdG9wUGFyYW1zKCkpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBDaGFpbiByYXRoZXIgdGhhbiByZXBsYWNlOiB0aGUgdHJhbnNwb3J0J3Mgb3duIHN5bmMgdGVhcmRvd24gZHJvcHMgdGhlIHRydXN0ZWQtaW5wdXQgY2hhbm5lbCdzXG4gICAgICAvLyBhZGIgcG9ydCBmb3J3YXJkLCB3aGljaCB3b3VsZCBvdGhlcndpc2UgYmUgc3RyYW5kZWQgb24gdGhlIGRldmljZSBieSBhbiBhYnJ1cHQgZXhpdC5cbiAgICAgIGNvbnN0IG9yaWdpbmFsRGlzcG9zZVN5bmMgPSBhcHBpdW1UcmFuc3BvcnQuZGlzcG9zZVN5bmMuYmluZChhcHBpdW1UcmFuc3BvcnQpO1xuICAgICAgdHJhbnNwb3J0LmRpc3Bvc2VTeW5jID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIG9yaWdpbmFsRGlzcG9zZVN5bmMoKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0aGlzLnN0b3BBdXRvU3RhcnRlZFByb2Nlc3Nlc0Jlc3RFZmZvcnQoYnVpbGRTdG9wUGFyYW1zKCkpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3BBdXRvU3RhcnRlZFByb2Nlc3Nlc1ZlcmlmaWVkKGJ1aWxkU3RvcFBhcmFtcygpKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJ1aWxkU3RvcFBhcmFtcygpOiBTdG9wQXV0b1N0YXJ0ZWRQcm9jZXNzZXNQYXJhbXMge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXBwaXVtUHJvY2VzcyxcbiAgICAgICAgYXZkTmFtZTogb3B0aW9ucy5hdmROYW1lLFxuICAgICAgICBkZXZpY2VJZDogYWN0dWFsRGV2aWNlSWQsXG4gICAgICAgIGVtdWxhdG9yUHJvY2VzcyxcbiAgICAgICAgb3duZWRFbXVsYXRvclBpZHMsXG4gICAgICAgIHBvcnQsXG4gICAgICAgIHVybFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVzY3JpYmVzIGFuIGFkb3B0ZWQgc2VydmVyJ3MgcHJvdmVuYW5jZSBmb3IgdGhlIHByZWZsaWdodCBsb2csIHNvIGEgc3RhbGVcbiAgICogbGVmdG92ZXIgaXMgdmlzaWJsZSBpbiB0aGUgdHJhbnNjcmlwdCBvZiBhIHJ1biB0aGF0IGdvZXMgb24gdG8gc3VjY2VlZCBcdTIwMTQgbm90XG4gICAqIG9ubHkgaW4gdGhlIGVycm9yIG9mIG9uZSB0aGF0IGZhaWxzLlxuICAgKlxuICAgKiBAcGFyYW0gbWFya2VyIC0gVGhlIG1hcmtlciByZWFkIGZvciB0aGUgcG9ydCwgaWYgYW55LlxuICAgKiBAcmV0dXJucyBBIHNob3J0IHByb3ZlbmFuY2UgZGVzY3JpcHRpb24uXG4gICAqL1xuICBwcml2YXRlIGRlc2NyaWJlQWRvcHRlZFNlcnZlcihtYXJrZXI6IEFwcGl1bVNlcnZlck1hcmtlciB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gICAgaWYgKCFtYXJrZXIgfHwgIWNoZWNrSXNIYXJuZXNzT3duZWRBcHBpdW1TZXJ2ZXIobWFya2VyKSkge1xuICAgICAgcmV0dXJuICdub3Qgc3RhcnRlZCBieSB0aGlzIGhhcm5lc3MnO1xuICAgIH1cblxuICAgIGNvbnN0IGFnZUluU2Vjb25kcyA9IE1hdGgucm91bmQoKERhdGUubm93KCkgLSBtYXJrZXIuc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMpIC8gTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQpO1xuICAgIGNvbnN0IHVuc3RvcHBlZFN1ZmZpeCA9IG1hcmtlci5zdG9wQXR0ZW1wdGVkQXRJbk1pbGxpc2Vjb25kcyA9PT0gdW5kZWZpbmVkID8gJycgOiAnLCBhbmQgYW4gZWFybGllciBydW4gZmFpbGVkIHRvIHN0b3AgaXQnO1xuICAgIHJldHVybiBgc3RhcnRlZCBieSBhbiBlYXJsaWVyIHJ1biBvZiB0aGlzIGhhcm5lc3MsIHBpZCAke1N0cmluZyhtYXJrZXIucGlkKX0sIHVwIGZvciAke1N0cmluZyhhZ2VJblNlY29uZHMpfXMke3Vuc3RvcHBlZFN1ZmZpeH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2JlcyB0aGUgZGV2aWNlIGFuZCByZXR1cm5zIHRoZSBmYWlsdXJlIG1lc3NhZ2Ugd2hlbiBpdCBpcyBubyBsb25nZXJcbiAgICogdXNhYmxlLCBvciBgdW5kZWZpbmVkYCB3aGVuIGl0IGlzIGZpbmUuXG4gICAqXG4gICAqIFRoZSByZWFkaW5lc3MgZ2F0ZXMgdGhhdCBydW4gYmVmb3JlIHRoaXMgb25lIGFyZSBkZWxpYmVyYXRlbHkgYmVzdC1lZmZvcnQgXHUyMDE0XG4gICAqIHRoZXkgd2FybiBhbmQgcHJvY2VlZCBcdTIwMTQgc28gbm90aGluZyBhc2tlZCB3aGV0aGVyIHRoZSBkZXZpY2Ugd2FzIHN0aWxsIHRoZXJlXG4gICAqIGF0IHRoZSBtb21lbnQgaXQgbWF0dGVyZWQuIEEgZ3Vlc3QgdGhhdCB3ZW50IHF1aWV0IGluIHRoZSBtZWFudGltZSB3YXNcbiAgICogaGFuZGVkIHRvIEFwcGl1bSwgd2hpY2ggcmVwb3J0ZWQgYERldmljZSA8aWQ+IHdhcyBub3QgaW4gdGhlIGxpc3Qgb2ZcbiAgICogY29ubmVjdGVkIGRldmljZXNgOyBgYWRiIGRldmljZXNgIHRoZW4gbGlzdGVkIGl0LCBhbmQgdGhlIHRyYWlsIHdlbnQgY29sZC5cbiAgICpcbiAgICogVGhlIHNlY29uZCBwcm9iZSBpcyBvbmx5IHBhaWQgZm9yIHdoZW4gdGhlIGZpcnN0IG9uZSBmYWlscywgYW5kIHRoZSB2ZXJkaWN0XG4gICAqIGRpc3Rpbmd1aXNoZXMgYSBmcm96ZW4gZ3Vlc3QgZnJvbSBhbiB1bnJlYWNoYWJsZSBlbXVsYXRvciBcdTIwMTQgc2VlXG4gICAqIGBlbXVsYXRvci1saXZlbmVzcy50c2AgZm9yIHRoZSBtZWFzdXJlbWVudHMgYmVoaW5kIHRoYXQgc3BsaXQuXG4gICAqXG4gICAqIFJldHVybmluZyB0aGUgbWVzc2FnZSByYXRoZXIgdGhhbiB0aHJvd2luZyBpdCBpcyB3aGF0IGxldHMgYm90aCBjYWxsZXJzIHVzZVxuICAgKiB0aGUgc2FtZSBkaWFnbm9zaXM6IHRoZSBwcm92aXNpb25pbmcgbG9vcCBkZWNpZGVzIHdoZXRoZXIgdG8gYm9vdCBhIGZyZXNoXG4gICAqIGVtdWxhdG9yLCBhbmQgdGhlIHNlc3Npb24gcGF0aCBuZWVkcyBpdHMgb3duIGVycm9yIHRvIHN1cnZpdmUgYXMgdGhlXG4gICAqIGBjYXVzZWAuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgdG8gcHJvYmUuXG4gICAqIEBwYXJhbSBlbXVsYXRvckNhcHR1cmUgLSBUaGUgZW11bGF0b3IncyBvdXRwdXQsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBpdC5cbiAgICogQHJldHVybnMgVGhlIGRpYWdub3Npcywgb3IgYHVuZGVmaW5lZGAgd2hlbiB0aGUgZGV2aWNlIHN0aWxsIGFuc3dlcnMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRpYWdub3NlRGV2aWNlKGRldmljZUlkOiBzdHJpbmcsIGVtdWxhdG9yQ2FwdHVyZT86IEVtdWxhdG9yQ2FwdHVyZSk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3Qgc2hlbGxQcm9iZSA9IGF3YWl0IHRoaXMucHJvYmVEZXZpY2VTaGVsbChkZXZpY2VJZCk7XG4gICAgaWYgKHNoZWxsUHJvYmUgPT09ICdhbnN3ZXJlZCcpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBkaWQgbm90IGFuc3dlciBcXGBhZGIgLXMgJHtkZXZpY2VJZH0gc2hlbGxcXGA7IGNoZWNraW5nIHdoZXRoZXIgdGhlIGVtdWxhdG9yIGl0c2VsZiBpcyBzdGlsbCBhbGl2ZS4uLmApO1xuICAgIGNvbnN0IFtjb25zb2xlUHJvYmUsIGlzTGlzdGVkQnlBZGJdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgdGhpcy5wcm9iZUVtdWxhdG9yQ29uc29sZShkZXZpY2VJZCksXG4gICAgICB0aGlzLmNoZWNrSXNEZXZpY2VMaXN0ZWRRdWlldGx5KGRldmljZUlkKVxuICAgIF0pO1xuXG4gICAgY29uc3QgdmVyZGljdCA9IHJlc29sdmVFbXVsYXRvckxpdmVuZXNzVmVyZGljdCh7XG4gICAgICBjb25zb2xlUHJvYmUsXG4gICAgICBkZXZpY2VJZCxcbiAgICAgIGlzTGlzdGVkQnlBZGIsXG4gICAgICBzaGVsbFByb2JlXG4gICAgfSk7XG4gICAgdGhpcy5sb2coYERldmljZSBsaXZlbmVzczogJHtkZXZpY2VJZH0gc2hlbGw9JHtzaGVsbFByb2JlfSwgY29uc29sZT0ke2NvbnNvbGVQcm9iZX0gLT4gJHt2ZXJkaWN0fS5gKTtcblxuICAgIC8vIFVucmVhY2hhYmxlIGluIHByYWN0aWNlIFx1MjAxNCB0aGUgdmVyZGljdCBpcyBvbmx5IGAnYWxpdmUnYCB3aGVuIHRoZSBzaGVsbCBhbnN3ZXJlZCwgd2hpY2ggcmV0dXJuZWQgYWJvdmUgXHUyMDE0IGJ1dCBpdCBpcyB3aGF0IG5hcnJvd3MgdGhlIHR5cGUgZm9yIHRoZSBidWlsZGVyLlxuICAgIHJldHVybiB2ZXJkaWN0ID09PSAnYWxpdmUnXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiBidWlsZEVtdWxhdG9yTGl2ZW5lc3NNZXNzYWdlKHtcbiAgICAgICAgZGV2aWNlSWQsXG4gICAgICAgIGVtdWxhdG9yT3V0cHV0OiBlbXVsYXRvckNhcHR1cmU/LnJlYWQoKSA/PyAnJyxcbiAgICAgICAgcHJvYmVUaW1lb3V0SW5NaWxsaXNlY29uZHM6IERFVklDRV9MSVZFTkVTU19USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgdmVyZGljdFxuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGR1bXBDb25uZWN0aXZpdHkoZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGl2aXR5UHJvYmVSZXN1bHQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIGV4ZWNGaWxlKFxuICAgICAgICAnYWRiJyxcbiAgICAgICAgWyctcycsIGRldmljZUlkLCAnc2hlbGwnLCAnZHVtcHN5cycsICdjb25uZWN0aXZpdHknXSxcbiAgICAgICAgeyBtYXhCdWZmZXI6IEFEQl9EVU1QU1lTX01BWF9CVUZGRVJfSU5fQllURVMsIHRpbWVvdXQ6IEFEQl9EVU1QU1lTX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sXG4gICAgICAgIChlcnJvciwgc3Rkb3V0LCBzdGRlcnIpID0+IHtcbiAgICAgICAgICAvKlxuICAgICAgICAgICAqIEEgZmFpbHVyZSBjYXJyaWVzIGl0cyByZWFzb24sIE5PVCBhbiBlbXB0eSBzdHJpbmcuIFRoZSBvdGhlciBwcm9iZXNcbiAgICAgICAgICAgKiBjb2xsYXBzZSBhIGZhaWx1cmUgaW50byBlbXB0eSBvdXRwdXQgYmVjYXVzZSB0aGVyZSBcImVtcHR5XCIgYW5kXG4gICAgICAgICAgICogXCJmYWlsZWRcIiBib3RoIG1lYW4gbm90LWlkbGUsIGJ1dCBoZXJlIHRoZXkgbWVhbiBkaWZmZXJlbnQgdGhpbmdzIGFuZFxuICAgICAgICAgICAqIG9ubHkgb25lIG9mIHRoZW0gaXMgYWJvdXQgdGhlIG5ldHdvcms6IGEgcHJvYmUgdGhhdCBuZXZlciBhbnN3ZXJzXG4gICAgICAgICAgICogbXVzdCBub3QgYmUgcmVwb3J0ZWQgYXMgYSBndWVzdCB3aXRob3V0IGEgcm91dGUuXG4gICAgICAgICAgICovXG4gICAgICAgICAgaWYgKCFlcnJvcikge1xuICAgICAgICAgICAgcmVzb2x2ZSh7IG91dHB1dDogc3Rkb3V0IH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGRldGFpbCA9IChzdGRlcnIudHJpbSgpIHx8IGVycm9yLm1lc3NhZ2UudHJpbSgpKS5zcGxpdCgnXFxuJywgMSlbMF0gPz8gJyc7XG4gICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICBmYWlsdXJlUmVhc29uOiBlcnJvci5raWxsZWRcbiAgICAgICAgICAgICAgPyBgbm8gYW5zd2VyIHdpdGhpbiAke1N0cmluZyhBREJfRFVNUFNZU19USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXNgXG4gICAgICAgICAgICAgIDogZGV0YWlsIHx8ICdhZGIgZmFpbGVkIHdpdGggbm8gbWVzc2FnZSdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZSBBcHBpdW0gdG9vbGNoYWluIGlzIHByZXNlbnQgYmVmb3JlIHRoZSBzZXJ2ZXIgaXMgYXV0by1zdGFydGVkOlxuICAgKiBBcHBpdW0gaXRzZWxmLCB0aGVuIHRoZSBgdWlhdXRvbWF0b3IyYCBkcml2ZXIuIEVhY2ggaXMgY2hlY2tlZCBmaXJzdCBhbmRcbiAgICogaW5zdGFsbGVkIG9ubHkgd2hlbiBtaXNzaW5nLCBzbyBhIGZ1bGx5LXByb3Zpc2lvbmVkIG1hY2hpbmUgaW5jdXJzIGp1c3QgdHdvXG4gICAqIGZhc3QgdmVyc2lvbi9saXN0IHByb2Jlcy5cbiAgICpcbiAgICogT25seSBpbnZva2VkIHdoZW4gdGhlIGhhcm5lc3MgaXMgYWJvdXQgdG8gYXV0by1zdGFydCB0aGUgc2VydmVyIGFuZFxuICAgKiB7QGxpbmsgT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucy5zaG91bGRBdXRvSW5zdGFsbEFwcGl1bURlcGVuZGVuY2llc31cbiAgICogaXMgZW5hYmxlZC4gQ29tbWFuZHMgYXJlIHBhc3NlZCBhcyBzdHJpbmdzIHNvIGBleGVjYCBydW5zIHRoZW0gdGhyb3VnaCB0aGVcbiAgICogc2hlbGwsIHdoaWNoIHJlc29sdmVzIHRoZSBgbnBtYC9gbnB4YCBgLmNtZGAgc2hpbXMgb24gV2luZG93cyAodGhlIGFycmF5XG4gICAqIHBhdGggc3Bhd25zIHdpdGhvdXQgYSBzaGVsbCBhbmQgY2Fubm90KS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQXBwaXVtRGVwZW5kZW5jaWVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlQXBwaXVtSW5zdGFsbGVkKCk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVVaWF1dG9tYXRvcjJEcml2ZXJJbnN0YWxsZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQXBwaXVtSW5zdGFsbGVkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nKCdDaGVja2luZyB3aGV0aGVyIEFwcGl1bSBpcyBpbnN0YWxsZWQuLi4nKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBleGVjKCducHggLS1uby1pbnN0YWxsIGFwcGl1bSAtLXZlcnNpb24nLCB7XG4gICAgICBpc1F1aWV0OiB0cnVlLFxuICAgICAgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsXG4gICAgICBzaG91bGRJbmNsdWRlRGV0YWlsczogdHJ1ZVxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdC5leGl0Q29kZSA9PT0gMCkge1xuICAgICAgdGhpcy5sb2coYEFwcGl1bSBpcyBpbnN0YWxsZWQgKHZlcnNpb24gJHtyZXN1bHQuc3Rkb3V0LnRyaW0oKSB8fCAndW5rbm93bid9KS5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxvZygnQXBwaXVtIGlzIG5vdCBpbnN0YWxsZWQuIEluc3RhbGxpbmcgZ2xvYmFsbHkgdmlhIGBucG0gaW5zdGFsbCAtZyBhcHBpdW1gLi4uJyk7XG4gICAgYXdhaXQgZXhlYygnbnBtIGluc3RhbGwgLWcgYXBwaXVtJyk7XG5cbiAgICAvKlxuICAgICAqIFJlLXZlcmlmeTogYSBnbG9iYWwgaW5zdGFsbCBjYW4gbGFuZCB1bmRlciBhbiBucG0gcHJlZml4IHdob3NlIGJpbiBkaXIgaXNcbiAgICAgKiBub3Qgb24gdGhlIHNwYXduIFBBVEggKGUuZy4gYSBzY29vcC9udm0tbWFuYWdlZCBwcmVmaXgpLCBpbiB3aGljaCBjYXNlXG4gICAgICogYG5weCAtLW5vLWluc3RhbGwgYXBwaXVtYCBzdGlsbCBjYW5ub3QgcmVzb2x2ZSBpdC4gRmFpbCBmYXN0IHdpdGggYW5cbiAgICAgKiBhY3Rpb25hYmxlIG1lc3NhZ2UgcmF0aGVyIHRoYW4gcHJvY2VlZGluZyB0byBhdXRvLXN0YXJ0IGEgc2VydmVyIHRoYXQgY2FuXG4gICAgICogbmV2ZXIgY29tZSB1cCAod2hpY2ggd291bGQgb3RoZXJ3aXNlIHNwaW4gb3V0IHRoZSBmdWxsIHJlYWRpbmVzcyB0aW1lb3V0KS5cbiAgICAgKi9cbiAgICBjb25zdCB2ZXJpZnkgPSBhd2FpdCBleGVjKCducHggLS1uby1pbnN0YWxsIGFwcGl1bSAtLXZlcnNpb24nLCB7XG4gICAgICBpc1F1aWV0OiB0cnVlLFxuICAgICAgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsXG4gICAgICBzaG91bGRJbmNsdWRlRGV0YWlsczogdHJ1ZVxuICAgIH0pO1xuICAgIGlmICh2ZXJpZnkuZXhpdENvZGUgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0FwcGl1bSB3YXMgaW5zdGFsbGVkIHZpYSBgbnBtIGluc3RhbGwgLWcgYXBwaXVtYCBidXQgaXMgc3RpbGwgbm90IHJlc29sdmFibGUgdmlhIGBucHggLS1uby1pbnN0YWxsIGFwcGl1bWAuICdcbiAgICAgICAgICArICdUaGUgbnBtIGdsb2JhbCBiaW4gZGlyZWN0b3J5IChzZWUgYG5wbSBjb25maWcgZ2V0IHByZWZpeGApIGlzIGxpa2VseSBub3Qgb24gUEFUSC4gQWRkIGl0IHRvIFBBVEgsIG9yIHNldCAnXG4gICAgICAgICAgKyAnYHNob3VsZEF1dG9JbnN0YWxsQXBwaXVtRGVwZW5kZW5jaWVzOiBmYWxzZWAgYW5kIGluc3RhbGwvbWFuYWdlIEFwcGl1bSB5b3Vyc2VsZi4nXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmxvZyhgQXBwaXVtIGluc3RhbGxlZCAodmVyc2lvbiAke3ZlcmlmeS5zdGRvdXQudHJpbSgpIHx8ICd1bmtub3duJ30pLmApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZhaWxzIGZhc3Qgd2hlbiB0aGUgcmVxdWVzdGVkIEFWRCBkb2VzIG5vdCBleGlzdCwgYmVmb3JlIGFuIGVtdWxhdG9yIGlzXG4gICAqIHNwYXduZWQuXG4gICAqXG4gICAqIFdpdGhvdXQgdGhpcyBwcmVmbGlnaHQgYSBtaXNzaW5nIEFWRCBuYW1lIGlzIG9ubHkgZGlzY292ZXJlZCBhZnRlclxuICAgKiB7QGxpbmsgc3RhcnRFbXVsYXRvcn0gc3Bhd25zIGBlbXVsYXRvciAtYXZkIDxuYW1lPmAgYW5kIHRoZSBib290IG5ldmVyXG4gICAqIGNvbXBsZXRlcyBcdTIwMTQgYSBmdWxsIHtAbGluayBFTVVMQVRPUl9CT09UX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTfSBzcGluIGVuZGluZ1xuICAgKiBpbiBhIGdlbmVyaWMgXCJubyBuZXcgZGV2aWNlIGFwcGVhcmVkXCIuIEluc3RlYWQgdGhpcyBsaXN0cyB0aGUgY29uZmlndXJlZFxuICAgKiBBVkRzIHVwIGZyb250IGFuZCB0aHJvd3MgYW4gYWN0aW9uYWJsZSBlcnJvciBuYW1pbmcgdGhlIGF2YWlsYWJsZSBvbmVzLiBBVkRcbiAgICogY3JlYXRpb24gaXMgZGVsaWJlcmF0ZWx5IG5vdCBhdXRvbWF0ZWQgKGl0IHJlcXVpcmVzIGEgc3lzdGVtLWltYWdlIGRvd25sb2FkLFxuICAgKiBsaWNlbnNlIGFjY2VwdGFuY2UsIGFuZCBoYXJkd2FyZS9BUEktbGV2ZWwgY2hvaWNlcykuXG4gICAqXG4gICAqIEBwYXJhbSBhdmROYW1lIC0gVGhlIHJlcXVlc3RlZCBBVkQgbmFtZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQXZkRXhpc3RzKGF2ZE5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGVtdWxhdG9yQmluYXJ5ID0gcmVzb2x2ZUVtdWxhdG9yQmluYXJ5UGF0aCgpO1xuICAgIHRoaXMubG9nKGBWZXJpZnlpbmcgQVZEIFwiJHthdmROYW1lfVwiIGV4aXN0cyAoJHtlbXVsYXRvckJpbmFyeX0gLWxpc3QtYXZkcykuLi5gKTtcblxuICAgIGNvbnN0IFtlcnJvciwgc3Rkb3V0XSA9IGF3YWl0IG5ldyBQcm9taXNlPFtFcnJvciB8IG51bGwsIHN0cmluZ10+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShlbXVsYXRvckJpbmFyeSwgWyctbGlzdC1hdmRzJ10sIHsgdGltZW91dDogRU1VTEFUT1JfTElTVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LCAoZXhlY0Vycm9yLCBleGVjU3Rkb3V0KSA9PiB7XG4gICAgICAgIHJlc29sdmUoW2V4ZWNFcnJvciwgZXhlY1N0ZG91dF0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBsaXN0IEFWRHMgdmlhIFxcYCR7ZW11bGF0b3JCaW5hcnl9IC1saXN0LWF2ZHNcXGA6ICR7ZXJyb3IubWVzc2FnZX0uIGBcbiAgICAgICAgICArICdJcyB0aGUgQW5kcm9pZCBTREsgZW11bGF0b3IgaW5zdGFsbGVkIGFuZCBBTkRST0lEX0hPTUUvQU5EUk9JRF9TREtfUk9PVCBjb3JyZWN0PydcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFjaGVja0F2ZEV4aXN0cyh7IGF2ZExpc3RPdXRwdXQ6IHN0ZG91dCwgYXZkTmFtZSB9KSkge1xuICAgICAgY29uc3QgYXZhaWxhYmxlID0gbGlzdEF2YWlsYWJsZUF2ZHMoc3Rkb3V0KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEFuZHJvaWQgQVZEIFwiJHthdmROYW1lfVwiIG5vdCBmb3VuZC4gQXZhaWxhYmxlIEFWRHM6ICR7YXZhaWxhYmxlLmxlbmd0aCA+IDAgPyBhdmFpbGFibGUuam9pbignLCAnKSA6ICcobm9uZSknfS4gYFxuICAgICAgICAgICsgJ0NyZWF0ZSBpdCAoZS5nLiBpbiB0aGUgQW5kcm9pZCBTdHVkaW8gRGV2aWNlIE1hbmFnZXIsIG9yIHZpYSBgYXZkbWFuYWdlciBjcmVhdGUgYXZkYCksIG9yIHNldCBgYXZkTmFtZWAgdG8gYW4gZXhpc3RpbmcgQVZELidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYEFWRCBcIiR7YXZkTmFtZX1cIiBleGlzdHMuYCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVuc3VyZURldmljZUNvbm5lY3RlZChwYXJhbXM6IEVuc3VyZURldmljZUNvbm5lY3RlZFBhcmFtcyk6IFByb21pc2U8RW5zdXJlRGV2aWNlQ29ubmVjdGVkUmVzdWx0PiB7XG4gICAgY29uc3QgeyBhdmROYW1lLCBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzLCBpc0VtdWxhdG9yVmlzaWJsZSwgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgdGltZW91dHM6IERldmljZVJlYWRpbmVzc1RpbWVvdXRzID0geyBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzLCBuZXR3b3JrUmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgfTtcbiAgICAvKlxuICAgICAqIEJlZm9yZSB0aGUgZGV2aWNlIGxpc3RpbmcsIHNvIGEgbGVmdG92ZXIgc3RvcHBlZCBoZXJlIGlzIG5vdCBsaXN0ZWQuIE9ubHlcbiAgICAgKiBPVEhFUiBBVkRzOiBhIGxlZnRvdmVyIG9mIHRoaXMgb25lIGlzIHdvcnRoIGFkb3B0aW5nIChhbmQgb3duaW5nKSBiZWxvdy5cbiAgICAgKiBUaGlzIGlzIHRoZSBzZXF1ZW5jZSB0aGF0IGZpbGxlZCB0aGUgZHJpdmU6IGEgbGVha2VkIGBvYnNpZGlhbl90ZXN0YCBzYXRcbiAgICAgKiBiZXNpZGUgZXZlcnkgbGF0ZXIgcnVuLCBlYWNoIG9mIHdoaWNoIHByb2JlZCBpdCBhcyBgb3RoZXItYXZkYCwgYm9vdGVkXG4gICAgICogaXRzIG93biBlbXVsYXRvciBuZXh0IHRvIGl0LCBhbmQgbGVmdCBpdCBydW5uaW5nLlxuICAgICAqL1xuICAgIGF3YWl0IHRoaXMuZW11bGF0b3JzLnJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9ycyh7IGV4Y2VwdEF2ZE5hbWU6IGF2ZE5hbWUsIHNjb3BlOiAncHJlZmxpZ2h0JyB9KTtcbiAgICBjb25zdCBkZXZpY2VJZHNCZWZvcmUgPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZERldmljZUlkcygpO1xuICAgIHRoaXMubG9nKGBDaGVja2luZyBleGlzdGluZyBkZXZpY2VzIGZvciBBVkQgXCIke2F2ZE5hbWV9XCIuLi4gKGNvbm5lY3RlZDogWyR7ZGV2aWNlSWRzQmVmb3JlLmpvaW4oJywgJyl9XSlgKTtcblxuICAgIGNvbnN0IHByb2JlUmVzdWx0cyA9IGF3YWl0IHRoaXMucHJvYmVEZXZpY2VzRm9yQXZkKGF2ZE5hbWUsIGRldmljZUlkc0JlZm9yZSk7XG4gICAgdGhpcy5sb2coYEFWRCBwcm9iZTogJHtidWlsZEF2ZFByb2JlU3VtbWFyeShwcm9iZVJlc3VsdHMpfS5gKTtcbiAgICBjb25zdCBwcm9iZVZlcmRpY3QgPSByZXNvbHZlQXZkUHJvYmVWZXJkaWN0KHByb2JlUmVzdWx0cyk7XG5cbiAgICBzd2l0Y2ggKHByb2JlVmVyZGljdC52ZXJkaWN0KSB7XG4gICAgICBjYXNlICdyZWZ1c2UnOiB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIFNpbGVuY2UgaXMgbm90IGEgc2tpcC4gRmFsbGluZyB0aHJvdWdoIHRvIGEgbGF1bmNoIGhlcmUgaXMgd2hhdFxuICAgICAgICAgKiBwcm9kdWNlZCBgRkFUQUwgfCBSdW5uaW5nIG11bHRpcGxlIGVtdWxhdG9ycyB3aXRoIHRoZSBzYW1lIEFWRGAgXHUyMDE0XG4gICAgICAgICAqIHNlZSBgYXZkLXByb2JlLXZlcmRpY3QudHNgIGZvciB0aGUgcnVuIHRoaXMgcmVwcm9kdWNlcy5cbiAgICAgICAgICovXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihidWlsZFVucmVhZGFibGVEZXZpY2VzTWVzc2FnZSh7XG4gICAgICAgICAgYXZkTmFtZSxcbiAgICAgICAgICBwcm9iZVRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgICB1bnJlYWRhYmxlRGV2aWNlSWRzOiBwcm9iZVZlcmRpY3QudW5yZWFkYWJsZURldmljZUlkc1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgICBjYXNlICdyZXVzZSc6IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmV1c2VDb25uZWN0ZWREZXZpY2UoYXZkTmFtZSwgcHJvYmVWZXJkaWN0LmRldmljZUlkLCB0aW1lb3V0cyk7XG4gICAgICB9XG4gICAgICBjYXNlICdzdGFydC1uZXcnOiB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICByZXR1cm4gYXNzZXJ0TmV2ZXIocHJvYmVWZXJkaWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxvZyhgQVZEIFwiJHthdmROYW1lfVwiIG5vdCBmb3VuZCBvbiBhbnkgZXhpc3RpbmcgZGV2aWNlLCBzdGFydGluZyBhIG5ldyBlbXVsYXRvci4uLmApO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlQXZkRXhpc3RzKGF2ZE5hbWUpO1xuICAgIC8qXG4gICAgICogU25hcHNob3QgdGhlIGVtdWxhdG9yIHByb2Nlc3NlcyB0aGF0IHByZWRhdGUgdGhpcyBsYXVuY2gsIHNvIHRoZSBvbmVzIHRoYXRcbiAgICAgKiBhcHBlYXIgYWNyb3NzIGl0IGNhbiBiZSBpZGVudGlmaWVkIGFzIE9VUlMuIFRoZSBsYXVuY2hlcidzIFBJRCBpcyBub3RcbiAgICAgKiBlbm91Z2ggdG8ga2lsbDogdW5kZXIgYC1uby13aW5kb3dgIHRoZSBwcm9jZXNzIHRoYXQgaG9sZHMgdGhlIEFWRCBpcyB0aGVcbiAgICAgKiBgcWVtdS1zeXN0ZW0tKi1oZWFkbGVzc2AgYmFja2VuZCBpdCBmb3Jrcywgd2hpY2ggc3Vydml2ZXMgYSBgdGFza2tpbGwgL1RgXG4gICAgICogb2YgdGhlIGxhdW5jaGVyIChzZWUgYGVtdWxhdG9yLWJhY2tlbmQudHNgKS4gRGlmZmluZyBoZXJlIFx1MjAxNCByYXRoZXIgdGhhblxuICAgICAqIHN3ZWVwaW5nIGBxZW11KmAgYXQgdGVhcmRvd24gXHUyMDE0IGlzIHdoYXQga2VlcHMgdGhlIGhhcm5lc3MgZnJvbSBraWxsaW5nXG4gICAgICogc29tZWJvZHkgZWxzZSdzIGVtdWxhdG9yLlxuICAgICAqL1xuICAgIGNvbnN0IGVtdWxhdG9yUGlkc0JlZm9yZSA9IGF3YWl0IHRoaXMubGlzdEVtdWxhdG9yQmFja2VuZFBpZHMoW10pO1xuICAgIGNvbnN0IHNob3VsZFJldXNlU25hcHNob3QgPSBwYXJhbXMuc2hvdWxkUmV1c2VFbXVsYXRvclNuYXBzaG90ID09PSB0cnVlO1xuICAgIGlmIChzaG91bGRSZXVzZVNuYXBzaG90KSB7XG4gICAgICB0aGlzLmxvZ1NuYXBzaG90QWdlKGF2ZE5hbWUpO1xuICAgIH1cbiAgICBjb25zdCBsYXVuY2hlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGVtdWxhdG9yID0gdGhpcy5zdGFydEVtdWxhdG9yKGF2ZE5hbWUsIHNob3VsZFJldXNlU25hcHNob3QsIGlzRW11bGF0b3JWaXNpYmxlKTtcbiAgICBjb25zdCBpc1JlY29yZGVkRnJvbUxhdW5jaCA9IHRoaXMucmVjb3JkRW11bGF0b3JMYXVuY2goeyBhdmROYW1lLCBlbXVsYXRvciwgbGF1bmNoZWRBdEluTWlsbGlzZWNvbmRzLCBwcmVMYXVuY2hFbXVsYXRvclBpZHM6IGVtdWxhdG9yUGlkc0JlZm9yZSB9KTtcblxuICAgIC8qXG4gICAgICogVGhlIGNhcHR1cmUgaXMgTk9UIHN0b3BwZWQgaGVyZSBhbnkgbW9yZS4gSXQgdXNlZCB0byBiZSwgaW4gYSBgZmluYWxseWBcbiAgICAgKiB0aGUgbW9tZW50IGEgZGV2aWNlIGFwcGVhcmVkIFx1MjAxNCB3aGljaCBmcm96ZSB0aGUgZW11bGF0b3IncyB0ZXN0aW1vbnlcbiAgICAgKiBleGFjdGx5IG9uZSBzdGVwIGJlZm9yZSB0aGUgZmFpbHVyZSB0aGlzIGhhcm5lc3MgY291bGQgbm90IGV4cGxhaW4uIFRoZVxuICAgICAqIGhhbmdpbmctdGhyZWFkIGFuZCBwYWNrZXQtc3RyZWFtZXIgbGluZXMgYXJlIHByaW50ZWQgbGF0ZXIsIHdoaWxlIHRoZSBydW5cbiAgICAgKiBpcyBpbnNpZGUgYGVzdGFibGlzaFNlc3Npb25gLiBUaGUgd2luZG93IG5vdyBjbG9zZXMgdGhlcmUgaW5zdGVhZC5cbiAgICAgKi9cbiAgICBsZXQgYWN0dWFsRGV2aWNlSWQ6IHN0cmluZztcbiAgICB0cnkge1xuICAgICAgYWN0dWFsRGV2aWNlSWQgPSBhd2FpdCB0aGlzLndhaXRGb3JOZXdEZXZpY2UoZGV2aWNlSWRzQmVmb3JlLCBlbXVsYXRvciwgdGltZW91dHMsIChkZXZpY2VJZCkgPT4ge1xuICAgICAgICB0aGlzLnJlY29yZEVtdWxhdG9yTGF1bmNoRGV2aWNlKHsgYXZkTmFtZSwgZGV2aWNlSWQsIGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvKlxuICAgICAgICogVGhpcyBlbXVsYXRvciBpcyBvdXJzIGFuZCB0aGlzIGlzIHRoZSBsYXN0IHBvaW50IGFueXRoaW5nIGhvbGRzIGl0OiBhXG4gICAgICAgKiByZWplY3Rpb24gaGVyZSByZWFjaGVzIHRoZSBjYWxsZXIgd2l0aCBubyBkZXZpY2UgcmVzdWx0LCBzbyBpdHNcbiAgICAgICAqIHRlYXJkb3duIGhhcyBubyBwcm9jZXNzIHRvIHN0b3AuIEEgYm9vdCB0aGF0IGZhaWxlZCBhIHJlYWRpbmVzcyBnYXRlIFx1MjAxNFxuICAgICAgICogdGhlIGlkbGUgd2FpdCwgdGhlIG5ldHdvcmsgd2FpdCBcdTIwMTQgdXNlZCB0byBsZWF2ZSBhIHJ1bm5pbmcgZW11bGF0b3JcbiAgICAgICAqIGJlaGluZCBleGFjdGx5IHRoaXMgd2F5LlxuICAgICAgICovXG4gICAgICBhd2FpdCB0aGlzLnN0b3BFbXVsYXRvckFmdGVyRmFpbGVkU3RhcnQoeyBhdmROYW1lLCBkZXZpY2VJZHNCZWZvcmUsIGVtdWxhdG9yLCBlbXVsYXRvclBpZHNCZWZvcmUgfSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBjb25zdCBvd25lZEVtdWxhdG9yUGlkcyA9IGF3YWl0IHRoaXMubGlzdEVtdWxhdG9yQmFja2VuZFBpZHMoZW11bGF0b3JQaWRzQmVmb3JlKTtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBFbXVsYXRvciBcIiR7YXZkTmFtZX1cIiBzdGFydGVkLCBkZXZpY2UgJHthY3R1YWxEZXZpY2VJZH0gaXMgY29ubmVjdGVkIChvd25lZCBlbXVsYXRvciBQSURzOiBbJHtvd25lZEVtdWxhdG9yUGlkcy5qb2luKCcsICcpfV0pLmBcbiAgICApO1xuICAgIC8qXG4gICAgICogUmVjb3JkZWQgaGVyZSBcdTIwMTQgaW5jbHVkaW5nIHdoZW4gdGhpcyBjb2RlIHJ1bnMgaW4gYSB0ZXN0IHdvcmtlciwgd2hpY2ggaXNcbiAgICAgKiB0aGUgY2FzZSB0aGUgaW4tbWVtb3J5IG93bmVyc2hpcCBsb3N0OiB0aGUgd29ya2VyIGRpZXMgd2l0aG91dCBhXG4gICAgICogdGVhcmRvd24sIGFuZCB0aGUgbWFya2VyIGlzIHdoYXQgbGV0cyB0aGUgcnVuJ3MgZ2xvYmFsIHRlYXJkb3duLCBvciB0aGVcbiAgICAgKiBuZXh0IHJ1biwgZmluZCBhbmQgc3RvcCB3aGF0IGl0IHN0YXJ0ZWQuIFRoaXMgd3JpdGUgY29tcGxldGVzIHRoZSByZWNvcmRcbiAgICAgKiB0aGUgbGF1bmNoIG9wZW5lZDogc2FtZSBsYXVuY2ggdGltZSwgbm93IHdpdGggdGhlIFFFTVUgYmFja2VuZCB0aGVcbiAgICAgKiBsYXVuY2hlciBmb3JrZWQsIHdoaWNoIGlzIHRoZSBwcm9jZXNzIHRoYXQgYWN0dWFsbHkgaG9sZHMgdGhlIEFWRC5cbiAgICAgKi9cbiAgICB3cml0ZUVtdWxhdG9yTWFya2VyKHsgYXZkTmFtZSwgZGV2aWNlSWQ6IGFjdHVhbERldmljZUlkLCBvd25lZEVtdWxhdG9yUGlkcywgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHM6IGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyB9KTtcbiAgICBpZiAoIWlzUmVjb3JkZWRGcm9tTGF1bmNoKSB7XG4gICAgICAvLyBUaGUgbWFya2VyIGNvdmVycyBhIHJ1biB0aGF0IGVuZHMgb3IgaXMgZm9sbG93ZWQgYnkgYW5vdGhlcjsgdGhlIHJlYXBlciBjb3ZlcnMgb25lIGtpbGxlZCB3aXRoIG5vdGhpbmcgYWZ0ZXIgaXQuXG4gICAgICB0aGlzLmFybUVtdWxhdG9yUmVhcGVyKGF2ZE5hbWUsIGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyk7XG4gICAgfVxuICAgIGF3YWl0IHRoaXMuc3VwcHJlc3NFcnJvckRpYWxvZ3MoYWN0dWFsRGV2aWNlSWQpO1xuICAgIHJldHVybiB7XG4gICAgICBhY3R1YWxEZXZpY2VJZCxcbiAgICAgIGVtdWxhdG9yQ2FwdHVyZTogeyByZWFkOiBlbXVsYXRvci5yZWFkT3V0cHV0LCBzdG9wOiBlbXVsYXRvci5zdG9wQ2FwdHVyZSB9LFxuICAgICAgZW11bGF0b3JQcm9jZXNzOiBlbXVsYXRvci5wcm9jZXNzLFxuICAgICAgb3duZWRFbXVsYXRvclBpZHNcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVVaWF1dG9tYXRvcjJEcml2ZXJJbnN0YWxsZWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5sb2coYENoZWNraW5nIHdoZXRoZXIgdGhlICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfSBkcml2ZXIgaXMgaW5zdGFsbGVkLi4uYCk7XG4gICAgY29uc3QgZHJpdmVyTGlzdEpzb24gPSBhd2FpdCBleGVjKCducHggLS1uby1pbnN0YWxsIGFwcGl1bSBkcml2ZXIgbGlzdCAtLWluc3RhbGxlZCAtLWpzb24nLCB7XG4gICAgICBpc1F1aWV0OiB0cnVlLFxuICAgICAgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWVcbiAgICB9KTtcblxuICAgIGlmIChjaGVja0lzQXBwaXVtRHJpdmVySW5zdGFsbGVkKHsgZHJpdmVyTGlzdEpzb24sIGRyaXZlck5hbWU6IFVJQVVUT01BVE9SMl9EUklWRVJfTkFNRSB9KSkge1xuICAgICAgdGhpcy5sb2coYFRoZSAke1VJQVVUT01BVE9SMl9EUklWRVJfTkFNRX0gZHJpdmVyIGlzIGluc3RhbGxlZC5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxvZyhgVGhlICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfSBkcml2ZXIgaXMgbm90IGluc3RhbGxlZC4gSW5zdGFsbGluZyB2aWEgXFxgYXBwaXVtIGRyaXZlciBpbnN0YWxsICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfVxcYC4uLmApO1xuICAgIGF3YWl0IGV4ZWMoYG5weCAtLW5vLWluc3RhbGwgYXBwaXVtIGRyaXZlciBpbnN0YWxsICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfWApO1xuICAgIHRoaXMubG9nKGBUaGUgJHtVSUFVVE9NQVRPUjJfRFJJVkVSX05BTUV9IGRyaXZlciBpbnN0YWxsZWQuYCk7XG4gIH1cblxuICAvKipcbiAgICogRXN0YWJsaXNoZXMgdGhlIFdlYkRyaXZlcklPIHNlc3Npb24sIHJlY29nbml6aW5nIHRoZSBvbmUgZmFpbHVyZSB0aGF0IGJsYW1lc1xuICAgKiB0aGUgd3Jvbmcgc3ViamVjdDogYENvdWxkIG5vdCBmaW5kIGEgY29ubmVjdGVkIEFuZHJvaWQgZGV2aWNlYCBmcm9tIGEgc2VydmVyXG4gICAqIHdob3NlIGFkYiBpcyB3ZWRnZWQgd2hpbGUgdGhlIGhvc3QncyBvd24gYWRiIHNlZXMgdGhlIGRldmljZSBmaW5lLlxuICAgKlxuICAgKiBBIHNlcnZlciBhbiBlYXJsaWVyIHJ1biBvZiB0aGlzIGhhcm5lc3Mgc3RhcnRlZCBpcyByZXN0YXJ0ZWQgYW5kIHRoZSBzZXNzaW9uXG4gICAqIHJldHJpZWQgb25jZSBcdTIwMTQgdGhlIGNvbmZpcm1lZCByZW1lZHkuIEEgZm9yZWlnbiBvciB1c2VyLW1hbmFnZWQgc2VydmVyIGlzXG4gICAqIG5ldmVyIGtpbGxlZDsgaXQgaXMgcmVwb3J0ZWQgd2l0aCBhIG1lc3NhZ2UgdGhhdCBuYW1lcyB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHNlc3Npb24gY2FwYWJpbGl0aWVzIHBsdXMgd2hhdCBpcyBrbm93biBhYm91dCB0aGUgc2VydmVyLlxuICAgKiBAcmV0dXJucyBUaGUgc2Vzc2lvbiwgYW5kIHRoZSByZXBsYWNlbWVudCBzZXJ2ZXIgcHJvY2VzcyB3aGVuIG9uZSB3YXMgc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZXN0YWJsaXNoU2Vzc2lvbihwYXJhbXM6IEVzdGFibGlzaFNlc3Npb25QYXJhbXMpOiBQcm9taXNlPEVzdGFibGlzaFNlc3Npb25SZXN1bHQ+IHtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBDb25uZWN0aW5nIHRvIEFwcGl1bSAoZGV2aWNlPSR7cGFyYW1zLmRldmljZUlkfSwgYXBwPSR7cGFyYW1zLmFwcElkfSwgcmV0cnlUaW1lb3V0OiAke1N0cmluZyhwYXJhbXMuc2Vzc2lvbkNvbm5lY3Rpb25SZXRyeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMsIHJldHJpZXM6ICR7U3RyaW5nKEFQUElVTV9DT05ORUNUSU9OX1JFVFJZX0NPVU5UKX0pLi4uYFxuICAgICk7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgYnJvd3NlcjogYXdhaXQgdGhpcy5jb25uZWN0U2Vzc2lvbihwYXJhbXMpIH07XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGNvbnN0IHZlcmRpY3QgPSByZXNvbHZlV2VkZ2VkQXBwaXVtU2VydmVyUmVtZWR5KHtcbiAgICAgICAgY29ubmVjdGVkRGV2aWNlSWRzOiBhd2FpdCB0aGlzLmdldENvbm5lY3RlZERldmljZUlkc1F1aWV0bHkoKSxcbiAgICAgICAgZGV2aWNlSWQ6IHBhcmFtcy5kZXZpY2VJZCxcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGlzQWRvcHRlZFNlcnZlcjogcGFyYW1zLmlzQWRvcHRlZFNlcnZlcixcbiAgICAgICAgaXNBdXRvU3RhcnRBbGxvd2VkOiBwYXJhbXMuc2hvdWxkQXV0b1N0YXJ0QXBwaXVtICE9PSBmYWxzZSxcbiAgICAgICAgaXNIYXJuZXNzT3duZWRTZXJ2ZXI6IGNoZWNrSXNIYXJuZXNzT3duZWRBcHBpdW1TZXJ2ZXIocGFyYW1zLmFwcGl1bVNlcnZlck1hcmtlcilcbiAgICAgIH0pO1xuXG4gICAgICBpZiAodmVyZGljdC5yZW1lZHkgPT09ICdub3Qtd2VkZ2VkJykge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgaWYgKHZlcmRpY3QucmVtZWR5ID09PSAncmVwb3J0Jykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5idWlsZFdlZGdlZE1lc3NhZ2UocGFyYW1zLCB2ZXJkaWN0LnJlYXNvbiksIHsgY2F1c2U6IGVycm9yIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZXN0YXJ0V2VkZ2VkU2VydmVyQW5kUmV0cnkocGFyYW1zLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVzdGFibGlzaGVzIHRoZSBzZXNzaW9uLCBhbmQgd2hlbiB0aGF0IGZhaWxzLCBhc2tzIHRoZSBkZXZpY2Ugd2hldGhlciBpdCBpc1xuICAgKiBzdGlsbCB0aGVyZSBiZWZvcmUgbGV0dGluZyB0aGUgZmFpbHVyZSBzdGFuZC5cbiAgICpcbiAgICogYGVzdGFibGlzaFNlc3Npb25gIG93bnMgZXhhY3RseSBvbmUgZGlhZ25vc2lzIFx1MjAxNCB0aGUgc3RhbGUgQXBwaXVtIHNlcnZlciBcdTIwMTRcbiAgICogYW5kIHJldGhyb3dzIGV2ZXJ5dGhpbmcgZWxzZSB1bnRvdWNoZWQuIFRoYXQgaXMgcmlnaHQgYXMgZmFyIGFzIGl0IGdvZXMsIGJ1dFxuICAgKiBldmVyeSBzaWduYXR1cmUgdGhpcyBoYXJuZXNzIGFjdHVhbGx5IGZhaWxzIHdpdGggb24gYSB3ZWRnZWQgZW11bGF0b3IgZmFsbHNcbiAgICogaW50byBcImV2ZXJ5dGhpbmcgZWxzZVwiOiBgRGV2aWNlIDxpZD4gd2FzIG5vdCBpbiB0aGUgbGlzdCBvZiBjb25uZWN0ZWRcbiAgICogZGV2aWNlc2AsIGBlcnJvcjogY2xvc2VkYCwgYW5kIGEgYmFyZSBgUE9TVCAvc2Vzc2lvbmAgdGltZW91dC4gUmF0aGVyIHRoYW5cbiAgICogdGVhY2hpbmcgdGhlIHNlcnZlciBtb2R1bGUgdG8gcmVjb2duaXplIGVycm9yIHN0cmluZ3MgdGhhdCBhcmUgbm90IGFib3V0IHRoZVxuICAgKiBzZXJ2ZXIsIHRoZSBkZXZpY2UgaXMgc2ltcGx5IHJlLXByb2JlZCBoZXJlLCB3aGVyZSB0aGUgZGV2aWNlIGlzIGtub3duLiBBXG4gICAqIHdlZGdlZCBlbXVsYXRvciB0aGVuIHJlcG9ydHMgaXRzZWxmLCBhbmQgdGhlIG9yaWdpbmFsIGVycm9yIGlzIGtlcHQgYXMgdGhlXG4gICAqIGBjYXVzZWAuXG4gICAqXG4gICAqIEBwYXJhbSBlbXVsYXRvckNhcHR1cmUgLSBUaGUgZW11bGF0b3IncyBvdXRwdXQsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBpdC5cbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzZXNzaW9uIHBhcmFtZXRlcnMuXG4gICAqIEByZXR1cm5zIFRoZSBlc3RhYmxpc2hlZCBzZXNzaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlc3RhYmxpc2hTZXNzaW9uT3JEaWFnbm9zZURldmljZShcbiAgICBlbXVsYXRvckNhcHR1cmU6IEVtdWxhdG9yQ2FwdHVyZSB8IHVuZGVmaW5lZCxcbiAgICBwYXJhbXM6IEVzdGFibGlzaFNlc3Npb25QYXJhbXNcbiAgKTogUHJvbWlzZTxFc3RhYmxpc2hTZXNzaW9uUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmVzdGFibGlzaFNlc3Npb24ocGFyYW1zKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgY29uc3QgZGlhZ25vc2lzID0gYXdhaXQgdGhpcy5kaWFnbm9zZURldmljZShwYXJhbXMuZGV2aWNlSWQsIGVtdWxhdG9yQ2FwdHVyZSk7XG4gICAgICBpZiAoZGlhZ25vc2lzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihkaWFnbm9zaXMsIHsgY2F1c2U6IGVycm9yIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0Q29ubmVjdGVkRGV2aWNlSWRzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gbGlzdE9ubGluZURldmljZUlkcyhhd2FpdCB0aGlzLmVtdWxhdG9ycy5nZXREZXZpY2VzT3V0cHV0KCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIHRoZSBob3N0J3MgY29ubmVjdGVkIGRldmljZXMgZm9yIHRoZSB3ZWRnZWQtc2VydmVyIGNyb3NzLWNoZWNrLCB3aGVyZVxuICAgKiBhbiBhZGIgdGhhdCBpdHNlbGYgZmFpbHMgbXVzdCBub3QgYmUgcmVhZCBhcyBldmlkZW5jZSBhZ2FpbnN0IHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBjb25uZWN0ZWQgZGV2aWNlIElEcywgb3IgYW4gZW1wdHkgbGlzdCB3aGVuIGFkYiBjb3VsZCBub3QgYmUgcnVuLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRDb25uZWN0ZWREZXZpY2VJZHNRdWlldGx5KCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkRGV2aWNlSWRzKCk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIHRoaXMubG9nKGBDb3VsZCBub3QgcmUtY2hlY2sgY29ubmVjdGVkIGRldmljZXM6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGV2aWNlUHJvcGVydHkoZGV2aWNlSWQ6IHN0cmluZywgcHJvcGVydHk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgJ2FkYicsXG4gICAgICAgIFsnLXMnLCBkZXZpY2VJZCwgJ3NoZWxsJywgJ2dldHByb3AnLCBwcm9wZXJ0eV0sXG4gICAgICAgIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LFxuICAgICAgICAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgICAgIC8vIFJldHVybiBubyBvdXRwdXQgb24gdGltZW91dC9lcnJvciAobm90IHBhcnRpYWwgc3Rkb3V0KSBzbyBhIG5vbi1yZXNwb25zaXZlIGd1ZXN0IHJlYWRzIGFzIFwibm90IGlkbGVcIi5cbiAgICAgICAgICByZXNvbHZlKGVycm9yID8gJycgOiBzdGRvdXQpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIHRoZSBlbXVsYXRvciBwcm9jZXNzZXMgY3VycmVudGx5IHJ1bm5pbmcgb24gdGhlIGhvc3QsIGV4Y2x1ZGluZyBhIHNldFxuICAgKiB0aGF0IGlzIGFscmVhZHkgYWNjb3VudGVkIGZvci5cbiAgICpcbiAgICogQ2FsbGVkIHR3aWNlIGFyb3VuZCBhIGxhdW5jaDogd2l0aCBhbiBlbXB0eSBga25vd25QaWRzYCB0byBzbmFwc2hvdCB3aGF0XG4gICAqIHByZWRhdGVzIGl0LCB0aGVuIHdpdGggdGhhdCBzbmFwc2hvdCB0byBuYW1lIHdoYXQgdGhlIGxhdW5jaCBhZGRlZCBcdTIwMTQgd2hpY2hcbiAgICogaXMgcHJlY2lzZWx5IHRoZSBzZXQgdGhpcyBydW4gb3ducy5cbiAgICpcbiAgICogQmVzdC1lZmZvcnQ6IGEgbGlzdGluZyB0aGF0IGNhbm5vdCBiZSBwcm9kdWNlZCB5aWVsZHMgbm8gUElEcywgc28gYW5cbiAgICogdW5hdmFpbGFibGUgYHRhc2tsaXN0YC9gcHNgIGRlZ3JhZGVzIHRvIFwibm90aGluZyB0byBlc2NhbGF0ZSB0b1wiIHJhdGhlciB0aGFuXG4gICAqIGZhaWxpbmcgdGhlIHJ1biBpdCBpcyBjbGVhbmluZyB1cCBmb3IuICoqSXQgc2F5cyBzbywgbG91ZGx5KiogXHUyMDE0IGFuIGVtcHR5IHNldFxuICAgKiB0aGF0IG1lYW5zIFwibm8gYmFja2VuZCB0byBvd25cIiBhbmQgb25lIHRoYXQgbWVhbnMgXCJ0aGUgcXVlcnkgZmFpbGVkXCIgYXJlXG4gICAqIG90aGVyd2lzZSB0aGUgc2FtZSBsb2cgbGluZSwgYW5kIHRoZSBzZWNvbmQgc2lsZW50bHkgZGlzYXJtcyB0aGUgZXNjYWxhdGlvbi5cbiAgICogVGhhdCBpcyBub3QgaHlwb3RoZXRpY2FsOiB0aGUgZmlyc3QgZW5kLXRvLWVuZCBydW4gb2YgdGhpcyBjb2RlIGxvZ2dlZFxuICAgKiBgb3duZWQgZW11bGF0b3IgUElEczogW11gIGZvciBhIGxhdW5jaCB3aG9zZSBiYWNrZW5kIHdhcyBkZW1vbnN0cmFibHkgdGhlcmUsXG4gICAqIGJlY2F1c2UgYHRhc2tsaXN0YCBvdmVycmFuIGEgMTBzIGJ1ZGdldCBvbiBhIGhvc3QgdGhlIHdlZGdlZCBlbXVsYXRvciBoYWRcbiAgICogYWxyZWFkeSBzbG93ZWQgdG8gdGhlIHBvaW50IHdoZXJlIGV2ZXJ5IGBhZGJgIGNhbGwgd2FzIHRpbWluZyBvdXQgdG9vIFx1MjAxNCB0aGVcbiAgICogc2FtZSBjb250ZW50aW9uICoqTDQ1Kiogc2l6ZXMgYEFEQl9EVU1QU1lTX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTYCBmb3IsIGFuZFxuICAgKiB0aGUgc2FtZSBcIndyb25nIGJ1ZGdldCBzaWxlbnRseSBkaXNhYmxlcyB0aGUgY2hlY2tcIiBzaGFwZS5cbiAgICpcbiAgICogQSBob3N0IGFsd2F5cyBoYXMgcHJvY2Vzc2VzLCBzbyBhIGxpc3RpbmcgdGhhdCBwYXJzZXMgdG8gKip6ZXJvKiogcm93cyBpcyBhXG4gICAqIGZhaWxlZCBxdWVyeSBob3dldmVyIGl0IGV4aXRlZCwgYW5kIGlzIHJlcG9ydGVkIGxpa2Ugb25lLlxuICAgKlxuICAgKiBAcGFyYW0ga25vd25QaWRzIC0gRW11bGF0b3IgUElEcyB0byBleGNsdWRlLlxuICAgKiBAcmV0dXJucyBUaGUgZW11bGF0b3IgUElEcyBub3QgaW4gYGtub3duUGlkc2AuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxpc3RFbXVsYXRvckJhY2tlbmRQaWRzKGtub3duUGlkczogcmVhZG9ubHkgbnVtYmVyW10pOiBQcm9taXNlPG51bWJlcltdPiB7XG4gICAgY29uc3QgcHJvY2Vzc2VzID0gYXdhaXQgdGhpcy5lbXVsYXRvcnMucXVlcnlIb3N0UHJvY2Vzc2VzKCk7XG4gICAgaWYgKHByb2Nlc3NlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZyhcbiAgICAgICAgJ1dhcm5pbmc6IHRoZSBob3N0IHByb2Nlc3MgbGlzdGluZyBmYWlsZWQsIHNvIHRoaXMgcnVuIGNhbm5vdCBpZGVudGlmeSB0aGUgZW11bGF0b3IgYmFja2VuZCBpdCBvd25zLiBUZWFyZG93biB3aWxsIGZhbGwgYmFjayB0byBgYWRiIGRldmljZXNgIGFsb25lIGFuZCB3aWxsIGhhdmUgbm8gUElEIHRvIGVzY2FsYXRlIHRvLidcbiAgICAgICk7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHMoeyBrbm93blBpZHMsIHByb2Nlc3NlcyB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbGlzdEluc3RhbGxlZFBhY2thZ2VzKGRldmljZUlkOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoXG4gICAgICAgICdhZGInLFxuICAgICAgICBbJy1zJywgZGV2aWNlSWQsICdzaGVsbCcsICdjbWQnLCAncGFja2FnZScsICdsaXN0JywgJ3BhY2thZ2VzJ10sXG4gICAgICAgIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LFxuICAgICAgICAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgICAgIC8vIFJldHVybiBubyBvdXRwdXQgb24gdGltZW91dC9lcnJvciBzbyBhIGNodXJuaW5nIGd1ZXN0J3Mgc2xvdy9wYXJ0aWFsIHBhY2thZ2UgbGlzdCBjYW4ndCBmYWxzZWx5IHJlYWQgYXMgaWRsZS5cbiAgICAgICAgICByZXNvbHZlKGVycm9yID8gJycgOiBzdGRvdXQpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBwcm9jZXNzZXMgc3RpbGwgbGlzdGVuaW5nIG9uIGEgcG9ydC5cbiAgICpcbiAgICogVGhpcyBpcyB0aGUgb25seSByZWFsIGVzY2FsYXRpb24gYXZhaWxhYmxlIGZvciB0aGUgQXBwaXVtIHNlcnZlcjogdGhlIFBJRFxuICAgKiB0aGUgaGFybmVzcyBob2xkcyBpcyB0aGUgc2hlbGwgd3JhcHBlciBpdCBzcGF3bmVkLCBzbyByZS1raWxsaW5nIGl0IGFjaGlldmVzXG4gICAqIG5vdGhpbmcsIHdoaWxlIGEgc29ja2V0IHN0aWxsIGFuc3dlcmluZyBvbiB0aGUgcG9ydCBpcyBkaXJlY3QgZXZpZGVuY2Ugb2ZcbiAgICogd2hhdCBzdXJ2aXZlZC5cbiAgICpcbiAgICogQHBhcmFtIHBvcnQgLSBUaGUgcG9ydCB0byBxdWVyeS5cbiAgICogQHJldHVybnMgVGhlIGxpc3RlbmluZyBQSURzLCBvciBhbiBlbXB0eSBsaXN0IHdoZW4gdGhlIHF1ZXJ5IGNvdWxkIG5vdCBiZSBydW4uXG4gICAqL1xuICBwcml2YXRlIGxpc3RQb3J0T3duZXJQaWRzKHBvcnQ6IG51bWJlcik6IFByb21pc2U8bnVtYmVyW10+IHtcbiAgICBjb25zdCBxdWVyeSA9IGJ1aWxkUG9ydE93bmVyUXVlcnkocG9ydCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPG51bWJlcltdPigocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoXG4gICAgICAgIHF1ZXJ5LmNvbW1hbmQsXG4gICAgICAgIHF1ZXJ5LmNvbW1hbmRBcmd1bWVudHMsXG4gICAgICAgIHsgbWF4QnVmZmVyOiBBREJfRFVNUFNZU19NQVhfQlVGRkVSX0lOX0JZVEVTLCB0aW1lb3V0OiBIT1NUX1BST0NFU1NfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSxcbiAgICAgICAgKGVycm9yLCBzdGRvdXQpID0+IHtcbiAgICAgICAgICAvLyBgbHNvZmAgZXhpdHMgbm9uLXplcm8gd2hlbiBub3RoaW5nIGhvbGRzIHRoZSBwb3J0LCB3aGljaCBpcyBhIGxlZ2l0aW1hdGUgZW1wdHkgYW5zd2VyLlxuICAgICAgICAgIHJlc29sdmUocGFyc2VQb3J0T3duZXJQaWRzKHsgb3V0cHV0OiBlcnJvciA/ICcnIDogc3Rkb3V0LCBwb3J0IH0pKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jaHJvbm91cyB7QGxpbmsgbGlzdFBvcnRPd25lclBpZHN9LCBmb3IgdGhlIGBwcm9jZXNzLm9uKCdleGl0JylgIHRlYXJkb3duXG4gICAqIHRoYXQgY2Fubm90IGF3YWl0LlxuICAgKlxuICAgKiBJdHMgYnVkZ2V0IGlzIGRlbGliZXJhdGVseSAqKm5vdCoqIHRoZSBhc3luYyBwYXRoJ3M6IHRoaXMgY2FsbCBibG9ja3MgcHJvY2Vzc1xuICAgKiBleGl0IG91dHJpZ2h0LCBzbyBpdCB0YWtlcyBhIHNob3J0IG9uZSBhbmQgZ2l2ZXMgdXAgcmF0aGVyIHRoYW4gaG9sZGluZyB0aGVcbiAgICogZXhpdCBoYW5kbGVyIGZvciBoYWxmIGEgbWludXRlIG9uIGEgY29udGVuZGVkIGhvc3QuIEdpdmluZyB1cCBsb3NlcyB0aGVcbiAgICogZXNjYWxhdGlvbiwgd2hpY2ggdGhlIHN5bmMgcGF0aCdzIGxvZyBhbHJlYWR5IGFkbWl0cyBpdCBjYW5ub3QgY29uZmlybS5cbiAgICpcbiAgICogQHBhcmFtIHBvcnQgLSBUaGUgcG9ydCB0byBxdWVyeS5cbiAgICogQHJldHVybnMgVGhlIGxpc3RlbmluZyBQSURzLCBvciBhbiBlbXB0eSBsaXN0IHdoZW4gdGhlIHF1ZXJ5IGNvdWxkIG5vdCBiZSBydW4gaW4gdGltZS5cbiAgICovXG4gIHByaXZhdGUgbGlzdFBvcnRPd25lclBpZHNTeW5jKHBvcnQ6IG51bWJlcik6IG51bWJlcltdIHtcbiAgICBjb25zdCBxdWVyeSA9IGJ1aWxkUG9ydE93bmVyUXVlcnkocG9ydCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGV4ZWNGaWxlU3luYyhxdWVyeS5jb21tYW5kLCBxdWVyeS5jb21tYW5kQXJndW1lbnRzLCB7XG4gICAgICAgIGVuY29kaW5nOiAndXRmLTgnLFxuICAgICAgICBtYXhCdWZmZXI6IEFEQl9EVU1QU1lTX01BWF9CVUZGRVJfSU5fQllURVMsXG4gICAgICAgIHRpbWVvdXQ6IFNZTkNfVEVBUkRPV05fUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHBhcnNlUG9ydE93bmVyUGlkcyh7IG91dHB1dCwgcG9ydCB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvZyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsb2coYFt0cmFuc3BvcnQtZmFjdG9yeToke3RoaXMudHlwZX1dICR7bWVzc2FnZX1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dzIGhvdyBvbGQgdGhlIHNuYXBzaG90IGEgcnVuIGhhcyBvcHRlZCBpbnRvIHJlc3VtaW5nIGlzLlxuICAgKlxuICAgKiBCZXN0LWVmZm9ydDogYSBtaXNzaW5nIHNuYXBzaG90IGlzIHRoZSBub3JtYWwgc3RhdGUgb2YgYSBmcmVzaCBBVkQsIG5vdCBhXG4gICAqIGZhaWx1cmUsIGFuZCB0aGlzIGlzIGEgZGlhZ25vc3RpYyByYXRoZXIgdGhhbiBhIGdhdGUuXG4gICAqXG4gICAqIEBwYXJhbSBhdmROYW1lIC0gVGhlIEFWRCB3aG9zZSBzbmFwc2hvdCBpcyBhYm91dCB0byBiZSByZXN1bWVkLlxuICAgKi9cbiAgcHJpdmF0ZSBsb2dTbmFwc2hvdEFnZShhdmROYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgc2F2ZWRBdDogRGF0ZSB8IHVuZGVmaW5lZDtcblxuICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGJ1aWxkQXZkU25hcHNob3REaXJlY3RvcnlDYW5kaWRhdGVzKHsgYXZkTmFtZSwgZW52aXJvbm1lbnQ6IHByb2Nlc3MuZW52LCBob21lRGlyZWN0b3J5OiBob21lZGlyKCkgfSkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNhdmVkQXQgPSBzdGF0U3luYyhjYW5kaWRhdGUpLm10aW1lO1xuICAgICAgICBicmVhaztcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBOb3QgdGhpcyBBVkQgaG9tZSBcdTIwMTQgdHJ5IHRoZSBuZXh0IGNhbmRpZGF0ZS5cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxvZyhidWlsZFNuYXBzaG90QWdlTWVzc2FnZSh7IGF2ZE5hbWUsIHNhdmVkQXQgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIG9uZSBlbXVsYXRvcidzIEFWRCBuYW1lIGZyb20gaXRzIGNvbnNvbGUsIHJldHJ5aW5nIG9uY2UuXG4gICAqXG4gICAqIFRoZSByZXRyeSBpcyB3aGF0IG1ha2VzIHRoZSByZWZ1c2FsIHByb3BvcnRpb25hdGU6IHRoZSBwcm9iZSdzIHdob2xlIGJ1ZGdldFxuICAgKiBpcyA1cywgYW5kIGEgc2Vjb25kIGxvb2sgY29zdHMgbGVzcyB0aGFuIGEgY29sbGlkaW5nIGxhdW5jaCBkb2VzLiBXaGF0IGl0XG4gICAqIG11c3QgbmV2ZXIgZG8gaXMgcmVwb3J0IGEgbm9uLWFuc3dlciBhcyBhbiBhbnN3ZXIgXHUyMDE0IHRoZSBkaXNjYXJkZWQgYF9lcnJvcmBcbiAgICogdGhpcyByZXBsYWNlcyByZXNvbHZlZCBgJydgLCB3aGljaCBjb21wYXJlZCB1bmVxdWFsIHRvIHRoZSB3YW50ZWQgQVZEIGFuZCBzb1xuICAgKiByZWFkIGFzIGEgZGVmaW5pdGUgXCJzb21lIG90aGVyIEFWRFwiLlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgZW11bGF0b3IgdG8gYXNrLlxuICAgKiBAcmV0dXJucyBUaGUgQVZEIG5hbWUgaXQgYW5zd2VyZWQsIG9yIGB1bmRlZmluZWRgIHdoZW4gaXQgZGlkIG5vdCBhbnN3ZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2JlQXZkTmFtZShkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBBVkRfUFJPQkVfQVRURU1QVF9DT1VOVDsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBhbnN3ZXIgPSBhd2FpdCBuZXcgUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGV4ZWNGaWxlKFxuICAgICAgICAgICdhZGInLFxuICAgICAgICAgIFsnLXMnLCBkZXZpY2VJZCwgJ2VtdScsICdhdmQnLCAnbmFtZSddLFxuICAgICAgICAgIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LFxuICAgICAgICAgIChlcnJvciwgc3Rkb3V0KSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKGVycm9yID8gdW5kZWZpbmVkIDogc3Rkb3V0LnNwbGl0KCdcXG4nLCAxKVswXT8udHJpbSgpKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKGFuc3dlciAhPT0gdW5kZWZpbmVkICYmIGFuc3dlci5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgICB9XG5cbiAgICAgIGlmIChhdHRlbXB0IDwgQVZEX1BST0JFX0FUVEVNUFRfQ09VTlQpIHtcbiAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgYERldmljZSAke2RldmljZUlkfSBkaWQgbm90IGFuc3dlciBcXGBhZGIgLXMgJHtkZXZpY2VJZH0gZW11IGF2ZCBuYW1lXFxgIHdpdGhpbiAke1N0cmluZyhBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tczsgcmV0cnlpbmcgb25jZS5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc2tzIGV2ZXJ5IGNvbm5lY3RlZCBkZXZpY2Ugd2hpY2ggQVZEIGl0IGlzIHNlcnZpbmcuXG4gICAqXG4gICAqIEEgZGV2aWNlIHRoYXQgaXMgbm90IGEgbG9jYWxseSBzdGFydGVkIGVtdWxhdG9yIGlzIG5ldmVyIGFza2VkOiBpdHMgY29uc29sZVxuICAgKiBjYW5ub3QgYW5zd2VyIGhvd2V2ZXIgaGVhbHRoeSBpdCBpcywgYW5kIHJlYWRpbmcgdGhhdCBhcyBzaWxlbmNlIHdvdWxkXG4gICAqIHJlZnVzZSBldmVyeSBydW4gb24gYSBob3N0IHdpdGggYSBoYW5kc2V0IHBsdWdnZWQgaW4gXHUyMDE0IHNlZVxuICAgKiBgYXZkLXByb2JlLXZlcmRpY3QudHNgLlxuICAgKlxuICAgKiBAcGFyYW0gYXZkTmFtZSAtIFRoZSBBVkQgdGhlIHJ1biB3YW50cy5cbiAgICogQHBhcmFtIGRldmljZUlkcyAtIFRoZSBjb25uZWN0ZWQgZGV2aWNlcy5cbiAgICogQHJldHVybnMgT25lIG91dGNvbWUgcGVyIGRldmljZSwgaW4gbGlzdGVkIG9yZGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9iZURldmljZXNGb3JBdmQoYXZkTmFtZTogc3RyaW5nLCBkZXZpY2VJZHM6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxBdmRQcm9iZVJlc3VsdFtdPiB7XG4gICAgY29uc3QgcmVzdWx0czogQXZkUHJvYmVSZXN1bHRbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBkZXZpY2VJZCBvZiBkZXZpY2VJZHMpIHtcbiAgICAgIGNvbnN0IHByb2JlZEF2ZE5hbWUgPSBjaGVja0lzRW11bGF0b3JEZXZpY2VJZChkZXZpY2VJZCkgPyBhd2FpdCB0aGlzLnByb2JlQXZkTmFtZShkZXZpY2VJZCkgOiB1bmRlZmluZWQ7XG4gICAgICByZXN1bHRzLnB1c2goeyBkZXZpY2VJZCwgb3V0Y29tZTogY2xhc3NpZnlBdmRQcm9iZSh7IGF2ZE5hbWUsIGRldmljZUlkLCBwcm9iZWRBdmROYW1lIH0pIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFza3MgdGhlICoqZ3Vlc3QqKiB3aGV0aGVyIGl0IGlzIHN0aWxsIHNjaGVkdWxpbmcgd29yaywgdmlhIGBhZGJkYC5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSB0byBwcm9iZS5cbiAgICogQHJldHVybnMgV2hhdCBpdCBhbnN3ZXJlZC5cbiAgICovXG4gIHByaXZhdGUgcHJvYmVEZXZpY2VTaGVsbChkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTxFbXVsYXRvckxpdmVuZXNzUHJvYmVPdXRjb21lPiB7XG4gICAgcmV0dXJuIHRoaXMucnVuTGl2ZW5lc3NQcm9iZShbJy1zJywgZGV2aWNlSWQsICdzaGVsbCcsICd0cnVlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFza3MgdGhlICoqZW11bGF0b3IgcHJvY2VzcyoqIHdoZXRoZXIgaXQgaXMgc3RpbGwgcnVubmluZywgdmlhIGl0cyBjb25zb2xlLlxuICAgKlxuICAgKiBUaGUgY29uc29sZSBpcyBzZXJ2ZWQgYnkgdGhlIGVtdWxhdG9yIGl0c2VsZiByYXRoZXIgdGhhbiBieSB0aGUgZ3Vlc3QsIHdoaWNoXG4gICAqIGlzIHdoYXQgbWFrZXMgaXQgYWJsZSB0byB0ZWxsIGEgZnJvemVuIGd1ZXN0IGZyb20gYSB3ZWRnZWQgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgdG8gcHJvYmUuXG4gICAqIEByZXR1cm5zIFdoYXQgaXQgYW5zd2VyZWQuXG4gICAqL1xuICBwcml2YXRlIHByb2JlRW11bGF0b3JDb25zb2xlKGRldmljZUlkOiBzdHJpbmcpOiBQcm9taXNlPEVtdWxhdG9yTGl2ZW5lc3NQcm9iZU91dGNvbWU+IHtcbiAgICByZXR1cm4gdGhpcy5ydW5MaXZlbmVzc1Byb2JlKFsnLXMnLCBkZXZpY2VJZCwgJ2VtdScsICdhdmQnLCAnc3RhdHVzJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGEgbGVmdG92ZXIgc2VydmVyIGFuIGVhcmxpZXIgcnVuIGZhaWxlZCB0byBzdG9wLCBpbnN0ZWFkIG9mXG4gICAqIGFkb3B0aW5nIGl0LlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBvdGhlciBoYWxmIG9mIHtAbGluayBzdG9wQXV0b1N0YXJ0ZWRBcHBpdW1TZXJ2ZXJ9J3Mgc3RhbXBlZFxuICAgKiBtYXJrZXIsIGFuZCBpdCBpcyB0aGUgY2FzZSB0aGF0IG1vdGl2YXRlZCB0aGUgd2hvbGUgdmVyaWZpZWQgdGVhcmRvd246IHRoZVxuICAgKiBsZWZ0b3ZlciBhbnN3ZXJzIGAvc3RhdHVzYCBwZXJmZWN0bHksIGlzIGFkb3B0ZWQsIGFuZCB0aGVuIGRpZXMgc2Vjb25kcyBpbnRvIHRoZSBzZXNzaW9uIGFzXG4gICAqIGl0IGZpbmFsbHkgZmluaXNoZXMgc2h1dHRpbmcgZG93biBcdTIwMTQgYSBmYWlsdXJlIHRoYXQgcmVhZHMgYXMgYSBkZXZpY2Ugb3JcbiAgICogbmV0d29yayBmYXVsdC4gQSBzZXJ2ZXIgd2Uga25vdyB3ZSBhbHJlYWR5IGFza2VkIHRvIGRpZSBpcyBub3QgYSBzZXJ2ZXIgdG9cbiAgICogYnVpbGQgYSBzdWl0ZSBvbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBtYXJrZXIsIHRoZSBwb3J0IGFuZCB3aGV0aGVyIGEgcmVwbGFjZW1lbnQgbWF5IGJlIHN0YXJ0ZWQuXG4gICAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIHRoZSBwb3J0IHdhcyBmcmVlZCBhbmQgYSBmcmVzaCBzZXJ2ZXIgbXVzdCBiZSBzdGFydGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWNsYWltVW5zdG9wcGVkQXBwaXVtU2VydmVyKHBhcmFtczogUmVjbGFpbVVuc3RvcHBlZEFwcGl1bVNlcnZlclBhcmFtcyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHN0b3BBdHRlbXB0ZWRBdEluTWlsbGlzZWNvbmRzID0gcGFyYW1zLm1hcmtlci5zdG9wQXR0ZW1wdGVkQXRJbk1pbGxpc2Vjb25kcyA/PyBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGFnZUluU2Vjb25kcyA9IE1hdGgucm91bmQoKERhdGUubm93KCkgLSBzdG9wQXR0ZW1wdGVkQXRJbk1pbGxpc2Vjb25kcykgLyBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORCk7XG4gICAgY29uc3QgcHJvdmVuYW5jZSA9IGB0aGUgc2VydmVyIG9uIHBvcnQgJHtTdHJpbmcocGFyYW1zLnBvcnQpfSBpcyBhIGxlZnRvdmVyIGFuIGVhcmxpZXIgcnVuIG9mIHRoaXMgaGFybmVzcyB0cmllZCB0byBzdG9wICR7U3RyaW5nKGFnZUluU2Vjb25kcyl9cyBhZ28gYW5kIGNvdWxkIG5vdGA7XG5cbiAgICBpZiAocGFyYW1zLnNob3VsZEF1dG9TdGFydEFwcGl1bSA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMubG9nKGBXQVJOSU5HOiAke3Byb3ZlbmFuY2V9LiBBdXRvLXN0YXJ0IGlzIGRpc2FibGVkLCBzbyB0aGlzIHJ1biBhZG9wdHMgaXQgYW55d2F5OyBpZiB0aGUgc2Vzc2lvbiBkaWVzIG1pZC1mbGlnaHQsIHRoYXQgaXMgd2h5LmApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMubG9nKGBSZWZ1c2luZyB0byBhZG9wdCBhIGtub3duLWRvb21lZCBzZXJ2ZXI6ICR7cHJvdmVuYW5jZX0uIEtpbGxpbmcgd2hhdGV2ZXIgaG9sZHMgdGhlIHBvcnQgYW5kIHN0YXJ0aW5nIGEgZnJlc2ggc2VydmVyLi4uYCk7XG4gICAgZm9yIChjb25zdCBwaWQgb2YgYXdhaXQgdGhpcy5saXN0UG9ydE93bmVyUGlkcyhwYXJhbXMucG9ydCkpIHtcbiAgICAgIGtpbGxQcm9jZXNzVHJlZUJ5UGlkKHBpZCk7XG4gICAgfVxuICAgIGNsZWFyQXBwaXVtU2VydmVyTWFya2VyKHBhcmFtcy5wb3J0KTtcblxuICAgIGlmIChhd2FpdCB0aGlzLmNoZWNrSXNBcHBpdW1TdG9wcGVkKHBhcmFtcy51cmwsIEFQUElVTV9FU0NBTEFURURfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EUykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMubG9nKGBXQVJOSU5HOiAke3Byb3ZlbmFuY2V9LCBhbmQgaXQgc3Vydml2ZWQgdGhpcyBydW4ncyBraWxsIHRvby4gQWRvcHRpbmcgaXQsIHdoaWNoIG1heSBmYWlsIG1pZC1zZXNzaW9uLmApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGFuIGVtdWxhdG9yIGFzIHRoaXMgcnVuJ3MgdGhlIG1vbWVudCBpdCBpcyBsYXVuY2hlZCwgYmVmb3JlIGl0IGhhc1xuICAgKiBhIGRldmljZSBcdTIwMTQgYW5kIGFybXMgaXRzIHJlYXBlciB0aGVyZS5cbiAgICpcbiAgICogVGhlIG1hcmtlciB1c2VkIHRvIGJlIHdyaXR0ZW4gb25jZSB0aGUgZGV2aWNlIGNvbm5lY3RlZCwgYWJvdXQgNDVzIGludG8gYVxuICAgKiBjb2xkIGJvb3QsIGFuZCB0aGUgcmVhcGVyIHdpdGggaXQuIEEgcnVubmVyIGtpbGxlZCBpbnNpZGUgdGhhdCB3aW5kb3cgbGVmdCBhXG4gICAqIHJ1bm5pbmcgZW11bGF0b3Igd2l0aCAqKm5vIG1hcmtlciBhdCBhbGwqKiwgd2hpY2ggZXZlcnkgbGF0ZXIgcnVuIGNvcnJlY3RseVxuICAgKiByZWZ1c2VzIHRvIHRvdWNoICgqKkw0NioqKSBhbmQgbm8gcmVhcGVyIHdhcyB3YXRjaGluZzogdGhlIGxlZnRvdmVyIHdhc1xuICAgKiBub2JvZHkncyB0byBzdG9wLCBmb3IgZXZlci4gQSBsYXVuY2gtdGltZSBtYXJrZXIgY2xvc2VzIHRoYXQgd2luZG93IHdpdGggdGhlXG4gICAqIG9uZSB0aGluZyBhbHJlYWR5IGtub3duIFx1MjAxNCB0aGUgbGF1bmNoZXIncyBQSUQsIHdoaWNoIGBlbXVsYXRvci1iYWNrZW5kLnRzYFxuICAgKiBjb3VudHMgYXMgYW4gZW11bGF0b3IgcHJvY2Vzcywgc28gdGhlIG1hcmtlciBjb252aWN0cyBhcyBhXG4gICAqIGBoYXJuZXNzLWxlZnRvdmVyYCBleGFjdGx5IGxpa2UgYSBjb21wbGV0ZWQgb25lIFx1MjAxNCBwbHVzIHRoZSBwcmUtbGF1bmNoXG4gICAqIHNuYXBzaG90LCB3aGljaCBpcyB3aGF0IGxldHMgYSBsYXRlciByZWNsYWltIGlkZW50aWZ5IHRoZSBiYWNrZW5kIHRoZVxuICAgKiBsYXVuY2hlciBmb3JrcyB3aXRob3V0IGhhdmluZyBiZWVuIHRoZXJlIHRvIHdhdGNoIGl0LlxuICAgKlxuICAgKiAqKkl0IG5ldmVyIG92ZXJ3cml0ZXMgYSBtYXJrZXIgd2hvc2UgcHJvY2Vzc2VzIGFyZSBzdGlsbCBydW5uaW5nLioqIEEgbGF1bmNoXG4gICAqIGNhbiBoYXBwZW4gd2hpbGUgYW4gb2xkZXIgZW11bGF0b3Igb2YgdGhlIHNhbWUgQVZEIGlzIHN0aWxsIHVwIGFuZCByZWNvcmRlZFxuICAgKiBcdTIwMTQgYW4gYG9mZmxpbmVgIGxlZnRvdmVyIHRoZSBwcm9iZSBjYW5ub3Qgc2VlLCB3aGljaCBpcyB0aGUgbGF1bmNoIHRoYXQgZGllc1xuICAgKiBvbiBgUnVubmluZyBtdWx0aXBsZSBlbXVsYXRvcnMgd2l0aCB0aGUgc2FtZSBBVkRgLiBDbG9iYmVyaW5nIHRoYXQgbWFya2VyXG4gICAqIHdvdWxkIGVyYXNlIHRoZSBvbmx5IHJlY29yZCBvZiBhIHJ1bm5pbmcgZW11bGF0b3IsIHRoZSB2ZXJ5IHRoaW5nXG4gICAqIGBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkYCBleGlzdHMgdG8gcHJldmVudC4gSW4gdGhhdCBjYXNlIHRoZSByZWNvcmRcbiAgICogd2FpdHMgZm9yIHRoZSBzdWNjZXNzIHBhdGgsIGFzIGJlZm9yZS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBBVkQsIGl0cyBsYXVuY2hlciwgYW5kIHdoZW4gaXQgd2FzIGxhdW5jaGVkLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgbGF1bmNoIHdhcyByZWNvcmRlZCBhbmQgaXRzIHJlYXBlciBhcm1lZC5cbiAgICovXG4gIHByaXZhdGUgcmVjb3JkRW11bGF0b3JMYXVuY2gocGFyYW1zOiBSZWNvcmRFbXVsYXRvckxhdW5jaFBhcmFtcyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHsgYXZkTmFtZSB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IGxhdW5jaGVyUGlkID0gcGFyYW1zLmVtdWxhdG9yLnByb2Nlc3MucGlkO1xuICAgIGlmIChsYXVuY2hlclBpZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZyhgVGhlIGVtdWxhdG9yIGxhdW5jaGVyIGZvciBBVkQgXCIke2F2ZE5hbWV9XCIgcmVwb3J0ZWQgbm8gUElELCBzbyBpdHMgbGF1bmNoIGNhbm5vdCBiZSByZWNvcmRlZDsgaXQgaXMgcmVjb3JkZWQgb25jZSBpdHMgZGV2aWNlIGNvbm5lY3RzLmApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nTWFya2VyID0gcmVhZEVtdWxhdG9yTWFya2VyKGF2ZE5hbWUpO1xuICAgIGlmIChleGlzdGluZ01hcmtlciAmJiAoc2VsZWN0TGl2ZU1hcmtlZFBpZHMoZXhpc3RpbmdNYXJrZXIsIHBhcmFtcy5wcmVMYXVuY2hFbXVsYXRvclBpZHMpLmxlbmd0aCA+IDAgfHwgY2hlY2tJc01hcmtlZEVtdWxhdG9yUnVubmluZyhleGlzdGluZ01hcmtlcikpKSB7XG4gICAgICB0aGlzLmxvZyhgTm90IHJlY29yZGluZyB0aGUgbGF1bmNoIG9mIEFWRCBcIiR7YXZkTmFtZX1cIiB5ZXQ6IGl0cyBleGlzdGluZyBtYXJrZXIgc3RpbGwgbmFtZXMgYSBydW5uaW5nIHByb2Nlc3MsIGFuZCB0aGF0IHJlY29yZCBpcyB0aGUgb25seSBvbmUgb2YgYW4gZW11bGF0b3IgdGhhdCBtYXkgc3RpbGwgYmUgdXAuYCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgd3JpdGVFbXVsYXRvck1hcmtlcih7XG4gICAgICBhdmROYW1lLFxuICAgICAgb3duZWRFbXVsYXRvclBpZHM6IFtsYXVuY2hlclBpZF0sXG4gICAgICBwcmVMYXVuY2hFbXVsYXRvclBpZHM6IHBhcmFtcy5wcmVMYXVuY2hFbXVsYXRvclBpZHMsXG4gICAgICBzdGFydGVkQXRJbk1pbGxpc2Vjb25kczogcGFyYW1zLmxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kc1xuICAgIH0pO1xuICAgIHRoaXMubG9nKGBSZWNvcmRlZCB0aGUgZW11bGF0b3IgbGF1bmNoIGZvciBBVkQgXCIke2F2ZE5hbWV9XCIgKGxhdW5jaGVyIFBJRCAke1N0cmluZyhsYXVuY2hlclBpZCl9KSBiZWZvcmUgaXRzIGRldmljZSBleGlzdHMsIHNvIGEga2lsbCBkdXJpbmcgdGhlIGJvb3Qgc3RpbGwgbGVhdmVzIGl0IGNvbnZpY3RhYmxlLmApO1xuICAgIHRoaXMuYXJtRW11bGF0b3JSZWFwZXIoYXZkTmFtZSwgcGFyYW1zLmxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRmlsbHMgdGhlIGRldmljZSBpbnRvIHRoZSBtYXJrZXIgdGhpcyBsYXVuY2ggd3JvdGUsIGFzIHNvb24gYXMgb25lIGFwcGVhcnMuXG4gICAqXG4gICAqIFdvcnRoIGl0cyBvd24gd3JpdGUgYmVjYXVzZSB0aGUgY29uc29sZSBzaHV0ZG93biBpcyB0aGUgb25seSBzdG9wIHRoYXRcbiAgICogcmVsZWFzZXMgdGhlIEFWRCdzIGBtdWx0aWluc3RhbmNlLmxvY2tgICgqKkw0NioqKSwgYW5kIGl0IG5lZWRzIGEgZGV2aWNlIHRvXG4gICAqIHRhbGsgdG8uIERlbGliZXJhdGVseSAqKm5vKiogaG9zdCBwcm9jZXNzIGxpc3RpbmcgaGVyZTogdGhhdCBxdWVyeSBpc1xuICAgKiBidWRnZXRlZCBhdCB7QGxpbmsgSE9TVF9QUk9DRVNTX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTfSBmb3IgZXhhY3RseVxuICAgKiB0aGlzIGNvbnRlbmRlZCB3aW5kb3csIGFuZCBzcGVuZGluZyBpdCBpbnNpZGUgdGhlIGJvb3QgcGF0aCB3b3VsZCBlYXQgdGhlXG4gICAqIHJlYWRpbmVzcyBidWRnZXRzIHRoYXQgZm9sbG93LiBUaGUgYmFja2VuZCBQSURzIGFycml2ZSB3aXRoIHRoZSBzdWNjZXNzXG4gICAqIHdyaXRlLCBvbmUgbGlzdGluZywgYXMgYmVmb3JlLlxuICAgKlxuICAgKiBPbmx5IGV2ZXIgZmlsbHMgaW4gKip0aGlzKiogbGF1bmNoJ3MgbWFya2VyOiBvbmUgY2FycnlpbmcgYW5vdGhlciBsYXVuY2hcbiAgICogdGltZSwgb3IgYSBkZXZpY2UgYWxyZWFkeSwgYmVsb25ncyB0byBhbiBlbXVsYXRvciB0aGlzIHJ1biBkaWQgbm90IHN0YXJ0LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIEFWRCwgdGhlIGRldmljZSB0aGF0IGFwcGVhcmVkLCBhbmQgdGhlIGxhdW5jaCBpdCBiZWxvbmdzIHRvLlxuICAgKi9cbiAgcHJpdmF0ZSByZWNvcmRFbXVsYXRvckxhdW5jaERldmljZShwYXJhbXM6IFJlY29yZEVtdWxhdG9yTGF1bmNoRGV2aWNlUGFyYW1zKTogdm9pZCB7XG4gICAgY29uc3QgeyBhdmROYW1lLCBkZXZpY2VJZCB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IG1hcmtlciA9IHJlYWRFbXVsYXRvck1hcmtlcihhdmROYW1lKTtcbiAgICBpZiAoIW1hcmtlciB8fCBtYXJrZXIuZGV2aWNlSWQgIT09IHVuZGVmaW5lZCB8fCBtYXJrZXIuc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgIT09IHBhcmFtcy5sYXVuY2hlZEF0SW5NaWxsaXNlY29uZHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3cml0ZUVtdWxhdG9yTWFya2VyKHtcbiAgICAgIGF2ZE5hbWUsXG4gICAgICBkZXZpY2VJZCxcbiAgICAgIG93bmVkRW11bGF0b3JQaWRzOiBtYXJrZXIub3duZWRFbXVsYXRvclBpZHMsXG4gICAgICAvLyBTdGlsbCBwcm92aXNpb25hbDogdGhlIGJhY2tlbmQncyBQSUQgYXJyaXZlcyB3aXRoIHRoZSBzdWNjZXNzIHdyaXRlLCBhbmQgdW50aWwgdGhlbiB0aGUgZGlmZiBpcyB3aGF0IGNvbnZpY3RzIGl0LlxuICAgICAgcHJlTGF1bmNoRW11bGF0b3JQaWRzOiBtYXJrZXIucHJlTGF1bmNoRW11bGF0b3JQaWRzLFxuICAgICAgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHM6IG1hcmtlci5zdGFydGVkQXRJbk1pbGxpc2Vjb25kc1xuICAgIH0pO1xuICAgIHRoaXMubG9nKGBSZWNvcmRlZCBkZXZpY2UgJHtkZXZpY2VJZH0gYWdhaW5zdCB0aGUgbGF1bmNoIG1hcmtlciBmb3IgQVZEIFwiJHthdmROYW1lfVwiLCBzbyBhIHN0b3AgZnJvbSBoZXJlIG9uIGNhbiBzaHV0IGl0IGRvd24gb3ZlciBpdHMgY29uc29sZS5gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhIHdlZGdlZCBzZXJ2ZXIgdGhpcyBoYXJuZXNzIHN0YXJ0ZWQgZWFybGllciBhbmQgcmV0cmllcyB0aGVcbiAgICogc2Vzc2lvbiBvbmNlLlxuICAgKlxuICAgKiBUaGUgb2xkIHNlcnZlciBpcyBraWxsZWQgYW5kIHRoZSBwb3J0IGlzIHdhaXRlZCBvdXQgYmVmb3JlIGEgcmVwbGFjZW1lbnQgaXNcbiAgICogc3RhcnRlZDogYSBzb2NrZXQgdGhhdCBrZWVwcyBhbnN3ZXJpbmcgYC9zdGF0dXNgIHdvdWxkIGxldCB0aGUgcmVhZGluZXNzXG4gICAqIHBvbGwgcGFzcyBvbiB0aGUgZHlpbmcgc2VydmVyLCBhbmQgYSBwb3J0IHRoYXQgbmV2ZXIgZ29lcyBxdWlldCBtZWFucyB0aGVcbiAgICoga2lsbCBkaWQgbm90IHRha2UgXHUyMDE0IGluIHdoaWNoIGNhc2Ugc3RhcnRpbmcgYW55dGhpbmcgb24gaXQgaXMgcG9pbnRsZXNzLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHNlc3Npb24gY2FwYWJpbGl0aWVzIHBsdXMgd2hhdCBpcyBrbm93biBhYm91dCB0aGUgc2VydmVyLlxuICAgKiBAcGFyYW0gb3JpZ2luYWxFcnJvciAtIFRoZSBmYWlsdXJlIHRoYXQgY29udmljdGVkIHRoZSBzZXJ2ZXIsIGxvZ2dlZCBzbyB0aGUgZGlhZ25vc2lzIGlzIG9uIHRoZSByZWNvcmQuXG4gICAqIEByZXR1cm5zIFRoZSBzZXNzaW9uIGFuZCB0aGUgcmVwbGFjZW1lbnQgc2VydmVyIHByb2Nlc3MuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlc3RhcnRXZWRnZWRTZXJ2ZXJBbmRSZXRyeShwYXJhbXM6IEVzdGFibGlzaFNlc3Npb25QYXJhbXMsIG9yaWdpbmFsRXJyb3I6IHVua25vd24pOiBQcm9taXNlPEVzdGFibGlzaFNlc3Npb25SZXN1bHQ+IHtcbiAgICBjb25zdCBtYXJrZXIgPSBlbnN1cmVOb25OdWxsYWJsZShwYXJhbXMuYXBwaXVtU2VydmVyTWFya2VyLCAnQSByZXN0YXJ0IHZlcmRpY3QgcmVxdWlyZXMgdGhlIG1hcmtlciB0aGF0IHByb3ZlZCBvd25lcnNoaXAuJyk7XG4gICAgdGhpcy5sb2coXG4gICAgICBgQXBwaXVtIGF0ICR7cGFyYW1zLnVybC5vcmlnaW59IGNhbm5vdCBzZWUgJHtwYXJhbXMuZGV2aWNlSWR9IGFsdGhvdWdoIHRoaXMgaG9zdCdzIGFkYiBjYW4gXHUyMDE0IHRoZSBzZXJ2ZXIgdGhpcyBoYXJuZXNzIHN0YXJ0ZWQgZWFybGllciAocGlkICR7U3RyaW5nKG1hcmtlci5waWQpfSkgaXMgc3RhbGUuIFJlc3RhcnRpbmcgaXQuLi4gKHNlc3Npb24gZmFpbGVkIHdpdGg6ICR7b3JpZ2luYWxFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gb3JpZ2luYWxFcnJvci5tZXNzYWdlIDogU3RyaW5nKG9yaWdpbmFsRXJyb3IpfSlgXG4gICAgKTtcblxuICAgIGtpbGxQcm9jZXNzVHJlZUJ5UGlkKG1hcmtlci5waWQpO1xuICAgIGNsZWFyQXBwaXVtU2VydmVyTWFya2VyKHBhcmFtcy5wb3J0KTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JBcHBpdW1TdG9wcGVkKHBhcmFtcy51cmwsIEFQUElVTV9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMuYnVpbGRXZWRnZWRNZXNzYWdlKHBhcmFtcywgJ3Jlc3RhcnQtZGlkLW5vdC1oZWxwJyksIHsgY2F1c2U6IGVycm9yIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGxhdW5jaCA9IHRoaXMuc3RhcnRBcHBpdW1TZXJ2ZXIocGFyYW1zLnBvcnQsIHBhcmFtcy5pc0FwcGl1bUNvbnNvbGVWaXNpYmxlKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JBcHBpdW1SZWFkeShwYXJhbXMudXJsLCBwYXJhbXMuYXBwaXVtU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMsIGxhdW5jaCk7XG4gICAgICB0aGlzLmxvZygnUmVwbGFjZW1lbnQgQXBwaXVtIHNlcnZlciBpcyByZWFkeSwgcmV0cnlpbmcgdGhlIHNlc3Npb24uLi4nKTtcbiAgICAgIHJldHVybiB7IGFwcGl1bVByb2Nlc3M6IGxhdW5jaC5wcm9jZXNzLCBicm93c2VyOiBhd2FpdCB0aGlzLmNvbm5lY3RTZXNzaW9uKHBhcmFtcykgfTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAga2lsbFByb2Nlc3NUcmVlKGxhdW5jaC5wcm9jZXNzKTtcbiAgICAgIGNsZWFyQXBwaXVtU2VydmVyTWFya2VyKHBhcmFtcy5wb3J0KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLmJ1aWxkV2VkZ2VkTWVzc2FnZShwYXJhbXMsICdyZXN0YXJ0LWRpZC1ub3QtaGVscCcpLCB7IGNhdXNlOiBlcnJvciB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRvcHRzIGEgZGV2aWNlIGFscmVhZHkgc2VydmluZyB0aGUgcmVxdWVzdGVkIEFWRC5cbiAgICpcbiAgICogQHBhcmFtIGF2ZE5hbWUgLSBUaGUgQVZEIGl0IGlzIHNlcnZpbmcuXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgdG8gYWRvcHQuXG4gICAqIEBwYXJhbSB0aW1lb3V0cyAtIFRoZSB0d28gcG9zdC1ib290IHJlYWRpbmVzcyBidWRnZXRzLlxuICAgKiBAcmV0dXJucyBUaGUgYWRvcHRlZCBkZXZpY2UsIG93bmluZyB0aGUgZW11bGF0b3IncyBQSURzIG9ubHkgd2hlbiBpdCBpcyBhIGxlZnRvdmVyIHRoaXMgaGFybmVzcyBzdGFydGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXVzZUNvbm5lY3RlZERldmljZShhdmROYW1lOiBzdHJpbmcsIGRldmljZUlkOiBzdHJpbmcsIHRpbWVvdXRzOiBEZXZpY2VSZWFkaW5lc3NUaW1lb3V0cyk6IFByb21pc2U8RW5zdXJlRGV2aWNlQ29ubmVjdGVkUmVzdWx0PiB7XG4gICAgLypcbiAgICAgKiBBIGRldmljZSB0aGlzIHJ1biBkaWQgbm90IHN0YXJ0IGlzIG5vdCB0aGlzIHJ1bidzIHRvIHN0b3AgXHUyMDE0IHVubGVzcyB0aGlzXG4gICAgICogaGFybmVzcyBzdGFydGVkIGl0IGFuZCBub3RoaW5nIGxpdmUgaXMgcmVzcG9uc2libGUgZm9yIGl0IGFueSBtb3JlLiBUaGVuXG4gICAgICogaXQgaXMgdGFrZW4gb3Zlciwgc28gdGhpcyBydW4ncyB0ZWFyZG93biBzdG9wcyBpdCBhbmQgYSBsZWFrZWQgZW11bGF0b3JcbiAgICAgKiBzZXJ2ZXMgYXQgbW9zdCBvbmUgbW9yZSBydW4gaW5zdGVhZCBvZiBsaXZpbmcgZm9yIGV2ZXIuXG4gICAgICovXG4gICAgY29uc3Qgb3duZWRFbXVsYXRvclBpZHMgPSBhd2FpdCB0aGlzLnRha2VPdmVyTGVmdG92ZXJFbXVsYXRvcihhdmROYW1lLCBkZXZpY2VJZCk7XG4gICAgdGhpcy5sb2coXG4gICAgICBvd25lZEVtdWxhdG9yUGlkcy5sZW5ndGggPiAwXG4gICAgICAgID8gYEFWRCBcIiR7YXZkTmFtZX1cIiBpcyBhbHJlYWR5IHJ1bm5pbmcgb24gZGV2aWNlICR7ZGV2aWNlSWR9IGFzIGEgbGVmdG92ZXIgdGhpcyBoYXJuZXNzIHN0YXJ0ZWQ7IHJldXNpbmcgaXQgYW5kIHRha2luZyBpdCBvdmVyIChvd25lZCBlbXVsYXRvciBQSURzOiBbJHtvd25lZEVtdWxhdG9yUGlkcy5qb2luKCcsICcpfV0pLCBzbyB0aGlzIHJ1biBzdG9wcyBpdC5gXG4gICAgICAgIDogYEFWRCBcIiR7YXZkTmFtZX1cIiBpcyBhbHJlYWR5IHJ1bm5pbmcgb24gZGV2aWNlICR7ZGV2aWNlSWR9LCByZXVzaW5nLmBcbiAgICApO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc3VwcHJlc3NFcnJvckRpYWxvZ3MoZGV2aWNlSWQpO1xuICAgICAgLypcbiAgICAgICAqIEEgcmV1c2VkIGRldmljZSBnZXRzIHRoZSBTQU1FIHNldHRsZSBnYXRlIGEgaGFybmVzcy1zdGFydGVkIG9uZSBnZXRzLlxuICAgICAgICogQXBwZWFyaW5nIGluIGBhZGIgZGV2aWNlc2Agc2F5cyBvbmx5IHRoYXQgYWRiZCBpcyB1cDogdGhlIGd1ZXN0IGNhblxuICAgICAgICogc3RpbGwgYmUgcnVubmluZyB0aGUgYm9vdCBhbmltYXRpb24gb3Igb3B0aW1pemluZyBwYWNrYWdlcywgYW5kIGFcbiAgICAgICAqIHNlc3Npb24gZXN0YWJsaXNoZWQgYWdhaW5zdCB0aGF0IGNvbnRlbmRzIHdpdGggdGhlIGNodXJuIGFuZCBpbmZsYXRlc1xuICAgICAgICogZXZlcnkgc3Vic2VxdWVudCByb3VuZC10cmlwIDI1LTUweCAoTDE5KS4gU2tpcHBpbmcgdGhlIGdhdGUgaGVyZSBpc1xuICAgICAgICogd2hhdCBsZXQgYSByZWxlYXNlIHByZWZsaWdodCBzcGVuZCBpdHMgd2hvbGUgbGF5b3V0LXJlYWR5IGJ1ZGdldCBvbiBhXG4gICAgICAgKiBoYW5kZnVsIG9mIGNvbnRlbmRlZCBwcm9iZXMgd2hpbGUgYGFkYiBkZXZpY2VzYCByZXBvcnRlZCBgZGV2aWNlYFxuICAgICAgICogdGhyb3VnaG91dC4gVGhlIHNhbWUgYXJndW1lbnQgYXBwbGllcyB0byB0aGUgbmV0d29yayBnYXRlOiBhIGRldmljZVxuICAgICAgICogdGhhdCBoYXMgYmVlbiB1cCBmb3Igc2Vjb25kcyBpcyBleGFjdGx5IG9uZSB3aXRoIG5vIHZhbGlkYXRlZCBuZXR3b3JrXG4gICAgICAgKiB5ZXQuXG4gICAgICAgKi9cbiAgICAgIGF3YWl0IHRoaXMud2FpdEZvckJvb3QoZGV2aWNlSWQsIERhdGUubm93KCkgKyBFTVVMQVRPUl9CT09UX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTLCB1bmRlZmluZWQpO1xuICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yRGV2aWNlUmVhZHkoZGV2aWNlSWQsIHRpbWVvdXRzKTtcbiAgICAgIGF3YWl0IHRoaXMud2FrZVNjcmVlbihkZXZpY2VJZCk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIEFzIHdpdGggYSBsYXVuY2ggdGhhdCBmYWlscyBpdHMgZ2F0ZXM6IGEgcmVqZWN0aW9uIGhlcmUgaGFuZHMgdGhlIGNhbGxlciBub3RoaW5nIHRvIHN0b3AuXG4gICAgICBpZiAob3duZWRFbXVsYXRvclBpZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCB0aGlzLmVtdWxhdG9ycy5zdG9wRW11bGF0b3IoeyBhdmROYW1lLCBkZXZpY2VJZCwgb3duZWRFbXVsYXRvclBpZHMgfSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICByZXR1cm4geyBhY3R1YWxEZXZpY2VJZDogZGV2aWNlSWQsIG93bmVkRW11bGF0b3JQaWRzIH07XG4gIH1cblxuICAvKipcbiAgICogUnVucyBvbmUgbGl2ZW5lc3MgcHJvYmUsIHJldHJ5aW5nIG9uY2UgYmVmb3JlIGNhbGxpbmcgaXQgc2lsZW5jZS5cbiAgICpcbiAgICogT25seSBzdWNjZXNzIGNvdW50cyBhcyBhbiBhbnN3ZXI6IGEgZmFpbGVkIGBhZGIgLi4uIGVtdWAgbWF5IGJlIHRoZSBhZGJcbiAgICogc2VydmVyIHJlZnVzaW5nIGFuIGBvZmZsaW5lYCBkZXZpY2UgcmF0aGVyIHRoYW4gdGhlIGNvbnNvbGUgYmVpbmcgZGVhZCwgYW5kXG4gICAqIHRoZSB0d28gYXJlIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gaGVyZSAoc2VlIGBlbXVsYXRvci1saXZlbmVzcy50c2ApLiBUaGVcbiAgICogc2luZ2xlIHJldHJ5IGlzIHRoZSBzYW1lIHJlc3RyYWludCBgcHJvYmVBdmROYW1lYCBhcHBsaWVzIGZvciB0aGUgc2FtZVxuICAgKiByZWFzb24gXHUyMDE0IGEgc2Vjb25kIGxvb2sgaXMgZmFyIGNoZWFwZXIgdGhhbiBhIHdyb25nIHZlcmRpY3QsIGFuZCB0aGlzIG9uZVxuICAgKiBkZWNpZGVzIHdoZXRoZXIgYSBydW4gaXMgYWJvcnRlZC5cbiAgICpcbiAgICogQHBhcmFtIGlucHV0IC0gVGhlIGFkYiBhcmd1bWVudHMuXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHByb2JlIGdvdCBhbiBhbnN3ZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJ1bkxpdmVuZXNzUHJvYmUoaW5wdXQ6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxFbXVsYXRvckxpdmVuZXNzUHJvYmVPdXRjb21lPiB7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gREVWSUNFX0xJVkVORVNTX0FUVEVNUFRfQ09VTlQ7IGF0dGVtcHQrKykge1xuICAgICAgY29uc3QgaXNBbnN3ZXJlZCA9IGF3YWl0IG5ldyBQcm9taXNlPGJvb2xlYW4+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGV4ZWNGaWxlKCdhZGInLCBbLi4uaW5wdXRdLCB7IHRpbWVvdXQ6IERFVklDRV9MSVZFTkVTU19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LCAoZXJyb3IpID0+IHtcbiAgICAgICAgICByZXNvbHZlKCFlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGlmIChpc0Fuc3dlcmVkKSB7XG4gICAgICAgIHJldHVybiAnYW5zd2VyZWQnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAnbm8tYW5zd2VyJztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEtleUV2ZW50KGRldmljZUlkOiBzdHJpbmcsIGtleUNvZGU6IG51bWJlciwgZGVzY3JpcHRpb246IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgJ2FkYicsXG4gICAgICAgIFsnLXMnLCBkZXZpY2VJZCwgJ3NoZWxsJywgJ2lucHV0JywgJ2tleWV2ZW50JywgU3RyaW5nKGtleUNvZGUpXSxcbiAgICAgICAgeyB0aW1lb3V0OiBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sXG4gICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgICAgIGBXYXJuaW5nOiBmYWlsZWQgdG8gJHtkZXNjcmlwdGlvbn0gKGtleWV2ZW50ICR7U3RyaW5nKGtleUNvZGUpfSk6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAndW5rbm93biBlcnJvcid9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHN0YXJ0QXBwaXVtQW5kRW11bGF0b3IocGFyYW1zOiBTdGFydEFwcGl1bUFuZEVtdWxhdG9yUGFyYW1zKTogUHJvbWlzZTxTdGFydEFwcGl1bUFuZEVtdWxhdG9yUmVzdWx0PiB7XG4gICAgY29uc3QgeyBhcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcywgYXBwaXVtVXJsLCBhdmROYW1lLCBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzLCBpc0FwcGl1bUNvbnNvbGVWaXNpYmxlLCBpc0VtdWxhdG9yVmlzaWJsZSwgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzLCBwb3J0LCBzaG91bGRBdXRvSW5zdGFsbEFwcGl1bURlcGVuZGVuY2llcywgc2hvdWxkQXV0b1N0YXJ0QXBwaXVtLCBzaG91bGRSZXVzZUVtdWxhdG9yU25hcHNob3QgfSA9IHBhcmFtcztcblxuICAgIGxldCBuZWVkc0FwcGl1bVN0YXJ0ID0gZmFsc2U7XG4gICAgbGV0IGFwcGl1bVNlcnZlck1hcmtlcjogQXBwaXVtU2VydmVyTWFya2VyIHwgdW5kZWZpbmVkO1xuXG4gICAgdGhpcy5sb2coYENoZWNraW5nIEFwcGl1bSBzZXJ2ZXIgYXQgJHthcHBpdW1VcmwuaHJlZn0uLi5gKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jaGVja0FwcGl1bVJlYWNoYWJsZShhcHBpdW1VcmwpO1xuICAgICAgYXBwaXVtU2VydmVyTWFya2VyID0gcmVhZEFwcGl1bVNlcnZlck1hcmtlcihwb3J0KTtcbiAgICAgIHRoaXMubG9nKGBBcHBpdW0gc2VydmVyIGlzIHJlYWNoYWJsZSAoJHt0aGlzLmRlc2NyaWJlQWRvcHRlZFNlcnZlcihhcHBpdW1TZXJ2ZXJNYXJrZXIpfSkuYCk7XG5cbiAgICAgIGlmIChhcHBpdW1TZXJ2ZXJNYXJrZXI/LnN0b3BBdHRlbXB0ZWRBdEluTWlsbGlzZWNvbmRzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbmVlZHNBcHBpdW1TdGFydCA9IGF3YWl0IHRoaXMucmVjbGFpbVVuc3RvcHBlZEFwcGl1bVNlcnZlcih7XG4gICAgICAgICAgbWFya2VyOiBhcHBpdW1TZXJ2ZXJNYXJrZXIsXG4gICAgICAgICAgcG9ydCxcbiAgICAgICAgICBzaG91bGRBdXRvU3RhcnRBcHBpdW0sXG4gICAgICAgICAgdXJsOiBhcHBpdW1VcmxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChuZWVkc0FwcGl1bVN0YXJ0KSB7XG4gICAgICAgICAgYXBwaXVtU2VydmVyTWFya2VyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGlmIChzaG91bGRBdXRvU3RhcnRBcHBpdW0gPT09IGZhbHNlKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbmVlZHNBcHBpdW1TdGFydCA9IHRydWU7XG4gICAgfVxuXG4gICAgbGV0IGFwcGl1bUxhdW5jaDogUHJvY2Vzc0xhdW5jaCB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChuZWVkc0FwcGl1bVN0YXJ0KSB7XG4gICAgICBpZiAoc2hvdWxkQXV0b0luc3RhbGxBcHBpdW1EZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVBcHBpdW1EZXBlbmRlbmNpZXMoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nKGBBcHBpdW0gbm90IHJlYWNoYWJsZSwgYXV0by1zdGFydGluZyBvbiBwb3J0ICR7U3RyaW5nKHBvcnQpfS4uLmApO1xuICAgICAgYXBwaXVtTGF1bmNoID0gdGhpcy5zdGFydEFwcGl1bVNlcnZlcihwb3J0LCBpc0FwcGl1bUNvbnNvbGVWaXNpYmxlKTtcbiAgICB9XG5cbiAgICBjb25zdCBhcHBpdW1Qcm9jZXNzID0gYXBwaXVtTGF1bmNoPy5wcm9jZXNzO1xuXG4gICAgLypcbiAgICAgKiBgYWxsU2V0dGxlZGAsIG5vdCBgYWxsYDogdGhlIHR3byBoYWx2ZXMgc3RhcnQgdG9nZXRoZXIsIHNvIGEgcmVqZWN0ZWRcbiAgICAgKiBBcHBpdW0gd2FpdCB1c2VkIHRvIGFiYW5kb24gYW4gZW11bGF0b3IgdGhhdCB3ZW50IG9uIHRvIGJvb3QgcGVyZmVjdGx5IFx1MjAxNFxuICAgICAqIHRoZSBsZWFrIHN1cnZpdmVkIHRoZSB2ZXJ5IHRlYXJkb3duIHRoYXQgd2FzIHN1cHBvc2VkIHRvIHByZXZlbnQgaXQsXG4gICAgICogYmVjYXVzZSB0aGUgZW11bGF0b3IncyBoYW5kbGUgb25seSBleGlzdHMgaW5zaWRlIHRoZSByZXN1bHQgYFByb21pc2UuYWxsYFxuICAgICAqIGRpc2NhcmRlZC4gQm90aCBvdXRjb21lcyBhcmUgY29sbGVjdGVkIHNvIGJvdGggY2FuIGJlIHN0b3BwZWQuXG4gICAgICovXG4gICAgY29uc3QgW2FwcGl1bU91dGNvbWUsIGRldmljZU91dGNvbWVdID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgIGFwcGl1bUxhdW5jaFxuICAgICAgICA/IHRoaXMud2FpdEZvckFwcGl1bVJlYWR5KGFwcGl1bVVybCwgYXBwaXVtU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMsIGFwcGl1bUxhdW5jaCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5sb2coJ0F1dG8tc3RhcnRlZCBBcHBpdW0gc2VydmVyIGlzIHJlYWR5LicpO1xuICAgICAgICB9KVxuICAgICAgICA6IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5lbnN1cmVEZXZpY2VDb25uZWN0ZWQoeyBhdmROYW1lLCBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzLCBpc0VtdWxhdG9yVmlzaWJsZSwgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzLCBzaG91bGRSZXVzZUVtdWxhdG9yU25hcHNob3QgfSlcbiAgICBdKTtcblxuICAgIGNvbnN0IGRldmljZVJlc3VsdCA9IGRldmljZU91dGNvbWUuc3RhdHVzID09PSAnZnVsZmlsbGVkJyA/IGRldmljZU91dGNvbWUudmFsdWUgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoYXBwaXVtT3V0Y29tZS5zdGF0dXMgPT09ICdyZWplY3RlZCcgfHwgZGV2aWNlUmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzVmVyaWZpZWQoe1xuICAgICAgICBhcHBpdW1Qcm9jZXNzLFxuICAgICAgICBhdmROYW1lLFxuICAgICAgICBkZXZpY2VJZDogZGV2aWNlUmVzdWx0Py5hY3R1YWxEZXZpY2VJZCxcbiAgICAgICAgZW11bGF0b3JQcm9jZXNzOiBkZXZpY2VSZXN1bHQ/LmVtdWxhdG9yUHJvY2VzcyxcbiAgICAgICAgb3duZWRFbXVsYXRvclBpZHM6IGRldmljZVJlc3VsdD8ub3duZWRFbXVsYXRvclBpZHMgPz8gW10sXG4gICAgICAgIHBvcnQsXG4gICAgICAgIHVybDogYXBwaXVtVXJsXG4gICAgICB9KTtcblxuICAgICAgdGhyb3cgZ2V0U2V0dGxlZEZhaWx1cmUoW2FwcGl1bU91dGNvbWUsIGRldmljZU91dGNvbWVdKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWN0dWFsRGV2aWNlSWQ6IGRldmljZVJlc3VsdC5hY3R1YWxEZXZpY2VJZCxcbiAgICAgIGFwcGl1bVByb2Nlc3MsXG4gICAgICBhcHBpdW1TZXJ2ZXJNYXJrZXIsXG4gICAgICBlbXVsYXRvckNhcHR1cmU6IGRldmljZVJlc3VsdC5lbXVsYXRvckNhcHR1cmUsXG4gICAgICBlbXVsYXRvclByb2Nlc3M6IGRldmljZVJlc3VsdC5lbXVsYXRvclByb2Nlc3MsXG4gICAgICBpc0Fkb3B0ZWRBcHBpdW1TZXJ2ZXI6ICFuZWVkc0FwcGl1bVN0YXJ0LFxuICAgICAgb3duZWRFbXVsYXRvclBpZHM6IGRldmljZVJlc3VsdC5vd25lZEVtdWxhdG9yUGlkc1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0QXBwaXVtU2VydmVyKHBvcnQ6IG51bWJlciwgaXNBcHBpdW1Db25zb2xlVmlzaWJsZT86IGJvb2xlYW4pOiBQcm9jZXNzTGF1bmNoIHtcbiAgICBjb25zdCBpc0NvbnNvbGVIaWRkZW4gPSBzaG91bGRIaWRlQXBwaXVtQ29uc29sZShpc0FwcGl1bUNvbnNvbGVWaXNpYmxlKTtcbiAgICBjb25zdCB7IGRldGFjaGVkLCB3aW5kb3dzSGlkZSB9ID0gcmVzb2x2ZUFwcGl1bVNwYXduRmxhZ3MoaXNDb25zb2xlSGlkZGVuKTtcbiAgICAvKlxuICAgICAqIGAtLW5vLWluc3RhbGxgOiBBcHBpdW0gaXMgZ3VhcmFudGVlZCBwcmVzZW50IGJ5IGBlbnN1cmVBcHBpdW1JbnN0YWxsZWRgXG4gICAgICogYmVmb3JlIHdlIHJlYWNoIGhlcmUsIHNvIHBpbiBucHggdG8gdGhlIGluc3RhbGxlZCBjb3B5LiBXaXRob3V0IGl0LCBucHhcbiAgICAgKiB3b3VsZCBzaWxlbnRseSB0cnkgdG8gZG93bmxvYWQgQXBwaXVtIGZyZXNoIGZyb20gdGhlIHJlZ2lzdHJ5IFx1MjAxNCBhXG4gICAgICogc2xvdy9odW5nIGZhaWx1cmUgaW4gYSBoaWRkZW4gY29uc29sZSBcdTIwMTQgd2hlbmV2ZXIgaXQgY291bGQgbm90IHJlc29sdmUgdGhlXG4gICAgICogZ2xvYmFsIGluc3RhbGwgKGUuZy4gYSBnbG9iYWwgcHJlZml4IG5vdCBvbiBQQVRIKS4gU2VlIGBlbnN1cmVBcHBpdW1JbnN0YWxsZWRgLlxuICAgICAqXG4gICAgICogUGlwZSBzdGRvdXQvc3RkZXJyIGV2ZW4gd2hlbiBoaWRkZW4gKHJhdGhlciB0aGFuIGRpc2NhcmRpbmcpIHNvIGFuIGVhcmx5XG4gICAgICogZmFpbHVyZSBzdWNoIGFzIGEgY3Jhc2ggb3IgYSBtaXNzaW5nIGRyaXZlciBpcyBjYXB0dXJlZCBhbmQgc3VyZmFjZWRcbiAgICAgKiBpbW1lZGlhdGVseSBieSBgd2FpdEZvckFwcGl1bVJlYWR5YCwgbWlycm9yaW5nIGBzdGFydEVtdWxhdG9yYDtcbiAgICAgKiBgd2luZG93c0hpZGVgIHN0aWxsIHN1cHByZXNzZXMgdGhlIGNvbnNvbGUgd2luZG93LlxuICAgICAqL1xuICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oYG5weCAtLW5vLWluc3RhbGwgYXBwaXVtIC0tbG9nLXRpbWVzdGFtcCAtLXBvcnQgJHtTdHJpbmcocG9ydCl9IC0tYWxsb3ctaW5zZWN1cmU9JHtDSFJPTUVEUklWRVJfQVVUT0RPV05MT0FEX0ZFQVRVUkV9YCwge1xuICAgICAgZGV0YWNoZWQsXG4gICAgICBzaGVsbDogdHJ1ZSxcbiAgICAgIHN0ZGlvOiBpc0NvbnNvbGVIaWRkZW4gPyBbJ2lnbm9yZScsICdwaXBlJywgJ3BpcGUnXSA6IFsnaWdub3JlJywgJ2luaGVyaXQnLCAnaW5oZXJpdCddLFxuICAgICAgd2luZG93c0hpZGVcbiAgICB9KTtcblxuICAgIGxldCBjYXB0dXJlZE91dHB1dCA9ICcnO1xuICAgIGxldCBleGl0SW5mbzogUHJvY2Vzc0V4aXRJbmZvIHwgdW5kZWZpbmVkO1xuICAgIGxldCBpc0NhcHR1cmluZyA9IHRydWU7XG5cbiAgICBjaGlsZC5zdGRvdXQ/Lm9uKCdkYXRhJywgYXBwZW5kT3V0cHV0KTtcbiAgICBjaGlsZC5zdGRlcnI/Lm9uKCdkYXRhJywgYXBwZW5kT3V0cHV0KTtcbiAgICBjaGlsZC5vbmNlKCdleGl0JywgKGNvZGUsIHNpZ25hbCkgPT4ge1xuICAgICAgZXhpdEluZm8gPSB7IGNvZGUsIHNpZ25hbCB9O1xuICAgIH0pO1xuICAgIGNoaWxkLm9uY2UoJ2Vycm9yJywgKGVycm9yKSA9PiB7XG4gICAgICBleGl0SW5mbyA9IHsgY29kZTogbnVsbCwgc2lnbmFsOiBudWxsLCBzcGF3bkVycm9yOiBlcnJvci5tZXNzYWdlIH07XG4gICAgfSk7XG5cbiAgICBjaGlsZC51bnJlZigpO1xuXG4gICAgLypcbiAgICAgKiBSZWNvcmQgdGhlIHNlcnZlciBhcyBvdXJzIGJlZm9yZSBhbnl0aGluZyBjYW4gYWRvcHQgaXQuIFRoZSBtYXJrZXIgaXMgd2hhdFxuICAgICAqIGxldHMgYSBsYXRlciBydW4gdGVsbCBpdHMgb3duIGxlZnRvdmVyIHNlcnZlciBmcm9tIGEgZm9yZWlnbiBvbmUsIGFuZCBzb1xuICAgICAqIHdoZXRoZXIgcmVzdGFydGluZyBhIHdlZGdlZCBzZXJ2ZXIgaXMgdGhpcyBoYXJuZXNzJ3MgY2FsbCB0byBtYWtlIFx1MjAxNCBzZWVcbiAgICAgKiBgYXBwaXVtLXNlcnZlci1tYXJrZXIudHNgLlxuICAgICAqL1xuICAgIGlmIChjaGlsZC5waWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgd3JpdGVBcHBpdW1TZXJ2ZXJNYXJrZXIoeyBwaWQ6IGNoaWxkLnBpZCwgcG9ydCB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJvY2VzczogY2hpbGQsXG4gICAgICByZWFkRXhpdEluZm86ICgpID0+IGV4aXRJbmZvLFxuICAgICAgcmVhZE91dHB1dDogKCkgPT4gY2FwdHVyZWRPdXRwdXQsXG4gICAgICBzdG9wQ2FwdHVyZTogKCk6IHZvaWQgPT4ge1xuICAgICAgICBpc0NhcHR1cmluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBhcHBlbmRPdXRwdXQoY2h1bms6IEJ1ZmZlcik6IHZvaWQge1xuICAgICAgaWYgKCFpc0NhcHR1cmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjYXB0dXJlZE91dHB1dCA9IChjYXB0dXJlZE91dHB1dCArIGNodW5rLnRvU3RyaW5nKCkpLnNsaWNlKC1BUFBJVU1fT1VUUFVUX1RBSUxfTUFYX0xFTkdUSCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGFydEVtdWxhdG9yKGF2ZE5hbWU6IHN0cmluZywgc2hvdWxkUmV1c2VTbmFwc2hvdDogYm9vbGVhbiwgaXNFbXVsYXRvclZpc2libGU/OiBib29sZWFuKTogUHJvY2Vzc0xhdW5jaCB7XG4gICAgY29uc3QgZW11bGF0b3JCaW5hcnkgPSByZXNvbHZlRW11bGF0b3JCaW5hcnlQYXRoKCk7XG4gICAgY29uc3QgaXNXaW5kb3dIaWRkZW4gPSBzaG91bGRIaWRlRW11bGF0b3JXaW5kb3coaXNFbXVsYXRvclZpc2libGUpO1xuICAgIGNvbnN0IGlucHV0ID0gYnVpbGRFbXVsYXRvckFyZ3VtZW50cyh7IGF2ZE5hbWUsIGlzSGlkZGVuOiBpc1dpbmRvd0hpZGRlbiwgc2hvdWxkUmV1c2VTbmFwc2hvdCB9KTtcbiAgICBjb25zdCB7IGRldGFjaGVkLCB3aW5kb3dzSGlkZSB9ID0gcmVzb2x2ZUVtdWxhdG9yU3Bhd25GbGFncyhpc1dpbmRvd0hpZGRlbik7XG4gICAgY29uc3QgeyBlbnZpcm9ubWVudCwgaXNOZXRzaW1Mb2dHdWFyZGVkIH0gPSBidWlsZEVtdWxhdG9yRW52aXJvbm1lbnQocHJvY2Vzcy5lbnYpO1xuICAgIHRoaXMubG9nKGBSdW5uaW5nOiAke2VtdWxhdG9yQmluYXJ5fSAke2lucHV0LmpvaW4oJyAnKX1gKTtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGlzTmV0c2ltTG9nR3VhcmRlZFxuICAgICAgICA/IGBuZXRzaW1kIGxvZyBsZXZlbDogUlVTVF9MT0c9JHtORVRTSU1fTE9HX0ZJTFRFUn0gKGtlZXBzIGl0cyB3aWZpLXN0YXRzIHdhcm5pbmcgZnJvbSBncm93aW5nIGl0cyBsb2cgd2l0aG91dCBib3VuZCkuYFxuICAgICAgICA6IGBuZXRzaW1kIGxvZyBsZXZlbDogUlVTVF9MT0c9JHtTdHJpbmcoZW52aXJvbm1lbnRbJ1JVU1RfTE9HJ10pfSwgc2V0IGJ5IHRoZSBjYWxsZXIgXHUyMDE0IHRoZSBoYXJuZXNzJ3MgYm91bmRlZCBkZWZhdWx0IGlzIG9mZiwgYW5kIG5ldHNpbWQncyBsb2cgY2FuIGdyb3cgd2l0aG91dCBib3VuZC5gXG4gICAgKTtcbiAgICAvKlxuICAgICAqIFBpcGUgKHJhdGhlciB0aGFuIGlnbm9yZSkgc3Rkb3V0L3N0ZGVyciBzbyBhbiBlYXJseSBmYWlsdXJlIHN1Y2ggYXNcbiAgICAgKiBcIng4Nl82NCBlbXVsYXRpb24gY3VycmVudGx5IHJlcXVpcmVzIGhhcmR3YXJlIGFjY2VsZXJhdGlvblwiIGNhbiBiZVxuICAgICAqIHN1cmZhY2VkIGltbWVkaWF0ZWx5IGluc3RlYWQgb2Ygd2FpdGluZyBvdXQgdGhlIGZ1bGwgYm9vdCB0aW1lb3V0LlxuICAgICAqL1xuICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oZW11bGF0b3JCaW5hcnksIGlucHV0LCB7XG4gICAgICBkZXRhY2hlZCxcbiAgICAgIGVudjogZW52aXJvbm1lbnQsXG4gICAgICBzdGRpbzogWydpZ25vcmUnLCAncGlwZScsICdwaXBlJ10sXG4gICAgICB3aW5kb3dzSGlkZVxuICAgIH0pO1xuXG4gICAgbGV0IGNhcHR1cmVkT3V0cHV0ID0gJyc7XG4gICAgbGV0IGV4aXRJbmZvOiBQcm9jZXNzRXhpdEluZm8gfCB1bmRlZmluZWQ7XG4gICAgbGV0IGlzQ2FwdHVyaW5nID0gdHJ1ZTtcblxuICAgIGNoaWxkLnN0ZG91dC5vbignZGF0YScsIGFwcGVuZE91dHB1dCk7XG4gICAgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgYXBwZW5kT3V0cHV0KTtcbiAgICBjaGlsZC5vbmNlKCdleGl0JywgKGNvZGUsIHNpZ25hbCkgPT4ge1xuICAgICAgZXhpdEluZm8gPSB7IGNvZGUsIHNpZ25hbCB9O1xuICAgIH0pO1xuICAgIC8qXG4gICAgICogQSBzcGF3biBmYWlsdXJlIChlLmcuIEVOT0VOVCBmb3IgYSBtaXNzaW5nL2Jyb2tlbiBlbXVsYXRvciBiaW5hcnkpIGVtaXRzXG4gICAgICogJ2Vycm9yJywgbm90ICdleGl0Jy4gUmVjb3JkIGl0IGFzIGEgc3ludGhldGljIGV4aXQgc28gdGhlIGJvb3QvbmV3LWRldmljZVxuICAgICAqIHBvbGxzIGZhaWwgZmFzdCBpbnN0ZWFkIG9mIHNwaW5uaW5nIG91dCB0aGUgZnVsbCBib290IHRpbWVvdXQuXG4gICAgICovXG4gICAgY2hpbGQub25jZSgnZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgIGV4aXRJbmZvID0geyBjb2RlOiBudWxsLCBzaWduYWw6IG51bGwsIHNwYXduRXJyb3I6IGVycm9yLm1lc3NhZ2UgfTtcbiAgICB9KTtcblxuICAgIGNoaWxkLnVucmVmKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJvY2VzczogY2hpbGQsXG4gICAgICByZWFkRXhpdEluZm86ICgpID0+IGV4aXRJbmZvLFxuICAgICAgcmVhZE91dHB1dDogKCkgPT4gY2FwdHVyZWRPdXRwdXQsXG4gICAgICBzdG9wQ2FwdHVyZTogKCk6IHZvaWQgPT4ge1xuICAgICAgICAvKlxuICAgICAgICAgKiBMZWF2ZSB0aGUgYGRhdGFgIGxpc3RlbmVycyBhdHRhY2hlZCBzbyB0aGUgcGlwZXMga2VlcCBkcmFpbmluZyAoYVxuICAgICAgICAgKiBmdWxsIE9TIHBpcGUgYnVmZmVyIHdvdWxkIGJsb2NrIHRoZSBsb25nLXJ1bm5pbmcgZW11bGF0b3IpOyB0aGUgZmxhZ1xuICAgICAgICAgKiBqdXN0IGZyZWV6ZXMgdGhlIGNhcHR1cmVkIHRhaWwgb25jZSBzdGFydHVwIGhhcyBzdWNjZWVkZWQuXG4gICAgICAgICAqL1xuICAgICAgICBpc0NhcHR1cmluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBhcHBlbmRPdXRwdXQoY2h1bms6IEJ1ZmZlcik6IHZvaWQge1xuICAgICAgaWYgKCFpc0NhcHR1cmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjYXB0dXJlZE91dHB1dCA9IChjYXB0dXJlZE91dHB1dCArIGNodW5rLnRvU3RyaW5nKCkpLnNsaWNlKC1FTVVMQVRPUl9PVVRQVVRfVEFJTF9NQVhfTEVOR1RIKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGlzYWJsZXMgdGhlIGd1ZXN0J3MgY3Jhc2gvQU5SIGRpYWxvZ3Mgb24gdGhlIGdpdmVuIGRldmljZS5cbiAgICpcbiAgICogQSByZXNvdXJjZS1zdGFydmVkIGVtdWxhdG9yIGNhbiByYWlzZSBhIFwiUHJvY2VzcyBzeXN0ZW0gaXNuJ3QgcmVzcG9uZGluZ1wiXG4gICAqIEFOUiAoYW4gYEFjdGl2aXR5TWFuYWdlclNlcnZpY2VgIHRpbWVvdXQpIHdob3NlIGRpYWxvZyBvdmVybGF5cyB0aGUgVUkuIElmXG4gICAqIGl0IGFwcGVhcnMgYmVmb3JlIEFwcGl1bSBhdHRhY2hlcywgbm90aGluZyBjYW4gZGlzbWlzcyBpdCBhbmQgdGhlIHJ1biBoYW5nc1xuICAgKiBvciBmYWlscyBpbnRlcm1pdHRlbnRseS4gU2V0dGluZyB0aGUgYGhpZGVfZXJyb3JfZGlhbG9nc2AgZ2xvYmFsIFx1MjAxNCB0aGUgc2FtZVxuICAgKiBmbGFnIEFuZHJvaWQncyBvd24gdGVzdCBpbmZyYSB1c2VzIFx1MjAxNCB0ZWxscyBgQWN0aXZpdHlNYW5hZ2VyU2VydmljZWAgdG9cbiAgICogbmV2ZXIgZHJhdyBjcmFzaC9BTlIgZGlhbG9ncywgc28gdGhlIEFOUiBjYW4gbm8gbG9uZ2VyIGJsb2NrIGF1dG9tYXRpb24uXG4gICAqXG4gICAqIFRoaXMgaXMgdGhlIGVhcmxpZXN0IHBvaW50IGF0IHdoaWNoIHRoZSBmbGFnIGNhbiBiZSBzZXQ6IHRoZSBmcmFtZXdvcmtcbiAgICogKGBzeXN0ZW1fc2VydmVyYCkgbXVzdCBiZSB1cCBiZWZvcmUgYHNldHRpbmdzIHB1dGAgd29ya3MsIHNvIGNhbGxlcnMgaW52b2tlXG4gICAqIGl0IG9ubHkgYWZ0ZXIgYHN5cy5ib290X2NvbXBsZXRlZGAuIEl0IG5hcnJvd3MgXHUyMDE0IGJ1dCBjYW5ub3QgZnVsbHkgY2xvc2UgXHUyMDE0XG4gICAqIHRoZSByYWNlIHdpdGggYW4gQU5SIHRoYXQgZmlyZXMgYmV0d2VlbiBib290IGNvbXBsZXRpbmcgYW5kIHRoaXMgY2FsbDsgYVxuICAgKiBwcmUtYmFrZWQgc25hcHNob3Qgd2l0aCB0aGUgZmxhZyBhbHJlYWR5IHNldCBpcyB0aGUgb25seSB3YXkgdG8gZWxpbWluYXRlXG4gICAqIGl0IGVudGlyZWx5LiBCZXN0LWVmZm9ydDogYSBmYWlsdXJlIGlzIGxvZ2dlZCwgbm90IHRocm93biwgc2luY2UgaXQgb25seVxuICAgKiBzdXBwcmVzc2VzIGEgc3ltcHRvbS5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSBVRElEIHRvIGNvbmZpZ3VyZS5cbiAgICovXG4gIC8qKlxuICAgKiBTdG9wcyB0aGUgQXBwaXVtIHNlcnZlciB0aGlzIHJ1biBzdGFydGVkLCBhbmQgKip2ZXJpZmllcyoqIGl0IHN0b3BwZWQuXG4gICAqXG4gICAqIFRoZSBwb3J0IGlzIHRoZSB2ZXJkaWN0OiBhIHNvY2tldCBzdGlsbCBhbnN3ZXJpbmcgYC9zdGF0dXNgIGFmdGVyIHRoZSBraWxsXG4gICAqIGlzIHRoZSBzZXJ2ZXIsIHdoYXRldmVyIHRoZSBQSUQgdGFibGUgc2F5cy4gV2hlbiBpdCBpcyBzdGlsbCB0aGVyZSB0aGVcbiAgICogbGlzdGVuZXIgaXMga2lsbGVkIGJ5IHBvcnQgb3duZXJzaGlwIFx1MjAxNCB0aGUgb25seSBlc2NhbGF0aW9uIHRoYXQgbWVhbnNcbiAgICogYW55dGhpbmcsIHNpbmNlIHJlLWtpbGxpbmcgdGhlIHNoZWxsIHdyYXBwZXIncyBQSUQgd291bGQganVzdCByZXBlYXQgdGhlXG4gICAqIGtpbGwgdGhhdCBhbHJlYWR5IGZhaWxlZC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzZXJ2ZXIgcHJvY2VzcywgaXRzIHBvcnQgYW5kIGl0cyBVUkwuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN0b3BBdXRvU3RhcnRlZEFwcGl1bVNlcnZlcihwYXJhbXM6IFN0b3BBdXRvU3RhcnRlZEFwcGl1bVNlcnZlclBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGtpbGxQcm9jZXNzVHJlZShwYXJhbXMuYXBwaXVtUHJvY2Vzcyk7XG5cbiAgICBsZXQgaGFzRXNjYWxhdGVkID0gZmFsc2U7XG4gICAgbGV0IGlzU3RvcHBlZCA9IGF3YWl0IHRoaXMuY2hlY2tJc0FwcGl1bVN0b3BwZWQocGFyYW1zLnVybCwgQVBQSVVNX1NUT1BfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMpO1xuXG4gICAgaWYgKCFpc1N0b3BwZWQpIHtcbiAgICAgIGNvbnN0IG93bmVyUGlkcyA9IGF3YWl0IHRoaXMubGlzdFBvcnRPd25lclBpZHMocGFyYW1zLnBvcnQpO1xuICAgICAgaWYgKG93bmVyUGlkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGhhc0VzY2FsYXRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgIGBBdXRvLXN0YXJ0ZWQgQXBwaXVtIHNlcnZlciBzdGlsbCBhbnN3ZXJzIG9uICR7cGFyYW1zLnVybC5vcmlnaW59IGFmdGVyIGl0cyBwcm9jZXNzIHRyZWUgd2FzIGtpbGxlZDsgZXNjYWxhdGluZyB0byB0aGUgUElEKHMpIGhvbGRpbmcgdGhlIHBvcnQ6IFske293bmVyUGlkcy5qb2luKCcsICcpfV0uYFxuICAgICAgICApO1xuICAgICAgICBmb3IgKGNvbnN0IHBpZCBvZiBvd25lclBpZHMpIHtcbiAgICAgICAgICBraWxsUHJvY2Vzc1RyZWVCeVBpZChwaWQpO1xuICAgICAgICB9XG4gICAgICAgIGlzU3RvcHBlZCA9IGF3YWl0IHRoaXMuY2hlY2tJc0FwcGl1bVN0b3BwZWQocGFyYW1zLnVybCwgQVBQSVVNX0VTQ0FMQVRFRF9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxvZyhidWlsZFRlYXJkb3duTWVzc2FnZSh7XG4gICAgICBldmlkZW5jZTogYHBvcnQgJHtTdHJpbmcocGFyYW1zLnBvcnQpfWAsXG4gICAgICBvdXRjb21lOiByZXNvbHZlVGVhcmRvd25PdXRjb21lKHsgaGFzRXNjYWxhdGVkLCBpc1N0b3BwZWQgfSksXG4gICAgICBzdWJqZWN0OiAnQXV0by1zdGFydGVkIEFwcGl1bSBzZXJ2ZXInLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBBUFBJVU1fU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH0pKTtcblxuICAgIGlmIChpc1N0b3BwZWQpIHtcbiAgICAgIC8vIERyb3AgdGhlIG1hcmtlciB3aXRoIHRoZSBzZXJ2ZXIgaXQgZGVzY3JpYmVzLCBzbyB0aGUgbmV4dCBydW4gY2Fubm90IG1pc3Rha2UgYSByZWN5Y2xlZCBQSUQgZm9yIG91cnMuXG4gICAgICBjbGVhckFwcGl1bVNlcnZlck1hcmtlcihwYXJhbXMucG9ydCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gS2VlcCB0aGUgbWFya2VyLCBzdGFtcGVkOiBhIGxlZnRvdmVyIHdlIGNvdWxkIG5vdCBraWxsIG11c3Qgc3RheSBjb252aWN0YWJsZSBieSB0aGUgbmV4dCBydW4uXG4gICAgcmVjb3JkQXBwaXVtU2VydmVyU3RvcEF0dGVtcHQocGFyYW1zLnBvcnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJlc3QtZWZmb3J0IHRlYXJkb3duIGZvciBgcHJvY2Vzcy5vbignZXhpdCcpYCwgd2hpY2ggY2Fubm90IGF3YWl0LlxuICAgKlxuICAgKiBJdCBraWxscywgbG9va3Mgb25jZSBmb3IgYSBzdXJ2aXZvciBzdGlsbCBob2xkaW5nIHRoZSBBcHBpdW0gcG9ydCBvciBhXG4gICAqIHN0aWxsLWxpdmUgZW11bGF0b3IgUElELCBraWxscyB0aG9zZSB0b28gXHUyMDE0IGFuZCB0aGVuIHNheXMgZXhhY3RseSB0aGF0LiBJdFxuICAgKiBuZXZlciBjbGFpbXMgYSB2ZXJpZmllZCBzdG9wLCBiZWNhdXNlIGl0IGNhbm5vdCB3YWl0IHRvIGVhcm4gb25lLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gRXZlcnl0aGluZyB0aGlzIHJ1biBzdGFydGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBzdG9wQXV0b1N0YXJ0ZWRQcm9jZXNzZXNCZXN0RWZmb3J0KHBhcmFtczogU3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzUGFyYW1zKTogdm9pZCB7XG4gICAgaWYgKHBhcmFtcy5hcHBpdW1Qcm9jZXNzKSB7XG4gICAgICBraWxsUHJvY2Vzc1RyZWUocGFyYW1zLmFwcGl1bVByb2Nlc3MpO1xuICAgICAgY29uc3Qgb3duZXJQaWRzID0gdGhpcy5saXN0UG9ydE93bmVyUGlkc1N5bmMocGFyYW1zLnBvcnQpO1xuICAgICAgZm9yIChjb25zdCBwaWQgb2Ygb3duZXJQaWRzKSB7XG4gICAgICAgIGtpbGxQcm9jZXNzVHJlZUJ5UGlkKHBpZCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvd25lclBpZHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICBgQXV0by1zdGFydGVkIEFwcGl1bSBzZXJ2ZXI6IHN0b3AgcmVxdWVzdGVkIGFuZCBQSUQocykgWyR7b3duZXJQaWRzLmpvaW4oJywgJyl9XSBob2xkaW5nIHBvcnQgJHtTdHJpbmcocGFyYW1zLnBvcnQpfSBraWxsZWQgXHUyMDE0IHN5bmMgdGVhcmRvd24gY2Fubm90IHdhaXQgdG8gY29uZmlybS5gXG4gICAgICAgICk7XG4gICAgICAgIHJlY29yZEFwcGl1bVNlcnZlclN0b3BBdHRlbXB0KHBhcmFtcy5wb3J0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nKGBBdXRvLXN0YXJ0ZWQgQXBwaXVtIHNlcnZlcjogc3RvcCByZXF1ZXN0ZWQsIG5vdGhpbmcgbGVmdCBsaXN0ZW5pbmcgb24gcG9ydCAke1N0cmluZyhwYXJhbXMucG9ydCl9LmApO1xuICAgICAgICBjbGVhckFwcGl1bVNlcnZlck1hcmtlcihwYXJhbXMucG9ydCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMuZW11bGF0b3JQcm9jZXNzICYmIHBhcmFtcy5vd25lZEVtdWxhdG9yUGlkcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmVtdWxhdG9yUHJvY2Vzcykge1xuICAgICAga2lsbFByb2Nlc3NUcmVlKHBhcmFtcy5lbXVsYXRvclByb2Nlc3MpO1xuICAgIH1cbiAgICBjb25zdCBzdXJ2aXZpbmdQaWRzID0gcGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLmZpbHRlcigocGlkKSA9PiBjaGVja0lzUHJvY2Vzc0FsaXZlKHBpZCkpO1xuICAgIGZvciAoY29uc3QgcGlkIG9mIHN1cnZpdmluZ1BpZHMpIHtcbiAgICAgIGtpbGxQcm9jZXNzVHJlZUJ5UGlkKHBpZCk7XG4gICAgfVxuXG4gICAgaWYgKHN1cnZpdmluZ1BpZHMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gS2VlcCB0aGUgbWFya2VyOiBub3RoaW5nIGhlcmUgd2FpdGVkIHRvIHNlZSB0aGVzZSBkaWUsIHNvIHRoZSBuZXh0IHJ1biBtdXN0IHN0aWxsIGJlIGFibGUgdG8gY29udmljdCB0aGVtLlxuICAgICAgdGhpcy5sb2coXG4gICAgICAgIGBBdXRvLXN0YXJ0ZWQgZW11bGF0b3I6IHN0b3AgcmVxdWVzdGVkIGFuZCBzdXJ2aXZpbmcgZW11bGF0b3IgUElEKHMpIFske3N1cnZpdmluZ1BpZHMuam9pbignLCAnKX1dIGtpbGxlZCBcdTIwMTQgc3luYyB0ZWFyZG93biBjYW5ub3Qgd2FpdCB0byBjb25maXJtLmBcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nKCdBdXRvLXN0YXJ0ZWQgZW11bGF0b3I6IHN0b3AgcmVxdWVzdGVkLCBubyBwcm9jZXNzIG9mIHRoaXMgcnVuIGxlZnQgcnVubmluZy4nKTtcbiAgICAgIGNsZWFyRW11bGF0b3JNYXJrZXJJZlN0b3BwZWQocGFyYW1zLmF2ZE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyBldmVyeXRoaW5nIHRoaXMgcnVuIGF1dG8tc3RhcnRlZCwgdmVyaWZ5aW5nIGVhY2ggc3RvcC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIEV2ZXJ5dGhpbmcgdGhpcyBydW4gc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzVmVyaWZpZWQocGFyYW1zOiBTdG9wQXV0b1N0YXJ0ZWRQcm9jZXNzZXNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpc0VtdWxhdG9yT3duZWQgPSBwYXJhbXMuZW11bGF0b3JQcm9jZXNzICE9PSB1bmRlZmluZWQgfHwgcGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLmxlbmd0aCA+IDA7XG4gICAgaWYgKCFwYXJhbXMuYXBwaXVtUHJvY2VzcyAmJiAhaXNFbXVsYXRvck93bmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sb2coJ1N0b3BwaW5nIGV2ZXJ5dGhpbmcgdGhpcyBydW4gYXV0by1zdGFydGVkLi4uJyk7XG5cbiAgICBpZiAocGFyYW1zLmFwcGl1bVByb2Nlc3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RvcEF1dG9TdGFydGVkQXBwaXVtU2VydmVyKHtcbiAgICAgICAgYXBwaXVtUHJvY2VzczogcGFyYW1zLmFwcGl1bVByb2Nlc3MsXG4gICAgICAgIHBvcnQ6IHBhcmFtcy5wb3J0LFxuICAgICAgICB1cmw6IHBhcmFtcy51cmxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChpc0VtdWxhdG9yT3duZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW11bGF0b3JzLnN0b3BFbXVsYXRvcih7XG4gICAgICAgIGF2ZE5hbWU6IHBhcmFtcy5hdmROYW1lLFxuICAgICAgICBkZXZpY2VJZDogcGFyYW1zLmRldmljZUlkLFxuICAgICAgICBlbXVsYXRvclByb2Nlc3M6IHBhcmFtcy5lbXVsYXRvclByb2Nlc3MsXG4gICAgICAgIG93bmVkRW11bGF0b3JQaWRzOiBwYXJhbXMub3duZWRFbXVsYXRvclBpZHNcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyBhbiBlbXVsYXRvciB0aGlzIHJ1biBsYXVuY2hlZCB3aG9zZSBzdGFydCBmYWlsZWQgYmVmb3JlIGl0IGNvdWxkIGJlXG4gICAqIGhhbmRlZCBiYWNrIFx1MjAxNCB0aGUgYm9vdCwgaWRsZSBvciBuZXR3b3JrIHdhaXQgZ2F2ZSB1cCBvbiBpdCwgb3IgaXQgbmV2ZXJcbiAgICogcHJvZHVjZWQgYSBkZXZpY2UgYXQgYWxsLlxuICAgKlxuICAgKiBUaGUgUElEcyBjb21lIGZyb20gdGhlIHNhbWUgcHJlLWxhdW5jaCBzbmFwc2hvdCBhIHN1Y2Nlc3NmdWwgc3RhcnQgdXNlcy4gVGhlXG4gICAqIGRldmljZSBpcyB3aGljaGV2ZXIgZW11bGF0b3IgYXBwZWFyZWQgYWNyb3NzIHRoZSBsYXVuY2gsIGluIGFueSBzdGF0ZTsgd2hlblxuICAgKiB0aGF0IGlzIG5vdCBleGFjdGx5IG9uZSwgdGhlIHN0b3AgZ29lcyBieSBQSURzIGFsb25lIHJhdGhlciB0aGFuIGd1ZXNzLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGxhdW5jaCwgYW5kIHdoYXQgcHJlZGF0ZWQgaXQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN0b3BFbXVsYXRvckFmdGVyRmFpbGVkU3RhcnQocGFyYW1zOiBTdG9wRW11bGF0b3JBZnRlckZhaWxlZFN0YXJ0UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgb3duZWRFbXVsYXRvclBpZHMgPSBhd2FpdCB0aGlzLmxpc3RFbXVsYXRvckJhY2tlbmRQaWRzKHBhcmFtcy5lbXVsYXRvclBpZHNCZWZvcmUpO1xuICAgIGxldCBuZXdEZXZpY2VJZHM6IHN0cmluZ1tdID0gW107XG4gICAgdHJ5IHtcbiAgICAgIG5ld0RldmljZUlkcyA9IHBhcnNlQWRiRGV2aWNlcyhhd2FpdCB0aGlzLmVtdWxhdG9ycy5nZXREZXZpY2VzT3V0cHV0KCkpXG4gICAgICAgIC5tYXAoKGVudHJ5KSA9PiBlbnRyeS5kZXZpY2VJZClcbiAgICAgICAgLmZpbHRlcigoZGV2aWNlSWQpID0+IGNoZWNrSXNFbXVsYXRvckRldmljZUlkKGRldmljZUlkKSAmJiAhcGFyYW1zLmRldmljZUlkc0JlZm9yZS5pbmNsdWRlcyhkZXZpY2VJZCkpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICB0aGlzLmxvZyhgQ291bGQgbm90IGxpc3QgZGV2aWNlcyB3aGlsZSBzdG9wcGluZyB0aGUgZmFpbGVkIGVtdWxhdG9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG5cbiAgICB0aGlzLmxvZyhgRW11bGF0b3IgXCIke3BhcmFtcy5hdmROYW1lfVwiIGZhaWxlZCB0byBzdGFydDsgc3RvcHBpbmcgaXQgKG93bmVkIGVtdWxhdG9yIFBJRHM6IFske293bmVkRW11bGF0b3JQaWRzLmpvaW4oJywgJyl9XSkuYCk7XG4gICAgYXdhaXQgdGhpcy5lbXVsYXRvcnMuc3RvcEVtdWxhdG9yKHtcbiAgICAgIGF2ZE5hbWU6IHBhcmFtcy5hdmROYW1lLFxuICAgICAgZGV2aWNlSWQ6IG5ld0RldmljZUlkcy5sZW5ndGggPT09IDEgPyBuZXdEZXZpY2VJZHNbMF0gOiB1bmRlZmluZWQsXG4gICAgICBlbXVsYXRvclByb2Nlc3M6IHBhcmFtcy5lbXVsYXRvci5wcm9jZXNzLFxuICAgICAgb3duZWRFbXVsYXRvclBpZHNcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc3VwcHJlc3NFcnJvckRpYWxvZ3MoZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nKGBEaXNhYmxpbmcgY3Jhc2gvQU5SIGRpYWxvZ3Mgb24gZGV2aWNlICR7ZGV2aWNlSWR9IChzZXR0aW5ncyBwdXQgZ2xvYmFsIGhpZGVfZXJyb3JfZGlhbG9ncyAxKS4uLmApO1xuXG4gICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgIGV4ZWNGaWxlKFxuICAgICAgICAnYWRiJyxcbiAgICAgICAgWyctcycsIGRldmljZUlkLCAnc2hlbGwnLCAnc2V0dGluZ3MnLCAncHV0JywgJ2dsb2JhbCcsICdoaWRlX2Vycm9yX2RpYWxvZ3MnLCAnMSddLFxuICAgICAgICB7IHRpbWVvdXQ6IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSxcbiAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICAgICAgYFdhcm5pbmc6IGZhaWxlZCB0byBkaXNhYmxlIGNyYXNoL0FOUiBkaWFsb2dzOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ3Vua25vd24gZXJyb3InfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGB0ZW1wLXZhdWx0LSpgIGRpcmVjdG9yaWVzIGVhcmxpZXIgcnVucyBsZWZ0IG9uIHRoZSBkZXZpY2UuXG4gICAqXG4gICAqIFJ1bnMgKipiZWZvcmUqKiBgcmVtb3RlKClgIGxhdW5jaGVzIE9ic2lkaWFuIFx1MjAxNCB0aGUgbGFzdCBtb21lbnQgYXQgd2hpY2hcbiAgICogbm90aGluZyBoYXMgdG8gZW51bWVyYXRlIHRoZSBkZXZpY2UncyB2YXVsdHMgeWV0LCBhbmQgdGhlIG9ubHkgc3dlZXAgdGhhdFxuICAgKiBkb2VzIG5vdCBkZXBlbmQgb24gYSBoZWFsdGh5IFdlYlZpZXcuIFRoYXQgaW5kZXBlbmRlbmNlIGlzIHRoZSB3aG9sZSBwb2ludDpcbiAgICogYSBydW4gd2hvc2UgV2ViVmlldyBkaWVkIGNhbm5vdCB1bnJlZ2lzdGVyIG9yIGRlbGV0ZSBpdHMgb3duIHZhdWx0LCBzb1xuICAgKiB3aXRob3V0IHRoaXMgZWFjaCBmYWlsdXJlIGxlYXZlcyByZXNpZHVlIHRoYXQgc2xvd3MgdGhlIG5leHQgcnVuJ3Mgc3RhcnR1cFxuICAgKiBlbnVtZXJhdGlvbiBhbmQgbWFrZXMgdGhlIG5leHQgZmFpbHVyZSBsaWtlbGllci5cbiAgICpcbiAgICogVW5jb25kaXRpb25hbCAobm8gYWdlIGdhdGUpIFx1MjAxNCBBbmRyb2lkIHJ1bnMgaG9sZCB0aGUgZXhjbHVzaXZlIGBhbmRyb2lkYFxuICAgKiBzZXR1cCBsb2NrLCBzbyBubyBjb25jdXJyZW50IHJ1biBjYW4gb3duIGEgZGV2aWNlIHZhdWx0LCBhbmQgYW4gYWdlIGdhdGVcbiAgICogd291bGQgbGV0IGEgdmF1bHQgbGVha2VkIG1pbnV0ZXMgYWdvIHN1cnZpdmUgaW50byB0aGlzIHJ1bi4gQmVzdC1lZmZvcnQ6IGFcbiAgICogZmFpbHVyZSBpcyBsb2dnZWQsIG5vdCB0aHJvd24uXG4gICAqXG4gICAqIFRoZSByZW1vdmFscyBnbyBvbmUgZGlyZWN0b3J5IGF0IGEgdGltZSBhbmQgdGhlIG91dGNvbWUgaXMgcmUtbGlzdGVkIHJhdGhlclxuICAgKiB0aGFuIGluZmVycmVkOyB7QGxpbmsgc3dlZXBEZXZpY2VMZWZ0b3ZlcnN9IGV4cGxhaW5zIHdoeS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBkZXZpY2UgYW5kIHZhdWx0IGJhc2UgcGF0aCB0byBzd2VlcC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc3dlZXBEZXZpY2VMZWZ0b3ZlclZhdWx0cyhwYXJhbXM6IFN3ZWVwRGV2aWNlTGVmdG92ZXJWYXVsdHNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGRldmljZUlkLCB2YXVsdEJhc2VQYXRoIH0gPSBwYXJhbXM7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3dlZXBEZXZpY2VMZWZ0b3ZlcnMoe1xuICAgICAgICBsaXN0TmFtZXM6IGFzeW5jICgpOiBQcm9taXNlPHN0cmluZ1tdPiA9PiB7XG4gICAgICAgICAgY29uc3QgbGlzdGluZyA9IGF3YWl0IGV4ZWMoXG4gICAgICAgICAgICBbJ2FkYicsICctcycsIGRldmljZUlkLCAnc2hlbGwnLCAnbHMnLCAnLTEnLCB2YXVsdEJhc2VQYXRoXSxcbiAgICAgICAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX1ZBVUxUX1NXRUVQX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBsaXN0aW5nLnNwbGl0KCdcXG4nKTtcbiAgICAgICAgfSxcbiAgICAgICAgcmVtb3ZlRGlyZWN0b3J5OiBhc3luYyAocGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgYXdhaXQgZXhlYyhcbiAgICAgICAgICAgIFsnYWRiJywgJy1zJywgZGV2aWNlSWQsICdzaGVsbCcsICdybScsICctcmYnLCBwYXRoXSxcbiAgICAgICAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX1ZBVUxUX1NXRUVQX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgICB2YXVsdEJhc2VQYXRoXG4gICAgICB9KTtcblxuICAgICAgaWYgKHJlc3VsdC5yZW1vdmVkQ291bnQgPT09IDAgJiYgcmVzdWx0LmZhaWxlZE5hbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmxvZyhgTm8gbGVmdG92ZXIgdGVtcCB2YXVsdHMgb24gZGV2aWNlICR7ZGV2aWNlSWR9LmApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMubG9nKGBSZW1vdmVkICR7U3RyaW5nKHJlc3VsdC5yZW1vdmVkQ291bnQpfSBsZWZ0b3ZlciB0ZW1wIHZhdWx0KHMpIGZyb20gJHt2YXVsdEJhc2VQYXRofSBvbiBkZXZpY2UgJHtkZXZpY2VJZH0uYCk7XG5cbiAgICAgIGlmIChyZXN1bHQuZmFpbGVkTmFtZXMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICBgV2FybmluZzogJHtTdHJpbmcocmVzdWx0LmZhaWxlZE5hbWVzLmxlbmd0aCl9IGxlZnRvdmVyIHRlbXAgdmF1bHQocykgY291bGQgbm90IGJlIHJlbW92ZWQgYW5kIHdpbGwgYmUgcmV0cmllZCBuZXh0IHJ1bjogJHtyZXN1bHQuZmFpbGVkTmFtZXMuam9pbignLCAnKX1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIHRoaXMubG9nKGBXYXJuaW5nOiBmYWlsZWQgdG8gc3dlZXAgbGVmdG92ZXIgdGVtcCB2YXVsdHM6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAndW5rbm93biBlcnJvcid9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRha2VzIG92ZXIgdGhlIHJ1bm5pbmcgZW11bGF0b3Igb2YgYW4gQVZEIHdoZW4gaXQgaXMgYSBsZWZ0b3ZlciB0aGlzIGhhcm5lc3NcbiAgICogc3RhcnRlZCwgc28gdGhpcyBydW4gYmVjb21lcyB0aGUgb25lIHJlc3BvbnNpYmxlIGZvciBzdG9wcGluZyBpdC5cbiAgICpcbiAgICogQHBhcmFtIGF2ZE5hbWUgLSBUaGUgQVZEIHRoZSBkZXZpY2UgaXMgc2VydmluZy5cbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSBzZXJ2aW5nIGl0LlxuICAgKiBAcmV0dXJucyBUaGUgZW11bGF0b3IgUElEcyB0aGlzIHJ1biBub3cgb3duczsgZW1wdHkgd2hlbiB0aGUgZW11bGF0b3IgaXMgbm90IGEgaGFybmVzcyBsZWZ0b3Zlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgdGFrZU92ZXJMZWZ0b3ZlckVtdWxhdG9yKGF2ZE5hbWU6IHN0cmluZywgZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyW10+IHtcbiAgICBjb25zdCBtYXJrZXIgPSByZWFkRW11bGF0b3JNYXJrZXIoYXZkTmFtZSk7XG4gICAgaWYgKCFtYXJrZXIpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9jZXNzZXMgPSBhd2FpdCB0aGlzLmVtdWxhdG9ycy5xdWVyeUhvc3RQcm9jZXNzZXMoKTtcbiAgICBpZiAocHJvY2Vzc2VzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nKGBDYW5ub3QgdGVsbCB3aGV0aGVyIEFWRCBcIiR7YXZkTmFtZX1cIiBpcyBhIGxlZnRvdmVyIHRoaXMgaGFybmVzcyBzdGFydGVkIHdpdGhvdXQgYSBob3N0IHByb2Nlc3MgbGlzdGluZzsgcmV1c2luZyBpdCB3aXRob3V0IHRha2luZyBpdCBvdmVyLmApO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGxpdmVFbXVsYXRvclBpZHMgPSBzZWxlY3RFbXVsYXRvckJhY2tlbmRQaWRzKHsga25vd25QaWRzOiBbXSwgcHJvY2Vzc2VzIH0pO1xuICAgIGNvbnN0IHZlcmRpY3QgPSByZXNvbHZlRW11bGF0b3JNYXJrZXJWZXJkaWN0KHtcbiAgICAgIGN1cnJlbnRQaWQ6IHByb2Nlc3MucGlkLFxuICAgICAgaXNPd25lckFsaXZlOiBjaGVja0lzUHJvY2Vzc0FsaXZlKG1hcmtlci5vd25lclBpZCksXG4gICAgICBsaXZlRW11bGF0b3JQaWRzLFxuICAgICAgbWFya2VyXG4gICAgfSk7XG5cbiAgICBzd2l0Y2ggKHZlcmRpY3QpIHtcbiAgICAgIGNhc2UgJ2hhcm5lc3MtbGVmdG92ZXInOiB7XG4gICAgICAgIGNvbnN0IG93bmVkRW11bGF0b3JQaWRzID0gc2VsZWN0TGl2ZU1hcmtlZFBpZHMobWFya2VyLCBsaXZlRW11bGF0b3JQaWRzKTtcbiAgICAgICAgd3JpdGVFbXVsYXRvck1hcmtlcih7IGF2ZE5hbWUsIGRldmljZUlkLCBvd25lZEVtdWxhdG9yUGlkcywgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHM6IG1hcmtlci5zdGFydGVkQXRJbk1pbGxpc2Vjb25kcyB9KTtcbiAgICAgICAgLypcbiAgICAgICAgICogVGhlIHJlYXBlciB0aGUgZWFybGllciBydW4gYXJtZWQgbWF5IHN0aWxsIGJlIHdhdGNoaW5nIHRoaXMgZW11bGF0b3JcbiAgICAgICAgICogXHUyMDE0IHRoZSBsYXVuY2ggdGltZSBpdCBrZXlzIG9uIHN1cnZpdmVzIGEgdGFrZW92ZXIgXHUyMDE0IGJ1dCBhbiBlbXVsYXRvclxuICAgICAgICAgKiBzdGFydGVkIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgdGhlIGhhcm5lc3MgaGFzIG5vbmUuIEEgc2Vjb25kIHJlYXBlclxuICAgICAgICAgKiBjb3N0cyBub3RoaW5nOiB3aGljaGV2ZXIgdGFrZXMgdGhlIGxvY2sgZmlyc3Qgc3RvcHMgdGhlIGVtdWxhdG9yLCBhbmRcbiAgICAgICAgICogdGhlIG90aGVyIHRoZW4gZmluZHMgdGhlIG1hcmtlciBnb25lIGFuZCBleGl0cy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYXJtRW11bGF0b3JSZWFwZXIoYXZkTmFtZSwgbWFya2VyLnN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzKTtcbiAgICAgICAgcmV0dXJuIG93bmVkRW11bGF0b3JQaWRzO1xuICAgICAgfVxuICAgICAgY2FzZSAnaW4tdXNlLWJ5LWxpdmUtcnVuJzoge1xuICAgICAgICB0aGlzLmxvZyhgQVZEIFwiJHthdmROYW1lfVwiIHdhcyBzdGFydGVkIGJ5IGEgaGFybmVzcyBwcm9jZXNzIHRoYXQgaXMgc3RpbGwgcnVubmluZyAoUElEICR7U3RyaW5nKG1hcmtlci5vd25lclBpZCl9KTsgdGhhdCBwcm9jZXNzIHN0YXlzIHJlc3BvbnNpYmxlIGZvciBzdG9wcGluZyBpdC5gKTtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgY2FzZSAnc3RhbGUtbWFya2VyJzoge1xuICAgICAgICBjbGVhckVtdWxhdG9yTWFya2VyKGF2ZE5hbWUpO1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHJldHVybiBhc3NlcnROZXZlcih2ZXJkaWN0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JBcHBpdW1SZWFkeSh1cmw6IFVSTCwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXIsIGxhdW5jaDogUHJvY2Vzc0xhdW5jaCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBXYWl0aW5nIGZvciBBcHBpdW0gYXQgJHt1cmwuaHJlZn0gKHRpbWVvdXQ6ICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMsIHBvbGw6ICR7U3RyaW5nKEFQUElVTV9TVEFSVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyl9bXMpLi4uYFxuICAgICk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBzdGFydCArIHRpbWVvdXRJbk1pbGxpc2Vjb25kcztcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIC8qXG4gICAgICAgKiBJZiB0aGUgc2VydmVyIHByb2Nlc3MgYWxyZWFkeSBkaWVkIChjcmFzaGVkLCBvciBuZXZlciBzdGFydGVkKSwgc3RvcFxuICAgICAgICogcG9sbGluZyBhbmQgc3VyZmFjZSB3aHkgXHUyMDE0IG90aGVyd2lzZSBhIGRvb21lZCBzZXJ2ZXIgc3BpbnMgb3V0IHRoZSB3aG9sZVxuICAgICAgICogcmVhZGluZXNzIHRpbWVvdXQgd2l0aCBubyBkaWFnbm9zdGljcywgdGhlIG9yaWdpbmFsIHN5bXB0b20gdGhpcyBleGlzdHNcbiAgICAgICAqIHRvIHByZXZlbnQuXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IGV4aXRJbmZvID0gbGF1bmNoLnJlYWRFeGl0SW5mbygpO1xuICAgICAgaWYgKGV4aXRJbmZvKSB7XG4gICAgICAgIHRocm93IGJ1aWxkRGVhdGhFcnJvcihleGl0SW5mbyk7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tBcHBpdW1SZWFjaGFibGUodXJsKTtcbiAgICAgICAgbGF1bmNoLnN0b3BDYXB0dXJlKCk7XG4gICAgICAgIHRoaXMubG9nKGBBcHBpdW0gc2VydmVyIHJlYWR5IGFmdGVyICR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMuYCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICB0aGlzLmxvZyhgQXBwaXVtIHNlcnZlciBub3QgcmVhZHkgeWV0IChlbGFwc2VkOiAke1N0cmluZyhEYXRlLm5vdygpIC0gc3RhcnQpfW1zKS4gUmV0cnlpbmcuLi5gKTtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEFQUElVTV9TVEFSVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGZpbmFsRXhpdEluZm8gPSBsYXVuY2gucmVhZEV4aXRJbmZvKCk7XG4gICAgaWYgKGZpbmFsRXhpdEluZm8pIHtcbiAgICAgIHRocm93IGJ1aWxkRGVhdGhFcnJvcihmaW5hbEV4aXRJbmZvKTtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXRUYWlsID0gbGF1bmNoLnJlYWRPdXRwdXQoKS50cmltKCk7XG4gICAgY29uc3Qgb3V0cHV0U2VjdGlvbiA9IG91dHB1dFRhaWwubGVuZ3RoID4gMCA/IGBcXG5cXG5BcHBpdW0gc2VydmVyIG91dHB1dCAodGFpbCk6XFxuJHtvdXRwdXRUYWlsfWAgOiAnJztcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEF1dG8tc3RhcnRlZCBBcHBpdW0gc2VydmVyIGRpZCBub3QgYmVjb21lIHJlYWR5IHdpdGhpbiAke1N0cmluZyh0aW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zLiR7b3V0cHV0U2VjdGlvbn1gKTtcblxuICAgIGZ1bmN0aW9uIGJ1aWxkRGVhdGhFcnJvcihleGl0SW5mbzogUHJvY2Vzc0V4aXRJbmZvKTogRXJyb3Ige1xuICAgICAgcmV0dXJuIG5ldyBFcnJvcihidWlsZFByb2Nlc3NFeGl0TWVzc2FnZSh7XG4gICAgICAgIGV4aXRJbmZvLFxuICAgICAgICBvdXRwdXQ6IGxhdW5jaC5yZWFkT3V0cHV0KCksXG4gICAgICAgIG91dHB1dExhYmVsOiAnQXBwaXVtIHNlcnZlciBvdXRwdXQnLFxuICAgICAgICBzdWJqZWN0OiAnQXV0by1zdGFydGVkIEFwcGl1bSBzZXJ2ZXInXG4gICAgICB9KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIHVudGlsIG5vdGhpbmcgYW5zd2VycyBgL3N0YXR1c2Agb24gdGhlIHBvcnQgYW55IG1vcmUuXG4gICAqXG4gICAqIEBwYXJhbSB1cmwgLSBUaGUgQXBwaXVtIHNlcnZlciBVUkwuXG4gICAqIEBwYXJhbSB0aW1lb3V0SW5NaWxsaXNlY29uZHMgLSBIb3cgbG9uZyB0byB3YWl0IGJlZm9yZSBnaXZpbmcgdXAuXG4gICAqIEB0aHJvd3MgSWYgdGhlIHBvcnQgaXMgc3RpbGwgc2VydmVkIHdoZW4gdGhlIHRpbWVvdXQgZWxhcHNlcy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckFwcGl1bVN0b3BwZWQodXJsOiBVUkwsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgdGltZW91dEluTWlsbGlzZWNvbmRzO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0FwcGl1bVJlYWNoYWJsZSh1cmwpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBBUFBJVU1fU1RBUlRfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFNvbWV0aGluZyBpcyBzdGlsbCBzZXJ2aW5nICR7dXJsLm9yaWdpbn0gJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcyBhZnRlciB0aGUgQXBwaXVtIHNlcnZlciB3YXMga2lsbGVkLmBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvbGxzIGBzeXMuYm9vdF9jb21wbGV0ZWRgIHVudGlsIHRoZSBkZXZpY2UgcmVwb3J0cyBhIGZpbmlzaGVkIGJvb3QuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgVURJRCB0byBwb2xsLlxuICAgKiBAcGFyYW0gZGVhZGxpbmUgLSBUaGUgYWJzb2x1dGUgdGltZSBhdCB3aGljaCB0byBnaXZlIHVwLlxuICAgKiBAcGFyYW0gZW11bGF0b3IgLSBUaGUgZW11bGF0b3IgdGhpcyBydW4gc3RhcnRlZCwgc28gaXRzIGVhcmx5IGRlYXRoIGZhaWxzIGZhc3QgaW5zdGVhZCBvZiBwb2xsaW5nIG91dCB0aGUgZGVhZGxpbmUuIE9taXR0ZWQgZm9yIGEgcmV1c2VkIGRldmljZSwgd2hpY2ggdGhpcyBydW4gZGlkIG5vdCBsYXVuY2ggYW5kIGNhbm5vdCBpbnNwZWN0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yQm9vdChkZXZpY2VJZDogc3RyaW5nLCBkZWFkbGluZTogbnVtYmVyLCBlbXVsYXRvcjogUHJvY2Vzc0xhdW5jaCB8IHVuZGVmaW5lZCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlbWFpbmluZ01zID0gTWF0aC5tYXgoMCwgZGVhZGxpbmUgLSBEYXRlLm5vdygpKTtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBXYWl0aW5nIGZvciBkZXZpY2UgJHtkZXZpY2VJZH0gdG8gZmluaXNoIGJvb3RpbmcgKHJlbWFpbmluZzogJHtTdHJpbmcocmVtYWluaW5nTXMpfW1zLCBwb2xsOiAke1N0cmluZyhFTVVMQVRPUl9CT09UX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gXG4gICAgKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IGlzQm9vdGVkID0gYXdhaXQgbmV3IFByb21pc2U8Ym9vbGVhbj4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgZXhlY0ZpbGUoXG4gICAgICAgICAgJ2FkYicsXG4gICAgICAgICAgWyctcycsIGRldmljZUlkLCAnc2hlbGwnLCAnZ2V0cHJvcCcsICdzeXMuYm9vdF9jb21wbGV0ZWQnXSxcbiAgICAgICAgICB7IHRpbWVvdXQ6IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSxcbiAgICAgICAgICAoX2Vycm9yLCBzdGRvdXQpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUoc3Rkb3V0LnRyaW0oKSA9PT0gJzEnKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKGlzQm9vdGVkKSB7XG4gICAgICAgIHRoaXMubG9nKGBEZXZpY2UgJHtkZXZpY2VJZH0gYm9vdCBjb21wbGV0ZWQuYCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhpdEluZm8gPSBlbXVsYXRvcj8ucmVhZEV4aXRJbmZvKCk7XG4gICAgICBpZiAoZXhpdEluZm8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGJ1aWxkUHJvY2Vzc0V4aXRNZXNzYWdlKHtcbiAgICAgICAgICBleGl0SW5mbyxcbiAgICAgICAgICBvdXRwdXQ6IGVtdWxhdG9yPy5yZWFkT3V0cHV0KCkgPz8gJycsXG4gICAgICAgICAgb3V0cHV0TGFiZWw6ICdFbXVsYXRvciBvdXRwdXQnLFxuICAgICAgICAgIHN1YmplY3Q6ICdBbmRyb2lkIGVtdWxhdG9yJ1xuICAgICAgICB9KSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgRU1VTEFUT1JfQk9PVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIFRoZSB0YWlsIGdvZXMgb24gdGhlIFRJTUVPVVQgdG9vLCBub3Qgb25seSBvbiB0aGUgZXhpdC4gQW4gZW11bGF0b3IgdGhhdFxuICAgICAqIHByaW50cyBgRkFUQUwgfCBSdW5uaW5nIG11bHRpcGxlIGVtdWxhdG9ycyB3aXRoIHRoZSBzYW1lIEFWRGAgYW5kIHRoZW5cbiAgICAgKiBsaW5nZXJzIG5ldmVyIHNldHMgYGV4aXRJbmZvYCwgc28gdGhpcyB1c2VkIHRvIGJlIHRoZSB3aG9sZSBvZiB3aGF0IHRoZVxuICAgICAqIHJlYWRlciBnb3QgXHUyMDE0IGEgYnVkZ2V0LCB3aXRoIHRoZSBleHBsYW5hdGlvbiBjYXB0dXJlZCBhbmQgZGlzY2FyZGVkLlxuICAgICAqL1xuICAgIHRocm93IG5ldyBFcnJvcihhcHBlbmRQcm9jZXNzT3V0cHV0VGFpbChcbiAgICAgIGBEZXZpY2UgXCIke2RldmljZUlkfVwiIGNvbm5lY3RlZCBidXQgZGlkIG5vdCBmaW5pc2ggYm9vdGluZyB3aXRoaW4gJHtTdHJpbmcoRU1VTEFUT1JfQk9PVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMuYCxcbiAgICAgIHsgb3V0cHV0OiBlbXVsYXRvcj8ucmVhZE91dHB1dCgpID8/ICcnLCBvdXRwdXRMYWJlbDogJ0VtdWxhdG9yIG91dHB1dCcgfVxuICAgICkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciBhIGJvb3RlZCBlbXVsYXRvciB0byBiZWNvbWUgaWRsZSBiZWZvcmUgdGhlIHNlc3Npb24gaXNcbiAgICogZXN0YWJsaXNoZWQgXHUyMDE0IHdoZXRoZXIgdGhpcyBydW4gc3RhcnRlZCBpdCBvciBmb3VuZCBpdCBhbHJlYWR5IHJ1bm5pbmcuXG4gICAqXG4gICAqIGBzeXMuYm9vdF9jb21wbGV0ZWRgIGZpcmVzIGJlZm9yZSB0aGUgZ3Vlc3QgaXMgYWN0dWFsbHkgaWRsZSBcdTIwMTQgcGFja2FnZVxuICAgKiBvcHRpbWl6YXRpb24gYW5kIHNlcnZpY2VzIGtlZXAgY2h1cm5pbmcgXHUyMDE0IHNvIGVzdGFibGlzaGluZyB0aGUgQXBwaXVtXG4gICAqIHNlc3Npb24gaW1tZWRpYXRlbHkgbWFrZXMgZXZlcnkgc2VyaWFsaXplZCBVaUF1dG9tYXRvcjIgYGFkYmAgcm91bmQtdHJpcFxuICAgKiBjb250ZW5kIHdpdGggdGhhdCB3b3JrIGFuZCBpbmZsYXRlcyBzZXNzaW9uIGVzdGFibGlzaG1lbnQgfjN4LiBUaGlzIHBvbGxzXG4gICAqIGEgbGF0ZXIsIHF1aWV0ZXIgc2lnbmFsIChib290IGFuaW1hdGlvbiBzdG9wcGVkICsgcGFja2FnZSBtYW5hZ2VyIHNlcnZpbmcsXG4gICAqIHZpYSB7QGxpbmsgY2hlY2tEZXZpY2VJZGxlfSkgYW5kIHJldHVybnMgYXMgc29vbiBhcyBpdCBpcyBzYXRpc2ZpZWQuXG4gICAqXG4gICAqIEEgKipyZXVzZWQqKiBkZXZpY2UgbmVlZHMgdGhpcyBldmVyeSBiaXQgYXMgbXVjaCBhcyBhIHN0YXJ0ZWQgb25lOiBiZWluZ1xuICAgKiBsaXN0ZWQgaW4gYGFkYiBkZXZpY2VzYCBzYXlzIG9ubHkgdGhhdCBhZGJkIGFuc3dlcnMsIGFuZCB0aGUgY2h1cm4gaXQgZG9lc1xuICAgKiBub3QgZ2F0ZSBpcyBwYWlkIGxhdGVyIGJ5IHdoYXRldmVyIHBvbGxzIHRoZSBXZWJWaWV3LlxuICAgKlxuICAgKiBCZXN0LWVmZm9ydDogaWYgdGhlIGd1ZXN0IGRvZXMgbm90IHJlcG9ydCBpZGxlIHdpdGhpbiB0aGUgYnVkZ2V0IGl0IGxvZ3MgYVxuICAgKiB3YXJuaW5nIGFuZCBwcm9jZWVkcyAoYSBzbG93IHNlc3Npb24gaXMgYmV0dGVyIHRoYW4gYSBmYWlsZWQgcnVuKSwgYW5kIGFcbiAgICogYnVkZ2V0IG9mIGAwYCBza2lwcyB0aGUgd2FpdCBlbnRpcmVseS5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSBVRElEIHRvIHBvbGwuXG4gICAqIEBwYXJhbSB0aW1lb3V0SW5NaWxsaXNlY29uZHMgLSBNYXhpbXVtIHRpbWUgdG8gd2FpdDsgYDBgIHNraXBzIHRoZSB3YWl0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yRGV2aWNlSWRsZShkZXZpY2VJZDogc3RyaW5nLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aW1lb3V0SW5NaWxsaXNlY29uZHMgPD0gMCkge1xuICAgICAgdGhpcy5sb2coYFNraXBwaW5nIHBvc3QtYm9vdCBpZGxlIHdhaXQgZm9yIGRldmljZSAke2RldmljZUlkfSAodGltZW91dCBpcyAwKS5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBzdGFydCArIHRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBXYWl0aW5nIGZvciBkZXZpY2UgJHtkZXZpY2VJZH0gdG8gYmVjb21lIGlkbGUgKHRpbWVvdXQ6ICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMsIHBvbGw6ICR7U3RyaW5nKERFVklDRV9JRExFX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gXG4gICAgKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IFtib290QW5pbWF0aW9uUHJvcGVydHksIHBhY2thZ2VMaXN0T3V0cHV0XSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgdGhpcy5nZXREZXZpY2VQcm9wZXJ0eShkZXZpY2VJZCwgJ2luaXQuc3ZjLmJvb3RhbmltJyksXG4gICAgICAgIHRoaXMubGlzdEluc3RhbGxlZFBhY2thZ2VzKGRldmljZUlkKVxuICAgICAgXSk7XG5cbiAgICAgIGlmIChjaGVja0RldmljZUlkbGUoeyBib290QW5pbWF0aW9uUHJvcGVydHksIHBhY2thZ2VMaXN0T3V0cHV0IH0pKSB7XG4gICAgICAgIHRoaXMubG9nKGBEZXZpY2UgJHtkZXZpY2VJZH0gaXMgaWRsZSBhZnRlciAke1N0cmluZyhEYXRlLm5vdygpIC0gc3RhcnQpfW1zLmApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMubG9nKGBEZXZpY2UgJHtkZXZpY2VJZH0gbm90IGlkbGUgeWV0IChlbGFwc2VkOiAke1N0cmluZyhEYXRlLm5vdygpIC0gc3RhcnQpfW1zKS4gUmV0cnlpbmcuLi5gKTtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgREVWSUNFX0lETEVfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2coXG4gICAgICBgV2FybmluZzogZGV2aWNlICR7ZGV2aWNlSWR9IGRpZCBub3QgcmVwb3J0IGlkbGUgd2l0aGluICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXM7IHByb2NlZWRpbmcgd2l0aCBzZXNzaW9uIGVzdGFibGlzaG1lbnQgYW55d2F5LmBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYm90aCBwb3N0LWJvb3QgcmVhZGluZXNzIGdhdGVzLCBpbiBvcmRlciwgb24gYSBkZXZpY2UgdGhhdCBoYXMganVzdFxuICAgKiByZXBvcnRlZCBgc3lzLmJvb3RfY29tcGxldGVkYC5cbiAgICpcbiAgICogVGhlIHNpbmdsZSBvd25lciBvZiBcIndoaWNoIGdhdGVzIGEgZGV2aWNlIHBhc3NlcyBiZWZvcmUgYSBzZXNzaW9uXCIsIHNvIHRoZVxuICAgKiBzdGFydGVkLWRldmljZSBhbmQgcmV1c2VkLWRldmljZSBicmFuY2hlcyBjYW5ub3QgZGl2ZXJnZSBvbiBpdCBcdTIwMTQgdGhlIGJyYW5jaFxuICAgKiB0aGF0IHNraXBwZWQgYSBnYXRlIGVudGlyZWx5IGlzIHRoZSBob2xlIGEgcmV1c2VkIGRldmljZSBvbmNlIGZlbGwgaW50byAoKipMNDMqKikuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgVURJRCB0byBnYXRlIG9uLlxuICAgKiBAcGFyYW0gdGltZW91dHMgLSBUaGUgdHdvIHJlc29sdmVkIGJ1ZGdldHMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JEZXZpY2VSZWFkeShkZXZpY2VJZDogc3RyaW5nLCB0aW1lb3V0czogRGV2aWNlUmVhZGluZXNzVGltZW91dHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLndhaXRGb3JEZXZpY2VJZGxlKGRldmljZUlkLCB0aW1lb3V0cy5kZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzKTtcbiAgICBhd2FpdCB0aGlzLndhaXRGb3JOZXR3b3JrVmFsaWRhdGVkKGRldmljZUlkLCB0aW1lb3V0cy5uZXR3b3JrUmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciBhIGJvb3RlZCBlbXVsYXRvciB0byBoYXZlIGEgKip2YWxpZGF0ZWQgZGVmYXVsdCBuZXR3b3JrKiogYmVmb3JlXG4gICAqIHRoZSBzZXNzaW9uIGlzIGVzdGFibGlzaGVkLlxuICAgKlxuICAgKiBUaGUgaWRsZSBnYXRlIGFib3ZlIHNheXMgbm90aGluZyBhYm91dCBjb25uZWN0aXZpdHksIGFuZCBpdHMgdHdvIHNpZ25hbHMgYXJlXG4gICAqIHNhdGlzZmllZCB3ZWxsIGJlZm9yZSB0aGUgZGVmYXVsdCBuZXR3b3JrIGlzIGNyZWF0ZWQgYW5kIHZhbGlkYXRlZCBcdTIwMTQgdGhhdFxuICAgKiBsYW5kcyB+ODBzIGludG8gZ3Vlc3QgdXB0aW1lLCB0ZW5zIG9mIHNlY29uZHMgYWZ0ZXIgdGhlIGJvb3QgZmxhZyBvbiBhIGZhc3RcbiAgICogaG9zdC4gQSBzdWl0ZSBzdGFydGVkIGluIHRoYXQgZ2FwIGRvZXMgbm90IG1lcmVseSBydW4gc2xvd2x5OiBhIHRlc3RcbiAgICogdGhhdCByZWFjaGVzIHRoZSBuZXR3b3JrIHJ1bnMgdG8gY29tcGxldGlvbiBhZ2FpbnN0IGEgc2lsZW50bHkgKiplbXB0eVxuICAgKiByZXN1bHQqKiwgd2hpY2ggbm8gYXNzZXJ0aW9uIGluc2lkZSB0aGUgc3VpdGUgY2FuIGRpc3Rpbmd1aXNoIGZyb20gYVxuICAgKiBnZW51aW5lbHkgZW1wdHkgcmVzcG9uc2UuIE9ubHkgYSByZWFkaW5lc3MgZ2F0ZSBjYW4gY2F0Y2ggdGhhdCwgd2hpY2ggaXMgd2h5XG4gICAqIHRoaXMgZXhpc3RzIChzZWUge0BsaW5rIGNoZWNrTmV0d29ya1ZhbGlkYXRlZH0sIHdoaWNoIGFsc28gcmVjb3JkcyB3aHkgdGhlXG4gICAqIHRocmVlIG9idmlvdXMgY29ubmVjdGl2aXR5IHByb2JlcyBhcmUgYWxsIHdyb25nKS5cbiAgICpcbiAgICogQmVzdC1lZmZvcnQsIG9uIHRoZSBzYW1lIGNvbnRyYWN0IGFzIHRoZSBpZGxlIGdhdGU6IGlmIG5vIHZhbGlkYXRlZCBuZXR3b3JrXG4gICAqIGFwcGVhcnMgd2l0aGluIHRoZSBidWRnZXQgaXQgbG9ncyBhIHdhcm5pbmcgKipuYW1pbmcgdGhlIG1pc3NpbmcgbmV0d29yayoqXG4gICAqIGFuZCBwcm9jZWVkcyAoYW4gb2ZmbGluZSBBVkQgaXMgc3RpbGwgYSB1c2FibGUgb25lIGZvciBzdWl0ZXMgdGhhdCBuZXZlclxuICAgKiB0b3VjaCB0aGUgbmV0d29yayksIGFuZCBhIGJ1ZGdldCBvZiBgMGAgc2tpcHMgdGhlIHdhaXQgZW50aXJlbHkuIFRoZSB3YXJuaW5nXG4gICAqIGlzIHRoZSBwb2ludCBcdTIwMTQgdGhlIGZhaWx1cmUgaXQgcHJlY2VkZXMgb3RoZXJ3aXNlIHN1cmZhY2VzIGFzIGEgYmFyZVxuICAgKiBgV2ViRHJpdmVyRXJyb3I6IHNjcmlwdCB0aW1lb3V0YCBuYW1pbmcgdGhlIHRyYW5zcG9ydCwgd2hpY2ggcmVhZHMgYXMgYVxuICAgKiBoYXJuZXNzIGRlZmVjdCByYXRoZXIgdGhhbiBhIG1pc3Npbmcgcm91dGUuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgVURJRCB0byBwb2xsLlxuICAgKiBAcGFyYW0gdGltZW91dEluTWlsbGlzZWNvbmRzIC0gTWF4aW11bSB0aW1lIHRvIHdhaXQ7IGAwYCBza2lwcyB0aGUgd2FpdC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvck5ldHdvcmtWYWxpZGF0ZWQoZGV2aWNlSWQ6IHN0cmluZywgdGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGltZW91dEluTWlsbGlzZWNvbmRzIDw9IDApIHtcbiAgICAgIHRoaXMubG9nKGBTa2lwcGluZyBuZXR3b3JrLXJlYWR5IHdhaXQgZm9yIGRldmljZSAke2RldmljZUlkfSAodGltZW91dCBpcyAwKS5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBzdGFydCArIHRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBXYWl0aW5nIGZvciBkZXZpY2UgJHtkZXZpY2VJZH0gdG8gcmVwb3J0IGEgdmFsaWRhdGVkIG5ldHdvcmsgKHRpbWVvdXQ6ICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMsIHBvbGw6ICR7U3RyaW5nKE5FVFdPUktfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpfW1zKS4uLmBcbiAgICApO1xuXG4gICAgbGV0IHByb2JlRmFpbHVyZUNvdW50ID0gMDtcbiAgICBsZXQgbGFzdEZhaWx1cmVSZWFzb24gPSAnJztcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IHByb2JlID0gYXdhaXQgdGhpcy5kdW1wQ29ubmVjdGl2aXR5KGRldmljZUlkKTtcbiAgICAgIGNvbnN0IGVsYXBzZWQgPSBTdHJpbmcoRGF0ZS5ub3coKSAtIHN0YXJ0KTtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpdml0eU91dHB1dCA9IHByb2JlLm91dHB1dDtcblxuICAgICAgaWYgKGNvbm5lY3Rpdml0eU91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHByb2JlRmFpbHVyZUNvdW50Kys7XG4gICAgICAgIGxhc3RGYWlsdXJlUmVhc29uID0gcHJvYmUuZmFpbHVyZVJlYXNvbiA/PyAndW5rbm93biBhZGIgZmFpbHVyZSc7XG4gICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgIGBEZXZpY2UgJHtkZXZpY2VJZH0gY29ubmVjdGl2aXR5IHByb2JlIGZhaWxlZCAoZWxhcHNlZDogJHtlbGFwc2VkfW1zKTogJHtsYXN0RmFpbHVyZVJlYXNvbn0uIFJldHJ5aW5nLi4uYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChjaGVja05ldHdvcmtWYWxpZGF0ZWQoeyBjb25uZWN0aXZpdHlPdXRwdXQgfSkpIHtcbiAgICAgICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBoYXMgYSB2YWxpZGF0ZWQgbmV0d29yayBhZnRlciAke2VsYXBzZWR9bXMuYCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nKGBEZXZpY2UgJHtkZXZpY2VJZH0gaGFzIG5vIHZhbGlkYXRlZCBuZXR3b3JrIHlldCAoZWxhcHNlZDogJHtlbGFwc2VkfW1zKS4gUmV0cnlpbmcuLi5gKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBORVRXT1JLX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogVHdvIGRpZmZlcmVudCBkaWFnbm9zZXMsIG5ldmVyIG1lcmdlZCBpbnRvIG9uZSBzZW50ZW5jZTogYSBndWVzdCB0aGF0XG4gICAgICogYW5zd2VyZWQgYW5kIHJlcG9ydGVkIG5vIG5ldHdvcmsgaXMgb2ZmbGluZSwgd2hpbGUgYSBndWVzdCB0aGF0IG5ldmVyXG4gICAgICogYW5zd2VyZWQgc2F5cyBub3RoaW5nIGFib3V0IGl0cyBuZXR3b3JrIGFuZCBldmVyeXRoaW5nIGFib3V0IGl0c2VsZi5cbiAgICAgKi9cbiAgICBjb25zdCBkaWFnbm9zaXMgPSBwcm9iZUZhaWx1cmVDb3VudCA+IDBcbiAgICAgID8gYCR7U3RyaW5nKHByb2JlRmFpbHVyZUNvdW50KX0gb2YgaXRzIGNvbm5lY3Rpdml0eSBwcm9iZXMgZmFpbGVkLCBsYXN0IFwiJHtsYXN0RmFpbHVyZVJlYXNvbn1cIiwgc28gdGhlIGd1ZXN0IG1heSBiZSB3ZWRnZWQgcmF0aGVyIHRoYW4gb2ZmbGluZWBcbiAgICAgIDogJ2l0IGFuc3dlcmVkIGV2ZXJ5IHByb2JlIGFuZCByZXBvcnRlZCBubyB2YWxpZGF0ZWQgZGVmYXVsdCBuZXR3b3JrJztcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBXYXJuaW5nOiBkZXZpY2UgJHtkZXZpY2VJZH0gcmVwb3J0ZWQgbm8gdmFsaWRhdGVkIG5ldHdvcmsgd2l0aGluICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMgKCR7ZGlhZ25vc2lzfSk7IGBcbiAgICAgICAgKyAncHJvY2VlZGluZyB3aXRoIHNlc3Npb24gZXN0YWJsaXNobWVudCBhbnl3YXkuIFRlc3RzIHRoYXQgcmVhY2ggdGhlIG5ldHdvcmsgd2lsbCBydW4gYWdhaW5zdCBhIGRldmljZSB3aXRoIG5vIHJvdXRlLCAnXG4gICAgICAgICsgJ2FuZCBtYXkgcmV0dXJuIEVNUFRZIFJFU1VMVFMgcmF0aGVyIHRoYW4gZmFpbCBcdTIwMTQgcmVhZCBhbnkgZW1wdHktbG9va2luZyBhc3NlcnRpb24gZmFpbHVyZSBiZWxvdyBhcyBhIG1pc3NpbmcgbmV0d29yayBmaXJzdC4nXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYWl0cyBmb3IgdGhlIGVtdWxhdG9yIHRoaXMgcnVuIGxhdW5jaGVkIHRvIHByb2R1Y2UgYSBkZXZpY2UsIGFuZCBmb3IgdGhhdFxuICAgKiBkZXZpY2UgdG8gYmVjb21lIHVzYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkc0JlZm9yZSAtIFRoZSBkZXZpY2VzIGNvbm5lY3RlZCBiZWZvcmUgdGhlIGxhdW5jaC5cbiAgICogQHBhcmFtIGVtdWxhdG9yIC0gVGhlIGxhdW5jaGVyLCBwb2xsZWQgZm9yIGFuIGVhcmx5IGV4aXQuXG4gICAqIEBwYXJhbSB0aW1lb3V0cyAtIFRoZSB0d28gcG9zdC1ib290IHJlYWRpbmVzcyBidWRnZXRzLlxuICAgKiBAcGFyYW0gb25EZXZpY2VBcHBlYXJlZCAtIENhbGxlZCB3aXRoIHRoZSBuZXcgZGV2aWNlIHRoZSBtb21lbnQgaXQgaXMgbGlzdGVkLCBiZWZvcmUgdGhlIHJlYWRpbmVzcyBnYXRlcy5cbiAgICogQHJldHVybnMgVGhlIG5ldyBkZXZpY2UncyBpZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvck5ld0RldmljZShcbiAgICBkZXZpY2VJZHNCZWZvcmU6IHN0cmluZ1tdLFxuICAgIGVtdWxhdG9yOiBQcm9jZXNzTGF1bmNoLFxuICAgIHRpbWVvdXRzOiBEZXZpY2VSZWFkaW5lc3NUaW1lb3V0cyxcbiAgICBvbkRldmljZUFwcGVhcmVkOiAoZGV2aWNlSWQ6IHN0cmluZykgPT4gdm9pZFxuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHRoaXMubG9nKFxuICAgICAgYFdhaXRpbmcgZm9yIGEgbmV3IGRldmljZSB0byBhcHBlYXIgaW4gQURCICh0aW1lb3V0OiAke1N0cmluZyhFTVVMQVRPUl9CT09UX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcywgcG9sbDogJHtTdHJpbmcoRU1VTEFUT1JfQk9PVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyl9bXMpLi4uYFxuICAgICk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgRU1VTEFUT1JfQk9PVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRJZHMgPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZERldmljZUlkcygpO1xuICAgICAgY29uc3QgbmV3SWRzID0gY3VycmVudElkcy5maWx0ZXIoKGlkKSA9PiAhZGV2aWNlSWRzQmVmb3JlLmluY2x1ZGVzKGlkKSk7XG5cbiAgICAgIGlmIChuZXdJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBhY3R1YWxEZXZpY2VJZCA9IG5ld0lkc1swXSA/PyAnJztcbiAgICAgICAgdGhpcy5sb2coYERldmljZSAke2FjdHVhbERldmljZUlkfSBhcHBlYXJlZCBpbiBBREIsIHdhaXRpbmcgZm9yIGJvb3QgdG8gY29tcGxldGUuLi5gKTtcbiAgICAgICAgb25EZXZpY2VBcHBlYXJlZChhY3R1YWxEZXZpY2VJZCk7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckJvb3QoYWN0dWFsRGV2aWNlSWQsIGRlYWRsaW5lLCBlbXVsYXRvcik7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckRldmljZVJlYWR5KGFjdHVhbERldmljZUlkLCB0aW1lb3V0cyk7XG4gICAgICAgIGF3YWl0IHRoaXMud2FrZVNjcmVlbihhY3R1YWxEZXZpY2VJZCk7XG4gICAgICAgIHJldHVybiBhY3R1YWxEZXZpY2VJZDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhpdEluZm8gPSBlbXVsYXRvci5yZWFkRXhpdEluZm8oKTtcbiAgICAgIGlmIChleGl0SW5mbykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYnVpbGRQcm9jZXNzRXhpdE1lc3NhZ2Uoe1xuICAgICAgICAgIGV4aXRJbmZvLFxuICAgICAgICAgIG91dHB1dDogZW11bGF0b3IucmVhZE91dHB1dCgpLFxuICAgICAgICAgIG91dHB1dExhYmVsOiAnRW11bGF0b3Igb3V0cHV0JyxcbiAgICAgICAgICBzdWJqZWN0OiAnQW5kcm9pZCBlbXVsYXRvcidcbiAgICAgICAgfSkpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEVNVUxBVE9SX0JPT1RfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQXMgaW4gYHdhaXRGb3JCb290YDogYW4gZW11bGF0b3IgdGhhdCBoYW5ncyBoYXMgYXMgbXVjaCB0byBzYXkgYXMgb25lIHRoYXQgZGllcy5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYXBwZW5kUHJvY2Vzc091dHB1dFRhaWwoXG4gICAgICBgTm8gbmV3IGVtdWxhdG9yIGRldmljZSBhcHBlYXJlZCB3aXRoaW4gJHtTdHJpbmcoRU1VTEFUT1JfQk9PVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMuYCxcbiAgICAgIHsgb3V0cHV0OiBlbXVsYXRvci5yZWFkT3V0cHV0KCksIG91dHB1dExhYmVsOiAnRW11bGF0b3Igb3V0cHV0JyB9XG4gICAgKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdha2VTY3JlZW4oZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nKGBXYWtpbmcgc2NyZWVuIG9uIGRldmljZSAke2RldmljZUlkfS4uLmApO1xuXG4gICAgYXdhaXQgdGhpcy5zZW5kS2V5RXZlbnQoZGV2aWNlSWQsIEtFWUNPREVfV0FLRVVQLCAnd2FrZSBzY3JlZW4nKTtcbiAgICBhd2FpdCB0aGlzLnNlbmRLZXlFdmVudChkZXZpY2VJZCwgS0VZQ09ERV9NRU5VLCAnZGlzbWlzcyBsb2NrIHNjcmVlbicpO1xuXG4gICAgdGhpcy5sb2coYFNjcmVlbiB3YWtlIGNvbXBsZXRlIG9uIGRldmljZSAke2RldmljZUlkfS5gKTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdHJhbnNwb3J0IGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUcmFuc3BvcnQgY29uZmlndXJhdGlvbi4gRGVmYXVsdHMgdG8gYW4gb3duZWQgZGVza3RvcCBDRFAgdHJhbnNwb3J0LlxuICogQHJldHVybnMgQSBuZXcgdHJhbnNwb3J0IGluc3RhbmNlLlxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JzaWRpYW4tZGV2LXV0aWxzL3BhcmFtcy1vcHRpb25zLW5hbWUtbWF0Y2ggLS0gUGVybWFuZW50OiBgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zYCBpcyBvbmUgdHJhbnNwb3J0IG9wdGlvbnMgYmFnIHJlYWQgYnkgZml2ZSBoZWxwZXJzLCBzbyBubyBwZXItb3duZXIgbmFtZSBjYW4gc2F0aXNmeSB0aGVtIGFsbC5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyhvcHRpb25zPzogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zKTogUHJvbWlzZTxPYnNpZGlhblRyYW5zcG9ydD4ge1xuICBjb25zdCB0eXBlID0gb3B0aW9ucz8udHlwZSA/PyBERUZBVUxUX1RSQU5TUE9SVF9UWVBFO1xuXG4gIGlmICghb3B0aW9ucyB8fCBvcHRpb25zLnR5cGUgPT09ICdvYnNpZGlhbi1jZHAnKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUNkcFRyYW5zcG9ydChvcHRpb25zKTtcbiAgfVxuXG4gIGNvbnN0IGZhY3RvcnkgPSBuZXcgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeSh0eXBlKTtcbiAgcmV0dXJuIGZhY3RvcnkuY3JlYXRlKG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBjYWNoZWQgdHJhbnNwb3J0IGluc3RhbmNlLCBjcmVhdGluZyBvbmUgZnJvbSB0aGUgZ2l2ZW4gb3B0aW9uc1xuICogaWYgbm90IGFscmVhZHkgY2FjaGVkLlxuICpcbiAqIFRoZSB0cmFuc3BvcnQgaXMgY2FjaGVkIHBlciB3b3JrZXIgcHJvY2VzcyBzbyBXZWJTb2NrZXQvQXBwaXVtIHNlc3Npb25zXG4gKiBhcmUgcmV1c2VkIGFjcm9zcyBjYWxscyB3aXRoaW4gdGhlIHNhbWUgdGVzdCB3b3JrZXIuXG4gKlxuICogVGhpcyBpcyB0aGUgc2luZ2xlIGVudHJ5IHBvaW50IGV2ZXJ5IHdvcmtlci1zaWRlIGNhbGxlciB1c2VzIGZvciB0aGUgKiphbWJpZW50KipcbiAqIHRyYW5zcG9ydCwgc28gaXQgaXMgYWxzbyB3aGVyZSBhIGZhaWxlZCBnbG9iYWwgc2V0dXAgaXMgdHVybmVkIGludG8gYSBmYWlsaW5nIHRlc3QuXG4gKiBBIGZhaWxlZCBzZXR1cCBwdWJsaXNoZXMgbm8gdHJhbnNwb3J0IG9wdGlvbnMsIGFuZCBgdW5kZWZpbmVkYCBvcHRpb25zIG1lYW4gdGhlIG93bmVkXG4gKiAqKmRlc2t0b3AqKiBDRFAgZGVmYXVsdCBcdTIwMTQgc28gd2l0aG91dCB0aGlzIGd1YXJkIGFuIEFuZHJvaWQgcHJvamVjdCdzIHN1aXRlIHdvdWxkIHJ1blxuICogb24gZGVza3RvcCBhbmQgdGhlbiBkaWUgb24gYW4gdW5yZWxhdGVkIENEUCBlcnJvciwgaGlkaW5nIHRoZSByZWFsIGNhdXNlICgqKkw5KiopLlxuICogVGhlIHNldHVwIHBhdGggaXRzZWxmIGlzIHVuYWZmZWN0ZWQ6IGBjb3JlU2V0dXBgIGJ1aWxkcyBpdHMgdHJhbnNwb3J0IHRocm91Z2hcbiAqIHtAbGluayBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9uc30gd2l0aCBleHBsaWNpdCBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gVHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24uIERlZmF1bHRzIHRvIGFuIG93bmVkIGRlc2t0b3AgQ0RQIHRyYW5zcG9ydC5cbiAqIEByZXR1cm5zIFRoZSBjYWNoZWQgb3IgbmV3bHkgY3JlYXRlZCB0cmFuc3BvcnQuXG4gKiBAdGhyb3dzIHtJbnRlZ3JhdGlvblNldHVwRmFpbGVkRXJyb3J9IFdoZW4gdGhpcyBwcm9qZWN0J3MgZ2xvYmFsIHNldHVwIGZhaWxlZC5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG9ic2lkaWFuLWRldi11dGlscy9wYXJhbXMtb3B0aW9ucy1uYW1lLW1hdGNoIC0tIFBlcm1hbmVudDogYE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9uc2AgaXMgb25lIHRyYW5zcG9ydCBvcHRpb25zIGJhZyByZWFkIGJ5IGZpdmUgaGVscGVycywgc28gbm8gcGVyLW93bmVyIG5hbWUgY2FuIHNhdGlzZnkgdGhlbSBhbGwuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0T3JDcmVhdGVUcmFuc3BvcnQob3B0aW9ucz86IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgY29uc3Qgc2V0dXBFcnJvciA9IGdldFNldHVwRXJyb3IoKTtcbiAgaWYgKHNldHVwRXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgSW50ZWdyYXRpb25TZXR1cEZhaWxlZEVycm9yKHNldHVwRXJyb3IpO1xuICB9XG5cbiAgaWYgKGNhY2hlZFRyYW5zcG9ydCkge1xuICAgIHJldHVybiBjYWNoZWRUcmFuc3BvcnQ7XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyhvcHRpb25zKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXMgLS0gU2luZ2xlLXRocmVhZGVkIHdvcmtlcjsgbm8gY29uY3VycmVudCB3cml0ZXMuXG4gIGNhY2hlZFRyYW5zcG9ydCA9IHJlc3VsdDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBTdG9wcyBldmVyeSBlbXVsYXRvciB0aGlzIGhhcm5lc3Mgc3RhcnRlZCB3aG9zZSBydW4gY2FuIG5vIGxvbmdlciBzdG9wIGl0XG4gKiBpdHNlbGYsIHZlcmlmeWluZyBlYWNoIHN0b3AuXG4gKlxuICogRm9yIHRoZSBnbG9iYWwgdGVhcmRvd24gb2YgYSBWaXRlc3QgcHJvamVjdCB3aG9zZSB0cmFuc3BvcnQgbGl2ZXMgaW4gaXRzIHRlc3RcbiAqIHdvcmtlcnMgcmF0aGVyIHRoYW4gaW4gYSB0cmFuc3BvcnQgZ2xvYmFsIHNldHVwOiB0aGUgd29ya2VyIGF1dG8tc3RhcnRzIHRoZVxuICogZW11bGF0b3IsIFZpdGVzdCBlbmRzIHRoZSB3b3JrZXIgd2l0aG91dCBhIHRlYXJkb3duLCBhbmQgb25seSB0aGUgbWFpblxuICogcHJvY2VzcydzIHRlYXJkb3duIGdldHMgYSB0dXJuIFx1MjAxNCBob2xkaW5nIG5vIGhhbmRsZSB0byB0aGUgZW11bGF0b3IsIGJ1dCBhYmxlXG4gKiB0byBmaW5kIGl0IGJ5IGl0cyBtYXJrZXIgKGBlbXVsYXRvci1tYXJrZXIudHNgKS5cbiAqXG4gKiBDYWxsIGl0IHdoaWxlIGhvbGRpbmcgdGhlIGBhbmRyb2lkYCBzZXR1cCBsb2NrIChMNyk6IHRoYXQgaXMgd2hhdCBndWFyYW50ZWVzXG4gKiBubyBvdGhlciBBbmRyb2lkIHJ1biBpcyB1c2luZyBhIG1hcmtlZCBlbXVsYXRvci4gRW11bGF0b3JzIHdpdGhvdXQgYSBtYXJrZXIgYXJlXG4gKiBuZXZlciB0b3VjaGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RvcEhhcm5lc3NTdGFydGVkRW11bGF0b3JzKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCByZWNsYWltZXIgPSBuZXcgRW11bGF0b3JSZWNsYWltZXIoKG1lc3NhZ2UpID0+IHtcbiAgICBsb2coYFt0cmFuc3BvcnQtZmFjdG9yeToke0FORFJPSURfQVBQSVVNX1RSQU5TUE9SVF9UWVBFfV0gJHttZXNzYWdlfWApO1xuICB9KTtcbiAgYXdhaXQgcmVjbGFpbWVyLnJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9ycyh7IHNjb3BlOiAnZW5kLW9mLXJ1bicgfSk7XG59XG5cbi8qKlxuICogVmVyaWZpZXMgdGhlIGhhcm5lc3Mtb3duZWQgaW5zdGFuY2UgYSB3b3JrZXIgd2FzIHRvbGQgdG8gYXR0YWNoIHRvIGlzIHN0aWxsXG4gKiBzZXJ2aW5nIENEUCwgYmVmb3JlIGhhbmRpbmcgYmFjayBhIHRyYW5zcG9ydCB0aGF0IGNhbiBvbmx5IGZhaWwgYWdhaW5zdCBpdC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBvbmNlLXBlci1maWxlIGNoZWNrOiB0cmFuc3BvcnQgY3JlYXRpb24gaXMgY2FjaGVkIHBlciB3b3JrZXIsIHNvXG4gKiBhIGxpdmUgaW5zdGFuY2UgcGF5cyBvbmUgbG9vcGJhY2sgcmVxdWVzdCBwZXIgdGVzdCBmaWxlIGFuZCBhIGRlYWQgb25lIHR1cm5zXG4gKiB0aGUgd2hvbGUgZmlsZSBpbnRvIGEgc2luZ2xlIG5hbWVkIGVycm9yLCByYWlzZWQgYmVmb3JlIHRoZSBmaXJzdCB0ZXN0LiBJdFxuICogcmVwbGFjZXMgdGhlIGBFQ09OTlJFRlVTRURgLXBlci1maWxlIGNhc2NhZGUgYSBtaWQtcnVuIGRlYXRoIHVzZWQgdG8gcHJvZHVjZSBcdTIwMTRcbiAqIGFuZCB0aGUgcGVyLWZpbGUgcHJvYmUgY29uc3VtZXJzIHdlcmUgd3JpdGluZyBpbnRvIHRoZWlyIG93biBgc2V0dXBGaWxlc2AgdG9cbiAqIGdldCB0aGUgc2FtZSBlZmZlY3QuXG4gKlxuICogT25seSBmb3IgdGhlIGhhcm5lc3MncyBvd24gaW5zdGFuY2VzOiBhIHBsYWluIGF0dGFjaCB0YXJnZXRzIGEgZm9yZWlnblxuICogT2JzaWRpYW4gd2hvc2UgYWJzZW5jZSBpcyB0aGUgdXNlcidzIHRvIHJlc29sdmUsIGFuZCBgcHJlZmxpZ2h0Q2hlY2tgIGFscmVhZHlcbiAqIGhhcyBhIHN0b3J5IGZvciBpdC5cbiAqXG4gKiBAcGFyYW0gaG9zdCAtIFRoZSBDRFAgaG9zdCB0byBwcm9iZS5cbiAqIEBwYXJhbSBwb3J0IC0gVGhlIENEUCBwb3J0IHRvIHByb2JlLlxuICogQHRocm93cyB7T3duZWRJbnN0YW5jZUV4aXRlZEVycm9yfSBXaGVuIG5vdGhpbmcgaXMgc2VydmluZyBDRFAgb24gdGhlIHBvcnQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGFzc2VydEhhcm5lc3NPd25lZEluc3RhbmNlSXNTZXJ2aW5nKGhvc3Q6IHN0cmluZywgcG9ydDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGNkcFVybCA9IGBodHRwOi8vJHtob3N0fToke1N0cmluZyhwb3J0KX1gO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7Y2RwVXJsfS9qc29uL3ZlcnNpb25gKTtcbiAgICBhd2FpdCByZXNwb25zZS5ib2R5Py5jYW5jZWwoKTtcbiAgICByZXR1cm47XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5vdGhpbmcgaXMgbGlzdGVuaW5nIFx1MjAxNCB0aGUgaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBsYXVuY2hlZCBpcyBnb25lLlxuICB9XG5cbiAgdGhyb3cgYnVpbGRPd25lZEluc3RhbmNlRXhpdGVkRXJyb3JGcm9tTWFya2VyKGNkcFVybCwgcmVhZE93bmVkSW5zdGFuY2VFeGl0TWFya2VyKHBvcnQpKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIHBsYXRmb3JtJ3MgXCJ3aG8gaG9sZHMgdGhpcyBwb3J0XCIgcXVlcnkuXG4gKlxuICogYG5ldHN0YXRgIGNhbm5vdCBmaWx0ZXIgYnkgcG9ydCwgc28gdGhlIHdob2xlIHRhYmxlIGNvbWVzIGJhY2sgYW5kIHRoZSBwYXJzZXJcbiAqIGRvZXMgdGhlIG1hdGNoaW5nOyBgbHNvZmAgZmlsdGVycyBzZXJ2ZXItc2lkZSBhbmQgYW5zd2VycyB3aXRoIGJhcmUgUElEcy5cbiAqXG4gKiBAcGFyYW0gcG9ydCAtIFRoZSBwb3J0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgVGhlIGNvbW1hbmQgYW5kIGFyZ3VtZW50cyB0byBydW4uXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkUG9ydE93bmVyUXVlcnkocG9ydDogbnVtYmVyKTogSG9zdENvbW1hbmRRdWVyeSB7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInXG4gICAgPyB7IGNvbW1hbmQ6ICduZXRzdGF0JywgY29tbWFuZEFyZ3VtZW50czogWyctYW5vJ10gfVxuICAgIDogeyBjb21tYW5kOiAnbHNvZicsIGNvbW1hbmRBcmd1bWVudHM6IFsnLXRpJywgYHRjcDoke1N0cmluZyhwb3J0KX1gXSB9O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkZXNrdG9wIENEUCB0cmFuc3BvcnQuIFdoZW4gYW4gZXhwbGljaXQgYHBvcnRgIGlzIGdpdmVuIHRoZVxuICogdHJhbnNwb3J0IGF0dGFjaGVzIHRvIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiBvbiB0aGF0IHBvcnQ7IG90aGVyd2lzZSBpdFxuICogbGF1bmNoZXMgYW5kIG93bnMgYW4gaXNvbGF0ZWQgaW5zdGFuY2UgKHRoZSBkZWZhdWx0LCBoZXJtZXRpYyBtb2RlKS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENEUCB0cmFuc3BvcnQgb3B0aW9ucy5cbiAqIEByZXR1cm5zIEEgY29uZmlndXJlZCBDRFAgdHJhbnNwb3J0LlxuICovXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVDZHBUcmFuc3BvcnQob3B0aW9ucz86IE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgaWYgKG9wdGlvbnM/LnBvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IG93bmVkU3VmZml4ID0gb3B0aW9ucy5pc0hhcm5lc3NPd25lZEluc3RhbmNlID8gJyAoaGFybmVzcy1vd25lZCknIDogJyc7XG4gICAgbG9nKGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBBdHRhY2hpbmcgdG8gcnVubmluZyBPYnNpZGlhbiR7b3duZWRTdWZmaXh9IChob3N0PSR7b3B0aW9ucy5ob3N0ID8/ICdsb2NhbGhvc3QnfSwgcG9ydD0ke1N0cmluZyhvcHRpb25zLnBvcnQpfSlgKTtcbiAgICBpZiAob3B0aW9ucy5pc0hhcm5lc3NPd25lZEluc3RhbmNlKSB7XG4gICAgICBhd2FpdCBhc3NlcnRIYXJuZXNzT3duZWRJbnN0YW5jZUlzU2VydmluZyhvcHRpb25zLmhvc3QgPz8gJ2xvY2FsaG9zdCcsIG9wdGlvbnMucG9ydCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGVza3RvcENkcFRyYW5zcG9ydChub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8RGVza3RvcENkcFRyYW5zcG9ydENvbmZpZz4oe1xuICAgICAgY2RwSG9zdDogb3B0aW9ucy5ob3N0LFxuICAgICAgY2RwUG9ydDogb3B0aW9ucy5wb3J0LFxuICAgICAgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogb3B0aW9ucy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzLFxuICAgICAgaXNIYXJuZXNzT3duZWRJbnN0YW5jZTogb3B0aW9ucy5pc0hhcm5lc3NPd25lZEluc3RhbmNlXG4gICAgfSkpO1xuICB9XG5cbiAgbG9nKCdbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBDcmVhdGluZyBvd25lZCBpc29sYXRlZCBPYnNpZGlhbiBpbnN0YW5jZScpO1xuICAvLyBCZWZvcmUgYHJlc29sdmVPd25lZEluc3RhbmNlQ29uZmlnYCwgd2hpY2ggbWF5IGRvd25sb2FkIGFuZCBjYWNoZSBhbiBpbnN0YWxsZXIgc2hlbGw6XG4gIC8vIEEgc3RydWN0dXJhbGx5IGludmFsaWQgY29uZmlnIGZvbGRlciBuYW1lIGNhbm5vdCBiZWNvbWUgdmFsaWQgbGF0ZXIsIHNvIHBheWluZyBmb3IgYVxuICAvLyBwcm92aXNpb25pbmcgcm91bmQtdHJpcCBmaXJzdCB3b3VsZCBvbmx5IGRlbGF5IHRoZSBzYW1lIGZhaWx1cmUuXG4gIGlmIChvcHRpb25zPy5jb25maWdEaXJlY3RvcnkgIT09IHVuZGVmaW5lZCkge1xuICAgIGFzc2VydFZhbGlkQ29uZmlnRGlyZWN0b3J5KG9wdGlvbnMuY29uZmlnRGlyZWN0b3J5KTtcbiAgfVxuICBjb25zdCBvd25lZEluc3RhbmNlID0gYXdhaXQgcmVzb2x2ZU93bmVkSW5zdGFuY2VDb25maWcob3B0aW9ucyk7XG4gIHJldHVybiBuZXcgRGVza3RvcENkcFRyYW5zcG9ydChub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8RGVza3RvcENkcFRyYW5zcG9ydENvbmZpZz4oe1xuICAgIGNkcEhvc3Q6IG9wdGlvbnM/Lmhvc3QsXG4gICAgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogb3B0aW9ucz8uY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgICBjb25maWdEaXJlY3Rvcnk6IG9wdGlvbnM/LmNvbmZpZ0RpcmVjdG9yeSxcbiAgICBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM6IHJlc29sdmVEZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMob3B0aW9ucyksXG4gICAgaXNPYnNpZGlhbkFwcFZpc2libGU6IG9wdGlvbnM/LmlzT2JzaWRpYW5BcHBWaXNpYmxlLFxuICAgIG93bmVkSW5zdGFuY2UsXG4gICAgc2hvdWxkRGlzYWJsZVNhbmRib3g6IG9wdGlvbnM/LnNob3VsZERpc2FibGVTYW5kYm94LFxuICAgIHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2s6IHdpbGxUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrKG9wdGlvbnM/LnNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2spLFxuICAgIHNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXM6IHdpbGxXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzKG9wdGlvbnM/LnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMpXG4gIH0pKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZnJlc2gsIGlzb2xhdGVkIHVzZXItZGF0YSBkaXJlY3RvcnkgZm9yIGFuIG93bmVkIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBuZXcgZGlyZWN0b3J5LlxuICovXG5mdW5jdGlvbiBjcmVhdGVPd25lZFVzZXJEYXRhRGlyZWN0b3J5KCk6IHN0cmluZyB7XG4gIGNvbnN0IHJvb3QgPSBqb2luKHRtcGRpcigpLCBIQVJORVNTX1RFTVBfRElSX05BTUUpO1xuICBta2RpclN5bmMocm9vdCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIHJldHVybiBta2R0ZW1wU3luYyhqb2luKHJvb3QsIE9XTkVEX1VTRVJfREFUQV9ESVJfUFJFRklYKSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgcmVqZWN0aW9uIHJlYXNvbiBhbW9uZyBzZXR0bGVkIG91dGNvbWVzLlxuICpcbiAqIEBwYXJhbSBvdXRjb21lcyAtIFRoZSBzZXR0bGVkIG91dGNvbWVzLCBhdCBsZWFzdCBvbmUgb2Ygd2hpY2ggaXMgZXhwZWN0ZWQgdG8gaGF2ZSByZWplY3RlZC5cbiAqIEByZXR1cm5zIFRoZSBmaXJzdCByZWplY3Rpb24gcmVhc29uLCBvciBhIHN0YW5kLWluIGVycm9yIHdoZW4gbm9uZSByZWplY3RlZC5cbiAqL1xuZnVuY3Rpb24gZ2V0U2V0dGxlZEZhaWx1cmUob3V0Y29tZXM6IHJlYWRvbmx5IFByb21pc2VTZXR0bGVkUmVzdWx0PHVua25vd24+W10pOiB1bmtub3duIHtcbiAgZm9yIChjb25zdCBvdXRjb21lIG9mIG91dGNvbWVzKSB7XG4gICAgaWYgKG91dGNvbWUuc3RhdHVzID09PSAncmVqZWN0ZWQnKSB7XG4gICAgICByZXR1cm4gb3V0Y29tZS5yZWFzb247XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBFcnJvcignQW5kcm9pZCBwcm92aXNpb25pbmcgZmFpbGVkIHdpdGhvdXQgbmFtaW5nIGEgcmVhc29uLicpO1xufVxuXG4vKipcbiAqIExvYWRzIGB3ZWJkcml2ZXJpb2Agb24gZGVtYW5kLlxuICpcbiAqIFRoZSBsb2FkIGlzIGRlZmVycmVkIGJlY2F1c2UgYSBzdGF0aWMgaW1wb3J0IHdvdWxkIGRyYWcgdGhlIHdob2xlIFdlYkRyaXZlclxuICogc3RhY2sgKGB3ZWJkcml2ZXJpb2AgKyBgQHdkaW8vKmAgKyBgYXJjaGl2ZXJgL2BjaGVlcmlvYC9ganN6aXBgKSBpbnRvIGV2ZXJ5XG4gKiBjb25zdW1lciBvZiB0aGlzIHBhY2thZ2UncyBpbmRleCBcdTIwMTQgYGV2YWxJbk9ic2lkaWFuYCByZWFjaGVzIHRoaXMgbW9kdWxlIFx1MjAxNCB3aGVuXG4gKiBvbmx5IHRoZSBBcHBpdW0gdHJhbnNwb3J0IG5lZWRzIGl0LiBOb3RoaW5nIG9uIHRoZSBkZXNrdG9wIENEUCBwYXRoIHRvdWNoZXNcbiAqIGB3ZWJkcml2ZXJpb2AgYXQgYWxsLlxuICpcbiAqIEl0IGFsc28ga2VlcHMgYGNoYWxrYCBvdXQgb2YgdGhhdCBncmFwaC4gYEB3ZGlvL2xvZ2dlcmAgaW1wb3J0cyBgY2hhbGtANWAsXG4gKiB3aG9zZSBpbnRlcm5hbCBgI3N1cHBvcnRzLWNvbG9yYCBzdWJwYXRoIGltcG9ydCBKZXN0J3MgVk0tbW9kdWxlcyBsaW5rZXIgZmFpbHNcbiAqIHRvIGxpbmssIHNvIGFuIGVhZ2VybHktaW1wb3J0ZWQgYHdlYmRyaXZlcmlvYCBraWxscyBhIEplc3QgRVNNIHN1aXRlIGF0IGltcG9ydFxuICogd2l0aCBgUmVmZXJlbmNlRXJyb3I6IENhbm5vdCBhY2Nlc3MgJ3N1cHBvcnRzQ29sb3InIGJlZm9yZSBpbml0aWFsaXphdGlvbmBcbiAqIGJlZm9yZSBhIHNpbmdsZSB0ZXN0IHJ1bnMgXHUyMDE0IHdoaWNoIGlzIHdoYXQgb25jZSBtYWRlIGB0ZXN0Omplc3RgIHJlZC4gQVxuICogYG1vZHVsZU5hbWVNYXBwZXJgIGNhbm5vdCBwYXRjaCBpdDogdGhlIG1hcHBlciBpcyBieXBhc3NlZCBmb3IgYCNgIHNwZWNpZmllcnMuXG4gKlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byB0aGUgYHdlYmRyaXZlcmlvYCBlbnRyeSBwb2ludHMgdGhlXG4gKiBBcHBpdW0gZmFjdG9yeSBjYWxscy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gaW1wb3J0V2ViZHJpdmVyaW8oKTogUHJvbWlzZTxXZWJkcml2ZXJpb01vZHVsZT4ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gYHdlYmRyaXZlcmlvYCBpcyBBcHBpdW0tb25seSwgc28gaXQgbXVzdCBiZSBsb2FkZWQgbGF6aWx5OiBhIHN0YXRpYyBpbXBvcnQgd291bGQgZHJhZyB0aGUgd2hvbGUgV2ViRHJpdmVyIHN0YWNrIGludG8gZXZlcnkgY29uc3VtZXIgb2YgdGhpcyBwYWNrYWdlJ3MgaW5kZXgsIGFuZCBgY2hhbGtgIHdpdGggaXQgKHNlZSB0aGUgZG9jIGNvbW1lbnQpLlxuICByZXR1cm4gYXdhaXQgaW1wb3J0KCd3ZWJkcml2ZXJpbycpO1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIHBvcnQtb3duZXIgbGlzdGluZyB3aXRoIHRoZSBwbGF0Zm9ybSdzIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJhdyBvdXRwdXQgYW5kIHRoZSBwb3J0IHRoYXQgd2FzIHF1ZXJpZWQuXG4gKiBAcmV0dXJucyBUaGUgUElEcyBob2xkaW5nIHRoZSBwb3J0LlxuICovXG5mdW5jdGlvbiBwYXJzZVBvcnRPd25lclBpZHMocGFyYW1zOiBQYXJzZVBvcnRPd25lclBpZHNQYXJhbXMpOiBudW1iZXJbXSB7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInXG4gICAgPyBwYXJzZVdpbmRvd3NOZXRzdGF0UGlkcyh7IG5ldHN0YXRPdXRwdXQ6IHBhcmFtcy5vdXRwdXQsIHBvcnQ6IHBhcmFtcy5wb3J0IH0pXG4gICAgOiBwYXJzZVBvc2l4THNvZlBpZHMocGFyYW1zLm91dHB1dCk7XG59XG5cbi8qKlxuICogUnVucyB0aGUgcHJvYWN0aXZlIGluc3RhbGxlclx1MjE5NGFwcCBjb21wYXRpYmlsaXR5IGNoZWNrIGZvciBhbiBhc2FyLXN3YXAgYW5kIGFjdHNcbiAqIG9uIHRoZSB2ZXJkaWN0OiBmb3IgYW4gaW5zdGFsbGVyIGJlbG93IHRoZSBhcHAncyBydW4gZmxvb3IgZWl0aGVyIHRocm93c1xuICoge0BsaW5rIEluY29tcGF0aWJsZUluc3RhbGxlclZlcnNpb25FcnJvcn0gKHdoZW5cbiAqIHtAbGluayBSZXNvbHZlQW5kUmVwb3J0Q29tcGF0aWJpbGl0eVBhcmFtcy5zaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyfSlcbiAqIG9yIHByb2NlZWRzIHRvIGxhdW5jaCB3aXRoIGEgd2FybmluZzsgZm9yIGEgcnVubmFibGUtYnV0LWJlbG93LXJlY29tbWVuZGVkXG4gKiBpbnN0YWxsZXIgbG9ncyBhIHdhcm5pbmcuIEJvdGggd2FybmluZ3MgYXJlIHN1cHByZXNzZWQgd2hlblxuICoge0BsaW5rIFJlc29sdmVBbmRSZXBvcnRDb21wYXRpYmlsaXR5UGFyYW1zLnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXN9IGlzXG4gKiBgZmFsc2VgLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcmVzb2x2ZWQgdmVyc2lvbnMgYW5kIHRoZSB3YXJuL3Rocm93IGtub2JzLlxuICogQHJldHVybnMgVGhlIHZlcmRpY3QsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm8gYXNhci1zd2FwIHRvIGNoZWNrLlxuICovXG5mdW5jdGlvbiByZXNvbHZlQW5kUmVwb3J0Q29tcGF0aWJpbGl0eShwYXJhbXM6IFJlc29sdmVBbmRSZXBvcnRDb21wYXRpYmlsaXR5UGFyYW1zKTogSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHsgYXBwVmVyc2lvbiwgaW5zdGFsbGVyVmVyc2lvbiwgc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlciwgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyB9ID0gcGFyYW1zO1xuICBpZiAoYXBwVmVyc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGNvbXBhdGliaWxpdHkgPSByZXNvbHZlSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSh7XG4gICAgYXBwVmVyc2lvbixcbiAgICBpbnN0YWxsZXJWZXJzaW9uLFxuICAgIG1ldGFkYXRhOiBnZXRWZXJzaW9uTWV0YWRhdGEoYXBwVmVyc2lvbilcbiAgfSk7XG5cbiAgY29uc3QgYWN0aW9uID0gcmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHlBY3Rpb24oe1xuICAgIHNob3VsZFRocm93T25JbmNvbXBhdGlibGVJbnN0YWxsZXIsXG4gICAgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyxcbiAgICB0aWVyOiBjb21wYXRpYmlsaXR5LnRpZXJcbiAgfSk7XG5cbiAgaWYgKGFjdGlvbiA9PT0gJ3Rocm93Jykge1xuICAgIHRocm93IG5ldyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3Ioe1xuICAgICAgYXBwVmVyc2lvbjogY29tcGF0aWJpbGl0eS5hcHBWZXJzaW9uLFxuICAgICAgaW5zdGFsbGVyVmVyc2lvbjogZW5zdXJlTm9uTnVsbGFibGUoY29tcGF0aWJpbGl0eS5pbnN0YWxsZXJWZXJzaW9uKSxcbiAgICAgIG1pblJ1bm5hYmxlSW5zdGFsbGVyVmVyc2lvbjogZW5zdXJlTm9uTnVsbGFibGUoY29tcGF0aWJpbGl0eS5taW5SdW5uYWJsZUluc3RhbGxlclZlcnNpb24pXG4gICAgfSk7XG4gIH1cblxuICBpZiAoYWN0aW9uID09PSAnd2Fybi11bnJ1bm5hYmxlJykge1xuICAgIGxvZyhcbiAgICAgIGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBPYnNpZGlhbiBpbnN0YWxsZXIgJHtlbnN1cmVOb25OdWxsYWJsZShjb21wYXRpYmlsaXR5Lmluc3RhbGxlclZlcnNpb24pfSBpcyBiZWxvdyB0aGUgYFxuICAgICAgICArIGBydW4gZmxvb3IgJHtlbnN1cmVOb25OdWxsYWJsZShjb21wYXRpYmlsaXR5Lm1pblJ1bm5hYmxlSW5zdGFsbGVyVmVyc2lvbil9IGZvciBPYnNpZGlhbiAke2NvbXBhdGliaWxpdHkuYXBwVmVyc2lvbn07IGBcbiAgICAgICAgKyAncHJvY2VlZGluZyB0byBsYXVuY2ggKHNob3VsZFRocm93T25JbmNvbXBhdGlibGVJbnN0YWxsZXIgaXMgZmFsc2UpIFx1MjAxNCB0aGUgYm9vdCB3aWxsIGxpa2VseSBkZWFkLWJvb3QuJ1xuICAgICk7XG4gIH0gZWxzZSBpZiAoYWN0aW9uID09PSAnd2Fybi1uYWdnZWQnKSB7XG4gICAgbG9nKGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSAke2Vuc3VyZU5vbk51bGxhYmxlKGNvbXBhdGliaWxpdHkubWVzc2FnZSl9YCk7XG4gIH1cblxuICByZXR1cm4gY29tcGF0aWJpbGl0eTtcbn1cblxuLyoqXG4gKiBEZWNpZGVzIGhvdyB0aGUgcmVxdWVzdGVkIGFwcCAoYXNhcikgdmVyc2lvbiB3aWxsIGJlIGFwcGxpZWQgdG8gYW4gb3duZWRcbiAqIGluc3RhbmNlLCB3aXRob3V0IGRvd25sb2FkaW5nIGFueXRoaW5nIHlldDogYW4gdXBncmFkZS1vbmx5IGFzYXItc3dhcCBvbnRvIHRoZVxuICogc2hlbGwsIGEgZG93bmdyYWRlIHRvIHRoZSBhcHAncyBvd24gaW5zdGFsbGVyIHNoZWxsLCBvciB0aGUgdXNlcidzIG5ld2VzdFxuICogaW5zdGFsbGVkIGFzYXIgd2hlbiBuZWl0aGVyIHZlcnNpb24gaXMgcGlubmVkLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ0RQIHRyYW5zcG9ydCBvcHRpb25zLlxuICogQHBhcmFtIHNoZWxsVmVyc2lvbiAtIFRoZSByZXNvbHZlZCBpbnN0YWxsZXIvc2hlbGwgdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAuXG4gKiBAcmV0dXJucyBUaGUgYXNhciBwbGFuIChhdCBtb3N0IG9uZSBvZiBpdHMgZmllbGRzIGlzIHNldCkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVBc2FyUGxhbihcbiAgb3B0aW9uczogT2JzaWRpYW5DZHBUcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkLFxuICBzaGVsbFZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZFxuKTogUHJvbWlzZTxBc2FyUGxhbj4ge1xuICBpZiAob3B0aW9ucz8ub2JzaWRpYW5WZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBhc2FyVmVyc2lvbiA9IGF3YWl0IHJlc29sdmVDb25jcmV0ZVZlcnNpb24ob3B0aW9ucy5vYnNpZGlhblZlcnNpb24pO1xuICAgIGlmIChzaGVsbFZlcnNpb24gIT09IHVuZGVmaW5lZCAmJiBjb21wYXJlVmVyc2lvbnMoYXNhclZlcnNpb24sIHNoZWxsVmVyc2lvbikgPj0gMCkge1xuICAgICAgcmV0dXJuIHsgYXNhclZlcnNpb25Ub1N3YXA6IGFzYXJWZXJzaW9uIH07XG4gICAgfVxuXG4gICAgLy8gQXNhci1zd2FwIGlzIHVwZ3JhZGUtb25seSwgc28gaXQgY2Fubm90IGFwcGx5IGEgdmVyc2lvbiBvbGRlciB0aGFuIHRoZVxuICAgIC8vIHNoZWxsJ3MgYnVuZGxlZCBvbmUgXHUyMDE0IGFuZCB3aGVuIHRoZSBzaGVsbCB2ZXJzaW9uIGlzIHVua25vd24gKGEgTGludXhcbiAgICAvLyBwYXRoLXBhcnNlIG1pc3MpIHdlIGNhbm5vdCBwcm92ZSB0aGUgc3dhcCB3b3VsZCBhcHBseSBhdCBhbGwuIEluIGJvdGhcbiAgICAvLyBjYXNlcyB1c2UgdGhlIHJlcXVlc3RlZCB2ZXJzaW9uJ3Mgb3duIGluc3RhbGxlciBzaGVsbCwgd2hvc2UgYnVuZGxlZCBhc2FyXG4gICAgLy8gaXMgZXhhY3RseSB0aGlzIHZlcnNpb24sIHNvIHRoZSBwaW4gaXMgYWx3YXlzIGhvbm9yZWQuXG4gICAgbG9nKGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBVc2luZyB0aGUgJHthc2FyVmVyc2lvbn0gaW5zdGFsbGVyIHNoZWxsIChzaGVsbCB2ZXJzaW9uICR7c2hlbGxWZXJzaW9uID8/ICd1bmtub3duJ307IGFzYXItc3dhcCBpcyB1cGdyYWRlLW9ubHkpLmApO1xuICAgIHJldHVybiB7IGRvd25ncmFkZUluc3RhbGxlclZlcnNpb246IGFzYXJWZXJzaW9uIH07XG4gIH1cblxuICBpZiAob3B0aW9ucz8ub2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBuZXdlc3QgPSBmaW5kTmV3ZXN0QXNhcihnZXRPYnNpZGlhbkNvbmZpZ0RpcmVjdG9yeSgpKTtcbiAgICBpZiAobmV3ZXN0ICYmIChzaGVsbFZlcnNpb24gPT09IHVuZGVmaW5lZCB8fCBjb21wYXJlVmVyc2lvbnMobmV3ZXN0LnZlcnNpb24sIHNoZWxsVmVyc2lvbikgPj0gMCkpIHtcbiAgICAgIHJldHVybiB7IGFzYXI6IHsgcGF0aDogbmV3ZXN0LnBhdGgsIHZlcnNpb246IG5ld2VzdC52ZXJzaW9uIH0gfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge307XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIGxvY2FsbHktaW5zdGFsbGVkIE9ic2lkaWFuIHNoZWxsLCB0b2xlcmF0aW5nIGl0cyBhYnNlbmNlLlxuICpcbiAqIFVubGlrZSB7QGxpbmsgcmVzb2x2ZU9ic2lkaWFuRXhlY3V0YWJsZX0gKHdoaWNoIHRocm93cyB3aGVuIE9ic2lkaWFuIGlzIG5vdFxuICogaW5zdGFsbGVkKSwgdGhpcyByZXR1cm5zIGB1bmRlZmluZWRgIGluIHRoYXQgY2FzZSwgc28gYSBjYWxsZXIgcGlubmluZyBhblxuICogaW5zdGFsbGVyIHZlcnNpb24gY2FuIGZhbGwgYmFjayB0byBkb3dubG9hZGluZyB0aGUgcGlubmVkIHNoZWxsIGluc3RlYWQgb2ZcbiAqIGZhaWxpbmcgb24gYSBob3N0IHdpdGggbm8gT2JzaWRpYW4gaW5zdGFsbGVkIChlLmcuIENJKS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgaW5zdGFsbGVkIHNoZWxsJ3MgcGF0aCBhbmQgZGV0ZWN0ZWQgdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAgd2hlblxuICogICBubyBPYnNpZGlhbiBpcyBpbnN0YWxsZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVJbnN0YWxsZWRTaGVsbE9yTnVsbCgpOiBQcm9taXNlPEluc3RhbGxlZFNoZWxsIHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZXhlUGF0aCA9IGF3YWl0IHJlc29sdmVPYnNpZGlhbkV4ZWN1dGFibGUoKTtcbiAgICByZXR1cm4geyBleGVQYXRoLCBzaGVsbFZlcnNpb246IGRldGVjdEluc3RhbGxlZFNoZWxsVmVyc2lvbihleGVQYXRoKSB9O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIHNoZWxsIGV4ZWN1dGFibGUsIGFzYXIgcHJvdmlzaW9uaW5nLCBhbmQgaXNvbGF0ZWQgdXNlci1kYXRhIGRpclxuICogZm9yIGEgaGFybmVzcy1vd25lZCBpbnN0YW5jZSBmcm9tIHRoZSByZXF1ZXN0ZWQgdmVyc2lvbiBrbm9icy5cbiAqXG4gKiAtIGBvYnNpZGlhbkluc3RhbGxlclZlcnNpb25gIHBpbnMgdGhlIEVsZWN0cm9uIHNoZWxsIChkb3dubG9hZHMgKyBleHRyYWN0cyBhXG4gKiAgIHBvcnRhYmxlIGJ1aWxkIHdoZW4gaXQgZGlmZmVycyBmcm9tIHRoZSBpbnN0YWxsZWQgc2hlbGwpLlxuICogLSBgb2JzaWRpYW5WZXJzaW9uYCBwaW5zIHRoZSBhcHA6IGFuIGFzYXItc3dhcCB3aGVuIGl0IGlzID49IHRoZSBzaGVsbCB2ZXJzaW9uXG4gKiAgIChjaGVhcCksIG90aGVyd2lzZSB0aGUgbWF0Y2hpbmcgaW5zdGFsbGVyIHNoZWxsIGlzIHVzZWQgKGRvd25ncmFkZSkuXG4gKiAtIFdoZW4gbmVpdGhlciBpcyBzZXQsIHRoZSB1c2VyJ3MgbmV3ZXN0IGluc3RhbGxlZCBhc2FyIGlzIGNvcGllZCBpbiAoc28gdGhlXG4gKiAgIG93bmVkIGluc3RhbmNlIG1hdGNoZXMgdGhlIHZlcnNpb24gdGhlIHVzZXIgY3VycmVudGx5IHJ1bnMpIHdpdGggemVybyBuZXR3b3JrLlxuICpcbiAqIFRoZSBjb25jcmV0ZSAoYXBwLCBpbnN0YWxsZXIpIHZlcnNpb24gcGFpciBpcyByZXNvbHZlZCAqYmVmb3JlKiBhbnkgc2hlbGwvYXNhclxuICogZG93bmxvYWQsIHNvIGEgcHJvYWN0aXZlIGluc3RhbGxlclx1MjE5NGFwcCBjb21wYXRpYmlsaXR5IGNoZWNrXG4gKiAoe0BsaW5rIHJlc29sdmVJbnN0YWxsZXJDb21wYXRpYmlsaXR5fSkgY2FuIGZhaWwgZmFzdDogYW4gaW5zdGFsbGVyIGJlbG93IHRoZVxuICogYXBwJ3MgcnVuIGZsb29yIHRocm93cyB7QGxpbmsgSW5jb21wYXRpYmxlSW5zdGFsbGVyVmVyc2lvbkVycm9yfSBiZWZvcmVcbiAqIGFueXRoaW5nIGlzIGRvd25sb2FkZWQgb3IgbGF1bmNoZWQgKHN1cGVyc2VkaW5nIHRoZSByZWFjdGl2ZSBkZWFkLWJvb3RcbiAqIGZhc3QtZmFpbCBmb3IgdGFibGUta25vd24gY29tYm9zKSwgYW5kIGEgcnVubmFibGUtYnV0LWJlbG93LXJlY29tbWVuZGVkXG4gKiBpbnN0YWxsZXIgbG9ncyBhIHdhcm5pbmcuIFRoZSB2ZXJkaWN0IGlzIHRocmVhZGVkIG9udG8gdGhlIHJldHVybmVkIGNvbmZpZyBzb1xuICogdGhlIHRyYW5zcG9ydCBjYW4gc3VyZmFjZSBpdCBhcyBkYXRhLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ0RQIHRyYW5zcG9ydCBvcHRpb25zLlxuICogQHJldHVybnMgVGhlIHJlc29sdmVkIG93bmVkLWluc3RhbmNlIGNvbmZpZy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZU93bmVkSW5zdGFuY2VDb25maWcob3B0aW9ucz86IE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T3duZWRJbnN0YW5jZUNvbmZpZz4ge1xuICAvLyBSZXNvbHZlIHRoZSBjb25jcmV0ZSBzaGVsbCAoaW5zdGFsbGVyKSB2ZXJzaW9uIGZpcnN0LCBidXQgZm9yIGEgcGlubmVkXG4gIC8vIGluc3RhbGxlciBERUZFUiByZXNvbHZpbmcvZG93bmxvYWRpbmcgdGhlIGFjdHVhbCBzaGVsbCB1bnRpbCBhZnRlciB0aGVcbiAgLy8gcHJvYWN0aXZlIGNvbXBhdGliaWxpdHkgY2hlY2ssIHNvIGFuIHVucnVubmFibGUgcGluIGZhaWxzIGZhc3QgXHUyMDE0IGJlZm9yZSB0aGVcbiAgLy8gKHBvc3NpYmx5IHNsb3cpIGluc3RhbGxlZC1zaGVsbCBkZXRlY3Rpb24gYW5kIGFueSBkb3dubG9hZC5cbiAgbGV0IGV4ZVBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbGV0IHNoZWxsVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBsZXQgcGlubmVkSW5zdGFsbGVyVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIGlmIChvcHRpb25zPy5vYnNpZGlhbkluc3RhbGxlclZlcnNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgIGV4ZVBhdGggPSBhd2FpdCByZXNvbHZlT2JzaWRpYW5FeGVjdXRhYmxlKCk7XG4gICAgc2hlbGxWZXJzaW9uID0gZGV0ZWN0SW5zdGFsbGVkU2hlbGxWZXJzaW9uKGV4ZVBhdGgpO1xuICB9IGVsc2Uge1xuICAgIC8vIEEgcGlubmVkIGluc3RhbGxlciB2ZXJzaW9uIGZ1bGx5IGRldGVybWluZXMgdGhlIHNoZWxsIHZlcnNpb24gdXAgZnJvbnQsXG4gICAgLy8gd2l0aG91dCByZXF1aXJpbmcgYSBsb2NhbGx5LWluc3RhbGxlZCBPYnNpZGlhbiAoYSBDSSBydW5uZXIgaGFzIG5vbmUpLlxuICAgIHBpbm5lZEluc3RhbGxlclZlcnNpb24gPSBhd2FpdCByZXNvbHZlQ29uY3JldGVWZXJzaW9uKG9wdGlvbnMub2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uKTtcbiAgICBzaGVsbFZlcnNpb24gPSBwaW5uZWRJbnN0YWxsZXJWZXJzaW9uO1xuICB9XG5cbiAgLy8gRGVjaWRlIGhvdyB0aGUgYXBwIChhc2FyKSB2ZXJzaW9uIHdpbGwgYmUgYXBwbGllZCwgc3RpbGwgV0lUSE9VVCBkb3dubG9hZGluZy5cbiAgY29uc3QgcGxhbiA9IGF3YWl0IHJlc29sdmVBc2FyUGxhbihvcHRpb25zLCBzaGVsbFZlcnNpb24pO1xuXG4gIC8vIFRoZSBhcHAgdmVyc2lvbiB0aGF0IHdpbGwgcnVuIGFzIGFuIGFzYXItc3dhcCBvbnRvIGBzaGVsbFZlcnNpb25gIFx1MjAxNCB0aGUgb25seVxuICAvLyBjb21iaW5hdGlvbiB0aGF0IGNhbiBkZWFkLWJvb3QuIFRoZSBkb3duZ3JhZGUgLyBvd24taW5zdGFsbGVyIHBhdGhzIHJ1biB0aGVcbiAgLy8gYXBwJ3Mgb3duIGluc3RhbGxlciBzaGVsbCwgc28gdGhleSBhbHdheXMgYm9vdCBhbmQgYXJlIG5vdCBjaGVja2VkLlxuICBjb25zdCBzd2FwQXBwVmVyc2lvbiA9IHBsYW4uYXNhclZlcnNpb25Ub1N3YXAgPz8gcGxhbi5hc2FyPy52ZXJzaW9uO1xuICBjb25zdCBjb21wYXRpYmlsaXR5ID0gcmVzb2x2ZUFuZFJlcG9ydENvbXBhdGliaWxpdHkoe1xuICAgIGFwcFZlcnNpb246IHN3YXBBcHBWZXJzaW9uLFxuICAgIGluc3RhbGxlclZlcnNpb246IHNoZWxsVmVyc2lvbixcbiAgICBzaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyOiB3aWxsVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcihvcHRpb25zPy5zaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyKSxcbiAgICBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzOiB3aWxsV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyhvcHRpb25zPy5zaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzKVxuICB9KTtcblxuICAvLyBUaGUgcGluIGlzIGtub3duIHJ1bm5hYmxlIFx1MjAxNCByZXNvbHZlL2Rvd25sb2FkIHRoZSBkZWZlcnJlZCBzaGVsbCArIGFzYXIgbm93LlxuICAvLyBSZXVzZSB0aGUgaW5zdGFsbGVkIHNoZWxsIG9ubHkgd2hlbiBpdCBhbHJlYWR5IG1hdGNoZXMgdGhlIHBpbiAoc2F2ZXMgdGhlXG4gIC8vIGRvd25sb2FkKTsgb3RoZXJ3aXNlIGRvd25sb2FkIGFuZCBleHRyYWN0IHRoZSBwaW5uZWQgaW5zdGFsbGVyLlxuICBpZiAocGlubmVkSW5zdGFsbGVyVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgaW5zdGFsbGVkID0gYXdhaXQgcmVzb2x2ZUluc3RhbGxlZFNoZWxsT3JOdWxsKCk7XG4gICAgZXhlUGF0aCA9IGluc3RhbGxlZD8uc2hlbGxWZXJzaW9uID09PSBwaW5uZWRJbnN0YWxsZXJWZXJzaW9uID8gaW5zdGFsbGVkLmV4ZVBhdGggOiBhd2FpdCBlbnN1cmVTaGVsbENhY2hlZChwaW5uZWRJbnN0YWxsZXJWZXJzaW9uKTtcbiAgfVxuICBpZiAocGxhbi5kb3duZ3JhZGVJbnN0YWxsZXJWZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICBleGVQYXRoID0gYXdhaXQgZW5zdXJlU2hlbGxDYWNoZWQocGxhbi5kb3duZ3JhZGVJbnN0YWxsZXJWZXJzaW9uKTtcbiAgfVxuXG4gIGNvbnN0IGFzYXIgPSBwbGFuLmFzYXJWZXJzaW9uVG9Td2FwID09PSB1bmRlZmluZWRcbiAgICA/IHBsYW4uYXNhclxuICAgIDogeyBwYXRoOiBhd2FpdCBlbnN1cmVBc2FyQ2FjaGVkKHBsYW4uYXNhclZlcnNpb25Ub1N3YXApLCB2ZXJzaW9uOiBwbGFuLmFzYXJWZXJzaW9uVG9Td2FwIH07XG5cbiAgcmV0dXJuIHtcbiAgICAuLi4oYXNhciAmJiB7IGFzYXIgfSksXG4gICAgLi4uKGNvbXBhdGliaWxpdHkgJiYgeyBjb21wYXRpYmlsaXR5IH0pLFxuICAgIGV4ZVBhdGg6IGVuc3VyZU5vbk51bGxhYmxlKGV4ZVBhdGgpLFxuXG4gICAgdXNlckRhdGFEaXJlY3Rvcnk6IGNyZWF0ZU93bmVkVXNlckRhdGFEaXJlY3RvcnkoKVxuICB9O1xufVxuXG4vKipcbiAqIFJlbW92ZXMgYENvbm5lY3Rpb25gIGFuZCBgQ29udGVudC1MZW5ndGhgIGZyb20gYSBXZWJEcml2ZXIgcmVxdWVzdCdzIGhlYWRlcnMuXG4gKlxuICogVGhlIGJ1bmRsZWQgYHdlYmRyaXZlcmAgcGFja2FnZSBzZXRzIGJvdGggaGVhZGVycyBleHBsaWNpdGx5LiBUaGV5IGFyZVxuICogZm9yYmlkZGVuIHJlcXVlc3QgaGVhZGVycyBwZXIgdGhlIEZldGNoIHNwZWM6IE5vZGUgdXAgdG8gMjUgYWNjZXB0ZWQgdGhlbVxuICogc2lsZW50bHksIGJ1dCBOb2RlIDI2IHJlamVjdHMgdGhlbSB3aXRoIGBVTkRfRVJSX0lOVkFMSURfQVJHYCwgYnJlYWtpbmcgdGhlXG4gKiBBcHBpdW0gYC9zZXNzaW9uYCByZXF1ZXN0LiBUaGUgdHJhbnNwb3J0IGxheWVyIG1hbmFnZXMgY29ubmVjdGlvbiByZXVzZSBhbmRcbiAqIHRoZSBGZXRjaCBBUEkgY29tcHV0ZXMgYENvbnRlbnQtTGVuZ3RoYCBmcm9tIHRoZSBib2R5LCBzbyBkcm9wcGluZyBib3RoIGlzXG4gKiBzYWZlIG9uIGV2ZXJ5IE5vZGUgdmVyc2lvbi4gU2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vd2ViZHJpdmVyaW8vd2ViZHJpdmVyaW8vaXNzdWVzLzE1MjY1fS5cbiAqXG4gKiBAcGFyYW0gcmVxdWVzdE9wdGlvbnMgLSBUaGUgcmVxdWVzdCBvcHRpb25zIGFib3V0IHRvIGJlIHNlbnQgYnkgV2ViRHJpdmVySU8uXG4gKiBAcmV0dXJucyBUaGUgc2FtZSByZXF1ZXN0IG9wdGlvbnMgd2l0aCB0aGUgZm9yYmlkZGVuIGhlYWRlcnMgcmVtb3ZlZC5cbiAqL1xuZnVuY3Rpb24gc3RyaXBGb3JiaWRkZW5GZXRjaEhlYWRlcnMocmVxdWVzdE9wdGlvbnM6IFJlcXVlc3RJbml0KTogUmVxdWVzdEluaXQge1xuICBpZiAocmVxdWVzdE9wdGlvbnMuaGVhZGVycyBpbnN0YW5jZW9mIEhlYWRlcnMpIHtcbiAgICByZXF1ZXN0T3B0aW9ucy5oZWFkZXJzLmRlbGV0ZSgnQ29ubmVjdGlvbicpO1xuICAgIHJlcXVlc3RPcHRpb25zLmhlYWRlcnMuZGVsZXRlKCdDb250ZW50LUxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVlc3RPcHRpb25zO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBY0EsZ0NBSU87QUFDUCxxQkFJTztBQUNQLHVCQUFpQjtBQUNqQixxQkFHTztBQUNQLHVCQUFxQjtBQUNyQiwwQkFBb0I7QUFvQnBCLDZCQUlPO0FBQ1AseUJBQTBDO0FBQzFDLGlDQUlPO0FBQ1Asa0NBTU87QUFDUCxtQ0FJTztBQUNQLHNCQUdPO0FBQ1AsK0JBTU87QUFDUCxtQ0FLTztBQUNQLDhCQUEy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
2230
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1mYWN0b3J5LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRmFjdG9yeSBmb3IgY3JlYXRpbmcgdHJhbnNwb3J0IGluc3RhbmNlcyBmcm9tIHtAbGluayBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnN9LlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGZhY3RvcnkgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgQ2hpbGRQcm9jZXNzIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB0eXBlIHtcbiAgYXR0YWNoLFxuICByZW1vdGVcbn0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQge1xuICBleGVjRmlsZSxcbiAgZXhlY0ZpbGVTeW5jLFxuICBzcGF3blxufSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBta2R0ZW1wU3luYyxcbiAgc3RhdFN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgaHR0cCBmcm9tICdub2RlOmh0dHAnO1xuaW1wb3J0IHtcbiAgaG9tZWRpcixcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgdHlwZSB7IEFwcGl1bVNlcnZlck1hcmtlciB9IGZyb20gJy4vYXBwaXVtLXNlcnZlci1tYXJrZXIuY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgQXZkTmFtZUNoYW5uZWwsXG4gIEF2ZE5hbWVDaGFubmVsQW5zd2VyXG59IGZyb20gJy4vYXZkLW5hbWUtY2hhbm5lbC5janMnO1xuaW1wb3J0IHR5cGUgeyBBdmRQcm9iZVJlc3VsdCB9IGZyb20gJy4vYXZkLXByb2JlLXZlcmRpY3QuY2pzJztcbmltcG9ydCB0eXBlIHsgRW11bGF0b3JMaXZlbmVzc1Byb2JlT3V0Y29tZSB9IGZyb20gJy4vZW11bGF0b3ItbGl2ZW5lc3MuY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgSG9zdENvbW1hbmRRdWVyeSxcbiAgSG9zdFByb2Nlc3NRdWVyeVJlc3VsdFxufSBmcm9tICcuL2VtdWxhdG9yLXJlY2xhaW0uY2pzJztcbmltcG9ydCB0eXBlIHsgSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB9IGZyb20gJy4vaW5zdGFsbGVyLWNvbXBhdGliaWxpdHkuY2pzJztcbmltcG9ydCB0eXBlIHsgTGF1bmNoZWREZXZpY2VDYW5kaWRhdGUgfSBmcm9tICcuL2xhdW5jaGVkLWRldmljZS1zZWxlY3Rpb24uY2pzJztcbmltcG9ydCB0eXBlIHsgQnVpbGRQb3J0T3duZXJRdWVyeU1lc3NhZ2VQYXJhbXMgfSBmcm9tICcuL3BvcnQtb3duZXItcXVlcnktdmVyZGljdC5janMnO1xuaW1wb3J0IHR5cGUgeyBQcm9jZXNzRXhpdEluZm8gfSBmcm9tICcuL3Byb2Nlc3MtZXhpdC1tZXNzYWdlLmNqcyc7XG5pbXBvcnQgdHlwZSB7XG4gIERlc2t0b3BDZHBUcmFuc3BvcnRDb25maWcsXG4gIE93bmVkSW5zdGFuY2VDb25maWdcbn0gZnJvbSAnLi90cmFuc3BvcnQtZGVza3RvcC1jZHAuY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucyxcbiAgT2JzaWRpYW5DZHBUcmFuc3BvcnRPcHRpb25zLFxuICBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnNcbn0gZnJvbSAnLi90cmFuc3BvcnQtb3B0aW9ucy5janMnO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5pbXBvcnQgdHlwZSB7IFdlZGdlZEFwcGl1bVNlcnZlclJlcG9ydFJlYXNvbiB9IGZyb20gJy4vd2VkZ2VkLWFwcGl1bS1zZXJ2ZXIuY2pzJztcblxuaW1wb3J0IHtcbiAgY2hlY2tJc0RldmljZUxpc3RlZCxcbiAgbGlzdE9ubGluZURldmljZUlkcyxcbiAgcGFyc2VBZGJEZXZpY2VzXG59IGZyb20gJy4vYWRiLWRldmljZS1saXN0LmNqcyc7XG5pbXBvcnQgeyByZXNvbHZlRW11bGF0b3JCaW5hcnlQYXRoIH0gZnJvbSAnLi9hbmRyb2lkLXNkay5janMnO1xuaW1wb3J0IHtcbiAgY2hlY2tJc0FwcGl1bURyaXZlckluc3RhbGxlZCxcbiAgVUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FLFxuICB3aWxsQXV0b0luc3RhbGxBcHBpdW1EZXBlbmRlbmNpZXNcbn0gZnJvbSAnLi9hcHBpdW0tZGVwZW5kZW5jaWVzLmNqcyc7XG5pbXBvcnQge1xuICBjaGVja0lzSGFybmVzc093bmVkQXBwaXVtU2VydmVyLFxuICBjbGVhckFwcGl1bVNlcnZlck1hcmtlcixcbiAgcmVhZEFwcGl1bVNlcnZlck1hcmtlcixcbiAgcmVjb3JkQXBwaXVtU2VydmVyU3RvcEF0dGVtcHQsXG4gIHdyaXRlQXBwaXVtU2VydmVyTWFya2VyXG59IGZyb20gJy4vYXBwaXVtLXNlcnZlci1tYXJrZXIuY2pzJztcbmltcG9ydCB7XG4gIHJlc29sdmVBcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgcmVzb2x2ZVNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgcmVzb2x2ZVNlc3Npb25Db25uZWN0aW9uUmV0cnlUaW1lb3V0SW5NaWxsaXNlY29uZHNcbn0gZnJvbSAnLi9hcHBpdW0tc2Vzc2lvbi1jb25maWcuY2pzJztcbmltcG9ydCB7XG4gIGNoZWNrQXZkRXhpc3RzLFxuICBsaXN0QXZhaWxhYmxlQXZkc1xufSBmcm9tICcuL2F2ZC1saXN0LmNqcyc7XG5pbXBvcnQge1xuICBidWlsZEF2ZE5hbWVDaGFubmVsQXJndW1lbnRzLFxuICBkZXNjcmliZUFkYkNvbW1hbmQsXG4gIEZJUlNUX0FWRF9OQU1FX0NIQU5ORUwsXG4gIHBhcnNlQXZkTmFtZUFuc3dlcixcbiAgcmVzb2x2ZU5leHRBdmROYW1lQ2hhbm5lbFxufSBmcm9tICcuL2F2ZC1uYW1lLWNoYW5uZWwuY2pzJztcbmltcG9ydCB7XG4gIGJ1aWxkQXZkUHJvYmVTdW1tYXJ5LFxuICBidWlsZFVucmVhZGFibGVEZXZpY2VzTWVzc2FnZSxcbiAgY2hlY2tJc0VtdWxhdG9yRGV2aWNlSWQsXG4gIGNsYXNzaWZ5QXZkUHJvYmUsXG4gIHJlc29sdmVBdmRQcm9iZVZlcmRpY3Rcbn0gZnJvbSAnLi9hdmQtcHJvYmUtdmVyZGljdC5janMnO1xuaW1wb3J0IHtcbiAgcmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHlBY3Rpb24sXG4gIHdpbGxUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyLFxuICB3aWxsVGhyb3dPblNpbGVudEFzYXJGYWxsYmFjayxcbiAgd2lsbFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXNcbn0gZnJvbSAnLi9jb21wYXRpYmlsaXR5LW9wdGlvbnMuY2pzJztcbmltcG9ydCB7IGFzc2VydFZhbGlkQ29uZmlnRGlyZWN0b3J5IH0gZnJvbSAnLi9jb25maWctZGlyZWN0b3J5LmNqcyc7XG5pbXBvcnQgeyBnZXRTZXR1cEVycm9yIH0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLmNqcyc7XG5pbXBvcnQge1xuICBjaGVja0RldmljZUlkbGUsXG4gIGNoZWNrTmV0d29ya1ZhbGlkYXRlZCxcbiAgcmVzb2x2ZURldmljZUlkbGVUaW1lb3V0SW5NaWxsaXNlY29uZHMsXG4gIHJlc29sdmVOZXR3b3JrUmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHNcbn0gZnJvbSAnLi9kZXZpY2UtcmVhZGluZXNzLmNqcyc7XG5pbXBvcnQge1xuICBidWlsZEVtdWxhdG9yQXJndW1lbnRzLFxuICBidWlsZEVtdWxhdG9yRW52aXJvbm1lbnQsXG4gIE5FVFNJTV9MT0dfRklMVEVSXG59IGZyb20gJy4vZW11bGF0b3ItYXJndW1lbnRzLmNqcyc7XG5pbXBvcnQgeyBzZWxlY3RFbXVsYXRvckJhY2tlbmRQaWRzIH0gZnJvbSAnLi9lbXVsYXRvci1iYWNrZW5kLmNqcyc7XG5pbXBvcnQge1xuICBidWlsZEVtdWxhdG9yTGl2ZW5lc3NNZXNzYWdlLFxuICByZXNvbHZlRW11bGF0b3JMaXZlbmVzc1ZlcmRpY3Rcbn0gZnJvbSAnLi9lbXVsYXRvci1saXZlbmVzcy5janMnO1xuaW1wb3J0IHtcbiAgY2hlY2tJc01hcmtlZEVtdWxhdG9yUnVubmluZyxcbiAgY2xlYXJFbXVsYXRvck1hcmtlcixcbiAgY2xlYXJFbXVsYXRvck1hcmtlcklmU3RvcHBlZCxcbiAgcmVhZEVtdWxhdG9yTWFya2VyLFxuICByZXNvbHZlRW11bGF0b3JNYXJrZXJWZXJkaWN0LFxuICBzZWxlY3RMaXZlTWFya2VkUGlkcyxcbiAgd3JpdGVFbXVsYXRvck1hcmtlclxufSBmcm9tICcuL2VtdWxhdG9yLW1hcmtlci5janMnO1xuaW1wb3J0IHsgc3Bhd25FbXVsYXRvclJlYXBlciB9IGZyb20gJy4vZW11bGF0b3ItcmVhcGVyLmNqcyc7XG5pbXBvcnQge1xuICBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTLFxuICBBREJfRFVNUFNZU19NQVhfQlVGRkVSX0lOX0JZVEVTLFxuICBFbXVsYXRvclJlY2xhaW1lclxufSBmcm9tICcuL2VtdWxhdG9yLXJlY2xhaW0uY2pzJztcbmltcG9ydCB7XG4gIGJ1aWxkQXZkU25hcHNob3REaXJlY3RvcnlDYW5kaWRhdGVzLFxuICBidWlsZFNuYXBzaG90QWdlTWVzc2FnZVxufSBmcm9tICcuL2VtdWxhdG9yLXNuYXBzaG90LmNqcyc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAnLi9leGVjLmNqcyc7XG5pbXBvcnQgeyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3IgfSBmcm9tICcuL2luY29tcGF0aWJsZS1pbnN0YWxsZXItdmVyc2lvbi1lcnJvci5janMnO1xuaW1wb3J0IHsgcmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2luc3RhbGxlci1jb21wYXRpYmlsaXR5LmNqcyc7XG5pbXBvcnQgeyBJbnRlZ3JhdGlvblNldHVwRmFpbGVkRXJyb3IgfSBmcm9tICcuL2ludGVncmF0aW9uLXNldHVwLWZhaWxlZC1lcnJvci5janMnO1xuaW1wb3J0IHtcbiAga2lsbFByb2Nlc3NUcmVlLFxuICBraWxsUHJvY2Vzc1RyZWVCeVBpZFxufSBmcm9tICcuL2tpbGwtcHJvY2Vzcy10cmVlLmNqcyc7XG5pbXBvcnQge1xuICByZXNvbHZlTGF1bmNoZWREZXZpY2UsXG4gIHNwbGl0TmV3RGV2aWNlc1xufSBmcm9tICcuL2xhdW5jaGVkLWRldmljZS1zZWxlY3Rpb24uY2pzJztcbmltcG9ydCB7XG4gIEhBUk5FU1NfVEVNUF9ESVJfTkFNRSxcbiAgT1dORURfVVNFUl9EQVRBX0RJUl9QUkVGSVgsXG4gIHN3ZWVwRGV2aWNlTGVmdG92ZXJzLFxuICB3aWxsU3dlZXBMZWZ0b3ZlcnNcbn0gZnJvbSAnLi9sZWZ0b3Zlci1jbGVhbnVwLmNqcyc7XG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuaW1wb3J0IHsgbm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzIH0gZnJvbSAnLi9ub3JtYWxpemUtb3B0aW9uYWwtcHJvcGVydGllcy5janMnO1xuaW1wb3J0IHsgZ2V0T2JzaWRpYW5Db25maWdEaXJlY3RvcnkgfSBmcm9tICcuL29ic2lkaWFuLWNvbmZpZy5janMnO1xuaW1wb3J0IHsgcmVzb2x2ZU9ic2lkaWFuRXhlY3V0YWJsZSB9IGZyb20gJy4vb2JzaWRpYW4tZXhlY3V0YWJsZS5janMnO1xuaW1wb3J0IHtcbiAgZGV0ZWN0SW5zdGFsbGVkU2hlbGxWZXJzaW9uLFxuICBlbnN1cmVTaGVsbENhY2hlZFxufSBmcm9tICcuL29ic2lkaWFuLWluc3RhbGxlci5janMnO1xuaW1wb3J0IHsgZ2V0VmVyc2lvbk1ldGFkYXRhIH0gZnJvbSAnLi9vYnNpZGlhbi1tZXRhZGF0YS5janMnO1xuaW1wb3J0IHtcbiAgZW5zdXJlQXNhckNhY2hlZCxcbiAgZmluZE5ld2VzdEFzYXIsXG4gIHJlc29sdmVDb25jcmV0ZVZlcnNpb25cbn0gZnJvbSAnLi9vYnNpZGlhbi12ZXJzaW9uLXN3aXRjaC5janMnO1xuaW1wb3J0IHsgY29tcGFyZVZlcnNpb25zIH0gZnJvbSAnLi9vYnNpZGlhbi12ZXJzaW9uLmNqcyc7XG5pbXBvcnQgeyByZWFkT3duZWRJbnN0YW5jZUV4aXRNYXJrZXIgfSBmcm9tICcuL293bmVkLWluc3RhbmNlLWV4aXQtbWFya2VyLmNqcyc7XG5pbXBvcnQgeyBidWlsZE93bmVkSW5zdGFuY2VFeGl0ZWRFcnJvckZyb21NYXJrZXIgfSBmcm9tICcuL293bmVkLWluc3RhbmNlLWV4aXRlZC1lcnJvci5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRQb3J0T3duZXJRdWVyeU1lc3NhZ2UsXG4gIG5vcm1hbGl6ZVN5bmNFeGVjRXJyb3IsXG4gIHJlc29sdmVQb3J0T3duZXJRdWVyeU91dGNvbWVcbn0gZnJvbSAnLi9wb3J0LW93bmVyLXF1ZXJ5LXZlcmRpY3QuY2pzJztcbmltcG9ydCB7XG4gIHBhcnNlUG9zaXhMc29mUGlkcyxcbiAgcGFyc2VXaW5kb3dzTmV0c3RhdFBpZHNcbn0gZnJvbSAnLi9wb3J0LW93bmVyLmNqcyc7XG5pbXBvcnQge1xuICBhcHBlbmRQcm9jZXNzT3V0cHV0VGFpbCxcbiAgYnVpbGRQcm9jZXNzRXhpdE1lc3NhZ2Vcbn0gZnJvbSAnLi9wcm9jZXNzLWV4aXQtbWVzc2FnZS5janMnO1xuaW1wb3J0IHsgY2hlY2tJc1Byb2Nlc3NBbGl2ZSB9IGZyb20gJy4vcHJvY2Vzcy1saXZlbmVzcy5janMnO1xuaW1wb3J0IHsgcmVzb2x2ZURlYWRCb290R3JhY2VJbk1pbGxpc2Vjb25kcyB9IGZyb20gJy4vcmVuZGVyZXItYm9vdC1kZXRlY3Rpb24uY2pzJztcbmltcG9ydCB7XG4gIHJlc29sdmVBcHBpdW1TcGF3bkZsYWdzLFxuICByZXNvbHZlRW11bGF0b3JTcGF3bkZsYWdzXG59IGZyb20gJy4vc3Bhd24tb3B0aW9ucy5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRUZWFyZG93bk1lc3NhZ2UsXG4gIHJlc29sdmVUZWFyZG93bk91dGNvbWVcbn0gZnJvbSAnLi90ZWFyZG93bi12ZXJkaWN0LmNqcyc7XG5pbXBvcnQge1xuICBBcHBpdW1UcmFuc3BvcnQsXG4gIERFRkFVTFRfQU5EUk9JRF9WQVVMVF9CQVNFX1BBVEhcbn0gZnJvbSAnLi90cmFuc3BvcnQtYXBwaXVtLmNqcyc7XG5pbXBvcnQgeyBEZXNrdG9wQ2RwVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQtZGVza3RvcC1jZHAuY2pzJztcbmltcG9ydCB7XG4gIGFzc2VydE5ldmVyLFxuICBlbnN1cmVOb25OdWxsYWJsZVxufSBmcm9tICcuL3R5cGUtZ3VhcmRzLmNqcyc7XG5pbXBvcnQge1xuICBzaG91bGRIaWRlQXBwaXVtQ29uc29sZSxcbiAgc2hvdWxkSGlkZUVtdWxhdG9yV2luZG93XG59IGZyb20gJy4vdmlzaWJpbGl0eS5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRXZWRnZWRBcHBpdW1TZXJ2ZXJNZXNzYWdlLFxuICBjaGVja0lzQXBwaXVtU3RhdHVzUmVhZHksXG4gIHJlc29sdmVXZWRnZWRBcHBpdW1TZXJ2ZXJSZW1lZHlcbn0gZnJvbSAnLi93ZWRnZWQtYXBwaXVtLXNlcnZlci5janMnO1xuXG5jb25zdCBBUFBfUEFDS0FHRSA9ICdtZC5vYnNpZGlhbic7XG5jb25zdCBBUFBfQUNUSVZJVFkgPSBgJHtBUFBfUEFDS0FHRX0uTWFpbkFjdGl2aXR5YDtcbi8qXG4gKiBIb3cgbWFueSB0aW1lcyB0aGUgQVZEIGFkb3B0aW9uIHByb2JlIGFza3MgYSBkZXZpY2Ugd2hpY2ggQVZEIGl0IGlzIHNlcnZpbmcuXG4gKiBPbmUgcmV0cnksIGJlY2F1c2UgdGhlIGFsdGVybmF0aXZlIHRvIGFuIGFuc3dlciBpcyByZWZ1c2luZyB0byBsYXVuY2g6IGFcbiAqIHNlY29uZCA1cyBsb29rIGlzIGZhciBjaGVhcGVyIHRoYW4gZWl0aGVyIGEgZmFsc2UgcmVmdXNhbCBvciB0aGUgY29sbGlkaW5nXG4gKiBsYXVuY2ggYSBkaXNjYXJkZWQgdGltZW91dCB1c2VkIHRvIGF1dGhvcml6ZSAoc2VlIGBhdmQtcHJvYmUtdmVyZGljdC50c2ApLlxuICovXG5jb25zdCBBVkRfUFJPQkVfQVRURU1QVF9DT1VOVCA9IDI7XG4vKlxuICogVGhlIGNvbm5lY3Rpdml0eSBkdW1wIGdldHMgYSBidWRnZXQgb2YgaXRzIE9XTiwgd2VsbCBhYm92ZSB0aGUgNXMgdGhlIG90aGVyXG4gKiBwcm9iZXMgc2hhcmUgXHUyMDE0IG5vdCBiZWNhdXNlIHRoZSBkdW1wIGlzIHNsb3cgKG1lYXN1cmVkIDAuOS0yLjRzIG9uIGEgcmVzcG9uc2l2ZVxuICogZ3Vlc3QsIGFsb25nc2lkZSBgZ2V0cHJvcGAncyAwLjctMi4xcyksIGJ1dCBiZWNhdXNlIGl0IHJ1bnMgaW4gdGhlIHdpbmRvd1xuICogd2hlcmUgcmVzaWR1YWwgcG9zdC1ib290IGNvbnRlbnRpb24gc3RpbGwgaW5mbGF0ZXMgZXZlcnkgYGFkYmAgcm91bmQtdHJpcFxuICogMjUtNTB4IChMMTkpLiBBdCA1cyBpdCBvdmVycmFuIG9uIEVWRVJZIHBvbGwgb2YgdGhlIGZpcnN0IGVuZC10by1lbmQgcnVuLFxuICogYW5kIGFuIG92ZXJydW4gaXMgcmVwb3J0ZWQgYXMgXCJubyBuZXR3b3JrXCIsIHNvIHRvbyBzbWFsbCBhIGJ1ZGdldCBkb2VzIG5vdFxuICogZGVncmFkZSB0aGlzIGdhdGUgXHUyMDE0IGl0IHNpbGVudGx5IGRpc2FibGVzIGl0IHdoaWxlIHRoZSBnYXRlIGNsYWltcyB0aGVcbiAqIG9wcG9zaXRlLiAzMHMgaXMgfjE1eCB0aGUgaWRsZSBjb3N0LCB3aGljaCBpcyB0aGF0IGluZmxhdGlvbiB3aXRoIHJvb20uXG4gKi9cbmNvbnN0IEFEQl9EVU1QU1lTX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzBfMDAwO1xuY29uc3QgQVBQSVVNX0NPTk5FQ1RJT05fUkVUUllfQ09VTlQgPSAzO1xuY29uc3QgQVBQSVVNX0VTQ0FMQVRFRF9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IEFQUElVTV9PVVRQVVRfVEFJTF9NQVhfTEVOR1RIID0gODAwMDtcbmNvbnN0IEFQUElVTV9QUkVGTElHSFRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA1MDAwO1xuY29uc3QgQVBQSVVNX1NUQVJUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgQVBQSVVNX1NUT1BfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxNV8wMDA7XG5jb25zdCBBREJfVkFVTFRfU1dFRVBfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG4vLyBBcHBpdW0gaW5zZWN1cmUgZmVhdHVyZSBsZXR0aW5nIHRoZSBVaUF1dG9tYXRvcjIgZHJpdmVyIGF1dG8tZG93bmxvYWQgYVxuLy8gY2hyb21lZHJpdmVyIG1hdGNoaW5nIE9ic2lkaWFuJ3MgV2ViVmlldyBDaHJvbWUgdmVyc2lvbi4gRW5hYmxpbmcgaXQgb24gdGhlXG4vLyBBcHBpdW0gc2VydmVyIChpdCBoYXMgbm8gZWZmZWN0IGFzIGEgY2FwYWJpbGl0eSkgYXZvaWRzIHRoZSBmYWlsdXJlXG4vLyBcIk5vIENocm9tZWRyaXZlciBmb3VuZCB0aGF0IGNhbiBhdXRvbWF0ZSBDaHJvbWUgLi4uXCIuXG5jb25zdCBDSFJPTUVEUklWRVJfQVVUT0RPV05MT0FEX0ZFQVRVUkUgPSAndWlhdXRvbWF0b3IyOmNocm9tZWRyaXZlcl9hdXRvZG93bmxvYWQnO1xuY29uc3QgREVGQVVMVF9UUkFOU1BPUlRfVFlQRSA9ICdvYnNpZGlhbi1jZHAnO1xuY29uc3QgQU5EUk9JRF9BUFBJVU1fVFJBTlNQT1JUX1RZUEU6IE9ic2lkaWFuQW5kcm9pZEFwcGl1bVRyYW5zcG9ydE9wdGlvbnNbJ3R5cGUnXSA9ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bSc7XG5jb25zdCBERVZJQ0VfSURMRV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG4vKlxuICogQnVkZ2V0IGZvciBlYWNoIG9mIHRoZSB0d28gbGl2ZW5lc3MgcHJvYmVzIHRha2VuIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGVcbiAqIHNlc3Npb24gKHNlZSBgZW11bGF0b3ItbGl2ZW5lc3MudHNgKS4gV2VsbCBhYm92ZSB0aGUgNXMgdGhlIHByZWZsaWdodCBwcm9iZXNcbiAqIHNoYXJlLCBiZWNhdXNlIHRoaXMgb25lIHJ1bnMgaW4gdGhlIHBvc3QtYm9vdCBjb250ZW50aW9uIHdpbmRvdyB0aGF0IGluZmxhdGVzXG4gKiBldmVyeSBgYWRiYCByb3VuZC10cmlwIDI1LTUweCAoTDQ1KSBcdTIwMTQgYW5kIGhlcmUgYSBmYWxzZSBcIm5vIGFuc3dlclwiIHdvdWxkXG4gKiBhYm9ydCBhIHJ1biB0aGF0IHdhcyBhYm91dCB0byB3b3JrLCB3aGljaCBpcyBhIHdvcnNlIGVycm9yIHRoYW4gd2FpdGluZy5cbiAqIDE1cyBpcyB3aGF0IHRoZSBzaXggaGFuZC1ib290cyB0aGF0IG1lYXN1cmVkIHRoZSB3ZWRnZSB1c2VkLCBhbmQgbm8gaGVhbHRoeVxuICogZ3Vlc3QgY2FtZSBjbG9zZSB0byBpdDogdGhlIGZhaWx1cmVzIGh1bmcgaW5kZWZpbml0ZWx5IHJhdGhlciB0aGFuIGFuc3dlcmluZ1xuICogc2xvd2x5LlxuICovXG5jb25zdCBERVZJQ0VfTElWRU5FU1NfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxNV8wMDA7XG4vKlxuICogSG93IG1hbnkgdGltZXMgZWFjaCBsaXZlbmVzcyBwcm9iZSBpcyBhc2tlZCBiZWZvcmUgaXRzIHNpbGVuY2UgaXMgYmVsaWV2ZWQuXG4gKiBPbmUgcmV0cnksIG1hdGNoaW5nIGBBVkRfUFJPQkVfQVRURU1QVF9DT1VOVGAgYW5kIGZvciB0aGUgc2FtZSByZWFzb246IHRoZVxuICogdmVyZGljdCBhYm9ydHMgdGhlIHJ1biwgc28gYSBzZWNvbmQgbG9vayBpcyBmYXIgY2hlYXBlciB0aGFuIGEgd3JvbmcgY2FsbC5cbiAqL1xuY29uc3QgREVWSUNFX0xJVkVORVNTX0FUVEVNUFRfQ09VTlQgPSAyO1xuLypcbiAqIEhvdyBtYW55IGVtdWxhdG9ycyBhIHJ1biBtYXkgYm9vdCBiZWZvcmUgZ2l2aW5nIHVwLiBPbmUgcmV0cnk6IHRoZSB3ZWRnZSB0aGF0XG4gKiBtb3RpdmF0ZXMgaXQgaXMgbm90IGRldGVybWluaXN0aWMgXHUyMDE0IG1lYXN1cmVkIDIwMjYtMDktMDUsIGEgZmlyc3QgZW11bGF0b3Igd2VudFxuICogcXVpZXQgMTI5cyBpbiBhbmQgdGhlIHJlcGxhY2VtZW50IGJvb3RlZCAxMXMgbGF0ZXIgcmFuIHRoZSB3aG9sZSBzdWl0ZSBcdTIwMTQgYnV0IGFcbiAqIGNvbGQgYm9vdCBjb3N0cyB+OTAtMjIwcywgc28gYSBzZWNvbmQgZmFpbHVyZSBpcyB3aGVyZSB0aGUgcnVuIHNob3VsZCBzdG9wIGFuZFxuICogc2F5IHNvIHJhdGhlciB0aGFuIGtlZXAgcGF5aW5nLlxuICovXG5jb25zdCBFTVVMQVRPUl9CT09UX0FUVEVNUFRfQ09VTlQgPSAyO1xuY29uc3QgRU1VTEFUT1JfQk9PVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5jb25zdCBFTVVMQVRPUl9CT09UX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTIwXzAwMDtcbmNvbnN0IEVNVUxBVE9SX0xJU1RfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxMF8wMDA7XG5jb25zdCBFTVVMQVRPUl9PVVRQVVRfVEFJTF9NQVhfTEVOR1RIID0gODAwMDtcbmNvbnN0IEhUVFBfTVVMVElQTEVfQ0hPSUNFUyA9IDMwMDtcbmNvbnN0IEhUVFBfT0sgPSAyMDA7XG4vLyBUaGUgVzNDIGRlZmF1bHQsIHJlc3RhdGVkIGJlY2F1c2UgYHRpbWVvdXRzYCBpcyBzZXQgYXMgYSB3aG9sZSBiYWc7IG5vIGVsZW1lbnQgaXMgZXZlciBsb2NhdGVkIGltcGxpY2l0bHkgaGVyZS5cbmNvbnN0IElNUExJQ0lUX1dBSVRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAwO1xuY29uc3QgS0VZQ09ERV9NRU5VID0gODI7XG5jb25zdCBLRVlDT0RFX1dBS0VVUCA9IDIyNDtcbmNvbnN0IE1JTExJU0VDT05EU19QRVJfU0VDT05EID0gMTAwMDtcbmNvbnN0IE5FVFdPUktfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAyMDAwO1xuLypcbiAqIEhvdyBsb25nIHRoZSBzZXJ2ZXIgd2FpdHMgZm9yIGEgbmV3IGNvbW1hbmQgYmVmb3JlIGFzc3VtaW5nIHRoZSBjbGllbnQgcXVpdFxuICogYW5kIGVuZGluZyB0aGUgc2Vzc2lvbi4gQXBwaXVtIHJlYWRzIGBuZXdDb21tYW5kVGltZW91dGAgaW4gU0VDT05EUywgd2hpY2ggdGhlXG4gKiBuYW1lIHRoaXMgY29uc3RhbnQgdXNlZCB0byBjYXJyeSAoYENPTU1BTkRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNgKSBnb3RcbiAqIHdyb25nIFx1MjAxNCB0aGUgdmFsdWUgd2FzIGFsd2F5cyB0aGUgaW50ZW5kZWQgZml2ZSBtaW51dGVzLCBhbmQgb25seSB0aGUgdW5pdCBpblxuICogdGhlIG5hbWUgd2FzIGEgbGllLiBJdCBpcyB1bnJlbGF0ZWQgdG8gdGhlIHBlci1zY3JpcHQgY2FwLCB3aGljaCBpc1xuICogYHRpbWVvdXRzLnNjcmlwdGAuXG4gKi9cbmNvbnN0IE5FV19DT01NQU5EX1RJTUVPVVRfSU5fU0VDT05EUyA9IDMwMDtcbi8vIFRoZSBXM0MgZGVmYXVsdCwgcmVzdGF0ZWQgZm9yIHRoZSBzYW1lIHJlYXNvbiBhcyB0aGUgaW1wbGljaXQgd2FpdCBhYm92ZS5cbmNvbnN0IFBBR0VfTE9BRF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDMwMF8wMDA7XG4vKlxuICogVGhlIHBvcnQgcXVlcnkncyBvd24gYnVkZ2V0LCBoZWxkIGFwYXJ0IGZyb20gdGhlIHdob2xlLWhvc3QgcHJvY2VzcyBsaXN0aW5nJ3NcbiAqIGV2ZW4gdGhvdWdoIGJvdGggcnVuIGluIHRoZSBzYW1lIGNvbnRlbmRlZCB3aW5kb3cuIEl0IHVzZWQgdG8gYm9ycm93XG4gKiBgSE9TVF9QUk9DRVNTX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTYCwgd2hpY2ggd2FzIGZpbmUgd2hpbGUgdGhhdCB3YXNcbiAqIGFsc28gMzBzIFx1MjAxNCBidXQgdGhhdCBvbmUgd2FzIHJhaXNlZCB0byAxMjBzIG9uIGEgbWVhc3VyZW1lbnQgb2YgYHRhc2tsaXN0YFxuICogd2Fsa2luZyB+NTQwIHByb2Nlc3NlcywgYW5kIGBuZXRzdGF0IC1hbm9gIC8gYGxzb2YgLXRpYCBkb2VzIG5vdGhpbmcgb2YgdGhlXG4gKiBraW5kLiBJbmhlcml0aW5nIGEgNHggcmlzZSBvbiBzb21lYm9keSBlbHNlJ3MgZXZpZGVuY2UgaXMgaG93IGEgYnVkZ2V0IHN0b3BzXG4gKiBtZWFuaW5nIGFueXRoaW5nLCBhbmQgdGhpcyBvbmUgZ2F0ZXMgdGhlIHRlYXJkb3duIGVzY2FsYXRpb24gZm9yIHRoZSBBcHBpdW1cbiAqIHNlcnZlciByYXRoZXIgdGhhbiB0aGUgZW11bGF0b3IuXG4gKi9cbmNvbnN0IFBPUlRfT1dORVJfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG5jb25zdCBTRVJWRVJfSU5TVEFMTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEyMF8wMDA7XG5jb25zdCBTRVJWRVJfTEFVTkNIX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTIwXzAwMDtcbi8qXG4gKiBUaGUgc3luYyB0ZWFyZG93biBydW5zIGluc2lkZSBgcHJvY2Vzcy5vbignZXhpdCcpYCwgc28gdGhpcyBxdWVyeSBibG9ja3MgdGhlXG4gKiBleGl0IGl0c2VsZi4gU2hvcnQgb24gcHVycG9zZTogbG9zaW5nIHRoZSBlc2NhbGF0aW9uIGlzIGJldHRlciB0aGFuIGhvbGRpbmdcbiAqIHRoZSBoYW5kbGVyIGZvciB0aGUgYXN5bmMgcGF0aCdzIDMwcywgYW5kIHRoZSBzeW5jIGxvZyBuZXZlciBjbGFpbXMgYVxuICogdmVyaWZpZWQgc3RvcCBhbnl3YXkuXG4gKi9cbmNvbnN0IFNZTkNfVEVBUkRPV05fUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA1MDAwO1xuXG4vKipcbiAqIEhvdyB0aGUgcmVxdWVzdGVkIGFwcCAoYXNhcikgdmVyc2lvbiB3aWxsIGJlIGFwcGxpZWQgdG8gYW4gb3duZWQgaW5zdGFuY2U7IGF0XG4gKiBtb3N0IG9uZSBmaWVsZCBpcyBzZXQgKHNlZSB7QGxpbmsgcmVzb2x2ZUFzYXJQbGFufSkuXG4gKi9cbmludGVyZmFjZSBBc2FyUGxhbiB7XG4gIC8qKlxuICBUaGUgdXNlcidzIG5ld2VzdCBpbnN0YWxsZWQgYXNhciB0byBwcm92aXNpb24gYXMtaXMgKG5vIGRvd25sb2FkKS5cbiAgICovXG4gIHJlYWRvbmx5IGFzYXI/OiBPd25lZEluc3RhbmNlQ29uZmlnWydhc2FyJ107XG5cbiAgLyoqXG4gIFRoZSBhcHAgdmVyc2lvbiB0byBkb3dubG9hZCBhbmQgYXNhci1zd2FwIG9udG8gdGhlIHNoZWxsLlxuICAgKi9cbiAgcmVhZG9ubHkgYXNhclZlcnNpb25Ub1N3YXA/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBhcHAgdmVyc2lvbiB3aG9zZSBvd24gaW5zdGFsbGVyIHNoZWxsIHRvIGRvd25sb2FkIChhIGRvd25ncmFkZSkuXG4gICAqL1xuICByZWFkb25seSBkb3duZ3JhZGVJbnN0YWxsZXJWZXJzaW9uPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIE91dGNvbWUgb2Ygb25lIGBkdW1wc3lzIGNvbm5lY3Rpdml0eWAgcHJvYmU6IGV4YWN0bHkgb25lIGZpZWxkIGlzIHNldC5cbiAqXG4gKiBBIGZhaWxlZCBwcm9iZSBjYXJyaWVzICoqd2h5KiogaXQgZmFpbGVkIHJhdGhlciB0aGFuIGNvbGxhcHNpbmcgaW50byBcIm5vXG4gKiBvdXRwdXRcIiwgYmVjYXVzZSB0aGUgdHdvIGZhaWx1cmVzIGxvb2sgbm90aGluZyBhbGlrZSBpbiBwcmFjdGljZSBhbmQgb25seSBvbmVcbiAqIG9mIHRoZW0gaXMgd29ydGggd2FpdGluZyBvdXQgXHUyMDE0IGEgMzBzIHRpbWVvdXQgaXMgYSBjb250ZW5kZWQgZ3Vlc3QsIHdoaWxlIGFuXG4gKiBpbnN0YW50IGBlcnJvcjogY2xvc2VkYCBpcyBhIGRlYWQgb25lLlxuICovXG5pbnRlcmZhY2UgQ29ubmVjdGl2aXR5UHJvYmVSZXN1bHQge1xuICAvKipcbiAgV2h5IHRoZSBwcm9iZSBmYWlsZWQsIHNldCBpZmYgaXQgZGlkIG5vdCBhbnN3ZXIuXG4gICAqL1xuICByZWFkb25seSBmYWlsdXJlUmVhc29uPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgcmF3IGR1bXAsIHNldCBpZmYgdGhlIHByb2JlIGFuc3dlcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0Pzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFRoZSB0d28gcG9zdC1ib290IHJlYWRpbmVzcyBidWRnZXRzLCBjYXJyaWVkIHRvZ2V0aGVyIHNvIHRoZSBzdGFydGVkLWRldmljZVxuICogYW5kIHJldXNlZC1kZXZpY2UgYnJhbmNoZXMgY2Fubm90IGRyaWZ0IGFwYXJ0IG9uIHdoaWNoIGdhdGVzIHRoZXkgcnVuLlxuICovXG5pbnRlcmZhY2UgRGV2aWNlUmVhZGluZXNzVGltZW91dHMge1xuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBwb3N0LWJvb3QgZGV2aWNlLWlkbGUgd2FpdCAoYDBgIHNraXBzIGl0KS5cbiAgICovXG4gIHJlYWRvbmx5IGRldmljZUlkbGVUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBuZXR3b3JrLXJlYWR5IHdhaXQgKGAwYCBza2lwcyBpdCkuXG4gICAqL1xuICByZWFkb25seSBuZXR3b3JrUmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgZW11bGF0b3IncyBjYXB0dXJlZCBvdXRwdXQsIGNhcnJpZWQgcGFzdCBib290IHNvIGEgZmFpbHVyZSBkdXJpbmcgc2Vzc2lvblxuICogY3JlYXRpb24gY2FuIHN0aWxsIHF1b3RlIGl0LlxuICpcbiAqIEJvb3QgdXNlZCB0byBiZSB0aGUgZW5kIG9mIHRoZSBlbXVsYXRvcidzIHVzZWZ1bG5lc3MgYXMgYSB3aXRuZXNzOiB0aGUgY2FwdHVyZVxuICogd2FzIGZyb3plbiB0aGUgbW9tZW50IGEgZGV2aWNlIGFwcGVhcmVkLCBhbmQgbm90aGluZyByZWFkIGl0IGFnYWluLiBCdXQgdGhlXG4gKiBsaW5lcyB0aGF0IGV4cGxhaW4gYSB3ZWRnZSBcdTIwMTQgYGRldGVjdGVkIGEgaGFuZ2luZyB0aHJlYWQgJ1FFTVUyIG1haW4gbG9vcCdgLFxuICogbmV0c2ltJ3MgYFVuYWJsZSB0byByZWNvbm5lY3QgdG8gcGFja2V0IHN0cmVhbWVyYCBcdTIwMTQgYXJlIHByaW50ZWQgKmFmdGVyKiB0aGF0LFxuICogd2hpbGUgdGhlIGhhcm5lc3MgaXMgaW5zaWRlIGBlc3RhYmxpc2hTZXNzaW9uYC4gU28gdGhlIHdpbmRvdyBub3cgY2xvc2VzIHdoZW5cbiAqIHRoZSBzZXNzaW9uIGlzIGVzdGFibGlzaGVkIHJhdGhlciB0aGFuIHdoZW4gdGhlIGRldmljZSBhcHBlYXJzLCBhbmQgdGhpcyBwYWlyXG4gKiBpcyB3aGF0IHRoZSBzZXNzaW9uIHBhdGggbmVlZHMgdG8gaG9sZCB0byBkbyB0aGF0IChzZWUgYGVtdWxhdG9yLWxpdmVuZXNzLnRzYCkuXG4gKi9cbmludGVyZmFjZSBFbXVsYXRvckNhcHR1cmUge1xuICAvKipcbiAgUmV0dXJucyB0aGUgY2FwdHVyZWQgc3Rkb3V0K3N0ZGVyciB0YWlsIChib3VuZGVkIHRvIHRoZSBtb3N0IHJlY2VudCBvdXRwdXQpLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVhZDogKCkgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICBGcmVlemVzIHRoZSB0YWlsLiBDYWxsZWQgb25jZSB0aGUgc2Vzc2lvbiBpcyBlc3RhYmxpc2hlZCBhbmQgdGhlIGVtdWxhdG9yIGhhcyBub3RoaW5nIGxlZnQgdG8gZXhwbGFpbi5cbiAgICovXG4gIHJlYWRvbmx5IHN0b3A6ICgpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIEFwcGl1bVRyYW5zcG9ydEZhY3RvcnkuZW5zdXJlRGV2aWNlQ29ubmVjdGVkfS5cbiAqL1xuaW50ZXJmYWNlIEVuc3VyZURldmljZUNvbm5lY3RlZFBhcmFtcyB7XG4gIC8qKlxuICBBVkQgbmFtZSB0byBjb25uZWN0IHRvIChzdGFydGluZyBhIG5ldyBlbXVsYXRvciBpZiBub3QgYWxyZWFkeSBydW5uaW5nKS5cbiAgICovXG4gIHJlYWRvbmx5IGF2ZE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBwb3N0LWJvb3QgZGV2aWNlLWlkbGUgd2FpdCAoYDBgIHNraXBzIGl0KS5cbiAgICovXG4gIHJlYWRvbmx5IGRldmljZUlkbGVUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgV2hldGhlciB0aGUgYXV0by1zdGFydGVkIGVtdWxhdG9yIHdpbmRvdyBpcyBzaG93biAob21pdHRlZCBcdTIxOTIgaGlkZGVuKS5cbiAgICovXG4gIHJlYWRvbmx5IGlzRW11bGF0b3JWaXNpYmxlPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBuZXR3b3JrLXJlYWR5IHdhaXQgKGAwYCBza2lwcyBpdCkuXG4gICAqL1xuICByZWFkb25seSBuZXR3b3JrUmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgV2hldGhlciB0aGUgYXV0by1zdGFydGVkIGVtdWxhdG9yIG1heSByZXN1bWUgYW5kIHJlZnJlc2ggdGhlIEFWRCdzIGJvb3Qgc25hcHNob3QgKG9taXR0ZWQgXHUyMTkyIGNvbGQgYm9vdCkuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRSZXVzZUVtdWxhdG9yU25hcHNob3Q/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeS5lbnN1cmVEZXZpY2VDb25uZWN0ZWR9LlxuICovXG5pbnRlcmZhY2UgRW5zdXJlRGV2aWNlQ29ubmVjdGVkUmVzdWx0IHtcbiAgLyoqXG4gIFRoZSBhY3R1YWwgZGV2aWNlIElEIHRoYXQgaXMgY29ubmVjdGVkIChtYXkgZGlmZmVyIGZyb20gdGhlIHJlcXVlc3RlZCBvbmUpLlxuICAgKi9cbiAgcmVhZG9ubHkgYWN0dWFsRGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGVtdWxhdG9yJ3Mgb3V0cHV0IGNhcHR1cmUsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBpdC4gQWJzZW50IGZvciBhblxuICAgKiBhZG9wdGVkIGRldmljZSwgd2hvc2UgZW11bGF0b3IgdGhpcyBydW4gbmV2ZXIgc3Bhd25lZCBhbmQgd2hvc2Ugb3V0cHV0IGl0XG4gICAqIHRoZXJlZm9yZSBuZXZlciBoYWQuXG4gICAqL1xuICByZWFkb25seSBlbXVsYXRvckNhcHR1cmU/OiBFbXVsYXRvckNhcHR1cmUgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBwcm9jZXNzLCBpZiBvbmUgd2FzIGF1dG8tc3RhcnRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGVtdWxhdG9yUHJvY2Vzcz86IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIGVtdWxhdG9yIHByb2Nlc3NlcyB0aGlzIHJ1biBpcyByZXNwb25zaWJsZSBmb3Iga2lsbGluZyBcdTIwMTQgdGhlIGxhdW5jaGVyXG4gICAqIHBsdXMgdGhlIFFFTVUgYmFja2VuZCBpdCBmb3JrZWQsIGlkZW50aWZpZWQgYnkgZGlmZmluZyB0aGUgaG9zdCdzIHByb2Nlc3NcbiAgICogbGlzdCBhY3Jvc3MgdGhlIGxhdW5jaC4gRW1wdHkgd2hlbiB0aGUgZGV2aWNlIHdhcyByZXVzZWQgcmF0aGVyIHRoYW5cbiAgICogc3RhcnRlZC4gU2VlIGBlbXVsYXRvci1iYWNrZW5kLnRzYCBmb3Igd2h5IHRoZSBsYXVuY2hlcidzIFBJRCBhbG9uZSBpcyBub3RcbiAgICogZW5vdWdoLlxuICAgKi9cbiAgcmVhZG9ubHkgb3duZWRFbXVsYXRvclBpZHM6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBBcHBpdW1UcmFuc3BvcnRGYWN0b3J5LmVzdGFibGlzaFNlc3Npb259LlxuICovXG5pbnRlcmZhY2UgRXN0YWJsaXNoU2Vzc2lvblBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQW5kcm9pZCBwYWNrYWdlIHRoZSBzZXNzaW9uIGRyaXZlcy5cbiAgICovXG4gIHJlYWRvbmx5IGFwcElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBtYXJrZXIgb2YgdGhlIGFkb3B0ZWQgc2VydmVyLCB3aGVuIGFuIGVhcmxpZXIgcnVuIG9mIHRoaXMgaGFybmVzcyBsZWZ0IG9uZS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVNlcnZlck1hcmtlcjogQXBwaXVtU2VydmVyTWFya2VyIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBSZXNvbHZlZCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgYSByZXBsYWNlbWVudCBBcHBpdW0gc2VydmVyIHRvIGJlY29tZSByZWFkeS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBkZXZpY2UgdGhlIHNlc3Npb24gaXMgZXN0YWJsaXNoZWQgYWdhaW5zdC5cbiAgICovXG4gIHJlYWRvbmx5IGRldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhlIHNlcnZlciB3YXMgYWRvcHRlZCByYXRoZXIgdGhhbiBzdGFydGVkIGJ5IHRoaXMgcnVuLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNBZG9wdGVkU2VydmVyOiBib29sZWFuO1xuXG4gIC8qKlxuICBXaGV0aGVyIGEgcmVwbGFjZW1lbnQgc2VydmVyJ3MgY29uc29sZSB3aW5kb3cgaXMgc2hvd24gKG9taXR0ZWQgXHUyMTkyIGhpZGRlbikuXG4gICAqL1xuICByZWFkb25seSBpc0FwcGl1bUNvbnNvbGVWaXNpYmxlPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIEFwcGl1bSBzZXJ2ZXIgcG9ydC5cbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcblxuICAvKipcbiAgUmVzb2x2ZWQgcGVyLXNjcmlwdCAocGVyLWBldmFsSW5PYnNpZGlhbmApIGNhcCBpbiBtaWxsaXNlY29uZHMsIHNlbnQgYXMgdGhlIFczQyBgdGltZW91dHMuc2NyaXB0YCBjYXBhYmlsaXR5LlxuICAgKi9cbiAgcmVhZG9ubHkgc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFJlc29sdmVkIFdlYkRyaXZlcklPIGNvbm5lY3Rpb24gcmV0cnkgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG4gICAqL1xuICByZWFkb25seSBzZXNzaW9uQ29ubmVjdGlvblJldHJ5VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFdoZXRoZXIgQXBwaXVtIGF1dG8tc3RhcnQgaXMgYWxsb3dlZCBcdTIwMTQgYSBgZmFsc2VgIGhlcmUgYWxzbyBmb3JiaWRzIHJlcGxhY2luZyBhIHdlZGdlZCBzZXJ2ZXIuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRBdXRvU3RhcnRBcHBpdW0/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgQXBwaXVtIHNlcnZlciBVUkwuXG4gICAqL1xuICByZWFkb25seSB1cmw6IFVSTDtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2Yge0BsaW5rIEFwcGl1bVRyYW5zcG9ydEZhY3RvcnkuZXN0YWJsaXNoU2Vzc2lvbn0uXG4gKi9cbmludGVyZmFjZSBFc3RhYmxpc2hTZXNzaW9uUmVzdWx0IHtcbiAgLyoqXG4gIFRoZSByZXBsYWNlbWVudCBBcHBpdW0gc2VydmVyIHByb2Nlc3MsIHdoZW4gYSB3ZWRnZWQgb25lIGhhZCB0byBiZSByZXN0YXJ0ZWQuXG4gICAqL1xuICByZWFkb25seSBhcHBpdW1Qcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgZXN0YWJsaXNoZWQgc2Vzc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IGJyb3dzZXI6IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgcmVtb3RlPj47XG59XG5cbi8qKlxuICogVGhlIGxvY2FsbHktaW5zdGFsbGVkIE9ic2lkaWFuIHNoZWxsIHJlc29sdmVkIGJ5IHtAbGluayByZXNvbHZlSW5zdGFsbGVkU2hlbGxPck51bGx9LlxuICovXG5pbnRlcmZhY2UgSW5zdGFsbGVkU2hlbGwge1xuICAvKipcbiAgQWJzb2x1dGUgcGF0aCB0byB0aGUgaW5zdGFsbGVkIHNoZWxsIGV4ZWN1dGFibGUuXG4gICAqL1xuICByZWFkb25seSBleGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBkZXRlY3RlZCBzaGVsbCB2ZXJzaW9uLCBvciBgdW5kZWZpbmVkYCB3aGVuIGl0IGNhbm5vdCBiZSBkZXRlcm1pbmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hlbGxWZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQSBzcGF3bmVkIGNoaWxkIHByb2Nlc3MgKHRoZSBBbmRyb2lkIGVtdWxhdG9yIG9yIHRoZSBBcHBpdW0gc2VydmVyKSB0b2dldGhlclxuICogd2l0aCBoZWxwZXJzIHRvIGluc3BlY3QgaXRzIGNhcHR1cmVkIG91dHB1dCBhbmQgZXhpdCBzdGF0dXMuXG4gKi9cbmludGVyZmFjZSBQYXJzZVBvcnRPd25lclBpZHNQYXJhbXMge1xuICAvKipcbiAgUmF3IHN0ZG91dCBvZiB0aGUgcGxhdGZvcm0ncyBwb3J0IHF1ZXJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0OiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwb3J0IHRoYXQgd2FzIHF1ZXJpZWQuXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBQcm9jZXNzTGF1bmNoIHtcbiAgLyoqXG4gIFRoZSBzcGF3bmVkIHByb2Nlc3MuXG4gICAqL1xuICBwcm9jZXNzOiBDaGlsZFByb2Nlc3M7XG5cbiAgLyoqXG4gIFJldHVybnMgdGhlIGV4aXQgLyBzcGF3bi1mYWlsdXJlIGRldGFpbHMgb25jZSB0aGUgcHJvY2VzcyBpcyBubyBsb25nZXIgcnVubmluZywgb3RoZXJ3aXNlIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgcmVhZEV4aXRJbmZvOiAoKSA9PiBQcm9jZXNzRXhpdEluZm8gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFJldHVybnMgdGhlIGNhcHR1cmVkIHN0ZG91dCtzdGRlcnIgKGJvdW5kZWQgdG8gdGhlIG1vc3QgcmVjZW50IG91dHB1dCkuXG4gICAqL1xuICByZWFkT3V0cHV0OiAoKSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gIFN0b3BzIGFjY3VtdWxhdGluZyBvdXRwdXQuIENhbGwgb25jZSBzdGFydHVwIGhhcyBzdWNjZWVkZWQuXG4gICAqL1xuICBzdG9wQ2FwdHVyZTogKCkgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeS5zdGFydEFwcGl1bUFuZEVtdWxhdG9yfS5cbiAqL1xuaW50ZXJmYWNlIFJlY2xhaW1VbnN0b3BwZWRBcHBpdW1TZXJ2ZXJQYXJhbXMge1xuICAvKipcbiAgVGhlIG1hcmtlciB0aGF0IHByb3ZlcyB0aGUgbGVmdG92ZXIgaXMgdGhpcyBoYXJuZXNzJ3Mgb3duLlxuICAgKi9cbiAgcmVhZG9ubHkgbWFya2VyOiBBcHBpdW1TZXJ2ZXJNYXJrZXI7XG5cbiAgLyoqXG4gIFRoZSBwb3J0IGl0IGlzIGhvbGRpbmcuXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG5cbiAgLyoqXG4gIFdoZXRoZXIgdGhpcyBydW4gaXMgYWxsb3dlZCB0byBzdGFydCBhIHJlcGxhY2VtZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkQXV0b1N0YXJ0QXBwaXVtPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIHNlcnZlcidzIFVSTC5cbiAgICovXG4gIHJlYWRvbmx5IHVybDogVVJMO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBBcHBpdW1UcmFuc3BvcnRGYWN0b3J5LnJlY29yZEVtdWxhdG9yTGF1bmNoRGV2aWNlfS5cbiAqL1xuaW50ZXJmYWNlIFJlY29yZEVtdWxhdG9yTGF1bmNoRGV2aWNlUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBBVkQgd2hvc2UgbGF1bmNoIHdhcyByZWNvcmRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGF2ZE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgVGhlIGRldmljZSB0aGF0IGhhcyBqdXN0IGFwcGVhcmVkIGluIEFEQi5cbiAgICovXG4gIHJlYWRvbmx5IGRldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFdoZW4gdGhlIGVtdWxhdG9yIHdhcyBsYXVuY2hlZCBcdTIwMTQgd2hhdCBpZGVudGlmaWVzIHRoZSBsYXVuY2ggdGhpcyBkZXZpY2UgYmVsb25ncyB0by5cbiAgICovXG4gIHJlYWRvbmx5IGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBBcHBpdW1UcmFuc3BvcnRGYWN0b3J5LnJlY29yZEVtdWxhdG9yTGF1bmNofS5cbiAqL1xuaW50ZXJmYWNlIFJlY29yZEVtdWxhdG9yTGF1bmNoUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBBVkQgYmVpbmcgc3RhcnRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGF2ZE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgVGhlIGxhdW5jaGVyIGp1c3Qgc3Bhd25lZCBmb3IgaXQuXG4gICAqL1xuICByZWFkb25seSBlbXVsYXRvcjogUHJvY2Vzc0xhdW5jaDtcblxuICAvKipcbiAgV2hlbiBpdCB3YXMgbGF1bmNoZWQsIHdoaWNoIGV2ZXJ5IGxhdGVyIHdyaXRlIG9mIHRoaXMgbWFya2VyIGtlZXBzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGF1bmNoZWRBdEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBwcm9jZXNzZXMgdGhhdCBwcmVkYXRlIHRoZSBsYXVuY2gsIHNvIHRoZSBiYWNrZW5kIGl0IGZvcmtzIGNhbiBiZSBpZGVudGlmaWVkIHdpdGhvdXQgYSBzZWNvbmQgc25hcHNob3QuXG4gICAqL1xuICByZWFkb25seSBwcmVMYXVuY2hFbXVsYXRvclBpZHM6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5pbnRlcmZhY2UgU3RhcnRBcHBpdW1BbmRFbXVsYXRvclBhcmFtcyB7XG4gIC8qKlxuICBSZXNvbHZlZCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgdGhlIGF1dG8tc3RhcnRlZCBBcHBpdW0gc2VydmVyIHRvIGJlY29tZSByZWFkeS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0gc2VydmVyIFVSTC5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVVybDogVVJMO1xuXG4gIC8qKlxuICBBVkQgbmFtZSB0byBzdGFydC5cbiAgICovXG4gIHJlYWRvbmx5IGF2ZE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBwb3N0LWJvb3QgZGV2aWNlLWlkbGUgd2FpdCAoYDBgIHNraXBzIGl0KS5cbiAgICovXG4gIHJlYWRvbmx5IGRldmljZUlkbGVUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgV2hldGhlciB0aGUgYXV0by1zdGFydGVkIEFwcGl1bSBzZXJ2ZXIgY29uc29sZSB3aW5kb3cgaXMgc2hvd24gKG9taXR0ZWQgXHUyMTkyIGhpZGRlbikuXG4gICAqL1xuICByZWFkb25seSBpc0FwcGl1bUNvbnNvbGVWaXNpYmxlPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgV2hldGhlciB0aGUgYXV0by1zdGFydGVkIGVtdWxhdG9yIHdpbmRvdyBpcyBzaG93biAob21pdHRlZCBcdTIxOTIgaGlkZGVuKS5cbiAgICovXG4gIHJlYWRvbmx5IGlzRW11bGF0b3JWaXNpYmxlPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgUmVzb2x2ZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBuZXR3b3JrLXJlYWR5IHdhaXQgKGAwYCBza2lwcyBpdCkuXG4gICAqL1xuICByZWFkb25seSBuZXR3b3JrUmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgVGhlIEFwcGl1bSBzZXJ2ZXIgcG9ydC5cbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcblxuICAvKipcbiAgV2hldGhlciBtaXNzaW5nIEFwcGl1bSBkZXBlbmRlbmNpZXMgbWF5IGJlIGF1dG8taW5zdGFsbGVkIGJlZm9yZSB0aGUgc2VydmVyIGlzIGF1dG8tc3RhcnRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZEF1dG9JbnN0YWxsQXBwaXVtRGVwZW5kZW5jaWVzOiBib29sZWFuO1xuXG4gIC8qKlxuICBXaGV0aGVyIEFwcGl1bSBhdXRvLXN0YXJ0IGlzIGFsbG93ZWQuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRBdXRvU3RhcnRBcHBpdW0/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBXaGV0aGVyIHRoZSBhdXRvLXN0YXJ0ZWQgZW11bGF0b3IgbWF5IHJlc3VtZSBhbmQgcmVmcmVzaCB0aGUgQVZEJ3MgYm9vdCBzbmFwc2hvdCAob21pdHRlZCBcdTIxOTIgY29sZCBib290KS5cbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZFJldXNlRW11bGF0b3JTbmFwc2hvdD86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIHtAbGluayBBcHBpdW1UcmFuc3BvcnRGYWN0b3J5LnN0YXJ0QXBwaXVtQW5kRW11bGF0b3J9LlxuICovXG5pbnRlcmZhY2UgU3RhcnRBcHBpdW1BbmRFbXVsYXRvclJlc3VsdCB7XG4gIC8qKlxuICBUaGUgYWN0dWFsIGRldmljZSBJRCB0aGF0IGlzIGNvbm5lY3RlZCAobWF5IGRpZmZlciBmcm9tIHRoZSByZXF1ZXN0ZWQgb25lKS5cbiAgICovXG4gIHJlYWRvbmx5IGFjdHVhbERldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0gc2VydmVyIHByb2Nlc3MsIGlmIG9uZSB3YXMgYXV0by1zdGFydGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgYXBwaXVtUHJvY2Vzcz86IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGFkb3B0ZWQgc2VydmVyJ3MgbWFya2VyLCB3aGVuIGFuIGVhcmxpZXIgcnVuIG9mIHRoaXMgaGFybmVzcyBsZWZ0IG9uZS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVNlcnZlck1hcmtlcj86IEFwcGl1bVNlcnZlck1hcmtlciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yJ3Mgb3V0cHV0IGNhcHR1cmUsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBpdC5cbiAgICovXG4gIHJlYWRvbmx5IGVtdWxhdG9yQ2FwdHVyZT86IEVtdWxhdG9yQ2FwdHVyZSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIHByb2Nlc3MsIGlmIG9uZSB3YXMgYXV0by1zdGFydGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JQcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGFuIGFscmVhZHktbGlzdGVuaW5nIHNlcnZlciB3YXMgYWRvcHRlZCByYXRoZXIgdGhhbiBzdGFydGVkIGJ5IHRoaXNcbiAgICogcnVuLiBPbmx5IGFuIGFkb3B0ZWQgc2VydmVyIGNhbiBiZSB0aGUgc3RhbGUgb25lIGB3ZWRnZWQtYXBwaXVtLXNlcnZlci50c2BcbiAgICogZGVzY3JpYmVzLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNBZG9wdGVkQXBwaXVtU2VydmVyOiBib29sZWFuO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgcHJvY2Vzc2VzIHRoaXMgcnVuIGlzIHJlc3BvbnNpYmxlIGZvciBraWxsaW5nOyBlbXB0eSB3aGVuIHRoZSBkZXZpY2Ugd2FzIHJldXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeS5zd2VlcERldmljZUxlZnRvdmVyVmF1bHRzfS5cbiAqL1xuaW50ZXJmYWNlIFN0b3BBdXRvU3RhcnRlZEFwcGl1bVNlcnZlclBhcmFtcyB7XG4gIC8qKlxuICBUaGUgc2VydmVyIHByb2Nlc3MgdGhpcyBydW4gc3Bhd25lZC5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVByb2Nlc3M6IENoaWxkUHJvY2VzcztcblxuICAvKipcbiAgVGhlIHBvcnQgaXQgd2FzIHN0YXJ0ZWQgb24sIHdob3NlIG1hcmtlciBpcyBjbGVhcmVkIG9yIHN0YW1wZWQgYnkgdGhlIG91dGNvbWUuXG4gICAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBzZXJ2ZXIncyBVUkwsIHBvbGxlZCB0byBkZWNpZGUgd2hldGhlciBpdCBhY3R1YWxseSBzdG9wcGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgdXJsOiBVUkw7XG59XG5cbmludGVyZmFjZSBTdG9wQXV0b1N0YXJ0ZWRQcm9jZXNzZXNQYXJhbXMge1xuICAvKipcbiAgVGhlIEFwcGl1bSBzZXJ2ZXIgcHJvY2Vzcywgd2hlbiB0aGlzIHJ1biBzdGFydGVkIG9uZS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcGl1bVByb2Nlc3M/OiBDaGlsZFByb2Nlc3MgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBBVkQgbmFtZSwgZm9yIHRoZSBlbXVsYXRvcidzIHdhcm5pbmcuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBkZXZpY2UgdGhlIGVtdWxhdG9yIGlzIHNlcnZpbmcsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBvbmUuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIGxhdW5jaGVyIHByb2Nlc3MsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBvbmUuXG4gICAqL1xuICByZWFkb25seSBlbXVsYXRvclByb2Nlc3M/OiBDaGlsZFByb2Nlc3MgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBQSURzIHRoaXMgcnVuIG93bnMgXHUyMDE0IHN0YXJ0ZWQsIG9yIHRha2VuIG92ZXIgYXMgYSBsZWZ0b3Zlci4gTm9uLWVtcHR5IG1lYW5zIHRoZSBlbXVsYXRvciBpcyB0aGlzIHJ1bidzIHRvIHN0b3AuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0gcG9ydC5cbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcblxuICAvKipcbiAgVGhlIEFwcGl1bSBzZXJ2ZXIgVVJMLlxuICAgKi9cbiAgcmVhZG9ubHkgdXJsOiBVUkw7XG59XG5cbmludGVyZmFjZSBTdG9wRW11bGF0b3JBZnRlckZhaWxlZFN0YXJ0UGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBBVkQgdGhlIGVtdWxhdG9yIHdhcyBzdGFydGVkIGZvci5cbiAgICovXG4gIHJlYWRvbmx5IGF2ZE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgVGhlIG9ubGluZSBkZXZpY2VzIGxpc3RlZCBiZWZvcmUgdGhlIGxhdW5jaC5cbiAgICovXG4gIHJlYWRvbmx5IGRldmljZUlkc0JlZm9yZTogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gIFRoZSBsYXVuY2ggdGhhdCBmYWlsZWQuXG4gICAqL1xuICByZWFkb25seSBlbXVsYXRvcjogUHJvY2Vzc0xhdW5jaDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIHByb2Nlc3NlcyB0aGF0IHByZWRhdGUgdGhlIGxhdW5jaCwgYW5kIGFyZSB0aGVyZWZvcmUgbm90IHRoaXMgcnVuJ3MuXG4gICAqL1xuICByZWFkb25seSBlbXVsYXRvclBpZHNCZWZvcmU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5pbnRlcmZhY2UgU3dlZXBEZXZpY2VMZWZ0b3ZlclZhdWx0c1BhcmFtcyB7XG4gIC8qKlxuICBUaGUgZGV2aWNlIFVESUQgdG8gc3dlZXAuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgZGV2aWNlLXNpZGUgZGlyZWN0b3J5IE9ic2lkaWFuIE1vYmlsZSBzdG9yZXMgaXRzIHZhdWx0cyBpbi5cbiAgICovXG4gIHJlYWRvbmx5IHZhdWx0QmFzZVBhdGg6IHN0cmluZztcbn1cblxubGV0IGNhY2hlZFRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJlc29sdmVBbmRSZXBvcnRDb21wYXRpYmlsaXR5fS5cbiAqL1xuaW50ZXJmYWNlIFJlc29sdmVBbmRSZXBvcnRDb21wYXRpYmlsaXR5UGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBhcHAgKGFzYXIpIHZlcnNpb24gdGhhdCB3aWxsIGJlIHN3YXBwZWQgb250byB0aGUgc2hlbGwsIG9yIGB1bmRlZmluZWRgXG4gICAqIHdoZW4gbm8gYXNhci1zd2FwIHdpbGwgaGFwcGVuIChub3RoaW5nIGlzIGNoZWNrZWQgdGhlbikuXG4gICAqL1xuICByZWFkb25seSBhcHBWZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSByZXNvbHZlZCBpbnN0YWxsZXIvc2hlbGwgdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAuXG4gICAqL1xuICByZWFkb25seSBpbnN0YWxsZXJWZXJzaW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYW4gYCd1bnJ1bm5hYmxlJ2AgdmVyZGljdCB0aHJvd3Mge0BsaW5rIEluY29tcGF0aWJsZUluc3RhbGxlclZlcnNpb25FcnJvcn1cbiAgICogKGB0cnVlYCkgb3IgcHJvY2VlZHMgdG8gbGF1bmNoIHdpdGggdGhlIHZlcmRpY3Qgc3VyZmFjZWQgYXMgZGF0YSAoYGZhbHNlYCkuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyOiBib29sZWFuO1xuXG4gIC8qKlxuICBXaGV0aGVyIGEgYCduYWdnZWQnYCAob3IgcHJvY2VlZGluZy1gJ3VucnVubmFibGUnYCkgdmVyZGljdCBpcyBsb2dnZWQuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzOiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRoZSBzbGljZSBvZiBgd2ViZHJpdmVyaW9gJ3Mgc3VyZmFjZSB0aGUgQXBwaXVtIGZhY3RvcnkgY2FsbHMsIG5hbWVkIHNvIHRoZVxuICogbGF6eSBsb2FkIGhhcyBhIHJldHVybiB0eXBlIHdpdGhvdXQgYSBzdGF0aWMgaW1wb3J0IG9mIHRoZSBtb2R1bGUgaXRzZWxmLlxuICovXG5pbnRlcmZhY2UgV2ViZHJpdmVyaW9Nb2R1bGUge1xuICAvKipcbiAgUmVhdHRhY2hlcyB0byBhbiBleGlzdGluZyBXZWJEcml2ZXIgc2Vzc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IGF0dGFjaDogdHlwZW9mIGF0dGFjaDtcblxuICAvKipcbiAgQ3JlYXRlcyBhIG5ldyBXZWJEcml2ZXIgc2Vzc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlbW90ZTogdHlwZW9mIHJlbW90ZTtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYWxsIEFwcGl1bSB0cmFuc3BvcnQgY3JlYXRpb24gbG9naWMsIGluY2x1ZGluZyBBcHBpdW0gc2VydmVyXG4gKiBzdGFydHVwLCBlbXVsYXRvciBtYW5hZ2VtZW50LCBhbmQgV2ViRHJpdmVySU8gc2Vzc2lvbiBlc3RhYmxpc2htZW50LlxuICpcbiAqIFVzaW5nIGEgY2xhc3MgYXZvaWRzIHRocmVhZGluZyB0aGUgdHJhbnNwb3J0IGB0eXBlYCBsYWJlbCB0aHJvdWdoIGV2ZXJ5XG4gKiBoZWxwZXIgZnVuY3Rpb24gXHUyMDE0IGB0aGlzLmxvZygpYCBhdXRvbWF0aWNhbGx5IHByZWZpeGVzIGl0LlxuICovXG5jbGFzcyBBcHBpdW1UcmFuc3BvcnRGYWN0b3J5IHtcbiAgcHJpdmF0ZSByZWFkb25seSBlbXVsYXRvcnM6IEVtdWxhdG9yUmVjbGFpbWVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHR5cGU6IHN0cmluZztcblxuICBwdWJsaWMgY29uc3RydWN0b3IodHlwZTogc3RyaW5nKSB7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLmVtdWxhdG9ycyA9IG5ldyBFbXVsYXRvclJlY2xhaW1lcigobWVzc2FnZSkgPT4ge1xuICAgICAgdGhpcy5sb2cobWVzc2FnZSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBBcHBpdW0gdHJhbnNwb3J0IGJ5IGVzdGFibGlzaGluZyBhIFdlYkRyaXZlcklPIHNlc3Npb24uXG4gICAqXG4gICAqIElmIGBvcHRpb25zLnNlc3Npb25JZGAgaXMgcHJlc2VudCwgcmVhdHRhY2hlcyB0byB0aGUgZXhpc3Rpbmcgc2Vzc2lvblxuICAgKiBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IG9uZS4gVGhpcyBhdm9pZHMgZHVwbGljYXRlIEFwcGl1bS9BREIgY29ubmVjdGlvbnNcbiAgICogd2hlbiB0ZXN0IHdvcmtlcnMgcmV1c2UgdGhlIGdsb2JhbCBzZXR1cCdzIHNlc3Npb24uXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQW5kcm9pZCBBcHBpdW0gdHJhbnNwb3J0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIEEgY29uZmlndXJlZCBBcHBpdW0gdHJhbnNwb3J0LlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNyZWF0ZShvcHRpb25zOiBPYnNpZGlhbkFuZHJvaWRBcHBpdW1UcmFuc3BvcnRPcHRpb25zKTogUHJvbWlzZTxPYnNpZGlhblRyYW5zcG9ydD4ge1xuICAgIHJldHVybiBvcHRpb25zLnNlc3Npb25JZCAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMuZGV2aWNlSWQgIT09IHVuZGVmaW5lZCA/IHRoaXMuYXR0YWNoVG9FeGlzdGluZ1Nlc3Npb24ob3B0aW9ucy5zZXNzaW9uSWQsIG9wdGlvbnMuZGV2aWNlSWQsIG9wdGlvbnMpIDogdGhpcy5jcmVhdGVOZXdTZXNzaW9uKG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFybXMgdGhlIGVtdWxhdG9yIHJlYXBlciAoYGVtdWxhdG9yLXJlYXBlci50c2ApIGZvciBhbiBlbXVsYXRvciB0aGlzIHJ1biBoYXNcbiAgICoganVzdCByZWNvcmRlZCBhcyBpdHMgb3duLlxuICAgKlxuICAgKiBAcGFyYW0gYXZkTmFtZSAtIFRoZSBBVkQgd2hvc2UgbWFya2VyIHdhcyBqdXN0IHdyaXR0ZW4uXG4gICAqIEBwYXJhbSBzdGFydGVkQXRJbk1pbGxpc2Vjb25kcyAtIFRoZSBlbXVsYXRvcidzIGxhdW5jaCB0aW1lLCBhcyB0aGUgbWFya2VyIHJlY29yZHMgaXQuXG4gICAqL1xuICBwcml2YXRlIGFybUVtdWxhdG9yUmVhcGVyKGF2ZE5hbWU6IHN0cmluZywgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHM6IG51bWJlcik6IHZvaWQge1xuICAgIHNwYXduRW11bGF0b3JSZWFwZXIoe1xuICAgICAgYXZkTmFtZSxcbiAgICAgIGxvZzogKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgdGhpcy5sb2cobWVzc2FnZSk7XG4gICAgICB9LFxuICAgICAgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHNcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc2tzIG9uZSBkZXZpY2UgZm9yIGl0cyBBVkQgbmFtZSBvdmVyIG9uZSBjaGFubmVsLlxuICAgKlxuICAgKiBSZXBvcnRzICp3aGV0aGVyIHRoZSBjb21tYW5kIGNhbWUgYmFjayogYWxvbmdzaWRlIHdoYXQgaXQgcHJpbnRlZCwgYmVjYXVzZVxuICAgKiB0aGUgc2VxdWVuY2luZyBpbiBgYXZkLW5hbWUtY2hhbm5lbC50c2AgdHVybnMgb24gdGhhdCBkaWZmZXJlbmNlOiBhIGNoYW5uZWxcbiAgICogdGhhdCBhbnN3ZXJlZCBhbiBlbXB0eSBwcm9wZXJ0eSBpcyBhbGl2ZSBhbmQgd29ydGggYXNraW5nIGFnYWluIHdpdGggdGhlXG4gICAqIG90aGVyIGtleSwgd2hpbGUgb25lIHRoYXQgbmV2ZXIgY2FtZSBiYWNrIGlzIG5vdC5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSB0byBhc2suXG4gICAqIEBwYXJhbSBjaGFubmVsIC0gVGhlIGNoYW5uZWwgdG8gYXNrIGl0IG92ZXIuXG4gICAqIEByZXR1cm5zIFdoYXQgdGhhdCBjaGFubmVsIGFuc3dlcmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc2tEZXZpY2VGb3JBdmROYW1lKGRldmljZUlkOiBzdHJpbmcsIGNoYW5uZWw6IEF2ZE5hbWVDaGFubmVsKTogUHJvbWlzZTxBdmROYW1lQ2hhbm5lbEFuc3dlcj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoXG4gICAgICAgICdhZGInLFxuICAgICAgICBidWlsZEF2ZE5hbWVDaGFubmVsQXJndW1lbnRzKHsgY2hhbm5lbCwgZGV2aWNlSWQgfSksXG4gICAgICAgIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LFxuICAgICAgICAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgICAgIHJlc29sdmUoZXJyb3IgPyB7IGRpZFJlc3BvbmQ6IGZhbHNlLCByZXBvcnRlZEF2ZE5hbWU6ICcnIH0gOiB7IGRpZFJlc3BvbmQ6IHRydWUsIHJlcG9ydGVkQXZkTmFtZTogcGFyc2VBdmROYW1lQW5zd2VyKHN0ZG91dCkgfSk7XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGF0dGFjaFRvRXhpc3RpbmdTZXNzaW9uKFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIGRldmljZUlkOiBzdHJpbmcsXG4gICAgb3B0aW9uczogT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9uc1xuICApOiBQcm9taXNlPE9ic2lkaWFuVHJhbnNwb3J0PiB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTChvcHRpb25zLmFwcGl1bVVybCk7XG4gICAgY29uc3QgcG9ydCA9IE51bWJlcih1cmwucG9ydCk7XG4gICAgY29uc3QgYXBwSWQgPSBvcHRpb25zLmFwcElkID8/IEFQUF9QQUNLQUdFO1xuXG4gICAgdGhpcy5sb2coYFJlYXR0YWNoaW5nIHRvIGV4aXN0aW5nIEFwcGl1bSBzZXNzaW9uICR7c2Vzc2lvbklkfSAoZGV2aWNlPSR7ZGV2aWNlSWR9KWApO1xuXG4gICAgY29uc3QgeyBhdHRhY2ggfSA9IGF3YWl0IGltcG9ydFdlYmRyaXZlcmlvKCk7XG4gICAgY29uc3QgYnJvd3NlciA9IGF3YWl0IGF0dGFjaCh7XG4gICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgcGxhdGZvcm1OYW1lOiAnQW5kcm9pZCdcbiAgICAgIH0sXG4gICAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgICAgbG9nTGV2ZWw6ICd3YXJuJyxcbiAgICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICAgIHBvcnQsXG4gICAgICBzZXNzaW9uSWQsXG4gICAgICB0cmFuc2Zvcm1SZXF1ZXN0OiBzdHJpcEZvcmJpZGRlbkZldGNoSGVhZGVyc1xuICAgIH0pO1xuXG4gICAgdGhpcy5sb2coJ1JlYXR0YWNoZWQgdG8gQXBwaXVtIHNlc3Npb24uJyk7XG5cbiAgICByZXR1cm4gbmV3IEFwcGl1bVRyYW5zcG9ydCh7XG4gICAgICBhcHBJZCxcbiAgICAgIGJyb3dzZXIsXG4gICAgICBkZXZpY2VJZCxcbiAgICAgIGlzU2Vzc2lvbk93bmVyOiBmYWxzZSxcbiAgICAgIHBsYXRmb3JtOiAnYW5kcm9pZCcsXG4gICAgICAvLyBUaGUgc2Vzc2lvbiB0aGlzIHJlYXR0YWNoZXMgdG8gd2FzIGNyZWF0ZWQgd2l0aCB0aGUgc2FtZSByZXNvbHV0aW9uLCBzbyB0aGUgbnVtYmVyIHJlcG9ydGVkIG9uIGFcbiAgICAgIC8vIHNjcmlwdCB0aW1lb3V0IGlzIHRoZSBvbmUgdGhhdCBzZXNzaW9uIGlzIGFjdHVhbGx5IGVuZm9yY2luZy5cbiAgICAgIHNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcmVzb2x2ZVNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgIHNob3VsZFN3ZWVwTGVmdG92ZXJzOiB3aWxsU3dlZXBMZWZ0b3ZlcnMob3B0aW9ucyksXG4gICAgICAuLi4ob3B0aW9ucy5hcHBTdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG9wdGlvbnMuYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSksXG4gICAgICAuLi4ob3B0aW9ucy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG9wdGlvbnMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSksXG4gICAgICAuLi4ob3B0aW9ucy52YXVsdEJhc2VQYXRoICE9PSB1bmRlZmluZWQgJiYgeyB2YXVsdEJhc2VQYXRoOiBvcHRpb25zLnZhdWx0QmFzZVBhdGggfSksXG4gICAgICAuLi4ob3B0aW9ucy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzICE9PSB1bmRlZmluZWQgJiYgeyB3ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSlcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRXZWRnZWRNZXNzYWdlKHBhcmFtczogRXN0YWJsaXNoU2Vzc2lvblBhcmFtcywgcmVhc29uOiBXZWRnZWRBcHBpdW1TZXJ2ZXJSZXBvcnRSZWFzb24pOiBzdHJpbmcge1xuICAgIGNvbnN0IG1hcmtlciA9IHBhcmFtcy5hcHBpdW1TZXJ2ZXJNYXJrZXI7XG4gICAgcmV0dXJuIGJ1aWxkV2VkZ2VkQXBwaXVtU2VydmVyTWVzc2FnZSh7XG4gICAgICBhcHBpdW1PcmlnaW46IHBhcmFtcy51cmwub3JpZ2luLFxuICAgICAgZGV2aWNlSWQ6IHBhcmFtcy5kZXZpY2VJZCxcbiAgICAgIHJlYXNvbixcbiAgICAgIC4uLihtYXJrZXIgIT09IHVuZGVmaW5lZCAmJiB7XG4gICAgICAgIHNlcnZlckFnZUluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpIC0gbWFya2VyLnN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzLFxuICAgICAgICBzZXJ2ZXJQaWQ6IG1hcmtlci5waWRcbiAgICAgIH0pXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUHJlZmxpZ2h0IHByb2JlIGZvciBhbiBhbHJlYWR5LXJ1bm5pbmcgc2VydmVyLlxuICAgKlxuICAgKiBMaXZlbmVzcyBpcyBub3QgcmVhZGluZXNzOiByZXNvbHZpbmcgb24gKmFueSogcmVzcG9uc2UgYWRvcHRzIGEgc2VydmVyIHRoYXRcbiAgICogaXMgcmVmdXNpbmcgc2Vzc2lvbnMgKGEgbm9uLTJ4eCBgL3N0YXR1c2AsIG9yIG9uZSB0aGF0IHJlcG9ydHMgaXRzZWxmXG4gICAqIHNodXR0aW5nIGRvd24pIGV4YWN0bHkgbGlrZSBhIGhlYWx0aHkgb25lLiBSZWplY3RpbmcgaW5zdGVhZCBoYW5kcyB0aG9zZVxuICAgKiBjYXNlcyB0byB0aGUgYXV0by1zdGFydCBwYXRoLiBJdCBjYW5ub3QgY2F0Y2ggdGhlIHdlZGdlZCBzZXJ2ZXIgb2ZcbiAgICogYHdlZGdlZC1hcHBpdW0tc2VydmVyLnRzYCBcdTIwMTQgdGhhdCBvbmUgYW5zd2VycyBgcmVhZHk6IHRydWVgIFx1MjAxNCB3aGljaCBpcyB3aHlcbiAgICogdGhlIHdlZGdlIGlzIHJlY29nbml6ZWQgZnJvbSB0aGUgZmFpbGVkIHNlc3Npb24gaW5zdGVhZC5cbiAgICpcbiAgICogQHBhcmFtIHVybCAtIFRoZSBBcHBpdW0gc2VydmVyIFVSTC5cbiAgICovXG4gIHByaXZhdGUgY2hlY2tBcHBpdW1SZWFjaGFibGUodXJsOiBVUkwpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdHVzVXJsID0gbmV3IFVSTCgnL3N0YXR1cycsIHVybCk7XG4gICAgICAvKlxuICAgICAgICogYGFnZW50OiBmYWxzZWAgXHUyMDE0IG5ldmVyIGEgcG9vbGVkIHNvY2tldC4gVGhlIGdsb2JhbCBhZ2VudCBrZWVwcyBzb2NrZXRzXG4gICAgICAgKiBhbGl2ZSBwZXIgaG9zdDpwb3J0LCBzbyBhIHByb2JlIGFmdGVyIGEgc2VydmVyIG9uIHRoYXQgcG9ydCB3YXMgcmVwbGFjZWRcbiAgICAgICAqIGNhbiByZXVzZSB0aGUgZGVhZCBzb2NrZXQgYW5kIGZhaWwgd2l0aCBgRUNPTk5SRVNFVGAgcmVnYXJkbGVzcyBvZiB3aGF0XG4gICAgICAgKiBpcyBsaXN0ZW5pbmcgbm93LiBUaGF0IHdvdWxkIG1ha2UgYHdhaXRGb3JBcHBpdW1TdG9wcGVkYCBjYWxsIGEgbGl2ZVxuICAgICAgICogc2VydmVyIGRlYWQsIGFuZCBpdCBpcyBleGFjdGx5IHRoZSBzZXF1ZW5jZSB0aGUgd2VkZ2VkLXNlcnZlciByZXN0YXJ0XG4gICAgICAgKiBwZXJmb3Jtcy4gQSBmcmVzaCBzb2NrZXQgcGVyIHByb2JlIGNvc3RzIG5vdGhpbmcgYXQgdGhpcyBmcmVxdWVuY3kuXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBodHRwLmdldChzdGF0dXNVcmwsIHsgYWdlbnQ6IGZhbHNlLCB0aW1lb3V0OiBBUFBJVU1fUFJFRkxJR0hUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sIChyZXNwb25zZSkgPT4ge1xuICAgICAgICBjb25zdCBzdGF0dXNDb2RlID0gcmVzcG9uc2Uuc3RhdHVzQ29kZSA/PyAwO1xuICAgICAgICBpZiAoc3RhdHVzQ29kZSA8IEhUVFBfT0sgfHwgc3RhdHVzQ29kZSA+PSBIVFRQX01VTFRJUExFX0NIT0lDRVMpIHtcbiAgICAgICAgICByZXNwb25zZS5yZXN1bWUoKTtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn0gYW5zd2VyZWQgL3N0YXR1cyB3aXRoIEhUVFAgJHtTdHJpbmcoc3RhdHVzQ29kZSl9OyBpdCBpcyBub3QgYWNjZXB0aW5nIHNlc3Npb25zLmApKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXNwb25zZS5zZXRFbmNvZGluZygndXRmLTgnKTtcbiAgICAgICAgbGV0IGJvZHkgPSAnJztcbiAgICAgICAgcmVzcG9uc2Uub24oJ2RhdGEnLCAoY2h1bms6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGJvZHkgKz0gY2h1bms7XG4gICAgICAgIH0pO1xuICAgICAgICByZXNwb25zZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGlmIChjaGVja0lzQXBwaXVtU3RhdHVzUmVhZHkoYm9keSkpIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn0gcmVwb3J0cyBpdCBpcyBub3QgcmVhZHkgdG8gYWNjZXB0IG5ldyBjb25uZWN0aW9ucy5gKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICByZXF1ZXN0Lm9uKCd0aW1lb3V0JywgKCkgPT4ge1xuICAgICAgICByZXF1ZXN0LmRlc3Ryb3koKTtcbiAgICAgICAgcmVqZWN0KFxuICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn0gZGlkIG5vdCByZXNwb25kIHdpdGhpbiAke1N0cmluZyhBUFBJVU1fUFJFRkxJR0hUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcy4gSXMgdGhlIEFwcGl1bSBzZXJ2ZXIgcnVubmluZz9gXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXF1ZXN0Lm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgICByZWplY3QoXG4gICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgYENhbm5vdCByZWFjaCBBcHBpdW0gc2VydmVyIGF0ICR7dXJsLm9yaWdpbn06ICR7ZXJyb3IubWVzc2FnZX0uIElzIHRoZSBBcHBpdW0gc2VydmVyIHJ1bm5pbmc/YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIG91dCB0aGUgQXBwaXVtIHBvcnQgYW5kIHJlcG9ydHMgd2hldGhlciBpdCB3ZW50IHF1aWV0LCByYXRoZXIgdGhhblxuICAgKiB0aHJvd2luZyBhcyB7QGxpbmsgd2FpdEZvckFwcGl1bVN0b3BwZWR9IGRvZXMuXG4gICAqXG4gICAqIEBwYXJhbSB1cmwgLSBUaGUgQXBwaXVtIHNlcnZlciBVUkwuXG4gICAqIEBwYXJhbSB0aW1lb3V0SW5NaWxsaXNlY29uZHMgLSBIb3cgbG9uZyB0byB3YWl0LlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiBub3RoaW5nIGFuc3dlcnMgb24gdGhlIHBvcnQgYW55IG1vcmUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNoZWNrSXNBcHBpdW1TdG9wcGVkKHVybDogVVJMLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JBcHBpdW1TdG9wcGVkKHVybCwgdGltZW91dEluTWlsbGlzZWNvbmRzKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgd2hldGhlciBhZGIgc3RpbGwgbGlzdHMgdGhlIGRldmljZSAqKmluIGFueSBzdGF0ZSoqLCB3aXRob3V0IGxldHRpbmdcbiAgICogYW4gYWRiIHRoYXQgaXRzZWxmIGZhaWxzIGNvdW50IGFzIGV2aWRlbmNlLlxuICAgKlxuICAgKiBBbnkgc3RhdGUsIG5vdCBqdXN0IGBkZXZpY2VgOiBhIGR5aW5nIGVtdWxhdG9yIGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlIGl0IGlzXG4gICAqIHN0aWxsIHRoZSB0aGluZyB0aGF0IGlzIHdyb25nICh0aGUgZGlzdGluY3Rpb24gYGFkYi1kZXZpY2UtbGlzdC50c2AgZHJhd3NcbiAgICogZm9yIHRlYXJkb3duLCBhbmQgdGhlIHJlYXNvbmluZyBjYXJyaWVzIG92ZXIpLiBSZWFkaW5nIGBvZmZsaW5lYCBhcyBnb25lXG4gICAqIGhlcmUgd291bGQgcmVwb3J0IGBkZXZpY2UtZ29uZWAgZm9yIHdoYXQgaXMgcmVhbGx5IGEgd2VkZ2UsIHNlbmRpbmcgdGhlXG4gICAqIHJlYWRlciB0byBsb29rIGZvciBhIHZhbmlzaGVkIGVtdWxhdG9yIHRoYXQgaXMgaW4gZmFjdCBzdGlsbCBzaXR0aW5nIHRoZXJlLlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgZGV2aWNlIHRvIGxvb2sgZm9yLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiBpdCBpcyBsaXN0ZWQ7IGBmYWxzZWAgd2hlbiBpdCBpcyBub3QsIG9yIGFkYiBjb3VsZCBub3QgYmUgcnVuLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0lzRGV2aWNlTGlzdGVkUXVpZXRseShkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBjaGVja0lzRGV2aWNlTGlzdGVkKHsgZGV2aWNlSWQsIGRldmljZXNPdXRwdXQ6IGF3YWl0IHRoaXMuZW11bGF0b3JzLmdldERldmljZXNPdXRwdXQoKSB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgdGhpcy5sb2coYENvdWxkIG5vdCByZS1jaGVjayB0aGUgZGV2aWNlIGxpc3Rpbmc6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY29ubmVjdFNlc3Npb24ocGFyYW1zOiBFc3RhYmxpc2hTZXNzaW9uUGFyYW1zKTogUHJvbWlzZTxBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIHJlbW90ZT4+PiB7XG4gICAgY29uc3QgeyByZW1vdGUgfSA9IGF3YWl0IGltcG9ydFdlYmRyaXZlcmlvKCk7XG4gICAgcmV0dXJuIHJlbW90ZSh7XG4gICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgJ2FwcGl1bTphcHBBY3Rpdml0eSc6IEFQUF9BQ1RJVklUWSxcbiAgICAgICAgJ2FwcGl1bTphcHBQYWNrYWdlJzogcGFyYW1zLmFwcElkLFxuICAgICAgICAnYXBwaXVtOmF1dG9HcmFudFBlcm1pc3Npb25zJzogdHJ1ZSxcbiAgICAgICAgJ2FwcGl1bTphdXRvbWF0aW9uTmFtZSc6ICdVaUF1dG9tYXRvcjInLFxuICAgICAgICAnYXBwaXVtOm5ld0NvbW1hbmRUaW1lb3V0JzogTkVXX0NPTU1BTkRfVElNRU9VVF9JTl9TRUNPTkRTLFxuICAgICAgICAnYXBwaXVtOm5vUmVzZXQnOiB0cnVlLFxuICAgICAgICAnYXBwaXVtOnVkaWQnOiBwYXJhbXMuZGV2aWNlSWQsXG4gICAgICAgICdhcHBpdW06dWlhdXRvbWF0b3IyU2VydmVySW5zdGFsbFRpbWVvdXQnOiBTRVJWRVJfSU5TVEFMTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgJ2FwcGl1bTp1aWF1dG9tYXRvcjJTZXJ2ZXJMYXVuY2hUaW1lb3V0JzogU0VSVkVSX0xBVU5DSF9USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgJ3BsYXRmb3JtTmFtZSc6ICdBbmRyb2lkJyxcbiAgICAgICAgLypcbiAgICAgICAgICogYHNjcmlwdGAgaXMgZGVjbGFyZWQgc28gdGhlIHBlci1jbG9zdXJlIGNhcCBpcyBhIG51bWJlciB0aGlzIGhhcm5lc3Mgb3ducyBhbmQgc3RhdGVzLCBidXQgdGhlXG4gICAgICAgICAqIERlY2xhcmF0aW9uIGlzIE5PVCB3aGF0IGVuZm9yY2VzIGl0OiBVaUF1dG9tYXRvcjIgd2FzIG1lYXN1cmVkIGFjY2VwdGluZyB0aGlzLCByZXBvcnRpbmcgaXRcbiAgICAgICAgICogQmFjayBhcyAzMDAwMCBmcm9tIHRoZSBXZWJWaWV3IGNvbnRleHQsIGFuZCBuZXZlciBhY3Rpbmcgb24gaXQgXHUyMDE0IG92ZXItY2FwIGNsb3N1cmVzIHJhbiBwYXN0IGFcbiAgICAgICAgICogNjBzIGNlaWxpbmcgd2l0aG91dCBvbmUgYHNjcmlwdCB0aW1lb3V0YC4gYEFwcGl1bVRyYW5zcG9ydC5ldmFsdWF0ZWAgZW5mb3JjZXMgdGhlIHNhbWUgbnVtYmVyXG4gICAgICAgICAqIE5vZGUtc2lkZSwgYW5kIHRoaXMgc3RheXMgYmVjYXVzZSBpdCBpcyBmcmVlLCBpdCBpcyB0aGUgaG9uZXN0IGRlY2xhcmF0aW9uIG9mIHRoZSBpbnRlbmRlZFxuICAgICAgICAgKiBCdWRnZXQsIGFuZCBpdCB3b3VsZCBzdGFydCB3b3JraW5nIG9uIGl0cyBvd24gaWYgYSBmdXR1cmUgZHJpdmVyIGhvbm91cmVkIGl0LiBUaGUgb3RoZXIgdHdvIGFyZVxuICAgICAgICAgKiBSZXN0YXRlZCBhdCB0aGVpciBXM0MgZGVmYXVsdHMgb25seSBiZWNhdXNlIHRoZSBjYXBhYmlsaXR5IGlzIGFsbC1vci1ub3RoaW5nIFx1MjAxNCBXZWJEcml2ZXJJTydzXG4gICAgICAgICAqIGBUaW1lb3V0c2AgdHlwZSBoYXMgbm8gcGFydGlhbCBmb3JtIFx1MjAxNCBzbyB0aGV5IGNoYW5nZSBub3RoaW5nLlxuICAgICAgICAgKi9cbiAgICAgICAgJ3RpbWVvdXRzJzoge1xuICAgICAgICAgIGltcGxpY2l0OiBJTVBMSUNJVF9XQUlUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTLFxuICAgICAgICAgIHBhZ2VMb2FkOiBQQUdFX0xPQURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICAgICAgc2NyaXB0OiBwYXJhbXMuc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjb25uZWN0aW9uUmV0cnlDb3VudDogQVBQSVVNX0NPTk5FQ1RJT05fUkVUUllfQ09VTlQsXG4gICAgICBjb25uZWN0aW9uUmV0cnlUaW1lb3V0OiBwYXJhbXMuc2Vzc2lvbkNvbm5lY3Rpb25SZXRyeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgICAgIGhvc3RuYW1lOiBwYXJhbXMudXJsLmhvc3RuYW1lLFxuICAgICAgbG9nTGV2ZWw6ICd3YXJuJyxcbiAgICAgIHBhdGg6IHBhcmFtcy51cmwucGF0aG5hbWUsXG4gICAgICBwb3J0OiBwYXJhbXMucG9ydCxcbiAgICAgIHRyYW5zZm9ybVJlcXVlc3Q6IHN0cmlwRm9yYmlkZGVuRmV0Y2hIZWFkZXJzXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNyZWF0ZU5ld1Nlc3Npb24ob3B0aW9uczogT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgICB0aGlzLmxvZyhgQ3JlYXRpbmcgQXBwaXVtVHJhbnNwb3J0ICh1cmw9JHtvcHRpb25zLmFwcGl1bVVybH0sIGF2ZD0ke29wdGlvbnMuYXZkTmFtZX0pYCk7XG5cbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKG9wdGlvbnMuYXBwaXVtVXJsKTtcblxuICAgIGNvbnN0IHBvcnQgPSBOdW1iZXIodXJsLnBvcnQpO1xuICAgIGlmIChOdW1iZXIuaXNOYU4ocG9ydCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgcG9ydCBpbiBhcHBpdW1Vcmw6ICR7dXJsLnBvcnR9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgYXBwSWQgPSBvcHRpb25zLmFwcElkID8/IEFQUF9QQUNLQUdFO1xuXG4gICAgbGV0IGFjdHVhbERldmljZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgbGV0IGFwcGl1bVByb2Nlc3M6IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZW11bGF0b3JQcm9jZXNzOiBDaGlsZFByb2Nlc3MgfCB1bmRlZmluZWQ7XG4gICAgbGV0IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXSA9IFtdO1xuXG4gICAgbGV0IHJlc3VsdDogU3RhcnRBcHBpdW1BbmRFbXVsYXRvclJlc3VsdCB8IHVuZGVmaW5lZDtcblxuICAgIHRyeSB7XG4gICAgICAvKlxuICAgICAgICogUHJvdmlzaW9uLCB0aGVuIGNoZWNrIHRoZSBkZXZpY2UgaXMgc3RpbGwgYW5zd2VyaW5nIFx1MjAxNCBhbmQgd2hlbiBpdCBpcyBub3RcbiAgICAgICAqIGFuZCB0aGUgZW11bGF0b3IgaXMgb3VycywgYm9vdCBhIGZyZXNoIG9uZSBpbnN0ZWFkIG9mIGNhcnJ5aW5nIG9uLlxuICAgICAgICpcbiAgICAgICAqIEEgd2VkZ2UgaXMgTk9UIGRldGVybWluaXN0aWMsIHdoaWNoIGlzIHdoYXQganVzdGlmaWVzIHRoZSByZXRyeS4gSW4gdGhlXG4gICAgICAgKiBydW4gdGhhdCBwcm92ZWQgaXQgKDIwMjYtMDktMDUpIHRoZSBmaXJzdCBlbXVsYXRvciB3ZW50IHF1aWV0IDEyOXMgaW4gYW5kXG4gICAgICAgKiB0aGUgc2Vjb25kLCBib290ZWQgMTFzIGxhdGVyIGZyb20gdGhlIHNhbWUgQVZEIHdpdGggdGhlIHNhbWUgYXJndW1lbnRzLFxuICAgICAgICogZXN0YWJsaXNoZWQgYSBzZXNzaW9uIGFuZCBkcm92ZSB0aGUgV2ViVmlldyB0byBjb21wbGV0aW9uLiBBbiBlYXJsaWVyXG4gICAgICAgKiBkcmFmdCBvZiB0aGlzIHdvcmsgYXJndWVkIHRoZSBvcHBvc2l0ZSBmcm9tIHRoZSBoYW5kLWJvb3QgZGF0YSBcdTIwMTQgdGhhdCBhXG4gICAgICAgKiByZS1ib290IGJ1eXMgdGhlIHNhbWUgZmFpbHVyZSA5MHMgbGF0ZXIgXHUyMDE0IGFuZCB0aGF0IHdhcyBzaW1wbHkgd3Jvbmc6XG4gICAgICAgKiBldmVyeSBoYW5kLWJvb3Qgd2FzIGEgZmlyc3QgYm9vdCwgc28gdGhlIGRhdGEgc2FpZCBub3RoaW5nIGFib3V0IHNlY29uZFxuICAgICAgICogb25lcy5cbiAgICAgICAqL1xuICAgICAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gRU1VTEFUT1JfQk9PVF9BVFRFTVBUX0NPVU5UOyBhdHRlbXB0KyspIHtcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgdGhpcy5zdGFydEFwcGl1bUFuZEVtdWxhdG9yKHtcbiAgICAgICAgICBhcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcmVzb2x2ZUFwcGl1bVN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzKG9wdGlvbnMpLFxuICAgICAgICAgIGFwcGl1bVVybDogdXJsLFxuICAgICAgICAgIGF2ZE5hbWU6IG9wdGlvbnMuYXZkTmFtZSxcbiAgICAgICAgICBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlRGV2aWNlSWRsZVRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgICBpc0FwcGl1bUNvbnNvbGVWaXNpYmxlOiBvcHRpb25zLmlzQXBwaXVtQ29uc29sZVZpc2libGUsXG4gICAgICAgICAgaXNFbXVsYXRvclZpc2libGU6IG9wdGlvbnMuaXNFbXVsYXRvclZpc2libGUsXG4gICAgICAgICAgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlTmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzKG9wdGlvbnMpLFxuICAgICAgICAgIHBvcnQsXG4gICAgICAgICAgc2hvdWxkQXV0b0luc3RhbGxBcHBpdW1EZXBlbmRlbmNpZXM6IHdpbGxBdXRvSW5zdGFsbEFwcGl1bURlcGVuZGVuY2llcyhvcHRpb25zKSxcbiAgICAgICAgICBzaG91bGRBdXRvU3RhcnRBcHBpdW06IG9wdGlvbnMuc2hvdWxkQXV0b1N0YXJ0QXBwaXVtLFxuICAgICAgICAgIHNob3VsZFJldXNlRW11bGF0b3JTbmFwc2hvdDogb3B0aW9ucy5zaG91bGRSZXVzZUVtdWxhdG9yU25hcHNob3RcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLypcbiAgICAgICAgICogT25seSBldmVyIFJFUExBQ0UgdGhpcyBoYW5kbGUsIG5ldmVyIGNsZWFyIGl0LiBUaGUgcmV0cnkgbGVhdmVzIHRoaXNcbiAgICAgICAgICogcnVuJ3MgQXBwaXVtIHNlcnZlciBydW5uaW5nIGFuZCBzd2FwcyBvbmx5IHRoZSBlbXVsYXRvciwgc28gdGhlIHNlY29uZFxuICAgICAgICAgKiBwYXNzIGZpbmRzIHRoYXQgc2VydmVyIHJlYWNoYWJsZSwgQURPUFRTIGl0LCBhbmQgcmV0dXJucyBubyBwcm9jZXNzXG4gICAgICAgICAqIGhhbmRsZS4gV3JpdGluZyB0aGF0IGB1bmRlZmluZWRgIG92ZXIgdGhlIGhhbmRsZSBmcm9tIHRoZSBmaXJzdCBwYXNzXG4gICAgICAgICAqIHdvdWxkIG9ycGhhbiB0aGUgdmVyeSBzZXJ2ZXIgdGhpcyBydW4gc3RhcnRlZCBcdTIwMTQgdGhlIGxlYWsgTDQ2IGV4aXN0cyB0b1xuICAgICAgICAgKiBwcmV2ZW50LCByZWludHJvZHVjZWQgYnkgdGhlIHJldHJ5LlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHJlc3VsdC5hcHBpdW1Qcm9jZXNzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBhcHBpdW1Qcm9jZXNzID0gcmVzdWx0LmFwcGl1bVByb2Nlc3M7XG4gICAgICAgIH1cbiAgICAgICAgZW11bGF0b3JQcm9jZXNzID0gcmVzdWx0LmVtdWxhdG9yUHJvY2VzcztcbiAgICAgICAgb3duZWRFbXVsYXRvclBpZHMgPSByZXN1bHQub3duZWRFbXVsYXRvclBpZHM7XG4gICAgICAgIGFjdHVhbERldmljZUlkID0gcmVzdWx0LmFjdHVhbERldmljZUlkO1xuXG4gICAgICAgIC8qXG4gICAgICAgICAqIEJlZm9yZSBgcmVtb3RlKClgIGxhdW5jaGVzIE9ic2lkaWFuIFx1MjAxNCB0aGUgbGFzdCBwb2ludCBhdCB3aGljaCBub3RoaW5nXG4gICAgICAgICAqIGhhcyB0byBlbnVtZXJhdGUgdGhlIGRldmljZSdzIHZhdWx0cyB5ZXQuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAod2lsbFN3ZWVwTGVmdG92ZXJzKG9wdGlvbnMpKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5zd2VlcERldmljZUxlZnRvdmVyVmF1bHRzKHtcbiAgICAgICAgICAgIGRldmljZUlkOiBhY3R1YWxEZXZpY2VJZCxcbiAgICAgICAgICAgIHZhdWx0QmFzZVBhdGg6IG9wdGlvbnMudmF1bHRCYXNlUGF0aCA/PyBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRIXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKlxuICAgICAgICAgKiBUaGUgbGFzdCBwb2ludCBhdCB3aGljaCBhIGRldmljZSB0aGF0IGhhcyBnb25lIHF1aWV0IGNhbiBzdGlsbCBiZVxuICAgICAgICAgKiByZXBvcnRlZCBhcyBpdHNlbGYuIFBhc3QgaGVyZSB0aGUgZmFpbHVyZSBiZWxvbmdzIHRvIEFwcGl1bSwgd2hpY2ggY2FuXG4gICAgICAgICAqIG9ubHkgc2F5IHRoZSBkZXZpY2UgaXMgXCJub3QgaW4gdGhlIGxpc3Qgb2YgY29ubmVjdGVkIGRldmljZXNcIiBcdTIwMTQgYW5cbiAgICAgICAgICogZXJyb3IgdGhhdCBuYW1lcyB0aGUgb25lIHRoaW5nIHRoYXQgaXMgbm90IHdyb25nLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgZGlhZ25vc2lzID0gYXdhaXQgdGhpcy5kaWFnbm9zZURldmljZShhY3R1YWxEZXZpY2VJZCwgcmVzdWx0LmVtdWxhdG9yQ2FwdHVyZSk7XG4gICAgICAgIGlmIChkaWFnbm9zaXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgLypcbiAgICAgICAgICogT25seSBhbiBlbXVsYXRvciB0aGlzIHJ1biBvd25zIG1heSBiZSByZXBsYWNlZCBcdTIwMTQgb25lIGl0IHN0YXJ0ZWQsIG9yIGFcbiAgICAgICAgICogbGVmdG92ZXIgb2YgdGhpcyBoYXJuZXNzIGl0IHRvb2sgb3Zlci4gQSBkZXZpY2UgdGhhdCB3YXMgbWVyZWx5XG4gICAgICAgICAqIGFkb3B0ZWQgKGBvd25lZEVtdWxhdG9yUGlkc2AgZW1wdHkpIGlzIHNvbWVib2R5IGVsc2UncyB0byByZXN0YXJ0IFx1MjAxNFxuICAgICAgICAgKiB0aGUgc2FtZSBvd25lcnNoaXAgbGluZSB0ZWFyZG93biBkcmF3cyBpbiBuZXZlciBzd2VlcGluZyBgcWVtdSpgLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3Qgb3duZWRFbXVsYXRvclByb2Nlc3MgPSBlbXVsYXRvclByb2Nlc3M7XG4gICAgICAgIGNvbnN0IGNhblJldHJ5ID0gYXR0ZW1wdCA8IEVNVUxBVE9SX0JPT1RfQVRURU1QVF9DT1VOVCAmJiBvd25lZEVtdWxhdG9yUGlkcy5sZW5ndGggPiAwO1xuICAgICAgICBpZiAoIWNhblJldHJ5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRpYWdub3Npcyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvZyhgJHtkaWFnbm9zaXN9XFxuXFxuQm9vdGluZyBhIGZyZXNoIGVtdWxhdG9yIGFuZCB0cnlpbmcgb25jZSBtb3JlIChhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQgKyAxKX0gb2YgJHtTdHJpbmcoRU1VTEFUT1JfQk9PVF9BVFRFTVBUX0NPVU5UKX0pLmApO1xuICAgICAgICAvKlxuICAgICAgICAgKiBEaXNvd24gQkVGT1JFIHN0b3BwaW5nLCBub3QgYWZ0ZXI6IHRoaXMgcnVuIGhhbmRzIHRoZSBlbXVsYXRvciBvdmVyIHRvXG4gICAgICAgICAqIGBzdG9wRW11bGF0b3JgIGFuZCBtdXN0IG5vdCBzdGlsbCBiZSBob2xkaW5nIGl0IGlmIHRoYXQgdGhyb3dzLCBvciB0aGVcbiAgICAgICAgICogb3V0ZXIgY2F0Y2gncyB0ZWFyZG93biB3b3VsZCBnbyBhZnRlciB0aGUgc2FtZSBwcm9jZXNzZXMgYSBzZWNvbmRcbiAgICAgICAgICogdGltZS5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGRvb21lZERldmljZUlkID0gYWN0dWFsRGV2aWNlSWQ7XG4gICAgICAgIGNvbnN0IGRvb21lZFBpZHMgPSBvd25lZEVtdWxhdG9yUGlkcztcbiAgICAgICAgZW11bGF0b3JQcm9jZXNzID0gdW5kZWZpbmVkO1xuICAgICAgICBvd25lZEVtdWxhdG9yUGlkcyA9IFtdO1xuICAgICAgICBhY3R1YWxEZXZpY2VJZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgYXdhaXQgdGhpcy5lbXVsYXRvcnMuc3RvcEVtdWxhdG9yKHtcbiAgICAgICAgICBhdmROYW1lOiBvcHRpb25zLmF2ZE5hbWUsXG4gICAgICAgICAgZGV2aWNlSWQ6IGRvb21lZERldmljZUlkLFxuICAgICAgICAgIGVtdWxhdG9yUHJvY2Vzczogb3duZWRFbXVsYXRvclByb2Nlc3MsXG4gICAgICAgICAgb3duZWRFbXVsYXRvclBpZHM6IGRvb21lZFBpZHNcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCB8fCBhY3R1YWxEZXZpY2VJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IHByb3Zpc2lvbiBhbiBBbmRyb2lkIGRldmljZSBmb3IgQVZEIFwiJHtvcHRpb25zLmF2ZE5hbWV9XCIuYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNlc3Npb25SZXN1bHQgPSBhd2FpdCB0aGlzLmVzdGFibGlzaFNlc3Npb25PckRpYWdub3NlRGV2aWNlKHJlc3VsdC5lbXVsYXRvckNhcHR1cmUsIHtcbiAgICAgICAgYXBwSWQsXG4gICAgICAgIGFwcGl1bVNlcnZlck1hcmtlcjogcmVzdWx0LmFwcGl1bVNlcnZlck1hcmtlcixcbiAgICAgICAgYXBwaXVtU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IHJlc29sdmVBcHBpdW1TdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgZGV2aWNlSWQ6IGFjdHVhbERldmljZUlkLFxuICAgICAgICBpc0Fkb3B0ZWRTZXJ2ZXI6IHJlc3VsdC5pc0Fkb3B0ZWRBcHBpdW1TZXJ2ZXIsXG4gICAgICAgIGlzQXBwaXVtQ29uc29sZVZpc2libGU6IG9wdGlvbnMuaXNBcHBpdW1Db25zb2xlVmlzaWJsZSxcbiAgICAgICAgcG9ydCxcbiAgICAgICAgc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlU2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzKG9wdGlvbnMpLFxuICAgICAgICBzZXNzaW9uQ29ubmVjdGlvblJldHJ5VGltZW91dEluTWlsbGlzZWNvbmRzOiByZXNvbHZlU2Vzc2lvbkNvbm5lY3Rpb25SZXRyeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgc2hvdWxkQXV0b1N0YXJ0QXBwaXVtOiBvcHRpb25zLnNob3VsZEF1dG9TdGFydEFwcGl1bSxcbiAgICAgICAgdXJsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgYnJvd3NlciA9IHNlc3Npb25SZXN1bHQuYnJvd3NlcjtcbiAgICAgIC8vIEEgd2VkZ2VkIGFkb3B0ZWQgc2VydmVyIGlzIHJlcGxhY2VkIGJ5IG9uZSB0aGlzIHJ1biBvd25zLCBzbyBpdCBtdXN0IGJlIHRvcm4gZG93biBsaWtlIGFueSBvdGhlciBhdXRvLXN0YXJ0ZWQgc2VydmVyLlxuICAgICAgaWYgKHNlc3Npb25SZXN1bHQuYXBwaXVtUHJvY2VzcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGFwcGl1bVByb2Nlc3MgPSBzZXNzaW9uUmVzdWx0LmFwcGl1bVByb2Nlc3M7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubG9nKCdBcHBpdW0gc2Vzc2lvbiBlc3RhYmxpc2hlZC4nKTtcbiAgICAgIC8qXG4gICAgICAgKiBUaGUgZW11bGF0b3IgaGFzIG5vdGhpbmcgbGVmdCB0byBleHBsYWluLCBzbyBmcmVlemUgaXRzIHRhaWwgaGVyZSByYXRoZXJcbiAgICAgICAqIHRoYW4gYXQgYm9vdC4gRXZlcnl0aGluZyB1cCB0byB0aGlzIGxpbmUgXHUyMDE0IGluY2x1ZGluZyB0aGUgd2luZG93IGluIHdoaWNoXG4gICAgICAgKiBhIHdlZGdlIHN1cmZhY2VzIFx1MjAxNCBpcyBub3cgaW5zaWRlIHRoZSBjYXB0dXJlZCBvdXRwdXQuXG4gICAgICAgKi9cbiAgICAgIHJlc3VsdC5lbXVsYXRvckNhcHR1cmU/LnN0b3AoKTtcbiAgICAgIGNvbnN0IGFwcGl1bVRyYW5zcG9ydCA9IG5ldyBBcHBpdW1UcmFuc3BvcnQoe1xuICAgICAgICBhcHBJZCxcbiAgICAgICAgYnJvd3NlcixcbiAgICAgICAgZGV2aWNlSWQ6IGFjdHVhbERldmljZUlkLFxuICAgICAgICBwbGF0Zm9ybTogJ2FuZHJvaWQnLFxuICAgICAgICAvLyBUaGUgc2FtZSBudW1iZXIgdGhlIHNlc3Npb24gd2FzIGNyZWF0ZWQgd2l0aCBhYm92ZSwgc28gYSBzY3JpcHQgdGltZW91dCByZXBvcnRzIHRoZSBjYXAgdGhhdCBraWxsZWQgaXQuXG4gICAgICAgIHNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcmVzb2x2ZVNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcyhvcHRpb25zKSxcbiAgICAgICAgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM6IHdpbGxTd2VlcExlZnRvdmVycyhvcHRpb25zKSxcbiAgICAgICAgLi4uKG9wdGlvbnMuYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMgIT09IHVuZGVmaW5lZCAmJiB7IGFwcFN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zLmFwcFN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzIH0pLFxuICAgICAgICAuLi4ob3B0aW9ucy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG9wdGlvbnMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSksXG4gICAgICAgIC4uLihvcHRpb25zLnZhdWx0QmFzZVBhdGggIT09IHVuZGVmaW5lZCAmJiB7IHZhdWx0QmFzZVBhdGg6IG9wdGlvbnMudmF1bHRCYXNlUGF0aCB9KSxcbiAgICAgICAgLi4uKG9wdGlvbnMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkICYmIHsgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kczogb3B0aW9ucy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzIH0pXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgb3JpZ2luYWxEaXNwb3NlID0gYXBwaXVtVHJhbnNwb3J0LmRpc3Bvc2UuYmluZChhcHBpdW1UcmFuc3BvcnQpO1xuICAgICAgY29uc3QgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydCA9IGFwcGl1bVRyYW5zcG9ydDtcbiAgICAgIHRyYW5zcG9ydC5kaXNwb3NlID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IG9yaWdpbmFsRGlzcG9zZSgpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuc3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzVmVyaWZpZWQoYnVpbGRTdG9wUGFyYW1zKCkpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBDaGFpbiByYXRoZXIgdGhhbiByZXBsYWNlOiB0aGUgdHJhbnNwb3J0J3Mgb3duIHN5bmMgdGVhcmRvd24gZHJvcHMgdGhlIHRydXN0ZWQtaW5wdXQgY2hhbm5lbCdzXG4gICAgICAvLyBhZGIgcG9ydCBmb3J3YXJkLCB3aGljaCB3b3VsZCBvdGhlcndpc2UgYmUgc3RyYW5kZWQgb24gdGhlIGRldmljZSBieSBhbiBhYnJ1cHQgZXhpdC5cbiAgICAgIGNvbnN0IG9yaWdpbmFsRGlzcG9zZVN5bmMgPSBhcHBpdW1UcmFuc3BvcnQuZGlzcG9zZVN5bmMuYmluZChhcHBpdW1UcmFuc3BvcnQpO1xuICAgICAgdHJhbnNwb3J0LmRpc3Bvc2VTeW5jID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIG9yaWdpbmFsRGlzcG9zZVN5bmMoKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICB0aGlzLnN0b3BBdXRvU3RhcnRlZFByb2Nlc3Nlc0Jlc3RFZmZvcnQoYnVpbGRTdG9wUGFyYW1zKCkpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3BBdXRvU3RhcnRlZFByb2Nlc3Nlc1ZlcmlmaWVkKGJ1aWxkU3RvcFBhcmFtcygpKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJ1aWxkU3RvcFBhcmFtcygpOiBTdG9wQXV0b1N0YXJ0ZWRQcm9jZXNzZXNQYXJhbXMge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXBwaXVtUHJvY2VzcyxcbiAgICAgICAgYXZkTmFtZTogb3B0aW9ucy5hdmROYW1lLFxuICAgICAgICBkZXZpY2VJZDogYWN0dWFsRGV2aWNlSWQsXG4gICAgICAgIGVtdWxhdG9yUHJvY2VzcyxcbiAgICAgICAgb3duZWRFbXVsYXRvclBpZHMsXG4gICAgICAgIHBvcnQsXG4gICAgICAgIHVybFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVzY3JpYmVzIGFuIGFkb3B0ZWQgc2VydmVyJ3MgcHJvdmVuYW5jZSBmb3IgdGhlIHByZWZsaWdodCBsb2csIHNvIGEgc3RhbGVcbiAgICogbGVmdG92ZXIgaXMgdmlzaWJsZSBpbiB0aGUgdHJhbnNjcmlwdCBvZiBhIHJ1biB0aGF0IGdvZXMgb24gdG8gc3VjY2VlZCBcdTIwMTQgbm90XG4gICAqIG9ubHkgaW4gdGhlIGVycm9yIG9mIG9uZSB0aGF0IGZhaWxzLlxuICAgKlxuICAgKiBAcGFyYW0gbWFya2VyIC0gVGhlIG1hcmtlciByZWFkIGZvciB0aGUgcG9ydCwgaWYgYW55LlxuICAgKiBAcmV0dXJucyBBIHNob3J0IHByb3ZlbmFuY2UgZGVzY3JpcHRpb24uXG4gICAqL1xuICBwcml2YXRlIGRlc2NyaWJlQWRvcHRlZFNlcnZlcihtYXJrZXI6IEFwcGl1bVNlcnZlck1hcmtlciB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gICAgaWYgKCFtYXJrZXIgfHwgIWNoZWNrSXNIYXJuZXNzT3duZWRBcHBpdW1TZXJ2ZXIobWFya2VyKSkge1xuICAgICAgcmV0dXJuICdub3Qgc3RhcnRlZCBieSB0aGlzIGhhcm5lc3MnO1xuICAgIH1cblxuICAgIGNvbnN0IGFnZUluU2Vjb25kcyA9IE1hdGgucm91bmQoKERhdGUubm93KCkgLSBtYXJrZXIuc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMpIC8gTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQpO1xuICAgIGNvbnN0IHVuc3RvcHBlZFN1ZmZpeCA9IG1hcmtlci5zdG9wQXR0ZW1wdGVkQXRJbk1pbGxpc2Vjb25kcyA9PT0gdW5kZWZpbmVkID8gJycgOiAnLCBhbmQgYW4gZWFybGllciBydW4gZmFpbGVkIHRvIHN0b3AgaXQnO1xuICAgIHJldHVybiBgc3RhcnRlZCBieSBhbiBlYXJsaWVyIHJ1biBvZiB0aGlzIGhhcm5lc3MsIHBpZCAke1N0cmluZyhtYXJrZXIucGlkKX0sIHVwIGZvciAke1N0cmluZyhhZ2VJblNlY29uZHMpfXMke3Vuc3RvcHBlZFN1ZmZpeH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2JlcyB0aGUgZGV2aWNlIGFuZCByZXR1cm5zIHRoZSBmYWlsdXJlIG1lc3NhZ2Ugd2hlbiBpdCBpcyBubyBsb25nZXJcbiAgICogdXNhYmxlLCBvciBgdW5kZWZpbmVkYCB3aGVuIGl0IGlzIGZpbmUuXG4gICAqXG4gICAqIFRoZSByZWFkaW5lc3MgZ2F0ZXMgdGhhdCBydW4gYmVmb3JlIHRoaXMgb25lIGFyZSBkZWxpYmVyYXRlbHkgYmVzdC1lZmZvcnQgXHUyMDE0XG4gICAqIHRoZXkgd2FybiBhbmQgcHJvY2VlZCBcdTIwMTQgc28gbm90aGluZyBhc2tlZCB3aGV0aGVyIHRoZSBkZXZpY2Ugd2FzIHN0aWxsIHRoZXJlXG4gICAqIGF0IHRoZSBtb21lbnQgaXQgbWF0dGVyZWQuIEEgZ3Vlc3QgdGhhdCB3ZW50IHF1aWV0IGluIHRoZSBtZWFudGltZSB3YXNcbiAgICogaGFuZGVkIHRvIEFwcGl1bSwgd2hpY2ggcmVwb3J0ZWQgYERldmljZSA8aWQ+IHdhcyBub3QgaW4gdGhlIGxpc3Qgb2ZcbiAgICogY29ubmVjdGVkIGRldmljZXNgOyBgYWRiIGRldmljZXNgIHRoZW4gbGlzdGVkIGl0LCBhbmQgdGhlIHRyYWlsIHdlbnQgY29sZC5cbiAgICpcbiAgICogVGhlIHNlY29uZCBwcm9iZSBpcyBvbmx5IHBhaWQgZm9yIHdoZW4gdGhlIGZpcnN0IG9uZSBmYWlscywgYW5kIHRoZSB2ZXJkaWN0XG4gICAqIGRpc3Rpbmd1aXNoZXMgYSBmcm96ZW4gZ3Vlc3QgZnJvbSBhbiB1bnJlYWNoYWJsZSBlbXVsYXRvciBcdTIwMTQgc2VlXG4gICAqIGBlbXVsYXRvci1saXZlbmVzcy50c2AgZm9yIHRoZSBtZWFzdXJlbWVudHMgYmVoaW5kIHRoYXQgc3BsaXQuXG4gICAqXG4gICAqIFJldHVybmluZyB0aGUgbWVzc2FnZSByYXRoZXIgdGhhbiB0aHJvd2luZyBpdCBpcyB3aGF0IGxldHMgYm90aCBjYWxsZXJzIHVzZVxuICAgKiB0aGUgc2FtZSBkaWFnbm9zaXM6IHRoZSBwcm92aXNpb25pbmcgbG9vcCBkZWNpZGVzIHdoZXRoZXIgdG8gYm9vdCBhIGZyZXNoXG4gICAqIGVtdWxhdG9yLCBhbmQgdGhlIHNlc3Npb24gcGF0aCBuZWVkcyBpdHMgb3duIGVycm9yIHRvIHN1cnZpdmUgYXMgdGhlXG4gICAqIGBjYXVzZWAuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgdG8gcHJvYmUuXG4gICAqIEBwYXJhbSBlbXVsYXRvckNhcHR1cmUgLSBUaGUgZW11bGF0b3IncyBvdXRwdXQsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBpdC5cbiAgICogQHJldHVybnMgVGhlIGRpYWdub3Npcywgb3IgYHVuZGVmaW5lZGAgd2hlbiB0aGUgZGV2aWNlIHN0aWxsIGFuc3dlcnMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRpYWdub3NlRGV2aWNlKGRldmljZUlkOiBzdHJpbmcsIGVtdWxhdG9yQ2FwdHVyZT86IEVtdWxhdG9yQ2FwdHVyZSk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3Qgc2hlbGxQcm9iZSA9IGF3YWl0IHRoaXMucHJvYmVEZXZpY2VTaGVsbChkZXZpY2VJZCk7XG4gICAgaWYgKHNoZWxsUHJvYmUgPT09ICdhbnN3ZXJlZCcpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBkaWQgbm90IGFuc3dlciBcXGBhZGIgLXMgJHtkZXZpY2VJZH0gc2hlbGxcXGA7IGNoZWNraW5nIHdoZXRoZXIgdGhlIGVtdWxhdG9yIGl0c2VsZiBpcyBzdGlsbCBhbGl2ZS4uLmApO1xuICAgIGNvbnN0IFtjb25zb2xlUHJvYmUsIGlzTGlzdGVkQnlBZGJdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgdGhpcy5wcm9iZUVtdWxhdG9yQ29uc29sZShkZXZpY2VJZCksXG4gICAgICB0aGlzLmNoZWNrSXNEZXZpY2VMaXN0ZWRRdWlldGx5KGRldmljZUlkKVxuICAgIF0pO1xuXG4gICAgY29uc3QgdmVyZGljdCA9IHJlc29sdmVFbXVsYXRvckxpdmVuZXNzVmVyZGljdCh7XG4gICAgICBjb25zb2xlUHJvYmUsXG4gICAgICBkZXZpY2VJZCxcbiAgICAgIGlzTGlzdGVkQnlBZGIsXG4gICAgICBzaGVsbFByb2JlXG4gICAgfSk7XG4gICAgdGhpcy5sb2coYERldmljZSBsaXZlbmVzczogJHtkZXZpY2VJZH0gc2hlbGw9JHtzaGVsbFByb2JlfSwgY29uc29sZT0ke2NvbnNvbGVQcm9iZX0gLT4gJHt2ZXJkaWN0fS5gKTtcblxuICAgIC8vIFVucmVhY2hhYmxlIGluIHByYWN0aWNlIFx1MjAxNCB0aGUgdmVyZGljdCBpcyBvbmx5IGAnYWxpdmUnYCB3aGVuIHRoZSBzaGVsbCBhbnN3ZXJlZCwgd2hpY2ggcmV0dXJuZWQgYWJvdmUgXHUyMDE0IGJ1dCBpdCBpcyB3aGF0IG5hcnJvd3MgdGhlIHR5cGUgZm9yIHRoZSBidWlsZGVyLlxuICAgIHJldHVybiB2ZXJkaWN0ID09PSAnYWxpdmUnXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiBidWlsZEVtdWxhdG9yTGl2ZW5lc3NNZXNzYWdlKHtcbiAgICAgICAgZGV2aWNlSWQsXG4gICAgICAgIGVtdWxhdG9yT3V0cHV0OiBlbXVsYXRvckNhcHR1cmU/LnJlYWQoKSA/PyAnJyxcbiAgICAgICAgcHJvYmVUaW1lb3V0SW5NaWxsaXNlY29uZHM6IERFVklDRV9MSVZFTkVTU19USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgdmVyZGljdFxuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGR1bXBDb25uZWN0aXZpdHkoZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGl2aXR5UHJvYmVSZXN1bHQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIGV4ZWNGaWxlKFxuICAgICAgICAnYWRiJyxcbiAgICAgICAgWyctcycsIGRldmljZUlkLCAnc2hlbGwnLCAnZHVtcHN5cycsICdjb25uZWN0aXZpdHknXSxcbiAgICAgICAgeyBtYXhCdWZmZXI6IEFEQl9EVU1QU1lTX01BWF9CVUZGRVJfSU5fQllURVMsIHRpbWVvdXQ6IEFEQl9EVU1QU1lTX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sXG4gICAgICAgIChlcnJvciwgc3Rkb3V0LCBzdGRlcnIpID0+IHtcbiAgICAgICAgICAvKlxuICAgICAgICAgICAqIEEgZmFpbHVyZSBjYXJyaWVzIGl0cyByZWFzb24sIE5PVCBhbiBlbXB0eSBzdHJpbmcuIFRoZSBvdGhlciBwcm9iZXNcbiAgICAgICAgICAgKiBjb2xsYXBzZSBhIGZhaWx1cmUgaW50byBlbXB0eSBvdXRwdXQgYmVjYXVzZSB0aGVyZSBcImVtcHR5XCIgYW5kXG4gICAgICAgICAgICogXCJmYWlsZWRcIiBib3RoIG1lYW4gbm90LWlkbGUsIGJ1dCBoZXJlIHRoZXkgbWVhbiBkaWZmZXJlbnQgdGhpbmdzIGFuZFxuICAgICAgICAgICAqIG9ubHkgb25lIG9mIHRoZW0gaXMgYWJvdXQgdGhlIG5ldHdvcms6IGEgcHJvYmUgdGhhdCBuZXZlciBhbnN3ZXJzXG4gICAgICAgICAgICogbXVzdCBub3QgYmUgcmVwb3J0ZWQgYXMgYSBndWVzdCB3aXRob3V0IGEgcm91dGUuXG4gICAgICAgICAgICovXG4gICAgICAgICAgaWYgKCFlcnJvcikge1xuICAgICAgICAgICAgcmVzb2x2ZSh7IG91dHB1dDogc3Rkb3V0IH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGRldGFpbCA9IChzdGRlcnIudHJpbSgpIHx8IGVycm9yLm1lc3NhZ2UudHJpbSgpKS5zcGxpdCgnXFxuJywgMSlbMF0gPz8gJyc7XG4gICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICBmYWlsdXJlUmVhc29uOiBlcnJvci5raWxsZWRcbiAgICAgICAgICAgICAgPyBgbm8gYW5zd2VyIHdpdGhpbiAke1N0cmluZyhBREJfRFVNUFNZU19USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXNgXG4gICAgICAgICAgICAgIDogZGV0YWlsIHx8ICdhZGIgZmFpbGVkIHdpdGggbm8gbWVzc2FnZSdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZSBBcHBpdW0gdG9vbGNoYWluIGlzIHByZXNlbnQgYmVmb3JlIHRoZSBzZXJ2ZXIgaXMgYXV0by1zdGFydGVkOlxuICAgKiBBcHBpdW0gaXRzZWxmLCB0aGVuIHRoZSBgdWlhdXRvbWF0b3IyYCBkcml2ZXIuIEVhY2ggaXMgY2hlY2tlZCBmaXJzdCBhbmRcbiAgICogaW5zdGFsbGVkIG9ubHkgd2hlbiBtaXNzaW5nLCBzbyBhIGZ1bGx5LXByb3Zpc2lvbmVkIG1hY2hpbmUgaW5jdXJzIGp1c3QgdHdvXG4gICAqIGZhc3QgdmVyc2lvbi9saXN0IHByb2Jlcy5cbiAgICpcbiAgICogT25seSBpbnZva2VkIHdoZW4gdGhlIGhhcm5lc3MgaXMgYWJvdXQgdG8gYXV0by1zdGFydCB0aGUgc2VydmVyIGFuZFxuICAgKiB7QGxpbmsgT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucy5zaG91bGRBdXRvSW5zdGFsbEFwcGl1bURlcGVuZGVuY2llc31cbiAgICogaXMgZW5hYmxlZC4gQ29tbWFuZHMgYXJlIHBhc3NlZCBhcyBzdHJpbmdzIHNvIGBleGVjYCBydW5zIHRoZW0gdGhyb3VnaCB0aGVcbiAgICogc2hlbGwsIHdoaWNoIHJlc29sdmVzIHRoZSBgbnBtYC9gbnB4YCBgLmNtZGAgc2hpbXMgb24gV2luZG93cyAodGhlIGFycmF5XG4gICAqIHBhdGggc3Bhd25zIHdpdGhvdXQgYSBzaGVsbCBhbmQgY2Fubm90KS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQXBwaXVtRGVwZW5kZW5jaWVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlQXBwaXVtSW5zdGFsbGVkKCk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVVaWF1dG9tYXRvcjJEcml2ZXJJbnN0YWxsZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQXBwaXVtSW5zdGFsbGVkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nKCdDaGVja2luZyB3aGV0aGVyIEFwcGl1bSBpcyBpbnN0YWxsZWQuLi4nKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBleGVjKCducHggLS1uby1pbnN0YWxsIGFwcGl1bSAtLXZlcnNpb24nLCB7XG4gICAgICBpc1F1aWV0OiB0cnVlLFxuICAgICAgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsXG4gICAgICBzaG91bGRJbmNsdWRlRGV0YWlsczogdHJ1ZVxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdC5leGl0Q29kZSA9PT0gMCkge1xuICAgICAgdGhpcy5sb2coYEFwcGl1bSBpcyBpbnN0YWxsZWQgKHZlcnNpb24gJHtyZXN1bHQuc3Rkb3V0LnRyaW0oKSB8fCAndW5rbm93bid9KS5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxvZygnQXBwaXVtIGlzIG5vdCBpbnN0YWxsZWQuIEluc3RhbGxpbmcgZ2xvYmFsbHkgdmlhIGBucG0gaW5zdGFsbCAtZyBhcHBpdW1gLi4uJyk7XG4gICAgYXdhaXQgZXhlYygnbnBtIGluc3RhbGwgLWcgYXBwaXVtJyk7XG5cbiAgICAvKlxuICAgICAqIFJlLXZlcmlmeTogYSBnbG9iYWwgaW5zdGFsbCBjYW4gbGFuZCB1bmRlciBhbiBucG0gcHJlZml4IHdob3NlIGJpbiBkaXIgaXNcbiAgICAgKiBub3Qgb24gdGhlIHNwYXduIFBBVEggKGUuZy4gYSBzY29vcC9udm0tbWFuYWdlZCBwcmVmaXgpLCBpbiB3aGljaCBjYXNlXG4gICAgICogYG5weCAtLW5vLWluc3RhbGwgYXBwaXVtYCBzdGlsbCBjYW5ub3QgcmVzb2x2ZSBpdC4gRmFpbCBmYXN0IHdpdGggYW5cbiAgICAgKiBhY3Rpb25hYmxlIG1lc3NhZ2UgcmF0aGVyIHRoYW4gcHJvY2VlZGluZyB0byBhdXRvLXN0YXJ0IGEgc2VydmVyIHRoYXQgY2FuXG4gICAgICogbmV2ZXIgY29tZSB1cCAod2hpY2ggd291bGQgb3RoZXJ3aXNlIHNwaW4gb3V0IHRoZSBmdWxsIHJlYWRpbmVzcyB0aW1lb3V0KS5cbiAgICAgKi9cbiAgICBjb25zdCB2ZXJpZnkgPSBhd2FpdCBleGVjKCducHggLS1uby1pbnN0YWxsIGFwcGl1bSAtLXZlcnNpb24nLCB7XG4gICAgICBpc1F1aWV0OiB0cnVlLFxuICAgICAgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsXG4gICAgICBzaG91bGRJbmNsdWRlRGV0YWlsczogdHJ1ZVxuICAgIH0pO1xuICAgIGlmICh2ZXJpZnkuZXhpdENvZGUgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0FwcGl1bSB3YXMgaW5zdGFsbGVkIHZpYSBgbnBtIGluc3RhbGwgLWcgYXBwaXVtYCBidXQgaXMgc3RpbGwgbm90IHJlc29sdmFibGUgdmlhIGBucHggLS1uby1pbnN0YWxsIGFwcGl1bWAuICdcbiAgICAgICAgICArICdUaGUgbnBtIGdsb2JhbCBiaW4gZGlyZWN0b3J5IChzZWUgYG5wbSBjb25maWcgZ2V0IHByZWZpeGApIGlzIGxpa2VseSBub3Qgb24gUEFUSC4gQWRkIGl0IHRvIFBBVEgsIG9yIHNldCAnXG4gICAgICAgICAgKyAnYHNob3VsZEF1dG9JbnN0YWxsQXBwaXVtRGVwZW5kZW5jaWVzOiBmYWxzZWAgYW5kIGluc3RhbGwvbWFuYWdlIEFwcGl1bSB5b3Vyc2VsZi4nXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmxvZyhgQXBwaXVtIGluc3RhbGxlZCAodmVyc2lvbiAke3ZlcmlmeS5zdGRvdXQudHJpbSgpIHx8ICd1bmtub3duJ30pLmApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZhaWxzIGZhc3Qgd2hlbiB0aGUgcmVxdWVzdGVkIEFWRCBkb2VzIG5vdCBleGlzdCwgYmVmb3JlIGFuIGVtdWxhdG9yIGlzXG4gICAqIHNwYXduZWQuXG4gICAqXG4gICAqIFdpdGhvdXQgdGhpcyBwcmVmbGlnaHQgYSBtaXNzaW5nIEFWRCBuYW1lIGlzIG9ubHkgZGlzY292ZXJlZCBhZnRlclxuICAgKiB7QGxpbmsgc3RhcnRFbXVsYXRvcn0gc3Bhd25zIGBlbXVsYXRvciAtYXZkIDxuYW1lPmAgYW5kIHRoZSBib290IG5ldmVyXG4gICAqIGNvbXBsZXRlcyBcdTIwMTQgYSBmdWxsIHtAbGluayBFTVVMQVRPUl9CT09UX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTfSBzcGluIGVuZGluZ1xuICAgKiBpbiBhIGdlbmVyaWMgXCJubyBuZXcgZGV2aWNlIGFwcGVhcmVkXCIuIEluc3RlYWQgdGhpcyBsaXN0cyB0aGUgY29uZmlndXJlZFxuICAgKiBBVkRzIHVwIGZyb250IGFuZCB0aHJvd3MgYW4gYWN0aW9uYWJsZSBlcnJvciBuYW1pbmcgdGhlIGF2YWlsYWJsZSBvbmVzLiBBVkRcbiAgICogY3JlYXRpb24gaXMgZGVsaWJlcmF0ZWx5IG5vdCBhdXRvbWF0ZWQgKGl0IHJlcXVpcmVzIGEgc3lzdGVtLWltYWdlIGRvd25sb2FkLFxuICAgKiBsaWNlbnNlIGFjY2VwdGFuY2UsIGFuZCBoYXJkd2FyZS9BUEktbGV2ZWwgY2hvaWNlcykuXG4gICAqXG4gICAqIEBwYXJhbSBhdmROYW1lIC0gVGhlIHJlcXVlc3RlZCBBVkQgbmFtZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQXZkRXhpc3RzKGF2ZE5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGVtdWxhdG9yQmluYXJ5ID0gcmVzb2x2ZUVtdWxhdG9yQmluYXJ5UGF0aCgpO1xuICAgIHRoaXMubG9nKGBWZXJpZnlpbmcgQVZEIFwiJHthdmROYW1lfVwiIGV4aXN0cyAoJHtlbXVsYXRvckJpbmFyeX0gLWxpc3QtYXZkcykuLi5gKTtcblxuICAgIGNvbnN0IFtlcnJvciwgc3Rkb3V0XSA9IGF3YWl0IG5ldyBQcm9taXNlPFtFcnJvciB8IG51bGwsIHN0cmluZ10+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShlbXVsYXRvckJpbmFyeSwgWyctbGlzdC1hdmRzJ10sIHsgdGltZW91dDogRU1VTEFUT1JfTElTVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LCAoZXhlY0Vycm9yLCBleGVjU3Rkb3V0KSA9PiB7XG4gICAgICAgIHJlc29sdmUoW2V4ZWNFcnJvciwgZXhlY1N0ZG91dF0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBsaXN0IEFWRHMgdmlhIFxcYCR7ZW11bGF0b3JCaW5hcnl9IC1saXN0LWF2ZHNcXGA6ICR7ZXJyb3IubWVzc2FnZX0uIGBcbiAgICAgICAgICArICdJcyB0aGUgQW5kcm9pZCBTREsgZW11bGF0b3IgaW5zdGFsbGVkIGFuZCBBTkRST0lEX0hPTUUvQU5EUk9JRF9TREtfUk9PVCBjb3JyZWN0PydcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFjaGVja0F2ZEV4aXN0cyh7IGF2ZExpc3RPdXRwdXQ6IHN0ZG91dCwgYXZkTmFtZSB9KSkge1xuICAgICAgY29uc3QgYXZhaWxhYmxlID0gbGlzdEF2YWlsYWJsZUF2ZHMoc3Rkb3V0KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEFuZHJvaWQgQVZEIFwiJHthdmROYW1lfVwiIG5vdCBmb3VuZC4gQXZhaWxhYmxlIEFWRHM6ICR7YXZhaWxhYmxlLmxlbmd0aCA+IDAgPyBhdmFpbGFibGUuam9pbignLCAnKSA6ICcobm9uZSknfS4gYFxuICAgICAgICAgICsgJ0NyZWF0ZSBpdCAoZS5nLiBpbiB0aGUgQW5kcm9pZCBTdHVkaW8gRGV2aWNlIE1hbmFnZXIsIG9yIHZpYSBgYXZkbWFuYWdlciBjcmVhdGUgYXZkYCksIG9yIHNldCBgYXZkTmFtZWAgdG8gYW4gZXhpc3RpbmcgQVZELidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYEFWRCBcIiR7YXZkTmFtZX1cIiBleGlzdHMuYCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVuc3VyZURldmljZUNvbm5lY3RlZChwYXJhbXM6IEVuc3VyZURldmljZUNvbm5lY3RlZFBhcmFtcyk6IFByb21pc2U8RW5zdXJlRGV2aWNlQ29ubmVjdGVkUmVzdWx0PiB7XG4gICAgY29uc3QgeyBhdmROYW1lLCBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzLCBpc0VtdWxhdG9yVmlzaWJsZSwgbmV0d29ya1JlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgdGltZW91dHM6IERldmljZVJlYWRpbmVzc1RpbWVvdXRzID0geyBkZXZpY2VJZGxlVGltZW91dEluTWlsbGlzZWNvbmRzLCBuZXR3b3JrUmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgfTtcbiAgICAvKlxuICAgICAqIEJlZm9yZSB0aGUgZGV2aWNlIGxpc3RpbmcsIHNvIGEgbGVmdG92ZXIgc3RvcHBlZCBoZXJlIGlzIG5vdCBsaXN0ZWQuIE9ubHlcbiAgICAgKiBPVEhFUiBBVkRzOiBhIGxlZnRvdmVyIG9mIHRoaXMgb25lIGlzIHdvcnRoIGFkb3B0aW5nIChhbmQgb3duaW5nKSBiZWxvdy5cbiAgICAgKiBUaGlzIGlzIHRoZSBzZXF1ZW5jZSB0aGF0IGZpbGxlZCB0aGUgZHJpdmU6IGEgbGVha2VkIGBvYnNpZGlhbl90ZXN0YCBzYXRcbiAgICAgKiBiZXNpZGUgZXZlcnkgbGF0ZXIgcnVuLCBlYWNoIG9mIHdoaWNoIHByb2JlZCBpdCBhcyBgb3RoZXItYXZkYCwgYm9vdGVkXG4gICAgICogaXRzIG93biBlbXVsYXRvciBuZXh0IHRvIGl0LCBhbmQgbGVmdCBpdCBydW5uaW5nLlxuICAgICAqL1xuICAgIGF3YWl0IHRoaXMuZW11bGF0b3JzLnJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9ycyh7IGV4Y2VwdEF2ZE5hbWU6IGF2ZE5hbWUsIHNjb3BlOiAncHJlZmxpZ2h0JyB9KTtcbiAgICBjb25zdCBkZXZpY2VJZHNCZWZvcmUgPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZERldmljZUlkcygpO1xuICAgIHRoaXMubG9nKGBDaGVja2luZyBleGlzdGluZyBkZXZpY2VzIGZvciBBVkQgXCIke2F2ZE5hbWV9XCIuLi4gKGNvbm5lY3RlZDogWyR7ZGV2aWNlSWRzQmVmb3JlLmpvaW4oJywgJyl9XSlgKTtcblxuICAgIGNvbnN0IHByb2JlUmVzdWx0cyA9IGF3YWl0IHRoaXMucHJvYmVEZXZpY2VzRm9yQXZkKGF2ZE5hbWUsIGRldmljZUlkc0JlZm9yZSk7XG4gICAgdGhpcy5sb2coYEFWRCBwcm9iZTogJHtidWlsZEF2ZFByb2JlU3VtbWFyeShwcm9iZVJlc3VsdHMpfS5gKTtcbiAgICBjb25zdCBwcm9iZVZlcmRpY3QgPSByZXNvbHZlQXZkUHJvYmVWZXJkaWN0KHByb2JlUmVzdWx0cyk7XG5cbiAgICBzd2l0Y2ggKHByb2JlVmVyZGljdC52ZXJkaWN0KSB7XG4gICAgICBjYXNlICdyZWZ1c2UnOiB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIFNpbGVuY2UgaXMgbm90IGEgc2tpcC4gRmFsbGluZyB0aHJvdWdoIHRvIGEgbGF1bmNoIGhlcmUgaXMgd2hhdFxuICAgICAgICAgKiBwcm9kdWNlZCBgRkFUQUwgfCBSdW5uaW5nIG11bHRpcGxlIGVtdWxhdG9ycyB3aXRoIHRoZSBzYW1lIEFWRGAgXHUyMDE0XG4gICAgICAgICAqIHNlZSBgYXZkLXByb2JlLXZlcmRpY3QudHNgIGZvciB0aGUgcnVuIHRoaXMgcmVwcm9kdWNlcy5cbiAgICAgICAgICovXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihidWlsZFVucmVhZGFibGVEZXZpY2VzTWVzc2FnZSh7XG4gICAgICAgICAgYXZkTmFtZSxcbiAgICAgICAgICBwcm9iZVRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICAgICAgICB1bnJlYWRhYmxlRGV2aWNlSWRzOiBwcm9iZVZlcmRpY3QudW5yZWFkYWJsZURldmljZUlkc1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgICBjYXNlICdyZXVzZSc6IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmV1c2VDb25uZWN0ZWREZXZpY2UoYXZkTmFtZSwgcHJvYmVWZXJkaWN0LmRldmljZUlkLCB0aW1lb3V0cyk7XG4gICAgICB9XG4gICAgICBjYXNlICdzdGFydC1uZXcnOiB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICByZXR1cm4gYXNzZXJ0TmV2ZXIocHJvYmVWZXJkaWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxvZyhgQVZEIFwiJHthdmROYW1lfVwiIG5vdCBmb3VuZCBvbiBhbnkgZXhpc3RpbmcgZGV2aWNlLCBzdGFydGluZyBhIG5ldyBlbXVsYXRvci4uLmApO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlQXZkRXhpc3RzKGF2ZE5hbWUpO1xuICAgIC8qXG4gICAgICogU25hcHNob3QgdGhlIGVtdWxhdG9yIHByb2Nlc3NlcyB0aGF0IHByZWRhdGUgdGhpcyBsYXVuY2gsIHNvIHRoZSBvbmVzIHRoYXRcbiAgICAgKiBhcHBlYXIgYWNyb3NzIGl0IGNhbiBiZSBpZGVudGlmaWVkIGFzIE9VUlMuIFRoZSBsYXVuY2hlcidzIFBJRCBpcyBub3RcbiAgICAgKiBlbm91Z2ggdG8ga2lsbDogdW5kZXIgYC1uby13aW5kb3dgIHRoZSBwcm9jZXNzIHRoYXQgaG9sZHMgdGhlIEFWRCBpcyB0aGVcbiAgICAgKiBgcWVtdS1zeXN0ZW0tKi1oZWFkbGVzc2AgYmFja2VuZCBpdCBmb3Jrcywgd2hpY2ggc3Vydml2ZXMgYSBgdGFza2tpbGwgL1RgXG4gICAgICogb2YgdGhlIGxhdW5jaGVyIChzZWUgYGVtdWxhdG9yLWJhY2tlbmQudHNgKS4gRGlmZmluZyBoZXJlIFx1MjAxNCByYXRoZXIgdGhhblxuICAgICAqIHN3ZWVwaW5nIGBxZW11KmAgYXQgdGVhcmRvd24gXHUyMDE0IGlzIHdoYXQga2VlcHMgdGhlIGhhcm5lc3MgZnJvbSBraWxsaW5nXG4gICAgICogc29tZWJvZHkgZWxzZSdzIGVtdWxhdG9yLlxuICAgICAqL1xuICAgIGNvbnN0IGVtdWxhdG9yUGlkc0JlZm9yZSA9IGF3YWl0IHRoaXMubGlzdEVtdWxhdG9yQmFja2VuZFBpZHMoW10pO1xuICAgIGNvbnN0IHNob3VsZFJldXNlU25hcHNob3QgPSBwYXJhbXMuc2hvdWxkUmV1c2VFbXVsYXRvclNuYXBzaG90ID09PSB0cnVlO1xuICAgIGlmIChzaG91bGRSZXVzZVNuYXBzaG90KSB7XG4gICAgICB0aGlzLmxvZ1NuYXBzaG90QWdlKGF2ZE5hbWUpO1xuICAgIH1cbiAgICBjb25zdCBsYXVuY2hlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGVtdWxhdG9yID0gdGhpcy5zdGFydEVtdWxhdG9yKGF2ZE5hbWUsIHNob3VsZFJldXNlU25hcHNob3QsIGlzRW11bGF0b3JWaXNpYmxlKTtcbiAgICBjb25zdCBpc1JlY29yZGVkRnJvbUxhdW5jaCA9IHRoaXMucmVjb3JkRW11bGF0b3JMYXVuY2goeyBhdmROYW1lLCBlbXVsYXRvciwgbGF1bmNoZWRBdEluTWlsbGlzZWNvbmRzLCBwcmVMYXVuY2hFbXVsYXRvclBpZHM6IGVtdWxhdG9yUGlkc0JlZm9yZSB9KTtcblxuICAgIC8qXG4gICAgICogVGhlIGNhcHR1cmUgaXMgTk9UIHN0b3BwZWQgaGVyZSBhbnkgbW9yZS4gSXQgdXNlZCB0byBiZSwgaW4gYSBgZmluYWxseWBcbiAgICAgKiB0aGUgbW9tZW50IGEgZGV2aWNlIGFwcGVhcmVkIFx1MjAxNCB3aGljaCBmcm96ZSB0aGUgZW11bGF0b3IncyB0ZXN0aW1vbnlcbiAgICAgKiBleGFjdGx5IG9uZSBzdGVwIGJlZm9yZSB0aGUgZmFpbHVyZSB0aGlzIGhhcm5lc3MgY291bGQgbm90IGV4cGxhaW4uIFRoZVxuICAgICAqIGhhbmdpbmctdGhyZWFkIGFuZCBwYWNrZXQtc3RyZWFtZXIgbGluZXMgYXJlIHByaW50ZWQgbGF0ZXIsIHdoaWxlIHRoZSBydW5cbiAgICAgKiBpcyBpbnNpZGUgYGVzdGFibGlzaFNlc3Npb25gLiBUaGUgd2luZG93IG5vdyBjbG9zZXMgdGhlcmUgaW5zdGVhZC5cbiAgICAgKi9cbiAgICBsZXQgYWN0dWFsRGV2aWNlSWQ6IHN0cmluZztcbiAgICB0cnkge1xuICAgICAgYWN0dWFsRGV2aWNlSWQgPSBhd2FpdCB0aGlzLndhaXRGb3JOZXdEZXZpY2UoYXZkTmFtZSwgZGV2aWNlSWRzQmVmb3JlLCBlbXVsYXRvciwgdGltZW91dHMsIChkZXZpY2VJZCkgPT4ge1xuICAgICAgICB0aGlzLnJlY29yZEVtdWxhdG9yTGF1bmNoRGV2aWNlKHsgYXZkTmFtZSwgZGV2aWNlSWQsIGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyB9KTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvKlxuICAgICAgICogVGhpcyBlbXVsYXRvciBpcyBvdXJzIGFuZCB0aGlzIGlzIHRoZSBsYXN0IHBvaW50IGFueXRoaW5nIGhvbGRzIGl0OiBhXG4gICAgICAgKiByZWplY3Rpb24gaGVyZSByZWFjaGVzIHRoZSBjYWxsZXIgd2l0aCBubyBkZXZpY2UgcmVzdWx0LCBzbyBpdHNcbiAgICAgICAqIHRlYXJkb3duIGhhcyBubyBwcm9jZXNzIHRvIHN0b3AuIEEgYm9vdCB0aGF0IGZhaWxlZCBhIHJlYWRpbmVzcyBnYXRlIFx1MjAxNFxuICAgICAgICogdGhlIGlkbGUgd2FpdCwgdGhlIG5ldHdvcmsgd2FpdCBcdTIwMTQgdXNlZCB0byBsZWF2ZSBhIHJ1bm5pbmcgZW11bGF0b3JcbiAgICAgICAqIGJlaGluZCBleGFjdGx5IHRoaXMgd2F5LlxuICAgICAgICovXG4gICAgICBhd2FpdCB0aGlzLnN0b3BFbXVsYXRvckFmdGVyRmFpbGVkU3RhcnQoeyBhdmROYW1lLCBkZXZpY2VJZHNCZWZvcmUsIGVtdWxhdG9yLCBlbXVsYXRvclBpZHNCZWZvcmUgfSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBjb25zdCBvd25lZEVtdWxhdG9yUGlkcyA9IGF3YWl0IHRoaXMubGlzdEVtdWxhdG9yQmFja2VuZFBpZHMoZW11bGF0b3JQaWRzQmVmb3JlKTtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBFbXVsYXRvciBcIiR7YXZkTmFtZX1cIiBzdGFydGVkLCBkZXZpY2UgJHthY3R1YWxEZXZpY2VJZH0gaXMgY29ubmVjdGVkIChvd25lZCBlbXVsYXRvciBQSURzOiBbJHtvd25lZEVtdWxhdG9yUGlkcy5qb2luKCcsICcpfV0pLmBcbiAgICApO1xuICAgIC8qXG4gICAgICogUmVjb3JkZWQgaGVyZSBcdTIwMTQgaW5jbHVkaW5nIHdoZW4gdGhpcyBjb2RlIHJ1bnMgaW4gYSB0ZXN0IHdvcmtlciwgd2hpY2ggaXNcbiAgICAgKiB0aGUgY2FzZSB0aGUgaW4tbWVtb3J5IG93bmVyc2hpcCBsb3N0OiB0aGUgd29ya2VyIGRpZXMgd2l0aG91dCBhXG4gICAgICogdGVhcmRvd24sIGFuZCB0aGUgbWFya2VyIGlzIHdoYXQgbGV0cyB0aGUgcnVuJ3MgZ2xvYmFsIHRlYXJkb3duLCBvciB0aGVcbiAgICAgKiBuZXh0IHJ1biwgZmluZCBhbmQgc3RvcCB3aGF0IGl0IHN0YXJ0ZWQuIFRoaXMgd3JpdGUgY29tcGxldGVzIHRoZSByZWNvcmRcbiAgICAgKiB0aGUgbGF1bmNoIG9wZW5lZDogc2FtZSBsYXVuY2ggdGltZSwgbm93IHdpdGggdGhlIFFFTVUgYmFja2VuZCB0aGVcbiAgICAgKiBsYXVuY2hlciBmb3JrZWQsIHdoaWNoIGlzIHRoZSBwcm9jZXNzIHRoYXQgYWN0dWFsbHkgaG9sZHMgdGhlIEFWRC5cbiAgICAgKi9cbiAgICB3cml0ZUVtdWxhdG9yTWFya2VyKHsgYXZkTmFtZSwgZGV2aWNlSWQ6IGFjdHVhbERldmljZUlkLCBvd25lZEVtdWxhdG9yUGlkcywgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHM6IGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyB9KTtcbiAgICBpZiAoIWlzUmVjb3JkZWRGcm9tTGF1bmNoKSB7XG4gICAgICAvLyBUaGUgbWFya2VyIGNvdmVycyBhIHJ1biB0aGF0IGVuZHMgb3IgaXMgZm9sbG93ZWQgYnkgYW5vdGhlcjsgdGhlIHJlYXBlciBjb3ZlcnMgb25lIGtpbGxlZCB3aXRoIG5vdGhpbmcgYWZ0ZXIgaXQuXG4gICAgICB0aGlzLmFybUVtdWxhdG9yUmVhcGVyKGF2ZE5hbWUsIGxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyk7XG4gICAgfVxuICAgIGF3YWl0IHRoaXMuc3VwcHJlc3NFcnJvckRpYWxvZ3MoYWN0dWFsRGV2aWNlSWQpO1xuICAgIHJldHVybiB7XG4gICAgICBhY3R1YWxEZXZpY2VJZCxcbiAgICAgIGVtdWxhdG9yQ2FwdHVyZTogeyByZWFkOiBlbXVsYXRvci5yZWFkT3V0cHV0LCBzdG9wOiBlbXVsYXRvci5zdG9wQ2FwdHVyZSB9LFxuICAgICAgZW11bGF0b3JQcm9jZXNzOiBlbXVsYXRvci5wcm9jZXNzLFxuICAgICAgb3duZWRFbXVsYXRvclBpZHNcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVVaWF1dG9tYXRvcjJEcml2ZXJJbnN0YWxsZWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5sb2coYENoZWNraW5nIHdoZXRoZXIgdGhlICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfSBkcml2ZXIgaXMgaW5zdGFsbGVkLi4uYCk7XG4gICAgY29uc3QgZHJpdmVyTGlzdEpzb24gPSBhd2FpdCBleGVjKCducHggLS1uby1pbnN0YWxsIGFwcGl1bSBkcml2ZXIgbGlzdCAtLWluc3RhbGxlZCAtLWpzb24nLCB7XG4gICAgICBpc1F1aWV0OiB0cnVlLFxuICAgICAgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWVcbiAgICB9KTtcblxuICAgIGlmIChjaGVja0lzQXBwaXVtRHJpdmVySW5zdGFsbGVkKHsgZHJpdmVyTGlzdEpzb24sIGRyaXZlck5hbWU6IFVJQVVUT01BVE9SMl9EUklWRVJfTkFNRSB9KSkge1xuICAgICAgdGhpcy5sb2coYFRoZSAke1VJQVVUT01BVE9SMl9EUklWRVJfTkFNRX0gZHJpdmVyIGlzIGluc3RhbGxlZC5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxvZyhgVGhlICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfSBkcml2ZXIgaXMgbm90IGluc3RhbGxlZC4gSW5zdGFsbGluZyB2aWEgXFxgYXBwaXVtIGRyaXZlciBpbnN0YWxsICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfVxcYC4uLmApO1xuICAgIGF3YWl0IGV4ZWMoYG5weCAtLW5vLWluc3RhbGwgYXBwaXVtIGRyaXZlciBpbnN0YWxsICR7VUlBVVRPTUFUT1IyX0RSSVZFUl9OQU1FfWApO1xuICAgIHRoaXMubG9nKGBUaGUgJHtVSUFVVE9NQVRPUjJfRFJJVkVSX05BTUV9IGRyaXZlciBpbnN0YWxsZWQuYCk7XG4gIH1cblxuICAvKipcbiAgICogRXN0YWJsaXNoZXMgdGhlIFdlYkRyaXZlcklPIHNlc3Npb24sIHJlY29nbml6aW5nIHRoZSBvbmUgZmFpbHVyZSB0aGF0IGJsYW1lc1xuICAgKiB0aGUgd3Jvbmcgc3ViamVjdDogYENvdWxkIG5vdCBmaW5kIGEgY29ubmVjdGVkIEFuZHJvaWQgZGV2aWNlYCBmcm9tIGEgc2VydmVyXG4gICAqIHdob3NlIGFkYiBpcyB3ZWRnZWQgd2hpbGUgdGhlIGhvc3QncyBvd24gYWRiIHNlZXMgdGhlIGRldmljZSBmaW5lLlxuICAgKlxuICAgKiBBIHNlcnZlciBhbiBlYXJsaWVyIHJ1biBvZiB0aGlzIGhhcm5lc3Mgc3RhcnRlZCBpcyByZXN0YXJ0ZWQgYW5kIHRoZSBzZXNzaW9uXG4gICAqIHJldHJpZWQgb25jZSBcdTIwMTQgdGhlIGNvbmZpcm1lZCByZW1lZHkuIEEgZm9yZWlnbiBvciB1c2VyLW1hbmFnZWQgc2VydmVyIGlzXG4gICAqIG5ldmVyIGtpbGxlZDsgaXQgaXMgcmVwb3J0ZWQgd2l0aCBhIG1lc3NhZ2UgdGhhdCBuYW1lcyB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHNlc3Npb24gY2FwYWJpbGl0aWVzIHBsdXMgd2hhdCBpcyBrbm93biBhYm91dCB0aGUgc2VydmVyLlxuICAgKiBAcmV0dXJucyBUaGUgc2Vzc2lvbiwgYW5kIHRoZSByZXBsYWNlbWVudCBzZXJ2ZXIgcHJvY2VzcyB3aGVuIG9uZSB3YXMgc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZXN0YWJsaXNoU2Vzc2lvbihwYXJhbXM6IEVzdGFibGlzaFNlc3Npb25QYXJhbXMpOiBQcm9taXNlPEVzdGFibGlzaFNlc3Npb25SZXN1bHQ+IHtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBDb25uZWN0aW5nIHRvIEFwcGl1bSAoZGV2aWNlPSR7cGFyYW1zLmRldmljZUlkfSwgYXBwPSR7cGFyYW1zLmFwcElkfSwgcmV0cnlUaW1lb3V0OiAke1N0cmluZyhwYXJhbXMuc2Vzc2lvbkNvbm5lY3Rpb25SZXRyeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMsIHJldHJpZXM6ICR7U3RyaW5nKEFQUElVTV9DT05ORUNUSU9OX1JFVFJZX0NPVU5UKX0pLi4uYFxuICAgICk7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgYnJvd3NlcjogYXdhaXQgdGhpcy5jb25uZWN0U2Vzc2lvbihwYXJhbXMpIH07XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGNvbnN0IHZlcmRpY3QgPSByZXNvbHZlV2VkZ2VkQXBwaXVtU2VydmVyUmVtZWR5KHtcbiAgICAgICAgY29ubmVjdGVkRGV2aWNlSWRzOiBhd2FpdCB0aGlzLmdldENvbm5lY3RlZERldmljZUlkc1F1aWV0bHkoKSxcbiAgICAgICAgZGV2aWNlSWQ6IHBhcmFtcy5kZXZpY2VJZCxcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGlzQWRvcHRlZFNlcnZlcjogcGFyYW1zLmlzQWRvcHRlZFNlcnZlcixcbiAgICAgICAgaXNBdXRvU3RhcnRBbGxvd2VkOiBwYXJhbXMuc2hvdWxkQXV0b1N0YXJ0QXBwaXVtICE9PSBmYWxzZSxcbiAgICAgICAgaXNIYXJuZXNzT3duZWRTZXJ2ZXI6IGNoZWNrSXNIYXJuZXNzT3duZWRBcHBpdW1TZXJ2ZXIocGFyYW1zLmFwcGl1bVNlcnZlck1hcmtlcilcbiAgICAgIH0pO1xuXG4gICAgICBpZiAodmVyZGljdC5yZW1lZHkgPT09ICdub3Qtd2VkZ2VkJykge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgaWYgKHZlcmRpY3QucmVtZWR5ID09PSAncmVwb3J0Jykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5idWlsZFdlZGdlZE1lc3NhZ2UocGFyYW1zLCB2ZXJkaWN0LnJlYXNvbiksIHsgY2F1c2U6IGVycm9yIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZXN0YXJ0V2VkZ2VkU2VydmVyQW5kUmV0cnkocGFyYW1zLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVzdGFibGlzaGVzIHRoZSBzZXNzaW9uLCBhbmQgd2hlbiB0aGF0IGZhaWxzLCBhc2tzIHRoZSBkZXZpY2Ugd2hldGhlciBpdCBpc1xuICAgKiBzdGlsbCB0aGVyZSBiZWZvcmUgbGV0dGluZyB0aGUgZmFpbHVyZSBzdGFuZC5cbiAgICpcbiAgICogYGVzdGFibGlzaFNlc3Npb25gIG93bnMgZXhhY3RseSBvbmUgZGlhZ25vc2lzIFx1MjAxNCB0aGUgc3RhbGUgQXBwaXVtIHNlcnZlciBcdTIwMTRcbiAgICogYW5kIHJldGhyb3dzIGV2ZXJ5dGhpbmcgZWxzZSB1bnRvdWNoZWQuIFRoYXQgaXMgcmlnaHQgYXMgZmFyIGFzIGl0IGdvZXMsIGJ1dFxuICAgKiBldmVyeSBzaWduYXR1cmUgdGhpcyBoYXJuZXNzIGFjdHVhbGx5IGZhaWxzIHdpdGggb24gYSB3ZWRnZWQgZW11bGF0b3IgZmFsbHNcbiAgICogaW50byBcImV2ZXJ5dGhpbmcgZWxzZVwiOiBgRGV2aWNlIDxpZD4gd2FzIG5vdCBpbiB0aGUgbGlzdCBvZiBjb25uZWN0ZWRcbiAgICogZGV2aWNlc2AsIGBlcnJvcjogY2xvc2VkYCwgYW5kIGEgYmFyZSBgUE9TVCAvc2Vzc2lvbmAgdGltZW91dC4gUmF0aGVyIHRoYW5cbiAgICogdGVhY2hpbmcgdGhlIHNlcnZlciBtb2R1bGUgdG8gcmVjb2duaXplIGVycm9yIHN0cmluZ3MgdGhhdCBhcmUgbm90IGFib3V0IHRoZVxuICAgKiBzZXJ2ZXIsIHRoZSBkZXZpY2UgaXMgc2ltcGx5IHJlLXByb2JlZCBoZXJlLCB3aGVyZSB0aGUgZGV2aWNlIGlzIGtub3duLiBBXG4gICAqIHdlZGdlZCBlbXVsYXRvciB0aGVuIHJlcG9ydHMgaXRzZWxmLCBhbmQgdGhlIG9yaWdpbmFsIGVycm9yIGlzIGtlcHQgYXMgdGhlXG4gICAqIGBjYXVzZWAuXG4gICAqXG4gICAqIEBwYXJhbSBlbXVsYXRvckNhcHR1cmUgLSBUaGUgZW11bGF0b3IncyBvdXRwdXQsIHdoZW4gdGhpcyBydW4gc3RhcnRlZCBpdC5cbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzZXNzaW9uIHBhcmFtZXRlcnMuXG4gICAqIEByZXR1cm5zIFRoZSBlc3RhYmxpc2hlZCBzZXNzaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlc3RhYmxpc2hTZXNzaW9uT3JEaWFnbm9zZURldmljZShcbiAgICBlbXVsYXRvckNhcHR1cmU6IEVtdWxhdG9yQ2FwdHVyZSB8IHVuZGVmaW5lZCxcbiAgICBwYXJhbXM6IEVzdGFibGlzaFNlc3Npb25QYXJhbXNcbiAgKTogUHJvbWlzZTxFc3RhYmxpc2hTZXNzaW9uUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmVzdGFibGlzaFNlc3Npb24ocGFyYW1zKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgY29uc3QgZGlhZ25vc2lzID0gYXdhaXQgdGhpcy5kaWFnbm9zZURldmljZShwYXJhbXMuZGV2aWNlSWQsIGVtdWxhdG9yQ2FwdHVyZSk7XG4gICAgICBpZiAoZGlhZ25vc2lzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihkaWFnbm9zaXMsIHsgY2F1c2U6IGVycm9yIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0Q29ubmVjdGVkRGV2aWNlSWRzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gbGlzdE9ubGluZURldmljZUlkcyhhd2FpdCB0aGlzLmVtdWxhdG9ycy5nZXREZXZpY2VzT3V0cHV0KCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIHRoZSBob3N0J3MgY29ubmVjdGVkIGRldmljZXMgZm9yIHRoZSB3ZWRnZWQtc2VydmVyIGNyb3NzLWNoZWNrLCB3aGVyZVxuICAgKiBhbiBhZGIgdGhhdCBpdHNlbGYgZmFpbHMgbXVzdCBub3QgYmUgcmVhZCBhcyBldmlkZW5jZSBhZ2FpbnN0IHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBjb25uZWN0ZWQgZGV2aWNlIElEcywgb3IgYW4gZW1wdHkgbGlzdCB3aGVuIGFkYiBjb3VsZCBub3QgYmUgcnVuLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRDb25uZWN0ZWREZXZpY2VJZHNRdWlldGx5KCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkRGV2aWNlSWRzKCk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIHRoaXMubG9nKGBDb3VsZCBub3QgcmUtY2hlY2sgY29ubmVjdGVkIGRldmljZXM6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGV2aWNlUHJvcGVydHkoZGV2aWNlSWQ6IHN0cmluZywgcHJvcGVydHk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgJ2FkYicsXG4gICAgICAgIFsnLXMnLCBkZXZpY2VJZCwgJ3NoZWxsJywgJ2dldHByb3AnLCBwcm9wZXJ0eV0sXG4gICAgICAgIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LFxuICAgICAgICAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgICAgIC8vIFJldHVybiBubyBvdXRwdXQgb24gdGltZW91dC9lcnJvciAobm90IHBhcnRpYWwgc3Rkb3V0KSBzbyBhIG5vbi1yZXNwb25zaXZlIGd1ZXN0IHJlYWRzIGFzIFwibm90IGlkbGVcIi5cbiAgICAgICAgICByZXNvbHZlKGVycm9yID8gJycgOiBzdGRvdXQpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIHRoZSBlbXVsYXRvciBwcm9jZXNzZXMgY3VycmVudGx5IHJ1bm5pbmcgb24gdGhlIGhvc3QsIGV4Y2x1ZGluZyBhIHNldFxuICAgKiB0aGF0IGlzIGFscmVhZHkgYWNjb3VudGVkIGZvci5cbiAgICpcbiAgICogQ2FsbGVkIHR3aWNlIGFyb3VuZCBhIGxhdW5jaDogd2l0aCBhbiBlbXB0eSBga25vd25QaWRzYCB0byBzbmFwc2hvdCB3aGF0XG4gICAqIHByZWRhdGVzIGl0LCB0aGVuIHdpdGggdGhhdCBzbmFwc2hvdCB0byBuYW1lIHdoYXQgdGhlIGxhdW5jaCBhZGRlZCBcdTIwMTQgd2hpY2hcbiAgICogaXMgcHJlY2lzZWx5IHRoZSBzZXQgdGhpcyBydW4gb3ducy5cbiAgICpcbiAgICogQmVzdC1lZmZvcnQ6IGEgbGlzdGluZyB0aGF0IGNhbm5vdCBiZSBwcm9kdWNlZCB5aWVsZHMgbm8gUElEcywgc28gYW5cbiAgICogdW5hdmFpbGFibGUgYHRhc2tsaXN0YC9gcHNgIGRlZ3JhZGVzIHRvIFwibm90aGluZyB0byBlc2NhbGF0ZSB0b1wiIHJhdGhlciB0aGFuXG4gICAqIGZhaWxpbmcgdGhlIHJ1biBpdCBpcyBjbGVhbmluZyB1cCBmb3IuICoqSXQgc2F5cyBzbywgbG91ZGx5KiogXHUyMDE0IGFuIGVtcHR5IHNldFxuICAgKiB0aGF0IG1lYW5zIFwibm8gYmFja2VuZCB0byBvd25cIiBhbmQgb25lIHRoYXQgbWVhbnMgXCJ0aGUgcXVlcnkgZmFpbGVkXCIgYXJlXG4gICAqIG90aGVyd2lzZSB0aGUgc2FtZSBsb2cgbGluZSwgYW5kIHRoZSBzZWNvbmQgc2lsZW50bHkgZGlzYXJtcyB0aGUgZXNjYWxhdGlvbi5cbiAgICpcbiAgICogVGhhdCBpcyBub3QgaHlwb3RoZXRpY2FsLCBhbmQgaXQgaGFzIG5vdyBoYXBwZW5lZCB0d2ljZSBmb3IgdGhlIHNhbWUgcmVhc29uOlxuICAgKiB0aGUgYnVkZ2V0IHdhcyBhIGd1ZXNzLiBUaGUgZmlyc3QgZW5kLXRvLWVuZCBydW4gb2YgdGhpcyBjb2RlIGxvZ2dlZFxuICAgKiBgb3duZWQgZW11bGF0b3IgUElEczogW11gIGZvciBhIGxhdW5jaCB3aG9zZSBiYWNrZW5kIHdhcyBkZW1vbnN0cmFibHkgdGhlcmUsXG4gICAqIGJlY2F1c2UgYHRhc2tsaXN0YCBvdmVycmFuIGEgKioxMHMqKiBidWRnZXQgb24gYSBob3N0IHRoZSB3ZWRnZWQgZW11bGF0b3IgaGFkXG4gICAqIGFscmVhZHkgc2xvd2VkIHRvIHRoZSBwb2ludCB3aGVyZSBldmVyeSBgYWRiYCBjYWxsIHdhcyB0aW1pbmcgb3V0IHRvbyBcdTIwMTQgdGhlXG4gICAqIHNhbWUgY29udGVudGlvbiAqKkw0NSoqIHNpemVzIGBBREJfRFVNUFNZU19USU1FT1VUX0lOX01JTExJU0VDT05EU2AgZm9yLiBJdHNcbiAgICogcmVwbGFjZW1lbnQsIDMwcywgdGhlbiBkaWQgdGhlIHNhbWUgdGhpbmcgb24gKipldmVyeSoqIEFuZHJvaWQgcnVuIGZyb20gb25lXG4gICAqIGhvc3QuIGBIT1NUX1BST0NFU1NfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNgIGNhcnJpZXMgdGhlIG1lYXN1cmVtZW50XG4gICAqIHRoYXQgcmVwbGFjZWQgdGhlIGd1ZXNzaW5nLCBhbmQgYGhvc3QtcHJvY2Vzcy1xdWVyeS12ZXJkaWN0LnRzYCBjYXJyaWVzIHRoZVxuICAgKiByZXBvcnRpbmcgdGhhdCBtYWtlcyB0aGUgbmV4dCBvdmVycnVuIHNheSB3aGljaCBmYWlsdXJlIGl0IHdhcyBpbnN0ZWFkIG9mXG4gICAqIHByaW50aW5nIGEgYmFyZSBgQ29tbWFuZCBmYWlsZWQ6YCB3aXRoIG5vdGhpbmcgYWZ0ZXIgaXQuXG4gICAqXG4gICAqIEEgaG9zdCBhbHdheXMgaGFzIHByb2Nlc3Nlcywgc28gYSBsaXN0aW5nIHRoYXQgcGFyc2VzIHRvICoqemVybyoqIHJvd3MgaXMgYVxuICAgKiBmYWlsZWQgcXVlcnkgaG93ZXZlciBpdCBleGl0ZWQsIGFuZCBpcyByZXBvcnRlZCBsaWtlIG9uZS5cbiAgICpcbiAgICogQHBhcmFtIGtub3duUGlkcyAtIEVtdWxhdG9yIFBJRHMgdG8gZXhjbHVkZS5cbiAgICogQHJldHVybnMgVGhlIGVtdWxhdG9yIFBJRHMgbm90IGluIGBrbm93blBpZHNgLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsaXN0RW11bGF0b3JCYWNrZW5kUGlkcyhrbm93blBpZHM6IHJlYWRvbmx5IG51bWJlcltdKTogUHJvbWlzZTxudW1iZXJbXT4ge1xuICAgIGNvbnN0IHByb2Nlc3NlcyA9IGF3YWl0IHRoaXMuZW11bGF0b3JzLnF1ZXJ5RW11bGF0b3JQcm9jZXNzZXMoKTtcbiAgICBpZiAocHJvY2Vzc2VzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nKFxuICAgICAgICAnV2FybmluZzogdGhlIGhvc3QgcHJvY2VzcyBsaXN0aW5nIGZhaWxlZCwgc28gdGhpcyBydW4gY2Fubm90IGlkZW50aWZ5IHRoZSBlbXVsYXRvciBiYWNrZW5kIGl0IG93bnMuIFRlYXJkb3duIHdpbGwgZmFsbCBiYWNrIHRvIGBhZGIgZGV2aWNlc2AgYWxvbmUgYW5kIHdpbGwgaGF2ZSBubyBQSUQgdG8gZXNjYWxhdGUgdG8uJ1xuICAgICAgKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZWN0RW11bGF0b3JCYWNrZW5kUGlkcyh7IGtub3duUGlkcywgcHJvY2Vzc2VzIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBsaXN0SW5zdGFsbGVkUGFja2FnZXMoZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgJ2FkYicsXG4gICAgICAgIFsnLXMnLCBkZXZpY2VJZCwgJ3NoZWxsJywgJ2NtZCcsICdwYWNrYWdlJywgJ2xpc3QnLCAncGFja2FnZXMnXSxcbiAgICAgICAgeyB0aW1lb3V0OiBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sXG4gICAgICAgIChlcnJvciwgc3Rkb3V0KSA9PiB7XG4gICAgICAgICAgLy8gUmV0dXJuIG5vIG91dHB1dCBvbiB0aW1lb3V0L2Vycm9yIHNvIGEgY2h1cm5pbmcgZ3Vlc3QncyBzbG93L3BhcnRpYWwgcGFja2FnZSBsaXN0IGNhbid0IGZhbHNlbHkgcmVhZCBhcyBpZGxlLlxuICAgICAgICAgIHJlc29sdmUoZXJyb3IgPyAnJyA6IHN0ZG91dCk7XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgdGhlIHByb2Nlc3NlcyBzdGlsbCBsaXN0ZW5pbmcgb24gYSBwb3J0LlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBvbmx5IHJlYWwgZXNjYWxhdGlvbiBhdmFpbGFibGUgZm9yIHRoZSBBcHBpdW0gc2VydmVyOiB0aGUgUElEXG4gICAqIHRoZSBoYXJuZXNzIGhvbGRzIGlzIHRoZSBzaGVsbCB3cmFwcGVyIGl0IHNwYXduZWQsIHNvIHJlLWtpbGxpbmcgaXQgYWNoaWV2ZXNcbiAgICogbm90aGluZywgd2hpbGUgYSBzb2NrZXQgc3RpbGwgYW5zd2VyaW5nIG9uIHRoZSBwb3J0IGlzIGRpcmVjdCBldmlkZW5jZSBvZlxuICAgKiB3aGF0IHN1cnZpdmVkLlxuICAgKlxuICAgKiBBIHF1ZXJ5IHRoYXQgZmFpbGVkIHN0aWxsIHlpZWxkcyBhbiBlbXB0eSBsaXN0IFx1MjAxNCB0aGUgZXNjYWxhdGlvbiBpc1xuICAgKiBiZXN0LWVmZm9ydCBcdTIwMTQgYnV0IGl0IGlzIG5ldmVyIHNpbGVudDogYGxzb2ZgJ3Mgb3duIFwibm90aGluZyBob2xkcyB0aGUgcG9ydFwiXG4gICAqIGlzIGFuIGFuc3dlciwgd2hpbGUgYSB0aW1lb3V0IG9yIGEgY3Jhc2ggaXMgbG9nZ2VkIGJ5IG5hbWUsIGJlY2F1c2UgYW5cbiAgICogZW1wdHkgbGlzdCBmcm9tIGVpdGhlciBkaXNhcm1zIHRoZSBlc2NhbGF0aW9uIHdpdGhvdXQgc2F5aW5nIHNvLlxuICAgKlxuICAgKiBAcGFyYW0gcG9ydCAtIFRoZSBwb3J0IHRvIHF1ZXJ5LlxuICAgKiBAcmV0dXJucyBUaGUgbGlzdGVuaW5nIFBJRHMsIG9yIGFuIGVtcHR5IGxpc3Qgd2hlbiBub3RoaW5nIGhvbGRzIHRoZSBwb3J0IG9yIHRoZSBxdWVyeSBmYWlsZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxpc3RQb3J0T3duZXJQaWRzKHBvcnQ6IG51bWJlcik6IFByb21pc2U8bnVtYmVyW10+IHtcbiAgICBjb25zdCBxdWVyeSA9IGJ1aWxkUG9ydE93bmVyUXVlcnkocG9ydCk7XG4gICAgY29uc3Qgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG5ldyBQcm9taXNlPEhvc3RQcm9jZXNzUXVlcnlSZXN1bHQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgcXVlcnkuY29tbWFuZCxcbiAgICAgICAgcXVlcnkuY29tbWFuZEFyZ3VtZW50cyxcbiAgICAgICAgeyBtYXhCdWZmZXI6IEFEQl9EVU1QU1lTX01BWF9CVUZGRVJfSU5fQllURVMsIHRpbWVvdXQ6IFBPUlRfT1dORVJfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSxcbiAgICAgICAgKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICAgIHJlc29sdmUoeyBlcnJvciwgc3RhbmRhcmRFcnJvcjogc3RkZXJyLCBzdGFuZGFyZE91dHB1dDogc3Rkb3V0IH0pO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0Y29tZSA9IHJlc29sdmVQb3J0T3duZXJRdWVyeU91dGNvbWUoe1xuICAgICAgZXJyb3JDb2RlOiByZXN1bHQuZXJyb3I/LmNvZGUgPz8gbnVsbCxcbiAgICAgIGhhc0ZhaWxlZDogcmVzdWx0LmVycm9yICE9PSBudWxsLFxuICAgICAgaXNLaWxsZWQ6IHJlc3VsdC5lcnJvcj8ua2lsbGVkID8/IGZhbHNlLFxuICAgICAgcGxhdGZvcm06IHByb2Nlc3MucGxhdGZvcm0sXG4gICAgICBzdGFuZGFyZEVycm9yOiByZXN1bHQuc3RhbmRhcmRFcnJvcixcbiAgICAgIHN0YW5kYXJkT3V0cHV0OiByZXN1bHQuc3RhbmRhcmRPdXRwdXRcbiAgICB9KTtcbiAgICB0aGlzLmxvZ1BvcnRPd25lclF1ZXJ5RmFpbHVyZSh7XG4gICAgICBjb21tYW5kOiBbcXVlcnkuY29tbWFuZCwgLi4ucXVlcnkuY29tbWFuZEFyZ3VtZW50c10uam9pbignICcpLFxuICAgICAgZWxhcHNlZEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMsXG4gICAgICBleGl0Q29kZTogdHlwZW9mIHJlc3VsdC5lcnJvcj8uY29kZSA9PT0gJ251bWJlcicgPyByZXN1bHQuZXJyb3IuY29kZSA6IG51bGwsXG4gICAgICBvdXRjb21lLFxuICAgICAgcG9ydCxcbiAgICAgIHNpZ25hbDogcmVzdWx0LmVycm9yPy5zaWduYWwgPz8gbnVsbCxcbiAgICAgIHN0YW5kYXJkRXJyb3I6IHJlc3VsdC5zdGFuZGFyZEVycm9yLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBQT1JUX09XTkVSX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gICAgfSk7XG5cbiAgICAvLyBUaGUgb25seSBmYWlsZWQgY2FsbCB0aGF0IHN0aWxsIGFuc3dlcmVkIGlzIGBsc29mYCdzIHNpbGVudCBcIm5vdGhpbmcgaG9sZHMgdGhlIHBvcnRcIiwgd2hpY2ggaGFzIG5vIFBJRHMgdG8gcGFyc2UuXG4gICAgcmV0dXJuIHJlc3VsdC5lcnJvciA9PT0gbnVsbCA/IHBhcnNlUG9ydE93bmVyUGlkcyh7IG91dHB1dDogcmVzdWx0LnN0YW5kYXJkT3V0cHV0LCBwb3J0IH0pIDogW107XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25vdXMge0BsaW5rIGxpc3RQb3J0T3duZXJQaWRzfSwgZm9yIHRoZSBgcHJvY2Vzcy5vbignZXhpdCcpYCB0ZWFyZG93blxuICAgKiB0aGF0IGNhbm5vdCBhd2FpdC5cbiAgICpcbiAgICogSXRzIGJ1ZGdldCBpcyBkZWxpYmVyYXRlbHkgKipub3QqKiB0aGUgYXN5bmMgcGF0aCdzOiB0aGlzIGNhbGwgYmxvY2tzIHByb2Nlc3NcbiAgICogZXhpdCBvdXRyaWdodCwgc28gaXQgdGFrZXMgYSBzaG9ydCBvbmUgYW5kIGdpdmVzIHVwIHJhdGhlciB0aGFuIGhvbGRpbmcgdGhlXG4gICAqIGV4aXQgaGFuZGxlciBmb3IgaGFsZiBhIG1pbnV0ZSBvbiBhIGNvbnRlbmRlZCBob3N0LiBHaXZpbmcgdXAgbG9zZXMgdGhlXG4gICAqIGVzY2FsYXRpb24sIHdoaWNoIHRoZSBzeW5jIHBhdGgncyBsb2cgYWxyZWFkeSBhZG1pdHMgaXQgY2Fubm90IGNvbmZpcm0uXG4gICAqXG4gICAqIEEgZmFpbHVyZSBpcyBjbGFzc2lmaWVkIGFuZCBsb2dnZWQgdGhlIHNhbWUgd2F5IGFzIHRoZSBhc3luYyBwYXRoJ3MuXG4gICAqXG4gICAqIEBwYXJhbSBwb3J0IC0gVGhlIHBvcnQgdG8gcXVlcnkuXG4gICAqIEByZXR1cm5zIFRoZSBsaXN0ZW5pbmcgUElEcywgb3IgYW4gZW1wdHkgbGlzdCB3aGVuIG5vdGhpbmcgaG9sZHMgdGhlIHBvcnQgb3IgdGhlIHF1ZXJ5IGZhaWxlZC5cbiAgICovXG4gIHByaXZhdGUgbGlzdFBvcnRPd25lclBpZHNTeW5jKHBvcnQ6IG51bWJlcik6IG51bWJlcltdIHtcbiAgICBjb25zdCBxdWVyeSA9IGJ1aWxkUG9ydE93bmVyUXVlcnkocG9ydCk7XG4gICAgY29uc3Qgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBvdXRwdXQgPSBleGVjRmlsZVN5bmMocXVlcnkuY29tbWFuZCwgcXVlcnkuY29tbWFuZEFyZ3VtZW50cywge1xuICAgICAgICBlbmNvZGluZzogJ3V0Zi04JyxcbiAgICAgICAgbWF4QnVmZmVyOiBBREJfRFVNUFNZU19NQVhfQlVGRkVSX0lOX0JZVEVTLFxuICAgICAgICB0aW1lb3V0OiBTWU5DX1RFQVJET1dOX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwYXJzZVBvcnRPd25lclBpZHMoeyBvdXRwdXQsIHBvcnQgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGZhaWx1cmUgPSBub3JtYWxpemVTeW5jRXhlY0Vycm9yKGVycm9yKTtcbiAgICAgIHRoaXMubG9nUG9ydE93bmVyUXVlcnlGYWlsdXJlKHtcbiAgICAgICAgY29tbWFuZDogW3F1ZXJ5LmNvbW1hbmQsIC4uLnF1ZXJ5LmNvbW1hbmRBcmd1bWVudHNdLmpvaW4oJyAnKSxcbiAgICAgICAgZWxhcHNlZEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMsXG4gICAgICAgIGV4aXRDb2RlOiBmYWlsdXJlLmV4aXRDb2RlLFxuICAgICAgICBvdXRjb21lOiByZXNvbHZlUG9ydE93bmVyUXVlcnlPdXRjb21lKHsgLi4uZmFpbHVyZSwgaGFzRmFpbGVkOiB0cnVlLCBwbGF0Zm9ybTogcHJvY2Vzcy5wbGF0Zm9ybSB9KSxcbiAgICAgICAgcG9ydCxcbiAgICAgICAgc2lnbmFsOiBmYWlsdXJlLnNpZ25hbCxcbiAgICAgICAgc3RhbmRhcmRFcnJvcjogZmFpbHVyZS5zdGFuZGFyZEVycm9yLFxuICAgICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IFNZTkNfVEVBUkRPV05fUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9nKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIGxvZyhgW3RyYW5zcG9ydC1mYWN0b3J5OiR7dGhpcy50eXBlfV0gJHttZXNzYWdlfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIExvZ3MgdGhlIHBvcnQtb3duZXIgcXVlcnkncyBmYWlsdXJlLCBpZiBpdCBmYWlsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgb3V0Y29tZSBhbmQgd2hhdCB0aGUgY2hpbGQgbGVmdCBiZWhpbmQuXG4gICAqL1xuICBwcml2YXRlIGxvZ1BvcnRPd25lclF1ZXJ5RmFpbHVyZShwYXJhbXM6IEJ1aWxkUG9ydE93bmVyUXVlcnlNZXNzYWdlUGFyYW1zKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGJ1aWxkUG9ydE93bmVyUXVlcnlNZXNzYWdlKHBhcmFtcyk7XG4gICAgaWYgKG1lc3NhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cobWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvZ3MgaG93IG9sZCB0aGUgc25hcHNob3QgYSBydW4gaGFzIG9wdGVkIGludG8gcmVzdW1pbmcgaXMuXG4gICAqXG4gICAqIEJlc3QtZWZmb3J0OiBhIG1pc3Npbmcgc25hcHNob3QgaXMgdGhlIG5vcm1hbCBzdGF0ZSBvZiBhIGZyZXNoIEFWRCwgbm90IGFcbiAgICogZmFpbHVyZSwgYW5kIHRoaXMgaXMgYSBkaWFnbm9zdGljIHJhdGhlciB0aGFuIGEgZ2F0ZS5cbiAgICpcbiAgICogQHBhcmFtIGF2ZE5hbWUgLSBUaGUgQVZEIHdob3NlIHNuYXBzaG90IGlzIGFib3V0IHRvIGJlIHJlc3VtZWQuXG4gICAqL1xuICBwcml2YXRlIGxvZ1NuYXBzaG90QWdlKGF2ZE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGxldCBzYXZlZEF0OiBEYXRlIHwgdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgYnVpbGRBdmRTbmFwc2hvdERpcmVjdG9yeUNhbmRpZGF0ZXMoeyBhdmROYW1lLCBlbnZpcm9ubWVudDogcHJvY2Vzcy5lbnYsIGhvbWVEaXJlY3Rvcnk6IGhvbWVkaXIoKSB9KSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2F2ZWRBdCA9IHN0YXRTeW5jKGNhbmRpZGF0ZSkubXRpbWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIE5vdCB0aGlzIEFWRCBob21lIFx1MjAxNCB0cnkgdGhlIG5leHQgY2FuZGlkYXRlLlxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubG9nKGJ1aWxkU25hcHNob3RBZ2VNZXNzYWdlKHsgYXZkTmFtZSwgc2F2ZWRBdCB9KSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgb25lIGVtdWxhdG9yJ3MgQVZEIG5hbWUsIG92ZXIgdGhlIGd1ZXN0IHByb3BlcnR5IGZpcnN0IGFuZCBpdHNcbiAgICogY29uc29sZSBvbmx5IGFzIGEgZmFsbGJhY2ssIHJldHJ5aW5nIHRoZSB3aG9sZSBzZXF1ZW5jZSBvbmNlLlxuICAgKlxuICAgKiBUaGUgcmV0cnkgaXMgd2hhdCBtYWtlcyB0aGUgcmVmdXNhbCBwcm9wb3J0aW9uYXRlOiBlYWNoIGF0dGVtcHQncyBidWRnZXQgaXNcbiAgICogNXMsIGFuZCBhIHNlY29uZCBsb29rIGNvc3RzIGxlc3MgdGhhbiBhIGNvbGxpZGluZyBsYXVuY2ggZG9lcy4gV2hhdCBpdCBtdXN0XG4gICAqIG5ldmVyIGRvIGlzIHJlcG9ydCBhIG5vbi1hbnN3ZXIgYXMgYW4gYW5zd2VyIFx1MjAxNCB0aGUgZGlzY2FyZGVkIGBfZXJyb3JgIHRoaXNcbiAgICogcmVwbGFjZXMgcmVzb2x2ZWQgYCcnYCwgd2hpY2ggY29tcGFyZWQgdW5lcXVhbCB0byB0aGUgd2FudGVkIEFWRCBhbmQgc28gcmVhZFxuICAgKiBhcyBhIGRlZmluaXRlIFwic29tZSBvdGhlciBBVkRcIi5cbiAgICpcbiAgICogKipXaGljaCBjaGFubmVsIGl0IGFza3MgaXMgdGhlIG90aGVyIGhhbGYuKiogVGhlIGNvbnNvbGUgaXMgYSBzZXBhcmF0ZSBUQ1BcbiAgICogcG9ydCB0aGF0IHdlZGdlcyBvbiBpdHMgb3duLCBzbyBrZXlpbmcgdGhlIHJlZnVzYWwgb24gaXQgbWFkZSBvbmVcbiAgICogdW5yZXNwb25zaXZlIGVtdWxhdG9yIFx1MjAxNCByb3V0aW5lbHkgYW5vdGhlciBwcm9qZWN0J3MgXHUyMDE0IGJsb2NrIGV2ZXJ5IEFuZHJvaWRcbiAgICogcnVuIG9uIHRoZSBtYWNoaW5lLiBUaGUgcHJvcGVydHkgdHJhdmVscyBgYWRiZGAsIHRoZSBjaGFubmVsIHRoaXMgcnVuIG5lZWRzXG4gICAqIGFueXdheTsgc2VlIGBhdmQtbmFtZS1jaGFubmVsLnRzYC5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGVtdWxhdG9yIHRvIGFzay5cbiAgICogQHJldHVybnMgVGhlIEFWRCBuYW1lIGl0IGFuc3dlcmVkLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vIGNoYW5uZWwgYW5zd2VyZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2JlQXZkTmFtZShkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBwcm9wZXJ0eUNvbW1hbmQgPSBkZXNjcmliZUFkYkNvbW1hbmQoYnVpbGRBdmROYW1lQ2hhbm5lbEFyZ3VtZW50cyh7IGNoYW5uZWw6IEZJUlNUX0FWRF9OQU1FX0NIQU5ORUwsIGRldmljZUlkIH0pKTtcbiAgICBjb25zdCBjb25zb2xlQ29tbWFuZCA9IGRlc2NyaWJlQWRiQ29tbWFuZChidWlsZEF2ZE5hbWVDaGFubmVsQXJndW1lbnRzKHsgY2hhbm5lbDogJ2NvbnNvbGUnLCBkZXZpY2VJZCB9KSk7XG5cbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBBVkRfUFJPQkVfQVRURU1QVF9DT1VOVDsgYXR0ZW1wdCsrKSB7XG4gICAgICBsZXQgY2hhbm5lbDogQXZkTmFtZUNoYW5uZWwgfCB1bmRlZmluZWQgPSBGSVJTVF9BVkRfTkFNRV9DSEFOTkVMO1xuXG4gICAgICB3aGlsZSAoY2hhbm5lbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IGFuc3dlciA9IGF3YWl0IHRoaXMuYXNrRGV2aWNlRm9yQXZkTmFtZShkZXZpY2VJZCwgY2hhbm5lbCk7XG5cbiAgICAgICAgaWYgKGFuc3dlci5yZXBvcnRlZEF2ZE5hbWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGlmIChjaGFubmVsICE9PSBGSVJTVF9BVkRfTkFNRV9DSEFOTkVMKSB7XG4gICAgICAgICAgICB0aGlzLmxvZyhgRGV2aWNlICR7ZGV2aWNlSWR9IGFuc3dlcmVkIFxcYCR7ZGVzY3JpYmVBZGJDb21tYW5kKGJ1aWxkQXZkTmFtZUNoYW5uZWxBcmd1bWVudHMoeyBjaGFubmVsLCBkZXZpY2VJZCB9KSl9XFxgLmApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBhbnN3ZXIucmVwb3J0ZWRBdmROYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hhbm5lbCA9IHJlc29sdmVOZXh0QXZkTmFtZUNoYW5uZWwoeyBjaGFubmVsLCBkaWRDaGFubmVsUmVzcG9uZDogYW5zd2VyLmRpZFJlc3BvbmQgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhdHRlbXB0IDwgQVZEX1BST0JFX0FUVEVNUFRfQ09VTlQpIHtcbiAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgYERldmljZSAke2RldmljZUlkfSBpZGVudGlmaWVkIGl0c2VsZiBvdmVyIG5laXRoZXIgXFxgJHtwcm9wZXJ0eUNvbW1hbmR9XFxgIG5vciBcXGAke2NvbnNvbGVDb21tYW5kfVxcYCBgXG4gICAgICAgICAgICArIGB3aXRoaW4gJHtTdHJpbmcoQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMgZWFjaDsgcmV0cnlpbmcgb25jZS5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc2tzIGV2ZXJ5IGNvbm5lY3RlZCBkZXZpY2Ugd2hpY2ggQVZEIGl0IGlzIHNlcnZpbmcuXG4gICAqXG4gICAqIEEgZGV2aWNlIHRoYXQgaXMgbm90IGEgbG9jYWxseSBzdGFydGVkIGVtdWxhdG9yIGlzIG5ldmVyIGFza2VkOiBpdHMgY29uc29sZVxuICAgKiBjYW5ub3QgYW5zd2VyIGhvd2V2ZXIgaGVhbHRoeSBpdCBpcywgYW5kIHJlYWRpbmcgdGhhdCBhcyBzaWxlbmNlIHdvdWxkXG4gICAqIHJlZnVzZSBldmVyeSBydW4gb24gYSBob3N0IHdpdGggYSBoYW5kc2V0IHBsdWdnZWQgaW4gXHUyMDE0IHNlZVxuICAgKiBgYXZkLXByb2JlLXZlcmRpY3QudHNgLlxuICAgKlxuICAgKiBAcGFyYW0gYXZkTmFtZSAtIFRoZSBBVkQgdGhlIHJ1biB3YW50cy5cbiAgICogQHBhcmFtIGRldmljZUlkcyAtIFRoZSBjb25uZWN0ZWQgZGV2aWNlcy5cbiAgICogQHJldHVybnMgT25lIG91dGNvbWUgcGVyIGRldmljZSwgaW4gbGlzdGVkIG9yZGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9iZURldmljZXNGb3JBdmQoYXZkTmFtZTogc3RyaW5nLCBkZXZpY2VJZHM6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxBdmRQcm9iZVJlc3VsdFtdPiB7XG4gICAgY29uc3QgcmVzdWx0czogQXZkUHJvYmVSZXN1bHRbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBkZXZpY2VJZCBvZiBkZXZpY2VJZHMpIHtcbiAgICAgIGNvbnN0IHByb2JlZEF2ZE5hbWUgPSBjaGVja0lzRW11bGF0b3JEZXZpY2VJZChkZXZpY2VJZCkgPyBhd2FpdCB0aGlzLnByb2JlQXZkTmFtZShkZXZpY2VJZCkgOiB1bmRlZmluZWQ7XG4gICAgICByZXN1bHRzLnB1c2goeyBkZXZpY2VJZCwgb3V0Y29tZTogY2xhc3NpZnlBdmRQcm9iZSh7IGF2ZE5hbWUsIGRldmljZUlkLCBwcm9iZWRBdmROYW1lIH0pIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFza3MgdGhlICoqZ3Vlc3QqKiB3aGV0aGVyIGl0IGlzIHN0aWxsIHNjaGVkdWxpbmcgd29yaywgdmlhIGBhZGJkYC5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSB0byBwcm9iZS5cbiAgICogQHJldHVybnMgV2hhdCBpdCBhbnN3ZXJlZC5cbiAgICovXG4gIHByaXZhdGUgcHJvYmVEZXZpY2VTaGVsbChkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTxFbXVsYXRvckxpdmVuZXNzUHJvYmVPdXRjb21lPiB7XG4gICAgcmV0dXJuIHRoaXMucnVuTGl2ZW5lc3NQcm9iZShbJy1zJywgZGV2aWNlSWQsICdzaGVsbCcsICd0cnVlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFza3MgdGhlICoqZW11bGF0b3IgcHJvY2VzcyoqIHdoZXRoZXIgaXQgaXMgc3RpbGwgcnVubmluZywgdmlhIGl0cyBjb25zb2xlLlxuICAgKlxuICAgKiBUaGUgY29uc29sZSBpcyBzZXJ2ZWQgYnkgdGhlIGVtdWxhdG9yIGl0c2VsZiByYXRoZXIgdGhhbiBieSB0aGUgZ3Vlc3QsIHdoaWNoXG4gICAqIGlzIHdoYXQgbWFrZXMgaXQgYWJsZSB0byB0ZWxsIGEgZnJvemVuIGd1ZXN0IGZyb20gYSB3ZWRnZWQgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgdG8gcHJvYmUuXG4gICAqIEByZXR1cm5zIFdoYXQgaXQgYW5zd2VyZWQuXG4gICAqL1xuICBwcml2YXRlIHByb2JlRW11bGF0b3JDb25zb2xlKGRldmljZUlkOiBzdHJpbmcpOiBQcm9taXNlPEVtdWxhdG9yTGl2ZW5lc3NQcm9iZU91dGNvbWU+IHtcbiAgICByZXR1cm4gdGhpcy5ydW5MaXZlbmVzc1Byb2JlKFsnLXMnLCBkZXZpY2VJZCwgJ2VtdScsICdhdmQnLCAnc3RhdHVzJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGEgbGVmdG92ZXIgc2VydmVyIGFuIGVhcmxpZXIgcnVuIGZhaWxlZCB0byBzdG9wLCBpbnN0ZWFkIG9mXG4gICAqIGFkb3B0aW5nIGl0LlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBvdGhlciBoYWxmIG9mIHtAbGluayBzdG9wQXV0b1N0YXJ0ZWRBcHBpdW1TZXJ2ZXJ9J3Mgc3RhbXBlZFxuICAgKiBtYXJrZXIsIGFuZCBpdCBpcyB0aGUgY2FzZSB0aGF0IG1vdGl2YXRlZCB0aGUgd2hvbGUgdmVyaWZpZWQgdGVhcmRvd246IHRoZVxuICAgKiBsZWZ0b3ZlciBhbnN3ZXJzIGAvc3RhdHVzYCBwZXJmZWN0bHksIGlzIGFkb3B0ZWQsIGFuZCB0aGVuIGRpZXMgc2Vjb25kcyBpbnRvIHRoZSBzZXNzaW9uIGFzXG4gICAqIGl0IGZpbmFsbHkgZmluaXNoZXMgc2h1dHRpbmcgZG93biBcdTIwMTQgYSBmYWlsdXJlIHRoYXQgcmVhZHMgYXMgYSBkZXZpY2Ugb3JcbiAgICogbmV0d29yayBmYXVsdC4gQSBzZXJ2ZXIgd2Uga25vdyB3ZSBhbHJlYWR5IGFza2VkIHRvIGRpZSBpcyBub3QgYSBzZXJ2ZXIgdG9cbiAgICogYnVpbGQgYSBzdWl0ZSBvbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBtYXJrZXIsIHRoZSBwb3J0IGFuZCB3aGV0aGVyIGEgcmVwbGFjZW1lbnQgbWF5IGJlIHN0YXJ0ZWQuXG4gICAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIHRoZSBwb3J0IHdhcyBmcmVlZCBhbmQgYSBmcmVzaCBzZXJ2ZXIgbXVzdCBiZSBzdGFydGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWNsYWltVW5zdG9wcGVkQXBwaXVtU2VydmVyKHBhcmFtczogUmVjbGFpbVVuc3RvcHBlZEFwcGl1bVNlcnZlclBhcmFtcyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHN0b3BBdHRlbXB0ZWRBdEluTWlsbGlzZWNvbmRzID0gcGFyYW1zLm1hcmtlci5zdG9wQXR0ZW1wdGVkQXRJbk1pbGxpc2Vjb25kcyA/PyBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGFnZUluU2Vjb25kcyA9IE1hdGgucm91bmQoKERhdGUubm93KCkgLSBzdG9wQXR0ZW1wdGVkQXRJbk1pbGxpc2Vjb25kcykgLyBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORCk7XG4gICAgY29uc3QgcHJvdmVuYW5jZSA9IGB0aGUgc2VydmVyIG9uIHBvcnQgJHtTdHJpbmcocGFyYW1zLnBvcnQpfSBpcyBhIGxlZnRvdmVyIGFuIGVhcmxpZXIgcnVuIG9mIHRoaXMgaGFybmVzcyB0cmllZCB0byBzdG9wICR7U3RyaW5nKGFnZUluU2Vjb25kcyl9cyBhZ28gYW5kIGNvdWxkIG5vdGA7XG5cbiAgICBpZiAocGFyYW1zLnNob3VsZEF1dG9TdGFydEFwcGl1bSA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMubG9nKGBXQVJOSU5HOiAke3Byb3ZlbmFuY2V9LiBBdXRvLXN0YXJ0IGlzIGRpc2FibGVkLCBzbyB0aGlzIHJ1biBhZG9wdHMgaXQgYW55d2F5OyBpZiB0aGUgc2Vzc2lvbiBkaWVzIG1pZC1mbGlnaHQsIHRoYXQgaXMgd2h5LmApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMubG9nKGBSZWZ1c2luZyB0byBhZG9wdCBhIGtub3duLWRvb21lZCBzZXJ2ZXI6ICR7cHJvdmVuYW5jZX0uIEtpbGxpbmcgd2hhdGV2ZXIgaG9sZHMgdGhlIHBvcnQgYW5kIHN0YXJ0aW5nIGEgZnJlc2ggc2VydmVyLi4uYCk7XG4gICAgZm9yIChjb25zdCBwaWQgb2YgYXdhaXQgdGhpcy5saXN0UG9ydE93bmVyUGlkcyhwYXJhbXMucG9ydCkpIHtcbiAgICAgIGtpbGxQcm9jZXNzVHJlZUJ5UGlkKHBpZCk7XG4gICAgfVxuICAgIGNsZWFyQXBwaXVtU2VydmVyTWFya2VyKHBhcmFtcy5wb3J0KTtcblxuICAgIGlmIChhd2FpdCB0aGlzLmNoZWNrSXNBcHBpdW1TdG9wcGVkKHBhcmFtcy51cmwsIEFQUElVTV9FU0NBTEFURURfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EUykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMubG9nKGBXQVJOSU5HOiAke3Byb3ZlbmFuY2V9LCBhbmQgaXQgc3Vydml2ZWQgdGhpcyBydW4ncyBraWxsIHRvby4gQWRvcHRpbmcgaXQsIHdoaWNoIG1heSBmYWlsIG1pZC1zZXNzaW9uLmApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGFuIGVtdWxhdG9yIGFzIHRoaXMgcnVuJ3MgdGhlIG1vbWVudCBpdCBpcyBsYXVuY2hlZCwgYmVmb3JlIGl0IGhhc1xuICAgKiBhIGRldmljZSBcdTIwMTQgYW5kIGFybXMgaXRzIHJlYXBlciB0aGVyZS5cbiAgICpcbiAgICogVGhlIG1hcmtlciB1c2VkIHRvIGJlIHdyaXR0ZW4gb25jZSB0aGUgZGV2aWNlIGNvbm5lY3RlZCwgYWJvdXQgNDVzIGludG8gYVxuICAgKiBjb2xkIGJvb3QsIGFuZCB0aGUgcmVhcGVyIHdpdGggaXQuIEEgcnVubmVyIGtpbGxlZCBpbnNpZGUgdGhhdCB3aW5kb3cgbGVmdCBhXG4gICAqIHJ1bm5pbmcgZW11bGF0b3Igd2l0aCAqKm5vIG1hcmtlciBhdCBhbGwqKiwgd2hpY2ggZXZlcnkgbGF0ZXIgcnVuIGNvcnJlY3RseVxuICAgKiByZWZ1c2VzIHRvIHRvdWNoICgqKkw0NioqKSBhbmQgbm8gcmVhcGVyIHdhcyB3YXRjaGluZzogdGhlIGxlZnRvdmVyIHdhc1xuICAgKiBub2JvZHkncyB0byBzdG9wLCBmb3IgZXZlci4gQSBsYXVuY2gtdGltZSBtYXJrZXIgY2xvc2VzIHRoYXQgd2luZG93IHdpdGggdGhlXG4gICAqIG9uZSB0aGluZyBhbHJlYWR5IGtub3duIFx1MjAxNCB0aGUgbGF1bmNoZXIncyBQSUQsIHdoaWNoIGBlbXVsYXRvci1iYWNrZW5kLnRzYFxuICAgKiBjb3VudHMgYXMgYW4gZW11bGF0b3IgcHJvY2Vzcywgc28gdGhlIG1hcmtlciBjb252aWN0cyBhcyBhXG4gICAqIGBoYXJuZXNzLWxlZnRvdmVyYCBleGFjdGx5IGxpa2UgYSBjb21wbGV0ZWQgb25lIFx1MjAxNCBwbHVzIHRoZSBwcmUtbGF1bmNoXG4gICAqIHNuYXBzaG90LCB3aGljaCBpcyB3aGF0IGxldHMgYSBsYXRlciByZWNsYWltIGlkZW50aWZ5IHRoZSBiYWNrZW5kIHRoZVxuICAgKiBsYXVuY2hlciBmb3JrcyB3aXRob3V0IGhhdmluZyBiZWVuIHRoZXJlIHRvIHdhdGNoIGl0LlxuICAgKlxuICAgKiAqKkl0IG5ldmVyIG92ZXJ3cml0ZXMgYSBtYXJrZXIgd2hvc2UgcHJvY2Vzc2VzIGFyZSBzdGlsbCBydW5uaW5nLioqIEEgbGF1bmNoXG4gICAqIGNhbiBoYXBwZW4gd2hpbGUgYW4gb2xkZXIgZW11bGF0b3Igb2YgdGhlIHNhbWUgQVZEIGlzIHN0aWxsIHVwIGFuZCByZWNvcmRlZFxuICAgKiBcdTIwMTQgYW4gYG9mZmxpbmVgIGxlZnRvdmVyIHRoZSBwcm9iZSBjYW5ub3Qgc2VlLCB3aGljaCBpcyB0aGUgbGF1bmNoIHRoYXQgZGllc1xuICAgKiBvbiBgUnVubmluZyBtdWx0aXBsZSBlbXVsYXRvcnMgd2l0aCB0aGUgc2FtZSBBVkRgLiBDbG9iYmVyaW5nIHRoYXQgbWFya2VyXG4gICAqIHdvdWxkIGVyYXNlIHRoZSBvbmx5IHJlY29yZCBvZiBhIHJ1bm5pbmcgZW11bGF0b3IsIHRoZSB2ZXJ5IHRoaW5nXG4gICAqIGBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkYCBleGlzdHMgdG8gcHJldmVudC4gSW4gdGhhdCBjYXNlIHRoZSByZWNvcmRcbiAgICogd2FpdHMgZm9yIHRoZSBzdWNjZXNzIHBhdGgsIGFzIGJlZm9yZS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBBVkQsIGl0cyBsYXVuY2hlciwgYW5kIHdoZW4gaXQgd2FzIGxhdW5jaGVkLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgbGF1bmNoIHdhcyByZWNvcmRlZCBhbmQgaXRzIHJlYXBlciBhcm1lZC5cbiAgICovXG4gIHByaXZhdGUgcmVjb3JkRW11bGF0b3JMYXVuY2gocGFyYW1zOiBSZWNvcmRFbXVsYXRvckxhdW5jaFBhcmFtcyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHsgYXZkTmFtZSB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IGxhdW5jaGVyUGlkID0gcGFyYW1zLmVtdWxhdG9yLnByb2Nlc3MucGlkO1xuICAgIGlmIChsYXVuY2hlclBpZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZyhgVGhlIGVtdWxhdG9yIGxhdW5jaGVyIGZvciBBVkQgXCIke2F2ZE5hbWV9XCIgcmVwb3J0ZWQgbm8gUElELCBzbyBpdHMgbGF1bmNoIGNhbm5vdCBiZSByZWNvcmRlZDsgaXQgaXMgcmVjb3JkZWQgb25jZSBpdHMgZGV2aWNlIGNvbm5lY3RzLmApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nTWFya2VyID0gcmVhZEVtdWxhdG9yTWFya2VyKGF2ZE5hbWUpO1xuICAgIGlmIChleGlzdGluZ01hcmtlciAmJiAoc2VsZWN0TGl2ZU1hcmtlZFBpZHMoZXhpc3RpbmdNYXJrZXIsIHBhcmFtcy5wcmVMYXVuY2hFbXVsYXRvclBpZHMpLmxlbmd0aCA+IDAgfHwgY2hlY2tJc01hcmtlZEVtdWxhdG9yUnVubmluZyhleGlzdGluZ01hcmtlcikpKSB7XG4gICAgICB0aGlzLmxvZyhgTm90IHJlY29yZGluZyB0aGUgbGF1bmNoIG9mIEFWRCBcIiR7YXZkTmFtZX1cIiB5ZXQ6IGl0cyBleGlzdGluZyBtYXJrZXIgc3RpbGwgbmFtZXMgYSBydW5uaW5nIHByb2Nlc3MsIGFuZCB0aGF0IHJlY29yZCBpcyB0aGUgb25seSBvbmUgb2YgYW4gZW11bGF0b3IgdGhhdCBtYXkgc3RpbGwgYmUgdXAuYCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgd3JpdGVFbXVsYXRvck1hcmtlcih7XG4gICAgICBhdmROYW1lLFxuICAgICAgb3duZWRFbXVsYXRvclBpZHM6IFtsYXVuY2hlclBpZF0sXG4gICAgICBwcmVMYXVuY2hFbXVsYXRvclBpZHM6IHBhcmFtcy5wcmVMYXVuY2hFbXVsYXRvclBpZHMsXG4gICAgICBzdGFydGVkQXRJbk1pbGxpc2Vjb25kczogcGFyYW1zLmxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kc1xuICAgIH0pO1xuICAgIHRoaXMubG9nKGBSZWNvcmRlZCB0aGUgZW11bGF0b3IgbGF1bmNoIGZvciBBVkQgXCIke2F2ZE5hbWV9XCIgKGxhdW5jaGVyIFBJRCAke1N0cmluZyhsYXVuY2hlclBpZCl9KSBiZWZvcmUgaXRzIGRldmljZSBleGlzdHMsIHNvIGEga2lsbCBkdXJpbmcgdGhlIGJvb3Qgc3RpbGwgbGVhdmVzIGl0IGNvbnZpY3RhYmxlLmApO1xuICAgIHRoaXMuYXJtRW11bGF0b3JSZWFwZXIoYXZkTmFtZSwgcGFyYW1zLmxhdW5jaGVkQXRJbk1pbGxpc2Vjb25kcyk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRmlsbHMgdGhlIGRldmljZSBpbnRvIHRoZSBtYXJrZXIgdGhpcyBsYXVuY2ggd3JvdGUsIGFzIHNvb24gYXMgb25lIGFwcGVhcnMuXG4gICAqXG4gICAqIFdvcnRoIGl0cyBvd24gd3JpdGUgYmVjYXVzZSB0aGUgY29uc29sZSBzaHV0ZG93biBpcyB0aGUgb25seSBzdG9wIHRoYXRcbiAgICogcmVsZWFzZXMgdGhlIEFWRCdzIGBtdWx0aWluc3RhbmNlLmxvY2tgICgqKkw0NioqKSwgYW5kIGl0IG5lZWRzIGEgZGV2aWNlIHRvXG4gICAqIHRhbGsgdG8uIERlbGliZXJhdGVseSAqKm5vKiogaG9zdCBwcm9jZXNzIGxpc3RpbmcgaGVyZTogdGhhdCBxdWVyeSBpc1xuICAgKiBidWRnZXRlZCBhdCBgSE9TVF9QUk9DRVNTX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTYCAoMTIwcykgZm9yIGV4YWN0bHlcbiAgICogdGhpcyBjb250ZW5kZWQgd2luZG93LCBhbmQgc3BlbmRpbmcgaXQgaW5zaWRlIHRoZSBib290IHBhdGggd291bGQgZWF0IHRoZVxuICAgKiByZWFkaW5lc3MgYnVkZ2V0cyB0aGF0IGZvbGxvdy4gVGhlIGJhY2tlbmQgUElEcyBhcnJpdmUgd2l0aCB0aGUgc3VjY2Vzc1xuICAgKiB3cml0ZSwgb25lIGxpc3RpbmcsIGFzIGJlZm9yZS5cbiAgICpcbiAgICogT25seSBldmVyIGZpbGxzIGluICoqdGhpcyoqIGxhdW5jaCdzIG1hcmtlcjogb25lIGNhcnJ5aW5nIGFub3RoZXIgbGF1bmNoXG4gICAqIHRpbWUsIG9yIGEgZGV2aWNlIGFscmVhZHksIGJlbG9uZ3MgdG8gYW4gZW11bGF0b3IgdGhpcyBydW4gZGlkIG5vdCBzdGFydC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBBVkQsIHRoZSBkZXZpY2UgdGhhdCBhcHBlYXJlZCwgYW5kIHRoZSBsYXVuY2ggaXQgYmVsb25ncyB0by5cbiAgICovXG4gIHByaXZhdGUgcmVjb3JkRW11bGF0b3JMYXVuY2hEZXZpY2UocGFyYW1zOiBSZWNvcmRFbXVsYXRvckxhdW5jaERldmljZVBhcmFtcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgYXZkTmFtZSwgZGV2aWNlSWQgfSA9IHBhcmFtcztcbiAgICBjb25zdCBtYXJrZXIgPSByZWFkRW11bGF0b3JNYXJrZXIoYXZkTmFtZSk7XG4gICAgaWYgKCFtYXJrZXIgfHwgbWFya2VyLmRldmljZUlkICE9PSB1bmRlZmluZWQgfHwgbWFya2VyLnN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzICE9PSBwYXJhbXMubGF1bmNoZWRBdEluTWlsbGlzZWNvbmRzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd3JpdGVFbXVsYXRvck1hcmtlcih7XG4gICAgICBhdmROYW1lLFxuICAgICAgZGV2aWNlSWQsXG4gICAgICBvd25lZEVtdWxhdG9yUGlkczogbWFya2VyLm93bmVkRW11bGF0b3JQaWRzLFxuICAgICAgLy8gU3RpbGwgcHJvdmlzaW9uYWw6IHRoZSBiYWNrZW5kJ3MgUElEIGFycml2ZXMgd2l0aCB0aGUgc3VjY2VzcyB3cml0ZSwgYW5kIHVudGlsIHRoZW4gdGhlIGRpZmYgaXMgd2hhdCBjb252aWN0cyBpdC5cbiAgICAgIHByZUxhdW5jaEVtdWxhdG9yUGlkczogbWFya2VyLnByZUxhdW5jaEVtdWxhdG9yUGlkcyxcbiAgICAgIHN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzOiBtYXJrZXIuc3RhcnRlZEF0SW5NaWxsaXNlY29uZHNcbiAgICB9KTtcbiAgICB0aGlzLmxvZyhgUmVjb3JkZWQgZGV2aWNlICR7ZGV2aWNlSWR9IGFnYWluc3QgdGhlIGxhdW5jaCBtYXJrZXIgZm9yIEFWRCBcIiR7YXZkTmFtZX1cIiwgc28gYSBzdG9wIGZyb20gaGVyZSBvbiBjYW4gc2h1dCBpdCBkb3duIG92ZXIgaXRzIGNvbnNvbGUuYCk7XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYSB3ZWRnZWQgc2VydmVyIHRoaXMgaGFybmVzcyBzdGFydGVkIGVhcmxpZXIgYW5kIHJldHJpZXMgdGhlXG4gICAqIHNlc3Npb24gb25jZS5cbiAgICpcbiAgICogVGhlIG9sZCBzZXJ2ZXIgaXMga2lsbGVkIGFuZCB0aGUgcG9ydCBpcyB3YWl0ZWQgb3V0IGJlZm9yZSBhIHJlcGxhY2VtZW50IGlzXG4gICAqIHN0YXJ0ZWQ6IGEgc29ja2V0IHRoYXQga2VlcHMgYW5zd2VyaW5nIGAvc3RhdHVzYCB3b3VsZCBsZXQgdGhlIHJlYWRpbmVzc1xuICAgKiBwb2xsIHBhc3Mgb24gdGhlIGR5aW5nIHNlcnZlciwgYW5kIGEgcG9ydCB0aGF0IG5ldmVyIGdvZXMgcXVpZXQgbWVhbnMgdGhlXG4gICAqIGtpbGwgZGlkIG5vdCB0YWtlIFx1MjAxNCBpbiB3aGljaCBjYXNlIHN0YXJ0aW5nIGFueXRoaW5nIG9uIGl0IGlzIHBvaW50bGVzcy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzZXNzaW9uIGNhcGFiaWxpdGllcyBwbHVzIHdoYXQgaXMga25vd24gYWJvdXQgdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIG9yaWdpbmFsRXJyb3IgLSBUaGUgZmFpbHVyZSB0aGF0IGNvbnZpY3RlZCB0aGUgc2VydmVyLCBsb2dnZWQgc28gdGhlIGRpYWdub3NpcyBpcyBvbiB0aGUgcmVjb3JkLlxuICAgKiBAcmV0dXJucyBUaGUgc2Vzc2lvbiBhbmQgdGhlIHJlcGxhY2VtZW50IHNlcnZlciBwcm9jZXNzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXN0YXJ0V2VkZ2VkU2VydmVyQW5kUmV0cnkocGFyYW1zOiBFc3RhYmxpc2hTZXNzaW9uUGFyYW1zLCBvcmlnaW5hbEVycm9yOiB1bmtub3duKTogUHJvbWlzZTxFc3RhYmxpc2hTZXNzaW9uUmVzdWx0PiB7XG4gICAgY29uc3QgbWFya2VyID0gZW5zdXJlTm9uTnVsbGFibGUocGFyYW1zLmFwcGl1bVNlcnZlck1hcmtlciwgJ0EgcmVzdGFydCB2ZXJkaWN0IHJlcXVpcmVzIHRoZSBtYXJrZXIgdGhhdCBwcm92ZWQgb3duZXJzaGlwLicpO1xuICAgIHRoaXMubG9nKFxuICAgICAgYEFwcGl1bSBhdCAke3BhcmFtcy51cmwub3JpZ2lufSBjYW5ub3Qgc2VlICR7cGFyYW1zLmRldmljZUlkfSBhbHRob3VnaCB0aGlzIGhvc3QncyBhZGIgY2FuIFx1MjAxNCB0aGUgc2VydmVyIHRoaXMgaGFybmVzcyBzdGFydGVkIGVhcmxpZXIgKHBpZCAke1N0cmluZyhtYXJrZXIucGlkKX0pIGlzIHN0YWxlLiBSZXN0YXJ0aW5nIGl0Li4uIChzZXNzaW9uIGZhaWxlZCB3aXRoOiAke29yaWdpbmFsRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IG9yaWdpbmFsRXJyb3IubWVzc2FnZSA6IFN0cmluZyhvcmlnaW5hbEVycm9yKX0pYFxuICAgICk7XG5cbiAgICBraWxsUHJvY2Vzc1RyZWVCeVBpZChtYXJrZXIucGlkKTtcbiAgICBjbGVhckFwcGl1bVNlcnZlck1hcmtlcihwYXJhbXMucG9ydCk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yQXBwaXVtU3RvcHBlZChwYXJhbXMudXJsLCBBUFBJVU1fU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLmJ1aWxkV2VkZ2VkTWVzc2FnZShwYXJhbXMsICdyZXN0YXJ0LWRpZC1ub3QtaGVscCcpLCB7IGNhdXNlOiBlcnJvciB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBsYXVuY2ggPSB0aGlzLnN0YXJ0QXBwaXVtU2VydmVyKHBhcmFtcy5wb3J0LCBwYXJhbXMuaXNBcHBpdW1Db25zb2xlVmlzaWJsZSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yQXBwaXVtUmVhZHkocGFyYW1zLnVybCwgcGFyYW1zLmFwcGl1bVN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzLCBsYXVuY2gpO1xuICAgICAgdGhpcy5sb2coJ1JlcGxhY2VtZW50IEFwcGl1bSBzZXJ2ZXIgaXMgcmVhZHksIHJldHJ5aW5nIHRoZSBzZXNzaW9uLi4uJyk7XG4gICAgICByZXR1cm4geyBhcHBpdW1Qcm9jZXNzOiBsYXVuY2gucHJvY2VzcywgYnJvd3NlcjogYXdhaXQgdGhpcy5jb25uZWN0U2Vzc2lvbihwYXJhbXMpIH07XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGtpbGxQcm9jZXNzVHJlZShsYXVuY2gucHJvY2Vzcyk7XG4gICAgICBjbGVhckFwcGl1bVNlcnZlck1hcmtlcihwYXJhbXMucG9ydCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5idWlsZFdlZGdlZE1lc3NhZ2UocGFyYW1zLCAncmVzdGFydC1kaWQtbm90LWhlbHAnKSwgeyBjYXVzZTogZXJyb3IgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkb3B0cyBhIGRldmljZSBhbHJlYWR5IHNlcnZpbmcgdGhlIHJlcXVlc3RlZCBBVkQuXG4gICAqXG4gICAqIEBwYXJhbSBhdmROYW1lIC0gVGhlIEFWRCBpdCBpcyBzZXJ2aW5nLlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgZGV2aWNlIHRvIGFkb3B0LlxuICAgKiBAcGFyYW0gdGltZW91dHMgLSBUaGUgdHdvIHBvc3QtYm9vdCByZWFkaW5lc3MgYnVkZ2V0cy5cbiAgICogQHJldHVybnMgVGhlIGFkb3B0ZWQgZGV2aWNlLCBvd25pbmcgdGhlIGVtdWxhdG9yJ3MgUElEcyBvbmx5IHdoZW4gaXQgaXMgYSBsZWZ0b3ZlciB0aGlzIGhhcm5lc3Mgc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmV1c2VDb25uZWN0ZWREZXZpY2UoYXZkTmFtZTogc3RyaW5nLCBkZXZpY2VJZDogc3RyaW5nLCB0aW1lb3V0czogRGV2aWNlUmVhZGluZXNzVGltZW91dHMpOiBQcm9taXNlPEVuc3VyZURldmljZUNvbm5lY3RlZFJlc3VsdD4ge1xuICAgIC8qXG4gICAgICogQSBkZXZpY2UgdGhpcyBydW4gZGlkIG5vdCBzdGFydCBpcyBub3QgdGhpcyBydW4ncyB0byBzdG9wIFx1MjAxNCB1bmxlc3MgdGhpc1xuICAgICAqIGhhcm5lc3Mgc3RhcnRlZCBpdCBhbmQgbm90aGluZyBsaXZlIGlzIHJlc3BvbnNpYmxlIGZvciBpdCBhbnkgbW9yZS4gVGhlblxuICAgICAqIGl0IGlzIHRha2VuIG92ZXIsIHNvIHRoaXMgcnVuJ3MgdGVhcmRvd24gc3RvcHMgaXQgYW5kIGEgbGVha2VkIGVtdWxhdG9yXG4gICAgICogc2VydmVzIGF0IG1vc3Qgb25lIG1vcmUgcnVuIGluc3RlYWQgb2YgbGl2aW5nIGZvciBldmVyLlxuICAgICAqL1xuICAgIGNvbnN0IG93bmVkRW11bGF0b3JQaWRzID0gYXdhaXQgdGhpcy50YWtlT3ZlckxlZnRvdmVyRW11bGF0b3IoYXZkTmFtZSwgZGV2aWNlSWQpO1xuICAgIHRoaXMubG9nKFxuICAgICAgb3duZWRFbXVsYXRvclBpZHMubGVuZ3RoID4gMFxuICAgICAgICA/IGBBVkQgXCIke2F2ZE5hbWV9XCIgaXMgYWxyZWFkeSBydW5uaW5nIG9uIGRldmljZSAke2RldmljZUlkfSBhcyBhIGxlZnRvdmVyIHRoaXMgaGFybmVzcyBzdGFydGVkOyByZXVzaW5nIGl0IGFuZCB0YWtpbmcgaXQgb3ZlciAob3duZWQgZW11bGF0b3IgUElEczogWyR7b3duZWRFbXVsYXRvclBpZHMuam9pbignLCAnKX1dKSwgc28gdGhpcyBydW4gc3RvcHMgaXQuYFxuICAgICAgICA6IGBBVkQgXCIke2F2ZE5hbWV9XCIgaXMgYWxyZWFkeSBydW5uaW5nIG9uIGRldmljZSAke2RldmljZUlkfSwgcmV1c2luZy5gXG4gICAgKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnN1cHByZXNzRXJyb3JEaWFsb2dzKGRldmljZUlkKTtcbiAgICAgIC8qXG4gICAgICAgKiBBIHJldXNlZCBkZXZpY2UgZ2V0cyB0aGUgU0FNRSBzZXR0bGUgZ2F0ZSBhIGhhcm5lc3Mtc3RhcnRlZCBvbmUgZ2V0cy5cbiAgICAgICAqIEFwcGVhcmluZyBpbiBgYWRiIGRldmljZXNgIHNheXMgb25seSB0aGF0IGFkYmQgaXMgdXA6IHRoZSBndWVzdCBjYW5cbiAgICAgICAqIHN0aWxsIGJlIHJ1bm5pbmcgdGhlIGJvb3QgYW5pbWF0aW9uIG9yIG9wdGltaXppbmcgcGFja2FnZXMsIGFuZCBhXG4gICAgICAgKiBzZXNzaW9uIGVzdGFibGlzaGVkIGFnYWluc3QgdGhhdCBjb250ZW5kcyB3aXRoIHRoZSBjaHVybiBhbmQgaW5mbGF0ZXNcbiAgICAgICAqIGV2ZXJ5IHN1YnNlcXVlbnQgcm91bmQtdHJpcCAyNS01MHggKEwxOSkuIFNraXBwaW5nIHRoZSBnYXRlIGhlcmUgaXNcbiAgICAgICAqIHdoYXQgbGV0IGEgcmVsZWFzZSBwcmVmbGlnaHQgc3BlbmQgaXRzIHdob2xlIGxheW91dC1yZWFkeSBidWRnZXQgb24gYVxuICAgICAgICogaGFuZGZ1bCBvZiBjb250ZW5kZWQgcHJvYmVzIHdoaWxlIGBhZGIgZGV2aWNlc2AgcmVwb3J0ZWQgYGRldmljZWBcbiAgICAgICAqIHRocm91Z2hvdXQuIFRoZSBzYW1lIGFyZ3VtZW50IGFwcGxpZXMgdG8gdGhlIG5ldHdvcmsgZ2F0ZTogYSBkZXZpY2VcbiAgICAgICAqIHRoYXQgaGFzIGJlZW4gdXAgZm9yIHNlY29uZHMgaXMgZXhhY3RseSBvbmUgd2l0aCBubyB2YWxpZGF0ZWQgbmV0d29ya1xuICAgICAgICogeWV0LlxuICAgICAgICovXG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JCb290KGRldmljZUlkLCBEYXRlLm5vdygpICsgRU1VTEFUT1JfQk9PVF9USU1FT1VUX0lOX01JTExJU0VDT05EUywgdW5kZWZpbmVkKTtcbiAgICAgIGF3YWl0IHRoaXMud2FpdEZvckRldmljZVJlYWR5KGRldmljZUlkLCB0aW1lb3V0cyk7XG4gICAgICBhd2FpdCB0aGlzLndha2VTY3JlZW4oZGV2aWNlSWQpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvLyBBcyB3aXRoIGEgbGF1bmNoIHRoYXQgZmFpbHMgaXRzIGdhdGVzOiBhIHJlamVjdGlvbiBoZXJlIGhhbmRzIHRoZSBjYWxsZXIgbm90aGluZyB0byBzdG9wLlxuICAgICAgaWYgKG93bmVkRW11bGF0b3JQaWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5lbXVsYXRvcnMuc3RvcEVtdWxhdG9yKHsgYXZkTmFtZSwgZGV2aWNlSWQsIG93bmVkRW11bGF0b3JQaWRzIH0pO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgYWN0dWFsRGV2aWNlSWQ6IGRldmljZUlkLCBvd25lZEVtdWxhdG9yUGlkcyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgb25lIGxpdmVuZXNzIHByb2JlLCByZXRyeWluZyBvbmNlIGJlZm9yZSBjYWxsaW5nIGl0IHNpbGVuY2UuXG4gICAqXG4gICAqIE9ubHkgc3VjY2VzcyBjb3VudHMgYXMgYW4gYW5zd2VyOiBhIGZhaWxlZCBgYWRiIC4uLiBlbXVgIG1heSBiZSB0aGUgYWRiXG4gICAqIHNlcnZlciByZWZ1c2luZyBhbiBgb2ZmbGluZWAgZGV2aWNlIHJhdGhlciB0aGFuIHRoZSBjb25zb2xlIGJlaW5nIGRlYWQsIGFuZFxuICAgKiB0aGUgdHdvIGFyZSBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIGhlcmUgKHNlZSBgZW11bGF0b3ItbGl2ZW5lc3MudHNgKS4gVGhlXG4gICAqIHNpbmdsZSByZXRyeSBpcyB0aGUgc2FtZSByZXN0cmFpbnQgYHByb2JlQXZkTmFtZWAgYXBwbGllcyBmb3IgdGhlIHNhbWVcbiAgICogcmVhc29uIFx1MjAxNCBhIHNlY29uZCBsb29rIGlzIGZhciBjaGVhcGVyIHRoYW4gYSB3cm9uZyB2ZXJkaWN0LCBhbmQgdGhpcyBvbmVcbiAgICogZGVjaWRlcyB3aGV0aGVyIGEgcnVuIGlzIGFib3J0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBpbnB1dCAtIFRoZSBhZGIgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBwcm9iZSBnb3QgYW4gYW5zd2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5MaXZlbmVzc1Byb2JlKGlucHV0OiByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8RW11bGF0b3JMaXZlbmVzc1Byb2JlT3V0Y29tZT4ge1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAxOyBhdHRlbXB0IDw9IERFVklDRV9MSVZFTkVTU19BVFRFTVBUX0NPVU5UOyBhdHRlbXB0KyspIHtcbiAgICAgIGNvbnN0IGlzQW5zd2VyZWQgPSBhd2FpdCBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICBleGVjRmlsZSgnYWRiJywgWy4uLmlucHV0XSwgeyB0aW1lb3V0OiBERVZJQ0VfTElWRU5FU1NfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSwgKGVycm9yKSA9PiB7XG4gICAgICAgICAgcmVzb2x2ZSghZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaXNBbnN3ZXJlZCkge1xuICAgICAgICByZXR1cm4gJ2Fuc3dlcmVkJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gJ25vLWFuc3dlcic7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRLZXlFdmVudChkZXZpY2VJZDogc3RyaW5nLCBrZXlDb2RlOiBudW1iZXIsIGRlc2NyaXB0aW9uOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoXG4gICAgICAgICdhZGInLFxuICAgICAgICBbJy1zJywgZGV2aWNlSWQsICdzaGVsbCcsICdpbnB1dCcsICdrZXlldmVudCcsIFN0cmluZyhrZXlDb2RlKV0sXG4gICAgICAgIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LFxuICAgICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgICAgICBgV2FybmluZzogZmFpbGVkIHRvICR7ZGVzY3JpcHRpb259IChrZXlldmVudCAke1N0cmluZyhrZXlDb2RlKX0pOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ3Vua25vd24gZXJyb3InfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzdGFydEFwcGl1bUFuZEVtdWxhdG9yKHBhcmFtczogU3RhcnRBcHBpdW1BbmRFbXVsYXRvclBhcmFtcyk6IFByb21pc2U8U3RhcnRBcHBpdW1BbmRFbXVsYXRvclJlc3VsdD4ge1xuICAgIGNvbnN0IHsgYXBwaXVtU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMsIGFwcGl1bVVybCwgYXZkTmFtZSwgZGV2aWNlSWRsZVRpbWVvdXRJbk1pbGxpc2Vjb25kcywgaXNBcHBpdW1Db25zb2xlVmlzaWJsZSwgaXNFbXVsYXRvclZpc2libGUsIG5ldHdvcmtSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcywgcG9ydCwgc2hvdWxkQXV0b0luc3RhbGxBcHBpdW1EZXBlbmRlbmNpZXMsIHNob3VsZEF1dG9TdGFydEFwcGl1bSwgc2hvdWxkUmV1c2VFbXVsYXRvclNuYXBzaG90IH0gPSBwYXJhbXM7XG5cbiAgICBsZXQgbmVlZHNBcHBpdW1TdGFydCA9IGZhbHNlO1xuICAgIGxldCBhcHBpdW1TZXJ2ZXJNYXJrZXI6IEFwcGl1bVNlcnZlck1hcmtlciB8IHVuZGVmaW5lZDtcblxuICAgIHRoaXMubG9nKGBDaGVja2luZyBBcHBpdW0gc2VydmVyIGF0ICR7YXBwaXVtVXJsLmhyZWZ9Li4uYCk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuY2hlY2tBcHBpdW1SZWFjaGFibGUoYXBwaXVtVXJsKTtcbiAgICAgIGFwcGl1bVNlcnZlck1hcmtlciA9IHJlYWRBcHBpdW1TZXJ2ZXJNYXJrZXIocG9ydCk7XG4gICAgICB0aGlzLmxvZyhgQXBwaXVtIHNlcnZlciBpcyByZWFjaGFibGUgKCR7dGhpcy5kZXNjcmliZUFkb3B0ZWRTZXJ2ZXIoYXBwaXVtU2VydmVyTWFya2VyKX0pLmApO1xuXG4gICAgICBpZiAoYXBwaXVtU2VydmVyTWFya2VyPy5zdG9wQXR0ZW1wdGVkQXRJbk1pbGxpc2Vjb25kcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG5lZWRzQXBwaXVtU3RhcnQgPSBhd2FpdCB0aGlzLnJlY2xhaW1VbnN0b3BwZWRBcHBpdW1TZXJ2ZXIoe1xuICAgICAgICAgIG1hcmtlcjogYXBwaXVtU2VydmVyTWFya2VyLFxuICAgICAgICAgIHBvcnQsXG4gICAgICAgICAgc2hvdWxkQXV0b1N0YXJ0QXBwaXVtLFxuICAgICAgICAgIHVybDogYXBwaXVtVXJsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAobmVlZHNBcHBpdW1TdGFydCkge1xuICAgICAgICAgIGFwcGl1bVNlcnZlck1hcmtlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBpZiAoc2hvdWxkQXV0b1N0YXJ0QXBwaXVtID09PSBmYWxzZSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIG5lZWRzQXBwaXVtU3RhcnQgPSB0cnVlO1xuICAgIH1cblxuICAgIGxldCBhcHBpdW1MYXVuY2g6IFByb2Nlc3NMYXVuY2ggfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAobmVlZHNBcHBpdW1TdGFydCkge1xuICAgICAgaWYgKHNob3VsZEF1dG9JbnN0YWxsQXBwaXVtRGVwZW5kZW5jaWVzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQXBwaXVtRGVwZW5kZW5jaWVzKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmxvZyhgQXBwaXVtIG5vdCByZWFjaGFibGUsIGF1dG8tc3RhcnRpbmcgb24gcG9ydCAke1N0cmluZyhwb3J0KX0uLi5gKTtcbiAgICAgIGFwcGl1bUxhdW5jaCA9IHRoaXMuc3RhcnRBcHBpdW1TZXJ2ZXIocG9ydCwgaXNBcHBpdW1Db25zb2xlVmlzaWJsZSk7XG4gICAgfVxuXG4gICAgY29uc3QgYXBwaXVtUHJvY2VzcyA9IGFwcGl1bUxhdW5jaD8ucHJvY2VzcztcblxuICAgIC8qXG4gICAgICogYGFsbFNldHRsZWRgLCBub3QgYGFsbGA6IHRoZSB0d28gaGFsdmVzIHN0YXJ0IHRvZ2V0aGVyLCBzbyBhIHJlamVjdGVkXG4gICAgICogQXBwaXVtIHdhaXQgdXNlZCB0byBhYmFuZG9uIGFuIGVtdWxhdG9yIHRoYXQgd2VudCBvbiB0byBib290IHBlcmZlY3RseSBcdTIwMTRcbiAgICAgKiB0aGUgbGVhayBzdXJ2aXZlZCB0aGUgdmVyeSB0ZWFyZG93biB0aGF0IHdhcyBzdXBwb3NlZCB0byBwcmV2ZW50IGl0LFxuICAgICAqIGJlY2F1c2UgdGhlIGVtdWxhdG9yJ3MgaGFuZGxlIG9ubHkgZXhpc3RzIGluc2lkZSB0aGUgcmVzdWx0IGBQcm9taXNlLmFsbGBcbiAgICAgKiBkaXNjYXJkZWQuIEJvdGggb3V0Y29tZXMgYXJlIGNvbGxlY3RlZCBzbyBib3RoIGNhbiBiZSBzdG9wcGVkLlxuICAgICAqL1xuICAgIGNvbnN0IFthcHBpdW1PdXRjb21lLCBkZXZpY2VPdXRjb21lXSA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbXG4gICAgICBhcHBpdW1MYXVuY2hcbiAgICAgICAgPyB0aGlzLndhaXRGb3JBcHBpdW1SZWFkeShhcHBpdW1VcmwsIGFwcGl1bVN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzLCBhcHBpdW1MYXVuY2gpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMubG9nKCdBdXRvLXN0YXJ0ZWQgQXBwaXVtIHNlcnZlciBpcyByZWFkeS4nKTtcbiAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIHRoaXMuZW5zdXJlRGV2aWNlQ29ubmVjdGVkKHsgYXZkTmFtZSwgZGV2aWNlSWRsZVRpbWVvdXRJbk1pbGxpc2Vjb25kcywgaXNFbXVsYXRvclZpc2libGUsIG5ldHdvcmtSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcywgc2hvdWxkUmV1c2VFbXVsYXRvclNuYXBzaG90IH0pXG4gICAgXSk7XG5cbiAgICBjb25zdCBkZXZpY2VSZXN1bHQgPSBkZXZpY2VPdXRjb21lLnN0YXR1cyA9PT0gJ2Z1bGZpbGxlZCcgPyBkZXZpY2VPdXRjb21lLnZhbHVlIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKGFwcGl1bU91dGNvbWUuc3RhdHVzID09PSAncmVqZWN0ZWQnIHx8IGRldmljZVJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3BBdXRvU3RhcnRlZFByb2Nlc3Nlc1ZlcmlmaWVkKHtcbiAgICAgICAgYXBwaXVtUHJvY2VzcyxcbiAgICAgICAgYXZkTmFtZSxcbiAgICAgICAgZGV2aWNlSWQ6IGRldmljZVJlc3VsdD8uYWN0dWFsRGV2aWNlSWQsXG4gICAgICAgIGVtdWxhdG9yUHJvY2VzczogZGV2aWNlUmVzdWx0Py5lbXVsYXRvclByb2Nlc3MsXG4gICAgICAgIG93bmVkRW11bGF0b3JQaWRzOiBkZXZpY2VSZXN1bHQ/Lm93bmVkRW11bGF0b3JQaWRzID8/IFtdLFxuICAgICAgICBwb3J0LFxuICAgICAgICB1cmw6IGFwcGl1bVVybFxuICAgICAgfSk7XG5cbiAgICAgIHRocm93IGdldFNldHRsZWRGYWlsdXJlKFthcHBpdW1PdXRjb21lLCBkZXZpY2VPdXRjb21lXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjdHVhbERldmljZUlkOiBkZXZpY2VSZXN1bHQuYWN0dWFsRGV2aWNlSWQsXG4gICAgICBhcHBpdW1Qcm9jZXNzLFxuICAgICAgYXBwaXVtU2VydmVyTWFya2VyLFxuICAgICAgZW11bGF0b3JDYXB0dXJlOiBkZXZpY2VSZXN1bHQuZW11bGF0b3JDYXB0dXJlLFxuICAgICAgZW11bGF0b3JQcm9jZXNzOiBkZXZpY2VSZXN1bHQuZW11bGF0b3JQcm9jZXNzLFxuICAgICAgaXNBZG9wdGVkQXBwaXVtU2VydmVyOiAhbmVlZHNBcHBpdW1TdGFydCxcbiAgICAgIG93bmVkRW11bGF0b3JQaWRzOiBkZXZpY2VSZXN1bHQub3duZWRFbXVsYXRvclBpZHNcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydEFwcGl1bVNlcnZlcihwb3J0OiBudW1iZXIsIGlzQXBwaXVtQ29uc29sZVZpc2libGU/OiBib29sZWFuKTogUHJvY2Vzc0xhdW5jaCB7XG4gICAgY29uc3QgaXNDb25zb2xlSGlkZGVuID0gc2hvdWxkSGlkZUFwcGl1bUNvbnNvbGUoaXNBcHBpdW1Db25zb2xlVmlzaWJsZSk7XG4gICAgY29uc3QgeyBkZXRhY2hlZCwgd2luZG93c0hpZGUgfSA9IHJlc29sdmVBcHBpdW1TcGF3bkZsYWdzKGlzQ29uc29sZUhpZGRlbik7XG4gICAgLypcbiAgICAgKiBgLS1uby1pbnN0YWxsYDogQXBwaXVtIGlzIGd1YXJhbnRlZWQgcHJlc2VudCBieSBgZW5zdXJlQXBwaXVtSW5zdGFsbGVkYFxuICAgICAqIGJlZm9yZSB3ZSByZWFjaCBoZXJlLCBzbyBwaW4gbnB4IHRvIHRoZSBpbnN0YWxsZWQgY29weS4gV2l0aG91dCBpdCwgbnB4XG4gICAgICogd291bGQgc2lsZW50bHkgdHJ5IHRvIGRvd25sb2FkIEFwcGl1bSBmcmVzaCBmcm9tIHRoZSByZWdpc3RyeSBcdTIwMTQgYVxuICAgICAqIHNsb3cvaHVuZyBmYWlsdXJlIGluIGEgaGlkZGVuIGNvbnNvbGUgXHUyMDE0IHdoZW5ldmVyIGl0IGNvdWxkIG5vdCByZXNvbHZlIHRoZVxuICAgICAqIGdsb2JhbCBpbnN0YWxsIChlLmcuIGEgZ2xvYmFsIHByZWZpeCBub3Qgb24gUEFUSCkuIFNlZSBgZW5zdXJlQXBwaXVtSW5zdGFsbGVkYC5cbiAgICAgKlxuICAgICAqIFBpcGUgc3Rkb3V0L3N0ZGVyciBldmVuIHdoZW4gaGlkZGVuIChyYXRoZXIgdGhhbiBkaXNjYXJkaW5nKSBzbyBhbiBlYXJseVxuICAgICAqIGZhaWx1cmUgc3VjaCBhcyBhIGNyYXNoIG9yIGEgbWlzc2luZyBkcml2ZXIgaXMgY2FwdHVyZWQgYW5kIHN1cmZhY2VkXG4gICAgICogaW1tZWRpYXRlbHkgYnkgYHdhaXRGb3JBcHBpdW1SZWFkeWAsIG1pcnJvcmluZyBgc3RhcnRFbXVsYXRvcmA7XG4gICAgICogYHdpbmRvd3NIaWRlYCBzdGlsbCBzdXBwcmVzc2VzIHRoZSBjb25zb2xlIHdpbmRvdy5cbiAgICAgKi9cbiAgICBjb25zdCBjaGlsZCA9IHNwYXduKGBucHggLS1uby1pbnN0YWxsIGFwcGl1bSAtLWxvZy10aW1lc3RhbXAgLS1wb3J0ICR7U3RyaW5nKHBvcnQpfSAtLWFsbG93LWluc2VjdXJlPSR7Q0hST01FRFJJVkVSX0FVVE9ET1dOTE9BRF9GRUFUVVJFfWAsIHtcbiAgICAgIGRldGFjaGVkLFxuICAgICAgc2hlbGw6IHRydWUsXG4gICAgICBzdGRpbzogaXNDb25zb2xlSGlkZGVuID8gWydpZ25vcmUnLCAncGlwZScsICdwaXBlJ10gOiBbJ2lnbm9yZScsICdpbmhlcml0JywgJ2luaGVyaXQnXSxcbiAgICAgIHdpbmRvd3NIaWRlXG4gICAgfSk7XG5cbiAgICBsZXQgY2FwdHVyZWRPdXRwdXQgPSAnJztcbiAgICBsZXQgZXhpdEluZm86IFByb2Nlc3NFeGl0SW5mbyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgaXNDYXB0dXJpbmcgPSB0cnVlO1xuXG4gICAgY2hpbGQuc3Rkb3V0Py5vbignZGF0YScsIGFwcGVuZE91dHB1dCk7XG4gICAgY2hpbGQuc3RkZXJyPy5vbignZGF0YScsIGFwcGVuZE91dHB1dCk7XG4gICAgY2hpbGQub25jZSgnZXhpdCcsIChjb2RlLCBzaWduYWwpID0+IHtcbiAgICAgIGV4aXRJbmZvID0geyBjb2RlLCBzaWduYWwgfTtcbiAgICB9KTtcbiAgICBjaGlsZC5vbmNlKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgZXhpdEluZm8gPSB7IGNvZGU6IG51bGwsIHNpZ25hbDogbnVsbCwgc3Bhd25FcnJvcjogZXJyb3IubWVzc2FnZSB9O1xuICAgIH0pO1xuXG4gICAgY2hpbGQudW5yZWYoKTtcblxuICAgIC8qXG4gICAgICogUmVjb3JkIHRoZSBzZXJ2ZXIgYXMgb3VycyBiZWZvcmUgYW55dGhpbmcgY2FuIGFkb3B0IGl0LiBUaGUgbWFya2VyIGlzIHdoYXRcbiAgICAgKiBsZXRzIGEgbGF0ZXIgcnVuIHRlbGwgaXRzIG93biBsZWZ0b3ZlciBzZXJ2ZXIgZnJvbSBhIGZvcmVpZ24gb25lLCBhbmQgc29cbiAgICAgKiB3aGV0aGVyIHJlc3RhcnRpbmcgYSB3ZWRnZWQgc2VydmVyIGlzIHRoaXMgaGFybmVzcydzIGNhbGwgdG8gbWFrZSBcdTIwMTQgc2VlXG4gICAgICogYGFwcGl1bS1zZXJ2ZXItbWFya2VyLnRzYC5cbiAgICAgKi9cbiAgICBpZiAoY2hpbGQucGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHdyaXRlQXBwaXVtU2VydmVyTWFya2VyKHsgcGlkOiBjaGlsZC5waWQsIHBvcnQgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByb2Nlc3M6IGNoaWxkLFxuICAgICAgcmVhZEV4aXRJbmZvOiAoKSA9PiBleGl0SW5mbyxcbiAgICAgIHJlYWRPdXRwdXQ6ICgpID0+IGNhcHR1cmVkT3V0cHV0LFxuICAgICAgc3RvcENhcHR1cmU6ICgpOiB2b2lkID0+IHtcbiAgICAgICAgaXNDYXB0dXJpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gYXBwZW5kT3V0cHV0KGNodW5rOiBCdWZmZXIpOiB2b2lkIHtcbiAgICAgIGlmICghaXNDYXB0dXJpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY2FwdHVyZWRPdXRwdXQgPSAoY2FwdHVyZWRPdXRwdXQgKyBjaHVuay50b1N0cmluZygpKS5zbGljZSgtQVBQSVVNX09VVFBVVF9UQUlMX01BWF9MRU5HVEgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRFbXVsYXRvcihhdmROYW1lOiBzdHJpbmcsIHNob3VsZFJldXNlU25hcHNob3Q6IGJvb2xlYW4sIGlzRW11bGF0b3JWaXNpYmxlPzogYm9vbGVhbik6IFByb2Nlc3NMYXVuY2gge1xuICAgIGNvbnN0IGVtdWxhdG9yQmluYXJ5ID0gcmVzb2x2ZUVtdWxhdG9yQmluYXJ5UGF0aCgpO1xuICAgIGNvbnN0IGlzV2luZG93SGlkZGVuID0gc2hvdWxkSGlkZUVtdWxhdG9yV2luZG93KGlzRW11bGF0b3JWaXNpYmxlKTtcbiAgICBjb25zdCBpbnB1dCA9IGJ1aWxkRW11bGF0b3JBcmd1bWVudHMoeyBhdmROYW1lLCBpc0hpZGRlbjogaXNXaW5kb3dIaWRkZW4sIHNob3VsZFJldXNlU25hcHNob3QgfSk7XG4gICAgY29uc3QgeyBkZXRhY2hlZCwgd2luZG93c0hpZGUgfSA9IHJlc29sdmVFbXVsYXRvclNwYXduRmxhZ3MoaXNXaW5kb3dIaWRkZW4pO1xuICAgIGNvbnN0IHsgZW52aXJvbm1lbnQsIGlzTmV0c2ltTG9nR3VhcmRlZCB9ID0gYnVpbGRFbXVsYXRvckVudmlyb25tZW50KHByb2Nlc3MuZW52KTtcbiAgICB0aGlzLmxvZyhgUnVubmluZzogJHtlbXVsYXRvckJpbmFyeX0gJHtpbnB1dC5qb2luKCcgJyl9YCk7XG4gICAgdGhpcy5sb2coXG4gICAgICBpc05ldHNpbUxvZ0d1YXJkZWRcbiAgICAgICAgPyBgbmV0c2ltZCBsb2cgbGV2ZWw6IFJVU1RfTE9HPSR7TkVUU0lNX0xPR19GSUxURVJ9IChrZWVwcyBpdHMgd2lmaS1zdGF0cyB3YXJuaW5nIGZyb20gZ3Jvd2luZyBpdHMgbG9nIHdpdGhvdXQgYm91bmQpLmBcbiAgICAgICAgOiBgbmV0c2ltZCBsb2cgbGV2ZWw6IFJVU1RfTE9HPSR7U3RyaW5nKGVudmlyb25tZW50WydSVVNUX0xPRyddKX0sIHNldCBieSB0aGUgY2FsbGVyIFx1MjAxNCB0aGUgaGFybmVzcydzIGJvdW5kZWQgZGVmYXVsdCBpcyBvZmYsIGFuZCBuZXRzaW1kJ3MgbG9nIGNhbiBncm93IHdpdGhvdXQgYm91bmQuYFxuICAgICk7XG4gICAgLypcbiAgICAgKiBQaXBlIChyYXRoZXIgdGhhbiBpZ25vcmUpIHN0ZG91dC9zdGRlcnIgc28gYW4gZWFybHkgZmFpbHVyZSBzdWNoIGFzXG4gICAgICogXCJ4ODZfNjQgZW11bGF0aW9uIGN1cnJlbnRseSByZXF1aXJlcyBoYXJkd2FyZSBhY2NlbGVyYXRpb25cIiBjYW4gYmVcbiAgICAgKiBzdXJmYWNlZCBpbW1lZGlhdGVseSBpbnN0ZWFkIG9mIHdhaXRpbmcgb3V0IHRoZSBmdWxsIGJvb3QgdGltZW91dC5cbiAgICAgKi9cbiAgICBjb25zdCBjaGlsZCA9IHNwYXduKGVtdWxhdG9yQmluYXJ5LCBpbnB1dCwge1xuICAgICAgZGV0YWNoZWQsXG4gICAgICBlbnY6IGVudmlyb25tZW50LFxuICAgICAgc3RkaW86IFsnaWdub3JlJywgJ3BpcGUnLCAncGlwZSddLFxuICAgICAgd2luZG93c0hpZGVcbiAgICB9KTtcblxuICAgIGxldCBjYXB0dXJlZE91dHB1dCA9ICcnO1xuICAgIGxldCBleGl0SW5mbzogUHJvY2Vzc0V4aXRJbmZvIHwgdW5kZWZpbmVkO1xuICAgIGxldCBpc0NhcHR1cmluZyA9IHRydWU7XG5cbiAgICBjaGlsZC5zdGRvdXQub24oJ2RhdGEnLCBhcHBlbmRPdXRwdXQpO1xuICAgIGNoaWxkLnN0ZGVyci5vbignZGF0YScsIGFwcGVuZE91dHB1dCk7XG4gICAgY2hpbGQub25jZSgnZXhpdCcsIChjb2RlLCBzaWduYWwpID0+IHtcbiAgICAgIGV4aXRJbmZvID0geyBjb2RlLCBzaWduYWwgfTtcbiAgICB9KTtcbiAgICAvKlxuICAgICAqIEEgc3Bhd24gZmFpbHVyZSAoZS5nLiBFTk9FTlQgZm9yIGEgbWlzc2luZy9icm9rZW4gZW11bGF0b3IgYmluYXJ5KSBlbWl0c1xuICAgICAqICdlcnJvcicsIG5vdCAnZXhpdCcuIFJlY29yZCBpdCBhcyBhIHN5bnRoZXRpYyBleGl0IHNvIHRoZSBib290L25ldy1kZXZpY2VcbiAgICAgKiBwb2xscyBmYWlsIGZhc3QgaW5zdGVhZCBvZiBzcGlubmluZyBvdXQgdGhlIGZ1bGwgYm9vdCB0aW1lb3V0LlxuICAgICAqL1xuICAgIGNoaWxkLm9uY2UoJ2Vycm9yJywgKGVycm9yKSA9PiB7XG4gICAgICBleGl0SW5mbyA9IHsgY29kZTogbnVsbCwgc2lnbmFsOiBudWxsLCBzcGF3bkVycm9yOiBlcnJvci5tZXNzYWdlIH07XG4gICAgfSk7XG5cbiAgICBjaGlsZC51bnJlZigpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByb2Nlc3M6IGNoaWxkLFxuICAgICAgcmVhZEV4aXRJbmZvOiAoKSA9PiBleGl0SW5mbyxcbiAgICAgIHJlYWRPdXRwdXQ6ICgpID0+IGNhcHR1cmVkT3V0cHV0LFxuICAgICAgc3RvcENhcHR1cmU6ICgpOiB2b2lkID0+IHtcbiAgICAgICAgLypcbiAgICAgICAgICogTGVhdmUgdGhlIGBkYXRhYCBsaXN0ZW5lcnMgYXR0YWNoZWQgc28gdGhlIHBpcGVzIGtlZXAgZHJhaW5pbmcgKGFcbiAgICAgICAgICogZnVsbCBPUyBwaXBlIGJ1ZmZlciB3b3VsZCBibG9jayB0aGUgbG9uZy1ydW5uaW5nIGVtdWxhdG9yKTsgdGhlIGZsYWdcbiAgICAgICAgICoganVzdCBmcmVlemVzIHRoZSBjYXB0dXJlZCB0YWlsIG9uY2Ugc3RhcnR1cCBoYXMgc3VjY2VlZGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgaXNDYXB0dXJpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gYXBwZW5kT3V0cHV0KGNodW5rOiBCdWZmZXIpOiB2b2lkIHtcbiAgICAgIGlmICghaXNDYXB0dXJpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY2FwdHVyZWRPdXRwdXQgPSAoY2FwdHVyZWRPdXRwdXQgKyBjaHVuay50b1N0cmluZygpKS5zbGljZSgtRU1VTEFUT1JfT1VUUFVUX1RBSUxfTUFYX0xFTkdUSCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERpc2FibGVzIHRoZSBndWVzdCdzIGNyYXNoL0FOUiBkaWFsb2dzIG9uIHRoZSBnaXZlbiBkZXZpY2UuXG4gICAqXG4gICAqIEEgcmVzb3VyY2Utc3RhcnZlZCBlbXVsYXRvciBjYW4gcmFpc2UgYSBcIlByb2Nlc3Mgc3lzdGVtIGlzbid0IHJlc3BvbmRpbmdcIlxuICAgKiBBTlIgKGFuIGBBY3Rpdml0eU1hbmFnZXJTZXJ2aWNlYCB0aW1lb3V0KSB3aG9zZSBkaWFsb2cgb3ZlcmxheXMgdGhlIFVJLiBJZlxuICAgKiBpdCBhcHBlYXJzIGJlZm9yZSBBcHBpdW0gYXR0YWNoZXMsIG5vdGhpbmcgY2FuIGRpc21pc3MgaXQgYW5kIHRoZSBydW4gaGFuZ3NcbiAgICogb3IgZmFpbHMgaW50ZXJtaXR0ZW50bHkuIFNldHRpbmcgdGhlIGBoaWRlX2Vycm9yX2RpYWxvZ3NgIGdsb2JhbCBcdTIwMTQgdGhlIHNhbWVcbiAgICogZmxhZyBBbmRyb2lkJ3Mgb3duIHRlc3QgaW5mcmEgdXNlcyBcdTIwMTQgdGVsbHMgYEFjdGl2aXR5TWFuYWdlclNlcnZpY2VgIHRvXG4gICAqIG5ldmVyIGRyYXcgY3Jhc2gvQU5SIGRpYWxvZ3MsIHNvIHRoZSBBTlIgY2FuIG5vIGxvbmdlciBibG9jayBhdXRvbWF0aW9uLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBlYXJsaWVzdCBwb2ludCBhdCB3aGljaCB0aGUgZmxhZyBjYW4gYmUgc2V0OiB0aGUgZnJhbWV3b3JrXG4gICAqIChgc3lzdGVtX3NlcnZlcmApIG11c3QgYmUgdXAgYmVmb3JlIGBzZXR0aW5ncyBwdXRgIHdvcmtzLCBzbyBjYWxsZXJzIGludm9rZVxuICAgKiBpdCBvbmx5IGFmdGVyIGBzeXMuYm9vdF9jb21wbGV0ZWRgLiBJdCBuYXJyb3dzIFx1MjAxNCBidXQgY2Fubm90IGZ1bGx5IGNsb3NlIFx1MjAxNFxuICAgKiB0aGUgcmFjZSB3aXRoIGFuIEFOUiB0aGF0IGZpcmVzIGJldHdlZW4gYm9vdCBjb21wbGV0aW5nIGFuZCB0aGlzIGNhbGw7IGFcbiAgICogcHJlLWJha2VkIHNuYXBzaG90IHdpdGggdGhlIGZsYWcgYWxyZWFkeSBzZXQgaXMgdGhlIG9ubHkgd2F5IHRvIGVsaW1pbmF0ZVxuICAgKiBpdCBlbnRpcmVseS4gQmVzdC1lZmZvcnQ6IGEgZmFpbHVyZSBpcyBsb2dnZWQsIG5vdCB0aHJvd24sIHNpbmNlIGl0IG9ubHlcbiAgICogc3VwcHJlc3NlcyBhIHN5bXB0b20uXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2UgVURJRCB0byBjb25maWd1cmUuXG4gICAqL1xuICAvKipcbiAgICogU3RvcHMgdGhlIEFwcGl1bSBzZXJ2ZXIgdGhpcyBydW4gc3RhcnRlZCwgYW5kICoqdmVyaWZpZXMqKiBpdCBzdG9wcGVkLlxuICAgKlxuICAgKiBUaGUgcG9ydCBpcyB0aGUgdmVyZGljdDogYSBzb2NrZXQgc3RpbGwgYW5zd2VyaW5nIGAvc3RhdHVzYCBhZnRlciB0aGUga2lsbFxuICAgKiBpcyB0aGUgc2VydmVyLCB3aGF0ZXZlciB0aGUgUElEIHRhYmxlIHNheXMuIFdoZW4gaXQgaXMgc3RpbGwgdGhlcmUgdGhlXG4gICAqIGxpc3RlbmVyIGlzIGtpbGxlZCBieSBwb3J0IG93bmVyc2hpcCBcdTIwMTQgdGhlIG9ubHkgZXNjYWxhdGlvbiB0aGF0IG1lYW5zXG4gICAqIGFueXRoaW5nLCBzaW5jZSByZS1raWxsaW5nIHRoZSBzaGVsbCB3cmFwcGVyJ3MgUElEIHdvdWxkIGp1c3QgcmVwZWF0IHRoZVxuICAgKiBraWxsIHRoYXQgYWxyZWFkeSBmYWlsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgc2VydmVyIHByb2Nlc3MsIGl0cyBwb3J0IGFuZCBpdHMgVVJMLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzdG9wQXV0b1N0YXJ0ZWRBcHBpdW1TZXJ2ZXIocGFyYW1zOiBTdG9wQXV0b1N0YXJ0ZWRBcHBpdW1TZXJ2ZXJQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBraWxsUHJvY2Vzc1RyZWUocGFyYW1zLmFwcGl1bVByb2Nlc3MpO1xuXG4gICAgbGV0IGhhc0VzY2FsYXRlZCA9IGZhbHNlO1xuICAgIGxldCBpc1N0b3BwZWQgPSBhd2FpdCB0aGlzLmNoZWNrSXNBcHBpdW1TdG9wcGVkKHBhcmFtcy51cmwsIEFQUElVTV9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKTtcblxuICAgIGlmICghaXNTdG9wcGVkKSB7XG4gICAgICBjb25zdCBvd25lclBpZHMgPSBhd2FpdCB0aGlzLmxpc3RQb3J0T3duZXJQaWRzKHBhcmFtcy5wb3J0KTtcbiAgICAgIGlmIChvd25lclBpZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBoYXNFc2NhbGF0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICBgQXV0by1zdGFydGVkIEFwcGl1bSBzZXJ2ZXIgc3RpbGwgYW5zd2VycyBvbiAke3BhcmFtcy51cmwub3JpZ2lufSBhZnRlciBpdHMgcHJvY2VzcyB0cmVlIHdhcyBraWxsZWQ7IGVzY2FsYXRpbmcgdG8gdGhlIFBJRChzKSBob2xkaW5nIHRoZSBwb3J0OiBbJHtvd25lclBpZHMuam9pbignLCAnKX1dLmBcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBwaWQgb2Ygb3duZXJQaWRzKSB7XG4gICAgICAgICAga2lsbFByb2Nlc3NUcmVlQnlQaWQocGlkKTtcbiAgICAgICAgfVxuICAgICAgICBpc1N0b3BwZWQgPSBhd2FpdCB0aGlzLmNoZWNrSXNBcHBpdW1TdG9wcGVkKHBhcmFtcy51cmwsIEFQUElVTV9FU0NBTEFURURfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYnVpbGRUZWFyZG93bk1lc3NhZ2Uoe1xuICAgICAgZXZpZGVuY2U6IGBwb3J0ICR7U3RyaW5nKHBhcmFtcy5wb3J0KX1gLFxuICAgICAgb3V0Y29tZTogcmVzb2x2ZVRlYXJkb3duT3V0Y29tZSh7IGhhc0VzY2FsYXRlZCwgaXNTdG9wcGVkIH0pLFxuICAgICAgc3ViamVjdDogJ0F1dG8tc3RhcnRlZCBBcHBpdW0gc2VydmVyJyxcbiAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQVBQSVVNX1NUT1BfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgICB9KSk7XG5cbiAgICBpZiAoaXNTdG9wcGVkKSB7XG4gICAgICAvLyBEcm9wIHRoZSBtYXJrZXIgd2l0aCB0aGUgc2VydmVyIGl0IGRlc2NyaWJlcywgc28gdGhlIG5leHQgcnVuIGNhbm5vdCBtaXN0YWtlIGEgcmVjeWNsZWQgUElEIGZvciBvdXJzLlxuICAgICAgY2xlYXJBcHBpdW1TZXJ2ZXJNYXJrZXIocGFyYW1zLnBvcnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEtlZXAgdGhlIG1hcmtlciwgc3RhbXBlZDogYSBsZWZ0b3ZlciB3ZSBjb3VsZCBub3Qga2lsbCBtdXN0IHN0YXkgY29udmljdGFibGUgYnkgdGhlIG5leHQgcnVuLlxuICAgIHJlY29yZEFwcGl1bVNlcnZlclN0b3BBdHRlbXB0KHBhcmFtcy5wb3J0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCZXN0LWVmZm9ydCB0ZWFyZG93biBmb3IgYHByb2Nlc3Mub24oJ2V4aXQnKWAsIHdoaWNoIGNhbm5vdCBhd2FpdC5cbiAgICpcbiAgICogSXQga2lsbHMsIGxvb2tzIG9uY2UgZm9yIGEgc3Vydml2b3Igc3RpbGwgaG9sZGluZyB0aGUgQXBwaXVtIHBvcnQgb3IgYVxuICAgKiBzdGlsbC1saXZlIGVtdWxhdG9yIFBJRCwga2lsbHMgdGhvc2UgdG9vIFx1MjAxNCBhbmQgdGhlbiBzYXlzIGV4YWN0bHkgdGhhdC4gSXRcbiAgICogbmV2ZXIgY2xhaW1zIGEgdmVyaWZpZWQgc3RvcCwgYmVjYXVzZSBpdCBjYW5ub3Qgd2FpdCB0byBlYXJuIG9uZS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIEV2ZXJ5dGhpbmcgdGhpcyBydW4gc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgc3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzQmVzdEVmZm9ydChwYXJhbXM6IFN0b3BBdXRvU3RhcnRlZFByb2Nlc3Nlc1BhcmFtcyk6IHZvaWQge1xuICAgIGlmIChwYXJhbXMuYXBwaXVtUHJvY2Vzcykge1xuICAgICAga2lsbFByb2Nlc3NUcmVlKHBhcmFtcy5hcHBpdW1Qcm9jZXNzKTtcbiAgICAgIGNvbnN0IG93bmVyUGlkcyA9IHRoaXMubGlzdFBvcnRPd25lclBpZHNTeW5jKHBhcmFtcy5wb3J0KTtcbiAgICAgIGZvciAoY29uc3QgcGlkIG9mIG93bmVyUGlkcykge1xuICAgICAgICBraWxsUHJvY2Vzc1RyZWVCeVBpZChwaWQpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3duZXJQaWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgYEF1dG8tc3RhcnRlZCBBcHBpdW0gc2VydmVyOiBzdG9wIHJlcXVlc3RlZCBhbmQgUElEKHMpIFske293bmVyUGlkcy5qb2luKCcsICcpfV0gaG9sZGluZyBwb3J0ICR7U3RyaW5nKHBhcmFtcy5wb3J0KX0ga2lsbGVkIFx1MjAxNCBzeW5jIHRlYXJkb3duIGNhbm5vdCB3YWl0IHRvIGNvbmZpcm0uYFxuICAgICAgICApO1xuICAgICAgICByZWNvcmRBcHBpdW1TZXJ2ZXJTdG9wQXR0ZW1wdChwYXJhbXMucG9ydCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvZyhgQXV0by1zdGFydGVkIEFwcGl1bSBzZXJ2ZXI6IHN0b3AgcmVxdWVzdGVkLCBub3RoaW5nIGxlZnQgbGlzdGVuaW5nIG9uIHBvcnQgJHtTdHJpbmcocGFyYW1zLnBvcnQpfS5gKTtcbiAgICAgICAgY2xlYXJBcHBpdW1TZXJ2ZXJNYXJrZXIocGFyYW1zLnBvcnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcGFyYW1zLmVtdWxhdG9yUHJvY2VzcyAmJiBwYXJhbXMub3duZWRFbXVsYXRvclBpZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5lbXVsYXRvclByb2Nlc3MpIHtcbiAgICAgIGtpbGxQcm9jZXNzVHJlZShwYXJhbXMuZW11bGF0b3JQcm9jZXNzKTtcbiAgICB9XG4gICAgY29uc3Qgc3Vydml2aW5nUGlkcyA9IHBhcmFtcy5vd25lZEVtdWxhdG9yUGlkcy5maWx0ZXIoKHBpZCkgPT4gY2hlY2tJc1Byb2Nlc3NBbGl2ZShwaWQpKTtcbiAgICBmb3IgKGNvbnN0IHBpZCBvZiBzdXJ2aXZpbmdQaWRzKSB7XG4gICAgICBraWxsUHJvY2Vzc1RyZWVCeVBpZChwaWQpO1xuICAgIH1cblxuICAgIGlmIChzdXJ2aXZpbmdQaWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIEtlZXAgdGhlIG1hcmtlcjogbm90aGluZyBoZXJlIHdhaXRlZCB0byBzZWUgdGhlc2UgZGllLCBzbyB0aGUgbmV4dCBydW4gbXVzdCBzdGlsbCBiZSBhYmxlIHRvIGNvbnZpY3QgdGhlbS5cbiAgICAgIHRoaXMubG9nKFxuICAgICAgICBgQXV0by1zdGFydGVkIGVtdWxhdG9yOiBzdG9wIHJlcXVlc3RlZCBhbmQgc3Vydml2aW5nIGVtdWxhdG9yIFBJRChzKSBbJHtzdXJ2aXZpbmdQaWRzLmpvaW4oJywgJyl9XSBraWxsZWQgXHUyMDE0IHN5bmMgdGVhcmRvd24gY2Fubm90IHdhaXQgdG8gY29uZmlybS5gXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZygnQXV0by1zdGFydGVkIGVtdWxhdG9yOiBzdG9wIHJlcXVlc3RlZCwgbm8gcHJvY2VzcyBvZiB0aGlzIHJ1biBsZWZ0IHJ1bm5pbmcuJyk7XG4gICAgICBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkKHBhcmFtcy5hdmROYW1lKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgZXZlcnl0aGluZyB0aGlzIHJ1biBhdXRvLXN0YXJ0ZWQsIHZlcmlmeWluZyBlYWNoIHN0b3AuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBFdmVyeXRoaW5nIHRoaXMgcnVuIHN0YXJ0ZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN0b3BBdXRvU3RhcnRlZFByb2Nlc3Nlc1ZlcmlmaWVkKHBhcmFtczogU3RvcEF1dG9TdGFydGVkUHJvY2Vzc2VzUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaXNFbXVsYXRvck93bmVkID0gcGFyYW1zLmVtdWxhdG9yUHJvY2VzcyAhPT0gdW5kZWZpbmVkIHx8IHBhcmFtcy5vd25lZEVtdWxhdG9yUGlkcy5sZW5ndGggPiAwO1xuICAgIGlmICghcGFyYW1zLmFwcGl1bVByb2Nlc3MgJiYgIWlzRW11bGF0b3JPd25lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubG9nKCdTdG9wcGluZyBldmVyeXRoaW5nIHRoaXMgcnVuIGF1dG8tc3RhcnRlZC4uLicpO1xuXG4gICAgaWYgKHBhcmFtcy5hcHBpdW1Qcm9jZXNzKSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3BBdXRvU3RhcnRlZEFwcGl1bVNlcnZlcih7XG4gICAgICAgIGFwcGl1bVByb2Nlc3M6IHBhcmFtcy5hcHBpdW1Qcm9jZXNzLFxuICAgICAgICBwb3J0OiBwYXJhbXMucG9ydCxcbiAgICAgICAgdXJsOiBwYXJhbXMudXJsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoaXNFbXVsYXRvck93bmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmVtdWxhdG9ycy5zdG9wRW11bGF0b3Ioe1xuICAgICAgICBhdmROYW1lOiBwYXJhbXMuYXZkTmFtZSxcbiAgICAgICAgZGV2aWNlSWQ6IHBhcmFtcy5kZXZpY2VJZCxcbiAgICAgICAgZW11bGF0b3JQcm9jZXNzOiBwYXJhbXMuZW11bGF0b3JQcm9jZXNzLFxuICAgICAgICBvd25lZEVtdWxhdG9yUGlkczogcGFyYW1zLm93bmVkRW11bGF0b3JQaWRzXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgYW4gZW11bGF0b3IgdGhpcyBydW4gbGF1bmNoZWQgd2hvc2Ugc3RhcnQgZmFpbGVkIGJlZm9yZSBpdCBjb3VsZCBiZVxuICAgKiBoYW5kZWQgYmFjayBcdTIwMTQgdGhlIGJvb3QsIGlkbGUgb3IgbmV0d29yayB3YWl0IGdhdmUgdXAgb24gaXQsIG9yIGl0IG5ldmVyXG4gICAqIHByb2R1Y2VkIGEgZGV2aWNlIGF0IGFsbC5cbiAgICpcbiAgICogVGhlIFBJRHMgY29tZSBmcm9tIHRoZSBzYW1lIHByZS1sYXVuY2ggc25hcHNob3QgYSBzdWNjZXNzZnVsIHN0YXJ0IHVzZXMuIFRoZVxuICAgKiBkZXZpY2UgaXMgd2hpY2hldmVyIGVtdWxhdG9yIGFwcGVhcmVkIGFjcm9zcyB0aGUgbGF1bmNoLCBpbiBhbnkgc3RhdGU7IHdoZW5cbiAgICogdGhhdCBpcyBub3QgZXhhY3RseSBvbmUsIHRoZSBzdG9wIGdvZXMgYnkgUElEcyBhbG9uZSByYXRoZXIgdGhhbiBndWVzcy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBsYXVuY2gsIGFuZCB3aGF0IHByZWRhdGVkIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzdG9wRW11bGF0b3JBZnRlckZhaWxlZFN0YXJ0KHBhcmFtczogU3RvcEVtdWxhdG9yQWZ0ZXJGYWlsZWRTdGFydFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG93bmVkRW11bGF0b3JQaWRzID0gYXdhaXQgdGhpcy5saXN0RW11bGF0b3JCYWNrZW5kUGlkcyhwYXJhbXMuZW11bGF0b3JQaWRzQmVmb3JlKTtcbiAgICBsZXQgbmV3RGV2aWNlSWRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIHRyeSB7XG4gICAgICBuZXdEZXZpY2VJZHMgPSBwYXJzZUFkYkRldmljZXMoYXdhaXQgdGhpcy5lbXVsYXRvcnMuZ2V0RGV2aWNlc091dHB1dCgpKVxuICAgICAgICAubWFwKChlbnRyeSkgPT4gZW50cnkuZGV2aWNlSWQpXG4gICAgICAgIC5maWx0ZXIoKGRldmljZUlkKSA9PiBjaGVja0lzRW11bGF0b3JEZXZpY2VJZChkZXZpY2VJZCkgJiYgIXBhcmFtcy5kZXZpY2VJZHNCZWZvcmUuaW5jbHVkZXMoZGV2aWNlSWQpKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgdGhpcy5sb2coYENvdWxkIG5vdCBsaXN0IGRldmljZXMgd2hpbGUgc3RvcHBpbmcgdGhlIGZhaWxlZCBlbXVsYXRvcjogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYEVtdWxhdG9yIFwiJHtwYXJhbXMuYXZkTmFtZX1cIiBmYWlsZWQgdG8gc3RhcnQ7IHN0b3BwaW5nIGl0IChvd25lZCBlbXVsYXRvciBQSURzOiBbJHtvd25lZEVtdWxhdG9yUGlkcy5qb2luKCcsICcpfV0pLmApO1xuICAgIGF3YWl0IHRoaXMuZW11bGF0b3JzLnN0b3BFbXVsYXRvcih7XG4gICAgICBhdmROYW1lOiBwYXJhbXMuYXZkTmFtZSxcbiAgICAgIGRldmljZUlkOiBuZXdEZXZpY2VJZHMubGVuZ3RoID09PSAxID8gbmV3RGV2aWNlSWRzWzBdIDogdW5kZWZpbmVkLFxuICAgICAgZW11bGF0b3JQcm9jZXNzOiBwYXJhbXMuZW11bGF0b3IucHJvY2VzcyxcbiAgICAgIG93bmVkRW11bGF0b3JQaWRzXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHN1cHByZXNzRXJyb3JEaWFsb2dzKGRldmljZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxvZyhgRGlzYWJsaW5nIGNyYXNoL0FOUiBkaWFsb2dzIG9uIGRldmljZSAke2RldmljZUlkfSAoc2V0dGluZ3MgcHV0IGdsb2JhbCBoaWRlX2Vycm9yX2RpYWxvZ3MgMSkuLi5gKTtcblxuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgJ2FkYicsXG4gICAgICAgIFsnLXMnLCBkZXZpY2VJZCwgJ3NoZWxsJywgJ3NldHRpbmdzJywgJ3B1dCcsICdnbG9iYWwnLCAnaGlkZV9lcnJvcl9kaWFsb2dzJywgJzEnXSxcbiAgICAgICAgeyB0aW1lb3V0OiBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sXG4gICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgICAgIGBXYXJuaW5nOiBmYWlsZWQgdG8gZGlzYWJsZSBjcmFzaC9BTlIgZGlhbG9nczogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICd1bmtub3duIGVycm9yJ31gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBgdGVtcC12YXVsdC0qYCBkaXJlY3RvcmllcyBlYXJsaWVyIHJ1bnMgbGVmdCBvbiB0aGUgZGV2aWNlLlxuICAgKlxuICAgKiBSdW5zICoqYmVmb3JlKiogYHJlbW90ZSgpYCBsYXVuY2hlcyBPYnNpZGlhbiBcdTIwMTQgdGhlIGxhc3QgbW9tZW50IGF0IHdoaWNoXG4gICAqIG5vdGhpbmcgaGFzIHRvIGVudW1lcmF0ZSB0aGUgZGV2aWNlJ3MgdmF1bHRzIHlldCwgYW5kIHRoZSBvbmx5IHN3ZWVwIHRoYXRcbiAgICogZG9lcyBub3QgZGVwZW5kIG9uIGEgaGVhbHRoeSBXZWJWaWV3LiBUaGF0IGluZGVwZW5kZW5jZSBpcyB0aGUgd2hvbGUgcG9pbnQ6XG4gICAqIGEgcnVuIHdob3NlIFdlYlZpZXcgZGllZCBjYW5ub3QgdW5yZWdpc3RlciBvciBkZWxldGUgaXRzIG93biB2YXVsdCwgc29cbiAgICogd2l0aG91dCB0aGlzIGVhY2ggZmFpbHVyZSBsZWF2ZXMgcmVzaWR1ZSB0aGF0IHNsb3dzIHRoZSBuZXh0IHJ1bidzIHN0YXJ0dXBcbiAgICogZW51bWVyYXRpb24gYW5kIG1ha2VzIHRoZSBuZXh0IGZhaWx1cmUgbGlrZWxpZXIuXG4gICAqXG4gICAqIFVuY29uZGl0aW9uYWwgKG5vIGFnZSBnYXRlKSBcdTIwMTQgQW5kcm9pZCBydW5zIGhvbGQgdGhlIGV4Y2x1c2l2ZSBgYW5kcm9pZGBcbiAgICogc2V0dXAgbG9jaywgc28gbm8gY29uY3VycmVudCBydW4gY2FuIG93biBhIGRldmljZSB2YXVsdCwgYW5kIGFuIGFnZSBnYXRlXG4gICAqIHdvdWxkIGxldCBhIHZhdWx0IGxlYWtlZCBtaW51dGVzIGFnbyBzdXJ2aXZlIGludG8gdGhpcyBydW4uIEJlc3QtZWZmb3J0OiBhXG4gICAqIGZhaWx1cmUgaXMgbG9nZ2VkLCBub3QgdGhyb3duLlxuICAgKlxuICAgKiBUaGUgcmVtb3ZhbHMgZ28gb25lIGRpcmVjdG9yeSBhdCBhIHRpbWUgYW5kIHRoZSBvdXRjb21lIGlzIHJlLWxpc3RlZCByYXRoZXJcbiAgICogdGhhbiBpbmZlcnJlZDsge0BsaW5rIHN3ZWVwRGV2aWNlTGVmdG92ZXJzfSBleHBsYWlucyB3aHkuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZGV2aWNlIGFuZCB2YXVsdCBiYXNlIHBhdGggdG8gc3dlZXAuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN3ZWVwRGV2aWNlTGVmdG92ZXJWYXVsdHMocGFyYW1zOiBTd2VlcERldmljZUxlZnRvdmVyVmF1bHRzUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBkZXZpY2VJZCwgdmF1bHRCYXNlUGF0aCB9ID0gcGFyYW1zO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN3ZWVwRGV2aWNlTGVmdG92ZXJzKHtcbiAgICAgICAgbGlzdE5hbWVzOiBhc3luYyAoKTogUHJvbWlzZTxzdHJpbmdbXT4gPT4ge1xuICAgICAgICAgIGNvbnN0IGxpc3RpbmcgPSBhd2FpdCBleGVjKFxuICAgICAgICAgICAgWydhZGInLCAnLXMnLCBkZXZpY2VJZCwgJ3NoZWxsJywgJ2xzJywgJy0xJywgdmF1bHRCYXNlUGF0aF0sXG4gICAgICAgICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9WQVVMVF9TV0VFUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gbGlzdGluZy5zcGxpdCgnXFxuJyk7XG4gICAgICAgIH0sXG4gICAgICAgIHJlbW92ZURpcmVjdG9yeTogYXN5bmMgKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICAgIGF3YWl0IGV4ZWMoXG4gICAgICAgICAgICBbJ2FkYicsICctcycsIGRldmljZUlkLCAnc2hlbGwnLCAncm0nLCAnLXJmJywgcGF0aF0sXG4gICAgICAgICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9WQVVMVF9TV0VFUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgdmF1bHRCYXNlUGF0aFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChyZXN1bHQucmVtb3ZlZENvdW50ID09PSAwICYmIHJlc3VsdC5mYWlsZWROYW1lcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5sb2coYE5vIGxlZnRvdmVyIHRlbXAgdmF1bHRzIG9uIGRldmljZSAke2RldmljZUlkfS5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZyhgUmVtb3ZlZCAke1N0cmluZyhyZXN1bHQucmVtb3ZlZENvdW50KX0gbGVmdG92ZXIgdGVtcCB2YXVsdChzKSBmcm9tICR7dmF1bHRCYXNlUGF0aH0gb24gZGV2aWNlICR7ZGV2aWNlSWR9LmApO1xuXG4gICAgICBpZiAocmVzdWx0LmZhaWxlZE5hbWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgYFdhcm5pbmc6ICR7U3RyaW5nKHJlc3VsdC5mYWlsZWROYW1lcy5sZW5ndGgpfSBsZWZ0b3ZlciB0ZW1wIHZhdWx0KHMpIGNvdWxkIG5vdCBiZSByZW1vdmVkIGFuZCB3aWxsIGJlIHJldHJpZWQgbmV4dCBydW46ICR7cmVzdWx0LmZhaWxlZE5hbWVzLmpvaW4oJywgJyl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICB0aGlzLmxvZyhgV2FybmluZzogZmFpbGVkIHRvIHN3ZWVwIGxlZnRvdmVyIHRlbXAgdmF1bHRzOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ3Vua25vd24gZXJyb3InfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUYWtlcyBvdmVyIHRoZSBydW5uaW5nIGVtdWxhdG9yIG9mIGFuIEFWRCB3aGVuIGl0IGlzIGEgbGVmdG92ZXIgdGhpcyBoYXJuZXNzXG4gICAqIHN0YXJ0ZWQsIHNvIHRoaXMgcnVuIGJlY29tZXMgdGhlIG9uZSByZXNwb25zaWJsZSBmb3Igc3RvcHBpbmcgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBhdmROYW1lIC0gVGhlIEFWRCB0aGUgZGV2aWNlIGlzIHNlcnZpbmcuXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBkZXZpY2Ugc2VydmluZyBpdC5cbiAgICogQHJldHVybnMgVGhlIGVtdWxhdG9yIFBJRHMgdGhpcyBydW4gbm93IG93bnM7IGVtcHR5IHdoZW4gdGhlIGVtdWxhdG9yIGlzIG5vdCBhIGhhcm5lc3MgbGVmdG92ZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHRha2VPdmVyTGVmdG92ZXJFbXVsYXRvcihhdmROYW1lOiBzdHJpbmcsIGRldmljZUlkOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcltdPiB7XG4gICAgY29uc3QgbWFya2VyID0gcmVhZEVtdWxhdG9yTWFya2VyKGF2ZE5hbWUpO1xuICAgIGlmICghbWFya2VyKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgcHJvY2Vzc2VzID0gYXdhaXQgdGhpcy5lbXVsYXRvcnMucXVlcnlFbXVsYXRvclByb2Nlc3NlcygpO1xuICAgIGlmIChwcm9jZXNzZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2coYENhbm5vdCB0ZWxsIHdoZXRoZXIgQVZEIFwiJHthdmROYW1lfVwiIGlzIGEgbGVmdG92ZXIgdGhpcyBoYXJuZXNzIHN0YXJ0ZWQgd2l0aG91dCBhIGhvc3QgcHJvY2VzcyBsaXN0aW5nOyByZXVzaW5nIGl0IHdpdGhvdXQgdGFraW5nIGl0IG92ZXIuYCk7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgbGl2ZUVtdWxhdG9yUGlkcyA9IHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHMoeyBrbm93blBpZHM6IFtdLCBwcm9jZXNzZXMgfSk7XG4gICAgY29uc3QgdmVyZGljdCA9IHJlc29sdmVFbXVsYXRvck1hcmtlclZlcmRpY3Qoe1xuICAgICAgY3VycmVudFBpZDogcHJvY2Vzcy5waWQsXG4gICAgICBpc093bmVyQWxpdmU6IGNoZWNrSXNQcm9jZXNzQWxpdmUobWFya2VyLm93bmVyUGlkKSxcbiAgICAgIGxpdmVFbXVsYXRvclBpZHMsXG4gICAgICBtYXJrZXJcbiAgICB9KTtcblxuICAgIHN3aXRjaCAodmVyZGljdCkge1xuICAgICAgY2FzZSAnaGFybmVzcy1sZWZ0b3Zlcic6IHtcbiAgICAgICAgY29uc3Qgb3duZWRFbXVsYXRvclBpZHMgPSBzZWxlY3RMaXZlTWFya2VkUGlkcyhtYXJrZXIsIGxpdmVFbXVsYXRvclBpZHMpO1xuICAgICAgICB3cml0ZUVtdWxhdG9yTWFya2VyKHsgYXZkTmFtZSwgZGV2aWNlSWQsIG93bmVkRW11bGF0b3JQaWRzLCBzdGFydGVkQXRJbk1pbGxpc2Vjb25kczogbWFya2VyLnN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzIH0pO1xuICAgICAgICAvKlxuICAgICAgICAgKiBUaGUgcmVhcGVyIHRoZSBlYXJsaWVyIHJ1biBhcm1lZCBtYXkgc3RpbGwgYmUgd2F0Y2hpbmcgdGhpcyBlbXVsYXRvclxuICAgICAgICAgKiBcdTIwMTQgdGhlIGxhdW5jaCB0aW1lIGl0IGtleXMgb24gc3Vydml2ZXMgYSB0YWtlb3ZlciBcdTIwMTQgYnV0IGFuIGVtdWxhdG9yXG4gICAgICAgICAqIHN0YXJ0ZWQgYnkgYW4gb2xkZXIgdmVyc2lvbiBvZiB0aGUgaGFybmVzcyBoYXMgbm9uZS4gQSBzZWNvbmQgcmVhcGVyXG4gICAgICAgICAqIGNvc3RzIG5vdGhpbmc6IHdoaWNoZXZlciB0YWtlcyB0aGUgbG9jayBmaXJzdCBzdG9wcyB0aGUgZW11bGF0b3IsIGFuZFxuICAgICAgICAgKiB0aGUgb3RoZXIgdGhlbiBmaW5kcyB0aGUgbWFya2VyIGdvbmUgYW5kIGV4aXRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hcm1FbXVsYXRvclJlYXBlcihhdmROYW1lLCBtYXJrZXIuc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMpO1xuICAgICAgICByZXR1cm4gb3duZWRFbXVsYXRvclBpZHM7XG4gICAgICB9XG4gICAgICBjYXNlICdpbi11c2UtYnktbGl2ZS1ydW4nOiB7XG4gICAgICAgIHRoaXMubG9nKGBBVkQgXCIke2F2ZE5hbWV9XCIgd2FzIHN0YXJ0ZWQgYnkgYSBoYXJuZXNzIHByb2Nlc3MgdGhhdCBpcyBzdGlsbCBydW5uaW5nIChQSUQgJHtTdHJpbmcobWFya2VyLm93bmVyUGlkKX0pOyB0aGF0IHByb2Nlc3Mgc3RheXMgcmVzcG9uc2libGUgZm9yIHN0b3BwaW5nIGl0LmApO1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBjYXNlICdzdGFsZS1tYXJrZXInOiB7XG4gICAgICAgIGNsZWFyRW11bGF0b3JNYXJrZXIoYXZkTmFtZSk7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgcmV0dXJuIGFzc2VydE5ldmVyKHZlcmRpY3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckFwcGl1bVJlYWR5KHVybDogVVJMLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlciwgbGF1bmNoOiBQcm9jZXNzTGF1bmNoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMubG9nKFxuICAgICAgYFdhaXRpbmcgZm9yIEFwcGl1bSBhdCAke3VybC5ocmVmfSAodGltZW91dDogJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcywgcG9sbDogJHtTdHJpbmcoQVBQSVVNX1NUQVJUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKX1tcykuLi5gXG4gICAgKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IHN0YXJ0ICsgdGltZW91dEluTWlsbGlzZWNvbmRzO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgLypcbiAgICAgICAqIElmIHRoZSBzZXJ2ZXIgcHJvY2VzcyBhbHJlYWR5IGRpZWQgKGNyYXNoZWQsIG9yIG5ldmVyIHN0YXJ0ZWQpLCBzdG9wXG4gICAgICAgKiBwb2xsaW5nIGFuZCBzdXJmYWNlIHdoeSBcdTIwMTQgb3RoZXJ3aXNlIGEgZG9vbWVkIHNlcnZlciBzcGlucyBvdXQgdGhlIHdob2xlXG4gICAgICAgKiByZWFkaW5lc3MgdGltZW91dCB3aXRoIG5vIGRpYWdub3N0aWNzLCB0aGUgb3JpZ2luYWwgc3ltcHRvbSB0aGlzIGV4aXN0c1xuICAgICAgICogdG8gcHJldmVudC5cbiAgICAgICAqL1xuICAgICAgY29uc3QgZXhpdEluZm8gPSBsYXVuY2gucmVhZEV4aXRJbmZvKCk7XG4gICAgICBpZiAoZXhpdEluZm8pIHtcbiAgICAgICAgdGhyb3cgYnVpbGREZWF0aEVycm9yKGV4aXRJbmZvKTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja0FwcGl1bVJlYWNoYWJsZSh1cmwpO1xuICAgICAgICBsYXVuY2guc3RvcENhcHR1cmUoKTtcbiAgICAgICAgdGhpcy5sb2coYEFwcGl1bSBzZXJ2ZXIgcmVhZHkgYWZ0ZXIgJHtTdHJpbmcoRGF0ZS5ub3coKSAtIHN0YXJ0KX1tcy5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHRoaXMubG9nKGBBcHBpdW0gc2VydmVyIG5vdCByZWFkeSB5ZXQgKGVsYXBzZWQ6ICR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMpLiBSZXRyeWluZy4uLmApO1xuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgQVBQSVVNX1NUQVJUX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZmluYWxFeGl0SW5mbyA9IGxhdW5jaC5yZWFkRXhpdEluZm8oKTtcbiAgICBpZiAoZmluYWxFeGl0SW5mbykge1xuICAgICAgdGhyb3cgYnVpbGREZWF0aEVycm9yKGZpbmFsRXhpdEluZm8pO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dFRhaWwgPSBsYXVuY2gucmVhZE91dHB1dCgpLnRyaW0oKTtcbiAgICBjb25zdCBvdXRwdXRTZWN0aW9uID0gb3V0cHV0VGFpbC5sZW5ndGggPiAwID8gYFxcblxcbkFwcGl1bSBzZXJ2ZXIgb3V0cHV0ICh0YWlsKTpcXG4ke291dHB1dFRhaWx9YCA6ICcnO1xuICAgIHRocm93IG5ldyBFcnJvcihgQXV0by1zdGFydGVkIEFwcGl1bSBzZXJ2ZXIgZGlkIG5vdCBiZWNvbWUgcmVhZHkgd2l0aGluICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMuJHtvdXRwdXRTZWN0aW9ufWApO1xuXG4gICAgZnVuY3Rpb24gYnVpbGREZWF0aEVycm9yKGV4aXRJbmZvOiBQcm9jZXNzRXhpdEluZm8pOiBFcnJvciB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKGJ1aWxkUHJvY2Vzc0V4aXRNZXNzYWdlKHtcbiAgICAgICAgZXhpdEluZm8sXG4gICAgICAgIG91dHB1dDogbGF1bmNoLnJlYWRPdXRwdXQoKSxcbiAgICAgICAgb3V0cHV0TGFiZWw6ICdBcHBpdW0gc2VydmVyIG91dHB1dCcsXG4gICAgICAgIHN1YmplY3Q6ICdBdXRvLXN0YXJ0ZWQgQXBwaXVtIHNlcnZlcidcbiAgICAgIH0pKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV2FpdHMgdW50aWwgbm90aGluZyBhbnN3ZXJzIGAvc3RhdHVzYCBvbiB0aGUgcG9ydCBhbnkgbW9yZS5cbiAgICpcbiAgICogQHBhcmFtIHVybCAtIFRoZSBBcHBpdW0gc2VydmVyIFVSTC5cbiAgICogQHBhcmFtIHRpbWVvdXRJbk1pbGxpc2Vjb25kcyAtIEhvdyBsb25nIHRvIHdhaXQgYmVmb3JlIGdpdmluZyB1cC5cbiAgICogQHRocm93cyBJZiB0aGUgcG9ydCBpcyBzdGlsbCBzZXJ2ZWQgd2hlbiB0aGUgdGltZW91dCBlbGFwc2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yQXBwaXVtU3RvcHBlZCh1cmw6IFVSTCwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyB0aW1lb3V0SW5NaWxsaXNlY29uZHM7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrQXBwaXVtUmVhY2hhYmxlKHVybCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEFQUElVTV9TVEFSVF9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgU29tZXRoaW5nIGlzIHN0aWxsIHNlcnZpbmcgJHt1cmwub3JpZ2lufSAke1N0cmluZyh0aW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zIGFmdGVyIHRoZSBBcHBpdW0gc2VydmVyIHdhcyBraWxsZWQuYFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgYHN5cy5ib290X2NvbXBsZXRlZGAgdW50aWwgdGhlIGRldmljZSByZXBvcnRzIGEgZmluaXNoZWQgYm9vdC5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSBVRElEIHRvIHBvbGwuXG4gICAqIEBwYXJhbSBkZWFkbGluZSAtIFRoZSBhYnNvbHV0ZSB0aW1lIGF0IHdoaWNoIHRvIGdpdmUgdXAuXG4gICAqIEBwYXJhbSBlbXVsYXRvciAtIFRoZSBlbXVsYXRvciB0aGlzIHJ1biBzdGFydGVkLCBzbyBpdHMgZWFybHkgZGVhdGggZmFpbHMgZmFzdCBpbnN0ZWFkIG9mIHBvbGxpbmcgb3V0IHRoZSBkZWFkbGluZS4gT21pdHRlZCBmb3IgYSByZXVzZWQgZGV2aWNlLCB3aGljaCB0aGlzIHJ1biBkaWQgbm90IGxhdW5jaCBhbmQgY2Fubm90IGluc3BlY3QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JCb290KGRldmljZUlkOiBzdHJpbmcsIGRlYWRsaW5lOiBudW1iZXIsIGVtdWxhdG9yOiBQcm9jZXNzTGF1bmNoIHwgdW5kZWZpbmVkKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVtYWluaW5nTXMgPSBNYXRoLm1heCgwLCBkZWFkbGluZSAtIERhdGUubm93KCkpO1xuICAgIHRoaXMubG9nKFxuICAgICAgYFdhaXRpbmcgZm9yIGRldmljZSAke2RldmljZUlkfSB0byBmaW5pc2ggYm9vdGluZyAocmVtYWluaW5nOiAke1N0cmluZyhyZW1haW5pbmdNcyl9bXMsIHBvbGw6ICR7U3RyaW5nKEVNVUxBVE9SX0JPT1RfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpfW1zKS4uLmBcbiAgICApO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgY29uc3QgaXNCb290ZWQgPSBhd2FpdCBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICBleGVjRmlsZShcbiAgICAgICAgICAnYWRiJyxcbiAgICAgICAgICBbJy1zJywgZGV2aWNlSWQsICdzaGVsbCcsICdnZXRwcm9wJywgJ3N5cy5ib290X2NvbXBsZXRlZCddLFxuICAgICAgICAgIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LFxuICAgICAgICAgIChfZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZShzdGRvdXQudHJpbSgpID09PSAnMScpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaXNCb290ZWQpIHtcbiAgICAgICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBib290IGNvbXBsZXRlZC5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleGl0SW5mbyA9IGVtdWxhdG9yPy5yZWFkRXhpdEluZm8oKTtcbiAgICAgIGlmIChleGl0SW5mbykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYnVpbGRQcm9jZXNzRXhpdE1lc3NhZ2Uoe1xuICAgICAgICAgIGV4aXRJbmZvLFxuICAgICAgICAgIG91dHB1dDogZW11bGF0b3I/LnJlYWRPdXRwdXQoKSA/PyAnJyxcbiAgICAgICAgICBvdXRwdXRMYWJlbDogJ0VtdWxhdG9yIG91dHB1dCcsXG4gICAgICAgICAgc3ViamVjdDogJ0FuZHJvaWQgZW11bGF0b3InXG4gICAgICAgIH0pKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBFTVVMQVRPUl9CT09UX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogVGhlIHRhaWwgZ29lcyBvbiB0aGUgVElNRU9VVCB0b28sIG5vdCBvbmx5IG9uIHRoZSBleGl0LiBBbiBlbXVsYXRvciB0aGF0XG4gICAgICogcHJpbnRzIGBGQVRBTCB8IFJ1bm5pbmcgbXVsdGlwbGUgZW11bGF0b3JzIHdpdGggdGhlIHNhbWUgQVZEYCBhbmQgdGhlblxuICAgICAqIGxpbmdlcnMgbmV2ZXIgc2V0cyBgZXhpdEluZm9gLCBzbyB0aGlzIHVzZWQgdG8gYmUgdGhlIHdob2xlIG9mIHdoYXQgdGhlXG4gICAgICogcmVhZGVyIGdvdCBcdTIwMTQgYSBidWRnZXQsIHdpdGggdGhlIGV4cGxhbmF0aW9uIGNhcHR1cmVkIGFuZCBkaXNjYXJkZWQuXG4gICAgICovXG4gICAgdGhyb3cgbmV3IEVycm9yKGFwcGVuZFByb2Nlc3NPdXRwdXRUYWlsKFxuICAgICAgYERldmljZSBcIiR7ZGV2aWNlSWR9XCIgY29ubmVjdGVkIGJ1dCBkaWQgbm90IGZpbmlzaCBib290aW5nIHdpdGhpbiAke1N0cmluZyhFTVVMQVRPUl9CT09UX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcy5gLFxuICAgICAgeyBvdXRwdXQ6IGVtdWxhdG9yPy5yZWFkT3V0cHV0KCkgPz8gJycsIG91dHB1dExhYmVsOiAnRW11bGF0b3Igb3V0cHV0JyB9XG4gICAgKSk7XG4gIH1cblxuICAvKipcbiAgICogV2FpdHMgZm9yIGEgYm9vdGVkIGVtdWxhdG9yIHRvIGJlY29tZSBpZGxlIGJlZm9yZSB0aGUgc2Vzc2lvbiBpc1xuICAgKiBlc3RhYmxpc2hlZCBcdTIwMTQgd2hldGhlciB0aGlzIHJ1biBzdGFydGVkIGl0IG9yIGZvdW5kIGl0IGFscmVhZHkgcnVubmluZy5cbiAgICpcbiAgICogYHN5cy5ib290X2NvbXBsZXRlZGAgZmlyZXMgYmVmb3JlIHRoZSBndWVzdCBpcyBhY3R1YWxseSBpZGxlIFx1MjAxNCBwYWNrYWdlXG4gICAqIG9wdGltaXphdGlvbiBhbmQgc2VydmljZXMga2VlcCBjaHVybmluZyBcdTIwMTQgc28gZXN0YWJsaXNoaW5nIHRoZSBBcHBpdW1cbiAgICogc2Vzc2lvbiBpbW1lZGlhdGVseSBtYWtlcyBldmVyeSBzZXJpYWxpemVkIFVpQXV0b21hdG9yMiBgYWRiYCByb3VuZC10cmlwXG4gICAqIGNvbnRlbmQgd2l0aCB0aGF0IHdvcmsgYW5kIGluZmxhdGVzIHNlc3Npb24gZXN0YWJsaXNobWVudCB+M3guIFRoaXMgcG9sbHNcbiAgICogYSBsYXRlciwgcXVpZXRlciBzaWduYWwgKGJvb3QgYW5pbWF0aW9uIHN0b3BwZWQgKyBwYWNrYWdlIG1hbmFnZXIgc2VydmluZyxcbiAgICogdmlhIHtAbGluayBjaGVja0RldmljZUlkbGV9KSBhbmQgcmV0dXJucyBhcyBzb29uIGFzIGl0IGlzIHNhdGlzZmllZC5cbiAgICpcbiAgICogQSAqKnJldXNlZCoqIGRldmljZSBuZWVkcyB0aGlzIGV2ZXJ5IGJpdCBhcyBtdWNoIGFzIGEgc3RhcnRlZCBvbmU6IGJlaW5nXG4gICAqIGxpc3RlZCBpbiBgYWRiIGRldmljZXNgIHNheXMgb25seSB0aGF0IGFkYmQgYW5zd2VycywgYW5kIHRoZSBjaHVybiBpdCBkb2VzXG4gICAqIG5vdCBnYXRlIGlzIHBhaWQgbGF0ZXIgYnkgd2hhdGV2ZXIgcG9sbHMgdGhlIFdlYlZpZXcuXG4gICAqXG4gICAqIEJlc3QtZWZmb3J0OiBpZiB0aGUgZ3Vlc3QgZG9lcyBub3QgcmVwb3J0IGlkbGUgd2l0aGluIHRoZSBidWRnZXQgaXQgbG9ncyBhXG4gICAqIHdhcm5pbmcgYW5kIHByb2NlZWRzIChhIHNsb3cgc2Vzc2lvbiBpcyBiZXR0ZXIgdGhhbiBhIGZhaWxlZCBydW4pLCBhbmQgYVxuICAgKiBidWRnZXQgb2YgYDBgIHNraXBzIHRoZSB3YWl0IGVudGlyZWx5LlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgZGV2aWNlIFVESUQgdG8gcG9sbC5cbiAgICogQHBhcmFtIHRpbWVvdXRJbk1pbGxpc2Vjb25kcyAtIE1heGltdW0gdGltZSB0byB3YWl0OyBgMGAgc2tpcHMgdGhlIHdhaXQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JEZXZpY2VJZGxlKGRldmljZUlkOiBzdHJpbmcsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyA8PSAwKSB7XG4gICAgICB0aGlzLmxvZyhgU2tpcHBpbmcgcG9zdC1ib290IGlkbGUgd2FpdCBmb3IgZGV2aWNlICR7ZGV2aWNlSWR9ICh0aW1lb3V0IGlzIDApLmApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IHN0YXJ0ICsgdGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgIHRoaXMubG9nKFxuICAgICAgYFdhaXRpbmcgZm9yIGRldmljZSAke2RldmljZUlkfSB0byBiZWNvbWUgaWRsZSAodGltZW91dDogJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcywgcG9sbDogJHtTdHJpbmcoREVWSUNFX0lETEVfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpfW1zKS4uLmBcbiAgICApO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgY29uc3QgW2Jvb3RBbmltYXRpb25Qcm9wZXJ0eSwgcGFja2FnZUxpc3RPdXRwdXRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICB0aGlzLmdldERldmljZVByb3BlcnR5KGRldmljZUlkLCAnaW5pdC5zdmMuYm9vdGFuaW0nKSxcbiAgICAgICAgdGhpcy5saXN0SW5zdGFsbGVkUGFja2FnZXMoZGV2aWNlSWQpXG4gICAgICBdKTtcblxuICAgICAgaWYgKGNoZWNrRGV2aWNlSWRsZSh7IGJvb3RBbmltYXRpb25Qcm9wZXJ0eSwgcGFja2FnZUxpc3RPdXRwdXQgfSkpIHtcbiAgICAgICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBpcyBpZGxlIGFmdGVyICR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMuYCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBub3QgaWRsZSB5ZXQgKGVsYXBzZWQ6ICR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMpLiBSZXRyeWluZy4uLmApO1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBERVZJQ0VfSURMRV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmxvZyhcbiAgICAgIGBXYXJuaW5nOiBkZXZpY2UgJHtkZXZpY2VJZH0gZGlkIG5vdCByZXBvcnQgaWRsZSB3aXRoaW4gJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tczsgcHJvY2VlZGluZyB3aXRoIHNlc3Npb24gZXN0YWJsaXNobWVudCBhbnl3YXkuYFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUnVucyBib3RoIHBvc3QtYm9vdCByZWFkaW5lc3MgZ2F0ZXMsIGluIG9yZGVyLCBvbiBhIGRldmljZSB0aGF0IGhhcyBqdXN0XG4gICAqIHJlcG9ydGVkIGBzeXMuYm9vdF9jb21wbGV0ZWRgLlxuICAgKlxuICAgKiBUaGUgc2luZ2xlIG93bmVyIG9mIFwid2hpY2ggZ2F0ZXMgYSBkZXZpY2UgcGFzc2VzIGJlZm9yZSBhIHNlc3Npb25cIiwgc28gdGhlXG4gICAqIHN0YXJ0ZWQtZGV2aWNlIGFuZCByZXVzZWQtZGV2aWNlIGJyYW5jaGVzIGNhbm5vdCBkaXZlcmdlIG9uIGl0IFx1MjAxNCB0aGUgYnJhbmNoXG4gICAqIHRoYXQgc2tpcHBlZCBhIGdhdGUgZW50aXJlbHkgaXMgdGhlIGhvbGUgYSByZXVzZWQgZGV2aWNlIG9uY2UgZmVsbCBpbnRvICgqKkw0MyoqKS5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSBVRElEIHRvIGdhdGUgb24uXG4gICAqIEBwYXJhbSB0aW1lb3V0cyAtIFRoZSB0d28gcmVzb2x2ZWQgYnVkZ2V0cy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckRldmljZVJlYWR5KGRldmljZUlkOiBzdHJpbmcsIHRpbWVvdXRzOiBEZXZpY2VSZWFkaW5lc3NUaW1lb3V0cyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMud2FpdEZvckRldmljZUlkbGUoZGV2aWNlSWQsIHRpbWVvdXRzLmRldmljZUlkbGVUaW1lb3V0SW5NaWxsaXNlY29uZHMpO1xuICAgIGF3YWl0IHRoaXMud2FpdEZvck5ldHdvcmtWYWxpZGF0ZWQoZGV2aWNlSWQsIHRpbWVvdXRzLm5ldHdvcmtSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogV2FpdHMgZm9yIGEgYm9vdGVkIGVtdWxhdG9yIHRvIGhhdmUgYSAqKnZhbGlkYXRlZCBkZWZhdWx0IG5ldHdvcmsqKiBiZWZvcmVcbiAgICogdGhlIHNlc3Npb24gaXMgZXN0YWJsaXNoZWQuXG4gICAqXG4gICAqIFRoZSBpZGxlIGdhdGUgYWJvdmUgc2F5cyBub3RoaW5nIGFib3V0IGNvbm5lY3Rpdml0eSwgYW5kIGl0cyB0d28gc2lnbmFscyBhcmVcbiAgICogc2F0aXNmaWVkIHdlbGwgYmVmb3JlIHRoZSBkZWZhdWx0IG5ldHdvcmsgaXMgY3JlYXRlZCBhbmQgdmFsaWRhdGVkIFx1MjAxNCB0aGF0XG4gICAqIGxhbmRzIH44MHMgaW50byBndWVzdCB1cHRpbWUsIHRlbnMgb2Ygc2Vjb25kcyBhZnRlciB0aGUgYm9vdCBmbGFnIG9uIGEgZmFzdFxuICAgKiBob3N0LiBBIHN1aXRlIHN0YXJ0ZWQgaW4gdGhhdCBnYXAgZG9lcyBub3QgbWVyZWx5IHJ1biBzbG93bHk6IGEgdGVzdFxuICAgKiB0aGF0IHJlYWNoZXMgdGhlIG5ldHdvcmsgcnVucyB0byBjb21wbGV0aW9uIGFnYWluc3QgYSBzaWxlbnRseSAqKmVtcHR5XG4gICAqIHJlc3VsdCoqLCB3aGljaCBubyBhc3NlcnRpb24gaW5zaWRlIHRoZSBzdWl0ZSBjYW4gZGlzdGluZ3Vpc2ggZnJvbSBhXG4gICAqIGdlbnVpbmVseSBlbXB0eSByZXNwb25zZS4gT25seSBhIHJlYWRpbmVzcyBnYXRlIGNhbiBjYXRjaCB0aGF0LCB3aGljaCBpcyB3aHlcbiAgICogdGhpcyBleGlzdHMgKHNlZSB7QGxpbmsgY2hlY2tOZXR3b3JrVmFsaWRhdGVkfSwgd2hpY2ggYWxzbyByZWNvcmRzIHdoeSB0aGVcbiAgICogdGhyZWUgb2J2aW91cyBjb25uZWN0aXZpdHkgcHJvYmVzIGFyZSBhbGwgd3JvbmcpLlxuICAgKlxuICAgKiBCZXN0LWVmZm9ydCwgb24gdGhlIHNhbWUgY29udHJhY3QgYXMgdGhlIGlkbGUgZ2F0ZTogaWYgbm8gdmFsaWRhdGVkIG5ldHdvcmtcbiAgICogYXBwZWFycyB3aXRoaW4gdGhlIGJ1ZGdldCBpdCBsb2dzIGEgd2FybmluZyAqKm5hbWluZyB0aGUgbWlzc2luZyBuZXR3b3JrKipcbiAgICogYW5kIHByb2NlZWRzIChhbiBvZmZsaW5lIEFWRCBpcyBzdGlsbCBhIHVzYWJsZSBvbmUgZm9yIHN1aXRlcyB0aGF0IG5ldmVyXG4gICAqIHRvdWNoIHRoZSBuZXR3b3JrKSwgYW5kIGEgYnVkZ2V0IG9mIGAwYCBza2lwcyB0aGUgd2FpdCBlbnRpcmVseS4gVGhlIHdhcm5pbmdcbiAgICogaXMgdGhlIHBvaW50IFx1MjAxNCB0aGUgZmFpbHVyZSBpdCBwcmVjZWRlcyBvdGhlcndpc2Ugc3VyZmFjZXMgYXMgYSBiYXJlXG4gICAqIGBXZWJEcml2ZXJFcnJvcjogc2NyaXB0IHRpbWVvdXRgIG5hbWluZyB0aGUgdHJhbnNwb3J0LCB3aGljaCByZWFkcyBhcyBhXG4gICAqIGhhcm5lc3MgZGVmZWN0IHJhdGhlciB0aGFuIGEgbWlzc2luZyByb3V0ZS5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZUlkIC0gVGhlIGRldmljZSBVRElEIHRvIHBvbGwuXG4gICAqIEBwYXJhbSB0aW1lb3V0SW5NaWxsaXNlY29uZHMgLSBNYXhpbXVtIHRpbWUgdG8gd2FpdDsgYDBgIHNraXBzIHRoZSB3YWl0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yTmV0d29ya1ZhbGlkYXRlZChkZXZpY2VJZDogc3RyaW5nLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aW1lb3V0SW5NaWxsaXNlY29uZHMgPD0gMCkge1xuICAgICAgdGhpcy5sb2coYFNraXBwaW5nIG5ldHdvcmstcmVhZHkgd2FpdCBmb3IgZGV2aWNlICR7ZGV2aWNlSWR9ICh0aW1lb3V0IGlzIDApLmApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IHN0YXJ0ICsgdGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgIHRoaXMubG9nKFxuICAgICAgYFdhaXRpbmcgZm9yIGRldmljZSAke2RldmljZUlkfSB0byByZXBvcnQgYSB2YWxpZGF0ZWQgbmV0d29yayAodGltZW91dDogJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcywgcG9sbDogJHtTdHJpbmcoTkVUV09SS19SRUFEWV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyl9bXMpLi4uYFxuICAgICk7XG5cbiAgICBsZXQgcHJvYmVGYWlsdXJlQ291bnQgPSAwO1xuICAgIGxldCBsYXN0RmFpbHVyZVJlYXNvbiA9ICcnO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgY29uc3QgcHJvYmUgPSBhd2FpdCB0aGlzLmR1bXBDb25uZWN0aXZpdHkoZGV2aWNlSWQpO1xuICAgICAgY29uc3QgZWxhcHNlZCA9IFN0cmluZyhEYXRlLm5vdygpIC0gc3RhcnQpO1xuICAgICAgY29uc3QgY29ubmVjdGl2aXR5T3V0cHV0ID0gcHJvYmUub3V0cHV0O1xuXG4gICAgICBpZiAoY29ubmVjdGl2aXR5T3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcHJvYmVGYWlsdXJlQ291bnQrKztcbiAgICAgICAgbGFzdEZhaWx1cmVSZWFzb24gPSBwcm9iZS5mYWlsdXJlUmVhc29uID8/ICd1bmtub3duIGFkYiBmYWlsdXJlJztcbiAgICAgICAgdGhpcy5sb2coXG4gICAgICAgICAgYERldmljZSAke2RldmljZUlkfSBjb25uZWN0aXZpdHkgcHJvYmUgZmFpbGVkIChlbGFwc2VkOiAke2VsYXBzZWR9bXMpOiAke2xhc3RGYWlsdXJlUmVhc29ufS4gUmV0cnlpbmcuLi5gXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGNoZWNrTmV0d29ya1ZhbGlkYXRlZCh7IGNvbm5lY3Rpdml0eU91dHB1dCB9KSkge1xuICAgICAgICB0aGlzLmxvZyhgRGV2aWNlICR7ZGV2aWNlSWR9IGhhcyBhIHZhbGlkYXRlZCBuZXR3b3JrIGFmdGVyICR7ZWxhcHNlZH1tcy5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBoYXMgbm8gdmFsaWRhdGVkIG5ldHdvcmsgeWV0IChlbGFwc2VkOiAke2VsYXBzZWR9bXMpLiBSZXRyeWluZy4uLmApO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIE5FVFdPUktfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBUd28gZGlmZmVyZW50IGRpYWdub3NlcywgbmV2ZXIgbWVyZ2VkIGludG8gb25lIHNlbnRlbmNlOiBhIGd1ZXN0IHRoYXRcbiAgICAgKiBhbnN3ZXJlZCBhbmQgcmVwb3J0ZWQgbm8gbmV0d29yayBpcyBvZmZsaW5lLCB3aGlsZSBhIGd1ZXN0IHRoYXQgbmV2ZXJcbiAgICAgKiBhbnN3ZXJlZCBzYXlzIG5vdGhpbmcgYWJvdXQgaXRzIG5ldHdvcmsgYW5kIGV2ZXJ5dGhpbmcgYWJvdXQgaXRzZWxmLlxuICAgICAqL1xuICAgIGNvbnN0IGRpYWdub3NpcyA9IHByb2JlRmFpbHVyZUNvdW50ID4gMFxuICAgICAgPyBgJHtTdHJpbmcocHJvYmVGYWlsdXJlQ291bnQpfSBvZiBpdHMgY29ubmVjdGl2aXR5IHByb2JlcyBmYWlsZWQsIGxhc3QgXCIke2xhc3RGYWlsdXJlUmVhc29ufVwiLCBzbyB0aGUgZ3Vlc3QgbWF5IGJlIHdlZGdlZCByYXRoZXIgdGhhbiBvZmZsaW5lYFxuICAgICAgOiAnaXQgYW5zd2VyZWQgZXZlcnkgcHJvYmUgYW5kIHJlcG9ydGVkIG5vIHZhbGlkYXRlZCBkZWZhdWx0IG5ldHdvcmsnO1xuICAgIHRoaXMubG9nKFxuICAgICAgYFdhcm5pbmc6IGRldmljZSAke2RldmljZUlkfSByZXBvcnRlZCBubyB2YWxpZGF0ZWQgbmV0d29yayB3aXRoaW4gJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcyAoJHtkaWFnbm9zaXN9KTsgYFxuICAgICAgICArICdwcm9jZWVkaW5nIHdpdGggc2Vzc2lvbiBlc3RhYmxpc2htZW50IGFueXdheS4gVGVzdHMgdGhhdCByZWFjaCB0aGUgbmV0d29yayB3aWxsIHJ1biBhZ2FpbnN0IGEgZGV2aWNlIHdpdGggbm8gcm91dGUsICdcbiAgICAgICAgKyAnYW5kIG1heSByZXR1cm4gRU1QVFkgUkVTVUxUUyByYXRoZXIgdGhhbiBmYWlsIFx1MjAxNCByZWFkIGFueSBlbXB0eS1sb29raW5nIGFzc2VydGlvbiBmYWlsdXJlIGJlbG93IGFzIGEgbWlzc2luZyBuZXR3b3JrIGZpcnN0LidcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhaXRzIGZvciB0aGUgZW11bGF0b3IgdGhpcyBydW4gbGF1bmNoZWQgdG8gcHJvZHVjZSBhIGRldmljZSwgYW5kIGZvciB0aGF0XG4gICAqIGRldmljZSB0byBiZWNvbWUgdXNhYmxlLlxuICAgKlxuICAgKiBPbmx5IGFuIGVtdWxhdG9yIHNlcnZpbmcgYGF2ZE5hbWVgIGlzIHRha2VuOiBhIGhhbmRzZXQsIG9yIGFub3RoZXIgZW11bGF0b3IsXG4gICAqIHRoYXQgY29tZXMgb25saW5lIGR1cmluZyB0aGUgYm9vdCBpcyBsb2dnZWQgYW5kIGlnbm9yZWQgXHUyMDE0IHNlZVxuICAgKiBgbGF1bmNoZWQtZGV2aWNlLXNlbGVjdGlvbi50c2AuXG4gICAqXG4gICAqIEBwYXJhbSBhdmROYW1lIC0gVGhlIEFWRCB0aGlzIHJ1biBsYXVuY2hlZC5cbiAgICogQHBhcmFtIGRldmljZUlkc0JlZm9yZSAtIFRoZSBkZXZpY2VzIGNvbm5lY3RlZCBiZWZvcmUgdGhlIGxhdW5jaC5cbiAgICogQHBhcmFtIGVtdWxhdG9yIC0gVGhlIGxhdW5jaGVyLCBwb2xsZWQgZm9yIGFuIGVhcmx5IGV4aXQuXG4gICAqIEBwYXJhbSB0aW1lb3V0cyAtIFRoZSB0d28gcG9zdC1ib290IHJlYWRpbmVzcyBidWRnZXRzLlxuICAgKiBAcGFyYW0gb25EZXZpY2VBcHBlYXJlZCAtIENhbGxlZCB3aXRoIHRoZSBuZXcgZGV2aWNlIHRoZSBtb21lbnQgaXQgaXMgbGlzdGVkLCBiZWZvcmUgdGhlIHJlYWRpbmVzcyBnYXRlcy5cbiAgICogQHJldHVybnMgVGhlIG5ldyBkZXZpY2UncyBpZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvck5ld0RldmljZShcbiAgICBhdmROYW1lOiBzdHJpbmcsXG4gICAgZGV2aWNlSWRzQmVmb3JlOiBzdHJpbmdbXSxcbiAgICBlbXVsYXRvcjogUHJvY2Vzc0xhdW5jaCxcbiAgICB0aW1lb3V0czogRGV2aWNlUmVhZGluZXNzVGltZW91dHMsXG4gICAgb25EZXZpY2VBcHBlYXJlZDogKGRldmljZUlkOiBzdHJpbmcpID0+IHZvaWRcbiAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBXYWl0aW5nIGZvciBhIG5ldyBkZXZpY2UgdG8gYXBwZWFyIGluIEFEQiAodGltZW91dDogJHtTdHJpbmcoRU1VTEFUT1JfQk9PVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMsIHBvbGw6ICR7U3RyaW5nKEVNVUxBVE9SX0JPT1RfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpfW1zKS4uLmBcbiAgICApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIEVNVUxBVE9SX0JPT1RfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG5cbiAgICAvKlxuICAgICAqIEVhY2ggZGV2aWNlIGlzIHJlcG9ydGVkIG9uY2UsIG5vdCBvbiBldmVyeSBwb2xsLiBBIGRldmljZSBydWxlZCBvdXQgc3RheXNcbiAgICAgKiBydWxlZCBvdXQ6IGEgaGFuZHNldCBuZXZlciBiZWNvbWVzIGFuIGVtdWxhdG9yLCBhbmQgYW4gZW11bGF0b3Igc2VydmluZ1xuICAgICAqIGFub3RoZXIgQVZEIGlzIG5vdCBnb2luZyB0byBzdGFydCBzZXJ2aW5nIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGNvbnN0IGlnbm9yZWREZXZpY2VJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IHsgZW11bGF0b3JEZXZpY2VJZHMsIG5vbkVtdWxhdG9yRGV2aWNlSWRzIH0gPSBzcGxpdE5ld0RldmljZXMoe1xuICAgICAgICBjb25uZWN0ZWREZXZpY2VJZHM6IGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkRGV2aWNlSWRzKCksXG4gICAgICAgIGRldmljZUlkc0JlZm9yZVxuICAgICAgfSk7XG5cbiAgICAgIGZvciAoY29uc3QgZGV2aWNlSWQgb2Ygbm9uRW11bGF0b3JEZXZpY2VJZHMpIHtcbiAgICAgICAgaWYgKGlnbm9yZWREZXZpY2VJZHMuaGFzKGRldmljZUlkKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWdub3JlZERldmljZUlkcy5hZGQoZGV2aWNlSWQpO1xuICAgICAgICB0aGlzLmxvZyhgRGV2aWNlICR7ZGV2aWNlSWR9IGNhbWUgb25saW5lIGR1cmluZyB0aGUgZW11bGF0b3IgYm9vdCBidXQgaXMgbm90IGFuIGVtdWxhdG9yOyBpZ25vcmluZyBpdC5gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FuZGlkYXRlczogTGF1bmNoZWREZXZpY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCBkZXZpY2VJZCBvZiBlbXVsYXRvckRldmljZUlkcykge1xuICAgICAgICBpZiAoIWlnbm9yZWREZXZpY2VJZHMuaGFzKGRldmljZUlkKSkge1xuICAgICAgICAgIGNhbmRpZGF0ZXMucHVzaCh7IGRldmljZUlkLCBwcm9iZWRBdmROYW1lOiBhd2FpdCB0aGlzLnByb2JlQXZkTmFtZShkZXZpY2VJZCkgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbGF1bmNoZWQgPSByZXNvbHZlTGF1bmNoZWREZXZpY2UoeyBhdmROYW1lLCBjYW5kaWRhdGVzIH0pO1xuXG4gICAgICBmb3IgKGNvbnN0IGRldmljZUlkIG9mIGxhdW5jaGVkLm90aGVyQXZkRGV2aWNlSWRzKSB7XG4gICAgICAgIGlnbm9yZWREZXZpY2VJZHMuYWRkKGRldmljZUlkKTtcbiAgICAgICAgdGhpcy5sb2coYERldmljZSAke2RldmljZUlkfSBjYW1lIG9ubGluZSBkdXJpbmcgdGhlIGVtdWxhdG9yIGJvb3QgYnV0IHNlcnZlcyBhbm90aGVyIEFWRCwgbm90IFwiJHthdmROYW1lfVwiOyBpZ25vcmluZyBpdC5gKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGxhdW5jaGVkLnVuYW5zd2VyZWREZXZpY2VJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmxvZyhgRGV2aWNlKHMpICR7bGF1bmNoZWQudW5hbnN3ZXJlZERldmljZUlkcy5qb2luKCcsICcpfSBkaWQgbm90IHNheSB3aGljaCBBVkQgdGhleSBzZXJ2ZSB5ZXQ7IGFza2luZyBhZ2FpbiBvbiB0aGUgbmV4dCBwb2xsLmApO1xuICAgICAgfVxuXG4gICAgICBpZiAobGF1bmNoZWQuZGV2aWNlSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBhY3R1YWxEZXZpY2VJZCA9IGxhdW5jaGVkLmRldmljZUlkO1xuICAgICAgICB0aGlzLmxvZyhgRGV2aWNlICR7YWN0dWFsRGV2aWNlSWR9IGFwcGVhcmVkIGluIEFEQiwgc2VydmluZyBBVkQgXCIke2F2ZE5hbWV9XCI7IHdhaXRpbmcgZm9yIGJvb3QgdG8gY29tcGxldGUuLi5gKTtcbiAgICAgICAgb25EZXZpY2VBcHBlYXJlZChhY3R1YWxEZXZpY2VJZCk7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckJvb3QoYWN0dWFsRGV2aWNlSWQsIGRlYWRsaW5lLCBlbXVsYXRvcik7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckRldmljZVJlYWR5KGFjdHVhbERldmljZUlkLCB0aW1lb3V0cyk7XG4gICAgICAgIGF3YWl0IHRoaXMud2FrZVNjcmVlbihhY3R1YWxEZXZpY2VJZCk7XG4gICAgICAgIHJldHVybiBhY3R1YWxEZXZpY2VJZDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhpdEluZm8gPSBlbXVsYXRvci5yZWFkRXhpdEluZm8oKTtcbiAgICAgIGlmIChleGl0SW5mbykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYnVpbGRQcm9jZXNzRXhpdE1lc3NhZ2Uoe1xuICAgICAgICAgIGV4aXRJbmZvLFxuICAgICAgICAgIG91dHB1dDogZW11bGF0b3IucmVhZE91dHB1dCgpLFxuICAgICAgICAgIG91dHB1dExhYmVsOiAnRW11bGF0b3Igb3V0cHV0JyxcbiAgICAgICAgICBzdWJqZWN0OiAnQW5kcm9pZCBlbXVsYXRvcidcbiAgICAgICAgfSkpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEVNVUxBVE9SX0JPT1RfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQXMgaW4gYHdhaXRGb3JCb290YDogYW4gZW11bGF0b3IgdGhhdCBoYW5ncyBoYXMgYXMgbXVjaCB0byBzYXkgYXMgb25lIHRoYXQgZGllcy5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYXBwZW5kUHJvY2Vzc091dHB1dFRhaWwoXG4gICAgICBgTm8gbmV3IGVtdWxhdG9yIGRldmljZSBhcHBlYXJlZCB3aXRoaW4gJHtTdHJpbmcoRU1VTEFUT1JfQk9PVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyl9bXMuYCxcbiAgICAgIHsgb3V0cHV0OiBlbXVsYXRvci5yZWFkT3V0cHV0KCksIG91dHB1dExhYmVsOiAnRW11bGF0b3Igb3V0cHV0JyB9XG4gICAgKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdha2VTY3JlZW4oZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nKGBXYWtpbmcgc2NyZWVuIG9uIGRldmljZSAke2RldmljZUlkfS4uLmApO1xuXG4gICAgYXdhaXQgdGhpcy5zZW5kS2V5RXZlbnQoZGV2aWNlSWQsIEtFWUNPREVfV0FLRVVQLCAnd2FrZSBzY3JlZW4nKTtcbiAgICBhd2FpdCB0aGlzLnNlbmRLZXlFdmVudChkZXZpY2VJZCwgS0VZQ09ERV9NRU5VLCAnZGlzbWlzcyBsb2NrIHNjcmVlbicpO1xuXG4gICAgdGhpcy5sb2coYFNjcmVlbiB3YWtlIGNvbXBsZXRlIG9uIGRldmljZSAke2RldmljZUlkfS5gKTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdHJhbnNwb3J0IGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUcmFuc3BvcnQgY29uZmlndXJhdGlvbi4gRGVmYXVsdHMgdG8gYW4gb3duZWQgZGVza3RvcCBDRFAgdHJhbnNwb3J0LlxuICogQHJldHVybnMgQSBuZXcgdHJhbnNwb3J0IGluc3RhbmNlLlxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JzaWRpYW4tZGV2LXV0aWxzL3BhcmFtcy1vcHRpb25zLW5hbWUtbWF0Y2ggLS0gUGVybWFuZW50OiBgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zYCBpcyBvbmUgdHJhbnNwb3J0IG9wdGlvbnMgYmFnIHJlYWQgYnkgZml2ZSBoZWxwZXJzLCBzbyBubyBwZXItb3duZXIgbmFtZSBjYW4gc2F0aXNmeSB0aGVtIGFsbC5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyhvcHRpb25zPzogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zKTogUHJvbWlzZTxPYnNpZGlhblRyYW5zcG9ydD4ge1xuICBjb25zdCB0eXBlID0gb3B0aW9ucz8udHlwZSA/PyBERUZBVUxUX1RSQU5TUE9SVF9UWVBFO1xuXG4gIGlmICghb3B0aW9ucyB8fCBvcHRpb25zLnR5cGUgPT09ICdvYnNpZGlhbi1jZHAnKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUNkcFRyYW5zcG9ydChvcHRpb25zKTtcbiAgfVxuXG4gIGNvbnN0IGZhY3RvcnkgPSBuZXcgQXBwaXVtVHJhbnNwb3J0RmFjdG9yeSh0eXBlKTtcbiAgcmV0dXJuIGZhY3RvcnkuY3JlYXRlKG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBjYWNoZWQgdHJhbnNwb3J0IGluc3RhbmNlLCBjcmVhdGluZyBvbmUgZnJvbSB0aGUgZ2l2ZW4gb3B0aW9uc1xuICogaWYgbm90IGFscmVhZHkgY2FjaGVkLlxuICpcbiAqIFRoZSB0cmFuc3BvcnQgaXMgY2FjaGVkIHBlciB3b3JrZXIgcHJvY2VzcyBzbyBXZWJTb2NrZXQvQXBwaXVtIHNlc3Npb25zXG4gKiBhcmUgcmV1c2VkIGFjcm9zcyBjYWxscyB3aXRoaW4gdGhlIHNhbWUgdGVzdCB3b3JrZXIuXG4gKlxuICogVGhpcyBpcyB0aGUgc2luZ2xlIGVudHJ5IHBvaW50IGV2ZXJ5IHdvcmtlci1zaWRlIGNhbGxlciB1c2VzIGZvciB0aGUgKiphbWJpZW50KipcbiAqIHRyYW5zcG9ydCwgc28gaXQgaXMgYWxzbyB3aGVyZSBhIGZhaWxlZCBnbG9iYWwgc2V0dXAgaXMgdHVybmVkIGludG8gYSBmYWlsaW5nIHRlc3QuXG4gKiBBIGZhaWxlZCBzZXR1cCBwdWJsaXNoZXMgbm8gdHJhbnNwb3J0IG9wdGlvbnMsIGFuZCBgdW5kZWZpbmVkYCBvcHRpb25zIG1lYW4gdGhlIG93bmVkXG4gKiAqKmRlc2t0b3AqKiBDRFAgZGVmYXVsdCBcdTIwMTQgc28gd2l0aG91dCB0aGlzIGd1YXJkIGFuIEFuZHJvaWQgcHJvamVjdCdzIHN1aXRlIHdvdWxkIHJ1blxuICogb24gZGVza3RvcCBhbmQgdGhlbiBkaWUgb24gYW4gdW5yZWxhdGVkIENEUCBlcnJvciwgaGlkaW5nIHRoZSByZWFsIGNhdXNlICgqKkw5KiopLlxuICogVGhlIHNldHVwIHBhdGggaXRzZWxmIGlzIHVuYWZmZWN0ZWQ6IGBjb3JlU2V0dXBgIGJ1aWxkcyBpdHMgdHJhbnNwb3J0IHRocm91Z2hcbiAqIHtAbGluayBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9uc30gd2l0aCBleHBsaWNpdCBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gVHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24uIERlZmF1bHRzIHRvIGFuIG93bmVkIGRlc2t0b3AgQ0RQIHRyYW5zcG9ydC5cbiAqIEByZXR1cm5zIFRoZSBjYWNoZWQgb3IgbmV3bHkgY3JlYXRlZCB0cmFuc3BvcnQuXG4gKiBAdGhyb3dzIHtJbnRlZ3JhdGlvblNldHVwRmFpbGVkRXJyb3J9IFdoZW4gdGhpcyBwcm9qZWN0J3MgZ2xvYmFsIHNldHVwIGZhaWxlZC5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG9ic2lkaWFuLWRldi11dGlscy9wYXJhbXMtb3B0aW9ucy1uYW1lLW1hdGNoIC0tIFBlcm1hbmVudDogYE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9uc2AgaXMgb25lIHRyYW5zcG9ydCBvcHRpb25zIGJhZyByZWFkIGJ5IGZpdmUgaGVscGVycywgc28gbm8gcGVyLW93bmVyIG5hbWUgY2FuIHNhdGlzZnkgdGhlbSBhbGwuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0T3JDcmVhdGVUcmFuc3BvcnQob3B0aW9ucz86IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgY29uc3Qgc2V0dXBFcnJvciA9IGdldFNldHVwRXJyb3IoKTtcbiAgaWYgKHNldHVwRXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgSW50ZWdyYXRpb25TZXR1cEZhaWxlZEVycm9yKHNldHVwRXJyb3IpO1xuICB9XG5cbiAgaWYgKGNhY2hlZFRyYW5zcG9ydCkge1xuICAgIHJldHVybiBjYWNoZWRUcmFuc3BvcnQ7XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyhvcHRpb25zKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXMgLS0gU2luZ2xlLXRocmVhZGVkIHdvcmtlcjsgbm8gY29uY3VycmVudCB3cml0ZXMuXG4gIGNhY2hlZFRyYW5zcG9ydCA9IHJlc3VsdDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBTdG9wcyBldmVyeSBlbXVsYXRvciB0aGlzIGhhcm5lc3Mgc3RhcnRlZCB3aG9zZSBydW4gY2FuIG5vIGxvbmdlciBzdG9wIGl0XG4gKiBpdHNlbGYsIHZlcmlmeWluZyBlYWNoIHN0b3AuXG4gKlxuICogRm9yIHRoZSBnbG9iYWwgdGVhcmRvd24gb2YgYSBWaXRlc3QgcHJvamVjdCB3aG9zZSB0cmFuc3BvcnQgbGl2ZXMgaW4gaXRzIHRlc3RcbiAqIHdvcmtlcnMgcmF0aGVyIHRoYW4gaW4gYSB0cmFuc3BvcnQgZ2xvYmFsIHNldHVwOiB0aGUgd29ya2VyIGF1dG8tc3RhcnRzIHRoZVxuICogZW11bGF0b3IsIFZpdGVzdCBlbmRzIHRoZSB3b3JrZXIgd2l0aG91dCBhIHRlYXJkb3duLCBhbmQgb25seSB0aGUgbWFpblxuICogcHJvY2VzcydzIHRlYXJkb3duIGdldHMgYSB0dXJuIFx1MjAxNCBob2xkaW5nIG5vIGhhbmRsZSB0byB0aGUgZW11bGF0b3IsIGJ1dCBhYmxlXG4gKiB0byBmaW5kIGl0IGJ5IGl0cyBtYXJrZXIgKGBlbXVsYXRvci1tYXJrZXIudHNgKS5cbiAqXG4gKiBDYWxsIGl0IHdoaWxlIGhvbGRpbmcgdGhlIGBhbmRyb2lkYCBzZXR1cCBsb2NrIChMNyk6IHRoYXQgaXMgd2hhdCBndWFyYW50ZWVzXG4gKiBubyBvdGhlciBBbmRyb2lkIHJ1biBpcyB1c2luZyBhIG1hcmtlZCBlbXVsYXRvci4gRW11bGF0b3JzIHdpdGhvdXQgYSBtYXJrZXIgYXJlXG4gKiBuZXZlciB0b3VjaGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RvcEhhcm5lc3NTdGFydGVkRW11bGF0b3JzKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCByZWNsYWltZXIgPSBuZXcgRW11bGF0b3JSZWNsYWltZXIoKG1lc3NhZ2UpID0+IHtcbiAgICBsb2coYFt0cmFuc3BvcnQtZmFjdG9yeToke0FORFJPSURfQVBQSVVNX1RSQU5TUE9SVF9UWVBFfV0gJHttZXNzYWdlfWApO1xuICB9KTtcbiAgYXdhaXQgcmVjbGFpbWVyLnJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9ycyh7IHNjb3BlOiAnZW5kLW9mLXJ1bicgfSk7XG59XG5cbi8qKlxuICogVmVyaWZpZXMgdGhlIGhhcm5lc3Mtb3duZWQgaW5zdGFuY2UgYSB3b3JrZXIgd2FzIHRvbGQgdG8gYXR0YWNoIHRvIGlzIHN0aWxsXG4gKiBzZXJ2aW5nIENEUCwgYmVmb3JlIGhhbmRpbmcgYmFjayBhIHRyYW5zcG9ydCB0aGF0IGNhbiBvbmx5IGZhaWwgYWdhaW5zdCBpdC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBvbmNlLXBlci1maWxlIGNoZWNrOiB0cmFuc3BvcnQgY3JlYXRpb24gaXMgY2FjaGVkIHBlciB3b3JrZXIsIHNvXG4gKiBhIGxpdmUgaW5zdGFuY2UgcGF5cyBvbmUgbG9vcGJhY2sgcmVxdWVzdCBwZXIgdGVzdCBmaWxlIGFuZCBhIGRlYWQgb25lIHR1cm5zXG4gKiB0aGUgd2hvbGUgZmlsZSBpbnRvIGEgc2luZ2xlIG5hbWVkIGVycm9yLCByYWlzZWQgYmVmb3JlIHRoZSBmaXJzdCB0ZXN0LiBJdFxuICogcmVwbGFjZXMgdGhlIGBFQ09OTlJFRlVTRURgLXBlci1maWxlIGNhc2NhZGUgYSBtaWQtcnVuIGRlYXRoIHVzZWQgdG8gcHJvZHVjZSBcdTIwMTRcbiAqIGFuZCB0aGUgcGVyLWZpbGUgcHJvYmUgY29uc3VtZXJzIHdlcmUgd3JpdGluZyBpbnRvIHRoZWlyIG93biBgc2V0dXBGaWxlc2AgdG9cbiAqIGdldCB0aGUgc2FtZSBlZmZlY3QuXG4gKlxuICogT25seSBmb3IgdGhlIGhhcm5lc3MncyBvd24gaW5zdGFuY2VzOiBhIHBsYWluIGF0dGFjaCB0YXJnZXRzIGEgZm9yZWlnblxuICogT2JzaWRpYW4gd2hvc2UgYWJzZW5jZSBpcyB0aGUgdXNlcidzIHRvIHJlc29sdmUsIGFuZCBgcHJlZmxpZ2h0Q2hlY2tgIGFscmVhZHlcbiAqIGhhcyBhIHN0b3J5IGZvciBpdC5cbiAqXG4gKiBAcGFyYW0gaG9zdCAtIFRoZSBDRFAgaG9zdCB0byBwcm9iZS5cbiAqIEBwYXJhbSBwb3J0IC0gVGhlIENEUCBwb3J0IHRvIHByb2JlLlxuICogQHRocm93cyB7T3duZWRJbnN0YW5jZUV4aXRlZEVycm9yfSBXaGVuIG5vdGhpbmcgaXMgc2VydmluZyBDRFAgb24gdGhlIHBvcnQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGFzc2VydEhhcm5lc3NPd25lZEluc3RhbmNlSXNTZXJ2aW5nKGhvc3Q6IHN0cmluZywgcG9ydDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGNkcFVybCA9IGBodHRwOi8vJHtob3N0fToke1N0cmluZyhwb3J0KX1gO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYCR7Y2RwVXJsfS9qc29uL3ZlcnNpb25gKTtcbiAgICBhd2FpdCByZXNwb25zZS5ib2R5Py5jYW5jZWwoKTtcbiAgICByZXR1cm47XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5vdGhpbmcgaXMgbGlzdGVuaW5nIFx1MjAxNCB0aGUgaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBsYXVuY2hlZCBpcyBnb25lLlxuICB9XG5cbiAgdGhyb3cgYnVpbGRPd25lZEluc3RhbmNlRXhpdGVkRXJyb3JGcm9tTWFya2VyKGNkcFVybCwgcmVhZE93bmVkSW5zdGFuY2VFeGl0TWFya2VyKHBvcnQpKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIHBsYXRmb3JtJ3MgXCJ3aG8gaG9sZHMgdGhpcyBwb3J0XCIgcXVlcnkuXG4gKlxuICogYG5ldHN0YXRgIGNhbm5vdCBmaWx0ZXIgYnkgcG9ydCwgc28gdGhlIHdob2xlIHRhYmxlIGNvbWVzIGJhY2sgYW5kIHRoZSBwYXJzZXJcbiAqIGRvZXMgdGhlIG1hdGNoaW5nOyBgbHNvZmAgZmlsdGVycyBzZXJ2ZXItc2lkZSBhbmQgYW5zd2VycyB3aXRoIGJhcmUgUElEcy5cbiAqXG4gKiBAcGFyYW0gcG9ydCAtIFRoZSBwb3J0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgVGhlIGNvbW1hbmQgYW5kIGFyZ3VtZW50cyB0byBydW4uXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkUG9ydE93bmVyUXVlcnkocG9ydDogbnVtYmVyKTogSG9zdENvbW1hbmRRdWVyeSB7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInXG4gICAgPyB7IGNvbW1hbmQ6ICduZXRzdGF0JywgY29tbWFuZEFyZ3VtZW50czogWyctYW5vJ10gfVxuICAgIDogeyBjb21tYW5kOiAnbHNvZicsIGNvbW1hbmRBcmd1bWVudHM6IFsnLXRpJywgYHRjcDoke1N0cmluZyhwb3J0KX1gXSB9O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkZXNrdG9wIENEUCB0cmFuc3BvcnQuIFdoZW4gYW4gZXhwbGljaXQgYHBvcnRgIGlzIGdpdmVuIHRoZVxuICogdHJhbnNwb3J0IGF0dGFjaGVzIHRvIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiBvbiB0aGF0IHBvcnQ7IG90aGVyd2lzZSBpdFxuICogbGF1bmNoZXMgYW5kIG93bnMgYW4gaXNvbGF0ZWQgaW5zdGFuY2UgKHRoZSBkZWZhdWx0LCBoZXJtZXRpYyBtb2RlKS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENEUCB0cmFuc3BvcnQgb3B0aW9ucy5cbiAqIEByZXR1cm5zIEEgY29uZmlndXJlZCBDRFAgdHJhbnNwb3J0LlxuICovXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVDZHBUcmFuc3BvcnQob3B0aW9ucz86IE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgaWYgKG9wdGlvbnM/LnBvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IG93bmVkU3VmZml4ID0gb3B0aW9ucy5pc0hhcm5lc3NPd25lZEluc3RhbmNlID8gJyAoaGFybmVzcy1vd25lZCknIDogJyc7XG4gICAgbG9nKGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBBdHRhY2hpbmcgdG8gcnVubmluZyBPYnNpZGlhbiR7b3duZWRTdWZmaXh9IChob3N0PSR7b3B0aW9ucy5ob3N0ID8/ICdsb2NhbGhvc3QnfSwgcG9ydD0ke1N0cmluZyhvcHRpb25zLnBvcnQpfSlgKTtcbiAgICBpZiAob3B0aW9ucy5pc0hhcm5lc3NPd25lZEluc3RhbmNlKSB7XG4gICAgICBhd2FpdCBhc3NlcnRIYXJuZXNzT3duZWRJbnN0YW5jZUlzU2VydmluZyhvcHRpb25zLmhvc3QgPz8gJ2xvY2FsaG9zdCcsIG9wdGlvbnMucG9ydCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGVza3RvcENkcFRyYW5zcG9ydChub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8RGVza3RvcENkcFRyYW5zcG9ydENvbmZpZz4oe1xuICAgICAgY2RwSG9zdDogb3B0aW9ucy5ob3N0LFxuICAgICAgY2RwUG9ydDogb3B0aW9ucy5wb3J0LFxuICAgICAgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogb3B0aW9ucy5jb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzLFxuICAgICAgaXNIYXJuZXNzT3duZWRJbnN0YW5jZTogb3B0aW9ucy5pc0hhcm5lc3NPd25lZEluc3RhbmNlXG4gICAgfSkpO1xuICB9XG5cbiAgbG9nKCdbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBDcmVhdGluZyBvd25lZCBpc29sYXRlZCBPYnNpZGlhbiBpbnN0YW5jZScpO1xuICAvLyBCZWZvcmUgYHJlc29sdmVPd25lZEluc3RhbmNlQ29uZmlnYCwgd2hpY2ggbWF5IGRvd25sb2FkIGFuZCBjYWNoZSBhbiBpbnN0YWxsZXIgc2hlbGw6XG4gIC8vIEEgc3RydWN0dXJhbGx5IGludmFsaWQgY29uZmlnIGZvbGRlciBuYW1lIGNhbm5vdCBiZWNvbWUgdmFsaWQgbGF0ZXIsIHNvIHBheWluZyBmb3IgYVxuICAvLyBwcm92aXNpb25pbmcgcm91bmQtdHJpcCBmaXJzdCB3b3VsZCBvbmx5IGRlbGF5IHRoZSBzYW1lIGZhaWx1cmUuXG4gIGlmIChvcHRpb25zPy5jb25maWdEaXJlY3RvcnkgIT09IHVuZGVmaW5lZCkge1xuICAgIGFzc2VydFZhbGlkQ29uZmlnRGlyZWN0b3J5KG9wdGlvbnMuY29uZmlnRGlyZWN0b3J5KTtcbiAgfVxuICBjb25zdCBvd25lZEluc3RhbmNlID0gYXdhaXQgcmVzb2x2ZU93bmVkSW5zdGFuY2VDb25maWcob3B0aW9ucyk7XG4gIHJldHVybiBuZXcgRGVza3RvcENkcFRyYW5zcG9ydChub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8RGVza3RvcENkcFRyYW5zcG9ydENvbmZpZz4oe1xuICAgIGNkcEhvc3Q6IG9wdGlvbnM/Lmhvc3QsXG4gICAgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogb3B0aW9ucz8uY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgICBjb25maWdEaXJlY3Rvcnk6IG9wdGlvbnM/LmNvbmZpZ0RpcmVjdG9yeSxcbiAgICBkZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHM6IHJlc29sdmVEZWFkQm9vdEdyYWNlSW5NaWxsaXNlY29uZHMob3B0aW9ucyksXG4gICAgaXNPYnNpZGlhbkFwcFZpc2libGU6IG9wdGlvbnM/LmlzT2JzaWRpYW5BcHBWaXNpYmxlLFxuICAgIG93bmVkSW5zdGFuY2UsXG4gICAgc2hvdWxkRGlzYWJsZVNhbmRib3g6IG9wdGlvbnM/LnNob3VsZERpc2FibGVTYW5kYm94LFxuICAgIHNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2s6IHdpbGxUaHJvd09uU2lsZW50QXNhckZhbGxiYWNrKG9wdGlvbnM/LnNob3VsZFRocm93T25TaWxlbnRBc2FyRmFsbGJhY2spLFxuICAgIHNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXM6IHdpbGxXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzKG9wdGlvbnM/LnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXMpXG4gIH0pKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZnJlc2gsIGlzb2xhdGVkIHVzZXItZGF0YSBkaXJlY3RvcnkgZm9yIGFuIG93bmVkIGluc3RhbmNlLlxuICpcbiAqIEByZXR1cm5zIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBuZXcgZGlyZWN0b3J5LlxuICovXG5mdW5jdGlvbiBjcmVhdGVPd25lZFVzZXJEYXRhRGlyZWN0b3J5KCk6IHN0cmluZyB7XG4gIGNvbnN0IHJvb3QgPSBqb2luKHRtcGRpcigpLCBIQVJORVNTX1RFTVBfRElSX05BTUUpO1xuICBta2RpclN5bmMocm9vdCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIHJldHVybiBta2R0ZW1wU3luYyhqb2luKHJvb3QsIE9XTkVEX1VTRVJfREFUQV9ESVJfUFJFRklYKSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgcmVqZWN0aW9uIHJlYXNvbiBhbW9uZyBzZXR0bGVkIG91dGNvbWVzLlxuICpcbiAqIEBwYXJhbSBvdXRjb21lcyAtIFRoZSBzZXR0bGVkIG91dGNvbWVzLCBhdCBsZWFzdCBvbmUgb2Ygd2hpY2ggaXMgZXhwZWN0ZWQgdG8gaGF2ZSByZWplY3RlZC5cbiAqIEByZXR1cm5zIFRoZSBmaXJzdCByZWplY3Rpb24gcmVhc29uLCBvciBhIHN0YW5kLWluIGVycm9yIHdoZW4gbm9uZSByZWplY3RlZC5cbiAqL1xuZnVuY3Rpb24gZ2V0U2V0dGxlZEZhaWx1cmUob3V0Y29tZXM6IHJlYWRvbmx5IFByb21pc2VTZXR0bGVkUmVzdWx0PHVua25vd24+W10pOiB1bmtub3duIHtcbiAgZm9yIChjb25zdCBvdXRjb21lIG9mIG91dGNvbWVzKSB7XG4gICAgaWYgKG91dGNvbWUuc3RhdHVzID09PSAncmVqZWN0ZWQnKSB7XG4gICAgICByZXR1cm4gb3V0Y29tZS5yZWFzb247XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBFcnJvcignQW5kcm9pZCBwcm92aXNpb25pbmcgZmFpbGVkIHdpdGhvdXQgbmFtaW5nIGEgcmVhc29uLicpO1xufVxuXG4vKipcbiAqIExvYWRzIGB3ZWJkcml2ZXJpb2Agb24gZGVtYW5kLlxuICpcbiAqIFRoZSBsb2FkIGlzIGRlZmVycmVkIGJlY2F1c2UgYSBzdGF0aWMgaW1wb3J0IHdvdWxkIGRyYWcgdGhlIHdob2xlIFdlYkRyaXZlclxuICogc3RhY2sgKGB3ZWJkcml2ZXJpb2AgKyBgQHdkaW8vKmAgKyBgYXJjaGl2ZXJgL2BjaGVlcmlvYC9ganN6aXBgKSBpbnRvIGV2ZXJ5XG4gKiBjb25zdW1lciBvZiB0aGlzIHBhY2thZ2UncyBpbmRleCBcdTIwMTQgYGV2YWxJbk9ic2lkaWFuYCByZWFjaGVzIHRoaXMgbW9kdWxlIFx1MjAxNCB3aGVuXG4gKiBvbmx5IHRoZSBBcHBpdW0gdHJhbnNwb3J0IG5lZWRzIGl0LiBOb3RoaW5nIG9uIHRoZSBkZXNrdG9wIENEUCBwYXRoIHRvdWNoZXNcbiAqIGB3ZWJkcml2ZXJpb2AgYXQgYWxsLlxuICpcbiAqIEl0IGFsc28ga2VlcHMgYGNoYWxrYCBvdXQgb2YgdGhhdCBncmFwaC4gYEB3ZGlvL2xvZ2dlcmAgaW1wb3J0cyBgY2hhbGtANWAsXG4gKiB3aG9zZSBpbnRlcm5hbCBgI3N1cHBvcnRzLWNvbG9yYCBzdWJwYXRoIGltcG9ydCBKZXN0J3MgVk0tbW9kdWxlcyBsaW5rZXIgZmFpbHNcbiAqIHRvIGxpbmssIHNvIGFuIGVhZ2VybHktaW1wb3J0ZWQgYHdlYmRyaXZlcmlvYCBraWxscyBhIEplc3QgRVNNIHN1aXRlIGF0IGltcG9ydFxuICogd2l0aCBgUmVmZXJlbmNlRXJyb3I6IENhbm5vdCBhY2Nlc3MgJ3N1cHBvcnRzQ29sb3InIGJlZm9yZSBpbml0aWFsaXphdGlvbmBcbiAqIGJlZm9yZSBhIHNpbmdsZSB0ZXN0IHJ1bnMgXHUyMDE0IHdoaWNoIGlzIHdoYXQgb25jZSBtYWRlIGB0ZXN0Omplc3RgIHJlZC4gQVxuICogYG1vZHVsZU5hbWVNYXBwZXJgIGNhbm5vdCBwYXRjaCBpdDogdGhlIG1hcHBlciBpcyBieXBhc3NlZCBmb3IgYCNgIHNwZWNpZmllcnMuXG4gKlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byB0aGUgYHdlYmRyaXZlcmlvYCBlbnRyeSBwb2ludHMgdGhlXG4gKiBBcHBpdW0gZmFjdG9yeSBjYWxscy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gaW1wb3J0V2ViZHJpdmVyaW8oKTogUHJvbWlzZTxXZWJkcml2ZXJpb01vZHVsZT4ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gYHdlYmRyaXZlcmlvYCBpcyBBcHBpdW0tb25seSwgc28gaXQgbXVzdCBiZSBsb2FkZWQgbGF6aWx5OiBhIHN0YXRpYyBpbXBvcnQgd291bGQgZHJhZyB0aGUgd2hvbGUgV2ViRHJpdmVyIHN0YWNrIGludG8gZXZlcnkgY29uc3VtZXIgb2YgdGhpcyBwYWNrYWdlJ3MgaW5kZXgsIGFuZCBgY2hhbGtgIHdpdGggaXQgKHNlZSB0aGUgZG9jIGNvbW1lbnQpLlxuICByZXR1cm4gYXdhaXQgaW1wb3J0KCd3ZWJkcml2ZXJpbycpO1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIHBvcnQtb3duZXIgbGlzdGluZyB3aXRoIHRoZSBwbGF0Zm9ybSdzIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJhdyBvdXRwdXQgYW5kIHRoZSBwb3J0IHRoYXQgd2FzIHF1ZXJpZWQuXG4gKiBAcmV0dXJucyBUaGUgUElEcyBob2xkaW5nIHRoZSBwb3J0LlxuICovXG5mdW5jdGlvbiBwYXJzZVBvcnRPd25lclBpZHMocGFyYW1zOiBQYXJzZVBvcnRPd25lclBpZHNQYXJhbXMpOiBudW1iZXJbXSB7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInXG4gICAgPyBwYXJzZVdpbmRvd3NOZXRzdGF0UGlkcyh7IG5ldHN0YXRPdXRwdXQ6IHBhcmFtcy5vdXRwdXQsIHBvcnQ6IHBhcmFtcy5wb3J0IH0pXG4gICAgOiBwYXJzZVBvc2l4THNvZlBpZHMocGFyYW1zLm91dHB1dCk7XG59XG5cbi8qKlxuICogUnVucyB0aGUgcHJvYWN0aXZlIGluc3RhbGxlclx1MjE5NGFwcCBjb21wYXRpYmlsaXR5IGNoZWNrIGZvciBhbiBhc2FyLXN3YXAgYW5kIGFjdHNcbiAqIG9uIHRoZSB2ZXJkaWN0OiBmb3IgYW4gaW5zdGFsbGVyIGJlbG93IHRoZSBhcHAncyBydW4gZmxvb3IgZWl0aGVyIHRocm93c1xuICoge0BsaW5rIEluY29tcGF0aWJsZUluc3RhbGxlclZlcnNpb25FcnJvcn0gKHdoZW5cbiAqIHtAbGluayBSZXNvbHZlQW5kUmVwb3J0Q29tcGF0aWJpbGl0eVBhcmFtcy5zaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyfSlcbiAqIG9yIHByb2NlZWRzIHRvIGxhdW5jaCB3aXRoIGEgd2FybmluZzsgZm9yIGEgcnVubmFibGUtYnV0LWJlbG93LXJlY29tbWVuZGVkXG4gKiBpbnN0YWxsZXIgbG9ncyBhIHdhcm5pbmcuIEJvdGggd2FybmluZ3MgYXJlIHN1cHByZXNzZWQgd2hlblxuICoge0BsaW5rIFJlc29sdmVBbmRSZXBvcnRDb21wYXRpYmlsaXR5UGFyYW1zLnNob3VsZFdhcm5PbkNvbXBhdGliaWxpdHlJc3N1ZXN9IGlzXG4gKiBgZmFsc2VgLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcmVzb2x2ZWQgdmVyc2lvbnMgYW5kIHRoZSB3YXJuL3Rocm93IGtub2JzLlxuICogQHJldHVybnMgVGhlIHZlcmRpY3QsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm8gYXNhci1zd2FwIHRvIGNoZWNrLlxuICovXG5mdW5jdGlvbiByZXNvbHZlQW5kUmVwb3J0Q29tcGF0aWJpbGl0eShwYXJhbXM6IFJlc29sdmVBbmRSZXBvcnRDb21wYXRpYmlsaXR5UGFyYW1zKTogSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHsgYXBwVmVyc2lvbiwgaW5zdGFsbGVyVmVyc2lvbiwgc2hvdWxkVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlciwgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyB9ID0gcGFyYW1zO1xuICBpZiAoYXBwVmVyc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGNvbXBhdGliaWxpdHkgPSByZXNvbHZlSW5zdGFsbGVyQ29tcGF0aWJpbGl0eSh7XG4gICAgYXBwVmVyc2lvbixcbiAgICBpbnN0YWxsZXJWZXJzaW9uLFxuICAgIG1ldGFkYXRhOiBnZXRWZXJzaW9uTWV0YWRhdGEoYXBwVmVyc2lvbilcbiAgfSk7XG5cbiAgY29uc3QgYWN0aW9uID0gcmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHlBY3Rpb24oe1xuICAgIHNob3VsZFRocm93T25JbmNvbXBhdGlibGVJbnN0YWxsZXIsXG4gICAgc2hvdWxkV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyxcbiAgICB0aWVyOiBjb21wYXRpYmlsaXR5LnRpZXJcbiAgfSk7XG5cbiAgaWYgKGFjdGlvbiA9PT0gJ3Rocm93Jykge1xuICAgIHRocm93IG5ldyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3Ioe1xuICAgICAgYXBwVmVyc2lvbjogY29tcGF0aWJpbGl0eS5hcHBWZXJzaW9uLFxuICAgICAgaW5zdGFsbGVyVmVyc2lvbjogZW5zdXJlTm9uTnVsbGFibGUoY29tcGF0aWJpbGl0eS5pbnN0YWxsZXJWZXJzaW9uKSxcbiAgICAgIG1pblJ1bm5hYmxlSW5zdGFsbGVyVmVyc2lvbjogZW5zdXJlTm9uTnVsbGFibGUoY29tcGF0aWJpbGl0eS5taW5SdW5uYWJsZUluc3RhbGxlclZlcnNpb24pXG4gICAgfSk7XG4gIH1cblxuICBpZiAoYWN0aW9uID09PSAnd2Fybi11bnJ1bm5hYmxlJykge1xuICAgIGxvZyhcbiAgICAgIGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBPYnNpZGlhbiBpbnN0YWxsZXIgJHtlbnN1cmVOb25OdWxsYWJsZShjb21wYXRpYmlsaXR5Lmluc3RhbGxlclZlcnNpb24pfSBpcyBiZWxvdyB0aGUgYFxuICAgICAgICArIGBydW4gZmxvb3IgJHtlbnN1cmVOb25OdWxsYWJsZShjb21wYXRpYmlsaXR5Lm1pblJ1bm5hYmxlSW5zdGFsbGVyVmVyc2lvbil9IGZvciBPYnNpZGlhbiAke2NvbXBhdGliaWxpdHkuYXBwVmVyc2lvbn07IGBcbiAgICAgICAgKyAncHJvY2VlZGluZyB0byBsYXVuY2ggKHNob3VsZFRocm93T25JbmNvbXBhdGlibGVJbnN0YWxsZXIgaXMgZmFsc2UpIFx1MjAxNCB0aGUgYm9vdCB3aWxsIGxpa2VseSBkZWFkLWJvb3QuJ1xuICAgICk7XG4gIH0gZWxzZSBpZiAoYWN0aW9uID09PSAnd2Fybi1uYWdnZWQnKSB7XG4gICAgbG9nKGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSAke2Vuc3VyZU5vbk51bGxhYmxlKGNvbXBhdGliaWxpdHkubWVzc2FnZSl9YCk7XG4gIH1cblxuICByZXR1cm4gY29tcGF0aWJpbGl0eTtcbn1cblxuLyoqXG4gKiBEZWNpZGVzIGhvdyB0aGUgcmVxdWVzdGVkIGFwcCAoYXNhcikgdmVyc2lvbiB3aWxsIGJlIGFwcGxpZWQgdG8gYW4gb3duZWRcbiAqIGluc3RhbmNlLCB3aXRob3V0IGRvd25sb2FkaW5nIGFueXRoaW5nIHlldDogYW4gdXBncmFkZS1vbmx5IGFzYXItc3dhcCBvbnRvIHRoZVxuICogc2hlbGwsIGEgZG93bmdyYWRlIHRvIHRoZSBhcHAncyBvd24gaW5zdGFsbGVyIHNoZWxsLCBvciB0aGUgdXNlcidzIG5ld2VzdFxuICogaW5zdGFsbGVkIGFzYXIgd2hlbiBuZWl0aGVyIHZlcnNpb24gaXMgcGlubmVkLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ0RQIHRyYW5zcG9ydCBvcHRpb25zLlxuICogQHBhcmFtIHNoZWxsVmVyc2lvbiAtIFRoZSByZXNvbHZlZCBpbnN0YWxsZXIvc2hlbGwgdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAuXG4gKiBAcmV0dXJucyBUaGUgYXNhciBwbGFuIChhdCBtb3N0IG9uZSBvZiBpdHMgZmllbGRzIGlzIHNldCkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVBc2FyUGxhbihcbiAgb3B0aW9uczogT2JzaWRpYW5DZHBUcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkLFxuICBzaGVsbFZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZFxuKTogUHJvbWlzZTxBc2FyUGxhbj4ge1xuICBpZiAob3B0aW9ucz8ub2JzaWRpYW5WZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBhc2FyVmVyc2lvbiA9IGF3YWl0IHJlc29sdmVDb25jcmV0ZVZlcnNpb24ob3B0aW9ucy5vYnNpZGlhblZlcnNpb24pO1xuICAgIGlmIChzaGVsbFZlcnNpb24gIT09IHVuZGVmaW5lZCAmJiBjb21wYXJlVmVyc2lvbnMoYXNhclZlcnNpb24sIHNoZWxsVmVyc2lvbikgPj0gMCkge1xuICAgICAgcmV0dXJuIHsgYXNhclZlcnNpb25Ub1N3YXA6IGFzYXJWZXJzaW9uIH07XG4gICAgfVxuXG4gICAgLy8gQXNhci1zd2FwIGlzIHVwZ3JhZGUtb25seSwgc28gaXQgY2Fubm90IGFwcGx5IGEgdmVyc2lvbiBvbGRlciB0aGFuIHRoZVxuICAgIC8vIHNoZWxsJ3MgYnVuZGxlZCBvbmUgXHUyMDE0IGFuZCB3aGVuIHRoZSBzaGVsbCB2ZXJzaW9uIGlzIHVua25vd24gKGEgTGludXhcbiAgICAvLyBwYXRoLXBhcnNlIG1pc3MpIHdlIGNhbm5vdCBwcm92ZSB0aGUgc3dhcCB3b3VsZCBhcHBseSBhdCBhbGwuIEluIGJvdGhcbiAgICAvLyBjYXNlcyB1c2UgdGhlIHJlcXVlc3RlZCB2ZXJzaW9uJ3Mgb3duIGluc3RhbGxlciBzaGVsbCwgd2hvc2UgYnVuZGxlZCBhc2FyXG4gICAgLy8gaXMgZXhhY3RseSB0aGlzIHZlcnNpb24sIHNvIHRoZSBwaW4gaXMgYWx3YXlzIGhvbm9yZWQuXG4gICAgbG9nKGBbdHJhbnNwb3J0LWZhY3Rvcnk6b2JzaWRpYW4tY2RwXSBVc2luZyB0aGUgJHthc2FyVmVyc2lvbn0gaW5zdGFsbGVyIHNoZWxsIChzaGVsbCB2ZXJzaW9uICR7c2hlbGxWZXJzaW9uID8/ICd1bmtub3duJ307IGFzYXItc3dhcCBpcyB1cGdyYWRlLW9ubHkpLmApO1xuICAgIHJldHVybiB7IGRvd25ncmFkZUluc3RhbGxlclZlcnNpb246IGFzYXJWZXJzaW9uIH07XG4gIH1cblxuICBpZiAob3B0aW9ucz8ub2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBuZXdlc3QgPSBmaW5kTmV3ZXN0QXNhcihnZXRPYnNpZGlhbkNvbmZpZ0RpcmVjdG9yeSgpKTtcbiAgICBpZiAobmV3ZXN0ICYmIChzaGVsbFZlcnNpb24gPT09IHVuZGVmaW5lZCB8fCBjb21wYXJlVmVyc2lvbnMobmV3ZXN0LnZlcnNpb24sIHNoZWxsVmVyc2lvbikgPj0gMCkpIHtcbiAgICAgIHJldHVybiB7IGFzYXI6IHsgcGF0aDogbmV3ZXN0LnBhdGgsIHZlcnNpb246IG5ld2VzdC52ZXJzaW9uIH0gfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge307XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIGxvY2FsbHktaW5zdGFsbGVkIE9ic2lkaWFuIHNoZWxsLCB0b2xlcmF0aW5nIGl0cyBhYnNlbmNlLlxuICpcbiAqIFVubGlrZSB7QGxpbmsgcmVzb2x2ZU9ic2lkaWFuRXhlY3V0YWJsZX0gKHdoaWNoIHRocm93cyB3aGVuIE9ic2lkaWFuIGlzIG5vdFxuICogaW5zdGFsbGVkKSwgdGhpcyByZXR1cm5zIGB1bmRlZmluZWRgIGluIHRoYXQgY2FzZSwgc28gYSBjYWxsZXIgcGlubmluZyBhblxuICogaW5zdGFsbGVyIHZlcnNpb24gY2FuIGZhbGwgYmFjayB0byBkb3dubG9hZGluZyB0aGUgcGlubmVkIHNoZWxsIGluc3RlYWQgb2ZcbiAqIGZhaWxpbmcgb24gYSBob3N0IHdpdGggbm8gT2JzaWRpYW4gaW5zdGFsbGVkIChlLmcuIENJKS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgaW5zdGFsbGVkIHNoZWxsJ3MgcGF0aCBhbmQgZGV0ZWN0ZWQgdmVyc2lvbiwgb3IgYHVuZGVmaW5lZGAgd2hlblxuICogICBubyBPYnNpZGlhbiBpcyBpbnN0YWxsZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVJbnN0YWxsZWRTaGVsbE9yTnVsbCgpOiBQcm9taXNlPEluc3RhbGxlZFNoZWxsIHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZXhlUGF0aCA9IGF3YWl0IHJlc29sdmVPYnNpZGlhbkV4ZWN1dGFibGUoKTtcbiAgICByZXR1cm4geyBleGVQYXRoLCBzaGVsbFZlcnNpb246IGRldGVjdEluc3RhbGxlZFNoZWxsVmVyc2lvbihleGVQYXRoKSB9O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIHNoZWxsIGV4ZWN1dGFibGUsIGFzYXIgcHJvdmlzaW9uaW5nLCBhbmQgaXNvbGF0ZWQgdXNlci1kYXRhIGRpclxuICogZm9yIGEgaGFybmVzcy1vd25lZCBpbnN0YW5jZSBmcm9tIHRoZSByZXF1ZXN0ZWQgdmVyc2lvbiBrbm9icy5cbiAqXG4gKiAtIGBvYnNpZGlhbkluc3RhbGxlclZlcnNpb25gIHBpbnMgdGhlIEVsZWN0cm9uIHNoZWxsIChkb3dubG9hZHMgKyBleHRyYWN0cyBhXG4gKiAgIHBvcnRhYmxlIGJ1aWxkIHdoZW4gaXQgZGlmZmVycyBmcm9tIHRoZSBpbnN0YWxsZWQgc2hlbGwpLlxuICogLSBgb2JzaWRpYW5WZXJzaW9uYCBwaW5zIHRoZSBhcHA6IGFuIGFzYXItc3dhcCB3aGVuIGl0IGlzID49IHRoZSBzaGVsbCB2ZXJzaW9uXG4gKiAgIChjaGVhcCksIG90aGVyd2lzZSB0aGUgbWF0Y2hpbmcgaW5zdGFsbGVyIHNoZWxsIGlzIHVzZWQgKGRvd25ncmFkZSkuXG4gKiAtIFdoZW4gbmVpdGhlciBpcyBzZXQsIHRoZSB1c2VyJ3MgbmV3ZXN0IGluc3RhbGxlZCBhc2FyIGlzIGNvcGllZCBpbiAoc28gdGhlXG4gKiAgIG93bmVkIGluc3RhbmNlIG1hdGNoZXMgdGhlIHZlcnNpb24gdGhlIHVzZXIgY3VycmVudGx5IHJ1bnMpIHdpdGggemVybyBuZXR3b3JrLlxuICpcbiAqIFRoZSBjb25jcmV0ZSAoYXBwLCBpbnN0YWxsZXIpIHZlcnNpb24gcGFpciBpcyByZXNvbHZlZCAqYmVmb3JlKiBhbnkgc2hlbGwvYXNhclxuICogZG93bmxvYWQsIHNvIGEgcHJvYWN0aXZlIGluc3RhbGxlclx1MjE5NGFwcCBjb21wYXRpYmlsaXR5IGNoZWNrXG4gKiAoe0BsaW5rIHJlc29sdmVJbnN0YWxsZXJDb21wYXRpYmlsaXR5fSkgY2FuIGZhaWwgZmFzdDogYW4gaW5zdGFsbGVyIGJlbG93IHRoZVxuICogYXBwJ3MgcnVuIGZsb29yIHRocm93cyB7QGxpbmsgSW5jb21wYXRpYmxlSW5zdGFsbGVyVmVyc2lvbkVycm9yfSBiZWZvcmVcbiAqIGFueXRoaW5nIGlzIGRvd25sb2FkZWQgb3IgbGF1bmNoZWQgKHN1cGVyc2VkaW5nIHRoZSByZWFjdGl2ZSBkZWFkLWJvb3RcbiAqIGZhc3QtZmFpbCBmb3IgdGFibGUta25vd24gY29tYm9zKSwgYW5kIGEgcnVubmFibGUtYnV0LWJlbG93LXJlY29tbWVuZGVkXG4gKiBpbnN0YWxsZXIgbG9ncyBhIHdhcm5pbmcuIFRoZSB2ZXJkaWN0IGlzIHRocmVhZGVkIG9udG8gdGhlIHJldHVybmVkIGNvbmZpZyBzb1xuICogdGhlIHRyYW5zcG9ydCBjYW4gc3VyZmFjZSBpdCBhcyBkYXRhLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ0RQIHRyYW5zcG9ydCBvcHRpb25zLlxuICogQHJldHVybnMgVGhlIHJlc29sdmVkIG93bmVkLWluc3RhbmNlIGNvbmZpZy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZU93bmVkSW5zdGFuY2VDb25maWcob3B0aW9ucz86IE9ic2lkaWFuQ2RwVHJhbnNwb3J0T3B0aW9ucyk6IFByb21pc2U8T3duZWRJbnN0YW5jZUNvbmZpZz4ge1xuICAvLyBSZXNvbHZlIHRoZSBjb25jcmV0ZSBzaGVsbCAoaW5zdGFsbGVyKSB2ZXJzaW9uIGZpcnN0LCBidXQgZm9yIGEgcGlubmVkXG4gIC8vIGluc3RhbGxlciBERUZFUiByZXNvbHZpbmcvZG93bmxvYWRpbmcgdGhlIGFjdHVhbCBzaGVsbCB1bnRpbCBhZnRlciB0aGVcbiAgLy8gcHJvYWN0aXZlIGNvbXBhdGliaWxpdHkgY2hlY2ssIHNvIGFuIHVucnVubmFibGUgcGluIGZhaWxzIGZhc3QgXHUyMDE0IGJlZm9yZSB0aGVcbiAgLy8gKHBvc3NpYmx5IHNsb3cpIGluc3RhbGxlZC1zaGVsbCBkZXRlY3Rpb24gYW5kIGFueSBkb3dubG9hZC5cbiAgbGV0IGV4ZVBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbGV0IHNoZWxsVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBsZXQgcGlubmVkSW5zdGFsbGVyVmVyc2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIGlmIChvcHRpb25zPy5vYnNpZGlhbkluc3RhbGxlclZlcnNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgIGV4ZVBhdGggPSBhd2FpdCByZXNvbHZlT2JzaWRpYW5FeGVjdXRhYmxlKCk7XG4gICAgc2hlbGxWZXJzaW9uID0gZGV0ZWN0SW5zdGFsbGVkU2hlbGxWZXJzaW9uKGV4ZVBhdGgpO1xuICB9IGVsc2Uge1xuICAgIC8vIEEgcGlubmVkIGluc3RhbGxlciB2ZXJzaW9uIGZ1bGx5IGRldGVybWluZXMgdGhlIHNoZWxsIHZlcnNpb24gdXAgZnJvbnQsXG4gICAgLy8gd2l0aG91dCByZXF1aXJpbmcgYSBsb2NhbGx5LWluc3RhbGxlZCBPYnNpZGlhbiAoYSBDSSBydW5uZXIgaGFzIG5vbmUpLlxuICAgIHBpbm5lZEluc3RhbGxlclZlcnNpb24gPSBhd2FpdCByZXNvbHZlQ29uY3JldGVWZXJzaW9uKG9wdGlvbnMub2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uKTtcbiAgICBzaGVsbFZlcnNpb24gPSBwaW5uZWRJbnN0YWxsZXJWZXJzaW9uO1xuICB9XG5cbiAgLy8gRGVjaWRlIGhvdyB0aGUgYXBwIChhc2FyKSB2ZXJzaW9uIHdpbGwgYmUgYXBwbGllZCwgc3RpbGwgV0lUSE9VVCBkb3dubG9hZGluZy5cbiAgY29uc3QgcGxhbiA9IGF3YWl0IHJlc29sdmVBc2FyUGxhbihvcHRpb25zLCBzaGVsbFZlcnNpb24pO1xuXG4gIC8vIFRoZSBhcHAgdmVyc2lvbiB0aGF0IHdpbGwgcnVuIGFzIGFuIGFzYXItc3dhcCBvbnRvIGBzaGVsbFZlcnNpb25gIFx1MjAxNCB0aGUgb25seVxuICAvLyBjb21iaW5hdGlvbiB0aGF0IGNhbiBkZWFkLWJvb3QuIFRoZSBkb3duZ3JhZGUgLyBvd24taW5zdGFsbGVyIHBhdGhzIHJ1biB0aGVcbiAgLy8gYXBwJ3Mgb3duIGluc3RhbGxlciBzaGVsbCwgc28gdGhleSBhbHdheXMgYm9vdCBhbmQgYXJlIG5vdCBjaGVja2VkLlxuICBjb25zdCBzd2FwQXBwVmVyc2lvbiA9IHBsYW4uYXNhclZlcnNpb25Ub1N3YXAgPz8gcGxhbi5hc2FyPy52ZXJzaW9uO1xuICBjb25zdCBjb21wYXRpYmlsaXR5ID0gcmVzb2x2ZUFuZFJlcG9ydENvbXBhdGliaWxpdHkoe1xuICAgIGFwcFZlcnNpb246IHN3YXBBcHBWZXJzaW9uLFxuICAgIGluc3RhbGxlclZlcnNpb246IHNoZWxsVmVyc2lvbixcbiAgICBzaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyOiB3aWxsVGhyb3dPbkluY29tcGF0aWJsZUluc3RhbGxlcihvcHRpb25zPy5zaG91bGRUaHJvd09uSW5jb21wYXRpYmxlSW5zdGFsbGVyKSxcbiAgICBzaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzOiB3aWxsV2Fybk9uQ29tcGF0aWJpbGl0eUlzc3VlcyhvcHRpb25zPy5zaG91bGRXYXJuT25Db21wYXRpYmlsaXR5SXNzdWVzKVxuICB9KTtcblxuICAvLyBUaGUgcGluIGlzIGtub3duIHJ1bm5hYmxlIFx1MjAxNCByZXNvbHZlL2Rvd25sb2FkIHRoZSBkZWZlcnJlZCBzaGVsbCArIGFzYXIgbm93LlxuICAvLyBSZXVzZSB0aGUgaW5zdGFsbGVkIHNoZWxsIG9ubHkgd2hlbiBpdCBhbHJlYWR5IG1hdGNoZXMgdGhlIHBpbiAoc2F2ZXMgdGhlXG4gIC8vIGRvd25sb2FkKTsgb3RoZXJ3aXNlIGRvd25sb2FkIGFuZCBleHRyYWN0IHRoZSBwaW5uZWQgaW5zdGFsbGVyLlxuICBpZiAocGlubmVkSW5zdGFsbGVyVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgaW5zdGFsbGVkID0gYXdhaXQgcmVzb2x2ZUluc3RhbGxlZFNoZWxsT3JOdWxsKCk7XG4gICAgZXhlUGF0aCA9IGluc3RhbGxlZD8uc2hlbGxWZXJzaW9uID09PSBwaW5uZWRJbnN0YWxsZXJWZXJzaW9uID8gaW5zdGFsbGVkLmV4ZVBhdGggOiBhd2FpdCBlbnN1cmVTaGVsbENhY2hlZChwaW5uZWRJbnN0YWxsZXJWZXJzaW9uKTtcbiAgfVxuICBpZiAocGxhbi5kb3duZ3JhZGVJbnN0YWxsZXJWZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICBleGVQYXRoID0gYXdhaXQgZW5zdXJlU2hlbGxDYWNoZWQocGxhbi5kb3duZ3JhZGVJbnN0YWxsZXJWZXJzaW9uKTtcbiAgfVxuXG4gIGNvbnN0IGFzYXIgPSBwbGFuLmFzYXJWZXJzaW9uVG9Td2FwID09PSB1bmRlZmluZWRcbiAgICA/IHBsYW4uYXNhclxuICAgIDogeyBwYXRoOiBhd2FpdCBlbnN1cmVBc2FyQ2FjaGVkKHBsYW4uYXNhclZlcnNpb25Ub1N3YXApLCB2ZXJzaW9uOiBwbGFuLmFzYXJWZXJzaW9uVG9Td2FwIH07XG5cbiAgcmV0dXJuIHtcbiAgICAuLi4oYXNhciAmJiB7IGFzYXIgfSksXG4gICAgLi4uKGNvbXBhdGliaWxpdHkgJiYgeyBjb21wYXRpYmlsaXR5IH0pLFxuICAgIGV4ZVBhdGg6IGVuc3VyZU5vbk51bGxhYmxlKGV4ZVBhdGgpLFxuXG4gICAgdXNlckRhdGFEaXJlY3Rvcnk6IGNyZWF0ZU93bmVkVXNlckRhdGFEaXJlY3RvcnkoKVxuICB9O1xufVxuXG4vKipcbiAqIFJlbW92ZXMgYENvbm5lY3Rpb25gIGFuZCBgQ29udGVudC1MZW5ndGhgIGZyb20gYSBXZWJEcml2ZXIgcmVxdWVzdCdzIGhlYWRlcnMuXG4gKlxuICogVGhlIGJ1bmRsZWQgYHdlYmRyaXZlcmAgcGFja2FnZSBzZXRzIGJvdGggaGVhZGVycyBleHBsaWNpdGx5LiBUaGV5IGFyZVxuICogZm9yYmlkZGVuIHJlcXVlc3QgaGVhZGVycyBwZXIgdGhlIEZldGNoIHNwZWM6IE5vZGUgdXAgdG8gMjUgYWNjZXB0ZWQgdGhlbVxuICogc2lsZW50bHksIGJ1dCBOb2RlIDI2IHJlamVjdHMgdGhlbSB3aXRoIGBVTkRfRVJSX0lOVkFMSURfQVJHYCwgYnJlYWtpbmcgdGhlXG4gKiBBcHBpdW0gYC9zZXNzaW9uYCByZXF1ZXN0LiBUaGUgdHJhbnNwb3J0IGxheWVyIG1hbmFnZXMgY29ubmVjdGlvbiByZXVzZSBhbmRcbiAqIHRoZSBGZXRjaCBBUEkgY29tcHV0ZXMgYENvbnRlbnQtTGVuZ3RoYCBmcm9tIHRoZSBib2R5LCBzbyBkcm9wcGluZyBib3RoIGlzXG4gKiBzYWZlIG9uIGV2ZXJ5IE5vZGUgdmVyc2lvbi4gU2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vd2ViZHJpdmVyaW8vd2ViZHJpdmVyaW8vaXNzdWVzLzE1MjY1fS5cbiAqXG4gKiBAcGFyYW0gcmVxdWVzdE9wdGlvbnMgLSBUaGUgcmVxdWVzdCBvcHRpb25zIGFib3V0IHRvIGJlIHNlbnQgYnkgV2ViRHJpdmVySU8uXG4gKiBAcmV0dXJucyBUaGUgc2FtZSByZXF1ZXN0IG9wdGlvbnMgd2l0aCB0aGUgZm9yYmlkZGVuIGhlYWRlcnMgcmVtb3ZlZC5cbiAqL1xuZnVuY3Rpb24gc3RyaXBGb3JiaWRkZW5GZXRjaEhlYWRlcnMocmVxdWVzdE9wdGlvbnM6IFJlcXVlc3RJbml0KTogUmVxdWVzdEluaXQge1xuICBpZiAocmVxdWVzdE9wdGlvbnMuaGVhZGVycyBpbnN0YW5jZW9mIEhlYWRlcnMpIHtcbiAgICByZXF1ZXN0T3B0aW9ucy5oZWFkZXJzLmRlbGV0ZSgnQ29ubmVjdGlvbicpO1xuICAgIHJlcXVlc3RPcHRpb25zLmhlYWRlcnMuZGVsZXRlKCdDb250ZW50LUxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVlc3RPcHRpb25zO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBY0EsZ0NBSU87QUFDUCxxQkFJTztBQUNQLHVCQUFpQjtBQUNqQixxQkFHTztBQUNQLHVCQUFxQjtBQUNyQiwwQkFBb0I7QUE2QnBCLDZCQUlPO0FBQ1AseUJBQTBDO0FBQzFDLGlDQUlPO0FBQ1Asa0NBTU87QUFDUCxtQ0FJTztBQUNQLHNCQUdPO0FBQ1AsOEJBTU87QUFDUCwrQkFNTztBQUNQLG1DQUtPO0FBQ1AsOEJBQTJDO0FBQzNDLDhCQUE4QjtBQUM5Qiw4QkFLTztBQUNQLGdDQUlPO0FBQ1AsOEJBQTBDO0FBQzFDLCtCQUdPO0FBQ1AsNkJBUU87QUFDUCw2QkFBb0M7QUFDcEMsOEJBSU87QUFDUCwrQkFHTztBQUNQLGtCQUFxQjtBQUNyQixrREFBa0Q7QUFDbEQscUNBQThDO0FBQzlDLDRDQUE0QztBQUM1QywrQkFHTztBQUNQLHVDQUdPO0FBQ1AsOEJBS087QUFDUCxpQkFBb0I7QUFDcEIsMkNBQTRDO0FBQzVDLDZCQUEyQztBQUMzQyxpQ0FBMEM7QUFDMUMsZ0NBR087QUFDUCwrQkFBbUM7QUFDbkMscUNB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