UNPKG

ngx-material-timepicker

Version:
218 lines 35.5 kB
import * as tslib_1 from "tslib"; import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core'; import { TimeUnit } from '../../models/time-unit.enum'; var CLOCK_HAND_STYLES = { small: { height: '75px', top: 'calc(50% - 75px)' }, large: { height: '103px', top: 'calc(50% - 103px)' } }; var NgxMaterialTimepickerFaceComponent = /** @class */ (function () { function NgxMaterialTimepickerFaceComponent() { this.timeUnit = TimeUnit; this.innerClockFaceSize = 85; this.timeChange = new EventEmitter(); this.timeSelected = new EventEmitter(); } NgxMaterialTimepickerFaceComponent.prototype.ngAfterViewInit = function () { this.setClockHandPosition(); this.addTouchEvents(); }; NgxMaterialTimepickerFaceComponent.prototype.ngOnChanges = function (changes) { var _this = this; var faceTimeChanges = changes['faceTime']; var selectedTimeChanges = changes['selectedTime']; if ((faceTimeChanges && faceTimeChanges.currentValue) && (selectedTimeChanges && selectedTimeChanges.currentValue)) { /* Set time according to passed an input value */ this.selectedTime = this.faceTime.find(function (time) { return time.time === _this.selectedTime.time; }); } if (selectedTimeChanges && selectedTimeChanges.currentValue) { this.setClockHandPosition(); } if (faceTimeChanges && faceTimeChanges.currentValue) { // To avoid an error ExpressionChangedAfterItHasBeenCheckedError setTimeout(function () { return _this.selectAvailableTime(); }); } }; NgxMaterialTimepickerFaceComponent.prototype.trackByTime = function (_, time) { return time.time; }; NgxMaterialTimepickerFaceComponent.prototype.onMousedown = function (e) { e.preventDefault(); this.isStarted = true; }; NgxMaterialTimepickerFaceComponent.prototype.selectTime = function (e) { if (!this.isStarted && (e instanceof MouseEvent && e.type !== 'click')) { return; } var clockFaceCords = this.clockFace.nativeElement.getBoundingClientRect(); /* Get x0 and y0 of the circle */ var centerX = clockFaceCords.left + clockFaceCords.width / 2; var centerY = clockFaceCords.top + clockFaceCords.height / 2; /* Counting the arctangent and convert it to from radian to deg */ var arctangent = Math.atan(Math.abs(e.clientX - centerX) / Math.abs(e.clientY - centerY)) * 180 / Math.PI; /* Get angle according to quadrant */ var circleAngle = countAngleByCords(centerX, centerY, e.clientX, e.clientY, arctangent); /* Check if selected time from the inner clock face (24 hours format only) */ var isInnerClockChosen = this.format && this.isInnerClockFace(centerX, centerY, e.clientX, e.clientY); /* Round angle according to angle step */ var angleStep = this.unit === TimeUnit.MINUTE ? (6 * (this.minutesGap || 1)) : 30; var roundedAngle = isInnerClockChosen ? roundAngle(circleAngle, angleStep) + 360 : roundAngle(circleAngle, angleStep); var angle = roundedAngle === 0 ? 360 : roundedAngle; var selectedTime = this.faceTime.find(function (val) { return val.angle === angle; }); if (selectedTime && !selectedTime.disabled) { this.timeChange.next(selectedTime); /* To let know whether user ended interaction with clock face */ if (!this.isStarted) { this.timeSelected.next(selectedTime.time); } } }; NgxMaterialTimepickerFaceComponent.prototype.onMouseup = function (e) { e.preventDefault(); this.isStarted = false; }; NgxMaterialTimepickerFaceComponent.prototype.isHourSelected = function (hour) { return (hour === this.selectedTime.time) && !this.isClockFaceDisabled; }; NgxMaterialTimepickerFaceComponent.prototype.isMinuteSelected = function (minute) { return ((this.selectedTime.time === minute) && (minute % (this.minutesGap || 5) === 0)) && !this.isClockFaceDisabled; }; NgxMaterialTimepickerFaceComponent.prototype.ngOnDestroy = function () { this.removeTouchEvents(); }; NgxMaterialTimepickerFaceComponent.prototype.addTouchEvents = function () { this.touchStartHandler = this.onMousedown.bind(this); this.touchEndHandler = this.onMouseup.bind(this); this.clockFace.nativeElement.addEventListener('touchstart', this.touchStartHandler); this.clockFace.nativeElement.addEventListener('touchend', this.touchEndHandler); }; NgxMaterialTimepickerFaceComponent.prototype.removeTouchEvents = function () { this.clockFace.nativeElement.removeEventListener('touchstart', this.touchStartHandler); this.clockFace.nativeElement.removeEventListener('touchend', this.touchEndHandler); }; NgxMaterialTimepickerFaceComponent.prototype.setClockHandPosition = function () { if (this.format === 24) { if (this.selectedTime.time > 12 || this.selectedTime.time === 0) { this.decreaseClockHand(); } else { this.increaseClockHand(); } } this.clockHand.nativeElement.style.transform = "rotate(" + this.selectedTime.angle + "deg)"; }; NgxMaterialTimepickerFaceComponent.prototype.selectAvailableTime = function () { var _this = this; var currentTime = this.faceTime.find(function (time) { return _this.selectedTime.time === time.time; }); this.isClockFaceDisabled = this.faceTime.every(function (time) { return time.disabled; }); if ((currentTime && currentTime.disabled) && !this.isClockFaceDisabled) { var availableTime = this.faceTime.find(function (time) { return !time.disabled; }); this.timeChange.next(availableTime); } }; NgxMaterialTimepickerFaceComponent.prototype.isInnerClockFace = function (x0, y0, x, y) { /* Detect whether time from the inner clock face or not (24 format only) */ return Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)) < this.innerClockFaceSize; }; NgxMaterialTimepickerFaceComponent.prototype.decreaseClockHand = function () { this.clockHand.nativeElement.style.height = CLOCK_HAND_STYLES.small.height; this.clockHand.nativeElement.style.top = CLOCK_HAND_STYLES.small.top; }; NgxMaterialTimepickerFaceComponent.prototype.increaseClockHand = function () { this.clockHand.nativeElement.style.height = CLOCK_HAND_STYLES.large.height; this.clockHand.nativeElement.style.top = CLOCK_HAND_STYLES.large.top; }; tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Array) ], NgxMaterialTimepickerFaceComponent.prototype, "faceTime", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], NgxMaterialTimepickerFaceComponent.prototype, "selectedTime", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Number) ], NgxMaterialTimepickerFaceComponent.prototype, "unit", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Number) ], NgxMaterialTimepickerFaceComponent.prototype, "format", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Number) ], NgxMaterialTimepickerFaceComponent.prototype, "minutesGap", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], NgxMaterialTimepickerFaceComponent.prototype, "timeChange", void 0); tslib_1.__decorate([ Output(), tslib_1.__metadata("design:type", Object) ], NgxMaterialTimepickerFaceComponent.prototype, "timeSelected", void 0); tslib_1.__decorate([ ViewChild('clockFace', { static: true }), tslib_1.__metadata("design:type", ElementRef) ], NgxMaterialTimepickerFaceComponent.prototype, "clockFace", void 0); tslib_1.__decorate([ ViewChild('clockHand', { static: true }), tslib_1.__metadata("design:type", ElementRef) ], NgxMaterialTimepickerFaceComponent.prototype, "clockHand", void 0); tslib_1.__decorate([ HostListener('mousedown', ['$event']), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", void 0) ], NgxMaterialTimepickerFaceComponent.prototype, "onMousedown", null); tslib_1.__decorate([ HostListener('click', ['$event']), HostListener('touchmove', ['$event.changedTouches[0]']), HostListener('touchend', ['$event.changedTouches[0]']), HostListener('mousemove', ['$event']), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", void 0) ], NgxMaterialTimepickerFaceComponent.prototype, "selectTime", null); tslib_1.__decorate([ HostListener('mouseup', ['$event']), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", [Object]), tslib_1.__metadata("design:returntype", void 0) ], NgxMaterialTimepickerFaceComponent.prototype, "onMouseup", null); NgxMaterialTimepickerFaceComponent = tslib_1.__decorate([ Component({ selector: 'ngx-material-timepicker-face', template: "<div class=\"clock-face\" #clockFace>\n <div *ngIf=\"unit !== timeUnit.MINUTE;else minutesFace\" class=\"clock-face__container\">\n <div class=\"clock-face__number clock-face__number--outer\"\n [style.transform]=\"'rotateZ('+ time.angle +'deg) translateX(-50%)' | styleSanitizer\"\n *ngFor=\"let time of faceTime.slice(0, 12); trackBy: trackByTime\">\n\t\t\t<span [style.transform]=\"'rotateZ(-'+ time.angle +'deg)' | styleSanitizer\"\n [ngClass]=\"{'active': isHourSelected(time.time), 'disabled': time.disabled}\">{{time.time}}</span>\n </div>\n <div class=\"clock-face__inner\" *ngIf=\"faceTime.length > 12\"\n [style.top]=\"'calc(50% - ' + innerClockFaceSize + 'px)'\">\n <div class=\"clock-face__number clock-face__number--inner\"\n [style.transform]=\"'rotateZ('+ time.angle +'deg) translateX(-50%)' | styleSanitizer\"\n [style.height.px]=\"innerClockFaceSize\"\n *ngFor=\"let time of faceTime.slice(12, 24); trackBy: trackByTime\">\n\t\t\t<span [style.transform]=\"'rotateZ(-'+ time.angle +'deg)' | styleSanitizer\"\n [ngClass]=\"{'active': isHourSelected(time.time), 'disabled': time.disabled}\">\n {{time.time === 0 ? '00' : time.time}}</span>\n </div>\n </div>\n </div>\n\n <span class=\"clock-face__clock-hand\" [ngClass]=\"{'clock-face__clock-hand_minute': unit === timeUnit.MINUTE}\"\n #clockHand [hidden]=\"isClockFaceDisabled\"></span>\n</div>\n<ng-template #minutesFace>\n <div class=\"clock-face__container\">\n <div class=\"clock-face__number clock-face__number--outer\"\n [style.transform]=\"'rotateZ('+ time.angle +'deg) translateX(-50%)' | styleSanitizer\"\n *ngFor=\"let time of faceTime; trackBy: trackByTime\">\n\t<span [style.transform]=\"'rotateZ(-'+ time.angle +'deg)' | styleSanitizer\"\n [ngClass]=\"{'active': isMinuteSelected(time.time), 'disabled': time.disabled}\">\n\t{{time.time === 0 ? '00' : time.time | minutesFormatter: minutesGap}}</span>\n </div>\n </div>\n</ng-template>\n", changeDetection: ChangeDetectionStrategy.OnPush, styles: [".clock-face{width:290px;height:290px;border-radius:50%;position:relative;display:flex;justify-content:center;padding:20px;box-sizing:border-box;background-color:#f0f0f0}@supports (background-color:var(--clock-face-background-color)){.clock-face{background-color:var(--clock-face-background-color)}}.clock-face__inner{position:absolute}.clock-face__container{margin-left:-2px}.clock-face__number{position:absolute;-webkit-transform-origin:0 100%;transform-origin:0 100%;width:50px;text-align:center;z-index:2}.clock-face__number--outer{height:calc(290px / 2 - 20px)}.clock-face__number--outer>span{font-size:16px;color:#6c6c6c}@supports (color:var(--clock-face-time-inactive-color)){.clock-face__number--outer>span{color:var(--clock-face-time-inactive-color)}}.clock-face__number--inner>span{font-size:14px;color:#929292}@supports (color:var(--clock-face-inner-time-inactive-color)){.clock-face__number--inner>span{color:var(--clock-face-inner-time-inactive-color)}}.clock-face__number>span{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:30px;height:30px;display:flex;justify-content:center;align-items:center;margin:auto;border-radius:50%;font-weight:500;font-family:Roboto,sans-serif}@supports (font-family:var(--primary-font-family)){.clock-face__number>span{font-family:var(--primary-font-family)}}.clock-face__number>span.active{background-color:#00bfff;color:#fff}@supports (background-color:var(--clock-hand-color)){.clock-face__number>span.active{background-color:var(--clock-hand-color);color:var(--clock-face-time-active-color)}}.clock-face__number>span.disabled{color:#c5c5c5}@supports (color:var(--clock-face-time-disabled-color)){.clock-face__number>span.disabled{color:var(--clock-face-time-disabled-color)}}.clock-face__clock-hand{height:103px;width:2px;-webkit-transform-origin:0 100%;transform-origin:0 100%;position:absolute;top:calc(50% - 103px);z-index:1;background-color:#00bfff}@supports (background-color:var(--clock-hand-color)){.clock-face__clock-hand{background-color:var(--clock-hand-color)}}.clock-face__clock-hand:after{content:'';width:7px;height:7px;border-radius:50%;background-color:inherit;position:absolute;bottom:-3px;left:-3.5px}.clock-face__clock-hand_minute:before{content:'';width:7px;height:7px;background-color:#fff;border-radius:50%;position:absolute;top:-8px;left:calc(50% - 8px);box-sizing:content-box;border:4px solid #00bfff}@supports (border-color:var(--clock-hand-color)){.clock-face__clock-hand_minute:before{border-color:var(--clock-hand-color)}}@media (max-device-width:1023px) and (orientation:landscape){.clock-face{width:225px;height:225px;padding:5px}.clock-face__number--outer{height:calc(225px / 2 - 5px)}.clock-face__clock-hand_minute:before{top:0}}"] }) ], NgxMaterialTimepickerFaceComponent); return NgxMaterialTimepickerFaceComponent; }()); export { NgxMaterialTimepickerFaceComponent }; function roundAngle(angle, step) { return Math.round(angle / step) * step; } function countAngleByCords(x0, y0, x, y, currentAngle) { if (y > y0 && x >= x0) { // II quarter return 180 - currentAngle; } else if (y > y0 && x < x0) { // III quarter return 180 + currentAngle; } else if (y < y0 && x < x0) { // IV quarter return 360 - currentAngle; } else { // I quarter return currentAngle; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW1hdGVyaWFsLXRpbWVwaWNrZXItZmFjZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtbWF0ZXJpYWwtdGltZXBpY2tlci8iLCJzb3VyY2VzIjpbInNyYy9hcHAvbWF0ZXJpYWwtdGltZXBpY2tlci9jb21wb25lbnRzL3RpbWVwaWNrZXItZmFjZS9uZ3gtbWF0ZXJpYWwtdGltZXBpY2tlci1mYWNlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUVILHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFFTixTQUFTLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXZELElBQU0saUJBQWlCLEdBQUc7SUFDdEIsS0FBSyxFQUFFO1FBQ0gsTUFBTSxFQUFFLE1BQU07UUFDZCxHQUFHLEVBQUUsa0JBQWtCO0tBQzFCO0lBQ0QsS0FBSyxFQUFFO1FBQ0gsTUFBTSxFQUFFLE9BQU87UUFDZixHQUFHLEVBQUUsbUJBQW1CO0tBQzNCO0NBQ0osQ0FBQztBQVFGO0lBTkE7UUFRSSxhQUFRLEdBQUcsUUFBUSxDQUFDO1FBR3BCLHVCQUFrQixHQUFHLEVBQUUsQ0FBQztRQVFkLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBaUIsQ0FBQztRQUMvQyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7SUF1SnhELENBQUM7SUE5SUcsNERBQWUsR0FBZjtRQUNJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsd0RBQVcsR0FBWCxVQUFZLE9BQXNCO1FBQWxDLGlCQWdCQztRQWZHLElBQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM1QyxJQUFNLG1CQUFt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V0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7Ozs7d0VBbUNyQztJQUdEO1FBREMsWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDOzs7O3VFQUluQztJQXJHUSxrQ0FBa0M7UUFOOUMsU0FBUyxDQUFDO1lBQ1AsUUFBUSxFQUFFLDhCQUE4QjtZQUN4Qyxvb0VBQTREO1lBRTVELGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNOztTQUNsRCxDQUFDO09BQ1csa0NBQWtDLENBcUs5QztJQUFELHlDQUFDO0NBQUEsQUFyS0QsSUFxS0M7U0FyS1ksa0NBQWtDO0FBdUsvQyxTQUFTLFVBQVUsQ0FBQyxLQUFhLEVBQUUsSUFBWTtJQUMzQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQztBQUMzQyxDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxFQUFVLEVBQUUsRUFBVSxFQUFFLENBQVMsRUFBRSxDQUFTLEVBQUUsWUFBb0I7SUFDekYsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBQyxhQUFhO1FBQ2pDLE9BQU8sR0FBRyxHQUFHLFlBQVksQ0FBQztLQUM3QjtTQUFNLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUMsY0FBYztRQUN4QyxPQUFPLEdBQUcsR0FBRyxZQUFZLENBQUM7S0FDN0I7U0FBTSxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFDLGFBQWE7UUFDdkMsT0FBTyxHQUFHLEdBQUcsWUFBWSxDQUFDO0tBQzdCO1NBQU0sRUFBQyxZQUFZO1FBQ2hCLE9BQU8sWUFBWSxDQUFDO0tBQ3ZCO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQWZ0ZXJWaWV3SW5pdCxcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT3V0cHV0LFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ2xvY2tGYWNlVGltZSB9IGZyb20gJy4uLy4uL21vZGVscy9jbG9jay1mYWNlLXRpbWUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRpbWVVbml0IH0gZnJvbSAnLi4vLi4vbW9kZWxzL3RpbWUtdW5pdC5lbnVtJztcblxuY29uc3QgQ0xPQ0tfSEFORF9TVFlMRVMgPSB7XG4gICAgc21hbGw6IHtcbiAgICAgICAgaGVpZ2h0OiAnNzVweCcsXG4gICAgICAgIHRvcDogJ2NhbGMoNTAlIC0gNzVweCknXG4gICAgfSxcbiAgICBsYXJnZToge1xuICAgICAgICBoZWlnaHQ6ICcxMDNweCcsXG4gICAgICAgIHRvcDogJ2NhbGMoNTAlIC0gMTAzcHgpJ1xuICAgIH1cbn07XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmd4LW1hdGVyaWFsLXRpbWVwaWNrZXItZmFjZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL25neC1tYXRlcmlhbC10aW1lcGlja2VyLWZhY2UuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL25neC1tYXRlcmlhbC10aW1lcGlja2VyLWZhY2UuY29tcG9uZW50LnNjc3MnXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBOZ3hNYXRlcmlhbFRpbWVwaWNrZXJGYWNlQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXG4gICAgdGltZVVuaXQgPSBUaW1lVW5pdDtcblxuICAgIGlzQ2xvY2tGYWNlRGlzYWJsZWQ6IGJvb2xlYW47XG4gICAgaW5uZXJDbG9ja0ZhY2VTaXplID0gODU7XG5cbiAgICBASW5wdXQoKSBmYWNlVGltZTogQ2xvY2tGYWNlVGltZVtdO1xuICAgIEBJbnB1dCgpIHNlbGVjdGVkVGltZTogQ2xvY2tGYWNlVGltZTtcbiAgICBASW5wdXQoKSB1bml0OiBUaW1lVW5pdDtcbiAgICBASW5wdXQoKSBmb3JtYXQ6IG51bWJlcjtcbiAgICBASW5wdXQoKSBtaW51dGVzR2FwOiBudW1iZXI7XG5cbiAgICBAT3V0cHV0KCkgdGltZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2xvY2tGYWNlVGltZT4oKTtcbiAgICBAT3V0cHV0KCkgdGltZVNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICBAVmlld0NoaWxkKCdjbG9ja0ZhY2UnLCB7c3RhdGljOiB0cnVlfSkgY2xvY2tGYWNlOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoJ2Nsb2NrSGFuZCcsIHtzdGF0aWM6IHRydWV9KSBjbG9ja0hhbmQ6IEVsZW1lbnRSZWY7XG5cbiAgICBwcml2YXRlIGlzU3RhcnRlZDogYm9vbGVhbjtcbiAgICBwcml2YXRlIHRvdWNoU3RhcnRIYW5kbGVyOiAoKSA9PiBhbnk7XG4gICAgcHJpdmF0ZSB0b3VjaEVuZEhhbmRsZXI6ICgpID0+IGFueTtcblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgdGhpcy5zZXRDbG9ja0hhbmRQb3NpdGlvbigpO1xuICAgICAgICB0aGlzLmFkZFRvdWNoRXZlbnRzKCk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgICAgICBjb25zdCBmYWNlVGltZUNoYW5nZXMgPSBjaGFuZ2VzWydmYWNlVGltZSddO1xuICAgICAgICBjb25zdCBzZWxlY3RlZFRpbWVDaGFuZ2VzID0gY2hhbmdlc1snc2VsZWN0ZWRUaW1lJ107XG5cbiAgICAgICAgaWYgKChmYWNlVGltZUNoYW5nZXMgJiYgZmFjZVRpbWVDaGFuZ2VzLmN1cnJlbnRWYWx1ZSlcbiAgICAgICAgICAgICYmIChzZWxlY3RlZFRpbWVDaGFuZ2VzICYmIHNlbGVjdGVkVGltZUNoYW5nZXMuY3VycmVudFZhbHVlKSkge1xuICAgICAgICAgICAgLyogU2V0IHRpbWUgYWNjb3JkaW5nIHRvIHBhc3NlZCBhbiBpbnB1dCB2YWx1ZSAqL1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFRpbWUgPSB0aGlzLmZhY2VUaW1lLmZpbmQodGltZSA9PiB0aW1lLnRpbWUgPT09IHRoaXMuc2VsZWN0ZWRUaW1lLnRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWxlY3RlZFRpbWVDaGFuZ2VzICYmIHNlbGVjdGVkVGltZUNoYW5nZXMuY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnNldENsb2NrSGFuZFBvc2l0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZhY2VUaW1lQ2hhbmdlcyAmJiBmYWNlVGltZUNoYW5nZXMuY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgICAvLyBUbyBhdm9pZCBhbiBlcnJvciBFeHByZXNzaW9uQ2hhbmdlZEFmdGVySXRIYXNCZWVuQ2hlY2tlZEVycm9yXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2VsZWN0QXZhaWxhYmxlVGltZSgpKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgdHJhY2tCeVRpbWUoXywgdGltZTogQ2xvY2tGYWNlVGltZSk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aW1lLnRpbWU7XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2Vkb3duJywgWyckZXZlbnQnXSlcbiAgICBvbk1vdXNlZG93bihlOiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuaXNTdGFydGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdjbGljaycsIFsnJGV2ZW50J10pXG4gICAgQEhvc3RMaXN0ZW5lcigndG91Y2htb3ZlJywgWyckZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0nXSlcbiAgICBASG9zdExpc3RlbmVyKCd0b3VjaGVuZCcsIFsnJGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdJ10pXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcbiAgICBzZWxlY3RUaW1lKGU6IE1vdXNlRXZlbnQgfCBUb3VjaCk6IHZvaWQge1xuXG4gICAgICAgIGlmICghdGhpcy5pc1N0YXJ0ZWQgJiYgKGUgaW5zdGFuY2VvZiBNb3VzZUV2ZW50ICYmIGUudHlwZSAhPT0gJ2NsaWNrJykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbG9ja0ZhY2VDb3JkcyA9IHRoaXMuY2xvY2tGYWNlLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgLyogR2V0IHgwIGFuZCB5MCBvZiB0aGUgY2lyY2xlICovXG4gICAgICAgIGNvbnN0IGNlbnRlclggPSBjbG9ja0ZhY2VDb3Jkcy5sZWZ0ICsgY2xvY2tGYWNlQ29yZHMud2lkdGggLyAyO1xuICAgICAgICBjb25zdCBjZW50ZXJZID0gY2xvY2tGYWNlQ29yZHMudG9wICsgY2xvY2tGYWNlQ29yZHMuaGVpZ2h0IC8gMjtcbiAgICAgICAgLyogQ291bnRpbmcgdGhlIGFyY3RhbmdlbnQgYW5kIGNvbnZlcnQgaXQgdG8gZnJvbSByYWRpYW4gdG8gZGVnICovXG4gICAgICAgIGNvbnN0IGFyY3RhbmdlbnQgPSBNYXRoLmF0YW4oTWF0aC5hYnMoZS5jbGllbnRYIC0gY2VudGVyWCkgLyBNYXRoLmFicyhlLmNsaWVudFkgLSBjZW50ZXJZKSkgKiAxODAgLyBNYXRoLlBJO1xuICAgICAgICAvKiBHZXQgYW5nbGUgYWNjb3JkaW5nIHRvIHF1YWRyYW50ICovXG4gICAgICAgIGNvbnN0IGNpcmNsZUFuZ2xlID0gY291bnRBbmdsZUJ5Q29yZHMoY2VudGVyWCwgY2VudGVyWSwgZS5jbGllbnRYLCBlLmNsaWVudFksIGFyY3RhbmdlbnQpO1xuICAgICAgICAvKiBDaGVjayBpZiBzZWxlY3RlZCB0aW1lIGZyb20gdGhlIGlubmVyIGNsb2NrIGZhY2UgKDI0IGhvdXJzIGZvcm1hdCBvbmx5KSAqL1xuICAgICAgICBjb25zdCBpc0lubmVyQ2xvY2tDaG9zZW4gPSB0aGlzLmZvcm1hdCAmJiB0aGlzLmlzSW5uZXJDbG9ja0ZhY2UoY2VudGVyWCwgY2VudGVyWSwgZS5jbGllbnRYLCBlLmNsaWVudFkpO1xuICAgICAgICAvKiBSb3VuZCBhbmdsZSBhY2NvcmRpbmcgdG8gYW5nbGUgc3RlcCAqL1xuICAgICAgICBjb25zdCBhbmdsZVN0ZXAgPSB0aGlzLnVuaXQgPT09IFRpbWVVbml0Lk1JTlVURSA/ICg2ICogKHRoaXMubWludXRlc0dhcCB8fCAxKSkgOiAzMDtcbiAgICAgICAgY29uc3Qgcm91bmRlZEFuZ2xlID0gaXNJbm5lckNsb2NrQ2hvc2VuXG4gICAgICAgICAgICA/IHJvdW5kQW5nbGUoY2lyY2xlQW5nbGUsIGFuZ2xlU3RlcCkgKyAzNjBcbiAgICAgICAgICAgIDogcm91bmRBbmdsZShjaXJjbGVBbmdsZSwgYW5nbGVTdGVwKTtcbiAgICAgICAgY29uc3QgYW5nbGUgPSByb3VuZGVkQW5nbGUgPT09IDAgPyAzNjAgOiByb3VuZGVkQW5nbGU7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRUaW1lID0gdGhpcy5mYWNlVGltZS5maW5kKHZhbCA9PiB2YWwuYW5nbGUgPT09IGFuZ2xlKTtcblxuICAgICAgICBpZiAoc2VsZWN0ZWRUaW1lICYmICFzZWxlY3RlZFRpbWUuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMudGltZUNoYW5nZS5uZXh0KHNlbGVjdGVkVGltZSk7XG5cbiAgICAgICAgICAgIC8qIFRvIGxldCBrbm93IHdoZXRoZXIgdXNlciBlbmRlZCBpbnRlcmFjdGlvbiB3aXRoIGNsb2NrIGZhY2UgKi9cbiAgICAgICAgICAgIGlmICghdGhpcy5pc1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVTZWxlY3RlZC5uZXh0KHNlbGVjdGVkVGltZS50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2V1cCcsIFsnJGV2ZW50J10pXG4gICAgb25Nb3VzZXVwKGU6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5pc1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpc0hvdXJTZWxlY3RlZChob3VyOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChob3VyID09PSB0aGlzLnNlbGVjdGVkVGltZS50aW1lKSAmJiAhdGhpcy5pc0Nsb2NrRmFjZURpc2FibGVkO1xuICAgIH1cblxuICAgIGlzTWludXRlU2VsZWN0ZWQobWludXRlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICgodGhpcy5zZWxlY3RlZFRpbWUudGltZSA9PT0gbWludXRlKSAmJiAobWludXRlICUgKHRoaXMubWludXRlc0dhcCB8fCA1KSA9PT0gMCkpICYmICF0aGlzLmlzQ2xvY2tGYWNlRGlzYWJsZWQ7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlVG91Y2hFdmVudHMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFkZFRvdWNoRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnRvdWNoU3RhcnRIYW5kbGVyID0gdGhpcy5vbk1vdXNlZG93bi5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnRvdWNoRW5kSGFuZGxlciA9IHRoaXMub25Nb3VzZXVwLmJpbmQodGhpcyk7XG5cbiAgICAgICAgdGhpcy5jbG9ja0ZhY2UubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy50b3VjaFN0YXJ0SGFuZGxlcik7XG4gICAgICAgIHRoaXMuY2xvY2tGYWNlLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLnRvdWNoRW5kSGFuZGxlcik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW1vdmVUb3VjaEV2ZW50cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jbG9ja0ZhY2UubmF0aXZlRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy50b3VjaFN0YXJ0SGFuZGxlcik7XG4gICAgICAgIHRoaXMuY2xvY2tGYWNlLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLnRvdWNoRW5kSGFuZGxlcik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRDbG9ja0hhbmRQb3NpdGlvbigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZm9ybWF0ID09PSAyNCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRUaW1lLnRpbWUgPiAxMiB8fCB0aGlzLnNlbGVjdGVkVGltZS50aW1lID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWNyZWFzZUNsb2NrSGFuZCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluY3JlYXNlQ2xvY2tIYW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNsb2NrSGFuZC5uYXRpdmVFbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IGByb3RhdGUoJHt0aGlzLnNlbGVjdGVkVGltZS5hbmdsZX1kZWcpYDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNlbGVjdEF2YWlsYWJsZVRpbWUoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gdGhpcy5mYWNlVGltZS5maW5kKHRpbWUgPT4gdGhpcy5zZWxlY3RlZFRpbWUudGltZSA9PT0gdGltZS50aW1lKTtcbiAgICAgICAgdGhpcy5pc0Nsb2NrRmFjZURpc2FibGVkID0gdGhpcy5mYWNlVGltZS5ldmVyeSh0aW1lID0+IHRpbWUuZGlzYWJsZWQpO1xuXG4gICAgICAgIGlmICgoY3VycmVudFRpbWUgJiYgY3VycmVudFRpbWUuZGlzYWJsZWQpICYmICF0aGlzLmlzQ2xvY2tGYWNlRGlzYWJsZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGF2YWlsYWJsZVRpbWUgPSB0aGlzLmZhY2VUaW1lLmZpbmQodGltZSA9PiAhdGltZS5kaXNhYmxlZCk7XG5cbiAgICAgICAgICAgIHRoaXMudGltZUNoYW5nZS5uZXh0KGF2YWlsYWJsZVRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc0lubmVyQ2xvY2tGYWNlKHgwOiBudW1iZXIsIHkwOiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIC8qIERldGVjdCB3aGV0aGVyIHRpbWUgZnJvbSB0aGUgaW5uZXIgY2xvY2sgZmFjZSBvciBub3QgKDI0IGZvcm1hdCBvbmx5KSAqL1xuICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHggLSB4MCwgMikgKyBNYXRoLnBvdyh5IC0geTAsIDIpKSA8IHRoaXMuaW5uZXJDbG9ja0ZhY2VTaXplO1xuICAgIH1cblxuICAgIHByaXZhdGUgZGVjcmVhc2VDbG9ja0hhbmQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2xvY2tIYW5kLm5hdGl2ZUVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gQ0xPQ0tfSEFORF9TVFlMRVMuc21hbGwuaGVpZ2h0O1xuICAgICAgICB0aGlzLmNsb2NrSGFuZC5uYXRpdmVFbGVtZW50LnN0eWxlLnRvcCA9IENMT0NLX0hBTkRfU1RZTEVTLnNtYWxsLnRvcDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluY3JlYXNlQ2xvY2tIYW5kKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNsb2NrSGFuZC5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IENMT0NLX0hBTkRfU1RZTEVTLmxhcmdlLmhlaWdodDtcbiAgICAgICAgdGhpcy5jbG9ja0hhbmQubmF0aXZlRWxlbWVudC5zdHlsZS50b3AgPSBDTE9DS19IQU5EX1NUWUxFUy5sYXJnZS50b3A7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByb3VuZEFuZ2xlKGFuZ2xlOiBudW1iZXIsIHN0ZXA6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoYW5nbGUgLyBzdGVwKSAqIHN0ZXA7XG59XG5cbmZ1bmN0aW9uIGNvdW50QW5nbGVCeUNvcmRzKHgwOiBudW1iZXIsIHkwOiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyLCBjdXJyZW50QW5nbGU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKHkgPiB5MCAmJiB4ID49IHgwKSB7Ly8gSUkgcXVhcnRlclxuICAgICAgICByZXR1cm4gMTgwIC0gY3VycmVudEFuZ2xlO1xuICAgIH0gZWxzZSBpZiAoeSA+IHkwICYmIHggPCB4MCkgey8vIElJSSBxdWFydGVyXG4gICAgICAgIHJldHVybiAxODAgKyBjdXJyZW50QW5nbGU7XG4gICAgfSBlbHNlIGlmICh5IDwgeTAgJiYgeCA8IHgwKSB7Ly8gSVYgcXVhcnRlclxuICAgICAgICByZXR1cm4gMzYwIC0gY3VycmVudEFuZ2xlO1xuICAgIH0gZWxzZSB7Ly8gSSBxdWFydGVyXG4gICAgICAgIHJldHVybiBjdXJyZW50QW5nbGU7XG4gICAgfVxufVxuIl19