jsforce
Version:
Salesforce API Library for JavaScript
292 lines (288 loc) • 39.9 kB
JavaScript
import "core-js/modules/es.error.cause.js";
import "core-js/modules/es.array.push.js";
import "core-js/modules/es.object.to-string.js";
import "core-js/modules/es.regexp.to-string.js";
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
import _getIteratorMethod from "@babel/runtime-corejs3/core-js/get-iterator-method";
import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array";
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty";
import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator";
var _excluded = ["url", "body"];
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof _Symbol && _getIteratorMethod(r) || r["@@iterator"]; if (!t) { if (_Array$isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { var _context8; if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = _sliceInstanceProperty(_context8 = {}.toString.call(r)).call(_context8, 8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator";
import "core-js/modules/es.function.name.js";
import "core-js/modules/es.regexp.exec.js";
import "core-js/modules/es.regexp.test.js";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _setTimeout from "@babel/runtime-corejs3/core-js-stable/set-timeout";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _keysInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/keys";
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context6, _context7; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context6 = ownKeys(Object(t), !0)).call(_context6, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context7 = ownKeys(Object(t))).call(_context7, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
import { Readable } from 'stream';
import fetch, { Response } from 'node-fetch';
import createHttpsProxyAgent from 'https-proxy-agent';
import { createHttpRequestHandlerStreams, executeWithTimeout, isRedirect, performRedirectRequest } from './request-helper';
import { getLogger } from './util/logger';
import is from '@sindresorhus/is';
/**
*
*/
var defaults = {};
/**
*
*/
export function setDefaults(defaults_) {
defaults = defaults_;
}
/**
*
*/
function startFetchRequest(_x, _x2, _x3, _x4, _x5) {
return _startFetchRequest.apply(this, arguments);
}
/**
*
*/
function _startFetchRequest() {
_startFetchRequest = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(request, options, input, output, emitter) {
var _options$retry$status, _options$retry, _options$retry$maxRet, _options$retry2, _options$retry$minTim, _options$retry3, _options$retry$timeou, _options$retry4, _options$retry$errorC, _options$retry5, _options$retry$method, _options$retry6, _options$timeout, _context4;
var counter,
logger,
httpProxy,
followRedirect,
agent,
url,
body,
rrequest,
controller,
retryCount,
retryOpts,
shouldRetryRequest,
_fetchWithRetries,
res,
fetchTimeout,
headers,
_iterator,
_step,
headerName,
response,
_args2 = arguments;
return _regeneratorRuntime.wrap(function _callee2$(_context5) {
while (1) switch (_context5.prev = _context5.next) {
case 0:
counter = _args2.length > 5 && _args2[5] !== undefined ? _args2[5] : 0;
logger = getLogger('fetch');
httpProxy = options.httpProxy, followRedirect = options.followRedirect;
agent = httpProxy ? createHttpsProxyAgent(httpProxy) : undefined;
url = request.url, body = request.body, rrequest = _objectWithoutProperties(request, _excluded);
controller = new AbortController();
retryCount = 0;
retryOpts = {
statusCodes: (_options$retry$status = (_options$retry = options.retry) === null || _options$retry === void 0 ? void 0 : _options$retry.statusCodes) !== null && _options$retry$status !== void 0 ? _options$retry$status : [420, 429, 500, 502, 503, 504],
maxRetries: (_options$retry$maxRet = (_options$retry2 = options.retry) === null || _options$retry2 === void 0 ? void 0 : _options$retry2.maxRetries) !== null && _options$retry$maxRet !== void 0 ? _options$retry$maxRet : 5,
minTimeout: (_options$retry$minTim = (_options$retry3 = options.retry) === null || _options$retry3 === void 0 ? void 0 : _options$retry3.minTimeout) !== null && _options$retry$minTim !== void 0 ? _options$retry$minTim : 500,
timeoutFactor: (_options$retry$timeou = (_options$retry4 = options.retry) === null || _options$retry4 === void 0 ? void 0 : _options$retry4.timeoutFactor) !== null && _options$retry$timeou !== void 0 ? _options$retry$timeou : 2,
errorCodes: (_options$retry$errorC = (_options$retry5 = options.retry) === null || _options$retry5 === void 0 ? void 0 : _options$retry5.errorCodes) !== null && _options$retry$errorC !== void 0 ? _options$retry$errorC : ['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN', 'ENETUNREACH', 'EHOSTDOWN', 'UND_ERR_SOCKET', 'ETIMEDOUT', 'EPIPE'],
methods: (_options$retry$method = (_options$retry6 = options.retry) === null || _options$retry6 === void 0 ? void 0 : _options$retry6.methods) !== null && _options$retry$method !== void 0 ? _options$retry$method : ['GET', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']
};
shouldRetryRequest = function shouldRetryRequest(maxRetry, resOrErr) {
var _context;
if (!_includesInstanceProperty(_context = retryOpts.methods).call(_context, request.method)) return false;
if (resOrErr instanceof Response) {
var _context2;
if (_includesInstanceProperty(_context2 = retryOpts.statusCodes).call(_context2, resOrErr.status)) {
if (maxRetry === retryCount) {
return false;
} else {
return true;
}
}
return false;
} else {
var _retryOpts$errorCodes;
if (maxRetry === retryCount) return false;
// only retry on operational errors
// https://github.com/node-fetch/node-fetch/blob/2.x/ERROR-HANDLING.md#error-handling-with-node-fetch
if (resOrErr.name != 'FetchError') return false;
if (is.nodeStream(body) && Readable.isDisturbed(body)) {
logger.debug('Body of type stream was read, unable to retry request.');
return false;
}
if ('code' in resOrErr && resOrErr.code && retryOpts !== null && retryOpts !== void 0 && (_retryOpts$errorCodes = retryOpts.errorCodes) !== null && _retryOpts$errorCodes !== void 0 && _includesInstanceProperty(_retryOpts$errorCodes).call(_retryOpts$errorCodes, resOrErr.code)) return true;
return false;
}
};
_fetchWithRetries = /*#__PURE__*/function () {
var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var maxRetry,
fetchOpts,
_res,
error,
_args = arguments;
return _regeneratorRuntime.wrap(function _callee$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
maxRetry = _args.length > 0 && _args[0] !== undefined ? _args[0] : retryOpts === null || retryOpts === void 0 ? void 0 : retryOpts.maxRetries;
fetchOpts = _objectSpread(_objectSpread(_objectSpread({}, rrequest), input && /^(post|put|patch)$/i.test(request.method) ? {
body: input
} : {}), {}, {
redirect: 'manual',
signal: controller.signal,
agent: agent
});
_context3.prev = 2;
_context3.next = 5;
return fetch(url, fetchOpts);
case 5:
_res = _context3.sent;
if (!shouldRetryRequest(retryOpts.maxRetries, _res)) {
_context3.next = 16;
break;
}
logger.debug("retrying for the ".concat(retryCount + 1, " time"));
logger.debug('reason: statusCode match');
_context3.next = 11;
return sleep(retryCount === 0 ? retryOpts.minTimeout : retryOpts.minTimeout * Math.pow(retryOpts.timeoutFactor, retryCount));
case 11:
// NOTE: this event is only used by tests and will be removed at any time.
// jsforce may switch to node's fetch which doesn't emit this event on retries.
emitter.emit('retry', retryCount);
retryCount++;
_context3.next = 15;
return _fetchWithRetries(maxRetry);
case 15:
return _context3.abrupt("return", _context3.sent);
case 16:
return _context3.abrupt("return", _res);
case 19:
_context3.prev = 19;
_context3.t0 = _context3["catch"](2);
logger.debug('Request failed');
error = _context3.t0; // request was canceled by consumer (AbortController), skip retry and rethrow.
if (!(error.name === 'AbortError')) {
_context3.next = 25;
break;
}
throw error;
case 25:
if (!shouldRetryRequest(retryOpts.maxRetries, error)) {
_context3.next = 33;
break;
}
logger.debug("retrying for the ".concat(retryCount + 1, " time"));
logger.debug("Error: ".concat(_context3.t0.message));
_context3.next = 30;
return sleep(retryCount === 0 ? retryOpts.minTimeout : retryOpts.minTimeout * Math.pow(retryOpts.timeoutFactor, retryCount));
case 30:
// NOTE: this event is only used by tests and will be removed at any time.
// jsforce may switch to node's fetch which doesn't emit this event on retries.
emitter.emit('retry', retryCount);
retryCount++;
return _context3.abrupt("return", _fetchWithRetries(maxRetry));
case 33:
logger.debug('Skipping retry...');
if (!(maxRetry === retryCount)) {
_context3.next = 38;
break;
}
throw _context3.t0;
case 38:
throw _context3.t0;
case 39:
case "end":
return _context3.stop();
}
}, _callee, null, [[2, 19]]);
}));
return function fetchWithRetries() {
return _ref.apply(this, arguments);
};
}();
// Timeout after 60s without a response
//
// node-fetch's default timeout is 0 and jsforce consumers can't set this when calling `Connection` methods so we set a long default at the fetch wrapper level.
fetchTimeout = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : 60000;
_context5.prev = 11;
_context5.next = 14;
return executeWithTimeout(_fetchWithRetries, fetchTimeout, function () {
return controller.abort();
});
case 14:
res = _context5.sent;
_context5.next = 21;
break;
case 17:
_context5.prev = 17;
_context5.t0 = _context5["catch"](11);
emitter.emit('error', _context5.t0);
return _context5.abrupt("return");
case 21:
headers = {};
_iterator = _createForOfIteratorHelper(_keysInstanceProperty(_context4 = res.headers).call(_context4));
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
headerName = _step.value;
headers[headerName.toLowerCase()] = res.headers.get(headerName);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
response = {
statusCode: res.status,
headers: headers
};
if (!(followRedirect && isRedirect(response.statusCode))) {
_context5.next = 28;
break;
}
try {
performRedirectRequest(request, response, followRedirect, counter, function (req) {
return startFetchRequest(req, options, undefined, output, emitter, counter + 1);
});
} catch (err) {
emitter.emit('error', err);
}
return _context5.abrupt("return");
case 28:
emitter.emit('response', response);
res.body.pipe(output);
case 30:
case "end":
return _context5.stop();
}
}, _callee2, null, [[11, 17]]);
}));
return _startFetchRequest.apply(this, arguments);
}
export default function request(req) {
var options_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = _objectSpread(_objectSpread({}, defaults), options_);
var _createHttpRequestHan = createHttpRequestHandlerStreams(req, options),
input = _createHttpRequestHan.input,
output = _createHttpRequestHan.output,
stream = _createHttpRequestHan.stream;
startFetchRequest(req, options, input, output, stream);
return stream;
}
var sleep = function sleep(ms) {
return new _Promise(function (r) {
return _setTimeout(r, ms);
});
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFkYWJsZSIsImZldGNoIiwiUmVzcG9uc2UiLCJjcmVhdGVIdHRwc1Byb3h5QWdlbnQiLCJjcmVhdGVIdHRwUmVxdWVzdEhhbmRsZXJTdHJlYW1zIiwiZXhlY3V0ZVdpdGhUaW1lb3V0IiwiaXNSZWRpcmVjdCIsInBlcmZvcm1SZWRpcmVjdFJlcXVlc3QiLCJnZXRMb2dnZXIiLCJpcyIsImRlZmF1bHRzIiwic2V0RGVmYXVsdHMiLCJkZWZhdWx0c18iLCJzdGFydEZldGNoUmVxdWVzdCIsIl94IiwiX3gyIiwiX3gzIiwiX3g0IiwiX3g1IiwiX3N0YXJ0RmV0Y2hSZXF1ZXN0IiwiYXBwbHkiLCJhcmd1bWVudHMiLCJfYXN5bmNUb0dlbmVyYXRvciIsIl9yZWdlbmVyYXRvclJ1bnRpbWUiLCJtYXJrIiwiX2NhbGxlZTIiLCJyZXF1ZXN0Iiwib3B0aW9ucyIsImlucHV0Iiwib3V0cHV0IiwiZW1pdHRlciIsIl9vcHRpb25zJHJldHJ5JHN0YXR1cyIsIl9vcHRpb25zJHJldHJ5IiwiX29wdGlvbnMkcmV0cnkkbWF4UmV0IiwiX29wdGlvbnMkcmV0cnkyIiwiX29wdGlvbnMkcmV0cnkkbWluVGltIiwiX29wdGlvbnMkcmV0cnkzIiwiX29wdGlvbnMkcmV0cnkkdGltZW91IiwiX29wdGlvbnMkcmV0cnk0IiwiX29wdGlvbnMkcmV0cnkkZXJyb3JDIiwiX29wdGlvbnMkcmV0cnk1IiwiX29wdGlvbnMkcmV0cnkkbWV0aG9kIiwiX29wdGlvbnMkcmV0cnk2IiwiX29wdGlvbnMkdGltZW91dCIsIl9jb250ZXh0NCIsImNvdW50ZXIiLCJsb2dnZXIiLCJodHRwUHJveHkiLCJmb2xsb3dSZWRpcmVjdCIsImFnZW50IiwidXJsIiwiYm9keSIsInJyZXF1ZXN0IiwiY29udHJvbGxlciIsInJldHJ5Q291bnQiLCJyZXRyeU9wdHMiLCJzaG91bGRSZXRyeVJlcXVlc3QiLCJfZmV0Y2hXaXRoUmV0cmllcyIsInJlcyIsImZldGNoVGltZW91dCIsImhlYWRlcnMiLCJfaXRlcmF0b3IiLCJfc3RlcCIsImhlYWRlck5hbWUiLCJyZXNwb25zZSIsIl9hcmdzMiIsIndyYXAiLCJfY2FsbGVlMiQiLCJfY29udGV4dDUiLCJwcmV2IiwibmV4dCIsImxlbmd0aCIsInVuZGVmaW5lZCIsIl9vYmplY3RXaXRob3V0UHJvcGVydGllcyIsIl9leGNsdWRlZCIsIkFib3J0Q29udHJvbGxlciIsInN0YXR1c0NvZGVzIiwicmV0cnkiLCJtYXhSZXRyaWVzIiwibWluVGltZW91dCIsInRpbWVvdXRGYWN0b3IiLCJlcnJvckNvZGVzIiwibWV0aG9kcyIsIm1heFJldHJ5IiwicmVzT3JFcnIiLCJfY29udGV4dCIsIl9pbmNsdWRlc0luc3RhbmNlUHJvcGVydHkiLCJjYWxsIiwibWV0aG9kIiwiX2NvbnRleHQyIiwic3RhdHVzIiwiX3JldHJ5T3B0cyRlcnJvckNvZGVzIiwibmFtZSIsIm5vZGVTdHJlYW0iLCJpc0Rpc3R1cmJlZCIsImRlYnVnIiwiY29kZSIsImZldGNoV2l0aFJldHJpZXMiLCJfcmVmIiwiX2NhbGxlZSIsImZldGNoT3B0cyIsIl9yZXMiLCJlcnJvciIsIl9hcmdzIiwiX2NhbGxlZSQiLCJfY29udGV4dDMiLCJfb2JqZWN0U3ByZWFkIiwidGVzdCIsInJlZGlyZWN0Iiwic2lnbmFsIiwic2VudCIsImNvbmNhdCIsInNsZWVwIiwiTWF0aCIsInBvdyIsImVtaXQiLCJhYnJ1cHQiLCJ0MCIsIm1lc3NhZ2UiLCJzdG9wIiwidGltZW91dCIsImFib3J0IiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJfa2V5c0luc3RhbmNlUHJvcGVydHkiLCJzIiwibiIsImRvbmUiLCJ2YWx1ZSIsInRvTG93ZXJDYXNlIiwiZ2V0IiwiZXJyIiwiZSIsImYiLCJzdGF0dXNDb2RlIiwicmVxIiwicGlwZSIsIm9wdGlvbnNfIiwiX2NyZWF0ZUh0dHBSZXF1ZXN0SGFuIiwic3RyZWFtIiwibXMiLCJfUHJvbWlzZSIsInIiLCJfc2V0VGltZW91dCJdLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ2V2ZW50cyc7XG5pbXBvcnQgeyBEdXBsZXgsIFJlYWRhYmxlLCBXcml0YWJsZSB9IGZyb20gJ3N0cmVhbSc7XG5pbXBvcnQgZmV0Y2gsIHsgUmVzcG9uc2UsIFJlcXVlc3RJbml0LCBGZXRjaEVycm9yIH0gZnJvbSAnbm9kZS1mZXRjaCc7XG5pbXBvcnQgY3JlYXRlSHR0cHNQcm94eUFnZW50IGZyb20gJ2h0dHBzLXByb3h5LWFnZW50JztcbmltcG9ydCB7XG4gIGNyZWF0ZUh0dHBSZXF1ZXN0SGFuZGxlclN0cmVhbXMsXG4gIGV4ZWN1dGVXaXRoVGltZW91dCxcbiAgaXNSZWRpcmVjdCxcbiAgcGVyZm9ybVJlZGlyZWN0UmVxdWVzdCxcbn0gZnJvbSAnLi9yZXF1ZXN0LWhlbHBlcic7XG5pbXBvcnQgeyBIdHRwUmVxdWVzdCwgSHR0cFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tICcuL3V0aWwvbG9nZ2VyJztcbmltcG9ydCBpcyBmcm9tICdAc2luZHJlc29yaHVzL2lzJztcblxuLyoqXG4gKlxuICovXG5sZXQgZGVmYXVsdHM6IEh0dHBSZXF1ZXN0T3B0aW9ucyA9IHt9O1xuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXREZWZhdWx0cyhkZWZhdWx0c186IEh0dHBSZXF1ZXN0T3B0aW9ucykge1xuICBkZWZhdWx0cyA9IGRlZmF1bHRzXztcbn1cblxuLyoqXG4gKlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFydEZldGNoUmVxdWVzdChcbiAgcmVxdWVzdDogSHR0cFJlcXVlc3QsXG4gIG9wdGlvbnM6IEh0dHBSZXF1ZXN0T3B0aW9ucyxcbiAgaW5wdXQ6IFJlYWRhYmxlIHwgdW5kZWZpbmVkLFxuICBvdXRwdXQ6IFdyaXRhYmxlLFxuICBlbWl0dGVyOiBFdmVudEVtaXR0ZXIsXG4gIGNvdW50ZXI6IG51bWJlciA9IDAsXG4pIHtcbiAgY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKCdmZXRjaCcpO1xuICBjb25zdCB7IGh0dHBQcm94eSwgZm9sbG93UmVkaXJlY3QgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGFnZW50ID0gaHR0cFByb3h5ID8gY3JlYXRlSHR0cHNQcm94eUFnZW50KGh0dHBQcm94eSkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHsgdXJsLCBib2R5LCAuLi5ycmVxdWVzdCB9ID0gcmVxdWVzdDtcbiAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBsZXQgcmV0cnlDb3VudCA9IDA7XG5cbiAgY29uc3QgcmV0cnlPcHRzOiBSZXF1aXJlZDxIdHRwUmVxdWVzdE9wdGlvbnNbJ3JldHJ5J10+ID0ge1xuICAgIHN0YXR1c0NvZGVzOiBvcHRpb25zLnJldHJ5Py5zdGF0dXNDb2RlcyA/PyBbNDIwLCA0MjksIDUwMCwgNTAyLCA1MDMsIDUwNF0sXG4gICAgbWF4UmV0cmllczogb3B0aW9ucy5yZXRyeT8ubWF4UmV0cmllcyA/PyA1LFxuICAgIG1pblRpbWVvdXQ6IG9wdGlvbnMucmV0cnk/Lm1pblRpbWVvdXQgPz8gNTAwLFxuICAgIHRpbWVvdXRGYWN0b3I6IG9wdGlvbnMucmV0cnk/LnRpbWVvdXRGYWN0b3IgPz8gMixcbiAgICBlcnJvckNvZGVzOiBvcHRpb25zLnJldHJ5Py5lcnJvckNvZGVzID8/IFtcbiAgICAgICdFQ09OTlJFU0VUJyxcbiAgICAgICdFQ09OTlJFRlVTRUQnLFxuICAgICAgJ0VOT1RGT1VORCcsXG4gICAgICAnRU5FVERPV04nLFxuICAgICAgJ0VORVRVTlJFQUNIJyxcbiAgICAgICdFSE9TVERPV04nLFxuICAgICAgJ1VORF9FUlJfU09DS0VUJyxcbiAgICAgICdFVElNRURPVVQnLFxuICAgICAgJ0VQSVBFJyxcbiAgICBdLFxuICAgIG1ldGhvZHM6IG9wdGlvbnMucmV0cnk/Lm1ldGhvZHMgPz8gW1xuICAgICAgJ0dFVCcsXG4gICAgICAnUFVUJyxcbiAgICAgICdIRUFEJyxcbiAgICAgICdPUFRJT05TJyxcbiAgICAgICdERUxFVEUnLFxuICAgIF0sXG4gIH07XG5cbiAgY29uc3Qgc2hvdWxkUmV0cnlSZXF1ZXN0ID0gKFxuICAgIG1heFJldHJ5OiBudW1iZXIsXG4gICAgcmVzT3JFcnI6IFJlc3BvbnNlIHwgRXJyb3IgfCBGZXRjaEVycm9yLFxuICApOiBib29sZWFuID0+IHtcbiAgICBpZiAoIXJldHJ5T3B0cy5tZXRob2RzLmluY2x1ZGVzKHJlcXVlc3QubWV0aG9kKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHJlc09yRXJyIGluc3RhbmNlb2YgUmVzcG9uc2UpIHtcbiAgICAgIGlmIChyZXRyeU9wdHMuc3RhdHVzQ29kZXMuaW5jbHVkZXMocmVzT3JFcnIuc3RhdHVzKSkge1xuICAgICAgICBpZiAobWF4UmV0cnkgPT09IHJldHJ5Q291bnQpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobWF4UmV0cnkgPT09IHJldHJ5Q291bnQpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gb25seSByZXRyeSBvbiBvcGVyYXRpb25hbCBlcnJvcnNcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlLWZldGNoL25vZGUtZmV0Y2gvYmxvYi8yLngvRVJST1ItSEFORExJTkcubWQjZXJyb3ItaGFuZGxpbmctd2l0aC1ub2RlLWZldGNoXG4gICAgICBpZiAocmVzT3JFcnIubmFtZSAhPSAnRmV0Y2hFcnJvcicpIHJldHVybiBmYWxzZTtcblxuICAgICAgaWYgKGlzLm5vZGVTdHJlYW0oYm9keSkgJiYgUmVhZGFibGUuaXNEaXN0dXJiZWQoYm9keSkpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdCb2R5IG9mIHR5cGUgc3RyZWFtIHdhcyByZWFkLCB1bmFibGUgdG8gcmV0cnkgcmVxdWVzdC4nKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICdjb2RlJyBpbiByZXNPckVyciAmJlxuICAgICAgICByZXNPckVyci5jb2RlICYmXG4gICAgICAgIHJldHJ5T3B0cz8uZXJyb3JDb2Rlcz8uaW5jbHVkZXMocmVzT3JFcnIuY29kZSlcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZmV0Y2hXaXRoUmV0cmllcyA9IGFzeW5jIChcbiAgICBtYXhSZXRyeSA9IHJldHJ5T3B0cz8ubWF4UmV0cmllcyxcbiAgKTogUHJvbWlzZTxSZXNwb25zZT4gPT4ge1xuICAgIGNvbnN0IGZldGNoT3B0czogUmVxdWVzdEluaXQgPSB7XG4gICAgICAuLi5ycmVxdWVzdCxcbiAgICAgIC4uLihpbnB1dCAmJiAvXihwb3N0fHB1dHxwYXRjaCkkL2kudGVzdChyZXF1ZXN0Lm1ldGhvZClcbiAgICAgICAgPyB7IGJvZHk6IGlucHV0IH1cbiAgICAgICAgOiB7fSksXG4gICAgICByZWRpcmVjdDogJ21hbnVhbCcsXG4gICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgYWdlbnQsXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIGZldGNoT3B0cyk7XG4gICAgICBpZiAoc2hvdWxkUmV0cnlSZXF1ZXN0KHJldHJ5T3B0cy5tYXhSZXRyaWVzLCByZXMpKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgcmV0cnlpbmcgZm9yIHRoZSAke3JldHJ5Q291bnQgKyAxfSB0aW1lYCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygncmVhc29uOiBzdGF0dXNDb2RlIG1hdGNoJyk7XG5cbiAgICAgICAgYXdhaXQgc2xlZXAoXG4gICAgICAgICAgcmV0cnlDb3VudCA9PT0gMFxuICAgICAgICAgICAgPyByZXRyeU9wdHMubWluVGltZW91dFxuICAgICAgICAgICAgOiByZXRyeU9wdHMubWluVGltZW91dCAqIHJldHJ5T3B0cy50aW1lb3V0RmFjdG9yICoqIHJldHJ5Q291bnQsXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gTk9URTogdGhpcyBldmVudCBpcyBvbmx5IHVzZWQgYnkgdGVzdHMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBhdCBhbnkgdGltZS5cbiAgICAgICAgLy8ganNmb3JjZSBtYXkgc3dpdGNoIHRvIG5vZGUncyBmZXRjaCB3aGljaCBkb2Vzbid0IGVtaXQgdGhpcyBldmVudCBvbiByZXRyaWVzLlxuICAgICAgICBlbWl0dGVyLmVtaXQoJ3JldHJ5JywgcmV0cnlDb3VudCk7XG4gICAgICAgIHJldHJ5Q291bnQrKztcblxuICAgICAgICByZXR1cm4gYXdhaXQgZmV0Y2hXaXRoUmV0cmllcyhtYXhSZXRyeSk7XG4gICAgICB9XG4gICAgICAvLyBzaG91bGQgd2UgdGhyb3cgaGVyZSBpZiB0aGUgbWF4UmV0cnkgYWxyZWFkeSBoYXBwZW5lZCBhbmQgc3RpbGwgZ290IHRoZSBzYW1lIHN0YXR1c0NvZGU/XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdSZXF1ZXN0IGZhaWxlZCcpO1xuICAgICAgY29uc3QgZXJyb3IgPSBlcnIgYXMgRXJyb3IgfCBGZXRjaEVycm9yO1xuXG4gICAgICAvLyByZXF1ZXN0IHdhcyBjYW5jZWxlZCBieSBjb25zdW1lciAoQWJvcnRDb250cm9sbGVyKSwgc2tpcCByZXRyeSBhbmQgcmV0aHJvdy5cbiAgICAgIGlmIChlcnJvci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG91bGRSZXRyeVJlcXVlc3QocmV0cnlPcHRzLm1heFJldHJpZXMsIGVycm9yKSkge1xuICAgICAgICBsb2dnZXIuZGVidWcoYHJldHJ5aW5nIGZvciB0aGUgJHtyZXRyeUNvdW50ICsgMX0gdGltZWApO1xuICAgICAgICBsb2dnZXIuZGVidWcoYEVycm9yOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cbiAgICAgICAgYXdhaXQgc2xlZXAoXG4gICAgICAgICAgcmV0cnlDb3VudCA9PT0gMFxuICAgICAgICAgICAgPyByZXRyeU9wdHMubWluVGltZW91dFxuICAgICAgICAgICAgOiByZXRyeU9wdHMubWluVGltZW91dCAqIHJldHJ5T3B0cy50aW1lb3V0RmFjdG9yICoqIHJldHJ5Q291bnQsXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gTk9URTogdGhpcyBldmVudCBpcyBvbmx5IHVzZWQgYnkgdGVzdHMgYW5kIHdpbGwgYmUgcmVtb3ZlZCBhdCBhbnkgdGltZS5cbiAgICAgICAgLy8ganNmb3JjZSBtYXkgc3dpdGNoIHRvIG5vZGUncyBmZXRjaCB3aGljaCBkb2Vzbid0IGVtaXQgdGhpcyBldmVudCBvbiByZXRyaWVzLlxuICAgICAgICBlbWl0dGVyLmVtaXQoJ3JldHJ5JywgcmV0cnlDb3VudCk7XG4gICAgICAgIHJldHJ5Q291bnQrKztcblxuICAgICAgICByZXR1cm4gZmV0Y2hXaXRoUmV0cmllcyhtYXhSZXRyeSk7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5kZWJ1ZygnU2tpcHBpbmcgcmV0cnkuLi4nKTtcblxuICAgICAgaWYgKG1heFJldHJ5ID09PSByZXRyeUNvdW50KSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgbGV0IHJlczogUmVzcG9uc2U7XG5cbiAgLy8gVGltZW91dCBhZnRlciA2MHMgd2l0aG91dCBhIHJlc3BvbnNlXG4gIC8vXG4gIC8vIG5vZGUtZmV0Y2gncyBkZWZhdWx0IHRpbWVvdXQgaXMgMCBhbmQganNmb3JjZSBjb25zdW1lcnMgY2FuJ3Qgc2V0IHRoaXMgd2hlbiBjYWxsaW5nIGBDb25uZWN0aW9uYCBtZXRob2RzIHNvIHdlIHNldCBhIGxvbmcgZGVmYXVsdCBhdCB0aGUgZmV0Y2ggd3JhcHBlciBsZXZlbC5cbiAgY29uc3QgZmV0Y2hUaW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0ID8/IDYwXzAwMFxuXG4gIHRyeSB7XG4gICAgcmVzID0gYXdhaXQgZXhlY3V0ZVdpdGhUaW1lb3V0KGZldGNoV2l0aFJldHJpZXMsIGZldGNoVGltZW91dCwgKCkgPT5cbiAgICAgIGNvbnRyb2xsZXIuYWJvcnQoKSxcbiAgICApO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlbWl0dGVyLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgaGVhZGVyczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuICBmb3IgKGNvbnN0IGhlYWRlck5hbWUgb2YgcmVzLmhlYWRlcnMua2V5cygpKSB7XG4gICAgaGVhZGVyc1toZWFkZXJOYW1lLnRvTG93ZXJDYXNlKCldID0gcmVzLmhlYWRlcnMuZ2V0KGhlYWRlck5hbWUpO1xuICB9XG4gIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXMsXG4gICAgaGVhZGVycyxcbiAgfTtcbiAgaWYgKGZvbGxvd1JlZGlyZWN0ICYmIGlzUmVkaXJlY3QocmVzcG9uc2Uuc3RhdHVzQ29kZSkpIHtcbiAgICB0cnkge1xuICAgICAgcGVyZm9ybVJlZGlyZWN0UmVxdWVzdChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgIGZvbGxvd1JlZGlyZWN0LFxuICAgICAgICBjb3VudGVyLFxuICAgICAgICAocmVxKSA9PlxuICAgICAgICAgIHN0YXJ0RmV0Y2hSZXF1ZXN0KFxuICAgICAgICAgICAgcmVxLFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG91dHB1dCxcbiAgICAgICAgICAgIGVtaXR0ZXIsXG4gICAgICAgICAgICBjb3VudGVyICsgMSxcbiAgICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGVtaXR0ZXIuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cbiAgZW1pdHRlci5lbWl0KCdyZXNwb25zZScsIHJlc3BvbnNlKTtcbiAgcmVzLmJvZHkucGlwZShvdXRwdXQpO1xufVxuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlcXVlc3QoXG4gIHJlcTogSHR0cFJlcXVlc3QsXG4gIG9wdGlvbnNfOiBIdHRwUmVxdWVzdE9wdGlvbnMgPSB7fSxcbik6IER1cGxleCB7XG4gIGNvbnN0IG9wdGlvbnMgPSB7IC4uLmRlZmF1bHRzLCAuLi5vcHRpb25zXyB9O1xuICBjb25zdCB7IGlucHV0LCBvdXRwdXQsIHN0cmVhbSB9ID0gY3JlYXRlSHR0cFJlcXVlc3RIYW5kbGVyU3RyZWFtcyhcbiAgICByZXEsXG4gICAgb3B0aW9ucyxcbiAgKTtcbiAgc3RhcnRGZXRjaFJlcXVlc3QocmVxLCBvcHRpb25zLCBpbnB1dCwgb3V0cHV0LCBzdHJlYW0pO1xuICByZXR1cm4gc3RyZWFtO1xufVxuXG5jb25zdCBzbGVlcCA9IChtczogbnVtYmVyKSA9PiBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsU0FBaUJBLFFBQVEsUUFBa0IsUUFBUTtBQUNuRCxPQUFPQyxLQUFLLElBQUlDLFFBQVEsUUFBaUMsWUFBWTtBQUNyRSxPQUFPQyxxQkFBcUIsTUFBTSxtQkFBbUI7QUFDckQsU0FDRUMsK0JBQStCLEVBQy9CQyxrQkFBa0IsRUFDbEJDLFVBQVUsRUFDVkMsc0JBQXNCLFFBQ2pCLGtCQUFrQjtBQUV6QixTQUFTQyxTQUFTLFFBQVEsZUFBZTtBQUN6QyxPQUFPQyxFQUFFLE1BQU0sa0JBQWtCOztBQUVqQztBQUNBO0FBQ0E7QUFDQSxJQUFJQyxRQUE0QixHQUFHLENBQUMsQ0FBQzs7QUFFckM7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTQyxXQUFXQSxDQUFDQyxTQUE2QixFQUFFO0VBQ3pERixRQUFRLEdBQUdFLFNBQVM7QUFDdEI7O0FBRUE7QUFDQTtBQUNBO0FBRkEsU0FHZUMsaUJBQWlCQSxDQUFBQyxFQUFBLEVBQUFDLEdBQUEsRUFBQUMsR0FBQSxFQUFBQyxHQUFBLEVBQUFDLEdBQUE7RUFBQSxPQUFBQyxrQkFBQSxDQUFBQyxLQUFBLE9BQUFDLFNBQUE7QUFBQTtBQXVNaEM7QUFDQTtBQUNBO0FBRkEsU0FBQUYsbUJBQUE7RUFBQUEsa0JBQUEsR0FBQUcsaUJBQUEsY0FBQUMsbUJBQUEsQ0FBQUMsSUFBQSxDQXZNQSxTQUFBQyxTQUNFQyxPQUFvQixFQUNwQkMsT0FBMkIsRUFDM0JDLEtBQTJCLEVBQzNCQyxNQUFnQixFQUNoQkMsT0FBcUI7SUFBQSxJQUFBQyxxQkFBQSxFQUFBQyxjQUFBLEVBQUFDLHFCQUFBLEVBQUFDLGVBQUEsRUFBQUMscUJBQUEsRUFBQUMsZUFBQSxFQUFBQyxxQkFBQSxFQUFBQyxlQUFBLEVBQUFDLHFCQUFBLEVBQUFDLGVBQUEsRUFBQUMscUJBQUEsRUFBQUMsZUFBQSxFQUFBQyxnQkFBQSxFQUFBQyxTQUFBO0lBQUEsSUFBQUMsT0FBQTtNQUFBQyxNQUFBO01BQUFDLFNBQUE7TUFBQUMsY0FBQTtNQUFBQyxLQUFBO01BQUFDLEdBQUE7TUFBQUMsSUFBQTtNQUFBQyxRQUFBO01BQUFDLFVBQUE7TUFBQUMsVUFBQTtNQUFBQyxTQUFBO01BQUFDLGtCQUFBO01BQUFDLGlCQUFBO01BQUFDLEdBQUE7TUFBQUMsWUFBQTtNQUFBQyxPQUFBO01BQUFDLFNBQUE7TUFBQUMsS0FBQTtNQUFBQyxVQUFBO01BQUFDLFFBQUE7TUFBQUMsTUFBQSxHQUFBNUMsU0FBQTtJQUFBLE9BQUFFLG1CQUFBLENBQUEyQyxJQUFBLFVBQUFDLFVBQUFDLFNBQUE7TUFBQSxrQkFBQUEsU0FBQSxDQUFBQyxJQUFBLEdBQUFELFNBQUEsQ0FBQUUsSUFBQTtRQUFBO1VBQ3JCekIsT0FBZSxHQUFBb0IsTUFBQSxDQUFBTSxNQUFBLFFBQUFOLE1BQUEsUUFBQU8sU0FBQSxHQUFBUCxNQUFBLE1BQUcsQ0FBQztVQUVibkIsTUFBTSxHQUFHdEMsU0FBUyxDQUFDLE9BQU8sQ0FBQztVQUN6QnVDLFNBQVMsR0FBcUJwQixPQUFPLENBQXJDb0IsU0FBUyxFQUFFQyxjQUFjLEdBQUtyQixPQUFPLENBQTFCcUIsY0FBYztVQUMzQkMsS0FBSyxHQUFHRixTQUFTLEdBQUc1QyxxQkFBcUIsQ0FBQzRDLFNBQVMsQ0FBQyxHQUFHeUIsU0FBUztVQUM5RHRCLEdBQUcsR0FBd0J4QixPQUFPLENBQWxDd0IsR0FBRyxFQUFFQyxJQUFJLEdBQWtCekIsT0FBTyxDQUE3QnlCLElBQUksRUFBS0MsUUFBUSxHQUFBcUIsd0JBQUEsQ0FBSy9DLE9BQU8sRUFBQWdELFNBQUE7VUFDcENyQixVQUFVLEdBQUcsSUFBSXNCLGVBQWUsQ0FBQyxDQUFDO1VBRXBDckIsVUFBVSxHQUFHLENBQUM7VUFFWkMsU0FBZ0QsR0FBRztZQUN2RHFCLFdBQVcsR0FBQTdDLHFCQUFBLElBQUFDLGNBQUEsR0FBRUwsT0FBTyxDQUFDa0QsS0FBSyxjQUFBN0MsY0FBQSx1QkFBYkEsY0FBQSxDQUFlNEMsV0FBVyxjQUFBN0MscUJBQUEsY0FBQUEscUJBQUEsR0FBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDO1lBQ3pFK0MsVUFBVSxHQUFBN0MscUJBQUEsSUFBQUMsZUFBQSxHQUFFUCxPQUFPLENBQUNrRCxLQUFLLGNBQUEzQyxlQUFBLHVCQUFiQSxlQUFBLENBQWU0QyxVQUFVLGNBQUE3QyxxQkFBQSxjQUFBQSxxQkFBQSxHQUFJLENBQUM7WUFDMUM4QyxVQUFVLEdBQUE1QyxxQkFBQSxJQUFBQyxlQUFBLEdBQUVULE9BQU8sQ0FBQ2tELEtBQUssY0FBQXpDLGVBQUEsdUJBQWJBLGVBQUEsQ0FBZTJDLFVBQVUsY0FBQTVDLHFCQUFBLGNBQUFBLHFCQUFBLEdBQUksR0FBRztZQUM1QzZDLGFBQWEsR0FBQTNDLHFCQUFBLElBQUFDLGVBQUEsR0FBRVgsT0FBTyxDQUFDa0QsS0FBSyxjQUFBdkMsZUFBQSx1QkFBYkEsZUFBQSxDQUFlMEMsYUFBYSxjQUFBM0MscUJBQUEsY0FBQUEscUJBQUEsR0FBSSxDQUFDO1lBQ2hENEMsVUFBVSxHQUFBMUMscUJBQUEsSUFBQUMsZUFBQSxHQUFFYixPQUFPLENBQUNrRCxLQUFLLGNBQUFyQyxlQUFBLHVCQUFiQSxlQUFBLENBQWV5QyxVQUFVLGNBQUExQyxxQkFBQSxjQUFBQSxxQkFBQSxHQUFJLENBQ3ZDLFlBQVksRUFDWixjQUFjLEVBQ2QsV0FBVyxFQUNYLFVBQVUsRUFDVixhQUFhLEVBQ2IsV0FBVyxFQUNYLGdCQUFnQixFQUNoQixXQUFXLEVBQ1gsT0FBTyxDQUNSO1lBQ0QyQyxPQUFPLEdBQUF6QyxxQkFBQSxJQUFBQyxlQUFBLEdBQUVmLE9BQU8sQ0FBQ2tELEtBQUssY0FBQW5DLGVBQUEsdUJBQWJBLGVBQUEsQ0FBZXdDLE9BQU8sY0FBQXpDLHFCQUFBLGNBQUFBLHFCQUFBLEdBQUksQ0FDakMsS0FBSyxFQUNMLEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNULFFBQVE7VUFFWixDQUFDO1VBRUtlLGtCQUFrQixHQUFHLFNBQXJCQSxrQkFBa0JBLENBQ3RCMkIsUUFBZ0IsRUFDaEJDLFFBQXVDLEVBQzNCO1lBQUEsSUFBQUMsUUFBQTtZQUNaLElBQUksQ0FBQ0MseUJBQUEsQ0FBQUQsUUFBQSxHQUFBOUIsU0FBUyxDQUFDMkIsT0FBTyxFQUFBSyxJQUFBLENBQUFGLFFBQUEsRUFBVTNELE9BQU8sQ0FBQzhELE1BQU0sQ0FBQyxFQUFFLE9BQU8sS0FBSztZQUU3RCxJQUFJSixRQUFRLFlBQVlsRixRQUFRLEVBQUU7Y0FBQSxJQUFBdUYsU0FBQTtjQUNoQyxJQUFJSCx5QkFBQSxDQUFBRyxTQUFBLEdBQUFsQyxTQUFTLENBQUNxQixXQUFXLEVBQUFXLElBQUEsQ0FBQUUsU0FBQSxFQUFVTCxRQUFRLENBQUNNLE1BQU0sQ0FBQyxFQUFFO2dCQUNuRCxJQUFJUCxRQUFRLEtBQUs3QixVQUFVLEVBQUU7a0JBQzNCLE9BQU8sS0FBSztnQkFDZCxDQUFDLE1BQU07a0JBQ0wsT0FBTyxJQUFJO2dCQUNiO2NBQ0Y7Y0FDQSxPQUFPLEtBQUs7WUFDZCxDQUFDLE1BQU07Y0FBQSxJQUFBcUMscUJBQUE7Y0FDTCxJQUFJUixRQUFRLEtBQUs3QixVQUFVLEVBQUUsT0FBTyxLQUFLOztjQUV6QztjQUNBO2NBQ0EsSUFBSThCLFFBQVEsQ0FBQ1EsSUFBSSxJQUFJLFlBQVksRUFBRSxPQUFPLEtBQUs7Y0FFL0MsSUFBSW5GLEVBQUUsQ0FBQ29GLFVBQVUsQ0FBQzFDLElBQUksQ0FBQyxJQUFJbkQsUUFBUSxDQUFDOEYsV0FBVyxDQUFDM0MsSUFBSSxDQUFDLEVBQUU7Z0JBQ3JETCxNQUFNLENBQUNpRCxLQUFLLENBQUMsd0RBQXdELENBQUM7Z0JBQ3RFLE9BQU8sS0FBSztjQUNkO2NBRUEsSUFDRSxNQUFNLElBQUlYLFFBQVEsSUFDbEJBLFFBQVEsQ0FBQ1ksSUFBSSxJQUNiekMsU0FBUyxhQUFUQSxTQUFTLGdCQUFBb0MscUJBQUEsR0FBVHBDLFNBQVMsQ0FBRTBCLFVBQVUsY0FBQVUscUJBQUEsZUFBckJMLHlCQUFBLENBQUFLLHFCQUFBLEVBQUFKLElBQUEsQ0FBQUkscUJBQUEsRUFBZ0NQLFFBQVEsQ0FBQ1ksSUFBSSxDQUFDLEVBRTlDLE9BQU8sSUFBSTtjQUViLE9BQU8sS0FBSztZQUNkO1VBQ0YsQ0FBQztVQUVLQyxpQkFBZ0I7WUFBQSxJQUFBQyxJQUFBLEdBQUE1RSxpQkFBQSxjQUFBQyxtQkFBQSxDQUFBQyxJQUFBLENBQUcsU0FBQTJFLFFBQUE7Y0FBQSxJQUFBaEIsUUFBQTtnQkFBQWlCLFNBQUE7Z0JBQUFDLElBQUE7Z0JBQUFDLEtBQUE7Z0JBQUFDLEtBQUEsR0FBQWxGLFNBQUE7Y0FBQSxPQUFBRSxtQkFBQSxDQUFBMkMsSUFBQSxVQUFBc0MsU0FBQUMsU0FBQTtnQkFBQSxrQkFBQUEsU0FBQSxDQUFBcEMsSUFBQSxHQUFBb0MsU0FBQSxDQUFBbkMsSUFBQTtrQkFBQTtvQkFDdkJhLFFBQVEsR0FBQW9CLEtBQUEsQ0FBQWhDLE1BQUEsUUFBQWdDLEtBQUEsUUFBQS9CLFNBQUEsR0FBQStCLEtBQUEsTUFBR2hELFNBQVMsYUFBVEEsU0FBUyx1QkFBVEEsU0FBUyxDQUFFdUIsVUFBVTtvQkFFMUJzQixTQUFzQixHQUFBTSxhQUFBLENBQUFBLGFBQUEsQ0FBQUEsYUFBQSxLQUN2QnRELFFBQVEsR0FDUHhCLEtBQUssSUFBSSxxQkFBcUIsQ0FBQytFLElBQUksQ0FBQ2pGLE9BQU8sQ0FBQzhELE1BQU0sQ0FBQyxHQUNuRDtzQkFBRXJDLElBQUksRUFBRXZCO29CQUFNLENBQUMsR0FDZixDQUFDLENBQUM7c0JBQ05nRixRQUFRLEVBQUUsUUFBUTtzQkFDbEJDLE1BQU0sRUFBRXhELFVBQVUsQ0FBQ3dELE1BQU07c0JBQ3pCNUQsS0FBSyxFQUFMQTtvQkFBSztvQkFBQXdELFNBQUEsQ0FBQXBDLElBQUE7b0JBQUFvQyxTQUFBLENBQUFuQyxJQUFBO29CQUFBLE9BSWFyRSxLQUFLLENBQUNpRCxHQUFHLEVBQUVrRCxTQUFTLENBQUM7a0JBQUE7b0JBQWpDMUMsSUFBRyxHQUFBK0MsU0FBQSxDQUFBSyxJQUFBO29CQUFBLEtBQ0x0RCxrQkFBa0IsQ0FBQ0QsU0FBUyxDQUFDdUIsVUFBVSxFQUFFcEIsSUFBRyxDQUFDO3NCQUFBK0MsU0FBQSxDQUFBbkMsSUFBQTtzQkFBQTtvQkFBQTtvQkFDL0N4QixNQUFNLENBQUNpRCxLQUFLLHFCQUFBZ0IsTUFBQSxDQUFxQnpELFVBQVUsR0FBRyxDQUFDLFVBQU8sQ0FBQztvQkFDdkRSLE1BQU0sQ0FBQ2lELEtBQUssQ0FBQywwQkFBMEIsQ0FBQztvQkFBQ1UsU0FBQSxDQUFBbkMsSUFBQTtvQkFBQSxPQUVuQzBDLEtBQUssQ0FDVDFELFVBQVUsS0FBSyxDQUFDLEdBQ1pDLFNBQVMsQ0FBQ3dCLFVBQVUsR0FDcEJ4QixTQUFTLENBQUN3QixVQUFVLEdBQUFrQyxJQUFBLENBQUFDLEdBQUEsQ0FBRzNELFNBQVMsQ0FBQ3lCLGFBQWEsRUFBSTFCLFVBQVUsQ0FDbEUsQ0FBQztrQkFBQTtvQkFFRDtvQkFDQTtvQkFDQXhCLE9BQU8sQ0FBQ3FGLElBQUksQ0FBQyxPQUFPLEVBQUU3RCxVQUFVLENBQUM7b0JBQ2pDQSxVQUFVLEVBQUU7b0JBQUNtRCxTQUFBLENBQUFuQyxJQUFBO29CQUFBLE9BRUEyQixpQkFBZ0IsQ0FBQ2QsUUFBUSxDQUFDO2tCQUFBO29CQUFBLE9BQUFzQixTQUFBLENBQUFXLE1BQUEsV0FBQVgsU0FBQSxDQUFBSyxJQUFBO2tCQUFBO29CQUFBLE9BQUFMLFNBQUEsQ0FBQVcsTUFBQSxXQUdsQzFELElBQUc7a0JBQUE7b0JBQUErQyxTQUFBLENBQUFwQyxJQUFBO29CQUFBb0MsU0FBQSxDQUFBWSxFQUFBLEdBQUFaLFNBQUE7b0JBRVYzRCxNQUFNLENBQUNpRCxLQUFLLENBQUMsZ0JBQWdCLENBQUM7b0JBQ3hCTyxLQUFLLEdBQUFHLFNBQUEsQ0FBQVksRUFBQSxFQUVYO29CQUFBLE1BQ0lmLEtBQUssQ0FBQ1YsSUFBSSxLQUFLLFlBQVk7c0JBQUFhLFNBQUEsQ0FBQW5DLElBQUE7c0JBQUE7b0JBQUE7b0JBQUEsTUFDdkJnQyxLQUFLO2tCQUFBO29CQUFBLEtBR1Q5QyxrQkFBa0IsQ0FBQ0QsU0FBUyxDQUFDdUIsVUFBVSxFQUFFd0IsS0FBSyxDQUFDO3NCQUFBRyxTQUFBLENBQUFuQyxJQUFBO3NCQUFBO29CQUFBO29CQUNqRHhCLE1BQU0sQ0FBQ2lELEtBQUsscUJBQUFnQixNQUFBLENBQXFCekQsVUFBVSxHQUFHLENBQUMsVUFBTyxDQUFDO29CQUN2RFIsTUFBTSxDQUFDaUQsS0FBSyxXQUFBZ0IsTUFBQSxDQUFXTixTQUFBLENBQUFZLEVBQUEsQ0FBZUMsT0FBTyxDQUFFLENBQUM7b0JBQUNiLFNBQUEsQ0FBQW5DLElBQUE7b0JBQUEsT0FFM0MwQyxLQUFLLENBQ1QxRCxVQUFVLEtBQUssQ0FBQyxHQUNaQyxTQUFTLENBQUN3QixVQUFVLEdBQ3BCeEIsU0FBUyxDQUFDd0IsVUFBVSxHQUFBa0MsSUFBQSxDQUFBQyxHQUFBLENBQUczRCxTQUFTLENBQUN5QixhQUFhLEVBQUkxQixVQUFVLENBQ2xFLENBQUM7a0JBQUE7b0JBRUQ7b0JBQ0E7b0JBQ0F4QixPQUFPLENBQUNxRixJQUFJLENBQUMsT0FBTyxFQUFFN0QsVUFBVSxDQUFDO29CQUNqQ0EsVUFBVSxFQUFFO29CQUFDLE9BQUFtRCxTQUFBLENBQUFXLE1BQUEsV0FFTm5CLGlCQUFnQixDQUFDZCxRQUFRLENBQUM7a0JBQUE7b0JBR25DckMsTUFBTSxDQUFDaUQsS0FBSyxDQUFDLG1CQUFtQixDQUFDO29CQUFDLE1BRTlCWixRQUFRLEtBQUs3QixVQUFVO3NCQUFBbUQsU0FBQSxDQUFBbkMsSUFBQTtzQkFBQTtvQkFBQTtvQkFBQSxNQUFBbUMsU0FBQSxDQUFBWSxFQUFBO2tCQUFBO29CQUFBLE1BQUFaLFNBQUEsQ0FBQVksRUFBQTtrQkFBQTtrQkFBQTtvQkFBQSxPQUFBWixTQUFBLENBQUFjLElBQUE7Z0JBQUE7Y0FBQSxHQUFBcEIsT0FBQTtZQUFBLENBTTlCO1lBQUEsZ0JBckVLRixnQkFBZ0JBLENBQUE7Y0FBQSxPQUFBQyxJQUFBLENBQUE5RSxLQUFBLE9BQUFDLFNBQUE7WUFBQTtVQUFBO1VBeUV0QjtVQUNBO1VBQ0E7VUFDTXNDLFlBQVksSUFBQWhCLGdCQUFBLEdBQUdoQixPQUFPLENBQUM2RixPQUFPLGNBQUE3RSxnQkFBQSxjQUFBQSxnQkFBQSxHQUFJLEtBQU07VUFBQXlCLFNBQUEsQ0FBQUMsSUFBQTtVQUFBRCxTQUFBLENBQUFFLElBQUE7VUFBQSxPQUdoQ2pFLGtCQUFrQixDQUFDNEYsaUJBQWdCLEVBQUV0QyxZQUFZLEVBQUU7WUFBQSxPQUM3RE4sVUFBVSxDQUFDb0UsS0FBSyxDQUFDLENBQUM7VUFBQSxDQUNwQixDQUFDO1FBQUE7VUFGRC9ELEdBQUcsR0FBQVUsU0FBQSxDQUFBMEMsSUFBQTtVQUFBMUMsU0FBQSxDQUFBRSxJQUFBO1VBQUE7UUFBQTtVQUFBRixTQUFBLENBQUFDLElBQUE7VUFBQUQsU0FBQSxDQUFBaUQsRUFBQSxHQUFBakQsU0FBQTtVQUlIdEMsT0FBTyxDQUFDcUYsSUFBSSxDQUFDLE9BQU8sRUFBQS9DLFNBQUEsQ0FBQWlELEVBQUssQ0FBQztVQUFDLE9BQUFqRCxTQUFBLENBQUFnRCxNQUFBO1FBQUE7VUFHdkJ4RCxPQUErQixHQUFHLENBQUMsQ0FBQztVQUFBQyxTQUFBLEdBQUE2RCwwQkFBQSxDQUNqQkMscUJBQUEsQ0FBQS9FLFNBQUEsR0FBQWMsR0FBRyxDQUFDRSxPQUFPLEVBQUEyQixJQUFBLENBQUEzQyxTQUFNLENBQUM7VUFBQTtZQUEzQyxLQUFBaUIsU0FBQSxDQUFBK0QsQ0FBQSxNQUFBOUQsS0FBQSxHQUFBRCxTQUFBLENBQUFnRSxDQUFBLElBQUFDLElBQUEsR0FBNkM7Y0FBbEMvRCxVQUFVLEdBQUFELEtBQUEsQ0FBQWlFLEtBQUE7Y0FDbkJuRSxPQUFPLENBQUNHLFVBQVUsQ0FBQ2lFLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBR3RFLEdBQUcsQ0FBQ0UsT0FBTyxDQUFDcUUsR0FBRyxDQUFDbEUsVUFBVSxDQUFDO1lBQ2pFO1VBQUMsU0FBQW1FLEdBQUE7WUFBQXJFLFNBQUEsQ0FBQXNFLENBQUEsQ0FBQUQsR0FBQTtVQUFBO1lBQUFyRSxTQUFBLENBQUF1RSxDQUFBO1VBQUE7VUFDS3BFLFFBQVEsR0FBRztZQUNmcUUsVUFBVSxFQUFFM0UsR0FBRyxDQUFDZ0MsTUFBTTtZQUN0QjlCLE9BQU8sRUFBUEE7VUFDRixDQUFDO1VBQUEsTUFDR1osY0FBYyxJQUFJMUMsVUFBVSxDQUFDMEQsUUFBUSxDQUFDcUUsVUFBVSxDQUFDO1lBQUFqRSxTQUFBLENBQUFFLElBQUE7WUFBQTtVQUFBO1VBQ25ELElBQUk7WUFDRi9ELHNCQUFzQixDQUNwQm1CLE9BQU8sRUFDUHNDLFFBQVEsRUFDUmhCLGNBQWMsRUFDZEgsT0FBTyxFQUNQLFVBQUN5RixHQUFHO2NBQUEsT0FDRnpILGlCQUFpQixDQUNmeUgsR0FBRyxFQUNIM0csT0FBTyxFQUNQNkMsU0FBUyxFQUNUM0MsTUFBTSxFQUNOQyxPQUFPLEVBQ1BlLE9BQU8sR0FBRyxDQUNaLENBQUM7WUFBQSxDQUNMLENBQUM7VUFDSCxDQUFDLENBQUMsT0FBT3FGLEdBQUcsRUFBRTtZQUNacEcsT0FBTyxDQUFDcUYsSUFBSSxDQUFDLE9BQU8sRUFBRWUsR0FBRyxDQUFDO1VBQzVCO1VBQUMsT0FBQTlELFNBQUEsQ0FBQWdELE1BQUE7UUFBQTtVQUdIdEYsT0FBTyxDQUFDcUYsSUFBSSxDQUFDLFVBQVUsRUFBRW5ELFFBQVEsQ0FBQztVQUNsQ04sR0FBRyxDQUFDUCxJQUFJLENBQUNvRixJQUFJLENBQUMxRyxNQUFNLENBQUM7UUFBQztRQUFBO1VBQUEsT0FBQXVDLFNBQUEsQ0FBQW1ELElBQUE7TUFBQTtJQUFBLEdBQUE5RixRQUFBO0VBQUEsQ0FDdkI7RUFBQSxPQUFBTixrQkFBQSxDQUFBQyxLQUFBLE9BQUFDLFNBQUE7QUFBQTtBQUtELGVBQWUsU0FBU0ssT0FBT0EsQ0FDN0I0RyxHQUFnQixFQUVSO0VBQUEsSUFEUkUsUUFBNEIsR0FBQW5ILFNBQUEsQ0FBQWtELE1BQUEsUUFBQWxELFNBQUEsUUFBQW1ELFNBQUEsR0FBQW5ELFNBQUEsTUFBRyxDQUFDLENBQUM7RUFFakMsSUFBTU0sT0FBTyxHQUFBK0UsYUFBQSxDQUFBQSxhQUFBLEtBQVFoRyxRQUFRLEdBQUs4SCxRQUFRLENBQUU7RUFDNUMsSUFBQUMscUJBQUEsR0FBa0NySSwrQkFBK0IsQ0FDL0RrSSxHQUFHLEVBQ0gzRyxPQUNGLENBQUM7SUFIT0MsS0FBSyxHQUFBNkcscUJBQUEsQ0FBTDdHLEtBQUs7SUFBRUMsTUFBTSxHQUFBNEcscUJBQUEsQ0FBTjVHLE1BQU07SUFBRTZHLE1BQU0sR0FBQUQscUJBQUEsQ0FBTkMsTUFBTTtFQUk3QjdILGlCQUFpQixDQUFDeUgsR0FBRyxFQUFFM0csT0FBTyxFQUFFQyxLQUFLLEVBQUVDLE1BQU0sRUFBRTZHLE1BQU0sQ0FBQztFQUN0RCxPQUFPQSxNQUFNO0FBQ2Y7QUFFQSxJQUFNMUIsS0FBSyxHQUFHLFNBQVJBLEtBQUtBLENBQUkyQixFQUFVO0VBQUEsT0FBSyxJQUFBQyxRQUFBLENBQVksVUFBQ0MsQ0FBQztJQUFBLE9BQUtDLFdBQUEsQ0FBV0QsQ0FBQyxFQUFFRixFQUFFLENBQUM7RUFBQSxFQUFDO0FBQUEiLCJpZ25vcmVMaXN0IjpbXX0=