@angular/animations 6.0.3 → 6.0.7

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.
Files changed (91) hide show
  1. package/browser/browser.metadata.json +1 -1
  2. package/browser/src/dsl/animation_transition_factory.d.ts +1 -1
  3. package/browser/src/render/animation_engine_next.d.ts +2 -1
  4. package/browser/src/render/shared.d.ts +2 -0
  5. package/browser/src/render/timeline_animation_engine.d.ts +2 -1
  6. package/browser/src/render/transition_animation_engine.d.ts +3 -3
  7. package/browser/testing.d.ts +0 -5
  8. package/browser/testing.metadata.json +1 -1
  9. package/browser.d.ts +0 -5
  10. package/browser.metadata.json +1 -1
  11. package/bundles/animations-browser-testing.umd.js +28 -10
  12. package/bundles/animations-browser-testing.umd.js.map +1 -1
  13. package/bundles/animations-browser-testing.umd.min.js +16 -2
  14. package/bundles/animations-browser-testing.umd.min.js.map +1 -1
  15. package/bundles/animations-browser.umd.js +200 -83
  16. package/bundles/animations-browser.umd.js.map +1 -1
  17. package/bundles/animations-browser.umd.min.js +55 -6
  18. package/bundles/animations-browser.umd.min.js.map +1 -1
  19. package/bundles/animations.umd.js +470 -577
  20. package/bundles/animations.umd.js.map +1 -1
  21. package/bundles/animations.umd.min.js +9 -2
  22. package/bundles/animations.umd.min.js.map +1 -1
  23. package/esm2015/animations.externs.js +1 -1
  24. package/esm2015/browser/browser.externs.js +3 -3
  25. package/esm2015/browser/src/dsl/animation_transition_factory.js +4 -3
  26. package/esm2015/browser/src/render/animation_driver.js +1 -12
  27. package/esm2015/browser/src/render/animation_engine_next.js +8 -4
  28. package/esm2015/browser/src/render/shared.js +18 -3
  29. package/esm2015/browser/src/render/timeline_animation_engine.js +6 -2
  30. package/esm2015/browser/src/render/transition_animation_engine.js +23 -19
  31. package/esm2015/browser/src/render/web_animations/web_animations_driver.js +3 -3
  32. package/esm2015/browser/src/util.js +57 -1
  33. package/esm2015/src/animation_metadata.js +626 -659
  34. package/esm2015/src/version.js +1 -1
  35. package/esm5/browser/index.js +5 -1
  36. package/esm5/browser/public_api.js +6 -1
  37. package/esm5/browser/src/browser.js +6 -1
  38. package/esm5/browser/src/dsl/animation.js +1 -1
  39. package/esm5/browser/src/dsl/animation_ast_builder.js +11 -4
  40. package/esm5/browser/src/dsl/animation_timeline_builder.js +27 -21
  41. package/esm5/browser/src/dsl/animation_timeline_instruction.js +1 -1
  42. package/esm5/browser/src/dsl/animation_transition_expr.js +1 -1
  43. package/esm5/browser/src/dsl/animation_transition_factory.js +3 -3
  44. package/esm5/browser/src/dsl/animation_transition_instruction.js +1 -1
  45. package/esm5/browser/src/dsl/animation_trigger.js +2 -8
  46. package/esm5/browser/src/dsl/element_instruction_map.js +1 -1
  47. package/esm5/browser/src/dsl/style_normalization/animation_style_normalizer.js +3 -15
  48. package/esm5/browser/src/dsl/style_normalization/web_animations_style_normalizer.js +8 -1
  49. package/esm5/browser/src/private_export.js +8 -1
  50. package/esm5/browser/src/render/animation_driver.js +8 -3
  51. package/esm5/browser/src/render/animation_engine_next.js +5 -4
  52. package/esm5/browser/src/render/css_keyframes/css_keyframes_driver.js +1 -1
  53. package/esm5/browser/src/render/css_keyframes/css_keyframes_player.js +2 -4
  54. package/esm5/browser/src/render/css_keyframes/direct_style_player.js +8 -1
  55. package/esm5/browser/src/render/css_keyframes/element_animation_style_handler.js +1 -1
  56. package/esm5/browser/src/render/shared.js +19 -3
  57. package/esm5/browser/src/render/timeline_animation_engine.js +10 -2
  58. package/esm5/browser/src/render/transition_animation_engine.js +36 -39
  59. package/esm5/browser/src/render/web_animations/dom_animation.js +1 -1
  60. package/esm5/browser/src/render/web_animations/web_animations_driver.js +3 -3
  61. package/esm5/browser/src/render/web_animations/web_animations_player.js +3 -7
  62. package/esm5/browser/src/util.js +51 -3
  63. package/esm5/browser/testing/index.js +5 -1
  64. package/esm5/browser/testing/public_api.js +6 -1
  65. package/esm5/browser/testing/src/mock_animation_driver.js +12 -17
  66. package/esm5/browser/testing/src/testing.js +8 -1
  67. package/esm5/index.js +5 -1
  68. package/esm5/public_api.js +6 -1
  69. package/esm5/src/animation_builder.js +3 -93
  70. package/esm5/src/animation_event.js +1 -1
  71. package/esm5/src/animation_metadata.js +439 -568
  72. package/esm5/src/animations.js +6 -1
  73. package/esm5/src/players/animation_group_player.js +2 -4
  74. package/esm5/src/players/animation_player.js +11 -14
  75. package/esm5/src/private_export.js +8 -1
  76. package/esm5/src/util.js +1 -1
  77. package/esm5/src/version.js +3 -23
  78. package/fesm2015/animations.js +446 -631
  79. package/fesm2015/animations.js.map +1 -1
  80. package/fesm2015/browser/testing.js +1 -1
  81. package/fesm2015/browser/testing.js.map +1 -1
  82. package/fesm2015/browser.js +104 -29
  83. package/fesm2015/browser.js.map +1 -1
  84. package/fesm5/animations.js +470 -577
  85. package/fesm5/animations.js.map +1 -1
  86. package/fesm5/browser/testing.js +28 -10
  87. package/fesm5/browser/testing.js.map +1 -1
  88. package/fesm5/browser.js +200 -83
  89. package/fesm5/browser.js.map +1 -1
  90. package/package.json +3 -3
  91. package/src/animation_metadata.d.ts +673 -650
@@ -8,6 +8,9 @@
8
8
  *
9
9
  * Use of this source code is governed by an MIT-style license that can be
10
10
  * found in the LICENSE file at https://angular.io/license
11
+ */
12
+ /**
13
+ * Represents a set of CSS styles for use in an animation style.
11
14
  * @record
12
15
  */
13
16
  export function ɵStyleData() { }
@@ -18,27 +21,79 @@ function ɵStyleData_tsickle_Closure_declarations() {
18
21
  }
19
22
  /** @enum {number} */
20
23
  const AnimationMetadataType = {
24
+ /**
25
+ * Associates a named animation state with a set of CSS styles.
26
+ * See `state()`
27
+ */
21
28
  State: 0,
29
+ /**
30
+ * Data for a transition from one animation state to another.
31
+ * See `transition()`
32
+ */
22
33
  Transition: 1,
34
+ /**
35
+ * Contains a set of animation steps.
36
+ * See `sequence()`
37
+ */
23
38
  Sequence: 2,
39
+ /**
40
+ * Contains a set of animation steps.
41
+ * See `{@link animations/group group()}`
42
+ */
24
43
  Group: 3,
44
+ /**
45
+ * Contains an animation step.
46
+ * See `animate()`
47
+ */
25
48
  Animate: 4,
49
+ /**
50
+ * Contains a set of animation steps.
51
+ * See `keyframes()`
52
+ */
26
53
  Keyframes: 5,
54
+ /**
55
+ * Contains a set of CSS property-value pairs into a named style.
56
+ * See `style()`
57
+ */
27
58
  Style: 6,
59
+ /**
60
+ * Associates an animation with an entry trigger that can be attached to an element.
61
+ * See `trigger()`
62
+ */
28
63
  Trigger: 7,
64
+ /**
65
+ * Contains a re-usable animation.
66
+ * See `animation()`
67
+ */
29
68
  Reference: 8,
69
+ /**
70
+ * Contains data to use in executing child animations returned by a query.
71
+ * See `animateChild()`
72
+ */
30
73
  AnimateChild: 9,
74
+ /**
75
+ * Contains animation parameters for a re-usable animation.
76
+ * See `useAnimation()`
77
+ */
31
78
  AnimateRef: 10,
79
+ /**
80
+ * Contains child-animation query data.
81
+ * See `query()`
82
+ */
32
83
  Query: 11,
84
+ /**
85
+ * Contains data for staggering an animation sequence.
86
+ * See `stagger()`
87
+ */
33
88
  Stagger: 12,
34
89
  };
35
90
  export { AnimationMetadataType };
36
91
  /**
37
- * \@experimental Animation support is experimental.
92
+ * Specifies automatic styling.
38
93
  */
39
94
  export const /** @type {?} */ AUTO_STYLE = '*';
40
95
  /**
41
- * \@experimental Animation support is experimental.
96
+ * Base for animation data structures.
42
97
  * @record
43
98
  */
44
99
  export function AnimationMetadata() { }
@@ -47,216 +102,294 @@ function AnimationMetadata_tsickle_Closure_declarations() {
47
102
  AnimationMetadata.prototype.type;
48
103
  }
49
104
  /**
50
- * Metadata representing the entry of animations. Instances of this interface are provided via the
51
- * animation DSL when the {\@link trigger trigger animation function} is called.
52
- *
53
- * \@experimental Animation support is experimental.
105
+ * Contains an animation trigger. Instantiated and returned by the
106
+ * `trigger()` function.
54
107
  * @record
55
108
  */
56
109
  export function AnimationTriggerMetadata() { }
57
110
  function AnimationTriggerMetadata_tsickle_Closure_declarations() {
58
- /** @type {?} */
111
+ /**
112
+ * The trigger name, used to associate it with an element. Unique within the component.
113
+ * @type {?}
114
+ */
59
115
  AnimationTriggerMetadata.prototype.name;
60
- /** @type {?} */
116
+ /**
117
+ * An animation definition object, containing an array of state and transition declarations.
118
+ * @type {?}
119
+ */
61
120
  AnimationTriggerMetadata.prototype.definitions;
62
- /** @type {?} */
121
+ /**
122
+ * An options object containing a delay and
123
+ * developer-defined parameters that provide styling defaults and
124
+ * can be overridden on invocation. Default delay is 0.
125
+ * @type {?}
126
+ */
63
127
  AnimationTriggerMetadata.prototype.options;
64
128
  }
65
129
  /**
66
- * Metadata representing the entry of animations. Instances of this interface are provided via the
67
- * animation DSL when the {\@link state state animation function} is called.
68
- *
69
- * \@experimental Animation support is experimental.
130
+ * Encapsulates an animation state by associating a state name with a set of CSS styles.
131
+ * Instantiated and returned by the `state()` function.
70
132
  * @record
71
133
  */
72
134
  export function AnimationStateMetadata() { }
73
135
  function AnimationStateMetadata_tsickle_Closure_declarations() {
74
- /** @type {?} */
136
+ /**
137
+ * The state name, unique within the component.
138
+ * @type {?}
139
+ */
75
140
  AnimationStateMetadata.prototype.name;
76
- /** @type {?} */
141
+ /**
142
+ * The CSS styles associated with this state.
143
+ * @type {?}
144
+ */
77
145
  AnimationStateMetadata.prototype.styles;
78
- /** @type {?|undefined} */
146
+ /**
147
+ * An options object containing
148
+ * developer-defined parameters that provide styling defaults and
149
+ * can be overridden on invocation.
150
+ * @type {?|undefined}
151
+ */
79
152
  AnimationStateMetadata.prototype.options;
80
153
  }
81
154
  /**
82
- * Metadata representing the entry of animations. Instances of this interface are provided via the
83
- * animation DSL when the {\@link transition transition animation function} is called.
84
- *
85
- * \@experimental Animation support is experimental.
155
+ * Encapsulates an animation transition. Instantiated and returned by the
156
+ * `transition()` function.
86
157
  * @record
87
158
  */
88
159
  export function AnimationTransitionMetadata() { }
89
160
  function AnimationTransitionMetadata_tsickle_Closure_declarations() {
90
- /** @type {?} */
161
+ /**
162
+ * An expression that describes a state change.
163
+ * @type {?}
164
+ */
91
165
  AnimationTransitionMetadata.prototype.expr;
92
- /** @type {?} */
166
+ /**
167
+ * One or more animation objects to which this transition applies.
168
+ * @type {?}
169
+ */
93
170
  AnimationTransitionMetadata.prototype.animation;
94
- /** @type {?} */
171
+ /**
172
+ * An options object containing a delay and
173
+ * developer-defined parameters that provide styling defaults and
174
+ * can be overridden on invocation. Default delay is 0.
175
+ * @type {?}
176
+ */
95
177
  AnimationTransitionMetadata.prototype.options;
96
178
  }
97
179
  /**
98
- * \@experimental Animation support is experimental.
180
+ * Encapsulates a reusable animation, which is a collection of individual animation steps.
181
+ * Instantiated and returned by the `animation()` function, and
182
+ * passed to the `useAnimation()` function.
99
183
  * @record
100
184
  */
101
185
  export function AnimationReferenceMetadata() { }
102
186
  function AnimationReferenceMetadata_tsickle_Closure_declarations() {
103
- /** @type {?} */
187
+ /**
188
+ * One or more animation step objects.
189
+ * @type {?}
190
+ */
104
191
  AnimationReferenceMetadata.prototype.animation;
105
- /** @type {?} */
192
+ /**
193
+ * An options object containing a delay and
194
+ * developer-defined parameters that provide styling defaults and
195
+ * can be overridden on invocation. Default delay is 0.
196
+ * @type {?}
197
+ */
106
198
  AnimationReferenceMetadata.prototype.options;
107
199
  }
108
200
  /**
109
- * \@experimental Animation support is experimental.
201
+ * Encapsulates an animation query. Instantiated and returned by
202
+ * the `query()` function.
110
203
  * @record
111
204
  */
112
205
  export function AnimationQueryMetadata() { }
113
206
  function AnimationQueryMetadata_tsickle_Closure_declarations() {
114
- /** @type {?} */
207
+ /**
208
+ * The CSS selector for this query.
209
+ * @type {?}
210
+ */
115
211
  AnimationQueryMetadata.prototype.selector;
116
- /** @type {?} */
212
+ /**
213
+ * One or more animation step objects.
214
+ * @type {?}
215
+ */
117
216
  AnimationQueryMetadata.prototype.animation;
118
- /** @type {?} */
217
+ /**
218
+ * A query options object.
219
+ * @type {?}
220
+ */
119
221
  AnimationQueryMetadata.prototype.options;
120
222
  }
121
223
  /**
122
- * Metadata representing the entry of animations. Instances of this interface are provided via the
123
- * animation DSL when the {\@link keyframes keyframes animation function} is called.
124
- *
125
- * \@experimental Animation support is experimental.
224
+ * Encapsulates a keyframes sequence. Instantiated and returned by
225
+ * the `keyframes()` function.
126
226
  * @record
127
227
  */
128
228
  export function AnimationKeyframesSequenceMetadata() { }
129
229
  function AnimationKeyframesSequenceMetadata_tsickle_Closure_declarations() {
130
- /** @type {?} */
230
+ /**
231
+ * An array of animation styles.
232
+ * @type {?}
233
+ */
131
234
  AnimationKeyframesSequenceMetadata.prototype.steps;
132
235
  }
133
236
  /**
134
- * Metadata representing the entry of animations. Instances of this interface are provided via the
135
- * animation DSL when the {\@link style style animation function} is called.
136
- *
137
- * \@experimental Animation support is experimental.
237
+ * Encapsulates an animation style. Instantiated and returned by
238
+ * the `style()` function.
138
239
  * @record
139
240
  */
140
241
  export function AnimationStyleMetadata() { }
141
242
  function AnimationStyleMetadata_tsickle_Closure_declarations() {
142
- /** @type {?} */
243
+ /**
244
+ * A set of CSS style properties.
245
+ * @type {?}
246
+ */
143
247
  AnimationStyleMetadata.prototype.styles;
144
- /** @type {?} */
248
+ /**
249
+ * A percentage of the total animate time at which the style is to be applied.
250
+ * @type {?}
251
+ */
145
252
  AnimationStyleMetadata.prototype.offset;
146
253
  }
147
254
  /**
148
- * Metadata representing the entry of animations. Instances of this interface are provided via the
149
- * animation DSL when the {\@link animate animate animation function} is called.
150
- *
151
- * \@experimental Animation support is experimental.
255
+ * Encapsulates an animation step. Instantiated and returned by
256
+ * the `animate()` function.
152
257
  * @record
153
258
  */
154
259
  export function AnimationAnimateMetadata() { }
155
260
  function AnimationAnimateMetadata_tsickle_Closure_declarations() {
156
- /** @type {?} */
261
+ /**
262
+ * The timing data for the step.
263
+ * @type {?}
264
+ */
157
265
  AnimationAnimateMetadata.prototype.timings;
158
- /** @type {?} */
266
+ /**
267
+ * A set of styles used in the step.
268
+ * @type {?}
269
+ */
159
270
  AnimationAnimateMetadata.prototype.styles;
160
271
  }
161
272
  /**
162
- * Metadata representing the entry of animations. Instances of this interface are provided via the
163
- * animation DSL when the {\@link animateChild animateChild animation function} is called.
164
- *
165
- * \@experimental Animation support is experimental.
273
+ * Encapsulates a child animation, that can be run explicitly when the parent is run.
274
+ * Instantiated and returned by the `animateChild` function.
166
275
  * @record
167
276
  */
168
277
  export function AnimationAnimateChildMetadata() { }
169
278
  function AnimationAnimateChildMetadata_tsickle_Closure_declarations() {
170
- /** @type {?} */
279
+ /**
280
+ * An options object containing a delay and
281
+ * developer-defined parameters that provide styling defaults and
282
+ * can be overridden on invocation. Default delay is 0.
283
+ * @type {?}
284
+ */
171
285
  AnimationAnimateChildMetadata.prototype.options;
172
286
  }
173
287
  /**
174
- * Metadata representing the entry of animations. Instances of this interface are provided via the
175
- * animation DSL when the {\@link useAnimation useAnimation animation function} is called.
176
- *
177
- * \@experimental Animation support is experimental.
288
+ * Encapsulates a reusable animation.
289
+ * Instantiated and returned by the `useAnimation()` function.
178
290
  * @record
179
291
  */
180
292
  export function AnimationAnimateRefMetadata() { }
181
293
  function AnimationAnimateRefMetadata_tsickle_Closure_declarations() {
182
- /** @type {?} */
294
+ /**
295
+ * An animation reference object.
296
+ * @type {?}
297
+ */
183
298
  AnimationAnimateRefMetadata.prototype.animation;
184
- /** @type {?} */
299
+ /**
300
+ * An options object containing a delay and
301
+ * developer-defined parameters that provide styling defaults and
302
+ * can be overridden on invocation. Default delay is 0.
303
+ * @type {?}
304
+ */
185
305
  AnimationAnimateRefMetadata.prototype.options;
186
306
  }
187
307
  /**
188
- * Metadata representing the entry of animations. Instances of this interface are provided via the
189
- * animation DSL when the {\@link sequence sequence animation function} is called.
190
- *
191
- * \@experimental Animation support is experimental.
308
+ * Encapsulates an animation sequence.
309
+ * Instantiated and returned by the `sequence()` function.
192
310
  * @record
193
311
  */
194
312
  export function AnimationSequenceMetadata() { }
195
313
  function AnimationSequenceMetadata_tsickle_Closure_declarations() {
196
- /** @type {?} */
314
+ /**
315
+ * An array of animation step objects.
316
+ * @type {?}
317
+ */
197
318
  AnimationSequenceMetadata.prototype.steps;
198
- /** @type {?} */
319
+ /**
320
+ * An options object containing a delay and
321
+ * developer-defined parameters that provide styling defaults and
322
+ * can be overridden on invocation. Default delay is 0.
323
+ * @type {?}
324
+ */
199
325
  AnimationSequenceMetadata.prototype.options;
200
326
  }
201
327
  /**
202
- * Metadata representing the entry of animations. Instances of this interface are provided via the
203
- * animation DSL when the {\@link group group animation function} is called.
204
- *
205
- * \@experimental Animation support is experimental.
328
+ * Encapsulates an animation group.
329
+ * Instantiated and returned by the `{\@link animations/group group()}` function.
206
330
  * @record
207
331
  */
208
332
  export function AnimationGroupMetadata() { }
209
333
  function AnimationGroupMetadata_tsickle_Closure_declarations() {
210
- /** @type {?} */
334
+ /**
335
+ * One or more animation or style steps that form this group.
336
+ * @type {?}
337
+ */
211
338
  AnimationGroupMetadata.prototype.steps;
212
- /** @type {?} */
339
+ /**
340
+ * An options object containing a delay and
341
+ * developer-defined parameters that provide styling defaults and
342
+ * can be overridden on invocation. Default delay is 0.
343
+ * @type {?}
344
+ */
213
345
  AnimationGroupMetadata.prototype.options;
214
346
  }
215
347
  /**
216
- * Metadata representing the entry of animations. Instances of this interface are provided via the
217
- * animation DSL when the {\@link stagger stagger animation function} is called.
348
+ * Encapsulates parameters for staggering the start times of a set of animation steps.
349
+ * Instantiated and returned by the `stagger()` function.
218
350
  *
219
- * \@experimental Animation support is experimental.
220
351
  * @record
221
352
  */
222
353
  export function AnimationStaggerMetadata() { }
223
354
  function AnimationStaggerMetadata_tsickle_Closure_declarations() {
224
- /** @type {?} */
355
+ /**
356
+ * The timing data for the steps.
357
+ * @type {?}
358
+ */
225
359
  AnimationStaggerMetadata.prototype.timings;
226
- /** @type {?} */
360
+ /**
361
+ * One or more animation steps.
362
+ * @type {?}
363
+ */
227
364
  AnimationStaggerMetadata.prototype.animation;
228
365
  }
229
366
  /**
230
- * `trigger` is an animation-specific function that is designed to be used inside of Angular's
231
- * animation DSL language. If this information is new, please navigate to the
232
- * {\@link Component#animations component animations metadata page} to gain a better
233
- * understanding of how animations in Angular are used.
234
- *
235
- * `trigger` Creates an animation trigger which will a list of {\@link state state} and
236
- * {\@link transition transition} entries that will be evaluated when the expression
367
+ * Creates a named animation trigger, containing a list of `state()`
368
+ * and `transition()` entries to be evaluated when the expression
237
369
  * bound to the trigger changes.
238
370
  *
239
- * Triggers are registered within the component annotation data under the
240
- * {\@link Component#animations animations section}. An animation trigger can be placed on an element
241
- * within a template by referencing the name of the trigger followed by the expression value that
242
- * the
243
- * trigger is bound to (in the form of `[\@triggerName]="expression"`.
371
+ * \@usageNotes
372
+ * Define an animation trigger in the `animations` section of `\@Component` metadata.
373
+ * In the template, reference the trigger by name and bind it to a trigger expression that
374
+ * evaluates to a defined animation state, using the following format:
244
375
  *
245
- * Animation trigger bindings strigify values and then match the previous and current values against
246
- * any linked transitions. If a boolean value is provided into the trigger binding then it will both
247
- * be represented as `1` or `true` and `0` or `false` for a true and false boolean values
248
- * respectively.
376
+ * `[\@triggerName]="expression"`
249
377
  *
250
- * ### Usage
378
+ * Animation trigger bindings convert all values to strings, and then match the
379
+ * previous and current values against any linked transitions.
380
+ * Booleans can be specified as `1` or `true` and `0` or `false`.
381
+ *
382
+ * ### Usage Example
251
383
  *
252
- * `trigger` will create an animation trigger reference based on the provided `name` value. The
253
- * provided `animation` value is expected to be an array consisting of {\@link state state} and
254
- * {\@link transition transition} declarations.
384
+ * The following example creates an animation trigger reference based on the provided
385
+ * name value.
386
+ * The provided animation value is expected to be an array consisting of state and
387
+ * transition declarations.
255
388
  *
256
389
  * ```typescript
257
390
  * \@Component({
258
- * selector: 'my-component',
259
- * templateUrl: 'my-component-tpl.html',
391
+ * selector: "my-component",
392
+ * templateUrl: "my-component-tpl.html",
260
393
  * animations: [
261
394
  * trigger("myAnimationTrigger", [
262
395
  * state(...),
@@ -271,8 +404,8 @@ function AnimationStaggerMetadata_tsickle_Closure_declarations() {
271
404
  * }
272
405
  * ```
273
406
  *
274
- * The template associated with this component will make use of the `myAnimationTrigger` animation
275
- * trigger by binding to an element within its template code.
407
+ * The template associated with this component makes use of the defined trigger
408
+ * by binding to an element within its template code.
276
409
  *
277
410
  * ```html
278
411
  * <!-- somewhere inside of my-component-tpl.html -->
@@ -283,9 +416,8 @@ function AnimationStaggerMetadata_tsickle_Closure_declarations() {
283
416
  * The `transition` animation method also supports reading an inline function which can decide
284
417
  * if its associated animation should be run.
285
418
  *
286
- * ```
287
- * // this method will be run each time the `myAnimationTrigger`
288
- * // trigger value changes...
419
+ * ```typescript
420
+ * // this method is run each time the `myAnimationTrigger` trigger value changes.
289
421
  * function myInlineMatcherFn(fromState: string, toState: string, element: any, params: {[key:
290
422
  * string]: any}): boolean {
291
423
  * // notice that `element` and `params` are also available here
@@ -308,18 +440,16 @@ function AnimationStaggerMetadata_tsickle_Closure_declarations() {
308
440
  * }
309
441
  * ```
310
442
  *
311
- * The inline method will be run each time the trigger
312
- * value changes
313
- *
314
- * ## Disable Animations
315
- * A special animation control binding called `\@.disabled` can be placed on an element which will
316
- * then disable animations for any inner animation triggers situated within the element as well as
317
- * any animations on the element itself.
443
+ * ### Disabling Animations
444
+ * When true, the special animation control binding `\@.disabled` binding prevents
445
+ * all animations from rendering.
446
+ * Place the `\@.disabled` binding on an element to disable
447
+ * animations on the element itself, as well as any inner animation triggers
448
+ * within the element.
318
449
  *
319
- * When true, the `\@.disabled` binding will prevent all animations from rendering. The example
320
- * below shows how to use this feature:
450
+ * The following example shows how to use this feature:
321
451
  *
322
- * ```ts
452
+ * ```typescript
323
453
  * \@Component({
324
454
  * selector: 'my-component',
325
455
  * template: `
@@ -339,19 +469,16 @@ function AnimationStaggerMetadata_tsickle_Closure_declarations() {
339
469
  * }
340
470
  * ```
341
471
  *
342
- * The `\@childAnimation` trigger will not animate because `\@.disabled` prevents it from happening
343
- * (when true).
344
- *
345
- * Note that `\@.disabled` will only disable all animations (this means any animations running on
346
- * the same element will also be disabled).
472
+ * When `\@.disabled` is true, it prevents the `\@childAnimation` trigger from animating,
473
+ * along with any inner animations.
347
474
  *
348
- * ### Disabling Animations Application-wide
349
- * When an area of the template is set to have animations disabled, **all** inner components will
350
- * also have their animations disabled as well. This means that all animations for an angular
351
- * application can be disabled by placing a host binding set on `\@.disabled` on the topmost Angular
352
- * component.
475
+ * ### Disable animations application-wide
476
+ * When an area of the template is set to have animations disabled,
477
+ * **all** inner components have their animations disabled as well.
478
+ * This means that you can disable all animations for an app
479
+ * by placing a host binding set on `\@.disabled` on the topmost Angular component.
353
480
  *
354
- * ```ts
481
+ * ```typescript
355
482
  * import {Component, HostBinding} from '\@angular/core';
356
483
  *
357
484
  * \@Component({
@@ -359,102 +486,109 @@ function AnimationStaggerMetadata_tsickle_Closure_declarations() {
359
486
  * templateUrl: 'app.component.html',
360
487
  * })
361
488
  * class AppComponent {
362
- * \@HostBinding('\@.disabled')
489
+ * \@HostBinding('@.disabled')
363
490
  * public animationsDisabled = true;
364
491
  * }
365
492
  * ```
366
493
  *
367
- * ### What about animations that us `query()` and `animateChild()`?
368
- * Despite inner animations being disabled, a parent animation can {\@link query query} for inner
369
- * elements located in disabled areas of the template and still animate them as it sees fit. This is
370
- * also the case for when a sub animation is queried by a parent and then later animated using {\@link
371
- * animateChild animateChild}.
372
- * ### Detecting when an animation is disabled
373
- * If a region of the DOM (or the entire application) has its animations disabled, then animation
374
- * trigger callbacks will still fire just as normal (only for zero seconds).
494
+ * ### Overriding disablement of inner animations
495
+ * Despite inner animations being disabled, a parent animation can `query()`
496
+ * for inner elements located in disabled areas of the template and still animate
497
+ * them if needed. This is also the case for when a sub animation is
498
+ * queried by a parent and then later animated using `animateChild()`.
375
499
  *
376
- * When a trigger callback fires it will provide an instance of an {\@link AnimationEvent}. If
377
- * animations
378
- * are disabled then the `.disabled` flag on the event will be true.
500
+ * ### Detecting when an animation is disabled
501
+ * If a region of the DOM (or the entire application) has its animations disabled, the animation
502
+ * trigger callbacks still fire, but for zero seconds. When the callback fires, it provides
503
+ * an instance of an `AnimationEvent`. If animations are disabled,
504
+ * the `.disabled` flag on the event is true.
379
505
  *
380
506
  * \@experimental Animation support is experimental.
381
- * @param {?} name
382
- * @param {?} definitions
383
- * @return {?}
507
+ * @param {?} name An identifying string.
508
+ * @param {?} definitions An animation definition object, containing an array of `state()`
509
+ * and `transition()` declarations.
510
+ *
511
+ * @return {?} An object that encapsulates the trigger data.
512
+ *
384
513
  */
385
514
  export function trigger(name, definitions) {
386
515
  return { type: 7 /* Trigger */, name, definitions, options: {} };
387
516
  }
388
517
  /**
389
- * `animate` is an animation-specific function that is designed to be used inside of Angular's
390
- * animation DSL language. If this information is new, please navigate to the {\@link
391
- * Component#animations component animations metadata page} to gain a better understanding of
392
- * how animations in Angular are used.
518
+ * Defines an animation step that combines styling information with timing information.
393
519
  *
394
- * `animate` specifies an animation step that will apply the provided `styles` data for a given
395
- * amount of time based on the provided `timing` expression value. Calls to `animate` are expected
396
- * to be used within {\@link sequence an animation sequence}, {\@link group group}, or {\@link
397
- * transition transition}.
520
+ * \@usageNotes
521
+ * Call within an animation `sequence()`, `{\@link animations/group group()}`, or
522
+ * `transition()` call to specify an animation step
523
+ * that applies given style data to the parent animation for a given amount of time.
398
524
  *
399
- * ### Usage
525
+ * ### Syntax Examples
526
+ * **Timing examples**
400
527
  *
401
- * The `animate` function accepts two input parameters: `timing` and `styles`:
528
+ * The following examples show various `timings` specifications.
529
+ * - `animate(500)` : Duration is 500 milliseconds.
530
+ * - `animate("1s")` : Duration is 1000 milliseconds.
531
+ * - `animate("100ms 0.5s")` : Duration is 100 milliseconds, delay is 500 milliseconds.
532
+ * - `animate("5s ease-in")` : Duration is 5000 milliseconds, easing in.
533
+ * - `animate("5s 10ms cubic-bezier(.17,.67,.88,.1)")` : Duration is 5000 milliseconds, delay is 10
534
+ * milliseconds, easing according to a bezier curve.
402
535
  *
403
- * - `timing` is a string based value that can be a combination of a duration with optional delay
404
- * and easing values. The format for the expression breaks down to `duration delay easing`
405
- * (therefore a value such as `1s 100ms ease-out` will be parse itself into `duration=1000,
406
- * delay=100, easing=ease-out`. If a numeric value is provided then that will be used as the
407
- * `duration` value in millisecond form.
408
- * - `styles` is the style input data which can either be a call to {\@link style style} or {\@link
409
- * keyframes keyframes}. If left empty then the styles from the destination state will be collected
410
- * and used (this is useful when describing an animation step that will complete an animation by
411
- * {\@link transition#the-final-animate-call animating to the final state}).
536
+ * **Style examples**
412
537
  *
538
+ * The following example calls `style()` to set a single CSS style.
413
539
  * ```typescript
414
- * // various functions for specifying timing data
415
- * animate(500, style(...))
416
- * animate("1s", style(...))
417
- * animate("100ms 0.5s", style(...))
418
- * animate("5s ease", style(...))
419
- * animate("5s 10ms cubic-bezier(.17,.67,.88,.1)", style(...))
420
- *
421
- * // either style() of keyframes() can be used
422
540
  * animate(500, style({ background: "red" }))
423
- * animate(500, keyframes([
541
+ * ```
542
+ * The following example calls `keyframes()` to set a CSS style
543
+ * to different values for successive keyframes.
544
+ * ```typescript
545
+ * animate(500, keyframes(
546
+ * [
424
547
  * style({ background: "blue" })),
425
548
  * style({ background: "red" }))
426
- * ])
549
+ * ])
427
550
  * ```
551
+ * @param {?} timings Sets `AnimateTimings` for the parent animation.
552
+ * A string in the format "duration [delay] [easing]".
553
+ * - Duration and delay are expressed as a number and optional time unit,
554
+ * such as "1s" or "10ms" for one second and 10 milliseconds, respectively.
555
+ * The default unit is milliseconds.
556
+ * - The easing value controls how the animation accelerates and decelerates
557
+ * during its runtime. Value is one of `ease`, `ease-in`, `ease-out`,
558
+ * `ease-in-out`, or a `cubic-bezier()` function call.
559
+ * If not supplied, no easing is applied.
560
+ *
561
+ * For example, the string "1s 100ms ease-out" specifies a duration of
562
+ * 1000 milliseconds, and delay of 100 ms, and the "ease-out" easing style,
563
+ * which decelerates near the end of the duration.
564
+ * @param {?=} styles Sets AnimationStyles for the parent animation.
565
+ * A function call to either `style()` or `keyframes()`
566
+ * that returns a collection of CSS style entries to be applied to the parent animation.
567
+ * When null, uses the styles from the destination state.
568
+ * This is useful when describing an animation step that will complete an animation;
569
+ * see "Animating to the final state" in `transitions()`.
570
+ * @return {?} An object that encapsulates the animation step.
428
571
  *
429
- * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
430
- *
431
- * \@experimental Animation support is experimental.
432
- * @param {?} timings
433
- * @param {?=} styles
434
- * @return {?}
435
572
  */
436
573
  export function animate(timings, styles = null) {
437
574
  return { type: 4 /* Animate */, styles, timings };
438
575
  }
439
576
  /**
440
- * `group` is an animation-specific function that is designed to be used inside of Angular's
441
- * animation DSL language. If this information is new, please navigate to the {\@link
442
- * Component#animations component animations metadata page} to gain a better understanding of
443
- * how animations in Angular are used.
444
- *
445
- * `group` specifies a list of animation steps that are all run in parallel. Grouped animations are
446
- * useful when a series of styles must be animated/closed off at different starting/ending times.
447
- *
448
- * The `group` function can either be used within a {\@link sequence sequence} or a {\@link transition
449
- * transition} and it will only continue to the next instruction once all of the inner animation
450
- * steps have completed.
451
- *
452
- * ### Usage
453
- *
454
- * The `steps` data that is passed into the `group` animation function can either consist of {\@link
455
- * style style} or {\@link animate animate} function calls. Each call to `style()` or `animate()`
456
- * within a group will be executed instantly (use {\@link keyframes keyframes} or a {\@link
457
- * animate#usage animate() with a delay value} to offset styles to be applied at a later time).
577
+ * \@description Defines a list of animation steps to be run in parallel.
578
+ *
579
+ * \@usageNotes
580
+ * Grouped animations are useful when a series of styles must be
581
+ * animated at different starting times and closed off at different ending times.
582
+ *
583
+ * When called within a `sequence()` or a
584
+ * `transition()` call, does not continue to the next
585
+ * instruction until all of the inner animation steps have completed.
586
+ * @param {?} steps An array of animation step objects.
587
+ * - When steps are defined by `style()` or `animate()`
588
+ * function calls, each call within the group is executed instantly.
589
+ * - To specify offset styles to be applied at a later time, define steps with
590
+ * `keyframes()`, or use `animate()` calls with a delay value.
591
+ * For example:
458
592
  *
459
593
  * ```typescript
460
594
  * group([
@@ -463,38 +597,33 @@ export function animate(timings, styles = null) {
463
597
  * ])
464
598
  * ```
465
599
  *
466
- * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
600
+ * @param {?=} options An options object containing a delay and
601
+ * developer-defined parameters that provide styling defaults and
602
+ * can be overridden on invocation.
603
+ *
604
+ * @return {?} An object that encapsulates the group data.
467
605
  *
468
- * \@experimental Animation support is experimental.
469
- * @param {?} steps
470
- * @param {?=} options
471
- * @return {?}
472
606
  */
