appium 2.0.0-beta.3 → 2.0.0-beta.30

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 (139) hide show
  1. package/README.md +10 -11
  2. package/build/lib/appium.d.ts +215 -0
  3. package/build/lib/appium.d.ts.map +1 -0
  4. package/build/lib/appium.js +238 -132
  5. package/build/lib/cli/args.d.ts +20 -0
  6. package/build/lib/cli/args.d.ts.map +1 -0
  7. package/build/lib/cli/args.js +96 -282
  8. package/build/lib/cli/driver-command.d.ts +36 -0
  9. package/build/lib/cli/driver-command.d.ts.map +1 -0
  10. package/build/lib/cli/driver-command.js +19 -12
  11. package/build/lib/cli/extension-command.d.ts +345 -0
  12. package/build/lib/cli/extension-command.d.ts.map +1 -0
  13. package/build/lib/cli/extension-command.js +171 -96
  14. package/build/lib/cli/extension.d.ts +14 -0
  15. package/build/lib/cli/extension.d.ts.map +1 -0
  16. package/build/lib/cli/extension.js +31 -16
  17. package/build/lib/cli/parser.d.ts +79 -0
  18. package/build/lib/cli/parser.d.ts.map +1 -0
  19. package/build/lib/cli/parser.js +152 -95
  20. package/build/lib/cli/plugin-command.d.ts +39 -0
  21. package/build/lib/cli/plugin-command.d.ts.map +1 -0
  22. package/build/lib/cli/plugin-command.js +18 -13
  23. package/build/lib/cli/utils.d.ts +29 -0
  24. package/build/lib/cli/utils.d.ts.map +1 -0
  25. package/build/lib/cli/utils.js +27 -3
  26. package/build/lib/config-file.d.ts +100 -0
  27. package/build/lib/config-file.d.ts.map +1 -0
  28. package/build/lib/config-file.js +136 -0
  29. package/build/lib/config.d.ts +40 -0
  30. package/build/lib/config.d.ts.map +1 -0
  31. package/build/lib/config.js +92 -67
  32. package/build/lib/constants.d.ts +48 -0
  33. package/build/lib/constants.d.ts.map +1 -0
  34. package/build/lib/constants.js +60 -0
  35. package/build/lib/extension/driver-config.d.ts +84 -0
  36. package/build/lib/extension/driver-config.d.ts.map +1 -0
  37. package/build/lib/extension/driver-config.js +190 -0
  38. package/build/lib/extension/extension-config.d.ts +170 -0
  39. package/build/lib/extension/extension-config.d.ts.map +1 -0
  40. package/build/lib/extension/extension-config.js +297 -0
  41. package/build/lib/extension/index.d.ts +39 -0
  42. package/build/lib/extension/index.d.ts.map +1 -0
  43. package/build/lib/extension/index.js +77 -0
  44. package/build/lib/extension/manifest.d.ts +174 -0
  45. package/build/lib/extension/manifest.d.ts.map +1 -0
  46. package/build/lib/extension/manifest.js +246 -0
  47. package/build/lib/extension/package-changed.d.ts +11 -0
  48. package/build/lib/extension/package-changed.d.ts.map +1 -0
  49. package/build/lib/extension/package-changed.js +68 -0
  50. package/build/lib/extension/plugin-config.d.ts +62 -0
  51. package/build/lib/extension/plugin-config.d.ts.map +1 -0
  52. package/build/lib/extension/plugin-config.js +87 -0
  53. package/build/lib/grid-register.d.ts +10 -0
  54. package/build/lib/grid-register.d.ts.map +1 -0
  55. package/build/lib/grid-register.js +21 -25
  56. package/build/lib/logger.d.ts +3 -0
  57. package/build/lib/logger.d.ts.map +1 -0
  58. package/build/lib/logger.js +4 -6
  59. package/build/lib/logsink.d.ts +4 -0
  60. package/build/lib/logsink.d.ts.map +1 -0
  61. package/build/lib/logsink.js +12 -16
  62. package/build/lib/main.d.ts +51 -0
  63. package/build/lib/main.d.ts.map +1 -0
  64. package/build/lib/main.js +174 -82
  65. package/build/lib/schema/arg-spec.d.ts +143 -0
  66. package/build/lib/schema/arg-spec.d.ts.map +1 -0
  67. package/build/lib/schema/arg-spec.js +119 -0
  68. package/build/lib/schema/cli-args.d.ts +19 -0
  69. package/build/lib/schema/cli-args.d.ts.map +1 -0
  70. package/build/lib/schema/cli-args.js +180 -0
  71. package/build/lib/schema/cli-transformers.d.ts +5 -0
  72. package/build/lib/schema/cli-transformers.d.ts.map +1 -0
  73. package/build/lib/schema/cli-transformers.js +74 -0
  74. package/build/lib/schema/index.d.ts +3 -0
  75. package/build/lib/schema/index.d.ts.map +1 -0
  76. package/build/lib/schema/index.js +34 -0
  77. package/build/lib/schema/keywords.d.ts +24 -0
  78. package/build/lib/schema/keywords.d.ts.map +1 -0
  79. package/build/lib/schema/keywords.js +70 -0
  80. package/build/lib/schema/schema.d.ts +259 -0
  81. package/build/lib/schema/schema.d.ts.map +1 -0
  82. package/build/lib/schema/schema.js +452 -0
  83. package/build/lib/utils.d.ts +66 -0
  84. package/build/lib/utils.d.ts.map +1 -0
  85. package/build/lib/utils.js +35 -139
  86. package/build/tsconfig.tsbuildinfo +1 -0
  87. package/index.js +11 -0
  88. package/lib/appium-config.schema.json +278 -0
  89. package/lib/appium.js +398 -155
  90. package/lib/cli/args.js +174 -377
  91. package/lib/cli/driver-command.js +22 -7
  92. package/lib/cli/extension-command.js +372 -177
  93. package/lib/cli/extension.js +32 -10
  94. package/lib/cli/parser.js +252 -83
  95. package/lib/cli/plugin-command.js +19 -6
  96. package/lib/cli/utils.js +22 -2
  97. package/lib/config-file.js +223 -0
  98. package/lib/config.js +169 -69
  99. package/lib/constants.js +78 -0
  100. package/lib/extension/driver-config.js +249 -0
  101. package/lib/extension/extension-config.js +458 -0
  102. package/lib/extension/index.js +102 -0
  103. package/lib/extension/manifest.js +486 -0
  104. package/lib/extension/package-changed.js +63 -0
  105. package/lib/extension/plugin-config.js +113 -0
  106. package/lib/grid-register.js +25 -22
  107. package/lib/logger.js +1 -1
  108. package/lib/logsink.js +14 -7
  109. package/lib/main.js +233 -83
  110. package/lib/schema/arg-spec.js +232 -0
  111. package/lib/schema/cli-args.js +261 -0
  112. package/lib/schema/cli-transformers.js +122 -0
  113. package/lib/schema/index.js +2 -0
  114. package/lib/schema/keywords.js +134 -0
  115. package/lib/schema/schema.js +734 -0
  116. package/lib/utils.js +85 -129
  117. package/package.json +62 -85
  118. package/scripts/postinstall.js +71 -0
  119. package/types/appium-manifest.d.ts +61 -0
  120. package/types/cli.d.ts +134 -0
  121. package/types/extension.d.ts +56 -0
  122. package/types/external-manifest.d.ts +58 -0
  123. package/types/index.d.ts +7 -0
  124. package/CHANGELOG.md +0 -3515
  125. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  126. package/build/lib/cli/npm.js +0 -206
  127. package/build/lib/cli/parser-helpers.js +0 -82
  128. package/build/lib/driver-config.js +0 -77
  129. package/build/lib/drivers.js +0 -96
  130. package/build/lib/extension-config.js +0 -251
  131. package/build/lib/plugin-config.js +0 -59
  132. package/build/lib/plugins.js +0 -14
  133. package/lib/cli/npm.js +0 -183
  134. package/lib/cli/parser-helpers.js +0 -79
  135. package/lib/driver-config.js +0 -46
  136. package/lib/drivers.js +0 -81
  137. package/lib/extension-config.js +0 -208
  138. package/lib/plugin-config.js +0 -34
  139. package/lib/plugins.js +0 -10
@@ -5,29 +5,25 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.AppiumDriver = void 0;
8
+ exports.NoDriverProxyCommandError = exports.AppiumDriver = void 0;
9
9
 
10
10
  require("source-map-support/register");
11
11
 
12
12
  var _lodash = _interopRequireDefault(require("lodash"));
13
13
 
14
- var _logger = _interopRequireDefault(require("./logger"));
15
-
16
14
  var _config = require("./config");
17
15
 
18
- var _drivers = require("./drivers");
19
-
20
- var _appiumBaseDriver = require("appium-base-driver");
21
-
22
- var _bluebird = _interopRequireDefault(require("bluebird"));
16
+ var _baseDriver = require("@appium/base-driver");
23
17
 
24
18
  var _asyncLock = _interopRequireDefault(require("async-lock"));
25
19
 
26
20
  var _utils = require("./utils");
27
21
 
28
- var _appiumSupport = require("appium-support");
22
+ var _support = require("@appium/support");
29
23
 
