UNPKG

carbon-components-angular

Version:
316 lines 34.4 kB
import { Directive, Input, Output, EventEmitter, HostBinding } from "@angular/core"; import { DialogService } from "./dialog.service"; import { CloseReasons } from "./dialog-config.interface"; import { fromEvent } from "rxjs"; import * as i0 from "@angular/core"; import * as i1 from "./dialog.service"; import * as i2 from "carbon-components-angular/utils"; /** * A generic directive that can be inherited from to create dialogs (for example, a tooltip or popover) * * This class contains the relevant initialization code, specific templates, options, and additional inputs * should be specified in the derived class. * * NOTE: All child classes should add `DialogService` as a provider, otherwise they will lose context that * the service relies on. */ export class DialogDirective { /** * Creates an instance of DialogDirective. * @param elementRef * @param viewContainerRef * @param dialogService * @param eventService */ constructor(elementRef, viewContainerRef, dialogService, /** * Deprecated as of v5 */ eventService) { this.elementRef = elementRef; this.viewContainerRef = viewContainerRef; this.dialogService = dialogService; this.eventService = eventService; /** * Title for the dialog */ this.title = ""; /** * Defines how the Dialog is triggered.(Hover and click behave the same on mobile - both respond to a single tap). * Do not add focusable elements if trigger is `hover` or `mouseenter`. */ this.trigger = "click"; /** * Defines how the Dialog close event is triggered. * * [See here](https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseleave_event) * for more on the difference between `mouseleave` and `mouseout`. * * Defaults to `click` when `trigger` is set to `click`. */ this.closeTrigger = "mouseleave"; /** * Placement of the dialog, usually relative to the element the directive is on. */ this.placement = "left"; /** * Spacing between the dialog and it's triggering element */ this.gap = 0; /** * Set to `true` to open the dialog next to the triggering component */ this.appendInline = false; /** * Optional data for templates */ this.data = {}; this.isOpen = false; /** * This prevents the dialog from being toggled */ this.disabled = false; /** * Emits an event when the dialog is closed */ this.onClose = new EventEmitter(); /** * Emits an event when the dialog is opened */ this.onOpen = new EventEmitter(); /** * Emits an event when the state of `isOpen` changes. Allows `isOpen` to be double bound */ this.isOpenChange = new EventEmitter(); this.role = "button"; this.hasPopup = true; this.subscriptions = []; } /** * @deprecated as of v5, use `cdsDialog` instead * Dialog body content. */ set ibmDialog(body) { this.cdsDialog = body; } get ariaOwns() { return this.isOpen ? this.dialogConfig.compID : null; } ngOnChanges(changes) { // set the config object (this can [and should!] be added to in child classes depending on what they need) this.dialogConfig = { title: this.title, content: this.cdsDialog, placement: this.placement, parentRef: this.elementRef, gap: this.gap, trigger: this.trigger, closeTrigger: this.closeTrigger, shouldClose: this.shouldClose || (() => true), appendInline: this.appendInline, wrapperClass: this.wrapperClass, data: this.data, offset: this.offset, disabled: this.disabled }; if (changes.isOpen) { if (changes.isOpen.currentValue) { this.open(); } else if (!changes.isOpen.firstChange) { this.close({ reason: CloseReasons.programmatic }); } } // Run any code a child class may need. this.onDialogChanges(changes); this.updateConfig(); } /** * Sets the config object and binds events for hovering or clicking before * running code from child class. */ ngOnInit() { // fix for safari hijacking clicks this.dialogService.singletonClickListen(); const element = this.elementRef.nativeElement; this.subscriptions.push(fromEvent(element, "keydown").subscribe((event) => { if (event.target === this.dialogConfig.parentRef.nativeElement && (event.key === "Tab" || event.key === "Tab" && event.shiftKey) || event.key === "Escape") { this.close({ reason: CloseReasons.interaction, target: event.target }); } })); // bind events for hovering or clicking the host if (this.trigger === "hover" || this.trigger === "mouseenter") { this.subscriptions.push(fromEvent(element, "mouseenter").subscribe(() => this.open()), fromEvent(element, this.closeTrigger).subscribe((event) => { this.close({ reason: CloseReasons.interaction, target: event.target }); }), fromEvent(element, "focus").subscribe(() => this.open()), fromEvent(element, "blur").subscribe((event) => { this.close({ reason: CloseReasons.interaction, target: event.target }); })); } else { this.subscriptions.push(fromEvent(element, "click").subscribe((event) => { this.toggle({ reason: CloseReasons.interaction, target: event.target }); }), fromEvent(element, "keydown").subscribe((event) => { if (event.key === "Enter" || event.key === " ") { setTimeout(() => { this.open(); }); } })); } DialogDirective.dialogCounter++; this.dialogConfig.compID = "dialog-" + DialogDirective.dialogCounter; // run any code a child class may need this.onDialogInit(); this.updateConfig(); } /** * When the host dies, kill the popover. * - Useful for use in a modal or similar. */ ngOnDestroy() { this.close({ reason: CloseReasons.destroyed }); this.subscriptions.forEach((subscription) => subscription.unsubscribe()); } /** * Helper method to call dialogService 'open'. * - Enforce accessibility by updating an aria attr for nativeElement. */ open(component) { // don't allow dialogs to be opened if they're already open if (this.dialogRef || this.disabled) { return; } // actually open the dialog, emit events, and set the open state this.dialogRef = this.dialogService.open(this.viewContainerRef, this.dialogConfig, component); this.isOpen = true; this.onOpen.emit(); this.isOpenChange.emit(true); // Handles emitting all the close events to clean everything up // Also enforce accessibility on close by updating an aria attr on the nativeElement. const subscription = this.dialogRef.instance.close.subscribe((meta) => { if (!this.dialogRef) { return; } if (this.dialogConfig.shouldClose && this.dialogConfig.shouldClose(meta)) { // close the dialog, emit events, and clear out the open states this.dialogService.close(this.dialogRef); this.dialogRef = null; this.isOpen = false; this.onClose.emit(); this.isOpenChange.emit(false); subscription.unsubscribe(); } }); return this.dialogRef; } /** * Helper method to toggle the open state of the dialog */ toggle(meta = { reason: CloseReasons.interaction }) { if (!this.isOpen) { this.open(); } else { this.close(meta); } } /** * Helper method to close the dialogRef. */ close(meta = { reason: CloseReasons.interaction }) { if (this.dialogRef) { this.dialogRef.instance.doClose(meta); } } /** * Empty method for child classes to override and specify additional init steps. * Run after DialogDirective completes it's ngOnInit. */ onDialogInit() { } /** * Empty method for child to override and specify additional on changes steps. * run after DialogDirective completes it's ngOnChanges. */ onDialogChanges(_changes) { } updateConfig() { } } DialogDirective.dialogCounter = 0; DialogDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogDirective, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.DialogService }, { token: i2.EventService }], target: i0.ɵɵFactoryTarget.Directive }); DialogDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: DialogDirective, selector: "[cdsDialog], [ibmDialog]", inputs: { title: "title", ibmDialog: "ibmDialog", cdsDialog: "cdsDialog", trigger: "trigger", closeTrigger: "closeTrigger", placement: "placement", offset: "offset", wrapperClass: "wrapperClass", gap: "gap", appendInline: "appendInline", data: "data", isOpen: "isOpen", disabled: "disabled", shouldClose: "shouldClose" }, outputs: { onClose: "onClose", onOpen: "onOpen", isOpenChange: "isOpenChange" }, host: { properties: { "attr.aria-expanded": "this.isOpen", "attr.role": "this.role", "attr.aria-haspopup": "this.hasPopup", "attr.aria-owns": "this.ariaOwns" } }, providers: [ DialogService ], exportAs: ["dialog"], usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogDirective, decorators: [{ type: Directive, args: [{ selector: "[cdsDialog], [ibmDialog]", exportAs: "dialog", providers: [ DialogService ] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.DialogService }, { type: i2.EventService }]; }, propDecorators: { title: [{ type: Input }], ibmDialog: [{ type: Input }], cdsDialog: [{ type: Input }], trigger: [{ type: Input }], closeTrigger: [{ type: Input }], placement: [{ type: Input }], offset: [{ type: Input }], wrapperClass: [{ type: Input }], gap: [{ type: Input }], appendInline: [{ type: Input }], data: [{ type: Input }], isOpen: [{ type: Input }, { type: HostBinding, args: ["attr.aria-expanded"] }], disabled: [{ type: Input }], shouldClose: [{ type: Input }], onClose: [{ type: Output }], onOpen: [{ type: Output }], isOpenChange: [{ type: Output }], role: [{ type: HostBinding, args: ["attr.role"] }], hasPopup: [{ type: HostBinding, args: ["attr.aria-haspopup"] }], ariaOwns: [{ type: HostBinding, args: ["attr.aria-owns"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhbG9nLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kaWFsb2cvZGlhbG9nLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQU9aLFdBQVcsRUFHWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFhLFlBQVksRUFBZ0IsTUFBTSwyQkFBMkIsQ0FBQztBQUdsRixPQUFPLEVBQUUsU0FBUyxFQUFnQixNQUFNLE1BQU0sQ0FBQzs7OztBQUUvQzs7Ozs7Ozs7R0FRRztBQVFILE1BQU0sT0FBTyxlQUFlO0lBNkYzQjs7Ozs7O09BTUc7SUFDSCxZQUNXLFVBQXNCLEVBQ3RCLGdCQUFrQyxFQUNsQyxhQUE0QjtJQUN0Qzs7T0FFRztJQUNPLFlBQTBCO1FBTjFCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUk1QixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQXpHckM7O1dBRUc7UUFDTSxVQUFLLEdBQUcsRUFBRSxDQUFDO1FBVXBCOzs7V0FHRztRQUNNLFlBQU8sR0FBcUMsT0FBTyxDQUFDO1FBQzdEOzs7Ozs7O1dBT0c7UUFDTSxpQkFBWSxHQUE4QixZQUFZLENBQUM7UUFDaEU7O1dBRUc7UUFDTSxjQUFTLEdBQUcsTUFBTSxDQUFDO1FBUzVCOztXQUVHO1FBQ00sUUFBRyxHQUFHLENBQUMsQ0FBQztRQUNqQjs7V0FFRztRQUNNLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzlCOztXQUVHO1FBQ00sU0FBSSxHQUFHLEVBQUUsQ0FBQztRQUV5QixXQUFNLEdBQUcsS0FBSyxDQUFDO1FBQzNEOztXQUVHO1FBQ00sYUFBUSxHQUFH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TztzQkFBaEIsTUFBTTtnQkFJRyxNQUFNO3NCQUFmLE1BQU07Z0JBSUcsWUFBWTtzQkFBckIsTUFBTTtnQkFFbUIsSUFBSTtzQkFBN0IsV0FBVzt1QkFBQyxXQUFXO2dCQUNXLFFBQVE7c0JBQTFDLFdBQVc7dUJBQUMsb0JBQW9CO2dCQUNFLFFBQVE7c0JBQTFDLFdBQVc7dUJBQUMsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0RGlyZWN0aXZlLFxuXHRJbnB1dCxcblx0T3V0cHV0LFxuXHRFdmVudEVtaXR0ZXIsXG5cdE9uSW5pdCxcblx0T25EZXN0cm95LFxuXHRFbGVtZW50UmVmLFxuXHRUZW1wbGF0ZVJlZixcblx0Vmlld0NvbnRhaW5lclJlZixcblx0T25DaGFuZ2VzLFxuXHRIb3N0QmluZGluZyxcblx0U2ltcGxlQ2hhbmdlcyxcblx0Q29tcG9uZW50UmVmXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBEaWFsb2dTZXJ2aWNlIH0gZnJvbSBcIi4vZGlhbG9nLnNlcnZpY2VcIjtcbmltcG9ydCB7IENsb3NlTWV0YSwgQ2xvc2VSZWFzb25zLCBEaWFsb2dDb25maWcgfSBmcm9tIFwiLi9kaWFsb2ctY29uZmlnLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgRXZlbnRTZXJ2aWNlIH0gZnJvbSBcImNhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXIvdXRpbHNcIjtcbmltcG9ydCB7IERpYWxvZyB9IGZyb20gXCIuL2RpYWxvZy5jb21wb25lbnRcIjtcbmltcG9ydCB7IGZyb21FdmVudCwgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcblxuLyoqXG4gKiBBIGdlbmVyaWMgZGlyZWN0aXZlIHRoYXQgY2FuIGJlIGluaGVyaXRlZCBmcm9tIHRvIGNyZWF0ZSBkaWFsb2dzIChmb3IgZXhhbXBsZSwgYSB0b29sdGlwIG9yIHBvcG92ZXIpXG4gKlxuICogVGhpcyBjbGFzcyBjb250YWlucyB0aGUgcmVsZXZhbnQgaW5pdGlhbGl6YXRpb24gY29kZSwgc3BlY2lmaWMgdGVtcGxhdGVzLCBvcHRpb25zLCBhbmQgYWRkaXRpb25hbCBpbnB1dHNcbiAqIHNob3VsZCBiZSBzcGVjaWZpZWQgaW4gdGhlIGRlcml2ZWQgY2xhc3MuXG4gKlxuICogTk9URTogQWxsIGNoaWxkIGNsYXNzZXMgc2hvdWxkIGFkZCBgRGlhbG9nU2VydmljZWAgYXMgYSBwcm92aWRlciwgb3RoZXJ3aXNlIHRoZXkgd2lsbCBsb3NlIGNvbnRleHQgdGhhdFxuICogdGhlIHNlcnZpY2UgcmVsaWVzIG9uLlxuICovXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6IFwiW2Nkc0RpYWxvZ10sIFtpYm1EaWFsb2ddXCIsXG5cdGV4cG9ydEFzOiBcImRpYWxvZ1wiLFxuXHRwcm92aWRlcnM6IFtcblx0XHREaWFsb2dTZXJ2aWNlXG5cdF1cbn0pXG5leHBvcnQgY2xhc3MgRGlhbG9nRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG5cdHN0YXRpYyBkaWFsb2dDb3VudGVyID0gMDtcblx0LyoqXG5cdCAqIFRpdGxlIGZvciB0aGUgZGlhbG9nXG5cdCAqL1xuXHRASW5wdXQoKSB0aXRsZSA9IFwiXCI7XG5cdC8qKlxuXHQgKiBAZGVwcmVjYXRlZCBhcyBvZiB2NSwgdXNlIGBjZHNEaWFsb2dgIGluc3RlYWRcblx0ICogRGlhbG9nIGJvZHkgY29udGVudC5cblx0ICovXG5cdEBJbnB1dCgpIHNldCBpYm1EaWFsb2coYm9keTogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pikge1xuXHRcdHRoaXMuY2RzRGlhbG9nID0gYm9keTtcblx0fVxuXG5cdEBJbnB1dCgpIGNkc0RpYWxvZzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAqIERlZmluZXMgaG93IHRoZSBEaWFsb2cgaXMgdHJpZ2dlcmVkLihIb3ZlciBhbmQgY2xpY2sgYmVoYXZlIHRoZSBzYW1lIG9uIG1vYmlsZSAtIGJvdGggcmVzcG9uZCB0byBhIHNpbmdsZSB0YXApLlxuXHQgKiBEbyBub3QgYWRkIGZvY3VzYWJsZSBlbGVtZW50cyBpZiB0cmlnZ2VyIGlzIGBob3ZlcmAgb3IgYG1vdXNlZW50ZXJgLlxuXHQgKi9cblx0QElucHV0KCkgdHJpZ2dlcjogXCJjbGlja1wiIHwgXCJob3ZlclwiIHwgXCJtb3VzZWVudGVyXCIgPSBcImNsaWNrXCI7XG5cdC8qKlxuXHQgKiBEZWZpbmVzIGhvdyB0aGUgRGlhbG9nIGNsb3NlIGV2ZW50IGlzIHRyaWdnZXJlZC5cblx0ICpcblx0ICogW1NlZSBoZXJlXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudC9tb3VzZWxlYXZlX2V2ZW50KVxuXHQgKiBmb3IgbW9yZSBvbiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGBtb3VzZWxlYXZlYCBhbmQgYG1vdXNlb3V0YC5cblx0ICpcblx0ICogRGVmYXVsdHMgdG8gYGNsaWNrYCB3aGVuIGB0cmlnZ2VyYCBpcyBzZXQgdG8gYGNsaWNrYC5cblx0ICovXG5cdEBJbnB1dCgpIGNsb3NlVHJpZ2dlcjogXCJtb3VzZW91dFwiIHwgXCJtb3VzZWxlYXZlXCIgPSBcIm1vdXNlbGVhdmVcIjtcblx0LyoqXG5cdCAqIFBsYWNlbWVudCBvZiB0aGUgZGlhbG9nLCB1c3VhbGx5IHJlbGF0aXZlIHRvIHRoZSBlbGVtZW50IHRoZSBkaXJlY3RpdmUgaXMgb24uXG5cdCAqL1xuXHRASW5wdXQoKSBwbGFjZW1lbnQgPSBcImxlZnRcIjtcblx0LyoqXG5cdCAqIFRoaXMgc3BlY2lmaWVzIGFueSB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBvZmZzZXQgZm9yIHRoZSBwb3NpdGlvbiBvZiB0aGUgZGlhbG9nXG5cdCAqL1xuXHRASW5wdXQoKSBvZmZzZXQ6IHsgeDogbnVtYmVyLCB5OiBudW1iZXIgfTtcblx0LyoqXG5cdCAqIENsYXNzZXMgdG8gYWRkIHRvIHRoZSBkaWFsb2cgY29udGFpbmVyXG5cdCAqL1xuXHRASW5wdXQoKSB3cmFwcGVyQ2xhc3M6IHN0cmluZztcblx0LyoqXG5cdCAqIFNwYWNpbmcgYmV0d2VlbiB0aGUgZGlhbG9nIGFuZCBpdCdzIHRyaWdnZXJpbmcgZWxlbWVudFxuXHQgKi9cblx0QElucHV0KCkgZ2FwID0gMDtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgdG8gb3BlbiB0aGUgZGlhbG9nIG5leHQgdG8gdGhlIHRyaWdnZXJpbmcgY29tcG9uZW50XG5cdCAqL1xuXHRASW5wdXQoKSBhcHBlbmRJbmxpbmUgPSBmYWxzZTtcblx0LyoqXG5cdCAqIE9wdGlvbmFsIGRhdGEgZm9yIHRlbXBsYXRlc1xuXHQgKi9cblx0QElucHV0KCkgZGF0YSA9IHt9O1xuXG5cdEBJbnB1dCgpIEBIb3N0QmluZGluZyhcImF0dHIuYXJpYS1leHBhbmRlZFwiKSBpc09wZW4gPSBmYWxzZTtcblx0LyoqXG5cdCAqIFRoaXMgcHJldmVudHMgdGhlIGRpYWxvZyBmcm9tIGJlaW5nIHRvZ2dsZWRcblx0ICovXG5cdEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBUaGlzIGlucHV0IGFsbG93cyBleHBsaWNpdCBjb250cm9sIG92ZXIgaG93IHRoZSBkaWFsb2cgc2hvdWxkIGNsb3NlXG5cdCAqL1xuXHRASW5wdXQoKSBzaG91bGRDbG9zZTogKG1ldGE6IENsb3NlTWV0YSkgPT4gYm9vbGVhbjtcblx0LyoqXG5cdCAqIENvbmZpZyBvYmplY3QgcGFzc2VkIHRvIHRoZSByZW5kZXJlZCBjb21wb25lbnRcblx0ICovXG5cdGRpYWxvZ0NvbmZpZzogRGlhbG9nQ29uZmlnO1xuXHQvKipcblx0ICogRW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgZGlhbG9nIGlzIGNsb3NlZFxuXHQgKi9cblx0QE91dHB1dCgpIG9uQ2xvc2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHQvKipcblx0ICogRW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZFxuXHQgKi9cblx0QE91dHB1dCgpIG9uT3BlbjogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cdC8qKlxuXHQgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBzdGF0ZSBvZiBgaXNPcGVuYCBjaGFuZ2VzLiBBbGxvd3MgYGlzT3BlbmAgdG8gYmUgZG91YmxlIGJvdW5kXG5cdCAqL1xuXHRAT3V0cHV0KCkgaXNPcGVuQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG5cdEBIb3N0QmluZGluZyhcImF0dHIucm9sZVwiKSByb2xlID0gXCJidXR0b25cIjtcblx0QEhvc3RCaW5kaW5nKFwiYXR0ci5hcmlhLWhhc3BvcHVwXCIpIGhhc1BvcHVwID0gdHJ1ZTtcblx0QEhvc3RCaW5kaW5nKFwiYXR0ci5hcmlhLW93bnNcIikgZ2V0IGFyaWFPd25zKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMuaXNPcGVuID8gdGhpcy5kaWFsb2dDb25maWcuY29tcElEIDogbnVsbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBLZWVwcyBhIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudGx5IG9wZW5lZCBkaWFsb2dcblx0ICovXG5cdHByb3RlY3RlZCBkaWFsb2dSZWY6IENvbXBvbmVudFJlZjxEaWFsb2c+O1xuXG5cdHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBEaWFsb2dEaXJlY3RpdmUuXG5cdCAqIEBwYXJhbSBlbGVtZW50UmVmXG5cdCAqIEBwYXJhbSB2aWV3Q29udGFpbmVyUmVmXG5cdCAqIEBwYXJhbSBkaWFsb2dTZXJ2aWNlXG5cdCAqIEBwYXJhbSBldmVudFNlcnZpY2Vcblx0ICovXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByb3RlY3RlZCBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuXHRcdHByb3RlY3RlZCB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuXHRcdHByb3RlY3RlZCBkaWFsb2dTZXJ2aWNlOiBEaWFsb2dTZXJ2aWNlLFxuXHRcdC8qKlxuXHRcdCAqIERlcHJlY2F0ZWQgYXMgb2YgdjVcblx0XHQgKi9cblx0XHRwcm90ZWN0ZWQgZXZlbnRTZXJ2aWNlOiBFdmVudFNlcnZpY2Vcblx0KSB7fVxuXG5cdG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcblx0XHQvLyBzZXQgdGhlIGNvbmZpZyBvYmplY3QgKHRoaXMgY2FuIFthbmQgc2hvdWxkIV0gYmUgYWRkZWQgdG8gaW4gY2hpbGQgY2xhc3NlcyBkZXBlbmRpbmcgb24gd2hhdCB0aGV5IG5lZWQpXG5cdFx0dGhpcy5kaWFsb2dDb25maWcgPSB7XG5cdFx0XHR0aXRsZTogdGhpcy50aXRsZSxcblx0XHRcdGNvbnRlbnQ6IHRoaXMuY2RzRGlhbG9nLFxuXHRcdFx0cGxhY2VtZW50OiB0aGlzLnBsYWNlbWVudCxcblx0XHRcdHBhcmVudFJlZjogdGhpcy5lbGVtZW50UmVmLFxuXHRcdFx0Z2FwOiB0aGlzLmdhcCxcblx0XHRcdHRyaWdnZXI6IHRoaXMudHJpZ2dlcixcblx0XHRcdGNsb3NlVHJpZ2dlcjogdGhpcy5jbG9zZVRyaWdnZXIsXG5cdFx0XHRzaG91bGRDbG9zZTogdGhpcy5zaG91bGRDbG9zZSB8fCAoKCkgPT4gdHJ1ZSksXG5cdFx0XHRhcHBlbmRJbmxpbmU6IHRoaXMuYXBwZW5kSW5saW5lLFxuXHRcdFx0d3JhcHBlckNsYXNzOiB0aGlzLndyYXBwZXJDbGFzcyxcblx0XHRcdGRhdGE6IHRoaXMuZGF0YSxcblx0XHRcdG9mZnNldDogdGhpcy5vZmZzZXQsXG5cdFx0XHRkaXNhYmxlZDogdGhpcy5kaXNhYmxlZFxuXHRcdH07XG5cblx0XHRpZiAoY2hhbmdlcy5pc09wZW4pIHtcblx0XHRcdGlmIChjaGFuZ2VzLmlzT3Blbi5jdXJyZW50VmFsdWUpIHtcblx0XHRcdFx0dGhpcy5vcGVuKCk7XG5cdFx0XHR9IGVsc2UgaWYgKCFjaGFuZ2VzLmlzT3Blbi5maXJzdENoYW5nZSkge1xuXHRcdFx0XHR0aGlzLmNsb3NlKHtcblx0XHRcdFx0XHRyZWFzb246IENsb3NlUmVhc29ucy5wcm9ncmFtbWF0aWNcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUnVuIGFueSBjb2RlIGEgY2hpbGQgY2xhc3MgbWF5IG5lZWQuXG5cdFx0dGhpcy5vbkRpYWxvZ0NoYW5nZXMoY2hhbmdlcyk7XG5cdFx0dGhpcy51cGRhdGVDb25maWcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBjb25maWcgb2JqZWN0IGFuZCBiaW5kcyBldmVudHMgZm9yIGhvdmVyaW5nIG9yIGNsaWNraW5nIGJlZm9yZVxuXHQgKiBydW5uaW5nIGNvZGUgZnJvbSBjaGlsZCBjbGFzcy5cblx0ICovXG5cdG5nT25Jbml0KCkge1xuXHRcdC8vIGZpeCBmb3Igc2FmYXJpIGhpamFja2luZyBjbGlja3Ncblx0XHR0aGlzLmRpYWxvZ1NlcnZpY2Uuc2luZ2xldG9uQ2xpY2tMaXN0ZW4oKTtcblxuXHRcdGNvbnN0IGVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG5cblx0XHR0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcblx0XHRcdGZyb21FdmVudChlbGVtZW50LCBcImtleWRvd25cIikuc3Vic2NyaWJlKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuXHRcdFx0XHRpZiAoZXZlbnQudGFyZ2V0ID09PSB0aGlzLmRpYWxvZ0NvbmZpZy5wYXJlbnRSZWYubmF0aXZlRWxlbWVudCAmJlxuXHRcdFx0XHRcdChldmVudC5rZXkgPT09IFwiVGFiXCIgfHwgZXZlbnQua2V5ID09PSBcIlRhYlwiICYmIGV2ZW50LnNoaWZ0S2V5KSB8fFxuXHRcdFx0XHRcdGV2ZW50LmtleSA9PT0gXCJFc2NhcGVcIikge1xuXHRcdFx0XHRcdHRoaXMuY2xvc2Uoe1xuXHRcdFx0XHRcdFx0cmVhc29uOiBDbG9zZVJlYXNvbnMuaW50ZXJhY3Rpb24sXG5cdFx0XHRcdFx0XHR0YXJnZXQ6IGV2ZW50LnRhcmdldFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdCk7XG5cblx0XHQvLyBiaW5kIGV2ZW50cyBmb3IgaG92ZXJpbmcgb3IgY2xpY2tpbmcgdGhlIGhvc3Rcblx0XHRpZiAodGhpcy50cmlnZ2VyID09PSBcImhvdmVyXCIgfHwgdGhpcy50cmlnZ2VyID09PSBcIm1vdXNlZW50ZXJcIikge1xuXHRcdFx0dGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG5cdFx0XHRcdGZyb21FdmVudChlbGVtZW50LCBcIm1vdXNlZW50ZXJcIikuc3Vic2NyaWJlKCgpID0+IHRoaXMub3BlbigpKSxcblx0XHRcdFx0ZnJvbUV2ZW50KGVsZW1lbnQsIHRoaXMuY2xvc2VUcmlnZ2VyKS5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5jbG9zZSh7XG5cdFx0XHRcdFx0XHRyZWFzb246IENsb3NlUmVhc29ucy5pbnRlcmFjdGlvbixcblx0XHRcdFx0XHRcdHRhcmdldDogZXZlbnQudGFyZ2V0XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0pLFxuXHRcdFx0XHRmcm9tRXZlbnQoZWxlbWVudCwgXCJmb2N1c1wiKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vcGVuKCkpLFxuXHRcdFx0XHRmcm9tRXZlbnQoZWxlbWVudCwgXCJibHVyXCIpLnN1YnNjcmliZSgoZXZlbnQpID0+IHtcblx0XHRcdFx0XHR0aGlzLmNsb3NlKHtcblx0XHRcdFx0XHRcdHJlYXNvbjogQ2xvc2VSZWFzb25zLmludGVyYWN0aW9uLFxuXHRcdFx0XHRcdFx0dGFyZ2V0OiBldmVudC50YXJnZXRcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuXHRcdFx0XHRmcm9tRXZlbnQoZWxlbWVudCwgXCJjbGlja1wiKS5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0dGhpcy50b2dnbGUoe1xuXHRcdFx0XHRcdFx0cmVhc29uOiBDbG9zZVJlYXNvbnMuaW50ZXJhY3Rpb24sXG5cdFx0XHRcdFx0XHR0YXJnZXQ6IGV2ZW50LnRhcmdldFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9KSxcblx0XHRcdFx0ZnJvbUV2ZW50KGVsZW1lbnQsIFwia2V5ZG93blwiKS5zdWJzY3JpYmUoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0aWYgKGV2ZW50LmtleSA9PT0gXCJFbnRlclwiIHx8IGV2ZW50LmtleSA9PT0gXCIgXCIpIHtcblx0XHRcdFx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHR0aGlzLm9wZW4oKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0RGlhbG9nRGlyZWN0aXZlLmRpYWxvZ0NvdW50ZXIrKztcblx0XHR0aGlzLmRpYWxvZ0NvbmZpZy5jb21wSUQgPSBcImRpYWxvZy1cIiArIERpYWxvZ0RpcmVjdGl2ZS5kaWFsb2dDb3VudGVyO1xuXG5cdFx0Ly8gcnVuIGFueSBjb2RlIGEgY2hpbGQgY2xhc3MgbWF5IG5lZWRcblx0XHR0aGlzLm9uRGlhbG9nSW5pdCgpO1xuXHRcdHRoaXMudXBkYXRlQ29uZmlnKCk7XG5cdH1cblxuXHQvKipcblx0ICogV2hlbiB0aGUgaG9zdCBkaWVzLCBraWxsIHRoZSBwb3BvdmVyLlxuXHQgKiAtIFVzZWZ1bCBmb3IgdXNlIGluIGEgbW9kYWwgb3Igc2ltaWxhci5cblx0ICovXG5cdG5nT25EZXN0cm95KCkge1xuXHRcdHRoaXMuY2xvc2Uoe1xuXHRcdFx0cmVhc29uOiBDbG9zZVJlYXNvbnMuZGVzdHJveWVkXG5cdFx0fSk7XG5cdFx0dGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goKHN1YnNjcmlwdGlvbikgPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhlbHBlciBtZXRob2QgdG8gY2FsbCBkaWFsb2dTZXJ2aWNlICdvcGVuJy5cblx0ICogLSBFbmZvcmNlIGFjY2Vzc2liaWxpdHkgYnkgdXBkYXRpbmcgYW4gYXJpYSBhdHRyIGZvciBuYXRpdmVFbGVtZW50LlxuXHQgKi9cblx0b3Blbihjb21wb25lbnQ/KSB7XG5cdFx0Ly8gZG9uJ3QgYWxsb3cgZGlhbG9ncyB0byBiZSBvcGVuZWQgaWYgdGhleSdyZSBhbHJlYWR5IG9wZW5cblx0XHRpZiAodGhpcy5kaWFsb2dSZWYgfHwgdGhpcy5kaXNhYmxlZCkgeyByZXR1cm47IH1cblxuXHRcdC8vIGFjdHVhbGx5IG9wZW4gdGhlIGRpYWxvZywgZW1pdCBldmVudHMsIGFuZCBzZXQgdGhlIG9wZW4gc3RhdGVcblx0XHR0aGlzLmRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKHRoaXMudmlld0NvbnRhaW5lclJlZiwgdGhpcy5kaWFsb2dDb25maWcsIGNvbXBvbmVudCk7XG5cdFx0dGhpcy5pc09wZW4gPSB0cnVlO1xuXHRcdHRoaXMub25PcGVuLmVtaXQoKTtcblx0XHR0aGlzLmlzT3BlbkNoYW5nZS5lbWl0KHRydWUpO1xuXG5cdFx0Ly8gSGFuZGxlcyBlbWl0dGluZyBhbGwgdGhlIGNsb3NlIGV2ZW50cyB0byBjbGVhbiBldmVyeXRoaW5nIHVwXG5cdFx0Ly8gQWxzbyBlbmZvcmNlIGFjY2Vzc2liaWxpdHkgb24gY2xvc2UgYnkgdXBkYXRpbmcgYW4gYXJpYSBhdHRyIG9uIHRoZSBuYXRpdmVFbGVtZW50LlxuXHRcdGNvbnN0IHN1YnNjcmlwdGlvbiA9IHRoaXMuZGlhbG9nUmVmLmluc3RhbmNlLmNsb3NlLnN1YnNjcmliZSgobWV0YTogQ2xvc2VNZXRhKSA9PiB7XG5cdFx0XHRpZiAoIXRoaXMuZGlhbG9nUmVmKSB7IHJldHVybjsgfVxuXHRcdFx0aWYgKHRoaXMuZGlhbG9nQ29uZmlnLnNob3VsZENsb3NlICYmIHRoaXMuZGlhbG9nQ29uZmlnLnNob3VsZENsb3NlKG1ldGEpKSB7XG5cdFx0XHRcdC8vIGNsb3NlIHRoZSBkaWFsb2csIGVtaXQgZXZlbnRzLCBhbmQgY2xlYXIgb3V0IHRoZSBvcGVuIHN0YXRlc1xuXHRcdFx0XHR0aGlzLmRpYWxvZ1NlcnZpY2UuY2xvc2UodGhpcy5kaWFsb2dSZWYpO1xuXHRcdFx0XHR0aGlzLmRpYWxvZ1JlZiA9IG51bGw7XG5cdFx0XHRcdHRoaXMuaXNPcGVuID0gZmFsc2U7XG5cdFx0XHRcdHRoaXMub25DbG9zZS5lbWl0KCk7XG5cdFx0XHRcdHRoaXMuaXNPcGVuQ2hhbmdlLmVtaXQoZmFsc2UpO1xuXHRcdFx0XHRzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHJldHVybiB0aGlzLmRpYWxvZ1JlZjtcblx0fVxuXG5cdC8qKlxuXHQgKiBIZWxwZXIgbWV0aG9kIHRvIHRvZ2dsZSB0aGUgb3BlbiBzdGF0ZSBvZiB0aGUgZGlhbG9nXG5cdCAqL1xuXHR0b2dnbGUobWV0YTogQ2xvc2VNZXRhID0geyByZWFzb246IENsb3NlUmVhc29ucy5pbnRlcmFjdGlvbiB9KSB7XG5cdFx0aWYgKCF0aGlzLmlzT3Blbikge1xuXHRcdFx0dGhpcy5vcGVuKCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuY2xvc2UobWV0YSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEhlbHBlciBtZXRob2QgdG8gY2xvc2UgdGhlIGRpYWxvZ1JlZi5cblx0ICovXG5cdGNsb3NlKG1ldGE6IENsb3NlTWV0YSA9IHsgcmVhc29uOiBDbG9zZVJlYXNvbnMuaW50ZXJhY3Rpb24gfSkge1xuXHRcdGlmICh0aGlzLmRpYWxvZ1JlZikge1xuXHRcdFx0dGhpcy5kaWFsb2dSZWYuaW5zdGFuY2UuZG9DbG9zZShtZXRhKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRW1wdHkgbWV0aG9kIGZvciBjaGlsZCBjbGFzc2VzIHRvIG92ZXJyaWRlIGFuZCBzcGVjaWZ5IGFkZGl0aW9uYWwgaW5pdCBzdGVwcy5cblx0ICogUnVuIGFmdGVyIERpYWxvZ0RpcmVjdGl2ZSBjb21wbGV0ZXMgaXQncyBuZ09uSW5pdC5cblx0ICovXG5cdHByb3RlY3RlZCBvbkRpYWxvZ0luaXQoKSB7fVxuXG5cdC8qKlxuXHQgKiBFbXB0eSBtZXRob2QgZm9yIGNoaWxkIHRvIG92ZXJyaWRlIGFuZCBzcGVjaWZ5IGFkZGl0aW9uYWwgb24gY2hhbmdlcyBzdGVwcy5cblx0ICogcnVuIGFmdGVyIERpYWxvZ0RpcmVjdGl2ZSBjb21wbGV0ZXMgaXQncyBuZ09uQ2hhbmdlcy5cblx0ICovXG5cdHByb3RlY3RlZCBvbkRpYWxvZ0NoYW5nZXMoX2NoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHt9XG5cblx0cHJvdGVjdGVkIHVwZGF0ZUNvbmZpZygpIHt9XG59XG4iXX0=