ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
144 lines • 33 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { NgClass, NgSwitch, NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core';
import { CandyDate } from 'ng-zorro-antd/core/time';
import { isNonEmptyString, isTemplateRef, valueFunctionProp } from 'ng-zorro-antd/core/util';
import { AbstractTable } from './abstract-table';
import { transCompatFormat } from './util';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/i18n";
export class DateTableComponent extends AbstractTable {
constructor(i18n, dateHelper) {
super();
this.i18n = i18n;
this.dateHelper = dateHelper;
}
changeValueFromInside(value) {
// Only change date not change time
this.activeDate = this.activeDate.setYear(value.getYear()).setMonth(value.getMonth()).setDate(value.getDate());
this.valueChange.emit(this.activeDate);
if (!this.activeDate.isSameMonth(this.value)) {
this.render();
}
}
makeHeadRow() {
const weekDays = [];
const start = this.activeDate.calendarStart({ weekStartsOn: this.dateHelper.getFirstDayOfWeek() });
for (let colIndex = 0; colIndex < this.MAX_COL; colIndex++) {
const day = start.addDays(colIndex);
weekDays.push({
trackByIndex: null,
value: day.nativeDate,
title: this.dateHelper.format(day.nativeDate, 'E'), // eg. Tue
content: this.dateHelper.format(day.nativeDate, this.getVeryShortWeekFormat()), // eg. Tu,
isSelected: false,
isDisabled: false,
onClick() { },
onMouseEnter() { }
});
}
return weekDays;
}
getVeryShortWeekFormat() {
return this.i18n.getLocaleId().toLowerCase().indexOf('zh') === 0 ? 'EEEEE' : 'EEEEEE'; // Use extreme short for chinese
}
makeBodyRows() {
const weekRows = [];
const firstDayOfMonth = this.activeDate.calendarStart({ weekStartsOn: this.dateHelper.getFirstDayOfWeek() });
for (let week = 0; week < this.MAX_ROW; week++) {
const weekStart = firstDayOfMonth.addDays(week * 7);
const row = {
isActive: false,
dateCells: [],
trackByIndex: week
};
for (let day = 0; day < 7; day++) {
const date = weekStart.addDays(day);
const dateFormat = transCompatFormat(this.i18n.getLocaleData('DatePicker.lang.dateFormat', 'YYYY-MM-DD'));
const title = this.dateHelper.format(date.nativeDate, dateFormat);
const label = this.dateHelper.format(date.nativeDate, 'dd');
const cell = {
trackByIndex: day,
value: date.nativeDate,
label,
isSelected: false,
isDisabled: false,
isToday: false,
title,
cellRender: valueFunctionProp(this.cellRender, date), // Customized content
fullCellRender: valueFunctionProp(this.fullCellRender, date),
content: `${date.getDate()}`,
onClick: () => this.changeValueFromInside(date),
onMouseEnter: () => this.cellHover.emit(date),
};
this.addCellProperty(cell, date);
if (this.showWeek && !row.weekNum) {
row.weekNum = this.dateHelper.getISOWeek(date.nativeDate);
}
if (date.isSameDay(this.value)) {
row.isActive = date.isSameDay(this.value);
}
row.dateCells.push(cell);
}
row.classMap = {
[`ant-picker-week-panel-row`]: this.canSelectWeek,
[`ant-picker-week-panel-row-selected`]: this.canSelectWeek && row.isActive
};
weekRows.push(row);
}
return weekRows;
}
addCellProperty(cell, date) {
cell.isTemplateRef = isTemplateRef(cell.cellRender);
cell.isNonEmptyString = isNonEmptyString(cell.cellRender);
if (this.hasRangeValue() && !this.canSelectWeek) {
const [startHover, endHover] = this.hoverValue;
const [startSelected, endSelected] = this.selectedValue;
// Selected
if (startSelected?.isSameDay(date)) {
cell.isSelectedStart = true;
cell.isSelected = true;
}
if (endSelected?.isSameDay(date)) {
cell.isSelectedEnd = true;
cell.isSelected = true;
}
if (startHover && endHover) {
cell.isHoverStart = startHover.isSameDay(date);
cell.isHoverEnd = endHover.isSameDay(date);
cell.isLastCellInPanel = date.isLastDayOfMonth();
cell.isFirstCellInPanel = date.isFirstDayOfMonth();
cell.isInHoverRange = startHover.isBeforeDay(date) && date.isBeforeDay(endHover);
}
cell.isStartSingle = startSelected && !endSelected;
cell.isEndSingle = !startSelected && endSelected;
cell.isInSelectedRange = startSelected?.isBeforeDay(date) && date.isBeforeDay(endSelected);
cell.isRangeStartNearHover = startSelected && cell.isInHoverRange;
cell.isRangeEndNearHover = endSelected && cell.isInHoverRange;
}
cell.isToday = date.isToday();
cell.isSelected = date.isSameDay(this.value);
cell.isDisabled = !!this.disabledDate?.(date.nativeDate);
cell.classMap = this.getClassMap(cell);
}
getClassMap(cell) {
const date = new CandyDate(cell.value);
return {
...super.getClassMap(cell),
[`ant-picker-cell-today`]: !!cell.isToday,
[`ant-picker-cell-in-view`]: date.isSameMonth(this.activeDate)
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: DateTableComponent, deps: [{ token: i1.NzI18nService }, { token: i1.DateHelperService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.2", type: DateTableComponent, isStandalone: true, selector: "date-table", inputs: { locale: "locale" }, exportAs: ["dateTable"], usesInheritance: true, ngImport: i0, template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n @if (headRow && headRow.length > 0) {\n <thead>\n <tr role=\"row\">\n @if (showWeek) {\n <th role=\"columnheader\"></th>\n }\n @for (cell of headRow; track $index) {\n <th role=\"columnheader\" title=\"{{ cell.title }}\"> {{ cell.content }}</th>\n }\n </tr>\n </thead>\n }\n\n <tbody>\n @for (row of bodyRows; track row.trackByIndex) {\n <tr [ngClass]=\"row.classMap!\" role=\"row\">\n @if (row.weekNum) {\n <td role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\"> {{ row.weekNum }}</td>\n }\n @for (cell of row.dateCells; track cell.trackByIndex) {\n <td\n title=\"{{ cell.title }}\"\n role=\"gridcell\"\n [ngClass]=\"cell.classMap!\"\n (click)=\"cell.isDisabled ? null : cell.onClick()\"\n (mouseenter)=\"cell.onMouseEnter()\"\n >\n @switch (prefixCls) {\n @case ('ant-picker') {\n @if (cell.isTemplateRef) {\n <ng-container *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\" />\n } @else if (cell.isNonEmptyString) {\n <span [innerHTML]=\"cell.cellRender\"></span>\n } @else {\n <div\n class=\"{{ prefixCls }}-cell-inner\"\n [attr.aria-selected]=\"cell.isSelected\"\n [attr.aria-disabled]=\"cell.isDisabled\"\n >\n {{ cell.content }}\n </div>\n }\n }\n @case ('ant-picker-calendar') {\n <div\n class=\"{{ prefixCls }}-date ant-picker-cell-inner\"\n [class.ant-picker-calendar-date-today]=\"cell.isToday\"\n >\n @if (cell.fullCellRender) {\n <ng-container *ngTemplateOutlet=\"$any(cell.fullCellRender); context: { $implicit: cell.value }\" />\n } @else {\n <div class=\"{{ prefixCls }}-date-value\">{{ cell.content }}</div>\n <div class=\"{{ prefixCls }}-date-content\">\n <ng-container *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\">\n </ng-container>\n </div>\n }\n </div>\n }\n }\n </td>\n }\n\n </tr>\n }\n </tbody>\n</table>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: DateTableComponent, decorators: [{
type: Component,
args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, selector: 'date-table', exportAs: 'dateTable', standalone: true, imports: [NgClass, NgSwitch, NgTemplateOutlet], template: "<table class=\"ant-picker-content\" cellspacing=\"0\" role=\"grid\">\n @if (headRow && headRow.length > 0) {\n <thead>\n <tr role=\"row\">\n @if (showWeek) {\n <th role=\"columnheader\"></th>\n }\n @for (cell of headRow; track $index) {\n <th role=\"columnheader\" title=\"{{ cell.title }}\"> {{ cell.content }}</th>\n }\n </tr>\n </thead>\n }\n\n <tbody>\n @for (row of bodyRows; track row.trackByIndex) {\n <tr [ngClass]=\"row.classMap!\" role=\"row\">\n @if (row.weekNum) {\n <td role=\"gridcell\" class=\"{{ prefixCls }}-cell-week\"> {{ row.weekNum }}</td>\n }\n @for (cell of row.dateCells; track cell.trackByIndex) {\n <td\n title=\"{{ cell.title }}\"\n role=\"gridcell\"\n [ngClass]=\"cell.classMap!\"\n (click)=\"cell.isDisabled ? null : cell.onClick()\"\n (mouseenter)=\"cell.onMouseEnter()\"\n >\n @switch (prefixCls) {\n @case ('ant-picker') {\n @if (cell.isTemplateRef) {\n <ng-container *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\" />\n } @else if (cell.isNonEmptyString) {\n <span [innerHTML]=\"cell.cellRender\"></span>\n } @else {\n <div\n class=\"{{ prefixCls }}-cell-inner\"\n [attr.aria-selected]=\"cell.isSelected\"\n [attr.aria-disabled]=\"cell.isDisabled\"\n >\n {{ cell.content }}\n </div>\n }\n }\n @case ('ant-picker-calendar') {\n <div\n class=\"{{ prefixCls }}-date ant-picker-cell-inner\"\n [class.ant-picker-calendar-date-today]=\"cell.isToday\"\n >\n @if (cell.fullCellRender) {\n <ng-container *ngTemplateOutlet=\"$any(cell.fullCellRender); context: { $implicit: cell.value }\" />\n } @else {\n <div class=\"{{ prefixCls }}-date-value\">{{ cell.content }}</div>\n <div class=\"{{ prefixCls }}-date-content\">\n <ng-container *ngTemplateOutlet=\"$any(cell.cellRender); context: { $implicit: cell.value }\">\n </ng-container>\n </div>\n }\n </div>\n }\n }\n </td>\n }\n\n </tr>\n }\n </tbody>\n</table>\n" }]
}], ctorParameters: () => [{ type: i1.NzI18nService }, { type: i1.DateHelperService }], propDecorators: { locale: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS10YWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9jb21wb25lbnRzL2RhdGUtcGlja2VyL2xpYi9kYXRlLXRhYmxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL2NvbXBvbmVudHMvZGF0ZS1waWNrZXIvbGliL2Fic3RyYWN0LXRhYmxlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBcUIsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFaEgsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUc3RixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sUUFBUSxDQUFDOzs7QUFZM0MsTUFBTSxPQUFPLGtCQUFtQixTQUFRLGFBQWE7SUFHbkQsWUFBb0IsSUFBbUIsRUFBVSxVQUE2QjtRQUM1RSxLQUFLLEVBQUUsQ0FBQztRQURVLFNBQUksR0FBSixJQUFJLENBQWU7UUFBVSxlQUFVLEdBQVYsVUFBVSxDQUFtQjtJQUU5RSxDQUFDO0lBRU8scUJBQXFCLENBQUMsS0FBZ0I7UUFDNUMsbUNBQW1DO1FBQ25DLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMs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QUFDLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVRLFdBQVcsQ0FBQyxJQUFjO1FBQ2pDLE1BQU0sSUFBSSxHQUFHLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QyxPQUFPO1lBQ0wsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztZQUMxQixDQUFDLHVCQUF1QixDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQ3pDLENBQUMseUJBQXlCLENBQUMsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7U0FDL0QsQ0FBQztJQUNKLENBQUM7OEdBdklVLGtCQUFrQjtrR0FBbEIsa0JBQWtCLG9KQzFCL0Isc2pGQW9FQSw0Q0Q1Q1ksT0FBTyxvRkFBWSxnQkFBZ0I7OzJGQUVsQyxrQkFBa0I7a0JBVjlCLFNBQVM7b0NBQ08saUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTSxZQUVyQyxZQUFZLFlBQ1osV0FBVyxjQUVULElBQUksV0FDUCxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLENBQUM7a0hBRzVCLE1BQU07c0JBQXZCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBOZ0NsYXNzLCBOZ1N3aXRjaCwgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IENhbmR5RGF0ZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90aW1lJztcbmltcG9ydCB7IGlzTm9uRW1wdHlTdHJpbmcsIGlzVGVtcGxhdGVSZWYsIHZhbHVlRnVuY3Rpb25Qcm9wIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuaW1wb3J0IHsgRGF0ZUhlbHBlclNlcnZpY2UsIE56Q2FsZW5kYXJJMThuSW50ZXJmYWNlLCBOekkxOG5TZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pMThuJztcblxuaW1wb3J0IHsgQWJzdHJhY3RUYWJsZSB9IGZyb20gJy4vYWJzdHJhY3QtdGFibGUnO1xuaW1wb3J0IHsgRGF0ZUJvZHlSb3csIERhdGVDZWxsIH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgdHJhbnNDb21wYXRGb3JtYXQgfSBmcm9tICcuL3V0aWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnZGF0ZS10YWJsZScsXG4gIGV4cG9ydEFzOiAnZGF0ZVRhYmxlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Fic3RyYWN0LXRhYmxlLmh0bWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbTmdDbGFzcywgTmdTd2l0Y2gsIE5nVGVtcGxhdGVPdXRsZXRdXG59KVxuZXhwb3J0IGNsYXNzIERhdGVUYWJsZUNvbXBvbmVudCBleHRlbmRzIEFic3RyYWN0VGFibGUgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uSW5pdCB7XG4gIEBJbnB1dCgpIG92ZXJyaWRlIGxvY2FsZSE6IE56Q2FsZW5kYXJJMThuSW50ZXJmYWNlO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaTE4bjogTnpJMThuU2VydmljZSwgcHJpdmF0ZSBkYXRlSGVscGVyOiBEYXRlSGVscGVyU2VydmljZSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwcml2YXRlIGNoYW5nZVZhbHVlRnJvbUluc2lkZSh2YWx1ZTogQ2FuZHlEYXRlKTogdm9pZCB7XG4gICAgLy8gT25seSBjaGFuZ2UgZGF0ZSBub3QgY2hhbmdlIHRpbWVcbiAgICB0aGlzLmFjdGl2ZURhdGUgPSB0aGlzLmFjdGl2ZURhdGUuc2V0WWVhcih2YWx1ZS5nZXRZZWFyKCkpLnNldE1vbnRoKHZhbHVlLmdldE1vbnRoKCkpLnNldERhdGUodmFsdWUuZ2V0RGF0ZSgpKTtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy5hY3RpdmVEYXRlKTtcblxuICAgIGlmICghdGhpcy5hY3RpdmVEYXRlLmlzU2FtZU1vbnRoKHRoaXMudmFsdWUpKSB7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIG1ha2VIZWFkUm93KCk6IERhdGVDZWxsW10ge1xuICAgIGNvbnN0IHdlZWtEYXlzOiBEYXRlQ2VsbFtdID0gW107XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmFjdGl2ZURhdGUuY2FsZW5kYXJTdGFydCh7IHdlZWtTdGFydHNPbjogdGhpcy5kYXRlSGVscGVyLmdldEZpcnN0RGF5T2ZXZWVrKCkgfSk7XG4gICAgZm9yIChsZXQgY29sSW5kZXggPSAwOyBjb2xJbmRleCA8IHRoaXMuTUFYX0NPTDsgY29sSW5kZXgrKykge1xuICAgICAgY29uc3QgZGF5ID0gc3RhcnQuYWRkRGF5cyhjb2xJbmRleCk7XG4gICAgICB3ZWVrRGF5cy5wdXNoKHtcbiAgICAgICAgdHJhY2tCeUluZGV4OiBudWxsLFxuICAgICAgICB2YWx1ZTogZGF5Lm5hdGl2ZURhdGUsXG4gICAgICAgIHRpdGxlOiB0aGlzLmRhdGVIZWxwZXIuZm9ybWF0KGRheS5uYXRpdmVEYXRlLCAnRScpLCAvLyBlZy4gVHVlXG4gICAgICAgIGNvbnRlbnQ6IHRoaXMuZGF0ZUhlbHBlci5mb3JtYXQoZGF5Lm5hdGl2ZURhdGUsIHRoaXMuZ2V0VmVyeVNob3J0V2Vla0Zvcm1hdCgpKSwgLy8gZWcuIFR1LFxuICAgICAgICBpc1NlbGVjdGVkOiBmYWxzZSxcbiAgICAgICAgaXNEaXNhYmxlZDogZmFsc2UsXG4gICAgICAgIG9uQ2xpY2soKTogdm9pZCB7fSxcbiAgICAgICAgb25Nb3VzZUVudGVyKCk6IHZvaWQge31cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gd2Vla0RheXM7XG4gIH1cblxuICBwcml2YXRlIGdldFZlcnlTaG9ydFdlZWtGb3JtYXQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pMThuLmdldExvY2FsZUlkKCkudG9Mb3dlckNhc2UoKS5pbmRleE9mKCd6aCcpID09PSAwID8gJ0VFRUVFJyA6ICdFRUVFRUUnOyAvLyBVc2UgZXh0cmVtZSBzaG9ydCBmb3IgY2hpbmVzZVxuICB9XG5cbiAgbWFrZUJvZHlSb3dzKCk6IERhdGVCb2R5Um93W10ge1xuICAgIGNvbnN0IHdlZWtSb3dzOiBEYXRlQm9keVJvd1tdID0gW107XG4gICAgY29uc3QgZmlyc3REYXlPZk1vbnRoID0gdGhpcy5hY3RpdmVEYXRlLmNhbGVuZGFyU3RhcnQoeyB3ZWVrU3RhcnRzT246IHRoaXMuZGF0ZUhlbHBlci5nZXRGaXJzdERheU9mV2VlaygpIH0pO1xuXG4gICAgZm9yIChsZXQgd2VlayA9IDA7IHdlZWsgPCB0aGlzLk1BWF9ST1c7IHdlZWsrKykge1xuICAgICAgY29uc3Qgd2Vla1N0YXJ0ID0gZmlyc3REYXlPZk1vbnRoLmFkZERheXMod2VlayAqIDcpO1xuICAgICAgY29uc3Qgcm93OiBEYXRlQm9keVJvdyA9IHtcbiAgICAgICAgaXNBY3RpdmU6IGZhbHNlLFxuICAgICAgICBkYXRlQ2VsbHM6IFtdLFxuICAgICAgICB0cmFja0J5SW5kZXg6IHdlZWtcbiAgICAgIH07XG5cbiAgICAgIGZvciAobGV0IGRheSA9IDA7IGRheSA8IDc7IGRheSsrKSB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSB3ZWVrU3RhcnQuYWRkRGF5cyhkYXkpO1xuICAgICAgICBjb25zdCBkYXRlRm9ybWF0ID0gdHJhbnNDb21wYXRGb3JtYXQodGhpcy5pMThuLmdldExvY2FsZURhdGEoJ0RhdGVQaWNrZXIubGFuZy5kYXRlRm9ybWF0JywgJ1lZWVktTU0tREQnKSk7XG4gICAgICAgIGNvbnN0IHRpdGxlID0gdGhpcy5kYXRlSGVscGVyLmZvcm1hdChkYXRlLm5hdGl2ZURhdGUsIGRhdGVGb3JtYXQpO1xuICAgICAgICBjb25zdCBsYWJlbCA9IHRoaXMuZGF0ZUhlbHBlci5mb3JtYXQoZGF0ZS5uYXRpdmVEYXRlLCAnZGQnKTtcbiAgICAgICAgY29uc3QgY2VsbDogRGF0ZUNlbGwgPSB7XG4gICAgICAgICAgdHJhY2tCeUluZGV4OiBkYXksXG4gICAgICAgICAgdmFsdWU6IGRhdGUubmF0aXZlRGF0ZSxcbiAgICAgICAgICBsYWJlbCxcbiAgICAgICAgICBpc1NlbGVjdGVkOiBmYWxzZSxcbiAgICAgICAgICBpc0Rpc2FibGVkOiBmYWxzZSxcbiAgICAgICAgICBpc1RvZGF5OiBmYWxzZSxcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICBjZWxsUmVuZGVyOiB2YWx1ZUZ1bmN0aW9uUHJvcCh0aGlzLmNlbGxSZW5kZXIhLCBkYXRlKSwgLy8gQ3VzdG9taXplZCBjb250ZW50XG4gICAgICAgICAgZnVsbENlbGxSZW5kZXI6IHZhbHVlRnVuY3Rpb25Qcm9wKHRoaXMuZnVsbENlbGxSZW5kZXIhLCBkYXRlKSxcbiAgICAgICAgICBjb250ZW50OiBgJHtkYXRlLmdldERhdGUoKX1gLFxuICAgICAgICAgIG9uQ2xpY2s6ICgpID0+IHRoaXMuY2hhbmdlVmFsdWVGcm9tSW5zaWRlKGRhdGUpLFxuICAgICAgICAgIG9uTW91c2VFbnRlcjogKCkgPT4gdGhpcy5jZWxsSG92ZXIuZW1pdChkYXRlKSxcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmFkZENlbGxQcm9wZXJ0eShjZWxsLCBkYXRlKTtcblxuICAgICAgICBpZiAodGhpcy5zaG93V2VlayAmJiAhcm93LndlZWtOdW0pIHtcbiAgICAgICAgICByb3cud2Vla051bSA9IHRoaXMuZGF0ZUhlbHBlci5nZXRJU09XZWVrKGRhdGUubmF0aXZlRGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGUuaXNTYW1lRGF5KHRoaXMudmFsdWUpKSB7XG4gICAgICAgICAgcm93LmlzQWN0aXZlID0gZGF0ZS5pc1NhbWVEYXkodGhpcy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcm93LmRhdGVDZWxscy5wdXNoKGNlbGwpO1xuICAgICAgfVxuICAgICAgcm93LmNsYXNzTWFwID0ge1xuICAgICAgICBbYGFudC1waWNrZXItd2Vlay1wYW5lbC1yb3dgXTogdGhpcy5jYW5TZWxlY3RXZWVrLFxuICAgICAgICBbYGFudC1waWNrZXItd2Vlay1wYW5lbC1yb3ctc2VsZWN0ZWRgXTogdGhpcy5jYW5TZWxlY3RXZWVrICYmIHJvdy5pc0FjdGl2ZVxuICAgICAgfTtcbiAgICAgIHdlZWtSb3dzLnB1c2gocm93KTtcbiAgICB9XG4gICAgcmV0dXJuIHdlZWtSb3dzO1xuICB9XG5cbiAgYWRkQ2VsbFByb3BlcnR5KGNlbGw6IERhdGVDZWxsLCBkYXRlOiBDYW5keURhdGUpOiB2b2lkIHtcbiAgICBjZWxsLmlzVGVtcGxhdGVSZWYgPSBpc1RlbXBsYXRlUmVmKGNlbGwuY2VsbFJlbmRlcik7XG4gICAgY2VsbC5pc05vbkVtcHR5U3RyaW5nID0gIGlzTm9uRW1wdHlTdHJpbmcoY2VsbC5jZWxsUmVuZGVyKTtcbiAgICBpZiAodGhpcy5oYXNSYW5nZVZhbHVlKCkgJiYgIXRoaXMuY2FuU2VsZWN0V2Vlaykge1xuICAgICAgY29uc3QgW3N0YXJ0SG92ZXIsIGVuZEhvdmVyXSA9IHRoaXMuaG92ZXJWYWx1ZTtcbiAgICAgIGNvbnN0IFtzdGFydFNlbGVjdGVkLCBlbmRTZWxlY3RlZF0gPSB0aGlzLnNlbGVjdGVkVmFsdWU7XG4gICAgICAvLyBTZWxlY3RlZFxuICAgICAgaWYgKHN0YXJ0U2VsZWN0ZWQ/LmlzU2FtZURheShkYXRlKSkge1xuICAgICAgICBjZWxsLmlzU2VsZWN0ZWRTdGFydCA9IHRydWU7XG4gICAgICAgIGNlbGwuaXNTZWxlY3RlZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbmRTZWxlY3RlZD8uaXNTYW1lRGF5KGRhdGUpKSB7XG4gICAgICAgIGNlbGwuaXNTZWxlY3RlZEVuZCA9IHRydWU7XG4gICAgICAgIGNlbGwuaXNTZWxlY3RlZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGFydEhvdmVyICYmIGVuZEhvdmVyKSB7XG4gICAgICAgIGNlbGwuaXNIb3ZlclN0YXJ0ID0gc3RhcnRIb3Zlci5pc1NhbWVEYXkoZGF0ZSk7XG4gICAgICAgIGNlbGwuaXNIb3ZlckVuZCA9IGVuZEhvdmVyLmlzU2FtZURheShkYXRlKTtcbiAgICAgICAgY2VsbC5pc0xhc3RDZWxsSW5QYW5lbCA9IGRhdGUuaXNMYXN0RGF5T2ZNb250aCgpO1xuICAgICAgICBjZWxsLmlzRmlyc3RDZWxsSW5QYW5lbCA9IGRhdGUuaXNGaXJzdERheU9mTW9udGgoKTtcbiAgICAgICAgY2VsbC5pc0luSG92ZXJSYW5nZSA9IHN0YXJ0SG92ZXIuaXNCZWZvcmVEYXkoZGF0ZSkgJiYgZGF0ZS5pc0JlZm9yZURheShlbmRIb3Zlcik7XG4gICAgICB9XG4gICAgICBjZWxsLmlzU3RhcnRTaW5nbGUgPSBzdGFydFNlbGVjdGVkICYmICFlbmRTZWxlY3RlZDtcbiAgICAgIGNlbGwuaXNFbmRTaW5nbGUgPSAhc3RhcnRTZWxlY3RlZCAmJiBlbmRTZWxlY3RlZDtcbiAgICAgIGNlbGwuaXNJblNlbGVjdGVkUmFuZ2UgPSBzdGFydFNlbGVjdGVkPy5pc0JlZm9yZURheShkYXRlKSAmJiBkYXRlLmlzQmVmb3JlRGF5KGVuZFNlbGVjdGVkKTtcbiAgICAgIGNlbGwuaXNSYW5nZVN0YXJ0TmVhckhvdmVyID0gc3RhcnRTZWxlY3RlZCAmJiBjZWxsLmlzSW5Ib3ZlclJhbmdlO1xuICAgICAgY2VsbC5pc1JhbmdlRW5kTmVhckhvdmVyID0gZW5kU2VsZWN0ZWQgJiYgY2VsbC5pc0luSG92ZXJSYW5nZTtcbiAgICB9XG5cbiAgICBjZWxsLmlzVG9kYXkgPSBkYXRlLmlzVG9kYXkoKTtcbiAgICBjZWxsLmlzU2VsZWN0ZWQgPSBkYXRlLmlzU2FtZURheSh0aGlzLnZhbHVlKTtcbiAgICBjZWxsLmlzRGlzYWJsZWQgPSAhIXRoaXMuZGlzYWJsZWREYXRlPy4oZGF0ZS5uYXRpdmVEYXRlKTtcbiAgICBjZWxsLmNsYXNzTWFwID0gdGhpcy5nZXRDbGFzc01hcChjZWxsKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGdldENsYXNzTWFwKGNlbGw6IERhdGVDZWxsKTogeyBba2V5OiBzdHJpbmddOiBib29sZWFuIH0ge1xuICAgIGNvbnN0IGRhdGUgPSBuZXcgQ2FuZHlEYXRlKGNlbGwudmFsdWUpO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdXBlci5nZXRDbGFzc01hcChjZWxsKSxcbiAgICAgIFtgYW50LXBpY2tlci1jZWxsLXRvZGF5YF06ICEhY2VsbC5pc1RvZGF5LFxuICAgICAgW2BhbnQtcGlja2VyLWNlbGwtaW4tdmlld2BdOiBkYXRlLmlzU2FtZU1vbnRoKHRoaXMuYWN0aXZlRGF0ZSlcbiAgICB9O1xuICB9XG59XG4iLCI8dGFibGUgY2xhc3M9XCJhbnQtcGlja2VyLWNvbnRlbnRcIiBjZWxsc3BhY2luZz1cIjBcIiByb2xlPVwiZ3JpZFwiPlxuICBAaWYgKGhlYWRSb3cgJiYgaGVhZFJvdy5sZW5ndGggPiAwKSB7XG4gICAgPHRoZWFkPlxuICAgICAgPHRyIHJvbGU9XCJyb3dcIj5cbiAgICAgICAgQGlmIChzaG93V2Vlaykge1xuICAgICAgICAgIDx0aCByb2xlPVwiY29sdW1uaGVhZGVyXCI+PC90aD5cbiAgICAgICAgfVxuICAgICAgICBAZm9yIChjZWxsIG9mIGhlYWRSb3c7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgIDx0aCByb2xlPVwiY29sdW1uaGVhZGVyXCIgdGl0bGU9XCJ7eyBjZWxsLnRpdGxlIH19XCI+IHt7IGNlbGwuY29udGVudCB9fTwvdGg+XG4gICAgICAgIH1cbiAgICAgIDwvdHI+XG4gICAgPC90aGVhZD5cbiAgfVxuXG4gIDx0Ym9keT5cbiAgICBAZm9yIChyb3cgb2YgYm9keVJvd3M7IHRyYWNrIHJvdy50cmFja0J5SW5kZXgpIHtcbiAgICAgIDx0ciBbbmdDbGFzc109XCJyb3cuY2xhc3NNYXAhXCIgcm9sZT1cInJvd1wiPlxuICAgICAgICBAaWYgKHJvdy53ZWVrTnVtKSB7XG4gICAgICAgICAgPHRkIHJvbGU9XCJncmlkY2VsbFwiIGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LWNlbGwtd2Vla1wiPiB7eyByb3cud2Vla051bSB9fTwvdGQ+XG4gICAgICAgIH1cbiAgICAgICAgQGZvciAoY2VsbCBvZiByb3cuZGF0ZUNlbGxzOyB0cmFjayBjZWxsLnRyYWNrQnlJbmRleCkge1xuICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgdGl0bGU9XCJ7eyBjZWxsLnRpdGxlIH19XCJcbiAgICAgICAgICAgIHJvbGU9XCJncmlkY2VsbFwiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJjZWxsLmNsYXNzTWFwIVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiY2VsbC5pc0Rpc2FibGVkID8gbnVsbCA6IGNlbGwub25DbGljaygpXCJcbiAgICAgICAgICAgIChtb3VzZWVudGVyKT1cImNlbGwub25Nb3VzZUVudGVyKClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBzd2l0Y2ggKHByZWZpeENscykge1xuICAgICAgICAgICAgICBAY2FzZSAoJ2FudC1waWNrZXInKSB7XG4gICAgICAgICAgICAgICAgQGlmIChjZWxsLmlzVGVtcGxhdGVSZWYpIHtcbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCIkYW55KGNlbGwuY2VsbFJlbmRlcik7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjZWxsLnZhbHVlIH1cIiAvPlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGNlbGwuaXNOb25FbXB0eVN0cmluZykge1xuICAgICAgICAgICAgICAgICAgPHNwYW4gW2lubmVySFRNTF09XCJjZWxsLmNlbGxSZW5kZXJcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LWNlbGwtaW5uZXJcIlxuICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImNlbGwuaXNTZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtZGlzYWJsZWRdPVwiY2VsbC5pc0Rpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3sgY2VsbC5jb250ZW50IH19XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGNhc2UgKCdhbnQtcGlja2VyLWNhbGVuZGFyJykge1xuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LWRhdGUgYW50LXBpY2tlci1jZWxsLWlubmVyXCJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5hbnQtcGlja2VyLWNhbGVuZGFyLWRhdGUtdG9kYXldPVwiY2VsbC5pc1RvZGF5XCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICBAaWYgKGNlbGwuZnVsbENlbGxSZW5kZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIiRhbnkoY2VsbC5mdWxsQ2VsbFJlbmRlcik7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjZWxsLnZhbHVlIH1cIiAvPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tZGF0ZS12YWx1ZVwiPnt7IGNlbGwuY29udGVudCB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LWRhdGUtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCIkYW55KGNlbGwuY2VsbFJlbmRlcik7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjZWxsLnZhbHVlIH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3RkPlxuICAgICAgICB9XG5cbiAgICAgIDwvdHI+XG4gICAgfVxuICA8L3Rib2R5PlxuPC90YWJsZT5cbiJdfQ==