UNPKG

@cloudbase/app

Version:
377 lines 45.5 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { DATA_VERSION, getSdkVersion, getBaseEndPoint, getEndPointInfo } from '../constants/common'; import { utils, constants } from '@cloudbase/utilities'; import { getLocalCache } from './cache'; import { Platform } from './adapter'; var ERRORS = constants.ERRORS; var genSeqId = utils.genSeqId, isFormData = utils.isFormData, formatUrl = utils.formatUrl; var ACTIONS_WITHOUT_ACCESSTOKEN = [ 'auth.getJwt', 'auth.logout', 'auth.signInWithTicket', 'auth.signInAnonymously', 'auth.signIn', 'auth.fetchAccessTokenWithRefreshToken', 'auth.signUpWithEmailAndPassword', 'auth.activateEndUserMail', 'auth.sendPasswordResetEmail', 'auth.resetPasswordWithToken', 'auth.isUsernameRegistered', ]; function bindHooks(instance, name, hooks) { var originMethod = instance[name]; instance[name] = function (options) { var data = {}; var headers = {}; hooks.forEach(function (hook) { var _a = hook.call(instance, options), appendedData = _a.data, appendedHeaders = _a.headers; Object.assign(data, appendedData); Object.assign(headers, appendedHeaders); }); var originData = options.data; originData && (function () { if (isFormData(originData)) { Object.keys(data).forEach(function (key) { originData.append(key, data[key]); }); return; } options.data = __assign(__assign({}, originData), data); })(); options.headers = __assign(__assign({}, (options.headers || {})), headers); return originMethod.call(instance, options); }; } function beforeEach() { var seqId = genSeqId(); return { data: { seqId: seqId, }, headers: { 'X-SDK-Version': "@cloudbase/js-sdk/".concat(getSdkVersion()), 'x-seqid': seqId, }, }; } var CloudbaseRequest = (function () { function CloudbaseRequest(config) { this.throwWhenRequestFail = false; this.config = config; var reqConfig = { timeout: this.config.timeout, timeoutMsg: "[@cloudbase/js-sdk] \u8BF7\u6C42\u5728".concat(this.config.timeout / 1000, "s\u5185\u672A\u5B8C\u6210\uFF0C\u5DF2\u4E2D\u65AD"), restrictedMethods: ['post', 'put'], }; this.reqClass = new Platform.adapter.reqClass(reqConfig); this.throwWhenRequestFail = config.throw || false; this.localCache = getLocalCache(this.config.env); bindHooks(this.reqClass, 'post', [beforeEach]); bindHooks(this.reqClass, 'upload', [beforeEach]); bindHooks(this.reqClass, 'download', [beforeEach]); } CloudbaseRequest.prototype.post = function (options) { return __awaiter(this, void 0, void 0, function () { var res; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.reqClass.post(options)]; case 1: res = _a.sent(); return [2, res]; } }); }); }; CloudbaseRequest.prototype.upload = function (options) { return __awaiter(this, void 0, void 0, function () { var res; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.reqClass.upload(options)]; case 1: res = _a.sent(); return [2, res]; } }); }); }; CloudbaseRequest.prototype.download = function (options) { return __awaiter(this, void 0, void 0, function () { var res; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.reqClass.download(options)]; case 1: res = _a.sent(); return [2, res]; } }); }); }; CloudbaseRequest.prototype.getBaseEndPoint = function () { return getBaseEndPoint(this.config.env); }; CloudbaseRequest.prototype.getOauthAccessTokenV2 = function (oauthClient) { return __awaiter(this, void 0, void 0, function () { var validAccessToken, credentials; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, oauthClient.getAccessToken()]; case 1: validAccessToken = _a.sent(); return [4, oauthClient.getCredentials()]; case 2: credentials = _a.sent(); return [2, { accessToken: validAccessToken, accessTokenExpire: new Date(credentials.expires_at).getTime(), }]; } }); }); }; CloudbaseRequest.prototype.request = function (action, params, options) { var _a, _b; return __awaiter(this, void 0, void 0, function () { var tcbTraceKey, contentType, tmpObj, app, oauthInstance, oauthClient, _c, payload, opts, traceHeader, parse, inQuery, search, formatQuery, _d, BASE_URL, PROTOCOL, newUrl, res, resTraceHeader; return __generator(this, function (_e) { switch (_e.label) { case 0: tcbTraceKey = "x-tcb-trace_".concat(this.config.env); contentType = 'application/x-www-form-urlencoded'; tmpObj = __assign({ action: action, dataVersion: DATA_VERSION, env: this.config.env }, params); if (!(ACTIONS_WITHOUT_ACCESSTOKEN.indexOf(action) === -1)) return [3, 2]; app = this.config._fromApp; if (!app.oauthInstance) { throw new Error('you can\'t request without auth'); } oauthInstance = app.oauthInstance; oauthClient = oauthInstance.oauth2client; _c = tmpObj; return [4, this.getOauthAccessTokenV2(oauthClient)]; case 1: _c.access_token = (_e.sent()).accessToken; _e.label = 2; case 2: if (action === 'storage.uploadFile') { payload = new FormData(); Object.keys(payload).forEach(function (key) { if (Object.prototype.hasOwnProperty.call(payload, key) && payload[key] !== undefined) { payload.append(key, tmpObj[key]); } }); contentType = 'multipart/form-data'; } else { contentType = 'application/json;charset=UTF-8'; payload = {}; Object.keys(tmpObj).forEach(function (key) { if (tmpObj[key] !== undefined) { payload[key] = tmpObj[key]; } }); } opts = { headers: { 'content-type': contentType, }, }; if (options === null || options === void 0 ? void 0 : options.onUploadProgress) { opts.onUploadProgress = options.onUploadProgress; } if (this.config.region) { opts.headers['X-TCB-Region'] = this.config.region; } traceHeader = this.localCache.getStore(tcbTraceKey); if (traceHeader) { opts.headers['X-TCB-Trace'] = traceHeader; } parse = (options === null || options === void 0 ? void 0 : options.parse) !== undefined ? options.parse : params.parse; inQuery = (options === null || options === void 0 ? void 0 : options.inQuery) !== undefined ? options.inQuery : params.inQuery; search = (options === null || options === void 0 ? void 0 : options.search) !== undefined ? options.search : params.search; formatQuery = __assign(__assign({}, ((options === null || options === void 0 ? void 0 : options.defaultQuery) || {})), { env: this.config.env }); parse && (formatQuery.parse = true); inQuery && (formatQuery = __assign(__assign({}, inQuery), formatQuery)); _d = getEndPointInfo(this.config.env, 'CLOUD_API'), BASE_URL = _d.baseUrl, PROTOCOL = _d.protocol; if (options.pathname) { newUrl = formatUrl(PROTOCOL, "".concat((_a = getBaseEndPoint(this.config.env)) === null || _a === void 0 ? void 0 : _a.replace(/^https?:/, ''), "/").concat(options.pathname), formatQuery); } else { newUrl = formatUrl(PROTOCOL, BASE_URL, formatQuery); } if (search) { newUrl += search; } return [4, this.post(__assign({ url: newUrl, data: payload }, opts))]; case 3: res = _e.sent(); resTraceHeader = (_b = res.header) === null || _b === void 0 ? void 0 : _b['x-tcb-trace']; if (resTraceHeader) { this.localCache.setStore(tcbTraceKey, resTraceHeader); } if ((Number(res.status) !== 200 && Number(res.statusCode) !== 200) || !res.data) { throw new Error('network request error'); } return [2, res]; } }); }); }; CloudbaseRequest.prototype.fetch = function (options) { var _a, _b, _c, _d, _e, _f, _g, _h; return __awaiter(this, void 0, void 0, function () { var token, _j, headers, restOptions, getAccessToken, doFetch, result, err_1; var _this = this; return __generator(this, function (_k) { switch (_k.label) { case 0: token = options.token, _j = options.headers, headers = _j === void 0 ? {} : _j, restOptions = __rest(options, ["token", "headers"]); getAccessToken = function () { return __awaiter(_this, void 0, void 0, function () { var app, oauthInstance, oauthClient; return __generator(this, function (_a) { switch (_a.label) { case 0: if (token != null) { return [2, token]; } app = this.config._fromApp; if (!app.oauthInstance) { throw new Error('you can\'t request without auth'); } oauthInstance = app.oauthInstance; oauthClient = oauthInstance.oauth2client; return [4, this.getOauthAccessTokenV2(oauthClient)]; case 1: return [2, (_a.sent()).accessToken]; } }); }); }; doFetch = function () { return __awaiter(_this, void 0, void 0, function () { var _a, _b, _c; var _d, _e; return __generator(this, function (_f) { switch (_f.label) { case 0: _b = (_a = this.reqClass).fetch; _d = {}; _e = { 'X-SDK-Version': "@cloudbase/js-sdk/".concat(getSdkVersion()) }; _c = "Bearer ".concat; return [4, getAccessToken()]; case 1: return [2, _b.apply(_a, [__assign.apply(void 0, [(_d.headers = __assign.apply(void 0, [(_e.Authorization = _c.apply("Bearer ", [_f.sent()]), _e), headers]), _d), restOptions])])]; } }); }); }; _k.label = 1; case 1: _k.trys.push([1, 3, , 6]); return [4, doFetch()]; case 2: result = _k.sent(); return [2, result]; case 3: err_1 = _k.sent(); if (!((err_1 === null || err_1 === void 0 ? void 0 : err_1.code) === 'ACCESS_TOKEN_EXPIRED')) return [3, 5]; if (typeof ((_d = (_c = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a._fromApp) === null || _b === void 0 ? void 0 : _b.oauthInstance) === null || _c === void 0 ? void 0 : _c.authApi) === null || _d === void 0 ? void 0 : _d.refreshTokenForce) !== 'function') { throw err_1; } return [4, ((_h = (_g = (_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e._fromApp) === null || _f === void 0 ? void 0 : _f.oauthInstance) === null || _g === void 0 ? void 0 : _g.authApi) === null || _h === void 0 ? void 0 : _h.refreshTokenForce())]; case 4: _k.sent(); return [2, doFetch()]; case 5: throw err_1; case 6: return [2]; } }); }); }; CloudbaseRequest.prototype.send = function (action, data, options) { if (data === void 0) { data = {}; } if (options === void 0) { options = {}; } return __awaiter(this, void 0, void 0, function () { var response; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.request(action, data, __assign(__assign({}, options), { onUploadProgress: data.onUploadProgress }))]; case 1: response = _a.sent(); if (response.data.code && this.throwWhenRequestFail) { throw new Error(JSON.stringify({ code: ERRORS.OPERATION_FAIL, msg: "[".concat(response.data.code, "] ").concat(response.data.message), })); } return [2, response.data]; } }); }); }; return CloudbaseRequest; }()); export { CloudbaseRequest }; var requestMap = {}; export function initRequest(config) { requestMap[config.env] = new CloudbaseRequest(__assign(__assign({}, config), { throw: true })); } export function getRequestByEnvId(env) { return requestMap[env]; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWJzL3JlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQVNuRyxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBU3ZELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDdkMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUM1QixJQUFBLE1BQU0sR0FBSyxTQUFTLE9BQWQsQ0FBYztBQUNwQixJQUFBLFFBQVEsR0FBNEIsS0FBSyxTQUFqQyxFQUFFLFVBQVUsR0FBZ0IsS0FBSyxXQUFyQixFQUFFLFNBQVMsR0FBSyxLQUFLLFVBQVYsQ0FBVTtBQUdqRCxJQUFNLDJCQUEyQixHQUFHO0lBQ2xDLGFBQWE7SUFDYixhQUFhO0lBQ2IsdUJBQXVCO0lBQ3ZCLHdCQUF3QjtJQUN4QixhQUFhO0lBQ2IsdUNBQXVDO0lBQ3ZDLGlDQUFpQztJQUNqQywwQkFBMEI7SUFDMUIsNkJBQTZCO0lBQzdCLDZCQUE2QjtJQUM3QiwyQkFBMkI7Q0FDNUIsQ0FBQTtBQUVELFNBQVMsU0FBUyxDQUFDLFFBQTZCLEVBQUUsSUFBWSxFQUFFLEtBQTJCO0lBQ3pGLElBQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNuQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsVUFBVSxPQUF3QjtRQUNqRCxJQUFNLElBQUksR0FBRyxFQUFFLENBQUE7UUFDZixJQUFNLE9BQU8sR0FBRyxFQUFFLENBQUE7UUFDbEIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFD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O3dCQUFwRyxRQUFRLEdBQUcsU0FBeUY7d0JBRTFHLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLG9CQUFvQixFQUFFOzRCQUNuRCxNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7Z0NBQzdCLElBQUksRUFBRSxNQUFNLENBQUMsY0FBYztnQ0FDM0IsR0FBRyxFQUFFLFdBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUssUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUU7NkJBQ3hELENBQUMsQ0FBRSxDQUFBO3lCQUNMO3dCQUVELFdBQU8sUUFBUSxDQUFDLElBQUksRUFBQTs7OztLQUNyQjtJQUNILHVCQUFDO0FBQUQsQ0FBQyxBQTlPRCxJQThPQzs7QUFFRCxJQUFNLFVBQVUsR0FBeUIsRUFBRSxDQUFBO0FBRTNDLE1BQU0sVUFBVSxXQUFXLENBQUMsTUFBK0I7SUFDekQsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLGdCQUFnQix1QkFDeEMsTUFBTSxLQUNULEtBQUssRUFBRSxJQUFJLElBQ1gsQ0FBQTtBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsR0FBVztJQUMzQyxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUN4QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgREFUQV9WRVJTSU9OLCBnZXRTZGtWZXJzaW9uLCBnZXRCYXNlRW5kUG9pbnQsIGdldEVuZFBvaW50SW5mbyB9IGZyb20gJy4uL2NvbnN0YW50cy9jb21tb24nXG5pbXBvcnQge1xuICBJUmVxdWVzdE9wdGlvbnMsXG4gIFNES1JlcXVlc3RJbnRlcmZhY2UsXG4gIFJlc3BvbnNlT2JqZWN0LFxuICBJVXBsb2FkUmVxdWVzdE9wdGlvbnMsXG4gIElSZXF1ZXN0Q29uZmlnLFxuICBJRmV0Y2hPcHRpb25zLFxufSBmcm9tICdAY2xvdWRiYXNlL2FkYXB0ZXItaW50ZXJmYWNlJ1xuaW1wb3J0IHsgdXRpbHMsIGNvbnN0YW50cyB9IGZyb20gJ0BjbG91ZGJhc2UvdXRpbGl0aWVzJ1xuaW1wb3J0IHsgS1YgfSBmcm9tICdAY2xvdWRiYXNlL3R5cGVzJ1xuaW1wb3J0IHtcbiAgSUdldEFjY2Vzc1Rva2VuUmVzdWx0LFxuICBJQ2xvdWRiYXNlUmVxdWVzdENvbmZpZyxcbiAgSUFwcGVuZGVkUmVxdWVzdEluZm8sXG4gIElSZXF1ZXN0QmVmb3JlSG9vayxcbn0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcy9yZXF1ZXN0J1xuaW1wb3J0IHsgSUNsb3VkYmFzZUNhY2hlIH0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcy9jYWNoZSdcbmltcG9ydCB7IGdldExvY2FsQ2FjaGUgfSBmcm9tICcuL2NhY2hlJ1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICcuL2FkYXB0ZXInXG5jb25zdCB7IEVSUk9SUyB9ID0gY29uc3RhbnRzXG5jb25zdCB7IGdlblNlcUlkLCBpc0Zvcm1EYXRhLCBmb3JtYXRVcmwgfSA9IHV0aWxzXG5cbi8vIOS4i+mdouWHoOenjSBhY3Rpb24g5LiN6ZyA6KaBIGFjY2VzcyB0b2tlblxuY29uc3QgQUNUSU9OU19XSVRIT1VUX0FDQ0VTU1RPS0VOID0gW1xuICAnYXV0aC5nZXRKd3QnLFxuICAnYXV0aC5sb2dvdXQnLFxuICAnYXV0aC5zaWduSW5XaXRoVGlja2V0JyxcbiAgJ2F1dGguc2lnbkluQW5vbnltb3VzbHknLFxuICAnYXV0aC5zaWduSW4nLFxuICAnYXV0aC5mZXRjaEFjY2Vzc1Rva2VuV2l0aFJlZnJlc2hUb2tlbicsXG4gICdhdXRoLnNpZ25VcFdpdGhFbWFpbEFuZFBhc3N3b3JkJyxcbiAgJ2F1dGguYWN0aXZhdGVFbmRVc2VyTWFpbCcsXG4gICdhdXRoLnNlbmRQYXNzd29yZFJlc2V0RW1haWwnLFxuICAnYXV0aC5yZXNldFBhc3N3b3JkV2l0aFRva2VuJyxcbiAgJ2F1dGguaXNVc2VybmFtZVJlZ2lzdGVyZWQnLFxuXVxuXG5mdW5jdGlvbiBiaW5kSG9va3MoaW5zdGFuY2U6IFNES1JlcXVlc3RJbnRlcmZhY2UsIG5hbWU6IHN0cmluZywgaG9va3M6IElSZXF1ZXN0QmVmb3JlSG9va1tdKSB7XG4gIGNvbnN0IG9yaWdpbk1ldGhvZCA9IGluc3RhbmNlW25hbWVdXG4gIGluc3RhbmNlW25hbWVdID0gZnVuY3Rpb24gKG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucykge1xuICAgIGNvbnN0IGRhdGEgPSB7fVxuICAgIGNvbnN0IGhlYWRlcnMgPSB7fVxuICAgIGhvb2tzLmZvckVhY2goKGhvb2spID0+IHtcbiAgICAgIGNvbnN0IHsgZGF0YTogYXBwZW5kZWREYXRhLCBoZWFkZXJzOiBhcHBlbmRlZEhlYWRlcnMgfSA9IGhvb2suY2FsbChpbnN0YW5jZSwgb3B0aW9ucylcbiAgICAgIE9iamVjdC5hc3NpZ24oZGF0YSwgYXBwZW5kZWREYXRhKVxuICAgICAgT2JqZWN0LmFzc2lnbihoZWFkZXJzLCBhcHBlbmRlZEhlYWRlcnMpXG4gICAgfSlcbiAgICBjb25zdCBvcmlnaW5EYXRhID0gb3B0aW9ucy5kYXRhXG4gICAgb3JpZ2luRGF0YVxuICAgICAgJiYgKCgpID0+IHtcbiAgICAgICAgaWYgKGlzRm9ybURhdGEob3JpZ2luRGF0YSkpIHtcbiAgICAgICAgICBPYmplY3Qua2V5cyhkYXRhKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgIChvcmlnaW5EYXRhIGFzIEZvcm1EYXRhKS5hcHBlbmQoa2V5LCBkYXRhW2tleV0pXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLmRhdGEgPSB7XG4gICAgICAgICAgLi4ub3JpZ2luRGF0YSxcbiAgICAgICAgICAuLi5kYXRhLFxuICAgICAgICB9XG4gICAgICB9KSgpXG4gICAgb3B0aW9ucy5oZWFkZXJzID0ge1xuICAgICAgLi4uKG9wdGlvbnMuaGVhZGVycyB8fCB7fSksXG4gICAgICAuLi5oZWFkZXJzLFxuICAgIH1cbiAgICByZXR1cm4gKG9yaWdpbk1ldGhvZCBhcyBGdW5jdGlvbikuY2FsbChpbnN0YW5jZSwgb3B0aW9ucylcbiAgfVxufVxuZnVuY3Rpb24gYmVmb3JlRWFjaCgpOiBJQXBwZW5kZWRSZXF1ZXN0SW5mbyB7XG4gIGNvbnN0IHNlcUlkID0gZ2VuU2VxSWQoKVxuICByZXR1cm4ge1xuICAgIGRhdGE6IHtcbiAgICAgIHNlcUlkLFxuICAgIH0sXG4gICAgaGVhZGVyczoge1xuICAgICAgJ1gtU0RLLVZlcnNpb24nOiBgQGNsb3VkYmFzZS9qcy1zZGsvJHtnZXRTZGtWZXJzaW9uKCl9YCxcbiAgICAgICd4LXNlcWlkJzogc2VxSWQsXG4gICAgfSxcbiAgfVxufVxuZXhwb3J0IGludGVyZmFjZSBJQ2xvdWRiYXNlUmVxdWVzdCB7XG4gIHBvc3Q6IChvcHRpb25zOiBJUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHVwbG9hZDogKG9wdGlvbnM6IElVcGxvYWRSZXF1ZXN0T3B0aW9ucykgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbiAgZG93bmxvYWQ6IChvcHRpb25zOiBJUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHJlcXVlc3Q6IChhY3Rpb246IHN0cmluZywgcGFyYW1zOiBLVjxhbnk+LCBvcHRpb25zPzogS1Y8YW55PikgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbiAgc2VuZDogKGFjdGlvbjogc3RyaW5nLCBkYXRhOiBLVjxhbnk+KSA9PiBQcm9taXNlPGFueT5cbiAgZmV0Y2g6IChvcHRpb25zOiBJRmV0Y2hPcHRpb25zKSA9PiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PlxufVxuXG4vKipcbiAqIEBjbGFzcyBDbG91ZGJhc2VSZXF1ZXN0XG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZGJhc2VSZXF1ZXN0IGltcGxlbWVudHMgSUNsb3VkYmFzZVJlcXVlc3Qge1xuICBjb25maWc6IElDbG91ZGJhc2VSZXF1ZXN0Q29uZmlnXG4gIHByaXZhdGUgcmVxQ2xhc3M6IFNES1JlcXVlc3RJbnRlcmZhY2VcbiAgLy8g6K+35rGC5aSx6LSl5piv5ZCm5oqb5Ye6RXJyb3JcbiAgcHJpdmF0ZSB0aHJvd1doZW5SZXF1ZXN0RmFpbCA9IGZhbHNlXG4gIC8vIOaMgeS5heWMluacrOWcsOWtmOWCqFxuICBwcml2YXRlIGxvY2FsQ2FjaGU6IElDbG91ZGJhc2VDYWNoZVxuICAvKipcbiAgICog5Yid5aeL5YyWXG4gICAqIEBwYXJhbSBjb25maWdcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogSUNsb3VkYmFzZVJlcXVlc3RDb25maWcgJiB7IHRocm93PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWdcbiAgICBjb25zdCByZXFDb25maWc6IElSZXF1ZXN0Q29uZmlnID0ge1xuICAgICAgdGltZW91dDogdGhpcy5jb25maWcudGltZW91dCxcbiAgICAgIHRpbWVvdXRNc2c6IGBbQGNsb3VkYmFzZS9qcy1zZGtdIOivt+axguWcqCR7dGhpcy5jb25maWcudGltZW91dCAvIDEwMDB9c+WGheacquWujOaIkO+8jOW3suS4reaWrWAsXG4gICAgICByZXN0cmljdGVkTWV0aG9kczogWydwb3N0JywgJ3B1dCddLFxuICAgIH1cbiAgICB0aGlzLnJlcUNsYXNzID0gbmV3IFBsYXRmb3JtLmFkYXB0ZXIucmVxQ2xhc3MocmVxQ29uZmlnKVxuICAgIHRoaXMudGhyb3dXaGVuUmVxdWVzdEZhaWwgPSBjb25maWcudGhyb3cgfHwgZmFsc2VcbiAgICB0aGlzLmxvY2FsQ2FjaGUgPSBnZXRMb2NhbENhY2hlKHRoaXMuY29uZmlnLmVudilcbiAgICBiaW5kSG9va3ModGhpcy5yZXFDbGFzcywgJ3Bvc3QnLCBbYmVmb3JlRWFjaF0pXG4gICAgYmluZEhvb2tzKHRoaXMucmVxQ2xhc3MsICd1cGxvYWQnLCBbYmVmb3JlRWFjaF0pXG4gICAgYmluZEhvb2tzKHRoaXMucmVxQ2xhc3MsICdkb3dubG9hZCcsIFtiZWZvcmVFYWNoXSlcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwb3N0KG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnJlcUNsYXNzLnBvc3Qob3B0aW9ucylcbiAgICByZXR1cm4gcmVzXG4gIH1cbiAgcHVibGljIGFzeW5jIHVwbG9hZChvcHRpb25zOiBJVXBsb2FkUmVxdWVzdE9wdGlvbnMpOiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5yZXFDbGFzcy51cGxvYWQob3B0aW9ucylcbiAgICByZXR1cm4gcmVzXG4gIH1cbiAgcHVibGljIGFzeW5jIGRvd25sb2FkKG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnJlcUNsYXNzLmRvd25sb2FkKG9wdGlvbnMpXG4gICAgcmV0dXJuIHJlc1xuICB9XG5cbiAgcHVibGljIGdldEJhc2VFbmRQb2ludCgpIHtcbiAgICByZXR1cm4gZ2V0QmFzZUVuZFBvaW50KHRoaXMuY29uZmlnLmVudilcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRPYXV0aEFjY2Vzc1Rva2VuVjIob2F1dGhDbGllbnQ6IGFueSk6IFByb21pc2U8SUdldEFjY2Vzc1Rva2VuUmVzdWx0PiB7XG4gICAgY29uc3QgdmFsaWRBY2Nlc3NUb2tlbiA9IGF3YWl0IG9hdXRoQ2xpZW50LmdldEFjY2Vzc1Rva2VuKClcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IGF3YWl0IG9hdXRoQ2xpZW50LmdldENyZWRlbnRpYWxzKClcbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzVG9rZW46IHZhbGlkQWNjZXNzVG9rZW4sXG4gICAgICBhY2Nlc3NUb2tlbkV4cGlyZTogbmV3IERhdGUoY3JlZGVudGlhbHMuZXhwaXJlc19hdCkuZ2V0VGltZSgpLFxuICAgIH1cbiAgfVxuXG4gIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbiAgcHVibGljIGFzeW5jIHJlcXVlc3QoXG4gICAgYWN0aW9uOiBzdHJpbmcsXG4gICAgcGFyYW1zOiBLVjxhbnk+LFxuICAgIG9wdGlvbnM/OiB7XG4gICAgICBvblVwbG9hZFByb2dyZXNzPzogRnVuY3Rpb25cbiAgICAgIHBhdGhuYW1lPzogc3RyaW5nXG4gICAgICBwYXJzZT86IGJvb2xlYW5cbiAgICAgIGluUXVlcnk/OiBLVjxhbnk+XG4gICAgICBzZWFyY2g/OiBzdHJpbmdcbiAgICAgIGRlZmF1bHRRdWVyeT86IEtWPGFueT5cbiAgICB9LFxuICApOiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PiB7XG4gICAgY29uc3QgdGNiVHJhY2VLZXkgPSBgeC10Y2ItdHJhY2VfJHt0aGlzLmNvbmZpZy5lbnZ9YFxuICAgIGxldCBjb250ZW50VHlwZSA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG5cbiAgICBjb25zdCB0bXBPYmo6IEtWPGFueT4gPSB7XG4gICAgICBhY3Rpb24sXG4gICAgICBkYXRhVmVyc2lvbjogREFUQV9WRVJTSU9OLFxuICAgICAgZW52OiB0aGlzLmNvbmZpZy5lbnYsXG4gICAgICAuLi5wYXJhbXMsXG4gICAgfVxuXG4gICAgaWYgKEFDVElPTlNfV0lUSE9VVF9BQ0NFU1NUT0tFTi5pbmRleE9mKGFjdGlvbikgPT09IC0xKSB7XG4gICAgICBjb25zdCBhcHAgPSB0aGlzLmNvbmZpZy5fZnJvbUFwcFxuXG4gICAgICBpZiAoIWFwcC5vYXV0aEluc3RhbmNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigneW91IGNhblxcJ3QgcmVxdWVzdCB3aXRob3V0IGF1dGgnKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IG9hdXRoSW5zdGFuY2UgfSA9IGFwcFxuICAgICAgY29uc3Qgb2F1dGhDbGllbnQgPSBvYXV0aEluc3RhbmNlLm9hdXRoMmNsaWVudFxuICAgICAgdG1wT2JqLmFjY2Vzc190b2tlbiA9IChhd2FpdCB0aGlzLmdldE9hdXRoQWNjZXNzVG9rZW5WMihvYXV0aENsaWVudCkpLmFjY2Vzc1Rva2VuXG4gICAgfVxuXG4gICAgLy8g5ou8Ym9keeWSjGNvbnRlbnQtdHlwZVxuICAgIGxldCBwYXlsb2FkXG4gICAgaWYgKGFjdGlvbiA9PT0gJ3N0b3JhZ2UudXBsb2FkRmlsZScpIHtcbiAgICAgIHBheWxvYWQgPSBuZXcgRm9ybURhdGEoKVxuICAgICAgT2JqZWN0LmtleXMocGF5bG9hZCkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGF5bG9hZCwga2V5KSAmJiBwYXlsb2FkW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHBheWxvYWQuYXBwZW5kKGtleSwgdG1wT2JqW2tleV0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBjb250ZW50VHlwZSA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJ1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50VHlwZSA9ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9VVRGLTgnXG4gICAgICBwYXlsb2FkID0ge31cbiAgICAgIE9iamVjdC5rZXlzKHRtcE9iaikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmICh0bXBPYmpba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGF5bG9hZFtrZXldID0gdG1wT2JqW2tleV1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gICAgY29uc3Qgb3B0czogYW55ID0ge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnY29udGVudC10eXBlJzogY29udGVudFR5cGUsXG4gICAgICB9LFxuICAgIH1cbiAgICBpZiAob3B0aW9ucz8ub25VcGxvYWRQcm9ncmVzcykge1xuICAgICAgb3B0cy5vblVwbG9hZFByb2dyZXNzID0gb3B0aW9ucy5vblVwbG9hZFByb2dyZXNzXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLnJlZ2lvbikge1xuICAgICAgb3B0cy5oZWFkZXJzWydYLVRDQi1SZWdpb24nXSA9IHRoaXMuY29uZmlnLnJlZ2lvblxuICAgIH1cblxuICAgIGNvbnN0IHRyYWNlSGVhZGVyID0gdGhpcy5sb2NhbENhY2hlLmdldFN0b3JlKHRjYlRyYWNlS2V5KVxuICAgIGlmICh0cmFjZUhlYWRlcikge1xuICAgICAgb3B0cy5oZWFkZXJzWydYLVRDQi1UcmFjZSddID0gdHJhY2VIZWFkZXJcbiAgICB9XG5cbiAgICAvLyDlj5Hlh7ror7fmsYJcbiAgICAvLyDmlrDnmoQgdXJsIOmcgOimgeaQuuW4piBlbnYg5Y+C5pWw6L+b6KGMIENPUlMg5qCh6aqMXG4gICAgLy8g6K+35rGC6ZO+5o6l5pSv5oyB5re75Yqg5Yqo5oCBIHF1ZXJ5IOWPguaVsO+8jOaWueS+v+eUqOaIt+iwg+ivleWumuS9jeivt+axglxuICAgIGNvbnN0IHBhcnNlID0gb3B0aW9ucz8ucGFyc2UgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGFyc2UgOiBwYXJhbXMucGFyc2VcbiAgICBjb25zdCBpblF1ZXJ5ID0gb3B0aW9ucz8uaW5RdWVyeSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5pblF1ZXJ5IDogcGFyYW1zLmluUXVlcnlcbiAgICBjb25zdCBzZWFyY2ggPSBvcHRpb25zPy5zZWFyY2ggIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc2VhcmNoIDogcGFyYW1zLnNlYXJjaFxuXG4gICAgbGV0IGZvcm1hdFF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge1xuICAgICAgLi4uKG9wdGlvbnM/LmRlZmF1bHRRdWVyeSB8fCB7fSksXG4gICAgICBlbnY6IHRoaXMuY29uZmlnLmVudixcbiAgICB9XG4gICAgLy8g5bCd6K+V6Kej5p6Q5ZON5bqU5pWw5o2u5Li6IEpTT05cbiAgICBwYXJzZSAmJiAoZm9ybWF0UXVlcnkucGFyc2UgPSB0cnVlKVxuICAgIGluUXVlcnlcbiAgICAgICYmIChmb3JtYXRRdWVyeSA9IHtcbiAgICAgICAgLi4uaW5RdWVyeSxcbiAgICAgICAgLi4uZm9ybWF0UXVlcnksXG4gICAgICB9KVxuXG4gICAgY29uc3QgeyBiYXNlVXJsOiBCQVNFX1VSTCwgcHJvdG9jb2w6IFBST1RPQ09MIH0gPSBnZXRFbmRQb2ludEluZm8odGhpcy5jb25maWcuZW52LCAnQ0xPVURfQVBJJylcbiAgICAvLyDnlJ/miJDor7fmsYIgdXJsXG4gICAgbGV0IG5ld1VybFxuICAgIGlmIChvcHRpb25zLnBhdGhuYW1lKSB7XG4gICAgICBuZXdVcmwgPSBmb3JtYXRVcmwoXG4gICAgICAgIFBST1RPQ09MLFxuICAgICAgICBgJHtnZXRCYXNlRW5kUG9pbnQodGhpcy5jb25maWcuZW52KT8ucmVwbGFjZSgvXmh0dHBzPzovLCAnJyl9LyR7b3B0aW9ucy5wYXRobmFtZX1gLFxuICAgICAgICBmb3JtYXRRdWVyeSxcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3VXJsID0gZm9ybWF0VXJsKFBST1RPQ09MLCBCQVNFX1VSTCwgZm9ybWF0UXVlcnkpXG4gICAgfVxuXG4gICAgaWYgKHNlYXJjaCkge1xuICAgICAgbmV3VXJsICs9IHNlYXJjaFxuICAgIH1cblxuICAgIGNvbnN0IHJlczogUmVzcG9uc2VPYmplY3QgPSBhd2FpdCB0aGlzLnBvc3Qoe1xuICAgICAgdXJsOiBuZXdVcmwsXG4gICAgICBkYXRhOiBwYXlsb2FkLFxuICAgICAgLi4ub3B0cyxcbiAgICB9KVxuXG4gICAgLy8g5L+d5a2YIHRyYWNlIGhlYWRlclxuICAgIGNvbnN0IHJlc1RyYWNlSGVhZGVyID0gcmVzLmhlYWRlcj8uWyd4LXRjYi10cmFjZSddXG4gICAgaWYgKHJlc1RyYWNlSGVhZGVyKSB7XG4gICAgICB0aGlzLmxvY2FsQ2FjaGUuc2V0U3RvcmUodGNiVHJhY2VLZXksIHJlc1RyYWNlSGVhZGVyKVxuICAgIH1cblxuICAgIGlmICgoTnVtYmVyKHJlcy5zdGF0dXMpICE9PSAyMDAgJiYgTnVtYmVyKHJlcy5zdGF0dXNDb2RlKSAhPT0gMjAwKSB8fCAhcmVzLmRhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbmV0d29yayByZXF1ZXN0IGVycm9yJylcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzXG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZmV0Y2gob3B0aW9uczogSUZldGNoT3B0aW9ucyAmIHsgdG9rZW4/OiBzdHJpbmcgfSk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCB7IHRva2VuLCBoZWFkZXJzID0ge30sIC4uLnJlc3RPcHRpb25zIH0gPSBvcHRpb25zXG4gICAgY29uc3QgZ2V0QWNjZXNzVG9rZW4gPSBhc3luYyAoKSA9PiB7XG4gICAgICBpZiAodG9rZW4gIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdG9rZW5cbiAgICAgIH1cbiAgICAgIGNvbnN0IGFwcCA9IHRoaXMuY29uZmlnLl9mcm9tQXBwXG5cbiAgICAgIGlmICghYXBwLm9hdXRoSW5zdGFuY2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd5b3UgY2FuXFwndCByZXF1ZXN0IHdpdGhvdXQgYXV0aCcpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgb2F1dGhJbnN0YW5jZSB9ID0gYXBwXG4gICAgICBjb25zdCBvYXV0aENsaWVudCA9IG9hdXRoSW5zdGFuY2Uub2F1dGgyY2xpZW50XG4gICAgICByZXR1cm4gKGF3YWl0IHRoaXMuZ2V0T2F1dGhBY2Nlc3NUb2tlblYyKG9hdXRoQ2xpZW50KSkuYWNjZXNzVG9rZW5cbiAgICB9XG5cbiAgICBjb25zdCBkb0ZldGNoID0gYXN5bmMgKCkgPT4gdGhpcy5yZXFDbGFzcy5mZXRjaCh7XG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIC8vICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIC8vICdYLVJlcXVlc3QtSWQnOiBgJHt1dGlscy5nZW5lcmF0ZVJlcXVlc3RJZCgpfWAsXG4gICAgICAgIC8vICdYLVJlcXVlc3QtVGltZXN0YW1wJzogYCR7RGF0ZS5ub3coKX1gLFxuICAgICAgICAnWC1TREstVmVyc2lvbic6IGBAY2xvdWRiYXNlL2pzLXNkay8ke2dldFNka1ZlcnNpb24oKX1gLFxuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YXdhaXQgZ2V0QWNjZXNzVG9rZW4oKX1gLFxuICAgICAgICAuLi5oZWFkZXJzLFxuICAgICAgfSxcbiAgICAgIC4uLnJlc3RPcHRpb25zLFxuICAgIH0pXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZG9GZXRjaCgpXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyPy5jb2RlID09PSAnQUNDRVNTX1RPS0VOX0VYUElSRUQnKSB7XG4gICAgICAgIC8vIOWmguaenOaYr+WboOS4uiB0b2tlbiDov4fmnJ/lpLHotKXvvIzliLcgdG9rZW4g5ZCO5YaN6K+V5LiA5qyhXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWc/Ll9mcm9tQXBwPy5vYXV0aEluc3RhbmNlPy5hdXRoQXBpPy5yZWZyZXNoVG9rZW5Gb3JjZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRocm93IGVyclxuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuY29uZmlnPy5fZnJvbUFwcD8ub2F1dGhJbnN0YW5jZT8uYXV0aEFwaT8ucmVmcmVzaFRva2VuRm9yY2UoKVxuICAgICAgICByZXR1cm4gZG9GZXRjaCgpXG4gICAgICB9XG4gICAgICAvLyDlhbbku5bljp/lm6DlkJHkuIrmipvlh7pcblxuICAgICAgdGhyb3cgZXJyXG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHNlbmQoYWN0aW9uOiBzdHJpbmcsIGRhdGE6IEtWPGFueT4gPSB7fSwgb3B0aW9uczogS1Y8YW55PiA9IHt9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdChhY3Rpb24sIGRhdGEsIHsgLi4ub3B0aW9ucywgb25VcGxvYWRQcm9ncmVzczogZGF0YS5vblVwbG9hZFByb2dyZXNzIH0pXG5cbiAgICBpZiAocmVzcG9uc2UuZGF0YS5jb2RlICYmIHRoaXMudGhyb3dXaGVuUmVxdWVzdEZhaWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGNvZGU6IEVSUk9SUy5PUEVSQVRJT05fRkFJTCxcbiAgICAgICAgbXNnOiBgWyR7cmVzcG9uc2UuZGF0YS5jb2RlfV0gJHtyZXNwb25zZS5kYXRhLm1lc3NhZ2V9YCxcbiAgICAgIH0pLClcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YVxuICB9XG59XG5cbmNvbnN0IHJlcXVlc3RNYXA6IEtWPENsb3VkYmFzZVJlcXVlc3Q+ID0ge31cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRSZXF1ZXN0KGNvbmZpZzogSUNsb3VkYmFzZVJlcXVlc3RDb25maWcpIHtcbiAgcmVxdWVzdE1hcFtjb25maWcuZW52XSA9IG5ldyBDbG91ZGJhc2VSZXF1ZXN0KHtcbiAgICAuLi5jb25maWcsXG4gICAgdGhyb3c6IHRydWUsXG4gIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0QnlFbnZJZChlbnY6IHN0cmluZyk6IENsb3VkYmFzZVJlcXVlc3Qge1xuICByZXR1cm4gcmVxdWVzdE1hcFtlbnZdXG59XG4iXX0=