UNPKG

@synerty/vortexjs

Version:

Custom observable data serialisation and routing based on Angular 2+

176 lines 23.2 kB
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, headers) { super(vortexStatusService, url, vortexClientName, headers); } shutdown() { this.setShutdown(); 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); // Set the headers for (const headerKey of vortex.headers.keys()) { self._http.setRequestHeader(headerKey, vortex.headers.get(headerKey)); } 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._vortex["setConnecting"](); this.vortexStatusService.logError(msg); // console.log("VortexConnection, connection errored out: " + msg); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVm9ydGV4Q2xpZW50SHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy92b3J0ZXgvVm9ydGV4Q2xpZW50SHR0cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXBELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQVdwRCxNQUFNLE9BQU8sZ0JBQWlCLFNBQVEsZUFBZTtJQUNqRDs7O09BR0c7SUFDSyxRQUFRLEdBQXVDLElBQUksQ0FBQztJQUU1RCxZQUNJLG1CQUF3QyxFQUN4QyxHQUFXLEVBQ1gsZ0JBQXdCLEVBQ3hCLE9BQW9CO1FBRXBCLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVTLFFBQVE7UUFDZCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztTQUN4QjtRQUNELE9BQU8sT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxxQkFBcUI7UUFDakIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFUyxhQUFhLENBQUMsVUFBb0I7UUFDeEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLDJCQUEyQixDQUMzQyxJQUFJLEVBQ0osSUFBSSxDQUFDLG1CQUFtQixFQUN4QixDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFDbEMsR0FB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LDJCQUEyQixDQUFDLG9CQUFvQjtZQUNoRCxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQ2hCO1lBQ0UsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7WUFDckIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUMzQjtJQUNMLENBQUM7SUFFTyxNQUFNLENBQUMsQ0FBQztRQUNaLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztRQUNoQixJQUFJLElBQUksQ0FBQyxZQUFZO1lBQUUsYUFBYSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV4RCxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBRTVDLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUViLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDcEIsR0FBRyxHQUFHLHlDQUF5QyxDQUFDO1NBQ25EO2FBQU07WUFDSCxJQUFJO2dCQUNBLEdBQUcsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7YUFDdEI7WUFBQyxPQUFPLENBQUMsRUFBRTthQUNYO1NBQ0o7UUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxtRUFBbUU7SUFDdkUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGJpbmQsIGRhdGVTdHIsIGdldEZpbHRTdHIgfSBmcm9tIFwiLi9VdGlsTWlzY1wiO1xuaW1wb3J0IHsgVm9ydGV4Q2xpZW50QUJDIH0gZnJvbSBcIi4vVm9ydGV4Q2xpZW50QUJDXCI7XG5pbXBvcnQgeyBWb3J0ZXhTdGF0dXNTZXJ2aWNlIH0gZnJvbSBcIi4vVm9ydGV4U3RhdHVzU2VydmljZVwiO1xuaW1wb3J0IHsgUGF5bG9hZEVudmVsb3BlIH0gZnJvbSBcIi4vUGF5bG9hZEVudmVsb3BlXCI7XG5pbXBvcnQgeyBIdHRwSGVhZGVycyB9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xuXG5pbnRlcmZhY2UgUmVjZWl2ZVBheWxvYWRDYWxsYWJsZSB7XG4gICAgKFBheWxvYWQpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgVm9ydGV4QmVhdENhbGxhYmxlIHtcbiAgICAoKTogdm9pZDtcbn1cblxuZXhwb3J0IGNsYXNzIFZvcnRleENsaWVudEh0dHAgZXh0ZW5kcyBWb3J0ZXhDbGllbnRBQkMge1xuICAgIC8qKlxuICAgICAqIFJhcFVJIFZvcnRleFNlcnZpY2UsIFRoaXMgY2xhc3MgaXMgcmVzcG9uc2libGUgZm9yIHNlbmRpbmcgYW5kIHJlY2VpdmluZyBwYXlsb2FkcyB0by9mcm9tXG4gICAgICogdGhlIHNlcnZlci5cbiAgICAgKi9cbiAgICBwcml2YXRlIGxhc3RDb25uOiBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24gfCBudWxsID0gbnVsbDtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICB2b3J0ZXhTdGF0dXNTZXJ2aWNlOiBWb3J0ZXhTdGF0dXNTZXJ2aWNlLFxuICAgICAgICB1cmw6IHN0cmluZyxcbiAgICAgICAgdm9ydGV4Q2xpZW50TmFtZTogc3RyaW5nLFxuICAgICAgICBoZWFkZXJzOiBIdHRwSGVhZGVycyxcbiAgICApIHtcbiAgICAgICAgc3VwZXIodm9ydGV4U3RhdHVzU2VydmljZSwgdXJsLCB2b3J0ZXhDbGllbnROYW1lLCBoZWFkZXJzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc2h1dGRvd24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuc2V0U2h1dGRvd24oKTtcbiAgICAgICAgaWYgKHRoaXMubGFzdENvbm4pIHtcbiAgICAgICAgICAgIHRoaXMubGFzdENvbm4uc2h1dGRvd24oKTtcbiAgICAgICAgICAgIHRoaXMubGFzdENvbm4gPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBzZXRDbG9zZWRCeUNvbm5lY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc2V0Q2xvc2VkKCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNlbmRWb3J0ZXhNc2codm9ydGV4TXNnczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sYXN0Q29ubiA9IG5ldyBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24oXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgdGhpcy52b3J0ZXhTdGF0dXNTZXJ2aWNlLFxuICAgICAgICAgICAgKHBheWxvYWQpID0+IHRoaXMucmVjZWl2ZShwYXlsb2FkKSxcbiAgICAgICAgICAgICgpID0+IHRoaXMuYmVhdCgpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmxhc3RDb25uLnNlbmQodm9ydGV4TXNncyk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGRhdGVTdHIoKSArIFwiU2VudCBwYXlsb2FkIHdpdGggZmlsdCA6IFwiICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZC5maWx0KSk7XG4gICAgfVxufVxuXG4vLyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjXG5jbGFzcyBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24ge1xuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFJFQ09OTkVDVF9TSVpFX0xJTUlUID0gMjAgKiAxMDI0ICogMTAyNDsgLy8gMjAgbWVnYWJ5dGVzXG5cbiAgICBwcml2YXRlIF92b3J0ZXg6IFZvcnRleENsaWVudEh0dHA7XG4gICAgcHJpdmF0ZSBfaHR0cDogWE1MSHR0cFJlcXVlc3Q7XG4gICAgcHJpdmF0ZSBfdXBkYXRlVGltZXI6IGFueTtcbiAgICBwcml2YXRlIF9yZXNwb25zZVBhcnNlSW5kZXg6IG51bWJlcjtcbiAgICBwcml2YXRlIF9jbG9zaW5nOiBib29sZWFuO1xuICAgIHByaXZhdGUgX2Fib3J0aW5nOiBib29sZWFuO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgdm9ydGV4OiBWb3J0ZXhDbGllbnRIdHRwLFxuICAgICAgICBwcml2YXRlIHZvcnRleFN0YXR1c1NlcnZpY2U6IFZvcnRleFN0YXR1c1NlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcmVjZWl2ZUNhbGxiYWNrOiBSZWNlaXZlUGF5bG9hZENhbGxhYmxlLFxuICAgICAgICBwcml2YXRlIHZvcnRleEJlYXRDYWxsYmFjazogVm9ydGV4QmVhdENhbGxhYmxlLFxuICAgICkge1xuICAgICAgICBsZXQgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgbGV0IHJhbmRBcmcgPSBNYXRoLnJhbmRvbSgpICsgXCIuXCIgKyBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgbGV0IGFyZ3MgPSB7XG4gICAgICAgICAgICB2b3J0ZXhVdWlkOiB2b3J0ZXgudXVpZCxcbiAgICAgICAgICAgIHZvcnRleE5hbWU6IHZvcnRleC5uYW1lLFxuICAgICAgICAgICAgX19yYW5kQXJnX186IHJhbmRBcmcsXG4gICAgICAgIH07XG5cbiAgICAgICAgc2VsZi5faHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICBzZWxmLl9odHRwLm9wZW4oXCJQT1NUXCIsIHNlbGYudm9ydGV4LnVybCArIGdldEZpbHRTdHIoYXJncyksIHRydWUpO1xuICAgICAgICAvLyBTZXQgdGhlIGhlYWRlcnNcbiAgICAgICAgZm9yIChjb25zdCBoZWFkZXJLZXkgb2Ygdm9ydGV4LmhlYWRlcnMua2V5cygpKSB7XG4gICAgICAgICAgICBzZWxmLl9odHRwLnNldFJlcXVlc3RIZWFkZXIoXG4gICAgICAgICAgICAgICAgaGVhZGVyS2V5LFxuICAgICAgICAgICAgICAgIHZvcnRleC5oZWFkZXJzLmdldChoZWFkZXJLZXkpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuX3VwZGF0ZVRpbWVyID0gbnVsbDtcblxuICAgICAgICAvLyBHb29kIGV2ZW50c1xuICAgICAgICBzZWxmLl9odHRwLm9ubG9hZHN0YXJ0ID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHNlbGYuX3JlY2VpdmVkKCk7XG5cbiAgICAgICAgICAgIC8vIEZvcmNlIGEgNTAtbWlsbGlzZWNvbmQgdGltZXIsIGFzIHNvbWUgYnJvd3NlcnMgZG9uJ3QgY2FsbCBcIm9ucHJvZ3Jlc3NcIlxuICAgICAgICAgICAgLy8gdmVyeSBvZnRlbi5cbiAgICAgICAgICAgIHNlbGYuX3VwZGF0ZVRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNlbGYuX3JlY2VpdmVkKCk7XG4gICAgICAgICAgICB9LCA1MCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgc2VsZi5faHR0cC5vbnByb2dyZXNzID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHNlbGYuX3JlY2VpdmVkKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgc2VsZi5faHR0cC5vbmxvYWQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKHNlbGYuX3VwZGF0ZVRpbWVyKSBjbGVhckludGVydmFsKHNlbGYuX3VwZGF0ZVRpbWVyKTtcbiAgICAgICAgICAgIHNlbGYuX3JlY2VpdmVkKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gQmFkIGV2ZW50c1xuICAgICAgICBzZWxmLl9odHRwLm9uYWJvcnQgPSBiaW5kKHNlbGYsIHNlbGYuX2Vycm9yKTtcbiAgICAgICAgc2VsZi5faHR0cC5vbmVycm9yID0gYmluZChzZWxmLCBzZWxmLl9lcnJvcik7XG4gICAgICAgIHNlbGYuX2h0dHAub250aW1lb3V0ID0gYmluZChzZWxmLCBzZWxmLl9lcnJvcik7XG5cbiAgICAgICAgc2VsZi5fcmVzcG9uc2VQYXJzZUluZGV4ID0gMDtcbiAgICAgICAgc2VsZi5fY2xvc2luZyA9IGZhbHNlO1xuICAgICAgICBzZWxmLl9hYm9ydGluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIHNodXRkb3duKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9jbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgaWYgKHRoaXMuX2h0dHApIHRoaXMuX2h0dHAuYWJvcnQoKTtcbiAgICB9XG5cbiAgICBzZW5kKHZvcnRleE1zZ3M6IHN0cmluZ1tdKSB7XG4gICAgICAgIGxldCBkYXRhID0gXCJcIjtcblxuICAgICAgICBmb3IgKGxldCB2b3J0ZXhNc2cgb2Ygdm9ydGV4TXNncykge1xuICAgICAgICAgICAgLy8gU2VyaWFsaXNlIHRoZSBwYXlsb2FkXG4gICAgICAgICAgICBkYXRhICs9IHZvcnRleE1zZyArIFwiLlwiO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJzZW5kaW5nIHBheWxvYWRcIik7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHhtbFN0cik7XG4gICAgICAgIHRoaXMuX2h0dHAuc2VuZChkYXRhKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZWNlaXZlZCgpIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICAvKlxuICAgICAgICAgKiBSZWNlaXZlZFxuICAgICAgICAgKlxuICAgICAgICAgKiBDYWxsZWQgd2hlbiBwcm9ncmVzcyBpcyBtYWRlIG9uIHJlY2VpdmluZyBkYXRhIGZyb20gdGhlIHZvcnRleCBzZXJ2ZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoaXMgbWVhbnMgdGhhdCBpdCBuZWVkcyB0byBiZSBhYmxlIHRvIGhhbmRsZSA6ICogcGFydGlhbCBwYXlsb2FkcyAoaW5cbiAgICAgICAgICogd2hpY2ggY2FzZSBpdCBkb2VzIG5vdGhpbmcpICogbXVsdGlwbGUgcGF5bG9hZHMgKGluIHdoaWNoIGNhc2UsIGl0IGJyZWFrc1xuICAgICAgICAgKiB0aGVtIHVwLCBwYXJzZXMgdGhlbSBhbmQgc2VuZHMgdGhlbSB0byB2b3J0ZXggaW5kaXZpZHVhbGx5KVxuICAgICAgICAgKi9cblxuICAgICAgICBpZiAoc2VsZi5fYWJvcnRpbmcpIHJldHVybjtcblxuICAgICAgICAvLyBJZiB3ZSByZWNlaXZlIHNvbWV0aGluZyB0aGF0IGlzIG5vdCB2YWxpZCB2b3J0ZXggZGF0YSwgdGhlbiByZWxvYWQgdGhlIHBhZ2VcbiAgICAgICAgLy8gVGhpcyB0eXBpY2FsbHkgb2NjdXJzIHdoZW4gd2UncmUgcmVjZXZpbmcgSFRNTCBiZWNhdXNlIHdlJ3JlIG5vdCBsb2dnZWQgaW4uXG4gICAgICAgIGlmICgvXjwvLnRlc3Qoc2VsZi5faHR0cC5yZXNwb25zZVRleHQpKSB7XG4gICAgICAgICAgICBzZWxmLnZvcnRleC5zZXRDbG9zZWRCeUNvbm5lY3Rpb24oKTtcbiAgICAgICAgICAgIHNlbGYuX2Nsb3NpbmcgPSB0cnVlO1xuICAgICAgICAgICAgc2VsZi5fYWJvcnRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgc2VsZi5faHR0cC5hYm9ydCgpO1xuXG4gICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNwbGl0IG91dCB0aGUgcGF5bG9hZHMgb2YgZGF0YSwgdGhleSBhcmUgZGVsaW1pdGVkIGJ5IGEgJy4nXG4gICAgICAgIGxldCBkYXRhID0gc2VsZi5faHR0cC5yZXNwb25zZVRleHQuc3Vic3RyKHNlbGYuX3Jlc3BvbnNlUGFyc2VJbmRleCk7XG4gICAgICAgIGxldCBwYXlsb2FkU2VwYXJhdG9ySW5kZXggPSBkYXRhLmluZGV4T2YoXCIuXCIpO1xuXG4gICAgICAgIHdoaWxlIChwYXlsb2FkU2VwYXJhdG9ySW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICBzZWxmLl9yZXNwb25zZVBhcnNlSW5kZXggKz0gcGF5bG9hZFNlcGFyYXRvckluZGV4ICsgMTtcblxuICAgICAgICAgICAgLy8gR2V0IHRoZSBiNjRlbmNvZGVkIHN0cmluZ1xuICAgICAgICAgICAgbGV0IHZvcnRleFN0ciA9IGRhdGEuc3Vic3RyKDAsIHBheWxvYWRTZXBhcmF0b3JJbmRleCk7XG5cbiAgICAgICAgICAgIGlmICh2b3J0ZXhTdHIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgc2VsZi52b3J0ZXhCZWF0Q2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIHBheWxvYWQgb2JqZWN0IGZyb20gaXRcbiAgICAgICAgICAgICAgICAvLyBTZW5kIHRvIHZvcnRleFxuICAgICAgICAgICAgICAgIFBheWxvYWRFbnZlbG9wZS5mcm9tVm9ydGV4TXNnKHZvcnRleFN0cilcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKHBlOiBQYXlsb2FkRW52ZWxvcGUpID0+IHNlbGYucmVjZWl2ZUNhbGxiYWNrKHBlKSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYCR7ZGF0ZVN0cigpfSBBbiBlcnJvciBvY2N1cmVkIGRlc2VyaWFsaXNpbmcgJHtlfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkYXRhID0gc2VsZi5faHR0cC5yZXNwb25zZVRleHQuc3Vic3RyKHNlbGYuX3Jlc3BvbnNlUGFyc2VJbmRleCk7XG4gICAgICAgICAgICBwYXlsb2FkU2VwYXJhdG9ySW5kZXggPSBkYXRhLmluZGV4T2YoXCIuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW4gdGhlIGV2ZW50IHRoYXQgdGhlIGJyb3dzZXIgaXMgYnVmZmVyaW5nIGFsbCB0aGlzIGRhdGEsIHdlIHNob3VsZFxuICAgICAgICAvLyByZWNvbm5lY3QgdG8gYWxsb3cgdGhlIGJyb3dzZXIgdG8gY2xlYW51cC5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgc2VsZi5faHR0cC5yZXNwb25zZVRleHQubGVuZ3RoID49XG4gICAgICAgICAgICBfVm9ydGV4Q2xpZW50SHR0cENvbm5lY3Rpb24uUkVDT05ORUNUX1NJWkVfTElNSVQgJiZcbiAgICAgICAgICAgICFzZWxmLl9jbG9zaW5nXG4gICAgICAgICkge1xuICAgICAgICAgICAgc2VsZi5fY2xvc2luZyA9IHRydWU7XG4gICAgICAgICAgICBzZWxmLnZvcnRleC5yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX2Vycm9yKGUpIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICBpZiAoc2VsZi5fdXBkYXRlVGltZXIpIGNsZWFySW50ZXJ2YWwoc2VsZi5fdXBkYXRlVGltZXIpO1xuXG4gICAgICAgIGlmIChzZWxmLl9hYm9ydGluZyB8fCB0aGlzLl9jbG9zaW5nKSByZXR1cm47XG5cbiAgICAgICAgbGV0IG1zZyA9IFwiXCI7XG5cbiAgICAgICAgaWYgKGUudHlwZSA9PT0gXCJhYm9ydFwiKSB7XG4gICAgICAgICAgICBtc2cgPSBcIlJlcXVlc3Qgd2FzIGFib3J0ZWQgYW5kIG5vdCBieSBWb3J0ZXhKU1wiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtc2cgPSBlLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl92b3J0ZXhbXCJzZXRDb25uZWN0aW5nXCJdKCk7XG4gICAgICAgIHRoaXMudm9ydGV4U3RhdHVzU2VydmljZS5sb2dFcnJvcihtc2cpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlZvcnRleENvbm5lY3Rpb24sIGNvbm5lY3Rpb24gZXJyb3JlZCBvdXQ6IFwiICsgbXNnKTtcbiAgICB9XG59XG4iXX0=