473
607
  export function group(steps, options = null) {
474
608
  return { type: 3 /* Group */, steps, options };
475
609
  }
476
610
  /**
477
- * `sequence` is an animation-specific function that is designed to be used inside of Angular's
478
- * animation DSL language. If this information is new, please navigate to the {\@link
479
- * Component#animations component animations metadata page} to gain a better understanding of
480
- * how animations in Angular are used.
611
+ * Defines a list of animation steps to be run sequentially, one by one.
481
612
  *
482
- * `sequence` Specifies a list of animation steps that are run one by one. (`sequence` is used by
483
- * default when an array is passed as animation data into {\@link transition transition}.)
613
+ * \@usageNotes
614
+ * When you pass an array of steps to a
615
+ * `transition()` call, the steps run sequentially by default.
616
+ * Compare this to the `{\@link animations/group group()}` call, which runs animation steps in parallel.
484
617
  *
485
- * The `sequence` function can either be used within a {\@link group group} or a {\@link transition
486
- * transition} and it will only continue to the next instruction once each of the inner animation
618
+ * When a sequence is used within a `{\@link animations/group group()}` or a `transition()` call,
619
+ * execution continues to the next instruction only after each of the inner animation
487
620
  * steps have completed.
488
621
  *
489
- * To perform animation styling in parallel with other animation steps then have a look at the
490
- * {\@link group group} animation function.
491
- *
492
- * ### Usage
493
622
  *
494
- * The `steps` data that is passed into the `sequence` animation function can either consist of
495
- * {\@link style style} or {\@link animate animate} function calls. A call to `style()` will apply the
496
- * provided styling data immediately while a call to `animate()` will apply its styling data over a
497
- * given time depending on its timing data.
623
+ * @param {?} steps An array of animation step objects.
624
+ * - Steps defined by `style()` calls apply the styling data immediately.
625
+ * - Steps defined by `animate()` calls apply the styling data over time
626
+ * as specified by the timing data.
498
627
  *
499
628
  * ```typescript
500
629
  * sequence([
@@ -503,139 +632,107 @@ export function group(steps, options = null) {
503
632
  * ])
504
633
  * ```
505
634
  *
506
- * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
635
+ * @param {?=} options An options object containing a delay and
636
+ * developer-defined parameters that provide styling defaults and
637
+ * can be overridden on invocation.
638
+ *
639
+ * @return {?} An object that encapsulates the sequence data.
507
640
  *
508
- * \@experimental Animation support is experimental.
509
- * @param {?} steps
510
- * @param {?=} options
511
- * @return {?}
512
641
  */
513
642
  export function sequence(steps, options = null) {
514
643
  return { type: 2 /* Sequence */, steps, options };
515
644
  }
516
645
  /**
517
- * `style` is an animation-specific function that is designed to be used inside of Angular's
518
- * animation DSL language. If this information is new, please navigate to the {\@link
519
- * Component#animations component animations metadata page} to gain a better understanding of
520
- * how animations in Angular are used.
521
- *
522
- * `style` declares a key/value object containing CSS properties/styles that can then be used for
523
- * {\@link state animation states}, within an {\@link sequence animation sequence}, or as styling data
524
- * for both {\@link animate animate} and {\@link keyframes keyframes}.
525
- *
526
- * ### Usage
646
+ * Declares a key/value object containing CSS properties/styles that
647
+ * can then be used for an animation `state`, within an animation `sequence`,
648
+ * or as styling data for calls to `animate()` and `keyframes()`.
527
649
  *
528
- * `style` takes in a key/value string map as data and expects one or more CSS property/value pairs
529
- * to be defined.
650
+ * \@usageNotes
651
+ * The following examples create animation styles that collect a set of
652
+ * CSS property values:
530
653
  *
531
654
  * ```typescript
532
- * // string values are used for css properties
655
+ * // string values for CSS properties
533
656
  * style({ background: "red", color: "blue" })
534
657
  *
535
- * // numerical (pixel) values are also supported
658
+ * // numerical pixel values
536
659
  * style({ width: 100, height: 0 })
537
660
  * ```
538
661
  *
539
- * #### Auto-styles (using `*`)
662
+ * The following example uses auto-styling to allow a component to animate from
663
+ * a height of 0 up to the height of the parent element:
540
664
  *
541
- * When an asterix (`*`) character is used as a value then it will be detected from the element
542
- * being animated and applied as animation data when the animation starts.
543
- *
544
- * This feature proves useful for a state depending on layout and/or environment factors; in such
545
- * cases the styles are calculated just before the animation starts.
546
- *
547
- * ```typescript
548
- * // the steps below will animate from 0 to the
549
- * // actual height of the element
665
+ * ```
550
666
  * style({ height: 0 }),
551
667
  * animate("1s", style({ height: "*" }))
552
668
  * ```
553
669
  *
554
- * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
555
670
  *
556
- * \@experimental Animation support is experimental.
557
- * @param {?} tokens
558
- * @return {?}
671
+ * @param {?} tokens A set of CSS styles or HTML styles associated with an animation state.
672
+ * The value can be any of the following:
673
+ * - A key-value style pair associating a CSS property with a value.
674
+ * - An array of key-value style pairs.
675
+ * - An asterisk (*), to use auto-styling, where styles are derived from the element
676
+ * being animated and applied to the animation when it starts.
677
+ *
678
+ * Auto-styling can be used to define a state that depends on layout or other
679
+ * environmental factors.
680
+ *
681
+ * @return {?} An object that encapsulates the style data.
682
+ *
559
683
  */
560
684
  export function style(tokens) {
561
685
  return { type: 6 /* Style */, styles: tokens, offset: null };
562
686
  }
563
687
  /**
564
- * `state` is an animation-specific function that is designed to be used inside of Angular's
565
- * animation DSL language. If this information is new, please navigate to the {\@link
566
- * Component#animations component animations metadata page} to gain a better understanding of
567
- * how animations in Angular are used.
568
- *
569
- * `state` declares an animation state within the given trigger. When a state is active within a
570
- * component then its associated styles will persist on the element that the trigger is attached to
571
- * (even when the animation ends).
572
- *
573
- * To animate between states, have a look at the animation {\@link transition transition} DSL
574
- * function. To register states to an animation trigger please have a look at the {\@link trigger
575
- * trigger} function.
576
- *
577
- * #### The `void` state
688
+ * Declares an animation state within a trigger attached to an element.
689
+ *
690
+ * \@usageNotes
691
+ * Use the `trigger()` function to register states to an animation trigger.
692
+ * Use the `transition()` function to animate between states.
693
+ * When a state is active within a component, its associated styles persist on the element,
694
+ * even when the animation ends.
695
+ *
696
+ * @param {?} name One or more names for the defined state in a comma-separated string.
697
+ * The following reserved state names can be supplied to define a style for specific use
698
+ * cases:
699
+ *
700
+ * - `void` You can associate styles with this name to be used when
701
+ * the element is detached from the application. For example, when an `ngIf` evaluates
702
+ * to false, the state of the associated element is void.
703
+ * - `*` (asterisk) Indicates the default state. You can associate styles with this name
704
+ * to be used as the fallback when the state that is being animated is not declared
705
+ * within the trigger.
706
+ *
707
+ * @param {?} styles A set of CSS styles associated with this state, created using the
708
+ * `style()` function.
709
+ * This set of styles persists on the element once the state has been reached.
710
+ * @param {?=} options Parameters that can be passed to the state when it is invoked.
711
+ * 0 or more key-value pairs.
712
+ * @return {?} An object that encapsulates the new state data.
578
713
  *
579
- * The `void` state value is a reserved word that angular uses to determine when the element is not
580
- * apart of the application anymore (e.g. when an `ngIf` evaluates to false then the state of the
581
- * associated element is void).
582
- *
583
- * #### The `*` (default) state
584
- *
585
- * The `*` state (when styled) is a fallback state that will be used if the state that is being
586
- * animated is not declared within the trigger.
587
- *
588
- * ### Usage
589
- *
590
- * `state` will declare an animation state with its associated styles
591
- * within the given trigger.
592
- *
593
- * - `stateNameExpr` can be one or more state names separated by commas.
594
- * - `styles` refers to the {\@link style styling data} that will be persisted on the element once
595
- * the state has been reached.
596
- *
597
- * ```typescript
598
- * // "void" is a reserved name for a state and is used to represent
599
- * // the state in which an element is detached from from the application.
600
- * state("void", style({ height: 0 }))
601
- *
602
- * // user-defined states
603
- * state("closed", style({ height: 0 }))
604
- * state("open, visible", style({ height: "*" }))
605
- * ```
606
- *
607
- * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
608
- *
609
- * \@experimental Animation support is experimental.
610
- * @param {?} name
611
- * @param {?} styles
612
- * @param {?=} options
613
- * @return {?}
614
714
  */
615
715
  export function state(name, styles, options) {
616
716
  return { type: 0 /* State */, name, styles, options };
617
717
  }
618
718
  /**
619
- * `keyframes` is an animation-specific function that is designed to be used inside of Angular's
620
- * animation DSL language. If this information is new, please navigate to the {\@link
621
- * Component#animations component animations metadata page} to gain a better understanding of
622
- * how animations in Angular are used.
719
+ * Defines a set of animation styles, associating each style with an optional `offset` value.
623
720
  *
624
- * `keyframes` specifies a collection of {\@link style style} entries each optionally characterized
625
- * by an `offset` value.
721
+ * \@usageNotes
722
+ * Use with the `animate()` call. Instead of applying animations
723
+ * from the current state
724
+ * to the destination state, keyframes describe how each style entry is applied and at what point
725
+ * within the animation arc.
726
+ * Compare [CSS Keyframe Animations](https://www.w3schools.com/css/css3_animations.asp).
626
727
  *
627
728
  * ### Usage
628
729
  *
629
- * The `keyframes` animation function is designed to be used alongside the {\@link animate animate}
630
- * animation function. Instead of applying animations from where they are currently to their
631
- * destination, keyframes can describe how each style entry is applied and at what point within the
632
- * animation arc (much like CSS Keyframe Animations do).
633
- *
634
- * For each `style()` entry an `offset` value can be set. Doing so allows to specify at what
635
- * percentage of the animate time the styles will be applied.
730
+ * In the following example, the offset values describe
731
+ * when each `backgroundColor` value is applied. The color is red at the start, and changes to
732
+ * blue when 20% of the total time has elapsed.
636
733
  *
637
734
  * ```typescript
638
- * // the provided offset values describe when each backgroundColor value is applied.
735
+ * // the provided offset values
639
736
  * animate("5s", keyframes([
640
737
  * style({ backgroundColor: "red", offset: 0 }),
641
738
  * style({ backgroundColor: "blue", offset: 0.2 }),
@@ -644,8 +741,8 @@ export function state(name, styles, options) {
644
741
  * ]))
645
742
  * ```
646
743
  *
647
- * Alternatively, if there are no `offset` values used within the style entries then the offsets
648
- * will be calculated automatically.
744
+ * If there are no `offset` values specified in the style entries, the offsets
745
+ * are calculated automatically.
649
746
  *
650
747
  * ```typescript
651
748
  * animate("5s", keyframes([
@@ -655,244 +752,206 @@ export function state(name, styles, options) {
655
752
  * style({ backgroundColor: "black" }) // offset = 1
656
753
  * ]))
657
754
  * ```
755
+ * @param {?} steps A set of animation styles with optional offset data.
756
+ * The optional `offset` value for a style specifies a percentage of the total animation
757
+ * time at which that style is applied.
758
+ * @return {?} An object that encapsulates the keyframes data.
658
759
  *
659
- * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
660
- *
661
- * \@experimental Animation support is experimental.
662
- * @param {?} steps
663
- * @return {?}
664
760
  */
665
761
  export function keyframes(steps) {
666
762
  return { type: 5 /* Keyframes */, steps };
667
763
  }
668
764
  /**
669
- * `transition` is an animation-specific function that is designed to be used inside of Angular's
670
- * animation DSL language. If this information is new, please navigate to the {\@link
671
- * Component#animations component animations metadata page} to gain a better understanding of
672
- * how animations in Angular are used.
673
- *
674
- * `transition` declares the {\@link sequence sequence of animation steps} that will be run when the
675
- * provided `stateChangeExpr` value is satisfied. The `stateChangeExpr` consists of a `state1 =>
676
- * state2` which consists of two known states (use an asterix (`*`) to refer to a dynamic starting
677
- * and/or ending state).
678
- *
679
- * A function can also be provided as the `stateChangeExpr` argument for a transition and this
680
- * function will be executed each time a state change occurs. If the value returned within the
681
- * function is true then the associated animation will be run.
765
+ * Declares an animation transition as a sequence of animation steps to run when a given
766
+ * condition is satisfied. The condition is a Boolean expression or function that compares
767
+ * the previous and current animation states, and returns true if this transition should occur.
768
+ * When the state criteria of a defined transition are met, the associated animation is
769
+ * triggered.
682
770
  *
683
- * Animation transitions are placed within an {\@link trigger animation trigger}. For an transition
684
- * to animate to a state value and persist its styles then one or more {\@link state animation
685
- * states} is expected to be defined.
771
+ * \@usageNotes
772
+ * The template associated with a component binds an animation trigger to an element.
686
773
  *
687
- * ### Usage
774
+ * ```HTML
775
+ * <!-- somewhere inside of my-component-tpl.html -->
776
+ * <div [\@myAnimationTrigger]="myStatusExp">...</div>
777
+ * ```
688
778
  *
689
- * An animation transition is kicked off the `stateChangeExpr` predicate evaluates to true based on
690
- * what the previous state is and what the current state has become. In other words, if a transition
691
- * is defined that matches the old/current state criteria then the associated animation will be
692
- * triggered.
779
+ * All transitions are defined within an animation trigger,
780
+ * along with named states that the transitions change to and from.
693
781
  *
694
782
  * ```typescript
695
- * // all transition/state changes are defined within an animation trigger
696
783
  * trigger("myAnimationTrigger", [
697
- * // if a state is defined then its styles will be persisted when the
698
- * // animation has fully completed itself
699
- * state("on", style({ background: "green" })),
700
- * state("off", style({ background: "grey" })),
701
- *
702
- * // a transition animation that will be kicked off when the state value
703
- * // bound to "myAnimationTrigger" changes from "on" to "off"
704
- * transition("on => off", animate(500)),
705
- *
706
- * // it is also possible to do run the same animation for both directions
707
- * transition("on <=> off", animate(500)),
708
- *
709
- * // or to define multiple states pairs separated by commas
710
- * transition("on => off, off => void", animate(500)),
711
- *
712
- * // this is a catch-all state change for when an element is inserted into
713
- * // the page and the destination state is unknown
714
- * transition("void => *", [
715
- * style({ opacity: 0 }),
716
- * animate(500)
717
- * ]),
784
+ * // define states
785
+ * state("on", style({ background: "green" })),
786
+ * state("off", style({ background: "grey" })),
787
+ * ...]
788
+ * ```
718
789
  *
719
- * // this will capture a state change between any states
720
- * transition("* => *", animate("1s 0s")),
790
+ * Note that when you call the `sequence()` function within a `{\@link animations/group group()}`
791
+ * or a `transition()` call, execution does not continue to the next instruction
792
+ * until each of the inner animation steps have completed.
721
793
  *
722
- * // you can also go full out and include a function
723
- * transition((fromState, toState) => {
724
- * // when `true` then it will allow the animation below to be invoked
725
- * return fromState == "off" && toState == "on";
726
- * }, animate("1s 0s"))
727
- * ])
728
- * ```
794
+ * ### Syntax examples
729
795
  *
730
- * The template associated with this component will make use of the `myAnimationTrigger` animation
731
- * trigger by binding to an element within its template code.
796
+ * The following examples define transitions between the two defined states (and default states),
797
+ * using various options:
732
798
  *
733
- * ```html
734
- * <!-- somewhere inside of my-component-tpl.html -->
735
- * <div [\@myAnimationTrigger]="myStatusExp">...</div>
799
+ * ```typescript
800
+ * // Transition occurs when the state value
801
+ * // bound to "myAnimationTrigger" changes from "on" to "off"
802
+ * transition("on => off", animate(500))
803
+ * // Run the same animation for both directions
804
+ * transition("on <=> off", animate(500))
805
+ * // Define multiple state-change pairs separated by commas
806
+ * transition("on => off, off => void", animate(500))
736
807
  * ```
737
808
  *
738
- * #### The final `animate` call
809
+ * ### Special values for state-change expressions
739
810
  *
740
- * If the final step within the transition steps is a call to `animate()` that **only** uses a
741
- * timing value with **no style data** then it will be automatically used as the final animation arc
742
- * for the element to animate itself to the final state. This involves an automatic mix of
743
- * adding/removing CSS styles so that the element will be in the exact state it should be for the
744
- * applied state to be presented correctly.
811
+ * - Catch-all state change for when an element is inserted into the page and the
812
+ * destination state is unknown:
745
813
  *
746
- * ```
747
- * // start off by hiding the element, but make sure that it animates properly to whatever state
748
- * // is currently active for "myAnimationTrigger"
814
+ * ```typescript
749
815
  * transition("void => *", [
750
- * style({ opacity: 0 }),
751
- * animate(500)
752
- * ])
816
+ * style({ opacity: 0 }),
817
+ * animate(500)
818
+ * ])
753
819
  * ```
754
820
  *
755
- * ### Using :enter and :leave
821
+ * - Capture a state change between any states:
756
822
  *
757
- * Given that enter (insertion) and leave (removal) animations are so common, the `transition`
758
- * function accepts both `:enter` and `:leave` values which are aliases for the `void => *` and `*
759
- * => void` state changes.
823
+ * `transition("* => *", animate("1s 0s"))`
760
824
  *
761
- * ```
825
+ * - Entry and exit transitions:
826
+ *
827
+ * ```typescript
762
828
  * transition(":enter", [
763
829
  * style({ opacity: 0 }),
764
830
  * animate(500, style({ opacity: 1 }))
765
- * ]),
831
+ * ]),
766
832
  * transition(":leave", [
767
833
  * animate(500, style({ opacity: 0 }))
768
- * ])
834
+ * ])
769
835
  * ```
770
836
  *
771
- * ### Boolean values
772
- * if a trigger binding value is a boolean value then it can be matched using a transition
773
- * expression that compares `true` and `false` or `1` and `0`.
837
+ * - Use `:increment` and `:decrement` to initiate transitions:
774
838
  *
775
- * ```
776
- * // in the template
777
- * <div [\@openClose]="open ? true : false">...</div>
839
+ * ```typescript
840
+ * transition(":increment", group([
841
+ * query(':enter', [
842
+ * style({ left: '100%' }),
843
+ * animate('0.5s ease-out', style('*'))
844
+ * ]),
845
+ * query(':leave', [
846
+ * animate('0.5s ease-out', style({ left: '-100%' }))
847
+ * ])
848
+ * ]))
778
849
  *
779
- * // in the component metadata
780
- * trigger('openClose', [
781
- * state('true', style({ height: '*' })),
782
- * state('false', style({ height: '0px' })),
783
- * transition('false <=> true', animate(500))
784
- * ])
850
+ * transition(":decrement", group([
851
+ * query(':enter', [
852
+ * style({ left: '100%' }),
853
+ * animate('0.5s ease-out', style('*'))
854
+ * ]),
855
+ * query(':leave', [
856
+ * animate('0.5s ease-out', style({ left: '-100%' }))
857
+ * ])
858
+ * ]))
785
859
  * ```
786
860
  *
787
- * ### Using :increment and :decrement
788
- * In addition to the :enter and :leave transition aliases, the :increment and :decrement aliases
789
- * can be used to kick off a transition when a numeric value has increased or decreased in value.
861
+ * ### State-change functions
862
+ *
863
+ * Here is an example of a `fromState` specified as a state-change function that invokes an
864
+ * animation when true:
790
865
  *
866
+ * ```typescript
867
+ * transition((fromState, toState) =>
868
+ * {
869
+ * return fromState == "off" && toState == "on";
870
+ * },
871
+ * animate("1s 0s"))
791
872
  * ```
792
- * import {group, animate, query, transition, style, trigger} from '\@angular/animations';
793
- * import {Component} from '\@angular/core';
794
873
  *
795
- * \@Component({
796
- * selector: 'banner-carousel-component',
797
- * styles: [`
798
- * .banner-container {
799
- * position:relative;
800
- * height:500px;
801
- * overflow:hidden;
802
- * }
803
- * .banner-container > .banner {
804
- * position:absolute;
805
- * left:0;
806
- * top:0;
807
- * font-size:200px;
808
- * line-height:500px;
809
- * font-weight:bold;
810
- * text-align:center;
811
- * width:100%;
812
- * }
813
- * `],
814
- * template: `
815
- * <button (click)="previous()">Previous</button>
816
- * <button (click)="next()">Next</button>
817
- * <hr>
818
- * <div [\@bannerAnimation]="selectedIndex" class="banner-container">
819
- * <div class="banner" *ngFor="let banner of banners"> {{ banner }} </div>
820
- * </div>
821
- * `,
822
- * animations: [
823
- * trigger('bannerAnimation', [
824
- * transition(":increment", group([
825
- * query(':enter', [
826
- * style({ left: '100%' }),
827
- * animate('0.5s ease-out', style('*'))
828
- * ]),
829
- * query(':leave', [
830
- * animate('0.5s ease-out', style({ left: '-100%' }))
831
- * ])
832
- * ])),
833
- * transition(":decrement", group([
834
- * query(':enter', [
835
- * style({ left: '-100%' }),
836
- * animate('0.5s ease-out', style('*'))
837
- * ]),
838
- * query(':leave', [
839
- * animate('0.5s ease-out', style({ left: '100%' }))
840
- * ])
841
- * ]))
842
- * ])
843
- * ]
844
- * })
845
- * class BannerCarouselComponent {
846
- * allBanners: string[] = ['1', '2', '3', '4'];
847
- * selectedIndex: number = 0;
874
+ * ### Animating to the final state
848
875
  *
849
- * get banners() {
850
- * return [this.allBanners[this.selectedIndex]];
851
- * }
876
+ * If the final step in a transition is a call to `animate()` that uses a timing value
877
+ * with no style data, that step is automatically considered the final animation arc,
878
+ * for the element to reach the final state. Angular automatically adds or removes
879
+ * CSS styles to ensure that the element is in the correct final state.
852
880
  *
853
- * previous() {
854
- * this.selectedIndex = Math.max(this.selectedIndex - 1, 0);
855
- * }
881
+ * The following example defines a transition that starts by hiding the element,
882
+ * then makes sure that it animates properly to whatever state is currently active for trigger:
856
883
  *
857
- * next() {
858
- * this.selectedIndex = Math.min(this.selectedIndex + 1, this.allBanners.length - 1);
859
- * }
860
- * }
884
+ * ```typescript
885
+ * transition("void => *", [
886
+ * style({ opacity: 0 }),
887
+ * animate(500)
888
+ * ])
889
+ * ```
890
+ * ### Boolean value matching
891
+ * If a trigger binding value is a Boolean, it can be matched using a transition expression
892
+ * that compares true and false or 1 and 0. For example:
893
+ *
894
+ * ```
895
+ * // in the template
896
+ * <div [\@openClose]="open ? true : false">...</div>
897
+ * // in the component metadata
898
+ * trigger('openClose', [
899
+ * state('true', style({ height: '*' })),
900
+ * state('false', style({ height: '0px' })),
901
+ * transition('false <=> true', animate(500))
902
+ * ])
861
903
  * ```
862
904
  *
863
- * {\@example core/animation/ts/dsl/animation_example.ts region='Component'}
905
+ * @param {?} stateChangeExpr A Boolean expression or function that compares the previous and current
906
+ * animation states, and returns true if this transition should occur. Note that "true" and "false"
907
+ * match 1 and 0, respectively. An expression is evaluated each time a state change occurs in the
908
+ * animation trigger element.
909
+ * The animation steps run when the expression evaluates to true.
910
+ *
911
+ * - A state-change string takes the form "state1 => state2", where each side is a defined animation
912
+ * state, or an asterix (*) to refer to a dynamic start or end state.
913
+ * - The expression string can contain multiple comma-separated statements;
914
+ * for example "state1 => state2, state3 => state4".
915
+ * - Special values `:enter` and `:leave` initiate a transition on the entry and exit states,
916
+ * equivalent to "void => *" and "* => void".
917
+ * - Special values `:increment` and `:decrement` initiate a transition when a numeric value has
918
+ * increased or decreased in value.
919
+ * - A function is executed each time a state change occurs in the animation trigger element.
920
+ * The animation steps run when the function returns true.
921
+ *
922
+ * @param {?} steps One or more animation objects, as returned by the `animate()` or
923
+ * `sequence()` function, that form a transformation from one state to another.
924
+ * A sequence is used by default when you pass an array.
925
+ * @param {?=} options An options object that can contain a delay value for the start of the animation,
926
+ * and additional developer-defined parameters. Provided values for additional parameters are used
927
+ * as defaults, and override values can be passed to the caller on invocation.
928
+ * @return {?} An object that encapsulates the transition data.
864
929
  *
865
- * \@experimental Animation support is experimental.
866
- * @param {?} stateChangeExpr
867
- * @param {?} steps
868
- * @param {?=} options
869
- * @return {?}
870
930
  */
871
931
  export function transition(stateChangeExpr, steps, options = null) {
872
932
  return { type: 1 /* Transition */, expr: stateChangeExpr, animation: steps, options };
873
933
  }
874
934
  /**
875
- * `animation` is an animation-specific function that is designed to be used inside of Angular's
876
- * animation DSL language.
935
+ * Produces a reusable animation that can be invoked in another animation or sequence,
936
+ * by calling the `useAnimation()` function.
877
937
  *
878
- * `var myAnimation = animation(...)` is designed to produce a reusable animation that can be later
879
- * invoked in another animation or sequence. Reusable animations are designed to make use of
880
- * animation parameters and the produced animation can be used via the `useAnimation` method.
938
+ * \@usageNotes
939
+ * The following example defines a reusable animation, providing some default parameter
940
+ * values.
881
941
  *
882
- * ```
942
+ * ```typescript
883
943
  * var fadeAnimation = animation([
884
944
  * style({ opacity: '{{ start }}' }),
885
945
  * animate('{{ time }}',
886
- * style({ opacity: '{{ end }}'}))
887
- * ], { params: { time: '1000ms', start: 0, end: 1 }});
946
+ * style({ opacity: '{{ end }}'}))
947
+ * ],
948
+ * { params: { time: '1000ms', start: 0, end: 1 }});
888
949
  * ```
889
950
  *
890
- * If parameters are attached to an animation then they act as **default parameter values**. When an
891
- * animation is invoked via `useAnimation` then parameter values are allowed to be passed in
892
- * directly. If any of the passed in parameter values are missing then the default values will be
893
- * used.
951
+ * The following invokes the defined animation with a call to `useAnimation()`,
952
+ * passing in override parameter values.
894
953
  *
895
- * ```
954
+ * ```js
896
955
  * useAnimation(fadeAnimation, {
897
956
  * params: {
898
957
  * time: '2s',
@@ -902,145 +961,67 @@ export function transition(stateChangeExpr, steps, options = null) {
902
961
  * })
903
962
  * ```
904
963
  *
905
- * If one or more parameter values are missing before animated then an error will be thrown.
964
+ * If any of the passed-in parameter values are missing from this call,
965
+ * the default values are used. If one or more parameter values are missing before a step is
966
+ * animated, `useAnimation()` throws an error.
967
+ * @param {?} steps One or more animation objects, as returned by the `animate()`
968
+ * or `sequence()` function, that form a transformation from one state to another.
969
+ * A sequence is used by default when you pass an array.
970
+ * @param {?=} options An options object that can contain a delay value for the start of the
971
+ * animation, and additional developer-defined parameters.
972
+ * Provided values for additional parameters are used as defaults,
973
+ * and override values can be passed to the caller on invocation.
974
+ * @return {?} An object that encapsulates the animation data.
906
975
  *
907
- * \@experimental Animation support is experimental.
908
- * @param {?} steps
909
- * @param {?=} options
910
- * @return {?}
911
976
  */
912
977
  export function animation(steps, options = null) {
913
978
  return { type: 8 /* Reference */, animation: steps, options };
914
979
  }
915
980
  /**
916
- * `animateChild` is an animation-specific function that is designed to be used inside of Angular's
917
- * animation DSL language. It works by allowing a queried element to execute its own
918
- * animation within the animation sequence.
981
+ * Executes a queried inner animation element within an animation sequence.
919
982
  *
920
- * Each time an animation is triggered in angular, the parent animation
921
- * will always get priority and any child animations will be blocked. In order
983
+ * \@usageNotes
984
+ * Each time an animation is triggered in Angular, the parent animation
985
+ * has priority and any child animations are blocked. In order
922
986
  * for a child animation to run, the parent animation must query each of the elements
923
- * containing child animations and then allow the animations to run using `animateChild`.
924
- *
925
- * The example HTML code below shows both parent and child elements that have animation
926
- * triggers that will execute at the same time.
927
- *
928
- * ```html
929
- * <!-- parent-child.component.html -->
930
- * <button (click)="exp =! exp">Toggle</button>
931
- * <hr>
932
- *
933
- * <div [\@parentAnimation]="exp">
934
- * <header>Hello</header>
935
- * <div [\@childAnimation]="exp">
936
- * one
937
- * </div>
938
- * <div [\@childAnimation]="exp">
939
- * two
940
- * </div>
941
- * <div [\@childAnimation]="exp">
942
- * three
943
- * </div>
944
- * </div>
945
- * ```
946
- *
947
- * Now when the `exp` value changes to true, only the `parentAnimation` animation will animate
948
- * because it has priority. However, using `query` and `animateChild` each of the inner animations
949
- * can also fire:
950
- *
951
- * ```ts
952
- * // parent-child.component.ts
953
- * import {trigger, transition, animate, style, query, animateChild} from '\@angular/animations';
954
- * \@Component({
955
- * selector: 'parent-child-component',
956
- * animations: [
957
- * trigger('parentAnimation', [
958
- * transition('false => true', [
959
- * query('header', [
960
- * style({ opacity: 0 }),
961
- * animate(500, style({ opacity: 1 }))
962
- * ]),
963
- * query('\@childAnimation', [
964
- * animateChild()
965
- * ])
966
- * ])
967
- * ]),
968
- * trigger('childAnimation', [
969
- * transition('false => true', [
970
- * style({ opacity: 0 }),
971
- * animate(500, style({ opacity: 1 }))
972
- * ])
973
- * ])
974
- * ]
975
- * })
976
- * class ParentChildCmp {
977
- * exp: boolean = false;
978
- * }
979
- * ```
980
- *
981
- * In the animation code above, when the `parentAnimation` transition kicks off it first queries to
982
- * find the header element and fades it in. It then finds each of the sub elements that contain the
983
- * `\@childAnimation` trigger and then allows for their animations to fire.
984
- *
985
- * This example can be further extended by using stagger:
986
- *
987
- * ```ts
988
- * query('\@childAnimation', stagger(100, [
989
- * animateChild()
990
- * ]))
991
- * ```
992
- *
993
- * Now each of the sub animations start off with respect to the `100ms` staggering step.
994
- *
995
- * ## The first frame of child animations
996
- * When sub animations are executed using `animateChild` the animation engine will always apply the
997
- * first frame of every sub animation immediately at the start of the animation sequence. This way
998
- * the parent animation does not need to set any initial styling data on the sub elements before the
999
- * sub animations kick off.
1000
- *
1001
- * In the example above the first frame of the `childAnimation`'s `false => true` transition
1002
- * consists of a style of `opacity: 0`. This is applied immediately when the `parentAnimation`
1003
- * animation transition sequence starts. Only then when the `\@childAnimation` is queried and called
1004
- * with `animateChild` will it then animate to its destination of `opacity: 1`.
987
+ * containing child animations, and run them using this function.
1005
988
  *
1006
- * Note that this feature designed to be used alongside {\@link query query()} and it will only work
1007
- * with animations that are assigned using the Angular animation DSL (this means that CSS keyframes
1008
- * and transitions are not handled by this API).
989
+ * Note that this feature designed to be used with `query()` and it will only work
990
+ * with animations that are assigned using the Angular animation library. CSS keyframes
991
+ * and transitions are not handled by this API.
992
+ * @param {?=} options An options object that can contain a delay value for the start of the
993
+ * animation, and additional override values for developer-defined parameters.
994
+ * @return {?} An object that encapsulates the child animation data.
1009
995
  *
1010
- * \@experimental Animation support is experimental.
1011
- * @param {?=} options
1012
- * @return {?}
1013
996
  */
1014
997
  export function animateChild(options = null) {
1015
998
  return { type: 9 /* AnimateChild */, options };
1016
999
  }
1017
1000
  /**
1018
- * `useAnimation` is an animation-specific function that is designed to be used inside of Angular's
1019
- * animation DSL language. It is used to kick off a reusable animation that is created using {\@link
1020
- * animation animation()}.
1001
+ * Starts a reusable animation that is created using the `animation()` function.
1021
1002
  *
1022
- * \@experimental Animation support is experimental.
1023
- * @param {?} animation
1024
- * @param {?=} options
1025
- * @return {?}
1003
+ * @param {?} animation The reusable animation to start.
1004
+ * @param {?=} options An options object that can contain a delay value for the start of
1005
+ * the animation, and additional override values for developer-defined parameters.
1006
+ * @return {?} An object that contains the animation parameters.
1026
1007
  */
1027
1008
  export function useAnimation(animation, options = null) {
1028
1009
  return { type: 10 /* AnimateRef */, animation, options };
1029
1010
  }
1030
1011
  /**
1031
- * `query` is an animation-specific function that is designed to be used inside of Angular's
1032
- * animation DSL language.
1012
+ * Finds one or more inner elements within the current element that is
1013
+ * being animated within a sequence. Use with `animateChild()`.
1033
1014
  *
1034
- * query() is used to find one or more inner elements within the current element that is
1035
- * being animated within the sequence. The provided animation steps are applied
1036
- * to the queried element (by default, an array is provided, then this will be
1037
- * treated as an animation sequence).
1015
+ * \@usageNotes
1016
+ * Tokens can be merged into a combined query selector string. For example:
1038
1017
  *
1039
- * ### Usage
1018
+ * ```typescript
1019
+ * query(':self, .record:enter, .record:leave, \@subTrigger', [...])
1020
+ * ```
1040
1021
  *
1041
- * query() is designed to collect multiple elements and works internally by using
1042
- * `element.querySelectorAll`. An additional options object can be provided which
1043
- * can be used to limit the total amount of items to be collected.
1022
+ * The `query()` function collects multiple elements and works internally by using
1023
+ * `element.querySelectorAll`. Use the `limit` field of an options object to limit
1024
+ * the total number of items to be collected. For example:
1044
1025
  *
1045
1026
  * ```js
1046
1027
  * query('div', [
@@ -1049,8 +1030,8 @@ export function useAnimation(animation, options = null) {
1049
1030
  * ], { limit: 1 })
1050
1031
  * ```
1051
1032
  *
1052
- * query(), by default, will throw an error when zero items are found. If a query
1053
- * has the `optional` flag set to true then this error will be ignored.
1033
+ * By default, throws an error when zero items are found. Set the
1034
+ * `optional` flag to ignore this error. For example:
1054
1035
  *
1055
1036
  * ```js
1056
1037
  * query('.some-element-that-may-not-be-there', [
@@ -1059,31 +1040,12 @@ export function useAnimation(animation, options = null) {
1059
1040
  * ], { optional: true })
1060
1041
  * ```
1061
1042
  *
1062
- * ### Special Selector Values
1063
- *
1064
- * The selector value within a query can collect elements that contain angular-specific
1065
- * characteristics
1066
- * using special pseudo-selectors tokens.
1067
- *
1068
- * These include:
1043
+ * ### Usage Example
1069
1044
  *
1070
- * - Querying for newly inserted/removed elements using `query(":enter")`/`query(":leave")`
1071
- * - Querying all currently animating elements using `query(":animating")`
1072
- * - Querying elements that contain an animation trigger using `query("\@triggerName")`
1073
- * - Querying all elements that contain an animation triggers using `query("\@*")`
1074
- * - Including the current element into the animation sequence using `query(":self")`
1075
- *
1076
- *
1077
- * Each of these pseudo-selector tokens can be merged together into a combined query selector
1078
- * string:
1079
- *
1080
- * ```
1081
- * query(':self, .record:enter, .record:leave, \@subTrigger', [...])
1082
- * ```
1045
+ * The following example queries for inner elements and animates them
1046
+ * individually using `animateChild()`.
1083
1047
  *
1084
- * ### Demo
1085
- *
1086
- * ```
1048
+ * ```typescript
1087
1049
  * \@Component({
1088
1050
  * selector: 'inner',
1089
1051
  * template: `
@@ -1116,27 +1078,38 @@ export function useAnimation(animation, options = null) {
1116
1078
  * }
1117
1079
  * }
1118
1080
  * ```
1081
+ * @param {?} selector The element to query, or a set of elements that contain Angular-specific
1082
+ * characteristics, specified with one or more of the following tokens.
1083
+ * - `query(":enter")` or `query(":leave")` : Query for newly inserted/removed elements.
1084
+ * - `query(":animating")` : Query all currently animating elements.
1085
+ * - `query("\@triggerName")` : Query elements that contain an animation trigger.
1086
+ * - `query("\@*")` : Query all elements that contain an animation triggers.
1087
+ * - `query(":self")` : Include the current element into the animation sequence.
1088
+ *
1089
+ * @param {?} animation One or more animation steps to apply to the queried element or elements.
1090
+ * An array is treated as an animation sequence.
1091
+ * @param {?=} options An options object. Use the 'limit' field to limit the total number of
1092
+ * items to collect.
1093
+ * @return {?} An object that encapsulates the query data.
1119
1094
  *
1120
- * \@experimental Animation support is experimental.
1121
- * @param {?} selector
1122
- * @param {?} animation
1123
- * @param {?=} options
1124
- * @return {?}
1125
1095
  */
