@hug/ngx-time-picker 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
# 3.0.0 (2025-02-06)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- ⚠️ migrate to Angular 19 ([d186ab2](https://github.com/DSI-HUG/ngx-components/commit/d186ab2))
|
|
6
|
+
|
|
7
|
+
### 🐛 Fixes
|
|
8
|
+
|
|
9
|
+
- ngx-core dependency no more required ([a4bfdaf](https://github.com/DSI-HUG/ngx-components/commit/a4bfdaf))
|
|
10
|
+
|
|
11
|
+
### 🌱 Dependencies
|
|
12
|
+
|
|
13
|
+
- **@hug/ngx-numeric-stepper:** upgrade to v3.0.0 ([405c1b5](https://github.com/DSI-HUG/ngx-components/commit/405c1b5))
|
|
14
|
+
|
|
15
|
+
### ❤️ Thank You
|
|
16
|
+
|
|
17
|
+
- Badisi @Badisi
|
|
18
|
+
- damien-guillermet @damien-guillermet
|
|
19
|
+
- dsi-hug-bot @dsi-hug-bot
|
|
20
|
+
|
|
21
|
+
## 2.0.1 (2024-09-25)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### 🌱 Dependencies
|
|
25
|
+
|
|
26
|
+
- **@hug/ngx-numeric-stepper:** upgrade to v2.0.1 ([0af4397](https://github.com/DSI-HUG/ngx-components/commit/0af4397))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### ❤️ Thank You
|
|
30
|
+
|
|
31
|
+
- dsi-hug-bot @dsi-hug-bot
|
|
32
|
+
|
|
1
33
|
# 2.0.0 (2024-09-11)
|
|
2
34
|
|
|
3
35
|
|
|
@@ -255,12 +255,12 @@ class NgxTimePickerComponent {
|
|
|
255
255
|
// ************* End of ControlValueAccessor Implementation **************
|
|
256
256
|
onChangeCallback = (_a) => undefined;
|
|
257
257
|
onTouchedCallback = () => undefined;
|
|
258
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
259
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
258
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxTimePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
259
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.4", type: NgxTimePickerComponent, isStandalone: true, selector: "ngx-time-picker", inputs: { mode: "mode", dataType: "dataType", forceNullValue: "forceNullValue", appearance: "appearance", autoFocus: "autoFocus", defaultPlaceholderHours: "defaultPlaceholderHours", defaultPlaceholderMinutes: "defaultPlaceholderMinutes", time: "time", step: "step", disabled: "disabled" }, outputs: { timeChange: "timeChange" }, viewQueries: [{ propertyName: "hours", first: true, predicate: ["hours"], descendants: true }, { propertyName: "minutes", first: true, predicate: ["minutes"], descendants: true }], ngImport: i0, template: "<!-- Hours -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"hours\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [style.display]=\"mode === 'minutesOnly' ? 'none' : 'block'\">\n <input\n #hours\n matInput\n type=\"text\"\n [ngModel]=\"hoursValue | number: '2.'\"\n (change)=\"onHoursChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'hours')\"\n [disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderHours\"\n (click)=\"onClick('hours')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('hours')\"\n (decrement)=\"decrementValue('hours')\"></ngx-numeric-stepper>\n</mat-form-field>\n\n<!-- Separator -->\n<span class=\"time-separator\" [style.display]=\"mode === 'minutesOnly' || mode === 'hoursOnly' ? 'none' : 'block'\">\n :\n</span>\n\n<!-- Minutes -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"minutes\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [style.display]=\"mode === 'hoursOnly' ? 'none' : 'block'\">\n <input\n #minutes\n matInput\n type=\"text\"\n [ngModel]=\"minutesValue | number: '2.'\"\n (change)=\"onMinutesChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'minutes')\"\n [disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderMinutes\"\n (click)=\"onClick('minutes')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('minutes')\"\n (decrement)=\"decrementValue('minutes')\"></ngx-numeric-stepper>\n</mat-form-field>\n", styles: ["ngx-time-picker{display:flex;flex-direction:row;align-items:baseline;justify-content:center}ngx-time-picker:not([inform]) .mat-form-field-appearance-outline .mat-mdc-form-field-wrapper{padding-bottom:0}ngx-time-picker:not([inform]) .mat-form-field-appearance-outline .mat-mdc-form-field-wrapper .mat-mdc-form-field-infix{border-bottom:.7em solid transparent}ngx-time-picker mat-form-field[ngx-numeric-stepper-form-field]{width:52px}ngx-time-picker .time-separator{width:4px;font-size:14.5px;line-height:17px;margin:0 8px}\n"], dependencies: [{ kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: NgxNumericStepperComponent, selector: "ngx-numeric-stepper", inputs: ["layout", "input", "arrowIcons", "showOnInit"], outputs: ["increment", "decrement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
260
260
|
}
|
|
261
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
261
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxTimePickerComponent, decorators: [{
|
|
262
262
|
type: Component,
|
|
263
|
-
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngx-time-picker', encapsulation: ViewEncapsulation.None,
|
|
263
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngx-time-picker', encapsulation: ViewEncapsulation.None, imports: [
|
|
264
264
|
DecimalPipe,
|
|
265
265
|
FormsModule,
|
|
266
266
|
MatFormField,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hug-ngx-time-picker.mjs","sources":["../../../projects/time-picker/src/time-picker.component.ts","../../../projects/time-picker/src/time-picker.component.html","../../../projects/time-picker/src/hug-ngx-time-picker.ts"],"sourcesContent":["import { BooleanInput, coerceBooleanProperty, coerceNumberProperty, NumberInput } from '@angular/cdk/coercion';\nimport { DecimalPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, EventEmitter, inject, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ControlValueAccessor, FormsModule, NgControl } from '@angular/forms';\nimport { MatFormField, MatFormFieldAppearance } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { NgxNumericStepperComponent } from '@hug/ngx-numeric-stepper';\nimport { isSameHour, set } from 'date-fns';\nimport { debounce, distinctUntilChanged, map, Subject, timer } from 'rxjs';\n\nexport type NgxTimePickerDisplayMode = 'fullTime' | 'fullTimeWithHoursDisabled' | 'fullTimeWithMinutesDisabled' | 'hoursOnly' | 'minutesOnly';\n\nexport type NgxDateOrDuration = Date | Duration;\n\ntype DataType = 'date' | 'duration';\n\ntype FieldType = 'hours' | 'minutes';\n\n// TODO sdil refactor rxjs flows\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-time-picker',\n styleUrls: ['./time-picker.component.scss'],\n templateUrl: './time-picker.component.html',\n encapsulation: ViewEncapsulation.None,\n standalone: true,\n imports: [\n DecimalPipe,\n FormsModule,\n MatFormField,\n MatInput,\n NgxNumericStepperComponent\n ]\n})\nexport class NgxTimePickerComponent implements ControlValueAccessor {\n @ViewChild('hours') public hours?: ElementRef<HTMLInputElement>;\n @ViewChild('minutes') public minutes?: ElementRef<HTMLInputElement>;\n\n @Output() public readonly timeChange = new EventEmitter<NgxDateOrDuration>();\n\n /** Display mode for the time-picker */\n @Input() public mode: NgxTimePickerDisplayMode = 'fullTime';\n\n /** Data type to manage (Date or Duration) */\n @Input() public dataType: DataType = 'date';\n\n /**\n * Force the hour or minute to be null (only if the other field is disabled)\n *\n * For instance, if set to true and the hours are disabled, the minutes input value will be null\n * This is useful to force the user to provide a value\n */\n @Input() public forceNullValue = false;\n\n @Input() public appearance: MatFormFieldAppearance = 'outline';\n\n @Input()\n public set autoFocus(value: BooleanInput) {\n this._autoFocus = coerceBooleanProperty(value);\n }\n\n @Input() public defaultPlaceholderHours = '_ _';\n @Input() public defaultPlaceholderMinutes = '_ _';\n\n @Input()\n public set time(value: NgxDateOrDuration | undefined) {\n this.writeValue(value);\n }\n\n public get time(): NgxDateOrDuration | undefined {\n return this.value;\n }\n\n /** Step of the arrows */\n @Input()\n public set step(value: NumberInput) {\n this._step = coerceNumberProperty(value);\n this.changeDetectorRef.markForCheck();\n }\n\n /** To get the step of the minutes arrows */\n public get step(): NumberInput {\n return this._step;\n }\n\n /** Disabled property setter. Can be string or empty so you can use it like : <time-picker disabled></time-picker> */\n @Input()\n public set disabled(value: BooleanInput) {\n this._disabled = coerceBooleanProperty(value);\n this.changeDetectorRef.markForCheck();\n }\n\n /** To get disabled attribute. */\n public get disabled(): BooleanInput {\n return this._disabled;\n }\n\n public onHoursChange$ = new Subject<Event | number>();\n public onMinutesChange$ = new Subject<Event | number>();\n public _step = 1;\n\n protected changeDetectorRef = inject(ChangeDetectorRef);\n protected control = inject(NgControl, { optional: true, self: true });\n private destroyRef = inject(DestroyRef);\n\n private _disabled = false;\n private _value?: NgxDateOrDuration;\n private _autoFocus = true;\n\n public constructor() {\n if (this.control) {\n this.control.valueAccessor = this;\n }\n\n this.onHoursChange$.pipe(\n debounce(hours => timer(typeof hours === 'object' ? 0 : 10)),\n distinctUntilChanged(),\n map(hours => {\n if (typeof hours === 'object') {\n const value = (hours.target as HTMLInputElement).value;\n return [value !== undefined ? parseInt(value, 10) : undefined, true] as const;\n }\n return [!isNaN(hours) ? hours : 0, false] as const;\n }),\n takeUntilDestroyed(this.destroyRef)\n ).subscribe(([hours, isEvent]) => {\n if (!this.value) {\n this.value = this.dataType === 'date' ? set(new Date(), { hours, minutes: 0, seconds: 0, milliseconds: 0 }) : { hours, minutes: 0 } as Duration;\n } else if (this.value instanceof Date) {\n const value = this.value?.getTime();\n const clone = new Date(value);\n if (hours !== undefined) {\n clone.setHours(hours);\n }\n this.value = clone;\n } else {\n this.value = {\n hours: hours && hours < 0 ? 0 : hours,\n minutes: this.value.minutes\n };\n }\n this.changeDetectorRef.markForCheck();\n\n if (isEvent && this._autoFocus && this.minutes) {\n this.minutes.nativeElement.focus({\n preventScroll: true\n });\n this.minutes.nativeElement.select();\n }\n });\n\n this.onMinutesChange$.pipe(\n debounce(minutes => timer(typeof minutes === 'object' ? 0 : 10)),\n distinctUntilChanged(),\n map(event => {\n let minutes: number | undefined;\n if (typeof event === 'object') {\n const value = (event.target as HTMLInputElement).value;\n minutes = value !== undefined ? parseInt(value, 10) : undefined;\n } else {\n minutes = event;\n }\n return minutes && !isNaN(minutes) && minutes || 0;\n }),\n takeUntilDestroyed(this.destroyRef)\n ).subscribe(minutes => {\n if (!this.value) {\n this.value = this.dataType === 'date' ? set(new Date(), { hours: 0, minutes, seconds: 0, milliseconds: 0 }) : { hours: 0, minutes } as Duration;\n } else if (this.value instanceof Date) {\n const newValue = new Date(this.value.getTime());\n if (minutes < 0) {\n minutes += 60;\n } else if (minutes >= 60) {\n minutes -= 60;\n }\n newValue.setMinutes(minutes);\n\n if (this.mode !== 'fullTimeWithHoursDisabled' || (this.mode === 'fullTimeWithHoursDisabled' && isSameHour(this.value, newValue))) {\n this.value = newValue;\n }\n } else {\n this.value = {\n hours: this.value.hours,\n minutes: minutes < 0 || minutes >= 60 ? 0 : minutes\n };\n }\n this.changeDetectorRef.markForCheck();\n });\n }\n\n public onKeyDown($event: KeyboardEvent, mode: 'hours' | 'minutes'): void {\n // Get input element\n const inputElement = mode === 'hours' ? this.hours?.nativeElement : this.minutes?.nativeElement;\n if ($event.key?.toLowerCase() === 'd') {\n $event.stopPropagation();\n $event.preventDefault();\n this.value = new Date();\n } else if (inputElement) {\n if ($event.key?.toLowerCase() === 'a' && $event.ctrlKey) {\n inputElement.select();\n } else if ($event.key && !['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Backspace', 'Delete', 'Tab', 'Enter', 'Control', 'Shift'].includes($event.key)) {\n // Set regex for input format validation (differs if we are dealing with a date or a duration)\n let regex;\n if (mode === 'hours') {\n regex = this.dataType === 'date' ? /^(\\d|[01]\\d|2[0-3])$/ : /^(\\d+)$/;\n } else {\n regex = /^(\\d|[0-5]\\d)$/;\n }\n\n // Get the selection in input element\n const [selectionStart, selectionEnd] = [inputElement.selectionStart || 0, inputElement.selectionEnd || 0].sort((a, b) => a - b);\n const selectionDiff = selectionEnd - selectionStart;\n\n // Get the current value in input element and update it with the new touched key\n const inputValue = inputElement.value || '';\n const inputValueArr = Array.from(inputValue);\n inputValueArr.splice(selectionStart, selectionDiff, $event.key);\n const newInputValue = inputValueArr.join('');\n\n // Prevent event if the time is not valid\n if (!regex.test(newInputValue)) {\n $event.stopPropagation();\n $event.preventDefault();\n } else if (this._autoFocus && mode === 'hours' && ((this.dataType === 'date' && parseFloat(newInputValue) >= 3) || newInputValue.length === 2)) {\n this.onHoursChange$.next($event);\n }\n }\n }\n }\n\n public get hoursValue(): number | undefined {\n if (!this.value || (this.forceNullValue && this.mode === 'fullTimeWithMinutesDisabled' && !!this.control?.pristine)) {\n return undefined;\n }\n return this.value instanceof Date ? this.value.getHours() : this.value.hours;\n }\n\n public get minutesValue(): number | undefined {\n if (!this.value || (this.forceNullValue && this.mode === 'fullTimeWithHoursDisabled' && !!this.control?.pristine)) {\n return undefined;\n }\n return this.value instanceof Date ? this.value.getMinutes() : this.value.minutes;\n }\n\n public incrementValue(fieldType: FieldType): void {\n if (fieldType === 'hours') {\n this.onHoursChange$.next((this.hoursValue || 0) + 1);\n } else {\n this.onMinutesChange$.next((this.minutesValue || 0) + this._step);\n }\n }\n\n public decrementValue(fieldType: FieldType): void {\n if (fieldType === 'hours') {\n this.onHoursChange$.next((this.hoursValue || 0) - 1);\n } else {\n this.onMinutesChange$.next((this.minutesValue || 0) - this._step);\n }\n }\n\n public onClick(mode: 'hours' | 'minutes'): void {\n if (this._autoFocus) {\n if (mode === 'hours') {\n this.hours?.nativeElement.select();\n } else {\n this.minutes?.nativeElement.select();\n }\n }\n }\n\n // ************* ControlValueAccessor Implementation **************\n /** set accessor including call the onchange callback */\n public set value(v: NgxDateOrDuration | undefined) {\n if (v !== this._value) {\n this.writeValue(v);\n this.onChangeCallback(v);\n this.timeChange.emit(v);\n }\n }\n\n /** get accessor */\n public get value(): NgxDateOrDuration | undefined {\n return this._value;\n }\n\n /** From ControlValueAccessor interface */\n public writeValue(value: NgxDateOrDuration | undefined): void {\n if ((value ?? null) !== (this._value ?? null)) {\n if (value instanceof Date) {\n this._value = value ? new Date(value.getTime()) : set(new Date(), { hours: 0, minutes: 0, seconds: 0 });\n } else {\n this._value = value;\n }\n\n this.changeDetectorRef.markForCheck();\n }\n }\n\n /** From ControlValueAccessor interface */\n public registerOnChange(fn: (_a: unknown) => void): void {\n this.onChangeCallback = fn;\n }\n\n /** From ControlValueAccessor interface */\n public registerOnTouched(fn: () => void): void {\n this.onTouchedCallback = fn;\n }\n\n public setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n // ************* End of ControlValueAccessor Implementation **************\n\n protected onChangeCallback = (_a: unknown): void => undefined;\n protected onTouchedCallback = (): void => undefined;\n}\n","<!-- Hours -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"hours\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [style.display]=\"mode === 'minutesOnly' ? 'none' : 'block'\">\n <input\n #hours\n matInput\n type=\"text\"\n [ngModel]=\"hoursValue | number: '2.'\"\n (change)=\"onHoursChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'hours')\"\n [disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderHours\"\n (click)=\"onClick('hours')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('hours')\"\n (decrement)=\"decrementValue('hours')\"></ngx-numeric-stepper>\n</mat-form-field>\n\n<!-- Separator -->\n<span class=\"time-separator\" [style.display]=\"mode === 'minutesOnly' || mode === 'hoursOnly' ? 'none' : 'block'\">\n :\n</span>\n\n<!-- Minutes -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"minutes\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [style.display]=\"mode === 'hoursOnly' ? 'none' : 'block'\">\n <input\n #minutes\n matInput\n type=\"text\"\n [ngModel]=\"minutesValue | number: '2.'\"\n (change)=\"onMinutesChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'minutes')\"\n [disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderMinutes\"\n (click)=\"onClick('minutes')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('minutes')\"\n (decrement)=\"decrementValue('minutes')\"></ngx-numeric-stepper>\n</mat-form-field>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hug-ngx-time-picker.mjs","sources":["../../../projects/time-picker/src/time-picker.component.ts","../../../projects/time-picker/src/time-picker.component.html","../../../projects/time-picker/src/hug-ngx-time-picker.ts"],"sourcesContent":["import { BooleanInput, coerceBooleanProperty, coerceNumberProperty, NumberInput } from '@angular/cdk/coercion';\nimport { DecimalPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, EventEmitter, inject, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ControlValueAccessor, FormsModule, NgControl } from '@angular/forms';\nimport { MatFormField, MatFormFieldAppearance } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { NgxNumericStepperComponent } from '@hug/ngx-numeric-stepper';\nimport { isSameHour, set } from 'date-fns';\nimport { debounce, distinctUntilChanged, map, Subject, timer } from 'rxjs';\n\nexport type NgxTimePickerDisplayMode = 'fullTime' | 'fullTimeWithHoursDisabled' | 'fullTimeWithMinutesDisabled' | 'hoursOnly' | 'minutesOnly';\n\nexport type NgxDateOrDuration = Date | Duration;\n\ntype DataType = 'date' | 'duration';\n\ntype FieldType = 'hours' | 'minutes';\n\n// TODO sdil refactor rxjs flows\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-time-picker',\n styleUrls: ['./time-picker.component.scss'],\n templateUrl: './time-picker.component.html',\n encapsulation: ViewEncapsulation.None,\n imports: [\n DecimalPipe,\n FormsModule,\n MatFormField,\n MatInput,\n NgxNumericStepperComponent\n ]\n})\nexport class NgxTimePickerComponent implements ControlValueAccessor {\n @ViewChild('hours') public hours?: ElementRef<HTMLInputElement>;\n @ViewChild('minutes') public minutes?: ElementRef<HTMLInputElement>;\n\n @Output() public readonly timeChange = new EventEmitter<NgxDateOrDuration>();\n\n /** Display mode for the time-picker */\n @Input() public mode: NgxTimePickerDisplayMode = 'fullTime';\n\n /** Data type to manage (Date or Duration) */\n @Input() public dataType: DataType = 'date';\n\n /**\n * Force the hour or minute to be null (only if the other field is disabled)\n *\n * For instance, if set to true and the hours are disabled, the minutes input value will be null\n * This is useful to force the user to provide a value\n */\n @Input() public forceNullValue = false;\n\n @Input() public appearance: MatFormFieldAppearance = 'outline';\n\n @Input()\n public set autoFocus(value: BooleanInput) {\n this._autoFocus = coerceBooleanProperty(value);\n }\n\n @Input() public defaultPlaceholderHours = '_ _';\n @Input() public defaultPlaceholderMinutes = '_ _';\n\n @Input()\n public set time(value: NgxDateOrDuration | undefined) {\n this.writeValue(value);\n }\n\n public get time(): NgxDateOrDuration | undefined {\n return this.value;\n }\n\n /** Step of the arrows */\n @Input()\n public set step(value: NumberInput) {\n this._step = coerceNumberProperty(value);\n this.changeDetectorRef.markForCheck();\n }\n\n /** To get the step of the minutes arrows */\n public get step(): NumberInput {\n return this._step;\n }\n\n /** Disabled property setter. Can be string or empty so you can use it like : <time-picker disabled></time-picker> */\n @Input()\n public set disabled(value: BooleanInput) {\n this._disabled = coerceBooleanProperty(value);\n this.changeDetectorRef.markForCheck();\n }\n\n /** To get disabled attribute. */\n public get disabled(): BooleanInput {\n return this._disabled;\n }\n\n public onHoursChange$ = new Subject<Event | number>();\n public onMinutesChange$ = new Subject<Event | number>();\n public _step = 1;\n\n protected changeDetectorRef = inject(ChangeDetectorRef);\n protected control = inject(NgControl, { optional: true, self: true });\n private destroyRef = inject(DestroyRef);\n\n private _disabled = false;\n private _value?: NgxDateOrDuration;\n private _autoFocus = true;\n\n public constructor() {\n if (this.control) {\n this.control.valueAccessor = this;\n }\n\n this.onHoursChange$.pipe(\n debounce(hours => timer(typeof hours === 'object' ? 0 : 10)),\n distinctUntilChanged(),\n map(hours => {\n if (typeof hours === 'object') {\n const value = (hours.target as HTMLInputElement).value;\n return [value !== undefined ? parseInt(value, 10) : undefined, true] as const;\n }\n return [!isNaN(hours) ? hours : 0, false] as const;\n }),\n takeUntilDestroyed(this.destroyRef)\n ).subscribe(([hours, isEvent]) => {\n if (!this.value) {\n this.value = this.dataType === 'date' ? set(new Date(), { hours, minutes: 0, seconds: 0, milliseconds: 0 }) : { hours, minutes: 0 } as Duration;\n } else if (this.value instanceof Date) {\n const value = this.value?.getTime();\n const clone = new Date(value);\n if (hours !== undefined) {\n clone.setHours(hours);\n }\n this.value = clone;\n } else {\n this.value = {\n hours: hours && hours < 0 ? 0 : hours,\n minutes: this.value.minutes\n };\n }\n this.changeDetectorRef.markForCheck();\n\n if (isEvent && this._autoFocus && this.minutes) {\n this.minutes.nativeElement.focus({\n preventScroll: true\n });\n this.minutes.nativeElement.select();\n }\n });\n\n this.onMinutesChange$.pipe(\n debounce(minutes => timer(typeof minutes === 'object' ? 0 : 10)),\n distinctUntilChanged(),\n map(event => {\n let minutes: number | undefined;\n if (typeof event === 'object') {\n const value = (event.target as HTMLInputElement).value;\n minutes = value !== undefined ? parseInt(value, 10) : undefined;\n } else {\n minutes = event;\n }\n return minutes && !isNaN(minutes) && minutes || 0;\n }),\n takeUntilDestroyed(this.destroyRef)\n ).subscribe(minutes => {\n if (!this.value) {\n this.value = this.dataType === 'date' ? set(new Date(), { hours: 0, minutes, seconds: 0, milliseconds: 0 }) : { hours: 0, minutes } as Duration;\n } else if (this.value instanceof Date) {\n const newValue = new Date(this.value.getTime());\n if (minutes < 0) {\n minutes += 60;\n } else if (minutes >= 60) {\n minutes -= 60;\n }\n newValue.setMinutes(minutes);\n\n if (this.mode !== 'fullTimeWithHoursDisabled' || (this.mode === 'fullTimeWithHoursDisabled' && isSameHour(this.value, newValue))) {\n this.value = newValue;\n }\n } else {\n this.value = {\n hours: this.value.hours,\n minutes: minutes < 0 || minutes >= 60 ? 0 : minutes\n };\n }\n this.changeDetectorRef.markForCheck();\n });\n }\n\n public onKeyDown($event: KeyboardEvent, mode: 'hours' | 'minutes'): void {\n // Get input element\n const inputElement = mode === 'hours' ? this.hours?.nativeElement : this.minutes?.nativeElement;\n if ($event.key?.toLowerCase() === 'd') {\n $event.stopPropagation();\n $event.preventDefault();\n this.value = new Date();\n } else if (inputElement) {\n if ($event.key?.toLowerCase() === 'a' && $event.ctrlKey) {\n inputElement.select();\n } else if ($event.key && !['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Backspace', 'Delete', 'Tab', 'Enter', 'Control', 'Shift'].includes($event.key)) {\n // Set regex for input format validation (differs if we are dealing with a date or a duration)\n let regex;\n if (mode === 'hours') {\n regex = this.dataType === 'date' ? /^(\\d|[01]\\d|2[0-3])$/ : /^(\\d+)$/;\n } else {\n regex = /^(\\d|[0-5]\\d)$/;\n }\n\n // Get the selection in input element\n const [selectionStart, selectionEnd] = [inputElement.selectionStart || 0, inputElement.selectionEnd || 0].sort((a, b) => a - b);\n const selectionDiff = selectionEnd - selectionStart;\n\n // Get the current value in input element and update it with the new touched key\n const inputValue = inputElement.value || '';\n const inputValueArr = Array.from(inputValue);\n inputValueArr.splice(selectionStart, selectionDiff, $event.key);\n const newInputValue = inputValueArr.join('');\n\n // Prevent event if the time is not valid\n if (!regex.test(newInputValue)) {\n $event.stopPropagation();\n $event.preventDefault();\n } else if (this._autoFocus && mode === 'hours' && ((this.dataType === 'date' && parseFloat(newInputValue) >= 3) || newInputValue.length === 2)) {\n this.onHoursChange$.next($event);\n }\n }\n }\n }\n\n public get hoursValue(): number | undefined {\n if (!this.value || (this.forceNullValue && this.mode === 'fullTimeWithMinutesDisabled' && !!this.control?.pristine)) {\n return undefined;\n }\n return this.value instanceof Date ? this.value.getHours() : this.value.hours;\n }\n\n public get minutesValue(): number | undefined {\n if (!this.value || (this.forceNullValue && this.mode === 'fullTimeWithHoursDisabled' && !!this.control?.pristine)) {\n return undefined;\n }\n return this.value instanceof Date ? this.value.getMinutes() : this.value.minutes;\n }\n\n public incrementValue(fieldType: FieldType): void {\n if (fieldType === 'hours') {\n this.onHoursChange$.next((this.hoursValue || 0) + 1);\n } else {\n this.onMinutesChange$.next((this.minutesValue || 0) + this._step);\n }\n }\n\n public decrementValue(fieldType: FieldType): void {\n if (fieldType === 'hours') {\n this.onHoursChange$.next((this.hoursValue || 0) - 1);\n } else {\n this.onMinutesChange$.next((this.minutesValue || 0) - this._step);\n }\n }\n\n public onClick(mode: 'hours' | 'minutes'): void {\n if (this._autoFocus) {\n if (mode === 'hours') {\n this.hours?.nativeElement.select();\n } else {\n this.minutes?.nativeElement.select();\n }\n }\n }\n\n // ************* ControlValueAccessor Implementation **************\n /** set accessor including call the onchange callback */\n public set value(v: NgxDateOrDuration | undefined) {\n if (v !== this._value) {\n this.writeValue(v);\n this.onChangeCallback(v);\n this.timeChange.emit(v);\n }\n }\n\n /** get accessor */\n public get value(): NgxDateOrDuration | undefined {\n return this._value;\n }\n\n /** From ControlValueAccessor interface */\n public writeValue(value: NgxDateOrDuration | undefined): void {\n if ((value ?? null) !== (this._value ?? null)) {\n if (value instanceof Date) {\n this._value = value ? new Date(value.getTime()) : set(new Date(), { hours: 0, minutes: 0, seconds: 0 });\n } else {\n this._value = value;\n }\n\n this.changeDetectorRef.markForCheck();\n }\n }\n\n /** From ControlValueAccessor interface */\n public registerOnChange(fn: (_a: unknown) => void): void {\n this.onChangeCallback = fn;\n }\n\n /** From ControlValueAccessor interface */\n public registerOnTouched(fn: () => void): void {\n this.onTouchedCallback = fn;\n }\n\n public setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n // ************* End of ControlValueAccessor Implementation **************\n\n protected onChangeCallback = (_a: unknown): void => undefined;\n protected onTouchedCallback = (): void => undefined;\n}\n","<!-- Hours -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"hours\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [style.display]=\"mode === 'minutesOnly' ? 'none' : 'block'\">\n <input\n #hours\n matInput\n type=\"text\"\n [ngModel]=\"hoursValue | number: '2.'\"\n (change)=\"onHoursChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'hours')\"\n [disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderHours\"\n (click)=\"onClick('hours')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('hours')\"\n (decrement)=\"decrementValue('hours')\"></ngx-numeric-stepper>\n</mat-form-field>\n\n<!-- Separator -->\n<span class=\"time-separator\" [style.display]=\"mode === 'minutesOnly' || mode === 'hoursOnly' ? 'none' : 'block'\">\n :\n</span>\n\n<!-- Minutes -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"minutes\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [style.display]=\"mode === 'hoursOnly' ? 'none' : 'block'\">\n <input\n #minutes\n matInput\n type=\"text\"\n [ngModel]=\"minutesValue | number: '2.'\"\n (change)=\"onMinutesChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'minutes')\"\n [disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderMinutes\"\n (click)=\"onClick('minutes')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('minutes')\"\n (decrement)=\"decrementValue('minutes')\"></ngx-numeric-stepper>\n</mat-form-field>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,53 +1,50 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"angular",
|
|
18
|
-
"material",
|
|
19
|
-
"material design",
|
|
20
|
-
"components"
|
|
21
|
-
],
|
|
22
|
-
"sideEffects": false,
|
|
23
|
-
"peerDependencies": {
|
|
24
|
-
"@angular/common": ">=18 <19",
|
|
25
|
-
"@angular/core": ">=18 <19",
|
|
26
|
-
"@angular/cdk": ">=18 <19",
|
|
27
|
-
"@angular/forms": ">=18 <19",
|
|
28
|
-
"@angular/material": ">=18 <19",
|
|
29
|
-
"rxjs": ">= 7.4.0",
|
|
30
|
-
"date-fns": "^2.30.0",
|
|
31
|
-
"@hug/ngx-core": "^2.0.0",
|
|
32
|
-
"@hug/ngx-numeric-stepper": "^2.0.0"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"tslib": "^2.7.0"
|
|
36
|
-
},
|
|
37
|
-
"publishConfig": {
|
|
38
|
-
"access": "public"
|
|
39
|
-
},
|
|
40
|
-
"module": "fesm2022/hug-ngx-time-picker.mjs",
|
|
41
|
-
"typings": "index.d.ts",
|
|
42
|
-
"exports": {
|
|
43
|
-
"./package.json": {
|
|
44
|
-
"default": "./package.json"
|
|
2
|
+
"name": "@hug/ngx-time-picker",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "HUG Angular - time picker component",
|
|
5
|
+
"homepage": "https://github.com/dsi-hug/ngx-components",
|
|
6
|
+
"license": "GPL-3.0-only",
|
|
7
|
+
"author": "HUG - Hôpitaux Universitaires Genève",
|
|
8
|
+
"contributors": [
|
|
9
|
+
"badisi (https://github.com/badisi)",
|
|
10
|
+
"vapkse (https://github.com/vapkse)"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/dsi-hug/ngx-components.git"
|
|
45
15
|
},
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
16
|
+
"keywords": [
|
|
17
|
+
"angular",
|
|
18
|
+
"material",
|
|
19
|
+
"material design",
|
|
20
|
+
"components"
|
|
21
|
+
],
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@angular/common": ">=19 <20",
|
|
25
|
+
"@angular/core": ">=19 <20",
|
|
26
|
+
"@angular/cdk": ">=19 <20",
|
|
27
|
+
"@angular/forms": ">=19 <20",
|
|
28
|
+
"@angular/material": ">=19 <20",
|
|
29
|
+
"rxjs": ">= 7.4.0",
|
|
30
|
+
"date-fns": "^2.30.0",
|
|
31
|
+
"@hug/ngx-numeric-stepper": "^3.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"tslib": "^2.7.0"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"module": "fesm2022/hug-ngx-time-picker.mjs",
|
|
40
|
+
"typings": "index.d.ts",
|
|
41
|
+
"exports": {
|
|
42
|
+
"./package.json": {
|
|
43
|
+
"default": "./package.json"
|
|
44
|
+
},
|
|
45
|
+
".": {
|
|
46
|
+
"types": "./index.d.ts",
|
|
47
|
+
"default": "./fesm2022/hug-ngx-time-picker.mjs"
|
|
48
|
+
}
|
|
51
49
|
}
|
|
52
|
-
}
|
|
53
50
|
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generated bundle index. Do not edit.
|
|
3
|
-
*/
|
|
4
|
-
export * from './index';
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHVnLW5neC10aW1lLXBpY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3RpbWUtcGlja2VyL3NyYy9odWctbmd4LXRpbWUtcGlja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
|
package/esm2022/index.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
export * from './time-picker.component';
|
|
2
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy90aW1lLXBpY2tlci9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx5QkFBeUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vdGltZS1waWNrZXIuY29tcG9uZW50JztcbiJdfQ==
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
|
|
2
|
-
import { DecimalPipe } from '@angular/common';
|
|
3
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, EventEmitter, inject, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
4
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
-
import { FormsModule, NgControl } from '@angular/forms';
|
|
6
|
-
import { MatFormField } from '@angular/material/form-field';
|
|
7
|
-
import { MatInput } from '@angular/material/input';
|
|
8
|
-
import { NgxNumericStepperComponent } from '@hug/ngx-numeric-stepper';
|
|
9
|
-
import { isSameHour, set } from 'date-fns';
|
|
10
|
-
import { debounce, distinctUntilChanged, map, Subject, timer } from 'rxjs';
|
|
11
|
-
import * as i0 from "@angular/core";
|
|
12
|
-
import * as i1 from "@angular/forms";
|
|
13
|
-
// TODO sdil refactor rxjs flows
|
|
14
|
-
export class NgxTimePickerComponent {
|
|
15
|
-
hours;
|
|
16
|
-
minutes;
|
|
17
|
-
timeChange = new EventEmitter();
|
|
18
|
-
/** Display mode for the time-picker */
|
|
19
|
-
mode = 'fullTime';
|
|
20
|
-
/** Data type to manage (Date or Duration) */
|
|
21
|
-
dataType = 'date';
|
|
22
|
-
/**
|
|
23
|
-
* Force the hour or minute to be null (only if the other field is disabled)
|
|
24
|
-
*
|
|
25
|
-
* For instance, if set to true and the hours are disabled, the minutes input value will be null
|
|
26
|
-
* This is useful to force the user to provide a value
|
|
27
|
-
*/
|
|
28
|
-
forceNullValue = false;
|
|
29
|
-
appearance = 'outline';
|
|
30
|
-
set autoFocus(value) {
|
|
31
|
-
this._autoFocus = coerceBooleanProperty(value);
|
|
32
|
-
}
|
|
33
|
-
defaultPlaceholderHours = '_ _';
|
|
34
|
-
defaultPlaceholderMinutes = '_ _';
|
|
35
|
-
set time(value) {
|
|
36
|
-
this.writeValue(value);
|
|
37
|
-
}
|
|
38
|
-
get time() {
|
|
39
|
-
return this.value;
|
|
40
|
-
}
|
|
41
|
-
/** Step of the arrows */
|
|
42
|
-
set step(value) {
|
|
43
|
-
this._step = coerceNumberProperty(value);
|
|
44
|
-
this.changeDetectorRef.markForCheck();
|
|
45
|
-
}
|
|
46
|
-
/** To get the step of the minutes arrows */
|
|
47
|
-
get step() {
|
|
48
|
-
return this._step;
|
|
49
|
-
}
|
|
50
|
-
/** Disabled property setter. Can be string or empty so you can use it like : <time-picker disabled></time-picker> */
|
|
51
|
-
set disabled(value) {
|
|
52
|
-
this._disabled = coerceBooleanProperty(value);
|
|
53
|
-
this.changeDetectorRef.markForCheck();
|
|
54
|
-
}
|
|
55
|
-
/** To get disabled attribute. */
|
|
56
|
-
get disabled() {
|
|
57
|
-
return this._disabled;
|
|
58
|
-
}
|
|
59
|
-
onHoursChange$ = new Subject();
|
|
60
|
-
onMinutesChange$ = new Subject();
|
|
61
|
-
_step = 1;
|
|
62
|
-
changeDetectorRef = inject(ChangeDetectorRef);
|
|
63
|
-
control = inject(NgControl, { optional: true, self: true });
|
|
64
|
-
destroyRef = inject(DestroyRef);
|
|
65
|
-
_disabled = false;
|
|
66
|
-
_value;
|
|
67
|
-
_autoFocus = true;
|
|
68
|
-
constructor() {
|
|
69
|
-
if (this.control) {
|
|
70
|
-
this.control.valueAccessor = this;
|
|
71
|
-
}
|
|
72
|
-
this.onHoursChange$.pipe(debounce(hours => timer(typeof hours === 'object' ? 0 : 10)), distinctUntilChanged(), map(hours => {
|
|
73
|
-
if (typeof hours === 'object') {
|
|
74
|
-
const value = hours.target.value;
|
|
75
|
-
return [value !== undefined ? parseInt(value, 10) : undefined, true];
|
|
76
|
-
}
|
|
77
|
-
return [!isNaN(hours) ? hours : 0, false];
|
|
78
|
-
}), takeUntilDestroyed(this.destroyRef)).subscribe(([hours, isEvent]) => {
|
|
79
|
-
if (!this.value) {
|
|
80
|
-
this.value = this.dataType === 'date' ? set(new Date(), { hours, minutes: 0, seconds: 0, milliseconds: 0 }) : { hours, minutes: 0 };
|
|
81
|
-
}
|
|
82
|
-
else if (this.value instanceof Date) {
|
|
83
|
-
const value = this.value?.getTime();
|
|
84
|
-
const clone = new Date(value);
|
|
85
|
-
if (hours !== undefined) {
|
|
86
|
-
clone.setHours(hours);
|
|
87
|
-
}
|
|
88
|
-
this.value = clone;
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
this.value = {
|
|
92
|
-
hours: hours && hours < 0 ? 0 : hours,
|
|
93
|
-
minutes: this.value.minutes
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
this.changeDetectorRef.markForCheck();
|
|
97
|
-
if (isEvent && this._autoFocus && this.minutes) {
|
|
98
|
-
this.minutes.nativeElement.focus({
|
|
99
|
-
preventScroll: true
|
|
100
|
-
});
|
|
101
|
-
this.minutes.nativeElement.select();
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
this.onMinutesChange$.pipe(debounce(minutes => timer(typeof minutes === 'object' ? 0 : 10)), distinctUntilChanged(), map(event => {
|
|
105
|
-
let minutes;
|
|
106
|
-
if (typeof event === 'object') {
|
|
107
|
-
const value = event.target.value;
|
|
108
|
-
minutes = value !== undefined ? parseInt(value, 10) : undefined;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
minutes = event;
|
|
112
|
-
}
|
|
113
|
-
return minutes && !isNaN(minutes) && minutes || 0;
|
|
114
|
-
}), takeUntilDestroyed(this.destroyRef)).subscribe(minutes => {
|
|
115
|
-
if (!this.value) {
|
|
116
|
-
this.value = this.dataType === 'date' ? set(new Date(), { hours: 0, minutes, seconds: 0, milliseconds: 0 }) : { hours: 0, minutes };
|
|
117
|
-
}
|
|
118
|
-
else if (this.value instanceof Date) {
|
|
119
|
-
const newValue = new Date(this.value.getTime());
|
|
120
|
-
if (minutes < 0) {
|
|
121
|
-
minutes += 60;
|
|
122
|
-
}
|
|
123
|
-
else if (minutes >= 60) {
|
|
124
|
-
minutes -= 60;
|
|
125
|
-
}
|
|
126
|
-
newValue.setMinutes(minutes);
|
|
127
|
-
if (this.mode !== 'fullTimeWithHoursDisabled' || (this.mode === 'fullTimeWithHoursDisabled' && isSameHour(this.value, newValue))) {
|
|
128
|
-
this.value = newValue;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
this.value = {
|
|
133
|
-
hours: this.value.hours,
|
|
134
|
-
minutes: minutes < 0 || minutes >= 60 ? 0 : minutes
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
this.changeDetectorRef.markForCheck();
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
onKeyDown($event, mode) {
|
|
141
|
-
// Get input element
|
|
142
|
-
const inputElement = mode === 'hours' ? this.hours?.nativeElement : this.minutes?.nativeElement;
|
|
143
|
-
if ($event.key?.toLowerCase() === 'd') {
|
|
144
|
-
$event.stopPropagation();
|
|
145
|
-
$event.preventDefault();
|
|
146
|
-
this.value = new Date();
|
|
147
|
-
}
|
|
148
|
-
else if (inputElement) {
|
|
149
|
-
if ($event.key?.toLowerCase() === 'a' && $event.ctrlKey) {
|
|
150
|
-
inputElement.select();
|
|
151
|
-
}
|
|
152
|
-
else if ($event.key && !['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Backspace', 'Delete', 'Tab', 'Enter', 'Control', 'Shift'].includes($event.key)) {
|
|
153
|
-
// Set regex for input format validation (differs if we are dealing with a date or a duration)
|
|
154
|
-
let regex;
|
|
155
|
-
if (mode === 'hours') {
|
|
156
|
-
regex = this.dataType === 'date' ? /^(\d|[01]\d|2[0-3])$/ : /^(\d+)$/;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
regex = /^(\d|[0-5]\d)$/;
|
|
160
|
-
}
|
|
161
|
-
// Get the selection in input element
|
|
162
|
-
const [selectionStart, selectionEnd] = [inputElement.selectionStart || 0, inputElement.selectionEnd || 0].sort((a, b) => a - b);
|
|
163
|
-
const selectionDiff = selectionEnd - selectionStart;
|
|
164
|
-
// Get the current value in input element and update it with the new touched key
|
|
165
|
-
const inputValue = inputElement.value || '';
|
|
166
|
-
const inputValueArr = Array.from(inputValue);
|
|
167
|
-
inputValueArr.splice(selectionStart, selectionDiff, $event.key);
|
|
168
|
-
const newInputValue = inputValueArr.join('');
|
|
169
|
-
// Prevent event if the time is not valid
|
|
170
|
-
if (!regex.test(newInputValue)) {
|
|
171
|
-
$event.stopPropagation();
|
|
172
|
-
$event.preventDefault();
|
|
173
|
-
}
|
|
174
|
-
else if (this._autoFocus && mode === 'hours' && ((this.dataType === 'date' && parseFloat(newInputValue) >= 3) || newInputValue.length === 2)) {
|
|
175
|
-
this.onHoursChange$.next($event);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
get hoursValue() {
|
|
181
|
-
if (!this.value || (this.forceNullValue && this.mode === 'fullTimeWithMinutesDisabled' && !!this.control?.pristine)) {
|
|
182
|
-
return undefined;
|
|
183
|
-
}
|
|
184
|
-
return this.value instanceof Date ? this.value.getHours() : this.value.hours;
|
|
185
|
-
}
|
|
186
|
-
get minutesValue() {
|
|
187
|
-
if (!this.value || (this.forceNullValue && this.mode === 'fullTimeWithHoursDisabled' && !!this.control?.pristine)) {
|
|
188
|
-
return undefined;
|
|
189
|
-
}
|
|
190
|
-
return this.value instanceof Date ? this.value.getMinutes() : this.value.minutes;
|
|
191
|
-
}
|
|
192
|
-
incrementValue(fieldType) {
|
|
193
|
-
if (fieldType === 'hours') {
|
|
194
|
-
this.onHoursChange$.next((this.hoursValue || 0) + 1);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
this.onMinutesChange$.next((this.minutesValue || 0) + this._step);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
decrementValue(fieldType) {
|
|
201
|
-
if (fieldType === 'hours') {
|
|
202
|
-
this.onHoursChange$.next((this.hoursValue || 0) - 1);
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
this.onMinutesChange$.next((this.minutesValue || 0) - this._step);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
onClick(mode) {
|
|
209
|
-
if (this._autoFocus) {
|
|
210
|
-
if (mode === 'hours') {
|
|
211
|
-
this.hours?.nativeElement.select();
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
this.minutes?.nativeElement.select();
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
// ************* ControlValueAccessor Implementation **************
|
|
219
|
-
/** set accessor including call the onchange callback */
|
|
220
|
-
set value(v) {
|
|
221
|
-
if (v !== this._value) {
|
|
222
|
-
this.writeValue(v);
|
|
223
|
-
this.onChangeCallback(v);
|
|
224
|
-
this.timeChange.emit(v);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
/** get accessor */
|
|
228
|
-
get value() {
|
|
229
|
-
return this._value;
|
|
230
|
-
}
|
|
231
|
-
/** From ControlValueAccessor interface */
|
|
232
|
-
writeValue(value) {
|
|
233
|
-
if ((value ?? null) !== (this._value ?? null)) {
|
|
234
|
-
if (value instanceof Date) {
|
|
235
|
-
this._value = value ? new Date(value.getTime()) : set(new Date(), { hours: 0, minutes: 0, seconds: 0 });
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
this._value = value;
|
|
239
|
-
}
|
|
240
|
-
this.changeDetectorRef.markForCheck();
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
/** From ControlValueAccessor interface */
|
|
244
|
-
registerOnChange(fn) {
|
|
245
|
-
this.onChangeCallback = fn;
|
|
246
|
-
}
|
|
247
|
-
/** From ControlValueAccessor interface */
|
|
248
|
-
registerOnTouched(fn) {
|
|
249
|
-
this.onTouchedCallback = fn;
|
|
250
|
-
}
|
|
251
|
-
setDisabledState(isDisabled) {
|
|
252
|
-
this.disabled = isDisabled;
|
|
253
|
-
}
|
|
254
|
-
// ************* End of ControlValueAccessor Implementation **************
|
|
255
|
-
onChangeCallback = (_a) => undefined;
|
|
256
|
-
onTouchedCallback = () => undefined;
|
|
257
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: NgxTimePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
258
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: NgxTimePickerComponent, isStandalone: true, selector: "ngx-time-picker", inputs: { mode: "mode", dataType: "dataType", forceNullValue: "forceNullValue", appearance: "appearance", autoFocus: "autoFocus", defaultPlaceholderHours: "defaultPlaceholderHours", defaultPlaceholderMinutes: "defaultPlaceholderMinutes", time: "time", step: "step", disabled: "disabled" }, outputs: { timeChange: "timeChange" }, viewQueries: [{ propertyName: "hours", first: true, predicate: ["hours"], descendants: true }, { propertyName: "minutes", first: true, predicate: ["minutes"], descendants: true }], ngImport: i0, template: "<!-- Hours -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"hours\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [style.display]=\"mode === 'minutesOnly' ? 'none' : 'block'\">\n <input\n #hours\n matInput\n type=\"text\"\n [ngModel]=\"hoursValue | number: '2.'\"\n (change)=\"onHoursChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'hours')\"\n [disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderHours\"\n (click)=\"onClick('hours')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('hours')\"\n (decrement)=\"decrementValue('hours')\"></ngx-numeric-stepper>\n</mat-form-field>\n\n<!-- Separator -->\n<span class=\"time-separator\" [style.display]=\"mode === 'minutesOnly' || mode === 'hoursOnly' ? 'none' : 'block'\">\n :\n</span>\n\n<!-- Minutes -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"minutes\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [style.display]=\"mode === 'hoursOnly' ? 'none' : 'block'\">\n <input\n #minutes\n matInput\n type=\"text\"\n [ngModel]=\"minutesValue | number: '2.'\"\n (change)=\"onMinutesChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'minutes')\"\n [disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderMinutes\"\n (click)=\"onClick('minutes')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('minutes')\"\n (decrement)=\"decrementValue('minutes')\"></ngx-numeric-stepper>\n</mat-form-field>\n", styles: ["ngx-time-picker{display:flex;flex-direction:row;align-items:baseline;justify-content:center}ngx-time-picker:not([inform]) .mat-form-field-appearance-outline .mat-mdc-form-field-wrapper{padding-bottom:0}ngx-time-picker:not([inform]) .mat-form-field-appearance-outline .mat-mdc-form-field-wrapper .mat-mdc-form-field-infix{border-bottom:.7em solid transparent}ngx-time-picker mat-form-field[ngx-numeric-stepper-form-field]{width:52px}ngx-time-picker .time-separator{width:4px;font-size:14.5px;line-height:17px;margin:0 8px}\n"], dependencies: [{ kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: NgxNumericStepperComponent, selector: "ngx-numeric-stepper", inputs: ["layout", "input", "arrowIcons", "showOnInit"], outputs: ["increment", "decrement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
259
|
-
}
|
|
260
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: NgxTimePickerComponent, decorators: [{
|
|
261
|
-
type: Component,
|
|
262
|
-
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngx-time-picker', encapsulation: ViewEncapsulation.None, standalone: true, imports: [
|
|
263
|
-
DecimalPipe,
|
|
264
|
-
FormsModule,
|
|
265
|
-
MatFormField,
|
|
266
|
-
MatInput,
|
|
267
|
-
NgxNumericStepperComponent
|
|
268
|
-
], template: "<!-- Hours -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"hours\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [style.display]=\"mode === 'minutesOnly' ? 'none' : 'block'\">\n <input\n #hours\n matInput\n type=\"text\"\n [ngModel]=\"hoursValue | number: '2.'\"\n (change)=\"onHoursChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'hours')\"\n [disabled]=\"disabled || mode === 'fullTimeWithHoursDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderHours\"\n (click)=\"onClick('hours')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('hours')\"\n (decrement)=\"decrementValue('hours')\"></ngx-numeric-stepper>\n</mat-form-field>\n\n<!-- Separator -->\n<span class=\"time-separator\" [style.display]=\"mode === 'minutesOnly' || mode === 'hoursOnly' ? 'none' : 'block'\">\n :\n</span>\n\n<!-- Minutes -->\n<mat-form-field\n [appearance]=\"appearance\"\n class=\"minutes\"\n [class.disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [style.display]=\"mode === 'hoursOnly' ? 'none' : 'block'\">\n <input\n #minutes\n matInput\n type=\"text\"\n [ngModel]=\"minutesValue | number: '2.'\"\n (change)=\"onMinutesChange$.next($event)\"\n (keydown)=\"onKeyDown($event, 'minutes')\"\n [disabled]=\"disabled || mode === 'fullTimeWithMinutesDisabled'\"\n [maxLength]=\"2\"\n autocomplete=\"off\"\n [placeholder]=\"defaultPlaceholderMinutes\"\n (click)=\"onClick('minutes')\" />\n <ngx-numeric-stepper\n (increment)=\"incrementValue('minutes')\"\n (decrement)=\"decrementValue('minutes')\"></ngx-numeric-stepper>\n</mat-form-field>\n", styles: ["ngx-time-picker{display:flex;flex-direction:row;align-items:baseline;justify-content:center}ngx-time-picker:not([inform]) .mat-form-field-appearance-outline .mat-mdc-form-field-wrapper{padding-bottom:0}ngx-time-picker:not([inform]) .mat-form-field-appearance-outline .mat-mdc-form-field-wrapper .mat-mdc-form-field-infix{border-bottom:.7em solid transparent}ngx-time-picker mat-form-field[ngx-numeric-stepper-form-field]{width:52px}ngx-time-picker .time-separator{width:4px;font-size:14.5px;line-height:17px;margin:0 8px}\n"] }]
|
|
269
|
-
}], ctorParameters: () => [], propDecorators: { hours: [{
|
|
270
|
-
type: ViewChild,
|
|
271
|
-
args: ['hours']
|
|
272
|
-
}], minutes: [{
|
|
273
|
-
type: ViewChild,
|
|
274
|
-
args: ['minutes']
|
|
275
|
-
}], timeChange: [{
|
|
276
|
-
type: Output
|
|
277
|
-
}], mode: [{
|
|
278
|
-
type: Input
|
|
279
|
-
}], dataType: [{
|
|
280
|
-
type: Input
|
|
281
|
-
}], forceNullValue: [{
|
|
282
|
-
type: Input
|
|
283
|
-
}], appearance: [{
|
|
284
|
-
type: Input
|
|
285
|
-
}], autoFocus: [{
|
|
286
|
-
type: Input
|
|
287
|
-
}], defaultPlaceholderHours: [{
|
|
288
|
-
type: Input
|
|
289
|
-
}], defaultPlaceholderMinutes: [{
|
|
290
|
-
type: Input
|
|
291
|
-
}], time: [{
|
|
292
|
-
type: Input
|
|
293
|
-
}], step: [{
|
|
294
|
-
type: Input
|
|
295
|
-
}], disabled: [{
|
|
296
|
-
type: Input
|
|
297
|
-
}] } });
|
|
298
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvdGltZS1waWNrZXIvc3JjL3RpbWUtcGlja2VyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3Byb2plY3RzL3RpbWUtcGlja2VyL3NyYy90aW1lLXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWdCLHFCQUFxQixFQUFFLG9CQUFvQixFQUFlLE1BQU0sdUJBQXVCLENBQUM7QUFDL0csT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFjLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakwsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDaEUsT0FBTyxFQUF3QixXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUUsT0FBTyxFQUFFLFlBQVksRUFBMEIsTUFBTSw4QkFBOEIsQ0FBQztBQUNwRixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQzs7O0FBVTNFLGdDQUFnQztBQWdCaEMsTUFBTSxPQUFPLHNCQUFzQjtJQUNKLEtBQUssQ0FBZ0M7SUFDbkMsT0FBTyxDQUFnQztJQUUx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QUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBQ0QsMEVBQTBFO0lBRWhFLGdCQUFnQixHQUFHLENBQUMsRUFBVyxFQUFRLEVBQUUsQ0FBQyxTQUFTLENBQUM7SUFDcEQsaUJBQWlCLEdBQUcsR0FBUyxFQUFFLENBQUMsU0FBUyxDQUFDO3VHQXhSM0Msc0JBQXNCOzJGQUF0QixzQkFBc0IseWtCQ25DbkMsK3pEQWtEQSxna0JEdEJRLFdBQVcsOENBQ1gsV0FBVywrbUJBQ1gsWUFBWSw0TEFDWixRQUFRLGlVQUNSLDBCQUEwQjs7MkZBR3JCLHNCQUFzQjtrQkFmbEMsU0FBUztzQ0FDVyx1QkFBdUIsQ0FBQyxNQUFNLFlBQ3JDLGlCQUFpQixpQkFHWixpQkFBaUIsQ0FBQyxJQUFJLGNBQ3pCLElBQUksV0FDUDt3QkFDTCxXQUFXO3dCQUNYLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixRQUFRO3dCQUNSLDBCQUEwQjtxQkFDN0I7d0RBRzBCLEtBQUs7c0JBQS9CLFNBQVM7dUJBQUMsT0FBTztnQkFDVyxPQUFPO3NCQUFuQyxTQUFTO3VCQUFDLFNBQVM7Z0JBRU0sVUFBVTtzQkFBbkMsTUFBTTtnQkFHUyxJQUFJO3NCQUFuQixLQUFLO2dCQUdVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBUVUsY0FBYztzQkFBN0IsS0FBSztnQkFFVSxVQUFVO3NCQUF6QixLQUFLO2dCQUdLLFNBQVM7c0JBRG5CLEtBQUs7Z0JBS1UsdUJBQXVCO3NCQUF0QyxLQUFLO2dCQUNVLHlCQUF5QjtzQkFBeEMsS0FBSztnQkFHSyxJQUFJO3NCQURkLEtBQUs7Z0JBV0ssSUFBSTtzQkFEZCxLQUFLO2dCQWFLLFFBQVE7c0JBRGxCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCb29sZWFuSW5wdXQsIGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSwgY29lcmNlTnVtYmVyUHJvcGVydHksIE51bWJlcklucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7IERlY2ltYWxQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIGluamVjdCwgSW5wdXQsIE91dHB1dCwgVmlld0NoaWxkLCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1zTW9kdWxlLCBOZ0NvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGQsIE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgTmd4TnVtZXJpY1N0ZXBwZXJDb21wb25lbnQgfSBmcm9tICdAaHVnL25neC1udW1lcmljLXN0ZXBwZXInO1xuaW1wb3J0IHsgaXNTYW1lSG91ciwgc2V0IH0gZnJvbSAnZGF0ZS1mbnMnO1xuaW1wb3J0IHsgZGVib3VuY2UsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIFN1YmplY3QsIHRpbWVyIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCB0eXBlIE5neFRpbWVQaWNrZXJEaXNwbGF5TW9kZSA9ICdmdWxsVGltZScgfCAnZnVsbFRpbWVXaXRoSG91cnNEaXNhYmxlZCcgfCAnZnVsbFRpbWVXaXRoTWludXRlc0Rpc2FibGVkJyB8ICdob3Vyc09ubHknIHwgJ21pbnV0ZXNPbmx5JztcblxuZXhwb3J0IHR5cGUgTmd4RGF0ZU9yRHVyYXRpb24gPSBEYXRlIHwgRHVyYXRpb247XG5cbnR5cGUgRGF0YVR5cGUgPSAnZGF0ZScgfCAnZHVyYXRpb24nO1xuXG50eXBlIEZpZWxkVHlwZSA9ICdob3VycycgfCAnbWludXRlcyc7XG5cbi8vIFRPRE8gc2RpbCByZWZhY3RvciByeGpzIGZsb3dzXG5AQ29tcG9uZW50KHtcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBzZWxlY3RvcjogJ25neC10aW1lLXBpY2tlcicsXG4gICAgc3R5bGVVcmxzOiBbJy4vdGltZS1waWNrZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdGltZS1waWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIERlY2ltYWxQaXBlLFxuICAgICAgICBGb3Jtc01vZHVsZSxcbiAgICAgICAgTWF0Rm9ybUZpZWxkLFxuICAgICAgICBNYXRJbnB1dCxcbiAgICAgICAgTmd4TnVtZXJpY1N0ZXBwZXJDb21wb25lbnRcbiAgICBdXG59KVxuZXhwb3J0IGNsYXNzIE5neFRpbWVQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG4gICAgQFZpZXdDaGlsZCgnaG91cnMnKSBwdWJsaWMgaG91cnM/OiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuICAgIEBWaWV3Q2hpbGQoJ21pbnV0ZXMnKSBwdWJsaWMgbWludXRlcz86IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD47XG5cbiAgICBAT3V0cHV0KCkgcHVibGljIHJlYWRvbmx5IHRpbWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE5neERhdGVPckR1cmF0aW9uPigpO1xuXG4gICAgLyoqIERpc3BsYXkgbW9kZSBmb3IgdGhlIHRpbWUtcGlja2VyICovXG4gICAgQElucHV0KCkgcHVibGljIG1vZGU6IE5neFRpbWVQaWNrZXJEaXNwbGF5TW9kZSA9ICdmdWxsVGltZSc7XG5cbiAgICAvKiogRGF0YSB0eXBlIHRvIG1hbmFnZSAoRGF0ZSBvciBEdXJhdGlvbikgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgZGF0YVR5cGU6IERhdGFUeXBlID0gJ2RhdGUnO1xuXG4gICAgLyoqXG4gICAgICogRm9yY2UgdGhlIGhvdXIgb3IgbWludXRlIHRvIGJlIG51bGwgKG9ubHkgaWYgdGhlIG90aGVyIGZpZWxkIGlzIGRpc2FibGVkKVxuICAgICAqXG4gICAgICogRm9yIGluc3RhbmNlLCBpZiBzZXQgdG8gdHJ1ZSBhbmQgdGhlIGhvdXJzIGFyZSBkaXNhYmxlZCwgdGhlIG1pbnV0ZXMgaW5wdXQgdmFsdWUgd2lsbCBiZSBudWxsXG4gICAgICogVGhpcyBpcyB1c2VmdWwgdG8gZm9yY2UgdGhlIHVzZXIgdG8gcHJvdmlkZSBhIHZhbHVlXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGZvcmNlTnVsbFZhbHVlID0gZmFsc2U7XG5cbiAgICBASW5wdXQoKSBwdWJsaWMgYXBwZWFyYW5jZTogTWF0Rm9ybUZpZWxkQXBwZWFyYW5jZSA9ICdvdXRsaW5lJztcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBhdXRvRm9jdXModmFsdWU6IEJvb2xlYW5JbnB1dCkge1xuICAgICAgICB0aGlzLl9hdXRvRm9jdXMgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICAgIH1cblxuICAgIEBJbnB1dCgpIHB1YmxpYyBkZWZhdWx0UGxhY2Vob2xkZXJIb3VycyA9ICdfIF8nO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBkZWZhdWx0UGxhY2Vob2xkZXJNaW51dGVzID0gJ18gXyc7XG5cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgdGltZSh2YWx1ZTogTmd4RGF0ZU9yRHVyYXRpb24gfCB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHRpbWUoKTogTmd4RGF0ZU9yRHVyYXRpb24gfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICAvKiogU3RlcCBvZiB0aGUgYXJyb3dzICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgc2V0IHN0ZXAodmFsdWU6IE51bWJlcklucHV0KSB7XG4gICAgICAgIHRoaXMuX3N0ZXAgPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2YWx1ZSk7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgLyoqIFRvIGdldCB0aGUgc3RlcCBvZiB0aGUgbWludXRlcyBhcnJvd3MgKi9cbiAgICBwdWJsaWMgZ2V0IHN0ZXAoKTogTnVtYmVySW5wdXQge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RlcDtcbiAgICB9XG5cbiAgICAvKiogRGlzYWJsZWQgcHJvcGVydHkgc2V0dGVyLiBDYW4gYmUgc3RyaW5nIG9yIGVtcHR5IHNvIHlvdSBjYW4gdXNlIGl0IGxpa2UgOiA8dGltZS1waWNrZXIgZGlzYWJsZWQ+PC90aW1lLXBpY2tlcj4gKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgZGlzYWJsZWQodmFsdWU6IEJvb2xlYW5JbnB1dCkge1xuICAgICAgICB0aGlzLl9kaXNhYmxlZCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgLyoqIFRvIGdldCBkaXNhYmxlZCBhdHRyaWJ1dGUuICovXG4gICAgcHVibGljIGdldCBkaXNhYmxlZCgpOiBCb29sZWFuSW5wdXQge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGlzYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIG9uSG91cnNDaGFuZ2UkID0gbmV3IFN1YmplY3Q8RXZlbnQgfCBudW1iZXI+KCk7XG4gICAgcHVibGljIG9uTWludXRlc0NoYW5nZSQgPSBuZXcgU3ViamVjdDxFdmVudCB8IG51bWJlcj4oKTtcbiAgICBwdWJsaWMgX3N0ZXAgPSAxO1xuXG4gICAgcHJvdGVjdGVkIGNoYW5nZURldGVjdG9yUmVmID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgICBwcm90ZWN0ZWQgY29udHJvbCA9IGluamVjdChOZ0NvbnRyb2wsIHsgb3B0aW9uYWw6IHRydWUsIHNlbGY6IHRydWUgfSk7XG4gICAgcHJpdmF0ZSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gICAgcHJpdmF0ZSBfZGlzYWJsZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIF92YWx1ZT86IE5neERhdGVPckR1cmF0aW9uO1xuICAgIHByaXZhdGUgX2F1dG9Gb2N1cyA9IHRydWU7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRyb2wpIHtcbiAgICAgICAgICAgIHRoaXMuY29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub25Ib3Vyc0NoYW5nZSQucGlwZShcbiAgICAgICAgICAgIGRlYm91bmNlKGhvdXJzID0+IHRpbWVyKHR5cGVvZiBob3VycyA9PT0gJ29iamVjdCcgPyAwIDogMTApKSxcbiAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgICAgICBtYXAoaG91cnMgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaG91cnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gKGhvdXJzLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFt2YWx1ZSAhPT0gdW5kZWZpbmVkID8gcGFyc2VJbnQodmFsdWUsIDEwKSA6IHVuZGVmaW5lZCwgdHJ1ZV0gYXMgY29uc3Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBbIWlzTmFOKGhvdXJzKSA/IGhvdXJzIDogMCwgZmFsc2VdIGFzIGNvbnN0O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgICApLnN1YnNjcmliZSgoW2hvdXJzLCBpc0V2ZW50XSkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuZGF0YVR5cGUgPT09ICdkYXRlJyA/IHNldChuZXcgRGF0ZSgpLCB7IGhvdXJzLCBtaW51dGVzOiAwLCBzZWNvbmRzOiAwLCBtaWxsaXNlY29uZHM6IDAgfSkgOiB7IGhvdXJzLCBtaW51dGVzOiAwIH0gYXMgRHVyYXRpb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnZhbHVlPy5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgY2xvbmUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKGhvdXJzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xvbmUuc2V0SG91cnMoaG91cnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gY2xvbmU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB7XG4gICAgICAgICAgICAgICAgICAgIGhvdXJzOiBob3VycyAmJiBob3VycyA8IDAgPyAwIDogaG91cnMsXG4gICAgICAgICAgICAgICAgICAgIG1pbnV0ZXM6IHRoaXMudmFsdWUubWludXRlc1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICAgICAgICBpZiAoaXNFdmVudCAmJiB0aGlzLl9hdXRvRm9jdXMgJiYgdGhpcy5taW51dGVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5taW51dGVzLm5hdGl2ZUVsZW1lbnQuZm9jdXMoe1xuICAgICAgICAgICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5taW51dGVzLm5hdGl2ZUVsZW1lbnQuc2VsZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMub25NaW51dGVzQ2hhbmdlJC5waXBlKFxuICAgICAgICAgICAgZGVib3VuY2UobWludXRlcyA9PiB0aW1lcih0eXBlb2YgbWludXRlcyA9PT0gJ29iamVjdCcgPyAwIDogMTApKSxcbiAgICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgICAgICBtYXAoZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBtaW51dGVzOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBldmVudCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBtaW51dGVzID0gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHBhcnNlSW50KHZhbHVlLCAxMCkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbWludXRlcyA9IGV2ZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWludXRlcyAmJiAhaXNOYU4obWludXRlcykgJiYgbWludXRlcyB8fCAwO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgICApLnN1YnNjcmliZShtaW51dGVzID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy52YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmRhdGFUeXBlID09PSAnZGF0ZScgPyBzZXQobmV3IERhdGUoKSwgeyBob3VyczogMCwgbWludXRlcywgc2Vjb25kczogMCwgbWlsbGlzZWNvbmRzOiAwIH0pIDogeyBob3VyczogMCwgbWludXRlcyB9IGFzIER1cmF0aW9uO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gbmV3IERhdGUodGhpcy52YWx1ZS5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgICAgIGlmIChtaW51dGVzIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBtaW51dGVzICs9IDYwO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWludXRlcyA+PSA2MCkge1xuICAgICAgICAgICAgICAgICAgICBtaW51dGVzIC09IDYwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuZXdWYWx1ZS5zZXRNaW51dGVzKG1pbnV0ZXMpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubW9kZSAhPT0gJ2Z1bGxUaW1lV2l0aEhvdXJzRGlzYWJsZWQnIHx8ICh0aGlzLm1vZGUgPT09ICdmdWxsVGltZVdpdGhIb3Vyc0Rpc2FibGVkJyAmJiBpc1NhbWVIb3VyKHRoaXMudmFsdWUsIG5ld1ZhbHVlKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgaG91cnM6IHRoaXMudmFsdWUuaG91cnMsXG4gICAgICAgICAgICAgICAgICAgIG1pbnV0ZXM6IG1pbnV0ZXMgPCAwIHx8IG1pbnV0ZXMgPj0gNjAgPyAwIDogbWludXRlc1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25LZXlEb3duKCRldmVudDogS2V5Ym9hcmRFdmVudCwgbW9kZTogJ2hvdXJzJyB8ICdtaW51dGVzJyk6IHZvaWQge1xuICAgICAgICAvLyBHZXQgaW5wdXQgZWxlbWVudFxuICAgICAgICBjb25zdCBpbnB1dEVsZW1lbnQgPSBtb2RlID09PSAnaG91cnMnID8gdGhpcy5ob3Vycz8ubmF0aXZlRWxlbWVudCA6IHRoaXMubWludXRlcz8ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgaWYgKCRldmVudC5rZXk/LnRvTG93ZXJDYXNlKCkgPT09ICdkJykge1xuICAgICAgICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gbmV3IERhdGUoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnB1dEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmICgkZXZlbnQua2V5Py50b0xvd2VyQ2FzZSgpID09PSAnYScgJiYgJGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEVsZW1lbnQuc2VsZWN0KCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCRldmVudC5rZXkgJiYgIVsnQXJyb3dVcCcsICdBcnJvd0Rvd24nLCAnQXJyb3dMZWZ0JywgJ0Fycm93UmlnaHQnLCAnQmFja3NwYWNlJywgJ0RlbGV0ZScsICdUYWInLCAnRW50ZXInLCAnQ29udHJvbCcsICdTaGlmdCddLmluY2x1ZGVzKCRldmVudC5rZXkpKSB7XG4gICAgICAgICAgICAgICAgLy8gU2V0IHJlZ2V4IGZvciBpbnB1dCBmb3JtYXQgdmFsaWRhdGlvbiAoZGlmZmVycyBpZiB3ZSBhcmUgZGVhbGluZyB3aXRoIGEgZGF0ZSBvciBhIGR1cmF0aW9uKVxuICAgICAgICAgICAgICAgIGxldCByZWdleDtcbiAgICAgICAgICAgICAgICBpZiAobW9kZSA9PT0gJ2hvdXJzJykge1xuICAgICAgICAgICAgICAgICAgICByZWdleCA9IHRoaXMuZGF0YVR5cGUgPT09ICdkYXRlJyA/IC9eKFxcZHxbMDFdXFxkfDJbMC0zXSkkLyA6IC9eKFxcZCspJC87XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVnZXggPSAvXihcXGR8WzAtNV1cXGQpJC87XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBzZWxlY3Rpb24gaW4gaW5wdXQgZWxlbWVudFxuICAgICAgICAgICAgICAgIGNvbnN0IFtzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kXSA9IFtpbnB1dEVsZW1lbnQuc2VsZWN0aW9uU3RhcnQgfHwgMCwgaW5wdXRFbGVtZW50LnNlbGVjdGlvbkVuZCB8fCAwXS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0aW9uRGlmZiA9IHNlbGVjdGlvbkVuZCAtIHNlbGVjdGlvblN0YXJ0O1xuXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBjdXJyZW50IHZhbHVlIGluIGlucHV0IGVsZW1lbnQgYW5kIHVwZGF0ZSBpdCB3aXRoIHRoZSBuZXcgdG91Y2hlZCBrZXlcbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dFZhbHVlID0gaW5wdXRFbGVtZW50LnZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0VmFsdWVBcnIgPSBBcnJheS5mcm9tKGlucHV0VmFsdWUpO1xuICAgICAgICAgICAgICAgIGlucHV0VmFsdWVBcnIuc3BsaWNlKHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25EaWZmLCAkZXZlbnQua2V5KTtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdJbnB1dFZhbHVlID0gaW5wdXRWYWx1ZUFyci5qb2luKCcnKTtcblxuICAgICAgICAgICAgICAgIC8vIFByZXZlbnQgZXZlbnQgaWYgdGhlIHRpbWUgaXMgbm90IHZhbGlkXG4gICAgICAgICAgICAgICAgaWYgKCFyZWdleC50ZXN0KG5ld0lucHV0VmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9hdXRvRm9jdXMgJiYgbW9kZSA9PT0gJ2hvdXJzJyAmJiAoKHRoaXMuZGF0YVR5cGUgPT09ICdkYXRlJyAmJiBwYXJzZUZsb2F0KG5ld0lucHV0VmFsdWUpID49IDMpIHx8IG5ld0lucHV0VmFsdWUubGVuZ3RoID09PSAyKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uSG91cnNDaGFuZ2UkLm5leHQoJGV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGhvdXJzVmFsdWUoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgaWYgKCF0aGlzLnZhbHVlIHx8ICh0aGlzLmZvcmNlTnVsbFZhbHVlICYmIHRoaXMubW9kZSA9PT0gJ2Z1bGxUaW1lV2l0aE1pbnV0ZXNEaXNhYmxlZCcgJiYgISF0aGlzLmNvbnRyb2w/LnByaXN0aW5lKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZSBpbnN0YW5jZW9mIERhdGUgPyB0aGlzLnZhbHVlLmdldEhvdXJzKCkgOiB0aGlzLnZhbHVlLmhvdXJzO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbWludXRlc1ZhbHVlKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmICghdGhpcy52YWx1ZSB8fCAodGhpcy5mb3JjZU51bGxWYWx1ZSAmJiB0aGlzLm1vZGUgPT09ICdmdWxsVGltZVdpdGhIb3Vyc0Rpc2FibGVkJyAmJiAhIXRoaXMuY29udHJvbD8ucHJpc3RpbmUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlIGluc3RhbmNlb2YgRGF0ZSA/IHRoaXMudmFsdWUuZ2V0TWludXRlcygpIDogdGhpcy52YWx1ZS5taW51dGVzO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbmNyZW1lbnRWYWx1ZShmaWVsZFR5cGU6IEZpZWxkVHlwZSk6IHZvaWQge1xuICAgICAgICBpZiAoZmllbGRUeXBlID09PSAnaG91cnMnKSB7XG4gICAgICAgICAgICB0aGlzLm9uSG91cnNDaGFuZ2UkLm5leHQoKHRoaXMuaG91cnNWYWx1ZSB8fCAwKSArIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vbk1pbnV0ZXNDaGFuZ2UkLm5leHQoKHRoaXMubWludXRlc1ZhbHVlIHx8IDApICsgdGhpcy5fc3RlcCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZGVjcmVtZW50VmFsdWUoZmllbGRUeXBlOiBGaWVsZFR5cGUpOiB2b2lkIHtcbiAgICAgICAgaWYgKGZpZWxkVHlwZSA9PT0gJ2hvdXJzJykge1xuICAgICAgICAgICAgdGhpcy5vbkhvdXJzQ2hhbmdlJC5uZXh0KCh0aGlzLmhvdXJzVmFsdWUgfHwgMCkgLSAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub25NaW51dGVzQ2hhbmdlJC5uZXh0KCh0aGlzLm1pbnV0ZXNWYWx1ZSB8fCAwKSAtIHRoaXMuX3N0ZXApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ2xpY2sobW9kZTogJ2hvdXJzJyB8ICdtaW51dGVzJyk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fYXV0b0ZvY3VzKSB7XG4gICAgICAgICAgICBpZiAobW9kZSA9PT0gJ2hvdXJzJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaG91cnM/Lm5hdGl2ZUVsZW1lbnQuc2VsZWN0KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubWludXRlcz8ubmF0aXZlRWxlbWVudC5zZWxlY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vICoqKioqKioqKioqKiogQ29udHJvbFZhbHVlQWNjZXNzb3IgSW1wbGVtZW50YXRpb24gKioqKioqKioqKioqKipcbiAgICAvKiogc2V0IGFjY2Vzc29yIGluY2x1ZGluZyBjYWxsIHRoZSBvbmNoYW5nZSBjYWxsYmFjayAqL1xuICAgIHB1YmxpYyBzZXQgdmFsdWUodjogTmd4RGF0ZU9yRHVyYXRpb24gfCB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHYgIT09IHRoaXMuX3ZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLndyaXRlVmFsdWUodik7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sodik7XG4gICAgICAgICAgICB0aGlzLnRpbWVDaGFuZ2UuZW1pdCh2KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBnZXQgYWNjZXNzb3IgKi9cbiAgICBwdWJsaWMgZ2V0IHZhbHVlKCk6IE5neERhdGVPckR1cmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICAgIH1cblxuICAgIC8qKiBGcm9tIENvbnRyb2xWYWx1ZUFjY2Vzc29yIGludGVyZmFjZSAqL1xuICAgIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlOiBOZ3hEYXRlT3JEdXJhdGlvbiB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgICAgICBpZiAoKHZhbHVlID8/IG51bGwpICE9PSAodGhpcy5fdmFsdWUgPz8gbnVsbCkpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlID8gbmV3IERhdGUodmFsdWUuZ2V0VGltZSgpKSA6IHNldChuZXcgRGF0ZSgpLCB7IGhvdXJzOiAwLCBtaW51dGVzOiAwLCBzZWNvbmRzOiAwIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEZyb20gQ29udHJvbFZhbHVlQWNjZXNzb3IgaW50ZXJmYWNlICovXG4gICAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm46IChfYTogdW5rbm93bikgPT4gdm9pZCk6IHZvaWQge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgICB9XG5cbiAgICAvKiogRnJvbSBDb250cm9sVmFsdWVBY2Nlc3NvciBpbnRlcmZhY2UgKi9cbiAgICBwdWJsaWMgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjayA9IGZuO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgfVxuICAgIC8vICoqKioqKioqKioqKiogRW5kIG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yIEltcGxlbWVudGF0aW9uICoqKioqKioqKioqKioqXG5cbiAgICBwcm90ZWN0ZWQgb25DaGFuZ2VDYWxsYmFjayA9IChfYTogdW5rbm93bik6IHZvaWQgPT4gdW5kZWZpbmVkO1xuICAgIHByb3RlY3RlZCBvblRvdWNoZWRDYWxsYmFjayA9ICgpOiB2b2lkID0+IHVuZGVmaW5lZDtcbn1cbiIsIjwhLS0gSG91cnMgLS0+XG48bWF0LWZvcm0tZmllbGRcbiAgICBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCJcbiAgICBjbGFzcz1cImhvdXJzXCJcbiAgICBbY2xhc3MuZGlzYWJsZWRdPVwiZGlzYWJsZWQgfHwgbW9kZSA9PT0gJ2Z1bGxUaW1lV2l0aEhvdXJzRGlzYWJsZWQnXCJcbiAgICBbc3R5bGUuZGlzcGxheV09XCJtb2RlID09PSAnbWludXRlc09ubHknID8gJ25vbmUnIDogJ2Jsb2NrJ1wiPlxuICAgIDxpbnB1dFxuICAgICAgICAjaG91cnNcbiAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICBbbmdNb2RlbF09XCJob3Vyc1ZhbHVlIHwgbnVtYmVyOiAnMi4nXCJcbiAgICAgICAgKGNoYW5nZSk9XCJvbkhvdXJzQ2hhbmdlJC5uZXh0KCRldmVudClcIlxuICAgICAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50LCAnaG91cnMnKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZCB8fCBtb2RlID09PSAnZnVsbFRpbWVXaXRoSG91cnNEaXNhYmxlZCdcIlxuICAgICAgICBbbWF4TGVuZ3RoXT1cIjJcIlxuICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZGVmYXVsdFBsYWNlaG9sZGVySG91cnNcIlxuICAgICAgICAoY2xpY2spPVwib25DbGljaygnaG91cnMnKVwiIC8+XG4gICAgPG5neC1udW1lcmljLXN0ZXBwZXJcbiAgICAgICAgKGluY3JlbWVudCk9XCJpbmNyZW1lbnRWYWx1ZSgnaG91cnMnKVwiXG4gICAgICAgIChkZWNyZW1lbnQpPVwiZGVjcmVtZW50VmFsdWUoJ2hvdXJzJylcIj48L25neC1udW1lcmljLXN0ZXBwZXI+XG48L21hdC1mb3JtLWZpZWxkPlxuXG48IS0tIFNlcGFyYXRvciAtLT5cbjxzcGFuIGNsYXNzPVwidGltZS1zZXBhcmF0b3JcIiBbc3R5bGUuZGlzcGxheV09XCJtb2RlID09PSAnbWludXRlc09ubHknIHx8IG1vZGUgPT09ICdob3Vyc09ubHknID8gJ25vbmUnIDogJ2Jsb2NrJ1wiPlxuICAgIDpcbjwvc3Bhbj5cblxuPCEtLSBNaW51dGVzIC0tPlxuPG1hdC1mb3JtLWZpZWxkXG4gICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgY2xhc3M9XCJtaW51dGVzXCJcbiAgICBbY2xhc3MuZGlzYWJsZWRdPVwiZGlzYWJsZWQgfHwgbW9kZSA9PT0gJ2Z1bGxUaW1lV2l0aE1pbnV0ZXNEaXNhYmxlZCdcIlxuICAgIFtzdHlsZS5kaXNwbGF5XT1cIm1vZGUgPT09ICdob3Vyc09ubHknID8gJ25vbmUnIDogJ2Jsb2NrJ1wiPlxuICAgIDxpbnB1dFxuICAgICAgICAjbWludXRlc1xuICAgICAgICBtYXRJbnB1dFxuICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgIFtuZ01vZGVsXT1cIm1pbnV0ZXNWYWx1ZSB8IG51bWJlcjogJzIuJ1wiXG4gICAgICAgIChjaGFuZ2UpPVwib25NaW51dGVzQ2hhbmdlJC5uZXh0KCRldmVudClcIlxuICAgICAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50LCAnbWludXRlcycpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkIHx8IG1vZGUgPT09ICdmdWxsVGltZVdpdGhNaW51dGVzRGlzYWJsZWQnXCJcbiAgICAgICAgW21heExlbmd0aF09XCIyXCJcbiAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgW3BsYWNlaG9sZGVyXT1cImRlZmF1bHRQbGFjZWhvbGRlck1pbnV0ZXNcIlxuICAgICAgICAoY2xpY2spPVwib25DbGljaygnbWludXRlcycpXCIgLz5cbiAgICA8bmd4LW51bWVyaWMtc3RlcHBlclxuICAgICAgICAoaW5jcmVtZW50KT1cImluY3JlbWVudFZhbHVlKCdtaW51dGVzJylcIlxuICAgICAgICAoZGVjcmVtZW50KT1cImRlY3JlbWVudFZhbHVlKCdtaW51dGVzJylcIj48L25neC1udW1lcmljLXN0ZXBwZXI+XG48L21hdC1mb3JtLWZpZWxkPlxuIl19
|