UNPKG

blast-graph-angular2

Version:

![Alt text](./resources/images/b-circle-trans-100.png) **with** ![Alt text](./resources/images/angular.png)

583 lines (582 loc) 40.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { BlastHelpers } from './blast-helpers'; import { Subject } from 'rxjs/index'; /** @type {?} */ export var BLAST_VERSION = '0.0.1'; /** @type {?} */ export var LOG_LEVEL = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3 }; /** * @record */ export function BlastServiceConfig() { } /** @type {?} */ BlastServiceConfig.prototype.initialTimeout; /** @type {?} */ BlastServiceConfig.prototype.maxTimeout; /** @type {?} */ BlastServiceConfig.prototype.reconnectIfNotNormalClose; var BlastService = /** @class */ (function () { function BlastService(url, connectNow, protocols, config) { this.url = url; this.protocols = protocols; this.config = config; this.reconnectAttempts = 0; this.sendQueue = []; this.onMessageCallbacks = []; this.onOpenCallbacks = []; this.onErrorCallbacks = []; this.onCloseCallbacks = []; this.readyStateConstants = { 'CONNECTING': 0, 'OPEN': 1, 'CLOSING': 2, 'CLOSED': 3, 'RECONNECT_ABORTED': 4 }; this.normalCloseCode = 1000; this.reconnectableStatusCodes = [4000]; this.logLevel = LOG_LEVEL.ERROR; /** @type {?} */ var match = new RegExp('wss?:\/\/').test(url); if (!match) { throw new Error('Invalid url provided'); } this.config = config || { initialTimeout: 500, maxTimeout: 300000, reconnectIfNotNormalClose: true }; this.dataStream = new Subject(); if (connectNow === undefined || connectNow) { this.connect(true); } } /** * @param {?=} force * @return {?} */ BlastService.prototype.connect = /** * @param {?=} force * @return {?} */ function (force) { var _this = this; if (force === void 0) { force = false; } /** @type {?} */ var self = this; if (force || !this.socket || this.socket.readyState !== this.readyStateConstants.OPEN) { self.socket = this.protocols ? new WebSocket(this.url, this.protocols) : new WebSocket(this.url); self.socket.onopen = function (ev) { _this.onOpenHandler(ev); }; self.socket.onmessage = function (ev) { if (BlastHelpers.isJson(ev.data)) { /** @type {?} */ var message = JSON.parse(ev.data); _this.debug('BlastService', 'jsonMessage', 'passing to handlers', ev.data); // call a json message handler - if true, then message handled mustn't carry on if (self.handleJsonMessage(message) === true) { return; } } self.onMessageHandler(ev.data); _this.dataStream.next(ev.data); }; this.socket.onclose = function (ev) { self.onCloseHandler(ev); }; this.socket.onerror = function (ev) { self.onErrorHandler(ev); _this.dataStream.error(ev); }; } }; /** * Run in Block Mode * Return true when can send and false in socket closed * @param {?} data * @param {?=} binary * @return {?} */ BlastService.prototype.sendMessage = /** * Run in Block Mode * Return true when can send and false in socket closed * @param {?} data * @param {?=} binary * @return {?} */ function (data, binary) { /** @type {?} */ var self = this; if (this.getReadyState() !== this.readyStateConstants.OPEN && this.getReadyState() !== this.readyStateConstants.CONNECTING) { this.connect(); } this.debug('BlastService', 'sendMessage', data); self.sendQueue.push({ message: data, binary: binary }); if (self.socket.readyState === self.readyStateConstants.OPEN) { self.fireQueue(); return true; } else { return false; } }; /** * Use {mode} mode to send {data} data * If no specify, Default SendMode is Observable mode * @param data * @param mode * @param binary * @returns */ /** * Use {mode} mode to send {data} data * If no specify, Default SendMode is Observable mode * @param {?} data * @param {?=} binary * @return {?} */ BlastService.prototype.send = /** * Use {mode} mode to send {data} data * If no specify, Default SendMode is Observable mode * @param {?} data * @param {?=} binary * @return {?} */ function (data, binary) { return this.sendMessage(data, binary); }; /** * @return {?} */ BlastService.prototype.getDataStream = /** * @return {?} */ function () { return this.dataStream; }; /** * @param {?} event * @return {?} */ BlastService.prototype.notifyOpenCallbacks = /** * @param {?} event * @return {?} */ function (event) { for (var i = 0; i < this.onOpenCallbacks.length; i++) { this.onOpenCallbacks[i].call(this, event); } }; /** * @return {?} */ BlastService.prototype.fireQueue = /** * @return {?} */ function () { while (this.sendQueue.length && this.socket.readyState === this.readyStateConstants.OPEN) { /** @type {?} */ var data = this.sendQueue.shift(); if (data.binary) { this.socket.send(data.message); } else { this.socket.send(BlastHelpers.isString(data.message) ? data.message : JSON.stringify(data.message)); } } }; /** * @param {?} event * @return {?} */ BlastService.prototype.notifyCloseCallbacks = /** * @param {?} event * @return {?} */ function (event) { for (var i = 0; i < this.onCloseCallbacks.length; i++) { this.onCloseCallbacks[i].call(this, event); } }; /** * @param {?} event * @return {?} */ BlastService.prototype.notifyErrorCallbacks = /** * @param {?} event * @return {?} */ function (event) { for (var i = 0; i < this.onErrorCallbacks.length; i++) { this.onErrorCallbacks[i].call(this, event); } }; /** * @param {?} cb * @return {?} */ BlastService.prototype.onOpen = /** * @param {?} cb * @return {?} */ function (cb) { this.onOpenCallbacks.push(cb); return this; }; ; /** * @param {?} cb * @return {?} */ BlastService.prototype.onClose = /** * @param {?} cb * @return {?} */ function (cb) { this.onCloseCallbacks.push(cb); return this; }; /** * @param {?} cb * @return {?} */ BlastService.prototype.onError = /** * @param {?} cb * @return {?} */ function (cb) { this.onErrorCallbacks.push(cb); return this; }; ; /** * @param {?} callback * @param {?=} options * @return {?} */ BlastService.prototype.onMessage = /** * @param {?} callback * @param {?=} options * @return {?} */ function (callback, options) { if (!BlastHelpers.isFunction(callback)) { throw new Error('Callback must be a function'); } this.onMessageCallbacks.push({ fn: callback, pattern: options ? options.filter : undefined, autoApply: options ? options.autoApply : true }); return this; }; /** * @param {?} message * @return {?} */ BlastService.prototype.handleJsonMessage = /** * @param {?} message * @return {?} */ function (message) { // as a default return false i.e. don't change message flow // enables extended classes to override this function return false; }; /** * @param {?} message * @return {?} */ BlastService.prototype.onMessageHandler = /** * @param {?} message * @return {?} */ function (message) { this.debug('BlastService', 'onMessageHandler', message.data); /** @type {?} */ var self = this; /** @type {?} */ var currentCallback; for (var i = 0; i < self.onMessageCallbacks.length; i++) { currentCallback = self.onMessageCallbacks[i]; currentCallback.fn.apply(self, [message]); } }; ; /** * @param {?} event * @return {?} */ BlastService.prototype.onOpenHandler = /** * @param {?} event * @return {?} */ function (event) { this.debug('BlastService', 'connected'); this.reconnectAttempts = 0; this.notifyOpenCallbacks(event); this.fireQueue(); }; /** * @param {?} event * @return {?} */ BlastService.prototype.onCloseHandler = /** * @param {?} event * @return {?} */ function (event) { this.debug('BlastService', 'closed'); this.notifyCloseCallbacks(event); if ((this.config.reconnectIfNotNormalClose && event.code !== this.normalCloseCode) || this.reconnectableStatusCodes.indexOf(event.code) > -1) { this.reconnect(); } else { this.sendQueue = []; this.dataStream.complete(); } }; ; /** * @param {?} event * @return {?} */ BlastService.prototype.onErrorHandler = /** * @param {?} event * @return {?} */ function (event) { this.debug('BlastService', 'onErrorHandler', event); this.notifyErrorCallbacks(event); }; ; /** * @return {?} */ BlastService.prototype.reconnect = /** * @return {?} */ function () { var _this = this; this.close(true); /** @type {?} */ var backoffDelay = this.getBackoffDelay(++this.reconnectAttempts); // let backoffDelaySeconds = backoffDelay / 1000; // // console.log('Reconnecting in ' + backoffDelaySeconds + ' seconds'); this.debug('BlastService', 'reconnectDelay', backoffDelay); setTimeout(function () { return _this.connect(); }, backoffDelay); return this; }; /** * @param {?=} force * @return {?} */ BlastService.prototype.close = /** * @param {?=} force * @return {?} */ function (force) { if (force === void 0) { force = false; } if (force || !this.socket.bufferedAmount) { this.socket.close(this.normalCloseCode); } return this; }; ; /** * @param {?} attempt * @return {?} */ BlastService.prototype.getBackoffDelay = /** * @param {?} attempt * @return {?} */ function (attempt) { /** @type {?} */ var R = Math.random() + 1; /** @type {?} */ var T = this.config.initialTimeout; /** @type {?} */ var F = 2; /** @type {?} */ var N = attempt; /** @type {?} */ var M = this.config.maxTimeout; return Math.floor(Math.min(R * T * Math.pow(F, N), M)); }; ; /** * @param {?} state * @return {?} */ BlastService.prototype.setInternalState = /** * @param {?} state * @return {?} */ function (state) { if (Math.floor(state) !== state || state < 0 || state > 4) { throw new Error('state must be an integer between 0 and 4, got: ' + state); } this.internalConnectionState = state; }; /** * Could be -1 if not initzialized yet * @returns */ /** * Could be -1 if not initzialized yet * @return {?} */ BlastService.prototype.getReadyState = /** * Could be -1 if not initzialized yet * @return {?} */ function () { if (this.socket == null) { return -1; } return this.internalConnectionState || this.socket.readyState; }; /** * @return {?} */ BlastService.prototype.getVersion = /** * @return {?} */ function () { return BLAST_VERSION; }; /** * @return {?} */ BlastService.prototype.hasConsole = /** * @return {?} */ function () { if (console === undefined) { return false; } return true; }; /** * @param {...?} args * @return {?} */ BlastService.prototype.debug = /** * @param {...?} args * @return {?} */ function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this.hasConsole() && this.logLevel < 1) { console.debug.apply(console, args); } }; /** * @param {...?} args * @return {?} */ BlastService.prototype.info = /** * @param {...?} args * @return {?} */ function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this.hasConsole() && this.logLevel < 2) { console.debug.apply(console, args); } }; /** * @param {...?} args * @return {?} */ BlastService.prototype.warn = /** * @param {...?} args * @return {?} */ function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this.hasConsole() && this.logLevel < 4) { console.debug.apply(console, args); } }; /** * @param {...?} args * @return {?} */ BlastService.prototype.error = /** * @param {...?} args * @return {?} */ function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } console.error.apply(console, args); }; /** * @param {?} level * @return {?} */ BlastService.prototype.setLogLevel = /** * @param {?} level * @return {?} */ function (level) { this.logLevel = level; }; return BlastService; }()); export { BlastService }; if (false) { /** @type {?} */ BlastService.prototype.reconnectAttempts; /** @type {?} */ BlastService.prototype.sendQueue; /** @type {?} */ BlastService.prototype.onMessageCallbacks; /** @type {?} */ BlastService.prototype.onOpenCallbacks; /** @type {?} */ BlastService.prototype.onErrorCallbacks; /** @type {?} */ BlastService.prototype.onCloseCallbacks; /** @type {?} */ BlastService.prototype.readyStateConstants; /** @type {?} */ BlastService.prototype.normalCloseCode; /** @type {?} */ BlastService.prototype.reconnectableStatusCodes; /** @type {?} */ BlastService.prototype.socket; /** @type {?} */ BlastService.prototype.dataStream; /** @type {?} */ BlastService.prototype.internalConnectionState; /** @type {?} */ BlastService.prototype.logLevel; /** @type {?} */ BlastService.prototype.url; /** @type {?} */ BlastService.prototype.protocols; /** @type {?} */ BlastService.prototype.config; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxhc3QtYW5ndWxhcjIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9ibGFzdC1ncmFwaC1hbmd1bGFyMi8iLCJzb3VyY2VzIjpbInNyYy9ibGFzdC1hbmd1bGFyMi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBSUEsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxZQUFZLENBQUM7O0FBRW5DLFdBQWEsYUFBYSxHQUFHLE9BQU8sQ0FBQzs7QUFFckMsV0FBYSxTQUFTLEdBQUc7SUFDckIsS0FBSyxFQUFFLENBQUM7SUFDUixJQUFJLEVBQUUsQ0FBQztJQUNQLElBQUksRUFBRSxDQUFDO0lBQ1AsS0FBSyxFQUFFLENBQUM7Q0FDWCxDQUFDOzs7Ozs7Ozs7OztBQVNGLElBQUE7SUF3Qkksc0JBQW9CLEdBQVcsRUFDM0IsVUFBb0IsRUFDWixXQUNBO1FBSFEsUUFBRyxHQUFILEdBQUcsQ0FBUTtRQUVuQixjQUFTLEdBQVQsU0FBUztRQUNULFdBQU0sR0FBTixNQUFNO2lDQXpCVSxDQUFDO3lCQUNGLEVBQUU7a0NBQ08sRUFBRTsrQkFDQSxFQUFFO2dDQUNELEVBQUU7Z0NBQ0YsRUFBRTttQ0FDWDtZQUMxQixZQUFZLEVBQUUsQ0FBQztZQUNmLE1BQU0sRUFBRSxDQUFDO1lBQ1QsU0FBUyxFQUFFLENBQUM7WUFDWixRQUFRLEVBQUUsQ0FBQztZQUNYLG1CQUFtQixFQUFFLENBQUM7U0FDekI7K0JBRXlCLElBQUk7d0NBQ0ssQ0FBQyxJQUFJLENBQUM7d0JBS3ZCLFNBQVMsQ0FBQyxLQUFLOztRQVE3QixJQUFNLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEQsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ1QsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFD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Vzs7OztJQUFYLFVBQVksS0FBYTtRQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztLQUN6Qjt1QkE5VEw7SUErVEMsQ0FBQTtBQXhTRCx3QkF3U0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGUsIE9wdGlvbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbi8qKlxuICogYmxhc3QtYW5ndWxhcjJcbiAqL1xuaW1wb3J0IHtCbGFzdEhlbHBlcnN9IGZyb20gJy4vYmxhc3QtaGVscGVycyc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMvaW5kZXgnO1xuXG5leHBvcnQgY29uc3QgQkxBU1RfVkVSU0lPTiA9ICcwLjAuMSc7XG5cbmV4cG9ydCBjb25zdCBMT0dfTEVWRUwgPSB7XG4gICAgREVCVUc6IDAsXG4gICAgSU5GTzogMSxcbiAgICBXQVJOOiAyLFxuICAgIEVSUk9SOiAzXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEJsYXN0U2VydmljZUNvbmZpZyB7XG4gICAgaW5pdGlhbFRpbWVvdXQ6IG51bWJlcjtcbiAgICBtYXhUaW1lb3V0OiBudW1iZXI7XG4gICAgcmVjb25uZWN0SWZOb3ROb3JtYWxDbG9zZTogYm9vbGVhbjtcbn1cblxuLy9ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQmxhc3RTZXJ2aWNlIHtcblxuICAgIHByaXZhdGUgcmVjb25uZWN0QXR0ZW1wdHMgPSAwO1xuICAgIHByaXZhdGUgc2VuZFF1ZXVlOiBhbnlbXSA9IFtdO1xuICAgIHByaXZhdGUgb25NZXNzYWdlQ2FsbGJhY2tzOiBhbnlbXSA9IFtdO1xuICAgIHByaXZhdGUgb25PcGVuQ2FsbGJhY2tzOiBGdW5jdGlvbltdID0gW107XG4gICAgcHJpdmF0ZSBvbkVycm9yQ2FsbGJhY2tzOiBGdW5jdGlvbltdID0gW107XG4gICAgcHJpdmF0ZSBvbkNsb3NlQ2FsbGJhY2tzOiBGdW5jdGlvbltdID0gW107XG4gICAgcHJpdmF0ZSByZWFkeVN0YXRlQ29uc3RhbnRzID0ge1xuICAgICAgICAnQ09OTkVDVElORyc6IDAsXG4gICAgICAgICdPUEVOJzogMSxcbiAgICAgICAgJ0NMT1NJTkcnOiAyLFxuICAgICAgICAnQ0xPU0VEJzogMyxcbiAgICAgICAgJ1JFQ09OTkVDVF9BQk9SVEVEJzogNFxuICAgIH07XG5cbiAgICBwcml2YXRlIG5vcm1hbENsb3NlQ29kZSA9IDEwMDA7XG4gICAgcHJpdmF0ZSByZWNvbm5lY3RhYmxlU3RhdHVzQ29kZXMgPSBbNDAwMF07XG4gICAgcHJpdmF0ZSBzb2NrZXQ6IFdlYlNvY2tldDtcbiAgICBwcml2YXRlIGRhdGFTdHJlYW06IFN1YmplY3Q8YW55PjtcbiAgICBwcml2YXRlIGludGVybmFsQ29ubmVjdGlvblN0YXRlOiBudW1iZXI7XG5cbiAgICBwdWJsaWMgbG9nTGV2ZWwgPSBMT0dfTEVWRUwuRVJST1I7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHVybDogc3RyaW5nLFxuICAgICAgICBjb25uZWN0Tm93PzogYm9vbGVhbixcbiAgICAgICAgcHJpdmF0ZSBwcm90b2NvbHM/OiBBcnJheTxzdHJpbmc+LFxuICAgICAgICBwcml2YXRlIGNvbmZpZz86IEJsYXN0U2VydmljZUNvbmZpZ1xuICAgICkge1xuXG4gICAgICAgIGNvbnN0IG1hdGNoID0gbmV3IFJlZ0V4cCgnd3NzPzpcXC9cXC8nKS50ZXN0KHVybCk7XG4gICAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB1cmwgcHJvdmlkZWQnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCB7aW5pdGlhbFRpbWVvdXQ6IDUwMCwgbWF4VGltZW91dDogMzAwMDAwLCByZWNvbm5lY3RJZk5vdE5vcm1hbENsb3NlOiB0cnVlfTtcbiAgICAgICAgdGhpcy5kYXRhU3RyZWFtID0gbmV3IFN1YmplY3QoKTtcblxuICAgICAgICBpZiAoY29ubmVjdE5vdyA9PT0gdW5kZWZpbmVkIHx8IGNvbm5lY3ROb3cpIHtcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdCh0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbm5lY3QoZm9yY2UgPSBmYWxzZSkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKGZvcmNlIHx8ICF0aGlzLnNvY2tldCB8fCB0aGlzLnNvY2tldC5yZWFkeVN0YXRlICE9PSB0aGlzLnJlYWR5U3RhdGVDb25zdGFudHMuT1BFTikge1xuICAgICAgICAgICAgc2VsZi5zb2NrZXQgPSB0aGlzLnByb3RvY29scyA/IG5ldyBXZWJTb2NrZXQodGhpcy51cmwsIHRoaXMucHJvdG9jb2xzKSA6IG5ldyBXZWJTb2NrZXQodGhpcy51cmwpO1xuXG4gICAgICAgICAgICBzZWxmLnNvY2tldC5vbm9wZW4gPSAoZXY6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5vbk9wZW5IYW5kbGVyKGV2KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzZWxmLnNvY2tldC5vbm1lc3NhZ2UgPSAoZXY6IE1lc3NhZ2VFdmVudCkgPT4ge1xuXG4gICAgICAgICAgICAgICAgaWYgKEJsYXN0SGVscGVycy5pc0pzb24oZXYuZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IEpTT04ucGFyc2UoZXYuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVidWcoJ0JsYXN0U2VydmljZScsICdqc29uTWVzc2FnZScsICdwYXNzaW5nIHRvIGhhbmRsZXJzJywgZXYuZGF0YSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gY2FsbCBhIGpzb24gbWVzc2FnZSBoYW5kbGVyIC0gaWYgdHJ1ZSwgdGhlbiBtZXNzYWdlIGhhbmRsZWQgbXVzdG4ndCBjYXJyeSBvblxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5oYW5kbGVKc29uTWVzc2FnZShtZXNzYWdlKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNlbGYub25NZXNzYWdlSGFuZGxlcihldi5kYXRhKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFTdHJlYW0ubmV4dChldi5kYXRhKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuc29ja2V0Lm9uY2xvc2UgPSAoZXY6IENsb3NlRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLm9uQ2xvc2VIYW5kbGVyKGV2KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuc29ja2V0Lm9uZXJyb3IgPSAoZXY6IEVycm9yRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLm9uRXJyb3JIYW5kbGVyKGV2KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFTdHJlYW0uZXJyb3IoZXYpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVuIGluIEJsb2NrIE1vZGVcbiAgICAgKiBSZXR1cm4gdHJ1ZSB3aGVuIGNhbiBzZW5kIGFuZCBmYWxzZSBpbiBzb2NrZXQgY2xvc2VkXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBwcml2YXRlIHNlbmRNZXNzYWdlKGRhdGE6IGFueSwgYmluYXJ5PzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXMuZ2V0UmVhZHlTdGF0ZSgpICE9PSB0aGlzLnJlYWR5U3RhdGVDb25zdGFudHMuT1BFTlxuICAgICAgICAgICAgJiYgdGhpcy5nZXRSZWFkeVN0YXRlKCkgIT09IHRoaXMucmVhZHlTdGF0ZUNvbnN0YW50cy5DT05ORUNUSU5HKSB7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRlYnVnKCdCbGFzdFNlcnZpY2UnLCAnc2VuZE1lc3NhZ2UnLCBkYXRhKTtcbiAgICAgICAgc2VsZi5zZW5kUXVldWUucHVzaCh7bWVzc2FnZTogZGF0YSwgYmluYXJ5OiBiaW5hcnl9KTtcbiAgICAgICAgaWYgKHNlbGYuc29ja2V0LnJlYWR5U3RhdGUgPT09IHNlbGYucmVhZHlTdGF0ZUNvbnN0YW50cy5PUEVOKSB7XG4gICAgICAgICAgICBzZWxmLmZpcmVRdWV1ZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2Uge21vZGV9IG1vZGUgdG8gc2VuZCB7ZGF0YX0gZGF0YVxuICAgICAqIElmIG5vIHNwZWNpZnksIERlZmF1bHQgU2VuZE1vZGUgaXMgT2JzZXJ2YWJsZSBtb2RlXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKiBAcGFyYW0gbW9kZVxuICAgICAqIEBwYXJhbSBiaW5hcnlcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICBzZW5kKGRhdGE6IGFueSwgYmluYXJ5PzogYm9vbGVhbik6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlbmRNZXNzYWdlKGRhdGEsIGJpbmFyeSk7XG4gICAgfVxuXG4gICAgZ2V0RGF0YVN0cmVhbSgpOiBTdWJqZWN0PGFueT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhU3RyZWFtO1xuICAgIH1cblxuXG4gICAgbm90aWZ5T3BlbkNhbGxiYWNrcyhldmVudDogRXZlbnQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9uT3BlbkNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5vbk9wZW5DYWxsYmFja3NbaV0uY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmaXJlUXVldWUoKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLnNlbmRRdWV1ZS5sZW5ndGggJiYgdGhpcy5zb2NrZXQucmVhZHlTdGF0ZSA9PT0gdGhpcy5yZWFkeVN0YXRlQ29uc3RhbnRzLk9QRU4pIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLnNlbmRRdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgICAgICBpZiAoZGF0YS5iaW5hcnkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNvY2tldC5zZW5kKGRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc29ja2V0LnNlbmQoXG4gICAgICAgICAgICAgICAgICAgIEJsYXN0SGVscGVycy5pc1N0cmluZyhkYXRhLm1lc3NhZ2UpID8gZGF0YS5tZXNzYWdlIDogSlNPTi5zdHJpbmdpZnkoZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBub3RpZnlDbG9zZUNhbGxiYWNrcyhldmVudDogRXZlbnQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9uQ2xvc2VDYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMub25DbG9zZUNhbGxiYWNrc1tpXS5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5vdGlmeUVycm9yQ2FsbGJhY2tzKGV2ZW50OiBFdmVudCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub25FcnJvckNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5vbkVycm9yQ2FsbGJhY2tzW2ldLmNhbGwodGhpcywgZXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25PcGVuKGNiOiBGdW5jdGlvbikge1xuICAgICAgICB0aGlzLm9uT3BlbkNhbGxiYWNrcy5wdXNoKGNiKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIG9uQ2xvc2UoY2I6IEZ1bmN0aW9uKSB7XG4gICAgICAgIHRoaXMub25DbG9zZUNhbGxiYWNrcy5wdXNoKGNiKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgb25FcnJvcihjYjogRnVuY3Rpb24pIHtcbiAgICAgICAgdGhpcy5vbkVycm9yQ2FsbGJhY2tzLnB1c2goY2IpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgb25NZXNzYWdlKGNhbGxiYWNrOiBGdW5jdGlvbiwgb3B0aW9ucz8pIHtcbiAgICAgICAgaWYgKCFCbGFzdEhlbHBlcnMuaXNGdW5jdGlvbihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9uTWVzc2FnZUNhbGxiYWNrcy5wdXNoKHtcbiAgICAgICAgICAgIGZuOiBjYWxsYmFjayxcbiAgICAgICAgICAgIHBhdHRlcm46IG9wdGlvbnMgPyBvcHRpb25zLmZpbHRlciA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGF1dG9BcHBseTogb3B0aW9ucyA/IG9wdGlvbnMuYXV0b0FwcGx5IDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgaGFuZGxlSnNvbk1lc3NhZ2UobWVzc2FnZTogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGFzIGEgZGVmYXVsdCByZXR1cm4gZmFsc2UgaS5lLiBkb24ndCBjaGFuZ2UgbWVzc2FnZSBmbG93XG4gICAgICAgIC8vIGVuYWJsZXMgZXh0ZW5kZWQgY2xhc3NlcyB0byBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBvbk1lc3NhZ2VIYW5kbGVyKG1lc3NhZ2U6IE1lc3NhZ2VFdmVudCkge1xuICAgICAgICB0aGlzLmRlYnVnKCdCbGFzdFNlcnZpY2UnLCAnb25NZXNzYWdlSGFuZGxlcicsIG1lc3NhZ2UuZGF0YSk7XG5cbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGxldCBjdXJyZW50Q2FsbGJhY2s7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5vbk1lc3NhZ2VDYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRDYWxsYmFjayA9IHNlbGYub25NZXNzYWdlQ2FsbGJhY2tzW2ldO1xuICAgICAgICAgICAgY3VycmVudENhbGxiYWNrLmZuLmFwcGx5KHNlbGYsIFttZXNzYWdlXSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgb25PcGVuSGFuZGxlcihldmVudDogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZygnQmxhc3RTZXJ2aWNlJywgJ2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlY29ubmVjdEF0dGVtcHRzID0gMDtcbiAgICAgICAgdGhpcy5ub3RpZnlPcGVuQ2FsbGJhY2tzKGV2ZW50KTtcbiAgICAgICAgdGhpcy5maXJlUXVldWUoKTtcbiAgICB9XG5cbiAgICBvbkNsb3NlSGFuZGxlcihldmVudDogQ2xvc2VFdmVudCkge1xuICAgICAgICB0aGlzLmRlYnVnKCdCbGFzdFNlcnZpY2UnLCAnY2xvc2VkJyk7XG4gICAgICAgIHRoaXMubm90aWZ5Q2xvc2VDYWxsYmFja3MoZXZlbnQpO1xuICAgICAgICBpZiAoKHRoaXMuY29uZmlnLnJlY29ubmVjdElmTm90Tm9ybWFsQ2xvc2UgJiYgZXZlbnQuY29kZSAhPT0gdGhpcy5ub3JtYWxDbG9zZUNvZGUpXG4gICAgICAgICAgICB8fCB0aGlzLnJlY29ubmVjdGFibGVTdGF0dXNDb2Rlcy5pbmRleE9mKGV2ZW50LmNvZGUpID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlbmRRdWV1ZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5kYXRhU3RyZWFtLmNvbXBsZXRlKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgb25FcnJvckhhbmRsZXIoZXZlbnQ6IEVycm9yRXZlbnQpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZygnQmxhc3RTZXJ2aWNlJywgJ29uRXJyb3JIYW5kbGVyJywgZXZlbnQpO1xuICAgICAgICB0aGlzLm5vdGlmeUVycm9yQ2FsbGJhY2tzKGV2ZW50KTtcbiAgICB9O1xuXG4gICAgcmVjb25uZWN0KCkge1xuICAgICAgICB0aGlzLmNsb3NlKHRydWUpO1xuICAgICAgICBjb25zdCBiYWNrb2ZmRGVsYXkgPSB0aGlzLmdldEJhY2tvZmZEZWxheSgrK3RoaXMucmVjb25uZWN0QXR0ZW1wdHMpO1xuICAgICAgICAvLyAgICAgICAgIGxldCBiYWNrb2ZmRGVsYXlTZWNvbmRzID0gYmFja29mZkRlbGF5IC8gMTAwMDtcbiAgICAgICAgLy8gICAgICAgICAvLyBjb25zb2xlLmxvZygnUmVjb25uZWN0aW5nIGluICcgKyBiYWNrb2ZmRGVsYXlTZWNvbmRzICsgJyBzZWNvbmRzJyk7XG4gICAgICAgIHRoaXMuZGVidWcoJ0JsYXN0U2VydmljZScsICdyZWNvbm5lY3REZWxheScsIGJhY2tvZmZEZWxheSk7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jb25uZWN0KCksIGJhY2tvZmZEZWxheSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGNsb3NlKGZvcmNlOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGZvcmNlIHx8ICF0aGlzLnNvY2tldC5idWZmZXJlZEFtb3VudCkge1xuICAgICAgICAgICAgdGhpcy5zb2NrZXQuY2xvc2UodGhpcy5ub3JtYWxDbG9zZUNvZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBnZXRCYWNrb2ZmRGVsYXkoYXR0ZW1wdDogbnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IFIgPSBNYXRoLnJhbmRvbSgpICsgMTtcbiAgICAgICAgY29uc3QgVCA9IHRoaXMuY29uZmlnLmluaXRpYWxUaW1lb3V0O1xuICAgICAgICBjb25zdCBGID0gMjtcbiAgICAgICAgY29uc3QgTiA9IGF0dGVtcHQ7XG4gICAgICAgIGNvbnN0IE0gPSB0aGlzLmNvbmZpZy5tYXhUaW1lb3V0O1xuXG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKE1hdGgubWluKFIgKiBUICogTWF0aC5wb3coRiwgTiksIE0pKTtcbiAgICB9O1xuXG4gICAgc2V0SW50ZXJuYWxTdGF0ZShzdGF0ZTogbnVtYmVyKSB7XG4gICAgICAgIGlmIChNYXRoLmZsb29yKHN0YXRlKSAhPT0gc3RhdGUgfHwgc3RhdGUgPCAwIHx8IHN0YXRlID4gNCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGF0ZSBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAwIGFuZCA0LCBnb3Q6ICcgKyBzdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbnRlcm5hbENvbm5lY3Rpb25TdGF0ZSA9IHN0YXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvdWxkIGJlIC0xIGlmIG5vdCBpbml0emlhbGl6ZWQgeWV0XG4gICAgICogQHJldHVybnMgXG4gICAgICovXG4gICAgZ2V0UmVhZHlTdGF0ZSgpOiBudW1iZXIge1xuICAgICAgICBpZiAodGhpcy5zb2NrZXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmludGVybmFsQ29ubmVjdGlvblN0YXRlIHx8IHRoaXMuc29ja2V0LnJlYWR5U3RhdGU7XG4gICAgfVxuXG4gICAgZ2V0VmVyc2lvbigpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gQkxBU1RfVkVSU0lPTjtcbiAgICB9XG5cblxuICAgIHByaXZhdGUgaGFzQ29uc29sZSgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGNvbnNvbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBwcml2YXRlIGRlYnVnKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc0NvbnNvbGUoKSAmJiB0aGlzLmxvZ0xldmVsIDwgMSkge1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1Zy5hcHBseShjb25zb2xlLCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGluZm8oLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29uc29sZSgpICYmIHRoaXMubG9nTGV2ZWwgPCAyKSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHdhcm4oLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29uc29sZSgpICYmIHRoaXMubG9nTGV2ZWwgPCA0KSB7XG4gICAgICAgICAgICBjb25zb2xlLmRlYnVnLmFwcGx5KGNvbnNvbGUsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVycm9yKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IuYXBwbHkoY29uc29sZSwgYXJncyk7XG4gICAgfVxuXG4gICAgc2V0TG9nTGV2ZWwobGV2ZWw6IG51bWJlcikge1xuICAgICAgICB0aGlzLmxvZ0xldmVsID0gbGV2ZWw7XG4gICAgfVxufVxuXG4iXX0=