obsidian-integration-testing 12.1.2 → 12.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +1 -5
  2. package/dist/lib/cjs/app-config.cjs +137 -0
  3. package/dist/lib/cjs/app-config.d.cts +190 -0
  4. package/dist/lib/cjs/appium-session-config.cjs +7 -1
  5. package/dist/lib/cjs/appium-session-config.d.cts +20 -0
  6. package/dist/lib/cjs/cdp-command-timeout-error.cjs +50 -0
  7. package/dist/lib/cjs/cdp-command-timeout-error.d.cts +48 -0
  8. package/dist/lib/cjs/connect-to-cdp.cjs +1 -1
  9. package/dist/lib/cjs/connect-to-cdp.d.cts +5 -0
  10. package/dist/lib/cjs/emulator-arguments.cjs +19 -3
  11. package/dist/lib/cjs/emulator-arguments.d.cts +44 -0
  12. package/dist/lib/cjs/emulator-device-id.cjs +1 -1
  13. package/dist/lib/cjs/emulator-device-id.d.cts +7 -6
  14. package/dist/lib/cjs/emulator-marker.cjs +169 -0
  15. package/dist/lib/cjs/emulator-marker.d.cts +224 -0
  16. package/dist/lib/cjs/emulator-reaper.cjs +248 -0
  17. package/dist/lib/cjs/emulator-reaper.d.cts +225 -0
  18. package/dist/lib/cjs/emulator-reclaim.cjs +312 -0
  19. package/dist/lib/cjs/emulator-reclaim.d.cts +179 -0
  20. package/dist/lib/cjs/eval-cap-exceeded-error.cjs +61 -0
  21. package/dist/lib/cjs/eval-cap-exceeded-error.d.cts +92 -0
  22. package/dist/lib/cjs/eval-cap.cjs +29 -0
  23. package/dist/lib/cjs/eval-cap.d.cts +43 -0
  24. package/dist/lib/cjs/global-setup-core.cjs +2 -3
  25. package/dist/lib/cjs/index.cjs +21 -1
  26. package/dist/lib/cjs/index.d.cts +7 -0
  27. package/dist/lib/cjs/library.cjs +1 -1
  28. package/dist/lib/cjs/poll-in-obsidian.cjs +1 -1
  29. package/dist/lib/cjs/poll-in-obsidian.d.cts +7 -2
  30. package/dist/lib/cjs/setup-lock.cjs +56 -8
  31. package/dist/lib/cjs/setup-lock.d.cts +53 -0
  32. package/dist/lib/cjs/soft-keyboard-geometry.cjs +17 -8
  33. package/dist/lib/cjs/soft-keyboard-geometry.d.cts +46 -9
  34. package/dist/lib/cjs/soft-keyboard.cjs +7 -4
  35. package/dist/lib/cjs/soft-keyboard.d.cts +16 -2
  36. package/dist/lib/cjs/transport-appium.cjs +70 -5
  37. package/dist/lib/cjs/transport-appium.d.cts +35 -0
  38. package/dist/lib/cjs/transport-desktop-cdp.cjs +98 -19
  39. package/dist/lib/cjs/transport-desktop-cdp.d.cts +44 -1
  40. package/dist/lib/cjs/transport-factory.cjs +297 -190
  41. package/dist/lib/cjs/transport-factory.d.cts +15 -0
  42. package/dist/lib/cjs/transport-options.cjs +1 -1
  43. package/dist/lib/cjs/transport-options.d.cts +38 -1
  44. package/dist/lib/cjs/webview-cdp.cjs +45 -14
  45. package/dist/lib/cjs/webview-cdp.d.cts +17 -0
  46. package/dist/lib/esm/app-config.d.mts +190 -0
  47. package/dist/lib/esm/app-config.mjs +110 -0
  48. package/dist/lib/esm/appium-session-config.d.mts +20 -0
  49. package/dist/lib/esm/appium-session-config.mjs +6 -1
  50. package/dist/lib/esm/cdp-command-timeout-error.d.mts +48 -0
  51. package/dist/lib/esm/cdp-command-timeout-error.mjs +26 -0
  52. package/dist/lib/esm/connect-to-cdp.d.mts +5 -0
  53. package/dist/lib/esm/connect-to-cdp.mjs +1 -1
  54. package/dist/lib/esm/emulator-arguments.d.mts +44 -0
  55. package/dist/lib/esm/emulator-arguments.mjs +16 -2
  56. package/dist/lib/esm/emulator-device-id.d.mts +7 -6
  57. package/dist/lib/esm/emulator-device-id.mjs +1 -1
  58. package/dist/lib/esm/emulator-marker.d.mts +224 -0
  59. package/dist/lib/esm/emulator-marker.mjs +134 -0
  60. package/dist/lib/esm/emulator-reaper.d.mts +225 -0
  61. package/dist/lib/esm/emulator-reaper.mjs +211 -0
  62. package/dist/lib/esm/emulator-reclaim.d.mts +179 -0
  63. package/dist/lib/esm/emulator-reclaim.mjs +291 -0
  64. package/dist/lib/esm/eval-cap-exceeded-error.d.mts +92 -0
  65. package/dist/lib/esm/eval-cap-exceeded-error.mjs +36 -0
  66. package/dist/lib/esm/eval-cap.d.mts +43 -0
  67. package/dist/lib/esm/eval-cap.mjs +5 -0
  68. package/dist/lib/esm/global-setup-core.mjs +6 -4
  69. package/dist/lib/esm/index.d.mts +7 -0
  70. package/dist/lib/esm/index.mjs +21 -1
  71. package/dist/lib/esm/library.mjs +1 -1
  72. package/dist/lib/esm/poll-in-obsidian.d.mts +7 -2
  73. package/dist/lib/esm/poll-in-obsidian.mjs +1 -1
  74. package/dist/lib/esm/setup-lock.d.mts +53 -0
  75. package/dist/lib/esm/setup-lock.mjs +52 -7
  76. package/dist/lib/esm/soft-keyboard-geometry.d.mts +46 -9
  77. package/dist/lib/esm/soft-keyboard-geometry.mjs +17 -8
  78. package/dist/lib/esm/soft-keyboard.d.mts +16 -2
  79. package/dist/lib/esm/soft-keyboard.mjs +7 -4
  80. package/dist/lib/esm/transport-appium.d.mts +35 -0
  81. package/dist/lib/esm/transport-appium.mjs +73 -5
  82. package/dist/lib/esm/transport-desktop-cdp.d.mts +44 -1
  83. package/dist/lib/esm/transport-desktop-cdp.mjs +98 -19
  84. package/dist/lib/esm/transport-factory.d.mts +15 -0
  85. package/dist/lib/esm/transport-factory.mjs +305 -184
  86. package/dist/lib/esm/transport-options.d.mts +38 -1
  87. package/dist/lib/esm/transport-options.mjs +1 -1
  88. package/dist/lib/esm/webview-cdp.d.mts +17 -0
  89. package/dist/lib/esm/webview-cdp.mjs +45 -14
  90. package/package.json +4 -4
@@ -29,6 +29,8 @@ var import_node_path = require("node:path");
29
29
  var import_app_startup_progress = require("./app-startup-progress.cjs");
30
30
  var import_capture_screenshot = require("./capture-screenshot.cjs");
31
31
  var import_error_to_string = require("./error-to-string.cjs");
32
+ var import_eval_cap_exceeded_error = require("./eval-cap-exceeded-error.cjs");
33
+ var import_eval_cap = require("./eval-cap.cjs");
32
34
  var import_exec = require("./exec.cjs");
33
35
  var import_leftover_cleanup = require("./leftover-cleanup.cjs");
34
36
  var import_log = require("./log.cjs");
@@ -45,7 +47,8 @@ const DEFAULT_APP_START_POLL_TIMEOUT_IN_MILLISECONDS = 18e4;
45
47
  const APP_RESTART_DELAY_IN_MILLISECONDS = 2e3;
46
48
  const DEFAULT_APP_ID = "md.obsidian";
47
49
  const ADB_VAULT_REMOVE_TIMEOUT_IN_MILLISECONDS = 3e4;
48
- const CONSOLE_CAPTURE_MARKER_TAG = "OIT_CAPTURE";
50
+ const CAP_RECOVERY_GRACE_IN_MILLISECONDS = import_eval_cap.DEFAULT_EVAL_CAP_IN_MILLISECONDS;
51
+ const CONSOLE_CAPTURE_MARKER_TAG = "OBSIDIAN_INTEGRATION_TESTING_CAPTURE";
49
52
  const CONSOLE_CAPTURE_TAIL_MAX_LENGTH = 8e3;
50
53
  const ADB_LOG_MARKER_TIMEOUT_IN_MILLISECONDS = 5e3;
51
54
  const LOGCAT_DUMP_TIMEOUT_IN_MILLISECONDS = 1e4;
@@ -90,9 +93,17 @@ class AppiumTransport {
90
93
  * can time out on slow emulators).
91
94
  */
92
95
  isInWebViewContext = false;
96
+ /**
97
+ * Whether the previous eval ended in a cap overrun, so the next one is owed the recovery grace.
98
+ *
99
+ * The abandoned closure is still running in the guest, and Appium serializes commands per session, so
100
+ * the next command queues behind whatever is left of it. See {@link AppiumTransport.evaluateWithinCap}.
101
+ */
102
+ isRecoveringFromCapOverrun = false;
93
103
  isSessionOwner;
94
104
  layoutReadyTimeoutInMilliseconds;
95
105
  platform;
106
+ scriptTimeoutInMilliseconds;
96
107
  shouldSweepLeftovers;
97
108
  vaultBasePath;
98
109
  webviewTimeoutInMilliseconds;
@@ -109,6 +120,7 @@ class AppiumTransport {
109
120
  this.platform = config.platform;
110
121
  this.appId = config.appId ?? DEFAULT_APP_ID;
111
122
  this.appStartTimeoutInMilliseconds = config.appStartTimeoutInMilliseconds ?? DEFAULT_APP_START_POLL_TIMEOUT_IN_MILLISECONDS;
123
+ this.scriptTimeoutInMilliseconds = config.scriptTimeoutInMilliseconds ?? import_eval_cap.DEFAULT_EVAL_CAP_IN_MILLISECONDS;
112
124
  this.shouldSweepLeftovers = config.shouldSweepLeftovers ?? true;
113
125
  this.vaultBasePath = config.vaultBasePath ?? DEFAULT_VAULT_BASE_PATH[this.platform] ?? DEFAULT_ANDROID_VAULT_BASE_PATH;
114
126
  this.webviewTimeoutInMilliseconds = config.webviewTimeoutInMilliseconds ?? DEFAULT_WEBVIEW_POLL_TIMEOUT_IN_MILLISECONDS;
@@ -192,15 +204,24 @@ class AppiumTransport {
192
204
  await this.ensureWebViewContext();
193
205
  await this.ensureInputChannel();
194
206
  try {
195
- const result = await this.browser.execute(
196
- `return (${expression})`
197
- );
207
+ const result = await this.evaluateWithinCap(`return (${expression})`);
198
208
  if (result === void 0 || result === null) {
199
209
  return NO_OUTPUT;
200
210
  }
201
211
  return result;
202
212
  } catch (error) {
213
+ if (error instanceof import_eval_cap_exceeded_error.EvalCapExceededError) {
214
+ throw error;
215
+ }
203
216
  this.isInWebViewContext = false;
217
+ if ((0, import_eval_cap_exceeded_error.isScriptTimeoutError)(error)) {
218
+ throw new import_eval_cap_exceeded_error.EvalCapExceededError({
219
+ capInMilliseconds: this.scriptTimeoutInMilliseconds,
220
+ cause: error,
221
+ optionName: "scriptTimeoutInMilliseconds",
222
+ transportName: "Android (Appium)"
223
+ });
224
+ }
204
225
  throw error;
205
226
  }
206
227
  }
@@ -474,6 +495,50 @@ class AppiumTransport {
474
495
  }
475
496
  throw new Error(`No ${WEBVIEW_CONTEXT_PREFIX} context found within ${String(this.webviewTimeoutInMilliseconds)}ms. Is the Obsidian app fully loaded?`);
476
497
  }
