UNPKG

ng-zorro-antd

Version:

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

370 lines (368 loc) 38.8 kB
import { __decorate } from "tslib"; import { ChangeDetectionStrategy, Component, ContentChildren, Input, Optional, ViewEncapsulation } from '@angular/core'; import { merge, Subject } from 'rxjs'; import { auditTime, startWith, switchMap, takeUntil, tap } from 'rxjs/operators'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { warn } from 'ng-zorro-antd/core/logger'; import { gridResponsiveMap, NzBreakpointEnum } from 'ng-zorro-antd/core/services'; import { InputBoolean } from 'ng-zorro-antd/core/util'; import { NzDescriptionsItemComponent } from './descriptions-item.component'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "ng-zorro-antd/core/services"; import * as i3 from "@angular/cdk/bidi"; import * as i4 from "@angular/common"; import * as i5 from "ng-zorro-antd/core/outlet"; const NZ_CONFIG_MODULE_NAME = 'descriptions'; const defaultColumnMap = { xxl: 3, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }; export class NzDescriptionsComponent { constructor(nzConfigService, cdr, breakpointService, directionality) { this.nzConfigService = nzConfigService; this.cdr = cdr; this.breakpointService = breakpointService; this.directionality = directionality; this._nzModuleName = NZ_CONFIG_MODULE_NAME; this.nzBordered = false; this.nzLayout = 'horizontal'; this.nzColumn = defaultColumnMap; this.nzSize = 'default'; this.nzTitle = ''; this.nzColon = true; this.itemMatrix = []; this.realColumn = 3; this.dir = 'ltr'; this.breakpoint = NzBreakpointEnum.md; this.destroy$ = new Subject(); } ngOnInit() { this.dir = this.directionality.value; this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction) => { this.dir = direction; }); } ngOnChanges(changes) { if (changes.nzColumn) { this.prepareMatrix(); } } ngAfterContentInit() { const contentChange$ = this.items.changes.pipe(startWith(this.items), takeUntil(this.destroy$)); merge(contentChange$, contentChange$.pipe(switchMap(() => merge(...this.items.map(i => i.inputChange$)).pipe(auditTime(16)))), this.breakpointService.subscribe(gridResponsiveMap).pipe(tap(bp => (this.breakpoint = bp)))) .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.prepareMatrix(); this.cdr.markForCheck(); }); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } /** * Prepare the render matrix according to description items' spans. */ prepareMatrix() { if (!this.items) { return; } let currentRow = []; let width = 0; const column = (this.realColumn = this.getColumn()); const items = this.items.toArray(); const length = items.length; const matrix = []; const flushRow = () => { matrix.push(currentRow); currentRow = []; width = 0; }; for (let i = 0; i < length; i++) { const item = items[i]; const { nzTitle: title, content, nzSpan: span } = item; width += span; // If the last item make the row's length exceeds `nzColumn`, the last // item should take all the space left. This logic is implemented in the template. // Warn user about that. if (width >= column) { if (width > column) { warn(`"nzColumn" is ${column} but we have row length ${width}`); } currentRow.push({ title, content, span: column - (width - span) }); flushRow(); } else if (i === length - 1) { currentRow.push({ title, content, span: column - (width - span) }); flushRow(); } else { currentRow.push({ title, content, span }); } } this.itemMatrix = matrix; } getColumn() { if (typeof this.nzColumn !== 'number') { return this.nzColumn[this.breakpoint]; } return this.nzColumn; } } NzDescriptionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: NzDescriptionsComponent, deps: [{ token: i1.NzConfigService }, { token: i0.ChangeDetectorRef }, { token: i2.NzBreakpointService }, { token: i3.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Component }); NzDescriptionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: NzDescriptionsComponent, selector: "nz-descriptions", inputs: { nzBordered: "nzBordered", nzLayout: "nzLayout", nzColumn: "nzColumn", nzSize: "nzSize", nzTitle: "nzTitle", nzExtra: "nzExtra", nzColon: "nzColon" }, host: { properties: { "class.ant-descriptions-bordered": "nzBordered", "class.ant-descriptions-middle": "nzSize === \"middle\"", "class.ant-descriptions-small": "nzSize === \"small\"", "class.ant-descriptions-rtl": "dir === \"rtl\"" }, classAttribute: "ant-descriptions" }, queries: [{ propertyName: "items", predicate: NzDescriptionsItemComponent }], exportAs: ["nzDescriptions"], usesOnChanges: true, ngImport: i0, template: ` <div *ngIf="nzTitle || nzExtra" class="ant-descriptions-header"> <div *ngIf="nzTitle" class="ant-descriptions-title"> <ng-container *nzStringTemplateOutlet="nzTitle">{{ nzTitle }}</ng-container> </div> <div *ngIf="nzExtra" class="ant-descriptions-extra"> <ng-container *nzStringTemplateOutlet="nzExtra">{{ nzExtra }}</ng-container> </div> </div> <div class="ant-descriptions-view"> <table> <tbody> <ng-container *ngIf="nzLayout === 'horizontal'"> <tr class="ant-descriptions-row" *ngFor="let row of itemMatrix; let i = index"> <ng-container *ngFor="let item of row; let isLast = last"> <!-- Horizontal & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> <!-- Horizontal & Bordered --> <ng-container *ngIf="nzBordered"> <td class="ant-descriptions-item-label" *nzStringTemplateOutlet="item.title"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> <td class="ant-descriptions-item-content" [colSpan]="item.span * 2 - 1"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </ng-container> </tr> </ng-container> <ng-container *ngIf="nzLayout === 'vertical'"> <!-- Vertical & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> </div> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> </tr> </ng-container> </ng-container> <!-- Vertical & Bordered --> <ng-container *ngIf="nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-label" [colSpan]="item.span"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-content" [colSpan]="item.span"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </tr> </ng-container> </ng-container> </ng-container> </tbody> </table> </div> `, isInline: true, directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); __decorate([ InputBoolean(), WithConfig() ], NzDescriptionsComponent.prototype, "nzBordered", void 0); __decorate([ WithConfig() ], NzDescriptionsComponent.prototype, "nzColumn", void 0); __decorate([ WithConfig() ], NzDescriptionsComponent.prototype, "nzSize", void 0); __decorate([ WithConfig(), InputBoolean() ], NzDescriptionsComponent.prototype, "nzColon", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: NzDescriptionsComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, selector: 'nz-descriptions', exportAs: 'nzDescriptions', preserveWhitespaces: false, template: ` <div *ngIf="nzTitle || nzExtra" class="ant-descriptions-header"> <div *ngIf="nzTitle" class="ant-descriptions-title"> <ng-container *nzStringTemplateOutlet="nzTitle">{{ nzTitle }}</ng-container> </div> <div *ngIf="nzExtra" class="ant-descriptions-extra"> <ng-container *nzStringTemplateOutlet="nzExtra">{{ nzExtra }}</ng-container> </div> </div> <div class="ant-descriptions-view"> <table> <tbody> <ng-container *ngIf="nzLayout === 'horizontal'"> <tr class="ant-descriptions-row" *ngFor="let row of itemMatrix; let i = index"> <ng-container *ngFor="let item of row; let isLast = last"> <!-- Horizontal & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> <!-- Horizontal & Bordered --> <ng-container *ngIf="nzBordered"> <td class="ant-descriptions-item-label" *nzStringTemplateOutlet="item.title"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> <td class="ant-descriptions-item-content" [colSpan]="item.span * 2 - 1"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </ng-container> </tr> </ng-container> <ng-container *ngIf="nzLayout === 'vertical'"> <!-- Vertical & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> </div> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> </tr> </ng-container> </ng-container> <!-- Vertical & Bordered --> <ng-container *ngIf="nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-label" [colSpan]="item.span"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-content" [colSpan]="item.span"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </tr> </ng-container> </ng-container> </ng-container> </tbody> </table> </div> `, host: { class: 'ant-descriptions', '[class.ant-descriptions-bordered]': 'nzBordered', '[class.ant-descriptions-middle]': 'nzSize === "middle"', '[class.ant-descriptions-small]': 'nzSize === "small"', '[class.ant-descriptions-rtl]': 'dir === "rtl"' } }] }], ctorParameters: function () { return [{ type: i1.NzConfigService }, { type: i0.ChangeDetectorRef }, { type: i2.NzBreakpointService }, { type: i3.Directionality, decorators: [{ type: Optional }] }]; }, propDecorators: { items: [{ type: ContentChildren, args: [NzDescriptionsItemComponent] }], nzBordered: [{ type: Input }], nzLayout: [{ type: Input }], nzColumn: [{ type: Input }], nzSize: [{ type: Input }], nzTitle: [{ type: Input }], nzExtra: [{ type: Input }], nzColon: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzY3JpcHRpb25zLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvZGVzY3JpcHRpb25zL2Rlc2NyaXB0aW9ucy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULGVBQWUsRUFDZixLQUFLLEVBSUwsUUFBUSxFQUlSLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpGLE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckYsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBdUIsTUFBTSw2QkFBNkIsQ0FBQztBQUV2RyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sK0JBQStCLENBQUM7Ozs7Ozs7QUFHNUUsTUFBTSxxQkFBcUIsR0FBZ0IsY0FBYyxDQUFDO0FBQzFELE1BQU0sZ0JBQWdCLEdBQTBDO0lBQzlELEdBQUcsRUFBRSxDQUFDO0lBQ04sRUFBRSxFQUFFLENBQUM7SUFDTCxFQUFFLEVBQUUsQ0FBQztJQUNMLEVBQUUsRUFBRSxDQUFDO0lBQ0wsRUFBRSxFQUFFLENBQUM7SUFDTCxFQUFFLEVBQUUsQ0FBQztDQUNOLENBQUM7QUFxSEYsTUFBTSxPQUFPLHVCQUF1QjtJQXNCbEMsWUFDUyxlQUFnQyxFQUMvQixHQUFzQixFQUN0QixpQkFBc0MsRUFDMUIsY0FBOEI7UUFI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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvR1Q7b0JBQ0QsSUFBSSxFQUFFO3dCQUNKLEtBQUssRUFBRSxrQkFBa0I7d0JBQ3pCLG1DQUFtQyxFQUFFLFlBQVk7d0JBQ2pELGlDQUFpQyxFQUFFLHFCQUFxQjt3QkFDeEQsZ0NBQWdDLEVBQUUsb0JBQW9CO3dCQUN0RCw4QkFBOEIsRUFBRSxlQUFlO3FCQUNoRDtpQkFDRjs7MEJBMkJJLFFBQVE7NENBckJtQyxLQUFLO3NCQUFsRCxlQUFlO3VCQUFDLDJCQUEyQjtnQkFFTCxVQUFVO3NCQUFoRCxLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ2lCLFFBQVE7c0JBQTlCLEtBQUs7Z0JBQ2lCLE1BQU07c0JBQTVCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDaUMsT0FBTztzQkFBN0MsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IERpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIFF1ZXJ5TGlzdCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgbWVyZ2UsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGF1ZGl0VGltZSwgc3RhcnRXaXRoLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOekNvbmZpZ0tleSwgTnpDb25maWdTZXJ2aWNlLCBXaXRoQ29uZmlnIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2NvbmZpZyc7XG5pbXBvcnQgeyB3YXJuIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2xvZ2dlcic7XG5pbXBvcnQgeyBncmlkUmVzcG9uc2l2ZU1hcCwgTnpCcmVha3BvaW50RW51bSwgTnpCcmVha3BvaW50U2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBCb29sZWFuSW5wdXQgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgSW5wdXRCb29sZWFuIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuXG5pbXBvcnQgeyBOekRlc2NyaXB0aW9uc0l0ZW1Db21wb25lbnQgfSBmcm9tICcuL2Rlc2NyaXB0aW9ucy1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOekRlc2NyaXB0aW9uc0l0ZW1SZW5kZXJQcm9wcywgTnpEZXNjcmlwdGlvbnNMYXlvdXQsIE56RGVzY3JpcHRpb25zU2l6ZSB9IGZyb20gJy4vdHlwaW5ncyc7XG5cbmNvbnN0IE5aX0NPTkZJR19NT0RVTEVfTkFNRTogTnpDb25maWdLZXkgPSAnZGVzY3JpcHRpb25zJztcbmNvbnN0IGRlZmF1bHRDb2x1bW5NYXA6IHsgW2tleSBpbiBOekJyZWFrcG9pbnRFbnVtXTogbnVtYmVyIH0gPSB7XG4gIHh4bDogMyxcbiAgeGw6IDMsXG4gIGxnOiAzLFxuICBtZDogMyxcbiAgc206IDIsXG4gIHhzOiAxXG59O1xuXG5AQ29tcG9uZW50KHtcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHNlbGVjdG9yOiAnbnotZGVzY3JpcHRpb25zJyxcbiAgZXhwb3J0QXM6ICduekRlc2NyaXB0aW9ucycsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgKm5nSWY9XCJuelRpdGxlIHx8IG56RXh0cmFcIiBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaGVhZGVyXCI+XG4gICAgICA8ZGl2ICpuZ0lmPVwibnpUaXRsZVwiIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy10aXRsZVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwibnpUaXRsZVwiPnt7IG56VGl0bGUgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiAqbmdJZj1cIm56RXh0cmFcIiBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtZXh0cmFcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbnpTdHJpbmdUZW1wbGF0ZU91dGxldD1cIm56RXh0cmFcIj57eyBuekV4dHJhIH19PC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy12aWV3XCI+XG4gICAgICA8dGFibGU+XG4gICAgICAgIDx0Ym9keT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibnpMYXlvdXQgPT09ICdob3Jpem9udGFsJ1wiPlxuICAgICAgICAgICAgPHRyIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1yb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIGl0ZW1NYXRyaXg7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiByb3c7IGxldCBpc0xhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICAgICAgPCEtLSBIb3Jpem9udGFsICYgTk9UIEJvcmRlcmVkIC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbnpCb3JkZXJlZFwiPlxuICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtXCIgW2NvbFNwYW5dPVwiaXRlbS5zcGFuXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW0tY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW0tbGFiZWxcIiBbY2xhc3MuYW50LWRlc2NyaXB0aW9ucy1pdGVtLW5vLWNvbG9uXT1cIiFuekNvbG9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbS50aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLnRpdGxlIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW0tY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIml0ZW0uY29udGVudFwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPCEtLSBIb3Jpem9udGFsICYgQm9yZGVyZWQgLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm56Qm9yZGVyZWRcIj5cbiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaXRlbS1sYWJlbFwiICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbS50aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbS50aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0udGl0bGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWNvbnRlbnRcIiBbY29sU3Bhbl09XCJpdGVtLnNwYW4gKiAyIC0gMVwiPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiaXRlbS5jb250ZW50XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJuekxheW91dCA9PT0gJ3ZlcnRpY2FsJ1wiPlxuICAgICAgICAgICAgPCEtLSBWZXJ0aWNhbCAmIE5PVCBCb3JkZXJlZCAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbnpCb3JkZXJlZFwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByb3cgb2YgaXRlbU1hdHJpeDsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtcm93XCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJvdzsgbGV0IGlzTGFzdCA9IGxhc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtXCIgW2NvbFNwYW5dPVwiaXRlbS5zcGFuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaXRlbS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWxhYmVsXCIgW2NsYXNzLmFudC1kZXNjcmlwdGlvbnMtaXRlbS1uby1jb2xvbl09XCIhbnpDb2xvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbS50aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0udGl0bGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtcm93XCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJvdzsgbGV0IGlzTGFzdCA9IGxhc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtXCIgW2NvbFNwYW5dPVwiaXRlbS5zcGFuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaXRlbS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIml0ZW0uY29udGVudFwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPCEtLSBWZXJ0aWNhbCAmIEJvcmRlcmVkIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm56Qm9yZGVyZWRcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcm93IG9mIGl0ZW1NYXRyaXg7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICA8dHIgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiByb3c7IGxldCBpc0xhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaXRlbS1sYWJlbFwiIFtjb2xTcGFuXT1cIml0ZW0uc3BhblwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJpdGVtLnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLnRpdGxlIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtcm93XCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJvdzsgbGV0IGlzTGFzdCA9IGxhc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWNvbnRlbnRcIiBbY29sU3Bhbl09XCJpdGVtLnNwYW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiaXRlbS5jb250ZW50XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdGJvZHk+XG4gICAgICA8L3RhYmxlPlxuICAgIDwvZGl2PlxuICBgLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdhbnQtZGVzY3JpcHRpb25zJyxcbiAgICAnW2NsYXNzLmFudC1kZXNjcmlwdGlvbnMtYm9yZGVyZWRdJzogJ256Qm9yZGVyZWQnLFxuICAgICdbY2xhc3MuYW50LWRlc2NyaXB0aW9ucy1taWRkbGVdJzogJ256U2l6ZSA9PT0gXCJtaWRkbGVcIicsXG4gICAgJ1tjbGFzcy5hbnQtZGVzY3JpcHRpb25zLXNtYWxsXSc6ICduelNpemUgPT09IFwic21hbGxcIicsXG4gICAgJ1tjbGFzcy5hbnQtZGVzY3JpcHRpb25zLXJ0bF0nOiAnZGlyID09PSBcInJ0bFwiJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIE56RGVzY3JpcHRpb25zQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEFmdGVyQ29udGVudEluaXQsIE9uSW5pdCB7XG4gIHJlYWRvbmx5IF9uek1vZHVsZU5hbWU6IE56Q29uZmlnS2V5ID0gTlpfQ09ORklHX01PRFVMRV9OQU1FO1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpCb3JkZXJlZDogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpDb2xvbjogQm9vbGVhbklucHV0O1xuXG4gIEBDb250ZW50Q2hpbGRyZW4oTnpEZXNjcmlwdGlvbnNJdGVtQ29tcG9uZW50KSBpdGVtcyE6IFF1ZXJ5TGlzdDxOekRlc2NyaXB0aW9uc0l0ZW1Db21wb25lbnQ+O1xuXG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBAV2l0aENvbmZpZygpIG56Qm9yZGVyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbnpMYXlvdXQ6IE56RGVzY3JpcHRpb25zTGF5b3V0ID0gJ2hvcml6b250YWwnO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56Q29sdW1uOiBudW1iZXIgfCB7IFtrZXkgaW4gTnpCcmVha3BvaW50RW51bV06IG51bWJlciB9ID0gZGVmYXVsdENvbHVtbk1hcDtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelNpemU6IE56RGVzY3JpcHRpb25zU2l6ZSA9ICdkZWZhdWx0JztcbiAgQElucHV0KCkgbnpUaXRsZTogc3RyaW5nIHwgVGVtcGxhdGVSZWY8dm9pZD4gPSAnJztcbiAgQElucHV0KCkgbnpFeHRyYT86IHN0cmluZyB8IFRlbXBsYXRlUmVmPHZvaWQ+O1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIEBJbnB1dEJvb2xlYW4oKSBuekNvbG9uOiBib29sZWFuID0gdHJ1ZTtcblxuICBpdGVtTWF0cml4OiBOekRlc2NyaXB0aW9uc0l0ZW1SZW5kZXJQcm9wc1tdW10gPSBbXTtcbiAgcmVhbENvbHVtbiA9IDM7XG4gIGRpcjogRGlyZWN0aW9uID0gJ2x0cic7XG5cbiAgcHJpdmF0ZSBicmVha3BvaW50OiBOekJyZWFrcG9pbnRFbnVtID0gTnpCcmVha3BvaW50RW51bS5tZDtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG56Q29uZmlnU2VydmljZTogTnpDb25maWdTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIGJyZWFrcG9pbnRTZXJ2aWNlOiBOekJyZWFrcG9pbnRTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZGlyZWN0aW9uYWxpdHk6IERpcmVjdGlvbmFsaXR5XG4gICkge31cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5kaXIgPSB0aGlzLmRpcmVjdGlvbmFsaXR5LnZhbHVlO1xuICAgIHRoaXMuZGlyZWN0aW9uYWxpdHkuY2hhbmdlPy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChkaXJlY3Rpb246IERpcmVjdGlvbikgPT4ge1xuICAgICAgdGhpcy5kaXIgPSBkaXJlY3Rpb247XG4gICAgfSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMubnpDb2x1bW4pIHtcbiAgICAgIHRoaXMucHJlcGFyZU1hdHJpeCgpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCBjb250ZW50Q2hhbmdlJCA9IHRoaXMuaXRlbXMuY2hhbmdlcy5waXBlKHN0YXJ0V2l0aCh0aGlzLml0ZW1zKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKTtcblxuICAgIG1lcmdlKFxuICAgICAgY29udGVudENoYW5nZSQsXG4gICAgICBjb250ZW50Q2hhbmdlJC5waXBlKHN3aXRjaE1hcCgoKSA9PiBtZXJnZSguLi50aGlzLml0ZW1zLm1hcChpID0+IGkuaW5wdXRDaGFuZ2UkKSkucGlwZShhdWRpdFRpbWUoMTYpKSkpLFxuICAgICAgdGhpcy5icmVha3BvaW50U2VydmljZS5zdWJzY3JpYmUoZ3JpZFJlc3BvbnNpdmVNYXApLnBpcGUodGFwKGJwID0+ICh0aGlzLmJyZWFrcG9pbnQgPSBicCkpKVxuICAgIClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnByZXBhcmVNYXRyaXgoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVwYXJlIHRoZSByZW5kZXIgbWF0cml4IGFjY29yZGluZyB0byBkZXNjcmlwdGlvbiBpdGVtcycgc3BhbnMuXG4gICAqL1xuICBwcml2YXRlIHByZXBhcmVNYXRyaXgoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLml0ZW1zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGN1cnJlbnRSb3c6IE56RGVzY3JpcHRpb25zSXRlbVJlbmRlclByb3BzW10gPSBbXTtcbiAgICBsZXQgd2lkdGggPSAwO1xuXG4gICAgY29uc3QgY29sdW1uID0gKHRoaXMucmVhbENvbHVtbiA9IHRoaXMuZ2V0Q29sdW1uKCkpO1xuICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5pdGVtcy50b0FycmF5KCk7XG4gICAgY29uc3QgbGVuZ3RoID0gaXRlbXMubGVuZ3RoO1xuICAgIGNvbnN0IG1hdHJpeDogTnpEZXNjcmlwdGlvbnNJdGVtUmVuZGVyUHJvcHNbXVtdID0gW107XG4gICAgY29uc3QgZmx1c2hSb3cgPSAoKTogdm9pZCA9PiB7XG4gICAgICBtYXRyaXgucHVzaChjdXJyZW50Um93KTtcbiAgICAgIGN1cnJlbnRSb3cgPSBbXTtcbiAgICAgIHdpZHRoID0gMDtcbiAgICB9O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zW2ldO1xuICAgICAgY29uc3QgeyBuelRpdGxlOiB0aXRsZSwgY29udGVudCwgbnpTcGFuOiBzcGFuIH0gPSBpdGVtO1xuXG4gICAgICB3aWR0aCArPSBzcGFuO1xuXG4gICAgICAvLyBJZiB0aGUgbGFzdCBpdGVtIG1ha2UgdGhlIHJvdydzIGxlbmd0aCBleGNlZWRzIGBuekNvbHVtbmAsIHRoZSBsYXN0XG4gICAgICAvLyBpdGVtIHNob3VsZCB0YWtlIGFsbCB0aGUgc3BhY2UgbGVmdC4gVGhpcyBsb2dpYyBpcyBpbXBsZW1lbnRlZCBpbiB0aGUgdGVtcGxhdGUuXG4gICAgICAvLyBXYXJuIHVzZXIgYWJvdXQgdGhhdC5cbiAgICAgIGlmICh3aWR0aCA+PSBjb2x1bW4pIHtcbiAgICAgICAgaWYgKHdpZHRoID4gY29sdW1uKSB7XG4gICAgICAgICAgd2FybihgXCJuekNvbHVtblwiIGlzICR7Y29sdW1ufSBidXQgd2UgaGF2ZSByb3cgbGVuZ3RoICR7d2lkdGh9YCk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudFJvdy5wdXNoKHsgdGl0bGUsIGNvbnRlbnQsIHNwYW46IGNvbHVtbiAtICh3aWR0aCAtIHNwYW4pIH0pO1xuICAgICAgICBmbHVzaFJvdygpO1xuICAgICAgfSBlbHNlIGlmIChpID09PSBsZW5ndGggLSAxKSB7XG4gICAgICAgIGN1cnJlbnRSb3cucHVzaCh7IHRpdGxlLCBjb250ZW50LCBzcGFuOiBjb2x1bW4gLSAod2lkdGggLSBzcGFuKSB9KTtcbiAgICAgICAgZmx1c2hSb3coKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnRSb3cucHVzaCh7IHRpdGxlLCBjb250ZW50LCBzcGFuIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuaXRlbU1hdHJpeCA9IG1hdHJpeDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sdW1uKCk6IG51bWJlciB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLm56Q29sdW1uICE9PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHRoaXMubnpDb2x1bW5bdGhpcy5icmVha3BvaW50XTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5uekNvbHVtbjtcbiAgfVxufVxuIl19