UNPKG

truly-ui

Version:

Web Components for Desktop Applications.

166 lines (164 loc) 28.2 kB
/* MIT License Copyright (c) 2018 Temainfo Software Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { Component, EventEmitter, Input, Output } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "../../directives/holiday-tooltip"; import * as i3 from "../../pipes/holiday"; export class TlCalendarDays { set currentDate(value) { if (this._currentDate.getMonth() !== new Date(value).getMonth()) { this._currentDate = new Date(value); this.buildCalendar(); } this.selectedDate = new Date(value); this._currentDate = new Date(value); } get currentDate() { return this._currentDate; } constructor() { this.holidays = []; this.borders = false; this.width = '300px'; this.height = '200px'; this.selectDay = new EventEmitter(); this.doubleClick = new EventEmitter(); this.dayOfMonth = []; this.selectedDate = new Date(); this.groupIndex = 0; this.dayOfWeek = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']; this._currentDate = new Date(); } ngOnInit() { this.buildCalendar(); } buildCalendar() { this.dayOfMonth = []; const daysByWeek = []; for (let i = 1; i <= new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 0).getDate(); i++) { daysByWeek.push({ dayOfWeek: this.getDateObject(i).getDay(), date: this.getDateObject(i), day: new Date(this.currentDate.getFullYear(), 0, i).getDate() }); } this.setGroupIndex(daysByWeek); this.setBeforeDays(); this.setAfterDays(); } setGroupIndex(daysByWeek) { this.dayOfMonth = this.groupBy(daysByWeek, 'dayOfWeek'); this.dayOfMonth.forEach((item, groupIndex) => { item.forEach((value) => { if (value.day === 1) { this.groupIndex = groupIndex; } }); }); } setBeforeDays() { if (this.groupIndex === 0) { this.groupIndex = 7; } for (let i = 0; i < this.groupIndex; i++) { this.dayOfMonth[i].unshift({ dayOfWeek: i, date: this.getDateObject(this.dayOfMonth[i][0].day - 7), day: this.getDateObject(this.dayOfMonth[i][0].day - 7).getDate() }); } } selectDate(date) { this.selectedDate = date; if (date.getMonth() !== this.currentDate.getMonth()) { this.currentDate = date; this.buildCalendar(); } this.selectDay.emit(this.selectedDate); } setAfterDays() { this.dayOfMonth.forEach((array, index) => { if (array.length < 6) { do { array.push({ dayOfWeek: index, date: this.getDateObject(array[array.length - 1].day + 7, array[array.length - 1].date.getMonth()), day: this.getDateObject(array[array.length - 1].day + 7).getDate() }); } while (array.length < 6); } }); } isCurrentDate(date) { if (!date) { return false; } const select = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0).getTime(); const current = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate(), 0, 0, 0, 0).getTime(); return select === current; } isOtherMonth(item) { return item.date.getMonth() !== this.currentDate.getMonth(); } today() { this.currentDate = new Date(); } isToday(date) { const today = new Date(new Date().setHours(0, 0, 0, 0)); const day = new Date(date.setHours(0, 0, 0, 0)); return today.getTime() === day.getTime(); } getDateObject(day, month) { return new Date(this.currentDate.getFullYear(), month ? month : this.currentDate.getMonth(), day); } groupBy(xs, key) { const objectArray = xs.reduce((rv, x) => { (rv[x[key]] = rv[x[key]] || []).push(x); return rv; }, []); objectArray.length = Object.keys(objectArray).length; return objectArray; } ngOnChanges(changes) { } } /** @nocollapse */ TlCalendarDays.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlCalendarDays, deps: [], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ TlCalendarDays.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TlCalendarDays, selector: "tl-days", inputs: { currentDate: "currentDate", holidays: "holidays", borders: "borders", width: "width", height: "height" }, outputs: { selectDay: "selectDay", doubleClick: "doubleClick" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ui-calendar-days\">\n <ng-container *ngTemplateOutlet=\"templateGrid\"></ng-container>\n</div>\n\n<ng-template #templateGrid>\n <ng-template ngFor let-item let-index [ngForOf]=\"dayOfMonth\">\n <ng-container *ngTemplateOutlet=\"templateLine; context: { $implicit: item }\"></ng-container>\n </ng-template>\n</ng-template>\n\n<ng-template let-item #templateCell>\n <ng-container *ngIf=\"item?.date | holiday:holidays as dayArray\">\n <div class=\"ui-calendar-cell\"\n [class.borders]=\"borders\"\n [class.today]=\"isToday(item?.date)\"\n (dblclick)=\"doubleClick.emit()\"\n (click)=\"selectDate( item?.date )\"\n [tooltipDay]=\"dayArray\"\n [tooltipHoliday]=\"dayArray?.length > 0\"\n [class.holiday]=\"dayArray?.length > 0\"\n [class.sunday]=\"item?.dayOfWeek === 0 && !isOtherMonth(item)\"\n [class.selected]=\"isCurrentDate( item?.date )\"\n [class.ui-other-month]=\"isOtherMonth(item)\">{{ item.day }}\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #templateLine let-item>\n <div class=\"ui-calendar-line\" [class.borders]=\"borders\">\n <ng-template ngFor let-item [ngForOf]=\"item\">\n <ng-template\n [ngTemplateOutlet]=\"templateCell\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\">\n </ng-template>\n </ng-template>\n </div>\n</ng-template>\n", styles: [":host{width:100%;height:100%}.ui-calendar-body{flex:1}.ui-calendar-days{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.ui-calendar-line{display:flex;height:100%;width:100%;flex-flow:column}.ui-calendar-line:last-child{border-right:0}.ui-calendar-cell{flex:1;display:flex;justify-content:center;align-items:center;font-size:1em;font-weight:500;-webkit-user-select:none;user-select:none;font-family:Segoe UI;box-sizing:border-box;transition:background .2s linear;border-radius:5px}.ui-calendar-cell.selected:not(.holiday){background:rgba(102,204,153,.1)}.ui-calendar-cell:hover{cursor:pointer}.ui-calendar-cell.today{font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.TlHolidayTooltipDirective, selector: "[tooltipHoliday]", inputs: ["tooltipHoliday", "tooltipDay"] }, { kind: "pipe", type: i3.TlHolidayPipe, name: "holiday" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlCalendarDays, decorators: [{ type: Component, args: [{ selector: 'tl-days', template: "<div class=\"ui-calendar-days\">\n <ng-container *ngTemplateOutlet=\"templateGrid\"></ng-container>\n</div>\n\n<ng-template #templateGrid>\n <ng-template ngFor let-item let-index [ngForOf]=\"dayOfMonth\">\n <ng-container *ngTemplateOutlet=\"templateLine; context: { $implicit: item }\"></ng-container>\n </ng-template>\n</ng-template>\n\n<ng-template let-item #templateCell>\n <ng-container *ngIf=\"item?.date | holiday:holidays as dayArray\">\n <div class=\"ui-calendar-cell\"\n [class.borders]=\"borders\"\n [class.today]=\"isToday(item?.date)\"\n (dblclick)=\"doubleClick.emit()\"\n (click)=\"selectDate( item?.date )\"\n [tooltipDay]=\"dayArray\"\n [tooltipHoliday]=\"dayArray?.length > 0\"\n [class.holiday]=\"dayArray?.length > 0\"\n [class.sunday]=\"item?.dayOfWeek === 0 && !isOtherMonth(item)\"\n [class.selected]=\"isCurrentDate( item?.date )\"\n [class.ui-other-month]=\"isOtherMonth(item)\">{{ item.day }}\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #templateLine let-item>\n <div class=\"ui-calendar-line\" [class.borders]=\"borders\">\n <ng-template ngFor let-item [ngForOf]=\"item\">\n <ng-template\n [ngTemplateOutlet]=\"templateCell\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\">\n </ng-template>\n </ng-template>\n </div>\n</ng-template>\n", styles: [":host{width:100%;height:100%}.ui-calendar-body{flex:1}.ui-calendar-days{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.ui-calendar-line{display:flex;height:100%;width:100%;flex-flow:column}.ui-calendar-line:last-child{border-right:0}.ui-calendar-cell{flex:1;display:flex;justify-content:center;align-items:center;font-size:1em;font-weight:500;-webkit-user-select:none;user-select:none;font-family:Segoe UI;box-sizing:border-box;transition:background .2s linear;border-radius:5px}.ui-calendar-cell.selected:not(.holiday){background:rgba(102,204,153,.1)}.ui-calendar-cell:hover{cursor:pointer}.ui-calendar-cell.today{font-weight:700}\n"] }] }], ctorParameters: function () { return []; }, propDecorators: { currentDate: [{ type: Input, args: ['currentDate'] }], holidays: [{ type: Input }], borders: [{ type: Input }], width: [{ type: Input }], height: [{ type: Input }], selectDay: [{ type: Output }], doubleClick: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItZGF5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL2NhbGVuZGFyL3BhcnRzL2NhbGVuZGFyLWRheXMvY2FsZW5kYXItZGF5cy50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL2NhbGVuZGFyL3BhcnRzL2NhbGVuZGFyLWRheXMvY2FsZW5kYXItZGF5cy5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQW9CRTtBQUVGLE9BQU8sRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFnQixNQUFNLGVBQWUsQ0FBQzs7Ozs7QUFjdkcsTUFBTSxPQUFPLGNBQWM7SUFFekIsSUFDSSxXQUFXLENBQUMsS0FBSztRQUNuQixJQUFLLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDaEUsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDdEI7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBd0JEO1FBdEJTLGFBQVEsR0FBMkIsRUFBRSxDQUFDO1FBRXRDLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFFaEIsVUFBSyxHQUFHLE9BQU8sQ0FBQztRQUVoQixXQUFN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LE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICAgIE1JVCBMaWNlbnNlXG5cbiAgICBDb3B5cmlnaHQgKGMpIDIwMTggVGVtYWluZm8gU29mdHdhcmVcblxuICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAgICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gICAgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICAgIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiAgICBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAgICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICAgIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuICAgIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICAgIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICAgIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICAgIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAgICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICAgIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gICAgU09GVFdBUkUuXG4qL1xuXG5pbXBvcnQge0NvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlc30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NhbGVuZGFySG9saWRheX0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9jYWxlbmRhci1ob2xpZGF5LmludGVyZmFjZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJEYXlzSW50ZXJmYWNlIHtcbiAgZGF5T2ZXZWVrOiBudW1iZXI7XG4gIGRhdGU6IERhdGU7XG4gIGRheTogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0bC1kYXlzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLWRheXMuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NhbGVuZGFyLWRheXMuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBUbENhbGVuZGFyRGF5cyBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoJ2N1cnJlbnREYXRlJylcbiAgc2V0IGN1cnJlbnREYXRlKHZhbHVlKSB7XG4gICAgaWYgKCB0aGlzLl9jdXJyZW50RGF0ZS5nZXRNb250aCgpICE9PSBuZXcgRGF0ZSh2YWx1ZSkuZ2V0TW9udGgoKSkge1xuICAgICAgdGhpcy5fY3VycmVudERhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICB0aGlzLmJ1aWxkQ2FsZW5kYXIoKTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgdGhpcy5fY3VycmVudERhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gIH1cblxuICBnZXQgY3VycmVudERhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnREYXRlO1xuICB9XG5cbiAgQElucHV0KCkgaG9saWRheXM6IEFycmF5PENhbGVuZGFySG9saWRheT4gPSBbXTtcblxuICBASW5wdXQoKSBib3JkZXJzID0gZmFsc2U7XG5cbiAgQElucHV0KCkgd2lkdGggPSAnMzAwcHgnO1xuXG4gIEBJbnB1dCgpIGhlaWdodCA9ICcyMDBweCc7XG5cbiAgQE91dHB1dCgpIHNlbGVjdERheSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAT3V0cHV0KCkgZG91YmxlQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgcHVibGljIGRheU9mTW9udGg6IEFycmF5PENhbGVuZGFyRGF5c0ludGVyZmFjZVtdPiA9IFtdO1xuXG4gIHB1YmxpYyBzZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSgpO1xuXG4gIHB1YmxpYyBncm91cEluZGV4ID0gMDtcblxuICBwdWJsaWMgZGF5T2ZXZWVrID0gWydEb20nLCAnU2VnJywgJ1RlcicsICdRdWEnLCAnUXVpJywgJ1NleCcsICdTYWInXTtcblxuICBwcml2YXRlIF9jdXJyZW50RGF0ZSA9IG5ldyBEYXRlKCk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmJ1aWxkQ2FsZW5kYXIoKTtcbiAgfVxuXG4gIGJ1aWxkQ2FsZW5kYXIoKSB7XG4gICAgdGhpcy5kYXlPZk1vbnRoID0gW107XG4gICAgY29uc3QgZGF5c0J5V2VlayA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IG5ldyBEYXRlKHRoaXMuY3VycmVudERhdGUuZ2V0RnVsbFllYXIoKSwgdGhpcy5jdXJyZW50RGF0ZS5nZXRNb250aCgpICsgMSwgMCkuZ2V0RGF0ZSgpOyBpKyspIHtcbiAgICAgIGRheXNCeVdlZWsucHVzaCh7XG4gICAgICAgIGRheU9mV2VlazogdGhpcy5nZXREYXRlT2JqZWN0KGkpLmdldERheSgpLFxuICAgICAgICBkYXRlOiB0aGlzLmdldERhdGVPYmplY3QoaSksXG4gICAgICAgIGRheTogbmV3IERhdGUodGhpcy5jdXJyZW50RGF0ZS5nZXRGdWxsWWVhcigpLCAwLCBpKS5nZXREYXRlKClcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnNldEdyb3VwSW5kZXgoIGRheXNCeVdlZWsgKTtcbiAgICB0aGlzLnNldEJlZm9yZURheXMoKTtcbiAgICB0aGlzLnNldEFmdGVyRGF5cygpO1xuICB9XG5cbiAgc2V0R3JvdXBJbmRleCggZGF5c0J5V2VlayApIHtcbiAgICB0aGlzLmRheU9mTW9udGggPSB0aGlzLmdyb3VwQnkoZGF5c0J5V2VlaywgJ2RheU9mV2VlaycpO1xuICAgIHRoaXMuZGF5T2ZNb250aC5mb3JFYWNoKChpdGVtLCBncm91cEluZGV4KSA9PiB7XG4gICAgICBpdGVtLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICAgIGlmICh2YWx1ZS5kYXkgPT09IDEpIHtcbiAgICAgICAgICB0aGlzLmdyb3VwSW5kZXggPSBncm91cEluZGV4O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHNldEJlZm9yZURheXMoKSB7XG4gICAgaWYgKHRoaXMuZ3JvdXBJbmRleCA9PT0gMCkge1xuICAgICAgdGhpcy5ncm91cEluZGV4ID0gNztcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmdyb3VwSW5kZXg7IGkrKykge1xuICAgICAgdGhpcy5kYXlPZk1vbnRoW2ldLnVuc2hpZnQoe1xuICAgICAgICBkYXlPZldlZWs6IGksXG4gICAgICAgIGRhdGU6IHRoaXMuZ2V0RGF0ZU9iamVjdCh0aGlzLmRheU9mTW9udGhbaV1bMF0uZGF5IC0gNyksXG4gICAgICAgIGRheTogdGhpcy5nZXREYXRlT2JqZWN0KHRoaXMuZGF5T2ZNb250aFtpXVswXS5kYXkgLSA3KS5nZXREYXRlKClcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHNlbGVjdERhdGUoZGF0ZTogRGF0ZSkge1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gZGF0ZTtcbiAgICBpZiAoZGF0ZS5nZXRNb250aCgpICE9PSB0aGlzLmN1cnJlbnREYXRlLmdldE1vbnRoKCkpIHtcbiAgICAgIHRoaXMuY3VycmVudERhdGUgPSBkYXRlO1xuICAgICAgdGhpcy5idWlsZENhbGVuZGFyKCk7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0RGF5LmVtaXQodGhpcy5zZWxlY3RlZERhdGUpO1xuICB9XG5cbiAgc2V0QWZ0ZXJEYXlzKCkge1xuICAgIHRoaXMuZGF5T2ZNb250aC5mb3JFYWNoKChhcnJheSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChhcnJheS5sZW5ndGggPCA2KSB7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBhcnJheS5wdXNoKHtcbiAgICAgICAgICAgIGRheU9mV2VlazogaW5kZXgsXG4gICAgICAgICAgICBkYXRlOiB0aGlzLmdldERhdGVPYmplY3QoYXJyYXlbYXJyYXkubGVuZ3RoIC0gMV0uZGF5ICsgNywgYXJyYXlbYXJyYXkubGVuZ3RoIC0gMV0uZGF0ZS5nZXRNb250aCgpKSxcbiAgICAgICAgICAgIGRheTogdGhpcy5nZXREYXRlT2JqZWN0KGFycmF5W2FycmF5Lmxlbmd0aCAtIDFdLmRheSArIDcpLmdldERhdGUoKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IHdoaWxlIChhcnJheS5sZW5ndGggPCA2KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlzQ3VycmVudERhdGUoIGRhdGU6IERhdGUgKSB7XG4gICAgaWYgKCAhZGF0ZSApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3Qgc2VsZWN0ID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksXG4gICAgICBkYXRlLmdldERhdGUoKSwgMCwgMCwgMCwgMCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBuZXcgRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZS5nZXRGdWxsWWVhcigpLCB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRNb250aCgpLFxuICAgICAgdGhpcy5zZWxlY3RlZERhdGUuZ2V0RGF0ZSgpLCAwLCAwLCAwLCAwKS5nZXRUaW1lKCk7XG4gICAgcmV0dXJuIHNlbGVjdCA9PT0gY3VycmVudDtcbiAgfVxuXG4gIGlzT3RoZXJNb250aCggaXRlbTogQ2FsZW5kYXJEYXlzSW50ZXJmYWNlICkge1xuICAgIHJldHVybiBpdGVtLmRhdGUuZ2V0TW9udGgoKSAhPT0gdGhpcy5jdXJyZW50RGF0ZS5nZXRNb250aCgpO1xuICB9XG5cbiAgdG9kYXkoKSB7XG4gICAgdGhpcy5jdXJyZW50RGF0ZSA9IG5ldyBEYXRlKCk7XG4gIH1cblxuICBpc1RvZGF5KGRhdGU6IERhdGUpIHtcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKG5ldyBEYXRlKCkuc2V0SG91cnMoMCwgMCwgMCwgMCkpO1xuICAgIGNvbnN0IGRheSA9IG5ldyBEYXRlKCBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDAgKSk7XG4gICAgcmV0dXJuIHRvZGF5LmdldFRpbWUoKSA9PT0gZGF5LmdldFRpbWUoKTtcbiAgfVxuXG4gIGdldERhdGVPYmplY3QoZGF5LCBtb250aD8pIHtcbiAgICByZXR1cm4gbmV3IERhdGUodGhpcy5jdXJyZW50RGF0ZS5nZXRGdWxsWWVhcigpLCBtb250aCA/IG1vbnRoIDogdGhpcy5jdXJyZW50RGF0ZS5nZXRNb250aCgpLCBkYXkpO1xuICB9XG5cbiAgZ3JvdXBCeSh4cywga2V5KSB7XG4gICAgY29uc3Qgb2JqZWN0QXJyYXkgPSB4cy5yZWR1Y2UoKHJ2LCB4KSA9PiB7XG4gICAgICAocnZbeFtrZXldXSA9IHJ2W3hba2V5XV0gfHwgW10pLnB1c2goeCk7XG4gICAgICByZXR1cm4gcnY7XG4gICAgfSwgW10pO1xuICAgIG9iamVjdEFycmF5Lmxlbmd0aCA9IE9iamVjdC5rZXlzKG9iamVjdEFycmF5KS5sZW5ndGg7XG4gICAgcmV0dXJuIG9iamVjdEFycmF5O1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoIGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMgKSB7XG4gIH1cblxufVxuIiwiPGRpdiBjbGFzcz1cInVpLWNhbGVuZGFyLWRheXNcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlR3JpZFwiPjwvbmctY29udGFpbmVyPlxuPC9kaXY+XG5cbjxuZy10ZW1wbGF0ZSAjdGVtcGxhdGVHcmlkPlxuICA8bmctdGVtcGxhdGUgbmdGb3IgbGV0LWl0ZW0gbGV0LWluZGV4IFtuZ0Zvck9mXT1cImRheU9mTW9udGhcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGVMaW5lOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogaXRlbSB9XCI+PC9uZy1jb250YWluZXI+XG4gIDwvbmctdGVtcGxhdGU+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgbGV0LWl0ZW0gI3RlbXBsYXRlQ2VsbD5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0/LmRhdGUgfCBob2xpZGF5OmhvbGlkYXlzIGFzIGRheUFycmF5XCI+XG4gICAgPGRpdiBjbGFzcz1cInVpLWNhbGVuZGFyLWNlbGxcIlxuICAgICAgICAgW2NsYXNzLmJvcmRlcnNdPVwiYm9yZGVyc1wiXG4gICAgICAgICBbY2xhc3MudG9kYXldPVwiaXNUb2RheShpdGVtPy5kYXRlKVwiXG4gICAgICAgICAoZGJsY2xpY2spPVwiZG91YmxlQ2xpY2suZW1pdCgpXCJcbiAgICAgICAgIChjbGljayk9XCJzZWxlY3REYXRlKCBpdGVtPy5kYXRlIClcIlxuICAgICAgICAgW3Rvb2x0aXBEYXldPVwiZGF5QXJyYXlcIlxuICAgICAgICAgW3Rvb2x0aXBIb2xpZGF5XT1cImRheUFycmF5Py5sZW5ndGggPiAwXCJcbiAgICAgICAgIFtjbGFzcy5ob2xpZGF5XT1cImRheUFycmF5Py5sZW5ndGggPiAwXCJcbiAgICAgICAgIFtjbGFzcy5zdW5kYXldPVwiaXRlbT8uZGF5T2ZXZWVrID09PSAwICYmICFpc090aGVyTW9udGgoaXRlbSlcIlxuICAgICAgICAgW2NsYXNzLnNlbGVjdGVkXT1cImlzQ3VycmVudERhdGUoIGl0ZW0/LmRhdGUgKVwiXG4gICAgICAgICBbY2xhc3MudWktb3RoZXItbW9udGhdPVwiaXNPdGhlck1vbnRoKGl0ZW0pXCI+e3sgaXRlbS5kYXkgfX1cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3RlbXBsYXRlTGluZSBsZXQtaXRlbT5cbiAgPGRpdiBjbGFzcz1cInVpLWNhbGVuZGFyLWxpbmVcIiBbY2xhc3MuYm9yZGVyc109XCJib3JkZXJzXCI+XG4gICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1pdGVtIFtuZ0Zvck9mXT1cIml0ZW1cIj5cbiAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJ0ZW1wbGF0ZUNlbGxcIlxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IGl0ZW0gfVwiPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG4iXX0=