ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
481 lines • 53.3 kB
JavaScript
import { __decorate } from "tslib";
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Optional, Output, ViewChildren, ViewEncapsulation } from '@angular/core';
import { of as observableOf, of, Subject } from 'rxjs';
import { distinctUntilChanged, map, takeUntil, withLatestFrom } from 'rxjs/operators';
import { getStatusClassNames, InputBoolean, toArray } from 'ng-zorro-antd/core/util';
import { NzTransferListComponent } from './transfer-list.component';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/i18n";
import * as i2 from "@angular/cdk/bidi";
import * as i3 from "ng-zorro-antd/core/form";
import * as i4 from "@angular/common";
import * as i5 from "ng-zorro-antd/button";
import * as i6 from "ng-zorro-antd/core/transition-patch";
import * as i7 from "ng-zorro-antd/core/wave";
import * as i8 from "ng-zorro-antd/icon";
import * as i9 from "./transfer-list.component";
export class NzTransferComponent {
// #endregion
constructor(cdr, i18n, elementRef, renderer, directionality, nzFormStatusService, nzFormNoStatusService) {
this.cdr = cdr;
this.i18n = i18n;
this.elementRef = elementRef;
this.renderer = renderer;
this.directionality = directionality;
this.nzFormStatusService = nzFormStatusService;
this.nzFormNoStatusService = nzFormNoStatusService;
this.unsubscribe$ = new Subject();
this.leftFilter = '';
this.rightFilter = '';
this.dir = 'ltr';
// status
this.prefixCls = 'ant-transfer';
this.statusCls = {};
this.hasFeedback = false;
// #region fields
this.nzDisabled = false;
this.nzDataSource = [];
this.nzTitles = ['', ''];
this.nzOperations = [];
this.nzListStyle = {};
this.nzShowSelectAll = true;
this.nzCanMove = (arg) => of(arg.list);
this.nzRenderList = null;
this.nzRender = null;
this.nzFooter = null;
this.nzShowSearch = false;
this.nzTargetKeys = [];
this.nzSelectedKeys = [];
this.nzStatus = '';
// events
this.nzChange = new EventEmitter();
this.nzSearchChange = new EventEmitter();
this.nzSelectChange = new EventEmitter();
// #endregion
// #region process data
// left
this.leftDataSource = [];
// right
this.rightDataSource = [];
this.handleLeftSelectAll = (checked) => this.handleSelect('left', checked);
this.handleRightSelectAll = (checked) => this.handleSelect('right', checked);
this.handleLeftSelect = (item) => this.handleSelect('left', !!item.checked, item);
this.handleRightSelect = (item) => this.handleSelect('right', !!item.checked, item);
// #endregion
// #region operation
this.leftActive = false;
this.rightActive = false;
this.moveToLeft = () => this.moveTo('left');
this.moveToRight = () => this.moveTo('right');
}
splitDataSource() {
this.leftDataSource = [];
this.rightDataSource = [];
this.nzDataSource.forEach(record => {
if (record.direction === 'right') {
record.direction = 'right';
this.rightDataSource.push(record);
}
else {
record.direction = 'left';
this.leftDataSource.push(record);
}
});
}
getCheckedData(direction) {
return this[direction === 'left' ? 'leftDataSource' : 'rightDataSource'].filter(w => w.checked);
}
handleSelect(direction, checked, item) {
const list = this.getCheckedData(direction);
this.updateOperationStatus(direction, list.length);
this.nzSelectChange.emit({ direction, checked, list, item });
}
handleFilterChange(ret) {
this.nzSearchChange.emit(ret);
}
updateOperationStatus(direction, count) {
this[direction === 'right' ? 'leftActive' : 'rightActive'] =
(typeof count === 'undefined' ? this.getCheckedData(direction).filter(w => !w.disabled).length : count) > 0;
}
moveTo(direction) {
const oppositeDirection = direction === 'left' ? 'right' : 'left';
this.updateOperationStatus(oppositeDirection, 0);
const datasource = direction === 'left' ? this.rightDataSource : this.leftDataSource;
const moveList = datasource.filter(item => item.checked === true && !item.disabled);
this.nzCanMove({ direction, list: moveList }).subscribe(newMoveList => this.truthMoveTo(direction, newMoveList.filter(i => !!i)), () => moveList.forEach(i => (i.checked = false)));
}
truthMoveTo(direction, list) {
const oppositeDirection = direction === 'left' ? 'right' : 'left';
const datasource = direction === 'left' ? this.rightDataSource : this.leftDataSource;
const targetDatasource = direction === 'left' ? this.leftDataSource : this.rightDataSource;
for (const item of list) {
item.checked = false;
item.hide = false;
item.direction = direction;
datasource.splice(datasource.indexOf(item), 1);
}
targetDatasource.splice(0, 0, ...list);
this.updateOperationStatus(oppositeDirection);
this.nzChange.emit({
from: oppositeDirection,
to: direction,
list
});
this.markForCheckAllList();
}
markForCheckAllList() {
if (!this.lists) {
return;
}
this.lists.forEach(i => i.markForCheck());
}
handleNzTargetKeys() {
const keys = toArray(this.nzTargetKeys);
const hasOwnKey = (e) => e.hasOwnProperty('key');
this.leftDataSource.forEach(e => {
if (hasOwnKey(e) && keys.indexOf(e.key) !== -1 && !e.disabled) {
e.checked = true;
}
});
this.moveToRight();
}
handleNzSelectedKeys() {
const keys = toArray(this.nzSelectedKeys);
this.nzDataSource.forEach(e => {
if (keys.indexOf(e.key) !== -1) {
e.checked = true;
}
});
const term = (ld) => ld.disabled === false && ld.checked === true;
this.rightActive = this.leftDataSource.some(term);
this.leftActive = this.rightDataSource.some(term);
}
ngOnInit() {
this.nzFormStatusService?.formStatusChanges
.pipe(distinctUntilChanged((pre, cur) => {
return pre.status === cur.status && pre.hasFeedback === cur.hasFeedback;
}), withLatestFrom(this.nzFormNoStatusService ? this.nzFormNoStatusService.noFormStatus : observableOf(false)), map(([{ status, hasFeedback }, noStatus]) => ({ status: noStatus ? '' : status, hasFeedback })), takeUntil(this.unsubscribe$))
.subscribe(({ status, hasFeedback }) => {
this.setStatusStyles(status, hasFeedback);
});
this.i18n.localeChange.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
this.locale = this.i18n.getLocaleData('Transfer');
this.markForCheckAllList();
});
this.dir = this.directionality.value;
this.directionality.change?.pipe(takeUntil(this.unsubscribe$)).subscribe((direction) => {
this.dir = direction;
this.cdr.detectChanges();
});
}
ngOnChanges(changes) {
const { nzStatus, nzDataSource, nzTargetKeys, nzSelectedKeys } = changes;
if (nzDataSource) {
this.splitDataSource();
this.updateOperationStatus('left');
this.updateOperationStatus('right');
this.cdr.detectChanges();
this.markForCheckAllList();
}
if (nzTargetKeys) {
this.handleNzTargetKeys();
}
if (nzSelectedKeys) {
this.handleNzSelectedKeys();
}
if (nzStatus) {
this.setStatusStyles(this.nzStatus, this.hasFeedback);
}
}
ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
setStatusStyles(status, hasFeedback) {
// set inner status
this.hasFeedback = hasFeedback;
this.cdr.markForCheck();
// render status if nzStatus is set
this.statusCls = getStatusClassNames(this.prefixCls, status, hasFeedback);
Object.keys(this.statusCls).forEach(status => {
if (this.statusCls[status]) {
this.renderer.addClass(this.elementRef.nativeElement, status);
}
else {
this.renderer.removeClass(this.elementRef.nativeElement, status);
}
});
}
}
NzTransferComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: NzTransferComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.NzI18nService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i2.Directionality, optional: true }, { token: i3.NzFormStatusService, optional: true }, { token: i3.NzFormNoStatusService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
NzTransferComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", type: NzTransferComponent, selector: "nz-transfer", inputs: { nzDisabled: "nzDisabled", nzDataSource: "nzDataSource", nzTitles: "nzTitles", nzOperations: "nzOperations", nzListStyle: "nzListStyle", nzShowSelectAll: "nzShowSelectAll", nzItemUnit: "nzItemUnit", nzItemsUnit: "nzItemsUnit", nzCanMove: "nzCanMove", nzRenderList: "nzRenderList", nzRender: "nzRender", nzFooter: "nzFooter", nzShowSearch: "nzShowSearch", nzFilterOption: "nzFilterOption", nzSearchPlaceholder: "nzSearchPlaceholder", nzNotFoundContent: "nzNotFoundContent", nzTargetKeys: "nzTargetKeys", nzSelectedKeys: "nzSelectedKeys", nzStatus: "nzStatus" }, outputs: { nzChange: "nzChange", nzSearchChange: "nzSearchChange", nzSelectChange: "nzSelectChange" }, host: { properties: { "class.ant-transfer-rtl": "dir === 'rtl'", "class.ant-transfer-disabled": "nzDisabled", "class.ant-transfer-customize-list": "nzRenderList" }, classAttribute: "ant-transfer" }, viewQueries: [{ propertyName: "lists", predicate: NzTransferListComponent, descendants: true }], exportAs: ["nzTransfer"], usesOnChanges: true, ngImport: i0, template: `
<nz-transfer-list
class="ant-transfer-list"
[ngStyle]="nzListStyle"
data-direction="left"
direction="left"
[titleText]="nzTitles[0]"
[showSelectAll]="nzShowSelectAll"
[dataSource]="leftDataSource"
[filter]="leftFilter"
[filterOption]="nzFilterOption"
(filterChange)="handleFilterChange($event)"
[renderList]="nzRenderList && nzRenderList[0]"
[render]="nzRender"
[disabled]="nzDisabled"
[showSearch]="nzShowSearch"
[searchPlaceholder]="nzSearchPlaceholder || locale?.searchPlaceholder"
[notFoundContent]="nzNotFoundContent"
[itemUnit]="nzItemUnit || locale?.itemUnit"
[itemsUnit]="nzItemsUnit || locale?.itemsUnit"
[footer]="nzFooter"
(handleSelect)="handleLeftSelect($event)"
(handleSelectAll)="handleLeftSelectAll($event)"
></nz-transfer-list>
<div *ngIf="dir !== 'rtl'" class="ant-transfer-operation">
<button
nz-button
type="button"
(click)="moveToLeft()"
[disabled]="nzDisabled || !leftActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="left"></span>
<span *ngIf="nzOperations[1]">{{ nzOperations[1] }}</span>
</button>
<button
nz-button
type="button"
(click)="moveToRight()"
[disabled]="nzDisabled || !rightActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="right"></span>
<span *ngIf="nzOperations[0]">{{ nzOperations[0] }}</span>
</button>
</div>
<div *ngIf="dir === 'rtl'" class="ant-transfer-operation">
<button
nz-button
type="button"
(click)="moveToRight()"
[disabled]="nzDisabled || !rightActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="left"></span>
<span *ngIf="nzOperations[0]">{{ nzOperations[0] }}</span>
</button>
<button
nz-button
type="button"
(click)="moveToLeft()"
[disabled]="nzDisabled || !leftActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="right"></span>
<span *ngIf="nzOperations[1]">{{ nzOperations[1] }}</span>
</button>
</div>
<nz-transfer-list
class="ant-transfer-list"
[ngStyle]="nzListStyle"
data-direction="right"
direction="right"
[titleText]="nzTitles[1]"
[showSelectAll]="nzShowSelectAll"
[dataSource]="rightDataSource"
[filter]="rightFilter"
[filterOption]="nzFilterOption"
(filterChange)="handleFilterChange($event)"
[renderList]="nzRenderList && nzRenderList[1]"
[render]="nzRender"
[disabled]="nzDisabled"
[showSearch]="nzShowSearch"
[searchPlaceholder]="nzSearchPlaceholder || locale?.searchPlaceholder"
[notFoundContent]="nzNotFoundContent"
[itemUnit]="nzItemUnit || locale?.itemUnit"
[itemsUnit]="nzItemsUnit || locale?.itemsUnit"
[footer]="nzFooter"
(handleSelect)="handleRightSelect($event)"
(handleSelectAll)="handleRightSelectAll($event)"
></nz-transfer-list>
`, isInline: true, dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i5.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i6.ɵNzTransitionPatchDirective, selector: "[nz-button], nz-button-group, [nz-icon], [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i7.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "directive", type: i8.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "component", type: i9.NzTransferListComponent, selector: "nz-transfer-list", inputs: ["direction", "titleText", "showSelectAll", "dataSource", "itemUnit", "itemsUnit", "filter", "disabled", "showSearch", "searchPlaceholder", "notFoundContent", "filterOption", "renderList", "render", "footer"], outputs: ["handleSelectAll", "handleSelect", "filterChange"], exportAs: ["nzTransferList"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
__decorate([
InputBoolean()
], NzTransferComponent.prototype, "nzDisabled", void 0);
__decorate([
InputBoolean()
], NzTransferComponent.prototype, "nzShowSelectAll", void 0);
__decorate([
InputBoolean()
], NzTransferComponent.prototype, "nzShowSearch", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: NzTransferComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-transfer',
exportAs: 'nzTransfer',
preserveWhitespaces: false,
template: `
<nz-transfer-list
class="ant-transfer-list"
[ngStyle]="nzListStyle"
data-direction="left"
direction="left"
[titleText]="nzTitles[0]"
[showSelectAll]="nzShowSelectAll"
[dataSource]="leftDataSource"
[filter]="leftFilter"
[filterOption]="nzFilterOption"
(filterChange)="handleFilterChange($event)"
[renderList]="nzRenderList && nzRenderList[0]"
[render]="nzRender"
[disabled]="nzDisabled"
[showSearch]="nzShowSearch"
[searchPlaceholder]="nzSearchPlaceholder || locale?.searchPlaceholder"
[notFoundContent]="nzNotFoundContent"
[itemUnit]="nzItemUnit || locale?.itemUnit"
[itemsUnit]="nzItemsUnit || locale?.itemsUnit"
[footer]="nzFooter"
(handleSelect)="handleLeftSelect($event)"
(handleSelectAll)="handleLeftSelectAll($event)"
></nz-transfer-list>
<div *ngIf="dir !== 'rtl'" class="ant-transfer-operation">
<button
nz-button
type="button"
(click)="moveToLeft()"
[disabled]="nzDisabled || !leftActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="left"></span>
<span *ngIf="nzOperations[1]">{{ nzOperations[1] }}</span>
</button>
<button
nz-button
type="button"
(click)="moveToRight()"
[disabled]="nzDisabled || !rightActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="right"></span>
<span *ngIf="nzOperations[0]">{{ nzOperations[0] }}</span>
</button>
</div>
<div *ngIf="dir === 'rtl'" class="ant-transfer-operation">
<button
nz-button
type="button"
(click)="moveToRight()"
[disabled]="nzDisabled || !rightActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="left"></span>
<span *ngIf="nzOperations[0]">{{ nzOperations[0] }}</span>
</button>
<button
nz-button
type="button"
(click)="moveToLeft()"
[disabled]="nzDisabled || !leftActive"
[nzType]="'primary'"
[nzSize]="'small'"
>
<span nz-icon nzType="right"></span>
<span *ngIf="nzOperations[1]">{{ nzOperations[1] }}</span>
</button>
</div>
<nz-transfer-list
class="ant-transfer-list"
[ngStyle]="nzListStyle"
data-direction="right"
direction="right"
[titleText]="nzTitles[1]"
[showSelectAll]="nzShowSelectAll"
[dataSource]="rightDataSource"
[filter]="rightFilter"
[filterOption]="nzFilterOption"
(filterChange)="handleFilterChange($event)"
[renderList]="nzRenderList && nzRenderList[1]"
[render]="nzRender"
[disabled]="nzDisabled"
[showSearch]="nzShowSearch"
[searchPlaceholder]="nzSearchPlaceholder || locale?.searchPlaceholder"
[notFoundContent]="nzNotFoundContent"
[itemUnit]="nzItemUnit || locale?.itemUnit"
[itemsUnit]="nzItemsUnit || locale?.itemsUnit"
[footer]="nzFooter"
(handleSelect)="handleRightSelect($event)"
(handleSelectAll)="handleRightSelectAll($event)"
></nz-transfer-list>
`,
host: {
class: 'ant-transfer',
'[class.ant-transfer-rtl]': `dir === 'rtl'`,
'[class.ant-transfer-disabled]': `nzDisabled`,
'[class.ant-transfer-customize-list]': `nzRenderList`
},
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.NzI18nService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i2.Directionality, decorators: [{
type: Optional
}] }, { type: i3.NzFormStatusService, decorators: [{
type: Optional
}] }, { type: i3.NzFormNoStatusService, decorators: [{
type: Optional
}] }]; }, propDecorators: { lists: [{
type: ViewChildren,
args: [NzTransferListComponent]
}], nzDisabled: [{
type: Input
}], nzDataSource: [{
type: Input
}], nzTitles: [{
type: Input
}], nzOperations: [{
type: Input
}], nzListStyle: [{
type: Input
}], nzShowSelectAll: [{
type: Input
}], nzItemUnit: [{
type: Input
}], nzItemsUnit: [{
type: Input
}], nzCanMove: [{
type: Input
}], nzRenderList: [{
type: Input
}], nzRender: [{
type: Input
}], nzFooter: [{
type: Input
}], nzShowSearch: [{
type: Input
}], nzFilterOption: [{
type: Input
}], nzSearchPlaceholder: [{
type: Input
}], nzNotFoundContent: [{
type: Input
}], nzTargetKeys: [{
type: Input
}], nzSelectedKeys: [{
type: Input
}], nzStatus: [{
type: Input
}], nzChange: [{
type: Output
}], nzSearchChange: [{
type: Output
}], nzSelectChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy90cmFuc2Zlci90cmFuc2Zlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBSUwsUUFBUSxFQUNSLE1BQU0sRUFLTixZQUFZLEVBQ1osaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBYyxFQUFFLElBQUksWUFBWSxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbkUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFXdEYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQVdyRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7Ozs7Ozs7Ozs7QUErR3BFLE1BQU0sT0FBTyxtQkFBbUI7SUE0STlCLGFBQWE7SUFFYixZQUNVLEdBQXNCLEVBQ3RCLElBQW1CLEVBQ25CLFVBQW1DLEVBQ25DLFFBQW1CLEVBQ1AsY0FBOEIsRUFDOUIsbUJBQXlDLEVBQ3pDLHFCQUE2QztRQU56RCxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixTQUFJLEdBQUosSUFBSSxDQUFlO1FBQ25CLGVBQVUsR0FBVixVQUFVLENBQXlCO1FBQ25DLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDUCxtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFzQjtRQUN6QywwQkFBcUIsR0FBckIscUJBQXFCLENBQXdCO1FBaEozRCxpQkFBWSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFLM0MsZUFB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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStGVDtvQkFDRCxJQUFJLEVBQUU7d0JBQ0osS0FBSyxFQUFFLGNBQWM7d0JBQ3JCLDBCQUEwQixFQUFFLGVBQWU7d0JBQzNDLCtCQUErQixFQUFFLFlBQVk7d0JBQzdDLHFDQUFxQyxFQUFFLGNBQWM7cUJBQ3REO29CQUNELGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO29CQUNyQyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtpQkFDaEQ7OzBCQW9KSSxRQUFROzswQkFDUixRQUFROzswQkFDUixRQUFROzRDQTlJNEIsS0FBSztzQkFBM0MsWUFBWTt1QkFBQyx1QkFBdUI7Z0JBY1osVUFBVTtzQkFBbEMsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNtQixlQUFlO3NCQUF2QyxLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNtQixZQUFZO3NCQUFwQyxLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFHYSxRQUFRO3NCQUExQixNQUFNO2dCQUNZLGNBQWM7c0JBQWhDLE1BQU07Z0JBQ1ksY0FBYztzQkFBaEMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IERpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGRyZW4sXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgYXMgb2JzZXJ2YWJsZU9mLCBvZiwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIG1hcCwgdGFrZVVudGlsLCB3aXRoTGF0ZXN0RnJvbSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpGb3JtTm9TdGF0dXNTZXJ2aWNlLCBOekZvcm1TdGF0dXNTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2Zvcm0nO1xuaW1wb3J0IHtcbiAgQm9vbGVhbklucHV0LFxuICBOZ0NsYXNzSW50ZXJmYWNlLFxuICBOZ1N0eWxlSW50ZXJmYWNlLFxuICBOelNhZmVBbnksXG4gIE56U3RhdHVzLFxuICBOelZhbGlkYXRlU3RhdHVzXG59IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBnZXRTdGF0dXNDbGFzc05hbWVzLCBJbnB1dEJvb2xlYW4sIHRvQXJyYXkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5pbXBvcnQgeyBOekkxOG5TZXJ2aWNlLCBOelRyYW5zZmVySTE4bkludGVyZmFjZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvaTE4bic7XG5cbmltcG9ydCB7XG4gIFRyYW5zZmVyQ2FuTW92ZSxcbiAgVHJhbnNmZXJDaGFuZ2UsXG4gIFRyYW5zZmVyRGlyZWN0aW9uLFxuICBUcmFuc2Zlckl0ZW0sXG4gIFRyYW5zZmVyU2VhcmNoQ2hhbmdlLFxuICBUcmFuc2ZlclNlbGVjdENoYW5nZVxufSBmcm9tICcuL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBOelRyYW5zZmVyTGlzdENvbXBvbmVudCB9IGZyb20gJy4vdHJhbnNmZXItbGlzdC5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei10cmFuc2ZlcicsXG4gIGV4cG9ydEFzOiAnbnpUcmFuc2ZlcicsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxuei10cmFuc2Zlci1saXN0XG4gICAgICBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0XCJcbiAgICAgIFtuZ1N0eWxlXT1cIm56TGlzdFN0eWxlXCJcbiAgICAgIGRhdGEtZGlyZWN0aW9uPVwibGVmdFwiXG4gICAgICBkaXJlY3Rpb249XCJsZWZ0XCJcbiAgICAgIFt0aXRsZVRleHRdPVwibnpUaXRsZXNbMF1cIlxuICAgICAgW3Nob3dTZWxlY3RBbGxdPVwibnpTaG93U2VsZWN0QWxsXCJcbiAgICAgIFtkYXRhU291cmNlXT1cImxlZnREYXRhU291cmNlXCJcbiAgICAgIFtmaWx0ZXJdPVwibGVmdEZpbHRlclwiXG4gICAgICBbZmlsdGVyT3B0aW9uXT1cIm56RmlsdGVyT3B0aW9uXCJcbiAgICAgIChmaWx0ZXJDaGFuZ2UpPVwiaGFuZGxlRmlsdGVyQ2hhbmdlKCRldmVudClcIlxuICAgICAgW3JlbmRlckxpc3RdPVwibnpSZW5kZXJMaXN0ICYmIG56UmVuZGVyTGlzdFswXVwiXG4gICAgICBbcmVuZGVyXT1cIm56UmVuZGVyXCJcbiAgICAgIFtkaXNhYmxlZF09XCJuekRpc2FibGVkXCJcbiAgICAgIFtzaG93U2VhcmNoXT1cIm56U2hvd1NlYXJjaFwiXG4gICAgICBbc2VhcmNoUGxhY2Vob2xkZXJdPVwibnpTZWFyY2hQbGFjZWhvbGRlciB8fCBsb2NhbGU/LnNlYXJjaFBsYWNlaG9sZGVyXCJcbiAgICAgIFtub3RGb3VuZENvbnRlbnRdPVwibnpOb3RGb3VuZENvbnRlbnRcIlxuICAgICAgW2l0ZW1Vbml0XT1cIm56SXRlbVVuaXQgfHwgbG9jYWxlPy5pdGVtVW5pdFwiXG4gICAgICBbaXRlbXNVbml0XT1cIm56SXRlbXNVbml0IHx8IGxvY2FsZT8uaXRlbXNVbml0XCJcbiAgICAgIFtmb290ZXJdPVwibnpGb290ZXJcIlxuICAgICAgKGhhbmRsZVNlbGVjdCk9XCJoYW5kbGVMZWZ0U2VsZWN0KCRldmVudClcIlxuICAgICAgKGhhbmRsZVNlbGVjdEFsbCk9XCJoYW5kbGVMZWZ0U2VsZWN0QWxsKCRldmVudClcIlxuICAgID48L256LXRyYW5zZmVyLWxpc3Q+XG4gICAgPGRpdiAqbmdJZj1cImRpciAhPT0gJ3J0bCdcIiBjbGFzcz1cImFudC10cmFuc2Zlci1vcGVyYXRpb25cIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgbnotYnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAoY2xpY2spPVwibW92ZVRvTGVmdCgpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cIm56RGlzYWJsZWQgfHwgIWxlZnRBY3RpdmVcIlxuICAgICAgICBbbnpUeXBlXT1cIidwcmltYXJ5J1wiXG4gICAgICAgIFtuelNpemVdPVwiJ3NtYWxsJ1wiXG4gICAgICA+XG4gICAgICAgIDxzcGFuIG56LWljb24gbnpUeXBlPVwibGVmdFwiPjwvc3Bhbj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCJuek9wZXJhdGlvbnNbMV1cIj57eyBuek9wZXJhdGlvbnNbMV0gfX08L3NwYW4+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgbnotYnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAoY2xpY2spPVwibW92ZVRvUmlnaHQoKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJuekRpc2FibGVkIHx8ICFyaWdodEFjdGl2ZVwiXG4gICAgICAgIFtuelR5cGVdPVwiJ3ByaW1hcnknXCJcbiAgICAgICAgW256U2l6ZV09XCInc21hbGwnXCJcbiAgICAgID5cbiAgICAgICAgPHNwYW4gbnotaWNvbiBuelR5cGU9XCJyaWdodFwiPjwvc3Bhbj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCJuek9wZXJhdGlvbnNbMF1cIj57eyBuek9wZXJhdGlvbnNbMF0gfX08L3NwYW4+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ0lmPVwiZGlyID09PSAncnRsJ1wiIGNsYXNzPVwiYW50LXRyYW5zZmVyLW9wZXJhdGlvblwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBuei1idXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJtb3ZlVG9SaWdodCgpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cIm56RGlzYWJsZWQgfHwgIXJpZ2h0QWN0aXZlXCJcbiAgICAgICAgW256VHlwZV09XCIncHJpbWFyeSdcIlxuICAgICAgICBbbnpTaXplXT1cIidzbWFsbCdcIlxuICAgICAgPlxuICAgICAgICA8c3BhbiBuei1pY29uIG56VHlwZT1cImxlZnRcIj48L3NwYW4+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwibnpPcGVyYXRpb25zWzBdXCI+e3sgbnpPcGVyYXRpb25zWzBdIH19PC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIG56LWJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgKGNsaWNrKT1cIm1vdmVUb0xlZnQoKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJuekRpc2FibGVkIHx8ICFsZWZ0QWN0aXZlXCJcbiAgICAgICAgW256VHlwZV09XCIncHJpbWFyeSdcIlxuICAgICAgICBbbnpTaXplXT1cIidzbWFsbCdcIlxuICAgICAgPlxuICAgICAgICA8c3BhbiBuei1pY29uIG56VHlwZT1cInJpZ2h0XCI+PC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cIm56T3BlcmF0aW9uc1sxXVwiPnt7IG56T3BlcmF0aW9uc1sxXSB9fTwvc3Bhbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIDxuei10cmFuc2Zlci1saXN0XG4gICAgICBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0XCJcbiAgICAgIFtuZ1N0eWxlXT1cIm56TGlzdFN0eWxlXCJcbiAgICAgIGRhdGEtZGlyZWN0aW9uPVwicmlnaHRcIlxuICAgICAgZGlyZWN0aW9uPVwicmlnaHRcIlxuICAgICAgW3RpdGxlVGV4dF09XCJuelRpdGxlc1sxXVwiXG4gICAgICBbc2hvd1NlbGVjdEFsbF09XCJuelNob3dTZWxlY3RBbGxcIlxuICAgICAgW2RhdGFTb3VyY2VdPVwicmlnaHREYXRhU291cmNlXCJcbiAgICAgIFtmaWx0ZXJdPVwicmlnaHRGaWx0ZXJcIlxuICAgICAgW2ZpbHRlck9wdGlvbl09XCJuekZpbHRlck9wdGlvblwiXG4gICAgICAoZmlsdGVyQ2hhbmdlKT1cImhhbmRsZUZpbHRlckNoYW5nZSgkZXZlbnQpXCJcbiAgICAgIFtyZW5kZXJMaXN0XT1cIm56UmVuZGVyTGlzdCAmJiBuelJlbmRlckxpc3RbMV1cIlxuICAgICAgW3JlbmRlcl09XCJuelJlbmRlclwiXG4gICAgICBbZGlzYWJsZWRdPVwibnpEaXNhYmxlZFwiXG4gICAgICBbc2hvd1NlYXJjaF09XCJuelNob3dTZWFyY2hcIlxuICAgICAgW3NlYXJjaFBsYWNlaG9sZGVyXT1cIm56U2VhcmNoUGxhY2Vob2xkZXIgfHwgbG9jYWxlPy5zZWFyY2hQbGFjZWhvbGRlclwiXG4gICAgICBbbm90Rm91bmRDb250ZW50XT1cIm56Tm90Rm91bmRDb250ZW50XCJcbiAgICAgIFtpdGVtVW5pdF09XCJuekl0ZW1Vbml0IHx8IGxvY2FsZT8uaXRlbVVuaXRcIlxuICAgICAgW2l0ZW1zVW5pdF09XCJuekl0ZW1zVW5pdCB8fCBsb2NhbGU/Lml0ZW1zVW5pdFwiXG4gICAgICBbZm9vdGVyXT1cIm56Rm9vdGVyXCJcbiAgICAgIChoYW5kbGVTZWxlY3QpPVwiaGFuZGxlUmlnaHRTZWxlY3QoJGV2ZW50KVwiXG4gICAgICAoaGFuZGxlU2VsZWN0QWxsKT1cImhhbmRsZVJpZ2h0U2VsZWN0QWxsKCRldmVudClcIlxuICAgID48L256LXRyYW5zZmVyLWxpc3Q+XG4gIGAsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC10cmFuc2ZlcicsXG4gICAgJ1tjbGFzcy5hbnQtdHJhbnNmZXItcnRsXSc6IGBkaXIgPT09ICdydGwnYCxcbiAgICAnW2NsYXNzLmFudC10cmFuc2Zlci1kaXNhYmxlZF0nOiBgbnpEaXNhYmxlZGAsXG4gICAgJ1tjbGFzcy5hbnQtdHJhbnNmZXItY3VzdG9taXplLWxpc3RdJzogYG56UmVuZGVyTGlzdGBcbiAgfSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgTnpUcmFuc2ZlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpEaXNhYmxlZDogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpTaG93U2VsZWN0QWxsOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uelNob3dTZWFyY2g6IEJvb2xlYW5JbnB1dDtcblxuICBwcml2YXRlIHVuc3Vic2NyaWJlJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgQFZpZXdDaGlsZHJlbihOelRyYW5zZmVyTGlzdENvbXBvbmVudCkgbGlzdHMhOiBRdWVyeUxpc3Q8TnpUcmFuc2Zlckxpc3RDb21wb25lbnQ+O1xuICBsb2NhbGUhOiBOelRyYW5zZmVySTE4bkludGVyZmFjZTtcblxuICBsZWZ0RmlsdGVyID0gJyc7XG4gIHJpZ2h0RmlsdGVyID0gJyc7XG4gIGRpcjogRGlyZWN0aW9uID0gJ2x0cic7XG5cbiAgLy8gc3RhdHVzXG4gIHByZWZpeENsczogc3RyaW5nID0gJ2FudC10cmFuc2Zlcic7XG4gIHN0YXR1c0NsczogTmdDbGFzc0ludGVyZmFjZSA9IHt9O1xuICBoYXNGZWVkYmFjazogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vICNyZWdpb24gZmllbGRzXG5cbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56RGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgbnpEYXRhU291cmNlOiBUcmFuc2Zlckl0ZW1bXSA9IFtdO1xuICBASW5wdXQoKSBuelRpdGxlczogc3RyaW5nW10gPSBbJycsICcnXTtcbiAgQElucHV0KCkgbnpPcGVyYXRpb25zOiBzdHJpbmdbXSA9IFtdO1xuICBASW5wdXQoKSBuekxpc3RTdHlsZTogTmdTdHlsZUludGVyZmFjZSA9IHt9O1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpTaG93U2VsZWN0QWxsID0gdHJ1ZTtcbiAgQElucHV0KCkgbnpJdGVtVW5pdD86IHN0cmluZztcbiAgQElucHV0KCkgbnpJdGVtc1VuaXQ/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIG56Q2FuTW92ZTogKGFyZzogVHJhbnNmZXJDYW5Nb3ZlKSA9PiBPYnNlcnZhYmxlPFRyYW5zZmVySXRlbVtdPiA9IChhcmc6IFRyYW5zZmVyQ2FuTW92ZSkgPT4gb2YoYXJnLmxpc3QpO1xuICBASW5wdXQoKSBuelJlbmRlckxpc3Q6IEFycmF5PFRlbXBsYXRlUmVmPE56U2FmZUFueT4gfCBudWxsPiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBuelJlbmRlcjogVGVtcGxhdGVSZWY8TnpTYWZlQW55PiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBuekZvb3RlcjogVGVtcGxhdGVSZWY8TnpTYWZlQW55PiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpTaG93U2VhcmNoID0gZmFsc2U7XG4gIEBJbnB1dCgpIG56RmlsdGVyT3B0aW9uPzogKGlucHV0VmFsdWU6IHN0cmluZywgaXRlbTogVHJhbnNmZXJJdGVtKSA9PiBib29sZWFuO1xuICBASW5wdXQoKSBuelNlYXJjaFBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICBASW5wdXQoKSBuek5vdEZvdW5kQ29udGVudD86IHN0cmluZztcbiAgQElucHV0KCkgbnpUYXJnZXRLZXlzOiBzdHJpbmdbXSA9IFtdO1xuICBASW5wdXQoKSBuelNlbGVjdGVkS2V5czogc3RyaW5nW10gPSBbXTtcbiAgQElucHV0KCkgbnpTdGF0dXM6IE56U3RhdHVzID0gJyc7XG5cbiAgLy8gZXZlbnRzXG4gIEBPdXRwdXQoKSByZWFkb25seSBuekNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8VHJhbnNmZXJDaGFuZ2U+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuelNlYXJjaENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8VHJhbnNmZXJTZWFyY2hDaGFuZ2U+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuelNlbGVjdENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8VHJhbnNmZXJTZWxlY3RDaGFuZ2U+KCk7XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJvY2VzcyBkYXRhXG5cbiAgLy8gbGVmdFxuICBsZWZ0RGF0YVNvdXJjZTogVHJhbnNmZXJJdGVtW10gPSBbXTtcblxuICAvLyByaWdodFxuICByaWdodERhdGFTb3VyY2U6IFRyYW5zZmVySXRlbVtdID0gW107XG5cbiAgcHJpdmF0ZSBzcGxpdERhdGFTb3VyY2UoKTogdm9pZCB7XG4gICAgdGhpcy5sZWZ0RGF0YVNvdXJjZSA9IFtdO1xuICAgIHRoaXMucmlnaHREYXRhU291cmNlID0gW107XG4gICAgdGhpcy5uekRhdGFTb3VyY2UuZm9yRWFjaChyZWNvcmQgPT4ge1xuICAgICAgaWYgKHJlY29yZC5kaXJlY3Rpb24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgcmVjb3JkLmRpcmVjdGlvbiA9ICdyaWdodCc7XG4gICAgICAgIHRoaXMucmlnaHREYXRhU291cmNlLnB1c2gocmVjb3JkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlY29yZC5kaXJlY3Rpb24gPSAnbGVmdCc7XG4gICAgICAgIHRoaXMubGVmdERhdGFTb3VyY2UucHVzaChyZWNvcmQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDaGVja2VkRGF0YShkaXJlY3Rpb246IFRyYW5zZmVyRGlyZWN0aW9uKTogVHJhbnNmZXJJdGVtW10ge1xuICAgIHJldHVybiB0aGlzW2RpcmVjdGlvbiA9PT0gJ2xlZnQnID8gJ2xlZnREYXRhU291cmNlJyA6ICdyaWdodERhdGFTb3VyY2UnXS5maWx0ZXIodyA9PiB3LmNoZWNrZWQpO1xuICB9XG5cbiAgaGFuZGxlTGVmdFNlbGVjdEFsbCA9IChjaGVja2VkOiBib29sZWFuKTogdm9pZCA9PiB0aGlzLmhhbmRsZVNlbGVjdCgnbGVmdCcsIGNoZWNrZWQpO1xuICBoYW5kbGVSaWdodFNlbGVjdEFsbCA9IChjaGVja2VkOiBib29sZWFuKTogdm9pZCA9PiB0aGlzLmhhbmRsZVNlbGVjdCgncmlnaHQnLCBjaGVja2VkKTtcblxuICBoYW5kbGVMZWZ0U2VsZWN0ID0gKGl0ZW06IFRyYW5zZmVySXRlbSk6IHZvaWQgPT4gdGhpcy5oYW5kbGVTZWxlY3QoJ2xlZnQnLCAhIWl0ZW0uY2hlY2tlZCwgaXRlbSk7XG4gIGhhbmRsZVJpZ2h0U2VsZWN0ID0gKGl0ZW06IFRyYW5zZmVySXRlbSk6IHZvaWQgPT4gdGhpcy5oYW5kbGVTZWxlY3QoJ3JpZ2h0JywgISFpdGVtLmNoZWNrZWQsIGl0ZW0pO1xuXG4gIGhhbmRsZVNlbGVjdChkaXJlY3Rpb246IFRyYW5zZmVyRGlyZWN0aW9uLCBjaGVja2VkOiBib29sZWFuLCBpdGVtPzogVHJhbnNmZXJJdGVtKTogdm9pZCB7XG4gICAgY29uc3QgbGlzdCA9IHRoaXMuZ2V0Q2hlY2tlZERhdGEoZGlyZWN0aW9uKTtcbiAgICB0aGlzLnVwZGF0ZU9wZXJhdGlvblN0YXR1cyhkaXJlY3Rpb24sIGxpc3QubGVuZ3RoKTtcbiAgICB0aGlzLm56U2VsZWN0Q2hhbmdlLmVtaXQoeyBkaXJlY3Rpb24sIGNoZWNrZWQsIGxpc3QsIGl0ZW0gfSk7XG4gIH1cblxuICBoYW5kbGVGaWx0ZXJDaGFuZ2UocmV0OiB7IGRpcmVjdGlvbjogVHJhbnNmZXJEaXJlY3Rpb247IHZhbHVlOiBzdHJpbmcgfSk6IHZvaWQge1xuICAgIHRoaXMubnpTZWFyY2hDaGFuZ2UuZW1pdChyZXQpO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gb3BlcmF0aW9uXG5cbiAgbGVmdEFjdGl2ZSA9IGZhbHNlO1xuICByaWdodEFjdGl2ZSA9IGZhbHNlO1xuXG4gIHByaXZhdGUgdXBkYXRlT3BlcmF0aW9uU3RhdHVzKGRpcmVjdGlvbjogVHJhbnNmZXJEaXJlY3Rpb24sIGNvdW50PzogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpc1tkaXJlY3Rpb24gPT09ICdyaWdodCcgPyAnbGVmdEFjdGl2ZScgOiAncmlnaHRBY3RpdmUnXSA9XG4gICAgICAodHlwZW9mIGNvdW50ID09PSAndW5kZWZpbmVkJyA/IHRoaXMuZ2V0Q2hlY2tlZERhdGEoZGlyZWN0aW9uKS5maWx0ZXIodyA9PiAhdy5kaXNhYmxlZCkubGVuZ3RoIDogY291bnQpID4gMDtcbiAgfVxuXG4gIG1vdmVUb0xlZnQgPSAoKTogdm9pZCA9PiB0aGlzLm1vdmVUbygnbGVmdCcpO1xuICBtb3ZlVG9SaWdodCA9ICgpOiB2b2lkID0+IHRoaXMubW92ZVRvKCdyaWdodCcpO1xuXG4gIG1vdmVUbyhkaXJlY3Rpb246IFRyYW5zZmVyRGlyZWN0aW9uKTogdm9pZCB7XG4gICAgY29uc3Qgb3Bwb3NpdGVEaXJlY3Rpb24gPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyA/ICdyaWdodCcgOiAnbGVmdCc7XG4gICAgdGhpcy51cGRhdGVPcGVyYXRpb25TdGF0dXMob3Bwb3NpdGVEaXJlY3Rpb24sIDApO1xuICAgIGNvbnN0IGRhdGFzb3VyY2UgPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyA/IHRoaXMucmlnaHREYXRhU291cmNlIDogdGhpcy5sZWZ0RGF0YVNvdXJjZTtcbiAgICBjb25zdCBtb3ZlTGlzdCA9IGRhdGFzb3VyY2UuZmlsdGVyKGl0ZW0gPT4gaXRlbS5jaGVja2VkID09PSB0cnVlICYmICFpdGVtLmRpc2FibGVkKTtcbiAgICB0aGlzLm56Q2FuTW92ZSh7IGRpcmVjdGlvbiwgbGlzdDogbW92ZUxpc3QgfSkuc3Vic2NyaWJlKFxuICAgICAgbmV3TW92ZUxpc3QgPT5cbiAgICAgICAgdGhpcy50cnV0aE1vdmVUbyhcbiAgICAgICAgICBkaXJlY3Rpb24sXG4gICAgICAgICAgbmV3TW92ZUxpc3QuZmlsdGVyKGkgPT4gISFpKVxuICAgICAgICApLFxuICAgICAgKCkgPT4gbW92ZUxpc3QuZm9yRWFjaChpID0+IChpLmNoZWNrZWQgPSBmYWxzZSkpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgdHJ1dGhNb3ZlVG8oZGlyZWN0aW9uOiBUcmFuc2ZlckRpcmVjdGlvbiwgbGlzdDogVHJhbnNmZXJJdGVtW10pOiB2b2lkIHtcbiAgICBjb25zdCBvcHBvc2l0ZURpcmVjdGlvbiA9IGRpcmVjdGlvbiA9PT0gJ2xlZnQnID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgICBjb25zdCBkYXRhc291cmNlID0gZGlyZWN0aW9uID09PSAnbGVmdCcgPyB0aGlzLnJpZ2h0RGF0YVNvdXJjZSA6IHRoaXMubGVmdERhdGFTb3VyY2U7XG4gICAgY29uc3QgdGFyZ2V0RGF0YXNvdXJjZSA9IGRpcmVjdGlvbiA9PT0gJ2xlZnQnID8gdGhpcy5sZWZ0RGF0YVNvdXJjZSA6IHRoaXMucmlnaHREYXRhU291cmNlO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBsaXN0KSB7XG4gICAgICBpdGVtLmNoZWNrZWQgPSBmYWxzZTtcbiAgICAgIGl0ZW0uaGlkZSA9IGZhbHNlO1xuICAgICAgaXRlbS5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgICBkYXRhc291cmNlLnNwbGljZShkYXRhc291cmNlLmluZGV4T2YoaXRlbSksIDEpO1xuICAgIH1cbiAgICB0YXJnZXREYXRhc291cmNlLnNwbGljZSgwLCAwLCAuLi5saXN0KTtcbiAgICB0aGlzLnVwZGF0ZU9wZXJhdGlvblN0YXR1cyhvcHBvc2l0ZURpcmVjdGlvbik7XG4gICAgdGhpcy5uekNoYW5nZS5lbWl0KHtcbiAgICAgIGZyb206IG9wcG9zaXRlRGlyZWN0aW9uLFxuICAgICAgdG86IGRpcmVjdGlvbixcbiAgICAgIGxpc3RcbiAgICB9KTtcbiAgICB0aGlzLm1hcmtGb3JDaGVja0FsbExpc3QoKTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBpMThuOiBOekkxOG5TZXJ2aWNlLFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZGlyZWN0aW9uYWxpdHk6IERpcmVjdGlvbmFsaXR5LFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgbnpGb3JtU3RhdHVzU2VydmljZT86IE56Rm9ybVN0YXR1c1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBuekZvcm1Ob1N0YXR1c1NlcnZpY2U/OiBOekZvcm1Ob1N0YXR1c1NlcnZpY2VcbiAgKSB7fVxuXG4gIHByaXZhdGUgbWFya0ZvckNoZWNrQWxsTGlzdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubGlzdHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5saXN0cy5mb3JFYWNoKGkgPT4gaS5tYXJrRm9yQ2hlY2soKSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZU56VGFyZ2V0S2V5cygpOiB2b2lkIHtcbiAgICBjb25zdCBrZXlzID0gdG9BcnJheSh0aGlzLm56VGFyZ2V0S2V5cyk7XG4gICAgY29uc3QgaGFzT3duS2V5ID0gKGU6IFRyYW5zZmVySXRlbSk6IGJvb2xlYW4gPT4gZS5oYXNPd25Qcm9wZXJ0eSgna2V5Jyk7XG4gICAgdGhpcy5sZWZ0RGF0YVNvdXJjZS5mb3JFYWNoKGUgPT4ge1xuICAgICAgaWYgKGhhc093bktleShlKSAmJiBrZXlzLmluZGV4T2YoZS5rZXkpICE9PSAtMSAmJiAhZS5kaXNhYmxlZCkge1xuICAgICAgICBlLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMubW92ZVRvUmlnaHQoKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlTnpTZWxlY3RlZEtleXMoKTogdm9pZCB7XG4gICAgY29uc3Qga2V5cyA9IHRvQXJyYXkodGhpcy5uelNlbGVjdGVkS2V5cyk7XG4gICAgdGhpcy5uekRhdGFTb3VyY2UuZm9yRWFjaChlID0+IHtcbiAgICAgIGlmIChrZXlzLmluZGV4T2YoZS5rZXkpICE9PSAtMSkge1xuICAgICAgICBlLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHRlcm0gPSAobGQ6IFRyYW5zZmVySXRlbSk6IGJvb2xlYW4