30
- const desiredCapabilityConstraints = {
24
+ var _schema = require("./schema");
25
+
26
+ const desiredCapabilityConstraints = Object.freeze({
31
27
  automationName: {
32
28
  presence: true,
33
29
  isString: true
@@ -36,24 +32,41 @@ const desiredCapabilityConstraints = {
36
32
  presence: true,
37
33
  isString: true
38
34
  }
39
- };
35
+ });
40
36
  const sessionsListGuard = new _asyncLock.default();
41
37
  const pendingDriversGuard = new _asyncLock.default();
42
38
 
43
- class AppiumDriver extends _appiumBaseDriver.BaseDriver {
44
- constructor(args) {
45
- if (args.tmpDir) {
46
- process.env.APPIUM_TMP_DIR = args.tmpDir;
39
+ class AppiumDriver extends _baseDriver.DriverCore {
40
+ sessions = {};
41
+ pendingDrivers = {};
42
+ newCommandTimeoutMs = 0;
43
+ pluginClasses = [];
44
+ sessionPlugins = {};
45
+ sessionlessPlugins = [];
46
+ driverConfig;
47
+ server;
48
+
49
+ constructor(opts) {
50
+ if (opts.tmpDir) {
51
+ process.env.APPIUM_TMP_DIR = opts.tmpDir;
47
52
  }
48
53
 
49
- super(args);
54
+ super(opts);
50
55
  this.desiredCapConstraints = desiredCapabilityConstraints;
51
- this.newCommandTimeoutMs = 0;
52
- this.args = Object.assign({}, args);
53
- this.sessions = {};
54
- this.pendingDrivers = {};
55
- this.plugins = [];
56
- (0, _config.updateBuildInfo)();
56
+ this.args = { ...opts
57
+ };
58
+ (0, _config.updateBuildInfo)().catch(err => {
59
+ this.log.debug(err);
60
+ });
61
+ }
62
+
63
+ get log() {
64
+ if (!this._log) {
65
+ const instanceName = `${this.constructor.name}@${_support.node.getObjectId(this).substring(0, 4)}`;
66
+ this._log = _support.logger.getLogger(instanceName);
67
+ }
68
+
69
+ return this._log;
57
70
  }
58
71
 
59
72
  get isCommandsQueueEnabled() {
@@ -76,34 +89,52 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
76
89
  }
77
90
 
78
91
  async getSessions() {
79
- const sessions = await sessionsListGuard.acquire(AppiumDriver.name, () => this.sessions);
80
- return _lodash.default.toPairs(sessions).map(([id, driver]) => ({
92
+ return _lodash.default.toPairs(this.sessions).map(([id, driver]) => ({
81
93
  id,
82
94
  capabilities: driver.caps
83
95
  }));
84
96
  }
85
97
 
86
- printNewSessionAnnouncement(driverName, driverVersion) {
87
- const introString = driverVersion ? `Appium v${_config.APPIUM_VER} creating new ${driverName} (v${driverVersion}) session` : `Appium v${_config.APPIUM_VER} creating new ${driverName} session`;
88
-
89
- _logger.default.info(introString);
98
+ printNewSessionAnnouncement(driverName, driverVersion, driverBaseVersion) {
99
+ this.log.info(driverVersion ? `Appium v${_config.APPIUM_VER} creating new ${driverName} (v${driverVersion}) session` : `Appium v${_config.APPIUM_VER} creating new ${driverName} session`);
100
+ this.log.info(`Checking BaseDriver versions for Appium and ${driverName}`);
101
+ this.log.info(AppiumDriver.baseVersion ? `Appium's BaseDriver version is ${AppiumDriver.baseVersion}` : `Could not determine Appium's BaseDriver version`);
102
+ this.log.info(driverBaseVersion ? `${driverName}'s BaseDriver version is ${driverBaseVersion}` : `Could not determine ${driverName}'s BaseDriver version`);
90
103
  }
91
104
 
92
- _findMatchingDriver(...args) {
93
- return (0, _drivers.findMatchingDriver)(...args);
105
+ assignCliArgsToExtension(extType, extName, extInstance) {
106
+ var _this$args$extType;
107
+
108
+ const allCliArgsForExt = (_this$args$extType = this.args[extType]) === null || _this$args$extType === void 0 ? void 0 : _this$args$extType[extName];
109
+
110
+ if (!_lodash.default.isEmpty(allCliArgsForExt)) {
111
+ const defaults = (0, _schema.getDefaultsForExtension)(extType, extName);
112
+ const cliArgs = _lodash.default.isEmpty(defaults) ? allCliArgsForExt : _lodash.default.omitBy(allCliArgsForExt, (value, key) => _lodash.default.isEqual(defaults[key], value));
113
+
114
+ if (!_lodash.default.isEmpty(cliArgs)) {
115
+ extInstance.cliArgs = cliArgs;
116
+ }
117
+ }
94
118
  }
95
119
 
96
- async createSession(jsonwpCaps, reqCaps, w3cCapabilities) {
120
+ async createSession(jsonwpCaps, reqCaps, w3cCapabilities, driverData) {
121
+ var _alwaysMatch, _w3cCapabilities;
122
+
97
123
  const defaultCapabilities = _lodash.default.cloneDeep(this.args.defaultCapabilities);
98
124
 
99
125
  const defaultSettings = (0, _utils.pullSettings)(defaultCapabilities);
100
126
  jsonwpCaps = _lodash.default.cloneDeep(jsonwpCaps);
101
- const jwpSettings = Object.assign({}, defaultSettings, (0, _utils.pullSettings)(jsonwpCaps));
127
+ const jwpSettings = { ...defaultSettings,
128
+ ...(0, _utils.pullSettings)(jsonwpCaps)
129
+ };
102
130
  w3cCapabilities = _lodash.default.cloneDeep(w3cCapabilities);
103
- const w3cSettings = Object.assign({}, jwpSettings);
104
- Object.assign(w3cSettings, (0, _utils.pullSettings)((w3cCapabilities || {}).alwaysMatch || {}));
131
+ const w3cSettings = { ...jwpSettings,
132
+ ...(0, _utils.pullSettings)((_alwaysMatch = ((_w3cCapabilities = w3cCapabilities) !== null && _w3cCapabilities !== void 0 ? _w3cCapabilities : {}).alwaysMatch) !== null && _alwaysMatch !== void 0 ? _alwaysMatch : {})
133
+ };
134
+
135
+ for (const firstMatchEntry of (_firstMatch = ((_w3cCapabilities2 = w3cCapabilities) !== null && _w3cCapabilities2 !== void 0 ? _w3cCapabilities2 : {}).firstMatch) !== null && _firstMatch !== void 0 ? _firstMatch : []) {
136
+ var _firstMatch, _w3cCapabilities2;
105
137
 
106
- for (const firstMatchEntry of (w3cCapabilities || {}).firstMatch || []) {
107
138
  Object.assign(w3cSettings, (0, _utils.pullSettings)(firstMatchEntry));
108
139
  }
109
140
 
@@ -115,10 +146,10 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
115
146
  const {
116
147
  desiredCaps,
117
148
  processedJsonwpCapabilities,
118
- processedW3CCapabilities,
119
- error
149
+ processedW3CCapabilities
120
150
  } = parsedCaps;
121
151
  protocol = parsedCaps.protocol;
152
+ const error = parsedCaps.error;
122
153
 
123
154
  if (error) {
124
155
  throw error;
@@ -126,78 +157,73 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
126
157
 
127
158
  const {
128
159
  driver: InnerDriver,
129
- version: driverVersion
130
- } = this._findMatchingDriver(this.driverConfig, desiredCaps);
131
-
132
- this.printNewSessionAnnouncement(InnerDriver.name, driverVersion);
160
+ version: driverVersion,
161
+ driverName
162
+ } = this.driverConfig.findMatchingDriver(desiredCaps);
163
+ this.printNewSessionAnnouncement(InnerDriver.name, driverVersion, InnerDriver.baseVersion);
133
164
 
134
165
  if (this.args.sessionOverride) {
135
166
  await this.deleteAllSessions();
136
167
  }
137
168
 
138
- let runningDriversData, otherPendingDriversData;
139
- const d = new InnerDriver(this.args);
169
+ let runningDriversData = [];
170
+ let otherPendingDriversData = [];
171
+ const driverInstance = new InnerDriver(this.args, true);
140
172
 
141
173
  if (this.args.relaxedSecurityEnabled) {
142
- _logger.default.info(`Applying relaxed security to '${InnerDriver.name}' as per ` + `server command line argument. All insecure features will be ` + `enabled unless explicitly disabled by --deny-insecure`);
143
-
144
- d.relaxedSecurityEnabled = true;
174
+ this.log.info(`Applying relaxed security to '${InnerDriver.name}' as per ` + `server command line argument. All insecure features will be ` + `enabled unless explicitly disabled by --deny-insecure`);
175
+ driverInstance.relaxedSecurityEnabled = true;
145
176
  }
146
177
 
147
178
  if (!_lodash.default.isEmpty(this.args.denyInsecure)) {
148
- _logger.default.info('Explicitly preventing use of insecure features:');
149
-
150
- this.args.denyInsecure.map(a => _logger.default.info(` ${a}`));
151
- d.denyInsecure = this.args.denyInsecure;
179
+ this.log.info('Explicitly preventing use of insecure features:');
180
+ this.args.denyInsecure.map(a => this.log.info(` ${a}`));
181
+ driverInstance.denyInsecure = this.args.denyInsecure;
152
182
  }
153
183
 
154
184
  if (!_lodash.default.isEmpty(this.args.allowInsecure)) {
155
- _logger.default.info('Explicitly enabling use of insecure features:');
156
-
157
- this.args.allowInsecure.map(a => _logger.default.info(` ${a}`));
158
- d.allowInsecure = this.args.allowInsecure;
185
+ this.log.info('Explicitly enabling use of insecure features:');
186
+ this.args.allowInsecure.map(a => this.log.info(` ${a}`));
187
+ driverInstance.allowInsecure = this.args.allowInsecure;
159
188
  }
160
189
 
161
- d.server = this.server;
190
+ this.assignCliArgsToExtension('driver', driverName, driverInstance);
191
+ driverInstance.assignServer(this.server, this.args.address, this.args.port, this.args.basePath);
162
192
 
163
193
  try {
164
- runningDriversData = await this.curSessionDataForDriver(InnerDriver);
194
+ var _await$this$curSessio;
195
+
196
+ runningDriversData = (_await$this$curSessio = await this.curSessionDataForDriver(InnerDriver)) !== null && _await$this$curSessio !== void 0 ? _await$this$curSessio : [];
165
197
  } catch (e) {
166
- throw new _appiumBaseDriver.errors.SessionNotCreatedError(e.message);
198
+ throw new _baseDriver.errors.SessionNotCreatedError(e.message);
167
199
  }
168
200
 
169
201
  await pendingDriversGuard.acquire(AppiumDriver.name, () => {
170
202
  this.pendingDrivers[InnerDriver.name] = this.pendingDrivers[InnerDriver.name] || [];
171
- otherPendingDriversData = this.pendingDrivers[InnerDriver.name].map(drv => drv.driverData);
172
- this.pendingDrivers[InnerDriver.name].push(d);
203
+ otherPendingDriversData = _lodash.default.compact(this.pendingDrivers[InnerDriver.name].map(drv => drv.driverData));
204
+ this.pendingDrivers[InnerDriver.name].push(driverInstance);
173
205
  });
174
206
 
175
207
  try {
176
- [innerSessionId, dCaps] = await d.createSession(processedJsonwpCapabilities, reqCaps, processedW3CCapabilities, [...runningDriversData, ...otherPendingDriversData]);
177
- protocol = d.protocol;
178
- await sessionsListGuard.acquire(AppiumDriver.name, () => {
179
- this.sessions[innerSessionId] = d;
180
- });
208
+ [innerSessionId, dCaps] = await driverInstance.createSession(processedJsonwpCapabilities, reqCaps, processedW3CCapabilities, [...runningDriversData, ...otherPendingDriversData]);
209
+ protocol = driverInstance.protocol;
210
+ this.sessions[innerSessionId] = driverInstance;
181
211
  } finally {
182
212
  await pendingDriversGuard.acquire(AppiumDriver.name, () => {
183
- _lodash.default.pull(this.pendingDrivers[InnerDriver.name], d);
213
+ _lodash.default.pull(this.pendingDrivers[InnerDriver.name], driverInstance);
184
214
  });
185
215
  }
186
216
 
187
- this.attachUnexpectedShutdownHandler(d, innerSessionId);
217
+ this.attachUnexpectedShutdownHandler(driverInstance, innerSessionId);
218
+ this.log.info(`New ${InnerDriver.name} session created successfully, session ` + `${innerSessionId} added to master session list`);
219
+ driverInstance.startNewCommandTimeout();
188
220
 
189
- _logger.default.info(`New ${InnerDriver.name} session created successfully, session ` + `${innerSessionId} added to master session list`);
190
-
191
- d.startNewCommandTimeout();
192
-
193
- if (d.isW3CProtocol() && !_lodash.default.isEmpty(w3cSettings)) {
194
- _logger.default.info(`Applying the initial values to Appium settings parsed from W3C caps: ` + JSON.stringify(w3cSettings));
195
-
196
- await d.updateSettings(w3cSettings);
197
- } else if (d.isMjsonwpProtocol() && !_lodash.default.isEmpty(jwpSettings)) {
198
- _logger.default.info(`Applying the initial values to Appium settings parsed from MJSONWP caps: ` + JSON.stringify(jwpSettings));
199
-
200
- await d.updateSettings(jwpSettings);
221
+ if (driverInstance.isW3CProtocol() && !_lodash.default.isEmpty(w3cSettings)) {
222
+ this.log.info(`Applying the initial values to Appium settings parsed from W3C caps: ` + JSON.stringify(w3cSettings));
223
+ await driverInstance.updateSettings(w3cSettings);
224
+ } else if (driverInstance.isMjsonwpProtocol() && !_lodash.default.isEmpty(jwpSettings)) {
225
+ this.log.info(`Applying the initial values to Appium settings parsed from MJSONWP caps: ` + JSON.stringify(jwpSettings));
226
+ await driverInstance.updateSettings(jwpSettings);
201
227
  }
202
228
  } catch (error) {
203
229
  return {
@@ -213,37 +239,43 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
213
239
  }
214
240
 
215
241
  attachUnexpectedShutdownHandler(driver, innerSessionId) {
216
- const removeSessionFromMasterList = (cause = new Error('Unknown error')) => {
217
- _logger.default.warn(`Closing session, cause was '${cause.message}'`);
218
-
219
- _logger.default.info(`Removing session '${innerSessionId}' from our master session list`);
242
+ const onShutdown = (cause = new Error('Unknown error')) => {
243
+ this.log.warn(`Ending session, cause was '${cause.message}'`);
244
+
245
+ if (this.sessionPlugins[innerSessionId]) {
246
+ for (const plugin of this.sessionPlugins[innerSessionId]) {
247
+ if (_lodash.default.isFunction(plugin.onUnexpectedShutdown)) {
248
+ this.log.debug(`Plugin ${plugin.name} defines an unexpected shutdown handler; calling it now`);
249
+
250
+ try {
251
+ plugin.onUnexpectedShutdown(driver, cause);
252
+ } catch (e) {
253
+ this.log.warn(`Got an error when running plugin ${plugin.name} shutdown handler: ${e}`);
254
+ }
255
+ } else {
256
+ this.log.debug(`Plugin ${plugin.name} does not define an unexpected shutdown handler`);
257
+ }
258
+ }
259
+ }
220
260
 
261
+ this.log.info(`Removing session '${innerSessionId}' from our master session list`);
221
262
  delete this.sessions[innerSessionId];
263
+ delete this.sessionPlugins[innerSessionId];
222
264
  };
223
265
 
224
- if (_lodash.default.isFunction((driver.onUnexpectedShutdown || {}).then)) {
225
- driver.onUnexpectedShutdown.then(() => {
226
- throw new Error('Unexpected shutdown');
227
- }).catch(e => {
228
- if (!(e instanceof _bluebird.default.CancellationError)) {
229
- removeSessionFromMasterList(e);
230
- }
231
- });
232
- } else if (_lodash.default.isFunction(driver.onUnexpectedShutdown)) {
233
- driver.onUnexpectedShutdown(removeSessionFromMasterList);
266
+ if (_lodash.default.isFunction(driver.onUnexpectedShutdown)) {
267
+ driver.onUnexpectedShutdown(onShutdown);
234
268
  } else {
235
- _logger.default.warn(`Failed to attach the unexpected shutdown listener. ` + `Is 'onUnexpectedShutdown' method available for '${driver.constructor.name}'?`);
269
+ this.log.warn(`Failed to attach the unexpected shutdown listener. ` + `Is 'onUnexpectedShutdown' method available for '${driver.constructor.name}'?`);
236
270
  }
237
271
  }
238
272
 
239
273
  async curSessionDataForDriver(InnerDriver) {
240
- const sessions = await sessionsListGuard.acquire(AppiumDriver.name, () => this.sessions);
241
-
242
- const data = _lodash.default.values(sessions).filter(s => s.constructor.name === InnerDriver.name).map(s => s.driverData);
274
+ const data = _lodash.default.compact(_lodash.default.values(this.sessions).filter(s => s.constructor.name === InnerDriver.name).map(s => s.driverData));
243
275
 
244
- for (let datum of data) {
276
+ for (const datum of data) {
245
277
  if (!datum) {
246
- throw new Error(`Problem getting session data for driver type ` + `${InnerDriver.name}; does it implement 'get ` + `driverData'?`);
278
+ throw new Error(`Problem getting session data for driver type ` + `${InnerDriver.name}; does it implement 'get driverData'?`);
247
279
  }
248
280
  }
249
281
 
@@ -254,29 +286,32 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
254
286
  let protocol;
255
287
 
256
288
  try {
257
- let otherSessionsData = null;
258
- let dstSession = null;
259
- await sessionsListGuard.acquire(AppiumDriver.name, () => {
289
+ let otherSessionsData;
290
+ const dstSession = await sessionsListGuard.acquire(AppiumDriver.name, () => {
260
291
  if (!this.sessions[sessionId]) {
261
292
  return;
262
293
  }
263
294
 
264
295
  const curConstructorName = this.sessions[sessionId].constructor.name;
265
296
  otherSessionsData = _lodash.default.toPairs(this.sessions).filter(([key, value]) => value.constructor.name === curConstructorName && key !== sessionId).map(([, value]) => value.driverData);
266
- dstSession = this.sessions[sessionId];
297
+ const dstSession = this.sessions[sessionId];
267
298
  protocol = dstSession.protocol;
268
-
269
- _logger.default.info(`Removing session ${sessionId} from our master session list`);
270
-
299
+ this.log.info(`Removing session ${sessionId} from our master session list`);
271
300
  delete this.sessions[sessionId];
301
+ delete this.sessionPlugins[sessionId];
302
+ return dstSession;
272
303
  });
304
+
305
+ if (!dstSession) {
306
+ throw new Error('Session not found');
307
+ }
308
+
273
309
  return {
274
310
  protocol,
275
311
  value: await dstSession.deleteSession(sessionId, otherSessionsData)
276
312
  };
277
313
  } catch (e) {
278
- _logger.default.error(`Had trouble ending session ${sessionId}: ${e.message}`);
279
-
314
+ this.log.error(`Had trouble ending session ${sessionId}: ${e.message}`);
280
315
  return {
281
316
  protocol,
282
317
  error: e
@@ -288,8 +323,7 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
288
323
  const sessionsCount = _lodash.default.size(this.sessions);
289
324
 
290
325
  if (0 === sessionsCount) {
291
- _logger.default.debug('There are no active sessions for cleanup');
292
-
326
+ this.log.debug('There are no active sessions for cleanup');
293
327
  return;
294
328
  }
295
329
 
@@ -297,64 +331,109 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
297
331
  force = false,
298
332
  reason
299
333
  } = opts;
300
-
301
- _logger.default.debug(`Cleaning up ${_appiumSupport.util.pluralize('active session', sessionsCount, true)}`);
302
-
334
+ this.log.debug(`Cleaning up ${_support.util.pluralize('active session', sessionsCount, true)}`);
303
335
  const cleanupPromises = force ? _lodash.default.values(this.sessions).map(drv => drv.startUnexpectedShutdown(reason && new Error(reason))) : _lodash.default.keys(this.sessions).map(id => this.deleteSession(id));
304
336
 
305
337
  for (const cleanupPromise of cleanupPromises) {
306
338
  try {
307
339
  await cleanupPromise;
308
340
  } catch (e) {
309
- _logger.default.debug(e);
341
+ this.log.debug(e);
310
342
  }
311
343
  }
312
344
  }
313
345
 
314
- pluginsToHandleCmd(cmd) {
315
- return this.plugins.filter(p => p.commands === true || _lodash.default.isArray(p.commands) && _lodash.default.includes(p.commands, cmd));
346
+ pluginsForSession(sessionId = null) {
347
+ if (sessionId) {
348
+ if (!this.sessionPlugins[sessionId]) {
349
+ this.sessionPlugins[sessionId] = this.createPluginInstances();
350
+ }
351
+
352
+ return this.sessionPlugins[sessionId];
353
+ }
354
+
355
+ if (_lodash.default.isEmpty(this.sessionlessPlugins)) {
356
+ this.sessionlessPlugins = this.createPluginInstances();
357
+ }
358
+
359
+ return this.sessionlessPlugins;
360
+ }
361
+
362
+ pluginsToHandleCmd(cmd, sessionId = null) {
363
+ return this.pluginsForSession(sessionId).filter(p => _lodash.default.isFunction(p[cmd]) || _lodash.default.isFunction(p.handle));
364
+ }
365
+
366
+ createPluginInstances() {
367
+ return this.pluginClasses.map(PluginClass => {
368
+ const name = PluginClass.pluginName;
369
+ const plugin = new PluginClass(name);
370
+ this.assignCliArgsToExtension('plugin', name, plugin);
371
+ return plugin;
372
+ });
316
373
  }
317
374
 
318
375
  async executeCommand(cmd, ...args) {
319
- const isGetStatus = cmd === 'getStatus';
320
- const isUmbrellaCmd = !isGetStatus && isAppiumDriverCommand(cmd);
321
- const isSessionCmd = !isGetStatus && !isUmbrellaCmd;
322
- const plugins = this.pluginsToHandleCmd(cmd);
376
+ var _$last;
377
+
378
+ const isGetStatus = cmd === _baseDriver.GET_STATUS_COMMAND;
379
+ const isUmbrellaCmd = isAppiumDriverCommand(cmd);
380
+ const isSessionCmd = (0, _baseDriver.isSessionCommand)(cmd);
381
+ const reqForProxy = (_$last = _lodash.default.last(args)) === null || _$last === void 0 ? void 0 : _$last.reqForProxy;
382
+
383
+ if (reqForProxy) {
384
+ args.pop();
385
+ }
386
+
323
387
  let sessionId = null;
324
388
  let dstSession = null;
325
389
  let protocol = null;
390
+ let driver = this;
326
391
 
327
392
  if (isSessionCmd) {
328
393
  sessionId = _lodash.default.last(args);
329
- dstSession = await sessionsListGuard.acquire(AppiumDriver.name, () => this.sessions[sessionId]);
394
+ dstSession = this.sessions[sessionId];
330
395
 
331
396
  if (!dstSession) {
332
397
  throw new Error(`The session with id '${sessionId}' does not exist`);
333
398
  }
334
399
 
335
400
  protocol = dstSession.protocol;
401
+
402
+ if (!isUmbrellaCmd) {
403
+ driver = dstSession;
404
+ }
336
405
  }
337
406
 
407
+ const plugins = this.pluginsToHandleCmd(cmd, sessionId);
338
408
  const cmdHandledBy = {
339
409
  default: false
340
410
  };
341
411
 
342
412
  const defaultBehavior = async () => {
343
- plugins.length && _logger.default.info(`Executing default handling behavior for command '${cmd}'`);
413
+ plugins.length && this.log.info(`Executing default handling behavior for command '${cmd}'`);
344
414
  cmdHandledBy.default = true;
345
415
 
416
+ if (reqForProxy) {
417
+ if (!dstSession.proxyCommand) {
418
+ throw new NoDriverProxyCommandError();
419
+ }
420
+
421
+ return await dstSession.proxyCommand(reqForProxy.originalUrl, reqForProxy.method, reqForProxy.body);
422
+ }
423
+
346
424
  if (isGetStatus) {
347
425
  return await this.getStatus();
348
426
  }
349
427
 
350
428
  if (isUmbrellaCmd) {
351
- return await super.executeCommand(cmd, ...args);
429
+ return await _baseDriver.BaseDriver.prototype.executeCommand.call(this, cmd, ...args);
352
430
  }
353
431
 
354
432
  return await dstSession.executeCommand(cmd, ...args);
355
433
  };
356
434
 
357
435
  const wrappedCmd = this.wrapCommandWithPlugins({
436
+ driver,
358
437
  cmd,
359
438
  args,
360
439
  plugins,
@@ -365,45 +444,63 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
365
444
  wrappedCmd,
366
445
  protocol
367
446
  });
368
- plugins.length && this.logPluginHandlerReport({
447
+ this.logPluginHandlerReport(plugins, {
369
448
  cmd,
370
449
  cmdHandledBy
371
450
  });
451
+
452
+ if (cmd === _baseDriver.CREATE_SESSION_COMMAND && this.sessionlessPlugins.length && !res.error) {
453
+ const sessionId = _lodash.default.first(res.value);
454
+
455
+ this.log.info(`Promoting ${this.sessionlessPlugins.length} sessionless plugins to be attached ` + `to session ID ${sessionId}`);
456
+ this.sessionPlugins[sessionId] = this.sessionlessPlugins;
457
+ this.sessionlessPlugins = [];
458
+ }
459
+
372
460
  return res;
373
461
  }
374
462
 
375
463
  wrapCommandWithPlugins({
464
+ driver,
376
465
  cmd,
377
466
  args,
378
467
  next,
379
468
  cmdHandledBy,
380
469
  plugins
381
470
  }) {
382
- plugins.length && _logger.default.info(`Plugins which can handle cmd '${cmd}': ${plugins.map(p => p.name)}`);
471
+ plugins.length && this.log.info(`Plugins which can handle cmd '${cmd}': ${plugins.map(p => p.name)}`);
383
472
 
384
473
  for (const plugin of plugins) {
385
474
  cmdHandledBy[plugin.name] = false;
386
475
 
387
476
  next = (_next => async () => {
388
- _logger.default.info(`Plugin ${plugin.name} is now handling cmd '${cmd}'`);
389
-
477
+ this.log.info(`Plugin ${plugin.name} is now handling cmd '${cmd}'`);
390
478
  cmdHandledBy[plugin.name] = true;
391
- return await plugin.handle(_next, this, cmd, ...args);
479
+
480
+ if (plugin[cmd]) {
481
+ return await plugin[cmd](_next, driver, ...args);
482
+ }
483
+
484
+ return await plugin.handle(_next, driver, cmd, ...args);
392
485
  })(next);
393
486
  }
394
487
 
395
488
  return next;
396
489
  }
397
490
 
398
- logPluginHandlerReport({
491
+ logPluginHandlerReport(plugins, {
399
492
  cmd,
400
493
  cmdHandledBy
401
494
  }) {
495
+ if (!plugins.length) {
496
+ return;
497
+ }
498
+
402
499
  const didHandle = Object.keys(cmdHandledBy).filter(k => cmdHandledBy[k]);
403
500
  const didntHandle = Object.keys(cmdHandledBy).filter(k => !cmdHandledBy[k]);
404
501
 
405
502
  if (didntHandle.length > 0) {
406
- _logger.default.info(`Command '${cmd}' was not handled by the following beahviors or plugins, even ` + `though they were registered to handle it: ${JSON.stringify(didntHandle)}. The ` + `command *was* handled by these: ${JSON.stringify(didHandle)}.`);
503
+ this.log.info(`Command '${cmd}' was *not* handled by the following behaviours or plugins, even ` + `though they were registered to handle it: ${JSON.stringify(didntHandle)}. The ` + `command *was* handled by these: ${JSON.stringify(didHandle)}.`);
407
504
  }
408
505
  }
409
506
 
@@ -452,8 +549,17 @@ class AppiumDriver extends _appiumBaseDriver.BaseDriver {
452
549
  exports.AppiumDriver = AppiumDriver;
453
550
 
454
551
  function isAppiumDriverCommand(cmd) {
455
- return !(0, _appiumBaseDriver.isSessionCommand)(cmd) || cmd === 'deleteSession';
456
- }require('source-map-support').install();
552
+ return !(0, _baseDriver.isSessionCommand)(cmd) || cmd === _baseDriver.DELETE_SESSION_COMMAND;
553
+ }
554
+
555
+ class NoDriverProxyCommandError extends Error {
556
+ code = 'APPIUMERR_NO_DRIVER_PROXYCOMMAND';
457
557
 
558
+ constructor() {
559
+ super(`The default behavior for this command was to proxy, but the driver ` + `did not have the 'proxyCommand' method defined. To fully support ` + `plugins, drivers should have 'proxyCommand' set to a jwpProxy object's ` + `'command()' method, in addition to the normal 'proxyReqRes'`);
560
+ }
561
+
562
+ }
458
563
 
459
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9hcHBpdW0uanMiXSwibmFtZXMiOlsiZGVzaXJlZENhcGFiaWxpdHlDb25zdHJhaW50cyIsImF1dG9tYXRpb25OYW1lIiwicHJlc2VuY2UiLCJpc1N0cmluZyIsInBsYXRmb3JtTmFtZSIsInNlc3Npb25zTGlzdEd1YXJkIiwiQXN5bmNMb2NrIiwicGVuZGluZ0RyaXZlcnNHdWFyZCIsIkFwcGl1bURyaXZlciIsIkJhc2VEcml2ZXIiLCJjb25zdHJ1Y3RvciIsImFyZ3MiLCJ0bXBEaXIiLCJwcm9jZXNzIiwiZW52IiwiQVBQSVVNX1RNUF9ESVIiLCJkZXNpcmVkQ2FwQ29uc3RyYWludHMiLCJuZXdDb21tYW5kVGltZW91dE1zIiwiT2JqZWN0IiwiYXNzaWduIiwic2Vzc2lvbnMiLCJwZW5kaW5nRHJpdmVycyIsInBsdWdpbnMiLCJpc0NvbW1hbmRzUXVldWVFbmFibGVkIiwic2Vzc2lvbkV4aXN0cyIsInNlc3Npb25JZCIsImRzdFNlc3Npb24iLCJkcml2ZXJGb3JTZXNzaW9uIiwiZ2V0U3RhdHVzIiwiYnVpbGQiLCJfIiwiY2xvbmUiLCJnZXRTZXNzaW9ucyIsImFjcXVpcmUiLCJuYW1lIiwidG9QYWlycyIsIm1hcCIsImlkIiwiZHJpdmVyIiwiY2FwYWJpbGl0aWVzIiwiY2FwcyIsInByaW50TmV3U2Vzc2lvbkFubm91bmNlbWVudCIsImRyaXZlck5hbWUiLCJkcml2ZXJWZXJzaW9uIiwiaW50cm9TdHJpbmciLCJBUFBJVU1fVkVSIiwibG9nIiwiaW5mbyIsIl9maW5kTWF0Y2hpbmdEcml2ZXIiLCJjcmVhdGVTZXNzaW9uIiwianNvbndwQ2FwcyIsInJlcUNhcHMiLCJ3M2NDYXBhYmlsaXRpZXMiLCJkZWZhdWx0Q2FwYWJpbGl0aWVzIiwiY2xvbmVEZWVwIiwiZGVmYXVsdFNldHRpbmdzIiwiandwU2V0dGluZ3MiLCJ3M2NTZXR0aW5ncyIsImFsd2F5c01hdGNoIiwiZmlyc3RNYXRjaEVudHJ5IiwiZmlyc3RNYXRjaCIsInByb3RvY29sIiwiaW5uZXJTZXNzaW9uSWQiLCJkQ2FwcyIsInBhcnNlZENhcHMiLCJkZXNpcmVkQ2FwcyIsInByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcyIsInByb2Nlc3NlZFczQ0NhcGFiaWxpdGllcyIsImVycm9yIiwiSW5uZXJEcml2ZXIiLCJ2ZXJzaW9uIiwiZHJpdmVyQ29uZmlnIiwic2Vzc2lvbk92ZXJyaWRlIiwiZGVsZXRlQWxsU2Vzc2lvbnMiLCJydW5uaW5nRHJpdmVyc0RhdGEiLCJvdGhlclBlbmRpbmdEcml2ZXJzRGF0YSIsImQiLCJyZWxheGVkU2VjdXJpdHlFbmFibGVkIiwiaXNFbXB0eSIsImRlbnlJbnNlY3VyZSIsImEiLCJhbGxvd0luc2VjdXJlIiwic2VydmVyIiwiY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIiLCJlIiwiZXJyb3JzIiwiU2Vzc2lvbk5vdENyZWF0ZWRFcnJvciIsIm1lc3NhZ2UiLCJkcnYiLCJkcml2ZXJEYXRhIiwicHVzaCIsInB1bGwiLCJhdHRhY2hVbmV4cGVjdGVkU2h1dGRvd25IYW5kbGVyIiwic3RhcnROZXdDb21tYW5kVGltZW91dCIsImlzVzNDUHJvdG9jb2wiLCJKU09OIiwic3RyaW5naWZ5IiwidXBkYXRlU2V0dGluZ3MiLCJpc01qc29ud3BQcm90b2NvbCIsInZhbHVlIiwicmVtb3ZlU2Vzc2lvbkZyb21NYXN0ZXJMaXN0IiwiY2F1c2UiLCJFcnJvciIsIndhcm4iLCJpc0Z1bmN0aW9uIiwib25VbmV4cGVjdGVkU2h1dGRvd24iLCJ0aGVuIiwiY2F0Y2giLCJCIiwiQ2FuY2VsbGF0aW9uRXJyb3IiLCJkYXRhIiwidmFsdWVzIiwiZmlsdGVyIiwicyIsImRhdHVtIiwiZGVsZXRlU2Vzc2lvbiIsIm90aGVyU2Vzc2lvbnNEYXRhIiwiY3VyQ29uc3RydWN0b3JOYW1lIiwia2V5Iiwib3B0cyIsInNlc3Npb25zQ291bnQiLCJzaXplIiwiZGVidWciLCJmb3JjZSIsInJlYXNvbiIsInV0aWwiLCJwbHVyYWxpemUiLCJjbGVhbnVwUHJvbWlzZXMiLCJzdGFydFVuZXhwZWN0ZWRTaHV0ZG93biIsImtleXMiLCJjbGVhbnVwUHJvbWlzZSIsInBsdWdpbnNUb0hhbmRsZUNtZCIsImNtZCIsInAiLCJjb21tYW5kcyIsImlzQXJyYXkiLCJpbmNsdWRlcyIsImV4ZWN1dGVDb21tYW5kIiwiaXNHZXRTdGF0dXMiLCJpc1VtYnJlbGxhQ21kIiwiaXNBcHBpdW1Ecml2ZXJDb21tYW5kIiwiaXNTZXNzaW9uQ21kIiwibGFzdCIsImNtZEhhbmRsZWRCeSIsImRlZmF1bHQiLCJkZWZhdWx0QmVoYXZpb3IiLCJsZW5ndGgiLCJ3cmFwcGVkQ21kIiwid3JhcENvbW1hbmRXaXRoUGx1Z2lucyIsIm5leHQiLCJyZXMiLCJleGVjdXRlV3JhcHBlZENvbW1hbmQiLCJsb2dQbHVnaW5IYW5kbGVyUmVwb3J0IiwicGx1Z2luIiwiX25leHQiLCJoYW5kbGUiLCJkaWRIYW5kbGUiLCJrIiwiZGlkbnRIYW5kbGUiLCJjbWRSZXMiLCJjbWRFcnIiLCJpc1BsYWluT2JqZWN0IiwiaGFzIiwicHJveHlBY3RpdmUiLCJnZXRQcm94eUF2b2lkTGlzdCIsImNhblByb3h5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU1BLDRCQUE0QixHQUFHO0FBQ25DQyxFQUFBQSxjQUFjLEVBQUU7QUFDZEMsSUFBQUEsUUFBUSxFQUFFLElBREk7QUFFZEMsSUFBQUEsUUFBUSxFQUFFO0FBRkksR0FEbUI7QUFLbkNDLEVBQUFBLFlBQVksRUFBRTtBQUNaRixJQUFBQSxRQUFRLEVBQUUsSUFERTtBQUVaQyxJQUFBQSxRQUFRLEVBQUU7QUFGRTtBQUxxQixDQUFyQztBQVdBLE1BQU1FLGlCQUFpQixHQUFHLElBQUlDLGtCQUFKLEVBQTFCO0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsSUFBSUQsa0JBQUosRUFBNUI7O0FBRUEsTUFBTUUsWUFBTixTQUEyQkMsNEJBQTNCLENBQXNDO0FBQ3BDQyxFQUFBQSxXQUFXLENBQUVD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LE1BRU87QUFDTFQsTUFBQUEsR0FBRyxDQUFDbkQsS0FBSixHQUFZNEQsTUFBWjtBQUNBVCxNQUFBQSxHQUFHLENBQUNsRixLQUFKLEdBQVk0RixNQUFaO0FBQ0FWLE1BQUFBLEdBQUcsQ0FBQ3pGLFFBQUosR0FBZUEsUUFBZjtBQUNEOztBQUNELFdBQU95RixHQUFQO0FBQ0Q7O0FBR0RhLEVBQUFBLFdBQVcsQ0FBRTFJLFNBQUYsRUFBYTtBQUN0QixVQUFNQyxVQUFVLEdBQUcsS0FBS04sUUFBTCxDQUFjSyxTQUFkLENBQW5CO0FBQ0EsV0FBT0MsVUFBVSxJQUFJSSxnQkFBRTBFLFVBQUYsQ0FBYTlFLFVBQVUsQ0FBQ3lJLFdBQXhCLENBQWQsSUFBc0R6SSxVQUFVLENBQUN5SSxXQUFYLENBQXVCMUksU0FBdkIsQ0FBN0Q7QUFDRDs7QUFFRDJJLEVBQUFBLGlCQUFpQixDQUFFM0ksU0FBRixFQUFhO0FBQzVCLFVBQU1DLFVBQVUsR0FBRyxLQUFLTixRQUFMLENBQWNLLFNBQWQsQ0FBbkI7QUFDQSxXQUFPQyxVQUFVLEdBQUdBLFVBQVUsQ0FBQzBJLGlCQUFYLEVBQUgsR0FBb0MsRUFBckQ7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxDQUFFNUksU0FBRixFQUFhO0FBQ25CLFVBQU1DLFVBQVUsR0FBRyxLQUFLTixRQUFMLENBQWNLLFNBQWQsQ0FBbkI7QUFDQSxXQUFPQyxVQUFVLElBQUlBLFVBQVUsQ0FBQzJJLFFBQVgsQ0FBb0I1SSxTQUFwQixDQUFyQjtBQUNEOztBQW5lbUM7Ozs7QUF3ZXRDLFNBQVNtSCxxQkFBVCxDQUFnQ1IsR0FBaEMsRUFBcUM7QUFDbkMsU0FBTyxDQUFDLHdDQUFpQkEsR0FBakIsQ0FBRCxJQUEwQkEsR0FBRyxLQUFLLGVBQXpDO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgeyBnZXRCdWlsZEluZm8sIHVwZGF0ZUJ1aWxkSW5mbywgQVBQSVVNX1ZFUiB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IGZpbmRNYXRjaGluZ0RyaXZlciB9IGZyb20gJy4vZHJpdmVycyc7XG5pbXBvcnQgeyBCYXNlRHJpdmVyLCBlcnJvcnMsIGlzU2Vzc2lvbkNvbW1hbmQgfSBmcm9tICdhcHBpdW0tYmFzZS1kcml2ZXInO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IEFzeW5jTG9jayBmcm9tICdhc3luYy1sb2NrJztcbmltcG9ydCB7IHBhcnNlQ2Fwc0ZvcklubmVyRHJpdmVyLCBwdWxsU2V0dGluZ3MgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IHV0aWwgfSBmcm9tICdhcHBpdW0tc3VwcG9ydCc7XG5cbmNvbnN0IGRlc2lyZWRDYXBhYmlsaXR5Q29uc3RyYWludHMgPSB7XG4gIGF1dG9tYXRpb25OYW1lOiB7XG4gICAgcHJlc2VuY2U6IHRydWUsXG4gICAgaXNTdHJpbmc6IHRydWUsXG4gIH0sXG4gIHBsYXRmb3JtTmFtZToge1xuICAgIHByZXNlbmNlOiB0cnVlLFxuICAgIGlzU3RyaW5nOiB0cnVlLFxuICB9LFxufTtcblxuY29uc3Qgc2Vzc2lvbnNMaXN0R3VhcmQgPSBuZXcgQXN5bmNMb2NrKCk7XG5jb25zdCBwZW5kaW5nRHJpdmVyc0d1YXJkID0gbmV3IEFzeW5jTG9jaygpO1xuXG5jbGFzcyBBcHBpdW1Ecml2ZXIgZXh0ZW5kcyBCYXNlRHJpdmVyIHtcbiAgY29uc3RydWN0b3IgKGFyZ3MpIHtcbiAgICAvLyBJdCBpcyBuZWNlc3NhcnkgdG8gc2V0IGAtLXRtcGAgaGVyZSBzaW5jZSBpdCBzaG91bGQgYmUgc2V0IHRvXG4gICAgLy8gcHJvY2Vzcy5lbnYuQVBQSVVNX1RNUF9ESVIgb25jZSBhdCBhbiBpbml0aWFsIHBvaW50IGluIHRoZSBBcHBpdW0gbGlmZWN5Y2xlLlxuICAgIC8vIFRoZSBwcm9jZXNzIGFyZ3VtZW50IHdpbGwgYmUgcmVmZXJlbmNlZCBieSBCYXNlRHJpdmVyLlxuICAgIC8vIFBsZWFzZSBjYWxsIGFwcGl1bS1zdXBwb3J0LnRlbXBEaXIgbW9kdWxlIHRvIGFwcGx5IHRoaXMgYmVuZWZpdC5cbiAgICBpZiAoYXJncy50bXBEaXIpIHtcbiAgICAgIHByb2Nlc3MuZW52LkFQUElVTV9UTVBfRElSID0gYXJncy50bXBEaXI7XG4gICAgfVxuXG4gICAgc3VwZXIoYXJncyk7XG5cbiAgICB0aGlzLmRlc2lyZWRDYXBDb25zdHJhaW50cyA9IGRlc2lyZWRDYXBhYmlsaXR5Q29uc3RyYWludHM7XG5cbiAgICAvLyB0aGUgbWFpbiBBcHBpdW0gRHJpdmVyIGhhcyBubyBuZXcgY29tbWFuZCB0aW1lb3V0XG4gICAgdGhpcy5uZXdDb21tYW5kVGltZW91dE1zID0gMDtcblxuICAgIHRoaXMuYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xuXG4gICAgLy8gQWNjZXNzIHRvIHNlc3Npb25zIGxpc3QgbXVzdCBiZSBndWFyZGVkIHdpdGggYSBTZW1hcGhvcmUsIGJlY2F1c2VcbiAgICAvLyBpdCBtaWdodCBiZSBjaGFuZ2VkIGJ5IG90aGVyIGFzeW5jIGNhbGxzIGF0IGFueSB0aW1lXG4gICAgLy8gSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICB0aGlzLnNlc3Npb25zID0ge307XG5cbiAgICAvLyBBY2Nlc3MgdG8gcGVuZGluZyBkcml2ZXJzIGxpc3QgbXVzdCBiZSBndWFyZGVkIHdpdGggYSBTZW1hcGhvcmUsIGJlY2F1c2VcbiAgICAvLyBpdCBtaWdodCBiZSBjaGFuZ2VkIGJ5IG90aGVyIGFzeW5jIGNhbGxzIGF0IGFueSB0aW1lXG4gICAgLy8gSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICB0aGlzLnBlbmRpbmdEcml2ZXJzID0ge307XG5cbiAgICB0aGlzLnBsdWdpbnMgPSBbXTtcblxuICAgIC8vIGFsbG93IHRoaXMgdG8gaGFwcGVuIGluIHRoZSBiYWNrZ3JvdW5kLCBzbyBubyBgYXdhaXRgXG4gICAgdXBkYXRlQnVpbGRJbmZvKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VsIGNvbW1hbmRzIHF1ZXVlaW5nIGZvciB0aGUgdW1icmVsbGEgQXBwaXVtIGRyaXZlclxuICAgKi9cbiAgZ2V0IGlzQ29tbWFuZHNRdWV1ZUVuYWJsZWQgKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHNlc3Npb25FeGlzdHMgKHNlc3Npb25JZCkge1xuICAgIGNvbnN0IGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgcmV0dXJuIGRzdFNlc3Npb24gJiYgZHN0U2Vzc2lvbi5zZXNzaW9uSWQgIT09IG51bGw7XG4gIH1cblxuICBkcml2ZXJGb3JTZXNzaW9uIChzZXNzaW9uSWQpIHtcbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICB9XG5cbiAgYXN5bmMgZ2V0U3RhdHVzICgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgcmV0dXJuIHtcbiAgICAgIGJ1aWxkOiBfLmNsb25lKGdldEJ1aWxkSW5mbygpKSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgZ2V0U2Vzc2lvbnMgKCkge1xuICAgIGNvbnN0IHNlc3Npb25zID0gYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4gdGhpcy5zZXNzaW9ucyk7XG4gICAgcmV0dXJuIF8udG9QYWlycyhzZXNzaW9ucylcbiAgICAgIC5tYXAoKFtpZCwgZHJpdmVyXSkgPT4gKHtpZCwgY2FwYWJpbGl0aWVzOiBkcml2ZXIuY2Fwc30pKTtcbiAgfVxuXG4gIHByaW50TmV3U2Vzc2lvbkFubm91bmNlbWVudCAoZHJpdmVyTmFtZSwgZHJpdmVyVmVyc2lvbikge1xuICAgIGNvbnN0IGludHJvU3RyaW5nID0gZHJpdmVyVmVyc2lvblxuICAgICAgPyBgQXBwaXVtIHYke0FQUElVTV9WRVJ9IGNyZWF0aW5nIG5ldyAke2RyaXZlck5hbWV9ICh2JHtkcml2ZXJWZXJzaW9ufSkgc2Vzc2lvbmBcbiAgICAgIDogYEFwcGl1bSB2JHtBUFBJVU1fVkVSfSBjcmVhdGluZyBuZXcgJHtkcml2ZXJOYW1lfSBzZXNzaW9uYDtcbiAgICBsb2cuaW5mbyhpbnRyb1N0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyBqdXN0IGFuIGFsaWFzIGZvciBkcml2ZXIuanMncyBtZXRob2QsIHdoaWNoIGlzIG5lY2Vzc2FyeSBmb3JcbiAgICogbW9ja2luZyBpbiB0aGUgdGVzdCBzdWl0ZVxuICAgKi9cbiAgX2ZpbmRNYXRjaGluZ0RyaXZlciAoLi4uYXJncykge1xuICAgIHJldHVybiBmaW5kTWF0Y2hpbmdEcml2ZXIoLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IHNlc3Npb25cbiAgICogQHBhcmFtIHtPYmplY3R9IGpzb253cENhcHMgSlNPTldQIGZvcm1hdHRlZCBkZXNpcmVkIGNhcGFiaWxpdGllc1xuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxQ2FwcyBSZXF1aXJlZCBjYXBhYmlsaXRpZXMgKEpTT05XUCBzdGFuZGFyZClcbiAgICogQHBhcmFtIHtPYmplY3R9IHczY0NhcGFiaWxpdGllcyBXM0MgY2FwYWJpbGl0aWVzXG4gICAqIEByZXR1cm4ge0FycmF5fSBVbmlxdWUgc2Vzc2lvbiBJRCBhbmQgY2FwYWJpbGl0aWVzXG4gICAqL1xuICBhc3luYyBjcmVhdGVTZXNzaW9uIChqc29ud3BDYXBzLCByZXFDYXBzLCB3M2NDYXBhYmlsaXRpZXMpIHtcbiAgICBjb25zdCBkZWZhdWx0Q2FwYWJpbGl0aWVzID0gXy5jbG9uZURlZXAodGhpcy5hcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMpO1xuICAgIGNvbnN0IGRlZmF1bHRTZXR0aW5ncyA9IHB1bGxTZXR0aW5ncyhkZWZhdWx0Q2FwYWJpbGl0aWVzKTtcbiAgICBqc29ud3BDYXBzID0gXy5jbG9uZURlZXAoanNvbndwQ2Fwcyk7XG4gICAgY29uc3QgandwU2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0U2V0dGluZ3MsIHB1bGxTZXR0aW5ncyhqc29ud3BDYXBzKSk7XG4gICAgdzNjQ2FwYWJpbGl0aWVzID0gXy5jbG9uZURlZXAodzNjQ2FwYWJpbGl0aWVzKTtcbiAgICAvLyBJdCBpcyBwb3NzaWJsZSB0aGF0IHRoZSBjbGllbnQgb25seSBwcm92aWRlcyBjYXBzIHVzaW5nIEpTT05XUCBzdGFuZGFyZCxcbiAgICAvLyBhbHRob3VnaCBmaXJzdE1hdGNoL2Fsd2F5c01hdGNoIHByb3BlcnRpZXMgYXJlIHN0aWxsIHByZXNlbnQuXG4gICAgLy8gSW4gc3VjaCBjYXNlIHdlIGFzc3VtZSB0aGUgY2xpZW50IHVuZGVyc3RhbmRzIFczQyBwcm90b2NvbCBhbmQgbWVyZ2UgdGhlIGdpdmVuXG4gICAgLy8gSlNPTldQIGNhcHMgdG8gVzNDIGNhcHNcbiAgICBjb25zdCB3M2NTZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIGp3cFNldHRpbmdzKTtcbiAgICBPYmplY3QuYXNzaWduKHczY1NldHRpbmdzLCBwdWxsU2V0dGluZ3MoKHczY0NhcGFiaWxpdGllcyB8fCB7fSkuYWx3YXlzTWF0Y2ggfHwge30pKTtcbiAgICBmb3IgKGNvbnN0IGZpcnN0TWF0Y2hFbnRyeSBvZiAoKHczY0NhcGFiaWxpdGllcyB8fCB7fSkuZmlyc3RNYXRjaCB8fCBbXSkpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24odzNjU2V0dGluZ3MsIHB1bGxTZXR0aW5ncyhmaXJzdE1hdGNoRW50cnkpKTtcbiAgICB9XG5cbiAgICBsZXQgcHJvdG9jb2w7XG4gICAgbGV0IGlubmVyU2Vzc2lvbklkLCBkQ2FwcztcbiAgICB0cnkge1xuICAgICAgLy8gUGFyc2UgdGhlIGNhcHMgaW50byBhIGZvcm1hdCB0aGF0IHRoZSBJbm5lckRyaXZlciB3aWxsIGFjY2VwdFxuICAgICAgY29uc3QgcGFyc2VkQ2FwcyA9IHBhcnNlQ2Fwc0ZvcklubmVyRHJpdmVyKFxuICAgICAgICBqc29ud3BDYXBzLFxuICAgICAgICB3M2NDYXBhYmlsaXRpZXMsXG4gICAgICAgIHRoaXMuZGVzaXJlZENhcENvbnN0cmFpbnRzLFxuICAgICAgICBkZWZhdWx0Q2FwYWJpbGl0aWVzXG4gICAgICApO1xuXG4gICAgICBjb25zdCB7ZGVzaXJlZENhcHMsIHByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcywgcHJvY2Vzc2VkVzNDQ2FwYWJpbGl0aWVzLCBlcnJvcn0gPSBwYXJzZWRDYXBzO1xuICAgICAgcHJvdG9jb2wgPSBwYXJzZWRDYXBzLnByb3RvY29sO1xuXG4gICAgICAvLyBJZiB0aGUgcGFyc2luZyBvZiB0aGUgY2FwcyBwcm9kdWNlZCBhbiBlcnJvciwgdGhyb3cgaXQgaW4gaGVyZVxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7XG4gICAgICAgIGRyaXZlcjogSW5uZXJEcml2ZXIsXG4gICAgICAgIHZlcnNpb246IGRyaXZlclZlcnNpb25cbiAgICAgIH0gPSB0aGlzLl9maW5kTWF0Y2hpbmdEcml2ZXIodGhpcy5kcml2ZXJDb25maWcsIGRlc2lyZWRDYXBzKTtcbiAgICAgIHRoaXMucHJpbnROZXdTZXNzaW9uQW5ub3VuY2VtZW50KElubmVyRHJpdmVyLm5hbWUsIGRyaXZlclZlcnNpb24pO1xuXG4gICAgICBpZiAodGhpcy5hcmdzLnNlc3Npb25PdmVycmlkZSkge1xuICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZUFsbFNlc3Npb25zKCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBydW5uaW5nRHJpdmVyc0RhdGEsIG90aGVyUGVuZGluZ0RyaXZlcnNEYXRhO1xuICAgICAgY29uc3QgZCA9IG5ldyBJbm5lckRyaXZlcih0aGlzLmFyZ3MpO1xuXG4gICAgICAvLyBXZSB3YW50IHRvIGFzc2lnbiBzZWN1cml0eSB2YWx1ZXMgZGlyZWN0bHkgb24gdGhlIGRyaXZlci4gVGhlIGRyaXZlclxuICAgICAgLy8gc2hvdWxkIG5vdCByZWFkIHNlY3VyaXR5IHZhbHVlcyBmcm9tIGB0aGlzLm9wdHNgIGJlY2F1c2UgdGhvc2UgdmFsdWVzXG4gICAgICAvLyBjb3VsZCBoYXZlIGJlZW4gc2V0IGJ5IGEgbWFsaWNpb3VzIHVzZXIgdmlhIGNhcGFiaWxpdGllcywgd2hlcmVhcyB3ZVxuICAgICAgLy8gd2FudCBhIGd1YXJhbnRlZSB0aGUgdmFsdWVzIHdlcmUgc2V0IGJ5IHRoZSBhcHBpdW0gc2VydmVyIGFkbWluXG4gICAgICBpZiAodGhpcy5hcmdzLnJlbGF4ZWRTZWN1cml0eUVuYWJsZWQpIHtcbiAgICAgICAgbG9nLmluZm8oYEFwcGx5aW5nIHJlbGF4ZWQgc2VjdXJpdHkgdG8gJyR7SW5uZXJEcml2ZXIubmFtZX0nIGFzIHBlciBgICtcbiAgICAgICAgICAgICAgICAgYHNlcnZlciBjb21tYW5kIGxpbmUgYXJndW1lbnQuIEFsbCBpbnNlY3VyZSBmZWF0dXJlcyB3aWxsIGJlIGAgK1xuICAgICAgICAgICAgICAgICBgZW5hYmxlZCB1bmxlc3MgZXhwbGljaXRseSBkaXNhYmxlZCBieSAtLWRlbnktaW5zZWN1cmVgKTtcbiAgICAgICAgZC5yZWxheGVkU2VjdXJpdHlFbmFibGVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcmdzLmRlbnlJbnNlY3VyZSkpIHtcbiAgICAgICAgbG9nLmluZm8oJ0V4cGxpY2l0bHkgcHJldmVudGluZyB1c2Ugb2YgaW5zZWN1cmUgZmVhdHVyZXM6Jyk7XG4gICAgICAgIHRoaXMuYXJncy5kZW55SW5zZWN1cmUubWFwKChhKSA9PiBsb2cuaW5mbyhgICAgICR7YX1gKSk7XG4gICAgICAgIGQuZGVueUluc2VjdXJlID0gdGhpcy5hcmdzLmRlbnlJbnNlY3VyZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcmdzLmFsbG93SW5zZWN1cmUpKSB7XG4gICAgICAgIGxvZy5pbmZvKCdFeHBsaWNpdGx5IGVuYWJsaW5nIHVzZSBvZiBpbnNlY3VyZSBmZWF0dXJlczonKTtcbiAgICAgICAgdGhpcy5hcmdzLmFsbG93SW5zZWN1cmUubWFwKChhKSA9PiBsb2cuaW5mbyhgICAgICR7YX1gKSk7XG4gICAgICAgIGQuYWxsb3dJbnNlY3VyZSA9IHRoaXMuYXJncy5hbGxvd0luc2VjdXJlO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGlzIGFzc2lnbm1lbnQgaXMgcmVxdWlyZWQgZm9yIGNvcnJlY3Qgd2ViIHNvY2tldHMgZnVuY3Rpb25hbGl0eSBpbnNpZGUgdGhlIGRyaXZlclxuICAgICAgZC5zZXJ2ZXIgPSB0aGlzLnNlcnZlcjtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJ1bm5pbmdEcml2ZXJzRGF0YSA9IGF3YWl0IHRoaXMuY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIoSW5uZXJEcml2ZXIpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBuZXcgZXJyb3JzLlNlc3Npb25Ob3RDcmVhdGVkRXJyb3IoZS5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHBlbmRpbmdEcml2ZXJzR3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICB0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdID0gdGhpcy5wZW5kaW5nRHJpdmVyc1tJbm5lckRyaXZlci5uYW1lXSB8fCBbXTtcbiAgICAgICAgb3RoZXJQZW5kaW5nRHJpdmVyc0RhdGEgPSB0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdLm1hcCgoZHJ2KSA9PiBkcnYuZHJpdmVyRGF0YSk7XG4gICAgICAgIHRoaXMucGVuZGluZ0RyaXZlcnNbSW5uZXJEcml2ZXIubmFtZV0ucHVzaChkKTtcbiAgICAgIH0pO1xuXG4gICAgICB0cnkge1xuICAgICAgICBbaW5uZXJTZXNzaW9uSWQsIGRDYXBzXSA9IGF3YWl0IGQuY3JlYXRlU2Vzc2lvbihcbiAgICAgICAgICBwcm9jZXNzZWRKc29ud3BDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgcmVxQ2FwcyxcbiAgICAgICAgICBwcm9jZXNzZWRXM0NDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgWy4uLnJ1bm5pbmdEcml2ZXJzRGF0YSwgLi4ub3RoZXJQZW5kaW5nRHJpdmVyc0RhdGFdXG4gICAgICAgICk7XG4gICAgICAgIHByb3RvY29sID0gZC5wcm90b2NvbDtcbiAgICAgICAgYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2Vzc2lvbnNbaW5uZXJTZXNzaW9uSWRdID0gZDtcbiAgICAgICAgfSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwZW5kaW5nRHJpdmVyc0d1YXJkLmFjcXVpcmUoQXBwaXVtRHJpdmVyLm5hbWUsICgpID0+IHtcbiAgICAgICAgICBfLnB1bGwodGhpcy5wZW5kaW5nRHJpdmVyc1tJbm5lckRyaXZlci5uYW1lXSwgZCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmF0dGFjaFVuZXhwZWN0ZWRTaHV0ZG93bkhhbmRsZXIoZCwgaW5uZXJTZXNzaW9uSWQpO1xuXG4gICAgICBsb2cuaW5mbyhgTmV3ICR7SW5uZXJEcml2ZXIubmFtZX0gc2Vzc2lvbiBjcmVhdGVkIHN1Y2Nlc3NmdWxseSwgc2Vzc2lvbiBgICtcbiAgICAgICAgICAgICAgYCR7aW5uZXJTZXNzaW9uSWR9IGFkZGVkIHRvIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcblxuICAgICAgLy8gc2V0IHRoZSBOZXcgQ29tbWFuZCBUaW1lb3V0IGZvciB0aGUgaW5uZXIgZHJpdmVyXG4gICAgICBkLnN0YXJ0TmV3Q29tbWFuZFRpbWVvdXQoKTtcblxuICAgICAgLy8gYXBwbHkgaW5pdGlhbCB2YWx1ZXMgdG8gQXBwaXVtIHNldHRpbmdzIChpZiBwcm92aWRlZClcbiAgICAgIGlmIChkLmlzVzNDUHJvdG9jb2woKSAmJiAhXy5pc0VtcHR5KHczY1NldHRpbmdzKSkge1xuICAgICAgICBsb2cuaW5mbyhgQXBwbHlpbmcgdGhlIGluaXRpYWwgdmFsdWVzIHRvIEFwcGl1bSBzZXR0aW5ncyBwYXJzZWQgZnJvbSBXM0MgY2FwczogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkodzNjU2V0dGluZ3MpKTtcbiAgICAgICAgYXdhaXQgZC51cGRhdGVTZXR0aW5ncyh3M2NTZXR0aW5ncyk7XG4gICAgICB9IGVsc2UgaWYgKGQuaXNNanNvbndwUHJvdG9jb2woKSAmJiAhXy5pc0VtcHR5KGp3cFNldHRpbmdzKSkge1xuICAgICAgICBsb2cuaW5mbyhgQXBwbHlpbmcgdGhlIGluaXRpYWwgdmFsdWVzIHRvIEFwcGl1bSBzZXR0aW5ncyBwYXJzZWQgZnJvbSBNSlNPTldQIGNhcHM6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGp3cFNldHRpbmdzKSk7XG4gICAgICAgIGF3YWl0IGQudXBkYXRlU2V0dGluZ3MoandwU2V0dGluZ3MpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcm90b2NvbCxcbiAgICAgICAgZXJyb3IsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwcm90b2NvbCxcbiAgICAgIHZhbHVlOiBbaW5uZXJTZXNzaW9uSWQsIGRDYXBzLCBwcm90b2NvbF1cbiAgICB9O1xuICB9XG5cbiAgYXR0YWNoVW5leHBlY3RlZFNodXRkb3duSGFuZGxlciAoZHJpdmVyLCBpbm5lclNlc3Npb25JZCkge1xuICAgIGNvbnN0IHJlbW92ZVNlc3Npb25Gcm9tTWFzdGVyTGlzdCA9IChjYXVzZSA9IG5ldyBFcnJvcignVW5rbm93biBlcnJvcicpKSA9PiB7XG4gICAgICBsb2cud2FybihgQ2xvc2luZyBzZXNzaW9uLCBjYXVzZSB3YXMgJyR7Y2F1c2UubWVzc2FnZX0nYCk7XG4gICAgICBsb2cuaW5mbyhgUmVtb3Zpbmcgc2Vzc2lvbiAnJHtpbm5lclNlc3Npb25JZH0nIGZyb20gb3VyIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcbiAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25zW2lubmVyU2Vzc2lvbklkXTtcbiAgICB9O1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByb21pc2UvcHJlZmVyLWF3YWl0LXRvLXRoZW5cbiAgICBpZiAoXy5pc0Z1bmN0aW9uKChkcml2ZXIub25VbmV4cGVjdGVkU2h1dGRvd24gfHwge30pLnRoZW4pKSB7XG4gICAgICAvLyBUT0RPOiBSZW1vdmUgdGhpcyBibG9jayBhZnRlciBhbGwgdGhlIGRyaXZlcnMgdXNlIGJhc2UgZHJpdmVyIGFib3ZlIHYgNS4wLjBcbiAgICAgIC8vIFJlbW92ZSB0aGUgc2Vzc2lvbiBvbiB1bmV4cGVjdGVkIHNodXRkb3duLCBzbyB0aGF0IHdlIGFyZSBpbiBhIHBvc2l0aW9uXG4gICAgICAvLyB0byBvcGVuIGFub3RoZXIgc2Vzc2lvbiBsYXRlciBvbi5cbiAgICAgIGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93blxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJvbWlzZS9wcmVmZXItYXdhaXQtdG8tdGhlblxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgLy8gaWYgd2UgZ2V0IGhlcmUsIHdlJ3ZlIGhhZCBhbiB1bmV4cGVjdGVkIHNodXRkb3duLCBzbyBlcnJvclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBzaHV0ZG93bicpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAvLyBpZiB3ZSBjYW5jZWxsZWQgdGhlIHVuZXhwZWN0ZWQgc2h1dGRvd24gcHJvbWlzZSwgdGhhdCBtZWFucyB3ZVxuICAgICAgICAgIC8vIG5vIGxvbmdlciBjYXJlIGFib3V0IGl0LCBhbmQgY2FuIHNhZmVseSBpZ25vcmUgaXRcbiAgICAgICAgICBpZiAoIShlIGluc3RhbmNlb2YgQi5DYW5jZWxsYXRpb25FcnJvcikpIHtcbiAgICAgICAgICAgIHJlbW92ZVNlc3Npb25Gcm9tTWFzdGVyTGlzdChlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pOyAvLyB0aGlzIGlzIGEgY2FuY2VsbGFibGUgcHJvbWlzZVxuICAgIH0gZWxzZSBpZiAoXy5pc0Z1bmN0aW9uKGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93bikpIHtcbiAgICAgIC8vIHNpbmNlIGJhc2UgZHJpdmVyIHYgNS4wLjBcbiAgICAgIGRyaXZlci5vblVuZXhwZWN0ZWRTaHV0ZG93bihyZW1vdmVTZXNzaW9uRnJvbU1hc3Rlckxpc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cud2FybihgRmFpbGVkIHRvIGF0dGFjaCB0aGUgdW5leHBlY3RlZCBzaHV0ZG93biBsaXN0ZW5lci4gYCArXG4gICAgICAgIGBJcyAnb25VbmV4cGVjdGVkU2h1dGRvd24nIG1ldGhvZCBhdmFpbGFibGUgZm9yICcke2RyaXZlci5jb25zdHJ1Y3Rvci5uYW1lfSc/YCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIgKElubmVyRHJpdmVyKSB7XG4gICAgY29uc3Qgc2Vzc2lvbnMgPSBhd2FpdCBzZXNzaW9uc0xpc3RHdWFyZC5hY3F1aXJlKEFwcGl1bURyaXZlci5uYW1lLCAoKSA9PiB0aGlzLnNlc3Npb25zKTtcbiAgICBjb25zdCBkYXRhID0gXy52YWx1ZXMoc2Vzc2lvbnMpXG4gICAgICAgICAgICAgICAgICAgLmZpbHRlcigocykgPT4gcy5jb25zdHJ1Y3Rvci5uYW1lID09PSBJbm5lckRyaXZlci5uYW1lKVxuICAgICAgICAgICAgICAgICAgIC5tYXAoKHMpID0+IHMuZHJpdmVyRGF0YSk7XG4gICAgZm9yIChsZXQgZGF0dW0gb2YgZGF0YSkge1xuICAgICAgaWYgKCFkYXR1bSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFByb2JsZW0gZ2V0dGluZyBzZXNzaW9uIGRhdGEgZm9yIGRyaXZlciB0eXBlIGAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYCR7SW5uZXJEcml2ZXIubmFtZX07IGRvZXMgaXQgaW1wbGVtZW50ICdnZXQgYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgZHJpdmVyRGF0YSc/YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlU2Vzc2lvbiAoc2Vzc2lvbklkKSB7XG4gICAgbGV0IHByb3RvY29sO1xuICAgIHRyeSB7XG4gICAgICBsZXQgb3RoZXJTZXNzaW9uc0RhdGEgPSBudWxsO1xuICAgICAgbGV0IGRzdFNlc3Npb24gPSBudWxsO1xuICAgICAgYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjdXJDb25zdHJ1Y3Rvck5hbWUgPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF0uY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgb3RoZXJTZXNzaW9uc0RhdGEgPSBfLnRvUGFpcnModGhpcy5zZXNzaW9ucylcbiAgICAgICAgICAgICAgLmZpbHRlcigoW2tleSwgdmFsdWVdKSA9PiB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lID09PSBjdXJDb25zdHJ1Y3Rvck5hbWUgJiYga2V5ICE9PSBzZXNzaW9uSWQpXG4gICAgICAgICAgICAgIC5tYXAoKFssIHZhbHVlXSkgPT4gdmFsdWUuZHJpdmVyRGF0YSk7XG4gICAgICAgIGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgICAgIHByb3RvY29sID0gZHN0U2Vzc2lvbi5wcm90b2NvbDtcbiAgICAgICAgbG9nLmluZm8oYFJlbW92aW5nIHNlc3Npb24gJHtzZXNzaW9uSWR9IGZyb20gb3VyIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcbiAgICAgICAgLy8gcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBkZWxldGVTZXNzaW9uIGNvbXBsZXRlcyBzdWNjZXNzZnVsbHkgb3Igbm90XG4gICAgICAgIC8vIG1ha2UgdGhlIHNlc3Npb24gdW5hdmFpbGFibGUsIGJlY2F1c2Ugd2hvIGtub3dzIHdoYXQgc3RhdGUgaXQgbWlnaHRcbiAgICAgICAgLy8gYmUgaW4gb3RoZXJ3aXNlXG4gICAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByb3RvY29sLFxuICAgICAgICB2YWx1ZTogYXdhaXQgZHN0U2Vzc2lvbi5kZWxldGVTZXNzaW9uKHNlc3Npb25JZCwgb3RoZXJTZXNzaW9uc0RhdGEpLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2cuZXJyb3IoYEhhZCB0cm91YmxlIGVuZGluZyBzZXNzaW9uICR7c2Vzc2lvbklkfTogJHtlLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcm90b2NvbCxcbiAgICAgICAgZXJyb3I6IGUsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZUFsbFNlc3Npb25zIChvcHRzID0ge30pIHtcbiAgICBjb25zdCBzZXNzaW9uc0NvdW50ID0gXy5zaXplKHRoaXMuc2Vzc2lvbnMpO1xuICAgIGlmICgwID09PSBzZXNzaW9uc0NvdW50KSB7XG4gICAgICBsb2cuZGVidWcoJ1RoZXJlIGFyZSBubyBhY3RpdmUgc2Vzc2lvbnMgZm9yIGNsZWFudXAnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICBmb3JjZSA9IGZhbHNlLFxuICAgICAgcmVhc29uLFxuICAgIH0gPSBvcHRzO1xuICAgIGxvZy5kZWJ1ZyhgQ2xlYW5pbmcgdXAgJHt1dGlsLnBsdXJhbGl6ZSgnYWN0aXZlIHNlc3Npb24nLCBzZXNzaW9uc0NvdW50LCB0cnVlKX1gKTtcbiAgICBjb25zdCBjbGVhbnVwUHJvbWlzZXMgPSBmb3JjZVxuICAgICAgPyBfLnZhbHVlcyh0aGlzLnNlc3Npb25zKS5tYXAoKGRydikgPT4gZHJ2LnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKHJlYXNvbiAmJiBuZXcgRXJyb3IocmVhc29uKSkpXG4gICAgICA6IF8ua2V5cyh0aGlzLnNlc3Npb25zKS5tYXAoKGlkKSA9PiB0aGlzLmRlbGV0ZVNlc3Npb24oaWQpKTtcbiAgICBmb3IgKGNvbnN0IGNsZWFudXBQcm9taXNlIG9mIGNsZWFudXBQcm9taXNlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY2xlYW51cFByb21pc2U7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwbHVnaW5zVG9IYW5kbGVDbWQgKGNtZCkge1xuICAgIHJldHVybiB0aGlzLnBsdWdpbnMuZmlsdGVyKChwKSA9PlxuICAgICAgcC5jb21tYW5kcyA9PT0gdHJ1ZSB8fFxuICAgICAgKF8uaXNBcnJheShwLmNvbW1hbmRzKSAmJiBfLmluY2x1ZGVzKHAuY29tbWFuZHMsIGNtZCkpXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGVDb21tYW5kIChjbWQsIC4uLmFyZ3MpIHtcbiAgICAvLyBXZSBoYXZlIGJhc2ljYWxseSB0aHJlZSBjYXNlcyBmb3IgaG93IHRvIGhhbmRsZSBjb21tYW5kczpcbiAgICAvLyAxLiBoYW5kbGUgZ2V0U3RhdHVzICh3ZSBkbyB0aGlzIGFzIGEgc3BlY2lhbCBvdXQgb2YgYmFuZCBjYXNlIHNvIGl0IGRvZXNuJ3QgZ2V0IGFkZGVkIHRvIGFuXG4gICAgLy8gICAgZXhlY3V0aW9uIHF1ZXVlLCBhbmQgY2FuIGJlIGNhbGxlZCB3aGlsZSBlLmcuIGNyZWF0ZVNlc3Npb24gaXMgaW4gcHJvZ3Jlc3MpXG4gICAgLy8gMi4gaGFuZGxlIGNvbW1hbmRzIHRoYXQgdGhpcyB1bWJyZWxsYSBkcml2ZXIgc2hvdWxkIGhhbmRsZSwgcmF0aGVyIHRoYW4gdGhlIGFjdHVhbCBzZXNzaW9uXG4gICAgLy8gICAgZHJpdmVyIChmb3IgZXhhbXBsZSwgZGVsZXRlU2Vzc2lvbiwgb3Igb3RoZXIgbm9uLXNlc3Npb24gY29tbWFuZHMpXG4gICAgLy8gMy4gaGFuZGxlIHNlc3Npb24gZHJpdmVyIGNvbW1hbmRzLlxuICAgIC8vIFRoZSB0cmlja3kgcGFydCBpcyB0aGF0IGJlY2F1c2Ugd2Ugc3VwcG9ydCBjb21tYW5kIHBsdWdpbnMsIHdlIG5lZWQgdG8gd3JhcCBhbnkgb2YgdGhlc2VcbiAgICAvLyBjYXNlcyB3aXRoIHBsdWdpbiBoYW5kbGluZy5cblxuICAgIGNvbnN0IGlzR2V0U3RhdHVzID0gY21kID09PSAnZ2V0U3RhdHVzJztcbiAgICBjb25zdCBpc1VtYnJlbGxhQ21kID0gIWlzR2V0U3RhdHVzICYmIGlzQXBwaXVtRHJpdmVyQ29tbWFuZChjbWQpO1xuICAgIGNvbnN0IGlzU2Vzc2lvbkNtZCA9ICFpc0dldFN0YXR1cyAmJiAhaXNVbWJyZWxsYUNtZDtcblxuICAgIC8vIGdldCBhbnkgcGx1Z2lucyB3aGljaCBhcmUgcmVnaXN0ZXJlZCBhcyBoYW5kbGluZyB0aGlzIGNvbW1hbmRcbiAgICBjb25zdCBwbHVnaW5zID0gdGhpcy5wbHVnaW5zVG9IYW5kbGVDbWQoY21kKTtcblxuICAgIC8vIGZpcnN0IGRvIHNvbWUgZXJyb3IgY2hlY2tpbmcuIElmIHdlJ3JlIHJlcXVlc3RpbmcgYSBzZXNzaW9uIGNvbW1hbmQgZXhlY3V0aW9uLCB0aGVuIG1ha2VcbiAgICAvLyBzdXJlIHRoYXQgc2Vzc2lvbiBhY3R1YWxseSBleGlzdHMgb24gdGhlIHNlc3Npb24gZHJpdmVyLCBhbmQgc2V0IHRoZSBzZXNzaW9uIGRyaXZlciBpdHNlbGZcbiAgICBsZXQgc2Vzc2lvbklkID0gbnVsbDtcbiAgICBsZXQgZHN0U2Vzc2lvbiA9IG51bGw7XG4gICAgbGV0IHByb3RvY29sID0gbnVsbDtcbiAgICBpZiAoaXNTZXNzaW9uQ21kKSB7XG4gICAgICBzZXNzaW9uSWQgPSBfLmxhc3QoYXJncyk7XG4gICAgICBkc3RTZXNzaW9uID0gYXdhaXQgc2Vzc2lvbnNMaXN0R3VhcmQuYWNxdWlyZShBcHBpdW1Ecml2ZXIubmFtZSwgKCkgPT4gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdKTtcbiAgICAgIGlmICghZHN0U2Vzc2lvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBzZXNzaW9uIHdpdGggaWQgJyR7c2Vzc2lvbklkfScgZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgIH1cbiAgICAgIC8vIG5vdyBzYXZlIHRoZSByZXNwb25zZSBwcm90b2NvbCBnaXZlbiB0aGF0IHRoZSBzZXNzaW9uIGRyaXZlcidzIHByb3RvY29sIG1pZ2h0IGRpZmZlclxuICAgICAgcHJvdG9jb2wgPSBkc3RTZXNzaW9uLnByb3RvY29sO1xuICAgIH1cblxuICAgIC8vIG5vdyB3ZSBkZWZpbmUgYSAnY21kSGFuZGxlZEJ5JyBvYmplY3Qgd2hpY2ggd2lsbCBrZWVwIHRyYWNrIG9mIHdoaWNoIHBsdWdpbnMgaGF2ZSBoYW5kbGVkIHRoaXNcbiAgICAvLyBjb21tYW5kLiB3ZSBjYXJlIGFib3V0IHRoaXMgYmVjYXVzZSAoYSkgbXVsdGlwbGUgcGx1Z2lucyBjYW4gaGFuZGxlIHRoZSBzYW1lIGNvbW1hbmQsIGFuZFxuICAgIC8vIChiKSB0aGVyZSdzIG5vIGd1YXJhbnRlZSB0aGF0IGEgcGx1Z2luIHdpbGwgYWN0dWFsbHkgY2FsbCB0aGUgbmV4dCgpIG1ldGhvZCB3aGljaCBydW5zIHRoZVxuICAgIC8vIG9yaWdpbmFsIGNvbW1hbmQgZXhlY3V0aW9uLiBUaGlzIHJlc3VsdHMgaW4gYSBzaXR1YXRpb24gd2hlcmUgdGhlIGNvbW1hbmQgbWlnaHQgYmUgaGFuZGxlZFxuICAgIC8vIGJ5IHNvbWUgYnV0IG5vdCBhbGwgcGx1Z2lucywgb3IgYnkgcGx1Z2luKHMpIGJ1dCBub3QgYnkgdGhlIGRlZmF1bHQgYmVoYXZpb3IuIFNvIHN0YXJ0IG91dFxuICAgIC8vIHRoaXMgb2JqZWN0IGRlY2xhcmluZyB0aGF0IHRoZSBkZWZhdWx0IGhhbmRsZXIgaGFzIG5vdCBiZWVuIGV4ZWN1dGVkLlxuICAgIGNvbnN0IGNtZEhhbmRsZWRCeSA9IHtkZWZhdWx0OiBmYWxzZX07XG5cbiAgICAvLyBub3cgd2UgZGVmaW5lIGFuIGFzeW5jIGZ1bmN0aW9uIHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIHBsdWdpbnMsIGFuZCBzdWNjZXNzaXZlbHkgd3JhcHBlZFxuICAgIC8vIGlmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgcGx1Z2luIHRoYXQgY2FuIGhhbmRsZSB0aGUgY29tbWFuZC4gVG8gc3RhcnQgb2ZmIHdpdGgsIHRoZSBhc3luY1xuICAgIC8vIGZ1bmN0aW9uIGlzIGRlZmluZWQgYXMgY2FsbGluZyB0aGUgZGVmYXVsdCBiZWhhdmlvciwgaS5lLiwgd2hpY2hldmVyIG9mIHRoZSAzIGNhc2VzIGFib3ZlIGlzXG4gICAgLy8gdGhlIGFwcHJvcHJpYXRlIG9uZVxuICAgIGNvbnN0IGRlZmF1bHRCZWhhdmlvciA9IGFzeW5jICgpID0+IHtcbiAgICAgIC8vIGlmIHdlJ3JlIHJ1bm5pbmcgd2l0aCBwbHVnaW5zLCBtYWtlIHN1cmUgd2UgbG9nIHRoYXQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgYWN0dWFsbHlcbiAgICAgIC8vIGhhcHBlbmluZyBzbyB3ZSBjYW4gdGVsbCB3aGVuIHRoZSBwbHVnaW4gY2FsbCBjaGFpbiBpcyB1bndyYXBwaW5nIHRvIHRoZSBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICAvLyBpZiB0aGF0J3Mgd2hhdCBoYXBwZW5zXG4gICAgICBwbHVnaW5zLmxlbmd0aCAmJiBsb2cuaW5mbyhgRXhlY3V0aW5nIGRlZmF1bHQgaGFuZGxpbmcgYmVoYXZpb3IgZm9yIGNvbW1hbmQgJyR7Y21kfSdgKTtcblxuICAgICAgLy8gaWYgd2UgbWFrZSBpdCBoZXJlLCB3ZSBrbm93IHRoYXQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgaGFuZGxlZFxuICAgICAgY21kSGFuZGxlZEJ5LmRlZmF1bHQgPSB0cnVlO1xuXG4gICAgICBpZiAoaXNHZXRTdGF0dXMpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0U3RhdHVzKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1VtYnJlbGxhQ21kKSB7XG4gICAgICAgIC8vIHNvbWUgY29tbWFuZHMsIGxpa2UgZGVsZXRlU2Vzc2lvbiwgd2Ugd2FudCB0byBtYWtlIHN1cmUgdG8gaGFuZGxlIG9uICp0aGlzKiBkcml2ZXIsXG4gICAgICAgIC8vIG5vdCB0aGUgcGxhdGZvcm0gZHJpdmVyXG4gICAgICAgIHJldHVybiBhd2FpdCBzdXBlci5leGVjdXRlQ29tbWFuZChjbWQsIC4uLmFyZ3MpO1xuICAgICAgfVxuXG4gICAgICAvLyBoZXJlIHdlIGtub3cgdGhhdCB3ZSBhcmUgZXhlY3V0aW5nIGEgc2Vzc2lvbiBjb21tYW5kLCBhbmQgaGF2ZSBhIHZhbGlkIHNlc3Npb24gZHJpdmVyXG4gICAgICByZXR1cm4gYXdhaXQgZHN0U2Vzc2lvbi5leGVjdXRlQ29tbWFuZChjbWQsIC4uLmFyZ3MpO1xuICAgIH07XG5cbiAgICAvLyBub3cgdGFrZSBvdXIgZGVmYXVsdCBiZWhhdmlvciwgd3JhcCBpdCB3aXRoIGFueSBudW1iZXIgb2YgcGx1Z2luIGJlaGF2aW9ycywgYW5kIHJ1biBpdFxuICAgIGNvbnN0IHdyYXBwZWRDbWQgPSB0aGlzLndyYXBDb21tYW5kV2l0aFBsdWdpbnMoe2NtZCwgYXJncywgcGx1Z2lucywgY21kSGFuZGxlZEJ5LCBuZXh0OiBkZWZhdWx0QmVoYXZpb3J9KTtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmV4ZWN1dGVXcmFwcGVkQ29tbWFuZCh7d3JhcHBlZENtZCwgcHJvdG9jb2x9KTtcblxuICAgIC8vIGlmIHdlIGhhZCBwbHVnaW5zLCBtYWtlIHN1cmUgdG8gbG9nIG91dCB0aGUgaGVscGZ1bCByZXBvcnQgYWJvdXQgd2hpY2ggcGx1Z2lucyBlbmRlZCB1cFxuICAgIC8vIGhhbmRsaW5nIHRoZSBjb21tYW5kIGFuZCB3aGljaCBkaWRuJ3RcbiAgICBwbHVnaW5zLmxlbmd0aCAmJiB0aGlzLmxvZ1BsdWdpbkhhbmRsZXJSZXBvcnQoe2NtZCwgY21kSGFuZGxlZEJ5fSk7XG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgd3JhcENvbW1hbmRXaXRoUGx1Z2lucyAoe2NtZCwgYXJncywgbmV4dCwgY21kSGFuZGxlZEJ5LCBwbHVnaW5zfSkge1xuICAgIHBsdWdpbnMubGVuZ3RoICYmIGxvZy5pbmZvKGBQbHVnaW5zIHdoaWNoIGNhbiBoYW5kbGUgY21kICcke2NtZH0nOiAke3BsdWdpbnMubWFwKChwKSA9PiBwLm5hbWUpfWApO1xuXG4gICAgLy8gbm93IHdlIGNhbiBnbyB0aHJvdWdoIGVhY2ggcGx1Z2luIGFuZCB3cmFwIGBuZXh0YCBhcm91bmQgaXRzIG93biBoYW5kbGVyLCBwYXNzaW5nIHRoZSAqb2xkKlxuICAgIC8vIG5leHQgaW4gc28gdGhhdCBpdCBjYW4gY2FsbCBpdCBpZiBpdCB3YW50cyB0b1xuICAgIGZvciAoY29uc3QgcGx1Z2luIG9mIHBsdWdpbnMpIHtcbiAgICAgIC8vIG5lZWQgYW4gSUlGRSBoZXJlIGJlY2F1c2Ugd2Ugd2FudCB0aGUgdmFsdWUgb2YgbmV4dCB0aGF0J3MgcGFzc2VkIHRvIHBsdWdpbi5oYW5kbGUgdG8gYmVcbiAgICAgIC8vIGV4YWN0bHkgdGhlIHZhbHVlIG9mIG5leHQgaGVyZSBiZWZvcmUgcmVhc3NpZ25tZW50OyB3ZSBkb24ndCB3YW50IGl0IHRvIGJlIGxhemlseVxuICAgICAgLy8gZXZhbHVhdGVkLCBvdGhlcndpc2Ugd2UgZW5kIHVwIHdpdGggaW5maW5pdGUgcmVjdXJzaW9uIG9mIHRoZSBsYXN0IGBuZXh0YCB0byBiZSBkZWZpbmVkLlxuICAgICAgY21kSGFuZGxlZEJ5W3BsdWdpbi5uYW1lXSA9IGZhbHNlOyAvLyB3ZSBzZWUgYSBuZXcgcGx1Z2luLCBzbyBhZGQgaXQgdG8gdGhlICdjbWRIYW5kbGVkQnknIG9iamVjdFxuICAgICAgbmV4dCA9ICgoX25leHQpID0+IGFzeW5jICgpID0+IHtcbiAgICAgICAgbG9nLmluZm8oYFBsdWdpbiAke3BsdWdpbi5uYW1lfSBpcyBub3cgaGFuZGxpbmcgY21kICcke2NtZH0nYCk7XG4gICAgICAgIGNtZEhhbmRsZWRCeVtwbHVnaW4ubmFtZV0gPSB0cnVlOyAvLyBpZiB3ZSBtYWtlIGl0IGhlcmUsIHRoaXMgcGx1Z2luIGhhcyBhdHRlbXB0ZWQgdG8gaGFuZGxlIGNtZFxuICAgICAgICByZXR1cm4gYXdhaXQgcGx1Z2luLmhhbmRsZShfbmV4dCwgdGhpcywgY21kLCAuLi5hcmdzKTtcbiAgICAgIH0pKG5leHQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXh0O1xuICB9XG5cbiAgbG9nUGx1Z2luSGFuZGxlclJlcG9ydCAoe2NtZCwgY21kSGFuZGxlZEJ5fSkge1xuICAgIC8vIGF0IHRoZSBlbmQgb2YgdGhlIGRheSwgd2UgaGF2ZSBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHdoaWNoIHBsdWdpbnMgZW5kZWQgdXAgZ2V0dGluZ1xuICAgIC8vIHRoZWlyIGNvZGUgcnVuIGFzIHBhcnQgb2YgaGFuZGxpbmcgdGhpcyBjb21tYW5kLiBCZWNhdXNlIHBsdWdpbnMgY2FuIGNob29zZSAqbm90KiB0b1xuICAgIC8vIHBhc3MgY29udHJvbCB0byBvdGhlciBwbHVnaW5zIG9yIHRvIHRoZSBkZWZhdWx0IGRyaXZlciBiZWhhdmlvciwgdGhpcyBpcyBpbmZvcm1hdGlvblxuICAgIC8vIHdoaWNoIGlzIHByb2JhYmx5IHVzZWZ1bCB0byB0aGUgdXNlciAoZXNwZWNpYWxseSBpbiBzaXR1YXRpb25zIHdoZXJlIHBsdWdpbnMgbWlnaHQgbm90XG4gICAgLy8gaW50ZXJhY3Qgd2VsbCB0b2dldGhlciwgYW5kIGl0IHdvdWxkIGJlIGhhcmQgdG8gZGVidWcgb3RoZXJ3aXNlIHdpdGhvdXQgdGhpcyBraW5kIG9mXG4gICAgLy8gbWVzc2FnZSkuXG4gICAgY29uc3QgZGlkSGFuZGxlID0gT2JqZWN0LmtleXMoY21kSGFuZGxlZEJ5KS5maWx0ZXIoKGspID0+IGNtZEhhbmRsZWRCeVtrXSk7XG4gICAgY29uc3QgZGlkbnRIYW5kbGUgPSBPYmplY3Qua2V5cyhjbWRIYW5kbGVkQnkpLmZpbHRlcigoaykgPT4gIWNtZEhhbmRsZWRCeVtrXSk7XG4gICAgaWYgKGRpZG50SGFuZGxlLmxlbmd0aCA+IDApIHtcbiAgICAgIGxvZy5pbmZvKGBDb21tYW5kICcke2NtZH0nIHdhcyBub3QgaGFuZGxlZCBieSB0aGUgZm9sbG93aW5nIGJlYWh2aW9ycyBvciBwbHVnaW5zLCBldmVuIGAgK1xuICAgICAgICAgICAgICAgYHRob3VnaCB0aGV5IHdlcmUgcmVnaXN0ZXJlZCB0byBoYW5kbGUgaXQ6ICR7SlNPTi5zdHJpbmdpZnkoZGlkbnRIYW5kbGUpfS4gVGhlIGAgK1xuICAgICAgICAgICAgICAgYGNvbW1hbmQgKndhcyogaGFuZGxlZCBieSB0aGVzZTogJHtKU09OLnN0cmluZ2lmeShkaWRIYW5kbGUpfS5gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBleGVjdXRlV3JhcHBlZENvbW1hbmQgKHt3cmFwcGVkQ21kLCBwcm90b2NvbH0pIHtcbiAgICBsZXQgY21kUmVzLCBjbWRFcnIsIHJlcyA9IHt9O1xuICAgIHRyeSB7XG4gICAgICAvLyBBdCB0aGlzIHBvaW50LCBgd3JhcHBlZENtZGAgZGVmaW5lcyBhIHdob2xlIHNlcXVlbmNlIG9mIHBsdWdpbiBoYW5kbGVycywgY3VsbWluYXRpbmcgaW5cbiAgICAgIC8vIG91ciBkZWZhdWx0IGhhbmRsZXIuIFdoYXRldmVyIGl0IHJldHVybnMgaXMgd2hhdCB3ZSdyZSBnb2luZyB0byB3YW50IHRvIHNlbmQgYmFjayB0byB0aGVcbiAgICAgIC8vIHVzZXIuXG4gICAgICBjbWRSZXMgPSBhd2FpdCB3cmFwcGVkQ21kKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY21kRXJyID0gZTtcbiAgICB9XG5cbiAgICAvLyBTYWRseSwgd2UgZG9uJ3Qga25vdyBleGFjdGx5IHdoYXQga2luZCBvZiBvYmplY3Qgd2lsbCBiZSByZXR1cm5lZC4gSXQgd2lsbCBlaXRoZXIgYmUgYSBiYXJlXG4gICAgLy8gb2JqZWN0LCBvciBhIHByb3RvY29sLWF3YXJlIG9iamVjdCB3aXRoIHByb3RvY29sIGFuZCBlcnJvci92YWx1ZSBrZXlzLiBTbyB3ZSBuZWVkIHRvIHNuaWZmXG4gICAgLy8gaXQgYW5kIG1ha2Ugc3VyZSB3ZSBkb24ndCBkb3VibGUtd3JhcCBpdCBpZiBpdCdzIHRoZSBsYXR0ZXIga2luZC5cbiAgICBpZiAoXy5pc1BsYWluT2JqZWN0KGNtZFJlcykgJiYgXy5oYXMoY21kUmVzLCAncHJvdG9jb2wnKSkge1xuICAgICAgcmVzID0gY21kUmVzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMudmFsdWUgPSBjbWRSZXM7XG4gICAgICByZXMuZXJyb3IgPSBjbWRFcnI7XG4gICAgICByZXMucHJvdG9jb2wgPSBwcm90b2NvbDtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG5cbiAgcHJveHlBY3RpdmUgKHNlc3Npb25JZCkge1xuICAgIGNvbnN0IGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgcmV0dXJuIGRzdFNlc3Npb24gJiYgXy5pc0Z1bmN0aW9uKGRzdFNlc3Npb24ucHJveHlBY3RpdmUpICYmIGRzdFNlc3Npb24ucHJveHlBY3RpdmUoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIGdldFByb3h5QXZvaWRMaXN0IChzZXNzaW9uSWQpIHtcbiAgICBjb25zdCBkc3RTZXNzaW9uID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgIHJldHVybiBkc3RTZXNzaW9uID8gZHN0U2Vzc2lvbi5nZXRQcm94eUF2b2lkTGlzdCgpIDogW107XG4gIH1cblxuICBjYW5Qcm94eSAoc2Vzc2lvbklkKSB7XG4gICAgY29uc3QgZHN0U2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgICByZXR1cm4gZHN0U2Vzc2lvbiAmJiBkc3RTZXNzaW9uLmNhblByb3h5KHNlc3Npb25JZCk7XG4gIH1cbn1cblxuLy8gaGVscCBkZWNpZGUgd2hpY2ggY29tbWFuZHMgc2hvdWxkIGJlIHByb3hpZWQgdG8gc3ViLWRyaXZlcnMgYW5kIHdoaWNoXG4vLyBzaG91bGQgYmUgaGFuZGxlZCBieSB0aGlzLCBvdXIgdW1icmVsbGEgZHJpdmVyXG5mdW5jdGlvbiBpc0FwcGl1bURyaXZlckNvbW1hbmQgKGNtZCkge1xuICByZXR1cm4gIWlzU2Vzc2lvbkNvbW1hbmQoY21kKSB8fCBjbWQgPT09ICdkZWxldGVTZXNzaW9uJztcbn1cblxuZXhwb3J0IHsgQXBwaXVtRHJpdmVyIH07XG4iXSwiZmlsZSI6ImxpYi9hcHBpdW0uanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==
564
+ exports.NoDriverProxyCommandError = NoDriverProxyCommandError;
565
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9hcHBpdW0uanMiXSwibmFtZXMiOlsiZGVzaXJlZENhcGFiaWxpdHlDb25zdHJhaW50cyIsIk9iamVjdCIsImZyZWV6ZSIsImF1dG9tYXRpb25OYW1lIiwicHJlc2VuY2UiLCJpc1N0cmluZyIsInBsYXRmb3JtTmFtZSIsInNlc3Npb25zTGlzdEd1YXJkIiwiQXN5bmNMb2NrIiwicGVuZGluZ0RyaXZlcnNHdWFyZCIsIkFwcGl1bURyaXZlciIsIkRyaXZlckNvcmUiLCJzZXNzaW9ucyIsInBlbmRpbmdEcml2ZXJzIiwibmV3Q29tbWFuZFRpbWVvdXRNcyIsInBsdWdpbkNsYXNzZXMiLCJzZXNzaW9uUGx1Z2lucyIsInNlc3Npb25sZXNzUGx1Z2lucyIsImRyaXZlckNvbmZpZyIsInNlcnZlciIsImNvbnN0cnVjdG9yIiwib3B0cyIsInRtcERpciIsInByb2Nlc3MiLCJlbnYiLCJBUFBJVU1fVE1QX0RJUiIsImRlc2lyZWRDYXBDb25zdHJhaW50cyIsImFyZ3MiLCJjYXRjaCIsImVyciIsImxvZyIsImRlYnVnIiwiX2xvZyIsImluc3RhbmNlTmFtZSIsIm5hbWUiLCJub2RlIiwiZ2V0T2JqZWN0SWQiLCJzdWJzdHJpbmciLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJpc0NvbW1hbmRzUXVldWVFbmFibGVkIiwic2Vzc2lvbkV4aXN0cyIsInNlc3Npb25JZCIsImRzdFNlc3Npb24iLCJkcml2ZXJGb3JTZXNzaW9uIiwiZ2V0U3RhdHVzIiwiYnVpbGQiLCJfIiwiY2xvbmUiLCJnZXRTZXNzaW9ucyIsInRvUGFpcnMiLCJtYXAiLCJpZCIsImRyaXZlciIsImNhcGFiaWxpdGllcyIsImNhcHMiLCJwcmludE5ld1Nlc3Npb25Bbm5vdW5jZW1lbnQiLCJkcml2ZXJOYW1lIiwiZHJpdmVyVmVyc2lvbiIsImRyaXZlckJhc2VWZXJzaW9uIiwiaW5mbyIsIkFQUElVTV9WRVIiLCJiYXNlVmVyc2lvbiIsImFzc2lnbkNsaUFyZ3NUb0V4dGVuc2lvbiIsImV4dFR5cGUiLCJleHROYW1lIiwiZXh0SW5zdGFuY2UiLCJhbGxDbGlBcmdzRm9yRXh0IiwiaXNFbXB0eSIsImRlZmF1bHRzIiwiY2xpQXJncyIsIm9taXRCeSIsInZhbHVlIiwia2V5IiwiaXNFcXVhbCIsImNyZWF0ZVNlc3Npb24iLCJqc29ud3BDYXBzIiwicmVxQ2FwcyIsInczY0NhcGFiaWxpdGllcyIsImRyaXZlckRhdGEiLCJkZWZhdWx0Q2FwYWJpbGl0aWVzIiwiY2xvbmVEZWVwIiwiZGVmYXVsdFNldHRpbmdzIiwiandwU2V0dGluZ3MiLCJ3M2NTZXR0aW5ncyIsImFsd2F5c01hdGNoIiwiZmlyc3RNYXRjaEVudHJ5IiwiZmlyc3RNYXRjaCIsImFzc2lnbiIsInByb3RvY29sIiwiaW5uZXJTZXNzaW9uSWQiLCJkQ2FwcyIsInBhcnNlZENhcHMiLCJkZXNpcmVkQ2FwcyIsInByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcyIsInByb2Nlc3NlZFczQ0NhcGFiaWxpdGllcyIsImVycm9yIiwiSW5uZXJEcml2ZXIiLCJ2ZXJzaW9uIiwiZmluZE1hdGNoaW5nRHJpdmVyIiwic2Vzc2lvbk92ZXJyaWRlIiwiZGVsZXRlQWxsU2Vzc2lvbnMiLCJydW5uaW5nRHJpdmVyc0RhdGEiLCJvdGhlclBlbmRpbmdEcml2ZXJzRGF0YSIsImRyaXZlckluc3RhbmNlIiwicmVsYXhlZFNlY3VyaXR5RW5hYmxlZCIsImRlbnlJbnNlY3VyZSIsImEiLCJhbGxvd0luc2VjdXJlIiwiYXNzaWduU2VydmVyIiwiYWRkcmVzcyIsInBvcnQiLCJiYXNlUGF0aCIsImN1clNlc3Npb25EYXRhRm9yRHJpdmVyIiwiZSIsImVycm9ycyIsIlNlc3Npb25Ob3RDcmVhdGVkRXJyb3IiLCJtZXNzYWdlIiwiYWNxdWlyZSIsImNvbXBhY3QiLCJkcnYiLCJwdXNoIiwicHVsbCIsImF0dGFjaFVuZXhwZWN0ZWRTaHV0ZG93bkhhbmRsZXIiLCJzdGFydE5ld0NvbW1hbmRUaW1lb3V0IiwiaXNXM0NQcm90b2NvbCIsIkpTT04iLCJzdHJpbmdpZnkiLCJ1cGRhdGVTZXR0aW5ncyIsImlzTWpzb253cFByb3RvY29sIiwib25TaHV0ZG93biIsImNhdXNlIiwiRXJyb3IiLCJ3YXJuIiwicGx1Z2luIiwiaXNGdW5jdGlvbiIsIm9uVW5leHBlY3RlZFNodXRkb3duIiwiZGF0YSIsInZhbHVlcyIsImZpbHRlciIsInMiLCJkYXR1bSIsImRlbGV0ZVNlc3Npb24iLCJvdGhlclNlc3Npb25zRGF0YSIsImN1ckNvbnN0cnVjdG9yTmFtZSIsInNlc3Npb25zQ291bnQiLCJzaXplIiwiZm9yY2UiLCJyZWFzb24iLCJ1dGlsIiwicGx1cmFsaXplIiwiY2xlYW51cFByb21pc2VzIiwic3RhcnRVbmV4cGVjdGVkU2h1dGRvd24iLCJrZXlzIiwiY2xlYW51cFByb21pc2UiLCJwbHVnaW5zRm9yU2Vzc2lvbiIsImNyZWF0ZVBsdWdpbkluc3RhbmNlcyIsInBsdWdpbnNUb0hhbmRsZUNtZCIsImNtZCIsInAiLCJoYW5kbGUiLCJQbHVnaW5DbGFzcyIsInBsdWdpbk5hbWUiLCJleGVjdXRlQ29tbWFuZCIsImlzR2V0U3RhdHVzIiwiR0VUX1NUQVRVU19DT01NQU5EIiwiaXNVbWJyZWxsYUNtZCIsImlzQXBwaXVtRHJpdmVyQ29tbWFuZCIsImlzU2Vzc2lvbkNtZCIsInJlcUZvclByb3h5IiwibGFzdCIsInBvcCIsInBsdWdpbnMiLCJjbWRIYW5kbGVkQnkiLCJkZWZhdWx0IiwiZGVmYXVsdEJlaGF2aW9yIiwibGVuZ3RoIiwicHJveHlDb21tYW5kIiwiTm9Ecml2ZXJQcm94eUNvbW1hbmRFcnJvciIsIm9yaWdpbmFsVXJsIiwibWV0aG9kIiwiYm9keSIsIkJhc2VEcml2ZXIiLCJwcm90b3R5cGUiLCJjYWxsIiwid3JhcHBlZENtZCIsIndyYXBDb21tYW5kV2l0aFBsdWdpbnMiLCJuZXh0IiwicmVzIiwiZXhlY3V0ZVdyYXBwZWRDb21tYW5kIiwibG9nUGx1Z2luSGFuZGxlclJlcG9ydCIsIkNSRUFURV9TRVNTSU9OX0NPTU1BTkQiLCJmaXJzdCIsIl9uZXh0IiwiZGlkSGFuZGxlIiwiayIsImRpZG50SGFuZGxlIiwiY21kUmVzIiwiY21kRXJyIiwiaXNQbGFpbk9iamVjdCIsImhhcyIsInByb3h5QWN0aXZlIiwiZ2V0UHJveHlBdm9pZExpc3QiLCJjYW5Qcm94eSIsIkRFTEVURV9TRVNTSU9OX0NPTU1BTkQiLCJjb2RlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUNBOztBQUNBOztBQUNBOztBQUdBOztBQUNBOztBQUNBOztBQUNBOztBQU1BLE1BQU1BLDRCQUE0QixHQUFHQyxNQUFNLENBQUNDLE1BQVAsQ0FBYztBQUNqREMsRUFBQUEsY0FBYyxFQUFFO0FBQ2RDLElBQUFBLFFBQVEsRUFBRSxJQURJO0FBRWRDLElBQUFBLFFBQVEsRUFBRTtBQUZJLEdBRGlDO0FBS2pEQyxFQUFBQSxZQUFZLEVBQUU7QUFDWkYsSUFBQUEsUUFBUSxFQUFFLElBREU7QUFFWkMsSUFBQUEsUUFBUSxFQUFFO0FBRkU7QUFMbUMsQ0FBZCxDQUFyQztBQVdBLE1BQU1FLGlCQUFpQixHQUFHLElBQUlDLGtCQUFKLEVBQTFCO0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsSUFBSUQsa0JBQUosRUFBNUI7O0FBS0EsTUFBTUUsWUFBTixTQUEyQkMsc0JBQTNCLENBQXNDO0FBT3BDQyxFQUFBQSxRQUFRLEdBQUcsRUFBSDtBQVFSQyxFQUFBQSxjQUFjLEdBQUcsRUFBSDtBQU9kQyxFQUFBQSxtQkFBbUIsR0FBRyxDQUFIO0FBTW5CQyxFQUFBQSxhQUFhLEdBQUcsRUFBSDtBQU1iQyxFQUFBQSxjQUFjLEdBQUcsRUFBSDtBQU1kQyxFQUFBQSxrQkFBa0IsR0FBRyxFQUFIO0FBR2xCQyxFQUFBQSxZQUFZO0FBR1pDLEVBQUFBLE1BQU07O0FBS05DLEVBQUFBLFdBQVcsQ0FBRUMsSUFBRixFQUFRO0FBS2pCLFFBQUlBLElBQUksQ0FBQ0MsTUFBVCxFQUFpQjtBQUNmQyxNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsY0FBWixHQUE2QkosSUFBSSxDQUFDQyxNQUFsQztBQUNEOztBQUVELFVBQU1E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QmpLLFNBQXBCLENBQXJCO0FBQ0Q7O0FBbHFCbUM7Ozs7QUF1cUJ0QyxTQUFTNkgscUJBQVQsQ0FBZ0NULEdBQWhDLEVBQXFDO0FBQ25DLFNBQU8sQ0FBQyxrQ0FBaUJBLEdBQWpCLENBQUQsSUFBMEJBLEdBQUcsS0FBSzhDLGtDQUF6QztBQUNEOztBQU1NLE1BQU0xQix5QkFBTixTQUF3QzlDLEtBQXhDLENBQThDO0FBSW5EeUUsRUFBQUEsSUFBSSxHQUFHLGtDQUFIOztBQUVKekwsRUFBQUEsV0FBVyxHQUFJO0FBQ2IsVUFBTyxxRUFBRCxHQUNDLG1FQURELEdBRUMseUVBRkQsR0FHQyw2REFIUDtBQUlEOztBQVhrRCIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZ2V0QnVpbGRJbmZvLCB1cGRhdGVCdWlsZEluZm8sIEFQUElVTV9WRVIgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBCYXNlRHJpdmVyLCBEcml2ZXJDb3JlLCBlcnJvcnMsIGlzU2Vzc2lvbkNvbW1hbmQsXG4gICAgICAgICBDUkVBVEVfU0VTU0lPTl9DT01NQU5ELCBERUxFVEVfU0VTU0lPTl9DT01NQU5ELCBHRVRfU1RBVFVTX0NPTU1BTkRcbn0gZnJvbSAnQGFwcGl1bS9iYXNlLWRyaXZlcic7XG5pbXBvcnQgQXN5bmNMb2NrIGZyb20gJ2FzeW5jLWxvY2snO1xuaW1wb3J0IHsgcGFyc2VDYXBzRm9ySW5uZXJEcml2ZXIsIHB1bGxTZXR0aW5ncyB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgdXRpbCwgbm9kZSwgbG9nZ2VyIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCB7IGdldERlZmF1bHRzRm9yRXh0ZW5zaW9uIH0gZnJvbSAnLi9zY2hlbWEnO1xuXG4vKipcbiAqIEludmFyaWFudCBzZXQgb2YgYmFzZSBjb25zdHJhaW50c1xuICogQHR5cGUge1JlYWRvbmx5PENvbnN0cmFpbnRzPn1cbiAqL1xuY29uc3QgZGVzaXJlZENhcGFiaWxpdHlDb25zdHJhaW50cyA9IE9iamVjdC5mcmVlemUoe1xuICBhdXRvbWF0aW9uTmFtZToge1xuICAgIHByZXNlbmNlOiB0cnVlLFxuICAgIGlzU3RyaW5nOiB0cnVlLFxuICB9LFxuICBwbGF0Zm9ybU5hbWU6IHtcbiAgICBwcmVzZW5jZTogdHJ1ZSxcbiAgICBpc1N0cmluZzogdHJ1ZSxcbiAgfSxcbn0pO1xuXG5jb25zdCBzZXNzaW9uc0xpc3RHdWFyZCA9IG5ldyBBc3luY0xvY2soKTtcbmNvbnN0IHBlbmRpbmdEcml2ZXJzR3VhcmQgPSBuZXcgQXN5bmNMb2NrKCk7XG5cbi8qKlxuICogQGltcGxlbWVudHMge1Nlc3Npb25IYW5kbGVyfVxuICovXG5jbGFzcyBBcHBpdW1Ecml2ZXIgZXh0ZW5kcyBEcml2ZXJDb3JlIHtcbiAgLyoqXG4gICAqIEFjY2VzcyB0byBzZXNzaW9ucyBsaXN0IG11c3QgYmUgZ3VhcmRlZCB3aXRoIGEgU2VtYXBob3JlLCBiZWNhdXNlXG4gICAqIGl0IG1pZ2h0IGJlIGNoYW5nZWQgYnkgb3RoZXIgYXN5bmMgY2FsbHMgYXQgYW55IHRpbWVcbiAgICogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsRXh0ZXJuYWxEcml2ZXI+fVxuICAgKi9cbiAgc2Vzc2lvbnMgPSB7fTtcblxuICAvKipcbiAgICogQWNjZXNzIHRvIHBlbmRpbmcgZHJpdmVycyBsaXN0IG11c3QgYmUgZ3VhcmRlZCB3aXRoIGEgU2VtYXBob3JlLCBiZWNhdXNlXG4gICAqIGl0IG1pZ2h0IGJlIGNoYW5nZWQgYnkgb3RoZXIgYXN5bmMgY2FsbHMgYXQgYW55IHRpbWVcbiAgICogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFjY2VzcyB0aGlzIHByb3BlcnR5IGRpcmVjdGx5IGZyb20gdGhlIG91dHNpZGVcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsRXh0ZXJuYWxEcml2ZXJbXT59XG4gICAqL1xuICBwZW5kaW5nRHJpdmVycyA9IHt9O1xuXG4gIC8qKlxuICAgKiBOb3RlIHRoYXQge0BsaW5rY29kZSBBcHBpdW1Ecml2ZXJ9IGhhcyBubyBgbmV3Q29tbWFuZFRpbWVvdXRgIG1ldGhvZC5cbiAgICogYEFwcGl1bURyaXZlcmAgZG9lcyBub3Qgc2V0IGFuZCBvYnNlcnZlIGl0cyBvd24gdGltZW91dHM7IGluZGl2aWR1YWxcbiAgICogc2Vzc2lvbnMgKG1hbmFnZWQgZHJpdmVycykgZG8gaW5zdGVhZC5cbiAgICovXG4gIG5ld0NvbW1hbmRUaW1lb3V0TXMgPSAwO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGFjdGl2ZSBwbHVnaW5zXG4gICAqIEB0eXBlIHtQbHVnaW5DbGFzc1tdfVxuICAgKi9cbiAgcGx1Z2luQ2xhc3NlcyA9IFtdO1xuXG4gIC8qKlxuICAgKiBtYXAgb2Ygc2Vzc2lvbnMgdG8gYWN0dWFsIHBsdWdpbiBpbnN0YW5jZXMgcGVyIHNlc3Npb25cbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsSW5zdGFuY2VUeXBlPFBsdWdpbkNsYXNzPltdPn1cbiAgICovXG4gIHNlc3Npb25QbHVnaW5zID0ge307XG5cbiAgLyoqXG4gICAqIHNvbWUgY29tbWFuZHMgYXJlIHNlc3Npb25sZXNzLCBzbyB3ZSBuZWVkIGEgc2V0IG9mIHBsdWdpbnMgZm9yIHRoZW1cbiAgICogQHR5cGUge0luc3RhbmNlVHlwZTxQbHVnaW5DbGFzcz5bXX1cbiAgICovXG4gIHNlc3Npb25sZXNzUGx1Z2lucyA9IFtdOztcblxuICAvKiogQHR5cGUge0RyaXZlckNvbmZpZ30gKi9cbiAgZHJpdmVyQ29uZmlnO1xuXG4gIC8qKiBAdHlwZSB7QXBwaXVtU2VydmVyfSAqL1xuICBzZXJ2ZXI7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RHJpdmVyT3B0c30gb3B0c1xuICAgKi9cbiAgY29uc3RydWN0b3IgKG9wdHMpIHtcbiAgICAvLyBJdCBpcyBuZWNlc3NhcnkgdG8gc2V0IGAtLXRtcGAgaGVyZSBzaW5jZSBpdCBzaG91bGQgYmUgc2V0IHRvXG4gICAgLy8gcHJvY2Vzcy5lbnYuQVBQSVVNX1RNUF9ESVIgb25jZSBhdCBhbiBpbml0aWFsIHBvaW50IGluIHRoZSBBcHBpdW0gbGlmZWN5Y2xlLlxuICAgIC8vIFRoZSBwcm9jZXNzIGFyZ3VtZW50IHdpbGwgYmUgcmVmZXJlbmNlZCBieSBCYXNlRHJpdmVyLlxuICAgIC8vIFBsZWFzZSBjYWxsIEBhcHBpdW0vc3VwcG9ydC50ZW1wRGlyIG1vZHVsZSB0byBhcHBseSB0aGlzIGJlbmVmaXQuXG4gICAgaWYgKG9wdHMudG1wRGlyKSB7XG4gICAgICBwcm9jZXNzLmVudi5BUFBJVU1fVE1QX0RJUiA9IG9wdHMudG1wRGlyO1xuICAgIH1cblxuICAgIHN1cGVyKG9wdHMpO1xuXG4gICAgdGhpcy5kZXNpcmVkQ2FwQ29uc3RyYWludHMgPSBkZXNpcmVkQ2FwYWJpbGl0eUNvbnN0cmFpbnRzO1xuXG4gICAgdGhpcy5hcmdzID0gey4uLm9wdHN9O1xuXG4gICAgLy8gYWxsb3cgdGhpcyB0byBoYXBwZW4gaW4gdGhlIGJhY2tncm91bmQsIHNvIG5vIGBhd2FpdGBcbiAgICAvLyBjYXRjaCB0aGlzIHRvIGF2b2lkIGFuIHVuaGFuZGxlZCByZWplY3Rpb25cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJvbWlzZS9wcmVmZXItYXdhaXQtdG8tdGhlbixwcm9taXNlL3ByZWZlci1hd2FpdC10by1jYWxsYmFja3NcbiAgICB1cGRhdGVCdWlsZEluZm8oKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhlcnIpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBjdXJyZW50IHVtYnJlbGxhIGRyaXZlciBpbnN0YW5jZVxuICAgKi9cbiAgZ2V0IGxvZyAoKSB7XG4gICAgaWYgKCF0aGlzLl9sb2cpIHtcbiAgICAgIGNvbnN0IGluc3RhbmNlTmFtZSA9IGAke3RoaXMuY29uc3RydWN0b3IubmFtZX1AJHtub2RlLmdldE9iamVjdElkKHRoaXMpLnN1YnN0cmluZygwLCA0KX1gO1xuICAgICAgdGhpcy5fbG9nID0gbG9nZ2VyLmdldExvZ2dlcihpbnN0YW5jZU5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbG9nO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbCBjb21tYW5kcyBxdWV1ZWluZyBmb3IgdGhlIHVtYnJlbGxhIEFwcGl1bSBkcml2ZXJcbiAgICovXG4gIGdldCBpc0NvbW1hbmRzUXVldWVFbmFibGVkICgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzZXNzaW9uRXhpc3RzIChzZXNzaW9uSWQpIHtcbiAgICBjb25zdCBkc3RTZXNzaW9uID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgIHJldHVybiBkc3RTZXNzaW9uICYmIGRzdFNlc3Npb24uc2Vzc2lvbklkICE9PSBudWxsO1xuICB9XG5cbiAgZHJpdmVyRm9yU2Vzc2lvbiAoc2Vzc2lvbklkKSB7XG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgfVxuXG4gIGFzeW5jIGdldFN0YXR1cyAoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcmVxdWlyZS1hd2FpdFxuICAgIHJldHVybiB7XG4gICAgICBidWlsZDogXy5jbG9uZShnZXRCdWlsZEluZm8oKSksXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGdldFNlc3Npb25zICgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZXF1aXJlLWF3YWl0XG4gICAgcmV0dXJuIF8udG9QYWlycyh0aGlzLnNlc3Npb25zKVxuICAgICAgLm1hcCgoW2lkLCBkcml2ZXJdKSA9PiAoe2lkLCBjYXBhYmlsaXRpZXM6IGRyaXZlci5jYXBzfSkpO1xuICB9XG5cbiAgcHJpbnROZXdTZXNzaW9uQW5ub3VuY2VtZW50IChkcml2ZXJOYW1lLCBkcml2ZXJWZXJzaW9uLCBkcml2ZXJCYXNlVmVyc2lvbikge1xuICAgIHRoaXMubG9nLmluZm8oZHJpdmVyVmVyc2lvblxuICAgICAgPyBgQXBwaXVtIHYke0FQUElVTV9WRVJ9IGNyZWF0aW5nIG5ldyAke2RyaXZlck5hbWV9ICh2JHtkcml2ZXJWZXJzaW9ufSkgc2Vzc2lvbmBcbiAgICAgIDogYEFwcGl1bSB2JHtBUFBJVU1fVkVSfSBjcmVhdGluZyBuZXcgJHtkcml2ZXJOYW1lfSBzZXNzaW9uYFxuICAgICk7XG4gICAgdGhpcy5sb2cuaW5mbyhgQ2hlY2tpbmcgQmFzZURyaXZlciB2ZXJzaW9ucyBmb3IgQXBwaXVtIGFuZCAke2RyaXZlck5hbWV9YCk7XG4gICAgdGhpcy5sb2cuaW5mbyhBcHBpdW1Ecml2ZXIuYmFzZVZlcnNpb25cbiAgICAgID8gYEFwcGl1bSdzIEJhc2VEcml2ZXIgdmVyc2lvbiBpcyAke0FwcGl1bURyaXZlci5iYXNlVmVyc2lvbn1gXG4gICAgICA6IGBDb3VsZCBub3QgZGV0ZXJtaW5lIEFwcGl1bSdzIEJhc2VEcml2ZXIgdmVyc2lvbmBcbiAgICApO1xuICAgIHRoaXMubG9nLmluZm8oZHJpdmVyQmFzZVZlcnNpb25cbiAgICAgID8gYCR7ZHJpdmVyTmFtZX0ncyBCYXNlRHJpdmVyIHZlcnNpb24gaXMgJHtkcml2ZXJCYXNlVmVyc2lvbn1gXG4gICAgICA6IGBDb3VsZCBub3QgZGV0ZXJtaW5lICR7ZHJpdmVyTmFtZX0ncyBCYXNlRHJpdmVyIHZlcnNpb25gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhbmQgYXNzaWduIENMSSBhcmdzIGZvciBhIGRyaXZlciBvciBwbHVnaW5cbiAgICpcbiAgICogSWYgdGhlIGV4dGVuc2lvbiBoYXMgcHJvdmlkZWQgYSBzY2hlbWEsIHZhbGlkYXRpb24gaGFzIGFscmVhZHkgaGFwcGVuZWQuXG4gICAqXG4gICAqIEFueSBhcmcgd2hpY2ggaXMgZXF1YWwgdG8gaXRzIGRlZmF1bHQgdmFsdWUgd2lsbCBub3QgYmUgYXNzaWduZWQgdG8gdGhlIGV4dGVuc2lvbi5cbiAgICogQHBhcmFtIHtFeHRlbnNpb25UeXBlfSBleHRUeXBlICdkcml2ZXInIG9yICdwbHVnaW4nXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBleHROYW1lIHRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IGV4dEluc3RhbmNlIHRoZSBkcml2ZXIgb3IgcGx1Z2luIGluc3RhbmNlXG4gICAqL1xuICBhc3NpZ25DbGlBcmdzVG9FeHRlbnNpb24gKGV4dFR5cGUsIGV4dE5hbWUsIGV4dEluc3RhbmNlKSB7XG4gICAgY29uc3QgYWxsQ2xpQXJnc0ZvckV4dCA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZyx1bmtub3duPnx1bmRlZmluZWR9ICovKHRoaXMuYXJnc1tleHRUeXBlXT8uW2V4dE5hbWVdKTtcbiAgICBpZiAoIV8uaXNFbXB0eShhbGxDbGlBcmdzRm9yRXh0KSkge1xuICAgICAgY29uc3QgZGVmYXVsdHMgPSBnZXREZWZhdWx0c0ZvckV4dGVuc2lvbihleHRUeXBlLCBleHROYW1lKTtcbiAgICAgIGNvbnN0IGNsaUFyZ3MgPSBfLmlzRW1wdHkoZGVmYXVsdHMpXG4gICAgICAgID8gYWxsQ2xpQXJnc0ZvckV4dFxuICAgICAgICA6IF8ub21pdEJ5KGFsbENsaUFyZ3NGb3JFeHQsICh2YWx1ZSwga2V5KSA9PiBfLmlzRXF1YWwoZGVmYXVsdHNba2V5XSwgdmFsdWUpKTtcbiAgICAgIGlmICghXy5pc0VtcHR5KGNsaUFyZ3MpKSB7XG4gICAgICAgIGV4dEluc3RhbmNlLmNsaUFyZ3MgPSBjbGlBcmdzO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgc2Vzc2lvblxuICAgKiBAcGFyYW0ge1czQ0NhcGFiaWxpdGllc30ganNvbndwQ2FwcyBKU09OV1AgZm9ybWF0dGVkIGRlc2lyZWQgY2FwYWJpbGl0aWVzXG4gICAqIEBwYXJhbSB7VzNDQ2FwYWJpbGl0aWVzfSByZXFDYXBzIFJlcXVpcmVkIGNhcGFiaWxpdGllcyAoSlNPTldQIHN0YW5kYXJkKVxuICAgKiBAcGFyYW0ge1czQ0NhcGFiaWxpdGllc30gdzNjQ2FwYWJpbGl0aWVzIFczQyBjYXBhYmlsaXRpZXNcbiAgICogQHBhcmFtIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJEYXRhW119IFtkcml2ZXJEYXRhXVxuICAgKi9cbiAgYXN5bmMgY3JlYXRlU2Vzc2lvbiAoanNvbndwQ2FwcywgcmVxQ2FwcywgdzNjQ2FwYWJpbGl0aWVzLCBkcml2ZXJEYXRhKSB7XG4gICAgY29uc3QgZGVmYXVsdENhcGFiaWxpdGllcyA9IF8uY2xvbmVEZWVwKHRoaXMuYXJncy5kZWZhdWx0Q2FwYWJpbGl0aWVzKTtcbiAgICBjb25zdCBkZWZhdWx0U2V0dGluZ3MgPSBwdWxsU2V0dGluZ3MoZGVmYXVsdENhcGFiaWxpdGllcyk7XG4gICAganNvbndwQ2FwcyA9IF8uY2xvbmVEZWVwKGpzb253cENhcHMpO1xuICAgIGNvbnN0IGp3cFNldHRpbmdzID0gey4uLmRlZmF1bHRTZXR0aW5ncywgLi4ucHVsbFNldHRpbmdzKGpzb253cENhcHMpfTtcbiAgICB3M2NDYXBhYmlsaXRpZXMgPSBfLmNsb25lRGVlcCh3M2NDYXBhYmlsaXRpZXMpO1xuICAgIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIGNsaWVudCBvbmx5IHByb3ZpZGVzIGNhcHMgdXNpbmcgSlNPTldQIHN0YW5kYXJkLFxuICAgIC8vIGFsdGhvdWdoIGZpcnN0TWF0Y2gvYWx3YXlzTWF0Y2ggcHJvcGVydGllcyBhcmUgc3RpbGwgcHJlc2VudC5cbiAgICAvLyBJbiBzdWNoIGNhc2Ugd2UgYXNzdW1lIHRoZSBjbGllbnQgdW5kZXJzdGFuZHMgVzNDIHByb3RvY29sIGFuZCBtZXJnZSB0aGUgZ2l2ZW5cbiAgICAvLyBKU09OV1AgY2FwcyB0byBXM0MgY2Fwc1xuICAgIGNvbnN0IHczY1NldHRpbmdzID0ge1xuICAgICAgLi4uandwU2V0dGluZ3MsXG4gICAgICAuLi5wdWxsU2V0dGluZ3MoKHczY0NhcGFiaWxpdGllcyA/PyB7fSkuYWx3YXlzTWF0Y2ggPz8ge30pXG4gICAgfTtcbiAgICBmb3IgKGNvbnN0IGZpcnN0TWF0Y2hFbnRyeSBvZiAoKHczY0NhcGFiaWxpdGllcyA/PyB7fSkuZmlyc3RNYXRjaCA/PyBbXSkpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24odzNjU2V0dGluZ3MsIHB1bGxTZXR0aW5ncyhmaXJzdE1hdGNoRW50cnkpKTtcbiAgICB9XG5cbiAgICBsZXQgcHJvdG9jb2w7XG4gICAgbGV0IGlubmVyU2Vzc2lvbklkLCBkQ2FwcztcbiAgICB0cnkge1xuICAgICAgLy8gUGFyc2UgdGhlIGNhcHMgaW50byBhIGZvcm1hdCB0aGF0IHRoZSBJbm5lckRyaXZlciB3aWxsIGFjY2VwdFxuICAgICAgY29uc3QgcGFyc2VkQ2FwcyA9IHBhcnNlQ2Fwc0ZvcklubmVyRHJpdmVyKFxuICAgICAgICBqc29ud3BDYXBzLFxuICAgICAgICB3M2NDYXBhYmlsaXRpZXMsXG4gICAgICAgIHRoaXMuZGVzaXJlZENhcENvbnN0cmFpbnRzLFxuICAgICAgICBkZWZhdWx0Q2FwYWJpbGl0aWVzXG4gICAgICApO1xuXG4gICAgICBjb25zdCB7ZGVzaXJlZENhcHMsIHByb2Nlc3NlZEpzb253cENhcGFiaWxpdGllcywgcHJvY2Vzc2VkVzNDQ2FwYWJpbGl0aWVzfSA9IC8qKiBAdHlwZSB7aW1wb3J0KCcuL3V0aWxzJykuUGFyc2VkRHJpdmVyQ2Fwc30gKi8ocGFyc2VkQ2Fwcyk7XG4gICAgICBwcm90b2NvbCA9IHBhcnNlZENhcHMucHJvdG9jb2w7XG4gICAgICBjb25zdCBlcnJvciA9IC8qKiBAdHlwZSB7aW1wb3J0KCcuL3V0aWxzJykuSW52YWxpZENhcHN9ICovKHBhcnNlZENhcHMpLmVycm9yO1xuICAgICAgLy8gSWYgdGhlIHBhcnNpbmcgb2YgdGhlIGNhcHMgcHJvZHVjZWQgYW4gZXJyb3IsIHRocm93IGl0IGluIGhlcmVcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgY29uc3Qge1xuICAgICAgICBkcml2ZXI6IElubmVyRHJpdmVyLFxuICAgICAgICB2ZXJzaW9uOiBkcml2ZXJWZXJzaW9uLFxuICAgICAgICBkcml2ZXJOYW1lXG4gICAgICB9ID0gdGhpcy5kcml2ZXJDb25maWcuZmluZE1hdGNoaW5nRHJpdmVyKGRlc2lyZWRDYXBzKTtcbiAgICAgIHRoaXMucHJpbnROZXdTZXNzaW9uQW5ub3VuY2VtZW50KElubmVyRHJpdmVyLm5hbWUsIGRyaXZlclZlcnNpb24sIElubmVyRHJpdmVyLmJhc2VWZXJzaW9uKTtcblxuICAgICAgaWYgKHRoaXMuYXJncy5zZXNzaW9uT3ZlcnJpZGUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5kZWxldGVBbGxTZXNzaW9ucygpO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIEB0eXBlIHtEcml2ZXJEYXRhW119XG4gICAgICAgKi9cbiAgICAgIGxldCBydW5uaW5nRHJpdmVyc0RhdGEgPSBbXTtcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge0RyaXZlckRhdGFbXX1cbiAgICAgICAqL1xuICAgICAgbGV0IG90aGVyUGVuZGluZ0RyaXZlcnNEYXRhID0gW107XG5cbiAgICAgIGNvbnN0IGRyaXZlckluc3RhbmNlID0gbmV3IElubmVyRHJpdmVyKHRoaXMuYXJncywgdHJ1ZSk7XG5cbiAgICAgIC8vIFdlIHdhbnQgdG8gYXNzaWduIHNlY3VyaXR5IHZhbHVlcyBkaXJlY3RseSBvbiB0aGUgZHJpdmVyLiBUaGUgZHJpdmVyXG4gICAgICAvLyBzaG91bGQgbm90IHJlYWQgc2VjdXJpdHkgdmFsdWVzIGZyb20gYHRoaXMub3B0c2AgYmVjYXVzZSB0aG9zZSB2YWx1ZXNcbiAgICAgIC8vIGNvdWxkIGhhdmUgYmVlbiBzZXQgYnkgYSBtYWxpY2lvdXMgdXNlciB2aWEgY2FwYWJpbGl0aWVzLCB3aGVyZWFzIHdlXG4gICAgICAvLyB3YW50IGEgZ3VhcmFudGVlIHRoZSB2YWx1ZXMgd2VyZSBzZXQgYnkgdGhlIGFwcGl1bSBzZXJ2ZXIgYWRtaW5cbiAgICAgIGlmICh0aGlzLmFyZ3MucmVsYXhlZFNlY3VyaXR5RW5hYmxlZCkge1xuICAgICAgICB0aGlzLmxvZy5pbmZvKGBBcHBseWluZyByZWxheGVkIHNlY3VyaXR5IHRvICcke0lubmVyRHJpdmVyLm5hbWV9JyBhcyBwZXIgYCArXG4gICAgICAgICAgYHNlcnZlciBjb21tYW5kIGxpbmUgYXJndW1lbnQuIEFsbCBpbnNlY3VyZSBmZWF0dXJlcyB3aWxsIGJlIGAgK1xuICAgICAgICAgIGBlbmFibGVkIHVubGVzcyBleHBsaWNpdGx5IGRpc2FibGVkIGJ5IC0tZGVueS1pbnNlY3VyZWApO1xuICAgICAgICBkcml2ZXJJbnN0YW5jZS5yZWxheGVkU2VjdXJpdHlFbmFibGVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzRW1wdHkodGhpcy5hcmdzLmRlbnlJbnNlY3VyZSkpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbygnRXhwbGljaXRseSBwcmV2ZW50aW5nIHVzZSBvZiBpbnNlY3VyZSBmZWF0dXJlczonKTtcbiAgICAgICAgdGhpcy5hcmdzLmRlbnlJbnNlY3VyZS5tYXAoKGEpID0+IHRoaXMubG9nLmluZm8oYCAgICAke2F9YCkpO1xuICAgICAgICBkcml2ZXJJbnN0YW5jZS5kZW55SW5zZWN1cmUgPSB0aGlzLmFyZ3MuZGVueUluc2VjdXJlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIV8uaXNFbXB0eSh0aGlzLmFyZ3MuYWxsb3dJbnNlY3VyZSkpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbygnRXhwbGljaXRseSBlbmFibGluZyB1c2Ugb2YgaW5zZWN1cmUgZmVhdHVyZXM6Jyk7XG4gICAgICAgIHRoaXMuYXJncy5hbGxvd0luc2VjdXJlLm1hcCgoYSkgPT4gdGhpcy5sb2cuaW5mbyhgICAgICR7YX1gKSk7XG4gICAgICAgIGRyaXZlckluc3RhbmNlLmFsbG93SW5zZWN1cmUgPSB0aGlzLmFyZ3MuYWxsb3dJbnNlY3VyZTtcbiAgICAgIH1cblxuICAgICAgLy8gTGlrZXdpc2UsIGFueSBkcml2ZXItc3BlY2lmaWMgQ0xJIGFyZ3MgdGhhdCB3ZXJlIHBhc3NlZCBpbiBzaG91bGQgYmUgYXNzaWduZWQgZGlyZWN0bHkgdG9cbiAgICAgIC8vIHRoZSBkcml2ZXIgc28gdGhhdCB0aGV5IGNhbm5vdCBiZSBtaW1pY2tlZCBieSBhIG1hbGljaW91cyB1c2VyIHNlbmRpbmcgaW4gY2FwYWJpbGl0aWVzXG4gICAgICB0aGlzLmFzc2lnbkNsaUFyZ3NUb0V4dGVuc2lvbignZHJpdmVyJywgZHJpdmVyTmFtZSwgZHJpdmVySW5zdGFuY2UpO1xuXG5cbiAgICAgIC8vIFRoaXMgYXNzaWdubWVudCBpcyByZXF1aXJlZCBmb3IgY29ycmVjdCB3ZWIgc29ja2V0cyBmdW5jdGlvbmFsaXR5IGluc2lkZSB0aGUgZHJpdmVyXG4gICAgICAvLyBEcml2ZXJzL3BsdWdpbnMgbWlnaHQgYWxzbyB3YW50IHRvIGtub3cgd2hlcmUgdGhleSBhcmUgaG9zdGVkXG4gICAgICBkcml2ZXJJbnN0YW5jZS5hc3NpZ25TZXJ2ZXIodGhpcy5zZXJ2ZXIsIHRoaXMuYXJncy5hZGRyZXNzLCB0aGlzLmFyZ3MucG9ydCwgdGhpcy5hcmdzLmJhc2VQYXRoKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcnVubmluZ0RyaXZlcnNEYXRhID0gYXdhaXQgdGhpcy5jdXJTZXNzaW9uRGF0YUZvckRyaXZlcihJbm5lckRyaXZlcikgPz8gW107XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBlcnJvcnMuU2Vzc2lvbk5vdENyZWF0ZWRFcnJvcihlLm1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgYXdhaXQgcGVuZGluZ0RyaXZlcnNHdWFyZC5hY3F1aXJlKEFwcGl1bURyaXZlci5uYW1lLCAoKSA9PiB7XG4gICAgICAgIHRoaXMucGVuZGluZ0RyaXZlcnNbSW5uZXJEcml2ZXIubmFtZV0gPSB0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdIHx8IFtdO1xuICAgICAgICBvdGhlclBlbmRpbmdEcml2ZXJzRGF0YSA9IF8uY29tcGFjdCh0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdLm1hcCgoZHJ2KSA9PiBkcnYuZHJpdmVyRGF0YSkpO1xuICAgICAgICB0aGlzLnBlbmRpbmdEcml2ZXJzW0lubmVyRHJpdmVyLm5hbWVdLnB1c2goZHJpdmVySW5zdGFuY2UpO1xuICAgICAgfSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIFtpbm5lclNlc3Npb25JZCwgZENhcHNdID0gYXdhaXQgZHJpdmVySW5zdGFuY2UuY3JlYXRlU2Vzc2lvbihcbiAgICAgICAgICBwcm9jZXNzZWRKc29ud3BDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgcmVxQ2FwcyxcbiAgICAgICAgICBwcm9jZXNzZWRXM0NDYXBhYmlsaXRpZXMsXG4gICAgICAgICAgWy4uLnJ1bm5pbmdEcml2ZXJzRGF0YSwgLi4ub3RoZXJQZW5kaW5nRHJpdmVyc0RhdGFdXG4gICAgICAgICk7XG4gICAgICAgIHByb3RvY29sID0gZHJpdmVySW5zdGFuY2UucHJvdG9jb2w7XG4gICAgICAgIHRoaXMuc2Vzc2lvbnNbaW5uZXJTZXNzaW9uSWRdID0gZHJpdmVySW5zdGFuY2U7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBwZW5kaW5nRHJpdmVyc0d1YXJkLmFjcXVpcmUoQXBwaXVtRHJpdmVyLm5hbWUsICgpID0+IHtcbiAgICAgICAgICBfLnB1bGwodGhpcy5wZW5kaW5nRHJpdmVyc1tJbm5lckRyaXZlci5uYW1lXSwgZHJpdmVySW5zdGFuY2UpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hdHRhY2hVbmV4cGVjdGVkU2h1dGRvd25IYW5kbGVyKGRyaXZlckluc3RhbmNlLCBpbm5lclNlc3Npb25JZCk7XG5cbiAgICAgIHRoaXMubG9nLmluZm8oYE5ldyAke0lubmVyRHJpdmVyLm5hbWV9IHNlc3Npb24gY3JlYXRlZCBzdWNjZXNzZnVsbHksIHNlc3Npb24gYCArXG4gICAgICAgIGAke2lubmVyU2Vzc2lvbklkfSBhZGRlZCB0byBtYXN0ZXIgc2Vzc2lvbiBsaXN0YCk7XG5cbiAgICAgIC8vIHNldCB0aGUgTmV3IENvbW1hbmQgVGltZW91dCBmb3IgdGhlIGlubmVyIGRyaXZlclxuICAgICAgZHJpdmVySW5zdGFuY2Uuc3RhcnROZXdDb21tYW5kVGltZW91dCgpO1xuXG4gICAgICAvLyBhcHBseSBpbml0aWFsIHZhbHVlcyB0byBBcHBpdW0gc2V0dGluZ3MgKGlmIHByb3ZpZGVkKVxuICAgICAgaWYgKGRyaXZlckluc3RhbmNlLmlzVzNDUHJvdG9jb2woKSAmJiAhXy5pc0VtcHR5KHczY1NldHRpbmdzKSkge1xuICAgICAgICB0aGlzLmxvZy5pbmZvKGBBcHBseWluZyB0aGUgaW5pdGlhbCB2YWx1ZXMgdG8gQXBwaXVtIHNldHRpbmdzIHBhcnNlZCBmcm9tIFczQyBjYXBzOiBgICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh3M2NTZXR0aW5ncykpO1xuICAgICAgICBhd2FpdCBkcml2ZXJJbnN0YW5jZS51cGRhdGVTZXR0aW5ncyh3M2NTZXR0aW5ncyk7XG4gICAgICB9IGVsc2UgaWYgKGRyaXZlckluc3RhbmNlLmlzTWpzb253cFByb3RvY29sKCkgJiYgIV8uaXNFbXB0eShqd3BTZXR0aW5ncykpIHtcbiAgICAgICAgdGhpcy5sb2cuaW5mbyhgQXBwbHlpbmcgdGhlIGluaXRpYWwgdmFsdWVzIHRvIEFwcGl1bSBzZXR0aW5ncyBwYXJzZWQgZnJvbSBNSlNPTldQIGNhcHM6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGp3cFNldHRpbmdzKSk7XG4gICAgICAgIGF3YWl0IGRyaXZlckluc3RhbmNlLnVwZGF0ZVNldHRpbmdzKGp3cFNldHRpbmdzKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHJvdG9jb2wsXG4gICAgICAgIGVycm9yLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJvdG9jb2wsXG4gICAgICB2YWx1ZTogW2lubmVyU2Vzc2lvbklkLCBkQ2FwcywgcHJvdG9jb2xdXG4gICAgfTtcbiAgfVxuXG4gIGF0dGFjaFVuZXhwZWN0ZWRTaHV0ZG93bkhhbmRsZXIgKGRyaXZlciwgaW5uZXJTZXNzaW9uSWQpIHtcbiAgICBjb25zdCBvblNodXRkb3duID0gKGNhdXNlID0gbmV3IEVycm9yKCdVbmtub3duIGVycm9yJykpID0+IHtcbiAgICAgIHRoaXMubG9nLndhcm4oYEVuZGluZyBzZXNzaW9uLCBjYXVzZSB3YXMgJyR7Y2F1c2UubWVzc2FnZX0nYCk7XG5cbiAgICAgIGlmICh0aGlzLnNlc3Npb25QbHVnaW5zW2lubmVyU2Vzc2lvbklkXSkge1xuICAgICAgICBmb3IgKGNvbnN0IHBsdWdpbiBvZiB0aGlzLnNlc3Npb25QbHVnaW5zW2lubmVyU2Vzc2lvbklkXSkge1xuICAgICAgICAgIGlmIChfLmlzRnVuY3Rpb24ocGx1Z2luLm9uVW5leHBlY3RlZFNodXRkb3duKSkge1xuICAgICAgICAgICAgdGhpcy5sb2cuZGVidWcoYFBsdWdpbiAke3BsdWdpbi5uYW1lfSBkZWZpbmVzIGFuIHVuZXhwZWN0ZWQgc2h1dGRvd24gaGFuZGxlcjsgY2FsbGluZyBpdCBub3dgKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHBsdWdpbi5vblVuZXhwZWN0ZWRTaHV0ZG93bihkcml2ZXIsIGNhdXNlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgdGhpcy5sb2cud2FybihgR290IGFuIGVycm9yIHdoZW4gcnVubmluZyBwbHVnaW4gJHtwbHVnaW4ubmFtZX0gc2h1dGRvd24gaGFuZGxlcjogJHtlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgUGx1Z2luICR7cGx1Z2luLm5hbWV9IGRvZXMgbm90IGRlZmluZSBhbiB1bmV4cGVjdGVkIHNodXRkb3duIGhhbmRsZXJgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2cuaW5mbyhgUmVtb3Zpbmcgc2Vzc2lvbiAnJHtpbm5lclNlc3Npb25JZH0nIGZyb20gb3VyIG1hc3RlciBzZXNzaW9uIGxpc3RgKTtcbiAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25zW2lubmVyU2Vzc2lvbklkXTtcbiAgICAgIGRlbGV0ZSB0aGlzLnNlc3Npb25QbHVnaW5zW2lubmVyU2Vzc2lvbklkXTtcbiAgICB9O1xuXG4gICAgaWYgKF8uaXNGdW5jdGlvbihkcml2ZXIub25VbmV4cGVjdGVkU2h1dGRvd24pKSB7XG4gICAgICBkcml2ZXIub25VbmV4cGVjdGVkU2h1dGRvd24ob25TaHV0ZG93bik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLndhcm4oYEZhaWxlZCB0byBhdHRhY2ggdGhlIHVuZXhwZWN0ZWQgc2h1dGRvd24gbGlzdGVuZXIuIGAgK1xuICAgICAgICBgSXMgJ29uVW5leHBlY3RlZFNodXRkb3duJyBtZXRob2QgYXZhaWxhYmxlIGZvciAnJHtkcml2ZXIuY29uc3RydWN0b3IubmFtZX0nP2ApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydCgnLi4vdHlwZXMvZXh0ZW5zaW9uJykuRHJpdmVyQ2xhc3N9IElubmVyRHJpdmVyXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPERyaXZlckRhdGFbXT59fVxuICAgKi9cbiAgYXN5bmMgY3VyU2Vzc2lvbkRhdGFGb3JEcml2ZXIgKElubmVyRHJpdmVyKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcmVxdWlyZS1hd2FpdFxuICAgIGNvbnN0IGRhdGEgPSBfLmNvbXBhY3QoXy52YWx1ZXModGhpcy5zZXNzaW9ucylcbiAgICAgIC5maWx0ZXIoKHMpID0+IHMuY29uc3RydWN0b3IubmFtZSA9PT0gSW5uZXJEcml2ZXIubmFtZSlcbiAgICAgIC5tYXAoKHMpID0+IHMuZHJpdmVyRGF0YSkpO1xuICAgIGZvciAoY29uc3QgZGF0dW0gb2YgZGF0YSkge1xuICAgICAgaWYgKCFkYXR1bSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFByb2JsZW0gZ2V0dGluZyBzZXNzaW9uIGRhdGEgZm9yIGRyaXZlciB0eXBlIGAgK1xuICAgICAgICAgIGAke0lubmVyRHJpdmVyLm5hbWV9OyBkb2VzIGl0IGltcGxlbWVudCAnZ2V0IGRyaXZlckRhdGEnP2ApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2Vzc2lvbklkXG4gICAqL1xuICBhc3luYyBkZWxldGVTZXNzaW9uIChzZXNzaW9uSWQpIHtcbiAgICBsZXQgcHJvdG9jb2w7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBvdGhlclNlc3Npb25zRGF0YTtcbiAgICAgIGNvbnN0IGRzdFNlc3Npb24gPSBhd2FpdCBzZXNzaW9uc0xpc3RHdWFyZC5hY3F1aXJlKEFwcGl1bURyaXZlci5uYW1lLCAoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGN1ckNvbnN0cnVjdG9yTmFtZSA9IHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXS5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICBvdGhlclNlc3Npb25zRGF0YSA9IF8udG9QYWlycyh0aGlzLnNlc3Npb25zKVxuICAgICAgICAgICAgICAuZmlsdGVyKChba2V5LCB2YWx1ZV0pID0+IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUgPT09IGN1ckNvbnN0cnVjdG9yTmFtZSAmJiBrZXkgIT09IHNlc3Npb25JZClcbiAgICAgICAgICAgICAgLm1hcCgoWywgdmFsdWVdKSA9PiB2YWx1ZS5kcml2ZXJEYXRhKTtcbiAgICAgICAgY29uc3QgZHN0U2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgICAgICAgcHJvdG9jb2wgPSBkc3RTZXNzaW9uLnByb3RvY29sO1xuICAgICAgICB0aGlzLmxvZy5pbmZvKGBSZW1vdmluZyBzZXNzaW9uICR7c2Vzc2lvbklkfSBmcm9tIG91ciBtYXN0ZXIgc2Vzc2lvbiBsaXN0YCk7XG4gICAgICAgIC8vIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgZGVsZXRlU2Vzc2lvbiBjb21wbGV0ZXMgc3VjY2Vzc2Z1bGx5IG9yIG5vdFxuICAgICAgICAvLyBtYWtlIHRoZSBzZXNzaW9uIHVuYXZhaWxhYmxlLCBiZWNhdXNlIHdobyBrbm93cyB3aGF0IHN0YXRlIGl0IG1pZ2h0XG4gICAgICAgIC8vIGJlIGluIG90aGVyd2lzZVxuICAgICAgICBkZWxldGUgdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgICAgICBkZWxldGUgdGhpcy5zZXNzaW9uUGx1Z2luc1tzZXNzaW9uSWRdO1xuICAgICAgICByZXR1cm4gZHN0U2Vzc2lvbjtcbiAgICAgIH0pO1xuICAgICAgLy8gdGhpcyBtYXkgbm90IGJlIGNvcnJlY3QsIGJ1dCBpZiBgZHN0U2Vzc2lvbmAgd2FzIGZhbHN5LCB0aGUgY2FsbCB0byBgZGVsZXRlU2Vzc2lvbigpYCB3b3VsZFxuICAgICAgLy8gdGhyb3cgYW55d2F5LlxuICAgICAgaWYgKCFkc3RTZXNzaW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2Vzc2lvbiBub3QgZm91bmQnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByb3RvY29sLFxuICAgICAgICB2YWx1ZTogYXdhaXQgZHN0U2Vzc2lvbi5kZWxldGVTZXNzaW9uKHNlc3Npb25JZCwgb3RoZXJTZXNzaW9uc0RhdGEpLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy5lcnJvcihgSGFkIHRyb3VibGUgZW5kaW5nIHNlc3Npb24gJHtzZXNzaW9uSWR9OiAke2UubWVzc2FnZX1gKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByb3RvY29sLFxuICAgICAgICBlcnJvcjogZSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGVsZXRlQWxsU2Vzc2lvbnMgKG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IHNlc3Npb25zQ291bnQgPSBfLnNpemUodGhpcy5zZXNzaW9ucyk7XG4gICAgaWYgKDAgPT09IHNlc3Npb25zQ291bnQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKCdUaGVyZSBhcmUgbm8gYWN0aXZlIHNlc3Npb25zIGZvciBjbGVhbnVwJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qge1xuICAgICAgZm9yY2UgPSBmYWxzZSxcbiAgICAgIHJlYXNvbixcbiAgICB9ID0gb3B0cztcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgQ2xlYW5pbmcgdXAgJHt1dGlsLnBsdXJhbGl6ZSgnYWN0aXZlIHNlc3Npb24nLCBzZXNzaW9uc0NvdW50LCB0cnVlKX1gKTtcbiAgICBjb25zdCBjbGVhbnVwUHJvbWlzZXMgPSBmb3JjZVxuICAgICAgPyBfLnZhbHVlcyh0aGlzLnNlc3Npb25zKS5tYXAoKGRydikgPT4gZHJ2LnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKHJlYXNvbiAmJiBuZXcgRXJyb3IocmVhc29uKSkpXG4gICAgICA6IF8ua2V5cyh0aGlzLnNlc3Npb25zKS5tYXAoKGlkKSA9PiB0aGlzLmRlbGV0ZVNlc3Npb24oaWQpKTtcbiAgICBmb3IgKGNvbnN0IGNsZWFudXBQcm9taXNlIG9mIGNsZWFudXBQcm9taXNlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY2xlYW51cFByb21pc2U7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGFwcHJvcHJpYXRlIHBsdWdpbnMgZm9yIGEgc2Vzc2lvbiAob3Igc2Vzc2lvbmxlc3MgcGx1Z2lucylcbiAgICpcbiAgICogQHBhcmFtIHs/c3RyaW5nfSBzZXNzaW9uSWQgLSB0aGUgc2Vzc2lvbklkIChvciBudWxsKSB0byB1c2UgdG8gZmluZCBwbHVnaW5zXG4gICAqIEByZXR1cm5zIHtBcnJheX0gLSBhcnJheSBvZiBwbHVnaW4gaW5zdGFuY2VzXG4gICAqL1xuICBwbHVnaW5zRm9yU2Vzc2lvbiAoc2Vzc2lvbklkID0gbnVsbCkge1xuICAgIGlmIChzZXNzaW9uSWQpIHtcbiAgICAgIGlmICghdGhpcy5zZXNzaW9uUGx1Z2luc1tzZXNzaW9uSWRdKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvblBsdWdpbnNbc2Vzc2lvbklkXSA9IHRoaXMuY3JlYXRlUGx1Z2luSW5zdGFuY2VzKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZXNzaW9uUGx1Z2luc1tzZXNzaW9uSWRdO1xuICAgIH1cblxuICAgIGlmIChfLmlzRW1wdHkodGhpcy5zZXNzaW9ubGVzc1BsdWdpbnMpKSB7XG4gICAgICB0aGlzLnNlc3Npb25sZXNzUGx1Z2lucyA9IHRoaXMuY3JlYXRlUGx1Z2luSW5zdGFuY2VzKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlc3Npb25sZXNzUGx1Z2lucztcbiAgfVxuXG4gIC8qKlxuICAgKiBUbyBnZXQgcGx1Z2lucyBmb3IgYSBjb21tYW5kLCB3ZSBlaXRoZXIgZ2V0IHRoZSBwbHVnaW4gaW5zdGFuY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGVcbiAgICogcGFydGljdWxhciBjb21tYW5kJ3Mgc2Vzc2lvbiwgb3IgaW4gdGhlIGNhc2Ugb2Ygc2Vzc2lvbmxlc3MgcGx1Z2lucywgcHVsbCBmcm9tIHRoZSBzZXQgb2ZcbiAgICogcGx1Z2luIGluc3RhbmNlcyByZXNlcnZlZCBmb3Igc2Vzc2lvbmxlc3MgY29tbWFuZHMgKGFuZCB3ZSBsYXppbHkgY3JlYXRlIHBsdWdpbiBpbnN0YW5jZXMgb25cbiAgICogZmlyc3QgdXNlKVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY21kIC0gdGhlIG5hbWUgb2YgdGhlIGNvbW1hbmQgdG8gZmluZCBhIHBsdWdpbiB0byBoYW5kbGVcbiAgICogQHBhcmFtIHs/c3RyaW5nfSBzZXNzaW9uSWQgLSB0aGUgcGFydGljdWxhciBzZXNzaW9uIGZvciB3aGljaCB0byBmaW5kIGEgcGx1Z2luLCBvciBudWxsIGlmXG4gICAqIHNlc3Npb25sZXNzXG4gICAqL1xuICBwbHVnaW5zVG9IYW5kbGVDbWQgKGNtZCwgc2Vzc2lvbklkID0gbnVsbCkge1xuICAgIC8vIHRvIGhhbmRsZSBhIGdpdmVuIGNvbW1hbmQsIGEgcGx1Z2luIHNob3VsZCBlaXRoZXIgaW1wbGVtZW50IHRoYXQgY29tbWFuZCBhcyBhIHBsdWdpblxuICAgIC8vIGluc3RhbmNlIG1ldGhvZCBvciBpdCBzaG91bGQgaW1wbGVtZW50IGEgZ2VuZXJpYyAnaGFuZGxlJyBtZXRob2RcbiAgICByZXR1cm4gdGhpcy5wbHVnaW5zRm9yU2Vzc2lvbihzZXNzaW9uSWQpXG4gICAgICAuZmlsdGVyKChwKSA9PiBfLmlzRnVuY3Rpb24ocFtjbWRdKSB8fCBfLmlzRnVuY3Rpb24ocC5oYW5kbGUpKTtcbiAgfVxuXG4gIGNyZWF0ZVBsdWdpbkluc3RhbmNlcyAoKSB7XG4gICAgcmV0dXJuIHRoaXMucGx1Z2luQ2xhc3Nlcy5tYXAoKFBsdWdpbkNsYXNzKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gUGx1Z2luQ2xhc3MucGx1Z2luTmFtZTtcbiAgICAgIGNvbnN0IHBsdWdpbiA9IG5ldyBQbHVnaW5DbGFzcyhuYW1lKTtcbiAgICAgIHRoaXMuYXNzaWduQ2xpQXJnc1RvRXh0ZW5zaW9uKCdwbHVnaW4nLCBuYW1lLCBwbHVnaW4pO1xuICAgICAgcmV0dXJuIHBsdWdpbjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY21kXG4gICAqIEBwYXJhbSAgey4uLmFueX0gYXJnc1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7dmFsdWU6IGFueSwgZXJyb3I/OiBFcnJvciwgcHJvdG9jb2w6IHN0cmluZ30gfCBpbXBvcnQoJ3R5cGUtZmVzdCcpLkFzeW5jUmV0dXJuVHlwZTxpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJbJ2V4ZWN1dGVDb21tYW5kJ10+Pn1cbiAgICovXG4gIGFzeW5jIGV4ZWN1dGVDb21tYW5kIChjbWQsIC4uLmFyZ3MpIHtcbiAgICAvLyBXZSBoYXZlIGJhc2ljYWxseSB0aHJlZSBjYXNlcyBmb3IgaG93IHRvIGhhbmRsZSBjb21tYW5kczpcbiAgICAvLyAxLiBoYW5kbGUgZ2V0U3RhdHVzICh3ZSBkbyB0aGlzIGFzIGEgc3BlY2lhbCBvdXQgb2YgYmFuZCBjYXNlIHNvIGl0IGRvZXNuJ3QgZ2V0IGFkZGVkIHRvIGFuXG4gICAgLy8gICAgZXhlY3V0aW9uIHF1ZXVlLCBhbmQgY2FuIGJlIGNhbGxlZCB3aGlsZSBlLmcuIGNyZWF0ZVNlc3Npb24gaXMgaW4gcHJvZ3Jlc3MpXG4gICAgLy8gMi4gaGFuZGxlIGNvbW1hbmRzIHRoYXQgdGhpcyB1bWJyZWxsYSBkcml2ZXIgc2hvdWxkIGhhbmRsZSwgcmF0aGVyIHRoYW4gdGhlIGFjdHVhbCBzZXNzaW9uXG4gICAgLy8gICAgZHJpdmVyIChmb3IgZXhhbXBsZSwgZGVsZXRlU2Vzc2lvbiwgb3Igb3RoZXIgbm9uLXNlc3Npb24gY29tbWFuZHMpXG4gICAgLy8gMy4gaGFuZGxlIHNlc3Npb24gZHJpdmVyIGNvbW1hbmRzLlxuICAgIC8vIFRoZSB0cmlja3kgcGFydCBpcyB0aGF0IGJlY2F1c2Ugd2Ugc3VwcG9ydCBjb21tYW5kIHBsdWdpbnMsIHdlIG5lZWQgdG8gd3JhcCBhbnkgb2YgdGhlc2VcbiAgICAvLyBjYXNlcyB3aXRoIHBsdWdpbiBoYW5kbGluZy5cblxuICAgIGNvbnN0IGlzR2V0U3RhdHVzID0gY21kID09PSBHRVRfU1RBVFVTX0NPTU1BTkQ7XG4gICAgY29uc3QgaXNVbWJyZWxsYUNtZCA9IGlzQXBwaXVtRHJpdmVyQ29tbWFuZChjbWQpO1xuICAgIGNvbnN0IGlzU2Vzc2lvbkNtZCA9IGlzU2Vzc2lvbkNvbW1hbmQoY21kKTtcblxuICAgIC8vIGlmIGEgcGx1Z2luIG92ZXJyaWRlIHByb3h5aW5nIGZvciB0aGlzIGNvbW1hbmQgYW5kIHRoYXQgaXMgd2h5IHdlIGFyZSBoZXJlIGluc3RlYWQgb2YganVzdFxuICAgIC8vIGxldHRpbmcgdGhlIHByb3RvY29sIHByb3h5IHRoZSBjb21tYW5kIGVudGlyZWx5LCBkZXRlcm1pbmUgdGhhdCwgZ2V0IHRoZSByZXF1ZXN0IG9iamVjdCBmb3JcbiAgICAvLyB1c2UgbGF0ZXIgb24sIHRoZW4gY2xlYW4gdXAgdGhlIGFyZ3NcbiAgICBjb25zdCByZXFGb3JQcm94eSA9IF8ubGFzdChhcmdzKT8ucmVxRm9yUHJveHk7XG4gICAgaWYgKHJlcUZvclByb3h5KSB7XG4gICAgICBhcmdzLnBvcCgpO1xuICAgIH1cblxuXG4gICAgLy8gZmlyc3QgZG8gc29tZSBlcnJvciBjaGVja2luZy4gSWYgd2UncmUgcmVxdWVzdGluZyBhIHNlc3Npb24gY29tbWFuZCBleGVjdXRpb24sIHRoZW4gbWFrZVxuICAgIC8vIHN1cmUgdGhhdCBzZXNzaW9uIGFjdHVhbGx5IGV4aXN0cyBvbiB0aGUgc2Vzc2lvbiBkcml2ZXIsIGFuZCBzZXQgdGhlIHNlc3Npb24gZHJpdmVyIGl0c2VsZlxuICAgIGxldCBzZXNzaW9uSWQgPSBudWxsO1xuICAgIGxldCBkc3RTZXNzaW9uID0gbnVsbDtcbiAgICBsZXQgcHJvdG9jb2wgPSBudWxsO1xuICAgIC8qKiBAdHlwZSB7dGhpcyB8IEV4dGVybmFsRHJpdmVyfSAqL1xuICAgIGxldCBkcml2ZXIgPSB0aGlzO1xuICAgIGlmIChpc1Nlc3Npb25DbWQpIHtcbiAgICAgIHNlc3Npb25JZCA9IF8ubGFzdChhcmdzKTtcbiAgICAgIGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgICBpZiAoIWRzdFNlc3Npb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgc2Vzc2lvbiB3aXRoIGlkICcke3Nlc3Npb25JZH0nIGRvZXMgbm90IGV4aXN0YCk7XG4gICAgICB9XG4gICAgICAvLyBub3cgc2F2ZSB0aGUgcmVzcG9uc2UgcHJvdG9jb2wgZ2l2ZW4gdGhhdCB0aGUgc2Vzc2lvbiBkcml2ZXIncyBwcm90b2NvbCBtaWdodCBkaWZmZXJcbiAgICAgIHByb3RvY29sID0gZHN0U2Vzc2lvbi5wcm90b2NvbDtcbiAgICAgIGlmICghaXNVbWJyZWxsYUNtZCkge1xuICAgICAgICBkcml2ZXIgPSBkc3RTZXNzaW9uO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGdldCBhbnkgcGx1Z2lucyB3aGljaCBhcmUgcmVnaXN0ZXJlZCBhcyBoYW5kbGluZyB0aGlzIGNvbW1hbmRcbiAgICBjb25zdCBwbHVnaW5zID0gdGhpcy5wbHVnaW5zVG9IYW5kbGVDbWQoY21kLCBzZXNzaW9uSWQpO1xuXG4gICAgLy8gbm93IHdlIGRlZmluZSBhICdjbWRIYW5kbGVkQnknIG9iamVjdCB3aGljaCB3aWxsIGtlZXAgdHJhY2sgb2Ygd2hpY2ggcGx1Z2lucyBoYXZlIGhhbmRsZWQgdGhpc1xuICAgIC8vIGNvbW1hbmQuIHdlIGNhcmUgYWJvdXQgdGhpcyBiZWNhdXNlIChhKSBtdWx0aXBsZSBwbHVnaW5zIGNhbiBoYW5kbGUgdGhlIHNhbWUgY29tbWFuZCwgYW5kXG4gICAgLy8gKGIpIHRoZXJlJ3Mgbm8gZ3VhcmFudGVlIHRoYXQgYSBwbHVnaW4gd2lsbCBhY3R1YWxseSBjYWxsIHRoZSBuZXh0KCkgbWV0aG9kIHdoaWNoIHJ1bnMgdGhlXG4gICAgLy8gb3JpZ2luYWwgY29tbWFuZCBleGVjdXRpb24uIFRoaXMgcmVzdWx0cyBpbiBhIHNpdHVhdGlvbiB3aGVyZSB0aGUgY29tbWFuZCBtaWdodCBiZSBoYW5kbGVkXG4gICAgLy8gYnkgc29tZSBidXQgbm90IGFsbCBwbHVnaW5zLCBvciBieSBwbHVnaW4ocykgYnV0IG5vdCBieSB0aGUgZGVmYXVsdCBiZWhhdmlvci4gU28gc3RhcnQgb3V0XG4gICAgLy8gdGhpcyBvYmplY3QgZGVjbGFyaW5nIHRoYXQgdGhlIGRlZmF1bHQgaGFuZGxlciBoYXMgbm90IGJlZW4gZXhlY3V0ZWQuXG4gICAgY29uc3QgY21kSGFuZGxlZEJ5ID0ge2RlZmF1bHQ6IGZhbHNlfTtcblxuICAgIC8vIG5vdyB3ZSBkZWZpbmUgYW4gYXN5bmMgZnVuY3Rpb24gd2hpY2ggd2lsbCBiZSBwYXNzZWQgdG8gcGx1Z2lucywgYW5kIHN1Y2Nlc3NpdmVseSB3cmFwcGVkXG4gICAgLy8gaWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBwbHVnaW4gdGhhdCBjYW4gaGFuZGxlIHRoZSBjb21tYW5kLiBUbyBzdGFydCBvZmYgd2l0aCwgdGhlIGFzeW5jXG4gICAgLy8gZnVuY3Rpb24gaXMgZGVmaW5lZCBhcyBjYWxsaW5nIHRoZSBkZWZhdWx0IGJlaGF2aW9yLCBpLmUuLCB3aGljaGV2ZXIgb2YgdGhlIDMgY2FzZXMgYWJvdmUgaXNcbiAgICAvLyB0aGUgYXBwcm9wcmlhdGUgb25lXG4gICAgY29uc3QgZGVmYXVsdEJlaGF2aW9yID0gYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gaWYgd2UncmUgcnVubmluZyB3aXRoIHBsdWdpbnMsIG1ha2Ugc3VyZSB3ZSBsb2cgdGhhdCB0aGUgZGVmYXVsdCBiZWhhdmlvciBpcyBhY3R1YWxseVxuICAgICAgLy8gaGFwcGVuaW5nIHNvIHdlIGNhbiB0ZWxsIHdoZW4gdGhlIHBsdWdpbiBjYWxsIGNoYWluIGlzIHVud3JhcHBpbmcgdG8gdGhlIGRlZmF1bHQgYmVoYXZpb3JcbiAgICAgIC8vIGlmIHRoYXQncyB3aGF0IGhhcHBlbnNcbiAgICAgIHBsdWdpbnMubGVuZ3RoICYmIHRoaXMubG9nLmluZm8oYEV4ZWN1dGluZyBkZWZhdWx0IGhhbmRsaW5nIGJlaGF2aW9yIGZvciBjb21tYW5kICcke2NtZH0nYCk7XG5cbiAgICAgIC8vIGlmIHdlIG1ha2UgaXQgaGVyZSwgd2Uga25vdyB0aGF0IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGlzIGhhbmRsZWRcbiAgICAgIGNtZEhhbmRsZWRCeS5kZWZhdWx0ID0gdHJ1ZTtcblxuICAgICAgaWYgKHJlcUZvclByb3h5KSB7XG4gICAgICAgIC8vIHdlIHdvdWxkIGhhdmUgcHJveGllZCB0aGlzIGNvbW1hbmQgaGFkIGEgcGx1Z2luIG5vdCBoYW5kbGVkIGl0LCBzbyB0aGUgZGVmYXVsdCBiZWhhdmlvclxuICAgICAgICAvLyBpcyB0byBkbyB0aGUgcHJveHkgYW5kIHJldHJpZXZlIHRoZSByZXN1bHQgaW50ZXJuYWxseSBzbyBpdCBjYW4gYmUgcGFzc2VkIHRvIHRoZSBwbHVnaW5cbiAgICAgICAgLy8gaW4gY2FzZSBpdCBjYWxscyAnYXdhaXQgbmV4dCgpJy4gVGhpcyByZXF1aXJlcyB0aGF0IHRoZSBkcml2ZXIgaGF2ZSBkZWZpbmVkXG4gICAgICAgIC8vICdwcm94eUNvbW1hbmQnIGFuZCBub3QganVzdCAncHJveHlSZXFSZXMnLlxuICAgICAgICBpZiAoIWRzdFNlc3Npb24ucHJveHlDb21tYW5kKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRHJpdmVyUHJveHlDb21tYW5kRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXdhaXQgZHN0U2Vzc2lvbi5wcm94eUNvbW1hbmQocmVxRm9yUHJveHkub3JpZ2luYWxVcmwsIHJlcUZvclByb3h5Lm1ldGhvZCxcbiAgICAgICAgICByZXFGb3JQcm94eS5ib2R5KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzR2V0U3RhdHVzKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmdldFN0YXR1cygpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNVbWJyZWxsYUNtZCkge1xuICAgICAgICAvLyBzb21lIGNvbW1hbmRzLCBsaWtlIGRlbGV0ZVNlc3Npb24sIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRvIGhhbmRsZSBvbiAqdGhpcyogZHJpdmVyLFxuICAgICAgICAvLyBub3QgdGhlIHBsYXRmb3JtIGRyaXZlclxuICAgICAgICByZXR1cm4gYXdhaXQgQmFzZURyaXZlci5wcm90b3R5cGUuZXhlY3V0ZUNvbW1hbmQuY2FsbCh0aGlzLCBjbWQsIC4uLmFyZ3MpO1xuICAgICAgfVxuXG4gICAgICAvLyBoZXJlIHdlIGtub3cgdGhhdCB3ZSBhcmUgZXhlY3V0aW5nIGEgc2Vzc2lvbiBjb21tYW5kLCBhbmQgaGF2ZSBhIHZhbGlkIHNlc3Npb24gZHJpdmVyXG4gICAgICByZXR1cm4gYXdhaXQgZHN0U2Vzc2lvbi5leGVjdXRlQ29tbWFuZChjbWQsIC4uLmFyZ3MpO1xuICAgIH07XG5cbiAgICAvLyBub3cgdGFrZSBvdXIgZGVmYXVsdCBiZWhhdmlvciwgd3JhcCBpdCB3aXRoIGFueSBudW1iZXIgb2YgcGx1Z2luIGJlaGF2aW9ycywgYW5kIHJ1biBpdFxuICAgIGNvbnN0IHdyYXBwZWRDbWQgPSB0aGlzLndyYXBDb21tYW5kV2l0aFBsdWdpbnMoe1xuICAgICAgZHJpdmVyLCBjbWQsIGFyZ3MsIHBsdWdpbnMsIGNtZEhhbmRsZWRCeSwgbmV4dDogZGVmYXVsdEJlaGF2aW9yXG4gICAgfSk7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5leGVjdXRlV3JhcHBlZENvbW1hbmQoe3dyYXBwZWRDbWQsIHByb3RvY29sfSk7XG5cbiAgICAvLyBpZiB3ZSBoYWQgcGx1Z2lucywgbWFrZSBzdXJlIHRvIGxvZyBvdXQgdGhlIGhlbHBmdWwgcmVwb3J0IGFib3V0IHdoaWNoIHBsdWdpbnMgZW5kZWQgdXBcbiAgICAvLyBoYW5kbGluZyB0aGUgY29tbWFuZCBhbmQgd2hpY2ggZGlkbid0XG4gICAgdGhpcy5sb2dQbHVnaW5IYW5kbGVyUmVwb3J0KHBsdWdpbnMsIHtjbWQsIGNtZEhhbmRsZWRCeX0pO1xuXG4gICAgLy8gQW5kIGZpbmFsbHksIGlmIHRoZSBjb21tYW5kIHdhcyBjcmVhdGVTZXNzaW9uLCB3ZSB3YW50IHRvIG1pZ3JhdGUgYW55IHBsdWdpbnMgd2hpY2ggd2VyZVxuICAgIC8vIHByZXZpb3VzbHkgc2Vzc2lvbmxlc3MgdG8gdXNlIHRoZSBuZXcgc2Vzc2lvbklkLCBzbyB0aGF0IHBsdWdpbnMgY2FuIHNoYXJlIHN0YXRlIGJldHdlZW5cbiAgICAvLyB0aGVpciBjcmVhdGVTZXNzaW9uIG1ldGhvZCBhbmQgb3RoZXIgaW5zdGFuY2UgbWV0aG9kc1xuICAgIGlmIChjbWQgPT09IENSRUFURV9TRVNTSU9OX0NPTU1BTkQgJiYgdGhpcy5zZXNzaW9ubGVzc1BsdWdpbnMubGVuZ3RoICYmICFyZXMuZXJyb3IpIHtcbiAgICAgIGNvbnN0IHNlc3Npb25JZCA9IF8uZmlyc3QocmVzLnZhbHVlKTtcbiAgICAgIHRoaXMubG9nLmluZm8oYFByb21vdGluZyAke3RoaXMuc2Vzc2lvbmxlc3NQbHVnaW5zLmxlbmd0aH0gc2Vzc2lvbmxlc3MgcGx1Z2lucyB0byBiZSBhdHRhY2hlZCBgICtcbiAgICAgICAgYHRvIHNlc3Npb24gSUQgJHtzZXNzaW9uSWR9YCk7XG4gICAgICB0aGlzLnNlc3Npb25QbHVnaW5zW3Nlc3Npb25JZF0gPSB0aGlzLnNlc3Npb25sZXNzUGx1Z2lucztcbiAgICAgIHRoaXMuc2Vzc2lvbmxlc3NQbHVnaW5zID0gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIHdyYXBDb21tYW5kV2l0aFBsdWdpbnMgKHtkcml2ZXIsIGNtZCwgYXJncywgbmV4dCwgY21kSGFuZGxlZEJ5LCBwbHVnaW5zfSkge1xuICAgIHBsdWdpbnMubGVuZ3RoICYmIHRoaXMubG9nLmluZm8oYFBsdWdpbnMgd2hpY2ggY2FuIGhhbmRsZSBjbWQgJyR7Y21kfSc6ICR7cGx1Z2lucy5tYXAoKHApID0+IHAubmFtZSl9YCk7XG5cbiAgICAvLyBub3cgd2UgY2FuIGdvIHRocm91Z2ggZWFjaCBwbHVnaW4gYW5kIHdyYXAgYG5leHRgIGFyb3VuZCBpdHMgb3duIGhhbmRsZXIsIHBhc3NpbmcgdGhlICpvbGQqXG4gICAgLy8gbmV4dCBpbiBzbyB0aGF0IGl0IGNhbiBjYWxsIGl0IGlmIGl0IHdhbnRzIHRvXG4gICAgZm9yIChjb25zdCBwbHVnaW4gb2YgcGx1Z2lucykge1xuICAgICAgLy8gbmVlZCBhbiBJSUZFIGhlcmUgYmVjYXVzZSB3ZSB3YW50IHRoZSB2YWx1ZSBvZiBuZXh0IHRoYXQncyBwYXNzZWQgdG8gcGx1Z2luLmhhbmRsZSB0byBiZVxuICAgICAgLy8gZXhhY3RseSB0aGUgdmFsdWUgb2YgbmV4dCBoZXJlIGJlZm9yZSByZWFzc2lnbm1lbnQ7IHdlIGRvbid0IHdhbnQgaXQgdG8gYmUgbGF6aWx5XG4gICAgICAvLyBldmFsdWF0ZWQsIG90aGVyd2lzZSB3ZSBlbmQgdXAgd2l0aCBpbmZpbml0ZSByZWN1cnNpb24gb2YgdGhlIGxhc3QgYG5leHRgIHRvIGJlIGRlZmluZWQuXG4gICAgICBjbWRIYW5kbGVkQnlbcGx1Z2luLm5hbWVdID0gZmFsc2U7IC8vIHdlIHNlZSBhIG5ldyBwbHVnaW4sIHNvIGFkZCBpdCB0byB0aGUgJ2NtZEhhbmRsZWRCeScgb2JqZWN0XG4gICAgICBuZXh0ID0gKChfbmV4dCkgPT4gYXN5bmMgKCkgPT4ge1xuICAgICAgICB0aGlzLmxvZy5pbmZvKGBQbHVnaW4gJHtwbHVnaW4ubmFtZX0gaXMgbm93IGhhbmRsaW5nIGNtZCAnJHtjbWR9J2ApO1xuICAgICAgICBjbWRIYW5kbGVkQnlbcGx1Z2luLm5hbWVdID0gdHJ1ZTsgLy8gaWYgd2UgbWFrZSBpdCBoZXJlLCB0aGlzIHBsdWdpbiBoYXMgYXR0ZW1wdGVkIHRvIGhhbmRsZSBjbWRcbiAgICAgICAgLy8gZmlyc3QgYXR0ZW1wdCB0byBoYW5kbGUgdGhlIGNvbW1hbmQgdmlhIGEgY29tbWFuZC1zcGVjaWZpYyBoYW5kbGVyIG9uIHRoZSBwbHVnaW5cbiAgICAgICAgaWYgKHBsdWdpbltjbWRdKSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHBsdWdpbltjbWRdKF9uZXh0LCBkcml2ZXIsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIC8vIG90aGVyd2lzZSwgY2FsbCB0aGUgZ2VuZXJpYyAnaGFuZGxlJyBtZXRob2RcbiAgICAgICAgcmV0dXJuIGF3YWl0IHBsdWdpbi5oYW5kbGUoX25leHQsIGRyaXZlciwgY21kLCAuLi5hcmdzKTtcbiAgICAgIH0pKG5leHQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXh0O1xuICB9XG5cbiAgbG9nUGx1Z2luSGFuZGxlclJlcG9ydCAocGx1Z2lucywge2NtZCwgY21kSGFuZGxlZEJ5fSkge1xuICAgIGlmICghcGx1Z2lucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBhdCB0aGUgZW5kIG9mIHRoZSBkYXksIHdlIGhhdmUgYW4gb2JqZWN0IHJlcHJlc2VudGluZyB3aGljaCBwbHVnaW5zIGVuZGVkIHVwIGdldHRpbmdcbiAgICAvLyB0aGVpciBjb2RlIHJ1biBhcyBwYXJ0IG9mIGhhbmRsaW5nIHRoaXMgY29tbWFuZC4gQmVjYXVzZSBwbHVnaW5zIGNhbiBjaG9vc2UgKm5vdCogdG9cbiAgICAvLyBwYXNzIGNvbnRyb2wgdG8gb3RoZXIgcGx1Z2lucyBvciB0byB0aGUgZGVmYXVsdCBkcml2ZXIgYmVoYXZpb3IsIHRoaXMgaXMgaW5mb3JtYXRpb25cbiAgICAvLyB3aGljaCBpcyBwcm9iYWJseSB1c2VmdWwgdG8gdGhlIHVzZXIgKGVzcGVjaWFsbHkgaW4gc2l0dWF0aW9ucyB3aGVyZSBwbHVnaW5zIG1pZ2h0IG5vdFxuICAgIC8vIGludGVyYWN0IHdlbGwgdG9nZXRoZXIsIGFuZCBpdCB3b3VsZCBiZSBoYXJkIHRvIGRlYnVnIG90aGVyd2lzZSB3aXRob3V0IHRoaXMga2luZCBvZlxuICAgIC8vIG1lc3NhZ2UpLlxuICAgIGNvbnN0IGRpZEhhbmRsZSA9IE9iamVjdC5rZXlzKGNtZEhhbmRsZWRCeSkuZmlsdGVyKChrKSA9PiBjbWRIYW5kbGVkQnlba10pO1xuICAgIGNvbnN0IGRpZG50SGFuZGxlID0gT2JqZWN0LmtleXMoY21kSGFuZGxlZEJ5KS5maWx0ZXIoKGspID0+ICFjbWRIYW5kbGVkQnlba10pO1xuICAgIGlmIChkaWRudEhhbmRsZS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBDb21tYW5kICcke2NtZH0nIHdhcyAqbm90KiBoYW5kbGVkIGJ5IHRoZSBmb2xsb3dpbmcgYmVoYXZpb3VycyBvciBwbHVnaW5zLCBldmVuIGAgK1xuICAgICAgICBgdGhvdWdoIHRoZXkgd2VyZSByZWdpc3RlcmVkIHRvIGhhbmRsZSBpdDogJHtKU09OLnN0cmluZ2lmeShkaWRudEhhbmRsZSl9LiBUaGUgYCArXG4gICAgICAgIGBjb21tYW5kICp3YXMqIGhhbmRsZWQgYnkgdGhlc2U6ICR7SlNPTi5zdHJpbmdpZnkoZGlkSGFuZGxlKX0uYCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZVdyYXBwZWRDb21tYW5kICh7d3JhcHBlZENtZCwgcHJvdG9jb2x9KSB7XG4gICAgbGV0IGNtZFJlcywgY21kRXJyLCByZXMgPSB7fTtcbiAgICB0cnkge1xuICAgICAgLy8gQXQgdGhpcyBwb2ludCwgYHdyYXBwZWRDbWRgIGRlZmluZXMgYSB3aG9sZSBzZXF1ZW5jZSBvZiBwbHVnaW4gaGFuZGxlcnMsIGN1bG1pbmF0aW5nIGluXG4gICAgICAvLyBvdXIgZGVmYXVsdCBoYW5kbGVyLiBXaGF0ZXZlciBpdCByZXR1cm5zIGlzIHdoYXQgd2UncmUgZ29pbmcgdG8gd2FudCB0byBzZW5kIGJhY2sgdG8gdGhlXG4gICAgICAvLyB1c2VyLlxuICAgICAgY21kUmVzID0gYXdhaXQgd3JhcHBlZENtZCgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNtZEVyciA9IGU7XG4gICAgfVxuXG4gICAgLy8gU2FkbHksIHdlIGRvbid0IGtub3cgZXhhY3RseSB3aGF0IGtpbmQgb2Ygb2JqZWN0IHdpbGwgYmUgcmV0dXJuZWQuIEl0IHdpbGwgZWl0aGVyIGJlIGEgYmFyZVxuICAgIC8vIG9iamVjdCwgb3IgYSBwcm90b2NvbC1hd2FyZSBvYmplY3Qgd2l0aCBwcm90b2NvbCBhbmQgZXJyb3IvdmFsdWUga2V5cy4gU28gd2UgbmVlZCB0byBzbmlmZlxuICAgIC8vIGl0IGFuZCBtYWtlIHN1cmUgd2UgZG9uJ3QgZG91YmxlLXdyYXAgaXQgaWYgaXQncyB0aGUgbGF0dGVyIGtpbmQuXG4gICAgaWYgKF8uaXNQbGFpbk9iamVjdChjbWRSZXMpICYmIF8uaGFzKGNtZFJlcywgJ3Byb3RvY29sJykpIHtcbiAgICAgIHJlcyA9IGNtZFJlcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzLnZhbHVlID0gY21kUmVzO1xuICAgICAgcmVzLmVycm9yID0gY21kRXJyO1xuICAgICAgcmVzLnByb3RvY29sID0gcHJvdG9jb2w7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBwcm94eUFjdGl2ZSAoc2Vzc2lvbklkKSB7XG4gICAgY29uc3QgZHN0U2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnNbc2Vzc2lvbklkXTtcbiAgICByZXR1cm4gZHN0U2Vzc2lvbiAmJiBfLmlzRnVuY3Rpb24oZHN0U2Vzc2lvbi5wcm94eUFjdGl2ZSkgJiYgZHN0U2Vzc2lvbi5wcm94eUFjdGl2ZShzZXNzaW9uSWQpO1xuICB9XG5cbiAgZ2V0UHJveHlBdm9pZExpc3QgKHNlc3Npb25JZCkge1xuICAgIGNvbnN0IGRzdFNlc3Npb24gPSB0aGlzLnNlc3Npb25zW3Nlc3Npb25JZF07XG4gICAgcmV0dXJuIGRzdFNlc3Npb24gPyBkc3RTZXNzaW9uLmdldFByb3h5QXZvaWRMaXN0KCkgOiBbXTtcbiAgfVxuXG4gIGNhblByb3h5IChzZXNzaW9uSWQpIHtcbiAgICBjb25zdCBkc3RTZXNzaW9uID0gdGhpcy5zZXNzaW9uc1tzZXNzaW9uSWRdO1xuICAgIHJldHVybiBkc3RTZXNzaW9uICYmIGRzdFNlc3Npb24uY2FuUHJveHkoc2Vzc2lvbklkKTtcbiAgfVxufVxuXG4vLyBoZWxwIGRlY2lkZSB3aGljaCBjb21tYW5kcyBzaG91bGQgYmUgcHJveGllZCB0byBzdWItZHJpdmVycyBhbmQgd2hpY2hcbi8vIHNob3VsZCBiZSBoYW5kbGVkIGJ5IHRoaXMsIG91ciB1bWJyZWxsYSBkcml2ZXJcbmZ1bmN0aW9uIGlzQXBwaXVtRHJpdmVyQ29tbWFuZCAoY21kKSB7XG4gIHJldHVybiAhaXNTZXNzaW9uQ29tbWFuZChjbWQpIHx8IGNtZCA9PT0gREVMRVRFX1NFU1NJT05fQ09NTUFORDtcbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBBcHBpdW0gdHJpZWQgdG8gcHJveHkgYSBjb21tYW5kIHVzaW5nIGEgZHJpdmVyJ3MgYHByb3h5Q29tbWFuZGAgbWV0aG9kIGJ1dCB0aGVcbiAqIG1ldGhvZCBkaWQgbm90IGV4aXN0XG4gKi9cbmV4cG9ydCBjbGFzcyBOb0RyaXZlclByb3h5Q29tbWFuZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogQHR5cGUge1JlYWRvbmx5PHN0cmluZz59XG4gICAqL1xuICBjb2RlID0gJ0FQUElVTUVSUl9OT19EUklWRVJfUFJPWFlDT01NQU5EJztcblxuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgc3VwZXIoYFRoZSBkZWZhdWx0IGJlaGF2aW9yIGZvciB0aGlzIGNvbW1hbmQgd2FzIHRvIHByb3h5LCBidXQgdGhlIGRyaXZlciBgICtcbiAgICAgICAgICBgZGlkIG5vdCBoYXZlIHRoZSAncHJveHlDb21tYW5kJyBtZXRob2QgZGVmaW5lZC4gVG8gZnVsbHkgc3VwcG9ydCBgICtcbiAgICAgICAgICBgcGx1Z2lucywgZHJpdmVycyBzaG91bGQgaGF2ZSAncHJveHlDb21tYW5kJyBzZXQgdG8gYSBqd3BQcm94eSBvYmplY3QncyBgICtcbiAgICAgICAgICBgJ2NvbW1hbmQoKScgbWV0aG9kLCBpbiBhZGRpdGlvbiB0byB0aGUgbm9ybWFsICdwcm94eVJlcVJlcydgKTtcbiAgfVxufVxuXG5leHBvcnQgeyBBcHBpdW1Ecml2ZXIgfTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuRXh0ZXJuYWxEcml2ZXJ9IEV4dGVybmFsRHJpdmVyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuVzNDQ2FwYWJpbGl0aWVzfSBXM0NDYXBhYmlsaXRpZXNcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJEYXRhfSBEcml2ZXJEYXRhXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuRHJpdmVyT3B0c30gRHJpdmVyT3B0c1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkNvbnN0cmFpbnRzfSBDb25zdHJhaW50c1xuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkFwcGl1bVNlcnZlcn0gQXBwaXVtU2VydmVyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi90eXBlcycpLkV4dGVuc2lvblR5cGV9IEV4dGVuc2lvblR5cGVcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uL3R5cGVzL2V4dGVuc2lvbicpLlBsdWdpbkNsYXNzfSBQbHVnaW5DbGFzc1xuICogQHR5cGVkZWYge2ltcG9ydCgnLi9leHRlbnNpb24vZHJpdmVyLWNvbmZpZycpLkRyaXZlckNvbmZpZ30gRHJpdmVyQ29uZmlnXG4gKi9cblxuLyoqXG4gKiBVc2VkIGJ5IHtAbGlua2NvZGUgQXBwaXVtRHJpdmVyLmNyZWF0ZVNlc3Npb259IGFuZCB7QGxpbmtjb2RlIEFwcGl1bURyaXZlci5kZWxldGVTZXNzaW9ufSB0byBkZXNjcmliZVxuICogcmVzdWx0LlxuICogQHRlbXBsYXRlIFZcbiAqIEB0eXBlZGVmIFNlc3Npb25IYW5kbGVyUmVzdWx0XG4gKiBAcHJvcGVydHkge1Z9IFt2YWx1ZV1cbiAqIEBwcm9wZXJ0eSB7RXJyb3J9IFtlcnJvcl1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbcHJvdG9jb2xdXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuU2Vzc2lvbkhhbmRsZXI8U2Vzc2lvbkhhbmRsZXJSZXN1bHQ8YW55W10+LFNlc3Npb25IYW5kbGVyUmVzdWx0PHZvaWQ+Pn0gU2Vzc2lvbkhhbmRsZXJcbiAqL1xuIl19