@cloudbase/app
Version:
cloudbase javascript sdk core
391 lines • 48.4 kB
JavaScript
"use strict";
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRequestByEnvId = exports.initRequest = exports.CloudbaseRequest = void 0;
var common_1 = require("../constants/common");
var utilities_1 = require("@cloudbase/utilities");
var cache_1 = require("./cache");
var adapter_1 = require("./adapter");
var ERRORS = utilities_1.constants.ERRORS;
var genSeqId = utilities_1.utils.genSeqId, isFormData = utilities_1.utils.isFormData, formatUrl = utilities_1.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((0, common_1.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 adapter_1.Platform.adapter.reqClass(reqConfig);
this.throwWhenRequestFail = config.throw || false;
this.localCache = (0, cache_1.getLocalCache)(this.config.env);
bindHooks(this.reqClass, 'post', [beforeEach]);
bindHooks(this.reqClass, 'upload', [beforeEach]);
bindHooks(this.reqClass, 'download', [beforeEach]);
utilities_1.langEvent.bus.on(utilities_1.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 (0, common_1.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: common_1.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 = (0, common_1.getEndPointInfo)(this.config.env, 'CLOUD_API'), BASE_URL = _d.baseUrl, PROTOCOL = _d.protocol;
if (options.pathname) {
newUrl = formatUrl(PROTOCOL, "".concat((_a = (0, common_1.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((0, common_1.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;
}());
exports.CloudbaseRequest = CloudbaseRequest;
var requestMap = {};
function initRequest(config) {
requestMap[config.env] = new CloudbaseRequest(__assign(__assign({}, config), { throw: true }));
}
exports.initRequest = initRequest;
function getRequestByEnvId(env) {
return requestMap[env];
}
exports.getRequestByEnvId = getRequestByEnvId;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWJzL3JlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUFtRztBQVNuRyxrREFBa0U7QUFTbEUsaUNBQXVDO0FBQ3ZDLHFDQUFvQztBQUM1QixJQUFBLE1BQU0sR0FBSyxxQkFBUyxPQUFkLENBQWM7QUFDcEIsSUFBQSxRQUFRLEdBQTRCLGlCQUFLLFNBQWpDLEVBQUUsVUFBVSxHQUFnQixpQkFBSyxXQUFyQixFQUFFLFNBQVMsR0FBSyxpQkFBSyxVQUFWLENBQVU7QUFHakQsSUFBTSwyQkFBMkIsR0FBRztJQUNsQyxhQUFhO0lBQ2IsYUFBYTtJQUNiLHVCQUF1QjtJQUN2Qix3QkFBd0I7SUFDeEIsYUFBYTtJQUNiLHVDQUF1QztJQUN2QyxpQ0FBaUM7SUFDakMsMEJBQTBCO0lBQzFCLDZCQUE2QjtJQUM3Qiw2QkFBNkI7SUFDN0IsMkJBQTJCO0NBQzVCLENBQUE7QUFFRCxTQUFTLFNBQVMsQ0FBQyxRQUE2QixFQUFFLElBQVksRUFBRSxLQUEyQjtJQUN6RixJQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDbkMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsT0FBd0I7UUFDakQsSUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQ2YsSUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFBO1FBQ2xCLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBQyxJQUFJO1lBQ1gsSUFBQSxLQUFtRCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBdkUsWUFBWSxVQUFBLEVBQVcsZUFBZSxhQUFpQyxDQUFBO1lBQ3JGLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFB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QUUsQ0FBQTtBQUUzQyxTQUFnQixXQUFXLENBQUMsTUFBK0I7SUFDekQsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLGdCQUFnQix1QkFDeEMsTUFBTSxLQUNULEtBQUssRUFBRSxJQUFJLElBQ1gsQ0FBQTtBQUNKLENBQUM7QUFMRCxrQ0FLQztBQUVELFNBQWdCLGlCQUFpQixDQUFDLEdBQVc7SUFDM0MsT0FBTyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUE7QUFDeEIsQ0FBQztBQUZELDhDQUVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgREFUQV9WRVJTSU9OLCBnZXRTZGtWZXJzaW9uLCBnZXRCYXNlRW5kUG9pbnQsIGdldEVuZFBvaW50SW5mbyB9IGZyb20gJy4uL2NvbnN0YW50cy9jb21tb24nXG5pbXBvcnQge1xuICBJUmVxdWVzdE9wdGlvbnMsXG4gIFNES1JlcXVlc3RJbnRlcmZhY2UsXG4gIFJlc3BvbnNlT2JqZWN0LFxuICBJVXBsb2FkUmVxdWVzdE9wdGlvbnMsXG4gIElSZXF1ZXN0Q29uZmlnLFxuICBJRmV0Y2hPcHRpb25zLFxufSBmcm9tICdAY2xvdWRiYXNlL2FkYXB0ZXItaW50ZXJmYWNlJ1xuaW1wb3J0IHsgdXRpbHMsIGNvbnN0YW50cywgbGFuZ0V2ZW50IH0gZnJvbSAnQGNsb3VkYmFzZS91dGlsaXRpZXMnXG5pbXBvcnQgeyBFbmRQb2ludEtleSwgS1YgfSBmcm9tICdAY2xvdWRiYXNlL3R5cGVzJ1xuaW1wb3J0IHtcbiAgSUdldEFjY2Vzc1Rva2VuUmVzdWx0LFxuICBJQ2xvdWRiYXNlUmVxdWVzdENvbmZpZyxcbiAgSUFwcGVuZGVkUmVxdWVzdEluZm8sXG4gIElSZXF1ZXN0QmVmb3JlSG9vayxcbn0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcy9yZXF1ZXN0J1xuaW1wb3J0IHsgSUNsb3VkYmFzZUNhY2hlIH0gZnJvbSAnQGNsb3VkYmFzZS90eXBlcy9jYWNoZSdcbmltcG9ydCB7IGdldExvY2FsQ2FjaGUgfSBmcm9tICcuL2NhY2hlJ1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICcuL2FkYXB0ZXInXG5jb25zdCB7IEVSUk9SUyB9ID0gY29uc3RhbnRzXG5jb25zdCB7IGdlblNlcUlkLCBpc0Zvcm1EYXRhLCBmb3JtYXRVcmwgfSA9IHV0aWxzXG5cbi8vIOS4i+mdouWHoOenjSBhY3Rpb24g5LiN6ZyA6KaBIGFjY2VzcyB0b2tlblxuY29uc3QgQUNUSU9OU19XSVRIT1VUX0FDQ0VTU1RPS0VOID0gW1xuICAnYXV0aC5nZXRKd3QnLFxuICAnYXV0aC5sb2dvdXQnLFxuICAnYXV0aC5zaWduSW5XaXRoVGlja2V0JyxcbiAgJ2F1dGguc2lnbkluQW5vbnltb3VzbHknLFxuICAnYXV0aC5zaWduSW4nLFxuICAnYXV0aC5mZXRjaEFjY2Vzc1Rva2VuV2l0aFJlZnJlc2hUb2tlbicsXG4gICdhdXRoLnNpZ25VcFdpdGhFbWFpbEFuZFBhc3N3b3JkJyxcbiAgJ2F1dGguYWN0aXZhdGVFbmRVc2VyTWFpbCcsXG4gICdhdXRoLnNlbmRQYXNzd29yZFJlc2V0RW1haWwnLFxuICAnYXV0aC5yZXNldFBhc3N3b3JkV2l0aFRva2VuJyxcbiAgJ2F1dGguaXNVc2VybmFtZVJlZ2lzdGVyZWQnLFxuXVxuXG5mdW5jdGlvbiBiaW5kSG9va3MoaW5zdGFuY2U6IFNES1JlcXVlc3RJbnRlcmZhY2UsIG5hbWU6IHN0cmluZywgaG9va3M6IElSZXF1ZXN0QmVmb3JlSG9va1tdKSB7XG4gIGNvbnN0IG9yaWdpbk1ldGhvZCA9IGluc3RhbmNlW25hbWVdXG4gIGluc3RhbmNlW25hbWVdID0gZnVuY3Rpb24gKG9wdGlvbnM6IElSZXF1ZXN0T3B0aW9ucykge1xuICAgIGNvbnN0IGRhdGEgPSB7fVxuICAgIGNvbnN0IGhlYWRlcnMgPSB7fVxuICAgIGhvb2tzLmZvckVhY2goKGhvb2spID0+IHtcbiAgICAgIGNvbnN0IHsgZGF0YTogYXBwZW5kZWREYXRhLCBoZWFkZXJzOiBhcHBlbmRlZEhlYWRlcnMgfSA9IGhvb2suY2FsbChpbnN0YW5jZSwgb3B0aW9ucylcbiAgICAgIE9iamVjdC5hc3NpZ24oZGF0YSwgYXBwZW5kZWREYXRhKVxuICAgICAgT2JqZWN0LmFzc2lnbihoZWFkZXJzLCBhcHBlbmRlZEhlYWRlcnMpXG4gICAgfSlcbiAgICBjb25zdCBvcmlnaW5EYXRhID0gb3B0aW9ucy5kYXRhXG4gICAgb3JpZ2luRGF0YVxuICAgICAgJiYgKCgpID0+IHtcbiAgICAgICAgaWYgKGlzRm9ybURhdGEob3JpZ2luRGF0YSkpIHtcbiAgICAgICAgICBPYmplY3Qua2V5cyhkYXRhKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgIChvcmlnaW5EYXRhIGFzIEZvcm1EYXRhKS5hcHBlbmQoa2V5LCBkYXRhW2tleV0pXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLmRhdGEgPSB7XG4gICAgICAgICAgLi4ub3JpZ2luRGF0YSxcbiAgICAgICAgICAuLi5kYXRhLFxuICAgICAgICB9XG4gICAgICB9KSgpXG4gICAgb3B0aW9ucy5oZWFkZXJzID0ge1xuICAgICAgLi4uKG9wdGlvbnMuaGVhZGVycyB8fCB7fSksXG4gICAgICAuLi5oZWFkZXJzLFxuICAgIH1cbiAgICByZXR1cm4gKG9yaWdpbk1ldGhvZCBhcyBGdW5jdGlvbikuY2FsbChpbnN0YW5jZSwgb3B0aW9ucylcbiAgfVxufVxuZnVuY3Rpb24gYmVmb3JlRWFjaCgpOiBJQXBwZW5kZWRSZXF1ZXN0SW5mbyB7XG4gIGNvbnN0IHNlcUlkID0gZ2VuU2VxSWQoKVxuICByZXR1cm4ge1xuICAgIGRhdGE6IHtcbiAgICAgIHNlcUlkLFxuICAgIH0sXG4gICAgaGVhZGVyczoge1xuICAgICAgJ1gtU0RLLVZlcnNpb24nOiBgQGNsb3VkYmFzZS9qcy1zZGsvJHtnZXRTZGtWZXJzaW9uKCl9YCxcbiAgICAgICd4LXNlcWlkJzogc2VxSWQsXG4gICAgfSxcbiAgfVxufVxuZXhwb3J0IGludGVyZmFjZSBJQ2xvdWRiYXNlUmVxdWVzdCB7XG4gIHBvc3Q6IChvcHRpb25zOiBJUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHVwbG9hZDogKG9wdGlvbnM6IElVcGxvYWRSZXF1ZXN0T3B0aW9ucykgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbiAgZG93bmxvYWQ6IChvcHRpb25zOiBJUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+XG4gIHJlcXVlc3Q6IChhY3Rpb246IHN0cmluZywgcGFyYW1zOiBLVjxhbnk+LCBvcHRpb25zPzogS1Y8YW55PikgPT4gUHJvbWlzZTxSZXNwb25zZU9iamVjdD5cbiAgc2VuZDogKGFjdGlvbjogc3RyaW5nLCBkYXRhOiBLVjxhbnk+KSA9PiBQcm9taXNlPGFueT5cbiAgZmV0Y2g6IChvcHRpb25zOiBJRmV0Y2hPcHRpb25zKSA9PiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PlxufVxuXG4vKipcbiAqIEBjbGFzcyBDbG91ZGJhc2VSZXF1ZXN0XG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZGJhc2VSZXF1ZXN0IGltcGxlbWVudHMgSUNsb3VkYmFzZVJlcXVlc3Qge1xuICBjb25maWc6IElDbG91ZGJhc2VSZXF1ZXN0Q29uZmlnXG4gIHByaXZhdGUgcmVxQ2xhc3M6IFNES1JlcXVlc3RJbnRlcmZhY2VcbiAgLy8g6K+35rGC5aSx6LSl5piv5ZCm5oqb5Ye6RXJyb3JcbiAgcHJpdmF0ZSB0aHJvd1doZW5SZXF1ZXN0RmFpbCA9IGZhbHNlXG4gIC8vIOaMgeS5heWMluacrOWcsOWtmOWCqFxuICBwcml2YXRlIGxvY2FsQ2FjaGU6IElDbG91ZGJhc2VDYWNoZVxuICAvKipcbiAgICog5Yid5aeL5YyWXG4gICAqIEBwYXJhbSBjb25maWdcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogSUNsb3VkYmFzZVJlcXVlc3RDb25maWcgJiB7IHRocm93PzogYm9vbGVhbiB9KSB7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWdcbiAgICBjb25zdCByZXFDb25maWc6IElSZXF1ZXN0Q29uZmlnID0ge1xuICAgICAgdGltZW91dDogdGhpcy5jb25maWcudGltZW91dCxcbiAgICAgIHRpbWVvdXRNc2c6IGBbQGNsb3VkYmFzZS9qcy1zZGtdIOivt+axguWcqCR7dGhpcy5jb25maWcudGltZW91dCAvIDEwMDB9c+WGheacquWujOaIkO+8jOW3suS4reaWrWAsXG4gICAgICByZXN0cmljdGVkTWV0aG9kczogWydwb3N0JywgJ3B1dCddLFxuICAgIH1cbiAgICB0aGlzLnJlcUNsYXNzID0gbmV3IFBsYXRmb3JtLmFkYXB0ZXIucmVxQ2xhc3MocmVxQ29uZmlnKVxuICAgIHRoaXMudGhyb3dXaGVuUmVxdWVzdEZhaWwgPSBjb25maWcudGhyb3cgfHwgZmFsc2VcbiAgICB0aGlzLmxvY2FsQ2FjaGUgPSBnZXRMb2NhbENhY2hlKHRoaXMuY29uZmlnLmVudilcbiAgICBiaW5kSG9va3ModGhpcy5yZXFDbGFzcywgJ3Bvc3QnLCBbYmVmb3JlRWFjaF0pXG4gICAgYmluZEhvb2tzKHRoaXMucmVxQ2xhc3MsICd1cGxvYWQnLCBbYmVmb3JlRWFjaF0pXG4gICAgYmluZEhvb2tzKHRoaXMucmVxQ2xhc3MsICdkb3dubG9hZCcsIFtiZWZvcmVFYWNoXSlcblxuICAgIGxhbmdFdmVudC5idXMub24obGFuZ0V2ZW50LkxBTkdfQ0hBTkdFX0VWRU5ULCAocGFyYW1zKSA9PiB7XG4gICAgICB0aGlzLmNvbmZpZy5pMThuID0gcGFyYW1zLmRhdGE/LmkxOG4gfHwgdGhpcy5jb25maWcuaTE4blxuICAgIH0pXG4gIH1cblxuICBwdWJsaWMgZ2V0RGVmYXVsdEhlYWRlcnMoKSB7XG4gICAgcmV0dXJuIHsgW3RoaXMuY29uZmlnLmkxOG4/LkxBTkdfSEVBREVSX0tFWV06IHRoaXMuY29uZmlnLmkxOG4/LmxhbmcgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHBvc3Qob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZU9iamVjdD4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMucmVxQ2xhc3MucG9zdCh7IC4uLm9wdGlvbnMsIGhlYWRlcnM6IHsgLi4ub3B0aW9ucy5oZWFkZXJzLCAuLi50aGlzLmdldERlZmF1bHRIZWFkZXJzKCkgfSB9KVxuICAgIHJldHVybiByZXNcbiAgfVxuICBwdWJsaWMgYXN5bmMgdXBsb2FkKG9wdGlvbnM6IElVcGxvYWRSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnJlcUNsYXNzLnVwbG9hZCh7IC4uLm9wdGlvbnMsIGhlYWRlcnM6IHsgLi4ub3B0aW9ucy5oZWFkZXJzLCAuLi50aGlzLmdldERlZmF1bHRIZWFkZXJzKCkgfSB9KVxuICAgIHJldHVybiByZXNcbiAgfVxuICBwdWJsaWMgYXN5bmMgZG93bmxvYWQob3B0aW9uczogSVJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZU9iamVjdD4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMucmVxQ2xhc3MuZG93bmxvYWQoeyAuLi5vcHRpb25zLCBoZWFkZXJzOiB7IC4uLm9wdGlvbnMuaGVhZGVycywgLi4udGhpcy5nZXREZWZhdWx0SGVhZGVycygpIH0gfSlcbiAgICByZXR1cm4gcmVzXG4gIH1cblxuICBwdWJsaWMgZ2V0QmFzZUVuZFBvaW50KGVuZFBvaW50S2V5OiBFbmRQb2ludEtleSA9ICdDTE9VRF9BUEknKSB7XG4gICAgcmV0dXJuIGdldEJhc2VFbmRQb2ludCh0aGlzLmNvbmZpZy5lbnYsIGVuZFBvaW50S2V5KVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGdldE9hdXRoQWNjZXNzVG9rZW5WMihvYXV0aENsaWVudDogYW55KTogUHJvbWlzZTxJR2V0QWNjZXNzVG9rZW5SZXN1bHQ+IHtcbiAgICBjb25zdCB2YWxpZEFjY2Vzc1Rva2VuID0gYXdhaXQgb2F1dGhDbGllbnQuZ2V0QWNjZXNzVG9rZW4oKVxuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gYXdhaXQgb2F1dGhDbGllbnQuZ2V0Q3JlZGVudGlhbHMoKVxuICAgIHJldHVybiB7XG4gICAgICBhY2Nlc3NUb2tlbjogdmFsaWRBY2Nlc3NUb2tlbixcbiAgICAgIGFjY2Vzc1Rva2VuRXhwaXJlOiBuZXcgRGF0ZShjcmVkZW50aWFscy5leHBpcmVzX2F0KS5nZXRUaW1lKCksXG4gICAgfVxuICB9XG5cbiAgLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuICBwdWJsaWMgYXN5bmMgcmVxdWVzdChcbiAgICBhY3Rpb246IHN0cmluZyxcbiAgICBwYXJhbXM6IEtWPGFueT4sXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIG9uVXBsb2FkUHJvZ3Jlc3M/OiBGdW5jdGlvblxuICAgICAgcGF0aG5hbWU/OiBzdHJpbmdcbiAgICAgIHBhcnNlPzogYm9vbGVhblxuICAgICAgaW5RdWVyeT86IEtWPGFueT5cbiAgICAgIHNlYXJjaD86IHN0cmluZ1xuICAgICAgZGVmYXVsdFF1ZXJ5PzogS1Y8YW55PlxuICAgIH0sXG4gICk6IFByb21pc2U8UmVzcG9uc2VPYmplY3Q+IHtcbiAgICBjb25zdCB0Y2JUcmFjZUtleSA9IGB4LXRjYi10cmFjZV8ke3RoaXMuY29uZmlnLmVudn1gXG4gICAgbGV0IGNvbnRlbnRUeXBlID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCdcblxuICAgIGNvbnN0IHRtcE9iajogS1Y8YW55PiA9IHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGRhdGFWZXJzaW9uOiBEQVRBX1ZFUlNJT04sXG4gICAgICBlbnY6IHRoaXMuY29uZmlnLmVudixcbiAgICAgIC4uLnBhcmFtcyxcbiAgICB9XG5cbiAgICBpZiAoQUNUSU9OU19XSVRIT1VUX0FDQ0VTU1RPS0VOLmluZGV4T2YoYWN0aW9uKSA9PT0gLTEpIHtcbiAgICAgIGNvbnN0IGFwcCA9IHRoaXMuY29uZmlnLl9mcm9tQXBwXG5cbiAgICAgIGlmICghYXBwLm9hdXRoSW5zdGFuY2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd5b3UgY2FuXFwndCByZXF1ZXN0IHdpdGhvdXQgYXV0aCcpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgb2F1dGhJbnN0YW5jZSB9ID0gYXBwXG4gICAgICBjb25zdCBvYXV0aENsaWVudCA9IG9hdXRoSW5zdGFuY2Uub2F1dGgyY2xpZW50XG4gICAgICB0bXBPYmouYWNjZXNzX3Rva2VuID0gKGF3YWl0IHRoaXMuZ2V0T2F1dGhBY2Nlc3NUb2tlblYyKG9hdXRoQ2xpZW50KSkuYWNjZXNzVG9rZW5cbiAgICB9XG5cbiAgICAvLyDmi7xib2R55ZKMY29udGVudC10eXBlXG4gICAgbGV0IHBheWxvYWRcbiAgICBpZiAoYWN0aW9uID09PSAnc3RvcmFnZS51cGxvYWRGaWxlJykge1xuICAgICAgcGF5bG9hZCA9IG5ldyBGb3JtRGF0YSgpXG4gICAgICBPYmplY3Qua2V5cyhwYXlsb2FkKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwYXlsb2FkLCBrZXkpICYmIHBheWxvYWRba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGF5bG9hZC5hcHBlbmQoa2V5LCB0bXBPYmpba2V5XSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIGNvbnRlbnRUeXBlID0gJ211bHRpcGFydC9mb3JtLWRhdGEnXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRlbnRUeXBlID0gJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD1VVEYtOCdcbiAgICAgIHBheWxvYWQgPSB7fVxuICAgICAgT2JqZWN0LmtleXModG1wT2JqKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgaWYgKHRtcE9ialtrZXldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBwYXlsb2FkW2tleV0gPSB0bXBPYmpba2V5XVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgICBjb25zdCBvcHRzOiBhbnkgPSB7XG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdjb250ZW50LXR5cGUnOiBjb250ZW50VHlwZSxcbiAgICAgICAgLi4udGhpcy5nZXREZWZhdWx0SGVhZGVycygpLFxuICAgICAgfSxcbiAgICB9XG4gICAgaWYgKG9wdGlvbnM/Lm9uVXBsb2FkUHJvZ3Jlc3MpIHtcbiAgICAgIG9wdHMub25VcGxvYWRQcm9ncmVzcyA9IG9wdGlvbnMub25VcGxvYWRQcm9ncmVzc1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5yZWdpb24pIHtcbiAgICAgIG9wdHMuaGVhZGVyc1snWC1UQ0ItUmVnaW9uJ10gPSB0aGlzLmNvbmZpZy5yZWdpb25cbiAgICB9XG5cbiAgICBjb25zdCB0cmFjZUhlYWRlciA9IHRoaXMubG9jYWxDYWNoZS5nZXRTdG9yZSh0Y2JUcmFjZUtleSlcbiAgICBpZiAodHJhY2VIZWFkZXIpIHtcbiAgICAgIG9wdHMuaGVhZGVyc1snWC1UQ0ItVHJhY2UnXSA9IHRyYWNlSGVhZGVyXG4gICAgfVxuXG4gICAgLy8g5Y+R5Ye66K+35rGCXG4gICAgLy8g5paw55qEIHVybCDpnIDopoHmkLrluKYgZW52IOWPguaVsOi/m+ihjCBDT1JTIOagoemqjFxuICAgIC8vIOivt+axgumTvuaOpeaUr+aMgea3u+WKoOWKqOaAgSBxdWVyeSDlj4LmlbDvvIzmlrnkvr/nlKjmiLfosIPor5XlrprkvY3or7fmsYJcbiAgICBjb25zdCBwYXJzZSA9IG9wdGlvbnM/LnBhcnNlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnBhcnNlIDogcGFyYW1zLnBhcnNlXG4gICAgY29uc3QgaW5RdWVyeSA9IG9wdGlvbnM/LmluUXVlcnkgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuaW5RdWVyeSA6IHBhcmFtcy5pblF1ZXJ5XG4gICAgY29uc3Qgc2VhcmNoID0gb3B0aW9ucz8uc2VhcmNoICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnNlYXJjaCA6IHBhcmFtcy5zZWFyY2hcblxuICAgIGxldCBmb3JtYXRRdWVyeTogUmVjb3JkPHN0cmluZywgYW55PiA9IHtcbiAgICAgIC4uLihvcHRpb25zPy5kZWZhdWx0UXVlcnkgfHwge30pLFxuICAgICAgZW52OiB0aGlzLmNvbmZpZy5lbnYsXG4gICAgfVxuICAgIC8vIOWwneivleino+aekOWTjeW6lOaVsOaNruS4uiBKU09OXG4gICAgcGFyc2UgJiYgKGZvcm1hdFF1ZXJ5LnBhcnNlID0gdHJ1ZSlcbiAgICBpblF1ZXJ5XG4gICAgICAmJiAoZm9ybWF0UXVlcnkgPSB7XG4gICAgICAgIC4uLmluUXVlcnksXG4gICAgICAgIC4uLmZvcm1hdFF1ZXJ5LFxuICAgICAgfSlcblxuICAgIGNvbnN0IHsgYmFzZVVybDogQkFTRV9VUkwsIHByb3RvY29sOiBQUk9UT0NPTCB9ID0gZ2V0RW5kUG9pbnRJbmZvKHRoaXMuY29uZmlnLmVudiwgJ0NMT1VEX0FQSScpXG4gICAgLy8g55Sf5oiQ6K+35rGCIHVybFxuICAgIGxldCBuZXdVcmxcbiAgICBpZiAob3B0aW9ucy5wYXRobmFtZSkge1xuICAgICAgbmV3VXJsID0gZm9ybWF0VXJsKFxuICAgICAgICBQUk9UT0NPTCxcbiAgICAgICAgYCR7Z2V0QmFzZUVuZFBvaW50KHRoaXMuY29uZmlnLmVudik/LnJlcGxhY2UoL15odHRwcz86LywgJycpfS8ke29wdGlvbnMucGF0aG5hbWV9YCxcbiAgICAgICAgZm9ybWF0UXVlcnksXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld1VybCA9IGZvcm1hdFVybChQUk9UT0NPTCwgQkFTRV9VUkwsIGZvcm1hdFF1ZXJ5KVxuICAgIH1cblxuICAgIGlmIChzZWFyY2gpIHtcbiAgICAgIG5ld1VybCArPSBzZWFyY2hcbiAgICB9XG5cbiAgICBjb25zdCByZXM6IFJlc3BvbnNlT2JqZWN0ID0gYXdhaXQgdGhpcy5wb3N0KHtcbiAgICAgIHVybDogbmV3VXJsLFxuICAgICAgZGF0YTogcGF5bG9hZCxcbiAgICAgIC4uLm9wdHMsXG4gICAgfSlcblxuICAgIC8vIOS/neWtmCB0cmFjZSBoZWFkZXJcbiAgICBjb25zdCByZXNUcmFjZUhlYWRlciA9IHJlcy5oZWFkZXI/LlsneC10Y2ItdHJhY2UnXVxuICAgIGlmIChyZXNUcmFjZUhlYWRlcikge1xuICAgICAgdGhpcy5sb2NhbENhY2hlLnNldFN0b3JlKHRjYlRyYWNlS2V5LCByZXNUcmFjZUhlYWRlcilcbiAgICB9XG5cbiAgICBpZiAoKE51bWJlcihyZXMuc3RhdHVzKSAhPT0gMjAwICYmIE51bWJlcihyZXMuc3RhdHVzQ29kZSkgIT09IDIwMCkgfHwgIXJlcy5kYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25ldHdvcmsgcmVxdWVzdCBlcnJvcicpXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGZldGNoKG9wdGlvbnM6IElGZXRjaE9wdGlvbnMgJiB7IHRva2VuPzogc3RyaW5nIH0pOiBQcm9taXNlPFJlc3BvbnNlT2JqZWN0PiB7XG4gICAgY29uc3QgeyB0b2tlbiwgaGVhZGVycyA9IHt9LCAuLi5yZXN0T3B0aW9ucyB9ID0gb3B0aW9uc1xuICAgIGNvbnN0IGdldEFjY2Vzc1Rva2VuID0gYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHRva2VuICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHRva2VuXG4gICAgICB9XG4gICAgICBjb25zdCBhcHAgPSB0aGlzLmNvbmZpZy5fZnJvbUFwcFxuXG4gICAgICBpZiAoIWFwcC5vYXV0aEluc3RhbmNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigneW91IGNhblxcJ3QgcmVxdWVzdCB3aXRob3V0IGF1dGgnKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IG9hdXRoSW5zdGFuY2UgfSA9IGFwcFxuICAgICAgY29uc3Qgb2F1dGhDbGllbnQgPSBvYXV0aEluc3RhbmNlLm9hdXRoMmNsaWVudFxuICAgICAgcmV0dXJuIChhd2FpdCB0aGlzLmdldE9hdXRoQWNjZXNzVG9rZW5WMihvYXV0aENsaWVudCkpLmFjY2Vzc1Rva2VuXG4gICAgfVxuXG4gICAgY29uc3QgZG9GZXRjaCA9IGFzeW5jICgpID0+IHRoaXMucmVxQ2xhc3MuZmV0Y2goe1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICAvLyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAvLyAnWC1SZXF1ZXN0LUlkJzogYCR7dXRpbHMuZ2VuZXJhdGVSZXF1ZXN0SWQoKX1gLFxuICAgICAgICAvLyAnWC1SZXF1ZXN0LVRpbWVzdGFtcCc6IGAke0RhdGUubm93KCl9YCxcbiAgICAgICAgJ1gtU0RLLVZlcnNpb24nOiBgQGNsb3VkYmFzZS9qcy1zZGsvJHtnZXRTZGtWZXJzaW9uKCl9YCxcbiAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2F3YWl0IGdldEFjY2Vzc1Rva2VuKCl9YCxcbiAgICAgICAgLi4udGhpcy5nZXREZWZhdWx0SGVhZGVycygpLFxuICAgICAgICAuLi5oZWFkZXJzLFxuICAgICAgfSxcbiAgICAgIC4uLnJlc3RPcHRpb25zLFxuICAgIH0pXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZG9GZXRjaCgpXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyPy5jb2RlID09PSAnQUNDRVNTX1RPS0VOX0VYUElSRUQnKSB7XG4gICAgICAgIC8vIOWmguaenOaYr+WboOS4uiB0b2tlbiDov4fmnJ/lpLHotKXvvIzliLcgdG9rZW4g5ZCO5YaN6K+V5LiA5qyhXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWc/Ll9mcm9tQXBwPy5vYXV0aEluc3RhbmNlPy5hdXRoQXBpPy5yZWZyZXNoVG9rZW5Gb3JjZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRocm93IGVyclxuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuY29uZmlnPy5fZnJvbUFwcD8ub2F1dGhJbnN0YW5jZT8uYXV0aEFwaT8ucmVmcmVzaFRva2VuRm9yY2UoKVxuICAgICAgICByZXR1cm4gZG9GZXRjaCgpXG4gICAgICB9XG4gICAgICAvLyDlhbbku5bljp/lm6DlkJHkuIrmipvlh7pcblxuICAgICAgdGhyb3cgZXJyXG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHNlbmQoYWN0aW9uOiBzdHJpbmcsIGRhdGE6IEtWPGFueT4gPSB7fSwgb3B0aW9uczogS1Y8YW55PiA9IHt9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdChhY3Rpb24sIGRhdGEsIHsgLi4ub3B0aW9ucywgb25VcGxvYWRQcm9ncmVzczogZGF0YS5vblVwbG9hZFByb2dyZXNzIH0pXG5cbiAgICBpZiAocmVzcG9uc2UuZGF0YS5jb2RlICYmIHRoaXMudGhyb3dXaGVuUmVxdWVzdEZhaWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGNvZGU6IEVSUk9SUy5PUEVSQVRJT05fRkFJTCxcbiAgICAgICAgbXNnOiBgWyR7cmVzcG9uc2UuZGF0YS5jb2RlfV0gJHtyZXNwb25zZS5kYXRhLm1lc3NhZ2V9YCxcbiAgICAgIH0pLClcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YVxuICB9XG59XG5cbmNvbnN0IHJlcXVlc3RNYXA6IEtWPENsb3VkYmFzZVJlcXVlc3Q+ID0ge31cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRSZXF1ZXN0KGNvbmZpZzogSUNsb3VkYmFzZVJlcXVlc3RDb25maWcpIHtcbiAgcmVxdWVzdE1hcFtjb25maWcuZW52XSA9IG5ldyBDbG91ZGJhc2VSZXF1ZXN0KHtcbiAgICAuLi5jb25maWcsXG4gICAgdGhyb3c6IHRydWUsXG4gIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0QnlFbnZJZChlbnY6IHN0cmluZyk6IENsb3VkYmFzZVJlcXVlc3Qge1xuICByZXR1cm4gcmVxdWVzdE1hcFtlbnZdXG59XG4iXX0=