UNPKG

@universis/common

Version:

Universis - common directives and services

215 lines (214 loc) 27.5 kB
import * as tslib_1 from "tslib"; import { Inject, Injectable, InjectionToken, Injector } from '@angular/core'; import { BehaviorSubject, Subject } from 'rxjs'; import { EventSourcePolyfill } from 'event-source-polyfill'; import { ConfigurationService } from '../../shared/services/configuration.service'; import { ActivatedUser } from '../../auth/services/activated-user.service'; import { takeUntil } from 'rxjs/operators'; export var ServerEventServiceStatus; (function (ServerEventServiceStatus) { ServerEventServiceStatus[ServerEventServiceStatus["Connecting"] = 0] = "Connecting"; ServerEventServiceStatus[ServerEventServiceStatus["Open"] = 1] = "Open"; ServerEventServiceStatus[ServerEventServiceStatus["Closed"] = 2] = "Closed"; })(ServerEventServiceStatus || (ServerEventServiceStatus = {})); export let SERVER_EVENT_SUBSCRIBERS = new InjectionToken('server.event.subscribers'); export let SERVER_EVENT_CHILD_SUBSCRIBERS = new InjectionToken('server.event.child.subscribers'); export class ServerEventService { constructor(configuration, injector, addSubscribers) { this.configuration = configuration; this.injector = injector; this.addSubscribers = addSubscribers; this.message = new BehaviorSubject(null); this.error = new BehaviorSubject(null); this._heartbeatTimeout = 120 * 1000; this.subscribers = new Map(); this.destroy$ = new Subject(); this.configuration.loaded .pipe(takeUntil(this.destroy$)) .subscribe(applicationConfiguration => { if (applicationConfiguration != null) { // inject activated user only after config is loaded this.activatedUser = this.injector.get(ActivatedUser); // load this.load(); // and destroy subscription this.closeSubscription(); } }); } closeSubscription() { this.destroy$.next(); this.destroy$.complete(); } load() { if (this.configuration.config && this.configuration.config.settings && this.configuration.config.settings.serverEvent) { const serverEvent = this.configuration.config.settings.serverEvent; if (serverEvent.heartbeatTimeout) { this._heartbeatTimeout = serverEvent.heartbeatTimeout; } } if (Array.isArray(this.addSubscribers)) { this.addSubscribers.forEach((addSubscriber) => { this.subscribe(addSubscriber); }); } this.activatedUser.user.subscribe((user) => { if (user == null) { if (this.status === ServerEventServiceStatus.Open) { this.close(); } } if (user) { if (this.status === ServerEventServiceStatus.Open) { this.close(); } this.open(); } }); } /** * Adds a server event subscriber * @param token */ subscribe(token) { const subscriber = this.injector.get(token); if (subscriber == null) { throw new Error('Server event subscriber cannot be instantiated.'); } if (typeof subscriber.subscribe !== 'function') { throw new Error('Expected an instance which implements ServerEventSubscriber.'); } const observer = subscriber.subscribe.bind(subscriber); this.subscribers.set(token, this.message.subscribe(observer)); } /** * Removes a server event subscriber * @param token */ unsubscribe(token) { const subscription = this.subscribers.get(token); // if subscription is not null if (subscription != null) { // unsubscribe subscription.unsubscribe(); } // remove item this.subscribers.delete(token); } get source() { if (this.configuration.settings && this.configuration.settings.remote && this.configuration.settings.remote.server) { return new URL('users/me/events/subscribe', this.configuration.settings.remote.server).toString(); } return '/users/me/events/subscribe'; } get heartbeatTimeout() { return this._heartbeatTimeout; } get status() { if (this.eventSource) { return this.eventSource.readyState; } return ServerEventServiceStatus.Closed; } openAsync() { return tslib_1.__awaiter(this, void 0, void 0, function* () { return this.open(); }); } getUserSync() { const value = sessionStorage.getItem('currentUser'); if (value == null) { return; } return JSON.parse(value); } open() { if (this.status === ServerEventServiceStatus.Open) { return this; } const user = this.getUserSync(); const headers = { 'Accept': 'application/json', 'Authorization': `Bearer ${user.token.access_token}` }; this.eventSource = new EventSourcePolyfill(this.source, { heartbeatTimeout: this.heartbeatTimeout, headers }); const messageListener = this.onMessage.bind(this); const errorListener = this.onError.bind(this); this.eventSource.addEventListener('message', messageListener); this.eventSource.addEventListener('error', errorListener); // set heartbeat interval this._heartbeatInterval = setInterval(() => { // close if (this.eventSource && this.eventSource.readyState !== ServerEventServiceStatus.Closed) { this.eventSource.close(); } const user = this.getUserSync(); if (user == null) { return; } const headers = { 'Accept': 'application/json', 'Authorization': `Bearer ${user.token.access_token}` }; // and create new this.eventSource = new EventSourcePolyfill(this.source, { heartbeatTimeout: this.heartbeatTimeout, headers }); // set listeners this.eventSource.addEventListener('message', messageListener); this.eventSource.addEventListener('error', errorListener); }, this.heartbeatTimeout - 5000); // set heartbeat interval return this; } onMessage(ev) { // emit message if (ev.type === 'message') { let data = null; if (typeof ev.data === 'string') { data = JSON.parse(ev.data); } else if (typeof ev.data === 'object') { data = ev.data; } if (data) { this.message.next(data); } } } onError(ev) { // emit error if (ev.error) { return this.error.next(ev.error); } return this.error.next(ev); } close() { if (this.eventSource) { this.eventSource.close(); return true; } // clear heartbeat interval if (this._heartbeatInterval) { clearInterval(this._heartbeatInterval); } return false; } } ServerEventService.decorators = [ { type: Injectable } ]; /** @nocollapse */ ServerEventService.ctorParameters = () => [ { type: ConfigurationService }, { type: Injector }, { type: Array, decorators: [{ type: Inject, args: [SERVER_EVENT_SUBSCRIBERS,] }] } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWV2ZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AdW5pdmVyc2lzL2NvbW1vbi8iLCJzb3VyY2VzIjpbImV2ZW50cy9zZXJ2aWNlcy9zZXJ2ZXItZXZlbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBTyxNQUFNLGVBQWUsQ0FBQztBQUNqRixPQUFPLEVBQUMsZUFBZSxFQUFFLE9BQU8sRUFBZSxNQUFNLE1BQU0sQ0FBQztBQUM1RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUNuRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE1BQU0sQ0FBTixJQUFZLHdCQUlYO0FBSkQsV0FBWSx3QkFBd0I7SUFDaEMsbUZBQVUsQ0FBQTtJQUNWLHVFQUFJLENBQUE7SUFDSiwyRUFBTSxDQUFBO0FBQ1YsQ0FBQyxFQUpXLHdCQUF3QixLQUF4Qix3QkFBd0IsUUFJbkM7QUFrQ0QsTUFBTSxDQUFDLElBQUksd0JBQXdCLEdBQUcsSUFBSSxjQUFjLENBQXFDLDBCQUEwQixDQUFDLENBQUM7QUFFekgsTUFBTSxDQUFDLElBQUksOEJBQThCLEdBQUcsSUFBSSxjQUFjLENBQXFDLGdDQUFnQyxDQUFDLENBQUM7QUFHckksTUFBTTtJQVVGLFlBQW9CLGFBQW1DLEVBQzNDLFFBQWtCLEVBQ2dCLGNBQWtEO1FBRjVFLGtCQUFhLEdBQWIsYUFBYSxDQUFzQjtRQUMzQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2dCLG1CQUFjLEdBQWQsY0FBYyxDQUFvQztRQVh6RixZQUFPLEdBQXlCLElBQUksZUFBZSxDQUFNLElBQUksQ0FB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RSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQzlCO2lCQUFNLElBQUksT0FBTyxFQUFFLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtnQkFDcEMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7YUFDbEI7WUFDRCxJQUFJLElBQUksRUFBRTtnQkFDTixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUMzQjtTQUNKO0lBQ0wsQ0FBQztJQUVTLE9BQU8sQ0FBQyxFQUFPO1FBQ3JCLGFBQWE7UUFDYixJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUU7WUFDVixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNwQztRQUNELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELEtBQUs7UUFDRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN6QixPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsMkJBQTJCO1FBQzNCLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztTQUMxQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7OztZQXpNSixVQUFVOzs7O1lBN0NGLG9CQUFvQjtZQUhlLFFBQVE7WUE2RGMsS0FBSyx1QkFBOUQsTUFBTSxTQUFDLHdCQUF3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbiwgSW5qZWN0b3IsIFR5cGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIFN1YmplY3QsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBFdmVudFNvdXJjZVBvbHlmaWxsIH0gZnJvbSAnZXZlbnQtc291cmNlLXBvbHlmaWxsJztcbmltcG9ydCB7IENvbmZpZ3VyYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlcnZpY2VzL2NvbmZpZ3VyYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRVc2VyIH0gZnJvbSAnLi4vLi4vYXV0aC9zZXJ2aWNlcy9hY3RpdmF0ZWQtdXNlci5zZXJ2aWNlJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmV4cG9ydCBlbnVtIFNlcnZlckV2ZW50U2VydmljZVN0YXR1cyB7XG4gICAgQ29ubmVjdGluZyxcbiAgICBPcGVuLFxuICAgIENsb3NlZFxufVxuXG5kZWNsYXJlIGludGVyZmFjZSBVc2VyU25hcHNob3Qge1xuICAgIGlkPzogYW55O1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0b2tlbjoge1xuICAgICAgICBhY2Nlc3NfdG9rZW46IHN0cmluZztcbiAgICAgICAgc2NvcGU6IHN0cmluZztcbiAgICB9O1xufVxuXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgU2VydmVyRXZlbnQge1xuICAgIGlkPzogc3RyaW5nO1xuICAgIGFkZGl0aW9uYWxUeXBlPzogc3RyaW5nO1xuICAgIGVudGl0eVNldD86IHN0cmluZztcbiAgICBlbnRpdHlUeXBlPzogc3RyaW5nO1xuICAgIGVudGl0eUFjdGlvbj86IHN0cmluZztcbiAgICB0YXJnZXQ/OiBhbnk7XG4gICAgcmVzdWx0PzogYW55O1xuICAgIHN0YXR1cz86IGFueTtcbiAgICBlcnJvcj86IGFueTtcbiAgICByZWNpcGllbnQ/OiBzdHJpbmc7XG4gICAgc2NvcGU/OiBzdHJpbmc7XG4gICAgZGF0ZUNyZWF0ZWQ/OiBEYXRlO1xufVxuXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgU2VydmVyRXZlbnRTdWJzY3JpYmVyIHtcbiAgICBzdWJzY3JpYmU8VD4oZXZlbnQ6IFQpOiB2b2lkO1xufVxuXG5kZWNsYXJlIGludGVyZmFjZSBTZXJ2ZXJFdmVudFNlcnZpY2VDb25maWd1cmF0aW9uIHtcbiAgICBoZWFydGJlYXRUaW1lb3V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgbGV0IFNFUlZFUl9FVkVOVF9TVUJTQ1JJQkVSUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxBcnJheTxUeXBlPFNlcnZlckV2ZW50U3Vic2NyaWJlcj4+Pignc2VydmVyLmV2ZW50LnN1YnNjcmliZXJzJyk7XG5cbmV4cG9ydCBsZXQgU0VSVkVSX0VWRU5UX0NISUxEX1NVQlNDUklCRVJTID0gbmV3IEluamVjdGlvblRva2VuPEFycmF5PFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPj4+KCdzZXJ2ZXIuZXZlbnQuY2hpbGQuc3Vic2NyaWJlcnMnKTtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFNlcnZlckV2ZW50U2VydmljZSB7XG4gICAgcHVibGljIG1lc3NhZ2U6IEJlaGF2aW9yU3ViamVjdDxhbnk+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnk+KG51bGwpO1xuICAgIHB1YmxpYyBlcnJvcjogQmVoYXZpb3JTdWJqZWN0PGFueT4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7XG4gICAgcHJpdmF0ZSBldmVudFNvdXJjZTogRXZlbnRTb3VyY2VQb2x5ZmlsbDtcbiAgICBwcml2YXRlIF9oZWFydGJlYXRUaW1lb3V0ID0gMTIwICogMTAwMDtcbiAgICBwcml2YXRlIF9oZWFydGJlYXRJbnRlcnZhbDogYW55O1xuICAgIHByaXZhdGUgYWN0aXZhdGVkVXNlcjogQWN0aXZhdGVkVXNlcjtcbiAgICBwdWJsaWMgc3Vic2NyaWJlcnM6IE1hcDxhbnksIFN1YnNjcmlwdGlvbj4gPSBuZXcgTWFwKCk7XG4gICAgcHJpdmF0ZSBkZXN0cm95JDogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IENvbmZpZ3VyYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICAgICAgQEluamVjdChTRVJWRVJfRVZFTlRfU1VCU0NSSUJFUlMpIHByaXZhdGUgYWRkU3Vic2NyaWJlcnM6IEFycmF5PFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPj4pIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5sb2FkZWRcbiAgICAgICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZShhcHBsaWNhdGlvbkNvbmZpZ3VyYXRpb24gPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcHBsaWNhdGlvbkNvbmZpZ3VyYXRpb24gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpbmplY3QgYWN0aXZhdGVkIHVzZXIgb25seSBhZnRlciBjb25maWcgaXMgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVkVXNlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KEFjdGl2YXRlZFVzZXIpO1xuICAgICAgICAgICAgICAgICAgICAvLyBsb2FkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICAvLyBhbmQgZGVzdHJveSBzdWJzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9zZVN1YnNjcmlwdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICBjbG9zZVN1YnNjcmlwdGlvbigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBsb2FkKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZ1xuICAgICAgICAgICAgJiYgdGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZy5zZXR0aW5nc1xuICAgICAgICAgICAgJiYgdGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZy5zZXR0aW5ncy5zZXJ2ZXJFdmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlcnZlckV2ZW50OiBTZXJ2ZXJFdmVudFNlcnZpY2VDb25maWd1cmF0aW9uID0gdGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZy5zZXR0aW5ncy5zZXJ2ZXJFdmVudDtcbiAgICAgICAgICAgICAgICBpZiAoc2VydmVyRXZlbnQuaGVhcnRiZWF0VGltZW91dCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9oZWFydGJlYXRUaW1lb3V0ID0gc2VydmVyRXZlbnQuaGVhcnRiZWF0VGltZW91dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5hZGRTdWJzY3JpYmVycykpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkU3Vic2NyaWJlcnMuZm9yRWFjaCgoYWRkU3Vic2NyaWJlcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3Vic2NyaWJlKGFkZFN1YnNjcmliZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hY3RpdmF0ZWRVc2VyLnVzZXIuc3Vic2NyaWJlKCh1c2VyKSA9PiB7XG4gICAgICAgICAgICBpZiAodXNlciA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdHVzID09PSBTZXJ2ZXJFdmVudFNlcnZpY2VTdGF0dXMuT3Blbikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT09IFNlcnZlckV2ZW50U2VydmljZVN0YXR1cy5PcGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBzZXJ2ZXIgZXZlbnQgc3Vic2NyaWJlclxuICAgICAqIEBwYXJhbSB0b2tlblxuICAgICAqL1xuICAgIHN1YnNjcmliZSh0b2tlbjogVHlwZTxTZXJ2ZXJFdmVudFN1YnNjcmliZXI+KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXI6IFNlcnZlckV2ZW50U3Vic2NyaWJlciA9IHRoaXMuaW5qZWN0b3IuZ2V0PFNlcnZlckV2ZW50U3Vic2NyaWJlcj4odG9rZW4pO1xuICAgICAgICBpZiAoc3Vic2NyaWJlciA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZlciBldmVudCBzdWJzY3JpYmVyIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBzdWJzY3JpYmVyLnN1YnNjcmliZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBhbiBpbnN0YW5jZSB3aGljaCBpbXBsZW1lbnRzIFNlcnZlckV2ZW50U3Vic2NyaWJlci4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvYnNlcnZlciA9IHN1YnNjcmliZXIuc3Vic2NyaWJlLmJpbmQoc3Vic2NyaWJlcik7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlcnMuc2V0KHRva2VuLCB0aGlzLm1lc3NhZ2Uuc3Vic2NyaWJlKG9ic2VydmVyKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIHNlcnZlciBldmVudCBzdWJzY3JpYmVyXG4gICAgICogQHBhcmFtIHRva2VuXG4gICAgICovXG4gICAgdW5zdWJzY3JpYmUodG9rZW46IFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPik6IHZvaWQge1xuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IHRoaXMuc3Vic2NyaWJlcnMuZ2V0KHRva2VuKTtcbiAgICAgICAgLy8gaWYgc3Vic2NyaXB0aW9uIGlzIG5vdCBudWxsXG4gICAgICAgIGlmIChzdWJzY3JpcHRpb24gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gdW5zdWJzY3JpYmVcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlbW92ZSBpdGVtXG4gICAgICAgIHRoaXMuc3Vic2NyaWJlcnMuZGVsZXRlKHRva2VuKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IHNvdXJjZSgpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uLnNldHRpbmdzICYmXG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0dGluZ3MucmVtb3RlICYmXG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0dGluZ3MucmVtb3RlLnNlcnZlcikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkwoJ3VzZXJzL21lL2V2ZW50cy9zdWJzY3JpYmUnLCB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0dGluZ3MucmVtb3RlLnNlcnZlcikudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJy91c2Vycy9tZS9ldmVudHMvc3Vic2NyaWJlJztcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGhlYXJ0YmVhdFRpbWVvdXQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlYXJ0YmVhdFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgZ2V0IHN0YXR1cygpOiBTZXJ2ZXJFdmVudFNlcnZpY2VTdGF0dXMge1xuICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTb3VyY2UucmVhZHlTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU2VydmVyRXZlbnRTZXJ2aWNlU3RhdHVzLkNsb3NlZDtcbiAgICB9XG5cbiAgICBhc3luYyBvcGVuQXN5bmMoKTogUHJvbWlzZTxTZXJ2ZXJFdmVudFNlcnZpY2U+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3BlbigpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0VXNlclN5bmMoKTogVXNlclNuYXBzaG90IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdjdXJyZW50VXNlcicpO1xuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlKSBhcyBVc2VyU25hcHNob3Q7XG4gICAgfVxuXG4gICAgb3BlbigpOiB0aGlzIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdHVzID09PSBTZXJ2ZXJFdmVudFNlcnZpY2VTdGF0dXMuT3Blbikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXNlcjogVXNlclNuYXBzaG90ID0gdGhpcy5nZXRVc2VyU3luYygpO1xuICAgICAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICdBdXRob3JpemF0aW9uJzogYEJlYXJlciAke3VzZXIudG9rZW4uYWNjZXNzX3Rva2VufWBcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5ldmVudFNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZVBvbHlmaWxsKHRoaXMuc291cmNlLCB7XG4gICAgICAgICAgICBoZWFydGJlYXRUaW1lb3V0OiB0aGlzLmhlYXJ0YmVhdFRpbWVvdXQsXG4gICAgICAgICAgICBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBtZXNzYWdlTGlzdGVuZXIgPSB0aGlzLm9uTWVzc2FnZS5iaW5kKHRoaXMpO1xuICAgICAgICBjb25zdCBlcnJvckxpc3RlbmVyID0gdGhpcy5vbkVycm9yLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG1lc3NhZ2VMaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBlcnJvckxpc3RlbmVyKTtcbiAgICAgICAgLy8gc2V0IGhlYXJ0YmVhdCBpbnRlcnZhbFxuICAgICAgICB0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNsb3NlXG4gICAgICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSAmJiB0aGlzLmV2ZW50U291cmNlLnJlYWR5U3RhdGUgIT09IFNlcnZlckV2ZW50U2VydmljZVN0YXR1cy5DbG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50U291cmNlLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB1c2VyID0gdGhpcy5nZXRVc2VyU3luYygpO1xuICAgICAgICAgICAgaWYgKHVzZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGhlYWRlcnMgPSB7XG4gICAgICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHt1c2VyLnRva2VuLmFjY2Vzc190b2tlbn1gXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gYW5kIGNyZWF0ZSBuZXdcbiAgICAgICAgICAgIHRoaXMuZXZlbnRTb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2VQb2x5ZmlsbCh0aGlzLnNvdXJjZSwge1xuICAgICAgICAgICAgICAgIGhlYXJ0YmVhdFRpbWVvdXQ6IHRoaXMuaGVhcnRiZWF0VGltZW91dCxcbiAgICAgICAgICAgICAgICBoZWFkZXJzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHNldCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG1lc3NhZ2VMaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50U291cmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZXJyb3JMaXN0ZW5lcik7XG4gICAgICAgIH0sIHRoaXMuaGVhcnRiZWF0VGltZW91dCAtIDUwMDApOyAvLyBzZXQgaGVhcnRiZWF0IGludGVydmFsXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBvbk1lc3NhZ2UoZXY6IGFueSk6IHZvaWQge1xuICAgICAgICAvLyBlbWl0IG1lc3NhZ2VcbiAgICAgICAgaWYgKGV2LnR5cGUgPT09ICdtZXNzYWdlJykge1xuICAgICAgICAgICAgbGV0IGRhdGE6IGFueSA9IG51bGw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGV2LmRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZXYuZGF0YSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBldi5kYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIGRhdGEgPSBldi5kYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2UubmV4dChkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBvbkVycm9yKGV2OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgLy8gZW1pdCBlcnJvclxuICAgICAgICBpZiAoZXYuZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yLm5leHQoZXYuZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yLm5leHQoZXYpO1xuICAgIH1cblxuICAgIGNsb3NlKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5ldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY2xlYXIgaGVhcnRiZWF0IGludGVydmFsXG4gICAgICAgIGlmICh0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxufVxuIl19