UNPKG

theme-lib

Version:

This is a simple example Angular Library published to npm.

693 lines 54.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /* * @license * Copyright Akveo. All Rights Reserved. * Licensed under the MIT License. See License.txt in the project root for license information. */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, ElementRef, EventEmitter, forwardRef, Inject, Input, Output, QueryList, ViewChild, } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { take, takeWhile } from 'rxjs/operators'; import { defer, merge } from 'rxjs'; import { NbAdjustment, NbOverlayService, NbPortalDirective, NbPosition, NbPositionBuilderService, NbTrigger, NbTriggerStrategyBuilder, } from '../cdk'; import { NbOptionComponent } from './option.component'; import { NbButtonComponent } from '../button/button.component'; import { NB_DOCUMENT } from '../../theme.options'; import { convertToBoolProperty } from '../helpers'; export class NbSelectLabelComponent { } NbSelectLabelComponent.decorators = [ { type: Component, args: [{ selector: 'nb-select-label', template: '<ng-content></ng-content>' }] } ]; /* * The `NbSelectComponent` provides a capability to select one of the passed items. * * @stacked-example(Showcase, select/select-showcase.component) * * ### Installation * * Import `NbSelectModule` to your feature module. * ```ts * @NgModule({ * imports: [ * // ... * NbSelectModule, * ], * }) * export class PageModule { } * ``` * ### Usage * * If you want to use it as the multi-select control you have to mark it as `multiple`. * In this case, `nb-select` will work only with arrays - accept arrays and propagate arrays. * * @stacked-example(Multiple, select/select-multiple.component) * * Items without values will clean selection. * * @stacked-example(Clean selection, select/select-clean.component) * * Select may be bounded using `selected` input: * * ```html * <nb-select [(selected)]="selected"></nb-selected> * ``` * * Or you can bind control with form controls or ngModel: * * @stacked-example(Select form binding, select/select-form.component) * * Options in the select may be grouped using `nb-option-group` component. * * @stacked-example(Grouping, select/select-groups.component) * * Select may have a placeholder that will be shown when nothing selected: * * @stacked-example(Placeholder, select/select-placeholder.component) * * You can disable select, options and whole groups. * * @stacked-example(Disabled select, select/select-disabled.component) * * Also, the custom label may be provided in select. * This custom label will be used for instead placeholder when something selected. * * @stacked-example(Custom label, select/select-label.component) * * Default `nb-select` size is `medium` and status color is `primary`. * Select is available in multiple colors using `status` property: * * @stacked-example(Select statuses, select/select-status.component) * * There are four select sizes: * * @stacked-example(Select sizes, select/select-sizes.component) * * And two additional style types - `outline`: * * @stacked-example(Outline select, select/select-outline.component) * * and `hero`: * * @stacked-example(Select colors, select/select-hero.component) * * Select is available in different shapes, that could be combined with the other properties: * * @stacked-example(Select shapes, select/select-shapes.component) * * * @styles * * select-border-width: * select-max-height: * select-bg: * select-checkbox-color: * select-checkmark-color: * select-option-disabled-bg: * select-option-disabled-opacity: * select-option-padding: * */ /** * @template T */ export class NbSelectComponent { /** * @param {?} document * @param {?} overlay * @param {?} hostRef * @param {?} positionBuilder * @param {?} cd */ constructor(document, overlay, hostRef, positionBuilder, cd) { this.document = document; this.overlay = overlay; this.hostRef = hostRef; this.positionBuilder = positionBuilder; this.cd = cd; /* * Select status (adds specific styles): * `primary`, `info`, `success`, `warning`, `danger` */ this.status = 'primary'; /* * Renders select placeholder if nothing selected. * */ this.placeholder = ''; /* * Will be emitted when selected value changes. * */ this.selectedChange = new EventEmitter(); this.multiple = false; /* * List of selected options. * */ this.selectionModel = []; /* * Current overlay position because of we have to toggle overlayPosition * in [ngClass] direction and this directive can use only string. */ this.overlayPosition = (/** @type {?} */ ('')); /* * Stream of events that will fire when one of the options fire selectionChange event. * */ this.selectionChange = defer(() => { return merge(...this.options.map(it => it.selectionChange)); }); this.alive = true; /* * Function passed through control value accessor to propagate changes. * */ this.onChange = () => { }; this.onTouched = () => { }; } /* * Accepts selected item or array of selected items. * */ /** * @param {?} value * @return {?} */ set setSelected(value) { this.writeValue(value); } /* * Gives capability just write `multiple` over the element. * */ /** * @param {?} multiple * @return {?} */ set setMultiple(multiple) { this.multiple = convertToBoolProperty(multiple); } /* * Determines is select opened. * */ /** * @return {?} */ get isOpened() { return this.ref && this.ref.hasAttached(); } /* * Determines is select hidden. * */ /** * @return {?} */ get isHidden() { return !this.isOpened; } /* * Returns width of the select button. * */ /** * @return {?} */ get hostWidth() { return this.hostRef.nativeElement.getBoundingClientRect().width; } /* * Content rendered in the label. * */ /** * @return {?} */ get selectionView() { if (this.selectionModel.length > 1) { return this.selectionModel.map((option) => option.content).join(', '); } return this.selectionModel[0].content; } /** * @return {?} */ ngOnInit() { this.createOverlay(); } /** * @return {?} */ ngAfterViewInit() { this.subscribeOnTriggers(); this.subscribeOnPositionChange(); this.subscribeOnSelectionChange(); } /** * @return {?} */ ngAfterContentInit() { if (this.queue) { this.writeValue(this.queue); this.cd.detectChanges(); } } /** * @return {?} */ ngOnDestroy() { this.ref.dispose(); } /** * @return {?} */ show() { if (this.isHidden) { this.ref.attach(this.portal); this.cd.markForCheck(); } } /** * @return {?} */ hide() { if (this.isOpened) { this.ref.detach(); this.cd.markForCheck(); } } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; this.cd.detectChanges(); } /** * @param {?} value * @return {?} */ writeValue(value) { if (!value) { return; } if (this.options) { this.setSelection(value); } else { this.queue = value; } } /* * Selects option or clear all selected options if value is null. * */ /** * @protected * @param {?} option * @return {?} */ handleSelect(option) { if (option.value) { this.selectOption(option); } else { this.reset(); } this.cd.detectChanges(); } /* * Deselect all selected options. * */ /** * @protected * @return {?} */ reset() { this.selectionModel.forEach((option) => option.deselect()); this.selectionModel = []; this.hide(); this.button.nativeElement.focus(); this.emitSelected(null); } /* * Determines how to select option as multiple or single. * */ /** * @protected * @param {?} option * @return {?} */ selectOption(option) { if (this.multiple) { this.handleMultipleSelect(option); } else { this.handleSingleSelect(option); } } /* * Select single option. * */ /** * @protected * @param {?} option * @return {?} */ handleSingleSelect(option) { /** @type {?} */ const selected = this.selectionModel.pop(); if (selected && selected !== option) { selected.deselect(); } this.selectionModel = [option]; option.select(); this.hide(); this.button.nativeElement.focus(); this.emitSelected(option.value); } /* * Select for multiple options. * */ /** * @protected * @param {?} option * @return {?} */ handleMultipleSelect(option) { if (option.selected) { this.selectionModel = this.selectionModel.filter(s => s.value !== option.value); option.deselect(); } else { this.selectionModel.push(option); option.select(); } this.emitSelected(this.selectionModel.map((opt) => opt.value)); } /** * @protected * @return {?} */ createOverlay() { /** @type {?} */ const scrollStrategy = this.createScrollStrategy(); this.positionStrategy = this.createPositionStrategy(); this.ref = this.overlay.create({ positionStrategy: this.positionStrategy, scrollStrategy }); } /** * @protected * @return {?} */ createPositionStrategy() { return this.positionBuilder .connectedTo(this.hostRef) .position(NbPosition.BOTTOM) .offset(0) .adjustment(NbAdjustment.VERTICAL); } /** * @protected * @return {?} */ createScrollStrategy() { return this.overlay.scrollStrategies.block(); } /** * @protected * @return {?} */ subscribeOnTriggers() { /** @type {?} */ const triggerStrategy = new NbTriggerStrategyBuilder() .document(this.document) .trigger(NbTrigger.CLICK) .host(this.hostRef.nativeElement) .container(() => this.getContainer()) .build(); triggerStrategy.show$ .pipe(takeWhile(() => this.alive)) .subscribe(() => this.show()); triggerStrategy.hide$ .pipe(takeWhile(() => this.alive)) .subscribe(($event) => { this.hide(); if (!this.isClickedWithinComponent($event)) { this.onTouched(); } }); } /** * @protected * @return {?} */ subscribeOnPositionChange() { this.positionStrategy.positionChange .pipe(takeWhile(() => this.alive)) .subscribe((position) => this.overlayPosition = position); this.positionStrategy.positionChange .pipe(take(1)) .subscribe(() => this.cd.detectChanges()); } /** * @protected * @return {?} */ subscribeOnSelectionChange() { this.selectionChange .pipe(takeWhile(() => this.alive)) .subscribe((option) => this.handleSelect(option)); } /** * @protected * @return {?} */ getContainer() { return this.ref && this.ref.hasAttached() && (/** @type {?} */ ({ location: { nativeElement: this.ref.overlayElement, }, })); } /* * Propagate selected value. * */ /** * @protected * @param {?} selected * @return {?} */ emitSelected(selected) { this.onChange(selected); this.selectedChange.emit(selected); } /* * Set selected value in model. * */ /** * @protected * @param {?} value * @return {?} */ setSelection(value) { /** @type {?} */ const isArray = Array.isArray(value); if (this.multiple && !isArray) { throw new Error('Can\'t assign single value if select is marked as multiple'); } if (!this.multiple && isArray) { throw new Error('Can\'t assign array if select is not marked as multiple'); } this.cleanSelection(); if (isArray) { ((/** @type {?} */ (value))).forEach((option) => this.selectValue(option)); } else { this.selectValue((/** @type {?} */ (value))); } this.cd.markForCheck(); this.cd.detectChanges(); } /** * @protected * @return {?} */ cleanSelection() { this.selectionModel.forEach((option) => option.deselect()); this.selectionModel = []; } /* * Selects value. * */ /** * @protected * @param {?} value * @return {?} */ selectValue(value) { /** @type {?} */ const corresponding = this.options.find((option) => option.value === value); if (corresponding) { corresponding.select(); this.selectionModel.push(corresponding); } } /* * Sets touched if focus moved outside of button and overlay, * ignoring the case when focus moved to options overlay. */ /** * @return {?} */ trySetTouched() { if (this.isHidden) { this.onTouched(); } } /** * @protected * @param {?} $event * @return {?} */ isClickedWithinComponent($event) { return this.hostRef.nativeElement === $event.target || this.hostRef.nativeElement.contains((/** @type {?} */ ($event.target))); } } NbSelectComponent.decorators = [ { type: Component, args: [{ selector: 'nb-select', template: "<button\r\n nbButton\r\n [size]=\"size\"\r\n [status]=\"status\"\r\n [shape]=\"shape\"\r\n [hero]=\"hero\"\r\n [disabled]=\"disabled\"\r\n [fullWidth]=\"fullWidth\"\r\n [outline]=\"outline\"\r\n [class.opened]=\"isOpened\"\r\n [ngClass]=\"overlayPosition\"\r\n (blur)=\"trySetTouched()\"\r\n type=\"button\">\r\n\r\n <ng-container *ngIf=\"selectionModel?.length\">\r\n\r\n <ng-container *ngIf=\"customLabel\">\r\n <ng-content select=\"nb-select-label\"></ng-content>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!customLabel\">{{ selectionView }}</ng-container>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"!selectionModel?.length\">{{ placeholder }}</ng-container>\r\n\r\n</button>\r\n\r\n<nb-card *nbPortal class=\"select\" [ngClass]=\"[status, overlayPosition]\" [style.width.px]=\"hostWidth\">\r\n <nb-card-body>\r\n <ng-content select=\"nb-option, nb-option-group\"></ng-content>\r\n </nb-card-body>\r\n</nb-card>\r\n", changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NbSelectComponent), multi: true, }, ], styles: ["/*!\r\n * @license\r\n * Copyright Akveo. All Rights Reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n */:host{display:block}:host button{position:relative;width:100%;text-align:start;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:none}:host button::after{top:50%;right:.75rem;position:absolute;display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:'';border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}"] }] } ]; /** @nocollapse */ NbSelectComponent.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }, { type: NbOverlayService }, { type: ElementRef }, { type: NbPositionBuilderService }, { type: ChangeDetectorRef } ]; NbSelectComponent.propDecorators = { size: [{ type: Input }], status: [{ type: Input }], shape: [{ type: Input }], hero: [{ type: Input }], disabled: [{ type: Input }], fullWidth: [{ type: Input }], outline: [{ type: Input }], placeholder: [{ type: Input }], selectedChange: [{ type: Output }], setSelected: [{ type: Input, args: ['selected',] }], setMultiple: [{ type: Input, args: ['multiple',] }], options: [{ type: ContentChildren, args: [NbOptionComponent, { descendants: true },] }], customLabel: [{ type: ContentChild, args: [NbSelectLabelComponent,] }], portal: [{ type: ViewChild, args: [NbPortalDirective,] }], button: [{ type: ViewChild, args: [NbButtonComponent, { read: ElementRef },] }] }; if (false) { /** @type {?} */ NbSelectComponent.prototype.size; /** @type {?} */ NbSelectComponent.prototype.status; /** @type {?} */ NbSelectComponent.prototype.shape; /** @type {?} */ NbSelectComponent.prototype.hero; /** @type {?} */ NbSelectComponent.prototype.disabled; /** @type {?} */ NbSelectComponent.prototype.fullWidth; /** @type {?} */ NbSelectComponent.prototype.outline; /** @type {?} */ NbSelectComponent.prototype.placeholder; /** @type {?} */ NbSelectComponent.prototype.selectedChange; /** @type {?} */ NbSelectComponent.prototype.options; /** @type {?} */ NbSelectComponent.prototype.customLabel; /** @type {?} */ NbSelectComponent.prototype.portal; /** @type {?} */ NbSelectComponent.prototype.button; /** @type {?} */ NbSelectComponent.prototype.multiple; /** @type {?} */ NbSelectComponent.prototype.selectionModel; /** @type {?} */ NbSelectComponent.prototype.positionStrategy; /** @type {?} */ NbSelectComponent.prototype.overlayPosition; /** @type {?} */ NbSelectComponent.prototype.selectionChange; /** * @type {?} * @protected */ NbSelectComponent.prototype.ref; /** * @type {?} * @protected */ NbSelectComponent.prototype.alive; /** * @type {?} * @protected */ NbSelectComponent.prototype.queue; /** * @type {?} * @protected */ NbSelectComponent.prototype.onChange; /** * @type {?} * @protected */ NbSelectComponent.prototype.onTouched; /** * @type {?} * @protected */ NbSelectComponent.prototype.document; /** * @type {?} * @protected */ NbSelectComponent.prototype.overlay; /** * @type {?} * @protected */ NbSelectComponent.prototype.hostRef; /** * @type {?} * @protected */ NbSelectComponent.prototype.positionBuilder; /** * @type {?} * @protected */ NbSelectComponent.prototype.cd; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3RoZW1lLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3NlbGVjdC9zZWxlY3QuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQU1BLE9BQU8sRUFHTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFFVCxZQUFZLEVBQ1osZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakQsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFFaEQsT0FBTyxFQUVMLFlBQVksRUFFWixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLFVBQVUsRUFDVix3QkFBd0IsRUFDeEIsU0FBUyxFQUVULHdCQUF3QixHQUN6QixNQUFNLFFBQVEsQ0FBQztBQUNoQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBT25ELE1BQU0sT0FBTyxzQkFBc0I7OztZQUpsQyxTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjtnQkFDM0IsUUFBUSxFQUFFLDJCQUEyQjthQUN0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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Q0FBcUU7O0lBc0JyRSxvQ0FBb0c7O0lBS3BHLHdDQUFrRDs7SUFLbEQsbUNBQXdEOztJQUV4RCxtQ0FBMEY7O0lBRTFGLHFDQUEwQjs7SUFLMUIsMkNBQTRDOztJQUU1Qyw2Q0FBd0Q7O0lBTXhELDRDQUErQzs7SUFLL0MsNENBRUc7Ozs7O0lBRUgsZ0NBQTRCOzs7OztJQUU1QixrQ0FBZ0M7Ozs7O0lBT2hDLGtDQUF5Qjs7Ozs7SUFLekIscUNBQXdDOzs7OztJQUN4QyxzQ0FBeUM7Ozs7O0lBRTdCLHFDQUF1Qzs7Ozs7SUFDdkMsb0NBQW1DOzs7OztJQUNuQyxvQ0FBMEM7Ozs7O0lBQzFDLDRDQUFtRDs7Ozs7SUFDbkQsK0JBQStCIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEFrdmVvLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG4gKi9cclxuXHJcbmltcG9ydCB7XHJcbiAgQWZ0ZXJDb250ZW50SW5pdCxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBDb21wb25lbnRSZWYsXHJcbiAgQ29udGVudENoaWxkLFxyXG4gIENvbnRlbnRDaGlsZHJlbixcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBmb3J3YXJkUmVmLFxyXG4gIEluamVjdCxcclxuICBJbnB1dCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxuICBRdWVyeUxpc3QsXHJcbiAgVmlld0NoaWxkLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IHRha2UsIHRha2VXaGlsZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgZGVmZXIsIG1lcmdlLCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcblxyXG5pbXBvcnQge1xyXG4gIE5iQWRqdXN0YWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3ksXHJcbiAgTmJBZGp1c3RtZW50LFxyXG4gIE5iT3ZlcmxheVJlZixcclxuICBOYk92ZXJsYXlTZXJ2aWNlLFxyXG4gIE5iUG9ydGFsRGlyZWN0aXZlLFxyXG4gIE5iUG9zaXRpb24sXHJcbiAgTmJQb3NpdGlvbkJ1aWxkZXJTZXJ2aWNlLCBOYlNjcm9sbFN0cmF0ZWd5LFxyXG4gIE5iVHJpZ2dlcixcclxuICBOYlRyaWdnZXJTdHJhdGVneSxcclxuICBOYlRyaWdnZXJTdHJhdGVneUJ1aWxkZXIsXHJcbn0gZnJvbSAnLi4vY2RrJztcclxuaW1wb3J0IHsgTmJPcHRpb25Db21wb25lbnQgfSBmcm9tICcuL29wdGlvbi5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBOYkJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJy4uL2J1dHRvbi9idXR0b24uY29tcG9uZW50JztcclxuaW1wb3J0IHsgTkJfRE9DVU1FTlQgfSBmcm9tICcuLi8uLi90aGVtZS5vcHRpb25zJztcclxuaW1wb3J0IHsgY29udmVydFRvQm9vbFByb3BlcnR5IH0gZnJvbSAnLi4vaGVscGVycyc7XHJcblxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduYi1zZWxlY3QtbGFiZWwnLFxyXG4gIHRlbXBsYXRlOiAnPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PicsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOYlNlbGVjdExhYmVsQ29tcG9uZW50IHtcclxufVxyXG5cclxuLypcclxuICogVGhlIGBOYlNlbGVjdENvbXBvbmVudGAgcHJvdmlkZXMgYSBjYXBhYmlsaXR5IHRvIHNlbGVjdCBvbmUgb2YgdGhlIHBhc3NlZCBpdGVtcy5cclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShTaG93Y2FzZSwgc2VsZWN0L3NlbGVjdC1zaG93Y2FzZS5jb21wb25lbnQpXHJcbiAqXHJcbiAqICMjIyBJbnN0YWxsYXRpb25cclxuICpcclxuICogSW1wb3J0IGBOYlNlbGVjdE1vZHVsZWAgdG8geW91ciBmZWF0dXJlIG1vZHVsZS5cclxuICogYGBgdHNcclxuICogQE5nTW9kdWxlKHtcclxuICogICBpbXBvcnRzOiBbXHJcbiAqICAgXHQvLyAuLi5cclxuICogICAgIE5iU2VsZWN0TW9kdWxlLFxyXG4gKiAgIF0sXHJcbiAqIH0pXHJcbiAqIGV4cG9ydCBjbGFzcyBQYWdlTW9kdWxlIHsgfVxyXG4gKiBgYGBcclxuICogIyMjIFVzYWdlXHJcbiAqXHJcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBpdCBhcyB0aGUgbXVsdGktc2VsZWN0IGNvbnRyb2wgeW91IGhhdmUgdG8gbWFyayBpdCBhcyBgbXVsdGlwbGVgLlxyXG4gKiBJbiB0aGlzIGNhc2UsIGBuYi1zZWxlY3RgIHdpbGwgd29yayBvbmx5IHdpdGggYXJyYXlzIC0gYWNjZXB0IGFycmF5cyBhbmQgcHJvcGFnYXRlIGFycmF5cy5cclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShNdWx0aXBsZSwgc2VsZWN0L3NlbGVjdC1tdWx0aXBsZS5jb21wb25lbnQpXHJcbiAqXHJcbiAqIEl0ZW1zIHdpdGhvdXQgdmFsdWVzIHdpbGwgY2xlYW4gc2VsZWN0aW9uLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKENsZWFuIHNlbGVjdGlvbiwgc2VsZWN0L3NlbGVjdC1jbGVhbi5jb21wb25lbnQpXHJcbiAqXHJcbiAqIFNlbGVjdCBtYXkgYmUgYm91bmRlZCB1c2luZyBgc2VsZWN0ZWRgIGlucHV0OlxyXG4gKlxyXG4gKiBgYGBodG1sXHJcbiAqIDxuYi1zZWxlY3QgWyhzZWxlY3RlZCldPVwic2VsZWN0ZWRcIj48L25iLXNlbGVjdGVkPlxyXG4gKiBgYGBcclxuICpcclxuICogT3IgeW91IGNhbiBiaW5kIGNvbnRyb2wgd2l0aCBmb3JtIGNvbnRyb2xzIG9yIG5nTW9kZWw6XHJcbiAqXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoU2VsZWN0IGZvcm0gYmluZGluZywgc2VsZWN0L3NlbGVjdC1mb3JtLmNvbXBvbmVudClcclxuICpcclxuICogT3B0aW9ucyBpbiB0aGUgc2VsZWN0IG1heSBiZSBncm91cGVkIHVzaW5nIGBuYi1vcHRpb24tZ3JvdXBgIGNvbXBvbmVudC5cclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShHcm91cGluZywgc2VsZWN0L3NlbGVjdC1ncm91cHMuY29tcG9uZW50KVxyXG4gKlxyXG4gKiBTZWxlY3QgbWF5IGhhdmUgYSBwbGFjZWhvbGRlciB0aGF0IHdpbGwgYmUgc2hvd24gd2hlbiBub3RoaW5nIHNlbGVjdGVkOlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFBsYWNlaG9sZGVyLCBzZWxlY3Qvc2VsZWN0LXBsYWNlaG9sZGVyLmNvbXBvbmVudClcclxuICpcclxuICogWW91IGNhbiBkaXNhYmxlIHNlbGVjdCwgb3B0aW9ucyBhbmQgd2hvbGUgZ3JvdXBzLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKERpc2FibGVkIHNlbGVjdCwgc2VsZWN0L3NlbGVjdC1kaXNhYmxlZC5jb21wb25lbnQpXHJcbiAqXHJcbiAqIEFsc28sIHRoZSBjdXN0b20gbGFiZWwgbWF5IGJlIHByb3ZpZGVkIGluIHNlbGVjdC5cclxuICogVGhpcyBjdXN0b20gbGFiZWwgd2lsbCBiZSB1c2VkIGZvciBpbnN0ZWFkIHBsYWNlaG9sZGVyIHdoZW4gc29tZXRoaW5nIHNlbGVjdGVkLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKEN1c3RvbSBsYWJlbCwgc2VsZWN0L3NlbGVjdC1sYWJlbC5jb21wb25lbnQpXHJcbiAqXHJcbiAqIERlZmF1bHQgYG5iLXNlbGVjdGAgc2l6ZSBpcyBgbWVkaXVtYCBhbmQgc3RhdHVzIGNvbG9yIGlzIGBwcmltYXJ5YC5cclxuICogU2VsZWN0IGlzIGF2YWlsYWJsZSBpbiBtdWx0aXBsZSBjb2xvcnMgdXNpbmcgYHN0YXR1c2AgcHJvcGVydHk6XHJcbiAqXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoU2VsZWN0IHN0YXR1c2VzLCBzZWxlY3Qvc2VsZWN0LXN0YXR1cy5jb21wb25lbnQpXHJcbiAqXHJcbiAqIFRoZXJlIGFyZSBmb3VyIHNlbGVjdCBzaXplczpcclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShTZWxlY3Qgc2l6ZXMsIHNlbGVjdC9zZWxlY3Qtc2l6ZXMuY29tcG9uZW50KVxyXG4gKlxyXG4gKiBBbmQgdHdvIGFkZGl0aW9uYWwgc3R5bGUgdHlwZXMgLSBgb3V0bGluZWA6XHJcbiAqXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoT3V0bGluZSBzZWxlY3QsIHNlbGVjdC9zZWxlY3Qtb3V0bGluZS5jb21wb25lbnQpXHJcbiAqXHJcbiAqIGFuZCBgaGVyb2A6XHJcbiAqXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoU2VsZWN0IGNvbG9ycywgc2VsZWN0L3NlbGVjdC1oZXJvLmNvbXBvbmVudClcclxuICpcclxuICogU2VsZWN0IGlzIGF2YWlsYWJsZSBpbiBkaWZmZXJlbnQgc2hhcGVzLCB0aGF0IGNvdWxkIGJlIGNvbWJpbmVkIHdpdGggdGhlIG90aGVyIHByb3BlcnRpZXM6XHJcbiAqXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoU2VsZWN0IHNoYXBlcywgc2VsZWN0L3NlbGVjdC1zaGFwZXMuY29tcG9uZW50KVxyXG4gKlxyXG4gKlxyXG4gKiBAc3R5bGVzXHJcbiAqXHJcbiAqIHNlbGVjdC1ib3JkZXItd2lkdGg6XHJcbiAqIHNlbGVjdC1tYXgtaGVpZ2h0OlxyXG4gKiBzZWxlY3QtYmc6XHJcbiAqIHNlbGVjdC1jaGVja2JveC1jb2xvcjpcclxuICogc2VsZWN0LWNoZWNrbWFyay1jb2xvcjpcclxuICogc2VsZWN0LW9wdGlvbi1kaXNhYmxlZC1iZzpcclxuICogc2VsZWN0LW9wdGlvbi1kaXNhYmxlZC1vcGFjaXR5OlxyXG4gKiBzZWxlY3Qtb3B0aW9uLXBhZGRpbmc6XHJcbiAqICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmItc2VsZWN0JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vc2VsZWN0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9zZWxlY3QuY29tcG9uZW50LnNjc3MnXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5iU2VsZWN0Q29tcG9uZW50KSxcclxuICAgICAgbXVsdGk6IHRydWUsXHJcbiAgICB9LFxyXG4gIF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOYlNlbGVjdENvbXBvbmVudDxUPiBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XHJcbiAgLypcclxuICAgKiBTZWxlY3Qgc2l6ZSwgYXZhaWxhYmxlIHNpemVzOlxyXG4gICAqIGB4eHNtYWxsYCwgYHhzbWFsbGAsIGBzbWFsbGAsIGBtZWRpdW1gLCBgbGFyZ2VgXHJcbiAgICovXHJcbiAgQElucHV0KCkgc2l6ZTogc3RyaW5nO1xyXG5cclxuICAvKlxyXG4gICAqIFNlbGVjdCBzdGF0dXMgKGFkZHMgc3BlY2lmaWMgc3R5bGVzKTpcclxuICAgKiBgcHJpbWFyeWAsIGBpbmZvYCwgYHN1Y2Nlc3NgLCBgd2FybmluZ2AsIGBkYW5nZXJgXHJcbiAgICovXHJcbiAgQElucHV0KCkgc3RhdHVzOiBzdHJpbmcgPSAncHJpbWFyeSc7XHJcblxyXG4gIC8qXHJcbiAgICogU2VsZWN0IHNoYXBlczogYHJlY3RhbmdsZWAsIGByb3VuZGAsIGBzZW1pLXJvdW5kYFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHNoYXBlOiBzdHJpbmc7XHJcblxyXG4gIC8qXHJcbiAgICogQWRkcyBgaGVyb2Agc3R5bGVzXHJcbiAgICovXHJcbiAgQElucHV0KCkgaGVybzogYm9vbGVhbjtcclxuXHJcbiAgLypcclxuICAgKiBEaXNhYmxlcyB0aGUgc2VsZWN0XHJcbiAgICovXHJcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qXHJcbiAgICogSWYgc2V0IGVsZW1lbnQgd2lsbCBmaWxsIGl0cyBjb250YWluZXJcclxuICAgKi9cclxuICBASW5wdXQoKSBmdWxsV2lkdGg6IGJvb2xlYW47XHJcblxyXG4gIC8qXHJcbiAgICogQWRkcyBgb3V0bGluZWAgc3R5bGVzXHJcbiAgICovXHJcbiAgQElucHV0KCkgb3V0bGluZTogYm9vbGVhbjtcclxuXHJcbiAgLypcclxuICAgKiBSZW5kZXJzIHNlbGVjdCBwbGFjZWhvbGRlciBpZiBub3RoaW5nIHNlbGVjdGVkLlxyXG4gICAqICovXHJcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICcnO1xyXG5cclxuICAvKlxyXG4gICAqIFdpbGwgYmUgZW1pdHRlZCB3aGVuIHNlbGVjdGVkIHZhbHVlIGNoYW5nZXMuXHJcbiAgICogKi9cclxuICBAT3V0cHV0KCkgc2VsZWN0ZWRDaGFuZ2U6IEV2ZW50RW1pdHRlcjxUIHwgVFtdPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgLypcclxuICAgKiBBY2NlcHRzIHNlbGVjdGVkIGl0ZW0gb3IgYXJyYXkgb2Ygc2VsZWN0ZWQgaXRlbXMuXHJcbiAgICogKi9cclxuICBASW5wdXQoJ3NlbGVjdGVkJylcclxuICBzZXQgc2V0U2VsZWN0ZWQodmFsdWU6IFQgfCBUW10pIHtcclxuICAgIHRoaXMud3JpdGVWYWx1ZSh2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIEdpdmVzIGNhcGFiaWxpdHkganVzdCB3cml0ZSBgbXVsdGlwbGVgIG92ZXIgdGhlIGVsZW1lbnQuXHJcbiAgICogKi9cclxuICBASW5wdXQoJ211bHRpcGxlJylcclxuICBzZXQgc2V0TXVsdGlwbGUobXVsdGlwbGU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMubXVsdGlwbGUgPSBjb252ZXJ0VG9Cb29sUHJvcGVydHkobXVsdGlwbGUpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBMaXN0IG9mIGBOYk9wdGlvbkNvbXBvbmVudGAncyBjb21wb25lbnRzIHBhc3NlZCBhcyBjb250ZW50LlxyXG4gICAqIFRPRE8gbWF5YmUgaXQgd291bGQgYmUgYmV0dGVyIHByb3ZpZGUgd3JhcHBlclxyXG4gICAqICovXHJcbiAgQENvbnRlbnRDaGlsZHJlbihOYk9wdGlvbkNvbXBvbmVudCwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KSBvcHRpb25zOiBRdWVyeUxpc3Q8TmJPcHRpb25Db21wb25lbnQ8VD4+O1xyXG5cclxuICAvKlxyXG4gICAqIEN1c3RvbSBzZWxlY3QgbGFiZWwsIHdpbGwgYmUgcmVuZGVyZWQgaW5zdGVhZCBvZiBkZWZhdWx0IGVudW1lcmF0aW9uIHdpdGggY29tYS5cclxuICAgKiAqL1xyXG4gIEBDb250ZW50Q2hpbGQoTmJTZWxlY3RMYWJlbENvbXBvbmVudCkgY3VzdG9tTGFiZWw7XHJcblxyXG4gIC8qXHJcbiAgICogTmJDYXJkIHdpdGggb3B0aW9ucyBjb250ZW50LlxyXG4gICAqICovXHJcbiAgQFZpZXdDaGlsZChOYlBvcnRhbERpcmVjdGl2ZSkgcG9ydGFsOiBOYlBvcnRhbERpcmVjdGl2ZTtcclxuXHJcbiAgQFZpZXdDaGlsZChOYkJ1dHRvbkNvbXBvbmVudCwgeyByZWFkOiBFbGVtZW50UmVmIH0pIGJ1dHRvbjogRWxlbWVudFJlZjxIVE1MQnV0dG9uRWxlbWVudD47XHJcblxyXG4gIG11bHRpcGxlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8qXHJcbiAgICogTGlzdCBvZiBzZWxlY3RlZCBvcHRpb25zLlxyXG4gICAqICovXHJcbiAgc2VsZWN0aW9uTW9kZWw6IE5iT3B0aW9uQ29tcG9uZW50PFQ+W10gPSBbXTtcclxuXHJcbiAgcG9zaXRpb25TdHJhdGVneTogTmJBZGp1c3RhYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneTtcclxuXHJcbiAgLypcclxuICAgKiBDdXJyZW50IG92ZXJsYXkgcG9zaXRpb24gYmVjYXVzZSBvZiB3ZSBoYXZlIHRvIHRvZ2dsZSBvdmVybGF5UG9zaXRpb25cclxuICAgKiBpbiBbbmdDbGFzc10gZGlyZWN0aW9uIGFuZCB0aGlzIGRpcmVjdGl2ZSBjYW4gdXNlIG9ubHkgc3RyaW5nLlxyXG4gICAqL1xyXG4gIG92ZXJsYXlQb3NpdGlvbjogTmJQb3NpdGlvbiA9ICcnIGFzIE5iUG9zaXRpb247XHJcblxyXG4gIC8qXHJcbiAgICogU3RyZWFtIG9mIGV2ZW50cyB0aGF0IHdpbGwgZmlyZSB3aGVuIG9uZSBvZiB0aGUgb3B0aW9ucyBmaXJlIHNlbGVjdGlvbkNoYW5nZSBldmVudC5cclxuICAgKiAqL1xyXG4gIHNlbGVjdGlvbkNoYW5nZTogT2JzZXJ2YWJsZTxOYk9wdGlvbkNvbXBvbmVudDxUPj4gPSBkZWZlcigoKSA9PiB7XHJcbiAgICByZXR1cm4gbWVyZ2UoLi4udGhpcy5vcHRpb25zLm1hcChpdCA9PiBpdC5zZWxlY3Rpb25DaGFuZ2UpKTtcclxuICB9KTtcclxuXHJcbiAgcHJvdGVjdGVkIHJlZjogTmJPdmVybGF5UmVmO1xyXG5cclxuICBwcm90ZWN0ZWQgYWxpdmU6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAvKlxyXG4gICAqIElmIGEgdXNlciBhc3NpZ25zIHZhbHVlIGJlZm9yZSBjb250ZW50IG5iLW9wdGlvbnMncyByZW5kZXJlZCB0aGUgdmFsdWUgd2lsbCBiZSBwdXR0ZWQgaW4gdGhpcyB2YXJpYWJsZS5cclxuICAgKiBBbmQgdGhlbiBhcHBsaWVkIGFmdGVyIGNvbnRlbnQgcmVuZGVyZWQuXHJcbiAgICogT25seSB0aGUgbGFzdCB2YWx1ZSB3aWxsIGJlIGFwcGxpZWQuXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgcXVldWU6IFQgfCBUW107XHJcblxyXG4gIC8qXHJcbiAgICogRnVuY3Rpb24gcGFzc2VkIHRocm91Z2ggY29udHJvbCB2YWx1ZSBhY2Nlc3NvciB0byBwcm9wYWdhdGUgY2hhbmdlcy5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBvbkNoYW5nZTogRnVuY3Rpb24gPSAoKSA9PiB7fTtcclxuICBwcm90ZWN0ZWQgb25Ub3VjaGVkOiBGdW5jdGlvbiA9ICgpID0+IHt9O1xyXG5cclxuICBjb25zdHJ1Y3RvcihASW5qZWN0KE5CX0RPQ1VNRU5UKSBwcm90ZWN0ZWQgZG9jdW1lbnQsXHJcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIG92ZXJsYXk6IE5iT3ZlcmxheVNlcnZpY2UsXHJcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIGhvc3RSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxyXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBwb3NpdGlvbkJ1aWxkZXI6IE5iUG9zaXRpb25CdWlsZGVyU2VydmljZSxcclxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmKSB7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIERldGVybWluZXMgaXMgc2VsZWN0IG9wZW5lZC5cclxuICAgKiAqL1xyXG4gIGdldCBpc09wZW5lZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnJlZiAmJiB0aGlzLnJlZi5oYXNBdHRhY2hlZCgpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBEZXRlcm1pbmVzIGlzIHNlbGVjdCBoaWRkZW4uXHJcbiAgICogKi9cclxuICBnZXQgaXNIaWRkZW4oKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gIXRoaXMuaXNPcGVuZWQ7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFJldHVybnMgd2lkdGggb2YgdGhlIHNlbGVjdCBidXR0b24uXHJcbiAgICogKi9cclxuICBnZXQgaG9zdFdpZHRoKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5ob3N0UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIENvbnRlbnQgcmVuZGVyZWQgaW4gdGhlIGxhYmVsLlxyXG4gICAqICovXHJcbiAgZ2V0IHNlbGVjdGlvblZpZXcoKSB7XHJcbiAgICBpZiAodGhpcy5zZWxlY3Rpb25Nb2RlbC5sZW5ndGggPiAxKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnNlbGVjdGlvbk1vZGVsLm1hcCgob3B0aW9uOiBOYk9wdGlvbkNvbXBvbmVudDxUPikgPT4gb3B0aW9uLmNvbnRlbnQpLmpvaW4oJywgJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uTW9kZWxbMF0uY29udGVudDtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5jcmVhdGVPdmVybGF5KCk7XHJcbiAgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICB0aGlzLnN1YnNjcmliZU9uVHJpZ2dlcnMoKTtcclxuICAgIHRoaXMuc3Vic2NyaWJlT25Qb3NpdGlvbkNoYW5nZSgpO1xyXG4gICAgdGhpcy5zdWJzY3JpYmVPblNlbGVjdGlvbkNoYW5nZSgpO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgaWYgKHRoaXMucXVldWUpIHtcclxuICAgICAgdGhpcy53cml0ZVZhbHVlKHRoaXMucXVldWUpO1xyXG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5yZWYuZGlzcG9zZSgpO1xyXG4gIH1cclxuXHJcbiAgc2hvdygpIHtcclxuICAgIGlmICh0aGlzLmlzSGlkZGVuKSB7XHJcbiAgICAgIHRoaXMucmVmLmF0dGFjaCh0aGlzLnBvcnRhbCk7XHJcbiAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBoaWRlKCkge1xyXG4gICAgaWYgKHRoaXMuaXNPcGVuZWQpIHtcclxuICAgICAgdGhpcy5yZWYuZGV0YWNoKCk7XHJcbiAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XHJcbiAgfVxyXG5cclxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xyXG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgfVxyXG5cclxuICB3cml0ZVZhbHVlKHZhbHVlOiBUIHwgVFtdKTogdm9pZCB7XHJcbiAgICBpZiAoIXZhbHVlKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zKSB7XHJcbiAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKHZhbHVlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucXVldWUgPSB2YWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogU2VsZWN0cyBvcHRpb24gb3IgY2xlYXIgYWxsIHNlbGVjdGVkIG9wdGlvbnMgaWYgdmFsdWUgaXMgbnVsbC5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBoYW5kbGVTZWxlY3Qob3B0aW9uOiBOYk9wdGlvbkNvbXBvbmVudDxUPikge1xyXG4gICAgaWYgKG9wdGlvbi52YWx1ZSkge1xyXG4gICAgICB0aGlzLnNlbGVjdE9wdGlvbihvcHRpb24pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5yZXNldCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBEZXNlbGVjdCBhbGwgc2VsZWN0ZWQgb3B0aW9ucy5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCByZXNldCgpIHtcclxuICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwuZm9yRWFjaCgob3B0aW9uOiBOYk9wdGlvbkNvbXBvbmVudDxUPikgPT4gb3B0aW9uLmRlc2VsZWN0KCkpO1xyXG4gICAgdGhpcy5zZWxlY3Rpb25Nb2RlbCA9IFtdO1xyXG4gICAgdGhpcy5oaWRlKCk7XHJcbiAgICB0aGlzLmJ1dHRvbi5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XHJcbiAgICB0aGlzLmVtaXRTZWxlY3RlZChudWxsKTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogRGV0ZXJtaW5lcyBob3cgdG8gc2VsZWN0IG9wdGlvbiBhcyBtdWx0aXBsZSBvciBzaW5nbGUuXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgc2VsZWN0T3B0aW9uKG9wdGlvbjogTmJPcHRpb25Db21wb25lbnQ8VD4pIHtcclxuICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlTXVsdGlwbGVTZWxlY3Qob3B0aW9uKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlU2luZ2xlU2VsZWN0KG9wdGlvbik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFNlbGVjdCBzaW5nbGUgb3B0aW9uLlxyXG4gICAqICovXHJcbiAgcHJvdGVjdGVkIGhhbmRsZVNpbmdsZVNlbGVjdChvcHRpb246IE5iT3B0aW9uQ29tcG9uZW50PFQ+KSB7XHJcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0aW9uTW9kZWwucG9wKCk7XHJcblxyXG4gICAgaWYgKHNlbGVjdGVkICYmIHNlbGVjdGVkICE9PSBvcHRpb24pIHtcclxuICAgICAgc2VsZWN0ZWQuZGVzZWxlY3QoKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnNlbGVjdGlvbk1vZGVsID0gW29wdGlvbl07XHJcbiAgICBvcHRpb24uc2VsZWN0KCk7XHJcbiAgICB0aGlzLmhpZGUoKTtcclxuICAgIHRoaXMuYnV0dG9uLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuXHJcbiAgICB0aGlzLmVtaXRTZWxlY3RlZChvcHRpb24udmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBTZWxlY3QgZm9yIG11bHRpcGxlIG9wdGlvbnMuXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgaGFuZGxlTXVsdGlwbGVTZWxlY3Qob3B0aW9uOiBOYk9wdGlvbkNvbXBvbmVudDxUPikge1xyXG4gICAgaWYgKG9wdGlvbi5zZWxlY3RlZCkge1xyXG4gICAgICB0aGlzLnNlbGVjdGlvbk1vZGVsID0gdGhpcy5zZWxlY3Rpb25Nb2RlbC5maWx0ZXIocyA9PiBzLnZhbHVlICE9PSBvcHRpb24udmFsdWUpO1xyXG4gICAgICBvcHRpb24uZGVzZWxlY3QoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0aW9uTW9kZWwucHVzaChvcHRpb24pO1xyXG4gICAgICBvcHRpb24uc2VsZWN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5lbWl0U2VsZWN0ZWQodGhpcy5zZWxlY3Rpb25Nb2RlbC5tYXAoKG9wdDogTmJPcHRpb25Db21wb25lbnQ8VD4pID0+IG9wdC52YWx1ZSkpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZU92ZXJsYXkoKSB7XHJcbiAgICBjb25zdCBzY3JvbGxTdHJhdGVneSA9IHRoaXMuY3JlYXRlU2Nyb2xsU3RyYXRlZ3koKTtcclxuICAgIHRoaXMucG9zaXRpb25TdHJhdGVneSA9IHRoaXMuY3JlYXRlUG9zaXRpb25TdHJhdGVneSgpO1xyXG4gICAgdGhpcy5yZWYgPSB0aGlzLm92ZXJsYXkuY3JlYXRlKHsgcG9zaXRpb25TdHJhdGVneTogdGhpcy5wb3NpdGlvblN0cmF0ZWd5LCBzY3JvbGxTdHJhdGVneSB9KTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjcmVhdGVQb3NpdGlvblN0cmF0ZWd5KCk6IE5iQWRqdXN0YWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3kge1xyXG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25CdWlsZGVyXHJcbiAgICAgIC5jb25uZWN0ZWRUbyh0aGlzLmhvc3RSZWYpXHJcbiAgICAgIC5wb3NpdGlvbih