@angular/core 9.0.0-rc.7 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/bundles/core-testing.umd.js +18 -16
  2. package/bundles/core-testing.umd.js.map +1 -1
  3. package/bundles/core-testing.umd.min.js +7 -7
  4. package/bundles/core-testing.umd.min.js.map +1 -1
  5. package/bundles/core.umd.js +6386 -6384
  6. package/bundles/core.umd.js.map +1 -1
  7. package/bundles/core.umd.min.js +182 -175
  8. package/bundles/core.umd.min.js.map +1 -1
  9. package/core.d.ts +726 -734
  10. package/core.metadata.json +1 -1
  11. package/esm2015/core.externs.js +5 -5
  12. package/esm2015/core.js +17 -15
  13. package/esm2015/index.js +2 -2
  14. package/esm2015/public_api.js +2 -2
  15. package/esm2015/src/application_init.js +10 -2
  16. package/esm2015/src/application_module.js +6 -3
  17. package/esm2015/src/application_ref.js +7 -7
  18. package/esm2015/src/core.js +4 -4
  19. package/esm2015/src/core_private_export.js +7 -7
  20. package/esm2015/src/core_render3_private_export.js +2 -2
  21. package/esm2015/src/debug/debug_node.js +55 -16
  22. package/esm2015/src/di/injectable.js +1 -13
  23. package/esm2015/src/di/injector.js +12 -10
  24. package/esm2015/src/di/interface/provider.js +1 -1
  25. package/esm2015/src/di/r3_injector.js +5 -4
  26. package/esm2015/src/i18n/locale_data_api.js +22 -6
  27. package/esm2015/src/i18n/locale_en.js +16 -5
  28. package/esm2015/src/i18n/localization.js +7 -1
  29. package/esm2015/src/i18n/tokens.js +41 -1
  30. package/esm2015/src/interface/type.js +1 -1
  31. package/esm2015/src/metadata/ng_module.js +1 -1
  32. package/esm2015/src/render/api.js +4 -1
  33. package/esm2015/src/render3/assert.js +9 -1
  34. package/esm2015/src/render3/bindings.js +16 -5
  35. package/esm2015/src/render3/component.js +54 -25
  36. package/esm2015/src/render3/component_ref.js +28 -18
  37. package/esm2015/src/render3/definition.js +3 -1
  38. package/esm2015/src/render3/di.js +3 -4
  39. package/esm2015/src/render3/di_setup.js +5 -7
  40. package/esm2015/src/render3/errors.js +3 -1
  41. package/esm2015/src/render3/features/inherit_definition_feature.js +89 -52
  42. package/esm2015/src/render3/features/ng_onchanges_feature.js +2 -2
  43. package/esm2015/src/render3/global_utils_api.js +3 -3
  44. package/esm2015/src/render3/i18n.js +60 -56
  45. package/esm2015/src/render3/index.js +2 -2
  46. package/esm2015/src/render3/instructions/advance.js +10 -11
  47. package/esm2015/src/render3/instructions/all.js +4 -5
  48. package/esm2015/src/render3/instructions/attribute.js +12 -5
  49. package/esm2015/src/render3/instructions/attribute_interpolation.js +66 -14
  50. package/esm2015/src/render3/instructions/change_detection.js +8 -23
  51. package/esm2015/src/render3/instructions/class_map_interpolation.js +13 -12
  52. package/esm2015/src/render3/instructions/container.js +15 -12
  53. package/esm2015/src/render3/instructions/element.js +45 -132
  54. package/esm2015/src/render3/instructions/element_container.js +8 -10
  55. package/esm2015/src/render3/instructions/embedded_view.js +7 -7
  56. package/esm2015/src/render3/instructions/host_property.js +10 -7
  57. package/esm2015/src/render3/instructions/listener.js +18 -16
  58. package/esm2015/src/render3/instructions/lview_debug.js +160 -23
  59. package/esm2015/src/render3/instructions/projection.js +7 -5
  60. package/esm2015/src/render3/instructions/property.js +27 -6
  61. package/esm2015/src/render3/instructions/property_interpolation.js +42 -23
  62. package/esm2015/src/render3/instructions/shared.js +279 -244
  63. package/esm2015/src/render3/instructions/storage.js +6 -8
  64. package/esm2015/src/render3/instructions/style_prop_interpolation.js +12 -12
  65. package/esm2015/src/render3/instructions/styling.js +731 -475
  66. package/esm2015/src/render3/instructions/text.js +5 -5
  67. package/esm2015/src/render3/interfaces/definition.js +41 -1
  68. package/esm2015/src/render3/interfaces/node.js +160 -115
  69. package/esm2015/src/render3/interfaces/styling.js +183 -375
  70. package/esm2015/src/render3/interfaces/view.js +10 -2
  71. package/esm2015/src/render3/jit/environment.js +1 -3
  72. package/esm2015/src/render3/namespaces.js +17 -0
  73. package/esm2015/src/render3/node_manipulation.js +177 -57
  74. package/esm2015/src/render3/node_selector_matcher.js +128 -24
  75. package/esm2015/src/render3/node_util.js +12 -7
  76. package/esm2015/src/render3/pipe.js +10 -14
  77. package/esm2015/src/render3/pure_function.js +107 -42
  78. package/esm2015/src/render3/query.js +32 -26
  79. package/esm2015/src/render3/state.js +57 -185
  80. package/esm2015/src/render3/styling/class_differ.js +47 -0
  81. package/esm2015/src/render3/styling/static_styling.js +54 -0
  82. package/esm2015/src/render3/styling/style_binding_list.js +437 -0
  83. package/esm2015/src/render3/styling/styling_parser.js +336 -0
  84. package/esm2015/src/render3/tokens.js +2 -2
  85. package/esm2015/src/render3/util/attrs_utils.js +125 -2
  86. package/esm2015/src/render3/util/change_detection_utils.js +33 -0
  87. package/esm2015/src/render3/util/discovery_utils.js +146 -119
  88. package/esm2015/src/render3/util/global_utils.js +5 -5
  89. package/esm2015/src/render3/util/view_utils.js +6 -6
  90. package/esm2015/src/render3/view_engine_compatibility.js +16 -17
  91. package/esm2015/src/render3/view_ref.js +16 -13
  92. package/esm2015/src/sanitization/bypass.js +1 -1
  93. package/esm2015/src/sanitization/sanitization.js +20 -5
  94. package/esm2015/src/util/array_utils.js +240 -1
  95. package/esm2015/src/util/assert.js +37 -21
  96. package/esm2015/src/util/char_code.js +8 -0
  97. package/esm2015/src/util/iterable.js +4 -1
  98. package/esm2015/src/util/ng_dev_mode.js +1 -12
  99. package/esm2015/src/util/stringify.js +14 -1
  100. package/esm2015/src/version.js +1 -1
  101. package/esm2015/src/view/services.js +1 -1
  102. package/esm2015/testing/src/r3_test_bed.js +5 -1
  103. package/esm2015/testing/src/r3_test_bed_compiler.js +5 -13
  104. package/esm2015/testing/src/styling.js +103 -0
  105. package/esm5/core.js +17 -15
  106. package/esm5/src/application_init.js +10 -2
  107. package/esm5/src/application_module.js +6 -3
  108. package/esm5/src/application_ref.js +6 -6
  109. package/esm5/src/core.js +2 -2
  110. package/esm5/src/core_private_export.js +7 -7
  111. package/esm5/src/core_render3_private_export.js +2 -2
  112. package/esm5/src/debug/debug_node.js +39 -14
  113. package/esm5/src/di/injectable.js +1 -1
  114. package/esm5/src/di/injector.js +12 -12
  115. package/esm5/src/di/interface/provider.js +1 -1
  116. package/esm5/src/di/r3_injector.js +5 -4
  117. package/esm5/src/i18n/locale_data_api.js +20 -6
  118. package/esm5/src/i18n/locale_en.js +16 -5
  119. package/esm5/src/i18n/localization.js +6 -1
  120. package/esm5/src/i18n/tokens.js +40 -1
  121. package/esm5/src/interface/type.js +1 -1
  122. package/esm5/src/metadata/ng_module.js +1 -1
  123. package/esm5/src/render/api.js +4 -1
  124. package/esm5/src/render3/assert.js +4 -1
  125. package/esm5/src/render3/bindings.js +19 -2
  126. package/esm5/src/render3/component.js +47 -22
  127. package/esm5/src/render3/component_ref.js +20 -17
  128. package/esm5/src/render3/definition.js +3 -1
  129. package/esm5/src/render3/di.js +3 -4
  130. package/esm5/src/render3/di_setup.js +4 -5
  131. package/esm5/src/render3/errors.js +3 -1
  132. package/esm5/src/render3/features/inherit_definition_feature.js +74 -42
  133. package/esm5/src/render3/features/ng_onchanges_feature.js +1 -1
  134. package/esm5/src/render3/global_utils_api.js +3 -3
  135. package/esm5/src/render3/i18n.js +51 -51
  136. package/esm5/src/render3/index.js +2 -2
  137. package/esm5/src/render3/instructions/advance.js +9 -11
  138. package/esm5/src/render3/instructions/all.js +1 -2
  139. package/esm5/src/render3/instructions/attribute.js +9 -5
  140. package/esm5/src/render3/instructions/attribute_interpolation.js +49 -13
  141. package/esm5/src/render3/instructions/change_detection.js +8 -21
  142. package/esm5/src/render3/instructions/class_map_interpolation.js +13 -12
  143. package/esm5/src/render3/instructions/container.js +13 -12
  144. package/esm5/src/render3/instructions/element.js +41 -113
  145. package/esm5/src/render3/instructions/element_container.js +8 -9
  146. package/esm5/src/render3/instructions/embedded_view.js +7 -7
  147. package/esm5/src/render3/instructions/host_property.js +8 -7
  148. package/esm5/src/render3/instructions/listener.js +13 -13
  149. package/esm5/src/render3/instructions/lview_debug.js +56 -15
  150. package/esm5/src/render3/instructions/projection.js +6 -5
  151. package/esm5/src/render3/instructions/property.js +17 -6
  152. package/esm5/src/render3/instructions/property_interpolation.js +32 -24
  153. package/esm5/src/render3/instructions/shared.js +258 -210
  154. package/esm5/src/render3/instructions/storage.js +4 -6
  155. package/esm5/src/render3/instructions/style_prop_interpolation.js +12 -12
  156. package/esm5/src/render3/instructions/styling.js +685 -367
  157. package/esm5/src/render3/instructions/text.js +5 -5
  158. package/esm5/src/render3/interfaces/definition.js +1 -1
  159. package/esm5/src/render3/interfaces/node.js +49 -1
  160. package/esm5/src/render3/interfaces/styling.js +57 -1
  161. package/esm5/src/render3/interfaces/view.js +1 -1
  162. package/esm5/src/render3/jit/environment.js +1 -3
  163. package/esm5/src/render3/namespaces.js +10 -0
  164. package/esm5/src/render3/node_manipulation.js +167 -54
  165. package/esm5/src/render3/node_selector_matcher.js +113 -20
  166. package/esm5/src/render3/node_util.js +12 -7
  167. package/esm5/src/render3/pipe.js +10 -14
  168. package/esm5/src/render3/pure_function.js +103 -33
  169. package/esm5/src/render3/query.js +25 -24
  170. package/esm5/src/render3/state.js +37 -133
  171. package/esm5/src/render3/styling/class_differ.js +39 -0
  172. package/esm5/src/render3/styling/static_styling.js +42 -0
  173. package/esm5/src/render3/styling/style_binding_list.js +411 -0
  174. package/esm5/src/render3/styling/styling_parser.js +265 -0
  175. package/esm5/src/render3/tokens.js +2 -2
  176. package/esm5/src/render3/util/attrs_utils.js +117 -2
  177. package/esm5/src/render3/util/change_detection_utils.js +23 -0
  178. package/esm5/src/render3/util/discovery_utils.js +115 -99
  179. package/esm5/src/render3/util/global_utils.js +5 -5
  180. package/esm5/src/render3/util/view_utils.js +5 -5
  181. package/esm5/src/render3/view_engine_compatibility.js +37 -39
  182. package/esm5/src/render3/view_ref.js +14 -13
  183. package/esm5/src/sanitization/bypass.js +1 -1
  184. package/esm5/src/sanitization/sanitization.js +16 -5
  185. package/esm5/src/util/array_utils.js +240 -1
  186. package/esm5/src/util/assert.js +37 -21
  187. package/esm5/src/util/char_code.js +8 -0
  188. package/esm5/src/util/iterable.js +4 -1
  189. package/esm5/src/util/ng_dev_mode.js +1 -12
  190. package/esm5/src/util/stringify.js +14 -1
  191. package/esm5/src/version.js +1 -1
  192. package/esm5/src/view/services.js +1 -1
  193. package/esm5/testing/src/r3_test_bed.js +9 -1
  194. package/esm5/testing/src/r3_test_bed_compiler.js +9 -15
  195. package/esm5/testing/src/styling.js +82 -0
  196. package/fesm2015/core.js +6431 -7075
  197. package/fesm2015/core.js.map +1 -1
  198. package/fesm2015/testing.js +10 -14
  199. package/fesm2015/testing.js.map +1 -1
  200. package/fesm5/core.js +6354 -6361
  201. package/fesm5/core.js.map +1 -1
  202. package/fesm5/testing.js +18 -16
  203. package/fesm5/testing.js.map +1 -1
  204. package/package.json +1 -1
  205. package/src/r3_symbols.d.ts +46 -23
  206. package/testing/testing.d.ts +3 -5
  207. package/testing/testing.metadata.json +1 -1
  208. package/testing.d.ts +2 -2
  209. package/esm2015/global.js +0 -7
  210. package/esm2015/src/render3/instructions/alloc_host_vars.js +0 -80
  211. package/esm2015/src/render3/styling/bindings.js +0 -1248
  212. package/esm2015/src/render3/styling/map_based_bindings.js +0 -384
  213. package/esm2015/src/render3/styling/state.js +0 -135
  214. package/esm2015/src/render3/styling/styling_debug.js +0 -655
  215. package/esm2015/src/render3/util/styling_utils.js +0 -625
  216. package/esm5/global.js +0 -9
  217. package/esm5/src/render3/instructions/alloc_host_vars.js +0 -62
  218. package/esm5/src/render3/styling/bindings.js +0 -949
  219. package/esm5/src/render3/styling/map_based_bindings.js +0 -310
  220. package/esm5/src/render3/styling/state.js +0 -56
  221. package/esm5/src/render3/styling/styling_debug.js +0 -315
  222. 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==