UNPKG

angular2-promise-buttons

Version:
219 lines 24.7 kB
import { Directive, HostListener, Inject, Input } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; import { DEFAULT_CFG } from './default-promise-btn-config'; import { userCfg } from './user-cfg'; import * as i0 from "@angular/core"; export class PromiseBtnDirective { constructor(el, cfg) { // provide configuration this.cfg = Object.assign({}, DEFAULT_CFG, cfg); // save element this.btnEl = el.nativeElement; } // this is added to fix the overriding of the disabled state by the loading indicator button. // https://github.com/johannesjo/angular2-promise-buttons/issues/34 set isDisabledFromTheOutsideSetter(v) { this.isDisabledFromTheOutside = v; if (v) { // disabled means always disabled this.btnEl.setAttribute('disabled', 'disabled'); } else if (this.isPromiseDone || this.isPromiseDone === undefined) { this.btnEl.removeAttribute('disabled'); } // else the button is loading, so do not change the disabled loading state. } set promiseBtn(passedValue) { const isObservable = passedValue instanceof Observable; const isSubscription = passedValue instanceof Subscription; const isBoolean = typeof passedValue === 'boolean'; const isPromise = passedValue instanceof Promise || (passedValue !== null && typeof passedValue === 'object' && typeof passedValue.then === 'function' && typeof passedValue.catch === 'function'); if (isObservable) { throw new TypeError('promiseBtn must be an instance of Subscription, instance of Observable given'); } else if (isSubscription) { const sub = passedValue; if (!sub.closed) { this.promise = new Promise((resolve) => { sub.add(resolve); }); } } else if (isPromise) { this.promise = passedValue; } else if (isBoolean) { this.promise = this.createPromiseFromBoolean(passedValue); } this.checkAndInitPromiseHandler(this.btnEl); } ngAfterContentInit() { this.prepareBtnEl(this.btnEl); // trigger changes once to handle initial promises this.checkAndInitPromiseHandler(this.btnEl); } ngOnDestroy() { // cleanup if (this.minDurationTimeout) { clearTimeout(this.minDurationTimeout); } } createPromiseFromBoolean(val) { if (val) { return new Promise((resolve) => { this._fakePromiseResolve = resolve; }); } else { if (this._fakePromiseResolve) { this._fakePromiseResolve(); } return this.promise; } } /** * Initializes all html and event handlers */ prepareBtnEl(btnEl) { // handle promises passed via promiseBtn attribute this.appendSpinnerTpl(btnEl); } /** * Checks if all required parameters are there and inits the promise handler */ checkAndInitPromiseHandler(btnEl) { // check if element and promise is set if (btnEl && this.promise) { this.initPromiseHandler(btnEl); } } /** * Helper FN to add class */ addLoadingClass(el) { if (typeof this.cfg.btnLoadingClass === 'string') { el.classList.add(this.cfg.btnLoadingClass); } } /** * Helper FN to remove classes */ removeLoadingClass(el) { if (typeof this.cfg.btnLoadingClass === 'string') { el.classList.remove(this.cfg.btnLoadingClass); } } /** * Handles everything to be triggered when the button is set * to loading state. */ initLoadingState(btnEl) { this.addLoadingClass(btnEl); this.disableBtn(btnEl); } /** * Handles everything to be triggered when loading is finished */ cancelLoadingStateIfPromiseAndMinDurationDone(btnEl) { if ((!this.cfg.minDuration || this.isMinDurationTimeoutDone) && this.isPromiseDone) { this.removeLoadingClass(btnEl); this.enableBtn(btnEl); } } disableBtn(btnEl) { if (this.cfg.disableBtn) { btnEl.setAttribute('disabled', 'disabled'); } } enableBtn(btnEl) { if (this.cfg.disableBtn) { if (this.isDisabledFromTheOutside) { btnEl.setAttribute('disabled', 'disabled'); } else { btnEl.removeAttribute('disabled'); } } } /** * Initializes a watcher for the promise. Also takes * this.cfg.minDuration into account if given. */ initPromiseHandler(btnEl) { const promise = this.promise; // watch promise to resolve or fail this.isMinDurationTimeoutDone = false; this.isPromiseDone = false; // create timeout if option is set if (this.cfg.minDuration) { this.minDurationTimeout = window.setTimeout(() => { this.isMinDurationTimeoutDone = true; this.cancelLoadingStateIfPromiseAndMinDurationDone(btnEl); }, this.cfg.minDuration); } const resolveLoadingState = () => { this.isPromiseDone = true; this.cancelLoadingStateIfPromiseAndMinDurationDone(btnEl); }; if (!this.cfg.handleCurrentBtnOnly) { this.initLoadingState(btnEl); } // native Promise doesn't have finally if (promise.finally) { promise.finally(resolveLoadingState); } else { promise .then(resolveLoadingState) .catch(resolveLoadingState); } } /** * $compile and append the spinner template to the button. */ appendSpinnerTpl(btnEl) { // TODO add some kind of compilation later on btnEl.insertAdjacentHTML('beforeend', this.cfg.spinnerTpl); } /** * Limit loading state to show only for the currently clicked button. * Executed only if this.cfg.handleCurrentBtnOnly is set */ handleCurrentBtnOnly() { if (!this.cfg.handleCurrentBtnOnly) { return true; // return true for testing } // Click triggers @Input update // We need to use timeout to wait for @Input to update window.setTimeout(() => { // return if something else than a promise is passed if (!this.promise) { return; } this.initLoadingState(this.btnEl); }, 0); } } PromiseBtnDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: PromiseBtnDirective, deps: [{ token: i0.ElementRef }, { token: userCfg }], target: i0.ɵɵFactoryTarget.Directive }); PromiseBtnDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.17", type: PromiseBtnDirective, selector: "[promiseBtn]", inputs: { isDisabledFromTheOutsideSetter: ["disabled", "isDisabledFromTheOutsideSetter"], promiseBtn: "promiseBtn" }, host: { listeners: { "click": "handleCurrentBtnOnly()" } }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: PromiseBtnDirective, decorators: [{ type: Directive, args: [{ selector: '[promiseBtn]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{ type: Inject, args: [userCfg] }] }]; }, propDecorators: { isDisabledFromTheOutsideSetter: [{ type: Input, args: ['disabled'] }], promiseBtn: [{ type: Input }], handleCurrentBtnOnly: [{ type: HostListener, args: ['click'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbWlzZS1idG4uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhcjItcHJvbWlzZS1idXR0b25zL3NyYy9wcm9taXNlLWJ0bi5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFtQixTQUFTLEVBQWMsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDOUcsT0FBTyxFQUFDLFVBQVUsRUFBRSxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDOUMsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBRXpELE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxZQUFZLENBQUM7O0FBTW5DLE1BQU0sT0FBTyxtQkFBbUI7SUFnQzlCLFlBQVksRUFBYyxFQUNHLEdBQXFCO1FBQ2hELHdCQUF3QjtRQUN4QixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUUvQyxlQUFlO1FBQ2YsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDO0lBQ2hDLENBQUM7SUF6QkQsNkZBQTZGO0lBQzdGLG1FQUFtRTtJQUNuRSxJQUNJLDhCQUE4QixDQUFDLENBQVU7UUFDM0MsSUFBSSxDQUFDLHdCQUF3QixHQUFHLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsRUFBRTtZQUNMLGlDQUFpQztZQUNqQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDakQ7YUFBTSxJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxTQUFTLEVBQUU7WUFDakUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDeEM7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Q0FBQyxHQUFHLENBQUMsVUFBb0IsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRDs7O09BR0c7SUFFSCxvQkFBb0I7UUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUU7WUFDbEMsT0FBTyxJQUFJLENBQUMsQ0FBQywwQkFBMEI7U0FDeEM7UUFFRCwrQkFBK0I7UUFDL0Isc0RBQXNEO1FBQ3RELE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ3JCLG9EQUFvRDtZQUNwRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDakIsT0FBTzthQUNSO1lBRUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDUixDQUFDOztpSEE1T1UsbUJBQW1CLDRDQWlDVixPQUFPO3FHQWpDaEIsbUJBQW1COzRGQUFuQixtQkFBbUI7a0JBSi9CLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGNBQWM7aUJBQ3pCOzswQkFtQ2MsTUFBTTsyQkFBQyxPQUFPOzRDQWhCdkIsOEJBQThCO3NCQURqQyxLQUFLO3VCQUFDLFVBQVU7Z0JBMEJiLFVBQVU7c0JBRGIsS0FBSztnQkFvTE4sb0JBQW9CO3NCQURuQixZQUFZO3VCQUFDLE9BQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FmdGVyQ29udGVudEluaXQsIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbmplY3QsIElucHV0LCBPbkRlc3Ryb3l9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtERUZBVUxUX0NGR30gZnJvbSAnLi9kZWZhdWx0LXByb21pc2UtYnRuLWNvbmZpZyc7XG5pbXBvcnQge1Byb21pc2VCdG5Db25maWd9IGZyb20gJy4vcHJvbWlzZS1idG4tY29uZmlnJztcbmltcG9ydCB7dXNlckNmZ30gZnJvbSAnLi91c2VyLWNmZyc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1twcm9taXNlQnRuXSdcbn0pXG5cbmV4cG9ydCBjbGFzcyBQcm9taXNlQnRuRGlyZWN0aXZlIGltcGxlbWVudHMgT25EZXN0cm95LCBBZnRlckNvbnRlbnRJbml0IHtcbiAgY2ZnOiBQcm9taXNlQnRuQ29uZmlnO1xuICAvLyB0aGUgdGltZW91dCB1c2VkIGZvciBtaW4gZHVyYXRpb24gZGlzcGxheVxuICBtaW5EdXJhdGlvblRpbWVvdXQ6IG51bWJlcjtcbiAgLy8gYm9vbGVhbiB0byBkZXRlcm1pbmUgbWluRHVyYXRpb25UaW1lb3V0IHN0YXRlXG4gIGlzTWluRHVyYXRpb25UaW1lb3V0RG9uZTogYm9vbGVhbjtcbiAgLy8gYm9vbGVhbiB0byBkZXRlcm1pbmUgaWYgcHJvbWlzZSB3YXMgcmVzb2x2ZWRcbiAgaXNQcm9taXNlRG9uZTogYm9vbGVhbjtcbiAgLy8gdGhlIHByb21pc2UgYnV0dG9uIGJ1dHRvbiBlbGVtZW50XG4gIGJ0bkVsOiBIVE1MRWxlbWVudDtcbiAgLy8gdGhlIHByb21pc2UgaXRzZWxmIG9yIGEgZnVuY3Rpb24gZXhwcmVzc2lvblxuICAvLyBOT1RFOiB3ZSBuZWVkIHRoZSB0eXBlIGFueSBoZXJlIGFzIHdlIG1pZ2h0IGRlYWwgd2l0aCBjdXN0b20gcHJvbWlzZXMgbGlrZSBibHVlYmlyZFxuICBwcm9taXNlOiBhbnk7XG5cbiAgLy8gdGhpcyBpcyBhZGRlZCB0byBmaXggdGhlIG92ZXJyaWRpbmcgb2YgdGhlIGRpc2FibGVkIHN0YXRlIGJ5IHRoZSBsb2FkaW5nIGluZGljYXRvciBidXR0b24uXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qb2hhbm5lc2pvL2FuZ3VsYXIyLXByb21pc2UtYnV0dG9ucy9pc3N1ZXMvMzRcbiAgQElucHV0KCdkaXNhYmxlZCcpXG4gIHNldCBpc0Rpc2FibGVkRnJvbVRoZU91dHNpZGVTZXR0ZXIodjogYm9vbGVhbikge1xuICAgIHRoaXMuaXNEaXNhYmxlZEZyb21UaGVPdXRzaWRlID0gdjtcbiAgICBpZiAodikge1xuICAgICAgLy8gZGlzYWJsZWQgbWVhbnMgYWx3YXlzIGRpc2FibGVkXG4gICAgICB0aGlzLmJ0bkVsLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNQcm9taXNlRG9uZSB8fCB0aGlzLmlzUHJvbWlzZURvbmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5idG5FbC5yZW1vdmVBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gICAgfVxuICAgIC8vIGVsc2UgdGhlIGJ1dHRvbiBpcyBsb2FkaW5nLCBzbyBkbyBub3QgY2hhbmdlIHRoZSBkaXNhYmxlZCBsb2FkaW5nIHN0YXRlLlxuICB9XG5cbiAgaXNEaXNhYmxlZEZyb21UaGVPdXRzaWRlOiBib29sZWFuO1xuXG4gIHByaXZhdGUgX2Zha2VQcm9taXNlUmVzb2x2ZTogKHZhbHVlOiB2b2lkKSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKGVsOiBFbGVtZW50UmVmLFxuICAgICAgICAgICAgICBASW5qZWN0KHVzZXJDZmcpIGNmZzogUHJvbWlzZUJ0bkNvbmZpZykge1xuICAgIC8vIHByb3ZpZGUgY29uZmlndXJhdGlvblxuICAgIHRoaXMuY2ZnID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9DRkcsIGNmZyk7XG5cbiAgICAvLyBzYXZlIGVsZW1lbnRcbiAgICB0aGlzLmJ0bkVsID0gZWwubmF0aXZlRWxlbWVudDtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHNldCBwcm9taXNlQnRuKHBhc3NlZFZhbHVlOiBhbnkpIHtcbiAgICBjb25zdCBpc09ic2VydmFibGU6IGJvb2xlYW4gPSBwYXNzZWRWYWx1ZSBpbnN0YW5jZW9mIE9ic2VydmFibGU7XG4gICAgY29uc3QgaXNTdWJzY3JpcHRpb246IGJvb2xlYW4gPSBwYXNzZWRWYWx1ZSBpbnN0YW5jZW9mIFN1YnNjcmlwdGlvbjtcbiAgICBjb25zdCBpc0Jvb2xlYW46IGJvb2xlYW4gPSB0eXBlb2YgcGFzc2VkVmFsdWUgPT09ICdib29sZWFuJztcbiAgICBjb25zdCBpc1Byb21pc2U6IGJvb2xlYW4gPSBwYXNzZWRWYWx1ZSBpbnN0YW5jZW9mIFByb21pc2UgfHwgKFxuICAgICAgcGFzc2VkVmFsdWUgIT09IG51bGwgJiZcbiAgICAgIHR5cGVvZiBwYXNzZWRWYWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiBwYXNzZWRWYWx1ZS50aGVuID09PSAnZnVuY3Rpb24nICYmXG4gICAgICB0eXBlb2YgcGFzc2VkVmFsdWUuY2F0Y2ggPT09ICdmdW5jdGlvbidcbiAgICApO1xuXG4gICAgaWYgKGlzT2JzZXJ2YWJsZSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncHJvbWlzZUJ0biBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIFN1YnNjcmlwdGlvbiwgaW5zdGFuY2Ugb2YgT2JzZXJ2YWJsZSBnaXZlbicpO1xuICAgIH0gZWxzZSBpZiAoaXNTdWJzY3JpcHRpb24pIHtcbiAgICAgIGNvbnN0IHN1YjogU3Vic2NyaXB0aW9uID0gcGFzc2VkVmFsdWU7XG4gICAgICBpZiAoIXN1Yi5jbG9zZWQpIHtcbiAgICAgICAgdGhpcy5wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICBzdWIuYWRkKHJlc29sdmUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzUHJvbWlzZSkge1xuICAgICAgdGhpcy5wcm9taXNlID0gcGFzc2VkVmFsdWU7XG4gICAgfSBlbHNlIGlmIChpc0Jvb2xlYW4pIHtcbiAgICAgIHRoaXMucHJvbWlzZSA9IHRoaXMuY3JlYXRlUHJvbWlzZUZyb21Cb29sZWFuKHBhc3NlZFZhbHVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmNoZWNrQW5kSW5pdFByb21pc2VIYW5kbGVyKHRoaXMuYnRuRWwpO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIHRoaXMucHJlcGFyZUJ0bkVsKHRoaXMuYnRuRWwpO1xuICAgIC8vIHRyaWdnZXIgY2hhbmdlcyBvbmNlIHRvIGhhbmRsZSBpbml0aWFsIHByb21pc2VzXG4gICAgdGhpcy5jaGVja0FuZEluaXRQcm9taXNlSGFuZGxlcih0aGlzLmJ0bkVsKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIC8vIGNsZWFudXBcbiAgICBpZiAodGhpcy5taW5EdXJhdGlvblRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLm1pbkR1cmF0aW9uVGltZW91dCk7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlUHJvbWlzZUZyb21Cb29sZWFuKHZhbDogYm9vbGVhbik6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHZhbCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIHRoaXMuX2Zha2VQcm9taXNlUmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX2Zha2VQcm9taXNlUmVzb2x2ZSkge1xuICAgICAgICB0aGlzLl9mYWtlUHJvbWlzZVJlc29sdmUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIGFsbCBodG1sIGFuZCBldmVudCBoYW5kbGVyc1xuICAgKi9cbiAgcHJlcGFyZUJ0bkVsKGJ0bkVsOiBIVE1MRWxlbWVudCkge1xuICAgIC8vIGhhbmRsZSBwcm9taXNlcyBwYXNzZWQgdmlhIHByb21pc2VCdG4gYXR0cmlidXRlXG4gICAgdGhpcy5hcHBlbmRTcGlubmVyVHBsKGJ0bkVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYWxsIHJlcXVpcmVkIHBhcmFtZXRlcnMgYXJlIHRoZXJlIGFuZCBpbml0cyB0aGUgcHJvbWlzZSBoYW5kbGVyXG4gICAqL1xuICBjaGVja0FuZEluaXRQcm9taXNlSGFuZGxlcihidG5FbDogSFRNTEVsZW1lbnQpIHtcbiAgICAvLyBjaGVjayBpZiBlbGVtZW50IGFuZCBwcm9taXNlIGlzIHNldFxuICAgIGlmIChidG5FbCAmJiB0aGlzLnByb21pc2UpIHtcbiAgICAgIHRoaXMuaW5pdFByb21pc2VIYW5kbGVyKGJ0bkVsKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIEZOIHRvIGFkZCBjbGFzc1xuICAgKi9cbiAgYWRkTG9hZGluZ0NsYXNzKGVsOiBhbnkpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuY2ZnLmJ0bkxvYWRpbmdDbGFzcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5hZGQodGhpcy5jZmcuYnRuTG9hZGluZ0NsYXNzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIEZOIHRvIHJlbW92ZSBjbGFzc2VzXG4gICAqL1xuICByZW1vdmVMb2FkaW5nQ2xhc3MoZWw6IGFueSkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5jZmcuYnRuTG9hZGluZ0NsYXNzID09PSAnc3RyaW5nJykge1xuICAgICAgZWwuY2xhc3NMaXN0LnJlbW92ZSh0aGlzLmNmZy5idG5Mb2FkaW5nQ2xhc3MpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIGV2ZXJ5dGhpbmcgdG8gYmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBzZXRcbiAgICogdG8gbG9hZGluZyBzdGF0ZS5cbiAgICovXG4gIGluaXRMb2FkaW5nU3RhdGUoYnRuRWw6IEhUTUxFbGVtZW50KSB7XG4gICAgdGhpcy5hZGRMb2FkaW5nQ2xhc3MoYnRuRWwpO1xuICAgIHRoaXMuZGlzYWJsZUJ0bihidG5FbCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBldmVyeXRoaW5nIHRvIGJlIHRyaWdnZXJlZCB3aGVuIGxvYWRpbmcgaXMgZmluaXNoZWRcbiAgICovXG4gIGNhbmNlbExvYWRpbmdTdGF0ZUlmUHJvbWlzZUFuZE1pbkR1cmF0aW9uRG9uZShidG5FbDogSFRNTEVsZW1lbnQpIHtcbiAgICBpZiAoKCF0aGlzLmNmZy5taW5EdXJhdGlvbiB8fCB0aGlzLmlzTWluRHVyYXRpb25UaW1lb3V0RG9uZSkgJiYgdGhpcy5pc1Byb21pc2VEb25lKSB7XG4gICAgICB0aGlzLnJlbW92ZUxvYWRpbmdDbGFzcyhidG5FbCk7XG4gICAgICB0aGlzLmVuYWJsZUJ0bihidG5FbCk7XG4gICAgfVxuICB9XG5cbiAgZGlzYWJsZUJ0bihidG5FbDogSFRNTEVsZW1lbnQpIHtcbiAgICBpZiAodGhpcy5jZmcuZGlzYWJsZUJ0bikge1xuICAgICAgYnRuRWwuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpO1xuICAgIH1cbiAgfVxuXG4gIGVuYWJsZUJ0bihidG5FbDogSFRNTEVsZW1lbnQpIHtcbiAgICBpZiAodGhpcy5jZmcuZGlzYWJsZUJ0bikge1xuICAgICAgaWYgKHRoaXMuaXNEaXNhYmxlZEZyb21UaGVPdXRzaWRlKSB7XG4gICAgICAgIGJ0bkVsLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJ0bkVsLnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgYSB3YXRjaGVyIGZvciB0aGUgcHJvbWlzZS4gQWxzbyB0YWtlc1xuICAgKiB0aGlzLmNmZy5taW5EdXJhdGlvbiBpbnRvIGFjY291bnQgaWYgZ2l2ZW4uXG4gICAqL1xuXG4gIGluaXRQcm9taXNlSGFuZGxlcihidG5FbDogSFRNTEVsZW1lbnQpIHtcbiAgICBjb25zdCBwcm9taXNlID0gdGhpcy5wcm9taXNlO1xuXG4gICAgLy8gd2F0Y2ggcHJvbWlzZSB0byByZXNvbHZlIG9yIGZhaWxcbiAgICB0aGlzLmlzTWluRHVyYXRpb25UaW1lb3V0RG9uZSA9IGZhbHNlO1xuICAgIHRoaXMuaXNQcm9taXNlRG9uZSA9IGZhbHNlO1xuXG4gICAgLy8gY3JlYXRlIHRpbWVvdXQgaWYgb3B0aW9uIGlzIHNldFxuICAgIGlmICh0aGlzLmNmZy5taW5EdXJhdGlvbikge1xuICAgICAgdGhpcy5taW5EdXJhdGlvblRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNNaW5EdXJhdGlvblRpbWVvdXREb25lID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jYW5jZWxMb2FkaW5nU3RhdGVJZlByb21pc2VBbmRNaW5EdXJhdGlvbkRvbmUoYnRuRWwpO1xuICAgICAgfSwgdGhpcy5jZmcubWluRHVyYXRpb24pO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc29sdmVMb2FkaW5nU3RhdGUgPSAoKSA9PiB7XG4gICAgICB0aGlzLmlzUHJvbWlzZURvbmUgPSB0cnVlO1xuICAgICAgdGhpcy5jYW5jZWxMb2FkaW5nU3RhdGVJZlByb21pc2VBbmRNaW5EdXJhdGlvbkRvbmUoYnRuRWwpO1xuICAgIH07XG5cbiAgICBpZiAoIXRoaXMuY2ZnLmhhbmRsZUN1cnJlbnRCdG5Pbmx5KSB7XG4gICAgICB0aGlzLmluaXRMb2FkaW5nU3RhdGUoYnRuRWwpO1xuICAgIH1cbiAgICAvLyBuYXRpdmUgUHJvbWlzZSBkb2Vzbid0IGhhdmUgZmluYWxseVxuICAgIGlmIChwcm9taXNlLmZpbmFsbHkpIHtcbiAgICAgIHByb21pc2UuZmluYWxseShyZXNvbHZlTG9hZGluZ1N0YXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZVxuICAgICAgICAudGhlbihyZXNvbHZlTG9hZGluZ1N0YXRlKVxuICAgICAgICAuY2F0Y2gocmVzb2x2ZUxvYWRpbmdTdGF0ZSk7XG4gICAgfVxuXG4gIH1cblxuXG4gIC8qKlxuICAgKiAkY29tcGlsZSBhbmQgYXBwZW5kIHRoZSBzcGlubmVyIHRlbXBsYXRlIHRvIHRoZSBidXR0b24uXG4gICAqL1xuICBhcHBlbmRTcGlubmVyVHBsKGJ0bkVsOiBIVE1MRWxlbWVudCkge1xuICAgIC8vIFRPRE8gYWRkIHNvbWUga2luZCBvZiBjb21waWxhdGlvbiBsYXRlciBvblxuICAgIGJ0bkVsLmluc2VydEFkamFjZW50SFRNTCgnYmVmb3JlZW5kJywgdGhpcy5jZmcuc3Bpbm5lclRwbCBhcyBzdHJpbmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpbWl0IGxvYWRpbmcgc3RhdGUgdG8gc2hvdyBvbmx5IGZvciB0aGUgY3VycmVudGx5IGNsaWNrZWQgYnV0dG9uLlxuICAgKiBFeGVjdXRlZCBvbmx5IGlmIHRoaXMuY2ZnLmhhbmRsZUN1cnJlbnRCdG5Pbmx5IGlzIHNldFxuICAgKi9cbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snKVxuICBoYW5kbGVDdXJyZW50QnRuT25seSgpIHtcbiAgICBpZiAoIXRoaXMuY2ZnLmhhbmRsZUN1cnJlbnRCdG5Pbmx5KSB7XG4gICAgICByZXR1cm4gdHJ1ZTsgLy8gcmV0dXJuIHRydWUgZm9yIHRlc3RpbmdcbiAgICB9XG5cbiAgICAvLyBDbGljayB0cmlnZ2VycyBASW5wdXQgdXBkYXRlXG4gICAgLy8gV2UgbmVlZCB0byB1c2UgdGltZW91dCB0byB3YWl0IGZvciBASW5wdXQgdG8gdXBkYXRlXG4gICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgLy8gcmV0dXJuIGlmIHNvbWV0aGluZyBlbHNlIHRoYW4gYSBwcm9taXNlIGlzIHBhc3NlZFxuICAgICAgaWYgKCF0aGlzLnByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmluaXRMb2FkaW5nU3RhdGUodGhpcy5idG5FbCk7XG4gICAgfSwgMCk7XG4gIH1cbn1cbiJdfQ==