1 | ;
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 | var _crypto = _interopRequireDefault(require("crypto"));
|
8 | var _os = _interopRequireDefault(require("os"));
|
9 | var tls = _interopRequireWildcard(require("tls"));
|
10 | var net = _interopRequireWildcard(require("net"));
|
11 | var _dns = _interopRequireDefault(require("dns"));
|
12 | var _constants = _interopRequireDefault(require("constants"));
|
13 | var _stream = require("stream");
|
14 | var _identity = require("@azure/identity");
|
15 | var _bulkLoad = _interopRequireDefault(require("./bulk-load"));
|
16 | var _debug = _interopRequireDefault(require("./debug"));
|
17 | var _events = require("events");
|
18 | var _instanceLookup = require("./instance-lookup");
|
19 | var _transientErrorLookup = require("./transient-error-lookup");
|
20 | var _packet = require("./packet");
|
21 | var _preloginPayload = _interopRequireDefault(require("./prelogin-payload"));
|
22 | var _login7Payload = _interopRequireDefault(require("./login7-payload"));
|
23 | var _ntlmPayload = _interopRequireDefault(require("./ntlm-payload"));
|
24 | var _request = _interopRequireDefault(require("./request"));
|
25 | var _rpcrequestPayload = _interopRequireDefault(require("./rpcrequest-payload"));
|
26 | var _sqlbatchPayload = _interopRequireDefault(require("./sqlbatch-payload"));
|
27 | var _messageIo = _interopRequireDefault(require("./message-io"));
|
28 | var _tokenStreamParser = require("./token/token-stream-parser");
|
29 | var _transaction = require("./transaction");
|
30 | var _errors = require("./errors");
|
31 | var _connector = require("./connector");
|
32 | var _library = require("./library");
|
33 | var _tdsVersions = require("./tds-versions");
|
34 | var _message = _interopRequireDefault(require("./message"));
|
35 | var _ntlm = require("./ntlm");
|
36 | var _dataType = require("./data-type");
|
37 | var _bulkLoadPayload = require("./bulk-load-payload");
|
38 | var _specialStoredProcedure = _interopRequireDefault(require("./special-stored-procedure"));
|
39 | var _package = require("../package.json");
|
40 | var _url = require("url");
|
41 | var _handler = require("./token/handler");
|
42 | function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
43 | function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
44 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
45 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
46 |
|
47 | /**
|
48 | * @private
|
49 | */
|
50 | const KEEP_ALIVE_INITIAL_DELAY = 30 * 1000;
|
51 | /**
|
52 | * @private
|
53 | */
|
54 | const DEFAULT_CONNECT_TIMEOUT = 15 * 1000;
|
55 | /**
|
56 | * @private
|
57 | */
|
58 | const DEFAULT_CLIENT_REQUEST_TIMEOUT = 15 * 1000;
|
59 | /**
|
60 | * @private
|
61 | */
|
62 | const DEFAULT_CANCEL_TIMEOUT = 5 * 1000;
|
63 | /**
|
64 | * @private
|
65 | */
|
66 | const DEFAULT_CONNECT_RETRY_INTERVAL = 500;
|
67 | /**
|
68 | * @private
|
69 | */
|
70 | const DEFAULT_PACKET_SIZE = 4 * 1024;
|
71 | /**
|
72 | * @private
|
73 | */
|
74 | const DEFAULT_TEXTSIZE = 2147483647;
|
75 | /**
|
76 | * @private
|
77 | */
|
78 | const DEFAULT_DATEFIRST = 7;
|
79 | /**
|
80 | * @private
|
81 | */
|
82 | const DEFAULT_PORT = 1433;
|
83 | /**
|
84 | * @private
|
85 | */
|
86 | const DEFAULT_TDS_VERSION = '7_4';
|
87 | /**
|
88 | * @private
|
89 | */
|
90 | const DEFAULT_LANGUAGE = 'us_english';
|
91 | /**
|
92 | * @private
|
93 | */
|
94 | const DEFAULT_DATEFORMAT = 'mdy';
|
95 |
|
96 | /**
|
97 | * @private
|
98 | */
|
99 |
|
100 | /**
|
101 | * @private
|
102 | */
|
103 | const CLEANUP_TYPE = {
|
104 | NORMAL: 0,
|
105 | REDIRECT: 1,
|
106 | RETRY: 2
|
107 | };
|
108 | /**
|
109 | * A [[Connection]] instance represents a single connection to a database server.
|
110 | *
|
111 | * ```js
|
112 | * var Connection = require('tedious').Connection;
|
113 | * var config = {
|
114 | * "authentication": {
|
115 | * ...,
|
116 | * "options": {...}
|
117 | * },
|
118 | * "options": {...}
|
119 | * };
|
120 | * var connection = new Connection(config);
|
121 | * ```
|
122 | *
|
123 | * Only one request at a time may be executed on a connection. Once a [[Request]]
|
124 | * has been initiated (with [[Connection.callProcedure]], [[Connection.execSql]],
|
125 | * or [[Connection.execSqlBatch]]), another should not be initiated until the
|
126 | * [[Request]]'s completion callback is called.
|
127 | */
|
128 | class Connection extends _events.EventEmitter {
|
129 | /**
|
130 | * @private
|
131 | */
|
132 |
|
133 | /**
|
134 | * @private
|
135 | */
|
136 |
|
137 | /**
|
138 | * @private
|
139 | */
|
140 |
|
141 | /**
|
142 | * @private
|
143 | */
|
144 |
|
145 | /**
|
146 | * @private
|
147 | */
|
148 |
|
149 | /**
|
150 | * @private
|
151 | */
|
152 |
|
153 | /**
|
154 | * @private
|
155 | */
|
156 |
|
157 | /**
|
158 | * @private
|
159 | */
|
160 |
|
161 | /**
|
162 | * @private
|
163 | */
|
164 |
|
165 | /**
|
166 | * @private
|
167 | */
|
168 |
|
169 | /**
|
170 | * @private
|
171 | */
|
172 |
|
173 | /**
|
174 | * @private
|
175 | */
|
176 |
|
177 | /**
|
178 | * @private
|
179 | */
|
180 |
|
181 | /**
|
182 | * @private
|
183 | */
|
184 |
|
185 | /**
|
186 | * @private
|
187 | */
|
188 |
|
189 | /**
|
190 | * @private
|
191 | */
|
192 |
|
193 | /**
|
194 | * @private
|
195 | */
|
196 |
|
197 | /**
|
198 | * @private
|
199 | */
|
200 |
|
201 | /**
|
202 | * @private
|
203 | */
|
204 |
|
205 | /**
|
206 | * @private
|
207 | */
|
208 |
|
209 | /**
|
210 | * @private
|
211 | */
|
212 |
|
213 | /**
|
214 | * @private
|
215 | */
|
216 |
|
217 | /**
|
218 | * @private
|
219 | */
|
220 |
|
221 | /**
|
222 | * @private
|
223 | */
|
224 |
|
225 | /**
|
226 | * @private
|
227 | */
|
228 |
|
229 | /**
|
230 | * @private
|
231 | */
|
232 |
|
233 | /**
|
234 | * @private
|
235 | */
|
236 |
|
237 | /**
|
238 | * @private
|
239 | */
|
240 | _cancelAfterRequestSent;
|
241 |
|
242 | /**
|
243 | * @private
|
244 | */
|
245 |
|
246 | /**
|
247 | * Note: be aware of the different options field:
|
248 | * 1. config.authentication.options
|
249 | * 2. config.options
|
250 | *
|
251 | * ```js
|
252 | * const { Connection } = require('tedious');
|
253 | *
|
254 | * const config = {
|
255 | * "authentication": {
|
256 | * ...,
|
257 | * "options": {...}
|
258 | * },
|
259 | * "options": {...}
|
260 | * };
|
261 | *
|
262 | * const connection = new Connection(config);
|
263 | * ```
|
264 | *
|
265 | * @param config
|
266 | */
|
267 | constructor(config) {
|
268 | super();
|
269 | if (typeof config !== 'object' || config === null) {
|
270 | throw new TypeError('The "config" argument is required and must be of type Object.');
|
271 | }
|
272 | if (typeof config.server !== 'string') {
|
273 | throw new TypeError('The "config.server" property is required and must be of type string.');
|
274 | }
|
275 | this.fedAuthRequired = false;
|
276 | let authentication;
|
277 | if (config.authentication !== undefined) {
|
278 | if (typeof config.authentication !== 'object' || config.authentication === null) {
|
279 | throw new TypeError('The "config.authentication" property must be of type Object.');
|
280 | }
|
281 | const type = config.authentication.type;
|
282 | const options = config.authentication.options === undefined ? {} : config.authentication.options;
|
283 | if (typeof type !== 'string') {
|
284 | throw new TypeError('The "config.authentication.type" property must be of type string.');
|
285 | }
|
286 | if (type !== 'default' && type !== 'ntlm' && type !== 'azure-active-directory-password' && type !== 'azure-active-directory-access-token' && type !== 'azure-active-directory-msi-vm' && type !== 'azure-active-directory-msi-app-service' && type !== 'azure-active-directory-service-principal-secret' && type !== 'azure-active-directory-default') {
|
287 | throw new TypeError('The "type" property must one of "default", "ntlm", "azure-active-directory-password", "azure-active-directory-access-token", "azure-active-directory-default", "azure-active-directory-msi-vm" or "azure-active-directory-msi-app-service" or "azure-active-directory-service-principal-secret".');
|
288 | }
|
289 | if (typeof options !== 'object' || options === null) {
|
290 | throw new TypeError('The "config.authentication.options" property must be of type object.');
|
291 | }
|
292 | if (type === 'ntlm') {
|
293 | if (typeof options.domain !== 'string') {
|
294 | throw new TypeError('The "config.authentication.options.domain" property must be of type string.');
|
295 | }
|
296 | if (options.userName !== undefined && typeof options.userName !== 'string') {
|
297 | throw new TypeError('The "config.authentication.options.userName" property must be of type string.');
|
298 | }
|
299 | if (options.password !== undefined && typeof options.password !== 'string') {
|
300 | throw new TypeError('The "config.authentication.options.password" property must be of type string.');
|
301 | }
|
302 | authentication = {
|
303 | type: 'ntlm',
|
304 | options: {
|
305 | userName: options.userName,
|
306 | password: options.password,
|
307 | domain: options.domain && options.domain.toUpperCase()
|
308 | }
|
309 | };
|
310 | } else if (type === 'azure-active-directory-password') {
|
311 | if (typeof options.clientId !== 'string') {
|
312 | throw new TypeError('The "config.authentication.options.clientId" property must be of type string.');
|
313 | }
|
314 | if (options.userName !== undefined && typeof options.userName !== 'string') {
|
315 | throw new TypeError('The "config.authentication.options.userName" property must be of type string.');
|
316 | }
|
317 | if (options.password !== undefined && typeof options.password !== 'string') {
|
318 | throw new TypeError('The "config.authentication.options.password" property must be of type string.');
|
319 | }
|
320 | if (options.tenantId !== undefined && typeof options.tenantId !== 'string') {
|
321 | throw new TypeError('The "config.authentication.options.tenantId" property must be of type string.');
|
322 | }
|
323 | authentication = {
|
324 | type: 'azure-active-directory-password',
|
325 | options: {
|
326 | userName: options.userName,
|
327 | password: options.password,
|
328 | tenantId: options.tenantId,
|
329 | clientId: options.clientId
|
330 | }
|
331 | };
|
332 | } else if (type === 'azure-active-directory-access-token') {
|
333 | if (typeof options.token !== 'string') {
|
334 | throw new TypeError('The "config.authentication.options.token" property must be of type string.');
|
335 | }
|
336 | authentication = {
|
337 | type: 'azure-active-directory-access-token',
|
338 | options: {
|
339 | token: options.token
|
340 | }
|
341 | };
|
342 | } else if (type === 'azure-active-directory-msi-vm') {
|
343 | if (options.clientId !== undefined && typeof options.clientId !== 'string') {
|
344 | throw new TypeError('The "config.authentication.options.clientId" property must be of type string.');
|
345 | }
|
346 | authentication = {
|
347 | type: 'azure-active-directory-msi-vm',
|
348 | options: {
|
349 | clientId: options.clientId
|
350 | }
|
351 | };
|
352 | } else if (type === 'azure-active-directory-default') {
|
353 | if (options.clientId !== undefined && typeof options.clientId !== 'string') {
|
354 | throw new TypeError('The "config.authentication.options.clientId" property must be of type string.');
|
355 | }
|
356 | authentication = {
|
357 | type: 'azure-active-directory-default',
|
358 | options: {
|
359 | clientId: options.clientId
|
360 | }
|
361 | };
|
362 | } else if (type === 'azure-active-directory-msi-app-service') {
|
363 | if (options.clientId !== undefined && typeof options.clientId !== 'string') {
|
364 | throw new TypeError('The "config.authentication.options.clientId" property must be of type string.');
|
365 | }
|
366 | authentication = {
|
367 | type: 'azure-active-directory-msi-app-service',
|
368 | options: {
|
369 | clientId: options.clientId
|
370 | }
|
371 | };
|
372 | } else if (type === 'azure-active-directory-service-principal-secret') {
|
373 | if (typeof options.clientId !== 'string') {
|
374 | throw new TypeError('The "config.authentication.options.clientId" property must be of type string.');
|
375 | }
|
376 | if (typeof options.clientSecret !== 'string') {
|
377 | throw new TypeError('The "config.authentication.options.clientSecret" property must be of type string.');
|
378 | }
|
379 | if (typeof options.tenantId !== 'string') {
|
380 | throw new TypeError('The "config.authentication.options.tenantId" property must be of type string.');
|
381 | }
|
382 | authentication = {
|
383 | type: 'azure-active-directory-service-principal-secret',
|
384 | options: {
|
385 | clientId: options.clientId,
|
386 | clientSecret: options.clientSecret,
|
387 | tenantId: options.tenantId
|
388 | }
|
389 | };
|
390 | } else {
|
391 | if (options.userName !== undefined && typeof options.userName !== 'string') {
|
392 | throw new TypeError('The "config.authentication.options.userName" property must be of type string.');
|
393 | }
|
394 | if (options.password !== undefined && typeof options.password !== 'string') {
|
395 | throw new TypeError('The "config.authentication.options.password" property must be of type string.');
|
396 | }
|
397 | authentication = {
|
398 | type: 'default',
|
399 | options: {
|
400 | userName: options.userName,
|
401 | password: options.password
|
402 | }
|
403 | };
|
404 | }
|
405 | } else {
|
406 | authentication = {
|
407 | type: 'default',
|
408 | options: {
|
409 | userName: undefined,
|
410 | password: undefined
|
411 | }
|
412 | };
|
413 | }
|
414 | this.config = {
|
415 | server: config.server,
|
416 | authentication: authentication,
|
417 | options: {
|
418 | abortTransactionOnError: false,
|
419 | appName: undefined,
|
420 | camelCaseColumns: false,
|
421 | cancelTimeout: DEFAULT_CANCEL_TIMEOUT,
|
422 | columnEncryptionKeyCacheTTL: 2 * 60 * 60 * 1000,
|
423 | // Units: milliseconds
|
424 | columnEncryptionSetting: false,
|
425 | columnNameReplacer: undefined,
|
426 | connectionRetryInterval: DEFAULT_CONNECT_RETRY_INTERVAL,
|
427 | connectTimeout: DEFAULT_CONNECT_TIMEOUT,
|
428 | connector: undefined,
|
429 | connectionIsolationLevel: _transaction.ISOLATION_LEVEL.READ_COMMITTED,
|
430 | cryptoCredentialsDetails: {},
|
431 | database: undefined,
|
432 | datefirst: DEFAULT_DATEFIRST,
|
433 | dateFormat: DEFAULT_DATEFORMAT,
|
434 | debug: {
|
435 | data: false,
|
436 | packet: false,
|
437 | payload: false,
|
438 | token: false
|
439 | },
|
440 | enableAnsiNull: true,
|
441 | enableAnsiNullDefault: true,
|
442 | enableAnsiPadding: true,
|
443 | enableAnsiWarnings: true,
|
444 | enableArithAbort: true,
|
445 | enableConcatNullYieldsNull: true,
|
446 | enableCursorCloseOnCommit: null,
|
447 | enableImplicitTransactions: false,
|
448 | enableNumericRoundabort: false,
|
449 | enableQuotedIdentifier: true,
|
450 | encrypt: true,
|
451 | fallbackToDefaultDb: false,
|
452 | encryptionKeyStoreProviders: undefined,
|
453 | instanceName: undefined,
|
454 | isolationLevel: _transaction.ISOLATION_LEVEL.READ_COMMITTED,
|
455 | language: DEFAULT_LANGUAGE,
|
456 | localAddress: undefined,
|
457 | maxRetriesOnTransientErrors: 3,
|
458 | multiSubnetFailover: false,
|
459 | packetSize: DEFAULT_PACKET_SIZE,
|
460 | port: DEFAULT_PORT,
|
461 | readOnlyIntent: false,
|
462 | requestTimeout: DEFAULT_CLIENT_REQUEST_TIMEOUT,
|
463 | rowCollectionOnDone: false,
|
464 | rowCollectionOnRequestCompletion: false,
|
465 | serverName: undefined,
|
466 | serverSupportsColumnEncryption: false,
|
467 | tdsVersion: DEFAULT_TDS_VERSION,
|
468 | textsize: DEFAULT_TEXTSIZE,
|
469 | trustedServerNameAE: undefined,
|
470 | trustServerCertificate: false,
|
471 | useColumnNames: false,
|
472 | useUTC: true,
|
473 | workstationId: undefined,
|
474 | lowerCaseGuids: false
|
475 | }
|
476 | };
|
477 | if (config.options) {
|
478 | if (config.options.port && config.options.instanceName) {
|
479 | throw new Error('Port and instanceName are mutually exclusive, but ' + config.options.port + ' and ' + config.options.instanceName + ' provided');
|
480 | }
|
481 | if (config.options.abortTransactionOnError !== undefined) {
|
482 | if (typeof config.options.abortTransactionOnError !== 'boolean' && config.options.abortTransactionOnError !== null) {
|
483 | throw new TypeError('The "config.options.abortTransactionOnError" property must be of type string or null.');
|
484 | }
|
485 | this.config.options.abortTransactionOnError = config.options.abortTransactionOnError;
|
486 | }
|
487 | if (config.options.appName !== undefined) {
|
488 | if (typeof config.options.appName !== 'string') {
|
489 | throw new TypeError('The "config.options.appName" property must be of type string.');
|
490 | }
|
491 | this.config.options.appName = config.options.appName;
|
492 | }
|
493 | if (config.options.camelCaseColumns !== undefined) {
|
494 | if (typeof config.options.camelCaseColumns !== 'boolean') {
|
495 | throw new TypeError('The "config.options.camelCaseColumns" property must be of type boolean.');
|
496 | }
|
497 | this.config.options.camelCaseColumns = config.options.camelCaseColumns;
|
498 | }
|
499 | if (config.options.cancelTimeout !== undefined) {
|
500 | if (typeof config.options.cancelTimeout !== 'number') {
|
501 | throw new TypeError('The "config.options.cancelTimeout" property must be of type number.');
|
502 | }
|
503 | this.config.options.cancelTimeout = config.options.cancelTimeout;
|
504 | }
|
505 | if (config.options.columnNameReplacer) {
|
506 | if (typeof config.options.columnNameReplacer !== 'function') {
|
507 | throw new TypeError('The "config.options.cancelTimeout" property must be of type function.');
|
508 | }
|
509 | this.config.options.columnNameReplacer = config.options.columnNameReplacer;
|
510 | }
|
511 | if (config.options.connectionIsolationLevel !== undefined) {
|
512 | (0, _transaction.assertValidIsolationLevel)(config.options.connectionIsolationLevel, 'config.options.connectionIsolationLevel');
|
513 | this.config.options.connectionIsolationLevel = config.options.connectionIsolationLevel;
|
514 | }
|
515 | if (config.options.connectTimeout !== undefined) {
|
516 | if (typeof config.options.connectTimeout !== 'number') {
|
517 | throw new TypeError('The "config.options.connectTimeout" property must be of type number.');
|
518 | }
|
519 | this.config.options.connectTimeout = config.options.connectTimeout;
|
520 | }
|
521 | if (config.options.connector !== undefined) {
|
522 | if (typeof config.options.connector !== 'function') {
|
523 | throw new TypeError('The "config.options.connector" property must be a function.');
|
524 | }
|
525 | this.config.options.connector = config.options.connector;
|
526 | }
|
527 | if (config.options.cryptoCredentialsDetails !== undefined) {
|
528 | if (typeof config.options.cryptoCredentialsDetails !== 'object' || config.options.cryptoCredentialsDetails === null) {
|
529 | throw new TypeError('The "config.options.cryptoCredentialsDetails" property must be of type Object.');
|
530 | }
|
531 | this.config.options.cryptoCredentialsDetails = config.options.cryptoCredentialsDetails;
|
532 | }
|
533 | if (config.options.database !== undefined) {
|
534 | if (typeof config.options.database !== 'string') {
|
535 | throw new TypeError('The "config.options.database" property must be of type string.');
|
536 | }
|
537 | this.config.options.database = config.options.database;
|
538 | }
|
539 | if (config.options.datefirst !== undefined) {
|
540 | if (typeof config.options.datefirst !== 'number' && config.options.datefirst !== null) {
|
541 | throw new TypeError('The "config.options.datefirst" property must be of type number.');
|
542 | }
|
543 | if (config.options.datefirst !== null && (config.options.datefirst < 1 || config.options.datefirst > 7)) {
|
544 | throw new RangeError('The "config.options.datefirst" property must be >= 1 and <= 7');
|
545 | }
|
546 | this.config.options.datefirst = config.options.datefirst;
|
547 | }
|
548 | if (config.options.dateFormat !== undefined) {
|
549 | if (typeof config.options.dateFormat !== 'string' && config.options.dateFormat !== null) {
|
550 | throw new TypeError('The "config.options.dateFormat" property must be of type string or null.');
|
551 | }
|
552 | this.config.options.dateFormat = config.options.dateFormat;
|
553 | }
|
554 | if (config.options.debug) {
|
555 | if (config.options.debug.data !== undefined) {
|
556 | if (typeof config.options.debug.data !== 'boolean') {
|
557 | throw new TypeError('The "config.options.debug.data" property must be of type boolean.');
|
558 | }
|
559 | this.config.options.debug.data = config.options.debug.data;
|
560 | }
|
561 | if (config.options.debug.packet !== undefined) {
|
562 | if (typeof config.options.debug.packet !== 'boolean') {
|
563 | throw new TypeError('The "config.options.debug.packet" property must be of type boolean.');
|
564 | }
|
565 | this.config.options.debug.packet = config.options.debug.packet;
|
566 | }
|
567 | if (config.options.debug.payload !== undefined) {
|
568 | if (typeof config.options.debug.payload !== 'boolean') {
|
569 | throw new TypeError('The "config.options.debug.payload" property must be of type boolean.');
|
570 | }
|
571 | this.config.options.debug.payload = config.options.debug.payload;
|
572 | }
|
573 | if (config.options.debug.token !== undefined) {
|
574 | if (typeof config.options.debug.token !== 'boolean') {
|
575 | throw new TypeError('The "config.options.debug.token" property must be of type boolean.');
|
576 | }
|
577 | this.config.options.debug.token = config.options.debug.token;
|
578 | }
|
579 | }
|
580 | if (config.options.enableAnsiNull !== undefined) {
|
581 | if (typeof config.options.enableAnsiNull !== 'boolean' && config.options.enableAnsiNull !== null) {
|
582 | throw new TypeError('The "config.options.enableAnsiNull" property must be of type boolean or null.');
|
583 | }
|
584 | this.config.options.enableAnsiNull = config.options.enableAnsiNull;
|
585 | }
|
586 | if (config.options.enableAnsiNullDefault !== undefined) {
|
587 | if (typeof config.options.enableAnsiNullDefault !== 'boolean' && config.options.enableAnsiNullDefault !== null) {
|
588 | throw new TypeError('The "config.options.enableAnsiNullDefault" property must be of type boolean or null.');
|
589 | }
|
590 | this.config.options.enableAnsiNullDefault = config.options.enableAnsiNullDefault;
|
591 | }
|
592 | if (config.options.enableAnsiPadding !== undefined) {
|
593 | if (typeof config.options.enableAnsiPadding !== 'boolean' && config.options.enableAnsiPadding !== null) {
|
594 | throw new TypeError('The "config.options.enableAnsiPadding" property must be of type boolean or null.');
|
595 | }
|
596 | this.config.options.enableAnsiPadding = config.options.enableAnsiPadding;
|
597 | }
|
598 | if (config.options.enableAnsiWarnings !== undefined) {
|
599 | if (typeof config.options.enableAnsiWarnings !== 'boolean' && config.options.enableAnsiWarnings !== null) {
|
600 | throw new TypeError('The "config.options.enableAnsiWarnings" property must be of type boolean or null.');
|
601 | }
|
602 | this.config.options.enableAnsiWarnings = config.options.enableAnsiWarnings;
|
603 | }
|
604 | if (config.options.enableArithAbort !== undefined) {
|
605 | if (typeof config.options.enableArithAbort !== 'boolean' && config.options.enableArithAbort !== null) {
|
606 | throw new TypeError('The "config.options.enableArithAbort" property must be of type boolean or null.');
|
607 | }
|
608 | this.config.options.enableArithAbort = config.options.enableArithAbort;
|
609 | }
|
610 | if (config.options.enableConcatNullYieldsNull !== undefined) {
|
611 | if (typeof config.options.enableConcatNullYieldsNull !== 'boolean' && config.options.enableConcatNullYieldsNull !== null) {
|
612 | throw new TypeError('The "config.options.enableConcatNullYieldsNull" property must be of type boolean or null.');
|
613 | }
|
614 | this.config.options.enableConcatNullYieldsNull = config.options.enableConcatNullYieldsNull;
|
615 | }
|
616 | if (config.options.enableCursorCloseOnCommit !== undefined) {
|
617 | if (typeof config.options.enableCursorCloseOnCommit !== 'boolean' && config.options.enableCursorCloseOnCommit !== null) {
|
618 | throw new TypeError('The "config.options.enableCursorCloseOnCommit" property must be of type boolean or null.');
|
619 | }
|
620 | this.config.options.enableCursorCloseOnCommit = config.options.enableCursorCloseOnCommit;
|
621 | }
|
622 | if (config.options.enableImplicitTransactions !== undefined) {
|
623 | if (typeof config.options.enableImplicitTransactions !== 'boolean' && config.options.enableImplicitTransactions !== null) {
|
624 | throw new TypeError('The "config.options.enableImplicitTransactions" property must be of type boolean or null.');
|
625 | }
|
626 | this.config.options.enableImplicitTransactions = config.options.enableImplicitTransactions;
|
627 | }
|
628 | if (config.options.enableNumericRoundabort !== undefined) {
|
629 | if (typeof config.options.enableNumericRoundabort !== 'boolean' && config.options.enableNumericRoundabort !== null) {
|
630 | throw new TypeError('The "config.options.enableNumericRoundabort" property must be of type boolean or null.');
|
631 | }
|
632 | this.config.options.enableNumericRoundabort = config.options.enableNumericRoundabort;
|
633 | }
|
634 | if (config.options.enableQuotedIdentifier !== undefined) {
|
635 | if (typeof config.options.enableQuotedIdentifier !== 'boolean' && config.options.enableQuotedIdentifier !== null) {
|
636 | throw new TypeError('The "config.options.enableQuotedIdentifier" property must be of type boolean or null.');
|
637 | }
|
638 | this.config.options.enableQuotedIdentifier = config.options.enableQuotedIdentifier;
|
639 | }
|
640 | if (config.options.encrypt !== undefined) {
|
641 | if (typeof config.options.encrypt !== 'boolean') {
|
642 | if (config.options.encrypt !== 'strict') {
|
643 | throw new TypeError('The "encrypt" property must be set to "strict", or of type boolean.');
|
644 | }
|
645 | }
|
646 | this.config.options.encrypt = config.options.encrypt;
|
647 | }
|
648 | if (config.options.fallbackToDefaultDb !== undefined) {
|
649 | if (typeof config.options.fallbackToDefaultDb !== 'boolean') {
|
650 | throw new TypeError('The "config.options.fallbackToDefaultDb" property must be of type boolean.');
|
651 | }
|
652 | this.config.options.fallbackToDefaultDb = config.options.fallbackToDefaultDb;
|
653 | }
|
654 | if (config.options.instanceName !== undefined) {
|
655 | if (typeof config.options.instanceName !== 'string') {
|
656 | throw new TypeError('The "config.options.instanceName" property must be of type string.');
|
657 | }
|
658 | this.config.options.instanceName = config.options.instanceName;
|
659 | this.config.options.port = undefined;
|
660 | }
|
661 | if (config.options.isolationLevel !== undefined) {
|
662 | (0, _transaction.assertValidIsolationLevel)(config.options.isolationLevel, 'config.options.isolationLevel');
|
663 | this.config.options.isolationLevel = config.options.isolationLevel;
|
664 | }
|
665 | if (config.options.language !== undefined) {
|
666 | if (typeof config.options.language !== 'string' && config.options.language !== null) {
|
667 | throw new TypeError('The "config.options.language" property must be of type string or null.');
|
668 | }
|
669 | this.config.options.language = config.options.language;
|
670 | }
|
671 | if (config.options.localAddress !== undefined) {
|
672 | if (typeof config.options.localAddress !== 'string') {
|
673 | throw new TypeError('The "config.options.localAddress" property must be of type string.');
|
674 | }
|
675 | this.config.options.localAddress = config.options.localAddress;
|
676 | }
|
677 | if (config.options.multiSubnetFailover !== undefined) {
|
678 | if (typeof config.options.multiSubnetFailover !== 'boolean') {
|
679 | throw new TypeError('The "config.options.multiSubnetFailover" property must be of type boolean.');
|
680 | }
|
681 | this.config.options.multiSubnetFailover = config.options.multiSubnetFailover;
|
682 | }
|
683 | if (config.options.packetSize !== undefined) {
|
684 | if (typeof config.options.packetSize !== 'number') {
|
685 | throw new TypeError('The "config.options.packetSize" property must be of type number.');
|
686 | }
|
687 | this.config.options.packetSize = config.options.packetSize;
|
688 | }
|
689 | if (config.options.port !== undefined) {
|
690 | if (typeof config.options.port !== 'number') {
|
691 | throw new TypeError('The "config.options.port" property must be of type number.');
|
692 | }
|
693 | if (config.options.port <= 0 || config.options.port >= 65536) {
|
694 | throw new RangeError('The "config.options.port" property must be > 0 and < 65536');
|
695 | }
|
696 | this.config.options.port = config.options.port;
|
697 | this.config.options.instanceName = undefined;
|
698 | }
|
699 | if (config.options.readOnlyIntent !== undefined) {
|
700 | if (typeof config.options.readOnlyIntent !== 'boolean') {
|
701 | throw new TypeError('The "config.options.readOnlyIntent" property must be of type boolean.');
|
702 | }
|
703 | this.config.options.readOnlyIntent = config.options.readOnlyIntent;
|
704 | }
|
705 | if (config.options.requestTimeout !== undefined) {
|
706 | if (typeof config.options.requestTimeout !== 'number') {
|
707 | throw new TypeError('The "config.options.requestTimeout" property must be of type number.');
|
708 | }
|
709 | this.config.options.requestTimeout = config.options.requestTimeout;
|
710 | }
|
711 | if (config.options.maxRetriesOnTransientErrors !== undefined) {
|
712 | if (typeof config.options.maxRetriesOnTransientErrors !== 'number') {
|
713 | throw new TypeError('The "config.options.maxRetriesOnTransientErrors" property must be of type number.');
|
714 | }
|
715 | if (config.options.maxRetriesOnTransientErrors < 0) {
|
716 | throw new TypeError('The "config.options.maxRetriesOnTransientErrors" property must be equal or greater than 0.');
|
717 | }
|
718 | this.config.options.maxRetriesOnTransientErrors = config.options.maxRetriesOnTransientErrors;
|
719 | }
|
720 | if (config.options.connectionRetryInterval !== undefined) {
|
721 | if (typeof config.options.connectionRetryInterval !== 'number') {
|
722 | throw new TypeError('The "config.options.connectionRetryInterval" property must be of type number.');
|
723 | }
|
724 | if (config.options.connectionRetryInterval <= 0) {
|
725 | throw new TypeError('The "config.options.connectionRetryInterval" property must be greater than 0.');
|
726 | }
|
727 | this.config.options.connectionRetryInterval = config.options.connectionRetryInterval;
|
728 | }
|
729 | if (config.options.rowCollectionOnDone !== undefined) {
|
730 | if (typeof config.options.rowCollectionOnDone !== 'boolean') {
|
731 | throw new TypeError('The "config.options.rowCollectionOnDone" property must be of type boolean.');
|
732 | }
|
733 | this.config.options.rowCollectionOnDone = config.options.rowCollectionOnDone;
|
734 | }
|
735 | if (config.options.rowCollectionOnRequestCompletion !== undefined) {
|
736 | if (typeof config.options.rowCollectionOnRequestCompletion !== 'boolean') {
|
737 | throw new TypeError('The "config.options.rowCollectionOnRequestCompletion" property must be of type boolean.');
|
738 | }
|
739 | this.config.options.rowCollectionOnRequestCompletion = config.options.rowCollectionOnRequestCompletion;
|
740 | }
|
741 | if (config.options.tdsVersion !== undefined) {
|
742 | if (typeof config.options.tdsVersion !== 'string') {
|
743 | throw new TypeError('The "config.options.tdsVersion" property must be of type string.');
|
744 | }
|
745 | this.config.options.tdsVersion = config.options.tdsVersion;
|
746 | }
|
747 | if (config.options.textsize !== undefined) {
|
748 | if (typeof config.options.textsize !== 'number' && config.options.textsize !== null) {
|
749 | throw new TypeError('The "config.options.textsize" property must be of type number or null.');
|
750 | }
|
751 | if (config.options.textsize > 2147483647) {
|
752 | throw new TypeError('The "config.options.textsize" can\'t be greater than 2147483647.');
|
753 | } else if (config.options.textsize < -1) {
|
754 | throw new TypeError('The "config.options.textsize" can\'t be smaller than -1.');
|
755 | }
|
756 | this.config.options.textsize = config.options.textsize | 0;
|
757 | }
|
758 | if (config.options.trustServerCertificate !== undefined) {
|
759 | if (typeof config.options.trustServerCertificate !== 'boolean') {
|
760 | throw new TypeError('The "config.options.trustServerCertificate" property must be of type boolean.');
|
761 | }
|
762 | this.config.options.trustServerCertificate = config.options.trustServerCertificate;
|
763 | }
|
764 | if (config.options.serverName !== undefined) {
|
765 | if (typeof config.options.serverName !== 'string') {
|
766 | throw new TypeError('The "config.options.serverName" property must be of type string.');
|
767 | }
|
768 | this.config.options.serverName = config.options.serverName;
|
769 | }
|
770 | if (config.options.useColumnNames !== undefined) {
|
771 | if (typeof config.options.useColumnNames !== 'boolean') {
|
772 | throw new TypeError('The "config.options.useColumnNames" property must be of type boolean.');
|
773 | }
|
774 | this.config.options.useColumnNames = config.options.useColumnNames;
|
775 | }
|
776 | if (config.options.useUTC !== undefined) {
|
777 | if (typeof config.options.useUTC !== 'boolean') {
|
778 | throw new TypeError('The "config.options.useUTC" property must be of type boolean.');
|
779 | }
|
780 | this.config.options.useUTC = config.options.useUTC;
|
781 | }
|
782 | if (config.options.workstationId !== undefined) {
|
783 | if (typeof config.options.workstationId !== 'string') {
|
784 | throw new TypeError('The "config.options.workstationId" property must be of type string.');
|
785 | }
|
786 | this.config.options.workstationId = config.options.workstationId;
|
787 | }
|
788 | if (config.options.lowerCaseGuids !== undefined) {
|
789 | if (typeof config.options.lowerCaseGuids !== 'boolean') {
|
790 | throw new TypeError('The "config.options.lowerCaseGuids" property must be of type boolean.');
|
791 | }
|
792 | this.config.options.lowerCaseGuids = config.options.lowerCaseGuids;
|
793 | }
|
794 | }
|
795 | this.secureContextOptions = this.config.options.cryptoCredentialsDetails;
|
796 | if (this.secureContextOptions.secureOptions === undefined) {
|
797 | // If the caller has not specified their own `secureOptions`,
|
798 | // we set `SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS` here.
|
799 | // Older SQL Server instances running on older Windows versions have
|
800 | // trouble with the BEAST workaround in OpenSSL.
|
801 | // As BEAST is a browser specific exploit, we can just disable this option here.
|
802 | this.secureContextOptions = Object.create(this.secureContextOptions, {
|
803 | secureOptions: {
|
804 | value: _constants.default.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
805 | }
|
806 | });
|
807 | }
|
808 | this.debug = this.createDebug();
|
809 | this.inTransaction = false;
|
810 | this.transactionDescriptors = [Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])];
|
811 |
|
812 | // 'beginTransaction', 'commitTransaction' and 'rollbackTransaction'
|
813 | // events are utilized to maintain inTransaction property state which in
|
814 | // turn is used in managing transactions. These events are only fired for
|
815 | // TDS version 7.2 and beyond. The properties below are used to emulate
|
816 | // equivalent behavior for TDS versions before 7.2.
|
817 | this.transactionDepth = 0;
|
818 | this.isSqlBatch = false;
|
819 | this.closed = false;
|
820 | this.messageBuffer = Buffer.alloc(0);
|
821 | this.curTransientRetryCount = 0;
|
822 | this.transientErrorLookup = new _transientErrorLookup.TransientErrorLookup();
|
823 | this.state = this.STATE.INITIALIZED;
|
824 | this._cancelAfterRequestSent = () => {
|
825 | this.messageIo.sendMessage(_packet.TYPE.ATTENTION);
|
826 | this.createCancelTimer();
|
827 | };
|
828 | }
|
829 | connect(connectListener) {
|
830 | if (this.state !== this.STATE.INITIALIZED) {
|
831 | throw new _errors.ConnectionError('`.connect` can not be called on a Connection in `' + this.state.name + '` state.');
|
832 | }
|
833 | if (connectListener) {
|
834 | const onConnect = err => {
|
835 | this.removeListener('error', onError);
|
836 | connectListener(err);
|
837 | };
|
838 | const onError = err => {
|
839 | this.removeListener('connect', onConnect);
|
840 | connectListener(err);
|
841 | };
|
842 | this.once('connect', onConnect);
|
843 | this.once('error', onError);
|
844 | }
|
845 | this.transitionTo(this.STATE.CONNECTING);
|
846 | }
|
847 |
|
848 | /**
|
849 | * The server has reported that the charset has changed.
|
850 | */
|
851 |
|
852 | /**
|
853 | * The attempt to connect and validate has completed.
|
854 | */
|
855 |
|
856 | /**
|
857 | * The server has reported that the active database has changed.
|
858 | * This may be as a result of a successful login, or a `use` statement.
|
859 | */
|
860 |
|
861 | /**
|
862 | * A debug message is available. It may be logged or ignored.
|
863 | */
|
864 |
|
865 | /**
|
866 | * Internal error occurs.
|
867 | */
|
868 |
|
869 | /**
|
870 | * The server has issued an error message.
|
871 | */
|
872 |
|
873 | /**
|
874 | * The connection has ended.
|
875 | *
|
876 | * This may be as a result of the client calling [[close]], the server
|
877 | * closing the connection, or a network error.
|
878 | */
|
879 |
|
880 | /**
|
881 | * The server has issued an information message.
|
882 | */
|
883 |
|
884 | /**
|
885 | * The server has reported that the language has changed.
|
886 | */
|
887 |
|
888 | /**
|
889 | * The connection was reset.
|
890 | */
|
891 |
|
892 | /**
|
893 | * A secure connection has been established.
|
894 | */
|
895 |
|
896 | on(event, listener) {
|
897 | return super.on(event, listener);
|
898 | }
|
899 |
|
900 | /**
|
901 | * @private
|
902 | */
|
903 |
|
904 | /**
|
905 | * @private
|
906 | */
|
907 |
|
908 | /**
|
909 | * @private
|
910 | */
|
911 |
|
912 | /**
|
913 | * @private
|
914 | */
|
915 |
|
916 | /**
|
917 | * @private
|
918 | */
|
919 |
|
920 | /**
|
921 | * @private
|
922 | */
|
923 |
|
924 | /**
|
925 | * @private
|
926 | */
|
927 |
|
928 | /**
|
929 | * @private
|
930 | */
|
931 |
|
932 | /**
|
933 | * @private
|
934 | */
|
935 |
|
936 | /**
|
937 | * @private
|
938 | */
|
939 |
|
940 | /**
|
941 | * @private
|
942 | */
|
943 |
|
944 | /**
|
945 | * @private
|
946 | */
|
947 |
|
948 | /**
|
949 | * @private
|
950 | */
|
951 |
|
952 | /**
|
953 | * @private
|
954 | */
|
955 |
|
956 | emit(event, ...args) {
|
957 | return super.emit(event, ...args);
|
958 | }
|
959 |
|
960 | /**
|
961 | * Closes the connection to the database.
|
962 | *
|
963 | * The [[Event_end]] will be emitted once the connection has been closed.
|
964 | */
|
965 | close() {
|
966 | this.transitionTo(this.STATE.FINAL);
|
967 | }
|
968 |
|
969 | /**
|
970 | * @private
|
971 | */
|
972 | initialiseConnection() {
|
973 | const signal = this.createConnectTimer();
|
974 | if (this.config.options.port) {
|
975 | return this.connectOnPort(this.config.options.port, this.config.options.multiSubnetFailover, signal, this.config.options.connector);
|
976 | } else {
|
977 | return (0, _instanceLookup.instanceLookup)({
|
978 | server: this.config.server,
|
979 | instanceName: this.config.options.instanceName,
|
980 | timeout: this.config.options.connectTimeout,
|
981 | signal: signal
|
982 | }).then(port => {
|
983 | process.nextTick(() => {
|
984 | this.connectOnPort(port, this.config.options.multiSubnetFailover, signal, this.config.options.connector);
|
985 | });
|
986 | }, err => {
|
987 | this.clearConnectTimer();
|
988 | if (signal.aborted) {
|
989 | // Ignore the AbortError for now, this is still handled by the connectTimer firing
|
990 | return;
|
991 | }
|
992 | process.nextTick(() => {
|
993 | this.emit('connect', new _errors.ConnectionError(err.message, 'EINSTLOOKUP'));
|
994 | });
|
995 | });
|
996 | }
|
997 | }
|
998 |
|
999 | /**
|
1000 | * @private
|
1001 | */
|
1002 | cleanupConnection(cleanupType) {
|
1003 | if (!this.closed) {
|
1004 | this.clearConnectTimer();
|
1005 | this.clearRequestTimer();
|
1006 | this.clearRetryTimer();
|
1007 | this.closeConnection();
|
1008 | if (cleanupType === CLEANUP_TYPE.REDIRECT) {
|
1009 | this.emit('rerouting');
|
1010 | } else if (cleanupType !== CLEANUP_TYPE.RETRY) {
|
1011 | process.nextTick(() => {
|
1012 | this.emit('end');
|
1013 | });
|
1014 | }
|
1015 | const request = this.request;
|
1016 | if (request) {
|
1017 | const err = new _errors.RequestError('Connection closed before request completed.', 'ECLOSE');
|
1018 | request.callback(err);
|
1019 | this.request = undefined;
|
1020 | }
|
1021 | this.closed = true;
|
1022 | this.loginError = undefined;
|
1023 | }
|
1024 | }
|
1025 |
|
1026 | /**
|
1027 | * @private
|
1028 | */
|
1029 | createDebug() {
|
1030 | const debug = new _debug.default(this.config.options.debug);
|
1031 | debug.on('debug', message => {
|
1032 | this.emit('debug', message);
|
1033 | });
|
1034 | return debug;
|
1035 | }
|
1036 |
|
1037 | /**
|
1038 | * @private
|
1039 | */
|
1040 | createTokenStreamParser(message, handler) {
|
1041 | return new _tokenStreamParser.Parser(message, this.debug, handler, this.config.options);
|
1042 | }
|
1043 | socketHandlingForSendPreLogin(socket) {
|
1044 | socket.on('error', error => {
|
1045 | this.socketError(error);
|
1046 | });
|
1047 | socket.on('close', () => {
|
1048 | this.socketClose();
|
1049 | });
|
1050 | socket.on('end', () => {
|
1051 | this.socketEnd();
|
1052 | });
|
1053 | socket.setKeepAlive(true, KEEP_ALIVE_INITIAL_DELAY);
|
1054 | this.messageIo = new _messageIo.default(socket, this.config.options.packetSize, this.debug);
|
1055 | this.messageIo.on('secure', cleartext => {
|
1056 | this.emit('secure', cleartext);
|
1057 | });
|
1058 | this.socket = socket;
|
1059 | this.closed = false;
|
1060 | this.debug.log('connected to ' + this.config.server + ':' + this.config.options.port);
|
1061 | this.sendPreLogin();
|
1062 | this.transitionTo(this.STATE.SENT_PRELOGIN);
|
1063 | }
|
1064 | wrapWithTls(socket, signal) {
|
1065 | signal.throwIfAborted();
|
1066 | return new Promise((resolve, reject) => {
|
1067 | const secureContext = tls.createSecureContext(this.secureContextOptions);
|
1068 | // If connect to an ip address directly,
|
1069 | // need to set the servername to an empty string
|
1070 | // if the user has not given a servername explicitly
|
1071 | const serverName = !net.isIP(this.config.server) ? this.config.server : '';
|
1072 | const encryptOptions = {
|
1073 | host: this.config.server,
|
1074 | socket: socket,
|
1075 | ALPNProtocols: ['tds/8.0'],
|
1076 | secureContext: secureContext,
|
1077 | servername: this.config.options.serverName ? this.config.options.serverName : serverName
|
1078 | };
|
1079 | const encryptsocket = tls.connect(encryptOptions);
|
1080 | const onAbort = () => {
|
1081 | encryptsocket.removeListener('error', onError);
|
1082 | encryptsocket.removeListener('connect', onConnect);
|
1083 | encryptsocket.destroy();
|
1084 | reject(signal.reason);
|
1085 | };
|
1086 | const onError = err => {
|
1087 | signal.removeEventListener('abort', onAbort);
|
1088 | encryptsocket.removeListener('error', onError);
|
1089 | encryptsocket.removeListener('connect', onConnect);
|
1090 | encryptsocket.destroy();
|
1091 | reject(err);
|
1092 | };
|
1093 | const onConnect = () => {
|
1094 | signal.removeEventListener('abort', onAbort);
|
1095 | encryptsocket.removeListener('error', onError);
|
1096 | encryptsocket.removeListener('connect', onConnect);
|
1097 | resolve(encryptsocket);
|
1098 | };
|
1099 | signal.addEventListener('abort', onAbort, {
|
1100 | once: true
|
1101 | });
|
1102 | encryptsocket.on('error', onError);
|
1103 | encryptsocket.on('secureConnect', onConnect);
|
1104 | });
|
1105 | }
|
1106 | connectOnPort(port, multiSubnetFailover, signal, customConnector) {
|
1107 | const connectOpts = {
|
1108 | host: this.routingData ? this.routingData.server : this.config.server,
|
1109 | port: this.routingData ? this.routingData.port : port,
|
1110 | localAddress: this.config.options.localAddress
|
1111 | };
|
1112 | const connect = customConnector || (multiSubnetFailover ? _connector.connectInParallel : _connector.connectInSequence);
|
1113 | (async () => {
|
1114 | let socket = await connect(connectOpts, _dns.default.lookup, signal);
|
1115 | if (this.config.options.encrypt === 'strict') {
|
1116 | try {
|
1117 | // Wrap the socket with TLS for TDS 8.0
|
1118 | socket = await this.wrapWithTls(socket, signal);
|
1119 | } catch (err) {
|
1120 | socket.end();
|
1121 | throw err;
|
1122 | }
|
1123 | }
|
1124 | this.socketHandlingForSendPreLogin(socket);
|
1125 | })().catch(err => {
|
1126 | this.clearConnectTimer();
|
1127 | if (signal.aborted) {
|
1128 | return;
|
1129 | }
|
1130 | process.nextTick(() => {
|
1131 | this.socketError(err);
|
1132 | });
|
1133 | });
|
1134 | }
|
1135 |
|
1136 | /**
|
1137 | * @private
|
1138 | */
|
1139 | closeConnection() {
|
1140 | if (this.socket) {
|
1141 | this.socket.destroy();
|
1142 | }
|
1143 | }
|
1144 |
|
1145 | /**
|
1146 | * @private
|
1147 | */
|
1148 | createConnectTimer() {
|
1149 | const controller = new AbortController();
|
1150 | this.connectTimer = setTimeout(() => {
|
1151 | controller.abort();
|
1152 | this.connectTimeout();
|
1153 | }, this.config.options.connectTimeout);
|
1154 | return controller.signal;
|
1155 | }
|
1156 |
|
1157 | /**
|
1158 | * @private
|
1159 | */
|
1160 | createCancelTimer() {
|
1161 | this.clearCancelTimer();
|
1162 | const timeout = this.config.options.cancelTimeout;
|
1163 | if (timeout > 0) {
|
1164 | this.cancelTimer = setTimeout(() => {
|
1165 | this.cancelTimeout();
|
1166 | }, timeout);
|
1167 | }
|
1168 | }
|
1169 |
|
1170 | /**
|
1171 | * @private
|
1172 | */
|
1173 | createRequestTimer() {
|
1174 | this.clearRequestTimer(); // release old timer, just to be safe
|
1175 | const request = this.request;
|
1176 | const timeout = request.timeout !== undefined ? request.timeout : this.config.options.requestTimeout;
|
1177 | if (timeout) {
|
1178 | this.requestTimer = setTimeout(() => {
|
1179 | this.requestTimeout();
|
1180 | }, timeout);
|
1181 | }
|
1182 | }
|
1183 |
|
1184 | /**
|
1185 | * @private
|
1186 | */
|
1187 | createRetryTimer() {
|
1188 | this.clearRetryTimer();
|
1189 | this.retryTimer = setTimeout(() => {
|
1190 | this.retryTimeout();
|
1191 | }, this.config.options.connectionRetryInterval);
|
1192 | }
|
1193 |
|
1194 | /**
|
1195 | * @private
|
1196 | */
|
1197 | connectTimeout() {
|
1198 | const hostPostfix = this.config.options.port ? `:${this.config.options.port}` : `\\${this.config.options.instanceName}`;
|
1199 | // If we have routing data stored, this connection has been redirected
|
1200 | const server = this.routingData ? this.routingData.server : this.config.server;
|
1201 | const port = this.routingData ? `:${this.routingData.port}` : hostPostfix;
|
1202 | // Grab the target host from the connection configuration, and from a redirect message
|
1203 | // otherwise, leave the message empty.
|
1204 | const routingMessage = this.routingData ? ` (redirected from ${this.config.server}${hostPostfix})` : '';
|
1205 | const message = `Failed to connect to ${server}${port}${routingMessage} in ${this.config.options.connectTimeout}ms`;
|
1206 | this.debug.log(message);
|
1207 | this.emit('connect', new _errors.ConnectionError(message, 'ETIMEOUT'));
|
1208 | this.connectTimer = undefined;
|
1209 | this.dispatchEvent('connectTimeout');
|
1210 | }
|
1211 |
|
1212 | /**
|
1213 | * @private
|
1214 | */
|
1215 | cancelTimeout() {
|
1216 | const message = `Failed to cancel request in ${this.config.options.cancelTimeout}ms`;
|
1217 | this.debug.log(message);
|
1218 | this.dispatchEvent('socketError', new _errors.ConnectionError(message, 'ETIMEOUT'));
|
1219 | }
|
1220 |
|
1221 | /**
|
1222 | * @private
|
1223 | */
|
1224 | requestTimeout() {
|
1225 | this.requestTimer = undefined;
|
1226 | const request = this.request;
|
1227 | request.cancel();
|
1228 | const timeout = request.timeout !== undefined ? request.timeout : this.config.options.requestTimeout;
|
1229 | const message = 'Timeout: Request failed to complete in ' + timeout + 'ms';
|
1230 | request.error = new _errors.RequestError(message, 'ETIMEOUT');
|
1231 | }
|
1232 |
|
1233 | /**
|
1234 | * @private
|
1235 | */
|
1236 | retryTimeout() {
|
1237 | this.retryTimer = undefined;
|
1238 | this.emit('retry');
|
1239 | this.transitionTo(this.STATE.CONNECTING);
|
1240 | }
|
1241 |
|
1242 | /**
|
1243 | * @private
|
1244 | */
|
1245 | clearConnectTimer() {
|
1246 | if (this.connectTimer) {
|
1247 | clearTimeout(this.connectTimer);
|
1248 | this.connectTimer = undefined;
|
1249 | }
|
1250 | }
|
1251 |
|
1252 | /**
|
1253 | * @private
|
1254 | */
|
1255 | clearCancelTimer() {
|
1256 | if (this.cancelTimer) {
|
1257 | clearTimeout(this.cancelTimer);
|
1258 | this.cancelTimer = undefined;
|
1259 | }
|
1260 | }
|
1261 |
|
1262 | /**
|
1263 | * @private
|
1264 | */
|
1265 | clearRequestTimer() {
|
1266 | if (this.requestTimer) {
|
1267 | clearTimeout(this.requestTimer);
|
1268 | this.requestTimer = undefined;
|
1269 | }
|
1270 | }
|
1271 |
|
1272 | /**
|
1273 | * @private
|
1274 | */
|
1275 | clearRetryTimer() {
|
1276 | if (this.retryTimer) {
|
1277 | clearTimeout(this.retryTimer);
|
1278 | this.retryTimer = undefined;
|
1279 | }
|
1280 | }
|
1281 |
|
1282 | /**
|
1283 | * @private
|
1284 | */
|
1285 | transitionTo(newState) {
|
1286 | if (this.state === newState) {
|
1287 | this.debug.log('State is already ' + newState.name);
|
1288 | return;
|
1289 | }
|
1290 | if (this.state && this.state.exit) {
|
1291 | this.state.exit.call(this, newState);
|
1292 | }
|
1293 | this.debug.log('State change: ' + (this.state ? this.state.name : 'undefined') + ' -> ' + newState.name);
|
1294 | this.state = newState;
|
1295 | if (this.state.enter) {
|
1296 | this.state.enter.apply(this);
|
1297 | }
|
1298 | }
|
1299 |
|
1300 | /**
|
1301 | * @private
|
1302 | */
|
1303 | getEventHandler(eventName) {
|
1304 | const handler = this.state.events[eventName];
|
1305 | if (!handler) {
|
1306 | throw new Error(`No event '${eventName}' in state '${this.state.name}'`);
|
1307 | }
|
1308 | return handler;
|
1309 | }
|
1310 |
|
1311 | /**
|
1312 | * @private
|
1313 | */
|
1314 | dispatchEvent(eventName, ...args) {
|
1315 | const handler = this.state.events[eventName];
|
1316 | if (handler) {
|
1317 | handler.apply(this, args);
|
1318 | } else {
|
1319 | this.emit('error', new Error(`No event '${eventName}' in state '${this.state.name}'`));
|
1320 | this.close();
|
1321 | }
|
1322 | }
|
1323 |
|
1324 | /**
|
1325 | * @private
|
1326 | */
|
1327 | socketError(error) {
|
1328 | if (this.state === this.STATE.CONNECTING || this.state === this.STATE.SENT_TLSSSLNEGOTIATION) {
|
1329 | const hostPostfix = this.config.options.port ? `:${this.config.options.port}` : `\\${this.config.options.instanceName}`;
|
1330 | // If we have routing data stored, this connection has been redirected
|
1331 | const server = this.routingData ? this.routingData.server : this.config.server;
|
1332 | const port = this.routingData ? `:${this.routingData.port}` : hostPostfix;
|
1333 | // Grab the target host from the connection configuration, and from a redirect message
|
1334 | // otherwise, leave the message empty.
|
1335 | const routingMessage = this.routingData ? ` (redirected from ${this.config.server}${hostPostfix})` : '';
|
1336 | const message = `Failed to connect to ${server}${port}${routingMessage} - ${error.message}`;
|
1337 | this.debug.log(message);
|
1338 | this.emit('connect', new _errors.ConnectionError(message, 'ESOCKET'));
|
1339 | } else {
|
1340 | const message = `Connection lost - ${error.message}`;
|
1341 | this.debug.log(message);
|
1342 | this.emit('error', new _errors.ConnectionError(message, 'ESOCKET'));
|
1343 | }
|
1344 | this.dispatchEvent('socketError', error);
|
1345 | }
|
1346 |
|
1347 | /**
|
1348 | * @private
|
1349 | */
|
1350 | socketEnd() {
|
1351 | this.debug.log('socket ended');
|
1352 | if (this.state !== this.STATE.FINAL) {
|
1353 | const error = new Error('socket hang up');
|
1354 | error.code = 'ECONNRESET';
|
1355 | this.socketError(error);
|
1356 | }
|
1357 | }
|
1358 |
|
1359 | /**
|
1360 | * @private
|
1361 | */
|
1362 | socketClose() {
|
1363 | this.debug.log('connection to ' + this.config.server + ':' + this.config.options.port + ' closed');
|
1364 | if (this.state === this.STATE.REROUTING) {
|
1365 | this.debug.log('Rerouting to ' + this.routingData.server + ':' + this.routingData.port);
|
1366 | this.dispatchEvent('reconnect');
|
1367 | } else if (this.state === this.STATE.TRANSIENT_FAILURE_RETRY) {
|
1368 | const server = this.routingData ? this.routingData.server : this.config.server;
|
1369 | const port = this.routingData ? this.routingData.port : this.config.options.port;
|
1370 | this.debug.log('Retry after transient failure connecting to ' + server + ':' + port);
|
1371 | this.dispatchEvent('retry');
|
1372 | } else {
|
1373 | this.transitionTo(this.STATE.FINAL);
|
1374 | }
|
1375 | }
|
1376 |
|
1377 | /**
|
1378 | * @private
|
1379 | */
|
1380 | sendPreLogin() {
|
1381 | const [, major, minor, build] = /^(\d+)\.(\d+)\.(\d+)/.exec(_package.version) ?? ['0.0.0', '0', '0', '0'];
|
1382 | const payload = new _preloginPayload.default({
|
1383 | // If encrypt setting is set to 'strict', then we should have already done the encryption before calling
|
1384 | // this function. Therefore, the encrypt will be set to false here.
|
1385 | // Otherwise, we will set encrypt here based on the encrypt Boolean value from the configuration.
|
1386 | encrypt: typeof this.config.options.encrypt === 'boolean' && this.config.options.encrypt,
|
1387 | version: {
|
1388 | major: Number(major),
|
1389 | minor: Number(minor),
|
1390 | build: Number(build),
|
1391 | subbuild: 0
|
1392 | }
|
1393 | });
|
1394 | this.messageIo.sendMessage(_packet.TYPE.PRELOGIN, payload.data);
|
1395 | this.debug.payload(function () {
|
1396 | return payload.toString(' ');
|
1397 | });
|
1398 | }
|
1399 |
|
1400 | /**
|
1401 | * @private
|
1402 | */
|
1403 | sendLogin7Packet() {
|
1404 | const payload = new _login7Payload.default({
|
1405 | tdsVersion: _tdsVersions.versions[this.config.options.tdsVersion],
|
1406 | packetSize: this.config.options.packetSize,
|
1407 | clientProgVer: 0,
|
1408 | clientPid: process.pid,
|
1409 | connectionId: 0,
|
1410 | clientTimeZone: new Date().getTimezoneOffset(),
|
1411 | clientLcid: 0x00000409
|
1412 | });
|
1413 | const {
|
1414 | authentication
|
1415 | } = this.config;
|
1416 | switch (authentication.type) {
|
1417 | case 'azure-active-directory-password':
|
1418 | payload.fedAuth = {
|
1419 | type: 'ADAL',
|
1420 | echo: this.fedAuthRequired,
|
1421 | workflow: 'default'
|
1422 | };
|
1423 | break;
|
1424 | case 'azure-active-directory-access-token':
|
1425 | payload.fedAuth = {
|
1426 | type: 'SECURITYTOKEN',
|
1427 | echo: this.fedAuthRequired,
|
1428 | fedAuthToken: authentication.options.token
|
1429 | };
|
1430 | break;
|
1431 | case 'azure-active-directory-msi-vm':
|
1432 | case 'azure-active-directory-default':
|
1433 | case 'azure-active-directory-msi-app-service':
|
1434 | case 'azure-active-directory-service-principal-secret':
|
1435 | payload.fedAuth = {
|
1436 | type: 'ADAL',
|
1437 | echo: this.fedAuthRequired,
|
1438 | workflow: 'integrated'
|
1439 | };
|
1440 | break;
|
1441 | case 'ntlm':
|
1442 | payload.sspi = (0, _ntlm.createNTLMRequest)({
|
1443 | domain: authentication.options.domain
|
1444 | });
|
1445 | break;
|
1446 | default:
|
1447 | payload.userName = authentication.options.userName;
|
1448 | payload.password = authentication.options.password;
|
1449 | }
|
1450 | payload.hostname = this.config.options.workstationId || _os.default.hostname();
|
1451 | payload.serverName = this.routingData ? this.routingData.server : this.config.server;
|
1452 | payload.appName = this.config.options.appName || 'Tedious';
|
1453 | payload.libraryName = _library.name;
|
1454 | payload.language = this.config.options.language;
|
1455 | payload.database = this.config.options.database;
|
1456 | payload.clientId = Buffer.from([1, 2, 3, 4, 5, 6]);
|
1457 | payload.readOnlyIntent = this.config.options.readOnlyIntent;
|
1458 | payload.initDbFatal = !this.config.options.fallbackToDefaultDb;
|
1459 | this.routingData = undefined;
|
1460 | this.messageIo.sendMessage(_packet.TYPE.LOGIN7, payload.toBuffer());
|
1461 | this.debug.payload(function () {
|
1462 | return payload.toString(' ');
|
1463 | });
|
1464 | }
|
1465 |
|
1466 | /**
|
1467 | * @private
|
1468 | */
|
1469 | sendFedAuthTokenMessage(token) {
|
1470 | const accessTokenLen = Buffer.byteLength(token, 'ucs2');
|
1471 | const data = Buffer.alloc(8 + accessTokenLen);
|
1472 | let offset = 0;
|
1473 | offset = data.writeUInt32LE(accessTokenLen + 4, offset);
|
1474 | offset = data.writeUInt32LE(accessTokenLen, offset);
|
1475 | data.write(token, offset, 'ucs2');
|
1476 | this.messageIo.sendMessage(_packet.TYPE.FEDAUTH_TOKEN, data);
|
1477 | // sent the fedAuth token message, the rest is similar to standard login 7
|
1478 | this.transitionTo(this.STATE.SENT_LOGIN7_WITH_STANDARD_LOGIN);
|
1479 | }
|
1480 |
|
1481 | /**
|
1482 | * @private
|
1483 | */
|
1484 | sendInitialSql() {
|
1485 | const payload = new _sqlbatchPayload.default(this.getInitialSql(), this.currentTransactionDescriptor(), this.config.options);
|
1486 | const message = new _message.default({
|
1487 | type: _packet.TYPE.SQL_BATCH
|
1488 | });
|
1489 | this.messageIo.outgoingMessageStream.write(message);
|
1490 | _stream.Readable.from(payload).pipe(message);
|
1491 | }
|
1492 |
|
1493 | /**
|
1494 | * @private
|
1495 | */
|
1496 | getInitialSql() {
|
1497 | const options = [];
|
1498 | if (this.config.options.enableAnsiNull === true) {
|
1499 | options.push('set ansi_nulls on');
|
1500 | } else if (this.config.options.enableAnsiNull === false) {
|
1501 | options.push('set ansi_nulls off');
|
1502 | }
|
1503 | if (this.config.options.enableAnsiNullDefault === true) {
|
1504 | options.push('set ansi_null_dflt_on on');
|
1505 | } else if (this.config.options.enableAnsiNullDefault === false) {
|
1506 | options.push('set ansi_null_dflt_on off');
|
1507 | }
|
1508 | if (this.config.options.enableAnsiPadding === true) {
|
1509 | options.push('set ansi_padding on');
|
1510 | } else if (this.config.options.enableAnsiPadding === false) {
|
1511 | options.push('set ansi_padding off');
|
1512 | }
|
1513 | if (this.config.options.enableAnsiWarnings === true) {
|
1514 | options.push('set ansi_warnings on');
|
1515 | } else if (this.config.options.enableAnsiWarnings === false) {
|
1516 | options.push('set ansi_warnings off');
|
1517 | }
|
1518 | if (this.config.options.enableArithAbort === true) {
|
1519 | options.push('set arithabort on');
|
1520 | } else if (this.config.options.enableArithAbort === false) {
|
1521 | options.push('set arithabort off');
|
1522 | }
|
1523 | if (this.config.options.enableConcatNullYieldsNull === true) {
|
1524 | options.push('set concat_null_yields_null on');
|
1525 | } else if (this.config.options.enableConcatNullYieldsNull === false) {
|
1526 | options.push('set concat_null_yields_null off');
|
1527 | }
|
1528 | if (this.config.options.enableCursorCloseOnCommit === true) {
|
1529 | options.push('set cursor_close_on_commit on');
|
1530 | } else if (this.config.options.enableCursorCloseOnCommit === false) {
|
1531 | options.push('set cursor_close_on_commit off');
|
1532 | }
|
1533 | if (this.config.options.datefirst !== null) {
|
1534 | options.push(`set datefirst ${this.config.options.datefirst}`);
|
1535 | }
|
1536 | if (this.config.options.dateFormat !== null) {
|
1537 | options.push(`set dateformat ${this.config.options.dateFormat}`);
|
1538 | }
|
1539 | if (this.config.options.enableImplicitTransactions === true) {
|
1540 | options.push('set implicit_transactions on');
|
1541 | } else if (this.config.options.enableImplicitTransactions === false) {
|
1542 | options.push('set implicit_transactions off');
|
1543 | }
|
1544 | if (this.config.options.language !== null) {
|
1545 | options.push(`set language ${this.config.options.language}`);
|
1546 | }
|
1547 | if (this.config.options.enableNumericRoundabort === true) {
|
1548 | options.push('set numeric_roundabort on');
|
1549 | } else if (this.config.options.enableNumericRoundabort === false) {
|
1550 | options.push('set numeric_roundabort off');
|
1551 | }
|
1552 | if (this.config.options.enableQuotedIdentifier === true) {
|
1553 | options.push('set quoted_identifier on');
|
1554 | } else if (this.config.options.enableQuotedIdentifier === false) {
|
1555 | options.push('set quoted_identifier off');
|
1556 | }
|
1557 | if (this.config.options.textsize !== null) {
|
1558 | options.push(`set textsize ${this.config.options.textsize}`);
|
1559 | }
|
1560 | if (this.config.options.connectionIsolationLevel !== null) {
|
1561 | options.push(`set transaction isolation level ${this.getIsolationLevelText(this.config.options.connectionIsolationLevel)}`);
|
1562 | }
|
1563 | if (this.config.options.abortTransactionOnError === true) {
|
1564 | options.push('set xact_abort on');
|
1565 | } else if (this.config.options.abortTransactionOnError === false) {
|
1566 | options.push('set xact_abort off');
|
1567 | }
|
1568 | return options.join('\n');
|
1569 | }
|
1570 |
|
1571 | /**
|
1572 | * @private
|
1573 | */
|
1574 | processedInitialSql() {
|
1575 | this.clearConnectTimer();
|
1576 | this.emit('connect');
|
1577 | }
|
1578 |
|
1579 | /**
|
1580 | * Execute the SQL batch represented by [[Request]].
|
1581 | * There is no param support, and unlike [[Request.execSql]],
|
1582 | * it is not likely that SQL Server will reuse the execution plan it generates for the SQL.
|
1583 | *
|
1584 | * In almost all cases, [[Request.execSql]] will be a better choice.
|
1585 | *
|
1586 | * @param request A [[Request]] object representing the request.
|
1587 | */
|
1588 | execSqlBatch(request) {
|
1589 | this.makeRequest(request, _packet.TYPE.SQL_BATCH, new _sqlbatchPayload.default(request.sqlTextOrProcedure, this.currentTransactionDescriptor(), this.config.options));
|
1590 | }
|
1591 |
|
1592 | /**
|
1593 | * Execute the SQL represented by [[Request]].
|
1594 | *
|
1595 | * As `sp_executesql` is used to execute the SQL, if the same SQL is executed multiples times
|
1596 | * using this function, the SQL Server query optimizer is likely to reuse the execution plan it generates
|
1597 | * for the first execution. This may also result in SQL server treating the request like a stored procedure
|
1598 | * which can result in the [[Event_doneInProc]] or [[Event_doneProc]] events being emitted instead of the
|
1599 | * [[Event_done]] event you might expect. Using [[execSqlBatch]] will prevent this from occurring but may have a negative performance impact.
|
1600 | *
|
1601 | * Beware of the way that scoping rules apply, and how they may [affect local temp tables](http://weblogs.sqlteam.com/mladenp/archive/2006/11/03/17197.aspx)
|
1602 | * If you're running in to scoping issues, then [[execSqlBatch]] may be a better choice.
|
1603 | * See also [issue #24](https://github.com/pekim/tedious/issues/24)
|
1604 | *
|
1605 | * @param request A [[Request]] object representing the request.
|
1606 | */
|
1607 | execSql(request) {
|
1608 | try {
|
1609 | request.validateParameters(this.databaseCollation);
|
1610 | } catch (error) {
|
1611 | request.error = error;
|
1612 | process.nextTick(() => {
|
1613 | this.debug.log(error.message);
|
1614 | request.callback(error);
|
1615 | });
|
1616 | return;
|
1617 | }
|
1618 | const parameters = [];
|
1619 | parameters.push({
|
1620 | type: _dataType.TYPES.NVarChar,
|
1621 | name: 'statement',
|
1622 | value: request.sqlTextOrProcedure,
|
1623 | output: false,
|
1624 | length: undefined,
|
1625 | precision: undefined,
|
1626 | scale: undefined
|
1627 | });
|
1628 | if (request.parameters.length) {
|
1629 | parameters.push({
|
1630 | type: _dataType.TYPES.NVarChar,
|
1631 | name: 'params',
|
1632 | value: request.makeParamsParameter(request.parameters),
|
1633 | output: false,
|
1634 | length: undefined,
|
1635 | precision: undefined,
|
1636 | scale: undefined
|
1637 | });
|
1638 | parameters.push(...request.parameters);
|
1639 | }
|
1640 | this.makeRequest(request, _packet.TYPE.RPC_REQUEST, new _rpcrequestPayload.default(_specialStoredProcedure.default.Sp_ExecuteSql, parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
|
1641 | }
|
1642 |
|
1643 | /**
|
1644 | * Creates a new BulkLoad instance.
|
1645 | *
|
1646 | * @param table The name of the table to bulk-insert into.
|
1647 | * @param options A set of bulk load options.
|
1648 | */
|
1649 |
|
1650 | newBulkLoad(table, callbackOrOptions, callback) {
|
1651 | let options;
|
1652 | if (callback === undefined) {
|
1653 | callback = callbackOrOptions;
|
1654 | options = {};
|
1655 | } else {
|
1656 | options = callbackOrOptions;
|
1657 | }
|
1658 | if (typeof options !== 'object') {
|
1659 | throw new TypeError('"options" argument must be an object');
|
1660 | }
|
1661 | return new _bulkLoad.default(table, this.databaseCollation, this.config.options, options, callback);
|
1662 | }
|
1663 |
|
1664 | /**
|
1665 | * Execute a [[BulkLoad]].
|
1666 | *
|
1667 | * ```js
|
1668 | * // We want to perform a bulk load into a table with the following format:
|
1669 | * // CREATE TABLE employees (first_name nvarchar(255), last_name nvarchar(255), day_of_birth date);
|
1670 | *
|
1671 | * const bulkLoad = connection.newBulkLoad('employees', (err, rowCount) => {
|
1672 | * // ...
|
1673 | * });
|
1674 | *
|
1675 | * // First, we need to specify the columns that we want to write to,
|
1676 | * // and their definitions. These definitions must match the actual table,
|
1677 | * // otherwise the bulk load will fail.
|
1678 | * bulkLoad.addColumn('first_name', TYPES.NVarchar, { nullable: false });
|
1679 | * bulkLoad.addColumn('last_name', TYPES.NVarchar, { nullable: false });
|
1680 | * bulkLoad.addColumn('date_of_birth', TYPES.Date, { nullable: false });
|
1681 | *
|
1682 | * // Execute a bulk load with a predefined list of rows.
|
1683 | * //
|
1684 | * // Note that these rows are held in memory until the
|
1685 | * // bulk load was performed, so if you need to write a large
|
1686 | * // number of rows (e.g. by reading from a CSV file),
|
1687 | * // passing an `AsyncIterable` is advisable to keep memory usage low.
|
1688 | * connection.execBulkLoad(bulkLoad, [
|
1689 | * { 'first_name': 'Steve', 'last_name': 'Jobs', 'day_of_birth': new Date('02-24-1955') },
|
1690 | * { 'first_name': 'Bill', 'last_name': 'Gates', 'day_of_birth': new Date('10-28-1955') }
|
1691 | * ]);
|
1692 | * ```
|
1693 | *
|
1694 | * @param bulkLoad A previously created [[BulkLoad]].
|
1695 | * @param rows A [[Iterable]] or [[AsyncIterable]] that contains the rows that should be bulk loaded.
|
1696 | */
|
1697 |
|
1698 | execBulkLoad(bulkLoad, rows) {
|
1699 | bulkLoad.executionStarted = true;
|
1700 | if (rows) {
|
1701 | if (bulkLoad.streamingMode) {
|
1702 | throw new Error("Connection.execBulkLoad can't be called with a BulkLoad that was put in streaming mode.");
|
1703 | }
|
1704 | if (bulkLoad.firstRowWritten) {
|
1705 | throw new Error("Connection.execBulkLoad can't be called with a BulkLoad that already has rows written to it.");
|
1706 | }
|
1707 | const rowStream = _stream.Readable.from(rows);
|
1708 |
|
1709 | // Destroy the packet transform if an error happens in the row stream,
|
1710 | // e.g. if an error is thrown from within a generator or stream.
|
1711 | rowStream.on('error', err => {
|
1712 | bulkLoad.rowToPacketTransform.destroy(err);
|
1713 | });
|
1714 |
|
1715 | // Destroy the row stream if an error happens in the packet transform,
|
1716 | // e.g. if the bulk load is cancelled.
|
1717 | bulkLoad.rowToPacketTransform.on('error', err => {
|
1718 | rowStream.destroy(err);
|
1719 | });
|
1720 | rowStream.pipe(bulkLoad.rowToPacketTransform);
|
1721 | } else if (!bulkLoad.streamingMode) {
|
1722 | // If the bulkload was not put into streaming mode by the user,
|
1723 | // we end the rowToPacketTransform here for them.
|
1724 | //
|
1725 | // If it was put into streaming mode, it's the user's responsibility
|
1726 | // to end the stream.
|
1727 | bulkLoad.rowToPacketTransform.end();
|
1728 | }
|
1729 | const onCancel = () => {
|
1730 | request.cancel();
|
1731 | };
|
1732 | const payload = new _bulkLoadPayload.BulkLoadPayload(bulkLoad);
|
1733 | const request = new _request.default(bulkLoad.getBulkInsertSql(), error => {
|
1734 | bulkLoad.removeListener('cancel', onCancel);
|
1735 | if (error) {
|
1736 | if (error.code === 'UNKNOWN') {
|
1737 | error.message += ' This is likely because the schema of the BulkLoad does not match the schema of the table you are attempting to insert into.';
|
1738 | }
|
1739 | bulkLoad.error = error;
|
1740 | bulkLoad.callback(error);
|
1741 | return;
|
1742 | }
|
1743 | this.makeRequest(bulkLoad, _packet.TYPE.BULK_LOAD, payload);
|
1744 | });
|
1745 | bulkLoad.once('cancel', onCancel);
|
1746 | this.execSqlBatch(request);
|
1747 | }
|
1748 |
|
1749 | /**
|
1750 | * Prepare the SQL represented by the request.
|
1751 | *
|
1752 | * The request can then be used in subsequent calls to
|
1753 | * [[execute]] and [[unprepare]]
|
1754 | *
|
1755 | * @param request A [[Request]] object representing the request.
|
1756 | * Parameters only require a name and type. Parameter values are ignored.
|
1757 | */
|
1758 | prepare(request) {
|
1759 | const parameters = [];
|
1760 | parameters.push({
|
1761 | type: _dataType.TYPES.Int,
|
1762 | name: 'handle',
|
1763 | value: undefined,
|
1764 | output: true,
|
1765 | length: undefined,
|
1766 | precision: undefined,
|
1767 | scale: undefined
|
1768 | });
|
1769 | parameters.push({
|
1770 | type: _dataType.TYPES.NVarChar,
|
1771 | name: 'params',
|
1772 | value: request.parameters.length ? request.makeParamsParameter(request.parameters) : null,
|
1773 | output: false,
|
1774 | length: undefined,
|
1775 | precision: undefined,
|
1776 | scale: undefined
|
1777 | });
|
1778 | parameters.push({
|
1779 | type: _dataType.TYPES.NVarChar,
|
1780 | name: 'stmt',
|
1781 | value: request.sqlTextOrProcedure,
|
1782 | output: false,
|
1783 | length: undefined,
|
1784 | precision: undefined,
|
1785 | scale: undefined
|
1786 | });
|
1787 | request.preparing = true;
|
1788 |
|
1789 | // TODO: We need to clean up this event handler, otherwise this leaks memory
|
1790 | request.on('returnValue', (name, value) => {
|
1791 | if (name === 'handle') {
|
1792 | request.handle = value;
|
1793 | } else {
|
1794 | request.error = new _errors.RequestError(`Tedious > Unexpected output parameter ${name} from sp_prepare`);
|
1795 | }
|
1796 | });
|
1797 | this.makeRequest(request, _packet.TYPE.RPC_REQUEST, new _rpcrequestPayload.default(_specialStoredProcedure.default.Sp_Prepare, parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
|
1798 | }
|
1799 |
|
1800 | /**
|
1801 | * Release the SQL Server resources associated with a previously prepared request.
|
1802 | *
|
1803 | * @param request A [[Request]] object representing the request.
|
1804 | * Parameters only require a name and type.
|
1805 | * Parameter values are ignored.
|
1806 | */
|
1807 | unprepare(request) {
|
1808 | const parameters = [];
|
1809 | parameters.push({
|
1810 | type: _dataType.TYPES.Int,
|
1811 | name: 'handle',
|
1812 | // TODO: Abort if `request.handle` is not set
|
1813 | value: request.handle,
|
1814 | output: false,
|
1815 | length: undefined,
|
1816 | precision: undefined,
|
1817 | scale: undefined
|
1818 | });
|
1819 | this.makeRequest(request, _packet.TYPE.RPC_REQUEST, new _rpcrequestPayload.default(_specialStoredProcedure.default.Sp_Unprepare, parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
|
1820 | }
|
1821 |
|
1822 | /**
|
1823 | * Execute previously prepared SQL, using the supplied parameters.
|
1824 | *
|
1825 | * @param request A previously prepared [[Request]].
|
1826 | * @param parameters An object whose names correspond to the names of
|
1827 | * parameters that were added to the [[Request]] before it was prepared.
|
1828 | * The object's values are passed as the parameters' values when the
|
1829 | * request is executed.
|
1830 | */
|
1831 | execute(request, parameters) {
|
1832 | const executeParameters = [];
|
1833 | executeParameters.push({
|
1834 | type: _dataType.TYPES.Int,
|
1835 | name: '',
|
1836 | // TODO: Abort if `request.handle` is not set
|
1837 | value: request.handle,
|
1838 | output: false,
|
1839 | length: undefined,
|
1840 | precision: undefined,
|
1841 | scale: undefined
|
1842 | });
|
1843 | try {
|
1844 | for (let i = 0, len = request.parameters.length; i < len; i++) {
|
1845 | const parameter = request.parameters[i];
|
1846 | executeParameters.push({
|
1847 | ...parameter,
|
1848 | value: parameter.type.validate(parameters ? parameters[parameter.name] : null, this.databaseCollation)
|
1849 | });
|
1850 | }
|
1851 | } catch (error) {
|
1852 | request.error = error;
|
1853 | process.nextTick(() => {
|
1854 | this.debug.log(error.message);
|
1855 | request.callback(error);
|
1856 | });
|
1857 | return;
|
1858 | }
|
1859 | this.makeRequest(request, _packet.TYPE.RPC_REQUEST, new _rpcrequestPayload.default(_specialStoredProcedure.default.Sp_Execute, executeParameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
|
1860 | }
|
1861 |
|
1862 | /**
|
1863 | * Call a stored procedure represented by [[Request]].
|
1864 | *
|
1865 | * @param request A [[Request]] object representing the request.
|
1866 | */
|
1867 | callProcedure(request) {
|
1868 | try {
|
1869 | request.validateParameters(this.databaseCollation);
|
1870 | } catch (error) {
|
1871 | request.error = error;
|
1872 | process.nextTick(() => {
|
1873 | this.debug.log(error.message);
|
1874 | request.callback(error);
|
1875 | });
|
1876 | return;
|
1877 | }
|
1878 | this.makeRequest(request, _packet.TYPE.RPC_REQUEST, new _rpcrequestPayload.default(request.sqlTextOrProcedure, request.parameters, this.currentTransactionDescriptor(), this.config.options, this.databaseCollation));
|
1879 | }
|
1880 |
|
1881 | /**
|
1882 | * Start a transaction.
|
1883 | *
|
1884 | * @param callback
|
1885 | * @param name A string representing a name to associate with the transaction.
|
1886 | * Optional, and defaults to an empty string. Required when `isolationLevel`
|
1887 | * is present.
|
1888 | * @param isolationLevel The isolation level that the transaction is to be run with.
|
1889 | *
|
1890 | * The isolation levels are available from `require('tedious').ISOLATION_LEVEL`.
|
1891 | * * `READ_UNCOMMITTED`
|
1892 | * * `READ_COMMITTED`
|
1893 | * * `REPEATABLE_READ`
|
1894 | * * `SERIALIZABLE`
|
1895 | * * `SNAPSHOT`
|
1896 | *
|
1897 | * Optional, and defaults to the Connection's isolation level.
|
1898 | */
|
1899 | beginTransaction(callback, name = '', isolationLevel = this.config.options.isolationLevel) {
|
1900 | (0, _transaction.assertValidIsolationLevel)(isolationLevel, 'isolationLevel');
|
1901 | const transaction = new _transaction.Transaction(name, isolationLevel);
|
1902 | if (this.config.options.tdsVersion < '7_2') {
|
1903 | return this.execSqlBatch(new _request.default('SET TRANSACTION ISOLATION LEVEL ' + transaction.isolationLevelToTSQL() + ';BEGIN TRAN ' + transaction.name, err => {
|
1904 | this.transactionDepth++;
|
1905 | if (this.transactionDepth === 1) {
|
1906 | this.inTransaction = true;
|
1907 | }
|
1908 | callback(err);
|
1909 | }));
|
1910 | }
|
1911 | const request = new _request.default(undefined, err => {
|
1912 | return callback(err, this.currentTransactionDescriptor());
|
1913 | });
|
1914 | return this.makeRequest(request, _packet.TYPE.TRANSACTION_MANAGER, transaction.beginPayload(this.currentTransactionDescriptor()));
|
1915 | }
|
1916 |
|
1917 | /**
|
1918 | * Commit a transaction.
|
1919 | *
|
1920 | * There should be an active transaction - that is, [[beginTransaction]]
|
1921 | * should have been previously called.
|
1922 | *
|
1923 | * @param callback
|
1924 | * @param name A string representing a name to associate with the transaction.
|
1925 | * Optional, and defaults to an empty string. Required when `isolationLevel`is present.
|
1926 | */
|
1927 | commitTransaction(callback, name = '') {
|
1928 | const transaction = new _transaction.Transaction(name);
|
1929 | if (this.config.options.tdsVersion < '7_2') {
|
1930 | return this.execSqlBatch(new _request.default('COMMIT TRAN ' + transaction.name, err => {
|
1931 | this.transactionDepth--;
|
1932 | if (this.transactionDepth === 0) {
|
1933 | this.inTransaction = false;
|
1934 | }
|
1935 | callback(err);
|
1936 | }));
|
1937 | }
|
1938 | const request = new _request.default(undefined, callback);
|
1939 | return this.makeRequest(request, _packet.TYPE.TRANSACTION_MANAGER, transaction.commitPayload(this.currentTransactionDescriptor()));
|
1940 | }
|
1941 |
|
1942 | /**
|
1943 | * Rollback a transaction.
|
1944 | *
|
1945 | * There should be an active transaction - that is, [[beginTransaction]]
|
1946 | * should have been previously called.
|
1947 | *
|
1948 | * @param callback
|
1949 | * @param name A string representing a name to associate with the transaction.
|
1950 | * Optional, and defaults to an empty string.
|
1951 | * Required when `isolationLevel` is present.
|
1952 | */
|
1953 | rollbackTransaction(callback, name = '') {
|
1954 | const transaction = new _transaction.Transaction(name);
|
1955 | if (this.config.options.tdsVersion < '7_2') {
|
1956 | return this.execSqlBatch(new _request.default('ROLLBACK TRAN ' + transaction.name, err => {
|
1957 | this.transactionDepth--;
|
1958 | if (this.transactionDepth === 0) {
|
1959 | this.inTransaction = false;
|
1960 | }
|
1961 | callback(err);
|
1962 | }));
|
1963 | }
|
1964 | const request = new _request.default(undefined, callback);
|
1965 | return this.makeRequest(request, _packet.TYPE.TRANSACTION_MANAGER, transaction.rollbackPayload(this.currentTransactionDescriptor()));
|
1966 | }
|
1967 |
|
1968 | /**
|
1969 | * Set a savepoint within a transaction.
|
1970 | *
|
1971 | * There should be an active transaction - that is, [[beginTransaction]]
|
1972 | * should have been previously called.
|
1973 | *
|
1974 | * @param callback
|
1975 | * @param name A string representing a name to associate with the transaction.\
|
1976 | * Optional, and defaults to an empty string.
|
1977 | * Required when `isolationLevel` is present.
|
1978 | */
|
1979 | saveTransaction(callback, name) {
|
1980 | const transaction = new _transaction.Transaction(name);
|
1981 | if (this.config.options.tdsVersion < '7_2') {
|
1982 | return this.execSqlBatch(new _request.default('SAVE TRAN ' + transaction.name, err => {
|
1983 | this.transactionDepth++;
|
1984 | callback(err);
|
1985 | }));
|
1986 | }
|
1987 | const request = new _request.default(undefined, callback);
|
1988 | return this.makeRequest(request, _packet.TYPE.TRANSACTION_MANAGER, transaction.savePayload(this.currentTransactionDescriptor()));
|
1989 | }
|
1990 |
|
1991 | /**
|
1992 | * Run the given callback after starting a transaction, and commit or
|
1993 | * rollback the transaction afterwards.
|
1994 | *
|
1995 | * This is a helper that employs [[beginTransaction]], [[commitTransaction]],
|
1996 | * [[rollbackTransaction]], and [[saveTransaction]] to greatly simplify the
|
1997 | * use of database transactions and automatically handle transaction nesting.
|
1998 | *
|
1999 | * @param cb
|
2000 | * @param isolationLevel
|
2001 | * The isolation level that the transaction is to be run with.
|
2002 | *
|
2003 | * The isolation levels are available from `require('tedious').ISOLATION_LEVEL`.
|
2004 | * * `READ_UNCOMMITTED`
|
2005 | * * `READ_COMMITTED`
|
2006 | * * `REPEATABLE_READ`
|
2007 | * * `SERIALIZABLE`
|
2008 | * * `SNAPSHOT`
|
2009 | *
|
2010 | * Optional, and defaults to the Connection's isolation level.
|
2011 | */
|
2012 | transaction(cb, isolationLevel) {
|
2013 | if (typeof cb !== 'function') {
|
2014 | throw new TypeError('`cb` must be a function');
|
2015 | }
|
2016 | const useSavepoint = this.inTransaction;
|
2017 | const name = '_tedious_' + _crypto.default.randomBytes(10).toString('hex');
|
2018 | const txDone = (err, done, ...args) => {
|
2019 | if (err) {
|
2020 | if (this.inTransaction && this.state === this.STATE.LOGGED_IN) {
|
2021 | this.rollbackTransaction(txErr => {
|
2022 | done(txErr || err, ...args);
|
2023 | }, name);
|
2024 | } else {
|
2025 | done(err, ...args);
|
2026 | }
|
2027 | } else if (useSavepoint) {
|
2028 | if (this.config.options.tdsVersion < '7_2') {
|
2029 | this.transactionDepth--;
|
2030 | }
|
2031 | done(null, ...args);
|
2032 | } else {
|
2033 | this.commitTransaction(txErr => {
|
2034 | done(txErr, ...args);
|
2035 | }, name);
|
2036 | }
|
2037 | };
|
2038 | if (useSavepoint) {
|
2039 | return this.saveTransaction(err => {
|
2040 | if (err) {
|
2041 | return cb(err);
|
2042 | }
|
2043 | if (isolationLevel) {
|
2044 | return this.execSqlBatch(new _request.default('SET transaction isolation level ' + this.getIsolationLevelText(isolationLevel), err => {
|
2045 | return cb(err, txDone);
|
2046 | }));
|
2047 | } else {
|
2048 | return cb(null, txDone);
|
2049 | }
|
2050 | }, name);
|
2051 | } else {
|
2052 | return this.beginTransaction(err => {
|
2053 | if (err) {
|
2054 | return cb(err);
|
2055 | }
|
2056 | return cb(null, txDone);
|
2057 | }, name, isolationLevel);
|
2058 | }
|
2059 | }
|
2060 |
|
2061 | /**
|
2062 | * @private
|
2063 | */
|
2064 | makeRequest(request, packetType, payload) {
|
2065 | if (this.state !== this.STATE.LOGGED_IN) {
|
2066 | const message = 'Requests can only be made in the ' + this.STATE.LOGGED_IN.name + ' state, not the ' + this.state.name + ' state';
|
2067 | this.debug.log(message);
|
2068 | request.callback(new _errors.RequestError(message, 'EINVALIDSTATE'));
|
2069 | } else if (request.canceled) {
|
2070 | process.nextTick(() => {
|
2071 | request.callback(new _errors.RequestError('Canceled.', 'ECANCEL'));
|
2072 | });
|
2073 | } else {
|
2074 | if (packetType === _packet.TYPE.SQL_BATCH) {
|
2075 | this.isSqlBatch = true;
|
2076 | } else {
|
2077 | this.isSqlBatch = false;
|
2078 | }
|
2079 | this.request = request;
|
2080 | request.connection = this;
|
2081 | request.rowCount = 0;
|
2082 | request.rows = [];
|
2083 | request.rst = [];
|
2084 | const onCancel = () => {
|
2085 | payloadStream.unpipe(message);
|
2086 | payloadStream.destroy(new _errors.RequestError('Canceled.', 'ECANCEL'));
|
2087 |
|
2088 | // set the ignore bit and end the message.
|
2089 | message.ignore = true;
|
2090 | message.end();
|
2091 | if (request instanceof _request.default && request.paused) {
|
2092 | // resume the request if it was paused so we can read the remaining tokens
|
2093 | request.resume();
|
2094 | }
|
2095 | };
|
2096 | request.once('cancel', onCancel);
|
2097 | this.createRequestTimer();
|
2098 | const message = new _message.default({
|
2099 | type: packetType,
|
2100 | resetConnection: this.resetConnectionOnNextRequest
|
2101 | });
|
2102 | this.messageIo.outgoingMessageStream.write(message);
|
2103 | this.transitionTo(this.STATE.SENT_CLIENT_REQUEST);
|
2104 | message.once('finish', () => {
|
2105 | request.removeListener('cancel', onCancel);
|
2106 | request.once('cancel', this._cancelAfterRequestSent);
|
2107 | this.resetConnectionOnNextRequest = false;
|
2108 | this.debug.payload(function () {
|
2109 | return payload.toString(' ');
|
2110 | });
|
2111 | });
|
2112 | const payloadStream = _stream.Readable.from(payload);
|
2113 | payloadStream.once('error', error => {
|
2114 | payloadStream.unpipe(message);
|
2115 |
|
2116 | // Only set a request error if no error was set yet.
|
2117 | request.error ??= error;
|
2118 | message.ignore = true;
|
2119 | message.end();
|
2120 | });
|
2121 | payloadStream.pipe(message);
|
2122 | }
|
2123 | }
|
2124 |
|
2125 | /**
|
2126 | * Cancel currently executed request.
|
2127 | */
|
2128 | cancel() {
|
2129 | if (!this.request) {
|
2130 | return false;
|
2131 | }
|
2132 | if (this.request.canceled) {
|
2133 | return false;
|
2134 | }
|
2135 | this.request.cancel();
|
2136 | return true;
|
2137 | }
|
2138 |
|
2139 | /**
|
2140 | * Reset the connection to its initial state.
|
2141 | * Can be useful for connection pool implementations.
|
2142 | *
|
2143 | * @param callback
|
2144 | */
|
2145 | reset(callback) {
|
2146 | const request = new _request.default(this.getInitialSql(), err => {
|
2147 | if (this.config.options.tdsVersion < '7_2') {
|
2148 | this.inTransaction = false;
|
2149 | }
|
2150 | callback(err);
|
2151 | });
|
2152 | this.resetConnectionOnNextRequest = true;
|
2153 | this.execSqlBatch(request);
|
2154 | }
|
2155 |
|
2156 | /**
|
2157 | * @private
|
2158 | */
|
2159 | currentTransactionDescriptor() {
|
2160 | return this.transactionDescriptors[this.transactionDescriptors.length - 1];
|
2161 | }
|
2162 |
|
2163 | /**
|
2164 | * @private
|
2165 | */
|
2166 | getIsolationLevelText(isolationLevel) {
|
2167 | switch (isolationLevel) {
|
2168 | case _transaction.ISOLATION_LEVEL.READ_UNCOMMITTED:
|
2169 | return 'read uncommitted';
|
2170 | case _transaction.ISOLATION_LEVEL.REPEATABLE_READ:
|
2171 | return 'repeatable read';
|
2172 | case _transaction.ISOLATION_LEVEL.SERIALIZABLE:
|
2173 | return 'serializable';
|
2174 | case _transaction.ISOLATION_LEVEL.SNAPSHOT:
|
2175 | return 'snapshot';
|
2176 | default:
|
2177 | return 'read committed';
|
2178 | }
|
2179 | }
|
2180 | }
|
2181 | function isTransientError(error) {
|
2182 | if (error instanceof AggregateError) {
|
2183 | error = error.errors[0];
|
2184 | }
|
2185 | return error instanceof _errors.ConnectionError && !!error.isTransient;
|
2186 | }
|
2187 | var _default = exports.default = Connection;
|
2188 | module.exports = Connection;
|
2189 | Connection.prototype.STATE = {
|
2190 | INITIALIZED: {
|
2191 | name: 'Initialized',
|
2192 | events: {}
|
2193 | },
|
2194 | CONNECTING: {
|
2195 | name: 'Connecting',
|
2196 | enter: function () {
|
2197 | this.initialiseConnection();
|
2198 | },
|
2199 | events: {
|
2200 | socketError: function () {
|
2201 | this.transitionTo(this.STATE.FINAL);
|
2202 | },
|
2203 | connectTimeout: function () {
|
2204 | this.transitionTo(this.STATE.FINAL);
|
2205 | }
|
2206 | }
|
2207 | },
|
2208 | SENT_PRELOGIN: {
|
2209 | name: 'SentPrelogin',
|
2210 | enter: function () {
|
2211 | (async () => {
|
2212 | let messageBuffer = Buffer.alloc(0);
|
2213 | let message;
|
2214 | try {
|
2215 | message = await this.messageIo.readMessage();
|
2216 | } catch (err) {
|
2217 | return this.socketError(err);
|
2218 | }
|
2219 | for await (const data of message) {
|
2220 | messageBuffer = Buffer.concat([messageBuffer, data]);
|
2221 | }
|
2222 | const preloginPayload = new _preloginPayload.default(messageBuffer);
|
2223 | this.debug.payload(function () {
|
2224 | return preloginPayload.toString(' ');
|
2225 | });
|
2226 | if (preloginPayload.fedAuthRequired === 1) {
|
2227 | this.fedAuthRequired = true;
|
2228 | }
|
2229 | if ('strict' !== this.config.options.encrypt && (preloginPayload.encryptionString === 'ON' || preloginPayload.encryptionString === 'REQ')) {
|
2230 | if (!this.config.options.encrypt) {
|
2231 | this.emit('connect', new _errors.ConnectionError("Server requires encryption, set 'encrypt' config option to true.", 'EENCRYPT'));
|
2232 | return this.close();
|
2233 | }
|
2234 | try {
|
2235 | this.transitionTo(this.STATE.SENT_TLSSSLNEGOTIATION);
|
2236 | await this.messageIo.startTls(this.secureContextOptions, this.config.options.serverName ? this.config.options.serverName : this.routingData?.server ?? this.config.server, this.config.options.trustServerCertificate);
|
2237 | } catch (err) {
|
2238 | return this.socketError(err);
|
2239 | }
|
2240 | }
|
2241 | this.sendLogin7Packet();
|
2242 | const {
|
2243 | authentication
|
2244 | } = this.config;
|
2245 | switch (authentication.type) {
|
2246 | case 'azure-active-directory-password':
|
2247 | case 'azure-active-directory-msi-vm':
|
2248 | case 'azure-active-directory-msi-app-service':
|
2249 | case 'azure-active-directory-service-principal-secret':
|
2250 | case 'azure-active-directory-default':
|
2251 | this.transitionTo(this.STATE.SENT_LOGIN7_WITH_FEDAUTH);
|
2252 | break;
|
2253 | case 'ntlm':
|
2254 | this.transitionTo(this.STATE.SENT_LOGIN7_WITH_NTLM);
|
2255 | break;
|
2256 | default:
|
2257 | this.transitionTo(this.STATE.SENT_LOGIN7_WITH_STANDARD_LOGIN);
|
2258 | break;
|
2259 | }
|
2260 | })().catch(err => {
|
2261 | process.nextTick(() => {
|
2262 | throw err;
|
2263 | });
|
2264 | });
|
2265 | },
|
2266 | events: {
|
2267 | socketError: function () {
|
2268 | this.transitionTo(this.STATE.FINAL);
|
2269 | },
|
2270 | connectTimeout: function () {
|
2271 | this.transitionTo(this.STATE.FINAL);
|
2272 | }
|
2273 | }
|
2274 | },
|
2275 | REROUTING: {
|
2276 | name: 'ReRouting',
|
2277 | enter: function () {
|
2278 | this.cleanupConnection(CLEANUP_TYPE.REDIRECT);
|
2279 | },
|
2280 | events: {
|
2281 | message: function () {},
|
2282 | socketError: function () {
|
2283 | this.transitionTo(this.STATE.FINAL);
|
2284 | },
|
2285 | connectTimeout: function () {
|
2286 | this.transitionTo(this.STATE.FINAL);
|
2287 | },
|
2288 | reconnect: function () {
|
2289 | this.transitionTo(this.STATE.CONNECTING);
|
2290 | }
|
2291 | }
|
2292 | },
|
2293 | TRANSIENT_FAILURE_RETRY: {
|
2294 | name: 'TRANSIENT_FAILURE_RETRY',
|
2295 | enter: function () {
|
2296 | this.curTransientRetryCount++;
|
2297 | this.cleanupConnection(CLEANUP_TYPE.RETRY);
|
2298 | },
|
2299 | events: {
|
2300 | message: function () {},
|
2301 | socketError: function () {
|
2302 | this.transitionTo(this.STATE.FINAL);
|
2303 | },
|
2304 | connectTimeout: function () {
|
2305 | this.transitionTo(this.STATE.FINAL);
|
2306 | },
|
2307 | retry: function () {
|
2308 | this.createRetryTimer();
|
2309 | }
|
2310 | }
|
2311 | },
|
2312 | SENT_TLSSSLNEGOTIATION: {
|
2313 | name: 'SentTLSSSLNegotiation',
|
2314 | events: {
|
2315 | socketError: function () {
|
2316 | this.transitionTo(this.STATE.FINAL);
|
2317 | },
|
2318 | connectTimeout: function () {
|
2319 | this.transitionTo(this.STATE.FINAL);
|
2320 | }
|
2321 | }
|
2322 | },
|
2323 | SENT_LOGIN7_WITH_STANDARD_LOGIN: {
|
2324 | name: 'SentLogin7WithStandardLogin',
|
2325 | enter: function () {
|
2326 | (async () => {
|
2327 | let message;
|
2328 | try {
|
2329 | message = await this.messageIo.readMessage();
|
2330 | } catch (err) {
|
2331 | return this.socketError(err);
|
2332 | }
|
2333 | const handler = new _handler.Login7TokenHandler(this);
|
2334 | const tokenStreamParser = this.createTokenStreamParser(message, handler);
|
2335 | await (0, _events.once)(tokenStreamParser, 'end');
|
2336 | if (handler.loginAckReceived) {
|
2337 | if (handler.routingData) {
|
2338 | this.routingData = handler.routingData;
|
2339 | this.transitionTo(this.STATE.REROUTING);
|
2340 | } else {
|
2341 | this.transitionTo(this.STATE.LOGGED_IN_SENDING_INITIAL_SQL);
|
2342 | }
|
2343 | } else if (this.loginError) {
|
2344 | if (isTransientError(this.loginError)) {
|
2345 | this.debug.log('Initiating retry on transient error');
|
2346 | this.transitionTo(this.STATE.TRANSIENT_FAILURE_RETRY);
|
2347 | } else {
|
2348 | this.emit('connect', this.loginError);
|
2349 | this.transitionTo(this.STATE.FINAL);
|
2350 | }
|
2351 | } else {
|
2352 | this.emit('connect', new _errors.ConnectionError('Login failed.', 'ELOGIN'));
|
2353 | this.transitionTo(this.STATE.FINAL);
|
2354 | }
|
2355 | })().catch(err => {
|
2356 | process.nextTick(() => {
|
2357 | throw err;
|
2358 | });
|
2359 | });
|
2360 | },
|
2361 | events: {
|
2362 | socketError: function () {
|
2363 | this.transitionTo(this.STATE.FINAL);
|
2364 | },
|
2365 | connectTimeout: function () {
|
2366 | this.transitionTo(this.STATE.FINAL);
|
2367 | }
|
2368 | }
|
2369 | },
|
2370 | SENT_LOGIN7_WITH_NTLM: {
|
2371 | name: 'SentLogin7WithNTLMLogin',
|
2372 | enter: function () {
|
2373 | (async () => {
|
2374 | while (true) {
|
2375 | let message;
|
2376 | try {
|
2377 | message = await this.messageIo.readMessage();
|
2378 | } catch (err) {
|
2379 | return this.socketError(err);
|
2380 | }
|
2381 | const handler = new _handler.Login7TokenHandler(this);
|
2382 | const tokenStreamParser = this.createTokenStreamParser(message, handler);
|
2383 | await (0, _events.once)(tokenStreamParser, 'end');
|
2384 | if (handler.loginAckReceived) {
|
2385 | if (handler.routingData) {
|
2386 | this.routingData = handler.routingData;
|
2387 | return this.transitionTo(this.STATE.REROUTING);
|
2388 | } else {
|
2389 | return this.transitionTo(this.STATE.LOGGED_IN_SENDING_INITIAL_SQL);
|
2390 | }
|
2391 | } else if (this.ntlmpacket) {
|
2392 | const authentication = this.config.authentication;
|
2393 | const payload = new _ntlmPayload.default({
|
2394 | domain: authentication.options.domain,
|
2395 | userName: authentication.options.userName,
|
2396 | password: authentication.options.password,
|
2397 | ntlmpacket: this.ntlmpacket
|
2398 | });
|
2399 | this.messageIo.sendMessage(_packet.TYPE.NTLMAUTH_PKT, payload.data);
|
2400 | this.debug.payload(function () {
|
2401 | return payload.toString(' ');
|
2402 | });
|
2403 | this.ntlmpacket = undefined;
|
2404 | } else if (this.loginError) {
|
2405 | if (isTransientError(this.loginError)) {
|
2406 | this.debug.log('Initiating retry on transient error');
|
2407 | return this.transitionTo(this.STATE.TRANSIENT_FAILURE_RETRY);
|
2408 | } else {
|
2409 | this.emit('connect', this.loginError);
|
2410 | return this.transitionTo(this.STATE.FINAL);
|
2411 | }
|
2412 | } else {
|
2413 | this.emit('connect', new _errors.ConnectionError('Login failed.', 'ELOGIN'));
|
2414 | return this.transitionTo(this.STATE.FINAL);
|
2415 | }
|
2416 | }
|
2417 | })().catch(err => {
|
2418 | process.nextTick(() => {
|
2419 | throw err;
|
2420 | });
|
2421 | });
|
2422 | },
|
2423 | events: {
|
2424 | socketError: function () {
|
2425 | this.transitionTo(this.STATE.FINAL);
|
2426 | },
|
2427 | connectTimeout: function () {
|
2428 | this.transitionTo(this.STATE.FINAL);
|
2429 | }
|
2430 | }
|
2431 | },
|
2432 | SENT_LOGIN7_WITH_FEDAUTH: {
|
2433 | name: 'SentLogin7Withfedauth',
|
2434 | enter: function () {
|
2435 | (async () => {
|
2436 | let message;
|
2437 | try {
|
2438 | message = await this.messageIo.readMessage();
|
2439 | } catch (err) {
|
2440 | return this.socketError(err);
|
2441 | }
|
2442 | const handler = new _handler.Login7TokenHandler(this);
|
2443 | const tokenStreamParser = this.createTokenStreamParser(message, handler);
|
2444 | await (0, _events.once)(tokenStreamParser, 'end');
|
2445 | if (handler.loginAckReceived) {
|
2446 | if (handler.routingData) {
|
2447 | this.routingData = handler.routingData;
|
2448 | this.transitionTo(this.STATE.REROUTING);
|
2449 | } else {
|
2450 | this.transitionTo(this.STATE.LOGGED_IN_SENDING_INITIAL_SQL);
|
2451 | }
|
2452 | return;
|
2453 | }
|
2454 | const fedAuthInfoToken = handler.fedAuthInfoToken;
|
2455 | if (fedAuthInfoToken && fedAuthInfoToken.stsurl && fedAuthInfoToken.spn) {
|
2456 | const authentication = this.config.authentication;
|
2457 | const tokenScope = new _url.URL('/.default', fedAuthInfoToken.spn).toString();
|
2458 | let credentials;
|
2459 | switch (authentication.type) {
|
2460 | case 'azure-active-directory-password':
|
2461 | credentials = new _identity.UsernamePasswordCredential(authentication.options.tenantId ?? 'common', authentication.options.clientId, authentication.options.userName, authentication.options.password);
|
2462 | break;
|
2463 | case 'azure-active-directory-msi-vm':
|
2464 | case 'azure-active-directory-msi-app-service':
|
2465 | const msiArgs = authentication.options.clientId ? [authentication.options.clientId, {}] : [{}];
|
2466 | credentials = new _identity.ManagedIdentityCredential(...msiArgs);
|
2467 | break;
|
2468 | case 'azure-active-directory-default':
|
2469 | const args = authentication.options.clientId ? {
|
2470 | managedIdentityClientId: authentication.options.clientId
|
2471 | } : {};
|
2472 | credentials = new _identity.DefaultAzureCredential(args);
|
2473 | break;
|
2474 | case 'azure-active-directory-service-principal-secret':
|
2475 | credentials = new _identity.ClientSecretCredential(authentication.options.tenantId, authentication.options.clientId, authentication.options.clientSecret);
|
2476 | break;
|
2477 | }
|
2478 | let tokenResponse;
|
2479 | try {
|
2480 | tokenResponse = await credentials.getToken(tokenScope);
|
2481 | } catch (err) {
|
2482 | this.loginError = new AggregateError([new _errors.ConnectionError('Security token could not be authenticated or authorized.', 'EFEDAUTH'), err]);
|
2483 | this.emit('connect', this.loginError);
|
2484 | this.transitionTo(this.STATE.FINAL);
|
2485 | return;
|
2486 | }
|
2487 | const token = tokenResponse.token;
|
2488 | this.sendFedAuthTokenMessage(token);
|
2489 | } else if (this.loginError) {
|
2490 | if (isTransientError(this.loginError)) {
|
2491 | this.debug.log('Initiating retry on transient error');
|
2492 | this.transitionTo(this.STATE.TRANSIENT_FAILURE_RETRY);
|
2493 | } else {
|
2494 | this.emit('connect', this.loginError);
|
2495 | this.transitionTo(this.STATE.FINAL);
|
2496 | }
|
2497 | } else {
|
2498 | this.emit('connect', new _errors.ConnectionError('Login failed.', 'ELOGIN'));
|
2499 | this.transitionTo(this.STATE.FINAL);
|
2500 | }
|
2501 | })().catch(err => {
|
2502 | process.nextTick(() => {
|
2503 | throw err;
|
2504 | });
|
2505 | });
|
2506 | },
|
2507 | events: {
|
2508 | socketError: function () {
|
2509 | this.transitionTo(this.STATE.FINAL);
|
2510 | },
|
2511 | connectTimeout: function () {
|
2512 | this.transitionTo(this.STATE.FINAL);
|
2513 | }
|
2514 | }
|
2515 | },
|
2516 | LOGGED_IN_SENDING_INITIAL_SQL: {
|
2517 | name: 'LoggedInSendingInitialSql',
|
2518 | enter: function () {
|
2519 | (async () => {
|
2520 | this.sendInitialSql();
|
2521 | let message;
|
2522 | try {
|
2523 | message = await this.messageIo.readMessage();
|
2524 | } catch (err) {
|
2525 | return this.socketError(err);
|
2526 | }
|
2527 | const tokenStreamParser = this.createTokenStreamParser(message, new _handler.InitialSqlTokenHandler(this));
|
2528 | await (0, _events.once)(tokenStreamParser, 'end');
|
2529 | this.transitionTo(this.STATE.LOGGED_IN);
|
2530 | this.processedInitialSql();
|
2531 | })().catch(err => {
|
2532 | process.nextTick(() => {
|
2533 | throw err;
|
2534 | });
|
2535 | });
|
2536 | },
|
2537 | events: {
|
2538 | socketError: function socketError() {
|
2539 | this.transitionTo(this.STATE.FINAL);
|
2540 | },
|
2541 | connectTimeout: function () {
|
2542 | this.transitionTo(this.STATE.FINAL);
|
2543 | }
|
2544 | }
|
2545 | },
|
2546 | LOGGED_IN: {
|
2547 | name: 'LoggedIn',
|
2548 | events: {
|
2549 | socketError: function () {
|
2550 | this.transitionTo(this.STATE.FINAL);
|
2551 | }
|
2552 | }
|
2553 | },
|
2554 | SENT_CLIENT_REQUEST: {
|
2555 | name: 'SentClientRequest',
|
2556 | enter: function () {
|
2557 | (async () => {
|
2558 | let message;
|
2559 | try {
|
2560 | message = await this.messageIo.readMessage();
|
2561 | } catch (err) {
|
2562 | return this.socketError(err);
|
2563 | }
|
2564 | // request timer is stopped on first data package
|
2565 | this.clearRequestTimer();
|
2566 | const tokenStreamParser = this.createTokenStreamParser(message, new _handler.RequestTokenHandler(this, this.request));
|
2567 |
|
2568 | // If the request was canceled and we have a `cancelTimer`
|
2569 | // defined, we send a attention message after the
|
2570 | // request message was fully sent off.
|
2571 | //
|
2572 | // We already started consuming the current message
|
2573 | // (but all the token handlers should be no-ops), and
|
2574 | // need to ensure the next message is handled by the
|
2575 | // `SENT_ATTENTION` state.
|
2576 | if (this.request?.canceled && this.cancelTimer) {
|
2577 | return this.transitionTo(this.STATE.SENT_ATTENTION);
|
2578 | }
|
2579 | const onResume = () => {
|
2580 | tokenStreamParser.resume();
|
2581 | };
|
2582 | const onPause = () => {
|
2583 | tokenStreamParser.pause();
|
2584 | this.request?.once('resume', onResume);
|
2585 | };
|
2586 | this.request?.on('pause', onPause);
|
2587 | if (this.request instanceof _request.default && this.request.paused) {
|
2588 | onPause();
|
2589 | }
|
2590 | const onCancel = () => {
|
2591 | tokenStreamParser.removeListener('end', onEndOfMessage);
|
2592 | if (this.request instanceof _request.default && this.request.paused) {
|
2593 | // resume the request if it was paused so we can read the remaining tokens
|
2594 | this.request.resume();
|
2595 | }
|
2596 | this.request?.removeListener('pause', onPause);
|
2597 | this.request?.removeListener('resume', onResume);
|
2598 |
|
2599 | // The `_cancelAfterRequestSent` callback will have sent a
|
2600 | // attention message, so now we need to also switch to
|
2601 | // the `SENT_ATTENTION` state to make sure the attention ack
|
2602 | // message is processed correctly.
|
2603 | this.transitionTo(this.STATE.SENT_ATTENTION);
|
2604 | };
|
2605 | const onEndOfMessage = () => {
|
2606 | this.request?.removeListener('cancel', this._cancelAfterRequestSent);
|
2607 | this.request?.removeListener('cancel', onCancel);
|
2608 | this.request?.removeListener('pause', onPause);
|
2609 | this.request?.removeListener('resume', onResume);
|
2610 | this.transitionTo(this.STATE.LOGGED_IN);
|
2611 | const sqlRequest = this.request;
|
2612 | this.request = undefined;
|
2613 | if (this.config.options.tdsVersion < '7_2' && sqlRequest.error && this.isSqlBatch) {
|
2614 | this.inTransaction = false;
|
2615 | }
|
2616 | sqlRequest.callback(sqlRequest.error, sqlRequest.rowCount, sqlRequest.rows);
|
2617 | };
|
2618 | tokenStreamParser.once('end', onEndOfMessage);
|
2619 | this.request?.once('cancel', onCancel);
|
2620 | })();
|
2621 | },
|
2622 | exit: function (nextState) {
|
2623 | this.clearRequestTimer();
|
2624 | },
|
2625 | events: {
|
2626 | socketError: function (err) {
|
2627 | const sqlRequest = this.request;
|
2628 | this.request = undefined;
|
2629 | this.transitionTo(this.STATE.FINAL);
|
2630 | sqlRequest.callback(err);
|
2631 | }
|
2632 | }
|
2633 | },
|
2634 | SENT_ATTENTION: {
|
2635 | name: 'SentAttention',
|
2636 | enter: function () {
|
2637 | (async () => {
|
2638 | let message;
|
2639 | try {
|
2640 | message = await this.messageIo.readMessage();
|
2641 | } catch (err) {
|
2642 | return this.socketError(err);
|
2643 | }
|
2644 | const handler = new _handler.AttentionTokenHandler(this, this.request);
|
2645 | const tokenStreamParser = this.createTokenStreamParser(message, handler);
|
2646 | await (0, _events.once)(tokenStreamParser, 'end');
|
2647 | // 3.2.5.7 Sent Attention State
|
2648 | // Discard any data contained in the response, until we receive the attention response
|
2649 | if (handler.attentionReceived) {
|
2650 | this.clearCancelTimer();
|
2651 | const sqlRequest = this.request;
|
2652 | this.request = undefined;
|
2653 | this.transitionTo(this.STATE.LOGGED_IN);
|
2654 | if (sqlRequest.error && sqlRequest.error instanceof _errors.RequestError && sqlRequest.error.code === 'ETIMEOUT') {
|
2655 | sqlRequest.callback(sqlRequest.error);
|
2656 | } else {
|
2657 | sqlRequest.callback(new _errors.RequestError('Canceled.', 'ECANCEL'));
|
2658 | }
|
2659 | }
|
2660 | })().catch(err => {
|
2661 | process.nextTick(() => {
|
2662 | throw err;
|
2663 | });
|
2664 | });
|
2665 | },
|
2666 | events: {
|
2667 | socketError: function (err) {
|
2668 | const sqlRequest = this.request;
|
2669 | this.request = undefined;
|
2670 | this.transitionTo(this.STATE.FINAL);
|
2671 | sqlRequest.callback(err);
|
2672 | }
|
2673 | }
|
2674 | },
|
2675 | FINAL: {
|
2676 | name: 'Final',
|
2677 | enter: function () {
|
2678 | this.cleanupConnection(CLEANUP_TYPE.NORMAL);
|
2679 | },
|
2680 | events: {
|
2681 | connectTimeout: function () {
|
2682 | // Do nothing, as the timer should be cleaned up.
|
2683 | },
|
2684 | message: function () {
|
2685 | // Do nothing
|
2686 | },
|
2687 | socketError: function () {
|
2688 | // Do nothing
|
2689 | }
|
2690 | }
|
2691 | }
|
2692 | };
|
2693 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY3J5cHRvIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfb3MiLCJ0bHMiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIm5ldCIsIl9kbnMiLCJfY29uc3RhbnRzIiwiX3N0cmVhbSIsIl9pZGVudGl0eSIsIl9idWxrTG9hZCIsIl9kZWJ1ZyIsIl9ldmVudHMiLCJfaW5zdGFuY2VMb29rdXAiLCJfdHJhbnNpZW50RXJyb3JMb29rdXAiLCJfcGFja2V0IiwiX3ByZWxvZ2luUGF5bG9hZCIsIl9sb2dpbjdQYXlsb2FkIiwiX250bG1QYXlsb2FkIiwiX3JlcXVlc3QiLCJfcnBjcmVxdWVzdFBheWxvYWQiLCJfc3FsYmF0Y2hQYXlsb2FkIiwiX21lc3NhZ2VJbyIsIl90b2tlblN0cmVhbVBhcnNlciIsIl90cmFuc2FjdGlvbiIsIl9lcnJvcnMiLCJfY29ubmVjdG9yIiwiX2xpYnJhcnkiLCJfdGRzVmVyc2lvbnMiLCJfbWVzc2FnZSIsIl9udGxtIiwiX2RhdGFUeXBlIiwiX2J1bGtMb2FkUGF5bG9hZCIsIl9zcGVjaWFsU3RvcmVkUHJvY2VkdXJlIiwiX3BhY2thZ2UiLCJfdXJsIiwiX2hhbmRsZXIiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJvYmoiLCJLRUVQX0FMSVZFX0lOSVRJQUxfREVMQVkiLCJERUZBVUxUX0NPTk5FQ1RfVElNRU9VVCIsIkRFRkFVTFRfQ0xJRU5UX1JFUVVFU1RfVElNRU9VVCIsIkRFRkFVTFRfQ0FOQ0VMX1RJTUVPVVQiLCJERUZBVUxUX0NPTk5FQ1RfUkVUUllfSU5URVJWQUwiLCJERUZBVUxUX1BBQ0tFVF9TSVpFIiwiREVGQVVMVF9URVhUU0laRSIsIkRFRkFVTFRfREFURUZJUlNUIiwiREVGQVVMVF9QT1JUIiwiREVGQVVMVF9URFNfVkVSU0lPTiIsIkRFRkFVTFRfTEFOR1VBR0UiLCJERUZBVUxUX0RBVEVGT1JNQVQiLCJDTEVBTlVQX1RZUEUiLCJOT1JNQUwiLCJSRURJUkVDVCIsIlJFVFJZIiwiQ29ubmVjdGlvbiIsIkV2ZW50RW1pdHRlciIsIl9jYW5jZWxBZnRlclJlcXVlc3RTZW50IiwiY29uc3RydWN0b3IiLCJjb25maWciLCJUeXBlRXJyb3IiLCJzZXJ2ZXIiLCJmZWRBdXRoUmVxdWlyZWQiLCJhdXRoZW50aWNhdGlvbiIsInVuZGVmaW5lZCIsInR5cGUiLCJvcHRpb25zIiwiZG9tYWluIiwidXNlck5hbWUiLCJwYXNzd29yZCIsInRvVXBwZXJDYXNlIiwiY2xpZW50SWQiLCJ0ZW5hbnRJZCIsInRva2VuIiwiY2xpZW50U2VjcmV0IiwiYWJvcnRUcmFuc2FjdGlvbk9uRXJyb3IiLCJhcHBOYW1lIiwiY2FtZWxDYXNlQ29sdW1ucyIsImNhbmNlbFRpbWVvdXQiLCJjb2x1bW5FbmNyeXB0aW9uS2V5Q2FjaGVUVEwiLCJjb2x1bW5FbmNyeXB0aW9uU2V0dGluZyIsImNvbHVtbk5hbWVSZXBsYWNlciIsImNvbm5lY3Rpb25SZXRyeUludGVydmFsIiwiY29ubmVjdFRpbWVvdXQiLCJjb25uZWN0b3IiLCJjb25uZWN0aW9uSXNvbGF0aW9uTGV2ZWwiLCJJU09MQVRJT05fTEVWRUwiLCJSRUFEX0NPTU1JVFRFRCIsImNyeXB0b0NyZWRlbnRpYWxzRGV0YWlscyIsImRhdGFiYXNlIiwiZGF0ZWZpcnN0IiwiZGF0ZUZvcm1hdCIsImRlYnVnIiwiZGF0YSIsInBhY2tldCIsInBheWxvYWQiLCJlbmFibGVBbnNpTnVsbCIsImVuYWJsZUFuc2lOdWxsRGVmYXVsdCIsImVuYWJsZUFuc2lQYWRkaW5nIiwiZW5hYmxlQW5zaVdhcm5pbmdzIiwiZW5hYmxlQXJpdGhBYm9ydCIsImVuYWJsZUNvbmNhdE51bGxZaWVsZHNOdWxsIiwiZW5hYmxlQ3Vyc29yQ2xvc2VPbkNvbW1pdCIsImVuYWJsZUltcGxpY2l0VHJhbnNhY3Rpb25zIiwiZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQiLCJlbmFibGVRdW90ZWRJZGVudGlmaWVyIiwiZW5jcnlwdCIsImZhbGxiYWNrVG9EZWZhdWx0RGIiLCJlbmNyeXB0aW9uS2V5U3RvcmVQcm92aWRlcnMiLCJpbnN0YW5jZU5hbWUiLCJpc29sYXRpb25MZXZlbCIsImxhbmd1YWdlIiwibG9jYWxBZGRyZXNzIiwibWF4UmV0cmllc09uVHJhbnNpZW50RXJyb3JzIiwibXVsdGlTdWJuZXRGYWlsb3ZlciIsInBhY2tldFNpemUiLCJwb3J0IiwicmVhZE9ubHlJbnRlbnQiLCJyZXF1ZXN0VGltZW91dCIsInJvd0NvbGxlY3Rpb25PbkRvbmUiLCJyb3dDb2xsZWN0aW9uT25SZXF1ZXN0Q29tcGxldGlvbiIsInNlcnZlck5hbWUiLCJzZXJ2ZXJTdXBwb3J0c0NvbHVtbkVuY3J5cHRpb24iLCJ0ZHNWZXJzaW9uIiwidGV4dHNpemUiLCJ0cnVzdGVkU2VydmVyTmFtZUFFIiwidHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZSIsInVzZUNvbHVtbk5hbWVzIiwidXNlVVRDIiwid29ya3N0YXRpb25JZCIsImxvd2VyQ2FzZUd1aWRzIiwiRXJyb3IiLCJhc3NlcnRWYWxpZElzb2xhdGlvbkxldmVsIiwiUmFuZ2VFcnJvciIsInNlY3VyZUNvbnRleHRPcHRpb25zIiwic2VjdXJlT3B0aW9ucyIsImNyZWF0ZSIsInZhbHVlIiwiY29uc3RhbnRzIiwiU1NMX09QX0RPTlRfSU5TRVJUX0VNUFRZX0ZSQUdNRU5UUyIsImNyZWF0ZURlYnVnIiwiaW5UcmFuc2FjdGlvbiIsInRyYW5zYWN0aW9uRGVzY3JpcHRvcnMiLCJCdWZmZXIiLCJmcm9tIiwidHJhbnNhY3Rpb25EZXB0aCIsImlzU3FsQmF0Y2giLCJjbG9zZWQiLCJtZXNzYWdlQnVmZmVyIiwiYWxsb2MiLCJjdXJUcmFuc2llbnRSZXRyeUNvdW50IiwidHJhbnNpZW50RXJyb3JMb29rdXAiLCJUcmFuc2llbnRFcnJvckxvb2t1cCIsInN0YXRlIiwiU1RBVEUiLCJJTklUSUFMSVpFRCIsIm1lc3NhZ2VJbyIsInNlbmRNZXNzYWdlIiwiVFlQRSIsIkFUVEVOVElPTiIsImNyZWF0ZUNhbmNlbFRpbWVyIiwiY29ubmVjdCIsImNvbm5lY3RMaXN0ZW5lciIsIkNvbm5lY3Rpb25FcnJvciIsIm5hbWUiLCJvbkNvbm5lY3QiLCJlcnIiLCJyZW1vdmVMaXN0ZW5lciIsIm9uRXJyb3IiLCJvbmNlIiwidHJhbnNpdGlvblRvIiwiQ09OTkVDVElORyIsIm9uIiwiZXZlbnQiLCJsaXN0ZW5lciIsImVtaXQiLCJhcmdzIiwiY2xvc2UiLCJGSU5BTCIsImluaXRpYWxpc2VDb25uZWN0aW9uIiwic2lnbmFsIiwiY3JlYXRlQ29ubmVjdFRpbWVyIiwiY29ubmVjdE9uUG9ydCIsImluc3RhbmNlTG9va3VwIiwidGltZW91dCIsInRoZW4iLCJwcm9jZXNzIiwibmV4dFRpY2siLCJjbGVhckNvbm5lY3RUaW1lciIsImFib3J0ZWQiLCJtZXNzYWdlIiwiY2xlYW51cENvbm5lY3Rpb24iLCJjbGVhbnVwVHlwZSIsImNsZWFyUmVxdWVzdFRpbWVyIiwiY2xlYXJSZXRyeVRpbWVyIiwiY2xvc2VDb25uZWN0aW9uIiwicmVxdWVzdCIsIlJlcXVlc3RFcnJvciIsImNhbGxiYWNrIiwibG9naW5FcnJvciIsIkRlYnVnIiwiY3JlYXRlVG9rZW5TdHJlYW1QYXJzZXIiLCJoYW5kbGVyIiwiVG9rZW5TdHJlYW1QYXJzZXIiLCJzb2NrZXRIYW5kbGluZ0ZvclNlbmRQcmVMb2dpbiIsInNvY2tldCIsImVycm9yIiwic29ja2V0RXJyb3IiLCJzb2NrZXRDbG9zZSIsInNvY2tldEVuZCIsInNldEtlZXBBbGl2ZSIsIk1lc3NhZ2VJTyIsImNsZWFydGV4dCIsImxvZyIsInNlbmRQcmVMb2dpbiIsIlNFTlRfUFJFTE9HSU4iLCJ3cmFwV2l0aFRscyIsInRocm93SWZBYm9ydGVkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJzZWN1cmVDb250ZXh0IiwiY3JlYXRlU2VjdXJlQ29udGV4dCIsImlzSVAiLCJlbmNyeXB0T3B0aW9ucyIsImhvc3QiLCJBTFBOUHJvdG9jb2xzIiwic2VydmVybmFtZSIsImVuY3J5cHRzb2NrZXQiLCJvbkFib3J0IiwiZGVzdHJveSIsInJlYXNvbiIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJhZGRFdmVudExpc3RlbmVyIiwiY3VzdG9tQ29ubmVjdG9yIiwiY29ubmVjdE9wdHMiLCJyb3V0aW5nRGF0YSIsImNvbm5lY3RJblBhcmFsbGVsIiwiY29ubmVjdEluU2VxdWVuY2UiLCJkbnMiLCJsb29rdXAiLCJlbmQiLCJjYXRjaCIsImNvbnRyb2xsZXIiLCJBYm9ydENvbnRyb2xsZXIiLCJjb25uZWN0VGltZXIiLCJzZXRUaW1lb3V0IiwiYWJvcnQiLCJjbGVhckNhbmNlbFRpbWVyIiwiY2FuY2VsVGltZXIiLCJjcmVhdGVSZXF1ZXN0VGltZXIiLCJyZXF1ZXN0VGltZXIiLCJjcmVhdGVSZXRyeVRpbWVyIiwicmV0cnlUaW1lciIsInJldHJ5VGltZW91dCIsImhvc3RQb3N0Zml4Iiwicm91dGluZ01lc3NhZ2UiLCJkaXNwYXRjaEV2ZW50IiwiY2FuY2VsIiwiY2xlYXJUaW1lb3V0IiwibmV3U3RhdGUiLCJleGl0IiwiZW50ZXIiLCJhcHBseSIsImdldEV2ZW50SGFuZGxlciIsImV2ZW50TmFtZSIsImV2ZW50cyIsIlNFTlRfVExTU1NMTkVHT1RJQVRJT04iLCJjb2RlIiwiUkVST1VUSU5HIiwiVFJBTlNJRU5UX0ZBSUxVUkVfUkVUUlkiLCJtYWpvciIsIm1pbm9yIiwiYnVpbGQiLCJleGVjIiwidmVyc2lvbiIsIlByZWxvZ2luUGF5bG9hZCIsIk51bWJlciIsInN1YmJ1aWxkIiwiUFJFTE9HSU4iLCJ0b1N0cmluZyIsInNlbmRMb2dpbjdQYWNrZXQiLCJMb2dpbjdQYXlsb2FkIiwidmVyc2lvbnMiLCJjbGllbnRQcm9nVmVyIiwiY2xpZW50UGlkIiwicGlkIiwiY29ubmVjdGlvbklkIiwiY2xpZW50VGltZVpvbmUiLCJEYXRlIiwiZ2V0VGltZXpvbmVPZmZzZXQiLCJjbGllbnRMY2lkIiwiZmVkQXV0aCIsImVjaG8iLCJ3b3JrZmxvdyIsImZlZEF1dGhUb2tlbiIsInNzcGkiLCJjcmVhdGVOVExNUmVxdWVzdCIsImhvc3RuYW1lIiwib3MiLCJsaWJyYXJ5TmFtZSIsImluaXREYkZhdGFsIiwiTE9HSU43IiwidG9CdWZmZXIiLCJzZW5kRmVkQXV0aFRva2VuTWVzc2FnZSIsImFjY2Vzc1Rva2VuTGVuIiwiYnl0ZUxlbmd0aCIsIm9mZnNldCIsIndyaXRlVUludDMyTEUiLCJ3cml0ZSIsIkZFREFVVEhfVE9LRU4iLCJTRU5UX0xPR0lON19XSVRIX1NUQU5EQVJEX0xPR0lOIiwic2VuZEluaXRpYWxTcWwiLCJTcWxCYXRjaFBheWxvYWQiLCJnZXRJbml0aWFsU3FsIiwiY3VycmVudFRyYW5zYWN0aW9uRGVzY3JpcHRvciIsIk1lc3NhZ2UiLCJTUUxfQkFUQ0giLCJvdXRnb2luZ01lc3NhZ2VTdHJlYW0iLCJSZWFkYWJsZSIsInBpcGUiLCJwdXNoIiwiZ2V0SXNvbGF0aW9uTGV2ZWxUZXh0Iiwiam9pbiIsInByb2Nlc3NlZEluaXRpYWxTcWwiLCJleGVjU3FsQmF0Y2giLCJtYWtlUmVxdWVzdCIsInNxbFRleHRPclByb2NlZHVyZSIsImV4ZWNTcWwiLCJ2YWxpZGF0ZVBhcmFtZXRlcnMiLCJkYXRhYmFzZUNvbGxhdGlvbiIsInBhcmFtZXRlcnMiLCJUWVBFUyIsIk5WYXJDaGFyIiwib3V0cHV0IiwibGVuZ3RoIiwicHJlY2lzaW9uIiwic2NhbGUiLCJtYWtlUGFyYW1zUGFyYW1ldGVyIiwiUlBDX1JFUVVFU1QiLCJScGNSZXF1ZXN0UGF5bG9hZCIsIlByb2NlZHVyZXMiLCJTcF9FeGVjdXRlU3FsIiwibmV3QnVsa0xvYWQiLCJ0YWJsZSIsImNhbGxiYWNrT3JPcHRpb25zIiwiQnVsa0xvYWQiLCJleGVjQnVsa0xvYWQiLCJidWxrTG9hZCIsInJvd3MiLCJleGVjdXRpb25TdGFydGVkIiwic3RyZWFtaW5nTW9kZSIsImZpcnN0Um93V3JpdHRlbiIsInJvd1N0cmVhbSIsInJvd1RvUGFja2V0VHJhbnNmb3JtIiwib25DYW5jZWwiLCJCdWxrTG9hZFBheWxvYWQiLCJSZXF1ZXN0IiwiZ2V0QnVsa0luc2VydFNxbCIsIkJVTEtfTE9BRCIsInByZXBhcmUiLCJJbnQiLCJwcmVwYXJpbmciLCJoYW5kbGUiLCJTcF9QcmVwYXJlIiwidW5wcmVwYXJlIiwiU3BfVW5wcmVwYXJlIiwiZXhlY3V0ZSIsImV4ZWN1dGVQYXJhbWV0ZXJzIiwibGVuIiwicGFyYW1ldGVyIiwidmFsaWRhdGUiLCJTcF9FeGVjdXRlIiwiY2FsbFByb2NlZHVyZSIsImJlZ2luVHJhbnNhY3Rpb24iLCJ0cmFuc2FjdGlvbiIsIlRyYW5zYWN0aW9uIiwiaXNvbGF0aW9uTGV2ZWxUb1RTUUwiLCJUUkFOU0FDVElPTl9NQU5BR0VSIiwiYmVnaW5QYXlsb2FkIiwiY29tbWl0VHJhbnNhY3Rpb24iLCJjb21taXRQYXlsb2FkIiwicm9sbGJhY2tUcmFuc2FjdGlvbiIsInJvbGxiYWNrUGF5bG9hZCIsInNhdmVUcmFuc2FjdGlvbiIsInNhdmVQYXlsb2FkIiwiY2IiLCJ1c2VTYXZlcG9pbnQiLCJjcnlwdG8iLCJyYW5kb21CeXRlcyIsInR4RG9uZSIsImRvbmUiLCJMT0dHRURfSU4iLCJ0eEVyciIsInBhY2tldFR5cGUiLCJjYW5jZWxlZCIsImNvbm5lY3Rpb24iLCJyb3dDb3VudCIsInJzdCIsInBheWxvYWRTdHJlYW0iLCJ1bnBpcGUiLCJpZ25vcmUiLCJwYXVzZWQiLCJyZXN1bWUiLCJyZXNldENvbm5lY3Rpb24iLCJyZXNldENvbm5lY3Rpb25Pbk5leHRSZXF1ZXN0IiwiU0VOVF9DTElFTlRfUkVRVUVTVCIsInJlc2V0IiwiUkVBRF9VTkNPTU1JVFRFRCIsIlJFUEVBVEFCTEVfUkVBRCIsIlNFUklBTElaQUJMRSIsIlNOQVBTSE9UIiwiaXNUcmFuc2llbnRFcnJvciIsIkFnZ3JlZ2F0ZUVycm9yIiwiZXJyb3JzIiwiaXNUcmFuc2llbnQiLCJfZGVmYXVsdCIsImV4cG9ydHMiLCJtb2R1bGUiLCJyZWFkTWVzc2FnZSIsImNvbmNhdCIsInByZWxvZ2luUGF5bG9hZCIsImVuY3J5cHRpb25TdHJpbmciLCJzdGFydFRscyIsIlNFTlRfTE9HSU43X1dJVEhfRkVEQVVUSCIsIlNFTlRfTE9HSU43X1dJVEhfTlRMTSIsInJlY29ubmVjdCIsInJldHJ5IiwiTG9naW43VG9rZW5IYW5kbGVyIiwidG9rZW5TdHJlYW1QYXJzZXIiLCJsb2dpbkFja1JlY2VpdmVkIiwiTE9HR0VEX0lOX1NFTkRJTkdfSU5JVElBTF9TUUwiLCJudGxtcGFja2V0IiwiTlRMTVJlc3BvbnNlUGF5bG9hZCIsIk5UTE1BVVRIX1BLVCIsImZlZEF1dGhJbmZvVG9rZW4iLCJzdHN1cmwiLCJzcG4iLCJ0b2tlblNjb3BlIiwiVVJMIiwiY3JlZGVudGlhbHMiLCJVc2VybmFtZVBhc3N3b3JkQ3JlZGVudGlhbCIsIm1zaUFyZ3MiLCJNYW5hZ2VkSWRlbnRpdHlDcmVkZW50aWFsIiwibWFuYWdlZElkZW50aXR5Q2xpZW50SWQiLCJEZWZhdWx0QXp1cmVDcmVkZW50aWFsIiwiQ2xpZW50U2VjcmV0Q3JlZGVudGlhbCIsInRva2VuUmVzcG9uc2UiLCJnZXRUb2tlbiIsIkluaXRpYWxTcWxUb2tlbkhhbmRsZXIiLCJSZXF1ZXN0VG9rZW5IYW5kbGVyIiwiU0VOVF9BVFRFTlRJT04iLCJvblJlc3VtZSIsIm9uUGF1c2UiLCJwYXVzZSIsIm9uRW5kT2ZNZXNzYWdlIiwic3FsUmVxdWVzdCIsIm5leHRTdGF0ZSIsIkF0dGVudGlvblRva2VuSGFuZGxlciIsImF0dGVudGlvblJlY2VpdmVkIl0sInNvdXJjZXMiOlsiLi4vc3JjL2Nvbm5lY3Rpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IG9zIGZyb20gJ29zJztcbmltcG9ydCAqIGFzIHRscyBmcm9tICd0bHMnO1xuaW1wb3J0ICogYXMgbmV0IGZyb20gJ25ldCc7XG5pbXBvcnQgZG5zIGZyb20gJ2Rucyc7XG5cbmltcG9ydCBjb25zdGFudHMgZnJvbSAnY29uc3RhbnRzJztcbmltcG9ydCB7IHR5cGUgU2VjdXJlQ29udGV4dE9wdGlvbnMgfSBmcm9tICd0bHMnO1xuXG5pbXBvcnQgeyBSZWFkYWJsZSB9IGZyb20gJ3N0cmVhbSc7XG5cbmltcG9ydCB7XG4gIERlZmF1bHRBenVyZUNyZWRlbnRpYWwsXG4gIENsaWVudFNlY3JldENyZWRlbnRpYWwsXG4gIE1hbmFnZWRJZGVudGl0eUNyZWRlbnRpYWwsXG4gIFVzZXJuYW1lUGFzc3dvcmRDcmVkZW50aWFsLFxufSBmcm9tICdAYXp1cmUvaWRlbnRpdHknO1xuXG5pbXBvcnQgQnVsa0xvYWQsIHsgdHlwZSBPcHRpb25zIGFzIEJ1bGtMb2FkT3B0aW9ucywgdHlwZSBDYWxsYmFjayBhcyBCdWxrTG9hZENhbGxiYWNrIH0gZnJvbSAnLi9idWxrLWxvYWQnO1xuaW1wb3J0IERlYnVnIGZyb20gJy4vZGVidWcnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBvbmNlIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCB7IGluc3RhbmNlTG9va3VwIH0gZnJvbSAnLi9pbnN0YW5jZS1sb29rdXAnO1xuaW1wb3J0IHsgVHJhbnNpZW50RXJyb3JMb29rdXAgfSBmcm9tICcuL3RyYW5zaWVudC1lcnJvci1sb29rdXAnO1xuaW1wb3J0IHsgVFlQRSB9IGZyb20gJy4vcGFja2V0JztcbmltcG9ydCBQcmVsb2dpblBheWxvYWQgZnJvbSAnLi9wcmVsb2dpbi1wYXlsb2FkJztcbmltcG9ydCBMb2dpbjdQYXlsb2FkIGZyb20gJy4vbG9naW43LXBheWxvYWQnO1xuaW1wb3J0IE5UTE1SZXNwb25zZVBheWxvYWQgZnJvbSAnLi9udGxtLXBheWxvYWQnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcbmltcG9ydCBScGNSZXF1ZXN0UGF5bG9hZCBmcm9tICcuL3JwY3JlcXVlc3QtcGF5bG9hZCc7XG5pbXBvcnQgU3FsQmF0Y2hQYXlsb2FkIGZyb20gJy4vc3FsYmF0Y2gtcGF5bG9hZCc7XG5pbXBvcnQgTWVzc2FnZUlPIGZyb20gJy4vbWVzc2FnZS1pbyc7XG5pbXBvcnQgeyBQYXJzZXIgYXMgVG9rZW5TdHJlYW1QYXJzZXIgfSBmcm9tICcuL3Rva2VuL3Rva2VuLXN0cmVhbS1wYXJzZXInO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24sIElTT0xBVElPTl9MRVZFTCwgYXNzZXJ0VmFsaWRJc29sYXRpb25MZXZlbCB9IGZyb20gJy4vdHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgQ29ubmVjdGlvbkVycm9yLCBSZXF1ZXN0RXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBjb25uZWN0SW5QYXJhbGxlbCwgY29ubmVjdEluU2VxdWVuY2UgfSBmcm9tICcuL2Nvbm5lY3Rvcic7XG5pbXBvcnQgeyBuYW1lIGFzIGxpYnJhcnlOYW1lIH0gZnJvbSAnLi9saWJyYXJ5JztcbmltcG9ydCB7IHZlcnNpb25zIH0gZnJvbSAnLi90ZHMtdmVyc2lvbnMnO1xuaW1wb3J0IE1lc3NhZ2UgZnJvbSAnLi9tZXNzYWdlJztcbmltcG9ydCB7IHR5cGUgTWV0YWRhdGEgfSBmcm9tICcuL21ldGFkYXRhLXBhcnNlcic7XG5pbXBvcnQgeyBjcmVhdGVOVExNUmVxdWVzdCB9IGZyb20gJy4vbnRsbSc7XG5pbXBvcnQgeyBDb2x1bW5FbmNyeXB0aW9uQXp1cmVLZXlWYXVsdFByb3ZpZGVyIH0gZnJvbSAnLi9hbHdheXMtZW5jcnlwdGVkL2tleXN0b3JlLXByb3ZpZGVyLWF6dXJlLWtleS12YXVsdCc7XG5cbmltcG9ydCB7IHR5cGUgUGFyYW1ldGVyLCBUWVBFUyB9IGZyb20gJy4vZGF0YS10eXBlJztcbmltcG9ydCB7IEJ1bGtMb2FkUGF5bG9hZCB9IGZyb20gJy4vYnVsay1sb2FkLXBheWxvYWQnO1xuaW1wb3J0IHsgQ29sbGF0aW9uIH0gZnJvbSAnLi9jb2xsYXRpb24nO1xuaW1wb3J0IFByb2NlZHVyZXMgZnJvbSAnLi9zcGVjaWFsLXN0b3JlZC1wcm9jZWR1cmUnO1xuXG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi4vcGFja2FnZS5qc29uJztcbmltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7XG5pbXBvcnQgeyBBdHRlbnRpb25Ub2tlbkhhbmRsZXIsIEluaXRpYWxTcWxUb2tlbkhhbmRsZXIsIExvZ2luN1Rva2VuSGFuZGxlciwgUmVxdWVzdFRva2VuSGFuZGxlciwgVG9rZW5IYW5kbGVyIH0gZnJvbSAnLi90b2tlbi9oYW5kbGVyJztcblxudHlwZSBCZWdpblRyYW5zYWN0aW9uQ2FsbGJhY2sgPVxuICAvKipcbiAgICogVGhlIGNhbGxiYWNrIGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHRvIHN0YXJ0IHRoZSB0cmFuc2FjdGlvbiBoYXMgY29tcGxldGVkLFxuICAgKiBlaXRoZXIgc3VjY2Vzc2Z1bGx5IG9yIHdpdGggYW4gZXJyb3IuXG4gICAqIElmIGFuIGVycm9yIG9jY3VycmVkIHRoZW4gYGVycmAgd2lsbCBkZXNjcmliZSB0aGUgZXJyb3IuXG4gICAqXG4gICAqIEFzIG9ubHkgb25lIHJlcXVlc3QgYXQgYSB0aW1lIG1heSBiZSBleGVjdXRlZCBvbiBhIGNvbm5lY3Rpb24sIGFub3RoZXIgcmVxdWVzdCBzaG91bGQgbm90XG4gICAqIGJlIGluaXRpYXRlZCB1bnRpbCB0aGlzIGNhbGxiYWNrIGlzIGNhbGxlZC5cbiAgICpcbiAgICogQHBhcmFtIGVyciBJZiBhbiBlcnJvciBvY2N1cnJlZCwgYW4gW1tFcnJvcl1dIG9iamVjdCB3aXRoIGRldGFpbHMgb2YgdGhlIGVycm9yLlxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25EZXNjcmlwdG9yIEEgQnVmZmVyIHRoYXQgZGVzY3JpYmUgdGhlIHRyYW5zYWN0aW9uXG4gICAqL1xuICAoZXJyOiBFcnJvciB8IG51bGwgfCB1bmRlZmluZWQsIHRyYW5zYWN0aW9uRGVzY3JpcHRvcj86IEJ1ZmZlcikgPT4gdm9pZFxuXG50eXBlIFNhdmVUcmFuc2FjdGlvbkNhbGxiYWNrID1cbiAgLyoqXG4gICAqIFRoZSBjYWxsYmFjayBpcyBjYWxsZWQgd2hlbiB0aGUgcmVxdWVzdCB0byBzZXQgYSBzYXZlcG9pbnQgd2l0aGluIHRoZVxuICAgKiB0cmFuc2FjdGlvbiBoYXMgY29tcGxldGVkLCBlaXRoZXIgc3VjY2Vzc2Z1bGx5IG9yIHdpdGggYW4gZXJyb3IuXG4gICAqIElmIGFuIGVycm9yIG9jY3VycmVkIHRoZW4gYGVycmAgd2lsbCBkZXNjcmliZSB0aGUgZXJyb3IuXG4gICAqXG4gICAqIEFzIG9ubHkgb25lIHJlcXVlc3QgYXQgYSB0aW1lIG1heSBiZSBleGVjdXRlZCBvbiBhIGNvbm5lY3Rpb24sIGFub3RoZXIgcmVxdWVzdCBzaG91bGQgbm90XG4gICAqIGJlIGluaXRpYXRlZCB1bnRpbCB0aGlzIGNhbGxiYWNrIGlzIGNhbGxlZC5cbiAgICpcbiAgICogQHBhcmFtIGVyciBJZiBhbiBlcnJvciBvY2N1cnJlZCwgYW4gW1tFcnJvcl1dIG9iamVjdCB3aXRoIGRldGFpbHMgb2YgdGhlIGVycm9yLlxuICAgKi9cbiAgKGVycjogRXJyb3IgfCBudWxsIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuXG50eXBlIENvbW1pdFRyYW5zYWN0aW9uQ2FsbGJhY2sgPVxuICAvKipcbiAgICogVGhlIGNhbGxiYWNrIGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHRvIGNvbW1pdCB0aGUgdHJhbnNhY3Rpb24gaGFzIGNvbXBsZXRlZCxcbiAgICogZWl0aGVyIHN1Y2Nlc3NmdWxseSBvciB3aXRoIGFuIGVycm9yLlxuICAgKiBJZiBhbiBlcnJvciBvY2N1cnJlZCB0aGVuIGBlcnJgIHdpbGwgZGVzY3JpYmUgdGhlIGVycm9yLlxuICAgKlxuICAgKiBBcyBvbmx5IG9uZSByZXF1ZXN0IGF0IGEgdGltZSBtYXkgYmUgZXhlY3V0ZWQgb24gYSBjb25uZWN0aW9uLCBhbm90aGVyIHJlcXVlc3Qgc2hvdWxkIG5vdFxuICAgKiBiZSBpbml0aWF0ZWQgdW50aWwgdGhpcyBjYWxsYmFjayBpcyBjYWxsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBlcnIgSWYgYW4gZXJyb3Igb2NjdXJyZWQsIGFuIFtbRXJyb3JdXSBvYmplY3Qgd2l0aCBkZXRhaWxzIG9mIHRoZSBlcnJvci5cbiAgICovXG4gIChlcnI6IEVycm9yIHwgbnVsbCB8IHVuZGVmaW5lZCkgPT4gdm9pZDtcblxudHlwZSBSb2xsYmFja1RyYW5zYWN0aW9uQ2FsbGJhY2sgPVxuICAvKipcbiAgICogVGhlIGNhbGxiYWNrIGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHRvIHJvbGxiYWNrIHRoZSB0cmFuc2FjdGlvbiBoYXNcbiAgICogY29tcGxldGVkLCBlaXRoZXIgc3VjY2Vzc2Z1bGx5IG9yIHdpdGggYW4gZXJyb3IuXG4gICAqIElmIGFuIGVycm9yIG9jY3VycmVkIHRoZW4gZXJyIHdpbGwgZGVzY3JpYmUgdGhlIGVycm9yLlxuICAgKlxuICAgKiBBcyBvbmx5IG9uZSByZXF1ZXN0IGF0IGEgdGltZSBtYXkgYmUgZXhlY3V0ZWQgb24gYSBjb25uZWN0aW9uLCBhbm90aGVyIHJlcXVlc3Qgc2hvdWxkIG5vdFxuICAgKiBiZSBpbml0aWF0ZWQgdW50aWwgdGhpcyBjYWxsYmFjayBpcyBjYWxsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBlcnIgSWYgYW4gZXJyb3Igb2NjdXJyZWQsIGFuIFtbRXJyb3JdXSBvYmplY3Qgd2l0aCBkZXRhaWxzIG9mIHRoZSBlcnJvci5cbiAgICovXG4gIChlcnI6IEVycm9yIHwgbnVsbCB8IHVuZGVmaW5lZCkgPT4gdm9pZDtcblxudHlwZSBSZXNldENhbGxiYWNrID1cbiAgLyoqXG4gICAqIFRoZSBjYWxsYmFjayBpcyBjYWxsZWQgd2hlbiB0aGUgY29ubmVjdGlvbiByZXNldCBoYXMgY29tcGxldGVkLFxuICAgKiBlaXRoZXIgc3VjY2Vzc2Z1bGx5IG9yIHdpdGggYW4gZXJyb3IuXG4gICAqXG4gICAqIElmIGFuIGVycm9yIG9jY3VycmVkIHRoZW4gYGVycmAgd2lsbCBkZXNjcmliZSB0aGUgZXJyb3IuXG4gICAqXG4gICAqIEFzIG9ubHkgb25lIHJlcXVlc3QgYXQgYSB0aW1lIG1heSBiZSBleGVjdXRlZCBvbiBhIGNvbm5lY3Rpb24sIGFub3RoZXJcbiAgICogcmVxdWVzdCBzaG91bGQgbm90IGJlIGluaXRpYXRlZCB1bnRpbCB0aGlzIGNhbGxiYWNrIGlzIGNhbGxlZFxuICAgKlxuICAgKiBAcGFyYW0gZXJyIElmIGFuIGVycm9yIG9jY3VycmVkLCBhbiBbW0Vycm9yXV0gb2JqZWN0IHdpdGggZGV0YWlscyBvZiB0aGUgZXJyb3IuXG4gICAqL1xuICAoZXJyOiBFcnJvciB8IG51bGwgfCB1bmRlZmluZWQpID0+IHZvaWQ7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbnR5cGUgVHJhbnNhY3Rpb25DYWxsYmFjazxUIGV4dGVuZHMgKGVycjogRXJyb3IgfCBudWxsIHwgdW5kZWZpbmVkLCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZD4gPVxuICAvKipcbiAgICogVGhlIGNhbGxiYWNrIGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHRvIHN0YXJ0IGEgdHJhbnNhY3Rpb24gKG9yIGNyZWF0ZSBhIHNhdmVwb2ludCwgaW5cbiAgICogdGhlIGNhc2Ugb2YgYSBuZXN0ZWQgdHJhbnNhY3Rpb24pIGhhcyBjb21wbGV0ZWQsIGVpdGhlciBzdWNjZXNzZnVsbHkgb3Igd2l0aCBhbiBlcnJvci5cbiAgICogSWYgYW4gZXJyb3Igb2NjdXJyZWQsIHRoZW4gYGVycmAgd2lsbCBkZXNjcmliZSB0aGUgZXJyb3IuXG4gICAqIElmIG5vIGVycm9yIG9jY3VycmVkLCB0aGUgY2FsbGJhY2sgc2hvdWxkIHBlcmZvcm0gaXRzIHdvcmsgYW5kIGV2ZW50dWFsbHkgY2FsbFxuICAgKiBgZG9uZWAgd2l0aCBhbiBlcnJvciBvciBudWxsICh0byB0cmlnZ2VyIGEgdHJhbnNhY3Rpb24gcm9sbGJhY2sgb3IgYVxuICAgKiB0cmFuc2FjdGlvbiBjb21taXQpIGFuZCBhbiBhZGRpdGlvbmFsIGNvbXBsZXRpb24gY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0XG4gICAqIHRvIHJvbGxiYWNrIG9yIGNvbW1pdCB0aGUgY3VycmVudCB0cmFuc2FjdGlvbiBoYXMgY29tcGxldGVkLCBlaXRoZXIgc3VjY2Vzc2Z1bGx5IG9yIHdpdGggYW4gZXJyb3IuXG4gICAqIEFkZGl0aW9uYWwgYXJndW1lbnRzIGdpdmVuIHRvIGBkb25lYCB3aWxsIGJlIHBhc3NlZCB0aHJvdWdoIHRvIHRoaXMgY2FsbGJhY2suXG4gICAqXG4gICAqIEFzIG9ubHkgb25lIHJlcXVlc3QgYXQgYSB0aW1lIG1heSBiZSBleGVjdXRlZCBvbiBhIGNvbm5lY3Rpb24sIGFub3RoZXIgcmVxdWVzdCBzaG91bGQgbm90XG4gICAqIGJlIGluaXRpYXRlZCB1bnRpbCB0aGUgY29tcGxldGlvbiBjYWxsYmFjayBpcyBjYWxsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBlcnIgSWYgYW4gZXJyb3Igb2NjdXJyZWQsIGFuIFtbRXJyb3JdXSBvYmplY3Qgd2l0aCBkZXRhaWxzIG9mIHRoZSBlcnJvci5cbiAgICogQHBhcmFtIHR4RG9uZSBJZiBubyBlcnJvciBvY2N1cnJlZCwgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgdG8gY29tbWl0IG9yIHJvbGxiYWNrIHRoZSB0cmFuc2FjdGlvbi5cbiAgICovXG4gIChlcnI6IEVycm9yIHwgbnVsbCB8IHVuZGVmaW5lZCwgdHhEb25lPzogVHJhbnNhY3Rpb25Eb25lPFQ+KSA9PiB2b2lkO1xuXG50eXBlIFRyYW5zYWN0aW9uRG9uZUNhbGxiYWNrID0gKGVycjogRXJyb3IgfCBudWxsIHwgdW5kZWZpbmVkLCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZDtcbnR5cGUgQ2FsbGJhY2tQYXJhbWV0ZXJzPFQgZXh0ZW5kcyAoZXJyOiBFcnJvciB8IG51bGwgfCB1bmRlZmluZWQsIC4uLmFyZ3M6IGFueVtdKSA9PiBhbnk+ID0gVCBleHRlbmRzIChlcnI6IEVycm9yIHwgbnVsbCB8IHVuZGVmaW5lZCwgLi4uYXJnczogaW5mZXIgUCkgPT4gYW55ID8gUCA6IG5ldmVyO1xuXG50eXBlIFRyYW5zYWN0aW9uRG9uZTxUIGV4dGVuZHMgKGVycjogRXJyb3IgfCBudWxsIHwgdW5kZWZpbmVkLCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZD4gPVxuICAvKipcbiAgICogSWYgbm8gZXJyb3Igb2NjdXJyZWQsIGEgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHRvIGNvbW1pdCBvciByb2xsYmFjayB0aGUgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBlcnIgSWYgYW4gZXJyIG9jY3VycmVkLCBhIHN0cmluZyB3aXRoIGRldGFpbHMgb2YgdGhlIGVycm9yLlxuICAgKi9cbiAgKGVycjogRXJyb3IgfCBudWxsIHwgdW5kZWZpbmVkLCBkb25lOiBULCAuLi5hcmdzOiBDYWxsYmFja1BhcmFtZXRlcnM8VD4pID0+IHZvaWQ7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgS0VFUF9BTElWRV9JTklUSUFMX0RFTEFZID0gMzAgKiAxMDAwO1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBERUZBVUxUX0NPTk5FQ1RfVElNRU9VVCA9IDE1ICogMTAwMDtcbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgREVGQVVMVF9DTElFTlRfUkVRVUVTVF9USU1FT1VUID0gMTUgKiAxMDAwO1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBERUZBVUxUX0NBTkNFTF9USU1FT1VUID0gNSAqIDEwMDA7XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IERFRkFVTFRfQ09OTkVDVF9SRVRSWV9JTlRFUlZBTCA9IDUwMDtcbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgREVGQVVMVF9QQUNLRVRfU0laRSA9IDQgKiAxMDI0O1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBERUZBVUxUX1RFWFRTSVpFID0gMjE0NzQ4MzY0Nztcbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgREVGQVVMVF9EQVRFRklSU1QgPSA3O1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBERUZBVUxUX1BPUlQgPSAxNDMzO1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBERUZBVUxUX1REU19WRVJTSU9OID0gJzdfNCc7XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IERFRkFVTFRfTEFOR1VBR0UgPSAndXNfZW5nbGlzaCc7XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IERFRkFVTFRfREFURUZPUk1BVCA9ICdtZHknO1xuXG5pbnRlcmZhY2UgQXp1cmVBY3RpdmVEaXJlY3RvcnlNc2lBcHBTZXJ2aWNlQXV0aGVudGljYXRpb24ge1xuICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktYXBwLXNlcnZpY2UnO1xuICBvcHRpb25zOiB7XG4gICAgLyoqXG4gICAgICogSWYgeW91IHVzZXIgd2FudCB0byBjb25uZWN0IHRvIGFuIEF6dXJlIGFwcCBzZXJ2aWNlIHVzaW5nIGEgc3BlY2lmaWMgY2xpZW50IGFjY291bnRcbiAgICAgKiB0aGV5IG5lZWQgdG8gcHJvdmlkZSBgY2xpZW50SWRgIGFzc29jaWF0ZSB0byB0aGVpciBjcmVhdGVkIGlkZW50aXR5LlxuICAgICAqXG4gICAgICogVGhpcyBpcyBvcHRpb25hbCBmb3IgcmV0cmlldmUgdG9rZW4gZnJvbSBhenVyZSB3ZWIgYXBwIHNlcnZpY2VcbiAgICAgKi9cbiAgICBjbGllbnRJZD86IHN0cmluZztcbiAgfTtcbn1cblxuaW50ZXJmYWNlIEF6dXJlQWN0aXZlRGlyZWN0b3J5TXNpVm1BdXRoZW50aWNhdGlvbiB7XG4gIHR5cGU6ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS12bSc7XG4gIG9wdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBJZiB5b3Ugd2FudCB0byBjb25uZWN0IHVzaW5nIGEgc3BlY2lmaWMgY2xpZW50IGFjY291bnRcbiAgICAgKiB0aGV5IG5lZWQgdG8gcHJvdmlkZSBgY2xpZW50SWRgIGFzc29jaWF0ZWQgdG8gdGhlaXIgY3JlYXRlZCBpZGVudGl0eS5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgb3B0aW9uYWwgZm9yIHJldHJpZXZlIGEgdG9rZW5cbiAgICAgKi9cbiAgICBjbGllbnRJZD86IHN0cmluZztcbiAgfTtcbn1cblxuaW50ZXJmYWNlIEF6dXJlQWN0aXZlRGlyZWN0b3J5RGVmYXVsdEF1dGhlbnRpY2F0aW9uIHtcbiAgdHlwZTogJ2F6dXJlLWFjdGl2ZS1kaXJlY3RvcnktZGVmYXVsdCc7XG4gIG9wdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBJZiB5b3Ugd2FudCB0byBjb25uZWN0IHVzaW5nIGEgc3BlY2lmaWMgY2xpZW50IGFjY291bnRcbiAgICAgKiB0aGV5IG5lZWQgdG8gcHJvdmlkZSBgY2xpZW50SWRgIGFzc29jaWF0ZWQgdG8gdGhlaXIgY3JlYXRlZCBpZGVudGl0eS5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgb3B0aW9uYWwgZm9yIHJldHJpZXZpbmcgYSB0b2tlblxuICAgICAqL1xuICAgIGNsaWVudElkPzogc3RyaW5nO1xuICB9O1xufVxuXG5cbmludGVyZmFjZSBBenVyZUFjdGl2ZURpcmVjdG9yeUFjY2Vzc1Rva2VuQXV0aGVudGljYXRpb24ge1xuICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1hY2Nlc3MtdG9rZW4nO1xuICBvcHRpb25zOiB7XG4gICAgLyoqXG4gICAgICogQSB1c2VyIG5lZWQgdG8gcHJvdmlkZSBgdG9rZW5gIHdoaWNoIHRoZXkgcmV0cmlldmVkIGVsc2Ugd2hlcmVcbiAgICAgKiB0byBmb3JtaW5nIHRoZSBjb25uZWN0aW9uLlxuICAgICAqL1xuICAgIHRva2VuOiBzdHJpbmc7XG4gIH07XG59XG5cbmludGVyZmFjZSBBenVyZUFjdGl2ZURpcmVjdG9yeVBhc3N3b3JkQXV0aGVudGljYXRpb24ge1xuICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1wYXNzd29yZCc7XG4gIG9wdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBBIHVzZXIgbmVlZCB0byBwcm92aWRlIGB1c2VyTmFtZWAgYXNzb2NpYXRlIHRvIHRoZWlyIGFjY291bnQuXG4gICAgICovXG4gICAgdXNlck5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgdXNlciBuZWVkIHRvIHByb3ZpZGUgYHBhc3N3b3JkYCBhc3NvY2lhdGUgdG8gdGhlaXIgYWNjb3VudC5cbiAgICAgKi9cbiAgICBwYXNzd29yZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBjbGllbnQgaWQgdG8gdXNlLlxuICAgICAqL1xuICAgIGNsaWVudElkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBwYXJhbWV0ZXIgZm9yIHNwZWNpZmljIEF6dXJlIHRlbmFudCBJRFxuICAgICAqL1xuICAgIHRlbmFudElkOiBzdHJpbmc7XG4gIH07XG59XG5cbmludGVyZmFjZSBBenVyZUFjdGl2ZURpcmVjdG9yeVNlcnZpY2VQcmluY2lwYWxTZWNyZXQge1xuICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1zZXJ2aWNlLXByaW5jaXBhbC1zZWNyZXQnO1xuICBvcHRpb25zOiB7XG4gICAgLyoqXG4gICAgICogQXBwbGljYXRpb24gKGBjbGllbnRgKSBJRCBmcm9tIHlvdXIgcmVnaXN0ZXJlZCBBenVyZSBhcHBsaWNhdGlvblxuICAgICAqL1xuICAgIGNsaWVudElkOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVGhlIGNyZWF0ZWQgYGNsaWVudCBzZWNyZXRgIGZvciB0aGlzIHJlZ2lzdGVyZWQgQXp1cmUgYXBwbGljYXRpb25cbiAgICAgKi9cbiAgICBjbGllbnRTZWNyZXQ6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBEaXJlY3RvcnkgKGB0ZW5hbnRgKSBJRCBmcm9tIHlvdXIgcmVnaXN0ZXJlZCBBenVyZSBhcHBsaWNhdGlvblxuICAgICAqL1xuICAgIHRlbmFudElkOiBzdHJpbmc7XG4gIH07XG59XG5cbmludGVyZmFjZSBOdGxtQXV0aGVudGljYXRpb24ge1xuICB0eXBlOiAnbnRsbSc7XG4gIG9wdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBVc2VyIG5hbWUgZnJvbSB5b3VyIHdpbmRvd3MgYWNjb3VudC5cbiAgICAgKi9cbiAgICB1c2VyTmFtZTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFBhc3N3b3JkIGZyb20geW91ciB3aW5kb3dzIGFjY291bnQuXG4gICAgICovXG4gICAgcGFzc3dvcmQ6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBPbmNlIHlvdSBzZXQgZG9tYWluIGZvciBudGxtIGF1dGhlbnRpY2F0aW9uIHR5cGUsIGRyaXZlciB3aWxsIGNvbm5lY3QgdG8gU1FMIFNlcnZlciB1c2luZyBkb21haW4gbG9naW4uXG4gICAgICpcbiAgICAgKiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3IgZm9ybWluZyBhIGNvbm5lY3Rpb24gdXNpbmcgbnRsbSB0eXBlXG4gICAgICovXG4gICAgZG9tYWluOiBzdHJpbmc7XG4gIH07XG59XG5cbmludGVyZmFjZSBEZWZhdWx0QXV0aGVudGljYXRpb24ge1xuICB0eXBlOiAnZGVmYXVsdCc7XG4gIG9wdGlvbnM6IHtcbiAgICAvKipcbiAgICAgKiBVc2VyIG5hbWUgdG8gdXNlIGZvciBzcWwgc2VydmVyIGxvZ2luLlxuICAgICAqL1xuICAgIHVzZXJOYW1lPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIFBhc3N3b3JkIHRvIHVzZSBmb3Igc3FsIHNlcnZlciBsb2dpbi5cbiAgICAgKi9cbiAgICBwYXNzd29yZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgfTtcbn1cblxuaW50ZXJmYWNlIEVycm9yV2l0aENvZGUgZXh0ZW5kcyBFcnJvciB7XG4gIGNvZGU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIENvbm5lY3Rpb25BdXRoZW50aWNhdGlvbiA9IERlZmF1bHRBdXRoZW50aWNhdGlvbiB8IE50bG1BdXRoZW50aWNhdGlvbiB8IEF6dXJlQWN0aXZlRGlyZWN0b3J5UGFzc3dvcmRBdXRoZW50aWNhdGlvbiB8IEF6dXJlQWN0aXZlRGlyZWN0b3J5TXNpQXBwU2VydmljZUF1dGhlbnRpY2F0aW9uIHwgQXp1cmVBY3RpdmVEaXJlY3RvcnlNc2lWbUF1dGhlbnRpY2F0aW9uIHwgQXp1cmVBY3RpdmVEaXJlY3RvcnlBY2Nlc3NUb2tlbkF1dGhlbnRpY2F0aW9uIHwgQXp1cmVBY3RpdmVEaXJlY3RvcnlTZXJ2aWNlUHJpbmNpcGFsU2VjcmV0IHwgQXp1cmVBY3RpdmVEaXJlY3RvcnlEZWZhdWx0QXV0aGVudGljYXRpb247XG5cbmludGVyZmFjZSBJbnRlcm5hbENvbm5lY3Rpb25Db25maWcge1xuICBzZXJ2ZXI6IHN0cmluZztcbiAgYXV0aGVudGljYXRpb246IENvbm5lY3Rpb25BdXRoZW50aWNhdGlvbjtcbiAgb3B0aW9uczogSW50ZXJuYWxDb25uZWN0aW9uT3B0aW9ucztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbnRlcm5hbENvbm5lY3Rpb25PcHRpb25zIHtcbiAgYWJvcnRUcmFuc2FjdGlvbk9uRXJyb3I6IGJvb2xlYW47XG4gIGFwcE5hbWU6IHVuZGVmaW5lZCB8IHN0cmluZztcbiAgY2FtZWxDYXNlQ29sdW1uczogYm9vbGVhbjtcbiAgY2FuY2VsVGltZW91dDogbnVtYmVyO1xuICBjb2x1bW5FbmNyeXB0aW9uS2V5Q2FjaGVUVEw6IG51bWJlcjtcbiAgY29sdW1uRW5jcnlwdGlvblNldHRpbmc6IGJvb2xlYW47XG4gIGNvbHVtbk5hbWVSZXBsYWNlcjogdW5kZWZpbmVkIHwgKChjb2xOYW1lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIG1ldGFkYXRhOiBNZXRhZGF0YSkgPT4gc3RyaW5nKTtcbiAgY29ubmVjdGlvblJldHJ5SW50ZXJ2YWw6IG51bWJlcjtcbiAgY29ubmVjdG9yOiB1bmRlZmluZWQgfCAoKCkgPT4gUHJvbWlzZTxuZXQuU29ja2V0Pik7XG4gIGNvbm5lY3RUaW1lb3V0OiBudW1iZXI7XG4gIGNvbm5lY3Rpb25Jc29sYXRpb25MZXZlbDogdHlwZW9mIElTT0xBVElPTl9MRVZFTFtrZXlvZiB0eXBlb2YgSVNPTEFUSU9OX0xFVkVMXTtcbiAgY3J5cHRvQ3JlZGVudGlhbHNEZXRhaWxzOiBTZWN1cmVDb250ZXh0T3B0aW9ucztcbiAgZGF0YWJhc2U6IHVuZGVmaW5lZCB8IHN0cmluZztcbiAgZGF0ZWZpcnN0OiBudW1iZXI7XG4gIGRhdGVGb3JtYXQ6IHN0cmluZztcbiAgZGVidWc6IHtcbiAgICBkYXRhOiBib29sZWFuO1xuICAgIHBhY2tldDogYm9vbGVhbjtcbiAgICBwYXlsb2FkOiBib29sZWFuO1xuICAgIHRva2VuOiBib29sZWFuO1xuICB9O1xuICBlbmFibGVBbnNpTnVsbDogbnVsbCB8IGJvb2xlYW47XG4gIGVuYWJsZUFuc2lOdWxsRGVmYXVsdDogbnVsbCB8IGJvb2xlYW47XG4gIGVuYWJsZUFuc2lQYWRkaW5nOiBudWxsIHwgYm9vbGVhbjtcbiAgZW5hYmxlQW5zaVdhcm5pbmdzOiBudWxsIHwgYm9vbGVhbjtcbiAgZW5hYmxlQXJpdGhBYm9ydDogbnVsbCB8IGJvb2xlYW47XG4gIGVuYWJsZUNvbmNhdE51bGxZaWVsZHNOdWxsOiBudWxsIHwgYm9vbGVhbjtcbiAgZW5hYmxlQ3Vyc29yQ2xvc2VPbkNvbW1pdDogbnVsbCB8IGJvb2xlYW47XG4gIGVuYWJsZUltcGxpY2l0VHJhbnNhY3Rpb25zOiBudWxsIHwgYm9vbGVhbjtcbiAgZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQ6IG51bGwgfCBib29sZWFuO1xuICBlbmFibGVRdW90ZWRJZGVudGlmaWVyOiBudWxsIHwgYm9vbGVhbjtcbiAgZW5jcnlwdDogc3RyaW5nIHwgYm9vbGVhbjtcbiAgZW5jcnlwdGlvbktleVN0b3JlUHJvdmlkZXJzOiBLZXlTdG9yZVByb3ZpZGVyTWFwIHwgdW5kZWZpbmVkO1xuICBmYWxsYmFja1RvRGVmYXVsdERiOiBib29sZWFuO1xuICBpbnN0YW5jZU5hbWU6IHVuZGVmaW5lZCB8IHN0cmluZztcbiAgaXNvbGF0aW9uTGV2ZWw6IHR5cGVvZiBJU09MQVRJT05fTEVWRUxba2V5b2YgdHlwZW9mIElTT0xBVElPTl9MRVZFTF07XG4gIGxhbmd1YWdlOiBzdHJpbmc7XG4gIGxvY2FsQWRkcmVzczogdW5kZWZpbmVkIHwgc3RyaW5nO1xuICBtYXhSZXRyaWVzT25UcmFuc2llbnRFcnJvcnM6IG51bWJlcjtcbiAgbXVsdGlTdWJuZXRGYWlsb3ZlcjogYm9vbGVhbjtcbiAgcGFja2V0U2l6ZTogbnVtYmVyO1xuICBwb3J0OiB1bmRlZmluZWQgfCBudW1iZXI7XG4gIHJlYWRPbmx5SW50ZW50OiBib29sZWFuO1xuICByZXF1ZXN0VGltZW91dDogbnVtYmVyO1xuICByb3dDb2xsZWN0aW9uT25Eb25lOiBib29sZWFuO1xuICByb3dDb2xsZWN0aW9uT25SZXF1ZXN0Q29tcGxldGlvbjogYm9vbGVhbjtcbiAgc2VydmVyTmFtZTogdW5kZWZpbmVkIHwgc3RyaW5nO1xuICBzZXJ2ZXJTdXBwb3J0c0NvbHVtbkVuY3J5cHRpb246IGJvb2xlYW47XG4gIHRkc1ZlcnNpb246IHN0cmluZztcbiAgdGV4dHNpemU6IG51bWJlcjtcbiAgdHJ1c3RlZFNlcnZlck5hbWVBRTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB0cnVzdFNlcnZlckNlcnRpZmljYXRlOiBib29sZWFuO1xuICB1c2VDb2x1bW5OYW1lczogYm9vbGVhbjtcbiAgdXNlVVRDOiBib29sZWFuO1xuICB3b3Jrc3RhdGlvbklkOiB1bmRlZmluZWQgfCBzdHJpbmc7XG4gIGxvd2VyQ2FzZUd1aWRzOiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgS2V5U3RvcmVQcm92aWRlck1hcCB7XG4gIFtrZXk6IHN0cmluZ106IENvbHVtbkVuY3J5cHRpb25BenVyZUtleVZhdWx0UHJvdmlkZXI7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuaW50ZXJmYWNlIFN0YXRlIHtcbiAgbmFtZTogc3RyaW5nO1xuICBlbnRlcj8odGhpczogQ29ubmVjdGlvbik6IHZvaWQ7XG4gIGV4aXQ/KHRoaXM6IENvbm5lY3Rpb24sIG5ld1N0YXRlOiBTdGF0ZSk6IHZvaWQ7XG4gIGV2ZW50czoge1xuICAgIHNvY2tldEVycm9yPyh0aGlzOiBDb25uZWN0aW9uLCBlcnI6IEVycm9yKTogdm9pZDtcbiAgICBjb25uZWN0VGltZW91dD8odGhpczogQ29ubmVjdGlvbik6IHZvaWQ7XG4gICAgbWVzc2FnZT8odGhpczogQ29ubmVjdGlvbiwgbWVzc2FnZTogTWVzc2FnZSk6IHZvaWQ7XG4gICAgcmV0cnk/KHRoaXM6IENvbm5lY3Rpb24pOiB2b2lkO1xuICAgIHJlY29ubmVjdD8odGhpczogQ29ubmVjdGlvbik6IHZvaWQ7XG4gIH07XG59XG5cbnR5cGUgQXV0aGVudGljYXRpb24gPSBEZWZhdWx0QXV0aGVudGljYXRpb24gfFxuICBOdGxtQXV0aGVudGljYXRpb24gfFxuICBBenVyZUFjdGl2ZURpcmVjdG9yeVBhc3N3b3JkQXV0aGVudGljYXRpb24gfFxuICBBenVyZUFjdGl2ZURpcmVjdG9yeU1zaUFwcFNlcnZpY2VBdXRoZW50aWNhdGlvbiB8XG4gIEF6dXJlQWN0aXZlRGlyZWN0b3J5TXNpVm1BdXRoZW50aWNhdGlvbiB8XG4gIEF6dXJlQWN0aXZlRGlyZWN0b3J5QWNjZXNzVG9rZW5BdXRoZW50aWNhdGlvbiB8XG4gIEF6dXJlQWN0aXZlRGlyZWN0b3J5U2VydmljZVByaW5jaXBhbFNlY3JldCB8XG4gIEF6dXJlQWN0aXZlRGlyZWN0b3J5RGVmYXVsdEF1dGhlbnRpY2F0aW9uO1xuXG50eXBlIEF1dGhlbnRpY2F0aW9uVHlwZSA9IEF1dGhlbnRpY2F0aW9uWyd0eXBlJ107XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29ubmVjdGlvbkNvbmZpZ3VyYXRpb24ge1xuICAvKipcbiAgICogSG9zdG5hbWUgdG8gY29ubmVjdCB0by5cbiAgICovXG4gIHNlcnZlcjogc3RyaW5nO1xuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBmb3JtaW5nIHRoZSBjb25uZWN0aW9uLlxuICAgKi9cbiAgb3B0aW9ucz86IENvbm5lY3Rpb25PcHRpb25zO1xuICAvKipcbiAgICogQXV0aGVudGljYXRpb24gcmVsYXRlZCBvcHRpb25zIGZvciBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXV0aGVudGljYXRpb24/OiBBdXRoZW50aWNhdGlvbk9wdGlvbnM7XG59XG5cbmludGVyZmFjZSBEZWJ1Z09wdGlvbnMge1xuICAvKipcbiAgICogQSBib29sZWFuLCBjb250cm9sbGluZyB3aGV0aGVyIFtbZGVidWddXSBldmVudHMgd2lsbCBiZSBlbWl0dGVkIHdpdGggdGV4dCBkZXNjcmliaW5nIHBhY2tldCBkYXRhIGRldGFpbHNcbiAgICpcbiAgICogKGRlZmF1bHQ6IGBmYWxzZWApXG4gICAqL1xuICBkYXRhOiBib29sZWFuO1xuICAvKipcbiAgICogQSBib29sZWFuLCBjb250cm9sbGluZyB3aGV0aGVyIFtbZGVidWddXSBldmVudHMgd2lsbCBiZSBlbWl0dGVkIHdpdGggdGV4dCBkZXNjcmliaW5nIHBhY2tldCBkZXRhaWxzXG4gICAqXG4gICAqIChkZWZhdWx0OiBgZmFsc2VgKVxuICAgKi9cbiAgcGFja2V0OiBib29sZWFuO1xuICAvKipcbiAgICogQSBib29sZWFuLCBjb250cm9sbGluZyB3aGV0aGVyIFtbZGVidWddXSBldmVudHMgd2lsbCBiZSBlbWl0dGVkIHdpdGggdGV4dCBkZXNjcmliaW5nIHBhY2tldCBwYXlsb2FkIGRldGFpbHNcbiAgICpcbiAgICogKGRlZmF1bHQ6IGBmYWxzZWApXG4gICAqL1xuICBwYXlsb2FkOiBib29sZWFuO1xuICAvKipcbiAgICogQSBib29sZWFuLCBjb250cm9sbGluZyB3aGV0aGVyIFtbZGVidWddXSBldmVudHMgd2lsbCBiZSBlbWl0dGVkIHdpdGggdGV4dCBkZXNjcmliaW5nIHRva2VuIHN0cmVhbSB0b2tlbnNcbiAgICpcbiAgICogKGRlZmF1bHQ6IGBmYWxzZWApXG4gICAqL1xuICB0b2tlbjogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIEF1dGhlbnRpY2F0aW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUeXBlIG9mIHRoZSBhdXRoZW50aWNhdGlvbiBtZXRob2QsIHZhbGlkIHR5cGVzIGFyZSBgZGVmYXVsdGAsIGBudGxtYCxcbiAgICogYGF6dXJlLWFjdGl2ZS1kaXJlY3RvcnktcGFzc3dvcmRgLCBgYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1hY2Nlc3MtdG9rZW5gLFxuICAgKiBgYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktdm1gLCBgYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktYXBwLXNlcnZpY2VgLFxuICAgKiBgYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1kZWZhdWx0YFxuICAgKiBvciBgYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1zZXJ2aWNlLXByaW5jaXBhbC1zZWNyZXRgXG4gICAqL1xuICB0eXBlPzogQXV0aGVudGljYXRpb25UeXBlO1xuICAvKipcbiAgICogRGlmZmVyZW50IG9wdGlvbnMgZm9yIGF1dGhlbnRpY2F0aW9uIHR5cGVzOlxuICAgKlxuICAgKiAqIGBkZWZhdWx0YDogW1tEZWZhdWx0QXV0aGVudGljYXRpb24ub3B0aW9uc11dXG4gICAqICogYG50bG1gIDpbW050bG1BdXRoZW50aWNhdGlvbl1dXG4gICAqICogYGF6dXJlLWFjdGl2ZS1kaXJlY3RvcnktcGFzc3dvcmRgIDogW1tBenVyZUFjdGl2ZURpcmVjdG9yeVBhc3N3b3JkQXV0aGVudGljYXRpb24ub3B0aW9uc11dXG4gICAqICogYGF6dXJlLWFjdGl2ZS1kaXJlY3RvcnktYWNjZXNzLXRva2VuYCA6IFtbQXp1cmVBY3RpdmVEaXJlY3RvcnlBY2Nlc3NUb2tlbkF1dGhlbnRpY2F0aW9uLm9wdGlvbnNdXVxuICAgKiAqIGBhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS12bWAgOiBbW0F6dXJlQWN0aXZlRGlyZWN0b3J5TXNpVm1BdXRoZW50aWNhdGlvbi5vcHRpb25zXV1cbiAgICogKiBgYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktYXBwLXNlcnZpY2VgIDogW1tBenVyZUFjdGl2ZURpcmVjdG9yeU1zaUFwcFNlcnZpY2VBdXRoZW50aWNhdGlvbi5vcHRpb25zXV1cbiAgICogKiBgYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1zZXJ2aWNlLXByaW5jaXBhbC1zZWNyZXRgIDogW1tBenVyZUFjdGl2ZURpcmVjdG9yeVNlcnZpY2VQcmluY2lwYWxTZWNyZXQub3B0aW9uc11dXG4gICAqICogYGF6dXJlLWFjdGl2ZS1kaXJlY3RvcnktZGVmYXVsdGAgOiBbW0F6dXJlQWN0aXZlRGlyZWN0b3J5RGVmYXVsdEF1dGhlbnRpY2F0aW9uLm9wdGlvbnNdXVxuICAgKi9cbiAgb3B0aW9ucz86IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25uZWN0aW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBIGJvb2xlYW4gZGV0ZXJtaW5pbmcgd2hldGhlciB0byByb2xsYmFjayBhIHRyYW5zYWN0aW9uIGF1dG9tYXRpY2FsbHkgaWYgYW55IGVycm9yIGlzIGVuY291bnRlcmVkXG4gICAqIGR1cmluZyB0aGUgZ2l2ZW4gdHJhbnNhY3Rpb24ncyBleGVjdXRpb24uIFRoaXMgc2V0cyB0aGUgdmFsdWUgZm9yIGBTRVQgWEFDVF9BQk9SVGAgZHVyaW5nIHRoZVxuICAgKiBpbml0aWFsIFNRTCBwaGFzZSBvZiBhIGNvbm5lY3Rpb24gW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3NxbC90LXNxbC9zdGF0ZW1lbnRzL3NldC14YWN0LWFib3J0LXRyYW5zYWN0LXNxbCkuXG4gICAqL1xuICBhYm9ydFRyYW5zYWN0aW9uT25FcnJvcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFwcGxpY2F0aW9uIG5hbWUgdXNlZCBmb3IgaWRlbnRpZnlpbmcgYSBzcGVjaWZpYyBhcHBsaWNhdGlvbiBpbiBwcm9maWxpbmcsIGxvZ2dpbmcgb3IgdHJhY2luZyB0b29scyBvZiBTUUxTZXJ2ZXIuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgVGVkaW91c2ApXG4gICAqL1xuICBhcHBOYW1lPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4sIGNvbnRyb2xsaW5nIHdoZXRoZXIgdGhlIGNvbHVtbiBuYW1lcyByZXR1cm5lZCB3aWxsIGhhdmUgdGhlIGZpcnN0IGxldHRlciBjb252ZXJ0ZWQgdG8gbG93ZXIgY2FzZVxuICAgKiAoYHRydWVgKSBvciBub3QuIFRoaXMgdmFsdWUgaXMgaWdub3JlZCBpZiB5b3UgcHJvdmlkZSBhIFtbY29sdW1uTmFtZVJlcGxhY2VyXV0uXG4gICAqXG4gICAqIChkZWZhdWx0OiBgZmFsc2VgKS5cbiAgICovXG4gIGNhbWVsQ2FzZUNvbHVtbnM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIFtbUmVxdWVzdC5jYW5jZWxdXSAoYWJvcnQpIG9mIGEgcmVxdWVzdCBpcyBjb25zaWRlcmVkIGZhaWxlZFxuICAgKlxuICAgKiAoZGVmYXVsdDogYDUwMDBgKS5cbiAgICovXG4gIGNhbmNlbFRpbWVvdXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gd2l0aCBwYXJhbWV0ZXJzIGAoY29sdW1uTmFtZSwgaW5kZXgsIGNvbHVtbk1ldGFEYXRhKWAgYW5kIHJldHVybmluZyBhIHN0cmluZy4gSWYgcHJvdmlkZWQsXG4gICAqIHRoaXMgd2lsbCBiZSBjYWxsZWQgb25jZSBwZXIgY29sdW1uIHBlciByZXN1bHQtc2V0LiBUaGUgcmV0dXJuZWQgdmFsdWUgd2lsbCBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIFNRTC1wcm92aWRlZFxuICAgKiBjb2x1bW4gbmFtZSBvbiByb3cgYW5kIG1ldGEgZGF0YSBvYmplY3RzLiBUaGlzIGFsbG93cyB5b3UgdG8gZHluYW1pY2FsbHkgY29udmVydCBiZXR3ZWVuIG5hbWluZyBjb252ZW50aW9ucy5cbiAgICpcbiAgICogKGRlZmF1bHQ6IGBudWxsYClcbiAgICovXG4gIGNvbHVtbk5hbWVSZXBsYWNlcj86IChjb2xOYW1lOiBzdHJpbmcsIGluZGV4OiBudW1iZXIsIG1ldGFkYXRhOiBNZXRhZGF0YSkgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgbWlsbGlzZWNvbmRzIGJlZm9yZSByZXRyeWluZyB0byBlc3RhYmxpc2ggY29ubmVjdGlvbiwgaW4gY2FzZSBvZiB0cmFuc2llbnQgZmFpbHVyZS5cbiAgICpcbiAgICogKGRlZmF1bHQ6YDUwMGApXG4gICAqL1xuICBjb25uZWN0aW9uUmV0cnlJbnRlcnZhbD86IG51bWJlcjtcblxuICAvKipcbiAgICogQ3VzdG9tIGNvbm5lY3RvciBmYWN0b3J5IG1ldGhvZC5cbiAgICpcbiAgICogKGRlZmF1bHQ6IGB1bmRlZmluZWRgKVxuICAgKi9cbiAgY29ubmVjdG9yPzogKCkgPT4gUHJvbWlzZTxuZXQuU29ja2V0PjtcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgYmVmb3JlIHRoZSBhdHRlbXB0IHRvIGNvbm5lY3QgaXMgY29uc2lkZXJlZCBmYWlsZWRcbiAgICpcbiAgICogKGRlZmF1bHQ6IGAxNTAwMGApLlxuICAgKi9cbiAgY29ubmVjdFRpbWVvdXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGlzb2xhdGlvbiBsZXZlbCBmb3IgbmV3IGNvbm5lY3Rpb25zLiBBbGwgb3V0LW9mLXRyYW5zYWN0aW9uIHF1ZXJpZXMgYXJlIGV4ZWN1dGVkIHdpdGggdGhpcyBzZXR0aW5nLlxuICAgKlxuICAgKiBUaGUgaXNvbGF0aW9uIGxldmVscyBhcmUgYXZhaWxhYmxlIGZyb20gYHJlcXVpcmUoJ3RlZGlvdXMnKS5JU09MQVRJT05fTEVWRUxgLlxuICAgKiAqIGBSRUFEX1VOQ09NTUlUVEVEYFxuICAgKiAqIGBSRUFEX0NPTU1JVFRFRGBcbiAgICogKiBgUkVQRUFUQUJMRV9SRUFEYFxuICAgKiAqIGBTRVJJQUxJWkFCTEVgXG4gICAqICogYFNOQVBTSE9UYFxuICAgKlxuICAgKiAoZGVmYXVsdDogYFJFQURfQ09NTUlURURgKS5cbiAgICovXG4gIGNvbm5lY3Rpb25Jc29sYXRpb25MZXZlbD86IG51bWJlcjtcblxuICAvKipcbiAgICogV2hlbiBlbmNyeXB0aW9uIGlzIHVzZWQsIGFuIG9iamVjdCBtYXkgYmUgc3VwcGxpZWQgdGhhdCB3aWxsIGJlIHVzZWRcbiAgICogZm9yIHRoZSBmaXJzdCBhcmd1bWVudCB3aGVuIGNhbGxpbmcgW2B0bHMuY3JlYXRlU2VjdXJlUGFpcmBdKGh0dHA6Ly9ub2RlanMub3JnL2RvY3MvbGF0ZXN0L2FwaS90bHMuaHRtbCN0bHNfdGxzX2NyZWF0ZXNlY3VyZXBhaXJfY3JlZGVudGlhbHNfaXNzZXJ2ZXJfcmVxdWVzdGNlcnRfcmVqZWN0dW5hdXRob3JpemVkKVxuICAgKlxuICAgKiAoZGVmYXVsdDogYHt9YClcbiAgICovXG4gIGNyeXB0b0NyZWRlbnRpYWxzRGV0YWlscz86IFNlY3VyZUNvbnRleHRPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBEYXRhYmFzZSB0byBjb25uZWN0IHRvIChkZWZhdWx0OiBkZXBlbmRlbnQgb24gc2VydmVyIGNvbmZpZ3VyYXRpb24pLlxuICAgKi9cbiAgZGF0YWJhc2U/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGZpcnN0IGRheSBvZiB0aGUgd2VlayB0byBhIG51bWJlciBmcm9tIDEgdGhyb3VnaCA3LlxuICAgKi9cbiAgZGF0ZWZpcnN0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBIHN0cmluZyByZXByZXNlbnRpbmcgcG9zaXRpb24gb2YgbW9udGgsIGRheSBhbmQgeWVhciBpbiB0ZW1wb3JhbCBkYXRhdHlwZXMuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgbWR5YClcbiAgICovXG4gIGRhdGVGb3JtYXQ/OiBzdHJpbmc7XG5cbiAgZGVidWc/OiBEZWJ1Z09wdGlvbnM7XG5cbiAgLyoqXG4gICAqIEEgYm9vbGVhbiwgY29udHJvbHMgdGhlIHdheSBudWxsIHZhbHVlcyBzaG91bGQgYmUgdXNlZCBkdXJpbmcgY29tcGFyaXNvbiBvcGVyYXRpb24uXG4gICAqXG4gICAqIChkZWZhdWx0OiBgdHJ1ZWApXG4gICAqL1xuICBlbmFibGVBbnNpTnVsbD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElmIHRydWUsIGBTRVQgQU5TSV9OVUxMX0RGTFRfT04gT05gIHdpbGwgYmUgc2V0IGluIHRoZSBpbml0aWFsIHNxbC4gVGhpcyBtZWFucyBuZXcgY29sdW1ucyB3aWxsIGJlXG4gICAqIG51bGxhYmxlIGJ5IGRlZmF1bHQuIFNlZSB0aGUgW1QtU1FMIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXMxODczNzUuYXNweClcbiAgICpcbiAgICogKGRlZmF1bHQ6IGB0cnVlYCkuXG4gICAqL1xuICBlbmFibGVBbnNpTnVsbERlZmF1bHQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4sIGNvbnRyb2xzIGlmIHBhZGRpbmcgc2hvdWxkIGJlIGFwcGxpZWQgZm9yIHZhbHVlcyBzaG9ydGVyIHRoYW4gdGhlIHNpemUgb2YgZGVmaW5lZCBjb2x1bW4uXG4gICAqXG4gICAqIChkZWZhdWx0OiBgdHJ1ZWApXG4gICAqL1xuICBlbmFibGVBbnNpUGFkZGluZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElmIHRydWUsIFNRTCBTZXJ2ZXIgd2lsbCBmb2xsb3cgSVNPIHN0YW5kYXJkIGJlaGF2aW9yIGR1cmluZyB2YXJpb3VzIGVycm9yIGNvbmRpdGlvbnMuIEZvciBkZXRhaWxzLFxuICAgKiBzZWUgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3NxbC90LXNxbC9zdGF0ZW1lbnRzL3NldC1hbnNpLXdhcm5pbmdzLXRyYW5zYWN0LXNxbClcbiAgICpcbiAgICogKGRlZmF1bHQ6IGB0cnVlYClcbiAgICovXG4gIGVuYWJsZUFuc2lXYXJuaW5ncz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEVuZHMgYSBxdWVyeSB3aGVuIGFuIG92ZXJmbG93IG9yIGRpdmlkZS1ieS16ZXJvIGVycm9yIG9jY3VycyBkdXJpbmcgcXVlcnkgZXhlY3V0aW9uLlxuICAgKiBTZWUgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3NxbC90LXNxbC9zdGF0ZW1lbnRzL3NldC1hcml0aGFib3J0LXRyYW5zYWN0LXNxbD92aWV3PXNxbC1zZXJ2ZXItMjAxNylcbiAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICpcbiAgICogKGRlZmF1bHQ6IGB0cnVlYClcbiAgICovXG4gIGVuYWJsZUFyaXRoQWJvcnQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4sIGRldGVybWluZXMgaWYgY29uY2F0ZW5hdGlvbiB3aXRoIE5VTEwgc2hvdWxkIHJlc3VsdCBpbiBOVUxMIG9yIGVtcHR5IHN0cmluZyB2YWx1ZSwgbW9yZSBkZXRhaWxzIGluXG4gICAqIFtkb2N1bWVudGF0aW9uXShodHRwczovL2RvY3MubWljcm9zb2Z0LmNvbS9lbi11cy9zcWwvdC1zcWwvc3RhdGVtZW50cy9zZXQtY29uY2F0LW51bGwteWllbGRzLW51bGwtdHJhbnNhY3Qtc3FsKVxuICAgKlxuICAgKiAoZGVmYXVsdDogYHRydWVgKVxuICAgKi9cbiAgZW5hYmxlQ29uY2F0TnVsbFlpZWxkc051bGw/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4sIGNvbnRyb2xzIHdoZXRoZXIgY3Vyc29yIHNob3VsZCBiZSBjbG9zZWQsIGlmIHRoZSB0cmFuc2FjdGlvbiBvcGVuaW5nIGl0IGdldHMgY29tbWl0dGVkIG9yIHJvbGxlZFxuICAgKiBiYWNrLlxuICAgKlxuICAgKiAoZGVmYXVsdDogYG51bGxgKVxuICAgKi9cbiAgZW5hYmxlQ3Vyc29yQ2xvc2VPbkNvbW1pdD86IGJvb2xlYW4gfCBudWxsO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4sIHNldHMgdGhlIGNvbm5lY3Rpb24gdG8gZWl0aGVyIGltcGxpY2l0IG9yIGF1dG9jb21taXQgdHJhbnNhY3Rpb24gbW9kZS5cbiAgICpcbiAgICogKGRlZmF1bHQ6IGBmYWxzZWApXG4gICAqL1xuICBlbmFibGVJbXBsaWNpdFRyYW5zYWN0aW9ucz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElmIGZhbHNlLCBlcnJvciBpcyBub3QgZ2VuZXJhdGVkIGR1cmluZyBsb3NzIG9mIHByZWNlc3Npb24uXG4gICAqXG4gICAqIChkZWZhdWx0OiBgZmFsc2VgKVxuICAgKi9cbiAgZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJZiB0cnVlLCBjaGFyYWN0ZXJzIGVuY2xvc2VkIGluIHNpbmdsZSBxdW90ZXMgYXJlIHRyZWF0ZWQgYXMgbGl0ZXJhbHMgYW5kIHRob3NlIGVuY2xvc2VkIGRvdWJsZSBxdW90ZXMgYXJlIHRyZWF0ZWQgYXMgaWRlbnRpZmllcnMuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgdHJ1ZWApXG4gICAqL1xuICBlbmFibGVRdW90ZWRJZGVudGlmaWVyPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBzdHJpbmcgdmFsdWUgdGhhdCBjYW4gYmUgb25seSBzZXQgdG8gJ3N0cmljdCcsIHdoaWNoIGluZGljYXRlcyB0aGUgdXNhZ2UgVERTIDguMCBwcm90b2NvbC4gT3RoZXJ3aXNlLFxuICAgKiBhIGJvb2xlYW4gZGV0ZXJtaW5pbmcgd2hldGhlciBvciBub3QgdGhlIGNvbm5lY3Rpb24gd2lsbCBiZSBlbmNyeXB0ZWQuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgdHJ1ZWApXG4gICAqL1xuICBlbmNyeXB0Pzogc3RyaW5nIHwgYm9vbGVhbjtcblxuICAvKipcbiAgICogQnkgZGVmYXVsdCwgaWYgdGhlIGRhdGFiYXNlIHJlcXVlc3RlZCBieSBbW2RhdGFiYXNlXV0gY2Fubm90IGJlIGFjY2Vzc2VkLFxuICAgKiB0aGUgY29ubmVjdGlvbiB3aWxsIGZhaWwgd2l0aCBhbiBlcnJvci4gSG93ZXZlciwgaWYgW1tmYWxsYmFja1RvRGVmYXVsdERiXV0gaXNcbiAgICogc2V0IHRvIGB0cnVlYCwgdGhlbiB0aGUgdXNlcidzIGRlZmF1bHQgZGF0YWJhc2Ugd2lsbCBiZSB1c2VkIGluc3RlYWRcbiAgICpcbiAgICogKGRlZmF1bHQ6IGBmYWxzZWApXG4gICAqL1xuICBmYWxsYmFja1RvRGVmYXVsdERiPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGluc3RhbmNlIG5hbWUgdG8gY29ubmVjdCB0by5cbiAgICogVGhlIFNRTCBTZXJ2ZXIgQnJvd3NlciBzZXJ2aWNlIG11c3QgYmUgcnVubmluZyBvbiB0aGUgZGF0YWJhc2Ugc2VydmVyLFxuICAgKiBhbmQgVURQIHBvcnQgMTQzNCBvbiB0aGUgZGF0YWJhc2Ugc2VydmVyIG11c3QgYmUgcmVhY2hhYmxlLlxuICAgKlxuICAgKiAobm8gZGVmYXVsdClcbiAgICpcbiAgICogTXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggW1twb3J0XV0uXG4gICAqL1xuICBpbnN0YW5jZU5hbWU/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGlzb2xhdGlvbiBsZXZlbCB0aGF0IHRyYW5zYWN0aW9ucyB3aWxsIGJlIHJ1biB3aXRoLlxuICAgKlxuICAgKiBUaGUgaXNvbGF0aW9uIGxldmVscyBhcmUgYXZhaWxhYmxlIGZyb20gYHJlcXVpcmUoJ3RlZGlvdXMnKS5JU09MQVRJT05fTEVWRUxgLlxuICAgKiAqIGBSRUFEX1VOQ09NTUlUVEVEYFxuICAgKiAqIGBSRUFEX0NPTU1JVFRFRGBcbiAgICogKiBgUkVQRUFUQUJMRV9SRUFEYFxuICAgKiAqIGBTRVJJQUxJWkFCTEVgXG4gICAqICogYFNOQVBTSE9UYFxuICAgKlxuICAgKiAoZGVmYXVsdDogYFJFQURfQ09NTUlURURgKS5cbiAgICovXG4gIGlzb2xhdGlvbkxldmVsPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhlIGxhbmd1YWdlIGVudmlyb25tZW50IGZvciB0aGUgc2Vzc2lvbi4gVGhlIHNlc3Npb24gbGFuZ3VhZ2UgZGV0ZXJtaW5lcyB0aGUgZGF0ZXRpbWUgZm9ybWF0cyBhbmQgc3lzdGVtIG1lc3NhZ2VzLlxuICAgKlxuICAgKiAoZGVmYXVsdDogYHVzX2VuZ2xpc2hgKS5cbiAgICovXG4gIGxhbmd1YWdlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHN0cmluZyBpbmRpY2F0aW5nIHdoaWNoIG5ldHdvcmsgaW50ZXJmYWNlIChpcCBhZGRyZXNzKSB0byB1c2Ugd2hlbiBjb25uZWN0aW5nIHRvIFNRTCBTZXJ2ZXIuXG4gICAqL1xuICBsb2NhbEFkZHJlc3M/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEEgYm9vbGVhbiBkZXRlcm1pbmluZyB3aGV0aGVyIHRvIHBhcnNlIHVuaXF1ZSBpZGVudGlmaWVyIHR5cGUgd2l0aCBsb3dlcmNhc2UgY2FzZSBjaGFyYWN0ZXJzLlxuICAgKlxuICAgKiAoZGVmYXVsdDogYGZhbHNlYCkuXG4gICAqL1xuICBsb3dlckNhc2VHdWlkcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBjb25uZWN0aW9uIHJldHJpZXMgZm9yIHRyYW5zaWVudCBlcnJvcnMu44CBXG4gICAqXG4gICAqIChkZWZhdWx0OiBgM2ApLlxuICAgKi9cbiAgbWF4UmV0cmllc09uVHJhbnNpZW50RXJyb3JzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBNdWx0aVN1Ym5ldEZhaWxvdmVyID0gVHJ1ZSBwYXJhbWV0ZXIsIHdoaWNoIGNhbiBoZWxwIG1pbmltaXplIHRoZSBjbGllbnQgcmVjb3ZlcnkgbGF0ZW5jeSB3aGVuIGZhaWxvdmVycyBvY2N1ci5cbiAgICpcbiAgICogKGRlZmF1bHQ6IGBmYWxzZWApLlxuICAgKi9cbiAgbXVsdGlTdWJuZXRGYWlsb3Zlcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBzaXplIG9mIFREUyBwYWNrZXRzIChzdWJqZWN0IHRvIG5lZ290aWF0aW9uIHdpdGggdGhlIHNlcnZlcikuXG4gICAqIFNob3VsZCBiZSBhIHBvd2VyIG9mIDIuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgNDA5NmApLlxuICAgKi9cbiAgcGFja2V0U2l6ZT86IG51bWJlcjtcblxuICAvKipcbiAgICogUG9ydCB0byBjb25uZWN0IHRvIChkZWZhdWx0OiBgMTQzM2ApLlxuICAgKlxuICAgKiBNdXR1YWxseSBleGNsdXNpdmUgd2l0aCBbW2luc3RhbmNlTmFtZV1dXG4gICAqL1xuICBwb3J0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4sIGRldGVybWluaW5nIHdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gd2lsbCByZXF1ZXN0IHJlYWQgb25seSBhY2Nlc3MgZnJvbSBhIFNRTCBTZXJ2ZXIgQXZhaWxhYmlsaXR5XG4gICAqIEdyb3VwLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtoZXJlXShodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaGg3MTAwNTQuYXNweCBcIk1pY3Jvc29mdDogQ29uZmlndXJlIFJlYWQtT25seSBSb3V0aW5nIGZvciBhbiBBdmFpbGFiaWxpdHkgR3JvdXAgKFNRTCBTZXJ2ZXIpXCIpXG4gICAqXG4gICAqIChkZWZhdWx0OiBgZmFsc2VgKS5cbiAgICovXG4gIHJlYWRPbmx5SW50ZW50PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgYmVmb3JlIGEgcmVxdWVzdCBpcyBjb25zaWRlcmVkIGZhaWxlZCwgb3IgYDBgIGZvciBubyB0aW1lb3V0LlxuICAgKlxuICAgKiBBcyBzb29uIGFzIGEgcmVzcG9uc2UgaXMgcmVjZWl2ZWQsIHRoZSB0aW1lb3V0IGlzIGNsZWFyZWQuIFRoaXMgbWVhbnMgdGhhdCBxdWVyaWVzIHRoYXQgaW1tZWRpYXRlbHkgcmV0dXJuIGEgcmVzcG9uc2UgaGF2ZSBhYmlsaXR5IHRvIHJ1biBsb25nZXIgdGhhbiB0aGlzIHRpbWVvdXQuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgMTUwMDBgKS5cbiAgICovXG4gIHJlcXVlc3RUaW1lb3V0PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4sIHRoYXQgd2hlbiB0cnVlIHdpbGwgZXhwb3NlIHJlY2VpdmVkIHJvd3MgaW4gUmVxdWVzdHMgZG9uZSByZWxhdGVkIGV2ZW50czpcbiAgICogKiBbW1JlcXVlc3QuRXZlbnRfZG9uZUluUHJvY11dXG4gICAqICogW1tSZXF1ZXN0LkV2ZW50X2RvbmVQcm9jXV1cbiAgICogKiBbW1JlcXVlc3QuRXZlbnRfZG9uZV1dXG4gICAqXG4gICAqIChkZWZhdWx0OiBgZmFsc2VgKVxuICAgKlxuICAgKiBDYXV0aW9uOiBJZiBtYW55IHJvdyBhcmUgcmVjZWl2ZWQsIGVuYWJsaW5nIHRoaXMgb3B0aW9uIGNvdWxkIHJlc3VsdCBpblxuICAgKiBleGNlc3NpdmUgbWVtb3J5IHVzYWdlLlxuICAgKi9cbiAgcm93Q29sbGVjdGlvbk9uRG9uZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgYm9vbGVhbiwgdGhhdCB3aGVuIHRydWUgd2lsbCBleHBvc2UgcmVjZWl2ZWQgcm93cyBpbiBSZXF1ZXN0cycgY29tcGxldGlvbiBjYWxsYmFjay5TZWUgW1tSZXF1ZXN0LmNvbnN0cnVjdG9yXV0uXG4gICAqXG4gICAqIChkZWZhdWx0OiBgZmFsc2VgKVxuICAgKlxuICAgKiBDYXV0aW9uOiBJZiBtYW55IHJvdyBhcmUgcmVjZWl2ZWQsIGVuYWJsaW5nIHRoaXMgb3B0aW9uIGNvdWxkIHJlc3VsdCBpblxuICAgKiBleGNlc3NpdmUgbWVtb3J5IHVzYWdlLlxuICAgKi9cbiAgcm93Q29sbGVjdGlvbk9uUmVxdWVzdENvbXBsZXRpb24/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbiBvZiBURFMgdG8gdXNlLiBJZiBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHNwZWNpZmllZCB2ZXJzaW9uLCBuZWdvdGlhdGVkIHZlcnNpb24gaXMgdXNlZCBpbnN0ZWFkLlxuICAgKlxuICAgKiBUaGUgdmVyc2lvbnMgYXJlIGF2YWlsYWJsZSBmcm9tIGByZXF1aXJlKCd0ZWRpb3VzJykuVERTX1ZFUlNJT05gLlxuICAgKiAqIGA3XzFgXG4gICAqICogYDdfMmBcbiAgICogKiBgN18zX0FgXG4gICAqICogYDdfM19CYFxuICAgKiAqIGA3XzRgXG4gICAqXG4gICAqIChkZWZhdWx0OiBgN180YClcbiAgICovXG4gIHRkc1ZlcnNpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgc2l6ZSBvZiB2YXJjaGFyKG1heCksIG52YXJjaGFyKG1heCksIHZhcmJpbmFyeShtYXgpLCB0ZXh0LCBudGV4dCwgYW5kIGltYWdlIGRhdGEgcmV0dXJuZWQgYnkgYSBTRUxFQ1Qgc3RhdGVtZW50LlxuICAgKlxuICAgKiAoZGVmYXVsdDogYDIxNDc0ODM2NDdgKVxuICAgKi9cbiAgdGV4dHNpemU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElmIFwidHJ1ZVwiLCB0aGUgU1FMIFNlcnZlciBTU0wgY2VydGlmaWNhdGUgaXMgYXV0b21hdGljYWxseSB0cnVzdGVkIHdoZW4gdGhlIGNvbW11bmljYXRpb24gbGF5ZXIgaXMgZW5jcnlwdGVkIHVzaW5nIFNTTC5cbiAgICpcbiAgICogSWYgXCJmYWxzZVwiLCB0aGUgU1FMIFNlcnZlciB2YWxpZGF0ZXMgdGhlIHNlcnZlciBTU0wgY2VydGlmaWNhdGUuIElmIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBmYWlscyxcbiAgICogdGhlIGRyaXZlciByYWlzZXMgYW4gZXJyb3IgYW5kIHRlcm1pbmF0ZXMgdGhlIGNvbm5lY3Rpb24uIE1ha2Ugc3VyZSB0aGUgdmFsdWUgcGFzc2VkIHRvIHNlcnZlck5hbWUgZXhhY3RseVxuICAgKiBtYXRjaGVzIHRoZSBDb21tb24gTmFtZSAoQ04pIG9yIEROUyBuYW1lIGluIHRoZSBTdWJqZWN0IEFsdGVybmF0ZSBOYW1lIGluIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUgZm9yIGFuIFNTTCBjb25uZWN0aW9uIHRvIHN1Y2NlZWQuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgdHJ1ZWApXG4gICAqL1xuICB0cnVzdFNlcnZlckNlcnRpZmljYXRlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICpcbiAgICovXG4gIHNlcnZlck5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBIGJvb2xlYW4gZGV0ZXJtaW5pbmcgd2hldGhlciB0byByZXR1cm4gcm93cyBhcyBhcnJheXMgb3Iga2V5LXZhbHVlIGNvbGxlY3Rpb25zLlxuICAgKlxuICAgKiAoZGVmYXVsdDogYGZhbHNlYCkuXG4gICAqL1xuICB1c2VDb2x1bW5OYW1lcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgYm9vbGVhbiBkZXRlcm1pbmluZyB3aGV0aGVyIHRvIHBhc3MgdGltZSB2YWx1ZXMgaW4gVVRDIG9yIGxvY2FsIHRpbWUuXG4gICAqXG4gICAqIChkZWZhdWx0OiBgdHJ1ZWApLlxuICAgKi9cbiAgdXNlVVRDPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHdvcmtzdGF0aW9uIElEIChXU0lEKSBvZiB0aGUgY2xpZW50LCBkZWZhdWx0IG9zLmhvc3RuYW1lKCkuXG4gICAqIFVzZWQgZm9yIGlkZW50aWZ5aW5nIGEgc3BlY2lmaWMgY2xpZW50IGluIHByb2ZpbGluZywgbG9nZ2luZyBvclxuICAgKiB0cmFjaW5nIGNsaWVudCBhY3Rpdml0eSBpbiBTUUxTZXJ2ZXIuXG4gICAqXG4gICAqIFRoZSB2YWx1ZSBpcyByZXBvcnRlZCBieSB0aGUgVFNRTCBmdW5jdGlvbiBIT1NUX05BTUUoKS5cbiAgICovXG4gIHdvcmtzdGF0aW9uSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3QgQ0xFQU5VUF9UWVBFID0ge1xuICBOT1JNQUw6IDAsXG4gIFJFRElSRUNUOiAxLFxuICBSRVRSWTogMlxufTtcblxuaW50ZXJmYWNlIFJvdXRpbmdEYXRhIHtcbiAgc2VydmVyOiBzdHJpbmc7XG4gIHBvcnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBBIFtbQ29ubmVjdGlvbl1dIGluc3RhbmNlIHJlcHJlc2VudHMgYSBzaW5nbGUgY29ubmVjdGlvbiB0byBhIGRhdGFiYXNlIHNlcnZlci5cbiAqXG4gKiBgYGBqc1xuICogdmFyIENvbm5lY3Rpb24gPSByZXF1aXJlKCd0ZWRpb3VzJykuQ29ubmVjdGlvbjtcbiAqIHZhciBjb25maWcgPSB7XG4gKiAgXCJhdXRoZW50aWNhdGlvblwiOiB7XG4gKiAgICAuLi4sXG4gKiAgICBcIm9wdGlvbnNcIjogey4uLn1cbiAqICB9LFxuICogIFwib3B0aW9uc1wiOiB7Li4ufVxuICogfTtcbiAqIHZhciBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24oY29uZmlnKTtcbiAqIGBgYFxuICpcbiAqIE9ubHkgb25lIHJlcXVlc3QgYXQgYSB0aW1lIG1heSBiZSBleGVjdXRlZCBvbiBhIGNvbm5lY3Rpb24uIE9uY2UgYSBbW1JlcXVlc3RdXVxuICogaGFzIGJlZW4gaW5pdGlhdGVkICh3aXRoIFtbQ29ubmVjdGlvbi5jYWxsUHJvY2VkdXJlXV0sIFtbQ29ubmVjdGlvbi5leGVjU3FsXV0sXG4gKiBvciBbW0Nvbm5lY3Rpb24uZXhlY1NxbEJhdGNoXV0pLCBhbm90aGVyIHNob3VsZCBub3QgYmUgaW5pdGlhdGVkIHVudGlsIHRoZVxuICogW1tSZXF1ZXN0XV0ncyBjb21wbGV0aW9uIGNhbGxiYWNrIGlzIGNhbGxlZC5cbiAqL1xuY2xhc3MgQ29ubmVjdGlvbiBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBmZWRBdXRoUmVxdWlyZWQ6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBjb25maWc6IEludGVybmFsQ29ubmVjdGlvbkNvbmZpZztcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHNlY3VyZUNvbnRleHRPcHRpb25zOiBTZWN1cmVDb250ZXh0T3B0aW9ucztcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIGluVHJhbnNhY3Rpb246IGJvb2xlYW47XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSB0cmFuc2FjdGlvbkRlc2NyaXB0b3JzOiBCdWZmZXJbXTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHRyYW5zYWN0aW9uRGVwdGg6IG51bWJlcjtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIGlzU3FsQmF0Y2g6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBjdXJUcmFuc2llbnRSZXRyeUNvdW50OiBudW1iZXI7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSB0cmFuc2llbnRFcnJvckxvb2t1cDogVHJhbnNpZW50RXJyb3JMb29rdXA7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBjbG9zZWQ6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBsb2dpbkVycm9yOiB1bmRlZmluZWQgfCBBZ2dyZWdhdGVFcnJvciB8IENvbm5lY3Rpb25FcnJvcjtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIGRlYnVnOiBEZWJ1ZztcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIG50bG1wYWNrZXQ6IHVuZGVmaW5lZCB8IGFueTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIG50bG1wYWNrZXRCdWZmZXI6IHVuZGVmaW5lZCB8IEJ1ZmZlcjtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRlY2xhcmUgU1RBVEU6IHtcbiAgICBJTklUSUFMSVpFRDogU3RhdGU7XG4gICAgQ09OTkVDVElORzogU3RhdGU7XG4gICAgU0VOVF9QUkVMT0dJTjogU3RhdGU7XG4gICAgUkVST1VUSU5HOiBTdGF0ZTtcbiAgICBUUkFOU0lFTlRfRkFJTFVSRV9SRVRSWTogU3RhdGU7XG4gICAgU0VOVF9UTFNTU0xORUdPVElBVElPTjogU3RhdGU7XG4gICAgU0VOVF9MT0dJTjdfV0lUSF9TVEFOREFSRF9MT0dJTjogU3RhdGU7XG4gICAgU0VOVF9MT0dJTjdfV0lUSF9OVExNOiBTdGF0ZTtcbiAgICBTRU5UX0xPR0lON19XSVRIX0ZFREFVVEg6IFN0YXRlO1xuICAgIExPR0dFRF9JTl9TRU5ESU5HX0lOSVRJQUxfU1FMOiBTdGF0ZTtcbiAgICBMT0dHRURfSU46IFN0YXRlO1xuICAgIFNFTlRfQ0xJRU5UX1JFUVVFU1Q6IFN0YXRlO1xuICAgIFNFTlRfQVRURU5USU9OOiBTdGF0ZTtcbiAgICBGSU5BTDogU3RhdGU7XG4gIH07XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHJvdXRpbmdEYXRhOiB1bmRlZmluZWQgfCBSb3V0aW5nRGF0YTtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRlY2xhcmUgbWVzc2FnZUlvOiBNZXNzYWdlSU87XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBzdGF0ZTogU3RhdGU7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSByZXNldENvbm5lY3Rpb25Pbk5leHRSZXF1ZXN0OiB1bmRlZmluZWQgfCBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSByZXF1ZXN0OiB1bmRlZmluZWQgfCBSZXF1ZXN0IHwgQnVsa0xvYWQ7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBwcm9jUmV0dXJuU3RhdHVzVmFsdWU6IHVuZGVmaW5lZCB8IGFueTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHNvY2tldDogdW5kZWZpbmVkIHwgbmV0LlNvY2tldDtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIG1lc3NhZ2VCdWZmZXI6IEJ1ZmZlcjtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRlY2xhcmUgY29ubmVjdFRpbWVyOiB1bmRlZmluZWQgfCBOb2RlSlMuVGltZW91dDtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIGNhbmNlbFRpbWVyOiB1bmRlZmluZWQgfCBOb2RlSlMuVGltZW91dDtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBkZWNsYXJlIHJlcXVlc3RUaW1lcjogdW5kZWZpbmVkIHwgTm9kZUpTLlRpbWVvdXQ7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSByZXRyeVRpbWVyOiB1bmRlZmluZWQgfCBOb2RlSlMuVGltZW91dDtcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9jYW5jZWxBZnRlclJlcXVlc3RTZW50OiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZGVjbGFyZSBkYXRhYmFzZUNvbGxhdGlvbjogQ29sbGF0aW9uIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBOb3RlOiBiZSBhd2FyZSBvZiB0aGUgZGlmZmVyZW50IG9wdGlvbnMgZmllbGQ6XG4gICAqIDEuIGNvbmZpZy5hdXRoZW50aWNhdGlvbi5vcHRpb25zXG4gICAqIDIuIGNvbmZpZy5vcHRpb25zXG4gICAqXG4gICAqIGBgYGpzXG4gICAqIGNvbnN0IHsgQ29ubmVjdGlvbiB9ID0gcmVxdWlyZSgndGVkaW91cycpO1xuICAgKlxuICAgKiBjb25zdCBjb25maWcgPSB7XG4gICAqICBcImF1dGhlbnRpY2F0aW9uXCI6IHtcbiAgICogICAgLi4uLFxuICAgKiAgICBcIm9wdGlvbnNcIjogey4uLn1cbiAgICogIH0sXG4gICAqICBcIm9wdGlvbnNcIjogey4uLn1cbiAgICogfTtcbiAgICpcbiAgICogY29uc3QgY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKGNvbmZpZyk7XG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IENvbm5lY3Rpb25Db25maWd1cmF0aW9uKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICh0eXBlb2YgY29uZmlnICE9PSAnb2JqZWN0JyB8fCBjb25maWcgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZ1wiIGFyZ3VtZW50IGlzIHJlcXVpcmVkIGFuZCBtdXN0IGJlIG9mIHR5cGUgT2JqZWN0LicpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY29uZmlnLnNlcnZlciAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5zZXJ2ZXJcIiBwcm9wZXJ0eSBpcyByZXF1aXJlZCBhbmQgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICB9XG5cbiAgICB0aGlzLmZlZEF1dGhSZXF1aXJlZCA9IGZhbHNlO1xuXG4gICAgbGV0IGF1dGhlbnRpY2F0aW9uOiBDb25uZWN0aW9uQXV0aGVudGljYXRpb247XG4gICAgaWYgKGNvbmZpZy5hdXRoZW50aWNhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGNvbmZpZy5hdXRoZW50aWNhdGlvbiAhPT0gJ29iamVjdCcgfHwgY29uZmlnLmF1dGhlbnRpY2F0aW9uID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5hdXRoZW50aWNhdGlvblwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBPYmplY3QuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHR5cGUgPSBjb25maWcuYXV0aGVudGljYXRpb24udHlwZTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucyA9PT0gdW5kZWZpbmVkID8ge30gOiBjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucztcblxuICAgICAgaWYgKHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcuYXV0aGVudGljYXRpb24udHlwZVwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlICE9PSAnZGVmYXVsdCcgJiYgdHlwZSAhPT0gJ250bG0nICYmIHR5cGUgIT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LXBhc3N3b3JkJyAmJiB0eXBlICE9PSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1hY2Nlc3MtdG9rZW4nICYmIHR5cGUgIT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS12bScgJiYgdHlwZSAhPT0gJ2F6dXJlLWFjdGl2ZS1kaXJlY3RvcnktbXNpLWFwcC1zZXJ2aWNlJyAmJiB0eXBlICE9PSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1zZXJ2aWNlLXByaW5jaXBhbC1zZWNyZXQnICYmIHR5cGUgIT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LWRlZmF1bHQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcInR5cGVcIiBwcm9wZXJ0eSBtdXN0IG9uZSBvZiBcImRlZmF1bHRcIiwgXCJudGxtXCIsIFwiYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1wYXNzd29yZFwiLCBcImF6dXJlLWFjdGl2ZS1kaXJlY3RvcnktYWNjZXNzLXRva2VuXCIsIFwiYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1kZWZhdWx0XCIsIFwiYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktdm1cIiBvciBcImF6dXJlLWFjdGl2ZS1kaXJlY3RvcnktbXNpLWFwcC1zZXJ2aWNlXCIgb3IgXCJhenVyZS1hY3RpdmUtZGlyZWN0b3J5LXNlcnZpY2UtcHJpbmNpcGFsLXNlY3JldFwiLicpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnIHx8IG9wdGlvbnMgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLmF1dGhlbnRpY2F0aW9uLm9wdGlvbnNcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgb2JqZWN0LicpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PT0gJ250bG0nKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5kb21haW4gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLmF1dGhlbnRpY2F0aW9uLm9wdGlvbnMuZG9tYWluXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zLnVzZXJOYW1lICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9wdGlvbnMudXNlck5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLmF1dGhlbnRpY2F0aW9uLm9wdGlvbnMudXNlck5hbWVcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMucGFzc3dvcmQgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0aW9ucy5wYXNzd29yZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucy5wYXNzd29yZFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBhdXRoZW50aWNhdGlvbiA9IHtcbiAgICAgICAgICB0eXBlOiAnbnRsbScsXG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgdXNlck5hbWU6IG9wdGlvbnMudXNlck5hbWUsXG4gICAgICAgICAgICBwYXNzd29yZDogb3B0aW9ucy5wYXNzd29yZCxcbiAgICAgICAgICAgIGRvbWFpbjogb3B0aW9ucy5kb21haW4gJiYgb3B0aW9ucy5kb21haW4udG9VcHBlckNhc2UoKVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2F6dXJlLWFjdGl2ZS1kaXJlY3RvcnktcGFzc3dvcmQnKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jbGllbnRJZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucy5jbGllbnRJZFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy51c2VyTmFtZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLnVzZXJOYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5hdXRoZW50aWNhdGlvbi5vcHRpb25zLnVzZXJOYW1lXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zLnBhc3N3b3JkICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9wdGlvbnMucGFzc3dvcmQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLmF1dGhlbnRpY2F0aW9uLm9wdGlvbnMucGFzc3dvcmRcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMudGVuYW50SWQgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0aW9ucy50ZW5hbnRJZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucy50ZW5hbnRJZFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBhdXRoZW50aWNhdGlvbiA9IHtcbiAgICAgICAgICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1wYXNzd29yZCcsXG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgdXNlck5hbWU6IG9wdGlvbnMudXNlck5hbWUsXG4gICAgICAgICAgICBwYXNzd29yZDogb3B0aW9ucy5wYXNzd29yZCxcbiAgICAgICAgICAgIHRlbmFudElkOiBvcHRpb25zLnRlbmFudElkLFxuICAgICAgICAgICAgY2xpZW50SWQ6IG9wdGlvbnMuY2xpZW50SWRcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LWFjY2Vzcy10b2tlbicpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnRva2VuICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5hdXRoZW50aWNhdGlvbi5vcHRpb25zLnRva2VuXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF1dGhlbnRpY2F0aW9uID0ge1xuICAgICAgICAgIHR5cGU6ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgdG9rZW46IG9wdGlvbnMudG9rZW5cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS12bScpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuY2xpZW50SWQgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0aW9ucy5jbGllbnRJZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucy5jbGllbnRJZFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBhdXRoZW50aWNhdGlvbiA9IHtcbiAgICAgICAgICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktdm0nLFxuICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNsaWVudElkOiBvcHRpb25zLmNsaWVudElkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1kZWZhdWx0Jykge1xuICAgICAgICBpZiAob3B0aW9ucy5jbGllbnRJZCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLmNsaWVudElkICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5hdXRoZW50aWNhdGlvbi5vcHRpb25zLmNsaWVudElkXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuICAgICAgICBhdXRoZW50aWNhdGlvbiA9IHtcbiAgICAgICAgICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1kZWZhdWx0JyxcbiAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICBjbGllbnRJZDogb3B0aW9ucy5jbGllbnRJZFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2F6dXJlLWFjdGl2ZS1kaXJlY3RvcnktbXNpLWFwcC1zZXJ2aWNlJykge1xuICAgICAgICBpZiAob3B0aW9ucy5jbGllbnRJZCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLmNsaWVudElkICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5hdXRoZW50aWNhdGlvbi5vcHRpb25zLmNsaWVudElkXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF1dGhlbnRpY2F0aW9uID0ge1xuICAgICAgICAgIHR5cGU6ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS1hcHAtc2VydmljZScsXG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgY2xpZW50SWQ6IG9wdGlvbnMuY2xpZW50SWRcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LXNlcnZpY2UtcHJpbmNpcGFsLXNlY3JldCcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmNsaWVudElkICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5hdXRoZW50aWNhdGlvbi5vcHRpb25zLmNsaWVudElkXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jbGllbnRTZWNyZXQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLmF1dGhlbnRpY2F0aW9uLm9wdGlvbnMuY2xpZW50U2VjcmV0XCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50ZW5hbnRJZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucy50ZW5hbnRJZFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBhdXRoZW50aWNhdGlvbiA9IHtcbiAgICAgICAgICB0eXBlOiAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1zZXJ2aWNlLXByaW5jaXBhbC1zZWNyZXQnLFxuICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNsaWVudElkOiBvcHRpb25zLmNsaWVudElkLFxuICAgICAgICAgICAgY2xpZW50U2VjcmV0OiBvcHRpb25zLmNsaWVudFNlY3JldCxcbiAgICAgICAgICAgIHRlbmFudElkOiBvcHRpb25zLnRlbmFudElkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKG9wdGlvbnMudXNlck5hbWUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb3B0aW9ucy51c2VyTmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcuYXV0aGVudGljYXRpb24ub3B0aW9ucy51c2VyTmFtZVwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5wYXNzd29yZCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zLnBhc3N3b3JkICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5hdXRoZW50aWNhdGlvbi5vcHRpb25zLnBhc3N3b3JkXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF1dGhlbnRpY2F0aW9uID0ge1xuICAgICAgICAgIHR5cGU6ICdkZWZhdWx0JyxcbiAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICB1c2VyTmFtZTogb3B0aW9ucy51c2VyTmFtZSxcbiAgICAgICAgICAgIHBhc3N3b3JkOiBvcHRpb25zLnBhc3N3b3JkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhdXRoZW50aWNhdGlvbiA9IHtcbiAgICAgICAgdHlwZTogJ2RlZmF1bHQnLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgdXNlck5hbWU6IHVuZGVmaW5lZCxcbiAgICAgICAgICBwYXNzd29yZDogdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5jb25maWcgPSB7XG4gICAgICBzZXJ2ZXI6IGNvbmZpZy5zZXJ2ZXIsXG4gICAgICBhdXRoZW50aWNhdGlvbjogYXV0aGVudGljYXRpb24sXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGFib3J0VHJhbnNhY3Rpb25PbkVycm9yOiBmYWxzZSxcbiAgICAgICAgYXBwTmFtZTogdW5kZWZpbmVkLFxuICAgICAgICBjYW1lbENhc2VDb2x1bW5zOiBmYWxzZSxcbiAgICAgICAgY2FuY2VsVGltZW91dDogREVGQVVMVF9DQU5DRUxfVElNRU9VVCxcbiAgICAgICAgY29sdW1uRW5jcnlwdGlvbktleUNhY2hlVFRMOiAyICogNjAgKiA2MCAqIDEwMDAsICAvLyBVbml0czogbWlsbGlzZWNvbmRzXG4gICAgICAgIGNvbHVtbkVuY3J5cHRpb25TZXR0aW5nOiBmYWxzZSxcbiAgICAgICAgY29sdW1uTmFtZVJlcGxhY2VyOiB1bmRlZmluZWQsXG4gICAgICAgIGNvbm5lY3Rpb25SZXRyeUludGVydmFsOiBERUZBVUxUX0NPTk5FQ1RfUkVUUllfSU5URVJWQUwsXG4gICAgICAgIGNvbm5lY3RUaW1lb3V0OiBERUZBVUxUX0NPTk5FQ1RfVElNRU9VVCxcbiAgICAgICAgY29ubmVjdG9yOiB1bmRlZmluZWQsXG4gICAgICAgIGNvbm5lY3Rpb25Jc29sYXRpb25MZXZlbDogSVNPTEFUSU9OX0xFVkVMLlJFQURfQ09NTUlUVEVELFxuICAgICAgICBjcnlwdG9DcmVkZW50aWFsc0RldGFpbHM6IHt9LFxuICAgICAgICBkYXRhYmFzZTogdW5kZWZpbmVkLFxuICAgICAgICBkYXRlZmlyc3Q6IERFRkFVTFRfREFURUZJUlNULFxuICAgICAgICBkYXRlRm9ybWF0OiBERUZBVUxUX0RBVEVGT1JNQVQsXG4gICAgICAgIGRlYnVnOiB7XG4gICAgICAgICAgZGF0YTogZmFsc2UsXG4gICAgICAgICAgcGFja2V0OiBmYWxzZSxcbiAgICAgICAgICBwYXlsb2FkOiBmYWxzZSxcbiAgICAgICAgICB0b2tlbjogZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgZW5hYmxlQW5zaU51bGw6IHRydWUsXG4gICAgICAgIGVuYWJsZUFuc2lOdWxsRGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgZW5hYmxlQW5zaVBhZGRpbmc6IHRydWUsXG4gICAgICAgIGVuYWJsZUFuc2lXYXJuaW5nczogdHJ1ZSxcbiAgICAgICAgZW5hYmxlQXJpdGhBYm9ydDogdHJ1ZSxcbiAgICAgICAgZW5hYmxlQ29uY2F0TnVsbFlpZWxkc051bGw6IHRydWUsXG4gICAgICAgIGVuYWJsZUN1cnNvckNsb3NlT25Db21taXQ6IG51bGwsXG4gICAgICAgIGVuYWJsZUltcGxpY2l0VHJhbnNhY3Rpb25zOiBmYWxzZSxcbiAgICAgICAgZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQ6IGZhbHNlLFxuICAgICAgICBlbmFibGVRdW90ZWRJZGVudGlmaWVyOiB0cnVlLFxuICAgICAgICBlbmNyeXB0OiB0cnVlLFxuICAgICAgICBmYWxsYmFja1RvRGVmYXVsdERiOiBmYWxzZSxcbiAgICAgICAgZW5jcnlwdGlvbktleVN0b3JlUHJvdmlkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgIGluc3RhbmNlTmFtZTogdW5kZWZpbmVkLFxuICAgICAgICBpc29sYXRpb25MZXZlbDogSVNPTEFUSU9OX0xFVkVMLlJFQURfQ09NTUlUVEVELFxuICAgICAgICBsYW5ndWFnZTogREVGQVVMVF9MQU5HVUFHRSxcbiAgICAgICAgbG9jYWxBZGRyZXNzOiB1bmRlZmluZWQsXG4gICAgICAgIG1heFJldHJpZXNPblRyYW5zaWVudEVycm9yczogMyxcbiAgICAgICAgbXVsdGlTdWJuZXRGYWlsb3ZlcjogZmFsc2UsXG4gICAgICAgIHBhY2tldFNpemU6IERFRkFVTFRfUEFDS0VUX1NJWkUsXG4gICAgICAgIHBvcnQ6IERFRkFVTFRfUE9SVCxcbiAgICAgICAgcmVhZE9ubHlJbnRlbnQ6IGZhbHNlLFxuICAgICAgICByZXF1ZXN0VGltZW91dDogREVGQVVMVF9DTElFTlRfUkVRVUVTVF9USU1FT1VULFxuICAgICAgICByb3dDb2xsZWN0aW9uT25Eb25lOiBmYWxzZSxcbiAgICAgICAgcm93Q29sbGVjdGlvbk9uUmVxdWVzdENvbXBsZXRpb246IGZhbHNlLFxuICAgICAgICBzZXJ2ZXJOYW1lOiB1bmRlZmluZWQsXG4gICAgICAgIHNlcnZlclN1cHBvcnRzQ29sdW1uRW5jcnlwdGlvbjogZmFsc2UsXG4gICAgICAgIHRkc1ZlcnNpb246IERFRkFVTFRfVERTX1ZFUlNJT04sXG4gICAgICAgIHRleHRzaXplOiBERUZBVUxUX1RFWFRTSVpFLFxuICAgICAgICB0cnVzdGVkU2VydmVyTmFtZUFFOiB1bmRlZmluZWQsXG4gICAgICAgIHRydXN0U2VydmVyQ2VydGlmaWNhdGU6IGZhbHNlLFxuICAgICAgICB1c2VDb2x1bW5OYW1lczogZmFsc2UsXG4gICAgICAgIHVzZVVUQzogdHJ1ZSxcbiAgICAgICAgd29ya3N0YXRpb25JZDogdW5kZWZpbmVkLFxuICAgICAgICBsb3dlckNhc2VHdWlkczogZmFsc2VcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKGNvbmZpZy5vcHRpb25zKSB7XG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMucG9ydCAmJiBjb25maWcub3B0aW9ucy5pbnN0YW5jZU5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb3J0IGFuZCBpbnN0YW5jZU5hbWUgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSwgYnV0ICcgKyBjb25maWcub3B0aW9ucy5wb3J0ICsgJyBhbmQgJyArIGNvbmZpZy5vcHRpb25zLmluc3RhbmNlTmFtZSArICcgcHJvdmlkZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmFib3J0VHJhbnNhY3Rpb25PbkVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5hYm9ydFRyYW5zYWN0aW9uT25FcnJvciAhPT0gJ2Jvb2xlYW4nICYmIGNvbmZpZy5vcHRpb25zLmFib3J0VHJhbnNhY3Rpb25PbkVycm9yICE9PSBudWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuYWJvcnRUcmFuc2FjdGlvbk9uRXJyb3JcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nIG9yIG51bGwuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmFib3J0VHJhbnNhY3Rpb25PbkVycm9yID0gY29uZmlnLm9wdGlvbnMuYWJvcnRUcmFuc2FjdGlvbk9uRXJyb3I7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5hcHBOYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5hcHBOYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmFwcE5hbWVcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5hcHBOYW1lID0gY29uZmlnLm9wdGlvbnMuYXBwTmFtZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmNhbWVsQ2FzZUNvbHVtbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmNhbWVsQ2FzZUNvbHVtbnMgIT09ICdib29sZWFuJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmNhbWVsQ2FzZUNvbHVtbnNcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMuY2FtZWxDYXNlQ29sdW1ucyA9IGNvbmZpZy5vcHRpb25zLmNhbWVsQ2FzZUNvbHVtbnM7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5jYW5jZWxUaW1lb3V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5jYW5jZWxUaW1lb3V0ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmNhbmNlbFRpbWVvdXRcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgbnVtYmVyLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5jYW5jZWxUaW1lb3V0ID0gY29uZmlnLm9wdGlvbnMuY2FuY2VsVGltZW91dDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmNvbHVtbk5hbWVSZXBsYWNlcikge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmNvbHVtbk5hbWVSZXBsYWNlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmNhbmNlbFRpbWVvdXRcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgZnVuY3Rpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmNvbHVtbk5hbWVSZXBsYWNlciA9IGNvbmZpZy5vcHRpb25zLmNvbHVtbk5hbWVSZXBsYWNlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmNvbm5lY3Rpb25Jc29sYXRpb25MZXZlbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGFzc2VydFZhbGlkSXNvbGF0aW9uTGV2ZWwoY29uZmlnLm9wdGlvbnMuY29ubmVjdGlvbklzb2xhdGlvbkxldmVsLCAnY29uZmlnLm9wdGlvbnMuY29ubmVjdGlvbklzb2xhdGlvbkxldmVsJyk7XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5jb25uZWN0aW9uSXNvbGF0aW9uTGV2ZWwgPSBjb25maWcub3B0aW9ucy5jb25uZWN0aW9uSXNvbGF0aW9uTGV2ZWw7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5jb25uZWN0VGltZW91dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMuY29ubmVjdFRpbWVvdXQgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuY29ubmVjdFRpbWVvdXRcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgbnVtYmVyLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5jb25uZWN0VGltZW91dCA9IGNvbmZpZy5vcHRpb25zLmNvbm5lY3RUaW1lb3V0O1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMuY29ubmVjdG9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5jb25uZWN0b3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5jb25uZWN0b3JcIiBwcm9wZXJ0eSBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmNvbm5lY3RvciA9IGNvbmZpZy5vcHRpb25zLmNvbm5lY3RvcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmNyeXB0b0NyZWRlbnRpYWxzRGV0YWlscyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMuY3J5cHRvQ3JlZGVudGlhbHNEZXRhaWxzICE9PSAnb2JqZWN0JyB8fCBjb25maWcub3B0aW9ucy5jcnlwdG9DcmVkZW50aWFsc0RldGFpbHMgPT09IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5jcnlwdG9DcmVkZW50aWFsc0RldGFpbHNcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgT2JqZWN0LicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5jcnlwdG9DcmVkZW50aWFsc0RldGFpbHMgPSBjb25maWcub3B0aW9ucy5jcnlwdG9DcmVkZW50aWFsc0RldGFpbHM7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5kYXRhYmFzZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMuZGF0YWJhc2UgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuZGF0YWJhc2VcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5kYXRhYmFzZSA9IGNvbmZpZy5vcHRpb25zLmRhdGFiYXNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZGF0ZWZpcnN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5kYXRlZmlyc3QgIT09ICdudW1iZXInICYmIGNvbmZpZy5vcHRpb25zLmRhdGVmaXJzdCAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmRhdGVmaXJzdFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBudW1iZXIuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZGF0ZWZpcnN0ICE9PSBudWxsICYmIChjb25maWcub3B0aW9ucy5kYXRlZmlyc3QgPCAxIHx8IGNvbmZpZy5vcHRpb25zLmRhdGVmaXJzdCA+IDcpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmRhdGVmaXJzdFwiIHByb3BlcnR5IG11c3QgYmUgPj0gMSBhbmQgPD0gNycpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5kYXRlZmlyc3QgPSBjb25maWcub3B0aW9ucy5kYXRlZmlyc3Q7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5kYXRlRm9ybWF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5kYXRlRm9ybWF0ICE9PSAnc3RyaW5nJyAmJiBjb25maWcub3B0aW9ucy5kYXRlRm9ybWF0ICE9PSBudWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuZGF0ZUZvcm1hdFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcgb3IgbnVsbC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMuZGF0ZUZvcm1hdCA9IGNvbmZpZy5vcHRpb25zLmRhdGVGb3JtYXQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5kZWJ1Zykge1xuICAgICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZGVidWcuZGF0YSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5kZWJ1Zy5kYXRhICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmRlYnVnLmRhdGFcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbi4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmRlYnVnLmRhdGEgPSBjb25maWcub3B0aW9ucy5kZWJ1Zy5kYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmRlYnVnLnBhY2tldCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5kZWJ1Zy5wYWNrZXQgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuZGVidWcucGFja2V0XCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIGJvb2xlYW4uJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5kZWJ1Zy5wYWNrZXQgPSBjb25maWcub3B0aW9ucy5kZWJ1Zy5wYWNrZXQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZGVidWcucGF5bG9hZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5kZWJ1Zy5wYXlsb2FkICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmRlYnVnLnBheWxvYWRcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbi4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmRlYnVnLnBheWxvYWQgPSBjb25maWcub3B0aW9ucy5kZWJ1Zy5wYXlsb2FkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmRlYnVnLnRva2VuICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmRlYnVnLnRva2VuICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmRlYnVnLnRva2VuXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIGJvb2xlYW4uJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5kZWJ1Zy50b2tlbiA9IGNvbmZpZy5vcHRpb25zLmRlYnVnLnRva2VuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5lbmFibGVBbnNpTnVsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGwgIT09ICdib29sZWFuJyAmJiBjb25maWcub3B0aW9ucy5lbmFibGVBbnNpTnVsbCAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lOdWxsXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIGJvb2xlYW4gb3IgbnVsbC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGwgPSBjb25maWcub3B0aW9ucy5lbmFibGVBbnNpTnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lOdWxsRGVmYXVsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGxEZWZhdWx0ICE9PSAnYm9vbGVhbicgJiYgY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGxEZWZhdWx0ICE9PSBudWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGxEZWZhdWx0XCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIGJvb2xlYW4gb3IgbnVsbC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGxEZWZhdWx0ID0gY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGxEZWZhdWx0O1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaVBhZGRpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lQYWRkaW5nICE9PSAnYm9vbGVhbicgJiYgY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaVBhZGRpbmcgIT09IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5lbmFibGVBbnNpUGFkZGluZ1wiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuIG9yIG51bGwuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lQYWRkaW5nID0gY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaVBhZGRpbmc7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5lbmFibGVBbnNpV2FybmluZ3MgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lXYXJuaW5ncyAhPT0gJ2Jvb2xlYW4nICYmIGNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lXYXJuaW5ncyAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lXYXJuaW5nc1wiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuIG9yIG51bGwuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lXYXJuaW5ncyA9IGNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lXYXJuaW5ncztcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmVuYWJsZUFyaXRoQWJvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmVuYWJsZUFyaXRoQWJvcnQgIT09ICdib29sZWFuJyAmJiBjb25maWcub3B0aW9ucy5lbmFibGVBcml0aEFib3J0ICE9PSBudWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuZW5hYmxlQXJpdGhBYm9ydFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuIG9yIG51bGwuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUFyaXRoQWJvcnQgPSBjb25maWcub3B0aW9ucy5lbmFibGVBcml0aEFib3J0O1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZW5hYmxlQ29uY2F0TnVsbFlpZWxkc051bGwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmVuYWJsZUNvbmNhdE51bGxZaWVsZHNOdWxsICE9PSAnYm9vbGVhbicgJiYgY29uZmlnLm9wdGlvbnMuZW5hYmxlQ29uY2F0TnVsbFlpZWxkc051bGwgIT09IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5lbmFibGVDb25jYXROdWxsWWllbGRzTnVsbFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuIG9yIG51bGwuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUNvbmNhdE51bGxZaWVsZHNOdWxsID0gY29uZmlnLm9wdGlvbnMuZW5hYmxlQ29uY2F0TnVsbFlpZWxkc051bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5lbmFibGVDdXJzb3JDbG9zZU9uQ29tbWl0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5lbmFibGVDdXJzb3JDbG9zZU9uQ29tbWl0ICE9PSAnYm9vbGVhbicgJiYgY29uZmlnLm9wdGlvbnMuZW5hYmxlQ3Vyc29yQ2xvc2VPbkNvbW1pdCAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmVuYWJsZUN1cnNvckNsb3NlT25Db21taXRcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbiBvciBudWxsLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVDdXJzb3JDbG9zZU9uQ29tbWl0ID0gY29uZmlnLm9wdGlvbnMuZW5hYmxlQ3Vyc29yQ2xvc2VPbkNvbW1pdDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmVuYWJsZUltcGxpY2l0VHJhbnNhY3Rpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5lbmFibGVJbXBsaWNpdFRyYW5zYWN0aW9ucyAhPT0gJ2Jvb2xlYW4nICYmIGNvbmZpZy5vcHRpb25zLmVuYWJsZUltcGxpY2l0VHJhbnNhY3Rpb25zICE9PSBudWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuZW5hYmxlSW1wbGljaXRUcmFuc2FjdGlvbnNcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbiBvciBudWxsLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVJbXBsaWNpdFRyYW5zYWN0aW9ucyA9IGNvbmZpZy5vcHRpb25zLmVuYWJsZUltcGxpY2l0VHJhbnNhY3Rpb25zO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmVuYWJsZU51bWVyaWNSb3VuZGFib3J0ICE9PSAnYm9vbGVhbicgJiYgY29uZmlnLm9wdGlvbnMuZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQgIT09IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5lbmFibGVOdW1lcmljUm91bmRhYm9ydFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuIG9yIG51bGwuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZU51bWVyaWNSb3VuZGFib3J0ID0gY29uZmlnLm9wdGlvbnMuZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5lbmFibGVRdW90ZWRJZGVudGlmaWVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5lbmFibGVRdW90ZWRJZGVudGlmaWVyICE9PSAnYm9vbGVhbicgJiYgY29uZmlnLm9wdGlvbnMuZW5hYmxlUXVvdGVkSWRlbnRpZmllciAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmVuYWJsZVF1b3RlZElkZW50aWZpZXJcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbiBvciBudWxsLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVRdW90ZWRJZGVudGlmaWVyID0gY29uZmlnLm9wdGlvbnMuZW5hYmxlUXVvdGVkSWRlbnRpZmllcjtcbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5lbmNyeXB0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5lbmNyeXB0ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICBpZiAoY29uZmlnLm9wdGlvbnMuZW5jcnlwdCAhPT0gJ3N0cmljdCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImVuY3J5cHRcIiBwcm9wZXJ0eSBtdXN0IGJlIHNldCB0byBcInN0cmljdFwiLCBvciBvZiB0eXBlIGJvb2xlYW4uJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5lbmNyeXB0ID0gY29uZmlnLm9wdGlvbnMuZW5jcnlwdDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmZhbGxiYWNrVG9EZWZhdWx0RGIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmZhbGxiYWNrVG9EZWZhdWx0RGIgIT09ICdib29sZWFuJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmZhbGxiYWNrVG9EZWZhdWx0RGJcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMuZmFsbGJhY2tUb0RlZmF1bHREYiA9IGNvbmZpZy5vcHRpb25zLmZhbGxiYWNrVG9EZWZhdWx0RGI7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5pbnN0YW5jZU5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmluc3RhbmNlTmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5pbnN0YW5jZU5hbWVcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5pbnN0YW5jZU5hbWUgPSBjb25maWcub3B0aW9ucy5pbnN0YW5jZU5hbWU7XG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMucG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmlzb2xhdGlvbkxldmVsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXNzZXJ0VmFsaWRJc29sYXRpb25MZXZlbChjb25maWcub3B0aW9ucy5pc29sYXRpb25MZXZlbCwgJ2NvbmZpZy5vcHRpb25zLmlzb2xhdGlvbkxldmVsJyk7XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5pc29sYXRpb25MZXZlbCA9IGNvbmZpZy5vcHRpb25zLmlzb2xhdGlvbkxldmVsO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMubGFuZ3VhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLmxhbmd1YWdlICE9PSAnc3RyaW5nJyAmJiBjb25maWcub3B0aW9ucy5sYW5ndWFnZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmxhbmd1YWdlXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZyBvciBudWxsLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5sYW5ndWFnZSA9IGNvbmZpZy5vcHRpb25zLmxhbmd1YWdlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMubG9jYWxBZGRyZXNzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5sb2NhbEFkZHJlc3MgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMubG9jYWxBZGRyZXNzXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMubG9jYWxBZGRyZXNzID0gY29uZmlnLm9wdGlvbnMubG9jYWxBZGRyZXNzO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMubXVsdGlTdWJuZXRGYWlsb3ZlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMubXVsdGlTdWJuZXRGYWlsb3ZlciAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMubXVsdGlTdWJuZXRGYWlsb3ZlclwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5tdWx0aVN1Ym5ldEZhaWxvdmVyID0gY29uZmlnLm9wdGlvbnMubXVsdGlTdWJuZXRGYWlsb3ZlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLnBhY2tldFNpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLnBhY2tldFNpemUgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMucGFja2V0U2l6ZVwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBudW1iZXIuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLnBhY2tldFNpemUgPSBjb25maWcub3B0aW9ucy5wYWNrZXRTaXplO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMucG9ydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMucG9ydCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5wb3J0XCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIG51bWJlci4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb25maWcub3B0aW9ucy5wb3J0IDw9IDAgfHwgY29uZmlnLm9wdGlvbnMucG9ydCA+PSA2NTUzNikge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5wb3J0XCIgcHJvcGVydHkgbXVzdCBiZSA+IDAgYW5kIDwgNjU1MzYnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMucG9ydCA9IGNvbmZpZy5vcHRpb25zLnBvcnQ7XG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMuaW5zdGFuY2VOYW1lID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMucmVhZE9ubHlJbnRlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLnJlYWRPbmx5SW50ZW50ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5yZWFkT25seUludGVudFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5yZWFkT25seUludGVudCA9IGNvbmZpZy5vcHRpb25zLnJlYWRPbmx5SW50ZW50O1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMucmVxdWVzdFRpbWVvdXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLnJlcXVlc3RUaW1lb3V0ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLnJlcXVlc3RUaW1lb3V0XCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIG51bWJlci4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMucmVxdWVzdFRpbWVvdXQgPSBjb25maWcub3B0aW9ucy5yZXF1ZXN0VGltZW91dDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLm1heFJldHJpZXNPblRyYW5zaWVudEVycm9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMubWF4UmV0cmllc09uVHJhbnNpZW50RXJyb3JzICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLm1heFJldHJpZXNPblRyYW5zaWVudEVycm9yc1wiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBudW1iZXIuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLm9wdGlvbnMubWF4UmV0cmllc09uVHJhbnNpZW50RXJyb3JzIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLm1heFJldHJpZXNPblRyYW5zaWVudEVycm9yc1wiIHByb3BlcnR5IG11c3QgYmUgZXF1YWwgb3IgZ3JlYXRlciB0aGFuIDAuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLm1heFJldHJpZXNPblRyYW5zaWVudEVycm9ycyA9IGNvbmZpZy5vcHRpb25zLm1heFJldHJpZXNPblRyYW5zaWVudEVycm9ycztcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLmNvbm5lY3Rpb25SZXRyeUludGVydmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy5jb25uZWN0aW9uUmV0cnlJbnRlcnZhbCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy5jb25uZWN0aW9uUmV0cnlJbnRlcnZhbFwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBudW1iZXIuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLm9wdGlvbnMuY29ubmVjdGlvblJldHJ5SW50ZXJ2YWwgPD0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmNvbm5lY3Rpb25SZXRyeUludGVydmFsXCIgcHJvcGVydHkgbXVzdCBiZSBncmVhdGVyIHRoYW4gMC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMuY29ubmVjdGlvblJldHJ5SW50ZXJ2YWwgPSBjb25maWcub3B0aW9ucy5jb25uZWN0aW9uUmV0cnlJbnRlcnZhbDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PbkRvbmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PbkRvbmUgIT09ICdib29sZWFuJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PbkRvbmVcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMucm93Q29sbGVjdGlvbk9uRG9uZSA9IGNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PbkRvbmU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5yb3dDb2xsZWN0aW9uT25SZXF1ZXN0Q29tcGxldGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMucm93Q29sbGVjdGlvbk9uUmVxdWVzdENvbXBsZXRpb24gIT09ICdib29sZWFuJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PblJlcXVlc3RDb21wbGV0aW9uXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIGJvb2xlYW4uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLnJvd0NvbGxlY3Rpb25PblJlcXVlc3RDb21wbGV0aW9uID0gY29uZmlnLm9wdGlvbnMucm93Q29sbGVjdGlvbk9uUmVxdWVzdENvbXBsZXRpb247XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy50ZHNWZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy50ZHNWZXJzaW9uICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLnRkc1ZlcnNpb25cIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy50ZHNWZXJzaW9uID0gY29uZmlnLm9wdGlvbnMudGRzVmVyc2lvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLnRleHRzaXplICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy50ZXh0c2l6ZSAhPT0gJ251bWJlcicgJiYgY29uZmlnLm9wdGlvbnMudGV4dHNpemUgIT09IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy50ZXh0c2l6ZVwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBudW1iZXIgb3IgbnVsbC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb25maWcub3B0aW9ucy50ZXh0c2l6ZSA+IDIxNDc0ODM2NDcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy50ZXh0c2l6ZVwiIGNhblxcJ3QgYmUgZ3JlYXRlciB0aGFuIDIxNDc0ODM2NDcuJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoY29uZmlnLm9wdGlvbnMudGV4dHNpemUgPCAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLnRleHRzaXplXCIgY2FuXFwndCBiZSBzbWFsbGVyIHRoYW4gLTEuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLnRleHRzaXplID0gY29uZmlnLm9wdGlvbnMudGV4dHNpemUgfCAwO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMudHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMudHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMudHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZVwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBib29sZWFuLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy50cnVzdFNlcnZlckNlcnRpZmljYXRlID0gY29uZmlnLm9wdGlvbnMudHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLnNlcnZlck5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5vcHRpb25zLnNlcnZlck5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMuc2VydmVyTmFtZVwiIHByb3BlcnR5IG11c3QgYmUgb2YgdHlwZSBzdHJpbmcuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb25maWcub3B0aW9ucy5zZXJ2ZXJOYW1lID0gY29uZmlnLm9wdGlvbnMuc2VydmVyTmFtZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLnVzZUNvbHVtbk5hbWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25maWcub3B0aW9ucy51c2VDb2x1bW5OYW1lcyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiY29uZmlnLm9wdGlvbnMudXNlQ29sdW1uTmFtZXNcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMudXNlQ29sdW1uTmFtZXMgPSBjb25maWcub3B0aW9ucy51c2VDb2x1bW5OYW1lcztcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5vcHRpb25zLnVzZVVUQyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMudXNlVVRDICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy51c2VVVENcIiBwcm9wZXJ0eSBtdXN0IGJlIG9mIHR5cGUgYm9vbGVhbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMudXNlVVRDID0gY29uZmlnLm9wdGlvbnMudXNlVVRDO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm9wdGlvbnMud29ya3N0YXRpb25JZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMud29ya3N0YXRpb25JZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJjb25maWcub3B0aW9ucy53b3Jrc3RhdGlvbklkXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29uZmlnLm9wdGlvbnMud29ya3N0YXRpb25JZCA9IGNvbmZpZy5vcHRpb25zLndvcmtzdGF0aW9uSWQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcub3B0aW9ucy5sb3dlckNhc2VHdWlkcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm9wdGlvbnMubG93ZXJDYXNlR3VpZHMgIT09ICdib29sZWFuJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImNvbmZpZy5vcHRpb25zLmxvd2VyQ2FzZUd1aWRzXCIgcHJvcGVydHkgbXVzdCBiZSBvZiB0eXBlIGJvb2xlYW4uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNvbmZpZy5vcHRpb25zLmxvd2VyQ2FzZUd1aWRzID0gY29uZmlnLm9wdGlvbnMubG93ZXJDYXNlR3VpZHM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZWN1cmVDb250ZXh0T3B0aW9ucyA9IHRoaXMuY29uZmlnLm9wdGlvbnMuY3J5cHRvQ3JlZGVudGlhbHNEZXRhaWxzO1xuICAgIGlmICh0aGlzLnNlY3VyZUNvbnRleHRPcHRpb25zLnNlY3VyZU9wdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gSWYgdGhlIGNhbGxlciBoYXMgbm90IHNwZWNpZmllZCB0aGVpciBvd24gYHNlY3VyZU9wdGlvbnNgLFxuICAgICAgLy8gd2Ugc2V0IGBTU0xfT1BfRE9OVF9JTlNFUlRfRU1QVFlfRlJBR01FTlRTYCBoZXJlLlxuICAgICAgLy8gT2xkZXIgU1FMIFNlcnZlciBpbnN0YW5jZXMgcnVubmluZyBvbiBvbGRlciBXaW5kb3dzIHZlcnNpb25zIGhhdmVcbiAgICAgIC8vIHRyb3VibGUgd2l0aCB0aGUgQkVBU1Qgd29ya2Fyb3VuZCBpbiBPcGVuU1NMLlxuICAgICAgLy8gQXMgQkVBU1QgaXMgYSBicm93c2VyIHNwZWNpZmljIGV4cGxvaXQsIHdlIGNhbiBqdXN0IGRpc2FibGUgdGhpcyBvcHRpb24gaGVyZS5cbiAgICAgIHRoaXMuc2VjdXJlQ29udGV4dE9wdGlvbnMgPSBPYmplY3QuY3JlYXRlKHRoaXMuc2VjdXJlQ29udGV4dE9wdGlvbnMsIHtcbiAgICAgICAgc2VjdXJlT3B0aW9uczoge1xuICAgICAgICAgIHZhbHVlOiBjb25zdGFudHMuU1NMX09QX0RPTlRfSU5TRVJUX0VNUFRZX0ZSQUdNRU5UU1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmRlYnVnID0gdGhpcy5jcmVhdGVEZWJ1ZygpO1xuICAgIHRoaXMuaW5UcmFuc2FjdGlvbiA9IGZhbHNlO1xuICAgIHRoaXMudHJhbnNhY3Rpb25EZXNjcmlwdG9ycyA9IFtCdWZmZXIuZnJvbShbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF0pXTtcblxuICAgIC8vICdiZWdpblRyYW5zYWN0aW9uJywgJ2NvbW1pdFRyYW5zYWN0aW9uJyBhbmQgJ3JvbGxiYWNrVHJhbnNhY3Rpb24nXG4gICAgLy8gZXZlbnRzIGFyZSB1dGlsaXplZCB0byBtYWludGFpbiBpblRyYW5zYWN0aW9uIHByb3BlcnR5IHN0YXRlIHdoaWNoIGluXG4gICAgLy8gdHVybiBpcyB1c2VkIGluIG1hbmFnaW5nIHRyYW5zYWN0aW9ucy4gVGhlc2UgZXZlbnRzIGFyZSBvbmx5IGZpcmVkIGZvclxuICAgIC8vIFREUyB2ZXJzaW9uIDcuMiBhbmQgYmV5b25kLiBUaGUgcHJvcGVydGllcyBiZWxvdyBhcmUgdXNlZCB0byBlbXVsYXRlXG4gICAgLy8gZXF1aXZhbGVudCBiZWhhdmlvciBmb3IgVERTIHZlcnNpb25zIGJlZm9yZSA3LjIuXG4gICAgdGhpcy50cmFuc2FjdGlvbkRlcHRoID0gMDtcbiAgICB0aGlzLmlzU3FsQmF0Y2ggPSBmYWxzZTtcbiAgICB0aGlzLmNsb3NlZCA9IGZhbHNlO1xuICAgIHRoaXMubWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygwKTtcblxuICAgIHRoaXMuY3VyVHJhbnNpZW50UmV0cnlDb3VudCA9IDA7XG4gICAgdGhpcy50cmFuc2llbnRFcnJvckxvb2t1cCA9IG5ldyBUcmFuc2llbnRFcnJvckxvb2t1cCgpO1xuXG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuU1RBVEUuSU5JVElBTElaRUQ7XG5cbiAgICB0aGlzLl9jYW5jZWxBZnRlclJlcXVlc3RTZW50ID0gKCkgPT4ge1xuICAgICAgdGhpcy5tZXNzYWdlSW8uc2VuZE1lc3NhZ2UoVFlQRS5BVFRFTlRJT04pO1xuICAgICAgdGhpcy5jcmVhdGVDYW5jZWxUaW1lcigpO1xuICAgIH07XG4gIH1cblxuICBjb25uZWN0KGNvbm5lY3RMaXN0ZW5lcj86IChlcnI/OiBFcnJvcikgPT4gdm9pZCkge1xuICAgIGlmICh0aGlzLnN0YXRlICE9PSB0aGlzLlNUQVRFLklOSVRJQUxJWkVEKSB7XG4gICAgICB0aHJvdyBuZXcgQ29ubmVjdGlvbkVycm9yKCdgLmNvbm5lY3RgIGNhbiBub3QgYmUgY2FsbGVkIG9uIGEgQ29ubmVjdGlvbiBpbiBgJyArIHRoaXMuc3RhdGUubmFtZSArICdgIHN0YXRlLicpO1xuICAgIH1cblxuICAgIGlmIChjb25uZWN0TGlzdGVuZXIpIHtcbiAgICAgIGNvbnN0IG9uQ29ubmVjdCA9IChlcnI/OiBFcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgICBjb25uZWN0TGlzdGVuZXIoZXJyKTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG9uRXJyb3IgPSAoZXJyOiBFcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdjb25uZWN0Jywgb25Db25uZWN0KTtcbiAgICAgICAgY29ubmVjdExpc3RlbmVyKGVycik7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLm9uY2UoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpO1xuICAgICAgdGhpcy5vbmNlKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgIH1cblxuICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuQ09OTkVDVElORyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHNlcnZlciBoYXMgcmVwb3J0ZWQgdGhhdCB0aGUgY2hhcnNldCBoYXMgY2hhbmdlZC5cbiAgICovXG4gIG9uKGV2ZW50OiAnY2hhcnNldENoYW5nZScsIGxpc3RlbmVyOiAoY2hhcnNldDogc3RyaW5nKSA9PiB2b2lkKTogdGhpc1xuXG4gIC8qKlxuICAgKiBUaGUgYXR0ZW1wdCB0byBjb25uZWN0IGFuZCB2YWxpZGF0ZSBoYXMgY29tcGxldGVkLlxuICAgKi9cbiAgb24oXG4gICAgZXZlbnQ6ICdjb25uZWN0JyxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZXJyIElmIHN1Y2Nlc3NmdWxseSBjb25uZWN0ZWQsIHdpbGwgYmUgZmFsc2V5LiBJZiB0aGVyZSB3YXMgYVxuICAgICAqICAgcHJvYmxlbSAod2l0aCBlaXRoZXIgY29ubmVjdGluZyBvciB2YWxpZGF0aW9uKSwgd2lsbCBiZSBhbiBbW0Vycm9yXV0gb2JqZWN0LlxuICAgICAqL1xuICAgIGxpc3RlbmVyOiAoZXJyOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICApOiB0aGlzXG5cbiAgLyoqXG4gICAqIFRoZSBzZXJ2ZXIgaGFzIHJlcG9ydGVkIHRoYXQgdGhlIGFjdGl2ZSBkYXRhYmFzZSBoYXMgY2hhbmdlZC5cbiAgICogVGhpcyBtYXkgYmUgYXMgYSByZXN1bHQgb2YgYSBzdWNjZXNzZnVsIGxvZ2luLCBvciBhIGB1c2VgIHN0YXRlbWVudC5cbiAgICovXG4gIG9uKGV2ZW50OiAnZGF0YWJhc2VDaGFuZ2UnLCBsaXN0ZW5lcjogKGRhdGFiYXNlTmFtZTogc3RyaW5nKSA9PiB2b2lkKTogdGhpc1xuXG4gIC8qKlxuICAgKiBBIGRlYnVnIG1lc3NhZ2UgaXMgYXZhaWxhYmxlLiBJdCBtYXkgYmUgbG9nZ2VkIG9yIGlnbm9yZWQuXG4gICAqL1xuICBvbihldmVudDogJ2RlYnVnJywgbGlzdGVuZXI6IChtZXNzYWdlVGV4dDogc3RyaW5nKSA9PiB2b2lkKTogdGhpc1xuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBlcnJvciBvY2N1cnMuXG4gICAqL1xuICBvbihldmVudDogJ2Vycm9yJywgbGlzdGVuZXI6IChlcnI6IEVycm9yKSA9PiB2b2lkKTogdGhpc1xuXG4gIC8qKlxuICAgKiBUaGUgc2VydmVyIGhhcyBpc3N1ZWQgYW4gZXJyb3IgbWVzc2FnZS5cbiAgICovXG4gIG9uKGV2ZW50OiAnZXJyb3JNZXNzYWdlJywgbGlzdGVuZXI6IChtZXNzYWdlOiBpbXBvcnQoJy4vdG9rZW4vdG9rZW4nKS5FcnJvck1lc3NhZ2VUb2tlbikgPT4gdm9pZCk6IHRoaXNcblxuICAvKipcbiAgICogVGhlIGNvbm5lY3Rpb24gaGFzIGVuZGVkLlxuICAgKlxuICAgKiBUaGlzIG1heSBiZSBhcyBhIHJlc3VsdCBvZiB0aGUgY2xpZW50IGNhbGxpbmcgW1tjbG9zZV1dLCB0aGUgc2VydmVyXG4gICAqIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24sIG9yIGEgbmV0d29yayBlcnJvci5cbiAgICovXG4gIG9uKGV2ZW50OiAnZW5kJywgbGlzdGVuZXI6ICgpID0+IHZvaWQpOiB0aGlzXG5cbiAgLyoqXG4gICAqIFRoZSBzZXJ2ZXIgaGFzIGlzc3VlZCBhbiBpbmZvcm1hdGlvbiBtZXNzYWdlLlxuICAgKi9cbiAgb24oZXZlbnQ6ICdpbmZvTWVzc2FnZScsIGxpc3RlbmVyOiAobWVzc2FnZTogaW1wb3J0KCcuL3Rva2VuL3Rva2VuJykuSW5mb01lc3NhZ2VUb2tlbikgPT4gdm9pZCk6IHRoaXNcblxuICAvKipcbiAgICogVGhlIHNlcnZlciBoYXMgcmVwb3J0ZWQgdGhhdCB0aGUgbGFuZ3VhZ2UgaGFzIGNoYW5nZWQuXG4gICAqL1xuICBvbihldmVudDogJ2xhbmd1YWdlQ2hhbmdlJywgbGlzdGVuZXI6IChsYW5ndWFnZU5hbWU6IHN0cmluZykgPT4gdm9pZCk6IHRoaXNcblxuICAvKipcbiAgICogVGhlIGNvbm5lY3Rpb24gd2FzIHJlc2V0LlxuICAgKi9cbiAgb24oZXZlbnQ6ICdyZXNldENvbm5lY3Rpb24nLCBsaXN0ZW5lcjogKCkgPT4gdm9pZCk6IHRoaXNcblxuICAvKipcbiAgICogQSBzZWN1cmUgY29ubmVjdGlvbiBoYXMgYmVlbiBlc3RhYmxpc2hlZC5cbiAgICovXG4gIG9uKGV2ZW50OiAnc2VjdXJlJywgbGlzdGVuZXI6IChjbGVhcnRleHQ6IGltcG9ydCgndGxzJykuVExTU29ja2V0KSA9PiB2b2lkKTogdGhpc1xuXG4gIG9uKGV2ZW50OiBzdHJpbmcgfCBzeW1ib2wsIGxpc3RlbmVyOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQpIHtcbiAgICByZXR1cm4gc3VwZXIub24oZXZlbnQsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ2NoYXJzZXRDaGFuZ2UnLCBjaGFyc2V0OiBzdHJpbmcpOiBib29sZWFuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ2Nvbm5lY3QnLCBlcnJvcj86IEVycm9yKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdkYXRhYmFzZUNoYW5nZScsIGRhdGFiYXNlTmFtZTogc3RyaW5nKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdkZWJ1ZycsIG1lc3NhZ2VUZXh0OiBzdHJpbmcpOiBib29sZWFuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ2Vycm9yJywgZXJyb3I6IEVycm9yKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdlcnJvck1lc3NhZ2UnLCBtZXNzYWdlOiBpbXBvcnQoJy4vdG9rZW4vdG9rZW4nKS5FcnJvck1lc3NhZ2VUb2tlbik6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAnZW5kJyk6IGJvb2xlYW5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBlbWl0KGV2ZW50OiAnaW5mb01lc3NhZ2UnLCBtZXNzYWdlOiBpbXBvcnQoJy4vdG9rZW4vdG9rZW4nKS5JbmZvTWVzc2FnZVRva2VuKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdsYW5ndWFnZUNoYW5nZScsIGxhbmd1YWdlTmFtZTogc3RyaW5nKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdzZWN1cmUnLCBjbGVhcnRleHQ6IGltcG9ydCgndGxzJykuVExTU29ja2V0KTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdyZXJvdXRpbmcnKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdyZXNldENvbm5lY3Rpb24nKTogYm9vbGVhblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGVtaXQoZXZlbnQ6ICdyZXRyeScpOiBib29sZWFuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZW1pdChldmVudDogJ3JvbGxiYWNrVHJhbnNhY3Rpb24nKTogYm9vbGVhblxuXG4gIGVtaXQoZXZlbnQ6IHN0cmluZyB8IHN5bWJvbCwgLi4uYXJnczogYW55W10pIHtcbiAgICByZXR1cm4gc3VwZXIuZW1pdChldmVudCwgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBkYXRhYmFzZS5cbiAgICpcbiAgICogVGhlIFtbRXZlbnRfZW5kXV0gd2lsbCBiZSBlbWl0dGVkIG9uY2UgdGhlIGNvbm5lY3Rpb24gaGFzIGJlZW4gY2xvc2VkLlxuICAgKi9cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGluaXRpYWxpc2VDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IHNpZ25hbCA9IHRoaXMuY3JlYXRlQ29ubmVjdFRpbWVyKCk7XG5cbiAgICBpZiAodGhpcy5jb25maWcub3B0aW9ucy5wb3J0KSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0T25Qb3J0KHRoaXMuY29uZmlnLm9wdGlvbnMucG9ydCwgdGhpcy5jb25maWcub3B0aW9ucy5tdWx0aVN1Ym5ldEZhaWxvdmVyLCBzaWduYWwsIHRoaXMuY29uZmlnLm9wdGlvbnMuY29ubmVjdG9yKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGluc3RhbmNlTG9va3VwKHtcbiAgICAgICAgc2VydmVyOiB0aGlzLmNvbmZpZy5zZXJ2ZXIsXG4gICAgICAgIGluc3RhbmNlTmFtZTogdGhpcy5jb25maWcub3B0aW9ucy5pbnN0YW5jZU5hbWUhLFxuICAgICAgICB0aW1lb3V0OiB0aGlzLmNvbmZpZy5vcHRpb25zLmNvbm5lY3RUaW1lb3V0LFxuICAgICAgICBzaWduYWw6IHNpZ25hbFxuICAgICAgfSkudGhlbigocG9ydCkgPT4ge1xuICAgICAgICBwcm9jZXNzLm5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmNvbm5lY3RPblBvcnQocG9ydCwgdGhpcy5jb25maWcub3B0aW9ucy5tdWx0aVN1Ym5ldEZhaWxvdmVyLCBzaWduYWwsIHRoaXMuY29uZmlnLm9wdGlvbnMuY29ubmVjdG9yKTtcbiAgICAgICAgfSk7XG4gICAgICB9LCAoZXJyKSA9PiB7XG4gICAgICAgIHRoaXMuY2xlYXJDb25uZWN0VGltZXIoKTtcblxuICAgICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgICAvLyBJZ25vcmUgdGhlIEFib3J0RXJyb3IgZm9yIG5vdywgdGhpcyBpcyBzdGlsbCBoYW5kbGVkIGJ5IHRoZSBjb25uZWN0VGltZXIgZmlyaW5nXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdjb25uZWN0JywgbmV3IENvbm5lY3Rpb25FcnJvcihlcnIubWVzc2FnZSwgJ0VJTlNUTE9PS1VQJykpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2xlYW51cENvbm5lY3Rpb24oY2xlYW51cFR5cGU6IHR5cGVvZiBDTEVBTlVQX1RZUEVba2V5b2YgdHlwZW9mIENMRUFOVVBfVFlQRV0pIHtcbiAgICBpZiAoIXRoaXMuY2xvc2VkKSB7XG4gICAgICB0aGlzLmNsZWFyQ29ubmVjdFRpbWVyKCk7XG4gICAgICB0aGlzLmNsZWFyUmVxdWVzdFRpbWVyKCk7XG4gICAgICB0aGlzLmNsZWFyUmV0cnlUaW1lcigpO1xuICAgICAgdGhpcy5jbG9zZUNvbm5lY3Rpb24oKTtcbiAgICAgIGlmIChjbGVhbnVwVHlwZSA9PT0gQ0xFQU5VUF9UWVBFLlJFRElSRUNUKSB7XG4gICAgICAgIHRoaXMuZW1pdCgncmVyb3V0aW5nJyk7XG4gICAgICB9IGVsc2UgaWYgKGNsZWFudXBUeXBlICE9PSBDTEVBTlVQX1RZUEUuUkVUUlkpIHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLnJlcXVlc3Q7XG4gICAgICBpZiAocmVxdWVzdCkge1xuICAgICAgICBjb25zdCBlcnIgPSBuZXcgUmVxdWVzdEVycm9yKCdDb25uZWN0aW9uIGNsb3NlZCBiZWZvcmUgcmVxdWVzdCBjb21wbGV0ZWQuJywgJ0VDTE9TRScpO1xuICAgICAgICByZXF1ZXN0LmNhbGxiYWNrKGVycik7XG4gICAgICAgIHRoaXMucmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jbG9zZWQgPSB0cnVlO1xuICAgICAgdGhpcy5sb2dpbkVycm9yID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY3JlYXRlRGVidWcoKSB7XG4gICAgY29uc3QgZGVidWcgPSBuZXcgRGVidWcodGhpcy5jb25maWcub3B0aW9ucy5kZWJ1Zyk7XG4gICAgZGVidWcub24oJ2RlYnVnJywgKG1lc3NhZ2UpID0+IHtcbiAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBtZXNzYWdlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZGVidWc7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNyZWF0ZVRva2VuU3RyZWFtUGFyc2VyKG1lc3NhZ2U6IE1lc3NhZ2UsIGhhbmRsZXI6IFRva2VuSGFuZGxlcikge1xuICAgIHJldHVybiBuZXcgVG9rZW5TdHJlYW1QYXJzZXIobWVzc2FnZSwgdGhpcy5kZWJ1ZywgaGFuZGxlciwgdGhpcy5jb25maWcub3B0aW9ucyk7XG4gIH1cblxuICBzb2NrZXRIYW5kbGluZ0ZvclNlbmRQcmVMb2dpbihzb2NrZXQ6IG5ldC5Tb2NrZXQpIHtcbiAgICBzb2NrZXQub24oJ2Vycm9yJywgKGVycm9yKSA9PiB7IHRoaXMuc29ja2V0RXJyb3IoZXJyb3IpOyB9KTtcbiAgICBzb2NrZXQub24oJ2Nsb3NlJywgKCkgPT4geyB0aGlzLnNvY2tldENsb3NlKCk7IH0pO1xuICAgIHNvY2tldC5vbignZW5kJywgKCkgPT4geyB0aGlzLnNvY2tldEVuZCgpOyB9KTtcbiAgICBzb2NrZXQuc2V0S2VlcEFsaXZlKHRydWUsIEtFRVBfQUxJVkVfSU5JVElBTF9ERUxBWSk7XG5cbiAgICB0aGlzLm1lc3NhZ2VJbyA9IG5ldyBNZXNzYWdlSU8oc29ja2V0LCB0aGlzLmNvbmZpZy5vcHRpb25zLnBhY2tldFNpemUsIHRoaXMuZGVidWcpO1xuICAgIHRoaXMubWVzc2FnZUlvLm9uKCdzZWN1cmUnLCAoY2xlYXJ0ZXh0KSA9PiB7IHRoaXMuZW1pdCgnc2VjdXJlJywgY2xlYXJ0ZXh0KTsgfSk7XG5cbiAgICB0aGlzLnNvY2tldCA9IHNvY2tldDtcblxuICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7XG4gICAgdGhpcy5kZWJ1Zy5sb2coJ2Nvbm5lY3RlZCB0byAnICsgdGhpcy5jb25maWcuc2VydmVyICsgJzonICsgdGhpcy5jb25maWcub3B0aW9ucy5wb3J0KTtcblxuICAgIHRoaXMuc2VuZFByZUxvZ2luKCk7XG4gICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5TRU5UX1BSRUxPR0lOKTtcbiAgfVxuXG4gIHdyYXBXaXRoVGxzKHNvY2tldDogbmV0LlNvY2tldCwgc2lnbmFsOiBBYm9ydFNpZ25hbCk6IFByb21pc2U8dGxzLlRMU1NvY2tldD4ge1xuICAgIHNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHNlY3VyZUNvbnRleHQgPSB0bHMuY3JlYXRlU2VjdXJlQ29udGV4dCh0aGlzLnNlY3VyZUNvbnRleHRPcHRpb25zKTtcbiAgICAgIC8vIElmIGNvbm5lY3QgdG8gYW4gaXAgYWRkcmVzcyBkaXJlY3RseSxcbiAgICAgIC8vIG5lZWQgdG8gc2V0IHRoZSBzZXJ2ZXJuYW1lIHRvIGFuIGVtcHR5IHN0cmluZ1xuICAgICAgLy8gaWYgdGhlIHVzZXIgaGFzIG5vdCBnaXZlbiBhIHNlcnZlcm5hbWUgZXhwbGljaXRseVxuICAgICAgY29uc3Qgc2VydmVyTmFtZSA9ICFuZXQuaXNJUCh0aGlzLmNvbmZpZy5zZXJ2ZXIpID8gdGhpcy5jb25maWcuc2VydmVyIDogJyc7XG4gICAgICBjb25zdCBlbmNyeXB0T3B0aW9ucyA9IHtcbiAgICAgICAgaG9zdDogdGhpcy5jb25maWcuc2VydmVyLFxuICAgICAgICBzb2NrZXQ6IHNvY2tldCxcbiAgICAgICAgQUxQTlByb3RvY29sczogWyd0ZHMvOC4wJ10sXG4gICAgICAgIHNlY3VyZUNvbnRleHQ6IHNlY3VyZUNvbnRleHQsXG4gICAgICAgIHNlcnZlcm5hbWU6IHRoaXMuY29uZmlnLm9wdGlvbnMuc2VydmVyTmFtZSA/IHRoaXMuY29uZmlnLm9wdGlvbnMuc2VydmVyTmFtZSA6IHNlcnZlck5hbWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBlbmNyeXB0c29ja2V0ID0gdGxzLmNvbm5lY3QoZW5jcnlwdE9wdGlvbnMpO1xuXG4gICAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4ge1xuICAgICAgICBlbmNyeXB0c29ja2V0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgICBlbmNyeXB0c29ja2V0LnJlbW92ZUxpc3RlbmVyKCdjb25uZWN0Jywgb25Db25uZWN0KTtcblxuICAgICAgICBlbmNyeXB0c29ja2V0LmRlc3Ryb3koKTtcblxuICAgICAgICByZWplY3Qoc2lnbmFsLnJlYXNvbik7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBvbkVycm9yID0gKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25BYm9ydCk7XG5cbiAgICAgICAgZW5jcnlwdHNvY2tldC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbkVycm9yKTtcbiAgICAgICAgZW5jcnlwdHNvY2tldC5yZW1vdmVMaXN0ZW5lcignY29ubmVjdCcsIG9uQ29ubmVjdCk7XG5cbiAgICAgICAgZW5jcnlwdHNvY2tldC5kZXN0cm95KCk7XG5cbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBvbkNvbm5lY3QgPSAoKSA9PiB7XG4gICAgICAgIHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpO1xuXG4gICAgICAgIGVuY3J5cHRzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25FcnJvcik7XG4gICAgICAgIGVuY3J5cHRzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpO1xuXG4gICAgICAgIHJlc29sdmUoZW5jcnlwdHNvY2tldCk7XG4gICAgICB9O1xuXG4gICAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkFib3J0LCB7IG9uY2U6IHRydWUgfSk7XG5cbiAgICAgIGVuY3J5cHRzb2NrZXQub24oJ2Vycm9yJywgb25FcnJvcik7XG4gICAgICBlbmNyeXB0c29ja2V0Lm9uKCdzZWN1cmVDb25uZWN0Jywgb25Db25uZWN0KTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbm5lY3RPblBvcnQocG9ydDogbnVtYmVyLCBtdWx0aVN1Ym5ldEZhaWxvdmVyOiBib29sZWFuLCBzaWduYWw6IEFib3J0U2lnbmFsLCBjdXN0b21Db25uZWN0b3I/OiAoKSA9PiBQcm9taXNlPG5ldC5Tb2NrZXQ+KSB7XG4gICAgY29uc3QgY29ubmVjdE9wdHMgPSB7XG4gICAgICBob3N0OiB0aGlzLnJvdXRpbmdEYXRhID8gdGhpcy5yb3V0aW5nRGF0YS5zZXJ2ZXIgOiB0aGlzLmNvbmZpZy5zZXJ2ZXIsXG4gICAgICBwb3J0OiB0aGlzLnJvdXRpbmdEYXRhID8gdGhpcy5yb3V0aW5nRGF0YS5wb3J0IDogcG9ydCxcbiAgICAgIGxvY2FsQWRkcmVzczogdGhpcy5jb25maWcub3B0aW9ucy5sb2NhbEFkZHJlc3NcbiAgICB9O1xuXG4gICAgY29uc3QgY29ubmVjdCA9IGN1c3RvbUNvbm5lY3RvciB8fCAobXVsdGlTdWJuZXRGYWlsb3ZlciA/IGNvbm5lY3RJblBhcmFsbGVsIDogY29ubmVjdEluU2VxdWVuY2UpO1xuXG4gICAgKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBzb2NrZXQgPSBhd2FpdCBjb25uZWN0KGNvbm5lY3RPcHRzLCBkbnMubG9va3VwLCBzaWduYWwpO1xuXG4gICAgICBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmNyeXB0ID09PSAnc3RyaWN0Jykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFdyYXAgdGhlIHNvY2tldCB3aXRoIFRMUyBmb3IgVERTIDguMFxuICAgICAgICAgIHNvY2tldCA9IGF3YWl0IHRoaXMud3JhcFdpdGhUbHMoc29ja2V0LCBzaWduYWwpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBzb2NrZXQuZW5kKCk7XG5cbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5zb2NrZXRIYW5kbGluZ0ZvclNlbmRQcmVMb2dpbihzb2NrZXQpO1xuICAgIH0pKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgdGhpcy5jbGVhckNvbm5lY3RUaW1lcigpO1xuXG4gICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBwcm9jZXNzLm5leHRUaWNrKCgpID0+IHsgdGhpcy5zb2NrZXRFcnJvcihlcnIpOyB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2xvc2VDb25uZWN0aW9uKCkge1xuICAgIGlmICh0aGlzLnNvY2tldCkge1xuICAgICAgdGhpcy5zb2NrZXQuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY3JlYXRlQ29ubmVjdFRpbWVyKCkge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgdGhpcy5jb25uZWN0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICAgIHRoaXMuY29ubmVjdFRpbWVvdXQoKTtcbiAgICB9LCB0aGlzLmNvbmZpZy5vcHRpb25zLmNvbm5lY3RUaW1lb3V0KTtcbiAgICByZXR1cm4gY29udHJvbGxlci5zaWduYWw7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNyZWF0ZUNhbmNlbFRpbWVyKCkge1xuICAgIHRoaXMuY2xlYXJDYW5jZWxUaW1lcigpO1xuICAgIGNvbnN0IHRpbWVvdXQgPSB0aGlzLmNvbmZpZy5vcHRpb25zLmNhbmNlbFRpbWVvdXQ7XG4gICAgaWYgKHRpbWVvdXQgPiAwKSB7XG4gICAgICB0aGlzLmNhbmNlbFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2FuY2VsVGltZW91dCgpO1xuICAgICAgfSwgdGltZW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjcmVhdGVSZXF1ZXN0VGltZXIoKSB7XG4gICAgdGhpcy5jbGVhclJlcXVlc3RUaW1lcigpOyAvLyByZWxlYXNlIG9sZCB0aW1lciwganVzdCB0byBiZSBzYWZlXG4gICAgY29uc3QgcmVxdWVzdCA9IHRoaXMucmVxdWVzdCBhcyBSZXF1ZXN0O1xuICAgIGNvbnN0IHRpbWVvdXQgPSAocmVxdWVzdC50aW1lb3V0ICE9PSB1bmRlZmluZWQpID8gcmVxdWVzdC50aW1lb3V0IDogdGhpcy5jb25maWcub3B0aW9ucy5yZXF1ZXN0VGltZW91dDtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgdGhpcy5yZXF1ZXN0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0VGltZW91dCgpO1xuICAgICAgfSwgdGltZW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjcmVhdGVSZXRyeVRpbWVyKCkge1xuICAgIHRoaXMuY2xlYXJSZXRyeVRpbWVyKCk7XG4gICAgdGhpcy5yZXRyeVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnJldHJ5VGltZW91dCgpO1xuICAgIH0sIHRoaXMuY29uZmlnLm9wdGlvbnMuY29ubmVjdGlvblJldHJ5SW50ZXJ2YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjb25uZWN0VGltZW91dCgpIHtcbiAgICBjb25zdCBob3N0UG9zdGZpeCA9IHRoaXMuY29uZmlnLm9wdGlvbnMucG9ydCA/IGA6JHt0aGlzLmNvbmZpZy5vcHRpb25zLnBvcnR9YCA6IGBcXFxcJHt0aGlzLmNvbmZpZy5vcHRpb25zLmluc3RhbmNlTmFtZX1gO1xuICAgIC8vIElmIHdlIGhhdmUgcm91dGluZyBkYXRhIHN0b3JlZCwgdGhpcyBjb25uZWN0aW9uIGhhcyBiZWVuIHJlZGlyZWN0ZWRcbiAgICBjb25zdCBzZXJ2ZXIgPSB0aGlzLnJvdXRpbmdEYXRhID8gdGhpcy5yb3V0aW5nRGF0YS5zZXJ2ZXIgOiB0aGlzLmNvbmZpZy5zZXJ2ZXI7XG4gICAgY29uc3QgcG9ydCA9IHRoaXMucm91dGluZ0RhdGEgPyBgOiR7dGhpcy5yb3V0aW5nRGF0YS5wb3J0fWAgOiBob3N0UG9zdGZpeDtcbiAgICAvLyBHcmFiIHRoZSB0YXJnZXQgaG9zdCBmcm9tIHRoZSBjb25uZWN0aW9uIGNvbmZpZ3VyYXRpb24sIGFuZCBmcm9tIGEgcmVkaXJlY3QgbWVzc2FnZVxuICAgIC8vIG90aGVyd2lzZSwgbGVhdmUgdGhlIG1lc3NhZ2UgZW1wdHkuXG4gICAgY29uc3Qgcm91dGluZ01lc3NhZ2UgPSB0aGlzLnJvdXRpbmdEYXRhID8gYCAocmVkaXJlY3RlZCBmcm9tICR7dGhpcy5jb25maWcuc2VydmVyfSR7aG9zdFBvc3RmaXh9KWAgOiAnJztcbiAgICBjb25zdCBtZXNzYWdlID0gYEZhaWxlZCB0byBjb25uZWN0IHRvICR7c2VydmVyfSR7cG9ydH0ke3JvdXRpbmdNZXNzYWdlfSBpbiAke3RoaXMuY29uZmlnLm9wdGlvbnMuY29ubmVjdFRpbWVvdXR9bXNgO1xuICAgIHRoaXMuZGVidWcubG9nKG1lc3NhZ2UpO1xuICAgIHRoaXMuZW1pdCgnY29ubmVjdCcsIG5ldyBDb25uZWN0aW9uRXJyb3IobWVzc2FnZSwgJ0VUSU1FT1VUJykpO1xuICAgIHRoaXMuY29ubmVjdFRpbWVyID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudCgnY29ubmVjdFRpbWVvdXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuY2VsVGltZW91dCgpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gYEZhaWxlZCB0byBjYW5jZWwgcmVxdWVzdCBpbiAke3RoaXMuY29uZmlnLm9wdGlvbnMuY2FuY2VsVGltZW91dH1tc2A7XG4gICAgdGhpcy5kZWJ1Zy5sb2cobWVzc2FnZSk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KCdzb2NrZXRFcnJvcicsIG5ldyBDb25uZWN0aW9uRXJyb3IobWVzc2FnZSwgJ0VUSU1FT1VUJykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICByZXF1ZXN0VGltZW91dCgpIHtcbiAgICB0aGlzLnJlcXVlc3RUaW1lciA9IHVuZGVmaW5lZDtcbiAgICBjb25zdCByZXF1ZXN0ID0gdGhpcy5yZXF1ZXN0ITtcbiAgICByZXF1ZXN0LmNhbmNlbCgpO1xuICAgIGNvbnN0IHRpbWVvdXQgPSAocmVxdWVzdC50aW1lb3V0ICE9PSB1bmRlZmluZWQpID8gcmVxdWVzdC50aW1lb3V0IDogdGhpcy5jb25maWcub3B0aW9ucy5yZXF1ZXN0VGltZW91dDtcbiAgICBjb25zdCBtZXNzYWdlID0gJ1RpbWVvdXQ6IFJlcXVlc3QgZmFpbGVkIHRvIGNvbXBsZXRlIGluICcgKyB0aW1lb3V0ICsgJ21zJztcbiAgICByZXF1ZXN0LmVycm9yID0gbmV3IFJlcXVlc3RFcnJvcihtZXNzYWdlLCAnRVRJTUVPVVQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcmV0cnlUaW1lb3V0KCkge1xuICAgIHRoaXMucmV0cnlUaW1lciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmVtaXQoJ3JldHJ5Jyk7XG4gICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5DT05ORUNUSU5HKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2xlYXJDb25uZWN0VGltZXIoKSB7XG4gICAgaWYgKHRoaXMuY29ubmVjdFRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5jb25uZWN0VGltZXIpO1xuICAgICAgdGhpcy5jb25uZWN0VGltZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjbGVhckNhbmNlbFRpbWVyKCkge1xuICAgIGlmICh0aGlzLmNhbmNlbFRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5jYW5jZWxUaW1lcik7XG4gICAgICB0aGlzLmNhbmNlbFRpbWVyID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2xlYXJSZXF1ZXN0VGltZXIoKSB7XG4gICAgaWYgKHRoaXMucmVxdWVzdFRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5yZXF1ZXN0VGltZXIpO1xuICAgICAgdGhpcy5yZXF1ZXN0VGltZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjbGVhclJldHJ5VGltZXIoKSB7XG4gICAgaWYgKHRoaXMucmV0cnlUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucmV0cnlUaW1lcik7XG4gICAgICB0aGlzLnJldHJ5VGltZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0cmFuc2l0aW9uVG8obmV3U3RhdGU6IFN0YXRlKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT09IG5ld1N0YXRlKSB7XG4gICAgICB0aGlzLmRlYnVnLmxvZygnU3RhdGUgaXMgYWxyZWFkeSAnICsgbmV3U3RhdGUubmFtZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5leGl0KSB7XG4gICAgICB0aGlzLnN0YXRlLmV4aXQuY2FsbCh0aGlzLCBuZXdTdGF0ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5kZWJ1Zy5sb2coJ1N0YXRlIGNoYW5nZTogJyArICh0aGlzLnN0YXRlID8gdGhpcy5zdGF0ZS5uYW1lIDogJ3VuZGVmaW5lZCcpICsgJyAtPiAnICsgbmV3U3RhdGUubmFtZSk7XG4gICAgdGhpcy5zdGF0ZSA9IG5ld1N0YXRlO1xuXG4gICAgaWYgKHRoaXMuc3RhdGUuZW50ZXIpIHtcbiAgICAgIHRoaXMuc3RhdGUuZW50ZXIuYXBwbHkodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBnZXRFdmVudEhhbmRsZXI8VCBleHRlbmRzIGtleW9mIFN0YXRlWydldmVudHMnXT4oZXZlbnROYW1lOiBUKTogTm9uTnVsbGFibGU8U3RhdGVbJ2V2ZW50cyddW1RdPiB7XG4gICAgY29uc3QgaGFuZGxlciA9IHRoaXMuc3RhdGUuZXZlbnRzW2V2ZW50TmFtZV07XG5cbiAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gZXZlbnQgJyR7ZXZlbnROYW1lfScgaW4gc3RhdGUgJyR7dGhpcy5zdGF0ZS5uYW1lfSdgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaGFuZGxlciE7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGRpc3BhdGNoRXZlbnQ8VCBleHRlbmRzIGtleW9mIFN0YXRlWydldmVudHMnXT4oZXZlbnROYW1lOiBULCAuLi5hcmdzOiBQYXJhbWV0ZXJzPE5vbk51bGxhYmxlPFN0YXRlWydldmVudHMnXVtUXT4+KSB7XG4gICAgY29uc3QgaGFuZGxlciA9IHRoaXMuc3RhdGUuZXZlbnRzW2V2ZW50TmFtZV0gYXMgKCh0aGlzOiBDb25uZWN0aW9uLCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgIGhhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoYE5vIGV2ZW50ICcke2V2ZW50TmFtZX0nIGluIHN0YXRlICcke3RoaXMuc3RhdGUubmFtZX0nYCkpO1xuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc29ja2V0RXJyb3IoZXJyb3I6IEVycm9yKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT09IHRoaXMuU1RBVEUuQ09OTkVDVElORyB8fCB0aGlzLnN0YXRlID09PSB0aGlzLlNUQVRFLlNFTlRfVExTU1NMTkVHT1RJQVRJT04pIHtcbiAgICAgIGNvbnN0IGhvc3RQb3N0Zml4ID0gdGhpcy5jb25maWcub3B0aW9ucy5wb3J0ID8gYDoke3RoaXMuY29uZmlnLm9wdGlvbnMucG9ydH1gIDogYFxcXFwke3RoaXMuY29uZmlnLm9wdGlvbnMuaW5zdGFuY2VOYW1lfWA7XG4gICAgICAvLyBJZiB3ZSBoYXZlIHJvdXRpbmcgZGF0YSBzdG9yZWQsIHRoaXMgY29ubmVjdGlvbiBoYXMgYmVlbiByZWRpcmVjdGVkXG4gICAgICBjb25zdCBzZXJ2ZXIgPSB0aGlzLnJvdXRpbmdEYXRhID8gdGhpcy5yb3V0aW5nRGF0YS5zZXJ2ZXIgOiB0aGlzLmNvbmZpZy5zZXJ2ZXI7XG4gICAgICBjb25zdCBwb3J0ID0gdGhpcy5yb3V0aW5nRGF0YSA/IGA6JHt0aGlzLnJvdXRpbmdEYXRhLnBvcnR9YCA6IGhvc3RQb3N0Zml4O1xuICAgICAgLy8gR3JhYiB0aGUgdGFyZ2V0IGhvc3QgZnJvbSB0aGUgY29ubmVjdGlvbiBjb25maWd1cmF0aW9uLCBhbmQgZnJvbSBhIHJlZGlyZWN0IG1lc3NhZ2VcbiAgICAgIC8vIG90aGVyd2lzZSwgbGVhdmUgdGhlIG1lc3NhZ2UgZW1wdHkuXG4gICAgICBjb25zdCByb3V0aW5nTWVzc2FnZSA9IHRoaXMucm91dGluZ0RhdGEgPyBgIChyZWRpcmVjdGVkIGZyb20gJHt0aGlzLmNvbmZpZy5zZXJ2ZXJ9JHtob3N0UG9zdGZpeH0pYCA6ICcnO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGBGYWlsZWQgdG8gY29ubmVjdCB0byAke3NlcnZlcn0ke3BvcnR9JHtyb3V0aW5nTWVzc2FnZX0gLSAke2Vycm9yLm1lc3NhZ2V9YDtcbiAgICAgIHRoaXMuZGVidWcubG9nKG1lc3NhZ2UpO1xuICAgICAgdGhpcy5lbWl0KCdjb25uZWN0JywgbmV3IENvbm5lY3Rpb25FcnJvcihtZXNzYWdlLCAnRVNPQ0tFVCcpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGBDb25uZWN0aW9uIGxvc3QgLSAke2Vycm9yLm1lc3NhZ2V9YDtcbiAgICAgIHRoaXMuZGVidWcubG9nKG1lc3NhZ2UpO1xuICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBDb25uZWN0aW9uRXJyb3IobWVzc2FnZSwgJ0VTT0NLRVQnKSk7XG4gICAgfVxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudCgnc29ja2V0RXJyb3InLCBlcnJvcik7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHNvY2tldEVuZCgpIHtcbiAgICB0aGlzLmRlYnVnLmxvZygnc29ja2V0IGVuZGVkJyk7XG4gICAgaWYgKHRoaXMuc3RhdGUgIT09IHRoaXMuU1RBVEUuRklOQUwpIHtcbiAgICAgIGNvbnN0IGVycm9yOiBFcnJvcldpdGhDb2RlID0gbmV3IEVycm9yKCdzb2NrZXQgaGFuZyB1cCcpO1xuICAgICAgZXJyb3IuY29kZSA9ICdFQ09OTlJFU0VUJztcbiAgICAgIHRoaXMuc29ja2V0RXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc29ja2V0Q2xvc2UoKSB7XG4gICAgdGhpcy5kZWJ1Zy5sb2coJ2Nvbm5lY3Rpb24gdG8gJyArIHRoaXMuY29uZmlnLnNlcnZlciArICc6JyArIHRoaXMuY29uZmlnLm9wdGlvbnMucG9ydCArICcgY2xvc2VkJyk7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT09IHRoaXMuU1RBVEUuUkVST1VUSU5HKSB7XG4gICAgICB0aGlzLmRlYnVnLmxvZygnUmVyb3V0aW5nIHRvICcgKyB0aGlzLnJvdXRpbmdEYXRhIS5zZXJ2ZXIgKyAnOicgKyB0aGlzLnJvdXRpbmdEYXRhIS5wb3J0KTtcblxuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KCdyZWNvbm5lY3QnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUgPT09IHRoaXMuU1RBVEUuVFJBTlNJRU5UX0ZBSUxVUkVfUkVUUlkpIHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IHRoaXMucm91dGluZ0RhdGEgPyB0aGlzLnJvdXRpbmdEYXRhLnNlcnZlciA6IHRoaXMuY29uZmlnLnNlcnZlcjtcbiAgICAgIGNvbnN0IHBvcnQgPSB0aGlzLnJvdXRpbmdEYXRhID8gdGhpcy5yb3V0aW5nRGF0YS5wb3J0IDogdGhpcy5jb25maWcub3B0aW9ucy5wb3J0O1xuICAgICAgdGhpcy5kZWJ1Zy5sb2coJ1JldHJ5IGFmdGVyIHRyYW5zaWVudCBmYWlsdXJlIGNvbm5lY3RpbmcgdG8gJyArIHNlcnZlciArICc6JyArIHBvcnQpO1xuXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoJ3JldHJ5Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc2VuZFByZUxvZ2luKCkge1xuICAgIGNvbnN0IFssIG1ham9yLCBtaW5vciwgYnVpbGRdID0gL14oXFxkKylcXC4oXFxkKylcXC4oXFxkKykvLmV4ZWModmVyc2lvbikgPz8gWycwLjAuMCcsICcwJywgJzAnLCAnMCddO1xuICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgUHJlbG9naW5QYXlsb2FkKHtcbiAgICAgIC8vIElmIGVuY3J5cHQgc2V0dGluZyBpcyBzZXQgdG8gJ3N0cmljdCcsIHRoZW4gd2Ugc2hvdWxkIGhhdmUgYWxyZWFkeSBkb25lIHRoZSBlbmNyeXB0aW9uIGJlZm9yZSBjYWxsaW5nXG4gICAgICAvLyB0aGlzIGZ1bmN0aW9uLiBUaGVyZWZvcmUsIHRoZSBlbmNyeXB0IHdpbGwgYmUgc2V0IHRvIGZhbHNlIGhlcmUuXG4gICAgICAvLyBPdGhlcndpc2UsIHdlIHdpbGwgc2V0IGVuY3J5cHQgaGVyZSBiYXNlZCBvbiB0aGUgZW5jcnlwdCBCb29sZWFuIHZhbHVlIGZyb20gdGhlIGNvbmZpZ3VyYXRpb24uXG4gICAgICBlbmNyeXB0OiB0eXBlb2YgdGhpcy5jb25maWcub3B0aW9ucy5lbmNyeXB0ID09PSAnYm9vbGVhbicgJiYgdGhpcy5jb25maWcub3B0aW9ucy5lbmNyeXB0LFxuICAgICAgdmVyc2lvbjogeyBtYWpvcjogTnVtYmVyKG1ham9yKSwgbWlub3I6IE51bWJlcihtaW5vciksIGJ1aWxkOiBOdW1iZXIoYnVpbGQpLCBzdWJidWlsZDogMCB9XG4gICAgfSk7XG5cbiAgICB0aGlzLm1lc3NhZ2VJby5zZW5kTWVzc2FnZShUWVBFLlBSRUxPR0lOLCBwYXlsb2FkLmRhdGEpO1xuICAgIHRoaXMuZGVidWcucGF5bG9hZChmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwYXlsb2FkLnRvU3RyaW5nKCcgICcpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzZW5kTG9naW43UGFja2V0KCkge1xuICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgTG9naW43UGF5bG9hZCh7XG4gICAgICB0ZHNWZXJzaW9uOiB2ZXJzaW9uc1t0aGlzLmNvbmZpZy5vcHRpb25zLnRkc1ZlcnNpb25dLFxuICAgICAgcGFja2V0U2l6ZTogdGhpcy5jb25maWcub3B0aW9ucy5wYWNrZXRTaXplLFxuICAgICAgY2xpZW50UHJvZ1ZlcjogMCxcbiAgICAgIGNsaWVudFBpZDogcHJvY2Vzcy5waWQsXG4gICAgICBjb25uZWN0aW9uSWQ6IDAsXG4gICAgICBjbGllbnRUaW1lWm9uZTogbmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpLFxuICAgICAgY2xpZW50TGNpZDogMHgwMDAwMDQwOVxuICAgIH0pO1xuXG4gICAgY29uc3QgeyBhdXRoZW50aWNhdGlvbiB9ID0gdGhpcy5jb25maWc7XG4gICAgc3dpdGNoIChhdXRoZW50aWNhdGlvbi50eXBlKSB7XG4gICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LXBhc3N3b3JkJzpcbiAgICAgICAgcGF5bG9hZC5mZWRBdXRoID0ge1xuICAgICAgICAgIHR5cGU6ICdBREFMJyxcbiAgICAgICAgICBlY2hvOiB0aGlzLmZlZEF1dGhSZXF1aXJlZCxcbiAgICAgICAgICB3b3JrZmxvdzogJ2RlZmF1bHQnXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LWFjY2Vzcy10b2tlbic6XG4gICAgICAgIHBheWxvYWQuZmVkQXV0aCA9IHtcbiAgICAgICAgICB0eXBlOiAnU0VDVVJJVFlUT0tFTicsXG4gICAgICAgICAgZWNobzogdGhpcy5mZWRBdXRoUmVxdWlyZWQsXG4gICAgICAgICAgZmVkQXV0aFRva2VuOiBhdXRoZW50aWNhdGlvbi5vcHRpb25zLnRva2VuXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS12bSc6XG4gICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LWRlZmF1bHQnOlxuICAgICAgY2FzZSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktYXBwLXNlcnZpY2UnOlxuICAgICAgY2FzZSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1zZXJ2aWNlLXByaW5jaXBhbC1zZWNyZXQnOlxuICAgICAgICBwYXlsb2FkLmZlZEF1dGggPSB7XG4gICAgICAgICAgdHlwZTogJ0FEQUwnLFxuICAgICAgICAgIGVjaG86IHRoaXMuZmVkQXV0aFJlcXVpcmVkLFxuICAgICAgICAgIHdvcmtmbG93OiAnaW50ZWdyYXRlZCdcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ250bG0nOlxuICAgICAgICBwYXlsb2FkLnNzcGkgPSBjcmVhdGVOVExNUmVxdWVzdCh7IGRvbWFpbjogYXV0aGVudGljYXRpb24ub3B0aW9ucy5kb21haW4gfSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBwYXlsb2FkLnVzZXJOYW1lID0gYXV0aGVudGljYXRpb24ub3B0aW9ucy51c2VyTmFtZTtcbiAgICAgICAgcGF5bG9hZC5wYXNzd29yZCA9IGF1dGhlbnRpY2F0aW9uLm9wdGlvbnMucGFzc3dvcmQ7XG4gICAgfVxuXG4gICAgcGF5bG9hZC5ob3N0bmFtZSA9IHRoaXMuY29uZmlnLm9wdGlvbnMud29ya3N0YXRpb25JZCB8fCBvcy5ob3N0bmFtZSgpO1xuICAgIHBheWxvYWQuc2VydmVyTmFtZSA9IHRoaXMucm91dGluZ0RhdGEgPyB0aGlzLnJvdXRpbmdEYXRhLnNlcnZlciA6IHRoaXMuY29uZmlnLnNlcnZlcjtcbiAgICBwYXlsb2FkLmFwcE5hbWUgPSB0aGlzLmNvbmZpZy5vcHRpb25zLmFwcE5hbWUgfHwgJ1RlZGlvdXMnO1xuICAgIHBheWxvYWQubGlicmFyeU5hbWUgPSBsaWJyYXJ5TmFtZTtcbiAgICBwYXlsb2FkLmxhbmd1YWdlID0gdGhpcy5jb25maWcub3B0aW9ucy5sYW5ndWFnZTtcbiAgICBwYXlsb2FkLmRhdGFiYXNlID0gdGhpcy5jb25maWcub3B0aW9ucy5kYXRhYmFzZTtcbiAgICBwYXlsb2FkLmNsaWVudElkID0gQnVmZmVyLmZyb20oWzEsIDIsIDMsIDQsIDUsIDZdKTtcblxuICAgIHBheWxvYWQucmVhZE9ubHlJbnRlbnQgPSB0aGlzLmNvbmZpZy5vcHRpb25zLnJlYWRPbmx5SW50ZW50O1xuICAgIHBheWxvYWQuaW5pdERiRmF0YWwgPSAhdGhpcy5jb25maWcub3B0aW9ucy5mYWxsYmFja1RvRGVmYXVsdERiO1xuXG4gICAgdGhpcy5yb3V0aW5nRGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1lc3NhZ2VJby5zZW5kTWVzc2FnZShUWVBFLkxPR0lONywgcGF5bG9hZC50b0J1ZmZlcigpKTtcblxuICAgIHRoaXMuZGVidWcucGF5bG9hZChmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBwYXlsb2FkLnRvU3RyaW5nKCcgICcpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzZW5kRmVkQXV0aFRva2VuTWVzc2FnZSh0b2tlbjogc3RyaW5nKSB7XG4gICAgY29uc3QgYWNjZXNzVG9rZW5MZW4gPSBCdWZmZXIuYnl0ZUxlbmd0aCh0b2tlbiwgJ3VjczInKTtcbiAgICBjb25zdCBkYXRhID0gQnVmZmVyLmFsbG9jKDggKyBhY2Nlc3NUb2tlbkxlbik7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgb2Zmc2V0ID0gZGF0YS53cml0ZVVJbnQzMkxFKGFjY2Vzc1Rva2VuTGVuICsgNCwgb2Zmc2V0KTtcbiAgICBvZmZzZXQgPSBkYXRhLndyaXRlVUludDMyTEUoYWNjZXNzVG9rZW5MZW4sIG9mZnNldCk7XG4gICAgZGF0YS53cml0ZSh0b2tlbiwgb2Zmc2V0LCAndWNzMicpO1xuICAgIHRoaXMubWVzc2FnZUlvLnNlbmRNZXNzYWdlKFRZUEUuRkVEQVVUSF9UT0tFTiwgZGF0YSk7XG4gICAgLy8gc2VudCB0aGUgZmVkQXV0aCB0b2tlbiBtZXNzYWdlLCB0aGUgcmVzdCBpcyBzaW1pbGFyIHRvIHN0YW5kYXJkIGxvZ2luIDdcbiAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLlNFTlRfTE9HSU43X1dJVEhfU1RBTkRBUkRfTE9HSU4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzZW5kSW5pdGlhbFNxbCgpIHtcbiAgICBjb25zdCBwYXlsb2FkID0gbmV3IFNxbEJhdGNoUGF5bG9hZCh0aGlzLmdldEluaXRpYWxTcWwoKSwgdGhpcy5jdXJyZW50VHJhbnNhY3Rpb25EZXNjcmlwdG9yKCksIHRoaXMuY29uZmlnLm9wdGlvbnMpO1xuXG4gICAgY29uc3QgbWVzc2FnZSA9IG5ldyBNZXNzYWdlKHsgdHlwZTogVFlQRS5TUUxfQkFUQ0ggfSk7XG4gICAgdGhpcy5tZXNzYWdlSW8ub3V0Z29pbmdNZXNzYWdlU3RyZWFtLndyaXRlKG1lc3NhZ2UpO1xuICAgIFJlYWRhYmxlLmZyb20ocGF5bG9hZCkucGlwZShtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgZ2V0SW5pdGlhbFNxbCgpIHtcbiAgICBjb25zdCBvcHRpb25zID0gW107XG5cbiAgICBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVBbnNpTnVsbCA9PT0gdHJ1ZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgYW5zaV9udWxscyBvbicpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVBbnNpTnVsbCA9PT0gZmFsc2UpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IGFuc2lfbnVsbHMgb2ZmJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlQW5zaU51bGxEZWZhdWx0ID09PSB0cnVlKSB7XG4gICAgICBvcHRpb25zLnB1c2goJ3NldCBhbnNpX251bGxfZGZsdF9vbiBvbicpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVBbnNpTnVsbERlZmF1bHQgPT09IGZhbHNlKSB7XG4gICAgICBvcHRpb25zLnB1c2goJ3NldCBhbnNpX251bGxfZGZsdF9vbiBvZmYnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVBbnNpUGFkZGluZyA9PT0gdHJ1ZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgYW5zaV9wYWRkaW5nIG9uJyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lQYWRkaW5nID09PSBmYWxzZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgYW5zaV9wYWRkaW5nIG9mZicpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUFuc2lXYXJuaW5ncyA9PT0gdHJ1ZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgYW5zaV93YXJuaW5ncyBvbicpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVBbnNpV2FybmluZ3MgPT09IGZhbHNlKSB7XG4gICAgICBvcHRpb25zLnB1c2goJ3NldCBhbnNpX3dhcm5pbmdzIG9mZicpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUFyaXRoQWJvcnQgPT09IHRydWUpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IGFyaXRoYWJvcnQgb24nKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlQXJpdGhBYm9ydCA9PT0gZmFsc2UpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IGFyaXRoYWJvcnQgb2ZmJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlQ29uY2F0TnVsbFlpZWxkc051bGwgPT09IHRydWUpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IGNvbmNhdF9udWxsX3lpZWxkc19udWxsIG9uJyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZUNvbmNhdE51bGxZaWVsZHNOdWxsID09PSBmYWxzZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgY29uY2F0X251bGxfeWllbGRzX251bGwgb2ZmJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlQ3Vyc29yQ2xvc2VPbkNvbW1pdCA9PT0gdHJ1ZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgY3Vyc29yX2Nsb3NlX29uX2NvbW1pdCBvbicpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVDdXJzb3JDbG9zZU9uQ29tbWl0ID09PSBmYWxzZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgY3Vyc29yX2Nsb3NlX29uX2NvbW1pdCBvZmYnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcub3B0aW9ucy5kYXRlZmlyc3QgIT09IG51bGwpIHtcbiAgICAgIG9wdGlvbnMucHVzaChgc2V0IGRhdGVmaXJzdCAke3RoaXMuY29uZmlnLm9wdGlvbnMuZGF0ZWZpcnN0fWApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLmRhdGVGb3JtYXQgIT09IG51bGwpIHtcbiAgICAgIG9wdGlvbnMucHVzaChgc2V0IGRhdGVmb3JtYXQgJHt0aGlzLmNvbmZpZy5vcHRpb25zLmRhdGVGb3JtYXR9YCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlSW1wbGljaXRUcmFuc2FjdGlvbnMgPT09IHRydWUpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IGltcGxpY2l0X3RyYW5zYWN0aW9ucyBvbicpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb25maWcub3B0aW9ucy5lbmFibGVJbXBsaWNpdFRyYW5zYWN0aW9ucyA9PT0gZmFsc2UpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IGltcGxpY2l0X3RyYW5zYWN0aW9ucyBvZmYnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcub3B0aW9ucy5sYW5ndWFnZSAhPT0gbnVsbCkge1xuICAgICAgb3B0aW9ucy5wdXNoKGBzZXQgbGFuZ3VhZ2UgJHt0aGlzLmNvbmZpZy5vcHRpb25zLmxhbmd1YWdlfWApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLmVuYWJsZU51bWVyaWNSb3VuZGFib3J0ID09PSB0cnVlKSB7XG4gICAgICBvcHRpb25zLnB1c2goJ3NldCBudW1lcmljX3JvdW5kYWJvcnQgb24nKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlTnVtZXJpY1JvdW5kYWJvcnQgPT09IGZhbHNlKSB7XG4gICAgICBvcHRpb25zLnB1c2goJ3NldCBudW1lcmljX3JvdW5kYWJvcnQgb2ZmJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlUXVvdGVkSWRlbnRpZmllciA9PT0gdHJ1ZSkge1xuICAgICAgb3B0aW9ucy5wdXNoKCdzZXQgcXVvdGVkX2lkZW50aWZpZXIgb24nKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuZW5hYmxlUXVvdGVkSWRlbnRpZmllciA9PT0gZmFsc2UpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IHF1b3RlZF9pZGVudGlmaWVyIG9mZicpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLnRleHRzaXplICE9PSBudWxsKSB7XG4gICAgICBvcHRpb25zLnB1c2goYHNldCB0ZXh0c2l6ZSAke3RoaXMuY29uZmlnLm9wdGlvbnMudGV4dHNpemV9YCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuY29ubmVjdGlvbklzb2xhdGlvbkxldmVsICE9PSBudWxsKSB7XG4gICAgICBvcHRpb25zLnB1c2goYHNldCB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwgJHt0aGlzLmdldElzb2xhdGlvbkxldmVsVGV4dCh0aGlzLmNvbmZpZy5vcHRpb25zLmNvbm5lY3Rpb25Jc29sYXRpb25MZXZlbCl9YCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuYWJvcnRUcmFuc2FjdGlvbk9uRXJyb3IgPT09IHRydWUpIHtcbiAgICAgIG9wdGlvbnMucHVzaCgnc2V0IHhhY3RfYWJvcnQgb24nKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMuYWJvcnRUcmFuc2FjdGlvbk9uRXJyb3IgPT09IGZhbHNlKSB7XG4gICAgICBvcHRpb25zLnB1c2goJ3NldCB4YWN0X2Fib3J0IG9mZicpO1xuICAgIH1cblxuICAgIHJldHVybiBvcHRpb25zLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcm9jZXNzZWRJbml0aWFsU3FsKCkge1xuICAgIHRoaXMuY2xlYXJDb25uZWN0VGltZXIoKTtcbiAgICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIHRoZSBTUUwgYmF0Y2ggcmVwcmVzZW50ZWQgYnkgW1tSZXF1ZXN0XV0uXG4gICAqIFRoZXJlIGlzIG5vIHBhcmFtIHN1cHBvcnQsIGFuZCB1bmxpa2UgW1tSZXF1ZXN0LmV4ZWNTcWxdXSxcbiAgICogaXQgaXMgbm90IGxpa2VseSB0aGF0IFNRTCBTZXJ2ZXIgd2lsbCByZXVzZSB0aGUgZXhlY3V0aW9uIHBsYW4gaXQgZ2VuZXJhdGVzIGZvciB0aGUgU1FMLlxuICAgKlxuICAgKiBJbiBhbG1vc3QgYWxsIGNhc2VzLCBbW1JlcXVlc3QuZXhlY1NxbF1dIHdpbGwgYmUgYSBiZXR0ZXIgY2hvaWNlLlxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdCBBIFtbUmVxdWVzdF1dIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHJlcXVlc3QuXG4gICAqL1xuICBleGVjU3FsQmF0Y2gocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMubWFrZVJlcXVlc3QocmVxdWVzdCwgVFlQRS5TUUxfQkFUQ0gsIG5ldyBTcWxCYXRjaFBheWxvYWQocmVxdWVzdC5zcWxUZXh0T3JQcm9jZWR1cmUhLCB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbkRlc2NyaXB0b3IoKSwgdGhpcy5jb25maWcub3B0aW9ucykpO1xuICB9XG5cbiAgLyoqXG4gICAqICBFeGVjdXRlIHRoZSBTUUwgcmVwcmVzZW50ZWQgYnkgW1tSZXF1ZXN0XV0uXG4gICAqXG4gICAqIEFzIGBzcF9leGVjdXRlc3FsYCBpcyB1c2VkIHRvIGV4ZWN1dGUgdGhlIFNRTCwgaWYgdGhlIHNhbWUgU1FMIGlzIGV4ZWN1dGVkIG11bHRpcGxlcyB0aW1lc1xuICAgKiB1c2luZyB0aGlzIGZ1bmN0aW9uLCB0aGUgU1FMIFNlcnZlciBxdWVyeSBvcHRpbWl6ZXIgaXMgbGlrZWx5IHRvIHJldXNlIHRoZSBleGVjdXRpb24gcGxhbiBpdCBnZW5lcmF0ZXNcbiAgICogZm9yIHRoZSBmaXJzdCBleGVjdXRpb24uIFRoaXMgbWF5IGFsc28gcmVzdWx0IGluIFNRTCBzZXJ2ZXIgdHJlYXRpbmcgdGhlIHJlcXVlc3QgbGlrZSBhIHN0b3JlZCBwcm9jZWR1cmVcbiAgICogd2hpY2ggY2FuIHJlc3VsdCBpbiB0aGUgW1tFdmVudF9kb25lSW5Qcm9jXV0gb3IgW1tFdmVudF9kb25lUHJvY11dIGV2ZW50cyBiZWluZyBlbWl0dGVkIGluc3RlYWQgb2YgdGhlXG4gICAqIFtbRXZlbnRfZG9uZV1dIGV2ZW50IHlvdSBtaWdodCBleHBlY3QuIFVzaW5nIFtbZXhlY1NxbEJhdGNoXV0gd2lsbCBwcmV2ZW50IHRoaXMgZnJvbSBvY2N1cnJpbmcgYnV0IG1heSBoYXZlIGEgbmVnYXRpdmUgcGVyZm9ybWFuY2UgaW1wYWN0LlxuICAgKlxuICAgKiBCZXdhcmUgb2YgdGhlIHdheSB0aGF0IHNjb3BpbmcgcnVsZXMgYXBwbHksIGFuZCBob3cgdGhleSBtYXkgW2FmZmVjdCBsb2NhbCB0ZW1wIHRhYmxlc10oaHR0cDovL3dlYmxvZ3Muc3FsdGVhbS5jb20vbWxhZGVucC9hcmNoaXZlLzIwMDYvMTEvMDMvMTcxOTcuYXNweClcbiAgICogSWYgeW91J3JlIHJ1bm5pbmcgaW4gdG8gc2NvcGluZyBpc3N1ZXMsIHRoZW4gW1tleGVjU3FsQmF0Y2hdXSBtYXkgYmUgYSBiZXR0ZXIgY2hvaWNlLlxuICAgKiBTZWUgYWxzbyBbaXNzdWUgIzI0XShodHRwczovL2dpdGh1Yi5jb20vcGVraW0vdGVkaW91cy9pc3N1ZXMvMjQpXG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0IEEgW1tSZXF1ZXN0XV0gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgcmVxdWVzdC5cbiAgICovXG4gIGV4ZWNTcWwocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRyeSB7XG4gICAgICByZXF1ZXN0LnZhbGlkYXRlUGFyYW1ldGVycyh0aGlzLmRhdGFiYXNlQ29sbGF0aW9uKTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXF1ZXN0LmVycm9yID0gZXJyb3I7XG5cbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICB0aGlzLmRlYnVnLmxvZyhlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgcmVxdWVzdC5jYWxsYmFjayhlcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmFtZXRlcnM6IFBhcmFtZXRlcltdID0gW107XG5cbiAgICBwYXJhbWV0ZXJzLnB1c2goe1xuICAgICAgdHlwZTogVFlQRVMuTlZhckNoYXIsXG4gICAgICBuYW1lOiAnc3RhdGVtZW50JyxcbiAgICAgIHZhbHVlOiByZXF1ZXN0LnNxbFRleHRPclByb2NlZHVyZSxcbiAgICAgIG91dHB1dDogZmFsc2UsXG4gICAgICBsZW5ndGg6IHVuZGVmaW5lZCxcbiAgICAgIHByZWNpc2lvbjogdW5kZWZpbmVkLFxuICAgICAgc2NhbGU6IHVuZGVmaW5lZFxuICAgIH0pO1xuXG4gICAgaWYgKHJlcXVlc3QucGFyYW1ldGVycy5sZW5ndGgpIHtcbiAgICAgIHBhcmFtZXRlcnMucHVzaCh7XG4gICAgICAgIHR5cGU6IFRZUEVTLk5WYXJDaGFyLFxuICAgICAgICBuYW1lOiAncGFyYW1zJyxcbiAgICAgICAgdmFsdWU6IHJlcXVlc3QubWFrZVBhcmFtc1BhcmFtZXRlcihyZXF1ZXN0LnBhcmFtZXRlcnMpLFxuICAgICAgICBvdXRwdXQ6IGZhbHNlLFxuICAgICAgICBsZW5ndGg6IHVuZGVmaW5lZCxcbiAgICAgICAgcHJlY2lzaW9uOiB1bmRlZmluZWQsXG4gICAgICAgIHNjYWxlOiB1bmRlZmluZWRcbiAgICAgIH0pO1xuXG4gICAgICBwYXJhbWV0ZXJzLnB1c2goLi4ucmVxdWVzdC5wYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICB0aGlzLm1ha2VSZXF1ZXN0KHJlcXVlc3QsIFRZUEUuUlBDX1JFUVVFU1QsIG5ldyBScGNSZXF1ZXN0UGF5bG9hZChQcm9jZWR1cmVzLlNwX0V4ZWN1dGVTcWwsIHBhcmFtZXRlcnMsIHRoaXMuY3VycmVudFRyYW5zYWN0aW9uRGVzY3JpcHRvcigpLCB0aGlzLmNvbmZpZy5vcHRpb25zLCB0aGlzLmRhdGFiYXNlQ29sbGF0aW9uKSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBCdWxrTG9hZCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHRhYmxlIFRoZSBuYW1lIG9mIHRoZSB0YWJsZSB0byBidWxrLWluc2VydCBpbnRvLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBBIHNldCBvZiBidWxrIGxvYWQgb3B0aW9ucy5cbiAgICovXG4gIG5ld0J1bGtMb2FkKHRhYmxlOiBzdHJpbmcsIGNhbGxiYWNrOiBCdWxrTG9hZENhbGxiYWNrKTogQnVsa0xvYWRcbiAgbmV3QnVsa0xvYWQodGFibGU6IHN0cmluZywgb3B0aW9uczogQnVsa0xvYWRPcHRpb25zLCBjYWxsYmFjazogQnVsa0xvYWRDYWxsYmFjayk6IEJ1bGtMb2FkXG4gIG5ld0J1bGtMb2FkKHRhYmxlOiBzdHJpbmcsIGNhbGxiYWNrT3JPcHRpb25zOiBCdWxrTG9hZE9wdGlvbnMgfCBCdWxrTG9hZENhbGxiYWNrLCBjYWxsYmFjaz86IEJ1bGtMb2FkQ2FsbGJhY2spIHtcbiAgICBsZXQgb3B0aW9uczogQnVsa0xvYWRPcHRpb25zO1xuXG4gICAgaWYgKGNhbGxiYWNrID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2tPck9wdGlvbnMgYXMgQnVsa0xvYWRDYWxsYmFjaztcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucyA9IGNhbGxiYWNrT3JPcHRpb25zIGFzIEJ1bGtMb2FkT3B0aW9ucztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm9wdGlvbnNcIiBhcmd1bWVudCBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEJ1bGtMb2FkKHRhYmxlLCB0aGlzLmRhdGFiYXNlQ29sbGF0aW9uLCB0aGlzLmNvbmZpZy5vcHRpb25zLCBvcHRpb25zLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIFtbQnVsa0xvYWRdXS5cbiAgICpcbiAgICogYGBganNcbiAgICogLy8gV2Ugd2FudCB0byBwZXJmb3JtIGEgYnVsayBsb2FkIGludG8gYSB0YWJsZSB3aXRoIHRoZSBmb2xsb3dpbmcgZm9ybWF0OlxuICAgKiAvLyBDUkVBVEUgVEFCTEUgZW1wbG95ZWVzIChmaXJzdF9uYW1lIG52YXJjaGFyKDI1NSksIGxhc3RfbmFtZSBudmFyY2hhcigyNTUpLCBkYXlfb2ZfYmlydGggZGF0ZSk7XG4gICAqXG4gICAqIGNvbnN0IGJ1bGtMb2FkID0gY29ubmVjdGlvbi5uZXdCdWxrTG9hZCgnZW1wbG95ZWVzJywgKGVyciwgcm93Q291bnQpID0+IHtcbiAgICogICAvLyAuLi5cbiAgICogfSk7XG4gICAqXG4gICAqIC8vIEZpcnN0LCB3ZSBuZWVkIHRvIHNwZWNpZnkgdGhlIGNvbHVtbnMgdGhhdCB3ZSB3YW50IHRvIHdyaXRlIHRvLFxuICAgKiAvLyBhbmQgdGhlaXIgZGVmaW5pdGlvbnMuIFRoZXNlIGRlZmluaXRpb25zIG11c3QgbWF0Y2ggdGhlIGFjdHVhbCB0YWJsZSxcbiAgICogLy8gb3RoZXJ3aXNlIHRoZSBidWxrIGxvYWQgd2lsbCBmYWlsLlxuICAgKiBidWxrTG9hZC5hZGRDb2x1bW4oJ2ZpcnN0X25hbWUnLCBUWVBFUy5OVmFyY2hhciwgeyBudWxsYWJsZTogZmFsc2UgfSk7XG4gICAqIGJ1bGtMb2FkLmFkZENvbHVtbignbGFzdF9uYW1lJywgVFlQRVMuTlZhcmNoYXIsIHsgbnVsbGFibGU6IGZhbHNlIH0pO1xuICAgKiBidWxrTG9hZC5hZGRDb2x1bW4oJ2RhdGVfb2ZfYmlydGgnLCBUWVBFUy5EYXRlLCB7IG51bGxhYmxlOiBmYWxzZSB9KTtcbiAgICpcbiAgICogLy8gRXhlY3V0ZSBhIGJ1bGsgbG9hZCB3aXRoIGEgcHJlZGVmaW5lZCBsaXN0IG9mIHJvd3MuXG4gICAqIC8vXG4gICAqIC8vIE5vdGUgdGhhdCB0aGVzZSByb3dzIGFyZSBoZWxkIGluIG1lbW9yeSB1bnRpbCB0aGVcbiAgICogLy8gYnVsayBsb2FkIHdhcyBwZXJmb3JtZWQsIHNvIGlmIHlvdSBuZWVkIHRvIHdyaXRlIGEgbGFyZ2VcbiAgICogLy8gbnVtYmVyIG9mIHJvd3MgKGUuZy4gYnkgcmVhZGluZyBmcm9tIGEgQ1NWIGZpbGUpLFxuICAgKiAvLyBwYXNzaW5nIGFuIGBBc3luY0l0ZXJhYmxlYCBpcyBhZHZpc2FibGUgdG8ga2VlcCBtZW1vcnkgdXNhZ2UgbG93LlxuICAgKiBjb25uZWN0aW9uLmV4ZWNCdWxrTG9hZChidWxrTG9hZCwgW1xuICAgKiAgIHsgJ2ZpcnN0X25hbWUnOiAnU3RldmUnLCAnbGFzdF9uYW1lJzogJ0pvYnMnLCAnZGF5X29mX2JpcnRoJzogbmV3IERhdGUoJzAyLTI0LTE5NTUnKSB9LFxuICAgKiAgIHsgJ2ZpcnN0X25hbWUnOiAnQmlsbCcsICdsYXN0X25hbWUnOiAnR2F0ZXMnLCAnZGF5X29mX2JpcnRoJzogbmV3IERhdGUoJzEwLTI4LTE5NTUnKSB9XG4gICAqIF0pO1xuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIGJ1bGtMb2FkIEEgcHJldmlvdXNseSBjcmVhdGVkIFtbQnVsa0xvYWRdXS5cbiAgICogQHBhcmFtIHJvd3MgQSBbW0l0ZXJhYmxlXV0gb3IgW1tBc3luY0l0ZXJhYmxlXV0gdGhhdCBjb250YWlucyB0aGUgcm93cyB0aGF0IHNob3VsZCBiZSBidWxrIGxvYWRlZC5cbiAgICovXG4gIGV4ZWNCdWxrTG9hZChidWxrTG9hZDogQnVsa0xvYWQsIHJvd3M6IEFzeW5jSXRlcmFibGU8dW5rbm93bltdIHwgeyBbY29sdW1uTmFtZTogc3RyaW5nXTogdW5rbm93biB9PiB8IEl0ZXJhYmxlPHVua25vd25bXSB8IHsgW2NvbHVtbk5hbWU6IHN0cmluZ106IHVua25vd24gfT4pOiB2b2lkXG5cbiAgZXhlY0J1bGtMb2FkKGJ1bGtMb2FkOiBCdWxrTG9hZCwgcm93cz86IEFzeW5jSXRlcmFibGU8dW5rbm93bltdIHwgeyBbY29sdW1uTmFtZTogc3RyaW5nXTogdW5rbm93biB9PiB8IEl0ZXJhYmxlPHVua25vd25bXSB8IHsgW2NvbHVtbk5hbWU6IHN0cmluZ106IHVua25vd24gfT4pIHtcbiAgICBidWxrTG9hZC5leGVjdXRpb25TdGFydGVkID0gdHJ1ZTtcblxuICAgIGlmIChyb3dzKSB7XG4gICAgICBpZiAoYnVsa0xvYWQuc3RyZWFtaW5nTW9kZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb25uZWN0aW9uLmV4ZWNCdWxrTG9hZCBjYW4ndCBiZSBjYWxsZWQgd2l0aCBhIEJ1bGtMb2FkIHRoYXQgd2FzIHB1dCBpbiBzdHJlYW1pbmcgbW9kZS5cIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChidWxrTG9hZC5maXJzdFJvd1dyaXR0ZW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29ubmVjdGlvbi5leGVjQnVsa0xvYWQgY2FuJ3QgYmUgY2FsbGVkIHdpdGggYSBCdWxrTG9hZCB0aGF0IGFscmVhZHkgaGFzIHJvd3Mgd3JpdHRlbiB0byBpdC5cIik7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJvd1N0cmVhbSA9IFJlYWRhYmxlLmZyb20ocm93cyk7XG5cbiAgICAgIC8vIERlc3Ryb3kgdGhlIHBhY2tldCB0cmFuc2Zvcm0gaWYgYW4gZXJyb3IgaGFwcGVucyBpbiB0aGUgcm93IHN0cmVhbSxcbiAgICAgIC8vIGUuZy4gaWYgYW4gZXJyb3IgaXMgdGhyb3duIGZyb20gd2l0aGluIGEgZ2VuZXJhdG9yIG9yIHN0cmVhbS5cbiAgICAgIHJvd1N0cmVhbS5vbignZXJyb3InLCAoZXJyKSA9PiB7XG4gICAgICAgIGJ1bGtMb2FkLnJvd1RvUGFja2V0VHJhbnNmb3JtLmRlc3Ryb3koZXJyKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBEZXN0cm95IHRoZSByb3cgc3RyZWFtIGlmIGFuIGVycm9yIGhhcHBlbnMgaW4gdGhlIHBhY2tldCB0cmFuc2Zvcm0sXG4gICAgICAvLyBlLmcuIGlmIHRoZSBidWxrIGxvYWQgaXMgY2FuY2VsbGVkLlxuICAgICAgYnVsa0xvYWQucm93VG9QYWNrZXRUcmFuc2Zvcm0ub24oJ2Vycm9yJywgKGVycikgPT4ge1xuICAgICAgICByb3dTdHJlYW0uZGVzdHJveShlcnIpO1xuICAgICAgfSk7XG5cbiAgICAgIHJvd1N0cmVhbS5waXBlKGJ1bGtMb2FkLnJvd1RvUGFja2V0VHJhbnNmb3JtKTtcbiAgICB9IGVsc2UgaWYgKCFidWxrTG9hZC5zdHJlYW1pbmdNb2RlKSB7XG4gICAgICAvLyBJZiB0aGUgYnVsa2xvYWQgd2FzIG5vdCBwdXQgaW50byBzdHJlYW1pbmcgbW9kZSBieSB0aGUgdXNlcixcbiAgICAgIC8vIHdlIGVuZCB0aGUgcm93VG9QYWNrZXRUcmFuc2Zvcm0gaGVyZSBmb3IgdGhlbS5cbiAgICAgIC8vXG4gICAgICAvLyBJZiBpdCB3YXMgcHV0IGludG8gc3RyZWFtaW5nIG1vZGUsIGl0J3MgdGhlIHVzZXIncyByZXNwb25zaWJpbGl0eVxuICAgICAgLy8gdG8gZW5kIHRoZSBzdHJlYW0uXG4gICAgICBidWxrTG9hZC5yb3dUb1BhY2tldFRyYW5zZm9ybS5lbmQoKTtcbiAgICB9XG5cbiAgICBjb25zdCBvbkNhbmNlbCA9ICgpID0+IHtcbiAgICAgIHJlcXVlc3QuY2FuY2VsKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgQnVsa0xvYWRQYXlsb2FkKGJ1bGtMb2FkKTtcblxuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdChidWxrTG9hZC5nZXRCdWxrSW5zZXJ0U3FsKCksIChlcnJvcjogKEVycm9yICYgeyBjb2RlPzogc3RyaW5nIH0pIHwgbnVsbCB8IHVuZGVmaW5lZCkgPT4ge1xuICAgICAgYnVsa0xvYWQucmVtb3ZlTGlzdGVuZXIoJ2NhbmNlbCcsIG9uQ2FuY2VsKTtcblxuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAnVU5LTk9XTicpIHtcbiAgICAgICAgICBlcnJvci5tZXNzYWdlICs9ICcgVGhpcyBpcyBsaWtlbHkgYmVjYXVzZSB0aGUgc2NoZW1hIG9mIHRoZSBCdWxrTG9hZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2NoZW1hIG9mIHRoZSB0YWJsZSB5b3UgYXJlIGF0dGVtcHRpbmcgdG8gaW5zZXJ0IGludG8uJztcbiAgICAgICAgfVxuICAgICAgICBidWxrTG9hZC5lcnJvciA9IGVycm9yO1xuICAgICAgICBidWxrTG9hZC5jYWxsYmFjayhlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5tYWtlUmVxdWVzdChidWxrTG9hZCwgVFlQRS5CVUxLX0xPQUQsIHBheWxvYWQpO1xuICAgIH0pO1xuXG4gICAgYnVsa0xvYWQub25jZSgnY2FuY2VsJywgb25DYW5jZWwpO1xuXG4gICAgdGhpcy5leGVjU3FsQmF0Y2gocmVxdWVzdCk7XG4gIH1cblxuICAvKipcbiAgICogUHJlcGFyZSB0aGUgU1FMIHJlcHJlc2VudGVkIGJ5IHRoZSByZXF1ZXN0LlxuICAgKlxuICAgKiBUaGUgcmVxdWVzdCBjYW4gdGhlbiBiZSB1c2VkIGluIHN1YnNlcXVlbnQgY2FsbHMgdG9cbiAgICogW1tleGVjdXRlXV0gYW5kIFtbdW5wcmVwYXJlXV1cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3QgQSBbW1JlcXVlc3RdXSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSByZXF1ZXN0LlxuICAgKiAgIFBhcmFtZXRlcnMgb25seSByZXF1aXJlIGEgbmFtZSBhbmQgdHlwZS4gUGFyYW1ldGVyIHZhbHVlcyBhcmUgaWdub3JlZC5cbiAgICovXG4gIHByZXBhcmUocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIGNvbnN0IHBhcmFtZXRlcnM6IFBhcmFtZXRlcltdID0gW107XG5cbiAgICBwYXJhbWV0ZXJzLnB1c2goe1xuICAgICAgdHlwZTogVFlQRVMuSW50LFxuICAgICAgbmFtZTogJ2hhbmRsZScsXG4gICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgb3V0cHV0OiB0cnVlLFxuICAgICAgbGVuZ3RoOiB1bmRlZmluZWQsXG4gICAgICBwcmVjaXNpb246IHVuZGVmaW5lZCxcbiAgICAgIHNjYWxlOiB1bmRlZmluZWRcbiAgICB9KTtcblxuICAgIHBhcmFtZXRlcnMucHVzaCh7XG4gICAgICB0eXBlOiBUWVBFUy5OVmFyQ2hhcixcbiAgICAgIG5hbWU6ICdwYXJhbXMnLFxuICAgICAgdmFsdWU6IHJlcXVlc3QucGFyYW1ldGVycy5sZW5ndGggPyByZXF1ZXN0Lm1ha2VQYXJhbXNQYXJhbWV0ZXIocmVxdWVzdC5wYXJhbWV0ZXJzKSA6IG51bGwsXG4gICAgICBvdXRwdXQ6IGZhbHNlLFxuICAgICAgbGVuZ3RoOiB1bmRlZmluZWQsXG4gICAgICBwcmVjaXNpb246IHVuZGVmaW5lZCxcbiAgICAgIHNjYWxlOiB1bmRlZmluZWRcbiAgICB9KTtcblxuICAgIHBhcmFtZXRlcnMucHVzaCh7XG4gICAgICB0eXBlOiBUWVBFUy5OVmFyQ2hhcixcbiAgICAgIG5hbWU6ICdzdG10JyxcbiAgICAgIHZhbHVlOiByZXF1ZXN0LnNxbFRleHRPclByb2NlZHVyZSxcbiAgICAgIG91dHB1dDogZmFsc2UsXG4gICAgICBsZW5ndGg6IHVuZGVmaW5lZCxcbiAgICAgIHByZWNpc2lvbjogdW5kZWZpbmVkLFxuICAgICAgc2NhbGU6IHVuZGVmaW5lZFxuICAgIH0pO1xuXG4gICAgcmVxdWVzdC5wcmVwYXJpbmcgPSB0cnVlO1xuXG4gICAgLy8gVE9ETzogV2UgbmVlZCB0byBjbGVhbiB1cCB0aGlzIGV2ZW50IGhhbmRsZXIsIG90aGVyd2lzZSB0aGlzIGxlYWtzIG1lbW9yeVxuICAgIHJlcXVlc3Qub24oJ3JldHVyblZhbHVlJywgKG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgaWYgKG5hbWUgPT09ICdoYW5kbGUnKSB7XG4gICAgICAgIHJlcXVlc3QuaGFuZGxlID0gdmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXF1ZXN0LmVycm9yID0gbmV3IFJlcXVlc3RFcnJvcihgVGVkaW91cyA+IFVuZXhwZWN0ZWQgb3V0cHV0IHBhcmFtZXRlciAke25hbWV9IGZyb20gc3BfcHJlcGFyZWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5tYWtlUmVxdWVzdChyZXF1ZXN0LCBUWVBFLlJQQ19SRVFVRVNULCBuZXcgUnBjUmVxdWVzdFBheWxvYWQoUHJvY2VkdXJlcy5TcF9QcmVwYXJlLCBwYXJhbWV0ZXJzLCB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbkRlc2NyaXB0b3IoKSwgdGhpcy5jb25maWcub3B0aW9ucywgdGhpcy5kYXRhYmFzZUNvbGxhdGlvbikpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGVhc2UgdGhlIFNRTCBTZXJ2ZXIgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCBhIHByZXZpb3VzbHkgcHJlcGFyZWQgcmVxdWVzdC5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3QgQSBbW1JlcXVlc3RdXSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSByZXF1ZXN0LlxuICAgKiAgIFBhcmFtZXRlcnMgb25seSByZXF1aXJlIGEgbmFtZSBhbmQgdHlwZS5cbiAgICogICBQYXJhbWV0ZXIgdmFsdWVzIGFyZSBpZ25vcmVkLlxuICAgKi9cbiAgdW5wcmVwYXJlKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICBjb25zdCBwYXJhbWV0ZXJzOiBQYXJhbWV0ZXJbXSA9IFtdO1xuXG4gICAgcGFyYW1ldGVycy5wdXNoKHtcbiAgICAgIHR5cGU6IFRZUEVTLkludCxcbiAgICAgIG5hbWU6ICdoYW5kbGUnLFxuICAgICAgLy8gVE9ETzogQWJvcnQgaWYgYHJlcXVlc3QuaGFuZGxlYCBpcyBub3Qgc2V0XG4gICAgICB2YWx1ZTogcmVxdWVzdC5oYW5kbGUsXG4gICAgICBvdXRwdXQ6IGZhbHNlLFxuICAgICAgbGVuZ3RoOiB1bmRlZmluZWQsXG4gICAgICBwcmVjaXNpb246IHVuZGVmaW5lZCxcbiAgICAgIHNjYWxlOiB1bmRlZmluZWRcbiAgICB9KTtcblxuICAgIHRoaXMubWFrZVJlcXVlc3QocmVxdWVzdCwgVFlQRS5SUENfUkVRVUVTVCwgbmV3IFJwY1JlcXVlc3RQYXlsb2FkKFByb2NlZHVyZXMuU3BfVW5wcmVwYXJlLCBwYXJhbWV0ZXJzLCB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbkRlc2NyaXB0b3IoKSwgdGhpcy5jb25maWcub3B0aW9ucywgdGhpcy5kYXRhYmFzZUNvbGxhdGlvbikpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgcHJldmlvdXNseSBwcmVwYXJlZCBTUUwsIHVzaW5nIHRoZSBzdXBwbGllZCBwYXJhbWV0ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdCBBIHByZXZpb3VzbHkgcHJlcGFyZWQgW1tSZXF1ZXN0XV0uXG4gICAqIEBwYXJhbSBwYXJhbWV0ZXJzICBBbiBvYmplY3Qgd2hvc2UgbmFtZXMgY29ycmVzcG9uZCB0byB0aGUgbmFtZXMgb2ZcbiAgICogICBwYXJhbWV0ZXJzIHRoYXQgd2VyZSBhZGRlZCB0byB0aGUgW1tSZXF1ZXN0XV0gYmVmb3JlIGl0IHdhcyBwcmVwYXJlZC5cbiAgICogICBUaGUgb2JqZWN0J3MgdmFsdWVzIGFyZSBwYXNzZWQgYXMgdGhlIHBhcmFtZXRlcnMnIHZhbHVlcyB3aGVuIHRoZVxuICAgKiAgIHJlcXVlc3QgaXMgZXhlY3V0ZWQuXG4gICAqL1xuICBleGVjdXRlKHJlcXVlc3Q6IFJlcXVlc3QsIHBhcmFtZXRlcnM/OiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSkge1xuICAgIGNvbnN0IGV4ZWN1dGVQYXJhbWV0ZXJzOiBQYXJhbWV0ZXJbXSA9IFtdO1xuXG4gICAgZXhlY3V0ZVBhcmFtZXRlcnMucHVzaCh7XG4gICAgICB0eXBlOiBUWVBFUy5JbnQsXG4gICAgICBuYW1lOiAnJyxcbiAgICAgIC8vIFRPRE86IEFib3J0IGlmIGByZXF1ZXN0LmhhbmRsZWAgaXMgbm90IHNldFxuICAgICAgdmFsdWU6IHJlcXVlc3QuaGFuZGxlLFxuICAgICAgb3V0cHV0OiBmYWxzZSxcbiAgICAgIGxlbmd0aDogdW5kZWZpbmVkLFxuICAgICAgcHJlY2lzaW9uOiB1bmRlZmluZWQsXG4gICAgICBzY2FsZTogdW5kZWZpbmVkXG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHJlcXVlc3QucGFyYW1ldGVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXIgPSByZXF1ZXN0LnBhcmFtZXRlcnNbaV07XG5cbiAgICAgICAgZXhlY3V0ZVBhcmFtZXRlcnMucHVzaCh7XG4gICAgICAgICAgLi4ucGFyYW1ldGVyLFxuICAgICAgICAgIHZhbHVlOiBwYXJhbWV0ZXIudHlwZS52YWxpZGF0ZShwYXJhbWV0ZXJzID8gcGFyYW1ldGVyc1twYXJhbWV0ZXIubmFtZV0gOiBudWxsLCB0aGlzLmRhdGFiYXNlQ29sbGF0aW9uKVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXF1ZXN0LmVycm9yID0gZXJyb3I7XG5cbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICB0aGlzLmRlYnVnLmxvZyhlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgcmVxdWVzdC5jYWxsYmFjayhlcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubWFrZVJlcXVlc3QocmVxdWVzdCwgVFlQRS5SUENfUkVRVUVTVCwgbmV3IFJwY1JlcXVlc3RQYXlsb2FkKFByb2NlZHVyZXMuU3BfRXhlY3V0ZSwgZXhlY3V0ZVBhcmFtZXRlcnMsIHRoaXMuY3VycmVudFRyYW5zYWN0aW9uRGVzY3JpcHRvcigpLCB0aGlzLmNvbmZpZy5vcHRpb25zLCB0aGlzLmRhdGFiYXNlQ29sbGF0aW9uKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbCBhIHN0b3JlZCBwcm9jZWR1cmUgcmVwcmVzZW50ZWQgYnkgW1tSZXF1ZXN0XV0uXG4gICAqXG4gICAqIEBwYXJhbSByZXF1ZXN0IEEgW1tSZXF1ZXN0XV0gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgcmVxdWVzdC5cbiAgICovXG4gIGNhbGxQcm9jZWR1cmUocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRyeSB7XG4gICAgICByZXF1ZXN0LnZhbGlkYXRlUGFyYW1ldGVycyh0aGlzLmRhdGFiYXNlQ29sbGF0aW9uKTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXF1ZXN0LmVycm9yID0gZXJyb3I7XG5cbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICB0aGlzLmRlYnVnLmxvZyhlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgcmVxdWVzdC5jYWxsYmFjayhlcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubWFrZVJlcXVlc3QocmVxdWVzdCwgVFlQRS5SUENfUkVRVUVTVCwgbmV3IFJwY1JlcXVlc3RQYXlsb2FkKHJlcXVlc3Quc3FsVGV4dE9yUHJvY2VkdXJlISwgcmVxdWVzdC5wYXJhbWV0ZXJzLCB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbkRlc2NyaXB0b3IoKSwgdGhpcy5jb25maWcub3B0aW9ucywgdGhpcy5kYXRhYmFzZUNvbGxhdGlvbikpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IGEgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBjYWxsYmFja1xuICAgKiBAcGFyYW0gbmFtZSBBIHN0cmluZyByZXByZXNlbnRpbmcgYSBuYW1lIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0cmFuc2FjdGlvbi5cbiAgICogICBPcHRpb25hbCwgYW5kIGRlZmF1bHRzIHRvIGFuIGVtcHR5IHN0cmluZy4gUmVxdWlyZWQgd2hlbiBgaXNvbGF0aW9uTGV2ZWxgXG4gICAqICAgaXMgcHJlc2VudC5cbiAgICogQHBhcmFtIGlzb2xhdGlvbkxldmVsIFRoZSBpc29sYXRpb24gbGV2ZWwgdGhhdCB0aGUgdHJhbnNhY3Rpb24gaXMgdG8gYmUgcnVuIHdpdGguXG4gICAqXG4gICAqICAgVGhlIGlzb2xhdGlvbiBsZXZlbHMgYXJlIGF2YWlsYWJsZSBmcm9tIGByZXF1aXJlKCd0ZWRpb3VzJykuSVNPTEFUSU9OX0xFVkVMYC5cbiAgICogICAqIGBSRUFEX1VOQ09NTUlUVEVEYFxuICAgKiAgICogYFJFQURfQ09NTUlUVEVEYFxuICAgKiAgICogYFJFUEVBVEFCTEVfUkVBRGBcbiAgICogICAqIGBTRVJJQUxJWkFCTEVgXG4gICAqICAgKiBgU05BUFNIT1RgXG4gICAqXG4gICAqICAgT3B0aW9uYWwsIGFuZCBkZWZhdWx0cyB0byB0aGUgQ29ubmVjdGlvbidzIGlzb2xhdGlvbiBsZXZlbC5cbiAgICovXG4gIGJlZ2luVHJhbnNhY3Rpb24oY2FsbGJhY2s6IEJlZ2luVHJhbnNhY3Rpb25DYWxsYmFjaywgbmFtZSA9ICcnLCBpc29sYXRpb25MZXZlbCA9IHRoaXMuY29uZmlnLm9wdGlvbnMuaXNvbGF0aW9uTGV2ZWwpIHtcbiAgICBhc3NlcnRWYWxpZElzb2xhdGlvbkxldmVsKGlzb2xhdGlvbkxldmVsLCAnaXNvbGF0aW9uTGV2ZWwnKTtcblxuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKG5hbWUsIGlzb2xhdGlvbkxldmVsKTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLnRkc1ZlcnNpb24gPCAnN18yJykge1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY1NxbEJhdGNoKG5ldyBSZXF1ZXN0KCdTRVQgVFJBTlNBQ1RJT04gSVNPTEFUSU9OIExFVkVMICcgKyAodHJhbnNhY3Rpb24uaXNvbGF0aW9uTGV2ZWxUb1RTUUwoKSkgKyAnO0JFR0lOIFRSQU4gJyArIHRyYW5zYWN0aW9uLm5hbWUsIChlcnIpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRlcHRoKys7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRGVwdGggPT09IDEpIHtcbiAgICAgICAgICB0aGlzLmluVHJhbnNhY3Rpb24gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KHVuZGVmaW5lZCwgKGVycikgPT4ge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgdGhpcy5jdXJyZW50VHJhbnNhY3Rpb25EZXNjcmlwdG9yKCkpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLm1ha2VSZXF1ZXN0KHJlcXVlc3QsIFRZUEUuVFJBTlNBQ1RJT05fTUFOQUdFUiwgdHJhbnNhY3Rpb24uYmVnaW5QYXlsb2FkKHRoaXMuY3VycmVudFRyYW5zYWN0aW9uRGVzY3JpcHRvcigpKSk7XG4gIH1cblxuICAvKipcbiAgICogQ29tbWl0IGEgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIFRoZXJlIHNob3VsZCBiZSBhbiBhY3RpdmUgdHJhbnNhY3Rpb24gLSB0aGF0IGlzLCBbW2JlZ2luVHJhbnNhY3Rpb25dXVxuICAgKiBzaG91bGQgaGF2ZSBiZWVuIHByZXZpb3VzbHkgY2FsbGVkLlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2tcbiAgICogQHBhcmFtIG5hbWUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgbmFtZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgdHJhbnNhY3Rpb24uXG4gICAqICAgT3B0aW9uYWwsIGFuZCBkZWZhdWx0cyB0byBhbiBlbXB0eSBzdHJpbmcuIFJlcXVpcmVkIHdoZW4gYGlzb2xhdGlvbkxldmVsYGlzIHByZXNlbnQuXG4gICAqL1xuICBjb21taXRUcmFuc2FjdGlvbihjYWxsYmFjazogQ29tbWl0VHJhbnNhY3Rpb25DYWxsYmFjaywgbmFtZSA9ICcnKSB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24obmFtZSk7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMudGRzVmVyc2lvbiA8ICc3XzInKSB7XG4gICAgICByZXR1cm4gdGhpcy5leGVjU3FsQmF0Y2gobmV3IFJlcXVlc3QoJ0NPTU1JVCBUUkFOICcgKyB0cmFuc2FjdGlvbi5uYW1lLCAoZXJyKSA9PiB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25EZXB0aC0tO1xuICAgICAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRlcHRoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5pblRyYW5zYWN0aW9uID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgfSkpO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IFJlcXVlc3QodW5kZWZpbmVkLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMubWFrZVJlcXVlc3QocmVxdWVzdCwgVFlQRS5UUkFOU0FDVElPTl9NQU5BR0VSLCB0cmFuc2FjdGlvbi5jb21taXRQYXlsb2FkKHRoaXMuY3VycmVudFRyYW5zYWN0aW9uRGVzY3JpcHRvcigpKSk7XG4gIH1cblxuICAvKipcbiAgICogUm9sbGJhY2sgYSB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogVGhlcmUgc2hvdWxkIGJlIGFuIGFjdGl2ZSB0cmFuc2FjdGlvbiAtIHRoYXQgaXMsIFtbYmVnaW5UcmFuc2FjdGlvbl1dXG4gICAqIHNob3VsZCBoYXZlIGJlZW4gcHJldmlvdXNseSBjYWxsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBjYWxsYmFja1xuICAgKiBAcGFyYW0gbmFtZSBBIHN0cmluZyByZXByZXNlbnRpbmcgYSBuYW1lIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0cmFuc2FjdGlvbi5cbiAgICogICBPcHRpb25hbCwgYW5kIGRlZmF1bHRzIHRvIGFuIGVtcHR5IHN0cmluZy5cbiAgICogICBSZXF1aXJlZCB3aGVuIGBpc29sYXRpb25MZXZlbGAgaXMgcHJlc2VudC5cbiAgICovXG4gIHJvbGxiYWNrVHJhbnNhY3Rpb24oY2FsbGJhY2s6IFJvbGxiYWNrVHJhbnNhY3Rpb25DYWxsYmFjaywgbmFtZSA9ICcnKSB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24obmFtZSk7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMudGRzVmVyc2lvbiA8ICc3XzInKSB7XG4gICAgICByZXR1cm4gdGhpcy5leGVjU3FsQmF0Y2gobmV3IFJlcXVlc3QoJ1JPTExCQUNLIFRSQU4gJyArIHRyYW5zYWN0aW9uLm5hbWUsIChlcnIpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRlcHRoLS07XG4gICAgICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRGVwdGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLmluVHJhbnNhY3Rpb24gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgfSkpO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IFJlcXVlc3QodW5kZWZpbmVkLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMubWFrZVJlcXVlc3QocmVxdWVzdCwgVFlQRS5UUkFOU0FDVElPTl9NQU5BR0VSLCB0cmFuc2FjdGlvbi5yb2xsYmFja1BheWxvYWQodGhpcy5jdXJyZW50VHJhbnNhY3Rpb25EZXNjcmlwdG9yKCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBzYXZlcG9pbnQgd2l0aGluIGEgdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIFRoZXJlIHNob3VsZCBiZSBhbiBhY3RpdmUgdHJhbnNhY3Rpb24gLSB0aGF0IGlzLCBbW2JlZ2luVHJhbnNhY3Rpb25dXVxuICAgKiBzaG91bGQgaGF2ZSBiZWVuIHByZXZpb3VzbHkgY2FsbGVkLlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2tcbiAgICogQHBhcmFtIG5hbWUgQSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgbmFtZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgdHJhbnNhY3Rpb24uXFxcbiAgICogICBPcHRpb25hbCwgYW5kIGRlZmF1bHRzIHRvIGFuIGVtcHR5IHN0cmluZy5cbiAgICogICBSZXF1aXJlZCB3aGVuIGBpc29sYXRpb25MZXZlbGAgaXMgcHJlc2VudC5cbiAgICovXG4gIHNhdmVUcmFuc2FjdGlvbihjYWxsYmFjazogU2F2ZVRyYW5zYWN0aW9uQ2FsbGJhY2ssIG5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKG5hbWUpO1xuICAgIGlmICh0aGlzLmNvbmZpZy5vcHRpb25zLnRkc1ZlcnNpb24gPCAnN18yJykge1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY1NxbEJhdGNoKG5ldyBSZXF1ZXN0KCdTQVZFIFRSQU4gJyArIHRyYW5zYWN0aW9uLm5hbWUsIChlcnIpID0+IHtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRlcHRoKys7XG4gICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICB9KSk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdCh1bmRlZmluZWQsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy5tYWtlUmVxdWVzdChyZXF1ZXN0LCBUWVBFLlRSQU5TQUNUSU9OX01BTkFHRVIsIHRyYW5zYWN0aW9uLnNhdmVQYXlsb2FkKHRoaXMuY3VycmVudFRyYW5zYWN0aW9uRGVzY3JpcHRvcigpKSk7XG4gIH1cblxuICAvKipcbiAgICogUnVuIHRoZSBnaXZlbiBjYWxsYmFjayBhZnRlciBzdGFydGluZyBhIHRyYW5zYWN0aW9uLCBhbmQgY29tbWl0IG9yXG4gICAqIHJvbGxiYWNrIHRoZSB0cmFuc2FjdGlvbiBhZnRlcndhcmRzLlxuICAgKlxuICAgKiBUaGlzIGlzIGEgaGVscGVyIHRoYXQgZW1wbG95cyBbW2JlZ2luVHJhbnNhY3Rpb25dXSwgW1tjb21taXRUcmFuc2FjdGlvbl1dLFxuICAgKiBbW3JvbGxiYWNrVHJhbnNhY3Rpb25dXSwgYW5kIFtbc2F2ZVRyYW5zYWN0aW9uXV0gdG8gZ3JlYXRseSBzaW1wbGlmeSB0aGVcbiAgICogdXNlIG9mIGRhdGFiYXNlIHRyYW5zYWN0aW9ucyBhbmQgYXV0b21hdGljYWxseSBoYW5kbGUgdHJhbnNhY3Rpb24gbmVzdGluZy5cbiAgICpcbiAgICogQHBhcmFtIGNiXG4gICAqIEBwYXJhbSBpc29sYXRpb25MZXZlbFxuICAgKiAgIFRoZSBpc29sYXRpb24gbGV2ZWwgdGhhdCB0aGUgdHJhbnNhY3Rpb24gaXMgdG8gYmUgcnVuIHdpdGguXG4gICAqXG4gICAqICAgVGhlIGlzb2xhdGlvbiBsZXZlbHMgYXJlIGF2YWlsYWJsZSBmcm9tIGByZXF1aXJlKCd0ZWRpb3VzJykuSVNPTEFUSU9OX0xFVkVMYC5cbiAgICogICAqIGBSRUFEX1VOQ09NTUlUVEVEYFxuICAgKiAgICogYFJFQURfQ09NTUlUVEVEYFxuICAgKiAgICogYFJFUEVBVEFCTEVfUkVBRGBcbiAgICogICAqIGBTRVJJQUxJWkFCTEVgXG4gICAqICAgKiBgU05BUFNIT1RgXG4gICAqXG4gICAqICAgT3B0aW9uYWwsIGFuZCBkZWZhdWx0cyB0byB0aGUgQ29ubmVjdGlvbidzIGlzb2xhdGlvbiBsZXZlbC5cbiAgICovXG4gIHRyYW5zYWN0aW9uKGNiOiAoZXJyOiBFcnJvciB8IG51bGwgfCB1bmRlZmluZWQsIHR4RG9uZT86IDxUIGV4dGVuZHMgVHJhbnNhY3Rpb25Eb25lQ2FsbGJhY2s+KGVycjogRXJyb3IgfCBudWxsIHwgdW5kZWZpbmVkLCBkb25lOiBULCAuLi5hcmdzOiBDYWxsYmFja1BhcmFtZXRlcnM8VD4pID0+IHZvaWQpID0+IHZvaWQsIGlzb2xhdGlvbkxldmVsPzogdHlwZW9mIElTT0xBVElPTl9MRVZFTFtrZXlvZiB0eXBlb2YgSVNPTEFUSU9OX0xFVkVMXSkge1xuICAgIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2BjYmAgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlU2F2ZXBvaW50ID0gdGhpcy5pblRyYW5zYWN0aW9uO1xuICAgIGNvbnN0IG5hbWUgPSAnX3RlZGlvdXNfJyArIChjcnlwdG8ucmFuZG9tQnl0ZXMoMTApLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgY29uc3QgdHhEb25lOiA8VCBleHRlbmRzIFRyYW5zYWN0aW9uRG9uZUNhbGxiYWNrPihlcnI6IEVycm9yIHwgbnVsbCB8IHVuZGVmaW5lZCwgZG9uZTogVCwgLi4uYXJnczogQ2FsbGJhY2tQYXJhbWV0ZXJzPFQ+KSA9PiB2b2lkID0gKGVyciwgZG9uZSwgLi4uYXJncykgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBpZiAodGhpcy5pblRyYW5zYWN0aW9uICYmIHRoaXMuc3RhdGUgPT09IHRoaXMuU1RBVEUuTE9HR0VEX0lOKSB7XG4gICAgICAgICAgdGhpcy5yb2xsYmFja1RyYW5zYWN0aW9uKCh0eEVycikgPT4ge1xuICAgICAgICAgICAgZG9uZSh0eEVyciB8fCBlcnIsIC4uLmFyZ3MpO1xuICAgICAgICAgIH0sIG5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRvbmUoZXJyLCAuLi5hcmdzKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh1c2VTYXZlcG9pbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMudGRzVmVyc2lvbiA8ICc3XzInKSB7XG4gICAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRlcHRoLS07XG4gICAgICAgIH1cbiAgICAgICAgZG9uZShudWxsLCAuLi5hcmdzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY29tbWl0VHJhbnNhY3Rpb24oKHR4RXJyKSA9PiB7XG4gICAgICAgICAgZG9uZSh0eEVyciwgLi4uYXJncyk7XG4gICAgICAgIH0sIG5hbWUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAodXNlU2F2ZXBvaW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5zYXZlVHJhbnNhY3Rpb24oKGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIGNiKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNvbGF0aW9uTGV2ZWwpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5leGVjU3FsQmF0Y2gobmV3IFJlcXVlc3QoJ1NFVCB0cmFuc2FjdGlvbiBpc29sYXRpb24gbGV2ZWwgJyArIHRoaXMuZ2V0SXNvbGF0aW9uTGV2ZWxUZXh0KGlzb2xhdGlvbkxldmVsKSwgKGVycikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGNiKGVyciwgdHhEb25lKTtcbiAgICAgICAgICB9KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGNiKG51bGwsIHR4RG9uZSk7XG4gICAgICAgIH1cbiAgICAgIH0sIG5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5iZWdpblRyYW5zYWN0aW9uKChlcnIpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiBjYihlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNiKG51bGwsIHR4RG9uZSk7XG4gICAgICB9LCBuYW1lLCBpc29sYXRpb25MZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBtYWtlUmVxdWVzdChyZXF1ZXN0OiBSZXF1ZXN0IHwgQnVsa0xvYWQsIHBhY2tldFR5cGU6IG51bWJlciwgcGF5bG9hZDogKEl0ZXJhYmxlPEJ1ZmZlcj4gfCBBc3luY0l0ZXJhYmxlPEJ1ZmZlcj4pICYgeyB0b1N0cmluZzogKGluZGVudD86IHN0cmluZykgPT4gc3RyaW5nIH0pIHtcbiAgICBpZiAodGhpcy5zdGF0ZSAhPT0gdGhpcy5TVEFURS5MT0dHRURfSU4pIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSAnUmVxdWVzdHMgY2FuIG9ubHkgYmUgbWFkZSBpbiB0aGUgJyArIHRoaXMuU1RBVEUuTE9HR0VEX0lOLm5hbWUgKyAnIHN0YXRlLCBub3QgdGhlICcgKyB0aGlzLnN0YXRlLm5hbWUgKyAnIHN0YXRlJztcbiAgICAgIHRoaXMuZGVidWcubG9nKG1lc3NhZ2UpO1xuICAgICAgcmVxdWVzdC5jYWxsYmFjayhuZXcgUmVxdWVzdEVycm9yKG1lc3NhZ2UsICdFSU5WQUxJRFNUQVRFJykpO1xuICAgIH0gZWxzZSBpZiAocmVxdWVzdC5jYW5jZWxlZCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICAgIHJlcXVlc3QuY2FsbGJhY2sobmV3IFJlcXVlc3RFcnJvcignQ2FuY2VsZWQuJywgJ0VDQU5DRUwnKSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHBhY2tldFR5cGUgPT09IFRZUEUuU1FMX0JBVENIKSB7XG4gICAgICAgIHRoaXMuaXNTcWxCYXRjaCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmlzU3FsQmF0Y2ggPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICAgIHJlcXVlc3QuY29ubmVjdGlvbiEgPSB0aGlzO1xuICAgICAgcmVxdWVzdC5yb3dDb3VudCEgPSAwO1xuICAgICAgcmVxdWVzdC5yb3dzISA9IFtdO1xuICAgICAgcmVxdWVzdC5yc3QhID0gW107XG5cbiAgICAgIGNvbnN0IG9uQ2FuY2VsID0gKCkgPT4ge1xuICAgICAgICBwYXlsb2FkU3RyZWFtLnVucGlwZShtZXNzYWdlKTtcbiAgICAgICAgcGF5bG9hZFN0cmVhbS5kZXN0cm95KG5ldyBSZXF1ZXN0RXJyb3IoJ0NhbmNlbGVkLicsICdFQ0FOQ0VMJykpO1xuXG4gICAgICAgIC8vIHNldCB0aGUgaWdub3JlIGJpdCBhbmQgZW5kIHRoZSBtZXNzYWdlLlxuICAgICAgICBtZXNzYWdlLmlnbm9yZSA9IHRydWU7XG4gICAgICAgIG1lc3NhZ2UuZW5kKCk7XG5cbiAgICAgICAgaWYgKHJlcXVlc3QgaW5zdGFuY2VvZiBSZXF1ZXN0ICYmIHJlcXVlc3QucGF1c2VkKSB7XG4gICAgICAgICAgLy8gcmVzdW1lIHRoZSByZXF1ZXN0IGlmIGl0IHdhcyBwYXVzZWQgc28gd2UgY2FuIHJlYWQgdGhlIHJlbWFpbmluZyB0b2tlbnNcbiAgICAgICAgICByZXF1ZXN0LnJlc3VtZSgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICByZXF1ZXN0Lm9uY2UoJ2NhbmNlbCcsIG9uQ2FuY2VsKTtcblxuICAgICAgdGhpcy5jcmVhdGVSZXF1ZXN0VGltZXIoKTtcblxuICAgICAgY29uc3QgbWVzc2FnZSA9IG5ldyBNZXNzYWdlKHsgdHlwZTogcGFja2V0VHlwZSwgcmVzZXRDb25uZWN0aW9uOiB0aGlzLnJlc2V0Q29ubmVjdGlvbk9uTmV4dFJlcXVlc3QgfSk7XG4gICAgICB0aGlzLm1lc3NhZ2VJby5vdXRnb2luZ01lc3NhZ2VTdHJlYW0ud3JpdGUobWVzc2FnZSk7XG4gICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLlNFTlRfQ0xJRU5UX1JFUVVFU1QpO1xuXG4gICAgICBtZXNzYWdlLm9uY2UoJ2ZpbmlzaCcsICgpID0+IHtcbiAgICAgICAgcmVxdWVzdC5yZW1vdmVMaXN0ZW5lcignY2FuY2VsJywgb25DYW5jZWwpO1xuICAgICAgICByZXF1ZXN0Lm9uY2UoJ2NhbmNlbCcsIHRoaXMuX2NhbmNlbEFmdGVyUmVxdWVzdFNlbnQpO1xuXG4gICAgICAgIHRoaXMucmVzZXRDb25uZWN0aW9uT25OZXh0UmVxdWVzdCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmRlYnVnLnBheWxvYWQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIHBheWxvYWQhLnRvU3RyaW5nKCcgICcpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwYXlsb2FkU3RyZWFtID0gUmVhZGFibGUuZnJvbShwYXlsb2FkKTtcbiAgICAgIHBheWxvYWRTdHJlYW0ub25jZSgnZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgICAgcGF5bG9hZFN0cmVhbS51bnBpcGUobWVzc2FnZSk7XG5cbiAgICAgICAgLy8gT25seSBzZXQgYSByZXF1ZXN0IGVycm9yIGlmIG5vIGVycm9yIHdhcyBzZXQgeWV0LlxuICAgICAgICByZXF1ZXN0LmVycm9yID8/PSBlcnJvcjtcblxuICAgICAgICBtZXNzYWdlLmlnbm9yZSA9IHRydWU7XG4gICAgICAgIG1lc3NhZ2UuZW5kKCk7XG4gICAgICB9KTtcbiAgICAgIHBheWxvYWRTdHJlYW0ucGlwZShtZXNzYWdlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VsIGN1cnJlbnRseSBleGVjdXRlZCByZXF1ZXN0LlxuICAgKi9cbiAgY2FuY2VsKCkge1xuICAgIGlmICghdGhpcy5yZXF1ZXN0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVxdWVzdC5jYW5jZWxlZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMucmVxdWVzdC5jYW5jZWwoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldCB0aGUgY29ubmVjdGlvbiB0byBpdHMgaW5pdGlhbCBzdGF0ZS5cbiAgICogQ2FuIGJlIHVzZWZ1bCBmb3IgY29ubmVjdGlvbiBwb29sIGltcGxlbWVudGF0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrXG4gICAqL1xuICByZXNldChjYWxsYmFjazogUmVzZXRDYWxsYmFjaykge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdCh0aGlzLmdldEluaXRpYWxTcWwoKSwgKGVycikgPT4ge1xuICAgICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMudGRzVmVyc2lvbiA8ICc3XzInKSB7XG4gICAgICAgIHRoaXMuaW5UcmFuc2FjdGlvbiA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICB9KTtcbiAgICB0aGlzLnJlc2V0Q29ubmVjdGlvbk9uTmV4dFJlcXVlc3QgPSB0cnVlO1xuICAgIHRoaXMuZXhlY1NxbEJhdGNoKHJlcXVlc3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjdXJyZW50VHJhbnNhY3Rpb25EZXNjcmlwdG9yKCkge1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uRGVzY3JpcHRvcnNbdGhpcy50cmFuc2FjdGlvbkRlc2NyaXB0b3JzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBnZXRJc29sYXRpb25MZXZlbFRleHQoaXNvbGF0aW9uTGV2ZWw6IHR5cGVvZiBJU09MQVRJT05fTEVWRUxba2V5b2YgdHlwZW9mIElTT0xBVElPTl9MRVZFTF0pIHtcbiAgICBzd2l0Y2ggKGlzb2xhdGlvbkxldmVsKSB7XG4gICAgICBjYXNlIElTT0xBVElPTl9MRVZFTC5SRUFEX1VOQ09NTUlUVEVEOlxuICAgICAgICByZXR1cm4gJ3JlYWQgdW5jb21taXR0ZWQnO1xuICAgICAgY2FzZSBJU09MQVRJT05fTEVWRUwuUkVQRUFUQUJMRV9SRUFEOlxuICAgICAgICByZXR1cm4gJ3JlcGVhdGFibGUgcmVhZCc7XG4gICAgICBjYXNlIElTT0xBVElPTl9MRVZFTC5TRVJJQUxJWkFCTEU6XG4gICAgICAgIHJldHVybiAnc2VyaWFsaXphYmxlJztcbiAgICAgIGNhc2UgSVNPTEFUSU9OX0xFVkVMLlNOQVBTSE9UOlxuICAgICAgICByZXR1cm4gJ3NuYXBzaG90JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAncmVhZCBjb21taXR0ZWQnO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpc1RyYW5zaWVudEVycm9yKGVycm9yOiBBZ2dyZWdhdGVFcnJvciB8IENvbm5lY3Rpb25FcnJvcik6IGJvb2xlYW4ge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBZ2dyZWdhdGVFcnJvcikge1xuICAgIGVycm9yID0gZXJyb3IuZXJyb3JzWzBdO1xuICB9XG4gIHJldHVybiAoZXJyb3IgaW5zdGFuY2VvZiBDb25uZWN0aW9uRXJyb3IpICYmICEhZXJyb3IuaXNUcmFuc2llbnQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IENvbm5lY3Rpb247XG5tb2R1bGUuZXhwb3J0cyA9IENvbm5lY3Rpb247XG5cbkNvbm5lY3Rpb24ucHJvdG90eXBlLlNUQVRFID0ge1xuICBJTklUSUFMSVpFRDoge1xuICAgIG5hbWU6ICdJbml0aWFsaXplZCcsXG4gICAgZXZlbnRzOiB7fVxuICB9LFxuICBDT05ORUNUSU5HOiB7XG4gICAgbmFtZTogJ0Nvbm5lY3RpbmcnLFxuICAgIGVudGVyOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGlzZUNvbm5lY3Rpb24oKTtcbiAgICB9LFxuICAgIGV2ZW50czoge1xuICAgICAgc29ja2V0RXJyb3I6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcbiAgICAgIH0sXG4gICAgICBjb25uZWN0VGltZW91dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgU0VOVF9QUkVMT0dJTjoge1xuICAgIG5hbWU6ICdTZW50UHJlbG9naW4nLFxuICAgIGVudGVyOiBmdW5jdGlvbigpIHtcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGxldCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmFsbG9jKDApO1xuXG4gICAgICAgIGxldCBtZXNzYWdlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIG1lc3NhZ2UgPSBhd2FpdCB0aGlzLm1lc3NhZ2VJby5yZWFkTWVzc2FnZSgpO1xuICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnNvY2tldEVycm9yKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IGRhdGEgb2YgbWVzc2FnZSkge1xuICAgICAgICAgIG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuY29uY2F0KFttZXNzYWdlQnVmZmVyLCBkYXRhXSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVsb2dpblBheWxvYWQgPSBuZXcgUHJlbG9naW5QYXlsb2FkKG1lc3NhZ2VCdWZmZXIpO1xuICAgICAgICB0aGlzLmRlYnVnLnBheWxvYWQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIHByZWxvZ2luUGF5bG9hZC50b1N0cmluZygnICAnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHByZWxvZ2luUGF5bG9hZC5mZWRBdXRoUmVxdWlyZWQgPT09IDEpIHtcbiAgICAgICAgICB0aGlzLmZlZEF1dGhSZXF1aXJlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCdzdHJpY3QnICE9PSB0aGlzLmNvbmZpZy5vcHRpb25zLmVuY3J5cHQgJiYgKHByZWxvZ2luUGF5bG9hZC5lbmNyeXB0aW9uU3RyaW5nID09PSAnT04nIHx8IHByZWxvZ2luUGF5bG9hZC5lbmNyeXB0aW9uU3RyaW5nID09PSAnUkVRJykpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLm9wdGlvbnMuZW5jcnlwdCkge1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdjb25uZWN0JywgbmV3IENvbm5lY3Rpb25FcnJvcihcIlNlcnZlciByZXF1aXJlcyBlbmNyeXB0aW9uLCBzZXQgJ2VuY3J5cHQnIGNvbmZpZyBvcHRpb24gdG8gdHJ1ZS5cIiwgJ0VFTkNSWVBUJykpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5TRU5UX1RMU1NTTE5FR09USUFUSU9OKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMubWVzc2FnZUlvLnN0YXJ0VGxzKHRoaXMuc2VjdXJlQ29udGV4dE9wdGlvbnMsIHRoaXMuY29uZmlnLm9wdGlvbnMuc2VydmVyTmFtZSA/IHRoaXMuY29uZmlnLm9wdGlvbnMuc2VydmVyTmFtZSA6IHRoaXMucm91dGluZ0RhdGE/LnNlcnZlciA/PyB0aGlzLmNvbmZpZy5zZXJ2ZXIsIHRoaXMuY29uZmlnLm9wdGlvbnMudHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNvY2tldEVycm9yKGVycik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZW5kTG9naW43UGFja2V0KCk7XG5cbiAgICAgICAgY29uc3QgeyBhdXRoZW50aWNhdGlvbiB9ID0gdGhpcy5jb25maWc7XG5cbiAgICAgICAgc3dpdGNoIChhdXRoZW50aWNhdGlvbi50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1wYXNzd29yZCc6XG4gICAgICAgICAgY2FzZSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1tc2ktdm0nOlxuICAgICAgICAgIGNhc2UgJ2F6dXJlLWFjdGl2ZS1kaXJlY3RvcnktbXNpLWFwcC1zZXJ2aWNlJzpcbiAgICAgICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LXNlcnZpY2UtcHJpbmNpcGFsLXNlY3JldCc6XG4gICAgICAgICAgY2FzZSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1kZWZhdWx0JzpcbiAgICAgICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuU0VOVF9MT0dJTjdfV0lUSF9GRURBVVRIKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ250bG0nOlxuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5TRU5UX0xPR0lON19XSVRIX05UTE0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuU0VOVF9MT0dJTjdfV0lUSF9TVEFOREFSRF9MT0dJTik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSkoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGV2ZW50czoge1xuICAgICAgc29ja2V0RXJyb3I6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcbiAgICAgIH0sXG4gICAgICBjb25uZWN0VGltZW91dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgUkVST1VUSU5HOiB7XG4gICAgbmFtZTogJ1JlUm91dGluZycsXG4gICAgZW50ZXI6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5jbGVhbnVwQ29ubmVjdGlvbihDTEVBTlVQX1RZUEUuUkVESVJFQ1QpO1xuICAgIH0sXG4gICAgZXZlbnRzOiB7XG4gICAgICBtZXNzYWdlOiBmdW5jdGlvbigpIHtcbiAgICAgIH0sXG4gICAgICBzb2NrZXRFcnJvcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfSxcbiAgICAgIGNvbm5lY3RUaW1lb3V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICB9LFxuICAgICAgcmVjb25uZWN0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5DT05ORUNUSU5HKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIFRSQU5TSUVOVF9GQUlMVVJFX1JFVFJZOiB7XG4gICAgbmFtZTogJ1RSQU5TSUVOVF9GQUlMVVJFX1JFVFJZJyxcbiAgICBlbnRlcjogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmN1clRyYW5zaWVudFJldHJ5Q291bnQrKztcbiAgICAgIHRoaXMuY2xlYW51cENvbm5lY3Rpb24oQ0xFQU5VUF9UWVBFLlJFVFJZKTtcbiAgICB9LFxuICAgIGV2ZW50czoge1xuICAgICAgbWVzc2FnZTogZnVuY3Rpb24oKSB7XG4gICAgICB9LFxuICAgICAgc29ja2V0RXJyb3I6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcbiAgICAgIH0sXG4gICAgICBjb25uZWN0VGltZW91dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfSxcbiAgICAgIHJldHJ5OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5jcmVhdGVSZXRyeVRpbWVyKCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBTRU5UX1RMU1NTTE5FR09USUFUSU9OOiB7XG4gICAgbmFtZTogJ1NlbnRUTFNTU0xOZWdvdGlhdGlvbicsXG4gICAgZXZlbnRzOiB7XG4gICAgICBzb2NrZXRFcnJvcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfSxcbiAgICAgIGNvbm5lY3RUaW1lb3V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBTRU5UX0xPR0lON19XSVRIX1NUQU5EQVJEX0xPR0lOOiB7XG4gICAgbmFtZTogJ1NlbnRMb2dpbjdXaXRoU3RhbmRhcmRMb2dpbicsXG4gICAgZW50ZXI6IGZ1bmN0aW9uKCkge1xuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgbGV0IG1lc3NhZ2U7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbWVzc2FnZSA9IGF3YWl0IHRoaXMubWVzc2FnZUlvLnJlYWRNZXNzYWdlKCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuc29ja2V0RXJyb3IoZXJyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgTG9naW43VG9rZW5IYW5kbGVyKHRoaXMpO1xuICAgICAgICBjb25zdCB0b2tlblN0cmVhbVBhcnNlciA9IHRoaXMuY3JlYXRlVG9rZW5TdHJlYW1QYXJzZXIobWVzc2FnZSwgaGFuZGxlcik7XG5cbiAgICAgICAgYXdhaXQgb25jZSh0b2tlblN0cmVhbVBhcnNlciwgJ2VuZCcpO1xuXG4gICAgICAgIGlmIChoYW5kbGVyLmxvZ2luQWNrUmVjZWl2ZWQpIHtcbiAgICAgICAgICBpZiAoaGFuZGxlci5yb3V0aW5nRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5yb3V0aW5nRGF0YSA9IGhhbmRsZXIucm91dGluZ0RhdGE7XG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLlJFUk9VVElORyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuTE9HR0VEX0lOX1NFTkRJTkdfSU5JVElBTF9TUUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxvZ2luRXJyb3IpIHtcbiAgICAgICAgICBpZiAoaXNUcmFuc2llbnRFcnJvcih0aGlzLmxvZ2luRXJyb3IpKSB7XG4gICAgICAgICAgICB0aGlzLmRlYnVnLmxvZygnSW5pdGlhdGluZyByZXRyeSBvbiB0cmFuc2llbnQgZXJyb3InKTtcbiAgICAgICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuVFJBTlNJRU5UX0ZBSUxVUkVfUkVUUlkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2Nvbm5lY3QnLCB0aGlzLmxvZ2luRXJyb3IpO1xuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZW1pdCgnY29ubmVjdCcsIG5ldyBDb25uZWN0aW9uRXJyb3IoJ0xvZ2luIGZhaWxlZC4nLCAnRUxPR0lOJykpO1xuICAgICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgICB9XG4gICAgICB9KSgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgZXZlbnRzOiB7XG4gICAgICBzb2NrZXRFcnJvcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfSxcbiAgICAgIGNvbm5lY3RUaW1lb3V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBTRU5UX0xPR0lON19XSVRIX05UTE06IHtcbiAgICBuYW1lOiAnU2VudExvZ2luN1dpdGhOVExNTG9naW4nLFxuICAgIGVudGVyOiBmdW5jdGlvbigpIHtcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgbGV0IG1lc3NhZ2U7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBhd2FpdCB0aGlzLm1lc3NhZ2VJby5yZWFkTWVzc2FnZSgpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zb2NrZXRFcnJvcihlcnIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgTG9naW43VG9rZW5IYW5kbGVyKHRoaXMpO1xuICAgICAgICAgIGNvbnN0IHRva2VuU3RyZWFtUGFyc2VyID0gdGhpcy5jcmVhdGVUb2tlblN0cmVhbVBhcnNlcihtZXNzYWdlLCBoYW5kbGVyKTtcblxuICAgICAgICAgIGF3YWl0IG9uY2UodG9rZW5TdHJlYW1QYXJzZXIsICdlbmQnKTtcblxuICAgICAgICAgIGlmIChoYW5kbGVyLmxvZ2luQWNrUmVjZWl2ZWQpIHtcbiAgICAgICAgICAgIGlmIChoYW5kbGVyLnJvdXRpbmdEYXRhKSB7XG4gICAgICAgICAgICAgIHRoaXMucm91dGluZ0RhdGEgPSBoYW5kbGVyLnJvdXRpbmdEYXRhO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5SRVJPVVRJTkcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuTE9HR0VEX0lOX1NFTkRJTkdfSU5JVElBTF9TUUwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5udGxtcGFja2V0KSB7XG4gICAgICAgICAgICBjb25zdCBhdXRoZW50aWNhdGlvbiA9IHRoaXMuY29uZmlnLmF1dGhlbnRpY2F0aW9uIGFzIE50bG1BdXRoZW50aWNhdGlvbjtcblxuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IG5ldyBOVExNUmVzcG9uc2VQYXlsb2FkKHtcbiAgICAgICAgICAgICAgZG9tYWluOiBhdXRoZW50aWNhdGlvbi5vcHRpb25zLmRvbWFpbixcbiAgICAgICAgICAgICAgdXNlck5hbWU6IGF1dGhlbnRpY2F0aW9uLm9wdGlvbnMudXNlck5hbWUsXG4gICAgICAgICAgICAgIHBhc3N3b3JkOiBhdXRoZW50aWNhdGlvbi5vcHRpb25zLnBhc3N3b3JkLFxuICAgICAgICAgICAgICBudGxtcGFja2V0OiB0aGlzLm50bG1wYWNrZXRcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VJby5zZW5kTWVzc2FnZShUWVBFLk5UTE1BVVRIX1BLVCwgcGF5bG9hZC5kYXRhKTtcbiAgICAgICAgICAgIHRoaXMuZGVidWcucGF5bG9hZChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQudG9TdHJpbmcoJyAgJyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5udGxtcGFja2V0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5sb2dpbkVycm9yKSB7XG4gICAgICAgICAgICBpZiAoaXNUcmFuc2llbnRFcnJvcih0aGlzLmxvZ2luRXJyb3IpKSB7XG4gICAgICAgICAgICAgIHRoaXMuZGVidWcubG9nKCdJbml0aWF0aW5nIHJldHJ5IG9uIHRyYW5zaWVudCBlcnJvcicpO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5UUkFOU0lFTlRfRkFJTFVSRV9SRVRSWSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Nvbm5lY3QnLCB0aGlzLmxvZ2luRXJyb3IpO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnY29ubmVjdCcsIG5ldyBDb25uZWN0aW9uRXJyb3IoJ0xvZ2luIGZhaWxlZC4nLCAnRUxPR0lOJykpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICB9KSgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgZXZlbnRzOiB7XG4gICAgICBzb2NrZXRFcnJvcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfSxcbiAgICAgIGNvbm5lY3RUaW1lb3V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBTRU5UX0xPR0lON19XSVRIX0ZFREFVVEg6IHtcbiAgICBuYW1lOiAnU2VudExvZ2luN1dpdGhmZWRhdXRoJyxcbiAgICBlbnRlcjogZnVuY3Rpb24oKSB7XG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBsZXQgbWVzc2FnZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtZXNzYWdlID0gYXdhaXQgdGhpcy5tZXNzYWdlSW8ucmVhZE1lc3NhZ2UoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zb2NrZXRFcnJvcihlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaGFuZGxlciA9IG5ldyBMb2dpbjdUb2tlbkhhbmRsZXIodGhpcyk7XG4gICAgICAgIGNvbnN0IHRva2VuU3RyZWFtUGFyc2VyID0gdGhpcy5jcmVhdGVUb2tlblN0cmVhbVBhcnNlcihtZXNzYWdlLCBoYW5kbGVyKTtcbiAgICAgICAgYXdhaXQgb25jZSh0b2tlblN0cmVhbVBhcnNlciwgJ2VuZCcpO1xuICAgICAgICBpZiAoaGFuZGxlci5sb2dpbkFja1JlY2VpdmVkKSB7XG4gICAgICAgICAgaWYgKGhhbmRsZXIucm91dGluZ0RhdGEpIHtcbiAgICAgICAgICAgIHRoaXMucm91dGluZ0RhdGEgPSBoYW5kbGVyLnJvdXRpbmdEYXRhO1xuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5SRVJPVVRJTkcpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkxPR0dFRF9JTl9TRU5ESU5HX0lOSVRJQUxfU1FMKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmZWRBdXRoSW5mb1Rva2VuID0gaGFuZGxlci5mZWRBdXRoSW5mb1Rva2VuO1xuXG4gICAgICAgIGlmIChmZWRBdXRoSW5mb1Rva2VuICYmIGZlZEF1dGhJbmZvVG9rZW4uc3RzdXJsICYmIGZlZEF1dGhJbmZvVG9rZW4uc3BuKSB7XG4gICAgICAgICAgY29uc3QgYXV0aGVudGljYXRpb24gPSB0aGlzLmNvbmZpZy5hdXRoZW50aWNhdGlvbiBhcyBBenVyZUFjdGl2ZURpcmVjdG9yeVBhc3N3b3JkQXV0aGVudGljYXRpb24gfCBBenVyZUFjdGl2ZURpcmVjdG9yeU1zaVZtQXV0aGVudGljYXRpb24gfCBBenVyZUFjdGl2ZURpcmVjdG9yeU1zaUFwcFNlcnZpY2VBdXRoZW50aWNhdGlvbiB8IEF6dXJlQWN0aXZlRGlyZWN0b3J5U2VydmljZVByaW5jaXBhbFNlY3JldCB8IEF6dXJlQWN0aXZlRGlyZWN0b3J5RGVmYXVsdEF1dGhlbnRpY2F0aW9uO1xuICAgICAgICAgIGNvbnN0IHRva2VuU2NvcGUgPSBuZXcgVVJMKCcvLmRlZmF1bHQnLCBmZWRBdXRoSW5mb1Rva2VuLnNwbikudG9TdHJpbmcoKTtcblxuICAgICAgICAgIGxldCBjcmVkZW50aWFscztcblxuICAgICAgICAgIHN3aXRjaCAoYXV0aGVudGljYXRpb24udHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1wYXNzd29yZCc6XG4gICAgICAgICAgICAgIGNyZWRlbnRpYWxzID0gbmV3IFVzZXJuYW1lUGFzc3dvcmRDcmVkZW50aWFsKFxuICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uLm9wdGlvbnMudGVuYW50SWQgPz8gJ2NvbW1vbicsXG4gICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb24ub3B0aW9ucy5jbGllbnRJZCxcbiAgICAgICAgICAgICAgICBhdXRoZW50aWNhdGlvbi5vcHRpb25zLnVzZXJOYW1lLFxuICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uLm9wdGlvbnMucGFzc3dvcmRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS12bSc6XG4gICAgICAgICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LW1zaS1hcHAtc2VydmljZSc6XG4gICAgICAgICAgICAgIGNvbnN0IG1zaUFyZ3MgPSBhdXRoZW50aWNhdGlvbi5vcHRpb25zLmNsaWVudElkID8gW2F1dGhlbnRpY2F0aW9uLm9wdGlvbnMuY2xpZW50SWQsIHt9XSA6IFt7fV07XG4gICAgICAgICAgICAgIGNyZWRlbnRpYWxzID0gbmV3IE1hbmFnZWRJZGVudGl0eUNyZWRlbnRpYWwoLi4ubXNpQXJncyk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYXp1cmUtYWN0aXZlLWRpcmVjdG9yeS1kZWZhdWx0JzpcbiAgICAgICAgICAgICAgY29uc3QgYXJncyA9IGF1dGhlbnRpY2F0aW9uLm9wdGlvbnMuY2xpZW50SWQgPyB7IG1hbmFnZWRJZGVudGl0eUNsaWVudElkOiBhdXRoZW50aWNhdGlvbi5vcHRpb25zLmNsaWVudElkIH0gOiB7fTtcbiAgICAgICAgICAgICAgY3JlZGVudGlhbHMgPSBuZXcgRGVmYXVsdEF6dXJlQ3JlZGVudGlhbChhcmdzKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdhenVyZS1hY3RpdmUtZGlyZWN0b3J5LXNlcnZpY2UtcHJpbmNpcGFsLXNlY3JldCc6XG4gICAgICAgICAgICAgIGNyZWRlbnRpYWxzID0gbmV3IENsaWVudFNlY3JldENyZWRlbnRpYWwoXG4gICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb24ub3B0aW9ucy50ZW5hbnRJZCxcbiAgICAgICAgICAgICAgICBhdXRoZW50aWNhdGlvbi5vcHRpb25zLmNsaWVudElkLFxuICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uLm9wdGlvbnMuY2xpZW50U2VjcmV0XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxldCB0b2tlblJlc3BvbnNlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0b2tlblJlc3BvbnNlID0gYXdhaXQgY3JlZGVudGlhbHMuZ2V0VG9rZW4odG9rZW5TY29wZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2luRXJyb3IgPSBuZXcgQWdncmVnYXRlRXJyb3IoXG4gICAgICAgICAgICAgIFtuZXcgQ29ubmVjdGlvbkVycm9yKCdTZWN1cml0eSB0b2tlbiBjb3VsZCBub3QgYmUgYXV0aGVudGljYXRlZCBvciBhdXRob3JpemVkLicsICdFRkVEQVVUSCcpLCBlcnJdKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnY29ubmVjdCcsIHRoaXMubG9naW5FcnJvcik7XG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cblxuICAgICAgICAgIGNvbnN0IHRva2VuID0gdG9rZW5SZXNwb25zZS50b2tlbjtcbiAgICAgICAgICB0aGlzLnNlbmRGZWRBdXRoVG9rZW5NZXNzYWdlKHRva2VuKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubG9naW5FcnJvcikge1xuICAgICAgICAgIGlmIChpc1RyYW5zaWVudEVycm9yKHRoaXMubG9naW5FcnJvcikpIHtcbiAgICAgICAgICAgIHRoaXMuZGVidWcubG9nKCdJbml0aWF0aW5nIHJldHJ5IG9uIHRyYW5zaWVudCBlcnJvcicpO1xuICAgICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5UUkFOU0lFTlRfRkFJTFVSRV9SRVRSWSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnY29ubmVjdCcsIHRoaXMubG9naW5FcnJvcik7XG4gICAgICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdjb25uZWN0JywgbmV3IENvbm5lY3Rpb25FcnJvcignTG9naW4gZmFpbGVkLicsICdFTE9HSU4nKSk7XG4gICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICAgIH1cblxuICAgICAgfSkoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGV2ZW50czoge1xuICAgICAgc29ja2V0RXJyb3I6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcbiAgICAgIH0sXG4gICAgICBjb25uZWN0VGltZW91dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgTE9HR0VEX0lOX1NFTkRJTkdfSU5JVElBTF9TUUw6IHtcbiAgICBuYW1lOiAnTG9nZ2VkSW5TZW5kaW5nSW5pdGlhbFNxbCcsXG4gICAgZW50ZXI6IGZ1bmN0aW9uKCkge1xuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgdGhpcy5zZW5kSW5pdGlhbFNxbCgpO1xuICAgICAgICBsZXQgbWVzc2FnZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtZXNzYWdlID0gYXdhaXQgdGhpcy5tZXNzYWdlSW8ucmVhZE1lc3NhZ2UoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zb2NrZXRFcnJvcihlcnIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRva2VuU3RyZWFtUGFyc2VyID0gdGhpcy5jcmVhdGVUb2tlblN0cmVhbVBhcnNlcihtZXNzYWdlLCBuZXcgSW5pdGlhbFNxbFRva2VuSGFuZGxlcih0aGlzKSk7XG4gICAgICAgIGF3YWl0IG9uY2UodG9rZW5TdHJlYW1QYXJzZXIsICdlbmQnKTtcblxuICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkxPR0dFRF9JTik7XG4gICAgICAgIHRoaXMucHJvY2Vzc2VkSW5pdGlhbFNxbCgpO1xuXG4gICAgICB9KSgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgZXZlbnRzOiB7XG4gICAgICBzb2NrZXRFcnJvcjogZnVuY3Rpb24gc29ja2V0RXJyb3IoKSB7XG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuICAgICAgfSxcbiAgICAgIGNvbm5lY3RUaW1lb3V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5GSU5BTCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBMT0dHRURfSU46IHtcbiAgICBuYW1lOiAnTG9nZ2VkSW4nLFxuICAgIGV2ZW50czoge1xuICAgICAgc29ja2V0RXJyb3I6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIFNFTlRfQ0xJRU5UX1JFUVVFU1Q6IHtcbiAgICBuYW1lOiAnU2VudENsaWVudFJlcXVlc3QnLFxuICAgIGVudGVyOiBmdW5jdGlvbigpIHtcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGxldCBtZXNzYWdlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIG1lc3NhZ2UgPSBhd2FpdCB0aGlzLm1lc3NhZ2VJby5yZWFkTWVzc2FnZSgpO1xuICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnNvY2tldEVycm9yKGVycik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVxdWVzdCB0aW1lciBpcyBzdG9wcGVkIG9uIGZpcnN0IGRhdGEgcGFja2FnZVxuICAgICAgICB0aGlzLmNsZWFyUmVxdWVzdFRpbWVyKCk7XG5cbiAgICAgICAgY29uc3QgdG9rZW5TdHJlYW1QYXJzZXIgPSB0aGlzLmNyZWF0ZVRva2VuU3RyZWFtUGFyc2VyKG1lc3NhZ2UsIG5ldyBSZXF1ZXN0VG9rZW5IYW5kbGVyKHRoaXMsIHRoaXMucmVxdWVzdCEpKTtcblxuICAgICAgICAvLyBJZiB0aGUgcmVxdWVzdCB3YXMgY2FuY2VsZWQgYW5kIHdlIGhhdmUgYSBgY2FuY2VsVGltZXJgXG4gICAgICAgIC8vIGRlZmluZWQsIHdlIHNlbmQgYSBhdHRlbnRpb24gbWVzc2FnZSBhZnRlciB0aGVcbiAgICAgICAgLy8gcmVxdWVzdCBtZXNzYWdlIHdhcyBmdWxseSBzZW50IG9mZi5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gV2UgYWxyZWFkeSBzdGFydGVkIGNvbnN1bWluZyB0aGUgY3VycmVudCBtZXNzYWdlXG4gICAgICAgIC8vIChidXQgYWxsIHRoZSB0b2tlbiBoYW5kbGVycyBzaG91bGQgYmUgbm8tb3BzKSwgYW5kXG4gICAgICAgIC8vIG5lZWQgdG8gZW5zdXJlIHRoZSBuZXh0IG1lc3NhZ2UgaXMgaGFuZGxlZCBieSB0aGVcbiAgICAgICAgLy8gYFNFTlRfQVRURU5USU9OYCBzdGF0ZS5cbiAgICAgICAgaWYgKHRoaXMucmVxdWVzdD8uY2FuY2VsZWQgJiYgdGhpcy5jYW5jZWxUaW1lcikge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLlNFTlRfQVRURU5USU9OKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG9uUmVzdW1lID0gKCkgPT4ge1xuICAgICAgICAgIHRva2VuU3RyZWFtUGFyc2VyLnJlc3VtZSgpO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBvblBhdXNlID0gKCkgPT4ge1xuICAgICAgICAgIHRva2VuU3RyZWFtUGFyc2VyLnBhdXNlKCk7XG5cbiAgICAgICAgICB0aGlzLnJlcXVlc3Q/Lm9uY2UoJ3Jlc3VtZScsIG9uUmVzdW1lKTtcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnJlcXVlc3Q/Lm9uKCdwYXVzZScsIG9uUGF1c2UpO1xuXG4gICAgICAgIGlmICh0aGlzLnJlcXVlc3QgaW5zdGFuY2VvZiBSZXF1ZXN0ICYmIHRoaXMucmVxdWVzdC5wYXVzZWQpIHtcbiAgICAgICAgICBvblBhdXNlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvbkNhbmNlbCA9ICgpID0+IHtcbiAgICAgICAgICB0b2tlblN0cmVhbVBhcnNlci5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25FbmRPZk1lc3NhZ2UpO1xuXG4gICAgICAgICAgaWYgKHRoaXMucmVxdWVzdCBpbnN0YW5jZW9mIFJlcXVlc3QgJiYgdGhpcy5yZXF1ZXN0LnBhdXNlZCkge1xuICAgICAgICAgICAgLy8gcmVzdW1lIHRoZSByZXF1ZXN0IGlmIGl0IHdhcyBwYXVzZWQgc28gd2UgY2FuIHJlYWQgdGhlIHJlbWFpbmluZyB0b2tlbnNcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdC5yZXN1bWUoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnJlcXVlc3Q/LnJlbW92ZUxpc3RlbmVyKCdwYXVzZScsIG9uUGF1c2UpO1xuICAgICAgICAgIHRoaXMucmVxdWVzdD8ucmVtb3ZlTGlzdGVuZXIoJ3Jlc3VtZScsIG9uUmVzdW1lKTtcblxuICAgICAgICAgIC8vIFRoZSBgX2NhbmNlbEFmdGVyUmVxdWVzdFNlbnRgIGNhbGxiYWNrIHdpbGwgaGF2ZSBzZW50IGFcbiAgICAgICAgICAvLyBhdHRlbnRpb24gbWVzc2FnZSwgc28gbm93IHdlIG5lZWQgdG8gYWxzbyBzd2l0Y2ggdG9cbiAgICAgICAgICAvLyB0aGUgYFNFTlRfQVRURU5USU9OYCBzdGF0ZSB0byBtYWtlIHN1cmUgdGhlIGF0dGVudGlvbiBhY2tcbiAgICAgICAgICAvLyBtZXNzYWdlIGlzIHByb2Nlc3NlZCBjb3JyZWN0bHkuXG4gICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5TRU5UX0FUVEVOVElPTik7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgb25FbmRPZk1lc3NhZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5yZXF1ZXN0Py5yZW1vdmVMaXN0ZW5lcignY2FuY2VsJywgdGhpcy5fY2FuY2VsQWZ0ZXJSZXF1ZXN0U2VudCk7XG4gICAgICAgICAgdGhpcy5yZXF1ZXN0Py5yZW1vdmVMaXN0ZW5lcignY2FuY2VsJywgb25DYW5jZWwpO1xuICAgICAgICAgIHRoaXMucmVxdWVzdD8ucmVtb3ZlTGlzdGVuZXIoJ3BhdXNlJywgb25QYXVzZSk7XG4gICAgICAgICAgdGhpcy5yZXF1ZXN0Py5yZW1vdmVMaXN0ZW5lcigncmVzdW1lJywgb25SZXN1bWUpO1xuXG4gICAgICAgICAgdGhpcy50cmFuc2l0aW9uVG8odGhpcy5TVEFURS5MT0dHRURfSU4pO1xuICAgICAgICAgIGNvbnN0IHNxbFJlcXVlc3QgPSB0aGlzLnJlcXVlc3QgYXMgUmVxdWVzdDtcbiAgICAgICAgICB0aGlzLnJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKHRoaXMuY29uZmlnLm9wdGlvbnMudGRzVmVyc2lvbiA8ICc3XzInICYmIHNxbFJlcXVlc3QuZXJyb3IgJiYgdGhpcy5pc1NxbEJhdGNoKSB7XG4gICAgICAgICAgICB0aGlzLmluVHJhbnNhY3Rpb24gPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3FsUmVxdWVzdC5jYWxsYmFjayhzcWxSZXF1ZXN0LmVycm9yLCBzcWxSZXF1ZXN0LnJvd0NvdW50LCBzcWxSZXF1ZXN0LnJvd3MpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRva2VuU3RyZWFtUGFyc2VyLm9uY2UoJ2VuZCcsIG9uRW5kT2ZNZXNzYWdlKTtcbiAgICAgICAgdGhpcy5yZXF1ZXN0Py5vbmNlKCdjYW5jZWwnLCBvbkNhbmNlbCk7XG4gICAgICB9KSgpO1xuXG4gICAgfSxcbiAgICBleGl0OiBmdW5jdGlvbihuZXh0U3RhdGUpIHtcbiAgICAgIHRoaXMuY2xlYXJSZXF1ZXN0VGltZXIoKTtcbiAgICB9LFxuICAgIGV2ZW50czoge1xuICAgICAgc29ja2V0RXJyb3I6IGZ1bmN0aW9uKGVycikge1xuICAgICAgICBjb25zdCBzcWxSZXF1ZXN0ID0gdGhpcy5yZXF1ZXN0ITtcbiAgICAgICAgdGhpcy5yZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkZJTkFMKTtcblxuICAgICAgICBzcWxSZXF1ZXN0LmNhbGxiYWNrKGVycik7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBTRU5UX0FUVEVOVElPTjoge1xuICAgIG5hbWU6ICdTZW50QXR0ZW50aW9uJyxcbiAgICBlbnRlcjogZnVuY3Rpb24oKSB7XG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBsZXQgbWVzc2FnZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtZXNzYWdlID0gYXdhaXQgdGhpcy5tZXNzYWdlSW8ucmVhZE1lc3NhZ2UoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zb2NrZXRFcnJvcihlcnIpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaGFuZGxlciA9IG5ldyBBdHRlbnRpb25Ub2tlbkhhbmRsZXIodGhpcywgdGhpcy5yZXF1ZXN0ISk7XG4gICAgICAgIGNvbnN0IHRva2VuU3RyZWFtUGFyc2VyID0gdGhpcy5jcmVhdGVUb2tlblN0cmVhbVBhcnNlcihtZXNzYWdlLCBoYW5kbGVyKTtcblxuICAgICAgICBhd2FpdCBvbmNlKHRva2VuU3RyZWFtUGFyc2VyLCAnZW5kJyk7XG4gICAgICAgIC8vIDMuMi41LjcgU2VudCBBdHRlbnRpb24gU3RhdGVcbiAgICAgICAgLy8gRGlzY2FyZCBhbnkgZGF0YSBjb250YWluZWQgaW4gdGhlIHJlc3BvbnNlLCB1bnRpbCB3ZSByZWNlaXZlIHRoZSBhdHRlbnRpb24gcmVzcG9uc2VcbiAgICAgICAgaWYgKGhhbmRsZXIuYXR0ZW50aW9uUmVjZWl2ZWQpIHtcbiAgICAgICAgICB0aGlzLmNsZWFyQ2FuY2VsVGltZXIoKTtcblxuICAgICAgICAgIGNvbnN0IHNxbFJlcXVlc3QgPSB0aGlzLnJlcXVlc3QhO1xuICAgICAgICAgIHRoaXMucmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB0aGlzLnRyYW5zaXRpb25Ubyh0aGlzLlNUQVRFLkxPR0dFRF9JTik7XG5cbiAgICAgICAgICBpZiAoc3FsUmVxdWVzdC5lcnJvciAmJiBzcWxSZXF1ZXN0LmVycm9yIGluc3RhbmNlb2YgUmVxdWVzdEVycm9yICYmIHNxbFJlcXVlc3QuZXJyb3IuY29kZSA9PT0gJ0VUSU1FT1VUJykge1xuICAgICAgICAgICAgc3FsUmVxdWVzdC5jYWxsYmFjayhzcWxSZXF1ZXN0LmVycm9yKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3FsUmVxdWVzdC5jYWxsYmFjayhuZXcgUmVxdWVzdEVycm9yKCdDYW5jZWxlZC4nLCAnRUNBTkNFTCcpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgfSkoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGV2ZW50czoge1xuICAgICAgc29ja2V0RXJyb3I6IGZ1bmN0aW9uKGVycikge1xuICAgICAgICBjb25zdCBzcWxSZXF1ZXN0ID0gdGhpcy5yZXF1ZXN0ITtcbiAgICAgICAgdGhpcy5yZXF1ZXN0ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIHRoaXMudHJhbnNpdGlvblRvKHRoaXMuU1RBVEUuRklOQUwpO1xuXG4gICAgICAgIHNxbFJlcXVlc3QuY2FsbGJhY2soZXJyKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIEZJTkFMOiB7XG4gICAgbmFtZTogJ0ZpbmFsJyxcbiAgICBlbnRlcjogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmNsZWFudXBDb25uZWN0aW9uKENMRUFOVVBfVFlQRS5OT1JNQUwpO1xuICAgIH0sXG4gICAgZXZlbnRzOiB7XG4gICAgICBjb25uZWN0VGltZW91dDogZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIERvIG5vdGhpbmcsIGFzIHRoZSB0aW1lciBzaG91bGQgYmUgY2xlYW5lZCB1cC5cbiAgICAgIH0sXG4gICAgICBtZXNzYWdlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgLy8gRG8gbm90aGluZ1xuICAgICAgfSxcbiAgICAgIHNvY2tldEVycm9yOiBmdW5jdGlvbigpIHtcbiAgICAgICAgLy8gRG8gbm90aGluZ1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsT0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsR0FBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUUsR0FBQSxHQUFBQyx1QkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksR0FBQSxHQUFBRCx1QkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUssSUFBQSxHQUFBTixzQkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQU0sVUFBQSxHQUFBUCxzQkFBQSxDQUFBQyxPQUFBO0FBR0EsSUFBQU8sT0FBQSxHQUFBUCxPQUFBO0FBRUEsSUFBQVEsU0FBQSxHQUFBUixPQUFBO0FBT0EsSUFBQVMsU0FBQSxHQUFBVixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVUsTUFBQSxHQUFBWCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVcsT0FBQSxHQUFBWCxPQUFBO0FBQ0EsSUFBQVksZUFBQSxHQUFBWixPQUFBO0FBQ0EsSUFBQWEscUJBQUEsR0FBQWIsT0FBQTtBQUNBLElBQUFjLE9BQUEsR0FBQWQsT0FBQTtBQUNB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 |
\ | No newline at end of file |