data-transport
Version:
A simple and responsive transport
276 lines • 41.6 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Transport = exports.getAction = void 0;
var tslib_1 = require("tslib");
var constant_1 = require("./constant");
var utils_1 = require("./utils");
var DEFAULT_TIMEOUT = 60 * 1000;
var DEFAULT_RESPOND = true;
var DEFAULT_SILENT = false;
var DEFAULT_PREFIX = 'DataTransport';
var getAction = function (prefix, name) {
return "".concat(prefix, "-").concat(name.toString());
};
exports.getAction = getAction;
var getListenName = function (prefix, action) {
return action.replace(new RegExp("^".concat(prefix, "-")), '');
};
/**
* Create a base transport
*/
var Transport = /** @class */ (function () {
function Transport(_b) {
var listener = _b.listener, sender = _b.sender, _c = _b.timeout, timeout = _c === void 0 ? DEFAULT_TIMEOUT : _c, _d = _b.verbose, verbose = _d === void 0 ? false : _d, _e = _b.prefix, prefix = _e === void 0 ? DEFAULT_PREFIX : _e, _f = _b.listenKeys, listenKeys = _f === void 0 ? [] : _f, _g = _b.checkListen, checkListen = _g === void 0 ? true : _g, serializer = _b.serializer, logger = _b.logger;
var _this = this;
var _h, _j;
this[_a] = new Map();
this.id = (0, utils_1.generateId)();
this[constant_1.listensMapKey] = (_h = this[constant_1.listensMapKey]) !== null && _h !== void 0 ? _h : new Map();
this[constant_1.originalListensMapKey] = (_j = this[constant_1.originalListensMapKey]) !== null && _j !== void 0 ? _j : new Map();
this[constant_1.listenerKey] = listener.bind(this);
this[constant_1.senderKey] = sender.bind(this);
this[constant_1.timeoutKey] = timeout;
this[constant_1.prefixKey] = prefix;
this[constant_1.serializerKey] = serializer;
this[constant_1.verboseKey] = verbose;
this[constant_1.logKey] = logger;
new Set(listenKeys).forEach(function (key) {
var _b;
var fn = _this[key];
if (__DEV__) {
if (typeof fn !== 'function') {
console.warn("'".concat(key, "' is NOT a methods or function."));
}
}
_this[constant_1.originalListensMapKey].set(key, fn);
Object.assign(_this, (_b = {},
_b[key] = function () {
if (__DEV__) {
throw new Error("The method '".concat(key, "' is a listen function that can NOT be actively called."));
}
},
_b));
});
this[constant_1.originalListensMapKey].forEach(function (value, name) {
_this[constant_1.produceKey](name, value);
});
this[constant_1.listenKey] = function (options) {
var _b, _c;
if (_this[constant_1.verboseKey]) {
if (typeof _this[constant_1.logKey] === 'function' && options) {
_this[constant_1.logKey](options);
}
else {
console.info('DataTransport Receive: ', options);
}
}
if (options === null || options === void 0 ? void 0 : options[constant_1.transportKey]) {
var listenName = getListenName(_this[constant_1.prefixKey], options.action);
var hasListen = typeof _this[listenName] === 'function';
if (options.type === constant_1.transportType.response) {
var resolve = _this[constant_1.requestsMapKey].get(options[constant_1.transportKey]);
if (resolve) {
var response = options.response;
resolve(typeof response === 'string' && ((_b = _this[constant_1.serializerKey]) === null || _b === void 0 ? void 0 : _b.parse)
? _this[constant_1.serializerKey].parse(response)
: response);
}
else if (hasListen) {
if (__DEV__ && checkListen) {
console.warn("The type '".concat(options.action, "' event '").concat(options[constant_1.transportKey], "' has been resolved. Please check for a duplicate response."));
}
}
}
else if (options.type === constant_1.transportType.request) {
var respond = _this[constant_1.listensMapKey].get(options.action);
if (typeof respond === 'function') {
var request = options.request;
respond(typeof request === 'string' && ((_c = _this[constant_1.serializerKey]) === null || _c === void 0 ? void 0 : _c.parse)
? _this[constant_1.serializerKey].parse(request)
: request, tslib_1.__assign(tslib_1.__assign({}, options), { transportId: options[constant_1.transportKey], hasRespond: options.hasRespond }));
}
else if (hasListen) {
if (__DEV__ && checkListen) {
console.error("The listen method or function '".concat(listenName, "' is NOT decorated by decorator '@listen' or be added 'listenKeys' list."));
}
}
}
}
};
var dispose = this[constant_1.listenerKey](this[constant_1.listenKey]);
this.dispose = function () {
if (typeof dispose === 'function') {
_this[constant_1.requestsMapKey].clear();
_this[constant_1.listensMapKey].clear();
_this[constant_1.originalListensMapKey].clear();
return dispose();
}
else if (__DEV__) {
console.warn("The return value of the the '".concat(_this.constructor.name, "' transport's listener should be a 'dispose' function for removing the listener"));
}
};
}
Transport.prototype[(_a = constant_1.requestsMapKey, constant_1.produceKey)] = function (name, fn) {
var _this = this;
// https://github.com/microsoft/TypeScript/issues/40465
var action = (0, exports.getAction)(this[constant_1.prefixKey], name);
this[constant_1.listensMapKey].set(action, function (request, _b) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var response, data;
var _c;
var _d;
var hasRespond = _b.hasRespond, transportId = _b.transportId, _ = _b.request, args = tslib_1.__rest(_b, ["hasRespond", "transportId", "request"]);
return tslib_1.__generator(this, function (_e) {
switch (_e.label) {
case 0:
if (!(typeof fn === 'function')) return [3 /*break*/, 2];
return [4 /*yield*/, fn.apply(this, request)];
case 1:
response = _e.sent();
if (!hasRespond)
return [2 /*return*/];
data = tslib_1.__assign(tslib_1.__assign({}, args), (_c = { action: action, response: (typeof response !== 'undefined' &&
((_d = this[constant_1.serializerKey]) === null || _d === void 0 ? void 0 : _d.stringify)
? this[constant_1.serializerKey].stringify(response)
: response), hasRespond: hasRespond }, _c[constant_1.transportKey] = transportId, _c.type = constant_1.transportType.response, _c.responseId = this.id, _c));
this[constant_1.senderKey](data);
return [3 /*break*/, 3];
case 2: throw new Error("The listener for event ".concat(name, " should be a function."));
case 3: return [2 /*return*/];
}
});
}); });
};
/**
* Listen an event that transport data.
*
* @param name A transport action as listen message data action type
* @param fn A transport listener
*/
Transport.prototype.listen = function (name, fn) {
var _this = this;
if (typeof name === 'string') {
if (this[constant_1.originalListensMapKey].get(name)) {
throw new Error("Failed to listen to the event \"".concat(name, "\", the event \"").concat(name, "\" is already listened to."));
}
if (typeof fn === 'function') {
this[constant_1.originalListensMapKey].set(name, fn);
this[constant_1.produceKey](name, fn);
}
else {
throw new Error("The listener for event ".concat(name, " should be a function."));
}
}
else {
throw new Error("The event name \"".concat(name.toString(), "\" is not a string, it should be a string."));
}
return function () {
_this[constant_1.originalListensMapKey].delete(name);
var action = (0, exports.getAction)(_this[constant_1.prefixKey], name);
_this[constant_1.listensMapKey].delete(action);
};
};
/**
* Emit an event that transport data.
*
* @param emitOptions A option for the transport data
* @param request A request data
*
* @returns Return a response for the request.
*/
Transport.prototype.emit = function (options) {
var request = [];
for (var _i = 1; _i < arguments.length; _i++) {
request[_i - 1] = arguments[_i];
}
return tslib_1.__awaiter(this, void 0, void 0, function () {
var params, hasRespond, isSilent, timeout, name, transportId, action, rawRequestData, timeoutId, promise;
var _b;
var _this = this;
var _c, _d, _e, _f, _g;
return tslib_1.__generator(this, function (_h) {
switch (_h.label) {
case 0:
params = typeof options === 'object' ? options : {};
hasRespond = (_c = params.respond) !== null && _c !== void 0 ? _c : DEFAULT_RESPOND;
isSilent = (_d = params.silent) !== null && _d !== void 0 ? _d : DEFAULT_SILENT;
timeout = (_e = params.timeout) !== null && _e !== void 0 ? _e : this[constant_1.timeoutKey];
name = (_f = params.name) !== null && _f !== void 0 ? _f : options;
transportId = (0, utils_1.generateId)();
if (__DEV__ && (!name || typeof name !== 'string')) {
throw new Error("The event name should be a string, and it's required.");
}
action = (0, exports.getAction)(this[constant_1.prefixKey], name);
rawRequestData = tslib_1.__assign(tslib_1.__assign({}, (params._extra ? { _extra: params._extra } : {})), (_b = { type: constant_1.transportType.request, action: action, request: (typeof request !== 'undefined' && ((_g = this[constant_1.serializerKey]) === null || _g === void 0 ? void 0 : _g.stringify)
? this[constant_1.serializerKey].stringify(request)
: request), hasRespond: hasRespond }, _b[constant_1.transportKey] = transportId, _b.requestId = this.id, _b));
if (this[constant_1.verboseKey]) {
if (typeof this[constant_1.logKey] === 'function') {
this[constant_1.logKey](rawRequestData);
}
else {
console.info('DataTransport Send: ', rawRequestData);
}
}
if (!!hasRespond) return [3 /*break*/, 3];
if (!(this[constant_1.beforeEmitKey] && !params.skipBeforeEmit)) return [3 /*break*/, 2];
return [4 /*yield*/, this[constant_1.beforeEmitKey]];
case 1:
_h.sent();
_h.label = 2;
case 2:
this[constant_1.senderKey](rawRequestData);
return [2 /*return*/, Promise.resolve(undefined)];
case 3:
promise = Promise.race([
new Promise(function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(this[constant_1.beforeEmitKey] && !params.skipBeforeEmit)) return [3 /*break*/, 2];
return [4 /*yield*/, this[constant_1.beforeEmitKey]];
case 1:
_b.sent();
_b.label = 2;
case 2:
this[constant_1.requestsMapKey].set(transportId, resolve);
this[constant_1.senderKey](rawRequestData);
return [2 /*return*/];
}
});
}); }),
new Promise(function (_, reject) {
timeoutId = setTimeout(function () {
reject();
}, timeout);
}),
]);
return [2 /*return*/, promise
.then(function (response) {
// support Safari 10-11.1
clearTimeout(timeoutId);
_this[constant_1.requestsMapKey].delete(transportId);
return response;
})
.catch(function (error) {
clearTimeout(timeoutId);
_this[constant_1.requestsMapKey].delete(transportId);
if (typeof error === 'undefined') {
if (isSilent)
return;
console.warn("The event '".concat(action, "' timed out for ").concat(timeout, " seconds..."), rawRequestData);
}
else {
if (__DEV__) {
throw error;
}
}
})];
}
});
});
};
return Transport;
}());
exports.Transport = Transport;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3RyYW5zcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHVDQWlCb0I7QUFhcEIsaUNBQXFDO0FBRXJDLElBQU0sZUFBZSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDbEMsSUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDO0FBQzdCLElBQU0sY0FBYyxHQUFHLEtBQUssQ0FBQztBQUM3QixJQUFNLGNBQWMsR0FBRyxlQUFlLENBQUM7QUFFaEMsSUFBTSxTQUFTLEdBQUcsVUFBQyxNQUFjLEVBQUUsSUFBWTtJQUNwRCxPQUFBLFVBQUcsTUFBTSxjQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBRTtBQUE5QixDQUE4QixDQUFDO0FBRHBCLFFBQUEsU0FBUyxhQUNXO0FBQ2pDLElBQU0sYUFBYSxHQUFHLFVBQUMsTUFBYyxFQUFFLE1BQWM7SUFDbkQsT0FBQSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksTUFBTSxDQUFDLFdBQUksTUFBTSxNQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7QUFBN0MsQ0FBNkMsQ0FBQztBQUVoRDs7R0FFRztBQUNIO0lBbUJFLG1CQUFZLEVBVU87WUFUakIsUUFBUSxjQUFBLEVBQ1IsTUFBTSxZQUFBLEVBQ04sZUFBeUIsRUFBekIsT0FBTyxtQkFBRyxlQUFlLEtBQUEsRUFDekIsZUFBZSxFQUFmLE9BQU8sbUJBQUcsS0FBSyxLQUFBLEVBQ2YsY0FBdUIsRUFBdkIsTUFBTSxtQkFBRyxjQUFjLEtBQUEsRUFDdkIsa0JBQWUsRUFBZixVQUFVLG1CQUFHLEVBQUUsS0FBQSxFQUNmLG1CQUFrQixFQUFsQixXQUFXLG1CQUFHLElBQUksS0FBQSxFQUNsQixVQUFVLGdCQUFBLEVBQ1YsTUFBTSxZQUFBO1FBVFIsaUJBOEdDOztRQTFITyxRQUFnQixHQUEwQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBNkxyRSxPQUFFLEdBQUcsSUFB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b0NBQ3JCLE1BQU0sRUFBRSxDQUFDO2dDQUNYLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQzs0QkFDZCxDQUFDLENBQUM7eUJBQ0gsQ0FBQyxDQUFDO3dCQUNILHNCQUFPLE9BQU87aUNBQ1gsSUFBSSxDQUFDLFVBQUMsUUFBUTtnQ0FDYix5QkFBeUI7Z0NBQ3pCLFlBQVksQ0FBQyxTQUEyQixDQUFDLENBQUM7Z0NBQzFDLEtBQUksQ0FBQyx5QkFBYyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dDQUN6QyxPQUFPLFFBQVEsQ0FBQzs0QkFDbEIsQ0FBQyxDQUFDO2lDQUNELEtBQUssQ0FBQyxVQUFDLEtBQUs7Z0NBQ1gsWUFBWSxDQUFDLFNBQTJCLENBQUMsQ0FBQztnQ0FDMUMsS0FBSSxDQUFDLHlCQUFjLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7Z0NBQ3pDLElBQUksT0FBTyxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7b0NBQ2pDLElBQUksUUFBUTt3Q0FBRSxPQUFPO29DQUNyQixPQUFPLENBQUMsSUFBSSxDQUNWLHFCQUFjLE1BQU0sNkJBQW1CLE9BQU8sZ0JBQWEsRUFDM0QsY0FBYyxDQUNmLENBQUM7Z0NBQ0osQ0FBQztxQ0FBTSxDQUFDO29DQUNOLElBQUksT0FBTyxFQUFFLENBQUM7d0NBQ1osTUFBTSxLQUFLLENBQUM7b0NBQ2QsQ0FBQztnQ0FDSCxDQUFDOzRCQUNILENBQUMsQ0FBQyxFQUFDOzs7O0tBQ047SUFDSCxnQkFBQztBQUFELENBQUMsQUE1UkQsSUE0UkM7QUE1UnFCLDhCQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgbGlzdGVuZXJLZXksXG4gIG9yaWdpbmFsTGlzdGVuc01hcEtleSxcbiAgcmVxdWVzdHNNYXBLZXksXG4gIGxpc3RlbnNNYXBLZXksXG4gIHNlbmRlcktleSxcbiAgdGltZW91dEtleSxcbiAgdHJhbnNwb3J0S2V5LFxuICBwcmVmaXhLZXksXG4gIHRyYW5zcG9ydFR5cGUsXG4gIHByb2R1Y2VLZXksXG4gIGxpc3RlbktleSxcbiAgc2VyaWFsaXplcktleSxcbiAgbG9nS2V5LFxuICB2ZXJib3NlS2V5LFxuICBiZWZvcmVFbWl0S2V5LFxuICBiZWZvcmVFbWl0UmVzb2x2ZUtleSxcbn0gZnJvbSAnLi9jb25zdGFudCc7XG5pbXBvcnQgdHlwZSB7XG4gIEVtaXRPcHRpb25zLFxuICBJUmVxdWVzdCxcbiAgSVJlc3BvbnNlLFxuICBMaXN0ZW5lck9wdGlvbnMsXG4gIFJlcXVlc3QsXG4gIExpc3RlbnNNYXAsXG4gIFJlc3BvbnNlLFxuICBUcmFuc3BvcnRPcHRpb25zLFxuICBFbWl0UGFyYW1ldGVyLFxuICBCYXNlSW50ZXJhY3Rpb24sXG59IGZyb20gJy4vaW50ZXJmYWNlJztcbmltcG9ydCB7IGdlbmVyYXRlSWQgfSBmcm9tICcuL3V0aWxzJztcblxuY29uc3QgREVGQVVMVF9USU1FT1VUID0gNjAgKiAxMDAwO1xuY29uc3QgREVGQVVMVF9SRVNQT05EID0gdHJ1ZTtcbmNvbnN0IERFRkFVTFRfU0lMRU5UID0gZmFsc2U7XG5jb25zdCBERUZBVUxUX1BSRUZJWCA9ICdEYXRhVHJhbnNwb3J0JztcblxuZXhwb3J0IGNvbnN0IGdldEFjdGlvbiA9IChwcmVmaXg6IHN0cmluZywgbmFtZTogc3RyaW5nKSA9PlxuICBgJHtwcmVmaXh9LSR7bmFtZS50b1N0cmluZygpfWA7XG5jb25zdCBnZXRMaXN0ZW5OYW1lID0gKHByZWZpeDogc3RyaW5nLCBhY3Rpb246IHN0cmluZykgPT5cbiAgYWN0aW9uLnJlcGxhY2UobmV3IFJlZ0V4cChgXiR7cHJlZml4fS1gKSwgJycpO1xuXG4vKipcbiAqIENyZWF0ZSBhIGJhc2UgdHJhbnNwb3J0XG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUcmFuc3BvcnQ8VCBleHRlbmRzIEJhc2VJbnRlcmFjdGlvbiA9IGFueT4ge1xuICBwcml2YXRlIFtsaXN0ZW5lcktleV06IFRyYW5zcG9ydE9wdGlvbnNbJ2xpc3RlbmVyJ107XG4gIHByaXZhdGUgW2xpc3RlbktleV06IChvcHRpb25zPzogTGlzdGVuZXJPcHRpb25zKSA9PiB2b2lkO1xuICBwcml2YXRlIFtzZW5kZXJLZXldOiBUcmFuc3BvcnRPcHRpb25zWydzZW5kZXInXTtcbiAgcHJpdmF0ZSBbdGltZW91dEtleV06IFRyYW5zcG9ydE9wdGlvbnNbJ3RpbWVvdXQnXTtcbiAgcHJpdmF0ZSBbcHJlZml4S2V5XTogVHJhbnNwb3J0T3B0aW9uc1sncHJlZml4J107XG4gIHByaXZhdGUgW3NlcmlhbGl6ZXJLZXldOiBUcmFuc3BvcnRPcHRpb25zWydzZXJpYWxpemVyJ107XG4gIHByaXZhdGUgW3JlcXVlc3RzTWFwS2V5XTogTWFwPHN0cmluZywgKHZhbHVlOiB1bmtub3duKSA9PiB2b2lkPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBbbGlzdGVuc01hcEtleV0hOiBMaXN0ZW5zTWFwO1xuICBwcml2YXRlIFtvcmlnaW5hbExpc3RlbnNNYXBLZXldITogTWFwPHN0cmluZywgRnVuY3Rpb24+O1xuICBwcml2YXRlIFtsb2dLZXldPzogKGxpc3Rlbk9wdGlvbnM6IExpc3RlbmVyT3B0aW9uczxhbnk+KSA9PiB2b2lkO1xuICBwcml2YXRlIFt2ZXJib3NlS2V5XTogYm9vbGVhbjtcbiAgcHJvdGVjdGVkIFtiZWZvcmVFbWl0S2V5XT86IFByb21pc2U8dm9pZD47XG4gIHByb3RlY3RlZCBbYmVmb3JlRW1pdFJlc29sdmVLZXldPzogKCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIGRpc3Bvc2UgdHJhbnNwb3J0XG4gICAqL1xuICBwdWJsaWMgZGlzcG9zZTogKCkgPT4gYW55O1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBsaXN0ZW5lcixcbiAgICBzZW5kZXIsXG4gICAgdGltZW91dCA9IERFRkFVTFRfVElNRU9VVCxcbiAgICB2ZXJib3NlID0gZmFsc2UsXG4gICAgcHJlZml4ID0gREVGQVVMVF9QUkVGSVgsXG4gICAgbGlzdGVuS2V5cyA9IFtdLFxuICAgIGNoZWNrTGlzdGVuID0gdHJ1ZSxcbiAgICBzZXJpYWxpemVyLFxuICAgIGxvZ2dlcixcbiAgfTogVHJhbnNwb3J0T3B0aW9ucykge1xuICAgIHRoaXNbbGlzdGVuc01hcEtleV0gPSB0aGlzW2xpc3RlbnNNYXBLZXldID8/IG5ldyBNYXAoKTtcbiAgICB0aGlzW29yaWdpbmFsTGlzdGVuc01hcEtleV0gPSB0aGlzW29yaWdpbmFsTGlzdGVuc01hcEtleV0gPz8gbmV3IE1hcCgpO1xuICAgIHRoaXNbbGlzdGVuZXJLZXldID0gbGlzdGVuZXIuYmluZCh0aGlzKTtcbiAgICB0aGlzW3NlbmRlcktleV0gPSBzZW5kZXIuYmluZCh0aGlzKTtcbiAgICB0aGlzW3RpbWVvdXRLZXldID0gdGltZW91dDtcbiAgICB0aGlzW3ByZWZpeEtleV0gPSBwcmVmaXg7XG4gICAgdGhpc1tzZXJpYWxpemVyS2V5XSA9IHNlcmlhbGl6ZXI7XG4gICAgdGhpc1t2ZXJib3NlS2V5XSA9IHZlcmJvc2U7XG4gICAgdGhpc1tsb2dLZXldID0gbG9nZ2VyO1xuXG4gICAgbmV3IFNldChsaXN0ZW5LZXlzKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGZuID0gKHRoaXMgYXMgYW55IGFzIFJlY29yZDxzdHJpbmcsIEZ1bmN0aW9uPilba2V5XTtcbiAgICAgIGlmIChfX0RFVl9fKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYCcke2tleX0nIGlzIE5PVCBhIG1ldGhvZHMgb3IgZnVuY3Rpb24uYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXNbb3JpZ2luYWxMaXN0ZW5zTWFwS2V5XS5zZXQoa2V5LCBmbik7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMsIHtcbiAgICAgICAgW2tleV0oKSB7XG4gICAgICAgICAgaWYgKF9fREVWX18pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYFRoZSBtZXRob2QgJyR7a2V5fScgaXMgYSBsaXN0ZW4gZnVuY3Rpb24gdGhhdCBjYW4gTk9UIGJlIGFjdGl2ZWx5IGNhbGxlZC5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGhpc1tvcmlnaW5hbExpc3RlbnNNYXBLZXldLmZvckVhY2goKHZhbHVlLCBuYW1lKSA9PiB7XG4gICAgICB0aGlzW3Byb2R1Y2VLZXldKG5hbWUsIHZhbHVlKTtcbiAgICB9KTtcblxuICAgIHRoaXNbbGlzdGVuS2V5XSA9IChvcHRpb25zPzogTGlzdGVuZXJPcHRpb25zKSA9PiB7XG4gICAgICBpZiAodGhpc1t2ZXJib3NlS2V5XSkge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXNbbG9nS2V5XSA9PT0gJ2Z1bmN0aW9uJyAmJiBvcHRpb25zKSB7XG4gICAgICAgICAgdGhpc1tsb2dLZXldIShvcHRpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmluZm8oJ0RhdGFUcmFuc3BvcnQgUmVjZWl2ZTogJywgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zPy5bdHJhbnNwb3J0S2V5XSkge1xuICAgICAgICBjb25zdCBsaXN0ZW5OYW1lID0gZ2V0TGlzdGVuTmFtZSh0aGlzW3ByZWZpeEtleV0hLCBvcHRpb25zLmFjdGlvbik7XG4gICAgICAgIGNvbnN0IGhhc0xpc3RlbiA9IHR5cGVvZiAodGhpcyBhcyBhbnkpW2xpc3Rlbk5hbWVdID09PSAnZnVuY3Rpb24nO1xuICAgICAgICBpZiAoKG9wdGlvbnMgYXMgSVJlc3BvbnNlKS50eXBlID09PSB0cmFuc3BvcnRUeXBlLnJlc3BvbnNlKSB7XG4gICAgICAgICAgY29uc3QgcmVzb2x2ZSA9IHRoaXNbcmVxdWVzdHNNYXBLZXldLmdldChvcHRpb25zW3RyYW5zcG9ydEtleV0pO1xuICAgICAgICAgIGlmIChyZXNvbHZlKSB7XG4gICAgICAgICAgICBjb25zdCB7IHJlc3BvbnNlIH0gPSBvcHRpb25zIGFzIElSZXNwb25zZTtcbiAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgIHR5cGVvZiByZXNwb25zZSA9PT0gJ3N0cmluZycgJiYgdGhpc1tzZXJpYWxpemVyS2V5XT8ucGFyc2VcbiAgICAgICAgICAgICAgICA/IHRoaXNbc2VyaWFsaXplcktleV0hLnBhcnNlIShyZXNwb25zZSlcbiAgICAgICAgICAgICAgICA6IHJlc3BvbnNlXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzTGlzdGVuKSB7XG4gICAgICAgICAgICBpZiAoX19ERVZfXyAmJiBjaGVja0xpc3Rlbikge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgYFRoZSB0eXBlICcke29wdGlvbnMuYWN0aW9ufScgZXZlbnQgJyR7b3B0aW9uc1t0cmFuc3BvcnRLZXldfScgaGFzIGJlZW4gcmVzb2x2ZWQuIFBsZWFzZSBjaGVjayBmb3IgYSBkdXBsaWNhdGUgcmVzcG9uc2UuYFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICgob3B0aW9ucyBhcyBJUmVxdWVzdCkudHlwZSA9PT0gdHJhbnNwb3J0VHlwZS5yZXF1ZXN0KSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uZCA9IHRoaXNbbGlzdGVuc01hcEtleV0uZ2V0KG9wdGlvbnMuYWN0aW9uKTtcbiAgICAgICAgICBpZiAodHlwZW9mIHJlc3BvbmQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgcmVxdWVzdCB9ID0gb3B0aW9ucyBhcyBJUmVxdWVzdDtcbiAgICAgICAgICAgIHJlc3BvbmQoXG4gICAgICAgICAgICAgIHR5cGVvZiByZXF1ZXN0ID09PSAnc3RyaW5nJyAmJiB0aGlzW3NlcmlhbGl6ZXJLZXldPy5wYXJzZVxuICAgICAgICAgICAgICAgID8gdGhpc1tzZXJpYWxpemVyS2V5XSEucGFyc2UhKHJlcXVlc3QpXG4gICAgICAgICAgICAgICAgOiByZXF1ZXN0LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICAgICAgICB0cmFuc3BvcnRJZDogb3B0aW9uc1t0cmFuc3BvcnRLZXldLFxuICAgICAgICAgICAgICAgIGhhc1Jlc3BvbmQ6IChvcHRpb25zIGFzIElSZXF1ZXN0KS5oYXNSZXNwb25kLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzTGlzdGVuKSB7XG4gICAgICAgICAgICBpZiAoX19ERVZfXyAmJiBjaGVja0xpc3Rlbikge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICAgIGBUaGUgbGlzdGVuIG1ldGhvZCBvciBmdW5jdGlvbiAnJHtsaXN0ZW5OYW1lfScgaXMgTk9UIGRlY29yYXRlZCBieSBkZWNvcmF0b3IgJ0BsaXN0ZW4nIG9yIGJlIGFkZGVkICdsaXN0ZW5LZXlzJyBsaXN0LmBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgZGlzcG9zZSA9IHRoaXNbbGlzdGVuZXJLZXldKHRoaXNbbGlzdGVuS2V5XSk7XG5cbiAgICB0aGlzLmRpc3Bvc2UgPSAoKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGRpc3Bvc2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpc1tyZXF1ZXN0c01hcEtleV0uY2xlYXIoKTtcbiAgICAgICAgdGhpc1tsaXN0ZW5zTWFwS2V5XS5jbGVhcigpO1xuICAgICAgICB0aGlzW29yaWdpbmFsTGlzdGVuc01hcEtleV0uY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIGRpc3Bvc2UoKTtcbiAgICAgIH0gZWxzZSBpZiAoX19ERVZfXykge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHRoZSAnJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9JyB0cmFuc3BvcnQncyBsaXN0ZW5lciBzaG91bGQgYmUgYSAnZGlzcG9zZScgZnVuY3Rpb24gZm9yIHJlbW92aW5nIHRoZSBsaXN0ZW5lcmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBbcHJvZHVjZUtleV08SyBleHRlbmRzIHN0cmluZywgUCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIEZ1bmN0aW9uPj4oXG4gICAgbmFtZTogSyxcbiAgICBmbjogUFtLXVxuICApIHtcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzQwNDY1XG4gICAgY29uc3QgYWN0aW9uID0gZ2V0QWN0aW9uKHRoaXNbcHJlZml4S2V5XSEsIG5hbWUpO1xuICAgIHRoaXNbbGlzdGVuc01hcEtleV0uc2V0KFxuICAgICAgYWN0aW9uLFxuICAgICAgYXN5bmMgKHJlcXVlc3QsIHsgaGFzUmVzcG9uZCwgdHJhbnNwb3J0SWQsIHJlcXVlc3Q6IF8sIC4uLmFyZ3MgfSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2U6IFJlc3BvbnNlPFBbS10+ID0gYXdhaXQgZm4uYXBwbHkodGhpcywgcmVxdWVzdCk7XG4gICAgICAgICAgaWYgKCFoYXNSZXNwb25kKSByZXR1cm47XG4gICAgICAgICAgY29uc3QgZGF0YTogSVJlc3BvbnNlID0ge1xuICAgICAgICAgICAgLi4uYXJncyxcbiAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgIHJlc3BvbnNlOiAodHlwZW9mIHJlc3BvbnNlICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgdGhpc1tzZXJpYWxpemVyS2V5XT8uc3RyaW5naWZ5XG4gICAgICAgICAgICAgID8gdGhpc1tzZXJpYWxpemVyS2V5XSEuc3RyaW5naWZ5IShyZXNwb25zZSlcbiAgICAgICAgICAgICAgOiByZXNwb25zZSkgYXMgc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgaGFzUmVzcG9uZCxcbiAgICAgICAgICAgIFt0cmFuc3BvcnRLZXldOiB0cmFuc3BvcnRJZCxcbiAgICAgICAgICAgIHR5cGU6IHRyYW5zcG9ydFR5cGUucmVzcG9uc2UsXG4gICAgICAgICAgICByZXNwb25zZUlkOiB0aGlzLmlkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpc1tzZW5kZXJLZXldKGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBUaGUgbGlzdGVuZXIgZm9yIGV2ZW50ICR7bmFtZX0gc2hvdWxkIGJlIGEgZnVuY3Rpb24uYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RlbiBhbiBldmVudCB0aGF0IHRyYW5zcG9ydCBkYXRhLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBBIHRyYW5zcG9ydCBhY3Rpb24gYXMgbGlzdGVuIG1lc3NhZ2UgZGF0YSBhY3Rpb24gdHlwZVxuICAgKiBAcGFyYW0gZm4gQSB0cmFuc3BvcnQgbGlzdGVuZXJcbiAgICovXG4gIHB1YmxpYyBsaXN0ZW48SyBleHRlbmRzIGtleW9mIFRbJ2xpc3RlbiddPihuYW1lOiBLLCBmbjogVFsnbGlzdGVuJ11bS10pIHtcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAodGhpc1tvcmlnaW5hbExpc3RlbnNNYXBLZXldLmdldChuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYEZhaWxlZCB0byBsaXN0ZW4gdG8gdGhlIGV2ZW50IFwiJHtuYW1lfVwiLCB0aGUgZXZlbnQgXCIke25hbWV9XCIgaXMgYWxyZWFkeSBsaXN0ZW5lZCB0by5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXNbb3JpZ2luYWxMaXN0ZW5zTWFwS2V5XS5zZXQobmFtZSwgZm4pO1xuICAgICAgICB0aGlzW3Byb2R1Y2VLZXldKG5hbWUsIGZuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGxpc3RlbmVyIGZvciBldmVudCAke25hbWV9IHNob3VsZCBiZSBhIGZ1bmN0aW9uLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBUaGUgZXZlbnQgbmFtZSBcIiR7bmFtZS50b1N0cmluZygpfVwiIGlzIG5vdCBhIHN0cmluZywgaXQgc2hvdWxkIGJlIGEgc3RyaW5nLmBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0aGlzW29yaWdpbmFsTGlzdGVuc01hcEtleV0uZGVsZXRlKG5hbWUpO1xuICAgICAgY29uc3QgYWN0aW9uID0gZ2V0QWN0aW9uKHRoaXNbcHJlZml4S2V5XSEsIG5hbWUpO1xuICAgICAgdGhpc1tsaXN0ZW5zTWFwS2V5XS5kZWxldGUoYWN0aW9uKTtcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGlkID0gZ2VuZXJhdGVJZCgpO1xuXG4gIC8qKlxuICAgKiBFbWl0IGFuIGV2ZW50IHRoYXQgdHJhbnNwb3J0IGRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSBlbWl0T3B0aW9ucyBBIG9wdGlvbiBmb3IgdGhlIHRyYW5zcG9ydCBkYXRhXG4gICAqIEBwYXJhbSByZXF1ZXN0IEEgcmVxdWVzdCBkYXRhXG4gICAqXG4gICAqIEByZXR1cm5zIFJldHVybiBhIHJlc3BvbnNlIGZvciB0aGUgcmVxdWVzdC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBlbWl0PEsgZXh0ZW5kcyBrZXlvZiBUWydlbWl0J10+KFxuICAgIG9wdGlvbnM6IEVtaXRPcHRpb25zPEs+LFxuICAgIC4uLnJlcXVlc3Q6IFJlcXVlc3Q8VFsnZW1pdCddW0tdPlxuICApOiBQcm9taXNlPFJlc3BvbnNlPFRbJ2VtaXQnXVtLXT4+IHtcbiAgICBjb25zdCBwYXJhbXMgPVxuICAgICAgdHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnID8gb3B0aW9ucyA6ICh7fSBhcyBFbWl0UGFyYW1ldGVyPEs+KTtcbiAgICBjb25zdCBoYXNSZXNwb25kID0gcGFyYW1zLnJlc3BvbmQgPz8gREVGQVVMVF9SRVNQT05EO1xuICAgIGNvbnN0IGlzU2lsZW50ID0gcGFyYW1zLnNpbGVudCA/PyBERUZBVUxUX1NJTEVOVDtcbiAgICBjb25zdCB0aW1lb3V0ID0gcGFyYW1zLnRpbWVvdXQgPz8gdGhpc1t0aW1lb3V0S2V5XTtcbiAgICBjb25zdCBuYW1lID0gcGFyYW1zLm5hbWUgPz8gb3B0aW9ucztcbiAgICBjb25zdCB0cmFuc3BvcnRJZCA9IGdlbmVyYXRlSWQoKTtcbiAgICBpZiAoX19ERVZfXyAmJiAoIW5hbWUgfHwgdHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgZXZlbnQgbmFtZSBzaG91bGQgYmUgYSBzdHJpbmcsIGFuZCBpdCdzIHJlcXVpcmVkLmApO1xuICAgIH1cbiAgICBjb25zdCBhY3Rpb24gPSBnZXRBY3Rpb24odGhpc1twcmVmaXhLZXldISwgbmFtZSBhcyBzdHJpbmcpO1xuICAgIGNvbnN0IHJhd1JlcXVlc3REYXRhOiBJUmVxdWVzdCA9IHtcbiAgICAgIC4uLihwYXJhbXMuX2V4dHJhID8geyBfZXh0cmE6IHBhcmFtcy5fZXh0cmEgfSA6IHt9KSxcbiAgICAgIHR5cGU6IHRyYW5zcG9ydFR5cGUucmVxdWVzdCxcbiAgICAgIGFjdGlvbixcbiAgICAgIHJlcXVlc3Q6ICh0eXBlb2YgcmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpc1tzZXJpYWxpemVyS2V5XT8uc3RyaW5naWZ5XG4gICAgICAgID8gdGhpc1tzZXJpYWxpemVyS2V5XSEuc3RyaW5naWZ5IShyZXF1ZXN0KVxuICAgICAgICA6IHJlcXVlc3QpIGFzIHVua25vd25bXSxcbiAgICAgIGhhc1Jlc3BvbmQsXG4gICAgICBbdHJhbnNwb3J0S2V5XTogdHJhbnNwb3J0SWQsXG4gICAgICByZXF1ZXN0SWQ6IHRoaXMuaWQsXG4gICAgfTtcbiAgICBpZiAodGhpc1t2ZXJib3NlS2V5XSkge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzW2xvZ0tleV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpc1tsb2dLZXldIShyYXdSZXF1ZXN0RGF0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmluZm8oJ0RhdGFUcmFuc3BvcnQgU2VuZDogJywgcmF3UmVxdWVzdERhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWhhc1Jlc3BvbmQpIHtcbiAgICAgIGlmICh0aGlzW2JlZm9yZUVtaXRLZXldICYmICFwYXJhbXMuc2tpcEJlZm9yZUVtaXQpIHtcbiAgICAgICAgYXdhaXQgdGhpc1tiZWZvcmVFbWl0S2V5XTtcbiAgICAgIH1cbiAgICAgIHRoaXNbc2VuZGVyS2V5XShyYXdSZXF1ZXN0RGF0YSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVuZGVmaW5lZCBhcyBSZXNwb25zZTxUWydlbWl0J11bS10+KTtcbiAgICB9XG4gICAgbGV0IHRpbWVvdXRJZDogTm9kZUpTLlRpbWVvdXQgfCBudW1iZXI7XG4gICAgY29uc3QgcHJvbWlzZSA9IFByb21pc2UucmFjZTxhbnk+KFtcbiAgICAgIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGlmICh0aGlzW2JlZm9yZUVtaXRLZXldICYmICFwYXJhbXMuc2tpcEJlZm9yZUVtaXQpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzW2JlZm9yZUVtaXRLZXldO1xuICAgICAgICB9XG4gICAgICAgIHRoaXNbcmVxdWVzdHNNYXBLZXldLnNldCh0cmFuc3BvcnRJZCwgcmVzb2x2ZSk7XG4gICAgICAgIHRoaXNbc2VuZGVyS2V5XShyYXdSZXF1ZXN0RGF0YSk7XG4gICAgICB9KSxcbiAgICAgIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+IHtcbiAgICAgICAgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgfSksXG4gICAgXSk7XG4gICAgcmV0dXJuIHByb21pc2VcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAvLyBzdXBwb3J0IFNhZmFyaSAxMC0xMS4xXG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQgYXMgTm9kZUpTLlRpbWVvdXQpO1xuICAgICAgICB0aGlzW3JlcXVlc3RzTWFwS2V5XS5kZWxldGUodHJhbnNwb3J0SWQpO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkIGFzIE5vZGVKUy5UaW1lb3V0KTtcbiAgICAgICAgdGhpc1tyZXF1ZXN0c01hcEtleV0uZGVsZXRlKHRyYW5zcG9ydElkKTtcbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBpZiAoaXNTaWxlbnQpIHJldHVybjtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgVGhlIGV2ZW50ICcke2FjdGlvbn0nIHRpbWVkIG91dCBmb3IgJHt0aW1lb3V0fSBzZWNvbmRzLi4uYCxcbiAgICAgICAgICAgIHJhd1JlcXVlc3REYXRhXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoX19ERVZfXykge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxufVxuIl19