UNPKG

carbon-components-angular

Version:
312 lines 33.2 kB
import { Directive, Input, Output, EventEmitter, HostBinding } from "@angular/core"; import { DialogService } from "./dialog.service"; import { CloseReasons } from "./dialog-config.interface"; 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, 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; } /** * @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.eventService.on(element, "keydown", (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.eventService.on(element, "mouseenter", this.open.bind(this)); this.eventService.on(element, this.closeTrigger, (event) => { this.close({ reason: CloseReasons.interaction, target: event.target }); }); this.eventService.on(element, "focus", this.open.bind(this)); this.eventService.on(element, "blur", (event) => { this.close({ reason: CloseReasons.interaction, target: event.target }); }); } else { this.eventService.on(element, "click", (event) => { this.toggle({ reason: CloseReasons.interaction, target: event.target }); }); this.eventService.on(element, "keydown", (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 }); } /** * 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. 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); } }); 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhbG9nLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kaWFsb2cvZGlhbG9nLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQU9aLFdBQVcsRUFHWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFhLFlBQVksRUFBZ0IsTUFBTSwyQkFBMkIsQ0FBQzs7OztBQUlsRjs7Ozs7Ozs7R0FRRztBQVFILE1BQU0sT0FBTyxlQUFlO0lBMkYzQjs7Ozs7O09BTUc7SUFDSCxZQUNXLFVBQXNCLEVBQ3RCLGdCQUFrQyxFQUNsQyxhQUE0QixFQUM1QixZQUEwQjtRQUgxQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFwR3JDOztXQUVHO1FBQ00sVUFBSyxHQUFHLEVBQUUsQ0FBQztRQVVwQjs7O1dBR0c7UUFDTSxZQUFPLEdBQXFDLE9BQU8sQ0FBQztRQUM3RDs7Ozs7OztXQU9HO1FBQ00saUJBQVksR0FBOEIsWUFBWSxDQUFDO1FBQ2hFOztXQUVHO1FBQ00sY0FBUyxHQUFHLE1BQU0sQ0FBQztRQVM1Qjs7V0FFRztRQUNNLFFBQUcsR0FBRyxDQUFDLENBQUM7UUFDakI7O1dBRUc7UUFDTSxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUM5Qjs7V0FFRztRQUNNLFNBQUksR0FBRyxFQUFFLENBQUM7UUFFeUIsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUMzRDs7V0FFRztRQUNNLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFTMUI7O1dBRUc7UUFDTyxZQUFPLEdBQXNCLElBQUksWUFBWSxFQUFF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QUVEOzs7T0FHRztJQUNPLFlBQVksS0FBSSxDQUFDO0lBRTNCOzs7T0FHRztJQUNPLGVBQWUsQ0FBQyxRQUF1QixJQUFHLENBQUM7SUFFM0MsWUFBWSxLQUFJLENBQUM7O0FBL1FwQiw2QkFBYSxHQUFHLENBQUMsQ0FBQzs0R0FEYixlQUFlO2dHQUFmLGVBQWUseW1CQUpoQjtRQUNWLGFBQWE7S0FDYjsyRkFFVyxlQUFlO2tCQVAzQixTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSwwQkFBMEI7b0JBQ3BDLFFBQVEsRUFBRSxRQUFRO29CQUNsQixTQUFTLEVBQUU7d0JBQ1YsYUFBYTtxQkFDYjtpQkFDRDt1TEFNUyxLQUFLO3NCQUFiLEtBQUs7Z0JBS08sU0FBUztzQkFBckIsS0FBSztnQkFJRyxTQUFTO3NCQUFqQixLQUFLO2dCQUtHLE9BQU87c0JBQWYsS0FBSztnQkFTRyxZQUFZO3NCQUFwQixLQUFLO2dCQUlHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBSUcsTUFBTTtzQkFBZCxLQUFLO2dCQUlHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBSUcsR0FBRztzQkFBWCxLQUFLO2dCQUlHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBSUcsSUFBSTtzQkFBWixLQUFLO2dCQUVzQyxNQUFNO3NCQUFqRCxLQUFLOztzQkFBSSxXQUFXO3VCQUFDLG9CQUFvQjtnQkFJakMsUUFBUTtzQkFBaEIsS0FBSztnQkFJRyxXQUFXO3NCQUFuQixLQUFLO2dCQVFJLE9BQU87c0JBQWhCLE1BQU07Z0JBSUcsTUFBTTtzQkFBZixNQUFNO2dCQUlHLFlBQVk7c0JBQXJCLE1BQU07Z0JBRW1CLElBQUk7c0JBQTdCLFdBQVc7dUJBQUMsV0FBVztnQkFDVyxRQUFRO3NCQUExQyxXQUFXO3VCQUFDLG9CQUFvQjtnQkFDRSxRQUFRO3NCQUExQyxXQUFXO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdERpcmVjdGl2ZSxcblx0SW5wdXQsXG5cdE91dHB1dCxcblx0RXZlbnRFbWl0dGVyLFxuXHRPbkluaXQsXG5cdE9uRGVzdHJveSxcblx0RWxlbWVudFJlZixcblx0VGVtcGxhdGVSZWYsXG5cdFZpZXdDb250YWluZXJSZWYsXG5cdE9uQ2hhbmdlcyxcblx0SG9zdEJpbmRpbmcsXG5cdFNpbXBsZUNoYW5nZXMsXG5cdENvbXBvbmVudFJlZlxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgRGlhbG9nU2VydmljZSB9IGZyb20gXCIuL2RpYWxvZy5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBDbG9zZU1ldGEsIENsb3NlUmVhc29ucywgRGlhbG9nQ29uZmlnIH0gZnJvbSBcIi4vZGlhbG9nLWNvbmZpZy5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IEV2ZW50U2VydmljZSB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL3V0aWxzXCI7XG5pbXBvcnQgeyBEaWFsb2cgfSBmcm9tIFwiLi9kaWFsb2cuY29tcG9uZW50XCI7XG5cbi8qKlxuICogQSBnZW5lcmljIGRpcmVjdGl2ZSB0aGF0IGNhbiBiZSBpbmhlcml0ZWQgZnJvbSB0byBjcmVhdGUgZGlhbG9ncyAoZm9yIGV4YW1wbGUsIGEgdG9vbHRpcCBvciBwb3BvdmVyKVxuICpcbiAqIFRoaXMgY2xhc3MgY29udGFpbnMgdGhlIHJlbGV2YW50IGluaXRpYWxpemF0aW9uIGNvZGUsIHNwZWNpZmljIHRlbXBsYXRlcywgb3B0aW9ucywgYW5kIGFkZGl0aW9uYWwgaW5wdXRzXG4gKiBzaG91bGQgYmUgc3BlY2lmaWVkIGluIHRoZSBkZXJpdmVkIGNsYXNzLlxuICpcbiAqIE5PVEU6IEFsbCBjaGlsZCBjbGFzc2VzIHNob3VsZCBhZGQgYERpYWxvZ1NlcnZpY2VgIGFzIGEgcHJvdmlkZXIsIG90aGVyd2lzZSB0aGV5IHdpbGwgbG9zZSBjb250ZXh0IHRoYXRcbiAqIHRoZSBzZXJ2aWNlIHJlbGllcyBvbi5cbiAqL1xuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiBcIltjZHNEaWFsb2ddLCBbaWJtRGlhbG9nXVwiLFxuXHRleHBvcnRBczogXCJkaWFsb2dcIixcblx0cHJvdmlkZXJzOiBbXG5cdFx0RGlhbG9nU2VydmljZVxuXHRdXG59KVxuZXhwb3J0IGNsYXNzIERpYWxvZ0RpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuXHRzdGF0aWMgZGlhbG9nQ291bnRlciA9IDA7XG5cdC8qKlxuXHQgKiBUaXRsZSBmb3IgdGhlIGRpYWxvZ1xuXHQgKi9cblx0QElucHV0KCkgdGl0bGUgPSBcIlwiO1xuXHQvKipcblx0ICogQGRlcHJlY2F0ZWQgYXMgb2YgdjUsIHVzZSBgY2RzRGlhbG9nYCBpbnN0ZWFkXG5cdCAqIERpYWxvZyBib2R5IGNvbnRlbnQuXG5cdCAqL1xuXHRASW5wdXQoKSBzZXQgaWJtRGlhbG9nKGJvZHk6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT4pIHtcblx0XHR0aGlzLmNkc0RpYWxvZyA9IGJvZHk7XG5cdH1cblxuXHRASW5wdXQoKSBjZHNEaWFsb2c6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cdC8qKlxuXHQgKiBEZWZpbmVzIGhvdyB0aGUgRGlhbG9nIGlzIHRyaWdnZXJlZC4oSG92ZXIgYW5kIGNsaWNrIGJlaGF2ZSB0aGUgc2FtZSBvbiBtb2JpbGUgLSBib3RoIHJlc3BvbmQgdG8gYSBzaW5nbGUgdGFwKS5cblx0ICogRG8gbm90IGFkZCBmb2N1c2FibGUgZWxlbWVudHMgaWYgdHJpZ2dlciBpcyBgaG92ZXJgIG9yIGBtb3VzZWVudGVyYC5cblx0ICovXG5cdEBJbnB1dCgpIHRyaWdnZXI6IFwiY2xpY2tcIiB8IFwiaG92ZXJcIiB8IFwibW91c2VlbnRlclwiID0gXCJjbGlja1wiO1xuXHQvKipcblx0ICogRGVmaW5lcyBob3cgdGhlIERpYWxvZyBjbG9zZSBldmVudCBpcyB0cmlnZ2VyZWQuXG5cdCAqXG5cdCAqIFtTZWUgaGVyZV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnQvbW91c2VsZWF2ZV9ldmVudClcblx0ICogZm9yIG1vcmUgb24gdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBgbW91c2VsZWF2ZWAgYW5kIGBtb3VzZW91dGAuXG5cdCAqXG5cdCAqIERlZmF1bHRzIHRvIGBjbGlja2Agd2hlbiBgdHJpZ2dlcmAgaXMgc2V0IHRvIGBjbGlja2AuXG5cdCAqL1xuXHRASW5wdXQoKSBjbG9zZVRyaWdnZXI6IFwibW91c2VvdXRcIiB8IFwibW91c2VsZWF2ZVwiID0gXCJtb3VzZWxlYXZlXCI7XG5cdC8qKlxuXHQgKiBQbGFjZW1lbnQgb2YgdGhlIGRpYWxvZywgdXN1YWxseSByZWxhdGl2ZSB0byB0aGUgZWxlbWVudCB0aGUgZGlyZWN0aXZlIGlzIG9uLlxuXHQgKi9cblx0QElucHV0KCkgcGxhY2VtZW50ID0gXCJsZWZ0XCI7XG5cdC8qKlxuXHQgKiBUaGlzIHNwZWNpZmllcyBhbnkgdmVydGljYWwgYW5kIGhvcml6b250YWwgb2Zmc2V0IGZvciB0aGUgcG9zaXRpb24gb2YgdGhlIGRpYWxvZ1xuXHQgKi9cblx0QElucHV0KCkgb2Zmc2V0OiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH07XG5cdC8qKlxuXHQgKiBDbGFzc2VzIHRvIGFkZCB0byB0aGUgZGlhbG9nIGNvbnRhaW5lclxuXHQgKi9cblx0QElucHV0KCkgd3JhcHBlckNsYXNzOiBzdHJpbmc7XG5cdC8qKlxuXHQgKiBTcGFjaW5nIGJldHdlZW4gdGhlIGRpYWxvZyBhbmQgaXQncyB0cmlnZ2VyaW5nIGVsZW1lbnRcblx0ICovXG5cdEBJbnB1dCgpIGdhcCA9IDA7XG5cdC8qKlxuXHQgKiBTZXQgdG8gYHRydWVgIHRvIG9wZW4gdGhlIGRpYWxvZyBuZXh0IHRvIHRoZSB0cmlnZ2VyaW5nIGNvbXBvbmVudFxuXHQgKi9cblx0QElucHV0KCkgYXBwZW5kSW5saW5lID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBPcHRpb25hbCBkYXRhIGZvciB0ZW1wbGF0ZXNcblx0ICovXG5cdEBJbnB1dCgpIGRhdGEgPSB7fTtcblxuXHRASW5wdXQoKSBASG9zdEJpbmRpbmcoXCJhdHRyLmFyaWEtZXhwYW5kZWRcIikgaXNPcGVuID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBUaGlzIHByZXZlbnRzIHRoZSBkaWFsb2cgZnJvbSBiZWluZyB0b2dnbGVkXG5cdCAqL1xuXHRASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuXHQvKipcblx0ICogVGhpcyBpbnB1dCBhbGxvd3MgZXhwbGljaXQgY29udHJvbCBvdmVyIGhvdyB0aGUgZGlhbG9nIHNob3VsZCBjbG9zZVxuXHQgKi9cblx0QElucHV0KCkgc2hvdWxkQ2xvc2U6IChtZXRhOiBDbG9zZU1ldGEpID0+IGJvb2xlYW47XG5cdC8qKlxuXHQgKiBDb25maWcgb2JqZWN0IHBhc3NlZCB0byB0aGUgcmVuZGVyZWQgY29tcG9uZW50XG5cdCAqL1xuXHRkaWFsb2dDb25maWc6IERpYWxvZ0NvbmZpZztcblx0LyoqXG5cdCAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIGRpYWxvZyBpcyBjbG9zZWRcblx0ICovXG5cdEBPdXRwdXQoKSBvbkNsb3NlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblx0LyoqXG5cdCAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIGRpYWxvZyBpcyBvcGVuZWRcblx0ICovXG5cdEBPdXRwdXQoKSBvbk9wZW46IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHQvKipcblx0ICogRW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgc3RhdGUgb2YgYGlzT3BlbmAgY2hhbmdlcy4gQWxsb3dzIGBpc09wZW5gIHRvIGJlIGRvdWJsZSBib3VuZFxuXHQgKi9cblx0QE91dHB1dCgpIGlzT3BlbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuXHRASG9zdEJpbmRpbmcoXCJhdHRyLnJvbGVcIikgcm9sZSA9IFwiYnV0dG9uXCI7XG5cdEBIb3N0QmluZGluZyhcImF0dHIuYXJpYS1oYXNwb3B1cFwiKSBoYXNQb3B1cCA9IHRydWU7XG5cdEBIb3N0QmluZGluZyhcImF0dHIuYXJpYS1vd25zXCIpIGdldCBhcmlhT3ducygpOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLmlzT3BlbiA/IHRoaXMuZGlhbG9nQ29uZmlnLmNvbXBJRCA6IG51bGw7XG5cdH1cblxuXHQvKipcblx0ICogS2VlcHMgYSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnRseSBvcGVuZWQgZGlhbG9nXG5cdCAqL1xuXHRwcm90ZWN0ZWQgZGlhbG9nUmVmOiBDb21wb25lbnRSZWY8RGlhbG9nPjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBEaWFsb2dEaXJlY3RpdmUuXG5cdCAqIEBwYXJhbSBlbGVtZW50UmVmXG5cdCAqIEBwYXJhbSB2aWV3Q29udGFpbmVyUmVmXG5cdCAqIEBwYXJhbSBkaWFsb2dTZXJ2aWNlXG5cdCAqIEBwYXJhbSBldmVudFNlcnZpY2Vcblx0ICovXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByb3RlY3RlZCBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuXHRcdHByb3RlY3RlZCB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuXHRcdHByb3RlY3RlZCBkaWFsb2dTZXJ2aWNlOiBEaWFsb2dTZXJ2aWNlLFxuXHRcdHByb3RlY3RlZCBldmVudFNlcnZpY2U6IEV2ZW50U2VydmljZVxuXHQpIHt9XG5cblx0bmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuXHRcdC8vIHNldCB0aGUgY29uZmlnIG9iamVjdCAodGhpcyBjYW4gW2FuZCBzaG91bGQhXSBiZSBhZGRlZCB0byBpbiBjaGlsZCBjbGFzc2VzIGRlcGVuZGluZyBvbiB3aGF0IHRoZXkgbmVlZClcblx0XHR0aGlzLmRpYWxvZ0NvbmZpZyA9IHtcblx0XHRcdHRpdGxlOiB0aGlzLnRpdGxlLFxuXHRcdFx0Y29udGVudDogdGhpcy5jZHNEaWFsb2csXG5cdFx0XHRwbGFjZW1lbnQ6IHRoaXMucGxhY2VtZW50LFxuXHRcdFx0cGFyZW50UmVmOiB0aGlzLmVsZW1lbnRSZWYsXG5cdFx0XHRnYXA6IHRoaXMuZ2FwLFxuXHRcdFx0dHJpZ2dlcjogdGhpcy50cmlnZ2VyLFxuXHRcdFx0Y2xvc2VUcmlnZ2VyOiB0aGlzLmNsb3NlVHJpZ2dlcixcblx0XHRcdHNob3VsZENsb3NlOiB0aGlzLnNob3VsZENsb3NlIHx8ICgoKSA9PiB0cnVlKSxcblx0XHRcdGFwcGVuZElubGluZTogdGhpcy5hcHBlbmRJbmxpbmUsXG5cdFx0XHR3cmFwcGVyQ2xhc3M6IHRoaXMud3JhcHBlckNsYXNzLFxuXHRcdFx0ZGF0YTogdGhpcy5kYXRhLFxuXHRcdFx0b2Zmc2V0OiB0aGlzLm9mZnNldCxcblx0XHRcdGRpc2FibGVkOiB0aGlzLmRpc2FibGVkXG5cdFx0fTtcblxuXHRcdGlmIChjaGFuZ2VzLmlzT3Blbikge1xuXHRcdFx0aWYgKGNoYW5nZXMuaXNPcGVuLmN1cnJlbnRWYWx1ZSkge1xuXHRcdFx0XHR0aGlzLm9wZW4oKTtcblx0XHRcdH0gZWxzZSBpZiAoIWNoYW5nZXMuaXNPcGVuLmZpcnN0Q2hhbmdlKSB7XG5cdFx0XHRcdHRoaXMuY2xvc2Uoe1xuXHRcdFx0XHRcdHJlYXNvbjogQ2xvc2VSZWFzb25zLnByb2dyYW1tYXRpY1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSdW4gYW55IGNvZGUgYSBjaGlsZCBjbGFzcyBtYXkgbmVlZC5cblx0XHR0aGlzLm9uRGlhbG9nQ2hhbmdlcyhjaGFuZ2VzKTtcblx0XHR0aGlzLnVwZGF0ZUNvbmZpZygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGNvbmZpZyBvYmplY3QgYW5kIGJpbmRzIGV2ZW50cyBmb3IgaG92ZXJpbmcgb3IgY2xpY2tpbmcgYmVmb3JlXG5cdCAqIHJ1bm5pbmcgY29kZSBmcm9tIGNoaWxkIGNsYXNzLlxuXHQgKi9cblx0bmdPbkluaXQoKSB7XG5cdFx0Ly8gZml4IGZvciBzYWZhcmkgaGlqYWNraW5nIGNsaWNrc1xuXHRcdHRoaXMuZGlhbG9nU2VydmljZS5zaW5nbGV0b25DbGlja0xpc3RlbigpO1xuXG5cdFx0Y29uc3QgZWxlbWVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuXG5cdFx0dGhpcy5ldmVudFNlcnZpY2Uub24oZWxlbWVudCwgXCJrZXlkb3duXCIsIChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuXHRcdFx0aWYgKGV2ZW50LnRhcmdldCA9PT0gdGhpcy5kaWFsb2dDb25maWcucGFyZW50UmVmLm5hdGl2ZUVsZW1lbnQgJiZcblx0XHRcdFx0KGV2ZW50LmtleSA9PT0gXCJUYWJcIiB8fCBldmVudC5rZXkgPT09IFwiVGFiXCIgJiYgZXZlbnQuc2hpZnRLZXkpIHx8XG5cdFx0XHRcdGV2ZW50LmtleSA9PT0gXCJFc2NhcGVcIikge1xuXHRcdFx0XHR0aGlzLmNsb3NlKHtcblx0XHRcdFx0XHRyZWFzb246IENsb3NlUmVhc29ucy5pbnRlcmFjdGlvbixcblx0XHRcdFx0XHR0YXJnZXQ6IGV2ZW50LnRhcmdldFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIGJpbmQgZXZlbnRzIGZvciBob3ZlcmluZyBvciBjbGlja2luZyB0aGUgaG9zdFxuXHRcdGlmICh0aGlzLnRyaWdnZXIgPT09IFwiaG92ZXJcIiB8fCB0aGlzLnRyaWdnZXIgPT09IFwibW91c2VlbnRlclwiKSB7XG5cdFx0XHR0aGlzLmV2ZW50U2VydmljZS5vbihlbGVtZW50LCBcIm1vdXNlZW50ZXJcIiwgdGhpcy5vcGVuLmJpbmQodGhpcykpO1xuXHRcdFx0dGhpcy5ldmVudFNlcnZpY2Uub24oZWxlbWVudCwgdGhpcy5jbG9zZVRyaWdnZXIsIChldmVudCkgPT4ge1xuXHRcdFx0XHR0aGlzLmNsb3NlKHtcblx0XHRcdFx0XHRyZWFzb246IENsb3NlUmVhc29ucy5pbnRlcmFjdGlvbixcblx0XHRcdFx0XHR0YXJnZXQ6IGV2ZW50LnRhcmdldFxuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5ldmVudFNlcnZpY2Uub24oZWxlbWVudCwgXCJmb2N1c1wiLCB0aGlzLm9wZW4uYmluZCh0aGlzKSk7XG5cdFx0XHR0aGlzLmV2ZW50U2VydmljZS5vbihlbGVtZW50LCBcImJsdXJcIiwgKGV2ZW50KSA9PiB7XG5cdFx0XHRcdHRoaXMuY2xvc2Uoe1xuXHRcdFx0XHRcdHJlYXNvbjogQ2xvc2VSZWFzb25zLmludGVyYWN0aW9uLFxuXHRcdFx0XHRcdHRhcmdldDogZXZlbnQudGFyZ2V0XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZXZlbnRTZXJ2aWNlLm9uKGVsZW1lbnQsIFwiY2xpY2tcIiwgKGV2ZW50KSA9PiB7XG5cdFx0XHRcdHRoaXMudG9nZ2xlKHtcblx0XHRcdFx0XHRyZWFzb246IENsb3NlUmVhc29ucy5pbnRlcmFjdGlvbixcblx0XHRcdFx0XHR0YXJnZXQ6IGV2ZW50LnRhcmdldFxuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5ldmVudFNlcnZpY2Uub24oZWxlbWVudCwgXCJrZXlkb3duXCIsIChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuXHRcdFx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkVudGVyXCIgfHwgZXZlbnQua2V5ID09PSBcIiBcIikge1xuXHRcdFx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5vcGVuKCk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdERpYWxvZ0RpcmVjdGl2ZS5kaWFsb2dDb3VudGVyKys7XG5cdFx0dGhpcy5kaWFsb2dDb25maWcuY29tcElEID0gXCJkaWFsb2ctXCIgKyBEaWFsb2dEaXJlY3RpdmUuZGlhbG9nQ291bnRlcjtcblxuXHRcdC8vIHJ1biBhbnkgY29kZSBhIGNoaWxkIGNsYXNzIG1heSBuZWVkXG5cdFx0dGhpcy5vbkRpYWxvZ0luaXQoKTtcblx0XHR0aGlzLnVwZGF0ZUNvbmZpZygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdoZW4gdGhlIGhvc3QgZGllcywga2lsbCB0aGUgcG9wb3Zlci5cblx0ICogLSBVc2VmdWwgZm9yIHVzZSBpbiBhIG1vZGFsIG9yIHNpbWlsYXIuXG5cdCAqL1xuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLmNsb3NlKHtcblx0XHRcdHJlYXNvbjogQ2xvc2VSZWFzb25zLmRlc3Ryb3llZFxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhlbHBlciBtZXRob2QgdG8gY2FsbCBkaWFsb2dTZXJ2aWNlICdvcGVuJy5cblx0ICogLSBFbmZvcmNlIGFjY2Vzc2liaWxpdHkgYnkgdXBkYXRpbmcgYW4gYXJpYSBhdHRyIGZvciBuYXRpdmVFbGVtZW50LlxuXHQgKi9cblx0b3Blbihjb21wb25lbnQ/KSB7XG5cdFx0Ly8gZG9uJ3QgYWxsb3cgZGlhbG9ncyB0byBiZSBvcGVuZWQgaWYgdGhleSdyZSBhbHJlYWR5IG9wZW5cblx0XHRpZiAodGhpcy5kaWFsb2dSZWYgfHwgdGhpcy5kaXNhYmxlZCkgeyByZXR1cm47IH1cblxuXHRcdC8vIGFjdHVhbGx5IG9wZW4gdGhlIGRpYWxvZywgZW1pdCBldmVudHMsIGFuZCBzZXQgdGhlIG9wZW4gc3RhdGVcblx0XHR0aGlzLmRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKHRoaXMudmlld0NvbnRhaW5lclJlZiwgdGhpcy5kaWFsb2dDb25maWcsIGNvbXBvbmVudCk7XG5cdFx0dGhpcy5pc09wZW4gPSB0cnVlO1xuXHRcdHRoaXMub25PcGVuLmVtaXQoKTtcblx0XHR0aGlzLmlzT3BlbkNoYW5nZS5lbWl0KHRydWUpO1xuXG5cdFx0Ly8gSGFuZGxlcyBlbWl0dGluZyBhbGwgdGhlIGNsb3NlIGV2ZW50cyB0byBjbGVhbiBldmVyeXRoaW5nIHVwXG5cdFx0Ly8gQWxzbyBlbmZvcmNlIGFjY2Vzc2liaWxpdHkgb24gY2xvc2UgYnkgdXBkYXRpbmcgYW4gYXJpYSBhdHRyIG9uIHRoZSBuYXRpdmVFbGVtZW50LlxuXHRcdHRoaXMuZGlhbG9nUmVmLmluc3RhbmNlLmNsb3NlLnN1YnNjcmliZSgobWV0YTogQ2xvc2VNZXRhKSA9PiB7XG5cdFx0XHRpZiAoIXRoaXMuZGlhbG9nUmVmKSB7IHJldHVybjsgfVxuXHRcdFx0aWYgKHRoaXMuZGlhbG9nQ29uZmlnLnNob3VsZENsb3NlICYmIHRoaXMuZGlhbG9nQ29uZmlnLnNob3VsZENsb3NlKG1ldGEpKSB7XG5cdFx0XHRcdC8vIGNsb3NlIHRoZSBkaWFsb2csIGVtaXQgZXZlbnRzLCBhbmQgY2xlYXIgb3V0IHRoZSBvcGVuIHN0YXRlc1xuXHRcdFx0XHR0aGlzLmRpYWxvZ1NlcnZpY2UuY2xvc2UodGhpcy5kaWFsb2dSZWYpO1xuXHRcdFx0XHR0aGlzLmRpYWxvZ1JlZiA9IG51bGw7XG5cdFx0XHRcdHRoaXMuaXNPcGVuID0gZmFsc2U7XG5cdFx0XHRcdHRoaXMub25DbG9zZS5lbWl0KCk7XG5cdFx0XHRcdHRoaXMuaXNPcGVuQ2hhbmdlLmVtaXQoZmFsc2UpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIHRoaXMuZGlhbG9nUmVmO1xuXHR9XG5cblx0LyoqXG5cdCAqIEhlbHBlciBtZXRob2QgdG8gdG9nZ2xlIHRoZSBvcGVuIHN0YXRlIG9mIHRoZSBkaWFsb2dcblx0ICovXG5cdHRvZ2dsZShtZXRhOiBDbG9zZU1ldGEgPSB7IHJlYXNvbjogQ2xvc2VSZWFzb25zLmludGVyYWN0aW9uIH0pIHtcblx0XHRpZiAoIXRoaXMuaXNPcGVuKSB7XG5cdFx0XHR0aGlzLm9wZW4oKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5jbG9zZShtZXRhKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogSGVscGVyIG1ldGhvZCB0byBjbG9zZSB0aGUgZGlhbG9nUmVmLlxuXHQgKi9cblx0Y2xvc2UobWV0YTogQ2xvc2VNZXRhID0geyByZWFzb246IENsb3NlUmVhc29ucy5pbnRlcmFjdGlvbiB9KSB7XG5cdFx0aWYgKHRoaXMuZGlhbG9nUmVmKSB7XG5cdFx0XHR0aGlzLmRpYWxvZ1JlZi5pbnN0YW5jZS5kb0Nsb3NlKG1ldGEpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBFbXB0eSBtZXRob2QgZm9yIGNoaWxkIGNsYXNzZXMgdG8gb3ZlcnJpZGUgYW5kIHNwZWNpZnkgYWRkaXRpb25hbCBpbml0IHN0ZXBzLlxuXHQgKiBSdW4gYWZ0ZXIgRGlhbG9nRGlyZWN0aXZlIGNvbXBsZXRlcyBpdCdzIG5nT25Jbml0LlxuXHQgKi9cblx0cHJvdGVjdGVkIG9uRGlhbG9nSW5pdCgpIHt9XG5cblx0LyoqXG5cdCAqIEVtcHR5IG1ldGhvZCBmb3IgY2hpbGQgdG8gb3ZlcnJpZGUgYW5kIHNwZWNpZnkgYWRkaXRpb25hbCBvbiBjaGFuZ2VzIHN0ZXBzLlxuXHQgKiBydW4gYWZ0ZXIgRGlhbG9nRGlyZWN0aXZlIGNvbXBsZXRlcyBpdCdzIG5nT25DaGFuZ2VzLlxuXHQgKi9cblx0cHJvdGVjdGVkIG9uRGlhbG9nQ2hhbmdlcyhfY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge31cblxuXHRwcm90ZWN0ZWQgdXBkYXRlQ29uZmlnKCkge31cbn1cbiJdfQ==