1126
1096
  export function query(selector, animation, options = null) {
1127
1097
  return { type: 11 /* Query */, selector, animation, options };
1128
1098
  }
1129
1099
  /**
1130
- * `stagger` is an animation-specific function that is designed to be used inside of Angular's
1131
- * animation DSL language. It is designed to be used inside of an animation {\@link query query()}
1132
- * and works by issuing a timing gap between after each queried item is animated.
1100
+ * Use within an animation `query()` call to issue a timing gap after
1101
+ * each queried item is animated.
1133
1102
  *
1134
- * ### Usage
1135
- *
1136
- * In the example below there is a container element that wraps a list of items stamped out
1137
- * by an ngFor. The container element contains an animation trigger that will later be set
1103
+ * \@usageNotes
1104
+ * In the following example, a container element wraps a list of items stamped out
1105
+ * by an `ngFor`. The container element contains an animation trigger that will later be set
1138
1106
  * to query for each of the inner items.
1139
1107
  *
1108
+ * Each time items are added, the opacity fade-in animation runs,
1109
+ * and each removed item is faded out.
1110
+ * When either of these animations occur, the stagger effect is
1111
+ * applied after each item's animation is started.
1112
+ *
1140
1113
  * ```html
1141
1114
  * <!-- list.component.html -->
1142
1115
  * <button (click)="toggle()">Show / Hide Items</button>
@@ -1148,15 +1121,15 @@ export function query(selector, animation, options = null) {
1148
1121
  * </div>
1149
1122
  * ```
1150
1123
  *
1151
- * The component code for this looks as such:
1124
+ * Here is the component code:
1152
1125
  *
1153
- * ```ts
1126
+ * ```typescript
1154
1127
  * import {trigger, transition, style, animate, query, stagger} from '\@angular/animations';
1155
1128
  * \@Component({
1156
1129
  * templateUrl: 'list.component.html',
1157
1130
  * animations: [
1158
1131
  * trigger('listAnimation', [
1159
- * //...
1132
+ * ...
1160
1133
  * ])
1161
1134
  * ]
1162
1135
  * })
@@ -1173,13 +1146,13 @@ export function query(selector, animation, options = null) {
1173
1146
  *
1174
1147
  * toggle() {
1175
1148
  * this.items.length ? this.hideItems() : this.showItems();
1176
- * }
1177
- * }
1149
+ * }
1150
+ * }
1178
1151
  * ```
1179
1152
  *
1180
- * And now for the animation trigger code:
1153
+ * Here is the animation trigger code:
1181
1154
  *
1182
- * ```ts
1155
+ * ```typescript
1183
1156
  * trigger('listAnimation', [
1184
1157
  * transition('* => *', [ // each time the binding value changes
1185
1158
  * query(':leave', [
@@ -1196,19 +1169,13 @@ export function query(selector, animation, options = null) {
1196
1169
  * ])
1197
1170
  * ])
1198
1171
  * ```
1172
+ * @param {?} timings A delay value.
1173
+ * @param {?} animation One ore more animation steps.
1174
+ * @return {?} An object that encapsulates the stagger data.
1199
1175
  *
1200
- * Now each time the items are added/removed then either the opacity
1201
- * fade-in animation will run or each removed item will be faded out.
1202
- * When either of these animations occur then a stagger effect will be
1203
- * applied after each item's animation is started.
1204
- *
1205
- * \@experimental Animation support is experimental.
1206
- * @param {?} timings
1207
- * @param {?} animation
1208
- * @return {?}
1209
1176
  */
1210
1177
  export function stagger(timings, animation) {
1211
1178
  return { type: 12 /* Stagger */, timings, animation };
1212
1179
  }
1213
1180
 
