@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
@@ -4,419 +4,227 @@
4
4
  * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
5
  */
6
6
  /**
7
- * A static-level representation of all style or class bindings/values
8
- * associated with a `TNode`.
9
- *
10
- * The `TStylingContext` unites all template styling bindings (i.e.
11
- * `[class]` and `[style]` bindings) as well as all host-level
12
- * styling bindings (for components and directives) together into
13
- * a single manifest
14
- *
15
- * The styling context is stored on a `TNode` on and there are
16
- * two instances of it: one for classes and another for styles.
17
- *
18
- * ```typescript
19
- * tNode.styles = [ ... a context only for styles ... ];
20
- * tNode.classes = [ ... a context only for classes ... ];
21
- * ```
22
- *
23
- * The styling context is created each time there are one or more
24
- * styling bindings (style or class bindings) present for an element,
25
- * but is only created once per `TNode`.
26
- *
27
- * `tNode.styles` and `tNode.classes` can be an instance of the following:
28
- *
29
- * ```typescript
30
- * tNode.styles = null; // no static styling or styling bindings active
31
- * tNode.styles = StylingMapArray; // only static values present (e.g. `<div style="width:200">`)
32
- * tNode.styles = TStylingContext; // one or more styling bindings present (e.g. `<div
33
- * [style.width]>`)
34
- * ```
35
- *
36
- * Both `tNode.styles` and `tNode.classes` are instantiated when anything
37
- * styling-related is active on an element. They are first created from
38
- * from the any of the element-level instructions (e.g. `element`,
39
- * `elementStart`, `elementHostAttrs`). When any static style/class
40
- * values are encountered they are registered on the `tNode.styles`
41
- * and `tNode.classes` data-structures. By default (when any static
42
- * values are encountered) the `tNode.styles` or `tNode.classes` values
43
- * are instances of a `StylingMapArray`. Only when style/class bindings
44
- * are detected then that styling map is converted into an instance of
45
- * `TStylingContext`.
46
- *
47
- * Due to the fact the the `TStylingContext` is stored on a `TNode`
48
- * this means that all data within the context is static. Instead of
49
- * storing actual styling binding values, the lView binding index values
50
- * are stored within the context. (static nature means it is more compact.)
51
- *
52
- * The code below shows a breakdown of two instances of `TStylingContext`
53
- * (one for `tNode.styles` and another for `tNode.classes`):
54
- *
55
- * ```typescript
56
- * // <div [class.active]="c" // lView binding index = 20
57
- * // [style.width]="x" // lView binding index = 21
58
- * // [style.height]="y"> // lView binding index = 22
59
- * // ...
60
- * // </div>
61
- * tNode.styles = [
62
- * 1, // the total amount of sources present (only `1` b/c there are only template
63
- * bindings)
64
- * [null], // initial values array (an instance of `StylingMapArray`)
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 { assertNumber, assertNumberInRange } from '../../util/assert';
14
+ /**
15
+ * Store the static values for the styling binding.
65
16
  *
66
- * 0, // config entry for the property (see `TStylingContextPropConfigFlags`)
67
- * 0b010, // template guard mask for height
68
- * 0, // host bindings guard mask for height
69
- * 'height', // the property name
70
- * 22, // the binding location for the "y" binding in the lView
71
- * null, // the default value for height
17
+ * The `TStylingStatic` is just `KeyValueArray` where key `""` (stored at location 0) contains the
18
+ * `TStylingKey` (stored at location 1). In other words this wraps the `TStylingKey` such that the
19
+ * `""` contains the wrapped value.
72
20
  *
73
- * 0, // config entry for the property (see `TStylingContextPropConfigFlags`)
74
- * 0b001, // template guard mask for width
75
- * 0, // host bindings guard mask for width
76
- * 'width', // the property name
77
- * 21, // the binding location for the "x" binding in the lView
78
- * null, // the default value for width
79
- * ];
21
+ * When instructions are resolving styling they may need to look forward or backwards in the linked
22
+ * list to resolve the value. For this reason we have to make sure that he linked list also contains
23
+ * the static values. However the list only has space for one item per styling instruction. For this
24
+ * reason we store the static values here as part of the `TStylingKey`. This means that the
25
+ * resolution function when looking for a value needs to first look at the binding value, and than
26
+ * at `TStylingKey` (if it exists).
80
27
  *
81
- * tNode.classes = [
82
- * 0, // the context config value (see `TStylingContextConfig`)
83
- * 1, // the total amount of sources present (only `1` b/c there are only template
84
- * bindings)
85
- * [null], // initial values array (an instance of `StylingMapArray`)
28
+ * Imagine we have:
86
29
  *
87
- * 0, // config entry for the property (see `TStylingContextPropConfigFlags`)
88
- * 0b001, // template guard mask for width
89
- * 0, // host bindings guard mask for width
90
- * 'active', // the property name
91
- * 20, // the binding location for the "c" binding in the lView
92
- * null, // the default value for the `active` class
93
- * ];
94
30
  * ```
31
+ * <div class="TEMPLATE" my-dir>
95
32
  *
96
- * Entry value present in an entry (called a tuple) within the
97
- * styling context is as follows:
98
- *
99
- * ```typescript
100
- * context = [
101
- * //...
102
- * configValue,
103
- * templateGuardMask,
104
- * hostBindingsGuardMask,
105
- * propName,
106
- * ...bindingIndices...,
107
- * defaultValue
108
- * //...
109
- * ];
33
+ * \@Directive({
34
+ * host: {
35
+ * class: 'DIR',
36
+ * '[class.dynamic]': 'exp' // ɵɵclassProp('dynamic', ctx.exp);
37
+ * }
38
+ * })
110
39
  * ```
111
40
  *
112
- * Below is a breakdown of each value:
113
- *
114
- * - **configValue**:
115
- * Property-specific configuration values. The only config setting
116
- * that is implemented right now is whether or not to sanitize the
117
- * value.
118
- *
119
- * - **templateGuardMask**:
120
- * A numeric value where each bit represents a binding index
121
- * location. Each binding index location is assigned based on
122
- * a local counter value that increments each time an instruction
123
- * is called:
41
+ * In the above case the linked list will contain one item:
124
42
  *
125
43
  * ```
126
- * <div [style.width]="x" // binding index = 21 (counter index = 0)
127
- * [style.height]="y"> // binding index = 22 (counter index = 1)
44
+ * // assume binding location: 10 for `ɵɵclassProp('dynamic', ctx.exp);`
45
+ * tData[10] = <TStylingStatic>[
46
+ * '': 'dynamic', // This is the wrapped value of `TStylingKey`
47
+ * 'DIR': true, // This is the default static value of directive binding.
48
+ * ];
49
+ * tData[10 + 1] = 0; // We don't have prev/next.
50
+ *
51
+ * lView[10] = undefined; // assume `ctx.exp` is `undefined`
52
+ * lView[10 + 1] = undefined; // Just normalized `lView[10]`
128
53
  * ```
129
54
  *
130
- * In the example code above, if the `width` value where to change
131
- * then the first bit in the local bit mask value would be flipped
132
- * (and the second bit for when `height`).
133
- *
134
- * If and when there are more than 32 binding sources in the context
135
- * (more than 32 `[style/class]` bindings) then the bit masking will
136
- * overflow and we are left with a situation where a `-1` value will
137
- * represent the bit mask. Due to the way that JavaScript handles
138
- * negative values, when the bit mask is `-1` then all bits within
139
- * that value will be automatically flipped (this is a quick and
140
- * efficient way to flip all bits on the mask when a special kind
141
- * of caching scenario occurs or when there are more than 32 bindings).
142
- *
143
- * - **hostBindingsGuardMask**:
144
- * Another instance of a guard mask that is specific to host bindings.
145
- * This behaves exactly the same way as does the `templateGuardMask`,
146
- * but will not contain any binding information processed in the template.
147
- * The reason why there are two instances of guard masks (one for the
148
- * template and another for host bindings) is because the template bindings
149
- * are processed before host bindings and the state information is not
150
- * carried over into the host bindings code. As soon as host bindings are
151
- * processed for an element the counter and state-based bit mask values are
152
- * set to `0`.
55
+ * So when the function is resolving styling value, it first needs to look into the linked list
56
+ * (there is none) and than into the static `TStylingStatic` too see if there is a default value for
57
+ * `dynamic` (there is not). Therefore it is safe to remove it.
153
58
  *
59
+ * If setting `true` case:
154
60
  * ```
155
- * <div [style.width]="x" // binding index = 21 (counter index = 0)
156
- * [style.height]="y" // binding index = 22 (counter index = 1)
157
- * dir-that-sets-width // binding index = 30 (counter index = 0)
158
- * dir-that-sets-width> // binding index = 31 (counter index = 1)
61
+ * lView[10] = true; // assume `ctx.exp` is `true`
62
+ * lView[10 + 1] = true; // Just normalized `lView[10]`
159
63
  * ```
160
- *
161
- * - **propName**:
162
- * The CSS property name or class name (e.g `width` or `active`).
163
- *
164
- * - **bindingIndices...**:
165
- * A series of numeric binding values that reflect where in the
166
- * lView to find the style/class values associated with the property.
167
- * Each value is in order in terms of priority (templates are first,
168
- * then directives and then components). When the context is flushed
169
- * and the style/class values are applied to the element (this happens
170
- * inside of the `stylingApply` instruction) then the flushing code
171
- * will keep checking each binding index against the associated lView
172
- * to find the first style/class value that is non-null.
173
- *
174
- * - **defaultValue**:
175
- * This is the default that will always be applied to the element if
176
- * and when all other binding sources return a result that is null.
177
- * Usually this value is `null` but it can also be a static value that
178
- * is intercepted when the tNode is first constructured (e.g.
179
- * `<div style="width:200px">` has a default value of `200px` for
180
- * the `width` property).
181
- *
182
- * Each time a new binding is encountered it is registered into the
183
- * context. The context then is continually updated until the first
184
- * styling apply call has been called (which is automatically scheduled
185
- * to be called once an element exits during change detection). Note that
186
- * each entry in the context is stored in alphabetical order.
187
- *
188
- * Once styling has been flushed for the first time for an element the
189
- * context will set as locked (this prevents bindings from being added
190
- * to the context later on).
191
- *
192
- * # How Styles/Classes are Rendered
193
- * Each time a styling instruction (e.g. `[class.name]`, `[style.prop]`,
194
- * etc...) is executed, the associated `lView` for the view is updated
195
- * at the current binding location. Also, when this happens, a local
196
- * counter value is incremented. If the binding value has changed then
197
- * a local `bitMask` variable is updated with the specific bit based
198
- * on the counter value.
199
- *
200
- * Below is a lightweight example of what happens when a single style
201
- * property is updated (i.e. `<div [style.prop]="val">`):
202
- *
203
- * ```typescript
204
- * function updateStyleProp(prop: string, value: string) {
205
- * const lView = getLView();
206
- * const bindingIndex = BINDING_INDEX++;
207
- *
208
- * // update the local counter value
209
- * const indexForStyle = stylingState.stylesCount++;
210
- * if (lView[bindingIndex] !== value) {
211
- * lView[bindingIndex] = value;
212
- *
213
- * // tell the local state that we have updated a style value
214
- * // by updating the bit mask
215
- * stylingState.bitMaskForStyles |= 1 << indexForStyle;
216
- * }
217
- * }
64
+ * So when the function is resolving styling value, it first needs to look into the linked list
65
+ * (there is none) and than into `TNode.residualClass` (TNode.residualStyle) which contains
218
66
  * ```
219
- *
220
- * Once all the bindings have updated a `bitMask` value will be populated.
221
- * This `bitMask` value is used in the apply algorithm (which is called
222
- * context resolution).
223
- *
224
- * ## The Apply Algorithm (Context Resolution)
225
- * As explained above, each time a binding updates its value, the resulting
226
- * value is stored in the `lView` array. These styling values have yet to
227
- * be flushed to the element.
228
- *
229
- * Once all the styling instructions have been evaluated, then the styling
230
- * context(s) are flushed to the element. When this happens, the context will
231
- * be iterated over (property by property) and each binding source will be
232
- * examined and the first non-null value will be applied to the element.
233
- *
234
- * Let's say that we the following template code:
235
- *
236
- * ```html
237
- * <div [style.width]="w1" dir-that-set-width="w2"></div>
67
+ * tNode.residualClass = [
68
+ * 'TEMPLATE': true,
69
+ * ];
238
70
  * ```
239
71
  *
240
- * There are two styling bindings in the code above and they both write
241
- * to the `width` property. When styling is flushed on the element, the
242
- * algorithm will try and figure out which one of these values to write
243
- * to the element.
244
- *
245
- * In order to figure out which value to apply, the following
246
- * binding prioritization is adhered to:
247
- *
248
- * 1. First template-level styling bindings are applied (if present).
249
- * This includes things like `[style.width]` and `[class.active]`.
250
- *
251
- * 2. Second are styling-level host bindings present in directives.
252
- * (if there are sub/super directives present then the sub directives
253
- * are applied first).
254
- *
255
- * 3. Third are styling-level host bindings present in components.
256
- * (if there are sub/super components present then the sub directives
257
- * are applied first).
258
- *
259
- * This means that in the code above the styling binding present in the
260
- * template is applied first and, only if its falsy, then the directive
261
- * styling binding for width will be applied.
262
- *
263
- * ### What about map-based styling bindings?
264
- * Map-based styling bindings are activated when there are one or more
265
- * `[style]` and/or `[class]` bindings present on an element. When this
266
- * code is activated, the apply algorithm will iterate over each map
267
- * entry and apply each styling value to the element with the same
268
- * prioritization rules as above.
269
- *
270
- * For the algorithm to apply styling values efficiently, the
271
- * styling map entries must be applied in sync (property by property)
272
- * with prop-based bindings. (The map-based algorithm is described
273
- * more inside of the `render3/styling/map_based_bindings.ts` file.)
274
- *
275
- * ## Sanitization
276
- * Sanitization is used to prevent invalid style values from being applied to
277
- * the element.
278
- *
279
- * It is enabled in two cases:
280
- *
281
- * 1. The `styleSanitizer(sanitizerFn)` instruction was called (just before any other
282
- * styling instructions are run).
283
- *
284
- * 2. The component/directive `LView` instance has a sanitizer object attached to it
285
- * (this happens when `renderComponent` is executed with a `sanitizer` value or
286
- * if the ngModule contains a sanitizer provider attached to it).
72
+ * This means that it is safe to add class.
73
+ * @record
74
+ */
75
+ export function TStylingStatic() { }
76
+ /**
77
+ * This is a branded number which contains previous and next index.
287
78
  *
288
- * If and when sanitization is active then all property/value entries will be evaluated
289
- * through the active sanitizer before they are applied to the element (or the styling
290
- * debug handler).
79
+ * When we come across styling instructions we need to store the `TStylingKey` in the correct
80
+ * order so that we can re-concatenate the styling value in the desired priority.
291
81
  *
292
- * If a `Sanitizer` object is used (via the `LView[SANITIZER]` value) then that object
293
- * will be used for every property.
82
+ * The insertion can happen either at the:
83
+ * - end of template as in the case of coming across additional styling instruction in the template
84
+ * - in front of the template in the case of coming across additional instruction in the
85
+ * `hostBindings`.
294
86
  *
295
- * If a `StyleSanitizerFn` function is used (via the `styleSanitizer`) then it will be
296
- * called in two ways:
87
+ * We use `TStylingRange` to store the previous and next index into the `TData` where the template
88
+ * bindings can be found.
297
89
  *
298
- * 1. property validation mode: this will be called early to mark whether a property
299
- * should be sanitized or not at during the flushing stage.
90
+ * - bit 0 is used to mark that the previous index has a duplicate for current value.
91
+ * - bit 1 is used to mark that the next index has a duplicate for the current value.
92
+ * - bits 2-16 are used to encode the next/tail of the template.
93
+ * - bits 17-32 are used to encode the previous/head of template.
300
94
  *
301
- * 2. value sanitization mode: this will be called during the flushing stage and will
302
- * run the sanitizer function against the value before applying it to the element.
95
+ * NODE: *duplicate* false implies that it is statically known that this binding will not collide
96
+ * with other bindings and therefore there is no need to check other bindings. For example the
97
+ * bindings in `<div [style.color]="exp" [style.width]="exp">` will never collide and will have
98
+ * their bits set accordingly. Previous duplicate means that we may need to check previous if the
99
+ * current binding is `null`. Next duplicate means that we may need to check next bindings if the
100
+ * current binding is not `null`.
303
101
  *
304
- * If sanitization returns an empty value then that empty value will be applied
305
- * to the element.
102
+ * NOTE: `0` has special significance and represents `null` as in no additional pointer.
306
103
  * @record
307
104
  */