498
+ /**
499
+ * Runs one Execute Script under the per-eval cap, raising {@link EvalCapExceededError} if it outlasts it.
500
+ *
501
+ * The cap covers the script ALONE — `ensureWebViewContext` and `ensureInputChannel` run before it,
502
+ * because a `switchContext` legitimately costs ~17s (**L19**) and charging that to a test's own budget
503
+ * would report the harness's setup as the test's overrun.
504
+ *
505
+ * The abandoned request is deliberately left in flight rather than cancelled. Nothing can cancel it:
506
+ * `Runtime.terminateExecution` over the transport's own CDP channel was measured releasing nothing,
507
+ * and a guest-side abort hook could not even be installed in time. What the same runs did show is that
508
+ * the session usually keeps serving — a vault read-back was answered 528ms after one such abandonment,
509
+ * with the session free — so bounding the wait costs a test its closure, not the rest of its suite.
510
+ *
511
+ * @param script - The script to run, already wrapped in its `return (...)`.
512
+ * @returns The script's result.
513
+ */
514
+ async evaluateWithinCap(script) {
515
+ const budgetInMilliseconds = this.isRecoveringFromCapOverrun ? this.scriptTimeoutInMilliseconds + CAP_RECOVERY_GRACE_IN_MILLISECONDS : this.scriptTimeoutInMilliseconds;
516
+ this.isRecoveringFromCapOverrun = false;
517
+ let capTimer;
518
+ const cap = new Promise((_resolve, reject) => {
519
+ capTimer = setTimeout(() => {
520
+ this.isRecoveringFromCapOverrun = true;
521
+ reject(
522
+ new import_eval_cap_exceeded_error.EvalCapExceededError({
523
+ capInMilliseconds: budgetInMilliseconds,
524
+ cause: new Error(`The Appium Execute Script carrying this closure did not answer within ${String(budgetInMilliseconds)}ms.`),
525
+ optionName: "scriptTimeoutInMilliseconds",
526
+ transportName: "Android (Appium)"
527
+ })
528
+ );
529
+ }, budgetInMilliseconds);
530
+ });
531
+ try {
532
+ return await Promise.race([
533
+ this.browser.execute(script),
534
+ cap
535
+ ]);
536
+ } finally {
537
+ if (capTimer !== void 0) {
538
+ clearTimeout(capTimer);
539
+ }
540
+ }
541
+ }
477
542
  /**
478
543
  * Converts a host-side vault path to the device-side path.
479
544
  *
@@ -704,4 +769,4 @@ function extractVaultName(vaultPath) {
704
769
  AppiumTransport,
705
770
  DEFAULT_ANDROID_VAULT_BASE_PATH
706
771
  });
707
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1hcHBpdW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBcHBpdW0gdHJhbnNwb3J0IFx1MjAxNCBldmFsdWF0ZXMgZXhwcmVzc2lvbnMgaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSB2aWEgV2ViVmlld1xuICogSmF2YVNjcmlwdCBpbmplY3Rpb24uIE1hbmFnZXMgdmF1bHQgbGlmZWN5Y2xlIHZpYSBsb2NhbFN0b3JhZ2UgYW5kIGZpbGUgcHVzaC5cbiAqXG4gKiBDb25maWd1cmVkIHZpYSBgZW52aXJvbm1lbnRPcHRpb25zLm9ic2lkaWFuVHJhbnNwb3J0YCBpbiB2aXRlc3QgY29uZmlnOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHZpdGVzdC5jb25maWcudHNcbiAqIGVudmlyb25tZW50T3B0aW9uczoge1xuICogICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICogICAgIHR5cGU6ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScsXG4gKiAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAqICAgICBhdmROYW1lOiAnb2JzaWRpYW5fdGVzdCcsXG4gKiAgIH0sXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBGb3IgQnJvd3NlclN0YWNrLCBzZXQgYGFwcGl1bVVybGAgdG8gdGhlIEJyb3dzZXJTdGFjayBodWIgVVJMXG4gKiBcdTIwMTQgdGhlIHRyYW5zcG9ydCBpdHNlbGYgaXMgaHViLWFnbm9zdGljLlxuICpcbiAqICMjIEhvdyB2YXVsdCByZWdpc3RyYXRpb24gd29ya3Mgb24gbW9iaWxlXG4gKlxuICogT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHQgcmVnaXN0cnkgaW4gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYDpcbiAqXG4gKiAtIGBtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzYCBcdTIwMTQgSlNPTiBhcnJheSBvZiByZWdpc3RlcmVkIHZhdWx0IHBhdGhzXG4gKiAtIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgIFx1MjAxNCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2YXVsdCBwYXRoXG4gKiAtIGBlbmFibGUtcGx1Z2luLTx2YXVsdFBhdGg+YCBcdTIwMTQgYFwidHJ1ZVwiYCB0byBlbmFibGUgdGhlIHBsdWdpbiBzeXN0ZW0gZm9yIHRoZSB2YXVsdFxuICpcbiAqIFRvIHJlZ2lzdGVyIGEgdmF1bHQgcHJvZ3JhbW1hdGljYWxseSAod2l0aG91dCBVSSBpbnRlcmFjdGlvbik6XG4gKlxuICogMS4gUHVzaCB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIChlLmcuIGAvc2RjYXJkL0RvY3VtZW50cy88TmFtZT4vLm9ic2lkaWFuL2FwcC5qc29uYClcbiAqIDIuIFN3aXRjaCB0byBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dFxuICogMy4gU2V0IHRoZSBsb2NhbFN0b3JhZ2UgZW50cmllc1xuICogNC4gQ2FsbCBgbG9jYXRpb24ucmVsb2FkKClgIFx1MjAxNCBPYnNpZGlhbiByZS1yZWFkcyBsb2NhbFN0b3JhZ2UgYW5kIG9wZW5zIHRoZSB2YXVsdFxuICpcbiAqIFRoaXMgYXZvaWRzIHRoZSBvbmJvYXJkaW5nIGZsb3cgZW50aXJlbHkuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBCcm93c2VyIH0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgcm0sXG4gIHdyaXRlRmlsZVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHtcbiAgQXBwU3RhcnR1cE1pbGVzdG9uZSxcbiAgQXBwU3RhcnR1cFBoYXNlLFxuICBTdGFydHVwUHJvYmVSZXN1bHRcbn0gZnJvbSAnLi9hcHAtc3RhcnR1cC1wcm9ncmVzcy5janMnO1xuaW1wb3J0IHR5cGUgeyBDYXB0dXJlU2NyZWVuc2hvdFBhcmFtcyB9IGZyb20gJy4vY2FwdHVyZS1zY3JlZW5zaG90LmNqcyc7XG5pbXBvcnQgdHlwZSB7IE1vYmlsZUlucHV0RW52ZWxvcGUgfSBmcm9tICcuL21vYmlsZS1pbnB1dC5janMnO1xuaW1wb3J0IHR5cGUge1xuICBDb25zb2xlQ2FwdHVyZUhhbmRsZSxcbiAgT2JzaWRpYW5UcmFuc3BvcnQsXG4gIFRyYW5zcG9ydEV2YWxPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5pbXBvcnQgdHlwZSB7IFdlYlZpZXdDZHBDb25uZWN0aW9uIH0gZnJvbSAnLi93ZWJ2aWV3LWNkcC5janMnO1xuXG5pbXBvcnQge1xuICBidWlsZFN0YXJ0dXBUaW1lb3V0TWVzc2FnZSxcbiAgY2hlY2tBcHBTdGFydGVkLFxuICBjaGVja0xheW91dFJlYWR5LFxuICBjbGFzc2lmeUFwcFN0YXJ0dXBQcm9iZSxcbiAgY29tcGFyZUFwcFN0YXJ0dXBNaWxlc3RvbmVzXG59IGZyb20gJy4vYXBwLXN0YXJ0dXAtcHJvZ3Jlc3MuY2pzJztcbmltcG9ydCB7XG4gIGRlY29kZUJhc2U2NFBuZyxcbiAgaXNQbmdcbn0gZnJvbSAnLi9jYXB0dXJlLXNjcmVlbnNob3QuY2pzJztcbmltcG9ydCB7IGVycm9yVG9TdHJpbmcgfSBmcm9tICcuL2Vycm9yLXRvLXN0cmluZy5janMnO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJy4vZXhlYy5janMnO1xuaW1wb3J0IHsgVEVNUF9WQVVMVF9ESVJfUFJFRklYIH0gZnJvbSAnLi9sZWZ0b3Zlci1jbGVhbnVwLmNqcyc7XG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRDbGFpbUlucHV0RXhwcmVzc2lvbixcbiAgYnVpbGRSZXNvbHZlSW5wdXRFeHByZXNzaW9uLFxuICBjaGVja0lucHV0Q2xhaW1HcmFudGVkLFxuICBNT0JJTEVfSU5QVVRfQklORElOR19OQU1FLFxuICB0b0NkcElucHV0Q29tbWFuZHNcbn0gZnJvbSAnLi9tb2JpbGUtaW5wdXQuY2pzJztcbmltcG9ydCB7IGNvbm5lY3RUb1dlYlZpZXdDZHAgfSBmcm9tICcuL3dlYnZpZXctY2RwLmNqcyc7XG5cbi8qKlxuICogU2Vzc2lvbiBjb25uZWN0aW9uIGluZm8gcmV0dXJuZWQgYnkge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5nZXRTZXNzaW9uSW5mb30sXG4gKiB1c2VkIHRvIHJlYXR0YWNoIGZyb20gYW5vdGhlciBwcm9jZXNzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgLyoqXG4gIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuXG4gICAqL1xuICBkZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgQXBwaXVtL1dlYkRyaXZlciBzZXNzaW9uIElELlxuICAgKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIEFwcGl1bSB0cmFuc3BvcnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwaXVtVHJhbnNwb3J0Q29uZmlnIHtcbiAgLyoqXG4gICAqIEFwcCBwYWNrYWdlIChBbmRyb2lkKSBvciBidW5kbGUgSUQgKGlPUykuXG4gICAqIERlZmF1bHRzIHRvIGAnbWQub2JzaWRpYW4nYC5cbiAgICovXG4gIGFwcElkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgT2JzaWRpYW4gTW9iaWxlIHRvIGdldCBhcyBmYXIgYXMgYGdsb2JhbFRoaXMuYXBwYFxuICAgKiBleGlzdGluZyBhZnRlciB0aGUgdmF1bHQgaXMgKHJlKW9wZW5lZCwgYmVmb3JlIHRoZSB0aWdodGVyXG4gICAqIHtAbGluayBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kc30gY2xvY2sgc3RhcnRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMTgwMDAwYFxuICAgKi9cbiAgYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBBcHBpdW0gYnJvd3Nlci9kcml2ZXIgaW5zdGFuY2UuXG4gICAqIENyZWF0ZWQgYnkgdGhlIGNvbnN1bWVyIHZpYSBlLmcuIFdlYkRyaXZlcklPJ3MgYHJlbW90ZSgpYC5cbiAgICovXG4gIGJyb3dzZXI6IEJyb3dzZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuXG4gICAqIFVzZWQgZm9yIGBhZGJgIGNvbW1hbmRzIHdoZW4gcHVzaGluZyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICAgKi9cbiAgZGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHRyYW5zcG9ydCBvd25zIHRoZSBBcHBpdW0gc2Vzc2lvbiBhbmQgc2hvdWxkIGRlbGV0ZSBpdCBvblxuICAgKiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LmRpc3Bvc2V9LlxuICAgKlxuICAgKiBgdHJ1ZWAgZm9yIHNlc3Npb25zIGNyZWF0ZWQgdmlhIGByZW1vdGUoKWAgKGdsb2JhbCBzZXR1cCkuXG4gICAqIGBmYWxzZWAgZm9yIHNlc3Npb25zIHJlYXR0YWNoZWQgdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycykuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgaXNTZXNzaW9uT3duZXI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3Igd2FpdGluZyBmb3IgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgLCBjb3VudGVkXG4gICAqIGZyb20gdGhlIG1vbWVudCB7QGxpbmsgYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHN9IGlzIHNhdGlzZmllZCBcdTIwMTQgbm90IGZyb21cbiAgICogdGhlIHJlbG9hZCwgc28gYSBjb2xkIGFwcCBzdGFydCBpcyBub3QgY2hhcmdlZCBhZ2FpbnN0IGl0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgOTAwMDBgXG4gICAqL1xuICBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogVGFyZ2V0IHBsYXRmb3JtLiBEZXRlcm1pbmVzIFdlYlZpZXcgY29udGV4dCBuYW1pbmcgYW5kIGRldmljZSBmaWxlIHBhdGhzLlxuICAgKi9cbiAgcGxhdGZvcm06ICdhbmRyb2lkJyB8ICdpb3MnO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHJlZ2lzdGVyaW5nIGEgdmF1bHQgYWxzbyBwcnVuZXMgdGhlICoqb3RoZXIqKiBgdGVtcC12YXVsdC0qYFxuICAgKiByZWdpc3RyYXRpb25zIGVhcmxpZXIgcnVucyBsZWZ0IGluIE9ic2lkaWFuIE1vYmlsZSdzIGBsb2NhbFN0b3JhZ2VgLlxuICAgKlxuICAgKiBUaGUgZGV2aWNlLXNpZGUgZGlyZWN0b3JpZXMgYXJlIHN3ZXB0IGJlZm9yZSB0aGUgYXBwIGxhdW5jaGVzIChzZWUgdGhlXG4gICAqIGZhY3RvcnkpOyB0aGlzIHJlbW92ZXMgdGhlaXIgbm93LWRhbmdsaW5nIHJlZ2lzdHJ5IGVudHJpZXMsIHdoaWNoIGFyZSB3aGF0XG4gICAqIE9ic2lkaWFuIGFjdHVhbGx5IGVudW1lcmF0ZXMgYXQgc3RhcnR1cC4gVW5yZWdpc3RlcmluZyB0aGlzIHJ1bidzIG93biB2YXVsdFxuICAgKiBpcyB1bmFmZmVjdGVkIFx1MjAxNCB0aGF0IGFsd2F5cyBoYXBwZW5zLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHNob3VsZFN3ZWVwTGVmdG92ZXJzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQmFzZSBwYXRoIG9uIHRoZSBkZXZpY2Ugd2hlcmUgT2JzaWRpYW4gc3RvcmVzIHZhdWx0cy5cbiAgICpcbiAgICogRGVmYXVsdHM6XG4gICAqIC0gQW5kcm9pZDogYC9zZGNhcmQvRG9jdW1lbnRzL2BcbiAgICogLSBpT1M6IGBAbWQub2JzaWRpYW46ZG9jdW1lbnRzL2BcbiAgICovXG4gIHZhdWx0QmFzZVBhdGg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB3YWl0aW5nIGZvciB0aGUgV2ViVmlldyBjb250ZXh0IHRvIGJlY29tZSBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA2MDAwMGBcbiAgICovXG4gIHdlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG59XG5cbmNvbnN0IE5PX09VVFBVVCA9ICcobm8gb3V0cHV0KSc7XG5jb25zdCBBUFBfU1RBVEVfRk9SRUdST1VORCA9IDQ7XG5jb25zdCBXRUJWSUVXX0NPTlRFWFRfUFJFRklYID0gJ1dFQlZJRVdfbWQub2JzaWRpYW4nO1xuY29uc3QgV0VCVklFV19QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IERFRkFVTFRfV0VCVklFV19QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNjBfMDAwO1xuY29uc3QgTEFZT1VUX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgREVGQVVMVF9MQVlPVVRfUkVBRFlfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDkwXzAwMDtcbmNvbnN0IERFRkFVTFRfQVBQX1NUQVJUX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxODBfMDAwO1xuY29uc3QgQVBQX1JFU1RBUlRfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gMjAwMDtcbmNvbnN0IERFRkFVTFRfQVBQX0lEID0gJ21kLm9ic2lkaWFuJztcbmNvbnN0IEFEQl9WQVVMVF9SRU1PVkVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG5cbi8vIC0tLSBDb25zb2xlIGNhcHR1cmUgKExheWVyIDIgb2YgdGhlIHBsdWdpbi1sb2FkIGVycm9yIHN1cmZhY2luZykgLS0tXG5jb25zdCBDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBRyA9ICdPSVRfQ0FQVFVSRSc7XG5jb25zdCBDT05TT0xFX0NBUFRVUkVfVEFJTF9NQVhfTEVOR1RIID0gODAwMDtcbmNvbnN0IEFEQl9MT0dfTUFSS0VSX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IExPR0NBVF9EVU1QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTBfMDAwO1xuLyoqXG4gKiBgYWRiIGxvZ2NhdCAtdiB0aW1lYCBsaW5lcyBsb29rIGxpa2UgYE1NLUREIEhIOk1NOlNTLm1tbSBMRVZFTC9UQUcoIFBJRCk6IG1lc3NhZ2VgLlxuICogS2VlcCBvbmx5IHRoZSB0YWdzIENocm9taXVtL1dlYlZpZXcgcm91dGVzIEpTIGBjb25zb2xlLipgIG91dHB1dCBhbmQgdW5jYXVnaHRcbiAqIGVycm9ycyB0byAoYGNocm9taXVtYCwgdGhlIENhcGFjaXRvciBjb25zb2xlIGJyaWRnZSwgYW5kIG5hdGl2ZSBgQW5kcm9pZFJ1bnRpbWVgKS5cbiAqL1xuY29uc3QgQ09OU09MRV9DQVBUVVJFX1RBR19SRSA9IC9cXC8oPzpjaHJvbWl1bXxBbmRyb2lkUnVudGltZXxDYXBhY2l0b3JcXC9Db25zb2xlKVxcKC87XG5cbi8qKlxuICogQmFzZSBwYXRoIG9uIGFuIEFuZHJvaWQgZGV2aWNlIHdoZXJlIE9ic2lkaWFuIE1vYmlsZSBzdG9yZXMgaXRzIHZhdWx0cy5cbiAqXG4gKiBFeHBvcnRlZCBiZWNhdXNlIHRoZSB0cmFuc3BvcnQgZmFjdG9yeSBzd2VlcHMgbGVmdG92ZXIgdmF1bHRzIGZyb20gaXQgYmVmb3JlXG4gKiBhIHRyYW5zcG9ydCBleGlzdHMgKHNlZSB0aGUgcmVwbydzIEwzMSkuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRIID0gJy9zZGNhcmQvRG9jdW1lbnRzLyc7XG5cbmNvbnN0IERFRkFVTFRfVkFVTFRfQkFTRV9QQVRIOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBhbmRyb2lkOiBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRILFxuICBpb3M6ICdAbWQub2JzaWRpYW46ZG9jdW1lbnRzLydcbn07XG5cbmludGVyZmFjZSBMb2FkaW5nQXBwIHtcbiAgd29ya3NwYWNlPzogTG9hZGluZ1dvcmtzcGFjZTtcbn1cblxuaW50ZXJmYWNlIExvYWRpbmdXb3Jrc3BhY2Uge1xuICBsYXlvdXRSZWFkeT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIEFwcGl1bVRyYW5zcG9ydC53YWl0Rm9yU3RhcnR1cE1pbGVzdG9uZX0uXG4gKi9cbmludGVyZmFjZSBXYWl0Rm9yU3RhcnR1cE1pbGVzdG9uZVBhcmFtcyB7XG4gIC8qKlxuICBXaGV0aGVyIHRoZSBtaWxlc3RvbmUganVzdCBvYnNlcnZlZCBlbmRzIHRoaXMgcGhhc2UuXG4gICAqL1xuICByZWFkb25seSBpc1NhdGlzZmllZDogKG1pbGVzdG9uZTogQXBwU3RhcnR1cE1pbGVzdG9uZSkgPT4gYm9vbGVhbjtcblxuICAvKipcbiAgVGhlIHBoYXNlIGJlaW5nIHdhaXRlZCBvdXQsIG5hbWVkIGluIHRoZSBsb2cgYW5kIGluIHRoZSB0aW1lb3V0IG1lc3NhZ2UuXG4gICAqL1xuICByZWFkb25seSBwaGFzZTogQXBwU3RhcnR1cFBoYXNlO1xuXG4gIC8qKlxuICBUaGlzIHBoYXNlJ3MgYnVkZ2V0LlxuICAgKi9cbiAgcmVhZG9ubHkgdGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogVHJhbnNwb3J0IHRoYXQgY29tbXVuaWNhdGVzIHdpdGggT2JzaWRpYW4gTW9iaWxlIHZpYSBBcHBpdW0gV2ViVmlldyBKUyBpbmplY3Rpb24uXG4gKlxuICogRXZhbHVhdGVzIGV4cHJlc3Npb25zIGJ5IHN3aXRjaGluZyB0byB0aGUgYFdFQlZJRVdfbWQub2JzaWRpYW5gIGNvbnRleHQgYW5kXG4gKiBjYWxsaW5nIGBleGVjdXRlKClgLiBNYW5hZ2VzIHZhdWx0cyBieSB3cml0aW5nIHRvIHRoZSBXZWJWaWV3J3MgYGxvY2FsU3RvcmFnZWBcbiAqICh3aGljaCBPYnNpZGlhbiB1c2VzIGFzIGl0cyB2YXVsdCByZWdpc3RyeSBvbiBtb2JpbGUpIGFuZCBwdXNoaW5nIGZpbGVzIHRvIHRoZSBkZXZpY2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBBcHBpdW1UcmFuc3BvcnQgaW1wbGVtZW50cyBPYnNpZGlhblRyYW5zcG9ydCB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIHRyYW5zcG9ydCBpcyBmb3IgYSBtb2JpbGUgcGxhdGZvcm0uIEFsd2F5cyBgdHJ1ZWAgZm9yIHRoaXMgdHJhbnNwb3J0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlzTW9iaWxlID0gdHJ1ZTtcbiAgcHJpdmF0ZSByZWFkb25seSBhcHBJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGFwcFN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgYnJvd3NlcjogQnJvd3NlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXZpY2VJZDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGBwcm9jZXNzLm9uKCdleGl0JylgIGhhbmRsZXIgdGhhdCB0ZWFycyB0aGUgY2hhbm5lbCBkb3duIHdoZW4gbm90aGluZyBlbHNlIHdpbGwuXG4gICAqL1xuICBwcml2YXRlIGRpc3Bvc2VJbnB1dENoYW5uZWxPbkV4aXQ6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogVGhlIGhvc3QgaGFsZiBvZiB0aGUgdHJ1c3RlZC1pbnB1dCBjaGFubmVsOiBhIENEUCBjb25uZWN0aW9uIHRvIHRoZSBXZWJWaWV3LCBpbmRlcGVuZGVudCBvZiB0aGVcbiAgICogQXBwaXVtIHNlc3Npb24sIG9wZW5lZCBsYXppbHkgb24gZmlyc3QgZXZhbHVhdGUgYW5kIHJldXNlZCAoc2VlICoqTDM5KiopLlxuICAgKi9cbiAgcHJpdmF0ZSBpbnB1dENoYW5uZWw6IG51bGwgfCBXZWJWaWV3Q2RwQ29ubmVjdGlvbiA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFNldCBvbmNlIHRoZSB0cnVzdGVkLWlucHV0IGNoYW5uZWwgaXMga25vd24gbm90IHRvIGJlIG9wZW5hYmxlIGhlcmUgKGlPUywgYSByZW1vdGUgaHViLCBubyBsb2NhbFxuICAgKiBgYWRiYCksIHNvIHRoZSBhdHRlbXB0IGlzIG5vdCByZXBlYXRlZCBvbiBldmVyeSBldmFsdWF0ZS5cbiAgICovXG4gIHByaXZhdGUgaXNJbnB1dENoYW5uZWxVbmF2YWlsYWJsZSA9IGZhbHNlO1xuICAvKipcbiAgICogVHJhY2tzIHdoZXRoZXIgdGhlIGRyaXZlciBpcyBjdXJyZW50bHkgc3dpdGNoZWQgdG8gdGhlIFdlYlZpZXcgY29udGV4dC5cbiAgICpcbiAgICogU2V0IHRvIGB0cnVlYCBhZnRlciBhIHN1Y2Nlc3NmdWwgYHN3aXRjaENvbnRleHQoV0VCVklFV19tZC5vYnNpZGlhbilgLlxuICAgKiBSZXNldCB0byBgZmFsc2VgIHdoZW4gdGhlIGNvbnRleHQgaXMga25vd24gdG8gYmUgaW52YWxpZGF0ZWRcbiAgICogKGUuZy4gYWZ0ZXIgYGxvY2F0aW9uLnJlbG9hZCgpYCBpbiB7QGxpbmsgcmVnaXN0ZXJWYXVsdH0pLlxuICAgKlxuICAgKiBXaGVuIGB0cnVlYCwge0BsaW5rIGVuc3VyZVdlYlZpZXdDb250ZXh0fSBza2lwcyB0aGUgZXhwZW5zaXZlXG4gICAqIGBnZXRDb250ZXh0cygpYCBjYWxsICh3aGljaCBydW5zIGBhZGIgc2hlbGwgY2F0IC9wcm9jL25ldC91bml4YCBhbmRcbiAgICogY2FuIHRpbWUgb3V0IG9uIHNsb3cgZW11bGF0b3JzKS5cbiAgICovXG4gIHByaXZhdGUgaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNTZXNzaW9uT3duZXI6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybTogJ2FuZHJvaWQnIHwgJ2lvcyc7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgdmF1bHRCYXNlUGF0aDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IEFwcGl1bSB0cmFuc3BvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBBcHBpdW0gdHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnOiBBcHBpdW1UcmFuc3BvcnRDb25maWcpIHtcbiAgICB0aGlzLmJyb3dzZXIgPSBjb25maWcuYnJvd3NlcjtcbiAgICB0aGlzLmRldmljZUlkID0gY29uZmlnLmRldmljZUlkO1xuICAgIHRoaXMuaXNTZXNzaW9uT3duZXIgPSBjb25maWcuaXNTZXNzaW9uT3duZXIgPz8gdHJ1ZTtcbiAgICB0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID0gY29uZmlnLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfTEFZT1VUX1JFQURZX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgdGhpcy5wbGF0Zm9ybSA9IGNvbmZpZy5wbGF0Zm9ybTtcbiAgICB0aGlzLmFwcElkID0gY29uZmlnLmFwcElkID8/IERFRkFVTFRfQVBQX0lEO1xuICAgIHRoaXMuYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBjb25maWcuYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9BUFBfU1RBUlRfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgICB0aGlzLnNob3VsZFN3ZWVwTGVmdG92ZXJzID0gY29uZmlnLnNob3VsZFN3ZWVwTGVmdG92ZXJzID8/IHRydWU7XG4gICAgdGhpcy52YXVsdEJhc2VQYXRoID0gY29uZmlnLnZhdWx0QmFzZVBhdGggPz8gREVGQVVMVF9WQVVMVF9CQVNFX1BBVEhbdGhpcy5wbGF0Zm9ybV0gPz8gREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSDtcbiAgICB0aGlzLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBjb25maWcud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyA/PyBERUZBVUxUX1dFQlZJRVdfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgfVxuXG4gIC8qKlxuICAgKiBCZWdpbnMgYSBjb25zb2xlIGNhcHR1cmUgYnkgc3RhbXBpbmcgdGhlIGRldmljZSBsb2cgd2l0aCBhIHVuaXF1ZSBtYXJrZXIuXG4gICAqXG4gICAqIFVzZXMgYGFkYiBzaGVsbCBsb2dgIHRvIHdyaXRlIGEgbWFya2VyIGludG8gYGxvZ2NhdGAgYXQgY2FwdHVyZSBzdGFydCBzbyBhXG4gICAqIGxhdGVyIHtAbGluayBBcHBpdW1UcmFuc3BvcnQucmVhZENvbnNvbGVDYXB0dXJlU2luY2V9IGNhbiBzbGljZSBvdXRcbiAgICogZXZlcnl0aGluZyB0aGUgV2ViVmlldyBsb2dnZWQgYWZ0ZXJ3YXJkcyBcdTIwMTQgd2l0aG91dCB0aGUgaW52YXNpdmUgYGxvZ2NhdCAtY2BcbiAgICogYnVmZmVyIGNsZWFyLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIGhhbmRsZSBjYXJyeWluZyB0aGUgdW5pcXVlIG1hcmtlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBiZWdpbkNvbnNvbGVDYXB0dXJlKCk6IFByb21pc2U8Q29uc29sZUNhcHR1cmVIYW5kbGU+IHtcbiAgICBjb25zdCBtYXJrZXIgPSBgJHtDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBR31fJHtyYW5kb21VVUlEKCl9YDtcbiAgICBhd2FpdCBleGVjKFxuICAgICAgWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbG9nJywgJy10JywgQ09OU09MRV9DQVBUVVJFX01BUktFUl9UQUcsIG1hcmtlcl0sXG4gICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9MT0dfTUFSS0VSX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICApO1xuICAgIHJldHVybiB7IG1hcmtlciB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENhcHR1cmVzIGEgUE5HIHNjcmVlbnNob3Qgb2YgdGhlIGRldmljZSdzIHNjcmVlbi5cbiAgICpcbiAgICogVGhlIGltYWdlIGlzIGFsd2F5cyB0aGUgZGV2aWNlJ3MgbmF0aXZlIGZyYW1lYnVmZmVyIFx1MjAxNCB0aGVyZSBpcyBubyBtb2JpbGVcbiAgICogZXF1aXZhbGVudCBvZiB0aGUgZGVza3RvcCB2aWV3cG9ydCBvdmVycmlkZSwgc29cbiAgICoge0BsaW5rIENhcHR1cmVTY3JlZW5zaG90UGFyYW1zLndpZHRoSW5QaXhlbHN9IC9cbiAgICoge0BsaW5rIENhcHR1cmVTY3JlZW5zaG90UGFyYW1zLmhlaWdodEluUGl4ZWxzfSBhcmUgaWdub3JlZC4gU2l6ZSBhIG1vYmlsZVxuICAgKiBjYXB0dXJlIGJ5IGNob29zaW5nIGFuIEFWRCB3aG9zZSBzY3JlZW4gZ2VvbWV0cnkgYWxyZWFkeSBtYXRjaGVzIHdoYXQgdGhlXG4gICAqIGltYWdlIGhhcyB0byBiZS5cbiAgICpcbiAgICogQHBhcmFtIF9wYXJhbXMgLSBDYXB0dXJlIHBhcmFtZXRlcnMuIElnbm9yZWQgb24gbW9iaWxlOiBgY3dkYCBkb2VzIG5vdCBzZWxlY3QgYSB3aW5kb3cgKHZhdWx0IHRhcmdldGluZyBpcyB2aWEgbG9jYWxTdG9yYWdlKSwgYW5kIHRoZSBzaXplIGNhbm5vdCBiZSBvdmVycmlkZGVuLlxuICAgKiBAcmV0dXJucyBUaGUgcmF3IFBORyBieXRlcy5cbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgZHJpdmVyIHJldHVybnMgZGF0YSB0aGF0IGlzIG5vdCBhIFBORy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBjYXB0dXJlU2NyZWVuc2hvdChfcGFyYW1zOiBDYXB0dXJlU2NyZWVuc2hvdFBhcmFtcyk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIGNvbnN0IGJ5dGVzID0gZGVjb2RlQmFzZTY0UG5nKGF3YWl0IHRoaXMuYnJvd3Nlci50YWtlU2NyZWVuc2hvdCgpKTtcbiAgICBpZiAoIWlzUG5nKGJ5dGVzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcHBpdW0gc2NyZWVuc2hvdCBlcnJvcjogdGFrZVNjcmVlbnNob3QgcmV0dXJuZWQgZGF0YSB0aGF0IGlzIG5vdCBhIFBORy4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogRW5kcyB0aGUgQXBwaXVtIHNlc3Npb24uXG4gICAqXG4gICAqIE9ubHkgZGVsZXRlcyB0aGUgc2Vzc2lvbiBpZiB0aGlzIHRyYW5zcG9ydCBvd25zIGl0LiBUcmFuc3BvcnRzIGNyZWF0ZWRcbiAgICogdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycyByZXVzaW5nIHRoZSBnbG9iYWwgc2V0dXAncyBzZXNzaW9uKSBza2lwXG4gICAqIGRlbGV0aW9uIHNvIHRoZSBzZXNzaW9uIHJlbWFpbnMgYXZhaWxhYmxlIGZvciB0aGUgb3duaW5nIHByb2Nlc3MuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWwoKTtcblxuICAgIGlmICh0aGlzLmlzU2Vzc2lvbk93bmVyKSB7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuZGVsZXRlU2Vzc2lvbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jaHJvbm91cyB0ZWFyZG93biBmb3IgYHByb2Nlc3Mub24oJ2V4aXQnKWAgaGFuZGxlcnMuXG4gICAqXG4gICAqIE9ubHkgdGhlIHRydXN0ZWQtaW5wdXQgY2hhbm5lbCBuZWVkcyBpdDogdGhlIEFwcGl1bSBzZXNzaW9uIGlzIHRoZSBvd25pbmcgcHJvY2VzcydzIHRvIGVuZCwgYW5kIGFuXG4gICAqIGFicnVwdCBleGl0IGlzIGV4YWN0bHkgd2hlbiB0aGUgYXN5bmMge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5kaXNwb3NlfSBuZXZlciBydW5zIFx1MjAxNCB3aGljaCB3b3VsZCBzdHJhbmRcbiAgICogdGhlIGFkYiBwb3J0IGZvcndhcmQgb24gdGhlIGRldmljZS5cbiAgICovXG4gIHB1YmxpYyBkaXNwb3NlU3luYygpOiB2b2lkIHtcbiAgICBjb25zdCBjaGFubmVsID0gdGhpcy5pbnB1dENoYW5uZWw7XG4gICAgdGhpcy5pbnB1dENoYW5uZWwgPSBudWxsO1xuICAgIHRoaXMudW5yZWdpc3RlcklucHV0Q2hhbm5lbEV4aXRIYW5kbGVyKCk7XG4gICAgY2hhbm5lbD8uZGlzcG9zZVN5bmMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZXMgYSBKYXZhU2NyaXB0IGV4cHJlc3Npb24gaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSdzIFdlYlZpZXcuXG4gICAqXG4gICAqIFN3aXRjaGVzIHRvIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dCwgZXhlY3V0ZXMgdGhlIGV4cHJlc3Npb24sXG4gICAqIGFuZCByZXR1cm5zIHRoZSByZXN1bHQgc3RyaW5nLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwcmVzc2lvbiAtIFRoZSBKYXZhU2NyaXB0IGV4cHJlc3Npb24gdG8gZXZhbHVhdGUuXG4gICAqIEBwYXJhbSBfb3B0aW9ucyAtIEV2YWx1YXRpb24gb3B0aW9ucyAoY3dkIGlzIG5vdCB1c2VkIG9uIG1vYmlsZSBcdTIwMTQgdmF1bHQgdGFyZ2V0aW5nIGlzIHZpYSBsb2NhbFN0b3JhZ2UpLlxuICAgKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCByZXN1bHQgc3RyaW5nLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGV2YWx1YXRlKGV4cHJlc3Npb246IHN0cmluZywgX29wdGlvbnM6IFRyYW5zcG9ydEV2YWxPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVJbnB1dENoYW5uZWwoKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZTxudWxsIHwgc3RyaW5nIHwgdW5kZWZpbmVkLCBbXT4oXG4gICAgICAgIGByZXR1cm4gKCR7ZXhwcmVzc2lvbn0pYFxuICAgICAgKTtcblxuICAgICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gTk9fT1VUUFVUO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvLyBDb250ZXh0IG1heSBoYXZlIGJlZW4gbG9zdCBtaWQtZXhlY3V0aW9uIChlLmcuIHBhZ2UgcmVsb2FkKS5cbiAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2Vzc2lvbiBjb25uZWN0aW9uIGluZm8gbmVlZGVkIHRvIHJlYXR0YWNoIHRvIHRoaXMgc2Vzc2lvblxuICAgKiBmcm9tIGFub3RoZXIgcHJvY2VzcyAoZS5nLiBhIHRlc3Qgd29ya2VyKS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHNlc3Npb24gSUQgYW5kIGRldmljZSBJRC5cbiAgICovXG4gIHB1YmxpYyBnZXRTZXNzaW9uSW5mbygpOiBBcHBpdW1TZXNzaW9uSW5mbyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRldmljZUlkOiB0aGlzLmRldmljZUlkLFxuICAgICAgc2Vzc2lvbklkOiB0aGlzLmJyb3dzZXIuc2Vzc2lvbklkXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyB0aGF0IHRoZSBPYnNpZGlhbiBhcHAgaXMgcnVubmluZyBhbmQgdGhlIFdlYlZpZXcgaXMgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gX3ZhdWx0UGF0aCAtIE5vdCB1c2VkIG9uIG1vYmlsZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBwcmVmbGlnaHRDaGVjayhfdmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBSdW5uaW5nIHByZWZsaWdodCBjaGVjay4uLicpO1xuICAgIGNvbnN0IHN0YXRlID0gYXdhaXQgdGhpcy5icm93c2VyLnF1ZXJ5QXBwU3RhdGUodGhpcy5hcHBJZCk7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gQXBwIHN0YXRlOiAke1N0cmluZyhzdGF0ZSl9IChuZWVkICR7U3RyaW5nKEFQUF9TVEFURV9GT1JFR1JPVU5EKX09Zm9yZWdyb3VuZClgKTtcbiAgICBpZiAoc3RhdGUgIT09IEFQUF9TVEFURV9GT1JFR1JPVU5EKSB7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBBY3RpdmF0aW5nIGFwcCAke3RoaXMuYXBwSWR9Li4uYCk7XG4gICAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IGZhbHNlO1xuICAgICAgYXdhaXQgdGhpcy5icm93c2VyLmFjdGl2YXRlQXBwKHRoaXMuYXBwSWQpO1xuICAgICAgYXdhaXQgZGVsYXkoQVBQX1JFU1RBUlRfREVMQVlfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG4gICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gUHJlZmxpZ2h0IGNoZWNrIHBhc3NlZC4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXNoZXMgdmF1bHQgZmlsZXMgdG8gdGhlIGRldmljZSB2aWEgY29tcHJlc3NlZCBgYWRiIHB1c2hgLlxuICAgKlxuICAgKiBDcmVhdGVzIGEgdGFyLmd6IGFyY2hpdmUgb2YgdGhlIGxvY2FsIHZhdWx0IGRpcmVjdG9yeSwgcHVzaGVzIGl0IHRvIHRoZVxuICAgKiBkZXZpY2UgYXMgYSBzaW5nbGUgZmlsZSwgYW5kIGV4dHJhY3RzIGl0IGluLXBsYWNlLiBUaGlzIGF2b2lkcyB0aGVcbiAgICogd2ViZHJpdmVyIGBSYW5nZUVycm9yYCBvbiBsYXJnZSBiYXNlNjQgcGF5bG9hZHMgYW5kIGlzIHNpZ25pZmljYW50bHlcbiAgICogZmFzdGVyIHRoYW4gcGVyLWZpbGUgYGJyb3dzZXIucHVzaEZpbGUoKWAgY2FsbHMuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgdmF1bHQgcGF0aCAodXNlZCBhcyB0aGUgdmF1bHQgZGlyZWN0b3J5IG5hbWUgb24gZGV2aWNlKS5cbiAgICogQHBhcmFtIF9maWxlcyAtIE1hcCBvZiByZWxhdGl2ZSBmaWxlIHBhdGhzIHRvIGNvbnRlbnQgYnVmZmVycyAodW51c2VkIFx1MjAxNCBhZGIgcHVzaGVzIHRoZSBkaXJlY3RvcnkgZGlyZWN0bHkpLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHB1c2hGaWxlcyh2YXVsdFBhdGg6IHN0cmluZywgX2ZpbGVzOiBSZWNvcmQ8c3RyaW5nLCBVaW50OEFycmF5Pik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRldmljZVZhdWx0UGF0aCA9IHRoaXMuZ2V0RGV2aWNlVmF1bHRQYXRoKHZhdWx0UGF0aCk7XG4gICAgY29uc3QgYXJjaGl2ZU5hbWUgPSBgdmF1bHQtJHtyYW5kb21VVUlEKCl9LnRhci5nemA7XG4gICAgY29uc3QgbG9jYWxBcmNoaXZlID0gam9pbih0bXBkaXIoKSwgYXJjaGl2ZU5hbWUpO1xuICAgIGNvbnN0IHJlbW90ZUFyY2hpdmUgPSBgL2RhdGEvbG9jYWwvdG1wLyR7YXJjaGl2ZU5hbWV9YDtcblxuICAgIHRyeSB7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBDcmVhdGluZyBhcmNoaXZlOiAke2xvY2FsQXJjaGl2ZX1gKTtcbiAgICAgIGF3YWl0IGV4ZWMoWyd0YXInLCAnY3pmJywgYXJjaGl2ZU5hbWUsICctQycsIHZhdWx0UGF0aCwgJy4nXSwgeyBjd2Q6IHRtcGRpcigpLCBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBQdXNoaW5nIGFyY2hpdmUgdG8gZGV2aWNlICR7dGhpcy5kZXZpY2VJZH0uLi5gKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAncHVzaCcsIGxvY2FsQXJjaGl2ZSwgcmVtb3RlQXJjaGl2ZV0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gRXh0cmFjdGluZyBhcmNoaXZlIG9uIGRldmljZSBhdCAke2RldmljZVZhdWx0UGF0aH0uLi5gKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbWtkaXInLCAnLXAnLCBkZXZpY2VWYXVsdFBhdGhdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3RhcicsICd4emYnLCByZW1vdGVBcmNoaXZlLCAnLUMnLCBkZXZpY2VWYXVsdFBhdGhdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG5cbiAgICAgIGxvZygnW2FwcGl1bS10cmFuc3BvcnRdIEZsdXNoaW5nIGZpbGVzeXN0ZW0gYnVmZmVycy4uLicpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdzeW5jJ10sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gQ2xlYW5pbmcgdXAgcmVtb3RlIGFyY2hpdmUuLi4nKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAncm0nLCByZW1vdGVBcmNoaXZlXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBybShsb2NhbEFyY2hpdmUsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIER1bXBzIGBhZGIgbG9nY2F0YCBhbmQgcmV0dXJucyB0aGUgV2ViVmlldyBjb25zb2xlL2Vycm9yIG91dHB1dCBsb2dnZWRcbiAgICogc2luY2UgdGhlIG1hcmtlciBmcm9tIHtAbGluayBBcHBpdW1UcmFuc3BvcnQuYmVnaW5Db25zb2xlQ2FwdHVyZX0uXG4gICAqXG4gICAqIEZpbHRlcnMgdG8gdGhlIENocm9taXVtL1dlYlZpZXcgdGFncyB0aGF0IGNhcnJ5IEpTIGBjb25zb2xlLipgIG91dHB1dCBhbmRcbiAgICogdW5jYXVnaHQgZXJyb3JzLCBhbmQgY2FwcyB0aGUgcmVzdWx0IGxlbmd0aC4gQm91bmRlZCwgcG9zdC1ob2MsXG4gICAqIGZhaWx1cmUtcGF0aC1vbmx5IFx1MjAxNCBuZXZlciBhIGxpdmUgbW9uaXRvci5cbiAgICpcbiAgICogQHBhcmFtIGhhbmRsZSAtIFRoZSBjYXB0dXJlIGhhbmRsZSAob3IgYHVuZGVmaW5lZGAgd2hlbiBjYXB0dXJlIG5ldmVyIHN0YXJ0ZWQpLlxuICAgKiBAcmV0dXJucyBUaGUgY2FwdHVyZWQgY29uc29sZS9lcnJvciB0ZXh0LCBvciBgdW5kZWZpbmVkYCBpZiBub3RoaW5nIHJlbGV2YW50IHdhcyBsb2dnZWQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVhZENvbnNvbGVDYXB0dXJlU2luY2UoaGFuZGxlOiBDb25zb2xlQ2FwdHVyZUhhbmRsZSB8IHVuZGVmaW5lZCk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKCFoYW5kbGUpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgZHVtcCA9IGF3YWl0IGV4ZWMoXG4gICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdsb2djYXQnLCAnLWQnLCAnLXYnLCAndGltZSddLFxuICAgICAgeyBpc1F1aWV0OiB0cnVlLCBzaG91bGRJZ25vcmVFeGl0Q29kZTogdHJ1ZSwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBMT0dDQVRfRFVNUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgKTtcblxuICAgIGNvbnN0IG1hcmtlckluZGV4ID0gZHVtcC5sYXN0SW5kZXhPZihoYW5kbGUubWFya2VyKTtcbiAgICBjb25zdCByZWdpb24gPSBtYXJrZXJJbmRleCA9PT0gLTEgPyBkdW1wIDogZHVtcC5zbGljZShtYXJrZXJJbmRleCArIGhhbmRsZS5tYXJrZXIubGVuZ3RoKTtcbiAgICBjb25zdCByZWxldmFudCA9IHJlZ2lvblxuICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgLmZpbHRlcigobGluZSkgPT4gQ09OU09MRV9DQVBUVVJFX1RBR19SRS50ZXN0KGxpbmUpKVxuICAgICAgLmpvaW4oJ1xcbicpXG4gICAgICAudHJpbSgpO1xuXG4gICAgaWYgKCFyZWxldmFudCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVsZXZhbnQuc2xpY2UoLUNPTlNPTEVfQ0FQVFVSRV9UQUlMX01BWF9MRU5HVEgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIHZhdWx0IG9uIG1vYmlsZSBieSBwdXNoaW5nIGZpbGVzIGFuZCBjb25maWd1cmluZyBsb2NhbFN0b3JhZ2UuXG4gICAqXG4gICAqIFRoZSByZWdpc3RyYXRpb24gZmxvdzpcbiAgICogMS4gUHVzaCBhIG1pbmltYWwgYC5vYnNpZGlhbi9hcHAuanNvbmAgdG8gdGhlIGRldmljZSBzbyBPYnNpZGlhbiByZWNvZ25pemVzIHRoZSB2YXVsdFxuICAgKiAyLiBTd2l0Y2ggdG8gdGhlIFdlYlZpZXcgY29udGV4dFxuICAgKiAzLiBBZGQgdGhlIHZhdWx0IHRvIGxvY2FsU3RvcmFnZSAoYG1vYmlsZS1leHRlcm5hbC12YXVsdHNgLCBgbW9iaWxlLXNlbGVjdGVkLXZhdWx0YCxcbiAgICogICAgYGVuYWJsZS1wbHVnaW4tPHBhdGg+YClcbiAgICogNC4gVHJpZ2dlciBgbG9jYXRpb24ucmVsb2FkKClgIHNvIE9ic2lkaWFuIHJlLXJlYWRzIGxvY2FsU3RvcmFnZSBhbmQgb3BlbnMgdGhlIHZhdWx0XG4gICAqIDUuIFdhaXQgZm9yIGBnbG9iYWxUaGlzLmFwcGAgdG8gZXhpc3QgKHRoZSBhcHAncyBjb2xkIHN0YXJ0KSwgdGhlbiBcdTIwMTQgb24gYVxuICAgKiAgICBzZXBhcmF0ZSwgdGlnaHRlciBidWRnZXQgXHUyMDE0IGZvciBgYXBwLndvcmtzcGFjZS5sYXlvdXRSZWFkeWBcbiAgICpcbiAgICogRXhpc3RpbmcgdmF1bHQgcmVnaXN0cmF0aW9ucyBpbiBsb2NhbFN0b3JhZ2UgYXJlIHByZXNlcnZlZCAoYXBwZW5kLCBub3RcbiAgICogb3ZlcndyaXRlKSBcdTIwMTQgZXhjZXB0IHRoZSAqKmhhcm5lc3MncyBvd24qKiBgdGVtcC12YXVsdC0qYCByZWdpc3RyYXRpb25zIGZyb21cbiAgICogZWFybGllciBydW5zLCB3aGljaCBhcmUgcHJ1bmVkIHdoZW4ge0BsaW5rIEFwcGl1bVRyYW5zcG9ydENvbmZpZy5zaG91bGRTd2VlcExlZnRvdmVyc31cbiAgICogaXMgb24uIFRoZWlyIGRpcmVjdG9yaWVzIGFyZSBhbHJlYWR5IGdvbmUgKHRoZSBmYWN0b3J5IHN3ZWVwcyB0aGVtIGJlZm9yZVxuICAgKiB0aGUgYXBwIGxhdW5jaGVzKSwgYW5kIGl0IGlzIHRoaXMgcmVnaXN0cnkgXHUyMDE0IG5vdCB0aGUgZmlsZXN5c3RlbSBcdTIwMTQgdGhhdFxuICAgKiBPYnNpZGlhbiBlbnVtZXJhdGVzIGF0IHN0YXJ0dXAsIHNvIGxlYXZpbmcgdGhlbSBpcyB3aGF0IG1ha2VzIGVhY2ggZmFpbGVkXG4gICAqIHJ1biBzbG93IHRoZSBuZXh0IG9uZSBkb3duLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IG9uIHRoZSBob3N0IG1hY2hpbmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVnaXN0ZXJWYXVsdCh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFJlZ2lzdGVyaW5nIHZhdWx0OiAke3ZhdWx0UGF0aH1gKTtcbiAgICBjb25zdCBkZXZpY2VWYXVsdFBhdGggPSB0aGlzLmdldERldmljZVZhdWx0UGF0aCh2YXVsdFBhdGgpO1xuXG4gICAgLy8gUHVzaCBhIG1pbmltYWwgLm9ic2lkaWFuIGRpcmVjdG9yeSBzbyBPYnNpZGlhbiByZWNvZ25pemVzIGl0IGFzIGEgdmF1bHQuXG4gICAgYXdhaXQgdGhpcy5wdXNoT2JzaWRpYW5NYXJrZXIoZGV2aWNlVmF1bHRQYXRoKTtcblxuICAgIC8vIFN3aXRjaCB0byBXZWJWaWV3IGFuZCBjb25maWd1cmUgbG9jYWxTdG9yYWdlLlxuICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcblxuICAgIC8vIEludmFsaWRhdGUgYmVmb3JlIHJlbG9hZCBcdTIwMTQgdGhlIHBhZ2Ugd2lsbCBuYXZpZ2F0ZSBhbmQgdGhlIFdlYlZpZXdcbiAgICAvLyBDb250ZXh0IG1heSBiZSB0ZW1wb3JhcmlseSB1bmF2YWlsYWJsZSBkdXJpbmcgcmVsb2FkLlxuICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG5cbiAgICBjb25zdCBzdGFsZVByZWZpeCA9IHRoaXMuc2hvdWxkU3dlZXBMZWZ0b3ZlcnMgPyBgJHt0aGlzLnZhdWx0QmFzZVBhdGh9JHtURU1QX1ZBVUxUX0RJUl9QUkVGSVh9YCA6ICcnO1xuXG4gICAgYXdhaXQgdGhpcy5icm93c2VyLmV4ZWN1dGUoXG4gICAgICAocGF0aDogc3RyaW5nLCBwcnVuZVByZWZpeDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGxldCBleGlzdGluZyA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnKSA/PyAnW10nKSBhcyBzdHJpbmdbXTtcblxuICAgICAgICBpZiAocHJ1bmVQcmVmaXgpIHtcbiAgICAgICAgICBjb25zdCBzdGFsZSA9IGV4aXN0aW5nLmZpbHRlcigocmVnaXN0ZXJlZCkgPT4gcmVnaXN0ZXJlZCAhPT0gcGF0aCAmJiByZWdpc3RlcmVkLnN0YXJ0c1dpdGgocHJ1bmVQcmVmaXgpKTtcbiAgICAgICAgICBmb3IgKGNvbnN0IHJlZ2lzdGVyZWQgb2Ygc3RhbGUpIHtcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGBlbmFibGUtcGx1Z2luLSR7cmVnaXN0ZXJlZH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZXhpc3RpbmcgPSBleGlzdGluZy5maWx0ZXIoKHJlZ2lzdGVyZWQpID0+ICFzdGFsZS5pbmNsdWRlcyhyZWdpc3RlcmVkKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWV4aXN0aW5nLmluY2x1ZGVzKHBhdGgpKSB7XG4gICAgICAgICAgZXhpc3RpbmcucHVzaChwYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnbW9iaWxlLWV4dGVybmFsLXZhdWx0cycsIEpTT04uc3RyaW5naWZ5KGV4aXN0aW5nKSk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtb2JpbGUtc2VsZWN0ZWQtdmF1bHQnLCBwYXRoKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oYGVuYWJsZS1wbHVnaW4tJHtwYXRofWAsICd0cnVlJyk7XG4gICAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgfSxcbiAgICAgIGRldmljZVZhdWx0UGF0aCxcbiAgICAgIHN0YWxlUHJlZml4XG4gICAgKTtcblxuICAgIC8vIFdhaXQgZm9yIHJlbG9hZCArIHZhdWx0IGluaXRpYWxpemF0aW9uLCBhcyB0d28gc2VwYXJhdGVseSBidWRnZXRlZCBwaGFzZXM6XG4gICAgLy8gVGhlIGFwcCdzIGNvbGQgc3RhcnQgZmlyc3QsIHRoZW4gT2JzaWRpYW4ncyBvd24gd29yay4gU2VlIGB3YWl0Rm9yQXBwU3RhcnRlZGAuXG4gICAgYXdhaXQgdGhpcy53YWl0Rm9yQXBwU3RhcnRlZCgpO1xuICAgIGF3YWl0IHRoaXMud2FpdEZvckxheW91dFJlYWR5KCk7XG4gIH1cblxuICAvKipcbiAgICogVW5yZWdpc3RlcnMgYSB2YXVsdCBvbiBtb2JpbGUgYnkgcmVtb3ZpbmcgaXQgZnJvbSBsb2NhbFN0b3JhZ2UuXG4gICAqXG4gICAqIFByZXNlcnZlcyBvdGhlciB2YXVsdCByZWdpc3RyYXRpb25zLiBJZiB0aGUgdW5yZWdpc3RlcmVkIHZhdWx0IHdhcyBzZWxlY3RlZCxcbiAgICogc3dpdGNoZXMgdG8gdGhlIGZpcnN0IHJlbWFpbmluZyB2YXVsdCAob3IgY2xlYXJzIHRoZSBzZWxlY3Rpb24pLlxuICAgKlxuICAgKiBUaGUgdmF1bHQncyAqKmZpbGVzIGFyZSB0aGVuIHJlbW92ZWQgZnJvbSB0aGUgZGV2aWNlIG92ZXIgYGFkYmAsIHdoZXRoZXIgb3JcbiAgICogbm90IHRoZSBgbG9jYWxTdG9yYWdlYCBzdGVwIHN1Y2NlZWRlZCoqIFx1MjAxNCBkZWxpYmVyYXRlbHksIGJlY2F1c2UgdGhlXG4gICAqIGBsb2NhbFN0b3JhZ2VgIHN0ZXAgZ29lcyB0aHJvdWdoIHRoZSBXZWJWaWV3IGFuZCBhIGRlYWQgV2ViVmlldyBpcyBleGFjdGx5XG4gICAqIHdoYXQgbW9zdCBBbmRyb2lkIGZhaWx1cmVzIGFyZS4gUm91dGluZyB0aGUgcmVtb3ZhbCB0aHJvdWdoIHRoZSBhcHAgd2FzIHdoYXRcbiAgICogbWFkZSBldmVyeSBmYWlsZWQgcnVuIGxlYWsgaXRzIHZhdWx0IChgVmF1bHQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogbm9cbiAgICogc3VjaCB3aW5kb3dgKSwgc28gdGhlIGZpbGVzeXN0ZW0tbGV2ZWwgcmVtb3ZhbCBtdXN0IG5vdCBkZXBlbmQgb24gaXQuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgb24gdGhlIGhvc3QgbWFjaGluZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB1bnJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBkZXZpY2VWYXVsdFBhdGggPSB0aGlzLmdldERldmljZVZhdWx0UGF0aCh2YXVsdFBhdGgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcblxuICAgICAgYXdhaXQgdGhpcy5icm93c2VyLmV4ZWN1dGUoKHBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBleGlzdGluZyA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnKSA/PyAnW10nKSBhcyBzdHJpbmdbXTtcbiAgICAgICAgY29uc3QgZmlsdGVyZWQgPSBleGlzdGluZy5maWx0ZXIoKHYpID0+IHYgIT09IHBhdGgpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnbW9iaWxlLWV4dGVybmFsLXZhdWx0cycsIEpTT04uc3RyaW5naWZ5KGZpbHRlcmVkKSk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGBlbmFibGUtcGx1Z2luLSR7cGF0aH1gKTtcbiAgICAgICAgaWYgKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtb2JpbGUtc2VsZWN0ZWQtdmF1bHQnKSA9PT0gcGF0aCkge1xuICAgICAgICAgIGlmIChmaWx0ZXJlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0JywgZmlsdGVyZWRbMF0gPz8gJycpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0Jyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCBkZXZpY2VWYXVsdFBhdGgpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2coXG4gICAgICAgIGBbYXBwaXVtLXRyYW5zcG9ydF0gQ291bGQgbm90IGRlcmVnaXN0ZXIgJHtkZXZpY2VWYXVsdFBhdGh9IGZyb20gbG9jYWxTdG9yYWdlIGBcbiAgICAgICAgICArIGAoJHtTdHJpbmcoZXJyb3IpfSk7IHJlbW92aW5nIGl0cyBmaWxlcyBhbnl3YXkuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJlbW92ZURldmljZVZhdWx0RGlyZWN0b3J5KGRldmljZVZhdWx0UGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSB0cnVzdGVkLWlucHV0IGNoYW5uZWwsIGlmIG9uZSBpcyBvcGVuLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBkaXNwb3NlSW5wdXRDaGFubmVsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmlucHV0Q2hhbm5lbDtcbiAgICB0aGlzLmlucHV0Q2hhbm5lbCA9IG51bGw7XG4gICAgdGhpcy51bnJlZ2lzdGVySW5wdXRDaGFubmVsRXhpdEhhbmRsZXIoKTtcbiAgICBhd2FpdCBjaGFubmVsPy5kaXNwb3NlKCk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgdGhlIHRydXN0ZWQtaW5wdXQgY2hhbm5lbCBpZiBpdCBpcyBub3QgYWxyZWFkeSBvcGVuLCBhbmQgcmUtb3BlbnMgaXQgaWYgdGhlIFdlYlZpZXcgd2VudCBhd2F5LlxuICAgKlxuICAgKiBJbnN0YWxscyBhIGBSdW50aW1lLmFkZEJpbmRpbmdgIGZ1bmN0aW9uIG9uIHRoZSBwYWdlIGFuZCBzZXJ2aWNlcyBldmVyeSBjYWxsIHRvIGl0IGZvciB0aGUgbGlmZSBvZiB0aGVcbiAgICogY29ubmVjdGlvbi4gVGhlIGJpbmRpbmcgaXMgZXhwb3NlZCBvbiAqZXZlcnkqIGV4ZWN1dGlvbiBjb250ZXh0IG9mIHRoZSBwYWdlLCBzbyBpdCBzdXJ2aXZlcyB0aGVcbiAgICogYGxvY2F0aW9uLnJlbG9hZCgpYCB0aGF0IHtAbGluayBBcHBpdW1UcmFuc3BvcnQucmVnaXN0ZXJWYXVsdH0gcGVyZm9ybXM7IG9ubHkgYSBmdWxsIGFwcCByZXN0YXJ0LCB3aGljaFxuICAgKiBkZXN0cm95cyB0aGUgV2ViVmlldyB0YXJnZXQsIG5lZWRzIHRoZSByZWNvbm5lY3QgYmVsb3cuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuc3VyZUlucHV0Q2hhbm5lbCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pbnB1dENoYW5uZWw/LmlzT3BlbiB8fCB0aGlzLmlzSW5wdXRDaGFubmVsVW5hdmFpbGFibGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUaGUgY2hhbm5lbCBpcyByZWFjaGFibGUgb25seSBvdmVyIGxvY2FsIGBhZGJgLCBzbyBpdCBkb2VzIG5vdCBleGlzdCBvbiBpT1Mgb3IgYWdhaW5zdCBhIHJlbW90ZSBodWJcbiAgICAvLyAoQnJvd3NlclN0YWNrKS4gVGhvc2UgYXJlIHN1cHBvcnRlZCB0cmFuc3BvcnRzLCBzbyB0aGlzIHN0YXlzICoqYmVzdC1lZmZvcnQqKjogYSBydW4gdGhhdCBuZXZlclxuICAgIC8vIERyaXZlcyBpbnB1dCBtdXN0IG5vdCBmYWlsIGJlY2F1c2UgdGhlIGNoYW5uZWwgY291bGQgbm90IGJlIG9wZW5lZC4gQSBydW4gdGhhdCAqZG9lcyogZHJpdmUgaW5wdXRcbiAgICAvLyBHZXRzIGEgbGVnaWJsZSBlcnJvciBmcm9tIHRoZSByZW5kZXJlcidzIG93biBndWFyZCwgd2hpY2ggbmFtZXMgdGhlIG1pc3NpbmcgY2hhbm5lbC5cbiAgICBpZiAodGhpcy5wbGF0Zm9ybSAhPT0gJ2FuZHJvaWQnKSB7XG4gICAgICB0aGlzLmlzSW5wdXRDaGFubmVsVW5hdmFpbGFibGUgPSB0cnVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZGlzcG9zZUlucHV0Q2hhbm5lbCgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCBjb25uZWN0VG9XZWJWaWV3Q2RwKHsgYXBwSWQ6IHRoaXMuYXBwSWQsIGRldmljZUlkOiB0aGlzLmRldmljZUlkIH0pO1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZW5kKCdSdW50aW1lLmVuYWJsZScpO1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZW5kKCdSdW50aW1lLmFkZEJpbmRpbmcnLCB7IG5hbWU6IE1PQklMRV9JTlBVVF9CSU5ESU5HX05BTUUgfSk7XG4gICAgICBjb25uZWN0aW9uLm9uKCdSdW50aW1lLmJpbmRpbmdDYWxsZWQnLCAocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgICBpZiAocGFyYW1zWyduYW1lJ10gIT09IE1PQklMRV9JTlBVVF9CSU5ESU5HX05BTUUpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXlsb2FkID0gcGFyYW1zWydwYXlsb2FkJ107XG4gICAgICAgIC8vIERlbGliZXJhdGVseSBub3QgYXdhaXRlZDogdGhpcyBydW5zIHdoaWxlIHRoZSByZW5kZXJlcidzIGBFeGVjdXRlIFNjcmlwdGAgaXMgc3RpbGwgcGVuZGluZywgYW5kXG4gICAgICAgIC8vIFRoYXQgaXMgdGhlIHdob2xlIHBvaW50IFx1MjAxNCB0aGUgcmVxdWVzdCBpcyBzZXJ2aWNlZCBjb25jdXJyZW50bHkgYW5kIGFuc3dlcmVkIGJ5IHJlc29sdmluZyB0aGVcbiAgICAgICAgLy8gUmVuZGVyZXIncyBwcm9taXNlIG92ZXIgdGhpcyBzYW1lIHNvY2tldC4gSXQgaGFuZGxlcyBpdHMgb3duIGZhaWx1cmVzLCBzbyBub3RoaW5nIHJlYWNoZXMgaGVyZS5cbiAgICAgICAgdGhpcy5oYW5kbGVJbnB1dFJlcXVlc3QoY29ubmVjdGlvbiwgdHlwZW9mIHBheWxvYWQgPT09ICdzdHJpbmcnID8gcGF5bG9hZCA6ICcnKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gVW5yZWFjaGFibGU6IGBoYW5kbGVJbnB1dFJlcXVlc3RgIG5ldmVyIHJlamVjdHMuXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuaW5wdXRDaGFubmVsID0gY29ubmVjdGlvbjtcblxuICAgICAgLy8gU2VsZi1jbGVhbmluZywgZGVsaWJlcmF0ZWx5OiB0aGlzIHRyYW5zcG9ydCBjYW4gYmUgY3JlYXRlZCBzdHJhaWdodCBmcm9tIGEgdGVzdCB3b3JrZXIsIHdpdGggbm9cbiAgICAgIC8vIGBjb3JlU2V0dXBgIG93bmluZyBpdHMgbGlmZWN5Y2xlIGFuZCB0aGVyZWZvcmUgbm90aGluZyB0aGF0IGV2ZXIgY2FsbHMgYGRpc3Bvc2VgL2BkaXNwb3NlU3luY2AgXHUyMDE0XG4gICAgICAvLyBXaGljaCBpcyBob3cgYSBydW4gbGVhdmVzIGl0cyBhZGIgcG9ydCBmb3J3YXJkIHN0cmFuZGVkIG9uIHRoZSBkZXZpY2UgKG9ic2VydmVkIDIwMjYtMDgtMzApLiBUaGVcbiAgICAgIC8vIEhhbmRsZXIgaXMgcmVtb3ZlZCBhZ2FpbiBvbiBkaXNwb3NhbCBzbyByZWNvbm5lY3RzIGRvIG5vdCBzdGFjayBsaXN0ZW5lcnMuXG4gICAgICB0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWxPbkV4aXQgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbm5lY3Rpb24uZGlzcG9zZVN5bmMoKTtcbiAgICAgIH07XG4gICAgICBwcm9jZXNzLm9uY2UoJ2V4aXQnLCB0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWxPbkV4aXQpO1xuXG4gICAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBUcnVzdGVkLWlucHV0IGNoYW5uZWwgb3Blbi4nKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgLy8gR2l2ZSB1cCBmb3IgdGhlIGxpZmUgb2YgdGhlIHRyYW5zcG9ydCByYXRoZXIgdGhhbiBwYXlpbmcgYW4gYGFkYmAgcm91bmQtdHJpcCBvbiBldmVyeSBldmFsLlxuICAgICAgLy8gQSBzb2NrZXQgdGhhdCBtZXJlbHkgKmNsb3NlZCogYWZ0ZXIgYSBzdWNjZXNzZnVsIGNvbm5lY3QgaXMgYSBkaWZmZXJlbnQgY2FzZSBcdTIwMTQgYGlzT3BlbmAgaXMgZmFsc2VcbiAgICAgIC8vIFRoZXJlIHdoaWxlIHRoaXMgZmxhZyBzdGF5cyB1bnNldCwgc28gdGhlIHJlY29ubmVjdCBhYm92ZSBzdGlsbCBydW5zLlxuICAgICAgdGhpcy5pc0lucHV0Q2hhbm5lbFVuYXZhaWxhYmxlID0gdHJ1ZTtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFRydXN0ZWQgaW5wdXQgaXMgdW5hdmFpbGFibGUgb24gdGhpcyBkZXZpY2U6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN3aXRjaGVzIHRoZSBkcml2ZXIgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0LlxuICAgKlxuICAgKiBJZiB0aGUgY29udGV4dCB3YXMgYWxyZWFkeSB2ZXJpZmllZCAoY2FjaGVkIHZpYSB7QGxpbmsgaXNJbldlYlZpZXdDb250ZXh0fSksXG4gICAqIHJldHVybnMgaW1tZWRpYXRlbHkgd2l0aG91dCBjYWxsaW5nIGBnZXRDb250ZXh0cygpYCBcdTIwMTQgd2hpY2ggcnVuc1xuICAgKiBgYWRiIHNoZWxsIGNhdCAvcHJvYy9uZXQvdW5peGAgYW5kIGNhbiB0aW1lIG91dCBvbiBzbG93IGVtdWxhdG9ycy5cbiAgICpcbiAgICogUG9sbHMgdW50aWwgdGhlIGNvbnRleHQgYmVjb21lcyBhdmFpbGFibGUgKHRoZSBhcHAgbWF5IHN0aWxsIGJlIGxvYWRpbmcpLlxuICAgKiBVc2VzIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dCBzcGVjaWZpY2FsbHkgdG8gYXZvaWQgY29ubmVjdGluZ1xuICAgKiB0byBDaHJvbWUgb3Igb3RoZXIgV2ViVmlld3Mgb24gdGhlIGRldmljZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlV2ViVmlld0NvbnRleHQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNJbldlYlZpZXdDb250ZXh0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgdGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdhaXRpbmcgZm9yICR7V0VCVklFV19DT05URVhUX1BSRUZJWH0gY29udGV4dCAodGltZW91dD0ke1N0cmluZyh0aGlzLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zKS4uLmApO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgY29uc3QgY29udGV4dHMgPSBhd2FpdCB0aGlzLmJyb3dzZXIuZ2V0Q29udGV4dHMoKTtcbiAgICAgIGNvbnN0IG9ic2lkaWFuQ29udGV4dCA9IGNvbnRleHRzLmZpbmQoKGNvbnRleHQpOiBjb250ZXh0IGlzIHN0cmluZyA9PiB0eXBlb2YgY29udGV4dCA9PT0gJ3N0cmluZycgJiYgY29udGV4dC5zdGFydHNXaXRoKFdFQlZJRVdfQ09OVEVYVF9QUkVGSVgpKTtcblxuICAgICAgaWYgKG9ic2lkaWFuQ29udGV4dCkge1xuICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBGb3VuZCBXZWJWaWV3IGNvbnRleHQ6ICR7b2JzaWRpYW5Db250ZXh0fWApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5zd2l0Y2hDb250ZXh0KG9ic2lkaWFuQ29udGV4dCk7XG4gICAgICAgICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSB0cnVlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBzd2l0Y2hDb250ZXh0IGZhaWxlZDogJHtTdHJpbmcoZXJyb3IpfS4gUmVzZXR0aW5nIHRvIE5BVElWRV9BUFAgYmVmb3JlIHJldHJ5aW5nLi4uYCk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5zd2l0Y2hDb250ZXh0KCdOQVRJVkVfQVBQJyk7XG4gICAgICAgICAgfSBjYXRjaCAocmVzZXRFcnJvcjogdW5rbm93bikge1xuICAgICAgICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gTkFUSVZFX0FQUCByZXNldCBhbHNvIGZhaWxlZDogJHtTdHJpbmcocmVzZXRFcnJvcil9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdlYlZpZXcgbm90IHJlYWR5LCBhdmFpbGFibGUgY29udGV4dHM6ICR7SlNPTi5zdHJpbmdpZnkoY29udGV4dHMpfS4gUmV0cnlpbmcuLi5gKTtcbiAgICAgIGF3YWl0IGRlbGF5KFdFQlZJRVdfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgTm8gJHtXRUJWSUVXX0NPTlRFWFRfUFJFRklYfSBjb250ZXh0IGZvdW5kIHdpdGhpbiAke1N0cmluZyh0aGlzLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zLiBJcyB0aGUgT2JzaWRpYW4gYXBwIGZ1bGx5IGxvYWRlZD9gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIGhvc3Qtc2lkZSB2YXVsdCBwYXRoIHRvIHRoZSBkZXZpY2Utc2lkZSBwYXRoLlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gQWJzb2x1dGUgcGF0aCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICAgKiBAcmV0dXJucyBUaGUgZGV2aWNlLXNpZGUgdmF1bHQgcGF0aC5cbiAgICovXG4gIHByaXZhdGUgZ2V0RGV2aWNlVmF1bHRQYXRoKHZhdWx0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy52YXVsdEJhc2VQYXRofSR7ZXh0cmFjdFZhdWx0TmFtZSh2YXVsdFBhdGgpfWA7XG4gIH1cblxuICAvKipcbiAgICogU2VydmljZXMgb25lIGlucHV0IHJlcXVlc3QgZnJvbSB0aGUgcmVuZGVyZXI6IGluamVjdCwgdGhlbiByZXNvbHZlIHRoZSByZW5kZXJlcidzIHByb21pc2UuXG4gICAqXG4gICAqIEV2ZXJ5IGZhaWx1cmUgcGF0aCBzdGlsbCByZXNvbHZlcyB0aGF0IHByb21pc2UgXHUyMDE0IHdpdGggYW4gZXJyb3IgbWVzc2FnZSB0aGUgcmVuZGVyZXIgcmUtdGhyb3dzIFx1MjAxNCBiZWNhdXNlXG4gICAqIGEgcmVxdWVzdCB0aGF0IGlzIHNpbGVudGx5IGRyb3BwZWQgd291bGQgaGFuZyB0aGUgY2xvc3VyZSB1bnRpbCB0aGUgd2hvbGUgcnVuIHRpbWVzIG91dCwgYW5kIHJlcG9ydFxuICAgKiBub3RoaW5nIGFib3V0IHdoeS5cbiAgICpcbiAgICogQHBhcmFtIGNvbm5lY3Rpb24gLSBUaGUgY2hhbm5lbCB0aGUgcmVxdWVzdCBhcnJpdmVkIG9uLlxuICAgKiBAcGFyYW0gcGF5bG9hZCAtIFRoZSByYXcgSlNPTiBwYXlsb2FkIHRoZSBiaW5kaW5nIHdhcyBjYWxsZWQgd2l0aC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlSW5wdXRSZXF1ZXN0KGNvbm5lY3Rpb246IFdlYlZpZXdDZHBDb25uZWN0aW9uLCBwYXlsb2FkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgcmVxdWVzdElkID0gJyc7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgaWQsIHJlcXVlc3QgfSA9IEpTT04ucGFyc2UocGF5bG9hZCkgYXMgTW9iaWxlSW5wdXRFbnZlbG9wZTtcbiAgICAgIHJlcXVlc3RJZCA9IGlkO1xuXG4gICAgICAvLyBFeGFjdGx5LW9uY2UgYWNyb3NzIGV2ZXJ5IGF0dGFjaGVkIGhvc3QuIGBSdW50aW1lLmJpbmRpbmdDYWxsZWRgIGlzIGJyb2FkY2FzdCB0byBBTEwgYXR0YWNoZWRcbiAgICAgIC8vIENEUCBzZXNzaW9ucywgc28gd2l0aG91dCB0aGlzIGVhY2ggcHJvY2VzcyBpbmplY3RzIHRoZSBnZXN0dXJlIGFnYWluOiBtZWFzdXJlZCAyMDI2LTA5LTEwLCBhXG4gICAgICAvLyBWaXRlc3QgbWFpbiBwcm9jZXNzIGFuZCBpdHMgd29ya2VyIHNlcnZpY2VkIHJlcXVlc3QgYGlkPTFgIGluIHRoZSBzYW1lIG1pbGxpc2Vjb25kLCBhbmQgb25lXG4gICAgICAvLyBgY2xpY2tFbGVtZW50YCByZWFjaGVkIHRoZSBwYWdlIGFzIHR3byBgcG9pbnRlcmRvd25gIC8gYHRvdWNoc3RhcnRgIHBhaXJzLlxuICAgICAgLy9cbiAgICAgIC8vIEEgTE9TRVIgTVVTVCBSRVRVUk4gU0lMRU5UTFk6IHRoZSB3aW5uZXIgaXMgdGhlIG9uZSB0aGF0IGluamVjdHMgYW5kIHRoZSBvbmUgdGhhdCByZXNvbHZlcyB0aGVcbiAgICAgIC8vIFJlbmRlcmVyJ3MgcHJvbWlzZSwgc28gYW5zd2VyaW5nIGhlcmUgYXMgd2VsbCB3b3VsZCByZXNvbHZlIGEgcmVxdWVzdCB3aG9zZSBnZXN0dXJlIHRoaXNcbiAgICAgIC8vIFByb2Nlc3MgbmV2ZXIgc2VudC5cbiAgICAgIGNvbnN0IGNsYWltID0gYXdhaXQgY29ubmVjdGlvbi5zZW5kKCdSdW50aW1lLmV2YWx1YXRlJywgeyBleHByZXNzaW9uOiBidWlsZENsYWltSW5wdXRFeHByZXNzaW9uKGlkKSwgcmV0dXJuQnlWYWx1ZTogdHJ1ZSB9KTtcbiAgICAgIGlmICghY2hlY2tJbnB1dENsYWltR3JhbnRlZChjbGFpbSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnNlbmRBbGwodG9DZHBJbnB1dENvbW1hbmRzKHJlcXVlc3QpKTtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uc2VuZCgnUnVudGltZS5ldmFsdWF0ZScsIHsgZXhwcmVzc2lvbjogYnVpbGRSZXNvbHZlSW5wdXRFeHByZXNzaW9uKGlkKSB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yVG9TdHJpbmcoZXJyb3IpO1xuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gVHJ1c3RlZCBpbnB1dCBmYWlsZWQ6ICR7bWVzc2FnZX1gKTtcbiAgICAgIGlmICghcmVxdWVzdElkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZW5kKCdSdW50aW1lLmV2YWx1YXRlJywgeyBleHByZXNzaW9uOiBidWlsZFJlc29sdmVJbnB1dEV4cHJlc3Npb24ocmVxdWVzdElkLCBtZXNzYWdlKSB9KTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBUaGUgc29ja2V0IGlzIGdvbmU7IHRoZSByZW5kZXJlcidzIG93biB0aW1lb3V0IGlzIHRoZSByZW1haW5pbmcgYmFja3N0b3AuXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2JlcyB0aGUgV2ViVmlldyBvbmNlIGZvciBob3cgZmFyIE9ic2lkaWFuJ3Mgc3RhcnR1cCBoYXMgZ290LlxuICAgKlxuICAgKiBBIHByb2JlIHRoYXQgdGhyb3dzIGlzIHJlcG9ydGVkIGFzIGB1bmRlZmluZWRgIHJhdGhlciB0aGFuIHByb3BhZ2F0ZWQ6IHRoZVxuICAgKiBwYWdlIGlzIG1pZC1gbG9jYXRpb24ucmVsb2FkKClgIGZvciBtb3N0IG9mIHRoZSBhcHAtc3RhcnQgcGhhc2UsIGFuZCBhXG4gICAqIFdlYlZpZXcgdGhhdCBjYW5ub3QgYW5zd2VyIHlldCBpcyB0aGUgKmV4cGVjdGVkKiByZWFkaW5nIHRoZXJlLCBub3QgYW4gZXJyb3IuXG4gICAqXG4gICAqIEByZXR1cm5zIFdoYXQgdGhlIHByb2JlIHNhdywgb3IgYHVuZGVmaW5lZGAgd2hlbiBpdCBjb3VsZCBub3QgcnVuLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9iZVN0YXJ0dXAoKTogUHJvbWlzZTxTdGFydHVwUHJvYmVSZXN1bHQgfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKCgpOiBTdGFydHVwUHJvYmVSZXN1bHQgPT4ge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWRlcHJlY2F0ZWQgLS0gV2UgbmVlZCBnbG9iYWwgYGFwcGAgdmFyaWFibGUuXG4gICAgICAgIGNvbnN0IGFwcCA9IGdsb2JhbFRoaXMuYXBwIGFzIExvYWRpbmdBcHAgfCB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaGFzQXBwOiAhIWFwcCxcbiAgICAgICAgICBoYXNXb3Jrc3BhY2U6ICEhYXBwPy53b3Jrc3BhY2UsXG4gICAgICAgICAgaXNMYXlvdXRSZWFkeTogISFhcHA/LndvcmtzcGFjZT8ubGF5b3V0UmVhZHlcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVzaGVzIHRoZSBtaW5pbWFsIGAub2JzaWRpYW4vYXBwLmpzb25gIHZhdWx0IG1hcmtlciB2aWEgYGFkYiBwdXNoYC5cbiAgICpcbiAgICogYGJyb3dzZXIucHVzaEZpbGVgIChXZWJEcml2ZXIgYmFzZTY0KSBpcyBhbiBvcmRlciBvZiBtYWduaXR1ZGUgc2xvd2VyIG9uIGFcbiAgICogY29sZCBvciBsb2FkZWQgZW11bGF0b3IgXHUyMDE0IG1lYXN1cmVkIGF0IDlcdTIwMTMyMXMgcGVyIGNhbGwgZm9yIHRoaXMgMi1ieXRlIG1hcmtlcixcbiAgICogdmVyc3VzIHN1Yi1zZWNvbmQgb3ZlciBgYWRiYC4gVGhpcyBtaXJyb3JzIHtAbGluayBwdXNoRmlsZXN9LCB3aGljaCBzd2l0Y2hlZFxuICAgKiB0byBgYWRiYCBmb3IgdGhlIHNhbWUgcmVhc29uLiBgbWtkaXIgLXBgIGd1YXJhbnRlZXMgdGhlIHBhcmVudCBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VWYXVsdFBhdGggLSBUaGUgZGV2aWNlLXNpZGUgdmF1bHQgZGlyZWN0b3J5IHBhdGguXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHB1c2hPYnNpZGlhbk1hcmtlcihkZXZpY2VWYXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGxvY2FsTWFya2VyID0gam9pbih0bXBkaXIoKSwgYG9ic2lkaWFuLW1hcmtlci0ke3JhbmRvbVVVSUQoKX0uanNvbmApO1xuICAgIGNvbnN0IHJlbW90ZU1hcmtlciA9IGAke2RldmljZVZhdWx0UGF0aH0vLm9ic2lkaWFuL2FwcC5qc29uYDtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB3cml0ZUZpbGUobG9jYWxNYXJrZXIsICd7fScsICd1dGYtOCcpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdta2RpcicsICctcCcsIGAke2RldmljZVZhdWx0UGF0aH0vLm9ic2lkaWFuYF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAncHVzaCcsIGxvY2FsTWFya2VyLCByZW1vdGVNYXJrZXJdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJtKGxvY2FsTWFya2VyLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgdmF1bHQgZGlyZWN0b3J5IGZyb20gdGhlIGRldmljZSBvdmVyIGBhZGJgLCBhbmQgQ0hFQ0tTIHRoYXQgaXQgaXNcbiAgICogYWN0dWFsbHkgZ29uZS5cbiAgICpcbiAgICogQmVzdC1lZmZvcnQ6IGEgZmFpbHVyZSBpcyBsb2dnZWQsIG5vdCB0aHJvd24sIHNvIGEgdGVhcmRvd24gcHJvYmxlbSBuZXZlclxuICAgKiBtYXNrcyB0aGUgdGVzdCByZXN1bHQuIFRoZSBuZXh0IHJ1bidzIHN0YXJ0LW9mLXJ1biBzd2VlcCBwaWNrcyB1cCB3aGF0ZXZlclxuICAgKiB0aGlzIGNvdWxkIG5vdCByZW1vdmUuXG4gICAqXG4gICAqIFRoZSBjaGVjayBpcyB0aGUgcG9pbnQuIGBybSAtcmZgIHJ1bnMgd2l0aCBgc2hvdWxkSWdub3JlRXhpdENvZGVgLCBzbyBhblxuICAgKiB1bnJlbW92ZWQgZGlyZWN0b3J5IHVzZWQgdG8gbGVhdmUgbm8gdHJhY2UgYXQgYWxsIFx1MjAxNCB3aGljaCBpcyBob3cgcnVucyB0aGF0XG4gICAqIHBhc3NlZCBlbmQgdG8gZW5kIHdlcmUgc3RpbGwgZm91bmQgdG8gYmUgbGVha2luZyBhIHZhdWx0IGFwaWVjZSwgaW52aXNpYmx5LFxuICAgKiB1bnRpbCBzb21lb25lIGNvdW50ZWQgdGhlIGRpcmVjdG9yaWVzIG9uIHRoZSBkZXZpY2UgYnkgaGFuZC4gQSBsZWFrIGlzIG5vd1xuICAgKiBuYW1lZCBpbiB0aGUgbG9nIGF0IHRoZSBtb21lbnQgaXQgaGFwcGVucy5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZVZhdWx0UGF0aCAtIFRoZSBkZXZpY2Utc2lkZSB2YXVsdCBkaXJlY3RvcnkgcGF0aC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVtb3ZlRGV2aWNlVmF1bHREaXJlY3RvcnkoZGV2aWNlVmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gUmVtb3ZpbmcgdmF1bHQgZGlyZWN0b3J5IGZyb20gZGV2aWNlOiAke2RldmljZVZhdWx0UGF0aH1gKTtcbiAgICAgIGF3YWl0IGV4ZWMoXG4gICAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3JtJywgJy1yZicsIGRldmljZVZhdWx0UGF0aF0sXG4gICAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX1ZBVUxUX1JFTU9WRV9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgICApO1xuXG4gICAgICBjb25zdCBsaXN0aW5nID0gYXdhaXQgZXhlYyhcbiAgICAgICAgWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbHMnLCAnLWQnLCBkZXZpY2VWYXVsdFBhdGhdLFxuICAgICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9WQVVMVF9SRU1PVkVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfVxuICAgICAgKTtcblxuICAgICAgaWYgKGxpc3RpbmcuaW5jbHVkZXMoZGV2aWNlVmF1bHRQYXRoKSkge1xuICAgICAgICBsb2coXG4gICAgICAgICAgYFthcHBpdW0tdHJhbnNwb3J0XSBXYXJuaW5nOiAke2RldmljZVZhdWx0UGF0aH0gc3Vydml2ZWQgcmVtb3ZhbCBhbmQgaXMgbm93IGxlYWtlZCByZXNpZHVlLiBgXG4gICAgICAgICAgICArICdUaGUgbmV4dCBydW5cXCdzIHN0YXJ0LW9mLXJ1biBzd2VlcCB3aWxsIHJldHJ5IGl0LidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gVmF1bHQgZGlyZWN0b3J5IHJlbW92YWwgZmFpbGVkIChub24tZmF0YWwpOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERyb3BzIHRoZSBgcHJvY2Vzcy5vbignZXhpdCcpYCBoYW5kbGVyIHRoYXQgd291bGQgb3RoZXJ3aXNlIGNsb3NlIGFuIGFscmVhZHktY2xvc2VkIGNoYW5uZWwsIGFuZCB3b3VsZFxuICAgKiBzdGFjayBhIGxpc3RlbmVyIHBlciByZWNvbm5lY3QuXG4gICAqL1xuICBwcml2YXRlIHVucmVnaXN0ZXJJbnB1dENoYW5uZWxFeGl0SGFuZGxlcigpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZGlzcG9zZUlucHV0Q2hhbm5lbE9uRXhpdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHByb2Nlc3Mub2ZmKCdleGl0JywgdGhpcy5kaXNwb3NlSW5wdXRDaGFubmVsT25FeGl0KTtcbiAgICB0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWxPbkV4aXQgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvbGxzIHVudGlsIGBnbG9iYWxUaGlzLmFwcGAgZXhpc3RzIGluIHRoZSBXZWJWaWV3IFx1MjAxNCB0aGUgYXBwIGhhcyBmaW5pc2hlZFxuICAgKiBpdHMgY29sZCBzdGFydCBhbmQgT2JzaWRpYW4ncyBvd24gYm9vdCBoYXMgYmVndW4uXG4gICAqXG4gICAqIFRoaXMgaXMgdGhlICoqZmlyc3QqKiBvZiB0aGUgdHdvIGJ1ZGdldHMgc3BlbnQgYWZ0ZXIgYGxvY2F0aW9uLnJlbG9hZCgpYCxcbiAgICogYW5kIHRoZSBnZW5lcm91cyBvbmUuIEV2ZXJ5dGhpbmcgaXQgcGF5cyBmb3IgaXMgb3V0c2lkZSBPYnNpZGlhbidzIGNvbnRyb2w6XG4gICAqIHRoZSBXZWJWaWV3IHJlbG9hZGluZywgYW5kIGEgZ3Vlc3QgdGhhdCBtYXkgc3RpbGwgYmUgb3B0aW1pemluZyBwYWNrYWdlcy5cbiAgICogS2VlcGluZyBpdCBzZXBhcmF0ZSBpcyB0aGUgcG9pbnQgb2YgdGhlIHNwbGl0IFx1MjAxNCB0aGUgb2xkIHNpbmdsZSB3YWxsIGNsb2NrXG4gICAqIHN0YXJ0ZWQgaGVyZSBhbmQgbGVmdCB0aGUgdGlnaHQgbGF5b3V0IGJ1ZGdldCBwYXlpbmcgZm9yIGEgY29sZCBzdGFydC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckFwcFN0YXJ0ZWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gV2FpdGluZyBmb3IgdGhlIGFwcCB0byBzdGFydCAodGltZW91dD0ke1N0cmluZyh0aGlzLmFwcFN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcykuLi5gKTtcbiAgICBhd2FpdCB0aGlzLndhaXRGb3JTdGFydHVwTWlsZXN0b25lKHtcbiAgICAgIGlzU2F0aXNmaWVkOiBjaGVja0FwcFN0YXJ0ZWQsXG4gICAgICBwaGFzZTogJ2FwcC1zdGFydCcsXG4gICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IHRoaXMuYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB1bnRpbCBgYXBwLndvcmtzcGFjZS5sYXlvdXRSZWFkeWAgaXMgYHRydWVgIGluIHRoZSBXZWJWaWV3LlxuICAgKlxuICAgKiBUaGUgKipzZWNvbmQqKiBidWRnZXQsIGFuZCB0aGUgdGlnaHQgb25lOiBieSB0aGUgdGltZSBpdCBzdGFydHMsIHRoZSBhcHAgaXNcbiAgICogYWxyZWFkeSB1cCwgc28gYWxsIGl0IGNvdmVycyBpcyBPYnNpZGlhbiBvcGVuaW5nIHRoZSB2YXVsdCBhbmQgbG9hZGluZ1xuICAgKiBwbHVnaW5zIFx1MjAxNCB+MXMgaW4gcHJhY3RpY2UsIFx1MjI2NDguNHMgdW5kZXIgaGVhdnkgaG9zdCBzdHJlc3MgKCoqTDE5KiopLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yTGF5b3V0UmVhZHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gV2FpdGluZyBmb3IgbGF5b3V0IHJlYWR5ICh0aW1lb3V0PSR7U3RyaW5nKHRoaXMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zKS4uLmApO1xuICAgIGF3YWl0IHRoaXMud2FpdEZvclN0YXJ0dXBNaWxlc3RvbmUoe1xuICAgICAgaXNTYXRpc2ZpZWQ6IGNoZWNrTGF5b3V0UmVhZHksXG4gICAgICBwaGFzZTogJ2xheW91dC1yZWFkeScsXG4gICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IHRoaXMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB0aGUgV2ViVmlldyB1bnRpbCBhIHN0YXJ0dXAgcGhhc2UncyBtaWxlc3RvbmUgaXMgc2F0aXNmaWVkLCB0cmFja2luZ1xuICAgKiB0aGUgZXZpZGVuY2UgdGhhdCB0ZWxscyBhIHNsb3cgT2JzaWRpYW4gZnJvbSBhIGNvbnRlbmRlZCBndWVzdC5cbiAgICpcbiAgICogRWFjaCBwb2xsIGNvc3RzIGV4YWN0bHkgb25lIGBicm93c2VyLmV4ZWN1dGVgIHJvdW5kLXRyaXAgXHUyMDE0IGRlbGliZXJhdGVseSBub3RcbiAgICogYW4ge0BsaW5rIGVuc3VyZVdlYlZpZXdDb250ZXh0fSBjYWxsLCB3aG9zZSBgZ2V0Q29udGV4dHMoKWAgcnVuc1xuICAgKiBgYWRiIHNoZWxsIGNhdCAvcHJvYy9uZXQvdW5peGAgYW5kIHdhcyBtZWFzdXJlZCBhdCB+MTdzIHBlciAqKkwxOSoqLiBUaGVcbiAgICogcm91bmQtdHJpcCBpcyB0aW1lZCwgYW5kIHRoZSBzbG93ZXN0IG9uZSBpcyByZXBvcnRlZCBvbiB0aW1lb3V0OiBhIHBoYXNlXG4gICAqIHRoYXQgcmFuIG91dCBhZnRlciBhIGhhbmRmdWwgb2YgcHJvYmVzIGVhY2ggdGFraW5nIHRlbnMgb2Ygc2Vjb25kcyB3YXNcbiAgICogc3RhcnZlZCBieSB0aGUgZ3Vlc3QsIG5vdCBieSBPYnNpZGlhbi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwaGFzZSwgaXRzIGJ1ZGdldCwgYW5kIHRoZSBwcmVkaWNhdGUgdGhhdCBlbmRzIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yU3RhcnR1cE1pbGVzdG9uZShwYXJhbXM6IFdhaXRGb3JTdGFydHVwTWlsZXN0b25lUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBpc1NhdGlzZmllZCwgcGhhc2UsIHRpbWVvdXRJbk1pbGxpc2Vjb25kcyB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IHN0YXJ0ICsgdGltZW91dEluTWlsbGlzZWNvbmRzO1xuXG4gICAgbGV0IGZ1cnRoZXN0TWlsZXN0b25lOiBBcHBTdGFydHVwTWlsZXN0b25lID0gJ25vLXdlYnZpZXcnO1xuICAgIGxldCBwb2xsQ291bnQgPSAwO1xuICAgIGxldCBzbG93ZXN0Um91bmRUcmlwSW5NaWxsaXNlY29uZHMgPSAwO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgY29uc3Qgcm91bmRUcmlwU3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgbWlsZXN0b25lID0gY2xhc3NpZnlBcHBTdGFydHVwUHJvYmUoYXdhaXQgdGhpcy5wcm9iZVN0YXJ0dXAoKSk7XG4gICAgICBjb25zdCByb3VuZFRyaXBJbk1pbGxpc2Vjb25kcyA9IERhdGUubm93KCkgLSByb3VuZFRyaXBTdGFydDtcblxuICAgICAgcG9sbENvdW50Kys7XG4gICAgICBzbG93ZXN0Um91bmRUcmlwSW5NaWxsaXNlY29uZHMgPSBNYXRoLm1heChzbG93ZXN0Um91bmRUcmlwSW5NaWxsaXNlY29uZHMsIHJvdW5kVHJpcEluTWlsbGlzZWNvbmRzKTtcbiAgICAgIGlmIChjb21wYXJlQXBwU3RhcnR1cE1pbGVzdG9uZXMobWlsZXN0b25lLCBmdXJ0aGVzdE1pbGVzdG9uZSkgPiAwKSB7XG4gICAgICAgIGZ1cnRoZXN0TWlsZXN0b25lID0gbWlsZXN0b25lO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNTYXRpc2ZpZWQobWlsZXN0b25lKSkge1xuICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBQaGFzZSBcIiR7cGhhc2V9XCIgc2F0aXNmaWVkIGFmdGVyICR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMgKCR7U3RyaW5nKHBvbGxDb3VudCl9IHByb2JlKHMpKS5gKTtcbiAgICAgICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxvZyhcbiAgICAgICAgYFthcHBpdW0tdHJhbnNwb3J0XSBQaGFzZSBcIiR7cGhhc2V9XCIgbm90IHNhdGlzZmllZCB5ZXQ6ICR7bWlsZXN0b25lfSBgXG4gICAgICAgICAgKyBgKGVsYXBzZWQ9JHtTdHJpbmcoRGF0ZS5ub3coKSAtIHN0YXJ0KX1tcywgcm91bmQtdHJpcD0ke1N0cmluZyhyb3VuZFRyaXBJbk1pbGxpc2Vjb25kcyl9bXMpLiBSZXRyeWluZy4uLmBcbiAgICAgICk7XG4gICAgICBhd2FpdCBkZWxheShMQVlPVVRfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihidWlsZFN0YXJ0dXBUaW1lb3V0TWVzc2FnZSh7XG4gICAgICBlbGFwc2VkSW5NaWxsaXNlY29uZHM6IERhdGUubm93KCkgLSBzdGFydCxcbiAgICAgIG1pbGVzdG9uZTogZnVydGhlc3RNaWxlc3RvbmUsXG4gICAgICBwaGFzZSxcbiAgICAgIHBvbGxDb3VudCxcbiAgICAgIHNsb3dlc3RSb3VuZFRyaXBJbk1pbGxpc2Vjb25kcyxcbiAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICAgIH0pKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGdpdmVuIGRlbGF5LlxuICpcbiAqIEBwYXJhbSBtcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgc2V0VGltZW91dChyZXNvbHZlLCBtcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSB2YXVsdCBkaXJlY3RvcnkgbmFtZSBmcm9tIGEgaG9zdC1zaWRlIHZhdWx0IHBhdGguXG4gKlxuICogQHBhcmFtIHZhdWx0UGF0aCAtIEFic29sdXRlIHBhdGggb24gdGhlIGhvc3QgbWFjaGluZS5cbiAqIEByZXR1cm5zIFRoZSBsYXN0IHBhdGggc2VnbWVudCAodmF1bHQgZGlyZWN0b3J5IG5hbWUpLlxuICovXG5mdW5jdGlvbiBleHRyYWN0VmF1bHROYW1lKHZhdWx0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHZhdWx0UGF0aC5yZXBsYWNlKC9bXFxcXC9dKyQvLCAnJyk7XG4gIGNvbnN0IGxhc3RTZXBhcmF0b3IgPSBNYXRoLm1heChub3JtYWxpemVkLmxhc3RJbmRleE9mKCcvJyksIG5vcm1hbGl6ZWQubGFzdEluZGV4T2YoJ1xcXFwnKSk7XG4gIHJldHVybiBub3JtYWxpemVkLnNsaWNlKGxhc3RTZXBhcmF0b3IgKyAxKTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQTRDQSx5QkFBMkI7QUFDM0Isc0JBR087QUFDUCxxQkFBdUI7QUFDdkIsdUJBQXFCO0FBZ0JyQixrQ0FNTztBQUNQLGdDQUdPO0FBQ1AsNkJBQThCO0FBQzlCLGtCQUFxQjtBQUNyQiw4QkFBc0M7QUFD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
772
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1hcHBpdW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBcHBpdW0gdHJhbnNwb3J0IFx1MjAxNCBldmFsdWF0ZXMgZXhwcmVzc2lvbnMgaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSB2aWEgV2ViVmlld1xuICogSmF2YVNjcmlwdCBpbmplY3Rpb24uIE1hbmFnZXMgdmF1bHQgbGlmZWN5Y2xlIHZpYSBsb2NhbFN0b3JhZ2UgYW5kIGZpbGUgcHVzaC5cbiAqXG4gKiBDb25maWd1cmVkIHZpYSBgZW52aXJvbm1lbnRPcHRpb25zLm9ic2lkaWFuVHJhbnNwb3J0YCBpbiB2aXRlc3QgY29uZmlnOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHZpdGVzdC5jb25maWcudHNcbiAqIGVudmlyb25tZW50T3B0aW9uczoge1xuICogICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICogICAgIHR5cGU6ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScsXG4gKiAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAqICAgICBhdmROYW1lOiAnb2JzaWRpYW5fdGVzdCcsXG4gKiAgIH0sXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBGb3IgQnJvd3NlclN0YWNrLCBzZXQgYGFwcGl1bVVybGAgdG8gdGhlIEJyb3dzZXJTdGFjayBodWIgVVJMXG4gKiBcdTIwMTQgdGhlIHRyYW5zcG9ydCBpdHNlbGYgaXMgaHViLWFnbm9zdGljLlxuICpcbiAqICMjIEhvdyB2YXVsdCByZWdpc3RyYXRpb24gd29ya3Mgb24gbW9iaWxlXG4gKlxuICogT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHQgcmVnaXN0cnkgaW4gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYDpcbiAqXG4gKiAtIGBtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzYCBcdTIwMTQgSlNPTiBhcnJheSBvZiByZWdpc3RlcmVkIHZhdWx0IHBhdGhzXG4gKiAtIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgIFx1MjAxNCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2YXVsdCBwYXRoXG4gKiAtIGBlbmFibGUtcGx1Z2luLTx2YXVsdFBhdGg+YCBcdTIwMTQgYFwidHJ1ZVwiYCB0byBlbmFibGUgdGhlIHBsdWdpbiBzeXN0ZW0gZm9yIHRoZSB2YXVsdFxuICpcbiAqIFRvIHJlZ2lzdGVyIGEgdmF1bHQgcHJvZ3JhbW1hdGljYWxseSAod2l0aG91dCBVSSBpbnRlcmFjdGlvbik6XG4gKlxuICogMS4gUHVzaCB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIChlLmcuIGAvc2RjYXJkL0RvY3VtZW50cy88TmFtZT4vLm9ic2lkaWFuL2FwcC5qc29uYClcbiAqIDIuIFN3aXRjaCB0byBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dFxuICogMy4gU2V0IHRoZSBsb2NhbFN0b3JhZ2UgZW50cmllc1xuICogNC4gQ2FsbCBgbG9jYXRpb24ucmVsb2FkKClgIFx1MjAxNCBPYnNpZGlhbiByZS1yZWFkcyBsb2NhbFN0b3JhZ2UgYW5kIG9wZW5zIHRoZSB2YXVsdFxuICpcbiAqIFRoaXMgYXZvaWRzIHRoZSBvbmJvYXJkaW5nIGZsb3cgZW50aXJlbHkuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBCcm93c2VyIH0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgcm0sXG4gIHdyaXRlRmlsZVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHtcbiAgQXBwU3RhcnR1cE1pbGVzdG9uZSxcbiAgQXBwU3RhcnR1cFBoYXNlLFxuICBTdGFydHVwUHJvYmVSZXN1bHRcbn0gZnJvbSAnLi9hcHAtc3RhcnR1cC1wcm9ncmVzcy5janMnO1xuaW1wb3J0IHR5cGUgeyBDYXB0dXJlU2NyZWVuc2hvdFBhcmFtcyB9IGZyb20gJy4vY2FwdHVyZS1zY3JlZW5zaG90LmNqcyc7XG5pbXBvcnQgdHlwZSB7IE1vYmlsZUlucHV0RW52ZWxvcGUgfSBmcm9tICcuL21vYmlsZS1pbnB1dC5janMnO1xuaW1wb3J0IHR5cGUge1xuICBDb25zb2xlQ2FwdHVyZUhhbmRsZSxcbiAgT2JzaWRpYW5UcmFuc3BvcnQsXG4gIFRyYW5zcG9ydEV2YWxPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5pbXBvcnQgdHlwZSB7IFdlYlZpZXdDZHBDb25uZWN0aW9uIH0gZnJvbSAnLi93ZWJ2aWV3LWNkcC5janMnO1xuXG5pbXBvcnQge1xuICBidWlsZFN0YXJ0dXBUaW1lb3V0TWVzc2FnZSxcbiAgY2hlY2tBcHBTdGFydGVkLFxuICBjaGVja0xheW91dFJlYWR5LFxuICBjbGFzc2lmeUFwcFN0YXJ0dXBQcm9iZSxcbiAgY29tcGFyZUFwcFN0YXJ0dXBNaWxlc3RvbmVzXG59IGZyb20gJy4vYXBwLXN0YXJ0dXAtcHJvZ3Jlc3MuY2pzJztcbmltcG9ydCB7XG4gIGRlY29kZUJhc2U2NFBuZyxcbiAgaXNQbmdcbn0gZnJvbSAnLi9jYXB0dXJlLXNjcmVlbnNob3QuY2pzJztcbmltcG9ydCB7IGVycm9yVG9TdHJpbmcgfSBmcm9tICcuL2Vycm9yLXRvLXN0cmluZy5janMnO1xuaW1wb3J0IHtcbiAgRXZhbENhcEV4Y2VlZGVkRXJyb3IsXG4gIGlzU2NyaXB0VGltZW91dEVycm9yXG59IGZyb20gJy4vZXZhbC1jYXAtZXhjZWVkZWQtZXJyb3IuY2pzJztcbmltcG9ydCB7IERFRkFVTFRfRVZBTF9DQVBfSU5fTUlMTElTRUNPTkRTIH0gZnJvbSAnLi9ldmFsLWNhcC5janMnO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJy4vZXhlYy5janMnO1xuaW1wb3J0IHsgVEVNUF9WQVVMVF9ESVJfUFJFRklYIH0gZnJvbSAnLi9sZWZ0b3Zlci1jbGVhbnVwLmNqcyc7XG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuaW1wb3J0IHtcbiAgYnVpbGRDbGFpbUlucHV0RXhwcmVzc2lvbixcbiAgYnVpbGRSZXNvbHZlSW5wdXRFeHByZXNzaW9uLFxuICBjaGVja0lucHV0Q2xhaW1HcmFudGVkLFxuICBNT0JJTEVfSU5QVVRfQklORElOR19OQU1FLFxuICB0b0NkcElucHV0Q29tbWFuZHNcbn0gZnJvbSAnLi9tb2JpbGUtaW5wdXQuY2pzJztcbmltcG9ydCB7IGNvbm5lY3RUb1dlYlZpZXdDZHAgfSBmcm9tICcuL3dlYnZpZXctY2RwLmNqcyc7XG5cbi8qKlxuICogU2Vzc2lvbiBjb25uZWN0aW9uIGluZm8gcmV0dXJuZWQgYnkge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5nZXRTZXNzaW9uSW5mb30sXG4gKiB1c2VkIHRvIHJlYXR0YWNoIGZyb20gYW5vdGhlciBwcm9jZXNzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgLyoqXG4gIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuXG4gICAqL1xuICBkZXZpY2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgQXBwaXVtL1dlYkRyaXZlciBzZXNzaW9uIElELlxuICAgKi9cbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIEFwcGl1bSB0cmFuc3BvcnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwaXVtVHJhbnNwb3J0Q29uZmlnIHtcbiAgLyoqXG4gICAqIEFwcCBwYWNrYWdlIChBbmRyb2lkKSBvciBidW5kbGUgSUQgKGlPUykuXG4gICAqIERlZmF1bHRzIHRvIGAnbWQub2JzaWRpYW4nYC5cbiAgICovXG4gIGFwcElkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgT2JzaWRpYW4gTW9iaWxlIHRvIGdldCBhcyBmYXIgYXMgYGdsb2JhbFRoaXMuYXBwYFxuICAgKiBleGlzdGluZyBhZnRlciB0aGUgdmF1bHQgaXMgKHJlKW9wZW5lZCwgYmVmb3JlIHRoZSB0aWdodGVyXG4gICAqIHtAbGluayBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kc30gY2xvY2sgc3RhcnRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMTgwMDAwYFxuICAgKi9cbiAgYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBBcHBpdW0gYnJvd3Nlci9kcml2ZXIgaW5zdGFuY2UuXG4gICAqIENyZWF0ZWQgYnkgdGhlIGNvbnN1bWVyIHZpYSBlLmcuIFdlYkRyaXZlcklPJ3MgYHJlbW90ZSgpYC5cbiAgICovXG4gIGJyb3dzZXI6IEJyb3dzZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuXG4gICAqIFVzZWQgZm9yIGBhZGJgIGNvbW1hbmRzIHdoZW4gcHVzaGluZyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICAgKi9cbiAgZGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHRyYW5zcG9ydCBvd25zIHRoZSBBcHBpdW0gc2Vzc2lvbiBhbmQgc2hvdWxkIGRlbGV0ZSBpdCBvblxuICAgKiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LmRpc3Bvc2V9LlxuICAgKlxuICAgKiBgdHJ1ZWAgZm9yIHNlc3Npb25zIGNyZWF0ZWQgdmlhIGByZW1vdGUoKWAgKGdsb2JhbCBzZXR1cCkuXG4gICAqIGBmYWxzZWAgZm9yIHNlc3Npb25zIHJlYXR0YWNoZWQgdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycykuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgaXNTZXNzaW9uT3duZXI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3Igd2FpdGluZyBmb3IgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgLCBjb3VudGVkXG4gICAqIGZyb20gdGhlIG1vbWVudCB7QGxpbmsgYXBwU3RhcnRUaW1lb3V0SW5NaWxsaXNlY29uZHN9IGlzIHNhdGlzZmllZCBcdTIwMTQgbm90IGZyb21cbiAgICogdGhlIHJlbG9hZCwgc28gYSBjb2xkIGFwcCBzdGFydCBpcyBub3QgY2hhcmdlZCBhZ2FpbnN0IGl0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgOTAwMDBgXG4gICAqL1xuICBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogVGFyZ2V0IHBsYXRmb3JtLiBEZXRlcm1pbmVzIFdlYlZpZXcgY29udGV4dCBuYW1pbmcgYW5kIGRldmljZSBmaWxlIHBhdGhzLlxuICAgKi9cbiAgcGxhdGZvcm06ICdhbmRyb2lkJyB8ICdpb3MnO1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyLXNjcmlwdCBjYXAsIGluIG1pbGxpc2Vjb25kcywgdGhpcyBzZXNzaW9uIHdhcyBnaXZlbiBhcyBpdHMgVzNDXG4gICAqIGB0aW1lb3V0cy5zY3JpcHRgIGNhcGFiaWxpdHkuXG4gICAqXG4gICAqIENhcnJpZWQgb25seSBzbyBhIHNjcmlwdCB0aW1lb3V0IGNhbiBiZSByZXBvcnRlZCB3aXRoIHRoZSBudW1iZXIgdGhhdFxuICAgKiBwcm9kdWNlZCBpdDsgdGhlIGNhcGFiaWxpdHkgaXRzZWxmIGlzIHNldCB3aGVuIHRoZSBzZXNzaW9uIGlzIGNyZWF0ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAzMDAwMGBcbiAgICovXG4gIHNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hldGhlciByZWdpc3RlcmluZyBhIHZhdWx0IGFsc28gcHJ1bmVzIHRoZSAqKm90aGVyKiogYHRlbXAtdmF1bHQtKmBcbiAgICogcmVnaXN0cmF0aW9ucyBlYXJsaWVyIHJ1bnMgbGVmdCBpbiBPYnNpZGlhbiBNb2JpbGUncyBgbG9jYWxTdG9yYWdlYC5cbiAgICpcbiAgICogVGhlIGRldmljZS1zaWRlIGRpcmVjdG9yaWVzIGFyZSBzd2VwdCBiZWZvcmUgdGhlIGFwcCBsYXVuY2hlcyAoc2VlIHRoZVxuICAgKiBmYWN0b3J5KTsgdGhpcyByZW1vdmVzIHRoZWlyIG5vdy1kYW5nbGluZyByZWdpc3RyeSBlbnRyaWVzLCB3aGljaCBhcmUgd2hhdFxuICAgKiBPYnNpZGlhbiBhY3R1YWxseSBlbnVtZXJhdGVzIGF0IHN0YXJ0dXAuIFVucmVnaXN0ZXJpbmcgdGhpcyBydW4ncyBvd24gdmF1bHRcbiAgICogaXMgdW5hZmZlY3RlZCBcdTIwMTQgdGhhdCBhbHdheXMgaGFwcGVucy5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICBzaG91bGRTd2VlcExlZnRvdmVycz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEJhc2UgcGF0aCBvbiB0aGUgZGV2aWNlIHdoZXJlIE9ic2lkaWFuIHN0b3JlcyB2YXVsdHMuXG4gICAqXG4gICAqIERlZmF1bHRzOlxuICAgKiAtIEFuZHJvaWQ6IGAvc2RjYXJkL0RvY3VtZW50cy9gXG4gICAqIC0gaU9TOiBgQG1kLm9ic2lkaWFuOmRvY3VtZW50cy9gXG4gICAqL1xuICB2YXVsdEJhc2VQYXRoPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3Igd2FpdGluZyBmb3IgdGhlIFdlYlZpZXcgY29udGV4dCB0byBiZWNvbWUgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNjAwMDBgXG4gICAqL1xuICB3ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xufVxuXG5jb25zdCBOT19PVVRQVVQgPSAnKG5vIG91dHB1dCknO1xuY29uc3QgQVBQX1NUQVRFX0ZPUkVHUk9VTkQgPSA0O1xuY29uc3QgV0VCVklFV19DT05URVhUX1BSRUZJWCA9ICdXRUJWSUVXX21kLm9ic2lkaWFuJztcbmNvbnN0IFdFQlZJRVdfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBERUZBVUxUX1dFQlZJRVdfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDYwXzAwMDtcbmNvbnN0IExBWU9VVF9SRUFEWV9QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IERFRkFVTFRfTEFZT1VUX1JFQURZX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA5MF8wMDA7XG5jb25zdCBERUZBVUxUX0FQUF9TVEFSVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTgwXzAwMDtcbmNvbnN0IEFQUF9SRVNUQVJUX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5jb25zdCBERUZBVUxUX0FQUF9JRCA9ICdtZC5vYnNpZGlhbic7XG5jb25zdCBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzBfMDAwO1xuLypcbiAqIEV4dHJhIGJ1ZGdldCBncmFudGVkIHRvIHRoZSBPTkUgZXZhbCB0aGF0IGZvbGxvd3MgYSBjYXAgb3ZlcnJ1biwgb24gdG9wIG9mIHRoZSBjYXAgaXRzZWxmLiBUaGVcbiAqIGFiYW5kb25lZCBjbG9zdXJlIGtlZXBzIHJ1bm5pbmcgaW4gdGhlIGd1ZXN0LCBhbmQgQXBwaXVtIHNlcmlhbGl6ZXMgY29tbWFuZHMgcGVyIHNlc3Npb24sIHNvIHRoZSBuZXh0XG4gKiBjb21tYW5kIHdhaXRzIG91dCB3aGF0ZXZlciBpcyBsZWZ0IG9mIGl0LiBTaXplZCBhdCB0aGUgZGVmYXVsdCBjYXAgYWdhaW4gXHUyMDE0IGRlcml2ZWQgZnJvbSBpdCByYXRoZXIgdGhhblxuICogcmVzdGF0ZWQsIHNvIHRoZSB0d28gY2Fubm90IGRyaWZ0IFx1MjAxNCB3aGljaCBpcyBhIHByYWdtYXRpYyBjZWlsaW5nIHJhdGhlciB0aGFuIGEgcHJvb2Y6IGEgY2xvc3VyZSBjYW5cbiAqIG91dHJ1biBhbnkgbnVtYmVyIHBpY2tlZCBoZXJlLiBJdCBkb2VzIG5vdCBuZWVkIHRvIGJlIGEgcHJvb2YsIGJlY2F1c2UgYSBndWVzdCB0aGF0IGlzIHN0aWxsIGJ1c3kgYWZ0ZXJcbiAqIGl0IHNpbXBseSBwcm9kdWNlcyBhbm90aGVyIG92ZXJydW4gb24gdGhlIG5leHQgZXZhbCwgd2hpY2ggaXMgZ3JhbnRlZCB0aGUgZ3JhY2UgaW4gdHVybiBcdTIwMTQgc28gdGhlIHNlc3Npb25cbiAqIHJlY292ZXJzIG92ZXIgc3VjY2Vzc2l2ZSBldmFscyBpbnN0ZWFkIG9mIGNvbXBvdW5kaW5nLCBhbmQgZXZlcnkgb25lIG9mIHRob3NlIGV2YWxzIHJlcG9ydHMgdGhlIHNhbWVcbiAqIGhvbmVzdCBkaWFnbm9zaXMuXG4gKi9cbmNvbnN0IENBUF9SRUNPVkVSWV9HUkFDRV9JTl9NSUxMSVNFQ09ORFMgPSBERUZBVUxUX0VWQUxfQ0FQX0lOX01JTExJU0VDT05EUztcblxuLy8gLS0tIENvbnNvbGUgY2FwdHVyZSAoTGF5ZXIgMiBvZiB0aGUgcGx1Z2luLWxvYWQgZXJyb3Igc3VyZmFjaW5nKSAtLS1cbi8qKlxuICogVGhlIGBsb2djYXRgIHRhZyBzdGFtcGVkIGF0IGNhcHR1cmUgc3RhcnQsIGFuZCB0aGUgcHJlZml4IG9mIHRoZSB1bmlxdWUgbWFya2VyIHdyaXR0ZW4gdW5kZXIgaXQuXG4gKlxuICogUHJvY2Vzcy1sb2NhbCByYXRoZXIgdGhhbiBhIHByb3RvY29sOiBgYmVnaW5Db25zb2xlQ2FwdHVyZWAgd3JpdGVzIGl0IGFuZCBgcmVhZENvbnNvbGVDYXB0dXJlU2luY2VgIHNlYXJjaGVzIHRoZSBkdW1wIGZvclxuICogdGhlIHNhbWUgc3RyaW5nLCBib3RoIGZyb20gdGhpcyBjb25zdGFudCwgc28gdGhlIHZhbHVlIGlzIGZyZWUgdG8gY2hhbmdlLiBJdCBvbmx5IGhhcyB0byBiZSB1bmxpa2VseSB0byBvY2N1ciBpbiBhblxuICogdW5yZWxhdGVkIGxvZyBsaW5lLlxuICovXG5jb25zdCBDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBRyA9ICdPQlNJRElBTl9JTlRFR1JBVElPTl9URVNUSU5HX0NBUFRVUkUnO1xuY29uc3QgQ09OU09MRV9DQVBUVVJFX1RBSUxfTUFYX0xFTkdUSCA9IDgwMDA7XG5jb25zdCBBREJfTE9HX01BUktFUl9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDUwMDA7XG5jb25zdCBMT0dDQVRfRFVNUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEwXzAwMDtcbi8qKlxuICogYGFkYiBsb2djYXQgLXYgdGltZWAgbGluZXMgbG9vayBsaWtlIGBNTS1ERCBISDpNTTpTUy5tbW0gTEVWRUwvVEFHKCBQSUQpOiBtZXNzYWdlYC5cbiAqIEtlZXAgb25seSB0aGUgdGFncyBDaHJvbWl1bS9XZWJWaWV3IHJvdXRlcyBKUyBgY29uc29sZS4qYCBvdXRwdXQgYW5kIHVuY2F1Z2h0XG4gKiBlcnJvcnMgdG8gKGBjaHJvbWl1bWAsIHRoZSBDYXBhY2l0b3IgY29uc29sZSBicmlkZ2UsIGFuZCBuYXRpdmUgYEFuZHJvaWRSdW50aW1lYCkuXG4gKi9cbmNvbnN0IENPTlNPTEVfQ0FQVFVSRV9UQUdfUkUgPSAvXFwvKD86Y2hyb21pdW18QW5kcm9pZFJ1bnRpbWV8Q2FwYWNpdG9yXFwvQ29uc29sZSlcXCgvO1xuXG4vKipcbiAqIEJhc2UgcGF0aCBvbiBhbiBBbmRyb2lkIGRldmljZSB3aGVyZSBPYnNpZGlhbiBNb2JpbGUgc3RvcmVzIGl0cyB2YXVsdHMuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSB0aGUgdHJhbnNwb3J0IGZhY3Rvcnkgc3dlZXBzIGxlZnRvdmVyIHZhdWx0cyBmcm9tIGl0IGJlZm9yZVxuICogYSB0cmFuc3BvcnQgZXhpc3RzIChzZWUgdGhlIHJlcG8ncyBMMzEpLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSCA9ICcvc2RjYXJkL0RvY3VtZW50cy8nO1xuXG5jb25zdCBERUZBVUxUX1ZBVUxUX0JBU0VfUEFUSDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgYW5kcm9pZDogREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSCxcbiAgaW9zOiAnQG1kLm9ic2lkaWFuOmRvY3VtZW50cy8nXG59O1xuXG5pbnRlcmZhY2UgTG9hZGluZ0FwcCB7XG4gIHdvcmtzcGFjZT86IExvYWRpbmdXb3Jrc3BhY2U7XG59XG5cbmludGVyZmFjZSBMb2FkaW5nV29ya3NwYWNlIHtcbiAgbGF5b3V0UmVhZHk/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBBcHBpdW1UcmFuc3BvcnQud2FpdEZvclN0YXJ0dXBNaWxlc3RvbmV9LlxuICovXG5pbnRlcmZhY2UgV2FpdEZvclN0YXJ0dXBNaWxlc3RvbmVQYXJhbXMge1xuICAvKipcbiAgV2hldGhlciB0aGUgbWlsZXN0b25lIGp1c3Qgb2JzZXJ2ZWQgZW5kcyB0aGlzIHBoYXNlLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNTYXRpc2ZpZWQ6IChtaWxlc3RvbmU6IEFwcFN0YXJ0dXBNaWxlc3RvbmUpID0+IGJvb2xlYW47XG5cbiAgLyoqXG4gIFRoZSBwaGFzZSBiZWluZyB3YWl0ZWQgb3V0LCBuYW1lZCBpbiB0aGUgbG9nIGFuZCBpbiB0aGUgdGltZW91dCBtZXNzYWdlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGhhc2U6IEFwcFN0YXJ0dXBQaGFzZTtcblxuICAvKipcbiAgVGhpcyBwaGFzZSdzIGJ1ZGdldC5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRyYW5zcG9ydCB0aGF0IGNvbW11bmljYXRlcyB3aXRoIE9ic2lkaWFuIE1vYmlsZSB2aWEgQXBwaXVtIFdlYlZpZXcgSlMgaW5qZWN0aW9uLlxuICpcbiAqIEV2YWx1YXRlcyBleHByZXNzaW9ucyBieSBzd2l0Y2hpbmcgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0IGFuZFxuICogY2FsbGluZyBgZXhlY3V0ZSgpYC4gTWFuYWdlcyB2YXVsdHMgYnkgd3JpdGluZyB0byB0aGUgV2ViVmlldydzIGBsb2NhbFN0b3JhZ2VgXG4gKiAod2hpY2ggT2JzaWRpYW4gdXNlcyBhcyBpdHMgdmF1bHQgcmVnaXN0cnkgb24gbW9iaWxlKSBhbmQgcHVzaGluZyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICovXG5leHBvcnQgY2xhc3MgQXBwaXVtVHJhbnNwb3J0IGltcGxlbWVudHMgT2JzaWRpYW5UcmFuc3BvcnQge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgZm9yIGEgbW9iaWxlIHBsYXRmb3JtLiBBbHdheXMgYHRydWVgIGZvciB0aGlzIHRyYW5zcG9ydC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpc01vYmlsZSA9IHRydWU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwSWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBhcHBTdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGJyb3dzZXI6IEJyb3dzZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGV2aWNlSWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBgcHJvY2Vzcy5vbignZXhpdCcpYCBoYW5kbGVyIHRoYXQgdGVhcnMgdGhlIGNoYW5uZWwgZG93biB3aGVuIG5vdGhpbmcgZWxzZSB3aWxsLlxuICAgKi9cbiAgcHJpdmF0ZSBkaXNwb3NlSW5wdXRDaGFubmVsT25FeGl0OiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIFRoZSBob3N0IGhhbGYgb2YgdGhlIHRydXN0ZWQtaW5wdXQgY2hhbm5lbDogYSBDRFAgY29ubmVjdGlvbiB0byB0aGUgV2ViVmlldywgaW5kZXBlbmRlbnQgb2YgdGhlXG4gICAqIEFwcGl1bSBzZXNzaW9uLCBvcGVuZWQgbGF6aWx5IG9uIGZpcnN0IGV2YWx1YXRlIGFuZCByZXVzZWQgKHNlZSAqKkwzOSoqKS5cbiAgICovXG4gIHByaXZhdGUgaW5wdXRDaGFubmVsOiBudWxsIHwgV2ViVmlld0NkcENvbm5lY3Rpb24gPSBudWxsO1xuXG4gIC8qKlxuICAgKiBTZXQgb25jZSB0aGUgdHJ1c3RlZC1pbnB1dCBjaGFubmVsIGlzIGtub3duIG5vdCB0byBiZSBvcGVuYWJsZSBoZXJlIChpT1MsIGEgcmVtb3RlIGh1Yiwgbm8gbG9jYWxcbiAgICogYGFkYmApLCBzbyB0aGUgYXR0ZW1wdCBpcyBub3QgcmVwZWF0ZWQgb24gZXZlcnkgZXZhbHVhdGUuXG4gICAqL1xuICBwcml2YXRlIGlzSW5wdXRDaGFubmVsVW5hdmFpbGFibGUgPSBmYWxzZTtcbiAgLyoqXG4gICAqIFRyYWNrcyB3aGV0aGVyIHRoZSBkcml2ZXIgaXMgY3VycmVudGx5IHN3aXRjaGVkIHRvIHRoZSBXZWJWaWV3IGNvbnRleHQuXG4gICAqXG4gICAqIFNldCB0byBgdHJ1ZWAgYWZ0ZXIgYSBzdWNjZXNzZnVsIGBzd2l0Y2hDb250ZXh0KFdFQlZJRVdfbWQub2JzaWRpYW4pYC5cbiAgICogUmVzZXQgdG8gYGZhbHNlYCB3aGVuIHRoZSBjb250ZXh0IGlzIGtub3duIHRvIGJlIGludmFsaWRhdGVkXG4gICAqIChlLmcuIGFmdGVyIGBsb2NhdGlvbi5yZWxvYWQoKWAgaW4ge0BsaW5rIHJlZ2lzdGVyVmF1bHR9KS5cbiAgICpcbiAgICogV2hlbiBgdHJ1ZWAsIHtAbGluayBlbnN1cmVXZWJWaWV3Q29udGV4dH0gc2tpcHMgdGhlIGV4cGVuc2l2ZVxuICAgKiBgZ2V0Q29udGV4dHMoKWAgY2FsbCAod2hpY2ggcnVucyBgYWRiIHNoZWxsIGNhdCAvcHJvYy9uZXQvdW5peGAgYW5kXG4gICAqIGNhbiB0aW1lIG91dCBvbiBzbG93IGVtdWxhdG9ycykuXG4gICAqL1xuICBwcml2YXRlIGlzSW5XZWJWaWV3Q29udGV4dCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBwcmV2aW91cyBldmFsIGVuZGVkIGluIGEgY2FwIG92ZXJydW4sIHNvIHRoZSBuZXh0IG9uZSBpcyBvd2VkIHRoZSByZWNvdmVyeSBncmFjZS5cbiAgICpcbiAgICogVGhlIGFiYW5kb25lZCBjbG9zdXJlIGlzIHN0aWxsIHJ1bm5pbmcgaW4gdGhlIGd1ZXN0LCBhbmQgQXBwaXVtIHNlcmlhbGl6ZXMgY29tbWFuZHMgcGVyIHNlc3Npb24sIHNvXG4gICAqIHRoZSBuZXh0IGNvbW1hbmQgcXVldWVzIGJlaGluZCB3aGF0ZXZlciBpcyBsZWZ0IG9mIGl0LiBTZWUge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5ldmFsdWF0ZVdpdGhpbkNhcH0uXG4gICAqL1xuICBwcml2YXRlIGlzUmVjb3ZlcmluZ0Zyb21DYXBPdmVycnVuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpc1Nlc3Npb25Pd25lcjogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHBsYXRmb3JtOiAnYW5kcm9pZCcgfCAnaW9zJztcbiAgcHJpdmF0ZSByZWFkb25seSBzY3JpcHRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBzaG91bGRTd2VlcExlZnRvdmVyczogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSB2YXVsdEJhc2VQYXRoOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB3ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgQXBwaXVtIHRyYW5zcG9ydC5cbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZyAtIEFwcGl1bSB0cmFuc3BvcnQgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihjb25maWc6IEFwcGl1bVRyYW5zcG9ydENvbmZpZykge1xuICAgIHRoaXMuYnJvd3NlciA9IGNvbmZpZy5icm93c2VyO1xuICAgIHRoaXMuZGV2aWNlSWQgPSBjb25maWcuZGV2aWNlSWQ7XG4gICAgdGhpcy5pc1Nlc3Npb25Pd25lciA9IGNvbmZpZy5pc1Nlc3Npb25Pd25lciA/PyB0cnVlO1xuICAgIHRoaXMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBjb25maWcubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9MQVlPVVRfUkVBRFlfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgICB0aGlzLnBsYXRmb3JtID0gY29uZmlnLnBsYXRmb3JtO1xuICAgIHRoaXMuYXBwSWQgPSBjb25maWcuYXBwSWQgPz8gREVGQVVMVF9BUFBfSUQ7XG4gICAgdGhpcy5hcHBTdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IGNvbmZpZy5hcHBTdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA/PyBERUZBVUxUX0FQUF9TVEFSVF9QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICAgIHRoaXMuc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzID0gY29uZmlnLnNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA/PyBERUZBVUxUX0VWQUxfQ0FQX0lOX01JTExJU0VDT05EUztcbiAgICB0aGlzLnNob3VsZFN3ZWVwTGVmdG92ZXJzID0gY29uZmlnLnNob3VsZFN3ZWVwTGVmdG92ZXJzID8/IHRydWU7XG4gICAgdGhpcy52YXVsdEJhc2VQYXRoID0gY29uZmlnLnZhdWx0QmFzZVBhdGggPz8gREVGQVVMVF9WQVVMVF9CQVNFX1BBVEhbdGhpcy5wbGF0Zm9ybV0gPz8gREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSDtcbiAgICB0aGlzLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBjb25maWcud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyA/PyBERUZBVUxUX1dFQlZJRVdfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgfVxuXG4gIC8qKlxuICAgKiBCZWdpbnMgYSBjb25zb2xlIGNhcHR1cmUgYnkgc3RhbXBpbmcgdGhlIGRldmljZSBsb2cgd2l0aCBhIHVuaXF1ZSBtYXJrZXIuXG4gICAqXG4gICAqIFVzZXMgYGFkYiBzaGVsbCBsb2dgIHRvIHdyaXRlIGEgbWFya2VyIGludG8gYGxvZ2NhdGAgYXQgY2FwdHVyZSBzdGFydCBzbyBhXG4gICAqIGxhdGVyIHtAbGluayBBcHBpdW1UcmFuc3BvcnQucmVhZENvbnNvbGVDYXB0dXJlU2luY2V9IGNhbiBzbGljZSBvdXRcbiAgICogZXZlcnl0aGluZyB0aGUgV2ViVmlldyBsb2dnZWQgYWZ0ZXJ3YXJkcyBcdTIwMTQgd2l0aG91dCB0aGUgaW52YXNpdmUgYGxvZ2NhdCAtY2BcbiAgICogYnVmZmVyIGNsZWFyLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIGhhbmRsZSBjYXJyeWluZyB0aGUgdW5pcXVlIG1hcmtlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBiZWdpbkNvbnNvbGVDYXB0dXJlKCk6IFByb21pc2U8Q29uc29sZUNhcHR1cmVIYW5kbGU+IHtcbiAgICBjb25zdCBtYXJrZXIgPSBgJHtDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBR31fJHtyYW5kb21VVUlEKCl9YDtcbiAgICBhd2FpdCBleGVjKFxuICAgICAgWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbG9nJywgJy10JywgQ09OU09MRV9DQVBUVVJFX01BUktFUl9UQUcsIG1hcmtlcl0sXG4gICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9MT0dfTUFSS0VSX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICApO1xuICAgIHJldHVybiB7IG1hcmtlciB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENhcHR1cmVzIGEgUE5HIHNjcmVlbnNob3Qgb2YgdGhlIGRldmljZSdzIHNjcmVlbi5cbiAgICpcbiAgICogVGhlIGltYWdlIGlzIGFsd2F5cyB0aGUgZGV2aWNlJ3MgbmF0aXZlIGZyYW1lYnVmZmVyIFx1MjAxNCB0aGVyZSBpcyBubyBtb2JpbGVcbiAgICogZXF1aXZhbGVudCBvZiB0aGUgZGVza3RvcCB2aWV3cG9ydCBvdmVycmlkZSwgc29cbiAgICoge0BsaW5rIENhcHR1cmVTY3JlZW5zaG90UGFyYW1zLndpZHRoSW5QaXhlbHN9IC9cbiAgICoge0BsaW5rIENhcHR1cmVTY3JlZW5zaG90UGFyYW1zLmhlaWdodEluUGl4ZWxzfSBhcmUgaWdub3JlZC4gU2l6ZSBhIG1vYmlsZVxuICAgKiBjYXB0dXJlIGJ5IGNob29zaW5nIGFuIEFWRCB3aG9zZSBzY3JlZW4gZ2VvbWV0cnkgYWxyZWFkeSBtYXRjaGVzIHdoYXQgdGhlXG4gICAqIGltYWdlIGhhcyB0byBiZS5cbiAgICpcbiAgICogQHBhcmFtIF9wYXJhbXMgLSBDYXB0dXJlIHBhcmFtZXRlcnMuIElnbm9yZWQgb24gbW9iaWxlOiBgY3dkYCBkb2VzIG5vdCBzZWxlY3QgYSB3aW5kb3cgKHZhdWx0IHRhcmdldGluZyBpcyB2aWEgbG9jYWxTdG9yYWdlKSwgYW5kIHRoZSBzaXplIGNhbm5vdCBiZSBvdmVycmlkZGVuLlxuICAgKiBAcmV0dXJucyBUaGUgcmF3IFBORyBieXRlcy5cbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgZHJpdmVyIHJldHVybnMgZGF0YSB0aGF0IGlzIG5vdCBhIFBORy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBjYXB0dXJlU2NyZWVuc2hvdChfcGFyYW1zOiBDYXB0dXJlU2NyZWVuc2hvdFBhcmFtcyk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICAgIGNvbnN0IGJ5dGVzID0gZGVjb2RlQmFzZTY0UG5nKGF3YWl0IHRoaXMuYnJvd3Nlci50YWtlU2NyZWVuc2hvdCgpKTtcbiAgICBpZiAoIWlzUG5nKGJ5dGVzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBcHBpdW0gc2NyZWVuc2hvdCBlcnJvcjogdGFrZVNjcmVlbnNob3QgcmV0dXJuZWQgZGF0YSB0aGF0IGlzIG5vdCBhIFBORy4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogRW5kcyB0aGUgQXBwaXVtIHNlc3Npb24uXG4gICAqXG4gICAqIE9ubHkgZGVsZXRlcyB0aGUgc2Vzc2lvbiBpZiB0aGlzIHRyYW5zcG9ydCBvd25zIGl0LiBUcmFuc3BvcnRzIGNyZWF0ZWRcbiAgICogdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycyByZXVzaW5nIHRoZSBnbG9iYWwgc2V0dXAncyBzZXNzaW9uKSBza2lwXG4gICAqIGRlbGV0aW9uIHNvIHRoZSBzZXNzaW9uIHJlbWFpbnMgYXZhaWxhYmxlIGZvciB0aGUgb3duaW5nIHByb2Nlc3MuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlzcG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWwoKTtcblxuICAgIGlmICh0aGlzLmlzU2Vzc2lvbk93bmVyKSB7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuZGVsZXRlU2Vzc2lvbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jaHJvbm91cyB0ZWFyZG93biBmb3IgYHByb2Nlc3Mub24oJ2V4aXQnKWAgaGFuZGxlcnMuXG4gICAqXG4gICAqIE9ubHkgdGhlIHRydXN0ZWQtaW5wdXQgY2hhbm5lbCBuZWVkcyBpdDogdGhlIEFwcGl1bSBzZXNzaW9uIGlzIHRoZSBvd25pbmcgcHJvY2VzcydzIHRvIGVuZCwgYW5kIGFuXG4gICAqIGFicnVwdCBleGl0IGlzIGV4YWN0bHkgd2hlbiB0aGUgYXN5bmMge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5kaXNwb3NlfSBuZXZlciBydW5zIFx1MjAxNCB3aGljaCB3b3VsZCBzdHJhbmRcbiAgICogdGhlIGFkYiBwb3J0IGZvcndhcmQgb24gdGhlIGRldmljZS5cbiAgICovXG4gIHB1YmxpYyBkaXNwb3NlU3luYygpOiB2b2lkIHtcbiAgICBjb25zdCBjaGFubmVsID0gdGhpcy5pbnB1dENoYW5uZWw7XG4gICAgdGhpcy5pbnB1dENoYW5uZWwgPSBudWxsO1xuICAgIHRoaXMudW5yZWdpc3RlcklucHV0Q2hhbm5lbEV4aXRIYW5kbGVyKCk7XG4gICAgY2hhbm5lbD8uZGlzcG9zZVN5bmMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZXMgYSBKYXZhU2NyaXB0IGV4cHJlc3Npb24gaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSdzIFdlYlZpZXcuXG4gICAqXG4gICAqIFN3aXRjaGVzIHRvIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dCwgZXhlY3V0ZXMgdGhlIGV4cHJlc3Npb24sXG4gICAqIGFuZCByZXR1cm5zIHRoZSByZXN1bHQgc3RyaW5nLlxuICAgKlxuICAgKiBAcGFyYW0gZXhwcmVzc2lvbiAtIFRoZSBKYXZhU2NyaXB0IGV4cHJlc3Npb24gdG8gZXZhbHVhdGUuXG4gICAqIEBwYXJhbSBfb3B0aW9ucyAtIEV2YWx1YXRpb24gb3B0aW9ucyAoY3dkIGlzIG5vdCB1c2VkIG9uIG1vYmlsZSBcdTIwMTQgdmF1bHQgdGFyZ2V0aW5nIGlzIHZpYSBsb2NhbFN0b3JhZ2UpLlxuICAgKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCByZXN1bHQgc3RyaW5nLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGV2YWx1YXRlKGV4cHJlc3Npb246IHN0cmluZywgX29wdGlvbnM6IFRyYW5zcG9ydEV2YWxPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVJbnB1dENoYW5uZWwoKTtcblxuICAgIHRyeSB7XG4gICAgICAvKlxuICAgICAgICogVGhlIGNhcCBpcyBlbmZvcmNlZCBIRVJFLCBvbiB0aGUgTm9kZSBzaWRlLCBhbmQgbm90IGJ5IHRoZSBgdGltZW91dHMuc2NyaXB0YCBjYXBhYmlsaXR5IHRoZVxuICAgICAgICogU2Vzc2lvbiBhbHNvIGRlY2xhcmVzLiBNZWFzdXJlZCBvbiBhIGxpdmUgZW11bGF0b3I6IHRoZSBjYXBhYmlsaXR5IGlzIGFjY2VwdGVkIGFuZCByZWFkc1xuICAgICAgICogQmFjayBhcyAzMDAwMCBpbiB0aGUgV2ViVmlldyBjb250ZXh0LCBhbmQgbm90aGluZyBldmVyIGVuZm9yY2VzIGl0IFx1MjAxNCBvdmVyLWNhcCBjbG9zdXJlcyBpbiBib3RoIHRoZVxuICAgICAgICogU2xlZXBpbmcgYW5kIHRoZSBzcGlubmluZyBzaGFwZSwgd2l0aCBhbmQgd2l0aG91dCBhbiBleHBsaWNpdCBgc2V0VGltZW91dHNgLCByYW4gcGFzdCBhIDYwcyBjZWlsaW5nXG4gICAgICAgKiBXaXRob3V0IFdlYkRyaXZlciByYWlzaW5nIGBzY3JpcHQgdGltZW91dGAgZXZlbiBvbmNlLiBXaGF0IGFjdHVhbGx5IGhhcHBlbnMgcGFzdCByb3VnaGx5IGhhbGYgYVxuICAgICAgICogTWludXRlIGlzIHdvcnNlIHRoYW4gYSBsYXRlIGFuc3dlcjogdGhlIGNsb3N1cmUgQ09NUExFVEVTIGluIHRoZSBndWVzdCBvbiBzY2hlZHVsZSAodGltZXJzIGFybWVkIGF0XG4gICAgICAgKiAzMHMgYW5kIDQwcyBmaXJlZCB3aXRoaW4gfjEzbXMgb2Ygbm9taW5hbCwgb24gYSB2aXNpYmxlIGFuZCBmb2N1c2VkIHBhZ2UpIGFuZCBpdHMgRXhlY3V0ZSBTY3JpcHRcbiAgICAgICAqIFJlc3BvbnNlIG5ldmVyIHJlYWNoZXMgdGhpcyBjbGllbnQgXHUyMDE0IHNvIHRoZSBwcm9taXNlIGJlbG93IHNpbXBseSBuZXZlciBzZXR0bGVzLlxuICAgICAgICpcbiAgICAgICAqIEEgaGFuZyBpcyB0aGUgb25lIGZhaWx1cmUgbW9kZSBhIHRlc3QgYXV0aG9yIGNhbm5vdCBhY3Qgb24sIHNvIHRoZSB3YWl0IGlzIGJvdW5kZWQgaGVyZS5cbiAgICAgICAqL1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ldmFsdWF0ZVdpdGhpbkNhcChgcmV0dXJuICgke2V4cHJlc3Npb259KWApO1xuXG4gICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQgfHwgcmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBOT19PVVRQVVQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8qXG4gICAgICAgKiBBIGNhcCBvdmVycnVuIGlzIHRoZSBvbmUgZmFpbHVyZSBoZXJlIHRoYXQgc2F5cyBub3RoaW5nIGFib3V0IHRoZSBjb250ZXh0OiB0aGUgY2xvc3VyZSBvdXRzdGF5ZWRcbiAgICAgICAqIEl0cyBidWRnZXQsIHRoZSBXZWJWaWV3IGlzIHN0aWxsIHRoZSBXZWJWaWV3LiBSZXNldHRpbmcgdGhlIGZsYWcgd291bGQgY2hhcmdlIHRoZSBORVhUIGV2YWwgYVxuICAgICAgICogfjE3cyBgc3dpdGNoQ29udGV4dGAgKCoqTDE5KiopIHRvIHJlY292ZXIgZnJvbSBzb21ldGhpbmcgdGhhdCB3YXMgbmV2ZXIgbG9zdC5cbiAgICAgICAqL1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXZhbENhcEV4Y2VlZGVkRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbnRleHQgbWF5IGhhdmUgYmVlbiBsb3N0IG1pZC1leGVjdXRpb24gKGUuZy4gcGFnZSByZWxvYWQpLlxuICAgICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSBmYWxzZTtcblxuICAgICAgLypcbiAgICAgICAqIEtlcHQgYXMgYSBmYXN0IHBhdGggZXZlbiB0aG91Z2ggdGhpcyBkcml2ZXIgd2FzIG1lYXN1cmVkIG5ldmVyIHJhaXNpbmcgaXQ6IGl0IGNvc3RzIG5vdGhpbmcsXG4gICAgICAgKiBJdCBpcyB0aGUgY29ycmVjdCB0cmFuc2xhdGlvbiBpZiBhIGZ1dHVyZSBkcml2ZXIgZG9lcyBlbmZvcmNlIHRoZSBjYXBhYmlsaXR5LCBhbmQgaXQga2VlcHMgdGhlIHR3b1xuICAgICAgICogVHJhbnNwb3J0cyByZXBvcnRpbmcgb25lIGVycm9yIGZvciBvbmUgY29uZGl0aW9uLlxuICAgICAgICovXG4gICAgICBpZiAoaXNTY3JpcHRUaW1lb3V0RXJyb3IoZXJyb3IpKSB7XG4gICAgICAgIHRocm93IG5ldyBFdmFsQ2FwRXhjZWVkZWRFcnJvcih7XG4gICAgICAgICAgY2FwSW5NaWxsaXNlY29uZHM6IHRoaXMuc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzLFxuICAgICAgICAgIGNhdXNlOiBlcnJvcixcbiAgICAgICAgICBvcHRpb25OYW1lOiAnc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzJyxcbiAgICAgICAgICB0cmFuc3BvcnROYW1lOiAnQW5kcm9pZCAoQXBwaXVtKSdcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzZXNzaW9uIGNvbm5lY3Rpb24gaW5mbyBuZWVkZWQgdG8gcmVhdHRhY2ggdG8gdGhpcyBzZXNzaW9uXG4gICAqIGZyb20gYW5vdGhlciBwcm9jZXNzIChlLmcuIGEgdGVzdCB3b3JrZXIpLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2Vzc2lvbiBJRCBhbmQgZGV2aWNlIElELlxuICAgKi9cbiAgcHVibGljIGdldFNlc3Npb25JbmZvKCk6IEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGV2aWNlSWQ6IHRoaXMuZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHRoaXMuYnJvd3Nlci5zZXNzaW9uSWRcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHRoYXQgdGhlIE9ic2lkaWFuIGFwcCBpcyBydW5uaW5nIGFuZCB0aGUgV2ViVmlldyBpcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBwYXJhbSBfdmF1bHRQYXRoIC0gTm90IHVzZWQgb24gbW9iaWxlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHByZWZsaWdodENoZWNrKF92YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZygnW2FwcGl1bS10cmFuc3BvcnRdIFJ1bm5pbmcgcHJlZmxpZ2h0IGNoZWNrLi4uJyk7XG4gICAgY29uc3Qgc3RhdGUgPSBhd2FpdCB0aGlzLmJyb3dzZXIucXVlcnlBcHBTdGF0ZSh0aGlzLmFwcElkKTtcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBBcHAgc3RhdGU6ICR7U3RyaW5nKHN0YXRlKX0gKG5lZWQgJHtTdHJpbmcoQVBQX1NUQVRFX0ZPUkVHUk9VTkQpfT1mb3JlZ3JvdW5kKWApO1xuICAgIGlmIChzdGF0ZSAhPT0gQVBQX1NUQVRFX0ZPUkVHUk9VTkQpIHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIEFjdGl2YXRpbmcgYXBwICR7dGhpcy5hcHBJZH0uLi5gKTtcbiAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuYWN0aXZhdGVBcHAodGhpcy5hcHBJZCk7XG4gICAgICBhd2FpdCBkZWxheShBUFBfUkVTVEFSVF9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcbiAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBQcmVmbGlnaHQgY2hlY2sgcGFzc2VkLicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1c2hlcyB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIHZpYSBjb21wcmVzc2VkIGBhZGIgcHVzaGAuXG4gICAqXG4gICAqIENyZWF0ZXMgYSB0YXIuZ3ogYXJjaGl2ZSBvZiB0aGUgbG9jYWwgdmF1bHQgZGlyZWN0b3J5LCBwdXNoZXMgaXQgdG8gdGhlXG4gICAqIGRldmljZSBhcyBhIHNpbmdsZSBmaWxlLCBhbmQgZXh0cmFjdHMgaXQgaW4tcGxhY2UuIFRoaXMgYXZvaWRzIHRoZVxuICAgKiB3ZWJkcml2ZXIgYFJhbmdlRXJyb3JgIG9uIGxhcmdlIGJhc2U2NCBwYXlsb2FkcyBhbmQgaXMgc2lnbmlmaWNhbnRseVxuICAgKiBmYXN0ZXIgdGhhbiBwZXItZmlsZSBgYnJvd3Nlci5wdXNoRmlsZSgpYCBjYWxscy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoICh1c2VkIGFzIHRoZSB2YXVsdCBkaXJlY3RvcnkgbmFtZSBvbiBkZXZpY2UpLlxuICAgKiBAcGFyYW0gX2ZpbGVzIC0gTWFwIG9mIHJlbGF0aXZlIGZpbGUgcGF0aHMgdG8gY29udGVudCBidWZmZXJzICh1bnVzZWQgXHUyMDE0IGFkYiBwdXNoZXMgdGhlIGRpcmVjdG9yeSBkaXJlY3RseSkuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcHVzaEZpbGVzKHZhdWx0UGF0aDogc3RyaW5nLCBfZmlsZXM6IFJlY29yZDxzdHJpbmcsIFVpbnQ4QXJyYXk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcbiAgICBjb25zdCBhcmNoaXZlTmFtZSA9IGB2YXVsdC0ke3JhbmRvbVVVSUQoKX0udGFyLmd6YDtcbiAgICBjb25zdCBsb2NhbEFyY2hpdmUgPSBqb2luKHRtcGRpcigpLCBhcmNoaXZlTmFtZSk7XG4gICAgY29uc3QgcmVtb3RlQXJjaGl2ZSA9IGAvZGF0YS9sb2NhbC90bXAvJHthcmNoaXZlTmFtZX1gO1xuXG4gICAgdHJ5IHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIENyZWF0aW5nIGFyY2hpdmU6ICR7bG9jYWxBcmNoaXZlfWApO1xuICAgICAgYXdhaXQgZXhlYyhbJ3RhcicsICdjemYnLCBhcmNoaXZlTmFtZSwgJy1DJywgdmF1bHRQYXRoLCAnLiddLCB7IGN3ZDogdG1wZGlyKCksIGlzUXVpZXQ6IHRydWUgfSk7XG5cbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFB1c2hpbmcgYXJjaGl2ZSB0byBkZXZpY2UgJHt0aGlzLmRldmljZUlkfS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdwdXNoJywgbG9jYWxBcmNoaXZlLCByZW1vdGVBcmNoaXZlXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBFeHRyYWN0aW5nIGFyY2hpdmUgb24gZGV2aWNlIGF0ICR7ZGV2aWNlVmF1bHRQYXRofS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdta2RpcicsICctcCcsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAndGFyJywgJ3h6ZicsIHJlbW90ZUFyY2hpdmUsICctQycsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gRmx1c2hpbmcgZmlsZXN5c3RlbSBidWZmZXJzLi4uJyk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3N5bmMnXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBDbGVhbmluZyB1cCByZW1vdGUgYXJjaGl2ZS4uLicpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdybScsIHJlbW90ZUFyY2hpdmVdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJtKGxvY2FsQXJjaGl2ZSwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRHVtcHMgYGFkYiBsb2djYXRgIGFuZCByZXR1cm5zIHRoZSBXZWJWaWV3IGNvbnNvbGUvZXJyb3Igb3V0cHV0IGxvZ2dlZFxuICAgKiBzaW5jZSB0aGUgbWFya2VyIGZyb20ge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5iZWdpbkNvbnNvbGVDYXB0dXJlfS5cbiAgICpcbiAgICogRmlsdGVycyB0byB0aGUgQ2hyb21pdW0vV2ViVmlldyB0YWdzIHRoYXQgY2FycnkgSlMgYGNvbnNvbGUuKmAgb3V0cHV0IGFuZFxuICAgKiB1bmNhdWdodCBlcnJvcnMsIGFuZCBjYXBzIHRoZSByZXN1bHQgbGVuZ3RoLiBCb3VuZGVkLCBwb3N0LWhvYyxcbiAgICogZmFpbHVyZS1wYXRoLW9ubHkgXHUyMDE0IG5ldmVyIGEgbGl2ZSBtb25pdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gaGFuZGxlIC0gVGhlIGNhcHR1cmUgaGFuZGxlIChvciBgdW5kZWZpbmVkYCB3aGVuIGNhcHR1cmUgbmV2ZXIgc3RhcnRlZCkuXG4gICAqIEByZXR1cm5zIFRoZSBjYXB0dXJlZCBjb25zb2xlL2Vycm9yIHRleHQsIG9yIGB1bmRlZmluZWRgIGlmIG5vdGhpbmcgcmVsZXZhbnQgd2FzIGxvZ2dlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWFkQ29uc29sZUNhcHR1cmVTaW5jZShoYW5kbGU6IENvbnNvbGVDYXB0dXJlSGFuZGxlIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoIWhhbmRsZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBkdW1wID0gYXdhaXQgZXhlYyhcbiAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ2xvZ2NhdCcsICctZCcsICctdicsICd0aW1lJ10sXG4gICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IExPR0NBVF9EVU1QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICApO1xuXG4gICAgY29uc3QgbWFya2VySW5kZXggPSBkdW1wLmxhc3RJbmRleE9mKGhhbmRsZS5tYXJrZXIpO1xuICAgIGNvbnN0IHJlZ2lvbiA9IG1hcmtlckluZGV4ID09PSAtMSA/IGR1bXAgOiBkdW1wLnNsaWNlKG1hcmtlckluZGV4ICsgaGFuZGxlLm1hcmtlci5sZW5ndGgpO1xuICAgIGNvbnN0IHJlbGV2YW50ID0gcmVnaW9uXG4gICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAuZmlsdGVyKChsaW5lKSA9PiBDT05TT0xFX0NBUFRVUkVfVEFHX1JFLnRlc3QobGluZSkpXG4gICAgICAuam9pbignXFxuJylcbiAgICAgIC50cmltKCk7XG5cbiAgICBpZiAoIXJlbGV2YW50KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiByZWxldmFudC5zbGljZSgtQ09OU09MRV9DQVBUVVJFX1RBSUxfTUFYX0xFTkdUSCk7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgdmF1bHQgb24gbW9iaWxlIGJ5IHB1c2hpbmcgZmlsZXMgYW5kIGNvbmZpZ3VyaW5nIGxvY2FsU3RvcmFnZS5cbiAgICpcbiAgICogVGhlIHJlZ2lzdHJhdGlvbiBmbG93OlxuICAgKiAxLiBQdXNoIGEgbWluaW1hbCBgLm9ic2lkaWFuL2FwcC5qc29uYCB0byB0aGUgZGV2aWNlIHNvIE9ic2lkaWFuIHJlY29nbml6ZXMgdGhlIHZhdWx0XG4gICAqIDIuIFN3aXRjaCB0byB0aGUgV2ViVmlldyBjb250ZXh0XG4gICAqIDMuIEFkZCB0aGUgdmF1bHQgdG8gbG9jYWxTdG9yYWdlIChgbW9iaWxlLWV4dGVybmFsLXZhdWx0c2AsIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgLFxuICAgKiAgICBgZW5hYmxlLXBsdWdpbi08cGF0aD5gKVxuICAgKiA0LiBUcmlnZ2VyIGBsb2NhdGlvbi5yZWxvYWQoKWAgc28gT2JzaWRpYW4gcmUtcmVhZHMgbG9jYWxTdG9yYWdlIGFuZCBvcGVucyB0aGUgdmF1bHRcbiAgICogNS4gV2FpdCBmb3IgYGdsb2JhbFRoaXMuYXBwYCB0byBleGlzdCAodGhlIGFwcCdzIGNvbGQgc3RhcnQpLCB0aGVuIFx1MjAxNCBvbiBhXG4gICAqICAgIHNlcGFyYXRlLCB0aWdodGVyIGJ1ZGdldCBcdTIwMTQgZm9yIGBhcHAud29ya3NwYWNlLmxheW91dFJlYWR5YFxuICAgKlxuICAgKiBFeGlzdGluZyB2YXVsdCByZWdpc3RyYXRpb25zIGluIGxvY2FsU3RvcmFnZSBhcmUgcHJlc2VydmVkIChhcHBlbmQsIG5vdFxuICAgKiBvdmVyd3JpdGUpIFx1MjAxNCBleGNlcHQgdGhlICoqaGFybmVzcydzIG93bioqIGB0ZW1wLXZhdWx0LSpgIHJlZ2lzdHJhdGlvbnMgZnJvbVxuICAgKiBlYXJsaWVyIHJ1bnMsIHdoaWNoIGFyZSBwcnVuZWQgd2hlbiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0Q29uZmlnLnNob3VsZFN3ZWVwTGVmdG92ZXJzfVxuICAgKiBpcyBvbi4gVGhlaXIgZGlyZWN0b3JpZXMgYXJlIGFscmVhZHkgZ29uZSAodGhlIGZhY3Rvcnkgc3dlZXBzIHRoZW0gYmVmb3JlXG4gICAqIHRoZSBhcHAgbGF1bmNoZXMpLCBhbmQgaXQgaXMgdGhpcyByZWdpc3RyeSBcdTIwMTQgbm90IHRoZSBmaWxlc3lzdGVtIFx1MjAxNCB0aGF0XG4gICAqIE9ic2lkaWFuIGVudW1lcmF0ZXMgYXQgc3RhcnR1cCwgc28gbGVhdmluZyB0aGVtIGlzIHdoYXQgbWFrZXMgZWFjaCBmYWlsZWRcbiAgICogcnVuIHNsb3cgdGhlIG5leHQgb25lIGRvd24uXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgb24gdGhlIGhvc3QgbWFjaGluZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWdpc3RlclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gUmVnaXN0ZXJpbmcgdmF1bHQ6ICR7dmF1bHRQYXRofWApO1xuICAgIGNvbnN0IGRldmljZVZhdWx0UGF0aCA9IHRoaXMuZ2V0RGV2aWNlVmF1bHRQYXRoKHZhdWx0UGF0aCk7XG5cbiAgICAvLyBQdXNoIGEgbWluaW1hbCAub2JzaWRpYW4gZGlyZWN0b3J5IHNvIE9ic2lkaWFuIHJlY29nbml6ZXMgaXQgYXMgYSB2YXVsdC5cbiAgICBhd2FpdCB0aGlzLnB1c2hPYnNpZGlhbk1hcmtlcihkZXZpY2VWYXVsdFBhdGgpO1xuXG4gICAgLy8gU3dpdGNoIHRvIFdlYlZpZXcgYW5kIGNvbmZpZ3VyZSBsb2NhbFN0b3JhZ2UuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVXZWJWaWV3Q29udGV4dCgpO1xuXG4gICAgLy8gSW52YWxpZGF0ZSBiZWZvcmUgcmVsb2FkIFx1MjAxNCB0aGUgcGFnZSB3aWxsIG5hdmlnYXRlIGFuZCB0aGUgV2ViVmlld1xuICAgIC8vIENvbnRleHQgbWF5IGJlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlIGR1cmluZyByZWxvYWQuXG4gICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSBmYWxzZTtcblxuICAgIGNvbnN0IHN0YWxlUHJlZml4ID0gdGhpcy5zaG91bGRTd2VlcExlZnRvdmVycyA/IGAke3RoaXMudmF1bHRCYXNlUGF0aH0ke1RFTVBfVkFVTFRfRElSX1BSRUZJWH1gIDogJyc7XG5cbiAgICBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZShcbiAgICAgIChwYXRoOiBzdHJpbmcsIHBydW5lUHJlZml4OiBzdHJpbmcpID0+IHtcbiAgICAgICAgbGV0IGV4aXN0aW5nID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbW9iaWxlLWV4dGVybmFsLXZhdWx0cycpID8/ICdbXScpIGFzIHN0cmluZ1tdO1xuXG4gICAgICAgIGlmIChwcnVuZVByZWZpeCkge1xuICAgICAgICAgIGNvbnN0IHN0YWxlID0gZXhpc3RpbmcuZmlsdGVyKChyZWdpc3RlcmVkKSA9PiByZWdpc3RlcmVkICE9PSBwYXRoICYmIHJlZ2lzdGVyZWQuc3RhcnRzV2l0aChwcnVuZVByZWZpeCkpO1xuICAgICAgICAgIGZvciAoY29uc3QgcmVnaXN0ZXJlZCBvZiBzdGFsZSkge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oYGVuYWJsZS1wbHVnaW4tJHtyZWdpc3RlcmVkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBleGlzdGluZyA9IGV4aXN0aW5nLmZpbHRlcigocmVnaXN0ZXJlZCkgPT4gIXN0YWxlLmluY2x1ZGVzKHJlZ2lzdGVyZWQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZXhpc3RpbmcuaW5jbHVkZXMocGF0aCkpIHtcbiAgICAgICAgICBleGlzdGluZy5wdXNoKHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJywgSlNPTi5zdHJpbmdpZnkoZXhpc3RpbmcpKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcsIHBhdGgpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShgZW5hYmxlLXBsdWdpbi0ke3BhdGh9YCwgJ3RydWUnKTtcbiAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICB9LFxuICAgICAgZGV2aWNlVmF1bHRQYXRoLFxuICAgICAgc3RhbGVQcmVmaXhcbiAgICApO1xuXG4gICAgLy8gV2FpdCBmb3IgcmVsb2FkICsgdmF1bHQgaW5pdGlhbGl6YXRpb24sIGFzIHR3byBzZXBhcmF0ZWx5IGJ1ZGdldGVkIHBoYXNlczpcbiAgICAvLyBUaGUgYXBwJ3MgY29sZCBzdGFydCBmaXJzdCwgdGhlbiBPYnNpZGlhbidzIG93biB3b3JrLiBTZWUgYHdhaXRGb3JBcHBTdGFydGVkYC5cbiAgICBhd2FpdCB0aGlzLndhaXRGb3JBcHBTdGFydGVkKCk7XG4gICAgYXdhaXQgdGhpcy53YWl0Rm9yTGF5b3V0UmVhZHkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVycyBhIHZhdWx0IG9uIG1vYmlsZSBieSByZW1vdmluZyBpdCBmcm9tIGxvY2FsU3RvcmFnZS5cbiAgICpcbiAgICogUHJlc2VydmVzIG90aGVyIHZhdWx0IHJlZ2lzdHJhdGlvbnMuIElmIHRoZSB1bnJlZ2lzdGVyZWQgdmF1bHQgd2FzIHNlbGVjdGVkLFxuICAgKiBzd2l0Y2hlcyB0byB0aGUgZmlyc3QgcmVtYWluaW5nIHZhdWx0IChvciBjbGVhcnMgdGhlIHNlbGVjdGlvbikuXG4gICAqXG4gICAqIFRoZSB2YXVsdCdzICoqZmlsZXMgYXJlIHRoZW4gcmVtb3ZlZCBmcm9tIHRoZSBkZXZpY2Ugb3ZlciBgYWRiYCwgd2hldGhlciBvclxuICAgKiBub3QgdGhlIGBsb2NhbFN0b3JhZ2VgIHN0ZXAgc3VjY2VlZGVkKiogXHUyMDE0IGRlbGliZXJhdGVseSwgYmVjYXVzZSB0aGVcbiAgICogYGxvY2FsU3RvcmFnZWAgc3RlcCBnb2VzIHRocm91Z2ggdGhlIFdlYlZpZXcgYW5kIGEgZGVhZCBXZWJWaWV3IGlzIGV4YWN0bHlcbiAgICogd2hhdCBtb3N0IEFuZHJvaWQgZmFpbHVyZXMgYXJlLiBSb3V0aW5nIHRoZSByZW1vdmFsIHRocm91Z2ggdGhlIGFwcCB3YXMgd2hhdFxuICAgKiBtYWRlIGV2ZXJ5IGZhaWxlZCBydW4gbGVhayBpdHMgdmF1bHQgKGBWYXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiBub1xuICAgKiBzdWNoIHdpbmRvd2ApLCBzbyB0aGUgZmlsZXN5c3RlbS1sZXZlbCByZW1vdmFsIG11c3Qgbm90IGRlcGVuZCBvbiBpdC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHVucmVnaXN0ZXJWYXVsdCh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRldmljZVZhdWx0UGF0aCA9IHRoaXMuZ2V0RGV2aWNlVmF1bHRQYXRoKHZhdWx0UGF0aCk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVXZWJWaWV3Q29udGV4dCgpO1xuXG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZSgocGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbW9iaWxlLWV4dGVybmFsLXZhdWx0cycpID8/ICdbXScpIGFzIHN0cmluZ1tdO1xuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IGV4aXN0aW5nLmZpbHRlcigodikgPT4gdiAhPT0gcGF0aCk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJywgSlNPTi5zdHJpbmdpZnkoZmlsdGVyZWQpKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oYGVuYWJsZS1wbHVnaW4tJHtwYXRofWApO1xuICAgICAgICBpZiAobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcpID09PSBwYXRoKSB7XG4gICAgICAgICAgaWYgKGZpbHRlcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtb2JpbGUtc2VsZWN0ZWQtdmF1bHQnLCBmaWx0ZXJlZFswXSA/PyAnJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdtb2JpbGUtc2VsZWN0ZWQtdmF1bHQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIGRldmljZVZhdWx0UGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhcbiAgICAgICAgYFthcHBpdW0tdHJhbnNwb3J0XSBDb3VsZCBub3QgZGVyZWdpc3RlciAke2RldmljZVZhdWx0UGF0aH0gZnJvbSBsb2NhbFN0b3JhZ2UgYFxuICAgICAgICAgICsgYCgke1N0cmluZyhlcnJvcil9KTsgcmVtb3ZpbmcgaXRzIGZpbGVzIGFueXdheS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMucmVtb3ZlRGV2aWNlVmF1bHREaXJlY3RvcnkoZGV2aWNlVmF1bHRQYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgdGhlIHRydXN0ZWQtaW5wdXQgY2hhbm5lbCwgaWYgb25lIGlzIG9wZW4uXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRpc3Bvc2VJbnB1dENoYW5uZWwoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2hhbm5lbCA9IHRoaXMuaW5wdXRDaGFubmVsO1xuICAgIHRoaXMuaW5wdXRDaGFubmVsID0gbnVsbDtcbiAgICB0aGlzLnVucmVnaXN0ZXJJbnB1dENoYW5uZWxFeGl0SGFuZGxlcigpO1xuICAgIGF3YWl0IGNoYW5uZWw/LmRpc3Bvc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVucyB0aGUgdHJ1c3RlZC1pbnB1dCBjaGFubmVsIGlmIGl0IGlzIG5vdCBhbHJlYWR5IG9wZW4sIGFuZCByZS1vcGVucyBpdCBpZiB0aGUgV2ViVmlldyB3ZW50IGF3YXkuXG4gICAqXG4gICAqIEluc3RhbGxzIGEgYFJ1bnRpbWUuYWRkQmluZGluZ2AgZnVuY3Rpb24gb24gdGhlIHBhZ2UgYW5kIHNlcnZpY2VzIGV2ZXJ5IGNhbGwgdG8gaXQgZm9yIHRoZSBsaWZlIG9mIHRoZVxuICAgKiBjb25uZWN0aW9uLiBUaGUgYmluZGluZyBpcyBleHBvc2VkIG9uICpldmVyeSogZXhlY3V0aW9uIGNvbnRleHQgb2YgdGhlIHBhZ2UsIHNvIGl0IHN1cnZpdmVzIHRoZVxuICAgKiBgbG9jYXRpb24ucmVsb2FkKClgIHRoYXQge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5yZWdpc3RlclZhdWx0fSBwZXJmb3Jtczsgb25seSBhIGZ1bGwgYXBwIHJlc3RhcnQsIHdoaWNoXG4gICAqIGRlc3Ryb3lzIHRoZSBXZWJWaWV3IHRhcmdldCwgbmVlZHMgdGhlIHJlY29ubmVjdCBiZWxvdy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlSW5wdXRDaGFubmVsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlucHV0Q2hhbm5lbD8uaXNPcGVuIHx8IHRoaXMuaXNJbnB1dENoYW5uZWxVbmF2YWlsYWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRoZSBjaGFubmVsIGlzIHJlYWNoYWJsZSBvbmx5IG92ZXIgbG9jYWwgYGFkYmAsIHNvIGl0IGRvZXMgbm90IGV4aXN0IG9uIGlPUyBvciBhZ2FpbnN0IGEgcmVtb3RlIGh1YlxuICAgIC8vIChCcm93c2VyU3RhY2spLiBUaG9zZSBhcmUgc3VwcG9ydGVkIHRyYW5zcG9ydHMsIHNvIHRoaXMgc3RheXMgKipiZXN0LWVmZm9ydCoqOiBhIHJ1biB0aGF0IG5ldmVyXG4gICAgLy8gRHJpdmVzIGlucHV0IG11c3Qgbm90IGZhaWwgYmVjYXVzZSB0aGUgY2hhbm5lbCBjb3VsZCBub3QgYmUgb3BlbmVkLiBBIHJ1biB0aGF0ICpkb2VzKiBkcml2ZSBpbnB1dFxuICAgIC8vIEdldHMgYSBsZWdpYmxlIGVycm9yIGZyb20gdGhlIHJlbmRlcmVyJ3Mgb3duIGd1YXJkLCB3aGljaCBuYW1lcyB0aGUgbWlzc2luZyBjaGFubmVsLlxuICAgIGlmICh0aGlzLnBsYXRmb3JtICE9PSAnYW5kcm9pZCcpIHtcbiAgICAgIHRoaXMuaXNJbnB1dENoYW5uZWxVbmF2YWlsYWJsZSA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5kaXNwb3NlSW5wdXRDaGFubmVsKCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IGNvbm5lY3RUb1dlYlZpZXdDZHAoeyBhcHBJZDogdGhpcy5hcHBJZCwgZGV2aWNlSWQ6IHRoaXMuZGV2aWNlSWQgfSk7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnNlbmQoJ1J1bnRpbWUuZW5hYmxlJyk7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnNlbmQoJ1J1bnRpbWUuYWRkQmluZGluZycsIHsgbmFtZTogTU9CSUxFX0lOUFVUX0JJTkRJTkdfTkFNRSB9KTtcbiAgICAgIGNvbm5lY3Rpb24ub24oJ1J1bnRpbWUuYmluZGluZ0NhbGxlZCcsIChwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB7XG4gICAgICAgIGlmIChwYXJhbXNbJ25hbWUnXSAhPT0gTU9CSUxFX0lOUFVUX0JJTkRJTkdfTkFNRSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBwYXJhbXNbJ3BheWxvYWQnXTtcbiAgICAgICAgLy8gRGVsaWJlcmF0ZWx5IG5vdCBhd2FpdGVkOiB0aGlzIHJ1bnMgd2hpbGUgdGhlIHJlbmRlcmVyJ3MgYEV4ZWN1dGUgU2NyaXB0YCBpcyBzdGlsbCBwZW5kaW5nLCBhbmRcbiAgICAgICAgLy8gVGhhdCBpcyB0aGUgd2hvbGUgcG9pbnQgXHUyMDE0IHRoZSByZXF1ZXN0IGlzIHNlcnZpY2VkIGNvbmN1cnJlbnRseSBhbmQgYW5zd2VyZWQgYnkgcmVzb2x2aW5nIHRoZVxuICAgICAgICAvLyBSZW5kZXJlcidzIHByb21pc2Ugb3ZlciB0aGlzIHNhbWUgc29ja2V0LiBJdCBoYW5kbGVzIGl0cyBvd24gZmFpbHVyZXMsIHNvIG5vdGhpbmcgcmVhY2hlcyBoZXJlLlxuICAgICAgICB0aGlzLmhhbmRsZUlucHV0UmVxdWVzdChjb25uZWN0aW9uLCB0eXBlb2YgcGF5bG9hZCA9PT0gJ3N0cmluZycgPyBwYXlsb2FkIDogJycpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBVbnJlYWNoYWJsZTogYGhhbmRsZUlucHV0UmVxdWVzdGAgbmV2ZXIgcmVqZWN0cy5cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5pbnB1dENoYW5uZWwgPSBjb25uZWN0aW9uO1xuXG4gICAgICAvLyBTZWxmLWNsZWFuaW5nLCBkZWxpYmVyYXRlbHk6IHRoaXMgdHJhbnNwb3J0IGNhbiBiZSBjcmVhdGVkIHN0cmFpZ2h0IGZyb20gYSB0ZXN0IHdvcmtlciwgd2l0aCBub1xuICAgICAgLy8gYGNvcmVTZXR1cGAgb3duaW5nIGl0cyBsaWZlY3ljbGUgYW5kIHRoZXJlZm9yZSBub3RoaW5nIHRoYXQgZXZlciBjYWxscyBgZGlzcG9zZWAvYGRpc3Bvc2VTeW5jYCBcdTIwMTRcbiAgICAgIC8vIFdoaWNoIGlzIGhvdyBhIHJ1biBsZWF2ZXMgaXRzIGFkYiBwb3J0IGZvcndhcmQgc3RyYW5kZWQgb24gdGhlIGRldmljZSAob2JzZXJ2ZWQgMjAyNi0wOC0zMCkuIFRoZVxuICAgICAgLy8gSGFuZGxlciBpcyByZW1vdmVkIGFnYWluIG9uIGRpc3Bvc2FsIHNvIHJlY29ubmVjdHMgZG8gbm90IHN0YWNrIGxpc3RlbmVycy5cbiAgICAgIHRoaXMuZGlzcG9zZUlucHV0Q2hhbm5lbE9uRXhpdCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgY29ubmVjdGlvbi5kaXNwb3NlU3luYygpO1xuICAgICAgfTtcbiAgICAgIHByb2Nlc3Mub25jZSgnZXhpdCcsIHRoaXMuZGlzcG9zZUlucHV0Q2hhbm5lbE9uRXhpdCk7XG5cbiAgICAgIGxvZygnW2FwcGl1bS10cmFuc3BvcnRdIFRydXN0ZWQtaW5wdXQgY2hhbm5lbCBvcGVuLicpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvLyBHaXZlIHVwIGZvciB0aGUgbGlmZSBvZiB0aGUgdHJhbnNwb3J0IHJhdGhlciB0aGFuIHBheWluZyBhbiBgYWRiYCByb3VuZC10cmlwIG9uIGV2ZXJ5IGV2YWwuXG4gICAgICAvLyBBIHNvY2tldCB0aGF0IG1lcmVseSAqY2xvc2VkKiBhZnRlciBhIHN1Y2Nlc3NmdWwgY29ubmVjdCBpcyBhIGRpZmZlcmVudCBjYXNlIFx1MjAxNCBgaXNPcGVuYCBpcyBmYWxzZVxuICAgICAgLy8gVGhlcmUgd2hpbGUgdGhpcyBmbGFnIHN0YXlzIHVuc2V0LCBzbyB0aGUgcmVjb25uZWN0IGFib3ZlIHN0aWxsIHJ1bnMuXG4gICAgICB0aGlzLmlzSW5wdXRDaGFubmVsVW5hdmFpbGFibGUgPSB0cnVlO1xuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gVHJ1c3RlZCBpbnB1dCBpcyB1bmF2YWlsYWJsZSBvbiB0aGlzIGRldmljZTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3dpdGNoZXMgdGhlIGRyaXZlciB0byB0aGUgYFdFQlZJRVdfbWQub2JzaWRpYW5gIGNvbnRleHQuXG4gICAqXG4gICAqIElmIHRoZSBjb250ZXh0IHdhcyBhbHJlYWR5IHZlcmlmaWVkIChjYWNoZWQgdmlhIHtAbGluayBpc0luV2ViVmlld0NvbnRleHR9KSxcbiAgICogcmV0dXJucyBpbW1lZGlhdGVseSB3aXRob3V0IGNhbGxpbmcgYGdldENvbnRleHRzKClgIFx1MjAxNCB3aGljaCBydW5zXG4gICAqIGBhZGIgc2hlbGwgY2F0IC9wcm9jL25ldC91bml4YCBhbmQgY2FuIHRpbWUgb3V0IG9uIHNsb3cgZW11bGF0b3JzLlxuICAgKlxuICAgKiBQb2xscyB1bnRpbCB0aGUgY29udGV4dCBiZWNvbWVzIGF2YWlsYWJsZSAodGhlIGFwcCBtYXkgc3RpbGwgYmUgbG9hZGluZykuXG4gICAqIFVzZXMgdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0IHNwZWNpZmljYWxseSB0byBhdm9pZCBjb25uZWN0aW5nXG4gICAqIHRvIENocm9tZSBvciBvdGhlciBXZWJWaWV3cyBvbiB0aGUgZGV2aWNlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVXZWJWaWV3Q29udGV4dCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pc0luV2ViVmlld0NvbnRleHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyB0aGlzLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gV2FpdGluZyBmb3IgJHtXRUJWSUVXX0NPTlRFWFRfUFJFRklYfSBjb250ZXh0ICh0aW1lb3V0PSR7U3RyaW5nKHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMpLi4uYCk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBjb25zdCBjb250ZXh0cyA9IGF3YWl0IHRoaXMuYnJvd3Nlci5nZXRDb250ZXh0cygpO1xuICAgICAgY29uc3Qgb2JzaWRpYW5Db250ZXh0ID0gY29udGV4dHMuZmluZCgoY29udGV4dCk6IGNvbnRleHQgaXMgc3RyaW5nID0+IHR5cGVvZiBjb250ZXh0ID09PSAnc3RyaW5nJyAmJiBjb250ZXh0LnN0YXJ0c1dpdGgoV0VCVklFV19DT05URVhUX1BSRUZJWCkpO1xuXG4gICAgICBpZiAob2JzaWRpYW5Db250ZXh0KSB7XG4gICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIEZvdW5kIFdlYlZpZXcgY29udGV4dDogJHtvYnNpZGlhbkNvbnRleHR9YCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLnN3aXRjaENvbnRleHQob2JzaWRpYW5Db250ZXh0KTtcbiAgICAgICAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIHN3aXRjaENvbnRleHQgZmFpbGVkOiAke1N0cmluZyhlcnJvcil9LiBSZXNldHRpbmcgdG8gTkFUSVZFX0FQUCBiZWZvcmUgcmV0cnlpbmcuLi5gKTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5icm93c2VyLnN3aXRjaENvbnRleHQoJ05BVElWRV9BUFAnKTtcbiAgICAgICAgICB9IGNhdGNoIChyZXNldEVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBOQVRJVkVfQVBQIHJlc2V0IGFsc28gZmFpbGVkOiAke1N0cmluZyhyZXNldEVycm9yKX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gV2ViVmlldyBub3QgcmVhZHksIGF2YWlsYWJsZSBjb250ZXh0czogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0cyl9LiBSZXRyeWluZy4uLmApO1xuICAgICAgYXdhaXQgZGVsYXkoV0VCVklFV19QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBObyAke1dFQlZJRVdfQ09OVEVYVF9QUkVGSVh9IGNvbnRleHQgZm91bmQgd2l0aGluICR7U3RyaW5nKHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMuIElzIHRoZSBPYnNpZGlhbiBhcHAgZnVsbHkgbG9hZGVkP2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgb25lIEV4ZWN1dGUgU2NyaXB0IHVuZGVyIHRoZSBwZXItZXZhbCBjYXAsIHJhaXNpbmcge0BsaW5rIEV2YWxDYXBFeGNlZWRlZEVycm9yfSBpZiBpdCBvdXRsYXN0cyBpdC5cbiAgICpcbiAgICogVGhlIGNhcCBjb3ZlcnMgdGhlIHNjcmlwdCBBTE9ORSBcdTIwMTQgYGVuc3VyZVdlYlZpZXdDb250ZXh0YCBhbmQgYGVuc3VyZUlucHV0Q2hhbm5lbGAgcnVuIGJlZm9yZSBpdCxcbiAgICogYmVjYXVzZSBhIGBzd2l0Y2hDb250ZXh0YCBsZWdpdGltYXRlbHkgY29zdHMgfjE3cyAoKipMMTkqKikgYW5kIGNoYXJnaW5nIHRoYXQgdG8gYSB0ZXN0J3Mgb3duIGJ1ZGdldFxuICAgKiB3b3VsZCByZXBvcnQgdGhlIGhhcm5lc3MncyBzZXR1cCBhcyB0aGUgdGVzdCdzIG92ZXJydW4uXG4gICAqXG4gICAqIFRoZSBhYmFuZG9uZWQgcmVxdWVzdCBpcyBkZWxpYmVyYXRlbHkgbGVmdCBpbiBmbGlnaHQgcmF0aGVyIHRoYW4gY2FuY2VsbGVkLiBOb3RoaW5nIGNhbiBjYW5jZWwgaXQ6XG4gICAqIGBSdW50aW1lLnRlcm1pbmF0ZUV4ZWN1dGlvbmAgb3ZlciB0aGUgdHJhbnNwb3J0J3Mgb3duIENEUCBjaGFubmVsIHdhcyBtZWFzdXJlZCByZWxlYXNpbmcgbm90aGluZyxcbiAgICogYW5kIGEgZ3Vlc3Qtc2lkZSBhYm9ydCBob29rIGNvdWxkIG5vdCBldmVuIGJlIGluc3RhbGxlZCBpbiB0aW1lLiBXaGF0IHRoZSBzYW1lIHJ1bnMgZGlkIHNob3cgaXMgdGhhdFxuICAgKiB0aGUgc2Vzc2lvbiB1c3VhbGx5IGtlZXBzIHNlcnZpbmcgXHUyMDE0IGEgdmF1bHQgcmVhZC1iYWNrIHdhcyBhbnN3ZXJlZCA1MjhtcyBhZnRlciBvbmUgc3VjaCBhYmFuZG9ubWVudCxcbiAgICogd2l0aCB0aGUgc2Vzc2lvbiBmcmVlIFx1MjAxNCBzbyBib3VuZGluZyB0aGUgd2FpdCBjb3N0cyBhIHRlc3QgaXRzIGNsb3N1cmUsIG5vdCB0aGUgcmVzdCBvZiBpdHMgc3VpdGUuXG4gICAqXG4gICAqIEBwYXJhbSBzY3JpcHQgLSBUaGUgc2NyaXB0IHRvIHJ1biwgYWxyZWFkeSB3cmFwcGVkIGluIGl0cyBgcmV0dXJuICguLi4pYC5cbiAgICogQHJldHVybnMgVGhlIHNjcmlwdCdzIHJlc3VsdC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZXZhbHVhdGVXaXRoaW5DYXAoc2NyaXB0OiBzdHJpbmcpOiBQcm9taXNlPG51bGwgfCBzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICAvKlxuICAgICAqIFRoZSBldmFsIEFGVEVSIGFuIG92ZXJydW4gZ2V0cyBhIGdyYWNlIHBlcmlvZCBvbiB0b3Agb2YgdGhlIGNhcCwgYW5kIHRoaXMgaXMgbm90IGdlbmVyb3NpdHkuIEFwcGl1bVxuICAgICAqIFNlcmlhbGl6ZXMgY29tbWFuZHMgcGVyIHNlc3Npb24sIGFuZCBhbiBhYmFuZG9uZWQgY2xvc3VyZSBrZWVwcyBydW5uaW5nIGluIHRoZSBndWVzdCBcdTIwMTQgc28gdGhlIG5leHRcbiAgICAgKiBDb21tYW5kIHF1ZXVlcyBiZWhpbmQgd2hhdGV2ZXIgaXMgbGVmdCBvZiBpdCBhbmQsIG9uIHRoZSBiYXJlIGNhcCwgaXMgY2FwcGVkIGluIGl0cyB0dXJuLiBUaGF0IGlzXG4gICAgICogTWVhc3VyZWQ6IHdpdGggdGhlIGNhcCBmaXJpbmcgYXQgMzBzIGFnYWluc3QgYSA0MHMgY2xvc3VyZSwgdGhlIGZvbGxvd2luZyB2YXVsdCByZWFkLWJhY2sgZmFpbGVkIGF0XG4gICAgICogMzAgMjA2bXMsIHdoaWxlIHRoZSBzYW1lIHJlYWQtYmFjayBpc3N1ZWQgYWZ0ZXIgdGhlIGNsb3N1cmUgaGFkIGZpbmlzaGVkIHdhcyBhbnN3ZXJlZCBpbiA1Mjhtcy5cbiAgICAgKlxuICAgICAqIFdhaXRpbmcgb24gdGhlIGFiYW5kb25lZCByZXF1ZXN0IGluc3RlYWQgd291bGQgbm90IHdvcms6IHRoYXQgcHJvbWlzZSBpcyB0aGUgb25lIHRoYXQgbmV2ZXIgc2V0dGxlcy5cbiAgICAgKiBXaGF0IGZyZWVzIHRoZSBzZXNzaW9uIGlzIHRoZSBHVUVTVCBmaW5pc2hpbmcsIG9uIGEgc2NoZWR1bGUgdGhpcyBzaWRlIGNhbm5vdCBrbm93IFx1MjAxNCBzbyB0aGUgZ3JhY2UgaXNcbiAgICAgKiBhIGNlaWxpbmcsIG5vdCBhIGRlbGF5LiBJdCBjb3N0cyBub3RoaW5nIHdoZW4gdGhlIHNlc3Npb24gY29tZXMgYmFjayBwcm9tcHRseSwgd2hpY2ggaXMgdGhlIG5vcm0uXG4gICAgICovXG4gICAgY29uc3QgYnVkZ2V0SW5NaWxsaXNlY29uZHMgPSB0aGlzLmlzUmVjb3ZlcmluZ0Zyb21DYXBPdmVycnVuXG4gICAgICA/IHRoaXMuc2NyaXB0VGltZW91dEluTWlsbGlzZWNvbmRzICsgQ0FQX1JFQ09WRVJZX0dSQUNFX0lOX01JTExJU0VDT05EU1xuICAgICAgOiB0aGlzLnNjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICB0aGlzLmlzUmVjb3ZlcmluZ0Zyb21DYXBPdmVycnVuID0gZmFsc2U7XG5cbiAgICBsZXQgY2FwVGltZXI6IE5vZGVKUy5UaW1lb3V0IHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY2FwID0gbmV3IFByb21pc2U8bmV2ZXI+KChfcmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjYXBUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmlzUmVjb3ZlcmluZ0Zyb21DYXBPdmVycnVuID0gdHJ1ZTtcbiAgICAgICAgcmVqZWN0KFxuICAgICAgICAgIG5ldyBFdmFsQ2FwRXhjZWVkZWRFcnJvcih7XG4gICAgICAgICAgICBjYXBJbk1pbGxpc2Vjb25kczogYnVkZ2V0SW5NaWxsaXNlY29uZHMsXG4gICAgICAgICAgICBjYXVzZTogbmV3IEVycm9yKGBUaGUgQXBwaXVtIEV4ZWN1dGUgU2NyaXB0IGNhcnJ5aW5nIHRoaXMgY2xvc3VyZSBkaWQgbm90IGFuc3dlciB3aXRoaW4gJHtTdHJpbmcoYnVkZ2V0SW5NaWxsaXNlY29uZHMpfW1zLmApLFxuICAgICAgICAgICAgb3B0aW9uTmFtZTogJ3NjcmlwdFRpbWVvdXRJbk1pbGxpc2Vjb25kcycsXG4gICAgICAgICAgICB0cmFuc3BvcnROYW1lOiAnQW5kcm9pZCAoQXBwaXVtKSdcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSwgYnVkZ2V0SW5NaWxsaXNlY29uZHMpO1xuICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgICB0aGlzLmJyb3dzZXIuZXhlY3V0ZTxudWxsIHwgc3RyaW5nIHwgdW5kZWZpbmVkLCBbXT4oc2NyaXB0KSxcbiAgICAgICAgY2FwXG4gICAgICBdKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKGNhcFRpbWVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGNhcFRpbWVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBob3N0LXNpZGUgdmF1bHQgcGF0aCB0byB0aGUgZGV2aWNlLXNpZGUgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIEFic29sdXRlIHBhdGggb24gdGhlIGhvc3QgbWFjaGluZS5cbiAgICogQHJldHVybnMgVGhlIGRldmljZS1zaWRlIHZhdWx0IHBhdGguXG4gICAqL1xuICBwcml2YXRlIGdldERldmljZVZhdWx0UGF0aCh2YXVsdFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMudmF1bHRCYXNlUGF0aH0ke2V4dHJhY3RWYXVsdE5hbWUodmF1bHRQYXRoKX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlcnZpY2VzIG9uZSBpbnB1dCByZXF1ZXN0IGZyb20gdGhlIHJlbmRlcmVyOiBpbmplY3QsIHRoZW4gcmVzb2x2ZSB0aGUgcmVuZGVyZXIncyBwcm9taXNlLlxuICAgKlxuICAgKiBFdmVyeSBmYWlsdXJlIHBhdGggc3RpbGwgcmVzb2x2ZXMgdGhhdCBwcm9taXNlIFx1MjAxNCB3aXRoIGFuIGVycm9yIG1lc3NhZ2UgdGhlIHJlbmRlcmVyIHJlLXRocm93cyBcdTIwMTQgYmVjYXVzZVxuICAgKiBhIHJlcXVlc3QgdGhhdCBpcyBzaWxlbnRseSBkcm9wcGVkIHdvdWxkIGhhbmcgdGhlIGNsb3N1cmUgdW50aWwgdGhlIHdob2xlIHJ1biB0aW1lcyBvdXQsIGFuZCByZXBvcnRcbiAgICogbm90aGluZyBhYm91dCB3aHkuXG4gICAqXG4gICAqIEBwYXJhbSBjb25uZWN0aW9uIC0gVGhlIGNoYW5uZWwgdGhlIHJlcXVlc3QgYXJyaXZlZCBvbi5cbiAgICogQHBhcmFtIHBheWxvYWQgLSBUaGUgcmF3IEpTT04gcGF5bG9hZCB0aGUgYmluZGluZyB3YXMgY2FsbGVkIHdpdGguXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGhhbmRsZUlucHV0UmVxdWVzdChjb25uZWN0aW9uOiBXZWJWaWV3Q2RwQ29ubmVjdGlvbiwgcGF5bG9hZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IHJlcXVlc3RJZCA9ICcnO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGlkLCByZXF1ZXN0IH0gPSBKU09OLnBhcnNlKHBheWxvYWQpIGFzIE1vYmlsZUlucHV0RW52ZWxvcGU7XG4gICAgICByZXF1ZXN0SWQgPSBpZDtcblxuICAgICAgLy8gRXhhY3RseS1vbmNlIGFjcm9zcyBldmVyeSBhdHRhY2hlZCBob3N0LiBgUnVudGltZS5iaW5kaW5nQ2FsbGVkYCBpcyBicm9hZGNhc3QgdG8gQUxMIGF0dGFjaGVkXG4gICAgICAvLyBDRFAgc2Vzc2lvbnMsIHNvIHdpdGhvdXQgdGhpcyBlYWNoIHByb2Nlc3MgaW5qZWN0cyB0aGUgZ2VzdHVyZSBhZ2FpbjogbWVhc3VyZWQgMjAyNi0wOS0xMCwgYVxuICAgICAgLy8gVml0ZXN0IG1haW4gcHJvY2VzcyBhbmQgaXRzIHdvcmtlciBzZXJ2aWNlZCByZXF1ZXN0IGBpZD0xYCBpbiB0aGUgc2FtZSBtaWxsaXNlY29uZCwgYW5kIG9uZVxuICAgICAgLy8gYGNsaWNrRWxlbWVudGAgcmVhY2hlZCB0aGUgcGFnZSBhcyB0d28gYHBvaW50ZXJkb3duYCAvIGB0b3VjaHN0YXJ0YCBwYWlycy5cbiAgICAgIC8vXG4gICAgICAvLyBBIExPU0VSIE1VU1QgUkVUVVJOIFNJTEVOVExZOiB0aGUgd2lubmVyIGlzIHRoZSBvbmUgdGhhdCBpbmplY3RzIGFuZCB0aGUgb25lIHRoYXQgcmVzb2x2ZXMgdGhlXG4gICAgICAvLyBSZW5kZXJlcidzIHByb21pc2UsIHNvIGFuc3dlcmluZyBoZXJlIGFzIHdlbGwgd291bGQgcmVzb2x2ZSBhIHJlcXVlc3Qgd2hvc2UgZ2VzdHVyZSB0aGlzXG4gICAgICAvLyBQcm9jZXNzIG5ldmVyIHNlbnQuXG4gICAgICBjb25zdCBjbGFpbSA9IGF3YWl0IGNvbm5lY3Rpb24uc2VuZCgnUnVudGltZS5ldmFsdWF0ZScsIHsgZXhwcmVzc2lvbjogYnVpbGRDbGFpbUlucHV0RXhwcmVzc2lvbihpZCksIHJldHVybkJ5VmFsdWU6IHRydWUgfSk7XG4gICAgICBpZiAoIWNoZWNrSW5wdXRDbGFpbUdyYW50ZWQoY2xhaW0pKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZW5kQWxsKHRvQ2RwSW5wdXRDb21tYW5kcyhyZXF1ZXN0KSk7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnNlbmQoJ1J1bnRpbWUuZXZhbHVhdGUnLCB7IGV4cHJlc3Npb246IGJ1aWxkUmVzb2x2ZUlucHV0RXhwcmVzc2lvbihpZCkgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvclRvU3RyaW5nKGVycm9yKTtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFRydXN0ZWQgaW5wdXQgZmFpbGVkOiAke21lc3NhZ2V9YCk7XG4gICAgICBpZiAoIXJlcXVlc3RJZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24uc2VuZCgnUnVudGltZS5ldmFsdWF0ZScsIHsgZXhwcmVzc2lvbjogYnVpbGRSZXNvbHZlSW5wdXRFeHByZXNzaW9uKHJlcXVlc3RJZCwgbWVzc2FnZSkgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gVGhlIHNvY2tldCBpcyBnb25lOyB0aGUgcmVuZGVyZXIncyBvd24gdGltZW91dCBpcyB0aGUgcmVtYWluaW5nIGJhY2tzdG9wLlxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9iZXMgdGhlIFdlYlZpZXcgb25jZSBmb3IgaG93IGZhciBPYnNpZGlhbidzIHN0YXJ0dXAgaGFzIGdvdC5cbiAgICpcbiAgICogQSBwcm9iZSB0aGF0IHRocm93cyBpcyByZXBvcnRlZCBhcyBgdW5kZWZpbmVkYCByYXRoZXIgdGhhbiBwcm9wYWdhdGVkOiB0aGVcbiAgICogcGFnZSBpcyBtaWQtYGxvY2F0aW9uLnJlbG9hZCgpYCBmb3IgbW9zdCBvZiB0aGUgYXBwLXN0YXJ0IHBoYXNlLCBhbmQgYVxuICAgKiBXZWJWaWV3IHRoYXQgY2Fubm90IGFuc3dlciB5ZXQgaXMgdGhlICpleHBlY3RlZCogcmVhZGluZyB0aGVyZSwgbm90IGFuIGVycm9yLlxuICAgKlxuICAgKiBAcmV0dXJucyBXaGF0IHRoZSBwcm9iZSBzYXcsIG9yIGB1bmRlZmluZWRgIHdoZW4gaXQgY291bGQgbm90IHJ1bi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcHJvYmVTdGFydHVwKCk6IFByb21pc2U8U3RhcnR1cFByb2JlUmVzdWx0IHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZSgoKTogU3RhcnR1cFByb2JlUmVzdWx0ID0+IHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1kZXByZWNhdGVkIC0tIFdlIG5lZWQgZ2xvYmFsIGBhcHBgIHZhcmlhYmxlLlxuICAgICAgICBjb25zdCBhcHAgPSBnbG9iYWxUaGlzLmFwcCBhcyBMb2FkaW5nQXBwIHwgdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGhhc0FwcDogISFhcHAsXG4gICAgICAgICAgaGFzV29ya3NwYWNlOiAhIWFwcD8ud29ya3NwYWNlLFxuICAgICAgICAgIGlzTGF5b3V0UmVhZHk6ICEhYXBwPy53b3Jrc3BhY2U/LmxheW91dFJlYWR5XG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFB1c2hlcyB0aGUgbWluaW1hbCBgLm9ic2lkaWFuL2FwcC5qc29uYCB2YXVsdCBtYXJrZXIgdmlhIGBhZGIgcHVzaGAuXG4gICAqXG4gICAqIGBicm93c2VyLnB1c2hGaWxlYCAoV2ViRHJpdmVyIGJhc2U2NCkgaXMgYW4gb3JkZXIgb2YgbWFnbml0dWRlIHNsb3dlciBvbiBhXG4gICAqIGNvbGQgb3IgbG9hZGVkIGVtdWxhdG9yIFx1MjAxNCBtZWFzdXJlZCBhdCA5XHUyMDEzMjFzIHBlciBjYWxsIGZvciB0aGlzIDItYnl0ZSBtYXJrZXIsXG4gICAqIHZlcnN1cyBzdWItc2Vjb25kIG92ZXIgYGFkYmAuIFRoaXMgbWlycm9ycyB7QGxpbmsgcHVzaEZpbGVzfSwgd2hpY2ggc3dpdGNoZWRcbiAgICogdG8gYGFkYmAgZm9yIHRoZSBzYW1lIHJlYXNvbi4gYG1rZGlyIC1wYCBndWFyYW50ZWVzIHRoZSBwYXJlbnQgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlVmF1bHRQYXRoIC0gVGhlIGRldmljZS1zaWRlIHZhdWx0IGRpcmVjdG9yeSBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwdXNoT2JzaWRpYW5NYXJrZXIoZGV2aWNlVmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2NhbE1hcmtlciA9IGpvaW4odG1wZGlyKCksIGBvYnNpZGlhbi1tYXJrZXItJHtyYW5kb21VVUlEKCl9Lmpzb25gKTtcbiAgICBjb25zdCByZW1vdGVNYXJrZXIgPSBgJHtkZXZpY2VWYXVsdFBhdGh9Ly5vYnNpZGlhbi9hcHAuanNvbmA7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgd3JpdGVGaWxlKGxvY2FsTWFya2VyLCAne30nLCAndXRmLTgnKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbWtkaXInLCAnLXAnLCBgJHtkZXZpY2VWYXVsdFBhdGh9Ly5vYnNpZGlhbmBdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3B1c2gnLCBsb2NhbE1hcmtlciwgcmVtb3RlTWFya2VyXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBybShsb2NhbE1hcmtlciwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIHZhdWx0IGRpcmVjdG9yeSBmcm9tIHRoZSBkZXZpY2Ugb3ZlciBgYWRiYCwgYW5kIENIRUNLUyB0aGF0IGl0IGlzXG4gICAqIGFjdHVhbGx5IGdvbmUuXG4gICAqXG4gICAqIEJlc3QtZWZmb3J0OiBhIGZhaWx1cmUgaXMgbG9nZ2VkLCBub3QgdGhyb3duLCBzbyBhIHRlYXJkb3duIHByb2JsZW0gbmV2ZXJcbiAgICogbWFza3MgdGhlIHRlc3QgcmVzdWx0LiBUaGUgbmV4dCBydW4ncyBzdGFydC1vZi1ydW4gc3dlZXAgcGlja3MgdXAgd2hhdGV2ZXJcbiAgICogdGhpcyBjb3VsZCBub3QgcmVtb3ZlLlxuICAgKlxuICAgKiBUaGUgY2hlY2sgaXMgdGhlIHBvaW50LiBgcm0gLXJmYCBydW5zIHdpdGggYHNob3VsZElnbm9yZUV4aXRDb2RlYCwgc28gYW5cbiAgICogdW5yZW1vdmVkIGRpcmVjdG9yeSB1c2VkIHRvIGxlYXZlIG5vIHRyYWNlIGF0IGFsbCBcdTIwMTQgd2hpY2ggaXMgaG93IHJ1bnMgdGhhdFxuICAgKiBwYXNzZWQgZW5kIHRvIGVuZCB3ZXJlIHN0aWxsIGZvdW5kIHRvIGJlIGxlYWtpbmcgYSB2YXVsdCBhcGllY2UsIGludmlzaWJseSxcbiAgICogdW50aWwgc29tZW9uZSBjb3VudGVkIHRoZSBkaXJlY3RvcmllcyBvbiB0aGUgZGV2aWNlIGJ5IGhhbmQuIEEgbGVhayBpcyBub3dcbiAgICogbmFtZWQgaW4gdGhlIGxvZyBhdCB0aGUgbW9tZW50IGl0IGhhcHBlbnMuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VWYXVsdFBhdGggLSBUaGUgZGV2aWNlLXNpZGUgdmF1bHQgZGlyZWN0b3J5IHBhdGguXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlbW92ZURldmljZVZhdWx0RGlyZWN0b3J5KGRldmljZVZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFJlbW92aW5nIHZhdWx0IGRpcmVjdG9yeSBmcm9tIGRldmljZTogJHtkZXZpY2VWYXVsdFBhdGh9YCk7XG4gICAgICBhd2FpdCBleGVjKFxuICAgICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdybScsICctcmYnLCBkZXZpY2VWYXVsdFBhdGhdLFxuICAgICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9WQVVMVF9SRU1PVkVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfVxuICAgICAgKTtcblxuICAgICAgY29uc3QgbGlzdGluZyA9IGF3YWl0IGV4ZWMoXG4gICAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ2xzJywgJy1kJywgZGV2aWNlVmF1bHRQYXRoXSxcbiAgICAgICAgeyBpc1F1aWV0OiB0cnVlLCBzaG91bGRJZ25vcmVFeGl0Q29kZTogdHJ1ZSwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICAgICk7XG5cbiAgICAgIGlmIChsaXN0aW5nLmluY2x1ZGVzKGRldmljZVZhdWx0UGF0aCkpIHtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIGBbYXBwaXVtLXRyYW5zcG9ydF0gV2FybmluZzogJHtkZXZpY2VWYXVsdFBhdGh9IHN1cnZpdmVkIHJlbW92YWwgYW5kIGlzIG5vdyBsZWFrZWQgcmVzaWR1ZS4gYFxuICAgICAgICAgICAgKyAnVGhlIG5leHQgcnVuXFwncyBzdGFydC1vZi1ydW4gc3dlZXAgd2lsbCByZXRyeSBpdC4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFZhdWx0IGRpcmVjdG9yeSByZW1vdmFsIGZhaWxlZCAobm9uLWZhdGFsKTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEcm9wcyB0aGUgYHByb2Nlc3Mub24oJ2V4aXQnKWAgaGFuZGxlciB0aGF0IHdvdWxkIG90aGVyd2lzZSBjbG9zZSBhbiBhbHJlYWR5LWNsb3NlZCBjaGFubmVsLCBhbmQgd291bGRcbiAgICogc3RhY2sgYSBsaXN0ZW5lciBwZXIgcmVjb25uZWN0LlxuICAgKi9cbiAgcHJpdmF0ZSB1bnJlZ2lzdGVySW5wdXRDaGFubmVsRXhpdEhhbmRsZXIoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWxPbkV4aXQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwcm9jZXNzLm9mZignZXhpdCcsIHRoaXMuZGlzcG9zZUlucHV0Q2hhbm5lbE9uRXhpdCk7XG4gICAgdGhpcy5kaXNwb3NlSW5wdXRDaGFubmVsT25FeGl0ID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB1bnRpbCBgZ2xvYmFsVGhpcy5hcHBgIGV4aXN0cyBpbiB0aGUgV2ViVmlldyBcdTIwMTQgdGhlIGFwcCBoYXMgZmluaXNoZWRcbiAgICogaXRzIGNvbGQgc3RhcnQgYW5kIE9ic2lkaWFuJ3Mgb3duIGJvb3QgaGFzIGJlZ3VuLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSAqKmZpcnN0Kiogb2YgdGhlIHR3byBidWRnZXRzIHNwZW50IGFmdGVyIGBsb2NhdGlvbi5yZWxvYWQoKWAsXG4gICAqIGFuZCB0aGUgZ2VuZXJvdXMgb25lLiBFdmVyeXRoaW5nIGl0IHBheXMgZm9yIGlzIG91dHNpZGUgT2JzaWRpYW4ncyBjb250cm9sOlxuICAgKiB0aGUgV2ViVmlldyByZWxvYWRpbmcsIGFuZCBhIGd1ZXN0IHRoYXQgbWF5IHN0aWxsIGJlIG9wdGltaXppbmcgcGFja2FnZXMuXG4gICAqIEtlZXBpbmcgaXQgc2VwYXJhdGUgaXMgdGhlIHBvaW50IG9mIHRoZSBzcGxpdCBcdTIwMTQgdGhlIG9sZCBzaW5nbGUgd2FsbCBjbG9ja1xuICAgKiBzdGFydGVkIGhlcmUgYW5kIGxlZnQgdGhlIHRpZ2h0IGxheW91dCBidWRnZXQgcGF5aW5nIGZvciBhIGNvbGQgc3RhcnQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JBcHBTdGFydGVkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdhaXRpbmcgZm9yIHRoZSBhcHAgdG8gc3RhcnQgKHRpbWVvdXQ9JHtTdHJpbmcodGhpcy5hcHBTdGFydFRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMpLi4uYCk7XG4gICAgYXdhaXQgdGhpcy53YWl0Rm9yU3RhcnR1cE1pbGVzdG9uZSh7XG4gICAgICBpc1NhdGlzZmllZDogY2hlY2tBcHBTdGFydGVkLFxuICAgICAgcGhhc2U6ICdhcHAtc3RhcnQnLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiB0aGlzLmFwcFN0YXJ0VGltZW91dEluTWlsbGlzZWNvbmRzXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgdW50aWwgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgIGlzIGB0cnVlYCBpbiB0aGUgV2ViVmlldy5cbiAgICpcbiAgICogVGhlICoqc2Vjb25kKiogYnVkZ2V0LCBhbmQgdGhlIHRpZ2h0IG9uZTogYnkgdGhlIHRpbWUgaXQgc3RhcnRzLCB0aGUgYXBwIGlzXG4gICAqIGFscmVhZHkgdXAsIHNvIGFsbCBpdCBjb3ZlcnMgaXMgT2JzaWRpYW4gb3BlbmluZyB0aGUgdmF1bHQgYW5kIGxvYWRpbmdcbiAgICogcGx1Z2lucyBcdTIwMTQgfjFzIGluIHByYWN0aWNlLCBcdTIyNjQ4LjRzIHVuZGVyIGhlYXZ5IGhvc3Qgc3RyZXNzICgqKkwxOSoqKS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvckxheW91dFJlYWR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdhaXRpbmcgZm9yIGxheW91dCByZWFkeSAodGltZW91dD0ke1N0cmluZyh0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcykuLi5gKTtcbiAgICBhd2FpdCB0aGlzLndhaXRGb3JTdGFydHVwTWlsZXN0b25lKHtcbiAgICAgIGlzU2F0aXNmaWVkOiBjaGVja0xheW91dFJlYWR5LFxuICAgICAgcGhhc2U6ICdsYXlvdXQtcmVhZHknLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiB0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgdGhlIFdlYlZpZXcgdW50aWwgYSBzdGFydHVwIHBoYXNlJ3MgbWlsZXN0b25lIGlzIHNhdGlzZmllZCwgdHJhY2tpbmdcbiAgICogdGhlIGV2aWRlbmNlIHRoYXQgdGVsbHMgYSBzbG93IE9ic2lkaWFuIGZyb20gYSBjb250ZW5kZWQgZ3Vlc3QuXG4gICAqXG4gICAqIEVhY2ggcG9sbCBjb3N0cyBleGFjdGx5IG9uZSBgYnJvd3Nlci5leGVjdXRlYCByb3VuZC10cmlwIFx1MjAxNCBkZWxpYmVyYXRlbHkgbm90XG4gICAqIGFuIHtAbGluayBlbnN1cmVXZWJWaWV3Q29udGV4dH0gY2FsbCwgd2hvc2UgYGdldENvbnRleHRzKClgIHJ1bnNcbiAgICogYGFkYiBzaGVsbCBjYXQgL3Byb2MvbmV0L3VuaXhgIGFuZCB3YXMgbWVhc3VyZWQgYXQgfjE3cyBwZXIgKipMMTkqKi4gVGhlXG4gICAqIHJvdW5kLXRyaXAgaXMgdGltZWQsIGFuZCB0aGUgc2xvd2VzdCBvbmUgaXMgcmVwb3J0ZWQgb24gdGltZW91dDogYSBwaGFzZVxuICAgKiB0aGF0IHJhbiBvdXQgYWZ0ZXIgYSBoYW5kZnVsIG9mIHByb2JlcyBlYWNoIHRha2luZyB0ZW5zIG9mIHNlY29uZHMgd2FzXG4gICAqIHN0YXJ2ZWQgYnkgdGhlIGd1ZXN0LCBub3QgYnkgT2JzaWRpYW4uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGhhc2UsIGl0cyBidWRnZXQsIGFuZCB0aGUgcHJlZGljYXRlIHRoYXQgZW5kcyBpdC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvclN0YXJ0dXBNaWxlc3RvbmUocGFyYW1zOiBXYWl0Rm9yU3RhcnR1cE1pbGVzdG9uZVBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgaXNTYXRpc2ZpZWQsIHBoYXNlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHMgfSA9IHBhcmFtcztcbiAgICBjb25zdCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBzdGFydCArIHRpbWVvdXRJbk1pbGxpc2Vjb25kcztcblxuICAgIGxldCBmdXJ0aGVzdE1pbGVzdG9uZTogQXBwU3RhcnR1cE1pbGVzdG9uZSA9ICduby13ZWJ2aWV3JztcbiAgICBsZXQgcG9sbENvdW50ID0gMDtcbiAgICBsZXQgc2xvd2VzdFJvdW5kVHJpcEluTWlsbGlzZWNvbmRzID0gMDtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IHJvdW5kVHJpcFN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IG1pbGVzdG9uZSA9IGNsYXNzaWZ5QXBwU3RhcnR1cFByb2JlKGF3YWl0IHRoaXMucHJvYmVTdGFydHVwKCkpO1xuICAgICAgY29uc3Qgcm91bmRUcmlwSW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpIC0gcm91bmRUcmlwU3RhcnQ7XG5cbiAgICAgIHBvbGxDb3VudCsrO1xuICAgICAgc2xvd2VzdFJvdW5kVHJpcEluTWlsbGlzZWNvbmRzID0gTWF0aC5tYXgoc2xvd2VzdFJvdW5kVHJpcEluTWlsbGlzZWNvbmRzLCByb3VuZFRyaXBJbk1pbGxpc2Vjb25kcyk7XG4gICAgICBpZiAoY29tcGFyZUFwcFN0YXJ0dXBNaWxlc3RvbmVzKG1pbGVzdG9uZSwgZnVydGhlc3RNaWxlc3RvbmUpID4gMCkge1xuICAgICAgICBmdXJ0aGVzdE1pbGVzdG9uZSA9IG1pbGVzdG9uZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU2F0aXNmaWVkKG1pbGVzdG9uZSkpIHtcbiAgICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gUGhhc2UgXCIke3BoYXNlfVwiIHNhdGlzZmllZCBhZnRlciAke1N0cmluZyhEYXRlLm5vdygpIC0gc3RhcnQpfW1zICgke1N0cmluZyhwb2xsQ291bnQpfSBwcm9iZShzKSkuYCk7XG4gICAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsb2coXG4gICAgICAgIGBbYXBwaXVtLXRyYW5zcG9ydF0gUGhhc2UgXCIke3BoYXNlfVwiIG5vdCBzYXRpc2ZpZWQgeWV0OiAke21pbGVzdG9uZX0gYFxuICAgICAgICAgICsgYChlbGFwc2VkPSR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMsIHJvdW5kLXRyaXA9JHtTdHJpbmcocm91bmRUcmlwSW5NaWxsaXNlY29uZHMpfW1zKS4gUmV0cnlpbmcuLi5gXG4gICAgICApO1xuICAgICAgYXdhaXQgZGVsYXkoTEFZT1VUX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYnVpbGRTdGFydHVwVGltZW91dE1lc3NhZ2Uoe1xuICAgICAgZWxhcHNlZEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpIC0gc3RhcnQsXG4gICAgICBtaWxlc3RvbmU6IGZ1cnRoZXN0TWlsZXN0b25lLFxuICAgICAgcGhhc2UsXG4gICAgICBwb2xsQ291bnQsXG4gICAgICBzbG93ZXN0Um91bmRUcmlwSW5NaWxsaXNlY29uZHMsXG4gICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgICB9KSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBnaXZlbiBkZWxheS5cbiAqXG4gKiBAcGFyYW0gbXMgLSBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGRlbGF5LlxuICovXG5mdW5jdGlvbiBkZWxheShtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0cyB0aGUgdmF1bHQgZGlyZWN0b3J5IG5hbWUgZnJvbSBhIGhvc3Qtc2lkZSB2YXVsdCBwYXRoLlxuICpcbiAqIEBwYXJhbSB2YXVsdFBhdGggLSBBYnNvbHV0ZSBwYXRoIG9uIHRoZSBob3N0IG1hY2hpbmUuXG4gKiBAcmV0dXJucyBUaGUgbGFzdCBwYXRoIHNlZ21lbnQgKHZhdWx0IGRpcmVjdG9yeSBuYW1lKS5cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdFZhdWx0TmFtZSh2YXVsdFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSB2YXVsdFBhdGgucmVwbGFjZSgvW1xcXFwvXSskLywgJycpO1xuICBjb25zdCBsYXN0U2VwYXJhdG9yID0gTWF0aC5tYXgobm9ybWFsaXplZC5sYXN0SW5kZXhPZignLycpLCBub3JtYWxpemVkLmxhc3RJbmRleE9mKCdcXFxcJykpO1xuICByZXR1cm4gbm9ybWFsaXplZC5zbGljZShs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
@@ -103,6 +103,16 @@ export interface AppiumTransportConfig {
103
103
  * Target platform. Determines WebView context naming and device file paths.
104
104
  */
