@sapui5/sap.fe.core 1.99.0 → 1.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/package.json +4 -2
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +1 -69
  4. package/src/sap/fe/core/AnnotationHelper.ts +0 -70
  5. package/src/sap/fe/core/AppComponent.js +388 -399
  6. package/src/sap/fe/core/AppComponent.ts +403 -0
  7. package/src/sap/fe/core/AppStateHandler.js +127 -158
  8. package/src/sap/fe/core/BaseController.js +82 -58
  9. package/src/sap/fe/core/BaseController.ts +68 -0
  10. package/src/sap/fe/core/CommonUtils.js +111 -20
  11. package/src/sap/fe/core/CommonUtils.ts +131 -32
  12. package/src/sap/fe/core/ExtensionAPI.js +278 -274
  13. package/src/sap/fe/core/ExtensionAPI.ts +250 -0
  14. package/src/sap/fe/core/PageController.js +157 -29
  15. package/src/sap/fe/core/PageController.ts +60 -32
  16. package/src/sap/fe/core/RouterProxy.js +694 -756
  17. package/src/sap/fe/core/RouterProxy.ts +11 -9
  18. package/src/sap/fe/core/Synchronization.js +21 -31
  19. package/src/sap/fe/core/TemplateComponent.js +1 -1
  20. package/src/sap/fe/core/TemplateComponent.ts +10 -3
  21. package/src/sap/fe/core/TemplateModel.js +20 -38
  22. package/src/sap/fe/core/TemplateModel.ts +1 -1
  23. package/src/sap/fe/core/TransactionHelper.js +1354 -1370
  24. package/src/sap/fe/core/TransactionHelper.ts +33 -22
  25. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +392 -0
  26. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +355 -0
  27. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +136 -0
  28. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +119 -0
  29. package/src/sap/fe/core/actions/collaboration/Manage.js +262 -0
  30. package/src/sap/fe/core/actions/collaboration/Manage.ts +244 -0
  31. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +103 -0
  32. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  33. package/src/sap/fe/core/actions/draft.js +30 -68
  34. package/src/sap/fe/core/actions/draft.ts +44 -71
  35. package/src/sap/fe/core/actions/messageHandling.js +55 -36
  36. package/src/sap/fe/core/actions/messageHandling.ts +66 -46
  37. package/src/sap/fe/core/actions/operations.js +34 -15
  38. package/src/sap/fe/core/actions/operations.ts +48 -18
  39. package/src/sap/fe/core/actions/sticky.js +17 -4
  40. package/src/sap/fe/core/actions/sticky.ts +21 -4
  41. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +69 -66
  42. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +65 -0
  43. package/src/sap/fe/core/controllerextensions/EditFlow.js +1593 -1669
  44. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1672 -0
  45. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +79 -54
  46. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +61 -0
  47. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +718 -779
  48. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +783 -0
  49. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +796 -816
  50. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +803 -0
  51. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1004 -1005
  52. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +978 -0
  53. package/src/sap/fe/core/controllerextensions/KPIManagement.js +487 -521
  54. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +2 -2
  55. package/src/sap/fe/core/controllerextensions/MassEdit.js +141 -169
  56. package/src/sap/fe/core/controllerextensions/MassEdit.ts +156 -0
  57. package/src/sap/fe/core/controllerextensions/MessageHandler.js +233 -244
  58. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +225 -0
  59. package/src/sap/fe/core/controllerextensions/PageReady.js +301 -336
  60. package/src/sap/fe/core/controllerextensions/PageReady.ts +12 -10
  61. package/src/sap/fe/core/controllerextensions/Paginator.js +188 -175
  62. package/src/sap/fe/core/controllerextensions/Paginator.ts +163 -0
  63. package/src/sap/fe/core/controllerextensions/Placeholder.js +157 -149
  64. package/src/sap/fe/core/controllerextensions/Placeholder.ts +151 -0
  65. package/src/sap/fe/core/controllerextensions/Routing.js +144 -125
  66. package/src/sap/fe/core/controllerextensions/Routing.ts +132 -0
  67. package/src/sap/fe/core/controllerextensions/RoutingListener.js +7 -6
  68. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  69. package/src/sap/fe/core/controllerextensions/Share.js +230 -268
  70. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  71. package/src/sap/fe/core/controllerextensions/SideEffects.js +592 -633
  72. package/src/sap/fe/core/controllerextensions/SideEffects.ts +8 -7
  73. package/src/sap/fe/core/controllerextensions/ViewState.js +788 -806
  74. package/src/sap/fe/core/controllerextensions/ViewState.ts +805 -0
  75. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
  76. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  77. package/src/sap/fe/core/controls/CommandExecution.js +67 -66
  78. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  79. package/src/sap/fe/core/controls/ConditionalWrapper.js +90 -75
  80. package/src/sap/fe/core/controls/ConditionalWrapper.ts +83 -0
  81. package/src/sap/fe/core/controls/CustomQuickViewPage.js +130 -125
  82. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +126 -0
  83. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +103 -112
  84. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +101 -0
  85. package/src/sap/fe/core/controls/FieldWrapper.js +122 -135
  86. package/src/sap/fe/core/controls/FieldWrapper.ts +115 -0
  87. package/src/sap/fe/core/controls/FilterBar.js +162 -159
  88. package/src/sap/fe/core/controls/FilterBar.ts +143 -0
  89. package/src/sap/fe/core/controls/FormElementWrapper.js +45 -39
  90. package/src/sap/fe/core/controls/FormElementWrapper.ts +40 -0
  91. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +37 -42
  92. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  93. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +126 -116
  94. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +98 -0
  95. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +241 -255
  96. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +245 -0
  97. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +150 -141
  98. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  99. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +335 -322
  100. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  101. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +74 -74
  102. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +70 -0
  103. package/src/sap/fe/core/converters/ConverterContext.js +348 -379
  104. package/src/sap/fe/core/converters/ConverterContext.ts +19 -16
  105. package/src/sap/fe/core/converters/ManifestSettings.js +12 -1
  106. package/src/sap/fe/core/converters/ManifestSettings.ts +12 -1
  107. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -378
  108. package/src/sap/fe/core/converters/ManifestWrapper.ts +10 -0
  109. package/src/sap/fe/core/converters/MetaModelConverter.js +6 -4
  110. package/src/sap/fe/core/converters/MetaModelConverter.ts +5 -2
  111. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  112. package/src/sap/fe/core/converters/TemplateConverter.ts +2 -1
  113. package/src/sap/fe/core/converters/annotations/DataField.js +26 -12
  114. package/src/sap/fe/core/converters/annotations/DataField.ts +37 -13
  115. package/src/sap/fe/core/converters/controls/Common/Form.js +2 -2
  116. package/src/sap/fe/core/converters/controls/Common/Form.ts +4 -2
  117. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  118. package/src/sap/fe/core/converters/controls/Common/KPI.ts +3 -2
  119. package/src/sap/fe/core/converters/controls/Common/Table.js +130 -23
  120. package/src/sap/fe/core/converters/controls/Common/Table.ts +134 -29
  121. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +118 -53
  122. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +156 -93
  123. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +161 -207
  124. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +148 -206
  125. package/src/sap/fe/core/converters/helpers/Aggregation.js +115 -133
  126. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  127. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  128. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  129. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  130. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  131. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  132. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +25 -4
  133. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +20 -3
  134. package/src/sap/fe/core/converters/templates/ListReportConverter.js +10 -4
  135. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +15 -4
  136. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +7 -5
  137. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +5 -1
  138. package/src/sap/fe/core/designtime/AppComponent.designtime.js +92 -98
  139. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  140. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  141. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  142. package/src/sap/fe/core/formatters/TableFormatter.js +53 -2
  143. package/src/sap/fe/core/formatters/TableFormatter.ts +51 -0
  144. package/src/sap/fe/core/fpm/Component.js +50 -54
  145. package/src/sap/fe/core/fpm/Component.ts +48 -0
  146. package/src/sap/fe/core/helpers/AppStartupHelper.js +323 -309
  147. package/src/sap/fe/core/helpers/AppStartupHelper.ts +363 -337
  148. package/src/sap/fe/core/helpers/BindingExpression.js +7 -7
  149. package/src/sap/fe/core/helpers/BindingExpression.ts +7 -7
  150. package/src/sap/fe/core/helpers/ClassSupport.js +186 -62
  151. package/src/sap/fe/core/helpers/ClassSupport.ts +168 -52
  152. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +5 -4
  153. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -5
  154. package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
  155. package/src/sap/fe/core/helpers/FPMHelper.ts +1 -1
  156. package/src/sap/fe/core/helpers/MassEditHelper.js +601 -684
  157. package/src/sap/fe/core/helpers/MassEditHelper.ts +699 -0
  158. package/src/sap/fe/core/helpers/ModelHelper.js +25 -1
  159. package/src/sap/fe/core/helpers/ModelHelper.ts +23 -0
  160. package/src/sap/fe/core/helpers/SemanticDateOperators.js +5 -1
  161. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +4 -0
  162. package/src/sap/fe/core/library.js +426 -451
  163. package/src/sap/fe/core/library.support.js +22 -33
  164. package/src/sap/fe/core/library.support.ts +23 -0
  165. package/src/sap/fe/core/library.ts +420 -0
  166. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
  167. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +4 -1
  168. package/src/sap/fe/core/messagebundle.properties +22 -5
  169. package/src/sap/fe/core/messagebundle_ar.properties +27 -7
  170. package/src/sap/fe/core/messagebundle_bg.properties +27 -7
  171. package/src/sap/fe/core/messagebundle_ca.properties +27 -7
  172. package/src/sap/fe/core/messagebundle_cs.properties +27 -7
  173. package/src/sap/fe/core/messagebundle_cy.properties +27 -7
  174. package/src/sap/fe/core/messagebundle_da.properties +27 -7
  175. package/src/sap/fe/core/messagebundle_de.properties +27 -7
  176. package/src/sap/fe/core/messagebundle_el.properties +27 -7
  177. package/src/sap/fe/core/messagebundle_en.properties +27 -7
  178. package/src/sap/fe/core/messagebundle_en_GB.properties +27 -7
  179. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +27 -7
  180. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +27 -7
  181. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +27 -7
  182. package/src/sap/fe/core/messagebundle_es.properties +27 -7
  183. package/src/sap/fe/core/messagebundle_es_MX.properties +27 -7
  184. package/src/sap/fe/core/messagebundle_et.properties +27 -7
  185. package/src/sap/fe/core/messagebundle_fi.properties +28 -8
  186. package/src/sap/fe/core/messagebundle_fr.properties +28 -8
  187. package/src/sap/fe/core/messagebundle_fr_CA.properties +29 -9
  188. package/src/sap/fe/core/messagebundle_hi.properties +27 -7
  189. package/src/sap/fe/core/messagebundle_hr.properties +27 -7
  190. package/src/sap/fe/core/messagebundle_hu.properties +27 -7
  191. package/src/sap/fe/core/messagebundle_id.properties +27 -7
  192. package/src/sap/fe/core/messagebundle_it.properties +27 -7
  193. package/src/sap/fe/core/messagebundle_iw.properties +27 -7
  194. package/src/sap/fe/core/messagebundle_ja.properties +26 -6
  195. package/src/sap/fe/core/messagebundle_kk.properties +27 -7
  196. package/src/sap/fe/core/messagebundle_ko.properties +27 -7
  197. package/src/sap/fe/core/messagebundle_lt.properties +27 -7
  198. package/src/sap/fe/core/messagebundle_lv.properties +28 -8
  199. package/src/sap/fe/core/messagebundle_ms.properties +27 -7
  200. package/src/sap/fe/core/messagebundle_nl.properties +27 -7
  201. package/src/sap/fe/core/messagebundle_no.properties +27 -7
  202. package/src/sap/fe/core/messagebundle_pl.properties +27 -7
  203. package/src/sap/fe/core/messagebundle_pt.properties +28 -8
  204. package/src/sap/fe/core/messagebundle_pt_PT.properties +27 -7
  205. package/src/sap/fe/core/messagebundle_ro.properties +27 -7
  206. package/src/sap/fe/core/messagebundle_ru.properties +27 -7
  207. package/src/sap/fe/core/messagebundle_sh.properties +27 -7
  208. package/src/sap/fe/core/messagebundle_sk.properties +27 -7
  209. package/src/sap/fe/core/messagebundle_sl.properties +27 -7
  210. package/src/sap/fe/core/messagebundle_sv.properties +27 -7
  211. package/src/sap/fe/core/messagebundle_th.properties +26 -6
  212. package/src/sap/fe/core/messagebundle_tr.properties +30 -10
  213. package/src/sap/fe/core/messagebundle_uk.properties +27 -7
  214. package/src/sap/fe/core/messagebundle_vi.properties +27 -7
  215. package/src/sap/fe/core/messagebundle_zh_CN.properties +27 -7
  216. package/src/sap/fe/core/messagebundle_zh_TW.properties +27 -7
  217. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +45 -71
  218. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +154 -192
  219. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +4 -4
  220. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +66 -92
  221. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +1 -1
  222. package/src/sap/fe/core/services/NavigationServiceFactory.js +284 -339
  223. package/src/sap/fe/core/services/NavigationServiceFactory.ts +10 -13
  224. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +67 -102
  225. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +5 -2
  226. package/src/sap/fe/core/services/RoutingServiceFactory.js +754 -814
  227. package/src/sap/fe/core/services/RoutingServiceFactory.ts +13 -13
  228. package/src/sap/fe/core/services/ShellServicesFactory.js +649 -736
  229. package/src/sap/fe/core/services/ShellServicesFactory.ts +7 -4
  230. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +567 -592
  231. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +22 -3
  232. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +354 -386
  233. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +21 -14
  234. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +1 -1
  235. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +1 -1
  236. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  237. package/src/sap/fe/core/support/CommonHelper.ts +1 -1
  238. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  239. package/src/sap/fe/core/templating/DataModelPathHelper.js +93 -85
  240. package/src/sap/fe/core/templating/DataModelPathHelper.ts +104 -95
  241. package/src/sap/fe/core/templating/FilterHelper.js +25 -32
  242. package/src/sap/fe/core/templating/FilterHelper.ts +36 -35
  243. package/src/sap/fe/core/templating/PropertyHelper.js +2 -2
  244. package/src/sap/fe/core/templating/PropertyHelper.ts +1 -1
  245. package/src/sap/fe/core/templating/UIFormatters.js +32 -26
  246. package/src/sap/fe/core/templating/UIFormatters.ts +37 -24
@@ -1,819 +1,799 @@
1
1
  /*!
2
2
  * SAP UI development toolkit for HTML5 (SAPUI5)
3
- (c) Copyright 2009-2021 SAP SE. All rights reserved
4
-
3
+ * (c) Copyright 2009-2021 SAP SE. All rights reserved
5
4
  */
