UNPKG

@ngx-gallery/lightbox

Version:

Angular gallery directive that hooks the lightbox with the images automatically.

209 lines 17.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, Optional, ChangeDetectionStrategy, ElementRef, Inject } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { DOCUMENT } from '@angular/common'; import { FocusTrapFactory } from '@angular/cdk/a11y'; import { lightboxAnimation } from './lightbox.animation'; var LightboxComponent = /** @class */ (function () { function LightboxComponent(_document, _focusTrapFactory, _elementRef, sanitizer) { this._document = _document; this._focusTrapFactory = _focusTrapFactory; this._elementRef = _elementRef; this.sanitizer = sanitizer; /** * State of the lightbox animation. */ this.state = 'enter'; this._savePreviouslyFocusedElement(); } /** Callback, invoked whenever an animation on the host completes. */ /** * Callback, invoked whenever an animation on the host completes. * @param {?} event * @return {?} */ LightboxComponent.prototype.onAnimationDone = /** * Callback, invoked whenever an animation on the host completes. * @param {?} event * @return {?} */ function (event) { if (event.toState === 'enter') { this._trapFocus(); } else { this.overlayRef.dispose(); this._restoreFocus(); } }; /** Moves the focus inside the focus trap. */ /** * Moves the focus inside the focus trap. * @private * @return {?} */ LightboxComponent.prototype._trapFocus = /** * Moves the focus inside the focus trap. * @private * @return {?} */ function () { if (!this._focusTrap) { this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement); } // If were to attempt to focus immediately, then the content of the lightbox would not yet be // ready in instances where change detection has to run first. To deal with this, we simply // wait for the microtask queue to be empty. this._focusTrap.focusInitialElementWhenReady(); }; /** Saves a reference to the element that was focused before the lightbox was opened. */ /** * Saves a reference to the element that was focused before the lightbox was opened. * @private * @return {?} */ LightboxComponent.prototype._savePreviouslyFocusedElement = /** * Saves a reference to the element that was focused before the lightbox was opened. * @private * @return {?} */ function () { var _this = this; if (this._document) { this._elementFocusedBeforeDialogWasOpened = (/** @type {?} */ (this._document.activeElement)); // Note that there is no focus method when rendering on the server. if (this._elementRef.nativeElement.focus) { // Move focus onto the lightbox immediately in order to prevent the user from accidentally // opening multiple dialogs at the same time. Needs to be async, because the element // may not be focusable immediately. Promise.resolve().then(function () { return _this._elementRef.nativeElement.focus(); }); } } }; /** Restores focus to the element that was focused before the lightbox opened. */ /** * Restores focus to the element that was focused before the lightbox opened. * @private * @return {?} */ LightboxComponent.prototype._restoreFocus = /** * Restores focus to the element that was focused before the lightbox opened. * @private * @return {?} */ function () { /** @type {?} */ var toFocus = this._elementFocusedBeforeDialogWasOpened; // We need the extra check, because IE can set the `activeElement` to null in some cases. if (toFocus && typeof toFocus.focus === 'function') { toFocus.focus(); } if (this._focusTrap) { this._focusTrap.destroy(); } }; LightboxComponent.decorators = [ { type: Component, args: [{ selector: 'lightbox', changeDetection: ChangeDetectionStrategy.OnPush, animations: [lightboxAnimation], template: "\n <gallery [id]=\"id\" [destroyRef]=\"false\" [skipInitConfig]=\"true\">\n <i class=\"g-btn-close\" aria-label=\"Close\" (click)=\"overlayRef.detach()\"\n [innerHTML]=\"sanitizer.bypassSecurityTrustHtml(closeIcon)\"></i>\n </gallery>\n ", host: { 'tabindex': '-1', 'aria-modal': 'true', '[attr.id]': '"lightbox-" + id', '[attr.role]': 'role', '[attr.aria-labelledby]': 'ariaLabel ? null : ariaLabelledBy', '[attr.aria-label]': 'ariaLabel', '[attr.aria-describedby]': 'ariaDescribedBy || null', '[@lightbox]': 'state', '(@lightbox.done)': 'onAnimationDone($event)', }, styles: ["::ng-deep lightbox{position:relative;display:block;width:1100px;height:800px;max-width:94vw;max-height:90vh;border-radius:4px;overflow:hidden;box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12)}::ng-deep lightbox:focus{outline:0}::ng-deep lightbox gallery{overflow:hidden;margin:0;display:block;width:100%;height:100%}::ng-deep .g-backdrop{background-color:rgba(0,0,0,.32)}::ng-deep .fullscreen{width:100%}::ng-deep .fullscreen ::ng-deep lightbox{max-width:unset;max-height:unset;position:fixed;top:0;left:0;bottom:0;right:0;height:100%;width:100%;border-radius:0}::ng-deep .g-overlay{margin:auto}@media only screen and (max-width:480px){::ng-deep .g-overlay{width:100%}::ng-deep .g-overlay ::ng-deep lightbox{max-width:unset;max-height:unset;position:fixed;top:0;left:0;bottom:0;right:0;height:100%;width:100%;border-radius:0}}::ng-deep .g-btn-close{position:absolute;right:.9em;top:.9em;z-index:60;cursor:pointer;width:20px;height:20px}@media only screen and (max-width:480px){::ng-deep .g-btn-close{right:.7em;top:.7em}}"] }] } ]; /** @nocollapse */ LightboxComponent.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] }, { type: FocusTrapFactory }, { type: ElementRef }, { type: DomSanitizer } ]; }; return LightboxComponent; }()); export { LightboxComponent }; if (false) { /** * Gallery ref id * @type {?} */ LightboxComponent.prototype.id; /** * Overlay ref to close the lightbox * @type {?} */ LightboxComponent.prototype.overlayRef; /** * Close button svg data * @type {?} */ LightboxComponent.prototype.closeIcon; /** * State of the lightbox animation. * @type {?} */ LightboxComponent.prototype.state; /** * The ARIA role of the lightbox element. * @type {?} */ LightboxComponent.prototype.role; /** * Aria label to assign to the lightbox element * @type {?} */ LightboxComponent.prototype.ariaLabel; /** * ID of the element that should be considered as the lightbox's label. * @type {?} */ LightboxComponent.prototype.ariaLabelledBy; /** * ID of the element that describes the lightbox. * @type {?} */ LightboxComponent.prototype.ariaDescribedBy; /** * The class that traps and manages focus within the lightbox. * @type {?} * @private */ LightboxComponent.prototype._focusTrap; /** * Element that was focused before the lightbox was opened. Save this to restore upon close. * @type {?} * @private */ LightboxComponent.prototype._elementFocusedBeforeDialogWasOpened; /** * @type {?} * @private */ LightboxComponent.prototype._document; /** * @type {?} * @private */ LightboxComponent.prototype._focusTrapFactory; /** * @type {?} * @private */ LightboxComponent.prototype._elementRef; /** @type {?} */ LightboxComponent.prototype.sanitizer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRib3guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1nYWxsZXJ5L2xpZ2h0Ym94LyIsInNvdXJjZXMiOlsibGliL2xpZ2h0Ym94LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsdUJBQXVCLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRzNDLE9BQU8sRUFBYSxnQkFBZ0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXpEO0lBdURFLDJCQUFrRCxTQUFjLEVBQzVDLGlCQUFtQyxFQUNuQyxXQUF1QixFQUN4QixTQUF1QjtRQUhRLGNBQVMsR0FBVCxTQUFTLENBQUs7UUFDNUMsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNuQyxnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUN4QixjQUFTLEdBQVQsU0FBUyxDQUFjOzs7O1FBdkIxQyxVQUFLLEdBQThCLE9BQU8sQ0FBQztRQXdCekMsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUVELHFFQUFxRTs7Ozs7O0lBQ3JFLDJDQUFlOzs7OztJQUFmLFVBQWdCLEtBQXFCO1FBQ25DLElBQUksS0FBSyxDQUFDLE9BQU8sS0FBSyxPQUFPLEVBQUU7WUFDN0IsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1NBQ25CO2FBQU07WUFDTCxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztTQUN0QjtJQUNILENBQUM7SUFFRCw2Q0FBNkM7Ozs7OztJQUNyQyxzQ0FBVTs7Ozs7SUFBbEI7UUFDRSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNwQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztTQUNqRjtRQUNELDZGQUE2RjtRQUM3RiwyRkFBMkY7UUFDM0YsNENBQTRDO1FBQzVDLElBQUksQ0FBQyxVQUFVLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztJQUNqRCxDQUFDO0lBRUQsd0ZBQXdGOzs7Ozs7SUFDaEYseURBQTZCOzs7OztJQUFyQztRQUFBLGlCQVlDO1FBWEMsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2xCLElBQUksQ0FBQyxvQ0FBb0MsR0FBRyxtQkFBQSxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBZSxDQUFDO1lBRXhGLG1FQUFtRTtZQUNuRSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRTtnQkFDeEMsMEZBQTBGO2dCQUMxRixvRkFBb0Y7Z0JBQ3BGLG9DQUFvQztnQkFDcEMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFNLE9BQUEsS0FBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLEVBQXRDLENBQXNDLENBQUMsQ0FBQzthQUN0RTtTQUNGO0lBQ0gsQ0FBQztJQUVELGlGQUFpRjs7Ozs7O0lBQ3pFLHlDQUFhOzs7OztJQUFyQjs7WUFDUSxPQUFPLEdBQUcsSUFBSSxDQUFDLG9DQUFvQztRQUV6RCx5RkFBeUY7UUFDekYsSUFBSSxPQUFPLElBQUksT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLFVBQVUsRUFBRTtZQUNsRCxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDakI7UUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUMzQjtJQUNILENBQUM7O2dCQTlHRixTQUFTLFNBQUM7b0JBQ1QsUUFBUSxFQUFFLFVBQVU7b0JBQ3BCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxVQUFVLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQztvQkFFL0IsUUFBUSxFQUFFLG1RQUtUO29CQUNELElBQUksRUFBRTt3QkFDSixVQUFVLEVBQUUsSUFBSTt3QkFDaEIsWUFBWSxFQUFFLE1BQU07d0JBQ3BCLFdBQVcsRUFBRSxrQkFBa0I7d0JBQy9CLGFBQWEsRUFBRSxNQUFNO3dCQUNyQix3QkFBd0IsRUFBRSxtQ0FBbUM7d0JBQzdELG1CQUFtQixFQUFFLFdBQVc7d0JBQ2hDLHlCQUF5QixFQUFFLHlCQUF5Qjt3QkFDcEQsYUFBYSxFQUFFLE9BQU87d0JBQ3RCLGtCQUFrQixFQUFFLHlCQUF5QjtxQkFDOUM7O2lCQUNGOzs7O2dEQWlDYyxRQUFRLFlBQUksTUFBTSxTQUFDLFFBQVE7Z0JBMUR0QixnQkFBZ0I7Z0JBTG1CLFVBQVU7Z0JBQ3hELFlBQVk7O0lBc0hyQix3QkFBQztDQUFBLEFBL0dELElBK0dDO1NBeEZZLGlCQUFpQjs7Ozs7O0lBRzVCLCtCQUFXOzs7OztJQUdYLHVDQUF1Qjs7Ozs7SUFHdkIsc0NBQWtCOzs7OztJQUdsQixrQ0FBMkM7Ozs7O0lBRzNDLGlDQUFhOzs7OztJQUdiLHNDQUFrQjs7Ozs7SUFHbEIsMkNBQXVCOzs7OztJQUd2Qiw0Q0FBd0I7Ozs7OztJQUd4Qix1Q0FBOEI7Ozs7OztJQUc5QixpRUFBMEQ7Ozs7O0lBRTlDLHNDQUFvRDs7Ozs7SUFDcEQsOENBQTJDOzs7OztJQUMzQyx3Q0FBK0I7O0lBQy9CLHNDQUE4QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT3B0aW9uYWwsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBFbGVtZW50UmVmLCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQW5pbWF0aW9uRXZlbnQgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7IE92ZXJsYXlSZWYgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBGb2N1c1RyYXAsIEZvY3VzVHJhcEZhY3RvcnkgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBsaWdodGJveEFuaW1hdGlvbiB9IGZyb20gJy4vbGlnaHRib3guYW5pbWF0aW9uJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGlnaHRib3gnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgYW5pbWF0aW9uczogW2xpZ2h0Ym94QW5pbWF0aW9uXSxcbiAgc3R5bGVVcmxzOiBbJy4vbGlnaHRib3guY29tcG9uZW50LnNjc3MnXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8Z2FsbGVyeSBbaWRdPVwiaWRcIiBbZGVzdHJveVJlZl09XCJmYWxzZVwiIFtza2lwSW5pdENvbmZpZ109XCJ0cnVlXCI+XG4gICAgICA8aSBjbGFzcz1cImctYnRuLWNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCIgKGNsaWNrKT1cIm92ZXJsYXlSZWYuZGV0YWNoKClcIlxuICAgICAgICAgW2lubmVySFRNTF09XCJzYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdEh0bWwoY2xvc2VJY29uKVwiPjwvaT5cbiAgICA8L2dhbGxlcnk+XG4gIGAsXG4gIGhvc3Q6IHtcbiAgICAndGFiaW5kZXgnOiAnLTEnLFxuICAgICdhcmlhLW1vZGFsJzogJ3RydWUnLFxuICAgICdbYXR0ci5pZF0nOiAnXCJsaWdodGJveC1cIiArIGlkJyxcbiAgICAnW2F0dHIucm9sZV0nOiAncm9sZScsXG4gICAgJ1thdHRyLmFyaWEtbGFiZWxsZWRieV0nOiAnYXJpYUxhYmVsID8gbnVsbCA6IGFyaWFMYWJlbGxlZEJ5JyxcbiAgICAnW2F0dHIuYXJpYS1sYWJlbF0nOiAnYXJpYUxhYmVsJyxcbiAgICAnW2F0dHIuYXJpYS1kZXNjcmliZWRieV0nOiAnYXJpYURlc2NyaWJlZEJ5IHx8IG51bGwnLFxuICAgICdbQGxpZ2h0Ym94XSc6ICdzdGF0ZScsXG4gICAgJyhAbGlnaHRib3guZG9uZSknOiAnb25BbmltYXRpb25Eb25lKCRldmVudCknLFxuICB9XG59KVxuZXhwb3J0IGNsYXNzIExpZ2h0Ym94Q29tcG9uZW50IHtcblxuICAvKiogR2FsbGVyeSByZWYgaWQgKi9cbiAgaWQ6IHN0cmluZztcblxuICAvKiogT3ZlcmxheSByZWYgdG8gY2xvc2UgdGhlIGxpZ2h0Ym94ICovXG4gIG92ZXJsYXlSZWY6IE92ZXJsYXlSZWY7XG5cbiAgLyoqIENsb3NlIGJ1dHRvbiBzdmcgZGF0YSAqL1xuICBjbG9zZUljb246IHN0cmluZztcblxuICAvKiogU3RhdGUgb2YgdGhlIGxpZ2h0Ym94IGFuaW1hdGlvbi4gKi9cbiAgc3RhdGU6ICd2b2lkJyB8ICdlbnRlcicgfCAnZXhpdCcgPSAnZW50ZXInO1xuXG4gIC8qKiBUaGUgQVJJQSByb2xlIG9mIHRoZSBsaWdodGJveCBlbGVtZW50LiAqL1xuICByb2xlOiBzdHJpbmc7XG5cbiAgLyoqIEFyaWEgbGFiZWwgdG8gYXNzaWduIHRvIHRoZSBsaWdodGJveCBlbGVtZW50ICovXG4gIGFyaWFMYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBJRCBvZiB0aGUgZWxlbWVudCB0aGF0IHNob3VsZCBiZSBjb25zaWRlcmVkIGFzIHRoZSBsaWdodGJveCdzIGxhYmVsLiAqL1xuICBhcmlhTGFiZWxsZWRCeTogc3RyaW5nO1xuXG4gIC8qKiBJRCBvZiB0aGUgZWxlbWVudCB0aGF0IGRlc2NyaWJlcyB0aGUgbGlnaHRib3guICovXG4gIGFyaWFEZXNjcmliZWRCeTogc3RyaW5nO1xuXG4gIC8qKiBUaGUgY2xhc3MgdGhhdCB0cmFwcyBhbmQgbWFuYWdlcyBmb2N1cyB3aXRoaW4gdGhlIGxpZ2h0Ym94LiAqL1xuICBwcml2YXRlIF9mb2N1c1RyYXA6IEZvY3VzVHJhcDtcblxuICAvKiogRWxlbWVudCB0aGF0IHdhcyBmb2N1c2VkIGJlZm9yZSB0aGUgbGlnaHRib3ggd2FzIG9wZW5lZC4gU2F2ZSB0aGlzIHRvIHJlc3RvcmUgdXBvbiBjbG9zZS4gKi9cbiAgcHJpdmF0ZSBfZWxlbWVudEZvY3VzZWRCZWZvcmVEaWFsb2dXYXNPcGVuZWQ6IEhUTUxFbGVtZW50O1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgX2RvY3VtZW50OiBhbnksXG4gICAgICAgICAgICAgIHByaXZhdGUgX2ZvY3VzVHJhcEZhY3Rvcnk6IEZvY3VzVHJhcEZhY3RvcnksXG4gICAgICAgICAgICAgIHByaXZhdGUgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgICAgICAgIHB1YmxpYyBzYW5pdGl6ZXI6IERvbVNhbml0aXplcikge1xuICAgIHRoaXMuX3NhdmVQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQoKTtcbiAgfVxuXG4gIC8qKiBDYWxsYmFjaywgaW52b2tlZCB3aGVuZXZlciBhbiBhbmltYXRpb24gb24gdGhlIGhvc3QgY29tcGxldGVzLiAqL1xuICBvbkFuaW1hdGlvbkRvbmUoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnRvU3RhdGUgPT09ICdlbnRlcicpIHtcbiAgICAgIHRoaXMuX3RyYXBGb2N1cygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm92ZXJsYXlSZWYuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5fcmVzdG9yZUZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIE1vdmVzIHRoZSBmb2N1cyBpbnNpZGUgdGhlIGZvY3VzIHRyYXAuICovXG4gIHByaXZhdGUgX3RyYXBGb2N1cygpIHtcbiAgICBpZiAoIXRoaXMuX2ZvY3VzVHJhcCkge1xuICAgICAgdGhpcy5fZm9jdXNUcmFwID0gdGhpcy5fZm9jdXNUcmFwRmFjdG9yeS5jcmVhdGUodGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgICB9XG4gICAgLy8gSWYgd2VyZSB0byBhdHRlbXB0IHRvIGZvY3VzIGltbWVkaWF0ZWx5LCB0aGVuIHRoZSBjb250ZW50IG9mIHRoZSBsaWdodGJveCB3b3VsZCBub3QgeWV0IGJlXG4gICAgLy8gcmVhZHkgaW4gaW5zdGFuY2VzIHdoZXJlIGNoYW5nZSBkZXRlY3Rpb24gaGFzIHRvIHJ1biBmaXJzdC4gVG8gZGVhbCB3aXRoIHRoaXMsIHdlIHNpbXBseVxuICAgIC8vIHdhaXQgZm9yIHRoZSBtaWNyb3Rhc2sgcXVldWUgdG8gYmUgZW1wdHkuXG4gICAgdGhpcy5fZm9jdXNUcmFwLmZvY3VzSW5pdGlhbEVsZW1lbnRXaGVuUmVhZHkoKTtcbiAgfVxuXG4gIC8qKiBTYXZlcyBhIHJlZmVyZW5jZSB0byB0aGUgZWxlbWVudCB0aGF0IHdhcyBmb2N1c2VkIGJlZm9yZSB0aGUgbGlnaHRib3ggd2FzIG9wZW5lZC4gKi9cbiAgcHJpdmF0ZSBfc2F2ZVByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCgpIHtcbiAgICBpZiAodGhpcy5fZG9jdW1lbnQpIHtcbiAgICAgIHRoaXMuX2VsZW1lbnRGb2N1c2VkQmVmb3JlRGlhbG9nV2FzT3BlbmVkID0gdGhpcy5fZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcblxuICAgICAgLy8gTm90ZSB0aGF0IHRoZXJlIGlzIG5vIGZvY3VzIG1ldGhvZCB3aGVuIHJlbmRlcmluZyBvbiB0aGUgc2VydmVyLlxuICAgICAgaWYgKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cykge1xuICAgICAgICAvLyBNb3ZlIGZvY3VzIG9udG8gdGhlIGxpZ2h0Ym94IGltbWVkaWF0ZWx5IGluIG9yZGVyIHRvIHByZXZlbnQgdGhlIHVzZXIgZnJvbSBhY2NpZGVudGFsbHlcbiAgICAgICAgLy8gb3BlbmluZyBtdWx0aXBsZSBkaWFsb2dzIGF0IHRoZSBzYW1lIHRpbWUuIE5lZWRzIHRvIGJlIGFzeW5jLCBiZWNhdXNlIHRoZSBlbGVtZW50XG4gICAgICAgIC8vIG1heSBub3QgYmUgZm9jdXNhYmxlIGltbWVkaWF0ZWx5LlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cygpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogUmVzdG9yZXMgZm9jdXMgdG8gdGhlIGVsZW1lbnQgdGhhdCB3YXMgZm9jdXNlZCBiZWZvcmUgdGhlIGxpZ2h0Ym94IG9wZW5lZC4gKi9cbiAgcHJpdmF0ZSBfcmVzdG9yZUZvY3VzKCkge1xuICAgIGNvbnN0IHRvRm9jdXMgPSB0aGlzLl9lbGVtZW50Rm9jdXNlZEJlZm9yZURpYWxvZ1dhc09wZW5lZDtcblxuICAgIC8vIFdlIG5lZWQgdGhlIGV4dHJhIGNoZWNrLCBiZWNhdXNlIElFIGNhbiBzZXQgdGhlIGBhY3RpdmVFbGVtZW50YCB0byBudWxsIGluIHNvbWUgY2FzZXMuXG4gICAgaWYgKHRvRm9jdXMgJiYgdHlwZW9mIHRvRm9jdXMuZm9jdXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRvRm9jdXMuZm9jdXMoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZm9jdXNUcmFwKSB7XG4gICAgICB0aGlzLl9mb2N1c1RyYXAuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxufVxuIl19