ng-alertbar
Version:
A configurable alertbar for Angular
445 lines • 31.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { Subject, timer } from 'rxjs';
import { filter, mapTo, switchMap, take, takeUntil } from 'rxjs/operators';
import { slide } from './animations';
import { defaults } from './defaults';
import { NgAlertbarService } from './ng-alertbar.service';
/** @type {?} */
var ALERT_LEAVE_ANIMATION_DURATION = 200;
var NgAlertbarComponent = /** @class */ (function () {
function NgAlertbarComponent(alertBarService, domSanitizer) {
this.alertBarService = alertBarService;
this.domSanitizer = domSanitizer;
this.queue = [];
this.queuePop = new Subject();
this.queueing = defaults.queueingEnabled;
this.lifeTime = defaults.lifeTimeMs;
this.showDelay = defaults.showDelayMs;
this.backgroundColor = defaults.backgroundColor;
this.borderColor = defaults.borderColor;
this.textColor = defaults.textColor;
this.widthMode = defaults.widthMode;
this.closeButton = defaults.closeButtonEnabled;
this.html = defaults.useHtml;
this.open = new EventEmitter();
this.close = new EventEmitter();
this.show = false;
this.destroy = new Subject();
}
Object.defineProperty(NgAlertbarComponent.prototype, "isFullWidth", {
get: /**
* @return {?}
*/
function () {
if (this.tempWidthMode) {
return this.tempWidthMode === 'full';
}
return this.widthMode === 'full';
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgAlertbarComponent.prototype, "showCloseButton", {
get: /**
* @return {?}
*/
function () {
if (this.tempCloseButton != null) {
return this.tempCloseButton;
}
return this.closeButton;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgAlertbarComponent.prototype, "useHtml", {
get: /**
* @return {?}
*/
function () {
if (this.tempHtml != null) {
return this.tempHtml;
}
return this.html;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgAlertbarComponent.prototype, "htmlMessage", {
get: /**
* @return {?}
*/
function () {
return this.domSanitizer.bypassSecurityTrustHtml(this.message);
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgAlertbarComponent.prototype, "openTriggerPostDelay$", {
/**
* The trigger stream after waiting the specified showDelay since the alert was triggered
*/
get: /**
* The trigger stream after waiting the specified showDelay since the alert was triggered
* @return {?}
*/
function () {
var _this = this;
return this.alertBarService.trigger$.pipe(switchMap((/**
* @param {?} trigger
* @return {?}
*/
function (trigger) {
/** @type {?} */
var options = trigger.options;
/** @type {?} */
var showDelay = (options && options.showDelay) || _this.showDelay;
return timer(showDelay).pipe(mapTo(trigger));
})), takeUntil(this.destroy));
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgAlertbarComponent.prototype, "postAlertLifetime$", {
/**
* The trigger stream after waiting the specified lifetime since the alert opened
*/
get: /**
* The trigger stream after waiting the specified lifetime since the alert opened
* @return {?}
*/
function () {
var _this = this;
return this.open.pipe(filter((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var options = _a.options;
return _this.shouldAlertAutoClose(options);
})), switchMap((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var options = _a.options;
/** @type {?} */
var lifeTime = (options && options.lifeTime) || _this.lifeTime;
return timer(lifeTime);
})), takeUntil(this.destroy));
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgAlertbarComponent.prototype, "cancelTrigger$", {
/**
* The service cancel trigger
*/
get: /**
* The service cancel trigger
* @return {?}
*/
function () {
return this.alertBarService.cancel$.pipe(takeUntil(this.destroy));
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgAlertbarComponent.prototype, "alertLeaveTimer", {
/**
* Timer representing the delay taken for an alert to animate when exiting
*/
get: /**
* Timer representing the delay taken for an alert to animate when exiting
* @return {?}
*/
function () {
return timer(ALERT_LEAVE_ANIMATION_DURATION).pipe(take(1));
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
NgAlertbarComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.openTriggerPostDelay$.subscribe((/**
* @param {?} trigger
* @return {?}
*/
function (trigger) { return _this.onTrigger(trigger); }));
this.queuePop.subscribe((/**
* @param {?} trigger
* @return {?}
*/
function (trigger) { return _this.showAlert(trigger); }));
this.postAlertLifetime$.subscribe((/**
* @return {?}
*/
function () { return _this.onClose(); }));
this.cancelTrigger$.subscribe((/**
* @return {?}
*/
function () { return _this.onClose(); }));
};
/**
* @return {?}
*/
NgAlertbarComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroy.next();
};
/**
* @private
* @param {?} trigger
* @return {?}
*/
NgAlertbarComponent.prototype.onTrigger = /**
* @private
* @param {?} trigger
* @return {?}
*/
function (trigger) {
if (this.queueing && !(trigger.options && trigger.options.bypassQueue) && this.show) {
this.queue.push(trigger);
return;
}
this.showAlert(trigger);
};
/**
* Sets up temp variables and shows the alert
* @param trigger The trigger to display
*/
/**
* Sets up temp variables and shows the alert
* @private
* @param {?} trigger The trigger to display
* @return {?}
*/
NgAlertbarComponent.prototype.showAlert = /**
* Sets up temp variables and shows the alert
* @private
* @param {?} trigger The trigger to display
* @return {?}
*/
function (trigger) {
this.clearTempOptions(); // Clear previous temporary options
this.assignTempOptions(trigger.options);
this.message = trigger.message;
this.show = true;
this.open.emit(trigger);
};
/**
* Closes any open alert. If there are any alerts waiting in the queue,
* the alert is popped off the queue and emitted for opening
*/
/**
* Closes any open alert. If there are any alerts waiting in the queue,
* the alert is popped off the queue and emitted for opening
* @return {?}
*/
NgAlertbarComponent.prototype.onClose = /**
* Closes any open alert. If there are any alerts waiting in the queue,
* the alert is popped off the queue and emitted for opening
* @return {?}
*/
function () {
var _this = this;
this.closeAlert();
if (this.queue.length > 0) {
this.alertLeaveTimer.subscribe((/**
* @return {?}
*/
function () {
_this.queuePop.next(_this.queue.shift());
}));
}
};
/**
* @private
* @return {?}
*/
NgAlertbarComponent.prototype.closeAlert = /**
* @private
* @return {?}
*/
function () {
this.show = false;
this.close.emit();
};
/**
* Clears out any temporary config options so that they
* do not persist beyond their single use
*/
/**
* Clears out any temporary config options so that they
* do not persist beyond their single use
* @private
* @return {?}
*/
NgAlertbarComponent.prototype.clearTempOptions = /**
* Clears out any temporary config options so that they
* do not persist beyond their single use
* @private
* @return {?}
*/
function () {
this.tempBackgroundColor = null;
this.tempBorderColor = null;
this.tempTextColor = null;
this.tempWidthMode = null;
this.tempCloseButton = null;
this.tempHtml = null;
};
/**
* Assigns the options included in the trigger to the temporary
* config variables so they can apply for the upcoming alert
* @param options The options passed in the trigger
*/
/**
* Assigns the options included in the trigger to the temporary
* config variables so they can apply for the upcoming alert
* @private
* @param {?} options The options passed in the trigger
* @return {?}
*/
NgAlertbarComponent.prototype.assignTempOptions = /**
* Assigns the options included in the trigger to the temporary
* config variables so they can apply for the upcoming alert
* @private
* @param {?} options The options passed in the trigger
* @return {?}
*/
function (options) {
if (!options) {
return;
}
this.tempBackgroundColor = options.backgroundColor;
this.tempBorderColor = options.borderColor;
this.tempTextColor = options.textColor;
this.tempWidthMode = options.widthMode;
this.tempCloseButton = options.closeButton;
this.tempHtml = options.html;
};
/**
* @private
* @param {?} options
* @return {?}
*/
NgAlertbarComponent.prototype.shouldAlertAutoClose = /**
* @private
* @param {?} options
* @return {?}
*/
function (options) {
if (options && options.lifeTime != null) {
return options.lifeTime > 0;
}
return this.lifeTime > 0; // Fallback to component setting
};
NgAlertbarComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-alertbar',
template: "\n <div *ngIf=\"show\" [@slide] class=\"ng-alert-bar-wrapper\">\n <div\n class=\"ng-alert-bar\"\n [class.full-width]=\"isFullWidth\"\n [style.background]=\"tempBackgroundColor || backgroundColor\"\n [style.border-color]=\"tempBorderColor || borderColor\"\n >\n <span class=\"ng-alert-bar-text\" [style.color]=\"tempTextColor || textColor\">\n <span *ngIf=\"!useHtml; else htmlMessageContainer\">{{ message }}</span>\n <ng-template #htmlMessageContainer><span [innerHTML]=\"htmlMessage\"></span></ng-template>\n <span *ngIf=\"showCloseButton\" class=\"ng-alert-close\" (click)=\"onClose()\">×</span>\n </span>\n </div>\n </div>\n ",
animations: [slide],
styles: [".ng-alert-bar-wrapper{position:absolute;top:0;left:0;width:100%;text-align:center;pointer-events:none}.ng-alert-bar{pointer-events:all}.ng-alert-bar:not(.full-width){display:inline-block}.ng-alert-close{font-size:1.1em;margin-left:.25rem;vertical-align:middle;cursor:pointer}"]
}] }
];
/** @nocollapse */
NgAlertbarComponent.ctorParameters = function () { return [
{ type: NgAlertbarService },
{ type: DomSanitizer }
]; };
NgAlertbarComponent.propDecorators = {
queueing: [{ type: Input }],
lifeTime: [{ type: Input }],
showDelay: [{ type: Input }],
backgroundColor: [{ type: Input }],
borderColor: [{ type: Input }],
textColor: [{ type: Input }],
widthMode: [{ type: Input }],
closeButton: [{ type: Input }],
html: [{ type: Input }],
open: [{ type: Output }],
close: [{ type: Output }]
};
return NgAlertbarComponent;
}());
export { NgAlertbarComponent };
if (false) {
/**
* @type {?}
* @private
*/
NgAlertbarComponent.prototype.queue;
/**
* @type {?}
* @private
*/
NgAlertbarComponent.prototype.queuePop;
/** @type {?} */
NgAlertbarComponent.prototype.queueing;
/** @type {?} */
NgAlertbarComponent.prototype.lifeTime;
/** @type {?} */
NgAlertbarComponent.prototype.showDelay;
/** @type {?} */
NgAlertbarComponent.prototype.backgroundColor;
/** @type {?} */
NgAlertbarComponent.prototype.tempBackgroundColor;
/** @type {?} */
NgAlertbarComponent.prototype.borderColor;
/** @type {?} */
NgAlertbarComponent.prototype.tempBorderColor;
/** @type {?} */
NgAlertbarComponent.prototype.textColor;
/** @type {?} */
NgAlertbarComponent.prototype.tempTextColor;
/** @type {?} */
NgAlertbarComponent.prototype.widthMode;
/** @type {?} */
NgAlertbarComponent.prototype.tempWidthMode;
/** @type {?} */
NgAlertbarComponent.prototype.closeButton;
/** @type {?} */
NgAlertbarComponent.prototype.tempCloseButton;
/** @type {?} */
NgAlertbarComponent.prototype.html;
/** @type {?} */
NgAlertbarComponent.prototype.tempHtml;
/** @type {?} */
NgAlertbarComponent.prototype.open;
/** @type {?} */
NgAlertbarComponent.prototype.close;
/** @type {?} */
NgAlertbarComponent.prototype.show;
/** @type {?} */
NgAlertbarComponent.prototype.message;
/**
* @type {?}
* @private
*/
NgAlertbarComponent.prototype.destroy;
/**
* @type {?}
* @private
*/
NgAlertbarComponent.prototype.alertBarService;
/**
* @type {?}
* @private
*/
NgAlertbarComponent.prototype.domSanitizer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctYWxlcnRiYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctYWxlcnRiYXIvIiwic291cmNlcyI6WyJsaWIvbmctYWxlcnRiYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFdEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7O0lBRXBELDhCQUE4QixHQUFHLEdBQUc7QUFFMUM7SUFxSEUsNkJBQW9CLGVBQWtDLEVBQVUsWUFBMEI7UUFBdEUsb0JBQWUsR0FBZixlQUFlLENBQW1CO1FBQVUsaUJBQVksR0FBWixZQUFZLENBQWM7UUEvRmxGLFVBQUssR0FBbUIsRUFBRSxDQUFDO1FBQzNCLGFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBZ0IsQ0FBQztRQUV0QyxhQUFRLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQztRQUNwQyxhQUFRLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQztRQUMvQixjQUFTLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQztRQUVqQyxvQkFBZSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFFM0MsZ0JBQVcsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDO1FBRW5DLGNBQVMsR0FB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LE1BQU07d0JBQ04sTUFBTTs7SUFnS1QsMEJBQUM7Q0FBQSxBQTVNRCxJQTRNQztTQXZMWSxtQkFBbUI7Ozs7OztJQUM5QixvQ0FBbUM7Ozs7O0lBQ25DLHVDQUErQzs7SUFFL0MsdUNBQTZDOztJQUM3Qyx1Q0FBd0M7O0lBQ3hDLHdDQUEwQzs7SUFFMUMsOENBQW9EOztJQUNwRCxrREFBNEI7O0lBQzVCLDBDQUE0Qzs7SUFDNUMsOENBQXdCOztJQUN4Qix3Q0FBd0M7O0lBQ3hDLDRDQUFzQjs7SUFFdEIsd0NBQXdDOztJQUN4Qyw0Q0FBa0M7O0lBQ2xDLDBDQUFtRDs7SUFDbkQsOENBQXlCOztJQUN6QixtQ0FBaUM7O0lBQ2pDLHVDQUFrQjs7SUFFbEIsbUNBQWtEOztJQUNsRCxvQ0FBMkM7O0lBRTNDLG1DQUFhOztJQUNiLHNDQUFnQjs7Ozs7SUFDaEIsc0NBQXNDOzs7OztJQXFFMUIsOENBQTBDOzs7OztJQUFFLDJDQUFrQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBTdWJqZWN0LCB0aW1lciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBtYXBUbywgc3dpdGNoTWFwLCB0YWtlLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBzbGlkZSB9IGZyb20gJy4vYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBkZWZhdWx0cyB9IGZyb20gJy4vZGVmYXVsdHMnO1xuaW1wb3J0IHsgQWxlcnRPcHRpb25zLCBBbGVydFRyaWdnZXIgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBOZ0FsZXJ0YmFyU2VydmljZSB9IGZyb20gJy4vbmctYWxlcnRiYXIuc2VydmljZSc7XG5cbmNvbnN0IEFMRVJUX0xFQVZFX0FOSU1BVElPTl9EVVJBVElPTiA9IDIwMDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmctYWxlcnRiYXInLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgKm5nSWY9XCJzaG93XCIgW0BzbGlkZV0gY2xhc3M9XCJuZy1hbGVydC1iYXItd3JhcHBlclwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cIm5nLWFsZXJ0LWJhclwiXG4gICAgICAgIFtjbGFzcy5mdWxsLXdpZHRoXT1cImlzRnVsbFdpZHRoXCJcbiAgICAgICAgW3N0eWxlLmJhY2tncm91bmRdPVwidGVtcEJhY2tncm91bmRDb2xvciB8fCBiYWNrZ3JvdW5kQ29sb3JcIlxuICAgICAgICBbc3R5bGUuYm9yZGVyLWNvbG9yXT1cInRlbXBCb3JkZXJDb2xvciB8fCBib3JkZXJDb2xvclwiXG4gICAgICA+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmctYWxlcnQtYmFyLXRleHRcIiBbc3R5bGUuY29sb3JdPVwidGVtcFRleHRDb2xvciB8fCB0ZXh0Q29sb3JcIj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cIiF1c2VIdG1sOyBlbHNlIGh0bWxNZXNzYWdlQ29udGFpbmVyXCI+e3sgbWVzc2FnZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2h0bWxNZXNzYWdlQ29udGFpbmVyPjxzcGFuIFtpbm5lckhUTUxdPVwiaHRtbE1lc3NhZ2VcIj48L3NwYW4+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cInNob3dDbG9zZUJ1dHRvblwiIGNsYXNzPVwibmctYWxlcnQtY2xvc2VcIiAoY2xpY2spPVwib25DbG9zZSgpXCI+JnRpbWVzOzwvc3Bhbj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlVXJsczogWycuL25nLWFsZXJ0YmFyLmNvbXBvbmVudC5jc3MnXSxcbiAgYW5pbWF0aW9uczogW3NsaWRlXVxufSlcbmV4cG9ydCBjbGFzcyBOZ0FsZXJ0YmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHF1ZXVlOiBBbGVydFRyaWdnZXJbXSA9IFtdO1xuICBwcml2YXRlIHF1ZXVlUG9wID0gbmV3IFN1YmplY3Q8QWxlcnRUcmlnZ2VyPigpO1xuXG4gIEBJbnB1dCgpIHF1ZXVlaW5nID0gZGVmYXVsdHMucXVldWVpbmdFbmFibGVkO1xuICBASW5wdXQoKSBsaWZlVGltZSA9IGRlZmF1bHRzLmxpZmVUaW1lTXM7XG4gIEBJbnB1dCgpIHNob3dEZWxheSA9IGRlZmF1bHRzLnNob3dEZWxheU1zO1xuXG4gIEBJbnB1dCgpIGJhY2tncm91bmRDb2xvciA9IGRlZmF1bHRzLmJhY2tncm91bmRDb2xvcjtcbiAgdGVtcEJhY2tncm91bmRDb2xvcjogc3RyaW5nO1xuICBASW5wdXQoKSBib3JkZXJDb2xvciA9IGRlZmF1bHRzLmJvcmRlckNvbG9yO1xuICB0ZW1wQm9yZGVyQ29sb3I6IHN0cmluZztcbiAgQElucHV0KCkgdGV4dENvbG9yID0gZGVmYXVsdHMudGV4dENvbG9yO1xuICB0ZW1wVGV4dENvbG9yOiBzdHJpbmc7XG5cbiAgQElucHV0KCkgd2lkdGhNb2RlID0gZGVmYXVsdHMud2lkdGhNb2RlO1xuICB0ZW1wV2lkdGhNb2RlOiAnZnVsbCcgfCAncGFydGlhbCc7XG4gIEBJbnB1dCgpIGNsb3NlQnV0dG9uID0gZGVmYXVsdHMuY2xvc2VCdXR0b25FbmFibGVkO1xuICB0ZW1wQ2xvc2VCdXR0b246IGJvb2xlYW47XG4gIEBJbnB1dCgpIGh0bWwgPSBkZWZhdWx0cy51c2VIdG1sO1xuICB0ZW1wSHRtbDogYm9vbGVhbjtcblxuICBAT3V0cHV0KCkgb3BlbiA9IG5ldyBFdmVudEVtaXR0ZXI8QWxlcnRUcmlnZ2VyPigpO1xuICBAT3V0cHV0KCkgY2xvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgc2hvdyA9IGZhbHNlO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIHByaXZhdGUgZGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgZ2V0IGlzRnVsbFdpZHRoKCkge1xuICAgIGlmICh0aGlzLnRlbXBXaWR0aE1vZGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnRlbXBXaWR0aE1vZGUgPT09ICdmdWxsJztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMud2lkdGhNb2RlID09PSAnZnVsbCc7XG4gIH1cblxuICBnZXQgc2hvd0Nsb3NlQnV0dG9uKCkge1xuICAgIGlmICh0aGlzLnRlbXBDbG9zZUJ1dHRvbiAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZW1wQ2xvc2VCdXR0b247XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNsb3NlQnV0dG9uO1xuICB9XG5cbiAgZ2V0IHVzZUh0bWwoKSB7XG4gICAgaWYgKHRoaXMudGVtcEh0bWwgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMudGVtcEh0bWw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmh0bWw7XG4gIH1cblxuICBnZXQgaHRtbE1lc3NhZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuZG9tU2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKHRoaXMubWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRyaWdnZXIgc3RyZWFtIGFmdGVyIHdhaXRpbmcgdGhlIHNwZWNpZmllZCBzaG93RGVsYXkgc2luY2UgdGhlIGFsZXJ0IHdhcyB0cmlnZ2VyZWRcbiAgICovXG4gIGdldCBvcGVuVHJpZ2dlclBvc3REZWxheSQoKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxlcnRCYXJTZXJ2aWNlLnRyaWdnZXIkLnBpcGUoXG4gICAgICBzd2l0Y2hNYXAodHJpZ2dlciA9PiB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0cmlnZ2VyLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHNob3dEZWxheSA9IChvcHRpb25zICYmIG9wdGlvbnMuc2hvd0RlbGF5KSB8fCB0aGlzLnNob3dEZWxheTtcbiAgICAgICAgcmV0dXJuIHRpbWVyKHNob3dEZWxheSkucGlwZShtYXBUbyh0cmlnZ2VyKSk7XG4gICAgICB9KSxcbiAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdHJpZ2dlciBzdHJlYW0gYWZ0ZXIgd2FpdGluZyB0aGUgc3BlY2lmaWVkIGxpZmV0aW1lIHNpbmNlIHRoZSBhbGVydCBvcGVuZWRcbiAgICovXG4gIGdldCBwb3N0QWxlcnRMaWZldGltZSQoKSB7XG4gICAgcmV0dXJuIHRoaXMub3Blbi5waXBlKFxuICAgICAgZmlsdGVyKCh7IG9wdGlvbnMgfSkgPT4gdGhpcy5zaG91bGRBbGVydEF1dG9DbG9zZShvcHRpb25zKSksXG4gICAgICBzd2l0Y2hNYXAoKHsgb3B0aW9ucyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGxpZmVUaW1lID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5saWZlVGltZSkgfHwgdGhpcy5saWZlVGltZTtcbiAgICAgICAgcmV0dXJuIHRpbWVyKGxpZmVUaW1lKTtcbiAgICAgIH0pLFxuICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBzZXJ2aWNlIGNhbmNlbCB0cmlnZ2VyXG4gICAqL1xuICBnZXQgY2FuY2VsVHJpZ2dlciQoKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxlcnRCYXJTZXJ2aWNlLmNhbmNlbCQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95KSk7XG4gIH1cblxuICAvKipcbiAgICogVGltZXIgcmVwcmVzZW50aW5nIHRoZSBkZWxheSB0YWtlbiBmb3IgYW4gYWxlcnQgdG8gYW5pbWF0ZSB3aGVuIGV4aXRpbmdcbiAgICovXG4gIGdldCBhbGVydExlYXZlVGltZXIoKSB7XG4gICAgcmV0dXJuIHRpbWVyKEFMRVJUX0xFQVZFX0FOSU1BVElPTl9EVVJBVElPTikucGlwZSh0YWtlKDEpKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYWxlcnRCYXJTZXJ2aWNlOiBOZ0FsZXJ0YmFyU2VydmljZSwgcHJpdmF0ZSBkb21TYW5pdGl6ZXI6IERvbVNhbml0aXplcikge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLm9wZW5UcmlnZ2VyUG9zdERlbGF5JC5zdWJzY3JpYmUodHJpZ2dlciA9PiB0aGlzLm9uVHJpZ2dlcih0cmlnZ2VyKSk7XG4gICAgdGhpcy5xdWV1ZVBvcC5zdWJzY3JpYmUodHJpZ2dlciA9PiB0aGlzLnNob3dBbGVydCh0cmlnZ2VyKSk7XG4gICAgdGhpcy5wb3N0QWxlcnRMaWZldGltZSQuc3Vic2NyaWJlKCgpID0+IHRoaXMub25DbG9zZSgpKTtcbiAgICB0aGlzLmNhbmNlbFRyaWdnZXIkLnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uQ2xvc2UoKSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3kubmV4dCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBvblRyaWdnZXIodHJpZ2dlcjogQWxlcnRUcmlnZ2VyKSB7XG4gICAgaWYgKHRoaXMucXVldWVpbmcgJiYgISh0cmlnZ2VyLm9wdGlvbnMgJiYgdHJpZ2dlci5vcHRpb25zLmJ5cGFzc1F1ZXVlKSAmJiB0aGlzLnNob3cpIHtcbiAgICAgIHRoaXMucXVldWUucHVzaCh0cmlnZ2VyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zaG93QWxlcnQodHJpZ2dlcik7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB1cCB0ZW1wIHZhcmlhYmxlcyBhbmQgc2hvd3MgdGhlIGFsZXJ0XG4gICAqIEBwYXJhbSB0cmlnZ2VyIFRoZSB0cmlnZ2VyIHRvIGRpc3BsYXlcbiAgICovXG4gIHByaXZhdGUgc2hvd0FsZXJ0KHRyaWdnZXI6IEFsZXJ0VHJpZ2dlcikge1xuICAgIHRoaXMuY2xlYXJUZW1wT3B0aW9ucygpOyAvLyBDbGVhciBwcmV2aW91cyB0ZW1wb3Jhcnkgb3B0aW9uc1xuICAgIHRoaXMuYXNzaWduVGVtcE9wdGlvbnModHJpZ2dlci5vcHRpb25zKTtcbiAgICB0aGlzLm1lc3NhZ2UgPSB0cmlnZ2VyLm1lc3NhZ2U7XG4gICAgdGhpcy5zaG93ID0gdHJ1ZTtcbiAgICB0aGlzLm9wZW4uZW1pdCh0cmlnZ2VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgYW55IG9wZW4gYWxlcnQuIElmIHRoZXJlIGFyZSBhbnkgYWxlcnRzIHdhaXRpbmcgaW4gdGhlIHF1ZXVlLFxuICAgKiB0aGUgYWxlcnQgaXMgcG9wcGVkIG9mZiB0aGUgcXVldWUgYW5kIGVtaXR0ZWQgZm9yIG9wZW5pbmdcbiAgICovXG4gIG9uQ2xvc2UoKSB7XG4gICAgdGhpcy5jbG9zZUFsZXJ0KCk7XG4gICAgaWYgKHRoaXMucXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5hbGVydExlYXZlVGltZXIuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5xdWV1ZVBvcC5uZXh0KHRoaXMucXVldWUuc2hpZnQoKSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNsb3NlQWxlcnQoKSB7XG4gICAgdGhpcy5zaG93ID0gZmFsc2U7XG4gICAgdGhpcy5jbG9zZS5lbWl0KCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIG91dCBhbnkgdGVtcG9yYXJ5IGNvbmZpZyBvcHRpb25zIHNvIHRoYXQgdGhleVxuICAgKiBkbyBub3QgcGVyc2lzdCBiZXlvbmQgdGhlaXIgc2luZ2xlIHVzZVxuICAgKi9cbiAgcHJpdmF0ZSBjbGVhclRlbXBPcHRpb25zKCk6IHZvaWQge1xuICAgIHRoaXMudGVtcEJhY2tncm91bmRDb2xvciA9IG51bGw7XG4gICAgdGhpcy50ZW1wQm9yZGVyQ29sb3IgPSBudWxsO1xuICAgIHRoaXMudGVtcFRleHRDb2xvciA9IG51bGw7XG4gICAgdGhpcy50ZW1wV2lkdGhNb2RlID0gbnVsbDtcbiAgICB0aGlzLnRlbXBDbG9zZUJ1dHRvbiA9IG51bGw7XG4gICAgdGhpcy50ZW1wSHRtbCA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQXNzaWducyB0aGUgb3B0aW9ucyBpbmNsdWRlZCBpbiB0aGUgdHJpZ2dlciB0byB0aGUgdGVtcG9yYXJ5XG4gICAqIGNvbmZpZyB2YXJpYWJsZXMgc28gdGhleSBjYW4gYXBwbHkgZm9yIHRoZSB1cGNvbWluZyBhbGVydFxuICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgb3B0aW9ucyBwYXNzZWQgaW4gdGhlIHRyaWdnZXJcbiAgICovXG4gIHByaXZhdGUgYXNzaWduVGVtcE9wdGlvbnMob3B0aW9uczogQWxlcnRPcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudGVtcEJhY2tncm91bmRDb2xvciA9IG9wdGlvbnMuYmFja2dyb3VuZENvbG9yO1xuICAgIHRoaXMudGVtcEJvcmRlckNvbG9yID0gb3B0aW9ucy5ib3JkZXJDb2xvcjtcbiAgICB0aGlzLnRlbXBUZXh0Q29sb3IgPSBvcHRpb25zLnRleHRDb2xvcjtcbiAgICB0aGlzLnRlbXBXaWR0aE1vZGUgPSBvcHRpb25zLndpZHRoTW9kZTtcbiAgICB0aGlzLnRlbXBDbG9zZUJ1dHRvbiA9IG9wdGlvbnMuY2xvc2VCdXR0b247XG4gICAgdGhpcy50ZW1wSHRtbCA9IG9wdGlvbnMuaHRtbDtcbiAgfVxuXG4gIHByaXZhdGUgc2hvdWxkQWxlcnRBdXRvQ2xvc2Uob3B0aW9uczogQWxlcnRPcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5saWZlVGltZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5saWZlVGltZSA+IDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmxpZmVUaW1lID4gMDsgLy8gRmFsbGJhY2sgdG8gY29tcG9uZW50IHNldHRpbmdcbiAgfVxufVxuIl19