gentics-ui-core
Version:
This is the common core framework for the Gentics CMS and Mesh UI, and other Angular applications.
259 lines • 30.1 kB
JavaScript
import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, HostListener, Input, Output, TemplateRef, ViewChild } from '@angular/core';
import { take } from 'rxjs/operators';
import { coerceToBoolean } from '../../common/coerce-to-boolean';
import { KeyCode } from '../../common/keycodes';
import { OverlayHostService } from '../overlay-host/overlay-host.service';
import { DropdownContentWrapper } from './dropdown-content-wrapper.component';
import { DropdownContent } from './dropdown-content.component';
import { DropdownTriggerDirective } from './dropdown-trigger.directive';
import { ScrollMask } from './scroll-mask.component';
import * as i0 from "@angular/core";
import * as i1 from "../overlay-host/overlay-host.service";
/**
* A Dropdown component. Depends on the [`<gtx-overlay-host>`](#/overlay-host) being present in the app.
*
* The component expects two child elements:
*
* * `<gtx-dropdown-trigger>` - this element is the button/label which the user will click to open the dropdown.
* * `<gtx-dropdown-content>` - contains the contents of the dropdown. If it contains a `<ul>`, specific styles will be applied
*
* The `<gtx-dropdown-content>` element may contain arbitrary content, but list items should be wrapped in `<gtx-dropdown-item>`.
* This will allow keyboard support for list navigation.
*
*
* ```html
* <gtx-dropdown-list>
* <gtx-dropdown-trigger>
* <a>Show List</a>
* </gtx-dropdown-trigger>
* <gtx-dropdown-content>
* <gtx-dropdown-item>First</gtx-dropdown-item>
* <gtx-dropdown-item>Second</gtx-dropdown-item>
* <gtx-dropdown-item>Third</gtx-dropdown-item>
* </gtx-dropdown-content>
* </gtx-dropdown-list>
* ```
*
* ## Programmatic Use
* When used programmatically (e.g. by getting a reference to the component via `@ContentChild(DropdownList)`, the
* following extended API is available:
*
* - `dropdownList.isOpen: boolean`
* - `dropdownList.openDropdown(): void`
* - `dropdownList.closeDropdown(): void`
* - `dropdownList.resize(): void`
*/
export class DropdownList {
constructor(overlayHostService) {
this.options = {
alignment: 'left',
width: 'contents',
belowTrigger: false,
sticky: false,
closeOnEscape: true
};
/**
* Fired whenever the dropdown contents are opened.
*/
this.open = new EventEmitter();
/**
* Fired whenever the dropdown contents are closed.
*/
this.close = new EventEmitter();
this._disabled = false;
overlayHostService.getHostView().then(view => this.overlayHostView = view);
}
/**
* Set the alignment of the dropdown, either 'left' or 'right'. *Default: 'left'*.
*/
get align() {
return this.options.alignment;
}
set align(val) {
this.options.alignment = val;
}
/**
* Set the width of the dropdown. Can be either `contents`, `trigger`, `expand` or a numeric value. 'Contents' will
* set a width sufficient to accommodate the widest list item. 'Trigger' sets the width to equal the width
* of the trigger element. 'Expand' is equivalent to the maximum of 'trigger' and 'contents'.
* A numeric value sets the width the a specific number of pixels. *Default: 'contents'*.
*/
get width() {
return this.options.width;
}
set width(val) {
const isValid = (s) => /^(trigger|contents|expand|[\d\.]+)$/.test(s);
if (isValid(val)) {
this.options.width = val;
}
}
/**
* If true, the dropdown will be positioned below the bottom of the trigger element. *Default: false*.
*/
get belowTrigger() {
return this.options.belowTrigger;
}
set belowTrigger(val) {
this.options.belowTrigger = coerceToBoolean(val);
}
/**
* If true, the dropdown will not close when clicked, but may only be closed by clicking outside the dropdown or
* pressing escape. *Default: false*
*/
get sticky() {
return this.options.sticky;
}
set sticky(val) {
this.options.sticky = coerceToBoolean(val);
}
/**
* If true, the dropdown will close when the escape key is pressed. *Default: true*
*/
get closeOnEscape() {
return this.options.closeOnEscape;
}
set closeOnEscape(val) {
this.options.closeOnEscape = coerceToBoolean(val);
}
/**
* If true, the dropdown will not open when the trigger is clicked.
*/
get disabled() {
return this._disabled;
}
set disabled(val) {
this._disabled = coerceToBoolean(val);
}
get isOpen() {
return !!this.contentComponentRef;
}
/**
* Remove the content wrapper from the body.
*/
ngOnDestroy() {
this.closeDropdown();
}
/**
* Prevent the user from causing a scroll via the keyboard.
*/
keyHandler(e) {
const keyCode = e.keyCode;
const toPrevent = [
KeyCode.UpArrow,
KeyCode.DownArrow,
KeyCode.PageUp,
KeyCode.PageDown,
KeyCode.Space,
KeyCode.Home,
KeyCode.End
];
if (-1 < toPrevent.indexOf(keyCode)) {
e.preventDefault();
}
switch (keyCode) {
case KeyCode.Escape:
if (this.options.closeOnEscape === true) {
this.closeDropdown();
}
break;
case KeyCode.Tab:
if (this.isOpen) {
e.preventDefault();
this.content.focusFirstItem();
}
}
}
/**
* Open the dropdown contents in the correct position.
*/
openDropdown() {
if (this._disabled) {
return;
}
this.contentComponentRef = this.overlayHostView.createComponent(DropdownContentWrapper, null);
const contentInstance = this.contentComponentRef.instance;
contentInstance.content = this.contentsTemplate;
contentInstance.trigger = this.trigger.elementRef.nativeElement;
Object.assign(contentInstance.options, this.options);
contentInstance.clicked.pipe(take(1)).subscribe(() => {
if (!this.sticky) {
this.closeDropdown();
}
});
contentInstance.escapeKeyPressed.pipe(take(1)).subscribe(() => {
if (this.closeOnEscape) {
this.closeDropdown();
}
});
// When focus is lost from the list items (by tabbing), close the dropdown and focus the
// first child of the trigger is possible.
this.content.focusLost.pipe(take(1)).subscribe(() => {
this.closeDropdown();
this.trigger.focus();
});
this.scrollMaskRef = this.overlayHostView.createComponent(ScrollMask, null);
this.scrollMaskRef.instance.clicked.pipe(take(1)).subscribe(() => this.closeDropdown());
this.open.emit();
}
resize() {
if (this.contentComponentRef) {
this.contentComponentRef.instance.setPositionAndSize();
}
}
onTriggerClick() {
if (!this.isOpen) {
this.openDropdown();
}
else {
this.closeDropdown();
}
}
/**
* Close the dropdown.
*/
closeDropdown() {
if (this.scrollMaskRef) {
this.scrollMaskRef.destroy();
}
if (this.contentComponentRef) {
this.contentComponentRef.destroy();
this.contentComponentRef = null;
}
this.close.emit();
}
}
/** @nocollapse */ DropdownList.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DropdownList, deps: [{ token: i1.OverlayHostService }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ DropdownList.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: DropdownList, selector: "gtx-dropdown-list", inputs: { align: "align", width: "width", belowTrigger: "belowTrigger", sticky: "sticky", closeOnEscape: "closeOnEscape", disabled: "disabled" }, outputs: { open: "open", close: "close" }, host: { listeners: { "keydown": "keyHandler($event)" } }, queries: [{ propertyName: "trigger", first: true, predicate: DropdownTriggerDirective, descendants: true, static: true }, { propertyName: "content", first: true, predicate: DropdownContent, descendants: true }], viewQueries: [{ propertyName: "contentsTemplate", first: true, predicate: TemplateRef, descendants: true, static: true }], ngImport: i0, template: "<div (click)=\"onTriggerClick()\"><ng-content select=\"gtx-dropdown-trigger\"></ng-content></div>\n<ng-template>\n <ng-content select=\"gtx-dropdown-content\"></ng-content>\n</ng-template>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: DropdownList, decorators: [{
type: Component,
args: [{ selector: 'gtx-dropdown-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div (click)=\"onTriggerClick()\"><ng-content select=\"gtx-dropdown-trigger\"></ng-content></div>\n<ng-template>\n <ng-content select=\"gtx-dropdown-content\"></ng-content>\n</ng-template>\n" }]
}], ctorParameters: function () { return [{ type: i1.OverlayHostService }]; }, propDecorators: { contentsTemplate: [{
type: ViewChild,
args: [TemplateRef, { static: true }]
}], trigger: [{
type: ContentChild,
args: [DropdownTriggerDirective, { static: true }]
}], content: [{
type: ContentChild,
args: [DropdownContent]
}], open: [{
type: Output
}], close: [{
type: Output
}], align: [{
type: Input
}], width: [{
type: Input
}], belowTrigger: [{
type: Input
}], sticky: [{
type: Input
}], closeOnEscape: [{
type: Input
}], disabled: [{
type: Input
}], keyHandler: [{
type: HostListener,
args: ['keydown', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24tbGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9kcm9wZG93bi1saXN0L2Ryb3Bkb3duLWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvZHJvcGRvd24tbGlzdC9kcm9wZG93bi1saXN0LnRwbC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsU0FBUyxFQUVULFlBQVksRUFDWixZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sV0FBVyxFQUNYLFNBQVMsRUFFWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFcEMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUM5QyxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUN4RSxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUM1RSxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFDN0QsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFFdEUsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLHlCQUF5QixDQUFDOzs7QUFFbkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlDRztBQU1ILE1BQU0sT0FBTyxZQUFZO0lBMEdyQixZQUFZLGtCQUFzQztRQXpHbEQsWUFBTyxHQUFHO1lBQ04sU0FBUyxFQUFFLE1BQTJCO1lBQ3RDLEtBQUssRUFBRSxVQUEyQjtZQUNsQyxZQUFZLEVBQUUsS0FBSztZQUNuQixNQUFNLEVBQUUsS0FB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Q29tcG9uZW50LFxuICAgIENvbXBvbmVudFJlZixcbiAgICBDb250ZW50Q2hpbGQsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIEhvc3RMaXN0ZW5lcixcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT3V0cHV0LFxuICAgIFRlbXBsYXRlUmVmLFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3Q29udGFpbmVyUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHt0YWtlfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7Y29lcmNlVG9Cb29sZWFufSBmcm9tICcuLi8uLi9jb21tb24vY29lcmNlLXRvLWJvb2xlYW4nO1xuaW1wb3J0IHtLZXlDb2RlfSBmcm9tICcuLi8uLi9jb21tb24va2V5Y29kZXMnO1xuaW1wb3J0IHtPdmVybGF5SG9zdFNlcnZpY2V9IGZyb20gJy4uL292ZXJsYXktaG9zdC9vdmVybGF5LWhvc3Quc2VydmljZSc7XG5pbXBvcnQge0Ryb3Bkb3duQ29udGVudFdyYXBwZXJ9IGZyb20gJy4vZHJvcGRvd24tY29udGVudC13cmFwcGVyLmNvbXBvbmVudCc7XG5pbXBvcnQge0Ryb3Bkb3duQ29udGVudH0gZnJvbSAnLi9kcm9wZG93bi1jb250ZW50LmNvbXBvbmVudCc7XG5pbXBvcnQge0Ryb3Bkb3duVHJpZ2dlckRpcmVjdGl2ZX0gZnJvbSAnLi9kcm9wZG93bi10cmlnZ2VyLmRpcmVjdGl2ZSc7XG5pbXBvcnQge0Ryb3Bkb3duQWxpZ25tZW50LCBEcm9wZG93bldpZHRofSBmcm9tICcuL2Ryb3Bkb3duLm1vZGVsJztcbmltcG9ydCB7U2Nyb2xsTWFza30gZnJvbSAnLi9zY3JvbGwtbWFzay5jb21wb25lbnQnO1xuXG4vKipcbiAqIEEgRHJvcGRvd24gY29tcG9uZW50LiBEZXBlbmRzIG9uIHRoZSBbYDxndHgtb3ZlcmxheS1ob3N0PmBdKCMvb3ZlcmxheS1ob3N0KSBiZWluZyBwcmVzZW50IGluIHRoZSBhcHAuXG4gKlxuICogVGhlIGNvbXBvbmVudCBleHBlY3RzIHR3byBjaGlsZCBlbGVtZW50czpcbiAqXG4gKiAqIGA8Z3R4LWRyb3Bkb3duLXRyaWdnZXI+YCAtIHRoaXMgZWxlbWVudCBpcyB0aGUgYnV0dG9uL2xhYmVsIHdoaWNoIHRoZSB1c2VyIHdpbGwgY2xpY2sgdG8gb3BlbiB0aGUgZHJvcGRvd24uXG4gKiAqIGA8Z3R4LWRyb3Bkb3duLWNvbnRlbnQ+YCAtIGNvbnRhaW5zIHRoZSBjb250ZW50cyBvZiB0aGUgZHJvcGRvd24uIElmIGl0IGNvbnRhaW5zIGEgYDx1bD5gLCBzcGVjaWZpYyBzdHlsZXMgd2lsbCBiZSBhcHBsaWVkXG4gKlxuICogVGhlIGA8Z3R4LWRyb3Bkb3duLWNvbnRlbnQ+YCBlbGVtZW50IG1heSBjb250YWluIGFyYml0cmFyeSBjb250ZW50LCBidXQgbGlzdCBpdGVtcyBzaG91bGQgYmUgd3JhcHBlZCBpbiBgPGd0eC1kcm9wZG93bi1pdGVtPmAuXG4gKiBUaGlzIHdpbGwgYWxsb3cga2V5Ym9hcmQgc3VwcG9ydCBmb3IgbGlzdCBuYXZpZ2F0aW9uLlxuICpcbiAqXG4gKiBgYGBodG1sXG4gKiA8Z3R4LWRyb3Bkb3duLWxpc3Q+XG4gKiAgICAgPGd0eC1kcm9wZG93bi10cmlnZ2VyPlxuICogICAgICAgICA8YT5TaG93IExpc3Q8L2E+XG4gKiAgICAgPC9ndHgtZHJvcGRvd24tdHJpZ2dlcj5cbiAqICAgICA8Z3R4LWRyb3Bkb3duLWNvbnRlbnQ+XG4gKiAgICAgICAgICA8Z3R4LWRyb3Bkb3duLWl0ZW0+Rmlyc3Q8L2d0eC1kcm9wZG93bi1pdGVtPlxuICogICAgICAgICAgPGd0eC1kcm9wZG93bi1pdGVtPlNlY29uZDwvZ3R4LWRyb3Bkb3duLWl0ZW0+XG4gKiAgICAgICAgICA8Z3R4LWRyb3Bkb3duLWl0ZW0+VGhpcmQ8L2d0eC1kcm9wZG93bi1pdGVtPlxuICogICAgIDwvZ3R4LWRyb3Bkb3duLWNvbnRlbnQ+XG4gKiA8L2d0eC1kcm9wZG93bi1saXN0PlxuICogYGBgXG4gKlxuICogIyMgUHJvZ3JhbW1hdGljIFVzZVxuICogV2hlbiB1c2VkIHByb2dyYW1tYXRpY2FsbHkgKGUuZy4gYnkgZ2V0dGluZyBhIHJlZmVyZW5jZSB0byB0aGUgY29tcG9uZW50IHZpYSBgQENvbnRlbnRDaGlsZChEcm9wZG93bkxpc3QpYCwgdGhlXG4gKiBmb2xsb3dpbmcgZXh0ZW5kZWQgQVBJIGlzIGF2YWlsYWJsZTpcbiAqXG4gKiAtIGBkcm9wZG93bkxpc3QuaXNPcGVuOiBib29sZWFuYFxuICogLSBgZHJvcGRvd25MaXN0Lm9wZW5Ecm9wZG93bigpOiB2b2lkYFxuICogLSBgZHJvcGRvd25MaXN0LmNsb3NlRHJvcGRvd24oKTogdm9pZGBcbiAqIC0gYGRyb3Bkb3duTGlzdC5yZXNpemUoKTogdm9pZGBcbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdndHgtZHJvcGRvd24tbGlzdCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2Ryb3Bkb3duLWxpc3QudHBsLmh0bWwnLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIERyb3Bkb3duTGlzdCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgICAgYWxpZ25tZW50OiAnbGVmdCcgYXMgRHJvcGRvd25BbGlnbm1lbnQsXG4gICAgICAgIHdpZHRoOiAnY29udGVudHMnIGFzIERyb3Bkb3duV2lkdGgsXG4gICAgICAgIGJlbG93VHJpZ2dlcjogZmFsc2UsXG4gICAgICAgIHN0aWNreTogZmFsc2UsXG4gICAgICAgIGNsb3NlT25Fc2NhcGU6IHRydWVcbiAgICB9O1xuICAgIEBWaWV3Q2hpbGQoVGVtcGxhdGVSZWYsIHsgc3RhdGljOiB0cnVlIH0pIGNvbnRlbnRzVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gICAgQENvbnRlbnRDaGlsZChEcm9wZG93blRyaWdnZXJEaXJlY3RpdmUsIHsgc3RhdGljOiB0cnVlIH0pIHRyaWdnZXI6IERyb3Bkb3duVHJpZ2dlckRpcmVjdGl2ZTtcbiAgICBAQ29udGVudENoaWxkKERyb3Bkb3duQ29udGVudCkgY29udGVudDogRHJvcGRvd25Db250ZW50O1xuXG4gICAgLyoqXG4gICAgICogRmlyZWQgd2hlbmV2ZXIgdGhlIGRyb3Bkb3duIGNvbnRlbnRzIGFyZSBvcGVuZWQuXG4gICAgICovXG4gICAgQE91dHB1dCgpIG9wZW4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICAvKipcbiAgICAgKiBGaXJlZCB3aGVuZXZlciB0aGUgZHJvcGRvd24gY29udGVudHMgYXJlIGNsb3NlZC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgY2xvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICBwcml2YXRlIF9kaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHByaXZhdGUgb3ZlcmxheUhvc3RWaWV3OiBWaWV3Q29udGFpbmVyUmVmO1xuICAgIHByaXZhdGUgc2Nyb2xsTWFza0ZhY3Rvcnk6IFNjcm9sbE1hc2s7XG4gICAgcHJpdmF0ZSBzY3JvbGxNYXNrUmVmOiBDb21wb25lbnRSZWY8U2Nyb2xsTWFzaz47XG4gICAgcHJpdmF0ZSBjb250ZW50Q29tcG9uZW50RmFjdG9yeTogRHJvcGRvd25Db250ZW50V3JhcHBlcjtcbiAgICBwcml2YXRlIGNvbnRlbnRDb21wb25lbnRSZWY6IENvbXBvbmVudFJlZjxEcm9wZG93bkNvbnRlbnRXcmFwcGVyPjtcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYWxpZ25tZW50IG9mIHRoZSBkcm9wZG93biwgZWl0aGVyICdsZWZ0JyBvciAncmlnaHQnLiAqRGVmYXVsdDogJ2xlZnQnKi5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBhbGlnbigpOiBEcm9wZG93bkFsaWdubWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuYWxpZ25tZW50O1xuICAgIH1cbiAgICBzZXQgYWxpZ24odmFsOiBEcm9wZG93bkFsaWdubWVudCkge1xuICAgICAgICB0aGlzLm9wdGlvbnMuYWxpZ25tZW50ID0gdmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgd2lkdGggb2YgdGhlIGRyb3Bkb3duLiBDYW4gYmUgZWl0aGVyIGBjb250ZW50c2AsIGB0cmlnZ2VyYCwgYGV4cGFuZGAgb3IgYSBudW1lcmljIHZhbHVlLiAnQ29udGVudHMnIHdpbGxcbiAgICAgKiBzZXQgYSB3aWR0aCBzdWZmaWNpZW50IHRvIGFjY29tbW9kYXRlIHRoZSB3aWRlc3QgbGlzdCBpdGVtLiAnVHJpZ2dlcicgc2V0cyB0aGUgd2lkdGggdG8gZXF1YWwgdGhlIHdpZHRoXG4gICAgICogb2YgdGhlIHRyaWdnZXIgZWxlbWVudC4gJ0V4cGFuZCcgaXMgZXF1aXZhbGVudCB0byB0aGUgbWF4aW11bSBvZiAndHJpZ2dlcicgYW5kICdjb250ZW50cycuXG4gICAgICogQSBudW1lcmljIHZhbHVlIHNldHMgdGhlIHdpZHRoIHRoZSBhIHNwZWNpZmljIG51bWJlciBvZiBwaXhlbHMuICpEZWZhdWx0OiAnY29udGVudHMnKi5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCB3aWR0aCgpOiBEcm9wZG93bldpZHRoIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy53aWR0aDtcbiAgICB9XG4gICAgc2V0IHdpZHRoKHZhbDogRHJvcGRvd25XaWR0aCkge1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gKHM6IHN0cmluZykgPT4gL14odHJpZ2dlcnxjb250ZW50c3xleHBhbmR8W1xcZFxcLl0rKSQvLnRlc3Qocyk7XG4gICAgICAgIGlmIChpc1ZhbGlkKHZhbCBhcyBzdHJpbmcpKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMud2lkdGggPSB2YWw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiB0cnVlLCB0aGUgZHJvcGRvd24gd2lsbCBiZSBwb3NpdGlvbmVkIGJlbG93IHRoZSBib3R0b20gb2YgdGhlIHRyaWdnZXIgZWxlbWVudC4gKkRlZmF1bHQ6IGZhbHNlKi5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBiZWxvd1RyaWdnZXIoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuYmVsb3dUcmlnZ2VyO1xuICAgIH1cbiAgICBzZXQgYmVsb3dUcmlnZ2VyKHZhbDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLm9wdGlvbnMuYmVsb3dUcmlnZ2VyID0gY29lcmNlVG9Cb29sZWFuKHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgdHJ1ZSwgdGhlIGRyb3Bkb3duIHdpbGwgbm90IGNsb3NlIHdoZW4gY2xpY2tlZCwgYnV0IG1heSBvbmx5IGJlIGNsb3NlZCBieSBjbGlja2luZyBvdXRzaWRlIHRoZSBkcm9wZG93biBvclxuICAgICAqIHByZXNzaW5nIGVzY2FwZS4gKkRlZmF1bHQ6IGZhbHNlKlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IHN0aWNreSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5zdGlja3k7XG4gICAgfVxuICAgIHNldCBzdGlja3kodmFsOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucy5zdGlja3kgPSBjb2VyY2VUb0Jvb2xlYW4odmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiB0cnVlLCB0aGUgZHJvcGRvd24gd2lsbCBjbG9zZSB3aGVuIHRoZSBlc2NhcGUga2V5IGlzIHByZXNzZWQuICpEZWZhdWx0OiB0cnVlKlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IGNsb3NlT25Fc2NhcGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuY2xvc2VPbkVzY2FwZTtcbiAgICB9XG4gICAgc2V0IGNsb3NlT25Fc2NhcGUodmFsOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucy5jbG9zZU9uRXNjYXBlID0gY29lcmNlVG9Cb29sZWFuKHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgdHJ1ZSwgdGhlIGRyb3Bkb3duIHdpbGwgbm90IG9wZW4gd2hlbiB0aGUgdHJpZ2dlciBpcyBjbGlja2VkLlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGlzYWJsZWQ7XG4gICAgfVxuICAgIHNldCBkaXNhYmxlZCh2YWw6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fZGlzYWJsZWQgPSBjb2VyY2VUb0Jvb2xlYW4odmFsKTtcbiAgICB9XG5cbiAgICBnZXQgaXNPcGVuKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLmNvbnRlbnRDb21wb25lbnRSZWY7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3Iob3ZlcmxheUhvc3RTZXJ2aWNlOiBPdmVybGF5SG9zdFNlcnZpY2UpIHtcbiAgICAgICAgb3ZlcmxheUhvc3RTZXJ2aWNlLmdldEhvc3RWaWV3KCkudGhlbih2aWV3ID0+IHRoaXMub3ZlcmxheUhvc3RWaWV3ID0gdmlldyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoZSBjb250ZW50IHdyYXBwZXIgZnJvbSB0aGUgYm9keS5cbiAgICAgKi9cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJldmVudCB0aGUgdXNlciBmcm9tIGNhdXNpbmcgYSBzY3JvbGwgdmlhIHRoZSBrZXlib2FyZC5cbiAgICAgKi9cbiAgICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSlcbiAgICBrZXlIYW5kbGVyKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qga2V5Q29kZSA9IGUua2V5Q29kZTtcbiAgICAgICAgY29uc3QgdG9QcmV2ZW50ID0gW1xuICAgICAgICAgICAgS2V5Q29kZS5VcEFycm93LFxuICAgICAgICAgICAgS2V5Q29kZS5Eb3duQXJyb3csXG4gICAgICAgICAgICBLZXlDb2RlLlBhZ2VVcCxcbiAgICAgICAgICAgIEtleUNvZGUuUGFnZURvd24sXG4gICAgICAgICAgICBLZXlDb2RlLlNwYWNlLFxuICAgICAgICAgICAgS2V5Q29kZS5Ib21lLFxuICAgICAgICAgICAgS2V5Q29kZS5FbmRcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAoLTEgPCB0b1ByZXZlbnQuaW5kZXhPZihrZXlDb2RlKSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoIChrZXlDb2RlKSB7XG4gICAgICAgICAgICBjYXNlIEtleUNvZGUuRXNjYXBlOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY2xvc2VPbkVzY2FwZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEtleUNvZGUuVGFiOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudC5mb2N1c0ZpcnN0SXRlbSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZW4gdGhlIGRyb3Bkb3duIGNvbnRlbnRzIGluIHRoZSBjb3JyZWN0IHBvc2l0aW9uLlxuICAgICAqL1xuICAgIG9wZW5Ecm9wZG93bigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2Rpc2FibGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb250ZW50Q29tcG9uZW50UmVmID0gdGhpcy5vdmVybGF5SG9zdFZpZXcuY3JlYXRlQ29tcG9uZW50KERyb3Bkb3duQ29udGVudFdyYXBwZXIsIG51bGwpO1xuICAgICAgICBjb25zdCBjb250ZW50SW5zdGFuY2UgPSB0aGlzLmNvbnRlbnRDb21wb25lbnRSZWYuaW5zdGFuY2U7XG4gICAgICAgIGNvbnRlbnRJbnN0YW5jZS5jb250ZW50ID0gdGhpcy5jb250ZW50c1RlbXBsYXRlO1xuICAgICAgICBjb250ZW50SW5zdGFuY2UudHJpZ2dlciA9IHRoaXMudHJpZ2dlci5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIE9iamVjdC5hc3NpZ24oY29udGVudEluc3RhbmNlLm9wdGlvbnMsIHRoaXMub3B0aW9ucyk7XG4gICAgICAgIGNvbnRlbnRJbnN0YW5jZS5jbGlja2VkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zdGlja3kpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnRlbnRJbnN0YW5jZS5lc2NhcGVLZXlQcmVzc2VkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNsb3NlT25Fc2NhcGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFdoZW4gZm9jdXMgaXMgbG9zdCBmcm9tIHRoZSBsaXN0IGl0ZW1zIChieSB0YWJiaW5nKSwgY2xvc2UgdGhlIGRyb3Bkb3duIGFuZCBmb2N1cyB0aGVcbiAgICAgICAgLy8gZmlyc3QgY2hpbGQgb2YgdGhlIHRyaWdnZXIgaXMgcG9zc2libGUuXG4gICAgICAgIHRoaXMuY29udGVudC5mb2N1c0xvc3QucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXIuZm9jdXMoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zY3JvbGxNYXNrUmVmID0gdGhpcy5vdmVybGF5SG9zdFZpZXcuY3JlYXRlQ29tcG9uZW50KFNjcm9sbE1hc2ssIG51bGwpO1xuICAgICAgICB0aGlzLnNjcm9sbE1hc2tSZWYuaW5zdGFuY2UuY2xpY2tlZC5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLmNsb3NlRHJvcGRvd24oKSk7XG4gICAgICAgIHRoaXMub3Blbi5lbWl0KCk7XG4gICAgfVxuXG4gICAgcmVzaXplKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jb250ZW50Q29tcG9uZW50UmVmKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRlbnRDb21wb25lbnRSZWYuaW5zdGFuY2Uuc2V0UG9zaXRpb25BbmRTaXplKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvblRyaWdnZXJDbGljaygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzT3Blbikge1xuICAgICAgICAgICAgdGhpcy5vcGVuRHJvcGRvd24oKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIGRyb3Bkb3duLlxuICAgICAqL1xuICAgIGNsb3NlRHJvcGRvd24oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNjcm9sbE1hc2tSZWYpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsTWFza1JlZi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY29udGVudENvbXBvbmVudFJlZikge1xuICAgICAgICAgICAgdGhpcy5jb250ZW50Q29tcG9uZW50UmVmLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuY29udGVudENvbXBvbmVudFJlZiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbG9zZS5lbWl0KCk7XG4gICAgfVxufVxuIiwiPGRpdiAoY2xpY2spPVwib25UcmlnZ2VyQ2xpY2soKVwiPjxuZy1jb250ZW50IHNlbGVjdD1cImd0eC1kcm9wZG93bi10cmlnZ2VyXCI+PC9uZy1jb250ZW50PjwvZGl2PlxuPG5nLXRlbXBsYXRlPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cImd0eC1kcm9wZG93bi1jb250ZW50XCI+PC9uZy1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==