@hug/ngx-time-picker 1.1.13 → 2.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,172 +1,186 @@
1
- ## 1.1.13 (2024-08-03)
1
+ # 2.0.0 (2024-09-11)
2
2
 
3
3
 
4
- ### 🐛 Fixes
4
+ ### 🚀 Features
5
5
 
6
- - **ngx-time-picker:** fix NG_VALUE_ACCESSOR error ([ec24577](https://github.com/DSI-HUG/ngx-components/commit/ec24577))
6
+ - update to angular 15 - FC-67 ([6bad712](https://github.com/DSI-HUG/ngx-components/commit/6bad712))
7
7
 
8
+ - update material to angular 15 - FC-67 ([44406c1](https://github.com/DSI-HUG/ngx-components/commit/44406c1))
8
9
 
9
- ### ❤️ Thank You
10
+ - time picker angular15 ([1d53f68](https://github.com/DSI-HUG/ngx-components/commit/1d53f68))
10
11
 
11
- - Serge
12
+ - remove NgxDetroy ([c64d8bb](https://github.com/DSI-HUG/ngx-components/commit/c64d8bb))
12
13
 
13
- ## 1.1.12 (2024-08-03)
14
+ - prettier ([2aa36f0](https://github.com/DSI-HUG/ngx-components/commit/2aa36f0))
15
+
16
+ - **ng18:** remove no more necessary files ([54c46a1](https://github.com/DSI-HUG/ngx-components/commit/54c46a1))
14
17
 
15
18
 
16
19
  ### 🐛 Fixes
17
20
 
18
- - **ngx-time-picker:** fix NG_VALUE_ACCESSOR error ([28bce28](https://github.com/DSI-HUG/ngx-components/commit/28bce28))
21
+ - lint ([11a9b75](https://github.com/DSI-HUG/ngx-components/commit/11a9b75))
19
22
 
23
+ - correctif passage compelt ng18 ([3fe864e](https://github.com/DSI-HUG/ngx-components/commit/3fe864e))
20
24
 
21
- ### ❤️ Thank You
25
+ - **ci:** tests ([9387ba8](https://github.com/DSI-HUG/ngx-components/commit/9387ba8))
22
26
 
23
- - Serge
24
-
25
- ## 1.1.11 (2024-08-03)
26
27
 
28
+ ### 🌱 Dependencies
27
29
 
28
- ### 🐛 Fixes
30
+ - **@hug/ngx-numeric-stepper:** upgrade to v2.0.0 ([67c347f](https://github.com/DSI-HUG/ngx-components/commit/67c347f))
29
31
 
30
- - **ngx-time-picker:** fix NG_VALUE_ACCESSOR error ([01df020](https://github.com/DSI-HUG/ngx-components/commit/01df020))
32
+ - **@hug/ngx-core:** upgrade to v2.0.0 ([ce6226c](https://github.com/DSI-HUG/ngx-components/commit/ce6226c))
31
33
 
32
34
 
33
35
  ### ❤️ Thank You
34
36
 
35
- - Serge
37
+ - Badisi
38
+ - dsi-hug-bot @dsi-hug-bot
39
+ - rfrt
36
40
 
37
- ## 1.1.10 (2024-07-25)
41
+ ## 1.1.13 (2024-08-03)
42
+
43
+ ### 🐛 Fixes
44
+
45
+ - **ngx-time-picker:** fix NG_VALUE_ACCESSOR error ([ec24577](https://github.com/DSI-HUG/ngx-components/commit/ec24577))
46
+
47
+ ### ❤️ Thank You
48
+
49
+ - Serge
38
50
 
51
+ ## 1.1.12 (2024-08-03)
39
52
 
40
53
  ### 🐛 Fixes
41
54
 
42
- - **ngx-time-picker:** update patch version ([98352e2](https://github.com/DSI-HUG/ngx-components/commit/98352e2))
55
+ - **ngx-time-picker:** fix NG_VALUE_ACCESSOR error ([28bce28](https://github.com/DSI-HUG/ngx-components/commit/28bce28))
43
56
 
57
+ ### ❤️ Thank You
44
58
 
45
- ### 🌱 Dependencies
59
+ - Serge
46
60
 
47
- - **@hug/ngx-numeric-stepper:** upgrade to v1.1.11 ([71e5911](https://github.com/DSI-HUG/ngx-components/commit/71e5911))
61
+ ## 1.1.11 (2024-08-03)
48
62
 
49
- - **@hug/ngx-core:** upgrade to v1.1.14 ([12ee5d4](https://github.com/DSI-HUG/ngx-components/commit/12ee5d4))
63
+ ### 🐛 Fixes
50
64
 
65
+ - **ngx-time-picker:** fix NG_VALUE_ACCESSOR error ([01df020](https://github.com/DSI-HUG/ngx-components/commit/01df020))
51
66
 
52
- ### ❤️ Thank You
67
+ ### ❤️ Thank You
53
68
 
54
- - dsi-hug-bot @dsi-hug-bot
55
- - Serge
69
+ - Serge
56
70
 
57
- ## 1.1.9 (2024-07-25)
71
+ ## 1.1.10 (2024-07-25)
58
72
 
73
+ ### 🐛 Fixes
74
+
75
+ - **ngx-time-picker:** update patch version ([98352e2](https://github.com/DSI-HUG/ngx-components/commit/98352e2))
59
76
 
60
77
  ### 🌱 Dependencies
61
78
 
62
- - **@hug/ngx-core:** upgrade to v1.1.13 ([15e11d7](https://github.com/DSI-HUG/ngx-components/commit/15e11d7))
79
+ - **@hug/ngx-numeric-stepper:** upgrade to v1.1.11 ([71e5911](https://github.com/DSI-HUG/ngx-components/commit/71e5911))
63
80
 
81
+ - **@hug/ngx-core:** upgrade to v1.1.14 ([12ee5d4](https://github.com/DSI-HUG/ngx-components/commit/12ee5d4))
64
82
 
65
- ### ❤️ Thank You
83
+ ### ❤️ Thank You
66
84
 
67
- - dsi-hug-bot @dsi-hug-bot
85
+ - dsi-hug-bot @dsi-hug-bot
86
+ - Serge
68
87
 
69
- ## 1.1.8 (2024-07-24)
88
+ ## 1.1.9 (2024-07-25)
70
89
 
90
+ ### 🌱 Dependencies
71
91
 
72
- ### 🐛 Fixes
92
+ - **@hug/ngx-core:** upgrade to v1.1.13 ([15e11d7](https://github.com/DSI-HUG/ngx-components/commit/15e11d7))
73
93
 
74
- - **ngx-time-picker:** update patch version ([f8a7d86](https://github.com/DSI-HUG/ngx-components/commit/f8a7d86))
94
+ ### ❤️ Thank You
75
95
 
96
+ - dsi-hug-bot @dsi-hug-bot
76
97
 
77
- ### 🌱 Dependencies
98
+ ## 1.1.8 (2024-07-24)
78
99
 
79
- - **@hug/ngx-numeric-stepper:** upgrade to v1.1.9 ([34f74e7](https://github.com/DSI-HUG/ngx-components/commit/34f74e7))
100
+ ### 🐛 Fixes
80
101
 
81
- - **@hug/ngx-core:** upgrade to v1.1.12 ([78a2936](https://github.com/DSI-HUG/ngx-components/commit/78a2936))
102
+ - **ngx-time-picker:** update patch version ([f8a7d86](https://github.com/DSI-HUG/ngx-components/commit/f8a7d86))
82
103
 
104
+ ### 🌱 Dependencies
83
105
 
84
- ### ❤️ Thank You
106
+ - **@hug/ngx-numeric-stepper:** upgrade to v1.1.9 ([34f74e7](https://github.com/DSI-HUG/ngx-components/commit/34f74e7))
85
107
 
86
- - dsi-hug-bot @dsi-hug-bot
87
- - Serge
108
+ - **@hug/ngx-core:** upgrade to v1.1.12 ([78a2936](https://github.com/DSI-HUG/ngx-components/commit/78a2936))
88
109
 
89
- ## 1.1.7 (2024-07-24)
110
+ ### ❤️ Thank You
90
111
 
112
+ - dsi-hug-bot @dsi-hug-bot
113
+ - Serge
91
114
 
92
- ### 🐛 Fixes
115
+ ## 1.1.7 (2024-07-24)
93
116
 
94
- - **ngx-time-picker:** update patch version ([f251f4a](https://github.com/DSI-HUG/ngx-components/commit/f251f4a))
117
+ ### 🐛 Fixes
95
118
 
119
+ - **ngx-time-picker:** update patch version ([f251f4a](https://github.com/DSI-HUG/ngx-components/commit/f251f4a))
96
120
 
97
121
  ### 🌱 Dependencies
98
122
 
99
- - **@hug/ngx-core:** upgrade to v1.1.11 ([bda1d8c](https://github.com/DSI-HUG/ngx-components/commit/bda1d8c))
100
-
101
- - **@hug/ngx-numeric-stepper:** upgrade to v1.1.8 ([b79bfa0](https://github.com/DSI-HUG/ngx-components/commit/b79bfa0))
123
+ - **@hug/ngx-core:** upgrade to v1.1.11 ([bda1d8c](https://github.com/DSI-HUG/ngx-components/commit/bda1d8c))
102
124
 
125
+ - **@hug/ngx-numeric-stepper:** upgrade to v1.1.8 ([b79bfa0](https://github.com/DSI-HUG/ngx-components/commit/b79bfa0))
103
126
 
104
- ### ❤️ Thank You
127
+ ### ❤️ Thank You
105
128
 
106
- - dsi-hug-bot @dsi-hug-bot
107
- - Serge
129
+ - dsi-hug-bot @dsi-hug-bot
130
+ - Serge
108
131
 
109
132
  ## 1.1.6 (2024-07-23)
110
133
 
111
-
112
134
  ### 🐛 Fixes
113
135
 
114
- - **ngx-time-picker:** compile path ([5fdb256](https://github.com/DSI-HUG/ngx-components/commit/5fdb256))
115
-
136
+ - **ngx-time-picker:** compile path ([5fdb256](https://github.com/DSI-HUG/ngx-components/commit/5fdb256))
116
137
 
117
138
  ### 🌱 Dependencies
118
139
 
119
- - **@hug/ngx-core:** upgrade to v1.1.9 ([3692c68](https://github.com/DSI-HUG/ngx-components/commit/3692c68))
120
-
121
- - **@hug/ngx-numeric-stepper:** upgrade to v1.1.7 ([1d42ddd](https://github.com/DSI-HUG/ngx-components/commit/1d42ddd))
140
+ - **@hug/ngx-core:** upgrade to v1.1.9 ([3692c68](https://github.com/DSI-HUG/ngx-components/commit/3692c68))
122
141
 
123
- - **@hug/ngx-core:** upgrade to v1.1.10 ([78dbe21](https://github.com/DSI-HUG/ngx-components/commit/78dbe21))
142
+ - **@hug/ngx-numeric-stepper:** upgrade to v1.1.7 ([1d42ddd](https://github.com/DSI-HUG/ngx-components/commit/1d42ddd))
124
143
 
144
+ - **@hug/ngx-core:** upgrade to v1.1.10 ([78dbe21](https://github.com/DSI-HUG/ngx-components/commit/78dbe21))
125
145
 
126
- ### ❤️ Thank You
146
+ ### ❤️ Thank You
127
147
 
128
- - dsi-hug-bot @dsi-hug-bot
129
- - Serge
148
+ - dsi-hug-bot @dsi-hug-bot
149
+ - Serge
130
150
 
131
151
  ## 1.1.5 (2024-07-23)
132
152
 
133
-
134
153
  ### 🐛 Fixes
135
154
 
136
- - **ngx-time-picker:** ngx prefix ([2c62859](https://github.com/DSI-HUG/ngx-components/commit/2c62859))
137
-
138
- - **ngx-time-picker:** ngx prefix ([bd4b65e](https://github.com/DSI-HUG/ngx-components/commit/bd4b65e))
155
+ - **ngx-time-picker:** ngx prefix ([2c62859](https://github.com/DSI-HUG/ngx-components/commit/2c62859))
139
156
 
157
+ - **ngx-time-picker:** ngx prefix ([bd4b65e](https://github.com/DSI-HUG/ngx-components/commit/bd4b65e))
140
158
 
141
159
  ### 🌱 Dependencies
142
160
 
143
- - **@hug/ngx-numeric-stepper:** upgrade to v1.1.6 ([094b0f2](https://github.com/DSI-HUG/ngx-components/commit/094b0f2))
161
+ - **@hug/ngx-numeric-stepper:** upgrade to v1.1.6 ([094b0f2](https://github.com/DSI-HUG/ngx-components/commit/094b0f2))
144
162
 
163
+ ### ❤️ Thank You
145
164
 
146
- ### ❤️ Thank You
147
-
148
- - dsi-hug-bot @dsi-hug-bot
149
- - Serge
165
+ - dsi-hug-bot @dsi-hug-bot
166
+ - Serge
150
167
 
151
168
  ## 1.1.4 (2024-07-23)
152
169
 
153
-
154
170
  ### 🐛 Fixes
155
171
 
156
- - **ngx-time-picker:** use inject ([16ab25a](https://github.com/DSI-HUG/ngx-components/commit/16ab25a))
157
-
172
+ - **ngx-time-picker:** use inject ([16ab25a](https://github.com/DSI-HUG/ngx-components/commit/16ab25a))
158
173
 
159
174
  ### 🌱 Dependencies
160
175
 
161
- - **@hug/ngx-core:** upgrade to v1.1.8 ([26f0d10](https://github.com/DSI-HUG/ngx-components/commit/26f0d10))
176
+ - **@hug/ngx-core:** upgrade to v1.1.8 ([26f0d10](https://github.com/DSI-HUG/ngx-components/commit/26f0d10))
162
177
 
163
- - **@hug/ngx-numeric-stepper:** upgrade to v1.1.5 ([a76174a](https://github.com/DSI-HUG/ngx-components/commit/a76174a))
178
+ - **@hug/ngx-numeric-stepper:** upgrade to v1.1.5 ([a76174a](https://github.com/DSI-HUG/ngx-components/commit/a76174a))
164
179
 
180
+ ### ❤️ Thank You
165
181
 
166
- ### ❤️ Thank You
167
-
168
- - dsi-hug-bot @dsi-hug-bot
169
- - Serge
182
+ - dsi-hug-bot @dsi-hug-bot
183
+ - Serge
170
184
 
171
185
  ## 1.1.3 (2024-07-08)
172
186
 
package/README.md CHANGED
@@ -1,4 +1,5 @@
1
- # @hug/ngx-time-picker
1
+ @hug/ngx-time-picker
2
+ =======
2
3
 
3
4
  The sources for this package are in the main [DSI-HUG/ngx-components](https://github.com/dsi-hug/ngx-components) repo. Please file issues and pull requests against that repo.
4
5
 
@@ -0,0 +1,298 @@
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