105
105
  platform: 'android' | 'ios';
106
+ /**
107
+ * The per-script cap, in milliseconds, this session was given as its W3C
108
+ * `timeouts.script` capability.
109
+ *
110
+ * Carried only so a script timeout can be reported with the number that
111
+ * produced it; the capability itself is set when the session is created.
112
+ *
113
+ * @default `30000`
114
+ */
115
+ scriptTimeoutInMilliseconds?: number;
106
116
  /**
107
117
  * Whether registering a vault also prunes the **other** `temp-vault-*`
108
118
  * registrations earlier runs left in Obsidian Mobile's `localStorage`.
@@ -179,9 +189,17 @@ export declare class AppiumTransport implements ObsidianTransport {
179
189
  * can time out on slow emulators).
180
190
  */
181
191
  private isInWebViewContext;
192
+ /**
193
+ * Whether the previous eval ended in a cap overrun, so the next one is owed the recovery grace.
194
+ *
195
+ * The abandoned closure is still running in the guest, and Appium serializes commands per session, so
196
+ * the next command queues behind whatever is left of it. See {@link AppiumTransport.evaluateWithinCap}.
197
+ */
198
+ private isRecoveringFromCapOverrun;
182
199
  private readonly isSessionOwner;
183
200
  private readonly layoutReadyTimeoutInMilliseconds;
