UNPKG

67.6 kBJavaScriptView Raw
1"use strict";
2
3const semver = require('semver');
4
5/**
6 * Module of mixed-in functions shared between node and client code
7 */
8const _require = require('./utils'),
9 isObject = _require.isObject,
10 hasOwn = _require.hasOwn;
11
12/**
13 * Expose `RequestBase`.
14 */
15
16module.exports = RequestBase;
17
18/**
19 * Initialize a new `RequestBase`.
20 *
21 * @api public
22 */
23
24function RequestBase() {}
25
26/**
27 * Clear previous timeout.
28 *
29 * @return {Request} for chaining
30 * @api public
31 */
32
33RequestBase.prototype.clearTimeout = function () {
34 clearTimeout(this._timer);
35 clearTimeout(this._responseTimeoutTimer);
36 clearTimeout(this._uploadTimeoutTimer);
37 delete this._timer;
38 delete this._responseTimeoutTimer;
39 delete this._uploadTimeoutTimer;
40 return this;
41};
42
43/**
44 * Override default response body parser
45 *
46 * This function will be called to convert incoming data into request.body
47 *
48 * @param {Function}
49 * @api public
50 */
51
52RequestBase.prototype.parse = function (fn) {
53 this._parser = fn;
54 return this;
55};
56
57/**
58 * Set format of binary response body.
59 * In browser valid formats are 'blob' and 'arraybuffer',
60 * which return Blob and ArrayBuffer, respectively.
61 *
62 * In Node all values result in Buffer.
63 *
64 * Examples:
65 *
66 * req.get('/')
67 * .responseType('blob')
68 * .end(callback);
69 *
70 * @param {String} val
71 * @return {Request} for chaining
72 * @api public
73 */
74
75RequestBase.prototype.responseType = function (value) {
76 this._responseType = value;
77 return this;
78};
79
80/**
81 * Override default request body serializer
82 *
83 * This function will be called to convert data set via .send or .attach into payload to send
84 *
85 * @param {Function}
86 * @api public
87 */
88
89RequestBase.prototype.serialize = function (fn) {
90 this._serializer = fn;
91 return this;
92};
93
94/**
95 * Set timeouts.
96 *
97 * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time.
98 * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections.
99 * - upload is the time since last bit of data was sent or received. This timeout works only if deadline timeout is off
100 *
101 * Value of 0 or false means no timeout.
102 *
103 * @param {Number|Object} ms or {response, deadline}
104 * @return {Request} for chaining
105 * @api public
106 */
107
108RequestBase.prototype.timeout = function (options) {
109 if (!options || typeof options !== 'object') {
110 this._timeout = options;
111 this._responseTimeout = 0;
112 this._uploadTimeout = 0;
113 return this;
114 }
115 for (const option in options) {
116 if (hasOwn(options, option)) {
117 switch (option) {
118 case 'deadline':
119 {
120 this._timeout = options.deadline;
121 break;
122 }
123 case 'response':
124 {
125 this._responseTimeout = options.response;
126 break;
127 }
128 case 'upload':
129 {
130 this._uploadTimeout = options.upload;
131 break;
132 }
133 default:
134 {
135 console.warn('Unknown timeout option', option);
136 }
137 }
138 }
139 }
140 return this;
141};
142
143/**
144 * Set number of retry attempts on error.
145 *
146 * Failed requests will be retried 'count' times if timeout or err.code >= 500.
147 *
148 * @param {Number} count
149 * @param {Function} [fn]
150 * @return {Request} for chaining
151 * @api public
152 */
153
154RequestBase.prototype.retry = function (count, fn) {
155 // Default to 1 if no count passed or true
156 if (arguments.length === 0 || count === true) count = 1;
157 if (count <= 0) count = 0;
158 this._maxRetries = count;
159 this._retries = 0;
160 this._retryCallback = fn;
161 return this;
162};
163
164//
165// NOTE: we do not include ESOCKETTIMEDOUT because that is from `request` package
166// <https://github.com/sindresorhus/got/pull/537>
167//
168// NOTE: we do not include EADDRINFO because it was removed from libuv in 2014
169// <https://github.com/libuv/libuv/commit/02e1ebd40b807be5af46343ea873331b2ee4e9c1>
170// <https://github.com/request/request/search?q=ESOCKETTIMEDOUT&unscoped_q=ESOCKETTIMEDOUT>
171//
172//
173// TODO: expose these as configurable defaults
174//
175const ERROR_CODES = new Set(['ETIMEDOUT', 'ECONNRESET', 'EADDRINUSE', 'ECONNREFUSED', 'EPIPE', 'ENOTFOUND', 'ENETUNREACH', 'EAI_AGAIN']);
176const STATUS_CODES = new Set([408, 413, 429, 500, 502, 503, 504, 521, 522, 524]);
177
178// TODO: we would need to make this easily configurable before adding it in (e.g. some might want to add POST)
179// const METHODS = new Set(['GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE']);
180
181/**
182 * Determine if a request should be retried.
183 * (Inspired by https://github.com/sindresorhus/got#retry)
184 *
185 * @param {Error} err an error
186 * @param {Response} [res] response
187 * @returns {Boolean} if segment should be retried
188 */
189RequestBase.prototype._shouldRetry = function (error, res) {
190 if (!this._maxRetries || this._retries++ >= this._maxRetries) {
191 return false;
192 }
193 if (this._retryCallback) {
194 try {
195 const override = this._retryCallback(error, res);
196 if (override === true) return true;
197 if (override === false) return false;
198 // undefined falls back to defaults
199 } catch (err) {
200 console.error(err);
201 }
202 }
203
204 // TODO: we would need to make this easily configurable before adding it in (e.g. some might want to add POST)
205 /*
206 if (
207 this.req &&
208 this.req.method &&
209 !METHODS.has(this.req.method.toUpperCase())
210 )
211 return false;
212 */
213 if (res && res.status && STATUS_CODES.has(res.status)) return true;
214 if (error) {
215 if (error.code && ERROR_CODES.has(error.code)) return true;
216 // Superagent timeout
217 if (error.timeout && error.code === 'ECONNABORTED') return true;
218 if (error.crossDomain) return true;
219 }
220 return false;
221};
222
223/**
224 * Retry request
225 *
226 * @return {Request} for chaining
227 * @api private
228 */
229
230RequestBase.prototype._retry = function () {
231 this.clearTimeout();
232
233 // node
234 if (this.req) {
235 this.req = null;
236 this.req = this.request();
237 }
238 this._aborted = false;
239 this.timedout = false;
240 this.timedoutError = null;
241 return this._end();
242};
243
244/**
245 * Promise support
246 *
247 * @param {Function} resolve
248 * @param {Function} [reject]
249 * @return {Request}
250 */
251
252RequestBase.prototype.then = function (resolve, reject) {
253 if (!this._fullfilledPromise) {
254 const self = this;
255 if (this._endCalled) {
256 console.warn('Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises');
257 }
258 this._fullfilledPromise = new Promise((resolve, reject) => {
259 self.on('abort', () => {
260 if (this._maxRetries && this._maxRetries > this._retries) {
261 return;
262 }
263 if (this.timedout && this.timedoutError) {
264 reject(this.timedoutError);
265 return;
266 }
267 const error = new Error('Aborted');
268 error.code = 'ABORTED';
269 error.status = this.status;
270 error.method = this.method;
271 error.url = this.url;
272 reject(error);
273 });
274 self.end((error, res) => {
275 if (error) reject(error);else resolve(res);
276 });
277 });
278 }
279 return this._fullfilledPromise.then(resolve, reject);
280};
281RequestBase.prototype.catch = function (callback) {
282 return this.then(undefined, callback);
283};
284
285/**
286 * Allow for extension
287 */
288
289RequestBase.prototype.use = function (fn) {
290 fn(this);
291 return this;
292};
293RequestBase.prototype.ok = function (callback) {
294 if (typeof callback !== 'function') throw new Error('Callback required');
295 this._okCallback = callback;
296 return this;
297};
298RequestBase.prototype._isResponseOK = function (res) {
299 if (!res) {
300 return false;
301 }
302 if (this._okCallback) {
303 return this._okCallback(res);
304 }
305 return res.status >= 200 && res.status < 300;
306};
307
308/**
309 * Get request header `field`.
310 * Case-insensitive.
311 *
312 * @param {String} field
313 * @return {String}
314 * @api public
315 */
316
317RequestBase.prototype.get = function (field) {
318 return this._header[field.toLowerCase()];
319};
320
321/**
322 * Get case-insensitive header `field` value.
323 * This is a deprecated internal API. Use `.get(field)` instead.
324 *
325 * (getHeader is no longer used internally by the superagent code base)
326 *
327 * @param {String} field
328 * @return {String}
329 * @api private
330 * @deprecated
331 */
332
333RequestBase.prototype.getHeader = RequestBase.prototype.get;
334
335/**
336 * Set header `field` to `val`, or multiple fields with one object.
337 * Case-insensitive.
338 *
339 * Examples:
340 *
341 * req.get('/')
342 * .set('Accept', 'application/json')
343 * .set('X-API-Key', 'foobar')
344 * .end(callback);
345 *
346 * req.get('/')
347 * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
348 * .end(callback);
349 *
350 * @param {String|Object} field
351 * @param {String} val
352 * @return {Request} for chaining
353 * @api public
354 */
355
356RequestBase.prototype.set = function (field, value) {
357 if (isObject(field)) {
358 for (const key in field) {
359 if (hasOwn(field, key)) this.set(key, field[key]);
360 }
361 return this;
362 }
363 this._header[field.toLowerCase()] = value;
364 this.header[field] = value;
365 return this;
366};
367
368/**
369 * Remove header `field`.
370 * Case-insensitive.
371 *
372 * Example:
373 *
374 * req.get('/')
375 * .unset('User-Agent')
376 * .end(callback);
377 *
378 * @param {String} field field name
379 */
380RequestBase.prototype.unset = function (field) {
381 delete this._header[field.toLowerCase()];
382 delete this.header[field];
383 return this;
384};
385
386/**
387 * Write the field `name` and `val`, or multiple fields with one object
388 * for "multipart/form-data" request bodies.
389 *
390 * ``` js
391 * request.post('/upload')
392 * .field('foo', 'bar')
393 * .end(callback);
394 *
395 * request.post('/upload')
396 * .field({ foo: 'bar', baz: 'qux' })
397 * .end(callback);
398 * ```
399 *
400 * @param {String|Object} name name of field
401 * @param {String|Blob|File|Buffer|fs.ReadStream} val value of field
402 * @param {String} options extra options, e.g. 'blob'
403 * @return {Request} for chaining
404 * @api public
405 */
406RequestBase.prototype.field = function (name, value, options) {
407 // name should be either a string or an object.
408 if (name === null || undefined === name) {
409 throw new Error('.field(name, val) name can not be empty');
410 }
411 if (this._data) {
412 throw new Error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()");
413 }
414 if (isObject(name)) {
415 for (const key in name) {
416 if (hasOwn(name, key)) this.field(key, name[key]);
417 }
418 return this;
419 }
420 if (Array.isArray(value)) {
421 for (const i in value) {
422 if (hasOwn(value, i)) this.field(name, value[i]);
423 }
424 return this;
425 }
426
427 // val should be defined now
428 if (value === null || undefined === value) {
429 throw new Error('.field(name, val) val can not be empty');
430 }
431 if (typeof value === 'boolean') {
432 value = String(value);
433 }
434
435 // fix https://github.com/ladjs/superagent/issues/1680
436 if (options) this._getFormData().append(name, value, options);else this._getFormData().append(name, value);
437 return this;
438};
439
440/**
441 * Abort the request, and clear potential timeout.
442 *
443 * @return {Request} request
444 * @api public
445 */
446RequestBase.prototype.abort = function () {
447 if (this._aborted) {
448 return this;
449 }
450 this._aborted = true;
451 if (this.xhr) this.xhr.abort(); // browser
452 if (this.req) {
453 // Node v13 has major differences in `abort()`
454 // https://github.com/nodejs/node/blob/v12.x/lib/internal/streams/end-of-stream.js
455 // https://github.com/nodejs/node/blob/v13.x/lib/internal/streams/end-of-stream.js
456 // https://github.com/nodejs/node/blob/v14.x/lib/internal/streams/end-of-stream.js
457 // (if you run a diff across these you will see the differences)
458 //
459 // References:
460 // <https://github.com/nodejs/node/issues/31630>
461 // <https://github.com/ladjs/superagent/pull/1084/commits/dc18679a7c5ccfc6046d882015e5126888973bc8>
462 //
463 // Thanks to @shadowgate15 and @niftylettuce
464 if (semver.gte(process.version, 'v13.0.0') && semver.lt(process.version, 'v14.0.0')) {
465 // Note that the reason this doesn't work is because in v13 as compared to v14
466 // there is no `callback = nop` set in end-of-stream.js above
467 throw new Error('Superagent does not work in v13 properly with abort() due to Node.js core changes');
468 }
469 this.req.abort(); // node
470 }
471
472 this.clearTimeout();
473 this.emit('abort');
474 return this;
475};
476RequestBase.prototype._auth = function (user, pass, options, base64Encoder) {
477 switch (options.type) {
478 case 'basic':
479 {
480 this.set('Authorization', `Basic ${base64Encoder(`${user}:${pass}`)}`);
481 break;
482 }
483 case 'auto':
484 {
485 this.username = user;
486 this.password = pass;
487 break;
488 }
489 case 'bearer':
490 {
491 // usage would be .auth(accessToken, { type: 'bearer' })
492 this.set('Authorization', `Bearer ${user}`);
493 break;
494 }
495 default:
496 {
497 break;
498 }
499 }
500 return this;
501};
502
503/**
504 * Enable transmission of cookies with x-domain requests.
505 *
506 * Note that for this to work the origin must not be
507 * using "Access-Control-Allow-Origin" with a wildcard,
508 * and also must set "Access-Control-Allow-Credentials"
509 * to "true".
510 * @param {Boolean} [on=true] - Set 'withCredentials' state
511 * @return {Request} for chaining
512 * @api public
513 */
514
515RequestBase.prototype.withCredentials = function (on) {
516 // This is browser-only functionality. Node side is no-op.
517 if (on === undefined) on = true;
518 this._withCredentials = on;
519 return this;
520};
521
522/**
523 * Set the max redirects to `n`. Does nothing in browser XHR implementation.
524 *
525 * @param {Number} n
526 * @return {Request} for chaining
527 * @api public
528 */
529
530RequestBase.prototype.redirects = function (n) {
531 this._maxRedirects = n;
532 return this;
533};
534
535/**
536 * Maximum size of buffered response body, in bytes. Counts uncompressed size.
537 * Default 200MB.
538 *
539 * @param {Number} n number of bytes
540 * @return {Request} for chaining
541 */
542RequestBase.prototype.maxResponseSize = function (n) {
543 if (typeof n !== 'number') {
544 throw new TypeError('Invalid argument');
545 }
546 this._maxResponseSize = n;
547 return this;
548};
549
550/**
551 * Convert to a plain javascript object (not JSON string) of scalar properties.
552 * Note as this method is designed to return a useful non-this value,
553 * it cannot be chained.
554 *
555 * @return {Object} describing method, url, and data of this request
556 * @api public
557 */
558
559RequestBase.prototype.toJSON = function () {
560 return {
561 method: this.method,
562 url: this.url,
563 data: this._data,
564 headers: this._header
565 };
566};
567
568/**
569 * Send `data` as the request body, defaulting the `.type()` to "json" when
570 * an object is given.
571 *
572 * Examples:
573 *
574 * // manual json
575 * request.post('/user')
576 * .type('json')
577 * .send('{"name":"tj"}')
578 * .end(callback)
579 *
580 * // auto json
581 * request.post('/user')
582 * .send({ name: 'tj' })
583 * .end(callback)
584 *
585 * // manual x-www-form-urlencoded
586 * request.post('/user')
587 * .type('form')
588 * .send('name=tj')
589 * .end(callback)
590 *
591 * // auto x-www-form-urlencoded
592 * request.post('/user')
593 * .type('form')
594 * .send({ name: 'tj' })
595 * .end(callback)
596 *
597 * // defaults to x-www-form-urlencoded
598 * request.post('/user')
599 * .send('name=tobi')
600 * .send('species=ferret')
601 * .end(callback)
602 *
603 * @param {String|Object} data
604 * @return {Request} for chaining
605 * @api public
606 */
607
608// eslint-disable-next-line complexity
609RequestBase.prototype.send = function (data) {
610 const isObject_ = isObject(data);
611 let type = this._header['content-type'];
612 if (this._formData) {
613 throw new Error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()");
614 }
615 if (isObject_ && !this._data) {
616 if (Array.isArray(data)) {
617 this._data = [];
618 } else if (!this._isHost(data)) {
619 this._data = {};
620 }
621 } else if (data && this._data && this._isHost(this._data)) {
622 throw new Error("Can't merge these send calls");
623 }
624
625 // merge
626 if (isObject_ && isObject(this._data)) {
627 for (const key in data) {
628 if (typeof data[key] === 'bigint') throw new Error('Cannot serialize BigInt value to json');
629 if (hasOwn(data, key)) this._data[key] = data[key];
630 }
631 } else if (typeof data === 'bigint') throw new Error('Cannot send value of type BigInt');else if (typeof data === 'string') {
632 // default to x-www-form-urlencoded
633 if (!type) this.type('form');
634 type = this._header['content-type'];
635 if (type) type = type.toLowerCase().trim();
636 if (type === 'application/x-www-form-urlencoded') {
637 this._data = this._data ? `${this._data}&${data}` : data;
638 } else {
639 this._data = (this._data || '') + data;
640 }
641 } else {
642 this._data = data;
643 }
644 if (!isObject_ || this._isHost(data)) {
645 return this;
646 }
647
648 // default to json
649 if (!type) this.type('json');
650 return this;
651};
652
653/**
654 * Sort `querystring` by the sort function
655 *
656 *
657 * Examples:
658 *
659 * // default order
660 * request.get('/user')
661 * .query('name=Nick')
662 * .query('search=Manny')
663 * .sortQuery()
664 * .end(callback)
665 *
666 * // customized sort function
667 * request.get('/user')
668 * .query('name=Nick')
669 * .query('search=Manny')
670 * .sortQuery(function(a, b){
671 * return a.length - b.length;
672 * })
673 * .end(callback)
674 *
675 *
676 * @param {Function} sort
677 * @return {Request} for chaining
678 * @api public
679 */
680
681RequestBase.prototype.sortQuery = function (sort) {
682 // _sort default to true but otherwise can be a function or boolean
683 this._sort = sort === undefined ? true : sort;
684 return this;
685};
686
687/**
688 * Compose querystring to append to req.url
689 *
690 * @api private
691 */
692RequestBase.prototype._finalizeQueryString = function () {
693 const query = this._query.join('&');
694 if (query) {
695 this.url += (this.url.includes('?') ? '&' : '?') + query;
696 }
697 this._query.length = 0; // Makes the call idempotent
698
699 if (this._sort) {
700 const index = this.url.indexOf('?');
701 if (index >= 0) {
702 const queryArray = this.url.slice(index + 1).split('&');
703 if (typeof this._sort === 'function') {
704 queryArray.sort(this._sort);
705 } else {
706 queryArray.sort();
707 }
708 this.url = this.url.slice(0, index) + '?' + queryArray.join('&');
709 }
710 }
711};
712
713// For backwards compat only
714RequestBase.prototype._appendQueryString = () => {
715 console.warn('Unsupported');
716};
717
718/**
719 * Invoke callback with timeout error.
720 *
721 * @api private
722 */
723
724RequestBase.prototype._timeoutError = function (reason, timeout, errno) {
725 if (this._aborted) {
726 return;
727 }
728 const error = new Error(`${reason + timeout}ms exceeded`);
729 error.timeout = timeout;
730 error.code = 'ECONNABORTED';
731 error.errno = errno;
732 this.timedout = true;
733 this.timedoutError = error;
734 this.abort();
735 this.callback(error);
736};
737RequestBase.prototype._setTimeouts = function () {
738 const self = this;
739
740 // deadline
741 if (this._timeout && !this._timer) {
742 this._timer = setTimeout(() => {
743 self._timeoutError('Timeout of ', self._timeout, 'ETIME');
744 }, this._timeout);
745 }
746
747 // response timeout
748 if (this._responseTimeout && !this._responseTimeoutTimer) {
749 this._responseTimeoutTimer = setTimeout(() => {
750 self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT');
751 }, this._responseTimeout);
752 }
753};
754//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzZW12ZXIiLCJyZXF1aXJlIiwiX3JlcXVpcmUiLCJpc09iamVjdCIsImhhc093biIsIm1vZHVsZSIsImV4cG9ydHMiLCJSZXF1ZXN0QmFzZSIsInByb3RvdHlwZSIsImNsZWFyVGltZW91dCIsIl90aW1lciIsIl9yZXNwb25zZVRpbWVvdXRUaW1lciIsIl91cGxvYWRUaW1lb3V0VGltZXIiLCJwYXJzZSIsImZuIiwiX3BhcnNlciIsInJlc3BvbnNlVHlwZSIsInZhbHVlIiwiX3Jlc3BvbnNlVHlwZSIsInNlcmlhbGl6ZSIsIl9zZXJpYWxpemVyIiwidGltZW91dCIsIm9wdGlvbnMiLCJfdGltZW91dCIsIl9yZXNwb25zZVRpbWVvdXQiLCJfdXBsb2FkVGltZW91dCIsIm9wdGlvbiIsImRlYWRsaW5lIiwicmVzcG9uc2UiLCJ1cGxvYWQiLCJjb25zb2xlIiwid2FybiIsInJldHJ5IiwiY291bnQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJfbWF4UmV0cmllcyIsIl9yZXRyaWVzIiwiX3JldHJ5Q2FsbGJhY2siLCJFUlJPUl9DT0RFUyIsIlNldCIsIlNUQVRVU19DT0RFUyIsIl9zaG91bGRSZXRyeSIsImVycm9yIiwicmVzIiwib3ZlcnJpZGUiLCJlcnIiLCJzdGF0dXMiLCJoYXMiLCJjb2RlIiwiY3Jvc3NEb21haW4iLCJfcmV0cnkiLCJyZXEiLCJyZXF1ZXN0IiwiX2Fib3J0ZWQiLCJ0aW1lZG91dCIsInRpbWVkb3V0RXJyb3IiLCJfZW5kIiwidGhlbiIsInJlc29sdmUiLCJyZWplY3QiLCJfZnVsbGZpbGxlZFByb21pc2UiLCJzZWxmIiwiX2VuZENhbGxlZCIsIlByb21pc2UiLCJvbiIsIkVycm9yIiwibWV0aG9kIiwidXJsIiwiZW5kIiwiY2F0Y2giLCJjYWxsYmFjayIsInVuZGVmaW5lZCIsInVzZSIsIm9rIiwiX29rQ2FsbGJhY2siLCJfaXNSZXNwb25zZU9LIiwiZ2V0IiwiZmllbGQiLCJfaGVhZGVyIiwidG9Mb3dlckNhc2UiLCJnZXRIZWFkZXIiLCJzZXQiLCJrZXkiLCJoZWFkZXIiLCJ1bnNldCIsIm5hbWUiLCJfZGF0YSIsIkFycmF5IiwiaXNBcnJheSIsImkiLCJTdHJpbmciLCJfZ2V0Rm9ybURhdGEiLCJhcHBlbmQiLCJhYm9ydCIsInhociIsImd0ZSIsInByb2Nlc3MiLCJ2ZXJzaW9uIiwibHQiLCJlbWl0IiwiX2F1dGgiLCJ1c2VyIiwicGFzcyIsImJhc2U2NEVuY29kZXIiLCJ0eXBlIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsIndpdGhDcmVkZW50aWFscyIsIl93aXRoQ3JlZGVudGlhbHMiLCJyZWRpcmVjdHMiLCJuIiwiX21heFJlZGlyZWN0cyIsIm1heFJlc3BvbnNlU2l6ZSIsIlR5cGVFcnJvciIsIl9tYXhSZXNwb25zZVNpemUiLCJ0b0pTT04iLCJkYXRhIiwiaGVhZGVycyIsInNlbmQiLCJpc09iamVjdF8iLCJfZm9ybURhdGEiLCJfaXNIb3N0IiwidHJpbSIsInNvcnRRdWVyeSIsInNvcnQiLCJfc29ydCIsIl9maW5hbGl6ZVF1ZXJ5U3RyaW5nIiwicXVlcnkiLCJfcXVlcnkiLCJqb2luIiwiaW5jbHVkZXMiLCJpbmRleCIsImluZGV4T2YiLCJxdWVyeUFycmF5Iiwic2xpY2UiLCJzcGxpdCIsIl9hcHBlbmRRdWVyeVN0cmluZyIsIl90aW1lb3V0RXJyb3IiLCJyZWFzb24iLCJlcnJubyIsIl9zZXRUaW1lb3V0cyIsInNldFRpbWVvdXQiXSwic291cmNlcyI6WyIuLi9zcmMvcmVxdWVzdC1iYXNlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHNlbXZlciA9IHJlcXVpcmUoJ3NlbXZlcicpO1xuXG4vKipcbiAqIE1vZHVsZSBvZiBtaXhlZC1pbiBmdW5jdGlvbnMgc2hhcmVkIGJldHdlZW4gbm9kZSBhbmQgY2xpZW50IGNvZGVcbiAqL1xuY29uc3QgeyBpc09iamVjdCwgaGFzT3duIH0gPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbi8qKlxuICogRXhwb3NlIGBSZXF1ZXN0QmFzZWAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBSZXF1ZXN0QmFzZTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXF1ZXN0QmFzZWAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0QmFzZSgpIHt9XG5cbi8qKlxuICogQ2xlYXIgcHJldmlvdXMgdGltZW91dC5cbiAqXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLmNsZWFyVGltZW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3Jlc3BvbnNlVGltZW91dFRpbWVyKTtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3VwbG9hZFRpbWVvdXRUaW1lcik7XG4gIGRlbGV0ZSB0aGlzLl90aW1lcjtcbiAgZGVsZXRlIHRoaXMuX3Jlc3BvbnNlVGltZW91dFRpbWVyO1xuICBkZWxldGUgdGhpcy5fdXBsb2FkVGltZW91dFRpbWVyO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgZGVmYXVsdCByZXNwb25zZSBib2R5IHBhcnNlclxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgdG8gY29udmVydCBpbmNvbWluZyBkYXRhIGludG8gcmVxdWVzdC5ib2R5XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gKGZuKSB7XG4gIHRoaXMuX3BhcnNlciA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IGZvcm1hdCBvZiBiaW5hcnkgcmVzcG9uc2UgYm9keS5cbiAqIEluIGJyb3dzZXIgdmFsaWQgZm9ybWF0cyBhcmUgJ2Jsb2InIGFuZCAnYXJyYXlidWZmZXInLFxuICogd2hpY2ggcmV0dXJuIEJsb2IgYW5kIEFycmF5QnVmZmVyLCByZXNwZWN0aXZlbHkuXG4gKlxuICogSW4gTm9kZSBhbGwgdmFsdWVzIHJlc3VsdCBpbiBCdWZmZXIuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAucmVzcG9uc2VUeXBlKCdibG9iJylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnJlc3BvbnNlVHlwZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB0aGlzLl9yZXNwb25zZVR5cGUgPSB2YWx1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIE92ZXJyaWRlIGRlZmF1bHQgcmVxdWVzdCBib2R5IHNlcmlhbGl6ZXJcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIHRvIGNvbnZlcnQgZGF0YSBzZXQgdmlhIC5zZW5kIG9yIC5hdHRhY2ggaW50byBwYXlsb2FkIHRvIHNlbmRcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuc2VyaWFsaXplID0gZnVuY3Rpb24gKGZuKSB7XG4gIHRoaXMuX3NlcmlhbGl6ZXIgPSBmbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCB0aW1lb3V0cy5cbiAqXG4gKiAtIHJlc3BvbnNlIHRpbWVvdXQgaXMgdGltZSBiZXR3ZWVuIHNlbmRpbmcgcmVxdWVzdCBhbmQgcmVjZWl2aW5nIHRoZSBmaXJzdCBieXRlIG9mIHRoZSByZXNwb25zZS4gSW5jbHVkZXMgRE5TIGFuZCBjb25uZWN0aW9uIHRpbWUuXG4gKiAtIGRlYWRsaW5lIGlzIHRoZSB0aW1lIGZyb20gc3RhcnQgb2YgdGhlIHJlcXVlc3QgdG8gcmVjZWl2aW5nIHJlc3BvbnNlIGJvZHkgaW4gZnVsbC4gSWYgdGhlIGRlYWRsaW5lIGlzIHRvbyBzaG9ydCBsYXJnZSBmaWxlcyBtYXkgbm90IGxvYWQgYXQgYWxsIG9uIHNsb3cgY29ubmVjdGlvbnMuXG4gKiAtIHVwbG9hZCBpcyB0aGUgdGltZSAgc2luY2UgbGFzdCBiaXQgb2YgZGF0YSB3YXMgc2VudCBvciByZWNlaXZlZC4gVGhpcyB0aW1lb3V0IHdvcmtzIG9ubHkgaWYgZGVhZGxpbmUgdGltZW91dCBpcyBvZmZcbiAqXG4gKiBWYWx1ZSBvZiAwIG9yIGZhbHNlIG1lYW5zIG5vIHRpbWVvdXQuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ8T2JqZWN0fSBtcyBvciB7cmVzcG9uc2UsIGRlYWRsaW5lfVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIHRoaXMuX3RpbWVvdXQgPSBvcHRpb25zO1xuICAgIHRoaXMuX3Jlc3BvbnNlVGltZW91dCA9IDA7XG4gICAgdGhpcy5fdXBsb2FkVGltZW91dCA9IDA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBmb3IgKGNvbnN0IG9wdGlvbiBpbiBvcHRpb25zKSB7XG4gICAgaWYgKGhhc093bihvcHRpb25zLCBvcHRpb24pKSB7XG4gICAgICBzd2l0Y2ggKG9wdGlvbikge1xuICAgICAgICBjYXNlICdkZWFkbGluZSc6IHtcbiAgICAgICAgICB0aGlzLl90aW1lb3V0ID0gb3B0aW9ucy5kZWFkbGluZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgJ3Jlc3BvbnNlJzoge1xuICAgICAgICAgIHRoaXMuX3Jlc3BvbnNlVGltZW91dCA9IG9wdGlvbnMucmVzcG9uc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjYXNlICd1cGxvYWQnOiB7XG4gICAgICAgICAgdGhpcy5fdXBsb2FkVGltZW91dCA9IG9wdGlvbnMudXBsb2FkO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgIGNvbnNvbGUud2FybignVW5rbm93biB0aW1lb3V0IG9wdGlvbicsIG9wdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IG51bWJlciBvZiByZXRyeSBhdHRlbXB0cyBvbiBlcnJvci5cbiAqXG4gKiBGYWlsZWQgcmVxdWVzdHMgd2lsbCBiZSByZXRyaWVkICdjb3VudCcgdGltZXMgaWYgdGltZW91dCBvciBlcnIuY29kZSA+PSA1MDAuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnJldHJ5ID0gZnVuY3Rpb24gKGNvdW50LCBmbikge1xuICAvLyBEZWZhdWx0IHRvIDEgaWYgbm8gY291bnQgcGFzc2VkIG9yIHRydWVcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDAgfHwgY291bnQgPT09IHRydWUpIGNvdW50ID0gMTtcbiAgaWYgKGNvdW50IDw9IDApIGNvdW50ID0gMDtcbiAgdGhpcy5fbWF4UmV0cmllcyA9IGNvdW50O1xuICB0aGlzLl9yZXRyaWVzID0gMDtcbiAgdGhpcy5fcmV0cnlDYWxsYmFjayA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vXG4vLyBOT1RFOiB3ZSBkbyBub3QgaW5jbHVkZSBFU09DS0VUVElNRURPVVQgYmVjYXVzZSB0aGF0IGlzIGZyb20gYHJlcXVlc3RgIHBhY2thZ2Vcbi8vICAgICAgIDxodHRwczovL2dpdGh1Yi5jb20vc2luZHJlc29yaHVzL2dvdC9wdWxsLzUzNz5cbi8vXG4vLyBOT1RFOiB3ZSBkbyBub3QgaW5jbHVkZSBFQUREUklORk8gYmVjYXVzZSBpdCB3YXMgcmVtb3ZlZCBmcm9tIGxpYnV2IGluIDIwMTRcbi8vICAgICAgIDxodHRwczovL2dpdGh1Yi5jb20vbGlidXYvbGlidXYvY29tbWl0LzAyZTFlYmQ0MGI4MDdiZTVhZjQ2MzQzZWE4NzMzMzFiMmVlNGU5YzE+XG4vLyAgICAgICA8aHR0cHM6Ly9naXRodWIuY29tL3JlcXVlc3QvcmVxdWVzdC9zZWFyY2g/cT1FU09DS0VUVElNRURPVVQmdW5zY29wZWRfcT1FU09DS0VUVElNRURPVVQ+XG4vL1xuLy9cbi8vIFRPRE86IGV4cG9zZSB0aGVzZSBhcyBjb25maWd1cmFibGUgZGVmYXVsdHNcbi8vXG5jb25zdCBFUlJPUl9DT0RFUyA9IG5ldyBTZXQoW1xuICAnRVRJTUVET1VUJyxcbiAgJ0VDT05OUkVTRVQnLFxuICAnRUFERFJJTlVTRScsXG4gICdFQ09OTlJFRlVTRUQnLFxuICAnRVBJUEUnLFxuICAnRU5PVEZPVU5EJyxcbiAgJ0VORVRVTlJFQUNIJyxcbiAgJ0VBSV9BR0FJTidcbl0pO1xuXG5jb25zdCBTVEFUVVNfQ09ERVMgPSBuZXcgU2V0KFtcbiAgNDA4LCA0MTMsIDQyOSwgNTAwLCA1MDIsIDUwMywgNTA0LCA1MjEsIDUyMiwgNTI0XG5dKTtcblxuLy8gVE9ETzogd2Ugd291bGQgbmVlZCB0byBtYWtlIHRoaXMgZWFzaWx5IGNvbmZpZ3VyYWJsZSBiZWZvcmUgYWRkaW5nIGl0IGluIChlLmcuIHNvbWUgbWlnaHQgd2FudCB0byBhZGQgUE9TVClcbi8vIGNvbnN0IE1FVEhPRFMgPSBuZXcgU2V0KFsnR0VUJywgJ1BVVCcsICdIRUFEJywgJ0RFTEVURScsICdPUFRJT05TJywgJ1RSQUNFJ10pO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHJlcXVlc3Qgc2hvdWxkIGJlIHJldHJpZWQuXG4gKiAoSW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL3NpbmRyZXNvcmh1cy9nb3QjcmV0cnkpXG4gKlxuICogQHBhcmFtIHtFcnJvcn0gZXJyIGFuIGVycm9yXG4gKiBAcGFyYW0ge1Jlc3BvbnNlfSBbcmVzXSByZXNwb25zZVxuICogQHJldHVybnMge0Jvb2xlYW59IGlmIHNlZ21lbnQgc2hvdWxkIGJlIHJldHJpZWRcbiAqL1xuUmVxdWVzdEJhc2UucHJvdG90eXBlLl9zaG91bGRSZXRyeSA9IGZ1bmN0aW9uIChlcnJvciwgcmVzKSB7XG4gIGlmICghdGhpcy5fbWF4UmV0cmllcyB8fCB0aGlzLl9yZXRyaWVzKysgPj0gdGhpcy5fbWF4UmV0cmllcykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICh0aGlzLl9yZXRyeUNhbGxiYWNrKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG92ZXJyaWRlID0gdGhpcy5fcmV0cnlDYWxsYmFjayhlcnJvciwgcmVzKTtcbiAgICAgIGlmIChvdmVycmlkZSA9PT0gdHJ1ZSkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAob3ZlcnJpZGUgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgICAvLyB1bmRlZmluZWQgZmFsbHMgYmFjayB0byBkZWZhdWx0c1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRPRE86IHdlIHdvdWxkIG5lZWQgdG8gbWFrZSB0aGlzIGVhc2lseSBjb25maWd1cmFibGUgYmVmb3JlIGFkZGluZyBpdCBpbiAoZS5nLiBzb21lIG1pZ2h0IHdhbnQgdG8gYWRkIFBPU1QpXG4gIC8qXG4gIGlmIChcbiAgICB0aGlzLnJlcSAmJlxuICAgIHRoaXMucmVxLm1ldGhvZCAmJlxuICAgICFNRVRIT0RTLmhhcyh0aGlzLnJlcS5tZXRob2QudG9VcHBlckNhc2UoKSlcbiAgKVxuICAgIHJldHVybiBmYWxzZTtcbiAgKi9cbiAgaWYgKHJlcyAmJiByZXMuc3RhdHVzICYmIFNUQVRVU19DT0RFUy5oYXMocmVzLnN0YXR1cykpIHJldHVybiB0cnVlO1xuICBpZiAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IuY29kZSAmJiBFUlJPUl9DT0RFUy5oYXMoZXJyb3IuY29kZSkpIHJldHVybiB0cnVlO1xuICAgIC8vIFN1cGVyYWdlbnQgdGltZW91dFxuICAgIGlmIChlcnJvci50aW1lb3V0ICYmIGVycm9yLmNvZGUgPT09ICdFQ09OTkFCT1JURUQnKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoZXJyb3IuY3Jvc3NEb21haW4pIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBSZXRyeSByZXF1ZXN0XG4gKlxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuX3JldHJ5ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmNsZWFyVGltZW91dCgpO1xuXG4gIC8vIG5vZGVcbiAgaWYgKHRoaXMucmVxKSB7XG4gICAgdGhpcy5yZXEgPSBudWxsO1xuICAgIHRoaXMucmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gIH1cblxuICB0aGlzLl9hYm9ydGVkID0gZmFsc2U7XG4gIHRoaXMudGltZWRvdXQgPSBmYWxzZTtcbiAgdGhpcy50aW1lZG91dEVycm9yID0gbnVsbDtcblxuICByZXR1cm4gdGhpcy5fZW5kKCk7XG59O1xuXG4vKipcbiAqIFByb21pc2Ugc3VwcG9ydFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc29sdmVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtyZWplY3RdXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICovXG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICBpZiAoIXRoaXMuX2Z1bGxmaWxsZWRQcm9taXNlKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgaWYgKHRoaXMuX2VuZENhbGxlZCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAnV2FybmluZzogc3VwZXJhZ2VudCByZXF1ZXN0IHdhcyBzZW50IHR3aWNlLCBiZWNhdXNlIGJvdGggLmVuZCgpIGFuZCAudGhlbigpIHdlcmUgY2FsbGVkLiBOZXZlciBjYWxsIC5lbmQoKSBpZiB5b3UgdXNlIHByb21pc2VzJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHNlbGYub24oJ2Fib3J0JywgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fbWF4UmV0cmllcyAmJiB0aGlzLl9tYXhSZXRyaWVzID4gdGhpcy5fcmV0cmllcykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnRpbWVkb3V0ICYmIHRoaXMudGltZWRvdXRFcnJvcikge1xuICAgICAgICAgIHJlamVjdCh0aGlzLnRpbWVkb3V0RXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCdBYm9ydGVkJyk7XG4gICAgICAgIGVycm9yLmNvZGUgPSAnQUJPUlRFRCc7XG4gICAgICAgIGVycm9yLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICAgICAgICBlcnJvci5tZXRob2QgPSB0aGlzLm1ldGhvZDtcbiAgICAgICAgZXJyb3IudXJsID0gdGhpcy51cmw7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgICAgIHNlbGYuZW5kKChlcnJvciwgcmVzKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgZWxzZSByZXNvbHZlKHJlcyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG59O1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuY2F0Y2ggPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgcmV0dXJuIHRoaXMudGhlbih1bmRlZmluZWQsIGNhbGxiYWNrKTtcbn07XG5cbi8qKlxuICogQWxsb3cgZm9yIGV4dGVuc2lvblxuICovXG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiAoZm4pIHtcbiAgZm4odGhpcyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLm9rID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHRocm93IG5ldyBFcnJvcignQ2FsbGJhY2sgcmVxdWlyZWQnKTtcbiAgdGhpcy5fb2tDYWxsYmFjayA9IGNhbGxiYWNrO1xuICByZXR1cm4gdGhpcztcbn07XG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS5faXNSZXNwb25zZU9LID0gZnVuY3Rpb24gKHJlcykge1xuICBpZiAoIXJlcykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICh0aGlzLl9va0NhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMuX29rQ2FsbGJhY2socmVzKTtcbiAgfVxuXG4gIHJldHVybiByZXMuc3RhdHVzID49IDIwMCAmJiByZXMuc3RhdHVzIDwgMzAwO1xufTtcblxuLyoqXG4gKiBHZXQgcmVxdWVzdCBoZWFkZXIgYGZpZWxkYC5cbiAqIENhc2UtaW5zZW5zaXRpdmUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoZmllbGQpIHtcbiAgcmV0dXJuIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbn07XG5cbi8qKlxuICogR2V0IGNhc2UtaW5zZW5zaXRpdmUgaGVhZGVyIGBmaWVsZGAgdmFsdWUuXG4gKiBUaGlzIGlzIGEgZGVwcmVjYXRlZCBpbnRlcm5hbCBBUEkuIFVzZSBgLmdldChmaWVsZClgIGluc3RlYWQuXG4gKlxuICogKGdldEhlYWRlciBpcyBubyBsb25nZXIgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBzdXBlcmFnZW50IGNvZGUgYmFzZSlcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICogQGRlcHJlY2F0ZWRcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuZ2V0SGVhZGVyID0gUmVxdWVzdEJhc2UucHJvdG90eXBlLmdldDtcblxuLyoqXG4gKiBTZXQgaGVhZGVyIGBmaWVsZGAgdG8gYHZhbGAsIG9yIG11bHRpcGxlIGZpZWxkcyB3aXRoIG9uZSBvYmplY3QuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICogICAgICAgIC5zZXQoJ1gtQVBJLUtleScsICdmb29iYXInKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCh7IEFjY2VwdDogJ2FwcGxpY2F0aW9uL2pzb24nLCAnWC1BUEktS2V5JzogJ2Zvb2JhcicgfSlcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGZpZWxkXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChmaWVsZCwgdmFsdWUpIHtcbiAgaWYgKGlzT2JqZWN0KGZpZWxkKSkge1xuICAgIGZvciAoY29uc3Qga2V5IGluIGZpZWxkKSB7XG4gICAgICBpZiAoaGFzT3duKGZpZWxkLCBrZXkpKSB0aGlzLnNldChrZXksIGZpZWxkW2tleV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldID0gdmFsdWU7XG4gIHRoaXMuaGVhZGVyW2ZpZWxkXSA9IHZhbHVlO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGhlYWRlciBgZmllbGRgLlxuICogQ2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnVuc2V0KCdVc2VyLUFnZW50JylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGQgZmllbGQgbmFtZVxuICovXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUudW5zZXQgPSBmdW5jdGlvbiAoZmllbGQpIHtcbiAgZGVsZXRlIHRoaXMuX2hlYWRlcltmaWVsZC50b0xvd2VyQ2FzZSgpXTtcbiAgZGVsZXRlIHRoaXMuaGVhZGVyW2ZpZWxkXTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFdyaXRlIHRoZSBmaWVsZCBgbmFtZWAgYW5kIGB2YWxgLCBvciBtdWx0aXBsZSBmaWVsZHMgd2l0aCBvbmUgb2JqZWN0XG4gKiBmb3IgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCIgcmVxdWVzdCBib2RpZXMuXG4gKlxuICogYGBgIGpzXG4gKiByZXF1ZXN0LnBvc3QoJy91cGxvYWQnKVxuICogICAuZmllbGQoJ2ZvbycsICdiYXInKVxuICogICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiByZXF1ZXN0LnBvc3QoJy91cGxvYWQnKVxuICogICAuZmllbGQoeyBmb286ICdiYXInLCBiYXo6ICdxdXgnIH0pXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBuYW1lIG5hbWUgb2YgZmllbGRcbiAqIEBwYXJhbSB7U3RyaW5nfEJsb2J8RmlsZXxCdWZmZXJ8ZnMuUmVhZFN0cmVhbX0gdmFsIHZhbHVlIG9mIGZpZWxkXG4gKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucyBleHRyYSBvcHRpb25zLCBlLmcuICdibG9iJ1xuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuZmllbGQgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIG9wdGlvbnMpIHtcbiAgLy8gbmFtZSBzaG91bGQgYmUgZWl0aGVyIGEgc3RyaW5nIG9yIGFuIG9iamVjdC5cbiAgaWYgKG5hbWUgPT09IG51bGwgfHwgdW5kZWZpbmVkID09PSBuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCcuZmllbGQobmFtZSwgdmFsKSBuYW1lIGNhbiBub3QgYmUgZW1wdHknKTtcbiAgfVxuXG4gIGlmICh0aGlzLl9kYXRhKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCIuZmllbGQoKSBjYW4ndCBiZSB1c2VkIGlmIC5zZW5kKCkgaXMgdXNlZC4gUGxlYXNlIHVzZSBvbmx5IC5zZW5kKCkgb3Igb25seSAuZmllbGQoKSAmIC5hdHRhY2goKVwiXG4gICAgKTtcbiAgfVxuXG4gIGlmIChpc09iamVjdChuYW1lKSkge1xuICAgIGZvciAoY29uc3Qga2V5IGluIG5hbWUpIHtcbiAgICAgIGlmIChoYXNPd24obmFtZSwga2V5KSkgdGhpcy5maWVsZChrZXksIG5hbWVba2V5XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBmb3IgKGNvbnN0IGkgaW4gdmFsdWUpIHtcbiAgICAgIGlmIChoYXNPd24odmFsdWUsIGkpKSB0aGlzLmZpZWxkKG5hbWUsIHZhbHVlW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHZhbCBzaG91bGQgYmUgZGVmaW5lZCBub3dcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHVuZGVmaW5lZCA9PT0gdmFsdWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJy5maWVsZChuYW1lLCB2YWwpIHZhbCBjYW4gbm90IGJlIGVtcHR5Jyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICB2YWx1ZSA9IFN0cmluZyh2YWx1ZSk7XG4gIH1cblxuICAvLyBmaXggaHR0cHM6Ly9naXRodWIuY29tL2xhZGpzL3N1cGVyYWdlbnQvaXNzdWVzLzE2ODBcbiAgaWYgKG9wdGlvbnMpIHRoaXMuX2dldEZvcm1EYXRhKCkuYXBwZW5kKG5hbWUsIHZhbHVlLCBvcHRpb25zKTtcbiAgZWxzZSB0aGlzLl9nZXRGb3JtRGF0YSgpLmFwcGVuZChuYW1lLCB2YWx1ZSk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFib3J0IHRoZSByZXF1ZXN0LCBhbmQgY2xlYXIgcG90ZW50aWFsIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH0gcmVxdWVzdFxuICogQGFwaSBwdWJsaWNcbiAqL1xuUmVxdWVzdEJhc2UucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5fYWJvcnRlZCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdGhpcy5fYWJvcnRlZCA9IHRydWU7XG4gIGlmICh0aGlzLnhocikgdGhpcy54aHIuYWJvcnQoKTsgLy8gYnJvd3NlclxuICBpZiAodGhpcy5yZXEpIHtcbiAgICAvLyBOb2RlIHYxMyBoYXMgbWFqb3IgZGlmZmVyZW5jZXMgaW4gYGFib3J0KClgXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvdjEyLngvbGliL2ludGVybmFsL3N0cmVhbXMvZW5kLW9mLXN0cmVhbS5qc1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iL3YxMy54L2xpYi9pbnRlcm5hbC9zdHJlYW1zL2VuZC1vZi1zdHJlYW0uanNcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvYmxvYi92MTQueC9saWIvaW50ZXJuYWwvc3RyZWFtcy9lbmQtb2Ytc3RyZWFtLmpzXG4gICAgLy8gKGlmIHlvdSBydW4gYSBkaWZmIGFjcm9zcyB0aGVzZSB5b3Ugd2lsbCBzZWUgdGhlIGRpZmZlcmVuY2VzKVxuICAgIC8vXG4gICAgLy8gUmVmZXJlbmNlczpcbiAgICAvLyA8aHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2lzc3Vlcy8zMTYzMD5cbiAgICAvLyA8aHR0cHM6Ly9naXRodWIuY29tL2xhZGpzL3N1cGVyYWdlbnQvcHVsbC8xMDg0L2NvbW1pdHMvZGMxODY3OWE3YzVjY2ZjNjA0NmQ4ODIwMTVlNTEyNjg4ODk3M2JjOD5cbiAgICAvL1xuICAgIC8vIFRoYW5rcyB0byBAc2hhZG93Z2F0ZTE1IGFuZCBAbmlmdHlsZXR0dWNlXG4gICAgaWYgKFxuICAgICAgc2VtdmVyLmd0ZShwcm9jZXNzLnZlcnNpb24sICd2MTMuMC4wJykgJiZcbiAgICAgIHNlbXZlci5sdChwcm9jZXNzLnZlcnNpb24sICd2MTQuMC4wJylcbiAgICApIHtcbiAgICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIHRoaXMgZG9lc24ndCB3b3JrIGlzIGJlY2F1c2UgaW4gdjEzIGFzIGNvbXBhcmVkIHRvIHYxNFxuICAgICAgLy8gdGhlcmUgaXMgbm8gYGNhbGxiYWNrID0gbm9wYCBzZXQgaW4gZW5kLW9mLXN0cmVhbS5qcyBhYm92ZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnU3VwZXJhZ2VudCBkb2VzIG5vdCB3b3JrIGluIHYxMyBwcm9wZXJseSB3aXRoIGFib3J0KCkgZHVlIHRvIE5vZGUuanMgY29yZSBjaGFuZ2VzJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcS5hYm9ydCgpOyAvLyBub2RlXG4gIH1cblxuICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICB0aGlzLmVtaXQoJ2Fib3J0Jyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLl9hdXRoID0gZnVuY3Rpb24gKHVzZXIsIHBhc3MsIG9wdGlvbnMsIGJhc2U2NEVuY29kZXIpIHtcbiAgc3dpdGNoIChvcHRpb25zLnR5cGUpIHtcbiAgICBjYXNlICdiYXNpYyc6IHtcbiAgICAgIHRoaXMuc2V0KCdBdXRob3JpemF0aW9uJywgYEJhc2ljICR7YmFzZTY0RW5jb2RlcihgJHt1c2VyfToke3Bhc3N9YCl9YCk7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjYXNlICdhdXRvJzoge1xuICAgICAgdGhpcy51c2VybmFtZSA9IHVzZXI7XG4gICAgICB0aGlzLnBhc3N3b3JkID0gcGFzcztcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGNhc2UgJ2JlYXJlcic6IHtcbiAgICAgIC8vIHVzYWdlIHdvdWxkIGJlIC5hdXRoKGFjY2Vzc1Rva2VuLCB7IHR5cGU6ICdiZWFyZXInIH0pXG4gICAgICB0aGlzLnNldCgnQXV0aG9yaXphdGlvbicsIGBCZWFyZXIgJHt1c2VyfWApO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZGVmYXVsdDoge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEVuYWJsZSB0cmFuc21pc3Npb24gb2YgY29va2llcyB3aXRoIHgtZG9tYWluIHJlcXVlc3RzLlxuICpcbiAqIE5vdGUgdGhhdCBmb3IgdGhpcyB0byB3b3JrIHRoZSBvcmlnaW4gbXVzdCBub3QgYmVcbiAqIHVzaW5nIFwiQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luXCIgd2l0aCBhIHdpbGRjYXJkLFxuICogYW5kIGFsc28gbXVzdCBzZXQgXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFsc1wiXG4gKiB0byBcInRydWVcIi5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29uPXRydWVdIC0gU2V0ICd3aXRoQ3JlZGVudGlhbHMnIHN0YXRlXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLndpdGhDcmVkZW50aWFscyA9IGZ1bmN0aW9uIChvbikge1xuICAvLyBUaGlzIGlzIGJyb3dzZXItb25seSBmdW5jdGlvbmFsaXR5LiBOb2RlIHNpZGUgaXMgbm8tb3AuXG4gIGlmIChvbiA9PT0gdW5kZWZpbmVkKSBvbiA9IHRydWU7XG4gIHRoaXMuX3dpdGhDcmVkZW50aWFscyA9IG9uO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRoZSBtYXggcmVkaXJlY3RzIHRvIGBuYC4gRG9lcyBub3RoaW5nIGluIGJyb3dzZXIgWEhSIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnJlZGlyZWN0cyA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuX21heFJlZGlyZWN0cyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBNYXhpbXVtIHNpemUgb2YgYnVmZmVyZWQgcmVzcG9uc2UgYm9keSwgaW4gYnl0ZXMuIENvdW50cyB1bmNvbXByZXNzZWQgc2l6ZS5cbiAqIERlZmF1bHQgMjAwTUIuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG4gbnVtYmVyIG9mIGJ5dGVzXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqL1xuUmVxdWVzdEJhc2UucHJvdG90eXBlLm1heFJlc3BvbnNlU2l6ZSA9IGZ1bmN0aW9uIChuKSB7XG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGFyZ3VtZW50Jyk7XG4gIH1cblxuICB0aGlzLl9tYXhSZXNwb25zZVNpemUgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ29udmVydCB0byBhIHBsYWluIGphdmFzY3JpcHQgb2JqZWN0IChub3QgSlNPTiBzdHJpbmcpIG9mIHNjYWxhciBwcm9wZXJ0aWVzLlxuICogTm90ZSBhcyB0aGlzIG1ldGhvZCBpcyBkZXNpZ25lZCB0byByZXR1cm4gYSB1c2VmdWwgbm9uLXRoaXMgdmFsdWUsXG4gKiBpdCBjYW5ub3QgYmUgY2hhaW5lZC5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRlc2NyaWJpbmcgbWV0aG9kLCB1cmwsIGFuZCBkYXRhIG9mIHRoaXMgcmVxdWVzdFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4ge1xuICAgIG1ldGhvZDogdGhpcy5tZXRob2QsXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBkYXRhOiB0aGlzLl9kYXRhLFxuICAgIGhlYWRlcnM6IHRoaXMuX2hlYWRlclxuICB9O1xufTtcblxuLyoqXG4gKiBTZW5kIGBkYXRhYCBhcyB0aGUgcmVxdWVzdCBib2R5LCBkZWZhdWx0aW5nIHRoZSBgLnR5cGUoKWAgdG8gXCJqc29uXCIgd2hlblxuICogYW4gb2JqZWN0IGlzIGdpdmVuLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgIC8vIG1hbnVhbCBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2pzb24nKVxuICogICAgICAgICAuc2VuZCgne1wibmFtZVwiOlwidGpcIn0nKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8ganNvblxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIG1hbnVhbCB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnZm9ybScpXG4gKiAgICAgICAgIC5zZW5kKCduYW1lPXRqJylcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBhdXRvIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gZGVmYXVsdHMgdG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKCduYW1lPXRvYmknKVxuICogICAgICAgIC5zZW5kKCdzcGVjaWVzPWZlcnJldCcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGRhdGFcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoZGF0YSkge1xuICBjb25zdCBpc09iamVjdF8gPSBpc09iamVjdChkYXRhKTtcbiAgbGV0IHR5cGUgPSB0aGlzLl9oZWFkZXJbJ2NvbnRlbnQtdHlwZSddO1xuXG4gIGlmICh0aGlzLl9mb3JtRGF0YSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwiLnNlbmQoKSBjYW4ndCBiZSB1c2VkIGlmIC5hdHRhY2goKSBvciAuZmllbGQoKSBpcyB1c2VkLiBQbGVhc2UgdXNlIG9ubHkgLnNlbmQoKSBvciBvbmx5IC5maWVsZCgpICYgLmF0dGFjaCgpXCJcbiAgICApO1xuICB9XG5cbiAgaWYgKGlzT2JqZWN0XyAmJiAhdGhpcy5fZGF0YSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICB0aGlzLl9kYXRhID0gW107XG4gICAgfSBlbHNlIGlmICghdGhpcy5faXNIb3N0KGRhdGEpKSB7XG4gICAgICB0aGlzLl9kYXRhID0ge307XG4gICAgfVxuICB9IGVsc2UgaWYgKGRhdGEgJiYgdGhpcy5fZGF0YSAmJiB0aGlzLl9pc0hvc3QodGhpcy5fZGF0YSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBtZXJnZSB0aGVzZSBzZW5kIGNhbGxzXCIpO1xuICB9XG5cbiAgLy8gbWVyZ2VcbiAgaWYgKGlzT2JqZWN0XyAmJiBpc09iamVjdCh0aGlzLl9kYXRhKSkge1xuICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICAgIGlmICh0eXBlb2YgZGF0YVtrZXldID09PSAnYmlnaW50JylcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3Qgc2VyaWFsaXplIEJpZ0ludCB2YWx1ZSB0byBqc29uJyk7XG4gICAgICBpZiAoaGFzT3duKGRhdGEsIGtleSkpIHRoaXMuX2RhdGFba2V5XSA9IGRhdGFba2V5XTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIGRhdGEgPT09ICdiaWdpbnQnKVxuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHNlbmQgdmFsdWUgb2YgdHlwZSBCaWdJbnQnKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gZGVmYXVsdCB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgICBpZiAoIXR5cGUpIHRoaXMudHlwZSgnZm9ybScpO1xuICAgIHR5cGUgPSB0aGlzLl9oZWFkZXJbJ2NvbnRlbnQtdHlwZSddO1xuICAgIGlmICh0eXBlKSB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgICBpZiAodHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpIHtcbiAgICAgIHRoaXMuX2RhdGEgPSB0aGlzLl9kYXRhID8gYCR7dGhpcy5fZGF0YX0mJHtkYXRhfWAgOiBkYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kYXRhID0gKHRoaXMuX2RhdGEgfHwgJycpICsgZGF0YTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gIH1cblxuICBpZiAoIWlzT2JqZWN0XyB8fCB0aGlzLl9pc0hvc3QoZGF0YSkpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGRlZmF1bHQgdG8ganNvblxuICBpZiAoIXR5cGUpIHRoaXMudHlwZSgnanNvbicpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU29ydCBgcXVlcnlzdHJpbmdgIGJ5IHRoZSBzb3J0IGZ1bmN0aW9uXG4gKlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgIC8vIGRlZmF1bHQgb3JkZXJcbiAqICAgICAgIHJlcXVlc3QuZ2V0KCcvdXNlcicpXG4gKiAgICAgICAgIC5xdWVyeSgnbmFtZT1OaWNrJylcbiAqICAgICAgICAgLnF1ZXJ5KCdzZWFyY2g9TWFubnknKVxuICogICAgICAgICAuc29ydFF1ZXJ5KClcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBjdXN0b21pemVkIHNvcnQgZnVuY3Rpb25cbiAqICAgICAgIHJlcXVlc3QuZ2V0KCcvdXNlcicpXG4gKiAgICAgICAgIC5xdWVyeSgnbmFtZT1OaWNrJylcbiAqICAgICAgICAgLnF1ZXJ5KCdzZWFyY2g9TWFubnknKVxuICogICAgICAgICAuc29ydFF1ZXJ5KGZ1bmN0aW9uKGEsIGIpe1xuICogICAgICAgICAgIHJldHVybiBhLmxlbmd0aCAtIGIubGVuZ3RoO1xuICogICAgICAgICB9KVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzb3J0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdEJhc2UucHJvdG90eXBlLnNvcnRRdWVyeSA9IGZ1bmN0aW9uIChzb3J0KSB7XG4gIC8vIF9zb3J0IGRlZmF1bHQgdG8gdHJ1ZSBidXQgb3RoZXJ3aXNlIGNhbiBiZSBhIGZ1bmN0aW9uIG9yIGJvb2xlYW5cbiAgdGhpcy5fc29ydCA9IHNvcnQgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBzb3J0O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ29tcG9zZSBxdWVyeXN0cmluZyB0byBhcHBlbmQgdG8gcmVxLnVybFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5SZXF1ZXN0QmFzZS5wcm90b3R5cGUuX2ZpbmFsaXplUXVlcnlTdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHF1ZXJ5ID0gdGhpcy5fcXVlcnkuam9pbignJicpO1xuICBpZiAocXVlcnkpIHtcbiAgICB0aGlzLnVybCArPSAodGhpcy51cmwuaW5jbHVkZXMoJz8nKSA/ICcmJyA6ICc/JykgKyBxdWVyeTtcbiAgfVxuXG4gIHRoaXMuX3F1ZXJ5Lmxlbmd0aCA9IDA7IC8vIE1ha2VzIHRoZSBjYWxsIGlkZW1wb3RlbnRcblxuICBpZiAodGhpcy5fc29ydCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy51cmwuaW5kZXhPZignPycpO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICBjb25zdCBxdWVyeUFycmF5ID0gdGhpcy51cmwuc2xpY2UoaW5kZXggKyAxKS5zcGxpdCgnJicpO1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLl9zb3J0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHF1ZXJ5QXJyYXkuc29ydCh0aGlzLl9zb3J0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXJ5QXJyYXkuc29ydCgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnVybCA9IHRoaXMudXJsLnNsaWNlKDAsIGluZGV4KSArICc/JyArIHF1ZXJ5QXJyYXkuam9pbignJicpO1xuICAgIH1cbiAgfVxufTtcblxuLy8gRm9yIGJhY2t3YXJkcyBjb21wYXQgb25seVxuUmVxdWVzdEJhc2UucHJvdG90eXBlLl9hcHBlbmRRdWVyeVN0cmluZyA9ICgpID0+IHtcbiAgY29uc29sZS53YXJuKCdVbnN1cHBvcnRlZCcpO1xufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgd2l0aCB0aW1lb3V0IGVycm9yLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS5fdGltZW91dEVycm9yID0gZnVuY3Rpb24gKHJlYXNvbiwgdGltZW91dCwgZXJybm8pIHtcbiAgaWYgKHRoaXMuX2Fib3J0ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcihgJHtyZWFzb24gKyB0aW1lb3V0fW1zIGV4Y2VlZGVkYCk7XG4gIGVycm9yLnRpbWVvdXQgPSB0aW1lb3V0O1xuICBlcnJvci5jb2RlID0gJ0VDT05OQUJPUlRFRCc7XG4gIGVycm9yLmVycm5vID0gZXJybm87XG4gIHRoaXMudGltZWRvdXQgPSB0cnVlO1xuICB0aGlzLnRpbWVkb3V0RXJyb3IgPSBlcnJvcjtcbiAgdGhpcy5hYm9ydCgpO1xuICB0aGlzLmNhbGxiYWNrKGVycm9yKTtcbn07XG5cblJlcXVlc3RCYXNlLnByb3RvdHlwZS5fc2V0VGltZW91dHMgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gIC8vIGRlYWRsaW5lXG4gIGlmICh0aGlzLl90aW1lb3V0ICYmICF0aGlzLl90aW1lcikge1xuICAgIHRoaXMuX3RpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBzZWxmLl90aW1lb3V0RXJyb3IoJ1RpbWVvdXQgb2YgJywgc2VsZi5fdGltZW91dCwgJ0VUSU1FJyk7XG4gICAgfSwgdGhpcy5fdGltZW91dCk7XG4gIH1cblxuICAvLyByZXNwb25zZSB0aW1lb3V0XG4gIGlmICh0aGlzLl9yZXNwb25zZVRpbWVvdXQgJiYgIXRoaXMuX3Jlc3BvbnNlVGltZW91dFRpbWVyKSB7XG4gICAgdGhpcy5fcmVzcG9uc2VUaW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHNlbGYuX3RpbWVvdXRFcnJvcihcbiAgICAgICAgJ1Jlc3BvbnNlIHRpbWVvdXQgb2YgJyxcbiAgICAgICAgc2VsZi5fcmVzcG9uc2VUaW1lb3V0LFxuICAgICAgICAnRVRJTUVET1VUJ1xuICAgICAgKTtcbiAgICB9LCB0aGlzLl9yZXNwb25zZVRpbWVvdXQpO1xuICB9XG59O1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFFBQVEsQ0FBQzs7QUFFaEM7QUFDQTtBQUNBO0FBQ0EsTUFBQUMsUUFBQSxHQUE2QkQsT0FBTyxDQUFDLFNBQVMsQ0FBQztFQUF2Q0UsUUFBUSxHQUFBRCxRQUFBLENBQVJDLFFBQVE7RUFBRUMsTUFBTSxHQUFBRixRQUFBLENBQU5FLE1BQU07O0FBRXhCO0FBQ0E7QUFDQTs7QUFFQUMsTUFBTSxDQUFDQyxPQUFPLEdBQUdDLFdBQVc7O0FBRTVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBU0EsV0FBV0EsQ0FBQSxFQUFHLENBQUM7O0FBRXhCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQUEsV0FBVyxDQUFDQyxTQUFTLENBQUNDLFlBQVksR0FBRyxZQUFZO0VBQy9DQSxZQUFZLENBQUMsSUFBSSxDQUFDQyxNQUFNLENBQUM7RUFDekJELFlBQVksQ0FBQyxJQUFJLENBQUNFLHFCQUFxQixDQUFDO0VBQ3hDRixZQUFZLENBQUMsSUFBSSxDQUFDRyxtQkFBbUIsQ0FBQztFQUN0QyxPQUFPLElBQUksQ0FBQ0YsTUFBTTtFQUNsQixPQUFPLElBQUksQ0FBQ0MscUJBQXFCO0VBQ2pDLE9BQU8sSUFBSSxDQUFDQyxtQkFBbUI7RUFDL0Is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
\No newline at end of file