UNPKG

jsforce

Version:

Salesforce API Library for JavaScript

505 lines (489 loc) 52.4 kB
import _Reflect$construct from "@babel/runtime-corejs3/core-js-stable/reflect/construct"; import _wrapNativeSuper from "@babel/runtime-corejs3/helpers/wrapNativeSuper"; import _typeof from "@babel/runtime-corejs3/helpers/typeof"; import _classCallCheck from "@babel/runtime-corejs3/helpers/classCallCheck"; import _createClass from "@babel/runtime-corejs3/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime-corejs3/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime-corejs3/helpers/getPrototypeOf"; import _inherits from "@babel/runtime-corejs3/helpers/inherits"; import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty"; import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator"; import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator"; import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat"; import _Date$now from "@babel/runtime-corejs3/core-js-stable/date/now"; import _Object$keys2 from "@babel/runtime-corejs3/core-js-stable/object/keys"; import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes"; import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array"; function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } import "core-js/modules/es.error.cause.js"; import "core-js/modules/es.array.join.js"; import "core-js/modules/es.array.push.js"; import "core-js/modules/es.function.name.js"; import "core-js/modules/es.object.keys.js"; import "core-js/modules/es.regexp.exec.js"; import "core-js/modules/es.regexp.test.js"; /** * */ import { EventEmitter } from 'events'; import xml2js from 'xml2js'; import { getLogger } from './util/logger'; import { StreamPromise } from './util/promise'; import { parseCSV } from './csv'; import { createLazyStream } from './util/stream'; import { getBodySize } from './util/get-body-size'; /** @private */ function parseJSON(str) { return JSON.parse(str); } /** @private */ function parseXML(_x) { return _parseXML.apply(this, arguments); } /** @private */ function _parseXML() { _parseXML = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(str) { return _regeneratorRuntime.wrap(function _callee5$(_context11) { while (1) switch (_context11.prev = _context11.next) { case 0: return _context11.abrupt("return", xml2js.parseStringPromise(str, { explicitArray: false })); case 1: case "end": return _context11.stop(); } }, _callee5); })); return _parseXML.apply(this, arguments); } function parseText(str) { return str; } /** * HTTP based API class with authorization hook */ export var HttpApi = /*#__PURE__*/function (_EventEmitter) { function HttpApi(conn, options) { var _this; _classCallCheck(this, HttpApi); _this = _callSuper(this, HttpApi); _this._conn = conn; _this._logger = conn._logLevel ? HttpApi._logger.createInstance(conn._logLevel) : HttpApi._logger; _this._responseType = options.responseType; _this._transport = options.transport || conn._transport; _this._noContentResponse = options.noContentResponse; _this._options = options; return _this; } /** * Callout to API endpoint using http */ _inherits(HttpApi, _EventEmitter); return _createClass(HttpApi, [{ key: "request", value: function request(_request) { var _this2 = this; return StreamPromise.create(function () { var _createLazyStream = createLazyStream(), stream = _createLazyStream.stream, setStream = _createLazyStream.setStream; var promise = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var _context, _context2; var refreshDelegate, bodyPromise, _body2, requestTime, requestPromise, response, responseTime, err, body; return _regeneratorRuntime.wrap(function _callee$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: refreshDelegate = _this2.getRefreshDelegate(); /* TODO decide remove or not this section */ /* // remember previous instance url in case it changes after a refresh const lastInstanceUrl = conn.instanceUrl; // check to see if the token refresh has changed the instance url if(lastInstanceUrl !== conn.instanceUrl){ // if the instance url has changed // then replace the current request urls instance url fragment // with the updated instance url request.url = request.url.replace(lastInstanceUrl,conn.instanceUrl); } */ if (!(refreshDelegate && refreshDelegate.isRefreshing())) { _context3.next = 10; break; } _context3.next = 4; return refreshDelegate.waitRefresh(); case 4: bodyPromise = _this2.request(_request); setStream(bodyPromise.stream()); _context3.next = 8; return bodyPromise; case 8: _body2 = _context3.sent; return _context3.abrupt("return", _body2); case 10: // hook before sending _this2.beforeSend(_request); _this2.emit('request', _request); _this2._logger.debug(_concatInstanceProperty(_context = "<request> method=".concat(_request.method, ", url=")).call(_context, _request.url)); requestTime = _Date$now(); requestPromise = _this2._transport.httpRequest(_request, _this2._options); setStream(requestPromise.stream()); _context3.prev = 16; _context3.next = 19; return requestPromise; case 19: response = _context3.sent; _context3.next = 26; break; case 22: _context3.prev = 22; _context3.t0 = _context3["catch"](16); _this2._logger.error(_context3.t0); throw _context3.t0; case 26: _context3.prev = 26; responseTime = _Date$now(); _this2._logger.debug("elapsed time: ".concat(responseTime - requestTime, " msec")); return _context3.finish(26); case 30: if (response) { _context3.next = 32; break; } return _context3.abrupt("return"); case 32: _this2._logger.debug(_concatInstanceProperty(_context2 = "<response> status=".concat(String(response.statusCode), ", url=")).call(_context2, _request.url)); _this2.emit('response', response); // Refresh token if session has been expired and requires authentication // when session refresh delegate is available if (!(_this2.isSessionExpired(response) && refreshDelegate)) { _context3.next = 39; break; } _context3.next = 37; return refreshDelegate.refresh(requestTime); case 37: /* remove the `content-length` header after token refresh * * SOAP requests include the access token their the body, * if the first req had an invalid token and jsforce successfully * refreshed it we need to remove the `content-length` header * so that it get's re-calculated again with the new body. * * REST request aren't affected by this because the access token * is sent via HTTP headers * * `_message` is only present in SOAP requests */ if ('_message' in _request && _request.headers && 'content-length' in _request.headers) { delete _request.headers['content-length']; } return _context3.abrupt("return", _this2.request(_request)); case 39: if (!_this2.isErrorResponse(response)) { _context3.next = 44; break; } _context3.next = 42; return _this2.getError(response); case 42: err = _context3.sent; throw err; case 44: _context3.next = 46; return _this2.getResponseBody(response); case 46: body = _context3.sent; return _context3.abrupt("return", body); case 48: case "end": return _context3.stop(); } }, _callee, null, [[16, 22, 26, 30]]); }))(); return { stream: stream, promise: promise }; }); } /** * @protected */ }, { key: "getRefreshDelegate", value: function getRefreshDelegate() { return this._conn._refreshDelegate; } /** * @protected */ }, { key: "beforeSend", value: function beforeSend(request) { var _context5; /* eslint-disable no-param-reassign */ var headers = request.headers || {}; if (this._conn.accessToken) { headers.Authorization = "Bearer ".concat(this._conn.accessToken); } if (this._conn._callOptions) { var callOptions = []; for (var _i = 0, _Object$keys = _Object$keys2(this._conn._callOptions); _i < _Object$keys.length; _i++) { var _context4; var name = _Object$keys[_i]; callOptions.push(_concatInstanceProperty(_context4 = "".concat(name, "=")).call(_context4, this._conn._callOptions[name])); } headers['Sforce-Call-Options'] = callOptions.join(', '); } var bodySize = getBodySize(request.body, headers); var cannotHaveBody = _includesInstanceProperty(_context5 = ['GET', 'HEAD', 'OPTIONS']).call(_context5, request.method); if (!cannotHaveBody && !!request.body && !('transfer-encoding' in headers) && !('content-length' in headers) && !!bodySize) { this._logger.debug("missing 'content-length' header, setting it to: ".concat(bodySize)); headers['content-length'] = String(bodySize); } request.headers = headers; } /** * Detect response content mime-type * @protected */ }, { key: "getResponseContentType", value: function getResponseContentType(response) { return this._responseType || response.headers && response.headers['content-type']; } /** * @private */ // eslint-disable-next-line @typescript-eslint/require-await }, { key: "parseResponseBody", value: (function () { var _parseResponseBody = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(response) { var contentType, parseBody, _context6; return _regeneratorRuntime.wrap(function _callee2$(_context7) { while (1) switch (_context7.prev = _context7.next) { case 0: contentType = this.getResponseContentType(response) || ''; parseBody = /^(text|application)\/xml(;|$)/.test(contentType) ? parseXML : /^application\/json(;|$)/.test(contentType) ? parseJSON : /^text\/csv(;|$)/.test(contentType) ? parseCSV : parseText; _context7.prev = 2; return _context7.abrupt("return", parseBody(response.body)); case 6: _context7.prev = 6; _context7.t0 = _context7["catch"](2); // TODO(next major): we could throw a new "invalid response body" error instead. this._logger.debug(_concatInstanceProperty(_context6 = "Failed to parse body of content-type: ".concat(contentType, ". Error: ")).call(_context6, _context7.t0.message)); return _context7.abrupt("return", response.body); case 10: case "end": return _context7.stop(); } }, _callee2, this, [[2, 6]]); })); function parseResponseBody(_x2) { return _parseResponseBody.apply(this, arguments); } return parseResponseBody; }() /** * Get response body * @protected */ ) }, { key: "getResponseBody", value: (function () { var _getResponseBody = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(response) { var body, err; return _regeneratorRuntime.wrap(function _callee3$(_context8) { while (1) switch (_context8.prev = _context8.next) { case 0: if (!(response.statusCode === 204)) { _context8.next = 2; break; } return _context8.abrupt("return", this._noContentResponse); case 2: _context8.next = 4; return this.parseResponseBody(response); case 4: body = _context8.sent; if (!this.hasErrorInResponseBody(body)) { _context8.next = 10; break; } _context8.next = 8; return this.getError(response, body); case 8: err = _context8.sent; throw err; case 10: if (!(response.statusCode === 300)) { _context8.next = 12; break; } throw new HttpApiError('Multiple records found', 'MULTIPLE_CHOICES', body); case 12: return _context8.abrupt("return", body); case 13: case "end": return _context8.stop(); } }, _callee3, this); })); function getResponseBody(_x3) { return _getResponseBody.apply(this, arguments); } return getResponseBody; }() /** * Detect session expiry * @protected */ ) }, { key: "isSessionExpired", value: function isSessionExpired(response) { var _context9; // TODO: // The connected app msg only applies to Agent API requests, we should move this to a separate SFAP/Agent API class later. return response.statusCode === 401 && !_includesInstanceProperty(_context9 = response.body).call(_context9, 'Connected app is not attached to Agent'); } /** * Detect error response * @protected */ }, { key: "isErrorResponse", value: function isErrorResponse(response) { return response.statusCode >= 400; } /** * Detect error in response body * @protected */ }, { key: "hasErrorInResponseBody", value: function hasErrorInResponseBody(_body) { return false; } /** * Parsing error message in response * @protected */ }, { key: "parseError", value: function parseError(body) { var errors = body; // XML response if (errors.Errors) { return errors.Errors.Error; } return errors; } /** * Get error message in response * @protected */ }, { key: "getError", value: (function () { var _getError = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(response, body) { var error; return _regeneratorRuntime.wrap(function _callee4$(_context10) { while (1) switch (_context10.prev = _context10.next) { case 0: _context10.prev = 0; _context10.t0 = this; _context10.t1 = body; if (_context10.t1) { _context10.next = 7; break; } _context10.next = 6; return this.parseResponseBody(response); case 6: _context10.t1 = _context10.sent; case 7: _context10.t2 = _context10.t1; error = _context10.t0.parseError.call(_context10.t0, _context10.t2); _context10.next = 13; break; case 11: _context10.prev = 11; _context10.t3 = _context10["catch"](0); case 13: if (!_Array$isArray(error)) { _context10.next = 19; break; } if (!(error.length === 1)) { _context10.next = 18; break; } error = error[0]; _context10.next = 19; break; case 18: return _context10.abrupt("return", new HttpApiError("Multiple errors returned.\n Check `error.data` for the error details", 'MULTIPLE_API_ERRORS', error)); case 19: error = _typeof(error) === 'object' && error !== null && typeof error.message === 'string' ? error : { errorCode: "ERROR_HTTP_".concat(response.statusCode), message: response.body }; if (!(response.headers['content-type'] === 'text/html')) { _context10.next = 23; break; } this._logger.debug("html response.body: ".concat(response.body)); return _context10.abrupt("return", new HttpApiError("HTTP response contains html content.\nCheck that the org exists and can be reached.\nSee `error.data` for the full html response.", error.errorCode, error.message)); case 23: return _context10.abrupt("return", error instanceof HttpApiError ? error : new HttpApiError(error.message, error.errorCode, error)); case 24: case "end": return _context10.stop(); } }, _callee4, this, [[0, 11]]); })); function getError(_x4, _x5) { return _getError.apply(this, arguments); } return getError; }()) }]); }(EventEmitter); /** * */ _defineProperty(HttpApi, "_logger", getLogger('http-api')); var HttpApiError = /*#__PURE__*/function (_Error) { /** * This contains error-specific details, usually returned from the API. */ function HttpApiError(message, errorCode, data) { var _this3; _classCallCheck(this, HttpApiError); _this3 = _callSuper(this, HttpApiError, [message]); _this3.name = errorCode || _this3.name; _this3.errorCode = _this3.name; _this3.data = data; return _this3; } /** * This will be removed in the next major (v4) * * @deprecated use `error.data` instead */ _inherits(HttpApiError, _Error); return _createClass(HttpApiError, [{ key: "content", get: function get() { return this.data; } }]); }(/*#__PURE__*/_wrapNativeSuper(Error)); export default HttpApi; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFdmVudEVtaXR0ZXIiLCJ4bWwyanMiLCJnZXRMb2dnZXIiLCJTdHJlYW1Qcm9taXNlIiwicGFyc2VDU1YiLCJjcmVhdGVMYXp5U3RyZWFtIiwiZ2V0Qm9keVNpemUiLCJwYXJzZUpTT04iLCJzdHIiLCJKU09OIiwicGFyc2UiLCJwYXJzZVhNTCIsIl94IiwiX3BhcnNlWE1MIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJfYXN5bmNUb0dlbmVyYXRvciIsIl9yZWdlbmVyYXRvclJ1bnRpbWUiLCJtYXJrIiwiX2NhbGxlZTUiLCJ3cmFwIiwiX2NhbGxlZTUkIiwiX2NvbnRleHQxMSIsInByZXYiLCJuZXh0IiwiYWJydXB0IiwicGFyc2VTdHJpbmdQcm9taXNlIiwiZXhwbGljaXRBcnJheSIsInN0b3AiLCJwYXJzZVRleHQiLCJIdHRwQXBpIiwiX0V2ZW50RW1pdHRlciIsImNvbm4iLCJvcHRpb25zIiwiX3RoaXMiLCJfY2xhc3NDYWxsQ2hlY2siLCJfY2FsbFN1cGVyIiwiX2Nvbm4iLCJfbG9nZ2VyIiwiX2xvZ0xldmVsIiwiY3JlYXRlSW5zdGFuY2UiLCJfcmVzcG9uc2VUeXBlIiwicmVzcG9uc2VUeXBlIiwiX3RyYW5zcG9ydCIsInRyYW5zcG9ydCIsIl9ub0NvbnRlbnRSZXNwb25zZSIsIm5vQ29udGVudFJlc3BvbnNlIiwiX29wdGlvbnMiLCJfaW5oZXJpdHMiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsInJlcXVlc3QiLCJfdGhpczIiLCJjcmVhdGUiLCJfY3JlYXRlTGF6eVN0cmVhbSIsInN0cmVhbSIsInNldFN0cmVhbSIsInByb21pc2UiLCJfY2FsbGVlIiwiX2NvbnRleHQiLCJfY29udGV4dDIiLCJyZWZyZXNoRGVsZWdhdGUiLCJib2R5UHJvbWlzZSIsIl9ib2R5MiIsInJlcXVlc3RUaW1lIiwicmVxdWVzdFByb21pc2UiLCJyZXNwb25zZSIsInJlc3BvbnNlVGltZSIsImVyciIsImJvZHkiLCJfY2FsbGVlJCIsIl9jb250ZXh0MyIsImdldFJlZnJlc2hEZWxlZ2F0ZSIsImlzUmVmcmVzaGluZyIsIndhaXRSZWZyZXNoIiwic2VudCIsImJlZm9yZVNlbmQiLCJlbWl0IiwiZGVidWciLCJfY29uY2F0SW5zdGFuY2VQcm9wZXJ0eSIsImNvbmNhdCIsIm1ldGhvZCIsImNhbGwiLCJ1cmwiLCJfRGF0ZSRub3ciLCJodHRwUmVxdWVzdCIsInQwIiwiZXJyb3IiLCJmaW5pc2giLCJTdHJpbmciLCJzdGF0dXNDb2RlIiwiaXNTZXNzaW9uRXhwaXJlZCIsInJlZnJlc2giLCJoZWFkZXJzIiwiaXNFcnJvclJlc3BvbnNlIiwiZ2V0RXJyb3IiLCJnZXRSZXNwb25zZUJvZHkiLCJfcmVmcmVzaERlbGVnYXRlIiwiX2NvbnRleHQ1IiwiYWNjZXNzVG9rZW4iLCJBdXRob3JpemF0aW9uIiwiX2NhbGxPcHRpb25zIiwiY2FsbE9wdGlvbnMiLCJfaSIsIl9PYmplY3Qka2V5cyIsIl9PYmplY3Qka2V5czIiLCJsZW5ndGgiLCJfY29udGV4dDQiLCJuYW1lIiwicHVzaCIsImpvaW4iLCJib2R5U2l6ZSIsImNhbm5vdEhhdmVCb2R5IiwiX2luY2x1ZGVzSW5zdGFuY2VQcm9wZXJ0eSIsImdldFJlc3BvbnNlQ29udGVudFR5cGUiLCJfcGFyc2VSZXNwb25zZUJvZHkiLCJfY2FsbGVlMiIsImNvbnRlbnRUeXBlIiwicGFyc2VCb2R5IiwiX2NvbnRleHQ2IiwiX2NhbGxlZTIkIiwiX2NvbnRleHQ3IiwidGVzdCIsIm1lc3NhZ2UiLCJwYXJzZVJlc3BvbnNlQm9keSIsIl94MiIsIl9nZXRSZXNwb25zZUJvZHkiLCJfY2FsbGVlMyIsIl9jYWxsZWUzJCIsIl9jb250ZXh0OCIsImhhc0Vycm9ySW5SZXNwb25zZUJvZHkiLCJIdHRwQXBpRXJyb3IiLCJfeDMiLCJfY29udGV4dDkiLCJfYm9keSIsInBhcnNlRXJyb3IiLCJlcnJvcnMiLCJFcnJvcnMiLCJFcnJvciIsIl9nZXRFcnJvciIsIl9jYWxsZWU0IiwiX2NhbGxlZTQkIiwiX2NvbnRleHQxMCIsInQxIiwidDIiLCJ0MyIsIl9BcnJheSRpc0FycmF5IiwiX3R5cGVvZiIsImVycm9yQ29kZSIsIl94NCIsIl94NSIsIl9kZWZpbmVQcm9wZXJ0eSIsIl9FcnJvciIsImRhdGEiLCJfdGhpczMiLCJnZXQiLCJfd3JhcE5hdGl2ZVN1cGVyIl0sInNvdXJjZXMiOlsiLi4vc3JjL2h0dHAtYXBpLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICpcbiAqL1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCB4bWwyanMgZnJvbSAneG1sMmpzJztcbmltcG9ydCB7IExvZ2dlciwgZ2V0TG9nZ2VyIH0gZnJvbSAnLi91dGlsL2xvZ2dlcic7XG5pbXBvcnQgeyBTdHJlYW1Qcm9taXNlIH0gZnJvbSAnLi91dGlsL3Byb21pc2UnO1xuaW1wb3J0IENvbm5lY3Rpb24gZnJvbSAnLi9jb25uZWN0aW9uJztcbmltcG9ydCBUcmFuc3BvcnQgZnJvbSAnLi90cmFuc3BvcnQnO1xuaW1wb3J0IHsgcGFyc2VDU1YgfSBmcm9tICcuL2Nzdic7XG5pbXBvcnQge1xuICBIdHRwUmVxdWVzdCxcbiAgSHR0cFJlcXVlc3RPcHRpb25zLFxuICBIdHRwUmVzcG9uc2UsXG4gIE9wdGlvbmFsLFxuICBTY2hlbWEsXG59IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgY3JlYXRlTGF6eVN0cmVhbSB9IGZyb20gJy4vdXRpbC9zdHJlYW0nO1xuaW1wb3J0IHsgZ2V0Qm9keVNpemUgfSBmcm9tICcuL3V0aWwvZ2V0LWJvZHktc2l6ZSc7XG5cbi8qKiBAcHJpdmF0ZSAqL1xuZnVuY3Rpb24gcGFyc2VKU09OKHN0cjogc3RyaW5nKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKHN0cik7XG59XG5cbi8qKiBAcHJpdmF0ZSAqL1xuYXN5bmMgZnVuY3Rpb24gcGFyc2VYTUwoc3RyOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHhtbDJqcy5wYXJzZVN0cmluZ1Byb21pc2Uoc3RyLCB7IGV4cGxpY2l0QXJyYXk6IGZhbHNlIH0pO1xufVxuXG4vKiogQHByaXZhdGUgKi9cbmZ1bmN0aW9uIHBhcnNlVGV4dChzdHI6IHN0cmluZykge1xuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIEhUVFAgYmFzZWQgQVBJIGNsYXNzIHdpdGggYXV0aG9yaXphdGlvbiBob29rXG4gKi9cbmV4cG9ydCBjbGFzcyBIdHRwQXBpPFMgZXh0ZW5kcyBTY2hlbWE+IGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgc3RhdGljIF9sb2dnZXIgPSBnZXRMb2dnZXIoJ2h0dHAtYXBpJyk7XG5cbiAgX2Nvbm46IENvbm5lY3Rpb248Uz47XG4gIF9sb2dnZXI6IExvZ2dlcjtcbiAgX3RyYW5zcG9ydDogVHJhbnNwb3J0O1xuICBfcmVzcG9uc2VUeXBlOiBzdHJpbmcgfCB2b2lkO1xuICBfbm9Db250ZW50UmVzcG9uc2U6IHN0cmluZyB8IHZvaWQ7XG4gIF9vcHRpb25zOiBIdHRwUmVxdWVzdE9wdGlvbnM7XG5cbiAgY29uc3RydWN0b3IoY29ubjogQ29ubmVjdGlvbjxTPiwgb3B0aW9uczogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9jb25uID0gY29ubjtcbiAgICB0aGlzLl9sb2dnZXIgPSBjb25uLl9sb2dMZXZlbFxuICAgICAgPyBIdHRwQXBpLl9sb2dnZXIuY3JlYXRlSW5zdGFuY2UoY29ubi5fbG9nTGV2ZWwpXG4gICAgICA6IEh0dHBBcGkuX2xvZ2dlcjtcbiAgICB0aGlzLl9yZXNwb25zZVR5cGUgPSBvcHRpb25zLnJlc3BvbnNlVHlwZTtcbiAgICB0aGlzLl90cmFuc3BvcnQgPSBvcHRpb25zLnRyYW5zcG9ydCB8fCBjb25uLl90cmFuc3BvcnQ7XG4gICAgdGhpcy5fbm9Db250ZW50UmVzcG9uc2UgPSBvcHRpb25zLm5vQ29udGVudFJlc3BvbnNlO1xuICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGxvdXQgdG8gQVBJIGVuZHBvaW50IHVzaW5nIGh0dHBcbiAgICovXG4gIHJlcXVlc3Q8UiA9IHVua25vd24+KHJlcXVlc3Q6IEh0dHBSZXF1ZXN0KTogU3RyZWFtUHJvbWlzZTxSPiB7XG4gICAgcmV0dXJuIFN0cmVhbVByb21pc2UuY3JlYXRlPFI+KCgpID0+IHtcbiAgICAgIGNvbnN0IHsgc3RyZWFtLCBzZXRTdHJlYW0gfSA9IGNyZWF0ZUxhenlTdHJlYW0oKTtcbiAgICAgIGNvbnN0IHByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZWZyZXNoRGVsZWdhdGUgPSB0aGlzLmdldFJlZnJlc2hEZWxlZ2F0ZSgpO1xuICAgICAgICAvKiBUT0RPIGRlY2lkZSByZW1vdmUgb3Igbm90IHRoaXMgc2VjdGlvbiAqL1xuICAgICAgICAvKlxuICAgICAgICAvLyByZW1lbWJlciBwcmV2aW91cyBpbnN0YW5jZSB1cmwgaW4gY2FzZSBpdCBjaGFuZ2VzIGFmdGVyIGEgcmVmcmVzaFxuICAgICAgICBjb25zdCBsYXN0SW5zdGFuY2VVcmwgPSBjb25uLmluc3RhbmNlVXJsO1xuXG4gICAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiB0aGUgdG9rZW4gcmVmcmVzaCBoYXMgY2hhbmdlZCB0aGUgaW5zdGFuY2UgdXJsXG4gICAgICAgIGlmKGxhc3RJbnN0YW5jZVVybCAhPT0gY29ubi5pbnN0YW5jZVVybCl7XG4gICAgICAgICAgLy8gaWYgdGhlIGluc3RhbmNlIHVybCBoYXMgY2hhbmdlZFxuICAgICAgICAgIC8vIHRoZW4gcmVwbGFjZSB0aGUgY3VycmVudCByZXF1ZXN0IHVybHMgaW5zdGFuY2UgdXJsIGZyYWdtZW50XG4gICAgICAgICAgLy8gd2l0aCB0aGUgdXBkYXRlZCBpbnN0YW5jZSB1cmxcbiAgICAgICAgICByZXF1ZXN0LnVybCA9IHJlcXVlc3QudXJsLnJlcGxhY2UobGFzdEluc3RhbmNlVXJsLGNvbm4uaW5zdGFuY2VVcmwpO1xuICAgICAgICB9XG4gICAgICAgICovXG4gICAgICAgIGlmIChyZWZyZXNoRGVsZWdhdGUgJiYgcmVmcmVzaERlbGVnYXRlLmlzUmVmcmVzaGluZygpKSB7XG4gICAgICAgICAgYXdhaXQgcmVmcmVzaERlbGVnYXRlLndhaXRSZWZyZXNoKCk7XG4gICAgICAgICAgY29uc3QgYm9keVByb21pc2UgPSB0aGlzLnJlcXVlc3QocmVxdWVzdCk7XG4gICAgICAgICAgc2V0U3RyZWFtKGJvZHlQcm9taXNlLnN0cmVhbSgpKTtcbiAgICAgICAgICBjb25zdCBib2R5ID0gYXdhaXQgYm9keVByb21pc2U7XG4gICAgICAgICAgcmV0dXJuIGJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBob29rIGJlZm9yZSBzZW5kaW5nXG4gICAgICAgIHRoaXMuYmVmb3JlU2VuZChyZXF1ZXN0KTtcblxuICAgICAgICB0aGlzLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KTtcbiAgICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKFxuICAgICAgICAgIGA8cmVxdWVzdD4gbWV0aG9kPSR7cmVxdWVzdC5tZXRob2R9LCB1cmw9JHtyZXF1ZXN0LnVybH1gLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCByZXF1ZXN0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RQcm9taXNlID0gdGhpcy5fdHJhbnNwb3J0Lmh0dHBSZXF1ZXN0KFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgdGhpcy5fb3B0aW9ucyxcbiAgICAgICAgKTtcblxuICAgICAgICBzZXRTdHJlYW0ocmVxdWVzdFByb21pc2Uuc3RyZWFtKCkpO1xuXG4gICAgICAgIGxldCByZXNwb25zZTogSHR0cFJlc3BvbnNlIHwgdm9pZDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RQcm9taXNlO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2VUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICBgZWxhcHNlZCB0aW1lOiAke3Jlc3BvbnNlVGltZSAtIHJlcXVlc3RUaW1lfSBtc2VjYCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKFxuICAgICAgICAgIGA8cmVzcG9uc2U+IHN0YXR1cz0ke1N0cmluZyhyZXNwb25zZS5zdGF0dXNDb2RlKX0sIHVybD0ke1xuICAgICAgICAgICAgcmVxdWVzdC51cmxcbiAgICAgICAgICB9YCxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5lbWl0KCdyZXNwb25zZScsIHJlc3BvbnNlKTtcbiAgICAgICAgLy8gUmVmcmVzaCB0b2tlbiBpZiBzZXNzaW9uIGhhcyBiZWVuIGV4cGlyZWQgYW5kIHJlcXVpcmVzIGF1dGhlbnRpY2F0aW9uXG4gICAgICAgIC8vIHdoZW4gc2Vzc2lvbiByZWZyZXNoIGRlbGVnYXRlIGlzIGF2YWlsYWJsZVxuICAgICAgICBpZiAodGhpcy5pc1Nlc3Npb25FeHBpcmVkKHJlc3BvbnNlKSAmJiByZWZyZXNoRGVsZWdhdGUpIHtcbiAgICAgICAgICBhd2FpdCByZWZyZXNoRGVsZWdhdGUucmVmcmVzaChyZXF1ZXN0VGltZSk7XG4gICAgICAgICAgLyogcmVtb3ZlIHRoZSBgY29udGVudC1sZW5ndGhgIGhlYWRlciBhZnRlciB0b2tlbiByZWZyZXNoXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBTT0FQIHJlcXVlc3RzIGluY2x1ZGUgdGhlIGFjY2VzcyB0b2tlbiB0aGVpciB0aGUgYm9keSxcbiAgICAgICAgICAgKiBpZiB0aGUgZmlyc3QgcmVxIGhhZCBhbiBpbnZhbGlkIHRva2VuIGFuZCBqc2ZvcmNlIHN1Y2Nlc3NmdWxseVxuICAgICAgICAgICAqIHJlZnJlc2hlZCBpdCB3ZSBuZWVkIHRvIHJlbW92ZSB0aGUgYGNvbnRlbnQtbGVuZ3RoYCBoZWFkZXJcbiAgICAgICAgICAgKiBzbyB0aGF0IGl0IGdldCdzIHJlLWNhbGN1bGF0ZWQgYWdhaW4gd2l0aCB0aGUgbmV3IGJvZHkuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBSRVNUIHJlcXVlc3QgYXJlbid0IGFmZmVjdGVkIGJ5IHRoaXMgYmVjYXVzZSB0aGUgYWNjZXNzIHRva2VuXG4gICAgICAgICAgICogaXMgc2VudCB2aWEgSFRUUCBoZWFkZXJzXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBgX21lc3NhZ2VgIGlzIG9ubHkgcHJlc2VudCBpbiBTT0FQIHJlcXVlc3RzXG4gICAgICAgICAgICovXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgJ19tZXNzYWdlJyBpbiByZXF1ZXN0ICYmXG4gICAgICAgICAgICByZXF1ZXN0LmhlYWRlcnMgJiZcbiAgICAgICAgICAgICdjb250ZW50LWxlbmd0aCcgaW4gcmVxdWVzdC5oZWFkZXJzXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBkZWxldGUgcmVxdWVzdC5oZWFkZXJzWydjb250ZW50LWxlbmd0aCddO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHJlcXVlc3QpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzRXJyb3JSZXNwb25zZShyZXNwb25zZSkpIHtcbiAgICAgICAgICBjb25zdCBlcnIgPSBhd2FpdCB0aGlzLmdldEVycm9yKHJlc3BvbnNlKTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHRoaXMuZ2V0UmVzcG9uc2VCb2R5KHJlc3BvbnNlKTtcbiAgICAgICAgcmV0dXJuIGJvZHk7XG4gICAgICB9KSgpO1xuICAgICAgcmV0dXJuIHsgc3RyZWFtLCBwcm9taXNlIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgZ2V0UmVmcmVzaERlbGVnYXRlKCkge1xuICAgIHJldHVybiB0aGlzLl9jb25uLl9yZWZyZXNoRGVsZWdhdGU7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgYmVmb3JlU2VuZChyZXF1ZXN0OiBIdHRwUmVxdWVzdCkge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXBhcmFtLXJlYXNzaWduICovXG4gICAgY29uc3QgaGVhZGVycyA9IHJlcXVlc3QuaGVhZGVycyB8fCB7fTtcbiAgICBpZiAodGhpcy5fY29ubi5hY2Nlc3NUb2tlbikge1xuICAgICAgaGVhZGVycy5BdXRob3JpemF0aW9uID0gYEJlYXJlciAke3RoaXMuX2Nvbm4uYWNjZXNzVG9rZW59YDtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2Nvbm4uX2NhbGxPcHRpb25zKSB7XG4gICAgICBjb25zdCBjYWxsT3B0aW9ucyA9IFtdO1xuICAgICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKHRoaXMuX2Nvbm4uX2NhbGxPcHRpb25zKSkge1xuICAgICAgICBjYWxsT3B0aW9ucy5wdXNoKGAke25hbWV9PSR7dGhpcy5fY29ubi5fY2FsbE9wdGlvbnNbbmFtZV19YCk7XG4gICAgICB9XG4gICAgICBoZWFkZXJzWydTZm9yY2UtQ2FsbC1PcHRpb25zJ10gPSBjYWxsT3B0aW9ucy5qb2luKCcsICcpO1xuICAgIH1cblxuICAgIGNvbnN0IGJvZHlTaXplID0gZ2V0Qm9keVNpemUocmVxdWVzdC5ib2R5LCBoZWFkZXJzKTtcblxuICAgIGNvbnN0IGNhbm5vdEhhdmVCb2R5ID0gWydHRVQnLCAnSEVBRCcsICdPUFRJT05TJ10uaW5jbHVkZXMocmVxdWVzdC5tZXRob2QpO1xuXG4gICAgaWYgKFxuICAgICAgIWNhbm5vdEhhdmVCb2R5ICYmXG4gICAgICAhIXJlcXVlc3QuYm9keSAmJlxuICAgICAgISgndHJhbnNmZXItZW5jb2RpbmcnIGluIGhlYWRlcnMpICYmXG4gICAgICAhKCdjb250ZW50LWxlbmd0aCcgaW4gaGVhZGVycykgJiZcbiAgICAgICEhYm9keVNpemVcbiAgICApIHtcbiAgICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYG1pc3NpbmcgJ2NvbnRlbnQtbGVuZ3RoJyBoZWFkZXIsIHNldHRpbmcgaXQgdG86ICR7Ym9keVNpemV9YCxcbiAgICAgICk7XG4gICAgICBoZWFkZXJzWydjb250ZW50LWxlbmd0aCddID0gU3RyaW5nKGJvZHlTaXplKTtcbiAgICB9XG4gICAgcmVxdWVzdC5oZWFkZXJzID0gaGVhZGVycztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgcmVzcG9uc2UgY29udGVudCBtaW1lLXR5cGVcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgZ2V0UmVzcG9uc2VDb250ZW50VHlwZShyZXNwb25zZTogSHR0cFJlc3BvbnNlKTogT3B0aW9uYWw8c3RyaW5nPiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuX3Jlc3BvbnNlVHlwZSB8fFxuICAgICAgKHJlc3BvbnNlLmhlYWRlcnMgJiYgcmVzcG9uc2UuaGVhZGVyc1snY29udGVudC10eXBlJ10pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9yZXF1aXJlLWF3YWl0XG4gIGFzeW5jIHBhcnNlUmVzcG9uc2VCb2R5KHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UpIHtcbiAgICBjb25zdCBjb250ZW50VHlwZSA9IHRoaXMuZ2V0UmVzcG9uc2VDb250ZW50VHlwZShyZXNwb25zZSkgfHwgJyc7XG4gICAgY29uc3QgcGFyc2VCb2R5ID0gL14odGV4dHxhcHBsaWNhdGlvbilcXC94bWwoO3wkKS8udGVzdChjb250ZW50VHlwZSlcbiAgICAgID8gcGFyc2VYTUxcbiAgICAgIDogL15hcHBsaWNhdGlvblxcL2pzb24oO3wkKS8udGVzdChjb250ZW50VHlwZSlcbiAgICAgID8gcGFyc2VKU09OXG4gICAgICA6IC9edGV4dFxcL2Nzdig7fCQpLy50ZXN0KGNvbnRlbnRUeXBlKVxuICAgICAgPyBwYXJzZUNTVlxuICAgICAgOiBwYXJzZVRleHQ7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBwYXJzZUJvZHkocmVzcG9uc2UuYm9keSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gVE9ETyhuZXh0IG1ham9yKTogd2UgY291bGQgdGhyb3cgYSBuZXcgXCJpbnZhbGlkIHJlc3BvbnNlIGJvZHlcIiBlcnJvciBpbnN0ZWFkLlxuICAgICAgdGhpcy5fbG9nZ2VyLmRlYnVnKGBGYWlsZWQgdG8gcGFyc2UgYm9keSBvZiBjb250ZW50LXR5cGU6ICR7Y29udGVudFR5cGV9LiBFcnJvcjogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKVxuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCByZXNwb25zZSBib2R5XG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIGFzeW5jIGdldFJlc3BvbnNlQm9keShyZXNwb25zZTogSHR0cFJlc3BvbnNlKSB7XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPT09IDIwNCkge1xuICAgICAgLy8gTm8gQ29udGVudFxuICAgICAgcmV0dXJuIHRoaXMuX25vQ29udGVudFJlc3BvbnNlO1xuICAgIH1cbiAgICBjb25zdCBib2R5ID0gYXdhaXQgdGhpcy5wYXJzZVJlc3BvbnNlQm9keShyZXNwb25zZSk7XG4gICAgbGV0IGVycjtcbiAgICBpZiAodGhpcy5oYXNFcnJvckluUmVzcG9uc2VCb2R5KGJvZHkpKSB7XG4gICAgICBlcnIgPSBhd2FpdCB0aGlzLmdldEVycm9yKHJlc3BvbnNlLCBib2R5KTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPT09IDMwMCkge1xuICAgICAgLy8gTXVsdGlwbGUgQ2hvaWNlc1xuICAgICAgdGhyb3cgbmV3IEh0dHBBcGlFcnJvcihcbiAgICAgICAgJ011bHRpcGxlIHJlY29yZHMgZm91bmQnLFxuICAgICAgICAnTVVMVElQTEVfQ0hPSUNFUycsXG4gICAgICAgIGJvZHksXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gYm9keTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3Qgc2Vzc2lvbiBleHBpcnlcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgaXNTZXNzaW9uRXhwaXJlZChyZXNwb25zZTogSHR0cFJlc3BvbnNlKSB7XG4gICAgLy8gVE9ETzpcbiAgICAvLyBUaGUgY29ubmVjdGVkIGFwcCBtc2cgb25seSBhcHBsaWVzIHRvIEFnZW50IEFQSSByZXF1ZXN0cywgd2Ugc2hvdWxkIG1vdmUgdGhpcyB0byBhIHNlcGFyYXRlIFNGQVAvQWdlbnQgQVBJIGNsYXNzIGxhdGVyLlxuICAgIHJldHVybiByZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MDEgJiYgIXJlc3BvbnNlLmJvZHkuaW5jbHVkZXMoJ0Nvbm5lY3RlZCBhcHAgaXMgbm90IGF0dGFjaGVkIHRvIEFnZW50JylcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgZXJyb3IgcmVzcG9uc2VcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgaXNFcnJvclJlc3BvbnNlKHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UpIHtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3RhdHVzQ29kZSA+PSA0MDA7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZWN0IGVycm9yIGluIHJlc3BvbnNlIGJvZHlcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgaGFzRXJyb3JJblJlc3BvbnNlQm9keShfYm9keTogT3B0aW9uYWw8c3RyaW5nPikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGVycm9yIG1lc3NhZ2UgaW4gcmVzcG9uc2VcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcGFyc2VFcnJvcihib2R5OiBhbnkpIHtcbiAgICBjb25zdCBlcnJvcnMgPSBib2R5O1xuXG4gICAgLy8gWE1MIHJlc3BvbnNlXG4gICAgaWYgKGVycm9ycy5FcnJvcnMpIHtcbiAgICAgIHJldHVybiBlcnJvcnMuRXJyb3JzLkVycm9yO1xuICAgIH1cblxuICAgIHJldHVybiBlcnJvcnM7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGVycm9yIG1lc3NhZ2UgaW4gcmVzcG9uc2VcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgYXN5bmMgZ2V0RXJyb3IocmVzcG9uc2U6IEh0dHBSZXNwb25zZSwgYm9keT86IGFueSk6IFByb21pc2U8RXJyb3I+IHtcbiAgICBsZXQgZXJyb3I7XG4gICAgdHJ5IHtcbiAgICAgIGVycm9yID0gdGhpcy5wYXJzZUVycm9yKGJvZHkgfHwgKGF3YWl0IHRoaXMucGFyc2VSZXNwb25zZUJvZHkocmVzcG9uc2UpKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUgbm8tZW1wdHlcbiAgICB9XG4gICAgXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZXJyb3IpKSB7XG4gICAgICBpZiAoZXJyb3IubGVuZ3RoID09PSAxKXtcbiAgICAgICAgZXJyb3IgPSBlcnJvclswXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBIdHRwQXBpRXJyb3IoXG4gICAgICAgICAgYE11bHRpcGxlIGVycm9ycyByZXR1cm5lZC5cbiAgQ2hlY2sgXFxgZXJyb3IuZGF0YVxcYCBmb3IgdGhlIGVycm9yIGRldGFpbHNgLCAnTVVMVElQTEVfQVBJX0VSUk9SUycsIGVycm9yKSAgIFxuICAgICAgfVxuICAgIH1cblxuICAgIGVycm9yID1cbiAgICAgIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcgJiZcbiAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICB0eXBlb2YgZXJyb3IubWVzc2FnZSA9PT0gJ3N0cmluZydcbiAgICAgICAgPyBlcnJvclxuICAgICAgICA6IHtcbiAgICAgICAgICAgIGVycm9yQ29kZTogYEVSUk9SX0hUVFBfJHtyZXNwb25zZS5zdGF0dXNDb2RlfWAsXG4gICAgICAgICAgICBtZXNzYWdlOiByZXNwb25zZS5ib2R5LFxuICAgICAgICAgIH07XG5cbiAgICBpZiAocmVzcG9uc2UuaGVhZGVyc1snY29udGVudC10eXBlJ10gPT09ICd0ZXh0L2h0bWwnKSB7XG4gICAgICB0aGlzLl9sb2dnZXIuZGVidWcoYGh0bWwgcmVzcG9uc2UuYm9keTogJHtyZXNwb25zZS5ib2R5fWApO1xuICAgICAgcmV0dXJuIG5ldyBIdHRwQXBpRXJyb3IoXG4gICAgICAgIGBIVFRQIHJlc3BvbnNlIGNvbnRhaW5zIGh0bWwgY29udGVudC5cbkNoZWNrIHRoYXQgdGhlIG9yZyBleGlzdHMgYW5kIGNhbiBiZSByZWFjaGVkLlxuU2VlIFxcYGVycm9yLmRhdGFcXGAgZm9yIHRoZSBmdWxsIGh0bWwgcmVzcG9uc2UuYCxcbiAgICAgICAgZXJyb3IuZXJyb3JDb2RlLFxuICAgICAgICBlcnJvci5tZXNzYWdlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3IgaW5zdGFuY2VvZiBIdHRwQXBpRXJyb3IgPyBlcnJvciA6IG5ldyBIdHRwQXBpRXJyb3IoZXJyb3IubWVzc2FnZSwgZXJyb3IuZXJyb3JDb2RlLCBlcnJvcik7XG4gIH1cbn1cblxuLyoqXG4gKlxuICovXG5jbGFzcyBIdHRwQXBpRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBUaGlzIGNvbnRhaW5zIGVycm9yLXNwZWNpZmljIGRldGFpbHMsIHVzdWFsbHkgcmV0dXJuZWQgZnJvbSB0aGUgQVBJLlxuICAgKi9cbiAgZGF0YTogYW55XG4gIGVycm9yQ29kZTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgZXJyb3JDb2RlPzogc3RyaW5nIHwgdW5kZWZpbmVkLCBkYXRhPzogYW55KSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gZXJyb3JDb2RlIHx8IHRoaXMubmFtZTtcbiAgICB0aGlzLmVycm9yQ29kZSA9IHRoaXMubmFtZTtcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBuZXh0IG1ham9yICh2NClcbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgdXNlIGBlcnJvci5kYXRhYCBpbnN0ZWFkXG4gICAqL1xuICBnZXQgY29udGVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEh0dHBBcGk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQSxTQUFTQSxZQUFZLFFBQVEsUUFBUTtBQUNyQyxPQUFPQyxNQUFNLE1BQU0sUUFBUTtBQUMzQixTQUFpQkMsU0FBUyxRQUFRLGVBQWU7QUFDakQsU0FBU0MsYUFBYSxRQUFRLGdCQUFnQjtBQUc5QyxTQUFTQyxRQUFRLFFBQVEsT0FBTztBQVFoQyxTQUFTQyxnQkFBZ0IsUUFBUSxlQUFlO0FBQ2hELFNBQVNDLFdBQVcsUUFBUSxzQkFBc0I7O0FBRWxEO0FBQ0EsU0FBU0MsU0FBU0EsQ0FBQ0MsR0FBVyxFQUFFO0VBQzlCLE9BQU9DLElBQUksQ0FBQ0MsS0FBSyxDQUFDRixHQUFHLENBQUM7QUFDeEI7O0FBRUE7QUFBQSxTQUNlRyxRQUFRQSxDQUFBQyxFQUFBO0VBQUEsT0FBQUMsU0FBQSxDQUFBQyxLQUFBLE9BQUFDLFNBQUE7QUFBQTtBQUl2QjtBQUFBLFNBQUFGLFVBQUE7RUFBQUEsU0FBQSxHQUFBRyxpQkFBQSxjQUFBQyxtQkFBQSxDQUFBQyxJQUFBLENBSkEsU0FBQUMsU0FBd0JYLEdBQVc7SUFBQSxPQUFBUyxtQkFBQSxDQUFBRyxJQUFBLFVBQUFDLFVBQUFDLFVBQUE7TUFBQSxrQkFBQUEsVUFBQSxDQUFBQyxJQUFBLEdBQUFELFVBQUEsQ0FBQUUsSUFBQTtRQUFBO1VBQUEsT0FBQUYsVUFBQSxDQUFBRyxNQUFBLFdBQzFCeEIsTUFBTSxDQUFDeUIsa0JB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