308
- export function TStylingContext() { }
105
+ export function TStylingRange() { }
309
106
  if (false) {
310
- /* Skipping unnamed member:
311
- [TStylingContextIndex.TotalSourcesPosition]: number;*/
312
- /* Skipping unnamed member:
313
- [TStylingContextIndex.InitialStylingValuePosition]: StylingMapArray;*/
107
+ /** @type {?} */
108
+ TStylingRange.prototype.__brand__;
314
109
  }
315
110
  /** @enum {number} */
316
- const TStylingContextIndex = {
317
- TotalSourcesPosition: 0,
318
- InitialStylingValuePosition: 1,
319
- ValuesStartPosition: 2,
320
- // each tuple entry in the context
321
- // (config, templateBitGuard, hostBindingBitGuard, prop, ...bindings||default-value)
322
- ConfigOffset: 0,
323
- TemplateBitGuardOffset: 1,
324
- HostBindingsBitGuardOffset: 2,
325
- PropOffset: 3,
326
- BindingsStartOffset: 4,
111
+ const StylingRange = {
112
+ /// Number of bits to shift for the previous pointer
113
+ PREV_SHIFT: 17,
114
+ /// Previous pointer mask.
115
+ PREV_MASK: 4294836224,
116
+ /// Number of bits to shift for the next pointer
117
+ NEXT_SHIFT: 2,
118
+ /// Next pointer mask.
119
+ NEXT_MASK: 131068,
120
+ // Mask to remove nagative bit. (interpret number as positive)
121
+ UNSIGNED_MASK: 32767,
122
+ /**
123
+ * This bit is set if the previous bindings contains a binding which could possibly cause a
124
+ * duplicate. For example: `<div [style]="map" [style.width]="width">`, the `width` binding will
125
+ * have previous duplicate set. The implication is that if `width` binding becomes `null`, it is
126
+ * necessary to defer the value to `map.width`. (Because `width` overwrites `map.width`.)
127
+ */
128
+ PREV_DUPLICATE: 2,
129
+ /**
130
+ * This bit is set to if the next binding contains a binding which could possibly cause a
131
+ * duplicate. For example: `<div [style]="map" [style.width]="width">`, the `map` binding will
132
+ * have next duplicate set. The implication is that if `map.width` binding becomes not `null`, it
133
+ * is necessary to defer the value to `width`. (Because `width` overwrites `map.width`.)
134
+ */
135
+ NEXT_DUPLICATE: 1,
327
136
  };
328
- export { TStylingContextIndex };
329
- /** @enum {number} */
330
- const TStylingContextPropConfigFlags = {
331
- Default: 0,
332
- SanitizationRequired: 1,
333
- TotalBits: 1,
334
- Mask: 1,
335
- };
336
- export { TStylingContextPropConfigFlags };
137
+ export { StylingRange };
337
138
  /**
338
- * A function used to apply or remove styling from an element for a given property.
339
- * @record
139
+ * @param {?} prev
140
+ * @param {?} next
141
+ * @return {?}
340
142
  */
341
- export function ApplyStylingFn() { }
143
+ export function toTStylingRange(prev, next) {
144
+ ngDevMode && assertNumberInRange(prev, 0, 32767 /* UNSIGNED_MASK */);
145
+ ngDevMode && assertNumberInRange(next, 0, 32767 /* UNSIGNED_MASK */);
146
+ return (/** @type {?} */ ((prev << 17 /* PREV_SHIFT */ | next << 2 /* NEXT_SHIFT */)));
147
+ }
342
148
  /**
343
- * Array-based representation of a key/value array.
344
- *
345
- * The format of the array is "property", "value", "property2",
346
- * "value2", etc...
347
- *
348
- * The first value in the array is reserved to store the instance
349
- * of the key/value array that was used to populate the property/
350
- * value entries that take place in the remainder of the array.
351
- * @record
149
+ * @param {?} tStylingRange
150
+ * @return {?}
352
151
  */
353
- export function StylingMapArray() { }
354
- if (false) {
355
- /* Skipping unnamed member:
356
- [StylingMapArrayIndex.RawValuePosition]: {}|string|number|null|undefined;*/
152
+ export function getTStylingRangePrev(tStylingRange) {
153
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
154
+ return (((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) >> 17 /* PREV_SHIFT */) & 32767 /* UNSIGNED_MASK */;
357
155
  }
358
- /** @enum {number} */
359
- const StylingMapArrayIndex = {
360
- /** Where the values start in the array */
361
- ValuesStartPosition: 1,
362
- /** The location of the raw key/value map instance used last to populate the array entries */
363
- RawValuePosition: 0,
364
- /** The size of each property/value entry */
365
- TupleSize: 2,
366
- /** The offset for the property entry in the tuple */
367
- PropOffset: 0,
368
- /** The offset for the value entry in the tuple */
369
- ValueOffset: 1,
370
- };
371
- export { StylingMapArrayIndex };
372
156
  /**
373
- * Used to apply/traverse across all map-based styling entries up to the provided `targetProp`
374
- * value.
375
- *
376
- * When called, each of the map-based `StylingMapArray` entries (which are stored in
377
- * the provided `LStylingData` array) will be iterated over. Depending on the provided
378
- * `mode` value, each prop/value entry may be applied or skipped over.
379
- *
380
- * If `targetProp` value is provided the iteration code will stop once it reaches
381
- * the property (if found). Otherwise if the target property is not encountered then
382
- * it will stop once it reaches the next value that appears alphabetically after it.
383
- *
384
- * If a `defaultValue` is provided then it will be applied to the element only if the
385
- * `targetProp` property value is encountered and the value associated with the target
386
- * property is `null`. The reason why the `defaultValue` is needed is to avoid having the
387
- * algorithm apply a `null` value and then apply a default value afterwards (this would
388
- * end up being two style property writes).
389
- *
390
- * @return whether or not the target property was reached and its value was
391
- * applied to the element.
392
- * @record
157
+ * @param {?} tStylingRange
158
+ * @return {?}
393
159
  */
394
- export function SyncStylingMapsFn() { }
395
- /** @enum {number} */
396
- const StylingMapsSyncMode = {
397
- /** Only traverse values (no prop/value styling entries get applied) */
398
- TraverseValues: 0,
399
- /** Apply every prop/value styling entry to the element */
400
- ApplyAllValues: 1,
401
- /** Only apply the target prop/value entry */
402
- ApplyTargetProp: 2,
403
- /** Skip applying the target prop/value entry */
404
- SkipTargetProp: 4,
405
- /** Iterate over inner maps map values in the context */
406
- RecurseInnerMaps: 8,
407
- /** Only check to see if a value was set somewhere in each map */
408
- CheckValuesOnly: 16,
409
- };
410
- export { StylingMapsSyncMode };
160
+ export function getTStylingRangePrevDuplicate(tStylingRange) {
161
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
162
+ return (((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) & 2 /* PREV_DUPLICATE */) ==
163
+ 2 /* PREV_DUPLICATE */;
164
+ }
411
165
  /**
412
- * Simplified `TNode` interface for styling-related code.
413
- *
414
- * The styling algorithm code only needs access to `flags`.
415
- * @record
166
+ * @param {?} tStylingRange
167
+ * @param {?} previous
168
+ * @return {?}
416
169
  */
417
- export function TStylingNode() { }
418
- if (false) {
170
+ export function setTStylingRangePrev(tStylingRange, previous) {
171
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
172
+ ngDevMode && assertNumberInRange(previous, 0, 32767 /* UNSIGNED_MASK */);
173
+ return (/** @type {?} */ (((((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) & ~4294836224 /* PREV_MASK */) |
174
+ (previous << 17 /* PREV_SHIFT */))));
175
+ }
176
+ /**
177
+ * @param {?} tStylingRange
178
+ * @return {?}
179
+ */
180
+ export function setTStylingRangePrevDuplicate(tStylingRange) {
181
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
182
+ return (/** @type {?} */ ((((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) | 2 /* PREV_DUPLICATE */)));
183
+ }
184
+ /**
185
+ * @param {?} tStylingRange
186
+ * @return {?}
187
+ */
188
+ export function getTStylingRangeNext(tStylingRange) {
189
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
190
+ return (((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) & 131068 /* NEXT_MASK */) >> 2 /* NEXT_SHIFT */;
191
+ }
192
+ /**
193
+ * @param {?} tStylingRange
194
+ * @param {?} next
195
+ * @return {?}
196
+ */
197
+ export function setTStylingRangeNext(tStylingRange, next) {
198
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
199
+ ngDevMode && assertNumberInRange(next, 0, 32767 /* UNSIGNED_MASK */);
200
+ return (/** @type {?} */ (((((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) & ~131068 /* NEXT_MASK */) | //
201
+ next << 2 /* NEXT_SHIFT */)));
202
+ }
203
+ /**
204
+ * @param {?} tStylingRange
205
+ * @return {?}
206
+ */
207
+ export function getTStylingRangeNextDuplicate(tStylingRange) {
208
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
209
+ return (((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) & 1 /* NEXT_DUPLICATE */) ===
210
+ 1 /* NEXT_DUPLICATE */;
211
+ }
212
+ /**
213
+ * @param {?} tStylingRange
214
+ * @return {?}
215
+ */
216
+ export function setTStylingRangeNextDuplicate(tStylingRange) {
217
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
218
+ return (/** @type {?} */ ((((/** @type {?} */ ((/** @type {?} */ (tStylingRange))))) | 1 /* NEXT_DUPLICATE */)));
219
+ }
220
+ /**
221
+ * @param {?} tStylingRange
222
+ * @return {?}
223
+ */
224
+ export function getTStylingRangeTail(tStylingRange) {
225
+ ngDevMode && assertNumber(tStylingRange, 'expected number');
419
226
  /** @type {?} */
420
- TStylingNode.prototype.flags;
227
+ const next = getTStylingRangeNext(tStylingRange);
228
+ return next === 0 ? getTStylingRangePrev(tStylingRange) : next;
421
229
  }
422
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvaW50ZXJmYWNlcy9zdHlsaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFxVUEscUNBT0M7Ozs7Ozs7O0FBS0QsTUFBa0Isb0JBQW9CO0lBQ3BDLG9CQUFvQixHQUFJO0lBQ3hCLDJCQUEyQixHQUFJO0lBQy9CLG1CQUFtQixHQUFJO0lBRXZCLGtDQUFrQztJQUNsQyxvRkFBb0Y7SUFDcEYsWUFBWSxHQUFJO0lBQ2hCLHNCQUFzQixHQUFJO0lBQzFCLDBCQUEwQixHQUFJO0lBQzlCLFVBQVUsR0FBSTtJQUNkLG1CQUFtQixHQUFJO0VBQ3hCOzs7QUFLRCxNQUFrQiw4QkFBOEI7SUFDOUMsT0FBTyxHQUFNO0lBQ2Isb0JBQW9CLEdBQU07SUFDMUIsU0FBUyxHQUFJO0lBQ2IsSUFBSSxHQUFNO0VBQ1g7Ozs7OztBQUtELG9DQUdDOzs7Ozs7Ozs7Ozs7QUFzQkQscUNBS0M7Ozs7OztBQUtELE1BQWtCLG9CQUFvQjtJQUNwQywwQ0FBMEM7SUFDMUMsbUJBQW1CLEdBQUk7SUFFdkIsNkZBQTZGO0lBQzdGLGdCQUFnQixHQUFJO0lBRXBCLDRDQUE0QztJQUM1QyxTQUFTLEdBQUk7SUFFYixxREFBcUQ7SUFDckQsVUFBVSxHQUFJO0lBRWQsa0RBQWtEO0lBQ2xELFdBQVcsR0FBSTtFQUNoQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBdUJELHVDQUtDOztBQUtELE1BQWtCLG1CQUFtQjtJQUNuQyx1RUFBdUU7SUFDdkUsY0FBYyxHQUFRO0lBRXRCLDBEQUEwRDtJQUMxRCxjQUFjLEdBQVE7SUFFdEIsNkNBQTZDO0lBQzdDLGVBQWUsR0FBUTtJQUV2QixnREFBZ0Q7SUFDaEQsY0FBYyxHQUFRO0lBRXRCLHdEQUF3RDtJQUN4RCxnQkFBZ0IsR0FBUztJQUV6QixpRUFBaUU7SUFDakUsZUFBZSxJQUFVO0VBQzFCOzs7Ozs7OztBQU9ELGtDQUFvRDs7O0lBQXBCLDZCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuKiBAbGljZW5zZVxuKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbipcbiogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuKi9cbmltcG9ydCB7U3R5bGVTYW5pdGl6ZUZufSBmcm9tICcuLi8uLi9zYW5pdGl6YXRpb24vc3R5bGVfc2FuaXRpemVyJztcblxuaW1wb3J0IHtUTm9kZUZsYWdzfSBmcm9tICcuL25vZGUnO1xuaW1wb3J0IHtQcm9jZWR1cmFsUmVuZGVyZXIzLCBSRWxlbWVudCwgUmVuZGVyZXIzfSBmcm9tICcuL3JlbmRlcmVyJztcbmltcG9ydCB7TFZpZXd9IGZyb20gJy4vdmlldyc7XG5cblxuLyoqXG4gKiAtLS0tLS0tLVxuICpcbiAqIFRoaXMgZmlsZSBjb250YWlucyB0aGUgY29yZSBpbnRlcmZhY2VzIGZvciBzdHlsaW5nIGluIEFuZ3VsYXIuXG4gKlxuICogVG8gbGVhcm4gbW9yZSBhYm91dCB0aGUgYWxnb3JpdGhtIHNlZSBgVFN0eWxpbmdDb250ZXh0YC5cbiAqXG4gKiAtLS0tLS0tLVxuICovXG5cbi8qKlxuICogQSBzdGF0aWMtbGV2ZWwgcmVwcmVzZW50YXRpb24gb2YgYWxsIHN0eWxlIG9yIGNsYXNzIGJpbmRpbmdzL3ZhbHVlc1xuICogYXNzb2NpYXRlZCB3aXRoIGEgYFROb2RlYC5cbiAqXG4gKiBUaGUgYFRTdHlsaW5nQ29udGV4dGAgdW5pdGVzIGFsbCB0ZW1wbGF0ZSBzdHlsaW5nIGJpbmRpbmdzIChpLmUuXG4gKiBgW2NsYXNzXWAgYW5kIGBbc3R5bGVdYCBiaW5kaW5ncykgYXMgd2VsbCBhcyBhbGwgaG9zdC1sZXZlbFxuICogc3R5bGluZyBiaW5kaW5ncyAoZm9yIGNvbXBvbmVudHMgYW5kIGRpcmVjdGl2ZXMpIHRvZ2V0aGVyIGludG9cbiAqIGEgc2luZ2xlIG1hbmlmZXN0XG4gKlxuICogVGhlIHN0eWxpbmcgY29udGV4dCBpcyBzdG9yZWQgb24gYSBgVE5vZGVgIG9uIGFuZCB0aGVyZSBhcmVcbiAqIHR3byBpbnN0YW5jZXMgb2YgaXQ6IG9uZSBmb3IgY2xhc3NlcyBhbmQgYW5vdGhlciBmb3Igc3R5bGVzLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHROb2RlLnN0eWxlcyA9IFsgLi4uIGEgY29udGV4dCBvbmx5IGZvciBzdHlsZXMgLi4uIF07XG4gKiB0Tm9kZS5jbGFzc2VzID0gWyAuLi4gYSBjb250ZXh0IG9ubHkgZm9yIGNsYXNzZXMgLi4uIF07XG4gKiBgYGBcbiAqXG4gKiBUaGUgc3R5bGluZyBjb250ZXh0IGlzIGNyZWF0ZWQgZWFjaCB0aW1lIHRoZXJlIGFyZSBvbmUgb3IgbW9yZVxuICogc3R5bGluZyBiaW5kaW5ncyAoc3R5bGUgb3IgY2xhc3MgYmluZGluZ3MpIHByZXNlbnQgZm9yIGFuIGVsZW1lbnQsXG4gKiBidXQgaXMgb25seSBjcmVhdGVkIG9uY2UgcGVyIGBUTm9kZWAuXG4gKlxuICogYHROb2RlLnN0eWxlc2AgYW5kIGB0Tm9kZS5jbGFzc2VzYCBjYW4gYmUgYW4gaW5zdGFuY2Ugb2YgdGhlIGZvbGxvd2luZzpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiB0Tm9kZS5zdHlsZXMgPSBudWxsOyAvLyBubyBzdGF0aWMgc3R5bGluZyBvciBzdHlsaW5nIGJpbmRpbmdzIGFjdGl2ZVxuICogdE5vZGUuc3R5bGVzID0gU3R5bGluZ01hcEFycmF5OyAvLyBvbmx5IHN0YXRpYyB2YWx1ZXMgcHJlc2VudCAoZS5nLiBgPGRpdiBzdHlsZT1cIndpZHRoOjIwMFwiPmApXG4gKiB0Tm9kZS5zdHlsZXMgPSBUU3R5bGluZ0NvbnRleHQ7IC8vIG9uZSBvciBtb3JlIHN0eWxpbmcgYmluZGluZ3MgcHJlc2VudCAoZS5nLiBgPGRpdlxuICogW3N0eWxlLndpZHRoXT5gKVxuICogYGBgXG4gKlxuICogQm90aCBgdE5vZGUuc3R5bGVzYCBhbmQgYHROb2RlLmNsYXNzZXNgIGFyZSBpbnN0YW50aWF0ZWQgd2hlbiBhbnl0aGluZ1xuICogc3R5bGluZy1yZWxhdGVkIGlzIGFjdGl2ZSBvbiBhbiBlbGVtZW50LiBUaGV5IGFyZSBmaXJzdCBjcmVhdGVkIGZyb21cbiAqIGZyb20gdGhlIGFueSBvZiB0aGUgZWxlbWVudC1sZXZlbCBpbnN0cnVjdGlvbnMgKGUuZy4gYGVsZW1lbnRgLFxuICogYGVsZW1lbnRTdGFydGAsIGBlbGVtZW50SG9zdEF0dHJzYCkuIFdoZW4gYW55IHN0YXRpYyBzdHlsZS9jbGFzc1xuICogdmFsdWVzIGFyZSBlbmNvdW50ZXJlZCB0aGV5IGFyZSByZWdpc3RlcmVkIG9uIHRoZSBgdE5vZGUuc3R5bGVzYFxuICogYW5kIGB0Tm9kZS5jbGFzc2VzYCBkYXRhLXN0cnVjdHVyZXMuIEJ5IGRlZmF1bHQgKHdoZW4gYW55IHN0YXRpY1xuICogdmFsdWVzIGFyZSBlbmNvdW50ZXJlZCkgdGhlIGB0Tm9kZS5zdHlsZXNgIG9yIGB0Tm9kZS5jbGFzc2VzYCB2YWx1ZXNcbiAqIGFyZSBpbnN0YW5jZXMgb2YgYSBgU3R5bGluZ01hcEFycmF5YC4gT25seSB3aGVuIHN0eWxlL2NsYXNzIGJpbmRpbmdzXG4gKiBhcmUgZGV0ZWN0ZWQgdGhlbiB0aGF0IHN0eWxpbmcgbWFwIGlzIGNvbnZlcnRlZCBpbnRvIGFuIGluc3RhbmNlIG9mXG4gKiBgVFN0eWxpbmdDb250ZXh0YC5cbiAqXG4gKiBEdWUgdG8gdGhlIGZhY3QgdGhlIHRoZSBgVFN0eWxpbmdDb250ZXh0YCBpcyBzdG9yZWQgb24gYSBgVE5vZGVgXG4gKiB0aGlzIG1lYW5zIHRoYXQgYWxsIGRhdGEgd2l0aGluIHRoZSBjb250ZXh0IGlzIHN0YXRpYy4gSW5zdGVhZCBvZlxuICogc3RvcmluZyBhY3R1YWwgc3R5bGluZyBiaW5kaW5nIHZhbHVlcywgdGhlIGxWaWV3IGJpbmRpbmcgaW5kZXggdmFsdWVzXG4gKiBhcmUgc3RvcmVkIHdpdGhpbiB0aGUgY29udGV4dC4gKHN0YXRpYyBuYXR1cmUgbWVhbnMgaXQgaXMgbW9yZSBjb21wYWN0LilcbiAqXG4gKiBUaGUgY29kZSBiZWxvdyBzaG93cyBhIGJyZWFrZG93biBvZiB0d28gaW5zdGFuY2VzIG9mIGBUU3R5bGluZ0NvbnRleHRgXG4gKiAob25lIGZvciBgdE5vZGUuc3R5bGVzYCBhbmQgYW5vdGhlciBmb3IgYHROb2RlLmNsYXNzZXNgKTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyA8ZGl2IFtjbGFzcy5hY3RpdmVdPVwiY1wiICAvLyBsVmlldyBiaW5kaW5nIGluZGV4ID0gMjBcbiAqIC8vICAgICAgW3N0eWxlLndpZHRoXT1cInhcIiAgIC8vIGxWaWV3IGJpbmRpbmcgaW5kZXggPSAyMVxuICogLy8gICAgICBbc3R5bGUuaGVpZ2h0XT1cInlcIj4gLy8gbFZpZXcgYmluZGluZyBpbmRleCA9IDIyXG4gKiAvLyAgLi4uXG4gKiAvLyA8L2Rpdj5cbiAqIHROb2RlLnN0eWxlcyA9IFtcbiAqICAgMSwgICAgICAgICAvLyB0aGUgdG90YWwgYW1vdW50IG9mIHNvdXJjZXMgcHJlc2VudCAob25seSBgMWAgYi9jIHRoZXJlIGFyZSBvbmx5IHRlbXBsYXRlXG4gKiBiaW5kaW5ncylcbiAqICAgW251bGxdLCAgICAvLyBpbml0aWFsIHZhbHVlcyBhcnJheSAoYW4gaW5zdGFuY2Ugb2YgYFN0eWxpbmdNYXBBcnJheWApXG4gKlxuICogICAwLCAgICAgICAgIC8vIGNvbmZpZyBlbnRyeSBmb3IgdGhlIHByb3BlcnR5IChzZWUgYFRTdHlsaW5nQ29udGV4dFByb3BDb25maWdGbGFnc2ApXG4gKiAgIDBiMDEwLCAgICAgLy8gdGVtcGxhdGUgZ3VhcmQgbWFzayBmb3IgaGVpZ2h0XG4gKiAgIDAsICAgICAgICAgLy8gaG9zdCBiaW5kaW5ncyBndWFyZCBtYXNrIGZvciBoZWlnaHRcbiAqICAgJ2hlaWdodCcsICAvLyB0aGUgcHJvcGVydHkgbmFtZVxuICogICAyMiwgICAgICAgIC8vIHRoZSBiaW5kaW5nIGxvY2F0aW9uIGZvciB0aGUgXCJ5XCIgYmluZGluZyBpbiB0aGUgbFZpZXdcbiAqICAgbnVsbCwgICAgICAvLyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgaGVpZ2h0XG4gKlxuICogICAwLCAgICAgICAgIC8vIGNvbmZpZyBlbnRyeSBmb3IgdGhlIHByb3BlcnR5IChzZWUgYFRTdHlsaW5nQ29udGV4dFByb3BDb25maWdGbGFnc2ApXG4gKiAgIDBiMDAxLCAgICAgLy8gdGVtcGxhdGUgZ3VhcmQgbWFzayBmb3Igd2lkdGhcbiAqICAgMCwgICAgICAgICAvLyBob3N0IGJpbmRpbmdzIGd1YXJkIG1hc2sgZm9yIHdpZHRoXG4gKiAgICd3aWR0aCcsICAgLy8gdGhlIHByb3BlcnR5IG5hbWVcbiAqICAgMjEsICAgICAgICAvLyB0aGUgYmluZGluZyBsb2NhdGlvbiBmb3IgdGhlIFwieFwiIGJpbmRpbmcgaW4gdGhlIGxWaWV3XG4gKiAgIG51bGwsICAgICAgLy8gdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHdpZHRoXG4gKiBdO1xuICpcbiAqIHROb2RlLmNsYXNzZXMgPSBbXG4gKiAgIDAsICAgICAgICAgLy8gdGhlIGNvbnRleHQgY29uZmlnIHZhbHVlIChzZWUgYFRTdHlsaW5nQ29udGV4dENvbmZpZ2ApXG4gKiAgIDEsICAgICAgICAgLy8gdGhlIHRvdGFsIGFtb3VudCBvZiBzb3VyY2VzIHByZXNlbnQgKG9ubHkgYDFgIGIvYyB0aGVyZSBhcmUgb25seSB0ZW1wbGF0ZVxuICogYmluZGluZ3MpXG4gKiAgIFtudWxsXSwgICAgLy8gaW5pdGlhbCB2YWx1ZXMgYXJyYXkgKGFuIGluc3RhbmNlIG9mIGBTdHlsaW5nTWFwQXJyYXlgKVxuICpcbiAqICAgMCwgICAgICAgICAvLyBjb25maWcgZW50cnkgZm9yIHRoZSBwcm9wZXJ0eSAoc2VlIGBUU3R5bGluZ0NvbnRleHRQcm9wQ29uZmlnRmxhZ3NgKVxuICogICAwYjAwMSwgICAgIC8vIHRlbXBsYXRlIGd1YXJkIG1hc2sgZm9yIHdpZHRoXG4gKiAgIDAsICAgICAgICAgLy8gaG9zdCBiaW5kaW5ncyBndWFyZCBtYXNrIGZvciB3aWR0aFxuICogICAnYWN0aXZlJywgIC8vIHRoZSBwcm9wZXJ0eSBuYW1lXG4gKiAgIDIwLCAgICAgICAgLy8gdGhlIGJpbmRpbmcgbG9jYXRpb24gZm9yIHRoZSBcImNcIiBiaW5kaW5nIGluIHRoZSBsVmlld1xuICogICBudWxsLCAgICAgIC8vIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUgYGFjdGl2ZWAgY2xhc3NcbiAqIF07XG4gKiBgYGBcbiAqXG4gKiBFbnRyeSB2YWx1ZSBwcmVzZW50IGluIGFuIGVudHJ5IChjYWxsZWQgYSB0dXBsZSkgd2l0aGluIHRoZVxuICogc3R5bGluZyBjb250ZXh0IGlzIGFzIGZvbGxvd3M6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogY29udGV4dCA9IFtcbiAqICAgLy8uLi5cbiAqICAgY29uZmlnVmFsdWUsXG4gKiAgIHRlbXBsYXRlR3VhcmRNYXNrLFxuICogICBob3N0QmluZGluZ3NHdWFyZE1hc2ssXG4gKiAgIHByb3BOYW1lLFxuICogICAuLi5iaW5kaW5nSW5kaWNlcy4uLixcbiAqICAgZGVmYXVsdFZhbHVlXG4gKiAgIC8vLi4uXG4gKiBdO1xuICogYGBgXG4gKlxuICogQmVsb3cgaXMgYSBicmVha2Rvd24gb2YgZWFjaCB2YWx1ZTpcbiAqXG4gKiAtICoqY29uZmlnVmFsdWUqKjpcbiAqICAgUHJvcGVydHktc3BlY2lmaWMgY29uZmlndXJhdGlvbiB2YWx1ZXMuIFRoZSBvbmx5IGNvbmZpZyBzZXR0aW5nXG4gKiAgIHRoYXQgaXMgaW1wbGVtZW50ZWQgcmlnaHQgbm93IGlzIHdoZXRoZXIgb3Igbm90IHRvIHNhbml0aXplIHRoZVxuICogICB2YWx1ZS5cbiAqXG4gKiAtICoqdGVtcGxhdGVHdWFyZE1hc2sqKjpcbiAqICAgQSBudW1lcmljIHZhbHVlIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHMgYSBiaW5kaW5nIGluZGV4XG4gKiAgIGxvY2F0aW9uLiBFYWNoIGJpbmRpbmcgaW5kZXggbG9jYXRpb24gaXMgYXNzaWduZWQgYmFzZWQgb25cbiAqICAgYSBsb2NhbCBjb3VudGVyIHZhbHVlIHRoYXQgaW5jcmVtZW50cyBlYWNoIHRpbWUgYW4gaW5zdHJ1Y3Rpb25cbiAqICAgaXMgY2FsbGVkOlxuICpcbiAqIGBgYFxuICogPGRpdiBbc3R5bGUud2lkdGhdPVwieFwiICAgLy8gYmluZGluZyBpbmRleCA9IDIxIChjb3VudGVyIGluZGV4ID0gMClcbiAqICAgICAgW3N0eWxlLmhlaWdodF09XCJ5XCI+IC8vIGJpbmRpbmcgaW5kZXggPSAyMiAoY291bnRlciBpbmRleCA9IDEpXG4gKiBgYGBcbiAqXG4gKiAgIEluIHRoZSBleGFtcGxlIGNvZGUgYWJvdmUsIGlmIHRoZSBgd2lkdGhgIHZhbHVlIHdoZXJlIHRvIGNoYW5nZVxuICogICB0aGVuIHRoZSBmaXJzdCBiaXQgaW4gdGhlIGxvY2FsIGJpdCBtYXNrIHZhbHVlIHdvdWxkIGJlIGZsaXBwZWRcbiAqICAgKGFuZCB0aGUgc2Vjb25kIGJpdCBmb3Igd2hlbiBgaGVpZ2h0YCkuXG4gKlxuICogICBJZiBhbmQgd2hlbiB0aGVyZSBhcmUgbW9yZSB0aGFuIDMyIGJpbmRpbmcgc291cmNlcyBpbiB0aGUgY29udGV4dFxuICogICAobW9yZSB0aGFuIDMyIGBbc3R5bGUvY2xhc3NdYCBiaW5kaW5ncykgdGhlbiB0aGUgYml0IG1hc2tpbmcgd2lsbFxuICogICBvdmVyZmxvdyBhbmQgd2UgYXJlIGxlZnQgd2l0aCBhIHNpdHVhdGlvbiB3aGVyZSBhIGAtMWAgdmFsdWUgd2lsbFxuICogICByZXByZXNlbnQgdGhlIGJpdCBtYXNrLiBEdWUgdG8gdGhlIHdheSB0aGF0IEphdmFTY3JpcHQgaGFuZGxlc1xuICogICBuZWdhdGl2ZSB2YWx1ZXMsIHdoZW4gdGhlIGJpdCBtYXNrIGlzIGAtMWAgdGhlbiBhbGwgYml0cyB3aXRoaW5cbiAqICAgdGhhdCB2YWx1ZSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZmxpcHBlZCAodGhpcyBpcyBhIHF1aWNrIGFuZFxuICogICBlZmZpY2llbnQgd2F5IHRvIGZsaXAgYWxsIGJpdHMgb24gdGhlIG1hc2sgd2hlbiBhIHNwZWNpYWwga2luZFxuICogICBvZiBjYWNoaW5nIHNjZW5hcmlvIG9jY3VycyBvciB3aGVuIHRoZXJlIGFyZSBtb3JlIHRoYW4gMzIgYmluZGluZ3MpLlxuICpcbiAqIC0gKipob3N0QmluZGluZ3NHdWFyZE1hc2sqKjpcbiAqICAgQW5vdGhlciBpbnN0YW5jZSBvZiBhIGd1YXJkIG1hc2sgdGhhdCBpcyBzcGVjaWZpYyB0byBob3N0IGJpbmRpbmdzLlxuICogICBUaGlzIGJlaGF2ZXMgZXhhY3RseSB0aGUgc2FtZSB3YXkgYXMgZG9lcyB0aGUgYHRlbXBsYXRlR3VhcmRNYXNrYCxcbiAqICAgYnV0IHdpbGwgbm90IGNvbnRhaW4gYW55IGJpbmRpbmcgaW5mb3JtYXRpb24gcHJvY2Vzc2VkIGluIHRoZSB0ZW1wbGF0ZS5cbiAqICAgVGhlIHJlYXNvbiB3aHkgdGhlcmUgYXJlIHR3byBpbnN0YW5jZXMgb2YgZ3VhcmQgbWFza3MgKG9uZSBmb3IgdGhlXG4gKiAgIHRlbXBsYXRlIGFuZCBhbm90aGVyIGZvciBob3N0IGJpbmRpbmdzKSBpcyBiZWNhdXNlIHRoZSB0ZW1wbGF0ZSBiaW5kaW5nc1xuICogICBhcmUgcHJvY2Vzc2VkIGJlZm9yZSBob3N0IGJpbmRpbmdzIGFuZCB0aGUgc3RhdGUgaW5mb3JtYXRpb24gaXMgbm90XG4gKiAgIGNhcnJpZWQgb3ZlciBpbnRvIHRoZSBob3N0IGJpbmRpbmdzIGNvZGUuIEFzIHNvb24gYXMgaG9zdCBiaW5kaW5ncyBhcmVcbiAqICAgcHJvY2Vzc2VkIGZvciBhbiBlbGVtZW50IHRoZSBjb3VudGVyIGFuZCBzdGF0ZS1iYXNlZCBiaXQgbWFzayB2YWx1ZXMgYXJlXG4gKiAgIHNldCB0byBgMGAuXG4gKlxuICogYGBgXG4gKiA8ZGl2IFtzdHlsZS53aWR0aF09XCJ4XCIgICAvLyBiaW5kaW5nIGluZGV4ID0gMjEgKGNvdW50ZXIgaW5kZXggPSAwKVxuICogICAgICBbc3R5bGUuaGVpZ2h0XT1cInlcIiAgLy8gYmluZGluZyBpbmRleCA9IDIyIChjb3VudGVyIGluZGV4ID0gMSlcbiAqICAgICAgZGlyLXRoYXQtc2V0cy13aWR0aCAgLy8gYmluZGluZyBpbmRleCA9IDMwIChjb3VudGVyIGluZGV4ID0gMClcbiAqICAgICAgZGlyLXRoYXQtc2V0cy13aWR0aD4gLy8gYmluZGluZyBpbmRleCA9IDMxIChjb3VudGVyIGluZGV4ID0gMSlcbiAqIGBgYFxuICpcbiAqIC0gKipwcm9wTmFtZSoqOlxuICogICBUaGUgQ1NTIHByb3BlcnR5IG5hbWUgb3IgY2xhc3MgbmFtZSAoZS5nIGB3aWR0aGAgb3IgYGFjdGl2ZWApLlxuICpcbiAqIC0gKipiaW5kaW5nSW5kaWNlcy4uLioqOlxuICogICBBIHNlcmllcyBvZiBudW1lcmljIGJpbmRpbmcgdmFsdWVzIHRoYXQgcmVmbGVjdCB3aGVyZSBpbiB0aGVcbiAqICAgbFZpZXcgdG8gZmluZCB0aGUgc3R5bGUvY2xhc3MgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcHJvcGVydHkuXG4gKiAgIEVhY2ggdmFsdWUgaXMgaW4gb3JkZXIgaW4gdGVybXMgb2YgcHJpb3JpdHkgKHRlbXBsYXRlcyBhcmUgZmlyc3QsXG4gKiAgIHRoZW4gZGlyZWN0aXZlcyBhbmQgdGhlbiBjb21wb25lbnRzKS4gV2hlbiB0aGUgY29udGV4dCBpcyBmbHVzaGVkXG4gKiAgIGFuZCB0aGUgc3R5bGUvY2xhc3MgdmFsdWVzIGFyZSBhcHBsaWVkIHRvIHRoZSBlbGVtZW50ICh0aGlzIGhhcHBlbnNcbiAqICAgaW5zaWRlIG9mIHRoZSBgc3R5bGluZ0FwcGx5YCBpbnN0cnVjdGlvbikgdGhlbiB0aGUgZmx1c2hpbmcgY29kZVxuICogICB3aWxsIGtlZXAgY2hlY2tpbmcgZWFjaCBiaW5kaW5nIGluZGV4IGFnYWluc3QgdGhlIGFzc29jaWF0ZWQgbFZpZXdcbiAqICAgdG8gZmluZCB0aGUgZmlyc3Qgc3R5bGUvY2xhc3MgdmFsdWUgdGhhdCBpcyBub24tbnVsbC5cbiAqXG4gKiAtICoqZGVmYXVsdFZhbHVlKio6XG4gKiAgIFRoaXMgaXMgdGhlIGRlZmF1bHQgdGhhdCB3aWxsIGFsd2F5cyBiZSBhcHBsaWVkIHRvIHRoZSBlbGVtZW50IGlmXG4gKiAgIGFuZCB3aGVuIGFsbCBvdGhlciBiaW5kaW5nIHNvdXJjZXMgcmV0dXJuIGEgcmVzdWx0IHRoYXQgaXMgbnVsbC5cbiAqICAgVXN1YWxseSB0aGlzIHZhbHVlIGlzIGBudWxsYCBidXQgaXQgY2FuIGFsc28gYmUgYSBzdGF0aWMgdmFsdWUgdGhhdFxuICogICBpcyBpbnRlcmNlcHRlZCB3aGVuIHRoZSB0Tm9kZSBpcyBmaXJzdCBjb25zdHJ1Y3R1cmVkIChlLmcuXG4gKiAgIGA8ZGl2IHN0eWxlPVwid2lkdGg6MjAwcHhcIj5gIGhhcyBhIGRlZmF1bHQgdmFsdWUgb2YgYDIwMHB4YCBmb3JcbiAqICAgdGhlIGB3aWR0aGAgcHJvcGVydHkpLlxuICpcbiAqIEVhY2ggdGltZSBhIG5ldyBiaW5kaW5nIGlzIGVuY291bnRlcmVkIGl0IGlzIHJlZ2lzdGVyZWQgaW50byB0aGVcbiAqIGNvbnRleHQuIFRoZSBjb250ZXh0IHRoZW4gaXMgY29udGludWFsbHkgdXBkYXRlZCB1bnRpbCB0aGUgZmlyc3RcbiAqIHN0eWxpbmcgYXBwbHkgY2FsbCBoYXMgYmVlbiBjYWxsZWQgKHdoaWNoIGlzIGF1dG9tYXRpY2FsbHkgc2NoZWR1bGVkXG4gKiB0byBiZSBjYWxsZWQgb25jZSBhbiBlbGVtZW50IGV4aXRzIGR1cmluZyBjaGFuZ2UgZGV0ZWN0aW9uKS4gTm90ZSB0aGF0XG4gKiBlYWNoIGVudHJ5IGluIHRoZSBjb250ZXh0IGlzIHN0b3JlZCBpbiBhbHBoYWJldGljYWwgb3JkZXIuXG4gKlxuICogT25jZSBzdHlsaW5nIGhhcyBiZWVuIGZsdXNoZWQgZm9yIHRoZSBmaXJzdCB0aW1lIGZvciBhbiBlbGVtZW50IHRoZVxuICogY29udGV4dCB3aWxsIHNldCBhcyBsb2NrZWQgKHRoaXMgcHJldmVudHMgYmluZGluZ3MgZnJvbSBiZWluZyBhZGRlZFxuICogdG8gdGhlIGNvbnRleHQgbGF0ZXIgb24pLlxuICpcbiAqICMgSG93IFN0eWxlcy9DbGFzc2VzIGFyZSBSZW5kZXJlZFxuICogRWFjaCB0aW1lIGEgc3R5bGluZyBpbnN0cnVjdGlvbiAoZS5nLiBgW2NsYXNzLm5hbWVdYCwgYFtzdHlsZS5wcm9wXWAsXG4gKiBldGMuLi4pIGlzIGV4ZWN1dGVkLCB0aGUgYXNzb2NpYXRlZCBgbFZpZXdgIGZvciB0aGUgdmlldyBpcyB1cGRhdGVkXG4gKiBhdCB0aGUgY3VycmVudCBiaW5kaW5nIGxvY2F0aW9uLiBBbHNvLCB3aGVuIHRoaXMgaGFwcGVucywgYSBsb2NhbFxuICogY291bnRlciB2YWx1ZSBpcyBpbmNyZW1lbnRlZC4gSWYgdGhlIGJpbmRpbmcgdmFsdWUgaGFzIGNoYW5nZWQgdGhlblxuICogYSBsb2NhbCBgYml0TWFza2AgdmFyaWFibGUgaXMgdXBkYXRlZCB3aXRoIHRoZSBzcGVjaWZpYyBiaXQgYmFzZWRcbiAqIG9uIHRoZSBjb3VudGVyIHZhbHVlLlxuICpcbiAqIEJlbG93IGlzIGEgbGlnaHR3ZWlnaHQgZXhhbXBsZSBvZiB3aGF0IGhhcHBlbnMgd2hlbiBhIHNpbmdsZSBzdHlsZVxuICogcHJvcGVydHkgaXMgdXBkYXRlZCAoaS5lLiBgPGRpdiBbc3R5bGUucHJvcF09XCJ2YWxcIj5gKTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBmdW5jdGlvbiB1cGRhdGVTdHlsZVByb3AocHJvcDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSB7XG4gKiAgIGNvbnN0IGxWaWV3ID0gZ2V0TFZpZXcoKTtcbiAqICAgY29uc3QgYmluZGluZ0luZGV4ID0gQklORElOR19JTkRFWCsrO1xuICpcbiAqICAgLy8gdXBkYXRlIHRoZSBsb2NhbCBjb3VudGVyIHZhbHVlXG4gKiAgIGNvbnN0IGluZGV4Rm9yU3R5bGUgPSBzdHlsaW5nU3RhdGUuc3R5bGVzQ291bnQrKztcbiAqICAgaWYgKGxWaWV3W2JpbmRpbmdJbmRleF0gIT09IHZhbHVlKSB7XG4gKiAgICAgbFZpZXdbYmluZGluZ0luZGV4XSA9IHZhbHVlO1xuICpcbiAqICAgICAvLyB0ZWxsIHRoZSBsb2NhbCBzdGF0ZSB0aGF0IHdlIGhhdmUgdXBkYXRlZCBhIHN0eWxlIHZhbHVlXG4gKiAgICAgLy8gYnkgdXBkYXRpbmcgdGhlIGJpdCBtYXNrXG4gKiAgICAgc3R5bGluZ1N0YXRlLmJpdE1hc2tGb3JTdHlsZXMgfD0gMSA8PCBpbmRleEZvclN0eWxlO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBPbmNlIGFsbCB0aGUgYmluZGluZ3MgaGF2ZSB1cGRhdGVkIGEgYGJpdE1hc2tgIHZhbHVlIHdpbGwgYmUgcG9wdWxhdGVkLlxuICogVGhpcyBgYml0TWFza2AgdmFsdWUgaXMgdXNlZCBpbiB0aGUgYXBwbHkgYWxnb3JpdGhtICh3aGljaCBpcyBjYWxsZWRcbiAqIGNvbnRleHQgcmVzb2x1dGlvbikuXG4gKlxuICogIyMgVGhlIEFwcGx5IEFsZ29yaXRobSAoQ29udGV4dCBSZXNvbHV0aW9uKVxuICogQXMgZXhwbGFpbmVkIGFib3ZlLCBlYWNoIHRpbWUgYSBiaW5kaW5nIHVwZGF0ZXMgaXRzIHZhbHVlLCB0aGUgcmVzdWx0aW5nXG4gKiB2YWx1ZSBpcyBzdG9yZWQgaW4gdGhlIGBsVmlld2AgYXJyYXkuIFRoZXNlIHN0eWxpbmcgdmFsdWVzIGhhdmUgeWV0IHRvXG4gKiBiZSBmbHVzaGVkIHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIE9uY2UgYWxsIHRoZSBzdHlsaW5nIGluc3RydWN0aW9ucyBoYXZlIGJlZW4gZXZhbHVhdGVkLCB0aGVuIHRoZSBzdHlsaW5nXG4gKiBjb250ZXh0KHMpIGFyZSBmbHVzaGVkIHRvIHRoZSBlbGVtZW50LiBXaGVuIHRoaXMgaGFwcGVucywgdGhlIGNvbnRleHQgd2lsbFxuICogYmUgaXRlcmF0ZWQgb3ZlciAocHJvcGVydHkgYnkgcHJvcGVydHkpIGFuZCBlYWNoIGJpbmRpbmcgc291cmNlIHdpbGwgYmVcbiAqIGV4YW1pbmVkIGFuZCB0aGUgZmlyc3Qgbm9uLW51bGwgdmFsdWUgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIExldCdzIHNheSB0aGF0IHdlIHRoZSBmb2xsb3dpbmcgdGVtcGxhdGUgY29kZTpcbiAqXG4gKiBgYGBodG1sXG4gKiA8ZGl2IFtzdHlsZS53aWR0aF09XCJ3MVwiIGRpci10aGF0LXNldC13aWR0aD1cIncyXCI+PC9kaXY+XG4gKiBgYGBcbiAqXG4gKiBUaGVyZSBhcmUgdHdvIHN0eWxpbmcgYmluZGluZ3MgaW4gdGhlIGNvZGUgYWJvdmUgYW5kIHRoZXkgYm90aCB3cml0ZVxuICogdG8gdGhlIGB3aWR0aGAgcHJvcGVydHkuIFdoZW4gc3R5bGluZyBpcyBmbHVzaGVkIG9uIHRoZSBlbGVtZW50LCB0aGVcbiAqIGFsZ29yaXRobSB3aWxsIHRyeSBhbmQgZmlndXJlIG91dCB3aGljaCBvbmUgb2YgdGhlc2UgdmFsdWVzIHRvIHdyaXRlXG4gKiB0byB0aGUgZWxlbWVudC5cbiAqXG4gKiBJbiBvcmRlciB0byBmaWd1cmUgb3V0IHdoaWNoIHZhbHVlIHRvIGFwcGx5LCB0aGUgZm9sbG93aW5nXG4gKiBiaW5kaW5nIHByaW9yaXRpemF0aW9uIGlzIGFkaGVyZWQgdG86XG4gKlxuICogICAxLiBGaXJzdCB0ZW1wbGF0ZS1sZXZlbCBzdHlsaW5nIGJpbmRpbmdzIGFyZSBhcHBsaWVkIChpZiBwcmVzZW50KS5cbiAqICAgICAgVGhpcyBpbmNsdWRlcyB0aGluZ3MgbGlrZSBgW3N0eWxlLndpZHRoXWAgYW5kIGBbY2xhc3MuYWN0aXZlXWAuXG4gKlxuICogICAyLiBTZWNvbmQgYXJlIHN0eWxpbmctbGV2ZWwgaG9zdCBiaW5kaW5ncyBwcmVzZW50IGluIGRpcmVjdGl2ZXMuXG4gKiAgICAgIChpZiB0aGVyZSBhcmUgc3ViL3N1cGVyIGRpcmVjdGl2ZXMgcHJlc2VudCB0aGVuIHRoZSBzdWIgZGlyZWN0aXZlc1xuICogICAgICBhcmUgYXBwbGllZCBmaXJzdCkuXG4gKlxuICogICAzLiBUaGlyZCBhcmUgc3R5bGluZy1sZXZlbCBob3N0IGJpbmRpbmdzIHByZXNlbnQgaW4gY29tcG9uZW50cy5cbiAqICAgICAgKGlmIHRoZXJlIGFyZSBzdWIvc3VwZXIgY29tcG9uZW50cyBwcmVzZW50IHRoZW4gdGhlIHN1YiBkaXJlY3RpdmVzXG4gKiAgICAgIGFyZSBhcHBsaWVkIGZpcnN0KS5cbiAqXG4gKiBUaGlzIG1lYW5zIHRoYXQgaW4gdGhlIGNvZGUgYWJvdmUgdGhlIHN0eWxpbmcgYmluZGluZyBwcmVzZW50IGluIHRoZVxuICogdGVtcGxhdGUgaXMgYXBwbGllZCBmaXJzdCBhbmQsIG9ubHkgaWYgaXRzIGZhbHN5LCB0aGVuIHRoZSBkaXJlY3RpdmVcbiAqIHN0eWxpbmcgYmluZGluZyBmb3Igd2lkdGggd2lsbCBiZSBhcHBsaWVkLlxuICpcbiAqICMjIyBXaGF0IGFib3V0IG1hcC1iYXNlZCBzdHlsaW5nIGJpbmRpbmdzP1xuICogTWFwLWJhc2VkIHN0eWxpbmcgYmluZGluZ3MgYXJlIGFjdGl2YXRlZCB3aGVuIHRoZXJlIGFyZSBvbmUgb3IgbW9yZVxuICogYFtzdHlsZV1gIGFuZC9vciBgW2NsYXNzXWAgYmluZGluZ3MgcHJlc2VudCBvbiBhbiBlbGVtZW50LiBXaGVuIHRoaXNcbiAqIGNvZGUgaXMgYWN0aXZhdGVkLCB0aGUgYXBwbHkgYWxnb3JpdGhtIHdpbGwgaXRlcmF0ZSBvdmVyIGVhY2ggbWFwXG4gKiBlbnRyeSBhbmQgYXBwbHkgZWFjaCBzdHlsaW5nIHZhbHVlIHRvIHRoZSBlbGVtZW50IHdpdGggdGhlIHNhbWVcbiAqIHByaW9yaXRpemF0aW9uIHJ1bGVzIGFzIGFib3ZlLlxuICpcbiAqIEZvciB0aGUgYWxnb3JpdGhtIHRvIGFwcGx5IHN0eWxpbmcgdmFsdWVzIGVmZmljaWVudGx5LCB0aGVcbiAqIHN0eWxpbmcgbWFwIGVudHJpZXMgbXVzdCBiZSBhcHBsaWVkIGluIHN5bmMgKHByb3BlcnR5IGJ5IHByb3BlcnR5KVxuICogd2l0aCBwcm9wLWJhc2VkIGJpbmRpbmdzLiAoVGhlIG1hcC1iYXNlZCBhbGdvcml0aG0gaXMgZGVzY3JpYmVkXG4gKiBtb3JlIGluc2lkZSBvZiB0aGUgYHJlbmRlcjMvc3R5bGluZy9tYXBfYmFzZWRfYmluZGluZ3MudHNgIGZpbGUuKVxuICpcbiAqICMjIFNhbml0aXphdGlvblxuICogU2FuaXRpemF0aW9uIGlzIHVzZWQgdG8gcHJldmVudCBpbnZhbGlkIHN0eWxlIHZhbHVlcyBmcm9tIGJlaW5nIGFwcGxpZWQgdG9cbiAqIHRoZSBlbGVtZW50LlxuICpcbiAqIEl0IGlzIGVuYWJsZWQgaW4gdHdvIGNhc2VzOlxuICpcbiAqICAgMS4gVGhlIGBzdHlsZVNhbml0aXplcihzYW5pdGl6ZXJGbilgIGluc3RydWN0aW9uIHdhcyBjYWxsZWQgKGp1c3QgYmVmb3JlIGFueSBvdGhlclxuICogICAgICBzdHlsaW5nIGluc3RydWN0aW9ucyBhcmUgcnVuKS5cbiAqXG4gKiAgIDIuIFRoZSBjb21wb25lbnQvZGlyZWN0aXZlIGBMVmlld2AgaW5zdGFuY2UgaGFzIGEgc2FuaXRpemVyIG9iamVjdCBhdHRhY2hlZCB0byBpdFxuICogICAgICAodGhpcyBoYXBwZW5zIHdoZW4gYHJlbmRlckNvbXBvbmVudGAgaXMgZXhlY3V0ZWQgd2l0aCBhIGBzYW5pdGl6ZXJgIHZhbHVlIG9yXG4gKiAgICAgIGlmIHRoZSBuZ01vZHVsZSBjb250YWlucyBhIHNhbml0aXplciBwcm92aWRlciBhdHRhY2hlZCB0byBpdCkuXG4gKlxuICogSWYgYW5kIHdoZW4gc2FuaXRpemF0aW9uIGlzIGFjdGl2ZSB0aGVuIGFsbCBwcm9wZXJ0eS92YWx1ZSBlbnRyaWVzIHdpbGwgYmUgZXZhbHVhdGVkXG4gKiB0aHJvdWdoIHRoZSBhY3RpdmUgc2FuaXRpemVyIGJlZm9yZSB0aGV5IGFyZSBhcHBsaWVkIHRvIHRoZSBlbGVtZW50IChvciB0aGUgc3R5bGluZ1xuICogZGVidWcgaGFuZGxlcikuXG4gKlxuICogSWYgYSBgU2FuaXRpemVyYCBvYmplY3QgaXMgdXNlZCAodmlhIHRoZSBgTFZpZXdbU0FOSVRJWkVSXWAgdmFsdWUpIHRoZW4gdGhhdCBvYmplY3RcbiAqIHdpbGwgYmUgdXNlZCBmb3IgZXZlcnkgcHJvcGVydHkuXG4gKlxuICogSWYgYSBgU3R5bGVTYW5pdGl6ZXJGbmAgZnVuY3Rpb24gaXMgdXNlZCAodmlhIHRoZSBgc3R5bGVTYW5pdGl6ZXJgKSB0aGVuIGl0IHdpbGwgYmVcbiAqIGNhbGxlZCBpbiB0d28gd2F5czpcbiAqXG4gKiAgIDEuIHByb3BlcnR5IHZhbGlkYXRpb24gbW9kZTogdGhpcyB3aWxsIGJlIGNhbGxlZCBlYXJseSB0byBtYXJrIHdoZXRoZXIgYSBwcm9wZXJ0eVxuICogICAgICBzaG91bGQgYmUgc2FuaXRpemVkIG9yIG5vdCBhdCBkdXJpbmcgdGhlIGZsdXNoaW5nIHN0YWdlLlxuICpcbiAqICAgMi4gdmFsdWUgc2FuaXRpemF0aW9uIG1vZGU6IHRoaXMgd2lsbCBiZSBjYWxsZWQgZHVyaW5nIHRoZSBmbHVzaGluZyBzdGFnZSBhbmQgd2lsbFxuICogICAgICBydW4gdGhlIHNhbml0aXplciBmdW5jdGlvbiBhZ2FpbnN0IHRoZSB2YWx1ZSBiZWZvcmUgYXBwbHlpbmcgaXQgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogSWYgc2FuaXRpemF0aW9uIHJldHVybnMgYW4gZW1wdHkgdmFsdWUgdGhlbiB0aGF0IGVtcHR5IHZhbHVlIHdpbGwgYmUgYXBwbGllZFxuICogdG8gdGhlIGVsZW1lbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVFN0eWxpbmdDb250ZXh0IGV4dGVuZHNcbiAgICBBcnJheTxudW1iZXJ8c3RyaW5nfG51bWJlcnxib29sZWFufG51bGx8U3R5bGluZ01hcEFycmF5fHt9PiB7XG4gIC8qKiBUaGUgdG90YWwgYW1vdW50IG9mIHNvdXJjZXMgcHJlc2VudCBpbiB0aGUgY29udGV4dCAqL1xuICBbVFN0eWxpbmdDb250ZXh0SW5kZXguVG90YWxTb3VyY2VzUG9zaXRpb25dOiBudW1iZXI7XG5cbiAgLyoqIEluaXRpYWwgdmFsdWUgcG9zaXRpb24gZm9yIHN0YXRpYyBzdHlsZXMgKi9cbiAgW1RTdHlsaW5nQ29udGV4dEluZGV4LkluaXRpYWxTdHlsaW5nVmFsdWVQb3NpdGlvbl06IFN0eWxpbmdNYXBBcnJheTtcbn1cblxuLyoqXG4gKiBBbiBpbmRleCBvZiBwb3NpdGlvbiBhbmQgb2Zmc2V0IHZhbHVlcyB1c2VkIHRvIG5hdmlnYXRlIHRoZSBgVFN0eWxpbmdDb250ZXh0YC5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gVFN0eWxpbmdDb250ZXh0SW5kZXgge1xuICBUb3RhbFNvdXJjZXNQb3NpdGlvbiA9IDAsXG4gIEluaXRpYWxTdHlsaW5nVmFsdWVQb3NpdGlvbiA9IDEsXG4gIFZhbHVlc1N0YXJ0UG9zaXRpb24gPSAyLFxuXG4gIC8vIGVhY2ggdHVwbGUgZW50cnkgaW4gdGhlIGNvbnRleHRcbiAgLy8gKGNvbmZpZywgdGVtcGxhdGVCaXRHdWFyZCwgaG9zdEJpbmRpbmdCaXRHdWFyZCwgcHJvcCwgLi4uYmluZGluZ3N8fGRlZmF1bHQtdmFsdWUpXG4gIENvbmZpZ09mZnNldCA9IDAsXG4gIFRlbXBsYXRlQml0R3VhcmRPZmZzZXQgPSAxLFxuICBIb3N0QmluZGluZ3NCaXRHdWFyZE9mZnNldCA9IDIsXG4gIFByb3BPZmZzZXQgPSAzLFxuICBCaW5kaW5nc1N0YXJ0T2Zmc2V0ID0gNFxufVxuXG4vKipcbiAqIEEgc2VyaWVzIG9mIGZsYWdzIHVzZWQgZm9yIGVhY2ggcHJvcGVydHkgZW50cnkgd2l0aGluIHRoZSBgVFN0eWxpbmdDb250ZXh0YC5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gVFN0eWxpbmdDb250ZXh0UHJvcENvbmZpZ0ZsYWdzIHtcbiAgRGVmYXVsdCA9IDBiMCxcbiAgU2FuaXRpemF0aW9uUmVxdWlyZWQgPSAwYjEsXG4gIFRvdGFsQml0cyA9IDEsXG4gIE1hc2sgPSAwYjEsXG59XG5cbi8qKlxuICogQSBmdW5jdGlvbiB1c2VkIHRvIGFwcGx5IG9yIHJlbW92ZSBzdHlsaW5nIGZyb20gYW4gZWxlbWVudCBmb3IgYSBnaXZlbiBwcm9wZXJ0eS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBseVN0eWxpbmdGbiB7XG4gIChyZW5kZXJlcjogUmVuZGVyZXIzfFByb2NlZHVyYWxSZW5kZXJlcjN8bnVsbCwgZWxlbWVudDogUkVsZW1lbnQsIHByb3A6IHN0cmluZywgdmFsdWU6IGFueSxcbiAgIGJpbmRpbmdJbmRleD86IG51bWJlcnxudWxsKTogdm9pZDtcbn1cblxuLyoqXG4gKiBSdW50aW1lIGRhdGEgdHlwZSB0aGF0IGlzIHVzZWQgdG8gc3RvcmUgYmluZGluZyBkYXRhIHJlZmVyZW5jZWQgZnJvbSB0aGUgYFRTdHlsaW5nQ29udGV4dGAuXG4gKlxuICogQmVjYXVzZSBgTFZpZXdgIGlzIGp1c3QgYW4gYXJyYXkgd2l0aCBkYXRhLCB0aGVyZSBpcyBubyByZWFzb24gdG9cbiAqIHNwZWNpYWwgY2FzZSBgTFZpZXdgIGV2ZXJ5d2hlcmUgaW4gdGhlIHN0eWxpbmcgYWxnb3JpdGhtLiBCeSBhbGxvd2luZ1xuICogdGhpcyBkYXRhIHR5cGUgdG8gYmUgYW4gYXJyYXkgdGhhdCBjb250YWlucyB2YXJpb3VzIHNjYWxhciBkYXRhIHR5cGVzLFxuICogYW4gaW5zdGFuY2Ugb2YgYExWaWV3YCBkb2Vzbid0IG5lZWQgdG8gYmUgY29uc3RydWN0ZWQgZm9yIHRlc3RzLlxuICovXG5leHBvcnQgdHlwZSBMU3R5bGluZ0RhdGEgPSBMVmlldyB8IChzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbClbXTtcblxuLyoqXG4gKiBBcnJheS1iYXNlZCByZXByZXNlbnRhdGlvbiBvZiBhIGtleS92YWx1ZSBhcnJheS5cbiAqXG4gKiBUaGUgZm9ybWF0IG9mIHRoZSBhcnJheSBpcyBcInByb3BlcnR5XCIsIFwidmFsdWVcIiwgXCJwcm9wZXJ0eTJcIixcbiAqIFwidmFsdWUyXCIsIGV0Yy4uLlxuICpcbiAqIFRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXkgaXMgcmVzZXJ2ZWQgdG8gc3RvcmUgdGhlIGluc3RhbmNlXG4gKiBvZiB0aGUga2V5L3ZhbHVlIGFycmF5IHRoYXQgd2FzIHVzZWQgdG8gcG9wdWxhdGUgdGhlIHByb3BlcnR5L1xuICogdmFsdWUgZW50cmllcyB0aGF0IHRha2UgcGxhY2UgaW4gdGhlIHJlbWFpbmRlciBvZiB0aGUgYXJyYXkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3R5bGluZ01hcEFycmF5IGV4dGVuZHMgQXJyYXk8e318c3RyaW5nfG51bWJlcnxudWxsfHVuZGVmaW5lZD4ge1xuICAvKipcbiAgICogVGhlIGxhc3QgcmF3IHZhbHVlIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGVudHJpZXMgaW4gdGhlIG1hcC5cbiAgICovXG4gIFtTdHlsaW5nTWFwQXJyYXlJbmRleC5SYXdWYWx1ZVBvc2l0aW9uXToge318c3RyaW5nfG51bWJlcnxudWxsfHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBBbiBpbmRleCBvZiBwb3NpdGlvbiBhbmQgb2Zmc2V0IHBvaW50cyBmb3IgYW55IGRhdGEgc3RvcmVkIHdpdGhpbiBhIGBTdHlsaW5nTWFwQXJyYXlgIGluc3RhbmNlLlxuICovXG5leHBvcnQgY29uc3QgZW51bSBTdHlsaW5nTWFwQXJyYXlJbmRleCB7XG4gIC8qKiBXaGVyZSB0aGUgdmFsdWVzIHN0YXJ0IGluIHRoZSBhcnJheSAqL1xuICBWYWx1ZXNTdGFydFBvc2l0aW9uID0gMSxcblxuICAvKiogVGhlIGxvY2F0aW9uIG9mIHRoZSByYXcga2V5L3ZhbHVlIG1hcCBpbnN0YW5jZSB1c2VkIGxhc3QgdG8gcG9wdWxhdGUgdGhlIGFycmF5IGVudHJpZXMgKi9cbiAgUmF3VmFsdWVQb3NpdGlvbiA9IDAsXG5cbiAgLyoqIFRoZSBzaXplIG9mIGVhY2ggcHJvcGVydHkvdmFsdWUgZW50cnkgKi9cbiAgVHVwbGVTaXplID0gMixcblxuICAvKiogVGhlIG9mZnNldCBmb3IgdGhlIHByb3BlcnR5IGVudHJ5IGluIHRoZSB0dXBsZSAqL1xuICBQcm9wT2Zmc2V0ID0gMCxcblxuICAvKiogVGhlIG9mZnNldCBmb3IgdGhlIHZhbHVlIGVudHJ5IGluIHRoZSB0dXBsZSAqL1xuICBWYWx1ZU9mZnNldCA9IDEsXG59XG5cbi8qKlxuICogVXNlZCB0byBhcHBseS90cmF2ZXJzZSBhY3Jvc3MgYWxsIG1hcC1iYXNlZCBzdHlsaW5nIGVudHJpZXMgdXAgdG8gdGhlIHByb3ZpZGVkIGB0YXJnZXRQcm9wYFxuICogdmFsdWUuXG4gKlxuICogV2hlbiBjYWxsZWQsIGVhY2ggb2YgdGhlIG1hcC1iYXNlZCBgU3R5bGluZ01hcEFycmF5YCBlbnRyaWVzICh3aGljaCBhcmUgc3RvcmVkIGluXG4gKiB0aGUgcHJvdmlkZWQgYExTdHlsaW5nRGF0YWAgYXJyYXkpIHdpbGwgYmUgaXRlcmF0ZWQgb3Zlci4gRGVwZW5kaW5nIG9uIHRoZSBwcm92aWRlZFxuICogYG1vZGVgIHZhbHVlLCBlYWNoIHByb3AvdmFsdWUgZW50cnkgbWF5IGJlIGFwcGxpZWQgb3Igc2tpcHBlZCBvdmVyLlxuICpcbiAqIElmIGB0YXJnZXRQcm9wYCB2YWx1ZSBpcyBwcm92aWRlZCB0aGUgaXRlcmF0aW9uIGNvZGUgd2lsbCBzdG9wIG9uY2UgaXQgcmVhY2hlc1xuICogdGhlIHByb3BlcnR5IChpZiBmb3VuZCkuIE90aGVyd2lzZSBpZiB0aGUgdGFyZ2V0IHByb3BlcnR5IGlzIG5vdCBlbmNvdW50ZXJlZCB0aGVuXG4gKiBpdCB3aWxsIHN0b3Agb25jZSBpdCByZWFjaGVzIHRoZSBuZXh0IHZhbHVlIHRoYXQgYXBwZWFycyBhbHBoYWJldGljYWxseSBhZnRlciBpdC5cbiAqXG4gKiBJZiBhIGBkZWZhdWx0VmFsdWVgIGlzIHByb3ZpZGVkIHRoZW4gaXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBlbGVtZW50IG9ubHkgaWYgdGhlXG4gKiBgdGFyZ2V0UHJvcGAgcHJvcGVydHkgdmFsdWUgaXMgZW5jb3VudGVyZWQgYW5kIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHRhcmdldFxuICogcHJvcGVydHkgaXMgYG51bGxgLiBUaGUgcmVhc29uIHdoeSB0aGUgYGRlZmF1bHRWYWx1ZWAgaXMgbmVlZGVkIGlzIHRvIGF2b2lkIGhhdmluZyB0aGVcbiAqIGFsZ29yaXRobSBhcHBseSBhIGBudWxsYCB2YWx1ZSBhbmQgdGhlbiBhcHBseSBhIGRlZmF1bHQgdmFsdWUgYWZ0ZXJ3YXJkcyAodGhpcyB3b3VsZFxuICogZW5kIHVwIGJlaW5nIHR3byBzdHlsZSBwcm9wZXJ0eSB3cml0ZXMpLlxuICpcbiAqIEByZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSB0YXJnZXQgcHJvcGVydHkgd2FzIHJlYWNoZWQgYW5kIGl0cyB2YWx1ZSB3YXNcbiAqICBhcHBsaWVkIHRvIHRoZSBlbGVtZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNTdHlsaW5nTWFwc0ZuIHtcbiAgKGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCwgcmVuZGVyZXI6IFJlbmRlcmVyM3xQcm9jZWR1cmFsUmVuZGVyZXIzfG51bGwsIGVsZW1lbnQ6IFJFbGVtZW50LFxuICAgZGF0YTogTFN0eWxpbmdEYXRhLCBzb3VyY2VJbmRleDogbnVtYmVyLCBhcHBseVN0eWxpbmdGbjogQXBwbHlTdHlsaW5nRm4sXG4gICBzYW5pdGl6ZXI6IFN0eWxlU2FuaXRpemVGbnxudWxsLCBtb2RlOiBTdHlsaW5nTWFwc1N5bmNNb2RlLCB0YXJnZXRQcm9wPzogc3RyaW5nfG51bGwsXG4gICBkZWZhdWx0VmFsdWU/OiBib29sZWFufHN0cmluZ3xudWxsKTogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBVc2VkIHRvIGRpcmVjdCBob3cgbWFwLWJhc2VkIHZhbHVlcyBhcmUgYXBwbGllZC90cmF2ZXJzZWQgd2hlbiBzdHlsaW5nIGlzIGZsdXNoZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIFN0eWxpbmdNYXBzU3luY01vZGUge1xuICAvKiogT25seSB0cmF2ZXJzZSB2YWx1ZXMgKG5vIHByb3AvdmFsdWUgc3R5bGluZyBlbnRyaWVzIGdldCBhcHBsaWVkKSAqL1xuICBUcmF2ZXJzZVZhbHVlcyA9IDBiMDAwLFxuXG4gIC8qKiBBcHBseSBldmVyeSBwcm9wL3ZhbHVlIHN0eWxpbmcgZW50cnkgdG8gdGhlIGVsZW1lbnQgKi9cbiAgQXBwbHlBbGxWYWx1ZXMgPSAwYjAwMSxcblxuICAvKiogT25seSBhcHBseSB0aGUgdGFyZ2V0IHByb3AvdmFsdWUgZW50cnkgKi9cbiAgQXBwbHlUYXJnZXRQcm9wID0gMGIwMTAsXG5cbiAgLyoqIFNraXAgYXBwbHlpbmcgdGhlIHRhcmdldCBwcm9wL3ZhbHVlIGVudHJ5ICovXG4gIFNraXBUYXJnZXRQcm9wID0gMGIxMDAsXG5cbiAgLyoqIEl0ZXJhdGUgb3ZlciBpbm5lciBtYXBzIG1hcCB2YWx1ZXMgaW4gdGhlIGNvbnRleHQgKi9cbiAgUmVjdXJzZUlubmVyTWFwcyA9IDBiMTAwMCxcblxuICAvKiogT25seSBjaGVjayB0byBzZWUgaWYgYSB2YWx1ZSB3YXMgc2V0IHNvbWV3aGVyZSBpbiBlYWNoIG1hcCAqL1xuICBDaGVja1ZhbHVlc09ubHkgPSAwYjEwMDAwLFxufVxuXG4vKipcbiAqIFNpbXBsaWZpZWQgYFROb2RlYCBpbnRlcmZhY2UgZm9yIHN0eWxpbmctcmVsYXRlZCBjb2RlLlxuICpcbiAqIFRoZSBzdHlsaW5nIGFsZ29yaXRobSBjb2RlIG9ubHkgbmVlZHMgYWNjZXNzIHRvIGBmbGFnc2AuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVFN0eWxpbmdOb2RlIHsgZmxhZ3M6IFROb2RlRmxhZ3M7IH1cbiJdfQ==
230
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvaW50ZXJmYWNlcy9zdHlsaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQVNBLE9BQU8sRUFBQyxZQUFZLEVBQUUsbUJBQW1CLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrRnBFLG9DQUE2RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBOEI3RCxtQ0FBOEQ7OztJQUE3QixrQ0FBMkI7OztBQUs1RCxNQUFrQixZQUFZO0lBQzVCLG9EQUFvRDtJQUNwRCxVQUFVLElBQUs7SUFDZiwwQkFBMEI7SUFDMUIsU0FBUyxZQUFhO0lBRXRCLGdEQUFnRDtJQUNoRCxVQUFVLEdBQUk7SUFDZCxzQkFBc0I7SUFDdEIsU0FBUyxRQUFZO0lBRXJCLDhEQUE4RDtJQUM5RCxhQUFhLE9BQVM7SUFFdEI7Ozs7O09BS0c7SUFDSCxjQUFjLEdBQU87SUFFckI7Ozs7O09BS0c7SUFDSCxjQUFjLEdBQU87RUFDdEI7Ozs7Ozs7QUFHRCxNQUFNLFVBQVUsZUFBZSxDQUFDLElBQVksRUFBRSxJQUFZO0lBQ3hELFNBQVMsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyw0QkFBNkIsQ0FBQztJQUN0RSxTQUFTLElBQUksbUJBQW1CLENBQUMsSUFBSSxFQUFFLENBQUMsNEJBQTZCLENBQUM7SUFDdEUsT0FBTyxtQkFBQSxDQUFDLElBQUksdUJBQTJCLEdBQUcsSUFBSSxzQkFBMkIsQ0FBQyxFQUFPLENBQUM7QUFDcEYsQ0FBQzs7Ozs7QUFFRCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsYUFBNEI7SUFDL0QsU0FBUyxJQUFJLFlBQVksQ0FBQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUM1RCxPQUFPLENBQUMsQ0FBQyxtQkFBQSxtQkFBQSxhQUFhLEVBQU8sRUFBVSxDQUFDLHVCQUEyQixDQUFDLDRCQUE2QixDQUFDO0FBQ3BHLENBQUM7Ozs7O0FBRUQsTUFBTSxVQUFVLDZCQUE2QixDQUFDLGFBQTRCO0lBQ3hFLFNBQVMsSUFBSSxZQUFZLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDNUQsT0FBTyxDQUFDLENBQUMsbUJBQUEsbUJBQUEsYUFBYSxFQUFPLEVBQVUsQ0FBQyx5QkFBOEIsQ0FBQzs4QkFDeEMsQ0FBQztBQUNsQyxDQUFDOzs7Ozs7QUFFRCxNQUFNLFVBQVUsb0JBQW9CLENBQ2hDLGFBQTRCLEVBQUUsUUFBZ0I7SUFDaEQsU0FBUyxJQUFJLFlBQVksQ0FBQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUM1RCxTQUFTLElBQUksbUJBQW1CLENBQUMsUUFBUSxFQUFFLENBQUMsNEJBQTZCLENBQUM7SUFDMUUsT0FBTyxtQkFBQSxDQUNILENBQUMsQ0FBQyxtQkFBQSxtQkFBQSxhQUFhLEVBQU8sRUFBVSxDQUFDLEdBQUcsMkJBQXVCLENBQUM7UUFDNUQsQ0FBQyxRQUFRLHVCQUEyQixDQUFDLENBQUMsRUFBTyxDQUFDO0FBQ3BELENBQUM7Ozs7O0FBRUQsTUFBTSxVQUFVLDZCQUE2QixDQUFDLGFBQTRCO0lBQ3hFLFNBQVMsSUFBSSxZQUFZLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDNUQsT0FBTyxtQkFBQSxDQUFDLENBQUMsbUJBQUEsbUJBQUEsYUFBYSxFQUFPLEVBQVUsQ0FBQyx5QkFBOEIsQ0FBQyxFQUFPLENBQUM7QUFDakYsQ0FBQzs7Ozs7QUFFRCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsYUFBNEI7SUFDL0QsU0FBUyxJQUFJLFlBQVksQ0FBQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUM1RCxPQUFPLENBQUMsQ0FBQyxtQkFBQSxtQkFBQSxhQUFhLEVBQU8sRUFBVSxDQUFDLHlCQUF5QixDQUFDLHNCQUEyQixDQUFDO0FBQ2hHLENBQUM7Ozs7OztBQUVELE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxhQUE0QixFQUFFLElBQVk7SUFDN0UsU0FBUyxJQUFJLFlBQVksQ0FBQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUM1RCxTQUFTLElBQUksbUJBQW1CLENBQUMsSUFBSSxFQUFFLENBQUMsNEJBQTZCLENBQUM7SUFDdEUsT0FBTyxtQkFBQSxDQUNILENBQUMsQ0FBQyxtQkFBQSxtQkFBQSxhQUFhLEVBQU8sRUFBVSxDQUFDLEdBQUcsdUJBQXVCLENBQUMsR0FBSSxFQUFFO1FBQ2xFLElBQUksc0JBQTJCLENBQUMsRUFBTyxDQUFDO0FBQzlDLENBQUM7Ozs7O0FBRUQsTUFBTSxVQUFVLDZCQUE2QixDQUFDLGFBQTRCO0lBQ3hFLFNBQVMsSUFBSSxZQUFZLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDNUQsT0FBTyxDQUFDLENBQUMsbUJBQUEsbUJBQUEsYUFBYSxFQUFPLEVBQVUsQ0FBQyx5QkFBOEIsQ0FBQzs4QkFDeEMsQ0FBQztBQUNsQyxDQUFDOzs7OztBQUVELE1BQU0sVUFBVSw2QkFBNkIsQ0FBQyxhQUE0QjtJQUN4RSxTQUFTLElBQUksWUFBWSxDQUFDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQzVELE9BQU8sbUJBQUEsQ0FBQyxDQUFDLG1CQUFBLG1CQUFBLGFBQWEsRUFBTyxFQUFVLENBQUMseUJBQThCLENBQUMsRUFBTyxDQUFDO0FBQ2pGLENBQUM7Ozs7O0FBRUQsTUFBTSxVQUFVLG9CQUFvQixDQUFDLGFBQTRCO0lBQy9ELFNBQVMsSUFBSSxZQUFZLENBQUMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLENBQUM7O1VBQ3RELElBQUksR0FBRyxvQkFBb0IsQ0FBQyxhQUFhLENBQUM7SUFDaEQsT0FBTyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ2pFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiogQGxpY2Vuc2VcbiogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4qXG4qIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4qIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiovXG5cbmltcG9ydCB7S2V5VmFsdWVBcnJheX0gZnJvbSAnLi4vLi4vdXRpbC9hcnJheV91dGlscyc7XG5pbXBvcnQge2Fzc2VydE51bWJlciwgYXNzZXJ0TnVtYmVySW5SYW5nZX0gZnJvbSAnLi4vLi4vdXRpbC9hc3NlcnQnO1xuXG4vKipcbiAqIFZhbHVlIHN0b3JlZCBpbiB0aGUgYFREYXRhYCB3aGljaCBpcyBuZWVkZWQgdG8gcmUtY29uY2F0ZW5hdGUgdGhlIHN0eWxpbmcuXG4gKlxuICogU2VlOiBgVFN0eWxpbmdLZXlQcmltaXRpdmVgIGFuZCBgVFN0eWxpbmdTdGF0aWNgXG4gKi9cbmV4cG9ydCB0eXBlIFRTdHlsaW5nS2V5ID0gVFN0eWxpbmdLZXlQcmltaXRpdmUgfCBUU3R5bGluZ1N0YXRpYztcblxuXG4vKipcbiAqIFRoZSBwcmltaXRpdmUgcG9ydGlvbiAoYFRTdHlsaW5nU3RhdGljYCByZW1vdmVkKSBvZiB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBgVERhdGFgIHdoaWNoIGlzXG4gKiBuZWVkZWQgdG8gcmUtY29uY2F0ZW5hdGUgdGhlIHN0eWxpbmcuXG4gKlxuICogLSBgc3RyaW5nYDogU3RvcmVzIHRoZSBwcm9wZXJ0eSBuYW1lLiBVc2VkIHdpdGggYMm1ybVzdHlsZVByb3BgL2DJtcm1Y2xhc3NQcm9wYCBpbnN0cnVjdGlvbi5cbiAqIC0gYG51bGxgOiBSZXByZXNlbnRzIG1hcCwgc28gdGhlcmUgaXMgbm8gbmFtZS4gVXNlZCB3aXRoIGDJtcm1c3R5bGVNYXBgL2DJtcm1Y2xhc3NNYXBgLlxuICogLSBgZmFsc2VgOiBSZXByZXNlbnRzIGFuIGlnbm9yZSBjYXNlLiBUaGlzIGhhcHBlbnMgd2hlbiBgybXJtXN0eWxlUHJvcGAvYMm1ybVjbGFzc1Byb3BgIGluc3RydWN0aW9uXG4gKiAgIGlzIGNvbWJpbmVkIHdpdGggZGlyZWN0aXZlIHdoaWNoIHNoYWRvd3MgaXRzIGlucHV0IGBASW5wdXQoJ2NsYXNzJylgLiBUaGF0IHdheSB0aGUgYmluZGluZ1xuICogICBzaG91bGQgbm90IHBhcnRpY2lwYXRlIGluIHRoZSBzdHlsaW5nIHJlc29sdXRpb24uXG4gKi9cbmV4cG9ydCB0eXBlIFRTdHlsaW5nS2V5UHJpbWl0aXZlID0gc3RyaW5nIHwgbnVsbCB8IGZhbHNlO1xuXG4vKipcbiAqIFN0b3JlIHRoZSBzdGF0aWMgdmFsdWVzIGZvciB0aGUgc3R5bGluZyBiaW5kaW5nLlxuICpcbiAqIFRoZSBgVFN0eWxpbmdTdGF0aWNgIGlzIGp1c3QgYEtleVZhbHVlQXJyYXlgIHdoZXJlIGtleSBgXCJcImAgKHN0b3JlZCBhdCBsb2NhdGlvbiAwKSBjb250YWlucyB0aGVcbiAqIGBUU3R5bGluZ0tleWAgKHN0b3JlZCBhdCBsb2NhdGlvbiAxKS4gSW4gb3RoZXIgd29yZHMgdGhpcyB3cmFwcyB0aGUgYFRTdHlsaW5nS2V5YCBzdWNoIHRoYXQgdGhlXG4gKiBgXCJcImAgY29udGFpbnMgdGhlIHdyYXBwZWQgdmFsdWUuXG4gKlxuICogV2hlbiBpbnN0cnVjdGlvbnMgYXJlIHJlc29sdmluZyBzdHlsaW5nIHRoZXkgbWF5IG5lZWQgdG8gbG9vayBmb3J3YXJkIG9yIGJhY2t3YXJkcyBpbiB0aGUgbGlua2VkXG4gKiBsaXN0IHRvIHJlc29sdmUgdGhlIHZhbHVlLiBGb3IgdGhpcyByZWFzb24gd2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCBoZSBsaW5rZWQgbGlzdCBhbHNvIGNvbnRhaW5zXG4gKiB0aGUgc3RhdGljIHZhbHVlcy4gSG93ZXZlciB0aGUgbGlzdCBvbmx5IGhhcyBzcGFjZSBmb3Igb25lIGl0ZW0gcGVyIHN0eWxpbmcgaW5zdHJ1Y3Rpb24uIEZvciB0aGlzXG4gKiByZWFzb24gd2Ugc3RvcmUgdGhlIHN0YXRpYyB2YWx1ZXMgaGVyZSBhcyBwYXJ0IG9mIHRoZSBgVFN0eWxpbmdLZXlgLiBUaGlzIG1lYW5zIHRoYXQgdGhlXG4gKiByZXNvbHV0aW9uIGZ1bmN0aW9uIHdoZW4gbG9va2luZyBmb3IgYSB2YWx1ZSBuZWVkcyB0byBmaXJzdCBsb29rIGF0IHRoZSBiaW5kaW5nIHZhbHVlLCBhbmQgdGhhblxuICogYXQgYFRTdHlsaW5nS2V5YCAoaWYgaXQgZXhpc3RzKS5cbiAqXG4gKiBJbWFnaW5lIHdlIGhhdmU6XG4gKlxuICogYGBgXG4gKiA8ZGl2IGNsYXNzPVwiVEVNUExBVEVcIiBteS1kaXI+XG4gKlxuICogQERpcmVjdGl2ZSh7XG4gKiAgIGhvc3Q6IHtcbiAqICAgICBjbGFzczogJ0RJUicsXG4gKiAgICAgJ1tjbGFzcy5keW5hbWljXSc6ICdleHAnIC8vIMm1ybVjbGFzc1Byb3AoJ2R5bmFtaWMnLCBjdHguZXhwKTtcbiAqICAgfVxuICogfSlcbiAqIGBgYFxuICpcbiAqIEluIHRoZSBhYm92ZSBjYXNlIHRoZSBsaW5rZWQgbGlzdCB3aWxsIGNvbnRhaW4gb25lIGl0ZW06XG4gKlxuICogYGBgXG4gKiAgIC8vIGFzc3VtZSBiaW5kaW5nIGxvY2F0aW9uOiAxMCBmb3IgYMm1ybVjbGFzc1Byb3AoJ2R5bmFtaWMnLCBjdHguZXhwKTtgXG4gKiAgIHREYXRhWzEwXSA9IDxUU3R5bGluZ1N0YXRpYz5bXG4gKiAgICAgJyc6ICdkeW5hbWljJywgLy8gVGhpcyBpcyB0aGUgd3JhcHBlZCB2YWx1ZSBvZiBgVFN0eWxpbmdLZXlgXG4gKiAgICAgJ0RJUic6IHRydWUsICAgLy8gVGhpcyBpcyB0aGUgZGVmYXVsdCBzdGF0aWMgdmFsdWUgb2YgZGlyZWN0aXZlIGJpbmRpbmcuXG4gKiAgIF07XG4gKiAgIHREYXRhWzEwICsgMV0gPSAwOyAvLyBXZSBkb24ndCBoYXZlIHByZXYvbmV4dC5cbiAqXG4gKiAgIGxWaWV3WzEwXSA9IHVuZGVmaW5lZDsgICAgIC8vIGFzc3VtZSBgY3R4LmV4cGAgaXMgYHVuZGVmaW5lZGBcbiAqICAgbFZpZXdbMTAgKyAxXSA9IHVuZGVmaW5lZDsgLy8gSnVzdCBub3JtYWxpemVkIGBsVmlld1sxMF1gXG4gKiBgYGBcbiAqXG4gKiBTbyB3aGVuIHRoZSBmdW5jdGlvbiBpcyByZXNvbHZpbmcgc3R5bGluZyB2YWx1ZSwgaXQgZmlyc3QgbmVlZHMgdG8gbG9vayBpbnRvIHRoZSBsaW5rZWQgbGlzdFxuICogKHRoZXJlIGlzIG5vbmUpIGFuZCB0aGFuIGludG8gdGhlIHN0YXRpYyBgVFN0eWxpbmdTdGF0aWNgIHRvbyBzZWUgaWYgdGhlcmUgaXMgYSBkZWZhdWx0IHZhbHVlIGZvclxuICogYGR5bmFtaWNgICh0aGVyZSBpcyBub3QpLiBUaGVyZWZvcmUgaXQgaXMgc2FmZSB0byByZW1vdmUgaXQuXG4gKlxuICogSWYgc2V0dGluZyBgdHJ1ZWAgY2FzZTpcbiAqIGBgYFxuICogICBsVmlld1sxMF0gPSB0cnVlOyAgICAgLy8gYXNzdW1lIGBjdHguZXhwYCBpcyBgdHJ1ZWBcbiAqICAgbFZpZXdbMTAgKyAxXSA9IHRydWU7IC8vIEp1c3Qgbm9ybWFsaXplZCBgbFZpZXdbMTBdYFxuICogYGBgXG4gKiBTbyB3aGVuIHRoZSBmdW5jdGlvbiBpcyByZXNvbHZpbmcgc3R5bGluZyB2YWx1ZSwgaXQgZmlyc3QgbmVlZHMgdG8gbG9vayBpbnRvIHRoZSBsaW5rZWQgbGlzdFxuICogKHRoZXJlIGlzIG5vbmUpIGFuZCB0aGFuIGludG8gYFROb2RlLnJlc2lkdWFsQ2xhc3NgIChUTm9kZS5yZXNpZHVhbFN0eWxlKSB3aGljaCBjb250YWluc1xuICogYGBgXG4gKiAgIHROb2RlLnJlc2lkdWFsQ2xhc3MgPSBbXG4gKiAgICAgJ1RFTVBMQVRFJzogdHJ1ZSxcbiAqICAgXTtcbiAqIGBgYFxuICpcbiAqIFRoaXMgbWVhbnMgdGhhdCBpdCBpcyBzYWZlIHRvIGFkZCBjbGFzcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUU3R5bGluZ1N0YXRpYyBleHRlbmRzIEtleVZhbHVlQXJyYXk8YW55PiB7fVxuXG4vKipcbiAqIFRoaXMgaXMgYSBicmFuZGVkIG51bWJlciB3aGljaCBjb250YWlucyBwcmV2aW91cyBhbmQgbmV4dCBpbmRleC5cbiAqXG4gKiBXaGVuIHdlIGNvbWUgYWNyb3NzIHN0eWxpbmcgaW5zdHJ1Y3Rpb25zIHdlIG5lZWQgdG8gc3RvcmUgdGhlIGBUU3R5bGluZ0tleWAgaW4gdGhlIGNvcnJlY3RcbiAqIG9yZGVyIHNvIHRoYXQgd2UgY2FuIHJlLWNvbmNhdGVuYXRlIHRoZSBzdHlsaW5nIHZhbHVlIGluIHRoZSBkZXNpcmVkIHByaW9yaXR5LlxuICpcbiAqIFRoZSBpbnNlcnRpb24gY2FuIGhhcHBlbiBlaXRoZXIgYXQgdGhlOlxuICogLSBlbmQgb2YgdGVtcGxhdGUgYXMgaW4gdGhlIGNhc2Ugb2YgY29taW5nIGFjcm9zcyBhZGRpdGlvbmFsIHN0eWxpbmcgaW5zdHJ1Y3Rpb24gaW4gdGhlIHRlbXBsYXRlXG4gKiAtIGluIGZyb250IG9mIHRoZSB0ZW1wbGF0ZSBpbiB0aGUgY2FzZSBvZiBjb21pbmcgYWNyb3NzIGFkZGl0aW9uYWwgaW5zdHJ1Y3Rpb24gaW4gdGhlXG4gKiAgIGBob3N0QmluZGluZ3NgLlxuICpcbiAqIFdlIHVzZSBgVFN0eWxpbmdSYW5nZWAgdG8gc3RvcmUgdGhlIHByZXZpb3VzIGFuZCBuZXh0IGluZGV4IGludG8gdGhlIGBURGF0YWAgd2hlcmUgdGhlIHRlbXBsYXRlXG4gKiBiaW5kaW5ncyBjYW4gYmUgZm91bmQuXG4gKlxuICogLSBiaXQgMCBpcyB1c2VkIHRvIG1hcmsgdGhhdCB0aGUgcHJldmlvdXMgaW5kZXggaGFzIGEgZHVwbGljYXRlIGZvciBjdXJyZW50IHZhbHVlLlxuICogLSBiaXQgMSBpcyB1c2VkIHRvIG1hcmsgdGhhdCB0aGUgbmV4dCBpbmRleCBoYXMgYSBkdXBsaWNhdGUgZm9yIHRoZSBjdXJyZW50IHZhbHVlLlxuICogLSBiaXRzIDItMTYgYXJlIHVzZWQgdG8gZW5jb2RlIHRoZSBuZXh0L3RhaWwgb2YgdGhlIHRlbXBsYXRlLlxuICogLSBiaXRzIDE3LTMyIGFyZSB1c2VkIHRvIGVuY29kZSB0aGUgcHJldmlvdXMvaGVhZCBvZiB0ZW1wbGF0ZS5cbiAqXG4gKiBOT0RFOiAqZHVwbGljYXRlKiBmYWxzZSBpbXBsaWVzIHRoYXQgaXQgaXMgc3RhdGljYWxseSBrbm93biB0aGF0IHRoaXMgYmluZGluZyB3aWxsIG5vdCBjb2xsaWRlXG4gKiB3aXRoIG90aGVyIGJpbmRpbmdzIGFuZCB0aGVyZWZvcmUgdGhlcmUgaXMgbm8gbmVlZCB0byBjaGVjayBvdGhlciBiaW5kaW5ncy4gRm9yIGV4YW1wbGUgdGhlXG4gKiBiaW5kaW5ncyBpbiBgPGRpdiBbc3R5bGUuY29sb3JdPVwiZXhwXCIgW3N0eWxlLndpZHRoXT1cImV4cFwiPmAgd2lsbCBuZXZlciBjb2xsaWRlIGFuZCB3aWxsIGhhdmVcbiAqIHRoZWlyIGJpdHMgc2V0IGFjY29yZGluZ2x5LiBQcmV2aW91cyBkdXBsaWNhdGUgbWVhbnMgdGhhdCB3ZSBtYXkgbmVlZCB0byBjaGVjayBwcmV2aW91cyBpZiB0aGVcbiAqIGN1cnJlbnQgYmluZGluZyBpcyBgbnVsbGAuIE5leHQgZHVwbGljYXRlIG1lYW5zIHRoYXQgd2UgbWF5IG5lZWQgdG8gY2hlY2sgbmV4dCBiaW5kaW5ncyBpZiB0aGVcbiAqIGN1cnJlbnQgYmluZGluZyBpcyBub3QgYG51bGxgLlxuICpcbiAqIE5PVEU6IGAwYCBoYXMgc3BlY2lhbCBzaWduaWZpY2FuY2UgYW5kIHJlcHJlc2VudHMgYG51bGxgIGFzIGluIG5vIGFkZGl0aW9uYWwgcG9pbnRlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUU3R5bGluZ1JhbmdlIHsgX19icmFuZF9fOiAnVFN0eWxpbmdSYW5nZSc7IH1cblxuLyoqXG4gKiBTaGlmdCBhbmQgbWFza3MgY29uc3RhbnRzIGZvciBlbmNvZGluZyB0d28gbnVtYmVycyBpbnRvIGFuZCBkdXBsaWNhdGUgaW5mbyBpbnRvIGEgc2luZ2xlIG51bWJlci5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gU3R5bGluZ1JhbmdlIHtcbiAgLy8vIE51bWJlciBvZiBiaXRzIHRvIHNoaWZ0IGZvciB0aGUgcHJldmlvdXMgcG9pbnRlclxuICBQUkVWX1NISUZUID0gMTcsXG4gIC8vLyBQcmV2aW91cyBwb2ludGVyIG1hc2suXG4gIFBSRVZfTUFTSyA9IDB4RkZGRTAwMDAsXG5cbiAgLy8vIE51bWJlciBvZiBiaXRzIHRvIHNoaWZ0IGZvciB0aGUgbmV4dCBwb2ludGVyXG4gIE5FWFRfU0hJRlQgPSAyLFxuICAvLy8gTmV4dCBwb2ludGVyIG1hc2suXG4gIE5FWFRfTUFTSyA9IDB4MDAxRkZGQyxcblxuICAvLyBNYXNrIHRvIHJlbW92ZSBuYWdhdGl2ZSBiaXQuIChpbnRlcnByZXQgbnVtYmVyIGFzIHBvc2l0aXZlKVxuICBVTlNJR05FRF9NQVNLID0gMHg3RkZGLFxuXG4gIC8qKlxuICAgKiBUaGlzIGJpdCBpcyBzZXQgaWYgdGhlIHByZXZpb3VzIGJpbmRpbmdzIGNvbnRhaW5zIGEgYmluZGluZyB3aGljaCBjb3VsZCBwb3NzaWJseSBjYXVzZSBhXG4gICAqIGR1cGxpY2F0ZS4gRm9yIGV4YW1wbGU6IGA8ZGl2IFtzdHlsZV09XCJtYXBcIiBbc3R5bGUud2lkdGhdPVwid2lkdGhcIj5gLCB0aGUgYHdpZHRoYCBiaW5kaW5nIHdpbGxcbiAgICogaGF2ZSBwcmV2aW91cyBkdXBsaWNhdGUgc2V0LiBUaGUgaW1wbGljYXRpb24gaXMgdGhhdCBpZiBgd2lkdGhgIGJpbmRpbmcgYmVjb21lcyBgbnVsbGAsIGl0IGlzXG4gICAqIG5lY2Vzc2FyeSB0byBkZWZlciB0aGUgdmFsdWUgdG8gYG1hcC53aWR0aGAuIChCZWNhdXNlIGB3aWR0aGAgb3ZlcndyaXRlcyBgbWFwLndpZHRoYC4pXG4gICAqL1xuICBQUkVWX0RVUExJQ0FURSA9IDB4MDIsXG5cbiAgLyoqXG4gICAqIFRoaXMgYml0IGlzIHNldCB0byBpZiB0aGUgbmV4dCBiaW5kaW5nIGNvbnRhaW5zIGEgYmluZGluZyB3aGljaCBjb3VsZCBwb3NzaWJseSBjYXVzZSBhXG4gICAqIGR1cGxpY2F0ZS4gRm9yIGV4YW1wbGU6IGA8ZGl2IFtzdHlsZV09XCJtYXBcIiBbc3R5bGUud2lkdGhdPVwid2lkdGhcIj5gLCB0aGUgYG1hcGAgYmluZGluZyB3aWxsXG4gICAqIGhhdmUgbmV4dCBkdXBsaWNhdGUgc2V0LiBUaGUgaW1wbGljYXRpb24gaXMgdGhhdCBpZiBgbWFwLndpZHRoYCBiaW5kaW5nIGJlY29tZXMgbm90IGBudWxsYCwgaXRcbiAgICogaXMgbmVjZXNzYXJ5IHRvIGRlZmVyIHRoZSB2YWx1ZSB0byBgd2lkdGhgLiAoQmVjYXVzZSBgd2lkdGhgIG92ZXJ3cml0ZXMgYG1hcC53aWR0aGAuKVxuICAgKi9cbiAgTkVYVF9EVVBMSUNBVEUgPSAweDAxLFxufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1RTdHlsaW5nUmFuZ2UocHJldjogbnVtYmVyLCBuZXh0OiBudW1iZXIpOiBUU3R5bGluZ1JhbmdlIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydE51bWJlckluUmFuZ2UocHJldiwgMCwgU3R5bGluZ1JhbmdlLlVOU0lHTkVEX01BU0spO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TnVtYmVySW5SYW5nZShuZXh0LCAwLCBTdHlsaW5nUmFuZ2UuVU5TSUdORURfTUFTSyk7XG4gIHJldHVybiAocHJldiA8PCBTdHlsaW5nUmFuZ2UuUFJFVl9TSElGVCB8IG5leHQgPDwgU3R5bGluZ1JhbmdlLk5FWFRfU0hJRlQpIGFzIGFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRTdHlsaW5nUmFuZ2VQcmV2KHRTdHlsaW5nUmFuZ2U6IFRTdHlsaW5nUmFuZ2UpOiBudW1iZXIge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TnVtYmVyKHRTdHlsaW5nUmFuZ2UsICdleHBlY3RlZCBudW1iZXInKTtcbiAgcmV0dXJuICgodFN0eWxpbmdSYW5nZSBhcyBhbnkgYXMgbnVtYmVyKSA+PiBTdHlsaW5nUmFuZ2UuUFJFVl9TSElGVCkgJiBTdHlsaW5nUmFuZ2UuVU5TSUdORURfTUFTSztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRTdHlsaW5nUmFuZ2VQcmV2RHVwbGljYXRlKHRTdHlsaW5nUmFuZ2U6IFRTdHlsaW5nUmFuZ2UpOiBib29sZWFuIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydE51bWJlcih0U3R5bGluZ1JhbmdlLCAnZXhwZWN0ZWQgbnVtYmVyJyk7XG4gIHJldHVybiAoKHRTdHlsaW5nUmFuZ2UgYXMgYW55IGFzIG51bWJlcikgJiBTdHlsaW5nUmFuZ2UuUFJFVl9EVVBMSUNBVEUpID09XG4gICAgICBTdHlsaW5nUmFuZ2UuUFJFVl9EVVBMSUNBVEU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRUU3R5bGluZ1JhbmdlUHJldihcbiAgICB0U3R5bGluZ1JhbmdlOiBUU3R5bGluZ1JhbmdlLCBwcmV2aW91czogbnVtYmVyKTogVFN0eWxpbmdSYW5nZSB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnROdW1iZXIodFN0eWxpbmdSYW5nZSwgJ2V4cGVjdGVkIG51bWJlcicpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TnVtYmVySW5SYW5nZShwcmV2aW91cywgMCwgU3R5bGluZ1JhbmdlLlVOU0lHTkVEX01BU0spO1xuICByZXR1cm4gKFxuICAgICAgKCh0U3R5bGluZ1JhbmdlIGFzIGFueSBhcyBudW1iZXIpICYgflN0eWxpbmdSYW5nZS5QUkVWX01BU0spIHxcbiAgICAgIChwcmV2aW91cyA8PCBTdHlsaW5nUmFuZ2UuUFJFVl9TSElGVCkpIGFzIGFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFRTdHlsaW5nUmFuZ2VQcmV2RHVwbGljYXRlKHRTdHlsaW5nUmFuZ2U6IFRTdHlsaW5nUmFuZ2UpOiBUU3R5bGluZ1JhbmdlIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydE51bWJlcih0U3R5bGluZ1JhbmdlLCAnZXhwZWN0ZWQgbnVtYmVyJyk7XG4gIHJldHVybiAoKHRTdHlsaW5nUmFuZ2UgYXMgYW55IGFzIG51bWJlcikgfCBTdHlsaW5nUmFuZ2UuUFJFVl9EVVBMSUNBVEUpIGFzIGFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRTdHlsaW5nUmFuZ2VOZXh0KHRTdHlsaW5nUmFuZ2U6IFRTdHlsaW5nUmFuZ2UpOiBudW1iZXIge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TnVtYmVyKHRTdHlsaW5nUmFuZ2UsICdleHBlY3RlZCBudW1iZXInKTtcbiAgcmV0dXJuICgodFN0eWxpbmdSYW5nZSBhcyBhbnkgYXMgbnVtYmVyKSAmIFN0eWxpbmdSYW5nZS5ORVhUX01BU0spID4+IFN0eWxpbmdSYW5nZS5ORVhUX1NISUZUO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0VFN0eWxpbmdSYW5nZU5leHQodFN0eWxpbmdSYW5nZTogVFN0eWxpbmdSYW5nZSwgbmV4dDogbnVtYmVyKTogVFN0eWxpbmdSYW5nZSB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnROdW1iZXIodFN0eWxpbmdSYW5nZSwgJ2V4cGVjdGVkIG51bWJlcicpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TnVtYmVySW5SYW5nZShuZXh0LCAwLCBTdHlsaW5nUmFuZ2UuVU5TSUdORURfTUFTSyk7XG4gIHJldHVybiAoXG4gICAgICAoKHRTdHlsaW5nUmFuZ2UgYXMgYW55IGFzIG51bWJlcikgJiB+U3R5bGluZ1JhbmdlLk5FWFRfTUFTSykgfCAgLy9cbiAgICAgIG5leHQgPDwgU3R5bGluZ1JhbmdlLk5FWFRfU0hJRlQpIGFzIGFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRTdHlsaW5nUmFuZ2VOZXh0RHVwbGljYXRlKHRTdHlsaW5nUmFuZ2U6IFRTdHlsaW5nUmFuZ2UpOiBib29sZWFuIHtcbiAgbmdEZXZNb2RlICYmIGFzc2VydE51bWJlcih0U3R5bGluZ1JhbmdlLCAnZXhwZWN0ZWQgbnVtYmVyJyk7XG4gIHJldHVybiAoKHRTdHlsaW5nUmFuZ2UgYXMgYW55IGFzIG51bWJlcikgJiBTdHlsaW5nUmFuZ2UuTkVYVF9EVVBMSUNBVEUpID09PVxuICAgICAgU3R5bGluZ1JhbmdlLk5FWFRfRFVQTElDQVRFO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0VFN0eWxpbmdSYW5nZU5leHREdXBsaWNhdGUodFN0eWxpbmdSYW5nZTogVFN0eWxpbmdSYW5nZSk6IFRTdHlsaW5nUmFuZ2Uge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0TnVtYmVyKHRTdHlsaW5nUmFuZ2UsICdleHBlY3RlZCBudW1iZXInKTtcbiAgcmV0dXJuICgodFN0eWxpbmdSYW5nZSBhcyBhbnkgYXMgbnVtYmVyKSB8IFN0eWxpbmdSYW5nZS5ORVhUX0RVUExJQ0FURSkgYXMgYW55O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VFN0eWxpbmdSYW5nZVRhaWwodFN0eWxpbmdSYW5nZTogVFN0eWxpbmdSYW5nZSk6IG51bWJlciB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnROdW1iZXIodFN0eWxpbmdSYW5nZSwgJ2V4cGVjdGVkIG51bWJlcicpO1xuICBjb25zdCBuZXh0ID0gZ2V0VFN0eWxpbmdSYW5nZU5leHQodFN0eWxpbmdSYW5nZSk7XG4gIHJldHVybiBuZXh0ID09PSAwID8gZ2V0VFN0eWxpbmdSYW5nZVByZXYodFN0eWxpbmdSYW5nZSkgOiBuZXh0O1xufSJdfQ==