UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

356 lines 38.3 kB
/** * 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 { NgClass, NgForOf, NgIf, NgTemplateOutlet } from '@angular/common'; import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewChildren, ViewEncapsulation, booleanAttribute } from '@angular/core'; import { Observable, fromEvent, merge } from 'rxjs'; import { startWith, switchMap } from 'rxjs/operators'; import { NzCheckboxComponent, NzCheckboxModule } from 'ng-zorro-antd/checkbox'; import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzTransferSearchComponent } from './transfer-search.component'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/checkbox"; import * as i2 from "ng-zorro-antd/empty"; export class NzTransferListComponent { get validData() { return this.dataSource.filter(w => !w.hide); } trackByHide(_index, item) { // The `validData` is a getter which returns new array each time the property is read. // This may lead to unexpected re-renders, tho the array hasn't been updated. return item.hide; } updateCheckStatus() { const validCount = this.dataSource.filter(w => !w.disabled).length; this.stat.checkCount = this.dataSource.filter(w => w.checked && !w.disabled).length; this.stat.shownCount = this.validData.length; this.stat.checkAll = validCount > 0 && validCount === this.stat.checkCount; this.stat.checkHalf = this.stat.checkCount > 0 && !this.stat.checkAll; // Note: this is done explicitly since the internal `nzChecked` value may not be updated in edge cases. // Consider the following flow: // 1) the initial value of `stat.checkAll` is `false` // 2) the user filters items // 3) the user clicks "Select All" checkbox // 4) the `NzCheckboxComponent` sets `nzChecked` to `true` internally // 5) the user clicks "Move to right" // 6) items are moved and the `updateCheckStatus` is invoked // 7) the `stat.checkAll` value has never been updated in this flow, it's always been `false` // 8) the `nzChecked` is still `true` and the checkbox is not unchecked // This is because Angular checks bindings and it checked that `[nzChecked]="stat.checkAll"` has // never been updated, so Angular did not set new `nzChecked` value on the checkbox. this.headerCheckbox && (this.headerCheckbox.nzChecked = this.stat.checkAll); } // #endregion // #region search handleFilter(value) { this.filter = value; this.dataSource.forEach(item => { item.hide = value.length > 0 && !this.matchFilter(value, item); }); this.stat.shownCount = this.validData.length; this.filterChange.emit({ direction: this.direction, value }); } handleClear() { this.handleFilter(''); } matchFilter(text, item) { if (this.filterOption) { return this.filterOption(text, item); } return item.title.includes(text); } // #endregion constructor(ngZone, cdr) { this.ngZone = ngZone; this.cdr = cdr; // #region fields this.direction = 'left'; this.titleText = ''; this.showSelectAll = true; this.dataSource = []; this.itemUnit = ''; this.itemsUnit = ''; this.filter = ''; this.disabled = false; this.renderList = null; this.render = null; this.footer = null; // events this.handleSelectAll = new EventEmitter(); this.handleSelect = new EventEmitter(); this.filterChange = new EventEmitter(); this.stat = { checkAll: false, checkHalf: false, checkCount: 0, shownCount: 0 }; this.onItemSelect = (item) => { if (this.disabled || item.disabled) { return; } item.checked = !item.checked; this.updateCheckStatus(); this.handleSelect.emit(item); }; this.onItemSelectAll = (status) => { this.dataSource.forEach(item => { if (!item.disabled && !item.hide) { item.checked = status; } }); this.updateCheckStatus(); this.handleSelectAll.emit(status); }; } markForCheck() { this.updateCheckStatus(); this.cdr.markForCheck(); } ngAfterViewInit() { this.checkboxes.changes .pipe(startWith(this.checkboxes), switchMap(() => { const checkboxes = this.checkboxes.toArray(); // Caretaker note: we explicitly should call `subscribe()` within the root zone. // `runOutsideAngular(() => fromEvent(...))` will just create an observable within the root zone, // but `addEventListener` is called when the `fromEvent` is subscribed. return new Observable(subscriber => this.ngZone.runOutsideAngular(() => merge(...checkboxes.map(checkbox => fromEvent(checkbox.nativeElement, 'click'))).subscribe(subscriber))); })) .subscribe(event => { event.stopPropagation(); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzTransferListComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.0.1", type: NzTransferListComponent, isStandalone: true, selector: "nz-transfer-list", inputs: { direction: "direction", titleText: "titleText", showSelectAll: "showSelectAll", dataSource: "dataSource", itemUnit: "itemUnit", itemsUnit: "itemsUnit", filter: "filter", disabled: ["disabled", "disabled", booleanAttribute], showSearch: ["showSearch", "showSearch", booleanAttribute], searchPlaceholder: "searchPlaceholder", notFoundContent: "notFoundContent", filterOption: "filterOption", renderList: "renderList", render: "render", footer: "footer" }, outputs: { handleSelectAll: "handleSelectAll", handleSelect: "handleSelect", filterChange: "filterChange" }, host: { properties: { "class.ant-transfer-list-with-footer": "!!footer" }, classAttribute: "ant-transfer-list" }, viewQueries: [{ propertyName: "headerCheckbox", first: true, predicate: ["headerCheckbox"], descendants: true, read: NzCheckboxComponent }, { propertyName: "checkboxes", predicate: ["checkboxes"], descendants: true, read: ElementRef }], exportAs: ["nzTransferList"], ngImport: i0, template: ` <ng-template #defaultRenderList> <ul *ngIf="stat.shownCount > 0" class="ant-transfer-list-content"> <li *ngFor="let item of validData; trackBy: trackByHide" (click)="onItemSelect(item)" class="ant-transfer-list-content-item" [ngClass]="{ 'ant-transfer-list-content-item-disabled': disabled || item.disabled }" > <label #checkboxes nz-checkbox [nzChecked]="item.checked" (nzCheckedChange)="onItemSelect(item)" [nzDisabled]="disabled || item.disabled" > <ng-container *ngIf="!render; else renderContainer">{{ item.title }}</ng-container> <ng-template #renderContainer [ngTemplateOutlet]="render" [ngTemplateOutletContext]="{ $implicit: item }" ></ng-template> </label> </li> </ul> <div *ngIf="stat.shownCount === 0" class="ant-transfer-list-body-not-found"> <nz-embed-empty [nzComponentName]="'transfer'" [specificContent]="notFoundContent"></nz-embed-empty> </div> </ng-template> <div class="ant-transfer-list-header"> <label *ngIf="showSelectAll" class="ant-transfer-list-checkbox" nz-checkbox #headerCheckbox [nzChecked]="stat.checkAll" (nzCheckedChange)="onItemSelectAll($event)" [nzIndeterminate]="stat.checkHalf" [nzDisabled]="stat.shownCount === 0 || disabled" ></label> <span class="ant-transfer-list-header-selected"> <span> {{ (stat.checkCount > 0 ? stat.checkCount + '/' : '') + stat.shownCount }} {{ validData.length > 1 ? itemsUnit : itemUnit }} </span> </span> <span *ngIf="titleText" class="ant-transfer-list-header-title">{{ titleText }}</span> </div> <div class="{{ showSearch ? 'ant-transfer-list-body ant-transfer-list-body-with-search' : 'ant-transfer-list-body' }}" [ngClass]="{ 'ant-transfer__nodata': stat.shownCount === 0 }" > <div *ngIf="showSearch" class="ant-transfer-list-body-search-wrapper"> <span nz-transfer-search class="ant-input-affix-wrapper ant-transfer-list-search" (valueChanged)="handleFilter($event)" (valueClear)="handleClear()" [placeholder]="searchPlaceholder" [disabled]="disabled" [value]="filter" ></span> </div> <ng-container *ngIf="renderList; else defaultRenderList"> <div class="ant-transfer-list-body-customize-wrapper"> <ng-container *ngTemplateOutlet=" renderList; context: { $implicit: validData, direction: direction, disabled: disabled, onItemSelectAll: onItemSelectAll, onItemSelect: onItemSelect, stat: stat } " ></ng-container> </div> </ng-container> </div> <div *ngIf="footer" class="ant-transfer-list-footer"> <ng-template [ngTemplateOutlet]="footer" [ngTemplateOutletContext]="{ $implicit: direction }"></ng-template> </div> `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i1.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: NzEmptyModule }, { kind: "component", type: i2.NzEmbedEmptyComponent, selector: "nz-embed-empty", inputs: ["nzComponentName", "specificContent"], exportAs: ["nzEmbedEmpty"] }, { kind: "component", type: NzTransferSearchComponent, selector: "[nz-transfer-search]", inputs: ["placeholder", "value", "disabled"], outputs: ["valueChanged", "valueClear"], exportAs: ["nzTransferSearch"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NzTransferListComponent, decorators: [{ type: Component, args: [{ selector: 'nz-transfer-list', exportAs: 'nzTransferList', preserveWhitespaces: false, template: ` <ng-template #defaultRenderList> <ul *ngIf="stat.shownCount > 0" class="ant-transfer-list-content"> <li *ngFor="let item of validData; trackBy: trackByHide" (click)="onItemSelect(item)" class="ant-transfer-list-content-item" [ngClass]="{ 'ant-transfer-list-content-item-disabled': disabled || item.disabled }" > <label #checkboxes nz-checkbox [nzChecked]="item.checked" (nzCheckedChange)="onItemSelect(item)" [nzDisabled]="disabled || item.disabled" > <ng-container *ngIf="!render; else renderContainer">{{ item.title }}</ng-container> <ng-template #renderContainer [ngTemplateOutlet]="render" [ngTemplateOutletContext]="{ $implicit: item }" ></ng-template> </label> </li> </ul> <div *ngIf="stat.shownCount === 0" class="ant-transfer-list-body-not-found"> <nz-embed-empty [nzComponentName]="'transfer'" [specificContent]="notFoundContent"></nz-embed-empty> </div> </ng-template> <div class="ant-transfer-list-header"> <label *ngIf="showSelectAll" class="ant-transfer-list-checkbox" nz-checkbox #headerCheckbox [nzChecked]="stat.checkAll" (nzCheckedChange)="onItemSelectAll($event)" [nzIndeterminate]="stat.checkHalf" [nzDisabled]="stat.shownCount === 0 || disabled" ></label> <span class="ant-transfer-list-header-selected"> <span> {{ (stat.checkCount > 0 ? stat.checkCount + '/' : '') + stat.shownCount }} {{ validData.length > 1 ? itemsUnit : itemUnit }} </span> </span> <span *ngIf="titleText" class="ant-transfer-list-header-title">{{ titleText }}</span> </div> <div class="{{ showSearch ? 'ant-transfer-list-body ant-transfer-list-body-with-search' : 'ant-transfer-list-body' }}" [ngClass]="{ 'ant-transfer__nodata': stat.shownCount === 0 }" > <div *ngIf="showSearch" class="ant-transfer-list-body-search-wrapper"> <span nz-transfer-search class="ant-input-affix-wrapper ant-transfer-list-search" (valueChanged)="handleFilter($event)" (valueClear)="handleClear()" [placeholder]="searchPlaceholder" [disabled]="disabled" [value]="filter" ></span> </div> <ng-container *ngIf="renderList; else defaultRenderList"> <div class="ant-transfer-list-body-customize-wrapper"> <ng-container *ngTemplateOutlet=" renderList; context: { $implicit: validData, direction: direction, disabled: disabled, onItemSelectAll: onItemSelectAll, onItemSelect: onItemSelect, stat: stat } " ></ng-container> </div> </ng-container> </div> <div *ngIf="footer" class="ant-transfer-list-footer"> <ng-template [ngTemplateOutlet]="footer" [ngTemplateOutletContext]="{ $implicit: direction }"></ng-template> </div> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'ant-transfer-list', '[class.ant-transfer-list-with-footer]': '!!footer' }, imports: [NgIf, NgForOf, NgClass, NzCheckboxModule, NgTemplateOutlet, NzEmptyModule, NzTransferSearchComponent], standalone: true }] }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { direction: [{ type: Input }], titleText: [{ type: Input }], showSelectAll: [{ type: Input }], dataSource: [{ type: Input }], itemUnit: [{ type: Input }], itemsUnit: [{ type: Input }], filter: [{ type: Input }], disabled: [{ type: Input, args: [{ transform: booleanAttribute }] }], showSearch: [{ type: Input, args: [{ transform: booleanAttribute }] }], searchPlaceholder: [{ type: Input }], notFoundContent: [{ type: Input }], filterOption: [{ type: Input }], renderList: [{ type: Input }], render: [{ type: Input }], footer: [{ type: Input }], handleSelectAll: [{ type: Output }], handleSelect: [{ type: Output }], filterChange: [{ type: Output }], headerCheckbox: [{ type: ViewChild, args: ['headerCheckbox', { read: NzCheckboxComponent }] }], checkboxes: [{ type: ViewChildren, args: ['checkboxes', { read: ElementRef }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmZXItbGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL3RyYW5zZmVyL3RyYW5zZmVyLWxpc3QuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNFLE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFHTixTQUFTLEVBQ1QsWUFBWSxFQUNaLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3BELE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBR3BELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDOzs7O0FBb0d4RSxNQUFNLE9BQU8sdUJBQXVCO0lBc0NsQyxJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELFdBQVcsQ0FBQyxNQUFjLEVBQUUsSUFBa0I7UUFDNUMsc0ZBQXNGO1FBQ3RGLDZFQUE2RTtRQUM3RSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkIsQ0FBQztJQXNCTyxpQkFBaUI7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QUFLO2dCQUdhLGVBQWU7c0JBQWpDLE1BQU07Z0JBQ1ksWUFBWTtzQkFBOUIsTUFBTTtnQkFDWSxZQUFZO3NCQUE5QixNQUFNO2dCQUVxRCxjQUFjO3NCQUF6RSxTQUFTO3VCQUFDLGdCQUFnQixFQUFFLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFO2dCQUVSLFVBQVU7c0JBQTNELFlBQVk7dUJBQUMsWUFBWSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IE5nQ2xhc3MsIE5nRm9yT2YsIE5nSWYsIE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDaGlsZHJlbixcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGJvb2xlYW5BdHRyaWJ1dGVcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmcm9tRXZlbnQsIG1lcmdlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzdGFydFdpdGgsIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpDaGVja2JveENvbXBvbmVudCwgTnpDaGVja2JveE1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY2hlY2tib3gnO1xuaW1wb3J0IHsgTnpFbXB0eU1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvZW1wdHknO1xuXG5pbXBvcnQgeyBSZW5kZXJMaXN0Q29udGV4dCwgVHJhbnNmZXJEaXJlY3Rpb24sIFRyYW5zZmVySXRlbSwgVHJhbnNmZXJTdGF0IH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTnpUcmFuc2ZlclNlYXJjaENvbXBvbmVudCB9IGZyb20gJy4vdHJhbnNmZXItc2VhcmNoLmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LXRyYW5zZmVyLWxpc3QnLFxuICBleHBvcnRBczogJ256VHJhbnNmZXJMaXN0JyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIHRlbXBsYXRlOiBgXG4gICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0UmVuZGVyTGlzdD5cbiAgICAgIDx1bCAqbmdJZj1cInN0YXQuc2hvd25Db3VudCA+IDBcIiBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0LWNvbnRlbnRcIj5cbiAgICAgICAgPGxpXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgdmFsaWREYXRhOyB0cmFja0J5OiB0cmFja0J5SGlkZVwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uSXRlbVNlbGVjdChpdGVtKVwiXG4gICAgICAgICAgY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1jb250ZW50LWl0ZW1cIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ2FudC10cmFuc2Zlci1saXN0LWNvbnRlbnQtaXRlbS1kaXNhYmxlZCc6IGRpc2FibGVkIHx8IGl0ZW0uZGlzYWJsZWQgfVwiXG4gICAgICAgID5cbiAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICNjaGVja2JveGVzXG4gICAgICAgICAgICBuei1jaGVja2JveFxuICAgICAgICAgICAgW256Q2hlY2tlZF09XCJpdGVtLmNoZWNrZWRcIlxuICAgICAgICAgICAgKG56Q2hlY2tlZENoYW5nZSk9XCJvbkl0ZW1TZWxlY3QoaXRlbSlcIlxuICAgICAgICAgICAgW256RGlzYWJsZWRdPVwiZGlzYWJsZWQgfHwgaXRlbS5kaXNhYmxlZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFyZW5kZXI7IGVsc2UgcmVuZGVyQ29udGFpbmVyXCI+e3sgaXRlbS50aXRsZSB9fTwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICNyZW5kZXJDb250YWluZXJcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwicmVuZGVyXCJcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiBpdGVtIH1cIlxuICAgICAgICAgICAgPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gICAgICA8ZGl2ICpuZ0lmPVwic3RhdC5zaG93bkNvdW50ID09PSAwXCIgY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1ib2R5LW5vdC1mb3VuZFwiPlxuICAgICAgICA8bnotZW1iZWQtZW1wdHkgW256Q29tcG9uZW50TmFtZV09XCIndHJhbnNmZXInXCIgW3NwZWNpZmljQ29udGVudF09XCJub3RGb3VuZENvbnRlbnRcIj48L256LWVtYmVkLWVtcHR5PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8ZGl2IGNsYXNzPVwiYW50LXRyYW5zZmVyLWxpc3QtaGVhZGVyXCI+XG4gICAgICA8bGFiZWxcbiAgICAgICAgKm5nSWY9XCJzaG93U2VsZWN0QWxsXCJcbiAgICAgICAgY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1jaGVja2JveFwiXG4gICAgICAgIG56LWNoZWNrYm94XG4gICAgICAgICNoZWFkZXJDaGVja2JveFxuICAgICAgICBbbnpDaGVja2VkXT1cInN0YXQuY2hlY2tBbGxcIlxuICAgICAgICAobnpDaGVja2VkQ2hhbmdlKT1cIm9uSXRlbVNlbGVjdEFsbCgkZXZlbnQpXCJcbiAgICAgICAgW256SW5kZXRlcm1pbmF0ZV09XCJzdGF0LmNoZWNrSGFsZlwiXG4gICAgICAgIFtuekRpc2FibGVkXT1cInN0YXQuc2hvd25Db3VudCA9PT0gMCB8fCBkaXNhYmxlZFwiXG4gICAgICA+PC9sYWJlbD5cbiAgICAgIDxzcGFuIGNsYXNzPVwiYW50LXRyYW5zZmVyLWxpc3QtaGVhZGVyLXNlbGVjdGVkXCI+XG4gICAgICAgIDxzcGFuPlxuICAgICAgICAgIHt7IChzdGF0LmNoZWNrQ291bnQgPiAwID8gc3RhdC5jaGVja0NvdW50ICsgJy8nIDogJycpICsgc3RhdC5zaG93bkNvdW50IH19XG4gICAgICAgICAge3sgdmFsaWREYXRhLmxlbmd0aCA+IDEgPyBpdGVtc1VuaXQgOiBpdGVtVW5pdCB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L3NwYW4+XG4gICAgICA8c3BhbiAqbmdJZj1cInRpdGxlVGV4dFwiIGNsYXNzPVwiYW50LXRyYW5zZmVyLWxpc3QtaGVhZGVyLXRpdGxlXCI+e3sgdGl0bGVUZXh0IH19PC9zcGFuPlxuICAgIDwvZGl2PlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwie3sgc2hvd1NlYXJjaCA/ICdhbnQtdHJhbnNmZXItbGlzdC1ib2R5IGFudC10cmFuc2Zlci1saXN0LWJvZHktd2l0aC1zZWFyY2gnIDogJ2FudC10cmFuc2Zlci1saXN0LWJvZHknIH19XCJcbiAgICAgIFtuZ0NsYXNzXT1cInsgJ2FudC10cmFuc2Zlcl9fbm9kYXRhJzogc3RhdC5zaG93bkNvdW50ID09PSAwIH1cIlxuICAgID5cbiAgICAgIDxkaXYgKm5nSWY9XCJzaG93U2VhcmNoXCIgY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1ib2R5LXNlYXJjaC13cmFwcGVyXCI+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgbnotdHJhbnNmZXItc2VhcmNoXG4gICAgICAgICAgY2xhc3M9XCJhbnQtaW5wdXQtYWZmaXgtd3JhcHBlciBhbnQtdHJhbnNmZXItbGlzdC1zZWFyY2hcIlxuICAgICAgICAgICh2YWx1ZUNoYW5nZWQpPVwiaGFuZGxlRmlsdGVyKCRldmVudClcIlxuICAgICAgICAgICh2YWx1ZUNsZWFyKT1cImhhbmRsZUNsZWFyKClcIlxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJzZWFyY2hQbGFjZWhvbGRlclwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICBbdmFsdWVdPVwiZmlsdGVyXCJcbiAgICAgICAgPjwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInJlbmRlckxpc3Q7IGVsc2UgZGVmYXVsdFJlbmRlckxpc3RcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0LWJvZHktY3VzdG9taXplLXdyYXBwZXJcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgICByZW5kZXJMaXN0O1xuICAgICAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICAgICAgJGltcGxpY2l0OiB2YWxpZERhdGEsXG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uOiBkaXJlY3Rpb24sXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGRpc2FibGVkLFxuICAgICAgICAgICAgICAgIG9uSXRlbVNlbGVjdEFsbDogb25JdGVtU2VsZWN0QWxsLFxuICAgICAgICAgICAgICAgIG9uSXRlbVNlbGVjdDogb25JdGVtU2VsZWN0LFxuICAgICAgICAgICAgICAgIHN0YXQ6IHN0YXRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdJZj1cImZvb3RlclwiIGNsYXNzPVwiYW50LXRyYW5zZmVyLWxpc3QtZm9vdGVyXCI+XG4gICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZm9vdGVyXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiBkaXJlY3Rpb24gfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG4gIGAsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdhbnQtdHJhbnNmZXItbGlzdCcsXG4gICAgJ1tjbGFzcy5hbnQtdHJhbnNmZXItbGlzdC13aXRoLWZvb3Rlcl0nOiAnISFmb290ZXInXG4gIH0sXG4gIGltcG9ydHM6IFtOZ0lmLCBOZ0Zvck9mLCBOZ0NsYXNzLCBOekNoZWNrYm94TW9kdWxlLCBOZ1RlbXBsYXRlT3V0bGV0LCBOekVtcHR5TW9kdWxlLCBOelRyYW5zZmVyU2VhcmNoQ29tcG9uZW50XSxcbiAgc3RhbmRhbG9uZTogdHJ1ZVxufSlcbmV4cG9ydCBjbGFzcyBOelRyYW5zZmVyTGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICAvLyAjcmVnaW9uIGZpZWxkc1xuXG4gIEBJbnB1dCgpIGRpcmVjdGlvbjogVHJhbnNmZXJEaXJlY3Rpb24gPSAnbGVmdCc7XG4gIEBJbnB1dCgpIHRpdGxlVGV4dCA9ICcnO1xuICBASW5wdXQoKSBzaG93U2VsZWN0QWxsID0gdHJ1ZTtcblxuICBASW5wdXQoKSBkYXRhU291cmNlOiBUcmFuc2Zlckl0ZW1bXSA9IFtdO1xuXG4gIEBJbnB1dCgpIGl0ZW1Vbml0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnJztcbiAgQElucHV0KCkgaXRlbXNVbml0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnJztcbiAgQElucHV0KCkgZmlsdGVyID0gJyc7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgc2hvd1NlYXJjaD86IGJvb2xlYW47XG4gIEBJbnB1dCgpIHNlYXJjaFBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICBASW5wdXQoKSBub3RGb3VuZENvbnRlbnQ/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGZpbHRlck9wdGlvbj86IChpbnB1dFZhbHVlOiBzdHJpbmcsIGl0ZW06IFRyYW5zZmVySXRlbSkgPT4gYm9vbGVhbjtcblxuICBASW5wdXQoKSByZW5kZXJMaXN0OiBUZW1wbGF0ZVJlZjxSZW5kZXJMaXN0Q29udGV4dD4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgcmVuZGVyOiBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogVHJhbnNmZXJJdGVtIH0+IHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIGZvb3RlcjogVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IFRyYW5zZmVyRGlyZWN0aW9uIH0+IHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gZXZlbnRzXG4gIEBPdXRwdXQoKSByZWFkb25seSBoYW5kbGVTZWxlY3RBbGw6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGhhbmRsZVNlbGVjdDogRXZlbnRFbWl0dGVyPFRyYW5zZmVySXRlbT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBmaWx0ZXJDaGFuZ2U6IEV2ZW50RW1pdHRlcjx7IGRpcmVjdGlvbjogVHJhbnNmZXJEaXJlY3Rpb247IHZhbHVlOiBzdHJpbmcgfT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQFZpZXdDaGlsZCgnaGVhZGVyQ2hlY2tib3gnLCB7IHJlYWQ6IE56Q2hlY2tib3hDb21wb25lbnQgfSkgaGVhZGVyQ2hlY2tib3g/OiBOekNoZWNrYm94Q29tcG9uZW50O1xuXG4gIEBWaWV3Q2hpbGRyZW4oJ2NoZWNrYm94ZXMnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSkgY2hlY2tib3hlcyE6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxMYWJlbEVsZW1lbnQ+PjtcblxuICBzdGF0OiBUcmFuc2ZlclN0YXQgPSB7XG4gICAgY2hlY2tBbGw6IGZhbHNlLFxuICAgIGNoZWNrSGFsZjogZmFsc2UsXG4gICAgY2hlY2tDb3VudDogMCxcbiAgICBzaG93bkNvdW50OiAwXG4gIH07XG5cbiAgZ2V0IHZhbGlkRGF0YSgpOiBUcmFuc2Zlckl0ZW1bXSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVNvdXJjZS5maWx0ZXIodyA9PiAhdy5oaWRlKTtcbiAgfVxuXG4gIHRyYWNrQnlIaWRlKF9pbmRleDogbnVtYmVyLCBpdGVtOiBUcmFuc2Zlckl0ZW0pOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgICAvLyBUaGUgYHZhbGlkRGF0YWAgaXMgYSBnZXR0ZXIgd2hpY2ggcmV0dXJucyBuZXcgYXJyYXkgZWFjaCB0aW1lIHRoZSBwcm9wZXJ0eSBpcyByZWFkLlxuICAgIC8vIFRoaXMgbWF5IGxlYWQgdG8gdW5leHBlY3RlZCByZS1yZW5kZXJzLCB0aG8gdGhlIGFycmF5IGhhc24ndCBiZWVuIHVwZGF0ZWQuXG4gICAgcmV0dXJuIGl0ZW0uaGlkZTtcbiAgfVxuXG4gIG9uSXRlbVNlbGVjdCA9IChpdGVtOiBUcmFuc2Zlckl0ZW0pOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCB8fCBpdGVtLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGl0ZW0uY2hlY2tlZCA9ICFpdGVtLmNoZWNrZWQ7XG4gICAgdGhpcy51cGRhdGVDaGVja1N0YXR1cygpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0LmVtaXQoaXRlbSk7XG4gIH07XG5cbiAgb25JdGVtU2VsZWN0QWxsID0gKHN0YXR1czogYm9vbGVhbik6IHZvaWQgPT4ge1xuICAgIHRoaXMuZGF0YVNvdXJjZS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaWYgKCFpdGVtLmRpc2FibGVkICYmICFpdGVtLmhpZGUpIHtcbiAgICAgICAgaXRlbS5jaGVja2VkID0gc3RhdHVzO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGVDaGVja1N0YXR1cygpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0QWxsLmVtaXQoc3RhdHVzKTtcbiAgfTtcblxuICBwcml2YXRlIHVwZGF0ZUNoZWNrU3RhdHVzKCk6IHZvaWQge1xuICAgIGNvbnN0IHZhbGlkQ291bnQgPSB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyKHcgPT4gIXcuZGlzYWJsZWQpLmxlbmd0aDtcbiAgICB0aGlzLnN0YXQuY2hlY2tDb3VudCA9IHRoaXMuZGF0YVNvdXJjZS5maWx0ZXIodyA9PiB3LmNoZWNrZWQgJiYgIXcuZGlzYWJsZWQpLmxlbmd0aDtcbiAgICB0aGlzLnN0YXQuc2hvd25Db3VudCA9IHRoaXMudmFsaWREYXRhLmxlbmd0aDtcbiAgICB0aGlzLnN0YXQuY2hlY2tBbGwgPSB2YWxpZENvdW50ID4gMCAmJiB2YWxpZENvdW50ID09PSB0aGlzLnN0YXQuY2hlY2tDb3VudDtcbiAgICB0aGlzLnN0YXQuY2hlY2tIYWxmID0gdGhpcy5zdGF0LmNoZWNrQ291bnQgPiAwICYmICF0aGlzLnN0YXQuY2hlY2tBbGw7XG4gICAgLy8gTm90ZTogdGhpcyBpcyBkb25lIGV4cGxpY2l0bHkgc2luY2UgdGhlIGludGVybmFsIGBuekNoZWNrZWRgIHZhbHVlIG1heSBub3QgYmUgdXBkYXRlZCBpbiBlZGdlIGNhc2VzLlxuICAgIC8vIENvbnNpZGVyIHRoZSBmb2xsb3dpbmcgZmxvdzpcbiAgICAvLyAxKSB0aGUgaW5pdGlhbCB2YWx1ZSBvZiBgc3RhdC5jaGVja0FsbGAgaXMgYGZhbHNlYFxuICAgIC8vIDIpIHRoZSB1c2VyIGZpbHRlcnMgaXRlbXNcbiAgICAvLyAzKSB0aGUgdXNlciBjbGlja3MgXCJTZWxlY3QgQWxsXCIgY2hlY2tib3hcbiAgICAvLyA0KSB0aGUgYE56Q2hlY2tib3hDb21wb25lbnRgIHNldHMgYG56Q2hlY2tlZGAgdG8gYHRydWVgIGludGVybmFsbHlcbiAgICAvLyA1KSB0aGUgdXNlciBjbGlja3MgXCJNb3ZlIHRvIHJpZ2h0XCJcbiAgICAvLyA2KSBpdGVtcyBhcmUgbW92ZWQgYW5kIHRoZSBgdXBkYXRlQ2hlY2tTdGF0dXNgIGlzIGludm9rZWRcbiAgICAvLyA3KSB0aGUgYHN0YXQuY2hlY2tBbGxgIHZhbHVlIGhhcyBuZXZlciBiZWVuIHVwZGF0ZWQgaW4gdGhpcyBmbG93LCBpdCdzIGFsd2F5cyBiZWVuIGBmYWxzZWBcbiAgICAvLyA4KSB0aGUgYG56Q2hlY2tlZGAgaXMgc3RpbGwgYHRydWVgIGFuZCB0aGUgY2hlY2tib3ggaXMgbm90IHVuY2hlY2tlZFxuICAgIC8vIFRoaXMgaXMgYmVjYXVzZSBBbmd1bGFyIGNoZWNrcyBiaW5kaW5ncyBhbmQgaXQgY2hlY2tlZCB0aGF0IGBbbnpDaGVja2VkXT1cInN0YXQuY2hlY2tBbGxcImAgaGFzXG4gICAgLy8gbmV2ZXIgYmVlbiB1cGRhdGVkLCBzbyBBbmd1bGFyIGRpZCBub3Qgc2V0IG5ldyBgbnpDaGVja2VkYCB2YWx1ZSBvbiB0aGUgY2hlY2tib3guXG4gICAgdGhpcy5oZWFkZXJDaGVja2JveCAmJiAodGhpcy5oZWFkZXJDaGVja2JveC5uekNoZWNrZWQgPSB0aGlzLnN0YXQuY2hlY2tBbGwpO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gc2VhcmNoXG5cbiAgaGFuZGxlRmlsdGVyKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlciA9IHZhbHVlO1xuICAgIHRoaXMuZGF0YVNvdXJjZS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaXRlbS5oaWRlID0gdmFsdWUubGVuZ3RoID4gMCAmJiAhdGhpcy5tYXRjaEZpbHRlcih2YWx1ZSwgaXRlbSk7XG4gICAgfSk7XG4gICAgdGhpcy5zdGF0LnNob3duQ291bnQgPSB0aGlzLnZhbGlkRGF0YS5sZW5ndGg7XG4gICAgdGhpcy5maWx0ZXJDaGFuZ2UuZW1pdCh7IGRpcmVjdGlvbjogdGhpcy5kaXJlY3Rpb24sIHZhbHVlIH0pO1xuICB9XG5cbiAgaGFuZGxlQ2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVGaWx0ZXIoJycpO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXRjaEZpbHRlcih0ZXh0OiBzdHJpbmcsIGl0ZW06IFRyYW5zZmVySXRlbSk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmZpbHRlck9wdGlvbikge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyT3B0aW9uKHRleHQsIGl0ZW0pO1xuICAgIH1cbiAgICByZXR1cm4gaXRlbS50aXRsZS5pbmNsdWRlcyh0ZXh0KTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHt9XG5cbiAgbWFya0ZvckNoZWNrKCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlQ2hlY2tTdGF0dXMoKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNoZWNrYm94ZXMuY2hhbmdlc1xuICAgICAgLnBpcGUoXG4gICAgICAgIHN0YXJ0V2l0aCh0aGlzLmNoZWNrYm94ZXMpLFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoZWNrYm94ZXMgPSB0aGlzLmNoZWNrYm94ZXMudG9BcnJheSgpO1xuICAgICAgICAgIC8vIENhcmV0YWtlciBub3RlOiB3ZSBleHBsaWNpdGx5IHNob3VsZCBjYWxsIGBzdWJzY3JpYmUoKWAgd2l0aGluIHRoZSByb290IHpvbmUuXG4gICAgICAgICAgLy8gYHJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IGZyb21FdmVudCguLi4pKWAgd2lsbCBqdXN0IGNyZWF0ZSBhbiBvYnNlcnZhYmxlIHdpdGhpbiB0aGUgcm9vdCB6b25lLFxuICAgICAgICAgIC8vIGJ1dCBgYWRkRXZlbnRMaXN0ZW5lcmAgaXMgY2FsbGVkIHdoZW4gdGhlIGBmcm9tRXZlbnRgIGlzIHN1YnNjcmliZWQuXG4gICAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+KHN1YnNjcmliZXIgPT5cbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+XG4gICAgICAgICAgICAgIG1lcmdlKC4uLmNoZWNrYm94ZXMubWFwKGNoZWNrYm94ID0+IGZyb21FdmVudDxNb3VzZUV2ZW50PihjaGVja2JveC5uYXRpdmVFbGVtZW50LCAnY2xpY2snKSkpLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfSk7XG4gIH1cbn1cbiJdfQ==