@angular/forms 16.0.0-next.4 → 16.0.0-next.6
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/{esm2020 → esm2022}/src/directives/abstract_form_group_directive.mjs +4 -4
- package/{esm2020 → esm2022}/src/directives/checkbox_value_accessor.mjs +4 -4
- package/{esm2020 → esm2022}/src/directives/control_value_accessor.mjs +7 -7
- package/{esm2020 → esm2022}/src/directives/default_value_accessor.mjs +4 -4
- package/{esm2020 → esm2022}/src/directives/ng_control_status.mjs +7 -7
- package/{esm2020 → esm2022}/src/directives/ng_form.mjs +4 -4
- package/esm2022/src/directives/ng_model.mjs +332 -0
- package/esm2022/src/directives/ng_model_group.mjs +95 -0
- package/{esm2020 → esm2022}/src/directives/ng_no_validate_directive.mjs +4 -4
- package/{esm2020 → esm2022}/src/directives/number_value_accessor.mjs +4 -4
- package/{esm2020 → esm2022}/src/directives/radio_control_value_accessor.mjs +11 -11
- package/{esm2020 → esm2022}/src/directives/range_value_accessor.mjs +4 -4
- package/esm2022/src/directives/reactive_directives/form_control_directive.mjs +185 -0
- package/esm2022/src/directives/reactive_directives/form_control_name.mjs +219 -0
- package/{esm2020 → esm2022}/src/directives/reactive_directives/form_group_directive.mjs +4 -4
- package/esm2022/src/directives/reactive_directives/form_group_name.mjs +247 -0
- package/{esm2020 → esm2022}/src/directives/select_control_value_accessor.mjs +7 -7
- package/{esm2020 → esm2022}/src/directives/select_multiple_control_value_accessor.mjs +7 -7
- package/{esm2020 → esm2022}/src/directives/validators.mjs +28 -28
- package/{esm2020 → esm2022}/src/directives.mjs +43 -43
- package/esm2022/src/form_builder.mjs +259 -0
- package/{esm2020 → esm2022}/src/form_providers.mjs +9 -9
- package/esm2022/src/model/abstract_model.mjs +939 -0
- package/esm2022/src/validators.mjs +678 -0
- package/{esm2020 → esm2022}/src/version.mjs +1 -1
- package/{fesm2020 → fesm2022}/forms.mjs +228 -187
- package/fesm2022/forms.mjs.map +1 -0
- package/index.d.ts +13 -3
- package/package.json +8 -14
- package/esm2020/src/directives/ng_model.mjs +0 -326
- package/esm2020/src/directives/ng_model_group.mjs +0 -89
- package/esm2020/src/directives/reactive_directives/form_control_directive.mjs +0 -185
- package/esm2020/src/directives/reactive_directives/form_control_name.mjs +0 -209
- package/esm2020/src/directives/reactive_directives/form_group_name.mjs +0 -227
- package/esm2020/src/form_builder.mjs +0 -259
- package/esm2020/src/model/abstract_model.mjs +0 -939
- package/esm2020/src/validators.mjs +0 -679
- package/fesm2015/forms.mjs +0 -7272
- package/fesm2015/forms.mjs.map +0 -1
- package/fesm2020/forms.mjs.map +0 -1
- /package/{esm2020 → esm2022}/forms.mjs +0 -0
- /package/{esm2020 → esm2022}/index.mjs +0 -0
- /package/{esm2020 → esm2022}/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/abstract_control_directive.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/control_container.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/error_examples.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/form_interface.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/ng_control.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/reactive_errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/shared.mjs +0 -0
- /package/{esm2020 → esm2022}/src/directives/template_driven_errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/errors.mjs +0 -0
- /package/{esm2020 → esm2022}/src/forms.mjs +0 -0
- /package/{esm2020 → esm2022}/src/model/form_array.mjs +0 -0
- /package/{esm2020 → esm2022}/src/model/form_control.mjs +0 -0
- /package/{esm2020 → esm2022}/src/model/form_group.mjs +0 -0
- /package/{esm2020 → esm2022}/src/util.mjs +0 -0
|
@@ -1,939 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
import { EventEmitter, ɵRuntimeError as RuntimeError } from '@angular/core';
|
|
9
|
-
import { asyncValidatorsDroppedWithOptsWarning, missingControlError, missingControlValueError, noControlsError } from '../directives/reactive_errors';
|
|
10
|
-
import { addValidators, composeAsyncValidators, composeValidators, hasValidator, removeValidators, toObservable } from '../validators';
|
|
11
|
-
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
|
|
12
|
-
/**
|
|
13
|
-
* Reports that a control is valid, meaning that no errors exist in the input value.
|
|
14
|
-
*
|
|
15
|
-
* @see `status`
|
|
16
|
-
*/
|
|
17
|
-
export const VALID = 'VALID';
|
|
18
|
-
/**
|
|
19
|
-
* Reports that a control is invalid, meaning that an error exists in the input value.
|
|
20
|
-
*
|
|
21
|
-
* @see `status`
|
|
22
|
-
*/
|
|
23
|
-
export const INVALID = 'INVALID';
|
|
24
|
-
/**
|
|
25
|
-
* Reports that a control is pending, meaning that that async validation is occurring and
|
|
26
|
-
* errors are not yet available for the input value.
|
|
27
|
-
*
|
|
28
|
-
* @see `markAsPending`
|
|
29
|
-
* @see `status`
|
|
30
|
-
*/
|
|
31
|
-
export const PENDING = 'PENDING';
|
|
32
|
-
/**
|
|
33
|
-
* Reports that a control is disabled, meaning that the control is exempt from ancestor
|
|
34
|
-
* calculations of validity or value.
|
|
35
|
-
*
|
|
36
|
-
* @see `markAsDisabled`
|
|
37
|
-
* @see `status`
|
|
38
|
-
*/
|
|
39
|
-
export const DISABLED = 'DISABLED';
|
|
40
|
-
/**
|
|
41
|
-
* Gets validators from either an options object or given validators.
|
|
42
|
-
*/
|
|
43
|
-
export function pickValidators(validatorOrOpts) {
|
|
44
|
-
return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.validators : validatorOrOpts) || null;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Creates validator function by combining provided validators.
|
|
48
|
-
*/
|
|
49
|
-
function coerceToValidator(validator) {
|
|
50
|
-
return Array.isArray(validator) ? composeValidators(validator) : validator || null;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Gets async validators from either an options object or given validators.
|
|
54
|
-
*/
|
|
55
|
-
export function pickAsyncValidators(asyncValidator, validatorOrOpts) {
|
|
56
|
-
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
57
|
-
if (isOptionsObj(validatorOrOpts) && asyncValidator) {
|
|
58
|
-
console.warn(asyncValidatorsDroppedWithOptsWarning);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.asyncValidators : asyncValidator) || null;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Creates async validator function by combining provided async validators.
|
|
65
|
-
*/
|
|
66
|
-
function coerceToAsyncValidator(asyncValidator) {
|
|
67
|
-
return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) :
|
|
68
|
-
asyncValidator || null;
|
|
69
|
-
}
|
|
70
|
-
export function isOptionsObj(validatorOrOpts) {
|
|
71
|
-
return validatorOrOpts != null && !Array.isArray(validatorOrOpts) &&
|
|
72
|
-
typeof validatorOrOpts === 'object';
|
|
73
|
-
}
|
|
74
|
-
export function assertControlPresent(parent, isGroup, key) {
|
|
75
|
-
const controls = parent.controls;
|
|
76
|
-
const collection = isGroup ? Object.keys(controls) : controls;
|
|
77
|
-
if (!collection.length) {
|
|
78
|
-
throw new RuntimeError(1000 /* RuntimeErrorCode.NO_CONTROLS */, NG_DEV_MODE ? noControlsError(isGroup) : '');
|
|
79
|
-
}
|
|
80
|
-
if (!controls[key]) {
|
|
81
|
-
throw new RuntimeError(1001 /* RuntimeErrorCode.MISSING_CONTROL */, NG_DEV_MODE ? missingControlError(isGroup, key) : '');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
export function assertAllValuesPresent(control, isGroup, value) {
|
|
85
|
-
control._forEachChild((_, key) => {
|
|
86
|
-
if (value[key] === undefined) {
|
|
87
|
-
throw new RuntimeError(1002 /* RuntimeErrorCode.MISSING_CONTROL_VALUE */, NG_DEV_MODE ? missingControlValueError(isGroup, key) : '');
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
// clang-format on
|
|
92
|
-
/**
|
|
93
|
-
* This is the base class for `FormControl`, `FormGroup`, and `FormArray`.
|
|
94
|
-
*
|
|
95
|
-
* It provides some of the shared behavior that all controls and groups of controls have, like
|
|
96
|
-
* running validators, calculating status, and resetting state. It also defines the properties
|
|
97
|
-
* that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
|
|
98
|
-
* instantiated directly.
|
|
99
|
-
*
|
|
100
|
-
* The first type parameter TValue represents the value type of the control (`control.value`).
|
|
101
|
-
* The optional type parameter TRawValue represents the raw value type (`control.getRawValue()`).
|
|
102
|
-
*
|
|
103
|
-
* @see [Forms Guide](/guide/forms)
|
|
104
|
-
* @see [Reactive Forms Guide](/guide/reactive-forms)
|
|
105
|
-
* @see [Dynamic Forms Guide](/guide/dynamic-form)
|
|
106
|
-
*
|
|
107
|
-
* @publicApi
|
|
108
|
-
*/
|
|
109
|
-
export class AbstractControl {
|
|
110
|
-
/**
|
|
111
|
-
* Initialize the AbstractControl instance.
|
|
112
|
-
*
|
|
113
|
-
* @param validators The function or array of functions that is used to determine the validity of
|
|
114
|
-
* this control synchronously.
|
|
115
|
-
* @param asyncValidators The function or array of functions that is used to determine validity of
|
|
116
|
-
* this control asynchronously.
|
|
117
|
-
*/
|
|
118
|
-
constructor(validators, asyncValidators) {
|
|
119
|
-
/** @internal */
|
|
120
|
-
this._pendingDirty = false;
|
|
121
|
-
/**
|
|
122
|
-
* Indicates that a control has its own pending asynchronous validation in progress.
|
|
123
|
-
*
|
|
124
|
-
* @internal
|
|
125
|
-
*/
|
|
126
|
-
this._hasOwnPendingAsyncValidator = false;
|
|
127
|
-
/** @internal */
|
|
128
|
-
this._pendingTouched = false;
|
|
129
|
-
/** @internal */
|
|
130
|
-
this._onCollectionChange = () => { };
|
|
131
|
-
this._parent = null;
|
|
132
|
-
/**
|
|
133
|
-
* A control is `pristine` if the user has not yet changed
|
|
134
|
-
* the value in the UI.
|
|
135
|
-
*
|
|
136
|
-
* @returns True if the user has not yet changed the value in the UI; compare `dirty`.
|
|
137
|
-
* Programmatic changes to a control's value do not mark it dirty.
|
|
138
|
-
*/
|
|
139
|
-
this.pristine = true;
|
|
140
|
-
/**
|
|
141
|
-
* True if the control is marked as `touched`.
|
|
142
|
-
*
|
|
143
|
-
* A control is marked `touched` once the user has triggered
|
|
144
|
-
* a `blur` event on it.
|
|
145
|
-
*/
|
|
146
|
-
this.touched = false;
|
|
147
|
-
/** @internal */
|
|
148
|
-
this._onDisabledChange = [];
|
|
149
|
-
this._assignValidators(validators);
|
|
150
|
-
this._assignAsyncValidators(asyncValidators);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Returns the function that is used to determine the validity of this control synchronously.
|
|
154
|
-
* If multiple validators have been added, this will be a single composed function.
|
|
155
|
-
* See `Validators.compose()` for additional information.
|
|
156
|
-
*/
|
|
157
|
-
get validator() {
|
|
158
|
-
return this._composedValidatorFn;
|
|
159
|
-
}
|
|
160
|
-
set validator(validatorFn) {
|
|
161
|
-
this._rawValidators = this._composedValidatorFn = validatorFn;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Returns the function that is used to determine the validity of this control asynchronously.
|
|
165
|
-
* If multiple validators have been added, this will be a single composed function.
|
|
166
|
-
* See `Validators.compose()` for additional information.
|
|
167
|
-
*/
|
|
168
|
-
get asyncValidator() {
|
|
169
|
-
return this._composedAsyncValidatorFn;
|
|
170
|
-
}
|
|
171
|
-
set asyncValidator(asyncValidatorFn) {
|
|
172
|
-
this._rawAsyncValidators = this._composedAsyncValidatorFn = asyncValidatorFn;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* The parent control.
|
|
176
|
-
*/
|
|
177
|
-
get parent() {
|
|
178
|
-
return this._parent;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* A control is `valid` when its `status` is `VALID`.
|
|
182
|
-
*
|
|
183
|
-
* @see {@link AbstractControl.status}
|
|
184
|
-
*
|
|
185
|
-
* @returns True if the control has passed all of its validation tests,
|
|
186
|
-
* false otherwise.
|
|
187
|
-
*/
|
|
188
|
-
get valid() {
|
|
189
|
-
return this.status === VALID;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* A control is `invalid` when its `status` is `INVALID`.
|
|
193
|
-
*
|
|
194
|
-
* @see {@link AbstractControl.status}
|
|
195
|
-
*
|
|
196
|
-
* @returns True if this control has failed one or more of its validation checks,
|
|
197
|
-
* false otherwise.
|
|
198
|
-
*/
|
|
199
|
-
get invalid() {
|
|
200
|
-
return this.status === INVALID;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* A control is `pending` when its `status` is `PENDING`.
|
|
204
|
-
*
|
|
205
|
-
* @see {@link AbstractControl.status}
|
|
206
|
-
*
|
|
207
|
-
* @returns True if this control is in the process of conducting a validation check,
|
|
208
|
-
* false otherwise.
|
|
209
|
-
*/
|
|
210
|
-
get pending() {
|
|
211
|
-
return this.status == PENDING;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* A control is `disabled` when its `status` is `DISABLED`.
|
|
215
|
-
*
|
|
216
|
-
* Disabled controls are exempt from validation checks and
|
|
217
|
-
* are not included in the aggregate value of their ancestor
|
|
218
|
-
* controls.
|
|
219
|
-
*
|
|
220
|
-
* @see {@link AbstractControl.status}
|
|
221
|
-
*
|
|
222
|
-
* @returns True if the control is disabled, false otherwise.
|
|
223
|
-
*/
|
|
224
|
-
get disabled() {
|
|
225
|
-
return this.status === DISABLED;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* A control is `enabled` as long as its `status` is not `DISABLED`.
|
|
229
|
-
*
|
|
230
|
-
* @returns True if the control has any status other than 'DISABLED',
|
|
231
|
-
* false if the status is 'DISABLED'.
|
|
232
|
-
*
|
|
233
|
-
* @see {@link AbstractControl.status}
|
|
234
|
-
*
|
|
235
|
-
*/
|
|
236
|
-
get enabled() {
|
|
237
|
-
return this.status !== DISABLED;
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* A control is `dirty` if the user has changed the value
|
|
241
|
-
* in the UI.
|
|
242
|
-
*
|
|
243
|
-
* @returns True if the user has changed the value of this control in the UI; compare `pristine`.
|
|
244
|
-
* Programmatic changes to a control's value do not mark it dirty.
|
|
245
|
-
*/
|
|
246
|
-
get dirty() {
|
|
247
|
-
return !this.pristine;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* True if the control has not been marked as touched
|
|
251
|
-
*
|
|
252
|
-
* A control is `untouched` if the user has not yet triggered
|
|
253
|
-
* a `blur` event on it.
|
|
254
|
-
*/
|
|
255
|
-
get untouched() {
|
|
256
|
-
return !this.touched;
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Reports the update strategy of the `AbstractControl` (meaning
|
|
260
|
-
* the event on which the control updates itself).
|
|
261
|
-
* Possible values: `'change'` | `'blur'` | `'submit'`
|
|
262
|
-
* Default value: `'change'`
|
|
263
|
-
*/
|
|
264
|
-
get updateOn() {
|
|
265
|
-
return this._updateOn ? this._updateOn : (this.parent ? this.parent.updateOn : 'change');
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Sets the synchronous validators that are active on this control. Calling
|
|
269
|
-
* this overwrites any existing synchronous validators.
|
|
270
|
-
*
|
|
271
|
-
* When you add or remove a validator at run time, you must call
|
|
272
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
273
|
-
*
|
|
274
|
-
* If you want to add a new validator without affecting existing ones, consider
|
|
275
|
-
* using `addValidators()` method instead.
|
|
276
|
-
*/
|
|
277
|
-
setValidators(validators) {
|
|
278
|
-
this._assignValidators(validators);
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Sets the asynchronous validators that are active on this control. Calling this
|
|
282
|
-
* overwrites any existing asynchronous validators.
|
|
283
|
-
*
|
|
284
|
-
* When you add or remove a validator at run time, you must call
|
|
285
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
286
|
-
*
|
|
287
|
-
* If you want to add a new validator without affecting existing ones, consider
|
|
288
|
-
* using `addAsyncValidators()` method instead.
|
|
289
|
-
*/
|
|
290
|
-
setAsyncValidators(validators) {
|
|
291
|
-
this._assignAsyncValidators(validators);
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Add a synchronous validator or validators to this control, without affecting other validators.
|
|
295
|
-
*
|
|
296
|
-
* When you add or remove a validator at run time, you must call
|
|
297
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
298
|
-
*
|
|
299
|
-
* Adding a validator that already exists will have no effect. If duplicate validator functions
|
|
300
|
-
* are present in the `validators` array, only the first instance would be added to a form
|
|
301
|
-
* control.
|
|
302
|
-
*
|
|
303
|
-
* @param validators The new validator function or functions to add to this control.
|
|
304
|
-
*/
|
|
305
|
-
addValidators(validators) {
|
|
306
|
-
this.setValidators(addValidators(validators, this._rawValidators));
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Add an asynchronous validator or validators to this control, without affecting other
|
|
310
|
-
* validators.
|
|
311
|
-
*
|
|
312
|
-
* When you add or remove a validator at run time, you must call
|
|
313
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
314
|
-
*
|
|
315
|
-
* Adding a validator that already exists will have no effect.
|
|
316
|
-
*
|
|
317
|
-
* @param validators The new asynchronous validator function or functions to add to this control.
|
|
318
|
-
*/
|
|
319
|
-
addAsyncValidators(validators) {
|
|
320
|
-
this.setAsyncValidators(addValidators(validators, this._rawAsyncValidators));
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Remove a synchronous validator from this control, without affecting other validators.
|
|
324
|
-
* Validators are compared by function reference; you must pass a reference to the exact same
|
|
325
|
-
* validator function as the one that was originally set. If a provided validator is not found,
|
|
326
|
-
* it is ignored.
|
|
327
|
-
*
|
|
328
|
-
* @usageNotes
|
|
329
|
-
*
|
|
330
|
-
* ### Reference to a ValidatorFn
|
|
331
|
-
*
|
|
332
|
-
* ```
|
|
333
|
-
* // Reference to the RequiredValidator
|
|
334
|
-
* const ctrl = new FormControl<string | null>('', Validators.required);
|
|
335
|
-
* ctrl.removeValidators(Validators.required);
|
|
336
|
-
*
|
|
337
|
-
* // Reference to anonymous function inside MinValidator
|
|
338
|
-
* const minValidator = Validators.min(3);
|
|
339
|
-
* const ctrl = new FormControl<string | null>('', minValidator);
|
|
340
|
-
* expect(ctrl.hasValidator(minValidator)).toEqual(true)
|
|
341
|
-
* expect(ctrl.hasValidator(Validators.min(3))).toEqual(false)
|
|
342
|
-
*
|
|
343
|
-
* ctrl.removeValidators(minValidator);
|
|
344
|
-
* ```
|
|
345
|
-
*
|
|
346
|
-
* When you add or remove a validator at run time, you must call
|
|
347
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
348
|
-
*
|
|
349
|
-
* @param validators The validator or validators to remove.
|
|
350
|
-
*/
|
|
351
|
-
removeValidators(validators) {
|
|
352
|
-
this.setValidators(removeValidators(validators, this._rawValidators));
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Remove an asynchronous validator from this control, without affecting other validators.
|
|
356
|
-
* Validators are compared by function reference; you must pass a reference to the exact same
|
|
357
|
-
* validator function as the one that was originally set. If a provided validator is not found, it
|
|
358
|
-
* is ignored.
|
|
359
|
-
*
|
|
360
|
-
* When you add or remove a validator at run time, you must call
|
|
361
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
362
|
-
*
|
|
363
|
-
* @param validators The asynchronous validator or validators to remove.
|
|
364
|
-
*/
|
|
365
|
-
removeAsyncValidators(validators) {
|
|
366
|
-
this.setAsyncValidators(removeValidators(validators, this._rawAsyncValidators));
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* Check whether a synchronous validator function is present on this control. The provided
|
|
370
|
-
* validator must be a reference to the exact same function that was provided.
|
|
371
|
-
*
|
|
372
|
-
* @usageNotes
|
|
373
|
-
*
|
|
374
|
-
* ### Reference to a ValidatorFn
|
|
375
|
-
*
|
|
376
|
-
* ```
|
|
377
|
-
* // Reference to the RequiredValidator
|
|
378
|
-
* const ctrl = new FormControl<number | null>(0, Validators.required);
|
|
379
|
-
* expect(ctrl.hasValidator(Validators.required)).toEqual(true)
|
|
380
|
-
*
|
|
381
|
-
* // Reference to anonymous function inside MinValidator
|
|
382
|
-
* const minValidator = Validators.min(3);
|
|
383
|
-
* const ctrl = new FormControl<number | null>(0, minValidator);
|
|
384
|
-
* expect(ctrl.hasValidator(minValidator)).toEqual(true)
|
|
385
|
-
* expect(ctrl.hasValidator(Validators.min(3))).toEqual(false)
|
|
386
|
-
* ```
|
|
387
|
-
*
|
|
388
|
-
* @param validator The validator to check for presence. Compared by function reference.
|
|
389
|
-
* @returns Whether the provided validator was found on this control.
|
|
390
|
-
*/
|
|
391
|
-
hasValidator(validator) {
|
|
392
|
-
return hasValidator(this._rawValidators, validator);
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* Check whether an asynchronous validator function is present on this control. The provided
|
|
396
|
-
* validator must be a reference to the exact same function that was provided.
|
|
397
|
-
*
|
|
398
|
-
* @param validator The asynchronous validator to check for presence. Compared by function
|
|
399
|
-
* reference.
|
|
400
|
-
* @returns Whether the provided asynchronous validator was found on this control.
|
|
401
|
-
*/
|
|
402
|
-
hasAsyncValidator(validator) {
|
|
403
|
-
return hasValidator(this._rawAsyncValidators, validator);
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Empties out the synchronous validator list.
|
|
407
|
-
*
|
|
408
|
-
* When you add or remove a validator at run time, you must call
|
|
409
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
410
|
-
*
|
|
411
|
-
*/
|
|
412
|
-
clearValidators() {
|
|
413
|
-
this.validator = null;
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Empties out the async validator list.
|
|
417
|
-
*
|
|
418
|
-
* When you add or remove a validator at run time, you must call
|
|
419
|
-
* `updateValueAndValidity()` for the new validation to take effect.
|
|
420
|
-
*
|
|
421
|
-
*/
|
|
422
|
-
clearAsyncValidators() {
|
|
423
|
-
this.asyncValidator = null;
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Marks the control as `touched`. A control is touched by focus and
|
|
427
|
-
* blur events that do not change the value.
|
|
428
|
-
*
|
|
429
|
-
* @see `markAsUntouched()`
|
|
430
|
-
* @see `markAsDirty()`
|
|
431
|
-
* @see `markAsPristine()`
|
|
432
|
-
*
|
|
433
|
-
* @param opts Configuration options that determine how the control propagates changes
|
|
434
|
-
* and emits events after marking is applied.
|
|
435
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
436
|
-
* marks all direct ancestors. Default is false.
|
|
437
|
-
*/
|
|
438
|
-
markAsTouched(opts = {}) {
|
|
439
|
-
this.touched = true;
|
|
440
|
-
if (this._parent && !opts.onlySelf) {
|
|
441
|
-
this._parent.markAsTouched(opts);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Marks the control and all its descendant controls as `touched`.
|
|
446
|
-
* @see `markAsTouched()`
|
|
447
|
-
*/
|
|
448
|
-
markAllAsTouched() {
|
|
449
|
-
this.markAsTouched({ onlySelf: true });
|
|
450
|
-
this._forEachChild((control) => control.markAllAsTouched());
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Marks the control as `untouched`.
|
|
454
|
-
*
|
|
455
|
-
* If the control has any children, also marks all children as `untouched`
|
|
456
|
-
* and recalculates the `touched` status of all parent controls.
|
|
457
|
-
*
|
|
458
|
-
* @see `markAsTouched()`
|
|
459
|
-
* @see `markAsDirty()`
|
|
460
|
-
* @see `markAsPristine()`
|
|
461
|
-
*
|
|
462
|
-
* @param opts Configuration options that determine how the control propagates changes
|
|
463
|
-
* and emits events after the marking is applied.
|
|
464
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
465
|
-
* marks all direct ancestors. Default is false.
|
|
466
|
-
*/
|
|
467
|
-
markAsUntouched(opts = {}) {
|
|
468
|
-
this.touched = false;
|
|
469
|
-
this._pendingTouched = false;
|
|
470
|
-
this._forEachChild((control) => {
|
|
471
|
-
control.markAsUntouched({ onlySelf: true });
|
|
472
|
-
});
|
|
473
|
-
if (this._parent && !opts.onlySelf) {
|
|
474
|
-
this._parent._updateTouched(opts);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
/**
|
|
478
|
-
* Marks the control as `dirty`. A control becomes dirty when
|
|
479
|
-
* the control's value is changed through the UI; compare `markAsTouched`.
|
|
480
|
-
*
|
|
481
|
-
* @see `markAsTouched()`
|
|
482
|
-
* @see `markAsUntouched()`
|
|
483
|
-
* @see `markAsPristine()`
|
|
484
|
-
*
|
|
485
|
-
* @param opts Configuration options that determine how the control propagates changes
|
|
486
|
-
* and emits events after marking is applied.
|
|
487
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
488
|
-
* marks all direct ancestors. Default is false.
|
|
489
|
-
*/
|
|
490
|
-
markAsDirty(opts = {}) {
|
|
491
|
-
this.pristine = false;
|
|
492
|
-
if (this._parent && !opts.onlySelf) {
|
|
493
|
-
this._parent.markAsDirty(opts);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Marks the control as `pristine`.
|
|
498
|
-
*
|
|
499
|
-
* If the control has any children, marks all children as `pristine`,
|
|
500
|
-
* and recalculates the `pristine` status of all parent
|
|
501
|
-
* controls.
|
|
502
|
-
*
|
|
503
|
-
* @see `markAsTouched()`
|
|
504
|
-
* @see `markAsUntouched()`
|
|
505
|
-
* @see `markAsDirty()`
|
|
506
|
-
*
|
|
507
|
-
* @param opts Configuration options that determine how the control emits events after
|
|
508
|
-
* marking is applied.
|
|
509
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
510
|
-
* marks all direct ancestors. Default is false.
|
|
511
|
-
*/
|
|
512
|
-
markAsPristine(opts = {}) {
|
|
513
|
-
this.pristine = true;
|
|
514
|
-
this._pendingDirty = false;
|
|
515
|
-
this._forEachChild((control) => {
|
|
516
|
-
control.markAsPristine({ onlySelf: true });
|
|
517
|
-
});
|
|
518
|
-
if (this._parent && !opts.onlySelf) {
|
|
519
|
-
this._parent._updatePristine(opts);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Marks the control as `pending`.
|
|
524
|
-
*
|
|
525
|
-
* A control is pending while the control performs async validation.
|
|
526
|
-
*
|
|
527
|
-
* @see {@link AbstractControl.status}
|
|
528
|
-
*
|
|
529
|
-
* @param opts Configuration options that determine how the control propagates changes and
|
|
530
|
-
* emits events after marking is applied.
|
|
531
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
532
|
-
* marks all direct ancestors. Default is false.
|
|
533
|
-
* * `emitEvent`: When true or not supplied (the default), the `statusChanges`
|
|
534
|
-
* observable emits an event with the latest status the control is marked pending.
|
|
535
|
-
* When false, no events are emitted.
|
|
536
|
-
*
|
|
537
|
-
*/
|
|
538
|
-
markAsPending(opts = {}) {
|
|
539
|
-
this.status = PENDING;
|
|
540
|
-
if (opts.emitEvent !== false) {
|
|
541
|
-
this.statusChanges.emit(this.status);
|
|
542
|
-
}
|
|
543
|
-
if (this._parent && !opts.onlySelf) {
|
|
544
|
-
this._parent.markAsPending(opts);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
/**
|
|
548
|
-
* Disables the control. This means the control is exempt from validation checks and
|
|
549
|
-
* excluded from the aggregate value of any parent. Its status is `DISABLED`.
|
|
550
|
-
*
|
|
551
|
-
* If the control has children, all children are also disabled.
|
|
552
|
-
*
|
|
553
|
-
* @see {@link AbstractControl.status}
|
|
554
|
-
*
|
|
555
|
-
* @param opts Configuration options that determine how the control propagates
|
|
556
|
-
* changes and emits events after the control is disabled.
|
|
557
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
558
|
-
* marks all direct ancestors. Default is false.
|
|
559
|
-
* * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
|
|
560
|
-
* `valueChanges`
|
|
561
|
-
* observables emit events with the latest status and value when the control is disabled.
|
|
562
|
-
* When false, no events are emitted.
|
|
563
|
-
*/
|
|
564
|
-
disable(opts = {}) {
|
|
565
|
-
// If parent has been marked artificially dirty we don't want to re-calculate the
|
|
566
|
-
// parent's dirtiness based on the children.
|
|
567
|
-
const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
|
|
568
|
-
this.status = DISABLED;
|
|
569
|
-
this.errors = null;
|
|
570
|
-
this._forEachChild((control) => {
|
|
571
|
-
control.disable({ ...opts, onlySelf: true });
|
|
572
|
-
});
|
|
573
|
-
this._updateValue();
|
|
574
|
-
if (opts.emitEvent !== false) {
|
|
575
|
-
this.valueChanges.emit(this.value);
|
|
576
|
-
this.statusChanges.emit(this.status);
|
|
577
|
-
}
|
|
578
|
-
this._updateAncestors({ ...opts, skipPristineCheck });
|
|
579
|
-
this._onDisabledChange.forEach((changeFn) => changeFn(true));
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* Enables the control. This means the control is included in validation checks and
|
|
583
|
-
* the aggregate value of its parent. Its status recalculates based on its value and
|
|
584
|
-
* its validators.
|
|
585
|
-
*
|
|
586
|
-
* By default, if the control has children, all children are enabled.
|
|
587
|
-
*
|
|
588
|
-
* @see {@link AbstractControl.status}
|
|
589
|
-
*
|
|
590
|
-
* @param opts Configure options that control how the control propagates changes and
|
|
591
|
-
* emits events when marked as untouched
|
|
592
|
-
* * `onlySelf`: When true, mark only this control. When false or not supplied,
|
|
593
|
-
* marks all direct ancestors. Default is false.
|
|
594
|
-
* * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
|
|
595
|
-
* `valueChanges`
|
|
596
|
-
* observables emit events with the latest status and value when the control is enabled.
|
|
597
|
-
* When false, no events are emitted.
|
|
598
|
-
*/
|
|
599
|
-
enable(opts = {}) {
|
|
600
|
-
// If parent has been marked artificially dirty we don't want to re-calculate the
|
|
601
|
-
// parent's dirtiness based on the children.
|
|
602
|
-
const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
|
|
603
|
-
this.status = VALID;
|
|
604
|
-
this._forEachChild((control) => {
|
|
605
|
-
control.enable({ ...opts, onlySelf: true });
|
|
606
|
-
});
|
|
607
|
-
this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
|
|
608
|
-
this._updateAncestors({ ...opts, skipPristineCheck });
|
|
609
|
-
this._onDisabledChange.forEach((changeFn) => changeFn(false));
|
|
610
|
-
}
|
|
611
|
-
_updateAncestors(opts) {
|
|
612
|
-
if (this._parent && !opts.onlySelf) {
|
|
613
|
-
this._parent.updateValueAndValidity(opts);
|
|
614
|
-
if (!opts.skipPristineCheck) {
|
|
615
|
-
this._parent._updatePristine();
|
|
616
|
-
}
|
|
617
|
-
this._parent._updateTouched();
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* Sets the parent of the control
|
|
622
|
-
*
|
|
623
|
-
* @param parent The new parent.
|
|
624
|
-
*/
|
|
625
|
-
setParent(parent) {
|
|
626
|
-
this._parent = parent;
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* The raw value of this control. For most control implementations, the raw value will include
|
|
630
|
-
* disabled children.
|
|
631
|
-
*/
|
|
632
|
-
getRawValue() {
|
|
633
|
-
return this.value;
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* Recalculates the value and validation status of the control.
|
|
637
|
-
*
|
|
638
|
-
* By default, it also updates the value and validity of its ancestors.
|
|
639
|
-
*
|
|
640
|
-
* @param opts Configuration options determine how the control propagates changes and emits events
|
|
641
|
-
* after updates and validity checks are applied.
|
|
642
|
-
* * `onlySelf`: When true, only update this control. When false or not supplied,
|
|
643
|
-
* update all direct ancestors. Default is false.
|
|
644
|
-
* * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
|
|
645
|
-
* `valueChanges`
|
|
646
|
-
* observables emit events with the latest status and value when the control is updated.
|
|
647
|
-
* When false, no events are emitted.
|
|
648
|
-
*/
|
|
649
|
-
updateValueAndValidity(opts = {}) {
|
|
650
|
-
this._setInitialStatus();
|
|
651
|
-
this._updateValue();
|
|
652
|
-
if (this.enabled) {
|
|
653
|
-
this._cancelExistingSubscription();
|
|
654
|
-
this.errors = this._runValidator();
|
|
655
|
-
this.status = this._calculateStatus();
|
|
656
|
-
if (this.status === VALID || this.status === PENDING) {
|
|
657
|
-
this._runAsyncValidator(opts.emitEvent);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
if (opts.emitEvent !== false) {
|
|
661
|
-
this.valueChanges.emit(this.value);
|
|
662
|
-
this.statusChanges.emit(this.status);
|
|
663
|
-
}
|
|
664
|
-
if (this._parent && !opts.onlySelf) {
|
|
665
|
-
this._parent.updateValueAndValidity(opts);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
/** @internal */
|
|
669
|
-
_updateTreeValidity(opts = { emitEvent: true }) {
|
|
670
|
-
this._forEachChild((ctrl) => ctrl._updateTreeValidity(opts));
|
|
671
|
-
this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
|
|
672
|
-
}
|
|
673
|
-
_setInitialStatus() {
|
|
674
|
-
this.status = this._allControlsDisabled() ? DISABLED : VALID;
|
|
675
|
-
}
|
|
676
|
-
_runValidator() {
|
|
677
|
-
return this.validator ? this.validator(this) : null;
|
|
678
|
-
}
|
|
679
|
-
_runAsyncValidator(emitEvent) {
|
|
680
|
-
if (this.asyncValidator) {
|
|
681
|
-
this.status = PENDING;
|
|
682
|
-
this._hasOwnPendingAsyncValidator = true;
|
|
683
|
-
const obs = toObservable(this.asyncValidator(this));
|
|
684
|
-
this._asyncValidationSubscription = obs.subscribe((errors) => {
|
|
685
|
-
this._hasOwnPendingAsyncValidator = false;
|
|
686
|
-
// This will trigger the recalculation of the validation status, which depends on
|
|
687
|
-
// the state of the asynchronous validation (whether it is in progress or not). So, it is
|
|
688
|
-
// necessary that we have updated the `_hasOwnPendingAsyncValidator` boolean flag first.
|
|
689
|
-
this.setErrors(errors, { emitEvent });
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
_cancelExistingSubscription() {
|
|
694
|
-
if (this._asyncValidationSubscription) {
|
|
695
|
-
this._asyncValidationSubscription.unsubscribe();
|
|
696
|
-
this._hasOwnPendingAsyncValidator = false;
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
/**
|
|
700
|
-
* Sets errors on a form control when running validations manually, rather than automatically.
|
|
701
|
-
*
|
|
702
|
-
* Calling `setErrors` also updates the validity of the parent control.
|
|
703
|
-
*
|
|
704
|
-
* @param opts Configuration options that determine how the control propagates
|
|
705
|
-
* changes and emits events after the control errors are set.
|
|
706
|
-
* * `emitEvent`: When true or not supplied (the default), the `statusChanges`
|
|
707
|
-
* observable emits an event after the errors are set.
|
|
708
|
-
*
|
|
709
|
-
* @usageNotes
|
|
710
|
-
*
|
|
711
|
-
* ### Manually set the errors for a control
|
|
712
|
-
*
|
|
713
|
-
* ```
|
|
714
|
-
* const login = new FormControl('someLogin');
|
|
715
|
-
* login.setErrors({
|
|
716
|
-
* notUnique: true
|
|
717
|
-
* });
|
|
718
|
-
*
|
|
719
|
-
* expect(login.valid).toEqual(false);
|
|
720
|
-
* expect(login.errors).toEqual({ notUnique: true });
|
|
721
|
-
*
|
|
722
|
-
* login.setValue('someOtherLogin');
|
|
723
|
-
*
|
|
724
|
-
* expect(login.valid).toEqual(true);
|
|
725
|
-
* ```
|
|
726
|
-
*/
|
|
727
|
-
setErrors(errors, opts = {}) {
|
|
728
|
-
this.errors = errors;
|
|
729
|
-
this._updateControlsErrors(opts.emitEvent !== false);
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
* Retrieves a child control given the control's name or path.
|
|
733
|
-
*
|
|
734
|
-
* @param path A dot-delimited string or array of string/number values that define the path to the
|
|
735
|
-
* control. If a string is provided, passing it as a string literal will result in improved type
|
|
736
|
-
* information. Likewise, if an array is provided, passing it `as const` will cause improved type
|
|
737
|
-
* information to be available.
|
|
738
|
-
*
|
|
739
|
-
* @usageNotes
|
|
740
|
-
* ### Retrieve a nested control
|
|
741
|
-
*
|
|
742
|
-
* For example, to get a `name` control nested within a `person` sub-group:
|
|
743
|
-
*
|
|
744
|
-
* * `this.form.get('person.name');`
|
|
745
|
-
*
|
|
746
|
-
* -OR-
|
|
747
|
-
*
|
|
748
|
-
* * `this.form.get(['person', 'name'] as const);` // `as const` gives improved typings
|
|
749
|
-
*
|
|
750
|
-
* ### Retrieve a control in a FormArray
|
|
751
|
-
*
|
|
752
|
-
* When accessing an element inside a FormArray, you can use an element index.
|
|
753
|
-
* For example, to get a `price` control from the first element in an `items` array you can use:
|
|
754
|
-
*
|
|
755
|
-
* * `this.form.get('items.0.price');`
|
|
756
|
-
*
|
|
757
|
-
* -OR-
|
|
758
|
-
*
|
|
759
|
-
* * `this.form.get(['items', 0, 'price']);`
|
|
760
|
-
*/
|
|
761
|
-
get(path) {
|
|
762
|
-
let currPath = path;
|
|
763
|
-
if (currPath == null)
|
|
764
|
-
return null;
|
|
765
|
-
if (!Array.isArray(currPath))
|
|
766
|
-
currPath = currPath.split('.');
|
|
767
|
-
if (currPath.length === 0)
|
|
768
|
-
return null;
|
|
769
|
-
return currPath.reduce((control, name) => control && control._find(name), this);
|
|
770
|
-
}
|
|
771
|
-
/**
|
|
772
|
-
* @description
|
|
773
|
-
* Reports error data for the control with the given path.
|
|
774
|
-
*
|
|
775
|
-
* @param errorCode The code of the error to check
|
|
776
|
-
* @param path A list of control names that designates how to move from the current control
|
|
777
|
-
* to the control that should be queried for errors.
|
|
778
|
-
*
|
|
779
|
-
* @usageNotes
|
|
780
|
-
* For example, for the following `FormGroup`:
|
|
781
|
-
*
|
|
782
|
-
* ```
|
|
783
|
-
* form = new FormGroup({
|
|
784
|
-
* address: new FormGroup({ street: new FormControl() })
|
|
785
|
-
* });
|
|
786
|
-
* ```
|
|
787
|
-
*
|
|
788
|
-
* The path to the 'street' control from the root form would be 'address' -> 'street'.
|
|
789
|
-
*
|
|
790
|
-
* It can be provided to this method in one of two formats:
|
|
791
|
-
*
|
|
792
|
-
* 1. An array of string control names, e.g. `['address', 'street']`
|
|
793
|
-
* 1. A period-delimited list of control names in one string, e.g. `'address.street'`
|
|
794
|
-
*
|
|
795
|
-
* @returns error data for that particular error. If the control or error is not present,
|
|
796
|
-
* null is returned.
|
|
797
|
-
*/
|
|
798
|
-
getError(errorCode, path) {
|
|
799
|
-
const control = path ? this.get(path) : this;
|
|
800
|
-
return control && control.errors ? control.errors[errorCode] : null;
|
|
801
|
-
}
|
|
802
|
-
/**
|
|
803
|
-
* @description
|
|
804
|
-
* Reports whether the control with the given path has the error specified.
|
|
805
|
-
*
|
|
806
|
-
* @param errorCode The code of the error to check
|
|
807
|
-
* @param path A list of control names that designates how to move from the current control
|
|
808
|
-
* to the control that should be queried for errors.
|
|
809
|
-
*
|
|
810
|
-
* @usageNotes
|
|
811
|
-
* For example, for the following `FormGroup`:
|
|
812
|
-
*
|
|
813
|
-
* ```
|
|
814
|
-
* form = new FormGroup({
|
|
815
|
-
* address: new FormGroup({ street: new FormControl() })
|
|
816
|
-
* });
|
|
817
|
-
* ```
|
|
818
|
-
*
|
|
819
|
-
* The path to the 'street' control from the root form would be 'address' -> 'street'.
|
|
820
|
-
*
|
|
821
|
-
* It can be provided to this method in one of two formats:
|
|
822
|
-
*
|
|
823
|
-
* 1. An array of string control names, e.g. `['address', 'street']`
|
|
824
|
-
* 1. A period-delimited list of control names in one string, e.g. `'address.street'`
|
|
825
|
-
*
|
|
826
|
-
* If no path is given, this method checks for the error on the current control.
|
|
827
|
-
*
|
|
828
|
-
* @returns whether the given error is present in the control at the given path.
|
|
829
|
-
*
|
|
830
|
-
* If the control is not present, false is returned.
|
|
831
|
-
*/
|
|
832
|
-
hasError(errorCode, path) {
|
|
833
|
-
return !!this.getError(errorCode, path);
|
|
834
|
-
}
|
|
835
|
-
/**
|
|
836
|
-
* Retrieves the top-level ancestor of this control.
|
|
837
|
-
*/
|
|
838
|
-
get root() {
|
|
839
|
-
let x = this;
|
|
840
|
-
while (x._parent) {
|
|
841
|
-
x = x._parent;
|
|
842
|
-
}
|
|
843
|
-
return x;
|
|
844
|
-
}
|
|
845
|
-
/** @internal */
|
|
846
|
-
_updateControlsErrors(emitEvent) {
|
|
847
|
-
this.status = this._calculateStatus();
|
|
848
|
-
if (emitEvent) {
|
|
849
|
-
this.statusChanges.emit(this.status);
|
|
850
|
-
}
|
|
851
|
-
if (this._parent) {
|
|
852
|
-
this._parent._updateControlsErrors(emitEvent);
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
/** @internal */
|
|
856
|
-
_initObservables() {
|
|
857
|
-
this.valueChanges = new EventEmitter();
|
|
858
|
-
this.statusChanges = new EventEmitter();
|
|
859
|
-
}
|
|
860
|
-
_calculateStatus() {
|
|
861
|
-
if (this._allControlsDisabled())
|
|
862
|
-
return DISABLED;
|
|
863
|
-
if (this.errors)
|
|
864
|
-
return INVALID;
|
|
865
|
-
if (this._hasOwnPendingAsyncValidator || this._anyControlsHaveStatus(PENDING))
|
|
866
|
-
return PENDING;
|
|
867
|
-
if (this._anyControlsHaveStatus(INVALID))
|
|
868
|
-
return INVALID;
|
|
869
|
-
return VALID;
|
|
870
|
-
}
|
|
871
|
-
/** @internal */
|
|
872
|
-
_anyControlsHaveStatus(status) {
|
|
873
|
-
return this._anyControls((control) => control.status === status);
|
|
874
|
-
}
|
|
875
|
-
/** @internal */
|
|
876
|
-
_anyControlsDirty() {
|
|
877
|
-
return this._anyControls((control) => control.dirty);
|
|
878
|
-
}
|
|
879
|
-
/** @internal */
|
|
880
|
-
_anyControlsTouched() {
|
|
881
|
-
return this._anyControls((control) => control.touched);
|
|
882
|
-
}
|
|
883
|
-
/** @internal */
|
|
884
|
-
_updatePristine(opts = {}) {
|
|
885
|
-
this.pristine = !this._anyControlsDirty();
|
|
886
|
-
if (this._parent && !opts.onlySelf) {
|
|
887
|
-
this._parent._updatePristine(opts);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
/** @internal */
|
|
891
|
-
_updateTouched(opts = {}) {
|
|
892
|
-
this.touched = this._anyControlsTouched();
|
|
893
|
-
if (this._parent && !opts.onlySelf) {
|
|
894
|
-
this._parent._updateTouched(opts);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
/** @internal */
|
|
898
|
-
_registerOnCollectionChange(fn) {
|
|
899
|
-
this._onCollectionChange = fn;
|
|
900
|
-
}
|
|
901
|
-
/** @internal */
|
|
902
|
-
_setUpdateStrategy(opts) {
|
|
903
|
-
if (isOptionsObj(opts) && opts.updateOn != null) {
|
|
904
|
-
this._updateOn = opts.updateOn;
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
/**
|
|
908
|
-
* Check to see if parent has been marked artificially dirty.
|
|
909
|
-
*
|
|
910
|
-
* @internal
|
|
911
|
-
*/
|
|
912
|
-
_parentMarkedDirty(onlySelf) {
|
|
913
|
-
const parentDirty = this._parent && this._parent.dirty;
|
|
914
|
-
return !onlySelf && !!parentDirty && !this._parent._anyControlsDirty();
|
|
915
|
-
}
|
|
916
|
-
/** @internal */
|
|
917
|
-
_find(name) {
|
|
918
|
-
return null;
|
|
919
|
-
}
|
|
920
|
-
/**
|
|
921
|
-
* Internal implementation of the `setValidators` method. Needs to be separated out into a
|
|
922
|
-
* different method, because it is called in the constructor and it can break cases where
|
|
923
|
-
* a control is extended.
|
|
924
|
-
*/
|
|
925
|
-
_assignValidators(validators) {
|
|
926
|
-
this._rawValidators = Array.isArray(validators) ? validators.slice() : validators;
|
|
927
|
-
this._composedValidatorFn = coerceToValidator(this._rawValidators);
|
|
928
|
-
}
|
|
929
|
-
/**
|
|
930
|
-
* Internal implementation of the `setAsyncValidators` method. Needs to be separated out into a
|
|
931
|
-
* different method, because it is called in the constructor and it can break cases where
|
|
932
|
-
* a control is extended.
|
|
933
|
-
*/
|
|
934
|
-
_assignAsyncValidators(validators) {
|
|
935
|
-
this._rawAsyncValidators = Array.isArray(validators) ? validators.slice() : validators;
|
|
936
|
-
this._composedAsyncValidatorFn = coerceToAsyncValidator(this._rawAsyncValidators);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RfbW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9mb3Jtcy9zcmMvbW9kZWwvYWJzdHJhY3RfbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLFlBQVksRUFBRSxhQUFhLElBQUksWUFBWSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRzFFLE9BQU8sRUFBQyxxQ0FBcUMsRUFBRSxtQkFBbUIsRUFBRSx3QkFBd0IsRUFBRSxlQUFlLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQztBQUlwSixPQUFPLEVBQUMsYUFBYSxFQUFFLHNCQUFzQixFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFckksTUFBTSxXQUFXLEdBQUcsT0FBTyxTQUFTLEtBQUssV0FBVyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFFcEU7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUM7QUFFN0I7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUM7QUFFakM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQztBQUVqQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDO0FBbUJuQzs7R0FFRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsZUFDSTtJQUNqQyxPQUFPLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDaEcsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxTQUF5QztJQUNsRSxP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SUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFDdkQsT0FBTyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQVEsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzFFLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsS0FBSyxDQUFDLElBQW1CO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxpQkFBaUIsQ0FBQyxVQUEwQztRQUNsRSxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO1FBQ2xGLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxzQkFBc0IsQ0FBQyxVQUFvRDtRQUNqRixJQUFJLENBQUMsbUJBQW1CLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7UUFDdkYsSUFBSSxDQUFDLHlCQUF5QixHQUFHLHNCQUFzQixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0V2ZW50RW1pdHRlciwgybVSdW50aW1lRXJyb3IgYXMgUnVudGltZUVycm9yfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7T2JzZXJ2YWJsZX0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7YXN5bmNWYWxpZGF0b3JzRHJvcHBlZFdpdGhPcHRzV2FybmluZywgbWlzc2luZ0NvbnRyb2xFcnJvciwgbWlzc2luZ0NvbnRyb2xWYWx1ZUVycm9yLCBub0NvbnRyb2xzRXJyb3J9IGZyb20gJy4uL2RpcmVjdGl2ZXMvcmVhY3RpdmVfZXJyb3JzJztcbmltcG9ydCB7QXN5bmNWYWxpZGF0b3JGbiwgVmFsaWRhdGlvbkVycm9ycywgVmFsaWRhdG9yRm59IGZyb20gJy4uL2RpcmVjdGl2ZXMvdmFsaWRhdG9ycyc7XG5pbXBvcnQge1J1bnRpbWVFcnJvckNvZGV9IGZyb20gJy4uL2Vycm9ycyc7XG5pbXBvcnQge0Zvcm1BcnJheSwgRm9ybUdyb3VwfSBmcm9tICcuLi9mb3Jtcyc7XG5pbXBvcnQge2FkZFZhbGlkYXRvcnMsIGNvbXBvc2VBc3luY1ZhbGlkYXRvcnMsIGNvbXBvc2VWYWxpZGF0b3JzLCBoYXNWYWxpZGF0b3IsIHJlbW92ZVZhbGlkYXRvcnMsIHRvT2JzZXJ2YWJsZX0gZnJvbSAnLi4vdmFsaWRhdG9ycyc7XG5cbmNvbnN0IE5HX0RFVl9NT0RFID0gdHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgISFuZ0Rldk1vZGU7XG5cbi8qKlxuICogUmVwb3J0cyB0aGF0IGEgY29udHJvbCBpcyB2YWxpZCwgbWVhbmluZyB0aGF0IG5vIGVycm9ycyBleGlzdCBpbiB0aGUgaW5wdXQgdmFsdWUuXG4gKlxuICogQHNlZSBgc3RhdHVzYFxuICovXG5leHBvcnQgY29uc3QgVkFMSUQgPSAnVkFMSUQnO1xuXG4vKipcbiAqIFJlcG9ydHMgdGhhdCBhIGNvbnRyb2wgaXMgaW52YWxpZCwgbWVhbmluZyB0aGF0IGFuIGVycm9yIGV4aXN0cyBpbiB0aGUgaW5wdXQgdmFsdWUuXG4gKlxuICogQHNlZSBgc3RhdHVzYFxuICovXG5leHBvcnQgY29uc3QgSU5WQUxJRCA9ICdJTlZBTElEJztcblxuLyoqXG4gKiBSZXBvcnRzIHRoYXQgYSBjb250cm9sIGlzIHBlbmRpbmcsIG1lYW5pbmcgdGhhdCB0aGF0IGFzeW5jIHZhbGlkYXRpb24gaXMgb2NjdXJyaW5nIGFuZFxuICogZXJyb3JzIGFyZSBub3QgeWV0IGF2YWlsYWJsZSBmb3IgdGhlIGlucHV0IHZhbHVlLlxuICpcbiAqIEBzZWUgYG1hcmtBc1BlbmRpbmdgXG4gKiBAc2VlIGBzdGF0dXNgXG4gKi9cbmV4cG9ydCBjb25zdCBQRU5ESU5HID0gJ1BFTkRJTkcnO1xuXG4vKipcbiAqIFJlcG9ydHMgdGhhdCBhIGNvbnRyb2wgaXMgZGlzYWJsZWQsIG1lYW5pbmcgdGhhdCB0aGUgY29udHJvbCBpcyBleGVtcHQgZnJvbSBhbmNlc3RvclxuICogY2FsY3VsYXRpb25zIG9mIHZhbGlkaXR5IG9yIHZhbHVlLlxuICpcbiAqIEBzZWUgYG1hcmtBc0Rpc2FibGVkYFxuICogQHNlZSBgc3RhdHVzYFxuICovXG5leHBvcnQgY29uc3QgRElTQUJMRUQgPSAnRElTQUJMRUQnO1xuXG4vKipcbiAqIEEgZm9ybSBjYW4gaGF2ZSBzZXZlcmFsIGRpZmZlcmVudCBzdGF0dXNlcy4gRWFjaFxuICogcG9zc2libGUgc3RhdHVzIGlzIHJldHVybmVkIGFzIGEgc3RyaW5nIGxpdGVyYWwuXG4gKlxuICogKiAqKlZBTElEKio6IFJlcG9ydHMgdGhhdCBhIGNvbnRyb2wgaXMgdmFsaWQsIG1lYW5pbmcgdGhhdCBubyBlcnJvcnMgZXhpc3QgaW4gdGhlIGlucHV0XG4gKiB2YWx1ZS5cbiAqICogKipJTlZBTElEKio6IFJlcG9ydHMgdGhhdCBhIGNvbnRyb2wgaXMgaW52YWxpZCwgbWVhbmluZyB0aGF0IGFuIGVycm9yIGV4aXN0cyBpbiB0aGUgaW5wdXRcbiAqIHZhbHVlLlxuICogKiAqKlBFTkRJTkcqKjogUmVwb3J0cyB0aGF0IGEgY29udHJvbCBpcyBwZW5kaW5nLCBtZWFuaW5nIHRoYXQgdGhhdCBhc3luYyB2YWxpZGF0aW9uIGlzXG4gKiBvY2N1cnJpbmcgYW5kIGVycm9ycyBhcmUgbm90IHlldCBhdmFpbGFibGUgZm9yIHRoZSBpbnB1dCB2YWx1ZS5cbiAqICogKipESVNBQkxFRCoqOiBSZXBvcnRzIHRoYXQgYSBjb250cm9sIGlzXG4gKiBkaXNhYmxlZCwgbWVhbmluZyB0aGF0IHRoZSBjb250cm9sIGlzIGV4ZW1wdCBmcm9tIGFuY2VzdG9yIGNhbGN1bGF0aW9ucyBvZiB2YWxpZGl0eSBvciB2YWx1ZS5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCB0eXBlIEZvcm1Db250cm9sU3RhdHVzID0gJ1ZBTElEJ3wnSU5WQUxJRCd8J1BFTkRJTkcnfCdESVNBQkxFRCc7XG5cbi8qKlxuICogR2V0cyB2YWxpZGF0b3JzIGZyb20gZWl0aGVyIGFuIG9wdGlvbnMgb2JqZWN0IG9yIGdpdmVuIHZhbGlkYXRvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwaWNrVmFsaWRhdG9ycyh2YWxpZGF0b3JPck9wdHM/OiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdfEFic3RyYWN0Q29udHJvbE9wdGlvbnN8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk6IFZhbGlkYXRvckZufFZhbGlkYXRvckZuW118bnVsbCB7XG4gIHJldHVybiAoaXNPcHRpb25zT2JqKHZhbGlkYXRvck9yT3B0cykgPyB2YWxpZGF0b3JPck9wdHMudmFsaWRhdG9ycyA6IHZhbGlkYXRvck9yT3B0cykgfHwgbnVsbDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHZhbGlkYXRvciBmdW5jdGlvbiBieSBjb21iaW5pbmcgcHJvdmlkZWQgdmFsaWRhdG9ycy5cbiAqL1xuZnVuY3Rpb24gY29lcmNlVG9WYWxpZGF0b3IodmFsaWRhdG9yOiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdfG51bGwpOiBWYWxpZGF0b3JGbnxudWxsIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsaWRhdG9yKSA/IGNvbXBvc2VWYWxpZGF0b3JzKHZhbGlkYXRvcikgOiB2YWxpZGF0b3IgfHwgbnVsbDtcbn1cblxuLyoqXG4gKiBHZXRzIGFzeW5jIHZhbGlkYXRvcnMgZnJvbSBlaXRoZXIgYW4gb3B0aW9ucyBvYmplY3Qgb3IgZ2l2ZW4gdmFsaWRhdG9ycy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBpY2tBc3luY1ZhbGlkYXRvcnMoXG4gICAgYXN5bmNWYWxpZGF0b3I/OiBBc3luY1ZhbGlkYXRvckZufEFzeW5jVmFsaWRhdG9yRm5bXXxudWxsLFxuICAgIHZhbGlkYXRvck9yT3B0cz86IFZhbGlkYXRvckZufFZhbGlkYXRvckZuW118QWJzdHJhY3RDb250cm9sT3B0aW9uc3xudWxsKTogQXN5bmNWYWxpZGF0b3JGbnxcbiAgICBBc3luY1ZhbGlkYXRvckZuW118bnVsbCB7XG4gIGlmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpIHtcbiAgICBpZiAoaXNPcHRpb25zT2JqKHZhbGlkYXRvck9yT3B0cykgJiYgYXN5bmNWYWxpZGF0b3IpIHtcbiAgICAgIGNvbnNvbGUud2Fybihhc3luY1ZhbGlkYXRvcnNEcm9wcGVkV2l0aE9wdHNXYXJuaW5nKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIChpc09wdGlvbnNPYmoodmFsaWRhdG9yT3JPcHRzKSA/IHZhbGlkYXRvck9yT3B0cy5hc3luY1ZhbGlkYXRvcnMgOiBhc3luY1ZhbGlkYXRvcikgfHwgbnVsbDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFzeW5jIHZhbGlkYXRvciBmdW5jdGlvbiBieSBjb21iaW5pbmcgcHJvdmlkZWQgYXN5bmMgdmFsaWRhdG9ycy5cbiAqL1xuZnVuY3Rpb24gY29lcmNlVG9Bc3luY1ZhbGlkYXRvcihhc3luY1ZhbGlkYXRvcj86IEFzeW5jVmFsaWRhdG9yRm58QXN5bmNWYWxpZGF0b3JGbltdfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTogQXN5bmNWYWxpZGF0b3JGbnxudWxsIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXN5bmNWYWxpZGF0b3IpID8gY29tcG9zZUFzeW5jVmFsaWRhdG9ycyhhc3luY1ZhbGlkYXRvcikgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3luY1ZhbGlkYXRvciB8fCBudWxsO1xufVxuXG5leHBvcnQgdHlwZSBGb3JtSG9va3MgPSAnY2hhbmdlJ3wnYmx1cid8J3N1Ym1pdCc7XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBvcHRpb25zIHByb3ZpZGVkIHRvIGFuIGBBYnN0cmFjdENvbnRyb2xgLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBYnN0cmFjdENvbnRyb2xPcHRpb25zIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBUaGUgbGlzdCBvZiB2YWxpZGF0b3JzIGFwcGxpZWQgdG8gYSBjb250cm9sLlxuICAgKi9cbiAgdmFsaWRhdG9ycz86IFZhbGlkYXRvckZufFZhbGlkYXRvckZuW118bnVsbDtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBUaGUgbGlzdCBvZiBhc3luYyB2YWxpZGF0b3JzIGFwcGxpZWQgdG8gY29udHJvbC5cbiAgICovXG4gIGFzeW5jVmFsaWRhdG9ycz86IEFzeW5jVmFsaWRhdG9yRm58QXN5bmNWYWxpZGF0b3JGbltdfG51bGw7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogVGhlIGV2ZW50IG5hbWUgZm9yIGNvbnRyb2wgdG8gdXBkYXRlIHVwb24uXG4gICAqL1xuICB1cGRhdGVPbj86ICdjaGFuZ2UnfCdibHVyJ3wnc3VibWl0Jztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzT3B0aW9uc09iaih2YWxpZGF0b3JPck9wdHM/OiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdfEFic3RyYWN0Q29udHJvbE9wdGlvbnN8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOiB2YWxpZGF0b3JPck9wdHMgaXMgQWJzdHJhY3RDb250cm9sT3B0aW9ucyB7XG4gIHJldHVybiB2YWxpZGF0b3JPck9wdHMgIT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWxpZGF0b3JPck9wdHMpICYmXG4gICAgICB0eXBlb2YgdmFsaWRhdG9yT3JPcHRzID09PSAnb2JqZWN0Jztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydENvbnRyb2xQcmVzZW50KHBhcmVudDogYW55LCBpc0dyb3VwOiBib29sZWFuLCBrZXk6IHN0cmluZ3xudW1iZXIpOiB2b2lkIHtcbiAgY29uc3QgY29udHJvbHMgPSBwYXJlbnQuY29udHJvbHMgYXMge1trZXk6IHN0cmluZ3xudW1iZXJdOiB1bmtub3dufTtcbiAgY29uc3QgY29sbGVjdGlvbiA9IGlzR3JvdXAgPyBPYmplY3Qua2V5cyhjb250cm9scykgOiBjb250cm9scztcbiAgaWYgKCFjb2xsZWN0aW9uLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuTk9fQ09OVFJPTFMsIE5HX0RFVl9NT0RFID8gbm9Db250cm9sc0Vycm9yKGlzR3JvdXApIDogJycpO1xuICB9XG4gIGlmICghY29udHJvbHNba2V5XSkge1xuICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuTUlTU0lOR19DT05UUk9MLCBOR19ERVZfTU9ERSA/IG1pc3NpbmdDb250cm9sRXJyb3IoaXNHcm91cCwga2V5KSA6ICcnKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0QWxsVmFsdWVzUHJlc2VudChjb250cm9sOiBhbnksIGlzR3JvdXA6IGJvb2xlYW4sIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgY29udHJvbC5fZm9yRWFjaENoaWxkKChfOiB1bmtub3duLCBrZXk6IHN0cmluZ3xudW1iZXIpID0+IHtcbiAgICBpZiAodmFsdWVba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKFxuICAgICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuTUlTU0lOR19DT05UUk9MX1ZBTFVFLFxuICAgICAgICAgIE5HX0RFVl9NT0RFID8gbWlzc2luZ0NvbnRyb2xWYWx1ZUVycm9yKGlzR3JvdXAsIGtleSkgOiAnJyk7XG4gICAgfVxuICB9KTtcbn1cblxuLy8gSXNBbnkgY2hlY2tzIGlmIFQgaXMgYGFueWAsIGJ5IGNoZWNraW5nIGEgY29uZGl0aW9uIHRoYXQgY291bGRuJ3QgcG9zc2libHkgYmUgdHJ1ZSBvdGhlcndpc2UuXG5leHBvcnQgdHlwZSDJtUlzQW55PFQsIFksIE4+ID0gMCBleHRlbmRzKDEmVCkgPyBZIDogTjtcblxuLyoqXG4gKiBgVHlwZWRPclVudHlwZWRgIGFsbG93cyBvbmUgb2YgdHdvIGRpZmZlcmVudCB0eXBlcyB0byBiZSBzZWxlY3RlZCwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIEZvcm1zXG4gKiBjbGFzcyBpdCdzIGFwcGxpZWQgdG8gaXMgdHlwZWQgb3Igbm90LlxuICpcbiAqIFRoaXMgaXMgZm9yIGludGVybmFsIEFuZ3VsYXIgdXNhZ2UgdG8gc3VwcG9ydCB0eXBlZCBmb3JtczsgZG8gbm90IGRpcmVjdGx5IHVzZSBpdC5cbiAqL1xuZXhwb3J0IHR5cGUgybVUeXBlZE9yVW50eXBlZDxULCBUeXBlZCwgVW50eXBlZD4gPSDJtUlzQW55PFQsIFVudHlwZWQsIFR5cGVkPjtcblxuLyoqXG4gKiBWYWx1ZSBnaXZlcyB0aGUgdmFsdWUgdHlwZSBjb3JyZXNwb25kaW5nIHRvIGEgY29udHJvbCB0eXBlLlxuICpcbiAqIE5vdGUgdGhhdCB0aGUgcmVzdWx0aW5nIHR5cGUgd2lsbCBmb2xsb3cgdGhlIHNhbWUgcnVsZXMgYXMgYC52YWx1ZWAgb24geW91ciBjb250cm9sLCBncm91cCwgb3JcbiAqIGFycmF5LCBpbmNsdWRpbmcgYHVuZGVmaW5lZGAgZm9yIGVhY2ggZ3JvdXAgZWxlbWVudCB3aGljaCBtaWdodCBiZSBkaXNhYmxlZC5cbiAqXG4gKiBJZiB5b3UgYXJlIHRyeWluZyB0byBleHRyYWN0IGEgdmFsdWUgdHlwZSBmb3IgYSBkYXRhIG1vZGVsLCB5b3UgcHJvYmFibHkgd2FudCB7QGxpbmsgUmF3VmFsdWV9LFxuICogd2hpY2ggd2lsbCBub3QgaGF2ZSBgdW5kZWZpbmVkYCBpbiBncm91cCBrZXlzLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogIyMjIGBGb3JtQ29udHJvbGAgdmFsdWUgdHlwZVxuICpcbiAqIFlvdSBjYW4gZXh0cmFjdCB0aGUgdmFsdWUgdHlwZSBvZiBhIHNpbmdsZSBjb250cm9sOlxuICpcbiAqIGBgYHRzXG4gKiB0eXBlIE5hbWVDb250cm9sID0gRm9ybUNvbnRyb2w8c3RyaW5nPjtcbiAqIHR5cGUgTmFtZVZhbHVlID0gVmFsdWU8TmFtZUNvbnRyb2w+O1xuICogYGBgXG4gKlxuICogVGhlIHJlc3VsdGluZyB0eXBlIGlzIGBzdHJpbmdgLlxuICpcbiAqICMjIyBgRm9ybUdyb3VwYCB2YWx1ZSB0eXBlXG4gKlxuICogSW1hZ2luZSB5b3UgaGF2ZSBhbiBpbnRlcmZhY2UgZGVmaW5pbmcgdGhlIGNvbnRyb2xzIGluIHlvdXIgZ3JvdXAuIFlvdSBjYW4gZXh0cmFjdCB0aGUgc2hhcGUgb2ZcbiAqIHRoZSB2YWx1ZXMgYXMgZm9sbG93czpcbiAqXG4gKiBgYGB0c1xuICogaW50ZXJmYWNlIFBhcnR5Rm9ybUNvbnRyb2xzIHtcbiAqICAgYWRkcmVzczogRm9ybUNvbnRyb2w8c3RyaW5nPjtcbiAqIH1cbiAqXG4gKiAvLyBWYWx1ZSBvcGVyYXRlcyBvbiBjb250cm9sczsgdGhlIG9iamVjdCBtdXN0IGJlIHdyYXBwZWQgaW4gYSBGb3JtR3JvdXAuXG4gKiB0eXBlIFBhcnR5Rm9ybVZhbHVlcyA9IFZhbHVlPEZvcm1Hcm91cDxQYXJ0eUZvcm1Db250cm9scz4+O1xuICogYGBgXG4gKlxuICogVGhlIHJlc3VsdGluZyB0eXBlIGlzIGB7YWRkcmVzczogc3RyaW5nfHVuZGVmaW5lZH1gLlxuICpcbiAqICMjIyBgRm9ybUFycmF5YCB2YWx1ZSB0eXBlXG4gKlxuICogWW91IGNhbiBleHRyYWN0IHZhbHVlcyBmcm9tIEZvcm1BcnJheXMgYXMgd2VsbDpcbiAqXG4gKiBgYGB0c1xuICogdHlwZSBHdWVzdE5hbWVzQ29udHJvbHMgPSBGb3JtQXJyYXk8Rm9ybUNvbnRyb2w8c3RyaW5nPj47XG4gKlxuICogdHlwZSBOYW1lc1ZhbHVlcyA9IFZhbHVlPEd1ZXN0TmFtZXNDb250cm9scz47XG4gKiBgYGBcbiAqXG4gKiBUaGUgcmVzdWx0aW5nIHR5cGUgaXMgYHN0cmluZ1tdYC5cbiAqXG4gKiAqKkludGVybmFsOiBub3QgZm9yIHB1YmxpYyB1c2UuKipcbiAqL1xuZXhwb3J0IHR5cGUgybVWYWx1ZTxUIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sfHVuZGVmaW5lZD4gPVxuICAgIFQgZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2w8YW55LCBhbnk+PyBUWyd2YWx1ZSddIDogbmV2ZXI7XG5cbi8qKlxuICogUmF3VmFsdWUgZ2l2ZXMgdGhlIHJhdyB2YWx1ZSB0eXBlIGNvcnJlc3BvbmRpbmcgdG8gYSBjb250cm9sIHR5cGUuXG4gKlxuICogTm90ZSB0aGF0IHRoZSByZXN1bHRpbmcgdHlwZSB3aWxsIGZvbGxvdyB0aGUgc2FtZSBydWxlcyBhcyBgLmdldFJhd1ZhbHVlKClgIG9uIHlvdXIgY29udHJvbCxcbiAqIGdyb3VwLCBvciBhcnJheS4gVGhpcyBtZWFucyB0aGF0IGFsbCBjb250cm9scyBpbnNpZGUgYSBncm91cCB3aWxsIGJlIHJlcXVpcmVkLCBub3Qgb3B0aW9uYWwsXG4gKiByZWdhcmRsZXNzIG9mIHRoZWlyIGRpc2FibGVkIHN0YXRlLlxuICpcbiAqIFlvdSBtYXkgYWxzbyB3aXNoIHRvIHVzZSB7QGxpbmsgybVWYWx1ZX0sIHdoaWNoIHdpbGwgaGF2ZSBgdW5kZWZpbmVkYCBpbiBncm91cCBrZXlzICh3aGljaCBjYW4gYmVcbiAqIGRpc2FibGVkKS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqICMjIyBgRm9ybUdyb3VwYCByYXcgdmFsdWUgdHlwZVxuICpcbiAqIEltYWdpbmUgeW91IGhhdmUgYW4gaW50ZXJmYWNlIGRlZmluaW5nIHRoZSBjb250cm9scyBpbiB5b3VyIGdyb3VwLiBZb3UgY2FuIGV4dHJhY3QgdGhlIHNoYXBlIG9mXG4gKiB0aGUgcmF3IHZhbHVlcyBhcyBmb2xsb3dzOlxuICpcbiAqIGBgYHRzXG4gKiBpbnRlcmZhY2UgUGFydHlGb3JtQ29udHJvbHMge1xuICogICBhZGRyZXNzOiBGb3JtQ29udHJvbDxzdHJpbmc+O1xuICogfVxuICpcbiAqIC8vIFJhd1ZhbHVlIG9wZXJhdGVzIG9uIGNvbnRyb2xzOyB0aGUgb2JqZWN0IG11c3QgYmUgd3JhcHBlZCBpbiBhIEZvcm1Hcm91cC5cbiAqIHR5cGUgUGFydHlGb3JtVmFsdWVzID0gUmF3VmFsdWU8Rm9ybUdyb3VwPFBhcnR5Rm9ybUNvbnRyb2xzPj47XG4gKiBgYGBcbiAqXG4gKiBUaGUgcmVzdWx0aW5nIHR5cGUgaXMgYHthZGRyZXNzOiBzdHJpbmd9YC4gKE5vdGUgdGhlIGFic2VuY2Ugb2YgYHVuZGVmaW5lZGAuKVxuICpcbiAqICAqKkludGVybmFsOiBub3QgZm9yIHB1YmxpYyB1c2UuKipcbiAqL1xuZXhwb3J0IHR5cGUgybVSYXdWYWx1ZTxUIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sfHVuZGVmaW5lZD4gPSBUIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sPGFueSwgYW55Pj9cbiAgICAoVFsnc2V0VmFsdWUnXSBleHRlbmRzKCh2OiBpbmZlciBSKSA9PiB2b2lkKSA/IFIgOiBuZXZlcikgOlxuICAgIG5ldmVyO1xuXG4vLyBEaXNhYmxlIGNsYW5nLWZvcm1hdCB0byBwcm9kdWNlIGNsZWFyZXIgZm9ybWF0dGluZyBmb3IgdGhlc2UgbXVsdGlsaW5lIHR5cGVzLlxuLy8gY2xhbmctZm9ybWF0IG9mZlxuXG4vKipcbiAqIFRva2VuaXplIHNwbGl0cyBhIHN0cmluZyBsaXRlcmFsIFMgYnkgYSBkZWxpbWl0ZXIgRC5cbiAqL1xuZXhwb3J0IHR5cGUgybVUb2tlbml6ZTxTIGV4dGVuZHMgc3RyaW5nLCBEIGV4dGVuZHMgc3RyaW5nPiA9XG4gIHN0cmluZyBleHRlbmRzIFMgPyBzdHJpbmdbXSA6IC8qIFMgbXVzdCBiZSBhIGxpdGVyYWwgKi9cbiAgICBTIGV4dGVuZHMgYCR7aW5mZXIgVH0ke0R9JHtpbmZlciBVfWAgPyBbVCwgLi4uybVUb2tlbml6ZTxVLCBEPl0gOlxuICAgICAgW1NdIC8qIEJhc2UgY2FzZSAqL1xuICA7XG5cbi8qKlxuICogQ29lcmNlU3RyQXJyVG9OdW1BcnIgYWNjZXB0cyBhbiBhcnJheSBvZiBzdHJpbmdzLCBhbmQgY29udmVydHMgYW55IG51bWVyaWMgc3RyaW5nIHRvIGEgbnVtYmVyLlxuICovXG5leHBvcnQgdHlwZSDJtUNvZXJjZVN0ckFyclRvTnVtQXJyPFM+ID1cbi8vIEV4dHJhY3QgdGhlIGhlYWQgb2YgdGhlIGFycmF5LlxuICBTIGV4dGVuZHMgW2luZmVyIEhlYWQsIC4uLmluZmVyIFRhaWxdID9cbiAgICAvLyBVc2luZyBhIHRlbXBsYXRlIGxpdGVyYWwgdHlwZSwgY29lcmNlIHRoZSBoZWFkIHRvIGBudW1iZXJgIGlmIHBvc3NpYmxlLlxuICAgIC8vIFRoZW4sIHJlY3Vyc2Ugb24gdGhlIHRhaWwuXG4gICAgSGVhZCBleHRlbmRzIGAke251bWJlcn1gID9cbiAgICAgIFtudW1iZXIsIC4uLsm1Q29lcmNlU3RyQXJyVG9OdW1BcnI8VGFpbD5dIDpcbiAgICAgIFtIZWFkLCAuLi7JtUNvZXJjZVN0ckFyclRvTnVtQXJyPFRhaWw+XSA6XG4gICAgW107XG5cbi8qKlxuICogTmF2aWdhdGUgdGFrZXMgYSB0eXBlIFQgYW5kIGFuIGFycmF5IEssIGFuZCByZXR1cm5zIHRoZSB0eXBlIG9mIFRbS1swXV1bS1sxXV1bS1syXV0uLi5cbiAqL1xuZXhwb3J0IHR5cGUgybVOYXZpZ2F0ZTxULCBLIGV4dGVuZHMoQXJyYXk8c3RyaW5nfG51bWJlcj4pPiA9XG4gIFQgZXh0ZW5kcyBvYmplY3QgPyAvKiBUIG11c3QgYmUgaW5kZXhhYmxlIChvYmplY3Qgb3IgYXJyYXkpICovXG4gICAgKEsgZXh0ZW5kcyBbaW5mZXIgSGVhZCwgLi4uaW5mZXIgVGFpbF0gPyAvKiBTcGxpdCBLIGludG8gaGVhZCBhbmQgdGFpbCAqL1xuICAgICAgKEhlYWQgZXh0ZW5kcyBrZXlvZiBUID8gLyogaGVhZChLKSBtdXN0IGluZGV4IFQgKi9cbiAgICAgICAgKFRhaWwgZXh0ZW5kcyhzdHJpbmd8bnVtYmVyKVtdID8gLyogdGFpbChLKSBtdXN0IGJlIGFuIGFycmF5ICovXG4gICAgICAgICAgW10gZXh0ZW5kcyBUYWlsID8gVFtIZWFkXSA6IC8qIGJhc2UgY2FzZTogSyBjYW4gYmUgc3BsaXQsIGJ1dCBUYWlsIGlzIGVtcHR5ICovXG4gICAgICAgICAgICAoybVOYXZpZ2F0ZTxUW0hlYWRdLCBUYWlsPikgLyogZXhwbG9yZSBUW2hlYWQoSyldIGJ5IHRhaWwoSykgKi8gOlxuICAgICAgICAgIGFueSkgLyogdGFpbChLKSB3YXMgbm90IGFuIGFycmF5LCBnaXZlIHVwICovIDpcbiAgICAgICAgbmV2ZXIpIC8qIGhlYWQoSykgZG9lcyBub3QgaW5kZXggVCwgZ2l2ZSB1cCAqLyA6XG4gICAgICBhbnkpIC8qIEsgY2Fubm90IGJlIHNwbGl0LCBnaXZlIHVwICovIDpcbiAgICBhbnkgLyogVCBpcyBub3QgaW5kZXhhYmxlLCBnaXZlIHVwICovXG4gIDtcblxuLyoqXG4gKiDJtVdyaXRlYWJsZSByZW1vdmVzIHJlYWRvbmx5IGZyb20gYWxsIGtleXMuXG4gKi9cbmV4cG9ydCB0eXBlIMm1V3JpdGVhYmxlPFQ+ID0ge1xuICAtcmVhZG9ubHlbUCBpbiBrZXlvZiBUXTogVFtQXVxufTtcblxuLyoqXG4gKiBHZXRQcm9wZXJ0eSB0YWtlcyBhIHR5cGUgVCBhbmQgc29tZSBwcm9wZXJ0eSBuYW1lcyBvciBpbmRpY2VzIEsuXG4gKiBJZiBLIGlzIGEgZG90LXNlcGFyYXRlZCBzdHJpbmcsIGl0IGlzIHRva2VuaXplZCBpbnRvIGFuIGFycmF5IGJlZm9yZSBwcm9jZWVkaW5nLlxuICogVGhlbiwgdGhlIHR5cGUgb2YgdGhlIG5lc3RlZCBwcm9wZXJ0eSBhdCBLIGlzIGNvbXB1dGVkOiBUW0tbMF1dW0tbMV1dW0tbMl1dLi4uXG4gKiBUaGlzIHdvcmtzIHdpdGggYm90aCBvYmplY3RzLCB3aGljaCBhcmUgaW5kZXhlZCBieSBwcm9wZXJ0eSBuYW1lLCBhbmQgYXJyYXlzLCB3aGljaCBhcmUgaW5kZXhlZFxuICogbnVtZXJpY2FsbHkuXG4gKlxuICogRm9yIGludGVybmFsIHVzZSBvbmx5LlxuICovXG5leHBvcnQgdHlwZSDJtUdldFByb3BlcnR5PFQsIEs+ID1cbiAgICAvLyBLIGlzIGEgc3RyaW5nXG4gICAgSyBleHRlbmRzIHN0cmluZyA/IMm1R2V0UHJvcGVydHk8VCwgybVDb2VyY2VTdHJBcnJUb051bUFycjzJtVRva2VuaXplPEssICcuJz4+PiA6XG4gICAgLy8gSXMgaXMgYW4gYXJyYXlcbiAgICDJtVdyaXRlYWJsZTxLPiBleHRlbmRzIEFycmF5PHN0cmluZ3xudW1iZXI+ID8gybVOYXZpZ2F0ZTxULCDJtVdyaXRlYWJsZTxLPj4gOlxuICAgIC8vIEZhbGwgdGhyb3VnaCBwZXJtaXNzaXZlbHkgaWYgd2UgY2FuJ3QgY2FsY3VsYXRlIHRoZSB0eXBlIG9mIEsuXG4gICAgYW55O1xuXG4vLyBjbGFuZy1mb3JtYXQgb25cblxuLyoqXG4gKiBUaGlzIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBgRm9ybUNvbnRyb2xgLCBgRm9ybUdyb3VwYCwgYW5kIGBGb3JtQXJyYXlgLlxuICpcbiAqIEl0IHByb3ZpZGVzIHNvbWUgb2YgdGhlIHNoYXJlZCBiZWhhdmlvciB0aGF0IGFsbCBjb250cm9scyBhbmQgZ3JvdXBzIG9mIGNvbnRyb2xzIGhhdmUsIGxpa2VcbiAqIHJ1bm5pbmcgdmFsaWRhdG9ycywgY2FsY3VsYXRpbmcgc3RhdHVzLCBhbmQgcmVzZXR0aW5nIHN0YXRlLiBJdCBhbHNvIGRlZmluZXMgdGhlIHByb3BlcnRpZXNcbiAqIHRoYXQgYXJlIHNoYXJlZCBiZXR3ZWVuIGFsbCBzdWItY2xhc3NlcywgbGlrZSBgdmFsdWVgLCBgdmFsaWRgLCBhbmQgYGRpcnR5YC4gSXQgc2hvdWxkbid0IGJlXG4gKiBpbnN0YW50aWF0ZWQgZGlyZWN0bHkuXG4gKlxuICogVGhlIGZpcnN0IHR5cGUgcGFyYW1ldGVyIFRWYWx1ZSByZXByZXNlbnRzIHRoZSB2YWx1ZSB0eXBlIG9mIHRoZSBjb250cm9sIChgY29udHJvbC52YWx1ZWApLlxuICogVGhlIG9wdGlvbmFsIHR5cGUgcGFyYW1ldGVyIFRSYXdWYWx1ZSAgcmVwcmVzZW50cyB0aGUgcmF3IHZhbHVlIHR5cGUgKGBjb250cm9sLmdldFJhd1ZhbHVlKClgKS5cbiAqXG4gKiBAc2VlIFtGb3JtcyBHdWlkZV0oL2d1aWRlL2Zvcm1zKVxuICogQHNlZSBbUmVhY3RpdmUgRm9ybXMgR3VpZGVdKC9ndWlkZS9yZWFjdGl2ZS1mb3JtcylcbiAqIEBzZWUgW0R5bmFtaWMgRm9ybXMgR3VpZGVdKC9ndWlkZS9keW5hbWljLWZvcm0pXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RDb250cm9sPFRWYWx1ZSA9IGFueSwgVFJhd1ZhbHVlIGV4dGVuZHMgVFZhbHVlID0gVFZhbHVlPiB7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3BlbmRpbmdEaXJ0eSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCBhIGNvbnRyb2wgaGFzIGl0cyBvd24gcGVuZGluZyBhc3luY2hyb25vdXMgdmFsaWRhdGlvbiBpbiBwcm9ncmVzcy5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfaGFzT3duUGVuZGluZ0FzeW5jVmFsaWRhdG9yID0gZmFsc2U7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfcGVuZGluZ1RvdWNoZWQgPSBmYWxzZTtcblxuICAvKiogQGludGVybmFsICovXG4gIF9vbkNvbGxlY3Rpb25DaGFuZ2UgPSAoKSA9PiB7fTtcblxuICAvKiogQGludGVybmFsICovXG4gIF91cGRhdGVPbj86IEZvcm1Ib29rcztcblxuICBwcml2YXRlIF9wYXJlbnQ6IEZvcm1Hcm91cHxGb3JtQXJyYXl8bnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2FzeW5jVmFsaWRhdGlvblN1YnNjcmlwdGlvbjogYW55O1xuXG4gIC8qKlxuICAgKiBDb250YWlucyB0aGUgcmVzdWx0IG9mIG1lcmdpbmcgc3luY2hyb25vdXMgdmFsaWRhdG9ycyBpbnRvIGEgc2luZ2xlIHZhbGlkYXRvciBmdW5jdGlvblxuICAgKiAoY29tYmluZWQgdXNpbmcgYFZhbGlkYXRvcnMuY29tcG9zZWApLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX2NvbXBvc2VkVmFsaWRhdG9yRm4hOiBWYWxpZGF0b3JGbnxudWxsO1xuXG4gIC8qKlxuICAgKiBDb250YWlucyB0aGUgcmVzdWx0IG9mIG1lcmdpbmcgYXN5bmNocm9ub3VzIHZhbGlkYXRvcnMgaW50byBhIHNpbmdsZSB2YWxpZGF0b3IgZnVuY3Rpb25cbiAgICogKGNvbWJpbmVkIHVzaW5nIGBWYWxpZGF0b3JzLmNvbXBvc2VBc3luY2ApLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX2NvbXBvc2VkQXN5bmNWYWxpZGF0b3JGbiE6IEFzeW5jVmFsaWRhdG9yRm58bnVsbDtcblxuICAvKipcbiAgICogU3luY2hyb25vdXMgdmFsaWRhdG9ycyBhcyB0aGV5IHdlcmUgcHJvdmlkZWQ6XG4gICAqICAtIGluIGBBYnN0cmFjdENvbnRyb2xgIGNvbnN0cnVjdG9yXG4gICAqICAtIGFzIGFuIGFyZ3VtZW50IHdoaWxlIGNhbGxpbmcgYHNldFZhbGlkYXRvcnNgIGZ1bmN0aW9uXG4gICAqICAtIHdoaWxlIGNhbGxpbmcgdGhlIHNldHRlciBvbiB0aGUgYHZhbGlkYXRvcmAgZmllbGQgKGUuZy4gYGNvbnRyb2wudmFsaWRhdG9yID0gdmFsaWRhdG9yRm5gKVxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX3Jhd1ZhbGlkYXRvcnMhOiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdfG51bGw7XG5cbiAgLyoqXG4gICAqIEFzeW5jaHJvbm91cyB2YWxpZGF0b3JzIGFzIHRoZXkgd2VyZSBwcm92aWRlZDpcbiAgICogIC0gaW4gYEFic3RyYWN0Q29udHJvbGAgY29uc3RydWN0b3JcbiAgICogIC0gYXMgYW4gYXJndW1lbnQgd2hpbGUgY2FsbGluZyBgc2V0QXN5bmNWYWxpZGF0b3JzYCBmdW5jdGlvblxuICAgKiAgLSB3aGlsZSBjYWxsaW5nIHRoZSBzZXR0ZXIgb24gdGhlIGBhc3luY1ZhbGlkYXRvcmAgZmllbGQgKGUuZy4gYGNvbnRyb2wuYXN5bmNWYWxpZGF0b3IgPVxuICAgKiBhc3luY1ZhbGlkYXRvckZuYClcbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcml2YXRlIF9yYXdBc3luY1ZhbGlkYXRvcnMhOiBBc3luY1ZhbGlkYXRvckZufEFzeW5jVmFsaWRhdG9yRm5bXXxudWxsO1xuXG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgY29udHJvbC5cbiAgICpcbiAgICogKiBGb3IgYSBgRm9ybUNvbnRyb2xgLCB0aGUgY3VycmVudCB2YWx1ZS5cbiAgICogKiBGb3IgYW4gZW5hYmxlZCBgRm9ybUdyb3VwYCwgdGhlIHZhbHVlcyBvZiBlbmFibGVkIGNvbnRyb2xzIGFzIGFuIG9iamVjdFxuICAgKiB3aXRoIGEga2V5LXZhbHVlIHBhaXIgZm9yIGVhY2ggbWVtYmVyIG9mIHRoZSBncm91cC5cbiAgICogKiBGb3IgYSBkaXNhYmxlZCBgRm9ybUdyb3VwYCwgdGhlIHZhbHVlcyBvZiBhbGwgY29udHJvbHMgYXMgYW4gb2JqZWN0XG4gICAqIHdpdGggYSBrZXktdmFsdWUgcGFpciBmb3IgZWFjaCBtZW1iZXIgb2YgdGhlIGdyb3VwLlxuICAgKiAqIEZvciBhIGBGb3JtQXJyYXlgLCB0aGUgdmFsdWVzIG9mIGVuYWJsZWQgY29udHJvbHMgYXMgYW4gYXJyYXkuXG4gICAqXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdmFsdWUhOiBUVmFsdWU7XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIEFic3RyYWN0Q29udHJvbCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHZhbGlkYXRvcnMgVGhlIGZ1bmN0aW9uIG9yIGFycmF5IG9mIGZ1bmN0aW9ucyB0aGF0IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSB2YWxpZGl0eSBvZlxuICAgKiAgICAgdGhpcyBjb250cm9sIHN5bmNocm9ub3VzbHkuXG4gICAqIEBwYXJhbSBhc3luY1ZhbGlkYXRvcnMgVGhlIGZ1bmN0aW9uIG9yIGFycmF5IG9mIGZ1bmN0aW9ucyB0aGF0IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHZhbGlkaXR5IG9mXG4gICAqICAgICB0aGlzIGNvbnRyb2wgYXN5bmNocm9ub3VzbHkuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHZhbGlkYXRvcnM6IFZhbGlkYXRvckZufFZhbGlkYXRvckZuW118bnVsbCxcbiAgICAgIGFzeW5jVmFsaWRhdG9yczogQXN5bmNWYWxpZGF0b3JGbnxBc3luY1ZhbGlkYXRvckZuW118bnVsbCkge1xuICAgIHRoaXMuX2Fzc2lnblZhbGlkYXRvcnModmFsaWRhdG9ycyk7XG4gICAgdGhpcy5fYXNzaWduQXN5bmNWYWxpZGF0b3JzKGFzeW5jVmFsaWRhdG9ycyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZnVuY3Rpb24gdGhhdCBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgdmFsaWRpdHkgb2YgdGhpcyBjb250cm9sIHN5bmNocm9ub3VzbHkuXG4gICAqIElmIG11bHRpcGxlIHZhbGlkYXRvcnMgaGF2ZSBiZWVuIGFkZGVkLCB0aGlzIHdpbGwgYmUgYSBzaW5nbGUgY29tcG9zZWQgZnVuY3Rpb24uXG4gICAqIFNlZSBgVmFsaWRhdG9ycy5jb21wb3NlKClgIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZ2V0IHZhbGlkYXRvcigpOiBWYWxpZGF0b3JGbnxudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fY29tcG9zZWRWYWxpZGF0b3JGbjtcbiAgfVxuICBzZXQgdmFsaWRhdG9yKHZhbGlkYXRvckZuOiBWYWxpZGF0b3JGbnxudWxsKSB7XG4gICAgdGhpcy5fcmF3VmFsaWRhdG9ycyA9IHRoaXMuX2NvbXBvc2VkVmFsaWRhdG9yRm4gPSB2YWxpZGF0b3JGbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBmdW5jdGlvbiB0aGF0IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSB2YWxpZGl0eSBvZiB0aGlzIGNvbnRyb2wgYXN5bmNocm9ub3VzbHkuXG4gICAqIElmIG11bHRpcGxlIHZhbGlkYXRvcnMgaGF2ZSBiZWVuIGFkZGVkLCB0aGlzIHdpbGwgYmUgYSBzaW5nbGUgY29tcG9zZWQgZnVuY3Rpb24uXG4gICAqIFNlZSBgVmFsaWRhdG9ycy5jb21wb3NlKClgIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZ2V0IGFzeW5jVmFsaWRhdG9yKCk6IEFzeW5jVmFsaWRhdG9yRm58bnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbXBvc2VkQXN5bmNWYWxpZGF0b3JGbjtcbiAgfVxuICBzZXQgYXN5bmNWYWxpZGF0b3IoYXN5bmNWYWxpZGF0b3JGbjogQXN5bmNWYWxpZGF0b3JGbnxudWxsKSB7XG4gICAgdGhpcy5fcmF3QXN5bmNWYWxpZGF0b3JzID0gdGhpcy5fY29tcG9zZWRBc3luY1ZhbGlkYXRvckZuID0gYXN5bmNWYWxpZGF0b3JGbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcGFyZW50IGNvbnRyb2wuXG4gICAqL1xuICBnZXQgcGFyZW50KCk6IEZvcm1Hcm91cHxGb3JtQXJyYXl8bnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3BhcmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdmFsaWRhdGlvbiBzdGF0dXMgb2YgdGhlIGNvbnRyb2wuXG4gICAqXG4gICAqIEBzZWUgYEZvcm1Db250cm9sU3RhdHVzYFxuICAgKlxuICAgKiBUaGVzZSBzdGF0dXMgdmFsdWVzIGFyZSBtdXR1YWxseSBleGNsdXNpdmUsIHNvIGEgY29udHJvbCBjYW5ub3QgYmVcbiAgICogYm90aCB2YWxpZCBBTkQgaW52YWxpZCBvciBpbnZhbGlkIEFORCBkaXNhYmxlZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzdGF0dXMhOiBGb3JtQ29udHJvbFN0YXR1cztcblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGB2YWxpZGAgd2hlbiBpdHMgYHN0YXR1c2AgaXMgYFZBTElEYC5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29udHJvbCBoYXMgcGFzc2VkIGFsbCBvZiBpdHMgdmFsaWRhdGlvbiB0ZXN0cyxcbiAgICogZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgZ2V0IHZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gVkFMSUQ7XG4gIH1cblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBpbnZhbGlkYCB3aGVuIGl0cyBgc3RhdHVzYCBpcyBgSU5WQUxJRGAuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIEFic3RyYWN0Q29udHJvbC5zdGF0dXN9XG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhpcyBjb250cm9sIGhhcyBmYWlsZWQgb25lIG9yIG1vcmUgb2YgaXRzIHZhbGlkYXRpb24gY2hlY2tzLFxuICAgKiBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBnZXQgaW52YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXMgPT09IElOVkFMSUQ7XG4gIH1cblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBwZW5kaW5nYCB3aGVuIGl0cyBgc3RhdHVzYCBpcyBgUEVORElOR2AuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIEFic3RyYWN0Q29udHJvbC5zdGF0dXN9XG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhpcyBjb250cm9sIGlzIGluIHRoZSBwcm9jZXNzIG9mIGNvbmR1Y3RpbmcgYSB2YWxpZGF0aW9uIGNoZWNrLFxuICAgKiBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBnZXQgcGVuZGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXMgPT0gUEVORElORztcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGNvbnRyb2wgaXMgYGRpc2FibGVkYCB3aGVuIGl0cyBgc3RhdHVzYCBpcyBgRElTQUJMRURgLlxuICAgKlxuICAgKiBEaXNhYmxlZCBjb250cm9scyBhcmUgZXhlbXB0IGZyb20gdmFsaWRhdGlvbiBjaGVja3MgYW5kXG4gICAqIGFyZSBub3QgaW5jbHVkZWQgaW4gdGhlIGFnZ3JlZ2F0ZSB2YWx1ZSBvZiB0aGVpciBhbmNlc3RvclxuICAgKiBjb250cm9scy5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29udHJvbCBpcyBkaXNhYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gRElTQUJMRUQ7XG4gIH1cblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBlbmFibGVkYCBhcyBsb25nIGFzIGl0cyBgc3RhdHVzYCBpcyBub3QgYERJU0FCTEVEYC5cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29udHJvbCBoYXMgYW55IHN0YXR1cyBvdGhlciB0aGFuICdESVNBQkxFRCcsXG4gICAqIGZhbHNlIGlmIHRoZSBzdGF0dXMgaXMgJ0RJU0FCTEVEJy5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICovXG4gIGdldCBlbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyAhPT0gRElTQUJMRUQ7XG4gIH1cblxuICAvKipcbiAgICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgYW55IGVycm9ycyBnZW5lcmF0ZWQgYnkgZmFpbGluZyB2YWxpZGF0aW9uLFxuICAgKiBvciBudWxsIGlmIHRoZXJlIGFyZSBubyBlcnJvcnMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZXJyb3JzITogVmFsaWRhdGlvbkVycm9yc3xudWxsO1xuXG4gIC8qKlxuICAgKiBBIGNvbnRyb2wgaXMgYHByaXN0aW5lYCBpZiB0aGUgdXNlciBoYXMgbm90IHlldCBjaGFuZ2VkXG4gICAqIHRoZSB2YWx1ZSBpbiB0aGUgVUkuXG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHVzZXIgaGFzIG5vdCB5ZXQgY2hhbmdlZCB0aGUgdmFsdWUgaW4gdGhlIFVJOyBjb21wYXJlIGBkaXJ0eWAuXG4gICAqIFByb2dyYW1tYXRpYyBjaGFuZ2VzIHRvIGEgY29udHJvbCdzIHZhbHVlIGRvIG5vdCBtYXJrIGl0IGRpcnR5LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHByaXN0aW5lOiBib29sZWFuID0gdHJ1ZTtcblxuICAvKipcbiAgICogQSBjb250cm9sIGlzIGBkaXJ0eWAgaWYgdGhlIHVzZXIgaGFzIGNoYW5nZWQgdGhlIHZhbHVlXG4gICAqIGluIHRoZSBVSS5cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdXNlciBoYXMgY2hhbmdlZCB0aGUgdmFsdWUgb2YgdGhpcyBjb250cm9sIGluIHRoZSBVSTsgY29tcGFyZSBgcHJpc3RpbmVgLlxuICAgKiBQcm9ncmFtbWF0aWMgY2hhbmdlcyB0byBhIGNvbnRyb2wncyB2YWx1ZSBkbyBub3QgbWFyayBpdCBkaXJ0eS5cbiAgICovXG4gIGdldCBkaXJ0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMucHJpc3RpbmU7XG4gIH1cblxuICAvKipcbiAgICogVHJ1ZSBpZiB0aGUgY29udHJvbCBpcyBtYXJrZWQgYXMgYHRvdWNoZWRgLlxuICAgKlxuICAgKiBBIGNvbnRyb2wgaXMgbWFya2VkIGB0b3VjaGVkYCBvbmNlIHRoZSB1c2VyIGhhcyB0cmlnZ2VyZWRcbiAgICogYSBgYmx1cmAgZXZlbnQgb24gaXQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdG91Y2hlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBUcnVlIGlmIHRoZSBjb250cm9sIGhhcyBub3QgYmVlbiBtYXJrZWQgYXMgdG91Y2hlZFxuICAgKlxuICAgKiBBIGNvbnRyb2wgaXMgYHVudG91Y2hlZGAgaWYgdGhlIHVzZXIgaGFzIG5vdCB5ZXQgdHJpZ2dlcmVkXG4gICAqIGEgYGJsdXJgIGV2ZW50IG9uIGl0LlxuICAgKi9cbiAgZ2V0IHVudG91Y2hlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMudG91Y2hlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIG11bHRpY2FzdGluZyBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gZXZlbnQgZXZlcnkgdGltZSB0aGUgdmFsdWUgb2YgdGhlIGNvbnRyb2wgY2hhbmdlcywgaW5cbiAgICogdGhlIFVJIG9yIHByb2dyYW1tYXRpY2FsbHkuIEl0IGFsc28gZW1pdHMgYW4gZXZlbnQgZWFjaCB0aW1lIHlvdSBjYWxsIGVuYWJsZSgpIG9yIGRpc2FibGUoKVxuICAgKiB3aXRob3V0IHBhc3NpbmcgYWxvbmcge2VtaXRFdmVudDogZmFsc2V9IGFzIGEgZnVuY3Rpb24gYXJndW1lbnQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdmFsdWVDaGFuZ2VzITogT2JzZXJ2YWJsZTxUVmFsdWU+O1xuXG4gIC8qKlxuICAgKiBBIG11bHRpY2FzdGluZyBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gZXZlbnQgZXZlcnkgdGltZSB0aGUgdmFsaWRhdGlvbiBgc3RhdHVzYCBvZiB0aGUgY29udHJvbFxuICAgKiByZWNhbGN1bGF0ZXMuXG4gICAqXG4gICAqIEBzZWUgYEZvcm1Db250cm9sU3RhdHVzYFxuICAgKiBAc2VlIHtAbGluayBBYnN0cmFjdENvbnRyb2wuc3RhdHVzfVxuICAgKlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHN0YXR1c0NoYW5nZXMhOiBPYnNlcnZhYmxlPEZvcm1Db250cm9sU3RhdHVzPjtcblxuICAvKipcbiAgICogUmVwb3J0cyB0aGUgdXBkYXRlIHN0cmF0ZWd5IG9mIHRoZSBgQWJzdHJhY3RDb250cm9sYCAobWVhbmluZ1xuICAgKiB0aGUgZXZlbnQgb24gd2hpY2ggdGhlIGNvbnRyb2wgdXBkYXRlcyBpdHNlbGYpLlxuICAgKiBQb3NzaWJsZSB2YWx1ZXM6IGAnY2hhbmdlJ2AgfCBgJ2JsdXInYCB8IGAnc3VibWl0J2BcbiAgICogRGVmYXVsdCB2YWx1ZTogYCdjaGFuZ2UnYFxuICAgKi9cbiAgZ2V0IHVwZGF0ZU9uKCk6IEZvcm1Ib29rcyB7XG4gICAgcmV0dXJuIHRoaXMuX3VwZGF0ZU9uID8gdGhpcy5fdXBkYXRlT24gOiAodGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC51cGRhdGVPbiA6ICdjaGFuZ2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBzeW5jaHJvbm91cyB2YWxpZGF0b3JzIHRoYXQgYXJlIGFjdGl2ZSBvbiB0aGlzIGNvbnRyb2wuICBDYWxsaW5nXG4gICAqIHRoaXMgb3ZlcndyaXRlcyBhbnkgZXhpc3Rpbmcgc3luY2hyb25vdXMgdmFsaWRhdG9ycy5cbiAgICpcbiAgICogV2hlbiB5b3UgYWRkIG9yIHJlbW92ZSBhIHZhbGlkYXRvciBhdCBydW4gdGltZSwgeW91IG11c3QgY2FsbFxuICAgKiBgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpYCBmb3IgdGhlIG5ldyB2YWxpZGF0aW9uIHRvIHRha2UgZWZmZWN0LlxuICAgKlxuICAgKiBJZiB5b3Ugd2FudCB0byBhZGQgYSBuZXcgdmFsaWRhdG9yIHdpdGhvdXQgYWZmZWN0aW5nIGV4aXN0aW5nIG9uZXMsIGNvbnNpZGVyXG4gICAqIHVzaW5nIGBhZGRWYWxpZGF0b3JzKClgIG1ldGhvZCBpbnN0ZWFkLlxuICAgKi9cbiAgc2V0VmFsaWRhdG9ycyh2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdfG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9hc3NpZ25WYWxpZGF0b3JzKHZhbGlkYXRvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGFzeW5jaHJvbm91cyB2YWxpZGF0b3JzIHRoYXQgYXJlIGFjdGl2ZSBvbiB0aGlzIGNvbnRyb2wuIENhbGxpbmcgdGhpc1xuICAgKiBvdmVyd3JpdGVzIGFueSBleGlzdGluZyBhc3luY2hyb25vdXMgdmFsaWRhdG9ycy5cbiAgICpcbiAgICogV2hlbiB5b3UgYWRkIG9yIHJlbW92ZSBhIHZhbGlkYXRvciBhdCBydW4gdGltZSwgeW91IG11c3QgY2FsbFxuICAgKiBgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpYCBmb3IgdGhlIG5ldyB2YWxpZGF0aW9uIHRvIHRha2UgZWZmZWN0LlxuICAgKlxuICAgKiBJZiB5b3Ugd2FudCB0byBhZGQgYSBuZXcgdmFsaWRhdG9yIHdpdGhvdXQgYWZmZWN0aW5nIGV4aXN0aW5nIG9uZXMsIGNvbnNpZGVyXG4gICAqIHVzaW5nIGBhZGRBc3luY1ZhbGlkYXRvcnMoKWAgbWV0aG9kIGluc3RlYWQuXG4gICAqL1xuICBzZXRBc3luY1ZhbGlkYXRvcnModmFsaWRhdG9yczogQXN5bmNWYWxpZGF0b3JGbnxBc3luY1ZhbGlkYXRvckZuW118bnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX2Fzc2lnbkFzeW5jVmFsaWRhdG9ycyh2YWxpZGF0b3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBzeW5jaHJvbm91cyB2YWxpZGF0b3Igb3IgdmFsaWRhdG9ycyB0byB0aGlzIGNvbnRyb2wsIHdpdGhvdXQgYWZmZWN0aW5nIG90aGVyIHZhbGlkYXRvcnMuXG4gICAqXG4gICAqIFdoZW4geW91IGFkZCBvciByZW1vdmUgYSB2YWxpZGF0b3IgYXQgcnVuIHRpbWUsIHlvdSBtdXN0IGNhbGxcbiAgICogYHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKWAgZm9yIHRoZSBuZXcgdmFsaWRhdGlvbiB0byB0YWtlIGVmZmVjdC5cbiAgICpcbiAgICogQWRkaW5nIGEgdmFsaWRhdG9yIHRoYXQgYWxyZWFkeSBleGlzdHMgd2lsbCBoYXZlIG5vIGVmZmVjdC4gSWYgZHVwbGljYXRlIHZhbGlkYXRvciBmdW5jdGlvbnNcbiAgICogYXJlIHByZXNlbnQgaW4gdGhlIGB2YWxpZGF0b3JzYCBhcnJheSwgb25seSB0aGUgZmlyc3QgaW5zdGFuY2Ugd291bGQgYmUgYWRkZWQgdG8gYSBmb3JtXG4gICAqIGNvbnRyb2wuXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3JzIFRoZSBuZXcgdmFsaWRhdG9yIGZ1bmN0aW9uIG9yIGZ1bmN0aW9ucyB0byBhZGQgdG8gdGhpcyBjb250cm9sLlxuICAgKi9cbiAgYWRkVmFsaWRhdG9ycyh2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdKTogdm9pZCB7XG4gICAgdGhpcy5zZXRWYWxpZGF0b3JzKGFkZFZhbGlkYXRvcnModmFsaWRhdG9ycywgdGhpcy5fcmF3VmFsaWRhdG9ycykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBhc3luY2hyb25vdXMgdmFsaWRhdG9yIG9yIHZhbGlkYXRvcnMgdG8gdGhpcyBjb250cm9sLCB3aXRob3V0IGFmZmVjdGluZyBvdGhlclxuICAgKiB2YWxpZGF0b3JzLlxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIEFkZGluZyBhIHZhbGlkYXRvciB0aGF0IGFscmVhZHkgZXhpc3RzIHdpbGwgaGF2ZSBubyBlZmZlY3QuXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3JzIFRoZSBuZXcgYXN5bmNocm9ub3VzIHZhbGlkYXRvciBmdW5jdGlvbiBvciBmdW5jdGlvbnMgdG8gYWRkIHRvIHRoaXMgY29udHJvbC5cbiAgICovXG4gIGFkZEFzeW5jVmFsaWRhdG9ycyh2YWxpZGF0b3JzOiBBc3luY1ZhbGlkYXRvckZufEFzeW5jVmFsaWRhdG9yRm5bXSk6IHZvaWQge1xuICAgIHRoaXMuc2V0QXN5bmNWYWxpZGF0b3JzKGFkZFZhbGlkYXRvcnModmFsaWRhdG9ycywgdGhpcy5fcmF3QXN5bmNWYWxpZGF0b3JzKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgc3luY2hyb25vdXMgdmFsaWRhdG9yIGZyb20gdGhpcyBjb250cm9sLCB3aXRob3V0IGFmZmVjdGluZyBvdGhlciB2YWxpZGF0b3JzLlxuICAgKiBWYWxpZGF0b3JzIGFyZSBjb21wYXJlZCBieSBmdW5jdGlvbiByZWZlcmVuY2U7IHlvdSBtdXN0IHBhc3MgYSByZWZlcmVuY2UgdG8gdGhlIGV4YWN0IHNhbWVcbiAgICogdmFsaWRhdG9yIGZ1bmN0aW9uIGFzIHRoZSBvbmUgdGhhdCB3YXMgb3JpZ2luYWxseSBzZXQuIElmIGEgcHJvdmlkZWQgdmFsaWRhdG9yIGlzIG5vdCBmb3VuZCxcbiAgICogaXQgaXMgaWdub3JlZC5cbiAgICpcbiAgICogQHVzYWdlTm90ZXNcbiAgICpcbiAgICogIyMjIFJlZmVyZW5jZSB0byBhIFZhbGlkYXRvckZuXG4gICAqXG4gICAqIGBgYFxuICAgKiAvLyBSZWZlcmVuY2UgdG8gdGhlIFJlcXVpcmVkVmFsaWRhdG9yXG4gICAqIGNvbnN0IGN0cmwgPSBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4oJycsIFZhbGlkYXRvcnMucmVxdWlyZWQpO1xuICAgKiBjdHJsLnJlbW92ZVZhbGlkYXRvcnMoVmFsaWRhdG9ycy5yZXF1aXJlZCk7XG4gICAqXG4gICAqIC8vIFJlZmVyZW5jZSB0byBhbm9ueW1vdXMgZnVuY3Rpb24gaW5zaWRlIE1pblZhbGlkYXRvclxuICAgKiBjb25zdCBtaW5WYWxpZGF0b3IgPSBWYWxpZGF0b3JzLm1pbigzKTtcbiAgICogY29uc3QgY3RybCA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPignJywgbWluVmFsaWRhdG9yKTtcbiAgICogZXhwZWN0KGN0cmwuaGFzVmFsaWRhdG9yKG1pblZhbGlkYXRvcikpLnRvRXF1YWwodHJ1ZSlcbiAgICogZXhwZWN0KGN0cmwuaGFzVmFsaWRhdG9yKFZhbGlkYXRvcnMubWluKDMpKSkudG9FcXVhbChmYWxzZSlcbiAgICpcbiAgICogY3RybC5yZW1vdmVWYWxpZGF0b3JzKG1pblZhbGlkYXRvcik7XG4gICAqIGBgYFxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3JzIFRoZSB2YWxpZGF0b3Igb3IgdmFsaWRhdG9ycyB0byByZW1vdmUuXG4gICAqL1xuICByZW1vdmVWYWxpZGF0b3JzKHZhbGlkYXRvcnM6IFZhbGlkYXRvckZufFZhbGlkYXRvckZuW10pOiB2b2lkIHtcbiAgICB0aGlzLnNldFZhbGlkYXRvcnMocmVtb3ZlVmFsaWRhdG9ycyh2YWxpZGF0b3JzLCB0aGlzLl9yYXdWYWxpZGF0b3JzKSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFuIGFzeW5jaHJvbm91cyB2YWxpZGF0b3IgZnJvbSB0aGlzIGNvbnRyb2wsIHdpdGhvdXQgYWZmZWN0aW5nIG90aGVyIHZhbGlkYXRvcnMuXG4gICAqIFZhbGlkYXRvcnMgYXJlIGNvbXBhcmVkIGJ5IGZ1bmN0aW9uIHJlZmVyZW5jZTsgeW91IG11c3QgcGFzcyBhIHJlZmVyZW5jZSB0byB0aGUgZXhhY3Qgc2FtZVxuICAgKiB2YWxpZGF0b3IgZnVuY3Rpb24gYXMgdGhlIG9uZSB0aGF0IHdhcyBvcmlnaW5hbGx5IHNldC4gSWYgYSBwcm92aWRlZCB2YWxpZGF0b3IgaXMgbm90IGZvdW5kLCBpdFxuICAgKiBpcyBpZ25vcmVkLlxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3JzIFRoZSBhc3luY2hyb25vdXMgdmFsaWRhdG9yIG9yIHZhbGlkYXRvcnMgdG8gcmVtb3ZlLlxuICAgKi9cbiAgcmVtb3ZlQXN5bmNWYWxpZGF0b3JzKHZhbGlkYXRvcnM6IEFzeW5jVmFsaWRhdG9yRm58QXN5bmNWYWxpZGF0b3JGbltdKTogdm9pZCB7XG4gICAgdGhpcy5zZXRBc3luY1ZhbGlkYXRvcnMocmVtb3ZlVmFsaWRhdG9ycyh2YWxpZGF0b3JzLCB0aGlzLl9yYXdBc3luY1ZhbGlkYXRvcnMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB3aGV0aGVyIGEgc3luY2hyb25vdXMgdmFsaWRhdG9yIGZ1bmN0aW9uIGlzIHByZXNlbnQgb24gdGhpcyBjb250cm9sLiBUaGUgcHJvdmlkZWRcbiAgICogdmFsaWRhdG9yIG11c3QgYmUgYSByZWZlcmVuY2UgdG8gdGhlIGV4YWN0IHNhbWUgZnVuY3Rpb24gdGhhdCB3YXMgcHJvdmlkZWQuXG4gICAqXG4gICAqIEB1c2FnZU5vdGVzXG4gICAqXG4gICAqICMjIyBSZWZlcmVuY2UgdG8gYSBWYWxpZGF0b3JGblxuICAgKlxuICAgKiBgYGBcbiAgICogLy8gUmVmZXJlbmNlIHRvIHRoZSBSZXF1aXJlZFZhbGlkYXRvclxuICAgKiBjb25zdCBjdHJsID0gbmV3IEZvcm1Db250cm9sPG51bWJlciB8IG51bGw+KDAsIFZhbGlkYXRvcnMucmVxdWlyZWQpO1xuICAgKiBleHBlY3QoY3RybC5oYXNWYWxpZGF0b3IoVmFsaWRhdG9ycy5yZXF1aXJlZCkpLnRvRXF1YWwodHJ1ZSlcbiAgICpcbiAgICogLy8gUmVmZXJlbmNlIHRvIGFub255bW91cyBmdW5jdGlvbiBpbnNpZGUgTWluVmFsaWRhdG9yXG4gICAqIGNvbnN0IG1pblZhbGlkYXRvciA9IFZhbGlkYXRvcnMubWluKDMpO1xuICAgKiBjb25zdCBjdHJsID0gbmV3IEZvcm1Db250cm9sPG51bWJlciB8IG51bGw+KDAsIG1pblZhbGlkYXRvcik7XG4gICAqIGV4cGVjdChjdHJsLmhhc1ZhbGlkYXRvcihtaW5WYWxpZGF0b3IpKS50b0VxdWFsKHRydWUpXG4gICAqIGV4cGVjdChjdHJsLmhhc1ZhbGlkYXRvcihWYWxpZGF0b3JzLm1pbigzKSkpLnRvRXF1YWwoZmFsc2UpXG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gdmFsaWRhdG9yIFRoZSB2YWxpZGF0b3IgdG8gY2hlY2sgZm9yIHByZXNlbmNlLiBDb21wYXJlZCBieSBmdW5jdGlvbiByZWZlcmVuY2UuXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIHByb3ZpZGVkIHZhbGlkYXRvciB3YXMgZm91bmQgb24gdGhpcyBjb250cm9sLlxuICAgKi9cbiAgaGFzVmFsaWRhdG9yKHZhbGlkYXRvcjogVmFsaWRhdG9yRm4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGFzVmFsaWRhdG9yKHRoaXMuX3Jhd1ZhbGlkYXRvcnMsIHZhbGlkYXRvcik7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciBhbiBhc3luY2hyb25vdXMgdmFsaWRhdG9yIGZ1bmN0aW9uIGlzIHByZXNlbnQgb24gdGhpcyBjb250cm9sLiBUaGUgcHJvdmlkZWRcbiAgICogdmFsaWRhdG9yIG11c3QgYmUgYSByZWZlcmVuY2UgdG8gdGhlIGV4YWN0IHNhbWUgZnVuY3Rpb24gdGhhdCB3YXMgcHJvdmlkZWQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3IgVGhlIGFzeW5jaHJvbm91cyB2YWxpZGF0b3IgdG8gY2hlY2sgZm9yIHByZXNlbmNlLiBDb21wYXJlZCBieSBmdW5jdGlvblxuICAgKiAgICAgcmVmZXJlbmNlLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBwcm92aWRlZCBhc3luY2hyb25vdXMgdmFsaWRhdG9yIHdhcyBmb3VuZCBvbiB0aGlzIGNvbnRyb2wuXG4gICAqL1xuICBoYXNBc3luY1ZhbGlkYXRvcih2YWxpZGF0b3I6IEFzeW5jVmFsaWRhdG9yRm4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gaGFzVmFsaWRhdG9yKHRoaXMuX3Jhd0FzeW5jVmFsaWRhdG9ycywgdmFsaWRhdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbXB0aWVzIG91dCB0aGUgc3luY2hyb25vdXMgdmFsaWRhdG9yIGxpc3QuXG4gICAqXG4gICAqIFdoZW4geW91IGFkZCBvciByZW1vdmUgYSB2YWxpZGF0b3IgYXQgcnVuIHRpbWUsIHlvdSBtdXN0IGNhbGxcbiAgICogYHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKWAgZm9yIHRoZSBuZXcgdmFsaWRhdGlvbiB0byB0YWtlIGVmZmVjdC5cbiAgICpcbiAgICovXG4gIGNsZWFyVmFsaWRhdG9ycygpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRvciA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogRW1wdGllcyBvdXQgdGhlIGFzeW5jIHZhbGlkYXRvciBsaXN0LlxuICAgKlxuICAgKiBXaGVuIHlvdSBhZGQgb3IgcmVtb3ZlIGEgdmFsaWRhdG9yIGF0IHJ1biB0aW1lLCB5b3UgbXVzdCBjYWxsXG4gICAqIGB1cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClgIGZvciB0aGUgbmV3IHZhbGlkYXRpb24gdG8gdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqL1xuICBjbGVhckFzeW5jVmFsaWRhdG9ycygpOiB2b2lkIHtcbiAgICB0aGlzLmFzeW5jVmFsaWRhdG9yID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrcyB0aGUgY29udHJvbCBhcyBgdG91Y2hlZGAuIEEgY29udHJvbCBpcyB0b3VjaGVkIGJ5IGZvY3VzIGFuZFxuICAgKiBibHVyIGV2ZW50cyB0aGF0IGRvIG5vdCBjaGFuZ2UgdGhlIHZhbHVlLlxuICAgKlxuICAgKiBAc2VlIGBtYXJrQXNVbnRvdWNoZWQoKWBcbiAgICogQHNlZSBgbWFya0FzRGlydHkoKWBcbiAgICogQHNlZSBgbWFya0FzUHJpc3RpbmUoKWBcbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzIGNoYW5nZXNcbiAgICogYW5kIGVtaXRzIGV2ZW50cyBhZnRlciBtYXJraW5nIGlzIGFwcGxpZWQuXG4gICAqICogYG9ubHlTZWxmYDogV2hlbiB0cnVlLCBtYXJrIG9ubHkgdGhpcyBjb250cm9sLiBXaGVuIGZhbHNlIG9yIG5vdCBzdXBwbGllZCxcbiAgICogbWFya3MgYWxsIGRpcmVjdCBhbmNlc3RvcnMuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqL1xuICBtYXJrQXNUb3VjaGVkKG9wdHM6IHtvbmx5U2VsZj86IGJvb2xlYW59ID0ge30pOiB2b2lkIHtcbiAgICAodGhpcyBhcyB7dG91Y2hlZDogYm9vbGVhbn0pLnRvdWNoZWQgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuX3BhcmVudCAmJiAhb3B0cy5vbmx5U2VsZikge1xuICAgICAgdGhpcy5fcGFyZW50Lm1hcmtBc1RvdWNoZWQob3B0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1hcmtzIHRoZSBjb250cm9sIGFuZCBhbGwgaXRzIGRlc2NlbmRhbnQgY29udHJvbHMgYXMgYHRvdWNoZWRgLlxuICAgKiBAc2VlIGBtYXJrQXNUb3VjaGVkKClgXG4gICAqL1xuICBtYXJrQWxsQXNUb3VjaGVkKCk6IHZvaWQge1xuICAgIHRoaXMubWFya0FzVG91Y2hlZCh7b25seVNlbGY6IHRydWV9KTtcblxuICAgIHRoaXMuX2ZvckVhY2hDaGlsZCgoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBjb250cm9sLm1hcmtBbGxBc1RvdWNoZWQoKSk7XG4gIH1cblxuICAvKipcbiAgICogTWFya3MgdGhlIGNvbnRyb2wgYXMgYHVudG91Y2hlZGAuXG4gICAqXG4gICAqIElmIHRoZSBjb250cm9sIGhhcyBhbnkgY2hpbGRyZW4sIGFsc28gbWFya3MgYWxsIGNoaWxkcmVuIGFzIGB1bnRvdWNoZWRgXG4gICAqIGFuZCByZWNhbGN1bGF0ZXMgdGhlIGB0b3VjaGVkYCBzdGF0dXMgb2YgYWxsIHBhcmVudCBjb250cm9scy5cbiAgICpcbiAgICogQHNlZSBgbWFya0FzVG91Y2hlZCgpYFxuICAgKiBAc2VlIGBtYXJrQXNEaXJ0eSgpYFxuICAgKiBAc2VlIGBtYXJrQXNQcmlzdGluZSgpYFxuICAgKlxuICAgKiBAcGFyYW0gb3B0cyBDb25maWd1cmF0aW9uIG9wdGlvbnMgdGhhdCBkZXRlcm1pbmUgaG93IHRoZSBjb250cm9sIHByb3BhZ2F0ZXMgY2hhbmdlc1xuICAgKiBhbmQgZW1pdHMgZXZlbnRzIGFmdGVyIHRoZSBtYXJraW5nIGlzIGFwcGxpZWQuXG4gICAqICogYG9ubHlTZWxmYDogV2hlbiB0cnVlLCBtYXJrIG9ubHkgdGhpcyBjb250cm9sLiBXaGVuIGZhbHNlIG9yIG5vdCBzdXBwbGllZCxcbiAgICogbWFya3MgYWxsIGRpcmVjdCBhbmNlc3RvcnMuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqL1xuICBtYXJrQXNVbnRvdWNoZWQob3B0czoge29ubHlTZWxmPzogYm9vbGVhbn0gPSB7fSk6IHZvaWQge1xuICAgICh0aGlzIGFzIHt0b3VjaGVkOiBib29sZWFufSkudG91Y2hlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3BlbmRpbmdUb3VjaGVkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9mb3JFYWNoQ2hpbGQoKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4ge1xuICAgICAgY29udHJvbC5tYXJrQXNVbnRvdWNoZWQoe29ubHlTZWxmOiB0cnVlfSk7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5fcGFyZW50ICYmICFvcHRzLm9ubHlTZWxmKSB7XG4gICAgICB0aGlzLl9wYXJlbnQuX3VwZGF0ZVRvdWNoZWQob3B0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1hcmtzIHRoZSBjb250cm9sIGFzIGBkaXJ0eWAuIEEgY29udHJvbCBiZWNvbWVzIGRpcnR5IHdoZW5cbiAgICogdGhlIGNvbnRyb2wncyB2YWx1ZSBpcyBjaGFuZ2VkIHRocm91Z2ggdGhlIFVJOyBjb21wYXJlIGBtYXJrQXNUb3VjaGVkYC5cbiAgICpcbiAgICogQHNlZSBgbWFya0FzVG91Y2hlZCgpYFxuICAgKiBAc2VlIGBtYXJrQXNVbnRvdWNoZWQoKWBcbiAgICogQHNlZSBgbWFya0FzUHJpc3RpbmUoKWBcbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzIGNoYW5nZXNcbiAgICogYW5kIGVtaXRzIGV2ZW50cyBhZnRlciBtYXJraW5nIGlzIGFwcGxpZWQuXG4gICAqICogYG9ubHlTZWxmYDogV2hlbiB0cnVlLCBtYXJrIG9ubHkgdGhpcyBjb250cm9sLiBXaGVuIGZhbHNlIG9yIG5vdCBzdXBwbGllZCxcbiAgICogbWFya3MgYWxsIGRpcmVjdCBhbmNlc3RvcnMuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqL1xuICBtYXJrQXNEaXJ0eShvcHRzOiB7b25seVNlbGY/OiBib29sZWFufSA9IHt9KTogdm9pZCB7XG4gICAgKHRoaXMgYXMge3ByaXN0aW5lOiBib29sZWFufSkucHJpc3RpbmUgPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLl9wYXJlbnQgJiYgIW9wdHMub25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC5tYXJrQXNEaXJ0eShvcHRzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFya3MgdGhlIGNvbnRyb2wgYXMgYHByaXN0aW5lYC5cbiAgICpcbiAgICogSWYgdGhlIGNvbnRyb2wgaGFzIGFueSBjaGlsZHJlbiwgbWFya3MgYWxsIGNoaWxkcmVuIGFzIGBwcmlzdGluZWAsXG4gICAqIGFuZCByZWNhbGN1bGF0ZXMgdGhlIGBwcmlzdGluZWAgc3RhdHVzIG9mIGFsbCBwYXJlbnRcbiAgICogY29udHJvbHMuXG4gICAqXG4gICAqIEBzZWUgYG1hcmtBc1RvdWNoZWQoKWBcbiAgICogQHNlZSBgbWFya0FzVW50b3VjaGVkKClgXG4gICAqIEBzZWUgYG1hcmtBc0RpcnR5KClgXG4gICAqXG4gICAqIEBwYXJhbSBvcHRzIENvbmZpZ3VyYXRpb24gb3B0aW9ucyB0aGF0IGRldGVybWluZSBob3cgdGhlIGNvbnRyb2wgZW1pdHMgZXZlbnRzIGFmdGVyXG4gICAqIG1hcmtpbmcgaXMgYXBwbGllZC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG1hcmsgb25seSB0aGlzIGNvbnRyb2wuIFdoZW4gZmFsc2Ugb3Igbm90IHN1cHBsaWVkLFxuICAgKiBtYXJrcyBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICovXG4gIG1hcmtBc1ByaXN0aW5lKG9wdHM6IHtvbmx5U2VsZj86IGJvb2xlYW59ID0ge30pOiB2b2lkIHtcbiAgICAodGhpcyBhcyB7cHJpc3RpbmU6IGJvb2xlYW59KS5wcmlzdGluZSA9IHRydWU7XG4gICAgdGhpcy5fcGVuZGluZ0RpcnR5ID0gZmFsc2U7XG5cbiAgICB0aGlzLl9mb3JFYWNoQ2hpbGQoKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4ge1xuICAgICAgY29udHJvbC5tYXJrQXNQcmlzdGluZSh7b25seVNlbGY6IHRydWV9KTtcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLl9wYXJlbnQgJiYgIW9wdHMub25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlUHJpc3RpbmUob3B0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1hcmtzIHRoZSBjb250cm9sIGFzIGBwZW5kaW5nYC5cbiAgICpcbiAgICogQSBjb250cm9sIGlzIHBlbmRpbmcgd2hpbGUgdGhlIGNvbnRyb2wgcGVyZm9ybXMgYXN5bmMgdmFsaWRhdGlvbi5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzIGNoYW5nZXMgYW5kXG4gICAqIGVtaXRzIGV2ZW50cyBhZnRlciBtYXJraW5nIGlzIGFwcGxpZWQuXG4gICAqICogYG9ubHlTZWxmYDogV2hlbiB0cnVlLCBtYXJrIG9ubHkgdGhpcyBjb250cm9sLiBXaGVuIGZhbHNlIG9yIG5vdCBzdXBwbGllZCxcbiAgICogbWFya3MgYWxsIGRpcmVjdCBhbmNlc3RvcnMuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqICogYGVtaXRFdmVudGA6IFdoZW4gdHJ1ZSBvciBub3Qgc3VwcGxpZWQgKHRoZSBkZWZhdWx0KSwgdGhlIGBzdGF0dXNDaGFuZ2VzYFxuICAgKiBvYnNlcnZhYmxlIGVtaXRzIGFuIGV2ZW50IHdpdGggdGhlIGxhdGVzdCBzdGF0dXMgdGhlIGNvbnRyb2wgaXMgbWFya2VkIHBlbmRpbmcuXG4gICAqIFdoZW4gZmFsc2UsIG5vIGV2ZW50cyBhcmUgZW1pdHRlZC5cbiAgICpcbiAgICovXG4gIG1hcmtBc1BlbmRpbmcob3B0czoge29ubHlTZWxmPzogYm9vbGVhbiwgZW1pdEV2ZW50PzogYm9vbGVhbn0gPSB7fSk6IHZvaWQge1xuICAgICh0aGlzIGFzIHtzdGF0dXM6IEZvcm1Db250cm9sU3RhdHVzfSkuc3RhdHVzID0gUEVORElORztcblxuICAgIGlmIChvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgICh0aGlzLnN0YXR1c0NoYW5nZXMgYXMgRXZlbnRFbWl0dGVyPEZvcm1Db250cm9sU3RhdHVzPikuZW1pdCh0aGlzLnN0YXR1cyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3BhcmVudCAmJiAhb3B0cy5vbmx5U2VsZikge1xuICAgICAgdGhpcy5fcGFyZW50Lm1hcmtBc1BlbmRpbmcob3B0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERpc2FibGVzIHRoZSBjb250cm9sLiBUaGlzIG1lYW5zIHRoZSBjb250cm9sIGlzIGV4ZW1wdCBmcm9tIHZhbGlkYXRpb24gY2hlY2tzIGFuZFxuICAgKiBleGNsdWRlZCBmcm9tIHRoZSBhZ2dyZWdhdGUgdmFsdWUgb2YgYW55IHBhcmVudC4gSXRzIHN0YXR1cyBpcyBgRElTQUJMRURgLlxuICAgKlxuICAgKiBJZiB0aGUgY29udHJvbCBoYXMgY2hpbGRyZW4sIGFsbCBjaGlsZHJlbiBhcmUgYWxzbyBkaXNhYmxlZC5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgQWJzdHJhY3RDb250cm9sLnN0YXR1c31cbiAgICpcbiAgICogQHBhcmFtIG9wdHMgQ29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgZGV0ZXJtaW5lIGhvdyB0aGUgY29udHJvbCBwcm9wYWdhdGVzXG4gICAqIGNoYW5nZXMgYW5kIGVtaXRzIGV2ZW50cyBhZnRlciB0aGUgY29udHJvbCBpcyBkaXNhYmxlZC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG1hcmsgb25seSB0aGlzIGNvbnRyb2wuIFdoZW4gZmFsc2Ugb3Igbm90IHN1cHBsaWVkLFxuICAgKiBtYXJrcyBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCBib3RoIHRoZSBgc3RhdHVzQ2hhbmdlc2AgYW5kXG4gICAqIGB2YWx1ZUNoYW5nZXNgXG4gICAqIG9ic2VydmFibGVzIGVtaXQgZXZlbnRzIHdpdGggdGhlIGxhdGVzdCBzdGF0dXMgYW5kIHZhbHVlIHdoZW4gdGhlIGNvbnRyb2wgaXMgZGlzYWJsZWQuXG4gICAqIFdoZW4gZmFsc2UsIG5vIGV2ZW50cyBhcmUgZW1pdHRlZC5cbiAgICovXG4gIGRpc2FibGUob3B0czoge29ubHlTZWxmPzogYm9vbGVhbiwgZW1pdEV2ZW50PzogYm9vbGVhbn0gPSB7fSk6IHZvaWQge1xuICAgIC8vIElmIHBhcmVudCBoYXMgYmVlbiBtYXJrZWQgYXJ0aWZpY2lhbGx5IGRpcnR5IHdlIGRvbid0IHdhbnQgdG8gcmUtY2FsY3VsYXRlIHRoZVxuICAgIC8vIHBhcmVudCdzIGRpcnRpbmVzcyBiYXNlZCBvbiB0aGUgY2hpbGRyZW4uXG4gICAgY29uc3Qgc2tpcFByaXN0aW5lQ2hlY2sgPSB0aGlzLl9wYXJlbnRNYXJrZWREaXJ0eShvcHRzLm9ubHlTZWxmKTtcblxuICAgICh0aGlzIGFzIHtzdGF0dXM6IEZvcm1Db250cm9sU3RhdHVzfSkuc3RhdHVzID0gRElTQUJMRUQ7XG4gICAgKHRoaXMgYXMge2Vycm9yczogVmFsaWRhdGlvbkVycm9ycyB8IG51bGx9KS5lcnJvcnMgPSBudWxsO1xuICAgIHRoaXMuX2ZvckVhY2hDaGlsZCgoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiB7XG4gICAgICBjb250cm9sLmRpc2FibGUoey4uLm9wdHMsIG9ubHlTZWxmOiB0cnVlfSk7XG4gICAgfSk7XG4gICAgdGhpcy5fdXBkYXRlVmFsdWUoKTtcblxuICAgIGlmIChvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgICh0aGlzLnZhbHVlQ2hhbmdlcyBhcyBFdmVudEVtaXR0ZXI8VFZhbHVlPikuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICAgICh0aGlzLnN0YXR1c0NoYW5nZXMgYXMgRXZlbnRFbWl0dGVyPEZvcm1Db250cm9sU3RhdHVzPikuZW1pdCh0aGlzLnN0YXR1cyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlQW5jZXN0b3JzKHsuLi5vcHRzLCBza2lwUHJpc3RpbmVDaGVja30pO1xuICAgIHRoaXMuX29uRGlzYWJsZWRDaGFuZ2UuZm9yRWFjaCgoY2hhbmdlRm4pID0+IGNoYW5nZUZuKHRydWUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGVzIHRoZSBjb250cm9sLiBUaGlzIG1lYW5zIHRoZSBjb250cm9sIGlzIGluY2x1ZGVkIGluIHZhbGlkYXRpb24gY2hlY2tzIGFuZFxuICAgKiB0aGUgYWdncmVnYXRlIHZhbHVlIG9mIGl0cyBwYXJlbnQuIEl0cyBzdGF0dXMgcmVjYWxjdWxhdGVzIGJhc2VkIG9uIGl0cyB2YWx1ZSBhbmRcbiAgICogaXRzIHZhbGlkYXRvcnMuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGlmIHRoZSBjb250cm9sIGhhcyBjaGlsZHJlbiwgYWxsIGNoaWxkcmVuIGFyZSBlbmFibGVkLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBBYnN0cmFjdENvbnRyb2wuc3RhdHVzfVxuICAgKlxuICAgKiBAcGFyYW0gb3B0cyBDb25maWd1cmUgb3B0aW9ucyB0aGF0IGNvbnRyb2wgaG93IHRoZSBjb250cm9sIHByb3BhZ2F0ZXMgY2hhbmdlcyBhbmRcbiAgICogZW1pdHMgZXZlbnRzIHdoZW4gbWFya2VkIGFzIHVudG91Y2hlZFxuICAgKiAqIGBvbmx5U2VsZmA6IFdoZW4gdHJ1ZSwgbWFyayBvbmx5IHRoaXMgY29udHJvbC4gV2hlbiBmYWxzZSBvciBub3Qgc3VwcGxpZWQsXG4gICAqIG1hcmtzIGFsbCBkaXJlY3QgYW5jZXN0b3JzLiBEZWZhdWx0IGlzIGZhbHNlLlxuICAgKiAqIGBlbWl0RXZlbnRgOiBXaGVuIHRydWUgb3Igbm90IHN1cHBsaWVkICh0aGUgZGVmYXVsdCksIGJvdGggdGhlIGBzdGF0dXNDaGFuZ2VzYCBhbmRcbiAgICogYHZhbHVlQ2hhbmdlc2BcbiAgICogb2JzZXJ2YWJsZXMgZW1pdCBldmVudHMgd2l0aCB0aGUgbGF0ZXN0IHN0YXR1cyBhbmQgdmFsdWUgd2hlbiB0aGUgY29udHJvbCBpcyBlbmFibGVkLlxuICAgKiBXaGVuIGZhbHNlLCBubyBldmVudHMgYXJlIGVtaXR0ZWQuXG4gICAqL1xuICBlbmFibGUob3B0czoge29ubHlTZWxmPzogYm9vbGVhbiwgZW1pdEV2ZW50PzogYm9vbGVhbn0gPSB7fSk6IHZvaWQge1xuICAgIC8vIElmIHBhcmVudCBoYXMgYmVlbiBtYXJrZWQgYXJ0aWZpY2lhbGx5IGRpcnR5IHdlIGRvbid0IHdhbnQgdG8gcmUtY2FsY3VsYXRlIHRoZVxuICAgIC8vIHBhcmVudCdzIGRpcnRpbmVzcyBiYXNlZCBvbiB0aGUgY2hpbGRyZW4uXG4gICAgY29uc3Qgc2tpcFByaXN0aW5lQ2hlY2sgPSB0aGlzLl9wYXJlbnRNYXJrZWREaXJ0eShvcHRzLm9ubHlTZWxmKTtcblxuICAgICh0aGlzIGFzIHtzdGF0dXM6IEZvcm1Db250cm9sU3RhdHVzfSkuc3RhdHVzID0gVkFMSUQ7XG4gICAgdGhpcy5fZm9yRWFjaENoaWxkKChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IHtcbiAgICAgIGNvbnRyb2wuZW5hYmxlKHsuLi5vcHRzLCBvbmx5U2VsZjogdHJ1ZX0pO1xuICAgIH0pO1xuICAgIHRoaXMudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7b25seVNlbGY6IHRydWUsIGVtaXRFdmVudDogb3B0cy5lbWl0RXZlbnR9KTtcblxuICAgIHRoaXMuX3VwZGF0ZUFuY2VzdG9ycyh7Li4ub3B0cywgc2tpcFByaXN0aW5lQ2hlY2t9KTtcbiAgICB0aGlzLl9vbkRpc2FibGVkQ2hhbmdlLmZvckVhY2goKGNoYW5nZUZuKSA9PiBjaGFuZ2VGbihmYWxzZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlQW5jZXN0b3JzKFxuICAgICAgb3B0czoge29ubHlTZWxmPzogYm9vbGVhbiwgZW1pdEV2ZW50PzogYm9vbGVhbiwgc2tpcFByaXN0aW5lQ2hlY2s/OiBib29sZWFufSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wYXJlbnQgJiYgIW9wdHMub25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KG9wdHMpO1xuICAgICAgaWYgKCFvcHRzLnNraXBQcmlzdGluZUNoZWNrKSB7XG4gICAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlUHJpc3RpbmUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlVG91Y2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBwYXJlbnQgb2YgdGhlIGNvbnRyb2xcbiAgICpcbiAgICogQHBhcmFtIHBhcmVudCBUaGUgbmV3IHBhcmVudC5cbiAgICovXG4gIHNldFBhcmVudChwYXJlbnQ6IEZvcm1Hcm91cHxGb3JtQXJyYXl8bnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgY29udHJvbC4gQWJzdHJhY3QgbWV0aG9kIChpbXBsZW1lbnRlZCBpbiBzdWItY2xhc3NlcykuXG4gICAqL1xuICBhYnN0cmFjdCBzZXRWYWx1ZSh2YWx1ZTogVFJhd1ZhbHVlLCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcblxuICAvKipcbiAgICogUGF0Y2hlcyB0aGUgdmFsdWUgb2YgdGhlIGNvbnRyb2wuIEFic3RyYWN0IG1ldGhvZCAoaW1wbGVtZW50ZWQgaW4gc3ViLWNsYXNzZXMpLlxuICAgKi9cbiAgYWJzdHJhY3QgcGF0Y2hWYWx1ZSh2YWx1ZTogVFZhbHVlLCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBjb250cm9sLiBBYnN0cmFjdCBtZXRob2QgKGltcGxlbWVudGVkIGluIHN1Yi1jbGFzc2VzKS5cbiAgICovXG4gIGFic3RyYWN0IHJlc2V0KHZhbHVlPzogVFZhbHVlLCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcblxuICAvKipcbiAgICogVGhlIHJhdyB2YWx1ZSBvZiB0aGlzIGNvbnRyb2wuIEZvciBtb3N0IGNvbnRyb2wgaW1wbGVtZW50YXRpb25zLCB0aGUgcmF3IHZhbHVlIHdpbGwgaW5jbHVkZVxuICAgKiBkaXNhYmxlZCBjaGlsZHJlbi5cbiAgICovXG4gIGdldFJhd1ZhbHVlKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogUmVjYWxjdWxhdGVzIHRoZSB2YWx1ZSBhbmQgdmFsaWRhdGlvbiBzdGF0dXMgb2YgdGhlIGNvbnRyb2wuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGl0IGFsc28gdXBkYXRlcyB0aGUgdmFsdWUgYW5kIHZhbGlkaXR5IG9mIGl0cyBhbmNlc3RvcnMuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRzIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBkZXRlcm1pbmUgaG93IHRoZSBjb250cm9sIHByb3BhZ2F0ZXMgY2hhbmdlcyBhbmQgZW1pdHMgZXZlbnRzXG4gICAqIGFmdGVyIHVwZGF0ZXMgYW5kIHZhbGlkaXR5IGNoZWNrcyBhcmUgYXBwbGllZC5cbiAgICogKiBgb25seVNlbGZgOiBXaGVuIHRydWUsIG9ubHkgdXBkYXRlIHRoaXMgY29udHJvbC4gV2hlbiBmYWxzZSBvciBub3Qgc3VwcGxpZWQsXG4gICAqIHVwZGF0ZSBhbGwgZGlyZWN0IGFuY2VzdG9ycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogKiBgZW1pdEV2ZW50YDogV2hlbiB0cnVlIG9yIG5vdCBzdXBwbGllZCAodGhlIGRlZmF1bHQpLCBib3RoIHRoZSBgc3RhdHVzQ2hhbmdlc2AgYW5kXG4gICAqIGB2YWx1ZUNoYW5nZXNgXG4gICAqIG9ic2VydmFibGVzIGVtaXQgZXZlbnRzIHdpdGggdGhlIGxhdGVzdCBzdGF0dXMgYW5kIHZhbHVlIHdoZW4gdGhlIGNvbnRyb2wgaXMgdXBkYXRlZC5cbiAgICogV2hlbiBmYWxzZSwgbm8gZXZlbnRzIGFyZSBlbWl0dGVkLlxuICAgKi9cbiAgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eShvcHRzOiB7b25seVNlbGY/OiBib29sZWFuLCBlbWl0RXZlbnQ/OiBib29sZWFufSA9IHt9KTogdm9pZCB7XG4gICAgdGhpcy5fc2V0SW5pdGlhbFN0YXR1cygpO1xuICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG5cbiAgICBpZiAodGhpcy5lbmFibGVkKSB7XG4gICAgICB0aGlzLl9jYW5jZWxFeGlzdGluZ1N1YnNjcmlwdGlvbigpO1xuICAgICAgKHRoaXMgYXMge2Vycm9yczogVmFsaWRhdGlvbkVycm9ycyB8IG51bGx9KS5lcnJvcnMgPSB0aGlzLl9ydW5WYWxpZGF0b3IoKTtcbiAgICAgICh0aGlzIGFzIHtzdGF0dXM6IEZvcm1Db250cm9sU3RhdHVzfSkuc3RhdHVzID0gdGhpcy5fY2FsY3VsYXRlU3RhdHVzKCk7XG5cbiAgICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gVkFMSUQgfHwgdGhpcy5zdGF0dXMgPT09IFBFTkRJTkcpIHtcbiAgICAgICAgdGhpcy5fcnVuQXN5bmNWYWxpZGF0b3Iob3B0cy5lbWl0RXZlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvcHRzLmVtaXRFdmVudCAhPT0gZmFsc2UpIHtcbiAgICAgICh0aGlzLnZhbHVlQ2hhbmdlcyBhcyBFdmVudEVtaXR0ZXI8VFZhbHVlPikuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICAgICh0aGlzLnN0YXR1c0NoYW5nZXMgYXMgRXZlbnRFbWl0dGVyPEZvcm1Db250cm9sU3RhdHVzPikuZW1pdCh0aGlzLnN0YXR1cyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3BhcmVudCAmJiAhb3B0cy5vbmx5U2VsZikge1xuICAgICAgdGhpcy5fcGFyZW50LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkob3B0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfdXBkYXRlVHJlZVZhbGlkaXR5KG9wdHM6IHtlbWl0RXZlbnQ/OiBib29sZWFufSA9IHtlbWl0RXZlbnQ6IHRydWV9KTogdm9pZCB7XG4gICAgdGhpcy5fZm9yRWFjaENoaWxkKChjdHJsOiBBYnN0cmFjdENvbnRyb2wpID0+IGN0cmwuX3VwZGF0ZVRyZWVWYWxpZGl0eShvcHRzKSk7XG4gICAgdGhpcy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHtvbmx5U2VsZjogdHJ1ZSwgZW1pdEV2ZW50OiBvcHRzLmVtaXRFdmVudH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0SW5pdGlhbFN0YXR1cygpIHtcbiAgICAodGhpcyBhcyB7c3RhdHVzOiBGb3JtQ29udHJvbFN0YXR1c30pLnN0YXR1cyA9IHRoaXMuX2FsbENvbnRyb2xzRGlzYWJsZWQoKSA/IERJU0FCTEVEIDogVkFMSUQ7XG4gIH1cblxuICBwcml2YXRlIF9ydW5WYWxpZGF0b3IoKTogVmFsaWRhdGlvbkVycm9yc3xudWxsIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0b3IgPyB0aGlzLnZhbGlkYXRvcih0aGlzKSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9ydW5Bc3luY1ZhbGlkYXRvcihlbWl0RXZlbnQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXN5bmNWYWxpZGF0b3IpIHtcbiAgICAgICh0aGlzIGFzIHtzdGF0dXM6IEZvcm1Db250cm9sU3RhdHVzfSkuc3RhdHVzID0gUEVORElORztcbiAgICAgIHRoaXMuX2hhc093blBlbmRpbmdBc3luY1ZhbGlkYXRvciA9IHRydWU7XG4gICAgICBjb25zdCBvYnMgPSB0b09ic2VydmFibGUodGhpcy5hc3luY1ZhbGlkYXRvcih0aGlzKSk7XG4gICAgICB0aGlzLl9hc3luY1ZhbGlkYXRpb25TdWJzY3JpcHRpb24gPSBvYnMuc3Vic2NyaWJlKChlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCkgPT4ge1xuICAgICAgICB0aGlzLl9oYXNPd25QZW5kaW5nQXN5bmNWYWxpZGF0b3IgPSBmYWxzZTtcbiAgICAgICAgLy8gVGhpcyB3aWxsIHRyaWdnZXIgdGhlIHJlY2FsY3VsYXRpb24gb2YgdGhlIHZhbGlkYXRpb24gc3RhdHVzLCB3aGljaCBkZXBlbmRzIG9uXG4gICAgICAgIC8vIHRoZSBzdGF0ZSBvZiB0aGUgYXN5bmNocm9ub3VzIHZhbGlkYXRpb24gKHdoZXRoZXIgaXQgaXMgaW4gcHJvZ3Jlc3Mgb3Igbm90KS4gU28sIGl0IGlzXG4gICAgICAgIC8vIG5lY2Vzc2FyeSB0aGF0IHdlIGhhdmUgdXBkYXRlZCB0aGUgYF9oYXNPd25QZW5kaW5nQXN5bmNWYWxpZGF0b3JgIGJvb2xlYW4gZmxhZyBmaXJzdC5cbiAgICAgICAgdGhpcy5zZXRFcnJvcnMoZXJyb3JzLCB7ZW1pdEV2ZW50fSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9jYW5jZWxFeGlzdGluZ1N1YnNjcmlwdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fYXN5bmNWYWxpZGF0aW9uU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLl9hc3luY1ZhbGlkYXRpb25TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuX2hhc093blBlbmRpbmdBc3luY1ZhbGlkYXRvciA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGVycm9ycyBvbiBhIGZvcm0gY29udHJvbCB3aGVuIHJ1bm5pbmcgdmFsaWRhdGlvbnMgbWFudWFsbHksIHJhdGhlciB0aGFuIGF1dG9tYXRpY2FsbHkuXG4gICAqXG4gICAqIENhbGxpbmcgYHNldEVycm9yc2AgYWxzbyB1cGRhdGVzIHRoZSB2YWxpZGl0eSBvZiB0aGUgcGFyZW50IGNvbnRyb2wuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRzIENvbmZpZ3VyYXRpb24gb3B0aW9ucyB0aGF0IGRldGVybWluZSBob3cgdGhlIGNvbnRyb2wgcHJvcGFnYXRlc1xuICAgKiBjaGFuZ2VzIGFuZCBlbWl0cyBldmVudHMgYWZ0ZXIgdGhlIGNvbnRyb2wgZXJyb3JzIGFyZSBzZXQuXG4gICAqICogYGVtaXRFdmVudGA6IFdoZW4gdHJ1ZSBvciBub3Qgc3VwcGxpZWQgKHRoZSBkZWZhdWx0KSwgdGhlIGBzdGF0dXNDaGFuZ2VzYFxuICAgKiBvYnNlcnZhYmxlIGVtaXRzIGFuIGV2ZW50IGFmdGVyIHRoZSBlcnJvcnMgYXJlIHNldC5cbiAgICpcbiAgICogQHVzYWdlTm90ZXNcbiAgICpcbiAgICogIyMjIE1hbnVhbGx5IHNldCB0aGUgZXJyb3JzIGZvciBhIGNvbnRyb2xcbiAgICpcbiAgICogYGBgXG4gICAqIGNvbnN0IGxvZ2luID0gbmV3IEZvcm1Db250cm9sKCdzb21lTG9naW4nKTtcbiAgICogbG9naW4uc2V0RXJyb3JzKHtcbiAgICogICBub3RVbmlxdWU6IHRydWVcbiAgICogfSk7XG4gICAqXG4gICAqIGV4cGVjdChsb2dpbi52YWxpZCkudG9FcXVhbChmYWxzZSk7XG4gICAqIGV4cGVjdChsb2dpbi5lcnJvcnMpLnRvRXF1YWwoeyBub3RVbmlxdWU6IHRydWUgfSk7XG4gICAqXG4gICAqIGxvZ2luLnNldFZhbHVlKCdzb21lT3RoZXJMb2dpbicpO1xuICAgKlxuICAgKiBleHBlY3QobG9naW4udmFsaWQpLnRvRXF1YWwodHJ1ZSk7XG4gICAqIGBgYFxuICAgKi9cbiAgc2V0RXJyb3JzKGVycm9yczogVmFsaWRhdGlvbkVycm9yc3xudWxsLCBvcHRzOiB7ZW1pdEV2ZW50PzogYm9vbGVhbn0gPSB7fSk6IHZvaWQge1xuICAgICh0aGlzIGFzIHtlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsfSkuZXJyb3JzID0gZXJyb3JzO1xuICAgIHRoaXMuX3VwZGF0ZUNvbnRyb2xzRXJyb3JzKG9wdHMuZW1pdEV2ZW50ICE9PSBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgY2hpbGQgY29udHJvbCBnaXZlbiB0aGUgY29udHJvbCdzIG5hbWUgb3IgcGF0aC5cbiAgICpcbiAgICogVGhpcyBzaWduYXR1cmUgZm9yIGdldCBzdXBwb3J0cyBzdHJpbmdzIGFuZCBgY29uc3RgIGFycmF5cyAoYC5nZXQoWydmb28nLCAnYmFyJ10gYXMgY29uc3QpYCkuXG4gICAqL1xuICBnZXQ8UCBleHRlbmRzIHN0cmluZ3wocmVhZG9ubHkoc3RyaW5nfG51bWJlcilbXSk+KHBhdGg6IFApOlxuICAgICAgQWJzdHJhY3RDb250cm9sPMm1R2V0UHJvcGVydHk8VFJhd1ZhbHVlLCBQPj58bnVsbDtcblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgY2hpbGQgY29udHJvbCBnaXZlbiB0aGUgY29udHJvbCdzIG5hbWUgb3IgcGF0aC5cbiAgICpcbiAgICogVGhpcyBzaWduYXR1cmUgZm9yIGBnZXRgIHN1cHBvcnRzIG5vbi1jb25zdCAobXV0YWJsZSkgYXJyYXlzLiBJbmZlcnJlZCB0eXBlXG4gICAqIGluZm9ybWF0aW9uIHdpbGwgbm90IGJlIGFzIHJvYnVzdCwgc28gcHJlZmVyIHRvIHBhc3MgYSBgcmVhZG9ubHlgIGFycmF5IGlmIHBvc3NpYmxlLlxuICAgKi9cbiAgZ2V0PFAgZXh0ZW5kcyBzdHJpbmd8QXJyYXk8c3RyaW5nfG51bWJlcj4+KHBhdGg6IFApOlxuICAgICAgQWJzdHJhY3RDb250cm9sPMm1R2V0UHJvcGVydHk8VFJhd1ZhbHVlLCBQPj58bnVsbDtcblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgY2hpbGQgY29udHJvbCBnaXZlbiB0aGUgY29udHJvbCdzIG5hbWUgb3IgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggQSBkb3QtZGVsaW1pdGVkIHN0cmluZyBvciBhcnJheSBvZiBzdHJpbmcvbnVtYmVyIHZhbHVlcyB0aGF0IGRlZmluZSB0aGUgcGF0aCB0byB0aGVcbiAgICogY29udHJvbC4gSWYgYSBzdHJpbmcgaXMgcHJvdmlkZWQsIHBhc3NpbmcgaXQgYXMgYSBzdHJpbmcgbGl0ZXJhbCB3aWxsIHJlc3VsdCBpbiBpbXByb3ZlZCB0eXBlXG4gICAqIGluZm9ybWF0aW9uLiBMaWtld2lzZSwgaWYgYW4gYXJyYXkgaXMgcHJvdmlkZWQsIHBhc3NpbmcgaXQgYGFzIGNvbnN0YCB3aWxsIGNhdXNlIGltcHJvdmVkIHR5cGVcbiAgICogaW5mb3JtYXRpb24gdG8gYmUgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAdXNhZ2VOb3Rlc1xuICAgKiAjIyMgUmV0cmlldmUgYSBuZXN0ZWQgY29udHJvbFxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYG5hbWVgIGNvbnRyb2wgbmVzdGVkIHdpdGhpbiBhIGBwZXJzb25gIHN1Yi1ncm91cDpcbiAgICpcbiAgICogKiBgdGhpcy5mb3JtLmdldCgncGVyc29uLm5hbWUnKTtgXG4gICAqXG4gICAqIC1PUi1cbiAgICpcbiAgICogKiBgdGhpcy5mb3JtLmdldChbJ3BlcnNvbicsICduYW1lJ10gYXMgY29uc3QpO2AgLy8gYGFzIGNvbnN0YCBnaXZlcyBpbXByb3ZlZCB0eXBpbmdzXG4gICAqXG4gICAqICMjIyBSZXRyaWV2ZSBhIGNvbnRyb2wgaW4gYSBGb3JtQXJyYXlcbiAgICpcbiAgICogV2hlbiBhY2Nlc3NpbmcgYW4gZWxlbWVudCBpbnNpZGUgYSBGb3JtQXJyYXksIHlvdSBjYW4gdXNlIGFuIGVsZW1lbnQgaW5kZXguXG4gICAqIEZvciBleGFtcGxlLCB0byBnZXQgYSBgcHJpY2VgIGNvbnRyb2wgZnJvbSB0aGUgZmlyc3QgZWxlbWVudCBpbiBhbiBgaXRlbXNgIGFycmF5IHlvdSBjYW4gdXNlOlxuICAgKlxuICAgKiAqIGB0aGlzLmZvcm0uZ2V0KCdpdGVtcy4wLnByaWNlJyk7YFxuICAgKlxuICAgKiAtT1ItXG4gICAqXG4gICAqICogYHRoaXMuZm9ybS5nZXQoWydpdGVtcycsIDAsICdwcmljZSddKTtgXG4gICAqL1xuICBnZXQ8UCBleHRlbmRzIHN0cmluZ3woKHN0cmluZyB8IG51bWJlcilbXSk+KHBhdGg6IFApOlxuICAgICAgQWJzdHJhY3RDb250cm9sPMm1R2V0UHJvcGVydHk8VFJhd1ZhbHVlLCBQPj58bnVsbCB7XG4gICAgbGV0IGN1cnJQYXRoOiBBcnJheTxzdHJpbmd8bnVtYmVyPnxzdHJpbmcgPSBwYXRoO1xuICAgIGlmIChjdXJyUGF0aCA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoY3VyclBhdGgpKSBjdXJyUGF0aCA9IGN1cnJQYXRoLnNwbGl0KCcuJyk7XG4gICAgaWYgKGN1cnJQYXRoLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIGN1cnJQYXRoLnJlZHVjZShcbiAgICAgICAgKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbHxudWxsLCBuYW1lKSA9PiBjb250cm9sICYmIGNvbnRyb2wuX2ZpbmQobmFtZSksIHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBSZXBvcnRzIGVycm9yIGRhdGEgZm9yIHRoZSBjb250cm9sIHdpdGggdGhlIGdpdmVuIHBhdGguXG4gICAqXG4gICAqIEBwYXJhbSBlcnJvckNvZGUgVGhlIGNvZGUgb2YgdGhlIGVycm9yIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBwYXRoIEEgbGlzdCBvZiBjb250cm9sIG5hbWVzIHRoYXQgZGVzaWduYXRlcyBob3cgdG8gbW92ZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRyb2xcbiAgICogdG8gdGhlIGNvbnRyb2wgdGhhdCBzaG91bGQgYmUgcXVlcmllZCBmb3IgZXJyb3JzLlxuICAgKlxuICAgKiBAdXNhZ2VOb3Rlc1xuICAgKiBGb3IgZXhhbXBsZSwgZm9yIHRoZSBmb2xsb3dpbmcgYEZvcm1Hcm91cGA6XG4gICAqXG4gICAqIGBgYFxuICAgKiBmb3JtID0gbmV3IEZvcm1Hcm91cCh7XG4gICAqICAgYWRkcmVzczogbmV3IEZvcm1Hcm91cCh7IHN0cmVldDogbmV3IEZvcm1Db250cm9sKCkgfSlcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKlxuICAgKiBUaGUgcGF0aCB0byB0aGUgJ3N0cmVldCcgY29udHJvbCBmcm9tIHRoZSByb290IGZvcm0gd291bGQgYmUgJ2FkZHJlc3MnIC0+ICdzdHJlZXQnLlxuICAgKlxuICAgKiBJdCBjYW4gYmUgcHJvdmlkZWQgdG8gdGhpcyBtZXRob2QgaW4gb25lIG9mIHR3byBmb3JtYXRzOlxuICAgKlxuICAgKiAxLiBBbiBhcnJheSBvZiBzdHJpbmcgY29udHJvbCBuYW1lcywgZS5nLiBgWydhZGRyZXNzJywgJ3N0cmVldCddYFxuICAgKiAxLiBBIHBlcmlvZC1kZWxpbWl0ZWQgbGlzdCBvZiBjb250cm9sIG5hbWVzIGluIG9uZSBzdHJpbmcsIGUuZy4gYCdhZGRyZXNzLnN0cmVldCdgXG4gICAqXG4gICAqIEByZXR1cm5zIGVycm9yIGRhdGEgZm9yIHRoYXQgcGFydGljdWxhciBlcnJvci4gSWYgdGhlIGNvbnRyb2wgb3IgZXJyb3IgaXMgbm90IHByZXNlbnQsXG4gICAqIG51bGwgaXMgcmV0dXJuZWQuXG4gICAqL1xuICBnZXRFcnJvcihlcnJvckNvZGU6IHN0cmluZywgcGF0aD86IEFycmF5PHN0cmluZ3xudW1iZXI+fHN0cmluZyk6IGFueSB7XG4gICAgY29uc3QgY29udHJvbCA9IHBhdGggPyB0aGlzLmdldChwYXRoKSA6IHRoaXM7XG4gICAgcmV0dXJuIGNvbnRyb2wgJiYgY29udHJvbC5lcnJvcnMgPyBjb250cm9sLmVycm9yc1tlcnJvckNvZGVdIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogUmVwb3J0cyB3aGV0aGVyIHRoZSBjb250cm9sIHdpdGggdGhlIGdpdmVuIHBhdGggaGFzIHRoZSBlcnJvciBzcGVjaWZpZWQuXG4gICAqXG4gICAqIEBwYXJhbSBlcnJvckNvZGUgVGhlIGNvZGUgb2YgdGhlIGVycm9yIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBwYXRoIEEgbGlzdCBvZiBjb250cm9sIG5hbWVzIHRoYXQgZGVzaWduYXRlcyBob3cgdG8gbW92ZSBmcm9tIHRoZSBjdXJyZW50IGNvbnRyb2xcbiAgICogdG8gdGhlIGNvbnRyb2wgdGhhdCBzaG91bGQgYmUgcXVlcmllZCBmb3IgZXJyb3JzLlxuICAgKlxuICAgKiBAdXNhZ2VOb3Rlc1xuICAgKiBGb3IgZXhhbXBsZSwgZm9yIHRoZSBmb2xsb3dpbmcgYEZvcm1Hcm91cGA6XG4gICAqXG4gICAqIGBgYFxuICAgKiBmb3JtID0gbmV3IEZvcm1Hcm91cCh7XG4gICAqICAgYWRkcmVzczogbmV3IEZvcm1Hcm91cCh7IHN0cmVldDogbmV3IEZvcm1Db250cm9sKCkgfSlcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKlxuICAgKiBUaGUgcGF0aCB0byB0aGUgJ3N0cmVldCcgY29udHJvbCBmcm9tIHRoZSByb290IGZvcm0gd291bGQgYmUgJ2FkZHJlc3MnIC0+ICdzdHJlZXQnLlxuICAgKlxuICAgKiBJdCBjYW4gYmUgcHJvdmlkZWQgdG8gdGhpcyBtZXRob2QgaW4gb25lIG9mIHR3byBmb3JtYXRzOlxuICAgKlxuICAgKiAxLiBBbiBhcnJheSBvZiBzdHJpbmcgY29udHJvbCBuYW1lcywgZS5nLiBgWydhZGRyZXNzJywgJ3N0cmVldCddYFxuICAgKiAxLiBBIHBlcmlvZC1kZWxpbWl0ZWQgbGlzdCBvZiBjb250cm9sIG5hbWVzIGluIG9uZSBzdHJpbmcsIGUuZy4gYCdhZGRyZXNzLnN0cmVldCdgXG4gICAqXG4gICAqIElmIG5vIHBhdGggaXMgZ2l2ZW4sIHRoaXMgbWV0aG9kIGNoZWNrcyBmb3IgdGhlIGVycm9yIG9uIHRoZSBjdXJyZW50IGNvbnRyb2wuXG4gICAqXG4gICAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIGVycm9yIGlzIHByZXNlbnQgaW4gdGhlIGNvbnRyb2wgYXQgdGhlIGdpdmVuIHBhdGguXG4gICAqXG4gICAqIElmIHRoZSBjb250cm9sIGlzIG5vdCBwcmVzZW50LCBmYWxzZSBpcyByZXR1cm5lZC5cbiAgICovXG4gIGhhc0Vycm9yKGVycm9yQ29kZTogc3RyaW5nLCBwYXRoPzogQXJyYXk8c3RyaW5nfG51bWJlcj58c3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5nZXRFcnJvcihlcnJvckNvZGUsIHBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgdG9wLWxldmVsIGFuY2VzdG9yIG9mIHRoaXMgY29udHJvbC5cbiAgICovXG4gIGdldCByb290KCk6IEFic3RyYWN0Q29udHJvbCB7XG4gICAgbGV0IHg6IEFic3RyYWN0Q29udHJvbCA9IHRoaXM7XG5cbiAgICB3aGlsZSAoeC5fcGFyZW50KSB7XG4gICAgICB4ID0geC5fcGFyZW50O1xuICAgIH1cblxuICAgIHJldHVybiB4O1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfdXBkYXRlQ29udHJvbHNFcnJvcnMoZW1pdEV2ZW50OiBib29sZWFuKTogdm9pZCB7XG4gICAgKHRoaXMgYXMge3N0YXR1czogRm9ybUNvbnRyb2xTdGF0dXN9KS5zdGF0dXMgPSB0aGlzLl9jYWxjdWxhdGVTdGF0dXMoKTtcblxuICAgIGlmIChlbWl0RXZlbnQpIHtcbiAgICAgICh0aGlzLnN0YXR1c0NoYW5nZXMgYXMgRXZlbnRFbWl0dGVyPEZvcm1Db250cm9sU3RhdHVzPikuZW1pdCh0aGlzLnN0YXR1cyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3BhcmVudCkge1xuICAgICAgdGhpcy5fcGFyZW50Ll91cGRhdGVDb250cm9sc0Vycm9ycyhlbWl0RXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX2luaXRPYnNlcnZhYmxlcygpIHtcbiAgICAodGhpcyBhcyB7dmFsdWVDaGFuZ2VzOiBPYnNlcnZhYmxlPFRWYWx1ZT59KS52YWx1ZUNoYW5nZXMgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgKHRoaXMgYXMge3N0YXR1c0NoYW5nZXM6IE9ic2VydmFibGU8Rm9ybUNvbnRyb2xTdGF0dXM+fSkuc3RhdHVzQ2hhbmdlcyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSBfY2FsY3VsYXRlU3RhdHVzKCk6IEZvcm1Db250cm9sU3RhdHVzIHtcbiAgICBpZiAodGhpcy5fYWxsQ29udHJvbHNEaXNhYmxlZCgpKSByZXR1cm4gRElTQUJMRUQ7XG4gICAgaWYgKHRoaXMuZXJyb3JzKSByZXR1cm4gSU5WQUxJRDtcbiAgICBpZiAodGhpcy5faGFzT3duUGVuZGluZ0FzeW5jVmFsaWRhdG9yIHx8IHRoaXMuX2FueUNvbnRyb2xzSGF2ZVN0YXR1cyhQRU5ESU5HKSkgcmV0dXJuIFBFTkRJTkc7XG4gICAgaWYgKHRoaXMuX2FueUNvbnRyb2xzSGF2ZVN0YXR1cyhJTlZBTElEKSkgcmV0dXJuIElOVkFMSUQ7XG4gICAgcmV0dXJuIFZBTElEO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBhYnN0cmFjdCBfdXBkYXRlVmFsdWUoKTogdm9pZDtcblxuICAvKiogQGludGVybmFsICovXG4gIGFic3RyYWN0IF9mb3JFYWNoQ2hpbGQoY2I6IChjOiBBYnN0cmFjdENvbnRyb2wpID0+IHZvaWQpOiB2b2lkO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYWJzdHJhY3QgX2FueUNvbnRyb2xzKGNvbmRpdGlvbjogKGM6IEFic3RyYWN0Q29udHJvbCkgPT4gYm9vbGVhbik6IGJvb2xlYW47XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBhYnN0cmFjdCBfYWxsQ29udHJvbHNEaXNhYmxlZCgpOiBib29sZWFuO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgYWJzdHJhY3QgX3N5bmNQZW5kaW5nQ29udHJvbHMoKTogYm9vbGVhbjtcblxuICAvKiogQGludGVybmFsICovXG4gIF9hbnlDb250cm9sc0hhdmVTdGF0dXMoc3RhdHVzOiBGb3JtQ29udHJvbFN0YXR1cyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9hbnlDb250cm9scygoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBjb250cm9sLnN0YXR1cyA9PT0gc3RhdHVzKTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX2FueUNvbnRyb2xzRGlydHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2FueUNvbnRyb2xzKChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IGNvbnRyb2wuZGlydHkpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfYW55Q29udHJvbHNUb3VjaGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9hbnlDb250cm9scygoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBjb250cm9sLnRvdWNoZWQpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfdXBkYXRlUHJpc3RpbmUob3B0czoge29ubHlTZWxmPzogYm9vbGVhbn0gPSB7fSk6IHZvaWQge1xuICAgICh0aGlzIGFzIHtwcmlzdGluZTogYm9vbGVhbn0pLnByaXN0aW5lID0gIXRoaXMuX2FueUNvbnRyb2xzRGlydHkoKTtcblxuICAgIGlmICh0aGlzLl9wYXJlbnQgJiYgIW9wdHMub25seVNlbGYpIHtcbiAgICAgIHRoaXMuX3BhcmVudC5fdXBkYXRlUHJpc3RpbmUob3B0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfdXBkYXRlVG91Y2hlZChvcHRzOiB7b25seVNlbGY/OiBib29sZWFufSA9IHt9KTogdm9pZCB7XG4gICAgKHRoaXMgYXMge3RvdWNoZWQ6IGJvb2xlYW59KS50b3VjaGVkID0gdGhpcy5fYW55Q29udHJvbHNUb3VjaGVkKCk7XG5cbiAgICBpZiAodGhpcy5fcGFyZW50ICYmICFvcHRzLm9ubHlTZWxmKSB7XG4gICAgICB0aGlzLl9wYXJlbnQuX3VwZGF0ZVRvdWNoZWQob3B0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfb25EaXNhYmxlZENoYW5nZTogQXJyYXk8KGlzRGlzYWJsZWQ6IGJvb2xlYW4pID0+IHZvaWQ+ID0gW107XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfcmVnaXN0ZXJPbkNvbGxlY3Rpb25DaGFuZ2UoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLl9vbkNvbGxlY3Rpb25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3NldFVwZGF0ZVN0cmF0ZWd5KG9wdHM/OiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdfEFic3RyYWN0Q29udHJvbE9wdGlvbnN8bnVsbCk6IHZvaWQge1xuICAgIGlmIChpc09wdGlvbnNPYmoob3B0cykgJiYgb3B0cy51cGRhdGVPbiAhPSBudWxsKSB7XG4gICAgICB0aGlzLl91cGRhdGVPbiA9IG9wdHMudXBkYXRlT24hO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogQ2hlY2sgdG8gc2VlIGlmIHBhcmVudCBoYXMgYmVlbiBtYXJrZWQgYXJ0aWZpY2lhbGx5IGRpcnR5LlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX3BhcmVudE1hcmtlZERpcnR5KG9ubHlTZWxmPzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhcmVudERpcnR5ID0gdGhpcy5fcGFyZW50ICYmIHRoaXMuX3BhcmVudC5kaXJ0eTtcbiAgICByZXR1cm4gIW9ubHlTZWxmICYmICEhcGFyZW50RGlydHkgJiYgIXRoaXMuX3BhcmVudCEuX2FueUNvbnRyb2xzRGlydHkoKTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX2ZpbmQobmFtZTogc3RyaW5nfG51bWJlcik6IEFic3RyYWN0Q29udHJvbHxudWxsIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgYHNldFZhbGlkYXRvcnNgIG1ldGhvZC4gTmVlZHMgdG8gYmUgc2VwYXJhdGVkIG91dCBpbnRvIGFcbiAgICogZGlmZmVyZW50IG1ldGhvZCwgYmVjYXVzZSBpdCBpcyBjYWxsZWQgaW4gdGhlIGNvbnN0cnVjdG9yIGFuZCBpdCBjYW4gYnJlYWsgY2FzZXMgd2hlcmVcbiAgICogYSBjb250cm9sIGlzIGV4dGVuZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfYXNzaWduVmFsaWRhdG9ycyh2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbnxWYWxpZGF0b3JGbltdfG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9yYXdWYWxpZGF0b3JzID0gQXJyYXkuaXNBcnJheSh2YWxpZGF0b3JzKSA/IHZhbGlkYXRvcnMuc2xpY2UoKSA6IHZhbGlkYXRvcnM7XG4gICAgdGhpcy5fY29tcG9zZWRWYWxpZGF0b3JGbiA9IGNvZXJjZVRvVmFsaWRhdG9yKHRoaXMuX3Jhd1ZhbGlkYXRvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIHRoZSBgc2V0QXN5bmNWYWxpZGF0b3JzYCBtZXRob2QuIE5lZWRzIHRvIGJlIHNlcGFyYXRlZCBvdXQgaW50byBhXG4gICAqIGRpZmZlcmVudCBtZXRob2QsIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGluIHRoZSBjb25zdHJ1Y3RvciBhbmQgaXQgY2FuIGJyZWFrIGNhc2VzIHdoZXJlXG4gICAqIGEgY29udHJvbCBpcyBleHRlbmRlZC5cbiAgICovXG4gIHByaXZhdGUgX2Fzc2lnbkFzeW5jVmFsaWRhdG9ycyh2YWxpZGF0b3JzOiBBc3luY1ZhbGlkYXRvckZufEFzeW5jVmFsaWRhdG9yRm5bXXxudWxsKTogdm9pZCB7XG4gICAgdGhpcy5fcmF3QXN5bmNWYWxpZGF0b3JzID0gQXJyYXkuaXNBcnJheSh2YWxpZGF0b3JzKSA/IHZhbGlkYXRvcnMuc2xpY2UoKSA6IHZhbGlkYXRvcnM7XG4gICAgdGhpcy5fY29tcG9zZWRBc3luY1ZhbGlkYXRvckZuID0gY29lcmNlVG9Bc3luY1ZhbGlkYXRvcih0aGlzLl9yYXdBc3luY1ZhbGlkYXRvcnMpO1xuICB9XG59XG4iXX0=
|