@junte/ui
Version:
Quality Angular UI components kit
280 lines • 41.3 kB
JavaScript
var DatePickerComponent_1;
import { __decorate, __metadata } from "tslib";
import { Component, forwardRef, HostBinding, HostListener, Input } from '@angular/core';
import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms';
import { format as formatDate, parse } from 'date-fns';
import { NGXLogger } from 'ngx-logger';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { Feature } from '../../core/enums/feature';
import { JunteUIConfig } from '../../config';
import { PropertyApi } from '../../core/decorators/api';
import { Breakpoint } from '../../core/enums/breakpoint';
import { UI } from '../../core/enums/ui';
import { Width } from '../../core/enums/width';
import { isEqual } from '../../core/utils/equal';
import { BreakpointService } from '../../layout/responsive/breakpoint.service';
import { DatePickerType } from './enums';
const INPUT_DELAY = 500;
const DIGIT_MASK_CHAR = '_';
const HOURS_MAX = 23;
const MINUTES_MAX = 59;
var Meridian;
(function (Meridian) {
Meridian["am"] = " AM";
Meridian["pm"] = " PM";
})(Meridian || (Meridian = {}));
let DatePickerComponent = DatePickerComponent_1 = class DatePickerComponent {
constructor(logger, fb, breakpoint, config) {
this.logger = logger;
this.fb = fb;
this.breakpoint = breakpoint;
this.config = config;
this.host = 'jnt-date-picker-host';
this.ui = UI;
this.datePickerType = DatePickerType;
this.meridians = Meridian;
this._type = DatePickerType.date;
this.reference = { popover: null };
this._width = Width.default;
this.dateControl = this.fb.control(null);
this.timeControl = this.fb.control(null);
this.hoursControl = this.fb.control(null);
this.minutesControl = this.fb.control(null);
this.calendarControl = this.fb.control(new Date());
this.form = this.fb.group({
date: this.dateControl,
time: this.timeControl,
hours: this.hoursControl,
minutes: this.minutesControl,
calendar: this.calendarControl
});
this.calendarOpened = false;
this.timeOpened = false;
this.placeholder = '';
this.features = [];
this.onChange = () => this.logger.error('value accessor is not registered');
this.onTouched = () => this.logger.error('value accessor is not registered');
this.registerOnChange = fn => this.onChange = fn;
this.registerOnTouched = fn => this.onTouched = fn;
this.onBlur = () => this.onTouched();
}
get mobile() {
return this.breakpoint.current === Breakpoint.mobile;
}
set type(type) {
this.clear();
this._type = type || DatePickerType.date;
}
get type() {
return this._type;
}
set width(width) {
this._width = width || Width.default;
}
ngOnInit() {
this.calendarControl.valueChanges.pipe(distinctUntilChanged())
.subscribe(date => {
this.dateControl.setValue(!!date ? formatDate(date, 'P', { locale: this.config.locale.dfns }).replace(/\D/gi, '') : null);
this.calendarOpened = false;
if (!!this.reference.popover) {
this.reference.popover.hide();
this.reference.popover = null;
}
});
this.hoursControl.valueChanges
.pipe(distinctUntilChanged((val1, val2) => isEqual(val1, val2)))
.subscribe(() => this.setTime());
this.minutesControl.valueChanges
.pipe(distinctUntilChanged((val1, val2) => isEqual(val1, val2)))
.subscribe(() => this.setTime());
this.dateControl.valueChanges.pipe(debounceTime(INPUT_DELAY), distinctUntilChanged())
.subscribe(date => this.update(date, true));
this.timeControl.valueChanges.pipe(debounceTime(INPUT_DELAY), distinctUntilChanged())
.subscribe(time => this.update(time));
}
close() {
if (!!this.reference.popover) {
this.reference.popover.hide();
this.reference.popover = null;
}
}
clear() {
this.dateControl.setValue(null, { emitEvent: false });
this.timeControl.setValue(null, { emitEvent: false });
this.hoursControl.setValue(null, { emitEvent: false });
this.minutesControl.setValue(null, { emitEvent: false });
}
update(value, close = false) {
if (!!value || this.type === DatePickerType.dateTime) {
if (this.type !== DatePickerType.dateTime) {
let output = this.type === DatePickerType.date
? this.config.locale.ui.masks.date
: this.config.locale.ui.masks.time + (this.meridian || '');
for (const char of value) {
output = output.replace(DIGIT_MASK_CHAR, char);
}
const parsed = parse(output, this.type === DatePickerType.date
? 'P' : 'p', new Date(0), { locale: this.config.locale.dfns });
if (parsed instanceof Date && !isNaN(parsed.getTime())) {
if (this.type === DatePickerType.date) {
this.calendarControl.setValue(parsed);
}
else {
this.hoursControl.setValue(parsed.getHours());
this.minutesControl.setValue(parsed.getMinutes());
}
this.onChange(parsed);
if (close) {
this.close();
}
}
}
else if (!!this.dateControl.value && !!this.timeControl.value) {
let output = this.config.locale.ui.masks.datetime + (this.meridian || '');
for (const char of this.dateControl.value) {
output = output.replace(DIGIT_MASK_CHAR, char);
}
for (const char of this.timeControl.value) {
output = output.replace(DIGIT_MASK_CHAR, char);
}
const parsed = parse(output, 'Pp', new Date(), { locale: this.config.locale.dfns });
if (parsed instanceof Date && !isNaN(parsed.getTime())) {
this.onChange(parsed);
if (close) {
this.close();
}
}
}
}
else {
this.onChange(null);
if (!this.dateControl.value) {
this.calendarControl.setValue(null, { emitEvent: false });
this.close();
}
else {
this.hoursControl.setValue(null, { emitEvent: false });
this.minutesControl.setValue(null, { emitEvent: false });
this.close();
}
}
}
setTime() {
let hours = '00';
let minutes = '00';
if (this.hoursControl.value !== null) {
hours = Math.min(Math.max(+this.hoursControl.value, 0), HOURS_MAX).toString();
this.hoursControl.setValue(+hours, { emitEvent: false });
hours = hours.length === 1 ? `0${hours}` : hours;
}
else {
this.hoursControl.setValue(0, { emitEvent: false });
}
if (this.minutesControl.value !== null) {
minutes = Math.min(Math.max(+this.minutesControl.value, 0), MINUTES_MAX).toString();
this.minutesControl.setValue(+minutes, { emitEvent: false });
minutes = minutes.length === 1 ? `0${minutes}` : minutes;
}
else {
this.minutesControl.setValue(0, { emitEvent: false });
}
this.timeControl.setValue(`${hours}${minutes}`);
}
writeValue(date) {
if (date instanceof Date && !isNaN(date.getTime())) {
this.calendarControl.setValue(date, { emitEvent: false });
this.dateControl.setValue(formatDate(date, 'P', { locale: this.config.locale.dfns }), { emitEvent: false });
}
else {
this.clear();
}
}
setDisabledState(disabled) {
disabled ? this.dateControl.disable({ emitEvent: false })
: this.dateControl.enable({ emitEvent: false });
}
};
DatePickerComponent.ctorParameters = () => [
{ type: NGXLogger },
{ type: FormBuilder },
{ type: BreakpointService },
{ type: JunteUIConfig }
];
__decorate([
HostBinding('attr.host'),
__metadata("design:type", Object)
], DatePickerComponent.prototype, "host", void 0);
__decorate([
HostBinding('attr.data-width'),
__metadata("design:type", String)
], DatePickerComponent.prototype, "_width", void 0);
__decorate([
HostBinding('attr.calendar-opened'),
__metadata("design:type", Object)
], DatePickerComponent.prototype, "calendarOpened", void 0);
__decorate([
HostBinding('attr.time-opened'),
__metadata("design:type", Object)
], DatePickerComponent.prototype, "timeOpened", void 0);
__decorate([
PropertyApi({
description: 'Placeholder for date picker',
type: 'string'
}),
Input(),
__metadata("design:type", Object)
], DatePickerComponent.prototype, "placeholder", void 0);
__decorate([
PropertyApi({
description: 'Button for reset input',
path: 'ui.feature',
options: [Feature.allowEmpty],
}),
HostBinding('attr.data-features'),
Input(),
__metadata("design:type", Array)
], DatePickerComponent.prototype, "features", void 0);
__decorate([
PropertyApi({
description: 'Date picker type',
path: 'ui.type',
options: [DatePickerType.date, DatePickerType.time, DatePickerType.dateTime]
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], DatePickerComponent.prototype, "type", null);
__decorate([
PropertyApi({
description: 'Input width',
path: 'ui.width',
default: Width.default,
options: [Width.default, Width.fluid]
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], DatePickerComponent.prototype, "width", null);
__decorate([
HostListener('blur'),
__metadata("design:type", Object)
], DatePickerComponent.prototype, "onBlur", void 0);
DatePickerComponent = DatePickerComponent_1 = __decorate([
Component({
selector: 'jnt-date-picker',
template: "<jnt-form child-of=\"jnt-date-picker-host\" [formGroup]=\"form\">\n <jnt-stack child-of=\"jnt-date-picker-host\" [orientation]=\"ui.orientation.horizontal\" [gutter]=\"mobile ? ui.gutter.none : ui.gutter.normal\">\n <ng-container *ngIf=\"type === datePickerType.date || type === datePickerType.dateTime\">\n <jnt-input child-of=\"jnt-date-picker-host\" *jntMinFor=\"ui.breakpoint.tablet\"\n data-input data-date\n formControlName=\"date\"\n [placeholder]=\"placeholder || ''\"\n [jntPopover]=\"{\n contentTemplate: calendarTemplate,\n trigger: ui.trigger.click,\n behaviour: ui.behaviour.dropdown,\n minWidth: '300px'\n }\"\n (attached)=\"reference.popover = $event\"\n [icon]=\"ui.icons.calendar\"\n [mask]=\"config.locale.ui.masks.date\"\n [width]=\"ui.width.fluid\"\n [features]=\"features\">\n </jnt-input>\n\n <jnt-input child-of=\"jnt-date-picker-host\" *jntFor=\"ui.breakpoint.mobile\" data-input\n formControlName=\"date\"\n [placeholder]=\"placeholder || ''\"\n [icon]=\"ui.icons.calendar\"\n (click)=\"calendarOpened = !calendarOpened\"\n [mask]=\"config.locale.ui.masks.date\"\n [width]=\"ui.width.fluid\"\n [features]=\"features\">\n </jnt-input>\n </ng-container>\n\n <ng-container *ngIf=\"type === datePickerType.time || type === datePickerType.dateTime\">\n <jnt-input child-of=\"jnt-date-picker-host\" *jntMinFor=\"ui.breakpoint.tablet\"\n data-input data-time\n formControlName=\"time\"\n [icon]=\"ui.icons.time\"\n [jntPopover]=\"{\n contentTemplate: timeTemplate,\n trigger: ui.trigger.click,\n behaviour: ui.behaviour.dropdown,\n features: [ui.feature.smarty],\n minWidth: '150px'\n }\"\n (attached)=\"reference.popover = $event\"\n [mask]=\"config.locale.ui.masks.time + (meridian || '')\"\n [features]=\"features\">\n </jnt-input>\n\n <jnt-input child-of=\"jnt-date-picker-host\" *jntFor=\"ui.breakpoint.mobile\" data-input\n formControlName=\"time\"\n [icon]=\"ui.icons.time\"\n (click)=\"timeOpened = !timeOpened\"\n [mask]=\"config.locale.ui.masks.time + (meridian || '')\"\n [features]=\"features\">\n </jnt-input>\n </ng-container>\n </jnt-stack>\n\n <ng-template #calendarTemplate>\n <jnt-stack child-of=\"jnt-date-picker-host\" data-calendar-dropdown [align]=\"ui.align.stretch\">\n <jnt-calendar child-of=\"jnt-date-picker-host\" data-calendar [features]=\"[ui.feature.today]\" formControlName=\"calendar\"></jnt-calendar>\n </jnt-stack>\n </ng-template>\n\n <ng-template #timeTemplate>\n <jnt-stack child-of=\"jnt-date-picker-host\" data-time-dropdown [orientation]=\"ui.orientation.horizontal\"\n [align]=\"ui.align.center\">\n\n <jnt-stack child-of=\"jnt-date-picker-host\" [align]=\"ui.align.stretch\" [gutter]=\"ui.gutter.small\" data-time-col>\n <jnt-button child-of=\"jnt-date-picker-host\" [icon]=\"ui.icons.chevronUp\"\n [size]=\"ui.size.small\"\n (click)=\"hoursControl.setValue(+hoursControl.value + 1)\">\n </jnt-button>\n <jnt-input child-of=\"jnt-date-picker-host\" data-input\n formControlName=\"hours\"\n [type]=\"ui.input.type.number\">\n </jnt-input>\n <jnt-button child-of=\"jnt-date-picker-host\" [icon]=\"ui.icons.chevronDown\"\n [size]=\"ui.size.small\"\n (click)=\"hoursControl.setValue(+hoursControl.value - 1)\">\n </jnt-button>\n </jnt-stack>\n\n <jnt-stack child-of=\"jnt-date-picker-host\" [align]=\"ui.align.stretch\" [gutter]=\"ui.gutter.small\" data-time-col>\n <jnt-button child-of=\"jnt-date-picker-host\" [icon]=\"ui.icons.chevronUp\"\n [size]=\"ui.size.small\"\n (click)=\"minutesControl.setValue(+minutesControl.value + 1)\">\n </jnt-button>\n <jnt-input child-of=\"jnt-date-picker-host\" data-input\n formControlName=\"minutes\"\n [type]=\"ui.input.type.number\">\n </jnt-input>\n <jnt-button child-of=\"jnt-date-picker-host\" [icon]=\"ui.icons.chevronDown\"\n [size]=\"ui.size.small\"\n (click)=\"minutesControl.setValue(+minutesControl.value - 1)\">\n </jnt-button>\n </jnt-stack>\n\n <jnt-stack child-of=\"jnt-date-picker-host\" *ngIf=\"config.locale.dfns.code !== 'ru'\"\n [align]=\"ui.align.stretch\"\n [gutter]=\"ui.gutter.small\" data-time-col>\n <jnt-button child-of=\"jnt-date-picker-host\" [text]=\"meridians.am\" (click)=\"meridian = meridians.am\"></jnt-button>\n <jnt-button child-of=\"jnt-date-picker-host\" [text]=\"meridians.pm\" (click)=\"meridian = meridians.pm\"></jnt-button>\n </jnt-stack>\n </jnt-stack>\n </ng-template>\n\n <ng-container *ngIf=\"mobile\">\n <ng-container *ngTemplateOutlet=\"calendarTemplate\"></ng-container>\n <ng-container *ngTemplateOutlet=\"timeTemplate\"></ng-container>\n </ng-container>\n</jnt-form>",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent_1),
multi: true
}
]
}),
__metadata("design:paramtypes", [NGXLogger,
FormBuilder,
BreakpointService,
JunteUIConfig])
], DatePickerComponent);
export { DatePickerComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGp1bnRlL3VpLyIsInNvdXJjZXMiOlsibGliL2Zvcm1zL2RhdGUtcGlja2VyL2RhdGUtcGlja2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsTUFBTSxJQUFJLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9DLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUUvRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRXpDLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQUN4QixNQUFNLGVBQWUs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bUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBmb3J3YXJkUmVmLCBIb3N0QmluZGluZywgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybUJ1aWxkZXIsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgZm9ybWF0IGFzIGZvcm1hdERhdGUsIHBhcnNlIH0gZnJvbSAnZGF0ZS1mbnMnO1xuaW1wb3J0IHsgTkdYTG9nZ2VyIH0gZnJvbSAnbmd4LWxvZ2dlcic7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRmVhdHVyZSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvZmVhdHVyZSc7XG5pbXBvcnQgeyBKdW50ZVVJQ29uZmlnIH0gZnJvbSAnLi4vLi4vY29uZmlnJztcbmltcG9ydCB7IFByb3BlcnR5QXBpIH0gZnJvbSAnLi4vLi4vY29yZS9kZWNvcmF0b3JzL2FwaSc7XG5pbXBvcnQgeyBCcmVha3BvaW50IH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy9icmVha3BvaW50JztcbmltcG9ydCB7IFVJIH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy91aSc7XG5pbXBvcnQgeyBXaWR0aCB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvd2lkdGgnO1xuaW1wb3J0IHsgaXNFcXVhbCB9IGZyb20gJy4uLy4uL2NvcmUvdXRpbHMvZXF1YWwnO1xuaW1wb3J0IHsgQnJlYWtwb2ludFNlcnZpY2UgfSBmcm9tICcuLi8uLi9sYXlvdXQvcmVzcG9uc2l2ZS9icmVha3BvaW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgUG9wb3Zlckluc3RhbmNlIH0gZnJvbSAnLi4vLi4vb3ZlcmxheXMvcG9wb3Zlci9wb3BvdmVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgRGF0ZVBpY2tlclR5cGUgfSBmcm9tICcuL2VudW1zJztcblxuY29uc3QgSU5QVVRfREVMQVkgPSA1MDA7XG5jb25zdCBESUdJVF9NQVNLX0NIQVIgPSAnXyc7XG5jb25zdCBIT1VSU19NQVggPSAyMztcbmNvbnN0IE1JTlVURVNfTUFYID0gNTk7XG5cbmVudW0gTWVyaWRpYW4ge1xuICBhbSA9ICcgQU0nLFxuICBwbSA9ICcgUE0nXG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2pudC1kYXRlLXBpY2tlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlLXBpY2tlci5lbmNhcHN1bGF0ZWQuaHRtbCcsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gRGF0ZVBpY2tlckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBEYXRlUGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmhvc3QnKSByZWFkb25seSBob3N0ID0gJ2pudC1kYXRlLXBpY2tlci1ob3N0JztcblxuICB1aSA9IFVJO1xuICBkYXRlUGlja2VyVHlwZSA9IERhdGVQaWNrZXJUeXBlO1xuICBtZXJpZGlhbnMgPSBNZXJpZGlhbjtcbiAgcHJpdmF0ZSBfdHlwZTogRGF0ZVBpY2tlclR5cGUgPSBEYXRlUGlja2VyVHlwZS5kYXRlO1xuXG4gIHJlZmVyZW5jZTogeyBwb3BvdmVyOiBQb3BvdmVySW5zdGFuY2UgfSA9IHtwb3BvdmVyOiBudWxsfTtcbiAgbWVyaWRpYW46IE1lcmlkaWFuO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXdpZHRoJylcbiAgX3dpZHRoOiBXaWR0aCA9IFdpZHRoLmRlZmF1bHQ7XG5cbiAgZGF0ZUNvbnRyb2wgPSB0aGlzLmZiLmNvbnRyb2wobnVsbCk7XG4gIHRpbWVDb250cm9sID0gdGhpcy5mYi5jb250cm9sKG51bGwpO1xuICBob3Vyc0NvbnRyb2wgPSB0aGlzLmZiLmNvbnRyb2wobnVsbCk7XG4gIG1pbnV0ZXNDb250cm9sID0gdGhpcy5mYi5jb250cm9sKG51bGwpO1xuICBjYWxlbmRhckNvbnRyb2wgPSB0aGlzLmZiLmNvbnRyb2wobmV3IERhdGUoKSk7XG4gIGZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICBkYXRlOiB0aGlzLmRhdGVDb250cm9sLFxuICAgIHRpbWU6IHRoaXMudGltZUNvbnRyb2wsXG4gICAgaG91cnM6IHRoaXMuaG91cnNDb250cm9sLFxuICAgIG1pbnV0ZXM6IHRoaXMubWludXRlc0NvbnRyb2wsXG4gICAgY2FsZW5kYXI6IHRoaXMuY2FsZW5kYXJDb250cm9sXG4gIH0pO1xuXG4gIGdldCBtb2JpbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuYnJlYWtwb2ludC5jdXJyZW50ID09PSBCcmVha3BvaW50Lm1vYmlsZTtcbiAgfVxuXG4gIEBIb3N0QmluZGluZygnYXR0ci5jYWxlbmRhci1vcGVuZWQnKVxuICBjYWxlbmRhck9wZW5lZCA9IGZhbHNlO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci50aW1lLW9wZW5lZCcpXG4gIHRpbWVPcGVuZWQgPSBmYWxzZTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnUGxhY2Vob2xkZXIgZm9yIGRhdGUgcGlja2VyJyxcbiAgICB0eXBlOiAnc3RyaW5nJ1xuICB9KVxuICBASW5wdXQoKVxuICBwbGFjZWhvbGRlciA9ICcnO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdCdXR0b24gZm9yIHJlc2V0IGlucHV0JyxcbiAgICBwYXRoOiAndWkuZmVhdHVyZScsXG4gICAgb3B0aW9uczogW0ZlYXR1cmUuYWxsb3dFbXB0eV0sXG4gIH0pXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLWZlYXR1cmVzJylcbiAgQElucHV0KClcbiAgZmVhdHVyZXM6IEZlYXR1cmVbXSA9IFtdO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdEYXRlIHBpY2tlciB0eXBlJyxcbiAgICBwYXRoOiAndWkudHlwZScsXG4gICAgb3B0aW9uczogW0RhdGVQaWNrZXJUeXBlLmRhdGUsIERhdGVQaWNrZXJUeXBlLnRpbWUsIERhdGVQaWNrZXJUeXBlLmRhdGVUaW1lXVxuICB9KVxuICBASW5wdXQoKVxuICBzZXQgdHlwZSh0eXBlOiBEYXRlUGlja2VyVHlwZSkge1xuICAgIHRoaXMuY2xlYXIoKTtcbiAgICB0aGlzLl90eXBlID0gdHlwZSB8fCBEYXRlUGlja2VyVHlwZS5kYXRlO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gIH1cblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnSW5wdXQgd2lkdGgnLFxuICAgIHBhdGg6ICd1aS53aWR0aCcsXG4gICAgZGVmYXVsdDogV2lkdGguZGVmYXVsdCxcbiAgICBvcHRpb25zOiBbV2lkdGguZGVmYXVsdCwgV2lkdGguZmx1aWRdXG4gIH0pXG4gIEBJbnB1dCgpIHNldCB3aWR0aCh3aWR0aDogV2lkdGgpIHtcbiAgICB0aGlzLl93aWR0aCA9IHdpZHRoIHx8IFdpZHRoLmRlZmF1bHQ7XG4gIH1cblxuICBvbkNoYW5nZTogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB0aGlzLmxvZ2dlci5lcnJvcigndmFsdWUgYWNjZXNzb3IgaXMgbm90IHJlZ2lzdGVyZWQnKTtcbiAgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4gdGhpcy5sb2dnZXIuZXJyb3IoJ3ZhbHVlIGFjY2Vzc29yIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIHJlZ2lzdGVyT25DaGFuZ2UgPSBmbiA9PiB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIHJlZ2lzdGVyT25Ub3VjaGVkID0gZm4gPT4gdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpIG9uQmx1ciA9ICgpID0+IHRoaXMub25Ub3VjaGVkKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBsb2dnZXI6IE5HWExvZ2dlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIsXG4gICAgICAgICAgICAgIHByaXZhdGUgYnJlYWtwb2ludDogQnJlYWtwb2ludFNlcnZpY2UsXG4gICAgICAgICAgICAgIHB1YmxpYyBjb25maWc6IEp1bnRlVUlDb25maWcpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuY2FsZW5kYXJDb250cm9sLnZhbHVlQ2hhbmdlcy5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpXG4gICAgICAuc3Vic2NyaWJlKGRhdGUgPT4ge1xuICAgICAgICB0aGlzLmRhdGVDb250cm9sLnNldFZhbHVlKCEhZGF0ZSA/IGZvcm1hdERhdGUoZGF0ZSwgJ1AnLFxuICAgICAgICAgIHtsb2NhbGU6IHRoaXMuY29uZmlnLmxvY2FsZS5kZm5zfSkucmVwbGFjZSgvXFxEL2dpLCAnJykgOiBudWxsKTtcbiAgICAgICAgdGhpcy5jYWxlbmRhck9wZW5lZCA9IGZhbHNlO1xuICAgICAgICBpZiAoISF0aGlzLnJlZmVyZW5jZS5wb3BvdmVyKSB7XG4gICAgICAgICAgdGhpcy5yZWZlcmVuY2UucG9wb3Zlci5oaWRlKCk7XG4gICAgICAgICAgdGhpcy5yZWZlcmVuY2UucG9wb3ZlciA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgdGhpcy5ob3Vyc0NvbnRyb2wudmFsdWVDaGFuZ2VzXG4gICAgICAucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgodmFsMSwgdmFsMikgPT4gaXNFcXVhbCh2YWwxLCB2YWwyKSkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuc2V0VGltZSgpKTtcblxuICAgIHRoaXMubWludXRlc0NvbnRyb2wudmFsdWVDaGFuZ2VzXG4gICAgICAucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgodmFsMSwgdmFsMikgPT4gaXNFcXVhbCh2YWwxLCB2YWwyKSkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuc2V0VGltZSgpKTtcblxuICAgIHRoaXMuZGF0ZUNvbnRyb2wudmFsdWVDaGFuZ2VzLnBpcGUoZGVib3VuY2VUaW1lKElOUFVUX0RFTEFZKSwgZGlzdGluY3RVbnRpbENoYW5nZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoZGF0ZSA9PiB0aGlzLnVwZGF0ZShkYXRlLCB0cnVlKSk7XG5cbiAgICB0aGlzLnRpbWVDb250cm9sLnZhbHVlQ2hhbmdlcy5waXBlKGRlYm91bmNlVGltZShJTlBVVF9ERUxBWSksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpXG4gICAgICAuc3Vic2NyaWJlKHRpbWUgPT4gdGhpcy51cGRhdGUodGltZSkpO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgaWYgKCEhdGhpcy5yZWZlcmVuY2UucG9wb3Zlcikge1xuICAgICAgdGhpcy5yZWZlcmVuY2UucG9wb3Zlci5oaWRlKCk7XG4gICAgICB0aGlzLnJlZmVyZW5jZS5wb3BvdmVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICB0aGlzLmRhdGVDb250cm9sLnNldFZhbHVlKG51bGwsIHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG4gICAgdGhpcy50aW1lQ29udHJvbC5zZXRWYWx1ZShudWxsLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgIHRoaXMuaG91cnNDb250cm9sLnNldFZhbHVlKG51bGwsIHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG4gICAgdGhpcy5taW51dGVzQ29udHJvbC5zZXRWYWx1ZShudWxsLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICB9XG5cbiAgdXBkYXRlKHZhbHVlOiBzdHJpbmcsIGNsb3NlID0gZmFsc2UpIHtcbiAgICBpZiAoISF2YWx1ZSB8fCB0aGlzLnR5cGUgPT09IERhdGVQaWNrZXJUeXBlLmRhdGVUaW1lKSB7XG4gICAgICBpZiAodGhpcy50eXBlICE9PSBEYXRlUGlja2VyVHlwZS5kYXRlVGltZSkge1xuICAgICAgICBsZXQgb3V0cHV0ID0gdGhpcy50eXBlID09PSBEYXRlUGlja2VyVHlwZS5kYXRlXG4gICAgICAgICAgPyB0aGlzLmNvbmZpZy5sb2NhbGUudWkubWFza3MuZGF0ZVxuICAgICAgICAgIDogdGhpcy5jb25maWcubG9jYWxlLnVpLm1hc2tzLnRpbWUgKyAodGhpcy5tZXJpZGlhbiB8fCAnJyk7XG4gICAgICAgIGZvciAoY29uc3QgY2hhciBvZiB2YWx1ZSkge1xuICAgICAgICAgIG91dHB1dCA9IG91dHB1dC5yZXBsYWNlKERJR0lUX01BU0tfQ0hBUiwgY2hhcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyc2VkID0gcGFyc2Uob3V0cHV0LCB0aGlzLnR5cGUgPT09IERhdGVQaWNrZXJUeXBlLmRhdGVcbiAgICAgICAgICA/ICdQJyA6ICdwJywgbmV3IERhdGUoMCksXG4gICAgICAgICAge2xvY2FsZTogdGhpcy5jb25maWcubG9jYWxlLmRmbnN9KTtcbiAgICAgICAgaWYgKHBhcnNlZCBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKHBhcnNlZC5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gRGF0ZVBpY2tlclR5cGUuZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5jYWxlbmRhckNvbnRyb2wuc2V0VmFsdWUocGFyc2VkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ob3Vyc0NvbnRyb2wuc2V0VmFsdWUocGFyc2VkLmdldEhvdXJzKCkpO1xuICAgICAgICAgICAgdGhpcy5taW51dGVzQ29udHJvbC5zZXRWYWx1ZShwYXJzZWQuZ2V0TWludXRlcygpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5vbkNoYW5nZShwYXJzZWQpO1xuICAgICAgICAgIGlmIChjbG9zZSkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghIXRoaXMuZGF0ZUNvbnRyb2wudmFsdWUgJiYgISF0aGlzLnRpbWVDb250cm9sLnZhbHVlKSB7XG4gICAgICAgIGxldCBvdXRwdXQgPSB0aGlzLmNvbmZpZy5sb2NhbGUudWkubWFza3MuZGF0ZXRpbWUgKyAodGhpcy5tZXJpZGlhbiB8fCAnJyk7XG4gICAgICAgIGZvciAoY29uc3QgY2hhciBvZiB0aGlzLmRhdGVDb250cm9sLnZhbHVlKSB7XG4gICAgICAgICAgb3V0cHV0ID0gb3V0cHV0LnJlcGxhY2UoRElHSVRfTUFTS19DSEFSLCBjaGFyKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGNoYXIgb2YgdGhpcy50aW1lQ29udHJvbC52YWx1ZSkge1xuICAgICAgICAgIG91dHB1dCA9IG91dHB1dC5yZXBsYWNlKERJR0lUX01BU0tfQ0hBUiwgY2hhcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyc2VkID0gcGFyc2Uob3V0cHV0LCAnUHAnLCBuZXcgRGF0ZSgpLFxuICAgICAgICAgIHtsb2NhbGU6IHRoaXMuY29uZmlnLmxvY2FsZS5kZm5zfSk7XG4gICAgICAgIGlmIChwYXJzZWQgaW5zdGFuY2VvZiBEYXRlICYmICFpc05hTihwYXJzZWQuZ2V0VGltZSgpKSkge1xuICAgICAgICAgIHRoaXMub25DaGFuZ2UocGFyc2VkKTtcbiAgICAgICAgICBpZiAoY2xvc2UpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vbkNoYW5nZShudWxsKTtcbiAgICAgIGlmICghdGhpcy5kYXRlQ29udHJvbC52YWx1ZSkge1xuICAgICAgICB0aGlzLmNhbGVuZGFyQ29udHJvbC5zZXRWYWx1ZShudWxsLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhvdXJzQ29udHJvbC5zZXRWYWx1ZShudWxsLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgICB0aGlzLm1pbnV0ZXNDb250cm9sLnNldFZhbHVlKG51bGwsIHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzZXRUaW1lKCkge1xuICAgIGxldCBob3VycyA9ICcwMCc7XG4gICAgbGV0IG1pbnV0ZXMgPSAnMDAnO1xuXG4gICAgaWYgKHRoaXMuaG91cnNDb250cm9sLnZhbHVlICE9PSBudWxsKSB7XG4gICAgICBob3VycyA9IE1hdGgubWluKE1hdGgubWF4KCt0aGlzLmhvdXJzQ29udHJvbC52YWx1ZSwgMCksIEhPVVJTX01BWCkudG9TdHJpbmcoKTtcbiAgICAgIHRoaXMuaG91cnNDb250cm9sLnNldFZhbHVlKCtob3Vycywge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICAgIGhvdXJzID0gaG91cnMubGVuZ3RoID09PSAxID8gYDAke2hvdXJzfWAgOiBob3VycztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ob3Vyc0NvbnRyb2wuc2V0VmFsdWUoMCwge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5taW51dGVzQ29udHJvbC52YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgbWludXRlcyA9IE1hdGgubWluKE1hdGgubWF4KCt0aGlzLm1pbnV0ZXNDb250cm9sLnZhbHVlLCAwKSwgTUlOVVRFU19NQVgpLnRvU3RyaW5nKCk7XG4gICAgICB0aGlzLm1pbnV0ZXNDb250cm9sLnNldFZhbHVlKCttaW51dGVzLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgbWludXRlcyA9IG1pbnV0ZXMubGVuZ3RoID09PSAxID8gYDAke21pbnV0ZXN9YCA6IG1pbnV0ZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubWludXRlc0NvbnRyb2wuc2V0VmFsdWUoMCwge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICB9XG5cbiAgICB0aGlzLnRpbWVDb250cm9sLnNldFZhbHVlKGAke2hvdXJzfSR7bWludXRlc31gKTtcbiAgfVxuXG4gIHdyaXRlVmFsdWUoZGF0ZTogRGF0ZSkge1xuICAgIGlmIChkYXRlIGluc3RhbmNlb2YgRGF0ZSAmJiAhaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICB0aGlzLmNhbGVuZGFyQ29udHJvbC5zZXRWYWx1ZShkYXRlLCB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICAgICAgdGhpcy5kYXRlQ29udHJvbC5zZXRWYWx1ZShmb3JtYXREYXRlKGRhdGUsICdQJyxcbiAgICAgICAge2xvY2FsZTogdGhpcy5jb25maWcubG9jYWxlLmRmbnN9KSwge2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jbGVhcigpO1xuICAgIH1cbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoZGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICBkaXNhYmxlZCA/IHRoaXMuZGF0ZUNvbnRyb2wuZGlzYWJsZSh7ZW1pdEV2ZW50OiBmYWxzZX0pXG4gICAgICA6IHRoaXMuZGF0ZUNvbnRyb2wuZW5hYmxlKHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG4gIH1cbn1cbiJdfQ==