UNPKG

smart-webcomponents-angular

Version:

[![Price](https://img.shields.io/badge/price-COMMERCIAL-0098f7.svg)](https://jqwidgets.com/license/)

388 lines 71.4 kB
import { Directive, Input, Output, EventEmitter } from '@angular/core'; import { BaseElement, Smart } from './smart.element'; import * as i0 from "@angular/core"; export { Smart } from './smart.element'; export class RibbonComponent extends BaseElement { constructor(ref) { super(ref); this.eventHandlers = []; /** @description This event is triggered whenever the ribbon component transitions from its expanded state to a collapsed state. It allows developers to execute custom logic or UI updates in response to the ribbon becoming minimized or hidden from view. * @param event. The custom event. */ this.onCollapse = new EventEmitter(); /** @description This event is fired when the ribbon begins the process of collapsing, allowing you to execute custom logic before the collapse completes. If you wish to prevent the ribbon from collapsing, you can call event.preventDefault() within your event handler. This will cancel the default collapsing action, keeping the ribbon expanded. * @param event. The custom event. */ this.onCollapsing = new EventEmitter(); /** @description This event is triggered when a user clicks the dialog launcher button, typically represented by a small icon (such as an arrow or ellipsis) in a component's toolbar or header. The event indicates the user's intention to open an extended options dialog or advanced settings panel related to the component. * @param event. The custom event. Custom event was created with: event.detail( groupLabel, groupId) * groupLabel - The label of the dialog launcher's ribbon group. * groupId - The id of the dialog launcher's ribbon group. */ this.onDialogLauncherClick = new EventEmitter(); /** @description This event is triggered whenever the ribbon interface transitions from its collapsed state to an expanded state, indicating that additional options or tools have become visible to the user. Use this event to execute custom logic or UI updates whenever the ribbon expands. * @param event. The custom event. */ this.onExpand = new EventEmitter(); /** @description This event is fired when the ribbon component begins to expand. You can intercept and cancel the expansion by calling event.preventDefault() within your event handler function. This allows you to programmatically control whether or not the ribbon expands based on custom logic. * @param event. The custom event. */ this.onExpanding = new EventEmitter(); /** @description This event is triggered whenever the file menu button is clicked by the user. It is typically used to open, display, or perform actions related to the file menu, such as showing file options or initializing file-related functions. The event provides an opportunity for developers to execute custom logic in response to user interaction with the file menu button. * @param event. The custom event. */ this.onFileButtonClick = new EventEmitter(); /** @description This event is triggered whenever the user opens the file menu, such as by clicking on the "File" option in the application's main menu bar. It allows developers to execute custom logic immediately when the file menu becomes visible to the user. * @param event. The custom event. */ this.onFileMenuOpen = new EventEmitter(); /** @description This event is triggered whenever the file menu is closed, either by user interaction or programmatically. It occurs after all menu actions have completed, signaling that the file menu is no longer visible or active. Developers can use this event to execute cleanup operations, update the user interface, or manage application state in response to the menu being closed. * @param event. The custom event. */ this.onFileMenuClose = new EventEmitter(); /** @description This event is triggered whenever a user clicks on an item within the file menu. It allows you to execute custom actions in response to specific file menu selections, such as opening, saving, or closing a file. The event provides details about the selected menu item, enabling context-aware handling within your application. * @param event. The custom event. Custom event was created with: event.detail( item) * item - The file menu item. */ this.onFileMenuItemClick = new EventEmitter(); /** @description This event is triggered whenever the user selects a different tab, indicating that the active tab within the interface has changed. It allows you to respond to changes in tab selection, such as updating displayed content, fetching new data, or tracking user navigation within tabbed components. * @param event. The custom event. Custom event was created with: event.detail( oldIndex, index) * oldIndex - The previous tab index. * index - The new index of the selected tab. */ this.onSelect = new EventEmitter(); /** @description This event is fired immediately before the active tab changes, allowing you to intercept and potentially prevent the tab switch. To cancel the tab selection change, call event.preventDefault() within your event handler. This provides an opportunity to perform validations or prompt the user before the change is finalized. * @param event. The custom event. Custom event was created with: event.detail( oldIndex, index) * oldIndex - The previous tab index. * index - The new index of the selected tab. */ this.onSelecting = new EventEmitter(); this.nativeElement = ref.nativeElement; } /** @description Creates the component on demand. * @param properties An optional object of properties, which will be added to the template binded ones. */ createComponent(properties = {}) { this.nativeElement = document.createElement('smart-ribbon'); for (let propertyName in properties) { this.nativeElement[propertyName] = properties[propertyName]; } return this.nativeElement; } /** @description Specifies whether the ribbon interface can be collapsed or expanded by the user, allowing for a more compact or fully visible display as needed. */ get collapsible() { return this.nativeElement ? this.nativeElement.collapsible : undefined; } set collapsible(value) { this.nativeElement ? this.nativeElement.collapsible = value : undefined; } /** @description Specifies the individual tab items to be displayed within the ribbon interface. Each tab item typically represents a distinct category or section, allowing users to easily navigate and access grouped commands or features within the ribbon. */ get dataSource() { return this.nativeElement ? this.nativeElement.dataSource : undefined; } set dataSource(value) { this.nativeElement ? this.nativeElement.dataSource = value : undefined; } /** @description Specifies or retrieves whether the element is disabled, preventing user interaction and making it unresponsive to mouse and keyboard events. When set to true, the element cannot be activated or receive input focus. */ get disabled() { return this.nativeElement ? this.nativeElement.disabled : undefined; } set disabled(value) { this.nativeElement ? this.nativeElement.disabled = value : undefined; } /** @description Specifies the available file menu options displayed within the ribbon interface, defining which actions (such as New, Open, Save, Print, etc.) users can access from the file menu. */ get fileMenu() { return this.nativeElement ? this.nativeElement.fileMenu : undefined; } set fileMenu(value) { this.nativeElement ? this.nativeElement.fileMenu = value : undefined; } /** @description Sets or retrieves the value of the unlockKey property, which is used to authenticate and authorize access to unlock the product. The unlockKey typically functions as a secure code or token required to enable full product functionality. */ get unlockKey() { return this.nativeElement ? this.nativeElement.unlockKey : undefined; } set unlockKey(value) { this.nativeElement ? this.nativeElement.unlockKey = value : undefined; } /** @description Specifies the localization settings for the ribbon, determining the language and regional formatting (such as date, time, and number formats) used for displaying text and other interface elements. */ get locale() { return this.nativeElement ? this.nativeElement.locale : undefined; } set locale(value) { this.nativeElement ? this.nativeElement.locale = value : undefined; } /** @description Specifies the text and content displayed in the ribbon's message area, allowing customization of informational or notification messages shown to users within the ribbon interface. */ get messages() { return this.nativeElement ? this.nativeElement.messages : undefined; } set messages(value) { this.nativeElement ? this.nativeElement.messages = value : undefined; } /** @description Specifies or retrieves a value that determines whether the element’s alignment is optimized for right-to-left (RTL) languages, such as Arabic or Hebrew. This affects the element’s text direction, layout flow, and alignment to accommodate locales that use right-to-left scripts. */ get rightToLeft() { return this.nativeElement ? this.nativeElement.rightToLeft : undefined; } set rightToLeft(value) { this.nativeElement ? this.nativeElement.rightToLeft = value : undefined; } /** @description Specifies which tab is currently selected and active in the tab navigation component, typically by its index or identifier. This property controls which tab's content is visible to the user. */ get selectedTab() { return this.nativeElement ? this.nativeElement.selectedTab : undefined; } set selectedTab(value) { this.nativeElement ? this.nativeElement.selectedTab = value : undefined; } /** @description Adds a new tab to the application's ribbon interface. The tab can be specified in one of three ways: as a configuration object defining the tab's properties, as an existing HTMLElement to be used as the tab, or as a string representing the id of an existing HTMLElement to be added as the tab. This provides flexibility in how ribbon tabs are created and integrated. * @param {any} tab. The ribbon tab to be added. */ addTab(tab) { if (this.nativeElement.isRendered) { this.nativeElement.addTab(tab); } else { this.nativeElement.whenRendered(() => { this.nativeElement.addTab(tab); }); } } /** @description Enhances a ribbon tab by adding a new group. The group can be specified in one of the following ways: as an object defining its properties, as a direct reference to an HTMLElement, or as a string representing the id of an existing HTMLElement. This flexibility allows you to create the group dynamically, use an already created DOM element, or reference an element by its id. * @param {any} tab. The id, index or HTMLElement of the parent ribbon tab. * @param {any} group. The ribbon group to be added. */ addGroup(tab, group) { if (this.nativeElement.isRendered) { this.nativeElement.addGroup(tab, group); } else { this.nativeElement.whenRendered(() => { this.nativeElement.addGroup(tab, group); }); } } /** @description Adds a new item to a specified ribbon group in the ribbon interface. The new item can be provided in one of the following forms: as a configuration object, as an actual HTMLElement, or by specifying the id of an existing HTMLElement. This offers flexibility in how ribbon items are defined and incorporated into the ribbon group. * @param {string | number | HTMLElement} tab. The id, index or HTMLElement of the parent ribbon tab. * @param {string | HTMLElement} group. The id or HTMLElement of the parent ribbon group. * @param {any} item. The ribbon item to be added. */ addItem(tab, group, item) { if (this.nativeElement.isRendered) { this.nativeElement.addItem(tab, group, item); } else { this.nativeElement.whenRendered(() => { this.nativeElement.addItem(tab, group, item); }); } } /** @description Minimizes the ribbon interface, hiding its commands and options, to provide more workspace on the screen. */ collapse() { if (this.nativeElement.isRendered) { this.nativeElement.collapse(); } else { this.nativeElement.whenRendered(() => { this.nativeElement.collapse(); }); } } /** @description Expands the ribbon interface to reveal additional tools, features, and options that are otherwise hidden from view. This action increases the available workspace by displaying the full set of ribbon commands and controls. */ expand() { if (this.nativeElement.isRendered) { this.nativeElement.expand(); } else { this.nativeElement.whenRendered(() => { this.nativeElement.expand(); }); } } /** @description Removes a specified tab from the ribbon interface, effectively hiding it and its associated commands from the user’s view. This action ensures that the tab and its contents are no longer accessible within the ribbon navigation. * @param {string | number} ribbonTab. The id or index of the ribbon tab to be removed. */ removeTab(ribbonTab) { if (this.nativeElement.isRendered) { this.nativeElement.removeTab(ribbonTab); } else { this.nativeElement.whenRendered(() => { this.nativeElement.removeTab(ribbonTab); }); } } /** @description Removes a specified ribbon group from the selected ribbon tab, effectively deleting that group's controls and functionalities from the tab's interface. * @param {string | number} ribbonTabIndex?. The id or index of the parent ribbon tab. * @param {string | number} ribbonGroup?. The id or index of the ribbon group to be removed. */ removeGroup(ribbonTabIndex, ribbonGroup) { if (this.nativeElement.isRendered) { this.nativeElement.removeGroup(ribbonTabIndex, ribbonGroup); } else { this.nativeElement.whenRendered(() => { this.nativeElement.removeGroup(ribbonTabIndex, ribbonGroup); }); } } /** @description Removes a specified ribbon item from its parent ribbon group, effectively deleting the item from the group and updating the user interface accordingly. This operation ensures that the ribbon group no longer displays or interacts with the removed item. * @param {string | number} ribbonTabIndex?. The id or index of the parent ribbon tab. * @param {string | number} ribbonGroup?. The id or index of the parent ribbon group. * @param {string | number} ribbonItem?. The id or index of the ribbon item to be removed. */ removeItem(ribbonTabIndex, ribbonGroup, ribbonItem) { if (this.nativeElement.isRendered) { this.nativeElement.removeItem(ribbonTabIndex, ribbonGroup, ribbonItem); } else { this.nativeElement.whenRendered(() => { this.nativeElement.removeItem(ribbonTabIndex, ribbonGroup, ribbonItem); }); } } /** @description Activates the specified ribbon tab, bringing its contents into focus and making its associated controls and options accessible to the user. * @param {string | number} ribbonTabIndex. The index of the ribbon tab to be selected. */ selectTab(ribbonTabIndex) { if (this.nativeElement.isRendered) { this.nativeElement.selectTab(ribbonTabIndex); } else { this.nativeElement.whenRendered(() => { this.nativeElement.selectTab(ribbonTabIndex); }); } } get isRendered() { return this.nativeElement ? this.nativeElement.isRendered : false; } ngOnInit() { } ngAfterViewInit() { const that = this; that.onCreate.emit(that.nativeElement); if (Smart) Smart.Render(); this.nativeElement.classList.add('smart-angular'); if (this.nativeElement.whenRendered) this.nativeElement.whenRendered(() => { that.onReady.emit(that.nativeElement); }); this.listen(); } ngOnDestroy() { this.unlisten(); } ngOnChanges(changes) { if (this.nativeElement && this.nativeElement.isRendered) { for (const propName in changes) { if (changes.hasOwnProperty(propName)) { this.nativeElement[propName] = changes[propName].currentValue; } } } } /** @description Add event listeners. */ listen() { const that = this; that.eventHandlers['collapseHandler'] = (event) => { that.onCollapse.emit(event); }; that.nativeElement.addEventListener('collapse', that.eventHandlers['collapseHandler']); that.eventHandlers['collapsingHandler'] = (event) => { that.onCollapsing.emit(event); }; that.nativeElement.addEventListener('collapsing', that.eventHandlers['collapsingHandler']); that.eventHandlers['dialogLauncherClickHandler'] = (event) => { that.onDialogLauncherClick.emit(event); }; that.nativeElement.addEventListener('dialogLauncherClick', that.eventHandlers['dialogLauncherClickHandler']); that.eventHandlers['expandHandler'] = (event) => { that.onExpand.emit(event); }; that.nativeElement.addEventListener('expand', that.eventHandlers['expandHandler']); that.eventHandlers['expandingHandler'] = (event) => { that.onExpanding.emit(event); }; that.nativeElement.addEventListener('expanding', that.eventHandlers['expandingHandler']); that.eventHandlers['fileButtonClickHandler'] = (event) => { that.onFileButtonClick.emit(event); }; that.nativeElement.addEventListener('fileButtonClick', that.eventHandlers['fileButtonClickHandler']); that.eventHandlers['fileMenuOpenHandler'] = (event) => { that.onFileMenuOpen.emit(event); }; that.nativeElement.addEventListener('fileMenuOpen', that.eventHandlers['fileMenuOpenHandler']); that.eventHandlers['fileMenuCloseHandler'] = (event) => { that.onFileMenuClose.emit(event); }; that.nativeElement.addEventListener('fileMenuClose', that.eventHandlers['fileMenuCloseHandler']); that.eventHandlers['fileMenuItemClickHandler'] = (event) => { that.onFileMenuItemClick.emit(event); }; that.nativeElement.addEventListener('fileMenuItemClick', that.eventHandlers['fileMenuItemClickHandler']); that.eventHandlers['selectHandler'] = (event) => { that.onSelect.emit(event); }; that.nativeElement.addEventListener('select', that.eventHandlers['selectHandler']); that.eventHandlers['selectingHandler'] = (event) => { that.onSelecting.emit(event); }; that.nativeElement.addEventListener('selecting', that.eventHandlers['selectingHandler']); } /** @description Remove event listeners. */ unlisten() { const that = this; if (that.eventHandlers['collapseHandler']) { that.nativeElement.removeEventListener('collapse', that.eventHandlers['collapseHandler']); } if (that.eventHandlers['collapsingHandler']) { that.nativeElement.removeEventListener('collapsing', that.eventHandlers['collapsingHandler']); } if (that.eventHandlers['dialogLauncherClickHandler']) { that.nativeElement.removeEventListener('dialogLauncherClick', that.eventHandlers['dialogLauncherClickHandler']); } if (that.eventHandlers['expandHandler']) { that.nativeElement.removeEventListener('expand', that.eventHandlers['expandHandler']); } if (that.eventHandlers['expandingHandler']) { that.nativeElement.removeEventListener('expanding', that.eventHandlers['expandingHandler']); } if (that.eventHandlers['fileButtonClickHandler']) { that.nativeElement.removeEventListener('fileButtonClick', that.eventHandlers['fileButtonClickHandler']); } if (that.eventHandlers['fileMenuOpenHandler']) { that.nativeElement.removeEventListener('fileMenuOpen', that.eventHandlers['fileMenuOpenHandler']); } if (that.eventHandlers['fileMenuCloseHandler']) { that.nativeElement.removeEventListener('fileMenuClose', that.eventHandlers['fileMenuCloseHandler']); } if (that.eventHandlers['fileMenuItemClickHandler']) { that.nativeElement.removeEventListener('fileMenuItemClick', that.eventHandlers['fileMenuItemClickHandler']); } if (that.eventHandlers['selectHandler']) { that.nativeElement.removeEventListener('select', that.eventHandlers['selectHandler']); } if (that.eventHandlers['selectingHandler']) { that.nativeElement.removeEventListener('selecting', that.eventHandlers['selectingHandler']); } } } RibbonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: RibbonComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); RibbonComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.6", type: RibbonComponent, selector: "smart-ribbon, [smart-ribbon]", inputs: { collapsible: "collapsible", dataSource: "dataSource", disabled: "disabled", fileMenu: "fileMenu", unlockKey: "unlockKey", locale: "locale", messages: "messages", rightToLeft: "rightToLeft", selectedTab: "selectedTab" }, outputs: { onCollapse: "onCollapse", onCollapsing: "onCollapsing", onDialogLauncherClick: "onDialogLauncherClick", onExpand: "onExpand", onExpanding: "onExpanding", onFileButtonClick: "onFileButtonClick", onFileMenuOpen: "onFileMenuOpen", onFileMenuClose: "onFileMenuClose", onFileMenuItemClick: "onFileMenuItemClick", onSelect: "onSelect", onSelecting: "onSelecting" }, exportAs: ["smart-ribbon"], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.6", ngImport: i0, type: RibbonComponent, decorators: [{ type: Directive, args: [{ exportAs: 'smart-ribbon', selector: 'smart-ribbon, [smart-ribbon]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { collapsible: [{ type: Input }], dataSource: [{ type: Input }], disabled: [{ type: Input }], fileMenu: [{ type: Input }], unlockKey: [{ type: Input }], locale: [{ type: Input }], messages: [{ type: Input }], rightToLeft: [{ type: Input }], selectedTab: [{ type: Input }], onCollapse: [{ type: Output }], onCollapsing: [{ type: Output }], onDialogLauncherClick: [{ type: Output }], onExpand: [{ type: Output }], onExpanding: [{ type: Output }], onFileButtonClick: [{ type: Output }], onFileMenuOpen: [{ type: Output }], onFileMenuClose: [{ type: Output }], onFileMenuItemClick: [{ type: Output }], onSelect: [{ type: Output }], onSelecting: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnQucmliYm9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcmliYm9uL3NyYy9zbWFydC5yaWJib24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFhLFNBQVMsRUFBNkIsS0FBSyxFQUErQyxNQUFNLEVBQUUsWUFBWSxFQUE4QixNQUFNLGVBQWUsQ0FBQztBQUN0TCxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDOztBQUVyRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFjeEMsTUFBTSxPQUFPLGVBQWdCLFNBQVEsV0FBVztJQUUvQyxZQUFZLEdBQXVCO1FBQ2xDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUlKLGtCQUFhLEdBQVUsRUFBRSxDQUFDO1FBOEZsQzs4Q0FDc0M7UUFDNUIsZUFBVSxHQUE4QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBRXJFOzhDQUNzQztRQUM1QixpQkFBWSxHQUE4QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBRXZFOzs7O1VBSUU7UUFDUSwwQkFBcUIsR0FBOEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUVoRjs4Q0FDc0M7UUFDNUIsYUFBUSxHQUE4QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBRW5FOzhDQUNzQztRQUM1QixnQkFBVyxHQUE4QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBRXRFOzhDQUNzQztRQUM1QixzQkFBaUIsR0FBOEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUU1RTs4Q0FDc0M7UUFDNUIsbUJBQWMsR0FBOEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUV6RTs4Q0FDc0M7UUFDNUIsb0JBQWUsR0FBOEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUUxRTs7O1VBR0U7UUFDUSx3QkFBbUIsR0FBOEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUU5RTs7OztVQUlFO1FBQ1EsYUFBUSxHQUE4QixJQUFJLFlB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c291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUmliYm9uIH0gZnJvbSAnLi8uLi9pbmRleCc7XG5pbXBvcnQgeyBSaWJib25GaWxlTWVudVBvc2l0aW9uLCBSaWJib25GaWxlTWVudVR5cGUsIFJpYmJvbkZpbGVNZW51LCBFbGVtZW50UmVuZGVyTW9kZX0gZnJvbSAnLi8uLi9pbmRleCc7XG5pbXBvcnQgeyBDb21wb25lbnQsIERpcmVjdGl2ZSwgQWZ0ZXJWaWV3SW5pdCwgRWxlbWVudFJlZiwgSW5wdXQsIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIFNpbXBsZUNoYW5nZXMsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBRdWVyeUxpc3QsIENvbnRlbnRDaGlsZHJlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmFzZUVsZW1lbnQsIFNtYXJ0IH0gZnJvbSAnLi9zbWFydC5lbGVtZW50JztcbmV4cG9ydCB7IFJpYmJvbkZpbGVNZW51UG9zaXRpb24sIFJpYmJvbkZpbGVNZW51VHlwZSwgUmliYm9uRmlsZU1lbnUsIEVsZW1lbnRSZW5kZXJNb2RlfSBmcm9tICcuLy4uL2luZGV4JztcbmV4cG9ydCB7IFNtYXJ0IH0gZnJvbSAnLi9zbWFydC5lbGVtZW50JztcbmV4cG9ydCB7IFJpYmJvbiB9IGZyb20gJy4vLi4vaW5kZXgnO1xuXG5cbmltcG9ydCB7IFJpYmJvblRhYkNvbXBvbmVudCB9IGZyb20gJy4vc21hcnQucmliYm9udGFiJztcblxuaW1wb3J0IHsgUmliYm9uR3JvdXBDb21wb25lbnQgfSBmcm9tICcuL3NtYXJ0LnJpYmJvbmdyb3VwJztcblxuaW1wb3J0IHsgUmliYm9uSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vc21hcnQucmliYm9uaXRlbSc7XG5cbkBEaXJlY3RpdmUoe1xuXHRleHBvcnRBczogJ3NtYXJ0LXJpYmJvbicsXHRzZWxlY3RvcjogJ3NtYXJ0LXJpYmJvbiwgW3NtYXJ0LXJpYmJvbl0nXG59KVxuXG5leHBvcnQgY2xhc3MgUmliYm9uQ29tcG9uZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcblxuXHRjb25zdHJ1Y3RvcihyZWY6IEVsZW1lbnRSZWY8UmliYm9uPikge1xuXHRcdHN1cGVyKHJlZik7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID0gcmVmLm5hdGl2ZUVsZW1lbnQgYXMgUmliYm9uO1xuXHR9XG5cblx0cHJpdmF0ZSBldmVudEhhbmRsZXJzOiBhbnlbXSA9IFtdO1xuXG5cdHB1YmxpYyBkZWNsYXJlIG5hdGl2ZUVsZW1lbnQ6IFJpYmJvbjtcblx0LyoqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIHRoZSBjb21wb25lbnQgb24gZGVtYW5kLlxuXHQgKiBAcGFyYW0gcHJvcGVydGllcyBBbiBvcHRpb25hbCBvYmplY3Qgb2YgcHJvcGVydGllcywgd2hpY2ggd2lsbCBiZSBhZGRlZCB0byB0aGUgdGVtcGxhdGUgYmluZGVkIG9uZXMuXG5cdCAqL1xuXHRwdWJsaWMgY3JlYXRlQ29tcG9uZW50KHByb3BlcnRpZXMgPSB7fSk6IGFueSB7XG4gICAgXHR0aGlzLm5hdGl2ZUVsZW1lbnQgPSA8UmliYm9uPmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NtYXJ0LXJpYmJvbicpO1xuXHRcdGZvciAobGV0IHByb3BlcnR5TmFtZSBpbiBwcm9wZXJ0aWVzKSB7IFxuIFx0XHRcdHRoaXMubmF0aXZlRWxlbWVudFtwcm9wZXJ0eU5hbWVdID0gcHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50O1xuXHR9XG5cdC8qKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHdoZXRoZXIgdGhlIHJpYmJvbiBpbnRlcmZhY2UgY2FuIGJlIGNvbGxhcHNlZCBvciBleHBhbmRlZCBieSB0aGUgdXNlciwgYWxsb3dpbmcgZm9yIGEgbW9yZSBjb21wYWN0IG9yIGZ1bGx5IHZpc2libGUgZGlzcGxheSBhcyBuZWVkZWQuICovXG5cdEBJbnB1dCgpXG5cdGdldCBjb2xsYXBzaWJsZSgpOiBhbnkge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuY29sbGFwc2libGUgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGNvbGxhcHNpYmxlKHZhbHVlOiBhbnkpIHtcblx0XHR0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuY29sbGFwc2libGUgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHRoZSBpbmRpdmlkdWFsIHRhYiBpdGVtcyB0byBiZSBkaXNwbGF5ZWQgd2l0aGluIHRoZSByaWJib24gaW50ZXJmYWNlLiBFYWNoIHRhYiBpdGVtIHR5cGljYWxseSByZXByZXNlbnRzIGEgZGlzdGluY3QgY2F0ZWdvcnkgb3Igc2VjdGlvbiwgYWxsb3dpbmcgdXNlcnMgdG8gZWFzaWx5IG5hdmlnYXRlIGFuZCBhY2Nlc3MgZ3JvdXBlZCBjb21tYW5kcyBvciBmZWF0dXJlcyB3aXRoaW4gdGhlIHJpYmJvbi4gKi9cblx0QElucHV0KClcblx0Z2V0IGRhdGFTb3VyY2UoKTogYW55IHtcblx0XHRyZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmRhdGFTb3VyY2UgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGRhdGFTb3VyY2UodmFsdWU6IGFueSkge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5kYXRhU291cmNlID0gdmFsdWUgOiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKiogQGRlc2NyaXB0aW9uIFNwZWNpZmllcyBvciByZXRyaWV2ZXMgd2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCwgcHJldmVudGluZyB1c2VyIGludGVyYWN0aW9uIGFuZCBtYWtpbmcgaXQgdW5yZXNwb25zaXZlIHRvIG1vdXNlIGFuZCBrZXlib2FyZCBldmVudHMuIFdoZW4gc2V0IHRvIHRydWUsIHRoZSBlbGVtZW50IGNhbm5vdCBiZSBhY3RpdmF0ZWQgb3IgcmVjZWl2ZSBpbnB1dCBmb2N1cy4gKi9cblx0QElucHV0KClcblx0Z2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmRpc2FibGVkID0gdmFsdWUgOiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKiogQGRlc2NyaXB0aW9uIFNwZWNpZmllcyB0aGUgYXZhaWxhYmxlIGZpbGUgbWVudSBvcHRpb25zIGRpc3BsYXllZCB3aXRoaW4gdGhlIHJpYmJvbiBpbnRlcmZhY2UsIGRlZmluaW5nIHdoaWNoIGFjdGlvbnMgKHN1Y2ggYXMgTmV3LCBPcGVuLCBTYXZlLCBQcmludCwgZXRjLikgdXNlcnMgY2FuIGFjY2VzcyBmcm9tIHRoZSBmaWxlIG1lbnUuICovXG5cdEBJbnB1dCgpXG5cdGdldCBmaWxlTWVudSgpOiBSaWJib25GaWxlTWVudSB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5maWxlTWVudSA6IHVuZGVmaW5lZDtcblx0fVxuXHRzZXQgZmlsZU1lbnUodmFsdWU6IFJpYmJvbkZpbGVNZW51KSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmZpbGVNZW51ID0gdmFsdWUgOiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKiogQGRlc2NyaXB0aW9uIFNldHMgb3IgcmV0cmlldmVzIHRoZSB2YWx1ZSBvZiB0aGUgdW5sb2NrS2V5IHByb3BlcnR5LCB3aGljaCBpcyB1c2VkIHRvIGF1dGhlbnRpY2F0ZSBhbmQgYXV0aG9yaXplIGFjY2VzcyB0byB1bmxvY2sgdGhlIHByb2R1Y3QuIFRoZSB1bmxvY2tLZXkgdHlwaWNhbGx5IGZ1bmN0aW9ucyBhcyBhIHNlY3VyZSBjb2RlIG9yIHRva2VuIHJlcXVpcmVkIHRvIGVuYWJsZSBmdWxsIHByb2R1Y3QgZnVuY3Rpb25hbGl0eS4gKi9cblx0QElucHV0KClcblx0Z2V0IHVubG9ja0tleSgpOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQudW5sb2NrS2V5IDogdW5kZWZpbmVkO1xuXHR9XG5cdHNldCB1bmxvY2tLZXkodmFsdWU6IHN0cmluZykge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC51bmxvY2tLZXkgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gU3BlY2lmaWVzIHRoZSBsb2NhbGl6YXRpb24gc2V0dGluZ3MgZm9yIHRoZSByaWJib24sIGRldGVybWluaW5nIHRoZSBsYW5ndWFnZSBhbmQgcmVnaW9uYWwgZm9ybWF0dGluZyAoc3VjaCBhcyBkYXRlLCB0aW1lLCBhbmQgbnVtYmVyIGZvcm1hdHMpIHVzZWQgZm9yIGRpc3BsYXlpbmcgdGV4dCBhbmQgb3RoZXIgaW50ZXJmYWNlIGVsZW1lbnRzLiAqL1xuXHRASW5wdXQoKVxuXHRnZXQgbG9jYWxlKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5sb2NhbGUgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IGxvY2FsZSh2YWx1ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LmxvY2FsZSA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgdGhlIHRleHQgYW5kIGNvbnRlbnQgZGlzcGxheWVkIGluIHRoZSByaWJib24ncyBtZXNzYWdlIGFyZWEsIGFsbG93aW5nIGN1c3RvbWl6YXRpb24gb2YgaW5mb3JtYXRpb25hbCBvciBub3RpZmljYXRpb24gbWVzc2FnZXMgc2hvd24gdG8gdXNlcnMgd2l0aGluIHRoZSByaWJib24gaW50ZXJmYWNlLiAqL1xuXHRASW5wdXQoKVxuXHRnZXQgbWVzc2FnZXMoKTogYW55IHtcblx0XHRyZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50Lm1lc3NhZ2VzIDogdW5kZWZpbmVkO1xuXHR9XG5cdHNldCBtZXNzYWdlcyh2YWx1ZTogYW55KSB7XG5cdFx0dGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50Lm1lc3NhZ2VzID0gdmFsdWUgOiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKiogQGRlc2NyaXB0aW9uIFNwZWNpZmllcyBvciByZXRyaWV2ZXMgYSB2YWx1ZSB0aGF0IGRldGVybWluZXMgd2hldGhlciB0aGUgZWxlbWVudOKAmXMgYWxpZ25tZW50IGlzIG9wdGltaXplZCBmb3IgcmlnaHQtdG8tbGVmdCAoUlRMKSBsYW5ndWFnZXMsIHN1Y2ggYXMgQXJhYmljIG9yIEhlYnJldy4gVGhpcyBhZmZlY3RzIHRoZSBlbGVtZW504oCZcyB0ZXh0IGRpcmVjdGlvbiwgbGF5b3V0IGZsb3csIGFuZCBhbGlnbm1lbnQgdG8gYWNjb21tb2RhdGUgbG9jYWxlcyB0aGF0IHVzZSByaWdodC10by1sZWZ0IHNjcmlwdHMuICovXG5cdEBJbnB1dCgpXG5cdGdldCByaWdodFRvTGVmdCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5uYXRpdmVFbGVtZW50ID8gdGhpcy5uYXRpdmVFbGVtZW50LnJpZ2h0VG9MZWZ0IDogdW5kZWZpbmVkO1xuXHR9XG5cdHNldCByaWdodFRvTGVmdCh2YWx1ZTogYm9vbGVhbikge1xuXHRcdHRoaXMubmF0aXZlRWxlbWVudCA/IHRoaXMubmF0aXZlRWxlbWVudC5yaWdodFRvTGVmdCA9IHZhbHVlIDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqIEBkZXNjcmlwdGlvbiBTcGVjaWZpZXMgd2hpY2ggdGFiIGlzIGN1cnJlbnRseSBzZWxlY3RlZCBhbmQgYWN0aXZlIGluIHRoZSB0YWIgbmF2aWdhdGlvbiBjb21wb25lbnQsIHR5cGljYWxseSBieSBpdHMgaW5kZXggb3IgaWRlbnRpZmllci4gVGhpcyBwcm9wZXJ0eSBjb250cm9scyB3aGljaCB0YWIncyBjb250ZW50IGlzIHZpc2libGUgdG8gdGhlIHVzZXIuICovXG5cdEBJbnB1dCgpXG5cdGdldCBzZWxlY3RlZFRhYigpOiBhbnkge1xuXHRcdHJldHVybiB0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuc2VsZWN0ZWRUYWIgOiB1bmRlZmluZWQ7XG5cdH1cblx0c2V0IHNlbGVjdGVkVGFiKHZhbHVlOiBhbnkpIHtcblx0XHR0aGlzLm5hdGl2ZUVsZW1lbnQgPyB0aGlzLm5hdGl2ZUVsZW1lbnQuc2VsZWN0ZWRUYWIgPSB2YWx1ZSA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKiBAZGVzY3JpcHRpb24gVGhpcyBldmVudCBpcyB0cmlnZ2VyZWQgd2hlbmV2ZXIgdGhlIHJpYmJvbiBjb21wb25lbnQgdHJhbnNpdGlvbnMgZnJvbSBpdHMgZXhwYW5kZWQgc3RhdGUgdG8gYSBjb2xsYXBzZWQgc3RhdGUuIEl0IGFsbG93cyBkZXZlbG9wZXJzIHRvIGV4ZWN1dGUgY3VzdG9tIGxvZ2ljIG9yIFVJIHVwZGF0ZXMgaW4gcmVzcG9uc2UgdG8gdGhlIHJpYmJvbiBiZWNvbWluZyBtaW5pbWl6ZWQgb3IgaGlkZGVuIGZyb20gdmlldy5cblx0KiAgQHBhcmFtIGV2ZW50LiBUaGUgY3VzdG9tIGV2ZW50LiBcdCovXG5cdEBPdXRwdXQoKSBvbkNvbGxhcHNlOiBFdmVudEVtaXR0ZXI8Q3VzdG9tRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdC8qKiBAZGVzY3JpcHRpb24gVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIHRoZSByaWJib24gYmVnaW5zIHRoZSBwcm9jZXNzIG9mIGNvbGxhcHNpbmcsIGFsbG93aW5nIHlvdSB0byBleGVjdXRlIGN1c3RvbSBsb2dpYyBiZWZvcmUgdGhlIGNvbGxhcHNlIGNvbXBsZXRlcy4gSWYgeW91IHdpc2ggdG8gcHJldmVudCB0aGUgcmliYm9uIGZyb20gY29sbGFwc2luZywgeW91IGNhbiBjYWxsIGV2ZW50LnByZXZlbnREZWZhdWx0KCkgd2l0aGluIHlvdXIgZXZlbnQgaGFuZGxlci4gVGhpcyB3aWxsIGNhbmNlbCB0aGUgZGVmYXVsdCBjb2xsYXBzaW5nIGFjdGlvbiwga2VlcGluZyB0aGUgcmliYm9uIGV4cGFuZGVkLlxuXHQqICBAcGFyYW0gZXZlbnQuIFRoZSBjdXN0b20gZXZlbnQuIFx0Ki9cblx0QE91dHB1dCgpIG9uQ29sbGFwc2luZzogRXZlbnRFbWl0dGVyPEN1c3RvbUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXHQvKiogQGRlc2NyaXB0aW9uIFRoaXMgZXZlbnQgaXMgdHJpZ2dlcmVkIHdoZW4gYSB1c2VyIGNsaWNrcyB0aGUgZGlhbG9nIGxhdW5jaGVyIGJ1dHRvbiwgdHlwaWNhbGx5IHJlcHJlc2VudGVkIGJ5IGEgc21hbGwgaWNvbiAoc3VjaCBhcyBhbiBhcnJvdyBvciBlbGxpcHNpcykgaW4gYSBjb21wb25lbnQncyB0b29sYmFyIG9yIGhlYWRlci4gVGhlIGV2ZW50IGluZGljYXRlcyB0aGUgdXNlcidzIGludGVudGlvbiB0byBvcGVuIGFuIGV4dGVuZGVkIG9wdGlvbnMgZGlhbG9nIG9yIGFkdmFuY2VkIHNldHRpbmdzIHBhbmVsIHJlbGF0ZWQgdG8gdGhlIGNvbXBvbmVudC5cblx0KiAgQHBhcmFtIGV2ZW50LiBUaGUgY3VzdG9tIGV2ZW50LiBcdEN1c3RvbSBldmVudCB3YXMgY3JlYXRlZCB3aXRoOiBldmVudC5kZXRhaWwoXHRncm91cExhYmVsLCBcdGdyb3VwSWQpXG5cdCogICBncm91cExhYmVsIC0gVGhlIGxhYmVsIG9mIHRoZSBkaWFsb2cgbGF1bmNoZXIncyByaWJib24gZ3JvdXAuXG5cdCogICBncm91cElkIC0gVGhlIGlkIG9mIHRoZSBkaWFsb2cgbGF1bmNoZXIncyByaWJ