UNPKG

materialize-angular

Version:
387 lines 34.5 kB
/** * @fileoverview added by tsickle * Generated from: app/completed-components/calendar/calendar.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @license * Copyright Workylab. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://raw.githubusercontent.com/workylab/materialize-angular/master/LICENSE */ import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { config } from '../../config'; import { days } from '../../fixtures/calendar-week-days'; import { months } from '../../fixtures/calendar-months'; export class CalendarComponent { constructor() { this.className = CalendarComponent.defaultProps.className; this.date = CalendarComponent.defaultProps.date; this.displayOtherMonthDays = CalendarComponent.defaultProps.displayOtherMonthDays; this.prefix = config.components.prefix; this.selectYearAnimationDuration = 150; this.scrollToActiveYear = this.scrollToActiveYear.bind(this); this.onSelectDayEmitter = new EventEmitter(); this.dayLabels = this.getDayLabels(days); this.monthLabels = this.getMonthLabels(months); } /** * @return {?} */ ngOnInit() { this.init(); } /** * @return {?} */ ngOnChanges() { this.init(); } /** * @return {?} */ init() { /** @type {?} */ const dateExists = (typeof this.date !== 'undefined' && this.date !== null); /** @type {?} */ const openDate = dateExists ? this.date : new Date(); /** @type {?} */ const isToday = this.isTodayDate(openDate); /** @type {?} */ const month = openDate.getMonth(); /** @type {?} */ const year = openDate.getFullYear(); this.weeks = this.fillWeeks(month, year); this.years = this.fillYears(year); this.selectedDate = this.createDateModel(openDate, false, isToday, dateExists); } /** * @param {?} dayLabels * @return {?} */ getDayLabels(dayLabels) { return [ dayLabels.sunday, dayLabels.monday, dayLabels.tuesday, dayLabels.wednesday, dayLabels.thursday, dayLabels.friday, dayLabels.saturday ]; } /** * @param {?} monthLabels * @return {?} */ getMonthLabels(monthLabels) { return [ monthLabels.january, monthLabels.february, monthLabels.march, monthLabels.april, monthLabels.may, monthLabels.june, monthLabels.july, monthLabels.august, monthLabels.september, monthLabels.october, monthLabels.november, monthLabels.december ]; } /** * @param {?} date * @param {?} isOutOfMonth * @param {?} isToday * @param {?} showSelected * @return {?} */ createDateModel(date, isOutOfMonth, isToday, showSelected) { /** @type {?} */ const weekDay = date.getDay(); /** @type {?} */ const month = date.getMonth(); /** @type {?} */ const dateModel = { ISODate: this.generateISODate(date), date: date, dayLabel: this.dayLabels[weekDay], isOutOfMonth: isOutOfMonth, isToday: isToday, monthLabel: this.monthLabels[month], showSelected: showSelected }; return dateModel; } /** * @param {?} day * @param {?} month * @param {?} year * @return {?} */ createDateObject(day, month, year) { /** @type {?} */ const date = new Date(); date.setDate(day); date.setMonth(month); date.setFullYear(year); return date; } /** * @param {?} currentYear * @return {?} */ fillYears(currentYear) { /** @type {?} */ const firstYear = currentYear - 100; /** @type {?} */ const lastYear = currentYear + 100; /** @type {?} */ const years = []; for (let i = firstYear; i <= lastYear; i++) { years.push(i); } return years; } /** * @param {?} month * @param {?} year * @return {?} */ fillWeeks(month, year) { this.selectedMonth = { label: this.monthLabels[month], number: month, year: year }; /** @type {?} */ const finalMonthDay = this.createDateObject(0, month, year); /** @type {?} */ const weeks = []; /** @type {?} */ let initMonthDate = new Date(year, month, 1); /** @type {?} */ let day = 0 - initMonthDate.getDay(); /** @type {?} */ let daysInWeek = []; while (initMonthDate.getDay() !== 0 || finalMonthDay >= initMonthDate) { ++day; initMonthDate = new Date(year, month, day); daysInWeek.push(this.createDayDate(initMonthDate, day, finalMonthDay)); if (daysInWeek.length === 7) { weeks.push(daysInWeek); daysInWeek = []; } } return weeks; } /** * @param {?} date * @return {?} */ isTodayDate(date) { /** @type {?} */ const ISOCurrentDate = this.generateISODate(new Date()); /** @type {?} */ const ISODate = this.generateISODate(date); /** @type {?} */ const isToday = (ISODate === ISOCurrentDate); return isToday; } /** * @param {?} date * @param {?} dayNumber * @param {?} finalMonthDay * @return {?} */ createDayDate(date, dayNumber, finalMonthDay) { /** @type {?} */ const isToday = this.isTodayDate(date); /** @type {?} */ const isOutOfMonth = (dayNumber <= 0 || date > finalMonthDay); return this.createDateModel(date, isOutOfMonth, isToday, true); } /** * @return {?} */ showPrevMonth() { /** @type {?} */ const month = this.selectedMonth.number; /** @type {?} */ const year = this.selectedMonth.year; /** @type {?} */ const prevMonth = month >= 1 ? month - 1 : 11; /** @type {?} */ const prevYear = month < 1 ? year - 1 : year; this.weeks = this.fillWeeks(prevMonth, prevYear); } /** * @return {?} */ showNextMonth() { /** @type {?} */ const month = this.selectedMonth.number; /** @type {?} */ const year = this.selectedMonth.year; /** @type {?} */ const nextMonth = month < 11 ? month + 1 : 0; /** @type {?} */ const nextYear = month >= 11 ? year + 1 : year; this.weeks = this.fillWeeks(nextMonth, nextYear); } /** * @param {?} date * @return {?} */ generateISODate(date) { /** @type {?} */ const day = date.getDate(); /** @type {?} */ const month = date.getMonth() + 1; /** @type {?} */ const year = date.getFullYear(); /** @type {?} */ const dayString = day > 9 ? day : `0${day}`; /** @type {?} */ const monthString = month > 9 ? month : `0${month}`; return `${year}-${monthString}-${dayString}`; } /** * @param {?} date * @return {?} */ onSelectDay(date) { if (date.isOutOfMonth) { return; } this.selectedDate = date; this.onSelectDayEmitter.emit(this.selectedDate); } /** * @param {?} year * @return {?} */ onSelectYear(year) { setTimeout((/** * @return {?} */ () => { /** @type {?} */ const day = this.selectedDate.date.getDate(); /** @type {?} */ const month = this.selectedDate.date.getMonth(); this.date = this.createDateObject(day, month, year); this.showYears = false; this.selectedDate = this.createDateModel(this.date, false, true, true); this.weeks = this.fillWeeks(month, year); }), this.selectYearAnimationDuration); } /** * @return {?} */ displayYears() { this.showYears = true; setTimeout(this.scrollToActiveYear, 0); } /** * @return {?} */ scrollToActiveYear() { const { nativeElement } = this.yearsContainerRef; /** @type {?} */ const activeYear = nativeElement.querySelector('.selected'); if (activeYear) { /** @type {?} */ const top = this.getScrollCenter(nativeElement, activeYear); nativeElement.scrollTop = top; } } /** * @param {?} container * @param {?} internalElement * @return {?} */ getScrollCenter(container, internalElement) { /** @type {?} */ const yearTop = internalElement.offsetTop; /** @type {?} */ const yearMiddleHeight = internalElement.offsetHeight / 2; /** @type {?} */ const containerTop = container.offsetTop; /** @type {?} */ const containerMiddleHeight = container.offsetHeight / 2; /** @type {?} */ const elementRelativeTop = (yearTop - containerTop) - (containerMiddleHeight - yearMiddleHeight); if (elementRelativeTop < 0) { return 0; } return elementRelativeTop; } } CalendarComponent.defaultProps = { className: '', date: new Date(), displayOtherMonthDays: true }; CalendarComponent.decorators = [ { type: Component, args: [{ selector: `${config.components.prefix}-calendar }`, template: "<div [ngClass]=\"[prefix + '-calendar', className]\">\n <div [ngClass]=\"prefix + '-calendar-header'\">\n <div [ngClass]=\"prefix + '-calendar-year'\">\n <materialize-button (onClick)=\"displayYears()\">{{ selectedMonth.year }}</materialize-button>\n </div>\n <div [ngClass]=\"prefix + '-calendar-date'\">\n <materialize-button (onClick)=\"showYears = false\">\n {{ selectedDate.dayLabel.shortName }}, {{ selectedDate.monthLabel.shortName }} {{ selectedDate.date.getDate() }}\n </materialize-button>\n </div>\n </div>\n\n <div [ngClass]=\"prefix + '-calendar-body'\">\n <ng-container *ngIf=\"!showYears\">\n <div [ngClass]=\"prefix + '-calendar-controls'\">\n <div [ngClass]=\"prefix + '-calendar-control'\" materializeRipple (click)=\"showPrevMonth()\">\n <materialize-icon>chevron_left</materialize-icon>\n </div>\n <div [ngClass]=\"prefix + '-calendar-month'\">\n {{ selectedMonth.label.shortName }} {{ selectedMonth.year }}\n </div>\n <div [ngClass]=\"prefix + '-calendar-control'\" materializeRipple (click)=\"showNextMonth()\">\n <materialize-icon>chevron_right</materialize-icon>\n </div>\n </div>\n \n <table [ngClass]=\"prefix + '-calendar-table'\">\n <thead>\n <tr>\n <td [ngClass]=\"prefix + '-calendar-day-name'\" *ngFor=\"let day of dayLabels\">{{ day.shortestName }}</td>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let week of weeks\">\n <td *ngFor=\"let day of week\">\n <div [ngClass]=\"prefix + '-calendar-day'\"\n (click)=\"onSelectDay(day)\"\n *ngIf=\"!day.isOutOfMonth || displayOtherMonthDays\"\n \n [class.current]=\"day.isToday\"\n [class.selected]=\"selectedDate.showSelected && selectedDate.ISODate === day.ISODate\"\n [class.disabled]=\"day.isOutOfMonth\"\n \n materializeRipple\n [rippleDuration]=\"800\"\n >\n {{ day.date.getDate() }}\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </ng-container>\n \n <div [ngClass]=\"prefix + '-calendar-years'\" #yearsContainer>\n <ng-container *ngIf=\"showYears\">\n <div [ngClass]=\"prefix + '-calendar-year-option'\"\n *ngFor=\"let year of years\"\n\n (click)=\"onSelectYear(year)\"\n [class.selected]=\"year === selectedMonth.year\"\n\n materializeRipple\n [rippleDuration]=\"selectYearAnimationDuration\"\n >\n {{ year }}\n </div>\n </ng-container>\n </div>\n </div>\n</div>\n" }] } ]; /** @nocollapse */ CalendarComponent.ctorParameters = () => []; CalendarComponent.propDecorators = { yearsContainerRef: [{ type: ViewChild, args: ['yearsContainer', { static: false },] }], onSelectDayEmitter: [{ type: Output, args: ['onSelectDay',] }], className: [{ type: Input }], date: [{ type: Input }], displayOtherMonthDays: [{ type: Input }] }; if (false) { /** @type {?} */ CalendarComponent.defaultProps; /** @type {?} */ CalendarComponent.prototype.yearsContainerRef; /** @type {?} */ CalendarComponent.prototype.onSelectDayEmitter; /** @type {?} */ CalendarComponent.prototype.className; /** @type {?} */ CalendarComponent.prototype.date; /** @type {?} */ CalendarComponent.prototype.displayOtherMonthDays; /** @type {?} */ CalendarComponent.prototype.prefix; /** @type {?} */ CalendarComponent.prototype.dayLabels; /** @type {?} */ CalendarComponent.prototype.monthLabels; /** @type {?} */ CalendarComponent.prototype.selectedDate; /** @type {?} */ CalendarComponent.prototype.selectedMonth; /** @type {?} */ CalendarComponent.prototype.showYears; /** @type {?} */ CalendarComponent.prototype.weeks; /** @type {?} */ CalendarComponent.prototype.years; /** @type {?} */ CalendarComponent.prototype.selectYearAnimationDuration; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbWF0ZXJpYWxpemUtYW5ndWxhci8iLCJzb3VyY2VzIjpbImFwcC9jb21wbGV0ZWQtY29tcG9uZW50cy9jYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBU0EsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqSCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUN6RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFNeEQsTUFBTSxPQUFPLGlCQUFpQjtJQTJCNUI7UUFoQlMsY0FBUyxHQUFXLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUM7UUFDN0QsU0FBSSxHQUFTLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7UUFDakQsMEJBQXFCLEdBQVksaUJBQWlCLENBQUMsWUFBWSxDQUFDLHFCQUFxQixDQUFDO1FBRXhGLFdBQU0sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQVVsQyxnQ0FBMkIsR0FBRyxHQUFHLENBQUM7UUFHdkMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksWUFBWSxFQUFhLENBQUM7UUFFeEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMs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V29ya3lsYWIuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3dvcmt5bGFiL21hdGVyaWFsaXplLWFuZ3VsYXIvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBDYWxlbmRhck1vZGVsLCBEYXRlTGFiZWwsIERhdGVNb2RlbCwgRGF5TGFiZWxzLCBNb250aExhYmVscywgTW9udGhNb2RlbCB9IGZyb20gJy4vY2FsZW5kYXIubW9kZWwnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uSW5pdCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gJy4uLy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBkYXlzIH0gZnJvbSAnLi4vLi4vZml4dHVyZXMvY2FsZW5kYXItd2Vlay1kYXlzJztcbmltcG9ydCB7IG1vbnRocyB9IGZyb20gJy4uLy4uL2ZpeHR1cmVzL2NhbGVuZGFyLW1vbnRocyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogYCR7IGNvbmZpZy5jb21wb25lbnRzLnByZWZpeCB9LWNhbGVuZGFyIH1gLFxuICB0ZW1wbGF0ZVVybDogJy4vY2FsZW5kYXIuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIENhbGVuZGFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBzdGF0aWMgcmVhZG9ubHkgZGVmYXVsdFByb3BzOiBDYWxlbmRhck1vZGVsID0ge1xuICAgIGNsYXNzTmFtZTogJycsXG4gICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICBkaXNwbGF5T3RoZXJNb250aERheXM6IHRydWVcbiAgfTtcblxuICBAVmlld0NoaWxkKCd5ZWFyc0NvbnRhaW5lcicsIHsgc3RhdGljOiBmYWxzZSB9KSB5ZWFyc0NvbnRhaW5lclJlZjogRWxlbWVudFJlZjtcblxuICBAT3V0cHV0KCdvblNlbGVjdERheScpIG9uU2VsZWN0RGF5RW1pdHRlcjogRXZlbnRFbWl0dGVyPERhdGVNb2RlbD47XG5cbiAgQElucHV0KCkgY2xhc3NOYW1lOiBzdHJpbmcgPSBDYWxlbmRhckNvbXBvbmVudC5kZWZhdWx0UHJvcHMuY2xhc3NOYW1lO1xuICBASW5wdXQoKSBkYXRlOiBEYXRlID0gQ2FsZW5kYXJDb21wb25lbnQuZGVmYXVsdFByb3BzLmRhdGU7XG4gIEBJbnB1dCgpIGRpc3BsYXlPdGhlck1vbnRoRGF5czogYm9vbGVhbiA9IENhbGVuZGFyQ29tcG9uZW50LmRlZmF1bHRQcm9wcy5kaXNwbGF5T3RoZXJNb250aERheXM7XG5cbiAgcHVibGljIHByZWZpeCA9IGNvbmZpZy5jb21wb25lbnRzLnByZWZpeDtcblxuICBwdWJsaWMgZGF5TGFiZWxzOiBBcnJheTxEYXRlTGFiZWw+O1xuICBwdWJsaWMgbW9udGhMYWJlbHM6IEFycmF5PERhdGVMYWJlbD47XG4gIHB1YmxpYyBzZWxlY3RlZERhdGU6IERhdGVNb2RlbDtcbiAgcHVibGljIHNlbGVjdGVkTW9udGg6IE1vbnRoTW9kZWw7XG4gIHB1YmxpYyBzaG93WWVhcnM6IGJvb2xlYW47XG4gIHB1YmxpYyB3ZWVrczogQXJyYXk8QXJyYXk8RGF0ZU1vZGVsPj47XG4gIHB1YmxpYyB5ZWFyczogQXJyYXk8bnVtYmVyPjtcblxuICBwdWJsaWMgc2VsZWN0WWVhckFuaW1hdGlvbkR1cmF0aW9uID0gMTUwO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuc2Nyb2xsVG9BY3RpdmVZZWFyID0gdGhpcy5zY3JvbGxUb0FjdGl2ZVllYXIuYmluZCh0aGlzKTtcblxuICAgIHRoaXMub25TZWxlY3REYXlFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlTW9kZWw+KCk7XG5cbiAgICB0aGlzLmRheUxhYmVscyA9IHRoaXMuZ2V0RGF5TGFiZWxzKGRheXMpO1xuICAgIHRoaXMubW9udGhMYWJlbHMgPSB0aGlzLmdldE1vbnRoTGFiZWxzKG1vbnRocyk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgaW5pdCgpIHtcbiAgICBjb25zdCBkYXRlRXhpc3RzID0gKHR5cGVvZiB0aGlzLmRhdGUgIT09ICd1bmRlZmluZWQnICYmIHRoaXMuZGF0ZSAhPT0gbnVsbCk7XG4gICAgY29uc3Qgb3BlbkRhdGUgPSBkYXRlRXhpc3RzID8gdGhpcy5kYXRlIDogbmV3IERhdGUoKTtcbiAgICBjb25zdCBpc1RvZGF5ID0gdGhpcy5pc1RvZGF5RGF0ZShvcGVuRGF0ZSk7XG4gICAgY29uc3QgbW9udGggPSBvcGVuRGF0ZS5nZXRNb250aCgpO1xuICAgIGNvbnN0IHllYXIgPSBvcGVuRGF0ZS5nZXRGdWxsWWVhcigpO1xuXG4gICAgdGhpcy53ZWVrcyA9IHRoaXMuZmlsbFdlZWtzKG1vbnRoLCB5ZWFyKTtcbiAgICB0aGlzLnllYXJzID0gdGhpcy5maWxsWWVhcnMoeWVhcik7XG5cbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IHRoaXMuY3JlYXRlRGF0ZU1vZGVsKG9wZW5EYXRlLCBmYWxzZSwgaXNUb2RheSwgZGF0ZUV4aXN0cyk7XG4gIH1cblxuICBnZXREYXlMYWJlbHMoZGF5TGFiZWxzOiBEYXlMYWJlbHMpOiBBcnJheTxEYXRlTGFiZWw+IHtcbiAgICByZXR1cm4gW1xuICAgICAgZGF5TGFiZWxzLnN1bmRheSxcbiAgICAgIGRheUxhYmVscy5tb25kYXksXG4gICAgICBkYXlMYWJlbHMudHVlc2RheSxcbiAgICAgIGRheUxhYmVscy53ZWRuZXNkYXksXG4gICAgICBkYXlMYWJlbHMudGh1cnNkYXksXG4gICAgICBkYXlMYWJlbHMuZnJpZGF5LFxuICAgICAgZGF5TGFiZWxzLnNhdHVyZGF5XG4gICAgXTtcbiAgfVxuXG4gIGdldE1vbnRoTGFiZWxzKG1vbnRoTGFiZWxzOiBNb250aExhYmVscyk6IEFycmF5PERhdGVMYWJlbD4ge1xuICAgIHJldHVybiBbXG4gICAgICBtb250aExhYmVscy5qYW51YXJ5LFxuICAgICAgbW9udGhMYWJlbHMuZmVicnVhcnksXG4gICAgICBtb250aExhYmVscy5tYXJjaCxcbiAgICAgIG1vbnRoTGFiZWxzLmFwcmlsLFxuICAgICAgbW9udGhMYWJlbHMubWF5LFxuICAgICAgbW9udGhMYWJlbHMuanVuZSxcbiAgICAgIG1vbnRoTGFiZWxzLmp1bHksXG4gICAgICBtb250aExhYmVscy5hdWd1c3QsXG4gICAgICBtb250aExhYmVscy5zZXB0ZW1iZXIsXG4gICAgICBtb250aExhYmVscy5vY3RvYmVyLFxuICAgICAgbW9udGhMYWJlbHMubm92ZW1iZXIsXG4gICAgICBtb250aExhYmVscy5kZWNlbWJlclxuICAgIF07XG4gIH1cblxuICBjcmVhdGVEYXRlTW9kZWwoZGF0ZTogRGF0ZSwgaXNPdXRPZk1vbnRoOiBib29sZWFuLCBpc1RvZGF5OiBib29sZWFuLCBzaG93U2VsZWN0ZWQ6IGJvb2xlYW4pOiBEYXRlTW9kZWwge1xuICAgIGNvbnN0IHdlZWtEYXkgPSBkYXRlLmdldERheSgpO1xuICAgIGNvbnN0IG1vbnRoID0gZGF0ZS5nZXRNb250aCgpO1xuXG4gICAgY29uc3QgZGF0ZU1vZGVsOiBEYXRlTW9kZWwgPSB7XG4gICAgICBJU09EYXRlOiB0aGlzLmdlbmVyYXRlSVNPRGF0ZShkYXRlKSxcbiAgICAgIGRhdGU6IGRhdGUsXG4gICAgICBkYXlMYWJlbDogdGhpcy5kYXlMYWJlbHNbd2Vla0RheV0sXG4gICAgICBpc091dE9mTW9udGg6IGlzT3V0T2ZNb250aCxcbiAgICAgIGlzVG9kYXk6IGlzVG9kYXksXG4gICAgICBtb250aExhYmVsOiB0aGlzLm1vbnRoTGFiZWxzW21vbnRoXSxcbiAgICAgIHNob3dTZWxlY3RlZDogc2hvd1NlbGVjdGVkXG4gICAgfTtcblxuICAgIHJldHVybiBkYXRlTW9kZWw7XG4gIH1cblxuICBjcmVhdGVEYXRlT2JqZWN0KGRheTogbnVtYmVyLCBtb250aDogbnVtYmVyLCB5ZWFyOiBudW1iZXIpOiBEYXRlIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcblxuICAgIGRhdGUuc2V0RGF0ZShkYXkpO1xuICAgIGRhdGUuc2V0TW9udGgobW9udGgpO1xuICAgIGRhdGUuc2V0RnVsbFllYXIoeWVhcik7XG5cbiAgICByZXR1cm4gZGF0ZTtcbiAgfVxuXG4gIGZpbGxZZWFycyhjdXJyZW50WWVhcjogbnVtYmVyKTogQXJyYXk8bnVtYmVyPiB7XG4gICAgY29uc3QgZmlyc3RZZWFyID0gY3VycmVudFllYXIgLSAxMDA7XG4gICAgY29uc3QgbGFzdFllYXIgPSBjdXJyZW50WWVhciArIDEwMDtcbiAgICBjb25zdCB5ZWFycyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IGZpcnN0WWVhcjsgaSA8PSBsYXN0WWVhcjsgaSsrKSB7XG4gICAgICB5ZWFycy5wdXNoKGkpO1xuICAgIH1cblxuICAgIHJldHVybiB5ZWFycztcbiAgfVxuXG4gIGZpbGxXZWVrcyhtb250aDogbnVtYmVyLCB5ZWFyOiBudW1iZXIpIHtcbiAgICB0aGlzLnNlbGVjdGVkTW9udGggPSB7XG4gICAgICBsYWJlbDogdGhpcy5tb250aExhYmVsc1ttb250aF0sXG4gICAgICBudW1iZXI6IG1vbnRoLFxuICAgICAgeWVhcjogeWVhclxuICAgIH07XG5cbiAgICBjb25zdCBmaW5hbE1vbnRoRGF5ID0gdGhpcy5jcmVhdGVEYXRlT2JqZWN0KDAsIG1vbnRoLCB5ZWFyKTtcbiAgICBjb25zdCB3ZWVrcyA9IFtdO1xuXG4gICAgbGV0IGluaXRNb250aERhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSk7XG4gICAgbGV0IGRheSA9IDAgLSBpbml0TW9udGhEYXRlLmdldERheSgpO1xuICAgIGxldCBkYXlzSW5XZWVrID0gW107XG5cbiAgICB3aGlsZSAoaW5pdE1vbnRoRGF0ZS5nZXREYXkoKSAhPT0gMCB8fCBmaW5hbE1vbnRoRGF5ID49IGluaXRNb250aERhdGUpIHtcbiAgICAgICsrZGF5O1xuXG4gICAgICBpbml0TW9udGhEYXRlID0gbmV3IERhdGUoeWVhciwgbW9udGgsIGRheSk7XG5cbiAgICAgIGRheXNJbldlZWsucHVzaCh0aGlzLmNyZWF0ZURheURhdGUoaW5pdE1vbnRoRGF0ZSwgZGF5LCBmaW5hbE1vbnRoRGF5KSk7XG5cbiAgICAgIGlmIChkYXlzSW5XZWVrLmxlbmd0aCA9PT0gNykge1xuICAgICAgICB3ZWVrcy5wdXNoKGRheXNJbldlZWspO1xuICAgICAgICBkYXlzSW5XZWVrID0gW107XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHdlZWtzO1xuICB9XG5cbiAgaXNUb2RheURhdGUoZGF0ZTogRGF0ZSkge1xuICAgIGNvbnN0IElTT0N1cnJlbnREYXRlID0gdGhpcy5nZW5lcmF0ZUlTT0RhdGUobmV3IERhdGUoKSk7XG4gICAgY29uc3QgSVNPRGF0ZSA9IHRoaXMuZ2VuZXJhdGVJU09EYXRlKGRhdGUpO1xuICAgIGNvbnN0IGlzVG9kYXkgPSAoSVNPRGF0ZSA9PT0gSVNPQ3VycmVudERhdGUpO1xuXG4gICAgcmV0dXJuIGlzVG9kYXk7XG4gIH1cblxuICBjcmVhdGVEYXlEYXRlKGRhdGU6IERhdGUsIGRheU51bWJlcjogbnVtYmVyLCBmaW5hbE1vbnRoRGF5OiBEYXRlKTogRGF0ZU1vZGVsIHtcbiAgICBjb25zdCBpc1RvZGF5ID0gdGhpcy5pc1RvZGF5RGF0ZShkYXRlKTtcbiAgICBjb25zdCBpc091dE9mTW9udGggPSAoZGF5TnVtYmVyIDw9IDAgfHwgZGF0ZSA+IGZpbmFsTW9udGhEYXkpO1xuXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlRGF0ZU1vZGVsKGRhdGUsIGlzT3V0T2ZNb250aCwgaXNUb2RheSwgdHJ1ZSk7XG4gIH1cblxuICBzaG93UHJldk1vbnRoKCkge1xuICAgIGNvbnN0IG1vbnRoID0gdGhpcy5zZWxlY3RlZE1vbnRoLm51bWJlcjtcbiAgICBjb25zdCB5ZWFyID0gdGhpcy5zZWxlY3RlZE1vbnRoLnllYXI7XG5cbiAgICBjb25zdCBwcmV2TW9udGggPSBtb250aCA+PSAxXG4gICAgICA/IG1vbnRoIC0gMVxuICAgICAgOiAxMTtcblxuICAgIGNvbnN0IHByZXZZZWFyID0gbW9udGggPCAxXG4gICAgICA/IHllYXIgLSAxXG4gICAgICA6IHllYXI7XG5cbiAgICB0aGlzLndlZWtzID0gdGhpcy5maWxsV2Vla3MocHJldk1vbnRoLCBwcmV2WWVhcik7XG4gIH1cblxuICBzaG93TmV4dE1vbnRoKCkge1xuICAgIGNvbnN0IG1vbnRoID0gdGhpcy5zZWxlY3RlZE1vbnRoLm51bWJlcjtcbiAgICBjb25zdCB5ZWFyID0gdGhpcy5zZWxlY3RlZE1vbnRoLnllYXI7XG5cbiAgICBjb25zdCBuZXh0TW9udGggPSBtb250aCA8IDExXG4gICAgICA/IG1vbnRoICsgMVxuICAgICAgOiAwO1xuXG4gICAgY29uc3QgbmV4dFllYXIgPSBtb250aCA+PSAxMVxuICAgICAgPyB5ZWFyICsgMVxuICAgICAgOiB5ZWFyO1xuXG4gICAgdGhpcy53ZWVrcyA9IHRoaXMuZmlsbFdlZWtzKG5leHRNb250aCwgbmV4dFllYXIpO1xuICB9XG5cbiAgZ2VuZXJhdGVJU09EYXRlKGRhdGU6IERhdGUpIHtcbiAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKTtcbiAgICBjb25zdCBtb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIDE7XG4gICAgY29uc3QgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblxuICAgIGNvbnN0IGRheVN0cmluZyA9IGRheSA+IDlcbiAgICAgID8gZGF5XG4gICAgICA6IGAwJHsgZGF5IH1gO1xuXG4gICAgY29uc3QgbW9udGhTdHJpbmcgPSBtb250aCA+IDlcbiAgICAgID8gbW9udGhcbiAgICAgIDogYDAkeyBtb250aCB9YDtcblxuICAgIHJldHVybiBgJHsgeWVhciB9LSR7IG1vbnRoU3RyaW5nIH0tJHsgZGF5U3RyaW5nIH1gO1xuICB9XG5cbiAgb25TZWxlY3REYXkoZGF0ZTogRGF0ZU1vZGVsKSB7XG4gICAgaWYgKGRhdGUuaXNPdXRPZk1vbnRoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBkYXRlO1xuICAgIHRoaXMub25TZWxlY3REYXlFbWl0dGVyLmVtaXQodGhpcy5zZWxlY3RlZERhdGUpO1xuICB9XG5cbiAgb25TZWxlY3RZZWFyKHllYXI6IG51bWJlcikge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3QgZGF5ID0gdGhpcy5zZWxlY3RlZERhdGUuZGF0ZS5nZXREYXRlKCk7XG4gICAgICBjb25zdCBtb250aCA9IHRoaXMuc2VsZWN0ZWREYXRlLmRhdGUuZ2V0TW9udGgoKTtcblxuICAgICAgdGhpcy5kYXRlID0gdGhpcy5jcmVhdGVEYXRlT2JqZWN0KGRheSwgbW9udGgsIHllYXIpO1xuICAgICAgdGhpcy5zaG93WWVhcnMgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gdGhpcy5jcmVhdGVEYXRlTW9kZWwodGhpcy5kYXRlLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgICAgIHRoaXMud2Vla3MgPSB0aGlzLmZpbGxXZWVrcyhtb250aCwgeWVhcik7XG4gICAgfSwgdGhpcy5zZWxlY3RZZWFyQW5pbWF0aW9uRHVyYXRpb24pO1xuICB9XG5cbiAgZGlzcGxheVllYXJzKCkge1xuICAgIHRoaXMuc2hvd1llYXJzID0gdHJ1ZTtcblxuICAgIHNldFRpbWVvdXQodGhpcy5zY3JvbGxUb0FjdGl2ZVllYXIsIDApO1xuICB9XG5cbiAgc2Nyb2xsVG9BY3RpdmVZZWFyKCkge1xuICAgIGNvbnN0IHsgbmF0aXZlRWxlbWVudCB9ID0gdGhpcy55ZWFyc0NvbnRhaW5lclJlZjtcbiAgICBjb25zdCBhY3RpdmVZZWFyOiBIVE1MRWxlbWVudCA9IG5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjdGVkJyk7XG5cbiAgICBpZiAoYWN0aXZlWWVhcikge1xuICAgICAgY29uc3QgdG9wID0gdGhpcy5nZXRTY3JvbGxDZW50ZXIobmF0aXZlRWxlbWVudCwgYWN0aXZlWWVhcik7XG5cbiAgICAgIG5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wID0gdG9wO1xuICAgIH1cbiAgfVxuXG4gIGdldFNjcm9sbENlbnRlcihjb250YWluZXI6IEhUTUxFbGVtZW50LCBpbnRlcm5hbEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogbnVtYmVyIHtcbiAgICBjb25zdCB5ZWFyVG9wID0gaW50ZXJuYWxFbGVtZW50Lm9mZnNldFRvcDtcbiAgICBjb25zdCB5ZWFyTWlkZGxlSGVpZ2h0ID0gaW50ZXJuYWxFbGVtZW50Lm9mZnNldEhlaWdodCAvIDI7XG5cbiAgICBjb25zdCBjb250YWluZXJUb3AgPSBjb250YWluZXIub2Zmc2V0VG9wO1xuICAgIGNvbnN0IGNvbnRhaW5lck1pZGRsZUhlaWdodCA9IGNvbnRhaW5lci5vZmZzZXRIZWlnaHQgLyAyO1xuXG4gICAgY29uc3QgZWxlbWVudFJlbGF0aXZlVG9wID0gKHllYXJUb3AgLSBjb250YWluZXJUb3ApIC0gKGNvbnRhaW5lck1pZGRsZUhlaWdodCAtIHllYXJNaWRkbGVIZWlnaHQpO1xuXG4gICAgaWYgKGVsZW1lbnRSZWxhdGl2ZVRvcCA8IDApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIHJldHVybiBlbGVtZW50UmVsYXRpdmVUb3A7XG4gIH1cbn1cbiJdfQ==