carbon-components-angular
Version:
Next generation components
316 lines • 34.4 kB
JavaScript
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=