@angular/animations 6.0.3 → 6.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/browser.metadata.json +1 -1
- package/browser/src/dsl/animation_transition_factory.d.ts +1 -1
- package/browser/src/render/animation_engine_next.d.ts +2 -1
- package/browser/src/render/shared.d.ts +2 -0
- package/browser/src/render/timeline_animation_engine.d.ts +2 -1
- package/browser/src/render/transition_animation_engine.d.ts +3 -3
- package/browser/testing.d.ts +0 -5
- package/browser/testing.metadata.json +1 -1
- package/browser.d.ts +0 -5
- package/browser.metadata.json +1 -1
- package/bundles/animations-browser-testing.umd.js +28 -10
- package/bundles/animations-browser-testing.umd.js.map +1 -1
- package/bundles/animations-browser-testing.umd.min.js +16 -2
- package/bundles/animations-browser-testing.umd.min.js.map +1 -1
- package/bundles/animations-browser.umd.js +200 -83
- package/bundles/animations-browser.umd.js.map +1 -1
- package/bundles/animations-browser.umd.min.js +55 -6
- package/bundles/animations-browser.umd.min.js.map +1 -1
- package/bundles/animations.umd.js +470 -577
- package/bundles/animations.umd.js.map +1 -1
- package/bundles/animations.umd.min.js +9 -2
- package/bundles/animations.umd.min.js.map +1 -1
- package/esm2015/animations.externs.js +1 -1
- package/esm2015/browser/browser.externs.js +3 -3
- package/esm2015/browser/src/dsl/animation_transition_factory.js +4 -3
- package/esm2015/browser/src/render/animation_driver.js +1 -12
- package/esm2015/browser/src/render/animation_engine_next.js +8 -4
- package/esm2015/browser/src/render/shared.js +18 -3
- package/esm2015/browser/src/render/timeline_animation_engine.js +6 -2
- package/esm2015/browser/src/render/transition_animation_engine.js +23 -19
- package/esm2015/browser/src/render/web_animations/web_animations_driver.js +3 -3
- package/esm2015/browser/src/util.js +57 -1
- package/esm2015/src/animation_metadata.js +626 -659
- package/esm2015/src/version.js +1 -1
- package/esm5/browser/index.js +5 -1
- package/esm5/browser/public_api.js +6 -1
- package/esm5/browser/src/browser.js +6 -1
- package/esm5/browser/src/dsl/animation.js +1 -1
- package/esm5/browser/src/dsl/animation_ast_builder.js +11 -4
- package/esm5/browser/src/dsl/animation_timeline_builder.js +27 -21
- package/esm5/browser/src/dsl/animation_timeline_instruction.js +1 -1
- package/esm5/browser/src/dsl/animation_transition_expr.js +1 -1
- package/esm5/browser/src/dsl/animation_transition_factory.js +3 -3
- package/esm5/browser/src/dsl/animation_transition_instruction.js +1 -1
- package/esm5/browser/src/dsl/animation_trigger.js +2 -8
- package/esm5/browser/src/dsl/element_instruction_map.js +1 -1
- package/esm5/browser/src/dsl/style_normalization/animation_style_normalizer.js +3 -15
- package/esm5/browser/src/dsl/style_normalization/web_animations_style_normalizer.js +8 -1
- package/esm5/browser/src/private_export.js +8 -1
- package/esm5/browser/src/render/animation_driver.js +8 -3
- package/esm5/browser/src/render/animation_engine_next.js +5 -4
- package/esm5/browser/src/render/css_keyframes/css_keyframes_driver.js +1 -1
- package/esm5/browser/src/render/css_keyframes/css_keyframes_player.js +2 -4
- package/esm5/browser/src/render/css_keyframes/direct_style_player.js +8 -1
- package/esm5/browser/src/render/css_keyframes/element_animation_style_handler.js +1 -1
- package/esm5/browser/src/render/shared.js +19 -3
- package/esm5/browser/src/render/timeline_animation_engine.js +10 -2
- package/esm5/browser/src/render/transition_animation_engine.js +36 -39
- package/esm5/browser/src/render/web_animations/dom_animation.js +1 -1
- package/esm5/browser/src/render/web_animations/web_animations_driver.js +3 -3
- package/esm5/browser/src/render/web_animations/web_animations_player.js +3 -7
- package/esm5/browser/src/util.js +51 -3
- package/esm5/browser/testing/index.js +5 -1
- package/esm5/browser/testing/public_api.js +6 -1
- package/esm5/browser/testing/src/mock_animation_driver.js +12 -17
- package/esm5/browser/testing/src/testing.js +8 -1
- package/esm5/index.js +5 -1
- package/esm5/public_api.js +6 -1
- package/esm5/src/animation_builder.js +3 -93
- package/esm5/src/animation_event.js +1 -1
- package/esm5/src/animation_metadata.js +439 -568
- package/esm5/src/animations.js +6 -1
- package/esm5/src/players/animation_group_player.js +2 -4
- package/esm5/src/players/animation_player.js +11 -14
- package/esm5/src/private_export.js +8 -1
- package/esm5/src/util.js +1 -1
- package/esm5/src/version.js +3 -23
- package/fesm2015/animations.js +446 -631
- package/fesm2015/animations.js.map +1 -1
- package/fesm2015/browser/testing.js +1 -1
- package/fesm2015/browser/testing.js.map +1 -1
- package/fesm2015/browser.js +104 -29
- package/fesm2015/browser.js.map +1 -1
- package/fesm5/animations.js +470 -577
- package/fesm5/animations.js.map +1 -1
- package/fesm5/browser/testing.js +28 -10
- package/fesm5/browser/testing.js.map +1 -1
- package/fesm5/browser.js +200 -83
- package/fesm5/browser.js.map +1 -1
- package/package.json +3 -3
- package/src/animation_metadata.d.ts +673 -650
|
@@ -1,38 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google Inc. 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
|
+
* Specifies automatic styling.
|
|
3
10
|
*/
|
|
4
11
|
export var AUTO_STYLE = '*';
|
|
5
12
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* {@link Component#animations component animations metadata page} to gain a better
|
|
9
|
-
* understanding of how animations in Angular are used.
|
|
10
|
-
*
|
|
11
|
-
* `trigger` Creates an animation trigger which will a list of {@link state state} and
|
|
12
|
-
* {@link transition transition} entries that will be evaluated when the expression
|
|
13
|
+
* Creates a named animation trigger, containing a list of `state()`
|
|
14
|
+
* and `transition()` entries to be evaluated when the expression
|
|
13
15
|
* bound to the trigger changes.
|
|
14
16
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
the
|
|
19
|
-
* trigger is bound to (in the form of `[@triggerName]="expression"`.
|
|
17
|
+
* @param name An identifying string.
|
|
18
|
+
* @param definitions An animation definition object, containing an array of `state()`
|
|
19
|
+
* and `transition()` declarations.
|
|
20
20
|
*
|
|
21
|
-
*
|
|
22
|
-
* any linked transitions. If a boolean value is provided into the trigger binding then it will both
|
|
23
|
-
* be represented as `1` or `true` and `0` or `false` for a true and false boolean values
|
|
24
|
-
* respectively.
|
|
21
|
+
* @return An object that encapsulates the trigger data.
|
|
25
22
|
*
|
|
26
|
-
*
|
|
23
|
+
* @usageNotes
|
|
24
|
+
* Define an animation trigger in the `animations` section of `@Component` metadata.
|
|
25
|
+
* In the template, reference the trigger by name and bind it to a trigger expression that
|
|
26
|
+
* evaluates to a defined animation state, using the following format:
|
|
27
|
+
*
|
|
28
|
+
* `[@triggerName]="expression"`
|
|
27
29
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
30
|
+
* Animation trigger bindings convert all values to strings, and then match the
|
|
31
|
+
* previous and current values against any linked transitions.
|
|
32
|
+
* Booleans can be specified as `1` or `true` and `0` or `false`.
|
|
33
|
+
*
|
|
34
|
+
* ### Usage Example
|
|
35
|
+
*
|
|
36
|
+
* The following example creates an animation trigger reference based on the provided
|
|
37
|
+
* name value.
|
|
38
|
+
* The provided animation value is expected to be an array consisting of state and
|
|
39
|
+
* transition declarations.
|
|
31
40
|
*
|
|
32
41
|
* ```typescript
|
|
33
42
|
* @Component({
|
|
34
|
-
* selector:
|
|
35
|
-
* templateUrl:
|
|
43
|
+
* selector: "my-component",
|
|
44
|
+
* templateUrl: "my-component-tpl.html",
|
|
36
45
|
* animations: [
|
|
37
46
|
* trigger("myAnimationTrigger", [
|
|
38
47
|
* state(...),
|
|
@@ -47,8 +56,8 @@ export var AUTO_STYLE = '*';
|
|
|
47
56
|
* }
|
|
48
57
|
* ```
|
|
49
58
|
*
|
|
50
|
-
* The template associated with this component
|
|
51
|
-
|
|
59
|
+
* The template associated with this component makes use of the defined trigger
|
|
60
|
+
* by binding to an element within its template code.
|
|
52
61
|
*
|
|
53
62
|
* ```html
|
|
54
63
|
* <!-- somewhere inside of my-component-tpl.html -->
|
|
@@ -59,9 +68,8 @@ export var AUTO_STYLE = '*';
|
|
|
59
68
|
* The `transition` animation method also supports reading an inline function which can decide
|
|
60
69
|
* if its associated animation should be run.
|
|
61
70
|
*
|
|
62
|
-
* ```
|
|
63
|
-
* // this method
|
|
64
|
-
* // trigger value changes...
|
|
71
|
+
* ```typescript
|
|
72
|
+
* // this method is run each time the `myAnimationTrigger` trigger value changes.
|
|
65
73
|
* function myInlineMatcherFn(fromState: string, toState: string, element: any, params: {[key:
|
|
66
74
|
string]: any}): boolean {
|
|
67
75
|
* // notice that `element` and `params` are also available here
|
|
@@ -84,18 +92,16 @@ export var AUTO_STYLE = '*';
|
|
|
84
92
|
* }
|
|
85
93
|
* ```
|
|
86
94
|
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
|
|
93
|
-
any animations on the element itself.
|
|
95
|
+
* ### Disabling Animations
|
|
96
|
+
* When true, the special animation control binding `@.disabled` binding prevents
|
|
97
|
+
* all animations from rendering.
|
|
98
|
+
* Place the `@.disabled` binding on an element to disable
|
|
99
|
+
* animations on the element itself, as well as any inner animation triggers
|
|
100
|
+
* within the element.
|
|
94
101
|
*
|
|
95
|
-
*
|
|
96
|
-
below shows how to use this feature:
|
|
102
|
+
* The following example shows how to use this feature:
|
|
97
103
|
*
|
|
98
|
-
* ```
|
|
104
|
+
* ```typescript
|
|
99
105
|
* @Component({
|
|
100
106
|
* selector: 'my-component',
|
|
101
107
|
* template: `
|
|
@@ -115,19 +121,16 @@ export var AUTO_STYLE = '*';
|
|
|
115
121
|
* }
|
|
116
122
|
* ```
|
|
117
123
|
*
|
|
118
|
-
*
|
|
119
|
-
|
|
120
|
-
*
|
|
121
|
-
* Note that `@.disabled` will only disable all animations (this means any animations running on
|
|
122
|
-
* the same element will also be disabled).
|
|
124
|
+
* When `@.disabled` is true, it prevents the `@childAnimation` trigger from animating,
|
|
125
|
+
* along with any inner animations.
|
|
123
126
|
*
|
|
124
|
-
* ###
|
|
125
|
-
* When an area of the template is set to have animations disabled,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
component.
|
|
127
|
+
* ### Disable animations application-wide
|
|
128
|
+
* When an area of the template is set to have animations disabled,
|
|
129
|
+
* **all** inner components have their animations disabled as well.
|
|
130
|
+
* This means that you can disable all animations for an app
|
|
131
|
+
* by placing a host binding set on `@.disabled` on the topmost Angular component.
|
|
129
132
|
*
|
|
130
|
-
* ```
|
|
133
|
+
* ```typescript
|
|
131
134
|
* import {Component, HostBinding} from '@angular/core';
|
|
132
135
|
*
|
|
133
136
|
* @Component({
|
|
@@ -140,19 +143,17 @@ export var AUTO_STYLE = '*';
|
|
|
140
143
|
* }
|
|
141
144
|
* ```
|
|
142
145
|
*
|
|
143
|
-
* ###
|
|
144
|
-
* Despite inner animations being disabled, a parent animation can
|
|
145
|
-
elements located in disabled areas of the template and still animate
|
|
146
|
-
also the case for when a sub animation is
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
* ### Detecting when an animation is disabled
|
|
150
|
-
* If a region of the DOM (or the entire application) has its animations disabled, then animation
|
|
151
|
-
* trigger callbacks will still fire just as normal (only for zero seconds).
|
|
146
|
+
* ### Overriding disablement of inner animations
|
|
147
|
+
* Despite inner animations being disabled, a parent animation can `query()`
|
|
148
|
+
* for inner elements located in disabled areas of the template and still animate
|
|
149
|
+
* them if needed. This is also the case for when a sub animation is
|
|
150
|
+
* queried by a parent and then later animated using `animateChild()`.
|
|
152
151
|
*
|
|
153
|
-
*
|
|
154
|
-
animations
|
|
155
|
-
*
|
|
152
|
+
* ### Detecting when an animation is disabled
|
|
153
|
+
* If a region of the DOM (or the entire application) has its animations disabled, the animation
|
|
154
|
+
* trigger callbacks still fire, but for zero seconds. When the callback fires, it provides
|
|
155
|
+
* an instance of an `AnimationEvent`. If animations are disabled,
|
|
156
|
+
* the `.disabled` flag on the event is true.
|
|
156
157
|
*
|
|
157
158
|
* @experimental Animation support is experimental.
|
|
158
159
|
*/
|
|
@@ -160,73 +161,74 @@ export function trigger(name, definitions) {
|
|
|
160
161
|
return { type: 7 /* Trigger */, name: name, definitions: definitions, options: {} };
|
|
161
162
|
}
|
|
162
163
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
164
|
+
* Defines an animation step that combines styling information with timing information.
|
|
165
|
+
*
|
|
166
|
+
* @param timings Sets `AnimateTimings` for the parent animation.
|
|
167
|
+
* A string in the format "duration [delay] [easing]".
|
|
168
|
+
* - Duration and delay are expressed as a number and optional time unit,
|
|
169
|
+
* such as "1s" or "10ms" for one second and 10 milliseconds, respectively.
|
|
170
|
+
* The default unit is milliseconds.
|
|
171
|
+
* - The easing value controls how the animation accelerates and decelerates
|
|
172
|
+
* during its runtime. Value is one of `ease`, `ease-in`, `ease-out`,
|
|
173
|
+
* `ease-in-out`, or a `cubic-bezier()` function call.
|
|
174
|
+
* If not supplied, no easing is applied.
|
|
175
|
+
*
|
|
176
|
+
* For example, the string "1s 100ms ease-out" specifies a duration of
|
|
177
|
+
* 1000 milliseconds, and delay of 100 ms, and the "ease-out" easing style,
|
|
178
|
+
* which decelerates near the end of the duration.
|
|
179
|
+
* @param styles Sets AnimationStyles for the parent animation.
|
|
180
|
+
* A function call to either `style()` or `keyframes()`
|
|
181
|
+
* that returns a collection of CSS style entries to be applied to the parent animation.
|
|
182
|
+
* When null, uses the styles from the destination state.
|
|
183
|
+
* This is useful when describing an animation step that will complete an animation;
|
|
184
|
+
* see "Animating to the final state" in `transitions()`.
|
|
185
|
+
* @returns An object that encapsulates the animation step.
|
|
186
|
+
*
|
|
187
|
+
* @usageNotes
|
|
188
|
+
* Call within an animation `sequence()`, `{@link animations/group group()}`, or
|
|
189
|
+
* `transition()` call to specify an animation step
|
|
190
|
+
* that applies given style data to the parent animation for a given amount of time.
|
|
191
|
+
*
|
|
192
|
+
* ### Syntax Examples
|
|
193
|
+
* **Timing examples**
|
|
194
|
+
*
|
|
195
|
+
* The following examples show various `timings` specifications.
|
|
196
|
+
* - `animate(500)` : Duration is 500 milliseconds.
|
|
197
|
+
* - `animate("1s")` : Duration is 1000 milliseconds.
|
|
198
|
+
* - `animate("100ms 0.5s")` : Duration is 100 milliseconds, delay is 500 milliseconds.
|
|
199
|
+
* - `animate("5s ease-in")` : Duration is 5000 milliseconds, easing in.
|
|
200
|
+
* - `animate("5s 10ms cubic-bezier(.17,.67,.88,.1)")` : Duration is 5000 milliseconds, delay is 10
|
|
201
|
+
* milliseconds, easing according to a bezier curve.
|
|
202
|
+
*
|
|
203
|
+
* **Style examples**
|
|
204
|
+
*
|
|
205
|
+
* The following example calls `style()` to set a single CSS style.
|
|
187
206
|
* ```typescript
|
|
188
|
-
* // various functions for specifying timing data
|
|
189
|
-
* animate(500, style(...))
|
|
190
|
-
* animate("1s", style(...))
|
|
191
|
-
* animate("100ms 0.5s", style(...))
|
|
192
|
-
* animate("5s ease", style(...))
|
|
193
|
-
* animate("5s 10ms cubic-bezier(.17,.67,.88,.1)", style(...))
|
|
194
|
-
*
|
|
195
|
-
* // either style() of keyframes() can be used
|
|
196
207
|
* animate(500, style({ background: "red" }))
|
|
197
|
-
*
|
|
208
|
+
* ```
|
|
209
|
+
* The following example calls `keyframes()` to set a CSS style
|
|
210
|
+
* to different values for successive keyframes.
|
|
211
|
+
* ```typescript
|
|
212
|
+
* animate(500, keyframes(
|
|
213
|
+
* [
|
|
198
214
|
* style({ background: "blue" })),
|
|
199
215
|
* style({ background: "red" }))
|
|
200
|
-
*
|
|
216
|
+
* ])
|
|
201
217
|
* ```
|
|
202
|
-
*
|
|
203
|
-
* {@example core/animation/ts/dsl/animation_example.ts region='Component'}
|
|
204
|
-
*
|
|
205
|
-
* @experimental Animation support is experimental.
|
|
206
218
|
*/
|
|
207
219
|
export function animate(timings, styles) {
|
|
208
220
|
if (styles === void 0) { styles = null; }
|
|
209
221
|
return { type: 4 /* Animate */, styles: styles, timings: timings };
|
|
210
222
|
}
|
|
211
223
|
/**
|
|
212
|
-
*
|
|
213
|
-
* animation DSL language. If this information is new, please navigate to the {@link
|
|
214
|
-
* Component#animations component animations metadata page} to gain a better understanding of
|
|
215
|
-
* how animations in Angular are used.
|
|
216
|
-
*
|
|
217
|
-
* `group` specifies a list of animation steps that are all run in parallel. Grouped animations are
|
|
218
|
-
* useful when a series of styles must be animated/closed off at different starting/ending times.
|
|
219
|
-
*
|
|
220
|
-
* The `group` function can either be used within a {@link sequence sequence} or a {@link transition
|
|
221
|
-
* transition} and it will only continue to the next instruction once all of the inner animation
|
|
222
|
-
* steps have completed.
|
|
224
|
+
* @description Defines a list of animation steps to be run in parallel.
|
|
223
225
|
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
226
|
+
* @param steps An array of animation step objects.
|
|
227
|
+
* - When steps are defined by `style()` or `animate()`
|
|
228
|
+
* function calls, each call within the group is executed instantly.
|
|
229
|
+
* - To specify offset styles to be applied at a later time, define steps with
|
|
230
|
+
* `keyframes()`, or use `animate()` calls with a delay value.
|
|
231
|
+
* For example:
|
|
230
232
|
*
|
|
231
233
|
* ```typescript
|
|
232
234
|
* group([
|
|
@@ -235,36 +237,31 @@ export function animate(timings, styles) {
|
|
|
235
237
|
* ])
|
|
236
238
|
* ```
|
|
237
239
|
*
|
|
238
|
-
*
|
|
240
|
+
* @param options An options object containing a delay and
|
|
241
|
+
* developer-defined parameters that provide styling defaults and
|
|
242
|
+
* can be overridden on invocation.
|
|
239
243
|
*
|
|
240
|
-
* @
|
|
244
|
+
* @return An object that encapsulates the group data.
|
|
245
|
+
*
|
|
246
|
+
* @usageNotes
|
|
247
|
+
* Grouped animations are useful when a series of styles must be
|
|
248
|
+
* animated at different starting times and closed off at different ending times.
|
|
249
|
+
*
|
|
250
|
+
* When called within a `sequence()` or a
|
|
251
|
+
* `transition()` call, does not continue to the next
|
|
252
|
+
* instruction until all of the inner animation steps have completed.
|
|
241
253
|
*/
|
|
242
254
|
export function group(steps, options) {
|
|
243
255
|
if (options === void 0) { options = null; }
|
|
244
256
|
return { type: 3 /* Group */, steps: steps, options: options };
|
|
245
257
|
}
|
|
246
258
|
/**
|
|
247
|
-
*
|
|
248
|
-
* animation DSL language. If this information is new, please navigate to the {@link
|
|
249
|
-
* Component#animations component animations metadata page} to gain a better understanding of
|
|
250
|
-
* how animations in Angular are used.
|
|
251
|
-
*
|
|
252
|
-
* `sequence` Specifies a list of animation steps that are run one by one. (`sequence` is used by
|
|
253
|
-
* default when an array is passed as animation data into {@link transition transition}.)
|
|
254
|
-
*
|
|
255
|
-
* The `sequence` function can either be used within a {@link group group} or a {@link transition
|
|
256
|
-
* transition} and it will only continue to the next instruction once each of the inner animation
|
|
257
|
-
* steps have completed.
|
|
258
|
-
*
|
|
259
|
-
* To perform animation styling in parallel with other animation steps then have a look at the
|
|
260
|
-
* {@link group group} animation function.
|
|
261
|
-
*
|
|
262
|
-
* ### Usage
|
|
259
|
+
* Defines a list of animation steps to be run sequentially, one by one.
|
|
263
260
|
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
261
|
+
* @param steps An array of animation step objects.
|
|
262
|
+
* - Steps defined by `style()` calls apply the styling data immediately.
|
|
263
|
+
* - Steps defined by `animate()` calls apply the styling data over time
|
|
264
|
+
* as specified by the timing data.
|
|
268
265
|
*
|
|
269
266
|
* ```typescript
|
|
270
267
|
* sequence([
|
|
@@ -273,131 +270,120 @@ export function group(steps, options) {
|
|
|
273
270
|
* ])
|
|
274
271
|
* ```
|
|
275
272
|
*
|
|
276
|
-
*
|
|
273
|
+
* @param options An options object containing a delay and
|
|
274
|
+
* developer-defined parameters that provide styling defaults and
|
|
275
|
+
* can be overridden on invocation.
|
|
277
276
|
*
|
|
278
|
-
* @
|
|
279
|
-
|
|
277
|
+
* @return An object that encapsulates the sequence data.
|
|
278
|
+
*
|
|
279
|
+
* @usageNotes
|
|
280
|
+
* When you pass an array of steps to a
|
|
281
|
+
* `transition()` call, the steps run sequentially by default.
|
|
282
|
+
* Compare this to the `{@link animations/group group()}` call, which runs animation steps in parallel.
|
|
283
|
+
*
|
|
284
|
+
* When a sequence is used within a `{@link animations/group group()}` or a `transition()` call,
|
|
285
|
+
* execution continues to the next instruction only after each of the inner animation
|
|
286
|
+
* steps have completed.
|
|
287
|
+
*
|
|
288
|
+
**/
|
|
280
289
|
export function sequence(steps, options) {
|
|
281
290
|
if (options === void 0) { options = null; }
|
|
282
291
|
return { type: 2 /* Sequence */, steps: steps, options: options };
|
|
283
292
|
}
|
|
284
293
|
/**
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
* how animations in Angular are used.
|
|
294
|
+
* Declares a key/value object containing CSS properties/styles that
|
|
295
|
+
* can then be used for an animation `state`, within an animation `sequence`,
|
|
296
|
+
* or as styling data for calls to `animate()` and `keyframes()`.
|
|
289
297
|
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
298
|
+
* @param tokens A set of CSS styles or HTML styles associated with an animation state.
|
|
299
|
+
* The value can be any of the following:
|
|
300
|
+
* - A key-value style pair associating a CSS property with a value.
|
|
301
|
+
* - An array of key-value style pairs.
|
|
302
|
+
* - An asterisk (*), to use auto-styling, where styles are derived from the element
|
|
303
|
+
* being animated and applied to the animation when it starts.
|
|
293
304
|
*
|
|
294
|
-
*
|
|
305
|
+
* Auto-styling can be used to define a state that depends on layout or other
|
|
306
|
+
* environmental factors.
|
|
295
307
|
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
308
|
+
* @return An object that encapsulates the style data.
|
|
309
|
+
*
|
|
310
|
+
* @usageNotes
|
|
311
|
+
* The following examples create animation styles that collect a set of
|
|
312
|
+
* CSS property values:
|
|
298
313
|
*
|
|
299
314
|
* ```typescript
|
|
300
|
-
* // string values
|
|
315
|
+
* // string values for CSS properties
|
|
301
316
|
* style({ background: "red", color: "blue" })
|
|
302
317
|
*
|
|
303
|
-
* // numerical
|
|
318
|
+
* // numerical pixel values
|
|
304
319
|
* style({ width: 100, height: 0 })
|
|
305
320
|
* ```
|
|
306
321
|
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
* When an asterix (`*`) character is used as a value then it will be detected from the element
|
|
310
|
-
* being animated and applied as animation data when the animation starts.
|
|
311
|
-
*
|
|
312
|
-
* This feature proves useful for a state depending on layout and/or environment factors; in such
|
|
313
|
-
* cases the styles are calculated just before the animation starts.
|
|
322
|
+
* The following example uses auto-styling to allow a component to animate from
|
|
323
|
+
* a height of 0 up to the height of the parent element:
|
|
314
324
|
*
|
|
315
|
-
* ```
|
|
316
|
-
* // the steps below will animate from 0 to the
|
|
317
|
-
* // actual height of the element
|
|
325
|
+
* ```
|
|
318
326
|
* style({ height: 0 }),
|
|
319
327
|
* animate("1s", style({ height: "*" }))
|
|
320
328
|
* ```
|
|
321
329
|
*
|
|
322
|
-
|
|
323
|
-
*
|
|
324
|
-
* @experimental Animation support is experimental.
|
|
325
|
-
*/
|
|
330
|
+
**/
|
|
326
331
|
export function style(tokens) {
|
|
327
332
|
return { type: 6 /* Style */, styles: tokens, offset: null };
|
|
328
333
|
}
|
|
329
334
|
/**
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
* trigger
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
|
|
356
|
-
* `state` will declare an animation state with its associated styles
|
|
357
|
-
* within the given trigger.
|
|
358
|
-
*
|
|
359
|
-
* - `stateNameExpr` can be one or more state names separated by commas.
|
|
360
|
-
* - `styles` refers to the {@link style styling data} that will be persisted on the element once
|
|
361
|
-
* the state has been reached.
|
|
362
|
-
*
|
|
363
|
-
* ```typescript
|
|
364
|
-
* // "void" is a reserved name for a state and is used to represent
|
|
365
|
-
* // the state in which an element is detached from from the application.
|
|
366
|
-
* state("void", style({ height: 0 }))
|
|
367
|
-
*
|
|
368
|
-
* // user-defined states
|
|
369
|
-
* state("closed", style({ height: 0 }))
|
|
370
|
-
* state("open, visible", style({ height: "*" }))
|
|
371
|
-
* ```
|
|
372
|
-
*
|
|
373
|
-
* {@example core/animation/ts/dsl/animation_example.ts region='Component'}
|
|
374
|
-
*
|
|
375
|
-
* @experimental Animation support is experimental.
|
|
376
|
-
*/
|
|
335
|
+
* Declares an animation state within a trigger attached to an element.
|
|
336
|
+
*
|
|
337
|
+
* @param name One or more names for the defined state in a comma-separated string.
|
|
338
|
+
* The following reserved state names can be supplied to define a style for specific use
|
|
339
|
+
* cases:
|
|
340
|
+
*
|
|
341
|
+
* - `void` You can associate styles with this name to be used when
|
|
342
|
+
* the element is detached from the application. For example, when an `ngIf` evaluates
|
|
343
|
+
* to false, the state of the associated element is void.
|
|
344
|
+
* - `*` (asterisk) Indicates the default state. You can associate styles with this name
|
|
345
|
+
* to be used as the fallback when the state that is being animated is not declared
|
|
346
|
+
* within the trigger.
|
|
347
|
+
*
|
|
348
|
+
* @param styles A set of CSS styles associated with this state, created using the
|
|
349
|
+
* `style()` function.
|
|
350
|
+
* This set of styles persists on the element once the state has been reached.
|
|
351
|
+
* @param options Parameters that can be passed to the state when it is invoked.
|
|
352
|
+
* 0 or more key-value pairs.
|
|
353
|
+
* @return An object that encapsulates the new state data.
|
|
354
|
+
*
|
|
355
|
+
* @usageNotes
|
|
356
|
+
* Use the `trigger()` function to register states to an animation trigger.
|
|
357
|
+
* Use the `transition()` function to animate between states.
|
|
358
|
+
* When a state is active within a component, its associated styles persist on the element,
|
|
359
|
+
* even when the animation ends.
|
|
360
|
+
**/
|
|
377
361
|
export function state(name, styles, options) {
|
|
378
362
|
return { type: 0 /* State */, name: name, styles: styles, options: options };
|
|
379
363
|
}
|
|
380
364
|
/**
|
|
381
|
-
*
|
|
382
|
-
* animation DSL language. If this information is new, please navigate to the {@link
|
|
383
|
-
* Component#animations component animations metadata page} to gain a better understanding of
|
|
384
|
-
* how animations in Angular are used.
|
|
365
|
+
* Defines a set of animation styles, associating each style with an optional `offset` value.
|
|
385
366
|
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
367
|
+
* @param steps A set of animation styles with optional offset data.
|
|
368
|
+
* The optional `offset` value for a style specifies a percentage of the total animation
|
|
369
|
+
* time at which that style is applied.
|
|
370
|
+
* @returns An object that encapsulates the keyframes data.
|
|
388
371
|
*
|
|
389
|
-
*
|
|
372
|
+
* @usageNotes
|
|
373
|
+
* Use with the `animate()` call. Instead of applying animations
|
|
374
|
+
* from the current state
|
|
375
|
+
* to the destination state, keyframes describe how each style entry is applied and at what point
|
|
376
|
+
* within the animation arc.
|
|
377
|
+
* Compare [CSS Keyframe Animations](https://www.w3schools.com/css/css3_animations.asp).
|
|
390
378
|
*
|
|
391
|
-
*
|
|
392
|
-
* animation function. Instead of applying animations from where they are currently to their
|
|
393
|
-
* destination, keyframes can describe how each style entry is applied and at what point within the
|
|
394
|
-
* animation arc (much like CSS Keyframe Animations do).
|
|
379
|
+
* ### Usage
|
|
395
380
|
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
381
|
+
* In the following example, the offset values describe
|
|
382
|
+
* when each `backgroundColor` value is applied. The color is red at the start, and changes to
|
|
383
|
+
* blue when 20% of the total time has elapsed.
|
|
398
384
|
*
|
|
399
385
|
* ```typescript
|
|
400
|
-
* // the provided offset values
|
|
386
|
+
* // the provided offset values
|
|
401
387
|
* animate("5s", keyframes([
|
|
402
388
|
* style({ backgroundColor: "red", offset: 0 }),
|
|
403
389
|
* style({ backgroundColor: "blue", offset: 0.2 }),
|
|
@@ -406,8 +392,8 @@ export function state(name, styles, options) {
|
|
|
406
392
|
* ]))
|
|
407
393
|
* ```
|
|
408
394
|
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
395
|
+
* If there are no `offset` values specified in the style entries, the offsets
|
|
396
|
+
* are calculated automatically.
|
|
411
397
|
*
|
|
412
398
|
* ```typescript
|
|
413
399
|
* animate("5s", keyframes([
|
|
@@ -416,240 +402,211 @@ export function state(name, styles, options) {
|
|
|
416
402
|
* style({ backgroundColor: "orange" }) // offset = 0.66
|
|
417
403
|
* style({ backgroundColor: "black" }) // offset = 1
|
|
418
404
|
* ]))
|
|
419
|
-
|
|
420
|
-
*
|
|
421
|
-
* {@example core/animation/ts/dsl/animation_example.ts region='Component'}
|
|
422
|
-
*
|
|
423
|
-
* @experimental Animation support is experimental.
|
|
405
|
+
*```
|
|
424
406
|
*/
|
|
425
407
|
export function keyframes(steps) {
|
|
426
408
|
return { type: 5 /* Keyframes */, steps: steps };
|
|
427
409
|
}
|
|
428
410
|
/**
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
* `transition` declares the {@link sequence sequence of animation steps} that will be run when the
|
|
435
|
-
* provided `stateChangeExpr` value is satisfied. The `stateChangeExpr` consists of a `state1 =>
|
|
436
|
-
* state2` which consists of two known states (use an asterix (`*`) to refer to a dynamic starting
|
|
437
|
-
* and/or ending state).
|
|
438
|
-
*
|
|
439
|
-
* A function can also be provided as the `stateChangeExpr` argument for a transition and this
|
|
440
|
-
* function will be executed each time a state change occurs. If the value returned within the
|
|
441
|
-
* function is true then the associated animation will be run.
|
|
442
|
-
*
|
|
443
|
-
* Animation transitions are placed within an {@link trigger animation trigger}. For an transition
|
|
444
|
-
* to animate to a state value and persist its styles then one or more {@link state animation
|
|
445
|
-
* states} is expected to be defined.
|
|
411
|
+
* Declares an animation transition as a sequence of animation steps to run when a given
|
|
412
|
+
* condition is satisfied. The condition is a Boolean expression or function that compares
|
|
413
|
+
* the previous and current animation states, and returns true if this transition should occur.
|
|
414
|
+
* When the state criteria of a defined transition are met, the associated animation is
|
|
415
|
+
* triggered.
|
|
446
416
|
*
|
|
447
|
-
*
|
|
417
|
+
* @param stateChangeExpr A Boolean expression or function that compares the previous and current
|
|
418
|
+
* animation states, and returns true if this transition should occur. Note that "true" and "false"
|
|
419
|
+
* match 1 and 0, respectively. An expression is evaluated each time a state change occurs in the
|
|
420
|
+
* animation trigger element.
|
|
421
|
+
* The animation steps run when the expression evaluates to true.
|
|
422
|
+
*
|
|
423
|
+
* - A state-change string takes the form "state1 => state2", where each side is a defined animation
|
|
424
|
+
* state, or an asterix (*) to refer to a dynamic start or end state.
|
|
425
|
+
* - The expression string can contain multiple comma-separated statements;
|
|
426
|
+
* for example "state1 => state2, state3 => state4".
|
|
427
|
+
* - Special values `:enter` and `:leave` initiate a transition on the entry and exit states,
|
|
428
|
+
* equivalent to "void => *" and "* => void".
|
|
429
|
+
* - Special values `:increment` and `:decrement` initiate a transition when a numeric value has
|
|
430
|
+
* increased or decreased in value.
|
|
431
|
+
* - A function is executed each time a state change occurs in the animation trigger element.
|
|
432
|
+
* The animation steps run when the function returns true.
|
|
433
|
+
*
|
|
434
|
+
* @param steps One or more animation objects, as returned by the `animate()` or
|
|
435
|
+
* `sequence()` function, that form a transformation from one state to another.
|
|
436
|
+
* A sequence is used by default when you pass an array.
|
|
437
|
+
* @param options An options object that can contain a delay value for the start of the animation,
|
|
438
|
+
* and additional developer-defined parameters. Provided values for additional parameters are used
|
|
439
|
+
* as defaults, and override values can be passed to the caller on invocation.
|
|
440
|
+
* @returns An object that encapsulates the transition data.
|
|
441
|
+
*
|
|
442
|
+
* @usageNotes
|
|
443
|
+
* The template associated with a component binds an animation trigger to an element.
|
|
444
|
+
*
|
|
445
|
+
* ```HTML
|
|
446
|
+
* <!-- somewhere inside of my-component-tpl.html -->
|
|
447
|
+
* <div [@myAnimationTrigger]="myStatusExp">...</div>
|
|
448
|
+
* ```
|
|
448
449
|
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* is defined that matches the old/current state criteria then the associated animation will be
|
|
452
|
-
* triggered.
|
|
450
|
+
* All transitions are defined within an animation trigger,
|
|
451
|
+
* along with named states that the transitions change to and from.
|
|
453
452
|
*
|
|
454
453
|
* ```typescript
|
|
455
|
-
* // all transition/state changes are defined within an animation trigger
|
|
456
454
|
* trigger("myAnimationTrigger", [
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
* // a transition animation that will be kicked off when the state value
|
|
463
|
-
* // bound to "myAnimationTrigger" changes from "on" to "off"
|
|
464
|
-
* transition("on => off", animate(500)),
|
|
465
|
-
*
|
|
466
|
-
* // it is also possible to do run the same animation for both directions
|
|
467
|
-
* transition("on <=> off", animate(500)),
|
|
468
|
-
*
|
|
469
|
-
* // or to define multiple states pairs separated by commas
|
|
470
|
-
* transition("on => off, off => void", animate(500)),
|
|
471
|
-
*
|
|
472
|
-
* // this is a catch-all state change for when an element is inserted into
|
|
473
|
-
* // the page and the destination state is unknown
|
|
474
|
-
* transition("void => *", [
|
|
475
|
-
* style({ opacity: 0 }),
|
|
476
|
-
* animate(500)
|
|
477
|
-
* ]),
|
|
455
|
+
* // define states
|
|
456
|
+
* state("on", style({ background: "green" })),
|
|
457
|
+
* state("off", style({ background: "grey" })),
|
|
458
|
+
* ...]
|
|
459
|
+
* ```
|
|
478
460
|
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
461
|
+
* Note that when you call the `sequence()` function within a `{@link animations/group group()}`
|
|
462
|
+
* or a `transition()` call, execution does not continue to the next instruction
|
|
463
|
+
* until each of the inner animation steps have completed.
|
|
481
464
|
*
|
|
482
|
-
*
|
|
483
|
-
* transition((fromState, toState) => {
|
|
484
|
-
* // when `true` then it will allow the animation below to be invoked
|
|
485
|
-
* return fromState == "off" && toState == "on";
|
|
486
|
-
* }, animate("1s 0s"))
|
|
487
|
-
* ])
|
|
488
|
-
* ```
|
|
465
|
+
* ### Syntax examples
|
|
489
466
|
*
|
|
490
|
-
* The
|
|
491
|
-
*
|
|
467
|
+
* The following examples define transitions between the two defined states (and default states),
|
|
468
|
+
* using various options:
|
|
492
469
|
*
|
|
493
|
-
* ```
|
|
494
|
-
*
|
|
495
|
-
*
|
|
470
|
+
* ```typescript
|
|
471
|
+
* // Transition occurs when the state value
|
|
472
|
+
* // bound to "myAnimationTrigger" changes from "on" to "off"
|
|
473
|
+
* transition("on => off", animate(500))
|
|
474
|
+
* // Run the same animation for both directions
|
|
475
|
+
* transition("on <=> off", animate(500))
|
|
476
|
+
* // Define multiple state-change pairs separated by commas
|
|
477
|
+
* transition("on => off, off => void", animate(500))
|
|
496
478
|
* ```
|
|
497
479
|
*
|
|
498
|
-
*
|
|
480
|
+
* ### Special values for state-change expressions
|
|
499
481
|
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
* for the element to animate itself to the final state. This involves an automatic mix of
|
|
503
|
-
* adding/removing CSS styles so that the element will be in the exact state it should be for the
|
|
504
|
-
* applied state to be presented correctly.
|
|
482
|
+
* - Catch-all state change for when an element is inserted into the page and the
|
|
483
|
+
* destination state is unknown:
|
|
505
484
|
*
|
|
506
|
-
* ```
|
|
507
|
-
* // start off by hiding the element, but make sure that it animates properly to whatever state
|
|
508
|
-
* // is currently active for "myAnimationTrigger"
|
|
485
|
+
* ```typescript
|
|
509
486
|
* transition("void => *", [
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
487
|
+
* style({ opacity: 0 }),
|
|
488
|
+
* animate(500)
|
|
489
|
+
* ])
|
|
513
490
|
* ```
|
|
514
491
|
*
|
|
515
|
-
*
|
|
492
|
+
* - Capture a state change between any states:
|
|
516
493
|
*
|
|
517
|
-
*
|
|
518
|
-
* function accepts both `:enter` and `:leave` values which are aliases for the `void => *` and `*
|
|
519
|
-
* => void` state changes.
|
|
494
|
+
* `transition("* => *", animate("1s 0s"))`
|
|
520
495
|
*
|
|
521
|
-
*
|
|
496
|
+
* - Entry and exit transitions:
|
|
497
|
+
*
|
|
498
|
+
* ```typescript
|
|
522
499
|
* transition(":enter", [
|
|
523
500
|
* style({ opacity: 0 }),
|
|
524
501
|
* animate(500, style({ opacity: 1 }))
|
|
525
|
-
*
|
|
502
|
+
* ]),
|
|
526
503
|
* transition(":leave", [
|
|
527
504
|
* animate(500, style({ opacity: 0 }))
|
|
528
|
-
*
|
|
505
|
+
* ])
|
|
529
506
|
* ```
|
|
530
507
|
*
|
|
531
|
-
*
|
|
532
|
-
* if a trigger binding value is a boolean value then it can be matched using a transition
|
|
533
|
-
* expression that compares `true` and `false` or `1` and `0`.
|
|
508
|
+
* - Use `:increment` and `:decrement` to initiate transitions:
|
|
534
509
|
*
|
|
535
|
-
* ```
|
|
536
|
-
*
|
|
537
|
-
*
|
|
510
|
+
* ```typescript
|
|
511
|
+
* transition(":increment", group([
|
|
512
|
+
* query(':enter', [
|
|
513
|
+
* style({ left: '100%' }),
|
|
514
|
+
* animate('0.5s ease-out', style('*'))
|
|
515
|
+
* ]),
|
|
516
|
+
* query(':leave', [
|
|
517
|
+
* animate('0.5s ease-out', style({ left: '-100%' }))
|
|
518
|
+
* ])
|
|
519
|
+
* ]))
|
|
538
520
|
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
521
|
+
* transition(":decrement", group([
|
|
522
|
+
* query(':enter', [
|
|
523
|
+
* style({ left: '100%' }),
|
|
524
|
+
* animate('0.5s ease-out', style('*'))
|
|
525
|
+
* ]),
|
|
526
|
+
* query(':leave', [
|
|
527
|
+
* animate('0.5s ease-out', style({ left: '-100%' }))
|
|
528
|
+
* ])
|
|
529
|
+
* ]))
|
|
545
530
|
* ```
|
|
546
531
|
*
|
|
547
|
-
* ###
|
|
548
|
-
*
|
|
549
|
-
*
|
|
532
|
+
* ### State-change functions
|
|
533
|
+
*
|
|
534
|
+
* Here is an example of a `fromState` specified as a state-change function that invokes an
|
|
535
|
+
* animation when true:
|
|
550
536
|
*
|
|
537
|
+
* ```typescript
|
|
538
|
+
* transition((fromState, toState) =>
|
|
539
|
+
* {
|
|
540
|
+
* return fromState == "off" && toState == "on";
|
|
541
|
+
* },
|
|
542
|
+
* animate("1s 0s"))
|
|
551
543
|
* ```
|
|
552
|
-
* import {group, animate, query, transition, style, trigger} from '@angular/animations';
|
|
553
|
-
* import {Component} from '@angular/core';
|
|
554
544
|
*
|
|
555
|
-
*
|
|
556
|
-
* selector: 'banner-carousel-component',
|
|
557
|
-
* styles: [`
|
|
558
|
-
* .banner-container {
|
|
559
|
-
* position:relative;
|
|
560
|
-
* height:500px;
|
|
561
|
-
* overflow:hidden;
|
|
562
|
-
* }
|
|
563
|
-
* .banner-container > .banner {
|
|
564
|
-
* position:absolute;
|
|
565
|
-
* left:0;
|
|
566
|
-
* top:0;
|
|
567
|
-
* font-size:200px;
|
|
568
|
-
* line-height:500px;
|
|
569
|
-
* font-weight:bold;
|
|
570
|
-
* text-align:center;
|
|
571
|
-
* width:100%;
|
|
572
|
-
* }
|
|
573
|
-
* `],
|
|
574
|
-
* template: `
|
|
575
|
-
* <button (click)="previous()">Previous</button>
|
|
576
|
-
* <button (click)="next()">Next</button>
|
|
577
|
-
* <hr>
|
|
578
|
-
* <div [@bannerAnimation]="selectedIndex" class="banner-container">
|
|
579
|
-
* <div class="banner" *ngFor="let banner of banners"> {{ banner }} </div>
|
|
580
|
-
* </div>
|
|
581
|
-
* `,
|
|
582
|
-
* animations: [
|
|
583
|
-
* trigger('bannerAnimation', [
|
|
584
|
-
* transition(":increment", group([
|
|
585
|
-
* query(':enter', [
|
|
586
|
-
* style({ left: '100%' }),
|
|
587
|
-
* animate('0.5s ease-out', style('*'))
|
|
588
|
-
* ]),
|
|
589
|
-
* query(':leave', [
|
|
590
|
-
* animate('0.5s ease-out', style({ left: '-100%' }))
|
|
591
|
-
* ])
|
|
592
|
-
* ])),
|
|
593
|
-
* transition(":decrement", group([
|
|
594
|
-
* query(':enter', [
|
|
595
|
-
* style({ left: '-100%' }),
|
|
596
|
-
* animate('0.5s ease-out', style('*'))
|
|
597
|
-
* ]),
|
|
598
|
-
* query(':leave', [
|
|
599
|
-
* animate('0.5s ease-out', style({ left: '100%' }))
|
|
600
|
-
* ])
|
|
601
|
-
* ]))
|
|
602
|
-
* ])
|
|
603
|
-
* ]
|
|
604
|
-
* })
|
|
605
|
-
* class BannerCarouselComponent {
|
|
606
|
-
* allBanners: string[] = ['1', '2', '3', '4'];
|
|
607
|
-
* selectedIndex: number = 0;
|
|
545
|
+
* ### Animating to the final state
|
|
608
546
|
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
547
|
+
* If the final step in a transition is a call to `animate()` that uses a timing value
|
|
548
|
+
* with no style data, that step is automatically considered the final animation arc,
|
|
549
|
+
* for the element to reach the final state. Angular automatically adds or removes
|
|
550
|
+
* CSS styles to ensure that the element is in the correct final state.
|
|
612
551
|
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
* }
|
|
552
|
+
* The following example defines a transition that starts by hiding the element,
|
|
553
|
+
* then makes sure that it animates properly to whatever state is currently active for trigger:
|
|
616
554
|
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
* }
|
|
620
|
-
*
|
|
555
|
+
* ```typescript
|
|
556
|
+
* transition("void => *", [
|
|
557
|
+
* style({ opacity: 0 }),
|
|
558
|
+
* animate(500)
|
|
559
|
+
* ])
|
|
621
560
|
* ```
|
|
561
|
+
* ### Boolean value matching
|
|
562
|
+
* If a trigger binding value is a Boolean, it can be matched using a transition expression
|
|
563
|
+
* that compares true and false or 1 and 0. For example:
|
|
622
564
|
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
* @
|
|
626
|
-
|
|
565
|
+
* ```
|
|
566
|
+
* // in the template
|
|
567
|
+
* <div [@openClose]="open ? true : false">...</div>
|
|
568
|
+
* // in the component metadata
|
|
569
|
+
* trigger('openClose', [
|
|
570
|
+
* state('true', style({ height: '*' })),
|
|
571
|
+
* state('false', style({ height: '0px' })),
|
|
572
|
+
* transition('false <=> true', animate(500))
|
|
573
|
+
* ])
|
|
574
|
+
* ```
|
|
575
|
+
**/
|
|
627
576
|
export function transition(stateChangeExpr, steps, options) {
|
|
628
577
|
if (options === void 0) { options = null; }
|
|
629
578
|
return { type: 1 /* Transition */, expr: stateChangeExpr, animation: steps, options: options };
|
|
630
579
|
}
|
|
631
580
|
/**
|
|
632
|
-
*
|
|
633
|
-
*
|
|
581
|
+
* Produces a reusable animation that can be invoked in another animation or sequence,
|
|
582
|
+
* by calling the `useAnimation()` function.
|
|
583
|
+
*
|
|
584
|
+
* @param steps One or more animation objects, as returned by the `animate()`
|
|
585
|
+
* or `sequence()` function, that form a transformation from one state to another.
|
|
586
|
+
* A sequence is used by default when you pass an array.
|
|
587
|
+
* @param options An options object that can contain a delay value for the start of the
|
|
588
|
+
* animation, and additional developer-defined parameters.
|
|
589
|
+
* Provided values for additional parameters are used as defaults,
|
|
590
|
+
* and override values can be passed to the caller on invocation.
|
|
591
|
+
* @returns An object that encapsulates the animation data.
|
|
592
|
+
*
|
|
593
|
+
* @usageNotes
|
|
594
|
+
* The following example defines a reusable animation, providing some default parameter
|
|
595
|
+
* values.
|
|
634
596
|
*
|
|
635
|
-
*
|
|
636
|
-
* invoked in another animation or sequence. Reusable animations are designed to make use of
|
|
637
|
-
* animation parameters and the produced animation can be used via the `useAnimation` method.
|
|
638
|
-
*
|
|
639
|
-
* ```
|
|
597
|
+
* ```typescript
|
|
640
598
|
* var fadeAnimation = animation([
|
|
641
599
|
* style({ opacity: '{{ start }}' }),
|
|
642
600
|
* animate('{{ time }}',
|
|
643
|
-
*
|
|
644
|
-
*
|
|
601
|
+
* style({ opacity: '{{ end }}'}))
|
|
602
|
+
* ],
|
|
603
|
+
* { params: { time: '1000ms', start: 0, end: 1 }});
|
|
645
604
|
* ```
|
|
646
605
|
*
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
* directly. If any of the passed in parameter values are missing then the default values will be
|
|
650
|
-
* used.
|
|
606
|
+
* The following invokes the defined animation with a call to `useAnimation()`,
|
|
607
|
+
* passing in override parameter values.
|
|
651
608
|
*
|
|
652
|
-
* ```
|
|
609
|
+
* ```js
|
|
653
610
|
* useAnimation(fadeAnimation, {
|
|
654
611
|
* params: {
|
|
655
612
|
* time: '2s',
|
|
@@ -659,140 +616,75 @@ export function transition(stateChangeExpr, steps, options) {
|
|
|
659
616
|
* })
|
|
660
617
|
* ```
|
|
661
618
|
*
|
|
662
|
-
* If
|
|
663
|
-
*
|
|
664
|
-
*
|
|
619
|
+
* If any of the passed-in parameter values are missing from this call,
|
|
620
|
+
* the default values are used. If one or more parameter values are missing before a step is
|
|
621
|
+
* animated, `useAnimation()` throws an error.
|
|
665
622
|
*/
|
|
666
623
|
export function animation(steps, options) {
|
|
667
624
|
if (options === void 0) { options = null; }
|
|
668
625
|
return { type: 8 /* Reference */, animation: steps, options: options };
|
|
669
626
|
}
|
|
670
627
|
/**
|
|
671
|
-
*
|
|
672
|
-
* animation DSL language. It works by allowing a queried element to execute its own
|
|
673
|
-
* animation within the animation sequence.
|
|
674
|
-
*
|
|
675
|
-
* Each time an animation is triggered in angular, the parent animation
|
|
676
|
-
* will always get priority and any child animations will be blocked. In order
|
|
677
|
-
* for a child animation to run, the parent animation must query each of the elements
|
|
678
|
-
* containing child animations and then allow the animations to run using `animateChild`.
|
|
679
|
-
*
|
|
680
|
-
* The example HTML code below shows both parent and child elements that have animation
|
|
681
|
-
* triggers that will execute at the same time.
|
|
628
|
+
* Executes a queried inner animation element within an animation sequence.
|
|
682
629
|
*
|
|
683
|
-
*
|
|
684
|
-
*
|
|
685
|
-
*
|
|
686
|
-
* <hr>
|
|
687
|
-
*
|
|
688
|
-
* <div [@parentAnimation]="exp">
|
|
689
|
-
* <header>Hello</header>
|
|
690
|
-
* <div [@childAnimation]="exp">
|
|
691
|
-
* one
|
|
692
|
-
* </div>
|
|
693
|
-
* <div [@childAnimation]="exp">
|
|
694
|
-
* two
|
|
695
|
-
* </div>
|
|
696
|
-
* <div [@childAnimation]="exp">
|
|
697
|
-
* three
|
|
698
|
-
* </div>
|
|
699
|
-
* </div>
|
|
700
|
-
* ```
|
|
701
|
-
*
|
|
702
|
-
* Now when the `exp` value changes to true, only the `parentAnimation` animation will animate
|
|
703
|
-
* because it has priority. However, using `query` and `animateChild` each of the inner animations
|
|
704
|
-
* can also fire:
|
|
705
|
-
*
|
|
706
|
-
* ```ts
|
|
707
|
-
* // parent-child.component.ts
|
|
708
|
-
* import {trigger, transition, animate, style, query, animateChild} from '@angular/animations';
|
|
709
|
-
* @Component({
|
|
710
|
-
* selector: 'parent-child-component',
|
|
711
|
-
* animations: [
|
|
712
|
-
* trigger('parentAnimation', [
|
|
713
|
-
* transition('false => true', [
|
|
714
|
-
* query('header', [
|
|
715
|
-
* style({ opacity: 0 }),
|
|
716
|
-
* animate(500, style({ opacity: 1 }))
|
|
717
|
-
* ]),
|
|
718
|
-
* query('@childAnimation', [
|
|
719
|
-
* animateChild()
|
|
720
|
-
* ])
|
|
721
|
-
* ])
|
|
722
|
-
* ]),
|
|
723
|
-
* trigger('childAnimation', [
|
|
724
|
-
* transition('false => true', [
|
|
725
|
-
* style({ opacity: 0 }),
|
|
726
|
-
* animate(500, style({ opacity: 1 }))
|
|
727
|
-
* ])
|
|
728
|
-
* ])
|
|
729
|
-
* ]
|
|
730
|
-
* })
|
|
731
|
-
* class ParentChildCmp {
|
|
732
|
-
* exp: boolean = false;
|
|
733
|
-
* }
|
|
734
|
-
* ```
|
|
735
|
-
*
|
|
736
|
-
* In the animation code above, when the `parentAnimation` transition kicks off it first queries to
|
|
737
|
-
* find the header element and fades it in. It then finds each of the sub elements that contain the
|
|
738
|
-
* `@childAnimation` trigger and then allows for their animations to fire.
|
|
739
|
-
*
|
|
740
|
-
* This example can be further extended by using stagger:
|
|
741
|
-
*
|
|
742
|
-
* ```ts
|
|
743
|
-
* query('@childAnimation', stagger(100, [
|
|
744
|
-
* animateChild()
|
|
745
|
-
* ]))
|
|
746
|
-
* ```
|
|
747
|
-
*
|
|
748
|
-
* Now each of the sub animations start off with respect to the `100ms` staggering step.
|
|
749
|
-
*
|
|
750
|
-
* ## The first frame of child animations
|
|
751
|
-
* When sub animations are executed using `animateChild` the animation engine will always apply the
|
|
752
|
-
* first frame of every sub animation immediately at the start of the animation sequence. This way
|
|
753
|
-
* the parent animation does not need to set any initial styling data on the sub elements before the
|
|
754
|
-
* sub animations kick off.
|
|
630
|
+
* @param options An options object that can contain a delay value for the start of the
|
|
631
|
+
* animation, and additional override values for developer-defined parameters.
|
|
632
|
+
* @return An object that encapsulates the child animation data.
|
|
755
633
|
*
|
|
756
|
-
*
|
|
757
|
-
*
|
|
758
|
-
*
|
|
759
|
-
*
|
|
760
|
-
*
|
|
761
|
-
* Note that this feature designed to be used alongside {@link query query()} and it will only work
|
|
762
|
-
* with animations that are assigned using the Angular animation DSL (this means that CSS keyframes
|
|
763
|
-
* and transitions are not handled by this API).
|
|
634
|
+
* @usageNotes
|
|
635
|
+
* Each time an animation is triggered in Angular, the parent animation
|
|
636
|
+
* has priority and any child animations are blocked. In order
|
|
637
|
+
* for a child animation to run, the parent animation must query each of the elements
|
|
638
|
+
* containing child animations, and run them using this function.
|
|
764
639
|
*
|
|
765
|
-
*
|
|
640
|
+
* Note that this feature designed to be used with `query()` and it will only work
|
|
641
|
+
* with animations that are assigned using the Angular animation library. CSS keyframes
|
|
642
|
+
* and transitions are not handled by this API.
|
|
766
643
|
*/
|
|
767
644
|
export function animateChild(options) {
|
|
768
645
|
if (options === void 0) { options = null; }
|
|
769
646
|
return { type: 9 /* AnimateChild */, options: options };
|
|
770
647
|
}
|
|
771
648
|
/**
|
|
772
|
-
*
|
|
773
|
-
* animation DSL language. It is used to kick off a reusable animation that is created using {@link
|
|
774
|
-
* animation animation()}.
|
|
649
|
+
* Starts a reusable animation that is created using the `animation()` function.
|
|
775
650
|
*
|
|
776
|
-
* @
|
|
651
|
+
* @param animation The reusable animation to start.
|
|
652
|
+
* @param options An options object that can contain a delay value for the start of
|
|
653
|
+
* the animation, and additional override values for developer-defined parameters.
|
|
654
|
+
* @return An object that contains the animation parameters.
|
|
777
655
|
*/
|
|
778
656
|
export function useAnimation(animation, options) {
|
|
779
657
|
if (options === void 0) { options = null; }
|
|
780
658
|
return { type: 10 /* AnimateRef */, animation: animation, options: options };
|
|
781
659
|
}
|
|
782
660
|
/**
|
|
783
|
-
*
|
|
784
|
-
*
|
|
785
|
-
*
|
|
786
|
-
*
|
|
787
|
-
*
|
|
788
|
-
*
|
|
789
|
-
*
|
|
661
|
+
* Finds one or more inner elements within the current element that is
|
|
662
|
+
* being animated within a sequence. Use with `animateChild()`.
|
|
663
|
+
*
|
|
664
|
+
* @param selector The element to query, or a set of elements that contain Angular-specific
|
|
665
|
+
* characteristics, specified with one or more of the following tokens.
|
|
666
|
+
* - `query(":enter")` or `query(":leave")` : Query for newly inserted/removed elements.
|
|
667
|
+
* - `query(":animating")` : Query all currently animating elements.
|
|
668
|
+
* - `query("@triggerName")` : Query elements that contain an animation trigger.
|
|
669
|
+
* - `query("@*")` : Query all elements that contain an animation triggers.
|
|
670
|
+
* - `query(":self")` : Include the current element into the animation sequence.
|
|
671
|
+
*
|
|
672
|
+
* @param animation One or more animation steps to apply to the queried element or elements.
|
|
673
|
+
* An array is treated as an animation sequence.
|
|
674
|
+
* @param options An options object. Use the 'limit' field to limit the total number of
|
|
675
|
+
* items to collect.
|
|
676
|
+
* @return An object that encapsulates the query data.
|
|
677
|
+
*
|
|
678
|
+
* @usageNotes
|
|
679
|
+
* Tokens can be merged into a combined query selector string. For example:
|
|
790
680
|
*
|
|
791
|
-
*
|
|
681
|
+
* ```typescript
|
|
682
|
+
* query(':self, .record:enter, .record:leave, @subTrigger', [...])
|
|
683
|
+
* ```
|
|
792
684
|
*
|
|
793
|
-
* query()
|
|
794
|
-
* `element.querySelectorAll`.
|
|
795
|
-
*
|
|
685
|
+
* The `query()` function collects multiple elements and works internally by using
|
|
686
|
+
* `element.querySelectorAll`. Use the `limit` field of an options object to limit
|
|
687
|
+
* the total number of items to be collected. For example:
|
|
796
688
|
*
|
|
797
689
|
* ```js
|
|
798
690
|
* query('div', [
|
|
@@ -801,8 +693,8 @@ export function useAnimation(animation, options) {
|
|
|
801
693
|
* ], { limit: 1 })
|
|
802
694
|
* ```
|
|
803
695
|
*
|
|
804
|
-
*
|
|
805
|
-
*
|
|
696
|
+
* By default, throws an error when zero items are found. Set the
|
|
697
|
+
* `optional` flag to ignore this error. For example:
|
|
806
698
|
*
|
|
807
699
|
* ```js
|
|
808
700
|
* query('.some-element-that-may-not-be-there', [
|
|
@@ -811,31 +703,12 @@ export function useAnimation(animation, options) {
|
|
|
811
703
|
* ], { optional: true })
|
|
812
704
|
* ```
|
|
813
705
|
*
|
|
814
|
-
* ###
|
|
815
|
-
*
|
|
816
|
-
* The selector value within a query can collect elements that contain angular-specific
|
|
817
|
-
* characteristics
|
|
818
|
-
* using special pseudo-selectors tokens.
|
|
706
|
+
* ### Usage Example
|
|
819
707
|
*
|
|
820
|
-
*
|
|
708
|
+
* The following example queries for inner elements and animates them
|
|
709
|
+
* individually using `animateChild()`.
|
|
821
710
|
*
|
|
822
|
-
*
|
|
823
|
-
* - Querying all currently animating elements using `query(":animating")`
|
|
824
|
-
* - Querying elements that contain an animation trigger using `query("@triggerName")`
|
|
825
|
-
* - Querying all elements that contain an animation triggers using `query("@*")`
|
|
826
|
-
* - Including the current element into the animation sequence using `query(":self")`
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
* Each of these pseudo-selector tokens can be merged together into a combined query selector
|
|
830
|
-
* string:
|
|
831
|
-
*
|
|
832
|
-
* ```
|
|
833
|
-
* query(':self, .record:enter, .record:leave, @subTrigger', [...])
|
|
834
|
-
* ```
|
|
835
|
-
*
|
|
836
|
-
* ### Demo
|
|
837
|
-
*
|
|
838
|
-
* ```
|
|
711
|
+
* ```typescript
|
|
839
712
|
* @Component({
|
|
840
713
|
* selector: 'inner',
|
|
841
714
|
* template: `
|
|
@@ -868,24 +741,29 @@ export function useAnimation(animation, options) {
|
|
|
868
741
|
* }
|
|
869
742
|
* }
|
|
870
743
|
* ```
|
|
871
|
-
*
|
|
872
|
-
* @experimental Animation support is experimental.
|
|
873
744
|
*/
|
|
874
745
|
export function query(selector, animation, options) {
|
|
875
746
|
if (options === void 0) { options = null; }
|
|
876
747
|
return { type: 11 /* Query */, selector: selector, animation: animation, options: options };
|
|
877
748
|
}
|
|
878
749
|
/**
|
|
879
|
-
*
|
|
880
|
-
*
|
|
881
|
-
* and works by issuing a timing gap between after each queried item is animated.
|
|
750
|
+
* Use within an animation `query()` call to issue a timing gap after
|
|
751
|
+
* each queried item is animated.
|
|
882
752
|
*
|
|
883
|
-
*
|
|
753
|
+
* @param timings A delay value.
|
|
754
|
+
* @param animation One ore more animation steps.
|
|
755
|
+
* @returns An object that encapsulates the stagger data.
|
|
884
756
|
*
|
|
885
|
-
*
|
|
886
|
-
*
|
|
757
|
+
* @usageNotes
|
|
758
|
+
* In the following example, a container element wraps a list of items stamped out
|
|
759
|
+
* by an `ngFor`. The container element contains an animation trigger that will later be set
|
|
887
760
|
* to query for each of the inner items.
|
|
888
761
|
*
|
|
762
|
+
* Each time items are added, the opacity fade-in animation runs,
|
|
763
|
+
* and each removed item is faded out.
|
|
764
|
+
* When either of these animations occur, the stagger effect is
|
|
765
|
+
* applied after each item's animation is started.
|
|
766
|
+
*
|
|
889
767
|
* ```html
|
|
890
768
|
* <!-- list.component.html -->
|
|
891
769
|
* <button (click)="toggle()">Show / Hide Items</button>
|
|
@@ -897,15 +775,15 @@ export function query(selector, animation, options) {
|
|
|
897
775
|
* </div>
|
|
898
776
|
* ```
|
|
899
777
|
*
|
|
900
|
-
*
|
|
778
|
+
* Here is the component code:
|
|
901
779
|
*
|
|
902
|
-
* ```
|
|
780
|
+
* ```typescript
|
|
903
781
|
* import {trigger, transition, style, animate, query, stagger} from '@angular/animations';
|
|
904
782
|
* @Component({
|
|
905
783
|
* templateUrl: 'list.component.html',
|
|
906
784
|
* animations: [
|
|
907
785
|
* trigger('listAnimation', [
|
|
908
|
-
*
|
|
786
|
+
* ...
|
|
909
787
|
* ])
|
|
910
788
|
* ]
|
|
911
789
|
* })
|
|
@@ -922,13 +800,13 @@ export function query(selector, animation, options) {
|
|
|
922
800
|
*
|
|
923
801
|
* toggle() {
|
|
924
802
|
* this.items.length ? this.hideItems() : this.showItems();
|
|
925
|
-
*
|
|
926
|
-
*
|
|
803
|
+
* }
|
|
804
|
+
* }
|
|
927
805
|
* ```
|
|
928
806
|
*
|
|
929
|
-
*
|
|
807
|
+
* Here is the animation trigger code:
|
|
930
808
|
*
|
|
931
|
-
* ```
|
|
809
|
+
* ```typescript
|
|
932
810
|
* trigger('listAnimation', [
|
|
933
811
|
* transition('* => *', [ // each time the binding value changes
|
|
934
812
|
* query(':leave', [
|
|
@@ -945,16 +823,9 @@ export function query(selector, animation, options) {
|
|
|
945
823
|
* ])
|
|
946
824
|
* ])
|
|
947
825
|
* ```
|
|
948
|
-
*
|
|
949
|
-
* Now each time the items are added/removed then either the opacity
|
|
950
|
-
* fade-in animation will run or each removed item will be faded out.
|
|
951
|
-
* When either of these animations occur then a stagger effect will be
|
|
952
|
-
* applied after each item's animation is started.
|
|
953
|
-
*
|
|
954
|
-
* @experimental Animation support is experimental.
|
|
955
826
|
*/
|
|
956
827
|
export function stagger(timings, animation) {
|
|
957
828
|
return { type: 12 /* Stagger */, timings: timings, animation: animation };
|
|
958
829
|
}
|
|
959
830
|
|
|
960
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uX21ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5pbWF0aW9ucy9zcmMvYW5pbWF0aW9uX21ldGFkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQStFQSxNQUFNLENBQUMsSUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdVOUIsTUFBTSxrQkFBa0IsSUFBWSxFQUFFLFdBQWdDO0lBQ3BFLE1BQU0sQ0FBQyxFQUFDLElBQUksaUJBQStCLEVBQUUsSUFBSSxNQUFBLEVBQUUsV0FBVyxhQUFBLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBQyxDQUFDO0NBQzlFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBK0NELE1BQU0sa0JBQ0YsT0FBd0IsRUFBRSxNQUNYO0lBRFcsdUJBQUEsRUFBQSxhQUNYO0lBQ2pCLE1BQU0sQ0FBQyxFQUFDLElBQUksaUJBQStCLEVBQUUsTUFBTSxRQUFBLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztDQUMvRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFpQ0QsTUFBTSxnQkFDRixLQUEwQixFQUFFLE9BQXVDO0lBQXZDLHdCQUFBLEVBQUEsY0FBdUM7SUFDckUsTUFBTSxDQUFDLEVBQUMsSUFBSSxlQUE2QixFQUFFLEtBQUssT0FBQSxFQUFFLE9BQU8sU0FBQSxFQUFDLENBQUM7Q0FDNUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0NELE1BQU0sbUJBQW1CLEtBQTBCLEVBQUUsT0FBdUM7SUFBdkMsd0JBQUEsRUFBQSxjQUF1QztJQUUxRixNQUFNLENBQUMsRUFBQyxJQUFJLGtCQUFnQyxFQUFFLEtBQUssT0FBQSxFQUFFLE9BQU8sU0FBQSxFQUFDLENBQUM7Q0FDL0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE0Q0QsTUFBTSxnQkFDRixNQUMyQztJQUM3QyxNQUFNLENBQUMsRUFBQyxJQUFJLGVBQTZCLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUM7Q0FDMUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrREQsTUFBTSxnQkFDRixJQUFZLEVBQUUsTUFBOEIsRUFDNUMsT0FBeUM7SUFDM0MsTUFBTSxDQUFDLEVBQUMsSUFBSSxlQUE2QixFQUFFLElBQUksTUFBQSxFQUFFLE1BQU0sUUFBQSxFQUFFLE9BQU8sU0FBQSxFQUFDLENBQUM7Q0FDbkU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUErQ0QsTUFBTSxvQkFBb0IsS0FBK0I7SUFDdkQsTUFBTSxDQUFDLEVBQUMsSUFBSSxtQkFBaUMsRUFBRSxLQUFLLE9BQUEsRUFBQyxDQUFDO0NBQ3ZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXlNRCxNQUFNLHFCQUNGLGVBQ3NFLEVBQ3RFLEtBQThDLEVBQzlDLE9BQXVDO0lBQXZDLHdCQUFBLEVBQUEsY0FBdUM7SUFDekMsTUFBTSxDQUFDLEVBQUMsSUFBSSxvQkFBa0MsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztDQUNuRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUNELE1BQU0sb0JBQ0YsS0FBOEMsRUFDOUMsT0FBdUM7SUFBdkMsd0JBQUEsRUFBQSxjQUF1QztJQUN6QyxNQUFNLENBQUMsRUFBQyxJQUFJLG1CQUFpQyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztDQUMzRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtR0QsTUFBTSx1QkFBdUIsT0FBMEM7SUFBMUMsd0JBQUEsRUFBQSxjQUEwQztJQUVyRSxNQUFNLENBQUMsRUFBQyxJQUFJLHNCQUFvQyxFQUFFLE9BQU8sU0FBQSxFQUFDLENBQUM7Q0FDNUQ7Ozs7Ozs7O0FBU0QsTUFBTSx1QkFDRixTQUFxQyxFQUNyQyxPQUF1QztJQUF2Qyx3QkFBQSxFQUFBLGNBQXVDO0lBQ3pDLE1BQU0sQ0FBQyxFQUFDLElBQUkscUJBQWtDLEVBQUUsU0FBUyxXQUFBLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztDQUNyRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBOEZELE1BQU0sZ0JBQ0YsUUFBZ0IsRUFBRSxTQUFrRCxFQUNwRSxPQUE0QztJQUE1Qyx3QkFBQSxFQUFBLGNBQTRDO0lBQzlDLE1BQU0sQ0FBQyxFQUFDLElBQUksZ0JBQTZCLEVBQUUsUUFBUSxVQUFBLEVBQUUsU0FBUyxXQUFBLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztDQUMxRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdGRCxNQUFNLGtCQUNGLE9BQXdCLEVBQ3hCLFNBQWtEO0lBQ3BELE1BQU0sQ0FBQyxFQUFDLElBQUksa0JBQStCLEVBQUUsT0FBTyxTQUFBLEVBQUUsU0FBUyxXQUFBLEVBQUMsQ0FBQztDQUNsRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgybVTdHlsZURhdGEgeyBba2V5OiBzdHJpbmddOiBzdHJpbmd8bnVtYmVyOyB9XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIGNyZWF0ZWQgaW50ZXJuYWxseVxuICogd2l0aGluIHRoZSBBbmd1bGFyIGFuaW1hdGlvbiBEU0wuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBkZWNsYXJlIHR5cGUgQW5pbWF0ZVRpbWluZ3MgPSB7XG4gIGR1cmF0aW9uOiBudW1iZXIsXG4gIGRlbGF5OiBudW1iZXIsXG4gIGVhc2luZzogc3RyaW5nIHwgbnVsbFxufTtcblxuLyoqXG4gKiBgQW5pbWF0aW9uT3B0aW9uc2AgcmVwcmVzZW50cyBvcHRpb25zIHRoYXQgY2FuIGJlIHBhc3NlZCBpbnRvIG1vc3QgYW5pbWF0aW9uIERTTCBtZXRob2RzLlxuICogV2hlbiBvcHRpb25zIGFyZSBwcm92aWRlZCwgdGhlIGRlbGF5IHZhbHVlIG9mIGFuIGFuaW1hdGlvbiBjYW4gYmUgY2hhbmdlZCBhbmQgYW5pbWF0aW9uIGlucHV0XG4gKiBwYXJhbWV0ZXJzIGNhbiBiZSBwYXNzZWQgaW4gdG8gY2hhbmdlIHN0eWxpbmcgYW5kIHRpbWluZyBkYXRhIHdoZW4gYW4gYW5pbWF0aW9uIGlzIHN0YXJ0ZWQuXG4gKlxuICogVGhlIGZvbGxvd2luZyBhbmltYXRpb24gRFNMIGZ1bmN0aW9ucyBhcmUgYWJsZSB0byBhY2NlcHQgYW5pbWF0aW9uIG9wdGlvbiBkYXRhOlxuICpcbiAqIC0ge0BsaW5rIHRyYW5zaXRpb24gdHJhbnNpdGlvbigpfVxuICogLSB7QGxpbmsgc2VxdWVuY2Ugc2VxdWVuY2UoKX1cbiAqIC0ge0BsaW5rIGdyb3VwIGdyb3VwKCl9XG4gKiAtIHtAbGluayBxdWVyeSBxdWVyeSgpfVxuICogLSB7QGxpbmsgYW5pbWF0aW9uIGFuaW1hdGlvbigpfVxuICogLSB7QGxpbmsgdXNlQW5pbWF0aW9uIHVzZUFuaW1hdGlvbigpfVxuICogLSB7QGxpbmsgYW5pbWF0ZUNoaWxkIGFuaW1hdGVDaGlsZCgpfVxuICpcbiAqIFByb2dyYW1tYXRpYyBhbmltYXRpb25zIGJ1aWx0IHVzaW5nIHtAbGluayBBbmltYXRpb25CdWlsZGVyIHRoZSBBbmltYXRpb25CdWlsZGVyIHNlcnZpY2V9IGFsc29cbiAqIG1ha2UgdXNlIG9mIEFuaW1hdGlvbk9wdGlvbnMuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBBbmltYXRpb25PcHRpb25zIHtcbiAgZGVsYXk/OiBudW1iZXJ8c3RyaW5nO1xuICBwYXJhbXM/OiB7W25hbWU6IHN0cmluZ106IGFueX07XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIGNyZWF0ZWQgaW50ZXJuYWxseVxuICogd2l0aGluIHRoZSBBbmd1bGFyIGFuaW1hdGlvbiBEU0wgd2hlbiB7QGxpbmsgYW5pbWF0ZUNoaWxkIGFuaW1hdGVDaGlsZCgpfSBpcyB1c2VkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgQW5pbWF0ZUNoaWxkT3B0aW9ucyBleHRlbmRzIEFuaW1hdGlvbk9wdGlvbnMgeyBkdXJhdGlvbj86IG51bWJlcnxzdHJpbmc7IH1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIFVzYWdlcyBvZiB0aGlzIGVudW0gYXJlIGNyZWF0ZWRcbiAqIGVhY2ggdGltZSBhbiBhbmltYXRpb24gRFNMIGZ1bmN0aW9uIGlzIHVzZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIEFuaW1hdGlvbk1ldGFkYXRhVHlwZSB7XG4gIFN0YXRlID0gMCxcbiAgVHJhbnNpdGlvbiA9IDEsXG4gIFNlcXVlbmNlID0gMixcbiAgR3JvdXAgPSAzLFxuICBBbmltYXRlID0gNCxcbiAgS2V5ZnJhbWVzID0gNSxcbiAgU3R5bGUgPSA2LFxuICBUcmlnZ2VyID0gNyxcbiAgUmVmZXJlbmNlID0gOCxcbiAgQW5pbWF0ZUNoaWxkID0gOSxcbiAgQW5pbWF0ZVJlZiA9IDEwLFxuICBRdWVyeSA9IDExLFxuICBTdGFnZ2VyID0gMTJcbn1cblxuLyoqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGNvbnN0IEFVVE9fU1RZTEUgPSAnKic7XG5cbi8qKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uTWV0YWRhdGEgeyB0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGU7IH1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgcHJvdmlkZWQgdmlhIHRoZVxuICogYW5pbWF0aW9uIERTTCB3aGVuIHRoZSB7QGxpbmsgdHJpZ2dlciB0cmlnZ2VyIGFuaW1hdGlvbiBmdW5jdGlvbn0gaXMgY2FsbGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblRyaWdnZXJNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgbmFtZTogc3RyaW5nO1xuICBkZWZpbml0aW9uczogQW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgb3B0aW9uczoge3BhcmFtcz86IHtbbmFtZTogc3RyaW5nXTogYW55fX18bnVsbDtcbn1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgcHJvdmlkZWQgdmlhIHRoZVxuICogYW5pbWF0aW9uIERTTCB3aGVuIHRoZSB7QGxpbmsgc3RhdGUgc3RhdGUgYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uU3RhdGVNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgbmFtZTogc3RyaW5nO1xuICBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGE7XG4gIG9wdGlvbnM/OiB7cGFyYW1zOiB7W25hbWU6IHN0cmluZ106IGFueX19O1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayB0cmFuc2l0aW9uIHRyYW5zaXRpb24gYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uVHJhbnNpdGlvbk1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBleHByOiBzdHJpbmd8XG4gICAgICAoKGZyb21TdGF0ZTogc3RyaW5nLCB0b1N0YXRlOiBzdHJpbmcsIGVsZW1lbnQ/OiBhbnksXG4gICAgICAgIHBhcmFtcz86IHtba2V5OiBzdHJpbmddOiBhbnl9KSA9PiBib29sZWFuKTtcbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YXxBbmltYXRpb25NZXRhZGF0YVtdO1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGF8QW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblF1ZXJ5TWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIHNlbGVjdG9yOiBzdHJpbmc7XG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGF8QW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgb3B0aW9uczogQW5pbWF0aW9uUXVlcnlPcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogTWV0YWRhdGEgcmVwcmVzZW50aW5nIHRoZSBlbnRyeSBvZiBhbmltYXRpb25zLiBJbnN0YW5jZXMgb2YgdGhpcyBpbnRlcmZhY2UgYXJlIHByb3ZpZGVkIHZpYSB0aGVcbiAqIGFuaW1hdGlvbiBEU0wgd2hlbiB0aGUge0BsaW5rIGtleWZyYW1lcyBrZXlmcmFtZXMgYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgc3RlcHM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGFbXTtcbn1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgcHJvdmlkZWQgdmlhIHRoZVxuICogYW5pbWF0aW9uIERTTCB3aGVuIHRoZSB7QGxpbmsgc3R5bGUgc3R5bGUgYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uU3R5bGVNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgc3R5bGVzOiAnKid8e1trZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlcn18QXJyYXk8e1trZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlcn18JyonPjtcbiAgb2Zmc2V0OiBudW1iZXJ8bnVsbDtcbn1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgcHJvdmlkZWQgdmlhIHRoZVxuICogYW5pbWF0aW9uIERTTCB3aGVuIHRoZSB7QGxpbmsgYW5pbWF0ZSBhbmltYXRlIGFuaW1hdGlvbiBmdW5jdGlvbn0gaXMgY2FsbGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgdGltaW5nczogc3RyaW5nfG51bWJlcnxBbmltYXRlVGltaW5ncztcbiAgc3R5bGVzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhfEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGF8bnVsbDtcbn1cblxuLyoqXG4gKiBNZXRhZGF0YSByZXByZXNlbnRpbmcgdGhlIGVudHJ5IG9mIGFuaW1hdGlvbnMuIEluc3RhbmNlcyBvZiB0aGlzIGludGVyZmFjZSBhcmUgcHJvdmlkZWQgdmlhIHRoZVxuICogYW5pbWF0aW9uIERTTCB3aGVuIHRoZSB7QGxpbmsgYW5pbWF0ZUNoaWxkIGFuaW1hdGVDaGlsZCBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25BbmltYXRlQ2hpbGRNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayB1c2VBbmltYXRpb24gdXNlQW5pbWF0aW9uIGFuaW1hdGlvbiBmdW5jdGlvbn0gaXMgY2FsbGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVSZWZNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgYW5pbWF0aW9uOiBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YTtcbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBzZXF1ZW5jZSBzZXF1ZW5jZSBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25TZXF1ZW5jZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBzdGVwczogQW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBncm91cCBncm91cCBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25Hcm91cE1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICBzdGVwczogQW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBxdWVyeSBxdWVyeSBhbmltYXRpb24gZnVuY3Rpb259IGlzIGNhbGxlZC5cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGRlY2xhcmUgaW50ZXJmYWNlIEFuaW1hdGlvblF1ZXJ5T3B0aW9ucyBleHRlbmRzIEFuaW1hdGlvbk9wdGlvbnMge1xuICBvcHRpb25hbD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBVc2VkIHRvIGxpbWl0IHRoZSB0b3RhbCBhbW91bnQgb2YgcmVzdWx0cyBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcXVlcnkgbGlzdC5cbiAgICpcbiAgICogSWYgYSBuZWdhdGl2ZSB2YWx1ZSBpcyBwcm92aWRlZCB0aGVuIHRoZSBxdWVyaWVkIHJlc3VsdHMgd2lsbCBiZSBsaW1pdGVkIGZyb20gdGhlXG4gICAqIGVuZCBvZiB0aGUgcXVlcnkgbGlzdCB0b3dhcmRzIHRoZSBiZWdpbm5pbmcgKGUuZy4gaWYgYGxpbWl0OiAtM2AgaXMgdXNlZCB0aGVuIHRoZVxuICAgKiBmaW5hbCAzIChvciBsZXNzKSBxdWVyaWVkIHJlc3VsdHMgd2lsbCBiZSB1c2VkIGZvciB0aGUgYW5pbWF0aW9uKS5cbiAgICovXG4gIGxpbWl0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIE1ldGFkYXRhIHJlcHJlc2VudGluZyB0aGUgZW50cnkgb2YgYW5pbWF0aW9ucy4gSW5zdGFuY2VzIG9mIHRoaXMgaW50ZXJmYWNlIGFyZSBwcm92aWRlZCB2aWEgdGhlXG4gKiBhbmltYXRpb24gRFNMIHdoZW4gdGhlIHtAbGluayBzdGFnZ2VyIHN0YWdnZXIgYW5pbWF0aW9uIGZ1bmN0aW9ufSBpcyBjYWxsZWQuXG4gKlxuKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblN0YWdnZXJNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgdGltaW5nczogc3RyaW5nfG51bWJlcjtcbiAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YXxBbmltYXRpb25NZXRhZGF0YVtdO1xufVxuXG4vKipcbiAqIGB0cmlnZ2VyYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIElmIHRoaXMgaW5mb3JtYXRpb24gaXMgbmV3LCBwbGVhc2UgbmF2aWdhdGUgdG8gdGhlXG4gKiB7QGxpbmsgQ29tcG9uZW50I2FuaW1hdGlvbnMgY29tcG9uZW50IGFuaW1hdGlvbnMgbWV0YWRhdGEgcGFnZX0gdG8gZ2FpbiBhIGJldHRlclxuICogdW5kZXJzdGFuZGluZyBvZiBob3cgYW5pbWF0aW9ucyBpbiBBbmd1bGFyIGFyZSB1c2VkLlxuICpcbiAqIGB0cmlnZ2VyYCBDcmVhdGVzIGFuIGFuaW1hdGlvbiB0cmlnZ2VyIHdoaWNoIHdpbGwgYSBsaXN0IG9mIHtAbGluayBzdGF0ZSBzdGF0ZX0gYW5kXG4gKiB7QGxpbmsgdHJhbnNpdGlvbiB0cmFuc2l0aW9ufSBlbnRyaWVzIHRoYXQgd2lsbCBiZSBldmFsdWF0ZWQgd2hlbiB0aGUgZXhwcmVzc2lvblxuICogYm91bmQgdG8gdGhlIHRyaWdnZXIgY2hhbmdlcy5cbiAqXG4gKiBUcmlnZ2VycyBhcmUgcmVnaXN0ZXJlZCB3aXRoaW4gdGhlIGNvbXBvbmVudCBhbm5vdGF0aW9uIGRhdGEgdW5kZXIgdGhlXG4gKiB7QGxpbmsgQ29tcG9uZW50I2FuaW1hdGlvbnMgYW5pbWF0aW9ucyBzZWN0aW9ufS4gQW4gYW5pbWF0aW9uIHRyaWdnZXIgY2FuIGJlIHBsYWNlZCBvbiBhbiBlbGVtZW50XG4gKiB3aXRoaW4gYSB0ZW1wbGF0ZSBieSByZWZlcmVuY2luZyB0aGUgbmFtZSBvZiB0aGUgdHJpZ2dlciBmb2xsb3dlZCBieSB0aGUgZXhwcmVzc2lvbiB2YWx1ZSB0aGF0XG4gdGhlXG4gKiB0cmlnZ2VyIGlzIGJvdW5kIHRvIChpbiB0aGUgZm9ybSBvZiBgW0B0cmlnZ2VyTmFtZV09XCJleHByZXNzaW9uXCJgLlxuICpcbiAqIEFuaW1hdGlvbiB0cmlnZ2VyIGJpbmRpbmdzIHN0cmlnaWZ5IHZhbHVlcyBhbmQgdGhlbiBtYXRjaCB0aGUgcHJldmlvdXMgYW5kIGN1cnJlbnQgdmFsdWVzIGFnYWluc3RcbiAqIGFueSBsaW5rZWQgdHJhbnNpdGlvbnMuIElmIGEgYm9vbGVhbiB2YWx1ZSBpcyBwcm92aWRlZCBpbnRvIHRoZSB0cmlnZ2VyIGJpbmRpbmcgdGhlbiBpdCB3aWxsIGJvdGhcbiAqIGJlIHJlcHJlc2VudGVkIGFzIGAxYCBvciBgdHJ1ZWAgYW5kIGAwYCBvciBgZmFsc2VgIGZvciBhIHRydWUgYW5kIGZhbHNlIGJvb2xlYW4gdmFsdWVzXG4gKiByZXNwZWN0aXZlbHkuXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogYHRyaWdnZXJgIHdpbGwgY3JlYXRlIGFuIGFuaW1hdGlvbiB0cmlnZ2VyIHJlZmVyZW5jZSBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYG5hbWVgIHZhbHVlLiBUaGVcbiAqIHByb3ZpZGVkIGBhbmltYXRpb25gIHZhbHVlIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGFycmF5IGNvbnNpc3Rpbmcgb2Yge0BsaW5rIHN0YXRlIHN0YXRlfSBhbmRcbiAqIHtAbGluayB0cmFuc2l0aW9uIHRyYW5zaXRpb259IGRlY2xhcmF0aW9ucy5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdteS1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZVVybDogJ215LWNvbXBvbmVudC10cGwuaHRtbCcsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKFwibXlBbmltYXRpb25UcmlnZ2VyXCIsIFtcbiAqICAgICAgIHN0YXRlKC4uLiksXG4gKiAgICAgICBzdGF0ZSguLi4pLFxuICogICAgICAgdHJhbnNpdGlvbiguLi4pLFxuICogICAgICAgdHJhbnNpdGlvbiguLi4pXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgbXlTdGF0dXNFeHAgPSBcInNvbWV0aGluZ1wiO1xuICogfVxuICogYGBgXG4gKlxuICogVGhlIHRlbXBsYXRlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbXBvbmVudCB3aWxsIG1ha2UgdXNlIG9mIHRoZSBgbXlBbmltYXRpb25UcmlnZ2VyYCBhbmltYXRpb25cbiB0cmlnZ2VyIGJ5IGJpbmRpbmcgdG8gYW4gZWxlbWVudCB3aXRoaW4gaXRzIHRlbXBsYXRlIGNvZGUuXG4gKlxuICogYGBgaHRtbFxuICogPCEtLSBzb21ld2hlcmUgaW5zaWRlIG9mIG15LWNvbXBvbmVudC10cGwuaHRtbCAtLT5cbiAqIDxkaXYgW0BteUFuaW1hdGlvblRyaWdnZXJdPVwibXlTdGF0dXNFeHBcIj4uLi48L2Rpdj5cbiAqIGBgYFxuICpcbiAqICMjIyBVc2luZyBhbiBpbmxpbmUgZnVuY3Rpb25cbiAqIFRoZSBgdHJhbnNpdGlvbmAgYW5pbWF0aW9uIG1ldGhvZCBhbHNvIHN1cHBvcnRzIHJlYWRpbmcgYW4gaW5saW5lIGZ1bmN0aW9uIHdoaWNoIGNhbiBkZWNpZGVcbiAqIGlmIGl0cyBhc3NvY2lhdGVkIGFuaW1hdGlvbiBzaG91bGQgYmUgcnVuLlxuICpcbiAqIGBgYFxuICogLy8gdGhpcyBtZXRob2Qgd2lsbCBiZSBydW4gZWFjaCB0aW1lIHRoZSBgbXlBbmltYXRpb25UcmlnZ2VyYFxuICogLy8gdHJpZ2dlciB2YWx1ZSBjaGFuZ2VzLi4uXG4gKiBmdW5jdGlvbiBteUlubGluZU1hdGNoZXJGbihmcm9tU3RhdGU6IHN0cmluZywgdG9TdGF0ZTogc3RyaW5nLCBlbGVtZW50OiBhbnksIHBhcmFtczoge1trZXk6XG4gc3RyaW5nXTogYW55fSk6IGJvb2xlYW4ge1xuICogICAvLyBub3RpY2UgdGhhdCBgZWxlbWVudGAgYW5kIGBwYXJhbXNgIGFyZSBhbHNvIGF2YWlsYWJsZSBoZXJlXG4gKiAgIHJldHVybiB0b1N0YXRlID09ICd5ZXMtcGxlYXNlLWFuaW1hdGUnO1xuICogfVxuICpcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ215LWNvbXBvbmVudCcsXG4gKiAgIHRlbXBsYXRlVXJsOiAnbXktY29tcG9uZW50LXRwbC5odG1sJyxcbiAqICAgYW5pbWF0aW9uczogW1xuICogICAgIHRyaWdnZXIoJ215QW5pbWF0aW9uVHJpZ2dlcicsIFtcbiAqICAgICAgIHRyYW5zaXRpb24obXlJbmxpbmVNYXRjaGVyRm4sIFtcbiAqICAgICAgICAgLy8gdGhlIGFuaW1hdGlvbiBzZXF1ZW5jZSBjb2RlXG4gKiAgICAgICBdKSxcbiAqICAgICBdKVxuICogICBdXG4gKiB9KVxuICogY2xhc3MgTXlDb21wb25lbnQge1xuICogICBteVN0YXR1c0V4cCA9IFwieWVzLXBsZWFzZS1hbmltYXRlXCI7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgaW5saW5lIG1ldGhvZCB3aWxsIGJlIHJ1biBlYWNoIHRpbWUgdGhlIHRyaWdnZXJcbiAqIHZhbHVlIGNoYW5nZXNcbiAqXG4gKiAjIyBEaXNhYmxlIEFuaW1hdGlvbnNcbiAqIEEgc3BlY2lhbCBhbmltYXRpb24gY29udHJvbCBiaW5kaW5nIGNhbGxlZCBgQC5kaXNhYmxlZGAgY2FuIGJlIHBsYWNlZCBvbiBhbiBlbGVtZW50IHdoaWNoIHdpbGxcbiB0aGVuIGRpc2FibGUgYW5pbWF0aW9ucyBmb3IgYW55IGlubmVyIGFuaW1hdGlvbiB0cmlnZ2VycyBzaXR1YXRlZCB3aXRoaW4gdGhlIGVsZW1lbnQgYXMgd2VsbCBhc1xuIGFueSBhbmltYXRpb25zIG9uIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqXG4gKiBXaGVuIHRydWUsIHRoZSBgQC5kaXNhYmxlZGAgYmluZGluZyB3aWxsIHByZXZlbnQgYWxsIGFuaW1hdGlvbnMgZnJvbSByZW5kZXJpbmcuIFRoZSBleGFtcGxlXG4gYmVsb3cgc2hvd3MgaG93IHRvIHVzZSB0aGlzIGZlYXR1cmU6XG4gKlxuICogYGBgdHNcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ215LWNvbXBvbmVudCcsXG4gKiAgIHRlbXBsYXRlOiBgXG4gKiAgICAgPGRpdiBbQC5kaXNhYmxlZF09XCJpc0Rpc2FibGVkXCI+XG4gKiAgICAgICA8ZGl2IFtAY2hpbGRBbmltYXRpb25dPVwiZXhwXCI+PC9kaXY+XG4gKiAgICAgPC9kaXY+XG4gKiAgIGAsXG4gKiAgIGFuaW1hdGlvbnM6IFtcbiAqICAgICB0cmlnZ2VyKFwiY2hpbGRBbmltYXRpb25cIiwgW1xuICogICAgICAgLy8gLi4uXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgaXNEaXNhYmxlZCA9IHRydWU7XG4gKiAgIGV4cCA9ICcuLi4nO1xuICogfVxuICogYGBgXG4gKlxuICogVGhlIGBAY2hpbGRBbmltYXRpb25gIHRyaWdnZXIgd2lsbCBub3QgYW5pbWF0ZSBiZWNhdXNlIGBALmRpc2FibGVkYCBwcmV2ZW50cyBpdCBmcm9tIGhhcHBlbmluZ1xuICh3aGVuIHRydWUpLlxuICpcbiAqIE5vdGUgdGhhdCBgQC5kaXNhYmxlZGAgd2lsbCBvbmx5IGRpc2FibGUgYWxsIGFuaW1hdGlvbnMgKHRoaXMgbWVhbnMgYW55IGFuaW1hdGlvbnMgcnVubmluZyBvblxuICogdGhlIHNhbWUgZWxlbWVudCB3aWxsIGFsc28gYmUgZGlzYWJsZWQpLlxuICpcbiAqICMjIyBEaXNhYmxpbmcgQW5pbWF0aW9ucyBBcHBsaWNhdGlvbi13aWRlXG4gKiBXaGVuIGFuIGFyZWEgb2YgdGhlIHRlbXBsYXRlIGlzIHNldCB0byBoYXZlIGFuaW1hdGlvbnMgZGlzYWJsZWQsICoqYWxsKiogaW5uZXIgY29tcG9uZW50cyB3aWxsXG4gYWxzbyBoYXZlIHRoZWlyIGFuaW1hdGlvbnMgZGlzYWJsZWQgYXMgd2VsbC4gVGhpcyBtZWFucyB0aGF0IGFsbCBhbmltYXRpb25zIGZvciBhbiBhbmd1bGFyXG4gYXBwbGljYXRpb24gY2FuIGJlIGRpc2FibGVkIGJ5IHBsYWNpbmcgYSBob3N0IGJpbmRpbmcgc2V0IG9uIGBALmRpc2FibGVkYCBvbiB0aGUgdG9wbW9zdCBBbmd1bGFyXG4gY29tcG9uZW50LlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQge0NvbXBvbmVudCwgSG9zdEJpbmRpbmd9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuICpcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2FwcC1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZVVybDogJ2FwcC5jb21wb25lbnQuaHRtbCcsXG4gKiB9KVxuICogY2xhc3MgQXBwQ29tcG9uZW50IHtcbiAqICAgQEhvc3RCaW5kaW5nKCdALmRpc2FibGVkJylcbiAqICAgcHVibGljIGFuaW1hdGlvbnNEaXNhYmxlZCA9IHRydWU7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMgV2hhdCBhYm91dCBhbmltYXRpb25zIHRoYXQgdXMgYHF1ZXJ5KClgIGFuZCBgYW5pbWF0ZUNoaWxkKClgP1xuICogRGVzcGl0ZSBpbm5lciBhbmltYXRpb25zIGJlaW5nIGRpc2FibGVkLCBhIHBhcmVudCBhbmltYXRpb24gY2FuIHtAbGluayBxdWVyeSBxdWVyeX0gZm9yIGlubmVyXG4gZWxlbWVudHMgbG9jYXRlZCBpbiBkaXNhYmxlZCBhcmVhcyBvZiB0aGUgdGVtcGxhdGUgYW5kIHN0aWxsIGFuaW1hdGUgdGhlbSBhcyBpdCBzZWVzIGZpdC4gVGhpcyBpc1xuIGFsc28gdGhlIGNhc2UgZm9yIHdoZW4gYSBzdWIgYW5pbWF0aW9uIGlzIHF1ZXJpZWQgYnkgYSBwYXJlbnQgYW5kIHRoZW4gbGF0ZXIgYW5pbWF0ZWQgdXNpbmcge0BsaW5rXG4gYW5pbWF0ZUNoaWxkIGFuaW1hdGVDaGlsZH0uXG5cbiAqICMjIyBEZXRlY3Rpbmcgd2hlbiBhbiBhbmltYXRpb24gaXMgZGlzYWJsZWRcbiAqIElmIGEgcmVnaW9uIG9mIHRoZSBET00gKG9yIHRoZSBlbnRpcmUgYXBwbGljYXRpb24pIGhhcyBpdHMgYW5pbWF0aW9ucyBkaXNhYmxlZCwgdGhlbiBhbmltYXRpb25cbiAqIHRyaWdnZXIgY2FsbGJhY2tzIHdpbGwgc3RpbGwgZmlyZSBqdXN0IGFzIG5vcm1hbCAob25seSBmb3IgemVybyBzZWNvbmRzKS5cbiAqXG4gKiBXaGVuIGEgdHJpZ2dlciBjYWxsYmFjayBmaXJlcyBpdCB3aWxsIHByb3ZpZGUgYW4gaW5zdGFuY2Ugb2YgYW4ge0BsaW5rIEFuaW1hdGlvbkV2ZW50fS4gSWZcbiBhbmltYXRpb25zXG4gKiBhcmUgZGlzYWJsZWQgdGhlbiB0aGUgYC5kaXNhYmxlZGAgZmxhZyBvbiB0aGUgZXZlbnQgd2lsbCBiZSB0cnVlLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJpZ2dlcihuYW1lOiBzdHJpbmcsIGRlZmluaXRpb25zOiBBbmltYXRpb25NZXRhZGF0YVtdKTogQW5pbWF0aW9uVHJpZ2dlck1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuVHJpZ2dlciwgbmFtZSwgZGVmaW5pdGlvbnMsIG9wdGlvbnM6IHt9fTtcbn1cblxuLyoqXG4gKiBgYW5pbWF0ZWAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJZiB0aGlzIGluZm9ybWF0aW9uIGlzIG5ldywgcGxlYXNlIG5hdmlnYXRlIHRvIHRoZSB7QGxpbmtcbiAqIENvbXBvbmVudCNhbmltYXRpb25zIGNvbXBvbmVudCBhbmltYXRpb25zIG1ldGFkYXRhIHBhZ2V9IHRvIGdhaW4gYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZlxuICogaG93IGFuaW1hdGlvbnMgaW4gQW5ndWxhciBhcmUgdXNlZC5cbiAqXG4gKiBgYW5pbWF0ZWAgc3BlY2lmaWVzIGFuIGFuaW1hdGlvbiBzdGVwIHRoYXQgd2lsbCBhcHBseSB0aGUgcHJvdmlkZWQgYHN0eWxlc2AgZGF0YSBmb3IgYSBnaXZlblxuICogYW1vdW50IG9mIHRpbWUgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGB0aW1pbmdgIGV4cHJlc3Npb24gdmFsdWUuIENhbGxzIHRvIGBhbmltYXRlYCBhcmUgZXhwZWN0ZWRcbiAqIHRvIGJlIHVzZWQgd2l0aGluIHtAbGluayBzZXF1ZW5jZSBhbiBhbmltYXRpb24gc2VxdWVuY2V9LCB7QGxpbmsgZ3JvdXAgZ3JvdXB9LCBvciB7QGxpbmtcbiAqIHRyYW5zaXRpb24gdHJhbnNpdGlvbn0uXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogVGhlIGBhbmltYXRlYCBmdW5jdGlvbiBhY2NlcHRzIHR3byBpbnB1dCBwYXJhbWV0ZXJzOiBgdGltaW5nYCBhbmQgYHN0eWxlc2A6XG4gKlxuICogLSBgdGltaW5nYCBpcyBhIHN0cmluZyBiYXNlZCB2YWx1ZSB0aGF0IGNhbiBiZSBhIGNvbWJpbmF0aW9uIG9mIGEgZHVyYXRpb24gd2l0aCBvcHRpb25hbCBkZWxheVxuICogYW5kIGVhc2luZyB2YWx1ZXMuIFRoZSBmb3JtYXQgZm9yIHRoZSBleHByZXNzaW9uIGJyZWFrcyBkb3duIHRvIGBkdXJhdGlvbiBkZWxheSBlYXNpbmdgXG4gKiAodGhlcmVmb3JlIGEgdmFsdWUgc3VjaCBhcyBgMXMgMTAwbXMgZWFzZS1vdXRgIHdpbGwgYmUgcGFyc2UgaXRzZWxmIGludG8gYGR1cmF0aW9uPTEwMDAsXG4gKiBkZWxheT0xMDAsIGVhc2luZz1lYXNlLW91dGAuIElmIGEgbnVtZXJpYyB2YWx1ZSBpcyBwcm92aWRlZCB0aGVuIHRoYXQgd2lsbCBiZSB1c2VkIGFzIHRoZVxuICogYGR1cmF0aW9uYCB2YWx1ZSBpbiBtaWxsaXNlY29uZCBmb3JtLlxuICogLSBgc3R5bGVzYCBpcyB0aGUgc3R5bGUgaW5wdXQgZGF0YSB3aGljaCBjYW4gZWl0aGVyIGJlIGEgY2FsbCB0byB7QGxpbmsgc3R5bGUgc3R5bGV9IG9yIHtAbGlua1xuICoga2V5ZnJhbWVzIGtleWZyYW1lc30uIElmIGxlZnQgZW1wdHkgdGhlbiB0aGUgc3R5bGVzIGZyb20gdGhlIGRlc3RpbmF0aW9uIHN0YXRlIHdpbGwgYmUgY29sbGVjdGVkXG4gKiBhbmQgdXNlZCAodGhpcyBpcyB1c2VmdWwgd2hlbiBkZXNjcmliaW5nIGFuIGFuaW1hdGlvbiBzdGVwIHRoYXQgd2lsbCBjb21wbGV0ZSBhbiBhbmltYXRpb24gYnlcbiAqIHtAbGluayB0cmFuc2l0aW9uI3RoZS1maW5hbC1hbmltYXRlLWNhbGwgYW5pbWF0aW5nIHRvIHRoZSBmaW5hbCBzdGF0ZX0pLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHZhcmlvdXMgZnVuY3Rpb25zIGZvciBzcGVjaWZ5aW5nIHRpbWluZyBkYXRhXG4gKiBhbmltYXRlKDUwMCwgc3R5bGUoLi4uKSlcbiAqIGFuaW1hdGUoXCIxc1wiLCBzdHlsZSguLi4pKVxuICogYW5pbWF0ZShcIjEwMG1zIDAuNXNcIiwgc3R5bGUoLi4uKSlcbiAqIGFuaW1hdGUoXCI1cyBlYXNlXCIsIHN0eWxlKC4uLikpXG4gKiBhbmltYXRlKFwiNXMgMTBtcyBjdWJpYy1iZXppZXIoLjE3LC42NywuODgsLjEpXCIsIHN0eWxlKC4uLikpXG4gKlxuICogLy8gZWl0aGVyIHN0eWxlKCkgb2Yga2V5ZnJhbWVzKCkgY2FuIGJlIHVzZWRcbiAqIGFuaW1hdGUoNTAwLCBzdHlsZSh7IGJhY2tncm91bmQ6IFwicmVkXCIgfSkpXG4gKiBhbmltYXRlKDUwMCwga2V5ZnJhbWVzKFtcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcImJsdWVcIiB9KSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZDogXCJyZWRcIiB9KSlcbiAqIF0pXG4gKiBgYGBcbiAqXG4gKiB7QGV4YW1wbGUgY29yZS9hbmltYXRpb24vdHMvZHNsL2FuaW1hdGlvbl9leGFtcGxlLnRzIHJlZ2lvbj0nQ29tcG9uZW50J31cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuaW1hdGUoXG4gICAgdGltaW5nczogc3RyaW5nIHwgbnVtYmVyLCBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGEgfCBBbmltYXRpb25LZXlmcmFtZXNTZXF1ZW5jZU1ldGFkYXRhIHxcbiAgICAgICAgbnVsbCA9IG51bGwpOiBBbmltYXRpb25BbmltYXRlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5BbmltYXRlLCBzdHlsZXMsIHRpbWluZ3N9O1xufVxuXG4vKipcbiAqIGBncm91cGAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJZiB0aGlzIGluZm9ybWF0aW9uIGlzIG5ldywgcGxlYXNlIG5hdmlnYXRlIHRvIHRoZSB7QGxpbmtcbiAqIENvbXBvbmVudCNhbmltYXRpb25zIGNvbXBvbmVudCBhbmltYXRpb25zIG1ldGFkYXRhIHBhZ2V9IHRvIGdhaW4gYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZlxuICogaG93IGFuaW1hdGlvbnMgaW4gQW5ndWxhciBhcmUgdXNlZC5cbiAqXG4gKiBgZ3JvdXBgIHNwZWNpZmllcyBhIGxpc3Qgb2YgYW5pbWF0aW9uIHN0ZXBzIHRoYXQgYXJlIGFsbCBydW4gaW4gcGFyYWxsZWwuIEdyb3VwZWQgYW5pbWF0aW9ucyBhcmVcbiAqIHVzZWZ1bCB3aGVuIGEgc2VyaWVzIG9mIHN0eWxlcyBtdXN0IGJlIGFuaW1hdGVkL2Nsb3NlZCBvZmYgYXQgZGlmZmVyZW50IHN0YXJ0aW5nL2VuZGluZyB0aW1lcy5cbiAqXG4gKiBUaGUgYGdyb3VwYCBmdW5jdGlvbiBjYW4gZWl0aGVyIGJlIHVzZWQgd2l0aGluIGEge0BsaW5rIHNlcXVlbmNlIHNlcXVlbmNlfSBvciBhIHtAbGluayB0cmFuc2l0aW9uXG4gKiB0cmFuc2l0aW9ufSBhbmQgaXQgd2lsbCBvbmx5IGNvbnRpbnVlIHRvIHRoZSBuZXh0IGluc3RydWN0aW9uIG9uY2UgYWxsIG9mIHRoZSBpbm5lciBhbmltYXRpb25cbiAqIHN0ZXBzIGhhdmUgY29tcGxldGVkLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIFRoZSBgc3RlcHNgIGRhdGEgdGhhdCBpcyBwYXNzZWQgaW50byB0aGUgYGdyb3VwYCBhbmltYXRpb24gZnVuY3Rpb24gY2FuIGVpdGhlciBjb25zaXN0IG9mIHtAbGlua1xuICogc3R5bGUgc3R5bGV9IG9yIHtAbGluayBhbmltYXRlIGFuaW1hdGV9IGZ1bmN0aW9uIGNhbGxzLiBFYWNoIGNhbGwgdG8gYHN0eWxlKClgIG9yIGBhbmltYXRlKClgXG4gKiB3aXRoaW4gYSBncm91cCB3aWxsIGJlIGV4ZWN1dGVkIGluc3RhbnRseSAodXNlIHtAbGluayBrZXlmcmFtZXMga2V5ZnJhbWVzfSBvciBhIHtAbGlua1xuICogYW5pbWF0ZSN1c2FnZSBhbmltYXRlKCkgd2l0aCBhIGRlbGF5IHZhbHVlfSB0byBvZmZzZXQgc3R5bGVzIHRvIGJlIGFwcGxpZWQgYXQgYSBsYXRlciB0aW1lKS5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBncm91cChbXG4gKiAgIGFuaW1hdGUoXCIxc1wiLCB7IGJhY2tncm91bmQ6IFwiYmxhY2tcIiB9KSlcbiAqICAgYW5pbWF0ZShcIjJzXCIsIHsgY29sb3I6IFwid2hpdGVcIiB9KSlcbiAqIF0pXG4gKiBgYGBcbiAqXG4gKiB7QGV4YW1wbGUgY29yZS9hbmltYXRpb24vdHMvZHNsL2FuaW1hdGlvbl9leGFtcGxlLnRzIHJlZ2lvbj0nQ29tcG9uZW50J31cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwKFxuICAgIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdLCBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25Hcm91cE1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuR3JvdXAsIHN0ZXBzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBgc2VxdWVuY2VgIGlzIGFuIGFuaW1hdGlvbi1zcGVjaWZpYyBmdW5jdGlvbiB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIEFuZ3VsYXInc1xuICogYW5pbWF0aW9uIERTTCBsYW5ndWFnZS4gSWYgdGhpcyBpbmZvcm1hdGlvbiBpcyBuZXcsIHBsZWFzZSBuYXZpZ2F0ZSB0byB0aGUge0BsaW5rXG4gKiBDb21wb25lbnQjYW5pbWF0aW9ucyBjb21wb25lbnQgYW5pbWF0aW9ucyBtZXRhZGF0YSBwYWdlfSB0byBnYWluIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2ZcbiAqIGhvdyBhbmltYXRpb25zIGluIEFuZ3VsYXIgYXJlIHVzZWQuXG4gKlxuICogYHNlcXVlbmNlYCBTcGVjaWZpZXMgYSBsaXN0IG9mIGFuaW1hdGlvbiBzdGVwcyB0aGF0IGFyZSBydW4gb25lIGJ5IG9uZS4gKGBzZXF1ZW5jZWAgaXMgdXNlZCBieVxuICogZGVmYXVsdCB3aGVuIGFuIGFycmF5IGlzIHBhc3NlZCBhcyBhbmltYXRpb24gZGF0YSBpbnRvIHtAbGluayB0cmFuc2l0aW9uIHRyYW5zaXRpb259LilcbiAqXG4gKiBUaGUgYHNlcXVlbmNlYCBmdW5jdGlvbiBjYW4gZWl0aGVyIGJlIHVzZWQgd2l0aGluIGEge0BsaW5rIGdyb3VwIGdyb3VwfSBvciBhIHtAbGluayB0cmFuc2l0aW9uXG4gKiB0cmFuc2l0aW9ufSBhbmQgaXQgd2lsbCBvbmx5IGNvbnRpbnVlIHRvIHRoZSBuZXh0IGluc3RydWN0aW9uIG9uY2UgZWFjaCBvZiB0aGUgaW5uZXIgYW5pbWF0aW9uXG4gKiBzdGVwcyBoYXZlIGNvbXBsZXRlZC5cbiAqXG4gKiBUbyBwZXJmb3JtIGFuaW1hdGlvbiBzdHlsaW5nIGluIHBhcmFsbGVsIHdpdGggb3RoZXIgYW5pbWF0aW9uIHN0ZXBzIHRoZW4gaGF2ZSBhIGxvb2sgYXQgdGhlXG4gKiB7QGxpbmsgZ3JvdXAgZ3JvdXB9IGFuaW1hdGlvbiBmdW5jdGlvbi5cbiAqXG4gKiAjIyMgVXNhZ2VcbiAqXG4gKiBUaGUgYHN0ZXBzYCBkYXRhIHRoYXQgaXMgcGFzc2VkIGludG8gdGhlIGBzZXF1ZW5jZWAgYW5pbWF0aW9uIGZ1bmN0aW9uIGNhbiBlaXRoZXIgY29uc2lzdCBvZlxuICoge0BsaW5rIHN0eWxlIHN0eWxlfSBvciB7QGxpbmsgYW5pbWF0ZSBhbmltYXRlfSBmdW5jdGlvbiBjYWxscy4gQSBjYWxsIHRvIGBzdHlsZSgpYCB3aWxsIGFwcGx5IHRoZVxuICogcHJvdmlkZWQgc3R5bGluZyBkYXRhIGltbWVkaWF0ZWx5IHdoaWxlIGEgY2FsbCB0byBgYW5pbWF0ZSgpYCB3aWxsIGFwcGx5IGl0cyBzdHlsaW5nIGRhdGEgb3ZlciBhXG4gKiBnaXZlbiB0aW1lIGRlcGVuZGluZyBvbiBpdHMgdGltaW5nIGRhdGEuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogc2VxdWVuY2UoW1xuICogICBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpLFxuICogICBhbmltYXRlKFwiMXNcIiwgeyBvcGFjaXR5OiAxIH0pKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIHtAZXhhbXBsZSBjb3JlL2FuaW1hdGlvbi90cy9kc2wvYW5pbWF0aW9uX2V4YW1wbGUudHMgcmVnaW9uPSdDb21wb25lbnQnfVxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VxdWVuY2Uoc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhW10sIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnMgfCBudWxsID0gbnVsbCk6XG4gICAgQW5pbWF0aW9uU2VxdWVuY2VNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlNlcXVlbmNlLCBzdGVwcywgb3B0aW9uc307XG59XG5cbi8qKlxuICogYHN0eWxlYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIElmIHRoaXMgaW5mb3JtYXRpb24gaXMgbmV3LCBwbGVhc2UgbmF2aWdhdGUgdG8gdGhlIHtAbGlua1xuICogQ29tcG9uZW50I2FuaW1hdGlvbnMgY29tcG9uZW50IGFuaW1hdGlvbnMgbWV0YWRhdGEgcGFnZX0gdG8gZ2FpbiBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mXG4gKiBob3cgYW5pbWF0aW9ucyBpbiBBbmd1bGFyIGFyZSB1c2VkLlxuICpcbiAqIGBzdHlsZWAgZGVjbGFyZXMgYSBrZXkvdmFsdWUgb2JqZWN0IGNvbnRhaW5pbmcgQ1NTIHByb3BlcnRpZXMvc3R5bGVzIHRoYXQgY2FuIHRoZW4gYmUgdXNlZCBmb3JcbiAqIHtAbGluayBzdGF0ZSBhbmltYXRpb24gc3RhdGVzfSwgd2l0aGluIGFuIHtAbGluayBzZXF1ZW5jZSBhbmltYXRpb24gc2VxdWVuY2V9LCBvciBhcyBzdHlsaW5nIGRhdGFcbiAqIGZvciBib3RoIHtAbGluayBhbmltYXRlIGFuaW1hdGV9IGFuZCB7QGxpbmsga2V5ZnJhbWVzIGtleWZyYW1lc30uXG4gKlxuICogIyMjIFVzYWdlXG4gKlxuICogYHN0eWxlYCB0YWtlcyBpbiBhIGtleS92YWx1ZSBzdHJpbmcgbWFwIGFzIGRhdGEgYW5kIGV4cGVjdHMgb25lIG9yIG1vcmUgQ1NTIHByb3BlcnR5L3ZhbHVlIHBhaXJzXG4gKiB0byBiZSBkZWZpbmVkLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHN0cmluZyB2YWx1ZXMgYXJlIHVzZWQgZm9yIGNzcyBwcm9wZXJ0aWVzXG4gKiBzdHlsZSh7IGJhY2tncm91bmQ6IFwicmVkXCIsIGNvbG9yOiBcImJsdWVcIiB9KVxuICpcbiAqIC8vIG51bWVyaWNhbCAocGl4ZWwpIHZhbHVlcyBhcmUgYWxzbyBzdXBwb3J0ZWRcbiAqIHN0eWxlKHsgd2lkdGg6IDEwMCwgaGVpZ2h0OiAwIH0pXG4gKiBgYGBcbiAqXG4gKiAjIyMjIEF1dG8tc3R5bGVzICh1c2luZyBgKmApXG4gKlxuICogV2hlbiBhbiBhc3Rlcml4IChgKmApIGNoYXJhY3RlciBpcyB1c2VkIGFzIGEgdmFsdWUgdGhlbiBpdCB3aWxsIGJlIGRldGVjdGVkIGZyb20gdGhlIGVsZW1lbnRcbiAqIGJlaW5nIGFuaW1hdGVkIGFuZCBhcHBsaWVkIGFzIGFuaW1hdGlvbiBkYXRhIHdoZW4gdGhlIGFuaW1hdGlvbiBzdGFydHMuXG4gKlxuICogVGhpcyBmZWF0dXJlIHByb3ZlcyB1c2VmdWwgZm9yIGEgc3RhdGUgZGVwZW5kaW5nIG9uIGxheW91dCBhbmQvb3IgZW52aXJvbm1lbnQgZmFjdG9yczsgaW4gc3VjaFxuICogY2FzZXMgdGhlIHN0eWxlcyBhcmUgY2FsY3VsYXRlZCBqdXN0IGJlZm9yZSB0aGUgYW5pbWF0aW9uIHN0YXJ0cy5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyB0aGUgc3RlcHMgYmVsb3cgd2lsbCBhbmltYXRlIGZyb20gMCB0byB0aGVcbiAqIC8vIGFjdHVhbCBoZWlnaHQgb2YgdGhlIGVsZW1lbnRcbiAqIHN0eWxlKHsgaGVpZ2h0OiAwIH0pLFxuICogYW5pbWF0ZShcIjFzXCIsIHN0eWxlKHsgaGVpZ2h0OiBcIipcIiB9KSlcbiAqIGBgYFxuICpcbiAqIHtAZXhhbXBsZSBjb3JlL2FuaW1hdGlvbi90cy9kc2wvYW5pbWF0aW9uX2V4YW1wbGUudHMgcmVnaW9uPSdDb21wb25lbnQnfVxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3R5bGUoXG4gICAgdG9rZW5zOiAnKicgfCB7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfSB8XG4gICAgQXJyYXk8JyonfHtba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJ9Pik6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdHlsZSwgc3R5bGVzOiB0b2tlbnMsIG9mZnNldDogbnVsbH07XG59XG5cbi8qKlxuICogYHN0YXRlYCBpcyBhbiBhbmltYXRpb24tc3BlY2lmaWMgZnVuY3Rpb24gdGhhdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBBbmd1bGFyJ3NcbiAqIGFuaW1hdGlvbiBEU0wgbGFuZ3VhZ2UuIElmIHRoaXMgaW5mb3JtYXRpb24gaXMgbmV3LCBwbGVhc2UgbmF2aWdhdGUgdG8gdGhlIHtAbGlua1xuICogQ29tcG9uZW50I2FuaW1hdGlvbnMgY29tcG9uZW50IGFuaW1hdGlvbnMgbWV0YWRhdGEgcGFnZX0gdG8gZ2FpbiBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mXG4gKiBob3cgYW5pbWF0aW9ucyBpbiBBbmd1bGFyIGFyZSB1c2VkLlxuICpcbiAqIGBzdGF0ZWAgZGVjbGFyZXMgYW4gYW5pbWF0aW9uIHN0YXRlIHdpdGhpbiB0aGUgZ2l2ZW4gdHJpZ2dlci4gV2hlbiBhIHN0YXRlIGlzIGFjdGl2ZSB3aXRoaW4gYVxuICogY29tcG9uZW50IHRoZW4gaXRzIGFzc29jaWF0ZWQgc3R5bGVzIHdpbGwgcGVyc2lzdCBvbiB0aGUgZWxlbWVudCB0aGF0IHRoZSB0cmlnZ2VyIGlzIGF0dGFjaGVkIHRvXG4gKiAoZXZlbiB3aGVuIHRoZSBhbmltYXRpb24gZW5kcykuXG4gKlxuICogVG8gYW5pbWF0ZSBiZXR3ZWVuIHN0YXRlcywgaGF2ZSBhIGxvb2sgYXQgdGhlIGFuaW1hdGlvbiB7QGxpbmsgdHJhbnNpdGlvbiB0cmFuc2l0aW9ufSBEU0xcbiAqIGZ1bmN0aW9uLiBUbyByZWdpc3RlciBzdGF0ZXMgdG8gYW4gYW5pbWF0aW9uIHRyaWdnZXIgcGxlYXNlIGhhdmUgYSBsb29rIGF0IHRoZSB7QGxpbmsgdHJpZ2dlclxuICogdHJpZ2dlcn0gZnVuY3Rpb24uXG4gKlxuICogIyMjIyBUaGUgYHZvaWRgIHN0YXRlXG4gKlxuICogVGhlIGB2b2lkYCBzdGF0ZSB2YWx1ZSBpcyBhIHJlc2VydmVkIHdvcmQgdGhhdCBhbmd1bGFyIHVzZXMgdG8gZGV0ZXJtaW5lIHdoZW4gdGhlIGVsZW1lbnQgaXMgbm90XG4gKiBhcGFydCBvZiB0aGUgYXBwbGljYXRpb24gYW55bW9yZSAoZS5nLiB3aGVuIGFuIGBuZ0lmYCBldmFsdWF0ZXMgdG8gZmFsc2UgdGhlbiB0aGUgc3RhdGUgb2YgdGhlXG4gKiBhc3NvY2lhdGVkIGVsZW1lbnQgaXMgdm9pZCkuXG4gKlxuICogIyMjIyBUaGUgYCpgIChkZWZhdWx0KSBzdGF0ZVxuICpcbiAqIFRoZSBgKmAgc3RhdGUgKHdoZW4gc3R5bGVkKSBpcyBhIGZhbGxiYWNrIHN0YXRlIHRoYXQgd2lsbCBiZSB1c2VkIGlmIHRoZSBzdGF0ZSB0aGF0IGlzIGJlaW5nXG4gKiBhbmltYXRlZCBpcyBub3QgZGVjbGFyZWQgd2l0aGluIHRoZSB0cmlnZ2VyLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIGBzdGF0ZWAgd2lsbCBkZWNsYXJlIGFuIGFuaW1hdGlvbiBzdGF0ZSB3aXRoIGl0cyBhc3NvY2lhdGVkIHN0eWxlc1xuICogd2l0aGluIHRoZSBnaXZlbiB0cmlnZ2VyLlxuICpcbiAqIC0gYHN0YXRlTmFtZUV4cHJgIGNhbiBiZSBvbmUgb3IgbW9yZSBzdGF0ZSBuYW1lcyBzZXBhcmF0ZWQgYnkgY29tbWFzLlxuICogLSBgc3R5bGVzYCByZWZlcnMgdG8gdGhlIHtAbGluayBzdHlsZSBzdHlsaW5nIGRhdGF9IHRoYXQgd2lsbCBiZSBwZXJzaXN0ZWQgb24gdGhlIGVsZW1lbnQgb25jZVxuICogdGhlIHN0YXRlIGhhcyBiZWVuIHJlYWNoZWQuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gXCJ2b2lkXCIgaXMgYSByZXNlcnZlZCBuYW1lIGZvciBhIHN0YXRlIGFuZCBpcyB1c2VkIHRvIHJlcHJlc2VudFxuICogLy8gdGhlIHN0YXRlIGluIHdoaWNoIGFuIGVsZW1lbnQgaXMgZGV0YWNoZWQgZnJvbSBmcm9tIHRoZSBhcHBsaWNhdGlvbi5cbiAqIHN0YXRlKFwidm9pZFwiLCBzdHlsZSh7IGhlaWdodDogMCB9KSlcbiAqXG4gKiAvLyB1c2VyLWRlZmluZWQgc3RhdGVzXG4gKiBzdGF0ZShcImNsb3NlZFwiLCBzdHlsZSh7IGhlaWdodDogMCB9KSlcbiAqIHN0YXRlKFwib3BlbiwgdmlzaWJsZVwiLCBzdHlsZSh7IGhlaWdodDogXCIqXCIgfSkpXG4gKiBgYGBcbiAqXG4gKiB7QGV4YW1wbGUgY29yZS9hbmltYXRpb24vdHMvZHNsL2FuaW1hdGlvbl9leGFtcGxlLnRzIHJlZ2lvbj0nQ29tcG9uZW50J31cbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXRlKFxuICAgIG5hbWU6IHN0cmluZywgc3R5bGVzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhLFxuICAgIG9wdGlvbnM/OiB7cGFyYW1zOiB7W25hbWU6IHN0cmluZ106IGFueX19KTogQW5pbWF0aW9uU3RhdGVNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlN0YXRlLCBuYW1lLCBzdHlsZXMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIGBrZXlmcmFtZXNgIGlzIGFuIGFuaW1hdGlvbi1zcGVjaWZpYyBmdW5jdGlvbiB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIEFuZ3VsYXInc1xuICogYW5pbWF0aW9uIERTTCBsYW5ndWFnZS4gSWYgdGhpcyBpbmZvcm1hdGlvbiBpcyBuZXcsIHBsZWFzZSBuYXZpZ2F0ZSB0byB0aGUge0BsaW5rXG4gKiBDb21wb25lbnQjYW5pbWF0aW9ucyBjb21wb25lbnQgYW5pbWF0aW9ucyBtZXRhZGF0YSBwYWdlfSB0byBnYWluIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2ZcbiAqIGhvdyBhbmltYXRpb25zIGluIEFuZ3VsYXIgYXJlIHVzZWQuXG4gKlxuICogYGtleWZyYW1lc2Agc3BlY2lmaWVzIGEgY29sbGVjdGlvbiBvZiB7QGxpbmsgc3R5bGUgc3R5bGV9IGVudHJpZXMgZWFjaCBvcHRpb25hbGx5IGNoYXJhY3Rlcml6ZWRcbiAqIGJ5IGFuIGBvZmZzZXRgIHZhbHVlLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIFRoZSBga2V5ZnJhbWVzYCBhbmltYXRpb24gZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBhbG9uZ3NpZGUgdGhlIHtAbGluayBhbmltYXRlIGFuaW1hdGV9XG4gKiBhbmltYXRpb24gZnVuY3Rpb24uIEluc3RlYWQgb2YgYXBwbHlpbmcgYW5pbWF0aW9ucyBmcm9tIHdoZXJlIHRoZXkgYXJlIGN1cnJlbnRseSB0byB0aGVpclxuICogZGVzdGluYXRpb24sIGtleWZyYW1lcyBjYW4gZGVzY3JpYmUgaG93IGVhY2ggc3R5bGUgZW50cnkgaXMgYXBwbGllZCBhbmQgYXQgd2hhdCBwb2ludCB3aXRoaW4gdGhlXG4gKiBhbmltYXRpb24gYXJjIChtdWNoIGxpa2UgQ1NTIEtleWZyYW1lIEFuaW1hdGlvbnMgZG8pLlxuICpcbiAqIEZvciBlYWNoIGBzdHlsZSgpYCBlbnRyeSBhbiBgb2Zmc2V0YCB2YWx1ZSBjYW4gYmUgc2V0LiBEb2luZyBzbyBhbGxvd3MgdG8gc3BlY2lmeSBhdCB3aGF0XG4gKiBwZXJjZW50YWdlIG9mIHRoZSBhbmltYXRlIHRpbWUgdGhlIHN0eWxlcyB3aWxsIGJlIGFwcGxpZWQuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gdGhlIHByb3ZpZGVkIG9mZnNldCB2YWx1ZXMgZGVzY3JpYmUgd2hlbiBlYWNoIGJhY2tncm91bmRDb2xvciB2YWx1ZSBpcyBhcHBsaWVkLlxuICogYW5pbWF0ZShcIjVzXCIsIGtleWZyYW1lcyhbXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcInJlZFwiLCBvZmZzZXQ6IDAgfSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcImJsdWVcIiwgb2Zmc2V0OiAwLjIgfSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcIm9yYW5nZVwiLCBvZmZzZXQ6IDAuMyB9KSxcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwiYmxhY2tcIiwgb2Zmc2V0OiAxIH0pXG4gKiBdKSlcbiAqIGBgYFxuICpcbiAqIEFsdGVybmF0aXZlbHksIGlmIHRoZXJlIGFyZSBubyBgb2Zmc2V0YCB2YWx1ZXMgdXNlZCB3aXRoaW4gdGhlIHN0eWxlIGVudHJpZXMgdGhlbiB0aGUgb2Zmc2V0c1xuICogd2lsbCBiZSBjYWxjdWxhdGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogYW5pbWF0ZShcIjVzXCIsIGtleWZyYW1lcyhbXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcInJlZFwiIH0pIC8vIG9mZnNldCA9IDBcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwiYmx1ZVwiIH0pIC8vIG9mZnNldCA9IDAuMzNcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwib3JhbmdlXCIgfSkgLy8gb2Zmc2V0ID0gMC42NlxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJibGFja1wiIH0pIC8vIG9mZnNldCA9IDFcbiAqIF0pKVxuICogYGBgXG4gKlxuICoge0BleGFtcGxlIGNvcmUvYW5pbWF0aW9uL3RzL2RzbC9hbmltYXRpb25fZXhhbXBsZS50cyByZWdpb249J0NvbXBvbmVudCd9XG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBrZXlmcmFtZXMoc3RlcHM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGFbXSk6IEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5LZXlmcmFtZXMsIHN0ZXBzfTtcbn1cblxuLyoqXG4gKiBgdHJhbnNpdGlvbmAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJZiB0aGlzIGluZm9ybWF0aW9uIGlzIG5ldywgcGxlYXNlIG5hdmlnYXRlIHRvIHRoZSB7QGxpbmtcbiAqIENvbXBvbmVudCNhbmltYXRpb25zIGNvbXBvbmVudCBhbmltYXRpb25zIG1ldGFkYXRhIHBhZ2V9IHRvIGdhaW4gYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZlxuICogaG93IGFuaW1hdGlvbnMgaW4gQW5ndWxhciBhcmUgdXNlZC5cbiAqXG4gKiBgdHJhbnNpdGlvbmAgZGVjbGFyZXMgdGhlIHtAbGluayBzZXF1ZW5jZSBzZXF1ZW5jZSBvZiBhbmltYXRpb24gc3RlcHN9IHRoYXQgd2lsbCBiZSBydW4gd2hlbiB0aGVcbiAqIHByb3ZpZGVkIGBzdGF0ZUNoYW5nZUV4cHJgIHZhbHVlIGlzIHNhdGlzZmllZC4gVGhlIGBzdGF0ZUNoYW5nZUV4cHJgIGNvbnNpc3RzIG9mIGEgYHN0YXRlMSA9PlxuICogc3RhdGUyYCB3aGljaCBjb25zaXN0cyBvZiB0d28ga25vd24gc3RhdGVzICh1c2UgYW4gYXN0ZXJpeCAoYCpgKSB0byByZWZlciB0byBhIGR5bmFtaWMgc3RhcnRpbmdcbiAqIGFuZC9vciBlbmRpbmcgc3RhdGUpLlxuICpcbiAqIEEgZnVuY3Rpb24gY2FuIGFsc28gYmUgcHJvdmlkZWQgYXMgdGhlIGBzdGF0ZUNoYW5nZUV4cHJgIGFyZ3VtZW50IGZvciBhIHRyYW5zaXRpb24gYW5kIHRoaXNcbiAqIGZ1bmN0aW9uIHdpbGwgYmUgZXhlY3V0ZWQgZWFjaCB0aW1lIGEgc3RhdGUgY2hhbmdlIG9jY3Vycy4gSWYgdGhlIHZhbHVlIHJldHVybmVkIHdpdGhpbiB0aGVcbiAqIGZ1bmN0aW9uIGlzIHRydWUgdGhlbiB0aGUgYXNzb2NpYXRlZCBhbmltYXRpb24gd2lsbCBiZSBydW4uXG4gKlxuICogQW5pbWF0aW9uIHRyYW5zaXRpb25zIGFyZSBwbGFjZWQgd2l0aGluIGFuIHtAbGluayB0cmlnZ2VyIGFuaW1hdGlvbiB0cmlnZ2VyfS4gRm9yIGFuIHRyYW5zaXRpb25cbiAqIHRvIGFuaW1hdGUgdG8gYSBzdGF0ZSB2YWx1ZSBhbmQgcGVyc2lzdCBpdHMgc3R5bGVzIHRoZW4gb25lIG9yIG1vcmUge0BsaW5rIHN0YXRlIGFuaW1hdGlvblxuICogc3RhdGVzfSBpcyBleHBlY3RlZCB0byBiZSBkZWZpbmVkLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIEFuIGFuaW1hdGlvbiB0cmFuc2l0aW9uIGlzIGtpY2tlZCBvZmYgdGhlIGBzdGF0ZUNoYW5nZUV4cHJgIHByZWRpY2F0ZSBldmFsdWF0ZXMgdG8gdHJ1ZSBiYXNlZCBvblxuICogd2hhdCB0aGUgcHJldmlvdXMgc3RhdGUgaXMgYW5kIHdoYXQgdGhlIGN1cnJlbnQgc3RhdGUgaGFzIGJlY29tZS4gSW4gb3RoZXIgd29yZHMsIGlmIGEgdHJhbnNpdGlvblxuICogaXMgZGVmaW5lZCB0aGF0IG1hdGNoZXMgdGhlIG9sZC9jdXJyZW50IHN0YXRlIGNyaXRlcmlhIHRoZW4gdGhlIGFzc29jaWF0ZWQgYW5pbWF0aW9uIHdpbGwgYmVcbiAqIHRyaWdnZXJlZC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBhbGwgdHJhbnNpdGlvbi9zdGF0ZSBjaGFuZ2VzIGFyZSBkZWZpbmVkIHdpdGhpbiBhbiBhbmltYXRpb24gdHJpZ2dlclxuICogdHJpZ2dlcihcIm15QW5pbWF0aW9uVHJpZ2dlclwiLCBbXG4gKiAgIC8vIGlmIGEgc3RhdGUgaXMgZGVmaW5lZCB0aGVuIGl0cyBzdHlsZXMgd2lsbCBiZSBwZXJzaXN0ZWQgd2hlbiB0aGVcbiAqICAgLy8gYW5pbWF0aW9uIGhhcyBmdWxseSBjb21wbGV0ZWQgaXRzZWxmXG4gKiAgIHN0YXRlKFwib25cIiwgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcImdyZWVuXCIgfSkpLFxuICogICBzdGF0ZShcIm9mZlwiLCBzdHlsZSh7IGJhY2tncm91bmQ6IFwiZ3JleVwiIH0pKSxcbiAqXG4gKiAgIC8vIGEgdHJhbnNpdGlvbiBhbmltYXRpb24gdGhhdCB3aWxsIGJlIGtpY2tlZCBvZmYgd2hlbiB0aGUgc3RhdGUgdmFsdWVcbiAqICAgLy8gYm91bmQgdG8gXCJteUFuaW1hdGlvblRyaWdnZXJcIiBjaGFuZ2VzIGZyb20gXCJvblwiIHRvIFwib2ZmXCJcbiAqICAgdHJhbnNpdGlvbihcIm9uID0+IG9mZlwiLCBhbmltYXRlKDUwMCkpLFxuICpcbiAqICAgLy8gaXQgaXMgYWxzbyBwb3NzaWJsZSB0byBkbyBydW4gdGhlIHNhbWUgYW5pbWF0aW9uIGZvciBib3RoIGRpcmVjdGlvbnNcbiAqICAgdHJhbnNpdGlvbihcIm9uIDw9PiBvZmZcIiwgYW5pbWF0ZSg1MDApKSxcbiAqXG4gKiAgIC8vIG9yIHRvIGRlZmluZSBtdWx0aXBsZSBzdGF0ZXMgcGFpcnMgc2VwYXJhdGVkIGJ5IGNvbW1hc1xuICogICB0cmFuc2l0aW9uKFwib24gPT4gb2ZmLCBvZmYgPT4gdm9pZFwiLCBhbmltYXRlKDUwMCkpLFxuICpcbiAqICAgLy8gdGhpcyBpcyBhIGNhdGNoLWFsbCBzdGF0ZSBjaGFuZ2UgZm9yIHdoZW4gYW4gZWxlbWVudCBpcyBpbnNlcnRlZCBpbnRvXG4gKiAgIC8vIHRoZSBwYWdlIGFuZCB0aGUgZGVzdGluYXRpb24gc3RhdGUgaXMgdW5rbm93blxuICogICB0cmFuc2l0aW9uKFwidm9pZCA9PiAqXCIsIFtcbiAqICAgICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgICAgYW5pbWF0ZSg1MDApXG4gKiAgIF0pLFxuICpcbiAqICAgLy8gdGhpcyB3aWxsIGNhcHR1cmUgYSBzdGF0ZSBjaGFuZ2UgYmV0d2VlbiBhbnkgc3RhdGVzXG4gKiAgIHRyYW5zaXRpb24oXCIqID0+ICpcIiwgYW5pbWF0ZShcIjFzIDBzXCIpKSxcbiAqXG4gKiAgIC8vIHlvdSBjYW4gYWxzbyBnbyBmdWxsIG91dCBhbmQgaW5jbHVkZSBhIGZ1bmN0aW9uXG4gKiAgIHRyYW5zaXRpb24oKGZyb21TdGF0ZSwgdG9TdGF0ZSkgPT4ge1xuICogICAgIC8vIHdoZW4gYHRydWVgIHRoZW4gaXQgd2lsbCBhbGxvdyB0aGUgYW5pbWF0aW9uIGJlbG93IHRvIGJlIGludm9rZWRcbiAqICAgICByZXR1cm4gZnJvbVN0YXRlID09IFwib2ZmXCIgJiYgdG9TdGF0ZSA9PSBcIm9uXCI7XG4gKiAgIH0sIGFuaW1hdGUoXCIxcyAwc1wiKSlcbiAqIF0pXG4gKiBgYGBcbiAqXG4gKiBUaGUgdGVtcGxhdGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29tcG9uZW50IHdpbGwgbWFrZSB1c2Ugb2YgdGhlIGBteUFuaW1hdGlvblRyaWdnZXJgIGFuaW1hdGlvblxuICogdHJpZ2dlciBieSBiaW5kaW5nIHRvIGFuIGVsZW1lbnQgd2l0aGluIGl0cyB0ZW1wbGF0ZSBjb2RlLlxuICpcbiAqIGBgYGh0bWxcbiAqIDwhLS0gc29tZXdoZXJlIGluc2lkZSBvZiBteS1jb21wb25lbnQtdHBsLmh0bWwgLS0+XG4gKiA8ZGl2IFtAbXlBbmltYXRpb25UcmlnZ2VyXT1cIm15U3RhdHVzRXhwXCI+Li4uPC9kaXY+XG4gKiBgYGBcbiAqXG4gKiAjIyMjIFRoZSBmaW5hbCBgYW5pbWF0ZWAgY2FsbFxuICpcbiAqIElmIHRoZSBmaW5hbCBzdGVwIHdpdGhpbiB0aGUgdHJhbnNpdGlvbiBzdGVwcyBpcyBhIGNhbGwgdG8gYGFuaW1hdGUoKWAgdGhhdCAqKm9ubHkqKiB1c2VzIGFcbiAqIHRpbWluZyB2YWx1ZSB3aXRoICoqbm8gc3R5bGUgZGF0YSoqIHRoZW4gaXQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHVzZWQgYXMgdGhlIGZpbmFsIGFuaW1hdGlvbiBhcmNcbiAqIGZvciB0aGUgZWxlbWVudCB0byBhbmltYXRlIGl0c2VsZiB0byB0aGUgZmluYWwgc3RhdGUuIFRoaXMgaW52b2x2ZXMgYW4gYXV0b21hdGljIG1peCBvZlxuICogYWRkaW5nL3JlbW92aW5nIENTUyBzdHlsZXMgc28gdGhhdCB0aGUgZWxlbWVudCB3aWxsIGJlIGluIHRoZSBleGFjdCBzdGF0ZSBpdCBzaG91bGQgYmUgZm9yIHRoZVxuICogYXBwbGllZCBzdGF0ZSB0byBiZSBwcmVzZW50ZWQgY29ycmVjdGx5LlxuICpcbiAqIGBgYFxuICogLy8gc3RhcnQgb2ZmIGJ5IGhpZGluZyB0aGUgZWxlbWVudCwgYnV0IG1ha2Ugc3VyZSB0aGF0IGl0IGFuaW1hdGVzIHByb3Blcmx5IHRvIHdoYXRldmVyIHN0YXRlXG4gKiAvLyBpcyBjdXJyZW50bHkgYWN0aXZlIGZvciBcIm15QW5pbWF0aW9uVHJpZ2dlclwiXG4gKiB0cmFuc2l0aW9uKFwidm9pZCA9PiAqXCIsIFtcbiAqICAgc3R5bGUoeyBvcGFjaXR5OiAwIH0pLFxuICogICBhbmltYXRlKDUwMClcbiAqIF0pXG4gKiBgYGBcbiAqXG4gKiAjIyMgVXNpbmcgOmVudGVyIGFuZCA6bGVhdmVcbiAqXG4gKiBHaXZlbiB0aGF0IGVudGVyIChpbnNlcnRpb24pIGFuZCBsZWF2ZSAocmVtb3ZhbCkgYW5pbWF0aW9ucyBhcmUgc28gY29tbW9uLCB0aGUgYHRyYW5zaXRpb25gXG4gKiBmdW5jdGlvbiBhY2NlcHRzIGJvdGggYDplbnRlcmAgYW5kIGA6bGVhdmVgIHZhbHVlcyB3aGljaCBhcmUgYWxpYXNlcyBmb3IgdGhlIGB2b2lkID0+ICpgIGFuZCBgKlxuICogPT4gdm9pZGAgc3RhdGUgY2hhbmdlcy5cbiAqXG4gKiBgYGBcbiAqIHRyYW5zaXRpb24oXCI6ZW50ZXJcIiwgW1xuICogICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgIGFuaW1hdGUoNTAwLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpXG4gKiBdKSxcbiAqIHRyYW5zaXRpb24oXCI6bGVhdmVcIiwgW1xuICogICBhbmltYXRlKDUwMCwgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKVxuICogXSlcbiAqIGBgYFxuICpcbiAqICMjIyBCb29sZWFuIHZhbHVlc1xuICogaWYgYSB0cmlnZ2VyIGJpbmRpbmcgdmFsdWUgaXMgYSBib29sZWFuIHZhbHVlIHRoZW4gaXQgY2FuIGJlIG1hdGNoZWQgdXNpbmcgYSB0cmFuc2l0aW9uXG4gKiBleHByZXNzaW9uIHRoYXQgY29tcGFyZXMgYHRydWVgIGFuZCBgZmFsc2VgIG9yIGAxYCBhbmQgYDBgLlxuICpcbiAqIGBgYFxuICogLy8gaW4gdGhlIHRlbXBsYXRlXG4gKiA8ZGl2IFtAb3BlbkNsb3NlXT1cIm9wZW4gPyB0cnVlIDogZmFsc2VcIj4uLi48L2Rpdj5cbiAqXG4gKiAvLyBpbiB0aGUgY29tcG9uZW50IG1ldGFkYXRhXG4gKiB0cmlnZ2VyKCdvcGVuQ2xvc2UnLCBbXG4gKiAgIHN0YXRlKCd0cnVlJywgc3R5bGUoeyBoZWlnaHQ6ICcqJyB9KSksXG4gKiAgIHN0YXRlKCdmYWxzZScsIHN0eWxlKHsgaGVpZ2h0OiAnMHB4JyB9KSksXG4gKiAgIHRyYW5zaXRpb24oJ2ZhbHNlIDw9PiB0cnVlJywgYW5pbWF0ZSg1MDApKVxuICogXSlcbiAqIGBgYFxuICpcbiAqICMjIyBVc2luZyA6aW5jcmVtZW50IGFuZCA6ZGVjcmVtZW50XG4gKiBJbiBhZGRpdGlvbiB0byB0aGUgOmVudGVyIGFuZCA6bGVhdmUgdHJhbnNpdGlvbiBhbGlhc2VzLCB0aGUgOmluY3JlbWVudCBhbmQgOmRlY3JlbWVudCBhbGlhc2VzXG4gKiBjYW4gYmUgdXNlZCB0byBraWNrIG9mZiBhIHRyYW5zaXRpb24gd2hlbiBhIG51bWVyaWMgdmFsdWUgaGFzIGluY3JlYXNlZCBvciBkZWNyZWFzZWQgaW4gdmFsdWUuXG4gKlxuICogYGBgXG4gKiBpbXBvcnQge2dyb3VwLCBhbmltYXRlLCBxdWVyeSwgdHJhbnNpdGlvbiwgc3R5bGUsIHRyaWdnZXJ9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuICogaW1wb3J0IHtDb21wb25lbnR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuICpcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2Jhbm5lci1jYXJvdXNlbC1jb21wb25lbnQnLFxuICogICBzdHlsZXM6IFtgXG4gKiAgICAgLmJhbm5lci1jb250YWluZXIge1xuICogICAgICAgIHBvc2l0aW9uOnJlbGF0aXZlO1xuICogICAgICAgIGhlaWdodDo1MDBweDtcbiAqICAgICAgICBvdmVyZmxvdzpoaWRkZW47XG4gKiAgICAgIH1cbiAqICAgICAuYmFubmVyLWNvbnRhaW5lciA+IC5iYW5uZXIge1xuICogICAgICAgIHBvc2l0aW9uOmFic29sdXRlO1xuICogICAgICAgIGxlZnQ6MDtcbiAqICAgICAgICB0b3A6MDtcbiAqICAgICAgICBmb250LXNpemU6MjAwcHg7XG4gKiAgICAgICAgbGluZS1oZWlnaHQ6NTAwcHg7XG4gKiAgICAgICAgZm9udC13ZWlnaHQ6Ym9sZDtcbiAqICAgICAgICB0ZXh0LWFsaWduOmNlbnRlcjtcbiAqICAgICAgICB3aWR0aDoxMDAlO1xuICogICAgICB9XG4gKiAgIGBdLFxuICogICB0ZW1wbGF0ZTogYFxuICogICAgIDxidXR0b24gKGNsaWNrKT1cInByZXZpb3VzKClcIj5QcmV2aW91czwvYnV0dG9uPlxuICogICAgIDxidXR0b24gKGNsaWNrKT1cIm5leHQoKVwiPk5leHQ8L2J1dHRvbj5cbiAqICAgICA8aHI+XG4gKiAgICAgPGRpdiBbQGJhbm5lckFuaW1hdGlvbl09XCJzZWxlY3RlZEluZGV4XCIgY2xhc3M9XCJiYW5uZXItY29udGFpbmVyXCI+XG4gKiAgICAgICA8ZGl2IGNsYXNzPVwiYmFubmVyXCIgKm5nRm9yPVwibGV0IGJhbm5lciBvZiBiYW5uZXJzXCI+IHt7IGJhbm5lciB9fSA8L2Rpdj5cbiAqICAgICA8L2Rpdj5cbiAqICAgYCxcbiAqICAgYW5pbWF0aW9uczogW1xuICogICAgIHRyaWdnZXIoJ2Jhbm5lckFuaW1hdGlvbicsIFtcbiAqICAgICAgIHRyYW5zaXRpb24oXCI6aW5jcmVtZW50XCIsIGdyb3VwKFtcbiAqICAgICAgICAgcXVlcnkoJzplbnRlcicsIFtcbiAqICAgICAgICAgICBzdHlsZSh7IGxlZnQ6ICcxMDAlJyB9KSxcbiAqICAgICAgICAgICBhbmltYXRlKCcwLjVzIGVhc2Utb3V0Jywgc3R5bGUoJyonKSlcbiAqICAgICAgICAgXSksXG4gKiAgICAgICAgIHF1ZXJ5KCc6bGVhdmUnLCBbXG4gKiAgICAgICAgICAgYW5pbWF0ZSgnMC41cyBlYXNlLW91dCcsIHN0eWxlKHsgbGVmdDogJy0xMDAlJyB9KSlcbiAqICAgICAgICAgXSlcbiAqICAgICAgIF0pKSxcbiAqICAgICAgIHRyYW5zaXRpb24oXCI6ZGVjcmVtZW50XCIsIGdyb3VwKFtcbiAqICAgICAgICAgcXVlcnkoJzplbnRlcicsIFtcbiAqICAgICAgICAgICBzdHlsZSh7IGxlZnQ6ICctMTAwJScgfSksXG4gKiAgICAgICAgICAgYW5pbWF0ZSgnMC41cyBlYXNlLW91dCcsIHN0eWxlKCcqJykpXG4gKiAgICAgICAgIF0pLFxuICogICAgICAgICBxdWVyeSgnOmxlYXZlJywgW1xuICogICAgICAgICAgIGFuaW1hdGUoJzAuNXMgZWFzZS1vdXQnLCBzdHlsZSh7IGxlZnQ6ICcxMDAlJyB9KSlcbiAqICAgICAgICAgXSlcbiAqICAgICAgIF0pKVxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBCYW5uZXJDYXJvdXNlbENvbXBvbmVudCB7XG4gKiAgIGFsbEJhbm5lcnM6IHN0cmluZ1tdID0gWycxJywgJzInLCAnMycsICc0J107XG4gKiAgIHNlbGVjdGVkSW5kZXg6IG51bWJlciA9IDA7XG4gKlxuICogICBnZXQgYmFubmVycygpIHtcbiAqICAgICAgcmV0dXJuIFt0aGlzLmFsbEJhbm5lcnNbdGhpcy5zZWxlY3RlZEluZGV4XV07XG4gKiAgIH1cbiAqXG4gKiAgIHByZXZpb3VzKCkge1xuICogICAgIHRoaXMuc2VsZWN0ZWRJbmRleCA9IE1hdGgubWF4KHRoaXMuc2VsZWN0ZWRJbmRleCAtIDEsIDApO1xuICogICB9XG4gKlxuICogICBuZXh0KCkge1xuICogICAgIHRoaXMuc2VsZWN0ZWRJbmRleCA9IE1hdGgubWluKHRoaXMuc2VsZWN0ZWRJbmRleCArIDEsIHRoaXMuYWxsQmFubmVycy5sZW5ndGggLSAxKTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICoge0BleGFtcGxlIGNvcmUvYW5pbWF0aW9uL3RzL2RzbC9hbmltYXRpb25fZXhhbXBsZS50cyByZWdpb249J0NvbXBvbmVudCd9XG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2l0aW9uKFxuICAgIHN0YXRlQ2hhbmdlRXhwcjogc3RyaW5nIHwgKChmcm9tU3RhdGU6IHN0cmluZywgdG9TdGF0ZTogc3RyaW5nLCBlbGVtZW50PzogYW55LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXM/OiB7W2tleTogc3RyaW5nXTogYW55fSkgPT4gYm9vbGVhbiksXG4gICAgc3RlcHM6IEFuaW1hdGlvbk1ldGFkYXRhIHwgQW5pbWF0aW9uTWV0YWRhdGFbXSxcbiAgICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25UcmFuc2l0aW9uTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5UcmFuc2l0aW9uLCBleHByOiBzdGF0ZUNoYW5nZUV4cHIsIGFuaW1hdGlvbjogc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIGBhbmltYXRpb25gIGlzIGFuIGFuaW1hdGlvbi1zcGVjaWZpYyBmdW5jdGlvbiB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIEFuZ3VsYXInc1xuICogYW5pbWF0aW9uIERTTCBsYW5ndWFnZS5cbiAqXG4gKiBgdmFyIG15QW5pbWF0aW9uID0gYW5pbWF0aW9uKC4uLilgIGlzIGRlc2lnbmVkIHRvIHByb2R1Y2UgYSByZXVzYWJsZSBhbmltYXRpb24gdGhhdCBjYW4gYmUgbGF0ZXJcbiAqIGludm9rZWQgaW4gYW5vdGhlciBhbmltYXRpb24gb3Igc2VxdWVuY2UuIFJldXNhYmxlIGFuaW1hdGlvbnMgYXJlIGRlc2lnbmVkIHRvIG1ha2UgdXNlIG9mXG4gKiBhbmltYXRpb24gcGFyYW1ldGVycyBhbmQgdGhlIHByb2R1Y2VkIGFuaW1hdGlvbiBjYW4gYmUgdXNlZCB2aWEgdGhlIGB1c2VBbmltYXRpb25gIG1ldGhvZC5cbiAqXG4gKiBgYGBcbiAqIHZhciBmYWRlQW5pbWF0aW9uID0gYW5pbWF0aW9uKFtcbiAqICAgc3R5bGUoeyBvcGFjaXR5OiAne3sgc3RhcnQgfX0nIH0pLFxuICogICBhbmltYXRlKCd7eyB0aW1lIH19JyxcbiAqICAgICBzdHlsZSh7IG9wYWNpdHk6ICd7eyBlbmQgfX0nfSkpXG4gKiBdLCB7IHBhcmFtczogeyB0aW1lOiAnMTAwMG1zJywgc3RhcnQ6IDAsIGVuZDogMSB9fSk7XG4gKiBgYGBcbiAqXG4gKiBJZiBwYXJhbWV0ZXJzIGFyZSBhdHRhY2hlZCB0byBhbiBhbmltYXRpb24gdGhlbiB0aGV5IGFjdCBhcyAqKmRlZmF1bHQgcGFyYW1ldGVyIHZhbHVlcyoqLiBXaGVuIGFuXG4gKiBhbmltYXRpb24gaXMgaW52b2tlZCB2aWEgYHVzZUFuaW1hdGlvbmAgdGhlbiBwYXJhbWV0ZXIgdmFsdWVzIGFyZSBhbGxvd2VkIHRvIGJlIHBhc3NlZCBpblxuICogZGlyZWN0bHkuIElmIGFueSBvZiB0aGUgcGFzc2VkIGluIHBhcmFtZXRlciB2YWx1ZXMgYXJlIG1pc3NpbmcgdGhlbiB0aGUgZGVmYXVsdCB2YWx1ZXMgd2lsbCBiZVxuICogdXNlZC5cbiAqXG4gKiBgYGBcbiAqIHVzZUFuaW1hdGlvbihmYWRlQW5pbWF0aW9uLCB7XG4gKiAgIHBhcmFtczoge1xuICogICAgIHRpbWU6ICcycycsXG4gKiAgICAgc3RhcnQ6IDEsXG4gKiAgICAgZW5kOiAwXG4gKiAgIH1cbiAqIH0pXG4gKiBgYGBcbiAqXG4gKiBJZiBvbmUgb3IgbW9yZSBwYXJhbWV0ZXIgdmFsdWVzIGFyZSBtaXNzaW5nIGJlZm9yZSBhbmltYXRlZCB0aGVuIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5pbWF0aW9uKFxuICAgIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10sXG4gICAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsKTogQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5SZWZlcmVuY2UsIGFuaW1hdGlvbjogc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIGBhbmltYXRlQ2hpbGRgIGlzIGFuIGFuaW1hdGlvbi1zcGVjaWZpYyBmdW5jdGlvbiB0aGF0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgaW5zaWRlIG9mIEFuZ3VsYXInc1xuICogYW5pbWF0aW9uIERTTCBsYW5ndWFnZS4gSXQgd29ya3MgYnkgYWxsb3dpbmcgYSBxdWVyaWVkIGVsZW1lbnQgdG8gZXhlY3V0ZSBpdHMgb3duXG4gKiBhbmltYXRpb24gd2l0aGluIHRoZSBhbmltYXRpb24gc2VxdWVuY2UuXG4gKlxuICogRWFjaCB0aW1lIGFuIGFuaW1hdGlvbiBpcyB0cmlnZ2VyZWQgaW4gYW5ndWxhciwgdGhlIHBhcmVudCBhbmltYXRpb25cbiAqIHdpbGwgYWx3YXlzIGdldCBwcmlvcml0eSBhbmQgYW55IGNoaWxkIGFuaW1hdGlvbnMgd2lsbCBiZSBibG9ja2VkLiBJbiBvcmRlclxuICogZm9yIGEgY2hpbGQgYW5pbWF0aW9uIHRvIHJ1biwgdGhlIHBhcmVudCBhbmltYXRpb24gbXVzdCBxdWVyeSBlYWNoIG9mIHRoZSBlbGVtZW50c1xuICogY29udGFpbmluZyBjaGlsZCBhbmltYXRpb25zIGFuZCB0aGVuIGFsbG93IHRoZSBhbmltYXRpb25zIHRvIHJ1biB1c2luZyBgYW5pbWF0ZUNoaWxkYC5cbiAqXG4gKiBUaGUgZXhhbXBsZSBIVE1MIGNvZGUgYmVsb3cgc2hvd3MgYm90aCBwYXJlbnQgYW5kIGNoaWxkIGVsZW1lbnRzIHRoYXQgaGF2ZSBhbmltYXRpb25cbiAqIHRyaWdnZXJzIHRoYXQgd2lsbCBleGVjdXRlIGF0IHRoZSBzYW1lIHRpbWUuXG4gKlxuICogYGBgaHRtbFxuICogPCEtLSBwYXJlbnQtY2hpbGQuY29tcG9uZW50Lmh0bWwgLS0+XG4gKiA8YnV0dG9uIChjbGljayk9XCJleHAgPSEgZXhwXCI+VG9nZ2xlPC9idXR0b24+XG4gKiA8aHI+XG4gKlxuICogPGRpdiBbQHBhcmVudEFuaW1hdGlvbl09XCJleHBcIj5cbiAqICAgPGhlYWRlcj5IZWxsbzwvaGVhZGVyPlxuICogICA8ZGl2IFtAY2hpbGRBbmltYXRpb25dPVwiZXhwXCI+XG4gKiAgICAgICBvbmVcbiAqICAgPC9kaXY+XG4gKiAgIDxkaXYgW0BjaGlsZEFuaW1hdGlvbl09XCJleHBcIj5cbiAqICAgICAgIHR3b1xuICogICA8L2Rpdj5cbiAqICAgPGRpdiBbQGNoaWxkQW5pbWF0aW9uXT1cImV4cFwiPlxuICogICAgICAgdGhyZWVcbiAqICAgPC9kaXY+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICpcbiAqIE5vdyB3aGVuIHRoZSBgZXhwYCB2YWx1ZSBjaGFuZ2VzIHRvIHRydWUsIG9ubHkgdGhlIGBwYXJlbnRBbmltYXRpb25gIGFuaW1hdGlvbiB3aWxsIGFuaW1hdGVcbiAqIGJlY2F1c2UgaXQgaGFzIHByaW9yaXR5LiBIb3dldmVyLCB1c2luZyBgcXVlcnlgIGFuZCBgYW5pbWF0ZUNoaWxkYCBlYWNoIG9mIHRoZSBpbm5lciBhbmltYXRpb25zXG4gKiBjYW4gYWxzbyBmaXJlOlxuICpcbiAqIGBgYHRzXG4gKiAvLyBwYXJlbnQtY2hpbGQuY29tcG9uZW50LnRzXG4gKiBpbXBvcnQge3RyaWdnZXIsIHRyYW5zaXRpb24sIGFuaW1hdGUsIHN0eWxlLCBxdWVyeSwgYW5pbWF0ZUNoaWxkfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ3BhcmVudC1jaGlsZC1jb21wb25lbnQnLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcigncGFyZW50QW5pbWF0aW9uJywgW1xuICogICAgICAgdHJhbnNpdGlvbignZmFsc2UgPT4gdHJ1ZScsIFtcbiAqICAgICAgICAgcXVlcnkoJ2hlYWRlcicsIFtcbiAqICAgICAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgICAgICAgICAgYW5pbWF0ZSg1MDAsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSlcbiAqICAgICAgICAgXSksXG4gKiAgICAgICAgIHF1ZXJ5KCdAY2hpbGRBbmltYXRpb24nLCBbXG4gKiAgICAgICAgICAgYW5pbWF0ZUNoaWxkKClcbiAqICAgICAgICAgXSlcbiAqICAgICAgIF0pXG4gKiAgICAgXSksXG4gKiAgICAgdHJpZ2dlcignY2hpbGRBbmltYXRpb24nLCBbXG4gKiAgICAgICB0cmFuc2l0aW9uKCdmYWxzZSA9PiB0cnVlJywgW1xuICogICAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgICAgICAgIGFuaW1hdGUoNTAwLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpXG4gKiAgICAgICBdKVxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBQYXJlbnRDaGlsZENtcCB7XG4gKiAgIGV4cDogYm9vbGVhbiA9IGZhbHNlO1xuICogfVxuICogYGBgXG4gKlxuICogSW4gdGhlIGFuaW1hdGlvbiBjb2RlIGFib3ZlLCB3aGVuIHRoZSBgcGFyZW50QW5pbWF0aW9uYCB0cmFuc2l0aW9uIGtpY2tzIG9mZiBpdCBmaXJzdCBxdWVyaWVzIHRvXG4gKiBmaW5kIHRoZSBoZWFkZXIgZWxlbWVudCBhbmQgZmFkZXMgaXQgaW4uIEl0IHRoZW4gZmluZHMgZWFjaCBvZiB0aGUgc3ViIGVsZW1lbnRzIHRoYXQgY29udGFpbiB0aGVcbiAqIGBAY2hpbGRBbmltYXRpb25gIHRyaWdnZXIgYW5kIHRoZW4gYWxsb3dzIGZvciB0aGVpciBhbmltYXRpb25zIHRvIGZpcmUuXG4gKlxuICogVGhpcyBleGFtcGxlIGNhbiBiZSBmdXJ0aGVyIGV4dGVuZGVkIGJ5IHVzaW5nIHN0YWdnZXI6XG4gKlxuICogYGBgdHNcbiAqIHF1ZXJ5KCdAY2hpbGRBbmltYXRpb24nLCBzdGFnZ2VyKDEwMCwgW1xuICogICBhbmltYXRlQ2hpbGQoKVxuICogXSkpXG4gKiBgYGBcbiAqXG4gKiBOb3cgZWFjaCBvZiB0aGUgc3ViIGFuaW1hdGlvbnMgc3RhcnQgb2ZmIHdpdGggcmVzcGVjdCB0byB0aGUgYDEwMG1zYCBzdGFnZ2VyaW5nIHN0ZXAuXG4gKlxuICogIyMgVGhlIGZpcnN0IGZyYW1lIG9mIGNoaWxkIGFuaW1hdGlvbnNcbiAqIFdoZW4gc3ViIGFuaW1hdGlvbnMgYXJlIGV4ZWN1dGVkIHVzaW5nIGBhbmltYXRlQ2hpbGRgIHRoZSBhbmltYXRpb24gZW5naW5lIHdpbGwgYWx3YXlzIGFwcGx5IHRoZVxuICogZmlyc3QgZnJhbWUgb2YgZXZlcnkgc3ViIGFuaW1hdGlvbiBpbW1lZGlhdGVseSBhdCB0aGUgc3RhcnQgb2YgdGhlIGFuaW1hdGlvbiBzZXF1ZW5jZS4gVGhpcyB3YXlcbiAqIHRoZSBwYXJlbnQgYW5pbWF0aW9uIGRvZXMgbm90IG5lZWQgdG8gc2V0IGFueSBpbml0aWFsIHN0eWxpbmcgZGF0YSBvbiB0aGUgc3ViIGVsZW1lbnRzIGJlZm9yZSB0aGVcbiAqIHN1YiBhbmltYXRpb25zIGtpY2sgb2ZmLlxuICpcbiAqIEluIHRoZSBleGFtcGxlIGFib3ZlIHRoZSBmaXJzdCBmcmFtZSBvZiB0aGUgYGNoaWxkQW5pbWF0aW9uYCdzIGBmYWxzZSA9PiB0cnVlYCB0cmFuc2l0aW9uXG4gKiBjb25zaXN0cyBvZiBhIHN0eWxlIG9mIGBvcGFjaXR5OiAwYC4gVGhpcyBpcyBhcHBsaWVkIGltbWVkaWF0ZWx5IHdoZW4gdGhlIGBwYXJlbnRBbmltYXRpb25gXG4gKiBhbmltYXRpb24gdHJhbnNpdGlvbiBzZXF1ZW5jZSBzdGFydHMuIE9ubHkgdGhlbiB3aGVuIHRoZSBgQGNoaWxkQW5pbWF0aW9uYCBpcyBxdWVyaWVkIGFuZCBjYWxsZWRcbiAqIHdpdGggYGFuaW1hdGVDaGlsZGAgd2lsbCBpdCB0aGVuIGFuaW1hdGUgdG8gaXRzIGRlc3RpbmF0aW9uIG9mIGBvcGFjaXR5OiAxYC5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBmZWF0dXJlIGRlc2lnbmVkIHRvIGJlIHVzZWQgYWxvbmdzaWRlIHtAbGluayBxdWVyeSBxdWVyeSgpfSBhbmQgaXQgd2lsbCBvbmx5IHdvcmtcbiAqIHdpdGggYW5pbWF0aW9ucyB0aGF0IGFyZSBhc3NpZ25lZCB1c2luZyB0aGUgQW5ndWxhciBhbmltYXRpb24gRFNMICh0aGlzIG1lYW5zIHRoYXQgQ1NTIGtleWZyYW1lc1xuICogYW5kIHRyYW5zaXRpb25zIGFyZSBub3QgaGFuZGxlZCBieSB0aGlzIEFQSSkuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmltYXRlQ2hpbGQob3B0aW9uczogQW5pbWF0ZUNoaWxkT3B0aW9ucyB8IG51bGwgPSBudWxsKTpcbiAgICBBbmltYXRpb25BbmltYXRlQ2hpbGRNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLkFuaW1hdGVDaGlsZCwgb3B0aW9uc307XG59XG5cbi8qKlxuICogYHVzZUFuaW1hdGlvbmAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJdCBpcyB1c2VkIHRvIGtpY2sgb2ZmIGEgcmV1c2FibGUgYW5pbWF0aW9uIHRoYXQgaXMgY3JlYXRlZCB1c2luZyB7QGxpbmtcbiAqIGFuaW1hdGlvbiBhbmltYXRpb24oKX0uXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VBbmltYXRpb24oXG4gICAgYW5pbWF0aW9uOiBBbmltYXRpb25SZWZlcmVuY2VNZXRhZGF0YSxcbiAgICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25BbmltYXRlUmVmTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5BbmltYXRlUmVmLCBhbmltYXRpb24sIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIGBxdWVyeWAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLlxuICpcbiAqIHF1ZXJ5KCkgaXMgdXNlZCB0byBmaW5kIG9uZSBvciBtb3JlIGlubmVyIGVsZW1lbnRzIHdpdGhpbiB0aGUgY3VycmVudCBlbGVtZW50IHRoYXQgaXNcbiAqIGJlaW5nIGFuaW1hdGVkIHdpdGhpbiB0aGUgc2VxdWVuY2UuIFRoZSBwcm92aWRlZCBhbmltYXRpb24gc3RlcHMgYXJlIGFwcGxpZWRcbiAqIHRvIHRoZSBxdWVyaWVkIGVsZW1lbnQgKGJ5IGRlZmF1bHQsIGFuIGFycmF5IGlzIHByb3ZpZGVkLCB0aGVuIHRoaXMgd2lsbCBiZVxuICogdHJlYXRlZCBhcyBhbiBhbmltYXRpb24gc2VxdWVuY2UpLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIHF1ZXJ5KCkgaXMgZGVzaWduZWQgdG8gY29sbGVjdCBtdWx0aXBsZSBlbGVtZW50cyBhbmQgd29ya3MgaW50ZXJuYWxseSBieSB1c2luZ1xuICogYGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbGAuIEFuIGFkZGl0aW9uYWwgb3B0aW9ucyBvYmplY3QgY2FuIGJlIHByb3ZpZGVkIHdoaWNoXG4gKiBjYW4gYmUgdXNlZCB0byBsaW1pdCB0aGUgdG90YWwgYW1vdW50IG9mIGl0ZW1zIHRvIGJlIGNvbGxlY3RlZC5cbiAqXG4gKiBgYGBqc1xuICogcXVlcnkoJ2RpdicsIFtcbiAqICAgYW5pbWF0ZSguLi4pLFxuICogICBhbmltYXRlKC4uLilcbiAqIF0sIHsgbGltaXQ6IDEgfSlcbiAqIGBgYFxuICpcbiAqIHF1ZXJ5KCksIGJ5IGRlZmF1bHQsIHdpbGwgdGhyb3cgYW4gZXJyb3Igd2hlbiB6ZXJvIGl0ZW1zIGFyZSBmb3VuZC4gSWYgYSBxdWVyeVxuICogaGFzIHRoZSBgb3B0aW9uYWxgIGZsYWcgc2V0IHRvIHRydWUgdGhlbiB0aGlzIGVycm9yIHdpbGwgYmUgaWdub3JlZC5cbiAqXG4gKiBgYGBqc1xuICogcXVlcnkoJy5zb21lLWVsZW1lbnQtdGhhdC1tYXktbm90LWJlLXRoZXJlJywgW1xuICogICBhbmltYXRlKC4uLiksXG4gKiAgIGFuaW1hdGUoLi4uKVxuICogXSwgeyBvcHRpb25hbDogdHJ1ZSB9KVxuICogYGBgXG4gKlxuICogIyMjIFNwZWNpYWwgU2VsZWN0b3IgVmFsdWVzXG4gKlxuICogVGhlIHNlbGVjdG9yIHZhbHVlIHdpdGhpbiBhIHF1ZXJ5IGNhbiBjb2xsZWN0IGVsZW1lbnRzIHRoYXQgY29udGFpbiBhbmd1bGFyLXNwZWNpZmljXG4gKiBjaGFyYWN0ZXJpc3RpY3NcbiAqIHVzaW5nIHNwZWNpYWwgcHNldWRvLXNlbGVjdG9ycyB0b2tlbnMuXG4gKlxuICogVGhlc2UgaW5jbHVkZTpcbiAqXG4gKiAgLSBRdWVyeWluZyBmb3IgbmV3bHkgaW5zZXJ0ZWQvcmVtb3ZlZCBlbGVtZW50cyB1c2luZyBgcXVlcnkoXCI6ZW50ZXJcIilgL2BxdWVyeShcIjpsZWF2ZVwiKWBcbiAqICAtIFF1ZXJ5aW5nIGFsbCBjdXJyZW50bHkgYW5pbWF0aW5nIGVsZW1lbnRzIHVzaW5nIGBxdWVyeShcIjphbmltYXRpbmdcIilgXG4gKiAgLSBRdWVyeWluZyBlbGVtZW50cyB0aGF0IGNvbnRhaW4gYW4gYW5pbWF0aW9uIHRyaWdnZXIgdXNpbmcgYHF1ZXJ5KFwiQHRyaWdnZXJOYW1lXCIpYFxuICogIC0gUXVlcnlpbmcgYWxsIGVsZW1lbnRzIHRoYXQgY29udGFpbiBhbiBhbmltYXRpb24gdHJpZ2dlcnMgdXNpbmcgYHF1ZXJ5KFwiQCpcIilgXG4gKiAgLSBJbmNsdWRpbmcgdGhlIGN1cnJlbnQgZWxlbWVudCBpbnRvIHRoZSBhbmltYXRpb24gc2VxdWVuY2UgdXNpbmcgYHF1ZXJ5KFwiOnNlbGZcIilgXG4gKlxuICpcbiAqICBFYWNoIG9mIHRoZXNlIHBzZXVkby1zZWxlY3RvciB0b2tlbnMgY2FuIGJlIG1lcmdlZCB0b2dldGhlciBpbnRvIGEgY29tYmluZWQgcXVlcnkgc2VsZWN0b3JcbiAqIHN0cmluZzpcbiAqXG4gKiAgYGBgXG4gKiAgcXVlcnkoJzpzZWxmLCAucmVjb3JkOmVudGVyLCAucmVjb3JkOmxlYXZlLCBAc3ViVHJpZ2dlcicsIFsuLi5dKVxuICogIGBgYFxuICpcbiAqICMjIyBEZW1vXG4gKlxuICogYGBgXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdpbm5lcicsXG4gKiAgIHRlbXBsYXRlOiBgXG4gKiAgICAgPGRpdiBbQHF1ZXJ5QW5pbWF0aW9uXT1cImV4cFwiPlxuICogICAgICAgPGgxPlRpdGxlPC9oMT5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50XCI+XG4gKiAgICAgICAgIEJsYWggYmxhaCBibGFoXG4gKiAgICAgICA8L2Rpdj5cbiAqICAgICA8L2Rpdj5cbiAqICAgYCxcbiAqICAgYW5pbWF0aW9uczogW1xuICogICAgdHJpZ2dlcigncXVlcnlBbmltYXRpb24nLCBbXG4gKiAgICAgIHRyYW5zaXRpb24oJyogPT4gZ29BbmltYXRlJywgW1xuICogICAgICAgIC8vIGhpZGUgdGhlIGlubmVyIGVsZW1lbnRzXG4gKiAgICAgICAgcXVlcnkoJ2gxJywgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKSxcbiAqICAgICAgICBxdWVyeSgnLmNvbnRlbnQnLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpLFxuICpcbiAqICAgICAgICAvLyBhbmltYXRlIHRoZSBpbm5lciBlbGVtZW50cyBpbiwgb25lIGJ5IG9uZVxuICogICAgICAgIHF1ZXJ5KCdoMScsIGFuaW1hdGUoMTAwMCwgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKSxcbiAqICAgICAgICBxdWVyeSgnLmNvbnRlbnQnLCBhbmltYXRlKDEwMDAsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSksXG4gKiAgICAgIF0pXG4gKiAgICBdKVxuICogIF1cbiAqIH0pXG4gKiBjbGFzcyBDbXAge1xuICogICBleHAgPSAnJztcbiAqXG4gKiAgIGdvQW5pbWF0ZSgpIHtcbiAqICAgICB0aGlzLmV4cCA9ICdnb0FuaW1hdGUnO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAZXhwZXJpbWVudGFsIEFuaW1hdGlvbiBzdXBwb3J0IGlzIGV4cGVyaW1lbnRhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHF1ZXJ5KFxuICAgIHNlbGVjdG9yOiBzdHJpbmcsIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGEgfCBBbmltYXRpb25NZXRhZGF0YVtdLFxuICAgIG9wdGlvbnM6IEFuaW1hdGlvblF1ZXJ5T3B0aW9ucyB8IG51bGwgPSBudWxsKTogQW5pbWF0aW9uUXVlcnlNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlF1ZXJ5LCBzZWxlY3RvciwgYW5pbWF0aW9uLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBgc3RhZ2dlcmAgaXMgYW4gYW5pbWF0aW9uLXNwZWNpZmljIGZ1bmN0aW9uIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBpbnNpZGUgb2YgQW5ndWxhcidzXG4gKiBhbmltYXRpb24gRFNMIGxhbmd1YWdlLiBJdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGluc2lkZSBvZiBhbiBhbmltYXRpb24ge0BsaW5rIHF1ZXJ5IHF1ZXJ5KCl9XG4gKiBhbmQgd29ya3MgYnkgaXNzdWluZyBhIHRpbWluZyBnYXAgYmV0d2VlbiBhZnRlciBlYWNoIHF1ZXJpZWQgaXRlbSBpcyBhbmltYXRlZC5cbiAqXG4gKiAjIyMgVXNhZ2VcbiAqXG4gKiBJbiB0aGUgZXhhbXBsZSBiZWxvdyB0aGVyZSBpcyBhIGNvbnRhaW5lciBlbGVtZW50IHRoYXQgd3JhcHMgYSBsaXN0IG9mIGl0ZW1zIHN0YW1wZWQgb3V0XG4gKiBieSBhbiBuZ0Zvci4gVGhlIGNvbnRhaW5lciBlbGVtZW50IGNvbnRhaW5zIGFuIGFuaW1hdGlvbiB0cmlnZ2VyIHRoYXQgd2lsbCBsYXRlciBiZSBzZXRcbiAqIHRvIHF1ZXJ5IGZvciBlYWNoIG9mIHRoZSBpbm5lciBpdGVtcy5cbiAqXG4gKiBgYGBodG1sXG4gKiA8IS0tIGxpc3QuY29tcG9uZW50Lmh0bWwgLS0+XG4gKiA8YnV0dG9uIChjbGljayk9XCJ0b2dnbGUoKVwiPlNob3cgLyBIaWRlIEl0ZW1zPC9idXR0b24+XG4gKiA8aHIgLz5cbiAqIDxkaXYgW0BsaXN0QW5pbWF0aW9uXT1cIml0ZW1zLmxlbmd0aFwiPlxuICogICA8ZGl2ICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zXCI+XG4gKiAgICAge3sgaXRlbSB9fVxuICogICA8L2Rpdj5cbiAqIDwvZGl2PlxuICogYGBgXG4gKlxuICogVGhlIGNvbXBvbmVudCBjb2RlIGZvciB0aGlzIGxvb2tzIGFzIHN1Y2g6XG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7dHJpZ2dlciwgdHJhbnNpdGlvbiwgc3R5bGUsIGFuaW1hdGUsIHF1ZXJ5LCBzdGFnZ2VyfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbiAqIEBDb21wb25lbnQoe1xuICogICB0ZW1wbGF0ZVVybDogJ2xpc3QuY29tcG9uZW50Lmh0bWwnLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcignbGlzdEFuaW1hdGlvbicsIFtcbiAqICAgICAgICAvLy4uLlxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBMaXN0Q29tcG9uZW50IHtcbiAqICAgaXRlbXMgPSBbXTtcbiAqXG4gKiAgIHNob3dJdGVtcygpIHtcbiAqICAgICB0aGlzLml0ZW1zID0gWzAsMSwyLDMsNF07XG4gKiAgIH1cbiAqXG4gKiAgIGhpZGVJdGVtcygpIHtcbiAqICAgICB0aGlzLml0ZW1zID0gW107XG4gKiAgIH1cbiAqXG4gKiAgIHRvZ2dsZSgpIHtcbiAqICAgICB0aGlzLml0ZW1zLmxlbmd0aCA/IHRoaXMuaGlkZUl0ZW1zKCkgOiB0aGlzLnNob3dJdGVtcygpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBBbmQgbm93IGZvciB0aGUgYW5pbWF0aW9uIHRyaWdnZXIgY29kZTpcbiAqXG4gKiBgYGB0c1xuICogdHJpZ2dlcignbGlzdEFuaW1hdGlvbicsIFtcbiAqICAgdHJhbnNpdGlvbignKiA9PiAqJywgWyAvLyBlYWNoIHRpbWUgdGhlIGJpbmRpbmcgdmFsdWUgY2hhbmdlc1xuICogICAgIHF1ZXJ5KCc6bGVhdmUnLCBbXG4gKiAgICAgICBzdGFnZ2VyKDEwMCwgW1xuICogICAgICAgICBhbmltYXRlKCcwLjVzJywgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKVxuICogICAgICAgXSlcbiAqICAgICBdKSxcbiAqICAgICBxdWVyeSgnOmVudGVyJywgW1xuICogICAgICAgc3R5bGUoeyBvcGFjaXR5OiAwIH0pLFxuICogICAgICAgc3RhZ2dlcigxMDAsIFtcbiAqICAgICAgICAgYW5pbWF0ZSgnMC41cycsIHN0eWxlKHsgb3BhY2l0eTogMSB9KSlcbiAqICAgICAgIF0pXG4gKiAgICAgXSlcbiAqICAgXSlcbiAqIF0pXG4gKiBgYGBcbiAqXG4gKiBOb3cgZWFjaCB0aW1lIHRoZSBpdGVtcyBhcmUgYWRkZWQvcmVtb3ZlZCB0aGVuIGVpdGhlciB0aGUgb3BhY2l0eVxuICogZmFkZS1pbiBhbmltYXRpb24gd2lsbCBydW4gb3IgZWFjaCByZW1vdmVkIGl0ZW0gd2lsbCBiZSBmYWRlZCBvdXQuXG4gKiBXaGVuIGVpdGhlciBvZiB0aGVzZSBhbmltYXRpb25zIG9jY3VyIHRoZW4gYSBzdGFnZ2VyIGVmZmVjdCB3aWxsIGJlXG4gKiBhcHBsaWVkIGFmdGVyIGVhY2ggaXRlbSdzIGFuaW1hdGlvbiBpcyBzdGFydGVkLlxuICpcbiAqIEBleHBlcmltZW50YWwgQW5pbWF0aW9uIHN1cHBvcnQgaXMgZXhwZXJpbWVudGFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhZ2dlcihcbiAgICB0aW1pbmdzOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10pOiBBbmltYXRpb25TdGFnZ2VyTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdGFnZ2VyLCB0aW1pbmdzLCBhbmltYXRpb259O1xufVxuIl19
|
|
831
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uX21ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5pbWF0aW9ucy9zcmMvYW5pbWF0aW9uX21ldGFkYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQW1KSDs7R0FFRztBQUNILE1BQU0sQ0FBQyxJQUFNLFVBQVUsR0FBRyxHQUFHLENBQUM7QUF5UDlCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtSkc7QUFDSCxNQUFNLGtCQUFrQixJQUFZLEVBQUUsV0FBZ0M7SUFDcEUsTUFBTSxDQUFDLEVBQUMsSUFBSSxpQkFBK0IsRUFBRSxJQUFJLE1BQUEsRUFBRSxXQUFXLGFBQUEsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdURHO0FBQ0gsTUFBTSxrQkFDRixPQUF3QixFQUFFLE1BQ1g7SUFEVyx1QkFBQSxFQUFBLGFBQ1g7SUFDakIsTUFBTSxDQUFDLEVBQUMsSUFBSSxpQkFBK0IsRUFBRSxNQUFNLFFBQUEsRUFBRSxPQUFPLFNBQUEsRUFBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEJHO0FBQ0gsTUFBTSxnQkFDRixLQUEwQixFQUFFLE9BQXVDO0lBQXZDLHdCQUFBLEVBQUEsY0FBdUM7SUFDckUsTUFBTSxDQUFDLEVBQUMsSUFBSSxlQUE2QixFQUFFLEtBQUssT0FBQSxFQUFFLE9BQU8sU0FBQSxFQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUE4Qkk7QUFDSixNQUFNLG1CQUFtQixLQUEwQixFQUFFLE9BQXVDO0lBQXZDLHdCQUFBLEVBQUEsY0FBdUM7SUFFMUYsTUFBTSxDQUFDLEVBQUMsSUFBSSxrQkFBZ0MsRUFBRSxLQUFLLE9BQUEsRUFBRSxPQUFPLFNBQUEsRUFBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXFDSTtBQUNKLE1BQU0sZ0JBQ0YsTUFDMkM7SUFDN0MsTUFBTSxDQUFDLEVBQUMsSUFBSSxlQUE2QixFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBQyxDQUFDO0FBQzNFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUEwQkk7QUFDSixNQUFNLGdCQUNGLElBQVksRUFBRSxNQUE4QixFQUM1QyxPQUF5QztJQUMzQyxNQUFNLENBQUMsRUFBQyxJQUFJLGVBQTZCLEVBQUUsSUFBSSxNQUFBLEVBQUUsTUFBTSxRQUFBLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBDRztBQUNILE1BQU0sb0JBQW9CLEtBQStCO0lBQ3ZELE1BQU0sQ0FBQyxFQUFDLElBQUksbUJBQWlDLEVBQUUsS0FBSyxPQUFBLEVBQUMsQ0FBQztBQUN4RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXFLSTtBQUNKLE1BQU0scUJBQ0YsZUFDc0UsRUFDdEUsS0FBOEMsRUFDOUMsT0FBdUM7SUFBdkMsd0JBQUEsRUFBQSxjQUF1QztJQUN6QyxNQUFNLENBQUMsRUFBQyxJQUFJLG9CQUFrQyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxPQUFPLFNBQUEsRUFBQyxDQUFDO0FBQ3BHLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMENHO0FBQ0gsTUFBTSxvQkFDRixLQUE4QyxFQUM5QyxPQUF1QztJQUF2Qyx3QkFBQSxFQUFBLGNBQXVDO0lBQ3pDLE1BQU0sQ0FBQyxFQUFDLElBQUksbUJBQWlDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxPQUFPLFNBQUEsRUFBQyxDQUFDO0FBQzVFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sdUJBQXVCLE9BQTBDO0lBQTFDLHdCQUFBLEVBQUEsY0FBMEM7SUFFckUsTUFBTSxDQUFDLEVBQUMsSUFBSSxzQkFBb0MsRUFBRSxPQUFPLFNBQUEsRUFBQyxDQUFDO0FBQzdELENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSx1QkFDRixTQUFxQyxFQUNyQyxPQUF1QztJQUF2Qyx3QkFBQSxFQUFBLGNBQXVDO0lBQ3pDLE1BQU0sQ0FBQyxFQUFDLElBQUkscUJBQWtDLEVBQUUsU0FBUyxXQUFBLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztBQUN0RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9GRztBQUNILE1BQU0sZ0JBQ0YsUUFBZ0IsRUFBRSxTQUFrRCxFQUNwRSxPQUE0QztJQUE1Qyx3QkFBQSxFQUFBLGNBQTRDO0lBQzlDLE1BQU0sQ0FBQyxFQUFDLElBQUksZ0JBQTZCLEVBQUUsUUFBUSxVQUFBLEVBQUUsU0FBUyxXQUFBLEVBQUUsT0FBTyxTQUFBLEVBQUMsQ0FBQztBQUMzRSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkVHO0FBQ0gsTUFBTSxrQkFDRixPQUF3QixFQUN4QixTQUFrRDtJQUNwRCxNQUFNLENBQUMsRUFBQyxJQUFJLGtCQUErQixFQUFFLE9BQU8sU0FBQSxFQUFFLFNBQVMsV0FBQSxFQUFDLENBQUM7QUFDbkUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgc2V0IG9mIENTUyBzdHlsZXMgZm9yIHVzZSBpbiBhbiBhbmltYXRpb24gc3R5bGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgybVTdHlsZURhdGEgeyBba2V5OiBzdHJpbmddOiBzdHJpbmd8bnVtYmVyOyB9XG5cbi8qKlxuKiBSZXByZXNlbnRzIGFuaW1hdGlvbi1zdGVwIHRpbWluZyBwYXJhbWV0ZXJzIGZvciBhbiBhbmltYXRpb24gc3RlcC4gIFxuKiBAc2VlIGBhbmltYXRlKClgXG4qL1xuZXhwb3J0IGRlY2xhcmUgdHlwZSBBbmltYXRlVGltaW5ncyA9IHtcbiAgLyoqXG4gICAqIFRoZSBmdWxsIGR1cmF0aW9uIG9mIGFuIGFuaW1hdGlvbiBzdGVwLiBBIG51bWJlciBhbmQgb3B0aW9uYWwgdGltZSB1bml0LFxuICAgKiBzdWNoIGFzIFwiMXNcIiBvciBcIjEwbXNcIiBmb3Igb25lIHNlY29uZCBhbmQgMTAgbWlsbGlzZWNvbmRzLCByZXNwZWN0aXZlbHkuXG4gICAqIFRoZSBkZWZhdWx0IHVuaXQgaXMgbWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgZHVyYXRpb246IG51bWJlcixcbiAgLyoqXG4gICAqIFRoZSBkZWxheSBpbiBhcHBseWluZyBhbiBhbmltYXRpb24gc3RlcC4gQSBudW1iZXIgYW5kIG9wdGlvbmFsIHRpbWUgdW5pdC5cbiAgICogVGhlIGRlZmF1bHQgdW5pdCBpcyBtaWxsaXNlY29uZHMuXG4gICAqL1xuICBkZWxheTogbnVtYmVyLFxuICAvKipcbiAgICogQW4gZWFzaW5nIHN0eWxlIHRoYXQgY29udHJvbHMgaG93IGFuIGFuaW1hdGlvbnMgc3RlcCBhY2NlbGVyYXRlc1xuICAgKiBhbmQgZGVjZWxlcmF0ZXMgZHVyaW5nIGl0cyBydW4gdGltZS4gQW4gZWFzaW5nIGZ1bmN0aW9uIHN1Y2ggYXMgYGN1YmljLWJlemllcigpYCxcbiAgICogb3Igb25lIG9mIHRoZSBmb2xsb3dpbmcgY29uc3RhbnRzOlxuICAgKiAtIGBlYXNlLWluYFxuICAgKiAtIGBlYXNlLW91dGBcbiAgICogLSBgZWFzZS1pbi1hbmQtb3V0YFxuICAgKi9cbiAgZWFzaW5nOiBzdHJpbmcgfCBudWxsXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBPcHRpb25zIHRoYXQgY29udHJvbCBhbmltYXRpb24gc3R5bGluZyBhbmQgdGltaW5nLlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgYW5pbWF0aW9uIGZ1bmN0aW9ucyBhY2NlcHQgYEFuaW1hdGlvbk9wdGlvbnNgIGRhdGE6XG4gKlxuICogLSBgdHJhbnNpdGlvbigpYFxuICogLSBgc2VxdWVuY2UoKWBcbiAqIC0gYHtAbGluayBhbmltYXRpb25zL2dyb3VwIGdyb3VwKCl9YFxuICogLSBgcXVlcnkoKWBcbiAqIC0gYGFuaW1hdGlvbigpYFxuICogLSBgdXNlQW5pbWF0aW9uKClgXG4gKiAtIGBhbmltYXRlQ2hpbGQoKWBcbiAqXG4gKiBQcm9ncmFtbWF0aWMgYW5pbWF0aW9ucyBidWlsdCB1c2luZyB0aGUgYEFuaW1hdGlvbkJ1aWxkZXJgIHNlcnZpY2UgYWxzb1xuICogbWFrZSB1c2Ugb2YgYEFuaW1hdGlvbk9wdGlvbnNgLlxuICovXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgQW5pbWF0aW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBTZXRzIGEgdGltZS1kZWxheSBmb3IgaW5pdGlhdGluZyBhbiBhbmltYXRpb24gYWN0aW9uLlxuICAgKiBBIG51bWJlciBhbmQgb3B0aW9uYWwgdGltZSB1bml0LCBzdWNoIGFzIFwiMXNcIiBvciBcIjEwbXNcIiBmb3Igb25lIHNlY29uZFxuICAgKiBhbmQgMTAgbWlsbGlzZWNvbmRzLCByZXNwZWN0aXZlbHkuVGhlIGRlZmF1bHQgdW5pdCBpcyBtaWxsaXNlY29uZHMuXG4gICAqIERlZmF1bHQgdmFsdWUgaXMgMCwgbWVhbmluZyBubyBkZWxheS5cbiAgICovXG4gIGRlbGF5PzogbnVtYmVyfHN0cmluZztcbiAgLyoqXG4gICogQSBzZXQgb2YgZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IG1vZGlmeSBzdHlsaW5nIGFuZCB0aW1pbmdcbiAgKiB3aGVuIGFuIGFuaW1hdGlvbiBhY3Rpb24gc3RhcnRzLiBBbiBhcnJheSBvZiBrZXktdmFsdWUgcGFpcnMsIHdoZXJlIHRoZSBwcm92aWRlZCB2YWx1ZVxuICAqIGlzIHVzZWQgYXMgYSBkZWZhdWx0LlxuICAqL1xuICBwYXJhbXM/OiB7W25hbWU6IHN0cmluZ106IGFueX07XG59XG5cbi8qKlxuICogQWRkcyBkdXJhdGlvbiBvcHRpb25zIHRvIGNvbnRyb2wgYW5pbWF0aW9uIHN0eWxpbmcgYW5kIHRpbWluZyBmb3IgYSBjaGlsZCBhbmltYXRpb24uXG4gKlxuICogQHNlZSBgYW5pbWF0ZUNoaWxkKClgXG4gKi9cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBBbmltYXRlQ2hpbGRPcHRpb25zIGV4dGVuZHMgQW5pbWF0aW9uT3B0aW9ucyB7IGR1cmF0aW9uPzogbnVtYmVyfHN0cmluZzsgfVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb25zdGFudHMgZm9yIHRoZSBjYXRlZ29yaWVzIG9mIHBhcmFtZXRlcnMgdGhhdCBjYW4gYmUgZGVmaW5lZCBmb3IgYW5pbWF0aW9ucy5cbiAqXG4gKiBBIGNvcnJlc3BvbmRpbmcgZnVuY3Rpb24gZGVmaW5lcyBhIHNldCBvZiBwYXJhbWV0ZXJzIGZvciBlYWNoIGNhdGVnb3J5LCBhbmRcbiAqIGNvbGxlY3RzIHRoZW0gaW50byBhIGNvcnJlc3BvbmRpbmcgYEFuaW1hdGlvbk1ldGFkYXRhYCBvYmplY3QuXG4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIEFuaW1hdGlvbk1ldGFkYXRhVHlwZSB7XG4gIC8qKlxuICAgKiBBc3NvY2lhdGVzIGEgbmFtZWQgYW5pbWF0aW9uIHN0YXRlIHdpdGggYSBzZXQgb2YgQ1NTIHN0eWxlcy5cbiAgICogU2VlIGBzdGF0ZSgpYFxuICAgKi9cbiAgU3RhdGUgPSAwLFxuICAvKipcbiAgICogRGF0YSBmb3IgYSB0cmFuc2l0aW9uIGZyb20gb25lIGFuaW1hdGlvbiBzdGF0ZSB0byBhbm90aGVyLlxuICAgKiBTZWUgYHRyYW5zaXRpb24oKWBcbiAgICovXG4gIFRyYW5zaXRpb24gPSAxLFxuICAvKipcbiAgICogQ29udGFpbnMgYSBzZXQgb2YgYW5pbWF0aW9uIHN0ZXBzLlxuICAgKiBTZWUgYHNlcXVlbmNlKClgXG4gICAqL1xuICBTZXF1ZW5jZSA9IDIsXG4gIC8qKlxuICAgKiBDb250YWlucyBhIHNldCBvZiBhbmltYXRpb24gc3RlcHMuXG4gICAqIFNlZSBge0BsaW5rIGFuaW1hdGlvbnMvZ3JvdXAgZ3JvdXAoKX1gXG4gICAqL1xuICBHcm91cCA9IDMsXG4gIC8qKlxuICAgKiBDb250YWlucyBhbiBhbmltYXRpb24gc3RlcC5cbiAgICogU2VlIGBhbmltYXRlKClgXG4gICAqL1xuICBBbmltYXRlID0gNCxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgc2V0IG9mIGFuaW1hdGlvbiBzdGVwcy5cbiAgICogU2VlIGBrZXlmcmFtZXMoKWBcbiAgICovXG4gIEtleWZyYW1lcyA9IDUsXG4gIC8qKlxuICAgKiBDb250YWlucyBhIHNldCBvZiBDU1MgcHJvcGVydHktdmFsdWUgcGFpcnMgaW50byBhIG5hbWVkIHN0eWxlLlxuICAgKiBTZWUgYHN0eWxlKClgXG4gICAqL1xuICBTdHlsZSA9IDYsXG4gIC8qKlxuICAgKiBBc3NvY2lhdGVzIGFuIGFuaW1hdGlvbiB3aXRoIGFuIGVudHJ5IHRyaWdnZXIgdGhhdCBjYW4gYmUgYXR0YWNoZWQgdG8gYW4gZWxlbWVudC5cbiAgICogU2VlIGB0cmlnZ2VyKClgXG4gICAqL1xuICBUcmlnZ2VyID0gNyxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgcmUtdXNhYmxlIGFuaW1hdGlvbi5cbiAgICogU2VlIGBhbmltYXRpb24oKWBcbiAgICovXG4gIFJlZmVyZW5jZSA9IDgsXG4gIC8qKlxuICAgKiBDb250YWlucyBkYXRhIHRvIHVzZSBpbiBleGVjdXRpbmcgY2hpbGQgYW5pbWF0aW9ucyByZXR1cm5lZCBieSBhIHF1ZXJ5LlxuICAgKiBTZWUgYGFuaW1hdGVDaGlsZCgpYFxuICAgKi9cbiAgQW5pbWF0ZUNoaWxkID0gOSxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGFuaW1hdGlvbiBwYXJhbWV0ZXJzIGZvciBhIHJlLXVzYWJsZSBhbmltYXRpb24uXG4gICAqIFNlZSBgdXNlQW5pbWF0aW9uKClgXG4gICAqL1xuICBBbmltYXRlUmVmID0gMTAsXG4gIC8qKlxuICAgKiBDb250YWlucyBjaGlsZC1hbmltYXRpb24gcXVlcnkgZGF0YS5cbiAgICogU2VlIGBxdWVyeSgpYFxuICAgKi9cbiAgUXVlcnkgPSAxMSxcbiAgLyoqXG4gICAqIENvbnRhaW5zIGRhdGEgZm9yIHN0YWdnZXJpbmcgYW4gYW5pbWF0aW9uIHNlcXVlbmNlLlxuICAgKiBTZWUgYHN0YWdnZXIoKWBcbiAgICovXG4gIFN0YWdnZXIgPSAxMlxufVxuXG4vKipcbiAqIFNwZWNpZmllcyBhdXRvbWF0aWMgc3R5bGluZy5cbiAqL1xuZXhwb3J0IGNvbnN0IEFVVE9fU1RZTEUgPSAnKic7XG5cbi8qKlxuICogQmFzZSBmb3IgYW5pbWF0aW9uIGRhdGEgc3RydWN0dXJlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25NZXRhZGF0YSB7IHR5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZTsgfVxuXG4vKipcbiAqIENvbnRhaW5zIGFuIGFuaW1hdGlvbiB0cmlnZ2VyLiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZVxuICogYHRyaWdnZXIoKWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uVHJpZ2dlck1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICAqIFRoZSB0cmlnZ2VyIG5hbWUsIHVzZWQgdG8gYXNzb2NpYXRlIGl0IHdpdGggYW4gZWxlbWVudC4gVW5pcXVlIHdpdGhpbiB0aGUgY29tcG9uZW50LlxuICAgICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEFuIGFuaW1hdGlvbiBkZWZpbml0aW9uIG9iamVjdCwgY29udGFpbmluZyBhbiBhcnJheSBvZiBzdGF0ZSBhbmQgdHJhbnNpdGlvbiBkZWNsYXJhdGlvbnMuXG4gICAqL1xuICBkZWZpbml0aW9uczogQW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAgICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAgICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi4gRGVmYXVsdCBkZWxheSBpcyAwLlxuICAgKi9cbiAgb3B0aW9uczoge3BhcmFtcz86IHtbbmFtZTogc3RyaW5nXTogYW55fX18bnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIHN0YXRlIGJ5IGFzc29jaWF0aW5nIGEgc3RhdGUgbmFtZSB3aXRoIGEgc2V0IG9mIENTUyBzdHlsZXMuXG4gKiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5IHRoZSBgc3RhdGUoKWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uU3RhdGVNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIFRoZSBzdGF0ZSBuYW1lLCB1bmlxdWUgd2l0aGluIHRoZSBjb21wb25lbnQuXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiAgVGhlIENTUyBzdHlsZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3RhdGUuXG4gICAqL1xuICBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGE7XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uXG4gICAqL1xuICBvcHRpb25zPzoge3BhcmFtczoge1tuYW1lOiBzdHJpbmddOiBhbnl9fTtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIHRyYW5zaXRpb24uIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnkgdGhlXG4gKiBgdHJhbnNpdGlvbigpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25UcmFuc2l0aW9uTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBBbiBleHByZXNzaW9uIHRoYXQgZGVzY3JpYmVzIGEgc3RhdGUgY2hhbmdlLlxuICAgKi9cbiAgZXhwcjogc3RyaW5nfFxuICAgICAgKChmcm9tU3RhdGU6IHN0cmluZywgdG9TdGF0ZTogc3RyaW5nLCBlbGVtZW50PzogYW55LFxuICAgICAgICBwYXJhbXM/OiB7W2tleTogc3RyaW5nXTogYW55fSkgPT4gYm9vbGVhbik7XG4gIC8qKlxuICAgKiBPbmUgb3IgbW9yZSBhbmltYXRpb24gb2JqZWN0cyB0byB3aGljaCB0aGlzIHRyYW5zaXRpb24gYXBwbGllcy5cbiAgICovXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGF8QW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAgICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAgICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi4gRGVmYXVsdCBkZWxheSBpcyAwLlxuICAgKi9cbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhIHJldXNhYmxlIGFuaW1hdGlvbiwgd2hpY2ggaXMgYSBjb2xsZWN0aW9uIG9mIGluZGl2aWR1YWwgYW5pbWF0aW9uIHN0ZXBzLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYGFuaW1hdGlvbigpYCBmdW5jdGlvbiwgYW5kXG4gKiBwYXNzZWQgdG8gdGhlIGB1c2VBbmltYXRpb24oKWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiAgT25lIG9yIG1vcmUgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAgICovXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGF8QW5pbWF0aW9uTWV0YWRhdGFbXTtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAgICogZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycyB0aGF0IHByb3ZpZGUgc3R5bGluZyBkZWZhdWx0cyBhbmRcbiAgICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi4gRGVmYXVsdCBkZWxheSBpcyAwLlxuICAgKi9cbiAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9uc3xudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhbiBhbmltYXRpb24gcXVlcnkuIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnlcbiAqIHRoZSBgcXVlcnkoKWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uUXVlcnlNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqICBUaGUgQ1NTIHNlbGVjdG9yIGZvciB0aGlzIHF1ZXJ5LlxuICAgKi9cbiAgc2VsZWN0b3I6IHN0cmluZztcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBzdGVwIG9iamVjdHMuXG4gICAqL1xuICBhbmltYXRpb246IEFuaW1hdGlvbk1ldGFkYXRhfEFuaW1hdGlvbk1ldGFkYXRhW107XG4gIC8qKlxuICAgKiBBIHF1ZXJ5IG9wdGlvbnMgb2JqZWN0LlxuICAgKi9cbiAgb3B0aW9uczogQW5pbWF0aW9uUXVlcnlPcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGEga2V5ZnJhbWVzIHNlcXVlbmNlLiBJbnN0YW50aWF0ZWQgYW5kIHJldHVybmVkIGJ5XG4gKiB0aGUgYGtleWZyYW1lcygpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25LZXlmcmFtZXNTZXF1ZW5jZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogQW4gYXJyYXkgb2YgYW5pbWF0aW9uIHN0eWxlcy5cbiAgICovXG4gIHN0ZXBzOiBBbmltYXRpb25TdHlsZU1ldGFkYXRhW107XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFuIGFuaW1hdGlvbiBzdHlsZS4gSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieVxuICogdGhlIGBzdHlsZSgpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25TdHlsZU1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogQSBzZXQgb2YgQ1NTIHN0eWxlIHByb3BlcnRpZXMuXG4gICAqL1xuICBzdHlsZXM6ICcqJ3x7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfXxBcnJheTx7W2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyfXwnKic+O1xuICAvKipcbiAgICogQSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBhbmltYXRlIHRpbWUgYXQgd2hpY2ggdGhlIHN0eWxlIGlzIHRvIGJlIGFwcGxpZWQuXG4gICAqL1xuICBvZmZzZXQ6IG51bWJlcnxudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhbiBhbmltYXRpb24gc3RlcC4gSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieVxuICogdGhlIGBhbmltYXRlKClgIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIFRoZSB0aW1pbmcgZGF0YSBmb3IgdGhlIHN0ZXAuXG4gICAqL1xuICB0aW1pbmdzOiBzdHJpbmd8bnVtYmVyfEFuaW1hdGVUaW1pbmdzO1xuICAvKipcbiAgICogQSBzZXQgb2Ygc3R5bGVzIHVzZWQgaW4gdGhlIHN0ZXAuXG4gICAqL1xuICBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGF8QW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YXxudWxsO1xufVxuXG4vKipcbiAqIEVuY2Fwc3VsYXRlcyBhIGNoaWxkIGFuaW1hdGlvbiwgdGhhdCBjYW4gYmUgcnVuIGV4cGxpY2l0bHkgd2hlbiB0aGUgcGFyZW50IGlzIHJ1bi5cbiAqIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnkgdGhlIGBhbmltYXRlQ2hpbGRgIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvbkFuaW1hdGVDaGlsZE1ldGFkYXRhIGV4dGVuZHMgQW5pbWF0aW9uTWV0YWRhdGEge1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGEgcmV1c2FibGUgYW5pbWF0aW9uLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYHVzZUFuaW1hdGlvbigpYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmltYXRpb25BbmltYXRlUmVmTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBBbiBhbmltYXRpb24gcmVmZXJlbmNlIG9iamVjdC5cbiAgICovXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGE7XG4gIC8qKlxuICAgKiBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGEgZGVsYXkgYW5kXG4gICAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gICAqIGNhbiBiZSBvdmVycmlkZGVuIG9uIGludm9jYXRpb24uIERlZmF1bHQgZGVsYXkgaXMgMC5cbiAgICovXG4gIG9wdGlvbnM6IEFuaW1hdGlvbk9wdGlvbnN8bnVsbDtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgYW4gYW5pbWF0aW9uIHNlcXVlbmNlLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYHNlcXVlbmNlKClgIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblNlcXVlbmNlTWV0YWRhdGEgZXh0ZW5kcyBBbmltYXRpb25NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiAgQW4gYXJyYXkgb2YgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAgICovXG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFuIGFuaW1hdGlvbiBncm91cC5cbiAqIEluc3RhbnRpYXRlZCBhbmQgcmV0dXJuZWQgYnkgdGhlIGB7QGxpbmsgYW5pbWF0aW9ucy9ncm91cCBncm91cCgpfWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5pbWF0aW9uR3JvdXBNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBvciBzdHlsZSBzdGVwcyB0aGF0IGZvcm0gdGhpcyBncm91cC5cbiAgICovXG4gIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdO1xuICAvKipcbiAgICogQW4gb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBhIGRlbGF5IGFuZFxuICAgKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICAgKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLiBEZWZhdWx0IGRlbGF5IGlzIDAuXG4gICAqL1xuICBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zfG51bGw7XG59XG5cbi8qKlxuICogRW5jYXBzdWxhdGVzIGFuaW1hdGlvbiBxdWVyeSBvcHRpb25zLlxuICogUGFzc2VkIHRvIHRoZSBgcXVlcnkoKWAgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBBbmltYXRpb25RdWVyeU9wdGlvbnMgZXh0ZW5kcyBBbmltYXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRydWUgaWYgdGhpcyBxdWVyeSBpcyBvcHRpb25hbCwgZmFsc2UgaWYgaXQgaXMgcmVxdWlyZWQuIERlZmF1bHQgaXMgZmFsc2UuXG4gICAqIEEgcmVxdWlyZWQgcXVlcnkgdGhyb3dzIGFuIGVycm9yIGlmIG5vIGVsZW1lbnRzIGFyZSByZXRyaWV2ZWQgd2hlblxuICAgKiB0aGUgcXVlcnkgaXMgZXhlY3V0ZWQuIEFuIG9wdGlvbmFsIHF1ZXJ5IGRvZXMgbm90LlxuICAgKlxuICAgKi9cbiAgb3B0aW9uYWw/OiBib29sZWFuO1xuICAvKipcbiAgICogQSBtYXhpbXVtIHRvdGFsIG51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybiBmcm9tIHRoZSBxdWVyeS5cbiAgICogSWYgbmVnYXRpdmUsIHJlc3VsdHMgYXJlIGxpbWl0ZWQgZnJvbSB0aGUgZW5kIG9mIHRoZSBxdWVyeSBsaXN0IHRvd2FyZHMgdGhlIGJlZ2lubmluZy5cbiAgICogQnkgZGVmYXVsdCwgcmVzdWx0cyBhcmUgbm90IGxpbWl0ZWQuXG4gICAqL1xuICBsaW1pdD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBFbmNhcHN1bGF0ZXMgcGFyYW1ldGVycyBmb3Igc3RhZ2dlcmluZyB0aGUgc3RhcnQgdGltZXMgb2YgYSBzZXQgb2YgYW5pbWF0aW9uIHN0ZXBzLlxuICogSW5zdGFudGlhdGVkIGFuZCByZXR1cm5lZCBieSB0aGUgYHN0YWdnZXIoKWAgZnVuY3Rpb24uXG4gKiovXG5leHBvcnQgaW50ZXJmYWNlIEFuaW1hdGlvblN0YWdnZXJNZXRhZGF0YSBleHRlbmRzIEFuaW1hdGlvbk1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIFRoZSB0aW1pbmcgZGF0YSBmb3IgdGhlIHN0ZXBzLlxuICAgKi9cbiAgdGltaW5nczogc3RyaW5nfG51bWJlcjtcbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBzdGVwcy5cbiAgICovXG4gIGFuaW1hdGlvbjogQW5pbWF0aW9uTWV0YWRhdGF8QW5pbWF0aW9uTWV0YWRhdGFbXTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmFtZWQgYW5pbWF0aW9uIHRyaWdnZXIsIGNvbnRhaW5pbmcgYSAgbGlzdCBvZiBgc3RhdGUoKWBcbiAqIGFuZCBgdHJhbnNpdGlvbigpYCBlbnRyaWVzIHRvIGJlIGV2YWx1YXRlZCB3aGVuIHRoZSBleHByZXNzaW9uXG4gKiBib3VuZCB0byB0aGUgdHJpZ2dlciBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSBuYW1lIEFuIGlkZW50aWZ5aW5nIHN0cmluZy5cbiAqIEBwYXJhbSBkZWZpbml0aW9ucyAgQW4gYW5pbWF0aW9uIGRlZmluaXRpb24gb2JqZWN0LCBjb250YWluaW5nIGFuIGFycmF5IG9mIGBzdGF0ZSgpYFxuICogYW5kIGB0cmFuc2l0aW9uKClgIGRlY2xhcmF0aW9ucy5cbiAqXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgdHJpZ2dlciBkYXRhLlxuICogXG4gKiBAdXNhZ2VOb3Rlc1xuICogRGVmaW5lIGFuIGFuaW1hdGlvbiB0cmlnZ2VyIGluIHRoZSBgYW5pbWF0aW9uc2Agc2VjdGlvbiBvZiBgQENvbXBvbmVudGAgbWV0YWRhdGEuXG4gKiBJbiB0aGUgdGVtcGxhdGUsIHJlZmVyZW5jZSB0aGUgdHJpZ2dlciBieSBuYW1lIGFuZCBiaW5kIGl0IHRvIGEgdHJpZ2dlciBleHByZXNzaW9uIHRoYXRcbiAqIGV2YWx1YXRlcyB0byBhIGRlZmluZWQgYW5pbWF0aW9uIHN0YXRlLCB1c2luZyB0aGUgZm9sbG93aW5nIGZvcm1hdDpcbiAqXG4gKiBgW0B0cmlnZ2VyTmFtZV09XCJleHByZXNzaW9uXCJgXG4gKlxuICogQW5pbWF0aW9uIHRyaWdnZXIgYmluZGluZ3MgY29udmVydCBhbGwgdmFsdWVzIHRvIHN0cmluZ3MsIGFuZCB0aGVuIG1hdGNoIHRoZSBcbiAqIHByZXZpb3VzIGFuZCBjdXJyZW50IHZhbHVlcyBhZ2FpbnN0IGFueSBsaW5rZWQgdHJhbnNpdGlvbnMuXG4gKiBCb29sZWFucyBjYW4gYmUgc3BlY2lmaWVkIGFzIGAxYCBvciBgdHJ1ZWAgYW5kIGAwYCBvciBgZmFsc2VgLlxuICpcbiAqICMjIyBVc2FnZSBFeGFtcGxlXG4gKiBcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBjcmVhdGVzIGFuIGFuaW1hdGlvbiB0cmlnZ2VyIHJlZmVyZW5jZSBiYXNlZCBvbiB0aGUgcHJvdmlkZWRcbiAqIG5hbWUgdmFsdWUuXG4gKiBUaGUgcHJvdmlkZWQgYW5pbWF0aW9uIHZhbHVlIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGFycmF5IGNvbnNpc3Rpbmcgb2Ygc3RhdGUgYW5kXG4gKiB0cmFuc2l0aW9uIGRlY2xhcmF0aW9ucy5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6IFwibXktY29tcG9uZW50XCIsXG4gKiAgIHRlbXBsYXRlVXJsOiBcIm15LWNvbXBvbmVudC10cGwuaHRtbFwiLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcihcIm15QW5pbWF0aW9uVHJpZ2dlclwiLCBbXG4gKiAgICAgICBzdGF0ZSguLi4pLFxuICogICAgICAgc3RhdGUoLi4uKSxcbiAqICAgICAgIHRyYW5zaXRpb24oLi4uKSxcbiAqICAgICAgIHRyYW5zaXRpb24oLi4uKVxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBNeUNvbXBvbmVudCB7XG4gKiAgIG15U3RhdHVzRXhwID0gXCJzb21ldGhpbmdcIjtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIFRoZSB0ZW1wbGF0ZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb21wb25lbnQgbWFrZXMgdXNlIG9mIHRoZSBkZWZpbmVkIHRyaWdnZXJcbiAqIGJ5IGJpbmRpbmcgdG8gYW4gZWxlbWVudCB3aXRoaW4gaXRzIHRlbXBsYXRlIGNvZGUuXG4gKlxuICogYGBgaHRtbFxuICogPCEtLSBzb21ld2hlcmUgaW5zaWRlIG9mIG15LWNvbXBvbmVudC10cGwuaHRtbCAtLT5cbiAqIDxkaXYgW0BteUFuaW1hdGlvblRyaWdnZXJdPVwibXlTdGF0dXNFeHBcIj4uLi48L2Rpdj5cbiAqIGBgYFxuICpcbiAqICMjIyBVc2luZyBhbiBpbmxpbmUgZnVuY3Rpb25cbiAqIFRoZSBgdHJhbnNpdGlvbmAgYW5pbWF0aW9uIG1ldGhvZCBhbHNvIHN1cHBvcnRzIHJlYWRpbmcgYW4gaW5saW5lIGZ1bmN0aW9uIHdoaWNoIGNhbiBkZWNpZGVcbiAqIGlmIGl0cyBhc3NvY2lhdGVkIGFuaW1hdGlvbiBzaG91bGQgYmUgcnVuLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHRoaXMgbWV0aG9kIGlzIHJ1biBlYWNoIHRpbWUgdGhlIGBteUFuaW1hdGlvblRyaWdnZXJgIHRyaWdnZXIgdmFsdWUgY2hhbmdlcy5cbiAqIGZ1bmN0aW9uIG15SW5saW5lTWF0Y2hlckZuKGZyb21TdGF0ZTogc3RyaW5nLCB0b1N0YXRlOiBzdHJpbmcsIGVsZW1lbnQ6IGFueSwgcGFyYW1zOiB7W2tleTpcbiBzdHJpbmddOiBhbnl9KTogYm9vbGVhbiB7XG4gKiAgIC8vIG5vdGljZSB0aGF0IGBlbGVtZW50YCBhbmQgYHBhcmFtc2AgYXJlIGFsc28gYXZhaWxhYmxlIGhlcmVcbiAqICAgcmV0dXJuIHRvU3RhdGUgPT0gJ3llcy1wbGVhc2UtYW5pbWF0ZSc7XG4gKiB9XG4gKlxuICogQENvbXBvbmVudCh7XG4gKiAgIHNlbGVjdG9yOiAnbXktY29tcG9uZW50JyxcbiAqICAgdGVtcGxhdGVVcmw6ICdteS1jb21wb25lbnQtdHBsLmh0bWwnLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcignbXlBbmltYXRpb25UcmlnZ2VyJywgW1xuICogICAgICAgdHJhbnNpdGlvbihteUlubGluZU1hdGNoZXJGbiwgW1xuICogICAgICAgICAvLyB0aGUgYW5pbWF0aW9uIHNlcXVlbmNlIGNvZGVcbiAqICAgICAgIF0pLFxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBNeUNvbXBvbmVudCB7XG4gKiAgIG15U3RhdHVzRXhwID0gXCJ5ZXMtcGxlYXNlLWFuaW1hdGVcIjtcbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIyBEaXNhYmxpbmcgQW5pbWF0aW9uc1xuICogV2hlbiB0cnVlLCB0aGUgc3BlY2lhbCBhbmltYXRpb24gY29udHJvbCBiaW5kaW5nIGBALmRpc2FibGVkYCBiaW5kaW5nIHByZXZlbnRzIFxuICogYWxsIGFuaW1hdGlvbnMgZnJvbSByZW5kZXJpbmcuXG4gKiBQbGFjZSB0aGUgIGBALmRpc2FibGVkYCBiaW5kaW5nIG9uIGFuIGVsZW1lbnQgdG8gZGlzYWJsZVxuICogYW5pbWF0aW9ucyBvbiB0aGUgZWxlbWVudCBpdHNlbGYsIGFzIHdlbGwgYXMgYW55IGlubmVyIGFuaW1hdGlvbiB0cmlnZ2Vyc1xuICogd2l0aGluIHRoZSBlbGVtZW50LlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdG8gdXNlIHRoaXMgZmVhdHVyZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdteS1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZTogYFxuICogICAgIDxkaXYgW0AuZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiPlxuICogICAgICAgPGRpdiBbQGNoaWxkQW5pbWF0aW9uXT1cImV4cFwiPjwvZGl2PlxuICogICAgIDwvZGl2PlxuICogICBgLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICAgdHJpZ2dlcihcImNoaWxkQW5pbWF0aW9uXCIsIFtcbiAqICAgICAgIC8vIC4uLlxuICogICAgIF0pXG4gKiAgIF1cbiAqIH0pXG4gKiBjbGFzcyBNeUNvbXBvbmVudCB7XG4gKiAgIGlzRGlzYWJsZWQgPSB0cnVlO1xuICogICBleHAgPSAnLi4uJztcbiAqIH1cbiAqIGBgYFxuICpcbiAqIFdoZW4gYEAuZGlzYWJsZWRgIGlzIHRydWUsIGl0IHByZXZlbnRzIHRoZSBgQGNoaWxkQW5pbWF0aW9uYCB0cmlnZ2VyIGZyb20gYW5pbWF0aW5nLFxuICogYWxvbmcgd2l0aCBhbnkgaW5uZXIgYW5pbWF0aW9ucy5cbiAqXG4gKiAjIyMgRGlzYWJsZSBhbmltYXRpb25zIGFwcGxpY2F0aW9uLXdpZGVcbiAqIFdoZW4gYW4gYXJlYSBvZiB0aGUgdGVtcGxhdGUgaXMgc2V0IHRvIGhhdmUgYW5pbWF0aW9ucyBkaXNhYmxlZCwgXG4gKiAqKmFsbCoqIGlubmVyIGNvbXBvbmVudHMgaGF2ZSB0aGVpciBhbmltYXRpb25zIGRpc2FibGVkIGFzIHdlbGwuXG4gKiBUaGlzIG1lYW5zIHRoYXQgeW91IGNhbiBkaXNhYmxlIGFsbCBhbmltYXRpb25zIGZvciBhbiBhcHBcbiAqIGJ5IHBsYWNpbmcgYSBob3N0IGJpbmRpbmcgc2V0IG9uIGBALmRpc2FibGVkYCBvbiB0aGUgdG9wbW9zdCBBbmd1bGFyIGNvbXBvbmVudC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQge0NvbXBvbmVudCwgSG9zdEJpbmRpbmd9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuICpcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2FwcC1jb21wb25lbnQnLFxuICogICB0ZW1wbGF0ZVVybDogJ2FwcC5jb21wb25lbnQuaHRtbCcsXG4gKiB9KVxuICogY2xhc3MgQXBwQ29tcG9uZW50IHtcbiAqICAgQEhvc3RCaW5kaW5nKCdALmRpc2FibGVkJylcbiAqICAgcHVibGljIGFuaW1hdGlvbnNEaXNhYmxlZCA9IHRydWU7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMgT3ZlcnJpZGluZyBkaXNhYmxlbWVudCBvZiBpbm5lciBhbmltYXRpb25zXG4gKiBEZXNwaXRlIGlubmVyIGFuaW1hdGlvbnMgYmVpbmcgZGlzYWJsZWQsIGEgcGFyZW50IGFuaW1hdGlvbiBjYW4gYHF1ZXJ5KClgXG4gKiBmb3IgaW5uZXIgZWxlbWVudHMgbG9jYXRlZCBpbiBkaXNhYmxlZCBhcmVhcyBvZiB0aGUgdGVtcGxhdGUgYW5kIHN0aWxsIGFuaW1hdGUgXG4gKiB0aGVtIGlmIG5lZWRlZC4gVGhpcyBpcyBhbHNvIHRoZSBjYXNlIGZvciB3aGVuIGEgc3ViIGFuaW1hdGlvbiBpcyBcbiAqIHF1ZXJpZWQgYnkgYSBwYXJlbnQgYW5kIHRoZW4gbGF0ZXIgYW5pbWF0ZWQgdXNpbmcgYGFuaW1hdGVDaGlsZCgpYC5cbiAqXG4gKiAjIyMgRGV0ZWN0aW5nIHdoZW4gYW4gYW5pbWF0aW9uIGlzIGRpc2FibGVkXG4gKiBJZiBhIHJlZ2lvbiBvZiB0aGUgRE9NIChvciB0aGUgZW50aXJlIGFwcGxpY2F0aW9uKSBoYXMgaXRzIGFuaW1hdGlvbnMgZGlzYWJsZWQsIHRoZSBhbmltYXRpb25cbiAqIHRyaWdnZXIgY2FsbGJhY2tzIHN0aWxsIGZpcmUsIGJ1dCBmb3IgemVybyBzZWNvbmRzLiBXaGVuIHRoZSBjYWxsYmFjayBmaXJlcywgaXQgcHJvdmlkZXNcbiAqIGFuIGluc3RhbmNlIG9mIGFuIGBBbmltYXRpb25FdmVudGAuIElmIGFuaW1hdGlvbnMgYXJlIGRpc2FibGVkLFxuICogdGhlIGAuZGlzYWJsZWRgIGZsYWcgb24gdGhlIGV2ZW50IGlzIHRydWUuXG4gKlxuICogQGV4cGVyaW1lbnRhbCBBbmltYXRpb24gc3VwcG9ydCBpcyBleHBlcmltZW50YWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmlnZ2VyKG5hbWU6IHN0cmluZywgZGVmaW5pdGlvbnM6IEFuaW1hdGlvbk1ldGFkYXRhW10pOiBBbmltYXRpb25UcmlnZ2VyTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5UcmlnZ2VyLCBuYW1lLCBkZWZpbml0aW9ucywgb3B0aW9uczoge319O1xufVxuXG4vKipcbiAqIERlZmluZXMgYW4gYW5pbWF0aW9uIHN0ZXAgdGhhdCBjb21iaW5lcyBzdHlsaW5nIGluZm9ybWF0aW9uIHdpdGggdGltaW5nIGluZm9ybWF0aW9uLlxuICpcbiAqIEBwYXJhbSB0aW1pbmdzIFNldHMgYEFuaW1hdGVUaW1pbmdzYCBmb3IgdGhlIHBhcmVudCBhbmltYXRpb24uXG4gKiBBIHN0cmluZyBpbiB0aGUgZm9ybWF0IFwiZHVyYXRpb24gW2RlbGF5XSBbZWFzaW5nXVwiLlxuICogIC0gRHVyYXRpb24gYW5kIGRlbGF5IGFyZSBleHByZXNzZWQgYXMgYSBudW1iZXIgYW5kIG9wdGlvbmFsIHRpbWUgdW5pdCxcbiAqIHN1Y2ggYXMgXCIxc1wiIG9yIFwiMTBtc1wiIGZvciBvbmUgc2Vjb25kIGFuZCAxMCBtaWxsaXNlY29uZHMsIHJlc3BlY3RpdmVseS5cbiAqIFRoZSBkZWZhdWx0IHVuaXQgaXMgbWlsbGlzZWNvbmRzLlxuICogIC0gVGhlIGVhc2luZyB2YWx1ZSBjb250cm9scyBob3cgdGhlIGFuaW1hdGlvbiBhY2NlbGVyYXRlcyBhbmQgZGVjZWxlcmF0ZXNcbiAqIGR1cmluZyBpdHMgcnVudGltZS4gVmFsdWUgaXMgb25lIG9mICBgZWFzZWAsIGBlYXNlLWluYCwgYGVhc2Utb3V0YCxcbiAqIGBlYXNlLWluLW91dGAsIG9yIGEgYGN1YmljLWJlemllcigpYCBmdW5jdGlvbiBjYWxsLlxuICogSWYgbm90IHN1cHBsaWVkLCBubyBlYXNpbmcgaXMgYXBwbGllZC5cbiAqXG4gKiBGb3IgZXhhbXBsZSwgdGhlIHN0cmluZyBcIjFzIDEwMG1zIGVhc2Utb3V0XCIgc3BlY2lmaWVzIGEgZHVyYXRpb24gb2ZcbiAqIDEwMDAgbWlsbGlzZWNvbmRzLCBhbmQgZGVsYXkgb2YgMTAwIG1zLCBhbmQgdGhlIFwiZWFzZS1vdXRcIiBlYXNpbmcgc3R5bGUsXG4gKiB3aGljaCBkZWNlbGVyYXRlcyBuZWFyIHRoZSBlbmQgb2YgdGhlIGR1cmF0aW9uLlxuICogQHBhcmFtIHN0eWxlcyBTZXRzIEFuaW1hdGlvblN0eWxlcyBmb3IgdGhlIHBhcmVudCBhbmltYXRpb24uXG4gKiBBIGZ1bmN0aW9uIGNhbGwgdG8gZWl0aGVyIGBzdHlsZSgpYCBvciBga2V5ZnJhbWVzKClgXG4gKiB0aGF0IHJldHVybnMgYSBjb2xsZWN0aW9uIG9mIENTUyBzdHlsZSBlbnRyaWVzIHRvIGJlIGFwcGxpZWQgdG8gdGhlIHBhcmVudCBhbmltYXRpb24uXG4gKiBXaGVuIG51bGwsIHVzZXMgdGhlIHN0eWxlcyBmcm9tIHRoZSBkZXN0aW5hdGlvbiBzdGF0ZS5cbiAqIFRoaXMgaXMgdXNlZnVsIHdoZW4gZGVzY3JpYmluZyBhbiBhbmltYXRpb24gc3RlcCB0aGF0IHdpbGwgY29tcGxldGUgYW4gYW5pbWF0aW9uO1xuICogc2VlIFwiQW5pbWF0aW5nIHRvIHRoZSBmaW5hbCBzdGF0ZVwiIGluIGB0cmFuc2l0aW9ucygpYC5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgYW5pbWF0aW9uIHN0ZXAuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIENhbGwgd2l0aGluIGFuIGFuaW1hdGlvbiBgc2VxdWVuY2UoKWAsIGB7QGxpbmsgYW5pbWF0aW9ucy9ncm91cCBncm91cCgpfWAsIG9yXG4gKiBgdHJhbnNpdGlvbigpYCBjYWxsIHRvIHNwZWNpZnkgYW4gYW5pbWF0aW9uIHN0ZXBcbiAqIHRoYXQgYXBwbGllcyBnaXZlbiBzdHlsZSBkYXRhIHRvIHRoZSBwYXJlbnQgYW5pbWF0aW9uIGZvciBhIGdpdmVuIGFtb3VudCBvZiB0aW1lLlxuICpcbiAqICMjIyBTeW50YXggRXhhbXBsZXNcbiAqICoqVGltaW5nIGV4YW1wbGVzKipcbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIHNob3cgdmFyaW91cyBgdGltaW5nc2Agc3BlY2lmaWNhdGlvbnMuXG4gKiAtIGBhbmltYXRlKDUwMClgIDogRHVyYXRpb24gaXMgNTAwIG1pbGxpc2Vjb25kcy5cbiAqIC0gYGFuaW1hdGUoXCIxc1wiKWAgOiBEdXJhdGlvbiBpcyAxMDAwIG1pbGxpc2Vjb25kcy5cbiAqIC0gYGFuaW1hdGUoXCIxMDBtcyAwLjVzXCIpYCA6IER1cmF0aW9uIGlzIDEwMCBtaWxsaXNlY29uZHMsIGRlbGF5IGlzIDUwMCBtaWxsaXNlY29uZHMuXG4gKiAtIGBhbmltYXRlKFwiNXMgZWFzZS1pblwiKWAgOiBEdXJhdGlvbiBpcyA1MDAwIG1pbGxpc2Vjb25kcywgZWFzaW5nIGluLlxuICogLSBgYW5pbWF0ZShcIjVzIDEwbXMgY3ViaWMtYmV6aWVyKC4xNywuNjcsLjg4LC4xKVwiKWAgOiBEdXJhdGlvbiBpcyA1MDAwIG1pbGxpc2Vjb25kcywgZGVsYXkgaXMgMTBcbiAqIG1pbGxpc2Vjb25kcywgZWFzaW5nIGFjY29yZGluZyB0byBhIGJlemllciBjdXJ2ZS5cbiAqXG4gKiAqKlN0eWxlIGV4YW1wbGVzKipcbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgY2FsbHMgYHN0eWxlKClgIHRvIHNldCBhIHNpbmdsZSBDU1Mgc3R5bGUuXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBhbmltYXRlKDUwMCwgc3R5bGUoeyBiYWNrZ3JvdW5kOiBcInJlZFwiIH0pKVxuICogYGBgXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgY2FsbHMgYGtleWZyYW1lcygpYCB0byBzZXQgYSBDU1Mgc3R5bGVcbiAqIHRvIGRpZmZlcmVudCB2YWx1ZXMgZm9yIHN1Y2Nlc3NpdmUga2V5ZnJhbWVzLlxuICogYGBgdHlwZXNjcmlwdFxuICogYW5pbWF0ZSg1MDAsIGtleWZyYW1lcyhcbiAqICBbXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZDogXCJibHVlXCIgfSkpLFxuICogICBzdHlsZSh7IGJhY2tncm91bmQ6IFwicmVkXCIgfSkpXG4gKiAgXSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5pbWF0ZShcbiAgICB0aW1pbmdzOiBzdHJpbmcgfCBudW1iZXIsIHN0eWxlczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YSB8IEFuaW1hdGlvbktleWZyYW1lc1NlcXVlbmNlTWV0YWRhdGEgfFxuICAgICAgICBudWxsID0gbnVsbCk6IEFuaW1hdGlvbkFuaW1hdGVNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLkFuaW1hdGUsIHN0eWxlcywgdGltaW5nc307XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmluZXMgYSBsaXN0IG9mIGFuaW1hdGlvbiBzdGVwcyB0byBiZSBydW4gaW4gcGFyYWxsZWwuXG4gKlxuICogQHBhcmFtIHN0ZXBzIEFuIGFycmF5IG9mIGFuaW1hdGlvbiBzdGVwIG9iamVjdHMuXG4gKiAtIFdoZW4gc3RlcHMgYXJlIGRlZmluZWQgYnkgYHN0eWxlKClgIG9yIGBhbmltYXRlKClgXG4gKiBmdW5jdGlvbiBjYWxscywgZWFjaCBjYWxsIHdpdGhpbiB0aGUgZ3JvdXAgaXMgZXhlY3V0ZWQgaW5zdGFudGx5LlxuICogLSBUbyBzcGVjaWZ5IG9mZnNldCBzdHlsZXMgdG8gYmUgYXBwbGllZCBhdCBhIGxhdGVyIHRpbWUsIGRlZmluZSBzdGVwcyB3aXRoXG4gKiBga2V5ZnJhbWVzKClgLCBvciB1c2UgYGFuaW1hdGUoKWAgY2FsbHMgd2l0aCBhIGRlbGF5IHZhbHVlLlxuICogRm9yIGV4YW1wbGU6XG4gKiBcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGdyb3VwKFtcbiAqICAgYW5pbWF0ZShcIjFzXCIsIHsgYmFja2dyb3VuZDogXCJibGFja1wiIH0pKVxuICogICBhbmltYXRlKFwiMnNcIiwgeyBjb2xvcjogXCJ3aGl0ZVwiIH0pKVxuICogXSlcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgYSBkZWxheSBhbmRcbiAqIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMgdGhhdCBwcm92aWRlIHN0eWxpbmcgZGVmYXVsdHMgYW5kXG4gKiBjYW4gYmUgb3ZlcnJpZGRlbiBvbiBpbnZvY2F0aW9uLlxuICpcbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBncm91cCBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBHcm91cGVkIGFuaW1hdGlvbnMgYXJlIHVzZWZ1bCB3aGVuIGEgc2VyaWVzIG9mIHN0eWxlcyBtdXN0IGJlIFxuICogYW5pbWF0ZWQgYXQgZGlmZmVyZW50IHN0YXJ0aW5nIHRpbWVzIGFuZCBjbG9zZWQgb2ZmIGF0IGRpZmZlcmVudCBlbmRpbmcgdGltZXMuXG4gKlxuICogV2hlbiBjYWxsZWQgd2l0aGluIGEgYHNlcXVlbmNlKClgIG9yIGFcbiAqIGB0cmFuc2l0aW9uKClgIGNhbGwsIGRvZXMgbm90IGNvbnRpbnVlIHRvIHRoZSBuZXh0XG4gKiBpbnN0cnVjdGlvbiB1bnRpbCBhbGwgb2YgdGhlIGlubmVyIGFuaW1hdGlvbiBzdGVwcyBoYXZlIGNvbXBsZXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwKFxuICAgIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdLCBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25Hcm91cE1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuR3JvdXAsIHN0ZXBzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIGEgbGlzdCBvZiBhbmltYXRpb24gc3RlcHMgdG8gYmUgcnVuIHNlcXVlbnRpYWxseSwgb25lIGJ5IG9uZS5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgQW4gYXJyYXkgb2YgYW5pbWF0aW9uIHN0ZXAgb2JqZWN0cy5cbiAqIC0gU3RlcHMgZGVmaW5lZCBieSBgc3R5bGUoKWAgY2FsbHMgYXBwbHkgdGhlIHN0eWxpbmcgZGF0YSBpbW1lZGlhdGVseS5cbiAqIC0gU3RlcHMgZGVmaW5lZCBieSBgYW5pbWF0ZSgpYCBjYWxscyBhcHBseSB0aGUgc3R5bGluZyBkYXRhIG92ZXIgdGltZVxuICogICBhcyBzcGVjaWZpZWQgYnkgdGhlIHRpbWluZyBkYXRhLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHNlcXVlbmNlKFtcbiAqICAgc3R5bGUoeyBvcGFjaXR5OiAwIH0pKSxcbiAqICAgYW5pbWF0ZShcIjFzXCIsIHsgb3BhY2l0eTogMSB9KSlcbiAqIF0pXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyBBbiBvcHRpb25zIG9iamVjdCBjb250YWluaW5nIGEgZGVsYXkgYW5kXG4gKiBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzIHRoYXQgcHJvdmlkZSBzdHlsaW5nIGRlZmF1bHRzIGFuZFxuICogY2FuIGJlIG92ZXJyaWRkZW4gb24gaW52b2NhdGlvbi5cbiAqXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgc2VxdWVuY2UgZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogV2hlbiB5b3UgcGFzcyBhbiBhcnJheSBvZiBzdGVwcyB0byBhXG4gKiBgdHJhbnNpdGlvbigpYCBjYWxsLCB0aGUgc3RlcHMgcnVuIHNlcXVlbnRpYWxseSBieSBkZWZhdWx0LlxuICogQ29tcGFyZSB0aGlzIHRvIHRoZSBge0BsaW5rIGFuaW1hdGlvbnMvZ3JvdXAgZ3JvdXAoKX1gIGNhbGwsIHdoaWNoIHJ1bnMgYW5pbWF0aW9uIHN0ZXBzIGluIHBhcmFsbGVsLlxuICpcbiAqIFdoZW4gYSBzZXF1ZW5jZSBpcyB1c2VkIHdpdGhpbiBhIGB7QGxpbmsgYW5pbWF0aW9ucy9ncm91cCBncm91cCgpfWAgb3IgYSBgdHJhbnNpdGlvbigpYCBjYWxsLFxuICogZXhlY3V0aW9uIGNvbnRpbnVlcyB0byB0aGUgbmV4dCBpbnN0cnVjdGlvbiBvbmx5IGFmdGVyIGVhY2ggb2YgdGhlIGlubmVyIGFuaW1hdGlvblxuICogc3RlcHMgaGF2ZSBjb21wbGV0ZWQuXG4gKlxuICoqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcXVlbmNlKHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YVtdLCBvcHRpb25zOiBBbmltYXRpb25PcHRpb25zIHwgbnVsbCA9IG51bGwpOlxuICAgIEFuaW1hdGlvblNlcXVlbmNlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TZXF1ZW5jZSwgc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIERlY2xhcmVzIGEga2V5L3ZhbHVlIG9iamVjdCBjb250YWluaW5nIENTUyBwcm9wZXJ0aWVzL3N0eWxlcyB0aGF0XG4gKiBjYW4gdGhlbiBiZSB1c2VkIGZvciBhbiBhbmltYXRpb24gYHN0YXRlYCwgd2l0aGluIGFuIGFuaW1hdGlvbiBgc2VxdWVuY2VgLFxuICogb3IgYXMgc3R5bGluZyBkYXRhIGZvciBjYWxscyB0byBgYW5pbWF0ZSgpYCBhbmQgYGtleWZyYW1lcygpYC5cbiAqXG4gKiBAcGFyYW0gdG9rZW5zIEEgc2V0IG9mIENTUyBzdHlsZXMgb3IgSFRNTCBzdHlsZXMgYXNzb2NpYXRlZCB3aXRoIGFuIGFuaW1hdGlvbiBzdGF0ZS5cbiAqIFRoZSB2YWx1ZSBjYW4gYmUgYW55IG9mIHRoZSBmb2xsb3dpbmc6XG4gKiAtIEEga2V5LXZhbHVlIHN0eWxlIHBhaXIgYXNzb2NpYXRpbmcgYSBDU1MgcHJvcGVydHkgd2l0aCBhIHZhbHVlLlxuICogLSBBbiBhcnJheSBvZiBrZXktdmFsdWUgc3R5bGUgcGFpcnMuXG4gKiAtIEFuIGFzdGVyaXNrICgqKSwgdG8gdXNlIGF1dG8tc3R5bGluZywgd2hlcmUgc3R5bGVzIGFyZSBkZXJpdmVkIGZyb20gdGhlIGVsZW1lbnRcbiAqIGJlaW5nIGFuaW1hdGVkIGFuZCBhcHBsaWVkIHRvIHRoZSBhbmltYXRpb24gd2hlbiBpdCBzdGFydHMuXG4gKlxuICogQXV0by1zdHlsaW5nIGNhbiBiZSB1c2VkIHRvIGRlZmluZSBhIHN0YXRlIHRoYXQgZGVwZW5kcyBvbiBsYXlvdXQgb3Igb3RoZXIgXG4gKiBlbnZpcm9ubWVudGFsIGZhY3RvcnMuXG4gKlxuICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIHN0eWxlIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZXMgY3JlYXRlIGFuaW1hdGlvbiBzdHlsZXMgdGhhdCBjb2xsZWN0IGEgc2V0IG9mXG4gKiBDU1MgcHJvcGVydHkgdmFsdWVzOlxuICogXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBzdHJpbmcgdmFsdWVzIGZvciBDU1MgcHJvcGVydGllc1xuICogc3R5bGUoeyBiYWNrZ3JvdW5kOiBcInJlZFwiLCBjb2xvcjogXCJibHVlXCIgfSlcbiAqXG4gKiAvLyBudW1lcmljYWwgcGl4ZWwgdmFsdWVzXG4gKiBzdHlsZSh7IHdpZHRoOiAxMDAsIGhlaWdodDogMCB9KVxuICogYGBgXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHVzZXMgYXV0by1zdHlsaW5nIHRvIGFsbG93IGEgY29tcG9uZW50IHRvIGFuaW1hdGUgZnJvbVxuICogYSBoZWlnaHQgb2YgMCB1cCB0byB0aGUgaGVpZ2h0IG9mIHRoZSBwYXJlbnQgZWxlbWVudDpcbiAqXG4gKiBgYGBcbiAqIHN0eWxlKHsgaGVpZ2h0OiAwIH0pLFxuICogYW5pbWF0ZShcIjFzXCIsIHN0eWxlKHsgaGVpZ2h0OiBcIipcIiB9KSlcbiAqIGBgYFxuICpcbiAqKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHlsZShcbiAgICB0b2tlbnM6ICcqJyB8IHtba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXJ9IHxcbiAgICBBcnJheTwnKid8e1trZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlcn0+KTogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLlN0eWxlLCBzdHlsZXM6IHRva2Vucywgb2Zmc2V0OiBudWxsfTtcbn1cblxuLyoqXG4gKiBEZWNsYXJlcyBhbiBhbmltYXRpb24gc3RhdGUgd2l0aGluIGEgdHJpZ2dlciBhdHRhY2hlZCB0byBhbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSBuYW1lIE9uZSBvciBtb3JlIG5hbWVzIGZvciB0aGUgZGVmaW5lZCBzdGF0ZSBpbiBhIGNvbW1hLXNlcGFyYXRlZCBzdHJpbmcuXG4gKiBUaGUgZm9sbG93aW5nIHJlc2VydmVkIHN0YXRlIG5hbWVzIGNhbiBiZSBzdXBwbGllZCB0byBkZWZpbmUgYSBzdHlsZSBmb3Igc3BlY2lmaWMgdXNlXG4gKiBjYXNlczpcbiAqXG4gKiAtIGB2b2lkYCBZb3UgY2FuIGFzc29jaWF0ZSBzdHlsZXMgd2l0aCB0aGlzIG5hbWUgdG8gYmUgdXNlZCB3aGVuXG4gKiB0aGUgZWxlbWVudCBpcyBkZXRhY2hlZCBmcm9tIHRoZSBhcHBsaWNhdGlvbi4gRm9yIGV4YW1wbGUsIHdoZW4gYW4gYG5nSWZgIGV2YWx1YXRlc1xuICogdG8gZmFsc2UsIHRoZSBzdGF0ZSBvZiB0aGUgYXNzb2NpYXRlZCBlbGVtZW50IGlzIHZvaWQuXG4gKiAgLSBgKmAgKGFzdGVyaXNrKSBJbmRpY2F0ZXMgdGhlIGRlZmF1bHQgc3RhdGUuIFlvdSBjYW4gYXNzb2NpYXRlIHN0eWxlcyB3aXRoIHRoaXMgbmFtZVxuICogdG8gYmUgdXNlZCBhcyB0aGUgZmFsbGJhY2sgd2hlbiB0aGUgc3RhdGUgdGhhdCBpcyBiZWluZyBhbmltYXRlZCBpcyBub3QgZGVjbGFyZWRcbiAqIHdpdGhpbiB0aGUgdHJpZ2dlci5cbiAqXG4gKiBAcGFyYW0gc3R5bGVzIEEgc2V0IG9mIENTUyBzdHlsZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3RhdGUsIGNyZWF0ZWQgdXNpbmcgdGhlXG4gKiBgc3R5bGUoKWAgZnVuY3Rpb24uXG4gKiBUaGlzIHNldCBvZiBzdHlsZXMgcGVyc2lzdHMgb24gdGhlIGVsZW1lbnQgb25jZSB0aGUgc3RhdGUgaGFzIGJlZW4gcmVhY2hlZC5cbiAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdGhhdCBjYW4gYmUgcGFzc2VkIHRvIHRoZSBzdGF0ZSB3aGVuIGl0IGlzIGludm9rZWQuXG4gKiAwIG9yIG1vcmUga2V5LXZhbHVlIHBhaXJzLlxuICogQHJldHVybiBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIG5ldyBzdGF0ZSBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBVc2UgdGhlIGB0cmlnZ2VyKClgIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIHN0YXRlcyB0byBhbiBhbmltYXRpb24gdHJpZ2dlci5cbiAqIFVzZSB0aGUgYHRyYW5zaXRpb24oKWAgZnVuY3Rpb24gdG8gYW5pbWF0ZSBiZXR3ZWVuIHN0YXRlcy5cbiAqIFdoZW4gYSBzdGF0ZSBpcyBhY3RpdmUgd2l0aGluIGEgY29tcG9uZW50LCBpdHMgYXNzb2NpYXRlZCBzdHlsZXMgcGVyc2lzdCBvbiB0aGUgZWxlbWVudCxcbiAqIGV2ZW4gd2hlbiB0aGUgYW5pbWF0aW9uIGVuZHMuXG4gKiovXG5leHBvcnQgZnVuY3Rpb24gc3RhdGUoXG4gICAgbmFtZTogc3RyaW5nLCBzdHlsZXM6IEFuaW1hdGlvblN0eWxlTWV0YWRhdGEsXG4gICAgb3B0aW9ucz86IHtwYXJhbXM6IHtbbmFtZTogc3RyaW5nXTogYW55fX0pOiBBbmltYXRpb25TdGF0ZU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuU3RhdGUsIG5hbWUsIHN0eWxlcywgb3B0aW9uc307XG59XG5cbi8qKlxuICogRGVmaW5lcyBhIHNldCBvZiBhbmltYXRpb24gc3R5bGVzLCBhc3NvY2lhdGluZyBlYWNoIHN0eWxlIHdpdGggYW4gb3B0aW9uYWwgYG9mZnNldGAgdmFsdWUuXG4gKlxuICogQHBhcmFtIHN0ZXBzIEEgc2V0IG9mIGFuaW1hdGlvbiBzdHlsZXMgd2l0aCBvcHRpb25hbCBvZmZzZXQgZGF0YS5cbiAqIFRoZSBvcHRpb25hbCBgb2Zmc2V0YCB2YWx1ZSBmb3IgYSBzdHlsZSBzcGVjaWZpZXMgYSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBhbmltYXRpb25cbiAqIHRpbWUgYXQgd2hpY2ggdGhhdCBzdHlsZSBpcyBhcHBsaWVkLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBrZXlmcmFtZXMgZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVXNlIHdpdGggdGhlIGBhbmltYXRlKClgIGNhbGwuIEluc3RlYWQgb2YgYXBwbHlpbmcgYW5pbWF0aW9uc1xuICogZnJvbSB0aGUgY3VycmVudCBzdGF0ZVxuICogdG8gdGhlIGRlc3RpbmF0aW9uIHN0YXRlLCBrZXlmcmFtZXMgZGVzY3JpYmUgaG93IGVhY2ggc3R5bGUgZW50cnkgaXMgYXBwbGllZCBhbmQgYXQgd2hhdCBwb2ludFxuICogd2l0aGluIHRoZSBhbmltYXRpb24gYXJjLlxuICogQ29tcGFyZSBbQ1NTIEtleWZyYW1lIEFuaW1hdGlvbnNdKGh0dHBzOi8vd3d3Lnczc2Nob29scy5jb20vY3NzL2NzczNfYW5pbWF0aW9ucy5hc3ApLlxuICpcbiAqICMjIyBVc2FnZVxuICpcbiAqIEluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZSwgdGhlIG9mZnNldCB2YWx1ZXMgZGVzY3JpYmVcbiAqIHdoZW4gZWFjaCBgYmFja2dyb3VuZENvbG9yYCB2YWx1ZSBpcyBhcHBsaWVkLiBUaGUgY29sb3IgaXMgcmVkIGF0IHRoZSBzdGFydCwgYW5kIGNoYW5nZXMgdG9cbiAqIGJsdWUgd2hlbiAyMCUgb2YgdGhlIHRvdGFsIHRpbWUgaGFzIGVsYXBzZWQuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gdGhlIHByb3ZpZGVkIG9mZnNldCB2YWx1ZXNcbiAqIGFuaW1hdGUoXCI1c1wiLCBrZXlmcmFtZXMoW1xuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJyZWRcIiwgb2Zmc2V0OiAwIH0pLFxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJibHVlXCIsIG9mZnNldDogMC4yIH0pLFxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJvcmFuZ2VcIiwgb2Zmc2V0OiAwLjMgfSksXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcImJsYWNrXCIsIG9mZnNldDogMSB9KVxuICogXSkpXG4gKiBgYGBcbiAqXG4gKiBJZiB0aGVyZSBhcmUgbm8gYG9mZnNldGAgdmFsdWVzIHNwZWNpZmllZCBpbiB0aGUgc3R5bGUgZW50cmllcywgdGhlIG9mZnNldHNcbiAqIGFyZSBjYWxjdWxhdGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogYW5pbWF0ZShcIjVzXCIsIGtleWZyYW1lcyhbXG4gKiAgIHN0eWxlKHsgYmFja2dyb3VuZENvbG9yOiBcInJlZFwiIH0pIC8vIG9mZnNldCA9IDBcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwiYmx1ZVwiIH0pIC8vIG9mZnNldCA9IDAuMzNcbiAqICAgc3R5bGUoeyBiYWNrZ3JvdW5kQ29sb3I6IFwib3JhbmdlXCIgfSkgLy8gb2Zmc2V0ID0gMC42NlxuICogICBzdHlsZSh7IGJhY2tncm91bmRDb2xvcjogXCJibGFja1wiIH0pIC8vIG9mZnNldCA9IDFcbiAqIF0pKVxuICpgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGtleWZyYW1lcyhzdGVwczogQW5pbWF0aW9uU3R5bGVNZXRhZGF0YVtdKTogQW5pbWF0aW9uS2V5ZnJhbWVzU2VxdWVuY2VNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLktleWZyYW1lcywgc3RlcHN9O1xufVxuXG4vKipcbiAqIERlY2xhcmVzIGFuIGFuaW1hdGlvbiB0cmFuc2l0aW9uIGFzIGEgc2VxdWVuY2Ugb2YgYW5pbWF0aW9uIHN0ZXBzIHRvIHJ1biB3aGVuIGEgZ2l2ZW5cbiAqIGNvbmRpdGlvbiBpcyBzYXRpc2ZpZWQuIFRoZSBjb25kaXRpb24gaXMgYSBCb29sZWFuIGV4cHJlc3Npb24gb3IgZnVuY3Rpb24gdGhhdCBjb21wYXJlc1xuICogdGhlIHByZXZpb3VzIGFuZCBjdXJyZW50IGFuaW1hdGlvbiBzdGF0ZXMsIGFuZCByZXR1cm5zIHRydWUgaWYgdGhpcyB0cmFuc2l0aW9uIHNob3VsZCBvY2N1ci5cbiAqIFdoZW4gdGhlIHN0YXRlIGNyaXRlcmlhIG9mIGEgZGVmaW5lZCB0cmFuc2l0aW9uIGFyZSBtZXQsIHRoZSBhc3NvY2lhdGVkIGFuaW1hdGlvbiBpc1xuICogdHJpZ2dlcmVkLlxuICpcbiAqIEBwYXJhbSBzdGF0ZUNoYW5nZUV4cHIgQSBCb29sZWFuIGV4cHJlc3Npb24gb3IgZnVuY3Rpb24gdGhhdCBjb21wYXJlcyB0aGUgcHJldmlvdXMgYW5kIGN1cnJlbnRcbiAqIGFuaW1hdGlvbiBzdGF0ZXMsIGFuZCByZXR1cm5zIHRydWUgaWYgdGhpcyB0cmFuc2l0aW9uIHNob3VsZCBvY2N1ci4gTm90ZSB0aGF0ICBcInRydWVcIiBhbmQgXCJmYWxzZVwiXG4gKiBtYXRjaCAxIGFuZCAwLCByZXNwZWN0aXZlbHkuIEFuIGV4cHJlc3Npb24gaXMgZXZhbHVhdGVkIGVhY2ggdGltZSBhIHN0YXRlIGNoYW5nZSBvY2N1cnMgaW4gdGhlXG4gKiBhbmltYXRpb24gdHJpZ2dlciBlbGVtZW50LlxuICogVGhlIGFuaW1hdGlvbiBzdGVwcyBydW4gd2hlbiB0aGUgZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZS5cbiAqXG4gKiAtIEEgc3RhdGUtY2hhbmdlIHN0cmluZyB0YWtlcyB0aGUgZm9ybSBcInN0YXRlMSA9PiBzdGF0ZTJcIiwgd2hlcmUgZWFjaCBzaWRlIGlzIGEgZGVmaW5lZCBhbmltYXRpb25cbiAqIHN0YXRlLCBvciBhbiBhc3Rlcml4ICgqKSB0byByZWZlciB0byBhIGR5bmFtaWMgc3RhcnQgb3IgZW5kIHN0YXRlLlxuICogICAtIFRoZSBleHByZXNzaW9uIHN0cmluZyBjYW4gY29udGFpbiBtdWx0aXBsZSBjb21tYS1zZXBhcmF0ZWQgc3RhdGVtZW50cztcbiAqIGZvciBleGFtcGxlIFwic3RhdGUxID0+IHN0YXRlMiwgc3RhdGUzID0+IHN0YXRlNFwiLlxuICogICAtIFNwZWNpYWwgdmFsdWVzIGA6ZW50ZXJgIGFuZCBgOmxlYXZlYCBpbml0aWF0ZSBhIHRyYW5zaXRpb24gb24gdGhlIGVudHJ5IGFuZCBleGl0IHN0YXRlcyxcbiAqIGVxdWl2YWxlbnQgdG8gIFwidm9pZCA9PiAqXCIgIGFuZCBcIiogPT4gdm9pZFwiLlxuICogICAtIFNwZWNpYWwgdmFsdWVzIGA6aW5jcmVtZW50YCBhbmQgYDpkZWNyZW1lbnRgIGluaXRpYXRlIGEgdHJhbnNpdGlvbiB3aGVuIGEgbnVtZXJpYyB2YWx1ZSBoYXNcbiAqIGluY3JlYXNlZCBvciBkZWNyZWFzZWQgaW4gdmFsdWUuXG4gKiAtIEEgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWFjaCB0aW1lIGEgc3RhdGUgY2hhbmdlIG9jY3VycyBpbiB0aGUgYW5pbWF0aW9uIHRyaWdnZXIgZWxlbWVudC5cbiAqIFRoZSBhbmltYXRpb24gc3RlcHMgcnVuIHdoZW4gdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZS5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgT25lIG9yIG1vcmUgYW5pbWF0aW9uIG9iamVjdHMsIGFzIHJldHVybmVkIGJ5IHRoZSBgYW5pbWF0ZSgpYCBvclxuICogYHNlcXVlbmNlKClgIGZ1bmN0aW9uLCB0aGF0IGZvcm0gYSB0cmFuc2Zvcm1hdGlvbiBmcm9tIG9uZSBzdGF0ZSB0byBhbm90aGVyLlxuICogQSBzZXF1ZW5jZSBpcyB1c2VkIGJ5IGRlZmF1bHQgd2hlbiB5b3UgcGFzcyBhbiBhcnJheS5cbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBkZWxheSB2YWx1ZSBmb3IgdGhlIHN0YXJ0IG9mIHRoZSBhbmltYXRpb24sXG4gKiBhbmQgYWRkaXRpb25hbCBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzLiBQcm92aWRlZCB2YWx1ZXMgZm9yIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBhcmUgdXNlZFxuICogYXMgZGVmYXVsdHMsIGFuZCBvdmVycmlkZSB2YWx1ZXMgY2FuIGJlIHBhc3NlZCB0byB0aGUgY2FsbGVyIG9uIGludm9jYXRpb24uXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIHRyYW5zaXRpb24gZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVGhlIHRlbXBsYXRlIGFzc29jaWF0ZWQgd2l0aCBhIGNvbXBvbmVudCBiaW5kcyBhbiBhbmltYXRpb24gdHJpZ2dlciB0byBhbiBlbGVtZW50LlxuICpcbiAqIGBgYEhUTUxcbiAqIDwhLS0gc29tZXdoZXJlIGluc2lkZSBvZiBteS1jb21wb25lbnQtdHBsLmh0bWwgLS0+XG4gKiA8ZGl2IFtAbXlBbmltYXRpb25UcmlnZ2VyXT1cIm15U3RhdHVzRXhwXCI+Li4uPC9kaXY+XG4gKiBgYGBcbiAqXG4gKiBBbGwgdHJhbnNpdGlvbnMgYXJlIGRlZmluZWQgd2l0aGluIGFuIGFuaW1hdGlvbiB0cmlnZ2VyLFxuICogYWxvbmcgd2l0aCBuYW1lZCBzdGF0ZXMgdGhhdCB0aGUgdHJhbnNpdGlvbnMgY2hhbmdlIHRvIGFuZCBmcm9tLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyaWdnZXIoXCJteUFuaW1hdGlvblRyaWdnZXJcIiwgW1xuICogIC8vIGRlZmluZSBzdGF0ZXNcbiAqICBzdGF0ZShcIm9uXCIsIHN0eWxlKHsgYmFja2dyb3VuZDogXCJncmVlblwiIH0pKSxcbiAqICBzdGF0ZShcIm9mZlwiLCBzdHlsZSh7IGJhY2tncm91bmQ6IFwiZ3JleVwiIH0pKSxcbiAqICAuLi5dXG4gKiBgYGBcbiAqXG4gKiBOb3RlIHRoYXQgd2hlbiB5b3UgY2FsbCB0aGUgYHNlcXVlbmNlKClgIGZ1bmN0aW9uIHdpdGhpbiBhIGB7QGxpbmsgYW5pbWF0aW9ucy9ncm91cCBncm91cCgpfWBcbiAqIG9yIGEgYHRyYW5zaXRpb24oKWAgY2FsbCwgZXhlY3V0aW9uIGRvZXMgbm90IGNvbnRpbnVlIHRvIHRoZSBuZXh0IGluc3RydWN0aW9uXG4gKiB1bnRpbCBlYWNoIG9mIHRoZSBpbm5lciBhbmltYXRpb24gc3RlcHMgaGF2ZSBjb21wbGV0ZWQuXG4gKlxuICogIyMjIFN5bnRheCBleGFtcGxlc1xuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZXMgZGVmaW5lIHRyYW5zaXRpb25zIGJldHdlZW4gdGhlIHR3byBkZWZpbmVkIHN0YXRlcyAoYW5kIGRlZmF1bHQgc3RhdGVzKSxcbiAqIHVzaW5nIHZhcmlvdXMgb3B0aW9uczpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBUcmFuc2l0aW9uIG9jY3VycyB3aGVuIHRoZSBzdGF0ZSB2YWx1ZVxuICogLy8gYm91bmQgdG8gXCJteUFuaW1hdGlvblRyaWdnZXJcIiBjaGFuZ2VzIGZyb20gXCJvblwiIHRvIFwib2ZmXCJcbiAqIHRyYW5zaXRpb24oXCJvbiA9PiBvZmZcIiwgYW5pbWF0ZSg1MDApKVxuICogLy8gUnVuIHRoZSBzYW1lIGFuaW1hdGlvbiBmb3IgYm90aCBkaXJlY3Rpb25zXG4gKiB0cmFuc2l0aW9uKFwib24gPD0+IG9mZlwiLCBhbmltYXRlKDUwMCkpXG4gKiAvLyBEZWZpbmUgbXVsdGlwbGUgc3RhdGUtY2hhbmdlIHBhaXJzIHNlcGFyYXRlZCBieSBjb21tYXNcbiAqIHRyYW5zaXRpb24oXCJvbiA9PiBvZmYsIG9mZiA9PiB2b2lkXCIsIGFuaW1hdGUoNTAwKSlcbiAqIGBgYFxuICpcbiAqICMjIyBTcGVjaWFsIHZhbHVlcyBmb3Igc3RhdGUtY2hhbmdlIGV4cHJlc3Npb25zXG4gKlxuICogLSBDYXRjaC1hbGwgc3RhdGUgY2hhbmdlIGZvciB3aGVuIGFuIGVsZW1lbnQgaXMgaW5zZXJ0ZWQgaW50byB0aGUgcGFnZSBhbmQgdGhlXG4gKiBkZXN0aW5hdGlvbiBzdGF0ZSBpcyB1bmtub3duOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyYW5zaXRpb24oXCJ2b2lkID0+ICpcIiwgW1xuICogIHN0eWxlKHsgb3BhY2l0eTogMCB9KSxcbiAqICBhbmltYXRlKDUwMClcbiAqICBdKVxuICogYGBgXG4gKlxuICogLSBDYXB0dXJlIGEgc3RhdGUgY2hhbmdlIGJldHdlZW4gYW55IHN0YXRlczpcbiAqXG4gKiAgYHRyYW5zaXRpb24oXCIqID0+ICpcIiwgYW5pbWF0ZShcIjFzIDBzXCIpKWBcbiAqXG4gKiAtIEVudHJ5IGFuZCBleGl0IHRyYW5zaXRpb25zOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyYW5zaXRpb24oXCI6ZW50ZXJcIiwgW1xuICogICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgIGFuaW1hdGUoNTAwLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpXG4gKiAgIF0pLFxuICogdHJhbnNpdGlvbihcIjpsZWF2ZVwiLCBbXG4gKiAgIGFuaW1hdGUoNTAwLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpXG4gKiAgIF0pXG4gKiBgYGBcbiAqXG4gKiAtIFVzZSBgOmluY3JlbWVudGAgYW5kIGA6ZGVjcmVtZW50YCB0byBpbml0aWF0ZSB0cmFuc2l0aW9uczpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB0cmFuc2l0aW9uKFwiOmluY3JlbWVudFwiLCBncm91cChbXG4gKiAgcXVlcnkoJzplbnRlcicsIFtcbiAqICAgICBzdHlsZSh7IGxlZnQ6ICcxMDAlJyB9KSxcbiAqICAgICBhbmltYXRlKCcwLjVzIGVhc2Utb3V0Jywgc3R5bGUoJyonKSlcbiAqICAgXSksXG4gKiAgcXVlcnkoJzpsZWF2ZScsIFtcbiAqICAgICBhbmltYXRlKCcwLjVzIGVhc2Utb3V0Jywgc3R5bGUoeyBsZWZ0OiAnLTEwMCUnIH0pKVxuICogIF0pXG4gKiBdKSlcbiAqXG4gKiB0cmFuc2l0aW9uKFwiOmRlY3JlbWVudFwiLCBncm91cChbXG4gKiAgcXVlcnkoJzplbnRlcicsIFtcbiAqICAgICBzdHlsZSh7IGxlZnQ6ICcxMDAlJyB9KSxcbiAqICAgICBhbmltYXRlKCcwLjVzIGVhc2Utb3V0Jywgc3R5bGUoJyonKSlcbiAqICAgXSksXG4gKiAgcXVlcnkoJzpsZWF2ZScsIFtcbiAqICAgICBhbmltYXRlKCcwLjVzIGVhc2Utb3V0Jywgc3R5bGUoeyBsZWZ0OiAnLTEwMCUnIH0pKVxuICogIF0pXG4gKiBdKSlcbiAqIGBgYFxuICpcbiAqICMjIyBTdGF0ZS1jaGFuZ2UgZnVuY3Rpb25zXG4gKlxuICogSGVyZSBpcyBhbiBleGFtcGxlIG9mIGEgYGZyb21TdGF0ZWAgc3BlY2lmaWVkIGFzIGEgc3RhdGUtY2hhbmdlIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBhblxuICogYW5pbWF0aW9uIHdoZW4gdHJ1ZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB0cmFuc2l0aW9uKChmcm9tU3RhdGUsIHRvU3RhdGUpID0+XG4gKiAge1xuICogICByZXR1cm4gZnJvbVN0YXRlID09IFwib2ZmXCIgJiYgdG9TdGF0ZSA9PSBcIm9uXCI7XG4gKiAgfSxcbiAqICBhbmltYXRlKFwiMXMgMHNcIikpXG4gKiBgYGBcbiAqXG4gKiAjIyMgQW5pbWF0aW5nIHRvIHRoZSBmaW5hbCBzdGF0ZVxuICpcbiAqIElmIHRoZSBmaW5hbCBzdGVwIGluIGEgdHJhbnNpdGlvbiBpcyBhIGNhbGwgdG8gYGFuaW1hdGUoKWAgdGhhdCB1c2VzIGEgdGltaW5nIHZhbHVlXG4gKiB3aXRoIG5vIHN0eWxlIGRhdGEsIHRoYXQgc3RlcCBpcyBhdXRvbWF0aWNhbGx5IGNvbnNpZGVyZWQgdGhlIGZpbmFsIGFuaW1hdGlvbiBhcmMsXG4gKiBmb3IgdGhlIGVsZW1lbnQgdG8gcmVhY2ggdGhlIGZpbmFsIHN0YXRlLiBBbmd1bGFyIGF1dG9tYXRpY2FsbHkgYWRkcyBvciByZW1vdmVzXG4gKiBDU1Mgc3R5bGVzIHRvIGVuc3VyZSB0aGF0IHRoZSBlbGVtZW50IGlzIGluIHRoZSBjb3JyZWN0IGZpbmFsIHN0YXRlLlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBkZWZpbmVzIGEgdHJhbnNpdGlvbiB0aGF0IHN0YXJ0cyBieSBoaWRpbmcgdGhlIGVsZW1lbnQsXG4gKiB0aGVuIG1ha2VzIHN1cmUgdGhhdCBpdCBhbmltYXRlcyBwcm9wZXJseSB0byB3aGF0ZXZlciBzdGF0ZSBpcyBjdXJyZW50bHkgYWN0aXZlIGZvciB0cmlnZ2VyOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyYW5zaXRpb24oXCJ2b2lkID0+ICpcIiwgW1xuICogICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgIGFuaW1hdGUoNTAwKVxuICogIF0pXG4gKiBgYGBcbiAqICMjIyBCb29sZWFuIHZhbHVlIG1hdGNoaW5nXG4gKiBJZiBhIHRyaWdnZXIgYmluZGluZyB2YWx1ZSBpcyBhIEJvb2xlYW4sIGl0IGNhbiBiZSBtYXRjaGVkIHVzaW5nIGEgdHJhbnNpdGlvbiBleHByZXNzaW9uXG4gKiB0aGF0IGNvbXBhcmVzIHRydWUgYW5kIGZhbHNlIG9yIDEgYW5kIDAuIEZvciBleGFtcGxlOlxuICpcbiAqIGBgYFxuICogLy8gaW4gdGhlIHRlbXBsYXRlXG4gKiA8ZGl2IFtAb3BlbkNsb3NlXT1cIm9wZW4gPyB0cnVlIDogZmFsc2VcIj4uLi48L2Rpdj5cbiAqIC8vIGluIHRoZSBjb21wb25lbnQgbWV0YWRhdGFcbiAqIHRyaWdnZXIoJ29wZW5DbG9zZScsIFtcbiAqICAgc3RhdGUoJ3RydWUnLCBzdHlsZSh7IGhlaWdodDogJyonIH0pKSxcbiAqICAgc3RhdGUoJ2ZhbHNlJywgc3R5bGUoeyBoZWlnaHQ6ICcwcHgnIH0pKSxcbiAqICAgdHJhbnNpdGlvbignZmFsc2UgPD0+IHRydWUnLCBhbmltYXRlKDUwMCkpXG4gKiBdKVxuICogYGBgXG4gKiovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNpdGlvbihcbiAgICBzdGF0ZUNoYW5nZUV4cHI6IHN0cmluZyB8ICgoZnJvbVN0YXRlOiBzdHJpbmcsIHRvU3RhdGU6IHN0cmluZywgZWxlbWVudD86IGFueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zPzoge1trZXk6IHN0cmluZ106IGFueX0pID0+IGJvb2xlYW4pLFxuICAgIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10sXG4gICAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsKTogQW5pbWF0aW9uVHJhbnNpdGlvbk1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuVHJhbnNpdGlvbiwgZXhwcjogc3RhdGVDaGFuZ2VFeHByLCBhbmltYXRpb246IHN0ZXBzLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBQcm9kdWNlcyBhIHJldXNhYmxlIGFuaW1hdGlvbiB0aGF0IGNhbiBiZSBpbnZva2VkIGluIGFub3RoZXIgYW5pbWF0aW9uIG9yIHNlcXVlbmNlLFxuICogYnkgY2FsbGluZyB0aGUgYHVzZUFuaW1hdGlvbigpYCBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0gc3RlcHMgT25lIG9yIG1vcmUgYW5pbWF0aW9uIG9iamVjdHMsIGFzIHJldHVybmVkIGJ5IHRoZSBgYW5pbWF0ZSgpYFxuICogb3IgYHNlcXVlbmNlKClgIGZ1bmN0aW9uLCB0aGF0IGZvcm0gYSB0cmFuc2Zvcm1hdGlvbiBmcm9tIG9uZSBzdGF0ZSB0byBhbm90aGVyLlxuICogQSBzZXF1ZW5jZSBpcyB1c2VkIGJ5IGRlZmF1bHQgd2hlbiB5b3UgcGFzcyBhbiBhcnJheS5cbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBkZWxheSB2YWx1ZSBmb3IgdGhlIHN0YXJ0IG9mIHRoZVxuICogYW5pbWF0aW9uLCBhbmQgYWRkaXRpb25hbCBkZXZlbG9wZXItZGVmaW5lZCBwYXJhbWV0ZXJzLlxuICogUHJvdmlkZWQgdmFsdWVzIGZvciBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgYXJlIHVzZWQgYXMgZGVmYXVsdHMsXG4gKiBhbmQgb3ZlcnJpZGUgdmFsdWVzIGNhbiBiZSBwYXNzZWQgdG8gdGhlIGNhbGxlciBvbiBpbnZvY2F0aW9uLlxuICogQHJldHVybnMgQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIHRoZSBhbmltYXRpb24gZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIGRlZmluZXMgYSByZXVzYWJsZSBhbmltYXRpb24sIHByb3ZpZGluZyBzb21lIGRlZmF1bHQgcGFyYW1ldGVyXG4gKiB2YWx1ZXMuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdmFyIGZhZGVBbmltYXRpb24gPSBhbmltYXRpb24oW1xuICogICBzdHlsZSh7IG9wYWNpdHk6ICd7eyBzdGFydCB9fScgfSksXG4gKiAgIGFuaW1hdGUoJ3t7IHRpbWUgfX0nLFxuICogICBzdHlsZSh7IG9wYWNpdHk6ICd7eyBlbmQgfX0nfSkpXG4gKiAgIF0sXG4gKiAgIHsgcGFyYW1zOiB7IHRpbWU6ICcxMDAwbXMnLCBzdGFydDogMCwgZW5kOiAxIH19KTtcbiAqIGBgYFxuICpcbiAqIFRoZSBmb2xsb3dpbmcgaW52b2tlcyB0aGUgZGVmaW5lZCBhbmltYXRpb24gd2l0aCBhIGNhbGwgdG8gYHVzZUFuaW1hdGlvbigpYCxcbiAqIHBhc3NpbmcgaW4gb3ZlcnJpZGUgcGFyYW1ldGVyIHZhbHVlcy5cbiAqXG4gKiBgYGBqc1xuICogdXNlQW5pbWF0aW9uKGZhZGVBbmltYXRpb24sIHtcbiAqICAgcGFyYW1zOiB7XG4gKiAgICAgdGltZTogJzJzJyxcbiAqICAgICBzdGFydDogMSxcbiAqICAgICBlbmQ6IDBcbiAqICAgfVxuICogfSlcbiAqIGBgYFxuICpcbiAqIElmIGFueSBvZiB0aGUgcGFzc2VkLWluIHBhcmFtZXRlciB2YWx1ZXMgYXJlIG1pc3NpbmcgZnJvbSB0aGlzIGNhbGwsXG4gKiB0aGUgZGVmYXVsdCB2YWx1ZXMgYXJlIHVzZWQuIElmIG9uZSBvciBtb3JlIHBhcmFtZXRlciB2YWx1ZXMgYXJlIG1pc3NpbmcgYmVmb3JlIGEgc3RlcCBpc1xuICogYW5pbWF0ZWQsIGB1c2VBbmltYXRpb24oKWAgdGhyb3dzIGFuIGVycm9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5pbWF0aW9uKFxuICAgIHN0ZXBzOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10sXG4gICAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsKTogQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5SZWZlcmVuY2UsIGFuaW1hdGlvbjogc3RlcHMsIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIEV4ZWN1dGVzIGEgcXVlcmllZCBpbm5lciBhbmltYXRpb24gZWxlbWVudCB3aXRoaW4gYW4gYW5pbWF0aW9uIHNlcXVlbmNlLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIEFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBkZWxheSB2YWx1ZSBmb3IgdGhlIHN0YXJ0IG9mIHRoZVxuICogYW5pbWF0aW9uLCBhbmQgYWRkaXRpb25hbCBvdmVycmlkZSB2YWx1ZXMgZm9yIGRldmVsb3Blci1kZWZpbmVkIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgY2hpbGQgYW5pbWF0aW9uIGRhdGEuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIEVhY2ggdGltZSBhbiBhbmltYXRpb24gaXMgdHJpZ2dlcmVkIGluIEFuZ3VsYXIsIHRoZSBwYXJlbnQgYW5pbWF0aW9uXG4gKiBoYXMgcHJpb3JpdHkgYW5kIGFueSBjaGlsZCBhbmltYXRpb25zIGFyZSBibG9ja2VkLiBJbiBvcmRlclxuICogZm9yIGEgY2hpbGQgYW5pbWF0aW9uIHRvIHJ1biwgdGhlIHBhcmVudCBhbmltYXRpb24gbXVzdCBxdWVyeSBlYWNoIG9mIHRoZSBlbGVtZW50c1xuICogY29udGFpbmluZyBjaGlsZCBhbmltYXRpb25zLCBhbmQgcnVuIHRoZW0gdXNpbmcgdGhpcyBmdW5jdGlvbi5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBmZWF0dXJlIGRlc2lnbmVkIHRvIGJlIHVzZWQgd2l0aCBgcXVlcnkoKWAgYW5kIGl0IHdpbGwgb25seSB3b3JrXG4gKiB3aXRoIGFuaW1hdGlvbnMgdGhhdCBhcmUgYXNzaWduZWQgdXNpbmcgdGhlIEFuZ3VsYXIgYW5pbWF0aW9uIGxpYnJhcnkuIENTUyBrZXlmcmFtZXNcbiAqIGFuZCB0cmFuc2l0aW9ucyBhcmUgbm90IGhhbmRsZWQgYnkgdGhpcyBBUEkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmltYXRlQ2hpbGQob3B0aW9uczogQW5pbWF0ZUNoaWxkT3B0aW9ucyB8IG51bGwgPSBudWxsKTpcbiAgICBBbmltYXRpb25BbmltYXRlQ2hpbGRNZXRhZGF0YSB7XG4gIHJldHVybiB7dHlwZTogQW5pbWF0aW9uTWV0YWRhdGFUeXBlLkFuaW1hdGVDaGlsZCwgb3B0aW9uc307XG59XG5cbi8qKlxuICogU3RhcnRzIGEgcmV1c2FibGUgYW5pbWF0aW9uIHRoYXQgaXMgY3JlYXRlZCB1c2luZyB0aGUgYGFuaW1hdGlvbigpYCBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0gYW5pbWF0aW9uIFRoZSByZXVzYWJsZSBhbmltYXRpb24gdG8gc3RhcnQuXG4gKiBAcGFyYW0gb3B0aW9ucyBBbiBvcHRpb25zIG9iamVjdCB0aGF0IGNhbiBjb250YWluIGEgZGVsYXkgdmFsdWUgZm9yIHRoZSBzdGFydCBvZiBcbiAqIHRoZSBhbmltYXRpb24sIGFuZCBhZGRpdGlvbmFsIG92ZXJyaWRlIHZhbHVlcyBmb3IgZGV2ZWxvcGVyLWRlZmluZWQgcGFyYW1ldGVycy5cbiAqIEByZXR1cm4gQW4gb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIGFuaW1hdGlvbiBwYXJhbWV0ZXJzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQW5pbWF0aW9uKFxuICAgIGFuaW1hdGlvbjogQW5pbWF0aW9uUmVmZXJlbmNlTWV0YWRhdGEsXG4gICAgb3B0aW9uczogQW5pbWF0aW9uT3B0aW9ucyB8IG51bGwgPSBudWxsKTogQW5pbWF0aW9uQW5pbWF0ZVJlZk1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuQW5pbWF0ZVJlZiwgYW5pbWF0aW9uLCBvcHRpb25zfTtcbn1cblxuLyoqXG4gKiBGaW5kcyBvbmUgb3IgbW9yZSBpbm5lciBlbGVtZW50cyB3aXRoaW4gdGhlIGN1cnJlbnQgZWxlbWVudCB0aGF0IGlzXG4gKiBiZWluZyBhbmltYXRlZCB3aXRoaW4gYSBzZXF1ZW5jZS4gVXNlIHdpdGggYGFuaW1hdGVDaGlsZCgpYC5cbiAqXG4gKiBAcGFyYW0gc2VsZWN0b3IgVGhlIGVsZW1lbnQgdG8gcXVlcnksIG9yIGEgc2V0IG9mIGVsZW1lbnRzIHRoYXQgY29udGFpbiBBbmd1bGFyLXNwZWNpZmljXG4gKiBjaGFyYWN0ZXJpc3RpY3MsIHNwZWNpZmllZCB3aXRoIG9uZSBvciBtb3JlIG9mIHRoZSBmb2xsb3dpbmcgdG9rZW5zLlxuICogIC0gYHF1ZXJ5KFwiOmVudGVyXCIpYCBvciBgcXVlcnkoXCI6bGVhdmVcIilgIDogUXVlcnkgZm9yIG5ld2x5IGluc2VydGVkL3JlbW92ZWQgZWxlbWVudHMuXG4gKiAgLSBgcXVlcnkoXCI6YW5pbWF0aW5nXCIpYCA6IFF1ZXJ5IGFsbCBjdXJyZW50bHkgYW5pbWF0aW5nIGVsZW1lbnRzLlxuICogIC0gYHF1ZXJ5KFwiQHRyaWdnZXJOYW1lXCIpYCA6IFF1ZXJ5IGVsZW1lbnRzIHRoYXQgY29udGFpbiBhbiBhbmltYXRpb24gdHJpZ2dlci5cbiAqICAtIGBxdWVyeShcIkAqXCIpYCA6IFF1ZXJ5IGFsbCBlbGVtZW50cyB0aGF0IGNvbnRhaW4gYW4gYW5pbWF0aW9uIHRyaWdnZXJzLlxuICogIC0gYHF1ZXJ5KFwiOnNlbGZcIilgIDogSW5jbHVkZSB0aGUgY3VycmVudCBlbGVtZW50IGludG8gdGhlIGFuaW1hdGlvbiBzZXF1ZW5jZS5cbiAqXG4gKiBAcGFyYW0gYW5pbWF0aW9uIE9uZSBvciBtb3JlIGFuaW1hdGlvbiBzdGVwcyB0byBhcHBseSB0byB0aGUgcXVlcmllZCBlbGVtZW50IG9yIGVsZW1lbnRzLlxuICogQW4gYXJyYXkgaXMgdHJlYXRlZCBhcyBhbiBhbmltYXRpb24gc2VxdWVuY2UuXG4gKiBAcGFyYW0gb3B0aW9ucyBBbiBvcHRpb25zIG9iamVjdC4gVXNlIHRoZSAnbGltaXQnIGZpZWxkIHRvIGxpbWl0IHRoZSB0b3RhbCBudW1iZXIgb2ZcbiAqIGl0ZW1zIHRvIGNvbGxlY3QuXG4gKiBAcmV0dXJuIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgcXVlcnkgZGF0YS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVG9rZW5zIGNhbiBiZSBtZXJnZWQgaW50byBhIGNvbWJpbmVkIHF1ZXJ5IHNlbGVjdG9yIHN0cmluZy4gRm9yIGV4YW1wbGU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogIHF1ZXJ5KCc6c2VsZiwgLnJlY29yZDplbnRlciwgLnJlY29yZDpsZWF2ZSwgQHN1YlRyaWdnZXInLCBbLi4uXSlcbiAqIGBgYFxuICpcbiAqIFRoZSBgcXVlcnkoKWAgZnVuY3Rpb24gY29sbGVjdHMgbXVsdGlwbGUgZWxlbWVudHMgYW5kIHdvcmtzIGludGVybmFsbHkgYnkgdXNpbmdcbiAqIGBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGxgLiBVc2UgdGhlIGBsaW1pdGAgZmllbGQgb2YgYW4gb3B0aW9ucyBvYmplY3QgdG8gbGltaXRcbiAqIHRoZSB0b3RhbCBudW1iZXIgb2YgaXRlbXMgdG8gYmUgY29sbGVjdGVkLiBGb3IgZXhhbXBsZTpcbiAqXG4gKiBgYGBqc1xuICogcXVlcnkoJ2RpdicsIFtcbiAqICAgYW5pbWF0ZSguLi4pLFxuICogICBhbmltYXRlKC4uLilcbiAqIF0sIHsgbGltaXQ6IDEgfSlcbiAqIGBgYFxuICpcbiAqIEJ5IGRlZmF1bHQsIHRocm93cyBhbiBlcnJvciB3aGVuIHplcm8gaXRlbXMgYXJlIGZvdW5kLiBTZXQgdGhlXG4gKiBgb3B0aW9uYWxgIGZsYWcgdG8gaWdub3JlIHRoaXMgZXJyb3IuIEZvciBleGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiBxdWVyeSgnLnNvbWUtZWxlbWVudC10aGF0LW1heS1ub3QtYmUtdGhlcmUnLCBbXG4gKiAgIGFuaW1hdGUoLi4uKSxcbiAqICAgYW5pbWF0ZSguLi4pXG4gKiBdLCB7IG9wdGlvbmFsOiB0cnVlIH0pXG4gKiBgYGBcbiAqXG4gKiAjIyMgVXNhZ2UgRXhhbXBsZVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBxdWVyaWVzIGZvciBpbm5lciBlbGVtZW50cyBhbmQgYW5pbWF0ZXMgdGhlbVxuICogaW5kaXZpZHVhbGx5IHVzaW5nIGBhbmltYXRlQ2hpbGQoKWAuIFxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2lubmVyJyxcbiAqICAgdGVtcGxhdGU6IGBcbiAqICAgICA8ZGl2IFtAcXVlcnlBbmltYXRpb25dPVwiZXhwXCI+XG4gKiAgICAgICA8aDE+VGl0bGU8L2gxPlxuICogICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnRcIj5cbiAqICAgICAgICAgQmxhaCBibGFoIGJsYWhcbiAqICAgICAgIDwvZGl2PlxuICogICAgIDwvZGl2PlxuICogICBgLFxuICogICBhbmltYXRpb25zOiBbXG4gKiAgICB0cmlnZ2VyKCdxdWVyeUFuaW1hdGlvbicsIFtcbiAqICAgICAgdHJhbnNpdGlvbignKiA9PiBnb0FuaW1hdGUnLCBbXG4gKiAgICAgICAgLy8gaGlkZSB0aGUgaW5uZXIgZWxlbWVudHNcbiAqICAgICAgICBxdWVyeSgnaDEnLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpLFxuICogICAgICAgIHF1ZXJ5KCcuY29udGVudCcsIHN0eWxlKHsgb3BhY2l0eTogMCB9KSksXG4gKlxuICogICAgICAgIC8vIGFuaW1hdGUgdGhlIGlubmVyIGVsZW1lbnRzIGluLCBvbmUgYnkgb25lXG4gKiAgICAgICAgcXVlcnkoJ2gxJywgYW5pbWF0ZSgxMDAwLCBzdHlsZSh7IG9wYWNpdHk6IDEgfSkpLFxuICogICAgICAgIHF1ZXJ5KCcuY29udGVudCcsIGFuaW1hdGUoMTAwMCwgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKSxcbiAqICAgICAgXSlcbiAqICAgIF0pXG4gKiAgXVxuICogfSlcbiAqIGNsYXNzIENtcCB7XG4gKiAgIGV4cCA9ICcnO1xuICpcbiAqICAgZ29BbmltYXRlKCkge1xuICogICAgIHRoaXMuZXhwID0gJ2dvQW5pbWF0ZSc7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcXVlcnkoXG4gICAgc2VsZWN0b3I6IHN0cmluZywgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10sXG4gICAgb3B0aW9uczogQW5pbWF0aW9uUXVlcnlPcHRpb25zIHwgbnVsbCA9IG51bGwpOiBBbmltYXRpb25RdWVyeU1ldGFkYXRhIHtcbiAgcmV0dXJuIHt0eXBlOiBBbmltYXRpb25NZXRhZGF0YVR5cGUuUXVlcnksIHNlbGVjdG9yLCBhbmltYXRpb24sIG9wdGlvbnN9O1xufVxuXG4vKipcbiAqIFVzZSB3aXRoaW4gYW4gYW5pbWF0aW9uIGBxdWVyeSgpYCBjYWxsIHRvIGlzc3VlIGEgdGltaW5nIGdhcCBhZnRlclxuICogZWFjaCBxdWVyaWVkIGl0ZW0gaXMgYW5pbWF0ZWQuXG4gKlxuICogQHBhcmFtIHRpbWluZ3MgQSBkZWxheSB2YWx1ZS5cbiAqIEBwYXJhbSBhbmltYXRpb24gT25lIG9yZSBtb3JlIGFuaW1hdGlvbiBzdGVwcy5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCB0aGF0IGVuY2Fwc3VsYXRlcyB0aGUgc3RhZ2dlciBkYXRhLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBJbiB0aGUgZm9sbG93aW5nIGV4YW1wbGUsIGEgY29udGFpbmVyIGVsZW1lbnQgd3JhcHMgYSBsaXN0IG9mIGl0ZW1zIHN0YW1wZWQgb3V0XG4gKiBieSBhbiBgbmdGb3JgLiBUaGUgY29udGFpbmVyIGVsZW1lbnQgY29udGFpbnMgYW4gYW5pbWF0aW9uIHRyaWdnZXIgdGhhdCB3aWxsIGxhdGVyIGJlIHNldFxuICogdG8gcXVlcnkgZm9yIGVhY2ggb2YgdGhlIGlubmVyIGl0ZW1zLlxuICpcbiAqIEVhY2ggdGltZSBpdGVtcyBhcmUgYWRkZWQsIHRoZSBvcGFjaXR5IGZhZGUtaW4gYW5pbWF0aW9uIHJ1bnMsXG4gKiBhbmQgZWFjaCByZW1vdmVkIGl0ZW0gaXMgZmFkZWQgb3V0LlxuICogV2hlbiBlaXRoZXIgb2YgdGhlc2UgYW5pbWF0aW9ucyBvY2N1ciwgdGhlIHN0YWdnZXIgZWZmZWN0IGlzXG4gKiBhcHBsaWVkIGFmdGVyIGVhY2ggaXRlbSdzIGFuaW1hdGlvbiBpcyBzdGFydGVkLlxuICpcbiAqIGBgYGh0bWxcbiAqIDwhLS0gbGlzdC5jb21wb25lbnQuaHRtbCAtLT5cbiAqIDxidXR0b24gKGNsaWNrKT1cInRvZ2dsZSgpXCI+U2hvdyAvIEhpZGUgSXRlbXM8L2J1dHRvbj5cbiAqIDxociAvPlxuICogPGRpdiBbQGxpc3RBbmltYXRpb25dPVwiaXRlbXMubGVuZ3RoXCI+XG4gKiAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIj5cbiAqICAgICB7eyBpdGVtIH19XG4gKiAgIDwvZGl2PlxuICogPC9kaXY+XG4gKiBgYGBcbiAqXG4gKiBIZXJlIGlzIHRoZSBjb21wb25lbnQgY29kZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQge3RyaWdnZXIsIHRyYW5zaXRpb24sIHN0eWxlLCBhbmltYXRlLCBxdWVyeSwgc3RhZ2dlcn0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG4gKiBAQ29tcG9uZW50KHtcbiAqICAgdGVtcGxhdGVVcmw6ICdsaXN0LmNvbXBvbmVudC5odG1sJyxcbiAqICAgYW5pbWF0aW9uczogW1xuICogICAgIHRyaWdnZXIoJ2xpc3RBbmltYXRpb24nLCBbXG4gKiAgICAgLi4uXG4gKiAgICAgXSlcbiAqICAgXVxuICogfSlcbiAqIGNsYXNzIExpc3RDb21wb25lbnQge1xuICogICBpdGVtcyA9IFtdO1xuICpcbiAqICAgc2hvd0l0ZW1zKCkge1xuICogICAgIHRoaXMuaXRlbXMgPSBbMCwxLDIsMyw0XTtcbiAqICAgfVxuICpcbiAqICAgaGlkZUl0ZW1zKCkge1xuICogICAgIHRoaXMuaXRlbXMgPSBbXTtcbiAqICAgfVxuICpcbiAqICAgdG9nZ2xlKCkge1xuICogICAgIHRoaXMuaXRlbXMubGVuZ3RoID8gdGhpcy5oaWRlSXRlbXMoKSA6IHRoaXMuc2hvd0l0ZW1zKCk7XG4gKiAgICB9XG4gKiAgfVxuICogYGBgXG4gKlxuICogSGVyZSBpcyB0aGUgYW5pbWF0aW9uIHRyaWdnZXIgY29kZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB0cmlnZ2VyKCdsaXN0QW5pbWF0aW9uJywgW1xuICogICB0cmFuc2l0aW9uKCcqID0+IConLCBbIC8vIGVhY2ggdGltZSB0aGUgYmluZGluZyB2YWx1ZSBjaGFuZ2VzXG4gKiAgICAgcXVlcnkoJzpsZWF2ZScsIFtcbiAqICAgICAgIHN0YWdnZXIoMTAwLCBbXG4gKiAgICAgICAgIGFuaW1hdGUoJzAuNXMnLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpXG4gKiAgICAgICBdKVxuICogICAgIF0pLFxuICogICAgIHF1ZXJ5KCc6ZW50ZXInLCBbXG4gKiAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDAgfSksXG4gKiAgICAgICBzdGFnZ2VyKDEwMCwgW1xuICogICAgICAgICBhbmltYXRlKCcwLjVzJywgc3R5bGUoeyBvcGFjaXR5OiAxIH0pKVxuICogICAgICAgXSlcbiAqICAgICBdKVxuICogICBdKVxuICogXSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhZ2dlcihcbiAgICB0aW1pbmdzOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgYW5pbWF0aW9uOiBBbmltYXRpb25NZXRhZGF0YSB8IEFuaW1hdGlvbk1ldGFkYXRhW10pOiBBbmltYXRpb25TdGFnZ2VyTWV0YWRhdGEge1xuICByZXR1cm4ge3R5cGU6IEFuaW1hdGlvbk1ldGFkYXRhVHlwZS5TdGFnZ2VyLCB0aW1pbmdzLCBhbmltYXRpb259O1xufVxuIl19
|