1214
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uX21ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5pbWF0aW9ucy9zcmMvYW5pbWF0aW9uX21ldGFkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBK0VBLE1BQU0sQ0FBQyx1QkFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ1U5QixNQUFNLGtCQUFrQixJQUFZLEVBQUUsV0FBZ0M7SUFDcEUsTUFBTSxDQUFDLEVBQUMsSUFBSSxpQkFBK0IsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUMsQ0FBQztDQUM5RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQStDRCxNQUFNLGtCQUNGLE9BQXdCLEVBQUUsU0FDZixJQUFJO0lBQ2pCLE1BQU0sQ0FBQyxFQUFDLElBQUksaUJBQStCLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQy9EOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWlDRCxNQUFNLGdCQUNGLEtBQTBCLEVBQUUsVUFBbUMsSUFBSTtJQUNyRSxNQUFNLENBQUMsRUFBQyxJQUFJLGVBQTZCLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQzVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9DRCxNQUFNLG1CQUFtQixLQUEwQixFQUFFLFVBQW1DLElBQUk7SUFFMUYsTUFBTSxDQUFDLEVBQUMsSUFBSSxrQkFBZ0MsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFDLENBQUM7Q0FDL0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTRDRCxNQUFNLGdCQUNGLE1BQzJDO0lBQzdDLE1BQU0sQ0FBQyxFQUFDLElBQUksZUFBNkIsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQztDQUMxRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrREQsTUFBTSxnQkFDRixJQUFZLEVBQUUsTUFBOEIsRUFDNUMsT0FBeUM7SUFDM0MsTUFBTSxDQUFDLEVBQUMsSUFBSSxlQUE2QixFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFDLENBQUM7Q0FDbkU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQStDRCxNQUFNLG9CQUFvQixLQUErQjtJQUN2RCxNQUFNLENBQUMsRUFBQyxJQUFJLG1CQUFpQyxFQUFFLEtBQUssRUFBQyxDQUFDO0NBQ3ZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF5TUQsTUFBTSxxQkFDRixlQUNzRSxFQUN0RSxLQUE4QyxFQUM5QyxVQUFtQyxJQUFJO0lBQ3pDLE1BQU0sQ0FBQyxFQUFDLElBQUksb0JBQWtDLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQ25HOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFxQ0QsTUFBTSxvQkFDRixLQUE4QyxFQUM5QyxVQUFtQyxJQUFJO0lBQ3pDLE1BQU0sQ0FBQyxFQUFDLElBQUksbUJBQWlDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUMsQ0FBQztDQUMzRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1HRCxNQUFNLHVCQUF1QixVQUFzQyxJQUFJO0lBRXJFLE1BQU0sQ0FBQyxFQUFDLElBQUksc0JBQW9DLEVBQUUsT0FBTyxFQUFDLENBQUM7Q0FDNUQ7Ozs7Ozs7Ozs7O0FBU0QsTUFBTSx1QkFDRixTQUFxQyxFQUNyQyxVQUFtQyxJQUFJO0lBQ3pDLE1BQU0sQ0FBQyxFQUFDLElBQUkscUJBQWtDLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQ3JFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBOEZELE1BQU0sZ0JBQ0YsUUFBZ0IsRUFBRSxTQUFrRCxFQUNwRSxVQUF3QyxJQUFJO0lBQzlDLE1BQU0sQ0FBQyxFQUFDLElBQUksZ0JBQTZCLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQztDQUMxRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdGRCxNQUFNLGtCQUNGLE9BQXdCLEVBQ3hCLFNBQWtEO0lBQ3BELE1BQU0sQ0FBQyxFQUFDLElBQUksa0JBQStCLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBQyxDQUFDO0NBQ2xFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSDJtVN0eWxlRGF0YSB7IFtrZXk6IHN0cmluZ106IHN0cmluZ3xudW1iZXI7IH1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgY3JlYXRlZCBpbnRlcm5hbGx5XG4gKiB3aXRoaW4gdGhlIEFuZ3VsYXIgYW5pbWF0aW9uIERTTC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGRlY2xhcmUgdHlwZSBBbmltYXRlVGltaW5ncyA9IHtcbiAgZHVyYXRpb246IG51bWJlcixcbiAgZGVsYXk6IG51bWJlcixcbiAgZWFzaW5nOiBzdHJpbmcgfCBudWxsXG59O1xuXG4vKipcbiAqIGBBbmltYXRpb25PcHRpb25zYCByZXByZXNlbnRzIG9wdGlvbnMgdGhhdCBjYW4gYmUgcGFzc2VkIGludG8gbW9zdCBhbmltYXRpb24gRFNMIG1ldGhvZHMuXG4gKiBXaGVuIG9wdGlvbnMgYXJlIHByb3ZpZGVkLCB0aGUgZGVsYXkgdmFsdWUgb2YgYW4gYW5pbWF0aW9uIGNhbiBiZSBjaGFuZ2VkIGFuZCBhbmltYXRpb24gaW5wdXRcbiAqIHBhcmFtZXRlcnMgY2FuIGJlIHBhc3NlZCBpbiB0byBjaGFuZ2Ugc3R5bGluZyBhbmQgdGltaW5nIGRhdGEgd2hlbiBhbiBhbmltYXRpb24gaXMgc3RhcnRlZC5cbiAqXG4gKiBUaGUgZm9sbG93aW5nIGFuaW1hdGlvbiBEU0wgZnVuY3Rpb25zIGFyZSBhYmxlIHRvIGFjY2VwdCBhbmltYXRpb24gb3B0aW9uIGRhdGE6XG4gKlxuICogLSB7QGxpbmsgdHJhbnNpdGlvbiB0cmFuc2l0aW9uKCl9XG4gKiAtIHtAbGluayBzZXF1ZW5jZSBzZXF1ZW5jZSgpfVxuICogLSB7QGxpbmsgZ3JvdXAgZ3JvdXAoKX1cbiAqIC0ge0BsaW5rIHF1ZXJ5IHF1ZXJ5KCl9XG4gKiAtIHtAbGluayBhbmltYXRpb24gYW5pbWF0aW9uKCl9XG4gKiAtIHtAbGluayB1c2VBbmltYXRpb24gdXNlQW5pbWF0aW9uKCl9XG4gKiAtIHtAbGluayBhbmltYXRlQ2hpbGQgYW5pbWF0ZUNoaWxkKCl9XG4gKlxuICogUHJvZ3JhbW1hdGljIGFuaW1hdGlvbnMgYnVpbHQgdXNpbmcge0BsaW5rIEFuaW1hdGlvbkJ1aWxkZXIgdGhlIEFuaW1hdGlvbkJ1aWxkZXIgc2VydmljZX0gYWxzb1xuICogbWFrZSB1c2Ugb2YgQW5pbWF0aW9uT3B0aW9ucy5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIEFuaW1hdGlvbk9wdGlvbnMge1xuICBkZWxheT86IG51bWJlcnxzdHJpbmc7XG4gIHBhcmFtcz86IHtbbmFtZTogc3RyaW5nXTogYW55fTtcbn1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgY3JlYXRlZCBpbnRlcm5hbGx5XG4gKiB3aXRoaW4gdGhlIEFuZ3VsYXIgYW5pbWF0aW9uIERTTCB3aGVuIHtAbGluayBhbmltYXRlQ2hpbGQgYW5pbWF0ZUNoaWxkKCl9IGlzIHVzZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBBbmltYXRlQ2hpbGRPcHRpb25zIGV4dGVuZHMgQW5pbWF0aW9uT3B0aW9ucyB7IGR1cmF0aW9uPzogbnVtYmVyfHN0cmluZzsgfVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gVXNhZ2VzIG9mIHRoaXMgZW51bSBhcmUgY3JlYXRlZFxuICogZWFjaCB0aW1lIGFuIGFuaW1hdGlvbiBEU0wgZnVuY3Rpb24gaXMgdXNlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gQW5pbWF0aW9uTWV0YWRhdGFUeXBlIHtcbiAgU3RhdGUgPSAwLFxuICBUcmFuc2l0aW9uID0gMSxcbiAgU2VxdWVuY2UgPSAyLFxuICBHcm91cCA9IDMsXG4gIEFuaW1hdGUgPSA0LFxuICBLZXlmcmFtZXMgPSA1LFxuICBTdHlsZSA9IDYsXG4gIFRyaWdnZXIgPSA3LFxuICBSZWZlcmVuY2UgPSA4LFxuICBBbmltYXRlQ2hpbGQgPSA5LFxuICBBbmltYXRlUmVmID0gMTAsXG4gIFF1ZXJ5ID0gMTEsXG4gIFN0YWdnZXIgPSAxMlxufVxuXG4vKipcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgY29uc3QgQVVUT19TVFlMRSA9ICcqJztcblxuLyoqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25NZXRhZGF0YSB7IHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZTsgfVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayB0cmlnZ2VyIHRyaWdnZXIgYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uVHJpZ2dlck1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlZmluaXRpb25zOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICBvcHRpb25zOiB7cGFyYW1zPzoge1tuYW1lOiBzdHJpbmddOiBhbnl9fXxudWxsO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBzdGF0ZSBzdGF0ZSBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25TdGF0ZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBuYW1lOiBzdHJpbmc7XG4gIHN0eWxlczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YTtcbiAgb3B0aW9ucz86IHtwYXJhbXM6IHtbbmFtZTogc3RyaW5nXTogYW55fX07XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHByb3ZpZGVkIHZpYSB0aGVcbiAqIGFuaW1hdGlvbiBEU0wgd2hlbiB0aGUge0BsaW5rIHRyYW5zaXRpb24gdHJhbnNpdGlvbiBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25UcmFuc2l0aW9uTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIGV4cHI6IHN0cmluZ3xcbiAgICAgICgoZnJvbVN0YXRlOiBzdHJpbmcsIHRvU3RhdGU6IHN0cmluZywgZWxlbWVudD86IGFueSxcbiAgICAgICAgcGFyYW1zPzoge1trZXk6IHN0cmluZ106IGFueX0pID0+IGJvb2xlYW4pO1xuICBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhfEFuaW1hdGlvbk1ldGFkYXRhW107XG4gIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnN8bnVsbDtcbn1cblxuLyoqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YXxBbmltYXRpb25NZXRhZGF0YVtdO1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uUXVlcnlNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgc2VsZWN0b3I6IHN0cmluZztcbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YXxBbmltYXRpb25NZXRhZGF0YVtdO1xuICBvcHRpb25zOiBBbmltYXRpb25RdWVyeU9wdGlvbnN8bnVsbDtcbn1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgcHJvdmlkZWQgdmlhIHRoZVxuICogYW5pbWF0aW9uIERTTCB3aGVuIHRoZSB7QGxpbmsga2V5ZnJhbWVzIGtleWZyYW1lcyBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25LZXlmcmFtZXNTZXF1ZW5jZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBzdGVwczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YVtdO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBzdHlsZSBzdHlsZSBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25TdHlsZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBzdHlsZXM6ICcqJ3x7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfXxBcnJheTx7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfXwnKic+O1xuICBvZmZzZXQ6IG51bWJlcnxudWxsO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBhbmltYXRlIGFuaW1hdGUgYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uQW5pbWF0ZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICB0aW1pbmdzOiBzdHJpbmd8bnVtYmVyfEFuaW1hdGVUaW1pbmdzO1xuICBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGF8QW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YXxudWxsO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBhbmltYXRlQ2hpbGQgYW5pbWF0ZUNoaWxkIGFuaW1hdGlvbiBmdW5jdGlvbn0gaXMgY2FsbGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVDaGlsZE1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHByb3ZpZGVkIHZpYSB0aGVcbiAqIGFuaW1hdGlvbiBEU0wgd2hlbiB0aGUge0BsaW5rIHVzZUFuaW1hdGlvbiB1c2VBbmltYXRpb24gYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uQW5pbWF0ZVJlZk1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBhbmltYXRpb246IEFuaW1hdGlvblJlZmVyZW5jZU1ldGFkYXRhO1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHByb3ZpZGVkIHZpYSB0aGVcbiAqIGFuaW1hdGlvbiBEU0wgd2hlbiB0aGUge0BsaW5rIHNlcXVlbmNlIHNlcXVlbmNlIGFuaW1hdGlvbiBmdW5jdGlvbn0gaXMgY2FsbGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblNlcXVlbmNlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHByb3ZpZGVkIHZpYSB0aGVcbiAqIGFuaW1hdGlvbiBEU0wgd2hlbiB0aGUge0BsaW5rIGdyb3VwIGdyb3VwIGFuaW1hdGlvbiBmdW5jdGlvbn0gaXMgY2FsbGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkdyb3VwTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHByb3ZpZGVkIHZpYSB0aGVcbiAqIGFuaW1hdGlvbiBEU0wgd2hlbiB0aGUge0BsaW5rIHF1ZXJ5IHF1ZXJ5IGFuaW1hdGlvbiBmdW5jdGlvbn0gaXMgY2FsbGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgQW5pbWF0aW9uUXVlcnlPcHRpb25zIGV4dGVuZHMgQW5pbWF0aW9uT3B0aW9ucyB7XG4gIG9wdGlvbmFsPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFVzZWQgdG8gbGltaXQgdGhlIHRvdGFsIGFtb3VudCBvZiByZXN1bHRzIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBxdWVyeSBsaXN0LlxuICAgKlxuICAgKiBJZiBhIG5lZ2F0aXZlIHZhbHVlIGlzIHByb3ZpZGVkIHRoZW4gdGhlIHF1ZXJpZWQgcmVzdWx0cyB3aWxsIGJlIGxpbWl0ZWQgZnJvbSB0aGVcbiAgICogZW5kIG9mIHRoZSBxdWVyeSBsaXN0IHRvd2FyZHMgdGhlIGJlZ2lubmluZyAoZS5nLiBpZiBgbGltaXQ6IC0zYCBpcyB1c2VkIHRoZW4gdGhlXG4gICAqIGZpbmFsIDMgKG9yIGxlc3MpIHF1ZXJpZWQgcmVzdWx0cyB3aWxsIGJlIHVzZWQgZm9yIHRoZSBhbmltYXRpb24pLlxuICAgKi9cbiAgbGltaXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHByb3ZpZGVkIHZpYSB0aGVcbiAqIGFuaW1hdGlvbiBEU0wgd2hlbiB0aGUge0BsaW5rIHN0YWdnZXIgc3RhZ2dlciBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4qIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uU3RhZ2dlck1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICB0aW1pbmdzOiBzdHJpbmd8bnVtYmVyO1xuICBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhfEFuaW1hdGlvbk1ldGFkYXRhW107XG59XG5cbi8qKlxuICogYHRyaWdnZXJgIGlzIGFuIGFuaW1hdGlvbi1zcGVjaWZpYyBmdW5jdGlvbiB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIEFuZ3VsYXInc1xuICogYW5pbWF0aW9uIERTTCBsYW5ndWFnZS4gSWYgdGhpcyBpbmZvcm1hdGlvbiBpcyBuZXcsIHBsZWFzZSBuYXZpZ2F0ZSB0byB0aGVcbiAqIHtAbGluayBDb21wb25lbnQjYW5pbWF0aW9ucyBjb21wb25lbnQgYW5pbWF0aW9ucyBtZXRhZGF0YSBwYWdlfSB0byBnYWluIGEgYmV0dGVyXG4gKiB1bmRlcnN0YW5kaW5nIG9mIGhvdyBhbmltYXRpb25zIGluIEFuZ3VsYXIgYXJlIHVzZWQuXG4gKlxuICogYHRyaWdnZXJgIENyZWF0ZXMgYW4gYW5pbWF0aW9uIHRyaWdnZXIgd2hpY2ggd2lsbCBhIGxpc3Qgb2Yge0BsaW5rIHN0YXRlIHN0YXRlfSBhbmRcbiAqIHtAbGluayB0cmFuc2l0aW9uIHRyYW5zaXRpb259IGVudHJpZXMgdGhhdCB3aWxsIGJlIGV2YWx1YXRlZCB3aGVuIHRoZSBleHByZXNzaW9uXG4gKiBib3VuZCB0byB0aGUgdHJpZ2dlciBjaGFuZ2VzLlxuICpcbiAqIFRyaWdnZXJzIGFyZSByZWdpc3RlcmVkIHdpdGhpbiB0aGUgY29tcG9uZW50IGFubm90YXRpb24gZGF0YSB1bmRlciB0aGVcbiAqIHtAbGluayBDb21wb25lbnQjYW5pbWF0aW9ucyBhbmltYXRpb25zIHNlY3Rpb259LiBBbiBhbmltYXRpb24gdHJpZ2dlciBjYW4gYmUgcGxhY2VkIG9uIGFuIGVsZW1lbnRcbiAqIHdpdGhpbiBhIHRlbXBsYXRlIGJ5IHJlZmVyZW5jaW5nIHRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyIGZvbGxvd2VkIGJ5IHRoZSBleHByZXNzaW9uIHZhbHVlIHRoYXRcbiB0aGVcbiAqIHRyaWdnZXIgaXMgYm91bmQgdG8gKGluIHRoZSBmb3JtIG9mIGBbQHRyaWdnZXJOYW1lXT1cImV4cHJlc3Npb25cImAuXG4gKlxuICogQW5pbWF0aW9uIHRyaWdnZXIgYmluZGluZ3Mgc3RyaWdpZnkgdmFsdWVzIGFuZCB0aGVuIG1hdGNoIHRoZSBwcmV2aW91cyBhbmQgY3VycmVudCB2YWx1ZXMgYWdhaW5zdFxuICogYW55IGxpbmtlZCB0cmFuc2l0aW9ucy4gSWYgYSBib29sZWFuIHZhbHVlIGlzIHByb3ZpZGVkIGludG8gdGhlIHRyaWdnZXIgYmluZGluZyB0aGVuIGl0IHdpbGwgYm90aFxuICogYmUgcmVwcmVzZW50ZWQgYXMgYDFgIG9yIGB0cnVlYCBhbmQgYDBgIG9yIGBmYWxzZWAgZm9yIGEgdHJ1ZSBhbmQgZmFsc2UgYm9vbGVhbiB2YWx1ZXNcbiAqIHJlc3BlY3RpdmVseS5cbiAqXG4gKiAjIyMgVXNhZ2VcbiAqXG4gKiBgdHJpZ2dlcmAgd2lsbCBjcmVhdGUgYW4gYW5pbWF0aW9uIHRyaWdnZXIgcmVmZXJlbmNlIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBgbmFtZWAgdmFsdWUuIFRoZVxuICogcHJvdmlkZWQgYGFuaW1hdGlvbmAgdmFsdWUgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXkgY29uc2lzdGluZyBvZiB7QGxpbmsgc3RhdGUgc3RhdGV9IGFuZFxuICoge0BsaW5rIHRyYW5zaXRpb24gdHJhbnNpdGlvbn0gZGVjbGFyYXRpb25zLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ215LWNvbXBvbmVudCcsXG4gKiAgIHRlbXBsYXRlVXJsOiAnbXktY29tcG9uZW50LXRwbC5odG1sJyxcbiAqICAgYW5pbWF0aW9uczogW1xuICogICAgIHRyaWdnZXIoXCJteUFuaW1hdGlvblRyaWdnZXJcIiwgW1xuICogICAgICAgc3RhdGUoLi4uKSxcbiAqICAgICAgIHN0YXRlKC4uLiksXG4gKiAgICAgICB0cmFuc2l0aW9uKC4uLiksXG4gKiAgICAgICB0cmFuc2l0aW9uKC4uLilcbiAqICAgICBdKVxuICogICBdXG4gKiB9KVxuICogY2xhc3MgTXlDb21wb25lbnQge1xuICogICBteVN0YXR1c0V4cCA9IFwic29tZXRoaW5nXCI7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgdGVtcGxhdGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29tcG9uZW50IHdpbGwgbWFrZSB1c2Ugb2YgdGhlIGBteUFuaW1hdGlvblRyaWdnZXJgIGFuaW1hdGlvblxuIHRyaWdnZXIgYnkgYmluZGluZyB0byBhbiBlbGVtZW50IHdpdGhpbiBpdHMgdGVtcGxhdGUgY29kZS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8IS0tIHNvbWV3aGVyZSBpbnNpZGUgb2YgbXktY29tcG9uZW50LXRwbC5odG1sIC0tPlxuICogPGRpdiBbQG15QW5pbWF0aW9uVHJpZ2dlcl09XCJteVN0YXR1c0V4cFwiPi4uLjwvZGl2PlxuICogYGBgXG4gKlxuICogIyMjIFVzaW5nIGFuIGlubGluZSBmdW5jdGlvblxuICogVGhlIGB0cmFuc2l0aW9uYCBhbmltYXRpb24gbWV0aG9kIGFsc28gc3VwcG9ydHMgcmVhZGluZyBhbiBpbmxpbmUgZnVuY3Rpb24gd2hpY2ggY2FuIGRlY2lkZVxuICogaWYgaXRzIGFzc29jaWF0ZWQgYW5pbWF0aW9uIHNob3VsZCBiZSBydW4uXG4gKlxuICogYGBgXG4gKiAvLyB0aGlzIG1ldGhvZCB3aWxsIGJlIHJ1biBlYWNoIHRpbWUgdGhlIGBteUFuaW1hdGlvblRyaWdnZXJgXG4gKiAvLyB0cmlnZ2VyIHZhbHVlIGNoYW5nZXMuLi5cbiAqIGZ1bmN0aW9uIG15SW5saW5lTWF0Y2hlckZuKGZyb21TdGF0ZTogc3RyaW5nLCB0b1N0YXRlOiBzdHJpbmcsIGVsZW1lbnQ6IGFueSwgcGFyYW1zOiB7W2tleTpcbiBzdHJpbmddOiBhbnl9KTogYm9vbGVhbiB7XG4gKiAgIC8vIG5vdGljZSB0aGF0IGBlbGVtZW50YCBhbmQgYHBhcmFtc2AgYXJlIGFsc28gYXZhaWxhYmxlIGhlcmVcbiAqICAgcmV0dXJuIHRvU3RhdGUgPT0gJ3llcy1wbGVhc2UtYW5pbWF0ZSc7XG4gKiB9XG4gKlxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnbXktY29tcG9uZW50JyxcbiAqICAgdGVtcGxhdGVVcmw6ICdteS1jb21wb25lbnQtdHBsLmh0bWwnLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcignbXlBbmltYXRpb25UcmlnZ2VyJywgW1xuICogICAgICAgdHJhbnNpdGlvbihteUlubGluZU1hdGNoZXJGbiwgW1xuICogICAgICAgICAvLyB0aGUgYW5pbWF0aW9uIHNlcXVlbmNlIGNvZGVcbiAqICAgICAgIF0pLFxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBNeUNvbXBvbmVudCB7XG4gKiAgIG15U3RhdHVzRXhwID0gXCJ5ZXMtcGxlYXNlLWFuaW1hdGVcIjtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIFRoZSBpbmxpbmUgbWV0aG9kIHdpbGwgYmUgcnVuIGVhY2ggdGltZSB0aGUgdHJpZ2dlclxuICogdmFsdWUgY2hhbmdlc1xuICpcbiAqICMjIERpc2FibGUgQW5pbWF0aW9uc1xuICogQSBzcGVjaWFsIGFuaW1hdGlvbiBjb250cm9sIGJpbmRpbmcgY2FsbGVkIGBALmRpc2FibGVkYCBjYW4gYmUgcGxhY2VkIG9uIGFuIGVsZW1lbnQgd2hpY2ggd2lsbFxuIHRoZW4gZGlzYWJsZSBhbmltYXRpb25zIGZvciBhbnkgaW5uZXIgYW5pbWF0aW9uIHRyaWdnZXJzIHNpdHVhdGVkIHdpdGhpbiB0aGUgZWxlbWVudCBhcyB3ZWxsIGFzXG4gYW55IGFuaW1hdGlvbnMgb24gdGhlIGVsZW1lbnQgaXRzZWxmLlxuICpcbiAqIFdoZW4gdHJ1ZSwgdGhlIGBALmRpc2FibGVkYCBiaW5kaW5nIHdpbGwgcHJldmVudCBhbGwgYW5pbWF0aW9ucyBmcm9tIHJlbmRlcmluZy4gVGhlIGV4YW1wbGVcbiBiZWxvdyBzaG93cyBob3cgdG8gdXNlIHRoaXMgZmVhdHVyZTpcbiAqXG4gKiBgYGB0c1xuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnbXktY29tcG9uZW50JyxcbiAqICAgdGVtcGxhdGU6IGBcbiAqICAgICA8ZGl2IFtALmRpc2FibGVkXT1cImlzRGlzYWJsZWRcIj5cbiAqICAgICAgIDxkaXYgW0BjaGlsZEFuaW1hdGlvbl09XCJleHBcIj48L2Rpdj5cbiAqICAgICA8L2Rpdj5cbiAqICAgYCxcbiAqICAgYW5pbWF0aW9uczogW1xuICogICAgIHRyaWdnZXIoXCJjaGlsZEFuaW1hdGlvblwiLCBbXG4gKiAgICAgICAvLyAuLi5cbiAqICAgICBdKVxuICogICBdXG4gKiB9KVxuICogY2xhc3MgTXlDb21wb25lbnQge1xuICogICBpc0Rpc2FibGVkID0gdHJ1ZTtcbiAqICAgZXhwID0gJy4uLic7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgYEBjaGlsZEFuaW1hdGlvbmAgdHJpZ2dlciB3aWxsIG5vdCBhbmltYXRlIGJlY2F1c2UgYEAuZGlzYWJsZWRgIHByZXZlbnRzIGl0IGZyb20gaGFwcGVuaW5nXG4gKHdoZW4gdHJ1ZSkuXG4gKlxuICogTm90ZSB0aGF0IGBALmRpc2FibGVkYCB3aWxsIG9ubHkgZGlzYWJsZSBhbGwgYW5pbWF0aW9ucyAodGhpcyBtZWFucyBhbnkgYW5pbWF0aW9ucyBydW5uaW5nIG9uXG4gKiB0aGUgc2FtZSBlbGVtZW50IHdpbGwgYWxzbyBiZSBkaXNhYmxlZCkuXG4gKlxuICogIyMjIERpc2FibGluZyBBbmltYXRpb25zIEFwcGxpY2F0aW9uLXdpZGVcbiAqIFdoZW4gYW4gYXJlYSBvZiB0aGUgdGVtcGxhdGUgaXMgc2V0IHRvIGhhdmUgYW5pbWF0aW9ucyBkaXNhYmxlZCwgKiphbGwqKiBpbm5lciBjb21wb25lbnRzIHdpbGxcbiBhbHNvIGhhdmUgdGhlaXIgYW5pbWF0aW9ucyBkaXNhYmxlZCBhcyB3ZWxsLiBUaGlzIG1lYW5zIHRoYXQgYWxsIGFuaW1hdGlvbnMgZm9yIGFuIGFuZ3VsYXJcbiBhcHBsaWNhdGlvbiBjYW4gYmUgZGlzYWJsZWQgYnkgcGxhY2luZyBhIGhvc3QgYmluZGluZyBzZXQgb24gYEAuZGlzYWJsZWRgIG9uIHRoZSB0b3Btb3N0IEFuZ3VsYXJcbiBjb21wb25lbnQuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7Q29tcG9uZW50LCBIb3N0QmluZGluZ30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG4gKlxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnYXBwLWNvbXBvbmVudCcsXG4gKiAgIHRlbXBsYXRlVXJsOiAnYXBwLmNvbXBvbmVudC5odG1sJyxcbiAqIH0pXG4gKiBjbGFzcyBBcHBDb21wb25lbnQge1xuICogICBASG9zdEJpbmRpbmcoJ0AuZGlzYWJsZWQnKVxuICogICBwdWJsaWMgYW5pbWF0aW9uc0Rpc2FibGVkID0gdHJ1ZTtcbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIyBXaGF0IGFib3V0IGFuaW1hdGlvbnMgdGhhdCB1cyBgcXVlcnkoKWAgYW5kIGBhbmltYXRlQ2hpbGQoKWA/XG4gKiBEZXNwaXRlIGlubmVyIGFuaW1hdGlvbnMgYmVpbmcgZGlzYWJsZWQsIGEgcGFyZW50IGFuaW1hdGlvbiBjYW4ge0BsaW5rIHF1ZXJ5IHF1ZXJ5fSBmb3IgaW5uZXJcbiBlbGVtZW50cyBsb2NhdGVkIGluIGRpc2FibGVkIGFyZWFzIG9mIHRoZSB0ZW1wbGF0ZSBhbmQgc3RpbGwgYW5pbWF0ZSB0aGVtIGFzIGl0IHNlZXMgZml0LiBUaGlzIGlzXG4gYWxzbyB0aGUgY2FzZSBmb3Igd2hlbiBhIHN1YiBhbmltYXRpb24gaXMgcXVlcmllZCBieSBhIHBhcmVudCBhbmQgdGhlbiBsYXRlciBhbmltYXRlZCB1c2luZyB7QGxpbmtcbiBhbmltYXRlQ2hpbGQgYW5pbWF0ZUNoaWxkfS5cblxuICogIyMjIERldGVjdGluZyB3aGVuIGFuIGFuaW1hdGlvbiBpcyBkaXNhYmxlZFxuICogSWYgYSByZWdpb24gb2YgdGhlIERPTSAob3IgdGhlIGVudGlyZSBhcHBsaWNhdGlvbikgaGFzIGl0cyBhbmltYXRpb25zIGRpc2FibGVkLCB0aGVuIGFuaW1hdGlvblxuICogdHJpZ2dlciBjYWxsYmFja3Mgd2lsbCBzdGlsbCBmaXJlIGp1c3QgYXMgbm9ybWFsIChvbmx5IGZvciB6ZXJvIHNlY29uZHMpLlxuICpcbiAqIFdoZW4gYSB0cmlnZ2VyIGNhbGxiYWNrIGZpcmVzIGl0IHdpbGwgcHJvdmlkZSBhbiBpbnN0YW5jZSBvZiBhbiB7QGxpbmsgQW5pbWF0aW9uRXZlbnR9LiBJZlxuIGFuaW1hdGlvbnNcbiAqIGFyZSBkaXNhYmxlZCB0aGVuIHRoZSBgLmRpc2FibGVkYCBmbGFnIG9uIHRoZSBldmVudCB3aWxsIGJlIHRydWUuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmlnZ2VyKG5hbWU6IHN0cmluZywgZGVmaW5pdGlvbnM6IEFuaW1hdGlvbk1ldGFkYXRhW10pOiBBbmltYXRpb25UcmlnZ2VyTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5UcmlnZ2VyLCBuYW1lLCBkZWZpbml0aW9ucywgb3B0aW9uczoge319O1xufVxuXG4vKipcbiAqIGBhbmltYXRlYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIElmIHRoaXMgaW5mb3JtYXRpb24gaXMgbmV3LCBwbGVhc2UgbmF2aWdhdGUgdG8gdGhlIHtAbGlua1xuICogQ29tcG9uZW50I2FuaW1hdGlvbnMgY29tcG9uZW50IGFuaW1hdGlvbnMgbWV0YWRhdGEgcGFnZX0gdG8gZ2FpbiBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mXG4gKiBob3cgYW5pbWF0aW9ucyBpbiBBbmd1bGFyIGFyZSB1c2VkLlxuICpcbiAqIGBhbmltYXRlYCBzcGVjaWZpZXMgYW4gYW5pbWF0aW9uIHN0ZXAgdGhhdCB3aWxsIGFwcGx5IHRoZSBwcm92aWRlZCBgc3R5bGVzYCBkYXRhIGZvciBhIGdpdmVuXG4gKiBhbW91bnQgb2YgdGltZSBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYHRpbWluZ2AgZXhwcmVzc2lvbiB2YWx1ZS4gQ2FsbHMgdG8gYGFuaW1hdGVgIGFyZSBleHBlY3RlZFxuICogdG8gYmUgdXNlZCB3aXRoaW4ge0BsaW5rIHNlcXVlbmNlIGFuIGFuaW1hdGlvbiBzZXF1ZW5jZX0sIHtAbGluayBncm91cCBncm91cH0sIG9yIHtAbGlua1xuICogdHJhbnNpdGlvbiB0cmFuc2l0aW9ufS5cbiAqXG4gKiAjIyMgVXNhZ2VcbiAqXG4gKiBUaGUgYGFuaW1hdGVgIGZ1bmN0aW9uIGFjY2VwdHMgdHdvIGlucHV0IHBhcmFtZXRlcnM6IGB0aW1pbmdgIGFuZCBgc3R5bGVzYDpcbiAqXG4gKiAtIGB0aW1pbmdgIGlzIGEgc3RyaW5nIGJhc2VkIHZhbHVlIHRoYXQgY2FuIGJlIGEgY29tYmluYXRpb24gb2YgYSBkdXJhdGlvbiB3aXRoIG9wdGlvbmFsIGRlbGF5XG4gKiBhbmQgZWFzaW5nIHZhbHVlcy4gVGhlIGZvcm1hdCBmb3IgdGhlIGV4cHJlc3Npb24gYnJlYWtzIGRvd24gdG8gYGR1cmF0aW9uIGRlbGF5IGVhc2luZ2BcbiAqICh0aGVyZWZvcmUgYSB2YWx1ZSBzdWNoIGFzIGAxcyAxMDBtcyBlYXNlLW91dGAgd2lsbCBiZSBwYXJzZSBpdHNlbGYgaW50byBgZHVyYXRpb249MTAwMCxcbiAqIGRlbGF5PTEwMCwgZWFzaW5nPWVhc2Utb3V0YC4gSWYgYSBudW1lcmljIHZhbHVlIGlzIHByb3ZpZGVkIHRoZW4gdGhhdCB3aWxsIGJlIHVzZWQgYXMgdGhlXG4gKiBgZHVyYXRpb25gIHZhbHVlIGluIG1pbGxpc2Vjb25kIGZvcm0uXG4gKiAtIGBzdHlsZXNgIGlzIHRoZSBzdHlsZSBpbnB1dCBkYXRhIHdoaWNoIGNhbiBlaXRoZXIgYmUgYSBjYWxsIHRvIHtAbGluayBzdHlsZSBzdHlsZX0gb3Ige0BsaW5rXG4gKiBrZXlmcmFtZXMga2V5ZnJhbWVzfS4gSWYgbGVmdCBlbXB0eSB0aGVuIHRoZSBzdHlsZXMgZnJvbSB0aGUgZGVzdGluYXRpb24gc3RhdGUgd2lsbCBiZSBjb2xsZWN0ZWRcbiAqIGFuZCB1c2VkICh0aGlzIGlzIHVzZWZ1bCB3aGVuIGRlc2NyaWJpbmcgYW4gYW5pbWF0aW9uIHN0ZXAgdGhhdCB3aWxsIGNvbXBsZXRlIGFuIGFuaW1hdGlvbiBieVxuICoge0BsaW5rIHRyYW5zaXRpb24jdGhlLWZpbmFsLWFuaW1hdGUtY2FsbCBhbmltYXRpbmcgdG8gdGhlIGZpbmFsIHN0YXRlfSkuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gdmFyaW91cyBmdW5jdGlvbnMgZm9yIHNwZWNpZnlpbmcgdGltaW5nIGRhdGFcbiAqIGFuaW1hdGUoNTAwLCBzdHlsZSguLi4pKVxuICogYW5pbWF0ZShcIjFzXCIsIHN0eWxlKC4uLikpXG4gKiBhbmltYXRlKFwiMTAwbXMgMC41c1wiLCBzdHlsZSguLi4pKVxuICogYW5pbWF0ZShcIjVzIGVhc2VcIiwgc3R5bGUoLi4uKSlcbiAqIGFuaW1hdGUoXCI1cyAxMG1zIGN1YmljLWJlemllciguMTcsLjY3LC44OCwuMSlcIiwgc3R5bGUoLi4uKSlcbiAqXG4gKiAvLyBlaXRoZXIgc3R5bGUoKSBvZiBrZXlmcmFtZXMoKSBjYW4gYmUgdXNlZFxuICogYW5pbWF0ZSg1MDAsIHN0eWxlKHsgYmFja2dyb3VuZDogXCJyZWRcIiB9KSlcbiAqIGFuaW1hdGUoNTAwLCBrZXlmcmFtZXMoW1xuICogICBzdHlsZSh7IGJhY2tncm91bmQ6IFwiYmx1ZVwiIH0pKSxcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcInJlZFwiIH0pKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIHtAZXhhbXBsZSBjb3JlL2FuaW1hdGlvbi90cy9kc2wvYW5pbWF0aW9uX2V4YW1wbGUudHMgcmVnaW9uPSdDb21wb25lbnQnfVxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5pbWF0ZShcbiAgICB0aW1pbmdzOiBzdHJpbmcgfCBudW1iZXIsIHN0eWxlczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YSB8IEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGEgfFxuICAgICAgICBudWxsID0gbnVsbCk6IEFuaW1hdGlvbkFuaW1hdGVNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLkFuaW1hdGUsIHN0eWxlcywgdGltaW5nc307XG59XG5cbi8qKlxuICogYGdyb3VwYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIElmIHRoaXMgaW5mb3JtYXRpb24gaXMgbmV3LCBwbGVhc2UgbmF2aWdhdGUgdG8gdGhlIHtAbGlua1xuICogQ29tcG9uZW50I2FuaW1hdGlvbnMgY29tcG9uZW50IGFuaW1hdGlvbnMgbWV0YWRhdGEgcGFnZX0gdG8gZ2FpbiBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mXG4gKiBob3cgYW5pbWF0aW9ucyBpbiBBbmd1bGFyIGFyZSB1c2VkLlxuICpcbiAqIGBncm91cGAgc3BlY2lmaWVzIGEgbGlzdCBvZiBhbmltYXRpb24gc3RlcHMgdGhhdCBhcmUgYWxsIHJ1biBpbiBwYXJhbGxlbC4gR3JvdXBlZCBhbmltYXRpb25zIGFyZVxuICogdXNlZnVsIHdoZW4gYSBzZXJpZXMgb2Ygc3R5bGVzIG11c3QgYmUgYW5pbWF0ZWQvY2xvc2VkIG9mZiBhdCBkaWZmZXJlbnQgc3RhcnRpbmcvZW5kaW5nIHRpbWVzLlxuICpcbiAqIFRoZSBgZ3JvdXBgIGZ1bmN0aW9uIGNhbiBlaXRoZXIgYmUgdXNlZCB3aXRoaW4gYSB7QGxpbmsgc2VxdWVuY2Ugc2VxdWVuY2V9IG9yIGEge0BsaW5rIHRyYW5zaXRpb25cbiAqIHRyYW5zaXRpb259IGFuZCBpdCB3aWxsIG9ubHkgY29udGludWUgdG8gdGhlIG5leHQgaW5zdHJ1Y3Rpb24gb25jZSBhbGwgb2YgdGhlIGlubmVyIGFuaW1hdGlvblxuICogc3RlcHMgaGF2ZSBjb21wbGV0ZWQuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogVGhlIGBzdGVwc2AgZGF0YSB0aGF0IGlzIHBhc3NlZCBpbnRvIHRoZSBgZ3JvdXBgIGFuaW1hdGlvbiBmdW5jdGlvbiBjYW4gZWl0aGVyIGNvbnNpc3Qgb2Yge0BsaW5rXG4gKiBzdHlsZSBzdHlsZX0gb3Ige0BsaW5rIGFuaW1hdGUgYW5pbWF0ZX0gZnVuY3Rpb24gY2FsbHMuIEVhY2ggY2FsbCB0byBgc3R5bGUoKWAgb3IgYGFuaW1hdGUoKWBcbiAqIHdpdGhpbiBhIGdyb3VwIHdpbGwgYmUgZXhlY3V0ZWQgaW5zdGFudGx5ICh1c2Uge0BsaW5rIGtleWZyYW1lcyBrZXlmcmFtZXN9IG9yIGEge0BsaW5rXG4gKiBhbmltYXRlI3VzYWdlIGFuaW1hdGUoKSB3aXRoIGEgZGVsYXkgdmFsdWV9IHRvIG9mZnNldCBzdHlsZXMgdG8gYmUgYXBwbGllZCBhdCBhIGxhdGVyIHRpbWUpLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGdyb3VwKFtcbiAqICAgYW5pbWF0ZShcIjFzXCIsIHsgYmFja2dyb3VuZDogXCJibGFja1wiIH0pKVxuICogICBhbmltYXRlKFwiMnNcIiwgeyBjb2xvcjogXCJ3aGl0ZVwiIH0pKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIHtAZXhhbXBsZSBjb3JlL2FuaW1hdGlvbi90cy9kc2wvYW5pbWF0aW9uX2V4YW1wbGUudHMgcmVnaW9uPSdDb21wb25lbnQnfVxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXAoXG4gICAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhW10sIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsID0gbnVsbCk6IEFuaW1hdGlvbkdyb3VwTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5Hcm91cCwgc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIGBzZXF1ZW5jZWAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJZiB0aGlzIGluZm9ybWF0aW9uIGlzIG5ldywgcGxlYXNlIG5hdmlnYXRlIHRvIHRoZSB7QGxpbmtcbiAqIENvbXBvbmVudCNhbmltYXRpb25zIGNvbXBvbmVudCBhbmltYXRpb25zIG1ldGFkYXRhIHBhZ2V9IHRvIGdhaW4gYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZlxuICogaG93IGFuaW1hdGlvbnMgaW4gQW5ndWxhciBhcmUgdXNlZC5cbiAqXG4gKiBgc2VxdWVuY2VgIFNwZWNpZmllcyBhIGxpc3Qgb2YgYW5pbWF0aW9uIHN0ZXBzIHRoYXQgYXJlIHJ1biBvbmUgYnkgb25lLiAoYHNlcXVlbmNlYCBpcyB1c2VkIGJ5XG4gKiBkZWZhdWx0IHdoZW4gYW4gYXJyYXkgaXMgcGFzc2VkIGFzIGFuaW1hdGlvbiBkYXRhIGludG8ge0BsaW5rIHRyYW5zaXRpb24gdHJhbnNpdGlvbn0uKVxuICpcbiAqIFRoZSBgc2VxdWVuY2VgIGZ1bmN0aW9uIGNhbiBlaXRoZXIgYmUgdXNlZCB3aXRoaW4gYSB7QGxpbmsgZ3JvdXAgZ3JvdXB9IG9yIGEge0BsaW5rIHRyYW5zaXRpb25cbiAqIHRyYW5zaXRpb259IGFuZCBpdCB3aWxsIG9ubHkgY29udGludWUgdG8gdGhlIG5leHQgaW5zdHJ1Y3Rpb24gb25jZSBlYWNoIG9mIHRoZSBpbm5lciBhbmltYXRpb25cbiAqIHN0ZXBzIGhhdmUgY29tcGxldGVkLlxuICpcbiAqIFRvIHBlcmZvcm0gYW5pbWF0aW9uIHN0eWxpbmcgaW4gcGFyYWxsZWwgd2l0aCBvdGhlciBhbmltYXRpb24gc3RlcHMgdGhlbiBoYXZlIGEgbG9vayBhdCB0aGVcbiAqIHtAbGluayBncm91cCBncm91cH0gYW5pbWF0aW9uIGZ1bmN0aW9uLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIFRoZSBgc3RlcHNgIGRhdGEgdGhhdCBpcyBwYXNzZWQgaW50byB0aGUgYHNlcXVlbmNlYCBhbmltYXRpb24gZnVuY3Rpb24gY2FuIGVpdGhlciBjb25zaXN0IG9mXG4gKiB7QGxpbmsgc3R5bGUgc3R5bGV9IG9yIHtAbGluayBhbmltYXRlIGFuaW1hdGV9IGZ1bmN0aW9uIGNhbGxzLiBBIGNhbGwgdG8gYHN0eWxlKClgIHdpbGwgYXBwbHkgdGhlXG4gKiBwcm92aWRlZCBzdHlsaW5nIGRhdGEgaW1tZWRpYXRlbHkgd2hpbGUgYSBjYWxsIHRvIGBhbmltYXRlKClgIHdpbGwgYXBwbHkgaXRzIHN0eWxpbmcgZGF0YSBvdmVyIGFcbiAqIGdpdmVuIHRpbWUgZGVwZW5kaW5nIG9uIGl0cyB0aW1pbmcgZGF0YS5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBzZXF1ZW5jZShbXG4gKiAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSksXG4gKiAgIGFuaW1hdGUoXCIxc1wiLCB7IG9wYWNpdHk6IDEgfSkpXG4gKiBdKVxuICogYGBgXG4gKlxuICoge0BleGFtcGxlIGNvcmUvYW5pbWF0aW9uL3RzL2RzbC9hbmltYXRpb25fZXhhbXBsZS50cyByZWdpb249J0NvbXBvbmVudCd9XG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW5jZShzdGVwczogQW5pbWF0aW9uTWV0YWRhdGFbXSwgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsKTpcbiAgICBBbmltYXRpb25TZXF1ZW5jZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU2VxdWVuY2UsIHN0ZXBzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBgc3R5bGVgIGlzIGFuIGFuaW1hdGlvbi1zcGVjaWZpYyBmdW5jdGlvbiB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIEFuZ3VsYXInc1xuICogYW5pbWF0aW9uIERTTCBsYW5ndWFnZS4gSWYgdGhpcyBpbmZvcm1hdGlvbiBpcyBuZXcsIHBsZWFzZSBuYXZpZ2F0ZSB0byB0aGUge0BsaW5rXG4gKiBDb21wb25lbnQjYW5pbWF0aW9ucyBjb21wb25lbnQgYW5pbWF0aW9ucyBtZXRhZGF0YSBwYWdlfSB0byBnYWluIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2ZcbiAqIGhvdyBhbmltYXRpb25zIGluIEFuZ3VsYXIgYXJlIHVzZWQuXG4gKlxuICogYHN0eWxlYCBkZWNsYXJlcyBhIGtleS92YWx1ZSBvYmplY3QgY29udGFpbmluZyBDU1MgcHJvcGVydGllcy9zdHlsZXMgdGhhdCBjYW4gdGhlbiBiZSB1c2VkIGZvclxuICoge0BsaW5rIHN0YXRlIGFuaW1hdGlvbiBzdGF0ZXN9LCB3aXRoaW4gYW4ge0BsaW5rIHNlcXVlbmNlIGFuaW1hdGlvbiBzZXF1ZW5jZX0sIG9yIGFzIHN0eWxpbmcgZGF0YVxuICogZm9yIGJvdGgge0BsaW5rIGFuaW1hdGUgYW5pbWF0ZX0gYW5kIHtAbGluayBrZXlmcmFtZXMga2V5ZnJhbWVzfS5cbiAqXG4gKiAjIyMgVXNhZ2VcbiAqXG4gKiBgc3R5bGVgIHRha2VzIGluIGEga2V5L3ZhbHVlIHN0cmluZyBtYXAgYXMgZGF0YSBhbmQgZXhwZWN0cyBvbmUgb3IgbW9yZSBDU1MgcHJvcGVydHkvdmFsdWUgcGFpcnNcbiAqIHRvIGJlIGRlZmluZWQuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gc3RyaW5nIHZhbHVlcyBhcmUgdXNlZCBmb3IgY3NzIHByb3BlcnRpZXNcbiAqIHN0eWxlKHsgYmFja2dyb3VuZDogXCJyZWRcIiwgY29sb3I6IFwiYmx1ZVwiIH0pXG4gKlxuICogLy8gbnVtZXJpY2FsIChwaXhlbCkgdmFsdWVzIGFyZSBhbHNvIHN1cHBvcnRlZFxuICogc3R5bGUoeyB3aWR0aDogMTAwLCBoZWlnaHQ6IDAgfSlcbiAqIGBgYFxuICpcbiAqICMjIyMgQXV0by1zdHlsZXMgKHVzaW5nIGAqYClcbiAqXG4gKiBXaGVuIGFuIGFzdGVyaXggKGAqYCkgY2hhcmFjdGVyIGlzIHVzZWQgYXMgYSB2YWx1ZSB0aGVuIGl0IHdpbGwgYmUgZGV0ZWN0ZWQgZnJvbSB0aGUgZWxlbWVudFxuICogYmVpbmcgYW5pbWF0ZWQgYW5kIGFwcGxpZWQgYXMgYW5pbWF0aW9uIGRhdGEgd2hlbiB0aGUgYW5pbWF0aW9uIHN0YXJ0cy5cbiAqXG4gKiBUaGlzIGZlYXR1cmUgcHJvdmVzIHVzZWZ1bCBmb3IgYSBzdGF0ZSBkZXBlbmRpbmcgb24gbGF5b3V0IGFuZC9vciBlbnZpcm9ubWVudCBmYWN0b3JzOyBpbiBzdWNoXG4gKiBjYXNlcyB0aGUgc3R5bGVzIGFyZSBjYWxjdWxhdGVkIGp1c3QgYmVmb3JlIHRoZSBhbmltYXRpb24gc3RhcnRzLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHRoZSBzdGVwcyBiZWxvdyB3aWxsIGFuaW1hdGUgZnJvbSAwIHRvIHRoZVxuICogLy8gYWN0dWFsIGhlaWdodCBvZiB0aGUgZWxlbWVudFxuICogc3R5bGUoeyBoZWlnaHQ6IDAgfSksXG4gKiBhbmltYXRlKFwiMXNcIiwgc3R5bGUoeyBoZWlnaHQ6IFwiKlwiIH0pKVxuICogYGBgXG4gKlxuICoge0BleGFtcGxlIGNvcmUvYW5pbWF0aW9uL3RzL2RzbC9hbmltYXRpb25fZXhhbXBsZS50cyByZWdpb249J0NvbXBvbmVudCd9XG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHlsZShcbiAgICB0b2tlbnM6ICcqJyB8IHtba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJ9IHxcbiAgICBBcnJheTwnKid8e1trZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlcn0+KTogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlN0eWxlLCBzdHlsZXM6IHRva2Vucywgb2Zmc2V0OiBudWxsfTtcbn1cblxuLyoqXG4gKiBgc3RhdGVgIGlzIGFuIGFuaW1hdGlvbi1zcGVjaWZpYyBmdW5jdGlvbiB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIEFuZ3VsYXInc1xuICogYW5pbWF0aW9uIERTTCBsYW5ndWFnZS4gSWYgdGhpcyBpbmZvcm1hdGlvbiBpcyBuZXcsIHBsZWFzZSBuYXZpZ2F0ZSB0byB0aGUge0BsaW5rXG4gKiBDb21wb25lbnQjYW5pbWF0aW9ucyBjb21wb25lbnQgYW5pbWF0aW9ucyBtZXRhZGF0YSBwYWdlfSB0byBnYWluIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2ZcbiAqIGhvdyBhbmltYXRpb25zIGluIEFuZ3VsYXIgYXJlIHVzZWQuXG4gKlxuICogYHN0YXRlYCBkZWNsYXJlcyBhbiBhbmltYXRpb24gc3RhdGUgd2l0aGluIHRoZSBnaXZlbiB0cmlnZ2VyLiBXaGVuIGEgc3RhdGUgaXMgYWN0aXZlIHdpdGhpbiBhXG4gKiBjb21wb25lbnQgdGhlbiBpdHMgYXNzb2NpYXRlZCBzdHlsZXMgd2lsbCBwZXJzaXN0IG9uIHRoZSBlbGVtZW50IHRoYXQgdGhlIHRyaWdnZXIgaXMgYXR0YWNoZWQgdG9cbiAqIChldmVuIHdoZW4gdGhlIGFuaW1hdGlvbiBlbmRzKS5cbiAqXG4gKiBUbyBhbmltYXRlIGJldHdlZW4gc3RhdGVzLCBoYXZlIGEgbG9vayBhdCB0aGUgYW5pbWF0aW9uIHtAbGluayB0cmFuc2l0aW9uIHRyYW5zaXRpb259IERTTFxuICogZnVuY3Rpb24uIFRvIHJlZ2lzdGVyIHN0YXRlcyB0byBhbiBhbmltYXRpb24gdHJpZ2dlciBwbGVhc2UgaGF2ZSBhIGxvb2sgYXQgdGhlIHtAbGluayB0cmlnZ2VyXG4gKiB0cmlnZ2VyfSBmdW5jdGlvbi5cbiAqXG4gKiAjIyMjIFRoZSBgdm9pZGAgc3RhdGVcbiAqXG4gKiBUaGUgYHZvaWRgIHN0YXRlIHZhbHVlIGlzIGEgcmVzZXJ2ZWQgd29yZCB0aGF0IGFuZ3VsYXIgdXNlcyB0byBkZXRlcm1pbmUgd2hlbiB0aGUgZWxlbWVudCBpcyBub3RcbiAqIGFwYXJ0IG9mIHRoZSBhcHBsaWNhdGlvbiBhbnltb3JlIChlLmcuIHdoZW4gYW4gYG5nSWZgIGV2YWx1YXRlcyB0byBmYWxzZSB0aGVuIHRoZSBzdGF0ZSBvZiB0aGVcbiAqIGFzc29jaWF0ZWQgZWxlbWVudCBpcyB2b2lkKS5cbiAqXG4gKiAjIyMjIFRoZSBgKmAgKGRlZmF1bHQpIHN0YXRlXG4gKlxuICogVGhlIGAqYCBzdGF0ZSAod2hlbiBzdHlsZWQpIGlzIGEgZmFsbGJhY2sgc3RhdGUgdGhhdCB3aWxsIGJlIHVzZWQgaWYgdGhlIHN0YXRlIHRoYXQgaXMgYmVpbmdcbiAqIGFuaW1hdGVkIGlzIG5vdCBkZWNsYXJlZCB3aXRoaW4gdGhlIHRyaWdnZXIuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogYHN0YXRlYCB3aWxsIGRlY2xhcmUgYW4gYW5pbWF0aW9uIHN0YXRlIHdpdGggaXRzIGFzc29jaWF0ZWQgc3R5bGVzXG4gKiB3aXRoaW4gdGhlIGdpdmVuIHRyaWdnZXIuXG4gKlxuICogLSBgc3RhdGVOYW1lRXhwcmAgY2FuIGJlIG9uZSBvciBtb3JlIHN0YXRlIG5hbWVzIHNlcGFyYXRlZCBieSBjb21tYXMuXG4gKiAtIGBzdHlsZXNgIHJlZmVycyB0byB0aGUge0BsaW5rIHN0eWxlIHN0eWxpbmcgZGF0YX0gdGhhdCB3aWxsIGJlIHBlcnNpc3RlZCBvbiB0aGUgZWxlbWVudCBvbmNlXG4gKiB0aGUgc3RhdGUgaGFzIGJlZW4gcmVhY2hlZC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBcInZvaWRcIiBpcyBhIHJlc2VydmVkIG5hbWUgZm9yIGEgc3RhdGUgYW5kIGlzIHVzZWQgdG8gcmVwcmVzZW50XG4gKiAvLyB0aGUgc3RhdGUgaW4gd2hpY2ggYW4gZWxlbWVudCBpcyBkZXRhY2hlZCBmcm9tIGZyb20gdGhlIGFwcGxpY2F0aW9uLlxuICogc3RhdGUoXCJ2b2lkXCIsIHN0eWxlKHsgaGVpZ2h0OiAwIH0pKVxuICpcbiAqIC8vIHVzZXItZGVmaW5lZCBzdGF0ZXNcbiAqIHN0YXRlKFwiY2xvc2VkXCIsIHN0eWxlKHsgaGVpZ2h0OiAwIH0pKVxuICogc3RhdGUoXCJvcGVuLCB2aXNpYmxlXCIsIHN0eWxlKHsgaGVpZ2h0OiBcIipcIiB9KSlcbiAqIGBgYFxuICpcbiAqIHtAZXhhbXBsZSBjb3JlL2FuaW1hdGlvbi90cy9kc2wvYW5pbWF0aW9uX2V4YW1wbGUudHMgcmVnaW9uPSdDb21wb25lbnQnfVxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhdGUoXG4gICAgbmFtZTogc3RyaW5nLCBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGEsXG4gICAgb3B0aW9ucz86IHtwYXJhbXM6IHtbbmFtZTogc3RyaW5nXTogYW55fX0pOiBBbmltYXRpb25TdGF0ZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU3RhdGUsIG5hbWUsIHN0eWxlcywgb3B0aW9uc307XG59XG5cbi8qKlxuICogYGtleWZyYW1lc2AgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJZiB0aGlzIGluZm9ybWF0aW9uIGlzIG5ldywgcGxlYXNlIG5hdmlnYXRlIHRvIHRoZSB7QGxpbmtcbiAqIENvbXBvbmVudCNhbmltYXRpb25zIGNvbXBvbmVudCBhbmltYXRpb25zIG1ldGFkYXRhIHBhZ2V9IHRvIGdhaW4gYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZlxuICogaG93IGFuaW1hdGlvbnMgaW4gQW5ndWxhciBhcmUgdXNlZC5cbiAqXG4gKiBga2V5ZnJhbWVzYCBzcGVjaWZpZXMgYSBjb2xsZWN0aW9uIG9mIHtAbGluayBzdHlsZSBzdHlsZX0gZW50cmllcyBlYWNoIG9wdGlvbmFsbHkgY2hhcmFjdGVyaXplZFxuICogYnkgYW4gYG9mZnNldGAgdmFsdWUuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogVGhlIGBrZXlmcmFtZXNgIGFuaW1hdGlvbiBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGFsb25nc2lkZSB0aGUge0BsaW5rIGFuaW1hdGUgYW5pbWF0ZX1cbiAqIGFuaW1hdGlvbiBmdW5jdGlvbi4gSW5zdGVhZCBvZiBhcHBseWluZyBhbmltYXRpb25zIGZyb20gd2hlcmUgdGhleSBhcmUgY3VycmVudGx5IHRvIHRoZWlyXG4gKiBkZXN0aW5hdGlvbiwga2V5ZnJhbWVzIGNhbiBkZXNjcmliZSBob3cgZWFjaCBzdHlsZSBlbnRyeSBpcyBhcHBsaWVkIGFuZCBhdCB3aGF0IHBvaW50IHdpdGhpbiB0aGVcbiAqIGFuaW1hdGlvbiBhcmMgKG11Y2ggbGlrZSBDU1MgS2V5ZnJhbWUgQW5pbWF0aW9ucyBkbykuXG4gKlxuICogRm9yIGVhY2ggYHN0eWxlKClgIGVudHJ5IGFuIGBvZmZzZXRgIHZhbHVlIGNhbiBiZSBzZXQuIERvaW5nIHNvIGFsbG93cyB0byBzcGVjaWZ5IGF0IHdoYXRcbiAqIHBlcmNlbnRhZ2Ugb2YgdGhlIGFuaW1hdGUgdGltZSB0aGUgc3R5bGVzIHdpbGwgYmUgYXBwbGllZC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyB0aGUgcHJvdmlkZWQgb2Zmc2V0IHZhbHVlcyBkZXNjcmliZSB3aGVuIGVhY2ggYmFja2dyb3VuZENvbG9yIHZhbHVlIGlzIGFwcGxpZWQuXG4gKiBhbmltYXRlKFwiNXNcIiwga2V5ZnJhbWVzKFtcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwicmVkXCIsIG9mZnNldDogMCB9KSxcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwiYmx1ZVwiLCBvZmZzZXQ6IDAuMiB9KSxcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwib3JhbmdlXCIsIG9mZnNldDogMC4zIH0pLFxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJibGFja1wiLCBvZmZzZXQ6IDEgfSlcbiAqIF0pKVxuICogYGBgXG4gKlxuICogQWx0ZXJuYXRpdmVseSwgaWYgdGhlcmUgYXJlIG5vIGBvZmZzZXRgIHZhbHVlcyB1c2VkIHdpdGhpbiB0aGUgc3R5bGUgZW50cmllcyB0aGVuIHRoZSBvZmZzZXRzXG4gKiB3aWxsIGJlIGNhbGN1bGF0ZWQgYXV0b21hdGljYWxseS5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBhbmltYXRlKFwiNXNcIiwga2V5ZnJhbWVzKFtcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwicmVkXCIgfSkgLy8gb2Zmc2V0ID0gMFxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJibHVlXCIgfSkgLy8gb2Zmc2V0ID0gMC4zM1xuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJvcmFuZ2VcIiB9KSAvLyBvZmZzZXQgPSAwLjY2XG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcImJsYWNrXCIgfSkgLy8gb2Zmc2V0ID0gMVxuICogXSkpXG4gKiBgYGBcbiAqXG4gKiB7QGV4YW1wbGUgY29yZS9hbmltYXRpb24vdHMvZHNsL2FuaW1hdGlvbl9leGFtcGxlLnRzIHJlZ2lvbj0nQ29tcG9uZW50J31cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGtleWZyYW1lcyhzdGVwczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YVtdKTogQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLktleWZyYW1lcywgc3RlcHN9O1xufVxuXG4vKipcbiAqIGB0cmFuc2l0aW9uYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIElmIHRoaXMgaW5mb3JtYXRpb24gaXMgbmV3LCBwbGVhc2UgbmF2aWdhdGUgdG8gdGhlIHtAbGlua1xuICogQ29tcG9uZW50I2FuaW1hdGlvbnMgY29tcG9uZW50IGFuaW1hdGlvbnMgbWV0YWRhdGEgcGFnZX0gdG8gZ2FpbiBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mXG4gKiBob3cgYW5pbWF0aW9ucyBpbiBBbmd1bGFyIGFyZSB1c2VkLlxuICpcbiAqIGB0cmFuc2l0aW9uYCBkZWNsYXJlcyB0aGUge0BsaW5rIHNlcXVlbmNlIHNlcXVlbmNlIG9mIGFuaW1hdGlvbiBzdGVwc30gdGhhdCB3aWxsIGJlIHJ1biB3aGVuIHRoZVxuICogcHJvdmlkZWQgYHN0YXRlQ2hhbmdlRXhwcmAgdmFsdWUgaXMgc2F0aXNmaWVkLiBUaGUgYHN0YXRlQ2hhbmdlRXhwcmAgY29uc2lzdHMgb2YgYSBgc3RhdGUxID0+XG4gKiBzdGF0ZTJgIHdoaWNoIGNvbnNpc3RzIG9mIHR3byBrbm93biBzdGF0ZXMgKHVzZSBhbiBhc3Rlcml4IChgKmApIHRvIHJlZmVyIHRvIGEgZHluYW1pYyBzdGFydGluZ1xuICogYW5kL29yIGVuZGluZyBzdGF0ZSkuXG4gKlxuICogQSBmdW5jdGlvbiBjYW4gYWxzbyBiZSBwcm92aWRlZCBhcyB0aGUgYHN0YXRlQ2hhbmdlRXhwcmAgYXJndW1lbnQgZm9yIGEgdHJhbnNpdGlvbiBhbmQgdGhpc1xuICogZnVuY3Rpb24gd2lsbCBiZSBleGVjdXRlZCBlYWNoIHRpbWUgYSBzdGF0ZSBjaGFuZ2Ugb2NjdXJzLiBJZiB0aGUgdmFsdWUgcmV0dXJuZWQgd2l0aGluIHRoZVxuICogZnVuY3Rpb24gaXMgdHJ1ZSB0aGVuIHRoZSBhc3NvY2lhdGVkIGFuaW1hdGlvbiB3aWxsIGJlIHJ1bi5cbiAqXG4gKiBBbmltYXRpb24gdHJhbnNpdGlvbnMgYXJlIHBsYWNlZCB3aXRoaW4gYW4ge0BsaW5rIHRyaWdnZXIgYW5pbWF0aW9uIHRyaWdnZXJ9LiBGb3IgYW4gdHJhbnNpdGlvblxuICogdG8gYW5pbWF0ZSB0byBhIHN0YXRlIHZhbHVlIGFuZCBwZXJzaXN0IGl0cyBzdHlsZXMgdGhlbiBvbmUgb3IgbW9yZSB7QGxpbmsgc3RhdGUgYW5pbWF0aW9uXG4gKiBzdGF0ZXN9IGlzIGV4cGVjdGVkIHRvIGJlIGRlZmluZWQuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogQW4gYW5pbWF0aW9uIHRyYW5zaXRpb24gaXMga2lja2VkIG9mZiB0aGUgYHN0YXRlQ2hhbmdlRXhwcmAgcHJlZGljYXRlIGV2YWx1YXRlcyB0byB0cnVlIGJhc2VkIG9uXG4gKiB3aGF0IHRoZSBwcmV2aW91cyBzdGF0ZSBpcyBhbmQgd2hhdCB0aGUgY3VycmVudCBzdGF0ZSBoYXMgYmVjb21lLiBJbiBvdGhlciB3b3JkcywgaWYgYSB0cmFuc2l0aW9uXG4gKiBpcyBkZWZpbmVkIHRoYXQgbWF0Y2hlcyB0aGUgb2xkL2N1cnJlbnQgc3RhdGUgY3JpdGVyaWEgdGhlbiB0aGUgYXNzb2NpYXRlZCBhbmltYXRpb24gd2lsbCBiZVxuICogdHJpZ2dlcmVkLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIGFsbCB0cmFuc2l0aW9uL3N0YXRlIGNoYW5nZXMgYXJlIGRlZmluZWQgd2l0aGluIGFuIGFuaW1hdGlvbiB0cmlnZ2VyXG4gKiB0cmlnZ2VyKFwibXlBbmltYXRpb25UcmlnZ2VyXCIsIFtcbiAqICAgLy8gaWYgYSBzdGF0ZSBpcyBkZWZpbmVkIHRoZW4gaXRzIHN0eWxlcyB3aWxsIGJlIHBlcnNpc3RlZCB3aGVuIHRoZVxuICogICAvLyBhbmltYXRpb24gaGFzIGZ1bGx5IGNvbXBsZXRlZCBpdHNlbGZcbiAqICAgc3RhdGUoXCJvblwiLCBzdHlsZSh7IGJhY2tncm91bmQ6IFwiZ3JlZW5cIiB9KSksXG4gKiAgIHN0YXRlKFwib2ZmXCIsIHN0eWxlKHsgYmFja2dyb3VuZDogXCJncmV5XCIgfSkpLFxuICpcbiAqICAgLy8gYSB0cmFuc2l0aW9uIGFuaW1hdGlvbiB0aGF0IHdpbGwgYmUga2lja2VkIG9mZiB3aGVuIHRoZSBzdGF0ZSB2YWx1ZVxuICogICAvLyBib3VuZCB0byBcIm15QW5pbWF0aW9uVHJpZ2dlclwiIGNoYW5nZXMgZnJvbSBcIm9uXCIgdG8gXCJvZmZcIlxuICogICB0cmFuc2l0aW9uKFwib24gPT4gb2ZmXCIsIGFuaW1hdGUoNTAwKSksXG4gKlxuICogICAvLyBpdCBpcyBhbHNvIHBvc3NpYmxlIHRvIGRvIHJ1biB0aGUgc2FtZSBhbmltYXRpb24gZm9yIGJvdGggZGlyZWN0aW9uc1xuICogICB0cmFuc2l0aW9uKFwib24gPD0+IG9mZlwiLCBhbmltYXRlKDUwMCkpLFxuICpcbiAqICAgLy8gb3IgdG8gZGVmaW5lIG11bHRpcGxlIHN0YXRlcyBwYWlycyBzZXBhcmF0ZWQgYnkgY29tbWFzXG4gKiAgIHRyYW5zaXRpb24oXCJvbiA9PiBvZmYsIG9mZiA9PiB2b2lkXCIsIGFuaW1hdGUoNTAwKSksXG4gKlxuICogICAvLyB0aGlzIGlzIGEgY2F0Y2gtYWxsIHN0YXRlIGNoYW5nZSBmb3Igd2hlbiBhbiBlbGVtZW50IGlzIGluc2VydGVkIGludG9cbiAqICAgLy8gdGhlIHBhZ2UgYW5kIHRoZSBkZXN0aW5hdGlvbiBzdGF0ZSBpcyB1bmtub3duXG4gKiAgIHRyYW5zaXRpb24oXCJ2b2lkID0+ICpcIiwgW1xuICogICAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICAgICBhbmltYXRlKDUwMClcbiAqICAgXSksXG4gKlxuICogICAvLyB0aGlzIHdpbGwgY2FwdHVyZSBhIHN0YXRlIGNoYW5nZSBiZXR3ZWVuIGFueSBzdGF0ZXNcbiAqICAgdHJhbnNpdGlvbihcIiogPT4gKlwiLCBhbmltYXRlKFwiMXMgMHNcIikpLFxuICpcbiAqICAgLy8geW91IGNhbiBhbHNvIGdvIGZ1bGwgb3V0IGFuZCBpbmNsdWRlIGEgZnVuY3Rpb25cbiAqICAgdHJhbnNpdGlvbigoZnJvbVN0YXRlLCB0b1N0YXRlKSA9PiB7XG4gKiAgICAgLy8gd2hlbiBgdHJ1ZWAgdGhlbiBpdCB3aWxsIGFsbG93IHRoZSBhbmltYXRpb24gYmVsb3cgdG8gYmUgaW52b2tlZFxuICogICAgIHJldHVybiBmcm9tU3RhdGUgPT0gXCJvZmZcIiAmJiB0b1N0YXRlID09IFwib25cIjtcbiAqICAgfSwgYW5pbWF0ZShcIjFzIDBzXCIpKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIFRoZSB0ZW1wbGF0ZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb21wb25lbnQgd2lsbCBtYWtlIHVzZSBvZiB0aGUgYG15QW5pbWF0aW9uVHJpZ2dlcmAgYW5pbWF0aW9uXG4gKiB0cmlnZ2VyIGJ5IGJpbmRpbmcgdG8gYW4gZWxlbWVudCB3aXRoaW4gaXRzIHRlbXBsYXRlIGNvZGUuXG4gKlxuICogYGBgaHRtbFxuICogPCEtLSBzb21ld2hlcmUgaW5zaWRlIG9mIG15LWNvbXBvbmVudC10cGwuaHRtbCAtLT5cbiAqIDxkaXYgW0BteUFuaW1hdGlvblRyaWdnZXJdPVwibXlTdGF0dXNFeHBcIj4uLi48L2Rpdj5cbiAqIGBgYFxuICpcbiAqICMjIyMgVGhlIGZpbmFsIGBhbmltYXRlYCBjYWxsXG4gKlxuICogSWYgdGhlIGZpbmFsIHN0ZXAgd2l0aGluIHRoZSB0cmFuc2l0aW9uIHN0ZXBzIGlzIGEgY2FsbCB0byBgYW5pbWF0ZSgpYCB0aGF0ICoqb25seSoqIHVzZXMgYVxuICogdGltaW5nIHZhbHVlIHdpdGggKipubyBzdHlsZSBkYXRhKiogdGhlbiBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXNlZCBhcyB0aGUgZmluYWwgYW5pbWF0aW9uIGFyY1xuICogZm9yIHRoZSBlbGVtZW50IHRvIGFuaW1hdGUgaXRzZWxmIHRvIHRoZSBmaW5hbCBzdGF0ZS4gVGhpcyBpbnZvbHZlcyBhbiBhdXRvbWF0aWMgbWl4IG9mXG4gKiBhZGRpbmcvcmVtb3ZpbmcgQ1NTIHN0eWxlcyBzbyB0aGF0IHRoZSBlbGVtZW50IHdpbGwgYmUgaW4gdGhlIGV4YWN0IHN0YXRlIGl0IHNob3VsZCBiZSBmb3IgdGhlXG4gKiBhcHBsaWVkIHN0YXRlIHRvIGJlIHByZXNlbnRlZCBjb3JyZWN0bHkuXG4gKlxuICogYGBgXG4gKiAvLyBzdGFydCBvZmYgYnkgaGlkaW5nIHRoZSBlbGVtZW50LCBidXQgbWFrZSBzdXJlIHRoYXQgaXQgYW5pbWF0ZXMgcHJvcGVybHkgdG8gd2hhdGV2ZXIgc3RhdGVcbiAqIC8vIGlzIGN1cnJlbnRseSBhY3RpdmUgZm9yIFwibXlBbmltYXRpb25UcmlnZ2VyXCJcbiAqIHRyYW5zaXRpb24oXCJ2b2lkID0+ICpcIiwgW1xuICogICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgIGFuaW1hdGUoNTAwKVxuICogXSlcbiAqIGBgYFxuICpcbiAqICMjIyBVc2luZyA6ZW50ZXIgYW5kIDpsZWF2ZVxuICpcbiAqIEdpdmVuIHRoYXQgZW50ZXIgKGluc2VydGlvbikgYW5kIGxlYXZlIChyZW1vdmFsKSBhbmltYXRpb25zIGFyZSBzbyBjb21tb24sIHRoZSBgdHJhbnNpdGlvbmBcbiAqIGZ1bmN0aW9uIGFjY2VwdHMgYm90aCBgOmVudGVyYCBhbmQgYDpsZWF2ZWAgdmFsdWVzIHdoaWNoIGFyZSBhbGlhc2VzIGZvciB0aGUgYHZvaWQgPT4gKmAgYW5kIGAqXG4gKiA9PiB2b2lkYCBzdGF0ZSBjaGFuZ2VzLlxuICpcbiAqIGBgYFxuICogdHJhbnNpdGlvbihcIjplbnRlclwiLCBbXG4gKiAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICAgYW5pbWF0ZSg1MDAsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSlcbiAqIF0pLFxuICogdHJhbnNpdGlvbihcIjpsZWF2ZVwiLCBbXG4gKiAgIGFuaW1hdGUoNTAwLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpXG4gKiBdKVxuICogYGBgXG4gKlxuICogIyMjIEJvb2xlYW4gdmFsdWVzXG4gKiBpZiBhIHRyaWdnZXIgYmluZGluZyB2YWx1ZSBpcyBhIGJvb2xlYW4gdmFsdWUgdGhlbiBpdCBjYW4gYmUgbWF0Y2hlZCB1c2luZyBhIHRyYW5zaXRpb25cbiAqIGV4cHJlc3Npb24gdGhhdCBjb21wYXJlcyBgdHJ1ZWAgYW5kIGBmYWxzZWAgb3IgYDFgIGFuZCBgMGAuXG4gKlxuICogYGBgXG4gKiAvLyBpbiB0aGUgdGVtcGxhdGVcbiAqIDxkaXYgW0BvcGVuQ2xvc2VdPVwib3BlbiA/IHRydWUgOiBmYWxzZVwiPi4uLjwvZGl2PlxuICpcbiAqIC8vIGluIHRoZSBjb21wb25lbnQgbWV0YWRhdGFcbiAqIHRyaWdnZXIoJ29wZW5DbG9zZScsIFtcbiAqICAgc3RhdGUoJ3RydWUnLCBzdHlsZSh7IGhlaWdodDogJyonIH0pKSxcbiAqICAgc3RhdGUoJ2ZhbHNlJywgc3R5bGUoeyBoZWlnaHQ6ICcwcHgnIH0pKSxcbiAqICAgdHJhbnNpdGlvbignZmFsc2UgPD0+IHRydWUnLCBhbmltYXRlKDUwMCkpXG4gKiBdKVxuICogYGBgXG4gKlxuICogIyMjIFVzaW5nIDppbmNyZW1lbnQgYW5kIDpkZWNyZW1lbnRcbiAqIEluIGFkZGl0aW9uIHRvIHRoZSA6ZW50ZXIgYW5kIDpsZWF2ZSB0cmFuc2l0aW9uIGFsaWFzZXMsIHRoZSA6aW5jcmVtZW50IGFuZCA6ZGVjcmVtZW50IGFsaWFzZXNcbiAqIGNhbiBiZSB1c2VkIHRvIGtpY2sgb2ZmIGEgdHJhbnNpdGlvbiB3aGVuIGEgbnVtZXJpYyB2YWx1ZSBoYXMgaW5jcmVhc2VkIG9yIGRlY3JlYXNlZCBpbiB2YWx1ZS5cbiAqXG4gKiBgYGBcbiAqIGltcG9ydCB7Z3JvdXAsIGFuaW1hdGUsIHF1ZXJ5LCB0cmFuc2l0aW9uLCBzdHlsZSwgdHJpZ2dlcn0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG4gKiBpbXBvcnQge0NvbXBvbmVudH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG4gKlxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnYmFubmVyLWNhcm91c2VsLWNvbXBvbmVudCcsXG4gKiAgIHN0eWxlczogW2BcbiAqICAgICAuYmFubmVyLWNvbnRhaW5lciB7XG4gKiAgICAgICAgcG9zaXRpb246cmVsYXRpdmU7XG4gKiAgICAgICAgaGVpZ2h0OjUwMHB4O1xuICogICAgICAgIG92ZXJmbG93OmhpZGRlbjtcbiAqICAgICAgfVxuICogICAgIC5iYW5uZXItY29udGFpbmVyID4gLmJhbm5lciB7XG4gKiAgICAgICAgcG9zaXRpb246YWJzb2x1dGU7XG4gKiAgICAgICAgbGVmdDowO1xuICogICAgICAgIHRvcDowO1xuICogICAgICAgIGZvbnQtc2l6ZToyMDBweDtcbiAqICAgICAgICBsaW5lLWhlaWdodDo1MDBweDtcbiAqICAgICAgICBmb250LXdlaWdodDpib2xkO1xuICogICAgICAgIHRleHQtYWxpZ246Y2VudGVyO1xuICogICAgICAgIHdpZHRoOjEwMCU7XG4gKiAgICAgIH1cbiAqICAgYF0sXG4gKiAgIHRlbXBsYXRlOiBgXG4gKiAgICAgPGJ1dHRvbiAoY2xpY2spPVwicHJldmlvdXMoKVwiPlByZXZpb3VzPC9idXR0b24+XG4gKiAgICAgPGJ1dHRvbiAoY2xpY2spPVwibmV4dCgpXCI+TmV4dDwvYnV0dG9uPlxuICogICAgIDxocj5cbiAqICAgICA8ZGl2IFtAYmFubmVyQW5pbWF0aW9uXT1cInNlbGVjdGVkSW5kZXhcIiBjbGFzcz1cImJhbm5lci1jb250YWluZXJcIj5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJiYW5uZXJcIiAqbmdGb3I9XCJsZXQgYmFubmVyIG9mIGJhbm5lcnNcIj4ge3sgYmFubmVyIH19IDwvZGl2PlxuICogICAgIDwvZGl2PlxuICogICBgLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcignYmFubmVyQW5pbWF0aW9uJywgW1xuICogICAgICAgdHJhbnNpdGlvbihcIjppbmNyZW1lbnRcIiwgZ3JvdXAoW1xuICogICAgICAgICBxdWVyeSgnOmVudGVyJywgW1xuICogICAgICAgICAgIHN0eWxlKHsgbGVmdDogJzEwMCUnIH0pLFxuICogICAgICAgICAgIGFuaW1hdGUoJzAuNXMgZWFzZS1vdXQnLCBzdHlsZSgnKicpKVxuICogICAgICAgICBdKSxcbiAqICAgICAgICAgcXVlcnkoJzpsZWF2ZScsIFtcbiAqICAgICAgICAgICBhbmltYXRlKCcwLjVzIGVhc2Utb3V0Jywgc3R5bGUoeyBsZWZ0OiAnLTEwMCUnIH0pKVxuICogICAgICAgICBdKVxuICogICAgICAgXSkpLFxuICogICAgICAgdHJhbnNpdGlvbihcIjpkZWNyZW1lbnRcIiwgZ3JvdXAoW1xuICogICAgICAgICBxdWVyeSgnOmVudGVyJywgW1xuICogICAgICAgICAgIHN0eWxlKHsgbGVmdDogJy0xMDAlJyB9KSxcbiAqICAgICAgICAgICBhbmltYXRlKCcwLjVzIGVhc2Utb3V0Jywgc3R5bGUoJyonKSlcbiAqICAgICAgICAgXSksXG4gKiAgICAgICAgIHF1ZXJ5KCc6bGVhdmUnLCBbXG4gKiAgICAgICAgICAgYW5pbWF0ZSgnMC41cyBlYXNlLW91dCcsIHN0eWxlKHsgbGVmdDogJzEwMCUnIH0pKVxuICogICAgICAgICBdKVxuICogICAgICAgXSkpXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIEJhbm5lckNhcm91c2VsQ29tcG9uZW50IHtcbiAqICAgYWxsQmFubmVyczogc3RyaW5nW10gPSBbJzEnLCAnMicsICczJywgJzQnXTtcbiAqICAgc2VsZWN0ZWRJbmRleDogbnVtYmVyID0gMDtcbiAqXG4gKiAgIGdldCBiYW5uZXJzKCkge1xuICogICAgICByZXR1cm4gW3RoaXMuYWxsQmFubmVyc1t0aGlzLnNlbGVjdGVkSW5kZXhdXTtcbiAqICAgfVxuICpcbiAqICAgcHJldmlvdXMoKSB7XG4gKiAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gTWF0aC5tYXgodGhpcy5zZWxlY3RlZEluZGV4IC0gMSwgMCk7XG4gKiAgIH1cbiAqXG4gKiAgIG5leHQoKSB7XG4gKiAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gTWF0aC5taW4odGhpcy5zZWxlY3RlZEluZGV4ICsgMSwgdGhpcy5hbGxCYW5uZXJzLmxlbmd0aCAtIDEpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiB7QGV4YW1wbGUgY29yZS9hbmltYXRpb24vdHMvZHNsL2FuaW1hdGlvbl9leGFtcGxlLnRzIHJlZ2lvbj0nQ29tcG9uZW50J31cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zaXRpb24oXG4gICAgc3RhdGVDaGFuZ2VFeHByOiBzdHJpbmcgfCAoKGZyb21TdGF0ZTogc3RyaW5nLCB0b1N0YXRlOiBzdHJpbmcsIGVsZW1lbnQ/OiBhbnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcz86IHtba2V5OiBzdHJpbmddOiBhbnl9KSA9PiBib29sZWFuKSxcbiAgICBzdGVwczogQW5pbWF0aW9uTWV0YWRhdGEgfCBBbmltYXRpb25NZXRhZGF0YVtdLFxuICAgIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsID0gbnVsbCk6IEFuaW1hdGlvblRyYW5zaXRpb25NZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlRyYW5zaXRpb24sIGV4cHI6IHN0YXRlQ2hhbmdlRXhwciwgYW5pbWF0aW9uOiBzdGVwcywgb3B0aW9uc307XG59XG5cbi8qKlxuICogYGFuaW1hdGlvbmAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLlxuICpcbiAqIGB2YXIgbXlBbmltYXRpb24gPSBhbmltYXRpb24oLi4uKWAgaXMgZGVzaWduZWQgdG8gcHJvZHVjZSBhIHJldXNhYmxlIGFuaW1hdGlvbiB0aGF0IGNhbiBiZSBsYXRlclxuICogaW52b2tlZCBpbiBhbm90aGVyIGFuaW1hdGlvbiBvciBzZXF1ZW5jZS4gUmV1c2FibGUgYW5pbWF0aW9ucyBhcmUgZGVzaWduZWQgdG8gbWFrZSB1c2Ugb2ZcbiAqIGFuaW1hdGlvbiBwYXJhbWV0ZXJzIGFuZCB0aGUgcHJvZHVjZWQgYW5pbWF0aW9uIGNhbiBiZSB1c2VkIHZpYSB0aGUgYHVzZUFuaW1hdGlvbmAgbWV0aG9kLlxuICpcbiAqIGBgYFxuICogdmFyIGZhZGVBbmltYXRpb24gPSBhbmltYXRpb24oW1xuICogICBzdHlsZSh7IG9wYWNpdHk6ICd7eyBzdGFydCB9fScgfSksXG4gKiAgIGFuaW1hdGUoJ3t7IHRpbWUgfX0nLFxuICogICAgIHN0eWxlKHsgb3BhY2l0eTogJ3t7IGVuZCB9fSd9KSlcbiAqIF0sIHsgcGFyYW1zOiB7IHRpbWU6ICcxMDAwbXMnLCBzdGFydDogMCwgZW5kOiAxIH19KTtcbiAqIGBgYFxuICpcbiAqIElmIHBhcmFtZXRlcnMgYXJlIGF0dGFjaGVkIHRvIGFuIGFuaW1hdGlvbiB0aGVuIHRoZXkgYWN0IGFzICoqZGVmYXVsdCBwYXJhbWV0ZXIgdmFsdWVzKiouIFdoZW4gYW5cbiAqIGFuaW1hdGlvbiBpcyBpbnZva2VkIHZpYSBgdXNlQW5pbWF0aW9uYCB0aGVuIHBhcmFtZXRlciB2YWx1ZXMgYXJlIGFsbG93ZWQgdG8gYmUgcGFzc2VkIGluXG4gKiBkaXJlY3RseS4gSWYgYW55IG9mIHRoZSBwYXNzZWQgaW4gcGFyYW1ldGVyIHZhbHVlcyBhcmUgbWlzc2luZyB0aGVuIHRoZSBkZWZhdWx0IHZhbHVlcyB3aWxsIGJlXG4gKiB1c2VkLlxuICpcbiAqIGBgYFxuICogdXNlQW5pbWF0aW9uKGZhZGVBbmltYXRpb24sIHtcbiAqICAgcGFyYW1zOiB7XG4gKiAgICAgdGltZTogJzJzJyxcbiAqICAgICBzdGFydDogMSxcbiAqICAgICBlbmQ6IDBcbiAqICAgfVxuICogfSlcbiAqIGBgYFxuICpcbiAqIElmIG9uZSBvciBtb3JlIHBhcmFtZXRlciB2YWx1ZXMgYXJlIG1pc3NpbmcgYmVmb3JlIGFuaW1hdGVkIHRoZW4gYW4gZXJyb3Igd2lsbCBiZSB0aHJvd24uXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmltYXRpb24oXG4gICAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlJlZmVyZW5jZSwgYW5pbWF0aW9uOiBzdGVwcywgb3B0aW9uc307XG59XG5cbi8qKlxuICogYGFuaW1hdGVDaGlsZGAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJdCB3b3JrcyBieSBhbGxvd2luZyBhIHF1ZXJpZWQgZWxlbWVudCB0byBleGVjdXRlIGl0cyBvd25cbiAqIGFuaW1hdGlvbiB3aXRoaW4gdGhlIGFuaW1hdGlvbiBzZXF1ZW5jZS5cbiAqXG4gKiBFYWNoIHRpbWUgYW4gYW5pbWF0aW9uIGlzIHRyaWdnZXJlZCBpbiBhbmd1bGFyLCB0aGUgcGFyZW50IGFuaW1hdGlvblxuICogd2lsbCBhbHdheXMgZ2V0IHByaW9yaXR5IGFuZCBhbnkgY2hpbGQgYW5pbWF0aW9ucyB3aWxsIGJlIGJsb2NrZWQuIEluIG9yZGVyXG4gKiBmb3IgYSBjaGlsZCBhbmltYXRpb24gdG8gcnVuLCB0aGUgcGFyZW50IGFuaW1hdGlvbiBtdXN0IHF1ZXJ5IGVhY2ggb2YgdGhlIGVsZW1lbnRzXG4gKiBjb250YWluaW5nIGNoaWxkIGFuaW1hdGlvbnMgYW5kIHRoZW4gYWxsb3cgdGhlIGFuaW1hdGlvbnMgdG8gcnVuIHVzaW5nIGBhbmltYXRlQ2hpbGRgLlxuICpcbiAqIFRoZSBleGFtcGxlIEhUTUwgY29kZSBiZWxvdyBzaG93cyBib3RoIHBhcmVudCBhbmQgY2hpbGQgZWxlbWVudHMgdGhhdCBoYXZlIGFuaW1hdGlvblxuICogdHJpZ2dlcnMgdGhhdCB3aWxsIGV4ZWN1dGUgYXQgdGhlIHNhbWUgdGltZS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8IS0tIHBhcmVudC1jaGlsZC5jb21wb25lbnQuaHRtbCAtLT5cbiAqIDxidXR0b24gKGNsaWNrKT1cImV4cCA9ISBleHBcIj5Ub2dnbGU8L2J1dHRvbj5cbiAqIDxocj5cbiAqXG4gKiA8ZGl2IFtAcGFyZW50QW5pbWF0aW9uXT1cImV4cFwiPlxuICogICA8aGVhZGVyPkhlbGxvPC9oZWFkZXI+XG4gKiAgIDxkaXYgW0BjaGlsZEFuaW1hdGlvbl09XCJleHBcIj5cbiAqICAgICAgIG9uZVxuICogICA8L2Rpdj5cbiAqICAgPGRpdiBbQGNoaWxkQW5pbWF0aW9uXT1cImV4cFwiPlxuICogICAgICAgdHdvXG4gKiAgIDwvZGl2PlxuICogICA8ZGl2IFtAY2hpbGRBbmltYXRpb25dPVwiZXhwXCI+XG4gKiAgICAgICB0aHJlZVxuICogICA8L2Rpdj5cbiAqIDwvZGl2PlxuICogYGBgXG4gKlxuICogTm93IHdoZW4gdGhlIGBleHBgIHZhbHVlIGNoYW5nZXMgdG8gdHJ1ZSwgb25seSB0aGUgYHBhcmVudEFuaW1hdGlvbmAgYW5pbWF0aW9uIHdpbGwgYW5pbWF0ZVxuICogYmVjYXVzZSBpdCBoYXMgcHJpb3JpdHkuIEhvd2V2ZXIsIHVzaW5nIGBxdWVyeWAgYW5kIGBhbmltYXRlQ2hpbGRgIGVhY2ggb2YgdGhlIGlubmVyIGFuaW1hdGlvbnNcbiAqIGNhbiBhbHNvIGZpcmU6XG4gKlxuICogYGBgdHNcbiAqIC8vIHBhcmVudC1jaGlsZC5jb21wb25lbnQudHNcbiAqIGltcG9ydCB7dHJpZ2dlciwgdHJhbnNpdGlvbiwgYW5pbWF0ZSwgc3R5bGUsIHF1ZXJ5LCBhbmltYXRlQ2hpbGR9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAncGFyZW50LWNoaWxkLWNvbXBvbmVudCcsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKCdwYXJlbnRBbmltYXRpb24nLCBbXG4gKiAgICAgICB0cmFuc2l0aW9uKCdmYWxzZSA9PiB0cnVlJywgW1xuICogICAgICAgICBxdWVyeSgnaGVhZGVyJywgW1xuICogICAgICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICAgICAgICAgICBhbmltYXRlKDUwMCwgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKVxuICogICAgICAgICBdKSxcbiAqICAgICAgICAgcXVlcnkoJ0BjaGlsZEFuaW1hdGlvbicsIFtcbiAqICAgICAgICAgICBhbmltYXRlQ2hpbGQoKVxuICogICAgICAgICBdKVxuICogICAgICAgXSlcbiAqICAgICBdKSxcbiAqICAgICB0cmlnZ2VyKCdjaGlsZEFuaW1hdGlvbicsIFtcbiAqICAgICAgIHRyYW5zaXRpb24oJ2ZhbHNlID0+IHRydWUnLCBbXG4gKiAgICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICAgICAgICAgYW5pbWF0ZSg1MDAsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSlcbiAqICAgICAgIF0pXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIFBhcmVudENoaWxkQ21wIHtcbiAqICAgZXhwOiBib29sZWFuID0gZmFsc2U7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBJbiB0aGUgYW5pbWF0aW9uIGNvZGUgYWJvdmUsIHdoZW4gdGhlIGBwYXJlbnRBbmltYXRpb25gIHRyYW5zaXRpb24ga2lja3Mgb2ZmIGl0IGZpcnN0IHF1ZXJpZXMgdG9cbiAqIGZpbmQgdGhlIGhlYWRlciBlbGVtZW50IGFuZCBmYWRlcyBpdCBpbi4gSXQgdGhlbiBmaW5kcyBlYWNoIG9mIHRoZSBzdWIgZWxlbWVudHMgdGhhdCBjb250YWluIHRoZVxuICogYEBjaGlsZEFuaW1hdGlvbmAgdHJpZ2dlciBhbmQgdGhlbiBhbGxvd3MgZm9yIHRoZWlyIGFuaW1hdGlvbnMgdG8gZmlyZS5cbiAqXG4gKiBUaGlzIGV4YW1wbGUgY2FuIGJlIGZ1cnRoZXIgZXh0ZW5kZWQgYnkgdXNpbmcgc3RhZ2dlcjpcbiAqXG4gKiBgYGB0c1xuICogcXVlcnkoJ0BjaGlsZEFuaW1hdGlvbicsIHN0YWdnZXIoMTAwLCBbXG4gKiAgIGFuaW1hdGVDaGlsZCgpXG4gKiBdKSlcbiAqIGBgYFxuICpcbiAqIE5vdyBlYWNoIG9mIHRoZSBzdWIgYW5pbWF0aW9ucyBzdGFydCBvZmYgd2l0aCByZXNwZWN0IHRvIHRoZSBgMTAwbXNgIHN0YWdnZXJpbmcgc3RlcC5cbiAqXG4gKiAjIyBUaGUgZmlyc3QgZnJhbWUgb2YgY2hpbGQgYW5pbWF0aW9uc1xuICogV2hlbiBzdWIgYW5pbWF0aW9ucyBhcmUgZXhlY3V0ZWQgdXNpbmcgYGFuaW1hdGVDaGlsZGAgdGhlIGFuaW1hdGlvbiBlbmdpbmUgd2lsbCBhbHdheXMgYXBwbHkgdGhlXG4gKiBmaXJzdCBmcmFtZSBvZiBldmVyeSBzdWIgYW5pbWF0aW9uIGltbWVkaWF0ZWx5IGF0IHRoZSBzdGFydCBvZiB0aGUgYW5pbWF0aW9uIHNlcXVlbmNlLiBUaGlzIHdheVxuICogdGhlIHBhcmVudCBhbmltYXRpb24gZG9lcyBub3QgbmVlZCB0byBzZXQgYW55IGluaXRpYWwgc3R5bGluZyBkYXRhIG9uIHRoZSBzdWIgZWxlbWVudHMgYmVmb3JlIHRoZVxuICogc3ViIGFuaW1hdGlvbnMga2ljayBvZmYuXG4gKlxuICogSW4gdGhlIGV4YW1wbGUgYWJvdmUgdGhlIGZpcnN0IGZyYW1lIG9mIHRoZSBgY2hpbGRBbmltYXRpb25gJ3MgYGZhbHNlID0+IHRydWVgIHRyYW5zaXRpb25cbiAqIGNvbnNpc3RzIG9mIGEgc3R5bGUgb2YgYG9wYWNpdHk6IDBgLiBUaGlzIGlzIGFwcGxpZWQgaW1tZWRpYXRlbHkgd2hlbiB0aGUgYHBhcmVudEFuaW1hdGlvbmBcbiAqIGFuaW1hdGlvbiB0cmFuc2l0aW9uIHNlcXVlbmNlIHN0YXJ0cy4gT25seSB0aGVuIHdoZW4gdGhlIGBAY2hpbGRBbmltYXRpb25gIGlzIHF1ZXJpZWQgYW5kIGNhbGxlZFxuICogd2l0aCBgYW5pbWF0ZUNoaWxkYCB3aWxsIGl0IHRoZW4gYW5pbWF0ZSB0byBpdHMgZGVzdGluYXRpb24gb2YgYG9wYWNpdHk6IDFgLlxuICpcbiAqIE5vdGUgdGhhdCB0aGlzIGZlYXR1cmUgZGVzaWduZWQgdG8gYmUgdXNlZCBhbG9uZ3NpZGUge0BsaW5rIHF1ZXJ5IHF1ZXJ5KCl9IGFuZCBpdCB3aWxsIG9ubHkgd29ya1xuICogd2l0aCBhbmltYXRpb25zIHRoYXQgYXJlIGFzc2lnbmVkIHVzaW5nIHRoZSBBbmd1bGFyIGFuaW1hdGlvbiBEU0wgKHRoaXMgbWVhbnMgdGhhdCBDU1Mga2V5ZnJhbWVzXG4gKiBhbmQgdHJhbnNpdGlvbnMgYXJlIG5vdCBoYW5kbGVkIGJ5IHRoaXMgQVBJKS5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuaW1hdGVDaGlsZChvcHRpb25zOiBBbmltYXRlQ2hpbGRPcHRpb25zIHwgbnVsbCA9IG51bGwpOlxuICAgIEFuaW1hdGlvbkFuaW1hdGVDaGlsZE1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuQW5pbWF0ZUNoaWxkLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBgdXNlQW5pbWF0aW9uYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIEl0IGlzIHVzZWQgdG8ga2ljayBvZmYgYSByZXVzYWJsZSBhbmltYXRpb24gdGhhdCBpcyBjcmVhdGVkIHVzaW5nIHtAbGlua1xuICogYW5pbWF0aW9uIGFuaW1hdGlvbigpfS5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZUFuaW1hdGlvbihcbiAgICBhbmltYXRpb246IEFuaW1hdGlvblJlZmVyZW5jZU1ldGFkYXRhLFxuICAgIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsID0gbnVsbCk6IEFuaW1hdGlvbkFuaW1hdGVSZWZNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLkFuaW1hdGVSZWYsIGFuaW1hdGlvbiwgb3B0aW9uc307XG59XG5cbi8qKlxuICogYHF1ZXJ5YCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuXG4gKlxuICogcXVlcnkoKSBpcyB1c2VkIHRvIGZpbmQgb25lIG9yIG1vcmUgaW5uZXIgZWxlbWVudHMgd2l0aGluIHRoZSBjdXJyZW50IGVsZW1lbnQgdGhhdCBpc1xuICogYmVpbmcgYW5pbWF0ZWQgd2l0aGluIHRoZSBzZXF1ZW5jZS4gVGhlIHByb3ZpZGVkIGFuaW1hdGlvbiBzdGVwcyBhcmUgYXBwbGllZFxuICogdG8gdGhlIHF1ZXJpZWQgZWxlbWVudCAoYnkgZGVmYXVsdCwgYW4gYXJyYXkgaXMgcHJvdmlkZWQsIHRoZW4gdGhpcyB3aWxsIGJlXG4gKiB0cmVhdGVkIGFzIGFuIGFuaW1hdGlvbiBzZXF1ZW5jZSkuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogcXVlcnkoKSBpcyBkZXNpZ25lZCB0byBjb2xsZWN0IG11bHRpcGxlIGVsZW1lbnRzIGFuZCB3b3JrcyBpbnRlcm5hbGx5IGJ5IHVzaW5nXG4gKiBgZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsYC4gQW4gYWRkaXRpb25hbCBvcHRpb25zIG9iamVjdCBjYW4gYmUgcHJvdmlkZWQgd2hpY2hcbiAqIGNhbiBiZSB1c2VkIHRvIGxpbWl0IHRoZSB0b3RhbCBhbW91bnQgb2YgaXRlbXMgdG8gYmUgY29sbGVjdGVkLlxuICpcbiAqIGBgYGpzXG4gKiBxdWVyeSgnZGl2JywgW1xuICogICBhbmltYXRlKC4uLiksXG4gKiAgIGFuaW1hdGUoLi4uKVxuICogXSwgeyBsaW1pdDogMSB9KVxuICogYGBgXG4gKlxuICogcXVlcnkoKSwgYnkgZGVmYXVsdCwgd2lsbCB0aHJvdyBhbiBlcnJvciB3aGVuIHplcm8gaXRlbXMgYXJlIGZvdW5kLiBJZiBhIHF1ZXJ5XG4gKiBoYXMgdGhlIGBvcHRpb25hbGAgZmxhZyBzZXQgdG8gdHJ1ZSB0aGVuIHRoaXMgZXJyb3Igd2lsbCBiZSBpZ25vcmVkLlxuICpcbiAqIGBgYGpzXG4gKiBxdWVyeSgnLnNvbWUtZWxlbWVudC10aGF0LW1heS1ub3QtYmUtdGhlcmUnLCBbXG4gKiAgIGFuaW1hdGUoLi4uKSxcbiAqICAgYW5pbWF0ZSguLi4pXG4gKiBdLCB7IG9wdGlvbmFsOiB0cnVlIH0pXG4gKiBgYGBcbiAqXG4gKiAjIyMgU3BlY2lhbCBTZWxlY3RvciBWYWx1ZXNcbiAqXG4gKiBUaGUgc2VsZWN0b3IgdmFsdWUgd2l0aGluIGEgcXVlcnkgY2FuIGNvbGxlY3QgZWxlbWVudHMgdGhhdCBjb250YWluIGFuZ3VsYXItc3BlY2lmaWNcbiAqIGNoYXJhY3RlcmlzdGljc1xuICogdXNpbmcgc3BlY2lhbCBwc2V1ZG8tc2VsZWN0b3JzIHRva2Vucy5cbiAqXG4gKiBUaGVzZSBpbmNsdWRlOlxuICpcbiAqICAtIFF1ZXJ5aW5nIGZvciBuZXdseSBpbnNlcnRlZC9yZW1vdmVkIGVsZW1lbnRzIHVzaW5nIGBxdWVyeShcIjplbnRlclwiKWAvYHF1ZXJ5KFwiOmxlYXZlXCIpYFxuICogIC0gUXVlcnlpbmcgYWxsIGN1cnJlbnRseSBhbmltYXRpbmcgZWxlbWVudHMgdXNpbmcgYHF1ZXJ5KFwiOmFuaW1hdGluZ1wiKWBcbiAqICAtIFF1ZXJ5aW5nIGVsZW1lbnRzIHRoYXQgY29udGFpbiBhbiBhbmltYXRpb24gdHJpZ2dlciB1c2luZyBgcXVlcnkoXCJAdHJpZ2dlck5hbWVcIilgXG4gKiAgLSBRdWVyeWluZyBhbGwgZWxlbWVudHMgdGhhdCBjb250YWluIGFuIGFuaW1hdGlvbiB0cmlnZ2VycyB1c2luZyBgcXVlcnkoXCJAKlwiKWBcbiAqICAtIEluY2x1ZGluZyB0aGUgY3VycmVudCBlbGVtZW50IGludG8gdGhlIGFuaW1hdGlvbiBzZXF1ZW5jZSB1c2luZyBgcXVlcnkoXCI6c2VsZlwiKWBcbiAqXG4gKlxuICogIEVhY2ggb2YgdGhlc2UgcHNldWRvLXNlbGVjdG9yIHRva2VucyBjYW4gYmUgbWVyZ2VkIHRvZ2V0aGVyIGludG8gYSBjb21iaW5lZCBxdWVyeSBzZWxlY3RvclxuICogc3RyaW5nOlxuICpcbiAqICBgYGBcbiAqICBxdWVyeSgnOnNlbGYsIC5yZWNvcmQ6ZW50ZXIsIC5yZWNvcmQ6bGVhdmUsIEBzdWJUcmlnZ2VyJywgWy4uLl0pXG4gKiAgYGBgXG4gKlxuICogIyMjIERlbW9cbiAqXG4gKiBgYGBcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2lubmVyJyxcbiAqICAgdGVtcGxhdGU6IGBcbiAqICAgICA8ZGl2IFtAcXVlcnlBbmltYXRpb25dPVwiZXhwXCI+XG4gKiAgICAgICA8aDE+VGl0bGU8L2gxPlxuICogICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnRcIj5cbiAqICAgICAgICAgQmxhaCBibGFoIGJsYWhcbiAqICAgICAgIDwvZGl2PlxuICogICAgIDwvZGl2PlxuICogICBgLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICB0cmlnZ2VyKCdxdWVyeUFuaW1hdGlvbicsIFtcbiAqICAgICAgdHJhbnNpdGlvbignKiA9PiBnb0FuaW1hdGUnLCBbXG4gKiAgICAgICAgLy8gaGlkZSB0aGUgaW5uZXIgZWxlbWVudHNcbiAqICAgICAgICBxdWVyeSgnaDEnLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpLFxuICogICAgICAgIHF1ZXJ5KCcuY29udGVudCcsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSksXG4gKlxuICogICAgICAgIC8vIGFuaW1hdGUgdGhlIGlubmVyIGVsZW1lbnRzIGluLCBvbmUgYnkgb25lXG4gKiAgICAgICAgcXVlcnkoJ2gxJywgYW5pbWF0ZSgxMDAwLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpLFxuICogICAgICAgIHF1ZXJ5KCcuY29udGVudCcsIGFuaW1hdGUoMTAwMCwgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKSxcbiAqICAgICAgXSlcbiAqICAgIF0pXG4gKiAgXVxuICogfSlcbiAqIGNsYXNzIENtcCB7XG4gKiAgIGV4cCA9ICcnO1xuICpcbiAqICAgZ29BbmltYXRlKCkge1xuICogICAgIHRoaXMuZXhwID0gJ2dvQW5pbWF0ZSc7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcXVlcnkoXG4gICAgc2VsZWN0b3I6IHN0cmluZywgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10sXG4gICAgb3B0aW9uczogQW5pbWF0aW9uUXVlcnlPcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25RdWVyeU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuUXVlcnksIHNlbGVjdG9yLCBhbmltYXRpb24sIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIGBzdGFnZ2VyYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIEl0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIGFuIGFuaW1hdGlvbiB7QGxpbmsgcXVlcnkgcXVlcnkoKX1cbiAqIGFuZCB3b3JrcyBieSBpc3N1aW5nIGEgdGltaW5nIGdhcCBiZXR3ZWVuIGFmdGVyIGVhY2ggcXVlcmllZCBpdGVtIGlzIGFuaW1hdGVkLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIEluIHRoZSBleGFtcGxlIGJlbG93IHRoZXJlIGlzIGEgY29udGFpbmVyIGVsZW1lbnQgdGhhdCB3cmFwcyBhIGxpc3Qgb2YgaXRlbXMgc3RhbXBlZCBvdXRcbiAqIGJ5IGFuIG5nRm9yLiBUaGUgY29udGFpbmVyIGVsZW1lbnQgY29udGFpbnMgYW4gYW5pbWF0aW9uIHRyaWdnZXIgdGhhdCB3aWxsIGxhdGVyIGJlIHNldFxuICogdG8gcXVlcnkgZm9yIGVhY2ggb2YgdGhlIGlubmVyIGl0ZW1zLlxuICpcbiAqIGBgYGh0bWxcbiAqIDwhLS0gbGlzdC5jb21wb25lbnQuaHRtbCAtLT5cbiAqIDxidXR0b24gKGNsaWNrKT1cInRvZ2dsZSgpXCI+U2hvdyAvIEhpZGUgSXRlbXM8L2J1dHRvbj5cbiAqIDxociAvPlxuICogPGRpdiBbQGxpc3RBbmltYXRpb25dPVwiaXRlbXMubGVuZ3RoXCI+XG4gKiAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIj5cbiAqICAgICB7eyBpdGVtIH19XG4gKiAgIDwvZGl2PlxuICogPC9kaXY+XG4gKiBgYGBcbiAqXG4gKiBUaGUgY29tcG9uZW50IGNvZGUgZm9yIHRoaXMgbG9va3MgYXMgc3VjaDpcbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHt0cmlnZ2VyLCB0cmFuc2l0aW9uLCBzdHlsZSwgYW5pbWF0ZSwgcXVlcnksIHN0YWdnZXJ9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuICogQENvbXBvbmVudCh7XG4gKiAgIHRlbXBsYXRlVXJsOiAnbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKCdsaXN0QW5pbWF0aW9uJywgW1xuICogICAgICAgIC8vLi4uXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIExpc3RDb21wb25lbnQge1xuICogICBpdGVtcyA9IFtdO1xuICpcbiAqICAgc2hvd0l0ZW1zKCkge1xuICogICAgIHRoaXMuaXRlbXMgPSBbMCwxLDIsMyw0XTtcbiAqICAgfVxuICpcbiAqICAgaGlkZUl0ZW1zKCkge1xuICogICAgIHRoaXMuaXRlbXMgPSBbXTtcbiAqICAgfVxuICpcbiAqICAgdG9nZ2xlKCkge1xuICogICAgIHRoaXMuaXRlbXMubGVuZ3RoID8gdGhpcy5oaWRlSXRlbXMoKSA6IHRoaXMuc2hvd0l0ZW1zKCk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEFuZCBub3cgZm9yIHRoZSBhbmltYXRpb24gdHJpZ2dlciBjb2RlOlxuICpcbiAqIGBgYHRzXG4gKiB0cmlnZ2VyKCdsaXN0QW5pbWF0aW9uJywgW1xuICogICB0cmFuc2l0aW9uKCcqID0+IConLCBbIC8vIGVhY2ggdGltZSB0aGUgYmluZGluZyB2YWx1ZSBjaGFuZ2VzXG4gKiAgICAgcXVlcnkoJzpsZWF2ZScsIFtcbiAqICAgICAgIHN0YWdnZXIoMTAwLCBbXG4gKiAgICAgICAgIGFuaW1hdGUoJzAuNXMnLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpXG4gKiAgICAgICBdKVxuICogICAgIF0pLFxuICogICAgIHF1ZXJ5KCc6ZW50ZXInLCBbXG4gKiAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgICAgICBzdGFnZ2VyKDEwMCwgW1xuICogICAgICAgICBhbmltYXRlKCcwLjVzJywgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKVxuICogICAgICAgXSlcbiAqICAgICBdKVxuICogICBdKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIE5vdyBlYWNoIHRpbWUgdGhlIGl0ZW1zIGFyZSBhZGRlZC9yZW1vdmVkIHRoZW4gZWl0aGVyIHRoZSBvcGFjaXR5XG4gKiBmYWRlLWluIGFuaW1hdGlvbiB3aWxsIHJ1biBvciBlYWNoIHJlbW92ZWQgaXRlbSB3aWxsIGJlIGZhZGVkIG91dC5cbiAqIFdoZW4gZWl0aGVyIG9mIHRoZXNlIGFuaW1hdGlvbnMgb2NjdXIgdGhlbiBhIHN0YWdnZXIgZWZmZWN0IHdpbGwgYmVcbiAqIGFwcGxpZWQgYWZ0ZXIgZWFjaCBpdGVtJ3MgYW5pbWF0aW9uIGlzIHN0YXJ0ZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFnZ2VyKFxuICAgIHRpbWluZ3M6IHN0cmluZyB8IG51bWJlcixcbiAgICBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSk6IEFuaW1hdGlvblN0YWdnZXJNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlN0YWdnZXIsIHRpbWluZ3MsIGFuaW1hdGlvbn07XG59XG4iXX0=
1181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uX21ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5pbWF0aW9ucy9zcmMvYW5pbWF0aW9uX21ldGFkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTRKQSxNQUFNLENBQUMsdUJBQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNlk5QixNQUFNLGtCQUFrQixJQUFZLEVBQUUsV0FBZ0M7SUFDcEUsTUFBTSxDQUFDLEVBQUMsSUFBSSxpQkFBK0IsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUMsQ0FBQztDQUM5RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMERELE1BQU0sa0JBQ0YsT0FBd0IsRUFBRSxTQUNmLElBQUk7SUFDakIsTUFBTSxDQUFDLEVBQUMsSUFBSSxpQkFBK0IsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFDLENBQUM7Q0FDL0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBaUNELE1BQU0sZ0JBQ0YsS0FBMEIsRUFBRSxVQUFtQyxJQUFJO0lBQ3JFLE1BQU0sQ0FBQyxFQUFDLElBQUksZUFBNkIsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFDLENBQUM7Q0FDNUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWlDRCxNQUFNLG1CQUFtQixLQUEwQixFQUFFLFVBQW1DLElBQUk7SUFFMUYsTUFBTSxDQUFDLEVBQUMsSUFBSSxrQkFBZ0MsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFDLENBQUM7Q0FDL0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3Q0QsTUFBTSxnQkFDRixNQUMyQztJQUM3QyxNQUFNLENBQUMsRUFBQyxJQUFJLGVBQTZCLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUM7Q0FDMUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNkJELE1BQU0sZ0JBQ0YsSUFBWSxFQUFFLE1BQThCLEVBQzVDLE9BQXlDO0lBQzNDLE1BQU0sQ0FBQyxFQUFDLElBQUksZUFBNkIsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQ25FOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTZDRCxNQUFNLG9CQUFvQixLQUErQjtJQUN2RCxNQUFNLENBQUMsRUFBQyxJQUFJLG1CQUFpQyxFQUFFLEtBQUssRUFBQyxDQUFDO0NBQ3ZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3S0QsTUFBTSxxQkFDRixlQUNzRSxFQUN0RSxLQUE4QyxFQUM5QyxVQUFtQyxJQUFJO0lBQ3pDLE1BQU0sQ0FBQyxFQUFDLElBQUksb0JBQWtDLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQ25HOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTZDRCxNQUFNLG9CQUNGLEtBQThDLEVBQzlDLFVBQW1DLElBQUk7SUFDekMsTUFBTSxDQUFDLEVBQUMsSUFBSSxtQkFBaUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQzNFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkQsTUFBTSx1QkFBdUIsVUFBc0MsSUFBSTtJQUVyRSxNQUFNLENBQUMsRUFBQyxJQUFJLHNCQUFvQyxFQUFFLE9BQU8sRUFBQyxDQUFDO0NBQzVEOzs7Ozs7Ozs7QUFVRCxNQUFNLHVCQUNGLFNBQXFDLEVBQ3JDLFVBQW1DLElBQUk7SUFDekMsTUFBTSxDQUFDLEVBQUMsSUFBSSxxQkFBa0MsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFDLENBQUM7Q0FDckU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBdUZELE1BQU0sZ0JBQ0YsUUFBZ0IsRUFBRSxTQUFrRCxFQUNwRSxVQUF3QyxJQUFJO0lBQzlDLE1BQU0sQ0FBQyxFQUFDLElBQUksZ0JBQTZCLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQztDQUMxRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdGRCxNQUFNLGtCQUNGLE9BQXdCLEVBQ3hCLFNBQWtEO0lBQ3BELE1BQU0sQ0FBQyxFQUFDLElBQUksa0JBQStCLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBQyxDQUFDO0NBQ2xFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBzZXQgb2YgQ1NTIHN0eWxlcyBmb3IgdXNlIGluIGFuIGFuaW1hdGlvbiBzdHlsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSDJtVN0eWxlRGF0YSB7IFtrZXk6IHN0cmluZ106IHN0cmluZ3xudW1iZXI7IH1cblxuLyoqXG4qIFJlcHJlc2VudHMgYW5pbWF0aW9uLXN0ZXAgdGltaW5nIHBhcmFtZXRlcnMgZm9yIGFuIGFuaW1hdGlvbiBzdGVwLiAgXG4qIEBzZWUgYGFuaW1hdGUoKWBcbiovXG5leHBvcnQgZGVjbGFyZSB0eXBlIEFuaW1hdGVUaW1pbmdzID0ge1xuICAvKipcbiAgICogVGhlIGZ1bGwgZHVyYXRpb24gb2YgYW4gYW5pbWF0aW9uIHN0ZXAuIEEgbnVtYmVyIGFuZCBvcHRpb25hbCB0aW1lIHVuaXQsXG4gICAqIHN1Y2ggYXMgXCIxc1wiIG9yIFwiMTBtc1wiIGZvciBvbmUgc2Vjb25kIGFuZCAxMCBtaWxsaXNlY29uZHMsIHJlc3BlY3RpdmVseS5cbiAgICogVGhlIGRlZmF1bHQgdW5pdCBpcyBtaWxsaXNlY29uZHMuXG4gICAqL1xuICBkdXJhdGlvbjogbnVtYmVyLFxuICAvKipcbiAgICogVGhlIGRlbGF5IGluIGFwcGx5aW5nIGFuIGFuaW1hdGlvbiBzdGVwLiBBIG51bWJlciBhbmQgb3B0aW9uYWwgdGltZSB1bml0LlxuICAgKiBUaGUgZGVmYXVsdCB1bml0IGlzIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIGRlbGF5OiBudW1iZXIsXG4gIC8qKlxuICAgKiBBbiBlYXNpbmcgc3R5bGUgdGhhdCBjb250cm9scyBob3cgYW4gYW5pbWF0aW9ucyBzdGVwIGFjY2VsZXJhdGVzXG4gICAqIGFuZCBkZWNlbGVyYXRlcyBkdXJpbmcgaXRzIHJ1biB0aW1lLiBBbiBlYXNpbmcgZnVuY3Rpb24gc3VjaCBhcyBgY3ViaWMtYmV6aWVyKClgLFxuICAgKiBvciBvbmUgb2YgdGhlIGZvbGxvd2luZyBjb25zdGFudHM6XG4gICAqIC0gYGVhc2UtaW5gXG4gICAqIC0gYGVhc2Utb3V0YFxuICAgKiAtIGBlYXNlLWluLWFuZC1vdXRgXG4gICAqL1xuICBlYXNpbmc6IHN0cmluZyB8IG51bGxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE9wdGlvbnMgdGhhdCBjb250cm9sIGFuaW1hdGlvbiBzdHlsaW5nIGFuZCB0aW1pbmcuXG4gKlxuICogVGhlIGZvbGxvd2luZyBhbmltYXRpb24gZnVuY3Rpb25zIGFjY2VwdCBgQW5pbWF0aW9uT3B0aW9uc2AgZGF0YTpcbiAqXG4gKiAtIGB0cmFuc2l0aW9uKClgXG4gKiAtIGBzZXF1ZW5jZSgpYFxuICogLSBge0BsaW5rIGFuaW1hdGlvbnMvZ3JvdXAgZ3JvdXAoKX1gXG4gKiAtIGBxdWVyeSgpYFxuICogLSBgYW5pbWF0aW9uKClgXG4gKiAtIGB1c2VBbmltYXRpb24oKWBcbiAqIC0gYGFuaW1hdGVDaGlsZCgpYFxuICpcbiAqIFByb2dyYW1tYXRpYyBhbmltYXRpb25zIGJ1aWx0IHVzaW5nIHRoZSBgQW5pbWF0aW9uQnVpbGRlcmAgc2VydmljZSBhbHNvXG4gKiBtYWtlIHVzZSBvZiBgQW5pbWF0aW9uT3B0aW9uc2AuXG4gKi9cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBBbmltYXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFNldHMgYSB0aW1lLWRlbGF5IGZvciBpbml0aWF0aW5nIGFuIGFuaW1hdGlvbiBhY3Rpb24uXG4gICAqIEEgbnVtYmVyIGFuZCBvcHRpb25hbCB0aW1lIHVuaXQsIHN1Y2ggYXMgXCIxc1wiIG9yIFwiMTBtc1wiIGZvciBvbmUgc2Vjb25kXG4gICAqIGFuZCAxMCBtaWxsaXNlY29uZHMsIHJlc3BlY3RpdmVseS5UaGUgZGVmYXVsdCB1bml0IGlzIG1pbGxpc2Vjb25kcy5cbiAgICogRGVmYXVsdCB2YWx1ZSBpcyAwLCBtZWFuaW5nIG5vIGRlbGF5LlxuICAgKi9cbiAgZGVsYXk/OiBudW1iZXJ8c3RyaW5nO1xuICAvKipcbiAgKiBBIHNldCBvZiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgbW9kaWZ5IHN0eWxpbmcgYW5kIHRpbWluZ1xuICAqIHdoZW4gYW4gYW5pbWF0aW9uIGFjdGlvbiBzdGFydHMuIEFuIGFycmF5IG9mIGtleS12YWx1ZSBwYWlycywgd2hlcmUgdGhlIHByb3ZpZGVkIHZhbHVlXG4gICogaXMgdXNlZCBhcyBhIGRlZmF1bHQuXG4gICovXG4gIHBhcmFtcz86IHtbbmFtZTogc3RyaW5nXTogYW55fTtcbn1cblxuLyoqXG4gKiBBZGRzIGR1cmF0aW9uIG9wdGlvbnMgdG8gY29udHJvbCBhbmltYXRpb24gc3R5bGluZyBhbmQgdGltaW5nIGZvciBhIGNoaWxkIGFuaW1hdGlvbi5cbiAqXG4gKiBAc2VlIGBhbmltYXRlQ2hpbGQoKWBcbiAqL1xuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIEFuaW1hdGVDaGlsZE9wdGlvbnMgZXh0ZW5kcyBBbmltYXRpb25PcHRpb25zIHsgZHVyYXRpb24/OiBudW1iZXJ8c3RyaW5nOyB9XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnN0YW50cyBmb3IgdGhlIGNhdGVnb3JpZXMgb2YgcGFyYW1ldGVycyB0aGF0IGNhbiBiZSBkZWZpbmVkIGZvciBhbmltYXRpb25zLlxuICpcbiAqIEEgY29ycmVzcG9uZGluZyBmdW5jdGlvbiBkZWZpbmVzIGEgc2V0IG9mIHBhcmFtZXRlcnMgZm9yIGVhY2ggY2F0ZWdvcnksIGFuZFxuICogY29sbGVjdHMgdGhlbSBpbnRvIGEgY29ycmVzcG9uZGluZyBgQW5pbWF0aW9uTWV0YWRhdGFgIG9iamVjdC5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gQW5pbWF0aW9uTWV0YWRhdGFUeXBlIHtcbiAgLyoqXG4gICAqIEFzc29jaWF0ZXMgYSBuYW1lZCBhbmltYXRpb24gc3RhdGUgd2l0aCBhIHNldCBvZiBDU1Mgc3R5bGVzLlxuICAgKiBTZWUgYHN0YXRlKClgXG4gICAqL1xuICBTdGF0ZSA9IDAsXG4gIC8qKlxuICAgKiBEYXRhIGZvciBhIHRyYW5zaXRpb24gZnJvbSBvbmUgYW5pbWF0aW9uIHN0YXRlIHRvIGFub3RoZXIuXG4gICAqIFNlZSBgdHJhbnNpdGlvbigpYFxuICAgKi9cbiAgVHJhbnNpdGlvbiA9IDEsXG4gIC8qKlxuICAgKiBDb250YWlucyBhIHNldCBvZiBhbmltYXRpb24gc3RlcHMuXG4gICAqIFNlZSBgc2VxdWVuY2UoKWBcbiAgICovXG4gIFNlcXVlbmNlID0gMixcbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgc2V0IG9mIGFuaW1hdGlvbiBzdGVwcy5cbiAgICogU2VlIGB7QGxpbmsgYW5pbWF0aW9ucy9ncm91cCBncm91cCgpfWBcbiAgICovXG4gIEdyb3VwID0gMyxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGFuIGFuaW1hdGlvbiBzdGVwLlxuICAgKiBTZWUgYGFuaW1hdGUoKWBcbiAgICovXG4gIEFuaW1hdGUgPSA0LFxuICAvKipcbiAgICogQ29udGFpbnMgYSBzZXQgb2YgYW5pbWF0aW9uIHN0ZXBzLlxuICAgKiBTZWUgYGtleWZyYW1lcygpYFxuICAgKi9cbiAgS2V5ZnJhbWVzID0gNSxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgc2V0IG9mIENTUyBwcm9wZXJ0eS12YWx1ZSBwYWlycyBpbnRvIGEgbmFtZWQgc3R5bGUuXG4gICAqIFNlZSBgc3R5bGUoKWBcbiAgICovXG4gIFN0eWxlID0gNixcbiAgLyoqXG4gICAqIEFzc29jaWF0ZXMgYW4gYW5pbWF0aW9uIHdpdGggYW4gZW50cnkgdHJpZ2dlciB0aGF0IGNhbiBiZSBhdHRhY2hlZCB0byBhbiBlbGVtZW50LlxuICAgKiBTZWUgYHRyaWdnZXIoKWBcbiAgICovXG4gIFRyaWdnZXIgPSA3LFxuICAvKipcbiAgICogQ29udGFpbnMgYSByZS11c2FibGUgYW5pbWF0aW9uLlxuICAgKiBTZWUgYGFuaW1hdGlvbigpYFxuICAgKi9cbiAgUmVmZXJlbmNlID0gOCxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGRhdGEgdG8gdXNlIGluIGV4ZWN1dGluZyBjaGlsZCBhbmltYXRpb25zIHJldHVybmVkIGJ5IGEgcXVlcnkuXG4gICAqIFNlZSBgYW5pbWF0ZUNoaWxkKClgXG4gICAqL1xuICBBbmltYXRlQ2hpbGQgPSA5LFxuICAvKipcbiAgICogQ29udGFpbnMgYW5pbWF0aW9uIHBhcmFtZXRlcnMgZm9yIGEgcmUtdXNhYmxlIGFuaW1hdGlvbi5cbiAgICogU2VlIGB1c2VBbmltYXRpb24oKWBcbiAgICovXG4gIEFuaW1hdGVSZWYgPSAxMCxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGNoaWxkLWFuaW1hdGlvbiBxdWVyeSBkYXRhLlxuICAgKiBTZWUgYHF1ZXJ5KClgXG4gICAqL1xuICBRdWVyeSA9IDExLFxuICAvKipcbiAgICogQ29udGFpbnMgZGF0YSBmb3Igc3RhZ2dlcmluZyBhbiBhbmltYXRpb24gc2VxdWVuY2UuXG4gICAqIFNlZSBgc3RhZ2dlcigpYFxuICAgKi9cbiAgU3RhZ2dlciA9IDEyXG59XG5cbi8qKlxuICogU3BlY2lmaWVzIGF1dG9tYXRpYyBzdHlsaW5nLlxuICovXG5leHBvcnQgY29uc3QgQVVUT19TVFlMRSA9ICcqJztcblxuLyoqXG4gKiBCYXNlIGZvciBhbmltYXRpb24gZGF0YSBzdHJ1Y3R1cmVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbk1ldGFkYXRhIHsgdHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlOyB9XG5cbi8qKlxuICogQ29udGFpbnMgYW4gYW5pbWF0aW9uIHRyaWdnZXIuIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnkgdGhlXG4gKiBgdHJpZ2dlcigpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25UcmlnZ2VyTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgICogVGhlIHRyaWdnZXIgbmFtZSwgdXNlZCB0byBhc3NvY2lhdGUgaXQgd2l0aCBhbiBlbGVtZW50LiBVbmlxdWUgd2l0aGluIHRoZSBjb21wb25lbnQuXG4gICAgKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogQW4gYW5pbWF0aW9uIGRlZmluaXRpb24gb2JqZWN0LCBjb250YWluaW5nIGFuIGFycmF5IG9mIHN0YXRlIGFuZCB0cmFuc2l0aW9uIGRlY2xhcmF0aW9ucy5cbiAgICovXG4gIGRlZmluaXRpb25zOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiB7cGFyYW1zPzoge1tuYW1lOiBzdHJpbmddOiBhbnl9fXxudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhbiBhbmltYXRpb24gc3RhdGUgYnkgYXNzb2NpYXRpbmcgYSBzdGF0ZSBuYW1lIHdpdGggYSBzZXQgb2YgQ1NTIHN0eWxlcy5cbiAqIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnkgdGhlIGBzdGF0ZSgpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25TdGF0ZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogVGhlIHN0YXRlIG5hbWUsIHVuaXF1ZSB3aXRoaW4gdGhlIGNvbXBvbmVudC5cbiAgICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqICBUaGUgQ1NTIHN0eWxlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBzdGF0ZS5cbiAgICovXG4gIHN0eWxlczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YTtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmdcbiAgICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAgICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi5cbiAgICovXG4gIG9wdGlvbnM/OiB7cGFyYW1zOiB7W25hbWU6IHN0cmluZ106IGFueX19O1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhbiBhbmltYXRpb24gdHJhbnNpdGlvbi4gSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGVcbiAqIGB0cmFuc2l0aW9uKClgIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblRyYW5zaXRpb25NZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIEFuIGV4cHJlc3Npb24gdGhhdCBkZXNjcmliZXMgYSBzdGF0ZSBjaGFuZ2UuXG4gICAqL1xuICBleHByOiBzdHJpbmd8XG4gICAgICAoKGZyb21TdGF0ZTogc3RyaW5nLCB0b1N0YXRlOiBzdHJpbmcsIGVsZW1lbnQ/OiBhbnksXG4gICAgICAgIHBhcmFtcz86IHtba2V5OiBzdHJpbmddOiBhbnl9KSA9PiBib29sZWFuKTtcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBvYmplY3RzIHRvIHdoaWNoIHRoaXMgdHJhbnNpdGlvbiBhcHBsaWVzLlxuICAgKi9cbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YXxBbmltYXRpb25NZXRhZGF0YVtdO1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGEgcmV1c2FibGUgYW5pbWF0aW9uLCB3aGljaCBpcyBhIGNvbGxlY3Rpb24gb2YgaW5kaXZpZHVhbCBhbmltYXRpb24gc3RlcHMuXG4gKiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZSBgYW5pbWF0aW9uKClgIGZ1bmN0aW9uLCBhbmRcbiAqIHBhc3NlZCB0byB0aGUgYHVzZUFuaW1hdGlvbigpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqICBPbmUgb3IgbW9yZSBhbmltYXRpb24gc3RlcCBvYmplY3RzLlxuICAgKi9cbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YXxBbmltYXRpb25NZXRhZGF0YVtdO1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFuIGFuaW1hdGlvbiBxdWVyeS4gSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieVxuICogdGhlIGBxdWVyeSgpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25RdWVyeU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogIFRoZSBDU1Mgc2VsZWN0b3IgZm9yIHRoaXMgcXVlcnkuXG4gICAqL1xuICBzZWxlY3Rvcjogc3RyaW5nO1xuICAvKipcbiAgICogT25lIG9yIG1vcmUgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAgICovXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGF8QW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgLyoqXG4gICAqIEEgcXVlcnkgb3B0aW9ucyBvYmplY3QuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25RdWVyeU9wdGlvbnN8bnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYSBrZXlmcmFtZXMgc2VxdWVuY2UuIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnlcbiAqIHRoZSBga2V5ZnJhbWVzKClgIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBhbmltYXRpb24gc3R5bGVzLlxuICAgKi9cbiAgc3RlcHM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGFbXTtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIHN0eWxlLiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5XG4gKiB0aGUgYHN0eWxlKClgIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblN0eWxlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBBIHNldCBvZiBDU1Mgc3R5bGUgcHJvcGVydGllcy5cbiAgICovXG4gIHN0eWxlczogJyonfHtba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJ9fEFycmF5PHtba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJ9fCcqJz47XG4gIC8qKlxuICAgKiBBIHBlcmNlbnRhZ2Ugb2YgdGhlIHRvdGFsIGFuaW1hdGUgdGltZSBhdCB3aGljaCB0aGUgc3R5bGUgaXMgdG8gYmUgYXBwbGllZC5cbiAgICovXG4gIG9mZnNldDogbnVtYmVyfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFuIGFuaW1hdGlvbiBzdGVwLiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5XG4gKiB0aGUgYGFuaW1hdGUoKWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uQW5pbWF0ZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogVGhlIHRpbWluZyBkYXRhIGZvciB0aGUgc3RlcC5cbiAgICovXG4gIHRpbWluZ3M6IHN0cmluZ3xudW1iZXJ8QW5pbWF0ZVRpbWluZ3M7XG4gIC8qKlxuICAgKiBBIHNldCBvZiBzdHlsZXMgdXNlZCBpbiB0aGUgc3RlcC5cbiAgICovXG4gIHN0eWxlczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YXxBbmltYXRpb25LZXlmcmFtZXNTZXF1ZW5jZU1ldGFkYXRhfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGEgY2hpbGQgYW5pbWF0aW9uLCB0aGF0IGNhbiBiZSBydW4gZXhwbGljaXRseSB3aGVuIHRoZSBwYXJlbnQgaXMgcnVuLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYGFuaW1hdGVDaGlsZGAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uQW5pbWF0ZUNoaWxkTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGEgZGVsYXkgYW5kXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uIERlZmF1bHQgZGVsYXkgaXMgMC5cbiAgICovXG4gIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnN8bnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYSByZXVzYWJsZSBhbmltYXRpb24uXG4gKiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZSBgdXNlQW5pbWF0aW9uKClgIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVSZWZNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIEFuIGFuaW1hdGlvbiByZWZlcmVuY2Ugb2JqZWN0LlxuICAgKi9cbiAgYW5pbWF0aW9uOiBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YTtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAgICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAgICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi4gRGVmYXVsdCBkZWxheSBpcyAwLlxuICAgKi9cbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhbiBhbmltYXRpb24gc2VxdWVuY2UuXG4gKiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZSBgc2VxdWVuY2UoKWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uU2VxdWVuY2VNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqICBBbiBhcnJheSBvZiBhbmltYXRpb24gc3RlcCBvYmplY3RzLlxuICAgKi9cbiAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhW107XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGEgZGVsYXkgYW5kXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uIERlZmF1bHQgZGVsYXkgaXMgMC5cbiAgICovXG4gIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnN8bnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIGdyb3VwLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25Hcm91cE1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogT25lIG9yIG1vcmUgYW5pbWF0aW9uIG9yIHN0eWxlIHN0ZXBzIHRoYXQgZm9ybSB0aGlzIGdyb3VwLlxuICAgKi9cbiAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhW107XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGEgZGVsYXkgYW5kXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uIERlZmF1bHQgZGVsYXkgaXMgMC5cbiAgICovXG4gIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnN8bnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW5pbWF0aW9uIHF1ZXJ5IG9wdGlvbnMuXG4gKiBQYXNzZWQgdG8gdGhlIGBxdWVyeSgpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIEFuaW1hdGlvblF1ZXJ5T3B0aW9ucyBleHRlbmRzIEFuaW1hdGlvbk9wdGlvbnMge1xuICAvKipcbiAgICogVHJ1ZSBpZiB0aGlzIHF1ZXJ5IGlzIG9wdGlvbmFsLCBmYWxzZSBpZiBpdCBpcyByZXF1aXJlZC4gRGVmYXVsdCBpcyBmYWxzZS5cbiAgICogQSByZXF1aXJlZCBxdWVyeSB0aHJvd3MgYW4gZXJyb3IgaWYgbm8gZWxlbWVudHMgYXJlIHJldHJpZXZlZCB3aGVuXG4gICAqIHRoZSBxdWVyeSBpcyBleGVjdXRlZC4gQW4gb3B0aW9uYWwgcXVlcnkgZG9lcyBub3QuXG4gICAqXG4gICAqL1xuICBvcHRpb25hbD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBIG1heGltdW0gdG90YWwgbnVtYmVyIG9mIHJlc3VsdHMgdG8gcmV0dXJuIGZyb20gdGhlIHF1ZXJ5LlxuICAgKiBJZiBuZWdhdGl2ZSwgcmVzdWx0cyBhcmUgbGltaXRlZCBmcm9tIHRoZSBlbmQgb2YgdGhlIHF1ZXJ5IGxpc3QgdG93YXJkcyB0aGUgYmVnaW5uaW5nLlxuICAgKiBCeSBkZWZhdWx0LCByZXN1bHRzIGFyZSBub3QgbGltaXRlZC5cbiAgICovXG4gIGxpbWl0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBwYXJhbWV0ZXJzIGZvciBzdGFnZ2VyaW5nIHRoZSBzdGFydCB0aW1lcyBvZiBhIHNldCBvZiBhbmltYXRpb24gc3RlcHMuXG4gKiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZSBgc3RhZ2dlcigpYCBmdW5jdGlvbi5cbiAqKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uU3RhZ2dlck1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogVGhlIHRpbWluZyBkYXRhIGZvciB0aGUgc3RlcHMuXG4gICAqL1xuICB0aW1pbmdzOiBzdHJpbmd8bnVtYmVyO1xuICAvKipcbiAgICogT25lIG9yIG1vcmUgYW5pbWF0aW9uIHN0ZXBzLlxuICAgKi9cbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YXxBbmltYXRpb25NZXRhZGF0YVtdO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuYW1lZCBhbmltYXRpb24gdHJpZ2dlciwgY29udGFpbmluZyBhICBsaXN0IG9mIGBzdGF0ZSgpYFxuICogYW5kIGB0cmFuc2l0aW9uKClgIGVudHJpZXMgdG8gYmUgZXZhbHVhdGVkIHdoZW4gdGhlIGV4cHJlc3Npb25cbiAqIGJvdW5kIHRvIHRoZSB0cmlnZ2VyIGNoYW5nZXMuXG4gKlxuICogQHBhcmFtIG5hbWUgQW4gaWRlbnRpZnlpbmcgc3RyaW5nLlxuICogQHBhcmFtIGRlZmluaXRpb25zICBBbiBhbmltYXRpb24gZGVmaW5pdGlvbiBvYmplY3QsIGNvbnRhaW5pbmcgYW4gYXJyYXkgb2YgYHN0YXRlKClgXG4gKiBhbmQgYHRyYW5zaXRpb24oKWAgZGVjbGFyYXRpb25zLlxuICpcbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSB0cmlnZ2VyIGRhdGEuXG4gKiBcbiAqIEB1c2FnZU5vdGVzXG4gKiBEZWZpbmUgYW4gYW5pbWF0aW9uIHRyaWdnZXIgaW4gdGhlIGBhbmltYXRpb25zYCBzZWN0aW9uIG9mIGBAQ29tcG9uZW50YCBtZXRhZGF0YS5cbiAqIEluIHRoZSB0ZW1wbGF0ZSwgcmVmZXJlbmNlIHRoZSB0cmlnZ2VyIGJ5IG5hbWUgYW5kIGJpbmQgaXQgdG8gYSB0cmlnZ2VyIGV4cHJlc3Npb24gdGhhdFxuICogZXZhbHVhdGVzIHRvIGEgZGVmaW5lZCBhbmltYXRpb24gc3RhdGUsIHVzaW5nIHRoZSBmb2xsb3dpbmcgZm9ybWF0OlxuICpcbiAqIGBbQHRyaWdnZXJOYW1lXT1cImV4cHJlc3Npb25cImBcbiAqXG4gKiBBbmltYXRpb24gdHJpZ2dlciBiaW5kaW5ncyBjb252ZXJ0IGFsbCB2YWx1ZXMgdG8gc3RyaW5ncywgYW5kIHRoZW4gbWF0Y2ggdGhlIFxuICogcHJldmlvdXMgYW5kIGN1cnJlbnQgdmFsdWVzIGFnYWluc3QgYW55IGxpbmtlZCB0cmFuc2l0aW9ucy5cbiAqIEJvb2xlYW5zIGNhbiBiZSBzcGVjaWZpZWQgYXMgYDFgIG9yIGB0cnVlYCBhbmQgYDBgIG9yIGBmYWxzZWAuXG4gKlxuICogIyMjIFVzYWdlIEV4YW1wbGVcbiAqIFxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIGNyZWF0ZXMgYW4gYW5pbWF0aW9uIHRyaWdnZXIgcmVmZXJlbmNlIGJhc2VkIG9uIHRoZSBwcm92aWRlZFxuICogbmFtZSB2YWx1ZS5cbiAqIFRoZSBwcm92aWRlZCBhbmltYXRpb24gdmFsdWUgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXkgY29uc2lzdGluZyBvZiBzdGF0ZSBhbmRcbiAqIHRyYW5zaXRpb24gZGVjbGFyYXRpb25zLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogXCJteS1jb21wb25lbnRcIixcbiAqICAgdGVtcGxhdGVVcmw6IFwibXktY29tcG9uZW50LXRwbC5odG1sXCIsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKFwibXlBbmltYXRpb25UcmlnZ2VyXCIsIFtcbiAqICAgICAgIHN0YXRlKC4uLiksXG4gKiAgICAgICBzdGF0ZSguLi4pLFxuICogICAgICAgdHJhbnNpdGlvbiguLi4pLFxuICogICAgICAgdHJhbnNpdGlvbiguLi4pXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgbXlTdGF0dXNFeHAgPSBcInNvbWV0aGluZ1wiO1xuICogfVxuICogYGBgXG4gKlxuICogVGhlIHRlbXBsYXRlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbXBvbmVudCBtYWtlcyB1c2Ugb2YgdGhlIGRlZmluZWQgdHJpZ2dlclxuICogYnkgYmluZGluZyB0byBhbiBlbGVtZW50IHdpdGhpbiBpdHMgdGVtcGxhdGUgY29kZS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8IS0tIHNvbWV3aGVyZSBpbnNpZGUgb2YgbXktY29tcG9uZW50LXRwbC5odG1sIC0tPlxuICogPGRpdiBbQG15QW5pbWF0aW9uVHJpZ2dlcl09XCJteVN0YXR1c0V4cFwiPi4uLjwvZGl2PlxuICogYGBgXG4gKlxuICogIyMjIFVzaW5nIGFuIGlubGluZSBmdW5jdGlvblxuICogVGhlIGB0cmFuc2l0aW9uYCBhbmltYXRpb24gbWV0aG9kIGFsc28gc3VwcG9ydHMgcmVhZGluZyBhbiBpbmxpbmUgZnVuY3Rpb24gd2hpY2ggY2FuIGRlY2lkZVxuICogaWYgaXRzIGFzc29jaWF0ZWQgYW5pbWF0aW9uIHNob3VsZCBiZSBydW4uXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gdGhpcyBtZXRob2QgaXMgcnVuIGVhY2ggdGltZSB0aGUgYG15QW5pbWF0aW9uVHJpZ2dlcmAgdHJpZ2dlciB2YWx1ZSBjaGFuZ2VzLlxuICogZnVuY3Rpb24gbXlJbmxpbmVNYXRjaGVyRm4oZnJvbVN0YXRlOiBzdHJpbmcsIHRvU3RhdGU6IHN0cmluZywgZWxlbWVudDogYW55LCBwYXJhbXM6IHtba2V5OlxuIHN0cmluZ106IGFueX0pOiBib29sZWFuIHtcbiAqICAgLy8gbm90aWNlIHRoYXQgYGVsZW1lbnRgIGFuZCBgcGFyYW1zYCBhcmUgYWxzbyBhdmFpbGFibGUgaGVyZVxuICogICByZXR1cm4gdG9TdGF0ZSA9PSAneWVzLXBsZWFzZS1hbmltYXRlJztcbiAqIH1cbiAqXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdteS1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZVVybDogJ215LWNvbXBvbmVudC10cGwuaHRtbCcsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKCdteUFuaW1hdGlvblRyaWdnZXInLCBbXG4gKiAgICAgICB0cmFuc2l0aW9uKG15SW5saW5lTWF0Y2hlckZuLCBbXG4gKiAgICAgICAgIC8vIHRoZSBhbmltYXRpb24gc2VxdWVuY2UgY29kZVxuICogICAgICAgXSksXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgbXlTdGF0dXNFeHAgPSBcInllcy1wbGVhc2UtYW5pbWF0ZVwiO1xuICogfVxuICogYGBgXG4gKlxuICogIyMjIERpc2FibGluZyBBbmltYXRpb25zXG4gKiBXaGVuIHRydWUsIHRoZSBzcGVjaWFsIGFuaW1hdGlvbiBjb250cm9sIGJpbmRpbmcgYEAuZGlzYWJsZWRgIGJpbmRpbmcgcHJldmVudHMgXG4gKiBhbGwgYW5pbWF0aW9ucyBmcm9tIHJlbmRlcmluZy5cbiAqIFBsYWNlIHRoZSAgYEAuZGlzYWJsZWRgIGJpbmRpbmcgb24gYW4gZWxlbWVudCB0byBkaXNhYmxlXG4gKiBhbmltYXRpb25zIG9uIHRoZSBlbGVtZW50IGl0c2VsZiwgYXMgd2VsbCBhcyBhbnkgaW5uZXIgYW5pbWF0aW9uIHRyaWdnZXJzXG4gKiB3aXRoaW4gdGhlIGVsZW1lbnQuXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyB0byB1c2UgdGhpcyBmZWF0dXJlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ215LWNvbXBvbmVudCcsXG4gKiAgIHRlbXBsYXRlOiBgXG4gKiAgICAgPGRpdiBbQC5kaXNhYmxlZF09XCJpc0Rpc2FibGVkXCI+XG4gKiAgICAgICA8ZGl2IFtAY2hpbGRBbmltYXRpb25dPVwiZXhwXCI+PC9kaXY+XG4gKiAgICAgPC9kaXY+XG4gKiAgIGAsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKFwiY2hpbGRBbmltYXRpb25cIiwgW1xuICogICAgICAgLy8gLi4uXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgaXNEaXNhYmxlZCA9IHRydWU7XG4gKiAgIGV4cCA9ICcuLi4nO1xuICogfVxuICogYGBgXG4gKlxuICogV2hlbiBgQC5kaXNhYmxlZGAgaXMgdHJ1ZSwgaXQgcHJldmVudHMgdGhlIGBAY2hpbGRBbmltYXRpb25gIHRyaWdnZXIgZnJvbSBhbmltYXRpbmcsXG4gKiBhbG9uZyB3aXRoIGFueSBpbm5lciBhbmltYXRpb25zLlxuICpcbiAqICMjIyBEaXNhYmxlIGFuaW1hdGlvbnMgYXBwbGljYXRpb24td2lkZVxuICogV2hlbiBhbiBhcmVhIG9mIHRoZSB0ZW1wbGF0ZSBpcyBzZXQgdG8gaGF2ZSBhbmltYXRpb25zIGRpc2FibGVkLCBcbiAqICoqYWxsKiogaW5uZXIgY29tcG9uZW50cyBoYXZlIHRoZWlyIGFuaW1hdGlvbnMgZGlzYWJsZWQgYXMgd2VsbC5cbiAqIFRoaXMgbWVhbnMgdGhhdCB5b3UgY2FuIGRpc2FibGUgYWxsIGFuaW1hdGlvbnMgZm9yIGFuIGFwcFxuICogYnkgcGxhY2luZyBhIGhvc3QgYmluZGluZyBzZXQgb24gYEAuZGlzYWJsZWRgIG9uIHRoZSB0b3Btb3N0IEFuZ3VsYXIgY29tcG9uZW50LlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7Q29tcG9uZW50LCBIb3N0QmluZGluZ30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG4gKlxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnYXBwLWNvbXBvbmVudCcsXG4gKiAgIHRlbXBsYXRlVXJsOiAnYXBwLmNvbXBvbmVudC5odG1sJyxcbiAqIH0pXG4gKiBjbGFzcyBBcHBDb21wb25lbnQge1xuICogICBASG9zdEJpbmRpbmcoJ0AuZGlzYWJsZWQnKVxuICogICBwdWJsaWMgYW5pbWF0aW9uc0Rpc2FibGVkID0gdHJ1ZTtcbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIyBPdmVycmlkaW5nIGRpc2FibGVtZW50IG9mIGlubmVyIGFuaW1hdGlvbnNcbiAqIERlc3BpdGUgaW5uZXIgYW5pbWF0aW9ucyBiZWluZyBkaXNhYmxlZCwgYSBwYXJlbnQgYW5pbWF0aW9uIGNhbiBgcXVlcnkoKWBcbiAqIGZvciBpbm5lciBlbGVtZW50cyBsb2NhdGVkIGluIGRpc2FibGVkIGFyZWFzIG9mIHRoZSB0ZW1wbGF0ZSBhbmQgc3RpbGwgYW5pbWF0ZSBcbiAqIHRoZW0gaWYgbmVlZGVkLiBUaGlzIGlzIGFsc28gdGhlIGNhc2UgZm9yIHdoZW4gYSBzdWIgYW5pbWF0aW9uIGlzIFxuICogcXVlcmllZCBieSBhIHBhcmVudCBhbmQgdGhlbiBsYXRlciBhbmltYXRlZCB1c2luZyBgYW5pbWF0ZUNoaWxkKClgLlxuICpcbiAqICMjIyBEZXRlY3Rpbmcgd2hlbiBhbiBhbmltYXRpb24gaXMgZGlzYWJsZWRcbiAqIElmIGEgcmVnaW9uIG9mIHRoZSBET00gKG9yIHRoZSBlbnRpcmUgYXBwbGljYXRpb24pIGhhcyBpdHMgYW5pbWF0aW9ucyBkaXNhYmxlZCwgdGhlIGFuaW1hdGlvblxuICogdHJpZ2dlciBjYWxsYmFja3Mgc3RpbGwgZmlyZSwgYnV0IGZvciB6ZXJvIHNlY29uZHMuIFdoZW4gdGhlIGNhbGxiYWNrIGZpcmVzLCBpdCBwcm92aWRlc1xuICogYW4gaW5zdGFuY2Ugb2YgYW4gYEFuaW1hdGlvbkV2ZW50YC4gSWYgYW5pbWF0aW9ucyBhcmUgZGlzYWJsZWQsXG4gKiB0aGUgYC5kaXNhYmxlZGAgZmxhZyBvbiB0aGUgZXZlbnQgaXMgdHJ1ZS5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXIobmFtZTogc3RyaW5nLCBkZWZpbml0aW9uczogQW5pbWF0aW9uTWV0YWRhdGFbXSk6IEFuaW1hdGlvblRyaWdnZXJNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlRyaWdnZXIsIG5hbWUsIGRlZmluaXRpb25zLCBvcHRpb25zOiB7fX07XG59XG5cbi8qKlxuICogRGVmaW5lcyBhbiBhbmltYXRpb24gc3RlcCB0aGF0IGNvbWJpbmVzIHN0eWxpbmcgaW5mb3JtYXRpb24gd2l0aCB0aW1pbmcgaW5mb3JtYXRpb24uXG4gKlxuICogQHBhcmFtIHRpbWluZ3MgU2V0cyBgQW5pbWF0ZVRpbWluZ3NgIGZvciB0aGUgcGFyZW50IGFuaW1hdGlvbi5cbiAqIEEgc3RyaW5nIGluIHRoZSBmb3JtYXQgXCJkdXJhdGlvbiBbZGVsYXldIFtlYXNpbmddXCIuXG4gKiAgLSBEdXJhdGlvbiBhbmQgZGVsYXkgYXJlIGV4cHJlc3NlZCBhcyBhIG51bWJlciBhbmQgb3B0aW9uYWwgdGltZSB1bml0LFxuICogc3VjaCBhcyBcIjFzXCIgb3IgXCIxMG1zXCIgZm9yIG9uZSBzZWNvbmQgYW5kIDEwIG1pbGxpc2Vjb25kcywgcmVzcGVjdGl2ZWx5LlxuICogVGhlIGRlZmF1bHQgdW5pdCBpcyBtaWxsaXNlY29uZHMuXG4gKiAgLSBUaGUgZWFzaW5nIHZhbHVlIGNvbnRyb2xzIGhvdyB0aGUgYW5pbWF0aW9uIGFjY2VsZXJhdGVzIGFuZCBkZWNlbGVyYXRlc1xuICogZHVyaW5nIGl0cyBydW50aW1lLiBWYWx1ZSBpcyBvbmUgb2YgIGBlYXNlYCwgYGVhc2UtaW5gLCBgZWFzZS1vdXRgLFxuICogYGVhc2UtaW4tb3V0YCwgb3IgYSBgY3ViaWMtYmV6aWVyKClgIGZ1bmN0aW9uIGNhbGwuXG4gKiBJZiBub3Qgc3VwcGxpZWQsIG5vIGVhc2luZyBpcyBhcHBsaWVkLlxuICpcbiAqIEZvciBleGFtcGxlLCB0aGUgc3RyaW5nIFwiMXMgMTAwbXMgZWFzZS1vdXRcIiBzcGVjaWZpZXMgYSBkdXJhdGlvbiBvZlxuICogMTAwMCBtaWxsaXNlY29uZHMsIGFuZCBkZWxheSBvZiAxMDAgbXMsIGFuZCB0aGUgXCJlYXNlLW91dFwiIGVhc2luZyBzdHlsZSxcbiAqIHdoaWNoIGRlY2VsZXJhdGVzIG5lYXIgdGhlIGVuZCBvZiB0aGUgZHVyYXRpb24uXG4gKiBAcGFyYW0gc3R5bGVzIFNldHMgQW5pbWF0aW9uU3R5bGVzIGZvciB0aGUgcGFyZW50IGFuaW1hdGlvbi5cbiAqIEEgZnVuY3Rpb24gY2FsbCB0byBlaXRoZXIgYHN0eWxlKClgIG9yIGBrZXlmcmFtZXMoKWBcbiAqIHRoYXQgcmV0dXJucyBhIGNvbGxlY3Rpb24gb2YgQ1NTIHN0eWxlIGVudHJpZXMgdG8gYmUgYXBwbGllZCB0byB0aGUgcGFyZW50IGFuaW1hdGlvbi5cbiAqIFdoZW4gbnVsbCwgdXNlcyB0aGUgc3R5bGVzIGZyb20gdGhlIGRlc3RpbmF0aW9uIHN0YXRlLlxuICogVGhpcyBpcyB1c2VmdWwgd2hlbiBkZXNjcmliaW5nIGFuIGFuaW1hdGlvbiBzdGVwIHRoYXQgd2lsbCBjb21wbGV0ZSBhbiBhbmltYXRpb247XG4gKiBzZWUgXCJBbmltYXRpbmcgdG8gdGhlIGZpbmFsIHN0YXRlXCIgaW4gYHRyYW5zaXRpb25zKClgLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBhbmltYXRpb24gc3RlcC5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogQ2FsbCB3aXRoaW4gYW4gYW5pbWF0aW9uIGBzZXF1ZW5jZSgpYCwgYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YCwgb3JcbiAqIGB0cmFuc2l0aW9uKClgIGNhbGwgdG8gc3BlY2lmeSBhbiBhbmltYXRpb24gc3RlcFxuICogdGhhdCBhcHBsaWVzIGdpdmVuIHN0eWxlIGRhdGEgdG8gdGhlIHBhcmVudCBhbmltYXRpb24gZm9yIGEgZ2l2ZW4gYW1vdW50IG9mIHRpbWUuXG4gKlxuICogIyMjIFN5bnRheCBFeGFtcGxlc1xuICogKipUaW1pbmcgZXhhbXBsZXMqKlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZXMgc2hvdyB2YXJpb3VzIGB0aW1pbmdzYCBzcGVjaWZpY2F0aW9ucy5cbiAqIC0gYGFuaW1hdGUoNTAwKWAgOiBEdXJhdGlvbiBpcyA1MDAgbWlsbGlzZWNvbmRzLlxuICogLSBgYW5pbWF0ZShcIjFzXCIpYCA6IER1cmF0aW9uIGlzIDEwMDAgbWlsbGlzZWNvbmRzLlxuICogLSBgYW5pbWF0ZShcIjEwMG1zIDAuNXNcIilgIDogRHVyYXRpb24gaXMgMTAwIG1pbGxpc2Vjb25kcywgZGVsYXkgaXMgNTAwIG1pbGxpc2Vjb25kcy5cbiAqIC0gYGFuaW1hdGUoXCI1cyBlYXNlLWluXCIpYCA6IER1cmF0aW9uIGlzIDUwMDAgbWlsbGlzZWNvbmRzLCBlYXNpbmcgaW4uXG4gKiAtIGBhbmltYXRlKFwiNXMgMTBtcyBjdWJpYy1iZXppZXIoLjE3LC42NywuODgsLjEpXCIpYCA6IER1cmF0aW9uIGlzIDUwMDAgbWlsbGlzZWNvbmRzLCBkZWxheSBpcyAxMFxuICogbWlsbGlzZWNvbmRzLCBlYXNpbmcgYWNjb3JkaW5nIHRvIGEgYmV6aWVyIGN1cnZlLlxuICpcbiAqICoqU3R5bGUgZXhhbXBsZXMqKlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjYWxscyBgc3R5bGUoKWAgdG8gc2V0IGEgc2luZ2xlIENTUyBzdHlsZS5cbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGFuaW1hdGUoNTAwLCBzdHlsZSh7IGJhY2tncm91bmQ6IFwicmVkXCIgfSkpXG4gKiBgYGBcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjYWxscyBga2V5ZnJhbWVzKClgIHRvIHNldCBhIENTUyBzdHlsZVxuICogdG8gZGlmZmVyZW50IHZhbHVlcyBmb3Igc3VjY2Vzc2l2ZSBrZXlmcmFtZXMuXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBhbmltYXRlKDUwMCwga2V5ZnJhbWVzKFxuICogIFtcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcImJsdWVcIiB9KSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZDogXCJyZWRcIiB9KSlcbiAqICBdKVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmltYXRlKFxuICAgIHRpbWluZ3M6IHN0cmluZyB8IG51bWJlciwgc3R5bGVzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhIHwgQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSB8XG4gICAgICAgIG51bGwgPSBudWxsKTogQW5pbWF0aW9uQW5pbWF0ZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuQW5pbWF0ZSwgc3R5bGVzLCB0aW1pbmdzfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIGxpc3Qgb2YgYW5pbWF0aW9uIHN0ZXBzIHRvIGJlIHJ1biBpbiBwYXJhbGxlbC5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgQW4gYXJyYXkgb2YgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAqIC0gV2hlbiBzdGVwcyBhcmUgZGVmaW5lZCBieSBgc3R5bGUoKWAgb3IgYGFuaW1hdGUoKWBcbiAqIGZ1bmN0aW9uIGNhbGxzLCBlYWNoIGNhbGwgd2l0aGluIHRoZSBncm91cCBpcyBleGVjdXRlZCBpbnN0YW50bHkuXG4gKiAtIFRvIHNwZWNpZnkgb2Zmc2V0IHN0eWxlcyB0byBiZSBhcHBsaWVkIGF0IGEgbGF0ZXIgdGltZSwgZGVmaW5lIHN0ZXBzIHdpdGhcbiAqIGBrZXlmcmFtZXMoKWAsIG9yIHVzZSBgYW5pbWF0ZSgpYCBjYWxscyB3aXRoIGEgZGVsYXkgdmFsdWUuXG4gKiBGb3IgZXhhbXBsZTpcbiAqIFxuICogYGBgdHlwZXNjcmlwdFxuICogZ3JvdXAoW1xuICogICBhbmltYXRlKFwiMXNcIiwgeyBiYWNrZ3JvdW5kOiBcImJsYWNrXCIgfSkpXG4gKiAgIGFuaW1hdGUoXCIyc1wiLCB7IGNvbG9yOiBcIndoaXRlXCIgfSkpXG4gKiBdKVxuICogYGBgXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uXG4gKlxuICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIGdyb3VwIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIEdyb3VwZWQgYW5pbWF0aW9ucyBhcmUgdXNlZnVsIHdoZW4gYSBzZXJpZXMgb2Ygc3R5bGVzIG11c3QgYmUgXG4gKiBhbmltYXRlZCBhdCBkaWZmZXJlbnQgc3RhcnRpbmcgdGltZXMgYW5kIGNsb3NlZCBvZmYgYXQgZGlmZmVyZW50IGVuZGluZyB0aW1lcy5cbiAqXG4gKiBXaGVuIGNhbGxlZCB3aXRoaW4gYSBgc2VxdWVuY2UoKWAgb3IgYVxuICogYHRyYW5zaXRpb24oKWAgY2FsbCwgZG9lcyBub3QgY29udGludWUgdG8gdGhlIG5leHRcbiAqIGluc3RydWN0aW9uIHVudGlsIGFsbCBvZiB0aGUgaW5uZXIgYW5pbWF0aW9uIHN0ZXBzIGhhdmUgY29tcGxldGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXAoXG4gICAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhW10sIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsID0gbnVsbCk6IEFuaW1hdGlvbkdyb3VwTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5Hcm91cCwgc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIERlZmluZXMgYSBsaXN0IG9mIGFuaW1hdGlvbiBzdGVwcyB0byBiZSBydW4gc2VxdWVudGlhbGx5LCBvbmUgYnkgb25lLlxuICpcbiAqIEBwYXJhbSBzdGVwcyBBbiBhcnJheSBvZiBhbmltYXRpb24gc3RlcCBvYmplY3RzLlxuICogLSBTdGVwcyBkZWZpbmVkIGJ5IGBzdHlsZSgpYCBjYWxscyBhcHBseSB0aGUgc3R5bGluZyBkYXRhIGltbWVkaWF0ZWx5LlxuICogLSBTdGVwcyBkZWZpbmVkIGJ5IGBhbmltYXRlKClgIGNhbGxzIGFwcGx5IHRoZSBzdHlsaW5nIGRhdGEgb3ZlciB0aW1lXG4gKiAgIGFzIHNwZWNpZmllZCBieSB0aGUgdGltaW5nIGRhdGEuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogc2VxdWVuY2UoW1xuICogICBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpLFxuICogICBhbmltYXRlKFwiMXNcIiwgeyBvcGFjaXR5OiAxIH0pKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLlxuICpcbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBzZXF1ZW5jZSBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBXaGVuIHlvdSBwYXNzIGFuIGFycmF5IG9mIHN0ZXBzIHRvIGFcbiAqIGB0cmFuc2l0aW9uKClgIGNhbGwsIHRoZSBzdGVwcyBydW4gc2VxdWVudGlhbGx5IGJ5IGRlZmF1bHQuXG4gKiBDb21wYXJlIHRoaXMgdG8gdGhlIGB7QGxpbmsgYW5pbWF0aW9ucy9ncm91cCBncm91cCgpfWAgY2FsbCwgd2hpY2ggcnVucyBhbmltYXRpb24gc3RlcHMgaW4gcGFyYWxsZWwuXG4gKlxuICogV2hlbiBhIHNlcXVlbmNlIGlzIHVzZWQgd2l0aGluIGEgYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YCBvciBhIGB0cmFuc2l0aW9uKClgIGNhbGwsXG4gKiBleGVjdXRpb24gY29udGludWVzIHRvIHRoZSBuZXh0IGluc3RydWN0aW9uIG9ubHkgYWZ0ZXIgZWFjaCBvZiB0aGUgaW5uZXIgYW5pbWF0aW9uXG4gKiBzdGVwcyBoYXZlIGNvbXBsZXRlZC5cbiAqXG4gKiovXG5leHBvcnQgZnVuY3Rpb24gc2VxdWVuY2Uoc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhW10sIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsID0gbnVsbCk6XG4gICAgQW5pbWF0aW9uU2VxdWVuY2VNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlNlcXVlbmNlLCBzdGVwcywgb3B0aW9uc307XG59XG5cbi8qKlxuICogRGVjbGFyZXMgYSBrZXkvdmFsdWUgb2JqZWN0IGNvbnRhaW5pbmcgQ1NTIHByb3BlcnRpZXMvc3R5bGVzIHRoYXRcbiAqIGNhbiB0aGVuIGJlIHVzZWQgZm9yIGFuIGFuaW1hdGlvbiBgc3RhdGVgLCB3aXRoaW4gYW4gYW5pbWF0aW9uIGBzZXF1ZW5jZWAsXG4gKiBvciBhcyBzdHlsaW5nIGRhdGEgZm9yIGNhbGxzIHRvIGBhbmltYXRlKClgIGFuZCBga2V5ZnJhbWVzKClgLlxuICpcbiAqIEBwYXJhbSB0b2tlbnMgQSBzZXQgb2YgQ1NTIHN0eWxlcyBvciBIVE1MIHN0eWxlcyBhc3NvY2lhdGVkIHdpdGggYW4gYW5pbWF0aW9uIHN0YXRlLlxuICogVGhlIHZhbHVlIGNhbiBiZSBhbnkgb2YgdGhlIGZvbGxvd2luZzpcbiAqIC0gQSBrZXktdmFsdWUgc3R5bGUgcGFpciBhc3NvY2lhdGluZyBhIENTUyBwcm9wZXJ0eSB3aXRoIGEgdmFsdWUuXG4gKiAtIEFuIGFycmF5IG9mIGtleS12YWx1ZSBzdHlsZSBwYWlycy5cbiAqIC0gQW4gYXN0ZXJpc2sgKCopLCB0byB1c2UgYXV0by1zdHlsaW5nLCB3aGVyZSBzdHlsZXMgYXJlIGRlcml2ZWQgZnJvbSB0aGUgZWxlbWVudFxuICogYmVpbmcgYW5pbWF0ZWQgYW5kIGFwcGxpZWQgdG8gdGhlIGFuaW1hdGlvbiB3aGVuIGl0IHN0YXJ0cy5cbiAqXG4gKiBBdXRvLXN0eWxpbmcgY2FuIGJlIHVzZWQgdG8gZGVmaW5lIGEgc3RhdGUgdGhhdCBkZXBlbmRzIG9uIGxheW91dCBvciBvdGhlciBcbiAqIGVudmlyb25tZW50YWwgZmFjdG9ycy5cbiAqXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgc3R5bGUgZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVGhlIGZvbGxvd2luZyBleGFtcGxlcyBjcmVhdGUgYW5pbWF0aW9uIHN0eWxlcyB0aGF0IGNvbGxlY3QgYSBzZXQgb2ZcbiAqIENTUyBwcm9wZXJ0eSB2YWx1ZXM6XG4gKiBcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHN0cmluZyB2YWx1ZXMgZm9yIENTUyBwcm9wZXJ0aWVzXG4gKiBzdHlsZSh7IGJhY2tncm91bmQ6IFwicmVkXCIsIGNvbG9yOiBcImJsdWVcIiB9KVxuICpcbiAqIC8vIG51bWVyaWNhbCBwaXhlbCB2YWx1ZXNcbiAqIHN0eWxlKHsgd2lkdGg6IDEwMCwgaGVpZ2h0OiAwIH0pXG4gKiBgYGBcbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgdXNlcyBhdXRvLXN0eWxpbmcgdG8gYWxsb3cgYSBjb21wb25lbnQgdG8gYW5pbWF0ZSBmcm9tXG4gKiBhIGhlaWdodCBvZiAwIHVwIHRvIHRoZSBoZWlnaHQgb2YgdGhlIHBhcmVudCBlbGVtZW50OlxuICpcbiAqIGBgYFxuICogc3R5bGUoeyBoZWlnaHQ6IDAgfSksXG4gKiBhbmltYXRlKFwiMXNcIiwgc3R5bGUoeyBoZWlnaHQ6IFwiKlwiIH0pKVxuICogYGBgXG4gKlxuICoqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0eWxlKFxuICAgIHRva2VuczogJyonIHwge1trZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlcn0gfFxuICAgIEFycmF5PCcqJ3x7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfT4pOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU3R5bGUsIHN0eWxlczogdG9rZW5zLCBvZmZzZXQ6IG51bGx9O1xufVxuXG4vKipcbiAqIERlY2xhcmVzIGFuIGFuaW1hdGlvbiBzdGF0ZSB3aXRoaW4gYSB0cmlnZ2VyIGF0dGFjaGVkIHRvIGFuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIG5hbWUgT25lIG9yIG1vcmUgbmFtZXMgZm9yIHRoZSBkZWZpbmVkIHN0YXRlIGluIGEgY29tbWEtc2VwYXJhdGVkIHN0cmluZy5cbiAqIFRoZSBmb2xsb3dpbmcgcmVzZXJ2ZWQgc3RhdGUgbmFtZXMgY2FuIGJlIHN1cHBsaWVkIHRvIGRlZmluZSBhIHN0eWxlIGZvciBzcGVjaWZpYyB1c2VcbiAqIGNhc2VzOlxuICpcbiAqIC0gYHZvaWRgIFlvdSBjYW4gYXNzb2NpYXRlIHN0eWxlcyB3aXRoIHRoaXMgbmFtZSB0byBiZSB1c2VkIHdoZW5cbiAqIHRoZSBlbGVtZW50IGlzIGRldGFjaGVkIGZyb20gdGhlIGFwcGxpY2F0aW9uLiBGb3IgZXhhbXBsZSwgd2hlbiBhbiBgbmdJZmAgZXZhbHVhdGVzXG4gKiB0byBmYWxzZSwgdGhlIHN0YXRlIG9mIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgaXMgdm9pZC5cbiAqICAtIGAqYCAoYXN0ZXJpc2spIEluZGljYXRlcyB0aGUgZGVmYXVsdCBzdGF0ZS4gWW91IGNhbiBhc3NvY2lhdGUgc3R5bGVzIHdpdGggdGhpcyBuYW1lXG4gKiB0byBiZSB1c2VkIGFzIHRoZSBmYWxsYmFjayB3aGVuIHRoZSBzdGF0ZSB0aGF0IGlzIGJlaW5nIGFuaW1hdGVkIGlzIG5vdCBkZWNsYXJlZFxuICogd2l0aGluIHRoZSB0cmlnZ2VyLlxuICpcbiAqIEBwYXJhbSBzdHlsZXMgQSBzZXQgb2YgQ1NTIHN0eWxlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBzdGF0ZSwgY3JlYXRlZCB1c2luZyB0aGVcbiAqIGBzdHlsZSgpYCBmdW5jdGlvbi5cbiAqIFRoaXMgc2V0IG9mIHN0eWxlcyBwZXJzaXN0cyBvbiB0aGUgZWxlbWVudCBvbmNlIHRoZSBzdGF0ZSBoYXMgYmVlbiByZWFjaGVkLlxuICogQHBhcmFtIG9wdGlvbnMgUGFyYW1ldGVycyB0aGF0IGNhbiBiZSBwYXNzZWQgdG8gdGhlIHN0YXRlIHdoZW4gaXQgaXMgaW52b2tlZC5cbiAqIDAgb3IgbW9yZSBrZXktdmFsdWUgcGFpcnMuXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgbmV3IHN0YXRlIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIFVzZSB0aGUgYHRyaWdnZXIoKWAgZnVuY3Rpb24gdG8gcmVnaXN0ZXIgc3RhdGVzIHRvIGFuIGFuaW1hdGlvbiB0cmlnZ2VyLlxuICogVXNlIHRoZSBgdHJhbnNpdGlvbigpYCBmdW5jdGlvbiB0byBhbmltYXRlIGJldHdlZW4gc3RhdGVzLlxuICogV2hlbiBhIHN0YXRlIGlzIGFjdGl2ZSB3aXRoaW4gYSBjb21wb25lbnQsIGl0cyBhc3NvY2lhdGVkIHN0eWxlcyBwZXJzaXN0IG9uIHRoZSBlbGVtZW50LFxuICogZXZlbiB3aGVuIHRoZSBhbmltYXRpb24gZW5kcy5cbiAqKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGF0ZShcbiAgICBuYW1lOiBzdHJpbmcsIHN0eWxlczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YSxcbiAgICBvcHRpb25zPzoge3BhcmFtczoge1tuYW1lOiBzdHJpbmddOiBhbnl9fSk6IEFuaW1hdGlvblN0YXRlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdGF0ZSwgbmFtZSwgc3R5bGVzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIGEgc2V0IG9mIGFuaW1hdGlvbiBzdHlsZXMsIGFzc29jaWF0aW5nIGVhY2ggc3R5bGUgd2l0aCBhbiBvcHRpb25hbCBgb2Zmc2V0YCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgQSBzZXQgb2YgYW5pbWF0aW9uIHN0eWxlcyB3aXRoIG9wdGlvbmFsIG9mZnNldCBkYXRhLlxuICogVGhlIG9wdGlvbmFsIGBvZmZzZXRgIHZhbHVlIGZvciBhIHN0eWxlIHNwZWNpZmllcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIHRvdGFsIGFuaW1hdGlvblxuICogdGltZSBhdCB3aGljaCB0aGF0IHN0eWxlIGlzIGFwcGxpZWQuXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIGtleWZyYW1lcyBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBVc2Ugd2l0aCB0aGUgYGFuaW1hdGUoKWAgY2FsbC4gSW5zdGVhZCBvZiBhcHBseWluZyBhbmltYXRpb25zXG4gKiBmcm9tIHRoZSBjdXJyZW50IHN0YXRlXG4gKiB0byB0aGUgZGVzdGluYXRpb24gc3RhdGUsIGtleWZyYW1lcyBkZXNjcmliZSBob3cgZWFjaCBzdHlsZSBlbnRyeSBpcyBhcHBsaWVkIGFuZCBhdCB3aGF0IHBvaW50XG4gKiB3aXRoaW4gdGhlIGFuaW1hdGlvbiBhcmMuXG4gKiBDb21wYXJlIFtDU1MgS2V5ZnJhbWUgQW5pbWF0aW9uc10oaHR0cHM6Ly93d3cudzNzY2hvb2xzLmNvbS9jc3MvY3NzM19hbmltYXRpb25zLmFzcCkuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogSW4gdGhlIGZvbGxvd2luZyBleGFtcGxlLCB0aGUgb2Zmc2V0IHZhbHVlcyBkZXNjcmliZVxuICogd2hlbiBlYWNoIGBiYWNrZ3JvdW5kQ29sb3JgIHZhbHVlIGlzIGFwcGxpZWQuIFRoZSBjb2xvciBpcyByZWQgYXQgdGhlIHN0YXJ0LCBhbmQgY2hhbmdlcyB0b1xuICogYmx1ZSB3aGVuIDIwJSBvZiB0aGUgdG90YWwgdGltZSBoYXMgZWxhcHNlZC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyB0aGUgcHJvdmlkZWQgb2Zmc2V0IHZhbHVlc1xuICogYW5pbWF0ZShcIjVzXCIsIGtleWZyYW1lcyhbXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcInJlZFwiLCBvZmZzZXQ6IDAgfSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcImJsdWVcIiwgb2Zmc2V0OiAwLjIgfSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcIm9yYW5nZVwiLCBvZmZzZXQ6IDAuMyB9KSxcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwiYmxhY2tcIiwgb2Zmc2V0OiAxIH0pXG4gKiBdKSlcbiAqIGBgYFxuICpcbiAqIElmIHRoZXJlIGFyZSBubyBgb2Zmc2V0YCB2YWx1ZXMgc3BlY2lmaWVkIGluIHRoZSBzdHlsZSBlbnRyaWVzLCB0aGUgb2Zmc2V0c1xuICogYXJlIGNhbGN1bGF0ZWQgYXV0b21hdGljYWxseS5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBhbmltYXRlKFwiNXNcIiwga2V5ZnJhbWVzKFtcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwicmVkXCIgfSkgLy8gb2Zmc2V0ID0gMFxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJibHVlXCIgfSkgLy8gb2Zmc2V0ID0gMC4zM1xuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJvcmFuZ2VcIiB9KSAvLyBvZmZzZXQgPSAwLjY2XG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcImJsYWNrXCIgfSkgLy8gb2Zmc2V0ID0gMVxuICogXSkpXG4gKmBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24ga2V5ZnJhbWVzKHN0ZXBzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhW10pOiBBbmltYXRpb25LZXlmcmFtZXNTZXF1ZW5jZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuS2V5ZnJhbWVzLCBzdGVwc307XG59XG5cbi8qKlxuICogRGVjbGFyZXMgYW4gYW5pbWF0aW9uIHRyYW5zaXRpb24gYXMgYSBzZXF1ZW5jZSBvZiBhbmltYXRpb24gc3RlcHMgdG8gcnVuIHdoZW4gYSBnaXZlblxuICogY29uZGl0aW9uIGlzIHNhdGlzZmllZC4gVGhlIGNvbmRpdGlvbiBpcyBhIEJvb2xlYW4gZXhwcmVzc2lvbiBvciBmdW5jdGlvbiB0aGF0IGNvbXBhcmVzXG4gKiB0aGUgcHJldmlvdXMgYW5kIGN1cnJlbnQgYW5pbWF0aW9uIHN0YXRlcywgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGlzIHRyYW5zaXRpb24gc2hvdWxkIG9jY3VyLlxuICogV2hlbiB0aGUgc3RhdGUgY3JpdGVyaWEgb2YgYSBkZWZpbmVkIHRyYW5zaXRpb24gYXJlIG1ldCwgdGhlIGFzc29jaWF0ZWQgYW5pbWF0aW9uIGlzXG4gKiB0cmlnZ2VyZWQuXG4gKlxuICogQHBhcmFtIHN0YXRlQ2hhbmdlRXhwciBBIEJvb2xlYW4gZXhwcmVzc2lvbiBvciBmdW5jdGlvbiB0aGF0IGNvbXBhcmVzIHRoZSBwcmV2aW91cyBhbmQgY3VycmVudFxuICogYW5pbWF0aW9uIHN0YXRlcywgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGlzIHRyYW5zaXRpb24gc2hvdWxkIG9jY3VyLiBOb3RlIHRoYXQgIFwidHJ1ZVwiIGFuZCBcImZhbHNlXCJcbiAqIG1hdGNoIDEgYW5kIDAsIHJlc3BlY3RpdmVseS4gQW4gZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQgZWFjaCB0aW1lIGEgc3RhdGUgY2hhbmdlIG9jY3VycyBpbiB0aGVcbiAqIGFuaW1hdGlvbiB0cmlnZ2VyIGVsZW1lbnQuXG4gKiBUaGUgYW5pbWF0aW9uIHN0ZXBzIHJ1biB3aGVuIHRoZSBleHByZXNzaW9uIGV2YWx1YXRlcyB0byB0cnVlLlxuICpcbiAqIC0gQSBzdGF0ZS1jaGFuZ2Ugc3RyaW5nIHRha2VzIHRoZSBmb3JtIFwic3RhdGUxID0+IHN0YXRlMlwiLCB3aGVyZSBlYWNoIHNpZGUgaXMgYSBkZWZpbmVkIGFuaW1hdGlvblxuICogc3RhdGUsIG9yIGFuIGFzdGVyaXggKCopIHRvIHJlZmVyIHRvIGEgZHluYW1pYyBzdGFydCBvciBlbmQgc3RhdGUuXG4gKiAgIC0gVGhlIGV4cHJlc3Npb24gc3RyaW5nIGNhbiBjb250YWluIG11bHRpcGxlIGNvbW1hLXNlcGFyYXRlZCBzdGF0ZW1lbnRzO1xuICogZm9yIGV4YW1wbGUgXCJzdGF0ZTEgPT4gc3RhdGUyLCBzdGF0ZTMgPT4gc3RhdGU0XCIuXG4gKiAgIC0gU3BlY2lhbCB2YWx1ZXMgYDplbnRlcmAgYW5kIGA6bGVhdmVgIGluaXRpYXRlIGEgdHJhbnNpdGlvbiBvbiB0aGUgZW50cnkgYW5kIGV4aXQgc3RhdGVzLFxuICogZXF1aXZhbGVudCB0byAgXCJ2b2lkID0+ICpcIiAgYW5kIFwiKiA9PiB2b2lkXCIuXG4gKiAgIC0gU3BlY2lhbCB2YWx1ZXMgYDppbmNyZW1lbnRgIGFuZCBgOmRlY3JlbWVudGAgaW5pdGlhdGUgYSB0cmFuc2l0aW9uIHdoZW4gYSBudW1lcmljIHZhbHVlIGhhc1xuICogaW5jcmVhc2VkIG9yIGRlY3JlYXNlZCBpbiB2YWx1ZS5cbiAqIC0gQSBmdW5jdGlvbiBpcyBleGVjdXRlZCBlYWNoIHRpbWUgYSBzdGF0ZSBjaGFuZ2Ugb2NjdXJzIGluIHRoZSBhbmltYXRpb24gdHJpZ2dlciBlbGVtZW50LlxuICogVGhlIGFuaW1hdGlvbiBzdGVwcyBydW4gd2hlbiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlLlxuICpcbiAqIEBwYXJhbSBzdGVwcyBPbmUgb3IgbW9yZSBhbmltYXRpb24gb2JqZWN0cywgYXMgcmV0dXJuZWQgYnkgdGhlIGBhbmltYXRlKClgIG9yXG4gKiBgc2VxdWVuY2UoKWAgZnVuY3Rpb24sIHRoYXQgZm9ybSBhIHRyYW5zZm9ybWF0aW9uIGZyb20gb25lIHN0YXRlIHRvIGFub3RoZXIuXG4gKiBBIHNlcXVlbmNlIGlzIHVzZWQgYnkgZGVmYXVsdCB3aGVuIHlvdSBwYXNzIGFuIGFycmF5LlxuICogQHBhcmFtIG9wdGlvbnMgQW4gb3B0aW9ucyBvYmplY3QgdGhhdCBjYW4gY29udGFpbiBhIGRlbGF5IHZhbHVlIGZvciB0aGUgc3RhcnQgb2YgdGhlIGFuaW1hdGlvbixcbiAqIGFuZCBhZGRpdGlvbmFsIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMuIFByb3ZpZGVkIHZhbHVlcyBmb3IgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGFyZSB1c2VkXG4gKiBhcyBkZWZhdWx0cywgYW5kIG92ZXJyaWRlIHZhbHVlcyBjYW4gYmUgcGFzc2VkIHRvIHRoZSBjYWxsZXIgb24gaW52b2NhdGlvbi5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgdHJhbnNpdGlvbiBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBUaGUgdGVtcGxhdGUgYXNzb2NpYXRlZCB3aXRoIGEgY29tcG9uZW50IGJpbmRzIGFuIGFuaW1hdGlvbiB0cmlnZ2VyIHRvIGFuIGVsZW1lbnQuXG4gKlxuICogYGBgSFRNTFxuICogPCEtLSBzb21ld2hlcmUgaW5zaWRlIG9mIG15LWNvbXBvbmVudC10cGwuaHRtbCAtLT5cbiAqIDxkaXYgW0BteUFuaW1hdGlvblRyaWdnZXJdPVwibXlTdGF0dXNFeHBcIj4uLi48L2Rpdj5cbiAqIGBgYFxuICpcbiAqIEFsbCB0cmFuc2l0aW9ucyBhcmUgZGVmaW5lZCB3aXRoaW4gYW4gYW5pbWF0aW9uIHRyaWdnZXIsXG4gKiBhbG9uZyB3aXRoIG5hbWVkIHN0YXRlcyB0aGF0IHRoZSB0cmFuc2l0aW9ucyBjaGFuZ2UgdG8gYW5kIGZyb20uXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdHJpZ2dlcihcIm15QW5pbWF0aW9uVHJpZ2dlclwiLCBbXG4gKiAgLy8gZGVmaW5lIHN0YXRlc1xuICogIHN0YXRlKFwib25cIiwgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcImdyZWVuXCIgfSkpLFxuICogIHN0YXRlKFwib2ZmXCIsIHN0eWxlKHsgYmFja2dyb3VuZDogXCJncmV5XCIgfSkpLFxuICogIC4uLl1cbiAqIGBgYFxuICpcbiAqIE5vdGUgdGhhdCB3aGVuIHlvdSBjYWxsIHRoZSBgc2VxdWVuY2UoKWAgZnVuY3Rpb24gd2l0aGluIGEgYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YFxuICogb3IgYSBgdHJhbnNpdGlvbigpYCBjYWxsLCBleGVjdXRpb24gZG9lcyBub3QgY29udGludWUgdG8gdGhlIG5leHQgaW5zdHJ1Y3Rpb25cbiAqIHVudGlsIGVhY2ggb2YgdGhlIGlubmVyIGFuaW1hdGlvbiBzdGVwcyBoYXZlIGNvbXBsZXRlZC5cbiAqXG4gKiAjIyMgU3ludGF4IGV4YW1wbGVzXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlcyBkZWZpbmUgdHJhbnNpdGlvbnMgYmV0d2VlbiB0aGUgdHdvIGRlZmluZWQgc3RhdGVzIChhbmQgZGVmYXVsdCBzdGF0ZXMpLFxuICogdXNpbmcgdmFyaW91cyBvcHRpb25zOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIFRyYW5zaXRpb24gb2NjdXJzIHdoZW4gdGhlIHN0YXRlIHZhbHVlXG4gKiAvLyBib3VuZCB0byBcIm15QW5pbWF0aW9uVHJpZ2dlclwiIGNoYW5nZXMgZnJvbSBcIm9uXCIgdG8gXCJvZmZcIlxuICogdHJhbnNpdGlvbihcIm9uID0+IG9mZlwiLCBhbmltYXRlKDUwMCkpXG4gKiAvLyBSdW4gdGhlIHNhbWUgYW5pbWF0aW9uIGZvciBib3RoIGRpcmVjdGlvbnNcbiAqIHRyYW5zaXRpb24oXCJvbiA8PT4gb2ZmXCIsIGFuaW1hdGUoNTAwKSlcbiAqIC8vIERlZmluZSBtdWx0aXBsZSBzdGF0ZS1jaGFuZ2UgcGFpcnMgc2VwYXJhdGVkIGJ5IGNvbW1hc1xuICogdHJhbnNpdGlvbihcIm9uID0+IG9mZiwgb2ZmID0+IHZvaWRcIiwgYW5pbWF0ZSg1MDApKVxuICogYGBgXG4gKlxuICogIyMjIFNwZWNpYWwgdmFsdWVzIGZvciBzdGF0ZS1jaGFuZ2UgZXhwcmVzc2lvbnNcbiAqXG4gKiAtIENhdGNoLWFsbCBzdGF0ZSBjaGFuZ2UgZm9yIHdoZW4gYW4gZWxlbWVudCBpcyBpbnNlcnRlZCBpbnRvIHRoZSBwYWdlIGFuZCB0aGVcbiAqIGRlc3RpbmF0aW9uIHN0YXRlIGlzIHVua25vd246XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdHJhbnNpdGlvbihcInZvaWQgPT4gKlwiLCBbXG4gKiAgc3R5bGUoeyBvcGFjaXR5OiAwIH0pLFxuICogIGFuaW1hdGUoNTAwKVxuICogIF0pXG4gKiBgYGBcbiAqXG4gKiAtIENhcHR1cmUgYSBzdGF0ZSBjaGFuZ2UgYmV0d2VlbiBhbnkgc3RhdGVzOlxuICpcbiAqICBgdHJhbnNpdGlvbihcIiogPT4gKlwiLCBhbmltYXRlKFwiMXMgMHNcIikpYFxuICpcbiAqIC0gRW50cnkgYW5kIGV4aXQgdHJhbnNpdGlvbnM6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdHJhbnNpdGlvbihcIjplbnRlclwiLCBbXG4gKiAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICAgYW5pbWF0ZSg1MDAsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSlcbiAqICAgXSksXG4gKiB0cmFuc2l0aW9uKFwiOmxlYXZlXCIsIFtcbiAqICAgYW5pbWF0ZSg1MDAsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSlcbiAqICAgXSlcbiAqIGBgYFxuICpcbiAqIC0gVXNlIGA6aW5jcmVtZW50YCBhbmQgYDpkZWNyZW1lbnRgIHRvIGluaXRpYXRlIHRyYW5zaXRpb25zOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyYW5zaXRpb24oXCI6aW5jcmVtZW50XCIsIGdyb3VwKFtcbiAqICBxdWVyeSgnOmVudGVyJywgW1xuICogICAgIHN0eWxlKHsgbGVmdDogJzEwMCUnIH0pLFxuICogICAgIGFuaW1hdGUoJzAuNXMgZWFzZS1vdXQnLCBzdHlsZSgnKicpKVxuICogICBdKSxcbiAqICBxdWVyeSgnOmxlYXZlJywgW1xuICogICAgIGFuaW1hdGUoJzAuNXMgZWFzZS1vdXQnLCBzdHlsZSh7IGxlZnQ6ICctMTAwJScgfSkpXG4gKiAgXSlcbiAqIF0pKVxuICpcbiAqIHRyYW5zaXRpb24oXCI6ZGVjcmVtZW50XCIsIGdyb3VwKFtcbiAqICBxdWVyeSgnOmVudGVyJywgW1xuICogICAgIHN0eWxlKHsgbGVmdDogJzEwMCUnIH0pLFxuICogICAgIGFuaW1hdGUoJzAuNXMgZWFzZS1vdXQnLCBzdHlsZSgnKicpKVxuICogICBdKSxcbiAqICBxdWVyeSgnOmxlYXZlJywgW1xuICogICAgIGFuaW1hdGUoJzAuNXMgZWFzZS1vdXQnLCBzdHlsZSh7IGxlZnQ6ICctMTAwJScgfSkpXG4gKiAgXSlcbiAqIF0pKVxuICogYGBgXG4gKlxuICogIyMjIFN0YXRlLWNoYW5nZSBmdW5jdGlvbnNcbiAqXG4gKiBIZXJlIGlzIGFuIGV4YW1wbGUgb2YgYSBgZnJvbVN0YXRlYCBzcGVjaWZpZWQgYXMgYSBzdGF0ZS1jaGFuZ2UgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGFuXG4gKiBhbmltYXRpb24gd2hlbiB0cnVlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyYW5zaXRpb24oKGZyb21TdGF0ZSwgdG9TdGF0ZSkgPT5cbiAqICB7XG4gKiAgIHJldHVybiBmcm9tU3RhdGUgPT0gXCJvZmZcIiAmJiB0b1N0YXRlID09IFwib25cIjtcbiAqICB9LFxuICogIGFuaW1hdGUoXCIxcyAwc1wiKSlcbiAqIGBgYFxuICpcbiAqICMjIyBBbmltYXRpbmcgdG8gdGhlIGZpbmFsIHN0YXRlXG4gKlxuICogSWYgdGhlIGZpbmFsIHN0ZXAgaW4gYSB0cmFuc2l0aW9uIGlzIGEgY2FsbCB0byBgYW5pbWF0ZSgpYCB0aGF0IHVzZXMgYSB0aW1pbmcgdmFsdWVcbiAqIHdpdGggbm8gc3R5bGUgZGF0YSwgdGhhdCBzdGVwIGlzIGF1dG9tYXRpY2FsbHkgY29uc2lkZXJlZCB0aGUgZmluYWwgYW5pbWF0aW9uIGFyYyxcbiAqIGZvciB0aGUgZWxlbWVudCB0byByZWFjaCB0aGUgZmluYWwgc3RhdGUuIEFuZ3VsYXIgYXV0b21hdGljYWxseSBhZGRzIG9yIHJlbW92ZXNcbiAqIENTUyBzdHlsZXMgdG8gZW5zdXJlIHRoYXQgdGhlIGVsZW1lbnQgaXMgaW4gdGhlIGNvcnJlY3QgZmluYWwgc3RhdGUuXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIGRlZmluZXMgYSB0cmFuc2l0aW9uIHRoYXQgc3RhcnRzIGJ5IGhpZGluZyB0aGUgZWxlbWVudCxcbiAqIHRoZW4gbWFrZXMgc3VyZSB0aGF0IGl0IGFuaW1hdGVzIHByb3Blcmx5IHRvIHdoYXRldmVyIHN0YXRlIGlzIGN1cnJlbnRseSBhY3RpdmUgZm9yIHRyaWdnZXI6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdHJhbnNpdGlvbihcInZvaWQgPT4gKlwiLCBbXG4gKiAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICAgYW5pbWF0ZSg1MDApXG4gKiAgXSlcbiAqIGBgYFxuICogIyMjIEJvb2xlYW4gdmFsdWUgbWF0Y2hpbmdcbiAqIElmIGEgdHJpZ2dlciBiaW5kaW5nIHZhbHVlIGlzIGEgQm9vbGVhbiwgaXQgY2FuIGJlIG1hdGNoZWQgdXNpbmcgYSB0cmFuc2l0aW9uIGV4cHJlc3Npb25cbiAqIHRoYXQgY29tcGFyZXMgdHJ1ZSBhbmQgZmFsc2Ugb3IgMSBhbmQgMC4gRm9yIGV4YW1wbGU6XG4gKlxuICogYGBgXG4gKiAvLyBpbiB0aGUgdGVtcGxhdGVcbiAqIDxkaXYgW0BvcGVuQ2xvc2VdPVwib3BlbiA/IHRydWUgOiBmYWxzZVwiPi4uLjwvZGl2PlxuICogLy8gaW4gdGhlIGNvbXBvbmVudCBtZXRhZGF0YVxuICogdHJpZ2dlcignb3BlbkNsb3NlJywgW1xuICogICBzdGF0ZSgndHJ1ZScsIHN0eWxlKHsgaGVpZ2h0OiAnKicgfSkpLFxuICogICBzdGF0ZSgnZmFsc2UnLCBzdHlsZSh7IGhlaWdodDogJzBweCcgfSkpLFxuICogICB0cmFuc2l0aW9uKCdmYWxzZSA8PT4gdHJ1ZScsIGFuaW1hdGUoNTAwKSlcbiAqIF0pXG4gKiBgYGBcbiAqKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2l0aW9uKFxuICAgIHN0YXRlQ2hhbmdlRXhwcjogc3RyaW5nIHwgKChmcm9tU3RhdGU6IHN0cmluZywgdG9TdGF0ZTogc3RyaW5nLCBlbGVtZW50PzogYW55LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXM/OiB7W2tleTogc3RyaW5nXTogYW55fSkgPT4gYm9vbGVhbiksXG4gICAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25UcmFuc2l0aW9uTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5UcmFuc2l0aW9uLCBleHByOiBzdGF0ZUNoYW5nZUV4cHIsIGFuaW1hdGlvbjogc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIFByb2R1Y2VzIGEgcmV1c2FibGUgYW5pbWF0aW9uIHRoYXQgY2FuIGJlIGludm9rZWQgaW4gYW5vdGhlciBhbmltYXRpb24gb3Igc2VxdWVuY2UsXG4gKiBieSBjYWxsaW5nIHRoZSBgdXNlQW5pbWF0aW9uKClgIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSBzdGVwcyBPbmUgb3IgbW9yZSBhbmltYXRpb24gb2JqZWN0cywgYXMgcmV0dXJuZWQgYnkgdGhlIGBhbmltYXRlKClgXG4gKiBvciBgc2VxdWVuY2UoKWAgZnVuY3Rpb24sIHRoYXQgZm9ybSBhIHRyYW5zZm9ybWF0aW9uIGZyb20gb25lIHN0YXRlIHRvIGFub3RoZXIuXG4gKiBBIHNlcXVlbmNlIGlzIHVzZWQgYnkgZGVmYXVsdCB3aGVuIHlvdSBwYXNzIGFuIGFycmF5LlxuICogQHBhcmFtIG9wdGlvbnMgQW4gb3B0aW9ucyBvYmplY3QgdGhhdCBjYW4gY29udGFpbiBhIGRlbGF5IHZhbHVlIGZvciB0aGUgc3RhcnQgb2YgdGhlXG4gKiBhbmltYXRpb24sIGFuZCBhZGRpdGlvbmFsIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMuXG4gKiBQcm92aWRlZCB2YWx1ZXMgZm9yIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBhcmUgdXNlZCBhcyBkZWZhdWx0cyxcbiAqIGFuZCBvdmVycmlkZSB2YWx1ZXMgY2FuIGJlIHBhc3NlZCB0byB0aGUgY2FsbGVyIG9uIGludm9jYXRpb24uXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIGFuaW1hdGlvbiBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgZGVmaW5lcyBhIHJldXNhYmxlIGFuaW1hdGlvbiwgcHJvdmlkaW5nIHNvbWUgZGVmYXVsdCBwYXJhbWV0ZXJcbiAqIHZhbHVlcy5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB2YXIgZmFkZUFuaW1hdGlvbiA9IGFuaW1hdGlvbihbXG4gKiAgIHN0eWxlKHsgb3BhY2l0eTogJ3t7IHN0YXJ0IH19JyB9KSxcbiAqICAgYW5pbWF0ZSgne3sgdGltZSB9fScsXG4gKiAgIHN0eWxlKHsgb3BhY2l0eTogJ3t7IGVuZCB9fSd9KSlcbiAqICAgXSxcbiAqICAgeyBwYXJhbXM6IHsgdGltZTogJzEwMDBtcycsIHN0YXJ0OiAwLCBlbmQ6IDEgfX0pO1xuICogYGBgXG4gKlxuICogVGhlIGZvbGxvd2luZyBpbnZva2VzIHRoZSBkZWZpbmVkIGFuaW1hdGlvbiB3aXRoIGEgY2FsbCB0byBgdXNlQW5pbWF0aW9uKClgLFxuICogcGFzc2luZyBpbiBvdmVycmlkZSBwYXJhbWV0ZXIgdmFsdWVzLlxuICpcbiAqIGBgYGpzXG4gKiB1c2VBbmltYXRpb24oZmFkZUFuaW1hdGlvbiwge1xuICogICBwYXJhbXM6IHtcbiAqICAgICB0aW1lOiAnMnMnLFxuICogICAgIHN0YXJ0OiAxLFxuICogICAgIGVuZDogMFxuICogICB9XG4gKiB9KVxuICogYGBgXG4gKlxuICogSWYgYW55IG9mIHRoZSBwYXNzZWQtaW4gcGFyYW1ldGVyIHZhbHVlcyBhcmUgbWlzc2luZyBmcm9tIHRoaXMgY2FsbCxcbiAqIHRoZSBkZWZhdWx0IHZhbHVlcyBhcmUgdXNlZC4gSWYgb25lIG9yIG1vcmUgcGFyYW1ldGVyIHZhbHVlcyBhcmUgbWlzc2luZyBiZWZvcmUgYSBzdGVwIGlzXG4gKiBhbmltYXRlZCwgYHVzZUFuaW1hdGlvbigpYCB0aHJvd3MgYW4gZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmltYXRpb24oXG4gICAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlJlZmVyZW5jZSwgYW5pbWF0aW9uOiBzdGVwcywgb3B0aW9uc307XG59XG5cbi8qKlxuICogRXhlY3V0ZXMgYSBxdWVyaWVkIGlubmVyIGFuaW1hdGlvbiBlbGVtZW50IHdpdGhpbiBhbiBhbmltYXRpb24gc2VxdWVuY2UuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgQW4gb3B0aW9ucyBvYmplY3QgdGhhdCBjYW4gY29udGFpbiBhIGRlbGF5IHZhbHVlIGZvciB0aGUgc3RhcnQgb2YgdGhlXG4gKiBhbmltYXRpb24sIGFuZCBhZGRpdGlvbmFsIG92ZXJyaWRlIHZhbHVlcyBmb3IgZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycy5cbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBjaGlsZCBhbmltYXRpb24gZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogRWFjaCB0aW1lIGFuIGFuaW1hdGlvbiBpcyB0cmlnZ2VyZWQgaW4gQW5ndWxhciwgdGhlIHBhcmVudCBhbmltYXRpb25cbiAqIGhhcyBwcmlvcml0eSBhbmQgYW55IGNoaWxkIGFuaW1hdGlvbnMgYXJlIGJsb2NrZWQuIEluIG9yZGVyXG4gKiBmb3IgYSBjaGlsZCBhbmltYXRpb24gdG8gcnVuLCB0aGUgcGFyZW50IGFuaW1hdGlvbiBtdXN0IHF1ZXJ5IGVhY2ggb2YgdGhlIGVsZW1lbnRzXG4gKiBjb250YWluaW5nIGNoaWxkIGFuaW1hdGlvbnMsIGFuZCBydW4gdGhlbSB1c2luZyB0aGlzIGZ1bmN0aW9uLlxuICpcbiAqIE5vdGUgdGhhdCB0aGlzIGZlYXR1cmUgZGVzaWduZWQgdG8gYmUgdXNlZCB3aXRoIGBxdWVyeSgpYCBhbmQgaXQgd2lsbCBvbmx5IHdvcmtcbiAqIHdpdGggYW5pbWF0aW9ucyB0aGF0IGFyZSBhc3NpZ25lZCB1c2luZyB0aGUgQW5ndWxhciBhbmltYXRpb24gbGlicmFyeS4gQ1NTIGtleWZyYW1lc1xuICogYW5kIHRyYW5zaXRpb25zIGFyZSBub3QgaGFuZGxlZCBieSB0aGlzIEFQSS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuaW1hdGVDaGlsZChvcHRpb25zOiBBbmltYXRlQ2hpbGRPcHRpb25zIHwgbnVsbCA9IG51bGwpOlxuICAgIEFuaW1hdGlvbkFuaW1hdGVDaGlsZE1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuQW5pbWF0ZUNoaWxkLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBTdGFydHMgYSByZXVzYWJsZSBhbmltYXRpb24gdGhhdCBpcyBjcmVhdGVkIHVzaW5nIHRoZSBgYW5pbWF0aW9uKClgIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSBhbmltYXRpb24gVGhlIHJldXNhYmxlIGFuaW1hdGlvbiB0byBzdGFydC5cbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBkZWxheSB2YWx1ZSBmb3IgdGhlIHN0YXJ0IG9mIFxuICogdGhlIGFuaW1hdGlvbiwgYW5kIGFkZGl0aW9uYWwgb3ZlcnJpZGUgdmFsdWVzIGZvciBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzLlxuICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgYW5pbWF0aW9uIHBhcmFtZXRlcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VBbmltYXRpb24oXG4gICAgYW5pbWF0aW9uOiBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YSxcbiAgICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25BbmltYXRlUmVmTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5BbmltYXRlUmVmLCBhbmltYXRpb24sIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIEZpbmRzIG9uZSBvciBtb3JlIGlubmVyIGVsZW1lbnRzIHdpdGhpbiB0aGUgY3VycmVudCBlbGVtZW50IHRoYXQgaXNcbiAqIGJlaW5nIGFuaW1hdGVkIHdpdGhpbiBhIHNlcXVlbmNlLiBVc2Ugd2l0aCBgYW5pbWF0ZUNoaWxkKClgLlxuICpcbiAqIEBwYXJhbSBzZWxlY3RvciBUaGUgZWxlbWVudCB0byBxdWVyeSwgb3IgYSBzZXQgb2YgZWxlbWVudHMgdGhhdCBjb250YWluIEFuZ3VsYXItc3BlY2lmaWNcbiAqIGNoYXJhY3RlcmlzdGljcywgc3BlY2lmaWVkIHdpdGggb25lIG9yIG1vcmUgb2YgdGhlIGZvbGxvd2luZyB0b2tlbnMuXG4gKiAgLSBgcXVlcnkoXCI6ZW50ZXJcIilgIG9yIGBxdWVyeShcIjpsZWF2ZVwiKWAgOiBRdWVyeSBmb3IgbmV3bHkgaW5zZXJ0ZWQvcmVtb3ZlZCBlbGVtZW50cy5cbiAqICAtIGBxdWVyeShcIjphbmltYXRpbmdcIilgIDogUXVlcnkgYWxsIGN1cnJlbnRseSBhbmltYXRpbmcgZWxlbWVudHMuXG4gKiAgLSBgcXVlcnkoXCJAdHJpZ2dlck5hbWVcIilgIDogUXVlcnkgZWxlbWVudHMgdGhhdCBjb250YWluIGFuIGFuaW1hdGlvbiB0cmlnZ2VyLlxuICogIC0gYHF1ZXJ5KFwiQCpcIilgIDogUXVlcnkgYWxsIGVsZW1lbnRzIHRoYXQgY29udGFpbiBhbiBhbmltYXRpb24gdHJpZ2dlcnMuXG4gKiAgLSBgcXVlcnkoXCI6c2VsZlwiKWAgOiBJbmNsdWRlIHRoZSBjdXJyZW50IGVsZW1lbnQgaW50byB0aGUgYW5pbWF0aW9uIHNlcXVlbmNlLlxuICpcbiAqIEBwYXJhbSBhbmltYXRpb24gT25lIG9yIG1vcmUgYW5pbWF0aW9uIHN0ZXBzIHRvIGFwcGx5IHRvIHRoZSBxdWVyaWVkIGVsZW1lbnQgb3IgZWxlbWVudHMuXG4gKiBBbiBhcnJheSBpcyB0cmVhdGVkIGFzIGFuIGFuaW1hdGlvbiBzZXF1ZW5jZS5cbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0LiBVc2UgdGhlICdsaW1pdCcgZmllbGQgdG8gbGltaXQgdGhlIHRvdGFsIG51bWJlciBvZlxuICogaXRlbXMgdG8gY29sbGVjdC5cbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBxdWVyeSBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBUb2tlbnMgY2FuIGJlIG1lcmdlZCBpbnRvIGEgY29tYmluZWQgcXVlcnkgc2VsZWN0b3Igc3RyaW5nLiBGb3IgZXhhbXBsZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAgcXVlcnkoJzpzZWxmLCAucmVjb3JkOmVudGVyLCAucmVjb3JkOmxlYXZlLCBAc3ViVHJpZ2dlcicsIFsuLi5dKVxuICogYGBgXG4gKlxuICogVGhlIGBxdWVyeSgpYCBmdW5jdGlvbiBjb2xsZWN0cyBtdWx0aXBsZSBlbGVtZW50cyBhbmQgd29ya3MgaW50ZXJuYWxseSBieSB1c2luZ1xuICogYGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbGAuIFVzZSB0aGUgYGxpbWl0YCBmaWVsZCBvZiBhbiBvcHRpb25zIG9iamVjdCB0byBsaW1pdFxuICogdGhlIHRvdGFsIG51bWJlciBvZiBpdGVtcyB0byBiZSBjb2xsZWN0ZWQuIEZvciBleGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiBxdWVyeSgnZGl2JywgW1xuICogICBhbmltYXRlKC4uLiksXG4gKiAgIGFuaW1hdGUoLi4uKVxuICogXSwgeyBsaW1pdDogMSB9KVxuICogYGBgXG4gKlxuICogQnkgZGVmYXVsdCwgdGhyb3dzIGFuIGVycm9yIHdoZW4gemVybyBpdGVtcyBhcmUgZm91bmQuIFNldCB0aGVcbiAqIGBvcHRpb25hbGAgZmxhZyB0byBpZ25vcmUgdGhpcyBlcnJvci4gRm9yIGV4YW1wbGU6XG4gKlxuICogYGBganNcbiAqIHF1ZXJ5KCcuc29tZS1lbGVtZW50LXRoYXQtbWF5LW5vdC1iZS10aGVyZScsIFtcbiAqICAgYW5pbWF0ZSguLi4pLFxuICogICBhbmltYXRlKC4uLilcbiAqIF0sIHsgb3B0aW9uYWw6IHRydWUgfSlcbiAqIGBgYFxuICpcbiAqICMjIyBVc2FnZSBFeGFtcGxlXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHF1ZXJpZXMgZm9yIGlubmVyIGVsZW1lbnRzIGFuZCBhbmltYXRlcyB0aGVtXG4gKiBpbmRpdmlkdWFsbHkgdXNpbmcgYGFuaW1hdGVDaGlsZCgpYC4gXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnaW5uZXInLFxuICogICB0ZW1wbGF0ZTogYFxuICogICAgIDxkaXYgW0BxdWVyeUFuaW1hdGlvbl09XCJleHBcIj5cbiAqICAgICAgIDxoMT5UaXRsZTwvaDE+XG4gKiAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudFwiPlxuICogICAgICAgICBCbGFoIGJsYWggYmxhaFxuICogICAgICAgPC9kaXY+XG4gKiAgICAgPC9kaXY+XG4gKiAgIGAsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgIHRyaWdnZXIoJ3F1ZXJ5QW5pbWF0aW9uJywgW1xuICogICAgICB0cmFuc2l0aW9uKCcqID0+IGdvQW5pbWF0ZScsIFtcbiAqICAgICAgICAvLyBoaWRlIHRoZSBpbm5lciBlbGVtZW50c1xuICogICAgICAgIHF1ZXJ5KCdoMScsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSksXG4gKiAgICAgICAgcXVlcnkoJy5jb250ZW50Jywgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKSxcbiAqXG4gKiAgICAgICAgLy8gYW5pbWF0ZSB0aGUgaW5uZXIgZWxlbWVudHMgaW4sIG9uZSBieSBvbmVcbiAqICAgICAgICBxdWVyeSgnaDEnLCBhbmltYXRlKDEwMDAsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSksXG4gKiAgICAgICAgcXVlcnkoJy5jb250ZW50JywgYW5pbWF0ZSgxMDAwLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpLFxuICogICAgICBdKVxuICogICAgXSlcbiAqICBdXG4gKiB9KVxuICogY2xhc3MgQ21wIHtcbiAqICAgZXhwID0gJyc7XG4gKlxuICogICBnb0FuaW1hdGUoKSB7XG4gKiAgICAgdGhpcy5leHAgPSAnZ29BbmltYXRlJztcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBxdWVyeShcbiAgICBzZWxlY3Rvcjogc3RyaW5nLCBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgICBvcHRpb25zOiBBbmltYXRpb25RdWVyeU9wdGlvbnMgfCBudWxsID0gbnVsbCk6IEFuaW1hdGlvblF1ZXJ5TWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5RdWVyeSwgc2VsZWN0b3IsIGFuaW1hdGlvbiwgb3B0aW9uc307XG59XG5cbi8qKlxuICogVXNlIHdpdGhpbiBhbiBhbmltYXRpb24gYHF1ZXJ5KClgIGNhbGwgdG8gaXNzdWUgYSB0aW1pbmcgZ2FwIGFmdGVyXG4gKiBlYWNoIHF1ZXJpZWQgaXRlbSBpcyBhbmltYXRlZC5cbiAqXG4gKiBAcGFyYW0gdGltaW5ncyBBIGRlbGF5IHZhbHVlLlxuICogQHBhcmFtIGFuaW1hdGlvbiBPbmUgb3JlIG1vcmUgYW5pbWF0aW9uIHN0ZXBzLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBzdGFnZ2VyIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIEluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZSwgYSBjb250YWluZXIgZWxlbWVudCB3cmFwcyBhIGxpc3Qgb2YgaXRlbXMgc3RhbXBlZCBvdXRcbiAqIGJ5IGFuIGBuZ0ZvcmAuIFRoZSBjb250YWluZXIgZWxlbWVudCBjb250YWlucyBhbiBhbmltYXRpb24gdHJpZ2dlciB0aGF0IHdpbGwgbGF0ZXIgYmUgc2V0XG4gKiB0byBxdWVyeSBmb3IgZWFjaCBvZiB0aGUgaW5uZXIgaXRlbXMuXG4gKlxuICogRWFjaCB0aW1lIGl0ZW1zIGFyZSBhZGRlZCwgdGhlIG9wYWNpdHkgZmFkZS1pbiBhbmltYXRpb24gcnVucyxcbiAqIGFuZCBlYWNoIHJlbW92ZWQgaXRlbSBpcyBmYWRlZCBvdXQuXG4gKiBXaGVuIGVpdGhlciBvZiB0aGVzZSBhbmltYXRpb25zIG9jY3VyLCB0aGUgc3RhZ2dlciBlZmZlY3QgaXNcbiAqIGFwcGxpZWQgYWZ0ZXIgZWFjaCBpdGVtJ3MgYW5pbWF0aW9uIGlzIHN0YXJ0ZWQuXG4gKlxuICogYGBgaHRtbFxuICogPCEtLSBsaXN0LmNvbXBvbmVudC5odG1sIC0tPlxuICogPGJ1dHRvbiAoY2xpY2spPVwidG9nZ2xlKClcIj5TaG93IC8gSGlkZSBJdGVtczwvYnV0dG9uPlxuICogPGhyIC8+XG4gKiA8ZGl2IFtAbGlzdEFuaW1hdGlvbl09XCJpdGVtcy5sZW5ndGhcIj5cbiAqICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtc1wiPlxuICogICAgIHt7IGl0ZW0gfX1cbiAqICAgPC9kaXY+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICpcbiAqIEhlcmUgaXMgdGhlIGNvbXBvbmVudCBjb2RlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7dHJpZ2dlciwgdHJhbnNpdGlvbiwgc3R5bGUsIGFuaW1hdGUsIHF1ZXJ5LCBzdGFnZ2VyfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbiAqIEBDb21wb25lbnQoe1xuICogICB0ZW1wbGF0ZVVybDogJ2xpc3QuY29tcG9uZW50Lmh0bWwnLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcignbGlzdEFuaW1hdGlvbicsIFtcbiAqICAgICAuLi5cbiAqICAgICBdKVxuICogICBdXG4gKiB9KVxuICogY2xhc3MgTGlzdENvbXBvbmVudCB7XG4gKiAgIGl0ZW1zID0gW107XG4gKlxuICogICBzaG93SXRlbXMoKSB7XG4gKiAgICAgdGhpcy5pdGVtcyA9IFswLDEsMiwzLDRdO1xuICogICB9XG4gKlxuICogICBoaWRlSXRlbXMoKSB7XG4gKiAgICAgdGhpcy5pdGVtcyA9IFtdO1xuICogICB9XG4gKlxuICogICB0b2dnbGUoKSB7XG4gKiAgICAgdGhpcy5pdGVtcy5sZW5ndGggPyB0aGlzLmhpZGVJdGVtcygpIDogdGhpcy5zaG93SXRlbXMoKTtcbiAqICAgIH1cbiAqICB9XG4gKiBgYGBcbiAqXG4gKiBIZXJlIGlzIHRoZSBhbmltYXRpb24gdHJpZ2dlciBjb2RlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyaWdnZXIoJ2xpc3RBbmltYXRpb24nLCBbXG4gKiAgIHRyYW5zaXRpb24oJyogPT4gKicsIFsgLy8gZWFjaCB0aW1lIHRoZSBiaW5kaW5nIHZhbHVlIGNoYW5nZXNcbiAqICAgICBxdWVyeSgnOmxlYXZlJywgW1xuICogICAgICAgc3RhZ2dlcigxMDAsIFtcbiAqICAgICAgICAgYW5pbWF0ZSgnMC41cycsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSlcbiAqICAgICAgIF0pXG4gKiAgICAgXSksXG4gKiAgICAgcXVlcnkoJzplbnRlcicsIFtcbiAqICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICAgICAgIHN0YWdnZXIoMTAwLCBbXG4gKiAgICAgICAgIGFuaW1hdGUoJzAuNXMnLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpXG4gKiAgICAgICBdKVxuICogICAgIF0pXG4gKiAgIF0pXG4gKiBdKVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFnZ2VyKFxuICAgIHRpbWluZ3M6IHN0cmluZyB8IG51bWJlcixcbiAgICBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSk6IEFuaW1hdGlvblN0YWdnZXJNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlN0YWdnZXIsIHRpbWluZ3MsIGFuaW1hdGlvbn07XG59XG4iXX0=