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 _Reflect$construct from "@babel/runtime-corejs3/core-js-stable/reflect/construct"; 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 _wrapNativeSuper from "@babel/runtime-corejs3/helpers/wrapNativeSuper"; import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator"; import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty"; import _classCallCheck from "@babel/runtime-corejs3/helpers/classCallCheck"; import _createClass from "@babel/runtime-corejs3/helpers/createClass"; 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 _regeneratorRuntime from "@babel/runtime-corejs3/regenerator"; 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 _context12, _context13; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context12 = ownKeys(Object(t), !0)).call(_context12, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context13 = ownKeys(Object(t))).call(_context13, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice"; import _endsWithInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/ends-with"; import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat"; import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes"; import "core-js/modules/es.error.cause.js"; import "core-js/modules/es.array.join.js"; import "core-js/modules/es.function.name.js"; import "core-js/modules/es.object.keys.js"; import "core-js/modules/es.array.push.js"; import "core-js/modules/es.object.to-string.js"; import "core-js/modules/es.regexp.exec.js"; import "core-js/modules/es.regexp.to-string.js"; import "core-js/modules/es.string.replace.js"; /** * */ import { createHash, randomBytes } from 'crypto'; import querystring from 'querystring'; import Transport, { HttpProxyTransport, XdProxyTransport } from './transport'; var defaultOAuth2Config = { loginUrl: 'https://login.salesforce.com' }; // Makes a nodejs base64 encoded string compatible with rfc4648 alternative encoding for urls. // @param base64Encoded a nodejs base64 encoded string function base64UrlEscape(base64Encoded) { // builtin node js base 64 encoding is not 64 url compatible. // See https://toolsn.ietf.org/html/rfc4648#section-5 return base64Encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); } /** * type defs */ /** * OAuth2 class */ export var OAuth2 = /*#__PURE__*/function () { /** * */ function OAuth2(config) { _classCallCheck(this, OAuth2); var loginUrl = config.loginUrl, authzServiceUrl = config.authzServiceUrl, tokenServiceUrl = config.tokenServiceUrl, revokeServiceUrl = config.revokeServiceUrl, clientId = config.clientId, clientSecret = config.clientSecret, redirectUri = config.redirectUri, proxyUrl = config.proxyUrl, httpProxy = config.httpProxy, useVerifier = config.useVerifier; if (authzServiceUrl && tokenServiceUrl) { var _context; this.loginUrl = _sliceInstanceProperty(_context = authzServiceUrl.split('/')).call(_context, 0, 3).join('/'); this.authzServiceUrl = authzServiceUrl; this.tokenServiceUrl = tokenServiceUrl; this.revokeServiceUrl = revokeServiceUrl || "".concat(this.loginUrl, "/services/oauth2/revoke"); } else { var _context2, _context3, _context4, _context5; this.loginUrl = loginUrl !== null && loginUrl !== void 0 ? loginUrl : defaultOAuth2Config.loginUrl; var maybeSlash = _endsWithInstanceProperty(_context2 = this.loginUrl).call(_context2, '/') ? '' : '/'; this.authzServiceUrl = _concatInstanceProperty(_context3 = "".concat(this.loginUrl)).call(_context3, maybeSlash, "services/oauth2/authorize"); this.tokenServiceUrl = _concatInstanceProperty(_context4 = "".concat(this.loginUrl)).call(_context4, maybeSlash, "services/oauth2/token"); this.revokeServiceUrl = _concatInstanceProperty(_context5 = "".concat(this.loginUrl)).call(_context5, maybeSlash, "services/oauth2/revoke"); } this.clientId = clientId; this.clientSecret = clientSecret; this.redirectUri = redirectUri; if (proxyUrl) { this._transport = new XdProxyTransport(proxyUrl); } else if (httpProxy) { this._transport = new HttpProxyTransport(httpProxy); } else { this._transport = new Transport(); } if (useVerifier) { // Set a code verifier string for OAuth authorization this.codeVerifier = base64UrlEscape(randomBytes(Math.ceil(128)).toString('base64')); } } /** * Get Salesforce OAuth2 authorization page URL to redirect user agent. */ return _createClass(OAuth2, [{ key: "getAuthorizationUrl", value: function getAuthorizationUrl() { var _context6; var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (this.codeVerifier) { // code verifier must be a base 64 url encoded hash of 128 bytes of random data. Our random data is also // base 64 url encoded. See Connection.create(); params.code_challenge = base64UrlEscape(createHash('sha256').update(this.codeVerifier).digest('base64')); } var _params = _objectSpread(_objectSpread({}, params), {}, { response_type: 'code', client_id: this.clientId, redirect_uri: this.redirectUri }); return this.authzServiceUrl + (_includesInstanceProperty(_context6 = this.authzServiceUrl).call(_context6, '?') ? '&' : '?') + querystring.stringify(_params); } /** * OAuth2 Refresh Token Flow */ }, { key: "refreshToken", value: (function () { var _refreshToken2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(_refreshToken) { var params, ret; return _regeneratorRuntime.wrap(function _callee$(_context7) { while (1) switch (_context7.prev = _context7.next) { case 0: if (this.clientId) { _context7.next = 2; break; } throw new Error('No OAuth2 client id information is specified'); case 2: params = { grant_type: 'refresh_token', refresh_token: _refreshToken, client_id: this.clientId }; if (this.clientSecret) { params.client_secret = this.clientSecret; } _context7.next = 6; return this._postParams(params); case 6: ret = _context7.sent; return _context7.abrupt("return", ret); case 8: case "end": return _context7.stop(); } }, _callee, this); })); function refreshToken(_x) { return _refreshToken2.apply(this, arguments); } return refreshToken; }() /** * Send access token request to the token endpoint. * When a code (string) is passed in first argument, it will use Web Server Authentication Flow (Authorization Code Grant). * Otherwise, it will use the specified `grant_type` and pass parameters to the endpoint. */ ) }, { key: "requestToken", value: (function () { var _requestToken = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(codeOrParams) { var params, _params, ret, _args2 = arguments; return _regeneratorRuntime.wrap(function _callee2$(_context8) { while (1) switch (_context8.prev = _context8.next) { case 0: params = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {}; if (!(typeof codeOrParams === 'string' && (!this.clientId || !this.redirectUri))) { _context8.next = 3; break; } throw new Error('No OAuth2 client id or redirect uri configuration is specified'); case 3: _params = _objectSpread(_objectSpread({}, params), typeof codeOrParams === 'string' ? { grant_type: 'authorization_code', code: codeOrParams } : codeOrParams); if (this.clientId) { _params.client_id = this.clientId; } if (this.clientSecret) { _params.client_secret = this.clientSecret; } if (this.redirectUri) { _params.redirect_uri = this.redirectUri; } _context8.next = 9; return this._postParams(_params); case 9: ret = _context8.sent; return _context8.abrupt("return", ret); case 11: case "end": return _context8.stop(); } }, _callee2, this); })); function requestToken(_x2) { return _requestToken.apply(this, arguments); } return requestToken; }() /** * OAuth2 Username-Password Flow (Resource Owner Password Credentials) */ ) }, { key: "authenticate", value: (function () { var _authenticate = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(username, password) { var ret; return _regeneratorRuntime.wrap(function _callee3$(_context9) { while (1) switch (_context9.prev = _context9.next) { case 0: if (!(!this.clientId || !this.clientSecret)) { _context9.next = 2; break; } throw new Error('No valid OAuth2 client configuration set'); case 2: _context9.next = 4; return this._postParams({ grant_type: 'password', username: username, password: password, client_id: this.clientId, client_secret: this.clientSecret }); case 4: ret = _context9.sent; return _context9.abrupt("return", ret); case 6: case "end": return _context9.stop(); } }, _callee3, this); })); function authenticate(_x3, _x4) { return _authenticate.apply(this, arguments); } return authenticate; }() /** * OAuth2 Revoke Session Token */ ) }, { key: "revokeToken", value: (function () { var _revokeToken = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(token) { var response, res; return _regeneratorRuntime.wrap(function _callee4$(_context10) { while (1) switch (_context10.prev = _context10.next) { case 0: _context10.next = 2; return this._transport.httpRequest({ method: 'POST', url: this.revokeServiceUrl, body: querystring.stringify({ token: token }), headers: { 'content-type': 'application/x-www-form-urlencoded' } }); case 2: response = _context10.sent; if (!(response.statusCode >= 400)) { _context10.next = 7; break; } res = querystring.parse(response.body); if (!res || !res.error) { res = { error: "ERROR_HTTP_".concat(response.statusCode), error_description: response.body }; } throw new (/*#__PURE__*/function (_Error) { function _class(_ref) { var _this; var error = _ref.error, error_description = _ref.error_description; _classCallCheck(this, _class); _this = _callSuper(this, _class, [error_description]); _this.name = error; return _this; } _inherits(_class, _Error); return _createClass(_class); }(/*#__PURE__*/_wrapNativeSuper(Error)))(res); case 7: case "end": return _context10.stop(); } }, _callee4, this); })); function revokeToken(_x5) { return _revokeToken.apply(this, arguments); } return revokeToken; }() /** * @private */ ) }, { key: "_postParams", value: (function () { var _postParams2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(params) { var response, res; return _regeneratorRuntime.wrap(function _callee5$(_context11) { while (1) switch (_context11.prev = _context11.next) { case 0: if (this.codeVerifier) params.code_verifier = this.codeVerifier; _context11.next = 3; return this._transport.httpRequest({ method: 'POST', url: this.tokenServiceUrl, body: querystring.stringify(params), headers: { 'content-type': 'application/x-www-form-urlencoded' } }); case 3: response = _context11.sent; try { res = JSON.parse(response.body); } catch (e) { /* eslint-disable no-empty */ } if (!(response.statusCode >= 400)) { _context11.next = 8; break; } res = res || { error: "ERROR_HTTP_".concat(response.statusCode), error_description: response.body }; throw new (/*#__PURE__*/function (_Error2) { function _class2(_ref2) { var _this2; var error = _ref2.error, error_description = _ref2.error_description; _classCallCheck(this, _class2); _this2 = _callSuper(this, _class2, [error_description]); _this2.name = error; return _this2; } _inherits(_class2, _Error2); return _createClass(_class2); }(/*#__PURE__*/_wrapNativeSuper(Error)))(res); case 8: return _context11.abrupt("return", res); case 9: case "end": return _context11.stop(); } }, _callee5, this); })); function _postParams(_x6) { return _postParams2.apply(this, arguments); } return _postParams; }()) }]); }(); export default OAuth2; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjcmVhdGVIYXNoIiwicmFuZG9tQnl0ZXMiLCJxdWVyeXN0cmluZyIsIlRyYW5zcG9ydCIsIkh0dHBQcm94eVRyYW5zcG9ydCIsIlhkUHJveHlUcmFuc3BvcnQiLCJkZWZhdWx0T0F1dGgyQ29uZmlnIiwibG9naW5VcmwiLCJiYXNlNjRVcmxFc2NhcGUiLCJiYXNlNjRFbmNvZGVkIiwicmVwbGFjZSIsIk9BdXRoMiIsImNvbmZpZyIsIl9jbGFzc0NhbGxDaGVjayIsImF1dGh6U2VydmljZVVybCIsInRva2VuU2VydmljZVVybCIsInJldm9rZVNlcnZpY2VVcmwiLCJjbGllbnRJZCIsImNsaWVudFNlY3JldCIsInJlZGlyZWN0VXJpIiwicHJveHlVcmwiLCJodHRwUHJveHkiLCJ1c2VWZXJpZmllciIsIl9jb250ZXh0IiwiX3NsaWNlSW5zdGFuY2VQcm9wZXJ0eSIsInNwbGl0IiwiY2FsbCIsImpvaW4iLCJjb25jYXQiLCJfY29udGV4dDIiLCJfY29udGV4dDMiLCJfY29udGV4dDQiLCJfY29udGV4dDUiLCJtYXliZVNsYXNoIiwiX2VuZHNXaXRoSW5zdGFuY2VQcm9wZXJ0eSIsIl9jb25jYXRJbnN0YW5jZVByb3BlcnR5IiwiX3RyYW5zcG9ydCIsImNvZGVWZXJpZmllciIsIk1hdGgiLCJjZWlsIiwidG9TdHJpbmciLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsImdldEF1dGhvcml6YXRpb25VcmwiLCJfY29udGV4dDYiLCJwYXJhbXMiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJjb2RlX2NoYWxsZW5nZSIsInVwZGF0ZSIsImRpZ2VzdCIsIl9wYXJhbXMiLCJfb2JqZWN0U3ByZWFkIiwicmVzcG9uc2VfdHlwZSIsImNsaWVudF9pZCIsInJlZGlyZWN0X3VyaSIsIl9pbmNsdWRlc0luc3RhbmNlUHJvcGVydHkiLCJzdHJpbmdpZnkiLCJfcmVmcmVzaFRva2VuMiIsIl9hc3luY1RvR2VuZXJhdG9yIiwiX3JlZ2VuZXJhdG9yUnVudGltZSIsIm1hcmsiLCJfY2FsbGVlIiwicmVmcmVzaFRva2VuIiwicmV0Iiwid3JhcCIsIl9jYWxsZWUkIiwiX2NvbnRleHQ3IiwicHJldiIsIm5leHQiLCJFcnJvciIsImdyYW50X3R5cGUiLCJyZWZyZXNoX3Rva2VuIiwiY2xpZW50X3NlY3JldCIsIl9wb3N0UGFyYW1zIiwic2VudCIsImFicnVwdCIsInN0b3AiLCJfeCIsImFwcGx5IiwiX3JlcXVlc3RUb2tlbiIsIl9jYWxsZWUyIiwiY29kZU9yUGFyYW1zIiwiX2FyZ3MyIiwiX2NhbGxlZTIkIiwiX2NvbnRleHQ4IiwiY29kZSIsInJlcXVlc3RUb2tlbiIsIl94MiIsIl9hdXRoZW50aWNhdGUiLCJfY2FsbGVlMyIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJfY2FsbGVlMyQiLCJfY29udGV4dDkiLCJhdXRoZW50aWNhdGUiLCJfeDMiLCJfeDQiLCJfcmV2b2tlVG9rZW4iLCJfY2FsbGVlNCIsInRva2VuIiwicmVzcG9uc2UiLCJyZXMiLCJfY2FsbGVlNCQiLCJfY29udGV4dDEwIiwiaHR0cFJlcXVlc3QiLCJtZXRob2QiLCJ1cmwiLCJib2R5IiwiaGVhZGVycyIsInN0YXR1c0NvZGUiLCJwYXJzZSIsImVycm9yIiwiZXJyb3JfZGVzY3JpcHRpb24iLCJfRXJyb3IiLCJfY2xhc3MiLCJfcmVmIiwiX3RoaXMiLCJfY2FsbFN1cGVyIiwibmFtZSIsIl9pbmhlcml0cyIsIl93cmFwTmF0aXZlU3VwZXIiLCJyZXZva2VUb2tlbiIsIl94NSIsIl9wb3N0UGFyYW1zMiIsIl9jYWxsZWU1IiwiX2NhbGxlZTUkIiwiX2NvbnRleHQxMSIsImNvZGVfdmVyaWZpZXIiLCJKU09OIiwiZSIsIl9FcnJvcjIiLCJfY2xhc3MyIiwiX3JlZjIiLCJfdGhpczIiLCJfeDYiXSwic291cmNlcyI6WyIuLi9zcmMvb2F1dGgyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICpcbiAqL1xuaW1wb3J0IHtjcmVhdGVIYXNoLCByYW5kb21CeXRlc30gZnJvbSAnY3J5cHRvJztcbmltcG9ydCBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgVHJhbnNwb3J0LCB7SHR0cFByb3h5VHJhbnNwb3J0LCBYZFByb3h5VHJhbnNwb3J0fSBmcm9tICcuL3RyYW5zcG9ydCc7XG5pbXBvcnQge09wdGlvbmFsfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgZGVmYXVsdE9BdXRoMkNvbmZpZyA9IHtcbiAgbG9naW5Vcmw6ICdodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tJyxcbn07XG5cbi8vIE1ha2VzIGEgbm9kZWpzIGJhc2U2NCBlbmNvZGVkIHN0cmluZyBjb21wYXRpYmxlIHdpdGggcmZjNDY0OCBhbHRlcm5hdGl2ZSBlbmNvZGluZyBmb3IgdXJscy5cbi8vIEBwYXJhbSBiYXNlNjRFbmNvZGVkIGEgbm9kZWpzIGJhc2U2NCBlbmNvZGVkIHN0cmluZ1xuZnVuY3Rpb24gYmFzZTY0VXJsRXNjYXBlKGJhc2U2NEVuY29kZWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIGJ1aWx0aW4gbm9kZSBqcyBiYXNlIDY0IGVuY29kaW5nIGlzIG5vdCA2NCB1cmwgY29tcGF0aWJsZS5cbiAgLy8gU2VlIGh0dHBzOi8vdG9vbHNuLmlldGYub3JnL2h0bWwvcmZjNDY0OCNzZWN0aW9uLTVcbiAgcmV0dXJuIGJhc2U2NEVuY29kZWRcbiAgICAucmVwbGFjZSgvXFwrL2csICctJylcbiAgICAucmVwbGFjZSgvXFwvL2csICdfJylcbiAgICAucmVwbGFjZSgvPS9nLCAnJyk7XG59XG5cbi8qKlxuICogdHlwZSBkZWZzXG4gKi9cbmV4cG9ydCB0eXBlIE9BdXRoMkNvbmZpZyA9IHtcbiAgY2xpZW50SWQ/OiBzdHJpbmc7XG4gIGNsaWVudFNlY3JldD86IHN0cmluZztcbiAgcmVkaXJlY3RVcmk/OiBzdHJpbmc7XG4gIGxvZ2luVXJsPzogc3RyaW5nO1xuICBhdXRoelNlcnZpY2VVcmw/OiBzdHJpbmc7XG4gIHRva2VuU2VydmljZVVybD86IHN0cmluZztcbiAgcmV2b2tlU2VydmljZVVybD86IHN0cmluZztcbiAgcHJveHlVcmw/OiBzdHJpbmc7XG4gIGh0dHBQcm94eT86IHN0cmluZztcbiAgdXNlVmVyaWZpZXI/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgQXV0aHpSZXF1ZXN0UGFyYW1zID0ge1xuICBzY29wZT86IHN0cmluZztcbiAgc3RhdGU/OiBzdHJpbmc7XG4gIGNvZGVfY2hhbGxlbmdlPzogc3RyaW5nO1xufSAmIHtcbiAgW2F0dHI6IHN0cmluZ106IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIFRva2VuUmVzcG9uc2UgPSB7XG4gIHRva2VuX3R5cGU6ICdCZWFyZXInO1xuICAvKipcbiAgICogSWRlbnRpdHkgVVJMXG4gICAqXG4gICAqIFRoZSBmb3JtYXQgb2YgdGhlIFVSTCBpcyBodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tL2lkL29yZ0lEL3VzZXJJRC5cbiAgICovXG4gIGlkOiBzdHJpbmc7XG4gIGFjY2Vzc190b2tlbjogc3RyaW5nO1xuICByZWZyZXNoX3Rva2VuPzogc3RyaW5nO1xuICBzaWduYXR1cmU6IHN0cmluZztcbiAgaXNzdWVkX2F0OiBzdHJpbmc7XG4gIGluc3RhbmNlX3VybDogc3RyaW5nO1xuICBzZmRjX2NvbW11bml0eV91cmw/OiBzdHJpbmc7XG4gIHNmZGNfY29tbXVuaXR5X2lkPzogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBPQXV0aDIgY2xhc3NcbiAqL1xuZXhwb3J0IGNsYXNzIE9BdXRoMiB7XG4gIGxvZ2luVXJsOiBzdHJpbmc7XG4gIGF1dGh6U2VydmljZVVybDogc3RyaW5nO1xuICB0b2tlblNlcnZpY2VVcmw6IHN0cmluZztcbiAgcmV2b2tlU2VydmljZVVybDogc3RyaW5nO1xuICBjbGllbnRJZDogT3B0aW9uYWw8c3RyaW5nPjtcbiAgY2xpZW50U2VjcmV0OiBPcHRpb25hbDxzdHJpbmc+O1xuICByZWRpcmVjdFVyaTogT3B0aW9uYWw8c3RyaW5nPjtcbiAgY29kZVZlcmlmaWVyOiBPcHRpb25hbDxzdHJpbmc+O1xuXG4gIF90cmFuc3BvcnQ6IFRyYW5zcG9ydDtcblxuICAvKipcbiAgICpcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogT0F1dGgyQ29uZmlnKSB7XG4gICAgY29uc3Qge1xuICAgICAgbG9naW5VcmwsXG4gICAgICBhdXRoelNlcnZpY2VVcmwsXG4gICAgICB0b2tlblNlcnZpY2VVcmwsXG4gICAgICByZXZva2VTZXJ2aWNlVXJsLFxuICAgICAgY2xpZW50SWQsXG4gICAgICBjbGllbnRTZWNyZXQsXG4gICAgICByZWRpcmVjdFVyaSxcbiAgICAgIHByb3h5VXJsLFxuICAgICAgaHR0cFByb3h5LFxuICAgICAgdXNlVmVyaWZpZXIsXG4gICAgfSA9IGNvbmZpZztcbiAgICBpZiAoYXV0aHpTZXJ2aWNlVXJsICYmIHRva2VuU2VydmljZVVybCkge1xuICAgICAgdGhpcy5sb2dpblVybCA9IGF1dGh6U2VydmljZVVybC5zcGxpdCgnLycpLnNsaWNlKDAsIDMpLmpvaW4oJy8nKTtcbiAgICAgIHRoaXMuYXV0aHpTZXJ2aWNlVXJsID0gYXV0aHpTZXJ2aWNlVXJsO1xuICAgICAgdGhpcy50b2tlblNlcnZpY2VVcmwgPSB0b2tlblNlcnZpY2VVcmw7XG4gICAgICB0aGlzLnJldm9rZVNlcnZpY2VVcmwgPVxuICAgICAgICByZXZva2VTZXJ2aWNlVXJsIHx8IGAke3RoaXMubG9naW5Vcmx9L3NlcnZpY2VzL29hdXRoMi9yZXZva2VgO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2luVXJsID0gbG9naW5VcmwgPz8gZGVmYXVsdE9BdXRoMkNvbmZpZy5sb2dpblVybFxuXG4gICAgICBjb25zdCBtYXliZVNsYXNoID0gdGhpcy5sb2dpblVybC5lbmRzV2l0aCgnLycpID8gJycgOiAnLydcblxuICAgICAgdGhpcy5hdXRoelNlcnZpY2VVcmwgPSBgJHt0aGlzLmxvZ2luVXJsfSR7bWF5YmVTbGFzaH1zZXJ2aWNlcy9vYXV0aDIvYXV0aG9yaXplYFxuICAgICAgdGhpcy50b2tlblNlcnZpY2VVcmwgPSBgJHt0aGlzLmxvZ2luVXJsfSR7bWF5YmVTbGFzaH1zZXJ2aWNlcy9vYXV0aDIvdG9rZW5gXG4gICAgICB0aGlzLnJldm9rZVNlcnZpY2VVcmwgPSBgJHt0aGlzLmxvZ2luVXJsfSR7bWF5YmVTbGFzaH1zZXJ2aWNlcy9vYXV0aDIvcmV2b2tlYFxuICAgIH1cbiAgICB0aGlzLmNsaWVudElkID0gY2xpZW50SWQ7XG4gICAgdGhpcy5jbGllbnRTZWNyZXQgPSBjbGllbnRTZWNyZXQ7XG4gICAgdGhpcy5yZWRpcmVjdFVyaSA9IHJlZGlyZWN0VXJpO1xuICAgIGlmIChwcm94eVVybCkge1xuICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gbmV3IFhkUHJveHlUcmFuc3BvcnQocHJveHlVcmwpO1xuICAgIH0gZWxzZSBpZiAoaHR0cFByb3h5KSB7XG4gICAgICB0aGlzLl90cmFuc3BvcnQgPSBuZXcgSHR0cFByb3h5VHJhbnNwb3J0KGh0dHBQcm94eSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RyYW5zcG9ydCA9IG5ldyBUcmFuc3BvcnQoKTtcbiAgICB9XG4gICAgaWYgKHVzZVZlcmlmaWVyKSB7XG4gICAgICAvLyBTZXQgYSBjb2RlIHZlcmlmaWVyIHN0cmluZyBmb3IgT0F1dGggYXV0aG9yaXphdGlvblxuICAgICAgdGhpcy5jb2RlVmVyaWZpZXIgPSBiYXNlNjRVcmxFc2NhcGUoXG4gICAgICAgIHJhbmRvbUJ5dGVzKE1hdGguY2VpbCgxMjgpKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgU2FsZXNmb3JjZSBPQXV0aDIgYXV0aG9yaXphdGlvbiBwYWdlIFVSTCB0byByZWRpcmVjdCB1c2VyIGFnZW50LlxuICAgKi9cbiAgZ2V0QXV0aG9yaXphdGlvblVybChwYXJhbXM6IEF1dGh6UmVxdWVzdFBhcmFtcyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuY29kZVZlcmlmaWVyKSB7XG4gICAgICAvLyBjb2RlIHZlcmlmaWVyIG11c3QgYmUgYSBiYXNlIDY0IHVybCBlbmNvZGVkIGhhc2ggb2YgMTI4IGJ5dGVzIG9mIHJhbmRvbSBkYXRhLiBPdXIgcmFuZG9tIGRhdGEgaXMgYWxzb1xuICAgICAgLy8gYmFzZSA2NCB1cmwgZW5jb2RlZC4gU2VlIENvbm5lY3Rpb24uY3JlYXRlKCk7XG4gICAgICBwYXJhbXMuY29kZV9jaGFsbGVuZ2UgPSBiYXNlNjRVcmxFc2NhcGUoXG4gICAgICAgIGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZSh0aGlzLmNvZGVWZXJpZmllcikuZGlnZXN0KCdiYXNlNjQnKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgX3BhcmFtcyA9IHtcbiAgICAgIC4uLnBhcmFtcyxcbiAgICAgIHJlc3BvbnNlX3R5cGU6ICdjb2RlJyxcbiAgICAgIGNsaWVudF9pZDogdGhpcy5jbGllbnRJZCxcbiAgICAgIHJlZGlyZWN0X3VyaTogdGhpcy5yZWRpcmVjdFVyaSxcbiAgICB9O1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmF1dGh6U2VydmljZVVybCArXG4gICAgICAodGhpcy5hdXRoelNlcnZpY2VVcmwuaW5jbHVkZXMoJz8nKSA/ICcmJyA6ICc/JykgK1xuICAgICAgcXVlcnlzdHJpbmcuc3RyaW5naWZ5KF9wYXJhbXMgYXMgeyBbbmFtZTogc3RyaW5nXTogYW55IH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPQXV0aDIgUmVmcmVzaCBUb2tlbiBGbG93XG4gICAqL1xuICBhc3luYyByZWZyZXNoVG9rZW4ocmVmcmVzaFRva2VuOiBzdHJpbmcpOiBQcm9taXNlPFRva2VuUmVzcG9uc2U+IHtcbiAgICBpZiAoIXRoaXMuY2xpZW50SWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gT0F1dGgyIGNsaWVudCBpZCBpbmZvcm1hdGlvbiBpcyBzcGVjaWZpZWQnKTtcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zOiB7IFtwcm9wOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgIGdyYW50X3R5cGU6ICdyZWZyZXNoX3Rva2VuJyxcbiAgICAgIHJlZnJlc2hfdG9rZW46IHJlZnJlc2hUb2tlbixcbiAgICAgIGNsaWVudF9pZDogdGhpcy5jbGllbnRJZCxcbiAgICB9O1xuICAgIGlmICh0aGlzLmNsaWVudFNlY3JldCkge1xuICAgICAgcGFyYW1zLmNsaWVudF9zZWNyZXQgPSB0aGlzLmNsaWVudFNlY3JldDtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gYXdhaXQgdGhpcy5fcG9zdFBhcmFtcyhwYXJhbXMpO1xuICAgIHJldHVybiByZXQgYXMgVG9rZW5SZXNwb25zZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kIGFjY2VzcyB0b2tlbiByZXF1ZXN0IHRvIHRoZSB0b2tlbiBlbmRwb2ludC5cbiAgICogV2hlbiBhIGNvZGUgKHN0cmluZykgaXMgcGFzc2VkIGluIGZpcnN0IGFyZ3VtZW50LCBpdCB3aWxsIHVzZSBXZWIgU2VydmVyIEF1dGhlbnRpY2F0aW9uIEZsb3cgKEF1dGhvcml6YXRpb24gQ29kZSBHcmFudCkuXG4gICAqIE90aGVyd2lzZSwgaXQgd2lsbCB1c2UgdGhlIHNwZWNpZmllZCBgZ3JhbnRfdHlwZWAgYW5kIHBhc3MgcGFyYW1ldGVycyB0byB0aGUgZW5kcG9pbnQuXG4gICAqL1xuICBhc3luYyByZXF1ZXN0VG9rZW4oXG4gICAgY29kZU9yUGFyYW1zOiBzdHJpbmcgfCB7IGdyYW50X3R5cGU6IHN0cmluZzsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9LFxuICAgIHBhcmFtczogeyBbcHJvcDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fSxcbiAgKTogUHJvbWlzZTxUb2tlblJlc3BvbnNlPiB7XG4gICAgaWYgKFxuICAgICAgdHlwZW9mIGNvZGVPclBhcmFtcyA9PT0gJ3N0cmluZycgJiZcbiAgICAgICghdGhpcy5jbGllbnRJZCB8fCAhdGhpcy5yZWRpcmVjdFVyaSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ05vIE9BdXRoMiBjbGllbnQgaWQgb3IgcmVkaXJlY3QgdXJpIGNvbmZpZ3VyYXRpb24gaXMgc3BlY2lmaWVkJyxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IF9wYXJhbXM6IHsgW3Byb3A6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgLi4ucGFyYW1zLFxuICAgICAgLi4uKHR5cGVvZiBjb2RlT3JQYXJhbXMgPT09ICdzdHJpbmcnXG4gICAgICAgID8geyBncmFudF90eXBlOiAnYXV0aG9yaXphdGlvbl9jb2RlJywgY29kZTogY29kZU9yUGFyYW1zIH1cbiAgICAgICAgOiBjb2RlT3JQYXJhbXMpLFxuICAgIH07XG4gICAgaWYgKHRoaXMuY2xpZW50SWQpIHtcbiAgICAgIF9wYXJhbXMuY2xpZW50X2lkID0gdGhpcy5jbGllbnRJZDtcbiAgICB9XG4gICAgaWYgKHRoaXMuY2xpZW50U2VjcmV0KSB7XG4gICAgICBfcGFyYW1zLmNsaWVudF9zZWNyZXQgPSB0aGlzLmNsaWVudFNlY3JldDtcbiAgICB9XG4gICAgaWYgKHRoaXMucmVkaXJlY3RVcmkpIHtcbiAgICAgIF9wYXJhbXMucmVkaXJlY3RfdXJpID0gdGhpcy5yZWRpcmVjdFVyaTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gYXdhaXQgdGhpcy5fcG9zdFBhcmFtcyhfcGFyYW1zKTtcbiAgICByZXR1cm4gcmV0IGFzIFRva2VuUmVzcG9uc2U7XG4gIH1cblxuICAvKipcbiAgICogT0F1dGgyIFVzZXJuYW1lLVBhc3N3b3JkIEZsb3cgKFJlc291cmNlIE93bmVyIFBhc3N3b3JkIENyZWRlbnRpYWxzKVxuICAgKi9cbiAgYXN5bmMgYXV0aGVudGljYXRlKFxuICAgIHVzZXJuYW1lOiBzdHJpbmcsXG4gICAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxUb2tlblJlc3BvbnNlPiB7XG4gICAgaWYgKCF0aGlzLmNsaWVudElkIHx8ICF0aGlzLmNsaWVudFNlY3JldCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB2YWxpZCBPQXV0aDIgY2xpZW50IGNvbmZpZ3VyYXRpb24gc2V0Jyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IGF3YWl0IHRoaXMuX3Bvc3RQYXJhbXMoe1xuICAgICAgZ3JhbnRfdHlwZTogJ3Bhc3N3b3JkJyxcbiAgICAgIHVzZXJuYW1lLFxuICAgICAgcGFzc3dvcmQsXG4gICAgICBjbGllbnRfaWQ6IHRoaXMuY2xpZW50SWQsXG4gICAgICBjbGllbnRfc2VjcmV0OiB0aGlzLmNsaWVudFNlY3JldCxcbiAgICB9KTtcbiAgICByZXR1cm4gcmV0IGFzIFRva2VuUmVzcG9uc2U7XG4gIH1cblxuICAvKipcbiAgICogT0F1dGgyIFJldm9rZSBTZXNzaW9uIFRva2VuXG4gICAqL1xuICBhc3luYyByZXZva2VUb2tlbih0b2tlbjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl90cmFuc3BvcnQuaHR0cFJlcXVlc3Qoe1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICB1cmw6IHRoaXMucmV2b2tlU2VydmljZVVybCxcbiAgICAgIGJvZHk6IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSh7IHRva2VuIH0pLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID49IDQwMCkge1xuICAgICAgbGV0IHJlczogYW55ID0gcXVlcnlzdHJpbmcucGFyc2UocmVzcG9uc2UuYm9keSk7XG4gICAgICBpZiAoIXJlcyB8fCAhcmVzLmVycm9yKSB7XG4gICAgICAgIHJlcyA9IHtcbiAgICAgICAgICBlcnJvcjogYEVSUk9SX0hUVFBfJHtyZXNwb25zZS5zdGF0dXNDb2RlfWAsXG4gICAgICAgICAgZXJyb3JfZGVzY3JpcHRpb246IHJlc3BvbnNlLmJvZHksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgKGNsYXNzIGV4dGVuZHMgRXJyb3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcih7XG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgZXJyb3JfZGVzY3JpcHRpb24sXG4gICAgICAgIH06IHtcbiAgICAgICAgICBlcnJvcjogc3RyaW5nO1xuICAgICAgICAgIGVycm9yX2Rlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgICAgIH0pIHtcbiAgICAgICAgICBzdXBlcihlcnJvcl9kZXNjcmlwdGlvbik7XG4gICAgICAgICAgdGhpcy5uYW1lID0gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pKHJlcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBhc3luYyBfcG9zdFBhcmFtcyhwYXJhbXM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAodGhpcy5jb2RlVmVyaWZpZXIpIHBhcmFtcy5jb2RlX3ZlcmlmaWVyID0gdGhpcy5jb2RlVmVyaWZpZXI7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3RyYW5zcG9ydC5odHRwUmVxdWVzdCh7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIHVybDogdGhpcy50b2tlblNlcnZpY2VVcmwsXG4gICAgICBib2R5OiBxdWVyeXN0cmluZy5zdHJpbmdpZnkocGFyYW1zKSxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBsZXQgcmVzO1xuICAgIHRyeSB7XG4gICAgICByZXMgPSBKU09OLnBhcnNlKHJlc3BvbnNlLmJvZHkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWVtcHR5ICovXG4gICAgfVxuICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID49IDQwMCkge1xuICAgICAgcmVzID0gcmVzIHx8IHtcbiAgICAgICAgZXJyb3I6IGBFUlJPUl9IVFRQXyR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gLFxuICAgICAgICBlcnJvcl9kZXNjcmlwdGlvbjogcmVzcG9uc2UuYm9keSxcbiAgICAgIH07XG4gICAgICB0aHJvdyBuZXcgKGNsYXNzIGV4dGVuZHMgRXJyb3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcih7XG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgZXJyb3JfZGVzY3JpcHRpb24sXG4gICAgICAgIH06IHtcbiAgICAgICAgICBlcnJvcjogc3RyaW5nO1xuICAgICAgICAgIGVycm9yX2Rlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgICAgIH0pIHtcbiAgICAgICAgICBzdXBlcihlcnJvcl9kZXNjcmlwdGlvbik7XG4gICAgICAgICAgdGhpcy5uYW1lID0gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pKHJlcyk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgT0F1dGgyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBLFNBQVFBLFVBQVUsRUFBRUMsV0FBVyxRQUFPLFFBQVE7QUFDOUMsT0FBT0MsV0FBVyxNQUFNLGFBQWE7QUFDckMsT0FBT0MsU0FBUyxJQUFHQyxrQkFBa0IsRUFBRUMsZ0JBQWdCLFFBQU8sYUFBYTtBQUczRSxJQUFNQyxtQkFBbUIsR0FBRztFQUMxQkMsUUFBUSxFQUFFO0FBQ1osQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsU0FBU0MsZUFBZUEsQ0FBQ0MsYUFBcUIsRUFBVTtFQUN0RDtFQUNBO0VBQ0EsT0FBT0EsYUFBYSxDQUNqQkMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FDbkJBLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQ25CQSxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztB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