184
201
  private readonly platform;
202
+ private readonly scriptTimeoutInMilliseconds;
185
203
  private readonly shouldSweepLeftovers;
186
204
  private readonly vaultBasePath;
187
205
  private readonly webviewTimeoutInMilliseconds;
@@ -345,6 +363,23 @@ export declare class AppiumTransport implements ObsidianTransport {
345
363
  * to Chrome or other WebViews on the device.
346
364
  */
347
365
  private ensureWebViewContext;
366
+ /**
367
+ * Runs one Execute Script under the per-eval cap, raising {@link EvalCapExceededError} if it outlasts it.
368
+ *
369
+ * The cap covers the script ALONE — `ensureWebViewContext` and `ensureInputChannel` run before it,
370
+ * because a `switchContext` legitimately costs ~17s (**L19**) and charging that to a test's own budget
371
+ * would report the harness's setup as the test's overrun.
372
+ *
373
+ * The abandoned request is deliberately left in flight rather than cancelled. Nothing can cancel it:
374
+ * `Runtime.terminateExecution` over the transport's own CDP channel was measured releasing nothing,
375
+ * and a guest-side abort hook could not even be installed in time. What the same runs did show is that
376
+ * the session usually keeps serving — a vault read-back was answered 528ms after one such abandonment,
377
+ * with the session free — so bounding the wait costs a test its closure, not the rest of its suite.
378
+ *
379
+ * @param script - The script to run, already wrapped in its `return (...)`.
380
+ * @returns The script's result.
381
+ */
382
+ private evaluateWithinCap;
348
383
  /**
349
384
  * Converts a host-side vault path to the device-side path.
350
385
  *