UNPKG

@cloudbase/app

Version:
386 lines 48.1 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, langEvent } 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) { var _this = this; 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]); langEvent.bus.on(langEvent.LANG_CHANGE_EVENT, function (params) { var _a; _this.config.i18n = ((_a = params.data) === null || _a === void 0 ? void 0 : _a.i18n) || _this.config.i18n; }); } CloudbaseRequest.prototype.getDefaultHeaders = function () { var _a; var _b, _c; return _a = {}, _a[(_b = this.config.i18n) === null || _b === void 0 ? void 0 : _b.LANG_HEADER_KEY] = (_c = this.config.i18n) === null || _c === void 0 ? void 0 : _c.lang, _a; }; 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(__assign(__assign({}, options), { headers: __assign(__assign({}, options.headers), this.getDefaultHeaders()) }))]; 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(__assign(__assign({}, options), { headers: __assign(__assign({}, options.headers), this.getDefaultHeaders()) }))]; 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(__assign(__assign({}, options), { headers: __assign(__assign({}, options.headers), this.getDefaultHeaders()) }))]; case 1: res = _a.sent(); return [2, res]; } }); }); }; CloudbaseRequest.prototype.getBaseEndPoint = function (endPointKey) { if (endPointKey === void 0) { endPointKey = 'CLOUD_API'; } return getBaseEndPoint(this.config.env, endPointKey); }; 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: __assign({ 'content-type': contentType }, this.getDefaultHeaders()), }; 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, [__assign.apply(void 0, [(_e.Authorization = _c.apply("Bearer ", [_f.sent()]), _e), this.getDefaultHeaders()]), 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWJzL3JlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQVNuRyxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQVNsRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDNUIsSUFBQSxNQUFNLEdBQUssU0FBUyxPQUFkLENBQWM7QUFDcEIsSUFBQSxRQUFRLEdBQTRCLEtBQUssU0FBakMsRUFBRSxVQUFVLEdBQWdCLEtBQUssV0FBckIsRUFBRSxTQUFTLEdBQUssS0FBSyxVQUFWLENBQVU7QUFHakQsSUFBTSwyQkFBMkIsR0FBRztJQUNsQyxhQUFhO0lBQ2IsYUFBYTtJQUNiLHVCQUF1QjtJQUN2Qix3QkFBd0I7SUFDeEIsYUFBYTtJQUNiLHVDQUF1QztJQUN2QyxpQ0FBaUM7SUFDakMsMEJBQTBCO0lBQzFCLDZCQUE2QjtJQUM3Qiw2QkFBNkI7SUFDN0IsMkJBQTJCO0NBQzVCLENBQUE7QUFFRCxTQUFTLFNBQVMsQ0FBQyxRQUE2QixFQUFFLElBQVksRUFBRSxLQUEyQjtJQUN6RixJQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDbkMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsT0FBd0I7UUFDakQsSUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQ2YsSUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFBO1FBQ2xCLEtBQUssQ0FBQyxPQUFP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QTt5QkFDTDt3QkFFRCxXQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUE7Ozs7S0FDckI7SUFDSCx1QkFBQztBQUFELENBQUMsQUF4UEQsSUF3UEM7O0FBRUQsSUFBTSxVQUFVLEdBQXlCLEVBQUUsQ0FBQTtBQUUzQyxNQUFNLFVBQVUsV0FBVyxDQUFDLE1BQStCO0lBQ3pELFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxnQkFBZ0IsdUJBQ3hDLE1BQU0sS0FDVCxLQUFLLEVBQUUsSUFBSSxJQUNYLENBQUE7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEdBQVc7SUFDM0MsT0FBTyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUE7QUFDeEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERBVEFfVkVSU0lPTiwgZ2V0U2RrVmVyc2lvbiwgZ2V0QmFzZUVuZFBvaW50LCBnZXRFbmRQb2ludEluZm8gfSBmcm9tICcuLi9jb25zdGFudHMvY29tbW9uJ1xuaW1wb3J0IHtcbiAgSVJlcXVlc3RPcHRpb25zLFxuICBTREtSZXF1ZXN0SW50ZXJmYWNlLFxuICBSZXNwb25zZU9iamVjdCxcbiAgSVVwbG9hZFJlcXVlc3RPcHRpb25zLFxuICBJUmVxdWVzdENvbmZpZyxcbiAgSUZldGNoT3B0aW9ucyxcbn0gZnJvbSAnQGNsb3VkYmFzZS9hZGFwdGVyLWludGVyZmFjZSdcbmltcG9ydCB7IHV0aWxzLCBjb25zdGFudHMsIGxhbmdFdmVudCB9IGZyb20gJ0BjbG91ZGJhc2UvdXRpbGl0aWVzJ1xuaW1wb3J0IHsgRW5kUG9pbnRLZXksIEtWIH0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcydcbmltcG9ydCB7XG4gIElHZXRBY2Nlc3NUb2tlblJlc3VsdCxcbiAgSUNsb3VkYmFzZVJlcXVlc3RDb25maWcsXG4gIElBcHBlbmRlZFJlcXVlc3RJbmZvLFxuICBJUmVxdWVzdEJlZm9yZUhvb2ssXG59IGZyb20gJ0BjbG91ZGJhc2UvdHlwZXMvcmVxdWVzdCdcbmltcG9ydCB7IElDbG91ZGJhc2VDYWNoZSB9IGZyb20gJ0BjbG91ZGJhc2UvdHlwZXMvY2FjaGUnXG5pbXBvcnQgeyBnZXRMb2NhbENhY2hlIH0gZnJvbSAnLi9jYWNoZSdcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnLi9hZGFwdGVyJ1xuY29uc3QgeyBFUlJPUlMgfSA9IGNvbnN0YW50c1xuY29uc3QgeyBnZW5TZXFJZCwgaXNGb3JtRGF0YSwgZm9ybWF0VXJsIH0gPSB1dGlsc1xuXG4vLyDkuIvpnaLlh6Dnp40gYWN0aW9uIOS4jemcgOimgSBhY2Nlc3MgdG9rZW5cbmNvbnN0IEFDVElPTlNfV0lUSE9VVF9BQ0NFU1NUT0tFTiA9IFtcbiAgJ2F1dGguZ2V0Snd0JyxcbiAgJ2F1dGgubG9nb3V0JyxcbiAgJ2F1dGguc2lnbkluV2l0aFRpY2tldCcsXG4gICdhdXRoLnNpZ25JbkFub255bW91c2x5JyxcbiAgJ2F1dGguc2lnbkluJyxcbiAgJ2F1dGguZmV0Y2hBY2Nlc3NUb2tlbldpdGhSZWZyZXNoVG9rZW4nLFxuICAnYXV0aC5zaWduVXBXaXRoRW1haWxBbmRQYXNzd29yZCcsXG4gICdhdXRoLmFjdGl2YXRlRW5kVXNlck1haWwnLFxuICAnYXV0aC5zZW5kUGFzc3dvcmRSZXNldEVtYWlsJyxcbiAgJ2F1dGgucmVzZXRQYXNzd29yZFdpdGhUb2tlbicsXG4gICdhdXRoLmlzVXNlcm5hbWVSZWdpc3RlcmVkJyxcbl1cblxuZnVuY3Rpb24gYmluZEhvb2tzKGluc3RhbmNlOiBTREtSZXF1ZXN0SW50ZXJmYWNlLCBuYW1lOiBzdHJpbmcsIGhvb2tzOiBJUmVxdWVzdEJlZm9yZUhvb2tbXSkge1xuICBjb25zdCBvcmlnaW5NZXRob2QgPSBpbnN0YW5jZVtuYW1lXVxuICBpbnN0YW5jZVtuYW1lXSA9IGZ1bmN0aW9uIChvcHRpb25zOiBJUmVxdWVzdE9wdGlvbnMpIHtcbiAgICBjb25zdCBkYXRhID0ge31cbiAgICBjb25zdCBoZWFkZXJzID0ge31cbiAgICBob29rcy5mb3JFYWNoKChob29rKSA9PiB7XG4gICAgICBjb25zdCB7IGRhdGE6IGFwcGVuZGVkRGF0YSwgaGVhZGVyczogYXBwZW5kZWRIZWFkZXJzIH0gPSBob29rLmNhbGwoaW5zdGFuY2UsIG9wdGlvbnMpXG4gICAgICBPYmplY3QuYXNzaWduKGRhdGEsIGFwcGVuZGVkRGF0YSlcbiAgICAgIE9iamVjdC5hc3NpZ24oaGVhZGVycywgYXBwZW5kZWRIZWFkZXJzKVxuICAgIH0pXG4gICAgY29uc3Qgb3JpZ2luRGF0YSA9IG9wdGlvbnMuZGF0YVxuICAgIG9yaWdpbkRhdGFcbiAgICAgICYmICgoKSA9PiB7XG4gICAgICAgIGlmIChpc0Zvcm1EYXRhKG9yaWdpbkRhdGEpKSB7XG4gICAgICAgICAgT2JqZWN0LmtleXMoZGF0YSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICAob3JpZ2luRGF0YSBhcyBGb3JtRGF0YSkuYXBwZW5kKGtleSwgZGF0YVtrZXldKVxuICAgICAgICAgIH0pXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5kYXRhID0ge1xuICAgICAgICAgIC4uLm9yaWdpbkRhdGEsXG4gICAgICAgICAgLi4uZGF0YSxcbiAgICAgICAgfVxuICAgICAgfSkoKVxuICAgIG9wdGlvbnMuaGVhZGVycyA9IHtcbiAgICAgIC4uLihvcHRpb25zLmhlYWRlcnMgfHwge30pLFxuICAgICAgLi4uaGVhZGVycyxcbiAgICB9XG4gICAgcmV0dXJuIChvcmlnaW5NZXRob2QgYXMgRnVuY3Rpb24pLmNhbGwoaW5zdGFuY2UsIG9wdGlvbnMpXG4gIH1cbn1cbmZ1bmN0aW9uIGJlZm9yZUVhY2goKTogSUFwcGVuZGVkUmVxdWVzdEluZm8ge1xuICBjb25zdCBzZXFJZCA9IGdlblNlcUlkKClcbiAgcmV0dXJuIHtcbiAgICBkYXRhOiB7XG4gICAgICBzZXFJZCxcbiAgICB9LFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdYLVNESy1WZXJzaW9uJzogYEBjbG91ZGJhc2UvanMtc2RrLyR7Z2V0U2RrVmVyc2lvbigpfWAsXG4gICAgICAneC1zZXFpZCc6IHNlcUlkLFxuICAgIH0sXG4gIH1cbn1cbmV4cG9ydCBpbnRlcmZhY2UgSUNsb3VkYmFzZVJlcXVlc3Qge1xuICBwb3N0OiAob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKSA9PiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PlxuICB1cGxvYWQ6IChvcHRpb25zOiBJVXBsb2FkUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIGRvd25sb2FkOiAob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKSA9PiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PlxuICByZXF1ZXN0OiAoYWN0aW9uOiBzdHJpbmcsIHBhcmFtczogS1Y8YW55Piwgb3B0aW9ucz86IEtWPGFueT4pID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHNlbmQ6IChhY3Rpb246IHN0cmluZywgZGF0YTogS1Y8YW55PikgPT4gUHJvbWlzZTxhbnk+XG4gIGZldGNoOiAob3B0aW9uczogSUZldGNoT3B0aW9ucykgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbn1cblxuLyoqXG4gKiBAY2xhc3MgQ2xvdWRiYXNlUmVxdWVzdFxuICovXG5leHBvcnQgY2xhc3MgQ2xvdWRiYXNlUmVxdWVzdCBpbXBsZW1lbnRzIElDbG91ZGJhc2VSZXF1ZXN0IHtcbiAgY29uZmlnOiBJQ2xvdWRiYXNlUmVxdWVzdENvbmZpZ1xuICBwcml2YXRlIHJlcUNsYXNzOiBTREtSZXF1ZXN0SW50ZXJmYWNlXG4gIC8vIOivt+axguWksei0peaYr+WQpuaKm+WHukVycm9yXG4gIHByaXZhdGUgdGhyb3dXaGVuUmVxdWVzdEZhaWwgPSBmYWxzZVxuICAvLyDmjIHkuYXljJbmnKzlnLDlrZjlgqhcbiAgcHJpdmF0ZSBsb2NhbENhY2hlOiBJQ2xvdWRiYXNlQ2FjaGVcbiAgLyoqXG4gICAqIOWIneWni+WMllxuICAgKiBAcGFyYW0gY29uZmlnXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IElDbG91ZGJhc2VSZXF1ZXN0Q29uZmlnICYgeyB0aHJvdz86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnXG4gICAgY29uc3QgcmVxQ29uZmlnOiBJUmVxdWVzdENvbmZpZyA9IHtcbiAgICAgIHRpbWVvdXQ6IHRoaXMuY29uZmlnLnRpbWVvdXQsXG4gICAgICB0aW1lb3V0TXNnOiBgW0BjbG91ZGJhc2UvanMtc2RrXSDor7fmsYLlnKgke3RoaXMuY29uZmlnLnRpbWVvdXQgLyAxMDAwfXPlhoXmnKrlrozmiJDvvIzlt7LkuK3mlq1gLFxuICAgICAgcmVzdHJpY3RlZE1ldGhvZHM6IFsncG9zdCcsICdwdXQnXSxcbiAgICB9XG4gICAgdGhpcy5yZXFDbGFzcyA9IG5ldyBQbGF0Zm9ybS5hZGFwdGVyLnJlcUNsYXNzKHJlcUNvbmZpZylcbiAgICB0aGlzLnRocm93V2hlblJlcXVlc3RGYWlsID0gY29uZmlnLnRocm93IHx8IGZhbHNlXG4gICAgdGhpcy5sb2NhbENhY2hlID0gZ2V0TG9jYWxDYWNoZSh0aGlzLmNvbmZpZy5lbnYpXG4gICAgYmluZEhvb2tzKHRoaXMucmVxQ2xhc3MsICdwb3N0JywgW2JlZm9yZUVhY2hdKVxuICAgIGJpbmRIb29rcyh0aGlzLnJlcUNsYXNzLCAndXBsb2FkJywgW2JlZm9yZUVhY2hdKVxuICAgIGJpbmRIb29rcyh0aGlzLnJlcUNsYXNzLCAnZG93bmxvYWQnLCBbYmVmb3JlRWFjaF0pXG5cbiAgICBsYW5nRXZlbnQuYnVzLm9uKGxhbmdFdmVudC5MQU5HX0NIQU5HRV9FVkVOVCwgKHBhcmFtcykgPT4ge1xuICAgICAgdGhpcy5jb25maWcuaTE4biA9IHBhcmFtcy5kYXRhPy5pMThuIHx8IHRoaXMuY29uZmlnLmkxOG5cbiAgICB9KVxuICB9XG5cbiAgcHVibGljIGdldERlZmF1bHRIZWFkZXJzKCkge1xuICAgIHJldHVybiB7IFt0aGlzLmNvbmZpZy5pMThuPy5MQU5HX0hFQURFUl9LRVldOiB0aGlzLmNvbmZpZy5pMThuPy5sYW5nIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBwb3N0KG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnJlcUNsYXNzLnBvc3QoeyAuLi5vcHRpb25zLCBoZWFkZXJzOiB7IC4uLm9wdGlvbnMuaGVhZGVycywgLi4udGhpcy5nZXREZWZhdWx0SGVhZGVycygpIH0gfSlcbiAgICByZXR1cm4gcmVzXG4gIH1cbiAgcHVibGljIGFzeW5jIHVwbG9hZChvcHRpb25zOiBJVXBsb2FkUmVxdWVzdE9wdGlvbnMpOiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5yZXFDbGFzcy51cGxvYWQoeyAuLi5vcHRpb25zLCBoZWFkZXJzOiB7IC4uLm9wdGlvbnMuaGVhZGVycywgLi4udGhpcy5nZXREZWZhdWx0SGVhZGVycygpIH0gfSlcbiAgICByZXR1cm4gcmVzXG4gIH1cbiAgcHVibGljIGFzeW5jIGRvd25sb2FkKG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnJlcUNsYXNzLmRvd25sb2FkKHsgLi4ub3B0aW9ucywgaGVhZGVyczogeyAuLi5vcHRpb25zLmhlYWRlcnMsIC4uLnRoaXMuZ2V0RGVmYXVsdEhlYWRlcnMoKSB9IH0pXG4gICAgcmV0dXJuIHJlc1xuICB9XG5cbiAgcHVibGljIGdldEJhc2VFbmRQb2ludChlbmRQb2ludEtleTogRW5kUG9pbnRLZXkgPSAnQ0xPVURfQVBJJykge1xuICAgIHJldHVybiBnZXRCYXNlRW5kUG9pbnQodGhpcy5jb25maWcuZW52LCBlbmRQb2ludEtleSlcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRPYXV0aEFjY2Vzc1Rva2VuVjIob2F1dGhDbGllbnQ6IGFueSk6IFByb21pc2U8SUdldEFjY2Vzc1Rva2VuUmVzdWx0PiB7XG4gICAgY29uc3QgdmFsaWRBY2Nlc3NUb2tlbiA9IGF3YWl0IG9hdXRoQ2xpZW50LmdldEFjY2Vzc1Rva2VuKClcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IGF3YWl0IG9hdXRoQ2xpZW50LmdldENyZWRlbnRpYWxzKClcbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzVG9rZW46IHZhbGlkQWNjZXNzVG9rZW4sXG4gICAgICBhY2Nlc3NUb2tlbkV4cGlyZTogbmV3IERhdGUoY3JlZGVudGlhbHMuZXhwaXJlc19hdCkuZ2V0VGltZSgpLFxuICAgIH1cbiAgfVxuXG4gIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbiAgcHVibGljIGFzeW5jIHJlcXVlc3QoXG4gICAgYWN0aW9uOiBzdHJpbmcsXG4gICAgcGFyYW1zOiBLVjxhbnk+LFxuICAgIG9wdGlvbnM/OiB7XG4gICAgICBvblVwbG9hZFByb2dyZXNzPzogRnVuY3Rpb25cbiAgICAgIHBhdGhuYW1lPzogc3RyaW5nXG4gICAgICBwYXJzZT86IGJvb2xlYW5cbiAgICAgIGluUXVlcnk/OiBLVjxhbnk+XG4gICAgICBzZWFyY2g/OiBzdHJpbmdcbiAgICAgIGRlZmF1bHRRdWVyeT86IEtWPGFueT5cbiAgICB9LFxuICApOiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PiB7XG4gICAgY29uc3QgdGNiVHJhY2VLZXkgPSBgeC10Y2ItdHJhY2VfJHt0aGlzLmNvbmZpZy5lbnZ9YFxuICAgIGxldCBjb250ZW50VHlwZSA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG5cbiAgICBjb25zdCB0bXBPYmo6IEtWPGFueT4gPSB7XG4gICAgICBhY3Rpb24sXG4gICAgICBkYXRhVmVyc2lvbjogREFUQV9WRVJTSU9OLFxuICAgICAgZW52OiB0aGlzLmNvbmZpZy5lbnYsXG4gICAgICAuLi5wYXJhbXMsXG4gICAgfVxuXG4gICAgaWYgKEFDVElPTlNfV0lUSE9VVF9BQ0NFU1NUT0tFTi5pbmRleE9mKGFjdGlvbikgPT09IC0xKSB7XG4gICAgICBjb25zdCBhcHAgPSB0aGlzLmNvbmZpZy5fZnJvbUFwcFxuXG4gICAgICBpZiAoIWFwcC5vYXV0aEluc3RhbmNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigneW91IGNhblxcJ3QgcmVxdWVzdCB3aXRob3V0IGF1dGgnKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IG9hdXRoSW5zdGFuY2UgfSA9IGFwcFxuICAgICAgY29uc3Qgb2F1dGhDbGllbnQgPSBvYXV0aEluc3RhbmNlLm9hdXRoMmNsaWVudFxuICAgICAgdG1wT2JqLmFjY2Vzc190b2tlbiA9IChhd2FpdCB0aGlzLmdldE9hdXRoQWNjZXNzVG9rZW5WMihvYXV0aENsaWVudCkpLmFjY2Vzc1Rva2VuXG4gICAgfVxuXG4gICAgLy8g5ou8Ym9keeWSjGNvbnRlbnQtdHlwZVxuICAgIGxldCBwYXlsb2FkXG4gICAgaWYgKGFjdGlvbiA9PT0gJ3N0b3JhZ2UudXBsb2FkRmlsZScpIHtcbiAgICAgIHBheWxvYWQgPSBuZXcgRm9ybURhdGEoKVxuICAgICAgT2JqZWN0LmtleXMocGF5bG9hZCkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGF5bG9hZCwga2V5KSAmJiBwYXlsb2FkW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHBheWxvYWQuYXBwZW5kKGtleSwgdG1wT2JqW2tleV0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBjb250ZW50VHlwZSA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJ1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50VHlwZSA9ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9VVRGLTgnXG4gICAgICBwYXlsb2FkID0ge31cbiAgICAgIE9iamVjdC5rZXlzKHRtcE9iaikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGlmICh0bXBPYmpba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGF5bG9hZFtrZXldID0gdG1wT2JqW2tleV1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gICAgY29uc3Qgb3B0czogYW55ID0ge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnY29udGVudC10eXBlJzogY29udGVudFR5cGUsXG4gICAgICAgIC4uLnRoaXMuZ2V0RGVmYXVsdEhlYWRlcnMoKSxcbiAgICAgIH0sXG4gICAgfVxuICAgIGlmIChvcHRpb25zPy5vblVwbG9hZFByb2dyZXNzKSB7XG4gICAgICBvcHRzLm9uVXBsb2FkUHJvZ3Jlc3MgPSBvcHRpb25zLm9uVXBsb2FkUHJvZ3Jlc3NcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWcucmVnaW9uKSB7XG4gICAgICBvcHRzLmhlYWRlcnNbJ1gtVENCLVJlZ2lvbiddID0gdGhpcy5jb25maWcucmVnaW9uXG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2VIZWFkZXIgPSB0aGlzLmxvY2FsQ2FjaGUuZ2V0U3RvcmUodGNiVHJhY2VLZXkpXG4gICAgaWYgKHRyYWNlSGVhZGVyKSB7XG4gICAgICBvcHRzLmhlYWRlcnNbJ1gtVENCLVRyYWNlJ10gPSB0cmFjZUhlYWRlclxuICAgIH1cblxuICAgIC8vIOWPkeWHuuivt+axglxuICAgIC8vIOaWsOeahCB1cmwg6ZyA6KaB5pC65bimIGVudiDlj4LmlbDov5vooYwgQ09SUyDmoKHpqoxcbiAgICAvLyDor7fmsYLpk77mjqXmlK/mjIHmt7vliqDliqjmgIEgcXVlcnkg5Y+C5pWw77yM5pa55L6/55So5oi36LCD6K+V5a6a5L2N6K+35rGCXG4gICAgY29uc3QgcGFyc2UgPSBvcHRpb25zPy5wYXJzZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5wYXJzZSA6IHBhcmFtcy5wYXJzZVxuICAgIGNvbnN0IGluUXVlcnkgPSBvcHRpb25zPy5pblF1ZXJ5ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmluUXVlcnkgOiBwYXJhbXMuaW5RdWVyeVxuICAgIGNvbnN0IHNlYXJjaCA9IG9wdGlvbnM/LnNlYXJjaCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zZWFyY2ggOiBwYXJhbXMuc2VhcmNoXG5cbiAgICBsZXQgZm9ybWF0UXVlcnk6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7XG4gICAgICAuLi4ob3B0aW9ucz8uZGVmYXVsdFF1ZXJ5IHx8IHt9KSxcbiAgICAgIGVudjogdGhpcy5jb25maWcuZW52LFxuICAgIH1cbiAgICAvLyDlsJ3or5Xop6PmnpDlk43lupTmlbDmja7kuLogSlNPTlxuICAgIHBhcnNlICYmIChmb3JtYXRRdWVyeS5wYXJzZSA9IHRydWUpXG4gICAgaW5RdWVyeVxuICAgICAgJiYgKGZvcm1hdFF1ZXJ5ID0ge1xuICAgICAgICAuLi5pblF1ZXJ5LFxuICAgICAgICAuLi5mb3JtYXRRdWVyeSxcbiAgICAgIH0pXG5cbiAgICBjb25zdCB7IGJhc2VVcmw6IEJBU0VfVVJMLCBwcm90b2NvbDogUFJPVE9DT0wgfSA9IGdldEVuZFBvaW50SW5mbyh0aGlzLmNvbmZpZy5lbnYsICdDTE9VRF9BUEknKVxuICAgIC8vIOeUn+aIkOivt+axgiB1cmxcbiAgICBsZXQgbmV3VXJsXG4gICAgaWYgKG9wdGlvbnMucGF0aG5hbWUpIHtcbiAgICAgIG5ld1VybCA9IGZvcm1hdFVybChcbiAgICAgICAgUFJPVE9DT0wsXG4gICAgICAgIGAke2dldEJhc2VFbmRQb2ludCh0aGlzLmNvbmZpZy5lbnYpPy5yZXBsYWNlKC9eaHR0cHM/Oi8sICcnKX0vJHtvcHRpb25zLnBhdGhuYW1lfWAsXG4gICAgICAgIGZvcm1hdFF1ZXJ5LFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICBuZXdVcmwgPSBmb3JtYXRVcmwoUFJPVE9DT0wsIEJBU0VfVVJMLCBmb3JtYXRRdWVyeSlcbiAgICB9XG5cbiAgICBpZiAoc2VhcmNoKSB7XG4gICAgICBuZXdVcmwgKz0gc2VhcmNoXG4gICAgfVxuXG4gICAgY29uc3QgcmVzOiBSZXNwb25zZU9iamVjdCA9IGF3YWl0IHRoaXMucG9zdCh7XG4gICAgICB1cmw6IG5ld1VybCxcbiAgICAgIGRhdGE6IHBheWxvYWQsXG4gICAgICAuLi5vcHRzLFxuICAgIH0pXG5cbiAgICAvLyDkv53lrZggdHJhY2UgaGVhZGVyXG4gICAgY29uc3QgcmVzVHJhY2VIZWFkZXIgPSByZXMuaGVhZGVyPy5bJ3gtdGNiLXRyYWNlJ11cbiAgICBpZiAocmVzVHJhY2VIZWFkZXIpIHtcbiAgICAgIHRoaXMubG9jYWxDYWNoZS5zZXRTdG9yZSh0Y2JUcmFjZUtleSwgcmVzVHJhY2VIZWFkZXIpXG4gICAgfVxuXG4gICAgaWYgKChOdW1iZXIocmVzLnN0YXR1cykgIT09IDIwMCAmJiBOdW1iZXIocmVzLnN0YXR1c0NvZGUpICE9PSAyMDApIHx8ICFyZXMuZGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCduZXR3b3JrIHJlcXVlc3QgZXJyb3InKVxuICAgIH1cblxuICAgIHJldHVybiByZXNcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBmZXRjaChvcHRpb25zOiBJRmV0Y2hPcHRpb25zICYgeyB0b2tlbj86IHN0cmluZyB9KTogUHJvbWlzZTxSZXNwb25zZU9iamVjdD4ge1xuICAgIGNvbnN0IHsgdG9rZW4sIGhlYWRlcnMgPSB7fSwgLi4ucmVzdE9wdGlvbnMgfSA9IG9wdGlvbnNcbiAgICBjb25zdCBnZXRBY2Nlc3NUb2tlbiA9IGFzeW5jICgpID0+IHtcbiAgICAgIGlmICh0b2tlbiAhPSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0b2tlblxuICAgICAgfVxuICAgICAgY29uc3QgYXBwID0gdGhpcy5jb25maWcuX2Zyb21BcHBcblxuICAgICAgaWYgKCFhcHAub2F1dGhJbnN0YW5jZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3lvdSBjYW5cXCd0IHJlcXVlc3Qgd2l0aG91dCBhdXRoJylcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBvYXV0aEluc3RhbmNlIH0gPSBhcHBcbiAgICAgIGNvbnN0IG9hdXRoQ2xpZW50ID0gb2F1dGhJbnN0YW5jZS5vYXV0aDJjbGllbnRcbiAgICAgIHJldHVybiAoYXdhaXQgdGhpcy5nZXRPYXV0aEFjY2Vzc1Rva2VuVjIob2F1dGhDbGllbnQpKS5hY2Nlc3NUb2tlblxuICAgIH1cblxuICAgIGNvbnN0IGRvRmV0Y2ggPSBhc3luYyAoKSA9PiB0aGlzLnJlcUNsYXNzLmZldGNoKHtcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgLy8gJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgLy8gJ1gtUmVxdWVzdC1JZCc6IGAke3V0aWxzLmdlbmVyYXRlUmVxdWVzdElkKCl9YCxcbiAgICAgICAgLy8gJ1gtUmVxdWVzdC1UaW1lc3RhbXAnOiBgJHtEYXRlLm5vdygpfWAsXG4gICAgICAgICdYLVNESy1WZXJzaW9uJzogYEBjbG91ZGJhc2UvanMtc2RrLyR7Z2V0U2RrVmVyc2lvbigpfWAsXG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthd2FpdCBnZXRBY2Nlc3NUb2tlbigpfWAsXG4gICAgICAgIC4uLnRoaXMuZ2V0RGVmYXVsdEhlYWRlcnMoKSxcbiAgICAgICAgLi4uaGVhZGVycyxcbiAgICAgIH0sXG4gICAgICAuLi5yZXN0T3B0aW9ucyxcbiAgICB9KVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRvRmV0Y2goKVxuICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVycj8uY29kZSA9PT0gJ0FDQ0VTU19UT0tFTl9FWFBJUkVEJykge1xuICAgICAgICAvLyDlpoLmnpzmmK/lm6DkuLogdG9rZW4g6L+H5pyf5aSx6LSl77yM5Yi3IHRva2VuIOWQjuWGjeivleS4gOasoVxuICAgICAgICBpZiAodHlwZW9mIHRoaXMuY29uZmlnPy5fZnJvbUFwcD8ub2F1dGhJbnN0YW5jZT8uYXV0aEFwaT8ucmVmcmVzaFRva2VuRm9yY2UgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aHJvdyBlcnJcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLmNvbmZpZz8uX2Zyb21BcHA/Lm9hdXRoSW5zdGFuY2U/LmF1dGhBcGk/LnJlZnJlc2hUb2tlbkZvcmNlKClcbiAgICAgICAgcmV0dXJuIGRvRmV0Y2goKVxuICAgICAgfVxuICAgICAgLy8g5YW25LuW5Y6f5Zug5ZCR5LiK5oqb5Ye6XG5cbiAgICAgIHRocm93IGVyclxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZW5kKGFjdGlvbjogc3RyaW5nLCBkYXRhOiBLVjxhbnk+ID0ge30sIG9wdGlvbnM6IEtWPGFueT4gPSB7fSk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QoYWN0aW9uLCBkYXRhLCB7IC4uLm9wdGlvbnMsIG9uVXBsb2FkUHJvZ3Jlc3M6IGRhdGEub25VcGxvYWRQcm9ncmVzcyB9KVxuXG4gICAgaWYgKHJlc3BvbnNlLmRhdGEuY29kZSAmJiB0aGlzLnRocm93V2hlblJlcXVlc3RGYWlsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBjb2RlOiBFUlJPUlMuT1BFUkFUSU9OX0ZBSUwsXG4gICAgICAgIG1zZzogYFske3Jlc3BvbnNlLmRhdGEuY29kZX1dICR7cmVzcG9uc2UuZGF0YS5tZXNzYWdlfWAsXG4gICAgICB9KSwpXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGFcbiAgfVxufVxuXG5jb25zdCByZXF1ZXN0TWFwOiBLVjxDbG91ZGJhc2VSZXF1ZXN0PiA9IHt9XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0UmVxdWVzdChjb25maWc6IElDbG91ZGJhc2VSZXF1ZXN0Q29uZmlnKSB7XG4gIHJlcXVlc3RNYXBbY29uZmlnLmVudl0gPSBuZXcgQ2xvdWRiYXNlUmVxdWVzdCh7XG4gICAgLi4uY29uZmlnLFxuICAgIHRocm93OiB0cnVlLFxuICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVxdWVzdEJ5RW52SWQoZW52OiBzdHJpbmcpOiBDbG91ZGJhc2VSZXF1ZXN0IHtcbiAgcmV0dXJuIHJlcXVlc3RNYXBbZW52XVxufVxuIl19