6
- sap.ui.define(
7
- [
8
- "sap/ui/core/mvc/ControllerExtension",
9
- "sap/ui/core/mvc/OverrideExecution",
10
- "sap/fe/navigation/SelectionVariant",
11
- "sap/fe/core/helpers/ModelHelper",
12
- "sap/ui/core/util/XMLPreprocessor",
13
- "sap/ui/core/XMLTemplateProcessor",
14
- "sap/ui/core/Fragment",
15
- "sap/ui/model/json/JSONModel",
16
- "sap/base/Log",
17
- "sap/fe/core/CommonUtils",
18
- "sap/fe/core/helpers/KeepAliveHelper",
19
- "sap/base/util/merge"
20
- ],
21
- function(
22
- ControllerExtension,
23
- OverrideExecution,
24
- SelectionVariant,
25
- ModelHelper,
26
- XMLPreprocessor,
27
- XMLTemplateProcessor,
28
- Fragment,
29
- JSONModel,
30
- Log,
31
- CommonUtils,
32
- KeepAliveHelper,
33
- mergeObjects
34
- ) {
35
- "use strict";
36
-
37
- /**
38
- * {@link sap.ui.core.mvc.ControllerExtension Controller extension}
39
- *
40
- * @namespace
41
- * @alias sap.fe.core.controllerextensions.InternalInternalBasedNavigation
42
- *
43
- * @private
44
- * @since 1.84.0
45
- */
46
- return ControllerExtension.extend("sap.fe.core.controllerextensions.InternalInternalBasedNavigation", {
47
- metadata: {
48
- methods: {
49
- navigate: {
50
- "final": true,
51
- "public": true
52
- },
53
- getEntitySet: {
54
- "final": false,
55
- "public": false
56
- },
57
- navigateOutbound: {
58
- "final": true,
59
- "public": true
60
- },
61
- navigateWithConfirmationDialog: {
62
- "final": true,
63
- "public": true
64
- },
65
- getNavigationMode: {
66
- "final": false,
67
- "public": true,
68
- overrideExecution: OverrideExecution.Instead
69
- },
70
- prepareContextForExternalNavigation: {
71
- "final": true,
72
- "public": true
73
- },
74
- removeSensitiveData: {
75
- "final": true,
76
- "public": true
77
- },
78
- prepareFiltersForExternalNavigation: {
79
- "final": true,
80
- "public": true
81
- },
82
- getOutboundParams: {
83
- "final": true,
84
- "public": true
85
- }
86
- }
87
- },
88
- /**
89
- * Enables intent-based navigation (SemanticObject-Action) with the provided context.
90
- * If semantic object mapping is provided, this is also applied to the selection variant after the adaptation by a consumer.
91
- * This takes care of removing any technical parameters and determines if an explace or inplace navigation should take place.
92
- *
93
- * @param {string} sSemanticObject Semantic object for the target app
94
- * @param {string} sAction Action for the target app
95
- * @param {object} [mNavigationParameters] Optional parameters to be passed to the external navigation
96
- * @param {Array|object} [mNavigationParameters.navigationContexts] Uses one of the following to be passed to the intent:
97
- * a single instance of {@link sap.ui.model.odata.v4.Context}
98
- * multiple instances of {@link sap.ui.model.odata.v4.Context}
99
- * an object or an array of objects
100
- * If an array of objects is passed, the context is used to determine the metaPath and to remove any sensitive data
101
- * If an array of objects is passed, the following format ix expected:
102
- * {
103
- * data: {
104
- * ProductID: 7634,
105
- * Name: "Laptop"
106
- * },
107
- * metaPath: "/SalesOrderManage"
108
- * }
109
- * @param {string | object} [mNavigationParameters.semanticObjectMapping] String representation of the SemanticObjectMapping or SemanticObjectMapping that applies to this navigation
110
- * @param {object} [mNavigationParameters.defaultRefreshStrategy] Default refresh strategy to be used in case no refresh strategy is specified for the intent in the view.
111
- * @param {object} [mNavigationParameters.additionalNavigationParameters] Additional navigation parameters configured in the crossAppNavigation outbound parameters.
112
- **/
113
- navigate: function(sSemanticObject, sAction, mNavigationParameters) {
114
- var that = this;
115
- var _doNavigate = function(oContext) {
116
- var vNavigationContexts = mNavigationParameters && mNavigationParameters.navigationContexts,
117
- aNavigationContexts =
118
- vNavigationContexts && !Array.isArray(vNavigationContexts) ? [vNavigationContexts] : vNavigationContexts,
119
- vSemanticObjectMapping = mNavigationParameters && mNavigationParameters.semanticObjectMapping,
120
- vOutboundParams = mNavigationParameters && mNavigationParameters.additionalNavigationParameters,
121
- oTargetInfo = {
122
- semanticObject: sSemanticObject,
123
- action: sAction
124
- },
125
- oView = that.base.getView(),
126
- oController = oView.getController();
127
-
128
- if (oContext) {
129
- that._oView.setBindingContext(oContext);
130
- }
131
-
132
- if (sSemanticObject && sAction) {
133
- var aSemanticAttributes = [],
134
- oSelectionVariant = new SelectionVariant();
135
- // 1. get SemanticAttributes for navigation
136
- if (aNavigationContexts && aNavigationContexts.length) {
137
- aNavigationContexts.map(function(oNavigationContext) {
138
- // 1.1.a if navigation context is instance of sap.ui.mode.odata.v4.Context
139
- // else check if navigation context is of type object
140
- if (oNavigationContext.isA && oNavigationContext.isA("sap.ui.model.odata.v4.Context")) {
141
- // 1.1.b remove sensitive data
142
- var oSemanticAttributes = oNavigationContext.getObject(),
143
- sMetaPath = that._oMetaModel.getMetaPath(oNavigationContext.getPath());
144
- // TODO: also remove sensitive data from navigation properties
145
- oSemanticAttributes = that.removeSensitiveData(oSemanticAttributes, sMetaPath);
146
- var oNavContext = that.prepareContextForExternalNavigation(oSemanticAttributes, oNavigationContext);
147
- oTargetInfo["propertiesWithoutConflict"] = oNavContext.propertiesWithoutConflict;
148
- aSemanticAttributes.push(oNavContext.semanticAttributes);
149
- } else if (
150
- !(oNavigationContext && Array.isArray(oNavigationContext.data)) &&
151
- typeof oNavigationContext === "object"
152
- ) {
153
- // 1.1.b remove sensitive data from object
154
- aSemanticAttributes.push(
155
- that.removeSensitiveData(oNavigationContext.data, oNavigationContext.metaPath)
156
- );
157
- } else if (oNavigationContext && Array.isArray(oNavigationContext.data)) {
158
- // oNavigationContext.data can be array already ex : [{Customer: "10001"}, {Customer: "10091"}]
159
- // hence assigning it to the aSemanticAttributes
160
- aSemanticAttributes = that.removeSensitiveData(oNavigationContext.data, oNavigationContext.metaPath);
161
- }
162
- });
163
- }
164
- // 2.1 Merge base selection variant and sanitized semantic attributes into one SelectionVariant
165
- if (aSemanticAttributes && aSemanticAttributes.length) {
166
- oSelectionVariant = that._oNavigationService.mixAttributesAndSelectionVariant(
167
- aSemanticAttributes,
168
- oSelectionVariant.toJSONString()
169
- );
170
- }
171
-
172
- // 3. Add filterContextUrl to SV so the NavigationHandler can remove any sensitive data based on view entitySet
173
- var oModel = that._oView.getModel(),
174
- sEntitySet = that.getEntitySet(),
175
- sContextUrl = sEntitySet ? that._oNavigationService.constructContextUrl(sEntitySet, oModel) : undefined;
176
- if (sContextUrl) {
177
- oSelectionVariant.setFilterContextUrl(sContextUrl);
178
- }
179
-
180
- // Apply Outbound Parameters to the SV
181
- if (vOutboundParams) {
182
- that._applyOutboundParams(oSelectionVariant, vOutboundParams);
183
- }
184
-
185
- // 4. give an opportunity for the application to influence the SelectionVariant
186
- oController.intentBasedNavigation.adaptNavigationContext(oSelectionVariant, oTargetInfo);
187
-
188
- // 5. Apply semantic object mappings to the SV
189
- if (vSemanticObjectMapping) {
190
- that._applySemanticObjectMappings(oSelectionVariant, vSemanticObjectMapping);
191
- }
192
-
193
- // 6. remove technical parameters from Selection Variant
194
- that._removeTechnicalParameters(oSelectionVariant);
195
-
196
- // 7. check if programming model is sticky and page is editable
197
- var sNavMode = oController._intentBasedNavigation.getNavigationMode();
198
-
199
- // 8. Updating refresh strategy in internal model
200
- var mRefreshStrategies = (mNavigationParameters && mNavigationParameters.refreshStrategies) || {},
201
- oInternalModel = oView.getModel("internal");
202
- if (oInternalModel) {
203
- if (oView && oView.getViewData().refreshStrategyOnAppRestore) {
204
- var mViewRefreshStrategies = oView.getViewData().refreshStrategyOnAppRestore || {};
205
- mergeObjects(mRefreshStrategies, mViewRefreshStrategies);
206
- }
207
- var mRefreshStrategy = KeepAliveHelper.getRefreshStrategyForIntent(
208
- mRefreshStrategies,
209
- sSemanticObject,
210
- sAction
211
- );
212
- if (mRefreshStrategy) {
213
- oInternalModel.setProperty("/refreshStrategyOnAppRestore", mRefreshStrategy);
214
- }
215
- }
216
-
217
- // 9. Navigate via NavigationHandler
218
- var onError = function() {
219
- sap.ui.require(["sap/m/MessageBox"], function(MessageBox) {
220
- var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
221
- MessageBox.show(oResourceBundle.getText("C_COMMON_HELPER_NAVIGATION_ERROR_MESSAGE"), {
222
- title: oResourceBundle.getText("C_COMMON_NAVIGATION_ERROR_TITLE")
223
- });
224
- });
225
- };
226
- that._oNavigationService.navigate(
227
- sSemanticObject,
228
- sAction,
229
- oSelectionVariant.toJSONString(),
230
- null,
231
- onError,
232
- null,
233
- sNavMode
234
- );
235
- } else {
236
- throw new Error("Semantic Object/action is not provided");
237
- }
238
- };
239
- var oBindingContext = this.base.getView().getBindingContext();
240
- var oMetaModel = oBindingContext && oBindingContext.getModel().getMetaModel();
241
- if (
242
- this.getView().getViewData().converterType === "ObjectPage" &&
243
- oMetaModel &&
244
- !ModelHelper.isStickySessionSupported(oMetaModel)
245
- ) {
246
- CommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(
247
- _doNavigate.bind(this),
248
- Function.prototype,
249
- this.base.getView().getBindingContext(),
250
- this.base.getView().getController()
251
- );
252
- } else {
253
- _doNavigate();
254
- }
255
- },
256
-
257
- /**
258
- * Prepare attributes to be passed to external navigation.
259
- * @param {object} oSemanticAttributes Context data after removing all sensitive information.
260
- * @param {object} oContext Actual context from which the semanticAttributes were derived.
261
- * @returns {object} Object of prepared attributes for external navigation and no conflict properties.
262
- */
263
- prepareContextForExternalNavigation: function(oSemanticAttributes, oContext) {
264
- // 1. Find all distinct keys in the object SemanticAttributes
265
- // Store meta path for each occurence of the key
266
- var oDistinctKeys = {},
267
- sContextPath = oContext.getPath(),
268
- oMetaModel = oContext.getModel().getMetaModel(),
269
- sMetaPath = oMetaModel.getMetaPath(sContextPath),
270
- aMetaPathParts = sMetaPath.split("/").filter(Boolean);
271
-
272
- function _findDistinctKeysInObject(LookUpObject, sLookUpObjectMetaPath) {
273
- for (var sKey in LookUpObject) {
274
- // null case??
275
- if (LookUpObject[sKey] === null || typeof LookUpObject[sKey] !== "object") {
276
- if (!oDistinctKeys[sKey]) {
277
- // if key is found for the first time then create array
278
- oDistinctKeys[sKey] = [];
279
- }
280
- // push path to array
281
- oDistinctKeys[sKey].push(sLookUpObjectMetaPath);
282
- } else {
283
- // if a nested object is found
284
- var oNewLookUpObject = LookUpObject[sKey];
285
- _findDistinctKeysInObject(oNewLookUpObject, sLookUpObjectMetaPath + "/" + sKey);
286
- }
287
- }
288
- }
289
-
290
- _findDistinctKeysInObject(oSemanticAttributes, sMetaPath);
291
-
292
- // 2. Determine distinct key value and add conflicted paths to semantic attributes
293
- var sMainEntitySetName = aMetaPathParts[0],
294
- sMainEntityTypeName = oMetaModel.getObject("/" + sMainEntitySetName + "/@sapui.name"),
295
- oPropertiesWithoutConflict = {};
296
- var sMainEntityValuePath, sCurrentValuePath, sLastValuePath;
297
- for (var sDistinctKey in oDistinctKeys) {
298
- var aConflictingPaths = oDistinctKeys[sDistinctKey],
299
- sWinnerValuePath;
300
- // Find winner value for each distinct key in case of conflict by the following rule:
301
-
302
- // -> A. if any meta path for a distinct key is the same as main entity take that as the value
303
- // -> B. if A is not met keep the value from the current context (sMetaPath === path of distince key)
304
- // -> C. if A, B or C are not met take the last path for value
305
- if (aConflictingPaths.length > 1) {
306
- // conflict
307
- for (var i = 0; i <= aConflictingPaths.length - 1; i++) {
308
- var sPath = aConflictingPaths[i],
309
- sPathInContext = sPath.replace(sPath === sMetaPath ? sMetaPath : sMetaPath + "/", "");
310
- sPathInContext = (sPathInContext === "" ? sPathInContext : sPathInContext + "/") + sDistinctKey;
311
- var sEntityTypeName = oMetaModel.getObject(sPath + "/@sapui.name");
312
- // rule A
313
-
314
- // rule A
315
- if (sEntityTypeName === sMainEntityTypeName) {
316
- sMainEntityValuePath = sPathInContext;
317
- }
318
-
319
- // rule B
320
- if (sPath === sMetaPath) {
321
- sCurrentValuePath = sPathInContext;
322
- }
323
-
324
- // rule C
325
- sLastValuePath = sPathInContext;
326
-
327
- // add conflicted path to semantic attributes
328
- // check if the current path points to main entity and prefix attribute names accordingly
329
- oSemanticAttributes[
330
- (sMetaPath + "/" + sPathInContext)
331
- .split("/")
332
- .filter(function(sValue) {
333
- return sValue != "";
334
- })
335
- .join(".")
336
- ] = oContext.getProperty(sPathInContext);
337
- }
338
- // A || B || C
339
- sWinnerValuePath = sMainEntityValuePath || sCurrentValuePath || sLastValuePath;
340
- oSemanticAttributes[sDistinctKey] = oContext.getProperty(sWinnerValuePath);
341
- sMainEntityValuePath = undefined;
342
- sCurrentValuePath = undefined;
343
- sLastValuePath = undefined;
344
- } else {
345
- // no conflict, add distinct key without adding paths
346
- var sPath = aConflictingPaths[0], // because there is only one and hence no conflict
347
- sPathInContext = sPath.replace(sPath === sMetaPath ? sMetaPath : sMetaPath + "/", "");
348
- sPathInContext = (sPathInContext === "" ? sPathInContext : sPathInContext + "/") + sDistinctKey;
349
- oSemanticAttributes[sDistinctKey] = oContext.getProperty(sPathInContext);
350
- oPropertiesWithoutConflict[sDistinctKey] = (sMetaPath + "/" + sPathInContext)
351
- .split("/")
352
- .filter(function(sValue) {
353
- return sValue != "";
354
- })
355
- .join(".");
356
- }
357
- }
358
- // 3. Remove all Navigation properties
359
- for (var sProperty in oSemanticAttributes) {
360
- if (oSemanticAttributes[sProperty] !== null && typeof oSemanticAttributes[sProperty] === "object") {
361
- delete oSemanticAttributes[sProperty];
362
- }
363
- }
364
- return {
365
- semanticAttributes: oSemanticAttributes,
366
- propertiesWithoutConflict: oPropertiesWithoutConflict
367
- };
368
- },
369
- /**
370
- * Prepare filter conditions to be passed to external navigation.
371
- * @param {object} oFilterBarConditions Filter conditions.
372
- * @param {string} sRootPath Root path of the application.
373
- * @param {Array} aParameters Names of parameters to be considered.
374
- * @returns {object} Object of prepared filter conditions for external navigation and no conflict filters.
375
- */
376
- prepareFiltersForExternalNavigation: function(oFilterBarConditions, sRootPath, aParameters) {
377
- var oDistinctKeys = {};
378
- var oFilterConditionsWithoutConflict = {};
379
- var sMainEntityValuePath, sCurrentValuePath, sFullContextPath, sWinnerValuePath, sPathInContext;
380
- function _findDistinctKeysInObject(LookUpObject) {
381
- var sLookUpObjectMetaPath;
382
- for (var sKey in LookUpObject) {
383
- if (LookUpObject[sKey]) {
384
- if (sKey.includes("/")) {
385
- sLookUpObjectMetaPath = sKey; // "/SalesOrdermanage/_Item/Material"
386
- var aPathParts = sKey.split("/");
387
- sKey = aPathParts[aPathParts.length - 1];
388
- } else {
389
- sLookUpObjectMetaPath = sRootPath;
390
- }
391
- if (!oDistinctKeys[sKey]) {
392
- // if key is found for the first time then create array
393
- oDistinctKeys[sKey] = [];
394
- }
395
-
396
- // push path to array
397
- oDistinctKeys[sKey].push(sLookUpObjectMetaPath);
398
- }
399
- }
400
- }
401
-
402
- _findDistinctKeysInObject(oFilterBarConditions);
403
- for (var sDistinctKey in oDistinctKeys) {
404
- var aConflictingPaths = oDistinctKeys[sDistinctKey];
405
-
406
- if (aConflictingPaths.length > 1) {
407
- // conflict
408
- for (var i = 0; i <= aConflictingPaths.length - 1; i++) {
409
- var sPath = aConflictingPaths[i];
410
- if (sPath === sRootPath) {
411
- sFullContextPath = sRootPath + "/" + sDistinctKey;
412
- sPathInContext = sDistinctKey;
413
- sMainEntityValuePath = sDistinctKey;
414
- if (aParameters && aParameters.includes(sDistinctKey)) {
415
- oFilterBarConditions["$Parameter." + sDistinctKey] = oFilterBarConditions[sDistinctKey];
416
- }
417
- } else {
418
- sPathInContext = sPath;
419
- sFullContextPath = (sRootPath + "/" + sPath).replaceAll("*", "");
420
- sCurrentValuePath = sPath;
421
- }
422
- oFilterBarConditions[
423
- sFullContextPath
424
- .split("/")
425
- .filter(function(sValue) {
426
- return sValue != "";
427
- })
428
- .join(".")
429
- ] = oFilterBarConditions[sPathInContext];
430
- delete oFilterBarConditions[sPath];
431
- }
432
-
433
- sWinnerValuePath = sMainEntityValuePath || sCurrentValuePath;
434
- oFilterBarConditions[sDistinctKey] = oFilterBarConditions[sWinnerValuePath];
435
- } else {
436
- // no conflict, add distinct key without adding paths
437
- var sPath = aConflictingPaths[0], // because there is only one and hence no conflict
438
- sFullContextPath =
439
- sPath === sRootPath ? sRootPath + "/" + sDistinctKey : (sRootPath + "/" + sPath).replaceAll("*", "");
440
- oFilterConditionsWithoutConflict[sDistinctKey] = sFullContextPath
441
- .split("/")
442
- .filter(function(sValue) {
443
- return sValue != "";
444
- })
445
- .join(".");
446
- if (aParameters && aParameters.includes(sDistinctKey)) {
447
- oFilterBarConditions["$Parameter." + sDistinctKey] = oFilterBarConditions[sDistinctKey];
448
- }
449
- }
450
- }
451
-
452
- return {
453
- filterConditions: oFilterBarConditions,
454
- filterConditionsWithoutConflict: oFilterConditionsWithoutConflict
455
- };
456
- },
457
-
458
- /**
459
- * Get Navigation mode.
460
- *
461
- * @returns {string}
462
- */
463
- getNavigationMode: function() {
464
- return undefined;
465
- },
466
- /**
467
- * Allows for navigation to a given intent (SemanticObject-Action) with the provided context, using a dialog that shows the contexts which cannot be passed
468
- * If semantic object mapping is provided, this setting is also applied to the selection variant after adaptation by a consumer.
469
- * This setting also removes any technical parameters and determines if an inplace or explace navigation should take place.
470
- *
471
- * @param {string} sSemanticObject Semantic object for the target app
472
- * @param {string} sAction Action for the target app
473
- * @param {object} [mNavigationParameters] Optional parameters to be passed to the external navigation
474
- * @param {Array|object} [mNavigationParameters.navigationContexts] Single instance or multiple instances of {@link sap.ui.model.odata.v4.Context}, or alternatively an object or array of objects, to be passed to the intent.
475
- * @param {Array|object} [mNavigationParameters.applicableContexts] Single instance or multiple instances of {@link sap.ui.model.odata.v4.Context}, or alternatively an object or array of objects, to be passed to the intent and for which the IBN button is enabled
476
- * @param {Array|object} [mNavigationParameters.notApplicableContexts] Single instance or multiple instances of {@link sap.ui.model.odata.v4.Context}, or alternatively an object or array of objects, which cannot be passed to the intent.
477
- * if an array of contexts is passed the context is used to determine the meta path and accordingly remove the sensitive data
478
- * If an array of objects is passed, the following format is expected:
479
- * {
480
- * data: {
481
- * ProductID: 7634,
482
- * Name: "Laptop"
483
- * },
484
- * metaPath: "/SalesOrderManage"
485
- * }
486
- * The metaPath is used to remove any sensitive data.
487
- * @param {string | object} [mNavigationParameters.semanticObjectMapping] String representation of SemanticObjectMapping or SemanticObjectMapping that applies to this navigation
488
- **/
489
- navigateWithConfirmationDialog: function(sSemanticObject, sAction, mNavigationParameters) {
490
- var that = this;
491
- if (mNavigationParameters.notApplicableContexts && mNavigationParameters.notApplicableContexts.length >= 1) {
492
- var oApplicableContextDialog;
493
- var oController = {
494
- onClose: function() {
495
- // User cancels action
496
- oApplicableContextDialog.close();
497
- },
498
- onContinue: function() {
499
- // Users continues the action with the bound contexts
500
- mNavigationParameters.navigationContexts = mNavigationParameters.applicableContexts;
501
- oApplicableContextDialog.close();
502
- that.navigate(sSemanticObject, sAction, mNavigationParameters);
503
- }
504
- };
505
- var fnOpenAndFillDialog = function() {
506
- var oDialogContent,
507
- nNotApplicable = mNavigationParameters.notApplicableContexts.length,
508
- aNotApplicableItems = [];
509
- for (var i = 0; i < mNavigationParameters.notApplicableContexts.length; i++) {
510
- oDialogContent = mNavigationParameters.notApplicableContexts[i].getObject();
511
- aNotApplicableItems.push(oDialogContent);
512
- }
513
- var oNotApplicableItemsModel = new JSONModel(aNotApplicableItems);
514
- var oTotals = new JSONModel({ total: nNotApplicable, label: mNavigationParameters.label });
515
- oApplicableContextDialog.setModel(oNotApplicableItemsModel, "notApplicable");
516
- oApplicableContextDialog.setModel(oTotals, "totals");
517
- oApplicableContextDialog.open();
518
- };
519
- // Show the contexts that are not applicable and will not therefore be processed
520
- var sFragmentName = "sap.fe.core.controls.ActionPartial";
521
- var oDialogFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
522
- var oModel = this._oView.getModel();
523
- var oMetaModel = oModel.getMetaModel();
524
- var sCanonicalPath = mNavigationParameters.notApplicableContexts[0].getCanonicalPath();
525
- var sEntitySet = sCanonicalPath.substr(0, sCanonicalPath.indexOf("(")) + "/";
526
- Promise.resolve(
527
- XMLPreprocessor.process(
528
- oDialogFragment,
529
- { name: sFragmentName },
530
- {
531
- bindingContexts: {
532
- entityType: oMetaModel.createBindingContext(sEntitySet)
533
- },
534
- models: {
535
- entityType: oMetaModel,
536
- metaModel: oMetaModel
537
- }
538
- }
539
- )
540
- )
541
- .then(function(oFragment) {
542
- return Fragment.load({ definition: oFragment, controller: oController });
543
- })
544
- .then(function(oPopover) {
545
- oApplicableContextDialog = oPopover;
546
- that.getView().addDependent(oPopover);
547
- fnOpenAndFillDialog();
548
- })
549
- .catch(function() {
550
- Log.error("Error");
551
- });
552
- } else {
553
- that.navigate(sSemanticObject, sAction, mNavigationParameters);
554
- }
555
- },
556
- _removeTechnicalParameters: function(oSelectionVariant) {
557
- oSelectionVariant.removeSelectOption("@odata.context");
558
- oSelectionVariant.removeSelectOption("@odata.metadataEtag");
559
- oSelectionVariant.removeSelectOption("SAP__Messages");
560
- },
561
- /**
562
- * Get targeted Entity set.
563
- *
564
- * @returns {string} Entity set name
565
- *
566
- *
567
- */
568
- getEntitySet: function() {
569
- return this._oView.getViewData().entitySet;
570
- },
571
- /**
572
- * Removes sensitive data from the semantic attribute with respect to entitySet.
573
- *
574
- * @param {object} oAttributes Context data
575
- * @param {boolean} sMetaPath Meta path to reach the entityset in the MetaModel
576
- * @returns {Array} Array of semantic Attributes
577
- * @private
578
- **/
579
- // TO-DO add unit tests for this function in the controller extension qunit.
580
- removeSensitiveData: function(oAttributes, sMetaPath) {
581
- var aProperties = Object.keys(oAttributes);
582
- if (aProperties.length) {
583
- delete oAttributes["@odata.context"];
584
- delete oAttributes["@odata.metadataEtag"];
585
- delete oAttributes["SAP__Messages"];
586
- for (var j = 0; j < aProperties.length; j++) {
587
- if (oAttributes[aProperties[j]] && typeof oAttributes[aProperties[j]] === "object") {
588
- this.removeSensitiveData(oAttributes[aProperties[j]], sMetaPath + "/" + aProperties[j]);
589
- }
590
- var sProp = aProperties[j],
591
- aPropertyAnnotations = this._oMetaModel.getObject(sMetaPath + "/" + sProp + "@");
592
- if (aPropertyAnnotations) {
593
- if (
594
- aPropertyAnnotations["@com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive"] ||
595
- aPropertyAnnotations["@com.sap.vocabularies.UI.v1.ExcludeFromNavigationContext"] ||
596
- aPropertyAnnotations["@com.sap.vocabularies.Analytics.v1.Measure"]
597
- ) {
598
- delete oAttributes[sProp];
599
- } else if (aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"]) {
600
- var oFieldControl = aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"];
601
- if (oFieldControl["$EnumMember"] && oFieldControl["$EnumMember"].split("/")[1] === "Inapplicable") {
602
- delete oAttributes[sProp];
603
- } else if (
604
- oFieldControl["$Path"] &&
605
- this._isFieldControlPathInapplicable(oFieldControl["$Path"], oAttributes)
606
- ) {
607
- delete oAttributes[sProp];
608
- }
609
- }
610
- }
611
- }
612
- }
613
- return oAttributes;
614
- },
615
-
616
- /**
617
- * Check if Path based FieldControl Evaluates to inapplicable.
618
- *
619
- * @param {string} sFieldControlPath Field control path
620
- * @param {object} oAttribute SemanticAttributes
621
- * @returns {boolean} `true` if inapplicable
622
- *
623
- */
624
- _isFieldControlPathInapplicable: function(sFieldControlPath, oAttribute) {
625
- var bInapplicable = false,
626
- aParts = sFieldControlPath.split("/");
627
- // sensitive data is removed only if the path has already been resolved.
628
- if (aParts.length > 1) {
629
- bInapplicable =
630
- oAttribute[aParts[0]] && oAttribute[aParts[0]].hasOwnProperty(aParts[1]) && oAttribute[aParts[0]][aParts[1]] === 0;
631
- } else {
632
- bInapplicable = oAttribute[sFieldControlPath] === 0;
633
- }
634
- return bInapplicable;
635
- },
636
- /**
637
- * Method to replace Local Properties with Semantic Object mappings.
638
- *
639
- * @param {object} oSelectionVariant SelectionVariant consisting of filterbar, Table and Page Context
640
- * @param {object} vMappings A string representation of semantic object mapping
641
- * @returns {object} - Modified SelectionVariant with LocalProperty replaced with SemanticObjectProperties.
642
- */
643
- _applySemanticObjectMappings: function(oSelectionVariant, vMappings) {
644
- var oMappings = typeof vMappings === "string" ? JSON.parse(vMappings) : vMappings;
645
- for (var i = 0; i < oMappings.length; i++) {
646
- var sLocalProperty =
647
- (oMappings[i]["LocalProperty"] && oMappings[i]["LocalProperty"]["$PropertyPath"]) ||
648
- (oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"] &&
649
- oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"]["$Path"]);
650
- var sSemanticObjectProperty =
651
- oMappings[i]["SemanticObjectProperty"] || oMappings[i]["@com.sap.vocabularies.Common.v1.SemanticObjectProperty"];
652
- if (oSelectionVariant.getSelectOption(sLocalProperty)) {
653
- var oSelectOption = oSelectionVariant.getSelectOption(sLocalProperty);
654
-
655
- //Create a new SelectOption with sSemanticObjectProperty as the property Name and remove the older one
656
- oSelectionVariant.removeSelectOption(sLocalProperty);
657
- oSelectionVariant.massAddSelectOption(sSemanticObjectProperty, oSelectOption);
658
- }
659
- }
660
- return oSelectionVariant;
661
- },
662
- /**
663
- * Navigates to an Outbound provided in the manifest.
664
- * @function
665
- * @param {string} sOutbound Identifier to location the outbound in the manifest
666
- * @param {object} mNavigationParameters Optional map containing key/value pairs to be passed to the intent
667
- * @alias sap.fe.core.controllerextensions.IntentBasedNavigation#navigateOutbound
668
- * @since 1.86.0
669
- **/
670
- navigateOutbound: function(sOutbound, mNavigationParameters) {
671
- var oManifestEntry = this.base.getAppComponent().getManifestEntry("sap.app"),
672
- oOutbound = oManifestEntry.crossNavigation && oManifestEntry.crossNavigation.outbounds[sOutbound];
673
- if (!oOutbound) {
674
- Log.error("Outbound is not defined in manifest!!");
675
- return;
676
- }
677
- var sSemanticObject = oOutbound.semanticObject,
678
- sAction = oOutbound.action,
679
- outboundParams = oOutbound.parameters && this.getOutboundParams(oOutbound.parameters);
680
-
681
- if (mNavigationParameters) {
682
- var aNavParams = [];
683
- Object.keys(mNavigationParameters).forEach(function(key) {
684
- if (Array.isArray(mNavigationParameters[key])) {
685
- var aValues = mNavigationParameters[key];
686
- for (var i = 0; i < aValues.length; i++) {
687
- var oParams = {};
688
- oParams[key] = aValues[i];
689
- aNavParams.push(oParams);
690
- }
691
- } else {
692
- var oParams = {};
693
- oParams[key] = mNavigationParameters[key];
694
- aNavParams.push(oParams);
695
- }
696
- });
697
- }
698
- if (aNavParams || outboundParams) {
699
- mNavigationParameters = {
700
- navigationContexts: {
701
- data: aNavParams || outboundParams
702
- }
703
- };
704
- }
705
- this.base._intentBasedNavigation.navigate(sSemanticObject, sAction, mNavigationParameters);
706
- },
707
-
708
- /**
709
- * Method to apply outbound parameters defined in the manifest.
710
- * @param {object} oSelectionVariant SelectionVariant consisting of a filter bar, a table, and a page context
711
- * @param {object} vOutboundParams Outbound Properties defined in the manifest
712
- * @returns {object} - The modified SelectionVariant with outbound parameters.
713
- */
714
- _applyOutboundParams: function(oSelectionVariant, vOutboundParams) {
715
- var aParameters = Object.keys(vOutboundParams);
716
- var aSelectProperties = oSelectionVariant.getSelectOptionsPropertyNames();
717
- aParameters.forEach(function(key) {
718
- if (!aSelectProperties.includes(key)) {
719
- oSelectionVariant.addSelectOption(key, "I", "EQ", vOutboundParams[key]);
720
- }
721
- });
722
- return oSelectionVariant;
723
- },
724
- /**
725
- * Method to get the outbound parameters defined in the manifest.
726
- *
727
- * @function
728
- * @param {object} [oOutboundParams] Parameters defined in the outbounds. Only "plain" is supported
729
- * @returns {Array} Parameters with the key-Value pair
730
- **/
731
- getOutboundParams: function(oOutboundParams) {
732
- var oParamsMapping = {};
733
- if (oOutboundParams) {
734
- var aParameters = Object.keys(oOutboundParams) || [];
735
- if (aParameters.length > 0) {
736
- aParameters.forEach(function(key) {
737
- var oMapping = oOutboundParams[key];
738
- if (oMapping.value && oMapping.value.value && oMapping.value.format === "plain") {
739
- if (!oParamsMapping[key]) {
740
- oParamsMapping[key] = oMapping.value.value;
741
- }
742
- }
743
- });
744
- }
745
- }
746
- return oParamsMapping;
747
- },
748
-
749
- /**
750
- * Triggers an outbound navigation when a user chooses the chevron.
751
- *
752
- * @param {object} oController
753
- * @param {string} sOutboundTarget Name of the outbound target (needs to be defined in the manifest)
754
- * @param {sap.ui.model.odata.v4.Context} oContext The context that contains the data for the target app
755
- * @param {string} sCreatePath Create path when the chevron is created.
756
- * @returns {Promise} Promise which is resolved once the navigation is triggered
757
- */
758
-
759
- onChevronPressNavigateOutBound: function(oController, sOutboundTarget, oContext, sCreatePath) {
760
- var oOutbounds = oController
761
- .getAppComponent()
762
- .getRoutingService()
763
- .getOutbounds(),
764
- oDisplayOutbound = oOutbounds[sOutboundTarget],
765
- additionalNavigationParameters;
766
- if (oDisplayOutbound && oDisplayOutbound.semanticObject && oDisplayOutbound.action) {
767
- var oRefreshStrategies = {
768
- intents: {}
769
- },
770
- oDefaultRefreshStrategy = {},
771
- sMetaPath;
772
-
773
- if (oContext) {
774
- if (oContext.isA && oContext.isA("sap.ui.model.odata.v4.Context")) {
775
- sMetaPath = ModelHelper.getMetaPathForContext(oContext);
776
- oContext = [oContext];
777
- } else {
778
- sMetaPath = ModelHelper.getMetaPathForContext(oContext[0]);
779
- }
780
- oDefaultRefreshStrategy[sMetaPath] = "self";
781
- oRefreshStrategies["_feDefault"] = oDefaultRefreshStrategy;
782
- }
783
-
784
- if (sCreatePath) {
785
- var sKey = oDisplayOutbound.semanticObject + "-" + oDisplayOutbound.action;
786
- oRefreshStrategies.intents[sKey] = {};
787
- oRefreshStrategies.intents[sKey][sCreatePath] = "self";
788
- }
789
- if (oDisplayOutbound && oDisplayOutbound.parameters) {
790
- var oParams = oDisplayOutbound.parameters && this.getOutboundParams(oDisplayOutbound.parameters);
791
- if (Object.keys(oParams).length > 0) {
792
- additionalNavigationParameters = oParams;
793
- }
794
- }
795
-
796
- oController._intentBasedNavigation.navigate(oDisplayOutbound.semanticObject, oDisplayOutbound.action, {
797
- navigationContexts: oContext,
798
- refreshStrategies: oRefreshStrategies,
799
- additionalNavigationParameters: additionalNavigationParameters
800
- });
801
-
802
- //TODO: check why returning a promise is required
803
- return Promise.resolve();
804
- } else {
805
- throw new Error("outbound target " + sOutboundTarget + " not found in cross navigation definition of manifest");
806
- }
807
- },
808
-
809
- override: {
810
- onInit: function() {
811
- this._oAppComponent = this.base.getAppComponent();
812
- this._oMetaModel = this._oAppComponent.getModel().getMetaModel();
813
- this._oNavigationService = this._oAppComponent.getNavigationService();
814
- this._oView = this.base.getView();
815
- }
816
- }
817
- });
818
- }
819
- );
5
+ sap.ui.define(["sap/ui/core/mvc/ControllerExtension", "sap/ui/core/mvc/OverrideExecution", "sap/fe/navigation/SelectionVariant", "sap/fe/core/helpers/ModelHelper", "sap/ui/core/util/XMLPreprocessor", "sap/ui/core/XMLTemplateProcessor", "sap/ui/core/Fragment", "sap/ui/model/json/JSONModel", "sap/base/Log", "sap/fe/core/CommonUtils", "sap/fe/core/helpers/KeepAliveHelper", "sap/base/util/merge", "sap/fe/core/helpers/ClassSupport", "sap/fe/core/controllerextensions/ControllerExtensionMetadata"], function (ControllerExtension, OverrideExecution, SelectionVariant, ModelHelper, XMLPreprocessor, XMLTemplateProcessor, Fragment, JSONModel, Log, CommonUtils, KeepAliveHelper, mergeObjects, ClassSupport, ControllerExtensionMetadata) {
6
+ "use strict";
7
+
8
+ var _dec, _dec2, _dec3, _class, _class2;
9
+
10
+ var UI5Class = ClassSupport.UI5Class;
11
+ var Public = ClassSupport.Public;
12
+ var Private = ClassSupport.Private;
13
+ var Override = ClassSupport.Override;
14
+ var Final = ClassSupport.Final;
15
+ var Extensible = ClassSupport.Extensible;
16
+
17
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
18
+
19
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
20
+
21
+ function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; }
22
+
23
+ /**
24
+ * {@link sap.ui.core.mvc.ControllerExtension Controller extension}
25
+ *
26
+ * @namespace
27
+ * @alias sap.fe.core.controllerextensions.InternalInternalBasedNavigation
28
+ *
29
+ * @private
30
+ * @since 1.84.0
31
+ */
32
+ var InternalIntentBasedNavigation = (_dec = UI5Class("sap.fe.core.controllerextensions.InternalInternalBasedNavigation", ControllerExtensionMetadata), _dec2 = Override(), _dec3 = Extensible(OverrideExecution.Instead), _dec(_class = (_class2 = /*#__PURE__*/function (_ControllerExtension) {
33
+ _inherits(InternalIntentBasedNavigation, _ControllerExtension);
34
+
35
+ function InternalIntentBasedNavigation() {
36
+ return _ControllerExtension.apply(this, arguments) || this;
37
+ }
38
+
39
+ var _proto = InternalIntentBasedNavigation.prototype;
40
+
41
+ _proto.onInit = function onInit() {
42
+ this._oAppComponent = this.base.getAppComponent();
43
+ this._oMetaModel = this._oAppComponent.getModel().getMetaModel();
44
+ this._oNavigationService = this._oAppComponent.getNavigationService();
45
+ this._oView = this.base.getView();
46
+ }
47
+ /**
48
+ * Enables intent-based navigation (SemanticObject-Action) with the provided context.
49
+ * If semantic object mapping is provided, this is also applied to the selection variant after the adaptation by a consumer.
50
+ * This takes care of removing any technical parameters and determines if an explace or inplace navigation should take place.
51
+ *
52
+ * @param {string} sSemanticObject Semantic object for the target app
53
+ * @param {string} sAction Action for the target app
54
+ * @param {object} [mNavigationParameters] Optional parameters to be passed to the external navigation
55
+ * @param {Array|object} [mNavigationParameters.navigationContexts] Uses one of the following to be passed to the intent:
56
+ * a single instance of {@link sap.ui.model.odata.v4.Context}
57
+ * multiple instances of {@link sap.ui.model.odata.v4.Context}
58
+ * an object or an array of objects
59
+ * If an array of objects is passed, the context is used to determine the metaPath and to remove any sensitive data
60
+ * If an array of objects is passed, the following format ix expected:
61
+ * {
62
+ * data: {
63
+ * ProductID: 7634,
64
+ * Name: "Laptop"
65
+ * },
66
+ * metaPath: "/SalesOrderManage"
67
+ * }
68
+ * @param {string | object} [mNavigationParameters.semanticObjectMapping] String representation of the SemanticObjectMapping or SemanticObjectMapping that applies to this navigation
69
+ * @param {object} [mNavigationParameters.defaultRefreshStrategy] Default refresh strategy to be used in case no refresh strategy is specified for the intent in the view.
70
+ * @param {object} [mNavigationParameters.refreshStrategies]
71
+ * @param {object} [mNavigationParameters.additionalNavigationParameters] Additional navigation parameters configured in the crossAppNavigation outbound parameters.
72
+ **/
73
+ ;
74
+
75
+ _proto.navigate = function navigate(sSemanticObject, sAction, mNavigationParameters) {
76
+ var _this = this;
77
+
78
+ var _doNavigate = function (oContext) {
79
+ var vNavigationContexts = mNavigationParameters && mNavigationParameters.navigationContexts,
80
+ aNavigationContexts = vNavigationContexts && !Array.isArray(vNavigationContexts) ? [vNavigationContexts] : vNavigationContexts,
81
+ vSemanticObjectMapping = mNavigationParameters && mNavigationParameters.semanticObjectMapping,
82
+ vOutboundParams = mNavigationParameters && mNavigationParameters.additionalNavigationParameters,
83
+ oTargetInfo = {
84
+ semanticObject: sSemanticObject,
85
+ action: sAction
86
+ },
87
+ oView = _this.base.getView(),
88
+ oController = oView.getController();
89
+
90
+ if (oContext) {
91
+ _this._oView.setBindingContext(oContext);
92
+ }
93
+
94
+ if (sSemanticObject && sAction) {
95
+ var aSemanticAttributes = [],
96
+ oSelectionVariant = new SelectionVariant(); // 1. get SemanticAttributes for navigation
97
+
98
+ if (aNavigationContexts && aNavigationContexts.length) {
99
+ aNavigationContexts.map(function (oNavigationContext) {
100
+ // 1.1.a if navigation context is instance of sap.ui.mode.odata.v4.Context
101
+ // else check if navigation context is of type object
102
+ if (oNavigationContext.isA && oNavigationContext.isA("sap.ui.model.odata.v4.Context")) {
103
+ // 1.1.b remove sensitive data
104
+ var oSemanticAttributes = oNavigationContext.getObject();
105
+
106
+ var sMetaPath = _this._oMetaModel.getMetaPath(oNavigationContext.getPath()); // TODO: also remove sensitive data from navigation properties
107
+
108
+
109
+ oSemanticAttributes = _this.removeSensitiveData(oSemanticAttributes, sMetaPath);
110
+
111
+ var oNavContext = _this.prepareContextForExternalNavigation(oSemanticAttributes, oNavigationContext);
112
+
113
+ oTargetInfo["propertiesWithoutConflict"] = oNavContext.propertiesWithoutConflict;
114
+ aSemanticAttributes.push(oNavContext.semanticAttributes);
115
+ } else if (!(oNavigationContext && Array.isArray(oNavigationContext.data)) && typeof oNavigationContext === "object") {
116
+ // 1.1.b remove sensitive data from object
117
+ aSemanticAttributes.push(_this.removeSensitiveData(oNavigationContext.data, oNavigationContext.metaPath));
118
+ } else if (oNavigationContext && Array.isArray(oNavigationContext.data)) {
119
+ // oNavigationContext.data can be array already ex : [{Customer: "10001"}, {Customer: "10091"}]
120
+ // hence assigning it to the aSemanticAttributes
121
+ aSemanticAttributes = _this.removeSensitiveData(oNavigationContext.data, oNavigationContext.metaPath);
122
+ }
123
+ });
124
+ } // 2.1 Merge base selection variant and sanitized semantic attributes into one SelectionVariant
125
+
126
+
127
+ if (aSemanticAttributes && aSemanticAttributes.length) {
128
+ oSelectionVariant = _this._oNavigationService.mixAttributesAndSelectionVariant(aSemanticAttributes, oSelectionVariant.toJSONString());
129
+ } // 3. Add filterContextUrl to SV so the NavigationHandler can remove any sensitive data based on view entitySet
130
+
131
+
132
+ var oModel = _this._oView.getModel(),
133
+ sEntitySet = _this.getEntitySet(),
134
+ sContextUrl = sEntitySet ? _this._oNavigationService.constructContextUrl(sEntitySet, oModel) : undefined;
135
+
136
+ if (sContextUrl) {
137
+ oSelectionVariant.setFilterContextUrl(sContextUrl);
138
+ } // Apply Outbound Parameters to the SV
139
+
140
+
141
+ if (vOutboundParams) {
142
+ _this._applyOutboundParams(oSelectionVariant, vOutboundParams);
143
+ } // 4. give an opportunity for the application to influence the SelectionVariant
144
+
145
+
146
+ oController.intentBasedNavigation.adaptNavigationContext(oSelectionVariant, oTargetInfo); // 5. Apply semantic object mappings to the SV
147
+
148
+ if (vSemanticObjectMapping) {
149
+ _this._applySemanticObjectMappings(oSelectionVariant, vSemanticObjectMapping);
150
+ } // 6. remove technical parameters from Selection Variant
151
+
152
+
153
+ _this._removeTechnicalParameters(oSelectionVariant); // 7. check if programming model is sticky and page is editable
154
+
155
+
156
+ var sNavMode = oController._intentBasedNavigation.getNavigationMode(); // 8. Updating refresh strategy in internal model
157
+
158
+
159
+ var mRefreshStrategies = mNavigationParameters && mNavigationParameters.refreshStrategies || {},
160
+ oInternalModel = oView.getModel("internal");
161
+
162
+ if (oInternalModel) {
163
+ if ((oView && oView.getViewData()).refreshStrategyOnAppRestore) {
164
+ var mViewRefreshStrategies = oView.getViewData().refreshStrategyOnAppRestore || {};
165
+ mergeObjects(mRefreshStrategies, mViewRefreshStrategies);
166
+ }
167
+
168
+ var mRefreshStrategy = KeepAliveHelper.getRefreshStrategyForIntent(mRefreshStrategies, sSemanticObject, sAction);
169
+
170
+ if (mRefreshStrategy) {
171
+ oInternalModel.setProperty("/refreshStrategyOnAppRestore", mRefreshStrategy);
172
+ }
173
+ } // 9. Navigate via NavigationHandler
174
+
175
+
176
+ var onError = function () {
177
+ sap.ui.require(["sap/m/MessageBox"], function (MessageBox) {
178
+ var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core");
179
+ MessageBox.show(oResourceBundle.getText("C_COMMON_HELPER_NAVIGATION_ERROR_MESSAGE"), {
180
+ title: oResourceBundle.getText("C_COMMON_NAVIGATION_ERROR_TITLE")
181
+ });
182
+ });
183
+ };
184
+
185
+ _this._oNavigationService.navigate(sSemanticObject, sAction, oSelectionVariant.toJSONString(), undefined, onError, undefined, sNavMode);
186
+ } else {
187
+ throw new Error("Semantic Object/action is not provided");
188
+ }
189
+ };
190
+
191
+ var oBindingContext = this.base.getView().getBindingContext();
192
+ var oMetaModel = oBindingContext && oBindingContext.getModel().getMetaModel();
193
+
194
+ if (this.getView().getViewData().converterType === "ObjectPage" && oMetaModel && !ModelHelper.isStickySessionSupported(oMetaModel)) {
195
+ CommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(_doNavigate.bind(this), Function.prototype, this.base.getView().getBindingContext(), this.base.getView().getController());
196
+ } else {
197
+ _doNavigate();
198
+ }
199
+ }
200
+ /**
201
+ * Prepare attributes to be passed to external navigation.
202
+ * @param {object} oSemanticAttributes Context data after removing all sensitive information.
203
+ * @param {object} oContext Actual context from which the semanticAttributes were derived.
204
+ * @returns {object} Object of prepared attributes for external navigation and no conflict properties.
205
+ */
206
+ ;
207
+
208
+ _proto.prepareContextForExternalNavigation = function prepareContextForExternalNavigation(oSemanticAttributes, oContext) {
209
+ // 1. Find all distinct keys in the object SemanticAttributes
210
+ // Store meta path for each occurence of the key
211
+ var oDistinctKeys = {},
212
+ sContextPath = oContext.getPath(),
213
+ oMetaModel = oContext.getModel().getMetaModel(),
214
+ sMetaPath = oMetaModel.getMetaPath(sContextPath),
215
+ aMetaPathParts = sMetaPath.split("/").filter(Boolean);
216
+
217
+ function _findDistinctKeysInObject(LookUpObject, sLookUpObjectMetaPath) {
218
+ for (var sKey in LookUpObject) {
219
+ // null case??
220
+ if (LookUpObject[sKey] === null || typeof LookUpObject[sKey] !== "object") {
221
+ if (!oDistinctKeys[sKey]) {
222
+ // if key is found for the first time then create array
223
+ oDistinctKeys[sKey] = [];
224
+ } // push path to array
225
+
226
+
227
+ oDistinctKeys[sKey].push(sLookUpObjectMetaPath);
228
+ } else {
229
+ // if a nested object is found
230
+ var oNewLookUpObject = LookUpObject[sKey];
231
+
232
+ _findDistinctKeysInObject(oNewLookUpObject, sLookUpObjectMetaPath + "/" + sKey);
233
+ }
234
+ }
235
+ }
236
+
237
+ _findDistinctKeysInObject(oSemanticAttributes, sMetaPath); // 2. Determine distinct key value and add conflicted paths to semantic attributes
238
+
239
+
240
+ var sMainEntitySetName = aMetaPathParts[0],
241
+ sMainEntityTypeName = oMetaModel.getObject("/" + sMainEntitySetName + "/@sapui.name"),
242
+ oPropertiesWithoutConflict = {};
243
+ var sMainEntityValuePath, sCurrentValuePath, sLastValuePath;
244
+
245
+ for (var sDistinctKey in oDistinctKeys) {
246
+ var aConflictingPaths = oDistinctKeys[sDistinctKey];
247
+ var sWinnerValuePath = void 0; // Find winner value for each distinct key in case of conflict by the following rule:
248
+ // -> A. if any meta path for a distinct key is the same as main entity take that as the value
249
+ // -> B. if A is not met keep the value from the current context (sMetaPath === path of distince key)
250
+ // -> C. if A, B or C are not met take the last path for value
251
+
252
+ if (aConflictingPaths.length > 1) {
253
+ // conflict
254
+ for (var i = 0; i <= aConflictingPaths.length - 1; i++) {
255
+ var sPath = aConflictingPaths[i];
256
+ var sPathInContext = sPath.replace(sPath === sMetaPath ? sMetaPath : sMetaPath + "/", "");
257
+ sPathInContext = (sPathInContext === "" ? sPathInContext : sPathInContext + "/") + sDistinctKey;
258
+ var sEntityTypeName = oMetaModel.getObject(sPath + "/@sapui.name"); // rule A
259
+ // rule A
260
+
261
+ if (sEntityTypeName === sMainEntityTypeName) {
262
+ sMainEntityValuePath = sPathInContext;
263
+ } // rule B
264
+
265
+
266
+ if (sPath === sMetaPath) {
267
+ sCurrentValuePath = sPathInContext;
268
+ } // rule C
269
+
270
+
271
+ sLastValuePath = sPathInContext; // add conflicted path to semantic attributes
272
+ // check if the current path points to main entity and prefix attribute names accordingly
273
+
274
+ oSemanticAttributes[(sMetaPath + "/" + sPathInContext).split("/").filter(function (sValue) {
275
+ return sValue != "";
276
+ }).join(".")] = oContext.getProperty(sPathInContext);
277
+ } // A || B || C
278
+
279
+
280
+ sWinnerValuePath = sMainEntityValuePath || sCurrentValuePath || sLastValuePath;
281
+ oSemanticAttributes[sDistinctKey] = oContext.getProperty(sWinnerValuePath);
282
+ sMainEntityValuePath = undefined;
283
+ sCurrentValuePath = undefined;
284
+ sLastValuePath = undefined;
285
+ } else {
286
+ // no conflict, add distinct key without adding paths
287
+ var _sPath = aConflictingPaths[0]; // because there is only one and hence no conflict
288
+
289
+ var _sPathInContext = _sPath.replace(_sPath === sMetaPath ? sMetaPath : sMetaPath + "/", "");
290
+
291
+ _sPathInContext = (_sPathInContext === "" ? _sPathInContext : _sPathInContext + "/") + sDistinctKey;
292
+ oSemanticAttributes[sDistinctKey] = oContext.getProperty(_sPathInContext);
293
+ oPropertiesWithoutConflict[sDistinctKey] = (sMetaPath + "/" + _sPathInContext).split("/").filter(function (sValue) {
294
+ return sValue != "";
295
+ }).join(".");
296
+ }
297
+ } // 3. Remove all Navigation properties
298
+
299
+
300
+ for (var sProperty in oSemanticAttributes) {
301
+ if (oSemanticAttributes[sProperty] !== null && typeof oSemanticAttributes[sProperty] === "object") {
302
+ delete oSemanticAttributes[sProperty];
303
+ }
304
+ }
305
+
306
+ return {
307
+ semanticAttributes: oSemanticAttributes,
308
+ propertiesWithoutConflict: oPropertiesWithoutConflict
309
+ };
310
+ }
311
+ /**
312
+ * Prepare filter conditions to be passed to external navigation.
313
+ * @param {object} oFilterBarConditions Filter conditions.
314
+ * @param {string} sRootPath Root path of the application.
315
+ * @param {Array} aParameters Names of parameters to be considered.
316
+ * @returns {object} Object of prepared filter conditions for external navigation and no conflict filters.
317
+ */
318
+ ;
319
+
320
+ _proto.prepareFiltersForExternalNavigation = function prepareFiltersForExternalNavigation(oFilterBarConditions, sRootPath, aParameters) {
321
+ var sPath;
322
+ var oDistinctKeys = {};
323
+ var oFilterConditionsWithoutConflict = {};
324
+ var sMainEntityValuePath, sCurrentValuePath, sFullContextPath, sWinnerValuePath, sPathInContext;
325
+
326
+ function _findDistinctKeysInObject(LookUpObject) {
327
+ var sLookUpObjectMetaPath;
328
+
329
+ for (var sKey in LookUpObject) {
330
+ if (LookUpObject[sKey]) {
331
+ if (sKey.includes("/")) {
332
+ sLookUpObjectMetaPath = sKey; // "/SalesOrdermanage/_Item/Material"
333
+
334
+ var aPathParts = sKey.split("/");
335
+ sKey = aPathParts[aPathParts.length - 1];
336
+ } else {
337
+ sLookUpObjectMetaPath = sRootPath;
338
+ }
339
+
340
+ if (!oDistinctKeys[sKey]) {
341
+ // if key is found for the first time then create array
342
+ oDistinctKeys[sKey] = [];
343
+ } // push path to array
344
+
345
+
346
+ oDistinctKeys[sKey].push(sLookUpObjectMetaPath);
347
+ }
348
+ }
349
+ }
350
+
351
+ _findDistinctKeysInObject(oFilterBarConditions);
352
+
353
+ for (var sDistinctKey in oDistinctKeys) {
354
+ var aConflictingPaths = oDistinctKeys[sDistinctKey];
355
+
356
+ if (aConflictingPaths.length > 1) {
357
+ // conflict
358
+ for (var i = 0; i <= aConflictingPaths.length - 1; i++) {
359
+ sPath = aConflictingPaths[i];
360
+
361
+ if (sPath === sRootPath) {
362
+ sFullContextPath = sRootPath + "/" + sDistinctKey;
363
+ sPathInContext = sDistinctKey;
364
+ sMainEntityValuePath = sDistinctKey;
365
+
366
+ if (aParameters && aParameters.includes(sDistinctKey)) {
367
+ oFilterBarConditions["$Parameter." + sDistinctKey] = oFilterBarConditions[sDistinctKey];
368
+ }
369
+ } else {
370
+ sPathInContext = sPath;
371
+ sFullContextPath = (sRootPath + "/" + sPath).replaceAll(/\*/g, "");
372
+ sCurrentValuePath = sPath;
373
+ }
374
+
375
+ oFilterBarConditions[sFullContextPath.split("/").filter(function (sValue) {
376
+ return sValue != "";
377
+ }).join(".")] = oFilterBarConditions[sPathInContext];
378
+ delete oFilterBarConditions[sPath];
379
+ }
380
+
381
+ sWinnerValuePath = sMainEntityValuePath || sCurrentValuePath;
382
+ oFilterBarConditions[sDistinctKey] = oFilterBarConditions[sWinnerValuePath];
383
+ } else {
384
+ // no conflict, add distinct key without adding paths
385
+ sPath = aConflictingPaths[0];
386
+ sFullContextPath = sPath === sRootPath ? sRootPath + "/" + sDistinctKey : (sRootPath + "/" + sPath).replaceAll("*", "");
387
+ oFilterConditionsWithoutConflict[sDistinctKey] = sFullContextPath.split("/").filter(function (sValue) {
388
+ return sValue != "";
389
+ }).join(".");
390
+
391
+ if (aParameters && aParameters.includes(sDistinctKey)) {
392
+ oFilterBarConditions["$Parameter." + sDistinctKey] = oFilterBarConditions[sDistinctKey];
393
+ }
394
+ }
395
+ }
396
+
397
+ return {
398
+ filterConditions: oFilterBarConditions,
399
+ filterConditionsWithoutConflict: oFilterConditionsWithoutConflict
400
+ };
401
+ }
402
+ /**
403
+ * Get Navigation mode.
404
+ *
405
+ * @returns {string}
406
+ */
407
+ ;
408
+
409
+ _proto.getNavigationMode = function getNavigationMode() {
410
+ return undefined;
411
+ }
412
+ /**
413
+ * Allows for navigation to a given intent (SemanticObject-Action) with the provided context, using a dialog that shows the contexts which cannot be passed
414
+ * If semantic object mapping is provided, this setting is also applied to the selection variant after adaptation by a consumer.
415
+ * This setting also removes any technical parameters and determines if an inplace or explace navigation should take place.
416
+ *
417
+ * @param {string} sSemanticObject Semantic object for the target app
418
+ * @param {string} sAction Action for the target app
419
+ * @param {object} [mNavigationParameters] Optional parameters to be passed to the external navigation
420
+ * @param {string} [mNavigationParameters.label]
421
+ * @param {Array|object} [mNavigationParameters.navigationContexts] Single instance or multiple instances of {@link sap.ui.model.odata.v4.Context}, or alternatively an object or array of objects, to be passed to the intent.
422
+ * @param {Array|object} [mNavigationParameters.applicableContexts] Single instance or multiple instances of {@link sap.ui.model.odata.v4.Context}, or alternatively an object or array of objects, to be passed to the intent and for which the IBN button is enabled
423
+ * @param {Array|object} [mNavigationParameters.notApplicableContexts] Single instance or multiple instances of {@link sap.ui.model.odata.v4.Context}, or alternatively an object or array of objects, which cannot be passed to the intent.
424
+ * if an array of contexts is passed the context is used to determine the meta path and accordingly remove the sensitive data
425
+ * If an array of objects is passed, the following format is expected:
426
+ * {
427
+ * data: {
428
+ * ProductID: 7634,
429
+ * Name: "Laptop"
430
+ * },
431
+ * metaPath: "/SalesOrderManage"
432
+ * }
433
+ * The metaPath is used to remove any sensitive data.
434
+ * @param {string | object} [mNavigationParameters.semanticObjectMapping] String representation of SemanticObjectMapping or SemanticObjectMapping that applies to this navigation
435
+ **/
436
+ ;
437
+
438
+ _proto.navigateWithConfirmationDialog = function navigateWithConfirmationDialog(sSemanticObject, sAction, mNavigationParameters) {
439
+ var _mNavigationParameter,
440
+ _this2 = this;
441
+
442
+ if (mNavigationParameters !== null && mNavigationParameters !== void 0 && mNavigationParameters.notApplicableContexts && ((_mNavigationParameter = mNavigationParameters.notApplicableContexts) === null || _mNavigationParameter === void 0 ? void 0 : _mNavigationParameter.length) >= 1) {
443
+ var oApplicableContextDialog;
444
+ var oController = {
445
+ onClose: function () {
446
+ // User cancels action
447
+ oApplicableContextDialog.close();
448
+ },
449
+ onContinue: function () {
450
+ // Users continues the action with the bound contexts
451
+ mNavigationParameters.navigationContexts = mNavigationParameters.applicableContexts;
452
+ oApplicableContextDialog.close();
453
+
454
+ _this2.navigate(sSemanticObject, sAction, mNavigationParameters);
455
+ }
456
+ };
457
+
458
+ var fnOpenAndFillDialog = function () {
459
+ var oDialogContent;
460
+ var nNotApplicable = mNavigationParameters.notApplicableContexts.length,
461
+ aNotApplicableItems = [];
462
+
463
+ for (var i = 0; i < mNavigationParameters.notApplicableContexts.length; i++) {
464
+ oDialogContent = mNavigationParameters.notApplicableContexts[i].getObject();
465
+ aNotApplicableItems.push(oDialogContent);
466
+ }
467
+
468
+ var oNotApplicableItemsModel = new JSONModel(aNotApplicableItems);
469
+ var oTotals = new JSONModel({
470
+ total: nNotApplicable,
471
+ label: mNavigationParameters.label
472
+ });
473
+ oApplicableContextDialog.setModel(oNotApplicableItemsModel, "notApplicable");
474
+ oApplicableContextDialog.setModel(oTotals, "totals");
475
+ oApplicableContextDialog.open();
476
+ }; // Show the contexts that are not applicable and will not therefore be processed
477
+
478
+
479
+ var sFragmentName = "sap.fe.core.controls.ActionPartial";
480
+ var oDialogFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment");
481
+
482
+ var oModel = this._oView.getModel();
483
+
484
+ var oMetaModel = oModel.getMetaModel();
485
+ var sCanonicalPath = mNavigationParameters.notApplicableContexts[0].getCanonicalPath();
486
+ var sEntitySet = sCanonicalPath.substr(0, sCanonicalPath.indexOf("(")) + "/";
487
+ Promise.resolve(XMLPreprocessor.process(oDialogFragment, {
488
+ name: sFragmentName
489
+ }, {
490
+ bindingContexts: {
491
+ entityType: oMetaModel.createBindingContext(sEntitySet)
492
+ },
493
+ models: {
494
+ entityType: oMetaModel,
495
+ metaModel: oMetaModel
496
+ }
497
+ })).then(function (oFragment) {
498
+ return Fragment.load({
499
+ definition: oFragment,
500
+ controller: oController
501
+ });
502
+ }).then(function (oPopover) {
503
+ oApplicableContextDialog = oPopover;
504
+
505
+ _this2.getView().addDependent(oPopover);
506
+
507
+ fnOpenAndFillDialog();
508
+ }).catch(function () {
509
+ Log.error("Error");
510
+ });
511
+ } else {
512
+ this.navigate(sSemanticObject, sAction, mNavigationParameters);
513
+ }
514
+ };
515
+
516
+ _proto._removeTechnicalParameters = function _removeTechnicalParameters(oSelectionVariant) {
517
+ oSelectionVariant.removeSelectOption("@odata.context");
518
+ oSelectionVariant.removeSelectOption("@odata.metadataEtag");
519
+ oSelectionVariant.removeSelectOption("SAP__Messages");
520
+ }
521
+ /**
522
+ * Get targeted Entity set.
523
+ *
524
+ * @returns {string} Entity set name
525
+ *
526
+ *
527
+ */
528
+ ;
529
+
530
+ _proto.getEntitySet = function getEntitySet() {
531
+ return this._oView.getViewData().entitySet;
532
+ }
533
+ /**
534
+ * Removes sensitive data from the semantic attribute with respect to entitySet.
535
+ *
536
+ * @param {object} oAttributes Context data
537
+ * @param {string} sMetaPath Meta path to reach the entityset in the MetaModel
538
+ * @returns {Array} Array of semantic Attributes
539
+ * @private
540
+ **/
541
+ // TO-DO add unit tests for this function in the controller extension qunit.
542
+ ;
543
+
544
+ _proto.removeSensitiveData = function removeSensitiveData(oAttributes, sMetaPath) {
545
+ var aProperties = Object.keys(oAttributes);
546
+
547
+ if (aProperties.length) {
548
+ delete oAttributes["@odata.context"];
549
+ delete oAttributes["@odata.metadataEtag"];
550
+ delete oAttributes["SAP__Messages"];
551
+
552
+ for (var j = 0; j < aProperties.length; j++) {
553
+ if (oAttributes[aProperties[j]] && typeof oAttributes[aProperties[j]] === "object") {
554
+ this.removeSensitiveData(oAttributes[aProperties[j]], sMetaPath + "/" + aProperties[j]);
555
+ }
556
+
557
+ var sProp = aProperties[j],
558
+ aPropertyAnnotations = this._oMetaModel.getObject(sMetaPath + "/" + sProp + "@");
559
+
560
+ if (aPropertyAnnotations) {
561
+ if (aPropertyAnnotations["@com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive"] || aPropertyAnnotations["@com.sap.vocabularies.UI.v1.ExcludeFromNavigationContext"] || aPropertyAnnotations["@com.sap.vocabularies.Analytics.v1.Measure"]) {
562
+ delete oAttributes[sProp];
563
+ } else if (aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"]) {
564
+ var oFieldControl = aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"];
565
+
566
+ if (oFieldControl["$EnumMember"] && oFieldControl["$EnumMember"].split("/")[1] === "Inapplicable") {
567
+ delete oAttributes[sProp];
568
+ } else if (oFieldControl["$Path"] && this._isFieldControlPathInapplicable(oFieldControl["$Path"], oAttributes)) {
569
+ delete oAttributes[sProp];
570
+ }
571
+ }
572
+ }
573
+ }
574
+ }
575
+
576
+ return oAttributes;
577
+ }
578
+ /**
579
+ * Check if Path based FieldControl Evaluates to inapplicable.
580
+ *
581
+ * @param {string} sFieldControlPath Field control path
582
+ * @param {object} oAttribute SemanticAttributes
583
+ * @returns {boolean} `true` if inapplicable
584
+ *
585
+ */
586
+ ;
587
+
588
+ _proto._isFieldControlPathInapplicable = function _isFieldControlPathInapplicable(sFieldControlPath, oAttribute) {
589
+ var bInapplicable = false;
590
+ var aParts = sFieldControlPath.split("/"); // sensitive data is removed only if the path has already been resolved.
591
+
592
+ if (aParts.length > 1) {
593
+ bInapplicable = oAttribute[aParts[0]] && oAttribute[aParts[0]].hasOwnProperty(aParts[1]) && oAttribute[aParts[0]][aParts[1]] === 0;
594
+ } else {
595
+ bInapplicable = oAttribute[sFieldControlPath] === 0;
596
+ }
597
+
598
+ return bInapplicable;
599
+ }
600
+ /**
601
+ * Method to replace Local Properties with Semantic Object mappings.
602
+ *
603
+ * @param {object} oSelectionVariant SelectionVariant consisting of filterbar, Table and Page Context
604
+ * @param {object | string} vMappings A string representation of semantic object mapping
605
+ * @returns {object} - Modified SelectionVariant with LocalProperty replaced with SemanticObjectProperties.
606
+ */
607
+ ;
608
+
609
+ _proto._applySemanticObjectMappings = function _applySemanticObjectMappings(oSelectionVariant, vMappings) {
610
+ var oMappings = typeof vMappings === "string" ? JSON.parse(vMappings) : vMappings;
611
+
612
+ for (var i = 0; i < oMappings.length; i++) {
613
+ var sLocalProperty = oMappings[i]["LocalProperty"] && oMappings[i]["LocalProperty"]["$PropertyPath"] || oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"] && oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"]["$Path"];
614
+ var sSemanticObjectProperty = oMappings[i]["SemanticObjectProperty"] || oMappings[i]["@com.sap.vocabularies.Common.v1.SemanticObjectProperty"];
615
+
616
+ if (oSelectionVariant.getSelectOption(sLocalProperty)) {
617
+ var oSelectOption = oSelectionVariant.getSelectOption(sLocalProperty); //Create a new SelectOption with sSemanticObjectProperty as the property Name and remove the older one
618
+
619
+ oSelectionVariant.removeSelectOption(sLocalProperty);
620
+ oSelectionVariant.massAddSelectOption(sSemanticObjectProperty, oSelectOption);
621
+ }
622
+ }
623
+
624
+ return oSelectionVariant;
625
+ }
626
+ /**
627
+ * Navigates to an Outbound provided in the manifest.
628
+ * @function
629
+ * @param {string} sOutbound Identifier to location the outbound in the manifest
630
+ * @param {object} mNavigationParameters Optional map containing key/value pairs to be passed to the intent
631
+ * @alias sap.fe.core.controllerextensions.IntentBasedNavigation#navigateOutbound
632
+ * @since 1.86.0
633
+ **/
634
+ ;
635
+
636
+ _proto.navigateOutbound = function navigateOutbound(sOutbound, mNavigationParameters) {
637
+ var aNavParams;
638
+ var oManifestEntry = this.base.getAppComponent().getManifestEntry("sap.app"),
639
+ oOutbound = oManifestEntry.crossNavigation && oManifestEntry.crossNavigation.outbounds[sOutbound];
640
+
641
+ if (!oOutbound) {
642
+ Log.error("Outbound is not defined in manifest!!");
643
+ return;
644
+ }
645
+
646
+ var sSemanticObject = oOutbound.semanticObject,
647
+ sAction = oOutbound.action,
648
+ outboundParams = oOutbound.parameters && this.getOutboundParams(oOutbound.parameters);
649
+
650
+ if (mNavigationParameters) {
651
+ aNavParams = [];
652
+ Object.keys(mNavigationParameters).forEach(function (key) {
653
+ var oParams;
654
+
655
+ if (Array.isArray(mNavigationParameters[key])) {
656
+ var aValues = mNavigationParameters[key];
657
+
658
+ for (var i = 0; i < aValues.length; i++) {
659
+ var _aNavParams;
660
+
661
+ oParams = {};
662
+ oParams[key] = aValues[i];
663
+ (_aNavParams = aNavParams) === null || _aNavParams === void 0 ? void 0 : _aNavParams.push(oParams);
664
+ }
665
+ } else {
666
+ var _aNavParams2;
667
+
668
+ oParams = {};
669
+ oParams[key] = mNavigationParameters[key];
670
+ (_aNavParams2 = aNavParams) === null || _aNavParams2 === void 0 ? void 0 : _aNavParams2.push(oParams);
671
+ }
672
+ });
673
+ }
674
+
675
+ if (aNavParams || outboundParams) {
676
+ mNavigationParameters = {
677
+ navigationContexts: {
678
+ data: aNavParams || outboundParams
679
+ }
680
+ };
681
+ }
682
+
683
+ this.base._intentBasedNavigation.navigate(sSemanticObject, sAction, mNavigationParameters);
684
+ }
685
+ /**
686
+ * Method to apply outbound parameters defined in the manifest.
687
+ * @param {object} oSelectionVariant SelectionVariant consisting of a filter bar, a table, and a page context
688
+ * @param {object} vOutboundParams Outbound Properties defined in the manifest
689
+ * @returns {object} - The modified SelectionVariant with outbound parameters.
690
+ */
691
+ ;
692
+
693
+ _proto._applyOutboundParams = function _applyOutboundParams(oSelectionVariant, vOutboundParams) {
694
+ var aParameters = Object.keys(vOutboundParams);
695
+ var aSelectProperties = oSelectionVariant.getSelectOptionsPropertyNames();
696
+ aParameters.forEach(function (key) {
697
+ if (!aSelectProperties.includes(key)) {
698
+ oSelectionVariant.addSelectOption(key, "I", "EQ", vOutboundParams[key]);
699
+ }
700
+ });
701
+ return oSelectionVariant;
702
+ }
703
+ /**
704
+ * Method to get the outbound parameters defined in the manifest.
705
+ *
706
+ * @function
707
+ * @param {object} oOutboundParams Parameters defined in the outbounds. Only "plain" is supported
708
+ * @returns {Array} Parameters with the key-Value pair
709
+ **/
710
+ ;
711
+
712
+ _proto.getOutboundParams = function getOutboundParams(oOutboundParams) {
713
+ var oParamsMapping = {};
714
+
715
+ if (oOutboundParams) {
716
+ var aParameters = Object.keys(oOutboundParams) || [];
717
+
718
+ if (aParameters.length > 0) {
719
+ aParameters.forEach(function (key) {
720
+ var oMapping = oOutboundParams[key];
721
+
722
+ if (oMapping.value && oMapping.value.value && oMapping.value.format === "plain") {
723
+ if (!oParamsMapping[key]) {
724
+ oParamsMapping[key] = oMapping.value.value;
725
+ }
726
+ }
727
+ });
728
+ }
729
+ }
730
+
731
+ return oParamsMapping;
732
+ }
733
+ /**
734
+ * Triggers an outbound navigation when a user chooses the chevron.
735
+ *
736
+ * @param {object} oController
737
+ * @param {string} sOutboundTarget Name of the outbound target (needs to be defined in the manifest)
738
+ * @param {sap.ui.model.odata.v4.Context} oContext The context that contains the data for the target app
739
+ * @param {string} sCreatePath Create path when the chevron is created.
740
+ * @returns {Promise} Promise which is resolved once the navigation is triggered
741
+ */
742
+ ;
743
+
744
+ _proto.onChevronPressNavigateOutBound = function onChevronPressNavigateOutBound(oController, sOutboundTarget, oContext, sCreatePath) {
745
+ var oOutbounds = oController.getAppComponent().getRoutingService().getOutbounds();
746
+ var oDisplayOutbound = oOutbounds[sOutboundTarget];
747
+ var additionalNavigationParameters;
748
+
749
+ if (oDisplayOutbound && oDisplayOutbound.semanticObject && oDisplayOutbound.action) {
750
+ var oRefreshStrategies = {
751
+ intents: {}
752
+ };
753
+ var oDefaultRefreshStrategy = {};
754
+ var sMetaPath;
755
+
756
+ if (oContext) {
757
+ if (oContext.isA && oContext.isA("sap.ui.model.odata.v4.Context")) {
758
+ sMetaPath = ModelHelper.getMetaPathForContext(oContext);
759
+ oContext = [oContext];
760
+ } else {
761
+ sMetaPath = ModelHelper.getMetaPathForContext(oContext[0]);
762
+ }
763
+
764
+ oDefaultRefreshStrategy[sMetaPath] = "self";
765
+ oRefreshStrategies["_feDefault"] = oDefaultRefreshStrategy;
766
+ }
767
+
768
+ if (sCreatePath) {
769
+ var sKey = oDisplayOutbound.semanticObject + "-" + oDisplayOutbound.action;
770
+ oRefreshStrategies.intents[sKey] = {};
771
+ oRefreshStrategies.intents[sKey][sCreatePath] = "self";
772
+ }
773
+
774
+ if (oDisplayOutbound && oDisplayOutbound.parameters) {
775
+ var oParams = oDisplayOutbound.parameters && this.getOutboundParams(oDisplayOutbound.parameters);
776
+
777
+ if (Object.keys(oParams).length > 0) {
778
+ additionalNavigationParameters = oParams;
779
+ }
780
+ }
781
+
782
+ oController._intentBasedNavigation.navigate(oDisplayOutbound.semanticObject, oDisplayOutbound.action, {
783
+ navigationContexts: oContext,
784
+ refreshStrategies: oRefreshStrategies,
785
+ additionalNavigationParameters: additionalNavigationParameters
786
+ }); //TODO: check why returning a promise is required
787
+
788
+
789
+ return Promise.resolve();
790
+ } else {
791
+ throw new Error("outbound target " + sOutboundTarget + " not found in cross navigation definition of manifest");
792
+ }
793
+ };
794
+
795
+ return InternalIntentBasedNavigation;
796
+ }(ControllerExtension), (_applyDecoratedDescriptor(_class2.prototype, "onInit", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "onInit"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigate", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "navigate"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "prepareContextForExternalNavigation", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "prepareContextForExternalNavigation"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "prepareFiltersForExternalNavigation", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "prepareFiltersForExternalNavigation"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "getNavigationMode", [Public, _dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "getNavigationMode"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateWithConfirmationDialog", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateWithConfirmationDialog"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "getEntitySet", [Private], Object.getOwnPropertyDescriptor(_class2.prototype, "getEntitySet"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "removeSensitiveData", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "removeSensitiveData"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "navigateOutbound", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "navigateOutbound"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "getOutboundParams", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "getOutboundParams"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "onChevronPressNavigateOutBound", [Public, Final], Object.getOwnPropertyDescriptor(_class2.prototype, "onChevronPressNavigateOutBound"), _class2.prototype)), _class2)) || _class);
797
+ return InternalIntentBasedNavigation;
798
+ }, false);
799
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkludGVybmFsSW50ZW50QmFzZWROYXZpZ2F0aW9uLnRzIl0sIm5hbWVzIjpbIkludGVybmFsSW50ZW50QmFzZWROYXZpZ2F0aW9uIiwiVUk1Q2xhc3MiLCJDb250cm9sbGVyRXh0ZW5zaW9uTWV0YWRhdGEiLCJPdmVycmlkZSIsIkV4dGVuc2libGUiLCJPdmVycmlkZUV4ZWN1dGlvbiIsIkluc3RlYWQiLCJvbkluaXQiLCJfb0FwcENvbXBvbmVudCIsImJhc2UiLCJnZXRBcHBDb21wb25lbnQiLCJfb01ldGFNb2RlbCIsImdldE1vZGVsIiwiZ2V0TWV0YU1vZGVsIiwiX29OYXZpZ2F0aW9uU2VydmljZSIsImdldE5hdmlnYXRpb25TZXJ2aWNlIiwiX29WaWV3IiwiZ2V0VmlldyIsIm5hdmlnYXRlIiwic1NlbWFudGljT2JqZWN0Iiwic0FjdGlvbiIsIm1OYXZpZ2F0aW9uUGFyYW1ldGVycyIsIl9kb05hdmlnYXRlIiwib0NvbnRleHQiLCJ2TmF2aWdhdGlvbkNvbnRleHRzIiwibmF2aWdhdGlvbkNvbnRleHRzIiwiYU5hdmlnYXRpb25Db250ZXh0cyIsIkFycmF5IiwiaXNBcnJheSIsInZTZW1hbnRpY09iamVjdE1hcHBpbmciLCJzZW1hbnRpY09iamVjdE1hcHBpbmciLCJ2T3V0Ym91bmRQYXJhbXMiLCJhZGRpdGlvbmFsTmF2aWdhdGlvblBhcmFtZXRlcnMiLCJvVGFyZ2V0SW5mbyIsInNlbWFudGljT2JqZWN0IiwiYWN0aW9uIiwib1ZpZXciLCJvQ29udHJvbGxlciIsImdldENvbnRyb2xsZXIiLCJzZXRCaW5kaW5nQ29udGV4dCIsImFTZW1hbnRpY0F0dHJpYnV0ZXMiLCJvU2VsZWN0aW9uVmFyaWFudCIsIlNlbGVjdGlvblZhcmlhbnQiLCJsZW5ndGgiLCJtYXAiLCJvTmF2aWdhdGlvbkNvbnRleHQiLCJpc0EiLCJvU2VtYW50aWNBdHRyaWJ1dGVzIiwiZ2V0T2JqZWN0Iiwic01ldGFQYXRoIiwiZ2V0TWV0YVBhdGgiLCJnZXRQYXRoIiwicmVtb3ZlU2Vuc2l0aXZlRGF0YSIsIm9OYXZDb250ZXh0IiwicHJlcGFyZUNvbnRleHRGb3JFeHRlcm5hbE5hdmlnYXRpb24iLCJwcm9wZXJ0aWVzV2l0aG91dENvbmZsaWN0IiwicHVzaCIsInNlbWFudGljQXR0cmlidXRlcyIsImRhdGEiLCJtZXRhUGF0aCIsIm1peEF0dHJpYnV0ZXNBbmRTZWxlY3Rpb25WYXJpYW50IiwidG9KU09OU3RyaW5nIiwib01vZGVsIiwic0VudGl0eVNldCIsImdldEVudGl0eVNldCIsInNDb250ZXh0VXJsIiwiY29uc3RydWN0Q29udGV4dFVybCIsInVuZGVmaW5lZCIsInNldEZpbHRlckNvbnRleHRVcmwiLCJfYXBwbHlPdXRib3VuZFBhcmFtcyIsImludGVudEJhc2VkTmF2aWdhdGlvbiIsImFkYXB0TmF2aWdhdGlvbkNvbnRleHQiLCJfYXBwbHlTZW1hbnRpY09iamVjdE1hcHBpbmdzIiwiX3JlbW92ZVRlY2huaWNhbFBhcmFtZXRlcnMiLCJzTmF2TW9kZSIsIl9pbnRlbnRCYXNlZE5hdmlnYXRpb24iLCJnZXROYXZpZ2F0aW9uTW9kZSIsIm1SZWZyZXNoU3RyYXRlZ2llcyIsInJlZnJlc2hTdHJhdGVnaWVzIiwib0ludGVybmFsTW9kZWwiLCJnZXRWaWV3RGF0YSIsInJlZnJlc2hTdHJhdGVneU9uQXBwUmVzdG9yZSIsIm1WaWV3UmVmcmVzaFN0cmF0ZWdpZXMiLCJtZXJnZU9iamVjdHMiLCJtUmVmcmVzaFN0cmF0ZWd5IiwiS2VlcEFsaXZlSGVscGVyIiwiZ2V0UmVmcmVzaFN0cmF0ZWd5Rm9ySW50ZW50Iiwic2V0UHJvcGVydHkiLCJvbkVycm9yIiwic2FwIiwidWkiLCJyZXF1aXJlIiwiTWVzc2FnZUJveCIsIm9SZXNvdXJjZUJ1bmRsZSIsImdldENvcmUiLCJnZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUiLCJzaG93IiwiZ2V0VGV4dCIsInRpdGxlIiwiRXJyb3IiLCJvQmluZGluZ0NvbnRleHQiLCJnZXRCaW5kaW5nQ29udGV4dCIsIm9NZXRhTW9kZWwiLCJjb252ZXJ0ZXJUeXBlIiwiTW9kZWxIZWxwZXIiLCJpc1N0aWNreVNlc3Npb25TdXBwb3J0ZWQiLCJDb21tb25VdGlscyIsImZuUHJvY2Vzc0RhdGFMb3NzT3JEcmFmdERpc2NhcmRDb25maXJtYXRpb24iLCJiaW5kIiwiRnVuY3Rpb24iLCJwcm90b3R5cGUiLCJvRGlzdGluY3RLZXlzIiwic0NvbnRleHRQYXRoIiwiYU1ldGFQYXRoUGFydHMiLCJzcGxpdCIsImZpbHRlciIsIkJvb2xlYW4iLCJfZmluZERpc3RpbmN0S2V5c0luT2JqZWN0IiwiTG9va1VwT2JqZWN0Iiwic0xvb2tVcE9iamVjdE1ldGFQYXRoIiwic0tleSIsIm9OZXdMb29rVXBPYmplY3QiLCJzTWFpbkVudGl0eVNldE5hbWUiLCJzTWFpbkVudGl0eVR5cGVOYW1lIiwib1Byb3BlcnRpZXNXaXRob3V0Q29uZmxpY3QiLCJzTWFpbkVudGl0eVZhbHVlUGF0aCIsInNDdXJyZW50VmFsdWVQYXRoIiwic0xhc3RWYWx1ZVBhdGgiLCJzRGlzdGluY3RLZXkiLCJhQ29uZmxpY3RpbmdQYXRocyIsInNXaW5uZXJWYWx1ZVBhdGgiLCJpIiwic1BhdGgiLCJzUGF0aEluQ29udGV4dCIsInJlcGxhY2UiLCJzRW50aXR5VHlwZU5hbWUiLCJzVmFsdWUiLCJqb2luIiwiZ2V0UHJvcGVydHkiLCJzUHJvcGVydHkiLCJwcmVwYXJlRmlsdGVyc0ZvckV4dGVybmFsTmF2aWdhdGlvbiIsIm9GaWx0ZXJCYXJDb25kaXRpb25zIiwic1Jvb3RQYXRoIiwiYVBhcmFtZXRlcnMiLCJvRmlsdGVyQ29uZGl0aW9uc1dpdGhvdXRDb25mbGljdCIsInNGdWxsQ29udGV4dFBhdGgiLCJpbmNsdWRlcyIsImFQYXRoUGFydHMiLCJyZXBsYWNlQWxsIiwiZmlsdGVyQ29uZGl0aW9ucyIsImZpbHRlckNvbmRpdGlvbnNXaXRob3V0Q29uZmxpY3QiLCJuYXZpZ2F0ZVdpdGhDb25maXJtYXRpb25EaWFsb2ciLCJub3RBcHBsaWNhYmxlQ29udGV4dHMiLCJvQXBwbGljYWJsZUNvbnRleHREaWFsb2ciLCJvbkNsb3NlIiwiY2xvc2UiLCJvbkNvbnRpbnVlIiwiYXBwbGljYWJsZUNvbnRleHRzIiwiZm5PcGVuQW5kRmlsbERpYWxvZyIsIm9EaWFsb2dDb250ZW50Iiwibk5vdEFwcGxpY2FibGUiLCJhTm90QXBwbGljYWJsZUl0ZW1zIiwib05vdEFwcGxpY2FibGVJdGVtc01vZGVsIiwiSlNPTk1vZGVsIiwib1RvdGFscyIsInRvdGFsIiwibGFiZWwiLCJzZXRNb2RlbCIsIm9wZW4iLCJzRnJhZ21lbnROYW1lIiwib0RpYWxvZ0ZyYWdtZW50IiwiWE1MVGVtcGxhdGVQcm9jZXNzb3IiLCJsb2FkVGVtcGxhdGUiLCJzQ2Fub25pY2FsUGF0aCIsImdldENhbm9uaWNhbFBhdGgiLCJzdWJzdHIiLCJpbmRleE9mIiwiUHJvbWlzZSIsInJlc29sdmUiLCJYTUxQcmVwcm9jZXNzb3IiLCJwcm9jZXNzIiwibmFtZSIsImJpbmRpbmdDb250ZXh0cyIsImVudGl0eVR5cGUiLCJjcmVhdGVCaW5kaW5nQ29udGV4dCIsIm1vZGVscyIsIm1ldGFNb2RlbCIsInRoZW4iLCJvRnJhZ21lbnQiLCJGcmFnbWVudCIsImxvYWQiLCJkZWZpbml0aW9uIiwiY29udHJvbGxlciIsIm9Qb3BvdmVyIiwiYWRkRGVwZW5kZW50IiwiY2F0Y2giLCJMb2ciLCJlcnJvciIsInJlbW92ZVNlbGVjdE9wdGlvbiIsImVudGl0eVNldCIsIm9BdHRyaWJ1dGVzIiwiYVByb3BlcnRpZXMiLCJPYmplY3QiLCJrZXlzIiwiaiIsInNQcm9wIiwiYVByb3BlcnR5QW5ub3RhdGlvbnMiLCJvRmllbGRDb250cm9sIiwiX2lzRmllbGRDb250cm9sUGF0aEluYXBwbGljYWJsZSIsInNGaWVsZENvbnRyb2xQYXRoIiwib0F0dHJpYnV0ZSIsImJJbmFwcGxpY2FibGUiLCJhUGFydHMiLCJoYXNPd25Qcm9wZXJ0eSIsInZNYXBwaW5ncyIsIm9NYXBwaW5ncyIsIkpTT04iLCJwYXJzZSIsInNMb2NhbFByb3BlcnR5Iiwic1NlbWFudGljT2JqZWN0UHJvcGVydHkiLCJnZXRTZWxlY3RPcHRpb24iLCJvU2VsZWN0T3B0aW9uIiwibWFzc0FkZFNlbGVjdE9wdGlvbiIsIm5hdmlnYXRlT3V0Ym91bmQiLCJzT3V0Ym91bmQiLCJhTmF2UGFyYW1zIiwib01hbmlmZXN0RW50cnkiLCJnZXRNYW5pZmVzdEVudHJ5Iiwib091dGJvdW5kIiwiY3Jvc3NOYXZpZ2F0aW9uIiwib3V0Ym91bmRzIiwib3V0Ym91bmRQYXJhbXMiLCJwYXJhbWV0ZXJzIiwiZ2V0T3V0Ym91bmRQYXJhbXMiLCJmb3JFYWNoIiwia2V5Iiwib1BhcmFtcyIsImFWYWx1ZXMiLCJhU2VsZWN0UHJvcGVydGllcyIsImdldFNlbGVjdE9wdGlvbnNQcm9wZXJ0eU5hbWVzIiwiYWRkU2VsZWN0T3B0aW9uIiwib091dGJvdW5kUGFyYW1zIiwib1BhcmFtc01hcHBpbmciLCJvTWFwcGluZyIsInZhbHVlIiwiZm9ybWF0Iiwib25DaGV2cm9uUHJlc3NOYXZpZ2F0ZU91dEJvdW5kIiwic091dGJvdW5kVGFyZ2V0Iiwic0NyZWF0ZVBhdGgiLCJvT3V0Ym91bmRzIiwiZ2V0Um91dGluZ1NlcnZpY2UiLCJnZXRPdXRib3VuZHMiLCJvRGlzcGxheU91dGJvdW5kIiwib1JlZnJlc2hTdHJhdGVnaWVzIiwiaW50ZW50cyIsIm9EZWZhdWx0UmVmcmVzaFN0cmF0ZWd5IiwiZ2V0TWV0YVBhdGhGb3JDb250ZXh0IiwiQ29udHJvbGxlckV4dGVuc2lvbiIsIlB1YmxpYyIsIkZpbmFsIiwiUHJpdmF0ZSJdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7TUFFTUEsNkIsV0FETEMsUUFBUSxDQUFDLGtFQUFELEVBQXFFQywyQkFBckUsQyxVQU9QQyxRQUFRLEUsVUE4WVJDLFVBQVUsQ0FBQ0MsaUJBQWlCLENBQUNDLE9BQW5CLEM7Ozs7Ozs7OztXQTdZWEMsTSxHQURBLGtCQUNTO0FBQ1IsV0FBS0MsY0FBTCxHQUFzQixLQUFLQyxJQUFMLENBQVVDLGVBQVYsRUFBdEI7QUFDQSxXQUFLQyxXQUFMLEdBQW1CLEtBQUtILGNBQUwsQ0FBb0JJLFFBQXBCLEdBQStCQyxZQUEvQixFQUFuQjtBQUNBLFdBQUtDLG1CQUFMLEdBQTJCLEtBQUtOLGNBQUwsQ0FBb0JPLG9CQUFwQixFQUEzQjtBQUNBLFdBQUtDLE1BQUwsR0FBYyxLQUFLUCxJQUFMLENBQVVRLE9BQVYsRUFBZDtBQUNBO0FBRUQ7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O1dBR0NDLFEsR0FGQSxrQkFHQ0MsZUFIRCxFQUlDQyxPQUpELEVBS0NDLHFCQUxELEVBY0U7QUFBQTs7QUFDRCxVQUFNQyxXQUFXLEdBQUcsVUFBQ0MsUUFBRCxFQUFvQjtBQUN2QyxZQUFNQyxtQkFBbUIsR0FBR0gscUJBQXFCLElBQUlBLHFCQUFxQixDQUFDSSxrQkFBM0U7QUFBQSxZQUNDQyxtQkFBbUIsR0FDbEJGLG1CQUFtQixJQUFJLENBQUNHLEtBQUssQ0FBQ0MsT0FBTixDQUFjSixtQkFBZCxDQUF4QixHQUE2RCxDQUFDQSxtQkFBRCxDQUE3RCxHQUFxRkEsbUJBRnZGO0FBQUEsWUFHQ0ssc0JBQXNCLEdBQUdSLHFCQUFxQixJQUFJQSxxQkFBcUIsQ0FBQ1MscUJBSHpFO0FBQUEsWUFJQ0MsZUFBZSxHQUFHVixxQkFBcUIsSUFBSUEscUJBQXFCLENBQUNXLDhCQUpsRTtBQUFBLFlBS0NDLFdBQWdCLEdBQUc7QUFDbEJDLFVBQUFBLGNBQWMsRUFBRWYsZUFERTtBQUVsQmdCLFVBQUFBLE1BQU0sRUFBRWY7QUFGVSxTQUxwQjtBQUFBLFlBU0NnQixLQUFLLEdBQUcsS0FBSSxDQUFDM0IsSUFBTCxDQUFVUSxPQUFWLEVBVFQ7QUFBQSxZQVVDb0IsV0FBVyxHQUFHRCxLQUFLLENBQUNFLGFBQU4sRUFWZjs7QUFZQSxZQUFJZixRQUFKLEVBQWM7QUFDYixVQUFBLEtBQUksQ0FBQ1AsTUFBTCxDQUFZdUIsaUJBQVosQ0FBOEJoQixRQUE5QjtBQUNBOztBQUVELFlBQUlKLGVBQWUsSUFBSUMsT0FBdkIsRUFBZ0M7QUFDL0IsY0FBSW9CLG1CQUEwQixHQUFHLEVBQWpDO0FBQUEsY0FDQ0MsaUJBQWlCLEdBQUcsSUFBSUMsZ0JBQUosRUFEckIsQ0FEK0IsQ0FHL0I7O0FBQ0EsY0FBSWhCLG1CQUFtQixJQUFJQSxtQkFBbUIsQ0FBQ2lCLE1BQS9DLEVBQXVEO0FBQ3REakIsWUFBQUEsbUJBQW1CLENBQUNrQixHQUFwQixDQUF3QixVQUFDQyxrQkFBRCxFQUE2QjtBQUNwRDtBQUNBO0FBQ0Esa0JBQUlBLGtCQUFrQixDQUFDQyxHQUFuQixJQUEwQkQsa0JBQWtCLENBQUNDLEdBQW5CLENBQXVCLCtCQUF2QixDQUE5QixFQUF1RjtBQUN0RjtBQUNBLG9CQUFJQyxtQkFBbUIsR0FBR0Ysa0JBQWtCLENBQUNHLFNBQW5CLEVBQTFCOztBQUNBLG9CQUFNQyxTQUFTLEdBQUcsS0FBSSxDQUFDdEMsV0FBTCxDQUFpQnVDLFdBQWpCLENBQTZCTCxrQkFBa0IsQ0FBQ00sT0FBbkIsRUFBN0IsQ0FBbEIsQ0FIc0YsQ0FJdEY7OztBQUNBSixnQkFBQUEsbUJBQW1CLEdBQUcsS0FBSSxDQUFDSyxtQkFBTCxDQUF5QkwsbUJBQXpCLEVBQThDRSxTQUE5QyxDQUF0Qjs7QUFDQSxvQkFBTUksV0FBVyxHQUFHLEtBQUksQ0FBQ0MsbUNBQUwsQ0FBeUNQLG1CQUF6QyxFQUE4REYsa0JBQTlELENBQXBCOztBQUNBWixnQkFBQUEsV0FBVyxDQUFDLDJCQUFELENBQVgsR0FBMkNvQixXQUFXLENBQUNFLHlCQUF2RDtBQUNBZixnQkFBQUEsbUJBQW1CLENBQUNnQixJQUFwQixDQUF5QkgsV0FBVyxDQUFDSSxrQkFBckM7QUFDQSxlQVRELE1BU08sSUFDTixFQUFFWixrQkFBa0IsSUFBSWxCLEtBQUssQ0FBQ0MsT0FBTixDQUFjaUIsa0JBQWtCLENBQUNhLElBQWpDLENBQXhCLEtBQ0EsT0FBT2Isa0JBQVAsS0FBOEIsUUFGeEIsRUFHTDtBQUNEO0FBQ0FMLGdCQUFBQSxtQkFBbUIsQ0FBQ2dCLElBQXBCLENBQXlCLEtBQUksQ0FBQ0osbUJBQUwsQ0FBeUJQLGtCQUFrQixDQUFDYSxJQUE1QyxFQUFrRGIsa0JBQWtCLENBQUNjLFFBQXJFLENBQXpCO0FBQ0EsZUFOTSxNQU1BLElBQUlkLGtCQUFrQixJQUFJbEIsS0FBSyxDQUFDQyxPQUFOLENBQWNpQixrQkFBa0IsQ0FBQ2EsSUFBakMsQ0FBMUIsRUFBa0U7QUFDeEU7QUFDQTtBQUNBbEIsZ0JBQUFBLG1CQUFtQixHQUFHLEtBQUksQ0FBQ1ksbUJBQUwsQ0FBeUJQLGtCQUFrQixDQUFDYSxJQUE1QyxFQUFrRGIsa0JBQWtCLENBQUNjLFFBQXJFLENBQXRCO0FBQ0E7QUFDRCxhQXZCRDtBQXdCQSxXQTdCOEIsQ0E4Qi9COzs7QUFDQSxjQUFJbkIsbUJBQW1CLElBQUlBLG1CQUFtQixDQUFDRyxNQUEvQyxFQUF1RDtBQUN0REYsWUFBQUEsaUJBQWlCLEdBQUcsS0FBSSxDQUFDM0IsbUJBQUwsQ0FBeUI4QyxnQ0FBekIsQ0FDbkJwQixtQkFEbUIsRUFFbkJDLGlCQUFpQixDQUFDb0IsWUFBbEIsRUFGbUIsQ0FBcEI7QUFJQSxXQXBDOEIsQ0FzQy9COzs7QUFDQSxjQUFNQyxNQUFNLEdBQUcsS0FBSSxDQUFDOUMsTUFBTCxDQUFZSixRQUFaLEVBQWY7QUFBQSxjQUNDbUQsVUFBVSxHQUFHLEtBQUksQ0FBQ0MsWUFBTCxFQURkO0FBQUEsY0FFQ0MsV0FBVyxHQUFHRixVQUFVLEdBQUcsS0FBSSxDQUFDakQsbUJBQUwsQ0FBeUJvRCxtQkFBekIsQ0FBNkNILFVBQTdDLEVBQXlERCxNQUF6RCxDQUFILEdBQXNFSyxTQUYvRjs7QUFHQSxjQUFJRixXQUFKLEVBQWlCO0FBQ2hCeEIsWUFBQUEsaUJBQWlCLENBQUMyQixtQkFBbEIsQ0FBc0NILFdBQXRDO0FBQ0EsV0E1QzhCLENBOEMvQjs7O0FBQ0EsY0FBSWxDLGVBQUosRUFBcUI7QUFDcEIsWUFBQSxLQUFJLENBQUNzQyxvQkFBTCxDQUEwQjVCLGlCQUExQixFQUE2Q1YsZUFBN0M7QUFDQSxXQWpEOEIsQ0FtRC9COzs7QUFDQU0sVUFBQUEsV0FBVyxDQUFDaUMscUJBQVosQ0FBa0NDLHNCQUFsQyxDQUF5RDlCLGlCQUF6RCxFQUE0RVIsV0FBNUUsRUFwRCtCLENBc0QvQjs7QUFDQSxjQUFJSixzQkFBSixFQUE0QjtBQUMzQixZQUFBLEtBQUksQ0FBQzJDLDRCQUFMLENBQWtDL0IsaUJBQWxDLEVBQXFEWixzQkFBckQ7QUFDQSxXQXpEOEIsQ0EyRC9COzs7QUFDQSxVQUFBLEtBQUksQ0FBQzRDLDBCQUFMLENBQWdDaEMsaUJBQWhDLEVBNUQrQixDQThEL0I7OztBQUNBLGNBQU1pQyxRQUFRLEdBQUdyQyxXQUFXLENBQUNzQyxzQkFBWixDQUFtQ0MsaUJBQW5DLEVBQWpCLENBL0QrQixDQWlFL0I7OztBQUNBLGNBQU1DLGtCQUFrQixHQUFJeEQscUJBQXFCLElBQUlBLHFCQUFxQixDQUFDeUQsaUJBQWhELElBQXNFLEVBQWpHO0FBQUEsY0FDQ0MsY0FBYyxHQUFHM0MsS0FBSyxDQUFDeEIsUUFBTixDQUFlLFVBQWYsQ0FEbEI7O0FBRUEsY0FBSW1FLGNBQUosRUFBb0I7QUFDbkIsZ0JBQUksQ0FBQzNDLEtBQUssSUFBS0EsS0FBSyxDQUFDNEMsV0FBTixFQUFYLEVBQXdDQywyQkFBNUMsRUFBeUU7QUFDeEUsa0JBQU1DLHNCQUFzQixHQUFJOUMsS0FBSyxDQUFDNEMsV0FBTixFQUFELENBQTZCQywyQkFBN0IsSUFBNEQsRUFBM0Y7QUFDQUUsY0FBQUEsWUFBWSxDQUFDTixrQkFBRCxFQUFxQkssc0JBQXJCLENBQVo7QUFDQTs7QUFDRCxnQkFBTUUsZ0JBQWdCLEdBQUdDLGVBQWUsQ0FBQ0MsMkJBQWhCLENBQTRDVCxrQkFBNUMsRUFBZ0UxRCxlQUFoRSxFQUFpRkMsT0FBakYsQ0FBekI7O0FBQ0EsZ0JBQUlnRSxnQkFBSixFQUFzQjtBQUNyQkwsY0FBQUEsY0FBYyxDQUFDUSxXQUFmLENBQTJCLDhCQUEzQixFQUEyREgsZ0JBQTNEO0FBQ0E7QUFDRCxXQTdFOEIsQ0ErRS9COzs7QUFDQSxjQUFNSSxPQUFPLEdBQUcsWUFBVztBQUMxQkMsWUFBQUEsR0FBRyxDQUFDQyxFQUFKLENBQU9DLE9BQVAsQ0FBZSxDQUFDLGtCQUFELENBQWYsRUFBcUMsVUFBU0MsVUFBVCxFQUEwQjtBQUM5RCxrQkFBTUMsZUFBZSxHQUFHSixHQUFHLENBQUNDLEVBQUosQ0FBT0ksT0FBUCxHQUFpQkMsd0JBQWpCLENBQTBDLGFBQTFDLENBQXhCO0FBQ0FILGNBQUFBLFVBQVUsQ0FBQ0ksSUFBWCxDQUFnQkgsZUFBZSxDQUFDSSxPQUFoQixDQUF3QiwwQ0FBeEIsQ0FBaEIsRUFBcUY7QUFDcEZDLGdCQUFBQSxLQUFLLEVBQUVMLGVBQWUsQ0FBQ0ksT0FBaEIsQ0FBd0IsaUNBQXhCO0FBRDZFLGVBQXJGO0FBR0EsYUFMRDtBQU1BLFdBUEQ7O0FBUUEsVUFBQSxLQUFJLENBQUNuRixtQkFBTCxDQUF5QkksUUFBekIsQ0FDQ0MsZUFERCxFQUVDQyxPQUZELEVBR0VxQixpQkFBRCxDQUEyQm9CLFlBQTNCLEVBSEQsRUFJQ00sU0FKRCxFQUtDcUIsT0FMRCxFQU1DckIsU0FORCxFQU9DTyxRQVBEO0FBU0EsU0FqR0QsTUFpR087QUFDTixnQkFBTSxJQUFJeUIsS0FBSixDQUFVLHdDQUFWLENBQU47QUFDQTtBQUNELE9BckhEOztBQXNIQSxVQUFNQyxlQUFlLEdBQUcsS0FBSzNGLElBQUwsQ0FBVVEsT0FBVixHQUFvQm9GLGlCQUFwQixFQUF4QjtBQUNBLFVBQU1DLFVBQVUsR0FBR0YsZUFBZSxJQUFLQSxlQUFlLENBQUN4RixRQUFoQixHQUEyQkMsWUFBM0IsRUFBdkM7O0FBQ0EsVUFDRSxLQUFLSSxPQUFMLEdBQWUrRCxXQUFmLEVBQUQsQ0FBc0N1QixhQUF0QyxLQUF3RCxZQUF4RCxJQUNBRCxVQURBLElBRUEsQ0FBQ0UsV0FBVyxDQUFDQyx3QkFBWixDQUFxQ0gsVUFBckMsQ0FIRixFQUlFO0FBQ0RJLFFBQUFBLFdBQVcsQ0FBQ0MsMkNBQVosQ0FDQ3JGLFdBQVcsQ0FBQ3NGLElBQVosQ0FBaUIsSUFBakIsQ0FERCxFQUVDQyxRQUFRLENBQUNDLFNBRlYsRUFHQyxLQUFLckcsSUFBTCxDQUFVUSxPQUFWLEdBQW9Cb0YsaUJBQXBCLEVBSEQsRUFJQyxLQUFLNUYsSUFBTCxDQUFVUSxPQUFWLEdBQW9CcUIsYUFBcEIsRUFKRDtBQU1BLE9BWEQsTUFXTztBQUNOaEIsUUFBQUEsV0FBVztBQUNYO0FBQ0Q7QUFFRDtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztXQUdDZ0MsbUMsR0FGQSw2Q0FFb0NQLG1CQUZwQyxFQUU4RHhCLFFBRjlELEVBRWlGO0FBQ2hGO0FBQ0E7QUFDQSxVQUFNd0YsYUFBa0IsR0FBRyxFQUEzQjtBQUFBLFVBQ0NDLFlBQVksR0FBR3pGLFFBQVEsQ0FBQzRCLE9BQVQsRUFEaEI7QUFBQSxVQUVDbUQsVUFBVSxHQUFHL0UsUUFBUSxDQUFDWCxRQUFULEdBQW9CQyxZQUFwQixFQUZkO0FBQUEsVUFHQ29DLFNBQVMsR0FBR3FELFVBQVUsQ0FBQ3BELFdBQVgsQ0FBdUI4RCxZQUF2QixDQUhiO0FBQUEsVUFJQ0MsY0FBYyxHQUFHaEUsU0FBUyxDQUFDaUUsS0FBVixDQUFnQixHQUFoQixFQUFxQkMsTUFBckIsQ0FBNEJDLE9BQTVCLENBSmxCOztBQU1BLGVBQVNDLHlCQUFULENBQW1DQyxZQUFuQyxFQUFzREMscUJBQXRELEVBQWtGO0FBQ2pGLGFBQUssSUFBTUMsSUFBWCxJQUFtQkYsWUFBbkIsRUFBaUM7QUFDaEM7QUFDQSxjQUFJQSxZQUFZLENBQUNFLElBQUQsQ0FBWixLQUF1QixJQUF2QixJQUErQixPQUFPRixZQUFZLENBQUNFLElBQUQsQ0FBbkIsS0FBOEIsUUFBakUsRUFBMkU7QUFDMUUsZ0JBQUksQ0FBQ1QsYUFBYSxDQUFDUyxJQUFELENBQWxCLEVBQTBCO0FBQ3pCO0FBQ0FULGNBQUFBLGFBQWEsQ0FBQ1MsSUFBRCxDQUFiLEdBQXNCLEVBQXRCO0FBQ0EsYUFKeUUsQ0FLMUU7OztBQUNBVCxZQUFBQSxhQUFhLENBQUNTLElBQUQsQ0FBYixDQUFvQmhFLElBQXBCLENBQXlCK0QscUJBQXpCO0FBQ0EsV0FQRCxNQU9PO0FBQ047QUFDQSxnQkFBTUUsZ0JBQWdCLEdBQUdILFlBQVksQ0FBQ0UsSUFBRCxDQUFyQzs7QUFDQUgsWUFBQUEseUJBQXlCLENBQUNJLGdCQUFELEVBQW1CRixxQkFBcUIsR0FBRyxHQUF4QixHQUE4QkMsSUFBakQsQ0FBekI7QUFDQTtBQUNEO0FBQ0Q7O0FBRURILE1BQUFBLHlCQUF5QixDQUFDdEUsbUJBQUQsRUFBc0JFLFNBQXRCLENBQXpCLENBM0JnRixDQTZCaEY7OztBQUNBLFVBQU15RSxrQkFBa0IsR0FBR1QsY0FBYyxDQUFDLENBQUQsQ0FBekM7QUFBQSxVQUNDVSxtQkFBbUIsR0FBR3JCLFVBQVUsQ0FBQ3RELFNBQVgsQ0FBcUIsTUFBTTBFLGtCQUFOLEdBQTJCLGNBQWhELENBRHZCO0FBQUEsVUFFQ0UsMEJBQStCLEdBQUcsRUFGbkM7QUFHQSxVQUFJQyxvQkFBSixFQUEwQkMsaUJBQTFCLEVBQTZDQyxjQUE3Qzs7QUFDQSxXQUFLLElBQU1DLFlBQVgsSUFBMkJqQixhQUEzQixFQUEwQztBQUN6QyxZQUFNa0IsaUJBQWlCLEdBQUdsQixhQUFhLENBQUNpQixZQUFELENBQXZDO0FBQ0EsWUFBSUUsZ0JBQWdCLFNBQXBCLENBRnlDLENBR3pDO0FBRUE7QUFDQTtBQUNBOztBQUNBLFlBQUlELGlCQUFpQixDQUFDdEYsTUFBbEIsR0FBMkIsQ0FBL0IsRUFBa0M7QUFDakM7QUFDQSxlQUFLLElBQUl3RixDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxJQUFJRixpQkFBaUIsQ0FBQ3RGLE1BQWxCLEdBQTJCLENBQWhELEVBQW1Ed0YsQ0FBQyxFQUFwRCxFQUF3RDtBQUN2RCxnQkFBTUMsS0FBSyxHQUFHSCxpQkFBaUIsQ0FBQ0UsQ0FBRCxDQUEvQjtBQUNBLGdCQUFJRSxjQUFjLEdBQUdELEtBQUssQ0FBQ0UsT0FBTixDQUFjRixLQUFLLEtBQUtuRixTQUFWLEdBQXNCQSxTQUF0QixHQUFrQ0EsU0FBUyxHQUFHLEdBQTVELEVBQWlFLEVBQWpFLENBQXJCO0FBQ0FvRixZQUFBQSxjQUFjLEdBQUcsQ0FBQ0EsY0FBYyxLQUFLLEVBQW5CLEdBQXdCQSxjQUF4QixHQUF5Q0EsY0FBYyxHQUFHLEdBQTNELElBQWtFTCxZQUFuRjtBQUNBLGdCQUFNTyxlQUFlLEdBQUdqQyxVQUFVLENBQUN0RCxTQUFYLENBQXFCb0YsS0FBSyxHQUFHLGNBQTdCLENBQXhCLENBSnVELENBS3ZEO0FBRUE7O0FBQ0EsZ0JBQUlHLGVBQWUsS0FBS1osbUJBQXhCLEVBQTZDO0FBQzVDRSxjQUFBQSxvQkFBb0IsR0FBR1EsY0FBdkI7QUFDQSxhQVZzRCxDQVl2RDs7O0FBQ0EsZ0JBQUlELEtBQUssS0FBS25GLFNBQWQsRUFBeUI7QUFDeEI2RSxjQUFBQSxpQkFBaUIsR0FBR08sY0FBcEI7QUFDQSxhQWZzRCxDQWlCdkQ7OztBQUNBTixZQUFBQSxjQUFjLEdBQUdNLGNBQWpCLENBbEJ1RCxDQW9CdkQ7QUFDQTs7QUFDQXRGLFlBQUFBLG1CQUFtQixDQUNsQixDQUFDRSxTQUFTLEdBQUcsR0FBWixHQUFrQm9GLGNBQW5CLEVBQ0VuQixLQURGLENBQ1EsR0FEUixFQUVFQyxNQUZGLENBRVMsVUFBU3FCLE1BQVQsRUFBeUI7QUFDaEMscUJBQU9BLE1BQU0sSUFBSSxFQUFqQjtBQUNBLGFBSkYsRUFLRUMsSUFMRixDQUtPLEdBTFAsQ0FEa0IsQ0FBbkIsR0FPSWxILFFBQVEsQ0FBQ21ILFdBQVQsQ0FBcUJMLGNBQXJCLENBUEo7QUFRQSxXQWhDZ0MsQ0FpQ2pDOzs7QUFDQUgsVUFBQUEsZ0JBQWdCLEdBQUdMLG9CQUFvQixJQUFJQyxpQkFBeEIsSUFBNkNDLGNBQWhFO0FBQ0FoRixVQUFBQSxtQkFBbUIsQ0FBQ2lGLFlBQUQsQ0FBbkIsR0FBb0N6RyxRQUFRLENBQUNtSCxXQUFULENBQXFCUixnQkFBckIsQ0FBcEM7QUFDQUwsVUFBQUEsb0JBQW9CLEdBQUcxRCxTQUF2QjtBQUNBMkQsVUFBQUEsaUJBQWlCLEdBQUczRCxTQUFwQjtBQUNBNEQsVUFBQUEsY0FBYyxHQUFHNUQsU0FBakI7QUFDQSxTQXZDRCxNQXVDTztBQUNOO0FBQ0EsY0FBTWlFLE1BQUssR0FBR0gsaUJBQWlCLENBQUMsQ0FBRCxDQUEvQixDQUZNLENBRThCOztBQUNwQyxjQUFJSSxlQUFjLEdBQUdELE1BQUssQ0FBQ0UsT0FBTixDQUFjRixNQUFLLEtBQUtuRixTQUFWLEdBQXNCQSxTQUF0QixHQUFrQ0EsU0FBUyxHQUFHLEdBQTVELEVBQWlFLEVBQWpFLENBQXJCOztBQUNBb0YsVUFBQUEsZUFBYyxHQUFHLENBQUNBLGVBQWMsS0FBSyxFQUFuQixHQUF3QkEsZUFBeEIsR0FBeUNBLGVBQWMsR0FBRyxHQUEzRCxJQUFrRUwsWUFBbkY7QUFDQWpGLFVBQUFBLG1CQUFtQixDQUFDaUYsWUFBRCxDQUFuQixHQUFvQ3pHLFFBQVEsQ0FBQ21ILFdBQVQsQ0FBcUJMLGVBQXJCLENBQXBDO0FBQ0FULFVBQUFBLDBCQUEwQixDQUFDSSxZQUFELENBQTFCLEdBQTJDLENBQUMvRSxTQUFTLEdBQUcsR0FBWixHQUFrQm9GLGVBQW5CLEVBQ3pDbkIsS0FEeUMsQ0FDbkMsR0FEbUMsRUFFekNDLE1BRnlDLENBRWxDLFVBQVNxQixNQUFULEVBQXlCO0FBQ2hDLG1CQUFPQSxNQUFNLElBQUksRUFBakI7QUFDQSxXQUp5QyxFQUt6Q0MsSUFMeUMsQ0FLcEMsR0FMb0MsQ0FBM0M7QUFNQTtBQUNELE9BOUYrRSxDQStGaEY7OztBQUNBLFdBQUssSUFBTUUsU0FBWCxJQUF3QjVGLG1CQUF4QixFQUE2QztBQUM1QyxZQUFJQSxtQkFBbUIsQ0FBQzRGLFNBQUQsQ0FBbkIsS0FBbUMsSUFBbkMsSUFBMkMsT0FBTzVGLG1CQUFtQixDQUFDNEYsU0FBRCxDQUExQixLQUEwQyxRQUF6RixFQUFtRztBQUNsRyxpQkFBTzVGLG1CQUFtQixDQUFDNEYsU0FBRCxDQUExQjtBQUNBO0FBQ0Q7O0FBQ0QsYUFBTztBQUNObEYsUUFBQUEsa0JBQWtCLEVBQUVWLG1CQURkO0FBRU5RLFFBQUFBLHlCQUF5QixFQUFFcUU7QUFGckIsT0FBUDtBQUlBO0FBQ0Q7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztXQUdDZ0IsbUMsR0FGQSw2Q0FFb0NDLG9CQUZwQyxFQUUrREMsU0FGL0QsRUFFa0ZDLFdBRmxGLEVBRXVHO0FBQ3RHLFVBQUlYLEtBQUo7QUFDQSxVQUFNckIsYUFBa0IsR0FBRyxFQUEzQjtBQUNBLFVBQU1pQyxnQ0FBcUMsR0FBRyxFQUE5QztBQUNBLFVBQUluQixvQkFBSixFQUEwQkMsaUJBQTFCLEVBQTZDbUIsZ0JBQTdDLEVBQStEZixnQkFBL0QsRUFBaUZHLGNBQWpGOztBQUVBLGVBQVNoQix5QkFBVCxDQUFtQ0MsWUFBbkMsRUFBc0Q7QUFDckQsWUFBSUMscUJBQUo7O0FBQ0EsYUFBSyxJQUFJQyxJQUFULElBQWlCRixZQUFqQixFQUErQjtBQUM5QixjQUFJQSxZQUFZLENBQUNFLElBQUQsQ0FBaEIsRUFBd0I7QUFDdkIsZ0JBQUlBLElBQUksQ0FBQzBCLFFBQUwsQ0FBYyxHQUFkLENBQUosRUFBd0I7QUFDdkIzQixjQUFBQSxxQkFBcUIsR0FBR0MsSUFBeEIsQ0FEdUIsQ0FDTzs7QUFDOUIsa0JBQU0yQixVQUFVLEdBQUczQixJQUFJLENBQUNOLEtBQUwsQ0FBVyxHQUFYLENBQW5CO0FBQ0FNLGNBQUFBLElBQUksR0FBRzJCLFVBQVUsQ0FBQ0EsVUFBVSxDQUFDeEcsTUFBWCxHQUFvQixDQUFyQixDQUFqQjtBQUNBLGFBSkQsTUFJTztBQUNONEUsY0FBQUEscUJBQXFCLEdBQUd1QixTQUF4QjtBQUNBOztBQUNELGdCQUFJLENBQUMvQixhQUFhLENBQUNTLElBQUQsQ0FBbEIsRUFBMEI7QUFDekI7QUFDQVQsY0FBQUEsYUFBYSxDQUFDUyxJQUFELENBQWIsR0FBc0IsRUFBdEI7QUFDQSxhQVhzQixDQWF2Qjs7O0FBQ0FULFlBQUFBLGFBQWEsQ0FBQ1MsSUFBRCxDQUFiLENBQW9CaEUsSUFBcEIsQ0FBeUIrRCxxQkFBekI7QUFDQTtBQUNEO0FBQ0Q7O0FBRURGLE1BQUFBLHlCQUF5QixDQUFDd0Isb0JBQUQsQ0FBekI7O0FBQ0EsV0FBSyxJQUFNYixZQUFYLElBQTJCakIsYUFBM0IsRUFBMEM7QUFDekMsWUFBTWtCLGlCQUFpQixHQUFHbEIsYUFBYSxDQUFDaUIsWUFBRCxDQUF2Qzs7QUFFQSxZQUFJQyxpQkFBaUIsQ0FBQ3RGLE1BQWxCLEdBQTJCLENBQS9CLEVBQWtDO0FBQ2pDO0FBQ0EsZUFBSyxJQUFJd0YsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsSUFBSUYsaUJBQWlCLENBQUN0RixNQUFsQixHQUEyQixDQUFoRCxFQUFtRHdGLENBQUMsRUFBcEQsRUFBd0Q7QUFDdkRDLFlBQUFBLEtBQUssR0FBR0gsaUJBQWlCLENBQUNFLENBQUQsQ0FBekI7O0FBQ0EsZ0JBQUlDLEtBQUssS0FBS1UsU0FBZCxFQUF5QjtBQUN4QkcsY0FBQUEsZ0JBQWdCLEdBQUdILFNBQVMsR0FBRyxHQUFaLEdBQWtCZCxZQUFyQztBQUNBSyxjQUFBQSxjQUFjLEdBQUdMLFlBQWpCO0FBQ0FILGNBQUFBLG9CQUFvQixHQUFHRyxZQUF2Qjs7QUFDQSxrQkFBSWUsV0FBVyxJQUFJQSxXQUFXLENBQUNHLFFBQVosQ0FBcUJsQixZQUFyQixDQUFuQixFQUF1RDtBQUN0RGEsZ0JBQUFBLG9CQUFvQixDQUFDLGdCQUFnQmIsWUFBakIsQ0FBcEIsR0FBcURhLG9CQUFvQixDQUFDYixZQUFELENBQXpFO0FBQ0E7QUFDRCxhQVBELE1BT087QUFDTkssY0FBQUEsY0FBYyxHQUFHRCxLQUFqQjtBQUNBYSxjQUFBQSxnQkFBZ0IsR0FBRyxDQUFFSCxTQUFTLEdBQUcsR0FBWixHQUFrQlYsS0FBcEIsRUFBbUNnQixVQUFuQyxDQUE4QyxLQUE5QyxFQUFxRCxFQUFyRCxDQUFuQjtBQUNBdEIsY0FBQUEsaUJBQWlCLEdBQUdNLEtBQXBCO0FBQ0E7O0FBQ0RTLFlBQUFBLG9CQUFvQixDQUNuQkksZ0JBQWdCLENBQ2QvQixLQURGLENBQ1EsR0FEUixFQUVFQyxNQUZGLENBRVMsVUFBU3FCLE1BQVQsRUFBc0I7QUFDN0IscUJBQU9BLE1BQU0sSUFBSSxFQUFqQjtBQUNBLGFBSkYsRUFLRUMsSUFMRixDQUtPLEdBTFAsQ0FEbUIsQ0FBcEIsR0FPSUksb0JBQW9CLENBQUNSLGNBQUQsQ0FQeEI7QUFRQSxtQkFBT1Esb0JBQW9CLENBQUNULEtBQUQsQ0FBM0I7QUFDQTs7QUFFREYsVUFBQUEsZ0JBQWdCLEdBQUdMLG9CQUFvQixJQUFJQyxpQkFBM0M7QUFDQWUsVUFBQUEsb0JBQW9CLENBQUNiLFlBQUQsQ0FBcEIsR0FBcUNhLG9CQUFvQixDQUFDWCxnQkFBRCxDQUF6RDtBQUNBLFNBN0JELE1BNkJPO0FBQ047QUFDQUUsVUFBQUEsS0FBSyxHQUFHSCxpQkFBaUIsQ0FBQyxDQUFELENBQXpCO0FBQ0FnQixVQUFBQSxnQkFBZ0IsR0FDZmIsS0FBSyxLQUFLVSxTQUFWLEdBQXNCQSxTQUFTLEdBQUcsR0FBWixHQUFrQmQsWUFBeEMsR0FBdUQsQ0FBRWMsU0FBUyxHQUFHLEdBQVosR0FBa0JWLEtBQXBCLEVBQW1DZ0IsVUFBbkMsQ0FBOEMsR0FBOUMsRUFBbUQsRUFBbkQsQ0FEeEQ7QUFFQUosVUFBQUEsZ0NBQWdDLENBQUNoQixZQUFELENBQWhDLEdBQWlEaUIsZ0JBQWdCLENBQy9EL0IsS0FEK0MsQ0FDekMsR0FEeUMsRUFFL0NDLE1BRitDLENBRXhDLFVBQVNxQixNQUFULEVBQXNCO0FBQzdCLG1CQUFPQSxNQUFNLElBQUksRUFBakI7QUFDQSxXQUorQyxFQUsvQ0MsSUFMK0MsQ0FLMUMsR0FMMEMsQ0FBakQ7O0FBTUEsY0FBSU0sV0FBVyxJQUFJQSxXQUFXLENBQUNHLFFBQVosQ0FBcUJsQixZQUFyQixDQUFuQixFQUF1RDtBQUN0RGEsWUFBQUEsb0JBQW9CLENBQUMsZ0JBQWdCYixZQUFqQixDQUFwQixHQUFxRGEsb0JBQW9CLENBQUNiLFlBQUQsQ0FBekU7QUFDQTtBQUNEO0FBQ0Q7O0FBRUQsYUFBTztBQUNOcUIsUUFBQUEsZ0JBQWdCLEVBQUVSLG9CQURaO0FBRU5TLFFBQUFBLCtCQUErQixFQUFFTjtBQUYzQixPQUFQO0FBSUE7QUFFRDtBQUNEO0FBQ0E7QUFDQTtBQUNBOzs7V0FHQ3BFLGlCLEdBRkEsNkJBRW9CO0FBQ25CLGFBQU9ULFNBQVA7QUFDQTtBQUNEO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O1dBR0NvRiw4QixHQUZBLHdDQUdDcEksZUFIRCxFQUlDQyxPQUpELEVBS0NDLHFCQUxELEVBWUU7QUFBQTtBQUFBOztBQUNELFVBQUlBLHFCQUFxQixTQUFyQixJQUFBQSxxQkFBcUIsV0FBckIsSUFBQUEscUJBQXFCLENBQUVtSSxxQkFBdkIsSUFBZ0QsMEJBQUFuSSxxQkFBcUIsQ0FBQ21JLHFCQUF0QixnRkFBNkM3RyxNQUE3QyxLQUF1RCxDQUEzRyxFQUE4RztBQUM3RyxZQUFJOEcsd0JBQUo7QUFDQSxZQUFNcEgsV0FBVyxHQUFHO0FBQ25CcUgsVUFBQUEsT0FBTyxFQUFFLFlBQVc7QUFDbkI7QUFDQUQsWUFBQUEsd0JBQXdCLENBQUNFLEtBQXpCO0FBQ0EsV0FKa0I7QUFLbkJDLFVBQUFBLFVBQVUsRUFBRSxZQUFNO0FBQ2pCO0FBQ0F2SSxZQUFBQSxxQkFBcUIsQ0FBQ0ksa0JBQXRCLEdBQTJDSixxQkFBcUIsQ0FBQ3dJLGtCQUFqRTtBQUNBSixZQUFBQSx3QkFBd0IsQ0FBQ0UsS0FBekI7O0FBQ0EsWUFBQSxNQUFJLENBQUN6SSxRQUFMLENBQWNDLGVBQWQsRUFBK0JDLE9BQS9CLEVBQXdDQyxxQkFBeEM7QUFDQTtBQVZrQixTQUFwQjs7QUFZQSxZQUFNeUksbUJBQW1CLEdBQUcsWUFBVztBQUN0QyxjQUFJQyxjQUFKO0FBQ0EsY0FBTUMsY0FBYyxHQUFHM0kscUJBQXFCLENBQUNtSSxxQkFBdEIsQ0FBNEM3RyxNQUFuRTtBQUFBLGNBQ0NzSCxtQkFBbUIsR0FBRyxFQUR2Qjs7QUFFQSxlQUFLLElBQUk5QixDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHOUcscUJBQXFCLENBQUNtSSxxQkFBdEIsQ0FBNEM3RyxNQUFoRSxFQUF3RXdGLENBQUMsRUFBekUsRUFBNkU7QUFDNUU0QixZQUFBQSxjQUFjLEdBQUcxSSxxQkFBcUIsQ0FBQ21JLHFCQUF0QixDQUE0Q3JCLENBQTVDLEVBQStDbkYsU0FBL0MsRUFBakI7QUFDQWlILFlBQUFBLG1CQUFtQixDQUFDekcsSUFBcEIsQ0FBeUJ1RyxjQUF6QjtBQUNBOztBQUNELGNBQU1HLHdCQUF3QixHQUFHLElBQUlDLFNBQUosQ0FBY0YsbUJBQWQsQ0FBakM7QUFDQSxjQUFNRyxPQUFPLEdBQUcsSUFBSUQsU0FBSixDQUFjO0FBQUVFLFlBQUFBLEtBQUssRUFBRUwsY0FBVDtBQUF5Qk0sWUFBQUEsS0FBSyxFQUFFakoscUJBQXFCLENBQUNpSjtBQUF0RCxXQUFkLENBQWhCO0FBQ0FiLFVBQUFBLHdCQUF3QixDQUFDYyxRQUF6QixDQUFrQ0wsd0JBQWxDLEVBQTRELGVBQTVEO0FBQ0FULFVBQUFBLHdCQUF3QixDQUFDYyxRQUF6QixDQUFrQ0gsT0FBbEMsRUFBMkMsUUFBM0M7QUFDQVgsVUFBQUEsd0JBQXdCLENBQUNlLElBQXpCO0FBQ0EsU0FiRCxDQWQ2RyxDQTRCN0c7OztBQUNBLFlBQU1DLGFBQWEsR0FBRyxvQ0FBdEI7QUFDQSxZQUFNQyxlQUFlLEdBQUdDLG9CQUFvQixDQUFDQyxZQUFyQixDQUFrQ0gsYUFBbEMsRUFBaUQsVUFBakQsQ0FBeEI7O0FBQ0EsWUFBTTNHLE1BQU0sR0FBRyxLQUFLOUMsTUFBTCxDQUFZSixRQUFaLEVBQWY7O0FBQ0EsWUFBTTBGLFVBQVUsR0FBR3hDLE1BQU0sQ0FBQ2pELFlBQVAsRUFBbkI7QUFDQSxZQUFNZ0ssY0FBYyxHQUFHeEoscUJBQXFCLENBQUNtSSxxQkFBdEIsQ0FBNEMsQ0FBNUMsRUFBK0NzQixnQkFBL0MsRUFBdkI7QUFDQSxZQUFNL0csVUFBVSxHQUFHOEcsY0FBYyxDQUFDRSxNQUFmLENBQXNCLENBQXRCLEVBQXlCRixjQUFjLENBQUNHLE9BQWYsQ0FBdUIsR0FBdkIsQ0FBekIsSUFBd0QsR0FBM0U7QUFDQUMsUUFBQUEsT0FBTyxDQUFDQyxPQUFSLENBQ0NDLGVBQWUsQ0FBQ0MsT0FBaEIsQ0FDQ1YsZUFERCxFQUVDO0FBQUVXLFVBQUFBLElBQUksRUFBRVo7QUFBUixTQUZELEVBR0M7QUFDQ2EsVUFBQUEsZUFBZSxFQUFFO0FBQ2hCQyxZQUFBQSxVQUFVLEVBQUVqRixVQUFVLENBQUNrRixvQkFBWCxDQUFnQ3pILFVBQWhDO0FBREksV0FEbEI7QUFJQzBILFVBQUFBLE1BQU0sRUFBRTtBQUNQRixZQUFBQSxVQUFVLEVBQUVqRixVQURMO0FBRVBvRixZQUFBQSxTQUFTLEVBQUVwRjtBQUZKO0FBSlQsU0FIRCxDQURELEVBZUVxRixJQWZGLENBZU8sVUFBU0MsU0FBVCxFQUF5QjtBQUM5QixpQkFBT0MsUUFBUSxDQUFDQyxJQUFULENBQWM7QUFBRUMsWUFBQUEsVUFBVSxFQUFFSCxTQUFkO0FBQXlCSSxZQUFBQSxVQUFVLEVBQUUzSjtBQUFyQyxXQUFkLENBQVA7QUFDQSxTQWpCRixFQWtCRXNKLElBbEJGLENBa0JPLFVBQUNNLFFBQUQsRUFBbUI7QUFDeEJ4QyxVQUFBQSx3QkFBd0IsR0FBR3dDLFFBQTNCOztBQUNBLFVBQUEsTUFBSSxDQUFDaEwsT0FBTCxHQUFlaUwsWUFBZixDQUE0QkQsUUFBNUI7O0FBQ0FuQyxVQUFBQSxtQkFBbUI7QUFDbkIsU0F0QkYsRUF1QkVxQyxLQXZCRixDQXVCUSxZQUFXO0FBQ2pCQyxVQUFBQSxHQUFHLENBQUNDLEtBQUosQ0FBVSxPQUFWO0FBQ0EsU0F6QkY7QUEwQkEsT0E3REQsTUE2RE87QUFDTixhQUFLbkwsUUFBTCxDQUFjQyxlQUFkLEVBQStCQyxPQUEvQixFQUF3Q0MscUJBQXhDO0FBQ0E7QUFDRCxLOztXQUNEb0QsMEIsR0FBQSxvQ0FBMkJoQyxpQkFBM0IsRUFBbUQ7QUFDbERBLE1BQUFBLGlCQUFpQixDQUFDNkosa0JBQWxCLENBQXFDLGdCQUFyQztBQUNBN0osTUFBQUEsaUJBQWlCLENBQUM2SixrQkFBbEIsQ0FBcUMscUJBQXJDO0FBQ0E3SixNQUFBQSxpQkFBaUIsQ0FBQzZKLGtCQUFsQixDQUFxQyxlQUFyQztBQUNBO0FBQ0Q7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztXQUVDdEksWSxHQURBLHdCQUNlO0FBQ2QsYUFBUSxLQUFLaEQsTUFBTCxDQUFZZ0UsV0FBWixFQUFELENBQW1DdUgsU0FBMUM7QUFDQTtBQUNEO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQzs7O1dBR0FuSixtQixHQUZBLDZCQUVvQm9KLFdBRnBCLEVBRXNDdkosU0FGdEMsRUFFeUQ7QUFDeEQsVUFBTXdKLFdBQVcsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVlILFdBQVosQ0FBcEI7O0FBQ0EsVUFBSUMsV0FBVyxDQUFDOUosTUFBaEIsRUFBd0I7QUFDdkIsZUFBTzZKLFdBQVcsQ0FBQyxnQkFBRCxDQUFsQjtBQUNBLGVBQU9BLFdBQVcsQ0FBQyxxQkFBRCxDQUFsQjtBQUNBLGVBQU9BLFdBQVcsQ0FBQyxlQUFELENBQWxCOztBQUNBLGFBQUssSUFBSUksQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0gsV0FBVyxDQUFDOUosTUFBaEMsRUFBd0NpSyxDQUFDLEVBQXpDLEVBQTZDO0FBQzVDLGNBQUlKLFdBQVcsQ0FBQ0MsV0FBVyxDQUFDRyxDQUFELENBQVosQ0FBWCxJQUErQixPQUFPSixXQUFXLENBQUNDLFdBQVcsQ0FBQ0csQ0FBRCxDQUFaLENBQWxCLEtBQXVDLFFBQTFFLEVBQW9GO0FBQ25GLGlCQUFLeEosbUJBQUwsQ0FBeUJvSixXQUFXLENBQUNDLFdBQVcsQ0FBQ0csQ0FBRCxDQUFaLENBQXBDLEVBQXNEM0osU0FBUyxHQUFHLEdBQVosR0FBa0J3SixXQUFXLENBQUNHLENBQUQsQ0FBbkY7QUFDQTs7QUFDRCxjQUFNQyxLQUFLLEdBQUdKLFdBQVcsQ0FBQ0csQ0FBRCxDQUF6QjtBQUFBLGNBQ0NFLG9CQUFvQixHQUFHLEtBQUtuTSxXQUFMLENBQWlCcUMsU0FBakIsQ0FBMkJDLFNBQVMsR0FBRyxHQUFaLEdBQWtCNEosS0FBbEIsR0FBMEIsR0FBckQsQ0FEeEI7O0FBRUEsY0FBSUMsb0JBQUosRUFBMEI7QUFDekIsZ0JBQ0NBLG9CQUFvQixDQUFDLDhEQUFELENBQXBCLElBQ0FBLG9CQUFvQixDQUFDLDBEQUFELENBRHBCLElBRUFBLG9CQUFvQixDQUFDLDRDQUFELENBSHJCLEVBSUU7QUFDRCxxQkFBT04sV0FBVyxDQUFDSyxLQUFELENBQWxCO0FBQ0EsYUFORCxNQU1PLElBQUlDLG9CQUFvQixDQUFDLDhDQUFELENBQXhCLEVBQTBFO0FBQ2hGLGtCQUFNQyxhQUFhLEdBQUdELG9CQUFvQixDQUFDLDhDQUFELENBQTFDOztBQUNBLGtCQUFJQyxhQUFhLENBQUMsYUFBRCxDQUFiLElBQWdDQSxhQUFhLENBQUMsYUFBRCxDQUFiLENBQTZCN0YsS0FBN0IsQ0FBbUMsR0FBbkMsRUFBd0MsQ0FBeEMsTUFBK0MsY0FBbkYsRUFBbUc7QUFDbEcsdUJBQU9zRixXQUFXLENBQUNLLEtBQUQsQ0FBbEI7QUFDQSxlQUZELE1BRU8sSUFBSUUsYUFBYSxDQUFDLE9BQUQsQ0FBYixJQUEwQixLQUFLQywrQkFBTCxDQUFxQ0QsYUFBYSxDQUFDLE9BQUQsQ0FBbEQsRUFBNkRQLFdBQTdELENBQTlCLEVBQXlHO0FBQy9HLHVCQUFPQSxXQUFXLENBQUNLLEtBQUQsQ0FBbEI7QUFDQTtBQUNEO0FBQ0Q7QUFDRDtBQUNEOztBQUNELGFBQU9MLFdBQVA7QUFDQTtBQUVEO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztXQUNDUSwrQixHQUFBLHlDQUFnQ0MsaUJBQWhDLEVBQTJEQyxVQUEzRCxFQUE0RTtBQUMzRSxVQUFJQyxhQUFhLEdBQUcsS0FBcEI7QUFDQSxVQUFNQyxNQUFNLEdBQUdILGlCQUFpQixDQUFDL0YsS0FBbEIsQ0FBd0IsR0FBeEIsQ0FBZixDQUYyRSxDQUczRTs7QUFDQSxVQUFJa0csTUFBTSxDQUFDekssTUFBUCxHQUFnQixDQUFwQixFQUF1QjtBQUN0QndLLFFBQUFBLGFBQWEsR0FDWkQsVUFBVSxDQUFDRSxNQUFNLENBQUMsQ0FBRCxDQUFQLENBQVYsSUFBeUJGLFVBQVUsQ0FBQ0UsTUFBTSxDQUFDLENBQUQsQ0FBUCxDQUFWLENBQXNCQyxjQUF0QixDQUFxQ0QsTUFBTSxDQUFDLENBQUQsQ0FBM0MsQ0FBekIsSUFBNEVGLFVBQVUsQ0FBQ0UsTUFBTSxDQUFDLENBQUQsQ0FBUCxDQUFWLENBQXNCQSxNQUFNLENBQUMsQ0FBRCxDQUE1QixNQUFxQyxDQURsSDtBQUVBLE9BSEQsTUFHTztBQUNORCxRQUFBQSxhQUFhLEdBQUdELFVBQVUsQ0FBQ0QsaUJBQUQsQ0FBVixLQUFrQyxDQUFsRDtBQUNBOztBQUNELGFBQU9FLGFBQVA7QUFDQTtBQUNEO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7V0FDQzNJLDRCLEdBQUEsc0NBQTZCL0IsaUJBQTdCLEVBQWtFNkssU0FBbEUsRUFBOEY7QUFDN0YsVUFBTUMsU0FBUyxHQUFHLE9BQU9ELFNBQVAsS0FBcUIsUUFBckIsR0FBZ0NFLElBQUksQ0FBQ0MsS0FBTCxDQUFXSCxTQUFYLENBQWhDLEdBQXdEQSxTQUExRTs7QUFDQSxXQUFLLElBQUluRixDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHb0YsU0FBUyxDQUFDNUssTUFBOUIsRUFBc0N3RixDQUFDLEVBQXZDLEVBQTJDO0FBQzFDLFlBQU11RixjQUFjLEdBQ2xCSCxTQUFTLENBQUNwRixDQUFELENBQVQsQ0FBYSxlQUFiLEtBQWlDb0YsU0FBUyxDQUFDcEYsQ0FBRCxDQUFULENBQWEsZUFBYixFQUE4QixlQUE5QixDQUFsQyxJQUNDb0YsU0FBUyxDQUFDcEYsQ0FBRCxDQUFULENBQWEsK0NBQWIsS0FDQW9GLFNBQVMsQ0FBQ3BGLENBQUQsQ0FBVCxDQUFhLCtDQUFiLEVBQThELE9BQTlELENBSEY7QUFJQSxZQUFNd0YsdUJBQXVCLEdBQzVCSixTQUFTLENBQUNwRixDQUFELENBQVQsQ0FBYSx3QkFBYixLQUEwQ29GLFNBQVMsQ0FBQ3BGLENBQUQsQ0FBVCxDQUFhLHdEQUFiLENBRDNDOztBQUVBLFlBQUkxRixpQkFBaUIsQ0FBQ21MLGVBQWxCLENBQWtDRixjQUFsQyxDQUFKLEVBQXVEO0FBQ3RELGNBQU1HLGFBQWEsR0FBR3BMLGlCQUFpQixDQUFDbUwsZUFBbEIsQ0FBa0NGLGNBQWxDLENBQXRCLENBRHNELENBR3REOztBQUNBakwsVUFBQUEsaUJBQWlCLENBQUM2SixrQkFBbEIsQ0FBcUNvQixjQUFyQztBQUNBakwsVUFBQUEsaUJBQWlCLENBQUNxTCxtQkFBbEIsQ0FBc0NILHVCQUF0QyxFQUErREUsYUFBL0Q7QUFDQTtBQUNEOztBQUNELGFBQU9wTCxpQkFBUDtBQUNBO0FBQ0Q7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O1dBR0NzTCxnQixHQUZBLDBCQUVpQkMsU0FGakIsRUFFb0MzTSxxQkFGcEMsRUFFZ0U7QUFDL0QsVUFBSTRNLFVBQUo7QUFDQSxVQUFNQyxjQUFjLEdBQUcsS0FBS3pOLElBQUwsQ0FBVUMsZUFBVixHQUE0QnlOLGdCQUE1QixDQUE2QyxTQUE3QyxDQUF2QjtBQUFBLFVBQ0NDLFNBQVMsR0FBR0YsY0FBYyxDQUFDRyxlQUFmLElBQWtDSCxjQUFjLENBQUNHLGVBQWYsQ0FBK0JDLFNBQS9CLENBQXlDTixTQUF6QyxDQUQvQzs7QUFFQSxVQUFJLENBQUNJLFNBQUwsRUFBZ0I7QUFDZmhDLFFBQUFBLEdBQUcsQ0FBQ0MsS0FBSixDQUFVLHVDQUFWO0FBQ0E7QUFDQTs7QUFDRCxVQUFNbEwsZUFBZSxHQUFHaU4sU0FBUyxDQUFDbE0sY0FBbEM7QUFBQSxVQUNDZCxPQUFPLEdBQUdnTixTQUFTLENBQUNqTSxNQURyQjtBQUFBLFVBRUNvTSxjQUFjLEdBQUdILFNBQVMsQ0FBQ0ksVUFBVixJQUF3QixLQUFLQyxpQkFBTCxDQUF1QkwsU0FBUyxDQUFDSSxVQUFqQyxDQUYxQzs7QUFJQSxVQUFJbk4scUJBQUosRUFBMkI7QUFDMUI0TSxRQUFBQSxVQUFVLEdBQUcsRUFBYjtBQUNBdkIsUUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVl0TCxxQkFBWixFQUFtQ3FOLE9BQW5DLENBQTJDLFVBQVNDLEdBQVQsRUFBc0I7QUFDaEUsY0FBSUMsT0FBSjs7QUFDQSxjQUFJak4sS0FBSyxDQUFDQyxPQUFOLENBQWNQLHFCQUFxQixDQUFDc04sR0FBRCxDQUFuQyxDQUFKLEVBQStDO0FBQzlDLGdCQUFNRSxPQUFPLEdBQUd4TixxQkFBcUIsQ0FBQ3NOLEdBQUQsQ0FBckM7O0FBQ0EsaUJBQUssSUFBSXhHLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUcwRyxPQUFPLENBQUNsTSxNQUE1QixFQUFvQ3dGLENBQUMsRUFBckMsRUFBeUM7QUFBQTs7QUFDeEN5RyxjQUFBQSxPQUFPLEdBQUcsRUFBVjtBQUNBQSxjQUFBQSxPQUFPLENBQUNELEdBQUQsQ0FBUCxHQUFlRSxPQUFPLENBQUMxRyxDQUFELENBQXRCO0FBQ0EsNkJBQUE4RixVQUFVLFVBQVYsa0RBQVl6SyxJQUFaLENBQWlCb0wsT0FBakI7QUFDQTtBQUNELFdBUEQsTUFPTztBQUFBOztBQUNOQSxZQUFBQSxPQUFPLEdBQUcsRUFBVjtBQUNBQSxZQUFBQSxPQUFPLENBQUNELEdBQUQsQ0FBUCxHQUFldE4scUJBQXFCLENBQUNzTixHQUFELENBQXBDO0FBQ0EsNEJBQUFWLFVBQVUsVUFBVixvREFBWXpLLElBQVosQ0FBaUJvTCxPQUFqQjtBQUNBO0FBQ0QsU0FkRDtBQWVBOztBQUNELFVBQUlYLFVBQVUsSUFBSU0sY0FBbEIsRUFBa0M7QUFDakNsTixRQUFBQSxxQkFBcUIsR0FBRztBQUN2QkksVUFBQUEsa0JBQWtCLEVBQUU7QUFDbkJpQyxZQUFBQSxJQUFJLEVBQUV1SyxVQUFVLElBQUlNO0FBREQ7QUFERyxTQUF4QjtBQUtBOztBQUNELFdBQUs5TixJQUFMLENBQVVrRSxzQkFBVixDQUFpQ3pELFFBQWpDLENBQTBDQyxlQUExQyxFQUEyREMsT0FBM0QsRUFBb0VDLHFCQUFwRTtBQUNBO0FBRUQ7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7V0FDQ2dELG9CLEdBQUEsOEJBQXFCNUIsaUJBQXJCLEVBQTBEVixlQUExRCxFQUFnRjtBQUMvRSxVQUFNZ0gsV0FBVyxHQUFHMkQsTUFBTSxDQUFDQyxJQUFQLENBQVk1SyxlQUFaLENBQXBCO0FBQ0EsVUFBTStNLGlCQUFpQixHQUFHck0saUJBQWlCLENBQUNzTSw2QkFBbEIsRUFBMUI7QUFDQWhHLE1BQUFBLFdBQVcsQ0FBQzJGLE9BQVosQ0FBb0IsVUFBU0MsR0FBVCxFQUFzQjtBQUN6QyxZQUFJLENBQUNHLGlCQUFpQixDQUFDNUYsUUFBbEIsQ0FBMkJ5RixHQUEzQixDQUFMLEVBQXNDO0FBQ3JDbE0sVUFBQUEsaUJBQWlCLENBQUN1TSxlQUFsQixDQUFrQ0wsR0FBbEMsRUFBdUMsR0FBdkMsRUFBNEMsSUFBNUMsRUFBa0Q1TSxlQUFlLENBQUM0TSxHQUFELENBQWpFO0FBQ0E7QUFDRCxPQUpEO0FBS0EsYUFBT2xNLGlCQUFQO0FBQ0E7QUFDRDtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O1dBR0NnTSxpQixHQUZBLDJCQUVrQlEsZUFGbEIsRUFFd0M7QUFDdkMsVUFBTUMsY0FBbUIsR0FBRyxFQUE1Qjs7QUFDQSxVQUFJRCxlQUFKLEVBQXFCO0FBQ3BCLFlBQU1sRyxXQUFXLEdBQUcyRCxNQUFNLENBQUNDLElBQVAsQ0FBWXNDLGVBQVosS0FBZ0MsRUFBcEQ7O0FBQ0EsWUFBSWxHLFdBQVcsQ0FBQ3BHLE1BQVosR0FBcUIsQ0FBekIsRUFBNEI7QUFDM0JvRyxVQUFBQSxXQUFXLENBQUMyRixPQUFaLENBQW9CLFVBQVNDLEdBQVQsRUFBc0I7QUFDekMsZ0JBQU1RLFFBQVEsR0FBR0YsZUFBZSxDQUFDTixHQUFELENBQWhDOztBQUNBLGdCQUFJUSxRQUFRLENBQUNDLEtBQVQsSUFBa0JELFFBQVEsQ0FBQ0MsS0FBVCxDQUFlQSxLQUFqQyxJQUEwQ0QsUUFBUSxDQUFDQyxLQUFULENBQWVDLE1BQWYsS0FBMEIsT0FBeEUsRUFBaUY7QUFDaEYsa0JBQUksQ0FBQ0gsY0FBYyxDQUFDUCxHQUFELENBQW5CLEVBQTBCO0FBQ3pCTyxnQkFBQUEsY0FBYyxDQUFDUCxHQUFELENBQWQsR0FBc0JRLFFBQVEsQ0FBQ0MsS0FBVCxDQUFlQSxLQUFyQztBQUNBO0FBQ0Q7QUFDRCxXQVBEO0FBUUE7QUFDRDs7QUFDRCxhQUFPRixjQUFQO0FBQ0E7QUFFRDtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztXQUlDSSw4QixHQUZBLHdDQUUrQmpOLFdBRi9CLEVBRTREa04sZUFGNUQsRUFFcUZoTyxRQUZyRixFQUVvR2lPLFdBRnBHLEVBRXlIO0FBQ3hILFVBQU1DLFVBQVUsR0FBSXBOLFdBQVcsQ0FBQzNCLGVBQVosRUFBRCxDQUF1Q2dQLGlCQUF2QyxHQUEyREMsWUFBM0QsRUFBbkI7QUFDQSxVQUFNQyxnQkFBZ0IsR0FBR0gsVUFBVSxDQUFDRixlQUFELENBQW5DO0FBQ0EsVUFBSXZOLDhCQUFKOztBQUNBLFVBQUk0TixnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUMxTixjQUFyQyxJQUF1RDBOLGdCQUFnQixDQUFDek4sTUFBNUUsRUFBb0Y7QUFDbkYsWUFBTTBOLGtCQUF1QixHQUFHO0FBQy9CQyxVQUFBQSxPQUFPLEVBQUU7QUFEc0IsU0FBaEM7QUFHQSxZQUFNQyx1QkFBNEIsR0FBRyxFQUFyQztBQUNBLFlBQUk5TSxTQUFKOztBQUVBLFlBQUkxQixRQUFKLEVBQWM7QUFDYixjQUFJQSxRQUFRLENBQUN1QixHQUFULElBQWdCdkIsUUFBUSxDQUFDdUIsR0FBVCxDQUFhLCtCQUFiLENBQXBCLEVBQW1FO0FBQ2xFRyxZQUFBQSxTQUFTLEdBQUd1RCxXQUFXLENBQUN3SixxQkFBWixDQUFrQ3pPLFFBQWxDLENBQVo7QUFDQUEsWUFBQUEsUUFBUSxHQUFHLENBQUNBLFFBQUQsQ0FBWDtBQUNBLFdBSEQsTUFHTztBQUNOMEIsWUFBQUEsU0FBUyxHQUFHdUQsV0FBVyxDQUFDd0oscUJBQVosQ0FBa0N6TyxRQUFRLENBQUMsQ0FBRCxDQUExQyxDQUFaO0FBQ0E7O0FBQ0R3TyxVQUFBQSx1QkFBdUIsQ0FBQzlNLFNBQUQsQ0FBdkIsR0FBcUMsTUFBckM7QUFDQTRNLFVBQUFBLGtCQUFrQixDQUFDLFlBQUQsQ0FBbEIsR0FBbUNFLHVCQUFuQztBQUNBOztBQUVELFlBQUlQLFdBQUosRUFBaUI7QUFDaEIsY0FBTWhJLElBQUksR0FBR29JLGdCQUFnQixDQUFDMU4sY0FBakIsR0FBa0MsR0FBbEMsR0FBd0MwTixnQkFBZ0IsQ0FBQ3pOLE1BQXRFO0FBQ0EwTixVQUFBQSxrQkFBa0IsQ0FBQ0MsT0FBbkIsQ0FBMkJ0SSxJQUEzQixJQUFtQyxFQUFuQztBQUNBcUksVUFBQUEsa0JBQWtCLENBQUNDLE9BQW5CLENBQTJCdEksSUFBM0IsRUFBaUNnSSxXQUFqQyxJQUFnRCxNQUFoRDtBQUNBOztBQUNELFlBQUlJLGdCQUFnQixJQUFJQSxnQkFBZ0IsQ0FBQ3BCLFVBQXpDLEVBQXFEO0FBQ3BELGNBQU1JLE9BQU8sR0FBR2dCLGdCQUFnQixDQUFDcEIsVUFBakIsSUFBK0IsS0FBS0MsaUJBQUwsQ0FBdUJtQixnQkFBZ0IsQ0FBQ3BCLFVBQXhDLENBQS9DOztBQUNBLGNBQUk5QixNQUFNLENBQUNDLElBQVAsQ0FBWWlDLE9BQVosRUFBcUJqTSxNQUFyQixHQUE4QixDQUFsQyxFQUFxQztBQUNwQ1gsWUFBQUEsOEJBQThCLEdBQUc0TSxPQUFqQztBQUNBO0FBQ0Q7O0FBRUR2TSxRQUFBQSxXQUFXLENBQUNzQyxzQkFBWixDQUFtQ3pELFFBQW5DLENBQTRDME8sZ0JBQWdCLENBQUMxTixjQUE3RCxFQUE2RTBOLGdCQUFnQixDQUFDek4sTUFBOUYsRUFBc0c7QUFDckdWLFVBQUFBLGtCQUFrQixFQUFFRixRQURpRjtBQUVyR3VELFVBQUFBLGlCQUFpQixFQUFFK0ssa0JBRmtGO0FBR3JHN04sVUFBQUEsOEJBQThCLEVBQUVBO0FBSHFFLFNBQXRHLEVBOUJtRixDQW9DbkY7OztBQUNBLGVBQU9pSixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNBLE9BdENELE1Bc0NPO0FBQ04sY0FBTSxJQUFJL0UsS0FBSixDQUFVLHFCQUFxQm9KLGVBQXJCLEdBQXVDLHVEQUFqRCxDQUFOO0FBQ0E7QUFDRCxLOzs7SUE5dkIwQ1UsbUIsZ05Bd0MxQ0MsTSxFQUNBQyxLLDRLQTRKQUQsTSxFQUNBQyxLLHVNQWtIQUQsTSxFQUNBQyxLLHFMQTBGQUQsTSx1TEE2QkFBLE0sRUFDQUMsSywyS0F5RkFDLE8sZ0tBYUFGLE0sRUFDQUMsSyxvS0F3RkFELE0sRUFDQUMsSyxrS0FnRUFELE0sRUFDQUMsSyxnTEE2QkFELE0sRUFDQUMsSztTQWlEYW5RLDZCIiwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29udHJvbGxlckV4dGVuc2lvbiBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL0NvbnRyb2xsZXJFeHRlbnNpb25cIjtcbmltcG9ydCBPdmVycmlkZUV4ZWN1dGlvbiBmcm9tIFwic2FwL3VpL2NvcmUvbXZjL092ZXJyaWRlRXhlY3V0aW9uXCI7XG5pbXBvcnQgU2VsZWN0aW9uVmFyaWFudCBmcm9tIFwic2FwL2ZlL25hdmlnYXRpb24vU2VsZWN0aW9uVmFyaWFudFwiO1xuaW1wb3J0IE1vZGVsSGVscGVyIGZyb20gXCJzYXAvZmUvY29yZS9oZWxwZXJzL01vZGVsSGVscGVyXCI7XG5pbXBvcnQgWE1MUHJlcHJvY2Vzc29yIGZyb20gXCJzYXAvdWkvY29yZS91dGlsL1hNTFByZXByb2Nlc3NvclwiO1xuaW1wb3J0IFhNTFRlbXBsYXRlUHJvY2Vzc29yIGZyb20gXCJzYXAvdWkvY29yZS9YTUxUZW1wbGF0ZVByb2Nlc3NvclwiO1xuaW1wb3J0IEZyYWdtZW50IGZyb20gXCJzYXAvdWkvY29yZS9GcmFnbWVudFwiO1xuaW1wb3J0IEpTT05Nb2RlbCBmcm9tIFwic2FwL3VpL21vZGVsL2pzb24vSlNPTk1vZGVsXCI7XG5pbXBvcnQgTG9nIGZyb20gXCJzYXAvYmFzZS9Mb2dcIjtcbmltcG9ydCBDb21tb25VdGlscyBmcm9tIFwic2FwL2ZlL2NvcmUvQ29tbW9uVXRpbHNcIjtcbmltcG9ydCBLZWVwQWxpdmVIZWxwZXIgZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvS2VlcEFsaXZlSGVscGVyXCI7XG5pbXBvcnQgbWVyZ2VPYmplY3RzIGZyb20gXCJzYXAvYmFzZS91dGlsL21lcmdlXCI7XG5pbXBvcnQgeyBFeHRlbnNpYmxlLCBGaW5hbCwgT3ZlcnJpZGUsIFByaXZhdGUsIFB1YmxpYywgVUk1Q2xhc3MgfSBmcm9tIFwic2FwL2ZlL2NvcmUvaGVscGVycy9DbGFzc1N1cHBvcnRcIjtcbmltcG9ydCBDb250cm9sbGVyRXh0ZW5zaW9uTWV0YWRhdGEgZnJvbSBcInNhcC9mZS9jb3JlL2NvbnRyb2xsZXJleHRlbnNpb25zL0NvbnRyb2xsZXJFeHRlbnNpb25NZXRhZGF0YVwiO1xuaW1wb3J0IEFwcENvbXBvbmVudCBmcm9tIFwic2FwL2ZlL2NvcmUvQXBwQ29tcG9uZW50XCI7XG5pbXBvcnQgT0RhdGFNZXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1ldGFNb2RlbFwiO1xuaW1wb3J0IFZpZXcgZnJvbSBcInNhcC91aS9jb3JlL212Yy9WaWV3XCI7XG5pbXBvcnQgUGFnZUNvbnRyb2xsZXIgZnJvbSBcInNhcC9mZS9jb3JlL1BhZ2VDb250cm9sbGVyXCI7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gXCJzYXAvZmUvY29yZS9zZXJ2aWNlcy9OYXZpZ2F0aW9uU2VydmljZUZhY3RvcnlcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCJzYXAvdWkvbW9kZWwvQ29udGV4dFwiO1xuaW1wb3J0IERpYWxvZyBmcm9tIFwic2FwL20vRGlhbG9nXCI7XG5pbXBvcnQgUmVzb3VyY2VCdW5kbGUgZnJvbSBcInNhcC9iYXNlL2kxOG4vUmVzb3VyY2VCdW5kbGVcIjtcblxuLyoqXG4gKiB7QGxpbmsgc2FwLnVpLmNvcmUubXZjLkNvbnRyb2xsZXJFeHRlbnNpb24gQ29udHJvbGxlciBleHRlbnNpb259XG4gKlxuICogQG5hbWVzcGFjZVxuICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkludGVybmFsSW50ZXJuYWxCYXNlZE5hdmlnYXRpb25cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHNpbmNlIDEuODQuMFxuICovXG5AVUk1Q2xhc3MoXCJzYXAuZmUuY29yZS5jb250cm9sbGVyZXh0ZW5zaW9ucy5JbnRlcm5hbEludGVybmFsQmFzZWROYXZpZ2F0aW9uXCIsIENvbnRyb2xsZXJFeHRlbnNpb25NZXRhZGF0YSlcbmNsYXNzIEludGVybmFsSW50ZW50QmFzZWROYXZpZ2F0aW9uIGV4dGVuZHMgQ29udHJvbGxlckV4dGVuc2lvbiB7XG5cdHByaXZhdGUgYmFzZSE6IFBhZ2VDb250cm9sbGVyO1xuXHRwcml2YXRlIF9vQXBwQ29tcG9uZW50ITogQXBwQ29tcG9uZW50O1xuXHRwcml2YXRlIF9vTWV0YU1vZGVsITogT0RhdGFNZXRhTW9kZWw7XG5cdHByaXZhdGUgX29OYXZpZ2F0aW9uU2VydmljZSE6IE5hdmlnYXRpb25TZXJ2aWNlO1xuXHRwcml2YXRlIF9vVmlldyE6IFZpZXc7XG5cdEBPdmVycmlkZSgpXG5cdG9uSW5pdCgpIHtcblx0XHR0aGlzLl9vQXBwQ29tcG9uZW50ID0gdGhpcy5iYXNlLmdldEFwcENvbXBvbmVudCgpO1xuXHRcdHRoaXMuX29NZXRhTW9kZWwgPSB0aGlzLl9vQXBwQ29tcG9uZW50LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCkgYXMgT0RhdGFNZXRhTW9kZWw7XG5cdFx0dGhpcy5fb05hdmlnYXRpb25TZXJ2aWNlID0gdGhpcy5fb0FwcENvbXBvbmVudC5nZXROYXZpZ2F0aW9uU2VydmljZSgpO1xuXHRcdHRoaXMuX29WaWV3ID0gdGhpcy5iYXNlLmdldFZpZXcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbmFibGVzIGludGVudC1iYXNlZCBuYXZpZ2F0aW9uIChTZW1hbnRpY09iamVjdC1BY3Rpb24pIHdpdGggdGhlIHByb3ZpZGVkIGNvbnRleHQuXG5cdCAqIElmIHNlbWFudGljIG9iamVjdCBtYXBwaW5nIGlzIHByb3ZpZGVkLCB0aGlzIGlzIGFsc28gYXBwbGllZCB0byB0aGUgc2VsZWN0aW9uIHZhcmlhbnQgYWZ0ZXIgdGhlIGFkYXB0YXRpb24gYnkgYSBjb25zdW1lci5cblx0ICogVGhpcyB0YWtlcyBjYXJlIG9mIHJlbW92aW5nIGFueSB0ZWNobmljYWwgcGFyYW1ldGVycyBhbmQgZGV0ZXJtaW5lcyBpZiBhbiBleHBsYWNlIG9yIGlucGxhY2UgbmF2aWdhdGlvbiBzaG91bGQgdGFrZSBwbGFjZS5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNTZW1hbnRpY09iamVjdCBTZW1hbnRpYyBvYmplY3QgZm9yIHRoZSB0YXJnZXQgYXBwXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzQWN0aW9uICBBY3Rpb24gZm9yIHRoZSB0YXJnZXQgYXBwXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbbU5hdmlnYXRpb25QYXJhbWV0ZXJzXSBPcHRpb25hbCBwYXJhbWV0ZXJzIHRvIGJlIHBhc3NlZCB0byB0aGUgZXh0ZXJuYWwgbmF2aWdhdGlvblxuXHQgKiBAcGFyYW0ge0FycmF5fG9iamVjdH0gW21OYXZpZ2F0aW9uUGFyYW1ldGVycy5uYXZpZ2F0aW9uQ29udGV4dHNdIFVzZXMgb25lIG9mIHRoZSBmb2xsb3dpbmcgdG8gYmUgcGFzc2VkIHRvIHRoZSBpbnRlbnQ6XG5cdCAqICAgIGEgc2luZ2xlIGluc3RhbmNlIG9mIHtAbGluayBzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH1cblx0ICogICAgbXVsdGlwbGUgaW5zdGFuY2VzIG9mIHtAbGluayBzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH1cblx0ICogICAgYW4gb2JqZWN0IG9yIGFuIGFycmF5IG9mIG9iamVjdHNcblx0ICpcdFx0ICBJZiBhbiBhcnJheSBvZiBvYmplY3RzIGlzIHBhc3NlZCwgdGhlIGNvbnRleHQgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIG1ldGFQYXRoIGFuZCB0byByZW1vdmUgYW55IHNlbnNpdGl2ZSBkYXRhXG5cdCAqXHRcdCAgSWYgYW4gYXJyYXkgb2Ygb2JqZWN0cyBpcyBwYXNzZWQsIHRoZSBmb2xsb3dpbmcgZm9ybWF0IGl4IGV4cGVjdGVkOlxuXHQgKlx0XHQgIHtcblx0ICpcdFx0XHRkYXRhOiB7XG5cdCAqXHQgXHRcdFx0UHJvZHVjdElEOiA3NjM0LFxuXHQgKlx0XHRcdFx0TmFtZTogXCJMYXB0b3BcIlxuXHQgKlx0XHRcdCB9LFxuXHQgKlx0XHRcdCBtZXRhUGF0aDogXCIvU2FsZXNPcmRlck1hbmFnZVwiXG5cdCAqICAgICAgICB9XG5cdCAqIEBwYXJhbSB7c3RyaW5nIHwgb2JqZWN0fSBbbU5hdmlnYXRpb25QYXJhbWV0ZXJzLnNlbWFudGljT2JqZWN0TWFwcGluZ10gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBTZW1hbnRpY09iamVjdE1hcHBpbmcgb3IgU2VtYW50aWNPYmplY3RNYXBwaW5nIHRoYXQgYXBwbGllcyB0byB0aGlzIG5hdmlnYXRpb25cblx0ICogQHBhcmFtIHtvYmplY3R9IFttTmF2aWdhdGlvblBhcmFtZXRlcnMuZGVmYXVsdFJlZnJlc2hTdHJhdGVneV0gRGVmYXVsdCByZWZyZXNoIHN0cmF0ZWd5IHRvIGJlIHVzZWQgaW4gY2FzZSBubyByZWZyZXNoIHN0cmF0ZWd5IGlzIHNwZWNpZmllZCBmb3IgdGhlIGludGVudCBpbiB0aGUgdmlldy5cblx0ICogQHBhcmFtIHtvYmplY3R9IFttTmF2aWdhdGlvblBhcmFtZXRlcnMucmVmcmVzaFN0cmF0ZWdpZXNdXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbbU5hdmlnYXRpb25QYXJhbWV0ZXJzLmFkZGl0aW9uYWxOYXZpZ2F0aW9uUGFyYW1ldGVyc10gQWRkaXRpb25hbCBuYXZpZ2F0aW9uIHBhcmFtZXRlcnMgY29uZmlndXJlZCBpbiB0aGUgY3Jvc3NBcHBOYXZpZ2F0aW9uIG91dGJvdW5kIHBhcmFtZXRlcnMuXG5cdCAqKi9cblx0QFB1YmxpY1xuXHRARmluYWxcblx0bmF2aWdhdGUoXG5cdFx0c1NlbWFudGljT2JqZWN0OiBzdHJpbmcsXG5cdFx0c0FjdGlvbjogc3RyaW5nLFxuXHRcdG1OYXZpZ2F0aW9uUGFyYW1ldGVyczpcblx0XHRcdHwge1xuXHRcdFx0XHRcdG5hdmlnYXRpb25Db250ZXh0cz86IG9iamVjdCB8IGFueVtdIHwgdW5kZWZpbmVkO1xuXHRcdFx0XHRcdHNlbWFudGljT2JqZWN0TWFwcGluZz86IHN0cmluZyB8IG9iamVjdCB8IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRkZWZhdWx0UmVmcmVzaFN0cmF0ZWd5Pzogb2JqZWN0IHwgdW5kZWZpbmVkO1xuXHRcdFx0XHRcdHJlZnJlc2hTdHJhdGVnaWVzPzogYW55O1xuXHRcdFx0XHRcdGFkZGl0aW9uYWxOYXZpZ2F0aW9uUGFyYW1ldGVycz86IG9iamVjdCB8IHVuZGVmaW5lZDtcblx0XHRcdCAgfVxuXHRcdFx0fCB1bmRlZmluZWRcblx0KSB7XG5cdFx0Y29uc3QgX2RvTmF2aWdhdGUgPSAob0NvbnRleHQ/OiBhbnkpID0+IHtcblx0XHRcdGNvbnN0IHZOYXZpZ2F0aW9uQ29udGV4dHMgPSBtTmF2aWdhdGlvblBhcmFtZXRlcnMgJiYgbU5hdmlnYXRpb25QYXJhbWV0ZXJzLm5hdmlnYXRpb25Db250ZXh0cyxcblx0XHRcdFx0YU5hdmlnYXRpb25Db250ZXh0cyA9XG5cdFx0XHRcdFx0dk5hdmlnYXRpb25Db250ZXh0cyAmJiAhQXJyYXkuaXNBcnJheSh2TmF2aWdhdGlvbkNvbnRleHRzKSA/IFt2TmF2aWdhdGlvbkNvbnRleHRzXSA6IHZOYXZpZ2F0aW9uQ29udGV4dHMsXG5cdFx0XHRcdHZTZW1hbnRpY09iamVjdE1hcHBpbmcgPSBtTmF2aWdhdGlvblBhcmFtZXRlcnMgJiYgbU5hdmlnYXRpb25QYXJhbWV0ZXJzLnNlbWFudGljT2JqZWN0TWFwcGluZyxcblx0XHRcdFx0dk91dGJvdW5kUGFyYW1zID0gbU5hdmlnYXRpb25QYXJhbWV0ZXJzICYmIG1OYXZpZ2F0aW9uUGFyYW1ldGVycy5hZGRpdGlvbmFsTmF2aWdhdGlvblBhcmFtZXRlcnMsXG5cdFx0XHRcdG9UYXJnZXRJbmZvOiBhbnkgPSB7XG5cdFx0XHRcdFx0c2VtYW50aWNPYmplY3Q6IHNTZW1hbnRpY09iamVjdCxcblx0XHRcdFx0XHRhY3Rpb246IHNBY3Rpb25cblx0XHRcdFx0fSxcblx0XHRcdFx0b1ZpZXcgPSB0aGlzLmJhc2UuZ2V0VmlldygpLFxuXHRcdFx0XHRvQ29udHJvbGxlciA9IG9WaWV3LmdldENvbnRyb2xsZXIoKSBhcyBQYWdlQ29udHJvbGxlcjtcblxuXHRcdFx0aWYgKG9Db250ZXh0KSB7XG5cdFx0XHRcdHRoaXMuX29WaWV3LnNldEJpbmRpbmdDb250ZXh0KG9Db250ZXh0KTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHNTZW1hbnRpY09iamVjdCAmJiBzQWN0aW9uKSB7XG5cdFx0XHRcdGxldCBhU2VtYW50aWNBdHRyaWJ1dGVzOiBhbnlbXSA9IFtdLFxuXHRcdFx0XHRcdG9TZWxlY3Rpb25WYXJpYW50ID0gbmV3IFNlbGVjdGlvblZhcmlhbnQoKTtcblx0XHRcdFx0Ly8gMS4gZ2V0IFNlbWFudGljQXR0cmlidXRlcyBmb3IgbmF2aWdhdGlvblxuXHRcdFx0XHRpZiAoYU5hdmlnYXRpb25Db250ZXh0cyAmJiBhTmF2aWdhdGlvbkNvbnRleHRzLmxlbmd0aCkge1xuXHRcdFx0XHRcdGFOYXZpZ2F0aW9uQ29udGV4dHMubWFwKChvTmF2aWdhdGlvbkNvbnRleHQ6IGFueSkgPT4ge1xuXHRcdFx0XHRcdFx0Ly8gMS4xLmEgaWYgbmF2aWdhdGlvbiBjb250ZXh0IGlzIGluc3RhbmNlIG9mIHNhcC51aS5tb2RlLm9kYXRhLnY0LkNvbnRleHRcblx0XHRcdFx0XHRcdC8vIGVsc2UgY2hlY2sgaWYgbmF2aWdhdGlvbiBjb250ZXh0IGlzIG9mIHR5cGUgb2JqZWN0XG5cdFx0XHRcdFx0XHRpZiAob05hdmlnYXRpb25Db250ZXh0LmlzQSAmJiBvTmF2aWdhdGlvbkNvbnRleHQuaXNBKFwic2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHRcIikpIHtcblx0XHRcdFx0XHRcdFx0Ly8gMS4xLmIgcmVtb3ZlIHNlbnNpdGl2ZSBkYXRhXG5cdFx0XHRcdFx0XHRcdGxldCBvU2VtYW50aWNBdHRyaWJ1dGVzID0gb05hdmlnYXRpb25Db250ZXh0LmdldE9iamVjdCgpO1xuXHRcdFx0XHRcdFx0XHRjb25zdCBzTWV0YVBhdGggPSB0aGlzLl9vTWV0YU1vZGVsLmdldE1ldGFQYXRoKG9OYXZpZ2F0aW9uQ29udGV4dC5nZXRQYXRoKCkpO1xuXHRcdFx0XHRcdFx0XHQvLyBUT0RPOiBhbHNvIHJlbW92ZSBzZW5zaXRpdmUgZGF0YSBmcm9tICBuYXZpZ2F0aW9uIHByb3BlcnRpZXNcblx0XHRcdFx0XHRcdFx0b1NlbWFudGljQXR0cmlidXRlcyA9IHRoaXMucmVtb3ZlU2Vuc2l0aXZlRGF0YShvU2VtYW50aWNBdHRyaWJ1dGVzLCBzTWV0YVBhdGgpO1xuXHRcdFx0XHRcdFx0XHRjb25zdCBvTmF2Q29udGV4dCA9IHRoaXMucHJlcGFyZUNvbnRleHRGb3JFeHRlcm5hbE5hdmlnYXRpb24ob1NlbWFudGljQXR0cmlidXRlcywgb05hdmlnYXRpb25Db250ZXh0KTtcblx0XHRcdFx0XHRcdFx0b1RhcmdldEluZm9bXCJwcm9wZXJ0aWVzV2l0aG91dENvbmZsaWN0XCJdID0gb05hdkNvbnRleHQucHJvcGVydGllc1dpdGhvdXRDb25mbGljdDtcblx0XHRcdFx0XHRcdFx0YVNlbWFudGljQXR0cmlidXRlcy5wdXNoKG9OYXZDb250ZXh0LnNlbWFudGljQXR0cmlidXRlcyk7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0XHRcdFx0XHQhKG9OYXZpZ2F0aW9uQ29udGV4dCAmJiBBcnJheS5pc0FycmF5KG9OYXZpZ2F0aW9uQ29udGV4dC5kYXRhKSkgJiZcblx0XHRcdFx0XHRcdFx0dHlwZW9mIG9OYXZpZ2F0aW9uQ29udGV4dCA9PT0gXCJvYmplY3RcIlxuXHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdC8vIDEuMS5iIHJlbW92ZSBzZW5zaXRpdmUgZGF0YSBmcm9tIG9iamVjdFxuXHRcdFx0XHRcdFx0XHRhU2VtYW50aWNBdHRyaWJ1dGVzLnB1c2godGhpcy5yZW1vdmVTZW5zaXRpdmVEYXRhKG9OYXZpZ2F0aW9uQ29udGV4dC5kYXRhLCBvTmF2aWdhdGlvbkNvbnRleHQubWV0YVBhdGgpKTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAob05hdmlnYXRpb25Db250ZXh0ICYmIEFycmF5LmlzQXJyYXkob05hdmlnYXRpb25Db250ZXh0LmRhdGEpKSB7XG5cdFx0XHRcdFx0XHRcdC8vIG9OYXZpZ2F0aW9uQ29udGV4dC5kYXRhIGNhbiBiZSBhcnJheSBhbHJlYWR5IGV4IDogW3tDdXN0b21lcjogXCIxMDAwMVwifSwge0N1c3RvbWVyOiBcIjEwMDkxXCJ9XVxuXHRcdFx0XHRcdFx0XHQvLyBoZW5jZSBhc3NpZ25pbmcgaXQgdG8gdGhlIGFTZW1hbnRpY0F0dHJpYnV0ZXNcblx0XHRcdFx0XHRcdFx0YVNlbWFudGljQXR0cmlidXRlcyA9IHRoaXMucmVtb3ZlU2Vuc2l0aXZlRGF0YShvTmF2aWdhdGlvbkNvbnRleHQuZGF0YSwgb05hdmlnYXRpb25Db250ZXh0Lm1ldGFQYXRoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyAyLjEgTWVyZ2UgYmFzZSBzZWxlY3Rpb24gdmFyaWFudCBhbmQgc2FuaXRpemVkIHNlbWFudGljIGF0dHJpYnV0ZXMgaW50byBvbmUgU2VsZWN0aW9uVmFyaWFudFxuXHRcdFx0XHRpZiAoYVNlbWFudGljQXR0cmlidXRlcyAmJiBhU2VtYW50aWNBdHRyaWJ1dGVzLmxlbmd0aCkge1xuXHRcdFx0XHRcdG9TZWxlY3Rpb25WYXJpYW50ID0gdGhpcy5fb05hdmlnYXRpb25TZXJ2aWNlLm1peEF0dHJpYnV0ZXNBbmRTZWxlY3Rpb25WYXJpYW50KFxuXHRcdFx0XHRcdFx0YVNlbWFudGljQXR0cmlidXRlcyxcblx0XHRcdFx0XHRcdG9TZWxlY3Rpb25WYXJpYW50LnRvSlNPTlN0cmluZygpXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIDMuIEFkZCBmaWx0ZXJDb250ZXh0VXJsIHRvIFNWIHNvIHRoZSBOYXZpZ2F0aW9uSGFuZGxlciBjYW4gcmVtb3ZlIGFueSBzZW5zaXRpdmUgZGF0YSBiYXNlZCBvbiB2aWV3IGVudGl0eVNldFxuXHRcdFx0XHRjb25zdCBvTW9kZWwgPSB0aGlzLl9vVmlldy5nZXRNb2RlbCgpLFxuXHRcdFx0XHRcdHNFbnRpdHlTZXQgPSB0aGlzLmdldEVudGl0eVNldCgpLFxuXHRcdFx0XHRcdHNDb250ZXh0VXJsID0gc0VudGl0eVNldCA/IHRoaXMuX29OYXZpZ2F0aW9uU2VydmljZS5jb25zdHJ1Y3RDb250ZXh0VXJsKHNFbnRpdHlTZXQsIG9Nb2RlbCkgOiB1bmRlZmluZWQ7XG5cdFx0XHRcdGlmIChzQ29udGV4dFVybCkge1xuXHRcdFx0XHRcdG9TZWxlY3Rpb25WYXJpYW50LnNldEZpbHRlckNvbnRleHRVcmwoc0NvbnRleHRVcmwpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXBwbHkgT3V0Ym91bmQgUGFyYW1ldGVycyB0byB0aGUgU1Zcblx0XHRcdFx0aWYgKHZPdXRib3VuZFBhcmFtcykge1xuXHRcdFx0XHRcdHRoaXMuX2FwcGx5T3V0Ym91bmRQYXJhbXMob1NlbGVjdGlvblZhcmlhbnQsIHZPdXRib3VuZFBhcmFtcyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyA0LiBnaXZlIGFuIG9wcG9ydHVuaXR5IGZvciB0aGUgYXBwbGljYXRpb24gdG8gaW5mbHVlbmNlIHRoZSBTZWxlY3Rpb25WYXJpYW50XG5cdFx0XHRcdG9Db250cm9sbGVyLmludGVudEJhc2VkTmF2aWdhdGlvbi5hZGFwdE5hdmlnYXRpb25Db250ZXh0KG9TZWxlY3Rpb25WYXJpYW50LCBvVGFyZ2V0SW5mbyk7XG5cblx0XHRcdFx0Ly8gNS4gQXBwbHkgc2VtYW50aWMgb2JqZWN0IG1hcHBpbmdzIHRvIHRoZSBTVlxuXHRcdFx0XHRpZiAodlNlbWFudGljT2JqZWN0TWFwcGluZykge1xuXHRcdFx0XHRcdHRoaXMuX2FwcGx5U2VtYW50aWNPYmplY3RNYXBwaW5ncyhvU2VsZWN0aW9uVmFyaWFudCwgdlNlbWFudGljT2JqZWN0TWFwcGluZyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyA2LiByZW1vdmUgdGVjaG5pY2FsIHBhcmFtZXRlcnMgZnJvbSBTZWxlY3Rpb24gVmFyaWFudFxuXHRcdFx0XHR0aGlzLl9yZW1vdmVUZWNobmljYWxQYXJhbWV0ZXJzKG9TZWxlY3Rpb25WYXJpYW50KTtcblxuXHRcdFx0XHQvLyA3LiBjaGVjayBpZiBwcm9ncmFtbWluZyBtb2RlbCBpcyBzdGlja3kgYW5kIHBhZ2UgaXMgZWRpdGFibGVcblx0XHRcdFx0Y29uc3Qgc05hdk1vZGUgPSBvQ29udHJvbGxlci5faW50ZW50QmFzZWROYXZpZ2F0aW9uLmdldE5hdmlnYXRpb25Nb2RlKCk7XG5cblx0XHRcdFx0Ly8gOC4gVXBkYXRpbmcgcmVmcmVzaCBzdHJhdGVneSBpbiBpbnRlcm5hbCBtb2RlbFxuXHRcdFx0XHRjb25zdCBtUmVmcmVzaFN0cmF0ZWdpZXMgPSAobU5hdmlnYXRpb25QYXJhbWV0ZXJzICYmIG1OYXZpZ2F0aW9uUGFyYW1ldGVycy5yZWZyZXNoU3RyYXRlZ2llcykgfHwge30sXG5cdFx0XHRcdFx0b0ludGVybmFsTW9kZWwgPSBvVmlldy5nZXRNb2RlbChcImludGVybmFsXCIpIGFzIEpTT05Nb2RlbDtcblx0XHRcdFx0aWYgKG9JbnRlcm5hbE1vZGVsKSB7XG5cdFx0XHRcdFx0aWYgKChvVmlldyAmJiAob1ZpZXcuZ2V0Vmlld0RhdGEoKSBhcyBhbnkpKS5yZWZyZXNoU3RyYXRlZ3lPbkFwcFJlc3RvcmUpIHtcblx0XHRcdFx0XHRcdGNvbnN0IG1WaWV3UmVmcmVzaFN0cmF0ZWdpZXMgPSAob1ZpZXcuZ2V0Vmlld0RhdGEoKSBhcyBhbnkpLnJlZnJlc2hTdHJhdGVneU9uQXBwUmVzdG9yZSB8fCB7fTtcblx0XHRcdFx0XHRcdG1lcmdlT2JqZWN0cyhtUmVmcmVzaFN0cmF0ZWdpZXMsIG1WaWV3UmVmcmVzaFN0cmF0ZWdpZXMpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCBtUmVmcmVzaFN0cmF0ZWd5ID0gS2VlcEFsaXZlSGVscGVyLmdldFJlZnJlc2hTdHJhdGVneUZvckludGVudChtUmVmcmVzaFN0cmF0ZWdpZXMsIHNTZW1hbnRpY09iamVjdCwgc0FjdGlvbik7XG5cdFx0XHRcdFx0aWYgKG1SZWZyZXNoU3RyYXRlZ3kpIHtcblx0XHRcdFx0XHRcdG9JbnRlcm5hbE1vZGVsLnNldFByb3BlcnR5KFwiL3JlZnJlc2hTdHJhdGVneU9uQXBwUmVzdG9yZVwiLCBtUmVmcmVzaFN0cmF0ZWd5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyA5LiBOYXZpZ2F0ZSB2aWEgTmF2aWdhdGlvbkhhbmRsZXJcblx0XHRcdFx0Y29uc3Qgb25FcnJvciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHNhcC51aS5yZXF1aXJlKFtcInNhcC9tL01lc3NhZ2VCb3hcIl0sIGZ1bmN0aW9uKE1lc3NhZ2VCb3g6IGFueSkge1xuXHRcdFx0XHRcdFx0Y29uc3Qgb1Jlc291cmNlQnVuZGxlID0gc2FwLnVpLmdldENvcmUoKS5nZXRMaWJyYXJ5UmVzb3VyY2VCdW5kbGUoXCJzYXAuZmUuY29yZVwiKSBhcyBSZXNvdXJjZUJ1bmRsZTtcblx0XHRcdFx0XHRcdE1lc3NhZ2VCb3guc2hvdyhvUmVzb3VyY2VCdW5kbGUuZ2V0VGV4dChcIkNfQ09NTU9OX0hFTFBFUl9OQVZJR0FUSU9OX0VSUk9SX01FU1NBR0VcIiksIHtcblx0XHRcdFx0XHRcdFx0dGl0bGU6IG9SZXNvdXJjZUJ1bmRsZS5nZXRUZXh0KFwiQ19DT01NT05fTkFWSUdBVElPTl9FUlJPUl9USVRMRVwiKVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdHRoaXMuX29OYXZpZ2F0aW9uU2VydmljZS5uYXZpZ2F0ZShcblx0XHRcdFx0XHRzU2VtYW50aWNPYmplY3QsXG5cdFx0XHRcdFx0c0FjdGlvbixcblx0XHRcdFx0XHQob1NlbGVjdGlvblZhcmlhbnQgYXMgYW55KS50b0pTT05TdHJpbmcoKSxcblx0XHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdFx0b25FcnJvcixcblx0XHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdFx0c05hdk1vZGVcblx0XHRcdFx0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRocm93IG5ldyBFcnJvcihcIlNlbWFudGljIE9iamVjdC9hY3Rpb24gaXMgbm90IHByb3ZpZGVkXCIpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0Y29uc3Qgb0JpbmRpbmdDb250ZXh0ID0gdGhpcy5iYXNlLmdldFZpZXcoKS5nZXRCaW5kaW5nQ29udGV4dCgpO1xuXHRcdGNvbnN0IG9NZXRhTW9kZWwgPSBvQmluZGluZ0NvbnRleHQgJiYgKG9CaW5kaW5nQ29udGV4dC5nZXRNb2RlbCgpLmdldE1ldGFNb2RlbCgpIGFzIE9EYXRhTWV0YU1vZGVsKTtcblx0XHRpZiAoXG5cdFx0XHQodGhpcy5nZXRWaWV3KCkuZ2V0Vmlld0RhdGEoKSBhcyBhbnkpLmNvbnZlcnRlclR5cGUgPT09IFwiT2JqZWN0UGFnZVwiICYmXG5cdFx0XHRvTWV0YU1vZGVsICYmXG5cdFx0XHQhTW9kZWxIZWxwZXIuaXNTdGlja3lTZXNzaW9uU3VwcG9ydGVkKG9NZXRhTW9kZWwpXG5cdFx0KSB7XG5cdFx0XHRDb21tb25VdGlscy5mblByb2Nlc3NEYXRhTG9zc09yRHJhZnREaXNjYXJkQ29uZmlybWF0aW9uKFxuXHRcdFx0XHRfZG9OYXZpZ2F0ZS5iaW5kKHRoaXMpLFxuXHRcdFx0XHRGdW5jdGlvbi5wcm90b3R5cGUsXG5cdFx0XHRcdHRoaXMuYmFzZS5nZXRWaWV3KCkuZ2V0QmluZGluZ0NvbnRleHQoKSxcblx0XHRcdFx0dGhpcy5iYXNlLmdldFZpZXcoKS5nZXRDb250cm9sbGVyKClcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdF9kb05hdmlnYXRlKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFByZXBhcmUgYXR0cmlidXRlcyB0byBiZSBwYXNzZWQgdG8gZXh0ZXJuYWwgbmF2aWdhdGlvbi5cblx0ICogQHBhcmFtIHtvYmplY3R9IG9TZW1hbnRpY0F0dHJpYnV0ZXMgQ29udGV4dCBkYXRhIGFmdGVyIHJlbW92aW5nIGFsbCBzZW5zaXRpdmUgaW5mb3JtYXRpb24uXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvQ29udGV4dCBBY3R1YWwgY29udGV4dCBmcm9tIHdoaWNoIHRoZSBzZW1hbnRpY0F0dHJpYnV0ZXMgd2VyZSBkZXJpdmVkLlxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fSBPYmplY3Qgb2YgcHJlcGFyZWQgYXR0cmlidXRlcyBmb3IgZXh0ZXJuYWwgbmF2aWdhdGlvbiBhbmQgbm8gY29uZmxpY3QgcHJvcGVydGllcy5cblx0ICovXG5cdEBQdWJsaWNcblx0QEZpbmFsXG5cdHByZXBhcmVDb250ZXh0Rm9yRXh0ZXJuYWxOYXZpZ2F0aW9uKG9TZW1hbnRpY0F0dHJpYnV0ZXM6IGFueSwgb0NvbnRleHQ6IENvbnRleHQpIHtcblx0XHQvLyAxLiBGaW5kIGFsbCBkaXN0aW5jdCBrZXlzIGluIHRoZSBvYmplY3QgU2VtYW50aWNBdHRyaWJ1dGVzXG5cdFx0Ly8gU3RvcmUgbWV0YSBwYXRoIGZvciBlYWNoIG9jY3VyZW5jZSBvZiB0aGUga2V5XG5cdFx0Y29uc3Qgb0Rpc3RpbmN0S2V5czogYW55ID0ge30sXG5cdFx0XHRzQ29udGV4dFBhdGggPSBvQ29udGV4dC5nZXRQYXRoKCksXG5cdFx0XHRvTWV0YU1vZGVsID0gb0NvbnRleHQuZ2V0TW9kZWwoKS5nZXRNZXRhTW9kZWwoKSBhcyBPRGF0YU1ldGFNb2RlbCxcblx0XHRcdHNNZXRhUGF0aCA9IG9NZXRhTW9kZWwuZ2V0TWV0YVBhdGgoc0NvbnRleHRQYXRoKSxcblx0XHRcdGFNZXRhUGF0aFBhcnRzID0gc01ldGFQYXRoLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG5cblx0XHRmdW5jdGlvbiBfZmluZERpc3RpbmN0S2V5c0luT2JqZWN0KExvb2tVcE9iamVjdDogYW55LCBzTG9va1VwT2JqZWN0TWV0YVBhdGg6IGFueSkge1xuXHRcdFx0Zm9yIChjb25zdCBzS2V5IGluIExvb2tVcE9iamVjdCkge1xuXHRcdFx0XHQvLyBudWxsIGNhc2U/P1xuXHRcdFx0XHRpZiAoTG9va1VwT2JqZWN0W3NLZXldID09PSBudWxsIHx8IHR5cGVvZiBMb29rVXBPYmplY3Rbc0tleV0gIT09IFwib2JqZWN0XCIpIHtcblx0XHRcdFx0XHRpZiAoIW9EaXN0aW5jdEtleXNbc0tleV0pIHtcblx0XHRcdFx0XHRcdC8vIGlmIGtleSBpcyBmb3VuZCBmb3IgdGhlIGZpcnN0IHRpbWUgdGhlbiBjcmVhdGUgYXJyYXlcblx0XHRcdFx0XHRcdG9EaXN0aW5jdEtleXNbc0tleV0gPSBbXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gcHVzaCBwYXRoIHRvIGFycmF5XG5cdFx0XHRcdFx0b0Rpc3RpbmN0S2V5c1tzS2V5XS5wdXNoKHNMb29rVXBPYmplY3RNZXRhUGF0aCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gaWYgYSBuZXN0ZWQgb2JqZWN0IGlzIGZvdW5kXG5cdFx0XHRcdFx0Y29uc3Qgb05ld0xvb2tVcE9iamVjdCA9IExvb2tVcE9iamVjdFtzS2V5XTtcblx0XHRcdFx0XHRfZmluZERpc3RpbmN0S2V5c0luT2JqZWN0KG9OZXdMb29rVXBPYmplY3QsIHNMb29rVXBPYmplY3RNZXRhUGF0aCArIFwiL1wiICsgc0tleSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRfZmluZERpc3RpbmN0S2V5c0luT2JqZWN0KG9TZW1hbnRpY0F0dHJpYnV0ZXMsIHNNZXRhUGF0aCk7XG5cblx0XHQvLyAyLiBEZXRlcm1pbmUgZGlzdGluY3Qga2V5IHZhbHVlIGFuZCBhZGQgY29uZmxpY3RlZCBwYXRocyB0byBzZW1hbnRpYyBhdHRyaWJ1dGVzXG5cdFx0Y29uc3Qgc01haW5FbnRpdHlTZXROYW1lID0gYU1ldGFQYXRoUGFydHNbMF0sXG5cdFx0XHRzTWFpbkVudGl0eVR5cGVOYW1lID0gb01ldGFNb2RlbC5nZXRPYmplY3QoXCIvXCIgKyBzTWFpbkVudGl0eVNldE5hbWUgKyBcIi9Ac2FwdWkubmFtZVwiKSxcblx0XHRcdG9Qcm9wZXJ0aWVzV2l0aG91dENvbmZsaWN0OiBhbnkgPSB7fTtcblx0XHRsZXQgc01haW5FbnRpdHlWYWx1ZVBhdGgsIHNDdXJyZW50VmFsdWVQYXRoLCBzTGFzdFZhbHVlUGF0aDtcblx0XHRmb3IgKGNvbnN0IHNEaXN0aW5jdEtleSBpbiBvRGlzdGluY3RLZXlzKSB7XG5cdFx0XHRjb25zdCBhQ29uZmxpY3RpbmdQYXRocyA9IG9EaXN0aW5jdEtleXNbc0Rpc3RpbmN0S2V5XTtcblx0XHRcdGxldCBzV2lubmVyVmFsdWVQYXRoO1xuXHRcdFx0Ly8gRmluZCB3aW5uZXIgdmFsdWUgZm9yIGVhY2ggZGlzdGluY3Qga2V5IGluIGNhc2Ugb2YgY29uZmxpY3QgYnkgdGhlIGZvbGxvd2luZyBydWxlOlxuXG5cdFx0XHQvLyAtPiBBLiBpZiBhbnkgbWV0YSBwYXRoIGZvciBhIGRpc3RpbmN0IGtleSBpcyB0aGUgc2FtZSBhcyBtYWluIGVudGl0eSB0YWtlIHRoYXQgYXMgdGhlIHZhbHVlXG5cdFx0XHQvLyAtPiBCLiBpZiBBIGlzIG5vdCBtZXQga2VlcCB0aGUgdmFsdWUgZnJvbSB0aGUgY3VycmVudCBjb250ZXh0IChzTWV0YVBhdGggPT09IHBhdGggb2YgZGlzdGluY2Uga2V5KVxuXHRcdFx0Ly8gLT4gQy4gaWYgQSwgQiBvciBDIGFyZSBub3QgbWV0IHRha2UgdGhlIGxhc3QgcGF0aCBmb3IgdmFsdWVcblx0XHRcdGlmIChhQ29uZmxpY3RpbmdQYXRocy5sZW5ndGggPiAxKSB7XG5cdFx0XHRcdC8vIGNvbmZsaWN0XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDw9IGFDb25mbGljdGluZ1BhdGhzLmxlbmd0aCAtIDE7IGkrKykge1xuXHRcdFx0XHRcdGNvbnN0IHNQYXRoID0gYUNvbmZsaWN0aW5nUGF0aHNbaV07XG5cdFx0XHRcdFx0bGV0IHNQYXRoSW5Db250ZXh0ID0gc1BhdGgucmVwbGFjZShzUGF0aCA9PT0gc01ldGFQYXRoID8gc01ldGFQYXRoIDogc01ldGFQYXRoICsgXCIvXCIsIFwiXCIpO1xuXHRcdFx0XHRcdHNQYXRoSW5Db250ZXh0ID0gKHNQYXRoSW5Db250ZXh0ID09PSBcIlwiID8gc1BhdGhJbkNvbnRleHQgOiBzUGF0aEluQ29udGV4dCArIFwiL1wiKSArIHNEaXN0aW5jdEtleTtcblx0XHRcdFx0XHRjb25zdCBzRW50aXR5VHlwZU5hbWUgPSBvTWV0YU1vZGVsLmdldE9iamVjdChzUGF0aCArIFwiL0BzYXB1aS5uYW1lXCIpO1xuXHRcdFx0XHRcdC8vIHJ1bGUgQVxuXG5cdFx0XHRcdFx0Ly8gcnVsZSBBXG5cdFx0XHRcdFx0aWYgKHNFbnRpdHlUeXBlTmFtZSA9PT0gc01haW5FbnRpdHlUeXBlTmFtZSkge1xuXHRcdFx0XHRcdFx0c01haW5FbnRpdHlWYWx1ZVBhdGggPSBzUGF0aEluQ29udGV4dDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBydWxlIEJcblx0XHRcdFx0XHRpZiAoc1BhdGggPT09IHNNZXRhUGF0aCkge1xuXHRcdFx0XHRcdFx0c0N1cnJlbnRWYWx1ZVBhdGggPSBzUGF0aEluQ29udGV4dDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBydWxlIENcblx0XHRcdFx0XHRzTGFzdFZhbHVlUGF0aCA9IHNQYXRoSW5Db250ZXh0O1xuXG5cdFx0XHRcdFx0Ly8gYWRkIGNvbmZsaWN0ZWQgcGF0aCB0byBzZW1hbnRpYyBhdHRyaWJ1dGVzXG5cdFx0XHRcdFx0Ly8gY2hlY2sgaWYgdGhlIGN1cnJlbnQgcGF0aCBwb2ludHMgdG8gbWFpbiBlbnRpdHkgYW5kIHByZWZpeCBhdHRyaWJ1dGUgbmFtZXMgYWNjb3JkaW5nbHlcblx0XHRcdFx0XHRvU2VtYW50aWNBdHRyaWJ1dGVzW1xuXHRcdFx0XHRcdFx0KHNNZXRhUGF0aCArIFwiL1wiICsgc1BhdGhJbkNvbnRleHQpXG5cdFx0XHRcdFx0XHRcdC5zcGxpdChcIi9cIilcblx0XHRcdFx0XHRcdFx0LmZpbHRlcihmdW5jdGlvbihzVmFsdWU6IHN0cmluZykge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBzVmFsdWUgIT0gXCJcIjtcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0LmpvaW4oXCIuXCIpXG5cdFx0XHRcdFx0XSA9IG9Db250ZXh0LmdldFByb3BlcnR5KHNQYXRoSW5Db250ZXh0KTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBBIHx8IEIgfHwgQ1xuXHRcdFx0XHRzV2lubmVyVmFsdWVQYXRoID0gc01haW5FbnRpdHlWYWx1ZVBhdGggfHwgc0N1cnJlbnRWYWx1ZVBhdGggfHwgc0xhc3RWYWx1ZVBhdGg7XG5cdFx0XHRcdG9TZW1hbnRpY0F0dHJpYnV0ZXNbc0Rpc3RpbmN0S2V5XSA9IG9Db250ZXh0LmdldFByb3BlcnR5KHNXaW5uZXJWYWx1ZVBhdGgpO1xuXHRcdFx0XHRzTWFpbkVudGl0eVZhbHVlUGF0aCA9IHVuZGVmaW5lZDtcblx0XHRcdFx0c0N1cnJlbnRWYWx1ZVBhdGggPSB1bmRlZmluZWQ7XG5cdFx0XHRcdHNMYXN0VmFsdWVQYXRoID0gdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gbm8gY29uZmxpY3QsIGFkZCBkaXN0aW5jdCBrZXkgd2l0aG91dCBhZGRpbmcgcGF0aHNcblx0XHRcdFx0Y29uc3Qgc1BhdGggPSBhQ29uZmxpY3RpbmdQYXRoc1swXTsgLy8gYmVjYXVzZSB0aGVyZSBpcyBvbmx5IG9uZSBhbmQgaGVuY2Ugbm8gY29uZmxpY3Rcblx0XHRcdFx0bGV0IHNQYXRoSW5Db250ZXh0ID0gc1BhdGgucmVwbGFjZShzUGF0aCA9PT0gc01ldGFQYXRoID8gc01ldGFQYXRoIDogc01ldGFQYXRoICsgXCIvXCIsIFwiXCIpO1xuXHRcdFx0XHRzUGF0aEluQ29udGV4dCA9IChzUGF0aEluQ29udGV4dCA9PT0gXCJcIiA/IHNQYXRoSW5Db250ZXh0IDogc1BhdGhJbkNvbnRleHQgKyBcIi9cIikgKyBzRGlzdGluY3RLZXk7XG5cdFx0XHRcdG9TZW1hbnRpY0F0dHJpYnV0ZXNbc0Rpc3RpbmN0S2V5XSA9IG9Db250ZXh0LmdldFByb3BlcnR5KHNQYXRoSW5Db250ZXh0KTtcblx0XHRcdFx0b1Byb3BlcnRpZXNXaXRob3V0Q29uZmxpY3Rbc0Rpc3RpbmN0S2V5XSA9IChzTWV0YVBhdGggKyBcIi9cIiArIHNQYXRoSW5Db250ZXh0KVxuXHRcdFx0XHRcdC5zcGxpdChcIi9cIilcblx0XHRcdFx0XHQuZmlsdGVyKGZ1bmN0aW9uKHNWYWx1ZTogc3RyaW5nKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gc1ZhbHVlICE9IFwiXCI7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuam9pbihcIi5cIik7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIDMuIFJlbW92ZSBhbGwgTmF2aWdhdGlvbiBwcm9wZXJ0aWVzXG5cdFx0Zm9yIChjb25zdCBzUHJvcGVydHkgaW4gb1NlbWFudGljQXR0cmlidXRlcykge1xuXHRcdFx0aWYgKG9TZW1hbnRpY0F0dHJpYnV0ZXNbc1Byb3BlcnR5XSAhPT0gbnVsbCAmJiB0eXBlb2Ygb1NlbWFudGljQXR0cmlidXRlc1tzUHJvcGVydHldID09PSBcIm9iamVjdFwiKSB7XG5cdFx0XHRcdGRlbGV0ZSBvU2VtYW50aWNBdHRyaWJ1dGVzW3NQcm9wZXJ0eV07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHRzZW1hbnRpY0F0dHJpYnV0ZXM6IG9TZW1hbnRpY0F0dHJpYnV0ZXMsXG5cdFx0XHRwcm9wZXJ0aWVzV2l0aG91dENvbmZsaWN0OiBvUHJvcGVydGllc1dpdGhvdXRDb25mbGljdFxuXHRcdH07XG5cdH1cblx0LyoqXG5cdCAqIFByZXBhcmUgZmlsdGVyIGNvbmRpdGlvbnMgdG8gYmUgcGFzc2VkIHRvIGV4dGVybmFsIG5hdmlnYXRpb24uXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvRmlsdGVyQmFyQ29uZGl0aW9ucyBGaWx0ZXIgY29uZGl0aW9ucy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHNSb290UGF0aCBSb290IHBhdGggb2YgdGhlIGFwcGxpY2F0aW9uLlxuXHQgKiBAcGFyYW0ge0FycmF5fSBhUGFyYW1ldGVycyBOYW1lcyBvZiBwYXJhbWV0ZXJzIHRvIGJlIGNvbnNpZGVyZWQuXG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IE9iamVjdCBvZiBwcmVwYXJlZCBmaWx0ZXIgY29uZGl0aW9ucyBmb3IgZXh0ZXJuYWwgbmF2aWdhdGlvbiBhbmQgbm8gY29uZmxpY3QgZmlsdGVycy5cblx0ICovXG5cdEBQdWJsaWNcblx0QEZpbmFsXG5cdHByZXBhcmVGaWx0ZXJzRm9yRXh0ZXJuYWxOYXZpZ2F0aW9uKG9GaWx0ZXJCYXJDb25kaXRpb25zOiBhbnksIHNSb290UGF0aDogc3RyaW5nLCBhUGFyYW1ldGVycz86IGFueVtdKSB7XG5cdFx0bGV0IHNQYXRoO1xuXHRcdGNvbnN0IG9EaXN0aW5jdEtleXM6IGFueSA9IHt9O1xuXHRcdGNvbnN0IG9GaWx0ZXJDb25kaXRpb25zV2l0aG91dENvbmZsaWN0OiBhbnkgPSB7fTtcblx0XHRsZXQgc01haW5FbnRpdHlWYWx1ZVBhdGgsIHNDdXJyZW50VmFsdWVQYXRoLCBzRnVsbENvbnRleHRQYXRoLCBzV2lubmVyVmFsdWVQYXRoLCBzUGF0aEluQ29udGV4dDtcblxuXHRcdGZ1bmN0aW9uIF9maW5kRGlzdGluY3RLZXlzSW5PYmplY3QoTG9va1VwT2JqZWN0OiBhbnkpIHtcblx0XHRcdGxldCBzTG9va1VwT2JqZWN0TWV0YVBhdGg7XG5cdFx0XHRmb3IgKGxldCBzS2V5IGluIExvb2tVcE9iamVjdCkge1xuXHRcdFx0XHRpZiAoTG9va1VwT2JqZWN0W3NLZXldKSB7XG5cdFx0XHRcdFx0aWYgKHNLZXkuaW5jbHVkZXMoXCIvXCIpKSB7XG5cdFx0XHRcdFx0XHRzTG9va1VwT2JqZWN0TWV0YVBhdGggPSBzS2V5OyAvLyBcIi9TYWxlc09yZGVybWFuYWdlL19JdGVtL01hdGVyaWFsXCJcblx0XHRcdFx0XHRcdGNvbnN0IGFQYXRoUGFydHMgPSBzS2V5LnNwbGl0KFwiL1wiKTtcblx0XHRcdFx0XHRcdHNLZXkgPSBhUGF0aFBhcnRzW2FQYXRoUGFydHMubGVuZ3RoIC0gMV07XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHNMb29rVXBPYmplY3RNZXRhUGF0aCA9IHNSb290UGF0aDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCFvRGlzdGluY3RLZXlzW3NLZXldKSB7XG5cdFx0XHRcdFx0XHQvLyBpZiBrZXkgaXMgZm91bmQgZm9yIHRoZSBmaXJzdCB0aW1lIHRoZW4gY3JlYXRlIGFycmF5XG5cdFx0XHRcdFx0XHRvRGlzdGluY3RLZXlzW3NLZXldID0gW107XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gcHVzaCBwYXRoIHRvIGFycmF5XG5cdFx0XHRcdFx0b0Rpc3RpbmN0S2V5c1tzS2V5XS5wdXNoKHNMb29rVXBPYmplY3RNZXRhUGF0aCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRfZmluZERpc3RpbmN0S2V5c0luT2JqZWN0KG9GaWx0ZXJCYXJDb25kaXRpb25zKTtcblx0XHRmb3IgKGNvbnN0IHNEaXN0aW5jdEtleSBpbiBvRGlzdGluY3RLZXlzKSB7XG5cdFx0XHRjb25zdCBhQ29uZmxpY3RpbmdQYXRocyA9IG9EaXN0aW5jdEtleXNbc0Rpc3RpbmN0S2V5XTtcblxuXHRcdFx0aWYgKGFDb25mbGljdGluZ1BhdGhzLmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0Ly8gY29uZmxpY3Rcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPD0gYUNvbmZsaWN0aW5nUGF0aHMubGVuZ3RoIC0gMTsgaSsrKSB7XG5cdFx0XHRcdFx0c1BhdGggPSBhQ29uZmxpY3RpbmdQYXRoc1tpXTtcblx0XHRcdFx0XHRpZiAoc1BhdGggPT09IHNSb290UGF0aCkge1xuXHRcdFx0XHRcdFx0c0Z1bGxDb250ZXh0UGF0aCA9IHNSb290UGF0aCArIFwiL1wiICsgc0Rpc3RpbmN0S2V5O1xuXHRcdFx0XHRcdFx0c1BhdGhJbkNvbnRleHQgPSBzRGlzdGluY3RLZXk7XG5cdFx0XHRcdFx0XHRzTWFpbkVudGl0eVZhbHVlUGF0aCA9IHNEaXN0aW5jdEtleTtcblx0XHRcdFx0XHRcdGlmIChhUGFyYW1ldGVycyAmJiBhUGFyYW1ldGVycy5pbmNsdWRlcyhzRGlzdGluY3RLZXkpKSB7XG5cdFx0XHRcdFx0XHRcdG9GaWx0ZXJCYXJDb25kaXRpb25zW1wiJFBhcmFtZXRlci5cIiArIHNEaXN0aW5jdEtleV0gPSBvRmlsdGVyQmFyQ29uZGl0aW9uc1tzRGlzdGluY3RLZXldO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzUGF0aEluQ29udGV4dCA9IHNQYXRoO1xuXHRcdFx0XHRcdFx0c0Z1bGxDb250ZXh0UGF0aCA9ICgoc1Jvb3RQYXRoICsgXCIvXCIgKyBzUGF0aCkgYXMgYW55KS5yZXBsYWNlQWxsKC9cXCovZywgXCJcIik7XG5cdFx0XHRcdFx0XHRzQ3VycmVudFZhbHVlUGF0aCA9IHNQYXRoO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRvRmlsdGVyQmFyQ29uZGl0aW9uc1tcblx0XHRcdFx0XHRcdHNGdWxsQ29udGV4dFBhdGhcblx0XHRcdFx0XHRcdFx0LnNwbGl0KFwiL1wiKVxuXHRcdFx0XHRcdFx0XHQuZmlsdGVyKGZ1bmN0aW9uKHNWYWx1ZTogYW55KSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHNWYWx1ZSAhPSBcIlwiO1xuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHQuam9pbihcIi5cIilcblx0XHRcdFx0XHRdID0gb0ZpbHRlckJhckNvbmRpdGlvbnNbc1BhdGhJbkNvbnRleHRdO1xuXHRcdFx0XHRcdGRlbGV0ZSBvRmlsdGVyQmFyQ29uZGl0aW9uc1tzUGF0aF07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRzV2lubmVyVmFsdWVQYXRoID0gc01haW5FbnRpdHlWYWx1ZVBhdGggfHwgc0N1cnJlbnRWYWx1ZVBhdGg7XG5cdFx0XHRcdG9GaWx0ZXJCYXJDb25kaXRpb25zW3NEaXN0aW5jdEtleV0gPSBvRmlsdGVyQmFyQ29uZGl0aW9uc1tzV2lubmVyVmFsdWVQYXRoXTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIG5vIGNvbmZsaWN0LCBhZGQgZGlzdGluY3Qga2V5IHdpdGhvdXQgYWRkaW5nIHBhdGhzXG5cdFx0XHRcdHNQYXRoID0gYUNvbmZsaWN0aW5nUGF0aHNbMF07XG5cdFx0XHRcdHNGdWxsQ29udGV4dFBhdGggPVxuXHRcdFx0XHRcdHNQYXRoID09PSBzUm9vdFBhdGggPyBzUm9vdFBhdGggKyBcIi9cIiArIHNEaXN0aW5jdEtleSA6ICgoc1Jvb3RQYXRoICsgXCIvXCIgKyBzUGF0aCkgYXMgYW55KS5yZXBsYWNlQWxsKFwiKlwiLCBcIlwiKTtcblx0XHRcdFx0b0ZpbHRlckNvbmRpdGlvbnNXaXRob3V0Q29uZmxpY3Rbc0Rpc3RpbmN0S2V5XSA9IHNGdWxsQ29udGV4dFBhdGhcblx0XHRcdFx0XHQuc3BsaXQoXCIvXCIpXG5cdFx0XHRcdFx0LmZpbHRlcihmdW5jdGlvbihzVmFsdWU6IGFueSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHNWYWx1ZSAhPSBcIlwiO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmpvaW4oXCIuXCIpO1xuXHRcdFx0XHRpZiAoYVBhcmFtZXRlcnMgJiYgYVBhcmFtZXRlcnMuaW5jbHVkZXMoc0Rpc3RpbmN0S2V5KSkge1xuXHRcdFx0XHRcdG9GaWx0ZXJCYXJDb25kaXRpb25zW1wiJFBhcmFtZXRlci5cIiArIHNEaXN0aW5jdEtleV0gPSBvRmlsdGVyQmFyQ29uZGl0aW9uc1tzRGlzdGluY3RLZXldO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHtcblx0XHRcdGZpbHRlckNvbmRpdGlvbnM6IG9GaWx0ZXJCYXJDb25kaXRpb25zLFxuXHRcdFx0ZmlsdGVyQ29uZGl0aW9uc1dpdGhvdXRDb25mbGljdDogb0ZpbHRlckNvbmRpdGlvbnNXaXRob3V0Q29uZmxpY3Rcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBOYXZpZ2F0aW9uIG1vZGUuXG5cdCAqXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9XG5cdCAqL1xuXHRAUHVibGljXG5cdEBFeHRlbnNpYmxlKE92ZXJyaWRlRXhlY3V0aW9uLkluc3RlYWQpXG5cdGdldE5hdmlnYXRpb25Nb2RlKCkge1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0LyoqXG5cdCAqIEFsbG93cyBmb3IgbmF2aWdhdGlvbiB0byBhIGdpdmVuIGludGVudCAoU2VtYW50aWNPYmplY3QtQWN0aW9uKSB3aXRoIHRoZSBwcm92aWRlZCBjb250ZXh0LCB1c2luZyBhIGRpYWxvZyB0aGF0IHNob3dzIHRoZSBjb250ZXh0cyB3aGljaCBjYW5ub3QgYmUgcGFzc2VkXG5cdCAqIElmIHNlbWFudGljIG9iamVjdCBtYXBwaW5nIGlzIHByb3ZpZGVkLCB0aGlzIHNldHRpbmcgaXMgYWxzbyBhcHBsaWVkIHRvIHRoZSBzZWxlY3Rpb24gdmFyaWFudCBhZnRlciBhZGFwdGF0aW9uIGJ5IGEgY29uc3VtZXIuXG5cdCAqIFRoaXMgc2V0dGluZyBhbHNvIHJlbW92ZXMgYW55IHRlY2huaWNhbCBwYXJhbWV0ZXJzIGFuZCBkZXRlcm1pbmVzIGlmIGFuIGlucGxhY2Ugb3IgZXhwbGFjZSBuYXZpZ2F0aW9uIHNob3VsZCB0YWtlIHBsYWNlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc1NlbWFudGljT2JqZWN0IFNlbWFudGljIG9iamVjdCBmb3IgdGhlIHRhcmdldCBhcHBcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNBY3Rpb24gIEFjdGlvbiBmb3IgdGhlIHRhcmdldCBhcHBcblx0ICogQHBhcmFtIHtvYmplY3R9IFttTmF2aWdhdGlvblBhcmFtZXRlcnNdIE9wdGlvbmFsIHBhcmFtZXRlcnMgdG8gYmUgcGFzc2VkIHRvIHRoZSBleHRlcm5hbCBuYXZpZ2F0aW9uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBbbU5hdmlnYXRpb25QYXJhbWV0ZXJzLmxhYmVsXVxuXHQgKiBAcGFyYW0ge0FycmF5fG9iamVjdH0gW21OYXZpZ2F0aW9uUGFyYW1ldGVycy5uYXZpZ2F0aW9uQ29udGV4dHNdIFNpbmdsZSBpbnN0YW5jZSBvciBtdWx0aXBsZSBpbnN0YW5jZXMgb2Yge0BsaW5rIHNhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0fSwgb3IgYWx0ZXJuYXRpdmVseSBhbiBvYmplY3Qgb3IgYXJyYXkgb2Ygb2JqZWN0cywgdG8gYmUgcGFzc2VkIHRvIHRoZSBpbnRlbnQuXG5cdCAqIEBwYXJhbSB7QXJyYXl8b2JqZWN0fSBbbU5hdmlnYXRpb25QYXJhbWV0ZXJzLmFwcGxpY2FibGVDb250ZXh0c10gU2luZ2xlIGluc3RhbmNlIG9yIG11bHRpcGxlIGluc3RhbmNlcyBvZiB7QGxpbmsgc2FwLnVpLm1vZGVsLm9kYXRhLnY0LkNvbnRleHR9LCBvciBhbHRlcm5hdGl2ZWx5IGFuIG9iamVjdCBvciBhcnJheSBvZiBvYmplY3RzLCB0byBiZSBwYXNzZWQgdG8gdGhlIGludGVudCBhbmQgZm9yIHdoaWNoIHRoZSBJQk4gYnV0dG9uIGlzIGVuYWJsZWRcblx0ICogQHBhcmFtIHtBcnJheXxvYmplY3R9IFttTmF2aWdhdGlvblBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHRzXSBTaW5nbGUgaW5zdGFuY2Ugb3IgbXVsdGlwbGUgaW5zdGFuY2VzIG9mIHtAbGluayBzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dH0sIG9yIGFsdGVybmF0aXZlbHkgYW4gb2JqZWN0IG9yIGFycmF5IG9mIG9iamVjdHMsIHdoaWNoIGNhbm5vdCBiZSBwYXNzZWQgdG8gdGhlIGludGVudC5cblx0ICpcdFx0ICBpZiBhbiBhcnJheSBvZiBjb250ZXh0cyBpcyBwYXNzZWQgdGhlIGNvbnRleHQgaXMgdXNlZCB0byBkZXRlcm1pbmUgdGhlIG1ldGEgcGF0aCBhbmQgYWNjb3JkaW5nbHkgcmVtb3ZlIHRoZSBzZW5zaXRpdmUgZGF0YVxuXHQgKlx0XHQgIElmIGFuIGFycmF5IG9mIG9iamVjdHMgaXMgcGFzc2VkLCB0aGUgZm9sbG93aW5nIGZvcm1hdCBpcyBleHBlY3RlZDpcblx0ICpcdFx0ICB7XG5cdCAqXHRcdFx0ZGF0YToge1xuXHQgKlx0IFx0XHRcdFByb2R1Y3RJRDogNzYzNCxcblx0ICpcdFx0XHRcdE5hbWU6IFwiTGFwdG9wXCJcblx0ICpcdFx0XHQgfSxcblx0ICpcdFx0XHQgbWV0YVBhdGg6IFwiL1NhbGVzT3JkZXJNYW5hZ2VcIlxuXHQgKiAgICAgICAgfVxuXHQgKlx0XHRUaGUgbWV0YVBhdGggaXMgdXNlZCB0byByZW1vdmUgYW55IHNlbnNpdGl2ZSBkYXRhLlxuXHQgKiBAcGFyYW0ge3N0cmluZyB8IG9iamVjdH0gW21OYXZpZ2F0aW9uUGFyYW1ldGVycy5zZW1hbnRpY09iamVjdE1hcHBpbmddIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBTZW1hbnRpY09iamVjdE1hcHBpbmcgb3IgU2VtYW50aWNPYmplY3RNYXBwaW5nIHRoYXQgYXBwbGllcyB0byB0aGlzIG5hdmlnYXRpb25cblx0ICoqL1xuXHRAUHVibGljXG5cdEBGaW5hbFxuXHRuYXZpZ2F0ZVdpdGhDb25maXJtYXRpb25EaWFsb2coXG5cdFx0c1NlbWFudGljT2JqZWN0OiBzdHJpbmcsXG5cdFx0c0FjdGlvbjogc3RyaW5nLFxuXHRcdG1OYXZpZ2F0aW9uUGFyYW1ldGVycz86IHtcblx0XHRcdG5hdmlnYXRpb25Db250ZXh0cz86IG9iamVjdCB8IGFueVtdO1xuXHRcdFx0YXBwbGljYWJsZUNvbnRleHRzPzogb2JqZWN0IHwgYW55W107XG5cdFx0XHRub3RBcHBsaWNhYmxlQ29udGV4dHM/OiBhbnk7XG5cdFx0XHRsYWJlbD86IHN0cmluZztcblx0XHRcdHNlbWFudGljT2JqZWN0TWFwcGluZz86IHN0cmluZyB8IG9iamVjdDtcblx0XHR9XG5cdCkge1xuXHRcdGlmIChtTmF2aWdhdGlvblBhcmFtZXRlcnM/Lm5vdEFwcGxpY2FibGVDb250ZXh0cyAmJiBtTmF2aWdhdGlvblBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHRzPy5sZW5ndGggPj0gMSkge1xuXHRcdFx0bGV0IG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZzogRGlhbG9nO1xuXHRcdFx0Y29uc3Qgb0NvbnRyb2xsZXIgPSB7XG5cdFx0XHRcdG9uQ2xvc2U6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdC8vIFVzZXIgY2FuY2VscyBhY3Rpb25cblx0XHRcdFx0XHRvQXBwbGljYWJsZUNvbnRleHREaWFsb2cuY2xvc2UoKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0b25Db250aW51ZTogKCkgPT4ge1xuXHRcdFx0XHRcdC8vIFVzZXJzIGNvbnRpbnVlcyB0aGUgYWN0aW9uIHdpdGggdGhlIGJvdW5kIGNvbnRleHRzXG5cdFx0XHRcdFx0bU5hdmlnYXRpb25QYXJhbWV0ZXJzLm5hdmlnYXRpb25Db250ZXh0cyA9IG1OYXZpZ2F0aW9uUGFyYW1ldGVycy5hcHBsaWNhYmxlQ29udGV4dHM7XG5cdFx0XHRcdFx0b0FwcGxpY2FibGVDb250ZXh0RGlhbG9nLmNsb3NlKCk7XG5cdFx0XHRcdFx0dGhpcy5uYXZpZ2F0ZShzU2VtYW50aWNPYmplY3QsIHNBY3Rpb24sIG1OYXZpZ2F0aW9uUGFyYW1ldGVycyk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0XHRjb25zdCBmbk9wZW5BbmRGaWxsRGlhbG9nID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxldCBvRGlhbG9nQ29udGVudDtcblx0XHRcdFx0Y29uc3Qgbk5vdEFwcGxpY2FibGUgPSBtTmF2aWdhdGlvblBhcmFtZXRlcnMubm90QXBwbGljYWJsZUNvbnRleHRzLmxlbmd0aCxcblx0XHRcdFx0XHRhTm90QXBwbGljYWJsZUl0ZW1zID0gW107XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbU5hdmlnYXRpb25QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdG9EaWFsb2dDb250ZW50ID0gbU5hdmlnYXRpb25QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0c1tpXS5nZXRPYmplY3QoKTtcblx0XHRcdFx0XHRhTm90QXBwbGljYWJsZUl0ZW1zLnB1c2gob0RpYWxvZ0NvbnRlbnQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnN0IG9Ob3RBcHBsaWNhYmxlSXRlbXNNb2RlbCA9IG5ldyBKU09OTW9kZWwoYU5vdEFwcGxpY2FibGVJdGVtcyk7XG5cdFx0XHRcdGNvbnN0IG9Ub3RhbHMgPSBuZXcgSlNPTk1vZGVsKHsgdG90YWw6IG5Ob3RBcHBsaWNhYmxlLCBsYWJlbDogbU5hdmlnYXRpb25QYXJhbWV0ZXJzLmxhYmVsIH0pO1xuXHRcdFx0XHRvQXBwbGljYWJsZUNvbnRleHREaWFsb2cuc2V0TW9kZWwob05vdEFwcGxpY2FibGVJdGVtc01vZGVsLCBcIm5vdEFwcGxpY2FibGVcIik7XG5cdFx0XHRcdG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZy5zZXRNb2RlbChvVG90YWxzLCBcInRvdGFsc1wiKTtcblx0XHRcdFx0b0FwcGxpY2FibGVDb250ZXh0RGlhbG9nLm9wZW4oKTtcblx0XHRcdH07XG5cdFx0XHQvLyBTaG93IHRoZSBjb250ZXh0cyB0aGF0IGFyZSBub3QgYXBwbGljYWJsZSBhbmQgd2lsbCBub3QgdGhlcmVmb3JlIGJlIHByb2Nlc3NlZFxuXHRcdFx0Y29uc3Qgc0ZyYWdtZW50TmFtZSA9IFwic2FwLmZlLmNvcmUuY29udHJvbHMuQWN0aW9uUGFydGlhbFwiO1xuXHRcdFx0Y29uc3Qgb0RpYWxvZ0ZyYWdtZW50ID0gWE1MVGVtcGxhdGVQcm9jZXNzb3IubG9hZFRlbXBsYXRlKHNGcmFnbWVudE5hbWUsIFwiZnJhZ21lbnRcIik7XG5cdFx0XHRjb25zdCBvTW9kZWwgPSB0aGlzLl9vVmlldy5nZXRNb2RlbCgpO1xuXHRcdFx0Y29uc3Qgb01ldGFNb2RlbCA9IG9Nb2RlbC5nZXRNZXRhTW9kZWwoKTtcblx0XHRcdGNvbnN0IHNDYW5vbmljYWxQYXRoID0gbU5hdmlnYXRpb25QYXJhbWV0ZXJzLm5vdEFwcGxpY2FibGVDb250ZXh0c1swXS5nZXRDYW5vbmljYWxQYXRoKCk7XG5cdFx0XHRjb25zdCBzRW50aXR5U2V0ID0gc0Nhbm9uaWNhbFBhdGguc3Vic3RyKDAsIHNDYW5vbmljYWxQYXRoLmluZGV4T2YoXCIoXCIpKSArIFwiL1wiO1xuXHRcdFx0UHJvbWlzZS5yZXNvbHZlKFxuXHRcdFx0XHRYTUxQcmVwcm9jZXNzb3IucHJvY2Vzcyhcblx0XHRcdFx0XHRvRGlhbG9nRnJhZ21lbnQsXG5cdFx0XHRcdFx0eyBuYW1lOiBzRnJhZ21lbnROYW1lIH0sXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0YmluZGluZ0NvbnRleHRzOiB7XG5cdFx0XHRcdFx0XHRcdGVudGl0eVR5cGU6IG9NZXRhTW9kZWwuY3JlYXRlQmluZGluZ0NvbnRleHQoc0VudGl0eVNldClcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRtb2RlbHM6IHtcblx0XHRcdFx0XHRcdFx0ZW50aXR5VHlwZTogb01ldGFNb2RlbCxcblx0XHRcdFx0XHRcdFx0bWV0YU1vZGVsOiBvTWV0YU1vZGVsXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQpXG5cdFx0XHQpXG5cdFx0XHRcdC50aGVuKGZ1bmN0aW9uKG9GcmFnbWVudDogYW55KSB7XG5cdFx0XHRcdFx0cmV0dXJuIEZyYWdtZW50LmxvYWQoeyBkZWZpbml0aW9uOiBvRnJhZ21lbnQsIGNvbnRyb2xsZXI6IG9Db250cm9sbGVyIH0pO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQudGhlbigob1BvcG92ZXI6IGFueSkgPT4ge1xuXHRcdFx0XHRcdG9BcHBsaWNhYmxlQ29udGV4dERpYWxvZyA9IG9Qb3BvdmVyO1xuXHRcdFx0XHRcdHRoaXMuZ2V0VmlldygpLmFkZERlcGVuZGVudChvUG9wb3Zlcik7XG5cdFx0XHRcdFx0Zm5PcGVuQW5kRmlsbERpYWxvZygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQuY2F0Y2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0TG9nLmVycm9yKFwiRXJyb3JcIik7XG5cdFx0XHRcdH0pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLm5hdmlnYXRlKHNTZW1hbnRpY09iamVjdCwgc0FjdGlvbiwgbU5hdmlnYXRpb25QYXJhbWV0ZXJzKTtcblx0XHR9XG5cdH1cblx0X3JlbW92ZVRlY2huaWNhbFBhcmFtZXRlcnMob1NlbGVjdGlvblZhcmlhbnQ6IGFueSkge1xuXHRcdG9TZWxlY3Rpb25WYXJpYW50LnJlbW92ZVNlbGVjdE9wdGlvbihcIkBvZGF0YS5jb250ZXh0XCIpO1xuXHRcdG9TZWxlY3Rpb25WYXJpYW50LnJlbW92ZVNlbGVjdE9wdGlvbihcIkBvZGF0YS5tZXRhZGF0YUV0YWdcIik7XG5cdFx0b1NlbGVjdGlvblZhcmlhbnQucmVtb3ZlU2VsZWN0T3B0aW9uKFwiU0FQX19NZXNzYWdlc1wiKTtcblx0fVxuXHQvKipcblx0ICogR2V0IHRhcmdldGVkIEVudGl0eSBzZXQuXG5cdCAqXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9IEVudGl0eSBzZXQgbmFtZVxuXHQgKlxuXHQgKlxuXHQgKi9cblx0QFByaXZhdGVcblx0Z2V0RW50aXR5U2V0KCkge1xuXHRcdHJldHVybiAodGhpcy5fb1ZpZXcuZ2V0Vmlld0RhdGEoKSBhcyBhbnkpLmVudGl0eVNldDtcblx0fVxuXHQvKipcblx0ICogUmVtb3ZlcyBzZW5zaXRpdmUgZGF0YSBmcm9tIHRoZSBzZW1hbnRpYyBhdHRyaWJ1dGUgd2l0aCByZXNwZWN0IHRvIGVudGl0eVNldC5cblx0ICpcblx0ICogQHBhcmFtIHtvYmplY3R9IG9BdHRyaWJ1dGVzIENvbnRleHQgZGF0YVxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc01ldGFQYXRoIE1ldGEgcGF0aCB0byByZWFjaCB0aGUgZW50aXR5c2V0IGluIHRoZSBNZXRhTW9kZWxcblx0ICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBzZW1hbnRpYyBBdHRyaWJ1dGVzXG5cdCAqIEBwcml2YXRlXG5cdCAqKi9cblx0Ly8gVE8tRE8gYWRkIHVuaXQgdGVzdHMgZm9yIHRoaXMgZnVuY3Rpb24gaW4gdGhlIGNvbnRyb2xsZXIgZXh0ZW5zaW9uIHF1bml0LlxuXHRAUHVibGljXG5cdEBGaW5hbFxuXHRyZW1vdmVTZW5zaXRpdmVEYXRhKG9BdHRyaWJ1dGVzOiBhbnksIHNNZXRhUGF0aDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgYVByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhvQXR0cmlidXRlcyk7XG5cdFx0aWYgKGFQcm9wZXJ0aWVzLmxlbmd0aCkge1xuXHRcdFx0ZGVsZXRlIG9BdHRyaWJ1dGVzW1wiQG9kYXRhLmNvbnRleHRcIl07XG5cdFx0XHRkZWxldGUgb0F0dHJpYnV0ZXNbXCJAb2RhdGEubWV0YWRhdGFFdGFnXCJdO1xuXHRcdFx0ZGVsZXRlIG9BdHRyaWJ1dGVzW1wiU0FQX19NZXNzYWdlc1wiXTtcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgYVByb3BlcnRpZXMubGVuZ3RoOyBqKyspIHtcblx0XHRcdFx0aWYgKG9BdHRyaWJ1dGVzW2FQcm9wZXJ0aWVzW2pdXSAmJiB0eXBlb2Ygb0F0dHJpYnV0ZXNbYVByb3BlcnRpZXNbal1dID09PSBcIm9iamVjdFwiKSB7XG5cdFx0XHRcdFx0dGhpcy5yZW1vdmVTZW5zaXRpdmVEYXRhKG9BdHRyaWJ1dGVzW2FQcm9wZXJ0aWVzW2pdXSwgc01ldGFQYXRoICsgXCIvXCIgKyBhUHJvcGVydGllc1tqXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29uc3Qgc1Byb3AgPSBhUHJvcGVydGllc1tqXSxcblx0XHRcdFx0XHRhUHJvcGVydHlBbm5vdGF0aW9ucyA9IHRoaXMuX29NZXRhTW9kZWwuZ2V0T2JqZWN0KHNNZXRhUGF0aCArIFwiL1wiICsgc1Byb3AgKyBcIkBcIik7XG5cdFx0XHRcdGlmIChhUHJvcGVydHlBbm5vdGF0aW9ucykge1xuXHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdGFQcm9wZXJ0eUFubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLlBlcnNvbmFsRGF0YS52MS5Jc1BvdGVudGlhbGx5U2Vuc2l0aXZlXCJdIHx8XG5cdFx0XHRcdFx0XHRhUHJvcGVydHlBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5VSS52MS5FeGNsdWRlRnJvbU5hdmlnYXRpb25Db250ZXh0XCJdIHx8XG5cdFx0XHRcdFx0XHRhUHJvcGVydHlBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5BbmFseXRpY3MudjEuTWVhc3VyZVwiXVxuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0ZGVsZXRlIG9BdHRyaWJ1dGVzW3NQcm9wXTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGFQcm9wZXJ0eUFubm90YXRpb25zW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5GaWVsZENvbnRyb2xcIl0pIHtcblx0XHRcdFx0XHRcdGNvbnN0IG9GaWVsZENvbnRyb2wgPSBhUHJvcGVydHlBbm5vdGF0aW9uc1tcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuRmllbGRDb250cm9sXCJdO1xuXHRcdFx0XHRcdFx0aWYgKG9GaWVsZENvbnRyb2xbXCIkRW51bU1lbWJlclwiXSAmJiBvRmllbGRDb250cm9sW1wiJEVudW1NZW1iZXJcIl0uc3BsaXQoXCIvXCIpWzFdID09PSBcIkluYXBwbGljYWJsZVwiKSB7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSBvQXR0cmlidXRlc1tzUHJvcF07XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKG9GaWVsZENvbnRyb2xbXCIkUGF0aFwiXSAmJiB0aGlzLl9pc0ZpZWxkQ29udHJvbFBhdGhJbmFwcGxpY2FibGUob0ZpZWxkQ29udHJvbFtcIiRQYXRoXCJdLCBvQXR0cmlidXRlcykpIHtcblx0XHRcdFx0XHRcdFx0ZGVsZXRlIG9BdHRyaWJ1dGVzW3NQcm9wXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG9BdHRyaWJ1dGVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENoZWNrIGlmIFBhdGggYmFzZWQgRmllbGRDb250cm9sIEV2YWx1YXRlcyB0byBpbmFwcGxpY2FibGUuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzRmllbGRDb250cm9sUGF0aCBGaWVsZCBjb250cm9sIHBhdGhcblx0ICogQHBhcmFtIHtvYmplY3R9IG9BdHRyaWJ1dGUgU2VtYW50aWNBdHRyaWJ1dGVzXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgaW5hcHBsaWNhYmxlXG5cdCAqXG5cdCAqL1xuXHRfaXNGaWVsZENvbnRyb2xQYXRoSW5hcHBsaWNhYmxlKHNGaWVsZENvbnRyb2xQYXRoOiBzdHJpbmcsIG9BdHRyaWJ1dGU6IGFueSkge1xuXHRcdGxldCBiSW5hcHBsaWNhYmxlID0gZmFsc2U7XG5cdFx0Y29uc3QgYVBhcnRzID0gc0ZpZWxkQ29udHJvbFBhdGguc3BsaXQoXCIvXCIpO1xuXHRcdC8vIHNlbnNpdGl2ZSBkYXRhIGlzIHJlbW92ZWQgb25seSBpZiB0aGUgcGF0aCBoYXMgYWxyZWFkeSBiZWVuIHJlc29sdmVkLlxuXHRcdGlmIChhUGFydHMubGVuZ3RoID4gMSkge1xuXHRcdFx0YkluYXBwbGljYWJsZSA9XG5cdFx0XHRcdG9BdHRyaWJ1dGVbYVBhcnRzWzBdXSAmJiBvQXR0cmlidXRlW2FQYXJ0c1swXV0uaGFzT3duUHJvcGVydHkoYVBhcnRzWzFdKSAmJiBvQXR0cmlidXRlW2FQYXJ0c1swXV1bYVBhcnRzWzFdXSA9PT0gMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YkluYXBwbGljYWJsZSA9IG9BdHRyaWJ1dGVbc0ZpZWxkQ29udHJvbFBhdGhdID09PSAwO1xuXHRcdH1cblx0XHRyZXR1cm4gYkluYXBwbGljYWJsZTtcblx0fVxuXHQvKipcblx0ICogTWV0aG9kIHRvIHJlcGxhY2UgTG9jYWwgUHJvcGVydGllcyB3aXRoIFNlbWFudGljIE9iamVjdCBtYXBwaW5ncy5cblx0ICpcblx0ICogQHBhcmFtIHtvYmplY3R9IG9TZWxlY3Rpb25WYXJpYW50IFNlbGVjdGlvblZhcmlhbnQgY29uc2lzdGluZyBvZiBmaWx0ZXJiYXIsIFRhYmxlIGFuZCBQYWdlIENvbnRleHRcblx0ICogQHBhcmFtIHtvYmplY3QgfCBzdHJpbmd9IHZNYXBwaW5ncyBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBzZW1hbnRpYyBvYmplY3QgbWFwcGluZ1xuXHQgKiBAcmV0dXJucyB7b2JqZWN0fSAtIE1vZGlmaWVkIFNlbGVjdGlvblZhcmlhbnQgd2l0aCBMb2NhbFByb3BlcnR5IHJlcGxhY2VkIHdpdGggU2VtYW50aWNPYmplY3RQcm9wZXJ0aWVzLlxuXHQgKi9cblx0X2FwcGx5U2VtYW50aWNPYmplY3RNYXBwaW5ncyhvU2VsZWN0aW9uVmFyaWFudDogU2VsZWN0aW9uVmFyaWFudCwgdk1hcHBpbmdzOiBvYmplY3QgfCBzdHJpbmcpIHtcblx0XHRjb25zdCBvTWFwcGluZ3MgPSB0eXBlb2Ygdk1hcHBpbmdzID09PSBcInN0cmluZ1wiID8gSlNPTi5wYXJzZSh2TWFwcGluZ3MpIDogdk1hcHBpbmdzO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgb01hcHBpbmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCBzTG9jYWxQcm9wZXJ0eSA9XG5cdFx0XHRcdChvTWFwcGluZ3NbaV1bXCJMb2NhbFByb3BlcnR5XCJdICYmIG9NYXBwaW5nc1tpXVtcIkxvY2FsUHJvcGVydHlcIl1bXCIkUHJvcGVydHlQYXRoXCJdKSB8fFxuXHRcdFx0XHQob01hcHBpbmdzW2ldW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5Mb2NhbFByb3BlcnR5XCJdICYmXG5cdFx0XHRcdFx0b01hcHBpbmdzW2ldW1wiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5Mb2NhbFByb3BlcnR5XCJdW1wiJFBhdGhcIl0pO1xuXHRcdFx0Y29uc3Qgc1NlbWFudGljT2JqZWN0UHJvcGVydHkgPVxuXHRcdFx0XHRvTWFwcGluZ3NbaV1bXCJTZW1hbnRpY09iamVjdFByb3BlcnR5XCJdIHx8IG9NYXBwaW5nc1tpXVtcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuU2VtYW50aWNPYmplY3RQcm9wZXJ0eVwiXTtcblx0XHRcdGlmIChvU2VsZWN0aW9uVmFyaWFudC5nZXRTZWxlY3RPcHRpb24oc0xvY2FsUHJvcGVydHkpKSB7XG5cdFx0XHRcdGNvbnN0IG9TZWxlY3RPcHRpb24gPSBvU2VsZWN0aW9uVmFyaWFudC5nZXRTZWxlY3RPcHRpb24oc0xvY2FsUHJvcGVydHkpO1xuXG5cdFx0XHRcdC8vQ3JlYXRlIGEgbmV3IFNlbGVjdE9wdGlvbiB3aXRoIHNTZW1hbnRpY09iamVjdFByb3BlcnR5IGFzIHRoZSBwcm9wZXJ0eSBOYW1lIGFuZCByZW1vdmUgdGhlIG9sZGVyIG9uZVxuXHRcdFx0XHRvU2VsZWN0aW9uVmFyaWFudC5yZW1vdmVTZWxlY3RPcHRpb24oc0xvY2FsUHJvcGVydHkpO1xuXHRcdFx0XHRvU2VsZWN0aW9uVmFyaWFudC5tYXNzQWRkU2VsZWN0T3B0aW9uKHNTZW1hbnRpY09iamVjdFByb3BlcnR5LCBvU2VsZWN0T3B0aW9uKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG9TZWxlY3Rpb25WYXJpYW50O1xuXHR9XG5cdC8qKlxuXHQgKiBOYXZpZ2F0ZXMgdG8gYW4gT3V0Ym91bmQgcHJvdmlkZWQgaW4gdGhlIG1hbmlmZXN0LlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQHBhcmFtIHtzdHJpbmd9IHNPdXRib3VuZCBJZGVudGlmaWVyIHRvIGxvY2F0aW9uIHRoZSBvdXRib3VuZCBpbiB0aGUgbWFuaWZlc3Rcblx0ICogQHBhcmFtIHtvYmplY3R9IG1OYXZpZ2F0aW9uUGFyYW1ldGVycyBPcHRpb25hbCBtYXAgY29udGFpbmluZyBrZXkvdmFsdWUgcGFpcnMgdG8gYmUgcGFzc2VkIHRvIHRoZSBpbnRlbnRcblx0ICogQGFsaWFzIHNhcC5mZS5jb3JlLmNvbnRyb2xsZXJleHRlbnNpb25zLkludGVudEJhc2VkTmF2aWdhdGlvbiNuYXZpZ2F0ZU91dGJvdW5kXG5cdCAqIEBzaW5jZSAxLjg2LjBcblx0ICoqL1xuXHRAUHVibGljXG5cdEBGaW5hbFxuXHRuYXZpZ2F0ZU91dGJvdW5kKHNPdXRib3VuZDogc3RyaW5nLCBtTmF2aWdhdGlvblBhcmFtZXRlcnM6IGFueSkge1xuXHRcdGxldCBhTmF2UGFyYW1zOiBhbnlbXSB8IHVuZGVmaW5lZDtcblx0XHRjb25zdCBvTWFuaWZlc3RFbnRyeSA9IHRoaXMuYmFzZS5nZXRBcHBDb21wb25lbnQoKS5nZXRNYW5pZmVzdEVudHJ5KFwic2FwLmFwcFwiKSxcblx0XHRcdG9PdXRib3VuZCA9IG9NYW5pZmVzdEVudHJ5LmNyb3NzTmF2aWdhdGlvbiAmJiBvTWFuaWZlc3RFbnRyeS5jcm9zc05hdmlnYXRpb24ub3V0Ym91bmRzW3NPdXRib3VuZF07XG5cdFx0aWYgKCFvT3V0Ym91bmQpIHtcblx0XHRcdExvZy5lcnJvcihcIk91dGJvdW5kIGlzIG5vdCBkZWZpbmVkIGluIG1hbmlmZXN0ISFcIik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGNvbnN0IHNTZW1hbnRpY09iamVjdCA9IG9PdXRib3VuZC5zZW1hbnRpY09iamVjdCxcblx0XHRcdHNBY3Rpb24gPSBvT3V0Ym91bmQuYWN0aW9uLFxuXHRcdFx0b3V0Ym91bmRQYXJhbXMgPSBvT3V0Ym91bmQucGFyYW1ldGVycyAmJiB0aGlzLmdldE91dGJvdW5kUGFyYW1zKG9PdXRib3VuZC5wYXJhbWV0ZXJzKTtcblxuXHRcdGlmIChtTmF2aWdhdGlvblBhcmFtZXRlcnMpIHtcblx0XHRcdGFOYXZQYXJhbXMgPSBbXTtcblx0XHRcdE9iamVjdC5rZXlzKG1OYXZpZ2F0aW9uUGFyYW1ldGVycykuZm9yRWFjaChmdW5jdGlvbihrZXk6IHN0cmluZykge1xuXHRcdFx0XHRsZXQgb1BhcmFtczogYW55O1xuXHRcdFx0XHRpZiAoQXJyYXkuaXNBcnJheShtTmF2aWdhdGlvblBhcmFtZXRlcnNba2V5XSkpIHtcblx0XHRcdFx0XHRjb25zdCBhVmFsdWVzID0gbU5hdmlnYXRpb25QYXJhbWV0ZXJzW2tleV07XG5cdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRvUGFyYW1zID0ge307XG5cdFx0XHRcdFx0XHRvUGFyYW1zW2tleV0gPSBhVmFsdWVzW2ldO1xuXHRcdFx0XHRcdFx0YU5hdlBhcmFtcz8ucHVzaChvUGFyYW1zKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0b1BhcmFtcyA9IHt9O1xuXHRcdFx0XHRcdG9QYXJhbXNba2V5XSA9IG1OYXZpZ2F0aW9uUGFyYW1ldGVyc1trZXldO1xuXHRcdFx0XHRcdGFOYXZQYXJhbXM/LnB1c2gob1BhcmFtcyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoYU5hdlBhcmFtcyB8fCBvdXRib3VuZFBhcmFtcykge1xuXHRcdFx0bU5hdmlnYXRpb25QYXJhbWV0ZXJzID0ge1xuXHRcdFx0XHRuYXZpZ2F0aW9uQ29udGV4dHM6IHtcblx0XHRcdFx0XHRkYXRhOiBhTmF2UGFyYW1zIHx8IG91dGJvdW5kUGFyYW1zXG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHRcdHRoaXMuYmFzZS5faW50ZW50QmFzZWROYXZpZ2F0aW9uLm5hdmlnYXRlKHNTZW1hbnRpY09iamVjdCwgc0FjdGlvbiwgbU5hdmlnYXRpb25QYXJhbWV0ZXJzKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNZXRob2QgdG8gYXBwbHkgb3V0Ym91bmQgcGFyYW1ldGVycyBkZWZpbmVkIGluIHRoZSBtYW5pZmVzdC5cblx0ICogQHBhcmFtIHtvYmplY3R9IG9TZWxlY3Rpb25WYXJpYW50IFNlbGVjdGlvblZhcmlhbnQgY29uc2lzdGluZyBvZiBhIGZpbHRlciBiYXIsIGEgdGFibGUsIGFuZCBhIHBhZ2UgY29udGV4dFxuXHQgKiBAcGFyYW0ge29iamVjdH0gdk91dGJvdW5kUGFyYW1zIE91dGJvdW5kIFByb3BlcnRpZXMgZGVmaW5lZCBpbiB0aGUgbWFuaWZlc3Rcblx0ICogQHJldHVybnMge29iamVjdH0gLSBUaGUgbW9kaWZpZWQgU2VsZWN0aW9uVmFyaWFudCB3aXRoIG91dGJvdW5kIHBhcmFtZXRlcnMuXG5cdCAqL1xuXHRfYXBwbHlPdXRib3VuZFBhcmFtcyhvU2VsZWN0aW9uVmFyaWFudDogU2VsZWN0aW9uVmFyaWFudCwgdk91dGJvdW5kUGFyYW1zOiBhbnkpIHtcblx0XHRjb25zdCBhUGFyYW1ldGVycyA9IE9iamVjdC5rZXlzKHZPdXRib3VuZFBhcmFtcyk7XG5cdFx0Y29uc3QgYVNlbGVjdFByb3BlcnRpZXMgPSBvU2VsZWN0aW9uVmFyaWFudC5nZXRTZWxlY3RPcHRpb25zUHJvcGVydHlOYW1lcygpO1xuXHRcdGFQYXJhbWV0ZXJzLmZvckVhY2goZnVuY3Rpb24oa2V5OiBzdHJpbmcpIHtcblx0XHRcdGlmICghYVNlbGVjdFByb3BlcnRpZXMuaW5jbHVkZXMoa2V5KSkge1xuXHRcdFx0XHRvU2VsZWN0aW9uVmFyaWFudC5hZGRTZWxlY3RPcHRpb24oa2V5LCBcIklcIiwgXCJFUVwiLCB2T3V0Ym91bmRQYXJhbXNba2V5XSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIG9TZWxlY3Rpb25WYXJpYW50O1xuXHR9XG5cdC8qKlxuXHQgKiBNZXRob2QgdG8gZ2V0IHRoZSBvdXRib3VuZCBwYXJhbWV0ZXJzIGRlZmluZWQgaW4gdGhlIG1hbmlmZXN0LlxuXHQgKlxuXHQgKiBAZnVuY3Rpb25cblx0ICogQHBhcmFtIHtvYmplY3R9IG9PdXRib3VuZFBhcmFtcyBQYXJhbWV0ZXJzIGRlZmluZWQgaW4gdGhlIG91dGJvdW5kcy4gT25seSBcInBsYWluXCIgaXMgc3VwcG9ydGVkXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gUGFyYW1ldGVycyB3aXRoIHRoZSBrZXktVmFsdWUgcGFpclxuXHQgKiovXG5cdEBQdWJsaWNcblx0QEZpbmFsXG5cdGdldE91dGJvdW5kUGFyYW1zKG9PdXRib3VuZFBhcmFtczogYW55KSB7XG5cdFx0Y29uc3Qgb1BhcmFtc01hcHBpbmc6IGFueSA9IHt9O1xuXHRcdGlmIChvT3V0Ym91bmRQYXJhbXMpIHtcblx0XHRcdGNvbnN0IGFQYXJhbWV0ZXJzID0gT2JqZWN0LmtleXMob091dGJvdW5kUGFyYW1zKSB8fCBbXTtcblx0XHRcdGlmIChhUGFyYW1ldGVycy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdGFQYXJhbWV0ZXJzLmZvckVhY2goZnVuY3Rpb24oa2V5OiBzdHJpbmcpIHtcblx0XHRcdFx0XHRjb25zdCBvTWFwcGluZyA9IG9PdXRib3VuZFBhcmFtc1trZXldO1xuXHRcdFx0XHRcdGlmIChvTWFwcGluZy52YWx1ZSAmJiBvTWFwcGluZy52YWx1ZS52YWx1ZSAmJiBvTWFwcGluZy52YWx1ZS5mb3JtYXQgPT09IFwicGxhaW5cIikge1xuXHRcdFx0XHRcdFx0aWYgKCFvUGFyYW1zTWFwcGluZ1trZXldKSB7XG5cdFx0XHRcdFx0XHRcdG9QYXJhbXNNYXBwaW5nW2tleV0gPSBvTWFwcGluZy52YWx1ZS52YWx1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gb1BhcmFtc01hcHBpbmc7XG5cdH1cblxuXHQvKipcblx0ICogVHJpZ2dlcnMgYW4gb3V0Ym91bmQgbmF2aWdhdGlvbiB3aGVuIGEgdXNlciBjaG9vc2VzIHRoZSBjaGV2cm9uLlxuXHQgKlxuXHQgKiBAcGFyYW0ge29iamVjdH0gb0NvbnRyb2xsZXJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNPdXRib3VuZFRhcmdldCBOYW1lIG9mIHRoZSBvdXRib3VuZCB0YXJnZXQgKG5lZWRzIHRvIGJlIGRlZmluZWQgaW4gdGhlIG1hbmlmZXN0KVxuXHQgKiBAcGFyYW0ge3NhcC51aS5tb2RlbC5vZGF0YS52NC5Db250ZXh0fSBvQ29udGV4dCBUaGUgY29udGV4dCB0aGF0IGNvbnRhaW5zIHRoZSBkYXRhIGZvciB0aGUgdGFyZ2V0IGFwcFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc0NyZWF0ZVBhdGggQ3JlYXRlIHBhdGggd2hlbiB0aGUgY2hldnJvbiBpcyBjcmVhdGVkLlxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZX0gUHJvbWlzZSB3aGljaCBpcyByZXNvbHZlZCBvbmNlIHRoZSBuYXZpZ2F0aW9uIGlzIHRyaWdnZXJlZFxuXHQgKi9cblxuXHRAUHVibGljXG5cdEBGaW5hbFxuXHRvbkNoZXZyb25QcmVzc05hdmlnYXRlT3V0Qm91bmQob0NvbnRyb2xsZXI6IFBhZ2VDb250cm9sbGVyLCBzT3V0Ym91bmRUYXJnZXQ6IHN0cmluZywgb0NvbnRleHQ6IGFueSwgc0NyZWF0ZVBhdGg6IHN0cmluZykge1xuXHRcdGNvbnN0IG9PdXRib3VuZHMgPSAob0NvbnRyb2xsZXIuZ2V0QXBwQ29tcG9uZW50KCkgYXMgYW55KS5nZXRSb3V0aW5nU2VydmljZSgpLmdldE91dGJvdW5kcygpO1xuXHRcdGNvbnN0IG9EaXNwbGF5T3V0Ym91bmQgPSBvT3V0Ym91bmRzW3NPdXRib3VuZFRhcmdldF07XG5cdFx0bGV0IGFkZGl0aW9uYWxOYXZpZ2F0aW9uUGFyYW1ldGVycztcblx0XHRpZiAob0Rpc3BsYXlPdXRib3VuZCAmJiBvRGlzcGxheU91dGJvdW5kLnNlbWFudGljT2JqZWN0ICYmIG9EaXNwbGF5T3V0Ym91bmQuYWN0aW9uKSB7XG5cdFx0XHRjb25zdCBvUmVmcmVzaFN0cmF0ZWdpZXM6IGFueSA9IHtcblx0XHRcdFx0aW50ZW50czoge31cblx0XHRcdH07XG5cdFx0XHRjb25zdCBvRGVmYXVsdFJlZnJlc2hTdHJhdGVneTogYW55ID0ge307XG5cdFx0XHRsZXQgc01ldGFQYXRoO1xuXG5cdFx0XHRpZiAob0NvbnRleHQpIHtcblx0XHRcdFx0aWYgKG9Db250ZXh0LmlzQSAmJiBvQ29udGV4dC5pc0EoXCJzYXAudWkubW9kZWwub2RhdGEudjQuQ29udGV4dFwiKSkge1xuXHRcdFx0XHRcdHNNZXRhUGF0aCA9IE1vZGVsSGVscGVyLmdldE1ldGFQYXRoRm9yQ29udGV4dChvQ29udGV4dCk7XG5cdFx0XHRcdFx0b0NvbnRleHQgPSBbb0NvbnRleHRdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHNNZXRhUGF0aCA9IE1vZGVsSGVscGVyLmdldE1ldGFQYXRoRm9yQ29udGV4dChvQ29udGV4dFswXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0b0RlZmF1bHRSZWZyZXNoU3RyYXRlZ3lbc01ldGFQYXRoXSA9IFwic2VsZlwiO1xuXHRcdFx0XHRvUmVmcmVzaFN0cmF0ZWdpZXNbXCJfZmVEZWZhdWx0XCJdID0gb0RlZmF1bHRSZWZyZXNoU3RyYXRlZ3k7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzQ3JlYXRlUGF0aCkge1xuXHRcdFx0XHRjb25zdCBzS2V5ID0gb0Rpc3BsYXlPdXRib3VuZC5zZW1hbnRpY09iamVjdCArIFwiLVwiICsgb0Rpc3BsYXlPdXRib3VuZC5hY3Rpb247XG5cdFx0XHRcdG9SZWZyZXNoU3RyYXRlZ2llcy5pbnRlbnRzW3NLZXldID0ge307XG5cdFx0XHRcdG9SZWZyZXNoU3RyYXRlZ2llcy5pbnRlbnRzW3NLZXldW3NDcmVhdGVQYXRoXSA9IFwic2VsZlwiO1xuXHRcdFx0fVxuXHRcdFx0aWYgKG9EaXNwbGF5T3V0Ym91bmQgJiYgb0Rpc3BsYXlPdXRib3VuZC5wYXJhbWV0ZXJzKSB7XG5cdFx0XHRcdGNvbnN0IG9QYXJhbXMgPSBvRGlzcGxheU91dGJvdW5kLnBhcmFtZXRlcnMgJiYgdGhpcy5nZXRPdXRib3VuZFBhcmFtcyhvRGlzcGxheU91dGJvdW5kLnBhcmFtZXRlcnMpO1xuXHRcdFx0XHRpZiAoT2JqZWN0LmtleXMob1BhcmFtcykubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdGFkZGl0aW9uYWxOYXZpZ2F0aW9uUGFyYW1ldGVycyA9IG9QYXJhbXM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0b0NvbnRyb2xsZXIuX2ludGVudEJhc2VkTmF2aWdhdGlvbi5uYXZpZ2F0ZShvRGlzcGxheU91dGJvdW5kLnNlbWFudGljT2JqZWN0LCBvRGlzcGxheU91dGJvdW5kLmFjdGlvbiwge1xuXHRcdFx0XHRuYXZpZ2F0aW9uQ29udGV4dHM6IG9Db250ZXh0LFxuXHRcdFx0XHRyZWZyZXNoU3RyYXRlZ2llczogb1JlZnJlc2hTdHJhdGVnaWVzLFxuXHRcdFx0XHRhZGRpdGlvbmFsTmF2aWdhdGlvblBhcmFtZXRlcnM6IGFkZGl0aW9uYWxOYXZpZ2F0aW9uUGFyYW1ldGVyc1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vVE9ETzogY2hlY2sgd2h5IHJldHVybmluZyBhIHByb21pc2UgaXMgcmVxdWlyZWRcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwib3V0Ym91bmQgdGFyZ2V0IFwiICsgc091dGJvdW5kVGFyZ2V0ICsgXCIgbm90IGZvdW5kIGluIGNyb3NzIG5hdmlnYXRpb24gZGVmaW5pdGlvbiBvZiBtYW5pZmVzdFwiKTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW50ZXJuYWxJbnRlbnRCYXNlZE5hdmlnYXRpb247XG4iXX0=