UNPKG

ngx-datetime-16

Version:

Update of ng2-datetime that is compatible with Angular v16+

331 lines 34.2 kB
import { Component, Input, HostListener, HostBinding, forwardRef, } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; const CUSTOM_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxDatetimeComponent), multi: true, }; export class NgxDatetimeComponent { constructor() { this.timepickerOptions = {}; this.datepickerOptions = {}; this.idDatePicker = uniqueId('q-datepicker_'); this.idTimePicker = uniqueId('q-timepicker_'); this.onChange = (_) => { }; this.onTouched = () => { }; } get tabindexAttr() { return this.tabindex === undefined ? '-1' : undefined; } ngAfterViewInit() { this.init(); } ngOnDestroy() { if (this.datepicker) { this.datepicker.datepicker('destroy'); } if (this.timepicker) { this.timepicker.timepicker('remove'); } } ngOnChanges(changes) { if (changes) { if (changes['datepickerOptions'] && this.datepicker) { this.datepicker.datepicker('destroy'); if (changes['datepickerOptions'].currentValue) { this.datepicker = null; this.init(); } else if (changes['datepickerOptions'].currentValue === false) { this.datepicker.remove(); } } if (changes['timepickerOptions'] && this.timepicker) { this.timepicker.timepicker('remove'); if (changes['timepickerOptions'].currentValue) { this.timepicker = null; this.init(); } else if (changes['timepickerOptions'].currentValue === false) { this.timepicker.parent().remove(); } } } } writeValue(value) { this.date = value; if (isDate(this.date)) { setTimeout(() => { this.updateModel(this.date); }, 0); } else { this.clearModels(); } } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } checkEmptyValue(e) { const value = e.target.value; if (value === '' && (this.timepickerOptions === false || this.datepickerOptions === false || (this.timeModel === '' && this.dateModel === ''))) { this.onChange(undefined); } } clearModels() { this.onChange(undefined); if (this.timepicker) { this.timepicker.timepicker('setTime', null); } this.updateDatepicker(null); } showTimepicker() { this.timepicker.timepicker('showWidget'); } showDatepicker() { this.datepicker.datepicker('show'); } ////////////////////////////////// init() { if (!this.datepicker && this.datepickerOptions !== false) { let options = jQuery.extend({ enableOnReadonly: !this.readonly }, this.datepickerOptions); this.datepicker = $('#' + this.idDatePicker).datepicker(options); this.datepicker.on('changeDate', (e) => { let newDate = e.date; if (isDate(this.date) && isDate(newDate)) { // get hours/minutes newDate.setHours(this.date.getHours()); newDate.setMinutes(this.date.getMinutes()); newDate.setSeconds(this.date.getSeconds()); } this.date = newDate; this.onChange(newDate); }); } else if (this.datepickerOptions === false) { $('#' + this.idDatePicker).remove(); } if (!this.timepicker && this.timepickerOptions !== false) { let options = jQuery.extend({ defaultTime: false }, this.timepickerOptions); this.timepicker = $('#' + this.idTimePicker).timepicker(options); this.timepicker.on('changeTime.timepicker', (e) => { let { meridian, hours } = e.time; if (meridian) { // has meridian -> convert 12 to 24h if (meridian === 'PM' && hours < 12) { hours = hours + 12; } if (meridian === 'AM' && hours === 12) { hours = hours - 12; } hours = parseInt(this.pad(hours), 10); } if (!isDate(this.date)) { this.date = new Date(); this.updateDatepicker(this.date); } this.date.setHours(hours); this.date.setMinutes(e.time.minutes); this.date.setSeconds(e.time.seconds); this.onChange(this.date); }); } else if (this.timepickerOptions === false) { $('#' + this.idTimePicker).parent().remove(); } this.updateModel(this.date); } updateModel(date) { this.updateDatepicker(date); // update timepicker if (this.timepicker !== undefined && isDate(date)) { let hours = date.getHours(); if (this.timepickerOptions.showMeridian) { // Convert 24 to 12 hour system hours = hours === 0 || hours === 12 ? 12 : hours % 12; } const meridian = date.getHours() >= 12 ? ' PM' : ' AM'; const time = this.pad(hours) + ':' + this.pad(this.date.getMinutes()) + ':' + this.pad(this.date.getSeconds()) + (this.timepickerOptions.showMeridian || this.timepickerOptions.showMeridian === undefined ? meridian : ''); this.timepicker.timepicker('setTime', time); this.timeModel = time; // fix initial empty timeModel bug } } updateDatepicker(date) { if (this.datepicker !== undefined) { this.datepicker.datepicker('update', date); } } pad(value) { return value.toString().length < 2 ? '0' + value : value.toString(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: NgxDatetimeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.2", type: NgxDatetimeComponent, selector: "ngx-datetime", inputs: { timepickerOptions: ["timepicker", "timepickerOptions"], datepickerOptions: ["datepicker", "datepickerOptions"], hasClearButton: "hasClearButton", readonly: "readonly", required: "required", tabindex: "tabindex" }, host: { listeners: { "blur": "onTouched()" }, properties: { "attr.tabindex": "this.tabindexAttr" } }, providers: [CUSTOM_ACCESSOR], usesOnChanges: true, ngImport: i0, template: ` <div class="ng2-datetime"> <div [ngClass]="{ 'input-group': !datepickerOptions.hideIcon, date: true }" > <input id="{{ idDatePicker }}" type="text" class="form-control" [attr.readonly]="readonly" [attr.required]="required" [attr.placeholder]="datepickerOptions.placeholder || 'Choose date'" [attr.tabindex]="tabindex" [(ngModel)]="dateModel" (blur)="onTouched()" (keyup)="checkEmptyValue($event)" /> <div [hidden]="datepickerOptions.hideIcon || datepickerOptions === false" (click)="showDatepicker()" class="input-group-addon" > <span [ngClass]="datepickerOptions.icon || 'glyphicon glyphicon-th'" ></span> </div> </div> <div [ngClass]="{ 'input-group': !timepickerOptions.hideIcon, 'bootstrap-timepicker timepicker': true }" > <input id="{{ idTimePicker }}" type="text" class="form-control input-small" [attr.readonly]="readonly" [attr.required]="required" [attr.placeholder]="timepickerOptions.placeholder || 'Set time'" [attr.tabindex]="tabindex" [(ngModel)]="timeModel" (focus)="showTimepicker()" (blur)="onTouched()" (keyup)="checkEmptyValue($event)" /> <span [hidden]="timepickerOptions.hideIcon || false" class="input-group-addon" > <i [ngClass]="timepickerOptions.icon || 'glyphicon glyphicon-time'" ></i> </span> </div> <button *ngIf="hasClearButton" type="button" (click)="clearModels()"> Clear </button> </div> `, isInline: true, styles: [".ng2-datetime *[hidden]{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: NgxDatetimeComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-datetime', providers: [CUSTOM_ACCESSOR], template: ` <div class="ng2-datetime"> <div [ngClass]="{ 'input-group': !datepickerOptions.hideIcon, date: true }" > <input id="{{ idDatePicker }}" type="text" class="form-control" [attr.readonly]="readonly" [attr.required]="required" [attr.placeholder]="datepickerOptions.placeholder || 'Choose date'" [attr.tabindex]="tabindex" [(ngModel)]="dateModel" (blur)="onTouched()" (keyup)="checkEmptyValue($event)" /> <div [hidden]="datepickerOptions.hideIcon || datepickerOptions === false" (click)="showDatepicker()" class="input-group-addon" > <span [ngClass]="datepickerOptions.icon || 'glyphicon glyphicon-th'" ></span> </div> </div> <div [ngClass]="{ 'input-group': !timepickerOptions.hideIcon, 'bootstrap-timepicker timepicker': true }" > <input id="{{ idTimePicker }}" type="text" class="form-control input-small" [attr.readonly]="readonly" [attr.required]="required" [attr.placeholder]="timepickerOptions.placeholder || 'Set time'" [attr.tabindex]="tabindex" [(ngModel)]="timeModel" (focus)="showTimepicker()" (blur)="onTouched()" (keyup)="checkEmptyValue($event)" /> <span [hidden]="timepickerOptions.hideIcon || false" class="input-group-addon" > <i [ngClass]="timepickerOptions.icon || 'glyphicon glyphicon-time'" ></i> </span> </div> <button *ngIf="hasClearButton" type="button" (click)="clearModels()"> Clear </button> </div> `, styles: [".ng2-datetime *[hidden]{display:none}\n"] }] }], propDecorators: { timepickerOptions: [{ type: Input, args: ['timepicker'] }], datepickerOptions: [{ type: Input, args: ['datepicker'] }], hasClearButton: [{ type: Input, args: ['hasClearButton'] }], readonly: [{ type: Input }], required: [{ type: Input }], tabindex: [{ type: Input }], onTouched: [{ type: HostListener, args: ['blur'] }], tabindexAttr: [{ type: HostBinding, args: ['attr.tabindex'] }] } }); let id = 0; function uniqueId(prefix) { return prefix + ++id; } function isDate(obj) { return Object.prototype.toString.call(obj) === '[object Date]'; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWRhdGV0aW1lLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1kYXRldGltZS9zcmMvbGliL25neC1kYXRldGltZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsWUFBWSxFQUtaLFdBQVcsRUFDWCxVQUFVLEdBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7O0FBTXpFLE1BQU0sZUFBZSxHQUFHO0lBQ3RCLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztJQUNuRCxLQUFLLEVBQUUsSUFBSTtDQUNaLENBQUM7QUFtRUYsTUFBTSxPQUFPLG9CQUFvQjtJQWpFakM7UUFvRXVCLHNCQUFpQixHQUFRLEVBQUUsQ0FBQztRQUM1QixzQkFBaUIsR0FBUSxFQUFFLENBQUM7UUFjakQsaUJBQVksR0FBVyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDakQsaUJBQVksR0FBVyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFakQsYUFBUSxHQUFHLENBQUMsQ0FBTSxFQUFFLEVBQUUsR0FBRSxDQUFDLENBQUM7UUFHMUIsY0FBUyxHQUFHLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztLQThMdEI7SUE1TEMsSUFDSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDeEQsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNuQixJ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QztJQUN0RSxDQUFDOzhHQXJOVSxvQkFBb0I7a0dBQXBCLG9CQUFvQiw2V0EvRHBCLENBQUMsZUFBZSxDQUFDLCtDQUNsQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyRFQ7OzJGQUdVLG9CQUFvQjtrQkFqRWhDLFNBQVM7K0JBQ0UsY0FBYyxhQUNiLENBQUMsZUFBZSxDQUFDLFlBQ2xCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJEVDs4QkFNb0IsaUJBQWlCO3NCQUFyQyxLQUFLO3VCQUFDLFlBQVk7Z0JBQ0UsaUJBQWlCO3NCQUFyQyxLQUFLO3VCQUFDLFlBQVk7Z0JBQ00sY0FBYztzQkFBdEMsS0FBSzt1QkFBQyxnQkFBZ0I7Z0JBQ2QsUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBZ0JOLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxNQUFNO2dCQUloQixZQUFZO3NCQURmLFdBQVc7dUJBQUMsZUFBZTs7QUE4TDlCLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNYLFNBQVMsUUFBUSxDQUFDLE1BQWM7SUFDOUIsT0FBTyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7QUFDdkIsQ0FBQztBQUVELFNBQVMsTUFBTSxDQUFDLEdBQVE7SUFDdEIsT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssZUFBZSxDQUFDO0FBQ2pFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBIb3N0TGlzdGVuZXIsXG4gIEFmdGVyVmlld0luaXQsXG4gIE9uRGVzdHJveSxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgT25DaGFuZ2VzLFxuICBIb3N0QmluZGluZyxcbiAgZm9yd2FyZFJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBJVGltZXBpY2tlckV2ZW50IH0gZnJvbSAnLi9JVGltZXBpY2tlckV2ZW50JztcblxuZGVjbGFyZSB2YXIgalF1ZXJ5OiBhbnk7XG5kZWNsYXJlIHZhciAkOiBhbnk7XG5cbmNvbnN0IENVU1RPTV9BQ0NFU1NPUiA9IHtcbiAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5neERhdGV0aW1lQ29tcG9uZW50KSxcbiAgbXVsdGk6IHRydWUsXG59O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZGF0ZXRpbWUnLFxuICBwcm92aWRlcnM6IFtDVVNUT01fQUNDRVNTT1JdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJuZzItZGF0ZXRpbWVcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgW25nQ2xhc3NdPVwieyAnaW5wdXQtZ3JvdXAnOiAhZGF0ZXBpY2tlck9wdGlvbnMuaGlkZUljb24sIGRhdGU6IHRydWUgfVwiXG4gICAgICA+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGlkPVwie3sgaWREYXRlUGlja2VyIH19XCJcbiAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgIFthdHRyLnJlYWRvbmx5XT1cInJlYWRvbmx5XCJcbiAgICAgICAgICBbYXR0ci5yZXF1aXJlZF09XCJyZXF1aXJlZFwiXG4gICAgICAgICAgW2F0dHIucGxhY2Vob2xkZXJdPVwiZGF0ZXBpY2tlck9wdGlvbnMucGxhY2Vob2xkZXIgfHwgJ0Nob29zZSBkYXRlJ1wiXG4gICAgICAgICAgW2F0dHIudGFiaW5kZXhdPVwidGFiaW5kZXhcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwiZGF0ZU1vZGVsXCJcbiAgICAgICAgICAoYmx1cik9XCJvblRvdWNoZWQoKVwiXG4gICAgICAgICAgKGtleXVwKT1cImNoZWNrRW1wdHlWYWx1ZSgkZXZlbnQpXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIFtoaWRkZW5dPVwiZGF0ZXBpY2tlck9wdGlvbnMuaGlkZUljb24gfHwgZGF0ZXBpY2tlck9wdGlvbnMgPT09IGZhbHNlXCJcbiAgICAgICAgICAoY2xpY2spPVwic2hvd0RhdGVwaWNrZXIoKVwiXG4gICAgICAgICAgY2xhc3M9XCJpbnB1dC1ncm91cC1hZGRvblwiXG4gICAgICAgID5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgW25nQ2xhc3NdPVwiZGF0ZXBpY2tlck9wdGlvbnMuaWNvbiB8fCAnZ2x5cGhpY29uIGdseXBoaWNvbi10aCdcIlxuICAgICAgICAgID48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2XG4gICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAnaW5wdXQtZ3JvdXAnOiAhdGltZXBpY2tlck9wdGlvbnMuaGlkZUljb24sXG4gICAgICAgICAgJ2Jvb3RzdHJhcC10aW1lcGlja2VyIHRpbWVwaWNrZXInOiB0cnVlXG4gICAgICAgIH1cIlxuICAgICAgPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBpZD1cInt7IGlkVGltZVBpY2tlciB9fVwiXG4gICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sIGlucHV0LXNtYWxsXCJcbiAgICAgICAgICBbYXR0ci5yZWFkb25seV09XCJyZWFkb25seVwiXG4gICAgICAgICAgW2F0dHIucmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgIFthdHRyLnBsYWNlaG9sZGVyXT1cInRpbWVwaWNrZXJPcHRpb25zLnBsYWNlaG9sZGVyIHx8ICdTZXQgdGltZSdcIlxuICAgICAgICAgIFthdHRyLnRhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cInRpbWVNb2RlbFwiXG4gICAgICAgICAgKGZvY3VzKT1cInNob3dUaW1lcGlja2VyKClcIlxuICAgICAgICAgIChibHVyKT1cIm9uVG91Y2hlZCgpXCJcbiAgICAgICAgICAoa2V5dXApPVwiY2hlY2tFbXB0eVZhbHVlKCRldmVudClcIlxuICAgICAgICAvPlxuICAgICAgICA8c3BhblxuICAgICAgICAgIFtoaWRkZW5dPVwidGltZXBpY2tlck9wdGlvbnMuaGlkZUljb24gfHwgZmFsc2VcIlxuICAgICAgICAgIGNsYXNzPVwiaW5wdXQtZ3JvdXAtYWRkb25cIlxuICAgICAgICA+XG4gICAgICAgICAgPGlcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cInRpbWVwaWNrZXJPcHRpb25zLmljb24gfHwgJ2dseXBoaWNvbiBnbHlwaGljb24tdGltZSdcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGJ1dHRvbiAqbmdJZj1cImhhc0NsZWFyQnV0dG9uXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjbGVhck1vZGVscygpXCI+XG4gICAgICAgIENsZWFyXG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbJy5uZzItZGF0ZXRpbWUgKltoaWRkZW5dIHsgZGlzcGxheTogbm9uZTsgfSddLFxufSlcbmV4cG9ydCBjbGFzcyBOZ3hEYXRldGltZUNvbXBvbmVudFxuICBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlc1xue1xuICBASW5wdXQoJ3RpbWVwaWNrZXInKSB0aW1lcGlja2VyT3B0aW9uczogYW55ID0ge307XG4gIEBJbnB1dCgnZGF0ZXBpY2tlcicpIGRhdGVwaWNrZXJPcHRpb25zOiBhbnkgPSB7fTtcbiAgQElucHV0KCdoYXNDbGVhckJ1dHRvbicpIGhhc0NsZWFyQnV0dG9uPzogYm9vbGVhbjtcbiAgQElucHV0KCkgcmVhZG9ubHk/OiBib29sZWFuO1xuICBASW5wdXQoKSByZXF1aXJlZD86IGJvb2xlYW47XG4gIEBJbnB1dCgpIHRhYmluZGV4Pzogc3RyaW5nO1xuXG4gIGRhdGUhOiBEYXRlOyAvLyBuZ01vZGVsXG4gIGRhdGVNb2RlbD86IHN0cmluZztcbiAgdGltZU1vZGVsPzogc3RyaW5nO1xuXG4gIC8vIGluc3RhbmNlc1xuICBkYXRlcGlja2VyOiBhbnk7XG4gIHRpbWVwaWNrZXI6IGFueTtcblxuICBpZERhdGVQaWNrZXI6IHN0cmluZyA9IHVuaXF1ZUlkKCdxLWRhdGVwaWNrZXJfJyk7XG4gIGlkVGltZVBpY2tlcjogc3RyaW5nID0gdW5pcXVlSWQoJ3EtdGltZXBpY2tlcl8nKTtcblxuICBvbkNoYW5nZSA9IChfOiBhbnkpID0+IHt9O1xuXG4gIEBIb3N0TGlzdGVuZXIoJ2JsdXInKVxuICBvblRvdWNoZWQgPSAoKSA9PiB7fTtcblxuICBASG9zdEJpbmRpbmcoJ2F0dHIudGFiaW5kZXgnKVxuICBnZXQgdGFiaW5kZXhBdHRyKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMudGFiaW5kZXggPT09IHVuZGVmaW5lZCA/ICctMScgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5pbml0KCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5kYXRlcGlja2VyKSB7XG4gICAgICB0aGlzLmRhdGVwaWNrZXIuZGF0ZXBpY2tlcignZGVzdHJveScpO1xuICAgIH1cbiAgICBpZiAodGhpcy50aW1lcGlja2VyKSB7XG4gICAgICB0aGlzLnRpbWVwaWNrZXIudGltZXBpY2tlcigncmVtb3ZlJyk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzKSB7XG4gICAgICBpZiAoY2hhbmdlc1snZGF0ZXBpY2tlck9wdGlvbnMnXSAmJiB0aGlzLmRhdGVwaWNrZXIpIHtcbiAgICAgICAgdGhpcy5kYXRlcGlja2VyLmRhdGVwaWNrZXIoJ2Rlc3Ryb3knKTtcblxuICAgICAgICBpZiAoY2hhbmdlc1snZGF0ZXBpY2tlck9wdGlvbnMnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgICAgICB0aGlzLmRhdGVwaWNrZXIgPSBudWxsO1xuICAgICAgICAgIHRoaXMuaW5pdCgpO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYW5nZXNbJ2RhdGVwaWNrZXJPcHRpb25zJ10uY3VycmVudFZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICAgIHRoaXMuZGF0ZXBpY2tlci5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNoYW5nZXNbJ3RpbWVwaWNrZXJPcHRpb25zJ10gJiYgdGhpcy50aW1lcGlja2VyKSB7XG4gICAgICAgIHRoaXMudGltZXBpY2tlci50aW1lcGlja2VyKCdyZW1vdmUnKTtcblxuICAgICAgICBpZiAoY2hhbmdlc1sndGltZXBpY2tlck9wdGlvbnMnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgICAgICB0aGlzLnRpbWVwaWNrZXIgPSBudWxsO1xuICAgICAgICAgIHRoaXMuaW5pdCgpO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYW5nZXNbJ3RpbWVwaWNrZXJPcHRpb25zJ10uY3VycmVudFZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICAgIHRoaXMudGltZXBpY2tlci5wYXJlbnQoKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IGFueSkge1xuICAgIHRoaXMuZGF0ZSA9IHZhbHVlO1xuICAgIGlmIChpc0RhdGUodGhpcy5kYXRlKSkge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlTW9kZWwodGhpcy5kYXRlKTtcbiAgICAgIH0sIDApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNsZWFyTW9kZWxzKCk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKF86IGFueSkgPT4gdm9pZCkge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIGNoZWNrRW1wdHlWYWx1ZShlOiBhbnkpIHtcbiAgICBjb25zdCB2YWx1ZSA9IGUudGFyZ2V0LnZhbHVlO1xuICAgIGlmIChcbiAgICAgIHZhbHVlID09PSAnJyAmJlxuICAgICAgKHRoaXMudGltZXBpY2tlck9wdGlvbnMgPT09IGZhbHNlIHx8XG4gICAgICAgIHRoaXMuZGF0ZXBpY2tlck9wdGlvbnMgPT09IGZhbHNlIHx8XG4gICAgICAgICh0aGlzLnRpbWVNb2RlbCA9PT0gJycgJiYgdGhpcy5kYXRlTW9kZWwgPT09ICcnKSlcbiAgICApIHtcbiAgICAgIHRoaXMub25DaGFuZ2UodW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBjbGVhck1vZGVscygpIHtcbiAgICB0aGlzLm9uQ2hhbmdlKHVuZGVmaW5lZCk7XG4gICAgaWYgKHRoaXMudGltZXBpY2tlcikge1xuICAgICAgdGhpcy50aW1lcGlja2VyLnRpbWVwaWNrZXIoJ3NldFRpbWUnLCBudWxsKTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGVEYXRlcGlja2VyKG51bGwpO1xuICB9XG5cbiAgc2hvd1RpbWVwaWNrZXIoKSB7XG4gICAgdGhpcy50aW1lcGlja2VyLnRpbWVwaWNrZXIoJ3Nob3dXaWRnZXQnKTtcbiAgfVxuXG4gIHNob3dEYXRlcGlja2VyKCkge1xuICAgIHRoaXMuZGF0ZXBpY2tlci5kYXRlcGlja2VyKCdzaG93Jyk7XG4gIH1cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgcHJpdmF0ZSBpbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kYXRlcGlja2VyICYmIHRoaXMuZGF0ZXBpY2tlck9wdGlvbnMgIT09IGZhbHNlKSB7XG4gICAgICBsZXQgb3B0aW9ucyA9IGpRdWVyeS5leHRlbmQoXG4gICAgICAgIHsgZW5hYmxlT25SZWFkb25seTogIXRoaXMucmVhZG9ubHkgfSxcbiAgICAgICAgdGhpcy5kYXRlcGlja2VyT3B0aW9uc1xuICAgICAgKTtcbiAgICAgIHRoaXMuZGF0ZXBpY2tlciA9ICg8YW55PiQoJyMnICsgdGhpcy5pZERhdGVQaWNrZXIpKS5kYXRlcGlja2VyKG9wdGlvbnMpO1xuICAgICAgdGhpcy5kYXRlcGlja2VyLm9uKCdjaGFuZ2VEYXRlJywgKGU6IGFueSkgPT4ge1xuICAgICAgICBsZXQgbmV3RGF0ZTogRGF0ZSA9IGUuZGF0ZTtcblxuICAgICAgICBpZiAoaXNEYXRlKHRoaXMuZGF0ZSkgJiYgaXNEYXRlKG5ld0RhdGUpKSB7XG4gICAgICAgICAgLy8gZ2V0IGhvdXJzL21pbnV0ZXNcbiAgICAgICAgICBuZXdEYXRlLnNldEhvdXJzKHRoaXMuZGF0ZS5nZXRIb3VycygpKTtcbiAgICAgICAgICBuZXdEYXRlLnNldE1pbnV0ZXModGhpcy5kYXRlLmdldE1pbnV0ZXMoKSk7XG4gICAgICAgICAgbmV3RGF0ZS5zZXRTZWNvbmRzKHRoaXMuZGF0ZS5nZXRTZWNvbmRzKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kYXRlID0gbmV3RGF0ZTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZShuZXdEYXRlKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kYXRlcGlja2VyT3B0aW9ucyA9PT0gZmFsc2UpIHtcbiAgICAgICg8YW55PiQoJyMnICsgdGhpcy5pZERhdGVQaWNrZXIpKS5yZW1vdmUoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMudGltZXBpY2tlciAmJiB0aGlzLnRpbWVwaWNrZXJPcHRpb25zICE9PSBmYWxzZSkge1xuICAgICAgbGV0IG9wdGlvbnMgPSBqUXVlcnkuZXh0ZW5kKFxuICAgICAgICB7IGRlZmF1bHRUaW1lOiBmYWxzZSB9LFxuICAgICAgICB0aGlzLnRpbWVwaWNrZXJPcHRpb25zXG4gICAgICApO1xuICAgICAgdGhpcy50aW1lcGlja2VyID0gKDxhbnk+JCgnIycgKyB0aGlzLmlkVGltZVBpY2tlcikpLnRpbWVwaWNrZXIob3B0aW9ucyk7XG4gICAgICB0aGlzLnRpbWVwaWNrZXIub24oJ2NoYW5nZVRpbWUudGltZXBpY2tlcicsIChlOiBJVGltZXBpY2tlckV2ZW50KSA9PiB7XG4gICAgICAgIGxldCB7IG1lcmlkaWFuLCBob3VycyB9ID0gZS50aW1lO1xuXG4gICAgICAgIGlmIChtZXJpZGlhbikge1xuICAgICAgICAgIC8vIGhhcyBtZXJpZGlhbiAtPiBjb252ZXJ0IDEyIHRvIDI0aFxuICAgICAgICAgIGlmIChtZXJpZGlhbiA9PT0gJ1BNJyAmJiBob3VycyA8IDEyKSB7XG4gICAgICAgICAgICBob3VycyA9IGhvdXJzICsgMTI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChtZXJpZGlhbiA9PT0gJ0FNJyAmJiBob3VycyA9PT0gMTIpIHtcbiAgICAgICAgICAgIGhvdXJzID0gaG91cnMgLSAxMjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaG91cnMgPSBwYXJzZUludCh0aGlzLnBhZChob3VycyksIDEwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNEYXRlKHRoaXMuZGF0ZSkpIHtcbiAgICAgICAgICB0aGlzLmRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgIHRoaXMudXBkYXRlRGF0ZXBpY2tlcih0aGlzLmRhdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kYXRlLnNldEhvdXJzKGhvdXJzKTtcbiAgICAgICAgdGhpcy5kYXRlLnNldE1pbnV0ZXMoZS50aW1lLm1pbnV0ZXMpO1xuICAgICAgICB0aGlzLmRhdGUuc2V0U2Vjb25kcyhlLnRpbWUuc2Vjb25kcyk7XG4gICAgICAgIHRoaXMub25DaGFuZ2UodGhpcy5kYXRlKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy50aW1lcGlja2VyT3B0aW9ucyA9PT0gZmFsc2UpIHtcbiAgICAgICg8YW55PiQoJyMnICsgdGhpcy5pZFRpbWVQaWNrZXIpKS5wYXJlbnQoKS5yZW1vdmUoKTtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZU1vZGVsKHRoaXMuZGF0ZSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZU1vZGVsKGRhdGU6IERhdGUpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZURhdGVwaWNrZXIoZGF0ZSk7XG5cbiAgICAvLyB1cGRhdGUgdGltZXBpY2tlclxuICAgIGlmICh0aGlzLnRpbWVwaWNrZXIgIT09IHVuZGVmaW5lZCAmJiBpc0RhdGUoZGF0ZSkpIHtcbiAgICAgIGxldCBob3VycyA9IGRhdGUuZ2V0SG91cnMoKTtcbiAgICAgIGlmICh0aGlzLnRpbWVwaWNrZXJPcHRpb25zLnNob3dNZXJpZGlhbikge1xuICAgICAgICAvLyBDb252ZXJ0IDI0IHRvIDEyIGhvdXIgc3lzdGVtXG4gICAgICAgIGhvdXJzID0gaG91cnMgPT09IDAgfHwgaG91cnMgPT09IDEyID8gMTIgOiBob3VycyAlIDEyO1xuICAgICAgfVxuICAgICAgY29uc3QgbWVyaWRpYW4gPSBkYXRlLmdldEhvdXJzKCkgPj0gMTIgPyAnIFBNJyA6ICcgQU0nO1xuICAgICAgY29uc3QgdGltZSA9XG4gICAgICAgIHRoaXMucGFkKGhvdXJzKSArXG4gICAgICAgICc6JyArXG4gICAgICAgIHRoaXMucGFkKHRoaXMuZGF0ZS5nZXRNaW51dGVzKCkpICtcbiAgICAgICAgJzonICtcbiAgICAgICAgdGhpcy5wYWQodGhpcy5kYXRlLmdldFNlY29uZHMoKSkgK1xuICAgICAgICAodGhpcy50aW1lcGlja2VyT3B0aW9ucy5zaG93TWVyaWRpYW4gfHxcbiAgICAgICAgdGhpcy50aW1lcGlja2VyT3B0aW9ucy5zaG93TWVyaWRpYW4gPT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gbWVyaWRpYW5cbiAgICAgICAgICA6ICcnKTtcbiAgICAgIHRoaXMudGltZXBpY2tlci50aW1lcGlja2VyKCdzZXRUaW1lJywgdGltZSk7XG4gICAgICB0aGlzLnRpbWVNb2RlbCA9IHRpbWU7IC8vIGZpeCBpbml0aWFsIGVtcHR5IHRpbWVNb2RlbCBidWdcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZURhdGVwaWNrZXIoZGF0ZT86IGFueSkge1xuICAgIGlmICh0aGlzLmRhdGVwaWNrZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5kYXRlcGlja2VyLmRhdGVwaWNrZXIoJ3VwZGF0ZScsIGRhdGUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGFkKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpLmxlbmd0aCA8IDIgPyAnMCcgKyB2YWx1ZSA6IHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbn1cblxubGV0IGlkID0gMDtcbmZ1bmN0aW9uIHVuaXF1ZUlkKHByZWZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHByZWZpeCArICsraWQ7XG59XG5cbmZ1bmN0aW9uIGlzRGF0ZShvYmo6IGFueSkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbiJdfQ==