@angular/core 9.0.0-rc.9 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/core-testing.umd.js +10 -9
- package/bundles/core-testing.umd.js.map +1 -1
- package/bundles/core-testing.umd.min.js +6 -6
- package/bundles/core-testing.umd.min.js.map +1 -1
- package/bundles/core.umd.js +3619 -3914
- package/bundles/core.umd.js.map +1 -1
- package/bundles/core.umd.min.js +182 -175
- package/bundles/core.umd.min.js.map +1 -1
- package/core.d.ts +483 -651
- package/core.metadata.json +1 -1
- package/esm2015/core.js +17 -17
- package/esm2015/index.js +2 -2
- package/esm2015/public_api.js +2 -2
- package/esm2015/src/application_ref.js +7 -7
- package/esm2015/src/core.js +3 -3
- package/esm2015/src/core_private_export.js +7 -7
- package/esm2015/src/core_render3_private_export.js +2 -2
- package/esm2015/src/debug/debug_node.js +44 -12
- package/esm2015/src/i18n/locale_data_api.js +1 -2
- package/esm2015/src/interface/type.js +1 -1
- package/esm2015/src/metadata/ng_module.js +1 -1
- package/esm2015/src/render/api.js +4 -1
- package/esm2015/src/render3/assert.js +9 -1
- package/esm2015/src/render3/bindings.js +16 -5
- package/esm2015/src/render3/component.js +54 -25
- package/esm2015/src/render3/component_ref.js +11 -15
- package/esm2015/src/render3/definition.js +3 -1
- package/esm2015/src/render3/di.js +3 -4
- package/esm2015/src/render3/di_setup.js +5 -7
- package/esm2015/src/render3/errors.js +3 -1
- package/esm2015/src/render3/features/inherit_definition_feature.js +41 -13
- package/esm2015/src/render3/features/ng_onchanges_feature.js +2 -2
- package/esm2015/src/render3/global_utils_api.js +3 -3
- package/esm2015/src/render3/i18n.js +60 -56
- package/esm2015/src/render3/index.js +2 -2
- package/esm2015/src/render3/instructions/advance.js +10 -11
- package/esm2015/src/render3/instructions/all.js +4 -5
- package/esm2015/src/render3/instructions/attribute.js +6 -6
- package/esm2015/src/render3/instructions/attribute_interpolation.js +40 -21
- package/esm2015/src/render3/instructions/change_detection.js +8 -23
- package/esm2015/src/render3/instructions/class_map_interpolation.js +13 -12
- package/esm2015/src/render3/instructions/container.js +15 -12
- package/esm2015/src/render3/instructions/element.js +40 -127
- package/esm2015/src/render3/instructions/element_container.js +8 -10
- package/esm2015/src/render3/instructions/embedded_view.js +7 -7
- package/esm2015/src/render3/instructions/host_property.js +10 -7
- package/esm2015/src/render3/instructions/listener.js +18 -16
- package/esm2015/src/render3/instructions/lview_debug.js +160 -23
- package/esm2015/src/render3/instructions/projection.js +7 -5
- package/esm2015/src/render3/instructions/property.js +27 -6
- package/esm2015/src/render3/instructions/property_interpolation.js +40 -22
- package/esm2015/src/render3/instructions/shared.js +267 -240
- package/esm2015/src/render3/instructions/storage.js +6 -8
- package/esm2015/src/render3/instructions/style_prop_interpolation.js +12 -12
- package/esm2015/src/render3/instructions/styling.js +731 -475
- package/esm2015/src/render3/instructions/text.js +5 -5
- package/esm2015/src/render3/interfaces/definition.js +41 -1
- package/esm2015/src/render3/interfaces/node.js +160 -115
- package/esm2015/src/render3/interfaces/styling.js +183 -375
- package/esm2015/src/render3/interfaces/view.js +10 -2
- package/esm2015/src/render3/jit/environment.js +1 -3
- package/esm2015/src/render3/node_manipulation.js +177 -57
- package/esm2015/src/render3/node_selector_matcher.js +39 -24
- package/esm2015/src/render3/node_util.js +12 -7
- package/esm2015/src/render3/pipe.js +4 -6
- package/esm2015/src/render3/query.js +32 -26
- package/esm2015/src/render3/state.js +54 -183
- package/esm2015/src/render3/styling/class_differ.js +47 -0
- package/esm2015/src/render3/styling/static_styling.js +54 -0
- package/esm2015/src/render3/styling/style_binding_list.js +437 -0
- package/esm2015/src/render3/styling/styling_parser.js +336 -0
- package/esm2015/src/render3/tokens.js +2 -2
- package/esm2015/src/render3/util/attrs_utils.js +125 -2
- package/esm2015/src/render3/util/change_detection_utils.js +33 -0
- package/esm2015/src/render3/util/discovery_utils.js +146 -119
- package/esm2015/src/render3/util/global_utils.js +5 -5
- package/esm2015/src/render3/util/view_utils.js +6 -6
- package/esm2015/src/render3/view_engine_compatibility.js +16 -17
- package/esm2015/src/render3/view_ref.js +16 -13
- package/esm2015/src/sanitization/bypass.js +1 -1
- package/esm2015/src/sanitization/sanitization.js +20 -5
- package/esm2015/src/util/array_utils.js +240 -1
- package/esm2015/src/util/assert.js +37 -21
- package/esm2015/src/util/char_code.js +8 -0
- package/esm2015/src/util/iterable.js +4 -1
- package/esm2015/src/util/ng_dev_mode.js +1 -12
- package/esm2015/src/util/stringify.js +14 -1
- package/esm2015/src/version.js +1 -1
- package/esm2015/testing/src/r3_test_bed.js +5 -1
- package/esm2015/testing/src/r3_test_bed_compiler.js +2 -12
- package/esm2015/testing/src/styling.js +103 -0
- package/esm5/core.js +17 -17
- package/esm5/src/application_ref.js +6 -6
- package/esm5/src/core_private_export.js +7 -7
- package/esm5/src/core_render3_private_export.js +2 -2
- package/esm5/src/debug/debug_node.js +29 -11
- package/esm5/src/i18n/locale_data_api.js +1 -2
- package/esm5/src/interface/type.js +1 -1
- package/esm5/src/metadata/ng_module.js +1 -1
- package/esm5/src/render/api.js +4 -1
- package/esm5/src/render3/assert.js +4 -1
- package/esm5/src/render3/bindings.js +19 -2
- package/esm5/src/render3/component.js +47 -22
- package/esm5/src/render3/component_ref.js +9 -14
- package/esm5/src/render3/definition.js +3 -1
- package/esm5/src/render3/di.js +3 -4
- package/esm5/src/render3/di_setup.js +4 -5
- package/esm5/src/render3/errors.js +3 -1
- package/esm5/src/render3/features/inherit_definition_feature.js +36 -12
- package/esm5/src/render3/features/ng_onchanges_feature.js +1 -1
- package/esm5/src/render3/global_utils_api.js +3 -3
- package/esm5/src/render3/i18n.js +51 -51
- package/esm5/src/render3/index.js +2 -2
- package/esm5/src/render3/instructions/advance.js +9 -11
- package/esm5/src/render3/instructions/all.js +1 -2
- package/esm5/src/render3/instructions/attribute.js +5 -6
- package/esm5/src/render3/instructions/attribute_interpolation.js +31 -21
- package/esm5/src/render3/instructions/change_detection.js +8 -21
- package/esm5/src/render3/instructions/class_map_interpolation.js +13 -12
- package/esm5/src/render3/instructions/container.js +13 -12
- package/esm5/src/render3/instructions/element.js +36 -108
- package/esm5/src/render3/instructions/element_container.js +8 -9
- package/esm5/src/render3/instructions/embedded_view.js +7 -7
- package/esm5/src/render3/instructions/host_property.js +8 -7
- package/esm5/src/render3/instructions/listener.js +13 -13
- package/esm5/src/render3/instructions/lview_debug.js +56 -15
- package/esm5/src/render3/instructions/projection.js +6 -5
- package/esm5/src/render3/instructions/property.js +17 -6
- package/esm5/src/render3/instructions/property_interpolation.js +31 -23
- package/esm5/src/render3/instructions/shared.js +247 -207
- package/esm5/src/render3/instructions/storage.js +4 -6
- package/esm5/src/render3/instructions/style_prop_interpolation.js +12 -12
- package/esm5/src/render3/instructions/styling.js +685 -367
- package/esm5/src/render3/instructions/text.js +5 -5
- package/esm5/src/render3/interfaces/definition.js +1 -1
- package/esm5/src/render3/interfaces/node.js +49 -1
- package/esm5/src/render3/interfaces/styling.js +57 -1
- package/esm5/src/render3/interfaces/view.js +1 -1
- package/esm5/src/render3/jit/environment.js +1 -3
- package/esm5/src/render3/node_manipulation.js +167 -54
- package/esm5/src/render3/node_selector_matcher.js +40 -20
- package/esm5/src/render3/node_util.js +12 -7
- package/esm5/src/render3/pipe.js +4 -6
- package/esm5/src/render3/query.js +25 -24
- package/esm5/src/render3/state.js +34 -131
- package/esm5/src/render3/styling/class_differ.js +39 -0
- package/esm5/src/render3/styling/static_styling.js +42 -0
- package/esm5/src/render3/styling/style_binding_list.js +411 -0
- package/esm5/src/render3/styling/styling_parser.js +265 -0
- package/esm5/src/render3/tokens.js +2 -2
- package/esm5/src/render3/util/attrs_utils.js +117 -2
- package/esm5/src/render3/util/change_detection_utils.js +23 -0
- package/esm5/src/render3/util/discovery_utils.js +115 -99
- package/esm5/src/render3/util/global_utils.js +5 -5
- package/esm5/src/render3/util/view_utils.js +5 -5
- package/esm5/src/render3/view_engine_compatibility.js +37 -39
- package/esm5/src/render3/view_ref.js +14 -13
- package/esm5/src/sanitization/bypass.js +1 -1
- package/esm5/src/sanitization/sanitization.js +16 -5
- package/esm5/src/util/array_utils.js +240 -1
- package/esm5/src/util/assert.js +37 -21
- package/esm5/src/util/char_code.js +8 -0
- package/esm5/src/util/iterable.js +4 -1
- package/esm5/src/util/ng_dev_mode.js +1 -12
- package/esm5/src/util/stringify.js +14 -1
- package/esm5/src/version.js +1 -1
- package/esm5/testing/src/r3_test_bed.js +9 -1
- package/esm5/testing/src/r3_test_bed_compiler.js +2 -9
- package/esm5/testing/src/styling.js +82 -0
- package/fesm2015/core.js +5917 -6880
- package/fesm2015/core.js.map +1 -1
- package/fesm2015/testing.js +6 -12
- package/fesm2015/testing.js.map +1 -1
- package/fesm5/core.js +3588 -3884
- package/fesm5/core.js.map +1 -1
- package/fesm5/testing.js +10 -9
- package/fesm5/testing.js.map +1 -1
- package/package.json +1 -1
- package/src/r3_symbols.d.ts +1 -1
- package/testing/testing.d.ts +1 -3
- package/testing/testing.metadata.json +1 -1
- package/testing.d.ts +1 -1
- package/esm2015/global.js +0 -7
- package/esm2015/src/render3/instructions/alloc_host_vars.js +0 -80
- package/esm2015/src/render3/styling/bindings.js +0 -1248
- package/esm2015/src/render3/styling/map_based_bindings.js +0 -384
- package/esm2015/src/render3/styling/state.js +0 -135
- package/esm2015/src/render3/styling/styling_debug.js +0 -655
- package/esm2015/src/render3/util/styling_utils.js +0 -625
- package/esm5/global.js +0 -9
- package/esm5/src/render3/instructions/alloc_host_vars.js +0 -62
- package/esm5/src/render3/styling/bindings.js +0 -949
- package/esm5/src/render3/styling/map_based_bindings.js +0 -310
- package/esm5/src/render3/styling/state.js +0 -56
- package/esm5/src/render3/styling/styling_debug.js +0 -315
- package/esm5/src/render3/util/styling_utils.js +0 -378
|
@@ -1,625 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview added by tsickle
|
|
3
|
-
* Generated from: packages/core/src/render3/util/styling_utils.ts
|
|
4
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* @license
|
|
8
|
-
* Copyright Google Inc. All Rights Reserved.
|
|
9
|
-
*
|
|
10
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
11
|
-
* found in the LICENSE file at https://angular.io/license
|
|
12
|
-
*/
|
|
13
|
-
import { unwrapSafeValue } from '../../sanitization/bypass';
|
|
14
|
-
import { NO_CHANGE } from '../tokens';
|
|
15
|
-
/** @type {?} */
|
|
16
|
-
export const MAP_BASED_ENTRY_PROP_NAME = '[MAP]';
|
|
17
|
-
/** @type {?} */
|
|
18
|
-
export const TEMPLATE_DIRECTIVE_INDEX = 0;
|
|
19
|
-
/**
|
|
20
|
-
* Default fallback value for a styling binding.
|
|
21
|
-
*
|
|
22
|
-
* A value of `null` is used here which signals to the styling algorithm that
|
|
23
|
-
* the styling value is not present. This way if there are no other values
|
|
24
|
-
* detected then it will be removed once the style/class property is dirty and
|
|
25
|
-
* diffed within the styling algorithm present in `flushStyling`.
|
|
26
|
-
* @type {?}
|
|
27
|
-
*/
|
|
28
|
-
export const DEFAULT_BINDING_VALUE = null;
|
|
29
|
-
/** @type {?} */
|
|
30
|
-
export const DEFAULT_BINDING_INDEX = 0;
|
|
31
|
-
/** @type {?} */
|
|
32
|
-
const DEFAULT_TOTAL_SOURCES = 1;
|
|
33
|
-
// The first bit value reflects a map-based binding value's bit.
|
|
34
|
-
// The reason why it's always activated for every entry in the map
|
|
35
|
-
// is so that if any map-binding values update then all other prop
|
|
36
|
-
// based bindings will pass the guard check automatically without
|
|
37
|
-
// any extra code or flags.
|
|
38
|
-
/** @type {?} */
|
|
39
|
-
export const DEFAULT_GUARD_MASK_VALUE = 0b1;
|
|
40
|
-
/**
|
|
41
|
-
* Creates a new instance of the `TStylingContext`.
|
|
42
|
-
*
|
|
43
|
-
* The `TStylingContext` is used as a manifest of all style or all class bindings on
|
|
44
|
-
* an element. Because it is a T-level data-structure, it is only created once per
|
|
45
|
-
* tNode for styles and for classes. This function allocates a new instance of a
|
|
46
|
-
* `TStylingContext` with the initial values (see `interfaces.ts` for more info).
|
|
47
|
-
* @param {?} initialStyling
|
|
48
|
-
* @param {?} hasDirectives
|
|
49
|
-
* @return {?}
|
|
50
|
-
*/
|
|
51
|
-
export function allocTStylingContext(initialStyling, hasDirectives) {
|
|
52
|
-
initialStyling = initialStyling || allocStylingMapArray(null);
|
|
53
|
-
return [
|
|
54
|
-
DEFAULT_TOTAL_SOURCES,
|
|
55
|
-
initialStyling,
|
|
56
|
-
];
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* @param {?} value
|
|
60
|
-
* @return {?}
|
|
61
|
-
*/
|
|
62
|
-
export function allocStylingMapArray(value) {
|
|
63
|
-
return [value];
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* @param {?} tNode
|
|
67
|
-
* @param {?} flag
|
|
68
|
-
* @return {?}
|
|
69
|
-
*/
|
|
70
|
-
export function hasConfig(tNode, flag) {
|
|
71
|
-
return (tNode.flags & flag) !== 0;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Determines whether or not to apply styles/classes directly or via context resolution.
|
|
75
|
-
*
|
|
76
|
-
* There are three cases that are matched here:
|
|
77
|
-
* 1. there are no directives present AND `ngDevMode` is falsy
|
|
78
|
-
* 2. the `firstUpdatePass` has not already run (which means that
|
|
79
|
-
* there are more bindings to register and, therefore, direct
|
|
80
|
-
* style/class application is not yet possible)
|
|
81
|
-
* 3. There are no collisions (i.e. properties with more than one binding) across multiple
|
|
82
|
-
* sources (i.e. template + directive, directive + directive, directive + component)
|
|
83
|
-
* @param {?} tNode
|
|
84
|
-
* @param {?} isClassBased
|
|
85
|
-
* @param {?} firstUpdatePass
|
|
86
|
-
* @return {?}
|
|
87
|
-
*/
|
|
88
|
-
export function allowDirectStyling(tNode, isClassBased, firstUpdatePass) {
|
|
89
|
-
/** @type {?} */
|
|
90
|
-
let allow = false;
|
|
91
|
-
// if no directives are present then we do not need populate a context at all. This
|
|
92
|
-
// is because duplicate prop bindings cannot be registered through the template. If
|
|
93
|
-
// and when this happens we can safely apply the value directly without context
|
|
94
|
-
// resolution...
|
|
95
|
-
/** @type {?} */
|
|
96
|
-
const hasDirectives = hasConfig(tNode, 128 /* hasHostBindings */);
|
|
97
|
-
if (!hasDirectives) {
|
|
98
|
-
// `ngDevMode` is required to be checked here because tests/debugging rely on the context being
|
|
99
|
-
// populated. If things are in production mode then there is no need to build a context
|
|
100
|
-
// therefore the direct apply can be allowed (even on the first update).
|
|
101
|
-
allow = ngDevMode ? !firstUpdatePass : true;
|
|
102
|
-
}
|
|
103
|
-
else if (!firstUpdatePass) {
|
|
104
|
-
/** @type {?} */
|
|
105
|
-
const duplicateStylingFlag = isClassBased ? 8192 /* hasDuplicateClassBindings */ : 262144 /* hasDuplicateStyleBindings */;
|
|
106
|
-
/** @type {?} */
|
|
107
|
-
const hasDuplicates = hasConfig(tNode, duplicateStylingFlag);
|
|
108
|
-
/** @type {?} */
|
|
109
|
-
const hasOnlyMapOrPropsFlag = isClassBased ? 1536 /* hasClassPropAndMapBindings */ :
|
|
110
|
-
49152 /* hasStylePropAndMapBindings */;
|
|
111
|
-
/** @type {?} */
|
|
112
|
-
const hasOnlyMapsOrOnlyProps = (tNode.flags & hasOnlyMapOrPropsFlag) !== hasOnlyMapOrPropsFlag;
|
|
113
|
-
allow = !hasDuplicates && hasOnlyMapsOrOnlyProps;
|
|
114
|
-
}
|
|
115
|
-
return allow;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* @param {?} tNode
|
|
119
|
-
* @param {?} flag
|
|
120
|
-
* @return {?}
|
|
121
|
-
*/
|
|
122
|
-
export function patchConfig(tNode, flag) {
|
|
123
|
-
tNode.flags |= flag;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* @param {?} context
|
|
127
|
-
* @param {?} index
|
|
128
|
-
* @return {?}
|
|
129
|
-
*/
|
|
130
|
-
export function getProp(context, index) {
|
|
131
|
-
return (/** @type {?} */ (context[index + 3 /* PropOffset */]));
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* @param {?} context
|
|
135
|
-
* @param {?} index
|
|
136
|
-
* @return {?}
|
|
137
|
-
*/
|
|
138
|
-
function getPropConfig(context, index) {
|
|
139
|
-
return ((/** @type {?} */ (context[index + 0 /* ConfigOffset */]))) &
|
|
140
|
-
1 /* Mask */;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* @param {?} context
|
|
144
|
-
* @param {?} index
|
|
145
|
-
* @return {?}
|
|
146
|
-
*/
|
|
147
|
-
export function isSanitizationRequired(context, index) {
|
|
148
|
-
return (getPropConfig(context, index) & 1 /* SanitizationRequired */) !==
|
|
149
|
-
0;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* @param {?} context
|
|
153
|
-
* @param {?} index
|
|
154
|
-
* @param {?} isHostBinding
|
|
155
|
-
* @return {?}
|
|
156
|
-
*/
|
|
157
|
-
export function getGuardMask(context, index, isHostBinding) {
|
|
158
|
-
/** @type {?} */
|
|
159
|
-
const position = index + (isHostBinding ? 2 /* HostBindingsBitGuardOffset */ :
|
|
160
|
-
1 /* TemplateBitGuardOffset */);
|
|
161
|
-
return (/** @type {?} */ (context[position]));
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* @param {?} context
|
|
165
|
-
* @param {?} index
|
|
166
|
-
* @param {?} maskValue
|
|
167
|
-
* @param {?} isHostBinding
|
|
168
|
-
* @return {?}
|
|
169
|
-
*/
|
|
170
|
-
export function setGuardMask(context, index, maskValue, isHostBinding) {
|
|
171
|
-
/** @type {?} */
|
|
172
|
-
const position = index + (isHostBinding ? 2 /* HostBindingsBitGuardOffset */ :
|
|
173
|
-
1 /* TemplateBitGuardOffset */);
|
|
174
|
-
context[position] = maskValue;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* @param {?} context
|
|
178
|
-
* @return {?}
|
|
179
|
-
*/
|
|
180
|
-
export function getValuesCount(context) {
|
|
181
|
-
return getTotalSources(context) + 1;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* @param {?} context
|
|
185
|
-
* @return {?}
|
|
186
|
-
*/
|
|
187
|
-
export function getTotalSources(context) {
|
|
188
|
-
return context[0 /* TotalSourcesPosition */];
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* @param {?} context
|
|
192
|
-
* @param {?} index
|
|
193
|
-
* @param {?} offset
|
|
194
|
-
* @return {?}
|
|
195
|
-
*/
|
|
196
|
-
export function getBindingValue(context, index, offset) {
|
|
197
|
-
return (/** @type {?} */ (context[index + 4 /* BindingsStartOffset */ + offset]));
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* @param {?} context
|
|
201
|
-
* @param {?} index
|
|
202
|
-
* @return {?}
|
|
203
|
-
*/
|
|
204
|
-
export function getDefaultValue(context, index) {
|
|
205
|
-
return (/** @type {?} */ (context[index + 4 /* BindingsStartOffset */ + getTotalSources(context)]));
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* @param {?} context
|
|
209
|
-
* @param {?} index
|
|
210
|
-
* @param {?} value
|
|
211
|
-
* @return {?}
|
|
212
|
-
*/
|
|
213
|
-
export function setDefaultValue(context, index, value) {
|
|
214
|
-
return context[index + 4 /* BindingsStartOffset */ + getTotalSources(context)] =
|
|
215
|
-
value;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* @param {?} data
|
|
219
|
-
* @param {?} bindingIndex
|
|
220
|
-
* @param {?} value
|
|
221
|
-
* @return {?}
|
|
222
|
-
*/
|
|
223
|
-
export function setValue(data, bindingIndex, value) {
|
|
224
|
-
data[bindingIndex] = value;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* @template T
|
|
228
|
-
* @param {?} data
|
|
229
|
-
* @param {?} bindingIndex
|
|
230
|
-
* @return {?}
|
|
231
|
-
*/
|
|
232
|
-
export function getValue(data, bindingIndex) {
|
|
233
|
-
return bindingIndex !== 0 ? (/** @type {?} */ (data[bindingIndex])) : null;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* @param {?} context
|
|
237
|
-
* @param {?} tNode
|
|
238
|
-
* @param {?} isClassBased
|
|
239
|
-
* @return {?}
|
|
240
|
-
*/
|
|
241
|
-
export function getPropValuesStartPosition(context, tNode, isClassBased) {
|
|
242
|
-
/** @type {?} */
|
|
243
|
-
let startPosition = 2 /* ValuesStartPosition */;
|
|
244
|
-
/** @type {?} */
|
|
245
|
-
const flag = isClassBased ? 512 /* hasClassMapBindings */ : 16384 /* hasStyleMapBindings */;
|
|
246
|
-
if (hasConfig(tNode, flag)) {
|
|
247
|
-
startPosition += 4 /* BindingsStartOffset */ + getValuesCount(context);
|
|
248
|
-
}
|
|
249
|
-
return startPosition;
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* @param {?} a
|
|
253
|
-
* @param {?} b
|
|
254
|
-
* @return {?}
|
|
255
|
-
*/
|
|
256
|
-
export function hasValueChangedUnwrapSafeValue(a, b) {
|
|
257
|
-
return hasValueChanged(unwrapSafeValue(a), unwrapSafeValue(b));
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* @param {?} a
|
|
261
|
-
* @param {?} b
|
|
262
|
-
* @return {?}
|
|
263
|
-
*/
|
|
264
|
-
export function hasValueChanged(a, b) {
|
|
265
|
-
if (b === NO_CHANGE)
|
|
266
|
-
return false;
|
|
267
|
-
/** @type {?} */
|
|
268
|
-
const compareValueA = Array.isArray(a) ? a[0 /* RawValuePosition */] : a;
|
|
269
|
-
/** @type {?} */
|
|
270
|
-
const compareValueB = Array.isArray(b) ? b[0 /* RawValuePosition */] : b;
|
|
271
|
-
return !Object.is(compareValueA, compareValueB);
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Determines whether the provided styling value is truthy or falsy.
|
|
275
|
-
* @template T
|
|
276
|
-
* @param {?} value
|
|
277
|
-
* @return {?}
|
|
278
|
-
*/
|
|
279
|
-
export function isStylingValueDefined(value) {
|
|
280
|
-
// the reason why null is compared against is because
|
|
281
|
-
// a CSS class value that is set to `false` must be
|
|
282
|
-
// respected (otherwise it would be treated as falsy).
|
|
283
|
-
// Empty string values are because developers usually
|
|
284
|
-
// set a value to an empty string to remove it.
|
|
285
|
-
return value != null && value !== '';
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* @param {?} a
|
|
289
|
-
* @param {?} b
|
|
290
|
-
* @param {?=} separator
|
|
291
|
-
* @return {?}
|
|
292
|
-
*/
|
|
293
|
-
export function concatString(a, b, separator = ' ') {
|
|
294
|
-
return a + ((b.length && a.length) ? separator : '') + b;
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* @param {?} value
|
|
298
|
-
* @return {?}
|
|
299
|
-
*/
|
|
300
|
-
export function hyphenate(value) {
|
|
301
|
-
return value.replace(/[a-z][A-Z]/g, (/**
|
|
302
|
-
* @param {?} v
|
|
303
|
-
* @return {?}
|
|
304
|
-
*/
|
|
305
|
-
v => v.charAt(0) + '-' + v.charAt(1))).toLowerCase();
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Returns an instance of `StylingMapArray`.
|
|
309
|
-
*
|
|
310
|
-
* This function is designed to find an instance of `StylingMapArray` in case it is stored
|
|
311
|
-
* inside of an instance of `TStylingContext`. When a styling context is created it
|
|
312
|
-
* will copy over an initial styling values from the tNode (which are stored as a
|
|
313
|
-
* `StylingMapArray` on the `tNode.classes` or `tNode.styles` values).
|
|
314
|
-
* @param {?} value
|
|
315
|
-
* @return {?}
|
|
316
|
-
*/
|
|
317
|
-
export function getStylingMapArray(value) {
|
|
318
|
-
return isStylingContext(value) ?
|
|
319
|
-
((/** @type {?} */ (value)))[1 /* InitialStylingValuePosition */] :
|
|
320
|
-
(/** @type {?} */ (value));
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* @param {?} value
|
|
324
|
-
* @return {?}
|
|
325
|
-
*/
|
|
326
|
-
export function isStylingContext(value) {
|
|
327
|
-
// the StylingMapArray is in the format of [initial, prop, string, prop, string]
|
|
328
|
-
// and this is the defining value to distinguish between arrays
|
|
329
|
-
return Array.isArray(value) && value.length >= 2 /* ValuesStartPosition */ &&
|
|
330
|
-
typeof value[1] !== 'string';
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* @param {?} value
|
|
334
|
-
* @return {?}
|
|
335
|
-
*/
|
|
336
|
-
export function isStylingMapArray(value) {
|
|
337
|
-
// the StylingMapArray is in the format of [initial, prop, string, prop, string]
|
|
338
|
-
// and this is the defining value to distinguish between arrays
|
|
339
|
-
return Array.isArray(value) &&
|
|
340
|
-
(typeof ((/** @type {?} */ (value)))[1 /* ValuesStartPosition */] === 'string');
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* @param {?} context
|
|
344
|
-
* @return {?}
|
|
345
|
-
*/
|
|
346
|
-
export function getInitialStylingValue(context) {
|
|
347
|
-
/** @type {?} */
|
|
348
|
-
const map = getStylingMapArray(context);
|
|
349
|
-
return map && ((/** @type {?} */ (map[0 /* RawValuePosition */]))) || '';
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* @param {?} tNode
|
|
353
|
-
* @return {?}
|
|
354
|
-
*/
|
|
355
|
-
export function hasClassInput(tNode) {
|
|
356
|
-
return (tNode.flags & 16 /* hasClassInput */) !== 0;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* @param {?} tNode
|
|
360
|
-
* @return {?}
|
|
361
|
-
*/
|
|
362
|
-
export function hasStyleInput(tNode) {
|
|
363
|
-
return (tNode.flags & 32 /* hasStyleInput */) !== 0;
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* @param {?} map
|
|
367
|
-
* @param {?} index
|
|
368
|
-
* @return {?}
|
|
369
|
-
*/
|
|
370
|
-
export function getMapProp(map, index) {
|
|
371
|
-
return (/** @type {?} */ (map[index + 0 /* PropOffset */]));
|
|
372
|
-
}
|
|
373
|
-
/** @type {?} */
|
|
374
|
-
const MAP_DIRTY_VALUE = typeof ngDevMode !== 'undefined' && ngDevMode ? {} : { MAP_DIRTY_VALUE: true };
|
|
375
|
-
/**
|
|
376
|
-
* @param {?} map
|
|
377
|
-
* @return {?}
|
|
378
|
-
*/
|
|
379
|
-
export function setMapAsDirty(map) {
|
|
380
|
-
map[0 /* RawValuePosition */] = MAP_DIRTY_VALUE;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* @param {?} map
|
|
384
|
-
* @param {?} index
|
|
385
|
-
* @param {?} value
|
|
386
|
-
* @return {?}
|
|
387
|
-
*/
|
|
388
|
-
export function setMapValue(map, index, value) {
|
|
389
|
-
map[index + 1 /* ValueOffset */] = value;
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* @param {?} map
|
|
393
|
-
* @param {?} index
|
|
394
|
-
* @return {?}
|
|
395
|
-
*/
|
|
396
|
-
export function getMapValue(map, index) {
|
|
397
|
-
return (/** @type {?} */ (map[index + 1 /* ValueOffset */]));
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* @param {?} classes
|
|
401
|
-
* @return {?}
|
|
402
|
-
*/
|
|
403
|
-
export function forceClassesAsString(classes) {
|
|
404
|
-
if (classes && typeof classes !== 'string') {
|
|
405
|
-
classes = Object.keys(classes).join(' ');
|
|
406
|
-
}
|
|
407
|
-
return ((/** @type {?} */ (classes))) || '';
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* @param {?} styles
|
|
411
|
-
* @param {?} hyphenateProps
|
|
412
|
-
* @return {?}
|
|
413
|
-
*/
|
|
414
|
-
export function forceStylesAsString(styles, hyphenateProps) {
|
|
415
|
-
if (typeof styles == 'string')
|
|
416
|
-
return styles;
|
|
417
|
-
/** @type {?} */
|
|
418
|
-
let str = '';
|
|
419
|
-
if (styles) {
|
|
420
|
-
/** @type {?} */
|
|
421
|
-
const props = Object.keys(styles);
|
|
422
|
-
for (let i = 0; i < props.length; i++) {
|
|
423
|
-
/** @type {?} */
|
|
424
|
-
const prop = props[i];
|
|
425
|
-
/** @type {?} */
|
|
426
|
-
const propLabel = hyphenateProps ? hyphenate(prop) : prop;
|
|
427
|
-
/** @type {?} */
|
|
428
|
-
const value = styles[prop];
|
|
429
|
-
if (value !== null) {
|
|
430
|
-
str = concatString(str, `${propLabel}:${value}`, ';');
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return str;
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* @param {?} directiveOrSourceId
|
|
438
|
-
* @return {?}
|
|
439
|
-
*/
|
|
440
|
-
export function isHostStylingActive(directiveOrSourceId) {
|
|
441
|
-
return directiveOrSourceId !== TEMPLATE_DIRECTIVE_INDEX;
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Converts the provided styling map array into a string.
|
|
445
|
-
*
|
|
446
|
-
* Classes => `one two three`
|
|
447
|
-
* Styles => `prop:value; prop2:value2`
|
|
448
|
-
* @param {?} map
|
|
449
|
-
* @param {?} isClassBased
|
|
450
|
-
* @return {?}
|
|
451
|
-
*/
|
|
452
|
-
export function stylingMapToString(map, isClassBased) {
|
|
453
|
-
/** @type {?} */
|
|
454
|
-
let str = '';
|
|
455
|
-
for (let i = 1 /* ValuesStartPosition */; i < map.length; i += 2 /* TupleSize */) {
|
|
456
|
-
/** @type {?} */
|
|
457
|
-
const prop = getMapProp(map, i);
|
|
458
|
-
/** @type {?} */
|
|
459
|
-
const value = (/** @type {?} */ (getMapValue(map, i)));
|
|
460
|
-
/** @type {?} */
|
|
461
|
-
const attrValue = concatString(prop, isClassBased ? '' : value, ':');
|
|
462
|
-
str = concatString(str, attrValue, isClassBased ? ' ' : '; ');
|
|
463
|
-
}
|
|
464
|
-
return str;
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Converts the provided styling map array into a key value map.
|
|
468
|
-
* @param {?} map
|
|
469
|
-
* @return {?}
|
|
470
|
-
*/
|
|
471
|
-
export function stylingMapToStringMap(map) {
|
|
472
|
-
/** @type {?} */
|
|
473
|
-
let stringMap = {};
|
|
474
|
-
if (map) {
|
|
475
|
-
for (let i = 1 /* ValuesStartPosition */; i < map.length; i += 2 /* TupleSize */) {
|
|
476
|
-
/** @type {?} */
|
|
477
|
-
const prop = getMapProp(map, i);
|
|
478
|
-
/** @type {?} */
|
|
479
|
-
const value = (/** @type {?} */ (getMapValue(map, i)));
|
|
480
|
-
stringMap[prop] = value;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
return stringMap;
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Inserts the provided item into the provided styling array at the right spot.
|
|
487
|
-
*
|
|
488
|
-
* The `StylingMapArray` type is a sorted key/value array of entries. This means
|
|
489
|
-
* that when a new entry is inserted it must be placed at the right spot in the
|
|
490
|
-
* array. This function figures out exactly where to place it.
|
|
491
|
-
* @param {?} stylingMapArr
|
|
492
|
-
* @param {?} prop
|
|
493
|
-
* @param {?} value
|
|
494
|
-
* @param {?=} allowOverwrite
|
|
495
|
-
* @return {?}
|
|
496
|
-
*/
|
|
497
|
-
export function addItemToStylingMap(stylingMapArr, prop, value, allowOverwrite) {
|
|
498
|
-
for (let j = 1 /* ValuesStartPosition */; j < stylingMapArr.length; j += 2 /* TupleSize */) {
|
|
499
|
-
/** @type {?} */
|
|
500
|
-
const propAtIndex = getMapProp(stylingMapArr, j);
|
|
501
|
-
if (prop <= propAtIndex) {
|
|
502
|
-
/** @type {?} */
|
|
503
|
-
let applied = false;
|
|
504
|
-
if (propAtIndex === prop) {
|
|
505
|
-
/** @type {?} */
|
|
506
|
-
const valueAtIndex = stylingMapArr[j];
|
|
507
|
-
if (allowOverwrite || !isStylingValueDefined(valueAtIndex)) {
|
|
508
|
-
applied = true;
|
|
509
|
-
setMapValue(stylingMapArr, j, value);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
else {
|
|
513
|
-
applied = true;
|
|
514
|
-
stylingMapArr.splice(j, 0, prop, value);
|
|
515
|
-
}
|
|
516
|
-
return applied;
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
stylingMapArr.push(prop, value);
|
|
520
|
-
return true;
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Used to convert a {key:value} map into a `StylingMapArray` array.
|
|
524
|
-
*
|
|
525
|
-
* This function will either generate a new `StylingMapArray` instance
|
|
526
|
-
* or it will patch the provided `newValues` map value into an
|
|
527
|
-
* existing `StylingMapArray` value (this only happens if `bindingValue`
|
|
528
|
-
* is an instance of `StylingMapArray`).
|
|
529
|
-
*
|
|
530
|
-
* If a new key/value map is provided with an old `StylingMapArray`
|
|
531
|
-
* value then all properties will be overwritten with their new
|
|
532
|
-
* values or with `null`. This means that the array will never
|
|
533
|
-
* shrink in size (but it will also not be created and thrown
|
|
534
|
-
* away whenever the `{key:value}` map entries change).
|
|
535
|
-
* @param {?} bindingValue
|
|
536
|
-
* @param {?} newValues
|
|
537
|
-
* @param {?=} normalizeProps
|
|
538
|
-
* @return {?}
|
|
539
|
-
*/
|
|
540
|
-
export function normalizeIntoStylingMap(bindingValue, newValues, normalizeProps) {
|
|
541
|
-
/** @type {?} */
|
|
542
|
-
const stylingMapArr = Array.isArray(bindingValue) ? bindingValue : allocStylingMapArray(null);
|
|
543
|
-
stylingMapArr[0 /* RawValuePosition */] = newValues;
|
|
544
|
-
// because the new values may not include all the properties
|
|
545
|
-
// that the old ones had, all values are set to `null` before
|
|
546
|
-
// the new values are applied. This way, when flushed, the
|
|
547
|
-
// styling algorithm knows exactly what style/class values
|
|
548
|
-
// to remove from the element (since they are `null`).
|
|
549
|
-
for (let j = 1 /* ValuesStartPosition */; j < stylingMapArr.length; j += 2 /* TupleSize */) {
|
|
550
|
-
setMapValue(stylingMapArr, j, null);
|
|
551
|
-
}
|
|
552
|
-
/** @type {?} */
|
|
553
|
-
let props = null;
|
|
554
|
-
/** @type {?} */
|
|
555
|
-
let map;
|
|
556
|
-
/** @type {?} */
|
|
557
|
-
let allValuesTrue = false;
|
|
558
|
-
if (typeof newValues === 'string') { // [class] bindings allow string values
|
|
559
|
-
props = splitOnWhitespace(newValues);
|
|
560
|
-
allValuesTrue = props !== null;
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
563
|
-
props = newValues ? Object.keys(newValues) : null;
|
|
564
|
-
map = newValues;
|
|
565
|
-
}
|
|
566
|
-
if (props) {
|
|
567
|
-
for (let i = 0; i < props.length; i++) {
|
|
568
|
-
/** @type {?} */
|
|
569
|
-
const prop = props[i];
|
|
570
|
-
/** @type {?} */
|
|
571
|
-
const newProp = normalizeProps ? hyphenate(prop) : prop;
|
|
572
|
-
/** @type {?} */
|
|
573
|
-
const value = allValuesTrue ? true : (/** @type {?} */ (map))[prop];
|
|
574
|
-
addItemToStylingMap(stylingMapArr, newProp, value, true);
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
return stylingMapArr;
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* @param {?} text
|
|
581
|
-
* @return {?}
|
|
582
|
-
*/
|
|
583
|
-
export function splitOnWhitespace(text) {
|
|
584
|
-
/** @type {?} */
|
|
585
|
-
let array = null;
|
|
586
|
-
/** @type {?} */
|
|
587
|
-
let length = text.length;
|
|
588
|
-
/** @type {?} */
|
|
589
|
-
let start = 0;
|
|
590
|
-
/** @type {?} */
|
|
591
|
-
let foundChar = false;
|
|
592
|
-
for (let i = 0; i < length; i++) {
|
|
593
|
-
/** @type {?} */
|
|
594
|
-
const char = text.charCodeAt(i);
|
|
595
|
-
if (char <= 32 /*' '*/) {
|
|
596
|
-
if (foundChar) {
|
|
597
|
-
if (array === null)
|
|
598
|
-
array = [];
|
|
599
|
-
array.push(text.substring(start, i));
|
|
600
|
-
foundChar = false;
|
|
601
|
-
}
|
|
602
|
-
start = i + 1;
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
foundChar = true;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
if (foundChar) {
|
|
609
|
-
if (array === null)
|
|
610
|
-
array = [];
|
|
611
|
-
array.push(text.substring(start, length));
|
|
612
|
-
foundChar = false;
|
|
613
|
-
}
|
|
614
|
-
return array;
|
|
615
|
-
}
|
|
616
|
-
// TODO (matsko|AndrewKushnir): refactor this once we figure out how to generate separate
|
|
617
|
-
// `input('class') + classMap()` instructions.
|
|
618
|
-
/**
|
|
619
|
-
* @param {?} inputs
|
|
620
|
-
* @return {?}
|
|
621
|
-
*/
|
|
622
|
-
export function selectClassBasedInputName(inputs) {
|
|
623
|
-
return inputs.hasOwnProperty('class') ? 'class' : 'className';
|
|
624
|
-
}
|
|
625
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGluZ191dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvdXRpbC9zdHlsaW5nX3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQU9BLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUcxRCxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sV0FBVyxDQUFDOztBQUVwQyxNQUFNLE9BQU8seUJBQXlCLEdBQUcsT0FBTzs7QUFDaEQsTUFBTSxPQUFPLHdCQUF3QixHQUFHLENBQUM7Ozs7Ozs7Ozs7QUFVekMsTUFBTSxPQUFPLHFCQUFxQixHQUFHLElBQUk7O0FBRXpDLE1BQU0sT0FBTyxxQkFBcUIsR0FBRyxDQUFDOztNQUVoQyxxQkFBcUIsR0FBRyxDQUFDOzs7Ozs7O0FBTy9CLE1BQU0sT0FBTyx3QkFBd0IsR0FBRyxHQUFHOzs7Ozs7Ozs7Ozs7QUFVM0MsTUFBTSxVQUFVLG9CQUFvQixDQUNoQyxjQUFzQyxFQUFFLGFBQXNCO0lBQ2hFLGNBQWMsR0FBRyxjQUFjLElBQUksb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUQsT0FBTztRQUNMLHFCQUFxQjtRQUNyQixjQUFjO0tBQ2YsQ0FBQztBQUNKLENBQUM7Ozs7O0FBRUQsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQXlCO0lBQzVELE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqQixDQUFDOzs7Ozs7QUFFRCxNQUFNLFVBQVUsU0FBUyxDQUFDLEtBQW1CLEVBQUUsSUFBZ0I7SUFDN0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFhRCxNQUFNLFVBQVUsa0JBQWtCLENBQzlCLEtBQW1CLEVBQUUsWUFBcUIsRUFBRSxlQUF3Qjs7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QUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNyQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2FBQ25CO1lBQ0QsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDZjthQUFNO1lBQ0wsU0FBUyxHQUFHLElBQUksQ0FBQztTQUNsQjtLQUNGO0lBQ0QsSUFBSSxTQUFTLEVBQUU7UUFDYixJQUFJLEtBQUssS0FBSyxJQUFJO1lBQUUsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUMvQixLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDMUMsU0FBUyxHQUFHLEtBQUssQ0FBQztLQUNuQjtJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQzs7Ozs7OztBQUlELE1BQU0sVUFBVSx5QkFBeUIsQ0FBQyxNQUF1QjtJQUMvRCxPQUFPLE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO0FBQ2hFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiogQGxpY2Vuc2VcbiogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4qXG4qIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4qIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiovXG5pbXBvcnQge3Vud3JhcFNhZmVWYWx1ZX0gZnJvbSAnLi4vLi4vc2FuaXRpemF0aW9uL2J5cGFzcyc7XG5pbXBvcnQge1Byb3BlcnR5QWxpYXNlcywgVE5vZGVGbGFnc30gZnJvbSAnLi4vaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7TFN0eWxpbmdEYXRhLCBTdHlsaW5nTWFwQXJyYXksIFN0eWxpbmdNYXBBcnJheUluZGV4LCBUU3R5bGluZ0NvbnRleHQsIFRTdHlsaW5nQ29udGV4dEluZGV4LCBUU3R5bGluZ0NvbnRleHRQcm9wQ29uZmlnRmxhZ3MsIFRTdHlsaW5nTm9kZX0gZnJvbSAnLi4vaW50ZXJmYWNlcy9zdHlsaW5nJztcbmltcG9ydCB7Tk9fQ0hBTkdFfSBmcm9tICcuLi90b2tlbnMnO1xuXG5leHBvcnQgY29uc3QgTUFQX0JBU0VEX0VOVFJZX1BST1BfTkFNRSA9ICdbTUFQXSc7XG5leHBvcnQgY29uc3QgVEVNUExBVEVfRElSRUNUSVZFX0lOREVYID0gMDtcblxuLyoqXG4gKiBEZWZhdWx0IGZhbGxiYWNrIHZhbHVlIGZvciBhIHN0eWxpbmcgYmluZGluZy5cbiAqXG4gKiBBIHZhbHVlIG9mIGBudWxsYCBpcyB1c2VkIGhlcmUgd2hpY2ggc2lnbmFscyB0byB0aGUgc3R5bGluZyBhbGdvcml0aG0gdGhhdFxuICogdGhlIHN0eWxpbmcgdmFsdWUgaXMgbm90IHByZXNlbnQuIFRoaXMgd2F5IGlmIHRoZXJlIGFyZSBubyBvdGhlciB2YWx1ZXNcbiAqIGRldGVjdGVkIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIG9uY2UgdGhlIHN0eWxlL2NsYXNzIHByb3BlcnR5IGlzIGRpcnR5IGFuZFxuICogZGlmZmVkIHdpdGhpbiB0aGUgc3R5bGluZyBhbGdvcml0aG0gcHJlc2VudCBpbiBgZmx1c2hTdHlsaW5nYC5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfQklORElOR19WQUxVRSA9IG51bGw7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0JJTkRJTkdfSU5ERVggPSAwO1xuXG5jb25zdCBERUZBVUxUX1RPVEFMX1NPVVJDRVMgPSAxO1xuXG4vLyBUaGUgZmlyc3QgYml0IHZhbHVlIHJlZmxlY3RzIGEgbWFwLWJhc2VkIGJpbmRpbmcgdmFsdWUncyBiaXQuXG4vLyBUaGUgcmVhc29uIHdoeSBpdCdzIGFsd2F5cyBhY3RpdmF0ZWQgZm9yIGV2ZXJ5IGVudHJ5IGluIHRoZSBtYXBcbi8vIGlzIHNvIHRoYXQgaWYgYW55IG1hcC1iaW5kaW5nIHZhbHVlcyB1cGRhdGUgdGhlbiBhbGwgb3RoZXIgcHJvcFxuLy8gYmFzZWQgYmluZGluZ3Mgd2lsbCBwYXNzIHRoZSBndWFyZCBjaGVjayBhdXRvbWF0aWNhbGx5IHdpdGhvdXRcbi8vIGFueSBleHRyYSBjb2RlIG9yIGZsYWdzLlxuZXhwb3J0IGNvbnN0IERFRkFVTFRfR1VBUkRfTUFTS19WQUxVRSA9IDBiMTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBgVFN0eWxpbmdDb250ZXh0YC5cbiAqXG4gKiBUaGUgYFRTdHlsaW5nQ29udGV4dGAgaXMgdXNlZCBhcyBhIG1hbmlmZXN0IG9mIGFsbCBzdHlsZSBvciBhbGwgY2xhc3MgYmluZGluZ3Mgb25cbiAqIGFuIGVsZW1lbnQuIEJlY2F1c2UgaXQgaXMgYSBULWxldmVsIGRhdGEtc3RydWN0dXJlLCBpdCBpcyBvbmx5IGNyZWF0ZWQgb25jZSBwZXJcbiAqIHROb2RlIGZvciBzdHlsZXMgYW5kIGZvciBjbGFzc2VzLiBUaGlzIGZ1bmN0aW9uIGFsbG9jYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhXG4gKiBgVFN0eWxpbmdDb250ZXh0YCB3aXRoIHRoZSBpbml0aWFsIHZhbHVlcyAoc2VlIGBpbnRlcmZhY2VzLnRzYCBmb3IgbW9yZSBpbmZvKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFsbG9jVFN0eWxpbmdDb250ZXh0KFxuICAgIGluaXRpYWxTdHlsaW5nOiBTdHlsaW5nTWFwQXJyYXkgfCBudWxsLCBoYXNEaXJlY3RpdmVzOiBib29sZWFuKTogVFN0eWxpbmdDb250ZXh0IHtcbiAgaW5pdGlhbFN0eWxpbmcgPSBpbml0aWFsU3R5bGluZyB8fCBhbGxvY1N0eWxpbmdNYXBBcnJheShudWxsKTtcbiAgcmV0dXJuIFtcbiAgICBERUZBVUxUX1RPVEFMX1NPVVJDRVMsICAvLyAxKSB0b3RhbCBhbW91bnQgb2Ygc3R5bGluZyBzb3VyY2VzICh0ZW1wbGF0ZSwgZGlyZWN0aXZlcywgZXRjLi4uKVxuICAgIGluaXRpYWxTdHlsaW5nLCAgICAgICAgIC8vIDIpIGluaXRpYWwgc3R5bGluZyB2YWx1ZXNcbiAgXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG9jU3R5bGluZ01hcEFycmF5KHZhbHVlOiB7fSB8IHN0cmluZyB8IG51bGwpOiBTdHlsaW5nTWFwQXJyYXkge1xuICByZXR1cm4gW3ZhbHVlXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0NvbmZpZyh0Tm9kZTogVFN0eWxpbmdOb2RlLCBmbGFnOiBUTm9kZUZsYWdzKSB7XG4gIHJldHVybiAodE5vZGUuZmxhZ3MgJiBmbGFnKSAhPT0gMDtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgb3Igbm90IHRvIGFwcGx5IHN0eWxlcy9jbGFzc2VzIGRpcmVjdGx5IG9yIHZpYSBjb250ZXh0IHJlc29sdXRpb24uXG4gKlxuICogVGhlcmUgYXJlIHRocmVlIGNhc2VzIHRoYXQgYXJlIG1hdGNoZWQgaGVyZTpcbiAqIDEuIHRoZXJlIGFyZSBubyBkaXJlY3RpdmVzIHByZXNlbnQgQU5EIGBuZ0Rldk1vZGVgIGlzIGZhbHN5XG4gKiAyLiB0aGUgYGZpcnN0VXBkYXRlUGFzc2AgaGFzIG5vdCBhbHJlYWR5IHJ1biAod2hpY2ggbWVhbnMgdGhhdFxuICogICAgdGhlcmUgYXJlIG1vcmUgYmluZGluZ3MgdG8gcmVnaXN0ZXIgYW5kLCB0aGVyZWZvcmUsIGRpcmVjdFxuICogICAgc3R5bGUvY2xhc3MgYXBwbGljYXRpb24gaXMgbm90IHlldCBwb3NzaWJsZSlcbiAqIDMuIFRoZXJlIGFyZSBubyBjb2xsaXNpb25zIChpLmUuIHByb3BlcnRpZXMgd2l0aCBtb3JlIHRoYW4gb25lIGJpbmRpbmcpIGFjcm9zcyBtdWx0aXBsZVxuICogICAgc291cmNlcyAoaS5lLiB0ZW1wbGF0ZSArIGRpcmVjdGl2ZSwgZGlyZWN0aXZlICsgZGlyZWN0aXZlLCBkaXJlY3RpdmUgKyBjb21wb25lbnQpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd0RpcmVjdFN0eWxpbmcoXG4gICAgdE5vZGU6IFRTdHlsaW5nTm9kZSwgaXNDbGFzc0Jhc2VkOiBib29sZWFuLCBmaXJzdFVwZGF0ZVBhc3M6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgbGV0IGFsbG93ID0gZmFsc2U7XG5cbiAgLy8gaWYgbm8gZGlyZWN0aXZlcyBhcmUgcHJlc2VudCB0aGVuIHdlIGRvIG5vdCBuZWVkIHBvcHVsYXRlIGEgY29udGV4dCBhdCBhbGwuIFRoaXNcbiAgLy8gaXMgYmVjYXVzZSBkdXBsaWNhdGUgcHJvcCBiaW5kaW5ncyBjYW5ub3QgYmUgcmVnaXN0ZXJlZCB0aHJvdWdoIHRoZSB0ZW1wbGF0ZS4gSWZcbiAgLy8gYW5kIHdoZW4gdGhpcyBoYXBwZW5zIHdlIGNhbiBzYWZlbHkgYXBwbHkgdGhlIHZhbHVlIGRpcmVjdGx5IHdpdGhvdXQgY29udGV4dFxuICAvLyByZXNvbHV0aW9uLi4uXG4gIGNvbnN0IGhhc0RpcmVjdGl2ZXMgPSBoYXNDb25maWcodE5vZGUsIFROb2RlRmxhZ3MuaGFzSG9zdEJpbmRpbmdzKTtcbiAgaWYgKCFoYXNEaXJlY3RpdmVzKSB7XG4gICAgLy8gYG5nRGV2TW9kZWAgaXMgcmVxdWlyZWQgdG8gYmUgY2hlY2tlZCBoZXJlIGJlY2F1c2UgdGVzdHMvZGVidWdnaW5nIHJlbHkgb24gdGhlIGNvbnRleHQgYmVpbmdcbiAgICAvLyBwb3B1bGF0ZWQuIElmIHRoaW5ncyBhcmUgaW4gcHJvZHVjdGlvbiBtb2RlIHRoZW4gdGhlcmUgaXMgbm8gbmVlZCB0byBidWlsZCBhIGNvbnRleHRcbiAgICAvLyB0aGVyZWZvcmUgdGhlIGRpcmVjdCBhcHBseSBjYW4gYmUgYWxsb3dlZCAoZXZlbiBvbiB0aGUgZmlyc3QgdXBkYXRlKS5cbiAgICBhbGxvdyA9IG5nRGV2TW9kZSA/ICFmaXJzdFVwZGF0ZVBhc3MgOiB0cnVlO1xuICB9IGVsc2UgaWYgKCFmaXJzdFVwZGF0ZVBhc3MpIHtcbiAgICBjb25zdCBkdXBsaWNhdGVTdHlsaW5nRmxhZyA9XG4gICAgICAgIGlzQ2xhc3NCYXNlZCA/IFROb2RlRmxhZ3MuaGFzRHVwbGljYXRlQ2xhc3NCaW5kaW5ncyA6IFROb2RlRmxhZ3MuaGFzRHVwbGljYXRlU3R5bGVCaW5kaW5ncztcbiAgICBjb25zdCBoYXNEdXBsaWNhdGVzID0gaGFzQ29uZmlnKHROb2RlLCBkdXBsaWNhdGVTdHlsaW5nRmxhZyk7XG4gICAgY29uc3QgaGFzT25seU1hcE9yUHJvcHNGbGFnID0gaXNDbGFzc0Jhc2VkID8gVE5vZGVGbGFncy5oYXNDbGFzc1Byb3BBbmRNYXBCaW5kaW5ncyA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVE5vZGVGbGFncy5oYXNTdHlsZVByb3BBbmRNYXBCaW5kaW5ncztcbiAgICBjb25zdCBoYXNPbmx5TWFwc09yT25seVByb3BzID0gKHROb2RlLmZsYWdzICYgaGFzT25seU1hcE9yUHJvcHNGbGFnKSAhPT0gaGFzT25seU1hcE9yUHJvcHNGbGFnO1xuICAgIGFsbG93ID0gIWhhc0R1cGxpY2F0ZXMgJiYgaGFzT25seU1hcHNPck9ubHlQcm9wcztcbiAgfVxuXG4gIHJldHVybiBhbGxvdztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhdGNoQ29uZmlnKHROb2RlOiBUU3R5bGluZ05vZGUsIGZsYWc6IFROb2RlRmxhZ3MpOiB2b2lkIHtcbiAgdE5vZGUuZmxhZ3MgfD0gZmxhZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFByb3AoY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGNvbnRleHRbaW5kZXggKyBUU3R5bGluZ0NvbnRleHRJbmRleC5Qcm9wT2Zmc2V0XSBhcyBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIGdldFByb3BDb25maWcoY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIChjb250ZXh0W2luZGV4ICsgVFN0eWxpbmdDb250ZXh0SW5kZXguQ29uZmlnT2Zmc2V0XSBhcyBudW1iZXIpICZcbiAgICAgIFRTdHlsaW5nQ29udGV4dFByb3BDb25maWdGbGFncy5NYXNrO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTYW5pdGl6YXRpb25SZXF1aXJlZChjb250ZXh0OiBUU3R5bGluZ0NvbnRleHQsIGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIChnZXRQcm9wQ29uZmlnKGNvbnRleHQsIGluZGV4KSAmIFRTdHlsaW5nQ29udGV4dFByb3BDb25maWdGbGFncy5TYW5pdGl6YXRpb25SZXF1aXJlZCkgIT09XG4gICAgICAwO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0R3VhcmRNYXNrKFxuICAgIGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCwgaW5kZXg6IG51bWJlciwgaXNIb3N0QmluZGluZzogYm9vbGVhbik6IG51bWJlciB7XG4gIGNvbnN0IHBvc2l0aW9uID0gaW5kZXggKyAoaXNIb3N0QmluZGluZyA/IFRTdHlsaW5nQ29udGV4dEluZGV4Lkhvc3RCaW5kaW5nc0JpdEd1YXJkT2Zmc2V0IDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFN0eWxpbmdDb250ZXh0SW5kZXguVGVtcGxhdGVCaXRHdWFyZE9mZnNldCk7XG4gIHJldHVybiBjb250ZXh0W3Bvc2l0aW9uXSBhcyBudW1iZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRHdWFyZE1hc2soXG4gICAgY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBpbmRleDogbnVtYmVyLCBtYXNrVmFsdWU6IG51bWJlciwgaXNIb3N0QmluZGluZzogYm9vbGVhbikge1xuICBjb25zdCBwb3NpdGlvbiA9IGluZGV4ICsgKGlzSG9zdEJpbmRpbmcgPyBUU3R5bGluZ0NvbnRleHRJbmRleC5Ib3N0QmluZGluZ3NCaXRHdWFyZE9mZnNldCA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRTdHlsaW5nQ29udGV4dEluZGV4LlRlbXBsYXRlQml0R3VhcmRPZmZzZXQpO1xuICBjb250ZXh0W3Bvc2l0aW9uXSA9IG1hc2tWYWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlc0NvdW50KGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCk6IG51bWJlciB7XG4gIHJldHVybiBnZXRUb3RhbFNvdXJjZXMoY29udGV4dCkgKyAxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG90YWxTb3VyY2VzKGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCk6IG51bWJlciB7XG4gIHJldHVybiBjb250ZXh0W1RTdHlsaW5nQ29udGV4dEluZGV4LlRvdGFsU291cmNlc1Bvc2l0aW9uXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJpbmRpbmdWYWx1ZShjb250ZXh0OiBUU3R5bGluZ0NvbnRleHQsIGluZGV4OiBudW1iZXIsIG9mZnNldDogbnVtYmVyKSB7XG4gIHJldHVybiBjb250ZXh0W2luZGV4ICsgVFN0eWxpbmdDb250ZXh0SW5kZXguQmluZGluZ3NTdGFydE9mZnNldCArIG9mZnNldF0gYXMgbnVtYmVyIHwgc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdFZhbHVlKGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCwgaW5kZXg6IG51bWJlcik6IHN0cmluZ3xib29sZWFufG51bGwge1xuICByZXR1cm4gY29udGV4dFtpbmRleCArIFRTdHlsaW5nQ29udGV4dEluZGV4LkJpbmRpbmdzU3RhcnRPZmZzZXQgKyBnZXRUb3RhbFNvdXJjZXMoY29udGV4dCldIGFzXG4gICAgICAgICAgICAgc3RyaW5nIHxcbiAgICAgIGJvb2xlYW4gfCBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0RGVmYXVsdFZhbHVlKFxuICAgIGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCwgaW5kZXg6IG51bWJlciwgdmFsdWU6IHN0cmluZyB8IGJvb2xlYW4gfCBudWxsKSB7XG4gIHJldHVybiBjb250ZXh0W2luZGV4ICsgVFN0eWxpbmdDb250ZXh0SW5kZXguQmluZGluZ3NTdGFydE9mZnNldCArIGdldFRvdGFsU291cmNlcyhjb250ZXh0KV0gPVxuICAgICAgICAgICAgIHZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0VmFsdWUoZGF0YTogTFN0eWxpbmdEYXRhLCBiaW5kaW5nSW5kZXg6IG51bWJlciwgdmFsdWU6IGFueSkge1xuICBkYXRhW2JpbmRpbmdJbmRleF0gPSB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlPFQgPSBhbnk+KGRhdGE6IExTdHlsaW5nRGF0YSwgYmluZGluZ0luZGV4OiBudW1iZXIpOiBUfG51bGwge1xuICByZXR1cm4gYmluZGluZ0luZGV4ICE9PSAwID8gZGF0YVtiaW5kaW5nSW5kZXhdIGFzIFQgOiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJvcFZhbHVlc1N0YXJ0UG9zaXRpb24oXG4gICAgY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCB0Tm9kZTogVFN0eWxpbmdOb2RlLCBpc0NsYXNzQmFzZWQ6IGJvb2xlYW4pIHtcbiAgbGV0IHN0YXJ0UG9zaXRpb24gPSBUU3R5bGluZ0NvbnRleHRJbmRleC5WYWx1ZXNTdGFydFBvc2l0aW9uO1xuICBjb25zdCBmbGFnID0gaXNDbGFzc0Jhc2VkID8gVE5vZGVGbGFncy5oYXNDbGFzc01hcEJpbmRpbmdzIDogVE5vZGVGbGFncy5oYXNTdHlsZU1hcEJpbmRpbmdzO1xuICBpZiAoaGFzQ29uZmlnKHROb2RlLCBmbGFnKSkge1xuICAgIHN0YXJ0UG9zaXRpb24gKz0gVFN0eWxpbmdDb250ZXh0SW5kZXguQmluZGluZ3NTdGFydE9mZnNldCArIGdldFZhbHVlc0NvdW50KGNvbnRleHQpO1xuICB9XG4gIHJldHVybiBzdGFydFBvc2l0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzVmFsdWVDaGFuZ2VkVW53cmFwU2FmZVZhbHVlKFxuICAgIGE6IE5PX0NIQU5HRSB8IFN0eWxpbmdNYXBBcnJheSB8IG51bWJlciB8IFN0cmluZyB8IHN0cmluZyB8IG51bGwgfCBib29sZWFuIHwgdW5kZWZpbmVkIHwge30sXG4gICAgYjogTk9fQ0hBTkdFIHwgU3R5bGluZ01hcEFycmF5IHwgbnVtYmVyIHwgU3RyaW5nIHwgc3RyaW5nIHwgbnVsbCB8IGJvb2xlYW4gfCB1bmRlZmluZWQgfFxuICAgICAgICB7fSk6IGJvb2xlYW4ge1xuICByZXR1cm4gaGFzVmFsdWVDaGFuZ2VkKHVud3JhcFNhZmVWYWx1ZShhKSwgdW53cmFwU2FmZVZhbHVlKGIpKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gaGFzVmFsdWVDaGFuZ2VkKFxuICAgIGE6IE5PX0NIQU5HRSB8IFN0eWxpbmdNYXBBcnJheSB8IG51bWJlciB8IHN0cmluZyB8IG51bGwgfCBib29sZWFuIHwgdW5kZWZpbmVkIHwge30sXG4gICAgYjogTk9fQ0hBTkdFIHwgU3R5bGluZ01hcEFycmF5IHwgbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCB8IGJvb2xlYW4gfCB1bmRlZmluZWQgfCB7fSk6IGJvb2xlYW4ge1xuICBpZiAoYiA9PT0gTk9fQ0hBTkdFKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgY29tcGFyZVZhbHVlQSA9IEFycmF5LmlzQXJyYXkoYSkgPyBhW1N0eWxpbmdNYXBBcnJheUluZGV4LlJhd1ZhbHVlUG9zaXRpb25dIDogYTtcbiAgY29uc3QgY29tcGFyZVZhbHVlQiA9IEFycmF5LmlzQXJyYXkoYikgPyBiW1N0eWxpbmdNYXBBcnJheUluZGV4LlJhd1ZhbHVlUG9zaXRpb25dIDogYjtcbiAgcmV0dXJuICFPYmplY3QuaXMoY29tcGFyZVZhbHVlQSwgY29tcGFyZVZhbHVlQik7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBwcm92aWRlZCBzdHlsaW5nIHZhbHVlIGlzIHRydXRoeSBvciBmYWxzeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3R5bGluZ1ZhbHVlRGVmaW5lZDxUIGV4dGVuZHMgc3RyaW5nfG51bWJlcnx7fXxudWxsfHVuZGVmaW5lZD4odmFsdWU6IFQpOlxuICAgIHZhbHVlIGlzIE5vbk51bGxhYmxlPFQ+IHtcbiAgLy8gdGhlIHJlYXNvbiB3aHkgbnVsbCBpcyBjb21wYXJlZCBhZ2FpbnN0IGlzIGJlY2F1c2VcbiAgLy8gYSBDU1MgY2xhc3MgdmFsdWUgdGhhdCBpcyBzZXQgdG8gYGZhbHNlYCBtdXN0IGJlXG4gIC8vIHJlc3BlY3RlZCAob3RoZXJ3aXNlIGl0IHdvdWxkIGJlIHRyZWF0ZWQgYXMgZmFsc3kpLlxuICAvLyBFbXB0eSBzdHJpbmcgdmFsdWVzIGFyZSBiZWNhdXNlIGRldmVsb3BlcnMgdXN1YWxseVxuICAvLyBzZXQgYSB2YWx1ZSB0byBhbiBlbXB0eSBzdHJpbmcgdG8gcmVtb3ZlIGl0LlxuICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiB2YWx1ZSAhPT0gJyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb25jYXRTdHJpbmcoYTogc3RyaW5nLCBiOiBzdHJpbmcsIHNlcGFyYXRvciA9ICcgJyk6IHN0cmluZyB7XG4gIHJldHVybiBhICsgKChiLmxlbmd0aCAmJiBhLmxlbmd0aCkgPyBzZXBhcmF0b3IgOiAnJykgKyBiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaHlwaGVuYXRlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWUucmVwbGFjZSgvW2Etel1bQS1aXS9nLCB2ID0+IHYuY2hhckF0KDApICsgJy0nICsgdi5jaGFyQXQoMSkpLnRvTG93ZXJDYXNlKCk7XG59XG5cbi8qKlxuICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiBgU3R5bGluZ01hcEFycmF5YC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGZpbmQgYW4gaW5zdGFuY2Ugb2YgYFN0eWxpbmdNYXBBcnJheWAgaW4gY2FzZSBpdCBpcyBzdG9yZWRcbiAqIGluc2lkZSBvZiBhbiBpbnN0YW5jZSBvZiBgVFN0eWxpbmdDb250ZXh0YC4gV2hlbiBhIHN0eWxpbmcgY29udGV4dCBpcyBjcmVhdGVkIGl0XG4gKiB3aWxsIGNvcHkgb3ZlciBhbiBpbml0aWFsIHN0eWxpbmcgdmFsdWVzIGZyb20gdGhlIHROb2RlICh3aGljaCBhcmUgc3RvcmVkIGFzIGFcbiAqIGBTdHlsaW5nTWFwQXJyYXlgIG9uIHRoZSBgdE5vZGUuY2xhc3Nlc2Agb3IgYHROb2RlLnN0eWxlc2AgdmFsdWVzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0eWxpbmdNYXBBcnJheSh2YWx1ZTogVFN0eWxpbmdDb250ZXh0IHwgU3R5bGluZ01hcEFycmF5IHwgbnVsbCk6XG4gICAgU3R5bGluZ01hcEFycmF5fG51bGwge1xuICByZXR1cm4gaXNTdHlsaW5nQ29udGV4dCh2YWx1ZSkgP1xuICAgICAgKHZhbHVlIGFzIFRTdHlsaW5nQ29udGV4dClbVFN0eWxpbmdDb250ZXh0SW5kZXguSW5pdGlhbFN0eWxpbmdWYWx1ZVBvc2l0aW9uXSA6XG4gICAgICB2YWx1ZSBhcyBTdHlsaW5nTWFwQXJyYXk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0eWxpbmdDb250ZXh0KHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgLy8gdGhlIFN0eWxpbmdNYXBBcnJheSBpcyBpbiB0aGUgZm9ybWF0IG9mIFtpbml0aWFsLCBwcm9wLCBzdHJpbmcsIHByb3AsIHN0cmluZ11cbiAgLy8gYW5kIHRoaXMgaXMgdGhlIGRlZmluaW5nIHZhbHVlIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gYXJyYXlzXG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPj0gVFN0eWxpbmdDb250ZXh0SW5kZXguVmFsdWVzU3RhcnRQb3NpdGlvbiAmJlxuICAgICAgdHlwZW9mIHZhbHVlWzFdICE9PSAnc3RyaW5nJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3R5bGluZ01hcEFycmF5KHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgLy8gdGhlIFN0eWxpbmdNYXBBcnJheSBpcyBpbiB0aGUgZm9ybWF0IG9mIFtpbml0aWFsLCBwcm9wLCBzdHJpbmcsIHByb3AsIHN0cmluZ11cbiAgLy8gYW5kIHRoaXMgaXMgdGhlIGRlZmluaW5nIHZhbHVlIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gYXJyYXlzXG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJlxuICAgICAgKHR5cGVvZih2YWx1ZSBhcyBTdHlsaW5nTWFwQXJyYXkpW1N0eWxpbmdNYXBBcnJheUluZGV4LlZhbHVlc1N0YXJ0UG9zaXRpb25dID09PSAnc3RyaW5nJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbml0aWFsU3R5bGluZ1ZhbHVlKGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCB8IFN0eWxpbmdNYXBBcnJheSB8IG51bGwpOiBzdHJpbmcge1xuICBjb25zdCBtYXAgPSBnZXRTdHlsaW5nTWFwQXJyYXkoY29udGV4dCk7XG4gIHJldHVybiBtYXAgJiYgKG1hcFtTdHlsaW5nTWFwQXJyYXlJbmRleC5SYXdWYWx1ZVBvc2l0aW9uXSBhcyBzdHJpbmcgfCBudWxsKSB8fCAnJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0NsYXNzSW5wdXQodE5vZGU6IFRTdHlsaW5nTm9kZSkge1xuICByZXR1cm4gKHROb2RlLmZsYWdzICYgVE5vZGVGbGFncy5oYXNDbGFzc0lucHV0KSAhPT0gMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1N0eWxlSW5wdXQodE5vZGU6IFRTdHlsaW5nTm9kZSkge1xuICByZXR1cm4gKHROb2RlLmZsYWdzICYgVE5vZGVGbGFncy5oYXNTdHlsZUlucHV0KSAhPT0gMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcFByb3AobWFwOiBTdHlsaW5nTWFwQXJyYXksIGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gbWFwW2luZGV4ICsgU3R5bGluZ01hcEFycmF5SW5kZXguUHJvcE9mZnNldF0gYXMgc3RyaW5nO1xufVxuXG5jb25zdCBNQVBfRElSVFlfVkFMVUUgPVxuICAgIHR5cGVvZiBuZ0Rldk1vZGUgIT09ICd1bmRlZmluZWQnICYmIG5nRGV2TW9kZSA/IHt9IDoge01BUF9ESVJUWV9WQUxVRTogdHJ1ZX07XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRNYXBBc0RpcnR5KG1hcDogU3R5bGluZ01hcEFycmF5KTogdm9pZCB7XG4gIG1hcFtTdHlsaW5nTWFwQXJyYXlJbmRleC5SYXdWYWx1ZVBvc2l0aW9uXSA9IE1BUF9ESVJUWV9WQUxVRTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldE1hcFZhbHVlKFxuICAgIG1hcDogU3R5bGluZ01hcEFycmF5LCBpbmRleDogbnVtYmVyLCB2YWx1ZTogc3RyaW5nIHwgYm9vbGVhbiB8IG51bGwpOiB2b2lkIHtcbiAgbWFwW2luZGV4ICsgU3R5bGluZ01hcEFycmF5SW5kZXguVmFsdWVPZmZzZXRdID0gdmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXBWYWx1ZShtYXA6IFN0eWxpbmdNYXBBcnJheSwgaW5kZXg6IG51bWJlcik6IHN0cmluZ3xudWxsIHtcbiAgcmV0dXJuIG1hcFtpbmRleCArIFN0eWxpbmdNYXBBcnJheUluZGV4LlZhbHVlT2Zmc2V0XSBhcyBzdHJpbmcgfCBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9yY2VDbGFzc2VzQXNTdHJpbmcoY2xhc3Nlczogc3RyaW5nIHwge1trZXk6IHN0cmluZ106IGFueX0gfCBudWxsIHwgdW5kZWZpbmVkKTpcbiAgICBzdHJpbmcge1xuICBpZiAoY2xhc3NlcyAmJiB0eXBlb2YgY2xhc3NlcyAhPT0gJ3N0cmluZycpIHtcbiAgICBjbGFzc2VzID0gT2JqZWN0LmtleXMoY2xhc3Nlcykuam9pbignICcpO1xuICB9XG4gIHJldHVybiAoY2xhc3NlcyBhcyBzdHJpbmcpIHx8ICcnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9yY2VTdHlsZXNBc1N0cmluZyhcbiAgICBzdHlsZXM6IHtba2V5OiBzdHJpbmddOiBhbnl9IHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCwgaHlwaGVuYXRlUHJvcHM6IGJvb2xlYW4pOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIHN0eWxlcyA9PSAnc3RyaW5nJykgcmV0dXJuIHN0eWxlcztcbiAgbGV0IHN0ciA9ICcnO1xuICBpZiAoc3R5bGVzKSB7XG4gICAgY29uc3QgcHJvcHMgPSBPYmplY3Qua2V5cyhzdHlsZXMpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHByb3AgPSBwcm9wc1tpXTtcbiAgICAgIGNvbnN0IHByb3BMYWJlbCA9IGh5cGhlbmF0ZVByb3BzID8gaHlwaGVuYXRlKHByb3ApIDogcHJvcDtcbiAgICAgIGNvbnN0IHZhbHVlID0gc3R5bGVzW3Byb3BdO1xuICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgIHN0ciA9IGNvbmNhdFN0cmluZyhzdHIsIGAke3Byb3BMYWJlbH06JHt2YWx1ZX1gLCAnOycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNIb3N0U3R5bGluZ0FjdGl2ZShkaXJlY3RpdmVPclNvdXJjZUlkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGRpcmVjdGl2ZU9yU291cmNlSWQgIT09IFRFTVBMQVRFX0RJUkVDVElWRV9JTkRFWDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgcHJvdmlkZWQgc3R5bGluZyBtYXAgYXJyYXkgaW50byBhIHN0cmluZy5cbiAqXG4gKiBDbGFzc2VzID0+IGBvbmUgdHdvIHRocmVlYFxuICogU3R5bGVzID0+IGBwcm9wOnZhbHVlOyBwcm9wMjp2YWx1ZTJgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHlsaW5nTWFwVG9TdHJpbmcobWFwOiBTdHlsaW5nTWFwQXJyYXksIGlzQ2xhc3NCYXNlZDogYm9vbGVhbik6IHN0cmluZyB7XG4gIGxldCBzdHIgPSAnJztcbiAgZm9yIChsZXQgaSA9IFN0eWxpbmdNYXBBcnJheUluZGV4LlZhbHVlc1N0YXJ0UG9zaXRpb247IGkgPCBtYXAubGVuZ3RoO1xuICAgICAgIGkgKz0gU3R5bGluZ01hcEFycmF5SW5kZXguVHVwbGVTaXplKSB7XG4gICAgY29uc3QgcHJvcCA9IGdldE1hcFByb3AobWFwLCBpKTtcbiAgICBjb25zdCB2YWx1ZSA9IGdldE1hcFZhbHVlKG1hcCwgaSkgYXMgc3RyaW5nO1xuICAgIGNvbnN0IGF0dHJWYWx1ZSA9IGNvbmNhdFN0cmluZyhwcm9wLCBpc0NsYXNzQmFzZWQgPyAnJyA6IHZhbHVlLCAnOicpO1xuICAgIHN0ciA9IGNvbmNhdFN0cmluZyhzdHIsIGF0dHJWYWx1ZSwgaXNDbGFzc0Jhc2VkID8gJyAnIDogJzsgJyk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgcHJvdmlkZWQgc3R5bGluZyBtYXAgYXJyYXkgaW50byBhIGtleSB2YWx1ZSBtYXAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHlsaW5nTWFwVG9TdHJpbmdNYXAobWFwOiBTdHlsaW5nTWFwQXJyYXkgfCBudWxsKToge1trZXk6IHN0cmluZ106IGFueX0ge1xuICBsZXQgc3RyaW5nTWFwOiB7W2tleTogc3RyaW5nXTogYW55fSA9IHt9O1xuICBpZiAobWFwKSB7XG4gICAgZm9yIChsZXQgaSA9IFN0eWxpbmdNYXBBcnJheUluZGV4LlZhbHVlc1N0YXJ0UG9zaXRpb247IGkgPCBtYXAubGVuZ3RoO1xuICAgICAgICAgaSArPSBTdHlsaW5nTWFwQXJyYXlJbmRleC5UdXBsZVNpemUpIHtcbiAgICAgIGNvbnN0IHByb3AgPSBnZXRNYXBQcm9wKG1hcCwgaSk7XG4gICAgICBjb25zdCB2YWx1ZSA9IGdldE1hcFZhbHVlKG1hcCwgaSkgYXMgc3RyaW5nO1xuICAgICAgc3RyaW5nTWFwW3Byb3BdID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHJpbmdNYXA7XG59XG5cbi8qKlxuICogSW5zZXJ0cyB0aGUgcHJvdmlkZWQgaXRlbSBpbnRvIHRoZSBwcm92aWRlZCBzdHlsaW5nIGFycmF5IGF0IHRoZSByaWdodCBzcG90LlxuICpcbiAqIFRoZSBgU3R5bGluZ01hcEFycmF5YCB0eXBlIGlzIGEgc29ydGVkIGtleS92YWx1ZSBhcnJheSBvZiBlbnRyaWVzLiBUaGlzIG1lYW5zXG4gKiB0aGF0IHdoZW4gYSBuZXcgZW50cnkgaXMgaW5zZXJ0ZWQgaXQgbXVzdCBiZSBwbGFjZWQgYXQgdGhlIHJpZ2h0IHNwb3QgaW4gdGhlXG4gKiBhcnJheS4gVGhpcyBmdW5jdGlvbiBmaWd1cmVzIG91dCBleGFjdGx5IHdoZXJlIHRvIHBsYWNlIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkSXRlbVRvU3R5bGluZ01hcChcbiAgICBzdHlsaW5nTWFwQXJyOiBTdHlsaW5nTWFwQXJyYXksIHByb3A6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IGJvb2xlYW4gfCBudWxsLFxuICAgIGFsbG93T3ZlcndyaXRlPzogYm9vbGVhbikge1xuICBmb3IgKGxldCBqID0gU3R5bGluZ01hcEFycmF5SW5kZXguVmFsdWVzU3RhcnRQb3NpdGlvbjsgaiA8IHN0eWxpbmdNYXBBcnIubGVuZ3RoO1xuICAgICAgIGogKz0gU3R5bGluZ01hcEFycmF5SW5kZXguVHVwbGVTaXplKSB7XG4gICAgY29uc3QgcHJvcEF0SW5kZXggPSBnZXRNYXBQcm9wKHN0eWxpbmdNYXBBcnIsIGopO1xuICAgIGlmIChwcm9wIDw9IHByb3BBdEluZGV4KSB7XG4gICAgICBsZXQgYXBwbGllZCA9IGZhbHNlO1xuICAgICAgaWYgKHByb3BBdEluZGV4ID09PSBwcm9wKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlQXRJbmRleCA9IHN0eWxpbmdNYXBBcnJbal07XG4gICAgICAgIGlmIChhbGxvd092ZXJ3cml0ZSB8fCAhaXNTdHlsaW5nVmFsdWVEZWZpbmVkKHZhbHVlQXRJbmRleCkpIHtcbiAgICAgICAgICBhcHBsaWVkID0gdHJ1ZTtcbiAgICAgICAgICBzZXRNYXBWYWx1ZShzdHlsaW5nTWFwQXJyLCBqLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFwcGxpZWQgPSB0cnVlO1xuICAgICAgICBzdHlsaW5nTWFwQXJyLnNwbGljZShqLCAwLCBwcm9wLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXBwbGllZDtcbiAgICB9XG4gIH1cblxuICBzdHlsaW5nTWFwQXJyLnB1c2gocHJvcCwgdmFsdWUpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBVc2VkIHRvIGNvbnZlcnQgYSB7a2V5OnZhbHVlfSBtYXAgaW50byBhIGBTdHlsaW5nTWFwQXJyYXlgIGFycmF5LlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBlaXRoZXIgZ2VuZXJhdGUgYSBuZXcgYFN0eWxpbmdNYXBBcnJheWAgaW5zdGFuY2VcbiAqIG9yIGl0IHdpbGwgcGF0Y2ggdGhlIHByb3ZpZGVkIGBuZXdWYWx1ZXNgIG1hcCB2YWx1ZSBpbnRvIGFuXG4gKiBleGlzdGluZyBgU3R5bGluZ01hcEFycmF5YCB2YWx1ZSAodGhpcyBvbmx5IGhhcHBlbnMgaWYgYGJpbmRpbmdWYWx1ZWBcbiAqIGlzIGFuIGluc3RhbmNlIG9mIGBTdHlsaW5nTWFwQXJyYXlgKS5cbiAqXG4gKiBJZiBhIG5ldyBrZXkvdmFsdWUgbWFwIGlzIHByb3ZpZGVkIHdpdGggYW4gb2xkIGBTdHlsaW5nTWFwQXJyYXlgXG4gKiB2YWx1ZSB0aGVuIGFsbCBwcm9wZXJ0aWVzIHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2l0aCB0aGVpciBuZXdcbiAqIHZhbHVlcyBvciB3aXRoIGBudWxsYC4gVGhpcyBtZWFucyB0aGF0IHRoZSBhcnJheSB3aWxsIG5ldmVyXG4gKiBzaHJpbmsgaW4gc2l6ZSAoYnV0IGl0IHdpbGwgYWxzbyBub3QgYmUgY3JlYXRlZCBhbmQgdGhyb3duXG4gKiBhd2F5IHdoZW5ldmVyIHRoZSBge2tleTp2YWx1ZX1gIG1hcCBlbnRyaWVzIGNoYW5nZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVJbnRvU3R5bGluZ01hcChcbiAgICBiaW5kaW5nVmFsdWU6IG51bGwgfCBTdHlsaW5nTWFwQXJyYXksXG4gICAgbmV3VmFsdWVzOiB7W2tleTogc3RyaW5nXTogYW55fSB8IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsXG4gICAgbm9ybWFsaXplUHJvcHM/OiBib29sZWFuKTogU3R5bGluZ01hcEFycmF5IHtcbiAgY29uc3Qgc3R5bGluZ01hcEFycjogU3R5bGluZ01hcEFycmF5ID1cbiAgICAgIEFycmF5LmlzQXJyYXkoYmluZGluZ1ZhbHVlKSA/IGJpbmRpbmdWYWx1ZSA6IGFsbG9jU3R5bGluZ01hcEFycmF5KG51bGwpO1xuICBzdHlsaW5nTWFwQXJyW1N0eWxpbmdNYXBBcnJheUluZGV4LlJhd1ZhbHVlUG9zaXRpb25dID0gbmV3VmFsdWVzO1xuXG4gIC8vIGJlY2F1c2UgdGhlIG5ldyB2YWx1ZXMgbWF5IG5vdCBpbmNsdWRlIGFsbCB0aGUgcHJvcGVydGllc1xuICAvLyB0aGF0IHRoZSBvbGQgb25lcyBoYWQsIGFsbCB2YWx1ZXMgYXJlIHNldCB0byBgbnVsbGAgYmVmb3JlXG4gIC8vIHRoZSBuZXcgdmFsdWVzIGFyZSBhcHBsaWVkLiBUaGlzIHdheSwgd2hlbiBmbHVzaGVkLCB0aGVcbiAgLy8gc3R5bGluZyBhbGdvcml0aG0ga25vd3MgZXhhY3RseSB3aGF0IHN0eWxlL2NsYXNzIHZhbHVlc1xuICAvLyB0byByZW1vdmUgZnJvbSB0aGUgZWxlbWVudCAoc2luY2UgdGhleSBhcmUgYG51bGxgKS5cbiAgZm9yIChsZXQgaiA9IFN0eWxpbmdNYXBBcnJheUluZGV4LlZhbHVlc1N0YXJ0UG9zaXRpb247IGogPCBzdHlsaW5nTWFwQXJyLmxlbmd0aDtcbiAgICAgICBqICs9IFN0eWxpbmdNYXBBcnJheUluZGV4LlR1cGxlU2l6ZSkge1xuICAgIHNldE1hcFZhbHVlKHN0eWxpbmdNYXBBcnIsIGosIG51bGwpO1xuICB9XG5cbiAgbGV0IHByb3BzOiBzdHJpbmdbXXxudWxsID0gbnVsbDtcbiAgbGV0IG1hcDoge1trZXk6IHN0cmluZ106IGFueX18dW5kZWZpbmVkfG51bGw7XG4gIGxldCBhbGxWYWx1ZXNUcnVlID0gZmFsc2U7XG4gIGlmICh0eXBlb2YgbmV3VmFsdWVzID09PSAnc3RyaW5nJykgeyAgLy8gW2NsYXNzXSBiaW5kaW5ncyBhbGxvdyBzdHJpbmcgdmFsdWVzXG4gICAgcHJvcHMgPSBzcGxpdE9uV2hpdGVzcGFjZShuZXdWYWx1ZXMpO1xuICAgIGFsbFZhbHVlc1RydWUgPSBwcm9wcyAhPT0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICBwcm9wcyA9IG5ld1ZhbHVlcyA/IE9iamVjdC5rZXlzKG5ld1ZhbHVlcykgOiBudWxsO1xuICAgIG1hcCA9IG5ld1ZhbHVlcztcbiAgfVxuXG4gIGlmIChwcm9wcykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHByb3AgPSBwcm9wc1tpXTtcbiAgICAgIGNvbnN0IG5ld1Byb3AgPSBub3JtYWxpemVQcm9wcyA/IGh5cGhlbmF0ZShwcm9wKSA6IHByb3A7XG4gICAgICBjb25zdCB2YWx1ZSA9IGFsbFZhbHVlc1RydWUgPyB0cnVlIDogbWFwICFbcHJvcF07XG4gICAgICBhZGRJdGVtVG9TdHlsaW5nTWFwKHN0eWxpbmdNYXBBcnIsIG5ld1Byb3AsIHZhbHVlLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3R5bGluZ01hcEFycjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNwbGl0T25XaGl0ZXNwYWNlKHRleHQ6IHN0cmluZyk6IHN0cmluZ1tdfG51bGwge1xuICBsZXQgYXJyYXk6IHN0cmluZ1tdfG51bGwgPSBudWxsO1xuICBsZXQgbGVuZ3RoID0gdGV4dC5sZW5ndGg7XG4gIGxldCBzdGFydCA9IDA7XG4gIGxldCBmb3VuZENoYXIgPSBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoYXIgPSB0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGNoYXIgPD0gMzIgLyonICcqLykge1xuICAgICAgaWYgKGZvdW5kQ2hhcikge1xuICAgICAgICBpZiAoYXJyYXkgPT09IG51bGwpIGFycmF5ID0gW107XG4gICAgICAgIGFycmF5LnB1c2godGV4dC5zdWJzdHJpbmcoc3RhcnQsIGkpKTtcbiAgICAgICAgZm91bmRDaGFyID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBzdGFydCA9IGkgKyAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3VuZENoYXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBpZiAoZm91bmRDaGFyKSB7XG4gICAgaWYgKGFycmF5ID09PSBudWxsKSBhcnJheSA9IFtdO1xuICAgIGFycmF5LnB1c2godGV4dC5zdWJzdHJpbmcoc3RhcnQsIGxlbmd0aCkpO1xuICAgIGZvdW5kQ2hhciA9IGZhbHNlO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxuLy8gVE9ETyAobWF0c2tvfEFuZHJld0t1c2huaXIpOiByZWZhY3RvciB0aGlzIG9uY2Ugd2UgZmlndXJlIG91dCBob3cgdG8gZ2VuZXJhdGUgc2VwYXJhdGVcbi8vIGBpbnB1dCgnY2xhc3MnKSArIGNsYXNzTWFwKClgIGluc3RydWN0aW9ucy5cbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3RDbGFzc0Jhc2VkSW5wdXROYW1lKGlucHV0czogUHJvcGVydHlBbGlhc2VzKTogc3RyaW5nIHtcbiAgcmV0dXJuIGlucHV0cy5oYXNPd25Qcm9wZXJ0eSgnY2xhc3MnKSA/ICdjbGFzcycgOiAnY2xhc3NOYW1lJztcbn1cbiJdfQ==
|