UNPKG

ng2-signalr

Version:
190 lines 28.6 kB
import { Subject } from 'rxjs'; import { BroadcastEventListener } from '../eventing/broadcast.event.listener'; import { ConnectionStatus } from './connection.status'; export class SignalRConnection { constructor(jConnection, jProxy, zone, configuration) { this._enabledLogging = true; this._jProxy = jProxy; this._jConnection = jConnection; this._zone = zone; this._errors = this.wireUpErrorsAsObservable(); this._status = this.wireUpStatusEventsAsObservable(); this._configuration = configuration; this._enabledLogging = configuration.logging; this._listeners = {}; } get errors() { return this._errors; } get status() { return this._status; } get enabledLogging() { return this._enabledLogging; } set enabledLogging(val) { this._enabledLogging = val; } start() { const jTransports = this.convertTransports(this._configuration.transport); const $promise = new Promise((resolve, reject) => { this._jConnection .start({ jsonp: this._configuration.jsonp, pingInterval: this._configuration.pingInterval, transport: jTransports, withCredentials: this._configuration.withCredentials, }) .done(() => { this.log('Connection established, ID: ' + this._jConnection.id); this.log('Connection established, Transport: ' + this._jConnection.transport.name); resolve(this); }) .fail((error) => { this.log('Could not connect'); reject('Failed to connect. Error: ' + error.message); // ex: Error during negotiation request. }); }); return $promise; } stop() { this._jConnection.stop(); } get id() { return this._jConnection.id; } invoke(method, ...parameters) { if (method == null) { throw new Error('SignalRConnection: Failed to invoke. Argument \'method\' can not be null'); } this.log(`SignalRConnection. Start invoking \'${method}\'...`); const $promise = new Promise((resolve, reject) => { this._jProxy.invoke(method, ...parameters) .done((result) => { this.log(`\'${method}\' invoked succesfully. Resolving promise...`); resolve(result); this.log(`Promise resolved.`); }) .fail((err) => { this.log(`Invoking \'${method}\' failed. Rejecting promise...`); reject(err); this.log(`Promise rejected.`); }); }); return $promise; } listen(listener) { if (listener == null) { throw new Error('Failed to listen. Argument \'listener\' can not be null'); } const callback = (...args) => { this.run(() => { let casted = null; if (args.length > 0) { casted = args[0]; } this.log('SignalRConnection.proxy.on invoked. Calling listener next() ...'); listener.next(casted); this.log('listener next() called.'); }, this._configuration.executeEventsInZone); }; this.setListener(callback, listener); } stopListening(listener) { if (listener == null) { throw new Error('Failed to listen. Argument \'listener\' can not be null'); } this.log(`SignalRConnection: Stopping listening to server event with name ${listener.event}`); if (!this._listeners[listener.event]) { this._listeners[listener.event] = []; } for (const callback of this._listeners[listener.event]) { this._jProxy.off(listener.event, callback); } this._listeners[listener.event] = []; } listenFor(event) { if (event == null || event === '') { throw new Error('Failed to listen. Argument \'event\' can not be empty'); } const listener = new BroadcastEventListener(event); this.listen(listener); return listener; } listenForRaw(event) { if (event == null || event === '') { throw new Error('Failed to listen. Argument \'event\' can not be empty'); } const listener = new BroadcastEventListener(event); const callback = (...args) => { this.run(() => { let casted = []; if (args.length > 0) { casted = args; } this.log('SignalRConnection.proxy.on invoked. Calling listener next() ...'); listener.next(args); this.log('listener next() called.'); }, this._configuration.executeEventsInZone); }; this.setListener(callback, listener); return listener; } setListener(callback, listener) { this.log(`SignalRConnection: Starting to listen to server event with name ${listener.event}`); this._jProxy.on(listener.event, callback); if (this._listeners[listener.event] == null) { this._listeners[listener.event] = []; } this._listeners[listener.event].push(callback); } convertTransports(transports) { if (transports instanceof Array) { return transports.map((t) => t.name); } return transports.name; } wireUpErrorsAsObservable() { const sError = new Subject(); this._jConnection.error((error) => { this.run(() => sError.next(error), this._configuration.executeErrorsInZone); }); return sError; } wireUpStatusEventsAsObservable() { const sStatus = new Subject(); // aggregate all signalr connection status handlers into 1 observable. // handler wire up, for signalr connection status callback. this._jConnection.stateChanged((change) => { this.run(() => sStatus.next(new ConnectionStatus(change.newState)), this._configuration.executeStatusChangeInZone); }); return sStatus.asObservable(); } onBroadcastEventReceived(listener, ...args) { this.log('SignalRConnection.proxy.on invoked. Calling listener next() ...'); let casted = null; if (args.length > 0) { casted = args[0]; } this.run(() => { listener.next(casted); }, this._configuration.executeEventsInZone); this.log('listener next() called.'); } log(...args) { if (this.enabledLogging === false) { return; } // tslint:disable-next-line: no-console console.log(args.join(', ')); } run(func, inZone) { if (inZone) { this._zone.run(() => func()); } else { this._zone.runOutsideAngular(() => func()); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsci5jb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcyLXNpZ25hbHIvc3JjL2xpYi9zZXJ2aWNlcy9jb25uZWN0aW9uL3NpZ25hbHIuY29ubmVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBT3ZELE1BQU0sT0FBTyxpQkFBaUI7SUFXMUIsWUFBWSxXQUFnQixFQUFFLE1BQVcsRUFBRSxJQUFZLEVBQUUsYUFBbUM7UUFGcEYsb0JBQWUsR0FBRyxJQUFJLENBQUM7UUFHM0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7UUFDaEMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO1FBQ3JELElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxlQUFlLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQztRQUM3QyxJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsSUFBVyxNQUFNO1FBQ2IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxJQUFXLE1BQU07UUFDYixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQVcsY0FBYztRQUN2QixPQUFPLElBQUks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QUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFTyxHQUFHLENBQUMsSUFBZ0IsRUFBRSxNQUFlO1FBQ3pDLElBQUksTUFBTSxFQUFFO1lBQ1IsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNoQzthQUFNO1lBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1NBQzlDO0lBQ0wsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSVNpZ25hbFJDb25uZWN0aW9uIH0gZnJvbSAnLi9pLnNpZ25hbHIuY29ubmVjdGlvbic7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgQnJvYWRjYXN0RXZlbnRMaXN0ZW5lciB9IGZyb20gJy4uL2V2ZW50aW5nL2Jyb2FkY2FzdC5ldmVudC5saXN0ZW5lcic7XHJcbmltcG9ydCB7IENvbm5lY3Rpb25TdGF0dXMgfSBmcm9tICcuL2Nvbm5lY3Rpb24uc3RhdHVzJztcclxuaW1wb3J0IHsgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFNpZ25hbFJDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vc2lnbmFsci5jb25maWd1cmF0aW9uJztcclxuaW1wb3J0IHsgQ29ubmVjdGlvblRyYW5zcG9ydCB9IGZyb20gJy4vY29ubmVjdGlvbi50cmFuc3BvcnQnO1xyXG5cclxuZXhwb3J0IGRlY2xhcmUgdHlwZSBDYWxsYmFja0ZuID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNpZ25hbFJDb25uZWN0aW9uIGltcGxlbWVudHMgSVNpZ25hbFJDb25uZWN0aW9uIHtcclxuICAgIHByaXZhdGUgX3N0YXR1czogT2JzZXJ2YWJsZTxDb25uZWN0aW9uU3RhdHVzPjtcclxuICAgIHByaXZhdGUgX2Vycm9yczogT2JzZXJ2YWJsZTxhbnk+O1xyXG4gICAgcHJpdmF0ZSBfakNvbm5lY3Rpb246IGFueTtcclxuICAgIHByaXZhdGUgX2pQcm94eTogYW55O1xyXG4gICAgcHJpdmF0ZSBfem9uZTogTmdab25lO1xyXG4gICAgcHJpdmF0ZSBfY29uZmlndXJhdGlvbjogU2lnbmFsUkNvbmZpZ3VyYXRpb247XHJcbiAgICBwcml2YXRlIF9saXN0ZW5lcnM6IHsgW2V2ZW50TmFtZTogc3RyaW5nXTogQ2FsbGJhY2tGbltdIH07XHJcblxyXG4gICAgcHJpdmF0ZSBfZW5hYmxlZExvZ2dpbmcgPSB0cnVlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKGpDb25uZWN0aW9uOiBhbnksIGpQcm94eTogYW55LCB6b25lOiBOZ1pvbmUsIGNvbmZpZ3VyYXRpb246IFNpZ25hbFJDb25maWd1cmF0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5falByb3h5ID0galByb3h5O1xyXG4gICAgICAgIHRoaXMuX2pDb25uZWN0aW9uID0gakNvbm5lY3Rpb247XHJcbiAgICAgICAgdGhpcy5fem9uZSA9IHpvbmU7XHJcbiAgICAgICAgdGhpcy5fZXJyb3JzID0gdGhpcy53aXJlVXBFcnJvcnNBc09ic2VydmFibGUoKTtcclxuICAgICAgICB0aGlzLl9zdGF0dXMgPSB0aGlzLndpcmVVcFN0YXR1c0V2ZW50c0FzT2JzZXJ2YWJsZSgpO1xyXG4gICAgICAgIHRoaXMuX2NvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xyXG4gICAgICAgIHRoaXMuX2VuYWJsZWRMb2dnaW5nID0gY29uZmlndXJhdGlvbi5sb2dnaW5nO1xyXG4gICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgZXJyb3JzKCk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9ycztcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IHN0YXR1cygpOiBPYnNlcnZhYmxlPENvbm5lY3Rpb25TdGF0dXM+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdHVzO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgZW5hYmxlZExvZ2dpbmcoKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9lbmFibGVkTG9nZ2luZztcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2V0IGVuYWJsZWRMb2dnaW5nKHZhbDogYm9vbGVhbikge1xyXG4gICAgICB0aGlzLl9lbmFibGVkTG9nZ2luZyA9IHZhbDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhcnQoKTogUHJvbWlzZTxJU2lnbmFsUkNvbm5lY3Rpb24+IHtcclxuXHJcbiAgICAgICAgY29uc3QgalRyYW5zcG9ydHMgPSB0aGlzLmNvbnZlcnRUcmFuc3BvcnRzKHRoaXMuX2NvbmZpZ3VyYXRpb24udHJhbnNwb3J0KTtcclxuXHJcbiAgICAgICAgY29uc3QgJHByb21pc2UgPSBuZXcgUHJvbWlzZTxJU2lnbmFsUkNvbm5lY3Rpb24+KChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fakNvbm5lY3Rpb25cclxuICAgICAgICAgICAgICAgIC5zdGFydCh7XHJcbiAgICAgICAgICAgICAgICAgICAganNvbnA6IHRoaXMuX2NvbmZpZ3VyYXRpb24uanNvbnAsXHJcbiAgICAgICAgICAgICAgICAgICAgcGluZ0ludGVydmFsOiB0aGlzLl9jb25maWd1cmF0aW9uLnBpbmdJbnRlcnZhbCxcclxuICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnQ6IGpUcmFuc3BvcnRzLFxyXG4gICAgICAgICAgICAgICAgICAgIHdpdGhDcmVkZW50aWFsczogdGhpcy5fY29uZmlndXJhdGlvbi53aXRoQ3JlZGVudGlhbHMsXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmRvbmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9nKCdDb25uZWN0aW9uIGVzdGFibGlzaGVkLCBJRDogJyArIHRoaXMuX2pDb25uZWN0aW9uLmlkKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZygnQ29ubmVjdGlvbiBlc3RhYmxpc2hlZCwgVHJhbnNwb3J0OiAnICsgdGhpcy5fakNvbm5lY3Rpb24udHJhbnNwb3J0Lm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcyk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmZhaWwoKGVycm9yOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZygnQ291bGQgbm90IGNvbm5lY3QnKTtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoJ0ZhaWxlZCB0byBjb25uZWN0LiBFcnJvcjogJyArIGVycm9yLm1lc3NhZ2UpOyAvLyBleDogRXJyb3IgZHVyaW5nIG5lZ290aWF0aW9uIHJlcXVlc3QuXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gJHByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0b3AoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fakNvbm5lY3Rpb24uc3RvcCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgaWQoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fakNvbm5lY3Rpb24uaWQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGludm9rZShtZXRob2Q6IHN0cmluZywgLi4ucGFyYW1ldGVyczogYW55W10pOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGlmIChtZXRob2QgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NpZ25hbFJDb25uZWN0aW9uOiBGYWlsZWQgdG8gaW52b2tlLiBBcmd1bWVudCBcXCdtZXRob2RcXCcgY2FuIG5vdCBiZSBudWxsJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubG9nKGBTaWduYWxSQ29ubmVjdGlvbi4gU3RhcnQgaW52b2tpbmcgXFwnJHttZXRob2R9XFwnLi4uYCk7XHJcblxyXG4gICAgICAgIGNvbnN0ICRwcm9taXNlID0gbmV3IFByb21pc2U8YW55PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2pQcm94eS5pbnZva2UobWV0aG9kLCAuLi5wYXJhbWV0ZXJzKVxyXG4gICAgICAgICAgICAgICAgLmRvbmUoKHJlc3VsdDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2coYFxcJyR7bWV0aG9kfVxcJyBpbnZva2VkIHN1Y2Nlc2Z1bGx5LiBSZXNvbHZpbmcgcHJvbWlzZS4uLmApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZyhgUHJvbWlzZSByZXNvbHZlZC5gKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAuZmFpbCgoZXJyOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZyhgSW52b2tpbmcgXFwnJHttZXRob2R9XFwnIGZhaWxlZC4gUmVqZWN0aW5nIHByb21pc2UuLi5gKTtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZyhgUHJvbWlzZSByZWplY3RlZC5gKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiAkcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbGlzdGVuPFQ+KGxpc3RlbmVyOiBCcm9hZGNhc3RFdmVudExpc3RlbmVyPFQ+KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gbGlzdGVuLiBBcmd1bWVudCBcXCdsaXN0ZW5lclxcJyBjYW4gbm90IGJlIG51bGwnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrOiBDYWxsYmFja0ZuID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMucnVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBjYXN0ZWQ6IFQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc3RlZCA9IGFyZ3NbMF0gYXMgVDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMubG9nKCdTaWduYWxSQ29ubmVjdGlvbi5wcm94eS5vbiBpbnZva2VkLiBDYWxsaW5nIGxpc3RlbmVyIG5leHQoKSAuLi4nKTtcclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyLm5leHQoY2FzdGVkKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9nKCdsaXN0ZW5lciBuZXh0KCkgY2FsbGVkLicpO1xyXG4gICAgICAgICAgICB9LCB0aGlzLl9jb25maWd1cmF0aW9uLmV4ZWN1dGVFdmVudHNJblpvbmUpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHRoaXMuc2V0TGlzdGVuZXIoY2FsbGJhY2ssIGxpc3RlbmVyKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RvcExpc3RlbmluZzxUPihsaXN0ZW5lcjogQnJvYWRjYXN0RXZlbnRMaXN0ZW5lcjxUPik6IHZvaWQge1xyXG4gICAgICAgIGlmIChsaXN0ZW5lciA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGxpc3Rlbi4gQXJndW1lbnQgXFwnbGlzdGVuZXJcXCcgY2FuIG5vdCBiZSBudWxsJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmxvZyhgU2lnbmFsUkNvbm5lY3Rpb246IFN0b3BwaW5nIGxpc3RlbmluZyB0byBzZXJ2ZXIgZXZlbnQgd2l0aCBuYW1lICR7bGlzdGVuZXIuZXZlbnR9YCk7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9saXN0ZW5lcnNbbGlzdGVuZXIuZXZlbnRdKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVyc1tsaXN0ZW5lci5ldmVudF0gPSBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgdGhpcy5fbGlzdGVuZXJzW2xpc3RlbmVyLmV2ZW50XSkge1xyXG4gICAgICAgICAgICB0aGlzLl9qUHJveHkub2ZmKGxpc3RlbmVyLmV2ZW50LCBjYWxsYmFjayk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9saXN0ZW5lcnNbbGlzdGVuZXIuZXZlbnRdID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGxpc3RlbkZvcjxUPihldmVudDogc3RyaW5nKTogQnJvYWRjYXN0RXZlbnRMaXN0ZW5lcjxUPiB7XHJcbiAgICAgICAgaWYgKGV2ZW50ID09IG51bGwgfHwgZXZlbnQgPT09ICcnKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGxpc3Rlbi4gQXJndW1lbnQgXFwnZXZlbnRcXCcgY2FuIG5vdCBiZSBlbXB0eScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBuZXcgQnJvYWRjYXN0RXZlbnRMaXN0ZW5lcjxUPihldmVudCk7XHJcblxyXG4gICAgICAgIHRoaXMubGlzdGVuKGxpc3RlbmVyKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBsaXN0ZW5Gb3JSYXcoZXZlbnQ6IHN0cmluZyk6IEJyb2FkY2FzdEV2ZW50TGlzdGVuZXI8YW55W10+IHtcclxuICAgICAgICBpZiAoZXZlbnQgPT0gbnVsbCB8fCBldmVudCA9PT0gJycpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gbGlzdGVuLiBBcmd1bWVudCBcXCdldmVudFxcJyBjYW4gbm90IGJlIGVtcHR5Jyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IG5ldyBCcm9hZGNhc3RFdmVudExpc3RlbmVyPGFueVtdPihldmVudCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrOiBDYWxsYmFja0ZuID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMucnVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBjYXN0ZWQ6IGFueVtdID0gW107XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzdGVkID0gYXJncztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMubG9nKCdTaWduYWxSQ29ubmVjdGlvbi5wcm94eS5vbiBpbnZva2VkLiBDYWxsaW5nIGxpc3RlbmVyIG5leHQoKSAuLi4nKTtcclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyLm5leHQoYXJncyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZygnbGlzdGVuZXIgbmV4dCgpIGNhbGxlZC4nKTtcclxuICAgICAgICAgICAgfSwgdGhpcy5fY29uZmlndXJhdGlvbi5leGVjdXRlRXZlbnRzSW5ab25lKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB0aGlzLnNldExpc3RlbmVyKGNhbGxiYWNrLCBsaXN0ZW5lcik7XHJcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0TGlzdGVuZXI8VD4oY2FsbGJhY2s6IENhbGxiYWNrRm4sIGxpc3RlbmVyOiBCcm9hZGNhc3RFdmVudExpc3RlbmVyPFQ+KSB7XHJcbiAgICAgICAgdGhpcy5sb2coYFNpZ25hbFJDb25uZWN0aW9uOiBTdGFydGluZyB0byBsaXN0ZW4gdG8gc2VydmVyIGV2ZW50IHdpdGggbmFtZSAke2xpc3RlbmVyLmV2ZW50fWApO1xyXG4gICAgICAgIHRoaXMuX2pQcm94eS5vbihsaXN0ZW5lci5ldmVudCwgY2FsbGJhY2spO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fbGlzdGVuZXJzW2xpc3RlbmVyLmV2ZW50XSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVyc1tsaXN0ZW5lci5ldmVudF0gPSBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2xpc3RlbmVyc1tsaXN0ZW5lci5ldmVudF0ucHVzaChjYWxsYmFjayk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjb252ZXJ0VHJhbnNwb3J0cyh0cmFuc3BvcnRzOiBDb25uZWN0aW9uVHJhbnNwb3J0IHwgQ29ubmVjdGlvblRyYW5zcG9ydFtdKTogYW55IHtcclxuICAgICAgICBpZiAodHJhbnNwb3J0cyBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cmFuc3BvcnRzLm1hcCgodDogQ29ubmVjdGlvblRyYW5zcG9ydCkgPT4gdC5uYW1lKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydHMubmFtZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHdpcmVVcEVycm9yc0FzT2JzZXJ2YWJsZSgpOiBPYnNlcnZhYmxlPGFueT4ge1xyXG4gICAgICAgIGNvbnN0IHNFcnJvciA9IG5ldyBTdWJqZWN0PGFueT4oKTtcclxuXHJcbiAgICAgICAgdGhpcy5fakNvbm5lY3Rpb24uZXJyb3IoKGVycm9yOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5ydW4oKCkgPT4gc0Vycm9yLm5leHQoZXJyb3IpLCB0aGlzLl9jb25maWd1cmF0aW9uLmV4ZWN1dGVFcnJvcnNJblpvbmUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBzRXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSB3aXJlVXBTdGF0dXNFdmVudHNBc09ic2VydmFibGUoKTogT2JzZXJ2YWJsZTxDb25uZWN0aW9uU3RhdHVzPiB7XHJcbiAgICAgICAgY29uc3Qgc1N0YXR1cyA9IG5ldyBTdWJqZWN0PENvbm5lY3Rpb25TdGF0dXM+KCk7XHJcbiAgICAgICAgLy8gYWdncmVnYXRlIGFsbCBzaWduYWxyIGNvbm5lY3Rpb24gc3RhdHVzIGhhbmRsZXJzIGludG8gMSBvYnNlcnZhYmxlLlxyXG4gICAgICAgIC8vIGhhbmRsZXIgd2lyZSB1cCwgZm9yIHNpZ25hbHIgY29ubmVjdGlvbiBzdGF0dXMgY2FsbGJhY2suXHJcbiAgICAgICAgdGhpcy5fakNvbm5lY3Rpb24uc3RhdGVDaGFuZ2VkKChjaGFuZ2U6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnJ1bigoKSA9PiBzU3RhdHVzLm5leHQobmV3IENvbm5lY3Rpb25TdGF0dXMoY2hhbmdlLm5ld1N0YXRlKSksXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25maWd1cmF0aW9uLmV4ZWN1dGVTdGF0dXNDaGFuZ2VJblpvbmUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBzU3RhdHVzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgb25Ccm9hZGNhc3RFdmVudFJlY2VpdmVkPFQ+KGxpc3RlbmVyOiBCcm9hZGNhc3RFdmVudExpc3RlbmVyPFQ+LCAuLi5hcmdzOiBhbnlbXSkge1xyXG4gICAgICAgIHRoaXMubG9nKCdTaWduYWxSQ29ubmVjdGlvbi5wcm94eS5vbiBpbnZva2VkLiBDYWxsaW5nIGxpc3RlbmVyIG5leHQoKSAuLi4nKTtcclxuXHJcbiAgICAgICAgbGV0IGNhc3RlZDogVCA9IG51bGw7XHJcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBjYXN0ZWQgPSBhcmdzWzBdIGFzIFQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICAgIGxpc3RlbmVyLm5leHQoY2FzdGVkKTtcclxuICAgICAgICB9LCB0aGlzLl9jb25maWd1cmF0aW9uLmV4ZWN1dGVFdmVudHNJblpvbmUpO1xyXG5cclxuICAgICAgICB0aGlzLmxvZygnbGlzdGVuZXIgbmV4dCgpIGNhbGxlZC4nKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGxvZyguLi5hcmdzOiBhbnlbXSkge1xyXG4gICAgICAgIGlmICh0aGlzLmVuYWJsZWRMb2dnaW5nID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tY29uc29sZVxyXG4gICAgICAgIGNvbnNvbGUubG9nKGFyZ3Muam9pbignLCAnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBydW4oZnVuYzogKCkgPT4gdm9pZCwgaW5ab25lOiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKGluWm9uZSkge1xyXG4gICAgICAgICAgICB0aGlzLl96b25lLnJ1bigoKSA9PiBmdW5jKCkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gZnVuYygpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIl19