@angular/animations 19.0.0-next.1 → 19.0.0-next.11

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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/browser/index.d.ts +1 -1
  3. package/browser/testing/index.d.ts +1 -1
  4. package/fesm2022/animations.mjs +7 -7
  5. package/fesm2022/animations.mjs.map +1 -1
  6. package/fesm2022/browser/testing.mjs +1 -1
  7. package/fesm2022/browser/testing.mjs.map +1 -1
  8. package/fesm2022/browser.mjs +4 -4
  9. package/fesm2022/browser.mjs.map +1 -1
  10. package/index.d.ts +1 -1
  11. package/package.json +2 -8
  12. package/esm2022/animations.mjs +0 -5
  13. package/esm2022/browser/browser.mjs +0 -5
  14. package/esm2022/browser/index.mjs +0 -13
  15. package/esm2022/browser/public_api.mjs +0 -14
  16. package/esm2022/browser/src/browser.mjs +0 -15
  17. package/esm2022/browser/src/create_engine.mjs +0 -20
  18. package/esm2022/browser/src/dsl/animation.mjs +0 -37
  19. package/esm2022/browser/src/dsl/animation_ast.mjs +0 -3
  20. package/esm2022/browser/src/dsl/animation_ast_builder.mjs +0 -514
  21. package/esm2022/browser/src/dsl/animation_dsl_visitor.mjs +0 -2
  22. package/esm2022/browser/src/dsl/animation_timeline_builder.mjs +0 -780
  23. package/esm2022/browser/src/dsl/animation_timeline_instruction.mjs +0 -15
  24. package/esm2022/browser/src/dsl/animation_transition_expr.mjs +0 -82
  25. package/esm2022/browser/src/dsl/animation_transition_factory.mjs +0 -152
  26. package/esm2022/browser/src/dsl/animation_transition_instruction.mjs +0 -26
  27. package/esm2022/browser/src/dsl/animation_trigger.mjs +0 -65
  28. package/esm2022/browser/src/dsl/element_instruction_map.mjs +0 -22
  29. package/esm2022/browser/src/dsl/style_normalization/animation_style_normalizer.mjs +0 -18
  30. package/esm2022/browser/src/dsl/style_normalization/web_animations_style_normalizer.mjs +0 -63
  31. package/esm2022/browser/src/error_helpers.mjs +0 -145
  32. package/esm2022/browser/src/private_export.mjs +0 -19
  33. package/esm2022/browser/src/render/animation_driver.mjs +0 -71
  34. package/esm2022/browser/src/render/animation_engine_instruction.mjs +0 -2
  35. package/esm2022/browser/src/render/animation_engine_next.mjs +0 -83
  36. package/esm2022/browser/src/render/animation_renderer.mjs +0 -99
  37. package/esm2022/browser/src/render/renderer.mjs +0 -165
  38. package/esm2022/browser/src/render/shared.mjs +0 -162
  39. package/esm2022/browser/src/render/special_cased_styles.mjs +0 -97
  40. package/esm2022/browser/src/render/timeline_animation_engine.mjs +0 -140
  41. package/esm2022/browser/src/render/transition_animation_engine.mjs +0 -1516
  42. package/esm2022/browser/src/render/web_animations/animatable_props_set.mjs +0 -214
  43. package/esm2022/browser/src/render/web_animations/web_animations_driver.mjs +0 -54
  44. package/esm2022/browser/src/render/web_animations/web_animations_player.mjs +0 -177
  45. package/esm2022/browser/src/util.mjs +0 -217
  46. package/esm2022/browser/src/warning_helpers.mjs +0 -36
  47. package/esm2022/browser/testing/index.mjs +0 -13
  48. package/esm2022/browser/testing/public_api.mjs +0 -14
  49. package/esm2022/browser/testing/src/mock_animation_driver.mjs +0 -117
  50. package/esm2022/browser/testing/src/testing.mjs +0 -9
  51. package/esm2022/browser/testing/testing.mjs +0 -5
  52. package/esm2022/index.mjs +0 -13
  53. package/esm2022/public_api.mjs +0 -14
  54. package/esm2022/src/animation_builder.mjs +0 -200
  55. package/esm2022/src/animation_event.mjs +0 -9
  56. package/esm2022/src/animation_metadata.mjs +0 -934
  57. package/esm2022/src/animations.mjs +0 -17
  58. package/esm2022/src/errors.mjs +0 -9
  59. package/esm2022/src/players/animation_group_player.mjs +0 -147
  60. package/esm2022/src/players/animation_player.mjs +0 -104
  61. package/esm2022/src/private_export.mjs +0 -11
  62. package/esm2022/src/version.mjs +0 -15
