book-picker
Version:
<p align="center"> <img width="409" height="331" src="https://raw.githubusercontent.com/ymxk/book-picker/master/book-picker.gif"> </p>
358 lines • 29.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter } from '@angular/core';
import moment from 'moment';
import { HoursOfDay } from './hours-of-day';
import { TimeClass } from './time-class.enum';
import jspath from "jspath";
export class TimePickerComponent {
constructor() {
this.timeCells = [];
this.nowTime = moment();
this.bookeds = new Array();
this.hours = new Array();
this.selected = new EventEmitter();
this.onerror = new EventEmitter();
}
/**
* @return {?}
*/
ngOnInit() {
this.initBooksOrHours();
this.getHoursForDays();
}
/**
* @return {?}
*/
initBooksOrHours() {
if (!this.bookeds) {
this.bookeds = new Array();
}
if (!this.hours) {
this.hours = new Array();
}
}
/**
* @return {?}
*/
onClear() {
this.start = null;
this.end = null;
}
/**
* @return {?}
*/
emitSelected() {
this.selected.emit({ start: this.start, end: this.addHalfHour(this.end) });
}
/**
* @param {?} v
* @return {?}
*/
addHalfHour(v) {
return v ? v.clone().add(30, 'm') : null;
}
/**
* @return {?}
*/
emitError() {
this.onerror.emit();
}
/**
* @param {?} value
* @return {?}
*/
onSelected(value) {
if (this.start && this.end && this.start.isSame(value, 'm') && this.end.isSame(value, 'm')) {
this.onClear();
this.emitSelected();
return false;
}
if (this.start && this.end && this.start.isSame(value, 'm')) {
this.start = this.end;
this.emitSelected();
return false;
}
if (this.start && this.end && this.end.isSame(value, 'm')) {
this.end = this.start;
this.emitSelected();
return false;
}
if (!this.start && !this.end) {
/** @type {?} */
let x = this.includesDisable(value.clone(), value.clone());
if (x) {
this.emitError();
return false;
}
this.start = value;
this.end = value;
this.emitSelected();
return false;
}
if (value.isBefore(this.start)) {
/** @type {?} */
let x = this.includesDisable(value.clone(), this.start.clone());
if (x) {
this.emitError();
return false;
}
this.end = this.start;
this.start = value;
}
if (value.isAfter(this.start)) {
/** @type {?} */
let x = this.includesDisable(this.start.clone(), value.clone());
if (x) {
this.emitError();
return false;
}
this.end = value;
}
this.emitSelected();
}
/**
* @param {?} start
* @param {?} end
* @return {?}
*/
includesDisable(start, end) {
/** @type {?} */
let range = [];
for (let item = start; item.isBefore(end) || item.isSame(end); item.add(30, 'm')) {
range.push(item.clone());
}
return range.filter((/**
* @param {?} e
* @return {?}
*/
e => { return this.includesBooked(e) || this.includesCloses(e); })).length > 0;
}
/**
* @param {?} v
* @return {?}
*/
includesBooked(v) {
return this.bookeds.filter((/**
* @param {?} e
* @return {?}
*/
e => { return this.isBetweenDate(v, e.start, e.end); })).length > 0;
}
/**
* @param {?} v
* @return {?}
*/
includesCloses(v) {
/** @type {?} */
let ph = this.getOpenHoursOnDated();
if (ph && ph.length == 0) {
return true;
}
return ph.filter((/**
* @param {?} e
* @return {?}
*/
e => { return this.isBetweenNotEnd(v, e.opens, e.closes); })).length == 0;
}
/**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
isBetweenNotEnd(v, s, e) {
/** @type {?} */
let vs = this.setHourMinuteIgnorDate(v);
/** @type {?} */
let ss = this.setHourMinuteIgnorDate(s);
/** @type {?} */
let es = this.setHourMinuteIgnorDate(e);
return (vs.isBetween(ss, es, 'm') || vs.isSame(ss, 'm')) ? true : false;
}
/**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
isBetweenDate(v, s, e) {
return v.isBetween(s, e) || v.isSame(s) || v.isSame(e);
}
/**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
isBetweenM(v, s, e) {
return v.isBetween(s, e, 'm') || v.isSame(s, 'm') || v.isSame(e, 'm');
}
/**
* @param {?} value
* @return {?}
*/
getClassBy(value) {
if (this.includesBooked(value)) {
return TimeClass.BOOKED;
}
if (this.includesCloses(value)) {
return TimeClass.DISABLE;
}
if (this.isBetweenM(value, this.start, this.end)) {
return TimeClass.SELECTED;
}
return TimeClass.NORMAL;
}
/**
* @param {?} v
* @return {?}
*/
isSameDay(v) {
return moment().isSame(v, 'month') && moment().isSame(v, 'day');
}
/**
* @return {?}
*/
getDefaultOpenHours() {
return new HoursOfDay(this.nowTime.clone().startOf('day'), this.nowTime.clone().endOf('day'));
}
/**
* @return {?}
*/
nextHalfHourInNow() {
/** @type {?} */
const y = parseFloat(this.nowTime.clone().format('mm')) % 30;
return this.addHalfHour(this.nowTime.clone().subtract(y, 'm'));
}
/**
* @param {?} oh
* @return {?}
*/
replaceStartByNow(oh) {
/** @type {?} */
let start = this.setHourMinuteIgnorDate(oh.start);
if (this.isSameDay(start)) {
return new HoursOfDay(this.nextHalfHourInNow(), oh.end);
}
return oh;
}
/**
* @return {?}
*/
getHoursForDays() {
/** @type {?} */
let oh = this.getOpenHoursOnDated();
if (oh && oh.length > 0) {
this.createHours(this.toHoursOfDayFrom(oh));
}
else {
this.createHours(this.getDefaultOpenHours());
}
}
/**
* @param {?} v
* @return {?}
*/
setHourMinuteIgnorDate(v) {
return this.nowTime.clone().hour(v.hour()).minute(v.minute());
}
/**
* @param {?} oh
* @return {?}
*/
createHours(oh) {
/** @type {?} */
let t = this.replaceStartByNow(oh);
/** @type {?} */
let start = t.start.clone();
/** @type {?} */
let end = t.end.clone();
this.timeCells = [];
for (let item = start; item.isBefore(end); item.add(30, 'm')) {
this.timeCells.push(item.clone());
}
}
/**
* @return {?}
*/
getOpenHoursOnDated() {
return this.hours.filter((/**
* @param {?} e
* @return {?}
*/
(e) => {
return e.weeks.includes(this.nowTime.day());
}));
}
;
/**
* @param {?} ts
* @return {?}
*/
toHoursOfDayFrom(ts) {
/** @type {?} */
const opens = jspath.apply(`.opens`, ts);
/** @type {?} */
const closes = jspath.apply(`.closes`, ts);
return new HoursOfDay(this.setHourMinuteIgnorDate(moment.min(opens)), this.setHourMinuteIgnorDate(moment.max(closes)));
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
/** @type {?} */
let log = [];
for (let propName in changes) {
/** @type {?} */
let changedProp = changes[propName];
if (changedProp.isFirstChange()) {
this.nowTime = moment();
}
else {
this.onClear();
this.nowTime = changedProp.currentValue;
this.getHoursForDays();
}
}
}
}
TimePickerComponent.decorators = [
{ type: Component, args: [{
selector: 'app-time-picker',
template: "<section class=\"card\">\n\n\t<div *ngFor=\"let c of timeCells\" [ngClass]=\"getClassBy(c)\">\n\t\t<div (click)=\"onSelected(c)\">{{c | amDateFormat: 'HH:mm'}}</div>\n\t</div>\n</section>",
styles: ["@charset \"UTF-8\";.card{display:-webkit-flex;display:flex;min-width:100%;min-height:54px;overflow-x:auto;border-top:1px solid #e9e9e9;border-bottom:1px solid #e9e9e9}.card>div{min-width:55px;height:54px;background-color:#fff;text-align:center;border-left:1px solid #e9e9e9}.card>div>div:first-child{font-size:13px;font-family:PingFangSC-Regular;font-weight:400;color:#242424;line-height:54px}.card>div:last-child{border-right:1px solid #e9e9e9}.card::-webkit-scrollbar{display:none}.time-disable div{background:#fbfbfb;color:#c4c4c4!important;line-height:14px!important;padding:20px 0 0 2px}.time-disable ::after{content:\"\\a\u672A\u8425\u4E1A\";white-space:pre-wrap;font-size:10px;color:#c4c4c4}.time-selected div{background:#e5f2ff!important;color:#007aff!important;border-left:0!important}.time-booked div{background:#fbfbfb;color:#c4c4c4!important;line-height:14px!important;padding:20px 0 0 2px}.time-booked ::after{content:\"\\a\u5DF2\u9884\u8BA2\";white-space:pre-wrap;font-size:10px;color:#c4c4c4}"]
}] }
];
/** @nocollapse */
TimePickerComponent.ctorParameters = () => [];
TimePickerComponent.propDecorators = {
nowTime: [{ type: Input }],
bookeds: [{ type: Input }],
hours: [{ type: Input }],
selected: [{ type: Output }],
onerror: [{ type: Output }]
};
if (false) {
/** @type {?} */
TimePickerComponent.prototype.timeCells;
/** @type {?} */
TimePickerComponent.prototype.nowTime;
/** @type {?} */
TimePickerComponent.prototype.bookeds;
/** @type {?} */
TimePickerComponent.prototype.hours;
/** @type {?} */
TimePickerComponent.prototype.selected;
/** @type {?} */
TimePickerComponent.prototype.onerror;
/** @type {?} */
TimePickerComponent.prototype.start;
/** @type {?} */
TimePickerComponent.prototype.end;
/* Skipping unhandled member: ;*/
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYm9vay1waWNrZXIvIiwic291cmNlcyI6WyJ0aW1lLXBpY2tlci90aW1lLXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBMkIsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hHLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUk1QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQU81QixNQUFNLE9BQU8sbUJBQW1CO0lBVTlCO1FBVEEsY0FBUyxHQUFvQixFQUFFLENBQUM7UUFDdkIsWUFBTyxHQUFrQixNQUFNLEVBQUUsQ0FBQztRQUNsQyxZQUFPLEdBQWEsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNoQyxVQUFLLEdBQVksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUM1QixhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztRQUN6QyxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztJQUlsQyxDQUFDOzs7O0lBRWpCLFFBQVE7UUFDTixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDekIsQ0FBQzs7OztJQUVELGdCQUFnQjtRQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztTQUM1QjtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ2YsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1NBQzFCO0lBQ0gs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Q0FBQyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6SCxDQUFDOzs7OztJQUVELFdBQVcsQ0FBQyxPQUE0Qzs7WUFDbEQsR0FBRyxHQUFhLEVBQUU7UUFDdEIsS0FBSyxJQUFJLFFBQVEsSUFBSSxPQUFPLEVBQUU7O2dCQUN4QixXQUFXLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQztZQUNuQyxJQUFJLFdBQVcsQ0FBQyxhQUFhLEVBQUUsRUFBRTtnQkFDL0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLEVBQUUsQ0FBQzthQUN6QjtpQkFBTTtnQkFDTCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLE9BQU8sR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDeEI7U0FDRjtJQUNILENBQUM7OztZQXBORixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjtnQkFDM0IsdU1BQTJDOzthQUU1Qzs7Ozs7c0JBR0UsS0FBSztzQkFDTCxLQUFLO29CQUNMLEtBQUs7dUJBQ0wsTUFBTTtzQkFDTixNQUFNOzs7O0lBTFAsd0NBQWdDOztJQUNoQyxzQ0FBMkM7O0lBQzNDLHNDQUF5Qzs7SUFDekMsb0NBQXNDOztJQUN0Qyx1Q0FBbUQ7O0lBQ25ELHNDQUFrRDs7SUFDbEQsb0NBQXFCOztJQUNyQixrQ0FBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2UsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgVGltZVJhbmdlIH0gZnJvbSAnLi4vdGltZS1yYW5nZSc7XG5pbXBvcnQgeyBCb29rZWQgfSBmcm9tICcuLi9ib29rZWQnO1xuaW1wb3J0IHsgSG91cnMgfSBmcm9tICcuLi9ob3Vycyc7XG5pbXBvcnQgeyBIb3Vyc09mRGF5IH0gZnJvbSAnLi9ob3Vycy1vZi1kYXknO1xuaW1wb3J0IHsgVGltZUNsYXNzIH0gZnJvbSAnLi90aW1lLWNsYXNzLmVudW0nO1xuaW1wb3J0IGpzcGF0aCBmcm9tIFwianNwYXRoXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC10aW1lLXBpY2tlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi90aW1lLXBpY2tlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RpbWUtcGlja2VyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgVGltZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHRpbWVDZWxsczogbW9tZW50Lk1vbWVudFtdID0gW107XG4gIEBJbnB1dCgpIG5vd1RpbWU6IG1vbWVudC5Nb21lbnQgPSBtb21lbnQoKTtcbiAgQElucHV0KCkgYm9va2VkczogQm9va2VkW10gPSBuZXcgQXJyYXkoKTtcbiAgQElucHV0KCkgaG91cnM6IEhvdXJzW10gPSBuZXcgQXJyYXkoKTtcbiAgQE91dHB1dCgpIHNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxUaW1lUmFuZ2U+KCk7XG4gIEBPdXRwdXQoKSBvbmVycm9yID0gbmV3IEV2ZW50RW1pdHRlcjxUaW1lUmFuZ2U+KCk7XG4gIHN0YXJ0OiBtb21lbnQuTW9tZW50O1xuICBlbmQ6IG1vbWVudC5Nb21lbnQ7XG5cbiAgY29uc3RydWN0b3IoKSB7IH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmluaXRCb29rc09ySG91cnMoKTtcbiAgICB0aGlzLmdldEhvdXJzRm9yRGF5cygpO1xuICB9XG5cbiAgaW5pdEJvb2tzT3JIb3VycygpIHtcbiAgICBpZiAoIXRoaXMuYm9va2Vkcykge1xuICAgICAgdGhpcy5ib29rZWRzID0gbmV3IEFycmF5KCk7XG4gICAgfVxuICAgIGlmICghdGhpcy5ob3Vycykge1xuICAgICAgdGhpcy5ob3VycyA9IG5ldyBBcnJheSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uQ2xlYXIoKSB7XG4gICAgdGhpcy5zdGFydCA9IG51bGw7XG4gICAgdGhpcy5lbmQgPSBudWxsO1xuICB9XG5cbiAgZW1pdFNlbGVjdGVkKCkge1xuICAgIHRoaXMuc2VsZWN0ZWQuZW1pdCh7IHN0YXJ0OiB0aGlzLnN0YXJ0LCBlbmQ6IHRoaXMuYWRkSGFsZkhvdXIodGhpcy5lbmQpIH0pO1xuICB9XG5cbiAgYWRkSGFsZkhvdXIodjogbW9tZW50Lk1vbWVudCkge1xuICAgIHJldHVybiB2ID8gdi5jbG9uZSgpLmFkZCgzMCwgJ20nKSA6IG51bGw7XG4gIH1cblxuICBlbWl0RXJyb3IoKSB7XG4gICAgdGhpcy5vbmVycm9yLmVtaXQoKTtcbiAgfVxuXG4gIG9uU2VsZWN0ZWQodmFsdWU6IG1vbWVudC5Nb21lbnQpIHtcbiAgICBpZiAodGhpcy5zdGFydCAmJiB0aGlzLmVuZCAmJiB0aGlzLnN0YXJ0LmlzU2FtZSh2YWx1ZSwgJ20nKSAmJiB0aGlzLmVuZC5pc1NhbWUodmFsdWUsICdtJykpIHtcbiAgICAgIHRoaXMub25DbGVhcigpO1xuICAgICAgdGhpcy5lbWl0U2VsZWN0ZWQoKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3RhcnQgJiYgdGhpcy5lbmQgJiYgdGhpcy5zdGFydC5pc1NhbWUodmFsdWUsICdtJykpIHtcbiAgICAgIHRoaXMuc3RhcnQgPSB0aGlzLmVuZDtcbiAgICAgIHRoaXMuZW1pdFNlbGVjdGVkKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLnN0YXJ0ICYmIHRoaXMuZW5kICYmIHRoaXMuZW5kLmlzU2FtZSh2YWx1ZSwgJ20nKSkge1xuICAgICAgdGhpcy5lbmQgPSB0aGlzLnN0YXJ0O1xuICAgICAgdGhpcy5lbWl0U2VsZWN0ZWQoKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnN0YXJ0ICYmICF0aGlzLmVuZCkge1xuICAgICAgbGV0IHggPSB0aGlzLmluY2x1ZGVzRGlzYWJsZSh2YWx1ZS5jbG9uZSgpLCB2YWx1ZS5jbG9uZSgpKTtcbiAgICAgIGlmICh4KSB7XG4gICAgICAgIHRoaXMuZW1pdEVycm9yKCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhcnQgPSB2YWx1ZTtcbiAgICAgIHRoaXMuZW5kID0gdmFsdWU7XG4gICAgICB0aGlzLmVtaXRTZWxlY3RlZCgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodmFsdWUuaXNCZWZvcmUodGhpcy5zdGFydCkpIHtcbiAgICAgIGxldCB4ID0gdGhpcy5pbmNsdWRlc0Rpc2FibGUodmFsdWUuY2xvbmUoKSwgdGhpcy5zdGFydC5jbG9uZSgpKTtcbiAgICAgIGlmICh4KSB7XG4gICAgICAgIHRoaXMuZW1pdEVycm9yKCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW5kID0gdGhpcy5zdGFydDtcbiAgICAgIHRoaXMuc3RhcnQgPSB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKHZhbHVlLmlzQWZ0ZXIodGhpcy5zdGFydCkpIHtcbiAgICAgIGxldCB4ID0gdGhpcy5pbmNsdWRlc0Rpc2FibGUodGhpcy5zdGFydC5jbG9uZSgpLCB2YWx1ZS5jbG9uZSgpKTtcbiAgICAgIGlmICh4KSB7XG4gICAgICAgIHRoaXMuZW1pdEVycm9yKCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZW5kID0gdmFsdWU7XG4gICAgfVxuICAgIHRoaXMuZW1pdFNlbGVjdGVkKCk7XG4gIH1cblxuICBpbmNsdWRlc0Rpc2FibGUoc3RhcnQ6IG1vbWVudC5Nb21lbnQsIGVuZDogbW9tZW50Lk1vbWVudCkge1xuICAgIGxldCByYW5nZSA9IFtdO1xuICAgIGZvciAobGV0IGl0ZW0gPSBzdGFydDsgaXRlbS5pc0JlZm9yZShlbmQpIHx8IGl0ZW0uaXNTYW1lKGVuZCk7IGl0ZW0uYWRkKDMwLCAnbScpKSB7XG4gICAgICByYW5nZS5wdXNoKGl0ZW0uY2xvbmUoKSk7XG4gICAgfVxuICAgIHJldHVybiByYW5nZS5maWx0ZXIoZSA9PiB7IHJldHVybiB0aGlzLmluY2x1ZGVzQm9va2VkKGUpIHx8IHRoaXMuaW5jbHVkZXNDbG9zZXMoZSk7IH0pLmxlbmd0aCA+IDA7XG4gIH1cblxuICBpbmNsdWRlc0Jvb2tlZCh2OiBtb21lbnQuTW9tZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuYm9va2Vkcy5maWx0ZXIoZSA9PiB7IHJldHVybiB0aGlzLmlzQmV0d2VlbkRhdGUodiwgZS5zdGFydCwgZS5lbmQpIH0pLmxlbmd0aCA+IDA7XG4gIH1cblxuICBpbmNsdWRlc0Nsb3Nlcyh2OiBtb21lbnQuTW9tZW50KSB7XG4gICAgbGV0IHBoID0gdGhpcy5nZXRPcGVuSG91cnNPbkRhdGVkKCk7XG4gICAgaWYgKHBoICYmIHBoLmxlbmd0aCA9PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHBoLmZpbHRlcihlID0+IHsgcmV0dXJuIHRoaXMuaXNCZXR3ZWVuTm90RW5kKHYsIGUub3BlbnMsIGUuY2xvc2VzKTsgfSkubGVuZ3RoID09IDA7XG4gIH1cblxuICBpc0JldHdlZW5Ob3RFbmQodjogbW9tZW50Lk1vbWVudCwgczogbW9tZW50Lk1vbWVudCwgZTogbW9tZW50Lk1vbWVudCkge1xuICAgIGxldCB2cyA9IHRoaXMuc2V0SG91ck1pbnV0ZUlnbm9yRGF0ZSh2KTtcbiAgICBsZXQgc3MgPSB0aGlzLnNldEhvdXJNaW51dGVJZ25vckRhdGUocyk7XG4gICAgbGV0IGVzID0gdGhpcy5zZXRIb3VyTWludXRlSWdub3JEYXRlKGUpO1xuICAgIHJldHVybiAodnMuaXNCZXR3ZWVuKHNzLCBlcywgJ20nKSB8fCB2cy5pc1NhbWUoc3MsICdtJykpID8gdHJ1ZSA6IGZhbHNlO1xuICB9XG5cbiAgaXNCZXR3ZWVuRGF0ZSh2OiBtb21lbnQuTW9tZW50LCBzOiBtb21lbnQuTW9tZW50LCBlOiBtb21lbnQuTW9tZW50KSB7XG4gICAgcmV0dXJuIHYuaXNCZXR3ZWVuKHMsIGUpIHx8IHYuaXNTYW1lKHMpIHx8IHYuaXNTYW1lKGUpO1xuICB9XG5cbiAgaXNCZXR3ZWVuTSh2OiBtb21lbnQuTW9tZW50LCBzOiBtb21lbnQuTW9tZW50LCBlOiBtb21lbnQuTW9tZW50KSB7XG4gICAgcmV0dXJuIHYuaXNCZXR3ZWVuKHMsIGUsICdtJykgfHwgdi5pc1NhbWUocywgJ20nKSB8fCB2LmlzU2FtZShlLCAnbScpO1xuICB9XG5cbiAgZ2V0Q2xhc3NCeSh2YWx1ZTogbW9tZW50Lk1vbWVudCkge1xuICAgIGlmICh0aGlzLmluY2x1ZGVzQm9va2VkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFRpbWVDbGFzcy5CT09LRUQ7XG4gICAgfVxuICAgIGlmICh0aGlzLmluY2x1ZGVzQ2xvc2VzKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFRpbWVDbGFzcy5ESVNBQkxFO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc0JldHdlZW5NKHZhbHVlLCB0aGlzLnN0YXJ0LCB0aGlzLmVuZCkpIHtcbiAgICAgIHJldHVybiBUaW1lQ2xhc3MuU0VMRUNURUQ7XG4gICAgfVxuICAgIHJldHVybiBUaW1lQ2xhc3MuTk9STUFMO1xuICB9XG5cbiAgaXNTYW1lRGF5KHY6IG1vbWVudC5Nb21lbnQpIHtcbiAgICByZXR1cm4gbW9tZW50KCkuaXNTYW1lKHYsICdtb250aCcpICYmIG1vbWVudCgpLmlzU2FtZSh2LCAnZGF5Jyk7XG4gIH1cblxuICBnZXREZWZhdWx0T3BlbkhvdXJzKCkge1xuICAgIHJldHVybiBuZXcgSG91cnNPZkRheSh0aGlzLm5vd1RpbWUuY2xvbmUoKS5zdGFydE9mKCdkYXknKSwgdGhpcy5ub3dUaW1lLmNsb25lKCkuZW5kT2YoJ2RheScpKTtcbiAgfVxuXG4gIG5leHRIYWxmSG91ckluTm93KCkge1xuICAgIGNvbnN0IHkgPSBwYXJzZUZsb2F0KHRoaXMubm93VGltZS5jbG9uZSgpLmZvcm1hdCgnbW0nKSkgJSAzMDtcbiAgICByZXR1cm4gdGhpcy5hZGRIYWxmSG91cih0aGlzLm5vd1RpbWUuY2xvbmUoKS5zdWJ0cmFjdCh5LCAnbScpKTtcbiAgfVxuXG4gIHJlcGxhY2VTdGFydEJ5Tm93KG9oOiBIb3Vyc09mRGF5KSB7XG4gICAgbGV0IHN0YXJ0ID0gdGhpcy5zZXRIb3VyTWludXRlSWdub3JEYXRlKG9oLnN0YXJ0KTtcbiAgICBpZiAodGhpcy5pc1NhbWVEYXkoc3RhcnQpKSB7XG5cbiAgICAgIHJldHVybiBuZXcgSG91cnNPZkRheSh0aGlzLm5leHRIYWxmSG91ckluTm93KCksIG9oLmVuZCk7XG4gICAgfVxuICAgIHJldHVybiBvaDtcbiAgfVxuXG4gIGdldEhvdXJzRm9yRGF5cygpIHtcbiAgICBsZXQgb2ggPSB0aGlzLmdldE9wZW5Ib3Vyc09uRGF0ZWQoKTtcbiAgICBpZiAob2ggJiYgb2gubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5jcmVhdGVIb3Vycyh0aGlzLnRvSG91cnNPZkRheUZyb20ob2gpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jcmVhdGVIb3Vycyh0aGlzLmdldERlZmF1bHRPcGVuSG91cnMoKSk7XG4gICAgfVxuICB9XG5cbiAgc2V0SG91ck1pbnV0ZUlnbm9yRGF0ZSh2OiBtb21lbnQuTW9tZW50KSB7XG4gICAgcmV0dXJuIHRoaXMubm93VGltZS5jbG9uZSgpLmhvdXIodi5ob3VyKCkpLm1pbnV0ZSh2Lm1pbnV0ZSgpKTtcbiAgfVxuXG4gIGNyZWF0ZUhvdXJzKG9oOiBIb3Vyc09mRGF5KSB7XG4gICAgbGV0IHQgPSB0aGlzLnJlcGxhY2VTdGFydEJ5Tm93KG9oKTtcbiAgICBsZXQgc3RhcnQgPSB0LnN0YXJ0LmNsb25lKCk7XG4gICAgbGV0IGVuZCA9IHQuZW5kLmNsb25lKCk7XG4gICAgdGhpcy50aW1lQ2VsbHMgPSBbXTtcbiAgICBmb3IgKGxldCBpdGVtID0gc3RhcnQ7IGl0ZW0uaXNCZWZvcmUoZW5kKTsgaXRlbS5hZGQoMzAsICdtJykpIHtcbiAgICAgIHRoaXMudGltZUNlbGxzLnB1c2goaXRlbS5jbG9uZSgpKTtcbiAgICB9XG4gIH1cblxuICBnZXRPcGVuSG91cnNPbkRhdGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhvdXJzLmZpbHRlcigoZTogSG91cnMpID0+IHtcbiAgICAgIHJldHVybiBlLndlZWtzLmluY2x1ZGVzKHRoaXMubm93VGltZS5kYXkoKSk7IFxuICAgIH0pXG4gIH07XG5cbiAgdG9Ib3Vyc09mRGF5RnJvbSh0czogSG91cnNbXSkge1xuICAgIGNvbnN0IG9wZW5zID0ganNwYXRoLmFwcGx5KGAub3BlbnNgLCB0cyk7XG4gICAgY29uc3QgY2xvc2VzID0ganNwYXRoLmFwcGx5KGAuY2xvc2VzYCwgdHMpO1xuICAgIHJldHVybiBuZXcgSG91cnNPZkRheSh0aGlzLnNldEhvdXJNaW51dGVJZ25vckRhdGUobW9tZW50Lm1pbihvcGVucykpLCB0aGlzLnNldEhvdXJNaW51dGVJZ25vckRhdGUobW9tZW50Lm1heChjbG9zZXMpKSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiB7IFtwcm9wS2V5OiBzdHJpbmddOiBTaW1wbGVDaGFuZ2UgfSkge1xuICAgIGxldCBsb2c6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChsZXQgcHJvcE5hbWUgaW4gY2hhbmdlcykge1xuICAgICAgbGV0IGNoYW5nZWRQcm9wID0gY2hhbmdlc1twcm9wTmFtZV07XG4gICAgICBpZiAoY2hhbmdlZFByb3AuaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICAgIHRoaXMubm93VGltZSA9IG1vbWVudCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkNsZWFyKCk7XG4gICAgICAgIHRoaXMubm93VGltZSA9IGNoYW5nZWRQcm9wLmN1cnJlbnRWYWx1ZTtcbiAgICAgICAgdGhpcy5nZXRIb3Vyc0ZvckRheXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0iXX0=