@synerty/vortexjs
Version:
Custom observable data serialisation and routing based on Angular 2+
170 lines • 22.2 kB
JavaScript
import { bind, dateStr, getFiltStr } from "./UtilMisc";
import { VortexClientABC } from "./VortexClientABC";
import { PayloadEnvelope } from "./PayloadEnvelope";
export class VortexClientHttp extends VortexClientABC {
/**
* RapUI VortexService, This class is responsible for sending and receiving payloads to/from
* the server.
*/
lastConn = null;
constructor(vortexStatusService, url, vortexClientName) {
super(vortexStatusService, url, vortexClientName);
}
shutdown() {
if (this.lastConn) {
this.lastConn.shutdown();
this.lastConn = null;
}
return Promise.resolve();
}
setClosedByConnection() {
this.setClosed();
}
sendVortexMsg(vortexMsgs) {
this.lastConn = new _VortexClientHttpConnection(this, this.vortexStatusService, (payload) => this.receive(payload), () => this.beat());
this.lastConn.send(vortexMsgs);
// console.log(dateStr() + "Sent payload with filt : " + JSON.stringify(payload.filt));
}
}
// ############################################################################
class _VortexClientHttpConnection {
vortex;
vortexStatusService;
receiveCallback;
vortexBeatCallback;
static RECONNECT_SIZE_LIMIT = 20 * 1024 * 1024; // 20 megabytes
_vortex;
_http;
_updateTimer;
_responseParseIndex;
_closing;
_aborting;
constructor(vortex, vortexStatusService, receiveCallback, vortexBeatCallback) {
this.vortex = vortex;
this.vortexStatusService = vortexStatusService;
this.receiveCallback = receiveCallback;
this.vortexBeatCallback = vortexBeatCallback;
let self = this;
let randArg = Math.random() + "." + new Date().getTime();
let args = {
vortexUuid: vortex.uuid,
vortexName: vortex.name,
__randArg__: randArg,
};
self._http = new XMLHttpRequest();
self._http.open("POST", self.vortex.url + getFiltStr(args), true);
self._updateTimer = null;
// Good events
self._http.onloadstart = function (e) {
self._received();
// Force a 50-millisecond timer, as some browsers don't call "onprogress"
// very often.
self._updateTimer = setInterval(function () {
self._received();
}, 50);
};
self._http.onprogress = function (e) {
self._received();
};
self._http.onload = function (e) {
if (self._updateTimer)
clearInterval(self._updateTimer);
self._received();
};
// Bad events
self._http.onabort = bind(self, self._error);
self._http.onerror = bind(self, self._error);
self._http.ontimeout = bind(self, self._error);
self._responseParseIndex = 0;
self._closing = false;
self._aborting = false;
}
shutdown() {
this._closing = true;
if (this._http)
this._http.abort();
}
send(vortexMsgs) {
let data = "";
for (let vortexMsg of vortexMsgs) {
// Serialise the payload
data += vortexMsg + ".";
}
// console.log("sending payload");
// console.log(xmlStr);
this._http.send(data);
}
_received() {
let self = this;
/*
* Received
*
* Called when progress is made on receiving data from the vortex server.
*
* This means that it needs to be able to handle : * partial payloads (in
* which case it does nothing) * multiple payloads (in which case, it breaks
* them up, parses them and sends them to vortex individually)
*/
if (self._aborting)
return;
// If we receive something that is not valid vortex data, then reload the page
// This typically occurs when we're receving HTML because we're not logged in.
if (/^</.test(self._http.responseText)) {
self.vortex.setClosedByConnection();
self._closing = true;
self._aborting = true;
self._http.abort();
location.reload();
return;
}
// Split out the payloads of data, they are delimited by a '.'
let data = self._http.responseText.substr(self._responseParseIndex);
let payloadSeparatorIndex = data.indexOf(".");
while (payloadSeparatorIndex !== -1) {
self._responseParseIndex += payloadSeparatorIndex + 1;
// Get the b64encoded string
let vortexStr = data.substr(0, payloadSeparatorIndex);
if (vortexStr.length === 0) {
self.vortexBeatCallback();
}
else {
// Create payload object from it
// Send to vortex
PayloadEnvelope.fromVortexMsg(vortexStr)
.then((pe) => self.receiveCallback(pe))
.catch((e) => console.log(`${dateStr()} An error occured deserialising ${e}`));
}
data = self._http.responseText.substr(self._responseParseIndex);
payloadSeparatorIndex = data.indexOf(".");
}
// In the event that the browser is buffering all this data, we should
// reconnect to allow the browser to cleanup.
if (self._http.responseText.length >=
_VortexClientHttpConnection.RECONNECT_SIZE_LIMIT &&
!self._closing) {
self._closing = true;
self.vortex.reconnect();
}
}
_error(e) {
let self = this;
if (self._updateTimer)
clearInterval(self._updateTimer);
if (self._aborting || this._closing)
return;
let msg = "";
if (e.type === "abort") {
msg = "Request was aborted and not by VortexJS";
}
else {
try {
msg = e.toString();
}
catch (e) { }
}
this.vortexStatusService.setOnline(false);
this.vortexStatusService.logError(msg);
// console.log("VortexConnection, connection errored out: " + msg);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVm9ydGV4Q2xpZW50SHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy92b3J0ZXgvVm9ydGV4Q2xpZW50SHR0cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXBELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQVVwRCxNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsZUFBZTtJQUNqRDs7O09BR0c7SUFDSyxRQUFRLEdBQXVDLElBQUksQ0FBQztJQUU1RCxZQUNJLG1CQUF3QyxFQUN4QyxHQUFXLEVBQ1gsZ0JBQXdCO1FBRXhCLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRVMsUUFBUTtRQUNkLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7U0FDeEI7UUFDRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQscUJBQXFCO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRVMsYUFBYSxDQUFDLFVBQW9CO1FBQ3hDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSwyQkFBMkIsQ0FDM0MsSUFBSSxFQUNKLElBQUksQ0FBQyxtQkFBbUIsRUFDeEIsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQ2xDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FDcEIsQ0FBQztRQUNGLElBQUks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QUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV4RCxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBRTVDLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUViLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDcEIsR0FBRyxHQUFHLHlDQUF5QyxDQUFDO1NBQ25EO2FBQU07WUFDSCxJQUFJO2dCQUNBLEdBQUcsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7YUFDdEI7WUFBQyxPQUFPLENBQUMsRUFBRSxHQUFFO1NBQ2pCO1FBRUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLG1FQUFtRTtJQUN2RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYmluZCwgZGF0ZVN0ciwgZ2V0RmlsdFN0ciB9IGZyb20gXCIuL1V0aWxNaXNjXCI7XG5pbXBvcnQgeyBWb3J0ZXhDbGllbnRBQkMgfSBmcm9tIFwiLi9Wb3J0ZXhDbGllbnRBQkNcIjtcbmltcG9ydCB7IFZvcnRleFN0YXR1c1NlcnZpY2UgfSBmcm9tIFwiLi9Wb3J0ZXhTdGF0dXNTZXJ2aWNlXCI7XG5pbXBvcnQgeyBQYXlsb2FkRW52ZWxvcGUgfSBmcm9tIFwiLi9QYXlsb2FkRW52ZWxvcGVcIjtcblxuaW50ZXJmYWNlIFJlY2VpdmVQYXlsb2FkQ2FsbGFibGUge1xuICAgIChQYXlsb2FkKTogdm9pZDtcbn1cblxuaW50ZXJmYWNlIFZvcnRleEJlYXRDYWxsYWJsZSB7XG4gICAgKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBWb3J0ZXhDbGllbnRIdHRwIGV4dGVuZHMgVm9ydGV4Q2xpZW50QUJDIHtcbiAgICAvKipcbiAgICAgKiBSYXBVSSBWb3J0ZXhTZXJ2aWNlLCBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBzZW5kaW5nIGFuZCByZWNlaXZpbmcgcGF5bG9hZHMgdG8vZnJvbVxuICAgICAqIHRoZSBzZXJ2ZXIuXG4gICAgICovXG4gICAgcHJpdmF0ZSBsYXN0Q29ubjogX1ZvcnRleENsaWVudEh0dHBDb25uZWN0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgdm9ydGV4U3RhdHVzU2VydmljZTogVm9ydGV4U3RhdHVzU2VydmljZSxcbiAgICAgICAgdXJsOiBzdHJpbmcsXG4gICAgICAgIHZvcnRleENsaWVudE5hbWU6IHN0cmluZ1xuICAgICkge1xuICAgICAgICBzdXBlcih2b3J0ZXhTdGF0dXNTZXJ2aWNlLCB1cmwsIHZvcnRleENsaWVudE5hbWUpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMubGFzdENvbm4pIHtcbiAgICAgICAgICAgIHRoaXMubGFzdENvbm4uc2h1dGRvd24oKTtcbiAgICAgICAgICAgIHRoaXMubGFzdENvbm4gPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBzZXRDbG9zZWRCeUNvbm5lY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc2V0Q2xvc2VkKCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNlbmRWb3J0ZXhNc2codm9ydGV4TXNnczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sYXN0Q29ubiA9IG5ldyBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24oXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgdGhpcy52b3J0ZXhTdGF0dXNTZXJ2aWNlLFxuICAgICAgICAgICAgKHBheWxvYWQpID0+IHRoaXMucmVjZWl2ZShwYXlsb2FkKSxcbiAgICAgICAgICAgICgpID0+IHRoaXMuYmVhdCgpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubGFzdENvbm4uc2VuZCh2b3J0ZXhNc2dzKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2coZGF0ZVN0cigpICsgXCJTZW50IHBheWxvYWQgd2l0aCBmaWx0IDogXCIgKyBKU09OLnN0cmluZ2lmeShwYXlsb2FkLmZpbHQpKTtcbiAgICB9XG59XG5cbi8vICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbmNsYXNzIF9Wb3J0ZXhDbGllbnRIdHRwQ29ubmVjdGlvbiB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgUkVDT05ORUNUX1NJWkVfTElNSVQgPSAyMCAqIDEwMjQgKiAxMDI0OyAvLyAyMCBtZWdhYnl0ZXNcblxuICAgIHByaXZhdGUgX3ZvcnRleDogVm9ydGV4Q2xpZW50SHR0cDtcbiAgICBwcml2YXRlIF9odHRwOiBYTUxIdHRwUmVxdWVzdDtcbiAgICBwcml2YXRlIF91cGRhdGVUaW1lcjogYW55O1xuICAgIHByaXZhdGUgX3Jlc3BvbnNlUGFyc2VJbmRleDogbnVtYmVyO1xuICAgIHByaXZhdGUgX2Nsb3Npbmc6IGJvb2xlYW47XG4gICAgcHJpdmF0ZSBfYWJvcnRpbmc6IGJvb2xlYW47XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSB2b3J0ZXg6IFZvcnRleENsaWVudEh0dHAsXG4gICAgICAgIHByaXZhdGUgdm9ydGV4U3RhdHVzU2VydmljZTogVm9ydGV4U3RhdHVzU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWNlaXZlQ2FsbGJhY2s6IFJlY2VpdmVQYXlsb2FkQ2FsbGFibGUsXG4gICAgICAgIHByaXZhdGUgdm9ydGV4QmVhdENhbGxiYWNrOiBWb3J0ZXhCZWF0Q2FsbGFibGVcbiAgICApIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGxldCByYW5kQXJnID0gTWF0aC5yYW5kb20oKSArIFwiLlwiICsgbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGxldCBhcmdzID0ge1xuICAgICAgICAgICAgdm9ydGV4VXVpZDogdm9ydGV4LnV1aWQsXG4gICAgICAgICAgICB2b3J0ZXhOYW1lOiB2b3J0ZXgubmFtZSxcbiAgICAgICAgICAgIF9fcmFuZEFyZ19fOiByYW5kQXJnLFxuICAgICAgICB9O1xuXG4gICAgICAgIHNlbGYuX2h0dHAgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgc2VsZi5faHR0cC5vcGVuKFwiUE9TVFwiLCBzZWxmLnZvcnRleC51cmwgKyBnZXRGaWx0U3RyKGFyZ3MpLCB0cnVlKTtcblxuICAgICAgICBzZWxmLl91cGRhdGVUaW1lciA9IG51bGw7XG5cbiAgICAgICAgLy8gR29vZCBldmVudHNcbiAgICAgICAgc2VsZi5faHR0cC5vbmxvYWRzdGFydCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuXG4gICAgICAgICAgICAvLyBGb3JjZSBhIDUwLW1pbGxpc2Vjb25kIHRpbWVyLCBhcyBzb21lIGJyb3dzZXJzIGRvbid0IGNhbGwgXCJvbnByb2dyZXNzXCJcbiAgICAgICAgICAgIC8vIHZlcnkgb2Z0ZW4uXG4gICAgICAgICAgICBzZWxmLl91cGRhdGVUaW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuICAgICAgICAgICAgfSwgNTApO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNlbGYuX2h0dHAub25wcm9ncmVzcyA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNlbGYuX2h0dHAub25sb2FkID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmIChzZWxmLl91cGRhdGVUaW1lcikgY2xlYXJJbnRlcnZhbChzZWxmLl91cGRhdGVUaW1lcik7XG4gICAgICAgICAgICBzZWxmLl9yZWNlaXZlZCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEJhZCBldmVudHNcbiAgICAgICAgc2VsZi5faHR0cC5vbmFib3J0ID0gYmluZChzZWxmLCBzZWxmLl9lcnJvcik7XG4gICAgICAgIHNlbGYuX2h0dHAub25lcnJvciA9IGJpbmQoc2VsZiwgc2VsZi5fZXJyb3IpO1xuICAgICAgICBzZWxmLl9odHRwLm9udGltZW91dCA9IGJpbmQoc2VsZiwgc2VsZi5fZXJyb3IpO1xuXG4gICAgICAgIHNlbGYuX3Jlc3BvbnNlUGFyc2VJbmRleCA9IDA7XG4gICAgICAgIHNlbGYuX2Nsb3NpbmcgPSBmYWxzZTtcbiAgICAgICAgc2VsZi5fYWJvcnRpbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBzaHV0ZG93bigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fY2xvc2luZyA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLl9odHRwKSB0aGlzLl9odHRwLmFib3J0KCk7XG4gICAgfVxuXG4gICAgc2VuZCh2b3J0ZXhNc2dzOiBzdHJpbmdbXSkge1xuICAgICAgICBsZXQgZGF0YSA9IFwiXCI7XG5cbiAgICAgICAgZm9yIChsZXQgdm9ydGV4TXNnIG9mIHZvcnRleE1zZ3MpIHtcbiAgICAgICAgICAgIC8vIFNlcmlhbGlzZSB0aGUgcGF5bG9hZFxuICAgICAgICAgICAgZGF0YSArPSB2b3J0ZXhNc2cgKyBcIi5cIjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwic2VuZGluZyBwYXlsb2FkXCIpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyh4bWxTdHIpO1xuICAgICAgICB0aGlzLl9odHRwLnNlbmQoZGF0YSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVjZWl2ZWQoKSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcbiAgICAgICAgLypcbiAgICAgICAgICogUmVjZWl2ZWRcbiAgICAgICAgICpcbiAgICAgICAgICogQ2FsbGVkIHdoZW4gcHJvZ3Jlc3MgaXMgbWFkZSBvbiByZWNlaXZpbmcgZGF0YSBmcm9tIHRoZSB2b3J0ZXggc2VydmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGlzIG1lYW5zIHRoYXQgaXQgbmVlZHMgdG8gYmUgYWJsZSB0byBoYW5kbGUgOiAqIHBhcnRpYWwgcGF5bG9hZHMgKGluXG4gICAgICAgICAqIHdoaWNoIGNhc2UgaXQgZG9lcyBub3RoaW5nKSAqIG11bHRpcGxlIHBheWxvYWRzIChpbiB3aGljaCBjYXNlLCBpdCBicmVha3NcbiAgICAgICAgICogdGhlbSB1cCwgcGFyc2VzIHRoZW0gYW5kIHNlbmRzIHRoZW0gdG8gdm9ydGV4IGluZGl2aWR1YWxseSlcbiAgICAgICAgICovXG5cbiAgICAgICAgaWYgKHNlbGYuX2Fib3J0aW5nKSByZXR1cm47XG5cbiAgICAgICAgLy8gSWYgd2UgcmVjZWl2ZSBzb21ldGhpbmcgdGhhdCBpcyBub3QgdmFsaWQgdm9ydGV4IGRhdGEsIHRoZW4gcmVsb2FkIHRoZSBwYWdlXG4gICAgICAgIC8vIFRoaXMgdHlwaWNhbGx5IG9jY3VycyB3aGVuIHdlJ3JlIHJlY2V2aW5nIEhUTUwgYmVjYXVzZSB3ZSdyZSBub3QgbG9nZ2VkIGluLlxuICAgICAgICBpZiAoL148Ly50ZXN0KHNlbGYuX2h0dHAucmVzcG9uc2VUZXh0KSkge1xuICAgICAgICAgICAgc2VsZi52b3J0ZXguc2V0Q2xvc2VkQnlDb25uZWN0aW9uKCk7XG4gICAgICAgICAgICBzZWxmLl9jbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHNlbGYuX2Fib3J0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHNlbGYuX2h0dHAuYWJvcnQoKTtcblxuICAgICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTcGxpdCBvdXQgdGhlIHBheWxvYWRzIG9mIGRhdGEsIHRoZXkgYXJlIGRlbGltaXRlZCBieSBhICcuJ1xuICAgICAgICBsZXQgZGF0YSA9IHNlbGYuX2h0dHAucmVzcG9uc2VUZXh0LnN1YnN0cihzZWxmLl9yZXNwb25zZVBhcnNlSW5kZXgpO1xuICAgICAgICBsZXQgcGF5bG9hZFNlcGFyYXRvckluZGV4ID0gZGF0YS5pbmRleE9mKFwiLlwiKTtcblxuICAgICAgICB3aGlsZSAocGF5bG9hZFNlcGFyYXRvckluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgc2VsZi5fcmVzcG9uc2VQYXJzZUluZGV4ICs9IHBheWxvYWRTZXBhcmF0b3JJbmRleCArIDE7XG5cbiAgICAgICAgICAgIC8vIEdldCB0aGUgYjY0ZW5jb2RlZCBzdHJpbmdcbiAgICAgICAgICAgIGxldCB2b3J0ZXhTdHIgPSBkYXRhLnN1YnN0cigwLCBwYXlsb2FkU2VwYXJhdG9ySW5kZXgpO1xuXG4gICAgICAgICAgICBpZiAodm9ydGV4U3RyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHNlbGYudm9ydGV4QmVhdENhbGxiYWNrKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBwYXlsb2FkIG9iamVjdCBmcm9tIGl0XG4gICAgICAgICAgICAgICAgLy8gU2VuZCB0byB2b3J0ZXhcbiAgICAgICAgICAgICAgICBQYXlsb2FkRW52ZWxvcGUuZnJvbVZvcnRleE1zZyh2b3J0ZXhTdHIpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChwZTogUGF5bG9hZEVudmVsb3BlKSA9PiBzZWxmLnJlY2VpdmVDYWxsYmFjayhwZSkpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAke2RhdGVTdHIoKX0gQW4gZXJyb3Igb2NjdXJlZCBkZXNlcmlhbGlzaW5nICR7ZX1gXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRhdGEgPSBzZWxmLl9odHRwLnJlc3BvbnNlVGV4dC5zdWJzdHIoc2VsZi5fcmVzcG9uc2VQYXJzZUluZGV4KTtcbiAgICAgICAgICAgIHBheWxvYWRTZXBhcmF0b3JJbmRleCA9IGRhdGEuaW5kZXhPZihcIi5cIik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbiB0aGUgZXZlbnQgdGhhdCB0aGUgYnJvd3NlciBpcyBidWZmZXJpbmcgYWxsIHRoaXMgZGF0YSwgd2Ugc2hvdWxkXG4gICAgICAgIC8vIHJlY29ubmVjdCB0byBhbGxvdyB0aGUgYnJvd3NlciB0byBjbGVhbnVwLlxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBzZWxmLl9odHRwLnJlc3BvbnNlVGV4dC5sZW5ndGggPj1cbiAgICAgICAgICAgICAgICBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24uUkVDT05ORUNUX1NJWkVfTElNSVQgJiZcbiAgICAgICAgICAgICFzZWxmLl9jbG9zaW5nXG4gICAgICAgICkge1xuICAgICAgICAgICAgc2VsZi5fY2xvc2luZyA9IHRydWU7XG4gICAgICAgICAgICBzZWxmLnZvcnRleC5yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX2Vycm9yKGUpIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICBpZiAoc2VsZi5fdXBkYXRlVGltZXIpIGNsZWFySW50ZXJ2YWwoc2VsZi5fdXBkYXRlVGltZXIpO1xuXG4gICAgICAgIGlmIChzZWxmLl9hYm9ydGluZyB8fCB0aGlzLl9jbG9zaW5nKSByZXR1cm47XG5cbiAgICAgICAgbGV0IG1zZyA9IFwiXCI7XG5cbiAgICAgICAgaWYgKGUudHlwZSA9PT0gXCJhYm9ydFwiKSB7XG4gICAgICAgICAgICBtc2cgPSBcIlJlcXVlc3Qgd2FzIGFib3J0ZWQgYW5kIG5vdCBieSBWb3J0ZXhKU1wiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtc2cgPSBlLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52b3J0ZXhTdGF0dXNTZXJ2aWNlLnNldE9ubGluZShmYWxzZSk7XG4gICAgICAgIHRoaXMudm9ydGV4U3RhdHVzU2VydmljZS5sb2dFcnJvcihtc2cpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlZvcnRleENvbm5lY3Rpb24sIGNvbm5lY3Rpb24gZXJyb3JlZCBvdXQ6IFwiICsgbXNnKTtcbiAgICB9XG59XG4iXX0=