@cloudbase/app
Version:
cloudbase javascript sdk core
386 lines • 48.1 kB
JavaScript
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