@junte/ui
Version:
Quality Angular UI components kit
200 lines • 27.1 kB
JavaScript
var CalendarComponent_1;
import { __decorate, __metadata } from "tslib";
import { Component, ContentChild, ContentChildren, EventEmitter, forwardRef, HostBinding, HostListener, Input, Output, QueryList, TemplateRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { addDays, addMonths, addWeeks, addYears, getMonth, getYear, isSameMonth, startOfWeek, subMonths, subYears } from 'date-fns';
import { NGXLogger } from 'ngx-logger';
import { JunteUIConfig } from '../../config';
import { PropertyApi } from '../../core/decorators/api';
import { Feature } from '../../core/enums/feature';
import { UI } from '../../core/enums/ui';
import { I18N_PROVIDERS } from '../../core/i18n/providers';
import { today } from './utils';
import { WeekMetricComponent } from './week/week-metric.component';
const WEEKS_DISPLAYED = 6;
const DAYS_IN_WEEK = 7;
const DATE_ROWS = 3;
const DATE_COLS = 4;
var ViewType;
(function (ViewType) {
ViewType["date"] = "date";
ViewType["year"] = "year";
ViewType["month"] = "month";
})(ViewType || (ViewType = {}));
let CalendarComponent = CalendarComponent_1 = class CalendarComponent {
constructor(logger, config) {
this.logger = logger;
this.config = config;
this.host = 'jnt-calendar-host';
this.ui = UI;
this._period = today();
this.weeks = [];
this.months = [];
this.years = [];
this.viewType = ViewType;
this.view = ViewType.date;
this.features = [];
this.updated = new EventEmitter();
this.selected = new EventEmitter();
this.disabled = false;
this.onChange = () => this.logger.debug('value accessor is not registered');
this.onTouched = () => this.logger.debug('value accessor is not registered');
this.registerOnChange = fn => this.onChange = fn;
this.registerOnTouched = fn => this.onTouched = fn;
this.onBlur = () => this.onTouched();
}
set period(period) {
if (!isSameMonth(this._period, period)) {
this._period = period;
this.update();
}
}
get period() {
return this._period;
}
ngOnInit() {
this.update();
}
writeValue(date) {
this.current = date;
this.period = date || today();
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
select(date) {
this.current = date;
this.onChange(date);
this.selected.emit(date);
}
today() {
const now = new Date();
this.period = now;
this.select(now);
}
add() {
if (this.view === ViewType.date) {
this.period = addMonths(this.period, 1);
}
else if (this.view === ViewType.month) {
this.period = addYears(this.period, 1);
}
else {
this.period = addYears(this.period, 12);
}
}
sub() {
if (this.view === ViewType.date) {
this.period = subMonths(this.period, 1);
}
else if (this.view === ViewType.month) {
this.period = subYears(this.period, 1);
}
else {
this.period = subYears(this.period, 12);
}
}
update() {
const start = startOfWeek(new Date(getYear(this.period), getMonth(this.period), 1), { locale: this.config.locale.dfns });
let date = start;
this.weeks = [];
for (let i = 0; i < WEEKS_DISPLAYED; i++) {
this.weeks[i] = { days: [], date: date };
for (let j = 0; j < DAYS_IN_WEEK; j++) {
this.weeks[i].days[j] = addDays(date, j);
}
date = addWeeks(date, 1);
}
this.updated.emit({ start: start, end: date });
for (let i = 0; i < DATE_ROWS; i++) {
this.months[i] = [];
for (let j = 0; j < DATE_COLS; j++) {
this.months[i].push(new Date(getYear(this.period), i * DATE_COLS + j, 1));
}
}
for (let i = 0; i < DATE_ROWS; i++) {
this.years[i] = [];
for (let j = 0; j < DATE_COLS; j++) {
this.years[i].push(new Date(getYear(this.period) - 4 + i * DATE_COLS + j, i * DATE_COLS + j, 1));
}
}
}
};
CalendarComponent.ctorParameters = () => [
{ type: NGXLogger },
{ type: JunteUIConfig }
];
__decorate([
HostBinding('attr.host'),
__metadata("design:type", Object)
], CalendarComponent.prototype, "host", void 0);
__decorate([
PropertyApi({
description: 'Calendar features',
path: 'ui.feature',
options: [Feature.today]
}),
Input(),
__metadata("design:type", Array)
], CalendarComponent.prototype, "features", void 0);
__decorate([
ContentChildren(WeekMetricComponent),
__metadata("design:type", QueryList)
], CalendarComponent.prototype, "metrics", void 0);
__decorate([
ContentChild('calendarDayTemplate'),
__metadata("design:type", TemplateRef)
], CalendarComponent.prototype, "dayTemplate", void 0);
__decorate([
ContentChild('calendarMetricTemplate'),
__metadata("design:type", TemplateRef)
], CalendarComponent.prototype, "metricTemplate", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], CalendarComponent.prototype, "updated", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], CalendarComponent.prototype, "selected", void 0);
__decorate([
PropertyApi({
description: 'Set disabled state',
type: 'boolean',
default: 'false',
}),
HostBinding('attr.data-disabled'),
Input(),
__metadata("design:type", Object)
], CalendarComponent.prototype, "disabled", void 0);
__decorate([
PropertyApi({
description: 'Set current month for displaying',
type: 'Date'
}),
Input('month'),
__metadata("design:type", Date),
__metadata("design:paramtypes", [Date])
], CalendarComponent.prototype, "period", null);
__decorate([
HostListener('blur'),
__metadata("design:type", Object)
], CalendarComponent.prototype, "onBlur", void 0);
CalendarComponent = CalendarComponent_1 = __decorate([
Component({
selector: 'jnt-calendar',
template: "<jnt-stack child-of=\"jnt-calendar-host\" [align]=\"ui.align.stretch\">\n <table child-of=\"jnt-calendar-host\" >\n <thead child-of=\"jnt-calendar-host\" >\n <tr child-of=\"jnt-calendar-host\" >\n <td child-of=\"jnt-calendar-host\" >\n <jnt-button child-of=\"jnt-calendar-host\" data-arrow [icon]=\"ui.icons.chevronLeft\"\n [outline]=\"ui.outline.transparent\"\n [scheme]=\"ui.scheme.secondary\"\n [size]=\"ui.size.small\"\n (click)=\"sub()\">\n </jnt-button>\n </td>\n <td child-of=\"jnt-calendar-host\" *ngIf=\"view === viewType.date\" (click)=\"view = viewType.month\" colspan=\"5\">\n <jnt-button child-of=\"jnt-calendar-host\" data-date [outline]=\"ui.outline.transparent\"\n [scheme]=\"ui.scheme.secondary\"\n [size]=\"ui.size.small\"\n text=\"{{period | jntFormat: 'LLLL'}}, {{period | jntFormat: 'yyyy'}}\"></jnt-button>\n </td>\n <td child-of=\"jnt-calendar-host\" *ngIf=\"view === viewType.month\" (click)=\"view = viewType.year\" colspan=\"2\">\n <jnt-button child-of=\"jnt-calendar-host\" data-date [outline]=\"ui.outline.transparent\"\n [scheme]=\"ui.scheme.secondary\"\n [size]=\"ui.size.small\"\n [width]=\"ui.width.fluid\"\n text=\"{{period | jntFormat: 'yyyy'}}\">\n </jnt-button>\n </td>\n <td child-of=\"jnt-calendar-host\" *ngIf=\"view === viewType.year\" colspan=\"2\" data-year>\n {{(period | jntGetYear) - 4}} - {{(period | jntGetYear) + 7}}\n </td>\n <td child-of=\"jnt-calendar-host\" >\n <jnt-button child-of=\"jnt-calendar-host\" data-arrow [icon]=\"ui.icons.chevronRight\"\n [outline]=\"ui.outline.transparent\"\n [scheme]=\"ui.scheme.secondary\"\n [size]=\"ui.size.small\"\n (click)=\"add()\">\n </jnt-button>\n </td>\n <td child-of=\"jnt-calendar-host\" data-divider *ngIf=\"metrics.length\"></td>\n <td child-of=\"jnt-calendar-host\" data-metrics *ngIf=\"metrics.length\"\n [translate]=\"'label.metrics'\"\n [attr.colspan]=\"metrics.length\">\n Metrics\n </td>\n </tr>\n <tr child-of=\"jnt-calendar-host\" data-days *ngIf=\"view === viewType.date; else empty\">\n <th child-of=\"jnt-calendar-host\" *ngFor=\"let weekDay of [0,1,2,3,4,5,6]\">{{weekDay | jntWeekdayName:'x2'}}</th>\n\n <th child-of=\"jnt-calendar-host\" data-divider *ngIf=\"!!metrics.length\"></th>\n\n <th child-of=\"jnt-calendar-host\" data-metric *ngFor=\"let m of metrics\">\n {{m.title}}\n </th>\n </tr>\n\n <ng-template #empty>\n <tr child-of=\"jnt-calendar-host\" data-days>\n <th child-of=\"jnt-calendar-host\" *ngFor=\"let col of [1,2,3,4]\"></th>\n </tr>\n </ng-template>\n </thead>\n\n <tbody child-of=\"jnt-calendar-host\" >\n <ng-container *ngIf=\"view === viewType.date\">\n <tr child-of=\"jnt-calendar-host\" *ngFor=\"let w of weeks\"\n [attr.data-current-week]=\"(current | jntStartOfWeek) | jntIsEqual: (w.date | jntStartOfWeek)\">\n <td child-of=\"jnt-calendar-host\" data-day *ngFor=\"let d of w.days\"\n [attr.data-today]=\"d | jntIsToday\"\n [attr.data-current-month]=\"(d | jntStartOfMonth) | jntIsEqual: (period | jntStartOfMonth)\"\n [attr.data-selected-day]=\"(d | jntStartOfDay) | jntIsEqual: (current | jntStartOfDay)\"\n (click)=\"select(d)\" tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"!!dayTemplate ? dayTemplate: defaultDayTemplate;context:{date: d}\">\n </ng-container>\n </td>\n\n <td child-of=\"jnt-calendar-host\" data-divider *ngIf=\"!!metrics.length\"></td>\n\n <td child-of=\"jnt-calendar-host\" data-metric *ngFor=\"let m of metrics;let i = index;\">\n <ng-container *ngTemplateOutlet=\"metricTemplate;context:{metric: i, date: w.date}\">\n </ng-container>\n </td>\n </tr>\n </ng-container>\n\n <ng-container *ngIf=\"view === viewType.month\">\n <tr child-of=\"jnt-calendar-host\" *ngFor=\"let row of months\">\n <td child-of=\"jnt-calendar-host\" data-day data-day-extend *ngFor=\"let month of row\"\n [attr.data-current-month]=\"month | jntIsThisMonth\"\n [attr.data-selected-month]=\"(month | jntStartOfMonth) | jntIsEqual: (current | jntStartOfMonth)\"\n (click)=\"period = month; view = viewType.date\">\n {{month | jntFormat: 'LLL'}}\n </td>\n </tr>\n </ng-container>\n\n <ng-container *ngIf=\"view === viewType.year\">\n <tr child-of=\"jnt-calendar-host\" *ngFor=\"let row of years\">\n <td child-of=\"jnt-calendar-host\" data-day data-day-extend data-year *ngFor=\"let year of row\"\n [attr.data-current-year]=\"year | jntIsThisYear\"\n [attr.data-selected-year]=\"(year | jntStartOfYear) | jntIsEqual: (current | jntStartOfYear)\"\n (click)=\"period = year; view = viewType.month\">\n {{year | jntFormat: 'yyyy'}}\n </td>\n </tr>\n </ng-container>\n\n </tbody>\n </table>\n <jnt-stack child-of=\"jnt-calendar-host\" *ngIf=\"features | includes : ui.feature.today\" [align]=\"ui.align.center\">\n <jnt-button child-of=\"jnt-calendar-host\" [scheme]=\"ui.scheme.secondary\"\n [size]=\"ui.size.small\"\n [icon]=\"ui.icons.today\"\n text=\"Today\"\n (click)=\"today()\">\n </jnt-button>\n </jnt-stack>\n</jnt-stack>\n\n<ng-template #defaultDayTemplate let-date=\"date\">\n <div child-of=\"jnt-calendar-host\" data-default>{{date | jntGetDate}}</div>\n</ng-template>",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CalendarComponent_1),
multi: true
},
...I18N_PROVIDERS
]
}),
__metadata("design:paramtypes", [NGXLogger,
JunteUIConfig])
], CalendarComponent);
export { CalendarComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGp1bnRlL3VpLyIsInNvdXJjZXMiOlsibGliL2Zvcm1zL2NhbGVuZGFyL2NhbGVuZGFyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLGVBQWUsRUFDZixZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixTQUFTLEVBQ1QsV0FBVyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQ0wsT0FBTyxFQUFFLFNBQVMsRUFDbEIsUUFBUSxFQUNSLFFBQVEsRUFDUixRQUFRLEVBQ1IsT0FBTyxFQUNQLFdBQVcsRUFDWCxXQUFXLEVBQ1gsU0FBUyxFQUNULFFBQVEsRUFDVCxNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDaEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFbkUsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLFNBQVMsR0FBRyxDQUFD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QUFDLG9CQUFvQixDQUFDO0lBQ2pDLEtBQUssRUFBRTs7bURBQ1M7QUFPakI7SUFMQyxXQUFXLENBQUM7UUFDWCxXQUFXLEVBQUUsa0NBQWtDO1FBQy9DLElBQUksRUFBRSxNQUFNO0tBQ2IsQ0FBQztJQUNELEtBQUssQ0FBQyxPQUFPLENBQUM7OEJBQ0ksSUFBSTtxQ0FBSixJQUFJOytDQUt0QjtBQVVxQjtJQUFyQixZQUFZLENBQUMsTUFBTSxDQUFDOztpREFBaUM7QUFyRTNDLGlCQUFpQjtJQVo3QixTQUFTLENBQUM7UUFDVCxRQUFRLEVBQUUsY0FBYztRQUN4Qiw4dkxBQTJDO1FBQzNDLFNBQVMsRUFBRTtZQUNUO2dCQUNFLE9BQU8sRUFBRSxpQkFBaUI7Z0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsbUJBQWlCLENBQUM7Z0JBQ2hELEtBQUssRUFBRSxJQUFJO2FBQ1o7WUFDRCxHQUFHLGNBQWM7U0FDbEI7S0FDRixDQUFDO3FDQXdFNEIsU0FBUztRQUNWLGFBQWE7R0F4RTdCLGlCQUFpQixDQW9KN0I7U0FwSlksaUJBQWlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVGVtcGxhdGVSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBhZGREYXlzLCBhZGRNb250aHMsXG4gIGFkZFdlZWtzLFxuICBhZGRZZWFycyxcbiAgZ2V0TW9udGgsXG4gIGdldFllYXIsXG4gIGlzU2FtZU1vbnRoLFxuICBzdGFydE9mV2VlayxcbiAgc3ViTW9udGhzLFxuICBzdWJZZWFyc1xufSBmcm9tICdkYXRlLWZucyc7XG5pbXBvcnQgeyBOR1hMb2dnZXIgfSBmcm9tICduZ3gtbG9nZ2VyJztcbmltcG9ydCB7IEp1bnRlVUlDb25maWcgfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHsgUHJvcGVydHlBcGkgfSBmcm9tICcuLi8uLi9jb3JlL2RlY29yYXRvcnMvYXBpJztcbmltcG9ydCB7IEZlYXR1cmUgfSBmcm9tICcuLi8uLi9jb3JlL2VudW1zL2ZlYXR1cmUnO1xuaW1wb3J0IHsgVUkgfSBmcm9tICcuLi8uLi9jb3JlL2VudW1zL3VpJztcbmltcG9ydCB7IEkxOE5fUFJPVklERVJTIH0gZnJvbSAnLi4vLi4vY29yZS9pMThuL3Byb3ZpZGVycyc7XG5pbXBvcnQgeyBQZXJpb2QgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IHRvZGF5IH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBXZWVrTWV0cmljQ29tcG9uZW50IH0gZnJvbSAnLi93ZWVrL3dlZWstbWV0cmljLmNvbXBvbmVudCc7XG5cbmNvbnN0IFdFRUtTX0RJU1BMQVlFRCA9IDY7XG5jb25zdCBEQVlTX0lOX1dFRUsgPSA3O1xuY29uc3QgREFURV9ST1dTID0gMztcbmNvbnN0IERBVEVfQ09MUyA9IDQ7XG5cbmVudW0gVmlld1R5cGUge1xuICBkYXRlID0gJ2RhdGUnLFxuICB5ZWFyID0gJ3llYXInLFxuICBtb250aCA9ICdtb250aCdcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnam50LWNhbGVuZGFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmVuY2Fwc3VsYXRlZC5odG1sJyxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBDYWxlbmRhckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH0sXG4gICAgLi4uSTE4Tl9QUk9WSURFUlNcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQge1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5ob3N0JylcbiAgcmVhZG9ubHkgaG9zdCA9ICdqbnQtY2FsZW5kYXItaG9zdCc7XG5cbiAgdWkgPSBVSTtcblxuICBwcml2YXRlIF9wZXJpb2Q6IERhdGUgPSB0b2RheSgpO1xuXG4gIGN1cnJlbnQ6IERhdGU7XG5cbiAgd2Vla3MgPSBbXTtcbiAgbW9udGhzID0gW107XG4gIHllYXJzID0gW107XG4gIHZpZXdUeXBlID0gVmlld1R5cGU7XG4gIHZpZXc6IFZpZXdUeXBlID0gVmlld1R5cGUuZGF0ZTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnQ2FsZW5kYXIgZmVhdHVyZXMnLFxuICAgIHBhdGg6ICd1aS5mZWF0dXJlJyxcbiAgICBvcHRpb25zOiBbRmVhdHVyZS50b2RheV1cbiAgfSlcbiAgQElucHV0KClcbiAgZmVhdHVyZXM6IEZlYXR1cmVbXSA9IFtdO1xuXG4gIEBDb250ZW50Q2hpbGRyZW4oV2Vla01ldHJpY0NvbXBvbmVudClcbiAgbWV0cmljczogUXVlcnlMaXN0PFdlZWtNZXRyaWNDb21wb25lbnQ+O1xuXG4gIEBDb250ZW50Q2hpbGQoJ2NhbGVuZGFyRGF5VGVtcGxhdGUnKVxuICBkYXlUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBAQ29udGVudENoaWxkKCdjYWxlbmRhck1ldHJpY1RlbXBsYXRlJylcbiAgbWV0cmljVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgQE91dHB1dCgpXG4gIHVwZGF0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFBlcmlvZD4oKTtcblxuICBAT3V0cHV0KClcbiAgc2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGU+KCk7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1NldCBkaXNhYmxlZCBzdGF0ZScsXG4gICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlZmF1bHQ6ICdmYWxzZScsXG4gIH0pXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLWRpc2FibGVkJylcbiAgQElucHV0KClcbiAgZGlzYWJsZWQgPSBmYWxzZTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnU2V0IGN1cnJlbnQgbW9udGggZm9yIGRpc3BsYXlpbmcnLFxuICAgIHR5cGU6ICdEYXRlJ1xuICB9KVxuICBASW5wdXQoJ21vbnRoJylcbiAgc2V0IHBlcmlvZChwZXJpb2Q6IERhdGUpIHtcbiAgICBpZiAoIWlzU2FtZU1vbnRoKHRoaXMuX3BlcmlvZCwgcGVyaW9kKSkge1xuICAgICAgdGhpcy5fcGVyaW9kID0gcGVyaW9kO1xuICAgICAgdGhpcy51cGRhdGUoKTtcbiAgICB9XG4gIH1cblxuICBnZXQgcGVyaW9kKCkge1xuICAgIHJldHVybiB0aGlzLl9wZXJpb2Q7XG4gIH1cblxuICBvbkNoYW5nZTogKGRhdGU6IERhdGUpID0+IHZvaWQgPSAoKSA9PiB0aGlzLmxvZ2dlci5kZWJ1ZygndmFsdWUgYWNjZXNzb3IgaXMgbm90IHJlZ2lzdGVyZWQnKTtcbiAgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4gdGhpcy5sb2dnZXIuZGVidWcoJ3ZhbHVlIGFjY2Vzc29yIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIHJlZ2lzdGVyT25DaGFuZ2UgPSBmbiA9PiB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIHJlZ2lzdGVyT25Ub3VjaGVkID0gZm4gPT4gdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpIG9uQmx1ciA9ICgpID0+IHRoaXMub25Ub3VjaGVkKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBsb2dnZXI6IE5HWExvZ2dlcixcbiAgICAgICAgICAgICAgcHVibGljIGNvbmZpZzogSnVudGVVSUNvbmZpZykge1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIHdyaXRlVmFsdWUoZGF0ZTogRGF0ZSk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudCA9IGRhdGU7XG4gICAgdGhpcy5wZXJpb2QgPSBkYXRlIHx8IHRvZGF5KCk7XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxuXG4gIHNlbGVjdChkYXRlOiBEYXRlKSB7XG4gICAgdGhpcy5jdXJyZW50ID0gZGF0ZTtcbiAgICB0aGlzLm9uQ2hhbmdlKGRhdGUpO1xuICAgIHRoaXMuc2VsZWN0ZWQuZW1pdChkYXRlKTtcbiAgfVxuXG4gIHRvZGF5KCkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgdGhpcy5wZXJpb2QgPSBub3c7XG4gICAgdGhpcy5zZWxlY3Qobm93KTtcbiAgfVxuXG4gIGFkZCgpIHtcbiAgICBpZih0aGlzLnZpZXcgPT09IFZpZXdUeXBlLmRhdGUpIHtcbiAgICAgIHRoaXMucGVyaW9kID0gYWRkTW9udGhzKHRoaXMucGVyaW9kLCAxKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudmlldyA9PT0gVmlld1R5cGUubW9udGgpIHtcbiAgICAgIHRoaXMucGVyaW9kID0gYWRkWWVhcnModGhpcy5wZXJpb2QsIDEpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGVyaW9kID0gYWRkWWVhcnModGhpcy5wZXJpb2QsIDEyKVxuICAgIH1cbiAgfVxuXG4gIHN1YigpIHtcbiAgICBpZih0aGlzLnZpZXcgPT09IFZpZXdUeXBlLmRhdGUpIHtcbiAgICAgIHRoaXMucGVyaW9kID0gc3ViTW9udGhzKHRoaXMucGVyaW9kLCAxKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudmlldyA9PT0gVmlld1R5cGUubW9udGgpIHtcbiAgICAgIHRoaXMucGVyaW9kID0gc3ViWWVhcnModGhpcy5wZXJpb2QsIDEpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGVyaW9kID0gc3ViWWVhcnModGhpcy5wZXJpb2QsIDEyKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlKCkge1xuICAgIGNvbnN0IHN0YXJ0ID0gc3RhcnRPZldlZWsobmV3IERhdGUoZ2V0WWVhcih0aGlzLnBlcmlvZCksIGdldE1vbnRoKHRoaXMucGVyaW9kKSwgMSksXG4gICAgICB7bG9jYWxlOiB0aGlzLmNvbmZpZy5sb2NhbGUuZGZuc30pO1xuICAgIGxldCBkYXRlID0gc3RhcnQ7XG4gICAgdGhpcy53ZWVrcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgV0VFS1NfRElTUExBWUVEOyBpKyspIHtcbiAgICAgIHRoaXMud2Vla3NbaV0gPSB7ZGF5czogW10sIGRhdGU6IGRhdGV9O1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBEQVlTX0lOX1dFRUs7IGorKykge1xuICAgICAgICB0aGlzLndlZWtzW2ldLmRheXNbal0gPSBhZGREYXlzKGRhdGUsIGopO1xuICAgICAgfVxuICAgICAgZGF0ZSA9IGFkZFdlZWtzKGRhdGUsIDEpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZWQuZW1pdCh7c3RhcnQ6IHN0YXJ0LCBlbmQ6IGRhdGV9KTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgREFURV9ST1dTOyBpKyspIHtcbiAgICAgIHRoaXMubW9udGhzW2ldID0gW107XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IERBVEVfQ09MUzsgaisrKSB7XG4gICAgICAgIHRoaXMubW9udGhzW2ldLnB1c2gobmV3IERhdGUoZ2V0WWVhcih0aGlzLnBlcmlvZCksIGkgKiBEQVRFX0NPTFMgKyBqLCAxKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBEQVRFX1JPV1M7IGkrKykge1xuICAgICAgdGhpcy55ZWFyc1tpXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBEQVRFX0NPTFM7IGorKykge1xuICAgICAgICB0aGlzLnllYXJzW2ldLnB1c2gobmV3IERhdGUoZ2V0WWVhcih0aGlzLnBlcmlvZCkgLSA0ICsgaSAqIERBVEVfQ09MUyArIGosIGkgKiBEQVRFX0NPTFMgKyBqLCAxKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=