ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
332 lines • 38 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { BACKSPACE } from '@angular/cdk/keycodes';
import { NgFor, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, Host, Input, Optional, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { NzSelectItemComponent } from './select-item.component';
import { NzSelectPlaceholderComponent } from './select-placeholder.component';
import { NzSelectSearchComponent } from './select-search.component';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/core/no-animation";
export class NzSelectTopControlComponent {
updateTemplateVariable() {
const isSelectedValueEmpty = this.listOfTopItem.length === 0;
this.isShowPlaceholder = isSelectedValueEmpty && !this.isComposing && !this.inputValue;
this.isShowSingleLabel = !isSelectedValueEmpty && !this.isComposing && !this.inputValue;
}
isComposingChange(isComposing) {
this.isComposing = isComposing;
this.updateTemplateVariable();
}
onInputValueChange(value) {
if (value !== this.inputValue) {
this.inputValue = value;
this.updateTemplateVariable();
this.inputValueChange.emit(value);
this.tokenSeparate(value, this.tokenSeparators);
}
}
tokenSeparate(inputValue, tokenSeparators) {
const includesSeparators = (str, separators) => {
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < separators.length; ++i) {
if (str.lastIndexOf(separators[i]) > 0) {
return true;
}
}
return false;
};
const splitBySeparators = (str, separators) => {
const reg = new RegExp(`[${separators.join()}]`);
const array = str.split(reg).filter(token => token);
return [...new Set(array)];
};
if (inputValue &&
inputValue.length &&
tokenSeparators.length &&
this.mode !== 'default' &&
includesSeparators(inputValue, tokenSeparators)) {
const listOfLabel = splitBySeparators(inputValue, tokenSeparators);
this.tokenize.next(listOfLabel);
}
}
clearInputValue() {
if (this.nzSelectSearchComponent) {
this.nzSelectSearchComponent.clearInputValue();
}
}
focus() {
if (this.nzSelectSearchComponent) {
this.nzSelectSearchComponent.focus();
}
}
blur() {
if (this.nzSelectSearchComponent) {
this.nzSelectSearchComponent.blur();
}
}
trackValue(_index, option) {
return option.nzValue;
}
onDeleteItem(item) {
if (!this.disabled && !item.nzDisabled) {
this.deleteItem.next(item);
}
}
constructor(elementRef, ngZone, noAnimation) {
this.elementRef = elementRef;
this.ngZone = ngZone;
this.noAnimation = noAnimation;
this.nzId = null;
this.showSearch = false;
this.placeHolder = null;
this.open = false;
this.maxTagCount = Infinity;
this.autofocus = false;
this.disabled = false;
this.mode = 'default';
this.customTemplate = null;
this.maxTagPlaceholder = null;
this.removeIcon = null;
this.listOfTopItem = [];
this.tokenSeparators = [];
this.tokenize = new EventEmitter();
this.inputValueChange = new EventEmitter();
this.deleteItem = new EventEmitter();
this.listOfSlicedItem = [];
this.isShowPlaceholder = true;
this.isShowSingleLabel = false;
this.isComposing = false;
this.inputValue = null;
this.destroy$ = new Subject();
}
ngOnChanges(changes) {
const { listOfTopItem, maxTagCount, customTemplate, maxTagPlaceholder } = changes;
if (listOfTopItem) {
this.updateTemplateVariable();
}
if (listOfTopItem || maxTagCount || customTemplate || maxTagPlaceholder) {
const listOfSlicedItem = this.listOfTopItem.slice(0, this.maxTagCount).map(o => ({
nzLabel: o.nzLabel,
nzValue: o.nzValue,
nzDisabled: o.nzDisabled,
contentTemplateOutlet: this.customTemplate,
contentTemplateOutletContext: o
}));
if (this.listOfTopItem.length > this.maxTagCount) {
const exceededLabel = `+ ${this.listOfTopItem.length - this.maxTagCount} ...`;
const listOfSelectedValue = this.listOfTopItem.map(item => item.nzValue);
const exceededItem = {
nzLabel: exceededLabel,
nzValue: '$$__nz_exceeded_item',
nzDisabled: true,
contentTemplateOutlet: this.maxTagPlaceholder,
contentTemplateOutletContext: listOfSelectedValue.slice(this.maxTagCount)
};
listOfSlicedItem.push(exceededItem);
}
this.listOfSlicedItem = listOfSlicedItem;
}
}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
fromEvent(this.elementRef.nativeElement, 'click')
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
// `HTMLElement.focus()` is a native DOM API which doesn't require Angular to run change detection.
if (event.target !== this.nzSelectSearchComponent.inputElement.nativeElement) {
this.nzSelectSearchComponent.focus();
}
});
fromEvent(this.elementRef.nativeElement, 'keydown')
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
if (event.target instanceof HTMLInputElement) {
const inputValue = event.target.value;
if (event.keyCode === BACKSPACE &&
this.mode !== 'default' &&
!inputValue &&
this.listOfTopItem.length > 0) {
event.preventDefault();
// Run change detection only if the user has pressed the `Backspace` key and the following condition is met.
this.ngZone.run(() => this.onDeleteItem(this.listOfTopItem[this.listOfTopItem.length - 1]));
}
}
});
});
}
ngOnDestroy() {
this.destroy$.next();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: NzSelectTopControlComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i1.NzNoAnimationDirective, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: NzSelectTopControlComponent, isStandalone: true, selector: "nz-select-top-control", inputs: { nzId: "nzId", showSearch: "showSearch", placeHolder: "placeHolder", open: "open", maxTagCount: "maxTagCount", autofocus: "autofocus", disabled: "disabled", mode: "mode", customTemplate: "customTemplate", maxTagPlaceholder: "maxTagPlaceholder", removeIcon: "removeIcon", listOfTopItem: "listOfTopItem", tokenSeparators: "tokenSeparators" }, outputs: { tokenize: "tokenize", inputValueChange: "inputValueChange", deleteItem: "deleteItem" }, host: { classAttribute: "ant-select-selector" }, viewQueries: [{ propertyName: "nzSelectSearchComponent", first: true, predicate: NzSelectSearchComponent, descendants: true }], exportAs: ["nzSelectTopControl"], usesOnChanges: true, ngImport: i0, template: `
<!--single mode-->
<ng-container [ngSwitch]="mode">
<ng-container *ngSwitchCase="'default'">
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[showInput]="showSearch"
[mirrorSync]="false"
[autofocus]="autofocus"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
<nz-select-item
*ngIf="isShowSingleLabel"
[deletable]="false"
[disabled]="false"
[removeIcon]="removeIcon"
[label]="listOfTopItem[0].nzLabel"
[contentTemplateOutlet]="customTemplate"
[contentTemplateOutletContext]="listOfTopItem[0]"
></nz-select-item>
</ng-container>
<ng-container *ngSwitchDefault>
<!--multiple or tags mode-->
<nz-select-item
*ngFor="let item of listOfSlicedItem; trackBy: trackValue"
[removeIcon]="removeIcon"
[label]="item.nzLabel"
[disabled]="item.nzDisabled || disabled"
[contentTemplateOutlet]="item.contentTemplateOutlet"
[deletable]="true"
[contentTemplateOutletContext]="item.contentTemplateOutletContext"
(delete)="onDeleteItem(item.contentTemplateOutletContext)"
></nz-select-item>
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[autofocus]="autofocus"
[showInput]="true"
[mirrorSync]="true"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
</ng-container>
</ng-container>
<nz-select-placeholder *ngIf="isShowPlaceholder" [placeholder]="placeHolder"></nz-select-placeholder>
`, isInline: true, dependencies: [{ kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "component", type: NzSelectSearchComponent, selector: "nz-select-search", inputs: ["nzId", "disabled", "mirrorSync", "showInput", "focusTrigger", "value", "autofocus"], outputs: ["valueChange", "isComposingChange"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: NzSelectItemComponent, selector: "nz-select-item", inputs: ["disabled", "label", "deletable", "removeIcon", "contentTemplateOutletContext", "contentTemplateOutlet"], outputs: ["delete"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NzSelectPlaceholderComponent, selector: "nz-select-placeholder", inputs: ["placeholder"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: NzSelectTopControlComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-select-top-control',
exportAs: 'nzSelectTopControl',
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
template: `
<!--single mode-->
<ng-container [ngSwitch]="mode">
<ng-container *ngSwitchCase="'default'">
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[showInput]="showSearch"
[mirrorSync]="false"
[autofocus]="autofocus"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
<nz-select-item
*ngIf="isShowSingleLabel"
[deletable]="false"
[disabled]="false"
[removeIcon]="removeIcon"
[label]="listOfTopItem[0].nzLabel"
[contentTemplateOutlet]="customTemplate"
[contentTemplateOutletContext]="listOfTopItem[0]"
></nz-select-item>
</ng-container>
<ng-container *ngSwitchDefault>
<!--multiple or tags mode-->
<nz-select-item
*ngFor="let item of listOfSlicedItem; trackBy: trackValue"
[removeIcon]="removeIcon"
[label]="item.nzLabel"
[disabled]="item.nzDisabled || disabled"
[contentTemplateOutlet]="item.contentTemplateOutlet"
[deletable]="true"
[contentTemplateOutletContext]="item.contentTemplateOutletContext"
(delete)="onDeleteItem(item.contentTemplateOutletContext)"
></nz-select-item>
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[autofocus]="autofocus"
[showInput]="true"
[mirrorSync]="true"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
</ng-container>
</ng-container>
<nz-select-placeholder *ngIf="isShowPlaceholder" [placeholder]="placeHolder"></nz-select-placeholder>
`,
host: { class: 'ant-select-selector' },
imports: [
NgSwitch,
NzSelectSearchComponent,
NgSwitchCase,
NzSelectItemComponent,
NgIf,
NgSwitchDefault,
NgFor,
NzSelectPlaceholderComponent
],
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i1.NzNoAnimationDirective, decorators: [{
type: Host
}, {
type: Optional
}] }], propDecorators: { nzId: [{
type: Input
}], showSearch: [{
type: Input
}], placeHolder: [{
type: Input
}], open: [{
type: Input
}], maxTagCount: [{
type: Input
}], autofocus: [{
type: Input
}], disabled: [{
type: Input
}], mode: [{
type: Input
}], customTemplate: [{
type: Input
}], maxTagPlaceholder: [{
type: Input
}], removeIcon: [{
type: Input
}], listOfTopItem: [{
type: Input
}], tokenSeparators: [{
type: Input
}], tokenize: [{
type: Output
}], inputValueChange: [{
type: Output
}], deleteItem: [{
type: Output
}], nzSelectSearchComponent: [{
type: ViewChild,
args: [NzSelectSearchComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LXRvcC1jb250cm9sLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvc2VsZWN0L3NlbGVjdC10b3AtY29udHJvbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkYsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBRVQsWUFBWSxFQUNaLElBQUksRUFDSixLQUFLLEVBS0wsUUFBUSxFQUNSLE1BQU0sRUFHTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUszQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBMEVwRSxNQUFNLE9BQU8sMkJBQTJCO0lBMEJ0QyxzQkFBc0I7UUFDcEIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLGlCQUFpQixHQUFHLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDdkYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsb0JBQW9CLElBQUksQ0FB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ZUFBZTt3QkFDZixLQUFLO3dCQUNMLDRCQUE0QjtxQkFDN0I7b0JBQ0QsVUFBVSxFQUFFLElBQUk7aUJBQ2pCOzswQkF5R0ksSUFBSTs7MEJBQUksUUFBUTt5Q0F2R1YsSUFBSTtzQkFBWixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNhLFFBQVE7c0JBQTFCLE1BQU07Z0JBQ1ksZ0JBQWdCO3NCQUFsQyxNQUFNO2dCQUNZLFVBQVU7c0JBQTVCLE1BQU07Z0JBQzZCLHVCQUF1QjtzQkFBMUQsU0FBUzt1QkFBQyx1QkFBdUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBCQUNLU1BBQ0UgfSBmcm9tICdAYW5ndWxhci9jZGsva2V5Y29kZXMnO1xuaW1wb3J0IHsgTmdGb3IsIE5nSWYsIE5nU3dpdGNoLCBOZ1N3aXRjaENhc2UsIE5nU3dpdGNoRGVmYXVsdCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56Tm9BbmltYXRpb25EaXJlY3RpdmUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvbm8tYW5pbWF0aW9uJztcbmltcG9ydCB7IE56U2FmZUFueSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5cbmltcG9ydCB7IE56U2VsZWN0SXRlbUNvbXBvbmVudCB9IGZyb20gJy4vc2VsZWN0LWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7IE56U2VsZWN0UGxhY2Vob2xkZXJDb21wb25lbnQgfSBmcm9tICcuL3NlbGVjdC1wbGFjZWhvbGRlci5jb21wb25lbnQnO1xuaW1wb3J0IHsgTnpTZWxlY3RTZWFyY2hDb21wb25lbnQgfSBmcm9tICcuL3NlbGVjdC1zZWFyY2guY29tcG9uZW50JztcbmltcG9ydCB7IE56U2VsZWN0SXRlbUludGVyZmFjZSwgTnpTZWxlY3RNb2RlVHlwZSwgTnpTZWxlY3RUb3BDb250cm9sSXRlbVR5cGUgfSBmcm9tICcuL3NlbGVjdC50eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LXNlbGVjdC10b3AtY29udHJvbCcsXG4gIGV4cG9ydEFzOiAnbnpTZWxlY3RUb3BDb250cm9sJyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICB0ZW1wbGF0ZTogYFxuICAgIDwhLS1zaW5nbGUgbW9kZS0tPlxuICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cIm1vZGVcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidkZWZhdWx0J1wiPlxuICAgICAgICA8bnotc2VsZWN0LXNlYXJjaFxuICAgICAgICAgIFtueklkXT1cIm56SWRcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgW3ZhbHVlXT1cImlucHV0VmFsdWUhXCJcbiAgICAgICAgICBbc2hvd0lucHV0XT1cInNob3dTZWFyY2hcIlxuICAgICAgICAgIFttaXJyb3JTeW5jXT1cImZhbHNlXCJcbiAgICAgICAgICBbYXV0b2ZvY3VzXT1cImF1dG9mb2N1c1wiXG4gICAgICAgICAgW2ZvY3VzVHJpZ2dlcl09XCJvcGVuXCJcbiAgICAgICAgICAoaXNDb21wb3NpbmdDaGFuZ2UpPVwiaXNDb21wb3NpbmdDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uSW5wdXRWYWx1ZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgPjwvbnotc2VsZWN0LXNlYXJjaD5cbiAgICAgICAgPG56LXNlbGVjdC1pdGVtXG4gICAgICAgICAgKm5nSWY9XCJpc1Nob3dTaW5nbGVMYWJlbFwiXG4gICAgICAgICAgW2RlbGV0YWJsZV09XCJmYWxzZVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImZhbHNlXCJcbiAgICAgICAgICBbcmVtb3ZlSWNvbl09XCJyZW1vdmVJY29uXCJcbiAgICAgICAgICBbbGFiZWxdPVwibGlzdE9mVG9wSXRlbVswXS5uekxhYmVsXCJcbiAgICAgICAgICBbY29udGVudFRlbXBsYXRlT3V0bGV0XT1cImN1c3RvbVRlbXBsYXRlXCJcbiAgICAgICAgICBbY29udGVudFRlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJsaXN0T2ZUb3BJdGVtWzBdXCJcbiAgICAgICAgPjwvbnotc2VsZWN0LWl0ZW0+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoRGVmYXVsdD5cbiAgICAgICAgPCEtLW11bHRpcGxlIG9yIHRhZ3MgbW9kZS0tPlxuICAgICAgICA8bnotc2VsZWN0LWl0ZW1cbiAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBsaXN0T2ZTbGljZWRJdGVtOyB0cmFja0J5OiB0cmFja1ZhbHVlXCJcbiAgICAgICAgICBbcmVtb3ZlSWNvbl09XCJyZW1vdmVJY29uXCJcbiAgICAgICAgICBbbGFiZWxdPVwiaXRlbS5uekxhYmVsXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiaXRlbS5uekRpc2FibGVkIHx8IGRpc2FibGVkXCJcbiAgICAgICAgICBbY29udGVudFRlbXBsYXRlT3V0bGV0XT1cIml0ZW0uY29udGVudFRlbXBsYXRlT3V0bGV0XCJcbiAgICAgICAgICBbZGVsZXRhYmxlXT1cInRydWVcIlxuICAgICAgICAgIFtjb250ZW50VGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIml0ZW0uY29udGVudFRlbXBsYXRlT3V0bGV0Q29udGV4dFwiXG4gICAgICAgICAgKGRlbGV0ZSk9XCJvbkRlbGV0ZUl0ZW0oaXRlbS5jb250ZW50VGVtcGxhdGVPdXRsZXRDb250ZXh0KVwiXG4gICAgICAgID48L256LXNlbGVjdC1pdGVtPlxuICAgICAgICA8bnotc2VsZWN0LXNlYXJjaFxuICAgICAgICAgIFtueklkXT1cIm56SWRcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgW3ZhbHVlXT1cImlucHV0VmFsdWUhXCJcbiAgICAgICAgICBbYXV0b2ZvY3VzXT1cImF1dG9mb2N1c1wiXG4gICAgICAgICAgW3Nob3dJbnB1dF09XCJ0cnVlXCJcbiAgICAgICAgICBbbWlycm9yU3luY109XCJ0cnVlXCJcbiAgICAgICAgICBbZm9jdXNUcmlnZ2VyXT1cIm9wZW5cIlxuICAgICAgICAgIChpc0NvbXBvc2luZ0NoYW5nZSk9XCJpc0NvbXBvc2luZ0NoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwib25JbnB1dFZhbHVlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICA+PC9uei1zZWxlY3Qtc2VhcmNoPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG56LXNlbGVjdC1wbGFjZWhvbGRlciAqbmdJZj1cImlzU2hvd1BsYWNlaG9sZGVyXCIgW3BsYWNlaG9sZGVyXT1cInBsYWNlSG9sZGVyXCI+PC9uei1zZWxlY3QtcGxhY2Vob2xkZXI+XG4gIGAsXG4gIGhvc3Q6IHsgY2xhc3M6ICdhbnQtc2VsZWN0LXNlbGVjdG9yJyB9LFxuICBpbXBvcnRzOiBbXG4gICAgTmdTd2l0Y2gsXG4gICAgTnpTZWxlY3RTZWFyY2hDb21wb25lbnQsXG4gICAgTmdTd2l0Y2hDYXNlLFxuICAgIE56U2VsZWN0SXRlbUNvbXBvbmVudCxcbiAgICBOZ0lmLFxuICAgIE5nU3dpdGNoRGVmYXVsdCxcbiAgICBOZ0ZvcixcbiAgICBOelNlbGVjdFBsYWNlaG9sZGVyQ29tcG9uZW50XG4gIF0sXG4gIHN0YW5kYWxvbmU6IHRydWVcbn0pXG5leHBvcnQgY2xhc3MgTnpTZWxlY3RUb3BDb250cm9sQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIG56SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBzaG93U2VhcmNoID0gZmFsc2U7XG4gIEBJbnB1dCgpIHBsYWNlSG9sZGVyOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxOelNhZmVBbnk+IHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIG9wZW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWF4VGFnQ291bnQ6IG51bWJlciA9IEluZmluaXR5O1xuICBASW5wdXQoKSBhdXRvZm9jdXMgPSBmYWxzZTtcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgbW9kZTogTnpTZWxlY3RNb2RlVHlwZSA9ICdkZWZhdWx0JztcbiAgQElucHV0KCkgY3VzdG9tVGVtcGxhdGU6IFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBOelNlbGVjdEl0ZW1JbnRlcmZhY2UgfT4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgbWF4VGFnUGxhY2Vob2xkZXI6IFRlbXBsYXRlUmVmPHsgJGltcGxpY2l0OiBOelNhZmVBbnlbXSB9PiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSByZW1vdmVJY29uOiBUZW1wbGF0ZVJlZjxOelNhZmVBbnk+IHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIGxpc3RPZlRvcEl0ZW06IE56U2VsZWN0SXRlbUludGVyZmFjZVtdID0gW107XG4gIEBJbnB1dCgpIHRva2VuU2VwYXJhdG9yczogc3RyaW5nW10gPSBbXTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IHRva2VuaXplID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmdbXT4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGlucHV0VmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGRlbGV0ZUl0ZW0gPSBuZXcgRXZlbnRFbWl0dGVyPE56U2VsZWN0SXRlbUludGVyZmFjZT4oKTtcbiAgQFZpZXdDaGlsZChOelNlbGVjdFNlYXJjaENvbXBvbmVudCkgbnpTZWxlY3RTZWFyY2hDb21wb25lbnQhOiBOelNlbGVjdFNlYXJjaENvbXBvbmVudDtcbiAgbGlzdE9mU2xpY2VkSXRlbTogTnpTZWxlY3RUb3BDb250cm9sSXRlbVR5cGVbXSA9IFtdO1xuICBpc1Nob3dQbGFjZWhvbGRlciA9IHRydWU7XG4gIGlzU2hvd1NpbmdsZUxhYmVsID0gZmFsc2U7XG4gIGlzQ29tcG9zaW5nID0gZmFsc2U7XG4gIGlucHV0VmFsdWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHVwZGF0ZVRlbXBsYXRlVmFyaWFibGUoKTogdm9pZCB7XG4gICAgY29uc3QgaXNTZWxlY3RlZFZhbHVlRW1wdHkgPSB0aGlzLmxpc3RPZlRvcEl0ZW0ubGVuZ3RoID09PSAwO1xuICAgIHRoaXMuaXNTaG93UGxhY2Vob2xkZXIgPSBpc1NlbGVjdGVkVmFsdWVFbXB0eSAmJiAhdGhpcy5pc0NvbXBvc2luZyAmJiAhdGhpcy5pbnB1dFZhbHVlO1xuICAgIHRoaXMuaXNTaG93U2luZ2xlTGFiZWwgPSAhaXNTZWxlY3RlZFZhbHVlRW1wdHkgJiYgIXRoaXMuaXNDb21wb3NpbmcgJiYgIXRoaXMuaW5wdXRWYWx1ZTtcbiAgfVxuXG4gIGlzQ29tcG9zaW5nQ2hhbmdlKGlzQ29tcG9zaW5nOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5pc0NvbXBvc2luZyA9IGlzQ29tcG9zaW5nO1xuICAgIHRoaXMudXBkYXRlVGVtcGxhdGVWYXJpYWJsZSgpO1xuICB9XG5cbiAgb25JbnB1dFZhbHVlQ2hhbmdlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUgIT09IHRoaXMuaW5wdXRWYWx1ZSkge1xuICAgICAgdGhpcy5pbnB1dFZhbHVlID0gdmFsdWU7XG4gICAgICB0aGlzLnVwZGF0ZVRlbXBsYXRlVmFyaWFibGUoKTtcbiAgICAgIHRoaXMuaW5wdXRWYWx1ZUNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgICAgIHRoaXMudG9rZW5TZXBhcmF0ZSh2YWx1ZSwgdGhpcy50b2tlblNlcGFyYXRvcnMpO1xuICAgIH1cbiAgfVxuXG4gIHRva2VuU2VwYXJhdGUoaW5wdXRWYWx1ZTogc3RyaW5nLCB0b2tlblNlcGFyYXRvcnM6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgY29uc3QgaW5jbHVkZXNTZXBhcmF0b3JzID0gKHN0cjogc3RyaW5nLCBzZXBhcmF0b3JzOiBzdHJpbmdbXSk6IGJvb2xlYW4gPT4ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9wcmVmZXItZm9yLW9mXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlcGFyYXRvcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKHN0ci5sYXN0SW5kZXhPZihzZXBhcmF0b3JzW2ldKSA+IDApIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgY29uc3Qgc3BsaXRCeVNlcGFyYXRvcnMgPSAoc3RyOiBzdHJpbmcsIHNlcGFyYXRvcnM6IHN0cmluZ1tdKTogc3RyaW5nW10gPT4ge1xuICAgICAgY29uc3QgcmVnID0gbmV3IFJlZ0V4cChgWyR7c2VwYXJhdG9ycy5qb2luKCl9XWApO1xuICAgICAgY29uc3QgYXJyYXkgPSBzdHIuc3BsaXQocmVnKS5maWx0ZXIodG9rZW4gPT4gdG9rZW4pO1xuICAgICAgcmV0dXJuIFsuLi5uZXcgU2V0KGFycmF5KV07XG4gICAgfTtcbiAgICBpZiAoXG4gICAgICBpbnB1dFZhbHVlICYmXG4gICAgICBpbnB1dFZhbHVlLmxlbmd0aCAmJlxuICAgICAgdG9rZW5TZXBhcmF0b3JzLmxlbmd0aCAmJlxuICAgICAgdGhpcy5tb2RlICE9PSAnZGVmYXVsdCcgJiZcbiAgICAgIGluY2x1ZGVzU2VwYXJhdG9ycyhpbnB1dFZhbHVlLCB0b2tlblNlcGFyYXRvcnMpXG4gICAgKSB7XG4gICAgICBjb25zdCBsaXN0T2ZMYWJlbCA9IHNwbGl0QnlTZXBhcmF0b3JzKGlucHV0VmFsdWUsIHRva2VuU2VwYXJhdG9ycyk7XG4gICAgICB0aGlzLnRva2VuaXplLm5leHQobGlzdE9mTGFiZWwpO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFySW5wdXRWYWx1ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5uelNlbGVjdFNlYXJjaENvbXBvbmVudCkge1xuICAgICAgdGhpcy5uelNlbGVjdFNlYXJjaENvbXBvbmVudC5jbGVhcklucHV0VmFsdWUoKTtcbiAgICB9XG4gIH1cblxuICBmb2N1cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5uelNlbGVjdFNlYXJjaENvbXBvbmVudCkge1xuICAgICAgdGhpcy5uelNlbGVjdFNlYXJjaENvbXBvbmVudC5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIGJsdXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQpIHtcbiAgICAgIHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQuYmx1cigpO1xuICAgIH1cbiAgfVxuXG4gIHRyYWNrVmFsdWUoX2luZGV4OiBudW1iZXIsIG9wdGlvbjogTnpTZWxlY3RUb3BDb250cm9sSXRlbVR5cGUpOiBOelNhZmVBbnkge1xuICAgIHJldHVybiBvcHRpb24ubnpWYWx1ZTtcbiAgfVxuXG4gIG9uRGVsZXRlSXRlbShpdGVtOiBOelNlbGVjdEl0ZW1JbnRlcmZhY2UpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQgJiYgIWl0ZW0ubnpEaXNhYmxlZCkge1xuICAgICAgdGhpcy5kZWxldGVJdGVtLm5leHQoaXRlbSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIEBIb3N0KCkgQE9wdGlvbmFsKCkgcHVibGljIG5vQW5pbWF0aW9uOiBOek5vQW5pbWF0aW9uRGlyZWN0aXZlIHwgbnVsbFxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgbGlzdE9mVG9wSXRlbSwgbWF4VGFnQ291bnQsIGN1c3RvbVRlbXBsYXRlLCBtYXhUYWdQbGFjZWhvbGRlciB9ID0gY2hhbmdlcztcbiAgICBpZiAobGlzdE9mVG9wSXRlbSkge1xuICAgICAgdGhpcy51cGRhdGVUZW1wbGF0ZVZhcmlhYmxlKCk7XG4gICAgfVxuICAgIGlmIChsaXN0T2ZUb3BJdGVtIHx8IG1heFRhZ0NvdW50IHx8IGN1c3RvbVRlbXBsYXRlIHx8IG1heFRhZ1BsYWNlaG9sZGVyKSB7XG4gICAgICBjb25zdCBsaXN0T2ZTbGljZWRJdGVtOiBOelNlbGVjdFRvcENvbnRyb2xJdGVtVHlwZVtdID0gdGhpcy5saXN0T2ZUb3BJdGVtLnNsaWNlKDAsIHRoaXMubWF4VGFnQ291bnQpLm1hcChvID0+ICh7XG4gICAgICAgIG56TGFiZWw6IG8ubnpMYWJlbCxcbiAgICAgICAgbnpWYWx1ZTogby5uelZhbHVlLFxuICAgICAgICBuekRpc2FibGVkOiBvLm56RGlzYWJsZWQsXG4gICAgICAgIGNvbnRlbnRUZW1wbGF0ZU91dGxldDogdGhpcy5jdXN0b21UZW1wbGF0ZSxcbiAgICAgICAgY29udGVudFRlbXBsYXRlT3V0bGV0Q29udGV4dDogb1xuICAgICAgfSkpO1xuICAgICAgaWYgKHRoaXMubGlzdE9mVG9wSXRlbS5sZW5ndGggPiB0aGlzLm1heFRhZ0NvdW50KSB7XG4gICAgICAgIGNvbnN0IGV4Y2VlZGVkTGFiZWwgPSBgKyAke3RoaXMubGlzdE9mVG9wSXRlbS5sZW5ndGggLSB0aGlzLm1heFRhZ0NvdW50fSAuLi5gO1xuICAgICAgICBjb25zdCBsaXN0T2ZTZWxlY3RlZFZhbHVlID0gdGhpcy5saXN0T2ZUb3BJdGVtLm1hcChpdGVtID0+IGl0ZW0ubnpWYWx1ZSk7XG4gICAgICAgIGNvbnN0IGV4Y2VlZGVkSXRlbSA9IHtcbiAgICAgICAgICBuekxhYmVsOiBleGNlZWRlZExhYmVsLFxuICAgICAgICAgIG56VmFsdWU6ICckJF9fbnpfZXhjZWVkZWRfaXRlbScsXG4gICAgICAgICAgbnpEaXNhYmxlZDogdHJ1ZSxcbiAgICAgICAgICBjb250ZW50VGVtcGxhdGVPdXRsZXQ6IHRoaXMubWF4VGFnUGxhY2Vob2xkZXIsXG4gICAgICAgICAgY29udGVudFRlbXBsYXRlT3V0bGV0Q29udGV4dDogbGlzdE9mU2VsZWN0ZWRWYWx1ZS5zbGljZSh0aGlzLm1heFRhZ0NvdW50KVxuICAgICAgICB9O1xuICAgICAgICBsaXN0T2ZTbGljZWRJdGVtLnB1c2goZXhjZWVkZWRJdGVtKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubGlzdE9mU2xpY2VkSXRlbSA9IGxpc3RPZlNsaWNlZEl0ZW07XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnY2xpY2snKVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgICAgIC8vIGBIVE1MRWxlbWVudC5mb2N1cygpYCBpcyBhIG5hdGl2ZSBET00gQVBJIHdoaWNoIGRvZXNuJ3QgcmVxdWlyZSBBbmd1bGFyIHRvIHJ1biBjaGFuZ2UgZGV0ZWN0aW9uLlxuICAgICAgICAgIGlmIChldmVudC50YXJnZXQgIT09IHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQuZm9jdXMoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICBmcm9tRXZlbnQ8S2V5Ym9hcmRFdmVudD4odGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdrZXlkb3duJylcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgICAgICBpZiAoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xuICAgICAgICAgICAgY29uc3QgaW5wdXRWYWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZTtcblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBldmVudC5rZXlDb2RlID09PSBCQUNLU1BBQ0UgJiZcbiAgICAgICAgICAgICAgdGhpcy5tb2RlICE9PSAnZGVmYXVsdCcgJiZcbiAgICAgICAgICAgICAgIWlucHV0VmFsdWUgJiZcbiAgICAgICAgICAgICAgdGhpcy5saXN0T2ZUb3BJdGVtLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAvLyBSdW4gY2hhbmdlIGRldGVjdGlvbiBvbmx5IGlmIHRoZSB1c2VyIGhhcyBwcmVzc2VkIHRoZSBgQmFja3NwYWNlYCBrZXkgYW5kIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uIGlzIG1ldC5cbiAgICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMub25EZWxldGVJdGVtKHRoaXMubGlzdE9mVG9wSXRlbVt0aGlzLmxpc3RPZlRvcEl0ZW0ubGVuZ3RoIC0gMV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gIH1cbn1cbiJdfQ==