@@ -1,934 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- /**
9
- * @description Constants for the categories of parameters that can be defined for animations.
10
- *
11
- * A corresponding function defines a set of parameters for each category, and
12
- * collects them into a corresponding `AnimationMetadata` object.
13
- *
14
- * @publicApi
15
- */
16
- export var AnimationMetadataType;
17
- (function (AnimationMetadataType) {
18
- /**
19
- * Associates a named animation state with a set of CSS styles.
20
- * See [`state()`](api/animations/state)
21
- */
22
- AnimationMetadataType[AnimationMetadataType["State"] = 0] = "State";
23
- /**
24
- * Data for a transition from one animation state to another.
25
- * See `transition()`
26
- */
27
- AnimationMetadataType[AnimationMetadataType["Transition"] = 1] = "Transition";
28
- /**
29
- * Contains a set of animation steps.
30
- * See `sequence()`
31
- */
32
- AnimationMetadataType[AnimationMetadataType["Sequence"] = 2] = "Sequence";
33
- /**
34
- * Contains a set of animation steps.
35
- * See `{@link animations/group group()}`
36
- */
37
- AnimationMetadataType[AnimationMetadataType["Group"] = 3] = "Group";
38
- /**
39
- * Contains an animation step.
40
- * See `animate()`
41
- */
42
- AnimationMetadataType[AnimationMetadataType["Animate"] = 4] = "Animate";
43
- /**
44
- * Contains a set of animation steps.
45
- * See `keyframes()`
46
- */
47
- AnimationMetadataType[AnimationMetadataType["Keyframes"] = 5] = "Keyframes";
48
- /**
49
- * Contains a set of CSS property-value pairs into a named style.
50
- * See `style()`
51
- */
52
- AnimationMetadataType[AnimationMetadataType["Style"] = 6] = "Style";
53
- /**
54
- * Associates an animation with an entry trigger that can be attached to an element.
55
- * See `trigger()`
56
- */
57
- AnimationMetadataType[AnimationMetadataType["Trigger"] = 7] = "Trigger";
58
- /**
59
- * Contains a re-usable animation.
60
- * See `animation()`
61
- */
62
- AnimationMetadataType[AnimationMetadataType["Reference"] = 8] = "Reference";
63
- /**
64
- * Contains data to use in executing child animations returned by a query.
65
- * See `animateChild()`
66
- */
67
- AnimationMetadataType[AnimationMetadataType["AnimateChild"] = 9] = "AnimateChild";
68
- /**
69
- * Contains animation parameters for a re-usable animation.
70
- * See `useAnimation()`
71
- */
72
- AnimationMetadataType[AnimationMetadataType["AnimateRef"] = 10] = "AnimateRef";
73
- /**
74
- * Contains child-animation query data.
75
- * See `query()`
76
- */
77
- AnimationMetadataType[AnimationMetadataType["Query"] = 11] = "Query";
78
- /**
79
- * Contains data for staggering an animation sequence.
80
- * See `stagger()`
81
- */
82
- AnimationMetadataType[AnimationMetadataType["Stagger"] = 12] = "Stagger";
83
- })(AnimationMetadataType || (AnimationMetadataType = {}));
84
- /**
85
- * Specifies automatic styling.
86
- *
87
- * @publicApi
88
- */
89
- export const AUTO_STYLE = '*';
90
- /**
91
- * Creates a named animation trigger, containing a list of [`state()`](api/animations/state)
92
- * and `transition()` entries to be evaluated when the expression
93
- * bound to the trigger changes.
94
- *
95
- * @param name An identifying string.
96
- * @param definitions An animation definition object, containing an array of
97
- * [`state()`](api/animations/state) and `transition()` declarations.
98
- *
99
- * @return An object that encapsulates the trigger data.
100
- *
101
- * @usageNotes
102
- * Define an animation trigger in the `animations` section of `@Component` metadata.
103
- * In the template, reference the trigger by name and bind it to a trigger expression that
104
- * evaluates to a defined animation state, using the following format:
105
- *
106
- * `[@triggerName]="expression"`
107
- *
108
- * Animation trigger bindings convert all values to strings, and then match the
109
- * previous and current values against any linked transitions.
110
- * Booleans can be specified as `1` or `true` and `0` or `false`.
111
- *
112
- * ### Usage Example
113
- *
114
- * The following example creates an animation trigger reference based on the provided
115
- * name value.
116
- * The provided animation value is expected to be an array consisting of state and
117
- * transition declarations.
118
- *
119
- * ```typescript
120
- * @Component({
121
- * selector: "my-component",
122
- * templateUrl: "my-component-tpl.html",
123
- * animations: [
124
- * trigger("myAnimationTrigger", [
125
- * state(...),
126
- * state(...),
127
- * transition(...),
128
- * transition(...)
129
- * ])
130
- * ]
131
- * })
132
- * class MyComponent {
133
- * myStatusExp = "something";
134
- * }
135
- * ```
136
- *
137
- * The template associated with this component makes use of the defined trigger
138
- * by binding to an element within its template code.
139
- *
140
- * ```html
141
- * <!-- somewhere inside of my-component-tpl.html -->
142
- * <div [@myAnimationTrigger]="myStatusExp">...</div>
143
- * ```
144
- *
145
- * ### Using an inline function
146
- * The `transition` animation method also supports reading an inline function which can decide
147
- * if its associated animation should be run.
148
- *
149
- * ```typescript
150
- * // this method is run each time the `myAnimationTrigger` trigger value changes.
151
- * function myInlineMatcherFn(fromState: string, toState: string, element: any, params: {[key:
152
- string]: any}): boolean {
153
- * // notice that `element` and `params` are also available here
154
- * return toState == 'yes-please-animate';
155
- * }
156
- *
157
- * @Component({
158
- * selector: 'my-component',
159
- * templateUrl: 'my-component-tpl.html',
160
- * animations: [
161
- * trigger('myAnimationTrigger', [
162
- * transition(myInlineMatcherFn, [
163
- * // the animation sequence code
164
- * ]),
165
- * ])
166
- * ]
167
- * })
168
- * class MyComponent {
169
- * myStatusExp = "yes-please-animate";
170
- * }
171
- * ```
172
- *
173
- * ### Disabling Animations
174
- * When true, the special animation control binding `@.disabled` binding prevents
175
- * all animations from rendering.
176
- * Place the `@.disabled` binding on an element to disable
177
- * animations on the element itself, as well as any inner animation triggers
178
- * within the element.
179
- *
180
- * The following example shows how to use this feature:
181
- *
182
- * ```typescript
183
- * @Component({
184
- * selector: 'my-component',
185
- * template: `
186
- * <div [@.disabled]="isDisabled">
187
- * <div [@childAnimation]="exp"></div>
188
- * </div>
189
- * `,
190
- * animations: [
191
- * trigger("childAnimation", [
192
- * // ...
193
- * ])
194
- * ]
195
- * })
196
- * class MyComponent {
197
- * isDisabled = true;
198
- * exp = '...';
199
- * }
200
- * ```
201
- *
202
- * When `@.disabled` is true, it prevents the `@childAnimation` trigger from animating,
203
- * along with any inner animations.
204
- *
205
- * ### Disable animations application-wide
206
- * When an area of the template is set to have animations disabled,
207
- * **all** inner components have their animations disabled as well.
208
- * This means that you can disable all animations for an app
209
- * by placing a host binding set on `@.disabled` on the topmost Angular component.
210
- *
211
- * ```typescript
212
- * import {Component, HostBinding} from '@angular/core';
213
- *
214
- * @Component({
215
- * selector: 'app-component',
216
- * templateUrl: 'app.component.html',
217
- * })
218
- * class AppComponent {
219
- * @HostBinding('@.disabled')
220
- * public animationsDisabled = true;
221
- * }
222
- * ```
223
- *
224
- * ### Overriding disablement of inner animations
225
- * Despite inner animations being disabled, a parent animation can `query()`
226
- * for inner elements located in disabled areas of the template and still animate
227
- * them if needed. This is also the case for when a sub animation is
228
- * queried by a parent and then later animated using `animateChild()`.
229
- *
230
- * ### Detecting when an animation is disabled
231
- * If a region of the DOM (or the entire application) has its animations disabled, the animation
232
- * trigger callbacks still fire, but for zero seconds. When the callback fires, it provides
233
- * an instance of an `AnimationEvent`. If animations are disabled,
234
- * the `.disabled` flag on the event is true.
235
- *
236
- * @publicApi
237
- */
238
- export function trigger(name, definitions) {
239
- return { type: AnimationMetadataType.Trigger, name, definitions, options: {} };
240
- }
241
- /**
242
- * Defines an animation step that combines styling information with timing information.
243
- *
244
- * @param timings Sets `AnimateTimings` for the parent animation.
245
- * A string in the format "duration [delay] [easing]".
246
- * - Duration and delay are expressed as a number and optional time unit,
247
- * such as "1s" or "10ms" for one second and 10 milliseconds, respectively.
248
- * The default unit is milliseconds.
249
- * - The easing value controls how the animation accelerates and decelerates
250
- * during its runtime. Value is one of `ease`, `ease-in`, `ease-out`,
251
- * `ease-in-out`, or a `cubic-bezier()` function call.
252
- * If not supplied, no easing is applied.
253
- *
254
- * For example, the string "1s 100ms ease-out" specifies a duration of
255
- * 1000 milliseconds, and delay of 100 ms, and the "ease-out" easing style,
256
- * which decelerates near the end of the duration.
257
- * @param styles Sets AnimationStyles for the parent animation.
258
- * A function call to either `style()` or `keyframes()`
259
- * that returns a collection of CSS style entries to be applied to the parent animation.
260
- * When null, uses the styles from the destination state.
261
- * This is useful when describing an animation step that will complete an animation;
262
- * see "Animating to the final state" in `transitions()`.
263
- * @returns An object that encapsulates the animation step.
264
- *
265
- * @usageNotes
266
- * Call within an animation `sequence()`, `{@link animations/group group()}`, or
267
- * `transition()` call to specify an animation step
268
- * that applies given style data to the parent animation for a given amount of time.
269
- *
270
- * ### Syntax Examples
271
- * **Timing examples**
272
- *
273
- * The following examples show various `timings` specifications.
274
- * - `animate(500)` : Duration is 500 milliseconds.
275
- * - `animate("1s")` : Duration is 1000 milliseconds.
276
- * - `animate("100ms 0.5s")` : Duration is 100 milliseconds, delay is 500 milliseconds.
277
- * - `animate("5s ease-in")` : Duration is 5000 milliseconds, easing in.
278
- * - `animate("5s 10ms cubic-bezier(.17,.67,.88,.1)")` : Duration is 5000 milliseconds, delay is 10
279
- * milliseconds, easing according to a bezier curve.
280
- *
281
- * **Style examples**
282
- *
283
- * The following example calls `style()` to set a single CSS style.
284
- * ```typescript
285
- * animate(500, style({ background: "red" }))
286
- * ```
287
- * The following example calls `keyframes()` to set a CSS style
288
- * to different values for successive keyframes.
289
- * ```typescript
290
- * animate(500, keyframes(
291
- * [
292
- * style({ background: "blue" }),
293
- * style({ background: "red" })
294
- * ])
295
- * ```
296
- *
297
- * @publicApi
298
- */
299
- export function animate(timings, styles = null) {
300
- return { type: AnimationMetadataType.Animate, styles, timings };
301
- }
302
- /**
303
- * @description Defines a list of animation steps to be run in parallel.
304
- *
305
- * @param steps An array of animation step objects.
306
- * - When steps are defined by `style()` or `animate()`
307
- * function calls, each call within the group is executed instantly.
308
- * - To specify offset styles to be applied at a later time, define steps with
309
- * `keyframes()`, or use `animate()` calls with a delay value.
310
- * For example:
311
- *
312
- * ```typescript
313
- * group([
314
- * animate("1s", style({ background: "black" })),
315
- * animate("2s", style({ color: "white" }))
316
- * ])
317
- * ```
318
- *
319
- * @param options An options object containing a delay and
320
- * developer-defined parameters that provide styling defaults and
321
- * can be overridden on invocation.
322
- *
323
- * @return An object that encapsulates the group data.
324
- *
325
- * @usageNotes
326
- * Grouped animations are useful when a series of styles must be
327
- * animated at different starting times and closed off at different ending times.
328
- *
329
- * When called within a `sequence()` or a
330
- * `transition()` call, does not continue to the next
331
- * instruction until all of the inner animation steps have completed.
332
- *
333
- * @publicApi
334
- */
335
- export function group(steps, options = null) {
336
- return { type: AnimationMetadataType.Group, steps, options };
337
- }
338
- /**
339
- * Defines a list of animation steps to be run sequentially, one by one.
340
- *
341
- * @param steps An array of animation step objects.
342
- * - Steps defined by `style()` calls apply the styling data immediately.
343
- * - Steps defined by `animate()` calls apply the styling data over time
344
- * as specified by the timing data.
345
- *
346
- * ```typescript
347
- * sequence([
348
- * style({ opacity: 0 }),
349
- * animate("1s", style({ opacity: 1 }))
350
- * ])
351
- * ```
352
- *
353
- * @param options An options object containing a delay and
354
- * developer-defined parameters that provide styling defaults and
355
- * can be overridden on invocation.
356
- *
357
- * @return An object that encapsulates the sequence data.
358
- *
359
- * @usageNotes
360
- * When you pass an array of steps to a
361
- * `transition()` call, the steps run sequentially by default.
362
- * Compare this to the `{@link animations/group group()}` call, which runs animation steps in
363
- *parallel.
364
- *
365
- * When a sequence is used within a `{@link animations/group group()}` or a `transition()` call,
366
- * execution continues to the next instruction only after each of the inner animation
367
- * steps have completed.
368
- *
369
- * @publicApi
370
- **/
371
- export function sequence(steps, options = null) {
372
- return { type: AnimationMetadataType.Sequence, steps, options };
373
- }
374
- /**
375
- * Declares a key/value object containing CSS properties/styles that
376
- * can then be used for an animation [`state`](api/animations/state), within an animation
377
- *`sequence`, or as styling data for calls to `animate()` and `keyframes()`.
378
- *
379
- * @param tokens A set of CSS styles or HTML styles associated with an animation state.
380
- * The value can be any of the following:
381
- * - A key-value style pair associating a CSS property with a value.
382
- * - An array of key-value style pairs.
383
- * - An asterisk (*), to use auto-styling, where styles are derived from the element
384
- * being animated and applied to the animation when it starts.
385
- *
386
- * Auto-styling can be used to define a state that depends on layout or other
387
- * environmental factors.
388
- *
389
- * @return An object that encapsulates the style data.
390
- *
391
- * @usageNotes
392
- * The following examples create animation styles that collect a set of
393
- * CSS property values:
394
- *
395
- * ```typescript
396
- * // string values for CSS properties
397
- * style({ background: "red", color: "blue" })
398
- *
399
- * // numerical pixel values
400
- * style({ width: 100, height: 0 })
401
- * ```
402
- *
403
- * The following example uses auto-styling to allow an element to animate from
404
- * a height of 0 up to its full height:
405
- *
406
- * ```
407
- * style({ height: 0 }),
408
- * animate("1s", style({ height: "*" }))
409
- * ```
410
- *
411
- * @publicApi
412
- **/
413
- export function style(tokens) {
414
- return { type: AnimationMetadataType.Style, styles: tokens, offset: null };
415
- }
416
- /**
417
- * Declares an animation state within a trigger attached to an element.
418
- *
419
- * @param name One or more names for the defined state in a comma-separated string.
420
- * The following reserved state names can be supplied to define a style for specific use
421
- * cases:
422
- *
423
- * - `void` You can associate styles with this name to be used when
424
- * the element is detached from the application. For example, when an `ngIf` evaluates
425
- * to false, the state of the associated element is void.
426
- * - `*` (asterisk) Indicates the default state. You can associate styles with this name
427
- * to be used as the fallback when the state that is being animated is not declared
428
- * within the trigger.
429
- *
430
- * @param styles A set of CSS styles associated with this state, created using the
431
- * `style()` function.
432
- * This set of styles persists on the element once the state has been reached.
433
- * @param options Parameters that can be passed to the state when it is invoked.
434
- * 0 or more key-value pairs.
435
- * @return An object that encapsulates the new state data.
436
- *
437
- * @usageNotes
438
- * Use the `trigger()` function to register states to an animation trigger.
439
- * Use the `transition()` function to animate between states.
440
- * When a state is active within a component, its associated styles persist on the element,
441
- * even when the animation ends.
442
- *
443
- * @publicApi
444
- **/
445
- export function state(name, styles, options) {
446
- return { type: AnimationMetadataType.State, name, styles, options };
447
- }
448
- /**
449
- * Defines a set of animation styles, associating each style with an optional `offset` value.
450
- *
451
- * @param steps A set of animation styles with optional offset data.
452
- * The optional `offset` value for a style specifies a percentage of the total animation
453
- * time at which that style is applied.
454
- * @returns An object that encapsulates the keyframes data.
455
- *
456
- * @usageNotes
457
- * Use with the `animate()` call. Instead of applying animations
458
- * from the current state
459
- * to the destination state, keyframes describe how each style entry is applied and at what point
460
- * within the animation arc.
461
- * Compare [CSS Keyframe Animations](https://www.w3schools.com/css/css3_animations.asp).
462
- *
463
- * ### Usage
464
- *
465
- * In the following example, the offset values describe
466
- * when each `backgroundColor` value is applied. The color is red at the start, and changes to
467
- * blue when 20% of the total time has elapsed.
468
- *
469
- * ```typescript
470
- * // the provided offset values
471
- * animate("5s", keyframes([
472
- * style({ backgroundColor: "red", offset: 0 }),
473
- * style({ backgroundColor: "blue", offset: 0.2 }),
474
- * style({ backgroundColor: "orange", offset: 0.3 }),
475
- * style({ backgroundColor: "black", offset: 1 })
476
- * ]))
477
- * ```
478
- *
479
- * If there are no `offset` values specified in the style entries, the offsets
480
- * are calculated automatically.
481
- *
482
- * ```typescript
483
- * animate("5s", keyframes([
484
- * style({ backgroundColor: "red" }) // offset = 0
485
- * style({ backgroundColor: "blue" }) // offset = 0.33
486
- * style({ backgroundColor: "orange" }) // offset = 0.66
487
- * style({ backgroundColor: "black" }) // offset = 1
488
- * ]))
489
- *```
490
-
491
- * @publicApi
492
- */
493
- export function keyframes(steps) {
494
- return { type: AnimationMetadataType.Keyframes, steps };
495
- }
496
- /**
497
- * Declares an animation transition which is played when a certain specified condition is met.
498
- *
499
- * @param stateChangeExpr A string with a specific format or a function that specifies when the
500
- * animation transition should occur (see [State Change Expression](#state-change-expression)).
501
- *
502
- * @param steps One or more animation objects that represent the animation's instructions.
503
- *
504
- * @param options An options object that can be used to specify a delay for the animation or provide
505
- * custom parameters for it.
506
- *
507
- * @returns An object that encapsulates the transition data.
508
- *
509
- * @usageNotes
510
- *
511
- * ### State Change Expression
512
- *
513
- * The State Change Expression instructs Angular when to run the transition's animations, it can
514
- *either be
515
- * - a string with a specific syntax
516
- * - or a function that compares the previous and current state (value of the expression bound to
517
- * the element's trigger) and returns `true` if the transition should occur or `false` otherwise
518
- *
519
- * The string format can be:
520
- * - `fromState => toState`, which indicates that the transition's animations should occur then the
521
- * expression bound to the trigger's element goes from `fromState` to `toState`
522
- *
523
- * _Example:_
524
- * ```typescript
525
- * transition('open => closed', animate('.5s ease-out', style({ height: 0 }) ))
526
- * ```
527
- *
528
- * - `fromState <=> toState`, which indicates that the transition's animations should occur then
529
- * the expression bound to the trigger's element goes from `fromState` to `toState` or vice versa
530
- *
531
- * _Example:_
532
- * ```typescript
533
- * transition('enabled <=> disabled', animate('1s cubic-bezier(0.8,0.3,0,1)'))
534
- * ```
535
- *
536
- * - `:enter`/`:leave`, which indicates that the transition's animations should occur when the
537
- * element enters or exists the DOM
538
- *
539
- * _Example:_
540
- * ```typescript
541
- * transition(':enter', [
542
- * style({ opacity: 0 }),
543
- * animate('500ms', style({ opacity: 1 }))
544
- * ])
545
- * ```
546
- *
547
- * - `:increment`/`:decrement`, which indicates that the transition's animations should occur when
548
- * the numerical expression bound to the trigger's element has increased in value or decreased
549
- *
550
- * _Example:_
551
- * ```typescript
552
- * transition(':increment', query('@counter', animateChild()))
553
- * ```
554
- *
555
- * - a sequence of any of the above divided by commas, which indicates that transition's animations
556
- * should occur whenever one of the state change expressions matches
557
- *
558
- * _Example:_
559
- * ```typescript
560
- * transition(':increment, * => enabled, :enter', animate('1s ease', keyframes([
561
- * style({ transform: 'scale(1)', offset: 0}),
562
- * style({ transform: 'scale(1.1)', offset: 0.7}),
563
- * style({ transform: 'scale(1)', offset: 1})
564
- * ]))),
565
- * ```
566
- *
567
- * Also note that in such context:
568
- * - `void` can be used to indicate the absence of the element
569
- * - asterisks can be used as wildcards that match any state
570
- * - (as a consequence of the above, `void => *` is equivalent to `:enter` and `* => void` is
571
- * equivalent to `:leave`)
572
- * - `true` and `false` also match expression values of `1` and `0` respectively (but do not match
573
- * _truthy_ and _falsy_ values)
574
- *
575
- * <div class="alert is-helpful">
576
- *
577
- * Be careful about entering end leaving elements as their transitions present a common
578
- * pitfall for developers.
579
- *
580
- * Note that when an element with a trigger enters the DOM its `:enter` transition always
581
- * gets executed, but its `:leave` transition will not be executed if the element is removed
582
- * alongside its parent (as it will be removed "without warning" before its transition has
583
- * a chance to be executed, the only way that such transition can occur is if the element
584
- * is exiting the DOM on its own).
585
- *
586
- *
587
- * </div>
588
- *
589
- * ### Animating to a Final State
590
- *
591
- * If the final step in a transition is a call to `animate()` that uses a timing value
592
- * with no `style` data, that step is automatically considered the final animation arc,
593
- * for the element to reach the final state, in such case Angular automatically adds or removes
594
- * CSS styles to ensure that the element is in the correct final state.
595
- *
596
- *
597
- * ### Usage Examples
598
- *
599
- * - Transition animations applied based on
600
- * the trigger's expression value
601
- *
602
- * ```html
603
- * <div [@myAnimationTrigger]="myStatusExp">
604
- * ...
605
- * </div>
606
- * ```
607
- *
608
- * ```typescript
609
- * trigger("myAnimationTrigger", [
610
- * ..., // states
611
- * transition("on => off, open => closed", animate(500)),
612
- * transition("* <=> error", query('.indicator', animateChild()))
613
- * ])
614
- * ```
615
- *
616
- * - Transition animations applied based on custom logic dependent
617
- * on the trigger's expression value and provided parameters
618
- *
619
- * ```html
620
- * <div [@myAnimationTrigger]="{
621
- * value: stepName,
622
- * params: { target: currentTarget }
623
- * }">
624
- * ...
625
- * </div>
626
- * ```
627
- *
628
- * ```typescript
629
- * trigger("myAnimationTrigger", [
630
- * ..., // states
631
- * transition(
632
- * (fromState, toState, _element, params) =>
633
- * ['firststep', 'laststep'].includes(fromState.toLowerCase())
634
- * && toState === params?.['target'],
635
- * animate('1s')
636
- * )
637
- * ])
638
- * ```
639
- *
640
- * @publicApi
641
- **/
642
- export function transition(stateChangeExpr, steps, options = null) {
643
- return { type: AnimationMetadataType.Transition, expr: stateChangeExpr, animation: steps, options };
644
- }
645
- /**
646
- * Produces a reusable animation that can be invoked in another animation or sequence,
647
- * by calling the `useAnimation()` function.
648
- *
649
- * @param steps One or more animation objects, as returned by the `animate()`
650
- * or `sequence()` function, that form a transformation from one state to another.
651
- * A sequence is used by default when you pass an array.
652
- * @param options An options object that can contain a delay value for the start of the
653
- * animation, and additional developer-defined parameters.
654
- * Provided values for additional parameters are used as defaults,
655
- * and override values can be passed to the caller on invocation.
656
- * @returns An object that encapsulates the animation data.
657
- *
658
- * @usageNotes
659
- * The following example defines a reusable animation, providing some default parameter
660
- * values.
661
- *
662
- * ```typescript
663
- * var fadeAnimation = animation([
664
- * style({ opacity: '{{ start }}' }),
665
- * animate('{{ time }}',
666
- * style({ opacity: '{{ end }}'}))
667
- * ],
668
- * { params: { time: '1000ms', start: 0, end: 1 }});
669
- * ```
670
- *
671
- * The following invokes the defined animation with a call to `useAnimation()`,
672
- * passing in override parameter values.
673
- *
674
- * ```js
675
- * useAnimation(fadeAnimation, {
676
- * params: {
677
- * time: '2s',
678
- * start: 1,
679
- * end: 0
680
- * }
681
- * })
682
- * ```
683
- *
684
- * If any of the passed-in parameter values are missing from this call,
685
- * the default values are used. If one or more parameter values are missing before a step is
686
- * animated, `useAnimation()` throws an error.
687
- *
688
- * @publicApi
689
- */
690
- export function animation(steps, options = null) {
691
- return { type: AnimationMetadataType.Reference, animation: steps, options };
692
- }
693
- /**
694
- * Executes a queried inner animation element within an animation sequence.
695
- *
696
- * @param options An options object that can contain a delay value for the start of the
697
- * animation, and additional override values for developer-defined parameters.
698
- * @return An object that encapsulates the child animation data.
699
- *
700
- * @usageNotes
701
- * Each time an animation is triggered in Angular, the parent animation
702
- * has priority and any child animations are blocked. In order
703
- * for a child animation to run, the parent animation must query each of the elements
704
- * containing child animations, and run them using this function.
705
- *
706
- * Note that this feature is designed to be used with `query()` and it will only work
707
- * with animations that are assigned using the Angular animation library. CSS keyframes
708
- * and transitions are not handled by this API.
709
- *
710
- * @publicApi
711
- */
712
- export function animateChild(options = null) {
713
- return { type: AnimationMetadataType.AnimateChild, options };
714
- }
715
- /**
716
- * Starts a reusable animation that is created using the `animation()` function.
717
- *
718
- * @param animation The reusable animation to start.
719
- * @param options An options object that can contain a delay value for the start of
720
- * the animation, and additional override values for developer-defined parameters.
721
- * @return An object that contains the animation parameters.
722
- *
723
- * @publicApi
724
- */
725
- export function useAnimation(animation, options = null) {
726
- return { type: AnimationMetadataType.AnimateRef, animation, options };
727
- }
728
- /**
729
- * Finds one or more inner elements within the current element that is
730
- * being animated within a sequence. Use with `animate()`.
731
- *
732
- * @param selector The element to query, or a set of elements that contain Angular-specific
733
- * characteristics, specified with one or more of the following tokens.
734
- * - `query(":enter")` or `query(":leave")` : Query for newly inserted/removed elements (not
735
- * all elements can be queried via these tokens, see
736
- * [Entering and Leaving Elements](#entering-and-leaving-elements))
737
- * - `query(":animating")` : Query all currently animating elements.
738
- * - `query("@triggerName")` : Query elements that contain an animation trigger.
739
- * - `query("@*")` : Query all elements that contain an animation triggers.
740
- * - `query(":self")` : Include the current element into the animation sequence.
741
- *
742
- * @param animation One or more animation steps to apply to the queried element or elements.
743
- * An array is treated as an animation sequence.
744
- * @param options An options object. Use the 'limit' field to limit the total number of
745
- * items to collect.
746
- * @return An object that encapsulates the query data.
747
- *
748
- * @usageNotes
749
- *
750
- * ### Multiple Tokens
751
- *
752
- * Tokens can be merged into a combined query selector string. For example:
753
- *
754
- * ```typescript
755
- * query(':self, .record:enter, .record:leave, @subTrigger', [...])
756
- * ```
757
- *
758
- * The `query()` function collects multiple elements and works internally by using
759
- * `element.querySelectorAll`. Use the `limit` field of an options object to limit
760
- * the total number of items to be collected. For example:
761
- *
762
- * ```js
763
- * query('div', [
764
- * animate(...),
765
- * animate(...)
766
- * ], { limit: 1 })
767
- * ```
768
- *
769
- * By default, throws an error when zero items are found. Set the
770
- * `optional` flag to ignore this error. For example:
771
- *
772
- * ```js
773
- * query('.some-element-that-may-not-be-there', [
774
- * animate(...),
775
- * animate(...)
776
- * ], { optional: true })
777
- * ```
778
- *
779
- * ### Entering and Leaving Elements
780
- *
781
- * Not all elements can be queried via the `:enter` and `:leave` tokens, the only ones
782
- * that can are those that Angular assumes can enter/leave based on their own logic
783
- * (if their insertion/removal is simply a consequence of that of their parent they
784
- * should be queried via a different token in their parent's `:enter`/`:leave` transitions).
785
- *
786
- * The only elements Angular assumes can enter/leave based on their own logic (thus the only
787
- * ones that can be queried via the `:enter` and `:leave` tokens) are:
788
- * - Those inserted dynamically (via `ViewContainerRef`)
789
- * - Those that have a structural directive (which, under the hood, are a subset of the above ones)
790
- *
791
- * <div class="alert is-helpful">
792
- *
793
- * Note that elements will be successfully queried via `:enter`/`:leave` even if their
794
- * insertion/removal is not done manually via `ViewContainerRef`or caused by their structural
795
- * directive (e.g. they enter/exit alongside their parent).
796
- *
797
- * </div>
798
- *
799
- * <div class="alert is-important">
800
- *
801
- * There is an exception to what previously mentioned, besides elements entering/leaving based on
802
- * their own logic, elements with an animation trigger can always be queried via `:leave` when
803
- * their parent is also leaving.
804
- *
805
- * </div>
806
- *
807
- * ### Usage Example
808
- *
809
- * The following example queries for inner elements and animates them
810
- * individually using `animate()`.
811
- *
812
- * ```typescript
813
- * @Component({
814
- * selector: 'inner',
815
- * template: `
816
- * <div [@queryAnimation]="exp">
817
- * <h1>Title</h1>
818
- * <div class="content">
819
- * Blah blah blah
820
- * </div>
821
- * </div>
822
- * `,
823
- * animations: [
824
- * trigger('queryAnimation', [
825
- * transition('* => goAnimate', [
826
- * // hide the inner elements
827
- * query('h1', style({ opacity: 0 })),
828
- * query('.content', style({ opacity: 0 })),
829
- *
830
- * // animate the inner elements in, one by one
831
- * query('h1', animate(1000, style({ opacity: 1 }))),
832
- * query('.content', animate(1000, style({ opacity: 1 }))),
833
- * ])
834
- * ])
835
- * ]
836
- * })
837
- * class Cmp {
838
- * exp = '';
839
- *
840
- * goAnimate() {
841
- * this.exp = 'goAnimate';
842
- * }
843
- * }
844
- * ```
845
- *
846
- * @publicApi
847
- */
848
- export function query(selector, animation, options = null) {
849
- return { type: AnimationMetadataType.Query, selector, animation, options };
850
- }
851
- /**
852
- * Use within an animation `query()` call to issue a timing gap after
853
- * each queried item is animated.
854
- *
855
- * @param timings A delay value.
856
- * @param animation One ore more animation steps.
857
- * @returns An object that encapsulates the stagger data.
858
- *
859
- * @usageNotes
860
- * In the following example, a container element wraps a list of items stamped out
861
- * by an `ngFor`. The container element contains an animation trigger that will later be set
862
- * to query for each of the inner items.
863
- *
864
- * Each time items are added, the opacity fade-in animation runs,
865
- * and each removed item is faded out.
866
- * When either of these animations occur, the stagger effect is
867
- * applied after each item's animation is started.
868
- *
869
- * ```html
870
- * <!-- list.component.html -->
871
- * <button (click)="toggle()">Show / Hide Items</button>
872
- * <hr />
873
- * <div [@listAnimation]="items.length">
874
- * <div *ngFor="let item of items">
875
- * {{ item }}
876
- * </div>
877
- * </div>
878
- * ```
879
- *
880
- * Here is the component code:
881
- *
882
- * ```typescript
883
- * import {trigger, transition, style, animate, query, stagger} from '@angular/animations';
884
- * @Component({
885
- * templateUrl: 'list.component.html',
886
- * animations: [
887
- * trigger('listAnimation', [
888
- * ...
889
- * ])
890
- * ]
891
- * })
892
- * class ListComponent {
893
- * items = [];
894
- *
895
- * showItems() {
896
- * this.items = [0,1,2,3,4];
897
- * }
898
- *
899
- * hideItems() {
900
- * this.items = [];
901
- * }
902
- *
903
- * toggle() {
904
- * this.items.length ? this.hideItems() : this.showItems();
905
- * }
906
- * }
907
- * ```
908
- *
909
- * Here is the animation trigger code:
910
- *
911
- * ```typescript
912
- * trigger('listAnimation', [
913
- * transition('* => *', [ // each time the binding value changes
914
- * query(':leave', [
915
- * stagger(100, [
916
- * animate('0.5s', style({ opacity: 0 }))
917
- * ])
918
- * ]),
919
- * query(':enter', [
920
- * style({ opacity: 0 }),
921
- * stagger(100, [
922
- * animate('0.5s', style({ opacity: 1 }))
923
- * ])
924
- * ])
925
- * ])
926
- * ])
927
- * ```
928
- *
929
- * @publicApi
930
- */
931
- export function stagger(timings, animation) {
932
- return { type: AnimationMetadataType.Stagger, timings, animation };
933
- }
934
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uX21ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5pbWF0aW9ucy9zcmMvYW5pbWF0aW9uX21ldGFkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQXdGSDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFOLElBQVkscUJBa0VYO0FBbEVELFdBQVkscUJBQXFCO0lBQy9COzs7T0FHRztJQUNILG1FQUFTLENBQUE7SUFDVDs7O09BR0c7SUFDSCw2RUFBYyxDQUFBO0lBQ2Q7OztPQUdHO0lBQ0gseUVBQVksQ0FBQTtJQUNaOzs7T0FHRztJQUNILG1FQUFTLENBQUE7SUFDVDs7O09BR0c7SUFDSCx1RUFBVyxDQUFBO0lBQ1g7OztPQUdHO0lBQ0gsMkVBQWEsQ0FBQTtJQUNiOzs7T0FHRztJQUNILG1FQUFTLENBQUE7SUFDVDs7O09BR0c7SUFDSCx1RUFBVyxDQUFBO0lBQ1g7OztPQUdHO0lBQ0gsMkVBQWEsQ0FBQTtJQUNiOzs7T0FHRztJQUNILGlGQUFnQixDQUFBO0lBQ2hCOzs7T0FHRztJQUNILDhFQUFlLENBQUE7SUFDZjs7O09BR0c7SUFDSCxvRUFBVSxDQUFBO0lBQ1Y7OztPQUdHO0lBQ0gsd0VBQVksQ0FBQTtBQUNkLENBQUMsRUFsRVcscUJBQXFCLEtBQXJCLHFCQUFxQixRQWtFaEM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQztBQThSOUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1KRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQUMsSUFBWSxFQUFFLFdBQWdDO0lBQ3BFLE9BQU8sRUFBQyxJQUFJLEVBQUUscUJBQXFCLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBQyxDQUFDO0FBQy9FLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeURHO0FBQ0gsTUFBTSxVQUFVLE9BQU8sQ0FDckIsT0FBd0IsRUFDeEIsU0FBNkUsSUFBSTtJQUVqRixPQUFPLEVBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdDRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQ25CLEtBQTBCLEVBQzFCLFVBQW1DLElBQUk7SUFFdkMsT0FBTyxFQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDO0FBQzdELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFnQ0k7QUFDSixNQUFNLFVBQVUsUUFBUSxDQUN0QixLQUEwQixFQUMxQixVQUFtQyxJQUFJO0lBRXZDLE9BQU8sRUFBQyxJQUFJLEVBQUUscUJBQXFCLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUMsQ0FBQztBQUNoRSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBc0NJO0FBQ0osTUFBTSxVQUFVLEtBQUssQ0FDbkIsTUFBOEY7SUFFOUYsT0FBTyxFQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBNEJJO0FBQ0osTUFBTSxVQUFVLEtBQUssQ0FDbkIsSUFBWSxFQUNaLE1BQThCLEVBQzlCLE9BQXlDO0lBRXpDLE9BQU8sRUFBQyxJQUFJLEVBQUUscUJBQXFCLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFDLENBQUM7QUFDcEUsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRDRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBK0I7SUFDdkQsT0FBTyxFQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFDLENBQUM7QUFDeEQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBaUpJO0FBQ0osTUFBTSxVQUFVLFVBQVUsQ0FDeEIsZUFPaUIsRUFDakIsS0FBOEMsRUFDOUMsVUFBbUMsSUFBSTtJQUV2QyxPQUFPLEVBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFDLENBQUM7QUFDcEcsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRDRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQ3ZCLEtBQThDLEVBQzlDLFVBQW1DLElBQUk7SUFFdkMsT0FBTyxFQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUMsQ0FBQztBQUM1RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQzFCLFVBQXNDLElBQUk7SUFFMUMsT0FBTyxFQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQzFCLFNBQXFDLEVBQ3JDLFVBQW1DLElBQUk7SUFFdkMsT0FBTyxFQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBQyxDQUFDO0FBQ3RFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1SEc7QUFDSCxNQUFNLFVBQVUsS0FBSyxDQUNuQixRQUFnQixFQUNoQixTQUFrRCxFQUNsRCxVQUF3QyxJQUFJO0lBRTVDLE9BQU8sRUFBQyxJQUFJLEVBQUUscUJBQXFCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0VHO0FBQ0gsTUFBTSxVQUFVLE9BQU8sQ0FDckIsT0FBd0IsRUFDeEIsU0FBa0Q7SUFFbEQsT0FBTyxFQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBQyxDQUFDO0FBQ25FLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgc2V0IG9mIENTUyBzdHlsZXMgZm9yIHVzZSBpbiBhbiBhbmltYXRpb24gc3R5bGUgYXMgYSBnZW5lcmljLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIMm1U3R5bGVEYXRhIHtcbiAgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBzZXQgb2YgQ1NTIHN0eWxlcyBmb3IgdXNlIGluIGFuIGFuaW1hdGlvbiBzdHlsZSBhcyBhIE1hcC5cbiAqL1xuZXhwb3J0IHR5cGUgybVTdHlsZURhdGFNYXAgPSBNYXA8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXI+O1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYW5pbWF0aW9uLXN0ZXAgdGltaW5nIHBhcmFtZXRlcnMgZm9yIGFuIGFuaW1hdGlvbiBzdGVwLlxuICogQHNlZSB7QGxpbmsgYW5pbWF0ZX1cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBkZWNsYXJlIHR5cGUgQW5pbWF0ZVRpbWluZ3MgPSB7XG4gIC8qKlxuICAgKiBUaGUgZnVsbCBkdXJhdGlvbiBvZiBhbiBhbmltYXRpb24gc3RlcC4gQSBudW1iZXIgYW5kIG9wdGlvbmFsIHRpbWUgdW5pdCxcbiAgICogc3VjaCBhcyBcIjFzXCIgb3IgXCIxMG1zXCIgZm9yIG9uZSBzZWNvbmQgYW5kIDEwIG1pbGxpc2Vjb25kcywgcmVzcGVjdGl2ZWx5LlxuICAgKiBUaGUgZGVmYXVsdCB1bml0IGlzIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIGR1cmF0aW9uOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZGVsYXkgaW4gYXBwbHlpbmcgYW4gYW5pbWF0aW9uIHN0ZXAuIEEgbnVtYmVyIGFuZCBvcHRpb25hbCB0aW1lIHVuaXQuXG4gICAqIFRoZSBkZWZhdWx0IHVuaXQgaXMgbWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgZGVsYXk6IG51bWJlcjtcbiAgLyoqXG4gICAqIEFuIGVhc2luZyBzdHlsZSB0aGF0IGNvbnRyb2xzIGhvdyBhbiBhbmltYXRpb25zIHN0ZXAgYWNjZWxlcmF0ZXNcbiAgICogYW5kIGRlY2VsZXJhdGVzIGR1cmluZyBpdHMgcnVuIHRpbWUuIEFuIGVhc2luZyBmdW5jdGlvbiBzdWNoIGFzIGBjdWJpYy1iZXppZXIoKWAsXG4gICAqIG9yIG9uZSBvZiB0aGUgZm9sbG93aW5nIGNvbnN0YW50czpcbiAgICogLSBgZWFzZS1pbmBcbiAgICogLSBgZWFzZS1vdXRgXG4gICAqIC0gYGVhc2UtaW4tYW5kLW91dGBcbiAgICovXG4gIGVhc2luZzogc3RyaW5nIHwgbnVsbDtcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE9wdGlvbnMgdGhhdCBjb250cm9sIGFuaW1hdGlvbiBzdHlsaW5nIGFuZCB0aW1pbmcuXG4gKlxuICogVGhlIGZvbGxvd2luZyBhbmltYXRpb24gZnVuY3Rpb25zIGFjY2VwdCBgQW5pbWF0aW9uT3B0aW9uc2AgZGF0YTpcbiAqXG4gKiAtIGB0cmFuc2l0aW9uKClgXG4gKiAtIGBzZXF1ZW5jZSgpYFxuICogLSBge0BsaW5rIGFuaW1hdGlvbnMvZ3JvdXAgZ3JvdXAoKX1gXG4gKiAtIGBxdWVyeSgpYFxuICogLSBgYW5pbWF0aW9uKClgXG4gKiAtIGB1c2VBbmltYXRpb24oKWBcbiAqIC0gYGFuaW1hdGVDaGlsZCgpYFxuICpcbiAqIFByb2dyYW1tYXRpYyBhbmltYXRpb25zIGJ1aWx0IHVzaW5nIHRoZSBgQW5pbWF0aW9uQnVpbGRlcmAgc2VydmljZSBhbHNvXG4gKiBtYWtlIHVzZSBvZiBgQW5pbWF0aW9uT3B0aW9uc2AuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgQW5pbWF0aW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBTZXRzIGEgdGltZS1kZWxheSBmb3IgaW5pdGlhdGluZyBhbiBhbmltYXRpb24gYWN0aW9uLlxuICAgKiBBIG51bWJlciBhbmQgb3B0aW9uYWwgdGltZSB1bml0LCBzdWNoIGFzIFwiMXNcIiBvciBcIjEwbXNcIiBmb3Igb25lIHNlY29uZFxuICAgKiBhbmQgMTAgbWlsbGlzZWNvbmRzLCByZXNwZWN0aXZlbHkuVGhlIGRlZmF1bHQgdW5pdCBpcyBtaWxsaXNlY29uZHMuXG4gICAqIERlZmF1bHQgdmFsdWUgaXMgMCwgbWVhbmluZyBubyBkZWxheS5cbiAgICovXG4gIGRlbGF5PzogbnVtYmVyIHwgc3RyaW5nO1xuICAvKipcbiAgICogQSBzZXQgb2YgZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IG1vZGlmeSBzdHlsaW5nIGFuZCB0aW1pbmdcbiAgICogd2hlbiBhbiBhbmltYXRpb24gYWN0aW9uIHN0YXJ0cy4gQW4gYXJyYXkgb2Yga2V5LXZhbHVlIHBhaXJzLCB3aGVyZSB0aGUgcHJvdmlkZWQgdmFsdWVcbiAgICogaXMgdXNlZCBhcyBhIGRlZmF1bHQuXG4gICAqL1xuICBwYXJhbXM/OiB7W25hbWU6IHN0cmluZ106IGFueX07XG59XG5cbi8qKlxuICogQWRkcyBkdXJhdGlvbiBvcHRpb25zIHRvIGNvbnRyb2wgYW5pbWF0aW9uIHN0eWxpbmcgYW5kIHRpbWluZyBmb3IgYSBjaGlsZCBhbmltYXRpb24uXG4gKlxuICogQHNlZSB7QGxpbmsgYW5pbWF0ZUNoaWxkfVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIEFuaW1hdGVDaGlsZE9wdGlvbnMgZXh0ZW5kcyBBbmltYXRpb25PcHRpb25zIHtcbiAgZHVyYXRpb24/OiBudW1iZXIgfCBzdHJpbmc7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnN0YW50cyBmb3IgdGhlIGNhdGVnb3JpZXMgb2YgcGFyYW1ldGVycyB0aGF0IGNhbiBiZSBkZWZpbmVkIGZvciBhbmltYXRpb25zLlxuICpcbiAqIEEgY29ycmVzcG9uZGluZyBmdW5jdGlvbiBkZWZpbmVzIGEgc2V0IG9mIHBhcmFtZXRlcnMgZm9yIGVhY2ggY2F0ZWdvcnksIGFuZFxuICogY29sbGVjdHMgdGhlbSBpbnRvIGEgY29ycmVzcG9uZGluZyBgQW5pbWF0aW9uTWV0YWRhdGFgIG9iamVjdC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBlbnVtIEFuaW1hdGlvbk1ldGFkYXRhVHlwZSB7XG4gIC8qKlxuICAgKiBBc3NvY2lhdGVzIGEgbmFtZWQgYW5pbWF0aW9uIHN0YXRlIHdpdGggYSBzZXQgb2YgQ1NTIHN0eWxlcy5cbiAgICogU2VlIFtgc3RhdGUoKWBdKGFwaS9hbmltYXRpb25zL3N0YXRlKVxuICAgKi9cbiAgU3RhdGUgPSAwLFxuICAvKipcbiAgICogRGF0YSBmb3IgYSB0cmFuc2l0aW9uIGZyb20gb25lIGFuaW1hdGlvbiBzdGF0ZSB0byBhbm90aGVyLlxuICAgKiBTZWUgYHRyYW5zaXRpb24oKWBcbiAgICovXG4gIFRyYW5zaXRpb24gPSAxLFxuICAvKipcbiAgICogQ29udGFpbnMgYSBzZXQgb2YgYW5pbWF0aW9uIHN0ZXBzLlxuICAgKiBTZWUgYHNlcXVlbmNlKClgXG4gICAqL1xuICBTZXF1ZW5jZSA9IDIsXG4gIC8qKlxuICAgKiBDb250YWlucyBhIHNldCBvZiBhbmltYXRpb24gc3RlcHMuXG4gICAqIFNlZSBge0BsaW5rIGFuaW1hdGlvbnMvZ3JvdXAgZ3JvdXAoKX1gXG4gICAqL1xuICBHcm91cCA9IDMsXG4gIC8qKlxuICAgKiBDb250YWlucyBhbiBhbmltYXRpb24gc3RlcC5cbiAgICogU2VlIGBhbmltYXRlKClgXG4gICAqL1xuICBBbmltYXRlID0gNCxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgc2V0IG9mIGFuaW1hdGlvbiBzdGVwcy5cbiAgICogU2VlIGBrZXlmcmFtZXMoKWBcbiAgICovXG4gIEtleWZyYW1lcyA9IDUsXG4gIC8qKlxuICAgKiBDb250YWlucyBhIHNldCBvZiBDU1MgcHJvcGVydHktdmFsdWUgcGFpcnMgaW50byBhIG5hbWVkIHN0eWxlLlxuICAgKiBTZWUgYHN0eWxlKClgXG4gICAqL1xuICBTdHlsZSA9IDYsXG4gIC8qKlxuICAgKiBBc3NvY2lhdGVzIGFuIGFuaW1hdGlvbiB3aXRoIGFuIGVudHJ5IHRyaWdnZXIgdGhhdCBjYW4gYmUgYXR0YWNoZWQgdG8gYW4gZWxlbWVudC5cbiAgICogU2VlIGB0cmlnZ2VyKClgXG4gICAqL1xuICBUcmlnZ2VyID0gNyxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgcmUtdXNhYmxlIGFuaW1hdGlvbi5cbiAgICogU2VlIGBhbmltYXRpb24oKWBcbiAgICovXG4gIFJlZmVyZW5jZSA9IDgsXG4gIC8qKlxuICAgKiBDb250YWlucyBkYXRhIHRvIHVzZSBpbiBleGVjdXRpbmcgY2hpbGQgYW5pbWF0aW9ucyByZXR1cm5lZCBieSBhIHF1ZXJ5LlxuICAgKiBTZWUgYGFuaW1hdGVDaGlsZCgpYFxuICAgKi9cbiAgQW5pbWF0ZUNoaWxkID0gOSxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGFuaW1hdGlvbiBwYXJhbWV0ZXJzIGZvciBhIHJlLXVzYWJsZSBhbmltYXRpb24uXG4gICAqIFNlZSBgdXNlQW5pbWF0aW9uKClgXG4gICAqL1xuICBBbmltYXRlUmVmID0gMTAsXG4gIC8qKlxuICAgKiBDb250YWlucyBjaGlsZC1hbmltYXRpb24gcXVlcnkgZGF0YS5cbiAgICogU2VlIGBxdWVyeSgpYFxuICAgKi9cbiAgUXVlcnkgPSAxMSxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGRhdGEgZm9yIHN0YWdnZXJpbmcgYW4gYW5pbWF0aW9uIHNlcXVlbmNlLlxuICAgKiBTZWUgYHN0YWdnZXIoKWBcbiAgICovXG4gIFN0YWdnZXIgPSAxMixcbn1cblxuLyoqXG4gKiBTcGVjaWZpZXMgYXV0b21hdGljIHN0eWxpbmcuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY29uc3QgQVVUT19TVFlMRSA9ICcqJztcblxuLyoqXG4gKiBCYXNlIGZvciBhbmltYXRpb24gZGF0YSBzdHJ1Y3R1cmVzLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25NZXRhZGF0YSB7XG4gIHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZTtcbn1cblxuLyoqXG4gKiBDb250YWlucyBhbiBhbmltYXRpb24gdHJpZ2dlci4gSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGVcbiAqIGB0cmlnZ2VyKClgIGZ1bmN0aW9uLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25UcmlnZ2VyTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBUaGUgdHJpZ2dlciBuYW1lLCB1c2VkIHRvIGFzc29jaWF0ZSBpdCB3aXRoIGFuIGVsZW1lbnQuIFVuaXF1ZSB3aXRoaW4gdGhlIGNvbXBvbmVudC5cbiAgICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEFuIGFuaW1hdGlvbiBkZWZpbml0aW9uIG9iamVjdCwgY29udGFpbmluZyBhbiBhcnJheSBvZiBzdGF0ZSBhbmQgdHJhbnNpdGlvbiBkZWNsYXJhdGlvbnMuXG4gICAqL1xuICBkZWZpbml0aW9uczogQW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAgICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAgICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi4gRGVmYXVsdCBkZWxheSBpcyAwLlxuICAgKi9cbiAgb3B0aW9uczoge3BhcmFtcz86IHtbbmFtZTogc3RyaW5nXTogYW55fX0gfCBudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhbiBhbmltYXRpb24gc3RhdGUgYnkgYXNzb2NpYXRpbmcgYSBzdGF0ZSBuYW1lIHdpdGggYSBzZXQgb2YgQ1NTIHN0eWxlcy5cbiAqIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnkgdGhlIFtgc3RhdGUoKWBdKGFwaS9hbmltYXRpb25zL3N0YXRlKSBmdW5jdGlvbi5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uU3RhdGVNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIFRoZSBzdGF0ZSBuYW1lLCB1bmlxdWUgd2l0aGluIHRoZSBjb21wb25lbnQuXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiAgVGhlIENTUyBzdHlsZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3RhdGUuXG4gICAqL1xuICBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGE7XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uXG4gICAqL1xuICBvcHRpb25zPzoge3BhcmFtczoge1tuYW1lOiBzdHJpbmddOiBhbnl9fTtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIHRyYW5zaXRpb24uIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnkgdGhlXG4gKiBgdHJhbnNpdGlvbigpYCBmdW5jdGlvbi5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uVHJhbnNpdGlvbk1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogQW4gZXhwcmVzc2lvbiB0aGF0IGRlc2NyaWJlcyBhIHN0YXRlIGNoYW5nZS5cbiAgICovXG4gIGV4cHI6XG4gICAgfCBzdHJpbmdcbiAgICB8ICgoXG4gICAgICAgIGZyb21TdGF0ZTogc3RyaW5nLFxuICAgICAgICB0b1N0YXRlOiBzdHJpbmcsXG4gICAgICAgIGVsZW1lbnQ/OiBhbnksXG4gICAgICAgIHBhcmFtcz86IHtba2V5OiBzdHJpbmddOiBhbnl9LFxuICAgICAgKSA9PiBib29sZWFuKTtcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBvYmplY3RzIHRvIHdoaWNoIHRoaXMgdHJhbnNpdGlvbiBhcHBsaWVzLlxuICAgKi9cbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW107XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGEgZGVsYXkgYW5kXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uIERlZmF1bHQgZGVsYXkgaXMgMC5cbiAgICovXG4gIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhIHJldXNhYmxlIGFuaW1hdGlvbiwgd2hpY2ggaXMgYSBjb2xsZWN0aW9uIG9mIGluZGl2aWR1YWwgYW5pbWF0aW9uIHN0ZXBzLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYGFuaW1hdGlvbigpYCBmdW5jdGlvbiwgYW5kXG4gKiBwYXNzZWQgdG8gdGhlIGB1c2VBbmltYXRpb24oKWAgZnVuY3Rpb24uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblJlZmVyZW5jZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBzdGVwIG9iamVjdHMuXG4gICAqL1xuICBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAgICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAgICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi4gRGVmYXVsdCBkZWxheSBpcyAwLlxuICAgKi9cbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFuIGFuaW1hdGlvbiBxdWVyeS4gSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieVxuICogdGhlIGBxdWVyeSgpYCBmdW5jdGlvbi5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uUXVlcnlNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqICBUaGUgQ1NTIHNlbGVjdG9yIGZvciB0aGlzIHF1ZXJ5LlxuICAgKi9cbiAgc2VsZWN0b3I6IHN0cmluZztcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBzdGVwIG9iamVjdHMuXG4gICAqL1xuICBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgLyoqXG4gICAqIEEgcXVlcnkgb3B0aW9ucyBvYmplY3QuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25RdWVyeU9wdGlvbnMgfCBudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhIGtleWZyYW1lcyBzZXF1ZW5jZS4gSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieVxuICogdGhlIGBrZXlmcmFtZXMoKWAgZnVuY3Rpb24uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBhbmltYXRpb24gc3R5bGVzLlxuICAgKi9cbiAgc3RlcHM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGFbXTtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIHN0eWxlLiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5XG4gKiB0aGUgYHN0eWxlKClgIGZ1bmN0aW9uLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25TdHlsZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogQSBzZXQgb2YgQ1NTIHN0eWxlIHByb3BlcnRpZXMuXG4gICAqL1xuICBzdHlsZXM6ICcqJyB8IHtba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJ9IHwgQXJyYXk8e1trZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlcn0gfCAnKic+O1xuICAvKipcbiAgICogQSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBhbmltYXRlIHRpbWUgYXQgd2hpY2ggdGhlIHN0eWxlIGlzIHRvIGJlIGFwcGxpZWQuXG4gICAqL1xuICBvZmZzZXQ6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFuIGFuaW1hdGlvbiBzdGVwLiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5XG4gKiB0aGUgYGFuaW1hdGUoKWAgZnVuY3Rpb24uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIFRoZSB0aW1pbmcgZGF0YSBmb3IgdGhlIHN0ZXAuXG4gICAqL1xuICB0aW1pbmdzOiBzdHJpbmcgfCBudW1iZXIgfCBBbmltYXRlVGltaW5ncztcbiAgLyoqXG4gICAqIEEgc2V0IG9mIHN0eWxlcyB1c2VkIGluIHRoZSBzdGVwLlxuICAgKi9cbiAgc3R5bGVzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhIHwgQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSB8IG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGEgY2hpbGQgYW5pbWF0aW9uLCB0aGF0IGNhbiBiZSBydW4gZXhwbGljaXRseSB3aGVuIHRoZSBwYXJlbnQgaXMgcnVuLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYGFuaW1hdGVDaGlsZGAgZnVuY3Rpb24uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVDaGlsZE1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYSByZXVzYWJsZSBhbmltYXRpb24uXG4gKiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZSBgdXNlQW5pbWF0aW9uKClgIGZ1bmN0aW9uLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25BbmltYXRlUmVmTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBBbiBhbmltYXRpb24gcmVmZXJlbmNlIG9iamVjdC5cbiAgICovXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGE7XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGEgZGVsYXkgYW5kXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uIERlZmF1bHQgZGVsYXkgaXMgMC5cbiAgICovXG4gIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhbiBhbmltYXRpb24gc2VxdWVuY2UuXG4gKiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZSBgc2VxdWVuY2UoKWAgZnVuY3Rpb24uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblNlcXVlbmNlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiAgQW4gYXJyYXkgb2YgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAgICovXG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIGdyb3VwLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YCBmdW5jdGlvbi5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uR3JvdXBNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBvciBzdHlsZSBzdGVwcyB0aGF0IGZvcm0gdGhpcyBncm91cC5cbiAgICovXG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW5pbWF0aW9uIHF1ZXJ5IG9wdGlvbnMuXG4gKiBQYXNzZWQgdG8gdGhlIGBxdWVyeSgpYCBmdW5jdGlvbi5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBBbmltYXRpb25RdWVyeU9wdGlvbnMgZXh0ZW5kcyBBbmltYXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRydWUgaWYgdGhpcyBxdWVyeSBpcyBvcHRpb25hbCwgZmFsc2UgaWYgaXQgaXMgcmVxdWlyZWQuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqIEEgcmVxdWlyZWQgcXVlcnkgdGhyb3dzIGFuIGVycm9yIGlmIG5vIGVsZW1lbnRzIGFyZSByZXRyaWV2ZWQgd2hlblxuICAgKiB0aGUgcXVlcnkgaXMgZXhlY3V0ZWQuIEFuIG9wdGlvbmFsIHF1ZXJ5IGRvZXMgbm90LlxuICAgKlxuICAgKi9cbiAgb3B0aW9uYWw/OiBib29sZWFuO1xuICAvKipcbiAgICogQSBtYXhpbXVtIHRvdGFsIG51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybiBmcm9tIHRoZSBxdWVyeS5cbiAgICogSWYgbmVnYXRpdmUsIHJlc3VsdHMgYXJlIGxpbWl0ZWQgZnJvbSB0aGUgZW5kIG9mIHRoZSBxdWVyeSBsaXN0IHRvd2FyZHMgdGhlIGJlZ2lubmluZy5cbiAgICogQnkgZGVmYXVsdCwgcmVzdWx0cyBhcmUgbm90IGxpbWl0ZWQuXG4gICAqL1xuICBsaW1pdD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgcGFyYW1ldGVycyBmb3Igc3RhZ2dlcmluZyB0aGUgc3RhcnQgdGltZXMgb2YgYSBzZXQgb2YgYW5pbWF0aW9uIHN0ZXBzLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYHN0YWdnZXIoKWAgZnVuY3Rpb24uXG4gKlxuICogQHB1YmxpY0FwaVxuICoqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25TdGFnZ2VyTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBUaGUgdGltaW5nIGRhdGEgZm9yIHRoZSBzdGVwcy5cbiAgICovXG4gIHRpbWluZ3M6IHN0cmluZyB8IG51bWJlcjtcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBzdGVwcy5cbiAgICovXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGEgfCBBbmltYXRpb25NZXRhZGF0YVtdO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuYW1lZCBhbmltYXRpb24gdHJpZ2dlciwgY29udGFpbmluZyBhICBsaXN0IG9mIFtgc3RhdGUoKWBdKGFwaS9hbmltYXRpb25zL3N0YXRlKVxuICogYW5kIGB0cmFuc2l0aW9uKClgIGVudHJpZXMgdG8gYmUgZXZhbHVhdGVkIHdoZW4gdGhlIGV4cHJlc3Npb25cbiAqIGJvdW5kIHRvIHRoZSB0cmlnZ2VyIGNoYW5nZXMuXG4gKlxuICogQHBhcmFtIG5hbWUgQW4gaWRlbnRpZnlpbmcgc3RyaW5nLlxuICogQHBhcmFtIGRlZmluaXRpb25zICBBbiBhbmltYXRpb24gZGVmaW5pdGlvbiBvYmplY3QsIGNvbnRhaW5pbmcgYW4gYXJyYXkgb2ZcbiAqIFtgc3RhdGUoKWBdKGFwaS9hbmltYXRpb25zL3N0YXRlKSBhbmQgYHRyYW5zaXRpb24oKWAgZGVjbGFyYXRpb25zLlxuICpcbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSB0cmlnZ2VyIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIERlZmluZSBhbiBhbmltYXRpb24gdHJpZ2dlciBpbiB0aGUgYGFuaW1hdGlvbnNgIHNlY3Rpb24gb2YgYEBDb21wb25lbnRgIG1ldGFkYXRhLlxuICogSW4gdGhlIHRlbXBsYXRlLCByZWZlcmVuY2UgdGhlIHRyaWdnZXIgYnkgbmFtZSBhbmQgYmluZCBpdCB0byBhIHRyaWdnZXIgZXhwcmVzc2lvbiB0aGF0XG4gKiBldmFsdWF0ZXMgdG8gYSBkZWZpbmVkIGFuaW1hdGlvbiBzdGF0ZSwgdXNpbmcgdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gKlxuICogYFtAdHJpZ2dlck5hbWVdPVwiZXhwcmVzc2lvblwiYFxuICpcbiAqIEFuaW1hdGlvbiB0cmlnZ2VyIGJpbmRpbmdzIGNvbnZlcnQgYWxsIHZhbHVlcyB0byBzdHJpbmdzLCBhbmQgdGhlbiBtYXRjaCB0aGVcbiAqIHByZXZpb3VzIGFuZCBjdXJyZW50IHZhbHVlcyBhZ2FpbnN0IGFueSBsaW5rZWQgdHJhbnNpdGlvbnMuXG4gKiBCb29sZWFucyBjYW4gYmUgc3BlY2lmaWVkIGFzIGAxYCBvciBgdHJ1ZWAgYW5kIGAwYCBvciBgZmFsc2VgLlxuICpcbiAqICMjIyBVc2FnZSBFeGFtcGxlXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIGNyZWF0ZXMgYW4gYW5pbWF0aW9uIHRyaWdnZXIgcmVmZXJlbmNlIGJhc2VkIG9uIHRoZSBwcm92aWRlZFxuICogbmFtZSB2YWx1ZS5cbiAqIFRoZSBwcm92aWRlZCBhbmltYXRpb24gdmFsdWUgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXkgY29uc2lzdGluZyBvZiBzdGF0ZSBhbmRcbiAqIHRyYW5zaXRpb24gZGVjbGFyYXRpb25zLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogXCJteS1jb21wb25lbnRcIixcbiAqICAgdGVtcGxhdGVVcmw6IFwibXktY29tcG9uZW50LXRwbC5odG1sXCIsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKFwibXlBbmltYXRpb25UcmlnZ2VyXCIsIFtcbiAqICAgICAgIHN0YXRlKC4uLiksXG4gKiAgICAgICBzdGF0ZSguLi4pLFxuICogICAgICAgdHJhbnNpdGlvbiguLi4pLFxuICogICAgICAgdHJhbnNpdGlvbiguLi4pXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgbXlTdGF0dXNFeHAgPSBcInNvbWV0aGluZ1wiO1xuICogfVxuICogYGBgXG4gKlxuICogVGhlIHRlbXBsYXRlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbXBvbmVudCBtYWtlcyB1c2Ugb2YgdGhlIGRlZmluZWQgdHJpZ2dlclxuICogYnkgYmluZGluZyB0byBhbiBlbGVtZW50IHdpdGhpbiBpdHMgdGVtcGxhdGUgY29kZS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8IS0tIHNvbWV3aGVyZSBpbnNpZGUgb2YgbXktY29tcG9uZW50LXRwbC5odG1sIC0tPlxuICogPGRpdiBbQG15QW5pbWF0aW9uVHJpZ2dlcl09XCJteVN0YXR1c0V4cFwiPi4uLjwvZGl2PlxuICogYGBgXG4gKlxuICogIyMjIFVzaW5nIGFuIGlubGluZSBmdW5jdGlvblxuICogVGhlIGB0cmFuc2l0aW9uYCBhbmltYXRpb24gbWV0aG9kIGFsc28gc3VwcG9ydHMgcmVhZGluZyBhbiBpbmxpbmUgZnVuY3Rpb24gd2hpY2ggY2FuIGRlY2lkZVxuICogaWYgaXRzIGFzc29jaWF0ZWQgYW5pbWF0aW9uIHNob3VsZCBiZSBydW4uXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gdGhpcyBtZXRob2QgaXMgcnVuIGVhY2ggdGltZSB0aGUgYG15QW5pbWF0aW9uVHJpZ2dlcmAgdHJpZ2dlciB2YWx1ZSBjaGFuZ2VzLlxuICogZnVuY3Rpb24gbXlJbmxpbmVNYXRjaGVyRm4oZnJvbVN0YXRlOiBzdHJpbmcsIHRvU3RhdGU6IHN0cmluZywgZWxlbWVudDogYW55LCBwYXJhbXM6IHtba2V5OlxuIHN0cmluZ106IGFueX0pOiBib29sZWFuIHtcbiAqICAgLy8gbm90aWNlIHRoYXQgYGVsZW1lbnRgIGFuZCBgcGFyYW1zYCBhcmUgYWxzbyBhdmFpbGFibGUgaGVyZVxuICogICByZXR1cm4gdG9TdGF0ZSA9PSAneWVzLXBsZWFzZS1hbmltYXRlJztcbiAqIH1cbiAqXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdteS1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZVVybDogJ215LWNvbXBvbmVudC10cGwuaHRtbCcsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKCdteUFuaW1hdGlvblRyaWdnZXInLCBbXG4gKiAgICAgICB0cmFuc2l0aW9uKG15SW5saW5lTWF0Y2hlckZuLCBbXG4gKiAgICAgICAgIC8vIHRoZSBhbmltYXRpb24gc2VxdWVuY2UgY29kZVxuICogICAgICAgXSksXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgbXlTdGF0dXNFeHAgPSBcInllcy1wbGVhc2UtYW5pbWF0ZVwiO1xuICogfVxuICogYGBgXG4gKlxuICogIyMjIERpc2FibGluZyBBbmltYXRpb25zXG4gKiBXaGVuIHRydWUsIHRoZSBzcGVjaWFsIGFuaW1hdGlvbiBjb250cm9sIGJpbmRpbmcgYEAuZGlzYWJsZWRgIGJpbmRpbmcgcHJldmVudHNcbiAqIGFsbCBhbmltYXRpb25zIGZyb20gcmVuZGVyaW5nLlxuICogUGxhY2UgdGhlICBgQC5kaXNhYmxlZGAgYmluZGluZyBvbiBhbiBlbGVtZW50IHRvIGRpc2FibGVcbiAqIGFuaW1hdGlvbnMgb24gdGhlIGVsZW1lbnQgaXRzZWxmLCBhcyB3ZWxsIGFzIGFueSBpbm5lciBhbmltYXRpb24gdHJpZ2dlcnNcbiAqIHdpdGhpbiB0aGUgZWxlbWVudC5cbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgaG93IHRvIHVzZSB0aGlzIGZlYXR1cmU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnbXktY29tcG9uZW50JyxcbiAqICAgdGVtcGxhdGU6IGBcbiAqICAgICA8ZGl2IFtALmRpc2FibGVkXT1cImlzRGlzYWJsZWRcIj5cbiAqICAgICAgIDxkaXYgW0BjaGlsZEFuaW1hdGlvbl09XCJleHBcIj48L2Rpdj5cbiAqICAgICA8L2Rpdj5cbiAqICAgYCxcbiAqICAgYW5pbWF0aW9uczogW1xuICogICAgIHRyaWdnZXIoXCJjaGlsZEFuaW1hdGlvblwiLCBbXG4gKiAgICAgICAvLyAuLi5cbiAqICAgICBdKVxuICogICBdXG4gKiB9KVxuICogY2xhc3MgTXlDb21wb25lbnQge1xuICogICBpc0Rpc2FibGVkID0gdHJ1ZTtcbiAqICAgZXhwID0gJy4uLic7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBXaGVuIGBALmRpc2FibGVkYCBpcyB0cnVlLCBpdCBwcmV2ZW50cyB0aGUgYEBjaGlsZEFuaW1hdGlvbmAgdHJpZ2dlciBmcm9tIGFuaW1hdGluZyxcbiAqIGFsb25nIHdpdGggYW55IGlubmVyIGFuaW1hdGlvbnMuXG4gKlxuICogIyMjIERpc2FibGUgYW5pbWF0aW9ucyBhcHBsaWNhdGlvbi13aWRlXG4gKiBXaGVuIGFuIGFyZWEgb2YgdGhlIHRlbXBsYXRlIGlzIHNldCB0byBoYXZlIGFuaW1hdGlvbnMgZGlzYWJsZWQsXG4gKiAqKmFsbCoqIGlubmVyIGNvbXBvbmVudHMgaGF2ZSB0aGVpciBhbmltYXRpb25zIGRpc2FibGVkIGFzIHdlbGwuXG4gKiBUaGlzIG1lYW5zIHRoYXQgeW91IGNhbiBkaXNhYmxlIGFsbCBhbmltYXRpb25zIGZvciBhbiBhcHBcbiAqIGJ5IHBsYWNpbmcgYSBob3N0IGJpbmRpbmcgc2V0IG9uIGBALmRpc2FibGVkYCBvbiB0aGUgdG9wbW9zdCBBbmd1bGFyIGNvbXBvbmVudC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQge0NvbXBvbmVudCwgSG9zdEJpbmRpbmd9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuICpcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2FwcC1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZVVybDogJ2FwcC5jb21wb25lbnQuaHRtbCcsXG4gKiB9KVxuICogY2xhc3MgQXBwQ29tcG9uZW50IHtcbiAqICAgQEhvc3RCaW5kaW5nKCdALmRpc2FibGVkJylcbiAqICAgcHVibGljIGFuaW1hdGlvbnNEaXNhYmxlZCA9IHRydWU7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMgT3ZlcnJpZGluZyBkaXNhYmxlbWVudCBvZiBpbm5lciBhbmltYXRpb25zXG4gKiBEZXNwaXRlIGlubmVyIGFuaW1hdGlvbnMgYmVpbmcgZGlzYWJsZWQsIGEgcGFyZW50IGFuaW1hdGlvbiBjYW4gYHF1ZXJ5KClgXG4gKiBmb3IgaW5uZXIgZWxlbWVudHMgbG9jYXRlZCBpbiBkaXNhYmxlZCBhcmVhcyBvZiB0aGUgdGVtcGxhdGUgYW5kIHN0aWxsIGFuaW1hdGVcbiAqIHRoZW0gaWYgbmVlZGVkLiBUaGlzIGlzIGFsc28gdGhlIGNhc2UgZm9yIHdoZW4gYSBzdWIgYW5pbWF0aW9uIGlzXG4gKiBxdWVyaWVkIGJ5IGEgcGFyZW50IGFuZCB0aGVuIGxhdGVyIGFuaW1hdGVkIHVzaW5nIGBhbmltYXRlQ2hpbGQoKWAuXG4gKlxuICogIyMjIERldGVjdGluZyB3aGVuIGFuIGFuaW1hdGlvbiBpcyBkaXNhYmxlZFxuICogSWYgYSByZWdpb24gb2YgdGhlIERPTSAob3IgdGhlIGVudGlyZSBhcHBsaWNhdGlvbikgaGFzIGl0cyBhbmltYXRpb25zIGRpc2FibGVkLCB0aGUgYW5pbWF0aW9uXG4gKiB0cmlnZ2VyIGNhbGxiYWNrcyBzdGlsbCBmaXJlLCBidXQgZm9yIHplcm8gc2Vjb25kcy4gV2hlbiB0aGUgY2FsbGJhY2sgZmlyZXMsIGl0IHByb3ZpZGVzXG4gKiBhbiBpbnN0YW5jZSBvZiBhbiBgQW5pbWF0aW9uRXZlbnRgLiBJZiBhbmltYXRpb25zIGFyZSBkaXNhYmxlZCxcbiAqIHRoZSBgLmRpc2FibGVkYCBmbGFnIG9uIHRoZSBldmVudCBpcyB0cnVlLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXIobmFtZTogc3RyaW5nLCBkZWZpbml0aW9uczogQW5pbWF0aW9uTWV0YWRhdGFbXSk6IEFuaW1hdGlvblRyaWdnZXJNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlRyaWdnZXIsIG5hbWUsIGRlZmluaXRpb25zLCBvcHRpb25zOiB7fX07XG59XG5cbi8qKlxuICogRGVmaW5lcyBhbiBhbmltYXRpb24gc3RlcCB0aGF0IGNvbWJpbmVzIHN0eWxpbmcgaW5mb3JtYXRpb24gd2l0aCB0aW1pbmcgaW5mb3JtYXRpb24uXG4gKlxuICogQHBhcmFtIHRpbWluZ3MgU2V0cyBgQW5pbWF0ZVRpbWluZ3NgIGZvciB0aGUgcGFyZW50IGFuaW1hdGlvbi5cbiAqIEEgc3RyaW5nIGluIHRoZSBmb3JtYXQgXCJkdXJhdGlvbiBbZGVsYXldIFtlYXNpbmddXCIuXG4gKiAgLSBEdXJhdGlvbiBhbmQgZGVsYXkgYXJlIGV4cHJlc3NlZCBhcyBhIG51bWJlciBhbmQgb3B0aW9uYWwgdGltZSB1bml0LFxuICogc3VjaCBhcyBcIjFzXCIgb3IgXCIxMG1zXCIgZm9yIG9uZSBzZWNvbmQgYW5kIDEwIG1pbGxpc2Vjb25kcywgcmVzcGVjdGl2ZWx5LlxuICogVGhlIGRlZmF1bHQgdW5pdCBpcyBtaWxsaXNlY29uZHMuXG4gKiAgLSBUaGUgZWFzaW5nIHZhbHVlIGNvbnRyb2xzIGhvdyB0aGUgYW5pbWF0aW9uIGFjY2VsZXJhdGVzIGFuZCBkZWNlbGVyYXRlc1xuICogZHVyaW5nIGl0cyBydW50aW1lLiBWYWx1ZSBpcyBvbmUgb2YgIGBlYXNlYCwgYGVhc2UtaW5gLCBgZWFzZS1vdXRgLFxuICogYGVhc2UtaW4tb3V0YCwgb3IgYSBgY3ViaWMtYmV6aWVyKClgIGZ1bmN0aW9uIGNhbGwuXG4gKiBJZiBub3Qgc3VwcGxpZWQsIG5vIGVhc2luZyBpcyBhcHBsaWVkLlxuICpcbiAqIEZvciBleGFtcGxlLCB0aGUgc3RyaW5nIFwiMXMgMTAwbXMgZWFzZS1vdXRcIiBzcGVjaWZpZXMgYSBkdXJhdGlvbiBvZlxuICogMTAwMCBtaWxsaXNlY29uZHMsIGFuZCBkZWxheSBvZiAxMDAgbXMsIGFuZCB0aGUgXCJlYXNlLW91dFwiIGVhc2luZyBzdHlsZSxcbiAqIHdoaWNoIGRlY2VsZXJhdGVzIG5lYXIgdGhlIGVuZCBvZiB0aGUgZHVyYXRpb24uXG4gKiBAcGFyYW0gc3R5bGVzIFNldHMgQW5pbWF0aW9uU3R5bGVzIGZvciB0aGUgcGFyZW50IGFuaW1hdGlvbi5cbiAqIEEgZnVuY3Rpb24gY2FsbCB0byBlaXRoZXIgYHN0eWxlKClgIG9yIGBrZXlmcmFtZXMoKWBcbiAqIHRoYXQgcmV0dXJucyBhIGNvbGxlY3Rpb24gb2YgQ1NTIHN0eWxlIGVudHJpZXMgdG8gYmUgYXBwbGllZCB0byB0aGUgcGFyZW50IGFuaW1hdGlvbi5cbiAqIFdoZW4gbnVsbCwgdXNlcyB0aGUgc3R5bGVzIGZyb20gdGhlIGRlc3RpbmF0aW9uIHN0YXRlLlxuICogVGhpcyBpcyB1c2VmdWwgd2hlbiBkZXNjcmliaW5nIGFuIGFuaW1hdGlvbiBzdGVwIHRoYXQgd2lsbCBjb21wbGV0ZSBhbiBhbmltYXRpb247XG4gKiBzZWUgXCJBbmltYXRpbmcgdG8gdGhlIGZpbmFsIHN0YXRlXCIgaW4gYHRyYW5zaXRpb25zKClgLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBhbmltYXRpb24gc3RlcC5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogQ2FsbCB3aXRoaW4gYW4gYW5pbWF0aW9uIGBzZXF1ZW5jZSgpYCwgYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YCwgb3JcbiAqIGB0cmFuc2l0aW9uKClgIGNhbGwgdG8gc3BlY2lmeSBhbiBhbmltYXRpb24gc3RlcFxuICogdGhhdCBhcHBsaWVzIGdpdmVuIHN0eWxlIGRhdGEgdG8gdGhlIHBhcmVudCBhbmltYXRpb24gZm9yIGEgZ2l2ZW4gYW1vdW50IG9mIHRpbWUuXG4gKlxuICogIyMjIFN5bnRheCBFeGFtcGxlc1xuICogKipUaW1pbmcgZXhhbXBsZXMqKlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZXMgc2hvdyB2YXJpb3VzIGB0aW1pbmdzYCBzcGVjaWZpY2F0aW9ucy5cbiAqIC0gYGFuaW1hdGUoNTAwKWAgOiBEdXJhdGlvbiBpcyA1MDAgbWlsbGlzZWNvbmRzLlxuICogLSBgYW5pbWF0ZShcIjFzXCIpYCA6IER1cmF0aW9uIGlzIDEwMDAgbWlsbGlzZWNvbmRzLlxuICogLSBgYW5pbWF0ZShcIjEwMG1zIDAuNXNcIilgIDogRHVyYXRpb24gaXMgMTAwIG1pbGxpc2Vjb25kcywgZGVsYXkgaXMgNTAwIG1pbGxpc2Vjb25kcy5cbiAqIC0gYGFuaW1hdGUoXCI1cyBlYXNlLWluXCIpYCA6IER1cmF0aW9uIGlzIDUwMDAgbWlsbGlzZWNvbmRzLCBlYXNpbmcgaW4uXG4gKiAtIGBhbmltYXRlKFwiNXMgMTBtcyBjdWJpYy1iZXppZXIoLjE3LC42NywuODgsLjEpXCIpYCA6IER1cmF0aW9uIGlzIDUwMDAgbWlsbGlzZWNvbmRzLCBkZWxheSBpcyAxMFxuICogbWlsbGlzZWNvbmRzLCBlYXNpbmcgYWNjb3JkaW5nIHRvIGEgYmV6aWVyIGN1cnZlLlxuICpcbiAqICoqU3R5bGUgZXhhbXBsZXMqKlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjYWxscyBgc3R5bGUoKWAgdG8gc2V0IGEgc2luZ2xlIENTUyBzdHlsZS5cbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGFuaW1hdGUoNTAwLCBzdHlsZSh7IGJhY2tncm91bmQ6IFwicmVkXCIgfSkpXG4gKiBgYGBcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjYWxscyBga2V5ZnJhbWVzKClgIHRvIHNldCBhIENTUyBzdHlsZVxuICogdG8gZGlmZmVyZW50IHZhbHVlcyBmb3Igc3VjY2Vzc2l2ZSBrZXlmcmFtZXMuXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBhbmltYXRlKDUwMCwga2V5ZnJhbWVzKFxuICogIFtcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcImJsdWVcIiB9KSxcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcInJlZFwiIH0pXG4gKiAgXSlcbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuaW1hdGUoXG4gIHRpbWluZ3M6IHN0cmluZyB8IG51bWJlcixcbiAgc3R5bGVzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhIHwgQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSB8IG51bGwgPSBudWxsLFxuKTogQW5pbWF0aW9uQW5pbWF0ZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuQW5pbWF0ZSwgc3R5bGVzLCB0aW1pbmdzfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmaW5lcyBhIGxpc3Qgb2YgYW5pbWF0aW9uIHN0ZXBzIHRvIGJlIHJ1biBpbiBwYXJhbGxlbC5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgQW4gYXJyYXkgb2YgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAqIC0gV2hlbiBzdGVwcyBhcmUgZGVmaW5lZCBieSBgc3R5bGUoKWAgb3IgYGFuaW1hdGUoKWBcbiAqIGZ1bmN0aW9uIGNhbGxzLCBlYWNoIGNhbGwgd2l0aGluIHRoZSBncm91cCBpcyBleGVjdXRlZCBpbnN0YW50bHkuXG4gKiAtIFRvIHNwZWNpZnkgb2Zmc2V0IHN0eWxlcyB0byBiZSBhcHBsaWVkIGF0IGEgbGF0ZXIgdGltZSwgZGVmaW5lIHN0ZXBzIHdpdGhcbiAqIGBrZXlmcmFtZXMoKWAsIG9yIHVzZSBgYW5pbWF0ZSgpYCBjYWxscyB3aXRoIGEgZGVsYXkgdmFsdWUuXG4gKiBGb3IgZXhhbXBsZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBncm91cChbXG4gKiAgIGFuaW1hdGUoXCIxc1wiLCBzdHlsZSh7IGJhY2tncm91bmQ6IFwiYmxhY2tcIiB9KSksXG4gKiAgIGFuaW1hdGUoXCIyc1wiLCBzdHlsZSh7IGNvbG9yOiBcIndoaXRlXCIgfSkpXG4gKiBdKVxuICogYGBgXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uXG4gKlxuICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIGdyb3VwIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIEdyb3VwZWQgYW5pbWF0aW9ucyBhcmUgdXNlZnVsIHdoZW4gYSBzZXJpZXMgb2Ygc3R5bGVzIG11c3QgYmVcbiAqIGFuaW1hdGVkIGF0IGRpZmZlcmVudCBzdGFydGluZyB0aW1lcyBhbmQgY2xvc2VkIG9mZiBhdCBkaWZmZXJlbnQgZW5kaW5nIHRpbWVzLlxuICpcbiAqIFdoZW4gY2FsbGVkIHdpdGhpbiBhIGBzZXF1ZW5jZSgpYCBvciBhXG4gKiBgdHJhbnNpdGlvbigpYCBjYWxsLCBkb2VzIG5vdCBjb250aW51ZSB0byB0aGUgbmV4dFxuICogaW5zdHJ1Y3Rpb24gdW50aWwgYWxsIG9mIHRoZSBpbm5lciBhbmltYXRpb24gc3RlcHMgaGF2ZSBjb21wbGV0ZWQuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXAoXG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdLFxuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwsXG4pOiBBbmltYXRpb25Hcm91cE1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuR3JvdXAsIHN0ZXBzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIGEgbGlzdCBvZiBhbmltYXRpb24gc3RlcHMgdG8gYmUgcnVuIHNlcXVlbnRpYWxseSwgb25lIGJ5IG9uZS5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgQW4gYXJyYXkgb2YgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAqIC0gU3RlcHMgZGVmaW5lZCBieSBgc3R5bGUoKWAgY2FsbHMgYXBwbHkgdGhlIHN0eWxpbmcgZGF0YSBpbW1lZGlhdGVseS5cbiAqIC0gU3RlcHMgZGVmaW5lZCBieSBgYW5pbWF0ZSgpYCBjYWxscyBhcHBseSB0aGUgc3R5bGluZyBkYXRhIG92ZXIgdGltZVxuICogICBhcyBzcGVjaWZpZWQgYnkgdGhlIHRpbWluZyBkYXRhLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHNlcXVlbmNlKFtcbiAqICAgc3R5bGUoeyBvcGFjaXR5OiAwIH0pLFxuICogICBhbmltYXRlKFwiMXNcIiwgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLlxuICpcbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBzZXF1ZW5jZSBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBXaGVuIHlvdSBwYXNzIGFuIGFycmF5IG9mIHN0ZXBzIHRvIGFcbiAqIGB0cmFuc2l0aW9uKClgIGNhbGwsIHRoZSBzdGVwcyBydW4gc2VxdWVudGlhbGx5IGJ5IGRlZmF1bHQuXG4gKiBDb21wYXJlIHRoaXMgdG8gdGhlIGB7QGxpbmsgYW5pbWF0aW9ucy9ncm91cCBncm91cCgpfWAgY2FsbCwgd2hpY2ggcnVucyBhbmltYXRpb24gc3RlcHMgaW5cbiAqcGFyYWxsZWwuXG4gKlxuICogV2hlbiBhIHNlcXVlbmNlIGlzIHVzZWQgd2l0aGluIGEgYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YCBvciBhIGB0cmFuc2l0aW9uKClgIGNhbGwsXG4gKiBleGVjdXRpb24gY29udGludWVzIHRvIHRoZSBuZXh0IGluc3RydWN0aW9uIG9ubHkgYWZ0ZXIgZWFjaCBvZiB0aGUgaW5uZXIgYW5pbWF0aW9uXG4gKiBzdGVwcyBoYXZlIGNvbXBsZXRlZC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKiovXG5leHBvcnQgZnVuY3Rpb24gc2VxdWVuY2UoXG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdLFxuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwsXG4pOiBBbmltYXRpb25TZXF1ZW5jZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU2VxdWVuY2UsIHN0ZXBzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBEZWNsYXJlcyBhIGtleS92YWx1ZSBvYmplY3QgY29udGFpbmluZyBDU1MgcHJvcGVydGllcy9zdHlsZXMgdGhhdFxuICogY2FuIHRoZW4gYmUgdXNlZCBmb3IgYW4gYW5pbWF0aW9uIFtgc3RhdGVgXShhcGkvYW5pbWF0aW9ucy9zdGF0ZSksIHdpdGhpbiBhbiBhbmltYXRpb25cbiAqYHNlcXVlbmNlYCwgb3IgYXMgc3R5bGluZyBkYXRhIGZvciBjYWxscyB0byBgYW5pbWF0ZSgpYCBhbmQgYGtleWZyYW1lcygpYC5cbiAqXG4gKiBAcGFyYW0gdG9rZW5zIEEgc2V0IG9mIENTUyBzdHlsZXMgb3IgSFRNTCBzdHlsZXMgYXNzb2NpYXRlZCB3aXRoIGFuIGFuaW1hdGlvbiBzdGF0ZS5cbiAqIFRoZSB2YWx1ZSBjYW4gYmUgYW55IG9mIHRoZSBmb2xsb3dpbmc6XG4gKiAtIEEga2V5LXZhbHVlIHN0eWxlIHBhaXIgYXNzb2NpYXRpbmcgYSBDU1MgcHJvcGVydHkgd2l0aCBhIHZhbHVlLlxuICogLSBBbiBhcnJheSBvZiBrZXktdmFsdWUgc3R5bGUgcGFpcnMuXG4gKiAtIEFuIGFzdGVyaXNrICgqKSwgdG8gdXNlIGF1dG8tc3R5bGluZywgd2hlcmUgc3R5bGVzIGFyZSBkZXJpdmVkIGZyb20gdGhlIGVsZW1lbnRcbiAqIGJlaW5nIGFuaW1hdGVkIGFuZCBhcHBsaWVkIHRvIHRoZSBhbmltYXRpb24gd2hlbiBpdCBzdGFydHMuXG4gKlxuICogQXV0by1zdHlsaW5nIGNhbiBiZSB1c2VkIHRvIGRlZmluZSBhIHN0YXRlIHRoYXQgZGVwZW5kcyBvbiBsYXlvdXQgb3Igb3RoZXJcbiAqIGVudmlyb25tZW50YWwgZmFjdG9ycy5cbiAqXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgc3R5bGUgZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVGhlIGZvbGxvd2luZyBleGFtcGxlcyBjcmVhdGUgYW5pbWF0aW9uIHN0eWxlcyB0aGF0IGNvbGxlY3QgYSBzZXQgb2ZcbiAqIENTUyBwcm9wZXJ0eSB2YWx1ZXM6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gc3RyaW5nIHZhbHVlcyBmb3IgQ1NTIHByb3BlcnRpZXNcbiAqIHN0eWxlKHsgYmFja2dyb3VuZDogXCJyZWRcIiwgY29sb3I6IFwiYmx1ZVwiIH0pXG4gKlxuICogLy8gbnVtZXJpY2FsIHBpeGVsIHZhbHVlc1xuICogc3R5bGUoeyB3aWR0aDogMTAwLCBoZWlnaHQ6IDAgfSlcbiAqIGBgYFxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSB1c2VzIGF1dG8tc3R5bGluZyB0byBhbGxvdyBhbiBlbGVtZW50IHRvIGFuaW1hdGUgZnJvbVxuICogYSBoZWlnaHQgb2YgMCB1cCB0byBpdHMgZnVsbCBoZWlnaHQ6XG4gKlxuICogYGBgXG4gKiBzdHlsZSh7IGhlaWdodDogMCB9KSxcbiAqIGFuaW1hdGUoXCIxc1wiLCBzdHlsZSh7IGhlaWdodDogXCIqXCIgfSkpXG4gKiBgYGBcbiAqXG4gKiBAcHVibGljQXBpXG4gKiovXG5leHBvcnQgZnVuY3Rpb24gc3R5bGUoXG4gIHRva2VuczogJyonIHwge1trZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlcn0gfCBBcnJheTwnKicgfCB7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfT4sXG4pOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU3R5bGUsIHN0eWxlczogdG9rZW5zLCBvZmZzZXQ6IG51bGx9O1xufVxuXG4vKipcbiAqIERlY2xhcmVzIGFuIGFuaW1hdGlvbiBzdGF0ZSB3aXRoaW4gYSB0cmlnZ2VyIGF0dGFjaGVkIHRvIGFuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIG5hbWUgT25lIG9yIG1vcmUgbmFtZXMgZm9yIHRoZSBkZWZpbmVkIHN0YXRlIGluIGEgY29tbWEtc2VwYXJhdGVkIHN0cmluZy5cbiAqIFRoZSBmb2xsb3dpbmcgcmVzZXJ2ZWQgc3RhdGUgbmFtZXMgY2FuIGJlIHN1cHBsaWVkIHRvIGRlZmluZSBhIHN0eWxlIGZvciBzcGVjaWZpYyB1c2VcbiAqIGNhc2VzOlxuICpcbiAqIC0gYHZvaWRgIFlvdSBjYW4gYXNzb2NpYXRlIHN0eWxlcyB3aXRoIHRoaXMgbmFtZSB0byBiZSB1c2VkIHdoZW5cbiAqIHRoZSBlbGVtZW50IGlzIGRldGFjaGVkIGZyb20gdGhlIGFwcGxpY2F0aW9uLiBGb3IgZXhhbXBsZSwgd2hlbiBhbiBgbmdJZmAgZXZhbHVhdGVzXG4gKiB0byBmYWxzZSwgdGhlIHN0YXRlIG9mIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgaXMgdm9pZC5cbiAqICAtIGAqYCAoYXN0ZXJpc2spIEluZGljYXRlcyB0aGUgZGVmYXVsdCBzdGF0ZS4gWW91IGNhbiBhc3NvY2lhdGUgc3R5bGVzIHdpdGggdGhpcyBuYW1lXG4gKiB0byBiZSB1c2VkIGFzIHRoZSBmYWxsYmFjayB3aGVuIHRoZSBzdGF0ZSB0aGF0IGlzIGJlaW5nIGFuaW1hdGVkIGlzIG5vdCBkZWNsYXJlZFxuICogd2l0aGluIHRoZSB0cmlnZ2VyLlxuICpcbiAqIEBwYXJhbSBzdHlsZXMgQSBzZXQgb2YgQ1NTIHN0eWxlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBzdGF0ZSwgY3JlYXRlZCB1c2luZyB0aGVcbiAqIGBzdHlsZSgpYCBmdW5jdGlvbi5cbiAqIFRoaXMgc2V0IG9mIHN0eWxlcyBwZXJzaXN0cyBvbiB0aGUgZWxlbWVudCBvbmNlIHRoZSBzdGF0ZSBoYXMgYmVlbiByZWFjaGVkLlxuICogQHBhcmFtIG9wdGlvbnMgUGFyYW1ldGVycyB0aGF0IGNhbiBiZSBwYXNzZWQgdG8gdGhlIHN0YXRlIHdoZW4gaXQgaXMgaW52b2tlZC5cbiAqIDAgb3IgbW9yZSBrZXktdmFsdWUgcGFpcnMuXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgbmV3IHN0YXRlIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIFVzZSB0aGUgYHRyaWdnZXIoKWAgZnVuY3Rpb24gdG8gcmVnaXN0ZXIgc3RhdGVzIHRvIGFuIGFuaW1hdGlvbiB0cmlnZ2VyLlxuICogVXNlIHRoZSBgdHJhbnNpdGlvbigpYCBmdW5jdGlvbiB0byBhbmltYXRlIGJldHdlZW4gc3RhdGVzLlxuICogV2hlbiBhIHN0YXRlIGlzIGFjdGl2ZSB3aXRoaW4gYSBjb21wb25lbnQsIGl0cyBhc3NvY2lhdGVkIHN0eWxlcyBwZXJzaXN0IG9uIHRoZSBlbGVtZW50LFxuICogZXZlbiB3aGVuIHRoZSBhbmltYXRpb24gZW5kcy5cbiAqXG4gKiBAcHVibGljQXBpXG4gKiovXG5leHBvcnQgZnVuY3Rpb24gc3RhdGUoXG4gIG5hbWU6IHN0cmluZyxcbiAgc3R5bGVzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhLFxuICBvcHRpb25zPzoge3BhcmFtczoge1tuYW1lOiBzdHJpbmddOiBhbnl9fSxcbik6IEFuaW1hdGlvblN0YXRlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdGF0ZSwgbmFtZSwgc3R5bGVzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIGEgc2V0IG9mIGFuaW1hdGlvbiBzdHlsZXMsIGFzc29jaWF0aW5nIGVhY2ggc3R5bGUgd2l0aCBhbiBvcHRpb25hbCBgb2Zmc2V0YCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgQSBzZXQgb2YgYW5pbWF0aW9uIHN0eWxlcyB3aXRoIG9wdGlvbmFsIG9mZnNldCBkYXRhLlxuICogVGhlIG9wdGlvbmFsIGBvZmZzZXRgIHZhbHVlIGZvciBhIHN0eWxlIHNwZWNpZmllcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIHRvdGFsIGFuaW1hdGlvblxuICogdGltZSBhdCB3aGljaCB0aGF0IHN0eWxlIGlzIGFwcGxpZWQuXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIGtleWZyYW1lcyBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBVc2Ugd2l0aCB0aGUgYGFuaW1hdGUoKWAgY2FsbC4gSW5zdGVhZCBvZiBhcHBseWluZyBhbmltYXRpb25zXG4gKiBmcm9tIHRoZSBjdXJyZW50IHN0YXRlXG4gKiB0byB0aGUgZGVzdGluYXRpb24gc3RhdGUsIGtleWZyYW1lcyBkZXNjcmliZSBob3cgZWFjaCBzdHlsZSBlbnRyeSBpcyBhcHBsaWVkIGFuZCBhdCB3aGF0IHBvaW50XG4gKiB3aXRoaW4gdGhlIGFuaW1hdGlvbiBhcmMuXG4gKiBDb21wYXJlIFtDU1MgS2V5ZnJhbWUgQW5pbWF0aW9uc10oaHR0cHM6Ly93d3cudzNzY2hvb2xzLmNvbS9jc3MvY3NzM19hbmltYXRpb25zLmFzcCkuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogSW4gdGhlIGZvbGxvd2luZyBleGFtcGxlLCB0aGUgb2Zmc2V0IHZhbHVlcyBkZXNjcmliZVxuICogd2hlbiBlYWNoIGBiYWNrZ3JvdW5kQ29sb3JgIHZhbHVlIGlzIGFwcGxpZWQuIFRoZSBjb2xvciBpcyByZWQgYXQgdGhlIHN0YXJ0LCBhbmQgY2hhbmdlcyB0b1xuICogYmx1ZSB3aGVuIDIwJSBvZiB0aGUgdG90YWwgdGltZSBoYXMgZWxhcHNlZC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyB0aGUgcHJvdmlkZWQgb2Zmc2V0IHZhbHVlc1xuICogYW5pbWF0ZShcIjVzXCIsIGtleWZyYW1lcyhbXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcInJlZFwiLCBvZmZzZXQ6IDAgfSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcImJsdWVcIiwgb2Zmc2V0OiAwLjIgfSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcIm9yYW5nZVwiLCBvZmZzZXQ6IDAuMyB9KSxcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwiYmxhY2tcIiwgb2Zmc2V0OiAxIH0pXG4gKiBdKSlcbiAqIGBgYFxuICpcbiAqIElmIHRoZXJlIGFyZSBubyBgb2Zmc2V0YCB2YWx1ZXMgc3BlY2lmaWVkIGluIHRoZSBzdHlsZSBlbnRyaWVzLCB0aGUgb2Zmc2V0c1xuICogYXJlIGNhbGN1bGF0ZWQgYXV0b21hdGljYWxseS5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBhbmltYXRlKFwiNXNcIiwga2V5ZnJhbWVzKFtcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwicmVkXCIgfSkgLy8gb2Zmc2V0ID0gMFxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJibHVlXCIgfSkgLy8gb2Zmc2V0ID0gMC4zM1xuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJvcmFuZ2VcIiB9KSAvLyBvZmZzZXQgPSAwLjY2XG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcImJsYWNrXCIgfSkgLy8gb2Zmc2V0ID0gMVxuICogXSkpXG4gKmBgYFxuXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBrZXlmcmFtZXMoc3RlcHM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGFbXSk6IEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5LZXlmcmFtZXMsIHN0ZXBzfTtcbn1cblxuLyoqXG4gKiBEZWNsYXJlcyBhbiBhbmltYXRpb24gdHJhbnNpdGlvbiB3aGljaCBpcyBwbGF5ZWQgd2hlbiBhIGNlcnRhaW4gc3BlY2lmaWVkIGNvbmRpdGlvbiBpcyBtZXQuXG4gKlxuICogQHBhcmFtIHN0YXRlQ2hhbmdlRXhwciBBIHN0cmluZyB3aXRoIGEgc3BlY2lmaWMgZm9ybWF0IG9yIGEgZnVuY3Rpb24gdGhhdCBzcGVjaWZpZXMgd2hlbiB0aGVcbiAqIGFuaW1hdGlvbiB0cmFuc2l0aW9uIHNob3VsZCBvY2N1ciAoc2VlIFtTdGF0ZSBDaGFuZ2UgRXhwcmVzc2lvbl0oI3N0YXRlLWNoYW5nZS1leHByZXNzaW9uKSkuXG4gKlxuICogQHBhcmFtIHN0ZXBzIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBvYmplY3RzIHRoYXQgcmVwcmVzZW50IHRoZSBhbmltYXRpb24ncyBpbnN0cnVjdGlvbnMuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgQW4gb3B0aW9ucyBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IGEgZGVsYXkgZm9yIHRoZSBhbmltYXRpb24gb3IgcHJvdmlkZVxuICogY3VzdG9tIHBhcmFtZXRlcnMgZm9yIGl0LlxuICpcbiAqIEByZXR1cm5zIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgdHJhbnNpdGlvbiBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogIyMjIFN0YXRlIENoYW5nZSBFeHByZXNzaW9uXG4gKlxuICogVGhlIFN0YXRlIENoYW5nZSBFeHByZXNzaW9uIGluc3RydWN0cyBBbmd1bGFyIHdoZW4gdG8gcnVuIHRoZSB0cmFuc2l0aW9uJ3MgYW5pbWF0aW9ucywgaXQgY2FuXG4gKmVpdGhlciBiZVxuICogIC0gYSBzdHJpbmcgd2l0aCBhIHNwZWNpZmljIHN5bnRheFxuICogIC0gb3IgYSBmdW5jdGlvbiB0aGF0IGNvbXBhcmVzIHRoZSBwcmV2aW91cyBhbmQgY3VycmVudCBzdGF0ZSAodmFsdWUgb2YgdGhlIGV4cHJlc3Npb24gYm91bmQgdG9cbiAqICAgIHRoZSBlbGVtZW50J3MgdHJpZ2dlcikgYW5kIHJldHVybnMgYHRydWVgIGlmIHRoZSB0cmFuc2l0aW9uIHNob3VsZCBvY2N1ciBvciBgZmFsc2VgIG90aGVyd2lzZVxuICpcbiAqIFRoZSBzdHJpbmcgZm9ybWF0IGNhbiBiZTpcbiAqICAtIGBmcm9tU3RhdGUgPT4gdG9TdGF0ZWAsIHdoaWNoIGluZGljYXRlcyB0aGF0IHRoZSB0cmFuc2l0aW9uJ3MgYW5pbWF0aW9ucyBzaG91bGQgb2NjdXIgdGhlbiB0aGVcbiAqICAgIGV4cHJlc3Npb24gYm91bmQgdG8gdGhlIHRyaWdnZXIncyBlbGVtZW50IGdvZXMgZnJvbSBgZnJvbVN0YXRlYCB0byBgdG9TdGF0ZWBcbiAqXG4gKiAgICBfRXhhbXBsZTpfXG4gKiAgICAgIGBgYHR5cGVzY3JpcHRcbiAqICAgICAgICB0cmFuc2l0aW9uKCdvcGVuID0+IGNsb3NlZCcsIGFuaW1hdGUoJy41cyBlYXNlLW91dCcsIHN0eWxlKHsgaGVpZ2h0OiAwIH0pICkpXG4gKiAgICAgIGBgYFxuICpcbiAqICAtIGBmcm9tU3RhdGUgPD0+IHRvU3RhdGVgLCB3aGljaCBpbmRpY2F0ZXMgdGhhdCB0aGUgdHJhbnNpdGlvbidzIGFuaW1hdGlvbnMgc2hvdWxkIG9jY3VyIHRoZW5cbiAqICAgIHRoZSBleHByZXNzaW9uIGJvdW5kIHRvIHRoZSB0cmlnZ2VyJ3MgZWxlbWVudCBnb2VzIGZyb20gYGZyb21TdGF0ZWAgdG8gYHRvU3RhdGVgIG9yIHZpY2UgdmVyc2FcbiAqXG4gKiAgICBfRXhhbXBsZTpfXG4gKiAgICAgIGBgYHR5cGVzY3JpcHRcbiAqICAgICAgICB0cmFuc2l0aW9uKCdlbmFibGVkIDw9PiBkaXNhYmxlZCcsIGFuaW1hdGUoJzFzIGN1YmljLWJlemllcigwLjgsMC4zLDAsMSknKSlcbiAqICAgICAgYGBgXG4gKlxuICogIC0gYDplbnRlcmAvYDpsZWF2ZWAsIHdoaWNoIGluZGljYXRlcyB0aGF0IHRoZSB0cmFuc2l0aW9uJ3MgYW5pbWF0aW9ucyBzaG91bGQgb2NjdXIgd2hlbiB0aGVcbiAqICAgIGVsZW1lbnQgZW50ZXJzIG9yIGV4aXN0cyB0aGUgRE9NXG4gKlxuICogICAgX0V4YW1wbGU6X1xuICogICAgICBgYGB0eXBlc2NyaXB0XG4gKiAgICAgICAgdHJhbnNpdGlvbignOmVudGVyJywgW1xuICogICAgICAgICAgc3R5bGUoeyBvcGFjaXR5OiAwIH0pLFxuICogICAgICAgICAgYW5pbWF0ZSgnNTAwbXMnLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpXG4gKiAgICAgICAgXSlcbiAqICAgICAgYGBgXG4gKlxuICogIC0gYDppbmNyZW1lbnRgL2A6ZGVjcmVtZW50YCwgd2hpY2ggaW5kaWNhdGVzIHRoYXQgdGhlIHRyYW5zaXRpb24ncyBhbmltYXRpb25zIHNob3VsZCBvY2N1ciB3aGVuXG4gKiAgICB0aGUgbnVtZXJpY2FsIGV4cHJlc3Npb24gYm91bmQgdG8gdGhlIHRyaWdnZXIncyBlbGVtZW50IGhhcyBpbmNyZWFzZWQgaW4gdmFsdWUgb3IgZGVjcmVhc2VkXG4gKlxuICogICAgX0V4YW1wbGU6X1xuICogICAgICBgYGB0eXBlc2NyaXB0XG4gKiAgICAgICAgdHJhbnNpdGlvbignOmluY3JlbWVudCcsIHF1ZXJ5KCdAY291bnRlcicsIGFuaW1hdGVDaGlsZCgpKSlcbiAqICAgICAgYGBgXG4gKlxuICogIC0gYSBzZXF1ZW5jZSBvZiBhbnkgb2YgdGhlIGFib3ZlIGRpdmlkZWQgYnkgY29tbWFzLCB3aGljaCBpbmRpY2F0ZXMgdGhhdCB0cmFuc2l0aW9uJ3MgYW5pbWF0aW9uc1xuICogICAgc2hvdWxkIG9jY3VyIHdoZW5ldmVyIG9uZSBvZiB0aGUgc3RhdGUgY2hhbmdlIGV4cHJlc3Npb25zIG1hdGNoZXNcbiAqXG4gKiAgICBfRXhhbXBsZTpfXG4gKiAgICAgIGBgYHR5cGVzY3JpcHRcbiAqICAgICAgICB0cmFuc2l0aW9uKCc6aW5jcmVtZW50LCAqID0+IGVuYWJsZWQsIDplbnRlcicsIGFuaW1hdGUoJzFzIGVhc2UnLCBrZXlmcmFtZXMoW1xuICogICAgICAgICAgc3R5bGUoeyB0cmFuc2Zvcm06ICdzY2FsZSgxKScsIG9mZnNldDogMH0pLFxuICogICAgICAgICAgc3R5bGUoeyB0cmFuc2Zvcm06ICdzY2FsZSgxLjEpJywgb2Zmc2V0OiAwLjd9KSxcbiAqICAgICAgICAgIHN0eWxlKHsgdHJhbnNmb3JtOiAnc2NhbGUoMSknLCBvZmZzZXQ6IDF9KVxuICogICAgICAgIF0pKSksXG4gKiAgICAgIGBgYFxuICpcbiAqIEFsc28gbm90ZSB0aGF0IGluIHN1Y2ggY29udGV4dDpcbiAqICAtIGB2b2lkYCBjYW4gYmUgdXNlZCB0byBpbmRpY2F0ZSB0aGUgYWJzZW5jZSBvZiB0aGUgZWxlbWVudFxuICogIC0gYXN0ZXJpc2tzIGNhbiBiZSB1c2VkIGFzIHdpbGRjYXJkcyB0aGF0IG1hdGNoIGFueSBzdGF0ZVxuICogIC0gKGFzIGEgY29uc2VxdWVuY2Ugb2YgdGhlIGFib3ZlLCBgdm9pZCA9PiAqYCBpcyBlcXVpdmFsZW50IHRvIGA6ZW50ZXJgIGFuZCBgKiA9PiB2b2lkYCBpc1xuICogICAgZXF1aXZhbGVudCB0byBgOmxlYXZlYClcbiAqICAtIGB0cnVlYCBhbmQgYGZhbHNlYCBhbHNvIG1hdGNoIGV4cHJlc3Npb24gdmFsdWVzIG9mIGAxYCBhbmQgYDBgIHJlc3BlY3RpdmVseSAoYnV0IGRvIG5vdCBtYXRjaFxuICogICAgX3RydXRoeV8gYW5kIF9mYWxzeV8gdmFsdWVzKVxuICpcbiAqIDxkaXYgY2xhc3M9XCJhbGVydCBpcy1oZWxwZnVsXCI+XG4gKlxuICogIEJlIGNhcmVmdWwgYWJvdXQgZW50ZXJpbmcgZW5kIGxlYXZpbmcgZWxlbWVudHMgYXMgdGhlaXIgdHJhbnNpdGlvbnMgcHJlc2VudCBhIGNvbW1vblxuICogIHBpdGZhbGwgZm9yIGRldmVsb3BlcnMuXG4gKlxuICogIE5vdGUgdGhhdCB3aGVuIGFuIGVsZW1lbnQgd2l0aCBhIHRyaWdnZXIgZW50ZXJzIHRoZSBET00gaXRzIGA6ZW50ZXJgIHRyYW5zaXRpb24gYWx3YXlzXG4gKiAgZ2V0cyBleGVjdXRlZCwgYnV0IGl0cyBgOmxlYXZlYCB0cmFuc2l0aW9uIHdpbGwgbm90IGJlIGV4ZWN1dGVkIGlmIHRoZSBlbGVtZW50IGlzIHJlbW92ZWRcbiAqICBhbG9uZ3NpZGUgaXRzIHBhcmVudCAoYXMgaXQgd2lsbCBiZSByZW1vdmVkIFwid2l0aG91dCB3YXJuaW5nXCIgYmVmb3JlIGl0cyB0cmFuc2l0aW9uIGhhc1xuICogIGEgY2hhbmNlIHRvIGJlIGV4ZWN1dGVkLCB0aGUgb25seSB3YXkgdGhhdCBzdWNoIHRyYW5zaXRpb24gY2FuIG9jY3VyIGlzIGlmIHRoZSBlbGVtZW50XG4gKiAgaXMgZXhpdGluZyB0aGUgRE9NIG9uIGl0cyBvd24pLlxuICpcbiAqXG4gKiA8L2Rpdj5cbiAqXG4gKiAjIyMgQW5pbWF0aW5nIHRvIGEgRmluYWwgU3RhdGVcbiAqXG4gKiBJZiB0aGUgZmluYWwgc3RlcCBpbiBhIHRyYW5zaXRpb24gaXMgYSBjYWxsIHRvIGBhbmltYXRlKClgIHRoYXQgdXNlcyBhIHRpbWluZyB2YWx1ZVxuICogd2l0aCBubyBgc3R5bGVgIGRhdGEsIHRoYXQgc3RlcCBpcyBhdXRvbWF0aWNhbGx5IGNvbnNpZGVyZWQgdGhlIGZpbmFsIGFuaW1hdGlvbiBhcmMsXG4gKiBmb3IgdGhlIGVsZW1lbnQgdG8gcmVhY2ggdGhlIGZpbmFsIHN0YXRlLCBpbiBzdWNoIGNhc2UgQW5ndWxhciBhdXRvbWF0aWNhbGx5IGFkZHMgb3IgcmVtb3Zlc1xuICogQ1NTIHN0eWxlcyB0byBlbnN1cmUgdGhhdCB0aGUgZWxlbWVudCBpcyBpbiB0aGUgY29ycmVjdCBmaW5hbCBzdGF0ZS5cbiAqXG4gKlxuICogIyMjIFVzYWdlIEV4YW1wbGVzXG4gKlxuICogIC0gVHJhbnNpdGlvbiBhbmltYXRpb25zIGFwcGxpZWQgYmFzZWQgb25cbiAqICAgIHRoZSB0cmlnZ2VyJ3MgZXhwcmVzc2lvbiB2YWx1ZVxuICpcbiAqICAgYGBgaHRtbFxuICogICA8ZGl2IFtAbXlBbmltYXRpb25UcmlnZ2VyXT1cIm15U3RhdHVzRXhwXCI+XG4gKiAgICAuLi5cbiAqICAgPC9kaXY+XG4gKiAgIGBgYFxuICpcbiAqICAgYGBgdHlwZXNjcmlwdFxuICogICB0cmlnZ2VyKFwibXlBbmltYXRpb25UcmlnZ2VyXCIsIFtcbiAqICAgICAuLi4sIC8vIHN0YXRlc1xuICogICAgIHRyYW5zaXRpb24oXCJvbiA9PiBvZmYsIG9wZW4gPT4gY2xvc2VkXCIsIGFuaW1hdGUoNTAwKSksXG4gKiAgICAgdHJhbnNpdGlvbihcIiogPD0+IGVycm9yXCIsIHF1ZXJ5KCcuaW5kaWNhdG9yJywgYW5pbWF0ZUNoaWxkKCkpKVxuICogICBdKVxuICogICBgYGBcbiAqXG4gKiAgLSBUcmFuc2l0aW9uIGFuaW1hdGlvbnMgYXBwbGllZCBiYXNlZCBvbiBjdXN0b20gbG9naWMgZGVwZW5kZW50XG4gKiAgICBvbiB0aGUgdHJpZ2dlcidzIGV4cHJlc3Npb24gdmFsdWUgYW5kIHByb3ZpZGVkIHBhcmFtZXRlcnNcbiAqXG4gKiAgICBgYGBodG1sXG4gKiAgICA8ZGl2IFtAbXlBbmltYXRpb25UcmlnZ2VyXT1cIntcbiAqICAgICB2YWx1ZTogc3RlcE5hbWUsXG4gKiAgICAgcGFyYW1zOiB7IHRhcmdldDogY3VycmVudFRhcmdldCB9XG4gKiAgICB9XCI+XG4gKiAgICAgLi4uXG4gKiAgICA8L2Rpdj5cbiAqICAgIGBgYFxuICpcbiAqICAgIGBgYHR5cGVzY3JpcHRcbiAqICAgIHRyaWdnZXIoXCJteUFuaW1hdGlvblRyaWdnZXJcIiwgW1xuICogICAgICAuLi4sIC8vIHN0YXRlc1xuICogICAgICB0cmFuc2l0aW9uKFxuICogICAgICAgIChmcm9tU3RhdGUsIHRvU3RhdGUsIF9lbGVtZW50LCBwYXJhbXMpID0+XG4gKiAgICAgICAgICBbJ2ZpcnN0c3RlcCcsICdsYXN0c3RlcCddLmluY2x1ZGVzKGZyb21TdGF0ZS50b0xvd2VyQ2FzZSgpKVxuICogICAgICAgICAgJiYgdG9TdGF0ZSA9PT0gcGFyYW1zPy5bJ3RhcmdldCddLFxuICogICAgICAgIGFuaW1hdGUoJzFzJylcbiAqICAgICAgKVxuICogICAgXSlcbiAqICAgIGBgYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2l0aW9uKFxuICBzdGF0ZUNoYW5nZUV4cHI6XG4gICAgfCBzdHJpbmdcbiAgICB8ICgoXG4gICAgICAgIGZyb21TdGF0ZTogc3RyaW5nLFxuICAgICAgICB0b1N0YXRlOiBzdHJpbmcsXG4gICAgICAgIGVsZW1lbnQ/OiBhbnksXG4gICAgICAgIHBhcmFtcz86IHtba2V5OiBzdHJpbmddOiBhbnl9LFxuICAgICAgKSA9PiBib29sZWFuKSxcbiAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsLFxuKTogQW5pbWF0aW9uVHJhbnNpdGlvbk1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuVHJhbnNpdGlvbiwgZXhwcjogc3RhdGVDaGFuZ2VFeHByLCBhbmltYXRpb246IHN0ZXBzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBQcm9kdWNlcyBhIHJldXNhYmxlIGFuaW1hdGlvbiB0aGF0IGNhbiBiZSBpbnZva2VkIGluIGFub3RoZXIgYW5pbWF0aW9uIG9yIHNlcXVlbmNlLFxuICogYnkgY2FsbGluZyB0aGUgYHVzZUFuaW1hdGlvbigpYCBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgT25lIG9yIG1vcmUgYW5pbWF0aW9uIG9iamVjdHMsIGFzIHJldHVybmVkIGJ5IHRoZSBgYW5pbWF0ZSgpYFxuICogb3IgYHNlcXVlbmNlKClgIGZ1bmN0aW9uLCB0aGF0IGZvcm0gYSB0cmFuc2Zvcm1hdGlvbiBmcm9tIG9uZSBzdGF0ZSB0byBhbm90aGVyLlxuICogQSBzZXF1ZW5jZSBpcyB1c2VkIGJ5IGRlZmF1bHQgd2hlbiB5b3UgcGFzcyBhbiBhcnJheS5cbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBkZWxheSB2YWx1ZSBmb3IgdGhlIHN0YXJ0IG9mIHRoZVxuICogYW5pbWF0aW9uLCBhbmQgYWRkaXRpb25hbCBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzLlxuICogUHJvdmlkZWQgdmFsdWVzIGZvciBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgYXJlIHVzZWQgYXMgZGVmYXVsdHMsXG4gKiBhbmQgb3ZlcnJpZGUgdmFsdWVzIGNhbiBiZSBwYXNzZWQgdG8gdGhlIGNhbGxlciBvbiBpbnZvY2F0aW9uLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBhbmltYXRpb24gZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIGRlZmluZXMgYSByZXVzYWJsZSBhbmltYXRpb24sIHByb3ZpZGluZyBzb21lIGRlZmF1bHQgcGFyYW1ldGVyXG4gKiB2YWx1ZXMuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdmFyIGZhZGVBbmltYXRpb24gPSBhbmltYXRpb24oW1xuICogICBzdHlsZSh7IG9wYWNpdHk6ICd7eyBzdGFydCB9fScgfSksXG4gKiAgIGFuaW1hdGUoJ3t7IHRpbWUgfX0nLFxuICogICBzdHlsZSh7IG9wYWNpdHk6ICd7eyBlbmQgfX0nfSkpXG4gKiAgIF0sXG4gKiAgIHsgcGFyYW1zOiB7IHRpbWU6ICcxMDAwbXMnLCBzdGFydDogMCwgZW5kOiAxIH19KTtcbiAqIGBgYFxuICpcbiAqIFRoZSBmb2xsb3dpbmcgaW52b2tlcyB0aGUgZGVmaW5lZCBhbmltYXRpb24gd2l0aCBhIGNhbGwgdG8gYHVzZUFuaW1hdGlvbigpYCxcbiAqIHBhc3NpbmcgaW4gb3ZlcnJpZGUgcGFyYW1ldGVyIHZhbHVlcy5cbiAqXG4gKiBgYGBqc1xuICogdXNlQW5pbWF0aW9uKGZhZGVBbmltYXRpb24sIHtcbiAqICAgcGFyYW1zOiB7XG4gKiAgICAgdGltZTogJzJzJyxcbiAqICAgICBzdGFydDogMSxcbiAqICAgICBlbmQ6IDBcbiAqICAgfVxuICogfSlcbiAqIGBgYFxuICpcbiAqIElmIGFueSBvZiB0aGUgcGFzc2VkLWluIHBhcmFtZXRlciB2YWx1ZXMgYXJlIG1pc3NpbmcgZnJvbSB0aGlzIGNhbGwsXG4gKiB0aGUgZGVmYXVsdCB2YWx1ZXMgYXJlIHVzZWQuIElmIG9uZSBvciBtb3JlIHBhcmFtZXRlciB2YWx1ZXMgYXJlIG1pc3NpbmcgYmVmb3JlIGEgc3RlcCBpc1xuICogYW5pbWF0ZWQsIGB1c2VBbmltYXRpb24oKWAgdGhyb3dzIGFuIGVycm9yLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuaW1hdGlvbihcbiAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsLFxuKTogQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5SZWZlcmVuY2UsIGFuaW1hdGlvbjogc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIEV4ZWN1dGVzIGEgcXVlcmllZCBpbm5lciBhbmltYXRpb24gZWxlbWVudCB3aXRoaW4gYW4gYW5pbWF0aW9uIHNlcXVlbmNlLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBkZWxheSB2YWx1ZSBmb3IgdGhlIHN0YXJ0IG9mIHRoZVxuICogYW5pbWF0aW9uLCBhbmQgYWRkaXRpb25hbCBvdmVycmlkZSB2YWx1ZXMgZm9yIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgY2hpbGQgYW5pbWF0aW9uIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIEVhY2ggdGltZSBhbiBhbmltYXRpb24gaXMgdHJpZ2dlcmVkIGluIEFuZ3VsYXIsIHRoZSBwYXJlbnQgYW5pbWF0aW9uXG4gKiBoYXMgcHJpb3JpdHkgYW5kIGFueSBjaGlsZCBhbmltYXRpb25zIGFyZSBibG9ja2VkLiBJbiBvcmRlclxuICogZm9yIGEgY2hpbGQgYW5pbWF0aW9uIHRvIHJ1biwgdGhlIHBhcmVudCBhbmltYXRpb24gbXVzdCBxdWVyeSBlYWNoIG9mIHRoZSBlbGVtZW50c1xuICogY29udGFpbmluZyBjaGlsZCBhbmltYXRpb25zLCBhbmQgcnVuIHRoZW0gdXNpbmcgdGhpcyBmdW5jdGlvbi5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBmZWF0dXJlIGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgd2l0aCBgcXVlcnkoKWAgYW5kIGl0IHdpbGwgb25seSB3b3JrXG4gKiB3aXRoIGFuaW1hdGlvbnMgdGhhdCBhcmUgYXNzaWduZWQgdXNpbmcgdGhlIEFuZ3VsYXIgYW5pbWF0aW9uIGxpYnJhcnkuIENTUyBrZXlmcmFtZXNcbiAqIGFuZCB0cmFuc2l0aW9ucyBhcmUgbm90IGhhbmRsZWQgYnkgdGhpcyBBUEkuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5pbWF0ZUNoaWxkKFxuICBvcHRpb25zOiBBbmltYXRlQ2hpbGRPcHRpb25zIHwgbnVsbCA9IG51bGwsXG4pOiBBbmltYXRpb25BbmltYXRlQ2hpbGRNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLkFuaW1hdGVDaGlsZCwgb3B0aW9uc307XG59XG5cbi8qKlxuICogU3RhcnRzIGEgcmV1c2FibGUgYW5pbWF0aW9uIHRoYXQgaXMgY3JlYXRlZCB1c2luZyB0aGUgYGFuaW1hdGlvbigpYCBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0gYW5pbWF0aW9uIFRoZSByZXVzYWJsZSBhbmltYXRpb24gdG8gc3RhcnQuXG4gKiBAcGFyYW0gb3B0aW9ucyBBbiBvcHRpb25zIG9iamVjdCB0aGF0IGNhbiBjb250YWluIGEgZGVsYXkgdmFsdWUgZm9yIHRoZSBzdGFydCBvZlxuICogdGhlIGFuaW1hdGlvbiwgYW5kIGFkZGl0aW9uYWwgb3ZlcnJpZGUgdmFsdWVzIGZvciBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzLlxuICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgYW5pbWF0aW9uIHBhcmFtZXRlcnMuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQW5pbWF0aW9uKFxuICBhbmltYXRpb246IEFuaW1hdGlvblJlZmVyZW5jZU1ldGFkYXRhLFxuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwsXG4pOiBBbmltYXRpb25BbmltYXRlUmVmTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5BbmltYXRlUmVmLCBhbmltYXRpb24sIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIEZpbmRzIG9uZSBvciBtb3JlIGlubmVyIGVsZW1lbnRzIHdpdGhpbiB0aGUgY3VycmVudCBlbGVtZW50IHRoYXQgaXNcbiAqIGJlaW5nIGFuaW1hdGVkIHdpdGhpbiBhIHNlcXVlbmNlLiBVc2Ugd2l0aCBgYW5pbWF0ZSgpYC5cbiAqXG4gKiBAcGFyYW0gc2VsZWN0b3IgVGhlIGVsZW1lbnQgdG8gcXVlcnksIG9yIGEgc2V0IG9mIGVsZW1lbnRzIHRoYXQgY29udGFpbiBBbmd1bGFyLXNwZWNpZmljXG4gKiBjaGFyYWN0ZXJpc3RpY3MsIHNwZWNpZmllZCB3aXRoIG9uZSBvciBtb3JlIG9mIHRoZSBmb2xsb3dpbmcgdG9rZW5zLlxuICogIC0gYHF1ZXJ5KFwiOmVudGVyXCIpYCBvciBgcXVlcnkoXCI6bGVhdmVcIilgIDogUXVlcnkgZm9yIG5ld2x5IGluc2VydGVkL3JlbW92ZWQgZWxlbWVudHMgKG5vdFxuICogICAgIGFsbCBlbGVtZW50cyBjYW4gYmUgcXVlcmllZCB2aWEgdGhlc2UgdG9rZW5zLCBzZWVcbiAqICAgICBbRW50ZXJpbmcgYW5kIExlYXZpbmcgRWxlbWVudHNdKCNlbnRlcmluZy1hbmQtbGVhdmluZy1lbGVtZW50cykpXG4gKiAgLSBgcXVlcnkoXCI6YW5pbWF0aW5nXCIpYCA6IFF1ZXJ5IGFsbCBjdXJyZW50bHkgYW5pbWF0aW5nIGVsZW1lbnRzLlxuICogIC0gYHF1ZXJ5KFwiQHRyaWdnZXJOYW1lXCIpYCA6IFF1ZXJ5IGVsZW1lbnRzIHRoYXQgY29udGFpbiBhbiBhbmltYXRpb24gdHJpZ2dlci5cbiAqICAtIGBxdWVyeShcIkAqXCIpYCA6IFF1ZXJ5IGFsbCBlbGVtZW50cyB0aGF0IGNvbnRhaW4gYW4gYW5pbWF0aW9uIHRyaWdnZXJzLlxuICogIC0gYHF1ZXJ5KFwiOnNlbGZcIilgIDogSW5jbHVkZSB0aGUgY3VycmVudCBlbGVtZW50IGludG8gdGhlIGFuaW1hdGlvbiBzZXF1ZW5jZS5cbiAqXG4gKiBAcGFyYW0gYW5pbWF0aW9uIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBzdGVwcyB0byBhcHBseSB0byB0aGUgcXVlcmllZCBlbGVtZW50IG9yIGVsZW1lbnRzLlxuICogQW4gYXJyYXkgaXMgdHJlYXRlZCBhcyBhbiBhbmltYXRpb24gc2VxdWVuY2UuXG4gKiBAcGFyYW0gb3B0aW9ucyBBbiBvcHRpb25zIG9iamVjdC4gVXNlIHRoZSAnbGltaXQnIGZpZWxkIHRvIGxpbWl0IHRoZSB0b3RhbCBudW1iZXIgb2ZcbiAqIGl0ZW1zIHRvIGNvbGxlY3QuXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgcXVlcnkgZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqICMjIyBNdWx0aXBsZSBUb2tlbnNcbiAqXG4gKiBUb2tlbnMgY2FuIGJlIG1lcmdlZCBpbnRvIGEgY29tYmluZWQgcXVlcnkgc2VsZWN0b3Igc3RyaW5nLiBGb3IgZXhhbXBsZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAgcXVlcnkoJzpzZWxmLCAucmVjb3JkOmVudGVyLCAucmVjb3JkOmxlYXZlLCBAc3ViVHJpZ2dlcicsIFsuLi5dKVxuICogYGBgXG4gKlxuICogVGhlIGBxdWVyeSgpYCBmdW5jdGlvbiBjb2xsZWN0cyBtdWx0aXBsZSBlbGVtZW50cyBhbmQgd29ya3MgaW50ZXJuYWxseSBieSB1c2luZ1xuICogYGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbGAuIFVzZSB0aGUgYGxpbWl0YCBmaWVsZCBvZiBhbiBvcHRpb25zIG9iamVjdCB0byBsaW1pdFxuICogdGhlIHRvdGFsIG51bWJlciBvZiBpdGVtcyB0byBiZSBjb2xsZWN0ZWQuIEZvciBleGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiBxdWVyeSgnZGl2JywgW1xuICogICBhbmltYXRlKC4uLiksXG4gKiAgIGFuaW1hdGUoLi4uKVxuICogXSwgeyBsaW1pdDogMSB9KVxuICogYGBgXG4gKlxuICogQnkgZGVmYXVsdCwgdGhyb3dzIGFuIGVycm9yIHdoZW4gemVybyBpdGVtcyBhcmUgZm91bmQuIFNldCB0aGVcbiAqIGBvcHRpb25hbGAgZmxhZyB0byBpZ25vcmUgdGhpcyBlcnJvci4gRm9yIGV4YW1wbGU6XG4gKlxuICogYGBganNcbiAqIHF1ZXJ5KCcuc29tZS1lbGVtZW50LXRoYXQtbWF5LW5vdC1iZS10aGVyZScsIFtcbiAqICAgYW5pbWF0ZSguLi4pLFxuICogICBhbmltYXRlKC4uLilcbiAqIF0sIHsgb3B0aW9uYWw6IHRydWUgfSlcbiAqIGBgYFxuICpcbiAqICMjIyBFbnRlcmluZyBhbmQgTGVhdmluZyBFbGVtZW50c1xuICpcbiAqIE5vdCBhbGwgZWxlbWVudHMgY2FuIGJlIHF1ZXJpZWQgdmlhIHRoZSBgOmVudGVyYCBhbmQgYDpsZWF2ZWAgdG9rZW5zLCB0aGUgb25seSBvbmVzXG4gKiB0aGF0IGNhbiBhcmUgdGhvc2UgdGhhdCBBbmd1bGFyIGFzc3VtZXMgY2FuIGVudGVyL2xlYXZlIGJhc2VkIG9uIHRoZWlyIG93biBsb2dpY1xuICogKGlmIHRoZWlyIGluc2VydGlvbi9yZW1vdmFsIGlzIHNpbXBseSBhIGNvbnNlcXVlbmNlIG9mIHRoYXQgb2YgdGhlaXIgcGFyZW50IHRoZXlcbiAqIHNob3VsZCBiZSBxdWVyaWVkIHZpYSBhIGRpZmZlcmVudCB0b2tlbiBpbiB0aGVpciBwYXJlbnQncyBgOmVudGVyYC9gOmxlYXZlYCB0cmFuc2l0aW9ucykuXG4gKlxuICogVGhlIG9ubHkgZWxlbWVudHMgQW5ndWxhciBhc3N1bWVzIGNhbiBlbnRlci9sZWF2ZSBiYXNlZCBvbiB0aGVpciBvd24gbG9naWMgKHRodXMgdGhlIG9ubHlcbiAqIG9uZXMgdGhhdCBjYW4gYmUgcXVlcmllZCB2aWEgdGhlIGA6ZW50ZXJgIGFuZCBgOmxlYXZlYCB0b2tlbnMpIGFyZTpcbiAqICAtIFRob3NlIGluc2VydGVkIGR5bmFtaWNhbGx5ICh2aWEgYFZpZXdDb250YWluZXJSZWZgKVxuICogIC0gVGhvc2UgdGhhdCBoYXZlIGEgc3RydWN0dXJhbCBkaXJlY3RpdmUgKHdoaWNoLCB1bmRlciB0aGUgaG9vZCwgYXJlIGEgc3Vic2V0IG9mIHRoZSBhYm92ZSBvbmVzKVxuICpcbiAqIDxkaXYgY2xhc3M9XCJhbGVydCBpcy1oZWxwZnVsXCI+XG4gKlxuICogIE5vdGUgdGhhdCBlbGVtZW50cyB3aWxsIGJlIHN1Y2Nlc3NmdWxseSBxdWVyaWVkIHZpYSBgOmVudGVyYC9gOmxlYXZlYCBldmVuIGlmIHRoZWlyXG4gKiAgaW5zZXJ0aW9uL3JlbW92YWwgaXMgbm90IGRvbmUgbWFudWFsbHkgdmlhIGBWaWV3Q29udGFpbmVyUmVmYG9yIGNhdXNlZCBieSB0aGVpciBzdHJ1Y3R1cmFsXG4gKiAgZGlyZWN0aXZlIChlLmcuIHRoZXkgZW50ZXIvZXhpdCBhbG9uZ3NpZGUgdGhlaXIgcGFyZW50KS5cbiAqXG4gKiA8L2Rpdj5cbiAqXG4gKiA8ZGl2IGNsYXNzPVwiYWxlcnQgaXMtaW1wb3J0YW50XCI+XG4gKlxuICogIFRoZXJlIGlzIGFuIGV4Y2VwdGlvbiB0byB3aGF0IHByZXZpb3VzbHkgbWVudGlvbmVkLCBiZXNpZGVzIGVsZW1lbnRzIGVudGVyaW5nL2xlYXZpbmcgYmFzZWQgb25cbiAqICB0aGVpciBvd24gbG9naWMsIGVsZW1lbnRzIHdpdGggYW4gYW5pbWF0aW9uIHRyaWdnZXIgY2FuIGFsd2F5cyBiZSBxdWVyaWVkIHZpYSBgOmxlYXZlYCB3aGVuXG4gKiB0aGVpciBwYXJlbnQgaXMgYWxzbyBsZWF2aW5nLlxuICpcbiAqIDwvZGl2PlxuICpcbiAqICMjIyBVc2FnZSBFeGFtcGxlXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHF1ZXJpZXMgZm9yIGlubmVyIGVsZW1lbnRzIGFuZCBhbmltYXRlcyB0aGVtXG4gKiBpbmRpdmlkdWFsbHkgdXNpbmcgYGFuaW1hdGUoKWAuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnaW5uZXInLFxuICogICB0ZW1wbGF0ZTogYFxuICogICAgIDxkaXYgW0BxdWVyeUFuaW1hdGlvbl09XCJleHBcIj5cbiAqICAgICAgIDxoMT5UaXRsZTwvaDE+XG4gKiAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudFwiPlxuICogICAgICAgICBCbGFoIGJsYWggYmxhaFxuICogICAgICAgPC9kaXY+XG4gKiAgICAgPC9kaXY+XG4gKiAgIGAsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgIHRyaWdnZXIoJ3F1ZXJ5QW5pbWF0aW9uJywgW1xuICogICAgICB0cmFuc2l0aW9uKCcqID0+IGdvQW5pbWF0ZScsIFtcbiAqICAgICAgICAvLyBoaWRlIHRoZSBpbm5lciBlbGVtZW50c1xuICogICAgICAgIHF1ZXJ5KCdoMScsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSksXG4gKiAgICAgICAgcXVlcnkoJy5jb250ZW50Jywgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKSxcbiAqXG4gKiAgICAgICAgLy8gYW5pbWF0ZSB0aGUgaW5uZXIgZWxlbWVudHMgaW4sIG9uZSBieSBvbmVcbiAqICAgICAgICBxdWVyeSgnaDEnLCBhbmltYXRlKDEwMDAsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSkpLFxuICogICAgICAgIHF1ZXJ5KCcuY29udGVudCcsIGFuaW1hdGUoMTAwMCwgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKSksXG4gKiAgICAgIF0pXG4gKiAgICBdKVxuICogIF1cbiAqIH0pXG4gKiBjbGFzcyBDbXAge1xuICogICBleHAgPSAnJztcbiAqXG4gKiAgIGdvQW5pbWF0ZSgpIHtcbiAqICAgICB0aGlzLmV4cCA9ICdnb0FuaW1hdGUnO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBxdWVyeShcbiAgc2VsZWN0b3I6IHN0cmluZyxcbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10sXG4gIG9wdGlvbnM6IEFuaW1hdGlvblF1ZXJ5T3B0aW9ucyB8IG51bGwgPSBudWxsLFxuKTogQW5pbWF0aW9uUXVlcnlNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlF1ZXJ5LCBzZWxlY3RvciwgYW5pbWF0aW9uLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBVc2Ugd2l0aGluIGFuIGFuaW1hdGlvbiBgcXVlcnkoKWAgY2FsbCB0byBpc3N1ZSBhIHRpbWluZyBnYXAgYWZ0ZXJcbiAqIGVhY2ggcXVlcmllZCBpdGVtIGlzIGFuaW1hdGVkLlxuICpcbiAqIEBwYXJhbSB0aW1pbmdzIEEgZGVsYXkgdmFsdWUuXG4gKiBAcGFyYW0gYW5pbWF0aW9uIE9uZSBvcmUgbW9yZSBhbmltYXRpb24gc3RlcHMuXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIHN0YWdnZXIgZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogSW4gdGhlIGZvbGxvd2luZyBleGFtcGxlLCBhIGNvbnRhaW5lciBlbGVtZW50IHdyYXBzIGEgbGlzdCBvZiBpdGVtcyBzdGFtcGVkIG91dFxuICogYnkgYW4gYG5nRm9yYC4gVGhlIGNvbnRhaW5lciBlbGVtZW50IGNvbnRhaW5zIGFuIGFuaW1hdGlvbiB0cmlnZ2VyIHRoYXQgd2lsbCBsYXRlciBiZSBzZXRcbiAqIHRvIHF1ZXJ5IGZvciBlYWNoIG9mIHRoZSBpbm5lciBpdGVtcy5cbiAqXG4gKiBFYWNoIHRpbWUgaXRlbXMgYXJlIGFkZGVkLCB0aGUgb3BhY2l0eSBmYWRlLWluIGFuaW1hdGlvbiBydW5zLFxuICogYW5kIGVhY2ggcmVtb3ZlZCBpdGVtIGlzIGZhZGVkIG91dC5cbiAqIFdoZW4gZWl0aGVyIG9mIHRoZXNlIGFuaW1hdGlvbnMgb2NjdXIsIHRoZSBzdGFnZ2VyIGVmZmVjdCBpc1xuICogYXBwbGllZCBhZnRlciBlYWNoIGl0ZW0ncyBhbmltYXRpb24gaXMgc3RhcnRlZC5cbiAqXG4gKiBgYGBodG1sXG4gKiA8IS0tIGxpc3QuY29tcG9uZW50Lmh0bWwgLS0+XG4gKiA8YnV0dG9uIChjbGljayk9XCJ0b2dnbGUoKVwiPlNob3cgLyBIaWRlIEl0ZW1zPC9idXR0b24+XG4gKiA8aHIgLz5cbiAqIDxkaXYgW0BsaXN0QW5pbWF0aW9uXT1cIml0ZW1zLmxlbmd0aFwiPlxuICogICA8ZGl2ICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zXCI+XG4gKiAgICAge3sgaXRlbSB9fVxuICogICA8L2Rpdj5cbiAqIDwvZGl2PlxuICogYGBgXG4gKlxuICogSGVyZSBpcyB0aGUgY29tcG9uZW50IGNvZGU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHt0cmlnZ2VyLCB0cmFuc2l0aW9uLCBzdHlsZSwgYW5pbWF0ZSwgcXVlcnksIHN0YWdnZXJ9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuICogQENvbXBvbmVudCh7XG4gKiAgIHRlbXBsYXRlVXJsOiAnbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKCdsaXN0QW5pbWF0aW9uJywgW1xuICogICAgIC4uLlxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBMaXN0Q29tcG9uZW50IHtcbiAqICAgaXRlbXMgPSBbXTtcbiAqXG4gKiAgIHNob3dJdGVtcygpIHtcbiAqICAgICB0aGlzLml0ZW1zID0gWzAsMSwyLDMsNF07XG4gKiAgIH1cbiAqXG4gKiAgIGhpZGVJdGVtcygpIHtcbiAqICAgICB0aGlzLml0ZW1zID0gW107XG4gKiAgIH1cbiAqXG4gKiAgIHRvZ2dsZSgpIHtcbiAqICAgICB0aGlzLml0ZW1zLmxlbmd0aCA/IHRoaXMuaGlkZUl0ZW1zKCkgOiB0aGlzLnNob3dJdGVtcygpO1xuICogICAgfVxuICogIH1cbiAqIGBgYFxuICpcbiAqIEhlcmUgaXMgdGhlIGFuaW1hdGlvbiB0cmlnZ2VyIGNvZGU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdHJpZ2dlcignbGlzdEFuaW1hdGlvbicsIFtcbiAqICAgdHJhbnNpdGlvbignKiA9PiAqJywgWyAvLyBlYWNoIHRpbWUgdGhlIGJpbmRpbmcgdmFsdWUgY2hhbmdlc1xuICogICAgIHF1ZXJ5KCc6bGVhdmUnLCBbXG4gKiAgICAgICBzdGFnZ2VyKDEwMCwgW1xuICogICAgICAgICBhbmltYXRlKCcwLjVzJywgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKVxuICogICAgICAgXSlcbiAqICAgICBdKSxcbiAqICAgICBxdWVyeSgnOmVudGVyJywgW1xuICogICAgICAgc3R5bGUoeyBvcGFjaXR5OiAwIH0pLFxuICogICAgICAgc3RhZ2dlcigxMDAsIFtcbiAqICAgICAgICAgYW5pbWF0ZSgnMC41cycsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSlcbiAqICAgICAgIF0pXG4gKiAgICAgXSlcbiAqICAgXSlcbiAqIF0pXG4gKiBgYGBcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFnZ2VyKFxuICB0aW1pbmdzOiBzdHJpbmcgfCBudW1iZXIsXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGEgfCBBbmltYXRpb25NZXRhZGF0YVtdLFxuKTogQW5pbWF0aW9uU3RhZ2dlck1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU3RhZ2dlciwgdGltaW5ncywgYW5pbWF0aW9ufTtcbn1cbiJdfQ==